David Whittaker Sound Engine: Difference between revisions
KungFuFurby (talk | contribs) (Done recording most offsets, and found a second duplicate build case) |
KungFuFurby (talk | contribs) (Starting on voice command documentation. All VCMD ARAM locations are now recorded.) |
||
Line 1: | Line 1: | ||
__TOC__ | |||
David Whittaker Sound Engine is a sound driver for the SPC700 programmed by David Whittaker. | David Whittaker Sound Engine is a sound driver for the SPC700 programmed by David Whittaker. | ||
Many games have multiple different builds stored in the game at once, sometimes with code differences. Almost every single game has at least one unique build not shared by any of the other games: the exceptions are... | Many games have multiple different builds stored in the game at once, sometimes with code differences. Almost every single game has at least one unique build not shared by any of the other games: the exceptions are... | ||
*The opening logos for Lemmings 2: The Tribes and Apocalypse II | * The opening logos for Lemmings 2: The Tribes and Apocalypse II | ||
*Kick Off 3 Beta's Title Screen and Lawnmower Man/Virtual Wars' US Beta | * Kick Off 3 Beta's Title Screen and Lawnmower Man/Virtual Wars' US Beta | ||
These are the games where the sound engine was used: | These are the games where the sound engine was used: | ||
{| class="wikitable sortable" | {| class="wikitable sortable" | ||
|- | |- | ||
! Game Name !! Version !! ROM Offset | ! Game Name !! Music Version !! VCMD Code Location !! ROM Offset | ||
|- | |- | ||
| Dream TV || 0.0 (Beta 2)<br>2.0 (all other versions) || 0x0196A2 (Beta 2, uncompressed)<br>0x039B16 (all other versions, ''RNC compressed'') | | Dream TV || 0.0 (Beta 2)<br>2.0 (all other versions) || <tt>0x098A</tt> (Beta 2)<br><tt>0x0614</tt> (all other versions) || <tt>0x0196A2</tt> (Beta 2, uncompressed)<br><tt>0x039B16</tt> (all other versions, ''RNC compressed'') | ||
|- | |- | ||
| Krusty's Super Fun House || 1.0 || 0x0E8000 (all versions) | | Krusty's Super Fun House || 1.0 || <tt>0x04F1</tt> || <tt>0x0E8000</tt> (all versions) | ||
|- | |- | ||
| Kick Off/Super Kick Off || 1.0 || 0x098000 (all versions) | | Kick Off/Super Kick Off || 1.0 || <tt>0x04E6</tt> || <tt>0x098000</tt> (all versions) | ||
|- | |- | ||
| Batman: Revenge of the Joker || 2.0 || 0x068000 | | Batman: Revenge of the Joker || 2.0 || <tt>0x0610</tt> || <tt>0x068000</tt> | ||
|- | |- | ||
| Super SWIV/Firepower 2000 || 2.1 || 0x158000 | | Super SWIV/Firepower 2000 || 2.1 || <tt>0x06AD</tt> || <tt>0x158000</tt> | ||
|- | |- | ||
| Gods || 2.2 || 0x980000/0x98AFAC/0x99D448/0x9A8000 (all versions, three unique build variants, ''RNC compressed'') | | Gods || 2.2 || <tt>0x0500</tt>/<tt>0x0600</tt>/<tt>0x0612</tt> || <tt>0x980000</tt>/<tt>0x98AFAC</tt>/<tt>0x99D448</tt>/<tt>0x9A8000</tt> (all versions, three unique build variants, ''RNC compressed'') | ||
|- | |- | ||
| World Class Rugby || 2.2 || 0x0B8000 (all versions) | | World Class Rugby || 2.2 || <tt>0x0608</tt> || <tt>0x0B8000</tt> (all versions) | ||
|- | |- | ||
| Battle Cars || 3.0 || 0x0A8000 | | Battle Cars || 3.0 || <tt>0x0717</tt> || <tt>0x0A8000</tt> | ||
|- | |- | ||
| Chavez/Riddick Bowe Boxing || 3.0 (all other versions)<br>3.1 (Japanese version) || 0x0D8000 (all versions)/0x0E8000 (all versions except Chavez)<br>(three unique build variants, one per version between Chavez, US & Japanese versions) | | Chavez/Riddick Bowe Boxing || 3.0 (all other versions)<br>3.1 (Japanese version) || <tt>0x0621</tt> (Japanese version)<br><tt>0x067C</tt> (US version)<br><tt>0x067D</tt> (Chavez) || <tt>0x0D8000</tt> (all versions)/<tt>0x0E8000</tt> (all versions except Chavez)<br>(three unique build variants, one per version between Chavez, US & Japanese versions) | ||
|- | |- | ||
| Lawnmower Man/Virtual Wars || 3.1 || 0x9C8000 (all versions except US beta)/0x9E8000 (all versions) | | Lawnmower Man/Virtual Wars || 3.1 || <tt>0x06BD</tt> (US beta)<br><tt>0x06A4</tt> (all other versions) || <tt>0x9C8000</tt> (all versions except US beta)/0x9E8000 (all versions) | ||
|- | |- | ||
| Apocalypse II || 3.1 || 0x118000/0x168000 | | Apocalypse II || 3.1 || <tt>0x05AF</tt>/<tt>0x0624</tt> || <tt>0x118000</tt>/<tt>0x168000</tt> | ||
|- | |- | ||
| Elite Soccer/World Cup Striker || 3.1 || 0x1B8000 (all versions)/0x08D500 (US & Japanese version)/0x08D550 (European beta version)/0x08D640 (European version)<br>(Four unique build variants: two Title Screen (US/JP compared to EU) and two In-Game (US/EU compare to JP)) | | Elite Soccer/World Cup Striker || 3.1 || <tt>0x0601</tt> (US and European version In-Game)<br><tt>0x060B</tt> (US and Japanese version Title Screen)<br><tt>0x0704</tt> (Japanese version In-Game)<br><tt>0x070B</tt> (European version Title Screen) || <tt>0x1B8000</tt> (all versions)/<tt>0x08D500</tt> (US & Japanese version)/<tt>0x08D550</tt> (European beta version)/<tt>0x08D640</tt> (European version)<br>(Four unique build variants: two Title Screen (US/JP compared to EU) and two In-Game (US/EU compare to JP)) | ||
|- | |- | ||
| Kick Off 3 (Beta version only) || 3.1 || 0x1A8000/0x1D8000 | | Kick Off 3 (Beta version only) || 3.1 || <tt>0x0658</tt>/<tt>0x06BD</tt> || 0x1A8000/0x1D8000 | ||
|- | |- | ||
| Lemmings 2: The Tribes || 3.1 || ''(omitted for now: there are 16 copies of the code in the ROM, with five different build variants being present: four of them are used in one instance each, that being the opening logo, the Title Screen, the Beach Tribe and the Cavelem Tribe, and the others use a single common copy of the code)'' | | Lemmings 2: The Tribes || 3.1 || <tt>0x05AF</tt>/<tt>0x060F</tt>/<tt>0x0614</tt>/<tt>0x0621</tt>/<tt>0x0697</tt> || ''(omitted for now: there are 16 copies of the code in the ROM, with five different build variants being present: four of them are used in one instance each, that being the opening logo, the Title Screen, the Beach Tribe and the Cavelem Tribe, and the others use a single common copy of the code with modifications of constants and non-code pointers)'' | ||
|- | |- | ||
| Porky Pig's Haunted Holiday (Beta version only) || 3.1 || ''(omitted for now: there are 36 copies of the code in the ROM, none of which are unique except for the sound data)'' | | Porky Pig's Haunted Holiday (Beta version only) || 3.1 || <tt>0x06CA</tt> || ''(omitted for now: there are 36 copies of the code in the ROM, none of which are unique except for the sound data and modifications of constants and non-code pointers)'' | ||
|- | |- | ||
| Shaq Fu || 4.0a || 0xD96408 (all versions) | | Shaq Fu || 4.0a || <tt>0x0539</tt> || 0xD96408 (all versions) | ||
|- | |- | ||
| Michael Jordan: Chaos in the Windy City || 4.0b || 0xD2B18F (all versions) | | Michael Jordan: Chaos in the Windy City || 4.0b || <tt>0x0539</tt> || 0xD2B18F (all versions) | ||
|} | |} | ||
==Song Entry== | |||
For each song entry in an array of song definitions, one byte is defined as a starting tempo, followed by a series of pointers defined little endian style for each channel. For Dream TV Beta and Kick Off, only five pointers are defined. For Krusty's Super Fun House, only six pointers are defined. For all other games, eight pointers are defined. | |||
<pre>xx yy yy zz zz aa aa bb bb cc cc dd dd ee ee ff ff</pre> | |||
* xx is the starting tempo. | |||
* yy yy is a little-endian pointer to a pattern order list for channel 1. | |||
* zz zz is a little-endian pointer to a pattern order list for channel 2. | |||
* aa aa is a little-endian pointer to a pattern order list for channel 3. | |||
* bb bb is a little-endian pointer to a pattern order list for channel 4. | |||
* cc cc is a little-endian pointer to a pattern order list for channel 5. | |||
* dd dd is a little-endian pointer to a pattern order list for channel 6. ''(Krusty's Super Fun House only pre-V2.0)'' | |||
* ee ee is a little-endian pointer to a pattern order list for channel 7. ''(not supported pre-V2.0)'' | |||
* ff ff is a little-endian pointer to a pattern order list for channel 8. ''(not supported pre-V2.0)'' | |||
Two builds don't support song entries at all: | |||
* The opening logos for Lemmings 2: The Tribes and Apocalypse II | |||
* Kick Off 3 Beta (In-Game) | |||
==Pattern Order List== | |||
Each track has a list of pointers on a per-track basis. If the pointer is zero, then you jump back to the beginning of the pattern order list for that track. | |||
==Instrument Format== | |||
The instrument format at V0.0 is N-SPC/Kankichi-kun compatible minus noise support for SRCN values above 127. Post V1.0, one of the bytes loses its usage. | |||
The instrument format is defined as direct writes to DSP registers for the first four bytes, followed by two pitch-related bytes. They are defined in this order, from top to bottom... | |||
* SRCN | |||
* ADSR1 | |||
* ADSR2 | |||
* GAIN ''(unused byte post-V2.0)'' | |||
* Pitch Base Multiplier | |||
* Pitch Base Fractional Multiplier (in 256ths) | |||
==Voice Command Format== | |||
{| class="wikitable sortable" | |||
|- | |||
! VCMD ID !! Description !! Arguments !! Minimum Version | |||
|- | |||
| <tt>$00-$5F</tt> || Note || || 0.0 | |||
|- | |||
| <tt>$60-$7F</tt> || Note Length || || 0.0 | |||
|- | |||
| <tt>$80-$EC</tt> || Invalid || || 0.0 | |||
|- | |||
| <tt>$ED</tt> || Instant Pitch Change to Note || <tt>xx</tt> || 4.0a only | |||
|- | |||
| <tt>$ED</tt> || Set Master Volume || <tt>xx</tt> || 4.0b only | |||
|- | |||
| <tt>$EE</tt> || Volume Scaler by Fraction ||<tt>xx yy</tt> || 3.0 | |||
|- | |||
| <tt>$EF</tt> || Set ADSR ||<tt>xx yy</tt> || 2.0 | |||
|- | |||
| <tt>$F0</tt> || Fine Tune ||<tt>xx</tt> || 1.0 | |||
|- | |||
| <tt>$F1</tt> || Pitch Bend ||<tt>xx</tt> || 1.0 | |||
|- | |||
| <tt>$F2</tt> || Pitch Envelope ID ||<tt>xx</tt> || 0.0 | |||
|- | |||
| <tt>$F3</tt> || L/R Voice Volume ||<tt>xx yy</tt> || 0.0 | |||
|- | |||
| <tt>$F4</tt> || Tempo ||<tt>xx</tt> || 0.0 | |||
|- | |||
| <tt>$F5</tt> || Jump to Pattern in Order List ||<tt>xx xx</tt> || 0.0 | |||
|- | |||
| <tt>$F6</tt> || Invalid || || 0.0 | |||
|- | |||
| <tt>$F7</tt> || Invalid || || 0.0 | |||
|- | |||
| <tt>$F8</tt> || Key Off || || 0.0 | |||
|- | |||
| <tt>$F9</tt> || One Note Delay || || 0.0 | |||
|- | |||
| <tt>$FA</tt> || Instrument ||<tt>xx</tt> || 0.0 | |||
|- | |||
| <tt>$FB</tt> || Absolute Global Transposition ||<tt>xx</tt> || 0.0 | |||
|- | |||
| <tt>$FC</tt> || Absolute Transposition ||<tt>xx</tt> || 0.0 | |||
|- | |||
| <tt>$FD</tt> || Invalid || || 0.0 | |||
|- | |||
| <tt>$FE</tt> || Song End || || 0.0 | |||
|- | |||
| <tt>$FF</tt> || Pattern End || || 0.0 | |||
|} | |||
===Invalid (VCMDs <tt>$80-$EC</tt>, <tt>$F6-$F7</tt>, <tt>$FD</tt>, <tt>$ED</tt> (pre-V4.0), <tt>$EE</tt> (pre-V3.0), <tt>$EF</tt> (pre-V2.0), <tt>$F0-$F1</tt> (pre-V1.0))=== | |||
The sound driver deliberately freezes itself via an infinite branch always loop rather than crashing or skipping the byte. This also takes up VCMD slots that are not filled in earlier versions. | |||
'''Work in Progress... TODO...''' | '''Work in Progress... TODO...''' | ||
* Voice Command Format | |||
* Voice Command | |||
[[Category:SPC Sound Engines]] | [[Category:SPC Sound Engines]] |
Revision as of 18:19, 16 September 2020
David Whittaker Sound Engine is a sound driver for the SPC700 programmed by David Whittaker.
Many games have multiple different builds stored in the game at once, sometimes with code differences. Almost every single game has at least one unique build not shared by any of the other games: the exceptions are...
- The opening logos for Lemmings 2: The Tribes and Apocalypse II
- Kick Off 3 Beta's Title Screen and Lawnmower Man/Virtual Wars' US Beta
These are the games where the sound engine was used:
Game Name | Music Version | VCMD Code Location | ROM Offset |
---|---|---|---|
Dream TV | 0.0 (Beta 2) 2.0 (all other versions) |
0x098A (Beta 2) 0x0614 (all other versions) |
0x0196A2 (Beta 2, uncompressed) 0x039B16 (all other versions, RNC compressed) |
Krusty's Super Fun House | 1.0 | 0x04F1 | 0x0E8000 (all versions) |
Kick Off/Super Kick Off | 1.0 | 0x04E6 | 0x098000 (all versions) |
Batman: Revenge of the Joker | 2.0 | 0x0610 | 0x068000 |
Super SWIV/Firepower 2000 | 2.1 | 0x06AD | 0x158000 |
Gods | 2.2 | 0x0500/0x0600/0x0612 | 0x980000/0x98AFAC/0x99D448/0x9A8000 (all versions, three unique build variants, RNC compressed) |
World Class Rugby | 2.2 | 0x0608 | 0x0B8000 (all versions) |
Battle Cars | 3.0 | 0x0717 | 0x0A8000 |
Chavez/Riddick Bowe Boxing | 3.0 (all other versions) 3.1 (Japanese version) |
0x0621 (Japanese version) 0x067C (US version) 0x067D (Chavez) |
0x0D8000 (all versions)/0x0E8000 (all versions except Chavez) (three unique build variants, one per version between Chavez, US & Japanese versions) |
Lawnmower Man/Virtual Wars | 3.1 | 0x06BD (US beta) 0x06A4 (all other versions) |
0x9C8000 (all versions except US beta)/0x9E8000 (all versions) |
Apocalypse II | 3.1 | 0x05AF/0x0624 | 0x118000/0x168000 |
Elite Soccer/World Cup Striker | 3.1 | 0x0601 (US and European version In-Game) 0x060B (US and Japanese version Title Screen) 0x0704 (Japanese version In-Game) 0x070B (European version Title Screen) |
0x1B8000 (all versions)/0x08D500 (US & Japanese version)/0x08D550 (European beta version)/0x08D640 (European version) (Four unique build variants: two Title Screen (US/JP compared to EU) and two In-Game (US/EU compare to JP)) |
Kick Off 3 (Beta version only) | 3.1 | 0x0658/0x06BD | 0x1A8000/0x1D8000 |
Lemmings 2: The Tribes | 3.1 | 0x05AF/0x060F/0x0614/0x0621/0x0697 | (omitted for now: there are 16 copies of the code in the ROM, with five different build variants being present: four of them are used in one instance each, that being the opening logo, the Title Screen, the Beach Tribe and the Cavelem Tribe, and the others use a single common copy of the code with modifications of constants and non-code pointers) |
Porky Pig's Haunted Holiday (Beta version only) | 3.1 | 0x06CA | (omitted for now: there are 36 copies of the code in the ROM, none of which are unique except for the sound data and modifications of constants and non-code pointers) |
Shaq Fu | 4.0a | 0x0539 | 0xD96408 (all versions) |
Michael Jordan: Chaos in the Windy City | 4.0b | 0x0539 | 0xD2B18F (all versions) |
Song Entry
For each song entry in an array of song definitions, one byte is defined as a starting tempo, followed by a series of pointers defined little endian style for each channel. For Dream TV Beta and Kick Off, only five pointers are defined. For Krusty's Super Fun House, only six pointers are defined. For all other games, eight pointers are defined.
xx yy yy zz zz aa aa bb bb cc cc dd dd ee ee ff ff
- xx is the starting tempo.
- yy yy is a little-endian pointer to a pattern order list for channel 1.
- zz zz is a little-endian pointer to a pattern order list for channel 2.
- aa aa is a little-endian pointer to a pattern order list for channel 3.
- bb bb is a little-endian pointer to a pattern order list for channel 4.
- cc cc is a little-endian pointer to a pattern order list for channel 5.
- dd dd is a little-endian pointer to a pattern order list for channel 6. (Krusty's Super Fun House only pre-V2.0)
- ee ee is a little-endian pointer to a pattern order list for channel 7. (not supported pre-V2.0)
- ff ff is a little-endian pointer to a pattern order list for channel 8. (not supported pre-V2.0)
Two builds don't support song entries at all:
- The opening logos for Lemmings 2: The Tribes and Apocalypse II
- Kick Off 3 Beta (In-Game)
Pattern Order List
Each track has a list of pointers on a per-track basis. If the pointer is zero, then you jump back to the beginning of the pattern order list for that track.
Instrument Format
The instrument format at V0.0 is N-SPC/Kankichi-kun compatible minus noise support for SRCN values above 127. Post V1.0, one of the bytes loses its usage.
The instrument format is defined as direct writes to DSP registers for the first four bytes, followed by two pitch-related bytes. They are defined in this order, from top to bottom...
- SRCN
- ADSR1
- ADSR2
- GAIN (unused byte post-V2.0)
- Pitch Base Multiplier
- Pitch Base Fractional Multiplier (in 256ths)
Voice Command Format
VCMD ID | Description | Arguments | Minimum Version |
---|---|---|---|
$00-$5F | Note | 0.0 | |
$60-$7F | Note Length | 0.0 | |
$80-$EC | Invalid | 0.0 | |
$ED | Instant Pitch Change to Note | xx | 4.0a only |
$ED | Set Master Volume | xx | 4.0b only |
$EE | Volume Scaler by Fraction | xx yy | 3.0 |
$EF | Set ADSR | xx yy | 2.0 |
$F0 | Fine Tune | xx | 1.0 |
$F1 | Pitch Bend | xx | 1.0 |
$F2 | Pitch Envelope ID | xx | 0.0 |
$F3 | L/R Voice Volume | xx yy | 0.0 |
$F4 | Tempo | xx | 0.0 |
$F5 | Jump to Pattern in Order List | xx xx | 0.0 |
$F6 | Invalid | 0.0 | |
$F7 | Invalid | 0.0 | |
$F8 | Key Off | 0.0 | |
$F9 | One Note Delay | 0.0 | |
$FA | Instrument | xx | 0.0 |
$FB | Absolute Global Transposition | xx | 0.0 |
$FC | Absolute Transposition | xx | 0.0 |
$FD | Invalid | 0.0 | |
$FE | Song End | 0.0 | |
$FF | Pattern End | 0.0 |
Invalid (VCMDs $80-$EC, $F6-$F7, $FD, $ED (pre-V4.0), $EE (pre-V3.0), $EF (pre-V2.0), $F0-$F1 (pre-V1.0))
The sound driver deliberately freezes itself via an infinite branch always loop rather than crashing or skipping the byte. This also takes up VCMD slots that are not filled in earlier versions.
Work in Progress... TODO...
- Voice Command Format