From d4bc3f4e22c7ba23e628118e7706f43976de04bb Mon Sep 17 00:00:00 2001 From: chaoticgd <43898262+chaoticgd@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:43:52 +0000 Subject: [PATCH] Fix some unpacker bugs --- src/engine/tfrag_high.cpp | 4 ++-- src/iso/iso_unpacker.cpp | 2 +- src/iso/table_of_contents.cpp | 23 ++++++++--------------- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/engine/tfrag_high.cpp b/src/engine/tfrag_high.cpp index a598c7f8..a881d8d4 100644 --- a/src/engine/tfrag_high.cpp +++ b/src/engine/tfrag_high.cpp @@ -20,9 +20,9 @@ #include -#define MAX_TFACES_TOUCHING_VERTEX 12 +#define MAX_TFACES_TOUCHING_VERTEX 16 #define INIT_TFACE_INDICES \ - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} struct TfragFace { s32 ad_gif; diff --git a/src/iso/iso_unpacker.cpp b/src/iso/iso_unpacker.cpp index df524f31..a2e49705 100644 --- a/src/iso/iso_unpacker.cpp +++ b/src/iso/iso_unpacker.cpp @@ -118,7 +118,7 @@ static void add_missing_levels_from_filesystem(table_of_contents& toc, const Iso info.level.emplace(); info.level->header_lba = record.lba; info.level->file_lba = record.lba; - info.level->file_size = record.size; + info.level->file_size = Sector32::size_from_bytes(record.size); s32 header_size = iso.read(record.lba.bytes()); info.level->header = iso.read_multiple(record.lba.bytes(), header_size); info.level->prepend_header = false; diff --git a/src/iso/table_of_contents.cpp b/src/iso/table_of_contents.cpp index 8cb1cbff..b1f30d8b 100644 --- a/src/iso/table_of_contents.cpp +++ b/src/iso/table_of_contents.cpp @@ -28,7 +28,7 @@ static Opt adapt_rac1_audio_wad_header(InputStream& src, Rac1Amalg static Opt adapt_rac1_scene_wad_header(InputStream& src, Rac1AmalgamatedWadHeader& header); static Sector32 get_lz_size(InputStream& src, Sector32 sector); -static s64 get_rac234_level_table_offset(Buffer src); +static s64 guess_rac234_level_table_offset(Buffer src); static SectorRange add_sector_range(SectorRange range, Sector32 lsn); static SectorByteRange add_sector_byte_range(SectorByteRange range, Sector32 lsn); @@ -361,15 +361,15 @@ table_of_contents read_table_of_contents_rac234(InputStream& src) { table_of_contents toc; - s64 level_table_offset = get_rac234_level_table_offset(buffer); - if(level_table_offset == 0x0) { + s64 approximate_level_table_offset = guess_rac234_level_table_offset(buffer); + if(approximate_level_table_offset == 0x0) { // We've failed to find the level table, at least try to find some of the other tables. - level_table_offset = 0xffff; + approximate_level_table_offset = 0xffff; } s64 global_index = 0; s64 ofs = 0; - while(ofs + 4 * 6 < level_table_offset) { + while(ofs + 4 * 6 < approximate_level_table_offset) { GlobalWadInfo global; global.index = global_index++; global.offset_in_toc = ofs; @@ -383,20 +383,13 @@ table_of_contents read_table_of_contents_rac234(InputStream& src) { ofs += header_size; } - // This fixes an off-by-one error with R&C3 where since the first entry of - // the level table is supposed to be zeroed out, this code would otherwise - // think that the level table starts 0x18 bytes later than it actually does. - if(ofs + 0x18 == level_table_offset) { - level_table_offset -= 0x18; - } - - auto level_table = buffer.read_multiple(level_table_offset, TOC_MAX_LEVELS, "level table"); + auto level_table = buffer.read_multiple(ofs, TOC_MAX_LEVELS, "level table"); for(s32 i = 0; i < TOC_MAX_LEVELS; i++) { toc_level_table_entry entry = level_table[i]; LevelInfo level; level.level_table_index = i; - level.level_table_entry_offset = (s32) level_table_offset + i * sizeof(toc_level_table_entry); + level.level_table_entry_offset = (s32) ofs + i * sizeof(toc_level_table_entry); // The games have the fields in different orders, so we check the type // of what each field points to so we can support them all. @@ -433,7 +426,7 @@ table_of_contents read_table_of_contents_rac234(InputStream& src) { return toc; } -static s64 get_rac234_level_table_offset(Buffer src) { +static s64 guess_rac234_level_table_offset(Buffer src) { // Check that the two next entries are valid. This is necessary to // get past a false positive in Deadlocked. for(s64 i = 0; i < src.size() / 4 - 12; i++) {