aboutsummaryrefslogtreecommitdiff
path: root/docs/reference.html
diff options
context:
space:
mode:
authorAlexander Kassouni <alex@kassouni.net>2026-09-05 17:51:13 -0700
committerAlexander Kassouni <alex@kassouni.net>2026-09-05 17:51:13 -0700
commit46227e2003de28202cc4e82bca4f7f4745476c4e (patch)
treefe450ac33ffa13747613c3cfdf36ea24b3036c46 /docs/reference.html
init
Diffstat (limited to 'docs/reference.html')
-rw-r--r--docs/reference.html217
1 files changed, 217 insertions, 0 deletions
diff --git a/docs/reference.html b/docs/reference.html
new file mode 100644
index 0000000..5b86ebb
--- /dev/null
+++ b/docs/reference.html
@@ -0,0 +1,217 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>9. Reference tables — Animalese</title>
+<link rel="stylesheet" href="style.css">
+</head>
+<body>
+
+<nav class="crumb"><a href="index.html">Animalese pipeline</a> / 9. Reference tables</nav>
+
+<h1>9. Reference tables</h1>
+<p class="lede">Everything needed to reimplement the pipeline, plus an index into the
+decomp.</p>
+
+<h2>Voice codes</h2>
+
+<table>
+<tr><th>Code</th><th>Char</th><th>Class</th></tr>
+<tr><td><code>0x53</code>–<code>0x5C</code></td><td><code>0</code>–<code>9</code></td><td>2 (neither)</td></tr>
+<tr><td><code>0x5D</code> <code>0x61</code> <code>0x65</code> <code>0x6A</code> <code>0x6B</code> <code>0x71</code></td><td><code>a e i n o u</code></td><td>0 (vowel)</td></tr>
+<tr><td>other of <code>0x5D</code>–<code>0x76</code></td><td><code>b c d f g h j k l m p q r s t v w x y z</code></td><td>1 (consonant)</td></tr>
+<tr><td><code>0x80</code>–<code>0x86</code>, <code>0xFF</code></td><td>♪ &nbsp;␣ &nbsp;? &nbsp;! &nbsp;⏎ &nbsp;mute &nbsp;click &nbsp;empty</td><td>2 (neither)</td></tr>
+</table>
+
+<p>Letter <em>L</em> ↔ code: <code>0x5D + (L − 'a')</code>. Digit <em>D</em> ↔ code:
+<code>0x53 + D</code>.</p>
+
+<h2>Phoneme codes</h2>
+
+<p>Phoneme code <em>v</em> plays soundfont instrument <em>v</em>&nbsp;−&nbsp;1. Code 0 is
+silence. Codes marked † are produced by more than one rule and therefore share a
+sample.</p>
+
+<h3>Short vowels (<code>Sou_TanboinHenkan</code>)</h3>
+<table>
+<tr><th><code>a</code></th><th><code>i</code></th><th><code>u</code></th><th><code>e</code></th><th><code>o</code></th><th><code>n</code></th></tr>
+<tr><td>0x01</td><td>0x14</td><td>0x29</td><td>0x0A</td><td>0x1D</td><td>0x1B</td></tr>
+</table>
+
+<h3>Long vowels (<code>Sou_ChouboinHenkan</code>)</h3>
+<table>
+<tr><th><code>a</code></th><th><code>i</code></th><th><code>u</code></th><th><code>e</code></th><th><code>o</code></th><th><code>n</code></th></tr>
+<tr><td>0x02 †</td><td>0x15 †</td><td>0x2A †</td><td>0x0E †</td><td>0x1E</td><td>0x1B</td></tr>
+</table>
+<p>Used only when <code>class(a) == vowel &amp;&amp; class(b) == consonant &amp;&amp; c == 'e'</code>.
+The tables are otherwise byte-identical.</p>
+
+<h3>Consonants (both tables)</h3>
+<table>
+<tr><th>Letter</th><th>Code</th><th>Notes</th></tr>
+<tr><td><code>b</code></td><td>0x07</td><td></td></tr>
+<tr><td><code>c</code></td><td>0x23 / 0x18</td><td>soft (= <code>s</code>) if next letter is <code>i</code> or <code>e</code>, else hard (= <code>k</code>)</td></tr>
+<tr><td><code>d</code></td><td>0x09</td><td></td></tr>
+<tr><td><code>f</code></td><td>0x11</td><td></td></tr>
+<tr><td><code>g</code></td><td>0x12</td><td></td></tr>
+<tr><td><code>h</code></td><td>0x00</td><td><strong>silent</strong> — no instrument</td></tr>
+<tr><td><code>j</code></td><td>0x17</td><td>shares <code>ge</code></td></tr>
+<tr><td><code>k</code> <code>q</code></td><td>0x18</td><td></td></tr>
+<tr><td><code>l</code></td><td>0x19</td><td></td></tr>
+<tr><td><code>m</code></td><td>0x1A</td><td></td></tr>
+<tr><td><code>p</code></td><td>0x21</td><td></td></tr>
+<tr><td><code>r</code></td><td>0x22</td><td></td></tr>
+<tr><td><code>s</code></td><td>0x23</td><td></td></tr>
+<tr><td><code>t</code></td><td>0x26</td><td>shares digit <code>2</code></td></tr>
+<tr><td><code>v</code></td><td>0x2D</td><td></td></tr>
+<tr><td><code>w</code></td><td>0x2E</td><td></td></tr>
+<tr><td><code>x</code></td><td>0x31</td><td>shares <code>ks</code></td></tr>
+<tr><td><code>y</code></td><td>0x15</td><td>shares long <code>i</code> and <code>ea</code></td></tr>
+<tr><td><code>z</code></td><td>0x30</td><td></td></tr>
+</table>
+
+<h3>Digits (both tables)</h3>
+<table>
+<tr><th><code>0</code></th><th><code>1</code></th><th><code>2</code></th><th><code>3</code></th><th><code>4</code></th><th><code>5</code></th><th><code>6</code></th><th><code>7</code></th><th><code>8</code></th><th><code>9</code></th></tr>
+<tr><td>0x32</td><td>0x33</td><td>0x26</td><td>0x27</td><td>0x34</td><td>0x35</td><td>0x36</td><td>0x37</td><td>0x10</td><td>0x38</td></tr>
+</table>
+
+<h3>Digraphs (<code>Sou_ConnectCheck</code>) — 53 entries</h3>
+<table>
+<tr><th>Pair</th><th>Code</th><th>Pair</th><th>Code</th><th>Pair</th><th>Code</th><th>Pair</th><th>Code</th></tr>
+<tr><td><code>ai</code></td><td>0x0F</td><td><code>go</code></td><td>0x3E</td><td><code>no</code></td><td>0x49</td><td><code>si</code></td><td>0x36</td></tr>
+<tr><td><code>al</code></td><td>0x02</td><td><code>ha</code></td><td>0x3F</td><td><code>of</code></td><td>0x4A</td><td><code>so</code></td><td>0x4F</td></tr>
+<tr><td><code>an</code></td><td>0x39</td><td><code>he</code></td><td>0x40</td><td><code>oh</code></td><td>0x4B</td><td><code>su</code></td><td>0x25</td></tr>
+<tr><td><code>ar</code></td><td>0x16</td><td><code>hi</code></td><td>0x41</td><td><code>ok</code></td><td>0x4C</td><td><code>th</code></td><td>0x28</td></tr>
+<tr><td><code>as</code></td><td>0x3A</td><td><code>ho</code></td><td>0x42</td><td><code>on</code></td><td>0x4D</td><td><code>to</code></td><td>0x50</td></tr>
+<tr><td><code>be</code></td><td>0x3B</td><td><code>i␣</code></td><td>0x05</td><td><code>oo</code></td><td>0x2A</td><td><code>up</code></td><td>0x51</td></tr>
+<tr><td><code>by</code></td><td>0x3C</td><td><code>if</code></td><td>0x43</td><td><code>or</code></td><td>0x2C</td><td><code>we</code></td><td>0x52</td></tr>
+<tr><td><code>ch</code></td><td>0x08</td><td><code>in</code></td><td>0x44</td><td><code>ou</code></td><td>0x20</td><td><code>wo</code></td><td>0x33</td></tr>
+<tr><td><code>do</code></td><td>0x3D</td><td><code>ir</code></td><td>0x0C</td><td><code>ow</code></td><td>0x06</td><td><code>you</code></td><td>0x77</td></tr>
+<tr><td><code>ea</code></td><td>0x15</td><td><code>is</code></td><td>0x45</td><td><code>oy</code></td><td>0x1F</td><td><code>ze</code></td><td>0x32</td></tr>
+<tr><td><code>er</code></td><td>0x0D</td><td><code>it</code></td><td>0x46</td><td><code>re</code></td><td>0x0E</td><td></td><td></td></tr>
+<tr><td><code>fa</code></td><td>0x35</td><td><code>ks</code></td><td>0x31</td><td><code>se</code></td><td>0x37</td><td></td><td></td></tr>
+<tr><td><code>fo</code></td><td>0x34</td><td><code>me</code></td><td>0x47</td><td><code>sh</code></td><td>0x24</td><td></td><td></td></tr>
+<tr><td><code>ge</code></td><td>0x17</td><td><code>my</code></td><td>0x48</td><td><code>na</code></td><td>0x38</td><td></td><td></td></tr>
+<tr><td></td><td></td><td><code>ng</code></td><td>0x1C</td><td></td><td></td><td></td><td></td></tr>
+</table>
+<p>Of the 119 codes <code>0x01</code>–<code>0x77</code>, the phonology engine produces 76.
+The 43 it never produces are seven isolated gaps —
+<code>0x03 0x04 0x0B 0x13 0x2B 0x2F 0x4E</code> — plus the 36-code block
+<code>0x53</code>–<code>0x76</code>. The anti-repetition substitution can reach the first six
+of the gaps (it only emits <code>0x00</code>–<code>0x3F</code>); the block is reachable only
+via <a href="editor.html">the editor path</a>; <code>0x4E</code> appears to be reachable by
+nothing at all.</p>
+
+<h2>Specs</h2>
+
+<table>
+<tr><th>Spec</th><th>Seq</th><th>Bank</th><th>Vol</th><th>Pitch</th><th>Speaker</th></tr>
+<tr><td>2</td><td>243</td><td>156</td><td>0.65</td><td>1.00</td><td>lazy &amp; jock villagers; most special NPCs (default)</td></tr>
+<tr><td>3</td><td>244</td><td>157</td><td>0.65</td><td>1.00</td><td>cranky villagers; Wendell, Pete, Booker, Jack</td></tr>
+<tr><td>4</td><td>245</td><td>158</td><td>0.65</td><td>1.00</td><td>normal, peppy, snooty villagers; Pelly, Phyllis, Mabel, Sable, Blanca; event narration</td></tr>
+<tr><td>5</td><td>243</td><td>156</td><td>0.90</td><td>1.00</td><td>player, male — text editor only</td></tr>
+<tr><td>6</td><td>245</td><td>158</td><td>0.90</td><td>1.00</td><td>player, female — text editor only</td></tr>
+<tr><td>7</td><td>243</td><td>156</td><td>0.90</td><td>1.30</td><td>Timmy &amp; Tommy (via control code 93)</td></tr>
+<tr><td>8</td><td>245</td><td>158</td><td>0.90</td><td>0.75</td><td>Joan</td></tr>
+<tr><td>9</td><td>243</td><td>156</td><td>0.70</td><td>0.65</td><td>Farley</td></tr>
+</table>
+
+<h2>Text control codes that affect voice</h2>
+
+<table>
+<tr><th>Value</th><th>Name</th><th>Effect</th></tr>
+<tr><td>3</td><td><code>CURSOR_SET_TIME</code></td><td>pauses the cursor; lets a half-built window fire early</td></tr>
+<tr><td>75–79, 97</td><td><code>SET_MESSAGE_CONTENTS_*</code></td><td>emotion state (normal / angry / sad / fun / sleepy / gloomy)</td></tr>
+<tr><td>81</td><td><code>SOUND_CUT</code></td><td>plays system SE <code>0x54</code>, sends the end code, suppresses voice</td></tr>
+<tr><td>84</td><td><code>SET_CHAR_SCALE</code></td><td>changes glyph scale → the <a href="quirks.html">volume step</a></td></tr>
+<tr><td>90</td><td><code>SET_LINE_SCALE</code></td><td>same, per line</td></tr>
+<tr><td>92</td><td><code>VOICE_TRUE</code></td><td>restore spec (Timmy/Tommy only)</td></tr>
+<tr><td>93</td><td><code>VOICE_FALSE</code></td><td>spec 7 (Timmy/Tommy only)</td></tr>
+</table>
+
+<h2>Source index</h2>
+
+<p>Paths relative to the ac-decomp root. Line numbers are for commit
+<code>09ca8e8b</code>.</p>
+
+<h3>Message layer</h3>
+<table>
+<tr><td><code>src/game/m_msg_sound.c_inc:1</code></td><td><code>mMsg_sound_voice_get</code> — the 256-entry table</td></tr>
+<tr><td><code>&#8203;:26</code></td><td><code>mMsg_sound_voice_get_for_editor</code></td></tr>
+<tr><td><code>&#8203;:44</code></td><td><code>mMsg_sound_voice_get2</code> — newline injection</td></tr>
+<tr><td><code>&#8203;:52</code></td><td><code>mMsg_check_sound_special</code> — forced-voice message ranges</td></tr>
+<tr><td><code>&#8203;:66</code></td><td><code>mMsg_check_sound_animal</code></td></tr>
+<tr><td><code>&#8203;:85</code></td><td><code>mMsg_sound_voice_entry</code> — the (a, b, c) window</td></tr>
+<tr><td><code>&#8203;:117</code></td><td><code>mMsg_sound_voice_endcode_set</code></td></tr>
+<tr><td><code>&#8203;:126</code></td><td><code>mMsg_sound_CodeVoice</code></td></tr>
+<tr><td><code>&#8203;:259</code></td><td><code>mMsg_sound_voice_mode_get</code></td></tr>
+<tr><td><code>&#8203;:288</code></td><td><code>mMsg_sound_spec_change_voice_force</code></td></tr>
+<tr><td><code>&#8203;:317</code></td><td><code>mMsg_sound_spec_change_true/false</code> — Timmy/Tommy</td></tr>
+<tr><td><code>src/game/m_msg_cursol.c_inc:1100</code></td><td><code>mMsg_Main_Cursol_ControlCursol</code> — the cursor loop</td></tr>
+<tr><td><code>&#8203;:1184</code></td><td>the <code>NOT_PAUSE_FRAME</code> toggle</td></tr>
+<tr><td><code>src/game/m_msg_draw_font.c_inc:35</code></td><td>voice-fire decision</td></tr>
+<tr><td><code>src/game/m_font_main.c_inc:951</code></td><td><code>mFontSentence_animal_voice_se</code> — scale, and the call</td></tr>
+<tr><td><code>&#8203;:1078</code></td><td>the draw-loop trigger</td></tr>
+<tr><td><code>src/game/m_npc.c:32</code></td><td><code>l_sp_actor_name</code> — special-NPC spec table</td></tr>
+<tr><td><code>&#8203;:4116</code></td><td><code>mNpc_GetNpcSoundSpec</code></td></tr>
+<tr><td><code>src/game/m_submenu.c:364</code></td><td>player voice, specs 5 / 6</td></tr>
+<tr><td><code>src/game/m_editor_ovl.c:712</code></td><td>the mode-1 editor path</td></tr>
+</table>
+
+<h3>Bridge</h3>
+<table>
+<tr><td><code>src/audio.c:96</code></td><td><code>sAdo_VoiceSe</code></td></tr>
+<tr><td><code>&#8203;:152</code></td><td><code>sAdo_SetVoiceMode</code></td></tr>
+<tr><td><code>&#8203;:216</code></td><td><code>sAdo_SpecChange</code></td></tr>
+<tr><td><code>include/audio.h:45</code></td><td><code>VOICE_STATUS_*</code></td></tr>
+<tr><td><code>include/audio_defs.h:10</code></td><td><code>VOICE_MODE_*</code></td></tr>
+</table>
+
+<h3>Audio engine — <code>src/static/jaudio_NES/game/game64.c_inc</code></h3>
+<table>
+<tr><td><code>:22</code></td><td><code>VOICE_GROUP</code> = <code>NA_GROUP4</code></td></tr>
+<tr><td><code>:97</code></td><td><code>SOU_VOICE_SE</code> struct</td></tr>
+<tr><td><code>:236</code></td><td><code>SHIIN2BOIN</code> (dead)</td></tr>
+<tr><td><code>:311</code></td><td><code>sou_voice_se_init</code> — pan <code>0x3F</code>, reverb 0</td></tr>
+<tr><td><code>:820</code></td><td><code>Sou_VoiceStart</code></td></tr>
+<tr><td><code>:1174</code></td><td><code>Sou_VoiceMake</code></td></tr>
+<tr><td><code>:1708</code></td><td><code>Sou_SpecialRoutine10</code> — deferred syllable</td></tr>
+<tr><td><code>:1852</code></td><td><code>Na_GameFrame</code></td></tr>
+<tr><td><code>:2146</code></td><td><code>Sou_TanboinHenkan</code></td></tr>
+<tr><td><code>:2231</code></td><td><code>Sou_ChouboinHenkan</code></td></tr>
+<tr><td><code>:2316</code></td><td><code>Sou_ConnectCheck</code></td></tr>
+<tr><td><code>:2564</code></td><td><code>Sou_BoinShiinCheck</code></td></tr>
+<tr><td><code>:2598</code></td><td><code>Na_VoiceSe</code></td></tr>
+<tr><td><code>:3319</code></td><td><code>Na_SetVoiceMode</code></td></tr>
+<tr><td><code>:3459</code></td><td><code>Na_SpecChange</code></td></tr>
+<tr><td><code>melody.c:727</code></td><td><code>Na_MelodyVoice</code> — the ♪ handler</td></tr>
+<tr><td><code>audioheaders.c:4073</code></td><td>bank 156–158 entries</td></tr>
+<tr><td><code>audioheaders.c:4176</code></td><td><code>AudiodataHeaderStart</code> — the three archives</td></tr>
+<tr><td><code>audioheaders.c:4717</code></td><td>seq 243–245 → bank 156–158</td></tr>
+</table>
+
+<h3>Soundfont / bank loading</h3>
+<table>
+<tr><td><code>include/jaudio_NES/audiostruct.h:74</code></td><td><code>ArcEntry</code> / <code>ArcHeader</code></td></tr>
+<tr><td><code>&#8203;:95</code></td><td><code>adpcmloop</code>, <code>adpcmbook</code>, <code>smzwavetable</code>, <code>wtstr</code></td></tr>
+<tr><td><code>&#8203;:348</code></td><td><code>voicetable</code> — the instrument</td></tr>
+<tr><td><code>&#8203;:373</code></td><td><code>voiceinfo</code> — per-bank runtime info</td></tr>
+<tr><td><code>src/static/jaudio_NES/internal/system.c:772</code></td><td><code>__Link_BankNum</code> — alias entries</td></tr>
+<tr><td><code>&#8203;:813</code></td><td><code>Nas_BankOfsToAddr_Inner</code> — offset → pointer</td></tr>
+<tr><td><code>&#8203;:1171</code></td><td><code>__SetVlute</code> — <code>param0/1/2</code> decode</td></tr>
+<tr><td><code>&#8203;:1692</code></td><td><code>__WaveTouch</code> — sample vs bank relocation</td></tr>
+<tr><td><code>internal/channel.c:354</code></td><td><code>NoteToVoice</code></td></tr>
+<tr><td><code>&#8203;:368</code></td><td><code>ProgToVp</code> — instrument index → <code>voicetable</code></td></tr>
+<tr><td><code>internal/track.c:1159</code></td><td><code>Nas_ProgramChanger</code></td></tr>
+<tr><td><code>&#8203;:1399</code></td><td><code>SUBTRACK_CMD_SET_INSTRUMENT_BANK</code> — reverse bank-list index</td></tr>
+</table>
+
+<div class="pager">
+ <span><a href="quirks.html">← 8. Quirks &amp; corrections</a></span>
+ <span><a href="index.html">Index</a></span>
+</div>
+
+</body>
+</html>