diff --git a/bin/resources/GameIndex.yaml b/bin/resources/GameIndex.yaml index 7840bde349..ac574a5ab3 100644 --- a/bin/resources/GameIndex.yaml +++ b/bin/resources/GameIndex.yaml @@ -14515,8 +14515,8 @@ SLES-50879: name: "Paris-Dakar 2" region: "PAL-M5" compat: 5 - gameFixes: - - FpuNegDivHack # Fixes sky being shown over the 3D. + roundModes: + eeDivRoundMode: 1 # Fixes sky being shown over the 3D. SLES-50880: name: "BMX XXX" region: "PAL-M4" @@ -16840,8 +16840,8 @@ SLES-51897: name-sort: "Simpsons, The - Hit & Run" region: "PAL-M4" compat: 5 - gameFixes: - - FpuNegDivHack # Lens flare appears even when behind objects. + roundModes: + eeDivRoundMode: 1 # Lens flare appears even when behind objects. gsHWFixes: autoFlush: 2 # Fixes missing lens flare. SLES-51903: @@ -22037,8 +22037,8 @@ SLES-53804: SLES-53805: name: "Cocoto Funfair" region: "PAL-M5" - gameFixes: - - FpuNegDivHack # Fixes the cursor not being visible. + roundModes: + eeDivRoundMode: 1 # Fixes the cursor not being visible. SLES-53809: name: "K-1 Premium Dynamite!!" region: "PAL-E" @@ -23998,8 +23998,8 @@ SLES-54549: name: "Crazy Frog Racer 2" region: "PAL-M5" compat: 5 - gameFixes: - - FpuNegDivHack # Fixes black fade effects and some overlays texts in the menus. + roundModes: + eeDivRoundMode: 1 # Fixes black fade effects and some overlays texts in the menus. gsHWFixes: mipmap: 2 # Mipmap + trilinear, improves road and grass textures to match sw renderer. trilinearFiltering: 1 @@ -25716,8 +25716,8 @@ SLES-55170: SLES-55172: name: "Code Lyoko - Quest for Infinity" region: "PAL-M4" - gameFixes: - - FpuNegDivHack # Fixes missing texts on in-game textboxes. + roundModes: + eeDivRoundMode: 1 # Fixes missing texts on in-game textboxes. gsHWFixes: deinterlace: 9 # Game requires adaptive bff de-interlacing instead of auto for the UI at native. halfPixelOffset: 1 # Reduces ghosting effects. @@ -27312,8 +27312,7 @@ SLKA-15018: region: "NTSC-K" roundModes: eeRoundMode: 1 # Fixes camera issue. - gameFixes: - - FpuNegDivHack # Fixes target loss issue. + eeDivRoundMode: 1 # Fixes target loss issue. SLKA-15019: name: "F1 Career Challenge" region: "NTSC-K" @@ -27957,8 +27956,7 @@ SLKA-25165: region: "NTSC-K" roundModes: eeRoundMode: 1 # Fixes camera issue. - gameFixes: - - FpuNegDivHack # Fixes target loss issue. + eeDivRoundMode: 1 # Fixes target loss issue. SLKA-25166: name: "Sengoku Musou" region: "NTSC-K" @@ -28565,8 +28563,7 @@ SLKA-25314: region: "NTSC-K" roundModes: eeRoundMode: 1 # Fixes camera issue. - gameFixes: - - FpuNegDivHack # Fixes target loss issue. + eeDivRoundMode: 1 # Fixes target loss issue. SLKA-25315: name: "NBA Live 06" region: "NTSC-K" @@ -51852,8 +51849,8 @@ SLPS-25430: name-sort: るぱんさんせい ころんぶすのいさんはしゅにそまる name-en: "Lupin III - Columbus no Isan wa Akenisomaru" region: "NTSC-J" - gameFixes: - - FpuNegDivHack # Fixes game softlock after prison level. + roundModes: + eeDivRoundMode: 1 # Fixes game softlock after prison level. SLPS-25431: name: "Bokujou Monogatari - Oh! Wonderful Life" region: "NTSC-J" @@ -52581,8 +52578,7 @@ SLPS-25569: region: "NTSC-J" roundModes: eeRoundMode: 1 # Fixes camera issue. - gameFixes: - - FpuNegDivHack # Fixes target loss issue. + eeDivRoundMode: 1 # Fixes target loss issue. SLPS-25570: name: キノの旅II name-sort: きののたびII @@ -53487,8 +53483,7 @@ SLPS-25718: compat: 5 roundModes: eeRoundMode: 1 # Fix camera issue. - gameFixes: - - FpuNegDivHack # Fix target loss issue. + eeDivRoundMode: 1 # Fix target loss issue. patches: F616C207: content: |- @@ -54500,8 +54495,8 @@ SLPS-25914: name-sort: きどうせんしがんだむ ぎれんのやぼう あくしずのきょういV name-en: "Kidou Senshi Gundam - Giren no Yabou - Axis no Kyoui V" region: "NTSC-J" - gameFixes: - - FpuNegDivHack + roundModes: + eeDivRoundMode: 1 SLPS-25915: name: ザ・キング・オブ・ファイターズ 2002 アンリミテッドマッチ name-sort: ざ・きんぐ・おぶ・ふぁいたーず 2002 あんりみてっどまっち @@ -54660,8 +54655,8 @@ SLPS-25959: name-sort: きどうせんしがんだむ ぎれんのやぼう あくしずのきょういV GUNDAM 30th ANNIVERSARY COLLECTION name-en: "Kidou Senshi Gundam - Giren no Yabou - Axis no Kyoui V" region: "NTSC-J" - gameFixes: - - FpuNegDivHack + roundModes: + eeDivRoundMode: 1 SLPS-25961: name: 機動戦士ガンダムSEED DESTINY 連合 vs. Z.A.F.T. II plus GUNDAM 30th ANNIVERSARY COLLECTION name-sort: きどうせんしがんだむSEED DESTINY れんごう vs. Z.A.F.T. II plus GUNDAM 30th ANNIVERSARY COLLECTION @@ -54669,8 +54664,7 @@ SLPS-25961: region: "NTSC-K" roundModes: eeRoundMode: 1 # Fixes camera issue. - gameFixes: - - FpuNegDivHack # Fixes target loss issue. + eeDivRoundMode: 1 # Fixes target loss issue. SLPS-25971: name: "NeoGeo Online Collection Vol. 2 - Bakumatsu Roman - Gekka no Kenshi 1, 2" region: "NTSC-J" @@ -55453,8 +55447,7 @@ SLPS-73269: region: "NTSC-K" roundModes: eeRoundMode: 1 # Fixes camera issue. - gameFixes: - - FpuNegDivHack # Fixes target loss issue. + eeDivRoundMode: 1 # Fixes target loss issue. SLPS-73270: name: "Super Robot Taisen Z [PS2 The Best]" region: "NTSC-J" @@ -58550,8 +58543,8 @@ SLUS-20624: name-sort: "Simpsons, The - Hit & Run" region: "NTSC-U" compat: 5 - gameFixes: - - FpuNegDivHack # Lens flare appears even when behind objects. + roundModes: + eeDivRoundMode: 1 # Lens flare appears even when behind objects. gsHWFixes: autoFlush: 2 # Fixes missing lens flare. SLUS-20625: @@ -64126,8 +64119,8 @@ SLUS-21634: name: "Crazy Frog Racer 2" region: "NTSC-U" compat: 5 - gameFixes: - - FpuNegDivHack # Fixes black fade effects and some overlays texts in the menus. + roundModes: + eeDivRoundMode: 1 # Fixes black fade effects and some overlays texts in the menus. gsHWFixes: mipmap: 2 # Mipmap + trilinear, improves road and grass textures to match sw renderer. trilinearFiltering: 1 @@ -64672,8 +64665,8 @@ SLUS-21743: name: "Code Lyoko - Quest for Infinity" region: "NTSC-U" compat: 5 - gameFixes: - - FpuNegDivHack # Fixes missing texts on in-game textboxes. + roundModes: + eeDivRoundMode: 1 # Fixes missing texts on in-game textboxes. gsHWFixes: deinterlace: 9 # Game requires adaptive bff de-interlacing instead of auto for the UI at native. halfPixelOffset: 1 # Reduces ghosting effects. diff --git a/pcsx2-qt/Settings/AdvancedSettingsWidget.cpp b/pcsx2-qt/Settings/AdvancedSettingsWidget.cpp index 9af5e5cdc6..773ac2d04f 100644 --- a/pcsx2-qt/Settings/AdvancedSettingsWidget.cpp +++ b/pcsx2-qt/Settings/AdvancedSettingsWidget.cpp @@ -29,9 +29,10 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget* SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vu1Recompiler, "EmuCore/CPU/Recompiler", "EnableVU1", true); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.vuFlagHack, "EmuCore/Speedhacks", "vuFlagHack", true); - SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeRoundingMode, "EmuCore/CPU", "FPU.Roundmode", 3); - SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.vu0RoundingMode, "EmuCore/CPU", "VU0.Roundmode", 3); - SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.vu1RoundingMode, "EmuCore/CPU", "VU1.Roundmode", 3); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeRoundingMode, "EmuCore/CPU", "FPU.Roundmode", static_cast(FPRoundMode::ChopZero)); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.eeDivRoundingMode, "EmuCore/CPU", "FPUDiv.Roundmode", static_cast(FPRoundMode::Nearest)); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.vu0RoundingMode, "EmuCore/CPU", "VU0.Roundmode", static_cast(FPRoundMode::ChopZero)); + SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.vu1RoundingMode, "EmuCore/CPU", "VU1.Roundmode", static_cast(FPRoundMode::ChopZero)); if (m_dialog->isPerGameSettings()) { m_ui.eeClampMode->insertItem(0, tr("Use Global Setting [%1]").arg(m_ui.eeClampMode->itemText(getGlobalClampingModeIndex(-1)))); @@ -58,6 +59,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget* dialog->registerWidgetHelp(m_ui.eeRoundingMode, tr("Rounding Mode"), tr("Chop/Zero (Default)"), tr("Changes how PCSX2 handles rounding while emulating the Emotion Engine's Floating Point Unit (EE FPU). " "Because the various FPUs in the PS2 are non-compliant with international standards, some games may need different modes to do math correctly. The default value handles the vast majority of games; modifying this setting when a game is not having a visible problem can cause instability.")); + dialog->registerWidgetHelp(m_ui.eeDivRoundingMode, tr("Division Rounding Mode"), tr("Nearest (Default)"), tr("Determines how the results of floating-point division is rounded. Some games need specific settings; modifying this setting when a game is not having a visible problem can cause instability.")); dialog->registerWidgetHelp(m_ui.eeClampMode, tr("Clamping Mode"), tr("Normal (Default)"), tr("Changes how PCSX2 handles keeping floats in a standard x86 range. " "The default value handles the vast majority of games; modifying this setting when a game is not having a visible problem can cause instability.")); diff --git a/pcsx2-qt/Settings/AdvancedSettingsWidget.ui b/pcsx2-qt/Settings/AdvancedSettingsWidget.ui index e63d6abbf5..d2d859f7bd 100644 --- a/pcsx2-qt/Settings/AdvancedSettingsWidget.ui +++ b/pcsx2-qt/Settings/AdvancedSettingsWidget.ui @@ -95,13 +95,44 @@ + + + Division Rounding Mode: + + + + + + + + Nearest (Default) + + + + + Negative + + + + + Positive + + + + + Chop/Zero + + + + + Clamping Mode: - + @@ -125,7 +156,7 @@ - + diff --git a/pcsx2-qt/Settings/GameFixSettingsWidget.cpp b/pcsx2-qt/Settings/GameFixSettingsWidget.cpp index 9e30f1f42b..da1e4ded15 100644 --- a/pcsx2-qt/Settings/GameFixSettingsWidget.cpp +++ b/pcsx2-qt/Settings/GameFixSettingsWidget.cpp @@ -18,7 +18,6 @@ GameFixSettingsWidget::GameFixSettingsWidget(SettingsWindow* dialog, QWidget* pa m_ui.setupUi(this); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.FpuMulHack, "EmuCore/Gamefixes", "FpuMulHack", false); - SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.FpuNegDivHack, "EmuCore/Gamefixes", "FpuNegDivHack", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.GoemonTlbHack, "EmuCore/Gamefixes", "GoemonTlbHack", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.SoftwareRendererFMVHack, "EmuCore/Gamefixes", "SoftwareRendererFMVHack", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.SkipMPEGHack, "EmuCore/Gamefixes", "SkipMPEGHack", false); @@ -38,7 +37,6 @@ GameFixSettingsWidget::GameFixSettingsWidget(SettingsWindow* dialog, QWidget* pa SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.BlitInternalFPSHack, "EmuCore/Gamefixes", "BlitInternalFPSHack", false); dialog->registerWidgetHelp(m_ui.FpuMulHack, tr("FPU Multiply Hack"), tr("Unchecked"), tr("For Tales of Destiny.")); - dialog->registerWidgetHelp(m_ui.FpuNegDivHack, tr("FPU Negative Divide Hack"), tr("Unchecked"), tr("For Gundam Games.")); dialog->registerWidgetHelp(m_ui.GoemonTlbHack, tr("Preload TLB Hack"), tr("Unchecked"), tr("To avoid TLB miss on Goemon.")); dialog->registerWidgetHelp(m_ui.SoftwareRendererFMVHack, tr("Use Software Renderer For FMVs"), tr("Unchecked"), tr("Needed for some games with complex FMV rendering.")); dialog->registerWidgetHelp(m_ui.SkipMPEGHack, tr("Skip MPEG Hack"), tr("Unchecked"), tr("Skips videos/FMVs in games to avoid game hanging/freezes.")); diff --git a/pcsx2-qt/Settings/GameFixSettingsWidget.ui b/pcsx2-qt/Settings/GameFixSettingsWidget.ui index 1439c3cd4d..224f737c52 100644 --- a/pcsx2-qt/Settings/GameFixSettingsWidget.ui +++ b/pcsx2-qt/Settings/GameFixSettingsWidget.ui @@ -56,13 +56,6 @@ Game Fixes (NOT recommended to change globally) - - - - FPU Negative Divide Hack - - - diff --git a/pcsx2/Config.h b/pcsx2/Config.h index d7293f43c7..c9b47ed2f8 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -153,7 +153,6 @@ enum GamefixId GamefixId_FIRST = 0, Fix_FpuMultiply = GamefixId_FIRST, - Fix_FpuNegDiv, Fix_GoemonTlbMiss, Fix_SoftwareRendererFMV, Fix_SkipMpeg, @@ -539,6 +538,7 @@ struct Pcsx2Config RecompilerOptions Recompiler; FPControlRegister FPUFPCR; + FPControlRegister FPUDivFPCR; FPControlRegister VU0FPCR; FPControlRegister VU1FPCR; @@ -899,7 +899,6 @@ struct Pcsx2Config BITFIELD32() bool FpuMulHack : 1, // Tales of Destiny hangs. - FpuNegDivHack : 1, // Gundam games messed up camera-view. GoemonTlbHack : 1, // Gomeon tlb miss hack. The game need to access unmapped virtual address. Instead to handle it as exception, tlb are preloaded at startup SoftwareRendererFMVHack : 1, // Switches to software renderer for FMVs SkipMPEGHack : 1, // Skips MPEG videos (Katamari and other games need this) @@ -1264,7 +1263,6 @@ namespace EmuFolders //------------ SPECIAL GAME FIXES!!! --------------- #define CHECK_VUADDSUBHACK (EmuConfig.Gamefixes.VuAddSubHack) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate. #define CHECK_FPUMULHACK (EmuConfig.Gamefixes.FpuMulHack) // Special Fix for Tales of Destiny hangs. -#define CHECK_FPUNEGDIVHACK (EmuConfig.Gamefixes.FpuNegDivHack) // Special Fix for Gundam games messed up camera-view. #define CHECK_XGKICKHACK (EmuConfig.Gamefixes.XgKickHack) // Special Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics. #define CHECK_EETIMINGHACK (EmuConfig.Gamefixes.EETimingHack) // Fix all scheduled events to happen in 1 cycle. #define CHECK_INSTANTDMAHACK (EmuConfig.Gamefixes.InstantDMAHack) // Attempt to finish DMA's instantly, useful for games which rely on cache emulation. diff --git a/pcsx2/Docs/gamedb-schema.json b/pcsx2/Docs/gamedb-schema.json index 5223a21c51..9a41afbaa2 100644 --- a/pcsx2/Docs/gamedb-schema.json +++ b/pcsx2/Docs/gamedb-schema.json @@ -40,6 +40,11 @@ "minimum": 0, "maximum": 3 }, + "eeDivRoundMode": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, "vuRoundMode": { "type": "integer", "minimum": 0, @@ -97,7 +102,6 @@ "DMABusyHack", "EETimingHack", "FpuMulHack", - "FpuNegDivHack", "GIFFIFOHack", "GoemonTlbHack", "IbitHack", diff --git a/pcsx2/GameDatabase.cpp b/pcsx2/GameDatabase.cpp index 26cab1e021..46af1b52fc 100644 --- a/pcsx2/GameDatabase.cpp +++ b/pcsx2/GameDatabase.cpp @@ -120,6 +120,15 @@ void GameDatabase::parseAndInsert(const std::string_view& serial, const c4::yml: else Console.Error(fmt::format("[GameDB] Invalid EE round mode '{}', specified for serial: '{}'.", eeVal, serial)); } + if (node["roundModes"].has_child("eeDivRoundMode")) + { + int eeVal = -1; + node["roundModes"]["eeDivRoundMode"] >> eeVal; + if (eeVal >= 0 && eeVal < static_cast(FPRoundMode::MaxCount)) + gameEntry.eeDivRoundMode = static_cast(eeVal); + else + Console.Error(fmt::format("[GameDB] Invalid EE division round mode '{}', specified for serial: '{}'.", eeVal, serial)); + } if (node["roundModes"].has_child("vuRoundMode")) { int vuVal = -1; @@ -447,6 +456,19 @@ void GameDatabaseSchema::GameEntry::applyGameFixes(Pcsx2Config& config, bool app } } + if (eeDivRoundMode < FPRoundMode::MaxCount) + { + if (applyAuto) + { + Console.WriteLn("(GameDB) Changing EE/FPU divison roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast(eeDivRoundMode)]); + config.Cpu.FPUDivFPCR.SetRoundMode(eeDivRoundMode); + } + else + { + Console.Warning("[GameDB] Skipping changing EE/FPU roundmode to %d [%s]", eeRoundMode, s_round_modes[static_cast(eeRoundMode)]); + } + } + if (vu0RoundMode < FPRoundMode::MaxCount) { if (applyAuto) diff --git a/pcsx2/GameDatabase.h b/pcsx2/GameDatabase.h index 8b24b20587..b9f73f213f 100644 --- a/pcsx2/GameDatabase.h +++ b/pcsx2/GameDatabase.h @@ -93,6 +93,7 @@ namespace GameDatabaseSchema std::string region; Compatibility compat = Compatibility::Unknown; FPRoundMode eeRoundMode = FPRoundMode::MaxCount; + FPRoundMode eeDivRoundMode = FPRoundMode::MaxCount; FPRoundMode vu0RoundMode = FPRoundMode::MaxCount; FPRoundMode vu1RoundMode = FPRoundMode::MaxCount; ClampMode eeClampMode = ClampMode::Undefined; diff --git a/pcsx2/ImGui/FullscreenUI.cpp b/pcsx2/ImGui/FullscreenUI.cpp index acdd258326..74fe09ad22 100644 --- a/pcsx2/ImGui/FullscreenUI.cpp +++ b/pcsx2/ImGui/FullscreenUI.cpp @@ -4450,7 +4450,12 @@ void FullscreenUI::DrawAdvancedSettingsPage() DrawIntListSetting(bsi, FSUI_CSTR("Rounding Mode"), FSUI_CSTR("Determines how the results of floating-point operations are rounded. Some games need specific settings."), - "EmuCore/CPU", "FPU.Roundmode", 3, ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true); + "EmuCore/CPU", "FPU.Roundmode", static_cast(FPRoundMode::ChopZero), ee_rounding_mode_settings, + std::size(ee_rounding_mode_settings), true); + DrawIntListSetting(bsi, FSUI_CSTR("Division Rounding Mode"), + FSUI_CSTR("Determines how the results of floating-point division is rounded. Some games need specific settings."), + "EmuCore/CPU", "FPUDiv.Roundmode", static_cast(FPRoundMode::Nearest), + ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true); DrawClampingModeSetting(bsi, FSUI_CSTR("Clamping Mode"), FSUI_CSTR("Determines how out-of-range floating point numbers are handled. Some games need specific settings."), -1); @@ -4470,12 +4475,14 @@ void FullscreenUI::DrawAdvancedSettingsPage() MenuHeading(FSUI_CSTR("Vector Units")); DrawIntListSetting(bsi, FSUI_CSTR("VU0 Rounding Mode"), FSUI_CSTR("Determines how the results of floating-point operations are rounded. Some games need specific settings."), - "EmuCore/CPU", "VU0.Roundmode", 3, ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true); + "EmuCore/CPU", "VU0.Roundmode", static_cast(FPRoundMode::ChopZero), + ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true); DrawClampingModeSetting(bsi, FSUI_CSTR("VU0 Clamping Mode"), FSUI_CSTR("Determines how out-of-range floating point numbers are handled. Some games need specific settings."), 0); DrawIntListSetting(bsi, FSUI_CSTR("VU1 Rounding Mode"), FSUI_CSTR("Determines how the results of floating-point operations are rounded. Some games need specific settings."), - "EmuCore/CPU", "VU1.Roundmode", 3, ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true); + "EmuCore/CPU", "VU1.Roundmode", static_cast(FPRoundMode::ChopZero), + ee_rounding_mode_settings, std::size(ee_rounding_mode_settings), true); DrawClampingModeSetting(bsi, FSUI_CSTR("VU1 Clamping Mode"), FSUI_CSTR("Determines how out-of-range floating point numbers are handled. Some games need specific settings."), 1); DrawToggleSetting(bsi, FSUI_CSTR("Enable VU0 Recompiler (Micro Mode)"), @@ -4595,7 +4602,6 @@ void FullscreenUI::DrawGameFixesSettingsPage() FSUI_CSTR("Game fixes should not be modified unless you are aware of what each option does and the implications of doing so."), false, false, ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT_NO_SUMMARY); - DrawToggleSetting(bsi, FSUI_CSTR("FPU Negative Div Hack"), FSUI_CSTR("For Gundam games."), "EmuCore/Gamefixes", "FpuNegDivHack", false); DrawToggleSetting(bsi, FSUI_CSTR("FPU Multiply Hack"), FSUI_CSTR("For Tales of Destiny."), "EmuCore/Gamefixes", "FpuMulHack", false); DrawToggleSetting(bsi, FSUI_CSTR("Use Software Renderer For FMVs"), FSUI_CSTR("Needed for some games with complex FMV rendering."), "EmuCore/Gamefixes", "SoftwareRendererFMVHack", false); diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index e05441565e..c25949fb76 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -501,12 +501,17 @@ bool Pcsx2Config::CpuOptions::operator!=(const CpuOptions& right) const bool Pcsx2Config::CpuOptions::operator==(const CpuOptions& right) const { - return OpEqu(FPUFPCR) && OpEqu(VU0FPCR) && OpEqu(VU1FPCR) && OpEqu(AffinityControlMode) && OpEqu(Recompiler); + return OpEqu(FPUFPCR) && OpEqu(FPUDivFPCR) && OpEqu(VU0FPCR) && OpEqu(VU1FPCR) && OpEqu(AffinityControlMode) && OpEqu(Recompiler); } Pcsx2Config::CpuOptions::CpuOptions() { FPUFPCR = DEFAULT_FPU_FP_CONTROL_REGISTER; + + // Rounding defaults to nearest to match old behavior. + // TODO: Make it default to the same as the rest of the FPU operations, at some point. + FPUDivFPCR = FPControlRegister(DEFAULT_FPU_FP_CONTROL_REGISTER).SetRoundMode(FPRoundMode::Nearest); + VU0FPCR = DEFAULT_VU_FP_CONTROL_REGISTER; VU1FPCR = DEFAULT_VU_FP_CONTROL_REGISTER; AffinityControlMode = 0; @@ -536,6 +541,7 @@ void Pcsx2Config::CpuOptions::LoadSave(SettingsWrapper& wrap) }; read_fpcr(FPUFPCR, "FPU"); + read_fpcr(FPUDivFPCR, "FPUDiv"); read_fpcr(VU0FPCR, "VU0"); read_fpcr(VU1FPCR, "VU1"); @@ -1284,7 +1290,6 @@ bool Pcsx2Config::DEV9Options::HostEntry::operator!=(const HostEntry& right) con static const char* const tbl_GamefixNames[] = { "FpuMul", - "FpuNegDiv", "GoemonTlb", "SoftwareRendererFMV", "SkipMPEG", @@ -1328,7 +1333,6 @@ void Pcsx2Config::GamefixOptions::Set(GamefixId id, bool enabled) // clang-format off case Fix_VuAddSub: VuAddSubHack = enabled; break; case Fix_FpuMultiply: FpuMulHack = enabled; break; - case Fix_FpuNegDiv: FpuNegDivHack = enabled; break; case Fix_XGKick: XgKickHack = enabled; break; case Fix_EETiming: EETimingHack = enabled; break; case Fix_InstantDMA: InstantDMAHack = enabled; break; @@ -1367,7 +1371,6 @@ bool Pcsx2Config::GamefixOptions::Get(GamefixId id) const // clang-format off case Fix_VuAddSub: return VuAddSubHack; case Fix_FpuMultiply: return FpuMulHack; - case Fix_FpuNegDiv: return FpuNegDivHack; case Fix_XGKick: return XgKickHack; case Fix_EETiming: return EETimingHack; case Fix_InstantDMA: return InstantDMAHack; @@ -1396,7 +1399,6 @@ void Pcsx2Config::GamefixOptions::LoadSave(SettingsWrapper& wrap) SettingsWrapBitBool(VuAddSubHack); SettingsWrapBitBool(FpuMulHack); - SettingsWrapBitBool(FpuNegDivHack); SettingsWrapBitBool(XgKickHack); SettingsWrapBitBool(EETimingHack); SettingsWrapBitBool(InstantDMAHack); diff --git a/pcsx2/x86/iFPU.cpp b/pcsx2/x86/iFPU.cpp index aacd034ab5..f4bf4de5e4 100644 --- a/pcsx2/x86/iFPU.cpp +++ b/pcsx2/x86/iFPU.cpp @@ -1102,32 +1102,8 @@ void recDIV_S_xmm(int info) int t0reg = _allocTempXMMreg(XMMT_FPS); //Console.WriteLn("DIV"); - if (CHECK_FPUNEGDIVHACK) - { - if (EmuConfig.Cpu.FPUFPCR.GetRoundMode() != FPRoundMode::NegativeInfinity) - { - // Set roundmode to nearest since it isn't already - //Console.WriteLn("div to negative inf"); - - roundmode_neg = EmuConfig.Cpu.FPUFPCR; - roundmode_neg.SetRoundMode(FPRoundMode::NegativeInfinity); - xLDMXCSR(ptr32[&roundmode_neg.bitmask]); - roundmodeFlag = true; - } - } - else - { - if (EmuConfig.Cpu.FPUFPCR.GetRoundMode() != FPRoundMode::Nearest) - { - // Set roundmode to nearest since it isn't already - //Console.WriteLn("div to nearest"); - - roundmode_nearest = EmuConfig.Cpu.FPUFPCR; - roundmode_nearest.SetRoundMode(FPRoundMode::Nearest); - xLDMXCSR(ptr32[&roundmode_nearest.bitmask]); - roundmodeFlag = true; - } - } + if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) + xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUDivFPCR.bitmask]); switch (info & (PROCESS_EE_S | PROCESS_EE_T)) { @@ -1190,8 +1166,10 @@ void recDIV_S_xmm(int info) recDIVhelper2(EEREC_D, t0reg); break; } - if (roundmodeFlag) + + if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); + _freeXMMreg(t0reg); } @@ -1890,10 +1868,9 @@ void recRSQRThelper2(int regd, int t0reg) // Preforms the RSQRT function when re void recRSQRT_S_xmm(int info) { EE::Profiler.EmitOp(eeOpcode::RSQRT_F); - // iFPUd (Full mode) sets roundmode to nearest for rSQRT. - // Should this do the same, or should Full mode leave roundmode alone? --air - int t0reg = _allocTempXMMreg(XMMT_FPS); + // RSQRT doesn't change the round mode, because RSQRTSS ignores the rounding mode in MXCSR. + const int t0reg = _allocTempXMMreg(XMMT_FPS); //Console.WriteLn("FPU: RSQRT"); switch (info & (PROCESS_EE_S | PROCESS_EE_T)) diff --git a/pcsx2/x86/iFPUd.cpp b/pcsx2/x86/iFPUd.cpp index 62f5510bad..84f8d41b5a 100644 --- a/pcsx2/x86/iFPUd.cpp +++ b/pcsx2/x86/iFPUd.cpp @@ -657,35 +657,10 @@ alignas(16) static FPControlRegister roundmode_nearest, roundmode_neg; void recDIV_S_xmm(int info) { EE::Profiler.EmitOp(eeOpcode::DIV_F); - bool roundmodeFlag = false; //Console.WriteLn("DIV"); - if (CHECK_FPUNEGDIVHACK) - { - if (EmuConfig.Cpu.FPUFPCR.GetRoundMode() != FPRoundMode::NegativeInfinity) - { - // Set roundmode to nearest since it isn't already - //Console.WriteLn("div to negative inf"); - - roundmode_neg = EmuConfig.Cpu.FPUFPCR; - roundmode_neg.SetRoundMode(FPRoundMode::NegativeInfinity); - xLDMXCSR(ptr32[&roundmode_neg.bitmask]); - roundmodeFlag = true; - } - } - else - { - if (EmuConfig.Cpu.FPUFPCR.GetRoundMode() != FPRoundMode::Nearest) - { - // Set roundmode to nearest since it isn't already - //Console.WriteLn("div to nearest"); - - roundmode_nearest = EmuConfig.Cpu.FPUFPCR; - roundmode_nearest.SetRoundMode(FPRoundMode::Nearest); - xLDMXCSR(ptr32[&roundmode_nearest.bitmask]); - roundmodeFlag = true; - } - } + if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) + xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUDivFPCR.bitmask]); int sreg, treg; @@ -698,8 +673,9 @@ void recDIV_S_xmm(int info) xMOVSS(xRegisterSSE(EEREC_D), xRegisterSSE(sreg)); - if (roundmodeFlag) + if (EmuConfig.Cpu.FPUFPCR.bitmask != EmuConfig.Cpu.FPUDivFPCR.bitmask) xLDMXCSR(ptr32[&EmuConfig.Cpu.FPUFPCR.bitmask]); + _freeXMMreg(sreg); _freeXMMreg(treg); }