From f561cadf63cdcd2296689bbf02876ea4f0a775bf Mon Sep 17 00:00:00 2001 From: Low-power Date: Tue, 22 Nov 2022 17:40:50 +0800 Subject: [PATCH] Allow loading data files with lowercase name (#164) * Allow loading data files with lowercase name * Added lower case support for all game data files. Co-authored-by: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> --- SpaceCadetPinball/loader.cpp | 31 +++++++++++++++++++------------ SpaceCadetPinball/midi.cpp | 36 +++++++++++++++++++++++++----------- SpaceCadetPinball/midi.h | 1 + SpaceCadetPinball/pb.cpp | 24 +++++++++++++++++++----- 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/SpaceCadetPinball/loader.cpp b/SpaceCadetPinball/loader.cpp index 1551094..e9dd0b3 100644 --- a/SpaceCadetPinball/loader.cpp +++ b/SpaceCadetPinball/loader.cpp @@ -142,27 +142,34 @@ int loader::get_sound_id(int groupIndex) FieldTypes::ShortValue)); if (value && *value == 202) { + // File name is in lower case, while game data is usually in upper case. std::string fileName = loader_table->field(soundGroupId, FieldTypes::String); - - // File name is in lower case, while game data is in upper case. - std::transform(fileName.begin(), fileName.end(), fileName.begin(), - [](unsigned char c) { return std::toupper(c); }); if (pb::FullTiltMode) { // FT sounds are in SOUND subfolder fileName.insert(0, 1, PathSeparator); - fileName.insert(0, "SOUND"); + fileName.insert(0, "sound"); } + std::string filePath; float duration = -1; - auto filePath = pb::make_path_name(fileName); - auto file = fopenu(filePath.c_str(), "rb"); - if (file) + for (int i = 0; i < 2; i++) { - fread(&wavHeader, 1, sizeof wavHeader, file); - fclose(file); - auto sampleCount = wavHeader.data_size / (wavHeader.channels * (wavHeader.bits_per_sample / 8.0)); - duration = static_cast(sampleCount / wavHeader.sample_rate); + if (i == 1) + std::transform(fileName.begin(), fileName.end(), fileName.begin(), + [](unsigned char c) { return std::toupper(c); }); + + filePath = pb::make_path_name(fileName); + auto file = fopenu(filePath.c_str(), "rb"); + if (file) + { + fread(&wavHeader, 1, sizeof wavHeader, file); + fclose(file); + auto sampleCount = wavHeader.data_size / (wavHeader.channels * (wavHeader.bits_per_sample / + 8.0)); + duration = static_cast(sampleCount / wavHeader.sample_rate); + break; + } } sound_list[soundIndex].Duration = duration; diff --git a/SpaceCadetPinball/midi.cpp b/SpaceCadetPinball/midi.cpp index 8138f54..a2b3596 100644 --- a/SpaceCadetPinball/midi.cpp +++ b/SpaceCadetPinball/midi.cpp @@ -107,7 +107,6 @@ void midi::SetVolume(int volume) Mix_Music* midi::load_track(std::string fileName) { - Mix_Music* audio = nullptr; if (pb::FullTiltMode) { // FT sounds are in SOUND subfolder @@ -115,29 +114,47 @@ Mix_Music* midi::load_track(std::string fileName) fileName.insert(0, "SOUND"); } + auto audio = load_track_sub(fileName, true); + if (!audio) + audio = load_track_sub(fileName, false); + + if (!audio) + return nullptr; + + LoadedTracks.push_back(audio); + return audio; +} + +Mix_Music* midi::load_track_sub(std::string fileName, bool isMidi) +{ // FT has music in two formats, depending on game version: MIDI in 16bit, MIDS in 32bit. // 3DPB music is MIDI only. - auto basePath = pb::make_path_name(fileName); - for (int i = 0; i <= 1 && !audio; i++) + Mix_Music* audio = nullptr; + fileName += isMidi ? ".MID" : ".MDS"; + for (int i = 0; i < 2; i++) { - if (i == 0) + if (i == 1) + std::transform(fileName.begin(), fileName.end(), fileName.begin(), + [](unsigned char c) { return std::tolower(c); }); + if (isMidi) { - auto filePath = basePath + ".MID"; + auto filePath = pb::make_path_name(fileName); auto fileHandle = fopenu(filePath.c_str(), "rb"); if (fileHandle) { fclose(fileHandle); auto rw = SDL_RWFromFile(filePath.c_str(), "rb"); audio = Mix_LoadMUS_RW(rw, 1); + break; } } else { - auto midi = MdsToMidi(basePath + ".MDS"); + auto midi = MdsToMidi(pb::make_path_name(fileName)); if (midi) { // Dump converted MIDI file - /*auto filePath = basePath + ".midi"; + /*auto filePath = fileName + ".midi"; FILE* fileHandle = fopenu(filePath.c_str(), "wb"); fwrite(midi->data(), 1, midi->size(), fileHandle); fclose(fileHandle);*/ @@ -145,14 +162,11 @@ Mix_Music* midi::load_track(std::string fileName) auto rw = SDL_RWFromMem(midi->data(), static_cast(midi->size())); audio = Mix_LoadMUS_RW(rw, 1); // This call seems to leak memory no matter what. delete midi; + break; } } } - if (!audio) - return nullptr; - - LoadedTracks.push_back(audio); return audio; } diff --git a/SpaceCadetPinball/midi.h b/SpaceCadetPinball/midi.h index e8dc5cd..91efd28 100644 --- a/SpaceCadetPinball/midi.h +++ b/SpaceCadetPinball/midi.h @@ -110,6 +110,7 @@ private: static void StopPlayback(); static Mix_Music* load_track(std::string fileName); + static Mix_Music* load_track_sub(std::string fileName, bool isMidi); static Mix_Music* TrackToMidi(MidiTracks track); static std::vector* MdsToMidi(std::string file); }; diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index 1d68cb0..54ea982 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -140,15 +140,26 @@ void pb::SelectDatFile(const std::vector& dataSearchPaths) // Default game data test order: CADET.DAT, PINBALL.DAT, DEMO.DAT if (options::Options.Prefer3DPBGameData) + { std::swap(datFileNames[0], datFileNames[1]); + } for (auto path : dataSearchPaths) { - if (DatFileName.empty() && path) + if (!DatFileName.empty() || !path) + continue; + + BasePath = path; + for (const auto& datFileName : datFileNames) { - BasePath = path; - for (auto datFileName : datFileNames) + auto fileName = datFileName; + auto found = false; + for (int i = 0; i < 2; i++) { - auto datFilePath = make_path_name(datFileName); + if (i == 1) + std::transform(fileName.begin(), fileName.end(), fileName.begin(), + [](unsigned char c) { return std::tolower(c); }); + + auto datFilePath = make_path_name(fileName); auto datFile = fopenu(datFilePath.c_str(), "r"); if (datFile) { @@ -158,11 +169,14 @@ void pb::SelectDatFile(const std::vector& dataSearchPaths) FullTiltMode = true; if (datFileName == "DEMO.DAT") FullTiltDemoMode = FullTiltMode = true; - printf("Loading game from: %s\n", datFilePath.c_str()); + found = true; break; } } + + if (found) + break; } } }