aboutsummaryrefslogtreecommitdiff
path: root/docs/phonology.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/phonology.html')
-rw-r--r--docs/phonology.html42
1 files changed, 36 insertions, 6 deletions
diff --git a/docs/phonology.html b/docs/phonology.html
index ebbc872..075f3a2 100644
--- a/docs/phonology.html
+++ b/docs/phonology.html
@@ -47,8 +47,13 @@ rewritten.</p>
<h3>0. Lone mute</h3>
<pre>if (a == 0x85 &amp;&amp; b == 0xFF &amp;&amp; c == 0xFF) return;</pre>
-<p>Returns before touching any state, so a lone punctuation mark does not disturb the
-previous-character history.</p>
+<p><code>sou_num_org</code>, <code>sou_num2_org</code> and <code>sou_num3_org</code> are assigned
+<em>before</em> this test, so they <strong>are</strong> overwritten; what survives is
+<code>sou_last_num</code> / <code>sou_last_num2</code>, which are written further down. A lone
+punctuation mark therefore leaves the digraph history intact, but still clobbers the
+context bytes a pending <a href="#mode2">mode&nbsp;2</a> call will read —
+<code>sou_num3_org</code> for its short-vowel lookup, <code>sou_num_org</code> for its dedup
+comparison.</p>
<h3>1. Silent e (<code>:2612</code>)</h3>
<pre>if (a == 'e' &amp;&amp; b &gt; 0x77 &amp;&amp; class(last_num) == vowel &amp;&amp; class(last_num2) == consonant) {
@@ -71,6 +76,17 @@ are consumed by one sample.</p>
<h4>The digraph table — <code>Sou_ConnectCheck</code> (<code>:2316</code>)</h4>
<p>53 entries. All are two characters except <code>you</code>, the only rule that reads <code>c</code>; one pairs a letter with a space rather than another letter (<code>i␣</code>).</p>
+<div class="note">
+<strong><code>i␣</code> is very nearly unreachable.</strong> Its <code>b</code> is <code>0x81</code>,
+which is also a punctuation-flush trigger — so rule&nbsp;3 below sets <code>r28 = 3</code> and
+unconditionally reassigns <code>a</code>, discarding the <code>0x05</code>. It survives only when
+the previous call's <code>b</code> was <em>also</em> punctuation, which forces <code>r28 = 1</code>
+instead; <code>0x05</code> then falls through <code>Sou_TanboinHenkan</code>'s
+<code>default: return a</code> and reaches playback unchanged. Every other digraph has a letter
+in <code>b</code> and so never meets rule&nbsp;3 — for those, "<code>r28 = 2</code> falls straight
+through to playback" holds as written.
+</div>
+
<div class="grid2">
<code>ai</code>→0x0F<br><code>al</code>→0x02<br><code>an</code>→0x39<br><code>ar</code>→0x16<br><code>as</code>→0x3A<br>
<code>be</code>→0x3B<br><code>by</code>→0x3C<br>
@@ -110,9 +126,23 @@ each one a recorded syllable.</p>
<pre>a = Sou_ConnectCheck(sou_last_num2, sou_num_org, sou_num2_org);
if (a &lt; 0x53 || a &gt; 0x76) break; // it merged, or wasn't a letter — leave it
a = Sou_TanboinHenkan(a, b);</pre>
-<p>This gives the final letter of a word a chance to pair with the letter before it
-instead of being dropped against the following space. Note the guard also drops the
-whole branch if <code>a &gt; 0x77</code> before it starts.</p>
+<p>The <em>intent</em> is to give the final letter of a word a chance to pair with the letter
+before it instead of being dropped against the following space. What it does is narrower.
+<code>a</code> is reloaded from <code>sou_last_num2</code> — the <em>previous</em> call's
+<code>b</code> — and if <code>Sou_ConnectCheck</code> finds no merge it returns that byte
+unchanged, so <code>Sou_TanboinHenkan</code> speaks the previous letter a second time and the
+word-final letter is never voiced at all.</p>
+
+<p>Worked example, <code>cat␣</code>. Window <code>(c, a, t)</code> doesn't merge, so
+<code>r28 = 1</code> plays hard <code>c</code> and queues <code>a</code>; the deferred call plays
+<code>a</code>. Window <code>(t, ␣, …)</code> then hits rule&nbsp;3, reloads
+<code>a = sou_last_num2 = 'a'</code>, fails to merge <code>at</code>, and plays <code>a</code>
+again. The <code>t</code> makes no sound. The branch only pays off when the reloaded pair
+<em>does</em> merge — then the merged code plays and the <code>0x53</code>–<code>0x76</code>
+guard breaks out before <code>Sou_TanboinHenkan</code> can touch it.</p>
+
+<p>Note the guard also drops the whole branch if <code>a &gt; 0x77</code> before it starts, and
+that nothing is queued on this path.</p>
<h3>4. Vowel length (<code>:2658</code>, for <code>r28 == 1</code> or <code>4</code>)</h3>
<pre>if (class(a) == vowel &amp;&amp; class(b) == consonant &amp;&amp; c == 'e')
@@ -168,7 +198,7 @@ with the first syllable of the spoken number: <code>0</code>=<code>ze</code>(ro)
get codes nothing else reaches. The digraph names here are just labels for shared
samples — the recording itself presumably says the number.</p>
-<h2>The deferred second syllable — mode 2</h2>
+<h2 id="mode2">The deferred second syllable — mode 2</h2>
<p><code>Sou_SpecialRoutine10</code> (<code>:1708</code>) runs once per game frame inside
<code>Na_GameFrame</code>:</p>