Files
mitch030504--Wiicompiled_VR…/runtime/include/vr/mkw_vr_policy.h
T

190 lines
7.0 KiB
C++

// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <array>
#include <cstddef>
#include <cstdint>
namespace mkw::vr {
// Game-facing presentation policy. The OpenXR implementation owns session and
// swapchain state; this module only decides how Mario Kart Wii content should
// be presented once the integration layer publishes game observations.
enum class VRPresentationMode : uint8_t {
Desktop,
VirtualScreen,
ImmersiveRace,
};
enum class VRSceneMode : uint8_t {
Unknown,
FrontEnd,
Race,
Replay,
Awards,
Other,
};
enum class VRProjectionKind : uint8_t {
Unknown,
Perspective,
Orthographic,
};
enum class VRDrawPass : uint8_t {
Scene,
PostProcess,
};
enum class VRDrawClass : uint8_t {
Unknown,
PerspectiveWorld,
OrthographicHud,
PostProcess,
};
enum class VRDrawRoute : uint8_t {
DesktopPassthrough,
VirtualScreen,
StereoWorld,
HeadLockedHud,
PerEyePostProcess,
Unclassified,
};
// Instrumentation capabilities are explicit so a partial binding can never
// accidentally enable immersive rendering. In particular, a camera sample by
// itself is insufficient because orthographic UI would otherwise be rendered
// with the stereo world path.
enum MkwVRBinding : uint32_t {
MkwVRBindingNone = 0,
MkwVRBindingSceneState = 1u << 0,
MkwVRBindingRaceCamera = 1u << 1,
MkwVRBindingDrawClassification = 1u << 2,
MkwVRBindingPostProcess = 1u << 3,
MkwVRBindingCulling = 1u << 4,
};
inline constexpr uint32_t kMkwVRRequiredImmersiveBindings =
MkwVRBindingSceneState | MkwVRBindingRaceCamera | MkwVRBindingDrawClassification;
struct MkwVRPolicyConfig {
bool enabled = false;
// False is Flat Screen mode: races stay on the virtual screen the menus use.
bool immersive_races = true;
float world_units_per_meter = 500.0f;
float hud_distance_meters = 2.0f;
// Width of the virtual screen, shared by the menu quad layer and the
// immersive race HUD so 2D content keeps its place across the transition.
float hud_width_meters = 2.4f;
float hud_scale = 1.0f;
// World scale used while the first-person camera is engaged. This is what
// makes the race read life-size from the driver's seat; the third-person
// default deliberately does not, presenting it as a small diorama instead.
// Kept in step with RuntimeConfigFile's default, which the F10 bar resets to.
float first_person_units_per_meter = 30.0f;
};
struct MkwVRSceneObservation {
VRSceneMode mode = VRSceneMode::Unknown;
uint32_t local_player_count = 0;
uint64_t guest_frame_index = 0;
};
struct MkwVRCameraObservation {
// Mario Kart and NW4R expose affine view matrices as row-major 3x4 Mtx
// values. The integration layer is responsible for reading/converting the
// guest value; this policy never assumes a guest object layout.
std::array<float, 12> view_from_world{};
uint32_t guest_camera_address = 0;
uint64_t guest_frame_index = 0;
bool valid = false;
};
struct MkwVRDrawObservation {
VRProjectionKind projection = VRProjectionKind::Unknown;
VRDrawPass pass = VRDrawPass::Scene;
};
struct MkwVRPolicySnapshot {
VRPresentationMode presentation = VRPresentationMode::Desktop;
MkwVRPolicyConfig config{};
MkwVRSceneObservation scene{};
MkwVRCameraObservation camera{};
uint32_t available_bindings = MkwVRBindingNone;
bool session_active = false;
// A first-person camera is actually driving the view this frame. Set by the
// integration layer once the anchor it publishes to the renderer is valid,
// so the world scale can never disagree with where the camera is.
bool first_person_engaged = false;
// Changes whenever the stable presentation-safety state changes. Ordinary
// per-frame scene/camera publication does not advance it.
uint64_t safety_generation = 1;
// Opaque safety-state tag for the content being sealed. This also includes
// the current presentation mode, so a transient scene/camera mismatch
// cannot accept an immersive packet from an adjacent asynchronous frame.
uint64_t content_tag = 0;
// The scale headset translation and IPD are converted at. Head offsets in
// metres must use the same value, or the camera and the world disagree.
float EffectiveUnitsPerMeter() const noexcept {
return first_person_engaged ? config.first_person_units_per_meter
: config.world_units_per_meter;
}
};
// All policy functions are thread-safe. Publishing functions are intended for
// translated-game instrumentation on the guest thread; the renderer may take a
// snapshot without retaining references to mutable policy state.
void MkwVRPolicyReset() noexcept;
void MkwVRPolicyConfigure(const MkwVRPolicyConfig& config) noexcept;
void MkwVRPolicySetSessionActive(bool active) noexcept;
void MkwVRPolicySetAvailableBindings(uint32_t bindings) noexcept;
void MkwVRPolicyPublishScene(const MkwVRSceneObservation& scene) noexcept;
void MkwVRPolicyPublishRaceCamera(const MkwVRCameraObservation& camera) noexcept;
void MkwVRPolicyInvalidateRaceCamera() noexcept;
// Reported by the integration layer each time the first-person anchor engages
// or disengages. It selects the world scale and nothing else: presentation
// safety is unaffected, so this never advances the safety generation.
void MkwVRPolicySetFirstPersonEngaged(bool engaged) noexcept;
// Live world scale for the first-person camera. Separate from
// MkwVRPolicyConfigure so the F10 slider can retune it during a race without
// republishing (and revalidating) the whole configuration.
void MkwVRPolicySetFirstPersonUnitsPerMeter(float units_per_meter) noexcept;
// Flat Screen mode, live from the F10 menu. Unlike the scale above this changes
// which content is safe to present, so it advances the safety generation.
void MkwVRPolicySetImmersiveRaces(bool enabled) noexcept;
MkwVRPolicySnapshot MkwVRPolicyGetSnapshot() noexcept;
// This classifier is deliberately structural rather than heuristic: future
// hooks report whether the active projection is perspective/orthographic and
// whether execution is inside a post-processing boundary. No matrix-value or
// guest-address guessing occurs here.
VRDrawClass MkwVRPolicyClassifyDraw(const MkwVRDrawObservation& draw) noexcept;
VRDrawRoute MkwVRPolicyRouteDraw(VRDrawClass draw_class,
const MkwVRPolicySnapshot& snapshot) noexcept;
enum class MkwVRHookCapability : uint8_t {
SceneState,
RaceCamera,
DrawClassification,
PostProcess,
Culling,
};
// Validated PAL RMCP01 symbols from projects/mkwii/MAP.txt. These are future
// instrumentation candidates, not registered native replacements: the current
// PPC_NATIVE_OVERRIDE mechanism replaces a translated function outright and
// cannot safely observe it before/after its original body.
struct MkwVRHookPoint {
uint32_t address;
const char* symbol;
MkwVRHookCapability capability;
const char* purpose;
};
const MkwVRHookPoint* MkwVRPolicyHookPoints(std::size_t* count) noexcept;
} // namespace mkw::vr