2023-11-02 06:42:45 +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/>.
|
|
|
|
|
|
|
|
|
|
|
|
IF !DEF(GRADING_ASM)
|
|
|
|
DEF GRADING_ASM EQU 1
|
|
|
|
|
|
|
|
|
|
|
|
INCLUDE "globals.asm"
|
|
|
|
|
|
|
|
|
|
|
|
SECTION "Grade Variables", WRAM0
|
|
|
|
wDecayRate: ds 1
|
|
|
|
wGradePoints: ds 1
|
|
|
|
wInternalGrade: ds 1
|
|
|
|
wDisplayedGrade:: ds 1
|
|
|
|
wEffectTimer:: ds 1
|
|
|
|
wRankingDisqualified:: ds 1
|
|
|
|
|
|
|
|
|
|
|
|
SECTION "Grading Data", ROM0
|
|
|
|
; The Score Thresholds are 3/4th of the original ones.
|
|
|
|
sTGM1GradeScores:
|
|
|
|
dw $0003 ;00 — 8
|
|
|
|
dw $0006 ;00 — 7
|
|
|
|
dw $0009 ;00 — 6
|
|
|
|
dw $0015 ;00 — 5
|
|
|
|
dw $0021 ;00 — 4
|
|
|
|
dw $0039 ;00 — 3
|
|
|
|
dw $0060 ;00 — 2
|
|
|
|
dw $0090 ;00 — 1
|
|
|
|
dw $0120 ;00 — S1
|
|
|
|
dw $0165 ;00 — S2
|
|
|
|
dw $0225 ;00 — S3
|
|
|
|
dw $0300 ;00 — S4
|
|
|
|
dw $0390 ;00 — S5
|
|
|
|
dw $0495 ;00 — S6
|
|
|
|
dw $0615 ;00 — S7
|
|
|
|
dw $0750 ;00 — S8
|
|
|
|
dw $0900 ;00 — S9
|
|
|
|
|
|
|
|
sTGM3InternalGradeSystem:
|
|
|
|
db 125, 10, 20, 40, 50 ;Decay rate, (Internal grade points awarded for:) Single, Double, Triple, Tetris
|
|
|
|
db 80, 10, 20, 30, 40
|
|
|
|
db 80, 10, 20, 30, 40
|
|
|
|
db 50, 10, 15, 30, 40
|
|
|
|
db 45, 5, 15, 20, 40
|
|
|
|
db 45, 5, 15, 20, 30
|
|
|
|
db 45, 5, 10, 20, 30
|
|
|
|
db 40, 5, 10, 15, 30
|
|
|
|
db 40, 5, 10, 15, 30
|
|
|
|
db 40, 5, 10, 15, 30
|
|
|
|
db 40, 2, 12, 13, 30
|
|
|
|
db 40, 2, 12, 13, 30
|
|
|
|
db 30, 2, 12, 13, 30
|
|
|
|
db 30, 2, 12, 13, 30
|
|
|
|
db 30, 2, 12, 13, 30
|
|
|
|
db 20, 2, 12, 13, 30
|
|
|
|
db 20, 2, 12, 13, 30
|
|
|
|
db 20, 2, 12, 13, 30
|
|
|
|
db 20, 2, 12, 13, 30
|
|
|
|
db 20, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 15, 2, 12, 13, 30
|
|
|
|
db 10, 2, 12, 13, 30
|
|
|
|
db 10, 2, 12, 13, 30
|
|
|
|
|
|
|
|
sTGM3GradeBoosts:
|
|
|
|
db 0
|
|
|
|
db 1
|
|
|
|
db 2
|
|
|
|
db 3
|
|
|
|
db 4
|
|
|
|
db 5
|
|
|
|
db 5
|
|
|
|
db 6
|
|
|
|
db 6
|
|
|
|
db 7
|
|
|
|
db 7
|
|
|
|
db 7
|
|
|
|
db 8
|
|
|
|
db 8
|
|
|
|
db 8
|
|
|
|
db 9
|
|
|
|
db 9
|
|
|
|
db 10
|
|
|
|
db 11
|
|
|
|
db 12
|
|
|
|
db 12
|
|
|
|
db 12
|
|
|
|
db 13
|
|
|
|
db 13
|
|
|
|
db 14
|
|
|
|
db 14
|
|
|
|
db 15
|
|
|
|
db 15
|
|
|
|
db 16
|
|
|
|
db 16
|
|
|
|
db 17
|
|
|
|
|
|
|
|
; sTGM3ComboMultipliers:
|
|
|
|
; db 1, 1.0, 1.0, 1.0, 1.0 ; Combo size, (Multiplier for: ) Single, Double, Triple, Tetris
|
|
|
|
; db 2, 1.0, 1.2, 1.4, 1.5
|
|
|
|
; db 3, 1.0, 1.2, 1.5, 1.8
|
|
|
|
; db 4, 1.0, 1.4, 1.6, 2.0
|
|
|
|
; db 5, 1.0, 1.4, 1.7, 2.2
|
|
|
|
; db 6, 1.0, 1.4, 1.8, 2.3
|
|
|
|
; db 7, 1.0, 1.4, 1.9, 2.4
|
|
|
|
; db 8, 1.0, 1.5, 2.0, 2.5
|
|
|
|
; db 9, 1.0, 1.5, 2.1, 2.6
|
|
|
|
; db 10, 2.0, 2.5, 3.0, 3.0
|
|
|
|
|
|
|
|
sTGM3LevelMultiplier:
|
|
|
|
db 1 ; 000-249
|
|
|
|
db 2 ; 250-499
|
|
|
|
db 3 ; 500-749
|
|
|
|
db 4 ; 750-999
|
|
|
|
|
|
|
|
sTGM3BaselineCOOL:
|
|
|
|
db 52 ;070 (value in seconds)
|
|
|
|
db 52 ;170
|
|
|
|
db 49 ;270
|
|
|
|
db 45 ;370
|
|
|
|
db 45 ;470
|
|
|
|
db 42 ;570
|
|
|
|
db 42 ;670
|
|
|
|
db 38 ;770
|
|
|
|
db 38 ;870
|
|
|
|
|
|
|
|
sTGM3REGRETConditions:
|
|
|
|
db 1, 30 ;minutes, seconds
|
|
|
|
db 1, 15
|
|
|
|
db 1, 15
|
|
|
|
db 1, 8
|
|
|
|
db 1, 0
|
|
|
|
db 1, 0
|
|
|
|
db 0, 50
|
|
|
|
db 0, 50
|
|
|
|
db 0, 50
|
|
|
|
db 0, 50
|
|
|
|
|
|
|
|
SECTION "Grading Functions", ROM0
|
|
|
|
; Wipe the grading variables.
|
|
|
|
GradeInit::
|
|
|
|
xor a, a
|
|
|
|
ld [wDecayRate], a
|
|
|
|
ld [wGradePoints], a
|
|
|
|
ld [wInternalGrade], a
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
ld [wRankingDisqualified], a
|
|
|
|
ld [wEffectTimer], a
|
|
|
|
|
|
|
|
; Not all modes start at 9.
|
|
|
|
; Death starts ungraded.
|
|
|
|
ld a, [wSpeedCurveState]
|
|
|
|
cp a, SCURVE_DEAT
|
|
|
|
jr nz, .notdeat
|
|
|
|
ld a, GRADE_NONE
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
jr UpdateGrade
|
|
|
|
|
|
|
|
.notdeat
|
|
|
|
; Shirase starts ungraded.
|
|
|
|
ld a, [wSpeedCurveState]
|
|
|
|
cp a, SCURVE_SHIR
|
|
|
|
jr nz, .notshir
|
|
|
|
ld a, GRADE_NONE
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
jr UpdateGrade
|
|
|
|
|
|
|
|
.notshir
|
|
|
|
; All the rest start at 9.
|
|
|
|
ld a, GRADE_9
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
jr UpdateGrade
|
|
|
|
|
|
|
|
|
|
|
|
; Jumps to the grade update function for the current mode.
|
|
|
|
UpdateGrade::
|
|
|
|
ld hl, .gradejumptable
|
|
|
|
ld a, [wSpeedCurveState]
|
|
|
|
ld b, a
|
|
|
|
add a, b
|
|
|
|
add a, b
|
|
|
|
ld b, 0
|
|
|
|
ld c, a
|
|
|
|
add hl, bc
|
|
|
|
jp hl
|
|
|
|
|
|
|
|
.gradejumptable
|
|
|
|
jp UpdateGradeTGM1 ;DMGT
|
|
|
|
jp UpdateGradeTGM1 ;TGM1
|
|
|
|
jp UpdateGradeTGM1 ;TGM3
|
|
|
|
jp UpdateGradeDEAT ;DEAT
|
|
|
|
jp UpdateGradeSHIR ;SHIR
|
|
|
|
jp UpdateGradeTGM1 ;CHIL
|
|
|
|
|
|
|
|
|
|
|
|
; Get the four most significant figures of the score in BC as BCD.
|
|
|
|
PrepareScore:
|
|
|
|
ld a, [hScore+3]
|
|
|
|
ld b, a
|
|
|
|
ld a, [hScore+2]
|
|
|
|
swap a
|
|
|
|
or b
|
|
|
|
ld c, a
|
|
|
|
ld a, [hScore+1]
|
|
|
|
ld b, a
|
|
|
|
ld a, [hScore]
|
|
|
|
swap a
|
|
|
|
or b
|
|
|
|
ld b, a
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
UpdateGradeTGM1:
|
|
|
|
; Bail if we're already GM.
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
cp a, GRADE_GM
|
|
|
|
ret z
|
|
|
|
|
|
|
|
; Skip to GM check if already S9.
|
|
|
|
cp a, GRADE_S9
|
|
|
|
jr nc, .maybegm
|
|
|
|
|
|
|
|
.trygradeup
|
|
|
|
; Otherwise, check if we can increase the grade.
|
|
|
|
; Get our score into BC
|
|
|
|
call PrepareScore
|
|
|
|
|
|
|
|
; Double our current grade and use it as an offset into the scoring table.
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
add a
|
|
|
|
ld d, 0
|
|
|
|
ld e, a
|
|
|
|
|
|
|
|
; Have HL point to the next required score and get it into DE.
|
|
|
|
ld hl, sTGM1GradeScores
|
|
|
|
add hl, de
|
|
|
|
|
|
|
|
; LSB
|
|
|
|
ld a, [hl+]
|
|
|
|
ld e, a
|
|
|
|
|
|
|
|
; MSB
|
|
|
|
ld a, [hl]
|
|
|
|
ld d, a
|
|
|
|
|
|
|
|
; Check if BC >= DE...
|
|
|
|
; Return if B < D.
|
|
|
|
ld a, b
|
|
|
|
cp a, d
|
|
|
|
ret c
|
|
|
|
|
|
|
|
; We can confidently increase the grade if B > D.
|
|
|
|
jr nz, .increasegrade
|
|
|
|
|
|
|
|
; If B == D, we need to check C and E...
|
|
|
|
|
|
|
|
; Return if C < E. Otherwise increase the grade.
|
|
|
|
ld a, c
|
|
|
|
cp a, e
|
|
|
|
ret c
|
|
|
|
|
|
|
|
.increasegrade
|
|
|
|
; Add 1 to the grade.
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
inc a
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
|
|
|
|
; Play the jingle, if not already doing so.
|
|
|
|
ldh a, [hCurrentlyPlaying]
|
|
|
|
cp a, SFX_RANKUP
|
|
|
|
jr z, .skipjingle
|
|
|
|
ld a, SFX_RANKUP
|
|
|
|
call SFXEnqueue
|
|
|
|
|
|
|
|
; Prepare the effect stuff
|
|
|
|
.skipjingle
|
|
|
|
ld a, $0F
|
|
|
|
ld [wEffectTimer], a
|
|
|
|
|
|
|
|
; Loop and see if we can increment more grades.
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
cp a, GRADE_S9 ; Don't go past S9.
|
|
|
|
ret z
|
|
|
|
jr .trygradeup
|
|
|
|
|
|
|
|
.maybegm
|
|
|
|
; Level needs to be 1000 or greater.
|
|
|
|
ld a, [hCLevel] ; Level, thousands digit.
|
|
|
|
cp a, 1
|
|
|
|
ret c
|
|
|
|
|
|
|
|
; Set the grade to GM
|
|
|
|
ld a, GRADE_GM
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
|
|
|
|
; Sound effect
|
|
|
|
ld a, SFX_RANKGM
|
|
|
|
jp SFXEnqueue
|
|
|
|
|
|
|
|
; Prepare the effect stuff
|
|
|
|
ld a, $0F
|
|
|
|
ld [wEffectTimer], a
|
|
|
|
|
|
|
|
; Return
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
UpdateGradeDEAT:
|
|
|
|
; If we're disqualified, don't update the grade.
|
|
|
|
ld a, [wRankingDisqualified]
|
|
|
|
cp a, $FF
|
|
|
|
ret z
|
|
|
|
|
|
|
|
; If we are already GM, don't do anything.
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
cp a, GRADE_GM
|
|
|
|
ret z
|
|
|
|
|
|
|
|
.notgm
|
|
|
|
; If we're M, check if we should be GM.
|
|
|
|
cp a, GRADE_M
|
|
|
|
jr nz, .notm
|
|
|
|
|
|
|
|
; We should be GM if we're at or past level 1000.
|
|
|
|
ldh a, [hCLevel] ; Level, thousands digit.
|
|
|
|
cp a, 1
|
|
|
|
ret c ; If less than 1000, return.
|
|
|
|
|
|
|
|
; Otherwise give the grade!
|
|
|
|
ld a, GRADE_GM
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
|
|
|
|
; Play the jingle.
|
|
|
|
ld a, SFX_RANKGM
|
|
|
|
call SFXEnqueue
|
|
|
|
|
|
|
|
; Prepare the effect stuff
|
|
|
|
ld a, $0F
|
|
|
|
ld [wEffectTimer], a
|
|
|
|
ret
|
|
|
|
|
|
|
|
.notm
|
|
|
|
; If we're not M, check if we should be M.
|
|
|
|
ldh a, [hCLevel+1] ; Level, hundreds digit.
|
|
|
|
cp a, 5
|
|
|
|
ret c ; If less than 500, return.
|
|
|
|
|
|
|
|
; There's a 3:25 torikan for M.
|
|
|
|
ld b, 3
|
|
|
|
ld c, 25
|
|
|
|
call CheckTorikan
|
|
|
|
|
|
|
|
; If we failed the Torikan, disqualify from ranking.
|
|
|
|
cp a, $FF
|
|
|
|
jr nz, .disqualify
|
|
|
|
|
|
|
|
; Otherwise award M.
|
|
|
|
ld a, GRADE_M
|
|
|
|
ld [wDisplayedGrade], a
|
|
|
|
|
|
|
|
; Play the jingle.
|
|
|
|
ld a, SFX_RANKUP
|
|
|
|
call SFXEnqueue
|
|
|
|
|
|
|
|
; Prepare the effect stuff
|
|
|
|
ld a, $0F
|
|
|
|
ld [wEffectTimer], a
|
|
|
|
ret
|
|
|
|
|
|
|
|
.disqualify
|
|
|
|
; Disqualify from ranking.
|
|
|
|
ld a, $FF
|
|
|
|
ld [wRankingDisqualified], a
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
UpdateGradeSHIR:
|
|
|
|
; If we're disqualified, don't update the grade any higher.
|
|
|
|
ld a, [wRankingDisqualified]
|
|
|
|
cp a, $FF
|
|
|
|
ret z
|
|
|
|
|
|
|
|
; If we are already GM, don't do anything.
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
cp a, GRADE_S13
|
|
|
|
ret z
|
|
|
|
|
|
|
|
; We don't give out a grade until level 100.
|
|
|
|
ldh a, [hCLevel+1] ; Level, hundreds digit.
|
|
|
|
cp a, 0
|
|
|
|
ret z
|
|
|
|
|
|
|
|
; Get the hundreds and thousands of the level as a hex number.
|
|
|
|
ld b, a ; Hundreds
|
|
|
|
ldh a, [hCLevel] ; Thousands
|
|
|
|
swap a
|
|
|
|
or b
|
|
|
|
|
|
|
|
; Convert the BCD to hex.
|
|
|
|
ld c, a ; C = A
|
|
|
|
and a, $F0 ; A = A & $F0. A is now $00 to $90 if the number was correct BCD.
|
|
|
|
srl a ; A = A >> 1
|
|
|
|
ld b, a ; B = A
|
|
|
|
srl a
|
|
|
|
srl a ; A = A >> 2
|
|
|
|
add a, b ; A += B
|
|
|
|
ld b, a ; B = A. At this point B is 10, 20, 30, ... 90.
|
|
|
|
ld a, c ; A = C
|
|
|
|
and a, $0F ; A = A & $0F. A is now $00 to $09 if the number was correct BCD.
|
|
|
|
add a, b ; Adding B to A gives us the converted number.
|
|
|
|
|
|
|
|
; Adding GRADE_1 to this will give us the grade.
|
|
|
|
add a, GRADE_1
|
|
|
|
ld b, a
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
cp a, b
|
|
|
|
ret z ; If the grade is already correct, return.
|
2023-11-02 18:24:28 +00:00
|
|
|
ld a, b
|
2023-11-02 06:42:45 +00:00
|
|
|
ld [wDisplayedGrade], a ; Otherwise, set the grade.
|
|
|
|
|
|
|
|
; Play the jingle.
|
|
|
|
ld a, SFX_RANKUP
|
|
|
|
call SFXEnqueue
|
|
|
|
|
|
|
|
; Prepare the effect stuff
|
|
|
|
ld a, $0F
|
|
|
|
ld [wEffectTimer], a
|
|
|
|
|
|
|
|
; There's a few torikans for Shirase.
|
|
|
|
ld a, [wDisplayedGrade]
|
|
|
|
.s5torikan
|
|
|
|
cp a, GRADE_S5
|
|
|
|
jr nz, .s10torikan
|
|
|
|
|
|
|
|
; There's a 2:28 torikan after S5.
|
|
|
|
ld b, 2
|
|
|
|
ld c, 28
|
|
|
|
call CheckTorikan
|
|
|
|
|
|
|
|
; If we failed the Torikan, disqualify from ranking up further.
|
|
|
|
cp a, $FF
|
|
|
|
jr nz, .disqualify
|
|
|
|
ret
|
|
|
|
|
|
|
|
.s10torikan
|
|
|
|
cp a, GRADE_S10
|
|
|
|
ret nz
|
|
|
|
|
|
|
|
; There's a 4:56 torikan after S10.
|
|
|
|
ld b, 4
|
|
|
|
ld c, 56
|
|
|
|
call CheckTorikan
|
|
|
|
|
|
|
|
; If we failed the Torikan, disqualify from ranking up further.
|
|
|
|
cp a, $FF
|
|
|
|
jr nz, .disqualify
|
|
|
|
ret
|
|
|
|
|
|
|
|
.disqualify
|
|
|
|
ld a, $FF
|
|
|
|
ld [wRankingDisqualified], a
|
|
|
|
ret
|
|
|
|
|
|
|
|
ENDC
|