2023-10-21 15:28:38 +00:00
|
|
|
; DMGTRIS
|
|
|
|
; Copyright (C) 2023 - Randy Thiemann <randy.thiemann@gmail.com>
|
|
|
|
|
|
|
|
; This program is free software: you can redistribute it and/or modify
|
|
|
|
; it under the terms of the GNU General Public License as published by
|
|
|
|
; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
; (at your option) any later version.
|
|
|
|
|
|
|
|
; This program is distributed in the hope that it will be useful,
|
|
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
; GNU General Public License for more details.
|
|
|
|
|
|
|
|
; You should have received a copy of the GNU General Public License
|
|
|
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
2023-10-13 09:20:28 +00:00
|
|
|
IF !DEF(LEVEL_ASM)
|
|
|
|
DEF LEVEL_ASM EQU 1
|
|
|
|
|
|
|
|
|
2023-10-16 05:47:11 +00:00
|
|
|
INCLUDE "globals.asm"
|
|
|
|
|
|
|
|
|
2023-10-21 18:49:52 +00:00
|
|
|
SECTION "High Level Variables", HRAM
|
2023-10-17 11:52:57 +00:00
|
|
|
hCurrentDAS:: ds 1
|
|
|
|
hCurrentARE:: ds 1
|
2023-10-26 12:29:06 +00:00
|
|
|
hCurrentLineARE:: ds 1
|
2023-10-17 11:52:57 +00:00
|
|
|
hCurrentLockDelay:: ds 1
|
|
|
|
hCurrentLineClearDelay:: ds 1
|
2023-10-26 07:50:10 +00:00
|
|
|
hCurrentIntegerGravity:: ds 1
|
|
|
|
hCurrentFractionalGravity:: ds 1
|
2023-10-17 11:52:57 +00:00
|
|
|
hNextSpeedUp:: ds 2
|
|
|
|
hSpeedCurvePtr:: ds 2
|
2023-10-21 14:31:26 +00:00
|
|
|
hStartSpeed:: ds 2
|
2023-10-17 11:52:57 +00:00
|
|
|
hRequiresLineClear:: ds 1
|
2023-10-20 15:25:42 +00:00
|
|
|
hLevel:: ds 2
|
2023-10-21 18:49:52 +00:00
|
|
|
hCLevel:: ds 4
|
2023-11-13 01:18:13 +00:00
|
|
|
hNLevel:: ds 4
|
|
|
|
hTrueCLevel:: ds 4
|
2023-10-21 18:49:52 +00:00
|
|
|
hPrevHundreds:: ds 1
|
2023-10-17 11:52:57 +00:00
|
|
|
|
2023-11-08 21:35:08 +00:00
|
|
|
SECTION "Level Variables", WRAM0
|
|
|
|
wBoneActivationLevel: ds 2
|
|
|
|
wInvisActivationLevel: ds 2
|
|
|
|
wKillScreenActivationLevel: ds 2
|
2023-11-08 23:27:44 +00:00
|
|
|
wKillScreenActivationLevelBCD: ds 2
|
2023-11-09 19:56:44 +00:00
|
|
|
wLastLockLevel: ds 2
|
|
|
|
wStaffRollDuration:: ds 2
|
2023-11-09 20:26:17 +00:00
|
|
|
wBigStaffRoll:: ds 1
|
2023-11-08 21:35:08 +00:00
|
|
|
wBonesActive:: ds 1
|
|
|
|
wInvisActive:: ds 1
|
2023-11-08 22:36:10 +00:00
|
|
|
wKillScreenActive:: ds 1
|
2023-11-08 23:10:25 +00:00
|
|
|
wLockLevel:: ds 1
|
2023-11-09 19:56:44 +00:00
|
|
|
wShouldGoStaffRoll:: ds 1
|
|
|
|
wNoMoreLocks:: ds 1
|
2023-11-13 01:18:13 +00:00
|
|
|
wSkippedSectionsBCD:: ds 1
|
2023-11-08 21:35:08 +00:00
|
|
|
|
2023-10-13 09:20:28 +00:00
|
|
|
|
|
|
|
SECTION "Level Functions", ROM0
|
2023-10-27 19:37:32 +00:00
|
|
|
; Loads the initial state of the speed curve.
|
2023-10-13 09:20:28 +00:00
|
|
|
LevelInit::
|
2023-10-28 17:04:55 +00:00
|
|
|
; Bank to speed curve data.
|
|
|
|
ld b, BANK_OTHER
|
|
|
|
rst RSTSwitchBank
|
|
|
|
|
2023-10-13 09:20:28 +00:00
|
|
|
xor a, a
|
2023-10-17 11:52:57 +00:00
|
|
|
ldh [hRequiresLineClear], a
|
2023-11-08 21:35:08 +00:00
|
|
|
ld [wBonesActive], a
|
|
|
|
ld [wInvisActive], a
|
2023-11-08 22:36:10 +00:00
|
|
|
ld [wKillScreenActive], a
|
2023-11-08 23:10:25 +00:00
|
|
|
ld [wLockLevel], a
|
2023-11-09 19:56:44 +00:00
|
|
|
ld [wShouldGoStaffRoll], a
|
|
|
|
ld [wNoMoreLocks], a
|
2023-11-13 01:18:13 +00:00
|
|
|
ld [wSkippedSectionsBCD], a
|
2023-10-17 11:52:57 +00:00
|
|
|
|
2023-10-21 14:31:26 +00:00
|
|
|
ldh a, [hStartSpeed]
|
|
|
|
ld l, a
|
|
|
|
ldh a, [hStartSpeed+1]
|
|
|
|
ld h, a
|
|
|
|
|
|
|
|
; CLevel
|
|
|
|
ld a, [hl+]
|
|
|
|
ld b, a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hCLevel+3], a
|
2023-11-13 01:18:13 +00:00
|
|
|
ldh [hTrueCLevel+3], a
|
2023-10-21 14:31:26 +00:00
|
|
|
ld a, b
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hCLevel+2], a
|
2023-11-13 01:18:13 +00:00
|
|
|
ldh [hTrueCLevel+2], a
|
2023-10-21 14:31:26 +00:00
|
|
|
ld a, [hl+]
|
|
|
|
ld b, a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hCLevel+1], a
|
2023-11-13 01:18:13 +00:00
|
|
|
ldh [hTrueCLevel+1], a
|
2023-10-21 14:31:26 +00:00
|
|
|
ld a, b
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hCLevel], a
|
2023-11-13 01:18:13 +00:00
|
|
|
ldh [hTrueCLevel], a
|
2023-10-21 14:31:26 +00:00
|
|
|
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, l
|
|
|
|
ldh [hSpeedCurvePtr], a
|
|
|
|
ld a, h
|
|
|
|
ldh [hSpeedCurvePtr+1], a
|
|
|
|
|
2023-10-21 14:31:26 +00:00
|
|
|
; Binary level.
|
|
|
|
ld a, [hl+]
|
|
|
|
ldh [hLevel], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ldh [hLevel+1], a
|
|
|
|
|
|
|
|
; NLevel
|
|
|
|
ld a, [hl+]
|
|
|
|
ld b, a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hNLevel+3], a
|
2023-10-21 14:31:26 +00:00
|
|
|
ld a, b
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hNLevel+2], a
|
2023-10-21 14:31:26 +00:00
|
|
|
ld a, [hl+]
|
|
|
|
ld b, a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hNLevel+1], a
|
2023-10-21 14:31:26 +00:00
|
|
|
ld a, b
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hNLevel], a
|
2023-10-21 14:31:26 +00:00
|
|
|
|
2023-11-08 21:35:08 +00:00
|
|
|
; Get special data.
|
|
|
|
call SpecialLevelInit
|
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
; Restore the bank to keep the stack balanced.
|
2023-10-28 17:04:55 +00:00
|
|
|
rst RSTRestoreBank
|
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
; Get the speed curve
|
|
|
|
jp AdjustSpeedCurveForced
|
2023-10-27 19:37:32 +00:00
|
|
|
|
2023-10-17 11:52:57 +00:00
|
|
|
|
2023-11-08 21:35:08 +00:00
|
|
|
SpecialLevelInit:
|
|
|
|
ld a, [wSpeedCurveState]
|
|
|
|
ld b, a
|
|
|
|
add a, b
|
|
|
|
add a, b
|
|
|
|
ld b, 0
|
|
|
|
ld c, a
|
|
|
|
ld hl, .jumps
|
|
|
|
add hl, bc
|
|
|
|
jp hl
|
|
|
|
|
|
|
|
.jumps
|
|
|
|
jp .dmgt
|
|
|
|
jp .tgm1
|
|
|
|
jp .tgm3
|
|
|
|
jp .deat
|
|
|
|
jp .shir
|
|
|
|
jp .chil
|
|
|
|
jp .myco
|
|
|
|
|
|
|
|
.dmgt
|
|
|
|
ld hl, sDMGTSpeedCurveSpecialData
|
|
|
|
jr .loaddata
|
|
|
|
|
|
|
|
.tgm1
|
|
|
|
ld hl, sTGM1SpeedCurveSpecialData
|
|
|
|
jr .loaddata
|
|
|
|
|
|
|
|
.tgm3
|
|
|
|
ld hl, sTGM3SpeedCurveSpecialData
|
|
|
|
jr .loaddata
|
|
|
|
|
|
|
|
.deat
|
|
|
|
ld hl, sDEATSpeedCurveSpecialData
|
|
|
|
jr .loaddata
|
|
|
|
|
|
|
|
.shir
|
|
|
|
ld hl, sSHIRSpeedCurveSpecialData
|
|
|
|
jr .loaddata
|
|
|
|
|
|
|
|
.chil
|
|
|
|
ld hl, sCHILSpeedCurveSpecialData
|
|
|
|
jr .loaddata
|
|
|
|
|
|
|
|
.myco
|
|
|
|
ld hl, sMYCOSpeedCurveSpecialData
|
|
|
|
jr .loaddata
|
|
|
|
|
|
|
|
.loaddata
|
|
|
|
ld a, [hl+]
|
|
|
|
ld [wBoneActivationLevel], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ld [wBoneActivationLevel+1], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ld [wInvisActivationLevel], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ld [wInvisActivationLevel+1], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ld [wKillScreenActivationLevel], a
|
2023-11-08 23:27:44 +00:00
|
|
|
ld a, [hl+]
|
2023-11-08 21:35:08 +00:00
|
|
|
ld [wKillScreenActivationLevel+1], a
|
2023-11-08 23:27:44 +00:00
|
|
|
ld a, [hl+]
|
|
|
|
ld [wKillScreenActivationLevelBCD], a
|
2023-11-09 19:56:44 +00:00
|
|
|
ld a, [hl+]
|
2023-11-08 23:27:44 +00:00
|
|
|
ld [wKillScreenActivationLevelBCD+1], a
|
2023-11-09 19:56:44 +00:00
|
|
|
ld a, [hl+]
|
|
|
|
ld [wLastLockLevel], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ld [wLastLockLevel+1], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ld [wStaffRollDuration], a
|
2023-11-09 20:26:17 +00:00
|
|
|
ld a, [hl+]
|
2023-11-09 19:56:44 +00:00
|
|
|
ld [wStaffRollDuration+1], a
|
2023-11-09 20:26:17 +00:00
|
|
|
ld a, [hl]
|
|
|
|
ld [wBigStaffRoll], a
|
2023-11-08 21:35:08 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
|
2023-10-17 11:52:57 +00:00
|
|
|
; Increment level and speed up if necessary. Level increment in E.
|
|
|
|
; Levels may only increment by single digits.
|
|
|
|
LevelUp::
|
2023-11-08 23:10:25 +00:00
|
|
|
; Return if our level is hard locked.
|
|
|
|
ld a, [wLockLevel]
|
|
|
|
cp a, $FF
|
|
|
|
ret z
|
|
|
|
|
2023-10-17 11:52:57 +00:00
|
|
|
; Return if we're maxed out.
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hCLevel
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, $09
|
|
|
|
and a, [hl]
|
|
|
|
inc hl
|
|
|
|
and a, [hl]
|
|
|
|
inc hl
|
|
|
|
and a, [hl]
|
|
|
|
inc hl
|
|
|
|
and a, [hl]
|
|
|
|
ld c, [hl]
|
|
|
|
cp a, $09
|
|
|
|
ret z
|
|
|
|
|
2023-10-20 15:25:42 +00:00
|
|
|
; 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
|
2023-10-24 20:21:48 +00:00
|
|
|
sub a, l
|
2023-10-20 15:25:42 +00:00
|
|
|
ldh [hLevel+1], a
|
2023-10-24 20:21:48 +00:00
|
|
|
ld a, l
|
2023-10-20 15:25:42 +00:00
|
|
|
ldh [hLevel], a
|
|
|
|
|
2023-10-18 09:59:22 +00:00
|
|
|
; Save the current hundred digit.
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh a, [hCLevel+1]
|
|
|
|
ldh [hPrevHundreds], a
|
2023-10-18 07:31:08 +00:00
|
|
|
|
2023-10-17 11:52:57 +00:00
|
|
|
; Increment LSD.
|
2023-10-18 07:31:08 +00:00
|
|
|
.doit
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hCLevel+3
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl]
|
|
|
|
add a, e
|
|
|
|
ld [hl], a
|
|
|
|
cp a, $0A
|
|
|
|
jr c, .checknlevel
|
|
|
|
sub a, 10
|
|
|
|
ld [hl], a
|
|
|
|
|
|
|
|
; Carry the one...
|
|
|
|
dec hl
|
|
|
|
ld a, [hl]
|
|
|
|
inc a
|
|
|
|
ld [hl], a
|
|
|
|
cp a, $0A
|
|
|
|
jr c, .checknlevel
|
|
|
|
xor a, a
|
|
|
|
ld [hl], a
|
|
|
|
|
|
|
|
; Again...
|
|
|
|
dec hl
|
|
|
|
ld a, [hl]
|
|
|
|
inc a
|
|
|
|
ld [hl], a
|
|
|
|
cp a, $0A
|
|
|
|
jr c, .checknlevel
|
|
|
|
xor a, a
|
|
|
|
ld [hl], a
|
|
|
|
|
|
|
|
; Once more...
|
|
|
|
dec hl
|
|
|
|
ld a, [hl]
|
|
|
|
inc a
|
|
|
|
ld [hl], a
|
|
|
|
cp a, $0A
|
|
|
|
jr c, .checknlevel
|
|
|
|
|
|
|
|
; We're maxed out. Both levels should be set to 9999.
|
|
|
|
ld a, 9
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hCLevel], a
|
|
|
|
ldh [hCLevel+1], a
|
|
|
|
ldh [hCLevel+2], a
|
|
|
|
ldh [hCLevel+3], a
|
2023-10-24 20:21:48 +00:00
|
|
|
ld hl, 9999
|
|
|
|
ld a, l
|
|
|
|
ldh [hLevel], a
|
|
|
|
ld a, h
|
|
|
|
ldh [hLevel+1], a
|
2023-11-13 01:18:13 +00:00
|
|
|
jp AdjustSpeedCurve
|
2023-10-17 11:52:57 +00:00
|
|
|
|
|
|
|
.checknlevel
|
|
|
|
; Make wNLevel make sense.
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hCLevel
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, $09
|
|
|
|
and a, [hl]
|
|
|
|
inc hl
|
|
|
|
and a, [hl]
|
|
|
|
cp a, $09
|
|
|
|
; If wCLevel begins 99, wNLevel should be 9999.
|
|
|
|
jr nz, :+
|
|
|
|
ld a, 9
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh [hNLevel], a
|
|
|
|
ldh [hNLevel+1], a
|
|
|
|
ldh [hNLevel+2], a
|
|
|
|
ldh [hNLevel+3], a
|
2023-10-17 11:52:57 +00:00
|
|
|
; If the last two digits of wCLevel are 98, play the bell.
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hCLevel+2
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl+]
|
|
|
|
cp a, 9
|
2023-11-13 01:18:13 +00:00
|
|
|
jr nz, AdjustSpeedCurve
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl]
|
|
|
|
cp a, 8
|
2023-11-13 01:18:13 +00:00
|
|
|
jr nz, AdjustSpeedCurve
|
2023-10-17 11:56:00 +00:00
|
|
|
ld a, $FF
|
|
|
|
ldh [hRequiresLineClear], a
|
2023-11-10 22:16:47 +00:00
|
|
|
call SFXKill
|
2023-10-24 11:35:51 +00:00
|
|
|
ld a, SFX_LEVELLOCK
|
2023-10-17 11:52:57 +00:00
|
|
|
call SFXEnqueue
|
2023-10-18 09:59:22 +00:00
|
|
|
jr .leveljinglemaybe
|
2023-10-17 11:52:57 +00:00
|
|
|
|
|
|
|
; Otherwise check the second digit of wCLevel.
|
2023-10-21 18:49:52 +00:00
|
|
|
: ld hl, hCLevel+1
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl]
|
|
|
|
; If it's 9, wNLevel should be y0xx. With y being the first digit of wCLevel+1
|
|
|
|
cp a, 9
|
|
|
|
jr nz, :+
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hNLevel+1
|
2023-10-17 11:52:57 +00:00
|
|
|
xor a, a
|
|
|
|
ld [hl], a
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hCLevel
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl]
|
|
|
|
inc a
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hNLevel
|
2023-10-17 11:52:57 +00:00
|
|
|
ld [hl], a
|
|
|
|
jr .bellmaybe
|
|
|
|
|
|
|
|
; Otherwise just set the second digit of wNLevel to the second digit of wCLevel + 1.
|
2023-10-21 18:49:52 +00:00
|
|
|
: ld hl, hCLevel+1
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl]
|
|
|
|
inc a
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hNLevel+1
|
2023-10-17 11:52:57 +00:00
|
|
|
ld [hl], a
|
|
|
|
|
|
|
|
.bellmaybe
|
|
|
|
; If the last two digits of wCLevel are 99, play the bell.
|
2023-10-21 18:49:52 +00:00
|
|
|
ld hl, hCLevel+2
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl+]
|
|
|
|
and a, [hl]
|
|
|
|
cp a, 9
|
2023-10-18 09:59:22 +00:00
|
|
|
jr nz, .leveljinglemaybe
|
2023-11-09 19:56:44 +00:00
|
|
|
ld a, [wNoMoreLocks]
|
|
|
|
cp a, $FF
|
2023-11-13 01:18:13 +00:00
|
|
|
jr z, AdjustSpeedCurve
|
2023-10-17 11:56:00 +00:00
|
|
|
ld a, $FF
|
|
|
|
ldh [hRequiresLineClear], a
|
2023-11-10 22:16:47 +00:00
|
|
|
call SFXKill
|
2023-10-24 11:35:51 +00:00
|
|
|
ld a, SFX_LEVELLOCK
|
2023-10-17 11:52:57 +00:00
|
|
|
call SFXEnqueue
|
|
|
|
|
2023-10-18 09:59:22 +00:00
|
|
|
.leveljinglemaybe
|
2023-10-21 18:49:52 +00:00
|
|
|
ldh a, [hPrevHundreds]
|
2023-10-18 09:59:22 +00:00
|
|
|
ld b, a
|
2023-10-21 18:53:54 +00:00
|
|
|
ldh a, [hCLevel+1]
|
2023-10-18 09:59:22 +00:00
|
|
|
cp a, b
|
2023-11-13 01:18:13 +00:00
|
|
|
jr z, AdjustSpeedCurve
|
2023-11-10 22:16:47 +00:00
|
|
|
call SFXKill
|
2023-10-24 11:35:51 +00:00
|
|
|
ld a, SFX_LEVELUP
|
2023-10-18 09:59:22 +00:00
|
|
|
call SFXEnqueue
|
2023-11-13 01:18:13 +00:00
|
|
|
; This falls through to AdjustSpeedCurve, this is intended.
|
2023-10-18 09:59:22 +00:00
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
|
|
|
|
AdjustSpeedCurve:
|
|
|
|
call BuildTrueCLevel
|
2023-11-08 21:35:08 +00:00
|
|
|
call CheckSpecialLevelConditions
|
2023-11-13 01:18:13 +00:00
|
|
|
|
|
|
|
.docheck
|
|
|
|
.checkthousands
|
|
|
|
; Get the thousands level of the next speed up.
|
2023-10-17 11:52:57 +00:00
|
|
|
ldh a, [hNextSpeedUp]
|
2023-10-18 09:59:22 +00:00
|
|
|
swap a
|
|
|
|
and a, $0F
|
2023-11-13 01:18:13 +00:00
|
|
|
|
|
|
|
; Compare to ours.
|
|
|
|
ld hl, hTrueCLevel+CLEVEL_THOUSANDS
|
2023-10-17 11:52:57 +00:00
|
|
|
cp a, [hl]
|
2023-11-13 01:18:13 +00:00
|
|
|
jr z, .checkhundreds ; Equal? We need to check deeper.
|
|
|
|
jr c, AdjustSpeedCurveForced ; Ours higher? We need to increase.
|
|
|
|
ret ; Ours lower? We're done.
|
2023-10-17 11:52:57 +00:00
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
.checkhundreds
|
|
|
|
; Get the hundreds level of the next speed up.
|
|
|
|
ldh a, [hNextSpeedUp]
|
2023-10-17 11:52:57 +00:00
|
|
|
and a, $0F
|
2023-11-13 01:18:13 +00:00
|
|
|
|
|
|
|
; Compare to ours.
|
|
|
|
ld hl, hCLevel+CLEVEL_HUNDREDS
|
2023-10-17 11:52:57 +00:00
|
|
|
cp a, [hl]
|
2023-11-13 01:18:13 +00:00
|
|
|
jr z, .checktens ; Equal? We need to check deeper.
|
|
|
|
jr c, AdjustSpeedCurveForced ; Ours higher? We need to increase.
|
|
|
|
ret ; Ours lower? We're done.
|
2023-10-17 11:52:57 +00:00
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
.checktens
|
|
|
|
; Get the tens level of the next speed up.
|
|
|
|
ldh a, [hNextSpeedUp+1]
|
2023-10-18 09:59:22 +00:00
|
|
|
swap a
|
|
|
|
and a, $0F
|
2023-11-13 01:18:13 +00:00
|
|
|
|
|
|
|
; Compare to ours.
|
|
|
|
ld hl, hCLevel+CLEVEL_TENS
|
2023-10-17 11:52:57 +00:00
|
|
|
cp a, [hl]
|
2023-11-13 01:18:13 +00:00
|
|
|
jr z, .checkones ; Equal? We need to check deeper.
|
|
|
|
jr c, AdjustSpeedCurveForced ; Ours higher? We need to increase.
|
|
|
|
ret ; Ours lower? We're done.
|
2023-10-17 11:52:57 +00:00
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
.checkones
|
|
|
|
; Get the ones level of the next speed up.
|
|
|
|
ldh a, [hNextSpeedUp+1]
|
2023-10-17 11:52:57 +00:00
|
|
|
and a, $0F
|
2023-11-13 01:18:13 +00:00
|
|
|
|
|
|
|
; Compare to ours.
|
|
|
|
ld hl, hCLevel+CLEVEL_ONES
|
2023-10-17 11:52:57 +00:00
|
|
|
cp a, [hl]
|
2023-11-13 01:18:13 +00:00
|
|
|
jr c, AdjustSpeedCurveForced ; Ours higher? We need to increase.
|
|
|
|
ret nz ; Ours lower? We're done.
|
|
|
|
; Equal? We need to increase.
|
2023-10-17 11:52:57 +00:00
|
|
|
|
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
AdjustSpeedCurveForced:
|
|
|
|
; Update all data to the next speed curve data.
|
2023-10-28 17:04:55 +00:00
|
|
|
; Bank to speed curve data.
|
|
|
|
ld b, BANK_OTHER
|
|
|
|
rst RSTSwitchBank
|
|
|
|
|
2023-10-17 11:52:57 +00:00
|
|
|
; Load curve ptr.
|
|
|
|
ldh a, [hSpeedCurvePtr]
|
|
|
|
ld l, a
|
|
|
|
ldh a, [hSpeedCurvePtr+1]
|
|
|
|
ld h, a
|
|
|
|
|
2023-10-21 14:31:26 +00:00
|
|
|
; There's 4 bytes we don't care about.
|
|
|
|
inc hl
|
|
|
|
inc hl
|
|
|
|
inc hl
|
|
|
|
inc hl
|
|
|
|
|
2023-10-17 11:52:57 +00:00
|
|
|
; Get all the new data.
|
|
|
|
ld a, [hl+]
|
2023-10-26 07:50:10 +00:00
|
|
|
ldh [hCurrentIntegerGravity], a
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl+]
|
2023-10-26 07:50:10 +00:00
|
|
|
ldh [hCurrentFractionalGravity], a
|
2023-10-17 11:52:57 +00:00
|
|
|
ld a, [hl+]
|
|
|
|
ldh [hCurrentARE], a
|
|
|
|
ld a, [hl+]
|
2023-10-26 12:29:06 +00:00
|
|
|
ldh [hCurrentLineARE], a
|
|
|
|
ld a, [hl+]
|
2023-10-17 11:52:57 +00:00
|
|
|
ldh [hCurrentDAS], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ldh [hCurrentLockDelay], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ldh [hCurrentLineClearDelay], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ldh [hNextSpeedUp+1], a
|
|
|
|
ld a, [hl+]
|
|
|
|
ldh [hNextSpeedUp], a
|
|
|
|
|
|
|
|
; Save the new pointer.
|
|
|
|
ld a, l
|
|
|
|
ldh [hSpeedCurvePtr], a
|
|
|
|
ld a, h
|
|
|
|
ldh [hSpeedCurvePtr+1], a
|
2023-10-23 10:16:16 +00:00
|
|
|
|
|
|
|
; Do we want to force 20G?
|
|
|
|
ld a, [wAlways20GState]
|
2023-11-13 02:05:39 +00:00
|
|
|
or a, a
|
2023-11-13 01:18:13 +00:00
|
|
|
jr z, .continue
|
2023-10-23 10:16:16 +00:00
|
|
|
ld a, 20
|
2023-10-26 07:50:10 +00:00
|
|
|
ldh [hCurrentIntegerGravity], a
|
2023-11-13 02:35:09 +00:00
|
|
|
xor a, a
|
2023-10-26 07:50:10 +00:00
|
|
|
ldh [hCurrentFractionalGravity], a
|
2023-11-13 01:18:13 +00:00
|
|
|
|
|
|
|
.continue
|
|
|
|
call RSTRestoreBank
|
|
|
|
|
|
|
|
; Jump back, we may need to increase more than once.
|
|
|
|
jr AdjustSpeedCurve.docheck
|
|
|
|
|
|
|
|
|
|
|
|
; Builds an internal level that is the displayed level skipped an amount of sections ahead.
|
|
|
|
BuildTrueCLevel:
|
|
|
|
; Except in TGM3 mode, this will always just be the same as the real level, so check for the most common case and bail.
|
|
|
|
ld a, [wSkippedSectionsBCD]
|
2023-11-13 02:05:39 +00:00
|
|
|
or a, a
|
2023-11-13 01:18:13 +00:00
|
|
|
ret z
|
|
|
|
|
|
|
|
; Otherwise, to the thing.
|
|
|
|
ld de, hCLevel
|
|
|
|
ld hl, hTrueCLevel
|
|
|
|
ld bc, 4
|
|
|
|
call UnsafeMemCopy
|
|
|
|
|
|
|
|
; Amount of steps to increment hundreds.
|
|
|
|
ld a, [wSkippedSectionsBCD]
|
|
|
|
and a, $0F
|
|
|
|
ld b, a
|
|
|
|
|
|
|
|
; Increase hundreds
|
|
|
|
ldh a, [hTrueCLevel+CLEVEL_HUNDREDS]
|
|
|
|
add a, b
|
|
|
|
ldh [hTrueCLevel+CLEVEL_HUNDREDS], a
|
|
|
|
|
|
|
|
; Is hundreds overflowing?
|
|
|
|
cp a, $0A
|
|
|
|
jr c, .thousands
|
|
|
|
|
|
|
|
; Yes, it was, so decrease by 10, and increment thousands.
|
|
|
|
sub a, 10
|
|
|
|
ldh [hTrueCLevel+CLEVEL_HUNDREDS], a
|
|
|
|
ld hl, hTrueCLevel+CLEVEL_THOUSANDS
|
|
|
|
inc [hl]
|
|
|
|
|
|
|
|
.thousands
|
|
|
|
; Amount of steps to increment thousands.
|
|
|
|
ld a, [wSkippedSectionsBCD]
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
|
|
|
ld b, a
|
|
|
|
|
|
|
|
; Increase thousands
|
|
|
|
ldh a, [hTrueCLevel+CLEVEL_THOUSANDS]
|
|
|
|
add a, b
|
|
|
|
ldh [hTrueCLevel+CLEVEL_THOUSANDS], a
|
|
|
|
|
|
|
|
; This may cause a nonsense number. Fix it if that happens.
|
|
|
|
cp a, $0A
|
|
|
|
ret c
|
|
|
|
ld a, $09
|
|
|
|
ldh [hTrueCLevel+CLEVEL_THOUSANDS], a
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
2023-10-13 09:20:28 +00:00
|
|
|
|
|
|
|
|
2023-11-08 21:35:08 +00:00
|
|
|
CheckSpecialLevelConditions:
|
2023-11-09 19:56:44 +00:00
|
|
|
; Is our nlevel > our kill screen?
|
|
|
|
ld hl, wKillScreenActivationLevelBCD+1
|
|
|
|
ld a, [hl]
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
|
|
|
ld b, a
|
|
|
|
ldh a, [hNLevel]
|
|
|
|
cp a, b
|
|
|
|
jr c, .nooverride
|
|
|
|
jr nz, .override
|
|
|
|
ld a, [hl-]
|
|
|
|
and a, $0F
|
|
|
|
ld b, a
|
|
|
|
ldh a, [hNLevel+1]
|
|
|
|
cp a, b
|
|
|
|
jr c, .nooverride
|
|
|
|
jr nz, .override
|
|
|
|
ld a, [hl]
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
|
|
|
ld b, a
|
|
|
|
ldh a, [hNLevel+2]
|
|
|
|
cp a, b
|
|
|
|
jr c, .nooverride
|
|
|
|
jr nz, .override
|
|
|
|
ld a, [hl]
|
|
|
|
and a, $0F
|
|
|
|
ld b, a
|
|
|
|
ldh a, [hNLevel+3]
|
|
|
|
cp a, b
|
|
|
|
jr c, .nooverride
|
|
|
|
|
|
|
|
.override
|
|
|
|
ld hl, wKillScreenActivationLevelBCD
|
|
|
|
ld a, [hl]
|
|
|
|
and a, $0F
|
|
|
|
ldh [hNLevel+3], a
|
|
|
|
ld a, [hl+]
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
|
|
|
ldh [hNLevel+2], a
|
|
|
|
ld a, [hl]
|
|
|
|
and a, $0F
|
|
|
|
ldh [hNLevel+1], a
|
|
|
|
ld a, [hl]
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
|
|
|
ldh [hNLevel], a
|
|
|
|
|
2023-11-08 21:35:08 +00:00
|
|
|
; Get our level in bc
|
2023-11-09 19:56:44 +00:00
|
|
|
.nooverride
|
2023-11-08 21:35:08 +00:00
|
|
|
ldh a, [hLevel]
|
|
|
|
ld c, a
|
|
|
|
ldh a, [hLevel+1]
|
|
|
|
ld b, a
|
|
|
|
|
2023-11-09 19:56:44 +00:00
|
|
|
; Do we need to do a special lock?
|
|
|
|
.speciallock
|
|
|
|
ld hl, wLastLockLevel
|
|
|
|
ld a, [hl+]
|
|
|
|
cp a, $FF ; $FF means never.
|
|
|
|
jp z, .bones
|
|
|
|
|
|
|
|
; Load the level, binary in de.
|
|
|
|
ld e, a
|
|
|
|
ld d, [hl]
|
|
|
|
|
|
|
|
; Check if BC == DE...
|
|
|
|
ld a, b
|
|
|
|
cp a, d
|
|
|
|
jr nz, .bones
|
|
|
|
ld a, c
|
|
|
|
cp a, e
|
|
|
|
jr nz, .bones
|
|
|
|
|
|
|
|
; Jingle and level lock.
|
|
|
|
ld a, $FF
|
|
|
|
ldh [hRequiresLineClear], a
|
|
|
|
ld [wNoMoreLocks], a
|
|
|
|
push bc
|
2023-11-10 22:16:47 +00:00
|
|
|
call SFXKill
|
|
|
|
ld a, SFX_LEVELLOCK
|
2023-11-09 19:56:44 +00:00
|
|
|
call SFXEnqueue
|
|
|
|
pop bc
|
|
|
|
|
2023-11-08 21:35:08 +00:00
|
|
|
; Bones?
|
|
|
|
.bones
|
|
|
|
ld hl, wBoneActivationLevel
|
|
|
|
ld a, [hl+]
|
|
|
|
cp a, $FF ; $FF means never.
|
|
|
|
jp z, .invis
|
|
|
|
|
|
|
|
; Load the level, binary in de.
|
|
|
|
ld e, a
|
|
|
|
ld d, [hl]
|
|
|
|
|
|
|
|
; Check if BC >= DE...
|
|
|
|
; Skip if B < D.
|
|
|
|
ld a, b
|
|
|
|
cp a, d
|
|
|
|
jr c, .invis
|
|
|
|
|
|
|
|
; We can confidently enter the bone zone if B > D.
|
|
|
|
jr nz, .enterthebonezone
|
|
|
|
|
|
|
|
; If B == D, we need to check C and E...
|
|
|
|
|
|
|
|
; Skip if C < E. Otherwise enter the bone zone.
|
|
|
|
ld a, c
|
|
|
|
cp a, e
|
|
|
|
jr c, .invis
|
|
|
|
|
|
|
|
.enterthebonezone
|
|
|
|
ld a, $FF
|
|
|
|
ld [wBonesActive], a
|
|
|
|
|
|
|
|
; Invis?
|
|
|
|
.invis
|
|
|
|
ld hl, wInvisActivationLevel
|
|
|
|
ld a, [hl+]
|
|
|
|
cp a, $FF ; $FF means never.
|
|
|
|
jp z, .killscreen
|
|
|
|
|
|
|
|
; Load the level, binary in de.
|
|
|
|
ld e, a
|
|
|
|
ld d, [hl]
|
|
|
|
|
|
|
|
; Check if BC >= DE...
|
|
|
|
; Skip if B < D.
|
|
|
|
ld a, b
|
|
|
|
cp a, d
|
|
|
|
jr c, .killscreen
|
|
|
|
|
|
|
|
; We can confidently vanish if B > D.
|
|
|
|
jr nz, .vanishoxyaction
|
|
|
|
|
|
|
|
; If B == D, we need to check C and E...
|
|
|
|
|
|
|
|
; Skip if C < E. Otherwise vanish.
|
|
|
|
ld a, c
|
|
|
|
cp a, e
|
|
|
|
jr c, .killscreen
|
|
|
|
|
|
|
|
.vanishoxyaction
|
|
|
|
ld a, $FF
|
|
|
|
ld [wInvisActive], a
|
|
|
|
|
|
|
|
; Kill screen?
|
|
|
|
.killscreen
|
|
|
|
ld hl, wKillScreenActivationLevel
|
|
|
|
ld a, [hl+]
|
|
|
|
cp a, $FF
|
|
|
|
ret z
|
|
|
|
|
|
|
|
; Load the level, binary in de.
|
|
|
|
ld e, a
|
|
|
|
ld d, [hl]
|
|
|
|
|
|
|
|
; Check if BC >= DE...
|
|
|
|
; Ret if B < D.
|
|
|
|
ld a, b
|
|
|
|
cp a, d
|
|
|
|
ret c
|
|
|
|
|
|
|
|
; We can confidently rip if B > D.
|
|
|
|
jr nz, .rip
|
|
|
|
|
|
|
|
; If B == D, we need to check C and E...
|
|
|
|
|
|
|
|
; Skip if C < E. Otherwise rip.
|
|
|
|
ld a, c
|
|
|
|
cp a, e
|
|
|
|
ret c
|
|
|
|
|
|
|
|
.rip
|
2023-11-09 19:56:44 +00:00
|
|
|
call SFXKill
|
2023-11-08 22:36:10 +00:00
|
|
|
|
|
|
|
ld a, $FF
|
|
|
|
ld [wKillScreenActive], a
|
2023-11-08 23:27:44 +00:00
|
|
|
|
|
|
|
ld hl, wKillScreenActivationLevelBCD
|
|
|
|
ld a, [hl]
|
|
|
|
and a, $0F
|
|
|
|
ldh [hCLevel+3], a
|
|
|
|
ldh [hNLevel+3], a
|
|
|
|
ld a, [hl+]
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
|
|
|
ldh [hCLevel+2], a
|
|
|
|
ldh [hNLevel+2], a
|
|
|
|
ld a, [hl]
|
|
|
|
and a, $0F
|
|
|
|
ldh [hCLevel+1], a
|
|
|
|
ldh [hNLevel+1], a
|
|
|
|
ld a, [hl]
|
|
|
|
swap a
|
|
|
|
and a, $0F
|
|
|
|
ldh [hCLevel], a
|
|
|
|
ldh [hNLevel], a
|
|
|
|
ld a, $FF
|
|
|
|
ld [wLockLevel], a
|
2023-11-09 19:56:44 +00:00
|
|
|
|
|
|
|
; Since we triggered a kill screen, does this mean the game now just ends, or do we transition to the staff roll?
|
|
|
|
.staffroll
|
|
|
|
ld hl, wStaffRollDuration
|
|
|
|
ld a, [hl+]
|
|
|
|
cp a, $FF
|
|
|
|
jr z, .justkill
|
|
|
|
|
|
|
|
; Yes, tell the game that we should go to staff roll instead.
|
|
|
|
ld a, $FF
|
|
|
|
ld [wShouldGoStaffRoll], a
|
|
|
|
ret
|
|
|
|
|
|
|
|
.justkill
|
|
|
|
ld a, 1
|
|
|
|
ldh [hCurrentARE], a
|
|
|
|
ldh [hCurrentLineARE], a
|
|
|
|
ldh [hCurrentDAS], a
|
|
|
|
ldh [hCurrentLockDelay], a
|
|
|
|
ldh [hCurrentLineClearDelay], a
|
|
|
|
|
|
|
|
ld a, 20
|
|
|
|
ldh [hCurrentIntegerGravity], a
|
|
|
|
|
|
|
|
xor a, a
|
|
|
|
ldh [hCurrentFractionalGravity], a
|
2023-11-08 22:36:10 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
TriggerKillScreen::
|
2023-11-09 19:56:44 +00:00
|
|
|
call SFXKill
|
2023-11-08 22:36:10 +00:00
|
|
|
ld a, 1
|
|
|
|
ldh [hCurrentARE], a
|
|
|
|
ldh [hCurrentLineARE], a
|
|
|
|
ldh [hCurrentDAS], a
|
|
|
|
ldh [hCurrentLockDelay], a
|
|
|
|
ldh [hCurrentLineClearDelay], a
|
|
|
|
|
|
|
|
ld a, 20
|
|
|
|
ldh [hCurrentIntegerGravity], a
|
|
|
|
|
|
|
|
xor a, a
|
|
|
|
ldh [hCurrentFractionalGravity], a
|
|
|
|
ld [wKillScreenActivationLevel], a
|
|
|
|
ld [wKillScreenActivationLevel+1], a
|
|
|
|
|
|
|
|
ld a, $FF
|
|
|
|
ld [wKillScreenActive], a
|
2023-11-08 21:35:08 +00:00
|
|
|
ret
|
|
|
|
|
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
; Gets a 0-indexed section number, returned in A as binary.
|
|
|
|
; Levels 0000-0099 would return 0, levels 0100-0199 would return 1, ... levels 9900-9999 would return 99.
|
|
|
|
GetSection::
|
|
|
|
; Load thousands.
|
|
|
|
ldh a, [hCLevel+CLEVEL_THOUSANDS]
|
|
|
|
|
|
|
|
; Multiply by 10, which is equal to multiply by 8 + multiply by 2
|
|
|
|
ld b, a
|
|
|
|
sla b
|
2023-11-13 02:09:57 +00:00
|
|
|
add a, a
|
|
|
|
add a, a
|
|
|
|
add a, a
|
2023-11-13 01:18:13 +00:00
|
|
|
add a, b
|
|
|
|
|
|
|
|
; Add hundreds.
|
|
|
|
ld hl, hCLevel+CLEVEL_HUNDREDS
|
|
|
|
add a, [hl]
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
; Gets the current section, but as BCD in A.
|
|
|
|
GetSectionBCD::
|
|
|
|
ldh a, [hCLevel+CLEVEL_THOUSANDS]
|
|
|
|
swap a
|
|
|
|
ld hl, hCLevel+CLEVEL_HUNDREDS
|
|
|
|
or a, [hl]
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
2023-11-13 01:25:08 +00:00
|
|
|
; Gets a 0-indexed section number, returned in A as binary.
|
|
|
|
; Levels 0000-0099 would return 0, levels 0100-0199 would return 1, ... levels 9900-9999 would return 99.
|
|
|
|
; This version calculates the amount of skipped sections in.
|
|
|
|
GetAdjustedSection::
|
|
|
|
; Load thousands.
|
|
|
|
ldh a, [hTrueCLevel+CLEVEL_THOUSANDS]
|
|
|
|
|
|
|
|
; Multiply by 10, which is equal to multiply by 8 + multiply by 2
|
|
|
|
ld b, a
|
|
|
|
sla b
|
2023-11-13 02:09:57 +00:00
|
|
|
add a, a
|
|
|
|
add a, a
|
|
|
|
add a, a
|
2023-11-13 01:25:08 +00:00
|
|
|
add a, b
|
|
|
|
|
|
|
|
; Add hundreds.
|
|
|
|
ld hl, hTrueCLevel+CLEVEL_HUNDREDS
|
|
|
|
add a, [hl]
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
; Gets the current section, but as BCD in A.
|
|
|
|
; This version calculates the amount of skipped sections in.
|
|
|
|
GetAdjustedSectionBCD::
|
|
|
|
ldh a, [hTrueCLevel+CLEVEL_THOUSANDS]
|
|
|
|
swap a
|
|
|
|
ld hl, hTrueCLevel+CLEVEL_HUNDREDS
|
|
|
|
or a, [hl]
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
2023-11-13 01:18:13 +00:00
|
|
|
; Will skip the virtual level forward by 100 levels.
|
|
|
|
; This will NOT affect the displayed level, nor will it affect scoring.
|
|
|
|
; It will only make it so the internal speed pointer will be ahead by N*100 levels.
|
|
|
|
SkipSection::
|
|
|
|
ld a, [wSkippedSectionsBCD]
|
|
|
|
add a, $01
|
|
|
|
daa ; Yes, this is the rare case where this instruction is useful!
|
|
|
|
ld [wSkippedSectionsBCD], a
|
|
|
|
jp AdjustSpeedCurve
|
|
|
|
|
2023-10-13 09:20:28 +00:00
|
|
|
ENDC
|