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.
This commit is contained in:
iAmInAction 2022-04-25 08:06:13 +02:00 committed by GitHub
parent cc06d35bc7
commit 6bc1957ab6
Signed by untrusted user: GitHub
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 25 deletions

View File

@ -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<float>(sampleCount / wavHeader.sample_rate);
sound_list[soundIndex].WavePtr = Sound::LoadWaveFile(filePath);

View File

@ -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<uint8_t>(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<int>(length), SEEK_CUR);
zMap = new zmap_header_type(0, 0, 0);
}
entryData->Buffer = reinterpret_cast<char*>(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);

View File

@ -68,6 +68,11 @@ private:
{
T Buffer{};
fread(&Buffer, 1, sizeof(T), file);
if (sizeof(T) == 4) {
// uint32
Buffer = SDL_SwapLE32(Buffer);
}
return Buffer;
}
};

View File

@ -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)

View File

@ -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;