User:Kmeisthax/Findings/2011/6/21/v84-85 Patch Notes
VWF "disable" hack
Okay, time to defrag the VWF routine. Seriously, I was hoping to at least put this off to tomorrow...
Let's fix up the relajumps, first, then delete the NOPs.
ROM:0002FA2D ld a, b ;78 2FA2E call 2FC3F ;CD 3F 7C 31 nop 2 nop 3 nop 4 nop 5 nop ; 5 free bytes ROM:0002FA36 pop af ROM:0002FA37 push hl ROM:0002FA38 push af ROM:0002FA39 or a ROM:0002FA3A jr z, loc_FA47+2 ;Rela-Jump fwd. subtract 5 bytes, get 08 ROM:0002FA3C ld hl, $10 ROM:0002FA3F add hl, de ROM:0002FA40 ld a, c ;79 41 call 2FC3F ;CD 3F 7C 4 nop 5 nop 6 nop 7 nop 8 nop ; 5 more free bytes ROM:0002FA49 ei ROM:0002FA4A pop af ROM:0002FA4B pop hl ROM:0002FA4C pop de ROM:0002FA4D pop bc ROM:0002FA4E inc de ROM:0002FA4F dec b ROM:0002FA50 jr nz, loc_F9E4+2 ;Rela-Jump back. add 0xA / 10 bytes, get 9E ROM:0002FA52 ld a, 0 ROM:0002FA54 ld [WRAM_VWF_OldTileMode], a ROM:0002FA57 ld b, $7B ; '{' ROM:0002FA59 ld a, [WRAM_VWF_CurrentLetter] ROM:0002FA5C ld c, a ROM:0002FA5D ld a, [bc] ROM:0002FA5E inc a ROM:0002FA5F ld b, a ROM:0002FA60 ld a, [WRAM_VWF_GlyphShift] ROM:0002FA63 add a, b ROM:0002FA64 bit 3, a ROM:0002FA66 jr z, loc_FA7D ;Rela-Jump fwd. No change ROM:0002FA68 sub 8 ROM:0002FA6A push af ROM:0002FA6B ld a, 1 ROM:0002FA6D ld [WRAM_VWF_OldTileMode], a ROM:0002FA70 ld a, [byte_C7C6] ROM:0002FA73 cp 1 ROM:0002FA75 jr nz, unk_FA7C ;Rela-Jump fwd. no change ROM:0002FA77 ld a, 0 ROM:0002FA79 ld [byte_C7C6], a ROM:0002FA7C pop af ROM:0002FA7D ld [WRAM_VWF_GlyphShift], a ROM:0002FA80 ret ROM:0002FA80 ; --------------------------------------------------------------------------- ROM:0002FA81 db 0 ROM:0002FA82 db 0 ROM:0002FA83 db 0 ROM:0002FA84 db 0 ROM:0002FA85 db 0 ROM:0002FA86 db 0 ROM:0002FA87 db 0
I deleted 10 bytes from those nop-slides and inserted 10 nops at 2FA81, moving back all the code so that it's a single solid routine again. With that, let's insert some code. We need to check if a particular byte in the VWF state is set. The C7Cx line is allocated for VWF usage, so we'll use the next available byte: C7C8. You may think C7C7 is available but it's not because I already allocate it for an already-assembled-but-not-yet-injected Word Wrap hack.
WRAM C7C8: WRAM_VWF_Disable
When 1, this byte will cause the VWF to draw every letter as 8px wide irregardless of it's actual width. Our advice looks like this:
.VWFDisableAdvice: ld a, [WRAM_VWF_Disable] or a jr z, .VWFEnabled ld a, 8 jr .AccumGlyphSize
We'll just insert it straight into the current routine. Like so:
(Also: these rom line numbers are COMPLETELY INACCURATE! I wrote this before implementing the ROM, so I can't make IDA redisassemble it. lol)
ROM:0002FA4A pop af ROM:0002FA4B pop hl ROM:0002FA4C pop de ROM:0002FA4D pop bc ROM:0002FA4E inc de ROM:0002FA4F dec b ROM:0002FA50 jr nz, loc_F9E4+2 ;Rela-Jump back. add 0xA / 10 bytes, get 9E ROM:0002FA52 ld a, 0 ROM:0002FA54 ld [WRAM_VWF_OldTileMode], a ROM:0002FA57 ld b, $7B ; '{' ROM:0002FA59 ld a, [WRAM_VWF_CurrentLetter] ROM:0002FA5C ld c, a .VWFDisableAdvice: ld a, [WRAM_VWF_Disable] ;FA C8 C7 or a ;B7 jr z, .VWFEnabled ;28 04 ld a, 8 ;3E 08 jr .AccumGlyphSize ;18 02 .VWFEnabled: ROM:0002FA5D ld a, [bc] ROM:0002FA5E inc a .AccumGlyphSize: ROM:0002FA5F ld b, a ROM:0002FA60 ld a, [WRAM_VWF_GlyphShift]
Hey, nicknaming is working pretty well now! Let's find a routine to disable the VWF with...
The nickname screen is drawn with the Main Script, so we need to define VWF control codes like so:
Control Code EA = VWF Disable Control Code EB = VWF Enable
Main Script lives at B:4100, and the 1st Script Interpreter State lives at B:413C. We'll insert some advice here:
ROM:0002C1BA ; --------------------------------------------------------------------------- ROM:0002C1BA cp $E0 ; 'a' ; Return from script ROM:0002C1BC jr nz, 2C1D3 ROM:0002C1BE ld a, [WRAM_MainScript_CodePtrSpill0] ROM:0002C1C1 ld [WRAM_MainScript_TextPtr0], a ROM:0002C1C4 ld a, [WRAM_MainScript_CodePtrSpill1] ROM:0002C1C7 ld [WRAM_MainScript_TextPtr1], a ROM:0002C1CA call 2c337 ;this routine moves up the script pointer ROM:0002C1CD call 2c337 ROM:0002C1D0 jp 2c313 ROM:0002C1D3 ; --------------------------------------------------------------------------- ROM:0002C1D3 cp $E1 ; 'ß' ROM:0002C1D5 jp nc, 2C337 ; filters out unknown control codes ROM:0002C1D8 ld a, [byte_C9CC] ROM:0002C1DB or a ROM:0002C1DC jp z, 2c1e3 ROM:0002C1DF dec a
Specifically, let's change the cp/jr at 2C1BA to a nop/jump to an advice routine:
ROM:0002C1BA nop ;00 ROM:0002C1BB jp .MSNewControlCodes ;C3 89 7C
.MSNewControlCodes: cp $E0 ; Return from script FE E0 jp z, 2C1BE ;CA BE 41 cp $EA ;FE EA jr nz, .NotDisableCode ;20 08 ;VWF Disable ld a, 1 ;3E 01 ld [WRAM_VWF_Disable], a ;EA C8 C7 jp 2c313 ;exit ;C3 13 43 .NotDisableCode cp $EB ;FE EB jp nz, 2C1D3 ;next check in the sequence in the original routine ;C2 D3 41 xor a ;AF ld [WRAM_VWF_Disable], a ;EA C8 C7 jp 2c313 ;exit C3 13 43
We'll assemble the routine and stick it in 2FC89 (B:7C89), as it's the current free space I mentioned in the last set of patch notes. The routine is 1D bytes long, and thus the new free space pointer is 2FCA6.
Now we have to find some scripts to inject into. Here's some pointers!
BANK 45:5013 (This is 114060.)
Sadly I have no text insertion tools, so brb writing a python package for it...