diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index 1ff14f872e..235b6f739d 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -24,7 +24,7 @@ #include "InputCommon/GCPadStatus.h" // clang-format off -constexpr std::array s_hotkey_labels{{ +constexpr std::array s_hotkey_labels{{ _trans("Open"), _trans("Change Disc"), _trans("Eject Disc"), @@ -127,6 +127,10 @@ constexpr std::array s_hotkey_labels{{ _trans("Freelook Zoom Out"), _trans("Freelook Reset"), _trans("Freelook Toggle"), + _trans("Freelook Increase Field of View X"), + _trans("Freelook Decrease Field of View X"), + _trans("Freelook Increase Field of View Y"), + _trans("Freelook Decrease Field of View Y"), _trans("Toggle 3D Side-by-Side"), _trans("Toggle 3D Top-Bottom"), @@ -334,7 +338,7 @@ constexpr std::array s_groups_info = { {_trans("Controller Profile 4"), HK_NEXT_WIIMOTE_PROFILE_4, HK_PREV_GAME_WIIMOTE_PROFILE_4}, {_trans("Graphics Toggles"), HK_TOGGLE_CROP, HK_TOGGLE_TEXTURES}, {_trans("Internal Resolution"), HK_INCREASE_IR, HK_DECREASE_IR}, - {_trans("Freelook"), HK_FREELOOK_DECREASE_SPEED, HK_FREELOOK_TOGGLE}, + {_trans("Freelook"), HK_FREELOOK_DECREASE_SPEED, HK_FREELOOK_DECREASE_FOV_Y}, // i18n: Stereoscopic 3D {_trans("3D"), HK_TOGGLE_STEREO_SBS, HK_TOGGLE_STEREO_ANAGLYPH}, // i18n: Stereoscopic 3D @@ -469,6 +473,10 @@ void HotkeyManager::LoadDefaults(const ControllerInterface& ciface) set_key_expression(HK_FREELOOK_ZOOM_IN, SHIFT + " & W"); set_key_expression(HK_FREELOOK_ZOOM_OUT, SHIFT + " & S"); set_key_expression(HK_FREELOOK_RESET, SHIFT + " & R"); + set_key_expression(HK_FREELOOK_INCREASE_FOV_X, SHIFT + " & `Axis Z+`"); + set_key_expression(HK_FREELOOK_DECREASE_FOV_X, SHIFT + " & `Axis Z-`"); + set_key_expression(HK_FREELOOK_INCREASE_FOV_Y, SHIFT + " & `Axis Z+`"); + set_key_expression(HK_FREELOOK_DECREASE_FOV_Y, SHIFT + " & `Axis Z-`"); // Savestates const std::string non_fmt = NON + " & `F{}`"; diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h index 1a2216a4f3..68f82e2a87 100644 --- a/Source/Core/Core/HotkeyManager.h +++ b/Source/Core/Core/HotkeyManager.h @@ -111,6 +111,10 @@ enum Hotkey HK_FREELOOK_ZOOM_OUT, HK_FREELOOK_RESET, HK_FREELOOK_TOGGLE, + HK_FREELOOK_INCREASE_FOV_X, + HK_FREELOOK_DECREASE_FOV_X, + HK_FREELOOK_INCREASE_FOV_Y, + HK_FREELOOK_DECREASE_FOV_Y, HK_TOGGLE_STEREO_SBS, HK_TOGGLE_STEREO_TAB, diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 9c01be2d72..873bf823ea 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 118; // Last changed in PR 8813 +constexpr u32 STATE_VERSION = 119; // Last changed in PR 8820 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index e24929f79a..ec87f5a3fd 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -563,6 +563,18 @@ void HotkeyScheduler::Run() if (IsHotkey(HK_FREELOOK_ZOOM_OUT, true)) g_freelook_camera.Zoom(-fl_speed); + if (IsHotkey(HK_FREELOOK_INCREASE_FOV_X, true)) + g_freelook_camera.IncreaseFovX(g_freelook_camera.GetFovStepSize()); + + if (IsHotkey(HK_FREELOOK_DECREASE_FOV_X, true)) + g_freelook_camera.IncreaseFovX(-1.0f * g_freelook_camera.GetFovStepSize()); + + if (IsHotkey(HK_FREELOOK_INCREASE_FOV_Y, true)) + g_freelook_camera.IncreaseFovY(g_freelook_camera.GetFovStepSize()); + + if (IsHotkey(HK_FREELOOK_DECREASE_FOV_Y, true)) + g_freelook_camera.IncreaseFovY(-1.0f * g_freelook_camera.GetFovStepSize()); + if (IsHotkey(HK_FREELOOK_RESET, true)) g_freelook_camera.Reset(); diff --git a/Source/Core/VideoCommon/FreeLookCamera.cpp b/Source/Core/VideoCommon/FreeLookCamera.cpp index 4e49496dfd..3c04962c4e 100644 --- a/Source/Core/VideoCommon/FreeLookCamera.cpp +++ b/Source/Core/VideoCommon/FreeLookCamera.cpp @@ -204,6 +204,11 @@ Common::Matrix44 FreeLookCamera::GetView() return m_camera_controller->GetView(); } +Common::Vec2 FreeLookCamera::GetFieldOfView() const +{ + return Common::Vec2{m_fov_x, m_fov_y}; +} + void FreeLookCamera::MoveVertical(float amt) { m_camera_controller->MoveVertical(amt); @@ -228,9 +233,28 @@ void FreeLookCamera::Rotate(const Common::Vec3& amt) m_dirty = true; } +void FreeLookCamera::IncreaseFovX(float fov) +{ + m_fov_x += fov; + m_fov_x = std::clamp(m_fov_x, m_fov_step_size, m_fov_x); +} + +void FreeLookCamera::IncreaseFovY(float fov) +{ + m_fov_y += fov; + m_fov_y = std::clamp(m_fov_y, m_fov_step_size, m_fov_y); +} + +float FreeLookCamera::GetFovStepSize() const +{ + return m_fov_step_size; +} + void FreeLookCamera::Reset() { m_camera_controller->Reset(); + m_fov_x = 1.0f; + m_fov_y = 1.0f; m_dirty = true; } @@ -239,6 +263,8 @@ void FreeLookCamera::DoState(PointerWrap& p) if (p.mode == PointerWrap::MODE_WRITE || p.mode == PointerWrap::MODE_MEASURE) { p.Do(m_current_type); + p.Do(m_fov_x); + p.Do(m_fov_y); if (m_camera_controller) { m_camera_controller->DoState(p); diff --git a/Source/Core/VideoCommon/FreeLookCamera.h b/Source/Core/VideoCommon/FreeLookCamera.h index aaee69390c..0a35e20972 100644 --- a/Source/Core/VideoCommon/FreeLookCamera.h +++ b/Source/Core/VideoCommon/FreeLookCamera.h @@ -43,6 +43,7 @@ class FreeLookCamera public: void SetControlType(FreelookControlType type); Common::Matrix44 GetView(); + Common::Vec2 GetFieldOfView() const; void MoveVertical(float amt); void MoveHorizontal(float amt); @@ -51,6 +52,10 @@ public: void Rotate(const Common::Vec3& amt); + void IncreaseFovX(float fov); + void IncreaseFovY(float fov); + float GetFovStepSize() const; + void Reset(); void DoState(PointerWrap& p); @@ -60,8 +65,12 @@ public: private: bool m_dirty = false; + float m_fov_x = 1.0f; + float m_fov_y = 1.0f; std::optional m_current_type; std::unique_ptr m_camera_controller; + + float m_fov_step_size = 0.025f; }; extern FreeLookCamera g_freelook_camera; diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 6c65a86efa..8666e7b311 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -355,14 +355,17 @@ void VertexShaderManager::SetConstants() switch (xfmem.projection.type) { case GX_PERSPECTIVE: - g_fProjectionMatrix[0] = rawProjection[0] * g_ActiveConfig.fAspectRatioHackW; + { + const Common::Vec2 fov = + g_ActiveConfig.bFreeLook ? g_freelook_camera.GetFieldOfView() : Common::Vec2{1, 1}; + g_fProjectionMatrix[0] = rawProjection[0] * g_ActiveConfig.fAspectRatioHackW * fov.x; g_fProjectionMatrix[1] = 0.0f; - g_fProjectionMatrix[2] = rawProjection[1] * g_ActiveConfig.fAspectRatioHackW; + g_fProjectionMatrix[2] = rawProjection[1] * g_ActiveConfig.fAspectRatioHackW * fov.x; g_fProjectionMatrix[3] = 0.0f; g_fProjectionMatrix[4] = 0.0f; - g_fProjectionMatrix[5] = rawProjection[2] * g_ActiveConfig.fAspectRatioHackH; - g_fProjectionMatrix[6] = rawProjection[3] * g_ActiveConfig.fAspectRatioHackH; + g_fProjectionMatrix[5] = rawProjection[2] * g_ActiveConfig.fAspectRatioHackH * fov.y; + g_fProjectionMatrix[6] = rawProjection[3] * g_ActiveConfig.fAspectRatioHackH * fov.y; g_fProjectionMatrix[7] = 0.0f; g_fProjectionMatrix[8] = 0.0f; @@ -377,9 +380,11 @@ void VertexShaderManager::SetConstants() g_fProjectionMatrix[15] = 0.0f; g_stats.gproj = g_fProjectionMatrix; - break; + } + break; case GX_ORTHOGRAPHIC: + { g_fProjectionMatrix[0] = rawProjection[0]; g_fProjectionMatrix[1] = 0.0f; g_fProjectionMatrix[2] = 0.0f; @@ -403,7 +408,8 @@ void VertexShaderManager::SetConstants() g_stats.g2proj = g_fProjectionMatrix; g_stats.proj = rawProjection; - break; + } + break; default: ERROR_LOG(VIDEO, "Unknown projection type: %d", xfmem.projection.type);