feat: port DDGame__LoadFonts and DDGameWrapper__LoadFontExtension to Rust
Browse filesReplaces the usercall bridge to 0x570F30 with pure Rust that loads 28
bitmap fonts, 23 font extensions, and sets the font palette via typed
DDDisplay vtable calls. Adds three new DDDisplay vtable slots (load_font,
load_font_extension, set_font_palette) and expands gfx_color_table from
9 to 11 entries, absorbing former _unknown_7330 as font palette data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crates/openwa-core/src/address.rs
CHANGED
|
@@ -104,7 +104,9 @@ pub mod va {
|
|
| 104 |
/// DDGame__InitVersionFlags — stdcall(ddgame_wrapper)
|
| 105 |
fn/Stdcall DDGAME_INIT_VERSION_FLAGS = 0x0052_5BE0;
|
| 106 |
/// DDGame__LoadFonts — loads .fnt font resources into the display.
|
| 107 |
-
fn DDGAME_LOAD_FONTS = 0x0057_0F30;
|
|
|
|
|
|
|
| 108 |
/// DDGame__LoadHudAndWeaponSprites
|
| 109 |
fn/Thiscall DDGAME_LOAD_HUD_AND_WEAPON_SPRITES = 0x0053_D0E0;
|
| 110 |
/// DDGame__InitPaletteGradientSprites
|
|
|
|
| 104 |
/// DDGame__InitVersionFlags — stdcall(ddgame_wrapper)
|
| 105 |
fn/Stdcall DDGAME_INIT_VERSION_FLAGS = 0x0052_5BE0;
|
| 106 |
/// DDGame__LoadFonts — loads .fnt font resources into the display.
|
| 107 |
+
fn/Usercall DDGAME_LOAD_FONTS = 0x0057_0F30;
|
| 108 |
+
/// DDGameWrapper__LoadFontExtension — loads .fex font extension for a font slot.
|
| 109 |
+
fn/Stdcall DDGAME_WRAPPER_LOAD_FONT_EXTENSION = 0x0057_0E80;
|
| 110 |
/// DDGame__LoadHudAndWeaponSprites
|
| 111 |
fn/Thiscall DDGAME_LOAD_HUD_AND_WEAPON_SPRITES = 0x0053_D0E0;
|
| 112 |
/// DDGame__InitPaletteGradientSprites
|
crates/openwa-core/src/display/dd_display.rs
CHANGED
|
@@ -29,6 +29,41 @@ pub struct DDDisplayVtable {
|
|
| 29 |
/// set layer visibility
|
| 30 |
#[slot(23)]
|
| 31 |
pub set_layer_visibility: fn(this: *mut DDDisplay, layer: i32, value: i32),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
/// load sprite with flag (RET 0x14)
|
| 33 |
#[slot(31)]
|
| 34 |
pub load_sprite: fn(
|
|
|
|
| 29 |
/// set layer visibility
|
| 30 |
#[slot(23)]
|
| 31 |
pub set_layer_visibility: fn(this: *mut DDDisplay, layer: i32, value: i32),
|
| 32 |
+
/// load .fnt bitmap font into a font slot (RET 0x10)
|
| 33 |
+
///
|
| 34 |
+
/// DDDisplay__LoadFont (0x523560).
|
| 35 |
+
/// mode: font source (1-3, usually 1). font_id: slot index (1-based, max 0x1F).
|
| 36 |
+
/// gfx: GfxDir archive to load from. filename: .fnt resource name.
|
| 37 |
+
#[slot(34)]
|
| 38 |
+
pub load_font: fn(
|
| 39 |
+
this: *mut DDDisplay,
|
| 40 |
+
mode: i32,
|
| 41 |
+
font_id: i32,
|
| 42 |
+
gfx: *mut u8,
|
| 43 |
+
filename: *const core::ffi::c_char,
|
| 44 |
+
) -> u32,
|
| 45 |
+
/// load .fex font extension (extra glyphs) for a font slot (RET 0x14)
|
| 46 |
+
///
|
| 47 |
+
/// DDDisplay__LoadFontExtension (0x523620).
|
| 48 |
+
/// font_id: slot index. path: filesystem path to .fex file.
|
| 49 |
+
/// char_map: 61-byte character code table. palette_value: color from GfxColorTable.
|
| 50 |
+
/// flag: unknown (always 0 from DDGameWrapper__LoadFontExtension).
|
| 51 |
+
#[slot(35)]
|
| 52 |
+
pub load_font_extension: fn(
|
| 53 |
+
this: *mut DDDisplay,
|
| 54 |
+
font_id: i32,
|
| 55 |
+
path: *const core::ffi::c_char,
|
| 56 |
+
char_map: *const u8,
|
| 57 |
+
palette_value: u32,
|
| 58 |
+
flag: i32,
|
| 59 |
+
) -> u32,
|
| 60 |
+
/// set font palette for all loaded fonts (RET 0x8)
|
| 61 |
+
///
|
| 62 |
+
/// DDDisplay__SetFontPalette (0x523690).
|
| 63 |
+
/// font_count: total number of font slots loaded.
|
| 64 |
+
/// palette_value: palette/color entry from DDGame GfxColorTable.
|
| 65 |
+
#[slot(36)]
|
| 66 |
+
pub set_font_palette: fn(this: *mut DDDisplay, font_count: u32, palette_value: u32),
|
| 67 |
/// load sprite with flag (RET 0x14)
|
| 68 |
#[slot(31)]
|
| 69 |
pub load_sprite: fn(
|
crates/openwa-core/src/engine/ddgame.rs
CHANGED
|
@@ -230,14 +230,13 @@ pub struct DDGame {
|
|
| 230 |
pub _field_7304: u32,
|
| 231 |
/// 0x7308: Sprite/gfx dimension data (passed to GFX_DIR_LOAD_SPRITES).
|
| 232 |
pub gfx_sprite_data: [u8; 0x730C - 0x7308],
|
| 233 |
-
/// 0x730C-
|
| 234 |
/// Populated from colours.img pixel row: `color_table[i] = get_pixel(sprite, i, 0)`.
|
| 235 |
/// Known entries:
|
| 236 |
/// - [6] (0x7324): Crosshair line color (DrawPolygon param_2)
|
| 237 |
/// - [8] (0x732C): Crosshair line style (DrawPolygon param_1)
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
pub _unknown_7330: [u8; 8],
|
| 241 |
/// 0x7338: Fill pixel value
|
| 242 |
pub fill_pixel: u32,
|
| 243 |
/// 0x733C-0x733F: Unknown
|
|
|
|
| 230 |
pub _field_7304: u32,
|
| 231 |
/// 0x7308: Sprite/gfx dimension data (passed to GFX_DIR_LOAD_SPRITES).
|
| 232 |
pub gfx_sprite_data: [u8; 0x730C - 0x7308],
|
| 233 |
+
/// 0x730C-0x7337: GfxDir color table (11 entries).
|
| 234 |
/// Populated from colours.img pixel row: `color_table[i] = get_pixel(sprite, i, 0)`.
|
| 235 |
/// Known entries:
|
| 236 |
/// - [6] (0x7324): Crosshair line color (DrawPolygon param_2)
|
| 237 |
/// - [8] (0x732C): Crosshair line style (DrawPolygon param_1)
|
| 238 |
+
/// - [9]-[10] (0x7330-0x7334): Font palette entries (used by LoadFontExtension)
|
| 239 |
+
pub gfx_color_table: [u32; 11],
|
|
|
|
| 240 |
/// 0x7338: Fill pixel value
|
| 241 |
pub fill_pixel: u32,
|
| 242 |
/// 0x733C-0x733F: Unknown
|
crates/openwa-core/src/engine/ddgame_constructor.rs
CHANGED
|
@@ -153,7 +153,7 @@ pub fn init_constructor_addrs() {
|
|
| 153 |
unsafe {
|
| 154 |
SPRITE_REGION_CTOR_ADDR = rb(va::SPRITE_REGION_CONSTRUCTOR);
|
| 155 |
FUN_570A90_ADDR = rb(va::FUN_570A90);
|
| 156 |
-
|
| 157 |
LOAD_SPEECH_BANKS_ADDR = rb(va::DSSOUND_LOAD_ALL_SPEECH_BANKS);
|
| 158 |
LOADING_PROGRESS_TICK_ADDR = rb(va::DDGAME_WRAPPER_LOADING_PROGRESS_TICK);
|
| 159 |
GFX_LOAD_SPRITES_ADDR = rb(va::GFX_DIR_LOAD_SPRITES);
|
|
@@ -627,8 +627,7 @@ unsafe fn init_graphics_and_resources(
|
|
| 627 |
|
| 628 |
// ── Audio init (non-headless + sound available) ──
|
| 629 |
if !is_headless {
|
| 630 |
-
|
| 631 |
-
call_usercall_esi(wrapper, FUN_570F30_ADDR);
|
| 632 |
if !(*ddgame).sound.is_null() {
|
| 633 |
load_effect_wavs(wrapper);
|
| 634 |
// DSSound_LoadAllSpeechBanks: the original is hooked to our Rust
|
|
@@ -1067,11 +1066,11 @@ unsafe fn init_graphics_and_resources(
|
|
| 1067 |
|
| 1068 |
// Statics for usercall bridge addresses
|
| 1069 |
static mut FUN_570A90_ADDR: u32 = 0;
|
| 1070 |
-
|
| 1071 |
static mut LOAD_SPEECH_BANKS_ADDR: u32 = 0;
|
| 1072 |
static mut LOADING_PROGRESS_TICK_ADDR: u32 = 0;
|
| 1073 |
|
| 1074 |
-
/// Bridge: usercall(ESI=wrapper), plain RET. Used by FUN_570E20,
|
| 1075 |
#[cfg(target_arch = "x86")]
|
| 1076 |
#[unsafe(naked)]
|
| 1077 |
unsafe extern "C" fn call_usercall_esi(_wrapper: *mut DDGameWrapper, _addr: u32) {
|
|
|
|
| 153 |
unsafe {
|
| 154 |
SPRITE_REGION_CTOR_ADDR = rb(va::SPRITE_REGION_CONSTRUCTOR);
|
| 155 |
FUN_570A90_ADDR = rb(va::FUN_570A90);
|
| 156 |
+
|
| 157 |
LOAD_SPEECH_BANKS_ADDR = rb(va::DSSOUND_LOAD_ALL_SPEECH_BANKS);
|
| 158 |
LOADING_PROGRESS_TICK_ADDR = rb(va::DDGAME_WRAPPER_LOADING_PROGRESS_TICK);
|
| 159 |
GFX_LOAD_SPRITES_ADDR = rb(va::GFX_DIR_LOAD_SPRITES);
|
|
|
|
| 627 |
|
| 628 |
// ── Audio init (non-headless + sound available) ──
|
| 629 |
if !is_headless {
|
| 630 |
+
crate::engine::ddgame_load_fonts::load_fonts(wrapper);
|
|
|
|
| 631 |
if !(*ddgame).sound.is_null() {
|
| 632 |
load_effect_wavs(wrapper);
|
| 633 |
// DSSound_LoadAllSpeechBanks: the original is hooked to our Rust
|
|
|
|
| 1066 |
|
| 1067 |
// Statics for usercall bridge addresses
|
| 1068 |
static mut FUN_570A90_ADDR: u32 = 0;
|
| 1069 |
+
|
| 1070 |
static mut LOAD_SPEECH_BANKS_ADDR: u32 = 0;
|
| 1071 |
static mut LOADING_PROGRESS_TICK_ADDR: u32 = 0;
|
| 1072 |
|
| 1073 |
+
/// Bridge: usercall(ESI=wrapper), plain RET. Used by FUN_570E20, LoadSpeechBanks.
|
| 1074 |
#[cfg(target_arch = "x86")]
|
| 1075 |
#[unsafe(naked)]
|
| 1076 |
unsafe extern "C" fn call_usercall_esi(_wrapper: *mut DDGameWrapper, _addr: u32) {
|
crates/openwa-core/src/engine/ddgame_load_fonts.rs
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//! DDGame__LoadFonts (0x570F30) and DDGameWrapper__LoadFontExtension (0x570E80).
|
| 2 |
+
//!
|
| 3 |
+
//! Loads 28 bitmap fonts (.fnt) and 23 font extensions (.fex) into the display,
|
| 4 |
+
//! then sets the font palette. Called from DDGame__Constructor during loading.
|
| 5 |
+
|
| 6 |
+
use core::ffi::c_char;
|
| 7 |
+
use heapless::CString;
|
| 8 |
+
|
| 9 |
+
use crate::display::dd_display::DDDisplay;
|
| 10 |
+
use crate::engine::ddgame_wrapper::DDGameWrapper;
|
| 11 |
+
|
| 12 |
+
/// Total number of font slots loaded (1-based, so slots 1..=28).
|
| 13 |
+
const FONT_COUNT: u32 = 0x1C;
|
| 14 |
+
|
| 15 |
+
/// Number of font slots that get font extensions loaded (1..=23).
|
| 16 |
+
const FONT_EXT_COUNT: u32 = 0x17;
|
| 17 |
+
|
| 18 |
+
/// Font filenames (.fnt), indexed 1..=28 (slot 0 unused).
|
| 19 |
+
const FONT_FILENAMES: [&[u8]; 29] = [
|
| 20 |
+
b"\0", // [0] unused
|
| 21 |
+
b"smlred1.fnt\0", // [1]
|
| 22 |
+
b"smlblu1.fnt\0", // [2]
|
| 23 |
+
b"smlgrn1.fnt\0", // [3]
|
| 24 |
+
b"smlyel1.fnt\0", // [4]
|
| 25 |
+
b"smlppl1.fnt\0", // [5]
|
| 26 |
+
b"smlcyn1.fnt\0", // [6]
|
| 27 |
+
b"smlwht1.fnt\0", // [7]
|
| 28 |
+
b"smlwht2.fnt\0", // [8]
|
| 29 |
+
b"stdred1.fnt\0", // [9]
|
| 30 |
+
b"stdblu1.fnt\0", // [10]
|
| 31 |
+
b"stdgrn1.fnt\0", // [11]
|
| 32 |
+
b"stdyel1.fnt\0", // [12]
|
| 33 |
+
b"stdppl1.fnt\0", // [13]
|
| 34 |
+
b"stdcyn1.fnt\0", // [14]
|
| 35 |
+
b"stdwht1.fnt\0", // [15]
|
| 36 |
+
b"stdwht2.fnt\0", // [16]
|
| 37 |
+
b"medred1.fnt\0", // [17]
|
| 38 |
+
b"medblu1.fnt\0", // [18]
|
| 39 |
+
b"medgrn1.fnt\0", // [19]
|
| 40 |
+
b"medyel1.fnt\0", // [20]
|
| 41 |
+
b"medppl1.fnt\0", // [21]
|
| 42 |
+
b"medcyn1.fnt\0", // [22]
|
| 43 |
+
b"medwht1.fnt\0", // [23]
|
| 44 |
+
b"lnumred1.fnt\0", // [24]
|
| 45 |
+
b"lnumwht1.fnt\0", // [25]
|
| 46 |
+
b"lnumred2.fnt\0", // [26]
|
| 47 |
+
b"lnumwht2.fnt\0", // [27]
|
| 48 |
+
b"digiwht.fnt\0", // [28]
|
| 49 |
+
];
|
| 50 |
+
|
| 51 |
+
/// Font ID → size category index.
|
| 52 |
+
/// 0 = sml, 1 = std, 2 = med, 3 = bignum, 4 = digi.
|
| 53 |
+
/// Original data at 0x6A90E8.
|
| 54 |
+
const FONT_SIZE_CATEGORY: [u32; 29] = [
|
| 55 |
+
5, // [0] unused
|
| 56 |
+
0, 0, 0, 0, 0, 0, 0, 0, // [1-8] sml
|
| 57 |
+
1, 1, 1, 1, 1, 1, 1, 1, // [9-16] std
|
| 58 |
+
2, 2, 2, 2, 2, 2, 2, // [17-23] med
|
| 59 |
+
3, 3, 3, 3, // [24-27] bignum
|
| 60 |
+
4, // [28] digi
|
| 61 |
+
];
|
| 62 |
+
|
| 63 |
+
/// Font ID → color index. Original data at 0x6A9160.
|
| 64 |
+
const FONT_COLOR_INDEX: [u32; 29] = [
|
| 65 |
+
10, // [0]
|
| 66 |
+
0, 1, 2, 3, 4, 5, 6, 7, // [1-8] red, blu, grn, yel, ppl, cyn, wht1, wht2
|
| 67 |
+
0, 1, 2, 3, 4, 5, 6, 7, // [9-16]
|
| 68 |
+
0, 1, 2, 3, 4, 5, 6, // [17-23]
|
| 69 |
+
9, 6, 8, 7, // [24-27]
|
| 70 |
+
6, // [28]
|
| 71 |
+
];
|
| 72 |
+
|
| 73 |
+
/// Color index → gfx_color_table index (0-based).
|
| 74 |
+
/// Original data at 0x6A91D4 (1-based offsets from DDGame+0x7308, converted to 0-based).
|
| 75 |
+
const COLOR_TABLE_INDEX: [usize; 10] = [0, 1, 2, 3, 4, 5, 8, 6, 9, 10];
|
| 76 |
+
|
| 77 |
+
/// Size category → .fex path prefix.
|
| 78 |
+
const SIZE_PREFIXES: [&str; 5] = ["sml", "std", "med", "bignum", ""];
|
| 79 |
+
|
| 80 |
+
/// Extended character map (61 bytes). Original data at 0x66ACD8.
|
| 81 |
+
/// Defines which character codes are present in .fex font extension files.
|
| 82 |
+
const FONT_EXT_CHAR_MAP: [u8; 61] = [
|
| 83 |
+
0xBF, 0xA1, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D,
|
| 84 |
+
0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E,
|
| 85 |
+
0xA2, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
|
| 86 |
+
0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x0A, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0x00,
|
| 87 |
+
];
|
| 88 |
+
|
| 89 |
+
/// Load a font extension (.fex) for the given font slot.
|
| 90 |
+
///
|
| 91 |
+
/// Port of DDGameWrapper__LoadFontExtension (0x570E80, stdcall, RET 0x8).
|
| 92 |
+
/// Formats the .fex path from the font's size category, copies the character map,
|
| 93 |
+
/// resolves the palette value, and calls DDDisplay::load_font_extension.
|
| 94 |
+
unsafe fn load_font_extension(wrapper: *mut DDGameWrapper, font_id: u32) {
|
| 95 |
+
let size_category = FONT_SIZE_CATEGORY[font_id as usize];
|
| 96 |
+
let prefix = SIZE_PREFIXES[size_category as usize];
|
| 97 |
+
|
| 98 |
+
// Format path: "Data\Gfx\FontExt\{prefix}2.fex"
|
| 99 |
+
let mut path: CString<64> = CString::new();
|
| 100 |
+
let _ = path.extend_from_bytes(b"Data\\Gfx\\FontExt\\");
|
| 101 |
+
let _ = path.extend_from_bytes(prefix.as_bytes());
|
| 102 |
+
let _ = path.extend_from_bytes(b"2.fex");
|
| 103 |
+
|
| 104 |
+
// Copy character map to stack (original does REP MOVSD + MOVSB)
|
| 105 |
+
let char_map = FONT_EXT_CHAR_MAP;
|
| 106 |
+
|
| 107 |
+
// Resolve palette value: font_id → color_index → gfx_color_table entry
|
| 108 |
+
let color_index = FONT_COLOR_INDEX[font_id as usize];
|
| 109 |
+
let table_index = COLOR_TABLE_INDEX[color_index as usize];
|
| 110 |
+
let ddgame = (*wrapper).ddgame;
|
| 111 |
+
let palette_value = (*ddgame).gfx_color_table[table_index];
|
| 112 |
+
|
| 113 |
+
let display = (*wrapper).display;
|
| 114 |
+
DDDisplay::load_font_extension_raw(
|
| 115 |
+
display,
|
| 116 |
+
font_id as i32,
|
| 117 |
+
path.as_ptr() as *const c_char,
|
| 118 |
+
char_map.as_ptr(),
|
| 119 |
+
palette_value,
|
| 120 |
+
0,
|
| 121 |
+
);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
/// Load all bitmap fonts and font extensions.
|
| 125 |
+
///
|
| 126 |
+
/// Port of DDGame__LoadFonts (0x570F30, usercall ESI=DDGameWrapper).
|
| 127 |
+
///
|
| 128 |
+
/// Phase 1: Loads 28 .fnt bitmap fonts via DDDisplay::load_font.
|
| 129 |
+
/// Phase 2: Loads .fex font extensions for font slots 1-23.
|
| 130 |
+
/// Phase 3: Sets the font palette via DDDisplay::set_font_palette.
|
| 131 |
+
pub unsafe fn load_fonts(wrapper: *mut DDGameWrapper) {
|
| 132 |
+
let display = (*wrapper).display;
|
| 133 |
+
let gfx_dir = (*wrapper).primary_gfx_dir;
|
| 134 |
+
|
| 135 |
+
// Phase 1: Load all 28 .fnt font files
|
| 136 |
+
for font_id in 1..=FONT_COUNT {
|
| 137 |
+
let filename = FONT_FILENAMES[font_id as usize];
|
| 138 |
+
DDDisplay::load_font_raw(
|
| 139 |
+
display,
|
| 140 |
+
1,
|
| 141 |
+
font_id as i32,
|
| 142 |
+
gfx_dir,
|
| 143 |
+
filename.as_ptr() as *const c_char,
|
| 144 |
+
);
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
// Phase 2: Load font extensions for slots 1-23
|
| 148 |
+
for font_id in 1..=FONT_EXT_COUNT {
|
| 149 |
+
load_font_extension(wrapper, font_id);
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
// Phase 3: Set font palette — passes font count and gfx_color_table[7].
|
| 153 |
+
let ddgame = (*wrapper).ddgame;
|
| 154 |
+
let palette_value = (*ddgame).gfx_color_table[7];
|
| 155 |
+
DDDisplay::set_font_palette_raw(display, FONT_COUNT, palette_value);
|
| 156 |
+
}
|
crates/openwa-core/src/engine/mod.rs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
pub mod ddgame;
|
| 2 |
pub mod ddgame_constructor;
|
|
|
|
| 3 |
pub mod ddgame_wrapper;
|
| 4 |
pub mod game_info;
|
| 5 |
pub mod game_session;
|
|
|
|
| 1 |
pub mod ddgame;
|
| 2 |
pub mod ddgame_constructor;
|
| 3 |
+
pub mod ddgame_load_fonts;
|
| 4 |
pub mod ddgame_wrapper;
|
| 5 |
pub mod game_info;
|
| 6 |
pub mod game_session;
|