dmgtris/src/state_title.asm

1944 lines
32 KiB
NASM

; 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(STATE_TITLE_ASM)
DEF STATE_TITLE_ASM EQU 1
INCLUDE "globals.asm"
INCLUDE "res/title_data.inc"
SECTION "Title Variables", WRAM0
wSelected:: ds 1
wTitleMode:: ds 1
wProfileName:: ds 3
wDisplayingScoreMode:: ds 1
wScoreFlipTimer:: ds 1
SECTION "Title Function Trampolines", ROM0
; Trampolines to the banked function.
SwitchToTitle::
ld b, BANK_TITLE
rst RSTSwitchBank
call SwitchToTitleB
jp RSTRestoreBank
; Banks and jumps to the actual handler.
TitleEventLoopHandler::
ld b, BANK_TITLE
rst RSTSwitchBank
call TitleEventLoopHandlerB
rst RSTRestoreBank
jp EventLoopPostHandler
; Banks and jumps to the actual handler.
TitleVBlankHandler::
ld b, BANK_TITLE
rst RSTSwitchBank
call TitleVBlankHandlerB
rst RSTRestoreBank
jp EventLoop
PersistLevel:
ld b, BANK_OTHER
rst RSTSwitchBank
ld a, [hl+]
ld [rSelectedStartLevel], a
ld a, [hl]
ld [rSelectedStartLevel+1], a
jp RSTRestoreBank
DrawSpeedMain:
ld b, BANK_OTHER
rst RSTSwitchBank
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
ld a, [hl]
swap a
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_MAIN_START+2
ld [hl], a
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
ld a, [hl]
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_MAIN_START+3
ld [hl], a
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
inc hl
ld a, [hl]
swap a
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_MAIN_START+0
ld [hl], a
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
inc hl
ld a, [hl]
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_MAIN_START+1
ld [hl], a
jp RSTRestoreBank
DrawSpeedSettings:
ld b, BANK_OTHER
rst RSTSwitchBank
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
ld a, [hl]
swap a
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_SETTINGS_START+2
ld [hl], a
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
ld a, [hl]
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_SETTINGS_START+3
ld [hl], a
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
inc hl
ld a, [hl]
swap a
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_SETTINGS_START+0
ld [hl], a
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
inc hl
ld a, [hl]
and a, $0F
ld b, a
ld a, TILE_0
add a, b
ld hl, TITLE_SETTINGS_START+1
ld [hl], a
jp RSTRestoreBank
SECTION "Title Functions Banked", ROMX, BANK[BANK_TITLE]
SwitchToTitleB:
; Turn the screen off if it's on.
ldh a, [rLCDC]
and LCDCF_ON
jr z, :+ ; Screen is already off.
wait_vram
xor a, a
ldh [rLCDC], a
; And the tiles.
: call LoadTitleTiles
; Zero out SCX.
xor a, a
ldh [rSCX], a
; No screen squish for title.
call DisableScreenSquish
; Clear OAM.
call ClearOAM
; Set up the palettes.
ld a, PALETTE_INVERTED
set_bg_palette
set_obj0_palette
set_obj1_palette
; Go to the correct title screen mode.
ld a, TITLE_MAIN
call SwitchTitleMode
; Music start
call SFXKill
ld a, MUSIC_MENU
call SFXEnqueue
; Make sure the first game loop starts just like all the future ones.
wait_vblank
wait_vblank_end
ret
SwitchTitleMode:
; Set title to mode in A.
ld [wTitleMode], a
ld a, STATE_TITLE
ldh [hGameState], a
xor a, a
ld [wSelected], a
; Turn the screen off if it's on.
ldh a, [rLCDC]
and LCDCF_ON
jr z, :+ ; Screen is already off.
wait_vram
xor a, a
ldh [rLCDC], a
; Jump to correct handler.
: ld b, 0
ld a, [wTitleMode]
ld c, a
ld hl, .jumps
add hl, bc
jp hl
.jumps
jp .switchMain
jp .switchProfile
jp .switchSettings
jp .switchRecords
jp .switchCredits
.switchMain
ld de, sTitleScreenMainMap
ld hl, $9800
ld bc, sTitleScreenMainMapEnd - sTitleScreenMainMap
call UnsafeMemCopy
; Title screen easter egg.
ld a, [wInitialC]
cp a, $14
jr nz, .notsgb
ld de, sEasterS0
ld hl, EASTER_0
ld bc, 5
call UnsafeMemCopy
ld de, sEasterS1
ld hl, EASTER_1
ld bc, 5
call UnsafeMemCopy
jr .done
.notsgb
ld a, [wInitialA]
cp a, $FF
jr nz, .notmgb
ld de, sEasterM0
ld hl, EASTER_0
ld bc, 5
call UnsafeMemCopy
ld de, sEasterM1
ld hl, EASTER_1
ld bc, 5
call UnsafeMemCopy
jr .done
.notmgb
ld a, [wInitialA]
cp a, $11
jr nz, .done
ld a, [wInitialB]
bit 0, a
jr nz, .agb
ld de, sEasterC0
ld hl, EASTER_0-1
ld bc, 11
call UnsafeMemCopy
ld de, sEasterC1
ld hl, EASTER_1-1
ld bc, 11
call UnsafeMemCopy
jr .done
.agb
ld de, sEasterA0
ld hl, EASTER_0-1
ld bc, 11
call UnsafeMemCopy
ld de, sEasterA1
ld hl, EASTER_1-1
ld bc, 11
call UnsafeMemCopy
jr .done
.done
call GBCTitleInit
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BLK01
ldh [rLCDC], a
ret
.switchProfile
ld de, sTitleScreenProfileMap
ld hl, $9800
ld bc, sTitleScreenProfileMapEnd - sTitleScreenProfileMap
call UnsafeMemCopy
call GBCTitleInit
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BLK01
ldh [rLCDC], a
ret
.switchSettings
ld de, sTitleScreenSettingsMap
ld hl, $9800
ld bc, sTitleScreenSettingsMapEnd - sTitleScreenSettingsMap
call UnsafeMemCopy
call GBCTitleInit
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BLK01
ldh [rLCDC], a
ret
.switchRecords
ld de, sTitleScreenRecordsMap
ld hl, $9800
ld bc, sTitleScreenRecordsMapEnd - sTitleScreenRecordsMap
call UnsafeMemCopy
call GBCTitleInit
xor a, a
ldh [hSelectState], a
ld [wDisplayingScoreMode], a
ld [wScoreFlipTimer], a
call RenderScores
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BLK01
ldh [rLCDC], a
ret
.switchCredits
ld de, sTitleScreenCreditsMap
ld hl, $9800
ld bc, sTitleScreenCreditsMapEnd - sTitleScreenCreditsMap
call UnsafeMemCopy
call GBCTitleInit
ld a, LCDCF_ON | LCDCF_BGON | LCDCF_BLK01
ldh [rLCDC], a
ret
; Event loop handlers for title screen.
TitleEventLoopHandlerB:
call GBCTitleProcess
; Jump to the correct eventloop handler.
ld b, 0
ld a, [wTitleMode]
ld c, a
ld hl, .jumps
add hl, bc
jp hl
.jumps
jp .eventLoopMain
jp .eventLoopProfile
jp .eventLoopSettings
jp .eventLoopRecords
jp .eventLoopCredits
.eventLoopMain
; A/Start?
ldh a, [hAState]
cp a, 1
jp z, MainHandleA
ldh a, [hStartState]
cp a, 1
jp z, MainHandleA
; Select?
ldh a, [hSelectState]
cp a, 1
jp z, NextProfile
; Directions?
ldh a, [hUpState]
cp a, 1
jp z, MainHandleUp
cp a, 16
jp c, .d0
ldh a, [hFrameCtr]
and 3
cp a, 3
jp z, MainHandleUp
.d0
ldh a, [hDownState]
cp a, 1
jp z, MainHandleDown
cp a, 16
ret c
ldh a, [hFrameCtr]
and 3
cp a, 3
ret nz
jp MainHandleDown
.eventLoopProfile
; A/Start?
ldh a, [hAState]
cp a, 1
jp z, ProfileHandleA
ldh a, [hStartState]
cp a, 1
jp z, ProfileHandleA
; B?
ldh a, [hBState]
cp a, 1
jp z, ProfileHandleB
; Directions?
ldh a, [hUpState]
cp a, 1
jp z, ProfileHandleUp
cp a, 16
jp c, .d2
ldh a, [hFrameCtr]
and 3
cp a, 3
jp z, ProfileHandleUp
.d2
ldh a, [hDownState]
cp a, 1
jp z, ProfileHandleDown
cp a, 16
jp c, .l2
ldh a, [hFrameCtr]
and 3
cp a, 3
jp z, ProfileHandleDown
.l2
ldh a, [hLeftState]
cp a, 1
jp z, ProfileHandleLeft
cp a, 16
jp c, .r2
ldh a, [hLeftState]
and 3
cp a, 3
jp z, ProfileHandleLeft
.r2
ldh a, [hRightState]
cp a, 1
jp z, ProfileHandleRight
cp a, 16
ret c
ldh a, [hRightState]
and 3
cp a, 3
ret nz
jp ProfileHandleRight
ret
.eventLoopSettings
; A/Start?
ldh a, [hAState]
cp a, 1
jp z, SettingsHandleA
ldh a, [hStartState]
cp a, 1
jp z, SettingsHandleA
; B?
ldh a, [hBState]
cp a, 1
jp z, SettingsHandleB
; Directions?
ldh a, [hUpState]
cp a, 1
jp z, SettingsHandleUp
cp a, 16
jp c, .d1
ldh a, [hFrameCtr]
and 3
cp a, 3
jp z, SettingsHandleUp
.d1
ldh a, [hDownState]
cp a, 1
jp z, SettingsHandleDown
cp a, 16
jp c, .l1
ldh a, [hFrameCtr]
and 3
cp a, 3
jp z, SettingsHandleDown
.l1
ldh a, [hLeftState]
cp a, 1
jp z, SettingsHandleLeft
cp a, 16
jp c, .r1
ldh a, [hLeftState]
and 3
cp a, 3
jp z, SettingsHandleLeft
.r1
ldh a, [hRightState]
cp a, 1
jp z, SettingsHandleRight
cp a, 16
ret c
ldh a, [hRightState]
and 3
cp a, 3
ret nz
jp SettingsHandleRight
.eventLoopRecords
; B?
ldh a, [hBState]
cp a, 1
jp z, .quitrecords
; L/R?
ldh a, [hLeftState]
cp a, 1
jp z, RecordsHandleLeft
ldh a, [hRightState]
cp a, 1
jp z, RecordsHandleRight
; Select
ldh a, [hSelectState]
cp a, 255 ; Max hold duraction
jp z, RecordsHandleSelect
ld a, [wScoreFlipTimer]
inc a
ld [wScoreFlipTimer], a
cp a, 180
ret nz
xor a, a
ld [wScoreFlipTimer], a
ld a, [wDisplayingScoreMode]
cpl
ld [wDisplayingScoreMode], a
jp RenderScores
.eventLoopCredits
ldh a, [hAState]
cp a, 1
jp z, .quitcredits
ldh a, [hBState]
cp a, 1
jp z, .quitcredits
ldh a, [hStartState]
cp a, 1
jp z, .quitcredits
ret
.quitcredits
.quitrecords
ld a, TITLE_MAIN
jp SwitchTitleMode
; VBLank handlers for title screen.
TitleVBlankHandlerB:
call ToATTR
; Jump to the correct vblank handler.
ld b, 0
ld a, [wTitleMode]
ld c, a
ld hl, .jumps
add hl, bc
jp hl
.jumps
jp .vblankMain
jp .vblankProfile
jp .vblankSettings
jp .vblankRecords
jp .vblankCredits
.vblankMain
; What is the current option?
DEF option = 0
REPT TITLE_MAIN_OPTIONS
ld hl, TITLE_MAIN_OPTION_BASE+(32*option)
ld a, [wSelected]
cp a, option
jr z, .selected\@
.notselected\@:
ld a, TILE_UNSELECTED
ld [hl], a
jr .done\@
.selected\@:
ld a, TILE_SELECTED
ld [hl], a
.done\@:
DEF option += 1
ENDR
; RNG mode.
ld b, 0
ld a, [wRNGModeState]
add a, a
add a, a
ld c, a
ld hl, sRNGMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_MAIN_RNG
ld bc, 4
call UnsafeMemCopy
; ROT mode.
ld b, 0
ld a, [wRotModeState]
add a, a
add a, a
ld c, a
ld hl, sROTMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_MAIN_ROT
ld bc, 4
call UnsafeMemCopy
; DROP mode.
ld b, 0
ld a, [wDropModeState]
add a, a
add a, a
ld c, a
ld hl, sDROPMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_MAIN_DROP
ld bc, 4
call UnsafeMemCopy
; CURVE mode.
ld b, 0
ld a, [wSpeedCurveState]
add a, a
add a, a
ld c, a
ld hl, sCURVEMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_MAIN_SCURVE
ld bc, 4
call UnsafeMemCopy
; HIG mode.
ld a, [wSpeedCurveState]
cp a, SCURVE_DEAT
jr z, .disabled
cp a, SCURVE_SHIR
jr z, .disabled
xor a, a
ld b, a
ld a, [wAlways20GState]
add a, a
add a, a
ld c, a
ld hl, sHIGMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_MAIN_HIG
ld bc, 4
call UnsafeMemCopy
jr .profile
.disabled
ld de, sDisabled
ld hl, TITLE_MAIN_HIG
ld bc, 4
call UnsafeMemCopy
; PROFILE name.
.profile
ld de, wProfileName
ld hl, TITLE_MAIN_PROFILE
ld bc, 3
call UnsafeMemCopy
; START level.
jp DrawSpeedMain
.vblankProfile
; What is the current option?
DEF option = 0
REPT TITLE_PROFILE_OPTIONS
ld hl, TITLE_PROFILE_OPTION_BASE+(32*option)
ld a, [wSelected]
cp a, option
jr z, .selected\@
.notselected\@:
ld a, TILE_UNSELECTED
ld [hl], a
jr .done\@
.selected\@:
ld a, TILE_SELECTED
ld [hl], a
.done\@:
DEF option += 1
ENDR
; Which profile.
ld a, [rLastProfile]
add a, "0"
ld hl, TITLE_PROFILE_INDEX
ld [hl], a
; Name.
ld a, [wProfileName+0]
ld hl, TITLE_PROFILE_NAME_0
ld [hl], a
ld a, [wProfileName+1]
ld hl, TITLE_PROFILE_NAME_1
ld [hl], a
ld a, [wProfileName+2]
ld hl, TITLE_PROFILE_NAME_2
ld [hl], a
.buttons
ld b, 0
ld a, [wSwapABState]
add a, a
add a, a
ld c, a
ld hl, sBUTTONSMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_PROFILE_BUTTONS
ld bc, 4
call UnsafeMemCopy
.filter
ld b, 0
ldh a, [hFilterMode]
add a, a
add a, a
ld c, a
ld hl, sFilterMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_PROFILE_FILTER
ld bc, 4
call UnsafeMemCopy
; Tetry!
ld a, [wSelected]
ld hl, sTetryProfileNumber
ld bc, 64
: or a, a
jr z, .donetetry2
dec a
add hl, bc
jr :-
.donetetry2
ld d, h
ld e, l
ld hl, TITLE_PROFILE_TETRY
ld bc, 16
call SafeMemCopy
ld hl, TITLE_PROFILE_TETRY+(1*32)
ld bc, 16
call SafeMemCopy
ld hl, TITLE_PROFILE_TETRY+(2*32)
ld bc, 16
call SafeMemCopy
ld hl, TITLE_PROFILE_TETRY+(3*32)
ld bc, 16
jp SafeMemCopy
.vblankSettings
; What is the current option?
DEF option = 0
REPT TITLE_SETTINGS_OPTIONS
ld hl, TITLE_SETTINGS_OPTION_BASE+(32*option)
ld a, [wSelected]
cp a, option
jr z, .selected\@
.notselected\@:
ld a, TILE_UNSELECTED
ld [hl], a
jr .done\@
.selected\@:
ld a, TILE_SELECTED
ld [hl], a
.done\@:
DEF option += 1
ENDR
; RNG mode.
ld b, 0
ld a, [wRNGModeState]
add a, a
add a, a
ld c, a
ld hl, sRNGMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_SETTINGS_RNG
ld bc, 4
call UnsafeMemCopy
; ROT mode.
ld b, 0
ld a, [wRotModeState]
add a, a
add a, a
ld c, a
ld hl, sROTMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_SETTINGS_ROT
ld bc, 4
call UnsafeMemCopy
; DROP mode.
ld b, 0
ld a, [wDropModeState]
add a, a
add a, a
ld c, a
ld hl, sDROPMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_SETTINGS_DROP
ld bc, 4
call UnsafeMemCopy
; CURVE mode.
ld b, 0
ld a, [wSpeedCurveState]
add a, a
add a, a
ld c, a
ld hl, sCURVEMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_SETTINGS_SCURVE
ld bc, 4
call UnsafeMemCopy
; HIG mode.
ld a, [wSpeedCurveState]
cp a, SCURVE_DEAT
jr z, .disabled1
cp a, SCURVE_SHIR
jr z, .disabled1
xor a, a
ld b, a
ld a, [wAlways20GState]
add a, a
add a, a
ld c, a
ld hl, sHIGMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_SETTINGS_HIG
ld bc, 4
call UnsafeMemCopy
jr .start
.disabled1
ld de, sDisabled
ld hl, TITLE_SETTINGS_HIG
ld bc, 4
call UnsafeMemCopy
; START level.
.start
call DrawSpeedSettings
; Tetry!
ld a, [wSelected]
ld hl, sTetryRNG
ld bc, 64
: or a, a
jr z, .donetetry1
dec a
add hl, bc
jr :-
.donetetry1
ld d, h
ld e, l
ld hl, TITLE_SETTINGS_TETRY
ld bc, 16
call SafeMemCopy
ld hl, TITLE_SETTINGS_TETRY+(1*32)
ld bc, 16
call SafeMemCopy
ld hl, TITLE_SETTINGS_TETRY+(2*32)
ld bc, 16
call SafeMemCopy
ld hl, TITLE_SETTINGS_TETRY+(3*32)
ld bc, 16
jp SafeMemCopy
.vblankRecords
ld hl, TITLE_RECORDS_RESET_LOC
ld b, TITLE_RECORDS_RESET_BASE
ld [hl], b
ldh a, [hSelectState]
or a, a
ret z
inc b
ld [hl], b
cp a, 30
ret c
inc b
ld [hl], b
cp a, 60
ret c
inc b
ld [hl], b
cp a, 90
ret c
inc b
ld [hl], b
cp a, 120
ret c
inc b
ld [hl], b
cp a, 150
ret c
inc b
ld [hl], b
cp a, 180
ret c
inc b
ld [hl], b
cp a, 210
ret c
inc b
ld [hl], b
cp a, 240
ret c
inc b
ld [hl], b
ret
.vblankCredits
ret
MainHandleA:
ld a, [wSelected]
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 SwitchToGameplay
jp SwitchToGameplayBig
jp .toprofile
jp .tosettings
jp .torecords
jp .tocredits
.tosettings
ld a, TITLE_SETTINGS
jp SwitchTitleMode
.tocredits
ld a, TITLE_CREDITS
jp SwitchTitleMode
.toprofile
ld a, TITLE_PROFILE
jp SwitchTitleMode
.torecords
ld a, TITLE_RECORDS
jp SwitchTitleMode
MainHandleUp:
ld a, [wSelected]
or a, a
jr z, :+
dec a
ld [wSelected], a
ret
: ld a, TITLE_MAIN_OPTIONS-1
ld [wSelected], a
ret
MainHandleDown:
ld a, [wSelected]
cp a, TITLE_MAIN_OPTIONS-1
jr z, :+
inc a
ld [wSelected], a
ret
: xor a, a
ld [wSelected], a
ret
SettingsHandleA:
ld a, [wSelected]
cp a, TITLE_SETTINGS_SEL_BACK
jp nz, SettingsHandleRight
ld a, TITLE_MAIN
jp SwitchTitleMode
ProfileHandleB:
SettingsHandleB:
ld a, TITLE_MAIN
jp SwitchTitleMode
SettingsHandleDown:
ld a, [wSelected]
cp a, TITLE_SETTINGS_OPTIONS-1
jr z, :+
inc a
ld [wSelected], a
ret
: xor a, a
ld [wSelected], a
ret
SettingsHandleUp:
ld a, [wSelected]
or a, a
jr z, :+
dec a
ld [wSelected], a
ret
: ld a, TITLE_SETTINGS_OPTIONS-1
ld [wSelected], a
ret
SettingsHandleLeft:
ld a, [wSelected]
cp a, TITLE_SETTINGS_SEL_BACK
ret z
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 .rng
jp .rot
jp .drop
jp .curve
jp .hig
jp DecrementLevel
no_jump
.rng
ld a, [wRNGModeState]
or a, a
jr z, :+
dec a
ld [wRNGModeState], a
ld [rRNGModeState], a
ret
: ld a, RNG_MODE_COUNT-1
ld [wRNGModeState], a
ld [rRNGModeState], a
ret
.rot
ld a, [wRotModeState]
or a, a
jr z, :+
dec a
ld [wRotModeState], a
ld [rRotModeState], a
ret
: ld a, ROT_MODE_COUNT-1
ld [wRotModeState], a
ld [rRotModeState], a
ret
.drop
ld a, [wDropModeState]
or a, a
jr z, :+
dec a
ld [wDropModeState], a
ld [rDropModeState], a
ret
: ld a, DROP_MODE_COUNT-1
ld [wDropModeState], a
ld [rDropModeState], a
ret
.curve
ld a, [wSpeedCurveState]
or a, a
jr z, :+
dec a
ld [wSpeedCurveState], a
ld [rSpeedCurveState], a
call InitSpeedCurve
ret
: ld a, SCURVE_COUNT-1
ld [wSpeedCurveState], a
ld [rSpeedCurveState], a
call InitSpeedCurve
ret
.hig
ld a, [wAlways20GState]
or a, a
jr z, :+
dec a
ld [wAlways20GState], a
ld [rAlways20GState], a
ret
: ld a, HIG_MODE_COUNT-1
ld [wAlways20GState], a
ld [rAlways20GState], a
ret
SettingsHandleRight:
ld a, [wSelected]
cp a, TITLE_SETTINGS_SEL_BACK
ret z
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 .rng
jp .rot
jp .drop
jp .curve
jp .hig
jp IncrementLevel
no_jump
.rng
ld a, [wRNGModeState]
cp a, RNG_MODE_COUNT-1
jr z, :+
inc a
ld [wRNGModeState], a
ld [rRNGModeState], a
ret
: xor a, a
ld [wRNGModeState], a
ld [rRNGModeState], a
ret
.rot
ld a, [wRotModeState]
cp a, ROT_MODE_COUNT-1
jr z, :+
inc a
ld [wRotModeState], a
ld [rRotModeState], a
ret
: xor a, a
ld [wRotModeState], a
ld [rRotModeState], a
ret
.drop
ld a, [wDropModeState]
cp a, DROP_MODE_COUNT-1
jr z, :+
inc a
ld [wDropModeState], a
ld [rDropModeState], a
ret
: xor a, a
ld [wDropModeState], a
ld [rDropModeState], a
ret
.curve
ld a, [wSpeedCurveState]
cp a, SCURVE_COUNT-1
jr z, :+
inc a
ld [wSpeedCurveState], a
ld [rSpeedCurveState], a
call InitSpeedCurve
ret
: xor a, a
ld [wSpeedCurveState], a
ld [rSpeedCurveState], a
call InitSpeedCurve
ret
.hig
ld a, [wAlways20GState]
cp a, HIG_MODE_COUNT-1
jr z, :+
inc a
ld [wAlways20GState], a
ld [rAlways20GState], a
ret
: xor a, a
ld [wAlways20GState], a
ld [rAlways20GState], a
ret
ProfileHandleA:
ld a, [wSelected]
cp a, TITLE_PROFILE_SEL_BACK
ld b, a
ld a, TITLE_MAIN
jp z, SwitchTitleMode
ld a, b
cp a, TITLE_PROFILE_SEL_RESET
jp z, ResetProfile
jp ProfileHandleRight
ProfileHandleRight:
ld a, [wSelected]
cp a, TITLE_PROFILE_SEL_BACK
ret z
cp a, TITLE_PROFILE_SEL_RESET
ret z
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 .idx
jp .l0
jp .l1
jp .l2
jp .buttons
jp .filter
no_jump
no_jump
.idx
ld a, [rLastProfile]
inc a
cp a, PROFILE_COUNT
jr nz, .doit
xor a, a
.doit
jp ChangeProfile
.l0
ld a, [wProfileName+0]
inc a
cp a, "Z"+1
jr nz, .doit1
ld a, "0"-1
.doit1
ld [wProfileName+0], a
ld [rProfileName+0], a
ret
.l1
ld a, [wProfileName+1]
inc a
cp a, "Z"+1
jr nz, .doit2
ld a, "0"-1
.doit2
ld [wProfileName+1], a
ld [rProfileName+1], a
ret
.l2
ld a, [wProfileName+2]
inc a
cp a, "Z"+1
jr nz, .doit3
ld a, "0"-1
.doit3
ld [wProfileName+2], a
ld [rProfileName+2], a
ret
.buttons
ld a, [wSwapABState]
cp a, BUTTON_MODE_COUNT-1
jr z, :+
inc a
ld [wSwapABState], a
ld [rSwapABState], a
ret
: xor a, a
ld [wSwapABState], a
ld [rSwapABState], a
ret
.filter
ldh a, [hFilterMode]
cp a, FILTER_MODE_COUNT-1
jr z, :+
inc a
ldh [hFilterMode], a
ld [rFilterMode], a
ret
: xor a, a
ldh [hFilterMode], a
ld [rFilterMode], a
ret
ProfileHandleLeft:
ld a, [wSelected]
cp a, TITLE_PROFILE_SEL_BACK
ret z
cp a, TITLE_PROFILE_SEL_RESET
ret z
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 .idx
jp .l0
jp .l1
jp .l2
jp .buttons
jp .filter
no_jump
no_jump
.idx
ld a, [rLastProfile]
dec a
cp a, $FF
jr nz, .doit
ld a, PROFILE_COUNT-1
.doit
jp ChangeProfile
.l0
ld a, [wProfileName+0]
dec a
cp a, "0"-2
jr nz, .doit1
ld a, "Z"
.doit1
ld [wProfileName+0], a
ld [rProfileName+0], a
ret
.l1
ld a, [wProfileName+1]
dec a
cp a, "0"-2
jr nz, .doit2
ld a, "Z"
.doit2
ld [wProfileName+1], a
ld [rProfileName+1], a
ret
.l2
ld a, [wProfileName+2]
dec a
cp a, "0"-2
jr nz, .doit3
ld a, "Z"
.doit3
ld [wProfileName+2], a
ld [rProfileName+2], a
ret
.buttons
ld a, [wSwapABState]
or a, a
jr z, :+
dec a
ld [wSwapABState], a
ld [rSwapABState], a
ret
: ld a, BUTTON_MODE_COUNT-1
ld [wSwapABState], a
ld [rSwapABState], a
ret
.filter
ldh a, [hFilterMode]
or a, a
jr z, :+
dec a
ldh [hFilterMode], a
ld [rFilterMode], a
ret
: ld a, FILTER_MODE_COUNT-1
ldh [hFilterMode], a
ld [rFilterMode], a
ret
ProfileHandleDown:
ld a, [wSelected]
cp a, TITLE_PROFILE_OPTIONS-1
jr z, :+
inc a
ld [wSelected], a
ret
: xor a, a
ld [wSelected], a
ret
ProfileHandleUp:
ld a, [wSelected]
or a, a
jr z, :+
dec a
ld [wSelected], a
ret
: ld a, TITLE_PROFILE_OPTIONS-1
ld [wSelected], a
ret
; Decrements start level.
DecrementLevel:
; Decrement
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
ld bc, -SCURVE_ENTRY_SIZE
add hl, bc
ld a, l
ldh [hStartSpeed], a
ld a, h
ldh [hStartSpeed+1], a
call PersistLevel
jp CheckLevelRange
; Increments start level.
IncrementLevel:
; Increment
ldh a, [hStartSpeed]
ld l, a
ldh a, [hStartSpeed+1]
ld h, a
ld bc, SCURVE_ENTRY_SIZE
add hl, bc
ld a, l
ldh [hStartSpeed], a
ld a, h
ldh [hStartSpeed+1], a
call PersistLevel
jp CheckLevelRange
; Wipes the start level upon selecting a new speed curve.
InitSpeedCurve:
ld a, [wSpeedCurveState]
call GetStart
ld a, l
ldh [hStartSpeed], a
ld a, h
ldh [hStartSpeed+1], a
jp PersistLevel
; Gets the end of a speed curve.
GetEnd:
ld a, [wSpeedCurveState]
cp a, SCURVE_DMGT
jr nz, :+
ld bc, sDMGTSpeedCurveEnd
ret
: cp a, SCURVE_TGM1
jr nz, :+
ld bc, sTGM1SpeedCurveEnd
ret
: cp a, SCURVE_TGM3
jr nz, :+
ld bc, sTGM3SpeedCurveEnd
ret
: cp a, SCURVE_DEAT
jr nz, :+
ld bc, sDEATSpeedCurveEnd
ret
: cp a, SCURVE_SHIR
jr nz, :+
ld bc, sSHIRSpeedCurveEnd
ret
: cp a, SCURVE_CHIL
jr nz, :+
ld bc, sCHILSpeedCurveEnd
ret
: ld bc, sMYCOSpeedCurveEnd
ret
; Gets the beginning of a speed curve.
GetStart:
ld a, [wSpeedCurveState]
cp a, SCURVE_DMGT
jr nz, :+
ld hl, sDMGTSpeedCurve
ret
: cp a, SCURVE_TGM1
jr nz, :+
ld hl, sTGM1SpeedCurve
ret
: cp a, SCURVE_TGM3
jr nz, :+
ld hl, sTGM3SpeedCurve
ret
: cp a, SCURVE_DEAT
jr nz, :+
ld hl, sDEATSpeedCurve
ret
: cp a, SCURVE_SHIR
jr nz, :+
ld hl, sSHIRSpeedCurve
ret
: cp a, SCURVE_CHIL
jr nz, :+
ld hl, sCHILSpeedCurve
ret
: ld hl, sMYCOSpeedCurve
ret
; Make sure we don't overflow the level range.
CheckLevelRange:
; At end?
call GetEnd
ldh a, [hStartSpeed]
cp a, c
jr nz, .notatend
ldh a, [hStartSpeed+1]
cp a, b
jr nz, .notatend
call GetStart
ld a, l
ldh [hStartSpeed], a
ld a, h
ldh [hStartSpeed+1], a
call PersistLevel
.notatend
ld de, -SCURVE_ENTRY_SIZE
call GetStart
add hl, de
ldh a, [hStartSpeed]
cp a, l
jr nz, .notatstart
ldh a, [hStartSpeed+1]
cp a, h
jr nz, .notatstart
call GetEnd
ld h, b
ld l, c
add hl, de
ld a, l
ldh [hStartSpeed], a
ld a, h
ldh [hStartSpeed+1], a
call PersistLevel
.notatstart
ret
RecordsHandleLeft:
xor a, a
ldh [hSelectState], a
ld [wDisplayingScoreMode], a
ld [wScoreFlipTimer], a
ld a, [wSelected]
or a, a
jr z, :+
dec a
ld [wSelected], a
jp RenderScores
: ld a, SCURVE_COUNT-1
ld [wSelected], a
jp RenderScores
RecordsHandleRight:
xor a, a
ldh [hSelectState], a
ld [wDisplayingScoreMode], a
ld [wScoreFlipTimer], a
ld a, [wSelected]
cp a, SCURVE_COUNT-1
jr z, :+
inc a
ld [wSelected], a
jp RenderScores
: xor a, a
ld [wSelected], a
jp RenderScores
RecordsHandleSelect:
xor a, a
ldh [hSelectState], a
call ResetScores
jp RenderScores
RenderScores:
; Draw the mode.
: ld b, 0
ld a, [wSelected]
add a, a
add a, a
ld c, a
ld hl, sCURVEMode
add hl, bc
ld d, h
ld e, l
ld hl, TITLE_RECORDS_MODE
ld bc, 4
call SafeMemCopy
; Get the correct speed curve.
ld a, [wSelected]
call InitTargetHSTable
; Start of table is at HL. Put it in DE.
ld d, h
ld e, l
ld hl, TITLE_RECORDS_SCORE_BASE+4
REPT 10
ld a, [wDisplayingScoreMode]
cp a, $FF
jr z, .level\@
; Render score.
.score\@
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
; Go render the name.
jr .name\@
; Jump forward to level in the score.
.level\@
push hl
ld h, d
ld l, e
ld bc, 16
add hl, bc
ld d, h
ld e, l
pop hl
; Render it.
ld a, "L"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, "V"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, "L"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, 115
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, "0"
ld b, a
wait_vram
ld [hl], b
inc hl
; And jump back to the name.
push hl
ld h, d
ld l, e
ld bc, -12
add hl, bc
ld d, h
ld e, l
pop hl
.name\@
; Jump back to Name.
ld bc, -12
add hl, bc
; Render name.
ld a, [de]
inc de
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
ld b, a
wait_vram
ld [hl], b
inc hl
; Jump to tells.
ld bc, 10
add hl, bc
; Render them.
ld a, [de]
inc de
cp a, GRADE_NONE
jr nz, .grade\@
.nograde\@
ld a, 197
ld b, a
wait_vram
ld [hl], b
inc hl
jr .postgrade\@
.grade\@
add a, TITLE_RECORDS_GRADE_BASE
ld b, a
wait_vram
ld [hl], b
inc hl
.postgrade\@
ld a, [de]
inc de
add a, TITLE_RECORDS_RNG_BASE
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, TITLE_RECORDS_ROT_BASE
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, TITLE_RECORDS_DROP_BASE
ld b, a
wait_vram
ld [hl], b
inc hl
ld a, [de]
inc de
add a, TITLE_RECORDS_HIG_BASE
ld b, a
wait_vram
ld [hl], b
inc hl
; Jump to next line.
push hl
ld h, d
ld l, e
ld bc, 16
add hl, bc
ld d, h
ld e, l
pop hl
ld bc, 18
add hl, bc
ENDR
ret
ENDC