--- a/xenia-rs/crates/xenia-kernel/src/exports.rs +++ b/xenia-rs/crates/xenia-kernel/src/exports.rs @@ stub_return_zero … fn stub_return_zero(ctx: &mut PpcContext, _mem: &GuestMemory, _state: &mut KernelState) { ctx.gpr[3] = 0; } +/// Phase W: a literal `return 1`. Matches canary's +/// `VdInitializeEngines_entry` in `xboxkrnl_video.cc:271-279` which +/// returns `1` (truthy success token) rather than STATUS_SUCCESS=0. +/// Sylpheed-side guest code branches on this non-zero, so returning +/// 0 made the game skip the VdInitializeRingBuffer-and-after init +/// sequence and never set up the post-init render-target state. +fn stub_return_one(ctx: &mut PpcContext, _mem: &GuestMemory, _state: &mut KernelState) { + ctx.gpr[3] = 1; +} + @@ exports table … - state.register_export(Xboxkrnl, 0x01C2, "VdInitializeEngines", stub_success); + state.register_export(Xboxkrnl, 0x01C2, "VdInitializeEngines", stub_return_one); @@ tests mod … + /// Phase W: ensure `VdInitializeEngines` writes `r3=1` … + #[test] + fn vd_initialize_engines_returns_one() { + let (mut ctx, mem, mut state) = fresh(); + ctx.gpr[3] = 0xDEAD_BEEF; // sentinel — must be overwritten + stub_return_one(&mut ctx, &mem, &mut state); + assert_eq!(ctx.gpr[3], 1, "stub_return_one must put 1 in r3"); + }