diff options
| author | Alexander Kassouni <alex@kassouni.net> | 2026-09-05 17:51:13 -0700 |
|---|---|---|
| committer | Alexander Kassouni <alex@kassouni.net> | 2026-09-05 17:51:13 -0700 |
| commit | 46227e2003de28202cc4e82bca4f7f4745476c4e (patch) | |
| tree | fe450ac33ffa13747613c3cfdf36ea24b3036c46 /docs/editor.html | |
init
Diffstat (limited to 'docs/editor.html')
| -rw-r--r-- | docs/editor.html | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/docs/editor.html b/docs/editor.html new file mode 100644 index 0000000..8e46242 --- /dev/null +++ b/docs/editor.html @@ -0,0 +1,116 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>7. The editor path — Animalese</title> +<link rel="stylesheet" href="style.css"> +</head> +<body> + +<nav class="crumb"><a href="index.html">Animalese pipeline</a> / 7. The editor path</nav> + +<h1>7. The editor path</h1> +<p class="lede">There is a third calling convention into <code>Na_VoiceSe</code> that skips +the phonology engine entirely, and it explains what a third of the voice samples are +for.</p> + +<h2>Mode 1</h2> + +<p>The text editor overlay — used for letters, town and player names, patterns, and +anywhere else the player types — speaks each keystroke from +<code>src/game/m_editor_ovl.c:712</code>:</p> + +<pre>if (command == mED_COMMAND_OUTPUT_CODE) { + int voice = mMsg_sound_voice_get_for_editor(editor_ovl->now_code); + + if (voice == 0x85 || voice == 0x80 || voice == 0x81 || + voice == 0x82 || voice == 0x83 || voice == -1) + voice = 0x86; + + sAdo_VoiceSe(voice, 0xFF, 0xFF, 0, 32, 1); // ← mode 1 +} +else if (command == mED_COMMAND_EXCHANGE_CODE) { // cursor moved onto a character + if (exchange_code != -1 && mED_exchange_se_list[exchange_code]) + sAdo_VoiceSe(mMsg_sound_voice_get_for_editor(exchange_code), 0xFF, 0xFF, 0, 32, 1); + else + sAdo_SysTrgStart(0x36); +}</pre> + +<p>After both filters, only three things survive: letters (<code>0x5D</code>–<code>0x76</code>), +digits (<code>0x53</code>–<code>0x5C</code>), and the click (<code>0x86</code>).</p> + +<h2>What mode 1 does inside Na_VoiceSe</h2> + +<p><code>Na_VoiceSe</code>'s two <code>switch (f)</code> blocks handle only cases 0 and 2. +With <code>f == 1</code> both fall through, so:</p> + +<ul> + <li>no digraph merge, no vowel-length table, no silent e;</li> + <li><code>sou_num_org</code> etc. are never written, so <code>sou_last_num = + sou_num_org</code> further down just rewrites stale values — the message-path + history is not corrupted, but it is not updated either;</li> + <li><code>r28</code> is left uninitialised and never read;</li> + <li>nothing is queued for <code>Sou_SpecialRoutine10</code>;</li> + <li><strong><code>a</code> arrives at the playback stage as the raw voice code.</strong></li> +</ul> + +<p>The editor always runs at spec 5 or 6 (see <a href="gating.html">gating</a>), which +routes <code>0x86</code> to <code>NA_SE_BEBE</code> and passes everything else through. The +final guard is <code>if (a != 0 && a <= 0x77)</code>, and letters and digits both +satisfy it. So:</p> + +<pre>typing 'a' → Sou_VoiceStart(subtrack, 0x5D) → instrument 0x5C +typing 'z' → Sou_VoiceStart(subtrack, 0x76) → instrument 0x75 +typing '0' → Sou_VoiceStart(subtrack, 0x53) → instrument 0x52</pre> + +<h2>What this tells us about the sample set</h2> + +<p>Trace the reachable phoneme codes across the whole engine:</p> + +<table> +<tr><th>Code range</th><th>Instruments</th><th>Reached by</th></tr> +<tr><td><code>0x01</code>–<code>0x52</code></td><td>0–81</td><td>the phonology engine — short/long vowels, consonants, all 52 two-character digraphs plus <code>you</code></td></tr> +<tr><td><code>0x01</code>–<code>0x40</code></td><td></td><td>also the anti-repetition random substitution (<code>rand() >> 2</code>)</td></tr> +<tr><td><code>0x53</code>–<code>0x76</code></td><td>82–117</td><td><strong>only mode 1</strong> — one entry per digit and letter, in order</td></tr> +<tr><td><code>0x77</code></td><td>118</td><td>the <code>you</code> digraph, and nothing else</td></tr> +</table> + +<p>The <code>0x53</code>–<code>0x76</code> block is exactly 36 codes: ten digits then +twenty-six letters, in the same order as the voice-code alphabet, and it is +unreachable through any dialogue. The obvious reading is that these 36 samples are the +<strong>spoken names of the digits and letters</strong> — what you hear when typing a name +one character at a time.</p> + +<div class="note"> +<strong>Confidence.</strong> The code path is unambiguous; the interpretation of the samples +as letter names is inference. It is testable: extract instruments 82–117 from bank 156 +and listen. It also predicts that bank 157, which stops at 83 instruments, is a +phonology-only bank — and that is exactly what it is. +</div> + +<h2>Why bank 157 is short</h2> + +<p>Spec 3 (Wendell, Pete, Booker, Jack) uses sequence 244 / bank 157, which has 83 +instruments — codes <code>0x01</code>–<code>0x53</code>. That covers the entire phonology +output range (<code>≤ 0x52</code>) with one to spare, and omits the letter-name block +that spec 3 can never reach, since the editor is always spec 5 or 6.</p> + +<p>The one real casualty is <code>you</code> (<code>0x77</code>): the sequence's dynamic +table clamps out-of-range entries to the last routine, so a spec-3 voice saying "you" +plays instrument 82 instead. That is one wrong syllable on a common word, in four +NPCs' voices.</p> + +<div class="note"> +This corrects an earlier reading of <code>extraction.md</code> §2.4, which described bank 157 +as "collapsing every digraph sample above <code>0x53</code> onto one sound". Nothing above +<code>0x53</code> is a digraph — the block is not phonology at all. +</div> + +<div class="pager"> + <span><a href="soundfont.html">← 6. The soundfont lookup</a></span> + <span><a href="quirks.html">8. Quirks & corrections →</a></span> +</div> + +</body> +</html> |