mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-18 10:37:53 +01:00
Optimized table restart, external font loading.
Fixed memory leak related to restart. Added window to table size adjustment on init, imperfect.
This commit is contained in:
parent
6486589c4a
commit
80947888a0
7 changed files with 141 additions and 145 deletions
|
@ -5,25 +5,13 @@
|
||||||
|
|
||||||
#include "winmain.h"
|
#include "winmain.h"
|
||||||
|
|
||||||
int MainActual(LPCSTR lpCmdLine)
|
|
||||||
{
|
|
||||||
// Todo: get rid of restart to change resolution.
|
|
||||||
int returnCode;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
returnCode = winmain::WinMain(lpCmdLine);
|
|
||||||
}
|
|
||||||
while (winmain::RestartRequested());
|
|
||||||
return returnCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
std::string cmdLine;
|
std::string cmdLine;
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
cmdLine += argv[i];
|
cmdLine += argv[i];
|
||||||
|
|
||||||
return MainActual(cmdLine.c_str());
|
return winmain::WinMain(cmdLine.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
@ -32,7 +20,7 @@ int main(int argc, char* argv[])
|
||||||
// Windows subsystem main
|
// Windows subsystem main
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||||
{
|
{
|
||||||
return MainActual(lpCmdLine);
|
return winmain::WinMain(lpCmdLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fopen to _wfopen adapter, for UTF-8 paths
|
// fopen to _wfopen adapter, for UTF-8 paths
|
||||||
|
|
|
@ -43,8 +43,8 @@ void options::InitPrimary()
|
||||||
// Settings are loaded from disk on the first frame
|
// Settings are loaded from disk on the first frame
|
||||||
if (!imContext->SettingsLoaded)
|
if (!imContext->SettingsLoaded)
|
||||||
{
|
{
|
||||||
ImGui::NewFrame();
|
ImGui::LoadIniSettingsFromDisk(imContext->IO.IniFilename);
|
||||||
ImGui::EndFrame();
|
imContext->SettingsLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Options.Key = Options.KeyDft =
|
Options.Key = Options.KeyDft =
|
||||||
|
|
|
@ -360,12 +360,6 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::window_size(int* width, int* height)
|
|
||||||
{
|
|
||||||
*width = fullscrn::resolution_array[fullscrn::GetResolution()].TableWidth;
|
|
||||||
*height = fullscrn::resolution_array[fullscrn::GetResolution()].TableHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pb::pause_continue()
|
void pb::pause_continue()
|
||||||
{
|
{
|
||||||
winmain::single_step ^= true;
|
winmain::single_step ^= true;
|
||||||
|
|
|
@ -64,7 +64,6 @@ public:
|
||||||
static void ballset(float dx, float dy);
|
static void ballset(float dx, float dy);
|
||||||
static void frame(float dtMilliSec);
|
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 pause_continue();
|
static void pause_continue();
|
||||||
static void loose_focus();
|
static void loose_focus();
|
||||||
static void InputUp(GameInput input);
|
static void InputUp(GameInput input);
|
||||||
|
|
|
@ -132,6 +132,8 @@ void render::uninit()
|
||||||
delete sprite_list[0];
|
delete sprite_list[0];
|
||||||
while (!ball_list.empty())
|
while (!ball_list.empty())
|
||||||
delete ball_list[0];
|
delete ball_list[0];
|
||||||
|
for (auto& ballBmp : ball_bitmap)
|
||||||
|
delete ballBmp;
|
||||||
DebugOverlay::UnInit();
|
DebugOverlay::UnInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,6 @@ WelfordState winmain::SleepState{};
|
||||||
|
|
||||||
int winmain::WinMain(LPCSTR lpCmdLine)
|
int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
{
|
{
|
||||||
restart = false;
|
|
||||||
bQuit = false;
|
|
||||||
|
|
||||||
std::set_new_handler(memalloc_failure);
|
std::set_new_handler(memalloc_failure);
|
||||||
|
|
||||||
// SDL init
|
// SDL init
|
||||||
|
@ -101,25 +98,25 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
||||||
|
|
||||||
|
auto prefPath = SDL_GetPrefPath("", "SpaceCadetPinball");
|
||||||
|
auto basePath = SDL_GetBasePath();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
restart = false;
|
||||||
|
|
||||||
// ImGui init
|
// ImGui init
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiSDL::Initialize(renderer, 0, 0);
|
|
||||||
ImGui::StyleColorsDark();
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImIO = &io;
|
ImIO = &io;
|
||||||
|
|
||||||
auto prefPath = SDL_GetPrefPath("", "SpaceCadetPinball");
|
|
||||||
auto iniPath = std::string(prefPath) + "imgui_pb.ini";
|
auto iniPath = std::string(prefPath) + "imgui_pb.ini";
|
||||||
io.IniFilename = iniPath.c_str();
|
io.IniFilename = iniPath.c_str();
|
||||||
|
|
||||||
// First step: just load the options
|
// First option initialization step: just load settings from .ini. Needs ImGui context.
|
||||||
options::InitPrimary();
|
options::InitPrimary();
|
||||||
|
|
||||||
if (!Options.FontFileName.empty())
|
if (!Options.FontFileName.empty())
|
||||||
{
|
{
|
||||||
ImGuiSDL::Deinitialize();
|
|
||||||
io.Fonts->Clear();
|
|
||||||
ImVector<ImWchar> ranges;
|
ImVector<ImWchar> ranges;
|
||||||
translations::GetGlyphRange(&ranges);
|
translations::GetGlyphRange(&ranges);
|
||||||
ImFontConfig fontConfig{};
|
ImFontConfig fontConfig{};
|
||||||
|
@ -129,6 +126,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
fontConfig.OversampleH = 4;
|
fontConfig.OversampleH = 4;
|
||||||
|
|
||||||
// ToDo: improve font file test, checking if file exists is not enough
|
// ToDo: improve font file test, checking if file exists is not enough
|
||||||
|
auto fontLoaded = false;
|
||||||
auto fileName = Options.FontFileName.c_str();
|
auto fileName = Options.FontFileName.c_str();
|
||||||
auto fileHandle = fopenu(fileName, "rb");
|
auto fileHandle = fopenu(fileName, "rb");
|
||||||
if (fileHandle)
|
if (fileHandle)
|
||||||
|
@ -136,22 +134,22 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
fclose(fileHandle);
|
fclose(fileHandle);
|
||||||
|
|
||||||
// ToDo: Bind font size to UI scale
|
// ToDo: Bind font size to UI scale
|
||||||
if (!io.Fonts->AddFontFromFileTTF(fileName, 13.f, &fontConfig, ranges.Data))
|
if (io.Fonts->AddFontFromFileTTF(fileName, 13.f, &fontConfig, ranges.Data))
|
||||||
io.Fonts->AddFontDefault();
|
fontLoaded = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
io.Fonts->AddFontDefault();
|
|
||||||
|
|
||||||
|
if (!fontLoaded)
|
||||||
|
printf("Failed to load font: %s, using embedded font.\n", fileName);
|
||||||
io.Fonts->Build();
|
io.Fonts->Build();
|
||||||
ImGuiSDL::Initialize(renderer, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
ImGuiSDL::Initialize(renderer, 0, 0);
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
// ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend
|
// ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend
|
||||||
ImGui_ImplSDL2_InitForOpenGL(window, nullptr);
|
ImGui_ImplSDL2_InitForOpenGL(window, nullptr);
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
|
||||||
|
|
||||||
// Data search order: WD, executable path, user pref path, platform specific paths.
|
// Data search order: WD, executable path, user pref path, platform specific paths.
|
||||||
auto basePath = SDL_GetBasePath();
|
|
||||||
std::vector<const char*> searchPaths
|
std::vector<const char*> searchPaths
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -163,7 +161,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
searchPaths.insert(searchPaths.end(), std::begin(PlatformDataPaths), std::end(PlatformDataPaths));
|
searchPaths.insert(searchPaths.end(), std::begin(PlatformDataPaths), std::end(PlatformDataPaths));
|
||||||
pb::SelectDatFile(searchPaths);
|
pb::SelectDatFile(searchPaths);
|
||||||
|
|
||||||
// Second step: run updates depending on FullTiltMode
|
// Second step: run updates that depend on .DAT file selection
|
||||||
options::InitSecondary();
|
options::InitSecondary();
|
||||||
|
|
||||||
if (!Sound::Init(Options.SoundChannels, Options.Sounds, Options.SoundVolume))
|
if (!Sound::Init(Options.SoundChannels, Options.Sounds, Options.SoundVolume))
|
||||||
|
@ -198,6 +196,11 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
Options.FullScreen = true;
|
Options.FullScreen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Options.FullScreen)
|
||||||
|
{
|
||||||
|
auto resInfo = &fullscrn::resolution_array[fullscrn::GetResolution()];
|
||||||
|
SDL_SetWindowSize(MainWindow, resInfo->TableWidth, resInfo->TableHeight);
|
||||||
|
}
|
||||||
SDL_ShowWindow(window);
|
SDL_ShowWindow(window);
|
||||||
fullscrn::set_screen_mode(Options.FullScreen);
|
fullscrn::set_screen_mode(Options.FullScreen);
|
||||||
|
|
||||||
|
@ -206,12 +209,39 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
else
|
else
|
||||||
pb::replay_level(false);
|
pb::replay_level(false);
|
||||||
|
|
||||||
unsigned updateCounter = 0, frameCounter = 0;
|
MainLoop();
|
||||||
|
|
||||||
|
options::uninit();
|
||||||
|
midi::music_shutdown();
|
||||||
|
pb::uninit();
|
||||||
|
Sound::Close();
|
||||||
|
|
||||||
|
ImGuiSDL::Deinitialize();
|
||||||
|
ImGui_ImplSDL2_Shutdown();
|
||||||
|
ImGui::DestroyContext();
|
||||||
|
}
|
||||||
|
while (restart);
|
||||||
|
|
||||||
|
SDL_free(basePath);
|
||||||
|
SDL_free(prefPath);
|
||||||
|
delete gfr_display;
|
||||||
|
gfr_display = nullptr;
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void winmain::MainLoop()
|
||||||
|
{
|
||||||
|
bQuit = false;
|
||||||
|
unsigned updateCounter = 0, frameCounter = 0;
|
||||||
auto frameStart = Clock::now();
|
auto frameStart = Clock::now();
|
||||||
double UpdateToFrameCounter = 0;
|
double UpdateToFrameCounter = 0;
|
||||||
DurationMs sleepRemainder(0), frameDuration(TargetFrameTime);
|
DurationMs sleepRemainder(0), frameDuration(TargetFrameTime);
|
||||||
auto prevTime = frameStart;
|
auto prevTime = frameStart;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (DispFrameRate)
|
if (DispFrameRate)
|
||||||
|
@ -223,7 +253,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
auto elapsedSec = DurationMs(curTime - prevTime).count() * 0.001;
|
auto elapsedSec = DurationMs(curTime - prevTime).count() * 0.001;
|
||||||
snprintf(buf, sizeof buf, "Updates/sec = %02.02f Frames/sec = %02.02f ",
|
snprintf(buf, sizeof buf, "Updates/sec = %02.02f Frames/sec = %02.02f ",
|
||||||
updateCounter / elapsedSec, frameCounter / elapsedSec);
|
updateCounter / elapsedSec, frameCounter / elapsedSec);
|
||||||
SDL_SetWindowTitle(window, buf);
|
SDL_SetWindowTitle(MainWindow, buf);
|
||||||
FpsDetails = buf;
|
FpsDetails = buf;
|
||||||
frameCounter = updateCounter = 0;
|
frameCounter = updateCounter = 0;
|
||||||
prevTime = curTime;
|
prevTime = curTime;
|
||||||
|
@ -239,7 +269,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
SDL_GetMouseState(&x, &y);
|
SDL_GetMouseState(&x, &y);
|
||||||
SDL_GetWindowSize(window, &w, &h);
|
SDL_GetWindowSize(MainWindow, &w, &h);
|
||||||
float dx = static_cast<float>(last_mouse_x - x) / static_cast<float>(w);
|
float dx = static_cast<float>(last_mouse_x - x) / static_cast<float>(w);
|
||||||
float dy = static_cast<float>(y - last_mouse_y) / static_cast<float>(h);
|
float dy = static_cast<float>(y - last_mouse_y) / static_cast<float>(h);
|
||||||
pb::ballset(dx, dy);
|
pb::ballset(dx, dy);
|
||||||
|
@ -256,7 +286,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
// Mouse warp does not work over remote desktop or in some VMs
|
// Mouse warp does not work over remote desktop or in some VMs
|
||||||
x = abs(x - xMod);
|
x = abs(x - xMod);
|
||||||
y = abs(y - yMod);
|
y = abs(y - yMod);
|
||||||
SDL_WarpMouseInWindow(window, x, y);
|
SDL_WarpMouseInWindow(MainWindow, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_mouse_x = x;
|
last_mouse_x = x;
|
||||||
|
@ -297,16 +327,16 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
RenderUi();
|
RenderUi();
|
||||||
|
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(Renderer);
|
||||||
// Alternative clear hack, clear might fail on some systems
|
// Alternative clear hack, clear might fail on some systems
|
||||||
// Todo: remove original clear, if save for all platforms
|
// Todo: remove original clear, if save for all platforms
|
||||||
SDL_RenderFillRect(renderer, nullptr);
|
SDL_RenderFillRect(Renderer, nullptr);
|
||||||
render::PresentVScreen();
|
render::PresentVScreen();
|
||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGuiSDL::Render(ImGui::GetDrawData());
|
ImGuiSDL::Render(ImGui::GetDrawData());
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(Renderer);
|
||||||
frameCounter++;
|
frameCounter++;
|
||||||
UpdateToFrameCounter -= UpdateToFrameRatio;
|
UpdateToFrameCounter -= UpdateToFrameRatio;
|
||||||
}
|
}
|
||||||
|
@ -366,23 +396,6 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||||
{
|
{
|
||||||
printf("SDL Error: ^ Previous Error Repeated %u Times\n", PrevSdlErrorCount);
|
printf("SDL Error: ^ Previous Error Repeated %u Times\n", PrevSdlErrorCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free(basePath);
|
|
||||||
SDL_free(prefPath);
|
|
||||||
delete gfr_display;
|
|
||||||
gfr_display = nullptr;
|
|
||||||
options::uninit();
|
|
||||||
midi::music_shutdown();
|
|
||||||
pb::uninit();
|
|
||||||
Sound::Close();
|
|
||||||
ImGuiSDL::Deinitialize();
|
|
||||||
ImGui_ImplSDL2_Shutdown();
|
|
||||||
SDL_DestroyRenderer(renderer);
|
|
||||||
SDL_DestroyWindow(window);
|
|
||||||
ImGui::DestroyContext();
|
|
||||||
SDL_Quit();
|
|
||||||
|
|
||||||
return return_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void winmain::RenderUi()
|
void winmain::RenderUi()
|
||||||
|
@ -512,7 +525,7 @@ void winmain::RenderUi()
|
||||||
if (ImGui::MenuItem(item.DisplayName, nullptr, currentLanguage->Language == item.Language))
|
if (ImGui::MenuItem(item.DisplayName, nullptr, currentLanguage->Language == item.Language))
|
||||||
{
|
{
|
||||||
translations::SetCurrentLanguage(item.ShortName);
|
translations::SetCurrentLanguage(item.ShortName);
|
||||||
winmain::Restart();
|
Restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
|
@ -623,7 +636,7 @@ void winmain::RenderUi()
|
||||||
if (ImGui::BeginMenu(pb::get_rc_string(Msg::Menu1_Table_Resolution)))
|
if (ImGui::BeginMenu(pb::get_rc_string(Msg::Menu1_Table_Resolution)))
|
||||||
{
|
{
|
||||||
char buffer[20]{};
|
char buffer[20]{};
|
||||||
Msg resolutionStringId = Msg::Menu1_UseMaxResolution_640x480;
|
auto resolutionStringId = Msg::Menu1_UseMaxResolution_640x480;
|
||||||
|
|
||||||
switch (fullscrn::GetMaxResolution())
|
switch (fullscrn::GetMaxResolution())
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,7 +83,6 @@ public:
|
||||||
static void new_game();
|
static void new_game();
|
||||||
static void pause(bool toggle = true);
|
static void pause(bool toggle = true);
|
||||||
static void Restart();
|
static void Restart();
|
||||||
static bool RestartRequested() { return restart; }
|
|
||||||
static void UpdateFrameRate();
|
static void UpdateFrameRate();
|
||||||
private:
|
private:
|
||||||
static int return_value, DispFrameRate;
|
static int return_value, DispFrameRate;
|
||||||
|
@ -105,4 +104,5 @@ private:
|
||||||
static void RenderUi();
|
static void RenderUi();
|
||||||
static void RenderFrameTimeDialog();
|
static void RenderFrameTimeDialog();
|
||||||
static void HybridSleep(DurationMs seconds);
|
static void HybridSleep(DurationMs seconds);
|
||||||
|
static void MainLoop();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue