Compare commits

..

No commits in common. "4fa9f68107a7c88cf7a138b55955ce4cf903d3e8" and "e9c84abc9e300a6acd5e8c8b2f0ff6506a43294b" have entirely different histories.

19 changed files with 281 additions and 340 deletions

Binary file not shown.

Binary file not shown.

View File

@ -25,7 +25,7 @@ INCLUDE "globals.asm"
SECTION "High Banking Variables", HRAM SECTION "High Banking Variables", HRAM
hBankBackup: ds 1 hBankBackup: ds 1
; 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, and 0x38
SECTION "Switch Bank", ROM0[$08] SECTION "Switch Bank", ROM0[$08]
; Saves the current bank and switches to the bank in b. ; Saves the current bank and switches to the bank in b.
RSTSwitchBank:: RSTSwitchBank::

View File

@ -23,7 +23,6 @@ INCLUDE "globals.asm"
SECTION "DMG Intro Effect", ROM0 SECTION "DMG Intro Effect", ROM0
; Does a small effect on boot with the nintendo logo.
DoDMGEffect:: DoDMGEffect::
ld a, [wInitialA] ld a, [wInitialA]
cp a, $11 cp a, $11

View File

@ -62,10 +62,6 @@ hShouldLockIfGrounded: ds 1
SECTION "Field Functions", ROM0 SECTION "Field Functions", ROM0
; Initializes the field completely blank.
; Initializes the combo counter to 1.
; Initializes the bravo counter to 0.
; Initializes the shadow field.
FieldInit:: FieldInit::
xor a, a xor a, a
ldh [hBravo], a ldh [hBravo], a
@ -73,14 +69,14 @@ FieldInit::
ldh [hComboCt], a ldh [hComboCt], a
ld hl, wField ld hl, wField
ld bc, 10*24 ld bc, 10*24
ld d, TILE_BLANK ld d, 1
call UnsafeMemSet call UnsafeMemSet
ld hl, wShadowField ld hl, wShadowField
ld bc, 14*26 ld bc, 14*26
ld d, $FF ld d, $FF
jp UnsafeMemSet jp UnsafeMemSet
; Fills the field with the empty tile.
FieldClear:: FieldClear::
ld hl, wField ld hl, wField
ld bc, 10*24 ld bc, 10*24
@ -88,16 +84,13 @@ FieldClear::
jp UnsafeMemSet jp UnsafeMemSet
; Backs up the field.
; This backup field is used for pausing the game.
ToBackupField:: ToBackupField::
ld de, wField
ld hl, wBackupField ld hl, wBackupField
ld de, wField
ld bc, 10*24 ld bc, 10*24
jp UnsafeMemCopy jp UnsafeMemCopy
; Restores the backup of the field for ending pause mode.
FromBackupField:: FromBackupField::
ld hl, wField ld hl, wField
ld de, wBackupField ld de, wBackupField
@ -105,8 +98,6 @@ FromBackupField::
jp UnsafeMemCopy jp UnsafeMemCopy
; Copies the field to the shadow field.
; This shadow field is used to calculate whether or not the piece can fit.
ToShadowField:: ToShadowField::
ld hl, wField ld hl, wField
ld de, wShadowField+2 ld de, wShadowField+2
@ -128,7 +119,6 @@ ToShadowField::
ret ret
; Restores the shadow field to the main field.
FromShadowField: FromShadowField:
ld hl, wField ld hl, wField
ld de, wShadowField+2 ld de, wShadowField+2
@ -150,10 +140,9 @@ FromShadowField:
ret ret
; Blits the field onto the tile map. ; This routine will copy wField onto the screen.
; On the GBC, this chain calls into a special version that takes
; advantage of the GBC's CPU.
BlitField:: BlitField::
; Hold on, are we on a gbc?
ld a, [wInitialA] ld a, [wInitialA]
cp a, $11 cp a, $11
jp z, GBCBlitField jp z, GBCBlitField
@ -201,39 +190,39 @@ BlitField::
add hl, bc add hl, bc
ENDR ENDR
; This function is actually called as the vblank handler for the gameplay state. ; This has to finish just before the first LCDC interrupt of the frame or stuff will break in weird ways.
; This is why it jumps straight back to the event loop.
jp EventLoop jp EventLoop
; The current piece ID is used to get the offset into the rotation states
; corresponding to that piece's zero rotation.
SetPieceData: SetPieceData:
ldh a, [hCurrentPiece] ldh a, [hCurrentPiece]
sla a
sla a
sla a
sla a
ld c, a
ld b, 0
ld hl, sPieceRotationStates ld hl, sPieceRotationStates
add hl, bc ld de, 16
ld a, l : cp a, 0
jr z, :+
add hl, de
dec a
jr :-
: ld a, l
ldh [hPieceDataBase], a ldh [hPieceDataBase], a
ld a, h ld a, h
ldh [hPieceDataBase+1], a ldh [hPieceDataBase+1], a
ldh a, [hCurrentPiece]
ld hl, sPieceFastRotationStates ld hl, sPieceFastRotationStates
add hl, bc ld de, 16
ld a, l : cp a, 0
jr z, :+
add hl, de
dec a
jr :-
: ld a, l
ldh [hPieceDataBaseFast], a ldh [hPieceDataBaseFast], a
ld a, h ld a, h
ldh [hPieceDataBaseFast+1], a ldh [hPieceDataBaseFast+1], a
ret ret
; The rotation state is a further offset of 4 bytes.
SetPieceDataOffset: SetPieceDataOffset:
ldh a, [hCurrentPieceRotationState] ldh a, [hCurrentPieceRotationState]
sla a sla a
@ -259,6 +248,7 @@ XYToSFieldPtr:
ret ret
; Converts piece Y in B and a piece X in A to a pointer to the field in HL. ; Converts piece Y in B and a piece X in A to a pointer to the field in HL.
XYToFieldPtr: XYToFieldPtr:
ld hl, wField-2 ld hl, wField-2
@ -276,9 +266,6 @@ XYToFieldPtr:
ret ret
; This function makes HL point to the correct offset into the rotation data.
; This version of the data is used for thorough checking (T, J, and L have
; a middle column exception.)
GetPieceData: GetPieceData:
ldh a, [hPieceDataBase] ldh a, [hPieceDataBase]
ld l, a ld l, a
@ -286,13 +273,12 @@ GetPieceData:
ld h, a ld h, a
ldh a, [hPieceDataOffset] ldh a, [hPieceDataOffset]
ld c, a ld c, a
ld b, 0 xor a, a
ld b, a
add hl, bc add hl, bc
ret ret
; Same as the above but for the fast data. This data is used when the exact
; cell that failed isn't important.
GetPieceDataFast: GetPieceDataFast:
ldh a, [hPieceDataBaseFast] ldh a, [hPieceDataBaseFast]
ld l, a ld l, a
@ -305,12 +291,61 @@ GetPieceDataFast:
add hl, bc add hl, bc
ret 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. ; Checks if the piece can fit at the current position.
; HL should point to the piece's rotation state data. ; HL should point to the piece's rotation state data.
; DE should be pointing to the right place in the SHADOW field. ; DE should be pointing to the right place in the SHADOW field.
; This will return with $FF in A if the piece fits, or with the
; exact cell that caused the first failure in A.
CanPieceFit: CanPieceFit:
xor a, a xor a, a
ld b, a ld b, a
@ -468,63 +503,6 @@ CanPieceFit:
ret ret
; Checks if the piece can fit at the current position, but fast.
; HL should point to the piece's fast rotation state data.
; DE should be pointing to the right place in the SHADOW field.
; This will return with $FF in A if the piece fits, or with a non-$FF
; value if it doesn't.
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
; This function will draw the piece even if it can't fit.
; We use this to draw a final failed spawn before going game
; over.
ForceSpawnPiece:: ForceSpawnPiece::
call SetPieceData call SetPieceData
call SetPieceDataOffset call SetPieceDataOffset
@ -535,7 +513,8 @@ ForceSpawnPiece::
ld d, h ld d, h
ld e, l ld e, l
call GetPieceData call GetPieceData
ld b, GAME_OVER_OTHER ld a, GAME_OVER_OTHER
ld b, a
push hl push hl
push de push de
pop hl pop hl
@ -543,8 +522,6 @@ ForceSpawnPiece::
jp DrawPiece jp DrawPiece
; Initialize the state for a new piece and attempts to spawn it.
; On return, A will be $FF if the piece fit.
TrySpawnPiece:: TrySpawnPiece::
; Always reset these for a new piece. ; Always reset these for a new piece.
xor a, a xor a, a
@ -731,8 +708,6 @@ FindMaxG:
ret ret
; This is the main function that will process input, gravity, and locking.
; It should be ran once per frame as long as lock delay is greater than 0.
FieldProcess:: FieldProcess::
; ************************************************************** ; **************************************************************
; SETUP ; SETUP
@ -861,7 +836,7 @@ FieldProcess::
cp a, PIECE_Z cp a, PIECE_Z
jr z, .trykickright jr z, .trykickright
; I piece only kicks in ARS2 ; I piece only kicks in TGM3/TGW3/EASY/EAWY
cp a, PIECE_I cp a, PIECE_I
jr nz, :+ jr nz, :+
ld a, [wRotModeState] ld a, [wRotModeState]
@ -957,7 +932,7 @@ FieldProcess::
ldh [hLockDelayForce], a ldh [hLockDelayForce], a
jp .norot jp .norot
; In ARS2 mode, there are a few other kicks possible. ; In TGM3, TGW3, EASY, and EAWY modes, there are a few other kicks possible.
.maybetgm3rot .maybetgm3rot
ld a, [wRotModeState] ld a, [wRotModeState]
cp a, ROT_MODE_ARSTI cp a, ROT_MODE_ARSTI
@ -1253,7 +1228,6 @@ FieldProcess::
ld a, $FF ld a, $FF
ldh [hAwardDownBonus], a ldh [hAwardDownBonus], a
ld a, 20 ld a, 20
ldh [hWantedG], a
ld b, a ld b, a
ldh a, [hActualG] ldh a, [hActualG]
cp a, b cp a, b
@ -1286,7 +1260,7 @@ FieldProcess::
; Gravity? ; Gravity?
: ldh a, [hCurrentFractionalGravity] : ldh a, [hCurrentFractionalGravity]
cp a, $00 ; 0 is the sentinel value that should be interpreted as "every frame" cp a, $00
jr z, :+ jr z, :+
ld b, a ld b, a
ldh a, [hGravityCtr] ldh a, [hGravityCtr]
@ -1469,7 +1443,7 @@ FieldProcess::
ldh a, [hWantedG] ldh a, [hWantedG]
cp a, 1 cp a, 1
jr nz, .postghost jr nz, .postghost
ld a, [wInitialA] ; Let's not do the flickering on the GBC. ld a, [wInitialA]
cp a, $11 cp a, $11
jr z, .ghost jr z, .ghost
ldh a, [hEvenFrame] ldh a, [hEvenFrame]
@ -1507,22 +1481,20 @@ FieldProcess::
cp a, b cp a, b
jr z, .drawpiece jr z, .drawpiece
; If we're not grounded, draw the piece normally.
ldh a, [hGrounded]
cp a, $FF
jr nz, .drawpiece
; If the lock delay is 0, draw the piece in the final color. ; If the lock delay is 0, draw the piece in the final color.
ldh a, [hWantedTile] ldh a, [hCurrentPiece]
add a, 7 ld b, TILE_PIECE_0+7
add a, b
ldh [hWantedTile], a ldh [hWantedTile], a
ldh a, [hCurrentLockDelayRemaining] ldh a, [hCurrentLockDelayRemaining]
cp a, 0 cp a, 0
jr z, .drawpiece jr z, .drawpiece
; If we're not grounded, draw the piece normally.
ldh a, [hWantedTile]
sub a, 7
ldh [hWantedTile], a
ldh a, [hGrounded]
cp a, $FF
jr nz, .drawpiece
; Otherwise, look it up. ; Otherwise, look it up.
call GetTileShade call GetTileShade
@ -1543,7 +1515,7 @@ FieldProcess::
call DrawPiece call DrawPiece
ret ret
; Performs a lookup to see how "locked" the piece is.
GetTileShade: GetTileShade:
ldh a, [hCurrentLockDelay] ldh a, [hCurrentLockDelay]
cp a, 30 cp a, 30
@ -1651,8 +1623,6 @@ GetTileShade:
ret ret
; This is called every frame after a piece has been locked until the delay state ends.
; Lines are cleared, levels and score are awarded, and ARE time is waited out.
FieldDelay:: FieldDelay::
; Switch on the delay state. ; Switch on the delay state.
ld a, [wDelayState] ld a, [wDelayState]
@ -1691,7 +1661,7 @@ FieldDelay::
and a, d and a, d
cp a, $FF cp a, $FF
jr z, .skip jr z, .skip
ld a, DELAY_STATE_LINE_PRE_CLEAR ; If there were line clears, do a line clear delay, then a LINE_ARE delay. ld a, DELAY_STATE_LINE_PRE_CLEAR ; If there were line clears, do a line clear delay, then an ARE delay.
ld [wDelayState], a ld [wDelayState], a
ldh a, [hCurrentLineClearDelay] ldh a, [hCurrentLineClearDelay]
ldh [hRemainingDelay], a ldh [hRemainingDelay], a
@ -1834,7 +1804,7 @@ FieldDelay::
; Line clear delay. ; Line clear delay.
; Count down the delay. If we're out of delay, clear the lines and go to LINE_ARE. ; Count down the delay. If we're out of delay, clear the lines and go to ARE.
.lineclear .lineclear
ldh a, [hRemainingDelay] ldh a, [hRemainingDelay]
dec a dec a
@ -1888,12 +1858,12 @@ FieldDelay::
ldh [hCurrentPiece], a ldh [hCurrentPiece], a
call GetNextPiece call GetNextPiece
; Kill the sound for the next piece. ; Kill the sound for the next piece.
jp SFXKill call SFXKill
ret
; Shifts B into the line clear list.
; Also increments the line clear count.
AppendClearedLine: AppendClearedLine:
ldh a, [hLineClearCt] ldh a, [hLineClearCt]
inc a inc a
@ -1909,8 +1879,6 @@ AppendClearedLine:
ret ret
; Scans the field for lines that are completely filled with non-empty spaces.
; Every time one is found, it is added to a list.
FindClearedLines: FindClearedLines:
xor a, a xor a, a
ldh [hLineClearCt], a ldh [hLineClearCt], a
@ -1946,7 +1914,7 @@ FindClearedLines:
ret ret
; Goes through the list of cleared lines and marks those lines with the "line clear" tile.
MarkClear: MarkClear:
ldh a, [hClearedLines] ldh a, [hClearedLines]
cp a, $FF cp a, $FF
@ -1998,10 +1966,10 @@ MarkClear:
jr nz, :- jr nz, :-
ld bc, 10 ld bc, 10
ld d, TILE_CLEARING ld d, TILE_CLEARING
jp UnsafeMemSet call UnsafeMemSet
ret
; Once again, scans the field for cleared lines, but this time removes them.
ClearLines: ClearLines:
ld de, 0 ld de, 0

View File

@ -38,11 +38,9 @@ DEF R3 EQU %0000000000011111
SECTION "GBC Shadow Tilemap", WRAM0, ALIGN[8] SECTION "GBC Shadow Tilemap", WRAM0, ALIGN[8]
wShadowTilemap:: ds 32*32 wShadowTilemap:: ds 32*32
SECTION "GBC Shadow Tile Attributes", WRAM0, ALIGN[8] SECTION "GBC Shadow Tile Attributes", WRAM0, ALIGN[8]
wShadowTileAttrs:: ds 32*32 wShadowTileAttrs:: ds 32*32
SECTION "GBC Variables", WRAM0 SECTION "GBC Variables", WRAM0
wOuterReps:: ds 1 wOuterReps:: ds 1
wInnerReps:: ds 1 wInnerReps:: ds 1
@ -50,7 +48,6 @@ wTitlePal:: ds 1
SECTION "GBC Functions", ROM0 SECTION "GBC Functions", ROM0
; Copies the shadow tile attribute map to vram using instant HDMA.
ToATTR:: ToATTR::
ld a, [wInitialA] ld a, [wInitialA]
cp a, $11 cp a, $11
@ -74,7 +71,38 @@ ToATTR::
ret ret
; Sets up GBC registers for the title state. ToVRAM::
; Bank 1
ld a, 1
ldh [rVBK], a
ld a, HIGH(wShadowTileAttrs)
ldh [rHDMA1], a
ld a, LOW(wShadowTileAttrs)
ldh [rHDMA2], a
ld a, HIGH($9800)
ldh [rHDMA3], a
ld a, LOW($9800)
ldh [rHDMA4], a
ld a, 40
ldh [rHDMA5], a
; Bank 0
ld a, 0
ldh [rVBK], a
ld a, HIGH(wShadowTilemap)
ldh [rHDMA1], a
ld a, LOW(wShadowTilemap)
ldh [rHDMA2], a
ld a, HIGH($9800)
ldh [rHDMA3], a
ld a, LOW($9800)
ldh [rHDMA4], a
ld a, 39 | $80
ldh [rHDMA5], a
jp EventLoop
GBCTitleInit:: GBCTitleInit::
ld a, [wInitialA] ld a, [wInitialA]
cp a, $11 cp a, $11
@ -356,7 +384,7 @@ GBCTitleInit::
ld [wTitlePal], a ld [wTitlePal], a
ret ret
; Sets the GBC registers for the gameplay state.
GBCGameplayInit:: GBCGameplayInit::
ld a, [wInitialA] ld a, [wInitialA]
cp a, $11 cp a, $11
@ -650,7 +678,6 @@ GBCGameplayInit::
ret ret
; Additional GBC effects for the title screen process state.
GBCTitleProcess:: GBCTitleProcess::
ld a, [wInitialA] ld a, [wInitialA]
cp a, $11 cp a, $11
@ -698,10 +725,10 @@ GBCTitleProcess::
ld a, 3 ld a, 3
ld d, a ld d, a
ld bc, 32 ld bc, 32
jp UnsafeMemSet call UnsafeMemSet
ret
; Additional GBC effects for the gameplay process state.
GBCGameplayProcess:: GBCGameplayProcess::
ld a, [wInitialA] ld a, [wInitialA]
cp a, $11 cp a, $11
@ -919,38 +946,8 @@ GBCGameplayProcess::
ret ret
; Copies the shadow tile maps to VRAM using HDMA. The attributes are copied using instant mode
; The tile data is done using hblank mode.
GBCBlitField:: GBCBlitField::
ToVRAM:: jp ToVRAM
; Bank 1
ld a, 1
ldh [rVBK], a
ld a, HIGH(wShadowTileAttrs)
ldh [rHDMA1], a
ld a, LOW(wShadowTileAttrs)
ldh [rHDMA2], a
ld a, HIGH($9800)
ldh [rHDMA3], a
ld a, LOW($9800)
ldh [rHDMA4], a
ld a, 40
ldh [rHDMA5], a
; Bank 0
ld a, 0
ldh [rVBK], a
ld a, HIGH(wShadowTilemap)
ldh [rHDMA1], a
ld a, LOW(wShadowTilemap)
ldh [rHDMA2], a
ld a, HIGH($9800)
ldh [rHDMA3], a
ld a, LOW($9800)
ldh [rHDMA4], a
ld a, 39 | $80
ldh [rHDMA5], a
jp EventLoop
ENDC ENDC

View File

@ -35,7 +35,6 @@ hSelectState:: ds 1
SECTION "Input Functions", ROM0 SECTION "Input Functions", ROM0
; Zeroes out all button states.
InputInit:: InputInit::
xor a, a xor a, a
ldh [hUpState], a ldh [hUpState], a
@ -49,9 +48,6 @@ InputInit::
ret ret
; Gets the current state of all buttons.
; Held buttons are incremented. Buttons that aren't held are reset to 0.
; Left/Right cause Up/Down to be reset as well.
GetInput:: GetInput::
; Get the button state. ; Get the button state.
.btns .btns

View File

@ -27,13 +27,12 @@ hLCDCCtr:: ds 1
SECTION "Interrupt Initialization Functions", ROM0 SECTION "Interrupt Initialization Functions", ROM0
; Zeroes out the interrupt counter.
IntrInit:: IntrInit::
xor a, a xor a, a
ldh [hLCDCCtr], a ldh [hLCDCCtr], a
ret ret
; Sets up the STAT interrupt.
InitializeLCDCInterrupt:: InitializeLCDCInterrupt::
ld a, STATF_LYC ld a, STATF_LYC
ldh [rSTAT], a ldh [rSTAT], a
@ -50,8 +49,6 @@ InitializeLCDCInterrupt::
SECTION "LCDC Interrupt", ROM0[INT_HANDLER_STAT] SECTION "LCDC Interrupt", ROM0[INT_HANDLER_STAT]
; This interrupt handler will be called every 7 scanlines, scrolling up the tile map by 1 line. This has the
; effect of making the tiles appear as 8x7 pixels, and making 20 rows fit on the screen.
LCDCInterrupt: LCDCInterrupt:
push af push af
push hl push hl

View File

@ -41,11 +41,22 @@ hPrevHundreds:: ds 1
SECTION "Level Functions", ROM0 SECTION "Level Functions", ROM0
; Loads the initial state of the speed curve.
LevelInit:: LevelInit::
xor a, a xor a, a
ldh [hLevel], a
ldh [hLevel+1], a
ldh [hCLevel], a
ldh [hCLevel+1], a
ldh [hCLevel+2], a
ldh [hCLevel+3], a
ldh [hNLevel], a
ldh [hNLevel+2], a ; Note +1 is inited later.
ldh [hNLevel+3], a
ldh [hRequiresLineClear], a ldh [hRequiresLineClear], a
ld a, 1
ldh [hNLevel+1], a
ldh a, [hStartSpeed] ldh a, [hStartSpeed]
ld l, a ld l, a
ldh a, [hStartSpeed+1] ldh a, [hStartSpeed+1]
@ -98,8 +109,8 @@ LevelInit::
and a, $0F and a, $0F
ldh [hNLevel], a ldh [hNLevel], a
jp DoSpeedUp call DoSpeedUp
ret
; Increment level and speed up if necessary. Level increment in E. ; Increment level and speed up if necessary. Level increment in E.
; Levels may only increment by single digits. ; Levels may only increment by single digits.
@ -188,7 +199,8 @@ LevelUp::
ldh [hLevel+1], a ldh [hLevel+1], a
call DoSpeedUp call DoSpeedUp
ld a, SFX_RANKUP ld a, SFX_RANKUP
jp SFXEnqueue call SFXEnqueue
ret
.checknlevel .checknlevel
; Make wNLevel make sense. ; Make wNLevel make sense.
@ -294,14 +306,16 @@ LevelUp::
: ldh a, [hNextSpeedUp+1] : ldh a, [hNextSpeedUp+1]
and a, $0F and a, $0F
jr z, DoSpeedUp jr z, :+
ld hl, hCLevel+3 ld hl, hCLevel+3
cp a, [hl] cp a, [hl]
jr z, DoSpeedUp jr z, :+
ret nc ; This can fall through to the next function here. This is intentional. ret nc
: call DoSpeedUp
ret
; Iterates over the speed curve and loads the new constants.
DoSpeedUp: DoSpeedUp:
; Load curve ptr. ; Load curve ptr.
ldh a, [hSpeedCurvePtr] ldh a, [hSpeedCurvePtr]

View File

@ -39,6 +39,10 @@ wAlways20GState:: ds 1
wInitialA:: ds 1 wInitialA:: ds 1
wInitialB:: ds 1 wInitialB:: ds 1
wInitialC:: ds 1 wInitialC:: ds 1
wInitialD:: ds 1
wInitialE:: ds 1
wInitialH:: ds 1
wInitialL:: ds 1
SECTION "Stack", WRAM0 SECTION "Stack", WRAM0
@ -48,7 +52,6 @@ wStackEnd::
SECTION "Code Entry Point", ROM0 SECTION "Code Entry Point", ROM0
; Main entry point. Does some set up and then goes into an infinite event loop initialized on the title screen.
Main:: Main::
; Load the initial registers. For reasons. ; Load the initial registers. For reasons.
ld [wInitialA], a ld [wInitialA], a
@ -56,6 +59,14 @@ Main::
ld [wInitialB], a ld [wInitialB], a
ld a, c ld a, c
ld [wInitialC], a ld [wInitialC], a
ld a, d
ld [wInitialD], a
ld a, e
ld [wInitialE], a
ld a, h
ld [wInitialH], a
ld a, l
ld [wInitialL], a
; Let the DMG have some fun with the initial screen. ; Let the DMG have some fun with the initial screen.
call DoDMGEffect call DoDMGEffect
@ -117,7 +128,6 @@ Main::
call SwitchToTitle call SwitchToTitle
; Event loop time!
EventLoop:: EventLoop::
; Play the sound effect, if any. ; Play the sound effect, if any.
call SFXPlay call SFXPlay

View File

@ -23,7 +23,7 @@ INCLUDE "globals.asm"
SECTION "Memory Functions", ROM0 SECTION "Memory Functions", ROM0
; Copies data from de to hl, bc bytes. Doesn't check for vram access. ; Copies data from de to hl, bc bytes
UnsafeMemCopy:: UnsafeMemCopy::
ld a, [de] ld a, [de]
ld [hl+], a ld [hl+], a
@ -35,7 +35,7 @@ UnsafeMemCopy::
ret ret
; Copies data from de to hl, bc bytes. Checks for vram access. ; Copies data from de to hl, bc bytes
SafeMemCopy:: SafeMemCopy::
wait_vram wait_vram
ld a, [de] ld a, [de]
@ -47,8 +47,7 @@ SafeMemCopy::
jr nz, SafeMemCopy jr nz, SafeMemCopy
ret ret
; Sets memory from hl to hl+bc to d
; Sets memory from hl to hl+bc to d. Doesn't check for vram access.
UnsafeMemSet:: UnsafeMemSet::
ld [hl], d ld [hl], d
inc hl inc hl
@ -58,8 +57,6 @@ UnsafeMemSet::
jr nz, UnsafeMemSet jr nz, UnsafeMemSet
ret ret
; Sets memory from hl to hl+bc to d. Checks for vram access.
SafeMemSet:: SafeMemSet::
wait_vram wait_vram
ld [hl], d ld [hl], d

View File

@ -38,7 +38,6 @@ wTGM3WorstDroughtIdx: ds 1
section "RNG Functions", ROM0 section "RNG Functions", ROM0
; Snapshots the initial seed for a game, then initializes the history and piece queue.
RNGInit:: RNGInit::
; Do some bit fuckery on the seed using the gameboy's free-running timers. ; Do some bit fuckery on the seed using the gameboy's free-running timers.
ldh a, [rDIV] ldh a, [rDIV]
@ -113,7 +112,8 @@ RNGInit::
; Generate the next 2 to fill up the queue. ; Generate the next 2 to fill up the queue.
call GetNextPiece call GetNextPiece
jp GetNextPiece call GetNextPiece
ret
; Shift the generated piece into the history and save it. ; Shift the generated piece into the history and save it.
@ -354,27 +354,21 @@ GetNextTGM3Piece:
ld [hl], a ld [hl], a
ret ret
; Gets the next piece depending on RNG mode.
GetNextPiece:: GetNextPiece::
ld hl, .nextpiecejumps
ld a, [wRNGModeState] ld a, [wRNGModeState]
ld b, 0 cp a, RNG_MODE_HELL
ld c, a jp z, GetNextHellPiece
add a, c cp a, RNG_MODE_TGM1
add a, c jp z, GetNextTGM1Piece
ld c, a cp a, RNG_MODE_TGM2
add hl, bc jp z, GetNextTGM2Piece
jp hl cp a, RNG_MODE_TGM3
jp z, GetNextTGM3Piece
.nextpiecejumps cp a, RNG_MODE_NES
jp GetNextTGM1Piece jp z, GetNextNesPiece
jp GetNextTGM2Piece
jp GetNextTGM3Piece
jp GetNextHellPiece
jp GetNextNesPiece
; Tries generating bytes until it gets one in [0; 35)
Next35Piece: Next35Piece:
: call NextByte : call NextByte
and a, $3F and a, $3F
@ -383,7 +377,6 @@ Next35Piece:
ret ret
; Tries generating bytes until it gets one in [0; 7)
Next7Piece: Next7Piece:
: call NextByte : call NextByte
and a, $07 and a, $07
@ -392,7 +385,6 @@ Next7Piece:
ret ret
; Cyrcles the RNG returning a random byte in a.
NextByte: NextByte:
; Load seed ; Load seed
ld hl, hRNGSeed+3 ld hl, hRNGSeed+3

View File

@ -30,7 +30,6 @@ hScoreIncrementHead:: ds 1
SECTION "Score Functions", ROM0 SECTION "Score Functions", ROM0
; Wipes the score.
ScoreInit:: ScoreInit::
xor a, a xor a, a
ldh [hScore], a ldh [hScore], a
@ -50,7 +49,6 @@ ScoreInit::
ldh [hScoreIncrementBCD+5], a ldh [hScoreIncrementBCD+5], a
ret ret
; Increases the current score by the amount in wScoreIncrement. ; Increases the current score by the amount in wScoreIncrement.
IncreaseScore:: IncreaseScore::
; Wipe the old BCD score. ; Wipe the old BCD score.
@ -188,7 +186,8 @@ IncreaseScore::
xor a, a xor a, a
ldh [hScore], a ldh [hScore], a
ld a, SFX_RANKUP ld a, SFX_RANKUP
jp SFXEnqueue call SFXEnqueue
ret
ENDC ENDC

View File

@ -70,9 +70,8 @@ hNoisePlayhead:: ds 2
SECTION "SFX Functions", ROM0 SECTION "SFX Functions", ROM0
; Audio on, volume on, and enable all channels.
; Zeroes out all playheads and the queue.
SFXInit:: SFXInit::
; Audio on, volume on, and enable all channels.
ld a, $80 ld a, $80
ldh [rNR52], a ldh [rNR52], a
ld a, $FF ld a, $FF
@ -93,8 +92,8 @@ SFXInit::
ret ret
; Pop the head of the queue into A, the tail of the queue will be set to $FF.
SFXPopQueue: SFXPopQueue:
; Pop the head of the queue into A, the tail of the queue will be set to $FF.
ldh a, [hPlayQueue] ldh a, [hPlayQueue]
ld b, a ld b, a
ldh a, [hPlayQueue+1] ldh a, [hPlayQueue+1]
@ -109,8 +108,8 @@ SFXPopQueue:
ret ret
; Push A onto the tail of the queue, the head of the queue will be pushed off.
SFXPushQueue: SFXPushQueue:
; Push A onto the tail of the queue, the head of the queue will be pushed off.
ld b, a ld b, a
ldh a, [hPlayQueue+1] ldh a, [hPlayQueue+1]
ldh [hPlayQueue], a ldh [hPlayQueue], a
@ -123,18 +122,18 @@ SFXPushQueue:
ret ret
; Process the queue, if there's more to play, it will do so.
SFXProcessQueue: SFXProcessQueue:
; Clear the playhead. ; Clear the playhead.
xor a, a xor a, a
ldh [hPlayhead], a ldh [hPlayhead], a
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
; Music will just repeat.
ldh a, [hPlayQueue] ldh a, [hPlayQueue]
cp a, MUSIC_MENU cp a, MUSIC_MENU
jr nz, :+ jr nz, :+
jr SFXEnqueue call SFXEnqueue
ret
; Try 4 times to pop a sound effect off the queue. ; Try 4 times to pop a sound effect off the queue.
: call SFXPopQueue : call SFXPopQueue
@ -151,10 +150,10 @@ SFXProcessQueue:
ret z ret z
; If we got a valid sound effect, then play it. ; If we got a valid sound effect, then play it.
jr SFXEnqueue call SFXEnqueue
ret
; Noise effects use their own playhead that can play at the same time as the normal queue.
SFXTriggerNoise:: SFXTriggerNoise::
cp a, SFX_LINE_CLEAR cp a, SFX_LINE_CLEAR
jr nz, :+ jr nz, :+
@ -192,7 +191,8 @@ SFXEnqueue::
or a, l or a, l
jr z, :+ jr z, :+
ld a, b ld a, b
jr SFXPushQueue call SFXPushQueue
ret
; Menu music ; Menu music
: ld a, b : ld a, b
@ -203,7 +203,9 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sMusicMenu) ld a, HIGH(sMusicMenu)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
; Piece jingles. ; Piece jingles.
: ld a, b : ld a, b
@ -213,7 +215,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceI) ld a, HIGH(sSFXPieceI)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_I | SFX_IRS cp a, PIECE_I | SFX_IRS
@ -222,7 +225,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceIRSI) ld a, HIGH(sSFXPieceIRSI)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_S cp a, PIECE_S
@ -231,7 +235,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceS) ld a, HIGH(sSFXPieceS)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_S | SFX_IRS cp a, PIECE_S | SFX_IRS
@ -240,7 +245,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceIRSS) ld a, HIGH(sSFXPieceIRSS)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_Z cp a, PIECE_Z
@ -249,7 +255,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceZ) ld a, HIGH(sSFXPieceZ)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_Z | SFX_IRS cp a, PIECE_Z | SFX_IRS
@ -258,7 +265,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceIRSZ) ld a, HIGH(sSFXPieceIRSZ)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_J cp a, PIECE_J
@ -267,7 +275,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceJ) ld a, HIGH(sSFXPieceJ)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_J | SFX_IRS cp a, PIECE_J | SFX_IRS
@ -276,7 +285,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceIRSJ) ld a, HIGH(sSFXPieceIRSJ)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_L cp a, PIECE_L
@ -285,7 +295,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceL) ld a, HIGH(sSFXPieceL)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_L | SFX_IRS cp a, PIECE_L | SFX_IRS
@ -294,7 +305,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceIRSL) ld a, HIGH(sSFXPieceIRSL)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_O cp a, PIECE_O
@ -303,7 +315,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceO) ld a, HIGH(sSFXPieceO)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_O | SFX_IRS cp a, PIECE_O | SFX_IRS
@ -312,7 +325,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceIRSO) ld a, HIGH(sSFXPieceIRSO)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_T cp a, PIECE_T
@ -321,7 +335,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceT) ld a, HIGH(sSFXPieceT)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: ld a, b : ld a, b
cp a, PIECE_T | SFX_IRS cp a, PIECE_T | SFX_IRS
@ -330,7 +345,9 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXPieceIRST) ld a, HIGH(sSFXPieceIRST)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
; IRS ; IRS
: cp a, SFX_IHS : cp a, SFX_IHS
@ -339,7 +356,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXIHS) ld a, HIGH(sSFXIHS)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
: cp a, SFX_IHS | SFX_IRS : cp a, SFX_IHS | SFX_IRS
jr nz, :+ jr nz, :+
@ -347,7 +365,9 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXIHSIRS) ld a, HIGH(sSFXIHSIRS)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp SFXPlay call SFXPlay
ret
; Leveling ; Leveling
: cp a, SFX_LEVELLOCK : cp a, SFX_LEVELLOCK
@ -356,7 +376,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXLevelLock) ld a, HIGH(sSFXLevelLock)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jr SFXPlay call SFXPlay
ret
: cp a, SFX_LEVELUP : cp a, SFX_LEVELUP
jr nz, :+ jr nz, :+
@ -364,7 +385,9 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXLevelUp) ld a, HIGH(sSFXLevelUp)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jr SFXPlay call SFXPlay
ret
; Other ; Other
: cp a, SFX_RANKUP : cp a, SFX_RANKUP
@ -373,7 +396,8 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXRankUp) ld a, HIGH(sSFXRankUp)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jr SFXPlay call SFXPlay
ret
: cp a, SFX_READYGO : cp a, SFX_READYGO
ret nz ret nz
@ -381,9 +405,10 @@ SFXEnqueue::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, HIGH(sSFXReadyGo) ld a, HIGH(sSFXReadyGo)
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jr SFXPlay call SFXPlay
ret
; Kill the non-noise sound and clear the queue.
SFXKill:: SFXKill::
; Kill all sound without pops. ; Kill all sound without pops.
ld a, %00111111 ld a, %00111111
@ -391,10 +416,12 @@ SFXKill::
ldh [rNR21], a ldh [rNR21], a
ld a, $FF ld a, $FF
ldh [rNR31], a ldh [rNR31], a
;ldh [rNR41], a
ld a, %01000000 ld a, %01000000
ldh [rNR14], a ldh [rNR14], a
ldh [rNR24], a ldh [rNR24], a
ldh [rNR34], a ldh [rNR34], a
;ldh [rNR44], a
; Clear the queue. ; Clear the queue.
ld a, $FF ld a, $FF
@ -408,8 +435,6 @@ SFXKill::
ret ret
; Play routine for the noise channel.
; Must be called every frame.
SFXPlayNoise:: SFXPlayNoise::
; Get the noise playhead. ; Get the noise playhead.
ldh a, [hNoisePlayhead] ldh a, [hNoisePlayhead]
@ -459,11 +484,11 @@ SFXPlayNoise::
ldh [hNoisePlayhead], a ldh [hNoisePlayhead], a
ld a, h ld a, h
ldh [hNoisePlayhead+1], a ldh [hNoisePlayhead+1], a
jp RSTRestoreBank rst RSTRestoreBank
ret
; Play routine for the regular sfx channels. ; This play routine must be called every frame.
; Must be called every frame.
SFXPlay:: SFXPlay::
; Bank to correct bank. ; Bank to correct bank.
ldh a, [hPlayQueue] ldh a, [hPlayQueue]
@ -485,7 +510,8 @@ SFXPlay::
; Nothing to do if it's a null ptr. ; Nothing to do if it's a null ptr.
or a, l or a, l
jr nz, .getRegister jr nz, .getRegister
jp RSTRestoreBank rst RSTRestoreBank
ret
; Otherwise, get the register to write to. ; Otherwise, get the register to write to.
.getRegister .getRegister
@ -496,7 +522,8 @@ SFXPlay::
cp a, $FE cp a, $FE
jr nz, :+ jr nz, :+
rst RSTRestoreBank rst RSTRestoreBank
jp SFXProcessQueue call SFXProcessQueue
ret
; If it's $FF, then we're done for this frame. ; If it's $FF, then we're done for this frame.
: cp a, $FF : cp a, $FF
@ -519,7 +546,8 @@ SFXPlay::
ldh [hPlayhead], a ldh [hPlayhead], a
ld a, h ld a, h
ldh [hPlayhead+1], a ldh [hPlayhead+1], a
jp RSTRestoreBank rst RSTRestoreBank
ret
ENDC ENDC

View File

@ -90,15 +90,14 @@ OAMDMAEnd::
SECTION "OAM Functions", ROM0 SECTION "OAM Functions", ROM0
; Copies the OAM handler to HRAM.
CopyOAMHandler:: CopyOAMHandler::
ld de, OAMDMA ld de, OAMDMA
ld hl, hOAMDMA ld hl, hOAMDMA
ld bc, OAMDMAEnd - OAMDMA ld bc, OAMDMAEnd - OAMDMA
jp UnsafeMemCopy call UnsafeMemCopy
ret
; Clears OAM and shadow OAM.
ClearOAM:: ClearOAM::
ld hl, _OAMRAM ld hl, _OAMRAM
ld bc, $9F ld bc, $9F
@ -107,12 +106,12 @@ ClearOAM::
ld hl, wShadowOAM ld hl, wShadowOAM
ld bc, $9F ld bc, $9F
ld d, 0 ld d, 0
jp UnsafeMemSet call SafeMemSet
ret
SECTION "Domain Specific Functions", ROM0 SECTION "Domain Specific Functions", ROM0
; Puts the mode tells into sprites and displays them.
ApplyTells:: ApplyTells::
ld a, TELLS_BASE_Y ld a, TELLS_BASE_Y
ld [wSPRModeRNG], a ld [wSPRModeRNG], a
@ -156,8 +155,7 @@ ApplyTells::
ret ret
; Draws the next pieces as a sprite. ; Index of next piece in A.
; Index of next piece in A.
ApplyNext:: ApplyNext::
; Correct color ; Correct color
ld [wSPRNext1+3], a ld [wSPRNext1+3], a
@ -221,6 +219,7 @@ ApplyNext::
add a, NEXT_BASE_Y add a, NEXT_BASE_Y
ld [wSPRNext4+0], a ld [wSPRNext4+0], a
; Queue ; Queue
ld a, QUEUE_BASE_Y ld a, QUEUE_BASE_Y
ld [wSPRQueue1A], a ld [wSPRQueue1A], a
@ -255,10 +254,17 @@ ApplyNext::
ld [wSPRQueue2B+2], a ld [wSPRQueue2B+2], a
ret ret
; Index of hold piece in A.
; Draws the held piece.
; Index of held piece in A.
ApplyHold:: ApplyHold::
cp 255
jr nz, .doApplyHold
ld hl, wSPRHold1
ld bc, 16
ld d, 0
call UnsafeMemSet
ret
.doApplyHold
; Correct color ; Correct color
ld [wSPRHold1+3], a ld [wSPRHold1+3], a
ld [wSPRHold2+3], a ld [wSPRHold2+3], a
@ -276,6 +282,7 @@ ApplyHold::
ld a, b ld a, b
jr z, .show jr z, .show
.hide .hide
ld b, a ld b, a
ld a, TILE_BLANK ld a, TILE_BLANK
@ -343,9 +350,8 @@ ApplyHold::
ret ret
; Generic function to draw a BCD number (6 digits) as 6 sprites. ; Address of first sprite in hl.
; Address of first sprite in hl. ; Address of first digit in de.
; Address of first digit in de.
ApplyNumbers:: ApplyNumbers::
inc hl inc hl
inc hl inc hl
@ -384,10 +390,11 @@ ApplyNumbers::
ld a, [de] ld a, [de]
add a, TILE_0 add a, TILE_0
ld [hl], a ld [hl], a
add hl, bc
inc de
ret ret
; Positions all number sprites for gameplay.
SetNumberSpritePositions:: SetNumberSpritePositions::
ld a, SCORE_BASE_X ld a, SCORE_BASE_X
ld hl, wSPRScore1 ld hl, wSPRScore1

View File

@ -34,9 +34,8 @@ rSelectedStartLevel:: ds 2
SECTION "SRAM Functions", ROM0 SECTION "SRAM Functions", ROM0
; Check if our SRAM is initialized and of the correct version.
; Restores it if so, otherwise initializes it.
RestoreSRAM:: RestoreSRAM::
; Check if our SRAM is initialized and of the correct version.
ld a, [rCheck] ld a, [rCheck]
cp a, LOW(__UTC_YEAR__) cp a, LOW(__UTC_YEAR__)
jr nz, InitializeSRAM jr nz, InitializeSRAM
@ -76,7 +75,6 @@ RestoreSRAM::
ldh [hStartSpeed+1], a ldh [hStartSpeed+1], a
ret ret
; Initializes SRAM with default values.
InitializeSRAM: InitializeSRAM:
; Set the magic id. ; Set the magic id.
ld a, LOW(__UTC_YEAR__) ld a, LOW(__UTC_YEAR__)
@ -127,5 +125,4 @@ InitializeSRAM:
ld [rSelectedStartLevel+1], a ld [rSelectedStartLevel+1], a
ret ret
ENDC ENDC

View File

@ -48,7 +48,6 @@ hRequestedJingle: ds 1
SECTION "Gameplay Functions", ROM0 SECTION "Gameplay Functions", ROM0
; Change to game play mode. The event loop will call the event loop and vblank handlers for this mode after this returns.
SwitchToGameplay:: SwitchToGameplay::
; Turn the screen off if it's on. ; Turn the screen off if it's on.
ldh a, [rLCDC] ldh a, [rLCDC]
@ -114,7 +113,6 @@ SwitchToGameplay::
ret ret
; Main gameplay event loop.
GamePlayEventLoopHandler:: GamePlayEventLoopHandler::
; What mode are we in? ; What mode are we in?
ld hl, .modejumps ld hl, .modejumps
@ -136,7 +134,6 @@ GamePlayEventLoopHandler::
jp preGameOverMode jp preGameOverMode
jp pauseMode jp pauseMode
; Draw "READY" and wait a bit. ; Draw "READY" and wait a bit.
leadyMode: leadyMode:
ldh a, [hModeCounter] ldh a, [hModeCounter]
@ -362,7 +359,6 @@ delayMode:
: jp drawStaticInfo : jp drawStaticInfo
preGameOverMode: preGameOverMode:
; Spawn the failed piece. ; Spawn the failed piece.
call ForceSpawnPiece call ForceSpawnPiece
@ -582,7 +578,6 @@ drawStaticInfo:
jp EventLoopPostHandler jp EventLoopPostHandler
; Do the hold action.
DoHold: DoHold:
; Mark hold as spent. ; Mark hold as spent.
ld a, $FF ld a, $FF

View File

@ -27,7 +27,6 @@ wSelected:: ds 1
SECTION "Title Functions", ROM0 SECTION "Title Functions", ROM0
; Change to title mode. The event loop will call the event loop and vblank handlers for this mode after this returns.
SwitchToTitle:: SwitchToTitle::
; Turn the screen off if it's on. ; Turn the screen off if it's on.
ldh a, [rLCDC] ldh a, [rLCDC]
@ -137,7 +136,6 @@ SwitchToTitle::
ret ret
; Handles title screen input.
TitleEventLoopHandler:: TitleEventLoopHandler::
call GBCTitleProcess call GBCTitleProcess
@ -211,8 +209,6 @@ TitleEventLoopHandler::
.done .done
jp EventLoopPostHandler jp EventLoopPostHandler
; Decrements the currently selected option.
DecrementOption: DecrementOption:
.opt0 .opt0
ld a, [wSelected] ld a, [wSelected]
@ -311,8 +307,6 @@ DecrementOption:
jr DecrementLevel jr DecrementLevel
jp EventLoopPostHandler jp EventLoopPostHandler
; Decrements start level.
DecrementLevel: DecrementLevel:
; Decrement ; Decrement
ldh a, [hStartSpeed] ldh a, [hStartSpeed]
@ -330,7 +324,6 @@ DecrementLevel:
jp CheckLevelRange jp CheckLevelRange
; Increments the selected option.
IncrementOption: IncrementOption:
.opt0 .opt0
ld a, [wSelected] ld a, [wSelected]
@ -429,8 +422,6 @@ IncrementOption:
jr IncrementLevel jr IncrementLevel
jp EventLoopPostHandler jp EventLoopPostHandler
; Increments start level.
IncrementLevel: IncrementLevel:
; Increment ; Increment
ldh a, [hStartSpeed] ldh a, [hStartSpeed]
@ -447,11 +438,11 @@ IncrementLevel:
ld [rSelectedStartLevel+1], a ld [rSelectedStartLevel+1], a
jp CheckLevelRange jp CheckLevelRange
; Wipes the start level upon selecting a new speed curve.
InitSpeedCurve: InitSpeedCurve:
ld a, [wSpeedCurveState] ld a, [wSpeedCurveState]
call GetStart call GetStart
.set
ld a, l ld a, l
ldh [hStartSpeed], a ldh [hStartSpeed], a
ld [rSelectedStartLevel], a ld [rSelectedStartLevel], a
@ -461,7 +452,7 @@ InitSpeedCurve:
ret ret
; Gets the end of a speed curve.
GetEnd: GetEnd:
ld a, [wSpeedCurveState] ld a, [wSpeedCurveState]
cp a, SCURVE_DMGT cp a, SCURVE_DMGT
@ -487,8 +478,6 @@ GetEnd:
: ld bc, sCHILSpeedCurveEnd : ld bc, sCHILSpeedCurveEnd
ret ret
; Gets the beginning of a speed curve.
GetStart: GetStart:
ld a, [wSpeedCurveState] ld a, [wSpeedCurveState]
cp a, SCURVE_DMGT cp a, SCURVE_DMGT
@ -514,8 +503,6 @@ GetStart:
: ld hl, sCHILSpeedCurve : ld hl, sCHILSpeedCurve
ret ret
; Make sure we don't overflow the level range.
CheckLevelRange: CheckLevelRange:
; At end? ; At end?
call GetEnd call GetEnd
@ -560,7 +547,6 @@ CheckLevelRange:
jp EventLoopPostHandler jp EventLoopPostHandler
; Handles the display of the menu.
TitleVBlankHandler:: TitleVBlankHandler::
call ToATTR call ToATTR

View File

@ -27,63 +27,22 @@ hFrameCtr:: ds 1
hEvenFrame:: ds 1 hEvenFrame:: ds 1
SECTION "Time Variables", WRAM0
wMinutes:: ds 1
wSeconds:: ds 1
wFrames:: ds 1
SECTION "Time Functions", ROM0 SECTION "Time Functions", ROM0
; Zeroes all timers and gets the free-running timer ticking.
TimeInit:: TimeInit::
xor a, a xor a, a
ldh [rTMA], a ldh [rTMA], a
ldh [hEvenFrame], a ldh [hEvenFrame], a
ldh [hFrameCtr], a ldh [hFrameCtr], a
ld [wMinutes], a
ld [wSeconds], a
ld [wFrames], a
ld a, TACF_262KHZ | TACF_START ld a, TACF_262KHZ | TACF_START
ldh [rTAC], a ldh [rTAC], a
ret ret
; Resets the minute-second timer.
ResetTime::
xor a, a
ld [wMinutes], a
ld [wSeconds], a
ld [wFrames], a
ret
; Increments the global timer. Also saves whether we're on an even frame.
HandleTimers:: HandleTimers::
ldh a, [hFrameCtr] ldh a, [hFrameCtr]
inc a inc a
ldh [hFrameCtr], a ldh [hFrameCtr], a
and 1 and 1
ldh [hEvenFrame], a ldh [hEvenFrame], a
ld a, [wFrames]
inc a
ld [wFrames], a
cp a, 60
ret nz
xor a, a
ld [wFrames], a
ld a, [wSeconds]
inc a
ld [wSeconds], a
cp a, 60
ret nz
xor a, a
ld [wSeconds], a
ld a, [wMinutes]
inc a
ld [wMinutes], a
ret ret