diff --git a/SpaceCadetPinball/gdrv.cpp b/SpaceCadetPinball/gdrv.cpp index b714d9c..eee8626 100644 --- a/SpaceCadetPinball/gdrv.cpp +++ b/SpaceCadetPinball/gdrv.cpp @@ -413,19 +413,6 @@ void gdrv::copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int heigh } } -void gdrv::ScrollBitmapHorizontal(gdrv_bitmap8* bmp, int xStart) -{ - auto srcPtr = bmp->BmpBufPtr1; - auto startOffset = xStart >= 0 ? 0 : -xStart; - auto endOffset = xStart >= 0 ? xStart : 0; - auto length = bmp->Width - std::abs(xStart); - for (int y = bmp->Height; y > 0; --y) - { - std::memmove(srcPtr + endOffset, srcPtr + startOffset, length); - srcPtr += bmp->Stride; - } -} - void gdrv::grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width, int height) { diff --git a/SpaceCadetPinball/gdrv.h b/SpaceCadetPinball/gdrv.h index 743d63f..d06622d 100644 --- a/SpaceCadetPinball/gdrv.h +++ b/SpaceCadetPinball/gdrv.h @@ -64,7 +64,6 @@ public: int srcXOff, int srcYOff); static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff, gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff); - static void ScrollBitmapHorizontal(gdrv_bitmap8* bmp, int xStart); static void grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width, int height); private: /*COLORONCOLOR or HALFTONE*/ diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index 1c74b16..4f0b2e1 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -225,15 +225,12 @@ void pb::ballset(int x, int y) ball->Speed = maths::normalize_2d(&ball->Acceleration); } -void pb::frame(int time) +int pb::frame(int time) { static int frameTime = 0; if (time > 100) time = 100; - if (time <= 0) - return; - float timeMul = time * 0.001f; if (!mode_countdown(time)) { @@ -287,6 +284,7 @@ void pb::frame(int time) MainTable->tilt(time_now); } } + return 1; } void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls) diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index e8625bc..97106e6 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -26,7 +26,7 @@ public: static void toggle_demo(); static void replay_level(int demoMode); static void ballset(int x, int y); - static void frame(int time); + static int frame(int time); static void timed_frame(float timeNow, float timeDelta, bool drawBalls); static void window_size(int* width, int* height); static void pause_continue(); diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 3d2aec2..9df09c9 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -10,9 +10,6 @@ #include "Sound.h" #include "resource.h" #include "splash.h" -#include "render.h" - -const int TargetFrameTime = 8; HINSTANCE winmain::hinst = nullptr; HWND winmain::hwnd_frame = nullptr; @@ -30,6 +27,8 @@ int winmain::last_mouse_y; int winmain::mouse_down; int winmain::no_time_loss; +DWORD winmain::then; +DWORD winmain::now; UINT winmain::iFrostUniqueMsg; bool winmain::restart = false; @@ -51,10 +50,6 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi options::ReadOptions(); auto regSpaceCadet = pinball::get_rc_string(166, 0); - // Needed for sub 16ms sleep - if (timeBeginPeriod(1) == TIMERR_NOERROR) - atexit(ResetTimer); - if (options::get_int(regSpaceCadet, "Table Version", 1) <= 1) { auto tmpBuf = memory::allocate(0x1F4u); @@ -225,7 +220,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi pb::replay_level(0); DWORD someTimeCounter = 300u, prevTime = 0u; - int sleepRemainder = 0, frameDuration = TargetFrameTime; + then = timeGetTime(); while (true) { if (!someTimeCounter) @@ -248,6 +243,32 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi } SetWindowTextA(hwnd_frame, buf); + + if (DispGRhistory) + { + if (!gfr_display.BmpBufPtr1) + { + auto plt = static_cast(malloc(1024u)); + auto pltPtr = &plt[10]; + for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8) + { + unsigned char blue = i2, redGreen = i2; + if (i2 > 255) + { + blue = 255; + redGreen = i1; + } + + *pltPtr++ = {redGreen, redGreen, blue}; + } + gdrv::display_palette(plt); + free(plt); + gdrv::create_bitmap(&gfr_display, 400, 15); + } + + gdrv::blit(&gfr_display, 0, 0, 0, 0, 300, 10); + gdrv::fill_bitmap(&gfr_display, 300, 10, 0, 0, 0); + } } prevTime = curTime; } @@ -263,64 +284,50 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi if (has_focus) { - if (mouse_down && frameDuration >= 2) + if (mouse_down) { - /*last_mouse_n is in client coordinates*/ - POINT Point; - GetCursorPos(&Point); - ScreenToClient(hwnd_frame, &Point); - pb::ballset(last_mouse_x - Point.x, Point.y - last_mouse_y); - Point = POINT{ last_mouse_x, last_mouse_y }; - ClientToScreen(hwnd_frame, &Point); - SetCursorPos(Point.x, Point.y); + now = timeGetTime(); + if (now - then >= 2) + { + /*last_mouse_n is in client coordinates*/ + POINT Point; + GetCursorPos(&Point); + ScreenToClient(hwnd_frame, &Point); + pb::ballset(last_mouse_x - Point.x, Point.y - last_mouse_y); + Point = POINT{last_mouse_x, last_mouse_y}; + ClientToScreen(hwnd_frame, &Point); + SetCursorPos(Point.x, Point.y); + } } - if (!single_step) { - auto frameStart = timeGetTime(); - auto dt = frameDuration; - if (!no_time_loss) - pb::frame(dt); - else - no_time_loss = 0; - - if (DispGRhistory) + auto curTime = timeGetTime(); + now = curTime; + if (no_time_loss) { - auto width = render::vscreen.Width / 2; - auto height = 64; - if (!gfr_display.BmpBufPtr1) - { - gdrv::create_bitmap(&gfr_display, width, height); - } - - gdrv::ScrollBitmapHorizontal(&gfr_display, -1); - - float target = TargetFrameTime; - auto scale = height / target / 2; - gdrv::fill_bitmap(&gfr_display, 1, height, width - 1, 0, 0); // Background - - auto targetVal = dt < target ? dt : target; - auto targetHeight = min(static_cast(std::round(targetVal * scale)), height); - gdrv::fill_bitmap(&gfr_display, 1, targetHeight, width - 1, height - targetHeight, -1); // Target - - auto diffVal = dt < target ? target - dt : dt - target; - auto diffHeight = min(static_cast(std::round(diffVal * scale)), height); - 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); + then = curTime; + no_time_loss = 0; } - auto updateEnd = timeGetTime(); - auto sleepDuration = TargetFrameTime - (int)(updateEnd - frameStart) - sleepRemainder; - - if (sleepDuration > 0) - Sleep(sleepDuration); - - auto frameEnd = timeGetTime(); - sleepRemainder = (frameEnd - updateEnd) - sleepDuration; - frameDuration = min(frameEnd - frameStart, TargetFrameTime * 2); - - --someTimeCounter; + if (curTime == then) + { + Sleep(8u); + } + else if (pb::frame(curTime - then)) + { + if (gfr_display.BmpBufPtr1) + { + auto deltaT = now - then + 10; + auto fillChar = static_cast(deltaT); + if (deltaT > 236) + { + fillChar = -7; + } + gdrv::fill_bitmap(&gfr_display, 1, 10, 299 - someTimeCounter, 0, fillChar); + } + --someTimeCounter; + then = now; + } } } } @@ -530,32 +537,13 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP return DefWindowProcW(hWnd, Msg, wParam, lParam); switch (wParam) { - case 'G': - DispGRhistory ^= 1; + case 'H': + DispGRhistory = 1; return DefWindowProcW(hWnd, Msg, wParam, lParam); case 'Y': SetWindowTextA(hWnd, "Pinball"); DispFrameRate = DispFrameRate == 0; return DefWindowProcW(hWnd, Msg, wParam, lParam); - case 'O': - { - auto plt = static_cast(malloc(1024u)); - auto pltPtr = &plt[10]; - for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8) - { - unsigned char blue = i2, redGreen = i2; - if (i2 > 255) - { - blue = 255; - redGreen = i1; - } - - *pltPtr++ = { redGreen, redGreen, blue }; - } - gdrv::display_palette(plt); - free(plt); - } - break; case VK_F1: pb::frame(10); return DefWindowProcW(hWnd, Msg, wParam, lParam); diff --git a/SpaceCadetPinball/winmain.h b/SpaceCadetPinball/winmain.h index bbe5e3c..ff49949 100644 --- a/SpaceCadetPinball/winmain.h +++ b/SpaceCadetPinball/winmain.h @@ -26,14 +26,11 @@ public: private: static int return_value, bQuit, DispFrameRate, DispGRhistory, activated; static int has_focus, mouse_down, last_mouse_x, last_mouse_y, no_time_loss; + static DWORD then, now; static UINT iFrostUniqueMsg; static gdrv_bitmap8 gfr_display; static HCURSOR mouse_hsave; static bool restart; static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); - static void ResetTimer() - { - timeEndPeriod(1u); - } };