Skip to content

feat: full runtime implementation + Lua-driven UI#16

Merged
KaiserGranatapfel merged 1 commit intomainfrom
feature/full-runtime-implementation
Feb 10, 2026
Merged

feat: full runtime implementation + Lua-driven UI#16
KaiserGranatapfel merged 1 commit intomainfrom
feature/full-runtime-implementation

Conversation

@KaiserGranatapfel
Copy link
Owner

@KaiserGranatapfel KaiserGranatapfel commented Feb 10, 2026

Summary

  • Replace all SDK logging stubs with functional OS/SDK runtime (heap allocator, timers, interrupts, SDK dispatch)
  • Implement GX graphics engine — full state machine, vertex accumulation, dynamic TEV→WGSL shader generation, wgpu pipeline caching, EFB rendering at native 640×480 with upscaling
  • Add video interface (NTSC/PAL modes, VBlank timing, retrace callbacks) and audio system (AI DMA, DSP-ADPCM 64-voice decoder, stereo mixer, cpal output)
  • Move all UI to Lua — 14 widget types, 7 screen definitions (main menu, FPS, graphics, audio, controller config, game settings), callback registry, full Iced rendering
  • Rewrite game boot loop for winit 0.30 ApplicationHandler with ESC menu toggle, SDK init sequence, CPU context setup
  • Fix 8 bugs: CMPR/DXT1 decoder, all texture tile layouts, LRU cache, memory mapper overlaps, DMA byte copying, controller profile serialization
  • Resolve all clippy warnings (70+) across entire workspace; bump MSRV to 1.80

94 files changed, +8254 / -2772 lines across all 7 workspace crates + Lua UI definitions.

Test plan

  • cargo build --workspace compiles cleanly
  • cargo clippy --all-targets --all-features -- -D warnings — zero warnings
  • cargo test --all --lib --bins — 34 tests pass (3 core + 31 runtime)
  • cargo fmt --all -- --check — clean
  • Manual test: run game binary, verify window opens and Lua UI screens render
  • Manual test: feed a real DOL through the pipeline and verify SDK calls route to native implementations

Note

Medium Risk
Moderate risk: replaces the game binary entrypoint with a real event loop and runtime initialization (graphics/audio/update), which can introduce startup and platform-specific windowing issues; other changes are mostly MSRV/dependency updates and clippy-driven refactors.

Overview
Replaces the placeholder game entrypoint with a full runtime bootstrap. The new GameApp runs a winit ApplicationHandler loop, initializes the SDK/CPU context, creates a window, brings up gcrecomp-runtime graphics (and optional audio), handles resize/redraw, and toggles a menu flag on Esc.

Adds startup Lua loading for UI and game scripts (lua/ui/init.lua, lua/game/init.lua) plus logging via env_logger, and updates game dependencies accordingly.

Maintenance/clippy cleanup and toolchain bump: raises clippy MSRV to Rust 1.80, marks unused CLI/output helpers and codegen fields as underscore-prefixed, and applies small refactors/formatting in recompiler analysis/codegen to keep builds warning-free.

Written by Cursor Bugbot for commit b2190e8. This will update automatically on new commits. Configure here.

…, and Lua-driven UI

Replace all SDK logging stubs with functional implementations so recompiled
GameCube binaries can actually boot and run.

OS/SDK Foundation:
- Arena heap allocator (lo/hi cursors in GC address space)
- Timebase timer (40.5 MHz), interrupt system (32 slots)
- OSInit, OSReport, OSFatal and SDK dispatch routing

GX Graphics Engine:
- Full GX state machine (21 vertex attrs, 16 TEV stages, matrices,
  blend/Z/cull/scissor/viewport, lighting channels)
- Vertex accumulator with GXBegin/GXEnd and auto-flush draw lists
- Dynamic WGSL fragment shader generation from TEV configuration
- wgpu render pipeline cache keyed on GX state hash
- EFB at native 640x480 with depth buffer and upscaling

Video Interface:
- NTSC/PAL mode support, VBlank timing, retrace callbacks

Audio System:
- Audio Interface with DMA, Nintendo DSP-ADPCM decoder (64 voices)
- Stereo mixer with resampling, cpal output thread

Lua-Driven UI:
- Expanded widget system (14 types with callbacks, styles, children)
- 7 Lua screen definitions (main menu, FPS, graphics, audio,
  controller config, game settings)
- Callback registry with thread-safe string-based function lookup
- Full Iced rendering of all Lua widget types

Game Boot Loop:
- winit 0.30 ApplicationHandler with window creation and ESC menu toggle
- SDK init sequence, CPU context setup, DOL section loading

Bug Fixes:
- CMPR/DXT1 texture decoder with correct 8x8 macro-tile Z-order layout
- All 8 texture formats now use correct GC tile-based iteration
- LRU texture cache with proper VecDeque access-order tracking
- Memory mapper: removed ARAM overlap, added uncached mirror and HW regs
- DMA execute_transfer with actual RAM/ARAM byte copying
- Controller profile round-trip serialization with typed structs
- Resolved all clippy warnings across entire workspace (70+)
- Bumped MSRV to 1.80 (LazyLock usage)
@KaiserGranatapfel KaiserGranatapfel merged commit f7314f7 into main Feb 10, 2026
2 of 13 checks passed
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on March 31

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

}
WindowEvent::Resized(size) => {
if let Some(renderer) = runtime.renderer_mut() {
renderer.resize(size.width, size.height);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing zero-size guard causes wgpu panic on minimize

High Severity

The WindowEvent::Resized handler passes size.width and size.height directly to renderer.resize(), which sets them on the wgpu SurfaceConfiguration and calls surface.configure(). wgpu requires non-zero dimensions — when the window is minimized (common on Windows), winit delivers a Resized event with (0, 0), causing a panic inside wgpu. A guard like if size.width > 0 && size.height > 0 is needed before calling resize.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant