ejona86 / taus

Tetris - Actually Useful Statistics and other mods
MIT License
91 stars 3 forks source link

twoplayer: Add compatibility with jazzthief's controller display #19

Closed ejona86 closed 3 years ago

ejona86 commented 4 years ago

As seen at http://www.romhacking.net/reviews/6104/#review

... I would like to be able to use “Controller input display” and “Tetris - Actually Useful Statistics (TAUS)” hack implemented here as well to become the definitive version of Tetris for me. ...

Add compatibility with http://www.romhacking.net/hacks/4785/ , for ~both taus and~ twoplayer. The IPS is a bit over-aggressive and has a hunk of run of zeros: 22433 (addr), 1359 (length). So it needs to be applied before twoplayer. ~With taus, the mod's nametable change isn't present, but the sprite handling is.~ With twoplayer (in 1p mode) neither is present.

Edit: I mis-tested taus. I had taus.ips (not the dist version) sitting next to my taus.nes rom, so mesen ended up overwriting the nametable change. I was confused as to how the nametable could have been broken, and now it's clear: it wasn't.

ejona86 commented 4 years ago

There's two issues with TetrisControllerInputDisplay that make it incompatible with any twoplayer mod. 1) It does not disable itself when there are two players, so arrow keys will spam the second player's screen. 2) It corrupts oamStagingLength.

At the end of the mod, there is an adc oamStagingLength which is a bug, as y is already an offset relative to oamStaging; it should have just iny; sty oamStagingLength.

        lda     #$E0
        iny
        sta     oamStaging,y
        tya
        clc
        adc     oamStagingLength
        sta     oamStagingLength
        rts

If fixes are being made to TetrisControllerInputDisplay, then it would also be nice to remove the zeroing of unreferenced_data1, as it requires the mods to be applied in a particular order.

If those issues are fixed, then this should be enough to make twoplayer compatible.

diff --git a/twoplayer-tetris-PRG.s.diff b/twoplayer-tetris-PRG.s.diff
index 1a6cb7a..472e161 100644
--- a/twoplayer-tetris-PRG.s.diff
+++ b/twoplayer-tetris-PRG.s.diff
@@ -36,19 +36,7 @@
          adc     #$01
          sta     frameCounter
          lda     #$00
-@@ -436,32 +436,32 @@ branchOnGameMode:
- gameModeState_updatePlayer1:
-         jsr     makePlayer1Active
-         jsr     branchOnPlayStatePlayer1
-         jsr     stageSpriteForCurrentPiece
-         jsr     savePlayer1State
--        jsr     stageSpriteForNextPiece
-+        jsr_i   stageSpriteForNextPiece_player1_mod     ;jsr     stageSpriteForNextPiece
-         inc     gameModeState
-         rts
- 
- gameModeState_updatePlayer2:
-         lda     numberOfPlayers
+@@ -447,21 +447,21 @@ gameModeState_updatePlayer2:
          cmp     #$02
          bne     @ret
          jsr     makePlayer2Active
@@ -235,6 +223,21 @@
          lda     tetriminoY
          rol     a
          rol     a
+@@ -1717,12 +1717,12 @@ L8B9D:  lda     orientationTable,y
+         bne     L8B9D
+         stx     oamStagingLength
+         rts
+ 
+ stageSpriteForNextPiece:
+-        lda     displayNextPiece
+-        bne     @ret
++        jmp_i   stageSpriteForNextPiece_player1_mod     ;lda     displayNextPiece
++        nop                                             ;bne     @ret
+         lda     #$C8
+         sta     spriteXOffset
+         lda     #$77
+         sta     spriteYOffset
+         ldx     nextPiece
 @@ -1899,28 +1899,53 @@ sprite03PausePalette6:
  sprite05PausePalette4:
          .byte   $00,$19,$00,$00,$00,$0A,$00,$08
diff --git a/twoplayer.s b/twoplayer.s
index e2f99c2..9f443f5 100644
--- a/twoplayer.s
+++ b/twoplayer.s
@@ -68,6 +68,36 @@ binaryLines_P2_HI:

 .code

+; unreferenced_data1 padding to avoid colliding with
+; TetrisControllerInputDisplay. The TetrisControllerInputDisplay IPS zeros out
+; everything past this point, which meas it must be applied _before_ twoplayer.
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$00
+        .byte   $00,$00,$00,$00,$00,$00,$00,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+        .byte   $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
+
 initGameState_mod:
         .export initGameState_mod
         .import __GAMEBSS_SIZE__, __GAMEBSS_RUN__
ejona86 commented 3 years ago

I modified v1.0 of Jazzthief's TetrisControllerInputDisplay for compatibility with twoplayer, and also modified twoplayer. The two work together now. I pushed the source to my modified TetrisControllerInputDisplay as https://github.com/ejona86/taus/commit/fa131b34310ca3b2df6bce0cdba9a4c005e0b819 . I'll need to ask Jazzthief if he likes this version and would be willing for it to be "official."

TetrisControllerInputDisplay-taus-1.3.0-pre.zip