mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
Added float target frame time, set UPS to 120.
Improved frame stabilization. Ref PR #85.
This commit is contained in:
parent
0b2fd28fda
commit
ab7184ef86
@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
TPinballTable* pb::MainTable = nullptr;
|
TPinballTable* pb::MainTable = nullptr;
|
||||||
datFileStruct* pb::record_table = nullptr;
|
datFileStruct* pb::record_table = nullptr;
|
||||||
int pb::time_ticks = 0, pb::demo_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb::state, pb::frameCounter = 0;
|
int pb::time_ticks = 0, pb::demo_mode = 0, pb::game_mode = 2, pb::state, pb::frameCounter = 0;
|
||||||
float pb::time_now, pb::time_next, pb::ball_speed_limit;
|
float pb::time_now, pb::time_next, pb::ball_speed_limit, pb::mode_countdown_, pb::time_ticks_remainder = 0;
|
||||||
high_score_struct pb::highscore_table[5];
|
high_score_struct pb::highscore_table[5];
|
||||||
bool pb::FullTiltMode = false, pb::cheat_mode = false;
|
bool pb::FullTiltMode = false, pb::cheat_mode = false;
|
||||||
|
|
||||||
@ -225,29 +225,34 @@ void pb::ballset(int x, int y)
|
|||||||
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
ball->Speed = maths::normalize_2d(&ball->Acceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::frame(int time)
|
void pb::frame(float dtMilliSec)
|
||||||
{
|
{
|
||||||
static int frameTime = 0;
|
static float frameTime = 0;
|
||||||
|
|
||||||
if (time > 100)
|
if (dtMilliSec > 100)
|
||||||
time = 100;
|
dtMilliSec = 100;
|
||||||
if (time <= 0)
|
if (dtMilliSec <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float timeMul = time * 0.001f;
|
auto dtSec = dtMilliSec * 0.001f;
|
||||||
if (!mode_countdown(time))
|
if (!mode_countdown(dtMilliSec))
|
||||||
{
|
{
|
||||||
time_next = time_now + timeMul;
|
time_next = time_now + dtSec;
|
||||||
timed_frame(time_now, timeMul, true);
|
timed_frame(time_now, dtSec, true);
|
||||||
time_now = time_next;
|
time_now = time_next;
|
||||||
time_ticks += time;
|
|
||||||
|
auto dtMilliSecComp = dtMilliSec + time_ticks_remainder;
|
||||||
|
auto dtWhole = static_cast<int>(dtMilliSecComp);
|
||||||
|
time_ticks_remainder = dtMilliSecComp - static_cast<float>(dtWhole);
|
||||||
|
time_ticks += dtWhole;
|
||||||
|
|
||||||
if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up)
|
if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up)
|
||||||
{
|
{
|
||||||
nudge::nudge_count = timeMul * 4.0f + nudge::nudge_count;
|
nudge::nudge_count = dtSec * 4.0f + nudge::nudge_count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto nudgeDec = nudge::nudge_count - timeMul;
|
auto nudgeDec = nudge::nudge_count - dtSec;
|
||||||
if (nudgeDec <= 0.0f)
|
if (nudgeDec <= 0.0f)
|
||||||
nudgeDec = 0.0;
|
nudgeDec = 0.0;
|
||||||
nudge::nudge_count = nudgeDec;
|
nudge::nudge_count = nudgeDec;
|
||||||
@ -265,9 +270,9 @@ void pb::frame(int time)
|
|||||||
// Retained render prevents frame skip. The next best thing - complete refresh at fixed rate.
|
// Retained render prevents frame skip. The next best thing - complete refresh at fixed rate.
|
||||||
render::update(false);
|
render::update(false);
|
||||||
|
|
||||||
// Frame time at 60 FPS = 16.(6) ms = (16 + 17 + 17) / 3
|
// Frame time at 60 FPS = 16.(6) ms
|
||||||
auto targetTime = frameCounter % 3 == 0 ? 16 : 17;
|
auto targetTime = 1000 / 60.0f;
|
||||||
frameTime += time;
|
frameTime += dtMilliSec;
|
||||||
if (frameTime >= targetTime)
|
if (frameTime >= targetTime)
|
||||||
{
|
{
|
||||||
frameTime = min(frameTime - targetTime, 100);
|
frameTime = min(frameTime - targetTime, 100);
|
||||||
@ -526,7 +531,7 @@ void pb::keydown(int key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pb::mode_countdown(int time)
|
int pb::mode_countdown(float dtMilliSec)
|
||||||
{
|
{
|
||||||
if (!game_mode || game_mode <= 0)
|
if (!game_mode || game_mode <= 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -534,14 +539,14 @@ int pb::mode_countdown(int time)
|
|||||||
{
|
{
|
||||||
if (game_mode == 3)
|
if (game_mode == 3)
|
||||||
{
|
{
|
||||||
mode_countdown_ -= time;
|
mode_countdown_ -= dtMilliSec;
|
||||||
if (mode_countdown_ < 0 || time < 0)
|
if (mode_countdown_ < 0.0f || dtMilliSec < 0.0f)
|
||||||
mode_change(4);
|
mode_change(4);
|
||||||
}
|
}
|
||||||
else if (game_mode == 4)
|
else if (game_mode == 4)
|
||||||
{
|
{
|
||||||
mode_countdown_ -= time;
|
mode_countdown_ -= dtMilliSec;
|
||||||
if (mode_countdown_ < 0 || time < 0)
|
if (mode_countdown_ < 0.0f || dtMilliSec < 0.0f)
|
||||||
mode_change(1);
|
mode_change(1);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -26,14 +26,14 @@ public:
|
|||||||
static void toggle_demo();
|
static void toggle_demo();
|
||||||
static void replay_level(int demoMode);
|
static void replay_level(int demoMode);
|
||||||
static void ballset(int x, int y);
|
static void ballset(int x, int y);
|
||||||
static void frame(int time);
|
static void frame(float dtMilliSec);
|
||||||
static void timed_frame(float timeNow, float timeDelta, bool drawBalls);
|
static void timed_frame(float timeNow, float timeDelta, bool drawBalls);
|
||||||
static void window_size(int* width, int* height);
|
static void window_size(int* width, int* height);
|
||||||
static void pause_continue();
|
static void pause_continue();
|
||||||
static void loose_focus();
|
static void loose_focus();
|
||||||
static void keyup(int key);
|
static void keyup(int key);
|
||||||
static void keydown(int key);
|
static void keydown(int key);
|
||||||
static int mode_countdown(int time);
|
static int mode_countdown(float dtMilliSec);
|
||||||
static void launch_ball();
|
static void launch_ball();
|
||||||
static void end_game();
|
static void end_game();
|
||||||
static void high_scores();
|
static void high_scores();
|
||||||
@ -41,6 +41,7 @@ public:
|
|||||||
static bool chk_highscore();
|
static bool chk_highscore();
|
||||||
static float collide(float timeNow, float timeDelta, TBall* ball);
|
static float collide(float timeNow, float timeDelta, TBall* ball);
|
||||||
private:
|
private:
|
||||||
static int demo_mode, mode_countdown_;
|
static int demo_mode;
|
||||||
static int state;
|
static int state;
|
||||||
|
static float mode_countdown_, time_ticks_remainder;
|
||||||
};
|
};
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "splash.h"
|
#include "splash.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
||||||
const int TargetFrameTime = 8;
|
const float TargetUPS = 120, TargetFrameTime = 1000 / TargetUPS;
|
||||||
|
|
||||||
HINSTANCE winmain::hinst = nullptr;
|
HINSTANCE winmain::hinst = nullptr;
|
||||||
HWND winmain::hwnd_frame = nullptr;
|
HWND winmain::hwnd_frame = nullptr;
|
||||||
@ -225,7 +225,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||||||
pb::replay_level(0);
|
pb::replay_level(0);
|
||||||
|
|
||||||
DWORD someTimeCounter = 300u, prevTime = 0u, frameStart = timeGetTime();
|
DWORD someTimeCounter = 300u, prevTime = 0u, frameStart = timeGetTime();
|
||||||
int sleepRemainder = 0, frameDuration = TargetFrameTime;
|
float sleepRemainder = 0, frameDuration = TargetFrameTime;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!someTimeCounter)
|
if (!someTimeCounter)
|
||||||
@ -299,11 +299,11 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||||||
gdrv::fill_bitmap(&gfr_display, 1, height, width - 1, 0, 0); // Background
|
gdrv::fill_bitmap(&gfr_display, 1, height, width - 1, 0, 0); // Background
|
||||||
|
|
||||||
auto targetVal = dt < target ? dt : target;
|
auto targetVal = dt < target ? dt : target;
|
||||||
auto targetHeight = min(static_cast<int>(std::round(targetVal * scale)), height);
|
auto targetHeight = min(static_cast<int>(std::floor(targetVal * scale)), height);
|
||||||
gdrv::fill_bitmap(&gfr_display, 1, targetHeight, width - 1, height - targetHeight, -1); // Target
|
gdrv::fill_bitmap(&gfr_display, 1, targetHeight, width - 1, height - targetHeight, -1); // Target
|
||||||
|
|
||||||
auto diffVal = dt < target ? target - dt : dt - target;
|
auto diffVal = dt < target ? target - dt : dt - target;
|
||||||
auto diffHeight = min(static_cast<int>(std::round(diffVal * scale)), height);
|
auto diffHeight = min(static_cast<int>(std::floor(diffVal * scale)), height);
|
||||||
gdrv::fill_bitmap(&gfr_display, 1, diffHeight, width - 1, height - targetHeight - diffHeight, 1); // Target diff
|
gdrv::fill_bitmap(&gfr_display, 1, diffHeight, width - 1, height - targetHeight - diffHeight, 1); // Target diff
|
||||||
|
|
||||||
gdrv::blit(&gfr_display, 0, 0, render::vscreen.Width - width, 0, width, height);
|
gdrv::blit(&gfr_display, 0, 0, render::vscreen.Width - width, 0, width, height);
|
||||||
@ -311,21 +311,21 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||||||
|
|
||||||
auto updateEnd = timeGetTime();
|
auto updateEnd = timeGetTime();
|
||||||
auto sleepDuration = TargetFrameTime - (int)(updateEnd - frameStart) - sleepRemainder;
|
auto sleepDuration = TargetFrameTime - (int)(updateEnd - frameStart) - sleepRemainder;
|
||||||
|
auto intSleepDuration = static_cast<int>(sleepDuration);
|
||||||
|
|
||||||
DWORD frameEnd;
|
DWORD frameEnd;
|
||||||
if (sleepDuration > 0)
|
if (intSleepDuration > 0)
|
||||||
{
|
{
|
||||||
Sleep(sleepDuration);
|
Sleep(intSleepDuration);
|
||||||
frameEnd = timeGetTime();
|
frameEnd = timeGetTime();
|
||||||
sleepRemainder = (frameEnd - updateEnd) - sleepDuration;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
frameEnd = updateEnd;
|
frameEnd = updateEnd;
|
||||||
sleepRemainder = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frameDuration = min(frameEnd - frameStart, TargetFrameTime * 2);
|
sleepRemainder = max(min((int)(frameEnd - updateEnd) - sleepDuration, TargetFrameTime), -TargetFrameTime);
|
||||||
|
frameDuration = min((frameEnd - frameStart), TargetFrameTime * 2);
|
||||||
frameStart = frameEnd;
|
frameStart = frameEnd;
|
||||||
|
|
||||||
--someTimeCounter;
|
--someTimeCounter;
|
||||||
|
Loading…
Reference in New Issue
Block a user