Format reference/end06
This is the ending script format for Touhou 06-09 ( Embodiment of Scarlet Devil, Perfect Cherry Blossom, Imperishable Night and Phantasmagoria of Flower View).
Opcodes
As this is a text-based format, all parameters are given as ASCII strings. Each parameter is terminated with a null byte, each instruction with a line break1.
Opcode | Mnemonic2 | Parameter 1 | Parameter 2 | Parameter 3 | Description |
---|---|---|---|---|---|
(empty) | display
|
String | (N/a) | (N/a) | Display a line of text. |
@b
|
background
|
.jpg file | (N/a) | (N/a) | Displays the given file as background. |
@a
|
anm
|
??? | Script index? | Sprite index? | Execute anm script |
@V
|
scrollbg
|
Distance in pixels | Duration in frames | (N/a) | Scrolls background up (i.e. the image moves downward) |
@v
|
setscroll
|
Vertical coordinate of the new top border of the image | (N/a) | (N/a) | Sets the background vertical scroll position |
@F
|
exec
|
.end file | (N/a) | (N/a) | Executes the ending script in the given file. This file is re-loaded from the archive.
This also calls In th09 it also does something (preloads?) with |
@R
|
staffroll
|
(unused) | (N/a) | (N/a) | Unknown. Some sort of initialization. The first instruction of staff roll files. See @F for why it doesn't actually run.
|
@m
|
musicplay
|
.mid file3 | (N/a) | (N/a) | Loads the given BGM and restarts playback. |
@M
|
musicfade
|
Fade-out duration in seconds | (N/a) | (N/a) | Fades out BGM.
Passing 0 will stop playback immediately - active MIDI notes are not stopped in this case. |
@s
|
setdelay
|
Frames to wait after displaying line 2 and beyond | Frames to wait after displaying the top line | (N/a) | Set line delays.
When holding the |
@c
|
color
|
Color in 24-bit decimal BGR format.
e.g. |
(N/a) | (N/a) | Changes the text color. |
@r
|
waitreset
|
Maximum frames | Minimum frames | (N/a) | Same as @w , but resets text display after wait.
|
@w
|
wait
|
Maximum frames | Minimum frames | (N/a) | Waits for input and pauses script execution.
Parameter 2 is ignored if larger than parameter 1. |
@0
|
fadeinblack
|
Frames | (N/a) | (N/a) | Unused. @2 but black.
|
@1
|
fadeoutblack
|
Frames | (N/a) | (N/a) | Unused. @3 but black.
|
@2
|
fadein
|
Frames | (N/a) | (N/a) | Displays a white quad on top of the screen and fade it out in the given time. |
@3
|
fadeout
|
Frames | (N/a) | (N/a) | Fades the screen to white. |
@z
|
end
|
(N/a) | (N/a) | (N/a) | Ends script execution. Not calling this at the end will cause the game to crash! |
- 1 The static English patch for Imperishable Night by NDT seems to have an extra null after most instructions. For compatibility with that patch, ignore any extra arguments.
- 2 as used by Egor's decompiler
- 3 in Phantasmagoria of Flower View this is actually a single byte. 0x10 is ending theme, 0x11 is staff roll theme.
Limitations
- Text lines are limited to 64 bytes.
- Embodiment of Scarlet Devil: Like all longer text in this game, these are split on the 32th byte and rendered as a left and right half.
- A maximum of 6 lines can be displayed at once. Everything after that will be invisible, and the 10th line crashes the game.
Patching approach
- Firstly, I'd really like to have the layout engine done before doing this. Aligning text and character names with full-width spaces is silly.
- Also, EoSD requires its separate beautification treatment.
Each contiguous block of text, delimited by @c
, @w
or @r
, counts as one translation unit/template. Then, we simply replace the entire block with the new translated text.
Line count doesn't matter at all - it's highly unlikely to crash the game, and there's always one additional line available. Empty lines do matter, though.
Memory locations
game | version | end parser |
---|---|---|
Embodiment of Scarlet Devil | v1.02h | sub_40F7C0 |
Perfect Cherry Blossom | v1.00b | sub_41D700 |
Imperishable Night | v1.00d | sub_428B80 |
Phantasmagoria of Flower View | v1.50a | sub_40E8A0 |