From 8e07b7fc3fea6ab06154a18eaf77432c131adafd Mon Sep 17 00:00:00 2001 From: Desgging <1397755924@qq.com> Date: Sat, 23 Oct 2021 12:31:25 +0800 Subject: [PATCH 1/3] Full Tilt hack - ball doesn't delay at ramp hole (#63) --- SpaceCadetPinball/THole.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SpaceCadetPinball/THole.cpp b/SpaceCadetPinball/THole.cpp index 53bab24..531e1df 100644 --- a/SpaceCadetPinball/THole.cpp +++ b/SpaceCadetPinball/THole.cpp @@ -81,7 +81,15 @@ void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc ball->Position.X = Circle.Center.X; ball->Position.Y = Circle.Center.Y; ball->Acceleration.Z = 0.0; - Timer = timer::set(0.5f, this, TimerExpired); + /*Full Tilt hack - ball doesn't delay at the ramp hole*/ + if (pb::FullTiltMode) + { + BallCapturedSecondStage = 1; + } + else + { + Timer = timer::set(0.5f, this, TimerExpired); + } if (!PinballTable->TiltLockFlag) { loader::play_sound(HardHitSoundId); From 57af3af80052cdf674ae9fff1a4fd5db0e1ec7d2 Mon Sep 17 00:00:00 2001 From: toxie Date: Sat, 23 Oct 2021 06:33:04 +0200 Subject: [PATCH 2/3] Increase precision of mode_countdown_ handling (#52) * fix harmless warnings and properly try/catch allocations via new otherwise the error handling will never be triggered * increase precision of mode_countdown_ handling potentially there could be modes running a bit too long, depending on passed in ms (which were implicitly truncated before when passing in) also fix some harmless warnings * document warnings that i cannot handle on my own * revert changes to have a new cleaner PR after review/cherry picks * increase precision of mode_countdown_ handling potentially there could be modes running a bit too long, depending on passed in ms (which were implicitly truncated before when passing in) also fix some harmless warnings and add comments where original code is 'correct' but weird --- SpaceCadetPinball/TBall.cpp | 2 +- SpaceCadetPinball/TFlipper.cpp | 2 +- SpaceCadetPinball/TFlipperEdge.cpp | 1 - SpaceCadetPinball/TLightGroup.cpp | 2 +- SpaceCadetPinball/TPinballTable.cpp | 2 +- SpaceCadetPinball/TPlunger.cpp | 4 ++-- SpaceCadetPinball/TTripwire.cpp | 2 +- SpaceCadetPinball/control.cpp | 3 +-- SpaceCadetPinball/maths.cpp | 2 +- SpaceCadetPinball/maths.h | 2 +- SpaceCadetPinball/pb.cpp | 18 +++++++++--------- SpaceCadetPinball/pb.h | 5 +++-- SpaceCadetPinball/render.cpp | 2 +- SpaceCadetPinball/winmain.cpp | 8 ++++---- 14 files changed, 27 insertions(+), 28 deletions(-) diff --git a/SpaceCadetPinball/TBall.cpp b/SpaceCadetPinball/TBall.cpp index 25dd48f..b086594 100644 --- a/SpaceCadetPinball/TBall.cpp +++ b/SpaceCadetPinball/TBall.cpp @@ -40,7 +40,7 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false) Offset = *loader::query_float_attribute(groupIndex, 0, 500); auto visualCount = loader::query_visual_states(groupIndex); - auto index = 0; + int index = 0; if (visualCount > 0) { auto visualZPtr = VisualZArray; diff --git a/SpaceCadetPinball/TFlipper.cpp b/SpaceCadetPinball/TFlipper.cpp index 94999e5..a227c92 100644 --- a/SpaceCadetPinball/TFlipper.cpp +++ b/SpaceCadetPinball/TFlipper.cpp @@ -65,7 +65,7 @@ TFlipper::~TFlipper() int TFlipper::Message(int code, float value) { - if (code == 1 || code == 2 || code > 1008 && code <= 1011 || code == 1022) + if (code == 1 || code == 2 || (code > 1008 && code <= 1011) || code == 1022) { float timerTime; int command = code; diff --git a/SpaceCadetPinball/TFlipperEdge.cpp b/SpaceCadetPinball/TFlipperEdge.cpp index 151dc50..3d3821d 100644 --- a/SpaceCadetPinball/TFlipperEdge.cpp +++ b/SpaceCadetPinball/TFlipperEdge.cpp @@ -109,7 +109,6 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray) { if (FlipperFlag == 0) { - EdgeCollisionFlag = 0; CollisionFlag1 = 0; CollisionFlag2 = 0; set_control_points(ogRay->TimeNow); diff --git a/SpaceCadetPinball/TLightGroup.cpp b/SpaceCadetPinball/TLightGroup.cpp index 2cc1dee..616a906 100644 --- a/SpaceCadetPinball/TLightGroup.cpp +++ b/SpaceCadetPinball/TLightGroup.cpp @@ -432,7 +432,7 @@ int TLightGroup::next_light_up() { for (auto index = 0u; index < List.size(); ++index) { - if (!List.at(index)->BmpIndex1) + if (!List[index]->BmpIndex1) return static_cast(index); } return -1; diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp index 62148f7..810e9c2 100644 --- a/SpaceCadetPinball/TPinballTable.cpp +++ b/SpaceCadetPinball/TPinballTable.cpp @@ -368,7 +368,7 @@ int TPinballTable::Message(int code, float value) LightGroup->Message(34, 0.0); LightGroup->Message(20, 0.0); Plunger->Message(1016, 0.0); - if (Demo->ActiveFlag) + if (Demo && Demo->ActiveFlag) rc_text = pinball::get_rc_string(30, 0); else rc_text = pinball::get_rc_string(26, 0); diff --git a/SpaceCadetPinball/TPlunger.cpp b/SpaceCadetPinball/TPlunger.cpp index eb289a3..db9a1ca 100644 --- a/SpaceCadetPinball/TPlunger.cpp +++ b/SpaceCadetPinball/TPlunger.cpp @@ -37,7 +37,7 @@ void TPlunger::Collision(TBall* ball, vector_type* nextPosition, vector_type* di { if (PinballTable->TiltLockFlag) Message(1017, 0.0); - coef = RandFloat() * Boost * 0.1f + Boost; + coef = RandFloat() * Boost * 0.1f + Boost; // it is intended that the passed in coef is never used! maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, coef); } @@ -94,7 +94,7 @@ int TPlunger::Message(int code, float value) if (PullbackTimer_) timer::kill(PullbackTimer_); PullbackTimer_ = 0; - if (code == 1005) + if (code == 1005) // intended that this can never be reached (same as original) loader::play_sound(SoundIndexP2); auto bmp = ListBitmap->at(0); auto zMap = ListZMap->at(0); diff --git a/SpaceCadetPinball/TTripwire.cpp b/SpaceCadetPinball/TTripwire.cpp index 46bdacc..bc34094 100644 --- a/SpaceCadetPinball/TTripwire.cpp +++ b/SpaceCadetPinball/TTripwire.cpp @@ -6,7 +6,7 @@ #include "TBall.h" #include "TPinballTable.h" -TTripwire::TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, 1) +TTripwire::TTripwire(TPinballTable* table, int groupIndex) : TRollover(table, groupIndex, true) { } diff --git a/SpaceCadetPinball/control.cpp b/SpaceCadetPinball/control.cpp index 56d8a3b..dc41ae2 100644 --- a/SpaceCadetPinball/control.cpp +++ b/SpaceCadetPinball/control.cpp @@ -3923,9 +3923,7 @@ void control::SelectMissionController(int code, TPinballComponent* caller) if (light_on(&control_lite319_tag)) control_lite319_tag.Component->Message(20, 0.0); if (!light_on(&control_lite317_tag)) - { control_lite317_tag.Component->Message(7, 0.0); - } } else { @@ -4158,6 +4156,7 @@ void control::TimeWarpPartTwoController(int code, TPinballComponent* caller) control_lite317_tag.Component->Message(20, 0.0); control_lite198_tag.Component->MessageField = 1; MissionControl(66, nullptr); + // SpecialAddScore sets the score dirty flag. So next tick it will be redrawn. } void control::UnselectMissionController(int code, TPinballComponent* caller) diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index 7df44a4..bb41669 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -299,7 +299,7 @@ float maths::basic_collision(TBall* ball, vector_type* nextPosition, vector_type return projSpeed; } -float maths::Distance_Squared(vector_type vec1, vector_type vec2) +float maths::Distance_Squared(vector_type& vec1, vector_type& vec2) { return (vec1.Y - vec2.Y) * (vec1.Y - vec2.Y) + (vec1.X - vec2.X) * (vec1.X - vec2.X); } diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index a975463..3e0d767 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -87,7 +87,7 @@ public: static float basic_collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float elasticity, float smoothness, float threshold, float boost); - static float Distance_Squared(vector_type vec1, vector_type vec2); + static float Distance_Squared(vector_type& vec1, vector_type& vec2); static float DotProduct(vector_type* vec1, vector_type* vec2); static void vswap(vector_type* vec1, vector_type* vec2); static float Distance(vector_type* vec1, vector_type* vec2); diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index 95f45e5..4087d93 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -29,8 +29,8 @@ TPinballTable* pb::MainTable = nullptr; DatFile* pb::record_table = nullptr; -int pb::time_ticks = 0, pb::demo_mode = 0, pb::game_mode = 2, pb::mode_countdown_; -float pb::time_now = 0, pb::time_next = 0, pb::ball_speed_limit, pb::time_ticks_remainder = 0; +int pb::time_ticks = 0, pb::demo_mode = 0, pb::game_mode = 2; +float pb::mode_countdown_, pb::time_now = 0, pb::time_next = 0, pb::ball_speed_limit, pb::time_ticks_remainder = 0; high_score_struct pb::highscore_table[5]; bool pb::FullTiltMode = false, pb::cheat_mode = false; @@ -169,7 +169,7 @@ void pb::mode_change(int mode) case 4: winmain::LaunchBallEnabled = false; winmain::HighScoresEnabled = false; - mode_countdown_ = 5000; + mode_countdown_ = 5000.f; break; } game_mode = mode; @@ -317,7 +317,7 @@ void pb::window_size(int* width, int* height) void pb::pause_continue() { - winmain::single_step = winmain::single_step == 0; + winmain::single_step = (winmain::single_step == 0) ? 1 : 0; pinball::InfoTextBox->Clear(); pinball::MissTextBox->Clear(); if (winmain::single_step) @@ -399,7 +399,7 @@ void pb::InputDown(GameInput input) if (game_mode != 1) { - mode_countdown(-1); + mode_countdown(-1.f); return; } @@ -485,7 +485,7 @@ void pb::InputDown(GameInput input) } } -int pb::mode_countdown(int time) +int pb::mode_countdown(float time) { if (!game_mode || game_mode <= 0) return 1; @@ -494,13 +494,13 @@ int pb::mode_countdown(int time) if (game_mode == 3) { mode_countdown_ -= time; - if (mode_countdown_ < 0 || time < 0) + if (mode_countdown_ < 0.f || time < 0.f) mode_change(4); } else if (game_mode == 4) { mode_countdown_ -= time; - if (mode_countdown_ < 0 || time < 0) + if (mode_countdown_ < 0.f || time < 0.f) mode_change(1); } return 1; @@ -532,7 +532,7 @@ void pb::end_game() for (auto i = 0; i < playerCount; ++i) { - for (auto j = i; j < playerCount; ++j) + for (auto j = i+1; j < playerCount; ++j) { if (scores[j] > scores[i]) { diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index 0139db2..e787dc4 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -57,7 +57,7 @@ public: static void loose_focus(); static void InputUp(GameInput input); static void InputDown(GameInput input); - static int mode_countdown(int time); + static int mode_countdown(float time); static void launch_ball(); static void end_game(); static void high_scores(); @@ -66,7 +66,8 @@ public: static float collide(float timeNow, float timeDelta, TBall* ball); static void PushCheat(const std::string& cheat); private: - static int demo_mode, mode_countdown_; + static int demo_mode; + static float mode_countdown_; static bool AnyBindingMatchesInput(GameInput (&options)[3], GameInput key); }; diff --git a/SpaceCadetPinball/render.cpp b/SpaceCadetPinball/render.cpp index 30d6b35..40d0bb6 100644 --- a/SpaceCadetPinball/render.cpp +++ b/SpaceCadetPinball/render.cpp @@ -420,7 +420,7 @@ void render::build_occlude_list() } } - if (!mainSprite->UnknownFlag && mainSprite->Bmp && spriteArr->size() < 2) + if (mainSprite->Bmp && spriteArr->size() < 2) spriteArr->clear(); if (!spriteArr->empty()) { diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index cef4dbe..f8926bc 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -180,7 +180,7 @@ int winmain::WinMain(LPCSTR lpCmdLine) if (!gfr_display) { auto plt = static_cast(malloc(1024u)); - auto pltPtr = &plt[10]; + auto pltPtr = &plt[10]; // first 10 entries are system colors hardcoded in display_palette() for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8) { unsigned char blue = i2, redGreen = i2; @@ -215,8 +215,8 @@ int winmain::WinMain(LPCSTR lpCmdLine) int x, y, w, h; SDL_GetMouseState(&x, &y); SDL_GetWindowSize(window, &w, &h); - float dx = (last_mouse_x - x) / static_cast(w); - float dy = (y - last_mouse_y) / static_cast(h); + float dx = static_cast(last_mouse_x - x) / static_cast(w); + float dy = static_cast(y - last_mouse_y) / static_cast(h); pb::ballset(dx, dy); SDL_WarpMouseInWindow(window, last_mouse_x, last_mouse_y); @@ -655,7 +655,7 @@ int winmain::event_handler(const SDL_Event* event) pb::frame(10); break; case SDLK_F10: - single_step = single_step == 0; + single_step = (single_step == 0) ? 1 : 0; if (single_step == 0) no_time_loss = 1; break; From 5cd01807b2737103845c4977ced36857159e3b1f Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Sat, 23 Oct 2021 09:02:51 +0300 Subject: [PATCH 3/3] winmain: converted int to bool. Cleaned up some of the PR changes. --- SpaceCadetPinball/TBall.cpp | 23 ++++++++-------------- SpaceCadetPinball/THole.cpp | 14 +++++--------- SpaceCadetPinball/TPlunger.cpp | 2 +- SpaceCadetPinball/pb.cpp | 6 +++--- SpaceCadetPinball/winmain.cpp | 35 +++++++++++++++++----------------- SpaceCadetPinball/winmain.h | 7 ++++--- 6 files changed, 39 insertions(+), 48 deletions(-) diff --git a/SpaceCadetPinball/TBall.cpp b/SpaceCadetPinball/TBall.cpp index b086594..4b37e92 100644 --- a/SpaceCadetPinball/TBall.cpp +++ b/SpaceCadetPinball/TBall.cpp @@ -39,23 +39,16 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false) auto groupIndex = loader::query_handle(ballGroupName); Offset = *loader::query_float_attribute(groupIndex, 0, 500); + auto visualCount = loader::query_visual_states(groupIndex); - int index = 0; - if (visualCount > 0) + for (auto index = 0; index < visualCount; ++index) { - auto visualZPtr = VisualZArray; - do - { - loader::query_visual(groupIndex, index, &visual); - if (ListBitmap) - ListBitmap->push_back(visual.Bitmap); - auto visVec = reinterpret_cast(loader::query_float_attribute(groupIndex, index, 501)); - auto zDepth = proj::z_distance(visVec); - ++index; - *visualZPtr = zDepth; - ++visualZPtr; - } - while (index < visualCount); + loader::query_visual(groupIndex, index, &visual); + if (ListBitmap) + ListBitmap->push_back(visual.Bitmap); + auto visVec = reinterpret_cast(loader::query_float_attribute(groupIndex, index, 501)); + auto zDepth = proj::z_distance(visVec); + VisualZArray[index] = zDepth; } RenderSprite = render::create_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr); PinballTable->CollisionCompOffset = Offset; diff --git a/SpaceCadetPinball/THole.cpp b/SpaceCadetPinball/THole.cpp index 531e1df..49d1321 100644 --- a/SpaceCadetPinball/THole.cpp +++ b/SpaceCadetPinball/THole.cpp @@ -81,15 +81,11 @@ void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direc ball->Position.X = Circle.Center.X; ball->Position.Y = Circle.Center.Y; ball->Acceleration.Z = 0.0; - /*Full Tilt hack - ball doesn't delay at the ramp hole*/ - if (pb::FullTiltMode) - { - BallCapturedSecondStage = 1; - } - else - { - Timer = timer::set(0.5f, this, TimerExpired); - } + + // Ramp hole has no delay in FT. + auto captureTime = pb::FullTiltMode ? 0 : 0.5f; + Timer = timer::set(captureTime, this, TimerExpired); + if (!PinballTable->TiltLockFlag) { loader::play_sound(HardHitSoundId); diff --git a/SpaceCadetPinball/TPlunger.cpp b/SpaceCadetPinball/TPlunger.cpp index db9a1ca..488cd9c 100644 --- a/SpaceCadetPinball/TPlunger.cpp +++ b/SpaceCadetPinball/TPlunger.cpp @@ -94,7 +94,7 @@ int TPlunger::Message(int code, float value) if (PullbackTimer_) timer::kill(PullbackTimer_); PullbackTimer_ = 0; - if (code == 1005) // intended that this can never be reached (same as original) + if (code == 1005) loader::play_sound(SoundIndexP2); auto bmp = ListBitmap->at(0); auto zMap = ListZMap->at(0); diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index 4087d93..284ef7e 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -215,7 +215,7 @@ void pb::frame(float dtMilliSec) { if (dtMilliSec > 100) dtMilliSec = 100; - if (dtMilliSec < 0) + if (dtMilliSec <= 0) return; float dtSec = dtMilliSec * 0.001f; if (!mode_countdown(dtMilliSec)) @@ -317,7 +317,7 @@ void pb::window_size(int* width, int* height) void pb::pause_continue() { - winmain::single_step = (winmain::single_step == 0) ? 1 : 0; + winmain::single_step ^= true; pinball::InfoTextBox->Clear(); pinball::MissTextBox->Clear(); if (winmain::single_step) @@ -532,7 +532,7 @@ void pb::end_game() for (auto i = 0; i < playerCount; ++i) { - for (auto j = i+1; j < playerCount; ++j) + for (auto j = i + 1; j < playerCount; ++j) { if (scores[j] > scores[i]) { diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index f8926bc..83dfc66 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -15,16 +15,16 @@ SDL_Renderer* winmain::Renderer = nullptr; ImGuiIO* winmain::ImIO = nullptr; int winmain::return_value = 0; -int winmain::bQuit = 0; -int winmain::activated; +bool winmain::bQuit = false; +bool winmain::activated = false; int winmain::DispFrameRate = 0; int winmain::DispGRhistory = 0; -int winmain::single_step = 0; -int winmain::has_focus = 1; +bool winmain::single_step = false; +bool winmain::has_focus = true; int winmain::last_mouse_x; int winmain::last_mouse_y; int winmain::mouse_down; -int winmain::no_time_loss; +bool winmain::no_time_loss = false; bool winmain::restart = false; @@ -225,7 +225,7 @@ int winmain::WinMain(LPCSTR lpCmdLine) //last_mouse_x = x; //last_mouse_y = y; } - if (!single_step) + if (!single_step && !no_time_loss) { auto dt = static_cast(frameDuration.count()); auto dtWhole = static_cast(std::round(dt)); @@ -243,6 +243,7 @@ int winmain::WinMain(LPCSTR lpCmdLine) } updateCounter++; } + no_time_loss = false; if (UpdateToFrameCounter >= UpdateToFrameRatio) { @@ -595,7 +596,7 @@ int winmain::event_handler(const SDL_Event* event) { case SDL_QUIT: end_pause(); - bQuit = 1; + bQuit = true; fullscrn::shutdown(); return_value = 0; return 0; @@ -655,9 +656,9 @@ int winmain::event_handler(const SDL_Event* event) pb::frame(10); break; case SDLK_F10: - single_step = (single_step == 0) ? 1 : 0; - if (single_step == 0) - no_time_loss = 1; + single_step ^= true; + if (!single_step) + no_time_loss = true; break; default: break; @@ -713,21 +714,21 @@ int winmain::event_handler(const SDL_Event* event) case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_TAKE_FOCUS: case SDL_WINDOWEVENT_SHOWN: - activated = 1; + activated = true; Sound::Activate(); if (Options.Music && !single_step) midi::play_pb_theme(); - no_time_loss = 1; - has_focus = 1; + no_time_loss = true; + has_focus = true; break; case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_WINDOWEVENT_HIDDEN: - activated = 0; + activated = false; fullscrn::activate(0); Options.FullScreen = false; Sound::Deactivate(); midi::music_stop(); - has_focus = 0; + has_focus = false; pb::loose_focus(); break; case SDL_WINDOWEVENT_SIZE_CHANGED: @@ -846,7 +847,7 @@ void winmain::end_pause() if (single_step) { pb::pause_continue(); - no_time_loss = 1; + no_time_loss = true; } } @@ -859,7 +860,7 @@ void winmain::new_game() void winmain::pause() { pb::pause_continue(); - no_time_loss = 1; + no_time_loss = true; } void winmain::Restart() diff --git a/SpaceCadetPinball/winmain.h b/SpaceCadetPinball/winmain.h index fc75257..b83369c 100644 --- a/SpaceCadetPinball/winmain.h +++ b/SpaceCadetPinball/winmain.h @@ -41,7 +41,7 @@ class winmain public: static std::string DatFileName; - static int single_step; + static bool single_step; static SDL_Window* MainWindow; static SDL_Renderer* Renderer; static ImGuiIO* ImIO; @@ -62,8 +62,9 @@ public: static bool RestartRequested() { return restart; } static void UpdateFrameRate(); 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 int return_value, DispFrameRate, DispGRhistory; + static int mouse_down, last_mouse_x, last_mouse_y; + static bool no_time_loss, activated, bQuit, has_focus; static gdrv_bitmap8* gfr_display; static std::string FpsDetails; static bool restart;