diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt index 42ceb3548..8f5c8a369 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt @@ -14,8 +14,7 @@ enum class BooleanSetting( PLUGIN_LOADER("plugin_loader", Settings.SECTION_SYSTEM, false), ALLOW_PLUGIN_LOADER("allow_plugin_loader", Settings.SECTION_SYSTEM, true), SWAP_SCREEN("swap_screen", Settings.SECTION_LAYOUT, false), - VR_EXTRA_PERFORMANCE_MODE("vr_extra_performance_mode", Settings.SECTION_VR, false), - VR_IMMERSIVE_MODE("vr_immersive_mode", Settings.SECTION_VR, false); + VR_EXTRA_PERFORMANCE_MODE("vr_extra_performance_mode", Settings.SECTION_VR, false); override var boolean: Boolean = defaultValue diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt index 64f3419c8..7e375107e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt @@ -47,7 +47,11 @@ enum class IntSetting( USE_FRAME_LIMIT("use_frame_limit", Settings.SECTION_RENDERER, 1), VR_ENVIRONMENT("vr_environment", Settings.SECTION_VR, if (hMDType == VRUtils.HMDType.QUEST3.value) 1 else 2), - VR_CPU_LEVEL("vr_cpu_level", Settings.SECTION_VR, 3); + VR_CPU_LEVEL("vr_cpu_level", Settings.SECTION_VR, 3), + VR_IMMERSIVE_MODE("vr_immersive_mode", Settings.SECTION_VR, 0), + VR_IMMERSIVE_POSITIONAL_FACTOR("vr_immersive_positional_factor", Settings.SECTION_VR, 0), + VR_IMMERSIVE_POSITIONAL_GAME_SCALER("vr_immersive_positional_game_scaler", Settings.SECTION_VR, 0), + VR_SI_MODE_REGISTER_OFFSET("vr_si_mode_register_offset", Settings.SECTION_VR, 0); override var int: Int = defaultValue diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt index c627d4179..2d08e99dc 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -759,7 +759,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.string.factor3d, R.string.factor3d_description, 0, - 100, + 400, "%", IntSetting.STEREOSCOPIC_3D_DEPTH.key, IntSetting.STEREOSCOPIC_3D_DEPTH.defaultValue.toFloat() @@ -1111,13 +1111,53 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) IntSetting.NEW_3DS.defaultValue ) ) + + add(HeaderSetting(R.string.immersive_mode)) + add( - SwitchSetting( - BooleanSetting.VR_IMMERSIVE_MODE, + SingleChoiceSetting( + IntSetting.VR_IMMERSIVE_MODE, R.string.vr_immersive_mode_title, R.string.vr_immersive_mode_description, - BooleanSetting.VR_IMMERSIVE_MODE.key, - BooleanSetting.VR_IMMERSIVE_MODE.defaultValue + R.array.vrImmersiveModeNames, + R.array.vrImmersiveModeValues, + IntSetting.VR_IMMERSIVE_MODE.key, + IntSetting.VR_IMMERSIVE_MODE.defaultValue + ) + ) + add( + SliderSetting( + IntSetting.VR_IMMERSIVE_POSITIONAL_FACTOR, + R.string.vr_immersive_pos_factor_title, + R.string.vr_immersive_pos_factor_description, + 0, + 40, + "x", + IntSetting.VR_IMMERSIVE_POSITIONAL_FACTOR.key, + IntSetting.VR_IMMERSIVE_POSITIONAL_FACTOR.defaultValue.toFloat() + ) + ) + add( + SingleChoiceSetting( + IntSetting.VR_IMMERSIVE_POSITIONAL_GAME_SCALER, + R.string.vr_immersive_pos_game_scaler_title, + R.string.vr_immersive_pos_game_scaler_description, + R.array.vrPosFactorGameScalerNames, + R.array.vrPosFactorGameScalerValues, + IntSetting.VR_IMMERSIVE_POSITIONAL_GAME_SCALER.key, + IntSetting.VR_IMMERSIVE_POSITIONAL_GAME_SCALER.defaultValue + ) + ) + add( + SliderSetting( + IntSetting.VR_SI_MODE_REGISTER_OFFSET, + R.string.vr_si_mode_register_offset_title, + R.string.vr_si_mode_register_offset_description, + 0, + 92, + "register", + IntSetting.VR_SI_MODE_REGISTER_OFFSET.key, + IntSetting.VR_SI_MODE_REGISTER_OFFSET.defaultValue.toFloat() ) ) } diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index c191140ea..71549cec4 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -305,8 +305,6 @@ void Config::ReadValues() { // no point rendering passthrough in immersive mode VRSettings::values.vr_environment = static_cast(VRSettings::VREnvironmentType::VOID); - // When immersive mode is enabled, only OpenGL is supported. - Settings::values.graphics_api = Settings::GraphicsAPI::OpenGL; } // Miscellaneous diff --git a/src/android/app/src/main/jni/vr/layers/GameSurfaceLayer.cpp b/src/android/app/src/main/jni/vr/layers/GameSurfaceLayer.cpp index d2afa9f51..eb80f9107 100644 --- a/src/android/app/src/main/jni/vr/layers/GameSurfaceLayer.cpp +++ b/src/android/app/src/main/jni/vr/layers/GameSurfaceLayer.cpp @@ -264,35 +264,6 @@ void GameSurfaceLayer::Frame(const XrSpace& space, std::vector(2 * panelWidth) / static_cast(panelHeight); - /* - * This bit is entirely optional, rather than having the panel appear/disappear it emerge in - * smoothly, however to achieve it I had to make the scale factor mutable, which I appreciate - * might not be following the intention of this class. - * If a mutable class member isn't desired, then just drop this bit and use the visibleLowerPanel - * variable directly. - */ - const auto panelZoomSpeed = 0.15f; - if (showLowerPanel && lowerPanelScaleFactor < defaultLowerPanelScaleFactor) - { - if (lowerPanelScaleFactor == 0.0f) - { - lowerPanelScaleFactor = panelZoomSpeed; - } - else - { - lowerPanelScaleFactor *= 1.0f + panelZoomSpeed; - lowerPanelScaleFactor = std::min(lowerPanelScaleFactor, defaultLowerPanelScaleFactor); - } - } - else if (!showLowerPanel && lowerPanelScaleFactor > 0.0f) - { - lowerPanelScaleFactor /= 1.0f + panelZoomSpeed; - if (lowerPanelScaleFactor < panelZoomSpeed) - { - lowerPanelScaleFactor = 0.0f; - } - } - // Prevent a seam between the top and bottom view constexpr uint32_t verticalBorderTex = 1; const bool useCylinder = (GetCylinderSysprop() != 0) || (mImmersiveMode > 0); @@ -380,7 +351,7 @@ void GameSurfaceLayer::Frame(const XrSpace& space, std::vector 0.0f) + if (showLowerPanel) { const uint32_t cropHoriz = 90 * mResolutionFactor; XrCompositionLayerQuad layer = {}; @@ -408,9 +379,9 @@ void GameSurfaceLayer::Frame(const XrSpace& space, std::vector gOnCreateStartTime; std::unique_ptr gOpenXr; MessageQueue gMessageQueue; -const std::vector immersiveScaleFactor = {1.0f, 5.0f, 3.0f, 1.8f}; +const std::vector immersiveScaleFactor = {1.0f, 3.0f, 1.8f}; void ForwardButtonStateChangeToCitra(JNIEnv* jni, jobject activityObject, jmethodID forwardVRInputMethodID, const int androidButtonCode, @@ -537,15 +537,16 @@ private: } bool showLowerPanel = true; - float immersiveModeFactor = (VRSettings::values.vr_immersive_mode <= 2) ? immersiveScaleFactor[VRSettings::values.vr_immersive_mode] : immersiveScaleFactor[3]; + float immersiveModeFactor = (VRSettings::values.vr_immersive_mode < 2) ? immersiveScaleFactor[VRSettings::values.vr_immersive_mode] : immersiveScaleFactor[2]; // Push the HMD position through to the Rasterizer to pass on to the VS Uniform - if (Core::System::GetInstance().GPU().Renderer().Rasterizer()) + if (Core::System::GetInstance().IsPoweredOn() && + Core::System::GetInstance().GPU().Renderer().Rasterizer()) { - if ((VRSettings::values.vr_immersive_positional_factor == 0) || - //If in Normal immersive modes then look down for the lower panel to reveal itself (for some reason the Roll function returns pitch) - (VRSettings::values.vr_immersive_mode <= 2 && XrMath::Quatf::GetRollInRadians(gOpenXr->headLocation.pose.orientation) < -MATH_FLOAT_PI / 8.0f) || + if (VRSettings::values.vr_immersive_mode == 0 || + //If in normal immersive mode then look down for the lower panel to reveal itself (for some reason the Roll function returns pitch) + (VRSettings::values.vr_immersive_mode == 1 && XrMath::Quatf::GetRollInRadians(gOpenXr->headLocation.pose.orientation) < -MATH_FLOAT_PI / 8.0f) || //If in "super immersive" mode then put controller next to head in order to disable the mode temporarily - (VRSettings::values.vr_immersive_mode >= 3 && length < 0.2)) + (VRSettings::values.vr_immersive_mode > 2 && length < 0.2)) { XrVector4f identity[4] = {}; XrMath::Matrixf::Identity(identity); @@ -564,10 +565,10 @@ private: XrQuaternionf invertedOrientation = XrMath::Quatf::Inverted(gOpenXr->headLocation.pose.orientation); XrVector3f position = XrMath::Quatf::Rotate(invertedOrientation, gOpenXr->headLocation.pose.position); - float posScaler = powf(10.f, VRSettings::values.vr_immersive_positional_game_scaler); - inv_transform[3].x = -position.x * VRSettings::values.vr_immersive_positional_factor * posScaler; - inv_transform[3].y = -position.y * VRSettings::values.vr_immersive_positional_factor * posScaler; - inv_transform[3].z = -position.z * VRSettings::values.vr_immersive_positional_factor * posScaler; + float gamePosScaler = powf(10.f, VRSettings::values.vr_immersive_positional_game_scaler); + inv_transform[3].x = -position.x * VRSettings::values.vr_immersive_positional_factor * gamePosScaler; + inv_transform[3].y = -position.y * VRSettings::values.vr_immersive_positional_factor * gamePosScaler; + inv_transform[3].z = -position.z * VRSettings::values.vr_immersive_positional_factor * gamePosScaler; Core::System::GetInstance().GPU().Renderer().Rasterizer()->SetVRData(VRSettings::values.vr_immersive_mode, immersiveModeFactor, uoffset, (float*)inv_transform); showLowerPanel = false; diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 0a7312232..16f9e5adf 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -471,8 +471,7 @@ Off - Large - Low Resolution - Higher Resolution + 180 Degree Immersive Super Immersive - Profile 1 Super Immersive - Profile 2 (Set Register Offset for game) @@ -482,7 +481,6 @@ 1 2 3 - 4 diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index 3c67b078a..45fa9e16e 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp @@ -909,14 +909,14 @@ void RasterizerAccelerated::ApplyVRDataToPicaVSUniforms(Pica::Shader::Generator: switch (mode) { //OOT / MM specific - case 3: + case 2: if (vs_uniforms.uniforms.bools[1].b != 0 // this is essential && f[0][3] != 1.0) // This fixes the HUD { viewMatrixIndex = 4; } break; - case 4: + case 3: viewMatrixIndex = Settings::values.vr_si_mode_register_offset.GetValue(); break; case 9: @@ -930,7 +930,7 @@ void RasterizerAccelerated::ApplyVRDataToPicaVSUniforms(Pica::Shader::Generator: if (viewMatrixIndex != -1 && vs_uniforms.uniforms.f.size() > viewMatrixIndex) { - if (matrixMode == 3) + if (matrixMode == 2) { f[viewMatrixIndex][0] = vr_view[0]; f[viewMatrixIndex][1] = vr_view[4]; @@ -942,7 +942,7 @@ void RasterizerAccelerated::ApplyVRDataToPicaVSUniforms(Pica::Shader::Generator: f[viewMatrixIndex + 2][1] = vr_view[6]; f[viewMatrixIndex + 2][2] = vr_view[10]; } - else if (matrixMode >= 4) + else if (matrixMode >= 3) { float v[16], v2[16], v3[16]; MatrixTranspose(v, &f[viewMatrixIndex].x); diff --git a/src/video_core/shader/generator/glsl_shader_gen.cpp b/src/video_core/shader/generator/glsl_shader_gen.cpp index 114176f4c..712db4f62 100644 --- a/src/video_core/shader/generator/glsl_shader_gen.cpp +++ b/src/video_core/shader/generator/glsl_shader_gen.cpp @@ -39,6 +39,7 @@ layout (binding = 1, std140) uniform vs_data { #endif bool enable_clip1; vec4 clip_coef; + float vr_immersive_mode_factor; }; const vec2 EPSILON_Z = vec2(0.000001f, -1.00001f); diff --git a/src/video_core/shader/generator/shader_gen.h b/src/video_core/shader/generator/shader_gen.h index cd376ebcd..02a9ca33c 100644 --- a/src/video_core/shader/generator/shader_gen.h +++ b/src/video_core/shader/generator/shader_gen.h @@ -58,8 +58,6 @@ struct PicaGSConfigState { // semantic_maps[semantic name] -> GS output attribute index + component index std::array semantic_maps; - - bool use_vr_immersive_mode; }; /**