From 6bc1957ab6e1c44d0c22705c4ecb4c053d0391e2 Mon Sep 17 00:00:00 2001 From: iAmInAction <83808704+iAmInActions@users.noreply.github.com> Date: Mon, 25 Apr 2022 08:06:13 +0200 Subject: [PATCH] Fixed loading on big endian CPUs This allows you to run this code on little and big endian, thus making it run fine on PowerPC as well as x86 and ARM. --- SpaceCadetPinball/loader.cpp | 6 ++++ SpaceCadetPinball/partman.cpp | 53 +++++++++++++++++++++++++++++------ SpaceCadetPinball/partman.h | 5 ++++ SpaceCadetPinball/pb.cpp | 41 ++++++++++++++++----------- SpaceCadetPinball/pb.h | 1 + 5 files changed, 81 insertions(+), 25 deletions(-) diff --git a/SpaceCadetPinball/loader.cpp b/SpaceCadetPinball/loader.cpp index 60ffc0f..25f1696 100644 --- a/SpaceCadetPinball/loader.cpp +++ b/SpaceCadetPinball/loader.cpp @@ -165,6 +165,12 @@ int loader::get_sound_id(int groupIndex) fclose(file); } + // only swapping what seems to be necessary here - don't want to break anything + wavHeader.sample_rate = SDL_SwapLE32(wavHeader.sample_rate); + wavHeader.data_size = SDL_SwapLE32(wavHeader.data_size); + wavHeader.channels = SDL_SwapLE16(wavHeader.channels); + wavHeader.bits_per_sample = SDL_SwapLE16(wavHeader.bits_per_sample); + auto sampleCount = wavHeader.data_size / (wavHeader.channels * (wavHeader.bits_per_sample / 8.0)); sound_list[soundIndex].Duration = static_cast(sampleCount / wavHeader.sample_rate); sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(filePath); diff --git a/SpaceCadetPinball/partman.cpp b/SpaceCadetPinball/partman.cpp index 43eeb5f..2243422 100644 --- a/SpaceCadetPinball/partman.cpp +++ b/SpaceCadetPinball/partman.cpp @@ -21,6 +21,12 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode) return nullptr; fread(&header, 1, sizeof header, fileHandle); + + header.FileSize = SDL_SwapLE32(header.FileSize); + header.NumberOfGroups = SDL_SwapLE16(header.NumberOfGroups); + header.SizeOfBody = SDL_SwapLE32(header.SizeOfBody); + header.Unknown = SDL_SwapLE16(header.Unknown); + if (strcmp("PARTOUT(4.0)RESOURCE", header.FileSignature) != 0) { fclose(fileHandle); @@ -71,6 +77,11 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode) if (entryType == FieldTypes::Bitmap8bit) { fread(&bmpHeader, 1, sizeof(dat8BitBmpHeader), fileHandle); + bmpHeader.Width = SDL_SwapLE16(bmpHeader.Width); + bmpHeader.Height = SDL_SwapLE16(bmpHeader.Height); + bmpHeader.XPosition = SDL_SwapLE16(bmpHeader.XPosition); + bmpHeader.YPosition = SDL_SwapLE16(bmpHeader.YPosition); + bmpHeader.Size = SDL_SwapLE32(bmpHeader.Size); assertm(bmpHeader.Size + sizeof(dat8BitBmpHeader) == fieldSize, "partman: Wrong bitmap field size"); assertm(bmpHeader.Resolution <= 2, "partman: bitmap resolution out of bounds"); @@ -86,29 +97,31 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode) { zMapResolution = LRead(fileHandle); fieldSize--; - - // -1 means universal resolution, maybe. FT demo .006 is the only known user. - if (zMapResolution == 0xff) - zMapResolution = 0; - assertm(zMapResolution <= 2, "partman: zMap resolution out of bounds"); } fread(&zMapHeader, 1, sizeof(dat16BitBmpHeader), fileHandle); + zMapHeader.Width = SDL_SwapLE16(zMapHeader.Width); + zMapHeader.Height = SDL_SwapLE16(zMapHeader.Height); + zMapHeader.Stride = SDL_SwapLE16(zMapHeader.Stride); + zMapHeader.Unknown0 = SDL_SwapLE32(zMapHeader.Unknown0); + zMapHeader.Unknown1_0 = SDL_SwapLE16(zMapHeader.Unknown1_0); + zMapHeader.Unknown1_1 = SDL_SwapLE16(zMapHeader.Unknown1_1); auto length = fieldSize - sizeof(dat16BitBmpHeader); - zmap_header_type* zMap; + auto zMap = new zmap_header_type(zMapHeader.Width, zMapHeader.Height, zMapHeader.Stride); + zMap->Resolution = zMapResolution; if (zMapHeader.Stride * zMapHeader.Height * 2u == length) { - zMap = new zmap_header_type(zMapHeader.Width, zMapHeader.Height, zMapHeader.Stride); - zMap->Resolution = zMapResolution; fread(zMap->ZPtr1, 1, length, fileHandle); + for (int i = 0; i < zMapHeader.Stride * zMapHeader.Height; i++) { + zMap->ZPtr1[i] = SDL_SwapLE16(zMap->ZPtr1[i]); + } } else { // 3DPB .dat has zeroed zMap headers, in groups 497 and 498, skip them. fseek(fileHandle, static_cast(length), SEEK_CUR); - zMap = new zmap_header_type(0, 0, 0); } entryData->Buffer = reinterpret_cast(zMap); } @@ -122,6 +135,28 @@ DatFile* partman::load_records(LPCSTR lpFileName, bool fullTiltMode) break; } fread(entryBuffer, 1, fieldSize, fileHandle); + + switch (entryType) { + case FieldTypes::ShortValue: + case FieldTypes::Unknown2: + *(int16_t*)entryBuffer = SDL_SwapLE16(*(int16_t*)entryBuffer); + break; + case FieldTypes::ShortArray: + for (int i = 0; i < fieldSize / 2; i++) { + ((int16_t*)entryBuffer)[i] = SDL_SwapLE16(((int16_t*)entryBuffer)[i]); + } + break; + case FieldTypes::FloatArray: + for (int i = 0; i < fieldSize / 4; i++) { + ((float*)entryBuffer)[i] = SDL_SwapFloatLE(((float*)entryBuffer)[i]); + } + break; + case FieldTypes::Palette: + for (int i = 0; i < fieldSize / 4; i++) { + ((uint32_t*)entryBuffer)[i] = SDL_SwapLE32(((uint32_t*)entryBuffer)[i]); + } + break; + } } groupData->AddEntry(entryData); diff --git a/SpaceCadetPinball/partman.h b/SpaceCadetPinball/partman.h index 04fd02a..bb4b98f 100644 --- a/SpaceCadetPinball/partman.h +++ b/SpaceCadetPinball/partman.h @@ -68,6 +68,11 @@ private: { T Buffer{}; fread(&Buffer, 1, sizeof(T), file); + + if (sizeof(T) == 4) { + // uint32 + Buffer = SDL_SwapLE32(Buffer); + } return Buffer; } }; diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index a30c5a2..c376641 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -32,6 +32,7 @@ DatFile* pb::record_table = nullptr; int pb::time_ticks = 0; GameModes pb::game_mode = GameModes::GameOver; float 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::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false; std::string pb::DatFileName; @@ -97,7 +98,7 @@ int pb::init() MainTable = new TPinballTable(); - high_score::read(); + high_score::read(highscore_table); ball_speed_limit = MainTable->BallList.at(0)->Offset * 200.0f; return 0; } @@ -107,7 +108,7 @@ int pb::uninit() score::unload_msg_font(); loader::unload(); delete record_table; - high_score::write(); + high_score::write(highscore_table); delete MainTable; MainTable = nullptr; timer::uninit(); @@ -461,6 +462,11 @@ void pb::InputDown(GameInput input) nudge::nudge_up(); } + if (input.Type == InputTypes::GameController && input.Value == SDL_CONTROLLER_BUTTON_BACK) + { + winmain::new_game(); + } + if (cheat_mode && input.Type == InputTypes::Keyboard) { switch (input.Value) @@ -495,12 +501,10 @@ void pb::InputDown(GameInput input) ball->Acceleration.X = 0.0; break; case 'h': - { - high_score_struct entry{ {0}, 1000000000 }; - strncpy(entry.Name, pinball::get_rc_string(26, 0), sizeof entry.Name - 1); - high_score::show_and_set_high_score_dialog({ entry, 1 }); + char String1[200]; + strncpy(String1, pinball::get_rc_string(26, 0), sizeof String1 - 1); + high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1); break; - } case 'r': control::cheat_bump_rank(); break; @@ -523,6 +527,7 @@ void pb::end_game() { int scores[4]{}; int scoreIndex[4]{}; + char String1[200]; mode_change(GameModes::GameOver); int playerCount = MainTable->PlayerCount; @@ -556,12 +561,11 @@ void pb::end_game() { for (auto i = 0; i < playerCount; ++i) { - int position = high_score::get_score_position(scores[i]); + int position = high_score::get_score_position(highscore_table, scores[i]); if (position >= 0) { - high_score_struct entry{ {0}, scores[i] }; - strncpy(entry.Name, pinball::get_rc_string(scoreIndex[i] + 26, 0), sizeof entry.Name - 1); - high_score::show_and_set_high_score_dialog({ entry, -1 }); + strncpy(String1, pinball::get_rc_string(scoreIndex[i] + 26, 0), sizeof String1 - 1); + high_score::show_and_set_high_score_dialog(highscore_table, scores[i], position, String1); } } } @@ -569,7 +573,7 @@ void pb::end_game() void pb::high_scores() { - high_score::show_high_score_dialog(); + high_score::show_high_score_dialog(highscore_table); } void pb::tilt_no_more() @@ -584,12 +588,17 @@ bool pb::chk_highscore() { if (demo_mode) return false; - for (auto i = 0; i < MainTable->PlayerCount; ++i) + int playerIndex = MainTable->PlayerCount - 1; + if (playerIndex < 0) + return false; + for (int i = playerIndex; + high_score::get_score_position(highscore_table, MainTable->PlayerScores[i].ScoreStruct->Score) < 0; + --i) { - if (high_score::get_score_position(MainTable->PlayerScores[i].ScoreStruct->Score) >= 0) - return true; + if (--playerIndex < 0) + return false; } - return false; + return true; } float pb::collide(float timeNow, float timeDelta, TBall* ball) diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index 18984db..6ab60cb 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -45,6 +45,7 @@ public: static bool cheat_mode; static DatFile* record_table; static TPinballTable* MainTable; + static high_score_struct highscore_table[5]; static bool FullTiltMode, FullTiltDemoMode; static std::string DatFileName;