Sound Effects and PlaySound - HoraceAndTheSpider/Bloodwych-68k GitHub Wiki
Sound effects and PlaySound
Bloodwych SPS 439 stores five 8SVX sound samples in the executable. The game
does not pass a sample address to the playback routine. Instead, callers put a
zero-based sound ID in D0 and call PlaySound.
The routine is at memory address $8910 (binary offset $858C) in the SPS
439 source. It uses the ID to select one of six entries in
AudioSampleOffsets, so IDs 0 and 1 are two sounds located inside the first
sample file rather than two separate files.
Sound IDs
The following names describe the IDs used by the source. The broad sample descriptions are also consistent with the extracted-sample notes in the project archive.
ID in D0 |
Source selection | Sound description | Evidence / known callers |
|---|---|---|---|
$00 |
sample1.sound; period $28 |
Switch or interface click | Played during startup and the wall-switch action path. The extracted sample is documented as “Click / Switch”. |
$01 |
sample1.sound; period $9B |
Secondary click variant | This is the second playback entry within sample1.sound; the exact gameplay event for this variant is not isolated in the current SPS 439 call trace. |
$02 |
sample2.sound; period $5D |
Attack or fighting clink | Played by the physical-attack routine at adrCd0061DA. The extracted sample is documented as “Clink / Fighting”. |
$03 |
sample3.sound; period $28 |
Character death | Played from the character death-state handling path at adrCd0024BE. The extracted sample is documented as “Character Death”. |
$04 |
sample4.sound; period $49 |
Spell or fireball sound | Selected by the special-effect path at adrCd001E08. The extracted sample is documented as “Spell Sound / Fireball”. |
$05 |
sample5.sound; period $49 |
Alternative spell sound | Used by several spell, crystal, and Vivify-machine effect paths. The extracted sample is documented as “Alternative Spell Sound”. |
The descriptions distinguish the sound resources and their call-site context; they should not be read as a claim that every use of a shared sample has a different recording.
The PlaySound routine
The routine uses Paula audio channel 0. In simplified form, its operation is:
PlaySound:
move.w d1,-(sp) ; preserve the caller's D1
move.w #$0001,_custom+dmacon.l ; stop channel 0 DMA
move.w #$0080,_custom+intena.l ; disable the audio interrupt
asl.w #$02,d0 ; six entries, four bytes each
lea SFX_AudioSample_1.l,a0
add.w AudioSampleOffsets(pc,d0.w),a0
move.w AudioSampleOffsets+$2(pc,d0.w),d0
lea $0030(a0),a0 ; skip the 8SVX header
move.w -$0002(a0),d1 ; sample length before the body
lsr.w #$01,d1 ; Paula length is in words
asl.w #$02,d0 ; convert the period value
move.l a0,_custom+aud.l
move.w d1,_custom+aud0+ac_len.l
move.w #$0040,_custom+aud0+ac_vol.l
move.w d0,_custom+aud0+ac_per.l
move.w (a0),_custom+aud0+ac_dat.l
; short delay, enable channel 0 DMA, short delay
; clear the request, restore interrupts and restore D1
rts
The real routine is deliberately retained as the authoritative source in
asm/BLOODWYCH439.asm; the extract above shows the data flow rather than every
timing instruction.
Before programming Paula, the routine advances by $30 bytes from the
selected sound-file base. This skips the 8SVX header and leaves A0 pointing
at the sample body. The word immediately before that body supplies the sample
length. The routine halves that value because Paula's length register counts
words, not bytes.
The second word in each AudioSampleOffsets pair is loaded as a playback
period and multiplied by four before being written to aud0+ac_per. This is a
sample-specific playback-rate setting, not another byte offset.
AudioSampleOffsets
Each table entry is four bytes:
- a word offset from
SFX_AudioSample_1to the containing sound file; - a Paula playback-period value, multiplied by four before it is written to
aud0+ac_per; and - the next entry begins immediately after those two words.
In source form, the table is:
AudioSampleOffsets:
dc.w SFX_AudioSample_1-SFX_AudioSample_1 ; ID 0: $0000
dc.w $0028 ; ID 0 period
dc.w SFX_AudioSample_1-SFX_AudioSample_1 ; ID 1: $0000
dc.w $009B ; ID 1 period
dc.w SFX_AudioSample_2-SFX_AudioSample_1 ; ID 2: $0084
dc.w $005D ; ID 2 period
dc.w SFX_AudioSample_3-SFX_AudioSample_1 ; ID 3: $0646
dc.w $0028 ; ID 3 period
dc.w SFX_AudioSample_4-SFX_AudioSample_1 ; ID 4: $1ECE
dc.w $0049 ; ID 4 period
dc.w SFX_AudioSample_5-SFX_AudioSample_1 ; ID 5: $3684
dc.w $0049 ; ID 5 period
The table begins at memory address $8938 (binary offset $85B4). The first
words also show that the five sound files are stored sequentially: sample 2
starts $84 bytes after sample 1, sample 3 starts $646 bytes after sample 1,
sample 4 starts $1ECE, and sample 5 starts $3684.
Extracted sound resources
The SPS 439 extraction names these files using the .sound faux-extension.
They are the original binary sample blocks, not converted or normalised audio
files.
| File | Binary offset | Size | Source label |
|---|---|---|---|
data/BLOODWYCH439-clean/sfx/sample1.sound |
$5409E |
$84 |
SFX_AudioSample_1 |
data/BLOODWYCH439-clean/sfx/sample2.sound |
$54122 |
$5C2 |
SFX_AudioSample_2 |
data/BLOODWYCH439-clean/sfx/sample3.sound |
$546E4 |
$1888 |
SFX_AudioSample_3 |
data/BLOODWYCH439-clean/sfx/sample4.sound |
$55F6C |
$17B6 |
SFX_AudioSample_4 |
data/BLOODWYCH439-clean/sfx/sample5.sound |
$57722 |
$D82 |
SFX_AudioSample_5 |
These are sequential in the original binary. Their source memory labels are
$54422, $544A6, $54A68, $562F0, and $57AA6 respectively.
Call-site examples
The fixed-ID call sites in SPS 439 include:
moveq #$00,d0
jsr PlaySound.l ; startup click
moveq #$02,d0
bsr PlaySound ; physical attack
moveq #$01,d0
bsr PlaySound ; wall-feature / door click
moveq #$03,d0
jsr PlaySound.l ; character death path
moveq #$04,d0
jsr PlaySound.l ; spell effect
moveq #$05,d0
bsr PlaySound ; alternative spell/effect sound
Some trigger code loads a value from Trigger_WaitFlag into D0 and then
branches to PlaySound. That value is dynamic, so it should not be treated as
a new fixed sound ID without tracing the individual trigger handlers.
Source references
The primary evidence is the SPS 439 disassembly:
asm/BLOODWYCH439.asm,PlaySoundat$8910andAudioSampleOffsetsat$8938;asm/BLOODWYCH439_relabel_data.asm, where the sound resources are emitted asSFX_AudioSample_1throughSFX_AudioSample_5;_archive/data/bw-sfx/ReadMe.txt, which records the descriptions of the five extracted samples.
The routine uses standard Amiga Paula registers (DMACON, INTENA, INTREQ,
AUD, and AUD0) and an IFF 8SVX-style sample layout. The sound selection and
call-site meanings above are Bloodwych-specific; the DMA and sample playback
mechanism is conventional Amiga audio handling.