예제 #1
0
void hleLagSync(u64 userdata, int cyclesLate) {
	// The goal here is to prevent network, audio, and input lag from the real world.
	// Our normal timing is very "stop and go".  This is efficient, but causes real world lag.
	// This event (optionally) runs every 1ms to sync with the real world.

	if (!FrameTimingThrottled()) {
		lagSyncScheduled = false;
		return;
	}

	float scale = 1.0f;
	if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM) {
		// 0 is handled in FrameTimingThrottled().
		scale = 60.0f / g_Config.iFpsLimit;
	}

	const double goal = lastLagSync + (scale / 1000.0f);
	time_update();
	// Don't lag too long ever, if they leave it paused.
	while (time_now_d() < goal && goal < time_now_d() + 0.01) {
#ifndef _WIN32
		const double left = goal - time_now_d();
		usleep((long)(left * 1000000));
#endif
		time_update();
	}

	const int emuOver = (int)cyclesToUs(cyclesLate);
	const int over = (int)((time_now_d() - goal) * 1000000);
	ScheduleLagSync(over - emuOver);
}
예제 #2
0
void hleAfterFlip(u64 userdata, int cyclesLate) {
	gpu->BeginFrame();  // doesn't really matter if begin or end of frame.

	// This seems like as good a time as any to check if the config changed.
	if (lagSyncScheduled != g_Config.bForceLagSync) {
		ScheduleLagSync();
	}
}
예제 #3
0
void __DisplayInit() {
	gpuStats.Reset();
	hasSetMode = false;
	mode = 0;
	resumeMode = 0;
	holdMode = 0;
	brightnessLevel = 100;
	width = 480;
	height = 272;
	numSkippedFrames = 0;
	numVBlanksSinceFlip = 0;
	framebufIsLatched = false;
	framebuf.topaddr = 0x04000000;
	framebuf.pspFramebufFormat = GE_FORMAT_8888;
	framebuf.pspFramebufLinesize = 480; // ??
	lastFlipCycles = 0;
	lastFlipsTooFrequent = 0;
	wasPaused = false;

	enterVblankEvent = CoreTiming::RegisterEvent("EnterVBlank", &hleEnterVblank);
	leaveVblankEvent = CoreTiming::RegisterEvent("LeaveVBlank", &hleLeaveVblank);
	afterFlipEvent = CoreTiming::RegisterEvent("AfterFlip", &hleAfterFlip);

	lagSyncEvent = CoreTiming::RegisterEvent("LagSync", &hleLagSync);
	ScheduleLagSync();

	CoreTiming::ScheduleEvent(msToCycles(frameMs - vblankMs), enterVblankEvent, 0);
	isVblank = 0;
	vCount = 0;
	hCountBase = 0;
	curFrameTime = 0.0;
	nextFrameTime = 0.0;
	lastFrameTime = 0.0;

	flips = 0;
	fps = 0.0;
	actualFlips = 0;
	lastActualFlips = 0;
	lastNumFlips = 0;
	fpsHistoryValid = 0;
	fpsHistoryPos = 0;

	InitGfxState();

	__KernelRegisterWaitTypeFuncs(WAITTYPE_VBLANK, __DisplayVblankBeginCallback, __DisplayVblankEndCallback);
}
예제 #4
0
void __DisplayDoState(PointerWrap &p) {
	auto s = p.Section("sceDisplay", 1, 6);
	if (!s)
		return;

	p.Do(framebuf);
	p.Do(latchedFramebuf);
	p.Do(framebufIsLatched);
	p.Do(frameStartTicks);
	p.Do(vCount);
	if (s <= 2) {
		double oldHCountBase;
		p.Do(oldHCountBase);
		hCountBase = (int) oldHCountBase;
	} else {
		p.Do(hCountBase);
	}
	p.Do(isVblank);
	p.Do(hasSetMode);
	p.Do(mode);
	p.Do(resumeMode);
	p.Do(holdMode);
	if (s >= 4) {
		p.Do(brightnessLevel);
	}
	p.Do(width);
	p.Do(height);
	WaitVBlankInfo wvi(0);
	p.Do(vblankWaitingThreads, wvi);
	p.Do(vblankPausedWaits);

	p.Do(enterVblankEvent);
	CoreTiming::RestoreRegisterEvent(enterVblankEvent, "EnterVBlank", &hleEnterVblank);
	p.Do(leaveVblankEvent);
	CoreTiming::RestoreRegisterEvent(leaveVblankEvent, "LeaveVBlank", &hleLeaveVblank);
	p.Do(afterFlipEvent);
	CoreTiming::RestoreRegisterEvent(afterFlipEvent, "AfterFlip", &hleAfterFlip);

	if (s >= 5) {
		p.Do(lagSyncEvent);
		p.Do(lagSyncScheduled);
		CoreTiming::RestoreRegisterEvent(lagSyncEvent, "LagSync", &hleLagSync);
		lastLagSync = real_time_now();
		if (lagSyncScheduled != g_Config.bForceLagSync) {
			ScheduleLagSync();
		}
	} else {
		lagSyncEvent = CoreTiming::RegisterEvent("LagSync", &hleLagSync);
		ScheduleLagSync();
	}

	p.Do(gstate);
	gstate_c.DoState(p);
#ifndef _XBOX
	if (s < 2) {
		// This shouldn't have been savestated anyway, but it was.
		// It's unlikely to overlap with the first value in gpuStats.
		p.ExpectVoid(&gl_extensions.gpuVendor, sizeof(gl_extensions.gpuVendor));
	}
#endif
	if (s < 6) {
		p.Do(gpuStats);
	}
	gpu->DoState(p);

	ReapplyGfxState();

	if (p.mode == p.MODE_READ) {
		if (hasSetMode) {
			gpu->InitClear();
		}
		gpu->SetDisplayFramebuffer(framebuf.topaddr, framebuf.pspFramebufLinesize, framebuf.pspFramebufFormat);
	}
}