From 24ec2a92b56ca4296fe65b70524e36a8e1c67c2e Mon Sep 17 00:00:00 2001
From: Alexander Kassouni
Na_VoiceSe in full: the 55-entry digraph table, short/long
+ Na_VoiceSe in full: the 53-entry digraph table, short/long
vowel tables, silent e, magic e, and punctuation flush.if (a == 0x85 && b == 0xFF && c == 0xFF) return;-
Returns before touching any state, so a lone punctuation mark does not disturb the -previous-character history.
+sou_num_org, sou_num2_org and sou_num3_org are assigned
+before this test, so they are overwritten; what survives is
+sou_last_num / sou_last_num2, which are written further down. A lone
+punctuation mark therefore leaves the digraph history intact, but still clobbers the
+context bytes a pending mode 2 call will read —
+sou_num3_org for its short-vowel lookup, sou_num_org for its dedup
+comparison.
:2612)if (a == 'e' && b > 0x77 && class(last_num) == vowel && class(last_num2) == consonant) {
@@ -71,6 +76,17 @@ are consumed by one sample.
The digraph table — Sou_ConnectCheck (:2316)
53 entries. All are two characters except you, the only rule that reads c; one pairs a letter with a space rather than another letter (i␣).
+
+i␣ is very nearly unreachable. Its b is 0x81,
+which is also a punctuation-flush trigger — so rule 3 below sets r28 = 3 and
+unconditionally reassigns a, discarding the 0x05. It survives only when
+the previous call's b was also punctuation, which forces r28 = 1
+instead; 0x05 then falls through Sou_TanboinHenkan's
+default: return a and reaches playback unchanged. Every other digraph has a letter
+in b and so never meets rule 3 — for those, "r28 = 2 falls straight
+through to playback" holds as written.
+
+
ai→0x0F
al→0x02
an→0x39
ar→0x16
as→0x3A
be→0x3B
by→0x3C
@@ -110,9 +126,23 @@ each one a recorded syllable.
a = Sou_ConnectCheck(sou_last_num2, sou_num_org, sou_num2_org);
if (a < 0x53 || a > 0x76) break; // it merged, or wasn't a letter — leave it
a = Sou_TanboinHenkan(a, b);
-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 a > 0x77 before it starts.
+The intent 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.
+a is reloaded from sou_last_num2 — the previous call's
+b — and if Sou_ConnectCheck finds no merge it returns that byte
+unchanged, so Sou_TanboinHenkan speaks the previous letter a second time and the
+word-final letter is never voiced at all.
+
+Worked example, cat␣. Window (c, a, t) doesn't merge, so
+r28 = 1 plays hard c and queues a; the deferred call plays
+a. Window (t, ␣, …) then hits rule 3, reloads
+a = sou_last_num2 = 'a', fails to merge at, and plays a
+again. The t makes no sound. The branch only pays off when the reloaded pair
+does merge — then the merged code plays and the 0x53–0x76
+guard breaks out before Sou_TanboinHenkan can touch it.
+
+Note the guard also drops the whole branch if a > 0x77 before it starts, and
+that nothing is queued on this path.
4. Vowel length (:2658, for r28 == 1 or 4)
if (class(a) == vowel && class(b) == consonant && c == 'e')
@@ -168,7 +198,7 @@ with the first syllable of the spoken number: 0=ze(ro)
get codes nothing else reaches. The digraph names here are just labels for shared
samples — the recording itself presumably says the number.
-The deferred second syllable — mode 2
+The deferred second syllable — mode 2
Sou_SpecialRoutine10 (:1708) runs once per game frame inside
Na_GameFrame:
diff --git a/docs/playback.html b/docs/playback.html
index 1cf9464..73be9a2 100644
--- a/docs/playback.html
+++ b/docs/playback.html
@@ -33,7 +33,7 @@ into the phoneme path — the pitch and volume bumps below never apply to the pl
Code Char Effect
0x86click NA_SE_BEBE, then mute
0x81 0x84 0x85space, newline, mute mute
-0x82?mute, and pitch × 1.24 / 1.30 / 1.13 for sequence 243 / 244 / 245
+0x82?mute, and pitch × 1.24 / 1.30 / 1.13 for sou_now_voice_seq 1 / 2 / 3 — the small index Na_SpecChange sets alongside sequence 243 / 244 / 245, not the sequence number itself
0x83!mute, and volume × 1.15
anything else plays; sets sou_now_boin (dead, see quirks)
diff --git a/docs/quirks.html b/docs/quirks.html
index bb860c9..c46fdb2 100644
--- a/docs/quirks.html
+++ b/docs/quirks.html
@@ -145,7 +145,7 @@ the config. See gating.
Everything else in extraction.md §1 was re-verified against the current tree
-and holds: the voice table, the 55 digraph entries, both vowel tables, the per-spec
+and holds: the voice table, the 53 digraph entries, both vowel tables, the per-spec
timbre values, and the spec→sequence→bank mapping.
diff --git a/docs/scheduling.html b/docs/scheduling.html
index 581dff6..07f1e52 100644
--- a/docs/scheduling.html
+++ b/docs/scheduling.html
@@ -111,9 +111,12 @@ volume adjustment is skipped entirely. (What happens for other values is
not what it looks like.)
It also contains one very specific special case: if the character is ♪ at exactly
-normal scale in colour rgba(50, 60, 50, 255), the NPC id is forced to 0,
-suppressing the melody. This is presumably a specific piece of dialogue where a
-literal music note glyph should stay silent.
+normal scale in colour rgba(50, 60, 50, 255) and the NPC id is non-zero, that id
+is forced to 0. This does not silence it — Na_VoiceSe's ♪ escape
+only bails on voice == 0xFA, and melody_seq_offset[0] /
+melody_seq_size[0] are a real 0x120-byte entry. The effect is to play
+the figure on instrument 0 rather than the speaker's own, presumably so one particular
+line reads as a generic note instead of that character's timbre.
End of message
--
cgit v1.3.1