Minor bug fixes (#2128)

- make sure bsp is processed on `l` levels in extraction (caused missing
remaps)
- clean up a few prints in extraction
- handle the <15 byte differences in art group files automatically (no
more errors about file naming)
- fix potential exception thrown by merc2 in a few ways: fixed bad data
in FR3's, check texture index just in case, and handle exceptions a
little bit better (still a crash, but at least you get a print)
- fix mips2 ocean stuff causing ocean far crashes
This commit is contained in:
water111
2023-01-14 16:26:17 -05:00
committed by GitHub
parent 8a82c2225e
commit a0d2bce27b
20 changed files with 181 additions and 88 deletions
@@ -231,6 +231,7 @@ static void link_v2_or_v4(LinkedObjectFile& f,
const std::string& name,
DecompilerTypeSystem& dts,
GameVersion version) {
(void)name;
const auto* header = (const LinkHeaderV4*)&data.at(0);
ASSERT(header->version == 4 || header->version == 2);
@@ -313,7 +314,8 @@ static void link_v2_or_v4(LinkedObjectFile& f,
for (uint8_t i = 0; i < count; i++) {
if (!f.pointer_link_word(0, code_ptr_offset - code_offset, 0,
*((const uint32_t*)(&data.at(code_ptr_offset))))) {
lg::error("Skipping link in {} because it is out of range!", name.c_str());
// was this just a bug in the linker??
// lg::error("Skipping link in {} because it is out of range!", name.c_str());
}
f.stats.total_v2_pointers++;
code_ptr_offset += 4;
@@ -680,13 +682,6 @@ static void link_v3(LinkedObjectFile& f,
segment_size++;
adjusted = true;
}
if (adjusted) {
printf(
"Adjusted the size of segment %d in %s, this is fine, but rare (and may indicate a "
"bigger problem if it happens often)\n",
seg_id, name.c_str());
}
}
auto base_ptr = segment_data_offsets[seg_id];
+50 -4
View File
@@ -312,6 +312,55 @@ void ObjectFileDB::get_objs_from_dgo(const fs::path& filename, const Config& con
ASSERT(0 == reader.bytes_left());
}
/*!
* Are two object files the same?
* Unfortunately they seemed to have a memory bug in their art-group generator, so there's some
* uninitialized padding bytes.
*/
bool are_objects_the_same(const std::string& obj_name,
size_t size_a,
const u8* a,
size_t size_b,
const u8* b) {
if (size_a != size_b) {
return false;
}
// if they are byte-for-byte the same, it's a match
if (!memcmp(a, b, size_a)) {
return true;
}
// if it's an art group...
if (obj_name.size() > 3 && !obj_name.compare(obj_name.length() - 3, 3, "-ag")) {
// count up the number of differing bytes, and the location of the first one.
size_t first_diff = 0;
size_t last_diff = 0;
int num_diffs = 0;
bool found_first_diff = false;
for (size_t i = 0; i < size_a; i++) {
if (a[i] != b[i]) {
num_diffs++;
last_diff = i;
if (!found_first_diff) {
first_diff = i;
found_first_diff = true;
}
}
}
// find the gap between "code" (really data here) and link table. This has up to 15 bytes of
// uninitialized memory.
const auto* header = (const LinkHeaderV4*)a;
int link_data_offset = header->code_size + sizeof(LinkHeaderV4);
int start_off_diff_from_code_end = link_data_offset - (int)first_diff;
if (num_diffs < 16 && start_off_diff_from_code_end < 16 && (int)last_diff < link_data_offset) {
return true;
}
}
return false;
}
/*!
* Add an object file to the ObjectFileDB
*/
@@ -337,10 +386,7 @@ void ObjectFileDB::add_obj_from_dgo(const std::string& obj_name,
bool duplicated = false;
// first, check to see if we already got it...
for (auto& e : obj_files_by_name[obj_name]) {
if (e.data.size() == obj_size && e.record.hash == hash) {
// just to make sure we don't have a hash collision.
ASSERT(!memcmp(obj_data, e.data.data(), obj_size));
if (are_objects_the_same(obj_name, e.data.size(), e.data.data(), obj_size, obj_data)) {
// already got it!
e.reference_count++;
auto& rec = e.record;