Added “Prefer 3DPB game data” option.

Useful for quickly switching between the two datasets.
3DPB and FT data can be stored in one folder without collisions.
This commit is contained in:
Muzychenko Andrey 2021-11-21 15:40:56 +03:00
parent 3b7dc0dae2
commit 64c3f2031b
9 changed files with 102 additions and 71 deletions

View File

@ -26,7 +26,7 @@ const ControlRef options::Controls[6]
}; };
void options::init() void options::InitPrimary()
{ {
auto imContext = ImGui::GetCurrentContext(); auto imContext = ImGui::GetCurrentContext();
ImGuiSettingsHandler ini_handler; ImGuiSettingsHandler ini_handler;
@ -100,7 +100,11 @@ void options::init()
Options.SoundChannels = get_int("Sound Channels", DefSoundChannels); Options.SoundChannels = get_int("Sound Channels", DefSoundChannels);
Options.SoundChannels = std::min(MaxSoundChannels, std::max(MinSoundChannels, Options.SoundChannels)); Options.SoundChannels = std::min(MaxSoundChannels, std::max(MinSoundChannels, Options.SoundChannels));
Options.HybridSleep = get_int("HybridSleep", false); Options.HybridSleep = get_int("HybridSleep", false);
Options.Prefer3DPBGameData = get_int("Prefer 3DPB Game Data", false);
}
void options::InitSecondary()
{
winmain::UpdateFrameRate(); winmain::UpdateFrameRate();
auto maxRes = fullscrn::GetMaxResolution(); auto maxRes = fullscrn::GetMaxResolution();
@ -132,6 +136,7 @@ void options::uninit()
set_int("Uncapped Updates Per Second", Options.UncappedUpdatesPerSecond); set_int("Uncapped Updates Per Second", Options.UncappedUpdatesPerSecond);
set_int("Sound Channels", Options.SoundChannels); set_int("Sound Channels", Options.SoundChannels);
set_int("HybridSleep", Options.HybridSleep); set_int("HybridSleep", Options.HybridSleep);
set_int("Prefer 3DPB Game Data", Options.Prefer3DPBGameData);
} }
@ -251,6 +256,10 @@ void options::toggle(Menu1 uIDCheckItem)
Options.LinearFiltering ^= true; Options.LinearFiltering ^= true;
render::recreate_screen_texture(); render::recreate_screen_texture();
break; break;
case Menu1::Prefer3DPBGameData:
Options.Prefer3DPBGameData ^= true;
winmain::Restart();
break;
default: default:
break; break;
} }

View File

@ -26,6 +26,7 @@ enum class Menu1:int
R1024x768 = 503, R1024x768 = 503,
WindowUniformScale = 600, WindowUniformScale = 600,
WindowLinearFilter = 601, WindowLinearFilter = 601,
Prefer3DPBGameData = 700,
}; };
enum class InputTypes: unsigned enum class InputTypes: unsigned
@ -74,6 +75,7 @@ struct optionsStruct
bool UncappedUpdatesPerSecond; bool UncappedUpdatesPerSecond;
int SoundChannels; int SoundChannels;
bool HybridSleep; bool HybridSleep;
bool Prefer3DPBGameData;
}; };
struct ControlRef struct ControlRef
@ -93,7 +95,8 @@ public:
static constexpr int MaxSoundChannels = 32, MinSoundChannels = 1, DefSoundChannels = 8; static constexpr int MaxSoundChannels = 32, MinSoundChannels = 1, DefSoundChannels = 8;
static optionsStruct Options; static optionsStruct Options;
static void init(); static void InitPrimary();
static void InitSecondary();
static void uninit(); static void uninit();
static int get_int(LPCSTR lpValueName, int defaultValue); static int get_int(LPCSTR lpValueName, int defaultValue);
static void set_int(LPCSTR lpValueName, int data); static void set_int(LPCSTR lpValueName, int data);

View File

@ -33,15 +33,16 @@ 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; 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]; high_score_struct pb::highscore_table[5];
bool pb::FullTiltMode = false, pb::cheat_mode = false; bool pb::FullTiltMode = false, pb::cheat_mode = false;
std::string pb::DatFileName;
int pb::init() int pb::init()
{ {
float projMat[12], zMin = 0, zScaler = 0; float projMat[12], zMin = 0, zScaler = 0;
if (winmain::DatFileName.empty()) if (DatFileName.empty())
return 1; return 1;
auto dataFilePath = pinball::make_path_name(winmain::DatFileName); auto dataFilePath = pinball::make_path_name(DatFileName);
record_table = partman::load_records(dataFilePath.c_str(), FullTiltMode); record_table = partman::load_records(dataFilePath.c_str(), FullTiltMode);
auto useBmpFont = 0; auto useBmpFont = 0;
@ -117,6 +118,42 @@ int pb::uninit()
return 0; return 0;
} }
void pb::SelectDatFile(std::array<char*, 2> dataSearchPaths)
{
DatFileName.clear();
std::string datFileNames[2]
{
"CADET.DAT",
options::get_string("Pinball Data", pinball::get_rc_string(168, 0))
};
// Default game data test order: CADET.DAT, PINBALL.DAT
if (options::Options.Prefer3DPBGameData)
std::swap(datFileNames[0], datFileNames[1]);
for (auto path : dataSearchPaths)
{
if (DatFileName.empty() && path)
{
pinball::BasePath = path;
for (int i = 0; i < 2; i++)
{
auto datFileName = datFileNames[i];
auto datFilePath = pinball::make_path_name(datFileName);
auto datFile = fopenu(datFilePath.c_str(), "r");
if (datFile)
{
fclose(datFile);
DatFileName = datFileName;
FullTiltMode = datFileName == "CADET.DAT";
printf("Loading game from: %s\n", datFilePath.c_str());
break;
}
}
}
}
}
void pb::reset_table() void pb::reset_table()
{ {
if (MainTable) if (MainTable)

View File

@ -41,9 +41,11 @@ public:
static TPinballTable* MainTable; static TPinballTable* MainTable;
static high_score_struct highscore_table[5]; static high_score_struct highscore_table[5];
static bool FullTiltMode; static bool FullTiltMode;
static std::string DatFileName;
static int init(); static int init();
static int uninit(); static int uninit();
static void SelectDatFile(std::array<char*, 2> dataSearchPaths);
static void reset_table(); static void reset_table();
static void firsttime_setup(); static void firsttime_setup();
static void mode_change(int mode); static void mode_change(int mode);

View File

@ -29,6 +29,7 @@
#include <string> #include <string>
#include <thread> #include <thread>
#include <map> #include <map>
#include <array>
#define SDL_MAIN_HANDLED #define SDL_MAIN_HANDLED
#include "SDL.h" #include "SDL.h"

View File

@ -224,6 +224,7 @@ char pinball::getRcBuffer[6 * 256];
int pinball::rc_string_slot = 0; int pinball::rc_string_slot = 0;
int pinball::LeftShift = -1; int pinball::LeftShift = -1;
int pinball::RightShift = -1; int pinball::RightShift = -1;
std::string pinball::BasePath;
char* pinball::get_rc_string(int uID, int a2) char* pinball::get_rc_string(int uID, int a2)
{ {
@ -247,5 +248,5 @@ int pinball::get_rc_int(int uID, int* dst)
std::string pinball::make_path_name(const std::string& fileName) std::string pinball::make_path_name(const std::string& fileName)
{ {
return winmain::BasePath + fileName; return BasePath + fileName;
} }

View File

@ -10,6 +10,7 @@ public:
static TTextBox* MissTextBox; static TTextBox* MissTextBox;
static int RightShift; static int RightShift;
static int LeftShift; static int LeftShift;
static std::string BasePath;
static char* get_rc_string(int uID, int a2); static char* get_rc_string(int uID, int a2);
static int get_rc_int(int uID, int* dst); static int get_rc_int(int uID, int* dst);

View File

@ -29,14 +29,12 @@ bool winmain::no_time_loss = false;
bool winmain::restart = false; bool winmain::restart = false;
gdrv_bitmap8* winmain::gfr_display = nullptr; gdrv_bitmap8* winmain::gfr_display = nullptr;
std::string winmain::DatFileName;
bool winmain::ShowAboutDialog = false; bool winmain::ShowAboutDialog = false;
bool winmain::ShowImGuiDemo = false; bool winmain::ShowImGuiDemo = false;
bool winmain::ShowSpriteViewer = false; bool winmain::ShowSpriteViewer = false;
bool winmain::LaunchBallEnabled = true; bool winmain::LaunchBallEnabled = true;
bool winmain::HighScoresEnabled = true; bool winmain::HighScoresEnabled = true;
bool winmain::DemoActive = false; bool winmain::DemoActive = false;
std::string winmain::BasePath;
int winmain::MainMenuHeight = 0; int winmain::MainMenuHeight = 0;
std::string winmain::FpsDetails; std::string winmain::FpsDetails;
double winmain::UpdateToFrameRatio; double winmain::UpdateToFrameRatio;
@ -63,43 +61,6 @@ int winmain::WinMain(LPCSTR lpCmdLine)
pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr; pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr;
// Search for game data in: game folder, user folder
// Game data test order: CADET.DAT, PINBALL.DAT
char* dataSearchPaths[2]
{
SDL_GetBasePath(),
SDL_GetPrefPath(nullptr, "SpaceCadetPinball")
};
std::string datFileNames[2]
{
"CADET.DAT",
options::get_string("Pinball Data", pinball::get_rc_string(168, 0))
};
for (auto path : dataSearchPaths)
{
if (DatFileName.empty() && path)
{
BasePath = path;
for (int i = 0; i < 2; i++)
{
auto datFileName = datFileNames[i];
auto datFilePath = pinball::make_path_name(datFileName);
auto datFile = fopenu(datFilePath.c_str(), "r");
if (datFile)
{
fclose(datFile);
DatFileName = datFileName;
if (i == 0)
pb::FullTiltMode = true;
printf("Loading game from: %s\n", datFilePath.c_str());
break;
}
}
}
SDL_free(path);
}
// SDL window // SDL window
SDL_Window* window = SDL_CreateWindow SDL_Window* window = SDL_CreateWindow
( (
@ -152,27 +113,32 @@ int winmain::WinMain(LPCSTR lpCmdLine)
auto prefPath = SDL_GetPrefPath(nullptr, "SpaceCadetPinball"); auto prefPath = SDL_GetPrefPath(nullptr, "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();
SDL_free(prefPath);
// PB init from message handler // First step: just load the options, second: run updates depending on FullTiltMode
options::InitPrimary();
auto basePath = SDL_GetBasePath();
pb::SelectDatFile(std::array<char*, 2>
{ {
options::init(); basePath,
if (!Sound::Init(Options.SoundChannels, Options.Sounds)) prefPath
Options.Sounds = false; });
options::InitSecondary();
if (!pinball::quickFlag && !midi::music_init()) if (!Sound::Init(Options.SoundChannels, Options.Sounds))
Options.Music = false; Options.Sounds = false;
if (pb::init()) if (!pinball::quickFlag && !midi::music_init())
{ Options.Music = false;
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not load game data",
"The .dat file is missing", window);
return 1;
}
fullscrn::init(); if (pb::init())
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not load game data",
"The .dat file is missing", window);
return 1;
} }
fullscrn::init();
pb::reset_table(); pb::reset_table();
pb::firsttime_setup(); pb::firsttime_setup();
@ -249,7 +215,8 @@ int winmain::WinMain(LPCSTR lpCmdLine)
gdrv::ScrollBitmapHorizontal(gfr_display, -1); gdrv::ScrollBitmapHorizontal(gfr_display, -1);
gdrv::fill_bitmap(gfr_display, 1, halfHeight, width - 1, 0, ColorRgba::Black()); // Background gdrv::fill_bitmap(gfr_display, 1, halfHeight, width - 1, 0, ColorRgba::Black()); // Background
gdrv::fill_bitmap(gfr_display, 1, halfHeight, width - 1, halfHeight, ColorRgba::White()); // Target // Target
gdrv::fill_bitmap(gfr_display, 1, halfHeight, width - 1, halfHeight, ColorRgba::White());
auto target = static_cast<float>(TargetFrameTime.count()); auto target = static_cast<float>(TargetFrameTime.count());
auto scale = halfHeight / target; auto scale = halfHeight / target;
@ -303,13 +270,16 @@ int winmain::WinMain(LPCSTR lpCmdLine)
} }
// Limit duration to 2 * target time // Limit duration to 2 * target time
sleepRemainder = std::max(std::min(DurationMs(frameEnd - updateEnd) - targetTimeDelta, TargetFrameTime), -TargetFrameTime); sleepRemainder = std::max(std::min(DurationMs(frameEnd - updateEnd) - targetTimeDelta, TargetFrameTime),
-TargetFrameTime);
frameDuration = std::min<DurationMs>(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime); frameDuration = std::min<DurationMs>(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime);
frameStart = frameEnd; frameStart = frameEnd;
UpdateToFrameCounter++; UpdateToFrameCounter++;
} }
} }
SDL_free(basePath);
SDL_free(prefPath);
delete gfr_display; delete gfr_display;
gfr_display = nullptr; gfr_display = nullptr;
options::uninit(); options::uninit();
@ -352,7 +322,7 @@ void winmain::RenderUi()
// This window can not loose nav focus for some reason, clear it manually. // This window can not loose nav focus for some reason, clear it manually.
if (ImGui::IsNavInputDown(ImGuiNavInput_Cancel)) if (ImGui::IsNavInputDown(ImGuiNavInput_Cancel))
ImGui::FocusWindow(NULL); ImGui::FocusWindow(nullptr);
} }
// No demo window in release to save space // No demo window in release to save space
@ -539,6 +509,15 @@ void winmain::RenderUi()
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Game Data"))
{
if (ImGui::MenuItem("Prefer 3DPB Data", nullptr, Options.Prefer3DPBGameData))
{
options::toggle(Menu1::Prefer3DPBGameData);
}
ImGui::EndMenu();
}
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -705,7 +684,7 @@ int winmain::event_handler(const SDL_Event* event)
redGreen = i1; redGreen = i1;
} }
*pltPtr++ = ColorRgba{ blue, redGreen, redGreen, 0 }; *pltPtr++ = ColorRgba{blue, redGreen, redGreen, 0};
} }
gdrv::display_palette(plt); gdrv::display_palette(plt);
delete[] plt; delete[] plt;
@ -826,11 +805,11 @@ int winmain::event_handler(const SDL_Event* event)
case SDL_CONTROLLER_BUTTON_BACK: case SDL_CONTROLLER_BUTTON_BACK:
if (single_step) if (single_step)
{ {
SDL_Event event{ SDL_QUIT }; SDL_Event event{SDL_QUIT};
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
break; break;
default:; default: ;
} }
break; break;
case SDL_CONTROLLERBUTTONUP: case SDL_CONTROLLERBUTTONUP:
@ -953,15 +932,15 @@ void winmain::RenderFrameTimeDialog()
if (!gfr_display) if (!gfr_display)
return; return;
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2{ 300, 70 }); ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2{300, 70});
if (ImGui::Begin("Frame Times", &DispGRhistory, ImGuiWindowFlags_NoScrollbar)) if (ImGui::Begin("Frame Times", &DispGRhistory, ImGuiWindowFlags_NoScrollbar))
{ {
auto target = static_cast<float>(TargetFrameTime.count()); auto target = static_cast<float>(TargetFrameTime.count());
auto scale = 1 / (64 / 2 / target); auto scale = 1 / (gfr_display->Height / 2 / target);
auto spin = Options.HybridSleep ? static_cast<float>(SpinThreshold.count()) : 0; auto spin = Options.HybridSleep ? static_cast<float>(SpinThreshold.count()) : 0;
ImGui::Text("Target frame time:%03.04fms, 1px:%03.04fms, SpinThreshold:%03.04fms", ImGui::Text("Target frame time:%03.04fms, 1px:%03.04fms, SpinThreshold:%03.04fms",
target, scale, spin); target, scale, spin);
gfr_display->BlitToTexture(); gfr_display->BlitToTexture();
auto region = ImGui::GetContentRegionAvail(); auto region = ImGui::GetContentRegionAvail();
ImGui::Image(gfr_display->Texture, region); ImGui::Image(gfr_display->Texture, region);

View File

@ -65,7 +65,6 @@ class winmain
using TimePoint = std::chrono::time_point<Clock>; using TimePoint = std::chrono::time_point<Clock>;
public: public:
static std::string DatFileName;
static bool single_step; static bool single_step;
static SDL_Window* MainWindow; static SDL_Window* MainWindow;
static SDL_Renderer* Renderer; static SDL_Renderer* Renderer;
@ -73,7 +72,6 @@ public:
static bool LaunchBallEnabled; static bool LaunchBallEnabled;
static bool HighScoresEnabled; static bool HighScoresEnabled;
static bool DemoActive; static bool DemoActive;
static std::string BasePath;
static int MainMenuHeight; static int MainMenuHeight;
static int WinMain(LPCSTR lpCmdLine); static int WinMain(LPCSTR lpCmdLine);