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