Th06/Binary hacks
< Th06
Jump to navigation
Jump to search
Development of this patch has moved to GitHub. Please use the Issues page there to discuss possible improvements or additions to this patch, or simply send a pull request. For now, the existing wiki pages of this patch will remain for the sake of documentation, but they are no longer functional. |
Bugs
Fix buffer overflows (remove copy)(buffer_overflow_rem ) |
||
---|---|---|
Description | This is caused by needlessly copying the string argument to a local variable limited to 64 bytes. If the line exceeds this buffer, the game crashes. We fix it by removing the copy function and simply passing the pointer to the original text data. | |
Address |
|
|
Code | eb 19 90 jmp short +19h
nop
|
Fix buffer overflows (replace EAX)(buffer_overflow_rep_eax ) |
||
---|---|---|
Address |
|
|
Code | 8b45 18 mov eax, [ebp+18]
|
Fix buffer overflows (replace ECX)(buffer_overflow_rep_ecx ) |
||
---|---|---|
Address |
|
|
Code | 8b4d 18 mov ecx, [ebp+18]
|
Text alignment
Boss title alignment(boss_title_align ) |
||
---|---|---|
Description | * Call GetTextExtent on string to render
|
|
Address |
|
|
Code | 8b 45 18 50 e8 [GetTextExtent] 83 c0 04 50 3e db 04 e4 58 mov eax, [ebp+18]
push eax
call [GetTextExtent]
add eax, 4
push eax
fild dword ptr ds:[esp]
pop eax
|
Spell card and bomb text alignment(spell_align ) |
||
---|---|---|
Description | The English patch has its own hackish text length calculation, replacing the original string length loop before the FPU operations. We don't need that loop anyway, so we jump over it.
The rest is the same as above, just with different stack addresses and a jump over nonsensical calculations at the end. And yes, this is binarily identical for player bombs and enemy spells! |
|
Address |
|
|
Code | eb 25 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 8b 45 0c 50 e8 [GetTextExtent] 50 3e db 04 e4 58 eb 0b jmp +25h
nop (*25h)
mov eax, [ebp+c]
push eax
call [GetTextExtent]
push eax
fild dword ptr ds:[esp]
pop eax
jmp +0bh
|
Stage title alignment(stage_title_align ) |
||
---|---|---|
Description | Same, except that we divide the width by 2 here. | |
Address |
|
|
Code | 8b 45 18 50 e8 [GetTextExtent] d1 f8 83 c0 04 50 3e db 04 e4 58 eb 18 mov eax, [ebp+18]
push eax
call [GetTextExtent]
sar eax, 1
add eax, 1
push eax
fild dword ptr ds:[esp]
pop eax
jmp short +18
|
Fix spell align sillyness(spell_align_sillyness ) |
||
---|---|---|
Description | NOPing out a multiplication with 15 followed by a division by 16 correctly aligns spell card names as expected. Why ZUN did that is beyond me. | |
Address |
|
|
Code | 90 90 90 90 90 90 90 90 90 90 90 90 nop (*0bh)
|
Spell cards
Prepare ECL instruction register for spell ID fetching(spell_prepare ) |
||
---|---|---|
Description | Loads ESI with a pointer to the ECL instruction structure and reorders a couple of assignments to not break the code. ESI is not read or modified between this hack and spell_fetch_id where we need it. | |
Address |
|
|
Code | 8b75 e4 89f1 83c1 0c 894d e8 0fbf46 04 90 mov esi, dword ptr ss:[ebp-1c]
mov ecx, esi
add ecx, 0ch
mov dword ptr ss:[ebp-18], ecx
movsx eax, word ptr ds:[esi+4]
nop
|
Fetch spell ID(spell_fetch_id ) |
||
---|---|---|
Description | With the ECL instruction structure in ESI, we can optimize the element accesses, and end up with just enough space to fetch the spell card number into ECX. (This crashes the game without spell_prepare applied, maybe we should do something about that.) | |
Address |
|
|
Code | 0fbf4e 0e 89f0 83c0 10 50 0fbf56 0c movsx ecx, word ptr ds:[esi+0e] ; ECX = spell card number
mov eax, esi
add eax, 10 ; EAX = spell card name
push eax ; insert breakpoint here
movsx edx, word ptr ds:[esi+0c] ; EDX = face ID
|
Compatibility
Remove English patch spell translation lookup in the Result screen(unpatch_result_spell ) |
||
---|---|---|
Description | Necessary because we wouldn't be able to set any spell breakpoint, since the addresses we'd need differ between the original and the English patch. And since we have to do something about it anyway, we also keep the spell number in EAX to save one breakpoint. | |
Address |
|
|
Code | 89c1 c1e1 06 81c1 e8bc6900 51 6a 00 68 ffffff00 mov ecx,eax
shl ecx,6
add ecx,0x69bce8
push ecx
push 0
push 0xffffff
|
[[th06_custom|]] (th06_custom)
Translate pad input check(translate_padinput ) |
||
---|---|---|
Address |
|
|
Code | 89c3 6a 00 e8 [strings_strclr] f6c3 10 74 0e 68 dc914000 6a 00 e8 [strings_strcat] 59 59 f6c3 20 74 0e 68 d8914000 6a 00 e8 [strings_strcat] 59 59 f6c3 40 74 0e 68 d4914000 6a 00 e8 [strings_strcat] 59 59 f6c3 80 74 0e 68 d0914000 6a 00 e8 [strings_strcat] 59 59 eb 1a 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 mov ebx,eax
push 0
call [strings_strclr]
; Up
test bl,10
je short +0xe
push offset custom.004091DC
push 0
call [strings_strcat]
pop ecx
pop ecx
; Down
test bl,20
je short +0xe
push offset custom.004091D8
push 0
call [strings_strcat]
pop ecx
pop ecx
; Left
test bl,40
je +0xe
push offset custom.004091D4
push 0
call [strings_strcat]
pop ecx
pop ecx
; Right
test bl,80
je +0xe
push offset custom.004091D0
push 0
call [strings_strcat]
pop ecx
pop ecx
jmp short +0x1a
nop (*0x1a)
|