keen: more work on sound

This commit is contained in:
Vince Weaver 2024-04-04 00:14:27 -04:00
parent c36dfba91b
commit d48ecfc5da
7 changed files with 68 additions and 442 deletions

View File

@ -51,7 +51,7 @@ KEEN_MARS: keen_mars.o
ld65 -o KEEN_MARS keen_mars.o -C ../../linker_scripts/apple2_2000.inc
keen_mars.o: keen_mars.s zp.inc hardware.inc game_over.s \
sound_effects.s speaker_tone.s print_help.s \
sound_effects.s longer_sound.s print_help.s \
maps/mars_map.gr.zx02 graphics/parts.gr.zx02
ca65 -o keen_mars.o keen_mars.s -l keen_mars.lst
@ -67,7 +67,7 @@ keen_level1.o: keen_level1.s zp.inc hardware.inc \
maps/level1_map.lzsa \
status_bar.s draw_keen.s move_keen.s gr_putsprite_crop.s \
draw_tilemap.s \
sound_effects.s speaker_tone.s \
sound_effects.s longer_sound.s \
keyboard.s handle_laser.s
ca65 -o keen_level1.o keen_level1.s -l keen_level1.lst
@ -83,7 +83,7 @@ keen_level2.o: keen_level2.s zp.inc hardware.inc \
maps/level2_map.lzsa \
status_bar.s draw_keen.s move_keen.s gr_putsprite_crop.s \
draw_tilemap.s \
sound_effects.s speaker_tone.s \
sound_effects.s longer_sound.s \
keyboard.s handle_laser.s
ca65 -o keen_level2.o keen_level2.s -l keen_level2.lst

View File

@ -1,176 +1,20 @@
Working on better music effects
Start at mars (and after die and return to map):
Keensleft
Based on dumped code by the "KeenFX" tool
Start level
WLDENTRSND
Die
KEENDIESND
Note: 65535-value = note freq
Level Done
LVLDONESND
3) WLDENTERSND
64155, 10 ; 1380Hz F6?
63495, 5 ;
0,16
62355,2
62175,16
60855,2
0,14
60255,5
69595,13
0,13
58455,1
Game over
GAMEOVERSND
58275,1
58215,1
57975,1
58275,1
57915
57600
57735,2
57915
57675
57795
57615
57675
56555
15) LVLDONESND (door)
63735,4 E5
0,9
65735,6 E5
0,8
63735,6 E5
0,15
60975,2 C4
60915,5
0,11
61515,12 D4 (roughly)
61455,1
0,7
58275,1 E3
58755,10 F3
58695,1 F3
58755,1 F3
0,6
58655, F3
56715, C#3
0,4
56595,6 C3
0,7
57255, D3
57315, D3
0,2
57195,3 D3
57255,3 D3
57315,1 D3
0,9
57915, D#3
57600, D#3
0,3
57795,3 D#3
57600,4 D#3
0,11
58935, F3
58875
0,3
58995,29 F#3
0,12
55515,4 B2
55575,5
55515,1
55575,4
0,11
64935,5 C6
8) KEENDIESND
64515,4
0,14
62655,4
0,14
64515,5
0,15
62655,5
0,12
64575,4
0,12
62655,4
0,12
63795,3
0,20
61155,
61035
60855
60675
60555
60375
60195
60075
59895
59775
59655
59535
59475
59415
59295,2
59235
59175
59115
59065
58995,2
58935
58875,9
58935,2
58995
59065
59115
59175,2
59295
59415
59535
59775
60135
60555
60855
61095
61155
61215,2
61155,2
61095,3
61035
60915
60795
60735
60615
60555
60495
60255
60135
60015
59895
59895
59835
59775
59715,3
59835
59895,2
60075
60135
60255
60075
60615
60855
61515
61875
62295
63315
63435
63615
63675
63915
63975
64095
64215
64575
64875
TODO: 16) GAMEOVERSND
Get item
GOTITEMSND
Shoot laser
GUNCLICK

View File

@ -209,7 +209,7 @@ level1_bg_zx02:
.include "item_level1.s"
.include "sound_effects.s"
.include "speaker_tone.s"
.include "longer_sound.s"
level1_data_zx02:
.incbin "maps/level1_map.zx02"

View File

@ -188,7 +188,7 @@ parts_zx02:
.include "sound_effects.s"
.include "speaker_tone.s"
.include "longer_sound.s"

48
games/keen/longer_sound.s Normal file
View File

@ -0,0 +1,48 @@
; Based on redbook_sound.s
; it's originally by Paul Lutus, from the Apple II Red Book p45
; which can only do roughly 194Hz to 2000Hz+
; this makes things twice as long, which allows lower notes, but
; loses some precision on high notes
; also modified so "0" means no sound
;=====================================================
; speaker tone
;=====================================================
; A,X,Y trashed
; duration also trashed
; more exactly, it is (4+10F)+(13+10F) = 20F+17
speaker_tone:
ldy #0 ; 3
speaker_tone_loop:
lda $C030 ; click speaker ; 4
speaker_loop:
nop
nop
nop
nop
nop
dey ; ; 2
bne freq_loop ; ; 2/3
dec speaker_duration ; (Duration) ; 6
beq done_tone ; 2/3
freq_loop:
dex ; 2
bne speaker_loop ; 2/3
ldx speaker_frequency ; (Frequency) ; 4
beq speaker_loop ; play nothing if 0 ; 2/3
jmp speaker_tone_loop ; 3
done_tone:
rts
speaker_duration:
.byte $00
speaker_frequency:
.byte $00

View File

@ -1,127 +1,22 @@
;=====================
; entry music
entry_music:
lda SOUND_STATUS
bmi done_entry_music
; music from _mr_m_ on Commander Keen Forum, Jun 5 2009
; 4* D5 32
; 4* A4 32
; D5 A4 D5 G5 (all 8th)
lda #0
sta MUSIC_PTR
entry_music_loop:
ldx MUSIC_PTR
lda entry_music_freq,X
beq done_entry_music
sta speaker_frequency
lda entry_music_len,X
sta speaker_duration
jsr speaker_tone
lda #100
jsr WAIT ; FIXME: won't work if language card active
inc MUSIC_PTR
jmp entry_music_loop
done_entry_music:
rts
entry_music_freq:
.byte NOTE_D5,NOTE_D5,NOTE_D5,NOTE_D5
.byte NOTE_A4,NOTE_A4,NOTE_A4,NOTE_A4
.byte NOTE_D5,NOTE_A4,NOTE_D5,NOTE_G5
.byte 0
entry_music_len:
.byte 16,16,16,16
.byte 16,16,16,16
.byte 64,64,64,64
;=====================
; exit music
exit_music:
lda SOUND_STATUS
bmi done_exit_music
; all 16 notes
; F#4 A#4 C5 D5 D#5 F5
; G4 G4 G4
lda #0
sta MUSIC_PTR
exit_music_loop:
ldx MUSIC_PTR
lda exit_music_freq,X
beq done_exit_music
sta speaker_frequency
lda exit_music_len,X
sta speaker_duration
jsr speaker_tone
lda #100
jsr WAIT ; FIXME: won't work if language card active
inc MUSIC_PTR
jmp exit_music_loop
done_exit_music:
rts
; all 16 notes
; F#4 A#4 C5 D5 D#5 F5
; G4 G4 G4
exit_music_freq:
.byte NOTE_FSHARP4,NOTE_ASHARP4,NOTE_C5,NOTE_D5
.byte NOTE_DSHARP5,NOTE_F5,NOTE_G4,NOTE_G4
.byte NOTE_G4
.byte 0
exit_music_len:
.byte 48,48,48,48
.byte 48,48,48,48
.byte 48
;======================
; noise when jump
jump_noise:
lda SOUND_STATUS
bmi done_jump_noise
; bit $C030
done_jump_noise:
rts
;======================
; noise when bump head
head_noise:
lda SOUND_STATUS
bmi done_head_noise
lda #NOTE_D3
sta speaker_frequency
lda #5
sta speaker_duration
jsr speaker_tone
; bit $C030
; bit $C030
done_head_noise:
rts
@ -132,51 +27,17 @@ land_noise:
lda SOUND_STATUS
bmi done_land_noise
; bit $C030
done_land_noise:
rts
;======================
; rumble noise
rumble_noise:
lda SOUND_STATUS
bmi done_rumble_noise
ldx #50
rumble_red:
bit $C030
lda #100
jsr WAIT
dex
bne rumble_red
done_rumble_noise:
rts
;======================
; pickup noise
; C, two octaves+C?
pickup_noise:
lda SOUND_STATUS
bmi done_pickup_noise
lda #NOTE_C3
sta speaker_frequency
lda #25
sta speaker_duration
jsr speaker_tone
lda #NOTE_C5
sta speaker_frequency
lda #20
sta speaker_duration
jsr speaker_tone
done_pickup_noise:
rts
@ -189,11 +50,6 @@ buzzer_noise:
lda SOUND_STATUS
bmi done_buzzer_noise
lda #NOTE_C3
sta speaker_frequency
lda #10
sta speaker_duration
jsr speaker_tone
done_buzzer_noise:
rts
@ -209,18 +65,6 @@ enemy_noise:
lda SOUND_STATUS
bmi done_enemy_noise
lda #NOTE_A3
sta speaker_frequency
lda #20
sta speaker_duration
jsr speaker_tone
lda #NOTE_A4
sta speaker_frequency
lda #10
sta speaker_duration
jsr speaker_tone
done_enemy_noise:
rts
@ -231,11 +75,6 @@ laser_noise:
lda SOUND_STATUS
bmi done_enemy_noise
lda #NOTE_D4
sta speaker_frequency
lda #15
sta speaker_duration
jsr speaker_tone
done_laser_noise:
rts

View File

@ -1,105 +0,0 @@
; this code was widely shared for playing tones on Apple II
; by POKEing the machine language and CALLing from BASIC
; it's originally by Paul Lutus, from the Apple II Red Book p45
; it's hard to find good info on this, but loading from $C030
; "toggles" the speaker. So toggling twice is esentially a square wave?
; using regular load/store/bit of $C030 is safe. Some of the more
; advanced addressing modes can double-toggle due to how some 6502
; implementations run the address bus
; these seem to have been calculated assuming a 1MHz clock
; but the Apple II actually runs at roughly 1.023MHz
; or a frequency of 1/(speaker_freq*20.46e-6)
; to go other way, speaker_freq=1/(freq*20.46e-6)
; this table of notes was from
; http://eightbitsoundandfury.ld8.org/programming.html
; but seems off a bit and also assumes 1MHz clock
; 1MHz 1.023MHz
NOTE_C3 = 255 ; G3 5217us = 192Hz (G3, 5218us = 196Hz 249)
NOTE_CSHARP3 = 241 ; G#3 4931us = 203Hz (G#3, 4931us = 207Hz
NOTE_D3 = 227 ; A3
NOTE_DSHARP3 = 214 ; A#3
NOTE_E3 = 202 ; B3
NOTE_F3 = 191 ; C4
NOTE_FSHARP3 = 180 ; C#4
NOTE_G3 = 170 ; D4
NOTE_GSHARP3 = 161 ; D#4
NOTE_A3 = 152 ; E3
NOTE_ASHARP3 = 143 ; F3
NOTE_B3 = 135 ; F#3
NOTE_C4 = 128 ; G
NOTE_CSHARP4 = 121 ; G#
NOTE_D4 = 114 ; A
NOTE_DSHARP4 = 108 ; A#
NOTE_E4 = 102 ; B3
NOTE_F4 = 96 ; C
NOTE_FSHARP4 = 91 ; C#
NOTE_G4 = 85 ; D
NOTE_GSHARP4 = 81 ; D#
NOTE_A4 = 76 ; E
NOTE_ASHARP4 = 72 ; F
NOTE_B4 = 68 ; F#
NOTE_C5 = 64 ; G
NOTE_CSHARP5 = 60 ; G#
NOTE_D5 = 57 ; A
NOTE_DSHARP5 = 54 ; A#
NOTE_E5 = 51 ; B3
NOTE_F5 = 48 ; C
NOTE_FSHARP5 = 45 ; C#
NOTE_G5 = 43 ; D
NOTE_GSHARP5 = 40 ; D#
NOTE_A5 = 38 ; E
NOTE_ASHARP5 = 36 ; F
NOTE_B5 = 34 ; F#
;=====================================================
; speaker tone
;=====================================================
; A,X,Y trashed
; duration also trashed
; this was designed by basic to be poked into 770 ($302)
; on an Applesoft CALL, X=$9d, Y=$02 (A,Y = Address to call)
; it was originally designed for Integer BASIC where Y=0 on call
; and it was poked to $00 (zero page)
; the inner freq loop is roughly FREQ*10cycles
; so the square wave generated has a period of
; freq*20*1.023us
; or a frequency of 1/(freq*20.46e-6)
; more exactly, it is (4+10F)+(13+10F) = 20F+17
speaker_tone:
ldy #0 ; 3
speaker_tone_loop:
lda $C030 ; click speaker ; 4
speaker_loop:
dey ; ; 2
bne freq_loop ; ; 2/3
dec speaker_duration ; (Duration) ; 6
beq done_tone ; 2/3
freq_loop:
dex ; 2
bne speaker_loop ; 2/3
ldx speaker_frequency ; (Frequency) ; 4
jmp speaker_tone_loop ; 3
done_tone:
rts
speaker_duration:
.byte $00
speaker_frequency:
.byte $00