From 61ae2c524b1d41106b91f4a064d9e4510393e7bc Mon Sep 17 00:00:00 2001 From: Randy Thiemann Date: Sat, 21 Oct 2023 20:21:49 +0200 Subject: [PATCH] Add pause. --- DMGTRIS.GB | Bin 32768 -> 32768 bytes README.md | 1 + src/constants.asm | 3 + src/include/globals.asm | 1 + src/state_gameplay.asm | 135 +++++++++++++++++++++++++++++++--------- 5 files changed, 110 insertions(+), 30 deletions(-) diff --git a/DMGTRIS.GB b/DMGTRIS.GB index a9a5529aa00ea6deb79c66b954eb7e24bb3a91c5..f763ea1d60df7d941fd7c0e84bdeccac390219c9 100644 GIT binary patch delta 2681 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 diff --git a/README.md b/README.md index c98d2af..538dc9b 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Please do not try running it on older emulators such as VBA, since this game use - A — Rotate 1 - B — Rotate 2 - Select — Hold +- Start — Pause - Up — Sonic drop - Down — Soft drop/Lock - Left/Right — Move diff --git a/src/constants.asm b/src/constants.asm index f41a648..497aff1 100644 --- a/src/constants.asm +++ b/src/constants.asm @@ -68,6 +68,9 @@ CHARMAP "#", 125 SECTION "Static Data", ROM0 sLeady:: db " READY? " sGo:: db " GO " +sPause:: + db "P A U S E " + db " P A U S E" sPieceXOffsets:: ; How to draw each piece. X-offsets of the sprites. db 0, 8, 16, 24 ; I db 0, 8, 8, 16 ; Z diff --git a/src/include/globals.asm b/src/include/globals.asm index b88cbd5..cb256e0 100644 --- a/src/include/globals.asm +++ b/src/include/globals.asm @@ -152,6 +152,7 @@ DEF GAME_OVER_R10 EQU 133 DEF GAME_OVER_R12 EQU 153 DEF GAME_OVER_R14 EQU 173 DEF GAME_OVER_OTHER EQU 131 +DEF LEADY_GO_TIME EQU 90 ENDC diff --git a/src/state_gameplay.asm b/src/state_gameplay.asm index c954133..7b9c1c6 100644 --- a/src/state_gameplay.asm +++ b/src/state_gameplay.asm @@ -31,12 +31,9 @@ DEF MODE_PIECE_IN_MOTION EQU 5 DEF MODE_DELAY EQU 6 DEF MODE_GAME_OVER EQU 7 DEF MODE_PRE_GAME_OVER EQU 8 +DEF MODE_PAUSED EQU 9 -SECTION "Gameplay Variables", WRAM0 -wMode: ds 1 -wModeCounter: ds 1 - SECTION "Critical Gameplay Variables", HRAM hCurrentPiece:: ds 1 hCurrentPieceX:: ds 1 @@ -45,6 +42,9 @@ hCurrentPieceRotationState:: ds 1 hHeldPiece: ds 1 hHoldSpent:: ds 1 hSkipJingle: ds 1 +hMode: ds 1 +hModeCounter: ds 1 +hPrePause: ds 1 SECTION "Gameplay Functions", ROM0 @@ -90,9 +90,9 @@ SwitchToGameplay:: ; Leady mode. ld a, MODE_LEADY - ld [wMode], a - ld a, 90 - ld [wModeCounter], a + ldh [hMode], a + ld a, LEADY_GO_TIME + ldh [hModeCounter], a ; Install the event loop handlers. ld a, 1 @@ -110,7 +110,7 @@ SwitchToGameplay:: GamePlayEventLoopHandler:: ; What mode are we in? - ld a, [wMode] + ld a, [hMode] cp MODE_LEADY jr z, leadyMode cp MODE_GO @@ -129,12 +129,14 @@ GamePlayEventLoopHandler:: jp z, preGameOverMode cp MODE_GAME_OVER jp z, gameOverMode + cp MODE_PAUSED + jp z, pauseMode ; Draw "READY" and wait a bit. leadyMode: - ld a, [wModeCounter] - cp a, 90 + ldh a, [hModeCounter] + cp a, LEADY_GO_TIME jr nz, :+ call SFXKill ld a, SFX_READY_GO @@ -142,9 +144,9 @@ leadyMode: : dec a jr nz, :+ ld a, MODE_GO - ld [wMode], a - ld a, 90 -: ld [wModeCounter], a + ldh [hMode], a + ld a, LEADY_GO_TIME +: ldh [hModeCounter], a ld de, sLeady ld hl, wField+(14*10) ld bc, 10 @@ -154,13 +156,13 @@ leadyMode: ; Draw "GO" and wait a bit. goMode: - ld a, [wModeCounter] + ldh a, [hModeCounter] dec a jr nz, :+ ld a, MODE_POSTGO - ld [wMode], a + ldh [hMode], a xor a, a -: ld [wModeCounter], a +: ldh [hModeCounter], a ld de, sGo ld hl, wField+(14*10) ld bc, 10 @@ -171,7 +173,7 @@ goMode: ; Clear the field, ready for gameplay. postGoMode: ld a, MODE_FETCH_PIECE - ld [wMode], a + ldh [hMode], a call FieldClear jp drawStaticInfo @@ -259,7 +261,7 @@ fetchPieceMode: call SFXEnqueue .skipJingle ld a, MODE_SPAWN_PIECE - ld [wMode], a + ldh [hMode], a ; State falls through to the next. @@ -269,16 +271,25 @@ spawnPieceMode: cp a, $FF jr z, :+ ld a, MODE_PRE_GAME_OVER - ld [wMode], a + ldh [hMode], a jp drawStaticInfo : ld a, MODE_PIECE_IN_MOTION - ld [wMode], a + ldh [hMode], a ; This mode lasts for as long as the piece is in motion. ; Field will let us know when it has locked in place. pieceInMotionMode: - call FieldProcess + ldh a, [hStartState] + cp a, 1 + jr nz, :+ + ldh a, [hMode] + ldh [hPrePause], a + ld a, MODE_PAUSED + ldh [hMode], a + jp drawStaticInfo + +: call FieldProcess ; Do we hold? ld a, [hSelectState] @@ -297,14 +308,14 @@ pieceInMotionMode: ldh [hCurrentPieceRotationState], a call DoHold ld a, MODE_SPAWN_PIECE - ld [wMode], a + ldh [hMode], a ; Do we go into delay state? : ldh a, [hCurrentLockDelayRemaining] cp a, 0 jr nz, :+ ld a, MODE_DELAY - ld [wMode], a + ldh [hMode], a call ToShadowField ; No fall through this time. @@ -312,13 +323,22 @@ pieceInMotionMode: delayMode: - call FieldDelay + ldh a, [hStartState] + cp a, 1 + jr nz, :+ + ldh a, [hMode] + ldh [hPrePause], a + ld a, MODE_PAUSED + ldh [hMode], a + jp drawStaticInfo + +: call FieldDelay ldh a, [hRemainingDelay] cp a, 0 jr nz, :+ ld a, MODE_FETCH_PIECE - ld [wMode], a + ldh [hMode], a : jp drawStaticInfo @@ -417,7 +437,7 @@ preGameOverMode: .skip7\@ ENDR ld a, MODE_GAME_OVER - ld [wMode], a + ldh [hMode], a gameOverMode: @@ -434,10 +454,10 @@ gameOverMode: xor a, a ldh [hHoldSpent], a ld a, MODE_LEADY - ld [wMode], a - ld a, 90 - ld [wModeCounter], a - jr drawStaticInfo + ldh [hMode], a + ld a, LEADY_GO_TIME + ldh [hModeCounter], a + jp drawStaticInfo ; Quit : ldh a, [hBState] @@ -447,6 +467,61 @@ gameOverMode: jp EventLoopPostHandler +pauseMode: + ldh a, [hStartState] + cp a, 1 + jr nz, :+ + ldh a, [hPrePause] + ldh [hMode], a + jp drawStaticInfo + + ; Draw PAUSE all over the field, but not if we came from delay mode. +: ldh a, [hPrePause] + cp a, MODE_DELAY + jr z, drawStaticInfo + ld de, sPause + ld hl, wField+(4*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(6*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(8*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(10*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(12*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(14*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(16*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(18*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(20*10) + ld bc, 20 + call UnsafeMemCopy + ld de, sPause + ld hl, wField+(22*10) + ld bc, 20 + call UnsafeMemCopy + jr drawStaticInfo + + ; Always draw the score, level, next piece, and held piece. drawStaticInfo: : ld a, [wNextPiece]