dmgtris/src/hiscore.asm

426 lines
9.4 KiB
NASM
Raw Normal View History

2023-11-10 11:07:57 +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(HISCORE_ASM)
DEF HISCORE_ASM EQU 1
INCLUDE "globals.asm"
SECTION "Hi Score Data", ROM0
sHiscoreDefaultData::
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "DMG", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "TRI", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "SDM", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "GTR", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "ISD", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "MGT", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "RIS", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "DMG", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "TRI", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-11 13:44:23 +00:00
db 0, 0, 0, 0, 0, 0, 0, 0, "SDM", GRADE_NONE, RNG_MODE_TGM3, ROT_MODE_ARSTI, DROP_MODE_FIRM, HIG_MODE_OFF
2023-11-12 00:12:39 +00:00
db 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2023-11-10 11:07:57 +00:00
SECTION "Hi Score Variables", WRAM0
wTargetHSTable:: ds 2
2023-11-11 14:32:48 +00:00
wWorkingIdx:: ds 1
wWorkingPtr:: ds 1
2023-11-11 13:44:23 +00:00
wWorkingCopy:: ds ((HISCORE_ENTRY_COUNT+1)*(HISCORE_ENTRY_SIZE))
2023-11-11 14:32:48 +00:00
wInsertTarget:: ds 1
2023-11-10 11:07:57 +00:00
SECTION "Hi Score Functions", ROM0
CheckAndAddHiscore::
2023-11-11 14:32:48 +00:00
; Get the table
ld a, [wSpeedCurveState]
call InitTargetHSTable
; Initialize loop at 0.
xor a, a
ld [wInsertTarget], a
.checkloop
; Load the score at position a.
call GetHiScoreEntry
2023-11-12 00:12:39 +00:00
; Backup HL to DE for later.
ld d, h
ld e, l
; Compare grades, HL needs to forwarded 11 bytes.
.checkgrade
ld bc, 11
add hl, bc
; HL is now pointing to the grade in this high score.
; The handling depends on whether or not the old score had a grade.
ld a, [hl]
cp a, GRADE_NONE
jr z, .oldungraded
; The old score had a grade, so compare ours to theirs.
.oldgraded
ld b, a
ld a, [wDisplayedGrade]
2023-11-12 13:35:16 +00:00
cp a, GRADE_NONE
jr z, .notbetter ; If we don't have a grade, we're worse than any grade.
2023-11-12 00:12:39 +00:00
cp a, b
jr c, .notbetter ; If we're less, we're not better.
jr nz, .better ; If we're higher, we're better.
jr .checklevel ; Equal, so check level.
; The old score did NOT have a grade. So check if we do.
.oldungraded
ld a, [wDisplayedGrade]
cp a, GRADE_NONE
jr nz, .better ; We do have a grade, so we win.
; We don't have a grade either, so continue as equals.
; Our grade is equal.
; Compare levels. HL needs to be forwarded 5 bytes.
.checklevel
ld bc, 5
add hl, bc
; HL is now pointing to the level in this high score.
; Make BC point to our level.
ld bc, hCLevel
; And compare the first digit...
ld a, [bc]
cp a, [hl]
jr c, .notbetter ; Lower? Not better.
jr nz, .better ; Higher? Better.
inc bc ; Equal? Keep checking...
inc hl
; Second...
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Third...
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Fourth...
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
; Our level is equal.
; So now also check the score. Restore the DE from earlier.
.checkscore
ld h, d
ld l, e
2023-11-11 14:32:48 +00:00
; HL is pointing to that score, make BC point to our current score.
ld bc, hScore
; First digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Second digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Third digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Fourth digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Fifth digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Sixth digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Seventh digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
inc bc
inc hl
; Eighth digit
ld a, [bc]
cp a, [hl]
jr c, .notbetter
jr nz, .better
2023-11-12 00:12:39 +00:00
; If we fell through all the way to here, we are completely equal. Oldest score has priority.
2023-11-11 14:32:48 +00:00
; Loop or return if we didn't make the scores.
.notbetter
ld a, [wInsertTarget]
inc a
ld [wInsertTarget], a
cp a, 10
ret z
2023-11-12 00:12:39 +00:00
jp .checkloop
2023-11-11 14:32:48 +00:00
.better
jr InsertHiScore
; Inserts the current score data into the table.
; Data will be saved and persisted.
InsertHiScore::
; Copy the entire table to working data, but one row down.
.copylower
ld a, [wTargetHSTable]
ld e, a
ld a, [wTargetHSTable+1]
ld d, a
ld hl, wWorkingCopy+HISCORE_ENTRY_SIZE
ld bc, (HISCORE_ENTRY_COUNT*HISCORE_ENTRY_SIZE)
call UnsafeMemCopy
; Copy the top rows to the working data.
.copyupper
ld a, [wInsertTarget]
cp a, 0
jr z, .findrow
ld hl, 0
ld bc, HISCORE_ENTRY_SIZE
: add hl, bc
dec a
jr nz, :-
ld b, h
ld c, l
ld a, [wTargetHSTable]
ld e, a
ld a, [wTargetHSTable+1]
ld d, a
ld hl, wWorkingCopy
call UnsafeMemCopy
; Make HL point to the correct location to insert the new score
.findrow
ld hl, wWorkingCopy
ld bc, HISCORE_ENTRY_SIZE
ld a, [wInsertTarget]
cp a, 0
jr z, .insert
: add hl, bc
dec a
jr nz, :-
; And do the insertion
.insert
ldh a, [hScore+0]
ld [hl+], a
ldh a, [hScore+1]
ld [hl+], a
ldh a, [hScore+2]
ld [hl+], a
ldh a, [hScore+3]
ld [hl+], a
ldh a, [hScore+4]
ld [hl+], a
ldh a, [hScore+5]
ld [hl+], a
ldh a, [hScore+6]
ld [hl+], a
ldh a, [hScore+7]
ld [hl+], a
ld a, [wProfileName+0]
ld [hl+], a
ld a, [wProfileName+1]
ld [hl+], a
ld a, [wProfileName+2]
ld [hl+], a
ld a, [wDisplayedGrade]
ld [hl+], a
ld a, [wRNGModeState]
ld [hl+], a
ld a, [wRotModeState]
ld [hl+], a
ld a, [wDropModeState]
ld [hl+], a
ld a, [wAlways20GState]
ld [hl+], a
2023-11-12 00:12:39 +00:00
ldh a, [hCLevel+0]
ld [hl+], a
ldh a, [hCLevel+1]
ld [hl+], a
ldh a, [hCLevel+2]
ld [hl+], a
ldh a, [hCLevel+3]
ld [hl+], a
ldh a, [hNLevel+0]
ld [hl+], a
ldh a, [hNLevel+1]
ld [hl+], a
ldh a, [hNLevel+2]
ld [hl+], a
ldh a, [hNLevel+3]
ld [hl+], a
2023-11-11 14:32:48 +00:00
2023-11-12 00:12:39 +00:00
; 8 filler bytes.
2023-11-11 14:32:48 +00:00
xor a, a
2023-11-12 00:12:39 +00:00
REPT 8
2023-11-11 14:32:48 +00:00
ld [hl+], a
ENDR
; And copy it back.
.persist
ld de, wWorkingCopy
ld a, [wTargetHSTable]
ld l, a
ld a, [wTargetHSTable+1]
ld h, a
ld bc, HISCORE_ENTRY_COUNT*HISCORE_ENTRY_SIZE
jp UnsafeMemCopy
; Updates the pointers for the current hi score to point to the index in register A.
; HL will be left pointing at said memory.
GetHiScoreEntry::
ld [wWorkingIdx], a
ld a, [wTargetHSTable]
ld l, a
ld a, [wTargetHSTable+1]
ld h, a
ld bc, HISCORE_ENTRY_SIZE
ld a, [wWorkingIdx]
cp a, 0
jr z, .store
: add hl, bc
dec a
jr nz, :-
.store
ld a, l
ld [wWorkingPtr], a
ld a, h
ld [wWorkingPtr+1], a
2023-11-10 11:07:57 +00:00
ret
2023-11-11 14:32:48 +00:00
; Initializes all the pointers to point to the very first score in the table for the game mode passed in
; register A.
InitTargetHSTable::
ld b, a
add a, b
add a, b
ld c, a
ld b, 0
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, rScoreTableDMGT
jr .store
.tgm1
ld hl, rScoreTableTGM1
jr .store
.tgm3
ld hl, rScoreTableTGM3
jr .store
.deat
ld hl, rScoreTableDEAT
jr .store
.shir
ld hl, rScoreTableSHIR
jr .store
.chil
ld hl, rScoreTableCHIL
jr .store
.myco
ld hl, rScoreTableMYCO
.store
ld a, l
ld [wTargetHSTable], a
ld [wWorkingPtr], a
ld a, h
ld [wTargetHSTable+1], a
ld [wWorkingPtr+1], a
xor a, a
ld [wWorkingIdx], a
2023-11-10 11:07:57 +00:00
ret
ENDC