the minimap and world map go stock, and the chat loses its white plate

- the minimap cluster and the battleground list are the reference's own `Minimap.xml` and `BattlefieldFrame.xml`, ours deleted, and the sixteen engine names the static probe found unbound are built, not stubbed: the battleground list and queue family (the as-group join refused client-side with no packet when the map's `MaxPlayers` is below the group), the bodyless `CMSG_BATTLEFIELD_STATUS` on world enter — benilla never sent it, so a queue joined before a reconnect was invisible — the 5.5556 yd `BATTLEFIELDS_CLOSED` leash, and the meeting-stone pair over the `0x295` five-way table with both asymmetries; the ping's lifetime is the stock Lua's now (held 5 s, faded 0.5 s), `GetPingPosition` answers two numbers always — our nil was a Lua error on every frame of the stock `Minimap_OnUpdate` — and the map-change drop the reference never had is gone (1974)
- the world map is the reference's own `WorldMapFrame.xml`, our transcription deleted; built for it: the arrow-frame family (an anonymous `Model` child at its 33.6 px footprint, drawn app-side as the minimap's own arrow sprite through one shared constant), the battleground position family over `MSG_BATTLEGROUND_PLAYER_POSITIONS` both ways (the reference's 5000 ms request throttle), and `GetPlayerMapPosition` resolving `raid1..raid40` where it knew only the party (B320); `SetupFullscreenScale` — the engine binding `0x48c270` the map's and the cinematic frame's OnShow call, which our map had stood in for with Lua — is bound to the carved law `min(0.75 · aspect, 1)` off the configured aspect, written through the frame's own `SetScale` (1.0 at 4:3 and wider, 0.9375 at 5:4); a hovered POI writes the map's own area label, not the tooltip; named gap: `WorldMapPing` draws nothing yet (1980, 1981)
- the tutorial frame is the reference's own `TutorialFrame.xml`, over a tutorial system benilla never had: two bit banks filled from `SMSG_TUTORIAL_FLAGS` — the fire-once bank `TriggerTutorial` reads and sets (never a send) and the acknowledged bank `FlagTutorial` writes and sends; there is no tutorial CVar in the binary (210 `CVar::Register` sites censused), so "disable tutorials" is every bit acknowledged; the sites this app can produce are wired (the world-enter Welcome cascade, the level-up arm, item pushes, the loot sparkle, the meeting-stone and battleground arms), the rest named; the loader learned `<TitleRegion>` — the stock frame's drag handle, a region that emits no quad; and the `TabardModel` widget kind arrives ahead of its window, five ints bounded by the `.rdata` table `{170, 17, 6, 17, 51}` and the constant 100 000 tabard cost (1976, 1977)
- the chat window drew as an opaque white plate: the chat-cache loader, gated on `InWorld` alone, restored into the boot VM 130 ms before the deferred entry load filled it, and its per-VM memo then blocked the restore that would have reached the real frames — the plate the stock Lua tints black stayed the XML's white; between the entry edge and the load there is now no VM in the world (the edge parks the boot VM, the load takes it back), so no in-world feed pushes into a VM with no interface; the perf pill reads `59 fps  7.0 ms  17.3 cpu` — the MAIN thread's milliseconds in full text and the process-wide sum dim, because the sum of every thread's CPU time had been read as a frame time (a raid read 17 on it at a solid 60 with the main thread at 7); and `WOW_PROBE_UI_ONE_TEX=1` is a pricing lever, never a look, for the draw-count ceiling a UI atlas would reach before one is built (1978, 1954)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-04 20:59:53 +07:00
co-authored by Claude Fable 5.1
parent edd6628329
commit 9bf64e1a6b
89 changed files with 6164 additions and 2107 deletions
+101 -2
View File
@@ -16,7 +16,7 @@
use std::ffi::c_void;
use mlua::{LightUserData, Lua, Table, Value};
use mlua::{LightUserData, Lua, ObjectLike, Table, Value};
use super::binding_abi::optional_string;
use super::{Model, REG_FRAME_META, REG_FRAME_METHODS, REG_SCRIPTS, REG_WRAPPERS};
@@ -235,6 +235,7 @@ fn frame_kind_from_str(s: &str) -> Option<FrameKind> {
"MODEL" => FrameKind::Model,
"PLAYERMODEL" => FrameKind::PlayerModel,
"DRESSUPMODEL" => FrameKind::DressUpModel,
"TABARDMODEL" => FrameKind::TabardModel,
"MESSAGEFRAME" => FrameKind::MessageFrame,
"SCROLLINGMESSAGEFRAME" => FrameKind::ScrollingMessageFrame,
"COLORSELECT" => FrameKind::ColorSelect,
@@ -318,6 +319,39 @@ pub(super) fn install(lua: &Lua) -> mlua::Result<()> {
})?,
)?;
// SetupFullscreenScale(frame) — the registered binding `0x48c270` the stock WorldMapFrame.xml,
// CinematicFrame.xml and UIOptionsFrame.xml call from OnShow (decision 1980; wow-re
// `system/ui/scratch/setup-fullscreen-scale.md`, VERIFIED at the bytes): the frame's scale
// becomes `min(0.75 · a, 1.0)` for the CONFIGURED aspect `a` — the `gxResolution` width over
// height (the `widescreen` CVar's default of 1 selects it; at 0 the aspect is 4:3 and the
// scale 1) — and nothing else is written: no anchor, size or position, and `UIParent`'s
// scale never enters. It is the same `CSimpleFrame::SetScale` the Lua method calls. The
// window's aspect is the configured one here (the UI-unit rect keeps the pixel ratio); NaN
// takes the 1.0 leg as the reference's `fcomp` does. The three raises are the binding's own.
lua.globals().set(
"SetupFullscreenScale",
lua.create_function(|lua, frame: Value| {
let Value::Table(frame) = frame else {
return Err(mlua::Error::runtime("Usage: SetupFullscreenScale(frame)"));
};
if decode_id(&frame).is_err() {
return Err(mlua::Error::runtime(
"SetupFullscreenScale(): Couldn't find 'this' in frame object",
));
}
if frame_handle_of(lua, &frame).is_err() {
return Err(mlua::Error::runtime(
"SetupFullscreenScale(): Wrong object type, expected frame",
));
}
let scale = {
let model = lua.app_data_ref::<Model>().expect("model");
fullscreen_scale(model.screen.width() / model.screen.height())
};
frame.call_method::<()>("SetScale", scale)
})?,
)?;
// GetCursorPosition() → x, y — the last cursor position the host fed (`mouse_move`/
// `mouse_button`), UI units y-up like every other coordinate read. The real client scales by
// the UI scale; ours is the constant 1 (`GetEffectiveScale`), so the ref's `/scale` dance is
@@ -408,6 +442,13 @@ fn kind_method_registries(lua: &Lua, this: &Table) -> &'static [&'static str] {
super::modelframe::REG_PLAYERMODEL_METHODS,
super::modelframe::REG_MODEL_METHODS,
],
// Ten of its own (`0x84ee40`), then PlayerModel's three, then Model's 23 — the same
// derived → base probe as its sibling (1977).
Some(FrameKind::TabardModel) => &[
super::tabard::REG_TABARDMODEL_METHODS,
super::modelframe::REG_PLAYERMODEL_METHODS,
super::modelframe::REG_MODEL_METHODS,
],
Some(FrameKind::Minimap) => &[super::minimap::REG_MINIMAP_METHODS],
Some(FrameKind::Cooldown) => &[super::cooldown::REG_COOLDOWN_METHODS],
Some(FrameKind::GameTooltip) => &[super::tooltip::REG_TOOLTIP_METHODS],
@@ -431,7 +472,7 @@ fn kind_method_registries(lua: &Lua, this: &Table) -> &'static [&'static str] {
/// `virtual="true"`, or of a shape that does not fit the kind asked for — is still a warning plus a
/// working frame, because the registry lookup itself succeeded and that is the only thing the miss
/// branch tests.
fn create_frame(
pub(super) fn create_frame(
lua: &Lua,
(kind, name, parent, inherits): (String, Option<Value>, Option<Value>, Option<Value>),
) -> mlua::Result<Table> {
@@ -576,3 +617,61 @@ fn install_frame_methods(lua: &Lua) -> mlua::Result<()> {
lua.set_named_registry_value(REG_FRAME_METHODS, m)?;
Ok(())
}
/// `0x48c270`'s law: `g = 0.75 · aspect`, and the scale is `g` below 1.0, else 1.0 — NaN lands on
/// the 1.0 leg (the `fcomp` compare fails every ordered test).
pub(crate) fn fullscreen_scale(aspect: f32) -> f32 {
let g = 0.75 * aspect;
if g < 1.0 {
g
} else {
1.0
}
}
#[cfg(test)]
mod fullscreen_scale_tests {
use super::fullscreen_scale;
use crate::script::UiScript;
#[test]
fn the_scale_is_three_quarters_of_the_aspect_capped_at_one() {
assert_eq!(fullscreen_scale(4.0 / 3.0), 1.0);
assert_eq!(fullscreen_scale(16.0 / 9.0), 1.0);
assert!((fullscreen_scale(5.0 / 4.0) - 0.9375).abs() < 1e-6);
assert_eq!(fullscreen_scale(f32::NAN), 1.0);
}
#[test]
fn the_verb_scales_the_frame_and_raises_its_three_strings() {
let mut s = UiScript::new().unwrap();
s.set_screen_size(1280.0, 1024.0);
s.run(r#"f = CreateFrame("Frame", "FS") SetupFullscreenScale(f)"#)
.unwrap();
assert!((s.eval::<f64>("return f:GetScale()").unwrap() - 0.9375).abs() < 1e-6);
s.set_screen_size(1600.0, 900.0);
s.run("SetupFullscreenScale(f)").unwrap();
assert_eq!(s.eval::<f64>("return f:GetScale()").unwrap(), 1.0);
for (call, needle) in [
(
"SetupFullscreenScale()",
"Usage: SetupFullscreenScale(frame)",
),
(
"SetupFullscreenScale(7)",
"Usage: SetupFullscreenScale(frame)",
),
(
"SetupFullscreenScale({})",
"Couldn't find 'this' in frame object",
),
(
"SetupFullscreenScale(f:CreateTexture())",
"Wrong object type, expected frame",
),
] {
let err = s.run(call).unwrap_err().to_string();
assert!(err.contains(needle), "{call}: {err}");
}
}
}