Added Support for Multiplayer Player 1 Immersive View

This commit is contained in:
iChris4 committed 2026-09-16 17:06:03 +02:00
1 parent 9e37bb6447
commit 3e8bdcfd7b
22 files changed
+1013 -38

No files matched your search

+3 -2
View File
@@ -147,8 +147,9 @@ extern "C" void GX__CopyTex_8016fd74(uint32_t da, uint32_t c) {
// EFB exactly once, matching Dolphin's ConvertEFBRectangle path.
GXSetTexCopySrc(rawSrcLeft, rawSrcTop, rawSrcWidth, rawSrcHeight);
// EFB copies stay GPU-only except probe-sized ones (e.g. the 4x4 lens-flare depth probe),
// which Aurora reads back asynchronously via efb_ram::schedule and land in guest RAM a frame
// later. RISK: copies above the probe threshold, or on the offscreen list, are not
// which Aurora reads back asynchronously and publishes during the next copy to that buffer.
// GPU callbacks retain pixels in host memory so a scene restart cannot receive a late write
// into a freed/reused allocation. RISK: copies above the probe threshold, or on the offscreen list, are not
// auto-downloaded, so guest reads see stale RAM; call aurora_flush_efb_copies_to_ram if a
// copy needs reading back.
GXCopyTex(GuestToHostPtr(da), (GXBool)c);
+5 -2
View File
@@ -615,8 +615,11 @@ void VI_HLE_PresentFrame(bool presentedXfb, bool paceToRetrace) {
// asynchronous worker may ask for an XR packet after the guest has already
// begun the next frame, so immersive replay is accepted only when both
// tags match.
const uint64_t vrContentTag = mkw::vr::MkwVRPolicyGetSnapshot().content_tag;
aurora_end_frame_tagged(vrContentTag);
const auto vrPolicy = mkw::vr::MkwVRPolicyGetSnapshot();
aurora_set_stereo_local_player_count(
vrPolicy.presentation == mkw::vr::VRPresentationMode::ImmersiveRace
? vrPolicy.scene.local_player_count : 1);
aurora_end_frame_tagged(vrPolicy.content_tag);
if (paceThisFrame) {
PaceToRetraceBoundary(paceDeadline);
std::lock_guard<std::mutex> lock(g_viMutex);
+3 -1
View File
@@ -168,7 +168,9 @@ extern "C" void MkwVRObserveTranslatedFunctionEntry(uint32_t address,
case kRaceCameraUpdate: {
const uint32_t camera_address = context != nullptr ? context->gpr[3] : 0;
ObserveCamera(frame, camera_address);
PublishObservedCamera(frame, camera_address);
if (camera_address == FirstCamera(frame)) {
PublishObservedCamera(frame, camera_address);
}
break;
}
case kScnMgrRaceDraw: {
+10 -3
View File
@@ -86,12 +86,13 @@ VRPresentationMode SelectPresentation(const PolicyState& state) noexcept {
return VRPresentationMode::Desktop;
}
// A virtual screen is the fail-safe for menus, split-screen, and any
// A virtual screen is the fail-safe for menus and any
// incomplete instrumentation. It preserves the unmodified render path.
if ((state.available_bindings & kMkwVRRequiredImmersiveBindings) !=
kMkwVRRequiredImmersiveBindings ||
!state.config.immersive_races || state.scene.mode != VRSceneMode::Race ||
state.scene.local_player_count != 1 || !IsFiniteCamera(state.camera) ||
(state.scene.local_player_count < 1 || state.scene.local_player_count > 4) ||
!IsFiniteCamera(state.camera) ||
!ObservationsAreCoherent(state.scene, state.camera)) {
return VRPresentationMode::VirtualScreen;
}
@@ -111,7 +112,8 @@ VRPresentationMode SelectStablePresentation(const PolicyState& state) noexcept {
if ((state.available_bindings & kMkwVRRequiredImmersiveBindings) !=
kMkwVRRequiredImmersiveBindings ||
!state.config.immersive_races || state.scene.mode != VRSceneMode::Race ||
state.scene.local_player_count != 1 || !IsFiniteCamera(state.camera)) {
(state.scene.local_player_count < 1 || state.scene.local_player_count > 4) ||
!IsFiniteCamera(state.camera)) {
return VRPresentationMode::VirtualScreen;
}
@@ -211,6 +213,11 @@ void MkwVRPolicySetAvailableBindings(uint32_t bindings) noexcept {
void MkwVRPolicyPublishScene(const MkwVRSceneObservation& scene) noexcept {
std::lock_guard<std::mutex> lock(g_policy_mutex);
// A packet for a different split layout must not consume retained content,
// even when both layouts use immersive presentation.
if (scene.local_player_count != g_policy.scene.local_player_count) {
AdvanceSafetyGeneration(g_policy);
}
ApplyPolicyMutation([&] {
if (scene.mode != VRSceneMode::Race || g_policy.scene.mode != VRSceneMode::Race) {
// Never carry a camera sample across a menu/replay-to-race transition.