Compare commits

..

2 Commits

Author SHA1 Message Date
Randy Thiemann ed3ae01250 IHS and IRS 2023-10-18 13:14:58 +02:00
Randy Thiemann 51283ae200 Add Shadow Field 2023-10-18 13:14:48 +02:00
3 changed files with 181 additions and 26 deletions

View File

@ -6,29 +6,76 @@ INCLUDE "globals.asm"
SECTION "Field Variables", WRAM0 SECTION "Field Variables", WRAM0
wField:: ds (10*21) wField:: ds (10*24)
wShadowField:: ds (14*26)
SECTION "Field Functions", ROM0 SECTION "Field Functions", ROM0
FieldInit:: FieldInit::
ld hl, wField ld hl, wField
ld bc, 10*21 ld bc, 10*24
ld d, 1 ld d, 1
call UnsafeMemSet call UnsafeMemSet
ld hl, wShadowField
ld bc, 14*26
ld d, $FF
call UnsafeMemSet
ret ret
FieldClear:: FieldClear::
ld hl, wField ld hl, wField
ld bc, 10*21 ld bc, 10*24
ld d, TILE_FIELD_EMPTY ld d, TILE_FIELD_EMPTY
call UnsafeMemSet call UnsafeMemSet
ret ret
ToShadowField::
ld hl, wField
ld de, wShadowField+2
ld c, 24
.outer
ld b, 10
.inner
ld a, [hl+]
ld [de], a
inc de
dec b
jr nz, .inner
inc de
inc de
inc de
inc de
dec c
jr nz, .outer
ret
FromShadowField::
ld hl, wField
ld de, wShadowField+2
ld c, 24
.outer
ld b, 10
.inner
ld a, [de]
ld [hl+], a
inc de
dec b
jr nz, .inner
inc de
inc de
inc de
inc de
dec c
jr nz, .outer
ret
; This routine will copy wField onto the screen. ; This routine will copy wField onto the screen.
BlitField:: BlitField::
; What to copy ; What to copy
ld de, wField + 10 ld de, wField + 40
; Where to put it ; Where to put it
ld hl, FIELD_TOP_LEFT ld hl, FIELD_TOP_LEFT
; How much to increment hl after each row ; How much to increment hl after each row

View File

@ -22,6 +22,8 @@ hCurrentPieceX: ds 1
hCurrentPieceY: ds 1 hCurrentPieceY: ds 1
hCurrentPieceRotationState: ds 1 hCurrentPieceRotationState: ds 1
hHeldPiece: ds 1 hHeldPiece: ds 1
hHoldSpent: ds 1
hSkipJingle: ds 1
SECTION "Gameplay Functions", ROM0 SECTION "Gameplay Functions", ROM0
@ -62,6 +64,8 @@ SwitchToGameplay::
; We don't start with a held piece. ; We don't start with a held piece.
ld a, PIECE_NONE ld a, PIECE_NONE
ldh [hHeldPiece], a ldh [hHeldPiece], a
xor a, a
ldh [hHoldSpent], a
; Leady mode. ; Leady mode.
ld a, MODE_LEADY ld a, MODE_LEADY
@ -96,7 +100,8 @@ GamePlayEventLoopHandler::
cp MODE_FETCH_PIECE cp MODE_FETCH_PIECE
jr z, fetchPieceMode jr z, fetchPieceMode
cp MODE_SPAWN_PIECE cp MODE_SPAWN_PIECE
jr z, spawnPieceMode jp z, spawnPieceMode
; Draw "READY" and wait a bit. ; Draw "READY" and wait a bit.
leadyMode: leadyMode:
@ -113,6 +118,7 @@ leadyMode:
call UnsafeMemCopy call UnsafeMemCopy
jp drawStaticInfo jp drawStaticInfo
; Draw "GO" and wait a bit. ; Draw "GO" and wait a bit.
goMode: goMode:
ld a, [wModeCounter] ld a, [wModeCounter]
@ -128,6 +134,7 @@ goMode:
call UnsafeMemCopy call UnsafeMemCopy
jp drawStaticInfo jp drawStaticInfo
; Clear the field, ready for gameplay. ; Clear the field, ready for gameplay.
postGoMode: postGoMode:
ld a, MODE_FETCH_PIECE ld a, MODE_FETCH_PIECE
@ -135,31 +142,74 @@ postGoMode:
call FieldClear call FieldClear
jp drawStaticInfo jp drawStaticInfo
; Fetch the next piece. ; Fetch the next piece.
fetchPieceMode: fetchPieceMode:
ld a, [wNextPiece] ld a, [wNextPiece]
ldh [hCurrentPiece], a ldh [hCurrentPiece], a
call GetNextPiece call GetNextPiece
; Check if IRS is charged. ; A piece will spawn in the middle, at the top of the screen, not rotated by default.
ld a, 5
ldh [hCurrentPieceX], a
ld a, 3
ldh [hCurrentPieceY], a
xor a, a
ldh [hSkipJingle], a
ldh [hCurrentPieceRotationState], a
ldh [hHoldSpent], a
; Check if IHS is requested.
; Apply the hold if so.
.checkIHS
ld a, [hSelectState]
cp a, 0
jr z, .checkIRSA
call DoHold
; Holding does its own IRS check.
jr .checkJingle
; Check if IRS is requested.
; Apply the rotation if so.
.checkIRSA
ld a, [hAState] ld a, [hAState]
ld b, a cp a, 0
ld a, [hBState] jr z, .checkIRSB
or a, b ld a, 1
jr z, :+ ldh [hCurrentPieceRotationState], a
ld a, SFX_IRS ld a, SFX_IRS
call SFXEnqueue call SFXEnqueue
: ld a, [wNextPiece] .checkIRSB
ld a, [hBState]
cp a, 0
jr z, .checkJingle
ld a, 3
ldh [hCurrentPieceRotationState], a
ld a, SFX_IRS
call SFXEnqueue call SFXEnqueue
.checkJingle
ld a, [hSkipJingle]
cp a, 0
jr nz, .skipJingle
.playNextJingle
ld a, [wNextPiece]
call SFXEnqueue
.skipJingle
ld a, MODE_SPAWN_PIECE ld a, MODE_SPAWN_PIECE
ld [wMode], a ld [wMode], a
jp drawStaticInfo ; State falls through to the next.
; Spawn the piece. ; Spawn the piece.
spawnPieceMode: spawnPieceMode:
; todo ; TODO: At this point all the info needed to spawn the piece is known.
; We spawn the piece and then check if this causes a top out, and transition to the game over state if so.
; This then immediately transitions into regular gameplay.
call ToShadowField
call FromShadowField
ld a, [hEvenFrame] ld a, [hEvenFrame]
cp a, 0 cp a, 0
@ -176,7 +226,7 @@ spawnPieceMode:
jr nz, :+ jr nz, :+
ld a, MODE_FETCH_PIECE ld a, MODE_FETCH_PIECE
ld [wMode], a ld [wMode], a
jp drawStaticInfo jr drawStaticInfo
: ld a, [hLeftState] : ld a, [hLeftState]
cp a, 1 cp a, 1
@ -188,14 +238,20 @@ spawnPieceMode:
jr z, :++ jr z, :++
cp a, 12 cp a, 12
jr nc, :+ jr nc, :+
jp drawStaticInfo jr drawStaticInfo
: ldh a, [hFrameCtr] : ldh a, [hFrameCtr]
and %00000111 and %00000111
cp 4 cp 4
jp nz, drawStaticInfo jr nz, drawStaticInfo
: ld a, SFX_MOVE : ld a, SFX_MOVE
call SFXEnqueue call SFXEnqueue
jp drawStaticInfo jr drawStaticInfo
; This mode lasts for as long as the piece is in motion.
; Field will let us know when it has locked in place.
pieceInMotionMode:
; TODO.
; Always draw the score, level, next piece, and held piece. ; Always draw the score, level, next piece, and held piece.
@ -221,4 +277,56 @@ drawStaticInfo:
jp EventLoopPostHandler jp EventLoopPostHandler
DoHold:
; Mark hold as spent.
ld a, $FF
ldh [hHoldSpent], a
; Check if IRS is requested.
; Apply the rotation if so.
.checkIRSHA
ld a, [hAState]
cp a, 0
jr z, .checkIRSHB
ld a, 1
ldh [hCurrentPieceRotationState], a
ld a, SFX_IRS
call SFXEnqueue
.checkIRSHB
ld a, [hBState]
cp a, 0
jr z, .noRotation
ld a, 3
ldh [hCurrentPieceRotationState], a
ld a, SFX_IRS
call SFXEnqueue
jr .doHoldOperation
.noRotation
ld a, 0
ldh [hCurrentPieceRotationState], a
.doHoldOperation
; If we're not holding a piece, hold the current piece and get a new one.
ldh a, [hHeldPiece]
cp a, PIECE_NONE
jr nz, :+
ldh a, [hCurrentPiece]
ldh [hHeldPiece], a
ld a, [wNextPiece]
ldh [hCurrentPiece], a
call GetNextPiece
ret
: ld b, a
ldh a, [hCurrentPiece]
ldh [hHeldPiece], a
ld a, b
ldh [hCurrentPiece], a
ld a, $FF
ldh [hSkipJingle], a
ret
ENDC ENDC

View File

@ -1,5 +1,5 @@
#Emulicious settings file #Emulicious settings file
#Wed Oct 18 11:58:40 CEST 2023 #Wed Oct 18 13:09:20 CEST 2023
WindowEventViewerWindowHeight=1416 WindowEventViewerWindowHeight=1416
WindowEventViewerWindowDivider=876 WindowEventViewerWindowDivider=876
WindowMemoryTracerWindowY=631 WindowMemoryTracerWindowY=631
@ -17,7 +17,7 @@ GameBoyErrorBreakpointEnabled20=false
StretchToWindow=false StretchToWindow=false
WindowTileViewerOpen=false WindowTileViewerOpen=false
DebuggerWestPanelSelectedTab=0 DebuggerWestPanelSelectedTab=0
WindowMemoryTracerWindowWidth=243 WindowMemoryTracerWindowWidth=1136
WindowPaletteViewerOpen=false WindowPaletteViewerOpen=false
Key37=-1 Key37=-1
Key36=-1 Key36=-1
@ -99,7 +99,7 @@ Gamepad1Key30=-1
BankSwapAtPCBreakpointEnabled=false BankSwapAtPCBreakpointEnabled=false
DebuggerMemorySelectedTab=HRAM DebuggerMemorySelectedTab=HRAM
WindowVideoViewerOpen=true WindowVideoViewerOpen=true
WindowMemoryEditorTabVisibleRect=0,336,583,384 WindowMemoryEditorTabVisibleRect=0,0,583,128
Gamepad1Key29=-1 Gamepad1Key29=-1
Gamepad1Key28=-1 Gamepad1Key28=-1
Gamepad1Key27=-1 Gamepad1Key27=-1
@ -136,7 +136,7 @@ Gamepad1Key13=-1
Gamepad1Key12=-1 Gamepad1Key12=-1
Gamepad1Key11=-1 Gamepad1Key11=-1
Gamepad1Key10=-1 Gamepad1Key10=-1
WindowMemoryEditorSelectedAddress=434 WindowMemoryEditorSelectedAddress=0
WindowMemoryEditorWidth=665 WindowMemoryEditorWidth=665
GameBoyErrorBreakpointCondition9= GameBoyErrorBreakpointCondition9=
GameBoyErrorBreakpointCondition8= GameBoyErrorBreakpointCondition8=
@ -155,7 +155,7 @@ Gamepad0Key35=-1
Gamepad0Key34=-1 Gamepad0Key34=-1
Gamepad0Key33=-1 Gamepad0Key33=-1
Gamepad0Key32=-1 Gamepad0Key32=-1
WindowMemoryEditorSelectedTab=RAM WindowMemoryEditorSelectedTab=HRAM
Gamepad0Key31=-1 Gamepad0Key31=-1
Gamepad0Key30=-1 Gamepad0Key30=-1
SMSGamepadAThreshold=50 SMSGamepadAThreshold=50
@ -178,8 +178,8 @@ Gamepad0Key20=-1
DebuggerSouthPanelSelectedTab=1 DebuggerSouthPanelSelectedTab=1
WindowEmuliciousWidth=816 WindowEmuliciousWidth=816
WindowVideoViewerWidth=980 WindowVideoViewerWidth=980
WindowMemoryEditorY=582 WindowMemoryEditorY=557
WindowMemoryEditorX=1506 WindowMemoryEditorX=837
Gamepad0Key19=-1 Gamepad0Key19=-1
Gamepad0Key18=-1 Gamepad0Key18=-1
Gamepad0Key17=-1 Gamepad0Key17=-1
@ -199,8 +199,8 @@ GameBoyErrorBreakpointMessage32=
InterruptBreakpointCondition= InterruptBreakpointCondition=
Recent0=C\:\\workspace\\dmgtris\\bin\\out.gb Recent0=C\:\\workspace\\dmgtris\\bin\\out.gb
GameBoyErrorBreakpointMessage20= GameBoyErrorBreakpointMessage20=
WindowEmuliciousY=461 WindowEmuliciousY=474
WindowEmuliciousX=1508 WindowEmuliciousX=1512
GameBoyErrorBreakpointEnabled9=false GameBoyErrorBreakpointEnabled9=false
GameBoyErrorBreakpointEnabled8=false GameBoyErrorBreakpointEnabled8=false
GameBoyErrorBreakpointEnabled7=false GameBoyErrorBreakpointEnabled7=false