Phases 3–7: Complete GPU menu rendering pipeline#99
Merged
Conversation
…prite in frontend
The frontend_on check was too broad — it prevented all UpdateSDLWindow calls during the frontend, including splash screens that still use the palette-based rendering path.
- Move GPU texture loading after setpal("frontend.pal") so textures
are baked with the correct palette
- Add bounds check in menu_render_load_blocks to prevent raw pixel
data from being misidentified as block headers (integer overflow)
- Replace main menu fade_palette calls with GPU fade system using
fade_redraw_bg callback for visible fade transitions
- Add fade_redraw_bg static callback that redraws the background
during fade animations
…l discard in menu pixel shader
…Y/N prompt visibility
Convert car model coordinates from game's Z-up system to GPU's Y-up system, fix camera orbit to match original DrawCar view transform, apply Car[0].nYaw as model rotation for spinning car preview, and use stable palette[] array instead of pal_addr for texture atlas to fix blue-on-first-load color bug.
…per-segment approach with height-based coloring
Re-introduce menu_render.c/h as a thin routing layer that dispatches to either the GPU or software backend. Restores the original public API so frontend.c and roller.c compile without changes. Mode switching is deferred to the next begin_frame call via pendingMode.
F11 is captured by macOS for Show Desktop.
Set g_bPaletteSet before UpdateSDLWindow() in the software end_frame so the presentation path isn't skipped. The GPU menu path never calls fade_palette(), so the flag stayed false after setpal() cleared it. Forward asset load/free operations to both backends regardless of active mode, so switching mid-session doesn't leave stale GPU textures.
The GPU fade path uses alpha overlays and never updates pal_addr, leaving it zeroed after fade-out. Restore from the base palette[] array on mode switch so UpdateSDLWindow() has correct colors.
The original code used DrawCar(scrbuf + 34640, ...) for positioning (buffer offset = row 54, col 80) and never modified xbase/ybase. show_3dmap() also relied on xbase/ybase being set by init_screen(). The software backend was incorrectly overriding xbase/ybase with the GPU viewport coordinates and passing plain scrbuf.
Negate the yaw angle to match the original DrawCar rotation convention. The column-major model matrix was producing the opposite rotation direction.
Fix camera position to match original show_3dmap: camera at (-dist*cos(elev), 0, dist*sin(elev)) in game coords, mapped to GPU Y-up space with negative Z forward. Negate yaw to match original convention where yaw rotates the track vertices (camera orbit is the inverse). Replace hardcoded 0.8 radian FOV with VIEWDIST-derived value matching the car preview.
… before palette animation
…ing in MVP projection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phases 3–7 of the menu GPU rendering migration. Phase 2 was already merged to master; phases 3–7 were stacked PRs (#94–#98) that merged into each other's branches instead of cascading to master. This PR brings all remaining work into master.
menu_render_text,menu_render_scaled_text)Plan
docs/plans/2026-03-17-menu-gpu-rendering.md(phases 2–6)docs/plans/2026-03-19-menu-render-mode-switching.md(phase 7)