diff --git a/SpaceCadetPinball/DebugOverlay.cpp b/SpaceCadetPinball/DebugOverlay.cpp index a0c794d..a3d1ff3 100644 --- a/SpaceCadetPinball/DebugOverlay.cpp +++ b/SpaceCadetPinball/DebugOverlay.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "DebugOverlay.h" +#include "loader.h" #include "maths.h" #include "proj.h" #include "winmain.h" @@ -118,6 +119,10 @@ void DebugOverlay::DrawOverlay() if (options::Options.DebugOverlaySounds) DrawSoundPositions(); + // Draw ball depth cutoff steps that determine sprite size. + if (options::Options.DebugOverlayBallDepthGrid) + DrawBallDepthSteps(); + // Restore render target SDL_SetRenderTarget(winmain::Renderer, initialRenderTarget); SDL_SetRenderDrawColor(winmain::Renderer, @@ -243,6 +248,29 @@ void DebugOverlay::DrawSoundPositions() } } +void DebugOverlay::DrawBallDepthSteps() +{ + auto& edgeMan = *TTableLayer::edge_manager; + SDL_SetRenderDrawColor(winmain::Renderer, 200, 100, 0, 255); + + for (auto ball : pb::MainTable->BallList) + { + auto visualCount = loader::query_visual_states(ball->GroupIndex); + for (auto index = 0; index < visualCount; ++index) + { + auto depthPt = reinterpret_cast(loader::query_float_attribute(ball->GroupIndex, index, 501)); + auto pt = proj::xform_to_2d(*depthPt); + + // Snap X coordinate to edge box sides + auto x1 = proj::xform_to_2d(vector2{edgeMan.MinX, depthPt->Y}).X; + auto x2 = proj::xform_to_2d(vector2{edgeMan.MaxBoxX * edgeMan.AdvanceX + edgeMan.MinX, depthPt->Y}).X; + auto ff = proj::xform_to_2d(vector2{ edgeMan.MaxBoxX * edgeMan.AdvanceX + edgeMan.MinX, depthPt->Y }); + SDL_RenderDrawLine(winmain::Renderer, x1, pt.Y, x2, pt.Y); + } + break; + } +} + void DebugOverlay::DrawCicleType(circle_type& circle) { vector2 linePt{ circle.Center.X + sqrt(circle.RadiusSq), circle.Center.Y }; diff --git a/SpaceCadetPinball/DebugOverlay.h b/SpaceCadetPinball/DebugOverlay.h index ca1d523..3c95d52 100644 --- a/SpaceCadetPinball/DebugOverlay.h +++ b/SpaceCadetPinball/DebugOverlay.h @@ -21,4 +21,5 @@ private: static void DrawBallInfo(); static void DrawAllSprites(); static void DrawSoundPositions(); + static void DrawBallDepthSteps(); }; \ No newline at end of file diff --git a/SpaceCadetPinball/TBall.cpp b/SpaceCadetPinball/TBall.cpp index c6881b7..0f53a31 100644 --- a/SpaceCadetPinball/TBall.cpp +++ b/SpaceCadetPinball/TBall.cpp @@ -54,6 +54,7 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false) RenderSprite = new render_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr); PinballTable->CollisionCompOffset = Offset; Position.Z = Offset; + GroupIndex = groupIndex; } void TBall::Repaint() diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp index 7a9b4e2..740dc3c 100644 --- a/SpaceCadetPinball/options.cpp +++ b/SpaceCadetPinball/options.cpp @@ -117,6 +117,7 @@ void options::InitPrimary() Options.DebugOverlaySounds = get_int("Debug Overlay Sounds", true); translations::SetCurrentLanguage(get_string("Language", translations::GetCurrentLanguage()->ShortName).c_str()); Options.FontFileName = get_string("FontFileName", ""); + Options.DebugOverlayBallDepthGrid = get_int("Debug Overlay Ball Depth Grid", true); } void options::InitSecondary() @@ -167,6 +168,7 @@ void options::uninit() set_int("Debug Overlay Sounds", Options.DebugOverlaySounds); set_string("Language", translations::GetCurrentLanguage()->ShortName); set_string("FontFileName", Options.FontFileName.c_str()); + set_int("Debug Overlay Ball Depth Grid", Options.DebugOverlayBallDepthGrid); } diff --git a/SpaceCadetPinball/options.h b/SpaceCadetPinball/options.h index 07235d4..4157959 100644 --- a/SpaceCadetPinball/options.h +++ b/SpaceCadetPinball/options.h @@ -92,6 +92,7 @@ struct optionsStruct bool DebugOverlayCollisionMask; bool DebugOverlaySprites; bool DebugOverlaySounds; + bool DebugOverlayBallDepthGrid; std::string FontFileName; }; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 0a1ab50..19978fc 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -37,7 +37,8 @@ bool winmain::LaunchBallEnabled = true; bool winmain::HighScoresEnabled = true; bool winmain::DemoActive = false; int winmain::MainMenuHeight = 0; -std::string winmain::FpsDetails; +std::string winmain::FpsDetails, winmain::PrevSdlError; +unsigned winmain::PrevSdlErrorCount = 0; double winmain::UpdateToFrameRatio; winmain::DurationMs winmain::TargetFrameTime; optionsStruct& winmain::Options = options::Options; @@ -115,7 +116,7 @@ int winmain::WinMain(LPCSTR lpCmdLine) // First step: just load the options options::InitPrimary(); - if(!Options.FontFileName.empty()) + if (!Options.FontFileName.empty()) { ImGuiSDL::Deinitialize(); io.Fonts->Clear(); @@ -253,7 +254,8 @@ int winmain::WinMain(LPCSTR lpCmdLine) if (xMod != 0 || yMod != 0) { // Mouse warp does not work over remote desktop or in some VMs - x = abs(x - xMod); y = abs(y - yMod); + x = abs(x - xMod); + y = abs(y - yMod); SDL_WarpMouseInWindow(window, x, y); } @@ -310,10 +312,28 @@ int winmain::WinMain(LPCSTR lpCmdLine) } auto sdlError = SDL_GetError(); - if (sdlError[0]) + if (sdlError[0] || !PrevSdlError.empty()) { - SDL_ClearError(); - printf("SDL Error: %s\n", sdlError); + if (sdlError[0]) + SDL_ClearError(); + + // Rate limit duplicate SDL error messages. + if (sdlError != PrevSdlError) + { + PrevSdlError = sdlError; + if (PrevSdlErrorCount > 0) + { + printf("SDL Error: ^ Previous Error Repeated %u Times\n", PrevSdlErrorCount + 1); + PrevSdlErrorCount = 0; + } + + if (sdlError[0]) + printf("SDL Error: %s\n", sdlError); + } + else + { + PrevSdlErrorCount++; + } } auto updateEnd = Clock::now(); @@ -334,13 +354,19 @@ int winmain::WinMain(LPCSTR lpCmdLine) } // Limit duration to 2 * target time - sleepRemainder = Clamp(DurationMs(frameEnd - updateEnd) - targetTimeDelta, -TargetFrameTime, TargetFrameTime); + sleepRemainder = Clamp(DurationMs(frameEnd - updateEnd) - targetTimeDelta, -TargetFrameTime, + TargetFrameTime); frameDuration = std::min(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime); frameStart = frameEnd; UpdateToFrameCounter++; } } + if (PrevSdlErrorCount > 0) + { + printf("SDL Error: ^ Previous Error Repeated %u Times\n", PrevSdlErrorCount); + } + SDL_free(basePath); SDL_free(prefPath); delete gfr_display; @@ -481,7 +507,7 @@ void winmain::RenderUi() if (ImGui::BeginMenu("Language")) { auto currentLanguage = translations::GetCurrentLanguage(); - for (auto &item : translations::Languages) + for (auto& item : translations::Languages) { if (ImGui::MenuItem(item.DisplayName, nullptr, currentLanguage->Language == item.Language)) { @@ -504,14 +530,15 @@ void winmain::RenderUi() options::toggle(Menu1::SoundStereo); } ImGui::TextUnformatted("Sound Volume"); - if (ImGui::SliderInt("##Sound Volume", &Options.SoundVolume, options::MinVolume, options::MaxVolume, "%d", - ImGuiSliderFlags_AlwaysClamp)) + if (ImGui::SliderInt("##Sound Volume", &Options.SoundVolume, options::MinVolume, options::MaxVolume, + "%d", + ImGuiSliderFlags_AlwaysClamp)) { Sound::SetVolume(Options.SoundVolume); } ImGui::TextUnformatted("Sound Channels"); if (ImGui::SliderInt("##Sound Channels", &Options.SoundChannels, options::MinSoundChannels, - options::MaxSoundChannels, "%d", ImGuiSliderFlags_AlwaysClamp)) + options::MaxSoundChannels, "%d", ImGuiSliderFlags_AlwaysClamp)) { Sound::SetChannels(Options.SoundChannels); } @@ -522,8 +549,9 @@ void winmain::RenderUi() options::toggle(Menu1::Music); } ImGui::TextUnformatted("Music Volume"); - if (ImGui::SliderInt("##Music Volume", &Options.MusicVolume, options::MinVolume, options::MaxVolume, "%d", - ImGuiSliderFlags_AlwaysClamp)) + if (ImGui::SliderInt("##Music Volume", &Options.MusicVolume, options::MinVolume, options::MaxVolume, + "%d", + ImGuiSliderFlags_AlwaysClamp)) { midi::SetVolume(Options.MusicVolume); } @@ -597,12 +625,16 @@ void winmain::RenderUi() char buffer[20]{}; Msg resolutionStringId = Msg::Menu1_UseMaxResolution_640x480; - switch(fullscrn::GetMaxResolution()) { - case 0: resolutionStringId = Msg::Menu1_UseMaxResolution_640x480; break; - case 1: resolutionStringId = Msg::Menu1_UseMaxResolution_800x600; break; - case 2: resolutionStringId = Msg::Menu1_UseMaxResolution_1024x768; break; + switch (fullscrn::GetMaxResolution()) + { + case 0: resolutionStringId = Msg::Menu1_UseMaxResolution_640x480; + break; + case 1: resolutionStringId = Msg::Menu1_UseMaxResolution_800x600; + break; + case 2: resolutionStringId = Msg::Menu1_UseMaxResolution_1024x768; + break; } - + auto maxResText = pb::get_rc_string(resolutionStringId); if (ImGui::MenuItem(maxResText, nullptr, Options.Resolution == -1)) { @@ -657,6 +689,8 @@ void winmain::RenderUi() { if (ImGui::MenuItem("Box Grid", nullptr, Options.DebugOverlayGrid)) Options.DebugOverlayGrid ^= true; + if (ImGui::MenuItem("Ball Depth Grid", nullptr, Options.DebugOverlayBallDepthGrid)) + Options.DebugOverlayBallDepthGrid ^= true; if (ImGui::MenuItem("Sprite Positions", nullptr, Options.DebugOverlaySprites)) Options.DebugOverlaySprites ^= true; if (ImGui::MenuItem("All Edges", nullptr, Options.DebugOverlayAllEdges)) @@ -711,7 +745,7 @@ void winmain::RenderUi() options::RenderControlDialog(); if (DispGRhistory) RenderFrameTimeDialog(); - + // Print game texts on the sidebar gdrv::grtext_draw_ttext_in_box(); } diff --git a/SpaceCadetPinball/winmain.h b/SpaceCadetPinball/winmain.h index e833755..5550a78 100644 --- a/SpaceCadetPinball/winmain.h +++ b/SpaceCadetPinball/winmain.h @@ -90,7 +90,7 @@ private: static int mouse_down, last_mouse_x, last_mouse_y; static bool no_time_loss, activated, bQuit, has_focus, DispGRhistory; static gdrv_bitmap8* gfr_display; - static std::string FpsDetails; + static std::string FpsDetails, PrevSdlError; static bool restart; static bool ShowAboutDialog; static bool ShowImGuiDemo; @@ -100,6 +100,7 @@ private: static struct optionsStruct& Options; static DurationMs SpinThreshold; static WelfordState SleepState; + static unsigned PrevSdlErrorCount; static void RenderUi(); static void RenderFrameTimeDialog();