User:Kmeisthax/Findings/2011/6/21/v84-85 Patch Notes

From Wikifang, a definitive guide to Telefang, Dino Device and Bugsite
Jump to navigation Jump to search

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...