gb-tarot/Audio.inc

348 lines
5.8 KiB
PHP

PUSHS "Sound Variables", WRAM0[AUDIO_VARS_START]
ordersStart: dw
println "orders start is ", ordersStart
ordersLength: db
; audio player state
currentOrderNumber: db
currentRowNumber: db
println "currentRowNumber is ", currentRowNumber
currentTickNumber: db
currentPattern: dw
println "current pattern is ", currentPattern
audioReadHead: dw
AUDIO_VARIABLES_BEGIN:
speed: db
macro channel ; macro to define all the channell data in parallel
channel_\1_note: db
channel_\1_duty: db
channel_\1_volume: db
channel_\1_slide: db
channel_\1_arp: db
channel_\1_pan: db
channel_\1_vibrato: db
channel_\1_trigger: db
endm
channel 1
channel 2
channel 3
channel 4
println "channel 1 note is ", channel_1_note
AUDIO_VARIABLES_END:
POPS
SoundSetup:
ld a, LOW(gbtarottheme)
ld [ordersStart], a
ld a, HIGH(gbtarottheme)
ld [ordersStart+1], a
ld a, 0
ld [currentOrderNumber], a
ld [currentRowNumber], a
ld [currentTickNumber], a
ld a, $FF
ld [currentRowNumber], a
ld a, [ordersStart]
ld l, a
ld a, [ordersStart+1]
ld h, a
inc hl
ld a, [hl+]
ld [currentPattern], a
ld [audioReadHead], a
ld a, [hl+]
ld [currentPattern+1], a
ld [audioReadHead+1], a
ld hl, ZEROES
ld de, AUDIO_VARIABLES_BEGIN
ld bc, AUDIO_VARIABLES_END - AUDIO_VARIABLES_BEGIN
call CopyRange
ld a, 6
ld [speed], a
ld a, %1000_1111
ld [rNR52], a
ld a, $ff
ld [rNR51], a
ld a, $11
ld [rNR50], a
ret
SoundUpdate:
ld a, [speed]
ld b, a
ld a, [currentTickNumber]
inc a
call ArrayClampLoopingB
ld [currentTickNumber], a
cp a, 0
jp nz, .doneAllPackets ; if we're not zero, then just update the things
ld b, 64
ld a, [currentRowNumber]
inc a
call ArrayClampLoopingB
ld [currentRowNumber], a
cp a, 0
jp nz, :+ ; if the new row number is zero, then we go to the next pattern.
ld a, AUDHIGH_RESTART
ld [rNR14], a
; TODO: update for song orders
ld a, [currentPattern]
ld [audioReadHead], a
ld a, [currentPattern+1]
ld [audioReadHead+1], a
:
ld a, [audioReadHead]
ld l, a
ld a, [audioReadHead+1]
ld h, a
ld a, [currentRowNumber]
ld b, a
ld a, [hl+]
and a, $F0
cp a, 0
ret nz
ld a, [hl+]
cp a, b
jp nz, .doneAllPackets ; return if the current row doesn't equal the row we're looking at
; else we're looking at packets
.packetExamine
ld a, l
ld [audioReadHead], a
ld a, h
ld [audioReadHead+1], a
ld d, h
ld e, l
ld hl, channel_1_note
ld a, [de]
and a, $0F
cp a, 1
jp nz, :+
ld hl, channel_1_note
: cp a, 2
jp nz, :+
ld hl, channel_2_note
: cp a, 3
jp nz, :+
ld hl, channel_3_note
: cp a, 4
jp nz, :+
ld hl, channel_4_note
:
ld a, [de]
and a, $F0 ; grab the top nibble of [hl], which holds the effect.
; if nibble is zero, then update our read head (already done) and return.
cp a, $00
jp z, .doneAllPackets
ld bc, channel_1_note - channel_1_note
cp a, $10
jp z, .updateValue
ld bc, channel_1_volume - channel_1_note
cp a, $20
jp z, .updateVolume
ld bc, channel_1_duty - channel_1_note
cp a, $30
jp z, .updateValue
ld bc, channel_1_pan - channel_1_note
cp a, $40
jp z, .updateValue
ld bc, channel_1_arp - channel_1_note
cp a, $50
jp z, .updateValue
ld bc, channel_1_vibrato - channel_1_note
cp a, $60
jp z, .updateValue
ld bc, channel_1_slide - channel_1_note
cp a, $70
jp z, .updateValue
ld bc, channel_1_volume - channel_1_note
cp a, $80
jp z, .noteCut
cp a, $90
jp z, .patternJump
cp a, $a0
jp z, .breakSetStep
cp a, $b0
jp z, .setSpeed
cp a, $c0
jp z, .event
; and now a bunch of code for handling all those cases!
.updateVolume:
inc de
add hl, bc
ld a, 0
ld [channel_1_trigger], a
ld a, [hl]
cp a, 0
jp nz, :+
; if the volume is zero to start with,
; and the new volume is nonzero,
ld a, [de]
; set the trigger flag
cp a, 0
jp z, :+
ld a, AUDHIGH_RESTART
ld [channel_1_trigger], a
:
ld a, [de]
ld [hl], a
inc de
ld h, d
ld l, e
jp .packetExamine
.updateValue:
inc de
add hl, bc
: ld a, [de]
ld [hl], a
inc de
ld h, d
ld l, e
jp .packetExamine
.noteCut:
inc de
add hl, bc
ld [hl], 0
ld a, AUDHIGH_RESTART
ld [channel_1_trigger], a
inc de
ld h, d
ld l, e
jp .packetExamine
.patternJump:
; TODO
inc de
inc de
ld h, d
ld l, e
jp .packetExamine
.breakSetStep:
; TODO
inc de
inc de
ld h, d
ld l, e
jp .packetExamine
.setSpeed:
inc de
ld a, [de]
ld [speed], a
inc de
ld h, d
ld l, e
jp .packetExamine
.event:
; TODO
inc de
inc de
ld h, d
ld l, e
jp .packetExamine
.doneAllPackets:
call Channel_1_Update
call Channel_2_Update
call Channel_3_Update
call Channel_4_Update
ret
Channel_1_Update:
ld a, [channel_1_duty]
or a, $0a
ld [rNR11], a
ld a, [channel_1_volume]
sla a
sla a
sla a
sla a
and a, $F0
ld [rNR12], a
ld a, [channel_1_note]
ld hl, note_periods
ld b, 0
ld c, a
add hl, bc
add hl, bc ; double width values
ld a, [hl+]
ld [rNR13], a
ld a, [channel_1_trigger]
or a, [hl]
or a, AUDHIGH_LENGTH_OFF
ld [rNR14], a
ld a, 0
ld [channel_1_trigger], a
ret
Channel_2_Update:
Channel_3_Update:
Channel_4_Update:
ret
note_periods:
dw 44, 156, 262, 363, 457, 547, 631, 710, 786, 854, 923, 986, ; C3 to B3
dw 1046,1102,1155,1205,1253,1297,1339,1379,1417,1452,1486,1517, ; C4 to B4
dw 1546,1575,1602,1627,1650,1673,1694,1714,1732,1750,1767,1783, ; C5 to B5
dw 1798,1812,1825,1837,1849,1860,1871,1881,1890,1899,1907,1915, ; C6 to B6
dw 1923,1930,1936,1943,1949,1954,1959,1964,1969,1974,1978,1982, ; C7 to B7
dw 1985,1988,1992,1995,1998,2001,2004,2006,2009,2011,2013,2015 ; C8 to B8
INCLUDE "theme.inc"