diff --git a/docs/dev/findings.md b/docs/dev/findings.md index 5e51552b..2cc93ef6 100644 --- a/docs/dev/findings.md +++ b/docs/dev/findings.md @@ -11624,6 +11624,8 @@ User vs 1964: PC water jittered with player movement, "reset" even standing stil Ruled out on the way: the animation phases advance by `g_ClockTimer` (rate-independent); `PRIM_LOD_FRAC` and per-tile `uls/ult` offsets are handled by fast3d; `WrapFix` pre-wrap is off by default. A/B switches kept: `GE_D245_OLDVTX=1`, `GE_D245_OLDTEX=1`. Golden gate 3/3; Windows + Linux builds clean. +**Follow-up (2026-09-27): coloured dashes.** User playtest found rows of yellow/green/magenta dashes on Frigate's water, looking down near the horizon. The base-level crop in fix 1 had never run: its test used `loaded_texture.line_size_bytes`, which for a LoadBlock is the whole 1400-byte block, so the upload stayed 32x43 while the tri path normalised V by 32. The mip-chain rows (32-42) were sampled as garbage texels. Crop test now uses the tile's line size (the importer's row width): the dumped import is a clean 32x32 tile (indices 0-23). User-verified, golden gate 3/3. + **Status: FIXED (M-201, user-verified vs 1964, 2026-09-26).** ## D246 — Tiny pixel strips at the left and right edges of the screen, "like overscan" — look like raw pixels, not 3D graphics (M-116, user QA report). diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 3b0968b0..5d7e83b1 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -1375,11 +1375,15 @@ static void import_texture(int i, int tile, bool importReplacement) { static int d245_oldtex = -1; if (d245_oldtex < 0) d245_oldtex = getenv("GE_D245_OLDTEX") != NULL; const uint8_t maskt = rdp.texture_tile[tile].maskt; + /* Crop by the TILE line size (the importer's row width): for a + * LoadBlock, loaded_texture.line_size_bytes is the whole block, so + * testing against it never cropped (M-201 follow-up: the mip rows + * then showed as coloured dashes on Frigate's water). */ + const uint32_t d245_row = rdp.texture_tile[tile].line_size_bytes; if (!d245_oldtex && fmt == G_IM_FMT_RGBA && siz == G_IM_SIZ_16b && maskt > 0 && maskt < 12 && - loaded_texture.line_size_bytes > 0 && - loaded_texture.size_bytes > loaded_texture.line_size_bytes * (1u << maskt)) { + d245_row > 0 && loaded_texture.size_bytes > d245_row * (1u << maskt)) { LoadedTexture lt = loaded_texture; - lt.size_bytes = loaded_texture.line_size_bytes * (1u << maskt); + lt.size_bytes = d245_row * (1u << maskt); import_texture_ci8(tile, lt, rdp.tex_lod); } else { import_texture_ci8(tile, loaded_texture, rdp.tex_lod);