Esempio n. 1
0
dtime_t I_MSTime()
{
	return I_ConvertTimeToMs(I_GetTime());
}
Esempio n. 2
0
//
// D_RunTics
//
// The core of the main game loop.
// This loop allows the game simulation timing to be decoupled from the renderer
// timing. If the the user selects a capped framerate and isn't using the
// -timedemo parameter, both the simulation and render functions will be called
// TICRATE times a second. If the framerate is uncapped, the simulation function
// will still be called TICRATE times a second but the render function will
// be called as often as possible. After each iteration through the loop,
// the program yields briefly to the operating system.
//
void D_RunTics(void (*sim_func)(), void(*render_func)())
{
	static const uint64_t sim_dt = I_ConvertTimeFromMs(1000) / TICRATE;

	static uint64_t previous_time = I_GetTime();
	uint64_t current_time = I_GetTime();

	// reset the rendering interpolation
	render_lerp_amount = FRACUNIT;

	static uint64_t accumulator = sim_dt;

	if (!timingdemo)	// run simulation function at 35Hz?
	{
		// Run upto 4 simulation frames. Limit the number because there's already a
		// slowdown and running more will only make things worse.
		accumulator += MIN(current_time - previous_time, 4 * sim_dt);

		// calculate how late the start of the frame is (for debugging)
		uint64_t late_time_ms = current_time - previous_time > sim_dt ?
			I_ConvertTimeToMs(current_time - previous_time - sim_dt) : 0;

		if (late_time_ms > 2)
			DPrintf("Warning: frame start is %ums late!\n", late_time_ms);

		while (accumulator >= sim_dt)
		{
			sim_func();
			accumulator -= sim_dt;
		}

		// Use linear interpolation for rendering entities if the renderer
		// framerate is not synced with the physics frequency.
		if (maxfps != TICRATE && !(paused || menuactive || step_mode))
			render_lerp_amount = (fixed_t)(accumulator * FRACUNIT / sim_dt);
	}
	else			// run simulation function as fast as possible
	{
		sim_func();
		accumulator = 0;
	}

	render_func();

	static float previous_maxfps = -1;

	if (!timingdemo && capfps)		// render at a capped framerate?
	{
		static uint64_t render_dt, previous_block;
		uint64_t current_block;

		// The capped framerate has changed so recalculate some stuff
		if (maxfps != previous_maxfps)
		{
			render_dt = I_ConvertTimeFromMs(1000) / maxfps;
			previous_block = current_time / render_dt;
		}

		// With capped framerates, frames are rendered within fixed blocks of time
		// and at the end of a frame, sleep until the start of the next block.
		do
			I_Yield();
		while ( (current_block = I_GetTime() / render_dt) <= previous_block);

		previous_block = current_block;
		previous_maxfps = maxfps;
	}
	else if (!timingdemo)			// render at an unlimited framerate (but still yield)
	{
		// sleep for 1ms to allow the operating system some time
		I_Yield();
		previous_maxfps = -1;
	}

	previous_time = current_time;
}