Subtitles
Spoken dialogue and combat taunts draw their text in
FONTS\REDSEL.FNT on a virtual 640×480 screen, which the Glide renderer
scales to the output size.
Glyphs
- Advance per character: glyph width + 1. A space additionally adds the width
of
!, so a REDSEL space advances 11 pixels. Disabled glyphs advance 0 and are not drawn. - A glyph is drawn at (pen x +
offset_left, line top +offset_top). Palette index 0 is transparent. - Each glyph is drawn twice: first a shadow copy offset by (1, 1), then the main copy.
- Copies of REDSEL differ only in a value pair
A,B: NPC lines useSYSTEM.INI [3dfx] font_sel(shipped255,255), Cyrus’ linesfont_norm(125,255). The main copy is drawn with alphaB, the shadow copy with alphaB × 200 / 256(integer);Adoes not enter either alpha. Glide draws each copy with that value as the constant colour’s alpha. Values below 254 blend over the scene (source alpha, one minus source alpha); 254 and above draw without blending. - For NPC lines using
font_sel, main glyphs are opaque in the font’s own palette colours. BPAL entries are 6-bit; index 19539,3,14is crimson and index 8160,59,11is yellow. The shadow is the glyph shape in black, blended over the scene at alpha 199/255. - A line is centred on x = 320: it starts at
320 + trunc(−width / 2). - Subtitles ignore
[system] disable_text.
Shared text colour state
The Glide text colour setup does not select a palette. For a font with its
indexed-colour flag set, it reads the current text-colour index from the
already selected palette and writes those RGB components to the constant
colour state. The constant alpha is the font’s first style value, A.
For a font without that flag, all four constant colour components are set
to A instead. These are the text setup values; individual glyph and shadow
passes apply the rules above.
The text colour reset sets all four constant colour components to 255. It does not restore an earlier constant colour or change the selected palette.
Dialogue
The text is the RTX entry’s own string: the label of a voiced entry, the text
of a string-only entry. Script functions RTX, rtxAnim and RTXpAnim
(speaker: the scripted actor), RTXp (speaker: Cyrus) and combat taunts
create subtitles.
Slots
[dialog] dialog_max_dialog_lines is the number of subtitle slots, at least
16 (shipped 20), not a line limit. Slot 0 belongs to Cyrus (RTXp) and is
overwritten unconditionally; other speakers take the lowest free slot, and no
subtitle is created when none is free. Only one subtitle is drawn per frame:
the lowest active slot.
Wrapping
Width limit W = max([dialog] dialog_max_text_width, 150) (shipped 500),
measured with REDSEL advances. The text is split into tokens, each an optional
leading space plus a word. A token joins the line while running + token < W (strict); otherwise a line break replaces its leading space and the running
width restarts at the token’s width including the dropped space.
Position
With breaks line breaks, the block height is 26 × (max(breaks, 1) + 1)
and the first line’s top is 470 − height; each next line is 26 lower. One
line therefore sits at y 418, two lines at 418 and 444.
Timing
dialog_use_speech = 1: a voiced line shows while its clip plays and is freed when the clip stops. A string-only entry is neither drawn nor freed.dialog_use_speech = 0: the voice is stopped. The line starts withremaining = clip seconds × 256(voiced) orcharacters × 15(string-only) and loses 21 per game tick; it is freed onceremaining ≤ 0.dialog_print_text = 0: slots keep the same timing (script waits are unchanged) but nothing is drawn.- Script
RTXlines from a speaker farther thandialog_max_distance(1600) are not started.
Movies
Movie subtitles are documented in movies.