Compare commits
	
		
			5 Commits
		
	
	
		
			i-hate-cli
			...
			3d-stuff
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 4505760ec7 | ||
|  | 651663e5f7 | ||
|  | a9e5e59d9a | ||
|  | 96c375229b | ||
|  | ea928374a6 | 
| @@ -143,7 +143,7 @@ void Config::ReadValues() { | ||||
|     ReadSetting("Renderer", Settings::values.use_vsync_new); | ||||
|     ReadSetting("Renderer", Settings::values.texture_filter); | ||||
|  | ||||
|     ReadSetting("Renderer", Settings::values.mono_render_option); | ||||
|     ReadSetting("Renderer", Settings::values.swap_eyes); | ||||
|     ReadSetting("Renderer", Settings::values.render_3d); | ||||
|     ReadSetting("Renderer", Settings::values.factor_3d); | ||||
|     ReadSetting("Renderer", Settings::values.pp_shader_name); | ||||
|   | ||||
| @@ -582,6 +582,14 @@ void GRenderWindow::resizeEvent(QResizeEvent* event) { | ||||
|     OnFramebufferSizeChanged(); | ||||
| } | ||||
|  | ||||
| void GRenderWindow::moveEvent(QMoveEvent* event) { | ||||
|     QWidget::moveEvent(event); | ||||
|     if (is_secondary) { | ||||
|         const auto screen_pos = Common::MakeVec(pos().x(), pos().y()); | ||||
|         SetScreenPos(screen_pos); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool GRenderWindow::InitRenderTarget() { | ||||
|     { | ||||
|         // Create a dummy render widget so that Qt | ||||
|   | ||||
| @@ -136,6 +136,7 @@ public: | ||||
|     void closeEvent(QCloseEvent* event) override; | ||||
|  | ||||
|     void resizeEvent(QResizeEvent* event) override; | ||||
|     void moveEvent(QMoveEvent* event) override; | ||||
|  | ||||
|     void keyPressEvent(QKeyEvent* event) override; | ||||
|     void keyReleaseEvent(QKeyEvent* event) override; | ||||
|   | ||||
| @@ -505,9 +505,9 @@ void Config::ReadLayoutValues() { | ||||
|     ReadGlobalSetting(Settings::values.swap_screen); | ||||
|     ReadGlobalSetting(Settings::values.upright_screen); | ||||
|     ReadGlobalSetting(Settings::values.large_screen_proportion); | ||||
|     ReadBasicSetting(Settings::values.swap_eyes); | ||||
|  | ||||
|     if (global) { | ||||
|         ReadBasicSetting(Settings::values.mono_render_option); | ||||
|         ReadBasicSetting(Settings::values.custom_layout); | ||||
|         ReadBasicSetting(Settings::values.custom_top_left); | ||||
|         ReadBasicSetting(Settings::values.custom_top_top); | ||||
| @@ -1017,9 +1017,9 @@ void Config::SaveLayoutValues() { | ||||
|     WriteGlobalSetting(Settings::values.swap_screen); | ||||
|     WriteGlobalSetting(Settings::values.upright_screen); | ||||
|     WriteGlobalSetting(Settings::values.large_screen_proportion); | ||||
|     WriteBasicSetting(Settings::values.swap_eyes); | ||||
|  | ||||
|     if (global) { | ||||
|         WriteBasicSetting(Settings::values.mono_render_option); | ||||
|         WriteBasicSetting(Settings::values.custom_layout); | ||||
|         WriteBasicSetting(Settings::values.custom_top_left); | ||||
|         WriteBasicSetting(Settings::values.custom_top_top); | ||||
|   | ||||
| @@ -74,9 +74,8 @@ void ConfigureEnhancements::SetConfiguration() { | ||||
|     ui->render_3d_combobox->setCurrentIndex( | ||||
|         static_cast<int>(Settings::values.render_3d.GetValue())); | ||||
|     ui->factor_3d->setValue(Settings::values.factor_3d.GetValue()); | ||||
|     ui->mono_rendering_eye->setCurrentIndex( | ||||
|         static_cast<int>(Settings::values.mono_render_option.GetValue())); | ||||
|     updateShaders(Settings::values.render_3d.GetValue()); | ||||
|     ui->toggle_swap_eyes->setChecked(Settings::values.swap_eyes.GetValue()); | ||||
|     ui->toggle_linear_filter->setChecked(Settings::values.filter_mode.GetValue()); | ||||
|     ui->toggle_swap_screen->setChecked(Settings::values.swap_screen.GetValue()); | ||||
|     ui->toggle_upright_screen->setChecked(Settings::values.upright_screen.GetValue()); | ||||
| @@ -98,8 +97,7 @@ void ConfigureEnhancements::updateShaders(Settings::StereoRenderOption stereo_op | ||||
|     ui->shader_combobox->clear(); | ||||
|     ui->shader_combobox->setEnabled(true); | ||||
|  | ||||
|     if (stereo_option == Settings::StereoRenderOption::Interlaced || | ||||
|         stereo_option == Settings::StereoRenderOption::ReverseInterlaced) { | ||||
|     if (stereo_option == Settings::StereoRenderOption::Interlaced) { | ||||
|         ui->shader_combobox->addItem(QStringLiteral("horizontal (builtin)")); | ||||
|         ui->shader_combobox->setCurrentIndex(0); | ||||
|         ui->shader_combobox->setEnabled(false); | ||||
| @@ -135,8 +133,6 @@ void ConfigureEnhancements::ApplyConfiguration() { | ||||
|     Settings::values.render_3d = | ||||
|         static_cast<Settings::StereoRenderOption>(ui->render_3d_combobox->currentIndex()); | ||||
|     Settings::values.factor_3d = ui->factor_3d->value(); | ||||
|     Settings::values.mono_render_option = | ||||
|         static_cast<Settings::MonoRenderOption>(ui->mono_rendering_eye->currentIndex()); | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph) { | ||||
|         Settings::values.anaglyph_shader_name = | ||||
|             ui->shader_combobox->itemText(ui->shader_combobox->currentIndex()).toStdString(); | ||||
| @@ -146,6 +142,8 @@ void ConfigureEnhancements::ApplyConfiguration() { | ||||
|     } | ||||
|     Settings::values.large_screen_proportion = ui->large_screen_proportion->value(); | ||||
|  | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.swap_eyes, ui->toggle_swap_eyes, | ||||
|                                              swap_eyes); | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.filter_mode, | ||||
|                                              ui->toggle_linear_filter, linear_filter); | ||||
|     ConfigurationShared::ApplyPerGameSetting(&Settings::values.texture_filter, | ||||
| @@ -174,6 +172,7 @@ void ConfigureEnhancements::SetupPerGameUI() { | ||||
|     if (Settings::IsConfiguringGlobal()) { | ||||
|         ui->widget_resolution->setEnabled(Settings::values.resolution_factor.UsingGlobal()); | ||||
|         ui->widget_texture_filter->setEnabled(Settings::values.texture_filter.UsingGlobal()); | ||||
|         ui->toggle_swap_eyes->setEnabled(Settings::values.swap_eyes.UsingGlobal()); | ||||
|         ui->toggle_linear_filter->setEnabled(Settings::values.filter_mode.UsingGlobal()); | ||||
|         ui->toggle_swap_screen->setEnabled(Settings::values.swap_screen.UsingGlobal()); | ||||
|         ui->toggle_upright_screen->setEnabled(Settings::values.upright_screen.UsingGlobal()); | ||||
| @@ -193,6 +192,8 @@ void ConfigureEnhancements::SetupPerGameUI() { | ||||
|                                             linear_filter); | ||||
|     ConfigurationShared::SetColoredTristate(ui->toggle_swap_screen, Settings::values.swap_screen, | ||||
|                                             swap_screen); | ||||
|     ConfigurationShared::SetColoredTristate(ui->toggle_swap_eyes, Settings::values.swap_eyes, | ||||
|                                             swap_eyes); | ||||
|     ConfigurationShared::SetColoredTristate(ui->toggle_upright_screen, | ||||
|                                             Settings::values.upright_screen, upright_screen); | ||||
|     ConfigurationShared::SetColoredTristate(ui->toggle_dump_textures, | ||||
|   | ||||
| @@ -45,5 +45,6 @@ private: | ||||
|     ConfigurationShared::CheckState custom_textures; | ||||
|     ConfigurationShared::CheckState preload_textures; | ||||
|     ConfigurationShared::CheckState async_custom_loading; | ||||
|     ConfigurationShared::CheckState swap_eyes; | ||||
|     QColor bg_color; | ||||
| }; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>440</width> | ||||
|     <height>748</height> | ||||
|     <height>781</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="minimumSize"> | ||||
| @@ -199,11 +199,11 @@ | ||||
|              <string>xBRZ</string> | ||||
|             </property> | ||||
|            </item> | ||||
|             <item> | ||||
|               <property name="text"> | ||||
|                 <string>MMPX</string> | ||||
|               </property> | ||||
|             </item> | ||||
|            <item> | ||||
|             <property name="text"> | ||||
|              <string>MMPX</string> | ||||
|             </property> | ||||
|            </item> | ||||
|           </widget> | ||||
|          </item> | ||||
|         </layout> | ||||
| @@ -239,6 +239,11 @@ | ||||
|             <string>Side by Side</string> | ||||
|            </property> | ||||
|           </item> | ||||
|           <item> | ||||
|            <property name="text"> | ||||
|             <string>Top Bottom</string> | ||||
|            </property> | ||||
|           </item> | ||||
|           <item> | ||||
|            <property name="text"> | ||||
|             <string>Anaglyph</string> | ||||
| @@ -249,11 +254,6 @@ | ||||
|             <string>Interlaced</string> | ||||
|            </property> | ||||
|           </item> | ||||
|           <item> | ||||
|            <property name="text"> | ||||
|             <string>Reverse Interlaced</string> | ||||
|            </property> | ||||
|           </item> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
| @@ -288,26 +288,12 @@ | ||||
|       <item> | ||||
|        <layout class="QHBoxLayout" name="horizontalLayout_9"> | ||||
|         <item> | ||||
|          <widget class="QLabel" name="label_6"> | ||||
|          <widget class="QCheckBox" name="toggle_swap_eyes"> | ||||
|           <property name="text"> | ||||
|            <string>Eye to Render in Monoscopic Mode</string> | ||||
|            <string>Swap Eyes</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item> | ||||
|          <widget class="QComboBox" name="mono_rendering_eye"> | ||||
|           <item> | ||||
|            <property name="text"> | ||||
|             <string>Left Eye (default)</string> | ||||
|            </property> | ||||
|           </item> | ||||
|           <item> | ||||
|            <property name="text"> | ||||
|             <string>Right Eye</string> | ||||
|            </property> | ||||
|           </item> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </item> | ||||
|      </layout> | ||||
| @@ -539,7 +525,6 @@ | ||||
|   <tabstop>texture_filter_combobox</tabstop> | ||||
|   <tabstop>render_3d_combobox</tabstop> | ||||
|   <tabstop>factor_3d</tabstop> | ||||
|   <tabstop>mono_rendering_eye</tabstop> | ||||
|   <tabstop>layout_combobox</tabstop> | ||||
|   <tabstop>toggle_swap_screen</tabstop> | ||||
|   <tabstop>toggle_upright_screen</tabstop> | ||||
|   | ||||
| @@ -627,6 +627,8 @@ void GMainWindow::InitializeHotkeys() { | ||||
|         Settings::values.frame_limit.SetGlobal(!Settings::values.frame_limit.UsingGlobal()); | ||||
|         UpdateStatusBar(); | ||||
|     }); | ||||
|     connect_shortcut(QStringLiteral("Swap Eyes"), | ||||
|                      [&] { Settings::values.swap_eyes = !Settings::values.swap_eyes; }); | ||||
|     connect_shortcut(QStringLiteral("Toggle Texture Dumping"), | ||||
|                      [&] { Settings::values.dump_textures = !Settings::values.dump_textures; }); | ||||
|     connect_shortcut(QStringLiteral("Toggle Custom Textures"), | ||||
| @@ -2482,18 +2484,24 @@ void GMainWindow::OnMouseActivity() { | ||||
|     ShowMouseCursor(); | ||||
| } | ||||
|  | ||||
| void GMainWindow::mouseMoveEvent([[maybe_unused]] QMouseEvent* event) { | ||||
| void GMainWindow::mouseMoveEvent(QMouseEvent*) { | ||||
|     OnMouseActivity(); | ||||
| } | ||||
|  | ||||
| void GMainWindow::mousePressEvent([[maybe_unused]] QMouseEvent* event) { | ||||
| void GMainWindow::mousePressEvent(QMouseEvent*) { | ||||
|     OnMouseActivity(); | ||||
| } | ||||
|  | ||||
| void GMainWindow::mouseReleaseEvent([[maybe_unused]] QMouseEvent* event) { | ||||
| void GMainWindow::mouseReleaseEvent(QMouseEvent*) { | ||||
|     OnMouseActivity(); | ||||
| } | ||||
|  | ||||
| void GMainWindow::moveEvent(QMoveEvent* event) { | ||||
|     QMainWindow::moveEvent(event); | ||||
|     const auto screen_pos = Common::MakeVec(pos().x(), pos().y()); | ||||
|     render_window->SetScreenPos(screen_pos); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string details) { | ||||
|     QString status_message; | ||||
|  | ||||
|   | ||||
| @@ -374,6 +374,7 @@ protected: | ||||
|     void mouseMoveEvent(QMouseEvent* event) override; | ||||
|     void mousePressEvent(QMouseEvent* event) override; | ||||
|     void mouseReleaseEvent(QMouseEvent* event) override; | ||||
|     void moveEvent(QMoveEvent* event) override; | ||||
| }; | ||||
|  | ||||
| Q_DECLARE_METATYPE(std::size_t); | ||||
|   | ||||
| @@ -84,7 +84,7 @@ void LogSettings() { | ||||
|     log_setting("Renderer_TextureFilter", GetTextureFilterName(values.texture_filter.GetValue())); | ||||
|     log_setting("Stereoscopy_Render3d", values.render_3d.GetValue()); | ||||
|     log_setting("Stereoscopy_Factor3d", values.factor_3d.GetValue()); | ||||
|     log_setting("Stereoscopy_MonoRenderOption", values.mono_render_option.GetValue()); | ||||
|     log_setting("Stereoscopy_SwapEyes", values.swap_eyes.GetValue()); | ||||
|     if (values.render_3d.GetValue() == StereoRenderOption::Anaglyph) { | ||||
|         log_setting("Renderer_AnaglyphShader", values.anaglyph_shader_name.GetValue()); | ||||
|     } | ||||
|   | ||||
| @@ -49,19 +49,12 @@ enum class LayoutOption : u32 { | ||||
| enum class StereoRenderOption : u32 { | ||||
|     Off = 0, | ||||
|     SideBySide = 1, | ||||
|     Anaglyph = 2, | ||||
|     Interlaced = 3, | ||||
|     ReverseInterlaced = 4, | ||||
|     TopBottom = 2, | ||||
|     Anaglyph = 3, | ||||
|     Interlaced = 4, | ||||
|     CardboardVR = 5 | ||||
| }; | ||||
|  | ||||
| // Which eye to render when 3d is off. 800px wide mode could be added here in the future, when | ||||
| // implemented | ||||
| enum class MonoRenderOption : u32 { | ||||
|     LeftEye = 0, | ||||
|     RightEye = 1, | ||||
| }; | ||||
|  | ||||
| enum class AudioEmulation : u32 { | ||||
|     HLE = 0, | ||||
|     LLE = 1, | ||||
| @@ -467,8 +460,7 @@ struct Values { | ||||
|  | ||||
|     SwitchableSetting<StereoRenderOption> render_3d{StereoRenderOption::Off, "render_3d"}; | ||||
|     SwitchableSetting<u32> factor_3d{0, "factor_3d"}; | ||||
|     SwitchableSetting<MonoRenderOption> mono_render_option{MonoRenderOption::LeftEye, | ||||
|                                                            "mono_render_option"}; | ||||
|     SwitchableSetting<bool> swap_eyes{false, "swap_eyes"}; | ||||
|  | ||||
|     Setting<u32> cardboard_screen_size{85, "cardboard_screen_size"}; | ||||
|     Setting<s32> cardboard_x_shift{0, "cardboard_x_shift"}; | ||||
|   | ||||
| @@ -73,6 +73,13 @@ bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, uns | ||||
|                   framebuffer_x < layout.bottom_screen.right / 2) || | ||||
|                  (framebuffer_x >= (layout.bottom_screen.left / 2) + (layout.width / 2) && | ||||
|                   framebuffer_x < (layout.bottom_screen.right / 2) + (layout.width / 2)))); | ||||
|     } else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::TopBottom) { | ||||
|         return framebuffer_x >= layout.bottom_screen.left && | ||||
|                framebuffer_x < layout.bottom_screen.right && | ||||
|                ((framebuffer_y >= layout.bottom_screen.top / 2 && | ||||
|                  framebuffer_y < layout.bottom_screen.bottom / 2) || | ||||
|                 (framebuffer_y >= (layout.bottom_screen.top / 2) + (layout.height / 2) && | ||||
|                  framebuffer_y < (layout.bottom_screen.bottom / 2) + (layout.height / 2))); | ||||
|     } else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) { | ||||
|         return (framebuffer_y >= layout.bottom_screen.top && | ||||
|                 framebuffer_y < layout.bottom_screen.bottom && | ||||
| @@ -91,22 +98,35 @@ bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, uns | ||||
|  | ||||
| std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const { | ||||
|     if (new_x >= framebuffer_layout.width / 2) { | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|             new_x -= framebuffer_layout.width / 2; | ||||
|         else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) | ||||
|         } else if (Settings::values.render_3d.GetValue() == | ||||
|                    Settings::StereoRenderOption::CardboardVR) { | ||||
|             new_x -= | ||||
|                 (framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2); | ||||
|         } | ||||
|     } | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|         new_x = std::max(new_x, framebuffer_layout.bottom_screen.left / 2); | ||||
|         new_x = std::min(new_x, framebuffer_layout.bottom_screen.right / 2 - 1); | ||||
|     } else { | ||||
|         new_x = std::max(new_x, framebuffer_layout.bottom_screen.left); | ||||
|         new_x = std::min(new_x, framebuffer_layout.bottom_screen.right - 1); | ||||
|     if (new_y >= framebuffer_layout.height / 2) { | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::TopBottom) { | ||||
|             new_y -= framebuffer_layout.height / 2; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     new_y = std::max(new_y, framebuffer_layout.bottom_screen.top); | ||||
|     new_y = std::min(new_y, framebuffer_layout.bottom_screen.bottom - 1); | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|         new_x = std::clamp(new_x, framebuffer_layout.bottom_screen.left / 2, | ||||
|                            framebuffer_layout.bottom_screen.right / 2 - 1); | ||||
|     } else { | ||||
|         new_x = std::clamp(new_x, framebuffer_layout.bottom_screen.left, | ||||
|                            framebuffer_layout.bottom_screen.right - 1); | ||||
|     } | ||||
|  | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::TopBottom) { | ||||
|         new_y = std::clamp(new_y, framebuffer_layout.bottom_screen.top / 2, | ||||
|                            framebuffer_layout.bottom_screen.bottom / 2 - 1); | ||||
|     } else { | ||||
|         new_y = std::clamp(new_y, framebuffer_layout.bottom_screen.top, | ||||
|                            framebuffer_layout.bottom_screen.bottom - 1); | ||||
|     } | ||||
|  | ||||
|     return std::make_tuple(new_x, new_y); | ||||
| } | ||||
| @@ -122,17 +142,25 @@ void EmuWindow::CreateTouchState() { | ||||
| } | ||||
|  | ||||
| bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||
|     if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) | ||||
|     if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     if (framebuffer_x >= framebuffer_layout.width / 2) { | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|             framebuffer_x -= framebuffer_layout.width / 2; | ||||
|         else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) | ||||
|         } else if (Settings::values.render_3d.GetValue() == | ||||
|                    Settings::StereoRenderOption::CardboardVR) { | ||||
|             framebuffer_x -= | ||||
|                 (framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2); | ||||
|         } | ||||
|     } | ||||
|     std::lock_guard guard(touch_state->mutex); | ||||
|     if (framebuffer_y >= framebuffer_layout.height / 2) { | ||||
|         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::TopBottom) { | ||||
|             framebuffer_y -= framebuffer_layout.height / 2; | ||||
|         } | ||||
|     } | ||||
|     std::scoped_lock lock{touch_state->mutex}; | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) { | ||||
|         touch_state->touch_x = | ||||
|             static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) / | ||||
| @@ -143,9 +171,17 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||
|             static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left) / | ||||
|             (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); | ||||
|     } | ||||
|     touch_state->touch_y = | ||||
|         static_cast<float>(framebuffer_y - framebuffer_layout.bottom_screen.top) / | ||||
|         (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); | ||||
|  | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::TopBottom) { | ||||
|         touch_state->touch_y = | ||||
|             static_cast<float>(framebuffer_y - framebuffer_layout.bottom_screen.top / 2) / | ||||
|             (framebuffer_layout.bottom_screen.bottom / 2 - | ||||
|              framebuffer_layout.bottom_screen.top / 2); | ||||
|     } else { | ||||
|         touch_state->touch_y = | ||||
|             static_cast<float>(framebuffer_y - framebuffer_layout.bottom_screen.top) / | ||||
|             (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); | ||||
|     } | ||||
|  | ||||
|     if (!framebuffer_layout.is_rotated) { | ||||
|         std::swap(touch_state->touch_x, touch_state->touch_y); | ||||
| @@ -157,18 +193,20 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||
| } | ||||
|  | ||||
| void EmuWindow::TouchReleased() { | ||||
|     std::lock_guard guard{touch_state->mutex}; | ||||
|     std::scoped_lock lock{touch_state->mutex}; | ||||
|     touch_state->touch_pressed = false; | ||||
|     touch_state->touch_x = 0; | ||||
|     touch_state->touch_y = 0; | ||||
| } | ||||
|  | ||||
| void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { | ||||
|     if (!touch_state->touch_pressed) | ||||
|     if (!touch_state->touch_pressed) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) | ||||
|     if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) { | ||||
|         std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y); | ||||
|     } | ||||
|  | ||||
|     TouchPressed(framebuffer_x, framebuffer_y); | ||||
| } | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| #include <utility> | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "core/3ds.h" | ||||
| #include "core/frontend/framebuffer_layout.h" | ||||
|  | ||||
| @@ -217,6 +218,17 @@ public: | ||||
|         config = val; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Updates the position of the client window area relative to the origin of the host display. | ||||
|      */ | ||||
|     void SetScreenPos(const Common::Vec2i pos) { | ||||
|         screen_pos = pos; | ||||
|     } | ||||
|  | ||||
|     Common::Vec2i GetScreenPos() const { | ||||
|         return screen_pos; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns system information about the drawing area. | ||||
|      */ | ||||
| @@ -274,6 +286,7 @@ protected: | ||||
|     bool is_secondary{}; | ||||
|     bool strict_context_required{}; | ||||
|     WindowSystemInfo window_info; | ||||
|     Common::Vec2i screen_pos{}; | ||||
|  | ||||
| private: | ||||
|     /** | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  | ||||
| #include <cmath> | ||||
|  | ||||
| #include "common/alignment.h" | ||||
| #include "common/assert.h" | ||||
| #include "common/settings.h" | ||||
| #include "core/3ds.h" | ||||
|   | ||||
| @@ -151,8 +151,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { | ||||
|              static_cast<int>(Settings::values.render_3d.GetValue())); | ||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_Factor3d", | ||||
|              Settings::values.factor_3d.GetValue()); | ||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_MonoRenderOption", | ||||
|              static_cast<int>(Settings::values.mono_render_option.GetValue())); | ||||
|     AddField(Telemetry::FieldType::UserConfig, "Renderer_SwapEyes", | ||||
|              static_cast<int>(Settings::values.swap_eyes.GetValue())); | ||||
|     AddField(Telemetry::FieldType::UserConfig, "System_IsNew3ds", | ||||
|              Settings::values.is_new_3ds.GetValue()); | ||||
|     AddField(Telemetry::FieldType::UserConfig, "System_RegionValue", | ||||
|   | ||||
| @@ -103,4 +103,4 @@ add_custom_target(host_shaders | ||||
|         ${SHADER_HEADERS} | ||||
|     SOURCES | ||||
|         ${SHADER_SOURCES} | ||||
| ) | ||||
| ) | ||||
| @@ -4,17 +4,16 @@ | ||||
|  | ||||
| //? #version 430 core | ||||
|  | ||||
| // Anaglyph Red-Cyan shader based on Dubois algorithm | ||||
| // Constants taken from the paper: | ||||
| // "Conversion of a Stereo Pair to Anaglyph with | ||||
| // the Least-Squares Projection Method" | ||||
| // Eric Dubois, March 2009 | ||||
| const mat3 l = mat3( 0.437, 0.449, 0.164, | ||||
|               -0.062,-0.062,-0.024, | ||||
|               -0.048,-0.050,-0.017); | ||||
| const mat3 r = mat3(-0.011,-0.032,-0.007, | ||||
|                0.377, 0.761, 0.009, | ||||
|               -0.026,-0.093, 1.234); | ||||
| // https://cybereality.com/rendepth-red-cyan-anaglyph-filter-optimized-for-stereoscopic-3d-on-lcd-monitors/ | ||||
| const mat3 left_filter = mat3( | ||||
|         vec3(0.4561, 0.500484, 0.176381), | ||||
|         vec3(-0.400822, -0.0378246, -0.0157589), | ||||
|         vec3(-0.0152161, -0.0205971, -0.00546856)); | ||||
|  | ||||
| const mat3 right_filter = mat3( | ||||
|         vec3(-0.0434706, -0.0879388, -0.00155529), | ||||
|         vec3(0.378476, 0.73364, -0.0184503), | ||||
|         vec3(-0.0721527, -0.112961, 1.2264)); | ||||
|  | ||||
| layout(location = 0) in vec2 frag_tex_coord; | ||||
| layout(location = 0) out vec4 color; | ||||
| @@ -24,9 +23,22 @@ layout(binding = 1) uniform sampler2D color_texture_r; | ||||
|  | ||||
| uniform vec4 resolution; | ||||
| uniform int layer; | ||||
| uniform bool swap_eyes; | ||||
|  | ||||
| const vec3 gamma_map = vec3(1.6, 0.8, 1.0); | ||||
|  | ||||
| vec3 correct_color(vec3 original) { | ||||
|     vec3 corrected; | ||||
|     corrected.r = pow(original.r, 1.0 / gamma_map.r); | ||||
|     corrected.g = pow(original.g, 1.0 / gamma_map.g); | ||||
|     corrected.b = pow(original.b, 1.0 / gamma_map.b); | ||||
|     return corrected; | ||||
| } | ||||
|  | ||||
| void main() { | ||||
|     vec4 color_tex_l = texture(color_texture, frag_tex_coord); | ||||
|     vec4 color_tex_r = texture(color_texture_r, frag_tex_coord); | ||||
|     color = vec4(color_tex_l.rgb*l+color_tex_r.rgb*r, color_tex_l.a); | ||||
|     vec4 color_left = texture(color_texture, frag_tex_coord); | ||||
|     vec4 color_right = texture(color_texture_r, frag_tex_coord); | ||||
|     vec3 optimized_color = clamp(color_left.rgb * (swap_eyes ? right_filter : left_filter), vec3(0.0), vec3(1.0)) + | ||||
|                            clamp(color_right.rgb * (swap_eyes ? left_filter : right_filter), vec3(0.0), vec3(1.0)); | ||||
|     color = vec4(correct_color(optimized_color), color_left.a); | ||||
| } | ||||
|   | ||||
| @@ -7,16 +7,22 @@ | ||||
| layout(location = 0) in vec2 frag_tex_coord; | ||||
| layout(location = 0) out vec4 color; | ||||
|  | ||||
| layout(binding = 0) uniform sampler2D color_texture; | ||||
| layout(binding = 0) uniform sampler2D color_texture_l; | ||||
| layout(binding = 1) uniform sampler2D color_texture_r; | ||||
|  | ||||
| uniform vec4 o_resolution; | ||||
| uniform int reverse_interlaced; | ||||
| uniform ivec2 screen_pos; | ||||
| uniform bool swap_eyes; | ||||
|  | ||||
| void main() { | ||||
|     float screen_row = o_resolution.x * frag_tex_coord.x; | ||||
|     if (int(screen_row) % 2 == reverse_interlaced) | ||||
|         color = texture(color_texture, frag_tex_coord); | ||||
|     else | ||||
|     bool is_even = screen_pos.y % 2 == 0; | ||||
|     if (swap_eyes) { | ||||
|         is_even = !is_even; | ||||
|     } | ||||
|     if (int(screen_row) % 2 == int(is_even)) { | ||||
|         color = texture(color_texture_l, frag_tex_coord); | ||||
|     } else { | ||||
|         color = texture(color_texture_r, frag_tex_coord); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -49,6 +49,8 @@ uniform float4 i_resolution; | ||||
| uniform float4 o_resolution; | ||||
| // Layer | ||||
| uniform int layer; | ||||
| // Screen position | ||||
| uniform int2 screen_pos; | ||||
|  | ||||
| uniform sampler2D color_texture; | ||||
| uniform sampler2D color_texture_r; | ||||
| @@ -119,6 +121,11 @@ float2 GetCoordinates() | ||||
|     return frag_tex_coord; | ||||
| } | ||||
|  | ||||
| int2 GetScreenPos() | ||||
| { | ||||
|     return screen_pos; | ||||
| } | ||||
|  | ||||
| void SetOutput(float4 color_in) | ||||
| { | ||||
|     color = color_in; | ||||
|   | ||||
| @@ -54,8 +54,7 @@ struct ScreenRectVertex { | ||||
|  * | ||||
|  * @param flipped Whether the frame should be flipped upside down. | ||||
|  */ | ||||
| static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, const float height, | ||||
|                                                          bool flipped) { | ||||
| static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(u32 width, u32 height, bool flipped) { | ||||
|  | ||||
|     std::array<GLfloat, 3 * 2> matrix; // Laid out in column-major order | ||||
|  | ||||
| @@ -405,9 +404,7 @@ void RendererOpenGL::ReloadShader() { | ||||
|                 shader_data += shader_text; | ||||
|             } | ||||
|         } | ||||
|     } else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced || | ||||
|                Settings::values.render_3d.GetValue() == | ||||
|                    Settings::StereoRenderOption::ReverseInterlaced) { | ||||
|     } else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced) { | ||||
|         shader_data += HostShaders::OPENGL_PRESENT_INTERLACED_FRAG; | ||||
|     } else { | ||||
|         if (Settings::values.pp_shader_name.GetValue() == "none (builtin)") { | ||||
| @@ -429,23 +426,14 @@ void RendererOpenGL::ReloadShader() { | ||||
|     uniform_modelview_matrix = glGetUniformLocation(shader.handle, "modelview_matrix"); | ||||
|     uniform_color_texture = glGetUniformLocation(shader.handle, "color_texture"); | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph || | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced || | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::ReverseInterlaced) { | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced) { | ||||
|         uniform_swap_eyes = glGetUniformLocation(shader.handle, "swap_eyes"); | ||||
|         uniform_color_texture_r = glGetUniformLocation(shader.handle, "color_texture_r"); | ||||
|     } | ||||
|     if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced || | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::ReverseInterlaced) { | ||||
|         GLuint uniform_reverse_interlaced = | ||||
|             glGetUniformLocation(shader.handle, "reverse_interlaced"); | ||||
|         if (Settings::values.render_3d.GetValue() == | ||||
|             Settings::StereoRenderOption::ReverseInterlaced) | ||||
|             glUniform1i(uniform_reverse_interlaced, 1); | ||||
|         else | ||||
|             glUniform1i(uniform_reverse_interlaced, 0); | ||||
|     } | ||||
|     uniform_i_resolution = glGetUniformLocation(shader.handle, "i_resolution"); | ||||
|     uniform_o_resolution = glGetUniformLocation(shader.handle, "o_resolution"); | ||||
|     uniform_layer = glGetUniformLocation(shader.handle, "layer"); | ||||
|     uniform_screen_pos = glGetUniformLocation(shader.handle, "screen_pos"); | ||||
|     attrib_position = glGetAttribLocation(shader.handle, "vert_position"); | ||||
|     attrib_tex_coord = glGetAttribLocation(shader.handle, "vert_tex_coord"); | ||||
| } | ||||
| @@ -678,8 +666,7 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f | ||||
|     glClear(GL_COLOR_BUFFER_BIT); | ||||
|  | ||||
|     // Set projection matrix | ||||
|     std::array<GLfloat, 3 * 2> ortho_matrix = | ||||
|         MakeOrthographicMatrix((float)layout.width, (float)layout.height, flipped); | ||||
|     const auto ortho_matrix = MakeOrthographicMatrix(layout.width, layout.height, flipped); | ||||
|     glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data()); | ||||
|  | ||||
|     // Bind texture in Texture Unit 0 | ||||
| @@ -687,8 +674,12 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f | ||||
|  | ||||
|     const bool stereo_single_screen = | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph || | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced || | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::ReverseInterlaced; | ||||
|         Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced; | ||||
|  | ||||
|     // Set the screen position | ||||
|     const auto screen_pos = render_window.GetScreenPos() + | ||||
|                             Common::MakeVec<s32>(layout.top_screen.left, layout.top_screen.bottom); | ||||
|     glUniform2i(uniform_screen_pos, screen_pos.x, screen_pos.y); | ||||
|  | ||||
|     // Bind a second texture for the right eye if in Anaglyph mode | ||||
|     if (stereo_single_screen) { | ||||
| @@ -756,7 +747,7 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout, | ||||
|                                                : Layout::DisplayOrientation::Portrait; | ||||
|     switch (Settings::values.render_3d.GetValue()) { | ||||
|     case Settings::StereoRenderOption::Off: { | ||||
|         const int eye = static_cast<int>(Settings::values.mono_render_option.GetValue()); | ||||
|         const u32 eye = static_cast<u32>(Settings::values.swap_eyes.GetValue()); | ||||
|         DrawSingleScreen(screen_infos[eye], top_screen_left, top_screen_top, top_screen_width, | ||||
|                          top_screen_height, orientation); | ||||
|         break; | ||||
| @@ -770,6 +761,15 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout, | ||||
|                          top_screen_top, top_screen_width / 2, top_screen_height, orientation); | ||||
|         break; | ||||
|     } | ||||
|     case Settings::StereoRenderOption::TopBottom: { | ||||
|         DrawSingleScreen(screen_infos[0], top_screen_left, top_screen_top / 2, top_screen_width, | ||||
|                          top_screen_height / 2, orientation); | ||||
|         glUniform1i(uniform_layer, 1); | ||||
|         DrawSingleScreen(screen_infos[1], top_screen_left, | ||||
|                          static_cast<float>((top_screen_top / 2) + (layout.height / 2)), | ||||
|                          top_screen_width, top_screen_height / 2, orientation); | ||||
|         break; | ||||
|     } | ||||
|     case Settings::StereoRenderOption::CardboardVR: { | ||||
|         DrawSingleScreen(screen_infos[0], top_screen_left, top_screen_top, top_screen_width, | ||||
|                          top_screen_height, orientation); | ||||
| @@ -781,8 +781,8 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout, | ||||
|         break; | ||||
|     } | ||||
|     case Settings::StereoRenderOption::Anaglyph: | ||||
|     case Settings::StereoRenderOption::Interlaced: | ||||
|     case Settings::StereoRenderOption::ReverseInterlaced: { | ||||
|     case Settings::StereoRenderOption::Interlaced: { | ||||
|         glUniform1i(uniform_swap_eyes, Settings::values.swap_eyes.GetValue()); | ||||
|         DrawSingleScreenStereo(screen_infos[0], screen_infos[1], top_screen_left, top_screen_top, | ||||
|                                top_screen_width, top_screen_height, orientation); | ||||
|         break; | ||||
| @@ -803,8 +803,17 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout, | ||||
|  | ||||
|     const auto orientation = layout.is_rotated ? Layout::DisplayOrientation::Landscape | ||||
|                                                : Layout::DisplayOrientation::Portrait; | ||||
|     const auto render_3d = | ||||
| #ifndef ANDROID | ||||
|         Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows && | ||||
|                 Settings::values.render_3d.GetValue() != Settings::StereoRenderOption::Anaglyph | ||||
|             ? Settings::StereoRenderOption::Off | ||||
|             : Settings::values.render_3d.GetValue(); | ||||
| #else | ||||
|         const auto render_3d = Settings::values.render_3d.GetValue(); | ||||
| #endif | ||||
|  | ||||
|     switch (Settings::values.render_3d.GetValue()) { | ||||
|     switch (render_3d) { | ||||
|     case Settings::StereoRenderOption::Off: { | ||||
|         DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top, | ||||
|                          bottom_screen_width, bottom_screen_height, orientation); | ||||
| @@ -819,6 +828,15 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout, | ||||
|             bottom_screen_top, bottom_screen_width / 2, bottom_screen_height, orientation); | ||||
|         break; | ||||
|     } | ||||
|     case Settings::StereoRenderOption::TopBottom: { | ||||
|         DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top / 2, | ||||
|                          bottom_screen_width, bottom_screen_height / 2, orientation); | ||||
|         glUniform1i(uniform_layer, 1); | ||||
|         DrawSingleScreen(screen_infos[2], bottom_screen_left, | ||||
|                          static_cast<float>((bottom_screen_top / 2) + (layout.height / 2)), | ||||
|                          bottom_screen_width, bottom_screen_height / 2, orientation); | ||||
|         break; | ||||
|     } | ||||
|     case Settings::StereoRenderOption::CardboardVR: { | ||||
|         DrawSingleScreen(screen_infos[2], bottom_screen_left, bottom_screen_top, | ||||
|                          bottom_screen_width, bottom_screen_height, orientation); | ||||
| @@ -830,8 +848,8 @@ void RendererOpenGL::DrawBottomScreen(const Layout::FramebufferLayout& layout, | ||||
|         break; | ||||
|     } | ||||
|     case Settings::StereoRenderOption::Anaglyph: | ||||
|     case Settings::StereoRenderOption::Interlaced: | ||||
|     case Settings::StereoRenderOption::ReverseInterlaced: { | ||||
|     case Settings::StereoRenderOption::Interlaced: { | ||||
|         glUniform1i(uniform_swap_eyes, Settings::values.swap_eyes.GetValue()); | ||||
|         DrawSingleScreenStereo(screen_infos[2], screen_infos[2], bottom_screen_left, | ||||
|                                bottom_screen_top, bottom_screen_width, bottom_screen_height, | ||||
|                                orientation); | ||||
|   | ||||
| @@ -103,11 +103,13 @@ private: | ||||
|     GLuint uniform_modelview_matrix; | ||||
|     GLuint uniform_color_texture; | ||||
|     GLuint uniform_color_texture_r; | ||||
|     GLuint uniform_swap_eyes; | ||||
|  | ||||
|     // Shader uniform for Dolphin compatibility | ||||
|     GLuint uniform_i_resolution; | ||||
|     GLuint uniform_o_resolution; | ||||
|     GLuint uniform_layer; | ||||
|     GLuint uniform_screen_pos; | ||||
|  | ||||
|     // Shader attribute input indices | ||||
|     GLuint attrib_position; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user