From 942dbbc5b9afbb423bc34850d8169dcc22ba3b1f Mon Sep 17 00:00:00 2001 From: James Osborne Date: Sat, 6 Jun 2026 21:52:42 -0400 Subject: [PATCH] Patch matching BB battle param tables with raw HP diffs --- src/SendCommands.cc | 31 +++++++------ .../PsoPeepsBrutalPeepsHPBB.s | 43 ++++++++++--------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/SendCommands.cc b/src/SendCommands.cc index bc5309dc..b96fe47a 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -847,7 +847,6 @@ static std::shared_ptr> send_brutal_peeps_h constexpr uint32_t scan_start = 0x16760000; constexpr uint32_t scan_end = 0x16A90000; constexpr uint32_t signature_size = 64; - constexpr uint32_t hp_patch_bytes = 0x60 * 2; if (bp_entry->size < signature_size) { c->log.warning_f("Skipping Brutal Peeps HP client patch: BattleParamEntry_on.dat too small for signature"); @@ -865,21 +864,27 @@ static std::shared_ptr> send_brutal_peeps_h append_u32l(suffix, scan_start); append_u32l(suffix, scan_end); append_u32l(suffix, signature_size); - append_u32l(suffix, hp_patch_bytes); + append_u32l(suffix, 0); // patched below after diff generation suffix.append(vanilla_data, signature_size); - for (size_t z = 0; z < 0x60; z++) { - const auto& hp = table->stats[ultimate_index][z].char_stats.hp; - uint32_t hp_offset = reinterpret_cast(&hp) - target_data.data(); - const uint8_t* hp_bytes = reinterpret_cast(&hp); + uint32_t patch_entry_count = 0; + for (uint32_t offset = 0; offset < target_data.size(); offset++) { + uint8_t old_byte = static_cast(vanilla_data[offset]); + uint8_t new_byte = static_cast(target_data[offset]); + if (old_byte == new_byte) { + continue; + } - append_u32l(suffix, hp_offset); - suffix.push_back(static_cast(hp_bytes[0])); - - append_u32l(suffix, hp_offset + 1); - suffix.push_back(static_cast(hp_bytes[1])); + append_u32l(suffix, offset); + suffix.push_back(static_cast(new_byte)); + patch_entry_count++; } + suffix[12] = static_cast(patch_entry_count & 0xFF); + suffix[13] = static_cast((patch_entry_count >> 8) & 0xFF); + suffix[14] = static_cast((patch_entry_count >> 16) & 0xFF); + suffix[15] = static_cast((patch_entry_count >> 24) & 0xFF); + auto fn = s->client_functions->get("PsoPeepsBrutalPeepsHP", c->specific_version); auto promise = std::make_shared>(); @@ -895,8 +900,8 @@ static std::shared_ptr> send_brutal_peeps_h c->enabled_flags |= fn->client_flag; - c->log.info_f("Brutal Peeps HP client patch sent: tier={} mult={:g} patch_bytes={} scan={:08X}-{:08X}", - tier, mult, hp_patch_bytes, scan_start, scan_end); + c->log.info_f("Brutal Peeps HP client patch sent: tier={} mult={:g} patch_entries={} scan={:08X}-{:08X}", + tier, mult, patch_entry_count, scan_start, scan_end); return promise; diff --git a/system/client-functions/PsoPeepsBrutalPeepsHPBB.s b/system/client-functions/PsoPeepsBrutalPeepsHPBB.s index 76cc29cc..0350735d 100644 --- a/system/client-functions/PsoPeepsBrutalPeepsHPBB.s +++ b/system/client-functions/PsoPeepsBrutalPeepsHPBB.s @@ -14,23 +14,24 @@ start: push esi push edi push ebp + push 0 # [esp] = last matched table base / 0 jmp get_data_ptr get_data_ptr_ret: - pop ebx # ebx = suffix payload + pop ebx # ebx = suffix payload - mov esi, [ebx] # scan_start - mov edx, [ebx + 4] # scan_end - mov ecx, [ebx + 8] # signature_size - sub edx, ecx # scan limit = end - sig_size - lea edi, [ebx + 16] # signature ptr + mov esi, [ebx] # scan_start scan_again: + mov edx, [ebx + 4] # scan_end + mov ecx, [ebx + 8] # signature_size + sub edx, ecx # scan limit = end - sig_size cmp esi, edx - ja not_found + ja return xor ebp, ebp + lea edi, [ebx + 16] # signature ptr compare_again: cmp ebp, ecx @@ -48,32 +49,32 @@ next_candidate: jmp scan_again found_table: - # esi = BattleParamEntry_on.dat base - mov ecx, [ebx + 12] # patch entry count - mov edi, [ebx + 8] # signature_size - add edi, ebx - add edi, 16 # patch entries after header+signature + # esi = one matching BattleParam table base + mov [esp], esi # remember last match for return_value + + mov ecx, [ebx + 12] # patch entry count + mov edi, [ebx + 8] # signature_size + lea edi, [ebx + edi + 16] # patch entries after header+signature patch_again: test ecx, ecx - jz done + jz after_patch - mov edx, [edi] # offset from table base - mov al, [edi + 4] # byte value + mov edx, [edi] # offset from table base + mov al, [edi + 4] # byte value mov [esi + edx], al add edi, 5 dec ecx jmp patch_again -done: - mov eax, esi # return found table base - jmp return - -not_found: - xor eax, eax +after_patch: + inc esi # continue scanning after this match + jmp scan_again return: + mov eax, [esp] # 0 if none found, else last matched base + add esp, 4 pop ebp pop edi pop esi