diff --git a/README.md b/README.md index d323ea5..e8723a2 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,16 @@ Choose between a few randomizer options: Select the rotation rules: - ARS1: Classic ARS from TGM1 and TGM2. - ARS2: ARS from TGM3. +- NES: No kicks. ### Drop Mode -Select whether up performs a sonic drop, a hard drop, or nothing at all. +Choose how the up and down buttons act: +- FIRM: Up drops to the bottom but does not lock until you are in neutral position. Down locks. +- SNIC: Like FIRM, but thre is no neutral lock. +- HARD: Up drops and locks. Down does not lock until you go neutral when the piece is grounded. +- LOCK: Like HARD but down locks. +- NONE: Up does nothing. Down locks. + ### Speed Curve Select between several speed curves including the DMGTRIS default speed curve, TGM1, TGM3, as well as DEATH and SHIRASE mode. In addition there's a "CHILL" curve for when you just want to enjoy some tetris. It doesn't speed up very fast at all. diff --git a/bin/DMGTRIS.GBC b/bin/DMGTRIS.GBC index 7ddf83f..ecfebe1 100644 Binary files a/bin/DMGTRIS.GBC and b/bin/DMGTRIS.GBC differ diff --git a/bin/DMGTRIS.pocket b/bin/DMGTRIS.pocket index bc1585b..b3a6df0 100644 Binary files a/bin/DMGTRIS.pocket and b/bin/DMGTRIS.pocket differ diff --git a/src/constants.asm b/src/constants.asm index e219018..1c48953 100644 --- a/src/constants.asm +++ b/src/constants.asm @@ -61,8 +61,9 @@ CHARMAP "[", 129 CHARMAP "]", 130 CHARMAP "/", 128 CHARMAP "-", 127 -CHARMAP "|", 126 -CHARMAP "#", 125 +CHARMAP "#", 126 +CHARMAP ".", 216 +CHARMAP ":", 222 SECTION "Static Data", ROMX, BANK[1] @@ -83,9 +84,12 @@ sOption1:: sOption2:: db "ARS1" db "ARS2" + db " NES" sOption3:: + db "FIRM" db "SNIC" db "HARD" + db "LOCK" db "NONE" sOption4:: db "DMGT" diff --git a/src/field.asm b/src/field.asm index bd0f769..0784f32 100644 --- a/src/field.asm +++ b/src/field.asm @@ -58,6 +58,7 @@ hDownFrames: ds 1 hAwardDownBonus: ds 1 hStalePiece: ds 1 hBravo: ds 1 +hShouldLockIfGrounded: ds 1 SECTION "Field Functions", ROM0 @@ -528,6 +529,7 @@ TrySpawnPiece:: ldh [hDownFrames], a ldh [hAwardDownBonus], a ldh [hLockDelayForce], a + ldh [hShouldLockIfGrounded], a ldh a, [hCurrentLockDelay] ldh [hCurrentLockDelayRemaining], a ldh a, [hCurrentFramesPerGravityTick] @@ -576,8 +578,6 @@ TrySpawnPiece:: jp CanPieceFitFast - - ; Draws the piece onto the field. ; B is the tile. ; DE should point to the piece's rotation state data. @@ -820,6 +820,11 @@ FieldProcess:: ; Try kicks if the piece isn't I or O. And in the case of J L and T, only if the blocked side is the left or right. .maybekick ld c, a + ; No kicks for NES mode. + ld a, [wRotModeState] + cp a, ROT_MODE_NES + jp z, .norot + ldh a, [hCurrentPiece] ; O pieces never kick, obviously. cp a, PIECE_O @@ -1193,19 +1198,26 @@ FieldProcess:: cp a, 20 jr z, .postdrop ldh a, [hUpState] - cp a, 0 - jr z, .postdrop + cp a, 1 + jr nz, .postdrop ; What kind, if any? ld a, [wDropModeState] cp a, DROP_MODE_NONE jr z, .postdrop + cp a, DROP_MODE_LOCK + jr z, .harddrop cp a, DROP_MODE_HARD jr z, .harddrop ; Sonic drop. .sonicdrop + ld a, [wDropModeState] + cp a, DROP_MODE_SNIC + jr z, :+ ld a, $FF + ldh [hShouldLockIfGrounded], a +: ld a, $FF ldh [hAwardDownBonus], a ld a, 20 ldh [hWantedG], a @@ -1215,6 +1227,11 @@ FieldProcess:: jr nz, .grav ldh a, [hCurrentFramesPerGravityTick] ldh [hTicksUntilG], a + ld a, [wDropModeState] + cp a, DROP_MODE_SNIC + jr z, .grav + ld a, $FF + ldh [hShouldLockIfGrounded], a jr .grav ; Hard drop. @@ -1250,6 +1267,11 @@ FieldProcess:: ldh [hDownFrames], a ld a, 1 ldh [hTicksUntilG], a + ld a, [wDropModeState] + cp a, DROP_MODE_HARD + jr nz, :+ + ld a, $FF + ldh [hShouldLockIfGrounded], a ; Gravity? : ldh a, [hTicksUntilG] @@ -1302,7 +1324,7 @@ FieldProcess:: call GetPieceDataFast call CanPieceFitFast cp a, $FF - jr z, .notgrounded + jp z, .notgrounded ; We're grounded. .grounded @@ -1330,20 +1352,57 @@ FieldProcess:: .postcheckforfirmdropsound ldh a, [hDownState] cp a, 0 - jr z, .dontforcelock - ldh a, [hCurrentGravityPerTick] + jr z, .neutralcheck + + ; Don't lock on down for hard drop mode immediately. + ld a, [wDropModeState] + cp a, DROP_MODE_HARD + jr nz, :+ + ld a, $FF + ldh [hShouldLockIfGrounded], a + jr .dontforcelock + + ; Lock on down in modes <20G. +: ldh a, [hCurrentGravityPerTick] cp a, 20 jr nz, .forcelock + + ; In 20G mode, only lock if down has been pressed for exactly 1 frame. ldh a, [hDownState] cp a, 1 + jr z, .forcelock + jr .dontforcelock + + ; If the down button is not held, check if we're neutral and if that should lock. +.neutralcheck + ldh a, [hShouldLockIfGrounded] + cp a, 0 + jr z, .dontforcelock + + ; Check for neutral. + ldh a, [hUpState] + cp a, 0 + jr nz, .dontforcelock + ldh a, [hLeftState] + cp a, 0 + jr nz, .dontforcelock + ldh a, [hRightState] + cp a, 0 jr nz, .dontforcelock + ; Lock on neutral for a few modes. + ld a, [wDropModeState] + cp a, DROP_MODE_FIRM + jr z, .forcelock + cp a, DROP_MODE_HARD + jr z, .forcelock + jr .dontforcelock ; Set the lock delay to 0 and save it. .forcelock - ld a, 0 + xor a, a ldh [hCurrentLockDelayRemaining], a - jr .checklockdelay + jr .dolock ; Load the lock delay. ; Decrement it by one and save it. @@ -1380,6 +1439,8 @@ FieldProcess:: .notgrounded ldh a, [hCurrentLockDelay] ldh [hCurrentLockDelayRemaining], a + xor a, a + ldh [hShouldLockIfGrounded], a ; ************************************************************** diff --git a/src/include/globals.asm b/src/include/globals.asm index b5e781d..a7a813c 100644 --- a/src/include/globals.asm +++ b/src/include/globals.asm @@ -23,13 +23,6 @@ INCLUDE "hardware.inc" INCLUDE "structs.asm" -; PPU modes: -; - 0: HBlank -; - 1: VBlank -; - 2: OAM Scan -; - 3: Drawing - - ; Waits for PPU mode to be 0 or 1. ; We don't wait for 2 because it's super short and impractical to do much of anything in. MACRO wait_vram @@ -93,11 +86,14 @@ MACRO lb ld \1, (LOW(\2) << 8) | LOW(\3) ENDM + +; Magic bytes for save files. DEF SAVE_MAGIC_0 EQU "D" DEF SAVE_MAGIC_1 EQU "M" DEF SAVE_MAGIC_2 EQU "G" -DEF SAVE_MAGIC_3 EQU "3" +DEF SAVE_MAGIC_3 EQU "5" +; Some useful palettes. DEF PALETTE_REGULAR EQU %11100100 DEF PALETTE_INVERTED EQU %00011011 DEF PALETTE_MONO_0 EQU %11111111 @@ -113,6 +109,7 @@ DEF PALETTE_LIGHTER_1 EQU %10010000 DEF PALETTE_LIGHTER_2 EQU %01000000 DEF PALETTE_LIGHTER_3 EQU %00000000 +; Sprite base positions. DEF NEXT_BASE_X EQU 115 DEF NEXT_BASE_Y EQU 40 DEF HOLD_BASE_X EQU 115 @@ -123,8 +120,7 @@ DEF LEVEL_BASE_X EQU 120 DEF CLEVEL_BASE_Y EQU 136 DEF NLEVEL_BASE_Y EQU 148 -DEF SCURVE_ENTRY_SIZE EQU 8 - +; Piece names DEF PIECE_I EQU 0 DEF PIECE_Z EQU 1 DEF PIECE_S EQU 2 @@ -132,8 +128,8 @@ DEF PIECE_J EQU 3 DEF PIECE_L EQU 4 DEF PIECE_O EQU 5 DEF PIECE_T EQU 6 -DEF PIECE_NONE EQU 255 +; Sound effect names DEF SFX_IRS EQU $80 DEF SFX_IHS EQU 10 DEF SFX_LINE_CLEAR EQU 11 @@ -145,50 +141,11 @@ DEF SFX_RANKUP EQU 16 DEF SFX_READYGO EQU 17 DEF MUSIC_MENU EQU $EE -DEF STACK_SIZE EQU 64 +; Tile data offsets 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_TIME EQU 80 -DEF GO_TIME EQU 40 - -DEF BUTTON_MODE_NORM EQU 0 -DEF BUTTON_MODE_INVR EQU 1 -DEF BUTTON_MODE_COUNT EQU 2 - -DEF TILE_RNG_MODE_BASE EQU 217 -DEF RNG_MODE_TGM1 EQU 0 -DEF RNG_MODE_TGM2 EQU 1 -DEF RNG_MODE_TGM3 EQU 2 -DEF RNG_MODE_HELL EQU 3 -DEF RNG_MODE_NES EQU 4 -DEF RNG_MODE_COUNT EQU 5 - -DEF TILE_ROT_MODE_BASE EQU 225 -DEF ROT_MODE_ARS EQU 0 -DEF ROT_MODE_ARSTI EQU 1 -DEF ROT_MODE_COUNT EQU 2 - -DEF TILE_DROP_MODE_BASE EQU 229 -DEF DROP_MODE_SONIC EQU 0 -DEF DROP_MODE_HARD EQU 1 -DEF DROP_MODE_NONE EQU 2 -DEF DROP_MODE_COUNT EQU 3 - -DEF SCURVE_DMGT EQU 0 -DEF SCURVE_TGM1 EQU 1 -DEF SCURVE_TGM3 EQU 2 -DEF SCURVE_DEAT EQU 3 -DEF SCURVE_SHIR EQU 4 -DEF SCURVE_CHIL EQU 5 -DEF SCURVE_COUNT EQU 6 - -DEF TILE_HIG_MODE_BASE EQU 232 -DEF HIG_MODE_OFF EQU 0 -DEF HIG_MODE_ON EQU 1 -DEF HIG_MODE_COUNT EQU 2 - DEF TILE_FIELD_EMPTY EQU 4 DEF TILE_PIECE_0 EQU 10 DEF TILE_0 EQU 66 @@ -197,6 +154,52 @@ DEF TILE_GHOST EQU 125 DEF TILE_SELECTED EQU 193 DEF TILE_UNSELECTED EQU 194 +; Button mode. +DEF BUTTON_MODE_NORM EQU 0 +DEF BUTTON_MODE_INVR EQU 1 +DEF BUTTON_MODE_COUNT EQU 2 + +; RNG mode. +DEF TILE_RNG_MODE_BASE EQU 218 +DEF RNG_MODE_TGM1 EQU 0 +DEF RNG_MODE_TGM2 EQU 1 +DEF RNG_MODE_TGM3 EQU 2 +DEF RNG_MODE_HELL EQU 3 +DEF RNG_MODE_NES EQU 4 +DEF RNG_MODE_COUNT EQU 5 + +; Rotation mode. +DEF TILE_ROT_MODE_BASE EQU 223 +DEF ROT_MODE_ARS EQU 0 +DEF ROT_MODE_ARSTI EQU 1 +DEF ROT_MODE_NES EQU 2 +DEF ROT_MODE_COUNT EQU 3 + +; Drop mode. +DEF TILE_DROP_MODE_BASE EQU 226 +DEF DROP_MODE_FIRM EQU 0 +DEF DROP_MODE_SNIC EQU 1 +DEF DROP_MODE_HARD EQU 2 +DEF DROP_MODE_LOCK EQU 3 +DEF DROP_MODE_NONE EQU 4 +DEF DROP_MODE_COUNT EQU 5 + +; Speed curve selection. +DEF SCURVE_DMGT EQU 0 +DEF SCURVE_TGM1 EQU 1 +DEF SCURVE_TGM3 EQU 2 +DEF SCURVE_DEAT EQU 3 +DEF SCURVE_SHIR EQU 4 +DEF SCURVE_CHIL EQU 5 +DEF SCURVE_COUNT EQU 6 + +; 20G mode. +DEF TILE_HIG_MODE_BASE EQU 231 +DEF HIG_MODE_OFF EQU 0 +DEF HIG_MODE_ON EQU 1 +DEF HIG_MODE_COUNT EQU 2 + +; VRAM Offsets for title screen tiles DEF TITLE_OPTIONS EQU 7 DEF TITLE_OPTION_0 EQU $98E0 DEF TITLE_OPTION_1 EQU $9920 @@ -207,16 +210,33 @@ DEF TITLE_OPTION_5 EQU $9A20 DEF TITLE_OPTION_6 EQU $9A60 DEF TITLE_OPTION_OFFSET EQU 15 +; VRAM Offsets for gameplay tiles DEF FIELD_RNG EQU $9852 DEF FIELD_ROT EQU $9892 DEF FIELD_DROP EQU $9912 DEF FIELD_HIG EQU $9952 DEF FIELD_TOP_LEFT EQU $9800+1 +; Gameplay definitions. +DEF LEADY_TIME EQU 80 +DEF GO_TIME EQU 40 +DEF PIECE_SPAWN_X EQU 5 +DEF PIECE_SPAWN_Y EQU 3 +DEF ROTATION_STATE_DEF EQU 0 +DEF ROTATION_STATE_CW EQU 1 +DEF ROTATION_STATE_180 EQU 2 +DEF ROTATION_STATE_CCW EQU 3 + +; Game states. (Let these increase by 3) +DEF STATE_TITLE EQU 0 +DEF STATE_GAMEPLAY EQU 3 + +; Other +DEF STACK_SIZE EQU 64 DEF EASTER_0 EQU $9845 DEF EASTER_1 EQU $9865 +; Magic location for bank id. DEF rBANKID EQU $4007 - ENDC diff --git a/src/input.asm b/src/input.asm index 195770d..c8bb681 100644 --- a/src/input.asm +++ b/src/input.asm @@ -23,15 +23,14 @@ INCLUDE "globals.asm" SECTION "High Input Variables", HRAM -hUpState:: ds 1 -hDownState:: ds 1 -hLeftState:: ds 1 -hRightState:: ds 1 -hAState:: ds 1 -hBState:: ds 1 -hStartState:: ds 1 -hSelectState:: ds 1 -hDASCharge:: ds 1 +hUpState:: ds 1 +hDownState:: ds 1 +hLeftState:: ds 1 +hRightState:: ds 1 +hAState:: ds 1 +hBState:: ds 1 +hStartState:: ds 1 +hSelectState:: ds 1 @@ -46,37 +45,10 @@ InputInit:: ldh [hBState], a ldh [hStartState], a ldh [hSelectState], a - ldh [hDASCharge], a ret GetInput:: - ; Check if the left state > DAS charge. - ldh a, [hLeftState] - ld b, a - ldh a, [hDASCharge] - cp a, b - ; If so, save the new DAS charge. - jr nc, :+ - ld a, b - ;ldh [hDASCharge], a - - ; Check if the right state > DAS charge. -: ldh a, [hRightState] - ld b, a - ldh a, [hDASCharge] - cp a, b - ; If so, save the new DAS charge. - jr nc, :+ - ld a, b - ;ldh [hDASCharge], a - - ; There's an overflow risk here if the DAS charge is 255. -: cp a, $FF - jr nz, .btns - dec a - ldh [hDASCharge], a - ; Get the button state. .btns ld a, P1F_GET_BTN @@ -187,7 +159,7 @@ GetInput:: xor a, a ldh [hDownState], a - ; Read left button. If it's just been pressed, restore the held DAS charge. + ; Read left button. .readLeft bit 1, b jr nz, .clearLeft @@ -195,42 +167,41 @@ GetInput:: ldh a, [hLeftState] cp a, $FF jr z, .readRight - cp a, 0 - jr nz, :+ - ldh a, [hDASCharge] -: inc a + inc a ldh [hLeftState], a jr .readRight .clearLeft xor a, a ldh [hLeftState], a - ; Read right button. If it's just been pressed, restore the held DAS charge. + ; Read right button. .readRight bit 0, b jr nz, .clearRight .setRight ldh a, [hRightState] cp a, $FF - jr z, .checkDAS - cp a, 0 - jr nz, :+ - ldh a, [hDASCharge] -: inc a + jr z, .priorities + inc a ldh [hRightState], a - jr .checkDAS + jr .priorities .clearRight xor a, a ldh [hRightState], a - ; If none of the four directions are pressed, reset the DAS charge. -.checkDAS - ld a, b - or a, $F0 - cp a, $FF - ret nz + ; If left or right are pressed, zero out up and down. +.priorities + ldh a, [hRightState] + cp a, 0 + jr nz, .zero + ldh a, [hLeftState] + cp a, 0 + ret z + +.zero xor a, a - ldh [hDASCharge], a + ldh [hUpState], a + ldh [hDownState], a ret diff --git a/src/main.asm b/src/main.asm index acf9f8c..b44d3ea 100644 --- a/src/main.asm +++ b/src/main.asm @@ -126,21 +126,36 @@ EventLoop:: call HandleTimers ; Call the current state's event handler. - ld b, 0 + ld hl, .eventloopjumps ldh a, [hGameState] - cp a, b - jp nz, GamePlayEventLoopHandler + ld b, 0 + ld c, a + add hl, bc + jp hl + +.eventloopjumps jp TitleEventLoopHandler + jp GamePlayEventLoopHandler EventLoopPostHandler:: ; Wait for vblank. wait_vblank ; Do OAM DMA. - ; This will chain jump into the vblank handler. - jp hOAMDMA + call hOAMDMA - ; The VBlank Handler is expected to end with jr EventLoop. + ; Call the current state's vblank handler. + ld hl, .vblankjumps + ldh a, [hGameState] + ld b, 0 + ld c, a + add hl, bc + jp hl + +.vblankjumps + jp TitleVBlankHandler + jp BlitField + ; The VBlank Handler is expected to end with jp EventLoop. ENDC diff --git a/src/res/sources/tiles.gbr b/src/res/sources/tiles.gbr index 9f38600..d1625a9 100644 Binary files a/src/res/sources/tiles.gbr and b/src/res/sources/tiles.gbr differ diff --git a/src/res/tiles.inc b/src/res/tiles.inc index cacb0f7..7e10909 100644 --- a/src/res/tiles.inc +++ b/src/res/tiles.inc @@ -28,8 +28,8 @@ Tiles:: DB $67,$1F,$67,$1F,$67,$1F,$00,$00 DB $E6,$F8,$E6,$F8,$E6,$F8,$E6,$F8 DB $E6,$F8,$E6,$F8,$E6,$F8,$00,$00 + DB $00,$00,$00,$00,$00,$00,$10,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 - DB $00,$00,$00,$00,$01,$00,$00,$00 DB $00,$00,$00,$00,$00,$FF,$FF,$FF DB $00,$FF,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$FF,$FF,$FF,$00 @@ -44,8 +44,8 @@ Tiles:: DB $66,$BD,$7E,$99,$00,$FF,$00,$00 DB $00,$FF,$36,$C9,$6C,$93,$5A,$A5 DB $36,$C9,$6C,$93,$00,$FF,$00,$00 - DB $00,$FF,$00,$BD,$3C,$81,$00,$81 - DB $3C,$81,$00,$BD,$00,$FF,$00,$00 + DB $00,$FF,$42,$BD,$7E,$81,$7E,$81 + DB $7E,$81,$42,$BD,$00,$FF,$00,$00 DB $00,$FF,$3C,$C3,$5A,$A5,$7E,$81 DB $5A,$A5,$3C,$C3,$00,$FF,$00,$00 DB $00,$FF,$5A,$A5,$42,$BD,$42,$BD @@ -58,8 +58,8 @@ Tiles:: DB $E7,$BD,$FF,$99,$FF,$FF,$00,$00 DB $FF,$FF,$B7,$C9,$ED,$93,$DB,$A5 DB $B7,$C9,$ED,$93,$FF,$FF,$00,$00 - DB $FF,$FF,$81,$BD,$BD,$81,$81,$81 - DB $BD,$81,$81,$BD,$FF,$FF,$00,$00 + DB $FF,$FF,$C3,$BD,$FF,$81,$FF,$81 + DB $FF,$81,$C3,$BD,$FF,$FF,$00,$00 DB $FF,$FF,$BD,$C3,$DB,$A5,$FF,$81 DB $DB,$A5,$BD,$C3,$FF,$FF,$00,$00 DB $FF,$FF,$DB,$A5,$C3,$BD,$C3,$BD @@ -72,8 +72,8 @@ Tiles:: DB $66,$BD,$FE,$BB,$FF,$FF,$00,$00 DB $00,$FF,$36,$C9,$6C,$93,$5A,$A5 DB $36,$C9,$EE,$BB,$FF,$FF,$00,$00 - DB $00,$FF,$00,$BD,$3C,$81,$00,$81 - DB $3C,$81,$AA,$BF,$FF,$FF,$00,$00 + DB $00,$FF,$42,$BD,$7E,$81,$7E,$81 + DB $7E,$81,$EA,$BF,$FF,$FF,$00,$00 DB $00,$FF,$3C,$C3,$5A,$A5,$7E,$81 DB $5A,$A5,$BE,$EB,$FF,$FF,$00,$00 DB $00,$FF,$5A,$A5,$42,$BD,$42,$BD @@ -86,8 +86,8 @@ Tiles:: DB $EE,$BF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$36,$C9,$6C,$93,$5A,$A5 DB $BE,$EB,$FF,$FF,$FF,$FF,$00,$00 - DB $00,$FF,$00,$BD,$3C,$81,$00,$81 - DB $BE,$AB,$FF,$FF,$FF,$FF,$00,$00 + DB $00,$FF,$42,$BD,$7E,$81,$7E,$81 + DB $FE,$AB,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$3C,$C3,$5A,$A5,$7E,$81 DB $FA,$AF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$5A,$A5,$42,$BD,$42,$BD @@ -100,7 +100,7 @@ Tiles:: DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$36,$C9,$6C,$93,$FA,$AF DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 - DB $00,$FF,$00,$BD,$3C,$81,$AA,$AB + DB $00,$FF,$42,$BD,$7E,$81,$FE,$AB DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$3C,$C3,$5A,$A5,$FE,$AB DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 @@ -114,7 +114,7 @@ Tiles:: DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$36,$C9,$EE,$BB,$FF,$FF DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 - DB $00,$FF,$00,$BD,$BE,$AB,$FF,$FF + DB $00,$FF,$42,$BD,$FE,$AB,$FF,$FF DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$3C,$C3,$FA,$AF,$FF,$FF DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 @@ -128,7 +128,7 @@ Tiles:: DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$BE,$EB,$FF,$FF,$FF,$FF DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 - DB $00,$FF,$AA,$BF,$FF,$FF,$FF,$FF + DB $00,$FF,$EA,$BF,$FF,$FF,$FF,$FF DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 DB $00,$FF,$BE,$EB,$FF,$FF,$FF,$FF DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 @@ -272,10 +272,10 @@ Tiles:: DB $00,$FF,$55,$FF,$FF,$FF,$00,$00 DB $DB,$E7,$A5,$C3,$42,$81,$81,$00 DB $42,$81,$A5,$C3,$DB,$E7,$00,$00 - DB $10,$10,$38,$38,$7C,$7C,$10,$10 - DB $7C,$7C,$38,$38,$10,$10,$00,$00 - DB $00,$00,$28,$28,$6C,$6C,$FE,$FE - DB $6C,$6C,$28,$28,$00,$00,$00,$00 + DB $44,$44,$FE,$FE,$44,$44,$44,$44 + DB $44,$44,$FE,$FE,$44,$44,$00,$00 + DB $00,$00,$00,$00,$00,$00,$3C,$3C + DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$18,$18,$18,$18,$30,$30 DB $30,$30,$60,$60,$60,$60,$00,$00 DB $F0,$F0,$C0,$C0,$C0,$C0,$C0,$C0 @@ -453,7 +453,9 @@ Tiles:: DB $C6,$C6,$6C,$6C,$38,$38,$38,$38 DB $6C,$6C,$C6,$C6,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 - DB $00,$00,$00,$00,$00,$00,$00,$00 + DB $00,$00,$30,$30,$30,$30,$00,$00 + DB $00,$00,$30,$30,$30,$30,$00,$00 + DB $00,$00,$30,$30,$30,$30,$00,$00 DB $00,$75,$00,$47,$00,$55,$00,$55 DB $00,$75,$00,$00,$00,$3E,$00,$00 DB $00,$75,$00,$47,$00,$55,$00,$55 @@ -464,24 +466,20 @@ Tiles:: DB $00,$3E,$00,$2A,$00,$00,$00,$00 DB $00,$00,$00,$FF,$20,$81,$76,$81 DB $20,$81,$00,$FF,$00,$00,$00,$00 - DB $00,$00,$00,$00,$28,$28,$10,$10 - DB $28,$28,$00,$00,$00,$00,$00,$00 - DB $00,$00,$00,$00,$28,$28,$10,$10 - DB $28,$28,$00,$00,$00,$00,$00,$00 - DB $00,$00,$00,$00,$28,$28,$10,$10 - DB $28,$28,$00,$00,$00,$00,$00,$00 DB $00,$26,$00,$55,$00,$76,$00,$55 DB $00,$55,$00,$00,$00,$3E,$00,$00 DB $00,$26,$00,$55,$00,$76,$00,$55 DB $00,$55,$00,$00,$00,$36,$00,$00 - DB $00,$00,$00,$00,$28,$28,$10,$10 - DB $28,$28,$00,$00,$00,$00,$00,$00 - DB $00,$00,$00,$00,$28,$28,$10,$10 - DB $28,$28,$00,$00,$00,$00,$00,$00 + DB $00,$00,$00,$FF,$20,$81,$76,$81 + DB $20,$81,$00,$FF,$00,$00,$00,$00 + DB $02,$70,$02,$40,$02,$60,$07,$40 + DB $07,$40,$02,$00,$00,$1F,$00,$00 DB $02,$70,$02,$40,$02,$70,$07,$10 DB $07,$70,$02,$00,$00,$1F,$00,$00 DB $02,$50,$02,$50,$02,$70,$07,$50 DB $07,$50,$02,$00,$00,$1F,$00,$00 + DB $02,$40,$02,$40,$02,$40,$07,$40 + DB $07,$70,$02,$00,$00,$1F,$00,$00 DB $02,$50,$02,$50,$02,$20,$07,$50 DB $07,$50,$02,$00,$00,$1F,$00,$00 DB $00,$3E,$02,$61,$04,$51,$24,$49 @@ -508,10 +506,12 @@ Tiles:: DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 - DB $00,$E8,$00,$A8,$00,$A8,$00,$A8 - DB $00,$EE,$00,$00,$00,$00,$00,$00 - DB $00,$EA,$00,$8E,$00,$EA,$00,$2A - DB $00,$EA,$00,$00,$00,$00,$00,$00 + DB $00,$00,$00,$00,$00,$00,$00,$00 + DB $00,$00,$00,$00,$00,$00,$00,$00 + DB $00,$00,$00,$00,$00,$00,$00,$00 + DB $00,$00,$00,$00,$00,$00,$00,$00 + DB $00,$00,$00,$00,$00,$00,$00,$00 + DB $00,$00,$00,$00,$00,$00,$00,$00 DB $03,$03,$04,$04,$08,$08,$0D,$08 DB $0B,$09,$0D,$08,$0F,$08,$00,$00 DB $06,$05,$03,$03,$00,$00,$0F,$0F @@ -528,8 +528,8 @@ Tiles:: DB $82,$82,$82,$82,$EC,$EC,$00,$00 DB $44,$44,$CA,$CA,$4A,$4A,$4A,$4A DB $4A,$4A,$4A,$4A,$E4,$E4,$00,$00 - DB $CE,$CE,$28,$28,$28,$28,$4C,$4C - DB $82,$82,$82,$82,$EC,$EC,$00,$00 + DB $C6,$C6,$28,$28,$28,$28,$4E,$4E + DB $8A,$8A,$8A,$8A,$EC,$EC,$00,$00 DB $08,$08,$1C,$1C,$30,$30,$3C,$3C DB $3C,$3C,$1C,$1C,$14,$14,$00,$00 TilesEnd:: diff --git a/src/sprites.asm b/src/sprites.asm index 52e048d..35d4f52 100644 --- a/src/sprites.asm +++ b/src/sprites.asm @@ -65,12 +65,8 @@ OAMDMA:: : dec a jr nz, :- - ; Jump to the current state's vblank handler. - ld b, 0 - ldh a, [hGameState] - cp a, b - jp nz, BlitField - jp TitleVBlankHandler + ; Return + ret ENDL OAMDMAEnd:: diff --git a/src/sram.asm b/src/sram.asm index 96f32b4..d3e5c4f 100644 --- a/src/sram.asm +++ b/src/sram.asm @@ -59,7 +59,7 @@ InitializeSRAM: ld [rRotModeState], a ld [wRotModeState], a - ld a, DROP_MODE_SONIC + ld a, DROP_MODE_FIRM ld [rDropModeState], a ld [wDropModeState], a diff --git a/src/state_gameplay.asm b/src/state_gameplay.asm index 4d52ab9..b1bc142 100644 --- a/src/state_gameplay.asm +++ b/src/state_gameplay.asm @@ -23,15 +23,15 @@ INCLUDE "globals.asm" DEF MODE_LEADY EQU 0 -DEF MODE_GO EQU 1 -DEF MODE_POSTGO EQU 2 -DEF MODE_PREFETCHED_PIECE EQU 4 -DEF MODE_SPAWN_PIECE EQU 5 -DEF MODE_PIECE_IN_MOTION EQU 6 -DEF MODE_DELAY EQU 7 -DEF MODE_GAME_OVER EQU 8 -DEF MODE_PRE_GAME_OVER EQU 9 -DEF MODE_PAUSED EQU 10 +DEF MODE_GO EQU 3 +DEF MODE_POSTGO EQU 6 +DEF MODE_PREFETCHED_PIECE EQU 9 +DEF MODE_SPAWN_PIECE EQU 12 +DEF MODE_PIECE_IN_MOTION EQU 15 +DEF MODE_DELAY EQU 18 +DEF MODE_GAME_OVER EQU 21 +DEF MODE_PRE_GAME_OVER EQU 24 +DEF MODE_PAUSED EQU 27 SECTION "High Gameplay Variables", HRAM @@ -114,7 +114,7 @@ SwitchToGameplay:: call GBCGameplayInit ; Install the event loop handlers. - ld a, 1 + ld a, STATE_GAMEPLAY ldh [hGameState], a ; And turn the LCD back on before we start. @@ -132,28 +132,24 @@ SwitchToGameplay:: GamePlayEventLoopHandler:: ; What mode are we in? + ld hl, .modejumps ldh a, [hMode] - cp MODE_LEADY - jr z, leadyMode - cp MODE_GO - jr z, goMode - cp MODE_POSTGO - jr z, postGoMode - cp MODE_PREFETCHED_PIECE - jr z, prefetchedPieceMode - cp MODE_SPAWN_PIECE - jp z, spawnPieceMode - cp MODE_PIECE_IN_MOTION - jp z, pieceInMotionMode - cp MODE_DELAY - jp z, delayMode - cp MODE_PRE_GAME_OVER - jp z, preGameOverMode - cp MODE_GAME_OVER - jp z, gameOverMode - cp MODE_PAUSED - jp z, pauseMode + ld b, 0 + ld c, a + add hl, bc + jp hl +.modejumps + jp leadyMode + jp goMode + jp postGoMode + jp prefetchedPieceMode + jp spawnPieceMode + jp pieceInMotionMode + jp delayMode + jp gameOverMode + jp preGameOverMode + jp pauseMode ; Draw "READY" and wait a bit. leadyMode: @@ -210,11 +206,11 @@ prefetchedPieceMode: ; A piece will spawn in the middle, at the top of the screen, not rotated by default. ld a, $FF ldh [hRequestedJingle], a - ld a, 5 + ld a, PIECE_SPAWN_X ldh [hCurrentPieceX], a - ld a, 3 + ld a, PIECE_SPAWN_Y ldh [hCurrentPieceY], a - xor a, a + xor a, a ; ROTATION_STATE_DEF ldh [hCurrentPieceRotationState], a ldh [hHoldSpent], a @@ -252,7 +248,7 @@ prefetchedPieceMode: ld a, $FF ldh [hAState], a .cp1 - ld a, 3 + ld a, ROTATION_STATE_CCW ldh [hCurrentPieceRotationState], a ldh a, [hNextPiece] ld b, a @@ -279,7 +275,7 @@ prefetchedPieceMode: ld a, $FF ldh [hBState], a .cp2 - ld a, 1 + ld a, ROTATION_STATE_CW ldh [hCurrentPieceRotationState], a ldh a, [hNextPiece] ld b, a @@ -338,10 +334,11 @@ pieceInMotionMode: cp a, $FF jr z, :+ ; Reset position and rotation. - ld a, 5 + ld a, PIECE_SPAWN_X ldh [hCurrentPieceX], a - ld a, 3 + ld a, PIECE_SPAWN_Y ldh [hCurrentPieceY], a + xor a, a ; ROTATION_STATE_DEF ldh [hCurrentPieceRotationState], a call DoHold ld a, MODE_SPAWN_PIECE @@ -622,7 +619,7 @@ DoHold: ld a, $FF ldh [hAState], a .cp3 - ld a, 3 + ld a, ROTATION_STATE_CCW ldh [hCurrentPieceRotationState], a call SFXKill ld a, SFX_IRS | SFX_IHS @@ -647,7 +644,7 @@ DoHold: ld a, $FF ldh [hBState], a .cp4 - ld a, 1 + ld a, ROTATION_STATE_CW ldh [hCurrentPieceRotationState], a call SFXKill ld a, SFX_IRS | SFX_IHS @@ -658,7 +655,7 @@ DoHold: call SFXKill ld a, SFX_IHS call SFXEnqueue - ld a, 0 + xor a, a ; ROTATION_STATE_DEF ldh [hCurrentPieceRotationState], a .doHoldOperation diff --git a/src/state_title.asm b/src/state_title.asm index b7f1f4e..cc74f01 100644 --- a/src/state_title.asm +++ b/src/state_title.asm @@ -115,8 +115,10 @@ SwitchToTitle:: call GBCTitleInit ; Install the event loop handlers. - ld a, 0 + ld a, STATE_TITLE ldh [hGameState], a + + xor a, a ld [wSelected], a ; And turn the LCD back on before we start.