diff --git a/docs/internal/upstream/pr13-shaded-polyline-terminator.md b/docs/internal/upstream/pr13-shaded-polyline-terminator.md new file mode 100644 index 000000000..54ea49a80 --- /dev/null +++ b/docs/internal/upstream/pr13-shaded-polyline-terminator.md @@ -0,0 +1,9 @@ +# PR #13 shaded-polyline terminator provenance + +Parked from NyperYuhgard's PSXrecomp PR #13, commit +[`2ba52e9754d672fb5efdb6f8cba49c82f27a8734`](https://github.com/mstan/psxrecomp/commit/2ba52e9754d672fb5efdb6f8cba49c82f27a8734). + +The GP0 shaded-polyline terminator is checked before alternating color/vertex +decoding, so the hardware terminator is accepted in either stream position. All +other GPU, DMA, CD-ROM, MDEC, and SPU changes from the mixed upstream commit are +intentionally excluded from this focused branch. diff --git a/runtime/src/gpu.c b/runtime/src/gpu.c index f9bcacaca..88e119ef1 100644 --- a/runtime/src/gpu.c +++ b/runtime/src/gpu.c @@ -3584,6 +3584,14 @@ static void gpu_write_gp0_body(uint32_t val) { /* State: shaded polyline — alternating color, vertex words */ if (gp0_state == GP0_POLYLINE_SHADED) { + /* The terminator can arrive in either the color or vertex position. + * Check it before interpreting the alternating shaded-polyline stream; + * otherwise a vertex-position terminator is consumed as coordinates and + * de-phases all following GP0 commands. */ + if ((val & 0xF000F000u) == 0x50005000u) { + gp0_state = GP0_IDLE; + return; + } /* Even words (after cmd) are colors, odd words are vertices. * Sequence: [cmd+C0] [V0] [C1] [V1] [C2] [V2] ... * polyline_has_prev tracks: 0=need V0, 1=need C_next, 2=need V_next */ @@ -3598,12 +3606,7 @@ static void gpu_write_gp0_body(uint32_t val) { return; } if (polyline_has_prev == 1) { - /* Expecting color word (or terminator). Same hardware rule as the - * mono case: ONLY the masked 0x50005000 pattern terminates. */ - if ((val & 0xF000F000u) == 0x50005000u) { - gp0_state = GP0_IDLE; - return; - } + /* Expecting color word. */ polyline_color = rgb888_to_rgb555(val & 0xFFFFFFu); polyline_has_prev = 2; return;