User:Kmeisthax/Findings/2011/6/19/v83 Patch Notes

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

Multi-Text Mode VWF Hack

There are four 'text modes' in Telefang:

Mode 0: Common text. This is currently the only text type VWF'd. The glyph is drawn out on both bitplanes, like so:

   10110101
   10110101

Mode 1: D-Shot text. The glyph is drawn on the first bitplane, and the second is all white:

   10110101
   11111111

Mode 2: Inverted text (possibly used on intro cutscene text) The glyph is drawn on both bitplanes, inverted:

   01001010
   01001010

Mode 3: ??? text. The glyph is drawn on the second bitplane, and the first is all white:

   11111111
   10110101

The VWF is split into two routines: The "entry point" VWF advice, which every text routine ends up calling now. And the VWF core routine, which does the actual heavy lifting of drawing tiles. Nothing calls the VWF core directly other than the VWF advice. Here's a disassembled listing of the VWF advice routine:

   ROM:0002CE29 ; ---------------------------------------------------------------------------
   ROM:0002CE29                 jp      2FC00
   ROM:0002CE2C ; ---------------------------------------------------------------------------
   ROM:0002CE2C                 add     a, a
   ROM:0002CE2D                 jr      nc, 2CE30
   ROM:0002CE2F                 inc     b
   ROM:0002CE30                 sla     a
   ROM:0002CE32                 rl      b
   ROM:0002CE34                 sla     a
   ROM:0002CE36                 rl      b
   ROM:0002CE38                 ld      c, a
   ROM:0002CE39                 ld      hl, $5229
   ROM:0002CE3C                 add     hl, bc
   ROM:0002CE3D                 ld      d, h
   ROM:0002CE3E                 ld      e, l
   ROM:0002CE3F                 pop     hl
   ROM:0002CE40                 ld      a, [WRAM_TextStyle]
   ROM:0002CE43                 cp      0
   ROM:0002CE45                 jr      z, loc_CE53
   ROM:0002CE47                 cp      1
   ROM:0002CE49                 jr      z, loc_CE65
   ROM:0002CE4B                 cp      2
   ROM:0002CE4D                 jr      z, loc_CE79
   ROM:0002CE4F                 cp      3
   ROM:0002CE51                 jr      z, loc_CE8C
   ROM:0002CE53                 call    2F9C1           ; VWF Core
   ROM:0002CE56                 jr      2CE64
   ROM:0002CE58 ; ---------------------------------------------------------------------------
   ROM:0002CE58                 and     2               ; Dead code (used to be Textmode 0 pre VWF)
   ROM:0002CE5A                 jr      nz, loc_CE56
   ROM:0002CE5C                 ld      a, [de]
   ROM:0002CE5D                 ldi     [hl], a
   ROM:0002CE5E                 ldi     [hl], a
   ROM:0002CE5F                 ei
   ROM:0002CE60                 inc     de
   ROM:0002CE61                 dec     b
   ROM:0002CE62                 jr      nz, loc_CE55
   ROM:0002CE64                 ret                     ; this is actually jumped to,
   ROM:0002CE64                                         ; you just don't get a label
   ROM:0002CE64                                         ; because IDA sucks for banked
   ROM:0002CE64                                         ; ROM disassembly
   ROM:0002CE65 ; ---------------------------------------------------------------------------
   ROM:0002CE65                 ld      b, 8            ; Textmode 1: D-Shot Menu
   ROM:0002CE67                 di
   ROM:0002CE68                 ld      a, [byte_FF41]
   ROM:0002CE6A                 and     2
   ROM:0002CE6C                 jr      nz, loc_CE67+1
   ROM:0002CE6E                 ld      a, [de]
   ROM:0002CE6F                 ldi     [hl], a
   ROM:0002CE70                 ld      a, $FF
   ROM:0002CE72                 ldi     [hl], a
   ROM:0002CE73                 ei
   ROM:0002CE74                 inc     de
   ROM:0002CE75                 dec     b
   ROM:0002CE76                 jr      nz, loc_CE67
   ROM:0002CE78                 ret
   ROM:0002CE79 ; ---------------------------------------------------------------------------
   ROM:0002CE79                 ld      b, 8            ; Textmode 2
   ROM:0002CE7B                 di
   ROM:0002CE7C                 ld      a, [byte_FF41]
   ROM:0002CE7E                 and     2
   ROM:0002CE80                 jr      nz, loc_CE7C
   ROM:0002CE82                 ld      a, [de]
   ROM:0002CE83                 cpl
   ROM:0002CE84                 ldi     [hl], a
   ROM:0002CE85                 ldi     [hl], a
   ROM:0002CE86                 ei
   ROM:0002CE87                 inc     de
   ROM:0002CE88                 dec     b
   ROM:0002CE89                 jr      nz, loc_CE7B
   ROM:0002CE8B                 ret
   ROM:0002CE8C ; ---------------------------------------------------------------------------
   ROM:0002CE8C                 ld      b, 8            ; Textmode 3
   ROM:0002CE8E                 di
   ROM:0002CE8F                 ld      a, [byte_FF41]
   ROM:0002CE91                 and     2
   ROM:0002CE93                 jr      nz, loc_CE8F
   ROM:0002CE95                 ld      a, $FF
   ROM:0002CE97                 ldi     [hl], a
   ROM:0002CE98                 ld      a, [de]
   ROM:0002CE99                 ldi     [hl], a
   ROM:0002CE9A                 ei
   ROM:0002CE9B                 inc     de
   ROM:0002CE9C                 dec     b
   ROM:0002CE9D                 jr      nz, loc_CE8E
   ROM:0002CE9F                 ret
   ROM:0002CE9F ; ---------------------------------------------------------------------------

WRAM_TextStyle lives in WRAM CDB1, and it controls the color of the text. Sadly, the previous hacker who worked on VWF did not bother to make his VWF handle multiple text styles and instead decided to make it such that all other kinds of text styles don't touch the VWF. Sadly, with the enabling of status item VWFing, this also means that setting the text mode has the side effect of never allowing more than one letter to be drawn at a time.

So let's make our text VWF. First off, this also means ALL of the textmode code is dead now, so the VWF routine should just look like this:

   ROM:0002CE29 ; ---------------------------------------------------------------------------
   ROM:0002CE29                 jp      2FC00
   ROM:0002CE2C ; ---------------------------------------------------------------------------
   ROM:0002CE2C                 add     a, a
   ROM:0002CE2D                 jr      nc, 2CE30
   ROM:0002CE2F                 inc     b
   ROM:0002CE30                 sla     a
   ROM:0002CE32                 rl      b
   ROM:0002CE34                 sla     a
   ROM:0002CE36                 rl      b
   ROM:0002CE38                 ld      c, a
   ROM:0002CE39                 ld      hl, $5229
   ROM:0002CE3C                 add     hl, bc
   ROM:0002CE3D                 ld      d, h
   ROM:0002CE3E                 ld      e, l
   ROM:0002CE3F                 pop     hl
   ROM:0002CE40                 call    2F9C1           ; VWF Core
                                                        ; CD C1 79
   ROM:0002CE43                 ret                     ; C9
   ROM:0002CE43 ; ---------------------------------------------------------------------------
       to       ; FREE PARKING^WSPACE (Do not pass go, do not collect 0x5C bytes)
   ROM:0002CE9F ; ---------------------------------------------------------------------------

We get a whole nother 5C bytes out of the deal. Awesome. Now let's look at the VWF core...

This is an updated version of my earlier ROM B:79C1 disassembly. Relative jumps aren't properly corrected because I didn't bother to correct them. The relevant variables start from C7C1, and are:

   WRAM_VWF_CurrentLetter
   WRAM_VWF_GlyphShift
   WRAM_VWF_SPILL_CompositingArea
   WRAM_VWF_SPILL_CompositingArea + 1
   WRAM_VWF_OldTileMode
   WRAM_VWF_MainScriptHack
   ROM:0002F9C1 ; ---------------------------------------------------------------------------
   ROM:0002F9C1                 ld      b, 8
   ROM:0002F9C3                 ld      a, $CF ; '-'
   ROM:0002F9C5                 ld      [WRAM_VWF_SPILL_CompositingArea], a
   ROM:0002F9C8                 ld      a, $D0 ; '-'
   ROM:0002F9CA                 ld      [WRAM_VWF_SPILL_CompositingArea1], a
   ROM:0002F9CD                 push    hl
   ROM:0002F9CE                 push    bc
   ROM:0002F9CF                 ld      a, [WRAM_VWF_CurrentLetter]
   ROM:0002F9D2                 ld      h, $7B ; '{'
   ROM:0002F9D4                 ld      l, a
   ROM:0002F9D5                 xor     a
   ROM:0002F9D6                 ld      b, [hl]
   ROM:0002F9D7                 ld      a, [WRAM_VWF_GlyphShift]
   ROM:0002F9DA                 add     a, b
   ROM:0002F9DB                 bit     3, a
   ROM:0002F9DD                 jr      nz, loc_F9E2
   ROM:0002F9DF                 xor     a
   ROM:0002F9E0                 jr      loc_F9E4
   ROM:0002F9E2 ; ---------------------------------------------------------------------------
   ROM:0002F9E2                 ld      a, 1
   ROM:0002F9E4                 pop     bc
   ROM:0002F9E5                 pop     hl
   ROM:0002F9E6                 push    bc
   ROM:0002F9E7                 push    de
   ROM:0002F9E8                 push    hl
   ROM:0002F9E9                 push    af
   ROM:0002F9EA                 di
   ROM:0002F9EB                 ld      a, [WRAM_VWF_SPILL_CompositingArea]
   ROM:0002F9EE                 ld      h, a
   ROM:0002F9EF                 ld      a, [WRAM_VWF_SPILL_CompositingArea1]
   ROM:0002F9F2                 ld      l, a
   ROM:0002F9F3                 ld      b, [hl]
   ROM:0002F9F4                 inc     hl
   ROM:0002F9F5                 ld      c, [hl]
   ROM:0002F9F6                 dec     hl
   ROM:0002F9F7                 ld      a, [de]
   ROM:0002F9F8                 ld      d, a
   ROM:0002F9F9                 ld      e, 0
   ROM:0002F9FB                 ld      a, [WRAM_VWF_OldTileMode]
   ROM:0002F9FE                 cp      2
   ROM:0002FA00                 jr      z, loc_FA07+1
   ROM:0002FA02                 cp      1
   ROM:0002FA04                 jr      z, loc_FA0A
   ROM:0002FA06                 jr      loc_FA0A+1
   ROM:0002FA08 ; ---------------------------------------------------------------------------
   ROM:0002FA08                 ld      c, 0
   ROM:0002FA0A                 ld      b, c
   ROM:0002FA0B                 ld      a, [WRAM_VWF_GlyphShift]
   ROM:0002FA0E                 or      a
   ROM:0002FA0F                 jr      z, loc_FA18
   ROM:0002FA11                 srl     d
   ROM:0002FA13                 rr      e
   ROM:0002FA15                 dec     a
   ROM:0002FA16                 jr      nz, loc_FA10+1
   ROM:0002FA18                 ld      a, d
   ROM:0002FA19                 or      b
   ROM:0002FA1A                 ld      b, a
   ROM:0002FA1B                 ld      c, e
   ROM:0002FA1C                 ld      [hl], b
   ROM:0002FA1D                 inc     hl
   ROM:0002FA1E                 ld      [hl], c
   ROM:0002FA1F                 inc     hl
   ROM:0002FA20                 ld      a, h
   ROM:0002FA21                 ld      [WRAM_VWF_SPILL_CompositingArea], a
   ROM:0002FA24                 ld      a, l
   ROM:0002FA25                 ld      [WRAM_VWF_SPILL_CompositingArea1], a
   ROM:0002FA28                 pop     af
   ROM:0002FA29                 pop     hl
   ROM:0002FA2A                 ld      d, h
   ROM:0002FA2B                 ld      e, l
   ROM:0002FA2C                 push    af
   ROM:0002FA2D                 ld      a, [byte_FF41]
   ROM:0002FA2F                 and     2
   ROM:0002FA31                 jr      nz, loc_FA2C+1  ; Wait for blanking
   ROM:0002FA33                 ld      a, b
   ROM:0002FA34                 ldi     [hl], a
   ROM:0002FA35                 ldi     [hl], a
   ROM:0002FA36                 pop     af
   ROM:0002FA37                 push    hl
   ROM:0002FA38                 push    af
   ROM:0002FA39                 or      a
   ROM:0002FA3A                 jr      z, loc_FA47+2
   ROM:0002FA3C                 ld      hl, $10
   ROM:0002FA3F                 add     hl, de
   ROM:0002FA40                 ld      a, [byte_FF41]
   ROM:0002FA42                 and     2
   ROM:0002FA44                 jr      nz, loc_FA3F+1  ; Wait for Blanking
   ROM:0002FA46                 ld      a, c
   ROM:0002FA47                 ldi     [hl], a
   ROM:0002FA48                 ldi     [hl], a
   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
   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
   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
   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

We have a bit of extra space but that doesn't matter right now. We want to insert some advice. It'll be in the form of a subroutine call because we want to insert it in two places and we're already jumping out of the function (we don't have nearly enough room to do it inline). Our params will be:

   a    1bpp glyph
   hl   place to draw to
   VWFColorizeGlyph:
       push    bc                              ;C5
       ld      b, a                            ;47
       ld      a, [WRAM_TextStyle]             ;FA B1 CD
       bit     0, a                            ;CB 47
       jr      nz, .VWFColorize_DetX1          ;20 06
       bit     1, a                            ;CB 4F
       jr      z, .VWFColorize_Mode0           ;28 14
       jr      nz, .VWFColorize_Mode2          ;20 2C
   .VWFColorize_DetX1:
       bit     1, a                            ;CB 4F
       jr      z, .VWFColorize_Mode1           ;28 1A
       ;VWFColorize_Mode3
   
   .Mode3WFB:
       ld      a, [FF41]                       ;FA 41 FF
       and     2                               ;E6 02
       jr      nz, Mode3WFB                    ;20 F9
       
       ld      a, $FF                          ;3E FF
       ldi     [hl], a                         ;22
       ld      a, b                            ;78
       ldi     [hl], a                         ;22
       
       jr      .RestoreAndExit                 ;18 27
   
   .VWFColorize_Mode0:
       ld      a, [FF41]                       ;FA 41 FF
       and     2                               ;E6 02
       jr      nz, VWFColorize_Mode0           ;20 F9
       
       ld      a, b                            ;78
       ldi     [hl], a                         ;22
       ldi     [hl], a                         ;22
       
       jr      .RestoreAndExit                 ;18 1B
   .VWFColorize_Mode1:
       ld      a, [FF41]                       ;FA 41 FF
       and     2                               ;E6 02
       jr      nz, VWFColorize_Mode1           ;20 F9
       
       ld      a, b                            ;78
       ldi     [hl], a                         ;22
       ld      a, $FF                          ;3E FF
       ldi     [hl], a                         ;22
       jr      .RestoreAndExit                 ;18 0D
   .VWFColorize_Mode2:
       ld      a, b                            ;78
       cpl                                     ;2F
       ld      b, a                            ;47
   .Mode2WFB:
       ld      a, [FF41]                       ;FA 41 FF
       and     2                               ;E6 02
       jr      nz, .Mode2WFB                   ;20 F9
       ld      a, b                            ;78
       ldi     [hl], a                         ;22
       ldi     [hl], a                         ;22
   .RestoreAndExit
       pop     bc                              ;C1
       ret                                     ;C9

The routine is 75, or 0x4B, bytes long. We'll put it at 2FC3F, since nothing's been added to this free space since v65 on Bank B. The new free space pointer in BANK B is 2FC89 (B:7C89). It's done being assembled, so we're HALFWAY THERE!

Let's change the VWF now...

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

I'm not going to move those NOPs out because that means fixing some relajumps and I'm too tired to do that. If you need more space in this routine, just defrag it...