From a92fd98d7f83d729293bd2e819172c47a92a9180 Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Fri, 17 Jul 2020 03:50:02 -0700 Subject: [PATCH 01/12] Qt/GameListSettings: Fix QToolButtons staying highlighted after use --- src/duckstation-qt/gamelistsettingswidget.cpp | 26 +++++++++---------- src/duckstation-qt/gamelistsettingswidget.h | 10 +++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/duckstation-qt/gamelistsettingswidget.cpp b/src/duckstation-qt/gamelistsettingswidget.cpp index 793ac5554..6eb3e5216 100644 --- a/src/duckstation-qt/gamelistsettingswidget.cpp +++ b/src/duckstation-qt/gamelistsettingswidget.cpp @@ -214,14 +214,14 @@ GameListSettingsWidget::GameListSettingsWidget(QtHostInterface* host_interface, m_ui.searchDirectoryList->setCurrentIndex({}); connect(m_ui.searchDirectoryList, &QTableView::clicked, this, &GameListSettingsWidget::onDirectoryListItemClicked); - connect(m_ui.addSearchDirectoryButton, &QToolButton::pressed, this, - &GameListSettingsWidget::onAddSearchDirectoryButtonPressed); - connect(m_ui.removeSearchDirectoryButton, &QToolButton::pressed, this, - &GameListSettingsWidget::onRemoveSearchDirectoryButtonPressed); - connect(m_ui.rescanAllGames, &QToolButton::pressed, this, &GameListSettingsWidget::onRescanAllGamesPressed); - connect(m_ui.scanForNewGames, &QToolButton::pressed, this, &GameListSettingsWidget::onScanForNewGamesPressed); - connect(m_ui.updateRedumpDatabase, &QToolButton::pressed, this, - &GameListSettingsWidget::onUpdateRedumpDatabaseButtonPressed); + connect(m_ui.addSearchDirectoryButton, &QToolButton::clicked, this, + &GameListSettingsWidget::onAddSearchDirectoryButtonClicked); + connect(m_ui.removeSearchDirectoryButton, &QToolButton::clicked, this, + &GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked); + connect(m_ui.rescanAllGames, &QToolButton::clicked, this, &GameListSettingsWidget::onRescanAllGamesClicked); + connect(m_ui.scanForNewGames, &QToolButton::clicked, this, &GameListSettingsWidget::onScanForNewGamesClicked); + connect(m_ui.updateRedumpDatabase, &QToolButton::clicked, this, + &GameListSettingsWidget::onUpdateRedumpDatabaseButtonClicked); } GameListSettingsWidget::~GameListSettingsWidget() = default; @@ -265,12 +265,12 @@ void GameListSettingsWidget::addSearchDirectory(QWidget* parent_widget) m_search_directories_model->addEntry(dir, recursive); } -void GameListSettingsWidget::onAddSearchDirectoryButtonPressed() +void GameListSettingsWidget::onAddSearchDirectoryButtonClicked() { addSearchDirectory(this); } -void GameListSettingsWidget::onRemoveSearchDirectoryButtonPressed() +void GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked() { QModelIndexList selection = m_ui.searchDirectoryList->selectionModel()->selectedIndexes(); if (selection.size() < 1) @@ -280,17 +280,17 @@ void GameListSettingsWidget::onRemoveSearchDirectoryButtonPressed() m_search_directories_model->removeEntry(row); } -void GameListSettingsWidget::onRescanAllGamesPressed() +void GameListSettingsWidget::onRescanAllGamesClicked() { m_host_interface->refreshGameList(true, false); } -void GameListSettingsWidget::onScanForNewGamesPressed() +void GameListSettingsWidget::onScanForNewGamesClicked() { m_host_interface->refreshGameList(false, false); } -void GameListSettingsWidget::onUpdateRedumpDatabaseButtonPressed() +void GameListSettingsWidget::onUpdateRedumpDatabaseButtonClicked() { if (QMessageBox::question(this, tr("Download database from redump.org?"), tr("Do you wish to download the disc database from redump.org?\n\nThis will download " diff --git a/src/duckstation-qt/gamelistsettingswidget.h b/src/duckstation-qt/gamelistsettingswidget.h index d8df48010..59880d0a3 100644 --- a/src/duckstation-qt/gamelistsettingswidget.h +++ b/src/duckstation-qt/gamelistsettingswidget.h @@ -21,11 +21,11 @@ public Q_SLOTS: private Q_SLOTS: void onDirectoryListItemClicked(const QModelIndex& index); - void onAddSearchDirectoryButtonPressed(); - void onRemoveSearchDirectoryButtonPressed(); - void onScanForNewGamesPressed(); - void onRescanAllGamesPressed(); - void onUpdateRedumpDatabaseButtonPressed(); + void onAddSearchDirectoryButtonClicked(); + void onRemoveSearchDirectoryButtonClicked(); + void onScanForNewGamesClicked(); + void onRescanAllGamesClicked(); + void onUpdateRedumpDatabaseButtonClicked(); protected: void resizeEvent(QResizeEvent* event); From 401ecfa872a82680b1ebac930dfb88bfbebf33e4 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Thu, 16 Jul 2020 23:15:25 +1000 Subject: [PATCH 02/12] Bus: Make memory map public --- src/core/bus.h | 104 ++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/src/core/bus.h b/src/core/bus.h index de50b8287..6e126885a 100644 --- a/src/core/bus.h +++ b/src/core/bus.h @@ -29,6 +29,55 @@ class Bus friend DMA; public: + enum : u32 + { + RAM_BASE = 0x00000000, + RAM_SIZE = 0x200000, + RAM_MASK = RAM_SIZE - 1, + RAM_MIRROR_END = 0x800000, + EXP1_BASE = 0x1F000000, + EXP1_SIZE = 0x800000, + EXP1_MASK = EXP1_SIZE - 1, + MEMCTRL_BASE = 0x1F801000, + MEMCTRL_SIZE = 0x40, + MEMCTRL_MASK = MEMCTRL_SIZE - 1, + PAD_BASE = 0x1F801040, + PAD_SIZE = 0x10, + PAD_MASK = PAD_SIZE - 1, + SIO_BASE = 0x1F801050, + SIO_SIZE = 0x10, + SIO_MASK = SIO_SIZE - 1, + MEMCTRL2_BASE = 0x1F801060, + MEMCTRL2_SIZE = 0x10, + MEMCTRL2_MASK = MEMCTRL_SIZE - 1, + INTERRUPT_CONTROLLER_BASE = 0x1F801070, + INTERRUPT_CONTROLLER_SIZE = 0x10, + INTERRUPT_CONTROLLER_MASK = INTERRUPT_CONTROLLER_SIZE - 1, + DMA_BASE = 0x1F801080, + DMA_SIZE = 0x80, + DMA_MASK = DMA_SIZE - 1, + TIMERS_BASE = 0x1F801100, + TIMERS_SIZE = 0x40, + TIMERS_MASK = TIMERS_SIZE - 1, + CDROM_BASE = 0x1F801800, + CDROM_SIZE = 0x10, + CDROM_MASK = CDROM_SIZE - 1, + GPU_BASE = 0x1F801810, + GPU_SIZE = 0x10, + GPU_MASK = GPU_SIZE - 1, + MDEC_BASE = 0x1F801820, + MDEC_SIZE = 0x10, + MDEC_MASK = MDEC_SIZE - 1, + SPU_BASE = 0x1F801C00, + SPU_SIZE = 0x400, + SPU_MASK = 0x3FF, + EXP2_BASE = 0x1F802000, + EXP2_SIZE = 0x2000, + EXP2_MASK = EXP2_SIZE - 1, + BIOS_BASE = 0x1FC00000, + BIOS_SIZE = 0x80000 + }; + Bus(); ~Bus(); @@ -85,56 +134,10 @@ public: /// Clears all code bits for RAM regions. ALWAYS_INLINE void ClearRAMCodePageFlags() { m_ram_code_bits.reset(); } -private: - enum : u32 - { - RAM_BASE = 0x00000000, - RAM_SIZE = 0x200000, - RAM_MASK = RAM_SIZE - 1, - RAM_MIRROR_END = 0x800000, - EXP1_BASE = 0x1F000000, - EXP1_SIZE = 0x800000, - EXP1_MASK = EXP1_SIZE - 1, - MEMCTRL_BASE = 0x1F801000, - MEMCTRL_SIZE = 0x40, - MEMCTRL_MASK = MEMCTRL_SIZE - 1, - PAD_BASE = 0x1F801040, - PAD_SIZE = 0x10, - PAD_MASK = PAD_SIZE - 1, - SIO_BASE = 0x1F801050, - SIO_SIZE = 0x10, - SIO_MASK = SIO_SIZE - 1, - MEMCTRL2_BASE = 0x1F801060, - MEMCTRL2_SIZE = 0x10, - MEMCTRL2_MASK = MEMCTRL_SIZE - 1, - INTERRUPT_CONTROLLER_BASE = 0x1F801070, - INTERRUPT_CONTROLLER_SIZE = 0x10, - INTERRUPT_CONTROLLER_MASK = INTERRUPT_CONTROLLER_SIZE - 1, - DMA_BASE = 0x1F801080, - DMA_SIZE = 0x80, - DMA_MASK = DMA_SIZE - 1, - TIMERS_BASE = 0x1F801100, - TIMERS_SIZE = 0x40, - TIMERS_MASK = TIMERS_SIZE - 1, - CDROM_BASE = 0x1F801800, - CDROM_SIZE = 0x10, - CDROM_MASK = CDROM_SIZE - 1, - GPU_BASE = 0x1F801810, - GPU_SIZE = 0x10, - GPU_MASK = GPU_SIZE - 1, - MDEC_BASE = 0x1F801820, - MDEC_SIZE = 0x10, - MDEC_MASK = MDEC_SIZE - 1, - SPU_BASE = 0x1F801C00, - SPU_SIZE = 0x400, - SPU_MASK = 0x3FF, - EXP2_BASE = 0x1F802000, - EXP2_SIZE = 0x2000, - EXP2_MASK = EXP2_SIZE - 1, - BIOS_BASE = 0x1FC00000, - BIOS_SIZE = 0x80000 - }; + /// Direct access to RAM - used by DMA. + ALWAYS_INLINE u8* GetRAM() { return m_ram; } +private: enum : u32 { MEMCTRL_REG_COUNT = 9 @@ -238,9 +241,6 @@ private: void DoInvalidateCodeCache(u32 page_index); - /// Direct access to RAM - used by DMA. - ALWAYS_INLINE u8* GetRAM() { return m_ram; } - /// Returns the number of cycles stolen by DMA RAM access. ALWAYS_INLINE static TickCount GetDMARAMTickCount(u32 word_count) { From 5f76140aa53afa55081f8ea15ae94b3493588595 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 17 Jul 2020 23:17:49 +1000 Subject: [PATCH 03/12] libretro: Expose main RAM to frontend --- .../libretro_host_interface.cpp | 25 +++++++++++++++++++ .../libretro_host_interface.h | 2 ++ src/duckstation-libretro/main.cpp | 4 +-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/duckstation-libretro/libretro_host_interface.cpp b/src/duckstation-libretro/libretro_host_interface.cpp index 64af34bb9..687a8b1e1 100644 --- a/src/duckstation-libretro/libretro_host_interface.cpp +++ b/src/duckstation-libretro/libretro_host_interface.cpp @@ -5,6 +5,7 @@ #include "common/log.h" #include "common/string_util.h" #include "core/analog_controller.h" +#include "core/bus.h" #include "core/digital_controller.h" #include "core/game_list.h" #include "core/gpu.h" @@ -299,6 +300,30 @@ bool LibretroHostInterface::retro_unserialize(const void* data, size_t size) return true; } +void* LibretroHostInterface::retro_get_memory_data(unsigned id) +{ + switch (id) + { + case RETRO_MEMORY_SYSTEM_RAM: + return m_system ? m_system->GetBus()->GetRAM() : nullptr; + + default: + return nullptr; + } +} + +size_t LibretroHostInterface::retro_get_memory_size(unsigned id) +{ + switch (id) + { + case RETRO_MEMORY_SYSTEM_RAM: + return Bus::RAM_SIZE; + + default: + return 0; + } +} + bool LibretroHostInterface::AcquireHostDisplay() { // start in software mode, switch to hardware later diff --git a/src/duckstation-libretro/libretro_host_interface.h b/src/duckstation-libretro/libretro_host_interface.h index 030704fb3..ff1ab4f6d 100644 --- a/src/duckstation-libretro/libretro_host_interface.h +++ b/src/duckstation-libretro/libretro_host_interface.h @@ -37,6 +37,8 @@ public: size_t retro_serialize_size(); bool retro_serialize(void* data, size_t size); bool retro_unserialize(const void* data, size_t size); + void* retro_get_memory_data(unsigned id); + size_t retro_get_memory_size(unsigned id); protected: bool AcquireHostDisplay() override; diff --git a/src/duckstation-libretro/main.cpp b/src/duckstation-libretro/main.cpp index 41d6f4e5d..14bbc10d1 100644 --- a/src/duckstation-libretro/main.cpp +++ b/src/duckstation-libretro/main.cpp @@ -111,12 +111,12 @@ RETRO_API unsigned retro_get_region(void) RETRO_API void* retro_get_memory_data(unsigned id) { - return nullptr; + return g_libretro_host_interface.retro_get_memory_data(id); } RETRO_API size_t retro_get_memory_size(unsigned id) { - return 0; + return g_libretro_host_interface.retro_get_memory_size(id); } RETRO_API void retro_set_environment(retro_environment_t f) From 5c1c467e3812de919514fb11135c26c64ceb63e2 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 00:25:08 +1000 Subject: [PATCH 04/12] GTE: Add widescreen hack --- README.md | 1 + src/core/cpu_core.h | 3 +++ src/core/gte.cpp | 5 ++++- src/core/gte.h | 3 +++ src/core/host_interface.cpp | 5 +++++ src/core/settings.cpp | 10 ++++++---- src/core/settings.h | 1 + src/core/system.cpp | 6 +++++- 8 files changed, 28 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e0ee7f745..f7099b747 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ A "BIOS" ROM image is required to to start the emulator and to play games. You c ## Latest News +- 2020/07/18: Widescreen hack enhancement added. - 2020/07/04: Vulkan renderer now available in libretro core. - 2020/07/02: Now available as a libretro core. - 2020/07/01: Lightgun support with custom crosshairs. diff --git a/src/core/cpu_core.h b/src/core/cpu_core.h index ce07632be..b097f4dd4 100644 --- a/src/core/cpu_core.h +++ b/src/core/cpu_core.h @@ -54,6 +54,9 @@ public: ALWAYS_INLINE TickCount GetDowncount() const { return m_downcount; } ALWAYS_INLINE void SetDowncount(TickCount downcount) { m_downcount = downcount; } + ALWAYS_INLINE const GTE::Core& GetCop2() const { return m_cop2; } + ALWAYS_INLINE GTE::Core& GetCop2() { return m_cop2; } + // Sets the PC and flushes the pipeline. void SetPC(u32 new_pc); diff --git a/src/core/gte.cpp b/src/core/gte.cpp index 10c68dbf6..e7fa80c7c 100644 --- a/src/core/gte.cpp +++ b/src/core/gte.cpp @@ -578,7 +578,10 @@ void Core::RTPS(const s16 V[3], u8 shift, bool lm, bool last) // MAC0=(((H*20000h/SZ3)+1)/2)*IR1+OFX, SX2=MAC0/10000h ;ScrX FIFO -400h..+3FFh // MAC0=(((H*20000h/SZ3)+1)/2)*IR2+OFY, SY2=MAC0/10000h ;ScrY FIFO -400h..+3FFh const s64 result = static_cast(ZeroExtend64(UNRDivide(m_regs.H, m_regs.SZ3))); - const s64 Sx = s64(result) * s64(m_regs.IR1) + s64(m_regs.OFX); + + // (4 / 3) / (16 / 9) -> 0.75 -> (3 / 4) + const s64 Sx = m_widescreen_hack ? ((((s64(result) * s64(m_regs.IR1)) * s64(3)) / s64(4)) + s64(m_regs.OFX)) : + (s64(result) * s64(m_regs.IR1) + s64(m_regs.OFX)); const s64 Sy = s64(result) * s64(m_regs.IR2) + s64(m_regs.OFY); CheckMACOverflow<0>(Sx); CheckMACOverflow<0>(Sy); diff --git a/src/core/gte.h b/src/core/gte.h index bd5a91e60..bdc37b295 100644 --- a/src/core/gte.h +++ b/src/core/gte.h @@ -21,6 +21,8 @@ public: Core(); ~Core(); + ALWAYS_INLINE void SetWidescreenHack(bool enabled) { m_widescreen_hack = enabled; } + void Initialize(); void Reset(); bool DoState(StateWrapper& sw); @@ -109,6 +111,7 @@ private: void Execute_GPF(Instruction inst); Regs m_regs = {}; + bool m_widescreen_hack = false; }; #include "gte.inl" diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 9349448e4..c0ddbdbad 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -8,6 +8,7 @@ #include "common/log.h" #include "common/string_util.h" #include "controller.h" +#include "cpu_core.h" #include "dma.h" #include "gpu.h" #include "host_display.h" @@ -345,6 +346,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("GPU", "TextureFiltering", false); si.SetBoolValue("GPU", "DisableInterlacing", false); si.SetBoolValue("GPU", "ForceNTSCTimings", false); + si.SetBoolValue("GPU", "WidescreenHack", false); si.SetStringValue("Display", "CropMode", Settings::GetDisplayCropModeName(Settings::DEFAULT_DISPLAY_CROP_MODE)); si.SetStringValue("Display", "AspectRatio", @@ -468,6 +470,9 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings) m_system->GetDMA()->SetMaxSliceTicks(m_settings.dma_max_slice_ticks); m_system->GetDMA()->SetHaltTicks(m_settings.dma_halt_ticks); + + if (m_settings.gpu_widescreen_hack != old_settings.gpu_widescreen_hack) + m_system->GetCPU()->GetCop2().SetWidescreenHack(m_settings.gpu_widescreen_hack); } bool controllers_updated = false; diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 03ed63600..afa5e3359 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -98,6 +98,7 @@ void Settings::Load(SettingsInterface& si) gpu_texture_filtering = si.GetBoolValue("GPU", "TextureFiltering", false); gpu_disable_interlacing = si.GetBoolValue("GPU", "DisableInterlacing", false); gpu_force_ntsc_timings = si.GetBoolValue("GPU", "ForceNTSCTimings", false); + gpu_widescreen_hack = si.GetBoolValue("GPU", "WidescreenHack", false); display_crop_mode = ParseDisplayCropMode( @@ -200,6 +201,7 @@ void Settings::Save(SettingsInterface& si) const si.SetBoolValue("GPU", "TextureFiltering", gpu_texture_filtering); si.SetBoolValue("GPU", "DisableInterlacing", gpu_disable_interlacing); si.SetBoolValue("GPU", "ForceNTSCTimings", gpu_force_ntsc_timings); + si.SetBoolValue("GPU", "WidescreenHack", gpu_widescreen_hack); si.SetStringValue("Display", "CropMode", GetDisplayCropModeName(display_crop_mode)); si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio)); @@ -437,10 +439,10 @@ const char* Settings::GetDisplayCropModeDisplayName(DisplayCropMode crop_mode) return s_display_crop_mode_display_names[static_cast(crop_mode)]; } -static std::array s_display_aspect_ratio_names = - {{"4:3", "16:9", "8:7", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}}; -static constexpr std::array s_display_aspect_ratio_values = - {{4.0f / 3.0f, 16.0f / 9.0f, 8.0f / 7.0f, 2.0f / 1.0f, 1.0f, -1.0f}}; +static std::array s_display_aspect_ratio_names = { + {"4:3", "16:9", "8:7", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}}; +static constexpr std::array s_display_aspect_ratio_values = { + {4.0f / 3.0f, 16.0f / 9.0f, 8.0f / 7.0f, 2.0f / 1.0f, 1.0f, -1.0f}}; std::optional Settings::ParseDisplayAspectRatio(const char* str) { diff --git a/src/core/settings.h b/src/core/settings.h index ad9067fcf..f78721989 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -88,6 +88,7 @@ struct Settings bool gpu_texture_filtering = false; bool gpu_disable_interlacing = false; bool gpu_force_ntsc_timings = false; + bool gpu_widescreen_hack = false; DisplayCropMode display_crop_mode = DisplayCropMode::None; DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::R4_3; bool display_linear_filtering = true; diff --git a/src/core/system.cpp b/src/core/system.cpp index 6f4012353..73ac290ef 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -242,7 +242,8 @@ bool System::Boot(const SystemBootParameters& params) bool System::InitializeComponents(bool force_software_renderer) { - if (!CreateGPU(force_software_renderer ? GPURenderer::Software : GetSettings().gpu_renderer)) + const Settings& settings = GetSettings(); + if (!CreateGPU(force_software_renderer ? GPURenderer::Software : settings.gpu_renderer)) return false; m_cpu->Initialize(m_bus.get()); @@ -261,6 +262,9 @@ bool System::InitializeComponents(bool force_software_renderer) m_spu->Initialize(this, m_dma.get(), m_interrupt_controller.get()); m_mdec->Initialize(this, m_dma.get()); + // load settings + m_cpu->GetCop2().SetWidescreenHack(settings.gpu_widescreen_hack); + UpdateThrottlePeriod(); return true; } From 8c3051ae147ec2fc17aa189c4dc1a35b908a59bb Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 00:25:19 +1000 Subject: [PATCH 05/12] SDL: Add widescreen hack option --- src/duckstation-sdl/sdl_host_interface.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/duckstation-sdl/sdl_host_interface.cpp b/src/duckstation-sdl/sdl_host_interface.cpp index 14b179cf5..7bdcfd126 100644 --- a/src/duckstation-sdl/sdl_host_interface.cpp +++ b/src/duckstation-sdl/sdl_host_interface.cpp @@ -845,6 +845,7 @@ void SDLHostInterface::DrawQuickSettingsMenu() settings_changed |= ImGui::MenuItem("Scaled Dithering", nullptr, &m_settings_copy.gpu_scaled_dithering); settings_changed |= ImGui::MenuItem("Texture Filtering", nullptr, &m_settings_copy.gpu_texture_filtering); settings_changed |= ImGui::MenuItem("Disable Interlacing", nullptr, &m_settings_copy.gpu_disable_interlacing); + settings_changed |= ImGui::MenuItem("Widescreen Hack", nullptr, &m_settings_copy.gpu_widescreen_hack); settings_changed |= ImGui::MenuItem("Display Linear Filtering", nullptr, &m_settings_copy.display_linear_filtering); settings_changed |= ImGui::MenuItem("Display Integer Scaling", nullptr, &m_settings_copy.display_integer_scaling); @@ -1296,6 +1297,7 @@ void SDLHostInterface::DrawSettingsWindow() settings_changed |= ImGui::Checkbox("Texture Filtering", &m_settings_copy.gpu_texture_filtering); settings_changed |= ImGui::Checkbox("Disable Interlacing", &m_settings_copy.gpu_disable_interlacing); settings_changed |= ImGui::Checkbox("Force NTSC Timings", &m_settings_copy.gpu_force_ntsc_timings); + settings_changed |= ImGui::Checkbox("Widescreen Hack", &m_settings_copy.gpu_widescreen_hack); } ImGui::EndTabItem(); From 1e6740762dd39273a26d60cc74022bb954830c8d Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 00:25:25 +1000 Subject: [PATCH 06/12] Qt: Add widescreen hack option --- src/duckstation-qt/gpusettingswidget.cpp | 6 ++++++ src/duckstation-qt/gpusettingswidget.ui | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/duckstation-qt/gpusettingswidget.cpp b/src/duckstation-qt/gpusettingswidget.cpp index dfa20df14..9cfdca20c 100644 --- a/src/duckstation-qt/gpusettingswidget.cpp +++ b/src/duckstation-qt/gpusettingswidget.cpp @@ -43,6 +43,8 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p QStringLiteral("GPU/ForceNTSCTimings")); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.linearTextureFiltering, QStringLiteral("GPU/TextureFiltering")); + SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.widescreenHack, + QStringLiteral("GPU/WidescreenHack")); connect(m_ui.resolutionScale, QOverload::of(&QComboBox::currentIndexChanged), this, &GPUSettingsWidget::updateScaledDitheringEnabled); @@ -113,6 +115,10 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p "Smooths out the blockyness of magnified textures on 3D object by using bilinear " "filtering. Will have a greater effect on higher resolution scales. Currently this option " "produces artifacts around objects in many games and needs further work. Only applies to the hardware renderers."); + dialog->registerWidgetHelp(m_ui.widescreenHack, "Widescreen Hack", "Unchecked", + "Scales vertex positions in screen-space to a widescreen aspect ratio, essentially " + "increasing the field of view from 4:3 to 16:9 in 3D games. For 2D games, or games which " + "use pre-rendered backgrounds, this enhancement will not work as expected."); } GPUSettingsWidget::~GPUSettingsWidget() = default; diff --git a/src/duckstation-qt/gpusettingswidget.ui b/src/duckstation-qt/gpusettingswidget.ui index 1f89c4a66..11d177c5d 100644 --- a/src/duckstation-qt/gpusettingswidget.ui +++ b/src/duckstation-qt/gpusettingswidget.ui @@ -163,6 +163,13 @@ + + + + Widescreen Hack + + + From 2702eb90bf0e54309120e2274d3d5e4afa993313 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 00:25:41 +1000 Subject: [PATCH 07/12] libretro: Add widescreen hack option --- src/duckstation-libretro/libretro_host_interface.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/duckstation-libretro/libretro_host_interface.cpp b/src/duckstation-libretro/libretro_host_interface.cpp index 687a8b1e1..892b8a73a 100644 --- a/src/duckstation-libretro/libretro_host_interface.cpp +++ b/src/duckstation-libretro/libretro_host_interface.cpp @@ -348,7 +348,7 @@ void LibretroHostInterface::OnSystemDestroyed() m_using_hardware_renderer = false; } -static std::array s_option_definitions = {{ +static std::array s_option_definitions = {{ {"Console.Region", "Console Region", "Determines which region/hardware to emulate. Auto-Detect will use the region of the disc inserted.", @@ -437,6 +437,12 @@ static std::array s_option_definitions = {{ "others will break.", {{"true", "Enabled"}, {"false", "Disabled"}}, "false"}, + {"GPU.WidescreenHack", + "Widescreen Hack", + "Increases the field of view from 4:3 to 16:9 in 3D games. For 2D games, or games which use pre-rendered " + "backgrounds, this enhancement will not work as expected.", + {{"true", "Enabled"}, {"false", "Disabled"}}, + "false"}, {"Display.CropMode", "Crop Mode", "Changes how much of the image is cropped. Some games display garbage in the overscan area which is typically " From 5c5ee17fa7559ff3c4046760d6050120760c4d1b Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 01:28:35 +1000 Subject: [PATCH 08/12] Qt: Fix widescreen hack option positioning --- src/duckstation-qt/gpusettingswidget.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/duckstation-qt/gpusettingswidget.ui b/src/duckstation-qt/gpusettingswidget.ui index 11d177c5d..43a299d77 100644 --- a/src/duckstation-qt/gpusettingswidget.ui +++ b/src/duckstation-qt/gpusettingswidget.ui @@ -163,7 +163,7 @@ - + Widescreen Hack From 389f452e102b326e3f1c1f0235ea349d17097232 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 01:33:36 +1000 Subject: [PATCH 09/12] Qt/GameListSettings: Use push button for all buttons --- src/duckstation-qt/gamelistsettingswidget.cpp | 10 +++++----- src/duckstation-qt/gamelistsettingswidget.ui | 20 ++++--------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/duckstation-qt/gamelistsettingswidget.cpp b/src/duckstation-qt/gamelistsettingswidget.cpp index 6eb3e5216..985568621 100644 --- a/src/duckstation-qt/gamelistsettingswidget.cpp +++ b/src/duckstation-qt/gamelistsettingswidget.cpp @@ -214,13 +214,13 @@ GameListSettingsWidget::GameListSettingsWidget(QtHostInterface* host_interface, m_ui.searchDirectoryList->setCurrentIndex({}); connect(m_ui.searchDirectoryList, &QTableView::clicked, this, &GameListSettingsWidget::onDirectoryListItemClicked); - connect(m_ui.addSearchDirectoryButton, &QToolButton::clicked, this, + connect(m_ui.addSearchDirectoryButton, &QPushButton::clicked, this, &GameListSettingsWidget::onAddSearchDirectoryButtonClicked); - connect(m_ui.removeSearchDirectoryButton, &QToolButton::clicked, this, + connect(m_ui.removeSearchDirectoryButton, &QPushButton::clicked, this, &GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked); - connect(m_ui.rescanAllGames, &QToolButton::clicked, this, &GameListSettingsWidget::onRescanAllGamesClicked); - connect(m_ui.scanForNewGames, &QToolButton::clicked, this, &GameListSettingsWidget::onScanForNewGamesClicked); - connect(m_ui.updateRedumpDatabase, &QToolButton::clicked, this, + connect(m_ui.rescanAllGames, &QPushButton::clicked, this, &GameListSettingsWidget::onRescanAllGamesClicked); + connect(m_ui.scanForNewGames, &QPushButton::clicked, this, &GameListSettingsWidget::onScanForNewGamesClicked); + connect(m_ui.updateRedumpDatabase, &QPushButton::clicked, this, &GameListSettingsWidget::onUpdateRedumpDatabaseButtonClicked); } diff --git a/src/duckstation-qt/gamelistsettingswidget.ui b/src/duckstation-qt/gamelistsettingswidget.ui index f12a5b987..f94080e60 100644 --- a/src/duckstation-qt/gamelistsettingswidget.ui +++ b/src/duckstation-qt/gamelistsettingswidget.ui @@ -41,7 +41,7 @@ - + Add @@ -49,13 +49,10 @@ :/icons/list-add.png:/icons/list-add.png - - Qt::ToolButtonTextBesideIcon - - + Remove @@ -63,9 +60,6 @@ :/icons/list-remove.png:/icons/list-remove.png - - Qt::ToolButtonTextBesideIcon - @@ -82,7 +76,7 @@ - + Scan New @@ -90,13 +84,10 @@ :/icons/folder-open.png:/icons/folder-open.png - - Qt::ToolButtonTextBesideIcon - - + Rescan All @@ -104,9 +95,6 @@ :/icons/view-refresh.png:/icons/view-refresh.png - - Qt::ToolButtonTextBesideIcon - From 1069e12bffcd65e0c238d07b71f5b92368ab569b Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 01:33:51 +1000 Subject: [PATCH 10/12] Qt: Add binding how-to text to hotkey page --- src/duckstation-qt/settingsdialog.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/duckstation-qt/settingsdialog.cpp b/src/duckstation-qt/settingsdialog.cpp index 5fbdac13a..d1ab694bb 100644 --- a/src/duckstation-qt/settingsdialog.cpp +++ b/src/duckstation-qt/settingsdialog.cpp @@ -22,9 +22,10 @@ static constexpr std::array(SettingsDialog::Catego "to populate the game list. Search directories can be added, removed, and switched to recursive/non-recursive. " "Additionally, the redump.org database can be downloaded or updated to provide titles for discs, as the discs " "themselves do not provide title information.", - "Hotkey Settings
Binding a hotkey allows you to trigger events such as a resetting, powering " - "off, taking screenshots or saving/loading states at the press of a key/controller button. Hotkey titles are " - "self-explanatory.", + "Hotkey Settings
Binding a hotkey allows you to trigger events such as a resetting or taking " + "screenshots at the press of a key/controller button. Hotkey titles are self-explanatory. Clicking a binding will " + "start a countdown, in which case you should press the key or controller button/axis you wish to bind. If no button " + "is pressed and the timer lapses, the binding will be unchanged. To clear a binding, right-click the button.", "Controller Settings
This page lets you choose the type of controller you wish to simulate for " "the console, and rebind the keys or host game controller buttons to your choosing. Clicking a binding will start a " "countdown, in which case you should press the key or controller button/axis you wish to bind. (For rumble, press " From 2853bf851ac91828c3ed86784103d4ea27a99cb3 Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Fri, 17 Jul 2020 18:43:30 -0700 Subject: [PATCH 11/12] Qt/GameListSettings: Use native path separators Fixes possible duplicate game list entries on Windows. --- src/duckstation-qt/gamelistsettingswidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/duckstation-qt/gamelistsettingswidget.cpp b/src/duckstation-qt/gamelistsettingswidget.cpp index 985568621..36732f132 100644 --- a/src/duckstation-qt/gamelistsettingswidget.cpp +++ b/src/duckstation-qt/gamelistsettingswidget.cpp @@ -248,7 +248,9 @@ void GameListSettingsWidget::onDirectoryListItemClicked(const QModelIndex& index void GameListSettingsWidget::addSearchDirectory(QWidget* parent_widget) { - QString dir = QFileDialog::getExistingDirectory(parent_widget, tr("Select Search Directory")); + QString dir = + QDir::toNativeSeparators(QFileDialog::getExistingDirectory(parent_widget, tr("Select Search Directory"))); + if (dir.isEmpty()) return; From 39917117d2fc1fd9be5f666e20f3d518b21acfc6 Mon Sep 17 00:00:00 2001 From: Elizabeth Date: Sat, 18 Jul 2020 13:21:13 -0400 Subject: [PATCH 12/12] Disable Interlacing description "Unchecked" As noted by Kurayami6, Disable Interlacing should show "Unchecked" as the default option for this enhancement. --- src/duckstation-qt/gpusettingswidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/duckstation-qt/gpusettingswidget.cpp b/src/duckstation-qt/gpusettingswidget.cpp index 9cfdca20c..c1f42ceac 100644 --- a/src/duckstation-qt/gpusettingswidget.cpp +++ b/src/duckstation-qt/gpusettingswidget.cpp @@ -73,7 +73,7 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p "Some games display content in the overscan area, or use it for screen effects and may " "not display correctly with the All Borders setting. Only Overscan offers a good " "compromise between stability and hiding black borders."); - dialog->registerWidgetHelp(m_ui.disableInterlacing, "Disable Interlacing (force progressive render/scan)", "Checked", + dialog->registerWidgetHelp(m_ui.disableInterlacing, "Disable Interlacing (force progressive render/scan)", "Unchecked", "Forces the display of frames to progressive mode. This only affects the displayed image, " "the console will be unaware of the setting. If the game is internally producing " "interlaced frames, this option may not have any effect. Usually safe to enable.");