From d45a84038eb4886409d73440547a715b8161894e Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Tue, 21 Apr 2026 23:11:22 -0700 Subject: [PATCH] Promote shipped IMB profile fields --- crates/rrt-runtime/src/inspect/imb.rs | 42 +++++++++++++++++-- docs/rehost-queue.md | 1 + ...ngine-types-parser-semantics-2026-04-21.md | 14 ++++++- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/crates/rrt-runtime/src/inspect/imb.rs b/crates/rrt-runtime/src/inspect/imb.rs index 30166ac..d24f4e5 100644 --- a/crates/rrt-runtime/src/inspect/imb.rs +++ b/crates/rrt-runtime/src/inspect/imb.rs @@ -25,8 +25,10 @@ pub struct ImbInspectionReport { pub target_screen_width: Option, pub target_screen_height: Option, pub scaleable: Option, + pub horizontal_scale_modifier: Option, pub max_percent_of_interface_vram: Option, pub image_rect: Option<[i64; 4]>, + pub image_rect_scaled: Option<[i64; 4]>, pub notes: Vec, pub entries: Vec, pub malformed_lines: Vec, @@ -78,8 +80,10 @@ pub fn inspect_imb_bytes(bytes: &[u8]) -> Result Result Result Option> { - tokens + let numeric_tokens = numeric_prefix_tokens(tokens); + (!numeric_tokens.is_empty()) + .then_some(numeric_tokens)? .iter() .map(|token| token.parse::().ok()) .collect::>>() } fn parse_f64_tokens(tokens: &[String]) -> Option> { - tokens + let numeric_tokens = numeric_prefix_tokens(tokens); + (!numeric_tokens.is_empty()) + .then_some(numeric_tokens)? .iter() .map(|token| token.parse::().ok()) .collect::>>() } +fn numeric_prefix_tokens(tokens: &[String]) -> Vec<&str> { + tokens + .iter() + .take_while(|token| !token.starts_with(';')) + .map(|token| token.as_str()) + .collect() +} + fn find_scalar_string(entries: &[ImbInspectionEntry], key: &str) -> Option { entries .iter() @@ -220,4 +238,20 @@ mod tests { assert_eq!(report.scaleable, Some(true)); assert_eq!(report.max_percent_of_interface_vram, Some(0.06)); } + + #[test] + fn parses_comment_suffixed_numeric_rows_and_ne_profile_fields() { + let report = inspect_imb_bytes( + b"TGAName GP7L_NE\nHorizontalScaleModifier 0.75 ;384/512\nMaxPercentOfInterfaceVRAM 0.09 ;comment\nImageWHScaled 0 0 384 128\nImageWH 56 0 216 32 ;# 1 BigBoy\n", + ) + .expect("imb should parse"); + + assert_eq!(report.horizontal_scale_modifier, Some(0.75)); + assert_eq!(report.max_percent_of_interface_vram, Some(0.09)); + assert_eq!(report.image_rect_scaled, Some([0, 0, 384, 128])); + assert_eq!(report.image_rect, Some([56, 0, 216, 32])); + assert_eq!(report.entries[1].float_values, Some(vec![0.75])); + assert_eq!(report.entries[2].float_values, Some(vec![0.09])); + assert_eq!(report.entries[3].integer_values, Some(vec![0, 0, 384, 128])); + } } diff --git a/docs/rehost-queue.md b/docs/rehost-queue.md index 8b03d60..b8c19db 100644 --- a/docs/rehost-queue.md +++ b/docs/rehost-queue.md @@ -14,6 +14,7 @@ This file is the short active queue for the current runtime and reverse-engineer The repo now has structural inspectors for `.car`, `.lco`, `.cgo`, and `.cct`, but the binary side is still only partially semantic: the checked 1.05 corpus grounds `.car` fixed strings at `0x0c / 0x48 / 0x84` plus a second fixed stem slot at `0xa2` and a side-view resource name at `0xc0`, while `.lco` carries a stable primary stem at `0x04` and only conditional companion/body slots at `0x0c` and `0x12` when the leading stem slot is padded. The checked 1.05 corpus now also splits `.car` auxiliary stems into `126` direct matches, `14` role-neutral roots, and only `5` truly distinct cases, while `.cgo` collapses into five stable scalar ladders instead of arbitrary floats. The early `.lco` lane block is now partially partitioned too: only offsets `0x20`, `0x34`, `0x38`, `0x3c`, `0x44`, `0x48`, and `0x54` behave like low-cardinality buckets, while the other early lanes still look high-variance. + The side-view resource path is now grounded into `Data/2D/rt3_2IMB.PK4`, and the `.imb` parser now decodes shipped comment-suffixed numeric rows plus `_NE` profile fields such as `HorizontalScaleModifier` and `ImageWHScaled`. The next honest static work is to keep promoting those fixed lanes into stable parser fields, explain the five remaining distinct auxiliary-stem cases, and decide how far the `.cgo` ladders plus the low-cardinality `.lco` lanes can be grounded without overclaiming semantics. Preserved checked parser detail now lives in [EngineTypes parser semantics](rehost-queue/engine-types-parser-semantics-2026-04-21.md). Preserved checked format inventory detail now lives in [RT3 format inventory](rehost-queue/format-inventory-2026-04-21.md). diff --git a/docs/rehost-queue/engine-types-parser-semantics-2026-04-21.md b/docs/rehost-queue/engine-types-parser-semantics-2026-04-21.md index 4655b2e..8012bc7 100644 --- a/docs/rehost-queue/engine-types-parser-semantics-2026-04-21.md +++ b/docs/rehost-queue/engine-types-parser-semantics-2026-04-21.md @@ -51,6 +51,12 @@ first `.car` / `.lco` / `.cgo` / `.cct` inspector pass landed. - `7 -> 13 -> 27 -> 53` for `Mail` - `.cct` remains the least ambiguous sidecar: current shipped files still look like narrow one-row text metadata. +- The side-view resource seam is no longer a loose-file dead end: + - `CarSideView_*.imb` lives inside `Data/2D/rt3_2IMB.PK4` + - engine-specific `_NE.imb` profiles such as `2D2L_NE.imb` and `GP7L_NE.imb` live there too + - the `.imb` parser now preserves comment-suffixed numeric rows in those shipped files, so + `MaxPercentOfInterfaceVRAM`, `HorizontalScaleModifier`, `ImageWH`, and `ImageWHScaled` can + all surface as typed fields instead of falling back to raw text ## What The Current Parser Now Owns @@ -73,14 +79,18 @@ first `.car` / `.lco` / `.cgo` / `.cct` inspector pass landed. - scalar ladder counts by shared cargo-car family - `.cct` - tokenized identifier/value row +- `.imb` + - comment-aware typed numeric extraction for shipped profile rows + - `HorizontalScaleModifier` + - `ImageWHScaled` ## Remaining Static Questions - `.car` - what the `0xa2` auxiliary stem really represents in the five remaining distinct cases: alternate content root, paired tender/loco image root, or a narrower foreign-display alias - - whether the trailing side-view resource can be tied cleanly to `.imb` metadata without - inventing frontend semantics + - whether the trailing side-view resource can be tied cleanly to the PK4-backed `CarSideView_*` + metadata and the engine-specific `_NE.imb` profiles without inventing frontend semantics - `.lco` - whether the guarded companion-stem slot is a tender/fallback display family, a foreign reuse key, or only a subset authoring convenience