diff --git a/system/client-functions/AccurateKillCount/AccurateKillCount.59NL.patch.s b/system/client-functions/AccurateKillCount/AccurateKillCount.5___.patch.s similarity index 90% rename from system/client-functions/AccurateKillCount/AccurateKillCount.59NL.patch.s rename to system/client-functions/AccurateKillCount/AccurateKillCount.5___.patch.s index e03e6a45..f1442194 100644 --- a/system/client-functions/AccurateKillCount/AccurateKillCount.59NL.patch.s +++ b/system/client-functions/AccurateKillCount/AccurateKillCount.5___.patch.s @@ -1,6 +1,8 @@ .meta name="Kill count fix" .meta description="Fixes client-side\nkill counts when\nmultiple enemies are\nkilled on the same\nframe" +.versions 59NJ 59NL + entry_ptr: reloc0: .offsetof start @@ -9,9 +11,9 @@ start: - .data 0x005E32C8 + .data .deltaof TItemUnitUnsealable_count_kill, TItemUnitUnsealable_count_kill_end - .address 0x005E32C8 + .address TItemUnitUnsealable_count_kill: # [std] (TItemUnitUnsealable* this @ ecx) -> void mov eax, [ecx + 0xF8] movsx eax, word [eax + 0x11A] # eax = this->owner_player->num_kills_since_map_load @@ -29,14 +31,14 @@ TItemUnitUnsealable_count_kill_skip_update: setae dh shl edx, 1 or dword [ecx + 0xDC], edx - jmp 0x005E2C34 + jmp TItemUnitUnsealable_count_kill_end: - .data 0x005F3EFC + .data .deltaof TItemWeapon_LameDArgent_count_kill, TItemWeapon_LameDArgent_count_kill_end - .address 0x005F3EFC + .address TItemWeapon_LameDArgent_count_kill: mov eax, [ecx + 0xF8] movsx eax, word [eax + 0x11A] @@ -59,9 +61,9 @@ TItemWeapon_LameDArgent_count_kill_end: - .data 0x005FCA74 + .data .deltaof TItemWeapon_SealedJSword_count_kill, TItemWeapon_SealedJSword_count_kill_end - .address 0x005FCA74 + .address TItemWeapon_SealedJSword_count_kill: mov eax, [ecx + 0xF8] movsx eax, word [eax + 0x11A] diff --git a/system/client-functions/DrawDistance/DrawDistance.59NJ.patch.s b/system/client-functions/DrawDistance/DrawDistance.59NJ.patch.s new file mode 100644 index 00000000..02d785f7 --- /dev/null +++ b/system/client-functions/DrawDistance/DrawDistance.59NJ.patch.s @@ -0,0 +1,146 @@ +# Currently beta quality, map objects that fade like boxes, and Pioneer's +# background billboards and elevators still have regular draw distance. +# TODO: 90% of stuff is included, bring home the last 10%. + +.meta name="Draw Distance" +.meta description="Extends the draw\ndistance of many\nobjects" + +entry_ptr: +reloc0: + .offsetof start + +write_call_func: + .include WriteCallToCode-59NJ + +start: + mov eax, 0x41800000 # Environment clip distance mod 16.0f + mov [0x0097D198], eax # This affects mostly static map objects + mov [0x0097D19C], eax + mov [0x00097D1A0], eax + + mov ax, 0x9090 + mov [0x00689BC7], ax # Players draw distance 10000.0f always + mov eax, 0x41000000 # Use newly acquired skipped branch room + mov [0x00689BD1], eax # to store our float multiplier + + call patch_func_1 # Floor items + call patch_func_2 # Whole bunch of stuff, including NPCs + call patch_func_3 # Duplicate function from above, reuse same hook + call patch_func_4 # TODO: Which objects this affects? + call patch_func_5 # TODO: This one too? + call patch_func_6 # TODO: And this one? + ret + +# Floor items +patch_func_1: + pop ecx + push 8 + push 0x005C525B + call get_code_size1 + .deltaof patch_code1, patch_code_end1 +get_code_size1: + pop eax + push dword [eax] + call patch_code_end1 +patch_code1: + mov edx, [esp + 0x18] + fld st0, dword [0x00689BD1] + fld st0, dword [esp + 0x14] + fmulp st1, st0 + ret +patch_code_end1: + push ecx + jmp write_call_func + +# Whole bunch of stuff, including NPCs +patch_func_2: + pop ecx + push 9 + push 0x007BB21E + call get_code_size2 + .deltaof patch_code2, patch_code_end2 +get_code_size2: + pop eax + push dword [eax] + call patch_code_end2 +patch_code2: + test eax, 0x400 + fld st0, dword [0x00689BD1] + fld st0, dword [esp + 0x2C] + fmulp st1, st0 + ret +patch_code_end2: + push ecx + jmp write_call_func + +# Duplicate function from above, reuse same hook +patch_func_3: + mov eax, dword [0x007BB21F] + add eax, 0x002A1C74 + mov dword [0x00518843], eax + mov byte [0x00518842], 0xE8 + mov dword [0x00518847], 0x90909090 + ret + +# TOComputerMachine01 +patch_func_4: + pop ecx + push 7 + push 0x00616FF4 + call get_code_size4 + .deltaof patch_code4, patch_code_end4 +get_code_size4: + pop eax + push dword [eax] + call patch_code_end4 +patch_code4: + lea edx, [edi + 0x38] + fld st0, dword [0x00689BD1] + fld st0, dword [esp + 0x14] + fmulp st1, st0 + ret +patch_code_end4: + push ecx + jmp write_call_func + +# TObjCamera +patch_func_5: + pop ecx + push 6 + push 0x006439A8 + call get_code_size5 + .deltaof patch_code5, patch_code_end5 +get_code_size5: + pop eax + push dword [eax] + call patch_code_end5 +patch_code5: + fld st0, dword [0x00689BD1] + fld st0, dword [esp + 0x28] + fmulp st1, st0 + fchs st0 + ret +patch_code_end5: + push ecx + jmp write_call_func + +# TODO: And this one? +patch_func_6: + pop ecx + push 6 + push 0x0065B959 + call get_code_size6 + .deltaof patch_code6, patch_code_end6 +get_code_size6: + pop eax + push dword [eax] + call patch_code_end6 +patch_code6: + mov ebp, ecx + fld st0, dword [0x00689BD1] + fld st0, dword [esp + 0x30] + fmulp st1, st0 + ret +patch_code_end6: + push ecx + jmp write_call_func diff --git a/system/client-functions/EnemyDamageSync/EnemyDamageSync.59NJ.patch.s b/system/client-functions/EnemyDamageSync/EnemyDamageSync.59NJ.patch.s new file mode 100644 index 00000000..5f9d88ac --- /dev/null +++ b/system/client-functions/EnemyDamageSync/EnemyDamageSync.59NJ.patch.s @@ -0,0 +1,258 @@ +.meta name="DMC" +.meta description="Mitigates effects\nof enemy health\ndesync" +.meta client_flag="0x0000001000000000" + +entry_ptr: +reloc0: + .offsetof start + +write_call_to_code_multi: + .include WriteCallToCodeMulti-59NJ +write_address_of_code: + .include WriteAddressOfCode-59NJ + +start: + + # Replace 6x09 with 6xE4 in subcommand handler table + mov dword [0x00A0DC30], 0x000600E4 # subcommand=0xE4, flags=6 + push 0x00A0DC34 + call +4 + .deltaof handle_6xE4_start, handle_6xE4_end + pop eax + push dword [eax] + call handle_6xE4_end + +handle_6xE4_start: # (G_6xE4* cmd @ [esp + 4]) -> void + push ebx + push esi + push edi + + test byte [0x00AA8DFC], 0x80 + jz handle_6xE4_return + mov ebx, [esp + 0x10] # cmd + movzx eax, word [ebx + 2] + cmp eax, 0x1000 + jl handle_6xE4_return + cmp eax, 0x1B50 + jge handle_6xE4_return + + movzx eax, word [ebx + 2] + .include GetEnemyEntity-59NJ # auto* ene = get_enemy_entity(cmd->header.entity_id); + push eax + + movzx eax, word [ebx + 2] + and eax, 0x0FFF + imul eax, eax, 0x0C + add eax, [0x00AADE38] # eax = state_for_enemy(cmd->header.entity_id) + + cmp dword [ebx + 0x0C], 0 + jl handle_6xE4_not_proportional + mov cx, [ebx + 0x0A] # cmd->max_hp + sub cx, [eax + 0x06] # st.total_damage + movzx ecx, cx + xor edx, edx + cmp ecx, edx + cmovl ecx, edx + push ecx + fild st0, dword [esp] # current_hp = static_cast(max(cmd->max_hp - st.total_damage, 0)) + fld st0, dword [ebx + 0x0C] + fmulp st1, st0 + fistp dword [esp], st0 + mov ecx, dword [esp] # adjusted_hit_amount = static_cast(current_hp * cmd->factor) + add esp, 4 + xor edx, edx + inc edx + cmp ecx, edx + cmovl ecx, edx + mov [ebx + 0x04], cx # cmd->hit_amount = min(1, adjusted_hit_amount) +handle_6xE4_not_proportional: + + movzx edx, word [eax + 0x06] # st.total_damage + movsx esi, word [ebx + 0x04] # cmd->hit_amount + movzx edi, word [ebx + 0x0A] # cmd->max_hp + add edx, esi # st.total_damage + cmd->hit_amount + cmp edx, edi + jl handle_6xE4_damage_less_than_max_hp + mov [eax + 0x06], di # st.total_damage = cmd->max_hp; + mov edx, [eax] + test edx, 0x800 + jnz handle_6xE4_return_pop_ene + or edx, 0x800 + mov [eax], edx + cmp dword [esp], 0 + je handle_6xE4_return_pop_ene + push edx # out_cmd.flags + sub esp, 8 + mov word [esp], 0x030A # out_cmd.header.{subcommand,size} + mov si, [ebx + 2] + mov [esp + 2], si # out_cmd.header.entity_id + and si, 0x0FFF + mov [esp + 4], si # out_cmd.entity_index + mov [esp + 6], di # out_cmd.total_damage + mov ecx, esp + mov edx, 0x00801150 + call edx # send_and_handle_60(&out_cmd); + add esp, 0x10 + jmp handle_6xE4_return + +handle_6xE4_damage_less_than_max_hp: + xor edi, edi + cmp edx, edx + cmovl edx, edi + mov [eax + 0x06], dx # st.total_damage = std::max(st.total_damage + cmd->hit_amount, 0); + + mov edx, eax # edx = ene_st + mov eax, [esp] # eax = ene + test eax, eax + jz handle_6xE4_return_pop_ene + mov ecx, eax + push edx + mov edx, [ecx] + call [edx + 0x148] # ene->vtable[0x52](ene, &st); + +handle_6xE4_return_pop_ene: + add esp, 4 +handle_6xE4_return: + pop edi + pop esi + pop ebx + ret + +handle_6xE4_end: + call write_address_of_code + + + + # Write TObjectV00b421c0::incr_hp_with_sync + push 5 + push 0x00775224 # TObjectV00b421c0::v18_accept_hit (presumably Resta) - this is add_hp, not subtract_hp! + push 5 + push 0x00778063 # TObjectV00b421c0::subtract_hp_if_not_in_state_2 + push 5 + push 0x00777AB2 # TObjectV00b421c0::v19_handle_hit_special_effects + push 5 + push 0x00777B2B # TObjectV00b421c0::v19_handle_hit_special_effects + push 5 + push 0x00777BFC # TObjectV00b421c0::v19_handle_hit_special_effects + push 5 + push 0x00777C75 # TObjectV00b421c0::v19_handle_hit_special_effects + push 5 + push 0x00776D2D # TObjectV00b421c0::v19_handle_hit_special_effects + push 5 + push 0x007769C2 # TObjectV00b421c0::v19_handle_hit_special_effects + push 5 + push 0x0077683C # TObjectV00b421c0::v19_handle_hit_special_effects + push 5 + push 0x00776502 # TObjectV00b421c0::v19_handle_hit_special_effects (Devil's/Demon's) + push 5 + push 0x00775B57 # TObjectV00b421c0::v18_accept_hit + push 5 + push 0x00775A23 # TObjectV00b421c0::v18_accept_hit + push 5 + push 0x007757F0 # TObjectV00b421c0::v18_accept_hit + push 5 + push 0x00775606 # TObjectV00b421c0::v18_accept_hit + push 5 + push 0x007754BC # TObjectV00b421c0::v18_accept_hit + push 5 + push 0x00774E3D # TObjectV00b421c0::v18_accept_hit + push 5 + push 0x00774CD6 # TObjectV00b421c0::v18_accept_hit + push 5 + push 0x00774713 # TObjectV00b421c0::v17 + push 18 + call +4 + .deltaof on_add_or_subtract_hp_start, on_add_or_subtract_hp_end + pop eax + push dword [eax] + call on_add_or_subtract_hp_end + +on_add_or_subtract_hp_start: # (TObjectV00b421c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax + test byte [0x00AA8DFC], 0x80 + jz on_add_or_subtract_hp_skip_send + movzx eax, word [ecx + 0x1C] # ene->entity_id + cmp eax, 0x1000 + jl on_add_or_subtract_hp_skip_send + cmp eax, 0x1B50 + jge on_add_or_subtract_hp_skip_send + + and eax, 0x0FFF + imul eax, eax, 0x0C + add eax, [0x00AADE38] # eax = state_for_enemy(cmd->header.entity_id) + + sub esp, 0x10 + mov word [esp], 0x04E4 + mov dx, [ecx + 0x1C] + mov [esp + 0x02], dx # cmd.entity_id + mov dx, [esp + 0x14] + cmp dword [esp + 0x10], 0x00775229 # Check if callsite is add_hp + jne on_add_or_subtract_hp_skip_negate_amount + neg dx +on_add_or_subtract_hp_skip_negate_amount: + mov [esp + 0x04], dx # cmd.hit_amount + mov dx, [eax + 6] + mov [esp + 0x06], dx # cmd.total_damage_before_hit + mov dx, [ecx + 0x0334] + mov [esp + 0x08], dx # cmd.current_hp + mov dx, [ecx + 0x02BC] + mov [esp + 0x0A], dx # cmd.max_hp + mov dword [esp + 0x0C], 0xBF800000 # cmd.factor + + cmp dword [esp + 0x10], 0x00776507 # Check if callsite is Devil's/Demon's + jne on_add_or_subtract_hp_not_proportional + # esp is 0x18 down from where it is in caller's context + mov edx, 100 + sub edx, [esp + 0x24] # edx = (100 - special_amount) + push edx + fild st0, dword [esp] # current_hp_factor = static_cast(100 - special_amount) + fmul st0, dword [esp + 0x54] # *= weapon_reduction_factor + mov dword [esp], 0x42C80000 # 100.0f + fdiv st0, dword [esp] + add esp, 4 + fstp dword [esp + 0x0C], st0 # cmd.factor = ((100 - special_amount) * weapon_reduction_factor) / 100 +on_add_or_subtract_hp_not_proportional: + + mov edx, esp + push ecx + push 0x10 + push edx + mov ecx, [0x00AA8E04] + mov edx, 0x007D4CBC + call edx # send_60(root_protocol, &cmd, sizeof(cmd)); + pop ecx + add esp, 0x10 + +on_add_or_subtract_hp_skip_send: + mov eax, 0x007781F0 # subtract_hp + mov edx, 0x007781B0 # add_hp + cmp dword [esp], 0x00775229 # Check if callsite is add_hp + cmove eax, edx + jmp eax + +on_add_or_subtract_hp_end: + call write_call_to_code_multi + + + + push 5 + push 0x0078864B + push 1 + call +4 + .deltaof on_6x0A_patch_start, on_6x0A_patch_end + pop eax + push dword [eax] + call on_6x0A_patch_end + +on_6x0A_patch_start: # (TObjectV00b421c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax + test byte [0x00AA8DFC], 0x80 + jz on_6x0A_patch_skip_write + mov [esp + 0x0A], cx +on_6x0A_patch_skip_write: + ret + +on_6x0A_patch_end: + call write_call_to_code_multi + + + + ret diff --git a/system/client-functions/EnemyHPBars/EnemyHPBars.59NL.patch.s b/system/client-functions/EnemyHPBars/EnemyHPBars.5___.patch.s similarity index 55% rename from system/client-functions/EnemyHPBars/EnemyHPBars.59NL.patch.s rename to system/client-functions/EnemyHPBars/EnemyHPBars.5___.patch.s index 72074452..23a6c555 100644 --- a/system/client-functions/EnemyHPBars/EnemyHPBars.59NL.patch.s +++ b/system/client-functions/EnemyHPBars/EnemyHPBars.5___.patch.s @@ -1,45 +1,47 @@ .meta name="Enemy HP bars" .meta description="Shows HP bars in\nenemy info windows" +.versions 59NJ 59NL + entry_ptr: reloc0: .offsetof start start: .include WriteCodeBlocksBB - .data 0x007318DD + .data .data 6 .binary 81E2FDFFFFFF - .data 0x00731F2F + .data .data 1 .binary FA - .data 0x009F2DA4 + .data .data 4 .data 0x42480000 - .data 0x009F2DAC + .data .data 4 .data 0x41C00000 - .data 0x009F2DD4 + .data .data 4 .data 0x42480000 - .data 0x009F2DDC + .data .data 4 .data 0x41C00000 - .data 0x009F2E04 + .data .data 4 .data 0x42480000 - .data 0x009F2E0C + .data .data 4 .data 0x41C00000 - .data 0x009F2E34 + .data .data 4 .data 0x42480000 - .data 0x009F2E3C + .data .data 4 .data 0x41C00000 - .data 0x009F2E64 + .data .data 4 .data 0x42200000 - .data 0x009F2E80 + .data .data 4 .data 0xFF00FF15 .data 0x00000000 diff --git a/system/client-functions/ExitAnywhere/ExitAnywhere.59NL.patch.s b/system/client-functions/ExitAnywhere/ExitAnywhere.59NL.patch.s deleted file mode 100644 index 8e65eaa9..00000000 --- a/system/client-functions/ExitAnywhere/ExitAnywhere.59NL.patch.s +++ /dev/null @@ -1,17 +0,0 @@ -# This function implements $exit in a game when no quest is loaded. - -.meta name="Exit anywhere" -.meta description="" -.meta hide_from_patches_menu - -entry_ptr: -reloc0: - .offsetof start - -start: - xor eax, eax - mov [0x00A95624], eax # is_in_quest = false - mov [0x00A955E0], eax # dat_source_type = NONE - inc eax - mov [0x00AAE6D4], ax # should_leave_game = true - ret diff --git a/system/client-functions/ExitAnywhere/ExitAnywhere.5___.patch.s b/system/client-functions/ExitAnywhere/ExitAnywhere.5___.patch.s new file mode 100644 index 00000000..2ae8c25c --- /dev/null +++ b/system/client-functions/ExitAnywhere/ExitAnywhere.5___.patch.s @@ -0,0 +1,19 @@ +# This function implements $exit in a game when no quest is loaded. + +.meta name="Exit anywhere" +.meta description="" +.meta hide_from_patches_menu + +.versions 59NJ 59NL + +entry_ptr: +reloc0: + .offsetof start + +start: + xor eax, eax + mov [], eax # is_in_quest = false + mov [], eax # dat_source_type = NONE + inc eax + mov [], ax # should_leave_game = true + ret diff --git a/system/client-functions/FastTekker/FastTekker.59NL.patch.s b/system/client-functions/FastTekker/FastTekker.5___.patch.s similarity index 80% rename from system/client-functions/FastTekker/FastTekker.59NL.patch.s rename to system/client-functions/FastTekker/FastTekker.5___.patch.s index df7ca989..049a6b0b 100644 --- a/system/client-functions/FastTekker/FastTekker.59NL.patch.s +++ b/system/client-functions/FastTekker/FastTekker.5___.patch.s @@ -1,19 +1,21 @@ .meta name="Fast tekker" .meta description="Skips wind-up sound\nat tekker window" +.versions 59NJ 59NL + entry_ptr: reloc0: .offsetof start start: .include WriteCodeBlocksBB - .data 0x006DA113 + .data .deltaof patch1_start, patch1_end patch1_start: mov dword [edi + 0x14C], 1 patch1_end: - .data 0x006DA130 + .data .deltaof patch2_start, patch2_end patch2_start: nop diff --git a/system/client-functions/HungryMagSound/HungryMagSound.59NJ.patch.s b/system/client-functions/HungryMagSound/HungryMagSound.59NJ.patch.s new file mode 100644 index 00000000..46644072 --- /dev/null +++ b/system/client-functions/HungryMagSound/HungryMagSound.59NJ.patch.s @@ -0,0 +1,34 @@ +.meta name="MAG alert" +.meta description="Plays a sound when\nyour MAG is hungry" + +entry_ptr: +reloc0: + .offsetof start +start: + pop ecx + push 6 + push 0x005D91BE + call get_code_size + .deltaof patch_code, patch_code_end +get_code_size: + pop eax + push dword [eax] + call patch_code_end +patch_code: # [eax] (TItemMag* this @ ecx) -> void + mov dword [ecx + 0x01B8], eax + mov eax, [ecx + 0x00F8] + movzx eax, word [eax + 0x001C] # eax = this->owner_player->entity_id + cmp [0x00A9A074], eax + jne patch_code_skip_sound + push 0 + push 0 + push 0 + push 0xAC + mov eax, 0x00815020 + call eax + add esp, 0x10 +patch_code_skip_sound: + ret +patch_code_end: + push ecx + .include WriteCallToCode-59NJ diff --git a/system/client-functions/NoRareSelling/NoRareSelling.59NJ.patch.s b/system/client-functions/NoRareSelling/NoRareSelling.59NJ.patch.s new file mode 100644 index 00000000..f624e96d --- /dev/null +++ b/system/client-functions/NoRareSelling/NoRareSelling.59NJ.patch.s @@ -0,0 +1,43 @@ +# Original patch by Soly, in Blue Burst Patch Project +# https://github.com/Solybum/Blue-Burst-Patch-Project + +.meta name="No rare selling" +.meta description="Stops you from accidentally\nselling rares to vendors" + +entry_ptr: +reloc0: + .offsetof start +start: + # This works by setting the item price to zero if it's rare, which causes + # the game to prevent you from selling the item. For armors and weapons, this + # is easy because there are easily-patchable opcodes within branches that + # return a constant price for rare items. + xor eax, eax + mov [0x005D26EB], eax # Rare armors + mov [0x005D26D1], eax # Unidentified weapons + mov [0x005D26E6], eax # Rare weapons + + # For tools, it's harder to implement this, because the price comes from the + # ItemPMT tools table and there is no branch for rares. Still, we can add a + # branch to a stub to handle tools. + pop ecx + push 5 + push 0x005D2508 + call get_code_size + .deltaof patch_code, patch_code_end +get_code_size: + pop eax + push dword [eax] + call patch_code_end +patch_code: + # TODO: It'd be nice to have something like WriteJumpToAndFromCode, since + # this hook is supposed to return to a different place than where it was + # called, hence this mov [esp]. + mov dword [esp], 0x005D2556 + xor edi, edi + test byte [eax + 0x14], 0x80 # flags & 0x80 = is rare + cmovz edi, [eax + 0x10] # Use price from table if not rare + ret +patch_code_end: + push ecx + .include WriteCallToCode-59NL diff --git a/system/client-functions/Palette/Palette.59NJ.patch.s b/system/client-functions/Palette/Palette.59NJ.patch.s new file mode 100644 index 00000000..a1ada3b3 --- /dev/null +++ b/system/client-functions/Palette/Palette.59NJ.patch.s @@ -0,0 +1,230 @@ +# Original patch by Soly, in Blue Burst Patch Project +# https://github.com/Solybum/Blue-Burst-Patch-Project + +.meta name="Palette" +.meta description="Enables the alternate action\npalette for number keys" + +entry_ptr: +reloc0: + .offsetof start + +write_call_func: + .include WriteCallToCode-59NJ + +start: + mov al, 0xEB + mov [0x0068A7A5], al # SecondaryPaletteAttack1 + xor al, al + mov [0x006A11B7], al # SecondaryPaletteAttack2 + mov [0x006A0CB7], al # SecondaryPaletteAttack3 + + call patch_func_1 # GetCurrentPalette + call patch_func_2 # CheckHotkey1_1 + call patch_func_3 # CheckHotkey1_2 + call patch_func_4 # CheckHotkey2_1 + call patch_func_5 # CheckHotkey2_2 + call patch_func_6 # CheckHotkey3_1 + call patch_func_7 # CheckHotkey3_2 + jmp write_code_blocks # UnsetHotkey1, UnsetHotkey2, SetHotkey + +# GetCurrentPalette +patch_func_1: + pop ecx + push 8 + push 0x00748990 + call get_code_size1 + .deltaof patch_code1, patch_code_end1 +get_code_size1: + pop eax + push dword [eax] + call patch_code_end1 +patch_code1: + mov edx, [ebp - 0x14] + mov edx, [edx + 0x2C] + movzx edx, byte [edx + 0x62] + test edx, edx + setnz byte [0x00748B1B] + mov edx, edi + and edx, 0xFF + ret +patch_code_end1: + push ecx + jmp write_call_func + +# CheckHotkey1_1 +patch_func_2: + pop ecx + push 5 + push 0x007489DE + call get_code_size2 + .deltaof patch_code2, patch_code_end2 +get_code_size2: + pop eax + push dword [eax] + call patch_code_end2 +patch_code2: + cmp byte [0x00748B1B], 0 + jnz +0x06 + movzx edx, byte [eax + esi * 4 + 0x04] # main palette + ret + movzx edx, byte [eax + esi * 4 + 0x3C] # alt palette + ret +patch_code_end2: + push ecx + jmp write_call_func + +# CheckHotkey1_2 +patch_func_3: + pop ecx + push 5 + push 0x007489ED + call get_code_size3 + .deltaof patch_code3, patch_code_end3 +get_code_size3: + pop eax + push dword [eax] + call patch_code_end3 +patch_code3: + cmp byte [0x00748B1B], 0 + jnz +0x06 + movzx ecx, byte [eax + ecx * 2 + 0x05] # main palette + ret + movzx ecx, byte [eax + ecx * 2 + 0x3D] # alt palette + ret +patch_code_end3: + push ecx + jmp write_call_func + +# CheckHotkey2_1 +patch_func_4: + pop ecx + push 5 + push 0x00748A88 + call get_code_size4 + .deltaof patch_code4, patch_code_end4 +get_code_size4: + pop eax + push dword [eax] + call patch_code_end4 +patch_code4: + cmp byte [0x00748B1B], 0 + jnz +0x06 + movzx edx, byte [edx + ebx * 4 + 0x04] # main palette + ret + movzx edx, byte [edx + ebx * 4 + 0x3C] # alt palette + ret +patch_code_end4: + push ecx + jmp write_call_func + +# CheckHotkey2_2 +patch_func_5: + pop ecx + push 5 + push 0x00748A97 + call get_code_size5 + .deltaof patch_code5, patch_code_end5 +get_code_size5: + pop eax + push dword [eax] + call patch_code_end5 +patch_code5: + cmp byte [0x00748B1B], 0 + jnz +0x06 + movzx ecx, byte [edx + eax * 2 + 0x05] # main palette + ret + movzx ecx, byte [edx + eax * 2 + 0x3D] # alt palette + ret +patch_code_end5: + push ecx + jmp write_call_func + +# CheckHotkey3_1 +patch_func_6: + pop ecx + push 5 + push 0x007103D3 + call get_code_size6 + .deltaof patch_code6, patch_code_end6 +get_code_size6: + pop eax + push dword [eax] + call patch_code_end6 +patch_code6: + cmp byte [0x00748B1B], 0 + jnz +0x06 + movzx ecx, byte [eax + edx * 4 + 0x04] # main palette + ret + movzx ecx, byte [eax + edx * 4 + 0x3C] # alt palette + ret +patch_code_end6: + push ecx + jmp write_call_func + +# CheckHotkey3_2 +patch_func_7: + pop ecx + push 5 + push 0x007103DC + call get_code_size7 + .deltaof patch_code7, patch_code_end7 +get_code_size7: + pop eax + push dword [eax] + call patch_code_end7 +patch_code7: + cmp byte [0x00748B1B], 0 + jnz +0x06 + movzx ecx, byte [eax + edx * 4 + 0x05] # main palette + ret + movzx ecx, byte [eax + edx * 4 + 0x3D] # alt palette + ret +patch_code_end7: + push ecx + jmp write_call_func + +write_code_blocks: + .include WriteCodeBlocksBB + + .data 0x00748A05 + .deltaof code_block1_start, code_block1_end + +# UnsetHotkey1 +code_block1_start: + push dword [0x00748B1B] + push eax + mov eax, 0x0068CE4C # SetPaletteHotkey + call eax + .binary 909090909090909090 +code_block1_end: + .data 0x00748AAB + .deltaof code_block2_start, code_block2_end + +# UnsetHotkey2 +code_block2_start: + push dword [0x00748B1B] + push eax + mov eax, 0x0068CE4C # SetPaletteHotkey + call eax + .binary 909090909090909090 +code_block2_end: + .data 0x00748B0A + .deltaof code_block3_start, code_block3_end + +# SetHotkey +code_block3_start: + mov eax, [ebp - 0x24] + mov ecx, [ebp - 0x28] + movzx ebx, word [eax] + movzx edx, word [eax + 0x02] + push edx + push ebx + push esi + .binary 6800000000 # tmpCurrentPalette = 0x00748B1B + push 0 + mov eax, 0x0068CE4C # SetPaletteHotkey + call eax + .binary 90909090909090909090909090909090 +code_block3_end: + .data 0x00000000 + .data 0x00000000