Compare commits
7 Commits
Release_2.
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16b527e3cf | ||
|
|
683204519c | ||
|
|
ecdf802d68 | ||
|
|
dc00dbde0d | ||
|
|
862fe13dcd | ||
|
|
6c299ed103 | ||
|
|
fc1975a607 |
@@ -9,7 +9,8 @@
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
"ctestCommandArgs": "",
|
||||
"addressSanitizerEnabled": false
|
||||
},
|
||||
{
|
||||
"name": "x86-Debug",
|
||||
@@ -20,7 +21,8 @@
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ]
|
||||
"inheritEnvironments": [ "msvc_x86" ],
|
||||
"addressSanitizerEnabled": false
|
||||
},
|
||||
{
|
||||
"name": "x86-Release",
|
||||
|
||||
@@ -77,9 +77,9 @@ Tested with: macOS Big Sur (Intel) with Xcode 13 & macOS Montery Beta (Apple Sil
|
||||
* ~~Decompile original game~~
|
||||
* ~~Resizable window, scaled graphics~~
|
||||
* ~~Loader for high-res sprites from CADET.DAT~~
|
||||
* ~~Cross-platform port using SDL2, SDL2_mixer, ImGui~~
|
||||
* Misc features of Full Tilt: 3 music tracks, multiball, centered textboxes, etc.
|
||||
* Cross-platform port
|
||||
* Using SDL2, SDL2_mixer, ImGui
|
||||
* Maybe: Text translations
|
||||
* Maybe: Android port
|
||||
* Maybe x2: support for other two tables
|
||||
* Table specific BL (control interactions and missions) is hardcoded, othere parts might be also patched
|
||||
|
||||
@@ -297,7 +297,7 @@ void DatFile::Finalize()
|
||||
// PINBALL2.MID is an alternative font provided in 3DPB data
|
||||
// Scaled down because it is too large for top text box
|
||||
/*auto file = pinball::make_path_name("PINBALL2.MID");
|
||||
auto fileHandle = fopen(file.c_str(), "rb");
|
||||
auto fileHandle = fopenu(file.c_str(), "rb");
|
||||
fseek(fileHandle, 0, SEEK_END);
|
||||
auto fileSize = static_cast<uint32_t>(ftell(fileHandle));
|
||||
auto rcData = reinterpret_cast<MsgFont*>(new uint8_t[fileSize]);
|
||||
|
||||
@@ -57,7 +57,7 @@ void Sound::PlaySound(Mix_Chunk* wavePtr, int time)
|
||||
|
||||
Mix_Chunk* Sound::LoadWaveFile(const std::string& lpName)
|
||||
{
|
||||
auto wavFile = fopen(lpName.c_str(), "r");
|
||||
auto wavFile = fopenu(lpName.c_str(), "r");
|
||||
if (!wavFile)
|
||||
return nullptr;
|
||||
fclose(wavFile);
|
||||
|
||||
@@ -34,6 +34,25 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
{
|
||||
return MainActual(lpCmdLine);
|
||||
}
|
||||
|
||||
// fopen to _wfopen adapter, for UTF-8 paths
|
||||
FILE* fopenu(const char* path, const char* opt)
|
||||
{
|
||||
wchar_t* wideArgs[2]{};
|
||||
for (auto& arg : wideArgs)
|
||||
{
|
||||
auto src = wideArgs[0] ? opt : path;
|
||||
auto length = MultiByteToWideChar(CP_UTF8, 0, src, -1, nullptr, 0);
|
||||
arg = new wchar_t[length];
|
||||
MultiByteToWideChar(CP_UTF8, 0, src, -1, arg, length);
|
||||
}
|
||||
|
||||
auto fileHandle = _wfopen(wideArgs[0], wideArgs[1]);
|
||||
for (auto arg : wideArgs)
|
||||
delete[] arg;
|
||||
|
||||
return fileHandle;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
|
||||
|
||||
@@ -3775,9 +3775,9 @@ void control::SelectMissionController(int code, TPinballComponent* caller)
|
||||
if (light_on(&control_lite319_tag))
|
||||
control_lite319_tag.Component->Message(20, 0.0);
|
||||
control_lite198_tag.Component->MessageField = control_lite56_tag.Component->MessageField;
|
||||
auto scoreId = control_lite56_tag.Component->MessageField - 2;
|
||||
MissionControl(66, nullptr);
|
||||
int addedScore = SpecialAddScore(
|
||||
mission_select_scores[control_lite56_tag.Component->MessageField - 2]);
|
||||
int addedScore = SpecialAddScore(mission_select_scores[scoreId]);
|
||||
snprintf(Buffer, sizeof Buffer, pinball::get_rc_string(77, 0), addedScore);
|
||||
control_mission_text_box_tag.Component->Display(Buffer, 4.0);
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ int loader::get_sound_id(int groupIndex)
|
||||
}
|
||||
|
||||
auto filePath = pinball::make_path_name(fileName);
|
||||
auto file = fopen(filePath.c_str(), "rb");
|
||||
auto file = fopenu(filePath.c_str(), "rb");
|
||||
if (file)
|
||||
{
|
||||
fread(&wavHeader, 1, sizeof wavHeader, file);
|
||||
|
||||
@@ -101,11 +101,12 @@ Mix_Music* midi::load_track(std::string fileName)
|
||||
if (i == 0)
|
||||
{
|
||||
auto filePath = basePath + ".MID";
|
||||
auto fileHandle = fopen(filePath.c_str(), "rb");
|
||||
auto fileHandle = fopenu(filePath.c_str(), "rb");
|
||||
if (fileHandle)
|
||||
{
|
||||
fclose(fileHandle);
|
||||
audio = Mix_LoadMUS(filePath.c_str());
|
||||
auto rw = SDL_RWFromFile(filePath.c_str(), "rb");
|
||||
audio = Mix_LoadMUS_RW(rw, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -115,7 +116,7 @@ Mix_Music* midi::load_track(std::string fileName)
|
||||
{
|
||||
// Dump converted MIDI file
|
||||
/*auto filePath = basePath + ".midi";
|
||||
FILE* fileHandle = fopen(filePath.c_str(), "wb");
|
||||
FILE* fileHandle = fopenu(filePath.c_str(), "wb");
|
||||
fwrite(midi->data(), 1, midi->size(), fileHandle);
|
||||
fclose(fileHandle);*/
|
||||
|
||||
@@ -164,7 +165,7 @@ bool midi::play_track(Mix_Music* midi)
|
||||
/// <returns>Vector that contains MIDI file</returns>
|
||||
std::vector<uint8_t>* midi::MdsToMidi(std::string file)
|
||||
{
|
||||
auto fileHandle = fopen(file.c_str(), "rb");
|
||||
auto fileHandle = fopenu(file.c_str(), "rb");
|
||||
if (!fileHandle)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode)
|
||||
dat8BitBmpHeader bmpHeader{};
|
||||
dat16BitBmpHeader zMapHeader{};
|
||||
|
||||
auto fileHandle = fopen(lpFileName, "rb");
|
||||
auto fileHandle = fopenu(lpFileName, "rb");
|
||||
if (fileHandle == nullptr)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ int pb::init()
|
||||
{
|
||||
float projMat[12], zMin = 0, zScaler = 0;
|
||||
|
||||
if (winmain::DatFileName.empty())
|
||||
return 1;
|
||||
auto dataFilePath = pinball::make_path_name(winmain::DatFileName);
|
||||
record_table = partman::load_records(dataFilePath.c_str(), FullTiltMode);
|
||||
|
||||
|
||||
@@ -83,4 +83,14 @@ int Sign(T val)
|
||||
return (T(0) < val) - (val < T(0));
|
||||
}
|
||||
|
||||
// UTF-8 path adapter for fopen on Windows, implemented in SpaceCadetPinball.cpp
|
||||
#ifdef _WIN32
|
||||
extern FILE* fopenu(const char* path, const char* opt);
|
||||
#else
|
||||
inline FILE* fopenu(const char* path, const char* opt)
|
||||
{
|
||||
return fopen(path, opt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //PCH_H
|
||||
|
||||
@@ -36,7 +36,7 @@ bool winmain::ShowSpriteViewer = false;
|
||||
bool winmain::LaunchBallEnabled = true;
|
||||
bool winmain::HighScoresEnabled = true;
|
||||
bool winmain::DemoActive = false;
|
||||
char* winmain::BasePath;
|
||||
std::string winmain::BasePath;
|
||||
int winmain::MainMenuHeight = 0;
|
||||
std::string winmain::FpsDetails;
|
||||
double winmain::UpdateToFrameRatio;
|
||||
@@ -58,19 +58,44 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not initialize SDL2", SDL_GetError(), nullptr);
|
||||
return 1;
|
||||
}
|
||||
BasePath = SDL_GetBasePath();
|
||||
|
||||
pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr;
|
||||
DatFileName = options::get_string("Pinball Data", pinball::get_rc_string(168, 0));
|
||||
|
||||
/*Check for full tilt .dat file and switch to it automatically*/
|
||||
auto cadetFilePath = pinball::make_path_name("CADET.DAT");
|
||||
auto cadetDat = fopen(cadetFilePath.c_str(), "r");
|
||||
if (cadetDat)
|
||||
// Search for game data in: game folder, user folder
|
||||
// Game data test order: CADET.DAT, PINBALL.DAT
|
||||
char* dataSearchPaths[2]
|
||||
{
|
||||
fclose(cadetDat);
|
||||
DatFileName = "CADET.DAT";
|
||||
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
|
||||
@@ -339,7 +364,6 @@ void winmain::RenderUi()
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
return;
|
||||
}
|
||||
|
||||
// No demo window in release to save space
|
||||
@@ -348,7 +372,7 @@ void winmain::RenderUi()
|
||||
ImGui::ShowDemoWindow(&ShowImGuiDemo);
|
||||
#endif
|
||||
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
if (Options.ShowMenu && ImGui::BeginMainMenuBar())
|
||||
{
|
||||
int currentMenuHeight = static_cast<int>(ImGui::GetWindowSize().y);
|
||||
if (MainMenuHeight != currentMenuHeight)
|
||||
@@ -777,6 +801,13 @@ int winmain::event_handler(const SDL_Event* event)
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
pause();
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_BACK:
|
||||
if (single_step)
|
||||
{
|
||||
SDL_Event event{ SDL_QUIT };
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
static bool LaunchBallEnabled;
|
||||
static bool HighScoresEnabled;
|
||||
static bool DemoActive;
|
||||
static char* BasePath;
|
||||
static std::string BasePath;
|
||||
static int MainMenuHeight;
|
||||
|
||||
static int WinMain(LPCSTR lpCmdLine);
|
||||
|
||||
Reference in New Issue
Block a user