Song Selection Screen
Building a menu system to select songs. The structure for multiple songs, ready to expand.
Phase 2 begins. The complete game from Phase 1 becomes the foundation for something bigger.
This unit adds a song selection menu between the title screen and gameplay. Currently there’s only one song to choose, but the infrastructure is ready for more. When you add songs in future units, they’ll appear in this menu automatically.
Run It
Assemble and run:
acme -f cbm -o symphony.prg symphony.asm

Press fire on the title screen to reach the song selection menu. Select a song and press fire again to play.
The New Game Flow
The game now has five states instead of four:
TITLE → MENU → PLAYING → RESULTS/GAMEOVER → MENU
After completing or failing a song, you return to the menu—not the title. This feels more like a real game: pick a song, play it, try another.
New State Constant
We add STATE_MENU to our state machine:
STATE_TITLE = 0 ; Title screen
STATE_MENU = 1 ; Song selection menu (NEW!)
STATE_PLAYING = 2 ; Gameplay
STATE_RESULTS = 3 ; Success results
STATE_GAMEOVER = 4 ; Failure game over
The state numbers shifted. STATE_PLAYING is now 2 instead of 1. This matters for the main loop dispatcher.
Menu Variables
Three new zero-page variables track menu state:
cursor_pos = $10 ; Which song is highlighted
key_delay_count = $11 ; Prevents key repeat spam
selected_song = $12 ; Which song to play
The key delay prevents the cursor from flying through options when holding up/down. Without it, the menu would be unusable.
Drawing the Menu
The show_menu routine clears the screen and displays the song list:
show_menu:
; Clear screen
ldx #0
lda #CHAR_SPACE
clear_menu:
sta SCREEN,x
sta SCREEN+$100,x
sta SCREEN+$200,x
sta SCREEN+$2E8,x
inx
bne clear_menu
; Initialise cursor
lda #0
sta cursor_pos
sta key_delay_count
; Draw menu title
ldx #0
draw_menu_title:
lda menu_title,x
beq draw_menu_title_done
sta SCREEN + (4 * 40) + 12,x
lda #TITLE_COL
sta COLRAM + (4 * 40) + 12,x
inx
jmp draw_menu_title
draw_menu_title_done:
; Draw song list
jsr draw_song_list
rts
The cursor starts at position 0 (the first song). With only one song currently, that’s the only option.
Cursor Movement
The update_menu routine handles input:
update_menu:
; Handle key delay
lda key_delay_count
beq menu_check_input
dec key_delay_count
jmp menu_check_fire
menu_check_input:
; Check joystick up
lda CIA1_PRA
and #$01 ; Bit 0 = up
beq menu_up_pressed
; Check joystick down
lda CIA1_PRA
and #$02 ; Bit 1 = down
beq menu_down_pressed
jmp menu_check_fire
Key repeat delay works like this:
- If
key_delay_countis non-zero, skip input checking and decrement - When input detected, set
key_delay_counttoKEY_DELAY(10 frames) - This means roughly 5 cursor movements per second maximum
Sound Feedback
Two new sounds make the menu feel responsive:
MENU_MOVE_FREQ = $10 ; Lower pitch for cursor move
MENU_MOVE_WAVE = $11 ; Triangle (soft)
MENU_SELECT_FREQ = $18 ; Higher pitch for selection
MENU_SELECT_WAVE = $41 ; Pulse (click)
The move sound is soft and low. The select sound is brighter and sharper. This audio distinction helps users understand what action they just took.
Transitioning to Game
When fire is pressed, we store the selection and start the game:
menu_fire_pressed:
lda #$FF
sta CIA1_PRA
; Play select sound
jsr play_menu_select
; Store selected song
lda cursor_pos
sta selected_song
; Transition to game
jsr transition_to_game
rts
transition_to_game:
; Set up the selected song
; In future units, this will load different song data
; Initialise game
jsr init_game
lda #STATE_PLAYING
sta game_state
rts
Right now transition_to_game always loads the same song. In Unit 18, we’ll use selected_song to choose which song data to use.
Returning to Menu
After completing or failing, pressing fire now returns to the menu:
update_results:
; Check for fire to return to menu
lda CIA1_PRA
and #$10
beq results_fire
; ...
results_fire:
; ...
; Return to menu (not title)
jsr show_menu
lda #STATE_MENU
sta game_state
rts
This small change makes a big difference. Players can immediately try another song without going through the title screen.
Song Name Display
During gameplay, the selected song’s name appears in the HUD:
; Draw song name on gameplay screen
ldx #0
draw_song_name:
lda selected_song
; For now only song 0
lda song1_name,x
beq draw_song_name_done
sta SCREEN + 28,x
lda #11
sta COLRAM + 28,x
inx
jmp draw_song_name
draw_song_name_done:
When we add more songs, this will display which one is playing.
The Complete Code
; ============================================================================
; SID SYMPHONY - Unit 17: Song Selection Screen
; ============================================================================
; Adding a menu system to select songs. Currently only one song, but the
; structure is ready for multiple songs in the next unit.
;
; New concepts: Menu state, cursor tracking, key repeat delay
;
; Controls: Z = Track 1, X = Track 2, C = Track 3
; Up/Down = Menu navigation
; Fire/Space = Start game / Select
; ============================================================================
; ============================================================================
; CUSTOMISATION SECTION
; ============================================================================
; Screenshot mode - set to 1 to skip title and show menu immediately
; Used for automated screenshot capture. Override with: acme -DSCREENSHOT_MODE=1
!ifndef SCREENSHOT_MODE { SCREENSHOT_MODE = 0 }
; SID Voice Settings (for note playback)
VOICE1_WAVE = $21 ; Sawtooth for track 1
VOICE2_WAVE = $41 ; Pulse for track 2
VOICE3_WAVE = $11 ; Triangle for track 3
VOICE1_FREQ = $1C
VOICE2_FREQ = $0E
VOICE3_FREQ = $07
VOICE_AD = $09 ; Attack=0, Decay=9
VOICE_SR = $00 ; Sustain=0, Release=0
PULSE_WIDTH = $08
; Perfect hit sound - bright and satisfying
PERFECT_SFX_FREQ = $30 ; Higher pitch
PERFECT_SFX_WAVE = $21 ; Sawtooth (bright)
PERFECT_SFX_AD = $08 ; Fast attack, medium decay
PERFECT_SFX_SR = $00 ; No sustain
; Good hit sound - positive but lesser
GOOD_SFX_FREQ = $20 ; Lower pitch than perfect
GOOD_SFX_WAVE = $11 ; Triangle (softer)
GOOD_SFX_AD = $0A ; Slightly slower decay
GOOD_SFX_SR = $00 ; No sustain
; Miss sound settings - harsh buzz
MISS_FREQ = $08
MISS_WAVE = $81 ; Noise
MISS_AD = $00 ; Instant attack
MISS_SR = $A0 ; Quick sustain, fast release
; Menu sound settings
MENU_SELECT_FREQ = $18 ; Menu click pitch
MENU_SELECT_WAVE = $41 ; Pulse for click
MENU_SELECT_AD = $00 ; Instant
MENU_SELECT_SR = $80 ; Very short
MENU_MOVE_FREQ = $10 ; Lower pitch for cursor move
MENU_MOVE_WAVE = $11 ; Triangle (soft)
MENU_MOVE_AD = $00 ; Instant
MENU_MOVE_SR = $40 ; Very short
; Visual Settings
BORDER_COL = 0
BG_COL = 0
TRACK1_NOTE_COL = 10 ; Light red for high track
TRACK2_NOTE_COL = 13 ; Light green for mid track
TRACK3_NOTE_COL = 14 ; Light blue for low track
TRACK_LINE_COL = 11 ; Grey for track lines
HIT_ZONE_COL = 7 ; Yellow for hit zone
HIT_COL = 1
PERFECT_COL = 1 ; White flash for perfect
GOOD_COL = 7 ; Yellow flash for good
MISS_COL = 2 ; Red flash for miss
HEALTH_COL = 5 ; Green for health bar
PROGRESS_COL = 3 ; Cyan for progress bar
COMBO_COL = 13 ; Light green for combo
; Title screen colours
TITLE_COL = 1 ; White for title
SUBTITLE_COL = 11 ; Grey for subtitle
MENU_COL = 7 ; Yellow for menu items
CURSOR_COL = 1 ; White for cursor
; ============================================================================
; SCORING SETTINGS (BALANCED)
; ============================================================================
PERFECT_SCORE = 100 ; Perfect hit value
GOOD_SCORE = 50 ; Good hit value
; ============================================================================
; COMBO SETTINGS (BALANCED)
; ============================================================================
COMBO_TIER_2 = 10 ; 2x multiplier at 10 hits
COMBO_TIER_3 = 25 ; 3x multiplier at 25 hits
COMBO_TIER_4 = 50 ; 4x multiplier at 50 hits
; ============================================================================
; HEALTH SETTINGS (BALANCED FOR FAIRNESS)
; ============================================================================
HEALTH_MAX = 64 ; Maximum health
HEALTH_START = 32 ; Start at half health
HEALTH_PERFECT = 4 ; Gain 4 for perfect
HEALTH_GOOD = 2 ; Gain 2 for good
HEALTH_MISS = 8 ; Lose 8 for miss (forgiving)
; ============================================================================
; HIT DETECTION SETTINGS (BALANCED TIMING WINDOWS)
; ============================================================================
HIT_ZONE_MIN = 2 ; Earliest hit column
HIT_ZONE_MAX = 5 ; Latest hit column
HIT_ZONE_CENTRE = 3 ; Perfect timing column
; ============================================================================
; SONG SETTINGS
; ============================================================================
SONG_LENGTH = 64 ; 64 beats at 120 BPM = ~32 seconds
PROGRESS_WIDTH = 16 ; Progress bar width
; ============================================================================
; MENU SETTINGS
; ============================================================================
NUM_SONGS = 1 ; Currently only 1 song
KEY_DELAY = 10 ; Frames between key repeats
; ============================================================================
; GAME STATES
; ============================================================================
STATE_TITLE = 0 ; Title screen
STATE_MENU = 1 ; Song selection menu (NEW!)
STATE_PLAYING = 2 ; Gameplay
STATE_RESULTS = 3 ; Success results
STATE_GAMEOVER = 4 ; Failure game over
; ============================================================================
; MEMORY MAP
; ============================================================================
SCREEN = $0400
COLRAM = $D800
BORDER = $D020
BGCOL = $D021
CHARPTR = $D018
CHARSET = $3000
; SID registers
SID = $D400
SID_V1_FREQ_LO = $D400
SID_V1_FREQ_HI = $D401
SID_V1_PWHI = $D403
SID_V1_CTRL = $D404
SID_V1_AD = $D405
SID_V1_SR = $D406
SID_V2_FREQ_LO = $D407
SID_V2_FREQ_HI = $D408
SID_V2_PWHI = $D40A
SID_V2_CTRL = $D40B
SID_V2_AD = $D40C
SID_V2_SR = $D40D
SID_V3_FREQ_LO = $D40E
SID_V3_FREQ_HI = $D40F
SID_V3_PWHI = $D411
SID_V3_CTRL = $D412
SID_V3_AD = $D413
SID_V3_SR = $D414
SID_VOLUME = $D418
; CIA keyboard and joystick
CIA1_PRA = $DC00
CIA1_PRB = $DC01
; Track positions (balanced spacing)
TRACK1_ROW = 8 ; High track
TRACK2_ROW = 12 ; Mid track
TRACK3_ROW = 16 ; Low track
; HUD positions
HEALTH_ROW = 23 ; Health bar row
PROGRESS_ROW = 24 ; Progress bar row
; Combo display position
COMBO_ROW = 2 ; Combo display row
; Hit zone
HIT_ZONE_COLUMN = 3 ; Where notes are hit
; Custom character codes
CHAR_NOTE = 128
CHAR_TRACK = 129
CHAR_HITZONE = 130
CHAR_SPACE = 32
CHAR_BAR_FULL = 131
CHAR_BAR_EMPTY = 132
CHAR_CURSOR = 62 ; > character for menu cursor
; Note settings
MAX_NOTES = 8 ; Maximum simultaneous notes
NOTE_SPAWN_COL = 37 ; Where notes appear
; Timing
FRAMES_PER_BEAT = 25 ; 50fps / 25 = 2 beats per second = 120 BPM
END_DELAY_FRAMES = 75 ; 1.5 seconds after song ends
; Zero page
ZP_PTR = $FB
ZP_PTR_HI = $FC
; Variables
frame_count = $02
beat_count = $03
song_pos = $04
song_pos_hi = $05
temp_track = $06
key_pressed = $07
hit_quality = $08
border_flash = $09
miss_track = $0A
game_state = $0B
hit_note_freq = $0C
song_beat = $0D
song_ended = $0E
end_delay = $0F
cursor_pos = $10 ; Menu cursor position (NEW!)
key_delay_count = $11 ; Key repeat delay counter (NEW!)
selected_song = $12 ; Which song to play (NEW!)
; ----------------------------------------------------------------------------
; BASIC Stub
; ----------------------------------------------------------------------------
* = $0801
!byte $0C, $08
!byte $0A, $00
!byte $9E
!text "2064"
!byte $00
!byte $00, $00
; ----------------------------------------------------------------------------
; Main Program
; ----------------------------------------------------------------------------
* = $0810
start:
jsr copy_charset
jsr init_sid
!if SCREENSHOT_MODE = 1 {
; Screenshot mode: skip title, go to menu
jsr show_menu
lda #STATE_MENU
sta game_state
} else {
; Normal mode: show title screen
jsr show_title
lda #STATE_TITLE
sta game_state
}
main_loop:
lda #$FF
wait_raster:
cmp $D012
bne wait_raster
lda game_state
cmp #STATE_TITLE
beq do_title
cmp #STATE_MENU
beq do_menu
cmp #STATE_PLAYING
beq do_playing
cmp #STATE_RESULTS
beq do_results
jmp do_gameover
do_title:
jsr update_title
jmp main_loop
do_menu:
jsr update_menu
jmp main_loop
do_playing:
jsr update_playing
jmp main_loop
do_results:
jsr update_results
jmp main_loop
do_gameover:
jsr update_gameover
jmp main_loop
; ----------------------------------------------------------------------------
; Show Title Screen
; ----------------------------------------------------------------------------
show_title:
; Clear screen
lda #BORDER_COL
sta BORDER
lda #BG_COL
sta BGCOL
ldx #0
lda #CHAR_SPACE
clear_title:
sta SCREEN,x
sta SCREEN+$100,x
sta SCREEN+$200,x
sta SCREEN+$2E8,x
inx
bne clear_title
; Draw big title "SID SYMPHONY"
ldx #0
draw_title_text:
lda title_big,x
beq draw_title_done
sta SCREEN + (8 * 40) + 14,x
lda #TITLE_COL
sta COLRAM + (8 * 40) + 14,x
inx
jmp draw_title_text
draw_title_done:
; Draw subtitle "A RHYTHM GAME"
ldx #0
draw_subtitle:
lda subtitle_text,x
beq draw_subtitle_done
sta SCREEN + (10 * 40) + 13,x
lda #SUBTITLE_COL
sta COLRAM + (10 * 40) + 13,x
inx
jmp draw_subtitle
draw_subtitle_done:
; Draw controls
ldx #0
draw_controls:
lda controls_text,x
beq draw_controls_done
sta SCREEN + (14 * 40) + 11,x
lda #11
sta COLRAM + (14 * 40) + 11,x
inx
jmp draw_controls
draw_controls_done:
; Draw track info
ldx #0
draw_track_info:
lda track_info,x
beq draw_track_done
sta SCREEN + (16 * 40) + 9,x
lda #11
sta COLRAM + (16 * 40) + 9,x
inx
jmp draw_track_info
draw_track_done:
; Draw "PRESS FIRE TO START"
ldx #0
draw_press_fire:
lda press_fire_text,x
beq draw_press_done
sta SCREEN + (20 * 40) + 10,x
lda #7 ; Yellow
sta COLRAM + (20 * 40) + 10,x
inx
jmp draw_press_fire
draw_press_done:
rts
title_big:
!scr "sid symphony"
!byte 0
subtitle_text:
!scr "a rhythm game"
!byte 0
controls_text:
!scr "controls: z / x / c"
!byte 0
track_info:
!scr "hit notes as they reach"
!byte 0
press_fire_text:
!scr "press fire to start"
!byte 0
; ----------------------------------------------------------------------------
; Update Title State
; ----------------------------------------------------------------------------
update_title:
; Check for fire button (joystick port 2)
lda CIA1_PRA
and #$10 ; Bit 4 = fire
beq title_fire_pressed
; Also check space bar as alternative
lda #$7F
sta CIA1_PRA
lda CIA1_PRB
and #$10 ; Space
beq title_fire_pressed
; No input - stay on title
lda #$FF
sta CIA1_PRA
rts
title_fire_pressed:
lda #$FF
sta CIA1_PRA
; Play menu select sound
jsr play_menu_select
; Go to song selection menu
jsr show_menu
lda #STATE_MENU
sta game_state
rts
; ----------------------------------------------------------------------------
; Show Song Selection Menu
; ----------------------------------------------------------------------------
show_menu:
; Clear screen
ldx #0
lda #CHAR_SPACE
clear_menu:
sta SCREEN,x
sta SCREEN+$100,x
sta SCREEN+$200,x
sta SCREEN+$2E8,x
inx
bne clear_menu
; Initialise cursor
lda #0
sta cursor_pos
sta key_delay_count
; Draw menu title
ldx #0
draw_menu_title:
lda menu_title,x
beq draw_menu_title_done
sta SCREEN + (4 * 40) + 12,x
lda #TITLE_COL
sta COLRAM + (4 * 40) + 12,x
inx
jmp draw_menu_title
draw_menu_title_done:
; Draw instructions
ldx #0
draw_menu_instr:
lda menu_instructions,x
beq draw_menu_instr_done
sta SCREEN + (22 * 40) + 8,x
lda #SUBTITLE_COL
sta COLRAM + (22 * 40) + 8,x
inx
jmp draw_menu_instr
draw_menu_instr_done:
; Draw song list
jsr draw_song_list
rts
menu_title:
!scr "select a song"
!byte 0
menu_instructions:
!scr "up/down to select, fire to play"
!byte 0
; ----------------------------------------------------------------------------
; Draw Song List
; ----------------------------------------------------------------------------
draw_song_list:
; Draw each song entry
; For now, just one song
; Song 1
ldx #0
draw_song1:
lda song1_name,x
beq draw_song1_done
sta SCREEN + (10 * 40) + 14,x
lda #MENU_COL
sta COLRAM + (10 * 40) + 14,x
inx
jmp draw_song1
draw_song1_done:
; Draw cursor at current position
jsr draw_cursor
rts
; Song names
song1_name:
!scr "first steps"
!byte 0
; ----------------------------------------------------------------------------
; Draw Menu Cursor
; ----------------------------------------------------------------------------
draw_cursor:
; Clear all potential cursor positions
lda #CHAR_SPACE
sta SCREEN + (10 * 40) + 12
; (Room for more songs later)
; Draw cursor at current position
lda cursor_pos
asl ; Multiply by 2 (rows per song)
clc
adc #10 ; Start row
tax
; Calculate screen position
; Row X * 40 = screen offset
lda #0
sta ZP_PTR
lda #0
sta ZP_PTR_HI
; Multiply row by 40
cursor_row_mult:
cpx #0
beq cursor_row_done
lda ZP_PTR
clc
adc #40
sta ZP_PTR
lda ZP_PTR_HI
adc #0
sta ZP_PTR_HI
dex
jmp cursor_row_mult
cursor_row_done:
; Add column offset (12)
lda ZP_PTR
clc
adc #12
sta ZP_PTR
lda ZP_PTR_HI
adc #0
sta ZP_PTR_HI
; Add screen base
lda ZP_PTR
clc
adc #<SCREEN
sta ZP_PTR
lda ZP_PTR_HI
adc #>SCREEN
sta ZP_PTR_HI
; Draw cursor character
lda #CHAR_CURSOR
ldy #0
sta (ZP_PTR),y
; Set cursor colour
lda ZP_PTR
sec
sbc #<SCREEN
clc
adc #<COLRAM
sta ZP_PTR
lda ZP_PTR_HI
sbc #>SCREEN
adc #>COLRAM
sta ZP_PTR_HI
lda #CURSOR_COL
sta (ZP_PTR),y
rts
; ----------------------------------------------------------------------------
; Update Menu State
; ----------------------------------------------------------------------------
update_menu:
; Handle key delay
lda key_delay_count
beq menu_check_input
dec key_delay_count
jmp menu_check_fire
menu_check_input:
; Check joystick up (or W key)
lda CIA1_PRA
and #$01 ; Bit 0 = up
beq menu_up_pressed
; Check joystick down (or S key)
lda CIA1_PRA
and #$02 ; Bit 1 = down
beq menu_down_pressed
jmp menu_check_fire
menu_up_pressed:
lda cursor_pos
beq menu_set_delay ; Already at top
dec cursor_pos
jsr play_menu_move
jsr draw_cursor
jmp menu_set_delay
menu_down_pressed:
lda cursor_pos
cmp #NUM_SONGS-1
bcs menu_set_delay ; Already at bottom
inc cursor_pos
jsr play_menu_move
jsr draw_cursor
jmp menu_set_delay
menu_set_delay:
lda #KEY_DELAY
sta key_delay_count
menu_check_fire:
; Check for fire button
lda CIA1_PRA
and #$10
beq menu_fire_pressed
; Check space bar
lda #$7F
sta CIA1_PRA
lda CIA1_PRB
and #$10
beq menu_fire_pressed
lda #$FF
sta CIA1_PRA
rts
menu_fire_pressed:
lda #$FF
sta CIA1_PRA
; Play select sound
jsr play_menu_select
; Store selected song
lda cursor_pos
sta selected_song
; Transition to game
jsr transition_to_game
rts
; ----------------------------------------------------------------------------
; Transition to Game
; ----------------------------------------------------------------------------
transition_to_game:
; Set up the selected song (for now, only song 0)
; In future units, this will load different song data
; Initialise game
jsr init_game
lda #STATE_PLAYING
sta game_state
rts
; ----------------------------------------------------------------------------
; Play Menu Move Sound
; ----------------------------------------------------------------------------
play_menu_move:
lda #0
sta SID_V3_FREQ_LO
lda #MENU_MOVE_FREQ
sta SID_V3_FREQ_HI
lda #$08
sta SID_V3_PWHI
lda #MENU_MOVE_AD
sta SID_V3_AD
lda #MENU_MOVE_SR
sta SID_V3_SR
lda #MENU_MOVE_WAVE
ora #$01 ; Gate on
sta SID_V3_CTRL
rts
; ----------------------------------------------------------------------------
; Play Menu Select Sound
; ----------------------------------------------------------------------------
play_menu_select:
lda #0
sta SID_V3_FREQ_LO
lda #MENU_SELECT_FREQ
sta SID_V3_FREQ_HI
lda #$08
sta SID_V3_PWHI
lda #MENU_SELECT_AD
sta SID_V3_AD
lda #MENU_SELECT_SR
sta SID_V3_SR
lda #MENU_SELECT_WAVE
ora #$01 ; Gate on
sta SID_V3_CTRL
rts
; ----------------------------------------------------------------------------
; Initialize Game (called when starting from menu)
; ----------------------------------------------------------------------------
init_game:
jsr init_screen
jsr init_notes
jsr init_score
jsr init_health
jsr init_combo
jsr init_song
rts
; ----------------------------------------------------------------------------
; Initialize Combo
; ----------------------------------------------------------------------------
init_combo:
lda #0
sta combo
sta max_combo
jsr display_combo
rts
; ----------------------------------------------------------------------------
; Update Playing State
; ----------------------------------------------------------------------------
update_playing:
inc frame_count
lda frame_count
cmp #FRAMES_PER_BEAT
bcc no_new_beat
lda #0
sta frame_count
jsr advance_song
jsr check_spawn_note
no_new_beat:
jsr update_notes
jsr reset_track_colours
jsr update_border_flash
jsr check_keys
jsr check_song_end
rts
; ----------------------------------------------------------------------------
; Update Results State
; ----------------------------------------------------------------------------
update_results:
; Check for fire to return to menu
lda CIA1_PRA
and #$10
beq results_fire
; Also check space bar
lda #$7F
sta CIA1_PRA
lda CIA1_PRB
and #$10
beq results_fire
lda #$FF
sta CIA1_PRA
rts
results_fire:
lda #$FF
sta CIA1_PRA
jsr play_menu_select
; Return to menu (not title)
jsr show_menu
lda #STATE_MENU
sta game_state
rts
; ----------------------------------------------------------------------------
; Update Game Over State
; ----------------------------------------------------------------------------
update_gameover:
; Check for fire to return to menu
lda CIA1_PRA
and #$10
beq gameover_fire
; Also check space bar
lda #$7F
sta CIA1_PRA
lda CIA1_PRB
and #$10
beq gameover_fire
lda #$FF
sta CIA1_PRA
rts
gameover_fire:
lda #$FF
sta CIA1_PRA
jsr play_menu_select
; Return to menu (not title)
jsr show_menu
lda #STATE_MENU
sta game_state
rts
; ----------------------------------------------------------------------------
; Initialize Screen (Gameplay)
; ----------------------------------------------------------------------------
init_screen:
; Enable custom charset
lda #$1C ; Character ROM at $3000
sta CHARPTR
; Set colours
lda #BORDER_COL
sta BORDER
lda #BG_COL
sta BGCOL
; Clear screen
ldx #0
lda #CHAR_SPACE
clear_screen:
sta SCREEN,x
sta SCREEN+$100,x
sta SCREEN+$200,x
sta SCREEN+$2E8,x
inx
bne clear_screen
; Draw tracks
ldx #0
draw_tracks:
lda #CHAR_TRACK
sta SCREEN + (TRACK1_ROW * 40),x
sta SCREEN + (TRACK2_ROW * 40),x
sta SCREEN + (TRACK3_ROW * 40),x
lda #TRACK_LINE_COL
sta COLRAM + (TRACK1_ROW * 40),x
sta COLRAM + (TRACK2_ROW * 40),x
sta COLRAM + (TRACK3_ROW * 40),x
inx
cpx #38
bne draw_tracks
; Draw hit zones
lda #CHAR_HITZONE
sta SCREEN + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN
sta SCREEN + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN
sta SCREEN + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN
lda #HIT_ZONE_COL
sta COLRAM + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN
sta COLRAM + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN
sta COLRAM + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN
; Draw track labels
lda #$31 ; "1"
sta SCREEN + (TRACK1_ROW * 40)
lda #$32 ; "2"
sta SCREEN + (TRACK2_ROW * 40)
lda #$33 ; "3"
sta SCREEN + (TRACK3_ROW * 40)
lda #1
sta COLRAM + (TRACK1_ROW * 40)
sta COLRAM + (TRACK2_ROW * 40)
sta COLRAM + (TRACK3_ROW * 40)
; Draw HUD labels
ldx #0
draw_score_label:
lda score_label,x
beq draw_miss_label_start
sta SCREEN,x
lda #7
sta COLRAM,x
inx
jmp draw_score_label
draw_miss_label_start:
ldx #0
draw_miss_label:
lda miss_label,x
beq draw_combo_label_start
sta SCREEN + 14,x
lda #2
sta COLRAM + 14,x
inx
jmp draw_miss_label
draw_combo_label_start:
ldx #0
draw_combo_label:
lda combo_label,x
beq draw_health_label_start
sta SCREEN + (COMBO_ROW * 40) + 27,x
lda #COMBO_COL
sta COLRAM + (COMBO_ROW * 40) + 27,x
inx
jmp draw_combo_label
draw_health_label_start:
ldx #0
draw_health_label:
lda health_label,x
beq draw_progress_label_start
sta SCREEN + (HEALTH_ROW * 40),x
lda #HEALTH_COL
sta COLRAM + (HEALTH_ROW * 40),x
inx
jmp draw_health_label
draw_progress_label_start:
ldx #0
draw_progress_label:
lda progress_label,x
beq labels_done
sta SCREEN + (PROGRESS_ROW * 40),x
lda #PROGRESS_COL
sta COLRAM + (PROGRESS_ROW * 40),x
inx
jmp draw_progress_label
labels_done:
; Draw song name on gameplay screen
ldx #0
draw_song_name:
lda selected_song
; For now only song 0
lda song1_name,x
beq draw_song_name_done
sta SCREEN + 28,x
lda #11
sta COLRAM + 28,x
inx
jmp draw_song_name
draw_song_name_done:
rts
score_label:
!scr "score:"
!byte 0
miss_label:
!scr "miss:"
!byte 0
combo_label:
!scr "combo:"
!byte 0
health_label:
!scr "health:"
!byte 0
progress_label:
!scr "song:"
!byte 0
; ----------------------------------------------------------------------------
; Initialize Notes
; ----------------------------------------------------------------------------
init_notes:
ldx #0
lda #0
clear_notes:
sta note_track,x
sta note_col,x
sta note_freq,x
inx
cpx #MAX_NOTES
bne clear_notes
rts
; ----------------------------------------------------------------------------
; Initialize Score
; ----------------------------------------------------------------------------
init_score:
lda #0
sta score_lo
sta score_hi
sta miss_count
sta perfect_count
sta good_count
jsr display_score
jsr display_misses
rts
; ----------------------------------------------------------------------------
; Initialize Health
; ----------------------------------------------------------------------------
init_health:
lda #HEALTH_START
sta health
jsr display_health
rts
; ----------------------------------------------------------------------------
; Initialize Song
; ----------------------------------------------------------------------------
init_song:
lda #0
sta frame_count
sta beat_count
sta song_beat
sta song_ended
; Point to song data (for now, only one song)
lda #<song_data
sta song_pos
lda #>song_data
sta song_pos_hi
jsr display_progress
rts
; ----------------------------------------------------------------------------
; Initialize SID
; ----------------------------------------------------------------------------
init_sid:
; Clear SID
ldx #$18
lda #0
clear_sid:
sta SID,x
dex
bpl clear_sid
; Set volume
lda #$0F
sta SID_VOLUME
; Set pulse widths
lda #PULSE_WIDTH
sta SID_V1_PWHI
sta SID_V2_PWHI
sta SID_V3_PWHI
; Set ADSR for all voices
lda #VOICE_AD
sta SID_V1_AD
sta SID_V2_AD
sta SID_V3_AD
lda #VOICE_SR
sta SID_V1_SR
sta SID_V2_SR
sta SID_V3_SR
rts
; ----------------------------------------------------------------------------
; Copy Custom Charset
; ----------------------------------------------------------------------------
copy_charset:
; Copy default ROM charset to RAM first
sei
lda #$33
sta $01
ldx #0
copy_rom_chars:
lda $D000,x
sta CHARSET,x
lda $D100,x
sta CHARSET+$100,x
lda $D200,x
sta CHARSET+$200,x
lda $D300,x
sta CHARSET+$300,x
lda $D400,x
sta CHARSET+$400,x
lda $D500,x
sta CHARSET+$500,x
lda $D600,x
sta CHARSET+$600,x
lda $D700,x
sta CHARSET+$700,x
inx
bne copy_rom_chars
lda #$37
sta $01
cli
; Now add custom characters
; Character 128 - Note (solid circle)
lda #%00111100
sta CHARSET + (128 * 8) + 0
lda #%01111110
sta CHARSET + (128 * 8) + 1
lda #%11111111
sta CHARSET + (128 * 8) + 2
lda #%11111111
sta CHARSET + (128 * 8) + 3
lda #%11111111
sta CHARSET + (128 * 8) + 4
lda #%11111111
sta CHARSET + (128 * 8) + 5
lda #%01111110
sta CHARSET + (128 * 8) + 6
lda #%00111100
sta CHARSET + (128 * 8) + 7
; Character 129 - Track line (dashes)
lda #%00000000
sta CHARSET + (129 * 8) + 0
lda #%00000000
sta CHARSET + (129 * 8) + 1
lda #%00000000
sta CHARSET + (129 * 8) + 2
lda #%11001100
sta CHARSET + (129 * 8) + 3
lda #%11001100
sta CHARSET + (129 * 8) + 4
lda #%00000000
sta CHARSET + (129 * 8) + 5
lda #%00000000
sta CHARSET + (129 * 8) + 6
lda #%00000000
sta CHARSET + (129 * 8) + 7
; Character 130 - Hit zone (vertical bars)
lda #%10000001
sta CHARSET + (130 * 8) + 0
lda #%10000001
sta CHARSET + (130 * 8) + 1
lda #%10000001
sta CHARSET + (130 * 8) + 2
lda #%10000001
sta CHARSET + (130 * 8) + 3
lda #%10000001
sta CHARSET + (130 * 8) + 4
lda #%10000001
sta CHARSET + (130 * 8) + 5
lda #%10000001
sta CHARSET + (130 * 8) + 6
lda #%10000001
sta CHARSET + (130 * 8) + 7
; Character 131 - Bar full (solid block)
lda #%11111111
sta CHARSET + (131 * 8) + 0
sta CHARSET + (131 * 8) + 1
sta CHARSET + (131 * 8) + 2
sta CHARSET + (131 * 8) + 3
sta CHARSET + (131 * 8) + 4
sta CHARSET + (131 * 8) + 5
sta CHARSET + (131 * 8) + 6
sta CHARSET + (131 * 8) + 7
; Character 132 - Bar empty (hollow block)
lda #%11111111
sta CHARSET + (132 * 8) + 0
lda #%10000001
sta CHARSET + (132 * 8) + 1
sta CHARSET + (132 * 8) + 2
sta CHARSET + (132 * 8) + 3
sta CHARSET + (132 * 8) + 4
sta CHARSET + (132 * 8) + 5
sta CHARSET + (132 * 8) + 6
lda #%11111111
sta CHARSET + (132 * 8) + 7
rts
; ----------------------------------------------------------------------------
; Advance Song
; ----------------------------------------------------------------------------
advance_song:
inc song_beat
jsr display_progress
rts
; ----------------------------------------------------------------------------
; Check Spawn Note
; ----------------------------------------------------------------------------
check_spawn_note:
; Check if song has ended
lda song_ended
bne spawn_done
; Get pointer to current position in song
lda song_pos
sta ZP_PTR
lda song_pos_hi
sta ZP_PTR_HI
; Read beat number
ldy #0
lda (ZP_PTR),y
; Check for end marker
cmp #$FF
beq song_end_marker
; Check if this beat matches
cmp song_beat
bne spawn_done
; Spawn this note
iny
lda (ZP_PTR),y ; Track
sta temp_track
iny
lda (ZP_PTR),y ; Frequency
; Find free note slot
ldx #0
find_slot:
lda note_track,x
beq found_slot
inx
cpx #MAX_NOTES
bne find_slot
jmp advance_song_ptr ; No free slot, skip note
found_slot:
lda temp_track
sta note_track,x
lda #NOTE_SPAWN_COL
sta note_col,x
ldy #2
lda (ZP_PTR),y
sta note_freq,x
jsr draw_note
advance_song_ptr:
; Move to next note in song
lda song_pos
clc
adc #3
sta song_pos
lda song_pos_hi
adc #0
sta song_pos_hi
; Check if there are more notes on this beat
jmp check_spawn_note
song_end_marker:
lda #1
sta song_ended
spawn_done:
rts
; ----------------------------------------------------------------------------
; Update Notes
; ----------------------------------------------------------------------------
update_notes:
ldx #0
update_notes_loop:
lda note_track,x
beq update_next_note
; Erase at old position
jsr erase_note
; Move note left
dec note_col,x
; Check if past hit zone (missed)
lda note_col,x
cmp #HIT_ZONE_MIN
bcs note_still_active
; Note was missed
lda note_track,x
sta miss_track
lda #0
sta note_track,x
jsr handle_miss
jmp update_next_note
note_still_active:
jsr draw_note
update_next_note:
inx
cpx #MAX_NOTES
bne update_notes_loop
rts
; ----------------------------------------------------------------------------
; Draw Note
; ----------------------------------------------------------------------------
draw_note:
lda note_track,x
cmp #1
beq draw_note_t1
cmp #2
beq draw_note_t2
jmp draw_note_t3
draw_note_t1:
lda note_col,x
clc
adc #<(SCREEN + TRACK1_ROW * 40)
sta ZP_PTR
lda #>(SCREEN + TRACK1_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #CHAR_NOTE
ldy #0
sta (ZP_PTR),y
; Set colour
lda note_col,x
clc
adc #<(COLRAM + TRACK1_ROW * 40)
sta ZP_PTR
lda #>(COLRAM + TRACK1_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #TRACK1_NOTE_COL
sta (ZP_PTR),y
rts
draw_note_t2:
lda note_col,x
clc
adc #<(SCREEN + TRACK2_ROW * 40)
sta ZP_PTR
lda #>(SCREEN + TRACK2_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #CHAR_NOTE
ldy #0
sta (ZP_PTR),y
lda note_col,x
clc
adc #<(COLRAM + TRACK2_ROW * 40)
sta ZP_PTR
lda #>(COLRAM + TRACK2_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #TRACK2_NOTE_COL
sta (ZP_PTR),y
rts
draw_note_t3:
lda note_col,x
clc
adc #<(SCREEN + TRACK3_ROW * 40)
sta ZP_PTR
lda #>(SCREEN + TRACK3_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #CHAR_NOTE
ldy #0
sta (ZP_PTR),y
lda note_col,x
clc
adc #<(COLRAM + TRACK3_ROW * 40)
sta ZP_PTR
lda #>(COLRAM + TRACK3_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #TRACK3_NOTE_COL
sta (ZP_PTR),y
rts
; ----------------------------------------------------------------------------
; Erase Note
; ----------------------------------------------------------------------------
erase_note:
lda note_track,x
cmp #1
beq erase_note_t1
cmp #2
beq erase_note_t2
jmp erase_note_t3
erase_note_t1:
lda note_col,x
clc
adc #<(SCREEN + TRACK1_ROW * 40)
sta ZP_PTR
lda #>(SCREEN + TRACK1_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #CHAR_TRACK
ldy #0
sta (ZP_PTR),y
lda note_col,x
clc
adc #<(COLRAM + TRACK1_ROW * 40)
sta ZP_PTR
lda #>(COLRAM + TRACK1_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #TRACK_LINE_COL
sta (ZP_PTR),y
rts
erase_note_t2:
lda note_col,x
clc
adc #<(SCREEN + TRACK2_ROW * 40)
sta ZP_PTR
lda #>(SCREEN + TRACK2_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #CHAR_TRACK
ldy #0
sta (ZP_PTR),y
lda note_col,x
clc
adc #<(COLRAM + TRACK2_ROW * 40)
sta ZP_PTR
lda #>(COLRAM + TRACK2_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #TRACK_LINE_COL
sta (ZP_PTR),y
rts
erase_note_t3:
lda note_col,x
clc
adc #<(SCREEN + TRACK3_ROW * 40)
sta ZP_PTR
lda #>(SCREEN + TRACK3_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #CHAR_TRACK
ldy #0
sta (ZP_PTR),y
lda note_col,x
clc
adc #<(COLRAM + TRACK3_ROW * 40)
sta ZP_PTR
lda #>(COLRAM + TRACK3_ROW * 40)
adc #0
sta ZP_PTR_HI
lda #TRACK_LINE_COL
sta (ZP_PTR),y
rts
; ----------------------------------------------------------------------------
; Handle Miss
; ----------------------------------------------------------------------------
handle_miss:
jsr play_miss_sound
jsr break_combo
; Decrease health
lda #HEALTH_MISS
jsr decrease_health
; Flash border red
lda #MISS_COL
sta BORDER
lda #8
sta border_flash
; Flash the track where miss happened
lda miss_track
cmp #1
beq flash_miss_t1
cmp #2
beq flash_miss_t2
jmp flash_miss_t3
flash_miss_t1:
ldx #0
lda #MISS_COL
flash_m1_loop:
sta COLRAM + (TRACK1_ROW * 40),x
inx
cpx #38
bne flash_m1_loop
rts
flash_miss_t2:
ldx #0
lda #MISS_COL
flash_m2_loop:
sta COLRAM + (TRACK2_ROW * 40),x
inx
cpx #38
bne flash_m2_loop
rts
flash_miss_t3:
ldx #0
lda #MISS_COL
flash_m3_loop:
sta COLRAM + (TRACK3_ROW * 40),x
inx
cpx #38
bne flash_m3_loop
rts
; ----------------------------------------------------------------------------
; Play Miss Sound
; ----------------------------------------------------------------------------
play_miss_sound:
inc miss_count
jsr display_misses
lda #0
sta SID_V3_FREQ_LO
lda #MISS_FREQ
sta SID_V3_FREQ_HI
lda #MISS_AD
sta SID_V3_AD
lda #MISS_SR
sta SID_V3_SR
lda #MISS_WAVE
ora #$01
sta SID_V3_CTRL
rts
; ----------------------------------------------------------------------------
; Play Perfect Sound
; ----------------------------------------------------------------------------
play_perfect_sound:
lda #0
sta SID_V3_FREQ_LO
lda #PERFECT_SFX_FREQ
sta SID_V3_FREQ_HI
lda #PERFECT_SFX_AD
sta SID_V3_AD
lda #PERFECT_SFX_SR
sta SID_V3_SR
lda #PERFECT_SFX_WAVE
ora #$01
sta SID_V3_CTRL
rts
; ----------------------------------------------------------------------------
; Play Good Sound
; ----------------------------------------------------------------------------
play_good_sound:
lda #0
sta SID_V3_FREQ_LO
lda #GOOD_SFX_FREQ
sta SID_V3_FREQ_HI
lda #GOOD_SFX_AD
sta SID_V3_AD
lda #GOOD_SFX_SR
sta SID_V3_SR
lda #GOOD_SFX_WAVE
ora #$01
sta SID_V3_CTRL
rts
; ----------------------------------------------------------------------------
; Increase Health
; ----------------------------------------------------------------------------
increase_health:
clc
adc health
cmp #HEALTH_MAX
bcc health_ok
lda #HEALTH_MAX
health_ok:
sta health
jsr display_health
rts
; ----------------------------------------------------------------------------
; Decrease Health
; ----------------------------------------------------------------------------
decrease_health:
sta temp_track
lda health
sec
sbc temp_track
bcs health_not_zero
lda #0
health_not_zero:
sta health
jsr display_health
; Check for game over
lda health
bne no_game_over
jsr show_gameover
lda #STATE_GAMEOVER
sta game_state
no_game_over:
rts
; ----------------------------------------------------------------------------
; Display Health Bar
; ----------------------------------------------------------------------------
display_health:
; Calculate filled blocks (health / 4 = blocks, max 16)
lda health
lsr
lsr
sta temp_track
ldx #0
draw_health_bar:
cpx temp_track
bcs draw_empty_health
lda #CHAR_BAR_FULL
jmp store_health_char
draw_empty_health:
lda #CHAR_BAR_EMPTY
store_health_char:
sta SCREEN + (HEALTH_ROW * 40) + 8,x
lda #HEALTH_COL
sta COLRAM + (HEALTH_ROW * 40) + 8,x
inx
cpx #16
bne draw_health_bar
rts
; ----------------------------------------------------------------------------
; Display Progress Bar
; ----------------------------------------------------------------------------
display_progress:
; Calculate progress (song_beat / 4)
lda song_beat
lsr
lsr
sta temp_track
ldx #0
draw_progress_bar:
cpx temp_track
bcs draw_empty_progress
lda #CHAR_BAR_FULL
jmp store_progress_char
draw_empty_progress:
lda #CHAR_BAR_EMPTY
store_progress_char:
sta SCREEN + (PROGRESS_ROW * 40) + 8,x
lda #PROGRESS_COL
sta COLRAM + (PROGRESS_ROW * 40) + 8,x
inx
cpx #PROGRESS_WIDTH
bne draw_progress_bar
rts
; ----------------------------------------------------------------------------
; Combo System
; ----------------------------------------------------------------------------
increment_combo:
inc combo
lda combo
cmp max_combo
bcc combo_no_max
sta max_combo
combo_no_max:
jsr display_combo
rts
break_combo:
lda #0
sta combo
jsr display_combo
rts
display_combo:
; Display combo count
lda combo
ldx #0
combo_div_100:
cmp #100
bcc combo_done_100
sec
sbc #100
inx
jmp combo_div_100
combo_done_100:
pha
txa
ora #$30
sta SCREEN + (COMBO_ROW * 40) + 34
pla
ldx #0
combo_div_10:
cmp #10
bcc combo_done_10
sec
sbc #10
inx
jmp combo_div_10
combo_done_10:
pha
txa
ora #$30
sta SCREEN + (COMBO_ROW * 40) + 35
pla
ora #$30
sta SCREEN + (COMBO_ROW * 40) + 36
; Colour based on multiplier
jsr get_multiplier
cmp #1
beq combo_col_1x
cmp #2
beq combo_col_2x
cmp #3
beq combo_col_3x
jmp combo_col_4x
combo_col_1x:
lda #11 ; Grey
jmp set_combo_col
combo_col_2x:
lda #7 ; Yellow
jmp set_combo_col
combo_col_3x:
lda #5 ; Green
jmp set_combo_col
combo_col_4x:
lda #1 ; White
set_combo_col:
sta COLRAM + (COMBO_ROW * 40) + 34
sta COLRAM + (COMBO_ROW * 40) + 35
sta COLRAM + (COMBO_ROW * 40) + 36
rts
get_multiplier:
lda combo
cmp #COMBO_TIER_4
bcs mult_4x
cmp #COMBO_TIER_3
bcs mult_3x
cmp #COMBO_TIER_2
bcs mult_2x
lda #1
rts
mult_2x:
lda #2
rts
mult_3x:
lda #3
rts
mult_4x:
lda #4
rts
; ----------------------------------------------------------------------------
; Reset Track Colours
; ----------------------------------------------------------------------------
reset_track_colours:
ldx #1 ; Start at column 1 (skip label)
reset_col_loop:
lda #TRACK_LINE_COL
sta COLRAM + (TRACK1_ROW * 40),x
sta COLRAM + (TRACK2_ROW * 40),x
sta COLRAM + (TRACK3_ROW * 40),x
inx
cpx #38
bne reset_col_loop
; Restore hit zone colours
lda #HIT_ZONE_COL
sta COLRAM + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN
sta COLRAM + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN
sta COLRAM + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN
; Redraw notes with correct colours
ldx #0
redraw_loop:
lda note_track,x
beq redraw_next
jsr draw_note
redraw_next:
inx
cpx #MAX_NOTES
bne redraw_loop
rts
; ----------------------------------------------------------------------------
; Update Border Flash
; ----------------------------------------------------------------------------
update_border_flash:
lda border_flash
beq flash_done
dec border_flash
bne flash_done
lda #BORDER_COL
sta BORDER
flash_done:
rts
; ----------------------------------------------------------------------------
; Check Keys
; ----------------------------------------------------------------------------
check_keys:
lda #$FD
sta CIA1_PRA
lda CIA1_PRB
and #$10
bne check_x_key
lda #1
sta key_pressed
jsr check_hit
bcc check_x_key
jsr play_voice1_note
jsr flash_track1_hit
jsr award_points
check_x_key:
lda #$FB
sta CIA1_PRA
lda CIA1_PRB
and #$80
bne check_c_key
lda #2
sta key_pressed
jsr check_hit
bcc check_c_key
jsr play_voice2_note
jsr flash_track2_hit
jsr award_points
check_c_key:
lda #$FB
sta CIA1_PRA
lda CIA1_PRB
and #$10
bne check_keys_done
lda #3
sta key_pressed
jsr check_hit
bcc check_keys_done
jsr play_voice3_note
jsr flash_track3_hit
jsr award_points
check_keys_done:
lda #$FF
sta CIA1_PRA
rts
; ----------------------------------------------------------------------------
; Check Hit
; ----------------------------------------------------------------------------
check_hit:
ldx #0
check_hit_loop:
lda note_track,x
beq check_hit_next
cmp key_pressed
bne check_hit_next
lda note_col,x
cmp #HIT_ZONE_MIN
bcc check_hit_next
cmp #HIT_ZONE_MAX+1
bcs check_hit_next
lda note_freq,x
sta hit_note_freq
lda note_col,x
cmp #HIT_ZONE_CENTRE
bcc hit_good
cmp #HIT_ZONE_CENTRE+2
bcs hit_good
lda #2
sta hit_quality
jmp hit_found
hit_good:
lda #1
sta hit_quality
hit_found:
jsr erase_note
lda #0
sta note_track,x
sec
rts
check_hit_next:
inx
cpx #MAX_NOTES
bne check_hit_loop
lda #0
sta hit_quality
clc
rts
; ----------------------------------------------------------------------------
; Check Song End
; ----------------------------------------------------------------------------
check_song_end:
lda song_ended
beq not_ended
; Check if all notes cleared
ldx #0
check_notes_clear:
lda note_track,x
bne not_ended
inx
cpx #MAX_NOTES
bne check_notes_clear
; Add delay before results
inc end_delay
lda end_delay
cmp #END_DELAY_FRAMES
bcc not_ended
; Show results
jsr show_results
lda #STATE_RESULTS
sta game_state
not_ended:
rts
; ----------------------------------------------------------------------------
; Award Points
; ----------------------------------------------------------------------------
award_points:
jsr increment_combo
lda hit_quality
cmp #2
beq award_perfect
; Good hit
lda #GOOD_SCORE
jsr apply_multiplier
jsr add_score
inc good_count
; Play good sound effect
jsr play_good_sound
lda #GOOD_COL
sta BORDER
lda #4
sta border_flash
lda #HEALTH_GOOD
jsr increase_health
jmp award_done
award_perfect:
; Perfect hit
lda #PERFECT_SCORE
jsr apply_multiplier
jsr add_score
inc perfect_count
; Play perfect sound effect
jsr play_perfect_sound
lda #PERFECT_COL
sta BORDER
lda #6
sta border_flash
lda #HEALTH_PERFECT
jsr increase_health
award_done:
jsr display_score
rts
; ----------------------------------------------------------------------------
; Apply Multiplier
; ----------------------------------------------------------------------------
apply_multiplier:
sta base_score
jsr get_multiplier
sta current_mult
lda base_score
sta score_add_lo
lda #0
sta score_add_hi
lda current_mult
cmp #1
beq mult_done_apply
dec current_mult
mult_add_loop:
lda score_add_lo
clc
adc base_score
sta score_add_lo
lda score_add_hi
adc #0
sta score_add_hi
dec current_mult
bne mult_add_loop
mult_done_apply:
rts
base_score: !byte 0
current_mult: !byte 0
score_add_lo: !byte 0
score_add_hi: !byte 0
; ----------------------------------------------------------------------------
; Add Score
; ----------------------------------------------------------------------------
add_score:
lda score_lo
clc
adc score_add_lo
sta score_lo
lda score_hi
adc score_add_hi
sta score_hi
rts
; ----------------------------------------------------------------------------
; Display Score
; ----------------------------------------------------------------------------
display_score:
lda score_lo
sta work_lo
lda score_hi
sta work_hi
ldx #0
div_10000:
lda work_lo
sec
sbc #<10000
tay
lda work_hi
sbc #>10000
bcc done_10000
sta work_hi
sty work_lo
inx
jmp div_10000
done_10000:
txa
ora #$30
sta SCREEN + 8
ldx #0
div_1000:
lda work_lo
sec
sbc #<1000
tay
lda work_hi
sbc #>1000
bcc done_1000
sta work_hi
sty work_lo
inx
jmp div_1000
done_1000:
txa
ora #$30
sta SCREEN + 9
ldx #0
div_100:
lda work_lo
sec
sbc #100
bcc done_100
sta work_lo
inx
jmp div_100
done_100:
txa
ora #$30
sta SCREEN + 10
ldx #0
div_10:
lda work_lo
sec
sbc #10
bcc done_10
sta work_lo
inx
jmp div_10
done_10:
txa
ora #$30
sta SCREEN + 11
lda work_lo
ora #$30
sta SCREEN + 12
lda #7
sta COLRAM + 8
sta COLRAM + 9
sta COLRAM + 10
sta COLRAM + 11
sta COLRAM + 12
rts
; ----------------------------------------------------------------------------
; Display Misses
; ----------------------------------------------------------------------------
display_misses:
lda miss_count
ldx #0
miss_div_10:
cmp #10
bcc miss_done_10
sec
sbc #10
inx
jmp miss_div_10
miss_done_10:
pha
txa
ora #$30
sta SCREEN + 21
pla
ora #$30
sta SCREEN + 22
lda #2
sta COLRAM + 21
sta COLRAM + 22
rts
work_lo: !byte 0
work_hi: !byte 0
; ----------------------------------------------------------------------------
; Play Voices (for note playback)
; ----------------------------------------------------------------------------
play_voice1_note:
lda #0
sta SID_V1_FREQ_LO
lda hit_note_freq
sta SID_V1_FREQ_HI
lda #VOICE1_WAVE
ora #$01
sta SID_V1_CTRL
rts
play_voice2_note:
lda #0
sta SID_V2_FREQ_LO
lda hit_note_freq
sta SID_V2_FREQ_HI
lda #VOICE2_WAVE
ora #$01
sta SID_V2_CTRL
rts
play_voice3_note:
lda #0
sta SID_V3_FREQ_LO
lda hit_note_freq
sta SID_V3_FREQ_HI
lda #VOICE3_WAVE
ora #$01
sta SID_V3_CTRL
rts
; ----------------------------------------------------------------------------
; Flash Tracks
; ----------------------------------------------------------------------------
flash_track1_hit:
ldx #0
lda #HIT_COL
flash_t1h_loop:
sta COLRAM + (TRACK1_ROW * 40),x
inx
cpx #38
bne flash_t1h_loop
lda #1
sta COLRAM + (TRACK1_ROW * 40)
rts
flash_track2_hit:
ldx #0
lda #HIT_COL
flash_t2h_loop:
sta COLRAM + (TRACK2_ROW * 40),x
inx
cpx #38
bne flash_t2h_loop
lda #1
sta COLRAM + (TRACK2_ROW * 40)
rts
flash_track3_hit:
ldx #0
lda #HIT_COL
flash_t3h_loop:
sta COLRAM + (TRACK3_ROW * 40),x
inx
cpx #38
bne flash_t3h_loop
lda #1
sta COLRAM + (TRACK3_ROW * 40)
rts
; ----------------------------------------------------------------------------
; Show Results Screen
; ----------------------------------------------------------------------------
show_results:
; Clear screen
ldx #0
lda #CHAR_SPACE
clear_results:
sta SCREEN,x
sta SCREEN+$100,x
sta SCREEN+$200,x
sta SCREEN+$2E8,x
inx
bne clear_results
; Draw "SONG COMPLETE!"
ldx #0
draw_complete:
lda complete_text,x
beq draw_results_score
sta SCREEN + (5 * 40) + 13,x
lda #5
sta COLRAM + (5 * 40) + 13,x
inx
jmp draw_complete
draw_results_score:
; Draw score label
ldx #0
draw_rs_label:
lda results_score_label,x
beq draw_rs_value
sta SCREEN + (9 * 40) + 12,x
lda #7
sta COLRAM + (9 * 40) + 12,x
inx
jmp draw_rs_label
draw_rs_value:
; Draw score value
lda score_lo
sta work_lo
lda score_hi
sta work_hi
ldx #0
rs_div_10000:
lda work_lo
sec
sbc #<10000
tay
lda work_hi
sbc #>10000
bcc rs_done_10000
sta work_hi
sty work_lo
inx
jmp rs_div_10000
rs_done_10000:
txa
ora #$30
sta SCREEN + (9 * 40) + 23
ldx #0
rs_div_1000:
lda work_lo
sec
sbc #<1000
tay
lda work_hi
sbc #>1000
bcc rs_done_1000
sta work_hi
sty work_lo
inx
jmp rs_div_1000
rs_done_1000:
txa
ora #$30
sta SCREEN + (9 * 40) + 24
ldx #0
rs_div_100:
lda work_lo
sec
sbc #100
bcc rs_done_100
sta work_lo
inx
jmp rs_div_100
rs_done_100:
txa
ora #$30
sta SCREEN + (9 * 40) + 25
ldx #0
rs_div_10:
lda work_lo
sec
sbc #10
bcc rs_done_10
sta work_lo
inx
jmp rs_div_10
rs_done_10:
txa
ora #$30
sta SCREEN + (9 * 40) + 26
lda work_lo
ora #$30
sta SCREEN + (9 * 40) + 27
lda #7
sta COLRAM + (9 * 40) + 23
sta COLRAM + (9 * 40) + 24
sta COLRAM + (9 * 40) + 25
sta COLRAM + (9 * 40) + 26
sta COLRAM + (9 * 40) + 27
; Draw perfect count
ldx #0
draw_perfect_label:
lda perfect_label,x
beq draw_perfect_value
sta SCREEN + (11 * 40) + 12,x
lda #1
sta COLRAM + (11 * 40) + 12,x
inx
jmp draw_perfect_label
draw_perfect_value:
lda perfect_count
ldx #0
pv_div_10:
cmp #10
bcc pv_done_10
sec
sbc #10
inx
jmp pv_div_10
pv_done_10:
pha
txa
ora #$30
sta SCREEN + (11 * 40) + 23
pla
ora #$30
sta SCREEN + (11 * 40) + 24
lda #1
sta COLRAM + (11 * 40) + 23
sta COLRAM + (11 * 40) + 24
; Draw good count
ldx #0
draw_good_label:
lda good_label,x
beq draw_good_value
sta SCREEN + (12 * 40) + 12,x
lda #7
sta COLRAM + (12 * 40) + 12,x
inx
jmp draw_good_label
draw_good_value:
lda good_count
ldx #0
gv_div_10:
cmp #10
bcc gv_done_10
sec
sbc #10
inx
jmp gv_div_10
gv_done_10:
pha
txa
ora #$30
sta SCREEN + (12 * 40) + 23
pla
ora #$30
sta SCREEN + (12 * 40) + 24
lda #7
sta COLRAM + (12 * 40) + 23
sta COLRAM + (12 * 40) + 24
; Draw miss count
ldx #0
draw_miss_label_r:
lda miss_label_r,x
beq draw_miss_value
sta SCREEN + (13 * 40) + 12,x
lda #2
sta COLRAM + (13 * 40) + 12,x
inx
jmp draw_miss_label_r
draw_miss_value:
lda miss_count
ldx #0
mv_div_10:
cmp #10
bcc mv_done_10
sec
sbc #10
inx
jmp mv_div_10
mv_done_10:
pha
txa
ora #$30
sta SCREEN + (13 * 40) + 23
pla
ora #$30
sta SCREEN + (13 * 40) + 24
lda #2
sta COLRAM + (13 * 40) + 23
sta COLRAM + (13 * 40) + 24
; Draw max combo
ldx #0
draw_maxc_label:
lda maxcombo_label,x
beq draw_maxc_value
sta SCREEN + (15 * 40) + 12,x
lda #COMBO_COL
sta COLRAM + (15 * 40) + 12,x
inx
jmp draw_maxc_label
draw_maxc_value:
lda max_combo
ldx #0
mc_div_100:
cmp #100
bcc mc_done_100
sec
sbc #100
inx
jmp mc_div_100
mc_done_100:
pha
txa
ora #$30
sta SCREEN + (15 * 40) + 23
pla
ldx #0
mc_div_10:
cmp #10
bcc mc_done_10
sec
sbc #10
inx
jmp mc_div_10
mc_done_10:
pha
txa
ora #$30
sta SCREEN + (15 * 40) + 24
pla
ora #$30
sta SCREEN + (15 * 40) + 25
lda #COMBO_COL
sta COLRAM + (15 * 40) + 23
sta COLRAM + (15 * 40) + 24
sta COLRAM + (15 * 40) + 25
; Draw "PRESS FIRE"
ldx #0
draw_return:
lda return_text,x
beq results_done
sta SCREEN + (20 * 40) + 10,x
lda #11
sta COLRAM + (20 * 40) + 10,x
inx
jmp draw_return
results_done:
rts
complete_text:
!scr "song complete!"
!byte 0
results_score_label:
!scr "final score:"
!byte 0
perfect_label:
!scr "perfect:"
!byte 0
good_label:
!scr "good:"
!byte 0
miss_label_r:
!scr "misses:"
!byte 0
maxcombo_label:
!scr "max combo:"
!byte 0
return_text:
!scr "press fire to continue"
!byte 0
; ----------------------------------------------------------------------------
; Show Game Over Screen
; ----------------------------------------------------------------------------
show_gameover:
; Clear screen
ldx #0
lda #CHAR_SPACE
clear_gameover:
sta SCREEN,x
sta SCREEN+$100,x
sta SCREEN+$200,x
sta SCREEN+$2E8,x
inx
bne clear_gameover
; Draw "GAME OVER"
ldx #0
draw_gameover_text:
lda gameover_text,x
beq draw_gameover_score
sta SCREEN + (8 * 40) + 15,x
lda #2
sta COLRAM + (8 * 40) + 15,x
inx
jmp draw_gameover_text
draw_gameover_score:
; Draw score
ldx #0
draw_go_score_label:
lda gameover_score,x
beq draw_go_score_value
sta SCREEN + (12 * 40) + 12,x
lda #7
sta COLRAM + (12 * 40) + 12,x
inx
jmp draw_go_score_label
draw_go_score_value:
lda score_lo
sta work_lo
lda score_hi
sta work_hi
ldx #0
go_div_10000:
lda work_lo
sec
sbc #<10000
tay
lda work_hi
sbc #>10000
bcc go_done_10000
sta work_hi
sty work_lo
inx
jmp go_div_10000
go_done_10000:
txa
ora #$30
sta SCREEN + (12 * 40) + 23
ldx #0
go_div_1000:
lda work_lo
sec
sbc #<1000
tay
lda work_hi
sbc #>1000
bcc go_done_1000
sta work_hi
sty work_lo
inx
jmp go_div_1000
go_done_1000:
txa
ora #$30
sta SCREEN + (12 * 40) + 24
ldx #0
go_div_100:
lda work_lo
sec
sbc #100
bcc go_done_100
sta work_lo
inx
jmp go_div_100
go_done_100:
txa
ora #$30
sta SCREEN + (12 * 40) + 25
ldx #0
go_div_10:
lda work_lo
sec
sbc #10
bcc go_done_10
sta work_lo
inx
jmp go_div_10
go_done_10:
txa
ora #$30
sta SCREEN + (12 * 40) + 26
lda work_lo
ora #$30
sta SCREEN + (12 * 40) + 27
lda #7
sta COLRAM + (12 * 40) + 23
sta COLRAM + (12 * 40) + 24
sta COLRAM + (12 * 40) + 25
sta COLRAM + (12 * 40) + 26
sta COLRAM + (12 * 40) + 27
; Draw retry message
ldx #0
draw_retry:
lda retry_text,x
beq gameover_done
sta SCREEN + (18 * 40) + 10,x
lda #11
sta COLRAM + (18 * 40) + 10,x
inx
jmp draw_retry
gameover_done:
rts
gameover_text:
!scr "game over"
!byte 0
gameover_score:
!scr "your score:"
!byte 0
retry_text:
!scr "press fire to continue"
!byte 0
; ============================================================================
; SONG DATA - First Song: "First Steps"
; ============================================================================
; Format: beat, track (1-3), SID frequency high byte
; ============================================================================
song_data:
; Opening - gentle introduction
!byte 0, 1, $47 ; Beat 0: Track 1, high note
!byte 2, 2, $2C ; Beat 2: Track 2, mid note
!byte 4, 3, $11 ; Beat 4: Track 3, low note
; Build - add more notes
!byte 8, 1, $3B
!byte 10, 2, $27
!byte 12, 3, $13
; Complexity - overlapping patterns
!byte 16, 1, $35
!byte 17, 2, $2C
!byte 18, 1, $3B
!byte 20, 3, $16
; Theme repeats
!byte 24, 1, $47
!byte 26, 2, $35
!byte 28, 3, $11
; Variation
!byte 32, 2, $2F
!byte 34, 1, $4F
!byte 36, 3, $17
; Building intensity
!byte 40, 1, $58
!byte 42, 2, $2C
!byte 44, 3, $11
!byte 46, 2, $27
; Climax section
!byte 48, 1, $6A
!byte 49, 2, $35
!byte 50, 1, $58
!byte 52, 3, $1A
!byte 54, 2, $2F
; Resolution
!byte 56, 1, $47
!byte 58, 2, $2C
!byte 60, 3, $11
!byte 62, 1, $35
!byte $FF ; End marker
; ----------------------------------------------------------------------------
; Note Arrays
; ----------------------------------------------------------------------------
note_track:
!fill MAX_NOTES, 0
note_col:
!fill MAX_NOTES, 0
note_freq:
!fill MAX_NOTES, 0
; ----------------------------------------------------------------------------
; Game Variables
; ----------------------------------------------------------------------------
score_lo: !byte 0
score_hi: !byte 0
miss_count: !byte 0
perfect_count: !byte 0
good_count: !byte 0
health: !byte 0
combo: !byte 0
max_combo: !byte 0
; ============================================================================
; END OF SID SYMPHONY - UNIT 17
; ============================================================================
What’s Coming
The menu system is ready for expansion:
- Unit 18: Add Song 2 with different character
- Unit 19: Add difficulty selection to the menu
- Unit 20: Difficulty variants for each song
- Unit 21: Song 3 at faster tempo
The infrastructure built here pays off quickly.
What You’ve Learnt
- Menu state management - Adding states to the state machine
- Cursor tracking - Position variable and bounds checking
- Key repeat delay - Preventing input spam
- State transitions - Menu → Game → Menu flow
- Sound feedback - Different sounds for different actions
Phase 2 is underway.
What Changed
| 1 | 1 | ; ============================================================================ | |
| 2 | - | ; SID SYMPHONY - Unit 16: Phase 1 Complete | |
| 2 | + | ; SID SYMPHONY - Unit 17: Song Selection Screen | |
| 3 | 3 | ; ============================================================================ | |
| 4 | - | ; The complete Phase 1 rhythm game. Polished, balanced, and ready to play. | |
| 5 | - | ; Title screen, gameplay, results, game over - all working together. | |
| 4 | + | ; Adding a menu system to select songs. Currently only one song, but the | |
| 5 | + | ; structure is ready for multiple songs in the next unit. | |
| 6 | 6 | ; | |
| 7 | - | ; Controls: Z = Track 1 (high), X = Track 2 (mid), C = Track 3 (low) | |
| 8 | - | ; Fire/Space = Start game, return to title | |
| 7 | + | ; New concepts: Menu state, cursor tracking, key repeat delay | |
| 8 | + | ; | |
| 9 | + | ; Controls: Z = Track 1, X = Track 2, C = Track 3 | |
| 10 | + | ; Up/Down = Menu navigation | |
| 11 | + | ; Fire/Space = Start game / Select | |
| 9 | 12 | ; ============================================================================ | |
| 10 | 13 | | |
| 11 | 14 | ; ============================================================================ | |
| 12 | 15 | ; CUSTOMISATION SECTION | |
| 13 | 16 | ; ============================================================================ | |
| 17 | + | | |
| 18 | + | ; Screenshot mode - set to 1 to skip title and show menu immediately | |
| 19 | + | ; Used for automated screenshot capture. Override with: acme -DSCREENSHOT_MODE=1 | |
| 20 | + | !ifndef SCREENSHOT_MODE { SCREENSHOT_MODE = 0 } | |
| 14 | 21 | | |
| 15 | 22 | ; SID Voice Settings (for note playback) | |
| 16 | 23 | VOICE1_WAVE = $21 ; Sawtooth for track 1 | |
| ... | |||
| 48 | 55 | MENU_SELECT_WAVE = $41 ; Pulse for click | |
| 49 | 56 | MENU_SELECT_AD = $00 ; Instant | |
| 50 | 57 | MENU_SELECT_SR = $80 ; Very short | |
| 58 | + | | |
| 59 | + | MENU_MOVE_FREQ = $10 ; Lower pitch for cursor move | |
| 60 | + | MENU_MOVE_WAVE = $11 ; Triangle (soft) | |
| 61 | + | MENU_MOVE_AD = $00 ; Instant | |
| 62 | + | MENU_MOVE_SR = $40 ; Very short | |
| 51 | 63 | | |
| 52 | 64 | ; Visual Settings | |
| 53 | 65 | BORDER_COL = 0 | |
| ... | |||
| 72 | 84 | ; Title screen colours | |
| 73 | 85 | TITLE_COL = 1 ; White for title | |
| 74 | 86 | SUBTITLE_COL = 11 ; Grey for subtitle | |
| 87 | + | MENU_COL = 7 ; Yellow for menu items | |
| 88 | + | CURSOR_COL = 1 ; White for cursor | |
| 75 | 89 | | |
| 76 | 90 | ; ============================================================================ | |
| 77 | 91 | ; SCORING SETTINGS (BALANCED) | |
| ... | |||
| 112 | 126 | | |
| 113 | 127 | SONG_LENGTH = 64 ; 64 beats at 120 BPM = ~32 seconds | |
| 114 | 128 | PROGRESS_WIDTH = 16 ; Progress bar width | |
| 129 | + | | |
| 130 | + | ; ============================================================================ | |
| 131 | + | ; MENU SETTINGS | |
| 132 | + | ; ============================================================================ | |
| 133 | + | | |
| 134 | + | NUM_SONGS = 1 ; Currently only 1 song | |
| 135 | + | KEY_DELAY = 10 ; Frames between key repeats | |
| 115 | 136 | | |
| 116 | 137 | ; ============================================================================ | |
| 117 | 138 | ; GAME STATES | |
| 118 | 139 | ; ============================================================================ | |
| 119 | 140 | | |
| 120 | 141 | STATE_TITLE = 0 ; Title screen | |
| 121 | - | STATE_PLAYING = 1 ; Gameplay | |
| 122 | - | STATE_RESULTS = 2 ; Success results | |
| 123 | - | STATE_GAMEOVER = 3 ; Failure game over | |
| 142 | + | STATE_MENU = 1 ; Song selection menu (NEW!) | |
| 143 | + | STATE_PLAYING = 2 ; Gameplay | |
| 144 | + | STATE_RESULTS = 3 ; Success results | |
| 145 | + | STATE_GAMEOVER = 4 ; Failure game over | |
| 124 | 146 | | |
| 125 | 147 | ; ============================================================================ | |
| 126 | 148 | ; MEMORY MAP | |
| ... | |||
| 185 | 207 | CHAR_SPACE = 32 | |
| 186 | 208 | CHAR_BAR_FULL = 131 | |
| 187 | 209 | CHAR_BAR_EMPTY = 132 | |
| 210 | + | CHAR_CURSOR = 62 ; > character for menu cursor | |
| 188 | 211 | | |
| 189 | 212 | ; Note settings | |
| 190 | 213 | MAX_NOTES = 8 ; Maximum simultaneous notes | |
| ... | |||
| 213 | 236 | song_beat = $0D | |
| 214 | 237 | song_ended = $0E | |
| 215 | 238 | end_delay = $0F | |
| 239 | + | cursor_pos = $10 ; Menu cursor position (NEW!) | |
| 240 | + | key_delay_count = $11 ; Key repeat delay counter (NEW!) | |
| 241 | + | selected_song = $12 ; Which song to play (NEW!) | |
| 216 | 242 | | |
| 217 | 243 | ; ---------------------------------------------------------------------------- | |
| 218 | 244 | ; BASIC Stub | |
| ... | |||
| 236 | 262 | start: | |
| 237 | 263 | jsr copy_charset | |
| 238 | 264 | jsr init_sid | |
| 239 | - | jsr show_title | |
| 240 | 265 | | |
| 241 | - | ; Start in TITLE state | |
| 266 | + | !if SCREENSHOT_MODE = 1 { | |
| 267 | + | ; Screenshot mode: skip title, go to menu | |
| 268 | + | jsr show_menu | |
| 269 | + | lda #STATE_MENU | |
| 270 | + | sta game_state | |
| 271 | + | } else { | |
| 272 | + | ; Normal mode: show title screen | |
| 273 | + | jsr show_title | |
| 242 | 274 | lda #STATE_TITLE | |
| 243 | 275 | sta game_state | |
| 276 | + | } | |
| 244 | 277 | | |
| 245 | 278 | main_loop: | |
| 246 | 279 | lda #$FF | |
| ... | |||
| 251 | 284 | lda game_state | |
| 252 | 285 | cmp #STATE_TITLE | |
| 253 | 286 | beq do_title | |
| 287 | + | cmp #STATE_MENU | |
| 288 | + | beq do_menu | |
| 254 | 289 | cmp #STATE_PLAYING | |
| 255 | 290 | beq do_playing | |
| 256 | 291 | cmp #STATE_RESULTS | |
| ... | |||
| 259 | 294 | | |
| 260 | 295 | do_title: | |
| 261 | 296 | jsr update_title | |
| 297 | + | jmp main_loop | |
| 298 | + | | |
| 299 | + | do_menu: | |
| 300 | + | jsr update_menu | |
| 262 | 301 | jmp main_loop | |
| 263 | 302 | | |
| 264 | 303 | do_playing: | |
| ... | |||
| 384 | 423 | ; Check for fire button (joystick port 2) | |
| 385 | 424 | lda CIA1_PRA | |
| 386 | 425 | and #$10 ; Bit 4 = fire | |
| 387 | - | beq fire_pressed | |
| 426 | + | beq title_fire_pressed | |
| 388 | 427 | | |
| 389 | 428 | ; Also check space bar as alternative | |
| 390 | 429 | lda #$7F | |
| 391 | 430 | sta CIA1_PRA | |
| 392 | 431 | lda CIA1_PRB | |
| 393 | 432 | and #$10 ; Space | |
| 394 | - | beq fire_pressed | |
| 433 | + | beq title_fire_pressed | |
| 395 | 434 | | |
| 396 | 435 | ; No input - stay on title | |
| 397 | 436 | lda #$FF | |
| 398 | 437 | sta CIA1_PRA | |
| 399 | 438 | rts | |
| 400 | 439 | | |
| 401 | - | fire_pressed: | |
| 440 | + | title_fire_pressed: | |
| 402 | 441 | lda #$FF | |
| 403 | 442 | sta CIA1_PRA | |
| 404 | 443 | | |
| 405 | 444 | ; Play menu select sound | |
| 406 | 445 | jsr play_menu_select | |
| 407 | 446 | | |
| 408 | - | ; Start the game! | |
| 447 | + | ; Go to song selection menu | |
| 448 | + | jsr show_menu | |
| 449 | + | lda #STATE_MENU | |
| 450 | + | sta game_state | |
| 451 | + | rts | |
| 452 | + | | |
| 453 | + | ; ---------------------------------------------------------------------------- | |
| 454 | + | ; Show Song Selection Menu | |
| 455 | + | ; ---------------------------------------------------------------------------- | |
| 456 | + | | |
| 457 | + | show_menu: | |
| 458 | + | ; Clear screen | |
| 459 | + | ldx #0 | |
| 460 | + | lda #CHAR_SPACE | |
| 461 | + | clear_menu: | |
| 462 | + | sta SCREEN,x | |
| 463 | + | sta SCREEN+$100,x | |
| 464 | + | sta SCREEN+$200,x | |
| 465 | + | sta SCREEN+$2E8,x | |
| 466 | + | inx | |
| 467 | + | bne clear_menu | |
| 468 | + | | |
| 469 | + | ; Initialise cursor | |
| 470 | + | lda #0 | |
| 471 | + | sta cursor_pos | |
| 472 | + | sta key_delay_count | |
| 473 | + | | |
| 474 | + | ; Draw menu title | |
| 475 | + | ldx #0 | |
| 476 | + | draw_menu_title: | |
| 477 | + | lda menu_title,x | |
| 478 | + | beq draw_menu_title_done | |
| 479 | + | sta SCREEN + (4 * 40) + 12,x | |
| 480 | + | lda #TITLE_COL | |
| 481 | + | sta COLRAM + (4 * 40) + 12,x | |
| 482 | + | inx | |
| 483 | + | jmp draw_menu_title | |
| 484 | + | draw_menu_title_done: | |
| 485 | + | | |
| 486 | + | ; Draw instructions | |
| 487 | + | ldx #0 | |
| 488 | + | draw_menu_instr: | |
| 489 | + | lda menu_instructions,x | |
| 490 | + | beq draw_menu_instr_done | |
| 491 | + | sta SCREEN + (22 * 40) + 8,x | |
| 492 | + | lda #SUBTITLE_COL | |
| 493 | + | sta COLRAM + (22 * 40) + 8,x | |
| 494 | + | inx | |
| 495 | + | jmp draw_menu_instr | |
| 496 | + | draw_menu_instr_done: | |
| 497 | + | | |
| 498 | + | ; Draw song list | |
| 499 | + | jsr draw_song_list | |
| 500 | + | | |
| 501 | + | rts | |
| 502 | + | | |
| 503 | + | menu_title: | |
| 504 | + | !scr "select a song" | |
| 505 | + | !byte 0 | |
| 506 | + | | |
| 507 | + | menu_instructions: | |
| 508 | + | !scr "up/down to select, fire to play" | |
| 509 | + | !byte 0 | |
| 510 | + | | |
| 511 | + | ; ---------------------------------------------------------------------------- | |
| 512 | + | ; Draw Song List | |
| 513 | + | ; ---------------------------------------------------------------------------- | |
| 514 | + | | |
| 515 | + | draw_song_list: | |
| 516 | + | ; Draw each song entry | |
| 517 | + | ; For now, just one song | |
| 518 | + | | |
| 519 | + | ; Song 1 | |
| 520 | + | ldx #0 | |
| 521 | + | draw_song1: | |
| 522 | + | lda song1_name,x | |
| 523 | + | beq draw_song1_done | |
| 524 | + | sta SCREEN + (10 * 40) + 14,x | |
| 525 | + | lda #MENU_COL | |
| 526 | + | sta COLRAM + (10 * 40) + 14,x | |
| 527 | + | inx | |
| 528 | + | jmp draw_song1 | |
| 529 | + | draw_song1_done: | |
| 530 | + | | |
| 531 | + | ; Draw cursor at current position | |
| 532 | + | jsr draw_cursor | |
| 533 | + | rts | |
| 534 | + | | |
| 535 | + | ; Song names | |
| 536 | + | song1_name: | |
| 537 | + | !scr "first steps" | |
| 538 | + | !byte 0 | |
| 539 | + | | |
| 540 | + | ; ---------------------------------------------------------------------------- | |
| 541 | + | ; Draw Menu Cursor | |
| 542 | + | ; ---------------------------------------------------------------------------- | |
| 543 | + | | |
| 544 | + | draw_cursor: | |
| 545 | + | ; Clear all potential cursor positions | |
| 546 | + | lda #CHAR_SPACE | |
| 547 | + | sta SCREEN + (10 * 40) + 12 | |
| 548 | + | ; (Room for more songs later) | |
| 549 | + | | |
| 550 | + | ; Draw cursor at current position | |
| 551 | + | lda cursor_pos | |
| 552 | + | asl ; Multiply by 2 (rows per song) | |
| 553 | + | clc | |
| 554 | + | adc #10 ; Start row | |
| 555 | + | tax | |
| 556 | + | | |
| 557 | + | ; Calculate screen position | |
| 558 | + | ; Row X * 40 = screen offset | |
| 559 | + | lda #0 | |
| 560 | + | sta ZP_PTR | |
| 561 | + | lda #0 | |
| 562 | + | sta ZP_PTR_HI | |
| 563 | + | | |
| 564 | + | ; Multiply row by 40 | |
| 565 | + | cursor_row_mult: | |
| 566 | + | cpx #0 | |
| 567 | + | beq cursor_row_done | |
| 568 | + | lda ZP_PTR | |
| 569 | + | clc | |
| 570 | + | adc #40 | |
| 571 | + | sta ZP_PTR | |
| 572 | + | lda ZP_PTR_HI | |
| 573 | + | adc #0 | |
| 574 | + | sta ZP_PTR_HI | |
| 575 | + | dex | |
| 576 | + | jmp cursor_row_mult | |
| 577 | + | | |
| 578 | + | cursor_row_done: | |
| 579 | + | ; Add column offset (12) | |
| 580 | + | lda ZP_PTR | |
| 581 | + | clc | |
| 582 | + | adc #12 | |
| 583 | + | sta ZP_PTR | |
| 584 | + | lda ZP_PTR_HI | |
| 585 | + | adc #0 | |
| 586 | + | sta ZP_PTR_HI | |
| 587 | + | | |
| 588 | + | ; Add screen base | |
| 589 | + | lda ZP_PTR | |
| 590 | + | clc | |
| 591 | + | adc #<SCREEN | |
| 592 | + | sta ZP_PTR | |
| 593 | + | lda ZP_PTR_HI | |
| 594 | + | adc #>SCREEN | |
| 595 | + | sta ZP_PTR_HI | |
| 596 | + | | |
| 597 | + | ; Draw cursor character | |
| 598 | + | lda #CHAR_CURSOR | |
| 599 | + | ldy #0 | |
| 600 | + | sta (ZP_PTR),y | |
| 601 | + | | |
| 602 | + | ; Set cursor colour | |
| 603 | + | lda ZP_PTR | |
| 604 | + | sec | |
| 605 | + | sbc #<SCREEN | |
| 606 | + | clc | |
| 607 | + | adc #<COLRAM | |
| 608 | + | sta ZP_PTR | |
| 609 | + | lda ZP_PTR_HI | |
| 610 | + | sbc #>SCREEN | |
| 611 | + | adc #>COLRAM | |
| 612 | + | sta ZP_PTR_HI | |
| 613 | + | | |
| 614 | + | lda #CURSOR_COL | |
| 615 | + | sta (ZP_PTR),y | |
| 616 | + | | |
| 617 | + | rts | |
| 618 | + | | |
| 619 | + | ; ---------------------------------------------------------------------------- | |
| 620 | + | ; Update Menu State | |
| 621 | + | ; ---------------------------------------------------------------------------- | |
| 622 | + | | |
| 623 | + | update_menu: | |
| 624 | + | ; Handle key delay | |
| 625 | + | lda key_delay_count | |
| 626 | + | beq menu_check_input | |
| 627 | + | dec key_delay_count | |
| 628 | + | jmp menu_check_fire | |
| 629 | + | | |
| 630 | + | menu_check_input: | |
| 631 | + | ; Check joystick up (or W key) | |
| 632 | + | lda CIA1_PRA | |
| 633 | + | and #$01 ; Bit 0 = up | |
| 634 | + | beq menu_up_pressed | |
| 635 | + | | |
| 636 | + | ; Check joystick down (or S key) | |
| 637 | + | lda CIA1_PRA | |
| 638 | + | and #$02 ; Bit 1 = down | |
| 639 | + | beq menu_down_pressed | |
| 640 | + | | |
| 641 | + | jmp menu_check_fire | |
| 642 | + | | |
| 643 | + | menu_up_pressed: | |
| 644 | + | lda cursor_pos | |
| 645 | + | beq menu_set_delay ; Already at top | |
| 646 | + | dec cursor_pos | |
| 647 | + | jsr play_menu_move | |
| 648 | + | jsr draw_cursor | |
| 649 | + | jmp menu_set_delay | |
| 650 | + | | |
| 651 | + | menu_down_pressed: | |
| 652 | + | lda cursor_pos | |
| 653 | + | cmp #NUM_SONGS-1 | |
| 654 | + | bcs menu_set_delay ; Already at bottom | |
| 655 | + | inc cursor_pos | |
| 656 | + | jsr play_menu_move | |
| 657 | + | jsr draw_cursor | |
| 658 | + | jmp menu_set_delay | |
| 659 | + | | |
| 660 | + | menu_set_delay: | |
| 661 | + | lda #KEY_DELAY | |
| 662 | + | sta key_delay_count | |
| 663 | + | | |
| 664 | + | menu_check_fire: | |
| 665 | + | ; Check for fire button | |
| 666 | + | lda CIA1_PRA | |
| 667 | + | and #$10 | |
| 668 | + | beq menu_fire_pressed | |
| 669 | + | | |
| 670 | + | ; Check space bar | |
| 671 | + | lda #$7F | |
| 672 | + | sta CIA1_PRA | |
| 673 | + | lda CIA1_PRB | |
| 674 | + | and #$10 | |
| 675 | + | beq menu_fire_pressed | |
| 676 | + | | |
| 677 | + | lda #$FF | |
| 678 | + | sta CIA1_PRA | |
| 679 | + | rts | |
| 680 | + | | |
| 681 | + | menu_fire_pressed: | |
| 682 | + | lda #$FF | |
| 683 | + | sta CIA1_PRA | |
| 684 | + | | |
| 685 | + | ; Play select sound | |
| 686 | + | jsr play_menu_select | |
| 687 | + | | |
| 688 | + | ; Store selected song | |
| 689 | + | lda cursor_pos | |
| 690 | + | sta selected_song | |
| 691 | + | | |
| 692 | + | ; Transition to game | |
| 693 | + | jsr transition_to_game | |
| 694 | + | rts | |
| 695 | + | | |
| 696 | + | ; ---------------------------------------------------------------------------- | |
| 697 | + | ; Transition to Game | |
| 698 | + | ; ---------------------------------------------------------------------------- | |
| 699 | + | | |
| 700 | + | transition_to_game: | |
| 701 | + | ; Set up the selected song (for now, only song 0) | |
| 702 | + | ; In future units, this will load different song data | |
| 703 | + | | |
| 704 | + | ; Initialise game | |
| 409 | 705 | jsr init_game | |
| 410 | 706 | lda #STATE_PLAYING | |
| 411 | 707 | sta game_state | |
| 708 | + | rts | |
| 709 | + | | |
| 710 | + | ; ---------------------------------------------------------------------------- | |
| 711 | + | ; Play Menu Move Sound | |
| 712 | + | ; ---------------------------------------------------------------------------- | |
| 713 | + | | |
| 714 | + | play_menu_move: | |
| 715 | + | lda #0 | |
| 716 | + | sta SID_V3_FREQ_LO | |
| 717 | + | lda #MENU_MOVE_FREQ | |
| 718 | + | sta SID_V3_FREQ_HI | |
| 719 | + | lda #$08 | |
| 720 | + | sta SID_V3_PWHI | |
| 721 | + | lda #MENU_MOVE_AD | |
| 722 | + | sta SID_V3_AD | |
| 723 | + | lda #MENU_MOVE_SR | |
| 724 | + | sta SID_V3_SR | |
| 725 | + | lda #MENU_MOVE_WAVE | |
| 726 | + | ora #$01 ; Gate on | |
| 727 | + | sta SID_V3_CTRL | |
| 412 | 728 | rts | |
| 413 | 729 | | |
| 414 | 730 | ; ---------------------------------------------------------------------------- | |
| ... | |||
| 432 | 748 | rts | |
| 433 | 749 | | |
| 434 | 750 | ; ---------------------------------------------------------------------------- | |
| 435 | - | ; Initialize Game (called when starting from title) | |
| 751 | + | ; Initialize Game (called when starting from menu) | |
| 436 | 752 | ; ---------------------------------------------------------------------------- | |
| 437 | 753 | | |
| 438 | 754 | init_game: | |
| ... | |||
| 485 | 801 | ; ---------------------------------------------------------------------------- | |
| 486 | 802 | | |
| 487 | 803 | update_results: | |
| 488 | - | ; Check for fire to return to title | |
| 804 | + | ; Check for fire to return to menu | |
| 489 | 805 | lda CIA1_PRA | |
| 490 | 806 | and #$10 | |
| 491 | 807 | beq results_fire | |
| ... | |||
| 505 | 821 | lda #$FF | |
| 506 | 822 | sta CIA1_PRA | |
| 507 | 823 | | |
| 508 | - | ; Play menu select sound | |
| 509 | 824 | jsr play_menu_select | |
| 510 | 825 | | |
| 511 | - | ; Return to title screen | |
| 512 | - | jsr show_title | |
| 513 | - | lda #STATE_TITLE | |
| 826 | + | ; Return to menu (not title) | |
| 827 | + | jsr show_menu | |
| 828 | + | lda #STATE_MENU | |
| 514 | 829 | sta game_state | |
| 515 | 830 | rts | |
| 516 | 831 | | |
| ... | |||
| 519 | 834 | ; ---------------------------------------------------------------------------- | |
| 520 | 835 | | |
| 521 | 836 | update_gameover: | |
| 522 | - | ; Check for fire to return to title | |
| 837 | + | ; Check for fire to return to menu | |
| 523 | 838 | lda CIA1_PRA | |
| 524 | 839 | and #$10 | |
| 525 | 840 | beq gameover_fire | |
| 526 | 841 | | |
| 842 | + | ; Also check space bar | |
| 527 | 843 | lda #$7F | |
| 528 | 844 | sta CIA1_PRA | |
| 529 | 845 | lda CIA1_PRB | |
| ... | |||
| 538 | 854 | lda #$FF | |
| 539 | 855 | sta CIA1_PRA | |
| 540 | 856 | | |
| 541 | - | ; Play menu select sound | |
| 542 | 857 | jsr play_menu_select | |
| 543 | - | | |
| 544 | - | ; Return to title screen | |
| 545 | - | jsr show_title | |
| 546 | - | lda #STATE_TITLE | |
| 547 | - | sta game_state | |
| 548 | - | rts | |
| 549 | - | | |
| 550 | - | ; ---------------------------------------------------------------------------- | |
| 551 | - | ; Check Song End | |
| 552 | - | ; ---------------------------------------------------------------------------- | |
| 553 | - | | |
| 554 | - | check_song_end: | |
| 555 | - | lda song_ended | |
| 556 | - | beq song_not_ended | |
| 557 | - | | |
| 558 | - | ldx #0 | |
| 559 | - | check_notes_clear: | |
| 560 | - | lda note_track,x | |
| 561 | - | bne notes_still_active | |
| 562 | - | inx | |
| 563 | - | cpx #MAX_NOTES | |
| 564 | - | bne check_notes_clear | |
| 565 | - | | |
| 566 | - | dec end_delay | |
| 567 | - | bne song_not_ended | |
| 568 | 858 | | |
| 569 | - | jsr show_results | |
| 570 | - | lda #STATE_RESULTS | |
| 859 | + | ; Return to menu (not title) | |
| 860 | + | jsr show_menu | |
| 861 | + | lda #STATE_MENU | |
| 571 | 862 | sta game_state | |
| 572 | - | | |
| 573 | - | notes_still_active: | |
| 574 | - | song_not_ended: | |
| 575 | - | rts | |
| 576 | - | | |
| 577 | - | ; ---------------------------------------------------------------------------- | |
| 578 | - | ; Initialize Song | |
| 579 | - | ; ---------------------------------------------------------------------------- | |
| 580 | - | | |
| 581 | - | init_song: | |
| 582 | - | lda #<song_data | |
| 583 | - | sta song_pos | |
| 584 | - | lda #>song_data | |
| 585 | - | sta song_pos_hi | |
| 586 | - | | |
| 587 | - | lda #0 | |
| 588 | - | sta frame_count | |
| 589 | - | sta beat_count | |
| 590 | - | sta song_beat | |
| 591 | - | sta border_flash | |
| 592 | - | sta song_ended | |
| 593 | - | | |
| 594 | - | lda #END_DELAY_FRAMES | |
| 595 | - | sta end_delay | |
| 596 | - | | |
| 597 | - | jsr display_progress | |
| 598 | - | rts | |
| 599 | - | | |
| 600 | - | ; ---------------------------------------------------------------------------- | |
| 601 | - | ; Advance Song | |
| 602 | - | ; ---------------------------------------------------------------------------- | |
| 603 | - | | |
| 604 | - | advance_song: | |
| 605 | - | lda song_ended | |
| 606 | - | bne advance_done | |
| 607 | - | | |
| 608 | - | inc beat_count | |
| 609 | - | inc song_beat | |
| 610 | - | | |
| 611 | - | lda song_beat | |
| 612 | - | cmp #SONG_LENGTH | |
| 613 | - | bcc song_continues | |
| 614 | - | | |
| 615 | - | lda #1 | |
| 616 | - | sta song_ended | |
| 617 | - | | |
| 618 | - | song_continues: | |
| 619 | - | jsr display_progress | |
| 620 | - | | |
| 621 | - | advance_done: | |
| 622 | - | rts | |
| 623 | - | | |
| 624 | - | ; ---------------------------------------------------------------------------- | |
| 625 | - | ; Display Progress | |
| 626 | - | ; ---------------------------------------------------------------------------- | |
| 627 | - | | |
| 628 | - | display_progress: | |
| 629 | - | lda song_beat | |
| 630 | - | lsr | |
| 631 | - | lsr | |
| 632 | - | sta temp_progress | |
| 633 | - | | |
| 634 | - | ldx #0 | |
| 635 | - | lda temp_progress | |
| 636 | - | beq draw_empty_progress | |
| 637 | - | | |
| 638 | - | draw_full_progress: | |
| 639 | - | lda #CHAR_BAR_FULL | |
| 640 | - | sta SCREEN + (PROGRESS_ROW * 40) + 12,x | |
| 641 | - | lda #PROGRESS_COL | |
| 642 | - | sta COLRAM + (PROGRESS_ROW * 40) + 12,x | |
| 643 | - | inx | |
| 644 | - | cpx temp_progress | |
| 645 | - | bne draw_full_progress | |
| 646 | - | | |
| 647 | - | draw_empty_progress: | |
| 648 | - | cpx #PROGRESS_WIDTH | |
| 649 | - | beq progress_done | |
| 650 | - | lda #CHAR_BAR_EMPTY | |
| 651 | - | sta SCREEN + (PROGRESS_ROW * 40) + 12,x | |
| 652 | - | lda #11 | |
| 653 | - | sta COLRAM + (PROGRESS_ROW * 40) + 12,x | |
| 654 | - | inx | |
| 655 | - | jmp draw_empty_progress | |
| 656 | - | | |
| 657 | - | progress_done: | |
| 658 | - | rts | |
| 659 | - | | |
| 660 | - | temp_progress: !byte 0 | |
| 661 | - | | |
| 662 | - | ; ---------------------------------------------------------------------------- | |
| 663 | - | ; Get Multiplier | |
| 664 | - | ; ---------------------------------------------------------------------------- | |
| 665 | - | | |
| 666 | - | get_multiplier: | |
| 667 | - | lda combo | |
| 668 | - | cmp #COMBO_TIER_4 | |
| 669 | - | bcs mult_4x | |
| 670 | - | cmp #COMBO_TIER_3 | |
| 671 | - | bcs mult_3x | |
| 672 | - | cmp #COMBO_TIER_2 | |
| 673 | - | bcs mult_2x | |
| 674 | - | | |
| 675 | - | lda #1 | |
| 676 | - | rts | |
| 677 | - | | |
| 678 | - | mult_2x: | |
| 679 | - | lda #2 | |
| 680 | - | rts | |
| 681 | - | | |
| 682 | - | mult_3x: | |
| 683 | - | lda #3 | |
| 684 | - | rts | |
| 685 | - | | |
| 686 | - | mult_4x: | |
| 687 | - | lda #4 | |
| 688 | - | rts | |
| 689 | - | | |
| 690 | - | ; ---------------------------------------------------------------------------- | |
| 691 | - | ; Display Combo | |
| 692 | - | ; ---------------------------------------------------------------------------- | |
| 693 | - | | |
| 694 | - | display_combo: | |
| 695 | - | ldx #0 | |
| 696 | - | draw_combo_label: | |
| 697 | - | lda combo_label,x | |
| 698 | - | beq draw_combo_value | |
| 699 | - | sta SCREEN + (COMBO_ROW * 40) + 12,x | |
| 700 | - | lda #11 | |
| 701 | - | sta COLRAM + (COMBO_ROW * 40) + 12,x | |
| 702 | - | inx | |
| 703 | - | jmp draw_combo_label | |
| 704 | - | | |
| 705 | - | draw_combo_value: | |
| 706 | - | lda combo | |
| 707 | - | | |
| 708 | - | ldx #0 | |
| 709 | - | combo_div_100: | |
| 710 | - | cmp #100 | |
| 711 | - | bcc combo_done_100 | |
| 712 | - | sec | |
| 713 | - | sbc #100 | |
| 714 | - | inx | |
| 715 | - | jmp combo_div_100 | |
| 716 | - | combo_done_100: | |
| 717 | - | pha | |
| 718 | - | txa | |
| 719 | - | ora #$30 | |
| 720 | - | sta SCREEN + (COMBO_ROW * 40) + 18 | |
| 721 | - | pla | |
| 722 | - | | |
| 723 | - | ldx #0 | |
| 724 | - | combo_div_10: | |
| 725 | - | cmp #10 | |
| 726 | - | bcc combo_done_10 | |
| 727 | - | sec | |
| 728 | - | sbc #10 | |
| 729 | - | inx | |
| 730 | - | jmp combo_div_10 | |
| 731 | - | combo_done_10: | |
| 732 | - | pha | |
| 733 | - | txa | |
| 734 | - | ora #$30 | |
| 735 | - | sta SCREEN + (COMBO_ROW * 40) + 19 | |
| 736 | - | pla | |
| 737 | - | | |
| 738 | - | ora #$30 | |
| 739 | - | sta SCREEN + (COMBO_ROW * 40) + 20 | |
| 740 | - | | |
| 741 | - | jsr get_multiplier | |
| 742 | - | cmp #4 | |
| 743 | - | beq combo_col_4x | |
| 744 | - | cmp #3 | |
| 745 | - | beq combo_col_3x | |
| 746 | - | cmp #2 | |
| 747 | - | beq combo_col_2x | |
| 748 | - | | |
| 749 | - | lda #11 | |
| 750 | - | jmp set_combo_col | |
| 751 | - | | |
| 752 | - | combo_col_2x: | |
| 753 | - | lda #7 | |
| 754 | - | jmp set_combo_col | |
| 755 | - | | |
| 756 | - | combo_col_3x: | |
| 757 | - | lda #5 | |
| 758 | - | jmp set_combo_col | |
| 759 | - | | |
| 760 | - | combo_col_4x: | |
| 761 | - | lda #1 | |
| 762 | - | | |
| 763 | - | set_combo_col: | |
| 764 | - | sta COLRAM + (COMBO_ROW * 40) + 18 | |
| 765 | - | sta COLRAM + (COMBO_ROW * 40) + 19 | |
| 766 | - | sta COLRAM + (COMBO_ROW * 40) + 20 | |
| 767 | - | | |
| 768 | - | jsr get_multiplier | |
| 769 | - | ora #$30 | |
| 770 | - | sta SCREEN + (COMBO_ROW * 40) + 22 | |
| 771 | - | lda #$18 | |
| 772 | - | sta SCREEN + (COMBO_ROW * 40) + 23 | |
| 773 | - | | |
| 774 | - | jsr get_multiplier | |
| 775 | - | cmp #4 | |
| 776 | - | beq mult_col_4x | |
| 777 | - | cmp #3 | |
| 778 | - | beq mult_col_3x | |
| 779 | - | cmp #2 | |
| 780 | - | beq mult_col_2x | |
| 781 | - | | |
| 782 | - | lda #11 | |
| 783 | - | jmp set_mult_col | |
| 784 | - | | |
| 785 | - | mult_col_2x: | |
| 786 | - | lda #7 | |
| 787 | - | jmp set_mult_col | |
| 788 | - | | |
| 789 | - | mult_col_3x: | |
| 790 | - | lda #5 | |
| 791 | - | jmp set_mult_col | |
| 792 | - | | |
| 793 | - | mult_col_4x: | |
| 794 | - | lda #1 | |
| 795 | - | | |
| 796 | - | set_mult_col: | |
| 797 | - | sta COLRAM + (COMBO_ROW * 40) + 22 | |
| 798 | - | sta COLRAM + (COMBO_ROW * 40) + 23 | |
| 799 | - | | |
| 800 | - | rts | |
| 801 | - | | |
| 802 | - | combo_label: | |
| 803 | - | !scr "combo:" | |
| 804 | - | !byte 0 | |
| 805 | - | | |
| 806 | - | ; ---------------------------------------------------------------------------- | |
| 807 | - | ; Increment Combo | |
| 808 | - | ; ---------------------------------------------------------------------------- | |
| 809 | - | | |
| 810 | - | increment_combo: | |
| 811 | - | inc combo | |
| 812 | - | | |
| 813 | - | lda combo | |
| 814 | - | cmp max_combo | |
| 815 | - | bcc combo_not_max | |
| 816 | - | sta max_combo | |
| 817 | - | combo_not_max: | |
| 818 | - | | |
| 819 | - | jsr display_combo | |
| 820 | 863 | rts | |
| 821 | 864 | | |
| 822 | 865 | ; ---------------------------------------------------------------------------- | |
| 823 | - | ; Break Combo | |
| 866 | + | ; Initialize Screen (Gameplay) | |
| 824 | 867 | ; ---------------------------------------------------------------------------- | |
| 825 | - | | |
| 826 | - | break_combo: | |
| 827 | - | lda combo | |
| 828 | - | beq combo_already_zero | |
| 829 | - | | |
| 830 | - | lda #0 | |
| 831 | - | sta combo | |
| 832 | - | jsr display_combo | |
| 833 | 868 | | |
| 834 | - | combo_already_zero: | |
| 835 | - | rts | |
| 869 | + | init_screen: | |
| 870 | + | ; Enable custom charset | |
| 871 | + | lda #$1C ; Character ROM at $3000 | |
| 872 | + | sta CHARPTR | |
| 836 | 873 | | |
| 837 | - | ; ---------------------------------------------------------------------------- | |
| 838 | - | ; Show Results Screen | |
| 839 | - | ; ---------------------------------------------------------------------------- | |
| 874 | + | ; Set colours | |
| 875 | + | lda #BORDER_COL | |
| 876 | + | sta BORDER | |
| 877 | + | lda #BG_COL | |
| 878 | + | sta BGCOL | |
| 840 | 879 | | |
| 841 | - | show_results: | |
| 880 | + | ; Clear screen | |
| 842 | 881 | ldx #0 | |
| 843 | 882 | lda #CHAR_SPACE | |
| 844 | - | clear_for_results: | |
| 883 | + | clear_screen: | |
| 845 | 884 | sta SCREEN,x | |
| 846 | 885 | sta SCREEN+$100,x | |
| 847 | 886 | sta SCREEN+$200,x | |
| 848 | 887 | sta SCREEN+$2E8,x | |
| 849 | 888 | inx | |
| 850 | - | bne clear_for_results | |
| 889 | + | bne clear_screen | |
| 851 | 890 | | |
| 891 | + | ; Draw tracks | |
| 852 | 892 | ldx #0 | |
| 853 | - | draw_results_title: | |
| 854 | - | lda results_title,x | |
| 855 | - | beq draw_results_title_done | |
| 856 | - | sta SCREEN + (3 * 40) + 14,x | |
| 857 | - | lda #1 | |
| 858 | - | sta COLRAM + (3 * 40) + 14,x | |
| 893 | + | draw_tracks: | |
| 894 | + | lda #CHAR_TRACK | |
| 895 | + | sta SCREEN + (TRACK1_ROW * 40),x | |
| 896 | + | sta SCREEN + (TRACK2_ROW * 40),x | |
| 897 | + | sta SCREEN + (TRACK3_ROW * 40),x | |
| 898 | + | lda #TRACK_LINE_COL | |
| 899 | + | sta COLRAM + (TRACK1_ROW * 40),x | |
| 900 | + | sta COLRAM + (TRACK2_ROW * 40),x | |
| 901 | + | sta COLRAM + (TRACK3_ROW * 40),x | |
| 859 | 902 | inx | |
| 860 | - | jmp draw_results_title | |
| 861 | - | draw_results_title_done: | |
| 903 | + | cpx #38 | |
| 904 | + | bne draw_tracks | |
| 862 | 905 | | |
| 863 | - | ldx #0 | |
| 864 | - | draw_final_score_label: | |
| 865 | - | lda final_score_label,x | |
| 866 | - | beq draw_final_score_done | |
| 867 | - | sta SCREEN + (6 * 40) + 10,x | |
| 868 | - | lda #7 | |
| 869 | - | sta COLRAM + (6 * 40) + 10,x | |
| 870 | - | inx | |
| 871 | - | jmp draw_final_score_label | |
| 872 | - | draw_final_score_done: | |
| 873 | - | jsr display_final_score | |
| 906 | + | ; Draw hit zones | |
| 907 | + | lda #CHAR_HITZONE | |
| 908 | + | sta SCREEN + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN | |
| 909 | + | sta SCREEN + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN | |
| 910 | + | sta SCREEN + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN | |
| 911 | + | lda #HIT_ZONE_COL | |
| 912 | + | sta COLRAM + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN | |
| 913 | + | sta COLRAM + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN | |
| 914 | + | sta COLRAM + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN | |
| 874 | 915 | | |
| 875 | - | ldx #0 | |
| 876 | - | draw_perfects_label: | |
| 877 | - | lda perfects_label,x | |
| 878 | - | beq draw_perfects_done | |
| 879 | - | sta SCREEN + (8 * 40) + 10,x | |
| 916 | + | ; Draw track labels | |
| 917 | + | lda #$31 ; "1" | |
| 918 | + | sta SCREEN + (TRACK1_ROW * 40) | |
| 919 | + | lda #$32 ; "2" | |
| 920 | + | sta SCREEN + (TRACK2_ROW * 40) | |
| 921 | + | lda #$33 ; "3" | |
| 922 | + | sta SCREEN + (TRACK3_ROW * 40) | |
| 880 | 923 | lda #1 | |
| 881 | - | sta COLRAM + (8 * 40) + 10,x | |
| 882 | - | inx | |
| 883 | - | jmp draw_perfects_label | |
| 884 | - | draw_perfects_done: | |
| 885 | - | lda perfect_count | |
| 886 | - | jsr display_stat_at_8 | |
| 924 | + | sta COLRAM + (TRACK1_ROW * 40) | |
| 925 | + | sta COLRAM + (TRACK2_ROW * 40) | |
| 926 | + | sta COLRAM + (TRACK3_ROW * 40) | |
| 887 | 927 | | |
| 928 | + | ; Draw HUD labels | |
| 888 | 929 | ldx #0 | |
| 889 | - | draw_goods_label: | |
| 890 | - | lda goods_label,x | |
| 891 | - | beq draw_goods_done | |
| 892 | - | sta SCREEN + (9 * 40) + 10,x | |
| 930 | + | draw_score_label: | |
| 931 | + | lda score_label,x | |
| 932 | + | beq draw_miss_label_start | |
| 933 | + | sta SCREEN,x | |
| 893 | 934 | lda #7 | |
| 894 | - | sta COLRAM + (9 * 40) + 10,x | |
| 935 | + | sta COLRAM,x | |
| 895 | 936 | inx | |
| 896 | - | jmp draw_goods_label | |
| 897 | - | draw_goods_done: | |
| 898 | - | lda good_count | |
| 899 | - | jsr display_stat_at_9 | |
| 937 | + | jmp draw_score_label | |
| 900 | 938 | | |
| 939 | + | draw_miss_label_start: | |
| 901 | 940 | ldx #0 | |
| 902 | - | draw_misses_label: | |
| 903 | - | lda misses_label,x | |
| 904 | - | beq draw_misses_done | |
| 905 | - | sta SCREEN + (10 * 40) + 10,x | |
| 941 | + | draw_miss_label: | |
| 942 | + | lda miss_label,x | |
| 943 | + | beq draw_combo_label_start | |
| 944 | + | sta SCREEN + 14,x | |
| 906 | 945 | lda #2 | |
| 907 | - | sta COLRAM + (10 * 40) + 10,x | |
| 946 | + | sta COLRAM + 14,x | |
| 908 | 947 | inx | |
| 909 | - | jmp draw_misses_label | |
| 910 | - | draw_misses_done: | |
| 911 | - | lda miss_count | |
| 912 | - | jsr display_stat_at_10 | |
| 948 | + | jmp draw_miss_label | |
| 913 | 949 | | |
| 950 | + | draw_combo_label_start: | |
| 914 | 951 | ldx #0 | |
| 915 | - | draw_max_combo_label: | |
| 916 | - | lda max_combo_label,x | |
| 917 | - | beq draw_max_combo_done | |
| 918 | - | sta SCREEN + (12 * 40) + 10,x | |
| 919 | - | lda #13 | |
| 920 | - | sta COLRAM + (12 * 40) + 10,x | |
| 952 | + | draw_combo_label: | |
| 953 | + | lda combo_label,x | |
| 954 | + | beq draw_health_label_start | |
| 955 | + | sta SCREEN + (COMBO_ROW * 40) + 27,x | |
| 956 | + | lda #COMBO_COL | |
| 957 | + | sta COLRAM + (COMBO_ROW * 40) + 27,x | |
| 921 | 958 | inx | |
| 922 | - | jmp draw_max_combo_label | |
| 923 | - | draw_max_combo_done: | |
| 924 | - | lda max_combo | |
| 925 | - | jsr display_stat_at_12 | |
| 959 | + | jmp draw_combo_label | |
| 926 | 960 | | |
| 961 | + | draw_health_label_start: | |
| 927 | 962 | ldx #0 | |
| 928 | - | draw_accuracy_label: | |
| 929 | - | lda accuracy_label,x | |
| 930 | - | beq draw_accuracy_done | |
| 931 | - | sta SCREEN + (14 * 40) + 10,x | |
| 932 | - | lda #5 | |
| 933 | - | sta COLRAM + (14 * 40) + 10,x | |
| 963 | + | draw_health_label: | |
| 964 | + | lda health_label,x | |
| 965 | + | beq draw_progress_label_start | |
| 966 | + | sta SCREEN + (HEALTH_ROW * 40),x | |
| 967 | + | lda #HEALTH_COL | |
| 968 | + | sta COLRAM + (HEALTH_ROW * 40),x | |
| 934 | 969 | inx | |
| 935 | - | jmp draw_accuracy_label | |
| 936 | - | draw_accuracy_done: | |
| 937 | - | jsr calculate_accuracy | |
| 938 | - | jsr display_accuracy | |
| 970 | + | jmp draw_health_label | |
| 939 | 971 | | |
| 972 | + | draw_progress_label_start: | |
| 940 | 973 | ldx #0 | |
| 941 | - | draw_press_key: | |
| 942 | - | lda press_fire_results,x | |
| 943 | - | beq draw_press_key_done | |
| 944 | - | sta SCREEN + (18 * 40) + 9,x | |
| 945 | - | lda #7 | |
| 946 | - | sta COLRAM + (18 * 40) + 9,x | |
| 974 | + | draw_progress_label: | |
| 975 | + | lda progress_label,x | |
| 976 | + | beq labels_done | |
| 977 | + | sta SCREEN + (PROGRESS_ROW * 40),x | |
| 978 | + | lda #PROGRESS_COL | |
| 979 | + | sta COLRAM + (PROGRESS_ROW * 40),x | |
| 947 | 980 | inx | |
| 948 | - | jmp draw_press_key | |
| 949 | - | draw_press_key_done: | |
| 981 | + | jmp draw_progress_label | |
| 950 | 982 | | |
| 951 | - | lda #5 ; Green border for success | |
| 952 | - | sta BORDER | |
| 983 | + | labels_done: | |
| 984 | + | ; Draw song name on gameplay screen | |
| 985 | + | ldx #0 | |
| 986 | + | draw_song_name: | |
| 987 | + | lda selected_song | |
| 988 | + | ; For now only song 0 | |
| 989 | + | lda song1_name,x | |
| 990 | + | beq draw_song_name_done | |
| 991 | + | sta SCREEN + 28,x | |
| 992 | + | lda #11 | |
| 993 | + | sta COLRAM + 28,x | |
| 994 | + | inx | |
| 995 | + | jmp draw_song_name | |
| 996 | + | draw_song_name_done: | |
| 953 | 997 | | |
| 954 | 998 | rts | |
| 955 | - | | |
| 956 | - | results_title: | |
| 957 | - | !scr "song complete!" | |
| 958 | - | !byte 0 | |
| 959 | - | | |
| 960 | - | final_score_label: | |
| 961 | - | !scr "final score:" | |
| 962 | - | !byte 0 | |
| 963 | - | | |
| 964 | - | perfects_label: | |
| 965 | - | !scr "perfects:" | |
| 966 | - | !byte 0 | |
| 967 | 999 | | |
| 968 | - | goods_label: | |
| 969 | - | !scr "goods:" | |
| 1000 | + | score_label: | |
| 1001 | + | !scr "score:" | |
| 970 | 1002 | !byte 0 | |
| 971 | - | | |
| 972 | - | misses_label: | |
| 973 | - | !scr "misses:" | |
| 1003 | + | miss_label: | |
| 1004 | + | !scr "miss:" | |
| 974 | 1005 | !byte 0 | |
| 975 | - | | |
| 976 | - | max_combo_label: | |
| 977 | - | !scr "max combo:" | |
| 1006 | + | combo_label: | |
| 1007 | + | !scr "combo:" | |
| 978 | 1008 | !byte 0 | |
| 979 | - | | |
| 980 | - | accuracy_label: | |
| 981 | - | !scr "accuracy:" | |
| 1009 | + | health_label: | |
| 1010 | + | !scr "health:" | |
| 982 | 1011 | !byte 0 | |
| 983 | - | | |
| 984 | - | press_fire_results: | |
| 985 | - | !scr "press fire for title" | |
| 1012 | + | progress_label: | |
| 1013 | + | !scr "song:" | |
| 986 | 1014 | !byte 0 | |
| 987 | 1015 | | |
| 988 | 1016 | ; ---------------------------------------------------------------------------- | |
| 989 | - | ; Display Final Score | |
| 1017 | + | ; Initialize Notes | |
| 990 | 1018 | ; ---------------------------------------------------------------------------- | |
| 991 | - | | |
| 992 | - | display_final_score: | |
| 993 | - | lda score_lo | |
| 994 | - | sta work_lo | |
| 995 | - | lda score_hi | |
| 996 | - | sta work_hi | |
| 997 | - | | |
| 998 | - | ldx #0 | |
| 999 | - | fs_div_10000: | |
| 1000 | - | lda work_lo | |
| 1001 | - | sec | |
| 1002 | - | sbc #<10000 | |
| 1003 | - | tay | |
| 1004 | - | lda work_hi | |
| 1005 | - | sbc #>10000 | |
| 1006 | - | bcc fs_done_10000 | |
| 1007 | - | sta work_hi | |
| 1008 | - | sty work_lo | |
| 1009 | - | inx | |
| 1010 | - | jmp fs_div_10000 | |
| 1011 | - | fs_done_10000: | |
| 1012 | - | txa | |
| 1013 | - | ora #$30 | |
| 1014 | - | sta SCREEN + (6 * 40) + 23 | |
| 1015 | - | | |
| 1016 | - | ldx #0 | |
| 1017 | - | fs_div_1000: | |
| 1018 | - | lda work_lo | |
| 1019 | - | sec | |
| 1020 | - | sbc #<1000 | |
| 1021 | - | tay | |
| 1022 | - | lda work_hi | |
| 1023 | - | sbc #>1000 | |
| 1024 | - | bcc fs_done_1000 | |
| 1025 | - | sta work_hi | |
| 1026 | - | sty work_lo | |
| 1027 | - | inx | |
| 1028 | - | jmp fs_div_1000 | |
| 1029 | - | fs_done_1000: | |
| 1030 | - | txa | |
| 1031 | - | ora #$30 | |
| 1032 | - | sta SCREEN + (6 * 40) + 24 | |
| 1033 | - | | |
| 1034 | - | ldx #0 | |
| 1035 | - | fs_div_100: | |
| 1036 | - | lda work_lo | |
| 1037 | - | sec | |
| 1038 | - | sbc #100 | |
| 1039 | - | bcc fs_done_100 | |
| 1040 | - | sta work_lo | |
| 1041 | - | inx | |
| 1042 | - | jmp fs_div_100 | |
| 1043 | - | fs_done_100: | |
| 1044 | - | txa | |
| 1045 | - | ora #$30 | |
| 1046 | - | sta SCREEN + (6 * 40) + 25 | |
| 1047 | 1019 | | |
| 1020 | + | init_notes: | |
| 1048 | 1021 | ldx #0 | |
| 1049 | - | fs_div_10: | |
| 1050 | - | lda work_lo | |
| 1051 | - | sec | |
| 1052 | - | sbc #10 | |
| 1053 | - | bcc fs_done_10 | |
| 1054 | - | sta work_lo | |
| 1022 | + | lda #0 | |
| 1023 | + | clear_notes: | |
| 1024 | + | sta note_track,x | |
| 1025 | + | sta note_col,x | |
| 1026 | + | sta note_freq,x | |
| 1055 | 1027 | inx | |
| 1056 | - | jmp fs_div_10 | |
| 1057 | - | fs_done_10: | |
| 1058 | - | txa | |
| 1059 | - | ora #$30 | |
| 1060 | - | sta SCREEN + (6 * 40) + 26 | |
| 1061 | - | | |
| 1062 | - | lda work_lo | |
| 1063 | - | ora #$30 | |
| 1064 | - | sta SCREEN + (6 * 40) + 27 | |
| 1065 | - | | |
| 1066 | - | lda #7 | |
| 1067 | - | sta COLRAM + (6 * 40) + 23 | |
| 1068 | - | sta COLRAM + (6 * 40) + 24 | |
| 1069 | - | sta COLRAM + (6 * 40) + 25 | |
| 1070 | - | sta COLRAM + (6 * 40) + 26 | |
| 1071 | - | sta COLRAM + (6 * 40) + 27 | |
| 1072 | - | | |
| 1028 | + | cpx #MAX_NOTES | |
| 1029 | + | bne clear_notes | |
| 1073 | 1030 | rts | |
| 1074 | 1031 | | |
| 1075 | 1032 | ; ---------------------------------------------------------------------------- | |
| 1076 | - | ; Display Stats | |
| 1033 | + | ; Initialize Score | |
| 1077 | 1034 | ; ---------------------------------------------------------------------------- | |
| 1078 | - | | |
| 1079 | - | display_stat_at_8: | |
| 1080 | - | ldx #0 | |
| 1081 | - | stat8_div: | |
| 1082 | - | cmp #10 | |
| 1083 | - | bcc stat8_done | |
| 1084 | - | sec | |
| 1085 | - | sbc #10 | |
| 1086 | - | inx | |
| 1087 | - | jmp stat8_div | |
| 1088 | - | stat8_done: | |
| 1089 | - | pha | |
| 1090 | - | txa | |
| 1091 | - | ora #$30 | |
| 1092 | - | sta SCREEN + (8 * 40) + 23 | |
| 1093 | - | pla | |
| 1094 | - | ora #$30 | |
| 1095 | - | sta SCREEN + (8 * 40) + 24 | |
| 1096 | - | lda #1 | |
| 1097 | - | sta COLRAM + (8 * 40) + 23 | |
| 1098 | - | sta COLRAM + (8 * 40) + 24 | |
| 1099 | - | rts | |
| 1100 | 1035 | | |
| 1101 | - | display_stat_at_9: | |
| 1102 | - | ldx #0 | |
| 1103 | - | stat9_div: | |
| 1104 | - | cmp #10 | |
| 1105 | - | bcc stat9_done | |
| 1106 | - | sec | |
| 1107 | - | sbc #10 | |
| 1108 | - | inx | |
| 1109 | - | jmp stat9_div | |
| 1110 | - | stat9_done: | |
| 1111 | - | pha | |
| 1112 | - | txa | |
| 1113 | - | ora #$30 | |
| 1114 | - | sta SCREEN + (9 * 40) + 23 | |
| 1115 | - | pla | |
| 1116 | - | ora #$30 | |
| 1117 | - | sta SCREEN + (9 * 40) + 24 | |
| 1118 | - | lda #7 | |
| 1119 | - | sta COLRAM + (9 * 40) + 23 | |
| 1120 | - | sta COLRAM + (9 * 40) + 24 | |
| 1036 | + | init_score: | |
| 1037 | + | lda #0 | |
| 1038 | + | sta score_lo | |
| 1039 | + | sta score_hi | |
| 1040 | + | sta miss_count | |
| 1041 | + | sta perfect_count | |
| 1042 | + | sta good_count | |
| 1043 | + | jsr display_score | |
| 1044 | + | jsr display_misses | |
| 1121 | 1045 | rts | |
| 1122 | 1046 | | |
| 1123 | - | display_stat_at_10: | |
| 1124 | - | ldx #0 | |
| 1125 | - | stat10_div: | |
| 1126 | - | cmp #10 | |
| 1127 | - | bcc stat10_done | |
| 1128 | - | sec | |
| 1129 | - | sbc #10 | |
| 1130 | - | inx | |
| 1131 | - | jmp stat10_div | |
| 1132 | - | stat10_done: | |
| 1133 | - | pha | |
| 1134 | - | txa | |
| 1135 | - | ora #$30 | |
| 1136 | - | sta SCREEN + (10 * 40) + 23 | |
| 1137 | - | pla | |
| 1138 | - | ora #$30 | |
| 1139 | - | sta SCREEN + (10 * 40) + 24 | |
| 1140 | - | lda #2 | |
| 1141 | - | sta COLRAM + (10 * 40) + 23 | |
| 1142 | - | sta COLRAM + (10 * 40) + 24 | |
| 1143 | - | rts | |
| 1047 | + | ; ---------------------------------------------------------------------------- | |
| 1048 | + | ; Initialize Health | |
| 1049 | + | ; ---------------------------------------------------------------------------- | |
| 1144 | 1050 | | |
| 1145 | - | display_stat_at_12: | |
| 1146 | - | ldx #0 | |
| 1147 | - | stat12_div: | |
| 1148 | - | cmp #10 | |
| 1149 | - | bcc stat12_done | |
| 1150 | - | sec | |
| 1151 | - | sbc #10 | |
| 1152 | - | inx | |
| 1153 | - | jmp stat12_div | |
| 1154 | - | stat12_done: | |
| 1155 | - | pha | |
| 1156 | - | txa | |
| 1157 | - | ora #$30 | |
| 1158 | - | sta SCREEN + (12 * 40) + 23 | |
| 1159 | - | pla | |
| 1160 | - | ora #$30 | |
| 1161 | - | sta SCREEN + (12 * 40) + 24 | |
| 1162 | - | lda #13 | |
| 1163 | - | sta COLRAM + (12 * 40) + 23 | |
| 1164 | - | sta COLRAM + (12 * 40) + 24 | |
| 1051 | + | init_health: | |
| 1052 | + | lda #HEALTH_START | |
| 1053 | + | sta health | |
| 1054 | + | jsr display_health | |
| 1165 | 1055 | rts | |
| 1166 | 1056 | | |
| 1167 | 1057 | ; ---------------------------------------------------------------------------- | |
| 1168 | - | ; Calculate Accuracy | |
| 1058 | + | ; Initialize Song | |
| 1169 | 1059 | ; ---------------------------------------------------------------------------- | |
| 1170 | - | | |
| 1171 | - | calculate_accuracy: | |
| 1172 | - | lda perfect_count | |
| 1173 | - | clc | |
| 1174 | - | adc good_count | |
| 1175 | - | sta total_hits | |
| 1176 | - | | |
| 1177 | - | clc | |
| 1178 | - | adc miss_count | |
| 1179 | - | sta total_notes | |
| 1180 | - | | |
| 1181 | - | beq accuracy_zero | |
| 1182 | 1060 | | |
| 1183 | - | lda total_hits | |
| 1184 | - | sta dividend_lo | |
| 1061 | + | init_song: | |
| 1185 | 1062 | lda #0 | |
| 1186 | - | sta dividend_hi | |
| 1187 | - | | |
| 1188 | - | ldx #100 | |
| 1189 | - | mult_loop: | |
| 1190 | - | dex | |
| 1191 | - | beq mult_done | |
| 1192 | - | lda dividend_lo | |
| 1193 | - | clc | |
| 1194 | - | adc total_hits | |
| 1195 | - | sta dividend_lo | |
| 1196 | - | lda dividend_hi | |
| 1197 | - | adc #0 | |
| 1198 | - | sta dividend_hi | |
| 1199 | - | jmp mult_loop | |
| 1200 | - | mult_done: | |
| 1063 | + | sta frame_count | |
| 1064 | + | sta beat_count | |
| 1065 | + | sta song_beat | |
| 1066 | + | sta song_ended | |
| 1201 | 1067 | | |
| 1202 | - | lda #0 | |
| 1203 | - | sta accuracy | |
| 1204 | - | div_loop: | |
| 1205 | - | lda dividend_lo | |
| 1206 | - | sec | |
| 1207 | - | sbc total_notes | |
| 1208 | - | tay | |
| 1209 | - | lda dividend_hi | |
| 1210 | - | sbc #0 | |
| 1211 | - | bcc div_done | |
| 1212 | - | sta dividend_hi | |
| 1213 | - | sty dividend_lo | |
| 1214 | - | inc accuracy | |
| 1215 | - | jmp div_loop | |
| 1216 | - | div_done: | |
| 1217 | - | rts | |
| 1068 | + | ; Point to song data (for now, only one song) | |
| 1069 | + | lda #<song_data | |
| 1070 | + | sta song_pos | |
| 1071 | + | lda #>song_data | |
| 1072 | + | sta song_pos_hi | |
| 1218 | 1073 | | |
| 1219 | - | accuracy_zero: | |
| 1220 | - | lda #0 | |
| 1221 | - | sta accuracy | |
| 1074 | + | jsr display_progress | |
| 1222 | 1075 | rts | |
| 1223 | - | | |
| 1224 | - | total_hits: !byte 0 | |
| 1225 | - | total_notes: !byte 0 | |
| 1226 | - | dividend_lo: !byte 0 | |
| 1227 | - | dividend_hi: !byte 0 | |
| 1228 | - | accuracy: !byte 0 | |
| 1229 | 1076 | | |
| 1230 | 1077 | ; ---------------------------------------------------------------------------- | |
| 1231 | - | ; Display Accuracy | |
| 1078 | + | ; Initialize SID | |
| 1232 | 1079 | ; ---------------------------------------------------------------------------- | |
| 1233 | - | | |
| 1234 | - | display_accuracy: | |
| 1235 | - | lda accuracy | |
| 1236 | 1080 | | |
| 1237 | - | ldx #0 | |
| 1238 | - | acc_div_100: | |
| 1239 | - | cmp #100 | |
| 1240 | - | bcc acc_done_100 | |
| 1241 | - | sec | |
| 1242 | - | sbc #100 | |
| 1243 | - | inx | |
| 1244 | - | jmp acc_div_100 | |
| 1245 | - | acc_done_100: | |
| 1246 | - | pha | |
| 1247 | - | txa | |
| 1248 | - | ora #$30 | |
| 1249 | - | sta SCREEN + (14 * 40) + 23 | |
| 1250 | - | pla | |
| 1081 | + | init_sid: | |
| 1082 | + | ; Clear SID | |
| 1083 | + | ldx #$18 | |
| 1084 | + | lda #0 | |
| 1085 | + | clear_sid: | |
| 1086 | + | sta SID,x | |
| 1087 | + | dex | |
| 1088 | + | bpl clear_sid | |
| 1251 | 1089 | | |
| 1252 | - | ldx #0 | |
| 1253 | - | acc_div_10: | |
| 1254 | - | cmp #10 | |
| 1255 | - | bcc acc_done_10 | |
| 1256 | - | sec | |
| 1257 | - | sbc #10 | |
| 1258 | - | inx | |
| 1259 | - | jmp acc_div_10 | |
| 1260 | - | acc_done_10: | |
| 1261 | - | pha | |
| 1262 | - | txa | |
| 1263 | - | ora #$30 | |
| 1264 | - | sta SCREEN + (14 * 40) + 24 | |
| 1265 | - | pla | |
| 1090 | + | ; Set volume | |
| 1091 | + | lda #$0F | |
| 1092 | + | sta SID_VOLUME | |
| 1266 | 1093 | | |
| 1267 | - | ora #$30 | |
| 1268 | - | sta SCREEN + (14 * 40) + 25 | |
| 1094 | + | ; Set pulse widths | |
| 1095 | + | lda #PULSE_WIDTH | |
| 1096 | + | sta SID_V1_PWHI | |
| 1097 | + | sta SID_V2_PWHI | |
| 1098 | + | sta SID_V3_PWHI | |
| 1269 | 1099 | | |
| 1270 | - | lda #$25 ; % symbol | |
| 1271 | - | sta SCREEN + (14 * 40) + 26 | |
| 1100 | + | ; Set ADSR for all voices | |
| 1101 | + | lda #VOICE_AD | |
| 1102 | + | sta SID_V1_AD | |
| 1103 | + | sta SID_V2_AD | |
| 1104 | + | sta SID_V3_AD | |
| 1272 | 1105 | | |
| 1273 | - | lda #5 | |
| 1274 | - | sta COLRAM + (14 * 40) + 23 | |
| 1275 | - | sta COLRAM + (14 * 40) + 24 | |
| 1276 | - | sta COLRAM + (14 * 40) + 25 | |
| 1277 | - | sta COLRAM + (14 * 40) + 26 | |
| 1106 | + | lda #VOICE_SR | |
| 1107 | + | sta SID_V1_SR | |
| 1108 | + | sta SID_V2_SR | |
| 1109 | + | sta SID_V3_SR | |
| 1278 | 1110 | | |
| 1279 | 1111 | rts | |
| 1280 | 1112 | | |
| 1281 | 1113 | ; ---------------------------------------------------------------------------- | |
| 1282 | - | ; Copy Character Set | |
| 1114 | + | ; Copy Custom Charset | |
| 1283 | 1115 | ; ---------------------------------------------------------------------------- | |
| 1284 | 1116 | | |
| 1285 | 1117 | copy_charset: | |
| 1118 | + | ; Copy default ROM charset to RAM first | |
| 1286 | 1119 | sei | |
| 1287 | - | | |
| 1288 | - | lda $01 | |
| 1289 | - | pha | |
| 1290 | - | and #$FB | |
| 1120 | + | lda #$33 | |
| 1291 | 1121 | sta $01 | |
| 1292 | 1122 | | |
| 1293 | 1123 | ldx #0 | |
| 1294 | - | copy_loop: | |
| 1124 | + | copy_rom_chars: | |
| 1295 | 1125 | lda $D000,x | |
| 1296 | 1126 | sta CHARSET,x | |
| 1297 | 1127 | lda $D100,x | |
| ... | |||
| 1309 | 1139 | lda $D700,x | |
| 1310 | 1140 | sta CHARSET+$700,x | |
| 1311 | 1141 | inx | |
| 1312 | - | bne copy_loop | |
| 1142 | + | bne copy_rom_chars | |
| 1313 | 1143 | | |
| 1314 | - | pla | |
| 1144 | + | lda #$37 | |
| 1315 | 1145 | sta $01 | |
| 1316 | - | | |
| 1317 | 1146 | cli | |
| 1318 | - | | |
| 1319 | - | jsr define_custom_chars | |
| 1320 | - | | |
| 1321 | - | lda #$1C | |
| 1322 | - | sta CHARPTR | |
| 1323 | - | | |
| 1324 | - | rts | |
| 1325 | 1147 | | |
| 1326 | - | ; ---------------------------------------------------------------------------- | |
| 1327 | - | ; Define Custom Characters | |
| 1328 | - | ; ---------------------------------------------------------------------------- | |
| 1148 | + | ; Now add custom characters | |
| 1329 | 1149 | | |
| 1330 | - | define_custom_chars: | |
| 1331 | - | ; Note character - arrow/chevron shape | |
| 1332 | - | lda #%00000110 | |
| 1333 | - | sta CHARSET + (CHAR_NOTE * 8) + 0 | |
| 1334 | - | lda #%00011110 | |
| 1335 | - | sta CHARSET + (CHAR_NOTE * 8) + 1 | |
| 1150 | + | ; Character 128 - Note (solid circle) | |
| 1151 | + | lda #%00111100 | |
| 1152 | + | sta CHARSET + (128 * 8) + 0 | |
| 1336 | 1153 | lda #%01111110 | |
| 1337 | - | sta CHARSET + (CHAR_NOTE * 8) + 2 | |
| 1338 | - | lda #%11111110 | |
| 1339 | - | sta CHARSET + (CHAR_NOTE * 8) + 3 | |
| 1340 | - | lda #%11111110 | |
| 1341 | - | sta CHARSET + (CHAR_NOTE * 8) + 4 | |
| 1154 | + | sta CHARSET + (128 * 8) + 1 | |
| 1155 | + | lda #%11111111 | |
| 1156 | + | sta CHARSET + (128 * 8) + 2 | |
| 1157 | + | lda #%11111111 | |
| 1158 | + | sta CHARSET + (128 * 8) + 3 | |
| 1159 | + | lda #%11111111 | |
| 1160 | + | sta CHARSET + (128 * 8) + 4 | |
| 1161 | + | lda #%11111111 | |
| 1162 | + | sta CHARSET + (128 * 8) + 5 | |
| 1342 | 1163 | lda #%01111110 | |
| 1343 | - | sta CHARSET + (CHAR_NOTE * 8) + 5 | |
| 1344 | - | lda #%00011110 | |
| 1345 | - | sta CHARSET + (CHAR_NOTE * 8) + 6 | |
| 1346 | - | lda #%00000110 | |
| 1347 | - | sta CHARSET + (CHAR_NOTE * 8) + 7 | |
| 1164 | + | sta CHARSET + (128 * 8) + 6 | |
| 1165 | + | lda #%00111100 | |
| 1166 | + | sta CHARSET + (128 * 8) + 7 | |
| 1348 | 1167 | | |
| 1349 | - | ; Track line character | |
| 1168 | + | ; Character 129 - Track line (dashes) | |
| 1350 | 1169 | lda #%00000000 | |
| 1351 | - | sta CHARSET + (CHAR_TRACK * 8) + 0 | |
| 1352 | - | sta CHARSET + (CHAR_TRACK * 8) + 1 | |
| 1353 | - | sta CHARSET + (CHAR_TRACK * 8) + 2 | |
| 1354 | - | lda #%11111111 | |
| 1355 | - | sta CHARSET + (CHAR_TRACK * 8) + 3 | |
| 1356 | - | sta CHARSET + (CHAR_TRACK * 8) + 4 | |
| 1170 | + | sta CHARSET + (129 * 8) + 0 | |
| 1357 | 1171 | lda #%00000000 | |
| 1358 | - | sta CHARSET + (CHAR_TRACK * 8) + 5 | |
| 1359 | - | sta CHARSET + (CHAR_TRACK * 8) + 6 | |
| 1360 | - | sta CHARSET + (CHAR_TRACK * 8) + 7 | |
| 1172 | + | sta CHARSET + (129 * 8) + 1 | |
| 1173 | + | lda #%00000000 | |
| 1174 | + | sta CHARSET + (129 * 8) + 2 | |
| 1175 | + | lda #%11001100 | |
| 1176 | + | sta CHARSET + (129 * 8) + 3 | |
| 1177 | + | lda #%11001100 | |
| 1178 | + | sta CHARSET + (129 * 8) + 4 | |
| 1179 | + | lda #%00000000 | |
| 1180 | + | sta CHARSET + (129 * 8) + 5 | |
| 1181 | + | lda #%00000000 | |
| 1182 | + | sta CHARSET + (129 * 8) + 6 | |
| 1183 | + | lda #%00000000 | |
| 1184 | + | sta CHARSET + (129 * 8) + 7 | |
| 1361 | 1185 | | |
| 1362 | - | ; Hit zone character | |
| 1363 | - | lda #%01100110 | |
| 1364 | - | sta CHARSET + (CHAR_HITZONE * 8) + 0 | |
| 1365 | - | sta CHARSET + (CHAR_HITZONE * 8) + 1 | |
| 1366 | - | sta CHARSET + (CHAR_HITZONE * 8) + 2 | |
| 1367 | - | sta CHARSET + (CHAR_HITZONE * 8) + 3 | |
| 1368 | - | sta CHARSET + (CHAR_HITZONE * 8) + 4 | |
| 1369 | - | sta CHARSET + (CHAR_HITZONE * 8) + 5 | |
| 1370 | - | sta CHARSET + (CHAR_HITZONE * 8) + 6 | |
| 1371 | - | sta CHARSET + (CHAR_HITZONE * 8) + 7 | |
| 1186 | + | ; Character 130 - Hit zone (vertical bars) | |
| 1187 | + | lda #%10000001 | |
| 1188 | + | sta CHARSET + (130 * 8) + 0 | |
| 1189 | + | lda #%10000001 | |
| 1190 | + | sta CHARSET + (130 * 8) + 1 | |
| 1191 | + | lda #%10000001 | |
| 1192 | + | sta CHARSET + (130 * 8) + 2 | |
| 1193 | + | lda #%10000001 | |
| 1194 | + | sta CHARSET + (130 * 8) + 3 | |
| 1195 | + | lda #%10000001 | |
| 1196 | + | sta CHARSET + (130 * 8) + 4 | |
| 1197 | + | lda #%10000001 | |
| 1198 | + | sta CHARSET + (130 * 8) + 5 | |
| 1199 | + | lda #%10000001 | |
| 1200 | + | sta CHARSET + (130 * 8) + 6 | |
| 1201 | + | lda #%10000001 | |
| 1202 | + | sta CHARSET + (130 * 8) + 7 | |
| 1372 | 1203 | | |
| 1373 | - | ; Full bar character | |
| 1204 | + | ; Character 131 - Bar full (solid block) | |
| 1374 | 1205 | lda #%11111111 | |
| 1375 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 0 | |
| 1376 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 1 | |
| 1377 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 2 | |
| 1378 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 3 | |
| 1379 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 4 | |
| 1380 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 5 | |
| 1381 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 6 | |
| 1382 | - | sta CHARSET + (CHAR_BAR_FULL * 8) + 7 | |
| 1206 | + | sta CHARSET + (131 * 8) + 0 | |
| 1207 | + | sta CHARSET + (131 * 8) + 1 | |
| 1208 | + | sta CHARSET + (131 * 8) + 2 | |
| 1209 | + | sta CHARSET + (131 * 8) + 3 | |
| 1210 | + | sta CHARSET + (131 * 8) + 4 | |
| 1211 | + | sta CHARSET + (131 * 8) + 5 | |
| 1212 | + | sta CHARSET + (131 * 8) + 6 | |
| 1213 | + | sta CHARSET + (131 * 8) + 7 | |
| 1383 | 1214 | | |
| 1384 | - | ; Empty bar character | |
| 1215 | + | ; Character 132 - Bar empty (hollow block) | |
| 1385 | 1216 | lda #%11111111 | |
| 1386 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 0 | |
| 1217 | + | sta CHARSET + (132 * 8) + 0 | |
| 1387 | 1218 | lda #%10000001 | |
| 1388 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 1 | |
| 1389 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 2 | |
| 1390 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 3 | |
| 1391 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 4 | |
| 1392 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 5 | |
| 1393 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 6 | |
| 1219 | + | sta CHARSET + (132 * 8) + 1 | |
| 1220 | + | sta CHARSET + (132 * 8) + 2 | |
| 1221 | + | sta CHARSET + (132 * 8) + 3 | |
| 1222 | + | sta CHARSET + (132 * 8) + 4 | |
| 1223 | + | sta CHARSET + (132 * 8) + 5 | |
| 1224 | + | sta CHARSET + (132 * 8) + 6 | |
| 1394 | 1225 | lda #%11111111 | |
| 1395 | - | sta CHARSET + (CHAR_BAR_EMPTY * 8) + 7 | |
| 1396 | - | | |
| 1397 | - | rts | |
| 1398 | - | | |
| 1399 | - | ; ---------------------------------------------------------------------------- | |
| 1400 | - | ; Initialize Health | |
| 1401 | - | ; ---------------------------------------------------------------------------- | |
| 1402 | - | | |
| 1403 | - | init_health: | |
| 1404 | - | lda #HEALTH_START | |
| 1405 | - | sta health | |
| 1406 | - | jsr display_health | |
| 1407 | - | rts | |
| 1408 | - | | |
| 1409 | - | ; ---------------------------------------------------------------------------- | |
| 1410 | - | ; Initialize Score | |
| 1411 | - | ; ---------------------------------------------------------------------------- | |
| 1226 | + | sta CHARSET + (132 * 8) + 7 | |
| 1412 | 1227 | | |
| 1413 | - | init_score: | |
| 1414 | - | lda #0 | |
| 1415 | - | sta score_lo | |
| 1416 | - | sta score_hi | |
| 1417 | - | sta miss_count | |
| 1418 | - | sta perfect_count | |
| 1419 | - | sta good_count | |
| 1420 | - | jsr display_score | |
| 1421 | - | jsr display_misses | |
| 1422 | 1228 | rts | |
| 1423 | 1229 | | |
| 1424 | 1230 | ; ---------------------------------------------------------------------------- | |
| 1425 | - | ; Initialize Notes | |
| 1231 | + | ; Advance Song | |
| 1426 | 1232 | ; ---------------------------------------------------------------------------- | |
| 1427 | 1233 | | |
| 1428 | - | init_notes: | |
| 1429 | - | ldx #MAX_NOTES-1 | |
| 1430 | - | lda #0 | |
| 1431 | - | init_notes_loop: | |
| 1432 | - | sta note_track,x | |
| 1433 | - | sta note_col,x | |
| 1434 | - | sta note_freq,x | |
| 1435 | - | dex | |
| 1436 | - | bpl init_notes_loop | |
| 1234 | + | advance_song: | |
| 1235 | + | inc song_beat | |
| 1236 | + | jsr display_progress | |
| 1437 | 1237 | rts | |
| 1438 | 1238 | | |
| 1439 | 1239 | ; ---------------------------------------------------------------------------- | |
| ... | |||
| 1441 | 1241 | ; ---------------------------------------------------------------------------- | |
| 1442 | 1242 | | |
| 1443 | 1243 | check_spawn_note: | |
| 1244 | + | ; Check if song has ended | |
| 1444 | 1245 | lda song_ended | |
| 1445 | - | bne spawn_done_early | |
| 1246 | + | bne spawn_done | |
| 1247 | + | | |
| 1248 | + | ; Get pointer to current position in song | |
| 1249 | + | lda song_pos | |
| 1250 | + | sta ZP_PTR | |
| 1251 | + | lda song_pos_hi | |
| 1252 | + | sta ZP_PTR_HI | |
| 1446 | 1253 | | |
| 1254 | + | ; Read beat number | |
| 1447 | 1255 | ldy #0 | |
| 1256 | + | lda (ZP_PTR),y | |
| 1448 | 1257 | | |
| 1449 | - | spawn_check_loop: | |
| 1450 | - | lda (song_pos),y | |
| 1258 | + | ; Check for end marker | |
| 1451 | 1259 | cmp #$FF | |
| 1452 | - | beq spawn_song_end | |
| 1453 | - | | |
| 1454 | - | cmp beat_count | |
| 1455 | - | beq spawn_match | |
| 1456 | - | bcs spawn_done_early | |
| 1260 | + | beq song_end_marker | |
| 1457 | 1261 | | |
| 1458 | - | jmp spawn_advance | |
| 1262 | + | ; Check if this beat matches | |
| 1263 | + | cmp song_beat | |
| 1264 | + | bne spawn_done | |
| 1459 | 1265 | | |
| 1460 | - | spawn_match: | |
| 1266 | + | ; Spawn this note | |
| 1461 | 1267 | iny | |
| 1462 | - | lda (song_pos),y | |
| 1268 | + | lda (ZP_PTR),y ; Track | |
| 1463 | 1269 | sta temp_track | |
| 1464 | 1270 | iny | |
| 1465 | - | lda (song_pos),y | |
| 1466 | - | pha | |
| 1467 | - | lda temp_track | |
| 1468 | - | jsr spawn_note_with_freq | |
| 1469 | - | pla | |
| 1470 | - | dey | |
| 1471 | - | dey | |
| 1472 | - | | |
| 1473 | - | spawn_advance: | |
| 1474 | - | lda song_pos | |
| 1475 | - | clc | |
| 1476 | - | adc #3 | |
| 1477 | - | sta song_pos | |
| 1478 | - | lda song_pos_hi | |
| 1479 | - | adc #0 | |
| 1480 | - | sta song_pos_hi | |
| 1481 | - | jmp spawn_check_loop | |
| 1482 | - | | |
| 1483 | - | spawn_song_end: | |
| 1484 | - | lda #1 | |
| 1485 | - | sta song_ended | |
| 1486 | - | | |
| 1487 | - | spawn_done_early: | |
| 1488 | - | rts | |
| 1489 | - | | |
| 1490 | - | ; ---------------------------------------------------------------------------- | |
| 1491 | - | ; Spawn Note With Frequency | |
| 1492 | - | ; ---------------------------------------------------------------------------- | |
| 1493 | - | | |
| 1494 | - | spawn_note_with_freq: | |
| 1495 | - | sta temp_track | |
| 1271 | + | lda (ZP_PTR),y ; Frequency | |
| 1496 | 1272 | | |
| 1273 | + | ; Find free note slot | |
| 1497 | 1274 | ldx #0 | |
| 1498 | - | spawn_find_slot: | |
| 1275 | + | find_slot: | |
| 1499 | 1276 | lda note_track,x | |
| 1500 | - | beq spawn_found_slot | |
| 1277 | + | beq found_slot | |
| 1501 | 1278 | inx | |
| 1502 | 1279 | cpx #MAX_NOTES | |
| 1503 | - | bne spawn_find_slot | |
| 1504 | - | rts | |
| 1280 | + | bne find_slot | |
| 1281 | + | jmp advance_song_ptr ; No free slot, skip note | |
| 1505 | 1282 | | |
| 1506 | - | spawn_found_slot: | |
| 1283 | + | found_slot: | |
| 1507 | 1284 | lda temp_track | |
| 1508 | 1285 | sta note_track,x | |
| 1509 | 1286 | lda #NOTE_SPAWN_COL | |
| 1510 | 1287 | sta note_col,x | |
| 1511 | - | | |
| 1512 | - | tsx | |
| 1513 | - | lda $0103,x | |
| 1288 | + | ldy #2 | |
| 1289 | + | lda (ZP_PTR),y | |
| 1514 | 1290 | sta note_freq,x | |
| 1515 | - | | |
| 1516 | 1291 | jsr draw_note | |
| 1292 | + | | |
| 1293 | + | advance_song_ptr: | |
| 1294 | + | ; Move to next note in song | |
| 1295 | + | lda song_pos | |
| 1296 | + | clc | |
| 1297 | + | adc #3 | |
| 1298 | + | sta song_pos | |
| 1299 | + | lda song_pos_hi | |
| 1300 | + | adc #0 | |
| 1301 | + | sta song_pos_hi | |
| 1302 | + | | |
| 1303 | + | ; Check if there are more notes on this beat | |
| 1304 | + | jmp check_spawn_note | |
| 1305 | + | | |
| 1306 | + | song_end_marker: | |
| 1307 | + | lda #1 | |
| 1308 | + | sta song_ended | |
| 1309 | + | spawn_done: | |
| 1517 | 1310 | rts | |
| 1518 | 1311 | | |
| 1519 | 1312 | ; ---------------------------------------------------------------------------- | |
| ... | |||
| 1522 | 1315 | | |
| 1523 | 1316 | update_notes: | |
| 1524 | 1317 | ldx #0 | |
| 1525 | - | | |
| 1526 | - | update_loop: | |
| 1318 | + | update_notes_loop: | |
| 1527 | 1319 | lda note_track,x | |
| 1528 | - | beq update_next | |
| 1320 | + | beq update_next_note | |
| 1529 | 1321 | | |
| 1322 | + | ; Erase at old position | |
| 1530 | 1323 | jsr erase_note | |
| 1531 | 1324 | | |
| 1325 | + | ; Move note left | |
| 1532 | 1326 | dec note_col,x | |
| 1533 | - | lda note_col,x | |
| 1534 | - | cmp #1 | |
| 1535 | - | bcc update_miss | |
| 1536 | 1327 | | |
| 1537 | - | jsr draw_note | |
| 1538 | - | jmp update_next | |
| 1328 | + | ; Check if past hit zone (missed) | |
| 1329 | + | lda note_col,x | |
| 1330 | + | cmp #HIT_ZONE_MIN | |
| 1331 | + | bcs note_still_active | |
| 1539 | 1332 | | |
| 1540 | - | update_miss: | |
| 1333 | + | ; Note was missed | |
| 1541 | 1334 | lda note_track,x | |
| 1542 | 1335 | sta miss_track | |
| 1543 | 1336 | lda #0 | |
| 1544 | 1337 | sta note_track,x | |
| 1545 | 1338 | jsr handle_miss | |
| 1546 | - | | |
| 1547 | - | update_next: | |
| 1548 | - | inx | |
| 1549 | - | cpx #MAX_NOTES | |
| 1550 | - | bne update_loop | |
| 1551 | - | rts | |
| 1552 | - | | |
| 1553 | - | ; ---------------------------------------------------------------------------- | |
| 1554 | - | ; Handle Miss | |
| 1555 | - | ; ---------------------------------------------------------------------------- | |
| 1556 | - | | |
| 1557 | - | handle_miss: | |
| 1558 | - | inc miss_count | |
| 1559 | - | | |
| 1560 | - | jsr play_miss_sound | |
| 1561 | - | | |
| 1562 | - | lda #MISS_COL | |
| 1563 | - | sta BORDER | |
| 1564 | - | lda #8 | |
| 1565 | - | sta border_flash | |
| 1566 | - | | |
| 1567 | - | jsr display_misses | |
| 1568 | - | jsr decrease_health | |
| 1569 | - | jsr break_combo | |
| 1570 | - | | |
| 1571 | - | rts | |
| 1572 | - | | |
| 1573 | - | ; ---------------------------------------------------------------------------- | |
| 1574 | - | ; Decrease Health | |
| 1575 | - | ; ---------------------------------------------------------------------------- | |
| 1576 | - | | |
| 1577 | - | decrease_health: | |
| 1578 | - | lda health | |
| 1579 | - | sec | |
| 1580 | - | sbc #HEALTH_MISS | |
| 1581 | - | bcc health_zero | |
| 1582 | - | sta health | |
| 1583 | - | jsr display_health | |
| 1584 | - | jsr check_game_over | |
| 1585 | - | rts | |
| 1586 | - | | |
| 1587 | - | health_zero: | |
| 1588 | - | lda #0 | |
| 1589 | - | sta health | |
| 1590 | - | jsr display_health | |
| 1591 | - | jsr check_game_over | |
| 1592 | - | rts | |
| 1593 | - | | |
| 1594 | - | ; ---------------------------------------------------------------------------- | |
| 1595 | - | ; Increase Health | |
| 1596 | - | ; ---------------------------------------------------------------------------- | |
| 1597 | - | | |
| 1598 | - | increase_health: | |
| 1599 | - | clc | |
| 1600 | - | adc health | |
| 1601 | - | cmp #HEALTH_MAX | |
| 1602 | - | bcc health_ok | |
| 1603 | - | lda #HEALTH_MAX | |
| 1604 | - | health_ok: | |
| 1605 | - | sta health | |
| 1606 | - | jsr display_health | |
| 1607 | - | rts | |
| 1608 | - | | |
| 1609 | - | ; ---------------------------------------------------------------------------- | |
| 1610 | - | ; Check Game Over | |
| 1611 | - | ; ---------------------------------------------------------------------------- | |
| 1612 | - | | |
| 1613 | - | check_game_over: | |
| 1614 | - | lda health | |
| 1615 | - | bne not_game_over | |
| 1616 | - | | |
| 1617 | - | lda #STATE_GAMEOVER | |
| 1618 | - | sta game_state | |
| 1619 | - | jsr show_game_over | |
| 1620 | - | | |
| 1621 | - | not_game_over: | |
| 1622 | - | rts | |
| 1623 | - | | |
| 1624 | - | ; ---------------------------------------------------------------------------- | |
| 1625 | - | ; Show Game Over | |
| 1626 | - | ; ---------------------------------------------------------------------------- | |
| 1627 | - | | |
| 1628 | - | show_game_over: | |
| 1629 | - | ; Clear screen for game over display | |
| 1630 | - | ldx #0 | |
| 1631 | - | lda #CHAR_SPACE | |
| 1632 | - | clear_gameover: | |
| 1633 | - | sta SCREEN,x | |
| 1634 | - | sta SCREEN+$100,x | |
| 1635 | - | sta SCREEN+$200,x | |
| 1636 | - | sta SCREEN+$2E8,x | |
| 1637 | - | inx | |
| 1638 | - | bne clear_gameover | |
| 1639 | - | | |
| 1640 | - | ; Draw "GAME OVER" in red | |
| 1641 | - | ldx #0 | |
| 1642 | - | game_over_loop: | |
| 1643 | - | lda game_over_text,x | |
| 1644 | - | beq game_over_text_done | |
| 1645 | - | sta SCREEN + (6 * 40) + 15,x | |
| 1646 | - | lda #2 ; Red for failure | |
| 1647 | - | sta COLRAM + (6 * 40) + 15,x | |
| 1648 | - | inx | |
| 1649 | - | jmp game_over_loop | |
| 1650 | - | game_over_text_done: | |
| 1651 | - | | |
| 1652 | - | ; Draw "HEALTH DEPLETED" | |
| 1653 | - | ldx #0 | |
| 1654 | - | draw_depleted: | |
| 1655 | - | lda depleted_text,x | |
| 1656 | - | beq draw_depleted_done | |
| 1657 | - | sta SCREEN + (8 * 40) + 12,x | |
| 1658 | - | lda #10 ; Light red | |
| 1659 | - | sta COLRAM + (8 * 40) + 12,x | |
| 1660 | - | inx | |
| 1661 | - | jmp draw_depleted | |
| 1662 | - | draw_depleted_done: | |
| 1663 | - | | |
| 1664 | - | ; Show score achieved | |
| 1665 | - | ldx #0 | |
| 1666 | - | draw_go_score_label: | |
| 1667 | - | lda go_score_label,x | |
| 1668 | - | beq draw_go_score_done | |
| 1669 | - | sta SCREEN + (12 * 40) + 11,x | |
| 1670 | - | lda #7 | |
| 1671 | - | sta COLRAM + (12 * 40) + 11,x | |
| 1672 | - | inx | |
| 1673 | - | jmp draw_go_score_label | |
| 1674 | - | draw_go_score_done: | |
| 1675 | - | jsr display_gameover_score | |
| 1676 | - | | |
| 1677 | - | ; Show notes hit | |
| 1678 | - | ldx #0 | |
| 1679 | - | draw_go_notes_label: | |
| 1680 | - | lda go_notes_label,x | |
| 1681 | - | beq draw_go_notes_done | |
| 1682 | - | sta SCREEN + (14 * 40) + 11,x | |
| 1683 | - | lda #11 | |
| 1684 | - | sta COLRAM + (14 * 40) + 11,x | |
| 1685 | - | inx | |
| 1686 | - | jmp draw_go_notes_label | |
| 1687 | - | draw_go_notes_done: | |
| 1688 | - | lda perfect_count | |
| 1689 | - | clc | |
| 1690 | - | adc good_count | |
| 1691 | - | jsr display_go_stat | |
| 1692 | - | | |
| 1693 | - | ; "PRESS FIRE FOR TITLE" | |
| 1694 | - | ldx #0 | |
| 1695 | - | game_over_press: | |
| 1696 | - | lda press_fire_gameover,x | |
| 1697 | - | beq game_over_done | |
| 1698 | - | sta SCREEN + (18 * 40) + 10,x | |
| 1699 | - | lda #7 ; Yellow for action | |
| 1700 | - | sta COLRAM + (18 * 40) + 10,x | |
| 1701 | - | inx | |
| 1702 | - | jmp game_over_press | |
| 1703 | - | | |
| 1704 | - | game_over_done: | |
| 1705 | - | lda #2 ; Red border for failure | |
| 1706 | - | sta BORDER | |
| 1707 | - | rts | |
| 1708 | - | | |
| 1709 | - | game_over_text: | |
| 1710 | - | !scr "game over" | |
| 1711 | - | !byte 0 | |
| 1712 | - | | |
| 1713 | - | depleted_text: | |
| 1714 | - | !scr "health depleted" | |
| 1715 | - | !byte 0 | |
| 1716 | - | | |
| 1717 | - | go_score_label: | |
| 1718 | - | !scr "score achieved:" | |
| 1719 | - | !byte 0 | |
| 1720 | - | | |
| 1721 | - | go_notes_label: | |
| 1722 | - | !scr "notes hit:" | |
| 1723 | - | !byte 0 | |
| 1724 | - | | |
| 1725 | - | press_fire_gameover: | |
| 1726 | - | !scr "press fire for title" | |
| 1727 | - | !byte 0 | |
| 1728 | - | | |
| 1729 | - | ; Display gameover score (row 12) | |
| 1730 | - | display_gameover_score: | |
| 1731 | - | lda score_lo | |
| 1732 | - | sta work_lo | |
| 1733 | - | lda score_hi | |
| 1734 | - | sta work_hi | |
| 1735 | - | | |
| 1736 | - | ldx #0 | |
| 1737 | - | go_div_10000: | |
| 1738 | - | lda work_lo | |
| 1739 | - | sec | |
| 1740 | - | sbc #<10000 | |
| 1741 | - | tay | |
| 1742 | - | lda work_hi | |
| 1743 | - | sbc #>10000 | |
| 1744 | - | bcc go_done_10000 | |
| 1745 | - | sta work_hi | |
| 1746 | - | sty work_lo | |
| 1747 | - | inx | |
| 1748 | - | jmp go_div_10000 | |
| 1749 | - | go_done_10000: | |
| 1750 | - | txa | |
| 1751 | - | ora #$30 | |
| 1752 | - | sta SCREEN + (12 * 40) + 27 | |
| 1753 | - | | |
| 1754 | - | ldx #0 | |
| 1755 | - | go_div_1000: | |
| 1756 | - | lda work_lo | |
| 1757 | - | sec | |
| 1758 | - | sbc #<1000 | |
| 1759 | - | tay | |
| 1760 | - | lda work_hi | |
| 1761 | - | sbc #>1000 | |
| 1762 | - | bcc go_done_1000 | |
| 1763 | - | sta work_hi | |
| 1764 | - | sty work_lo | |
| 1765 | - | inx | |
| 1766 | - | jmp go_div_1000 | |
| 1767 | - | go_done_1000: | |
| 1768 | - | txa | |
| 1769 | - | ora #$30 | |
| 1770 | - | sta SCREEN + (12 * 40) + 28 | |
| 1771 | - | | |
| 1772 | - | ldx #0 | |
| 1773 | - | go_div_100: | |
| 1774 | - | lda work_lo | |
| 1775 | - | sec | |
| 1776 | - | sbc #100 | |
| 1777 | - | bcc go_done_100 | |
| 1778 | - | sta work_lo | |
| 1779 | - | inx | |
| 1780 | - | jmp go_div_100 | |
| 1781 | - | go_done_100: | |
| 1782 | - | txa | |
| 1783 | - | ora #$30 | |
| 1784 | - | sta SCREEN + (12 * 40) + 29 | |
| 1785 | - | | |
| 1786 | - | ldx #0 | |
| 1787 | - | go_div_10: | |
| 1788 | - | lda work_lo | |
| 1789 | - | sec | |
| 1790 | - | sbc #10 | |
| 1791 | - | bcc go_done_10 | |
| 1792 | - | sta work_lo | |
| 1793 | - | inx | |
| 1794 | - | jmp go_div_10 | |
| 1795 | - | go_done_10: | |
| 1796 | - | txa | |
| 1797 | - | ora #$30 | |
| 1798 | - | sta SCREEN + (12 * 40) + 30 | |
| 1799 | - | | |
| 1800 | - | lda work_lo | |
| 1801 | - | ora #$30 | |
| 1802 | - | sta SCREEN + (12 * 40) + 31 | |
| 1803 | - | | |
| 1804 | - | lda #7 | |
| 1805 | - | sta COLRAM + (12 * 40) + 27 | |
| 1806 | - | sta COLRAM + (12 * 40) + 28 | |
| 1807 | - | sta COLRAM + (12 * 40) + 29 | |
| 1808 | - | sta COLRAM + (12 * 40) + 30 | |
| 1809 | - | sta COLRAM + (12 * 40) + 31 | |
| 1810 | - | rts | |
| 1811 | - | | |
| 1812 | - | ; Display notes hit stat at row 14 | |
| 1813 | - | display_go_stat: | |
| 1814 | - | ldx #0 | |
| 1815 | - | go_stat_div: | |
| 1816 | - | cmp #10 | |
| 1817 | - | bcc go_stat_done | |
| 1818 | - | sec | |
| 1819 | - | sbc #10 | |
| 1820 | - | inx | |
| 1821 | - | jmp go_stat_div | |
| 1822 | - | go_stat_done: | |
| 1823 | - | pha | |
| 1824 | - | txa | |
| 1825 | - | ora #$30 | |
| 1826 | - | sta SCREEN + (14 * 40) + 27 | |
| 1827 | - | pla | |
| 1828 | - | ora #$30 | |
| 1829 | - | sta SCREEN + (14 * 40) + 28 | |
| 1830 | - | lda #11 | |
| 1831 | - | sta COLRAM + (14 * 40) + 27 | |
| 1832 | - | sta COLRAM + (14 * 40) + 28 | |
| 1833 | - | rts | |
| 1834 | - | | |
| 1835 | - | ; ---------------------------------------------------------------------------- | |
| 1836 | - | ; Display Health | |
| 1837 | - | ; ---------------------------------------------------------------------------- | |
| 1838 | - | | |
| 1839 | - | display_health: | |
| 1840 | - | lda health | |
| 1841 | - | lsr | |
| 1842 | - | lsr | |
| 1843 | - | lsr | |
| 1844 | - | sta temp_health | |
| 1845 | - | | |
| 1846 | - | ldx #0 | |
| 1847 | - | lda temp_health | |
| 1848 | - | beq draw_empty_bars | |
| 1339 | + | jmp update_next_note | |
| 1849 | 1340 | | |
| 1850 | - | draw_full_bars: | |
| 1851 | - | lda #CHAR_BAR_FULL | |
| 1852 | - | sta SCREEN + (HEALTH_ROW * 40) + 12,x | |
| 1853 | - | lda #HEALTH_COL | |
| 1854 | - | sta COLRAM + (HEALTH_ROW * 40) + 12,x | |
| 1855 | - | inx | |
| 1856 | - | cpx temp_health | |
| 1857 | - | bne draw_full_bars | |
| 1341 | + | note_still_active: | |
| 1342 | + | jsr draw_note | |
| 1858 | 1343 | | |
| 1859 | - | draw_empty_bars: | |
| 1860 | - | cpx #8 | |
| 1861 | - | beq health_done | |
| 1862 | - | lda #CHAR_BAR_EMPTY | |
| 1863 | - | sta SCREEN + (HEALTH_ROW * 40) + 12,x | |
| 1864 | - | lda #11 | |
| 1865 | - | sta COLRAM + (HEALTH_ROW * 40) + 12,x | |
| 1344 | + | update_next_note: | |
| 1866 | 1345 | inx | |
| 1867 | - | jmp draw_empty_bars | |
| 1868 | - | | |
| 1869 | - | health_done: | |
| 1870 | - | rts | |
| 1871 | - | | |
| 1872 | - | temp_health: !byte 0 | |
| 1873 | - | | |
| 1874 | - | ; ============================================================================ | |
| 1875 | - | ; POLISHED SOUND EFFECTS | |
| 1876 | - | ; ============================================================================ | |
| 1877 | - | | |
| 1878 | - | ; Play Perfect Hit Sound - Bright, high, satisfying | |
| 1879 | - | play_perfect_sound: | |
| 1880 | - | lda #0 | |
| 1881 | - | sta SID_V3_FREQ_LO | |
| 1882 | - | lda #PERFECT_SFX_FREQ | |
| 1883 | - | sta SID_V3_FREQ_HI | |
| 1884 | - | lda #$08 | |
| 1885 | - | sta SID_V3_PWHI | |
| 1886 | - | lda #PERFECT_SFX_AD | |
| 1887 | - | sta SID_V3_AD | |
| 1888 | - | lda #PERFECT_SFX_SR | |
| 1889 | - | sta SID_V3_SR | |
| 1890 | - | lda #PERFECT_SFX_WAVE | |
| 1891 | - | ora #$01 ; Gate on | |
| 1892 | - | sta SID_V3_CTRL | |
| 1893 | - | rts | |
| 1894 | - | | |
| 1895 | - | ; Play Good Hit Sound - Positive but lesser | |
| 1896 | - | play_good_sound: | |
| 1897 | - | lda #0 | |
| 1898 | - | sta SID_V3_FREQ_LO | |
| 1899 | - | lda #GOOD_SFX_FREQ | |
| 1900 | - | sta SID_V3_FREQ_HI | |
| 1901 | - | lda #$08 | |
| 1902 | - | sta SID_V3_PWHI | |
| 1903 | - | lda #GOOD_SFX_AD | |
| 1904 | - | sta SID_V3_AD | |
| 1905 | - | lda #GOOD_SFX_SR | |
| 1906 | - | sta SID_V3_SR | |
| 1907 | - | lda #GOOD_SFX_WAVE | |
| 1908 | - | ora #$01 ; Gate on | |
| 1909 | - | sta SID_V3_CTRL | |
| 1910 | - | rts | |
| 1911 | - | | |
| 1912 | - | ; Play Miss Sound - Harsh buzz | |
| 1913 | - | play_miss_sound: | |
| 1914 | - | lda #0 | |
| 1915 | - | sta SID_V3_FREQ_LO | |
| 1916 | - | lda #MISS_FREQ | |
| 1917 | - | sta SID_V3_FREQ_HI | |
| 1918 | - | lda #MISS_AD | |
| 1919 | - | sta SID_V3_AD | |
| 1920 | - | lda #MISS_SR | |
| 1921 | - | sta SID_V3_SR | |
| 1922 | - | lda #MISS_WAVE | |
| 1923 | - | ora #$01 ; Gate on | |
| 1924 | - | sta SID_V3_CTRL | |
| 1346 | + | cpx #MAX_NOTES | |
| 1347 | + | bne update_notes_loop | |
| 1925 | 1348 | rts | |
| 1926 | 1349 | | |
| 1927 | 1350 | ; ---------------------------------------------------------------------------- | |
| ... | |||
| 1934 | 1357 | beq draw_note_t1 | |
| 1935 | 1358 | cmp #2 | |
| 1936 | 1359 | beq draw_note_t2 | |
| 1937 | - | cmp #3 | |
| 1938 | - | beq draw_note_t3 | |
| 1939 | - | rts | |
| 1360 | + | jmp draw_note_t3 | |
| 1940 | 1361 | | |
| 1941 | 1362 | draw_note_t1: | |
| 1942 | 1363 | lda note_col,x | |
| ... | |||
| 1947 | 1368 | adc #0 | |
| 1948 | 1369 | sta ZP_PTR_HI | |
| 1949 | 1370 | | |
| 1950 | - | ldy #0 | |
| 1951 | 1371 | lda #CHAR_NOTE | |
| 1372 | + | ldy #0 | |
| 1952 | 1373 | sta (ZP_PTR),y | |
| 1953 | 1374 | | |
| 1375 | + | ; Set colour | |
| 1954 | 1376 | lda note_col,x | |
| 1955 | 1377 | clc | |
| 1956 | 1378 | adc #<(COLRAM + TRACK1_ROW * 40) | |
| ... | |||
| 1971 | 1393 | adc #0 | |
| 1972 | 1394 | sta ZP_PTR_HI | |
| 1973 | 1395 | | |
| 1974 | - | ldy #0 | |
| 1975 | 1396 | lda #CHAR_NOTE | |
| 1397 | + | ldy #0 | |
| 1976 | 1398 | sta (ZP_PTR),y | |
| 1977 | 1399 | | |
| 1978 | 1400 | lda note_col,x | |
| ... | |||
| 1995 | 1417 | adc #0 | |
| 1996 | 1418 | sta ZP_PTR_HI | |
| 1997 | 1419 | | |
| 1998 | - | ldy #0 | |
| 1999 | 1420 | lda #CHAR_NOTE | |
| 1421 | + | ldy #0 | |
| 2000 | 1422 | sta (ZP_PTR),y | |
| 2001 | 1423 | | |
| 2002 | 1424 | lda note_col,x | |
| ... | |||
| 2020 | 1442 | beq erase_note_t1 | |
| 2021 | 1443 | cmp #2 | |
| 2022 | 1444 | beq erase_note_t2 | |
| 2023 | - | cmp #3 | |
| 2024 | - | beq erase_note_t3 | |
| 2025 | - | rts | |
| 1445 | + | jmp erase_note_t3 | |
| 2026 | 1446 | | |
| 2027 | 1447 | erase_note_t1: | |
| 2028 | 1448 | lda note_col,x | |
| ... | |||
| 2033 | 1453 | adc #0 | |
| 2034 | 1454 | sta ZP_PTR_HI | |
| 2035 | 1455 | | |
| 2036 | - | ldy #0 | |
| 2037 | 1456 | lda #CHAR_TRACK | |
| 1457 | + | ldy #0 | |
| 2038 | 1458 | sta (ZP_PTR),y | |
| 2039 | 1459 | | |
| 2040 | 1460 | lda note_col,x | |
| ... | |||
| 2057 | 1477 | adc #0 | |
| 2058 | 1478 | sta ZP_PTR_HI | |
| 2059 | 1479 | | |
| 2060 | - | ldy #0 | |
| 2061 | 1480 | lda #CHAR_TRACK | |
| 1481 | + | ldy #0 | |
| 2062 | 1482 | sta (ZP_PTR),y | |
| 2063 | 1483 | | |
| 2064 | 1484 | lda note_col,x | |
| ... | |||
| 2081 | 1501 | adc #0 | |
| 2082 | 1502 | sta ZP_PTR_HI | |
| 2083 | 1503 | | |
| 2084 | - | ldy #0 | |
| 2085 | 1504 | lda #CHAR_TRACK | |
| 1505 | + | ldy #0 | |
| 2086 | 1506 | sta (ZP_PTR),y | |
| 2087 | 1507 | | |
| 2088 | 1508 | lda note_col,x | |
| ... | |||
| 2097 | 1517 | rts | |
| 2098 | 1518 | | |
| 2099 | 1519 | ; ---------------------------------------------------------------------------- | |
| 2100 | - | ; Initialize Screen | |
| 1520 | + | ; Handle Miss | |
| 2101 | 1521 | ; ---------------------------------------------------------------------------- | |
| 2102 | - | | |
| 2103 | - | init_screen: | |
| 2104 | - | lda #BORDER_COL | |
| 2105 | - | sta BORDER | |
| 2106 | - | lda #BG_COL | |
| 2107 | - | sta BGCOL | |
| 2108 | - | | |
| 2109 | - | ldx #0 | |
| 2110 | - | lda #CHAR_SPACE | |
| 2111 | - | clr_screen: | |
| 2112 | - | sta SCREEN,x | |
| 2113 | - | sta SCREEN+$100,x | |
| 2114 | - | sta SCREEN+$200,x | |
| 2115 | - | sta SCREEN+$2E8,x | |
| 2116 | - | inx | |
| 2117 | - | bne clr_screen | |
| 2118 | 1522 | | |
| 2119 | - | ldx #0 | |
| 2120 | - | lda #TRACK_LINE_COL | |
| 2121 | - | clr_colour: | |
| 2122 | - | sta COLRAM,x | |
| 2123 | - | sta COLRAM+$100,x | |
| 2124 | - | sta COLRAM+$200,x | |
| 2125 | - | sta COLRAM+$2E8,x | |
| 2126 | - | inx | |
| 2127 | - | bne clr_colour | |
| 1523 | + | handle_miss: | |
| 1524 | + | jsr play_miss_sound | |
| 1525 | + | jsr break_combo | |
| 2128 | 1526 | | |
| 2129 | - | jsr draw_tracks | |
| 2130 | - | jsr draw_hit_zones | |
| 2131 | - | jsr draw_labels | |
| 1527 | + | ; Decrease health | |
| 1528 | + | lda #HEALTH_MISS | |
| 1529 | + | jsr decrease_health | |
| 2132 | 1530 | | |
| 2133 | - | rts | |
| 1531 | + | ; Flash border red | |
| 1532 | + | lda #MISS_COL | |
| 1533 | + | sta BORDER | |
| 1534 | + | lda #8 | |
| 1535 | + | sta border_flash | |
| 2134 | 1536 | | |
| 2135 | - | ; ---------------------------------------------------------------------------- | |
| 2136 | - | ; Draw Tracks | |
| 2137 | - | ; ---------------------------------------------------------------------------- | |
| 1537 | + | ; Flash the track where miss happened | |
| 1538 | + | lda miss_track | |
| 1539 | + | cmp #1 | |
| 1540 | + | beq flash_miss_t1 | |
| 1541 | + | cmp #2 | |
| 1542 | + | beq flash_miss_t2 | |
| 1543 | + | jmp flash_miss_t3 | |
| 2138 | 1544 | | |
| 2139 | - | draw_tracks: | |
| 2140 | - | lda #CHAR_TRACK | |
| 1545 | + | flash_miss_t1: | |
| 2141 | 1546 | ldx #0 | |
| 2142 | - | draw_t1: | |
| 2143 | - | sta SCREEN + (TRACK1_ROW * 40),x | |
| 1547 | + | lda #MISS_COL | |
| 1548 | + | flash_m1_loop: | |
| 1549 | + | sta COLRAM + (TRACK1_ROW * 40),x | |
| 2144 | 1550 | inx | |
| 2145 | 1551 | cpx #38 | |
| 2146 | - | bne draw_t1 | |
| 1552 | + | bne flash_m1_loop | |
| 1553 | + | rts | |
| 2147 | 1554 | | |
| 1555 | + | flash_miss_t2: | |
| 2148 | 1556 | ldx #0 | |
| 2149 | - | draw_t2: | |
| 2150 | - | sta SCREEN + (TRACK2_ROW * 40),x | |
| 1557 | + | lda #MISS_COL | |
| 1558 | + | flash_m2_loop: | |
| 1559 | + | sta COLRAM + (TRACK2_ROW * 40),x | |
| 2151 | 1560 | inx | |
| 2152 | 1561 | cpx #38 | |
| 2153 | - | bne draw_t2 | |
| 1562 | + | bne flash_m2_loop | |
| 1563 | + | rts | |
| 2154 | 1564 | | |
| 1565 | + | flash_miss_t3: | |
| 2155 | 1566 | ldx #0 | |
| 2156 | - | draw_t3: | |
| 2157 | - | sta SCREEN + (TRACK3_ROW * 40),x | |
| 1567 | + | lda #MISS_COL | |
| 1568 | + | flash_m3_loop: | |
| 1569 | + | sta COLRAM + (TRACK3_ROW * 40),x | |
| 2158 | 1570 | inx | |
| 2159 | 1571 | cpx #38 | |
| 2160 | - | bne draw_t3 | |
| 2161 | - | | |
| 1572 | + | bne flash_m3_loop | |
| 2162 | 1573 | rts | |
| 2163 | 1574 | | |
| 2164 | 1575 | ; ---------------------------------------------------------------------------- | |
| 2165 | - | ; Draw Hit Zones | |
| 1576 | + | ; Play Miss Sound | |
| 2166 | 1577 | ; ---------------------------------------------------------------------------- | |
| 2167 | 1578 | | |
| 2168 | - | draw_hit_zones: | |
| 2169 | - | lda #CHAR_HITZONE | |
| 1579 | + | play_miss_sound: | |
| 1580 | + | inc miss_count | |
| 1581 | + | jsr display_misses | |
| 2170 | 1582 | | |
| 2171 | - | sta SCREEN + ((TRACK1_ROW-2) * 40) + HIT_ZONE_COLUMN | |
| 2172 | - | sta SCREEN + ((TRACK1_ROW-1) * 40) + HIT_ZONE_COLUMN | |
| 2173 | - | sta SCREEN + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN | |
| 2174 | - | sta SCREEN + ((TRACK1_ROW+1) * 40) + HIT_ZONE_COLUMN | |
| 1583 | + | lda #0 | |
| 1584 | + | sta SID_V3_FREQ_LO | |
| 1585 | + | lda #MISS_FREQ | |
| 1586 | + | sta SID_V3_FREQ_HI | |
| 1587 | + | lda #MISS_AD | |
| 1588 | + | sta SID_V3_AD | |
| 1589 | + | lda #MISS_SR | |
| 1590 | + | sta SID_V3_SR | |
| 1591 | + | lda #MISS_WAVE | |
| 1592 | + | ora #$01 | |
| 1593 | + | sta SID_V3_CTRL | |
| 1594 | + | rts | |
| 2175 | 1595 | | |
| 2176 | - | sta SCREEN + ((TRACK2_ROW-1) * 40) + HIT_ZONE_COLUMN | |
| 2177 | - | sta SCREEN + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN | |
| 2178 | - | sta SCREEN + ((TRACK2_ROW+1) * 40) + HIT_ZONE_COLUMN | |
| 1596 | + | ; ---------------------------------------------------------------------------- | |
| 1597 | + | ; Play Perfect Sound | |
| 1598 | + | ; ---------------------------------------------------------------------------- | |
| 2179 | 1599 | | |
| 2180 | - | sta SCREEN + ((TRACK3_ROW-1) * 40) + HIT_ZONE_COLUMN | |
| 2181 | - | sta SCREEN + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN | |
| 2182 | - | sta SCREEN + ((TRACK3_ROW+1) * 40) + HIT_ZONE_COLUMN | |
| 2183 | - | sta SCREEN + ((TRACK3_ROW+2) * 40) + HIT_ZONE_COLUMN | |
| 1600 | + | play_perfect_sound: | |
| 1601 | + | lda #0 | |
| 1602 | + | sta SID_V3_FREQ_LO | |
| 1603 | + | lda #PERFECT_SFX_FREQ | |
| 1604 | + | sta SID_V3_FREQ_HI | |
| 1605 | + | lda #PERFECT_SFX_AD | |
| 1606 | + | sta SID_V3_AD | |
| 1607 | + | lda #PERFECT_SFX_SR | |
| 1608 | + | sta SID_V3_SR | |
| 1609 | + | lda #PERFECT_SFX_WAVE | |
| 1610 | + | ora #$01 | |
| 1611 | + | sta SID_V3_CTRL | |
| 1612 | + | rts | |
| 2184 | 1613 | | |
| 2185 | - | lda #HIT_ZONE_COL | |
| 2186 | - | sta COLRAM + ((TRACK1_ROW-2) * 40) + HIT_ZONE_COLUMN | |
| 2187 | - | sta COLRAM + ((TRACK1_ROW-1) * 40) + HIT_ZONE_COLUMN | |
| 2188 | - | sta COLRAM + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN | |
| 2189 | - | sta COLRAM + ((TRACK1_ROW+1) * 40) + HIT_ZONE_COLUMN | |
| 1614 | + | ; ---------------------------------------------------------------------------- | |
| 1615 | + | ; Play Good Sound | |
| 1616 | + | ; ---------------------------------------------------------------------------- | |
| 2190 | 1617 | | |
| 2191 | - | sta COLRAM + ((TRACK2_ROW-1) * 40) + HIT_ZONE_COLUMN | |
| 2192 | - | sta COLRAM + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN | |
| 2193 | - | sta COLRAM + ((TRACK2_ROW+1) * 40) + HIT_ZONE_COLUMN | |
| 1618 | + | play_good_sound: | |
| 1619 | + | lda #0 | |
| 1620 | + | sta SID_V3_FREQ_LO | |
| 1621 | + | lda #GOOD_SFX_FREQ | |
| 1622 | + | sta SID_V3_FREQ_HI | |
| 1623 | + | lda #GOOD_SFX_AD | |
| 1624 | + | sta SID_V3_AD | |
| 1625 | + | lda #GOOD_SFX_SR | |
| 1626 | + | sta SID_V3_SR | |
| 1627 | + | lda #GOOD_SFX_WAVE | |
| 1628 | + | ora #$01 | |
| 1629 | + | sta SID_V3_CTRL | |
| 1630 | + | rts | |
| 2194 | 1631 | | |
| 2195 | - | sta COLRAM + ((TRACK3_ROW-1) * 40) + HIT_ZONE_COLUMN | |
| 2196 | - | sta COLRAM + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN | |
| 2197 | - | sta COLRAM + ((TRACK3_ROW+1) * 40) + HIT_ZONE_COLUMN | |
| 2198 | - | sta COLRAM + ((TRACK3_ROW+2) * 40) + HIT_ZONE_COLUMN | |
| 1632 | + | ; ---------------------------------------------------------------------------- | |
| 1633 | + | ; Increase Health | |
| 1634 | + | ; ---------------------------------------------------------------------------- | |
| 2199 | 1635 | | |
| 1636 | + | increase_health: | |
| 1637 | + | clc | |
| 1638 | + | adc health | |
| 1639 | + | cmp #HEALTH_MAX | |
| 1640 | + | bcc health_ok | |
| 1641 | + | lda #HEALTH_MAX | |
| 1642 | + | health_ok: | |
| 1643 | + | sta health | |
| 1644 | + | jsr display_health | |
| 2200 | 1645 | rts | |
| 2201 | 1646 | | |
| 2202 | 1647 | ; ---------------------------------------------------------------------------- | |
| 2203 | - | ; Draw Labels | |
| 1648 | + | ; Decrease Health | |
| 2204 | 1649 | ; ---------------------------------------------------------------------------- | |
| 2205 | 1650 | | |
| 2206 | - | draw_labels: | |
| 2207 | - | ldx #0 | |
| 2208 | - | draw_score_label: | |
| 2209 | - | lda score_label,x | |
| 2210 | - | beq draw_score_label_done | |
| 2211 | - | sta SCREEN + 1,x | |
| 2212 | - | lda #1 | |
| 2213 | - | sta COLRAM + 1,x | |
| 2214 | - | inx | |
| 2215 | - | bne draw_score_label | |
| 2216 | - | draw_score_label_done: | |
| 1651 | + | decrease_health: | |
| 1652 | + | sta temp_track | |
| 1653 | + | lda health | |
| 1654 | + | sec | |
| 1655 | + | sbc temp_track | |
| 1656 | + | bcs health_not_zero | |
| 1657 | + | lda #0 | |
| 1658 | + | health_not_zero: | |
| 1659 | + | sta health | |
| 1660 | + | jsr display_health | |
| 2217 | 1661 | | |
| 2218 | - | ldx #0 | |
| 2219 | - | draw_miss_label: | |
| 2220 | - | lda miss_label,x | |
| 2221 | - | beq draw_miss_label_done | |
| 2222 | - | sta SCREEN + 15,x | |
| 2223 | - | lda #2 | |
| 2224 | - | sta COLRAM + 15,x | |
| 2225 | - | inx | |
| 2226 | - | bne draw_miss_label | |
| 2227 | - | draw_miss_label_done: | |
| 1662 | + | ; Check for game over | |
| 1663 | + | lda health | |
| 1664 | + | bne no_game_over | |
| 1665 | + | jsr show_gameover | |
| 1666 | + | lda #STATE_GAMEOVER | |
| 1667 | + | sta game_state | |
| 1668 | + | no_game_over: | |
| 1669 | + | rts | |
| 2228 | 1670 | | |
| 2229 | - | ldx #0 | |
| 2230 | - | draw_title_game: | |
| 2231 | - | lda title_game,x | |
| 2232 | - | beq draw_title_game_done | |
| 2233 | - | sta SCREEN + 27,x | |
| 2234 | - | lda #1 | |
| 2235 | - | sta COLRAM + 27,x | |
| 2236 | - | inx | |
| 2237 | - | bne draw_title_game | |
| 2238 | - | draw_title_game_done: | |
| 1671 | + | ; ---------------------------------------------------------------------------- | |
| 1672 | + | ; Display Health Bar | |
| 1673 | + | ; ---------------------------------------------------------------------------- | |
| 2239 | 1674 | | |
| 2240 | - | ldx #0 | |
| 2241 | - | draw_health_label: | |
| 2242 | - | lda health_label,x | |
| 2243 | - | beq draw_health_label_done | |
| 2244 | - | sta SCREEN + (HEALTH_ROW * 40) + 4,x | |
| 2245 | - | lda #5 | |
| 2246 | - | sta COLRAM + (HEALTH_ROW * 40) + 4,x | |
| 2247 | - | inx | |
| 2248 | - | bne draw_health_label | |
| 2249 | - | draw_health_label_done: | |
| 1675 | + | display_health: | |
| 1676 | + | ; Calculate filled blocks (health / 4 = blocks, max 16) | |
| 1677 | + | lda health | |
| 1678 | + | lsr | |
| 1679 | + | lsr | |
| 1680 | + | sta temp_track | |
| 2250 | 1681 | | |
| 2251 | 1682 | ldx #0 | |
| 2252 | - | draw_progress_label: | |
| 2253 | - | lda progress_label,x | |
| 2254 | - | beq draw_progress_label_done | |
| 2255 | - | sta SCREEN + (PROGRESS_ROW * 40) + 4,x | |
| 2256 | - | lda #3 | |
| 2257 | - | sta COLRAM + (PROGRESS_ROW * 40) + 4,x | |
| 1683 | + | draw_health_bar: | |
| 1684 | + | cpx temp_track | |
| 1685 | + | bcs draw_empty_health | |
| 1686 | + | lda #CHAR_BAR_FULL | |
| 1687 | + | jmp store_health_char | |
| 1688 | + | draw_empty_health: | |
| 1689 | + | lda #CHAR_BAR_EMPTY | |
| 1690 | + | store_health_char: | |
| 1691 | + | sta SCREEN + (HEALTH_ROW * 40) + 8,x | |
| 1692 | + | lda #HEALTH_COL | |
| 1693 | + | sta COLRAM + (HEALTH_ROW * 40) + 8,x | |
| 2258 | 1694 | inx | |
| 2259 | - | bne draw_progress_label | |
| 2260 | - | draw_progress_label_done: | |
| 2261 | - | | |
| 2262 | - | lda #$1A ; Z label | |
| 2263 | - | sta SCREEN + (TRACK1_ROW * 40) | |
| 2264 | - | lda #TRACK1_NOTE_COL | |
| 2265 | - | sta COLRAM + (TRACK1_ROW * 40) | |
| 2266 | - | | |
| 2267 | - | lda #$18 ; X label | |
| 2268 | - | sta SCREEN + (TRACK2_ROW * 40) | |
| 2269 | - | lda #TRACK2_NOTE_COL | |
| 2270 | - | sta COLRAM + (TRACK2_ROW * 40) | |
| 2271 | - | | |
| 2272 | - | lda #$03 ; C label | |
| 2273 | - | sta SCREEN + (TRACK3_ROW * 40) | |
| 2274 | - | lda #TRACK3_NOTE_COL | |
| 2275 | - | sta COLRAM + (TRACK3_ROW * 40) | |
| 2276 | - | | |
| 1695 | + | cpx #16 | |
| 1696 | + | bne draw_health_bar | |
| 2277 | 1697 | rts | |
| 2278 | - | | |
| 2279 | - | score_label: | |
| 2280 | - | !scr "score:" | |
| 2281 | - | !byte 0 | |
| 2282 | - | | |
| 2283 | - | miss_label: | |
| 2284 | - | !scr "miss:" | |
| 2285 | - | !byte 0 | |
| 2286 | 1698 | | |
| 2287 | - | title_game: | |
| 2288 | - | !scr "sid symphony" | |
| 2289 | - | !byte 0 | |
| 1699 | + | ; ---------------------------------------------------------------------------- | |
| 1700 | + | ; Display Progress Bar | |
| 1701 | + | ; ---------------------------------------------------------------------------- | |
| 2290 | 1702 | | |
| 2291 | - | health_label: | |
| 2292 | - | !scr "health:" | |
| 2293 | - | !byte 0 | |
| 1703 | + | display_progress: | |
| 1704 | + | ; Calculate progress (song_beat / 4) | |
| 1705 | + | lda song_beat | |
| 1706 | + | lsr | |
| 1707 | + | lsr | |
| 1708 | + | sta temp_track | |
| 2294 | 1709 | | |
| 2295 | - | progress_label: | |
| 2296 | - | !scr "song:" | |
| 2297 | - | !byte 0 | |
| 1710 | + | ldx #0 | |
| 1711 | + | draw_progress_bar: | |
| 1712 | + | cpx temp_track | |
| 1713 | + | bcs draw_empty_progress | |
| 1714 | + | lda #CHAR_BAR_FULL | |
| 1715 | + | jmp store_progress_char | |
| 1716 | + | draw_empty_progress: | |
| 1717 | + | lda #CHAR_BAR_EMPTY | |
| 1718 | + | store_progress_char: | |
| 1719 | + | sta SCREEN + (PROGRESS_ROW * 40) + 8,x | |
| 1720 | + | lda #PROGRESS_COL | |
| 1721 | + | sta COLRAM + (PROGRESS_ROW * 40) + 8,x | |
| 1722 | + | inx | |
| 1723 | + | cpx #PROGRESS_WIDTH | |
| 1724 | + | bne draw_progress_bar | |
| 1725 | + | rts | |
| 2298 | 1726 | | |
| 2299 | 1727 | ; ---------------------------------------------------------------------------- | |
| 2300 | - | ; Initialize SID | |
| 1728 | + | ; Combo System | |
| 2301 | 1729 | ; ---------------------------------------------------------------------------- | |
| 2302 | 1730 | | |
| 2303 | - | init_sid: | |
| 2304 | - | ldx #$18 | |
| 1731 | + | increment_combo: | |
| 1732 | + | inc combo | |
| 1733 | + | lda combo | |
| 1734 | + | cmp max_combo | |
| 1735 | + | bcc combo_no_max | |
| 1736 | + | sta max_combo | |
| 1737 | + | combo_no_max: | |
| 1738 | + | jsr display_combo | |
| 1739 | + | rts | |
| 1740 | + | | |
| 1741 | + | break_combo: | |
| 2305 | 1742 | lda #0 | |
| 2306 | - | clear_sid: | |
| 2307 | - | sta SID,x | |
| 2308 | - | dex | |
| 2309 | - | bpl clear_sid | |
| 1743 | + | sta combo | |
| 1744 | + | jsr display_combo | |
| 1745 | + | rts | |
| 2310 | 1746 | | |
| 2311 | - | lda #$0F | |
| 2312 | - | sta SID_VOLUME | |
| 1747 | + | display_combo: | |
| 1748 | + | ; Display combo count | |
| 1749 | + | lda combo | |
| 1750 | + | ldx #0 | |
| 1751 | + | combo_div_100: | |
| 1752 | + | cmp #100 | |
| 1753 | + | bcc combo_done_100 | |
| 1754 | + | sec | |
| 1755 | + | sbc #100 | |
| 1756 | + | inx | |
| 1757 | + | jmp combo_div_100 | |
| 1758 | + | combo_done_100: | |
| 1759 | + | pha | |
| 1760 | + | txa | |
| 1761 | + | ora #$30 | |
| 1762 | + | sta SCREEN + (COMBO_ROW * 40) + 34 | |
| 2313 | 1763 | | |
| 2314 | - | lda #$00 | |
| 2315 | - | sta SID_V1_FREQ_LO | |
| 2316 | - | lda #VOICE1_FREQ | |
| 2317 | - | sta SID_V1_FREQ_HI | |
| 2318 | - | lda #PULSE_WIDTH | |
| 2319 | - | sta SID_V1_PWHI | |
| 2320 | - | lda #VOICE_AD | |
| 2321 | - | sta SID_V1_AD | |
| 2322 | - | lda #VOICE_SR | |
| 2323 | - | sta SID_V1_SR | |
| 1764 | + | pla | |
| 1765 | + | ldx #0 | |
| 1766 | + | combo_div_10: | |
| 1767 | + | cmp #10 | |
| 1768 | + | bcc combo_done_10 | |
| 1769 | + | sec | |
| 1770 | + | sbc #10 | |
| 1771 | + | inx | |
| 1772 | + | jmp combo_div_10 | |
| 1773 | + | combo_done_10: | |
| 1774 | + | pha | |
| 1775 | + | txa | |
| 1776 | + | ora #$30 | |
| 1777 | + | sta SCREEN + (COMBO_ROW * 40) + 35 | |
| 2324 | 1778 | | |
| 2325 | - | lda #$00 | |
| 2326 | - | sta SID_V2_FREQ_LO | |
| 2327 | - | lda #VOICE2_FREQ | |
| 2328 | - | sta SID_V2_FREQ_HI | |
| 2329 | - | lda #PULSE_WIDTH | |
| 2330 | - | sta SID_V2_PWHI | |
| 2331 | - | lda #VOICE_AD | |
| 2332 | - | sta SID_V2_AD | |
| 2333 | - | lda #VOICE_SR | |
| 2334 | - | sta SID_V2_SR | |
| 1779 | + | pla | |
| 1780 | + | ora #$30 | |
| 1781 | + | sta SCREEN + (COMBO_ROW * 40) + 36 | |
| 2335 | 1782 | | |
| 2336 | - | lda #$00 | |
| 2337 | - | sta SID_V3_FREQ_LO | |
| 2338 | - | lda #VOICE3_FREQ | |
| 2339 | - | sta SID_V3_FREQ_HI | |
| 2340 | - | lda #PULSE_WIDTH | |
| 2341 | - | sta SID_V3_PWHI | |
| 2342 | - | lda #VOICE_AD | |
| 2343 | - | sta SID_V3_AD | |
| 2344 | - | lda #VOICE_SR | |
| 2345 | - | sta SID_V3_SR | |
| 1783 | + | ; Colour based on multiplier | |
| 1784 | + | jsr get_multiplier | |
| 1785 | + | cmp #1 | |
| 1786 | + | beq combo_col_1x | |
| 1787 | + | cmp #2 | |
| 1788 | + | beq combo_col_2x | |
| 1789 | + | cmp #3 | |
| 1790 | + | beq combo_col_3x | |
| 1791 | + | jmp combo_col_4x | |
| 1792 | + | | |
| 1793 | + | combo_col_1x: | |
| 1794 | + | lda #11 ; Grey | |
| 1795 | + | jmp set_combo_col | |
| 1796 | + | combo_col_2x: | |
| 1797 | + | lda #7 ; Yellow | |
| 1798 | + | jmp set_combo_col | |
| 1799 | + | combo_col_3x: | |
| 1800 | + | lda #5 ; Green | |
| 1801 | + | jmp set_combo_col | |
| 1802 | + | combo_col_4x: | |
| 1803 | + | lda #1 ; White | |
| 1804 | + | | |
| 1805 | + | set_combo_col: | |
| 1806 | + | sta COLRAM + (COMBO_ROW * 40) + 34 | |
| 1807 | + | sta COLRAM + (COMBO_ROW * 40) + 35 | |
| 1808 | + | sta COLRAM + (COMBO_ROW * 40) + 36 | |
| 1809 | + | rts | |
| 2346 | 1810 | | |
| 1811 | + | get_multiplier: | |
| 1812 | + | lda combo | |
| 1813 | + | cmp #COMBO_TIER_4 | |
| 1814 | + | bcs mult_4x | |
| 1815 | + | cmp #COMBO_TIER_3 | |
| 1816 | + | bcs mult_3x | |
| 1817 | + | cmp #COMBO_TIER_2 | |
| 1818 | + | bcs mult_2x | |
| 1819 | + | lda #1 | |
| 1820 | + | rts | |
| 1821 | + | mult_2x: | |
| 1822 | + | lda #2 | |
| 1823 | + | rts | |
| 1824 | + | mult_3x: | |
| 1825 | + | lda #3 | |
| 1826 | + | rts | |
| 1827 | + | mult_4x: | |
| 1828 | + | lda #4 | |
| 2347 | 1829 | rts | |
| 2348 | 1830 | | |
| 2349 | 1831 | ; ---------------------------------------------------------------------------- | |
| ... | |||
| 2351 | 1833 | ; ---------------------------------------------------------------------------- | |
| 2352 | 1834 | | |
| 2353 | 1835 | reset_track_colours: | |
| 2354 | - | ldx #0 | |
| 1836 | + | ldx #1 ; Start at column 1 (skip label) | |
| 1837 | + | reset_col_loop: | |
| 2355 | 1838 | lda #TRACK_LINE_COL | |
| 2356 | - | reset_t1: | |
| 2357 | 1839 | sta COLRAM + (TRACK1_ROW * 40),x | |
| 2358 | - | inx | |
| 2359 | - | cpx #38 | |
| 2360 | - | bne reset_t1 | |
| 2361 | - | | |
| 2362 | - | ldx #0 | |
| 2363 | - | reset_t2: | |
| 2364 | 1840 | sta COLRAM + (TRACK2_ROW * 40),x | |
| 2365 | - | inx | |
| 2366 | - | cpx #38 | |
| 2367 | - | bne reset_t2 | |
| 2368 | - | | |
| 2369 | - | ldx #0 | |
| 2370 | - | reset_t3: | |
| 2371 | 1841 | sta COLRAM + (TRACK3_ROW * 40),x | |
| 2372 | 1842 | inx | |
| 2373 | 1843 | cpx #38 | |
| 2374 | - | bne reset_t3 | |
| 2375 | - | | |
| 2376 | - | lda #TRACK1_NOTE_COL | |
| 2377 | - | sta COLRAM + (TRACK1_ROW * 40) | |
| 2378 | - | lda #TRACK2_NOTE_COL | |
| 2379 | - | sta COLRAM + (TRACK2_ROW * 40) | |
| 2380 | - | lda #TRACK3_NOTE_COL | |
| 2381 | - | sta COLRAM + (TRACK3_ROW * 40) | |
| 1844 | + | bne reset_col_loop | |
| 2382 | 1845 | | |
| 1846 | + | ; Restore hit zone colours | |
| 2383 | 1847 | lda #HIT_ZONE_COL | |
| 2384 | 1848 | sta COLRAM + (TRACK1_ROW * 40) + HIT_ZONE_COLUMN | |
| 2385 | 1849 | sta COLRAM + (TRACK2_ROW * 40) + HIT_ZONE_COLUMN | |
| 2386 | 1850 | sta COLRAM + (TRACK3_ROW * 40) + HIT_ZONE_COLUMN | |
| 2387 | - | | |
| 2388 | - | jsr redraw_all_notes | |
| 2389 | - | | |
| 2390 | - | rts | |
| 2391 | - | | |
| 2392 | - | ; ---------------------------------------------------------------------------- | |
| 2393 | - | ; Redraw All Notes | |
| 2394 | - | ; ---------------------------------------------------------------------------- | |
| 2395 | 1851 | | |
| 2396 | - | redraw_all_notes: | |
| 1852 | + | ; Redraw notes with correct colours | |
| 2397 | 1853 | ldx #0 | |
| 2398 | 1854 | redraw_loop: | |
| 2399 | 1855 | lda note_track,x | |
| ... | |||
| 2525 | 1981 | lda #0 | |
| 2526 | 1982 | sta hit_quality | |
| 2527 | 1983 | clc | |
| 1984 | + | rts | |
| 1985 | + | | |
| 1986 | + | ; ---------------------------------------------------------------------------- | |
| 1987 | + | ; Check Song End | |
| 1988 | + | ; ---------------------------------------------------------------------------- | |
| 1989 | + | | |
| 1990 | + | check_song_end: | |
| 1991 | + | lda song_ended | |
| 1992 | + | beq not_ended | |
| 1993 | + | | |
| 1994 | + | ; Check if all notes cleared | |
| 1995 | + | ldx #0 | |
| 1996 | + | check_notes_clear: | |
| 1997 | + | lda note_track,x | |
| 1998 | + | bne not_ended | |
| 1999 | + | inx | |
| 2000 | + | cpx #MAX_NOTES | |
| 2001 | + | bne check_notes_clear | |
| 2002 | + | | |
| 2003 | + | ; Add delay before results | |
| 2004 | + | inc end_delay | |
| 2005 | + | lda end_delay | |
| 2006 | + | cmp #END_DELAY_FRAMES | |
| 2007 | + | bcc not_ended | |
| 2008 | + | | |
| 2009 | + | ; Show results | |
| 2010 | + | jsr show_results | |
| 2011 | + | lda #STATE_RESULTS | |
| 2012 | + | sta game_state | |
| 2013 | + | | |
| 2014 | + | not_ended: | |
| 2528 | 2015 | rts | |
| 2529 | 2016 | | |
| 2530 | 2017 | ; ---------------------------------------------------------------------------- | |
| ... | |||
| 2825 | 2312 | bne flash_t3h_loop | |
| 2826 | 2313 | lda #1 | |
| 2827 | 2314 | sta COLRAM + (TRACK3_ROW * 40) | |
| 2315 | + | rts | |
| 2316 | + | | |
| 2317 | + | ; ---------------------------------------------------------------------------- | |
| 2318 | + | ; Show Results Screen | |
| 2319 | + | ; ---------------------------------------------------------------------------- | |
| 2320 | + | | |
| 2321 | + | show_results: | |
| 2322 | + | ; Clear screen | |
| 2323 | + | ldx #0 | |
| 2324 | + | lda #CHAR_SPACE | |
| 2325 | + | clear_results: | |
| 2326 | + | sta SCREEN,x | |
| 2327 | + | sta SCREEN+$100,x | |
| 2328 | + | sta SCREEN+$200,x | |
| 2329 | + | sta SCREEN+$2E8,x | |
| 2330 | + | inx | |
| 2331 | + | bne clear_results | |
| 2332 | + | | |
| 2333 | + | ; Draw "SONG COMPLETE!" | |
| 2334 | + | ldx #0 | |
| 2335 | + | draw_complete: | |
| 2336 | + | lda complete_text,x | |
| 2337 | + | beq draw_results_score | |
| 2338 | + | sta SCREEN + (5 * 40) + 13,x | |
| 2339 | + | lda #5 | |
| 2340 | + | sta COLRAM + (5 * 40) + 13,x | |
| 2341 | + | inx | |
| 2342 | + | jmp draw_complete | |
| 2343 | + | | |
| 2344 | + | draw_results_score: | |
| 2345 | + | ; Draw score label | |
| 2346 | + | ldx #0 | |
| 2347 | + | draw_rs_label: | |
| 2348 | + | lda results_score_label,x | |
| 2349 | + | beq draw_rs_value | |
| 2350 | + | sta SCREEN + (9 * 40) + 12,x | |
| 2351 | + | lda #7 | |
| 2352 | + | sta COLRAM + (9 * 40) + 12,x | |
| 2353 | + | inx | |
| 2354 | + | jmp draw_rs_label | |
| 2355 | + | | |
| 2356 | + | draw_rs_value: | |
| 2357 | + | ; Draw score value | |
| 2358 | + | lda score_lo | |
| 2359 | + | sta work_lo | |
| 2360 | + | lda score_hi | |
| 2361 | + | sta work_hi | |
| 2362 | + | | |
| 2363 | + | ldx #0 | |
| 2364 | + | rs_div_10000: | |
| 2365 | + | lda work_lo | |
| 2366 | + | sec | |
| 2367 | + | sbc #<10000 | |
| 2368 | + | tay | |
| 2369 | + | lda work_hi | |
| 2370 | + | sbc #>10000 | |
| 2371 | + | bcc rs_done_10000 | |
| 2372 | + | sta work_hi | |
| 2373 | + | sty work_lo | |
| 2374 | + | inx | |
| 2375 | + | jmp rs_div_10000 | |
| 2376 | + | rs_done_10000: | |
| 2377 | + | txa | |
| 2378 | + | ora #$30 | |
| 2379 | + | sta SCREEN + (9 * 40) + 23 | |
| 2380 | + | | |
| 2381 | + | ldx #0 | |
| 2382 | + | rs_div_1000: | |
| 2383 | + | lda work_lo | |
| 2384 | + | sec | |
| 2385 | + | sbc #<1000 | |
| 2386 | + | tay | |
| 2387 | + | lda work_hi | |
| 2388 | + | sbc #>1000 | |
| 2389 | + | bcc rs_done_1000 | |
| 2390 | + | sta work_hi | |
| 2391 | + | sty work_lo | |
| 2392 | + | inx | |
| 2393 | + | jmp rs_div_1000 | |
| 2394 | + | rs_done_1000: | |
| 2395 | + | txa | |
| 2396 | + | ora #$30 | |
| 2397 | + | sta SCREEN + (9 * 40) + 24 | |
| 2398 | + | | |
| 2399 | + | ldx #0 | |
| 2400 | + | rs_div_100: | |
| 2401 | + | lda work_lo | |
| 2402 | + | sec | |
| 2403 | + | sbc #100 | |
| 2404 | + | bcc rs_done_100 | |
| 2405 | + | sta work_lo | |
| 2406 | + | inx | |
| 2407 | + | jmp rs_div_100 | |
| 2408 | + | rs_done_100: | |
| 2409 | + | txa | |
| 2410 | + | ora #$30 | |
| 2411 | + | sta SCREEN + (9 * 40) + 25 | |
| 2412 | + | | |
| 2413 | + | ldx #0 | |
| 2414 | + | rs_div_10: | |
| 2415 | + | lda work_lo | |
| 2416 | + | sec | |
| 2417 | + | sbc #10 | |
| 2418 | + | bcc rs_done_10 | |
| 2419 | + | sta work_lo | |
| 2420 | + | inx | |
| 2421 | + | jmp rs_div_10 | |
| 2422 | + | rs_done_10: | |
| 2423 | + | txa | |
| 2424 | + | ora #$30 | |
| 2425 | + | sta SCREEN + (9 * 40) + 26 | |
| 2426 | + | | |
| 2427 | + | lda work_lo | |
| 2428 | + | ora #$30 | |
| 2429 | + | sta SCREEN + (9 * 40) + 27 | |
| 2430 | + | | |
| 2431 | + | lda #7 | |
| 2432 | + | sta COLRAM + (9 * 40) + 23 | |
| 2433 | + | sta COLRAM + (9 * 40) + 24 | |
| 2434 | + | sta COLRAM + (9 * 40) + 25 | |
| 2435 | + | sta COLRAM + (9 * 40) + 26 | |
| 2436 | + | sta COLRAM + (9 * 40) + 27 | |
| 2437 | + | | |
| 2438 | + | ; Draw perfect count | |
| 2439 | + | ldx #0 | |
| 2440 | + | draw_perfect_label: | |
| 2441 | + | lda perfect_label,x | |
| 2442 | + | beq draw_perfect_value | |
| 2443 | + | sta SCREEN + (11 * 40) + 12,x | |
| 2444 | + | lda #1 | |
| 2445 | + | sta COLRAM + (11 * 40) + 12,x | |
| 2446 | + | inx | |
| 2447 | + | jmp draw_perfect_label | |
| 2448 | + | | |
| 2449 | + | draw_perfect_value: | |
| 2450 | + | lda perfect_count | |
| 2451 | + | ldx #0 | |
| 2452 | + | pv_div_10: | |
| 2453 | + | cmp #10 | |
| 2454 | + | bcc pv_done_10 | |
| 2455 | + | sec | |
| 2456 | + | sbc #10 | |
| 2457 | + | inx | |
| 2458 | + | jmp pv_div_10 | |
| 2459 | + | pv_done_10: | |
| 2460 | + | pha | |
| 2461 | + | txa | |
| 2462 | + | ora #$30 | |
| 2463 | + | sta SCREEN + (11 * 40) + 23 | |
| 2464 | + | pla | |
| 2465 | + | ora #$30 | |
| 2466 | + | sta SCREEN + (11 * 40) + 24 | |
| 2467 | + | lda #1 | |
| 2468 | + | sta COLRAM + (11 * 40) + 23 | |
| 2469 | + | sta COLRAM + (11 * 40) + 24 | |
| 2470 | + | | |
| 2471 | + | ; Draw good count | |
| 2472 | + | ldx #0 | |
| 2473 | + | draw_good_label: | |
| 2474 | + | lda good_label,x | |
| 2475 | + | beq draw_good_value | |
| 2476 | + | sta SCREEN + (12 * 40) + 12,x | |
| 2477 | + | lda #7 | |
| 2478 | + | sta COLRAM + (12 * 40) + 12,x | |
| 2479 | + | inx | |
| 2480 | + | jmp draw_good_label | |
| 2481 | + | | |
| 2482 | + | draw_good_value: | |
| 2483 | + | lda good_count | |
| 2484 | + | ldx #0 | |
| 2485 | + | gv_div_10: | |
| 2486 | + | cmp #10 | |
| 2487 | + | bcc gv_done_10 | |
| 2488 | + | sec | |
| 2489 | + | sbc #10 | |
| 2490 | + | inx | |
| 2491 | + | jmp gv_div_10 | |
| 2492 | + | gv_done_10: | |
| 2493 | + | pha | |
| 2494 | + | txa | |
| 2495 | + | ora #$30 | |
| 2496 | + | sta SCREEN + (12 * 40) + 23 | |
| 2497 | + | pla | |
| 2498 | + | ora #$30 | |
| 2499 | + | sta SCREEN + (12 * 40) + 24 | |
| 2500 | + | lda #7 | |
| 2501 | + | sta COLRAM + (12 * 40) + 23 | |
| 2502 | + | sta COLRAM + (12 * 40) + 24 | |
| 2503 | + | | |
| 2504 | + | ; Draw miss count | |
| 2505 | + | ldx #0 | |
| 2506 | + | draw_miss_label_r: | |
| 2507 | + | lda miss_label_r,x | |
| 2508 | + | beq draw_miss_value | |
| 2509 | + | sta SCREEN + (13 * 40) + 12,x | |
| 2510 | + | lda #2 | |
| 2511 | + | sta COLRAM + (13 * 40) + 12,x | |
| 2512 | + | inx | |
| 2513 | + | jmp draw_miss_label_r | |
| 2514 | + | | |
| 2515 | + | draw_miss_value: | |
| 2516 | + | lda miss_count | |
| 2517 | + | ldx #0 | |
| 2518 | + | mv_div_10: | |
| 2519 | + | cmp #10 | |
| 2520 | + | bcc mv_done_10 | |
| 2521 | + | sec | |
| 2522 | + | sbc #10 | |
| 2523 | + | inx | |
| 2524 | + | jmp mv_div_10 | |
| 2525 | + | mv_done_10: | |
| 2526 | + | pha | |
| 2527 | + | txa | |
| 2528 | + | ora #$30 | |
| 2529 | + | sta SCREEN + (13 * 40) + 23 | |
| 2530 | + | pla | |
| 2531 | + | ora #$30 | |
| 2532 | + | sta SCREEN + (13 * 40) + 24 | |
| 2533 | + | lda #2 | |
| 2534 | + | sta COLRAM + (13 * 40) + 23 | |
| 2535 | + | sta COLRAM + (13 * 40) + 24 | |
| 2536 | + | | |
| 2537 | + | ; Draw max combo | |
| 2538 | + | ldx #0 | |
| 2539 | + | draw_maxc_label: | |
| 2540 | + | lda maxcombo_label,x | |
| 2541 | + | beq draw_maxc_value | |
| 2542 | + | sta SCREEN + (15 * 40) + 12,x | |
| 2543 | + | lda #COMBO_COL | |
| 2544 | + | sta COLRAM + (15 * 40) + 12,x | |
| 2545 | + | inx | |
| 2546 | + | jmp draw_maxc_label | |
| 2547 | + | | |
| 2548 | + | draw_maxc_value: | |
| 2549 | + | lda max_combo | |
| 2550 | + | ldx #0 | |
| 2551 | + | mc_div_100: | |
| 2552 | + | cmp #100 | |
| 2553 | + | bcc mc_done_100 | |
| 2554 | + | sec | |
| 2555 | + | sbc #100 | |
| 2556 | + | inx | |
| 2557 | + | jmp mc_div_100 | |
| 2558 | + | mc_done_100: | |
| 2559 | + | pha | |
| 2560 | + | txa | |
| 2561 | + | ora #$30 | |
| 2562 | + | sta SCREEN + (15 * 40) + 23 | |
| 2563 | + | | |
| 2564 | + | pla | |
| 2565 | + | ldx #0 | |
| 2566 | + | mc_div_10: | |
| 2567 | + | cmp #10 | |
| 2568 | + | bcc mc_done_10 | |
| 2569 | + | sec | |
| 2570 | + | sbc #10 | |
| 2571 | + | inx | |
| 2572 | + | jmp mc_div_10 | |
| 2573 | + | mc_done_10: | |
| 2574 | + | pha | |
| 2575 | + | txa | |
| 2576 | + | ora #$30 | |
| 2577 | + | sta SCREEN + (15 * 40) + 24 | |
| 2578 | + | pla | |
| 2579 | + | ora #$30 | |
| 2580 | + | sta SCREEN + (15 * 40) + 25 | |
| 2581 | + | lda #COMBO_COL | |
| 2582 | + | sta COLRAM + (15 * 40) + 23 | |
| 2583 | + | sta COLRAM + (15 * 40) + 24 | |
| 2584 | + | sta COLRAM + (15 * 40) + 25 | |
| 2585 | + | | |
| 2586 | + | ; Draw "PRESS FIRE" | |
| 2587 | + | ldx #0 | |
| 2588 | + | draw_return: | |
| 2589 | + | lda return_text,x | |
| 2590 | + | beq results_done | |
| 2591 | + | sta SCREEN + (20 * 40) + 10,x | |
| 2592 | + | lda #11 | |
| 2593 | + | sta COLRAM + (20 * 40) + 10,x | |
| 2594 | + | inx | |
| 2595 | + | jmp draw_return | |
| 2596 | + | | |
| 2597 | + | results_done: | |
| 2598 | + | rts | |
| 2599 | + | | |
| 2600 | + | complete_text: | |
| 2601 | + | !scr "song complete!" | |
| 2602 | + | !byte 0 | |
| 2603 | + | | |
| 2604 | + | results_score_label: | |
| 2605 | + | !scr "final score:" | |
| 2606 | + | !byte 0 | |
| 2607 | + | | |
| 2608 | + | perfect_label: | |
| 2609 | + | !scr "perfect:" | |
| 2610 | + | !byte 0 | |
| 2611 | + | | |
| 2612 | + | good_label: | |
| 2613 | + | !scr "good:" | |
| 2614 | + | !byte 0 | |
| 2615 | + | | |
| 2616 | + | miss_label_r: | |
| 2617 | + | !scr "misses:" | |
| 2618 | + | !byte 0 | |
| 2619 | + | | |
| 2620 | + | maxcombo_label: | |
| 2621 | + | !scr "max combo:" | |
| 2622 | + | !byte 0 | |
| 2623 | + | | |
| 2624 | + | return_text: | |
| 2625 | + | !scr "press fire to continue" | |
| 2626 | + | !byte 0 | |
| 2627 | + | | |
| 2628 | + | ; ---------------------------------------------------------------------------- | |
| 2629 | + | ; Show Game Over Screen | |
| 2630 | + | ; ---------------------------------------------------------------------------- | |
| 2631 | + | | |
| 2632 | + | show_gameover: | |
| 2633 | + | ; Clear screen | |
| 2634 | + | ldx #0 | |
| 2635 | + | lda #CHAR_SPACE | |
| 2636 | + | clear_gameover: | |
| 2637 | + | sta SCREEN,x | |
| 2638 | + | sta SCREEN+$100,x | |
| 2639 | + | sta SCREEN+$200,x | |
| 2640 | + | sta SCREEN+$2E8,x | |
| 2641 | + | inx | |
| 2642 | + | bne clear_gameover | |
| 2643 | + | | |
| 2644 | + | ; Draw "GAME OVER" | |
| 2645 | + | ldx #0 | |
| 2646 | + | draw_gameover_text: | |
| 2647 | + | lda gameover_text,x | |
| 2648 | + | beq draw_gameover_score | |
| 2649 | + | sta SCREEN + (8 * 40) + 15,x | |
| 2650 | + | lda #2 | |
| 2651 | + | sta COLRAM + (8 * 40) + 15,x | |
| 2652 | + | inx | |
| 2653 | + | jmp draw_gameover_text | |
| 2654 | + | | |
| 2655 | + | draw_gameover_score: | |
| 2656 | + | ; Draw score | |
| 2657 | + | ldx #0 | |
| 2658 | + | draw_go_score_label: | |
| 2659 | + | lda gameover_score,x | |
| 2660 | + | beq draw_go_score_value | |
| 2661 | + | sta SCREEN + (12 * 40) + 12,x | |
| 2662 | + | lda #7 | |
| 2663 | + | sta COLRAM + (12 * 40) + 12,x | |
| 2664 | + | inx | |
| 2665 | + | jmp draw_go_score_label | |
| 2666 | + | | |
| 2667 | + | draw_go_score_value: | |
| 2668 | + | lda score_lo | |
| 2669 | + | sta work_lo | |
| 2670 | + | lda score_hi | |
| 2671 | + | sta work_hi | |
| 2672 | + | | |
| 2673 | + | ldx #0 | |
| 2674 | + | go_div_10000: | |
| 2675 | + | lda work_lo | |
| 2676 | + | sec | |
| 2677 | + | sbc #<10000 | |
| 2678 | + | tay | |
| 2679 | + | lda work_hi | |
| 2680 | + | sbc #>10000 | |
| 2681 | + | bcc go_done_10000 | |
| 2682 | + | sta work_hi | |
| 2683 | + | sty work_lo | |
| 2684 | + | inx | |
| 2685 | + | jmp go_div_10000 | |
| 2686 | + | go_done_10000: | |
| 2687 | + | txa | |
| 2688 | + | ora #$30 | |
| 2689 | + | sta SCREEN + (12 * 40) + 23 | |
| 2690 | + | | |
| 2691 | + | ldx #0 | |
| 2692 | + | go_div_1000: | |
| 2693 | + | lda work_lo | |
| 2694 | + | sec | |
| 2695 | + | sbc #<1000 | |
| 2696 | + | tay | |
| 2697 | + | lda work_hi | |
| 2698 | + | sbc #>1000 | |
| 2699 | + | bcc go_done_1000 | |
| 2700 | + | sta work_hi | |
| 2701 | + | sty work_lo | |
| 2702 | + | inx | |
| 2703 | + | jmp go_div_1000 | |
| 2704 | + | go_done_1000: | |
| 2705 | + | txa | |
| 2706 | + | ora #$30 | |
| 2707 | + | sta SCREEN + (12 * 40) + 24 | |
| 2708 | + | | |
| 2709 | + | ldx #0 | |
| 2710 | + | go_div_100: | |
| 2711 | + | lda work_lo | |
| 2712 | + | sec | |
| 2713 | + | sbc #100 | |
| 2714 | + | bcc go_done_100 | |
| 2715 | + | sta work_lo | |
| 2716 | + | inx | |
| 2717 | + | jmp go_div_100 | |
| 2718 | + | go_done_100: | |
| 2719 | + | txa | |
| 2720 | + | ora #$30 | |
| 2721 | + | sta SCREEN + (12 * 40) + 25 | |
| 2722 | + | | |
| 2723 | + | ldx #0 | |
| 2724 | + | go_div_10: | |
| 2725 | + | lda work_lo | |
| 2726 | + | sec | |
| 2727 | + | sbc #10 | |
| 2728 | + | bcc go_done_10 | |
| 2729 | + | sta work_lo | |
| 2730 | + | inx | |
| 2731 | + | jmp go_div_10 | |
| 2732 | + | go_done_10: | |
| 2733 | + | txa | |
| 2734 | + | ora #$30 | |
| 2735 | + | sta SCREEN + (12 * 40) + 26 | |
| 2736 | + | | |
| 2737 | + | lda work_lo | |
| 2738 | + | ora #$30 | |
| 2739 | + | sta SCREEN + (12 * 40) + 27 | |
| 2740 | + | | |
| 2741 | + | lda #7 | |
| 2742 | + | sta COLRAM + (12 * 40) + 23 | |
| 2743 | + | sta COLRAM + (12 * 40) + 24 | |
| 2744 | + | sta COLRAM + (12 * 40) + 25 | |
| 2745 | + | sta COLRAM + (12 * 40) + 26 | |
| 2746 | + | sta COLRAM + (12 * 40) + 27 | |
| 2747 | + | | |
| 2748 | + | ; Draw retry message | |
| 2749 | + | ldx #0 | |
| 2750 | + | draw_retry: | |
| 2751 | + | lda retry_text,x | |
| 2752 | + | beq gameover_done | |
| 2753 | + | sta SCREEN + (18 * 40) + 10,x | |
| 2754 | + | lda #11 | |
| 2755 | + | sta COLRAM + (18 * 40) + 10,x | |
| 2756 | + | inx | |
| 2757 | + | jmp draw_retry | |
| 2758 | + | | |
| 2759 | + | gameover_done: | |
| 2828 | 2760 | rts | |
| 2761 | + | | |
| 2762 | + | gameover_text: | |
| 2763 | + | !scr "game over" | |
| 2764 | + | !byte 0 | |
| 2765 | + | | |
| 2766 | + | gameover_score: | |
| 2767 | + | !scr "your score:" | |
| 2768 | + | !byte 0 | |
| 2769 | + | | |
| 2770 | + | retry_text: | |
| 2771 | + | !scr "press fire to continue" | |
| 2772 | + | !byte 0 | |
| 2829 | 2773 | | |
| 2830 | 2774 | ; ============================================================================ | |
| 2831 | - | ; SONG DATA - First Song (Balanced for Phase 1) | |
| 2775 | + | ; SONG DATA - First Song: "First Steps" | |
| 2832 | 2776 | ; ============================================================================ | |
| 2833 | 2777 | ; Format: beat, track (1-3), SID frequency high byte | |
| 2834 | - | ; Note spacing provides learnable pattern with variety | |
| 2835 | 2778 | ; ============================================================================ | |
| 2836 | 2779 | | |
| 2837 | 2780 | song_data: | |
| ... | |||
| 2909 | 2852 | max_combo: !byte 0 | |
| 2910 | 2853 | | |
| 2911 | 2854 | ; ============================================================================ | |
| 2912 | - | ; END OF SID SYMPHONY - PHASE 1 COMPLETE | |
| 2855 | + | ; END OF SID SYMPHONY - UNIT 17 | |
| 2913 | 2856 | ; ============================================================================ | |
| 2914 | 2857 | |