From 0143555f362ad15643d6da86d54743f864475004 Mon Sep 17 00:00:00 2001 From: Randy Thiemann Date: Fri, 20 Oct 2023 17:25:42 +0200 Subject: [PATCH] Implement scoring --- src/constants.asm | 44 +++++++++++ src/field.asm | 170 +++++++++++++++++++++++++++++++++++++------ src/level.asm | 17 +++++ tools/Emulicious.ini | 18 ++--- 4 files changed, 217 insertions(+), 32 deletions(-) diff --git a/src/constants.asm b/src/constants.asm index 2020670..445703b 100644 --- a/src/constants.asm +++ b/src/constants.asm @@ -229,6 +229,50 @@ sSpeedCurve:: ; Speed curve of the game. dw $FFFF ; End. + +sPieceFastRotationStates:: + ; I + db 14, 1, 1, 1 + db 2, 14, 14, 14 + db 14, 1, 1, 1 + db 2, 14, 14, 14 + + ; Z + db 14, 1, 14, 1 + db 2, 13, 1, 13 + db 14, 1, 14, 1 + db 2, 13, 1, 13 + + ; S + db 15, 1, 12, 1 + db 0, 14, 1, 14 + db 15, 1, 12, 1 + db 0, 14, 1, 14 + + ; J + db 14, 1, 1, 14 + db 1, 1, 13, 14 + db 14, 14, 1, 1 + db 1, 14, 13, 1 + + ; L + db 14, 1, 1, 12 + db 1, 14, 14, 1 + db 16, 12, 1, 1 + db 0, 1, 14, 14 + + ; O + db 15, 1, 13, 1 + db 15, 1, 13, 1 + db 15, 1, 13, 1 + db 15, 1, 13, 1 + + ; T + db 14, 1, 1, 13 + db 1, 14, 1, 13 + db 15, 13, 1, 1 + db 1, 13, 1, 14 + sPieceRotationStates:: ; How each piece is rotated. ; I db %0000 diff --git a/src/field.asm b/src/field.asm index 19a2cf2..bb5cfc5 100644 --- a/src/field.asm +++ b/src/field.asm @@ -17,6 +17,7 @@ wShadowField:: ds (14*26) SECTION "Field High Variables", HRAM hPieceDataBase: ds 2 +hPieceDataBaseFast: ds 2 hPieceDataOffset: ds 1 hCurrentLockDelayRemaining:: ds 1 hDeepestY: ds 1 @@ -30,10 +31,14 @@ hWantRotation: ds 1 hRemainingDelay:: ds 1 hDelayState: ds 1 hClearedLines: ds 4 +hLineClearCt: ds 1 +hComboCt: ds 1 SECTION "Field Functions", ROM0 FieldInit:: + ld a, 1 + ldh [hComboCt], a ld hl, wField ld bc, 10*24 ld d, 1 @@ -157,6 +162,19 @@ SetPieceData: ldh [hPieceDataBase], a ld a, h ldh [hPieceDataBase+1], a + + ldh a, [hCurrentPiece] + ld hl, sPieceFastRotationStates + ld de, 16 +: cp a, 0 + jr z, :+ + add hl, de + dec a + jr :- +: ld a, l + ldh [hPieceDataBaseFast], a + ld a, h + ldh [hPieceDataBaseFast+1], a ret @@ -215,6 +233,71 @@ GetPieceData: add hl, bc ret + +GetPieceDataFast: + ldh a, [hPieceDataBaseFast] + ld l, a + ldh a, [hPieceDataBaseFast+1] + ld h, a + ldh a, [hPieceDataOffset] + ld c, a + xor a, a + ld b, a + add hl, bc + ret + + ; Checks if the piece can fit at the current position, but fast. + ; HL should point to the piece's rotation state data. + ; DE should be pointing to the right place in the SHADOW field. +CanPieceFitFast: + ld a, [hl+] + add a, e + ld e, a + adc a, d + sub e + ld d, a + ld a, [de] + cp a, TILE_FIELD_EMPTY + jr z, :+ + xor a, a + ret +: ld a, [hl+] + add a, e + ld e, a + adc a, d + sub e + ld d, a + ld a, [de] + cp a, TILE_FIELD_EMPTY + jr z, :+ + xor a, a + ret +: ld a, [hl+] + add a, e + ld e, a + adc a, d + sub e + ld d, a + ld a, [de] + cp a, TILE_FIELD_EMPTY + jr z, :+ + xor a, a + ret +: ld a, [hl+] + add a, e + ld e, a + adc a, d + sub e + ld d, a + ld a, [de] + cp a, TILE_FIELD_EMPTY + jr z, :+ + xor a, a + ret +: ld a, $FF + ret + + ; Checks if the piece can fit at the current position. ; HL should point to the piece's rotation state data. ; DE should be pointing to the right place in the SHADOW field. @@ -530,42 +613,24 @@ FindMaxG: ldh a, [hCurrentPieceX] call XYToSFieldPtr push hl - ld a, 2 + ld a, 1 ldh [hActualG], a .try - ld de, 28 + ld de, 14 pop hl add hl, de push hl ld d, h ld e, l - call GetPieceData - call CanPieceFit + call GetPieceDataFast + call CanPieceFitFast cp a, $FF - jr nz, .foundmaybe + jr nz, .found ldh a, [hActualG] inc a - inc a ldh [hActualG], a jr .try -.foundmaybe - ldh a, [hActualG] - dec a - ldh [hActualG], a - ld de, -14 - pop hl - add hl, de - push hl - ld d, h - ld e, l - call GetPieceData - call CanPieceFit - cp a, $FF - jr nz, .found - pop hl - ret - .found pop hl ldh a, [hActualG] @@ -1291,11 +1356,68 @@ FieldDelay:: ; If we're out of delay, spawn a new piece. call SFXKill + ldh a, [hLineClearCt] + cp a, 0 + jr nz, :+ + ld a, 1 + ldh [hComboCt], a + ldh a, [hRequiresLineClear] + cp a, $FF + ret z + ld e, 1 + call LevelUp + ret + +: ldh a, [hLineClearCt] + ld e, a + call LevelUp + ld c, a + ld b, a + ldh a, [hComboCt] + add b + add b + sub 2 + ldh [hComboCt], a + + ; Score the line clears. + xor a, a + ld b, a + ldh a, [hLevel] + ld l, a + ldh a, [hLevel+1] + ld h, a + add hl, bc + rrc h + rr l + rrc h + rr l + inc hl + ld b, h + ld c, l + ldh a, [hComboCt] +: add hl, bc + dec a + cp a, 0 + jr nz, :- + ldh a, [hLineClearCt] +: add hl, bc + dec a + cp a, 0 + jr nz, :- + + ld a, l + ld [wScoreIncrement], a + ld a, h + ld [wScoreIncrement+1], a + call IncreaseScore ret AppendClearedLine: + ldh a, [hLineClearCt] + inc a + ldh [hLineClearCt], a ldh a, [hClearedLines+2] ldh [hClearedLines+3], a ldh a, [hClearedLines+1] @@ -1308,6 +1430,8 @@ AppendClearedLine: FindClearedLines: + xor a, a + ldh [hLineClearCt], a ld a, $FF ld c, 0 ldh [hClearedLines], a diff --git a/src/level.asm b/src/level.asm index 3114a9e..e80b9de 100644 --- a/src/level.asm +++ b/src/level.asm @@ -21,11 +21,14 @@ hCurrentFramesPerGravityTick:: ds 1 hNextSpeedUp:: ds 2 hSpeedCurvePtr:: ds 2 hRequiresLineClear:: ds 1 +hLevel:: ds 2 SECTION "Level Functions", ROM0 LevelInit:: xor a, a + ldh [hLevel], a + ldh [hLevel+1], a ld hl, wCLevel ld [hl+], a ld [hl+], a @@ -66,6 +69,20 @@ LevelUp:: cp a, $09 ret z + ; Binary addition + ldh a, [hLevel] + ld l, a + ldh a, [hLevel+1] + ld h, a + ld a, e + add a, l + ld l, a + adc a, h + sub l + ldh [hLevel+1], a + ld l, a + ldh [hLevel], a + ; Save the current hundred digit. ld a, [wCLevel+1] ld [wPrevHundreds], a diff --git a/tools/Emulicious.ini b/tools/Emulicious.ini index 80a1cb4..ae35860 100644 --- a/tools/Emulicious.ini +++ b/tools/Emulicious.ini @@ -1,5 +1,5 @@ #Emulicious settings file -#Fri Oct 20 16:26:17 CEST 2023 +#Fri Oct 20 17:25:15 CEST 2023 WindowProfilerWindowOpen=false WindowEventViewerWindowHeight=1416 WindowEventViewerWindowDivider=876 @@ -35,7 +35,7 @@ GameBoyErrorBreakpointEnabled17=false Key33=-1 GameBoyErrorBreakpointEnabled16=false Key32=-1 -WindowDebuggerHeight=987 +WindowDebuggerHeight=1896 Key31=-1 Key30=-1 WindowMemoryTracerWindowHeight=289 @@ -75,7 +75,7 @@ WindowMemoryTracerWindowOpen=false SMSInputDeviceB=1 SMSInputDeviceA=1 InterruptBreakpointEnabled=false -OutlineWidth=425 +OutlineWidth=208 DebuggerEventFiltersGameBoy= GameBoyErrorBreakpointSuspend9=true WindowMemoryEditorOpen=false @@ -179,7 +179,7 @@ Gamepad0Key23=-1 Gamepad0Key22=-1 DebuggerHideToolbar=false Gamepad0Key21=-1 -WindowDebuggerWidth=1481 +WindowDebuggerWidth=1096 Gamepad0Key20=-1 DebuggerSouthPanelSelectedTab=1 WindowEmuliciousWidth=816 @@ -197,7 +197,7 @@ FontSize=13 Gamepad0Key12=-1 Gamepad0Key11=-1 Gamepad0Key10=-1 -StackWidth=1311 +StackWidth=685 BankSwapAtPCBreakpointSuspend=true WindowEmuliciousHeight=781 WindowSpriteViewerHeight=527 @@ -270,8 +270,8 @@ Gamepad0Key3=-1 Gamepad0Key2=-1 Gamepad0Key1=-1 Gamepad0Key0=-1 -WindowDebuggerY=730 -WindowDebuggerX=1234 +WindowDebuggerY=-8 +WindowDebuggerX=2552 InterruptBreakpointSuspend=true SMSGamepadAKeyboard=false GameBoyErrorBreakpointSuspend32=true @@ -282,9 +282,9 @@ WindowEventViewerWindowWidth=2576 WindowRAMWatchWindowOpen=false BankSwapAtPCBreakpointCondition= GameBoyErrorBreakpointSuspend20=true -SouthPanelHeight=635 +SouthPanelHeight=1544 SMSbuttonsKeyboard=false -StackSplitLocation=320 +StackSplitLocation=774 WindowMemoryEditorHeight=534 WindowTilemapViewerWidth=404 GBGamepadKeyboard=false