2024-07-30 11:42:36 +00:00
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
2021-12-13 12:12:54 +00:00
# include <QtWidgets/QMessageBox>
# include <algorithm>
2022-11-23 13:20:49 +00:00
# include "AdvancedSettingsWidget.h"
2022-09-07 09:20:50 +00:00
# include "QtHost.h"
2021-12-13 12:12:54 +00:00
# include "QtUtils.h"
# include "SettingWidgetBinder.h"
2023-10-14 08:45:09 +00:00
# include "SettingsWindow.h"
2021-12-13 12:12:54 +00:00
2023-10-14 08:45:09 +00:00
AdvancedSettingsWidget : : AdvancedSettingsWidget ( SettingsWindow * dialog , QWidget * parent )
2022-12-28 04:44:34 +00:00
: QWidget ( parent )
, m_dialog ( dialog )
2021-12-13 12:12:54 +00:00
{
2022-02-15 14:29:18 +00:00
SettingsInterface * sif = dialog - > getSettingsInterface ( ) ;
2021-12-13 12:12:54 +00:00
m_ui . setupUi ( this ) ;
2022-02-15 14:29:18 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . eeRecompiler , " EmuCore/CPU/Recompiler " , " EnableEE " , true ) ;
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . eeCache , " EmuCore/CPU/Recompiler " , " EnableEECache " , false ) ;
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . eeINTCSpinDetection , " EmuCore/Speedhacks " , " IntcStat " , true ) ;
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . eeWaitLoopDetection , " EmuCore/Speedhacks " , " WaitLoop " , true ) ;
2022-10-29 03:39:19 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . eeFastmem , " EmuCore/CPU/Recompiler " , " EnableFastmem " , true ) ;
2023-01-25 15:13:55 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . pauseOnTLBMiss , " EmuCore/CPU/Recompiler " , " PauseOnTLBMiss " , false ) ;
2024-04-29 05:33:58 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . extraMemory , " EmuCore/CPU " , " ExtraMemory " , false ) ;
2021-12-13 12:12:54 +00:00
2022-02-15 14:29:18 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . vu0Recompiler , " EmuCore/CPU/Recompiler " , " EnableVU0 " , true ) ;
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . vu1Recompiler , " EmuCore/CPU/Recompiler " , " EnableVU1 " , true ) ;
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . vuFlagHack , " EmuCore/Speedhacks " , " vuFlagHack " , true ) ;
2024-06-15 13:34:50 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . instantVU1 , " EmuCore/Speedhacks " , " vu1Instant " , true ) ;
2021-12-13 12:12:54 +00:00
2024-01-05 14:34:21 +00:00
SettingWidgetBinder : : BindWidgetToIntSetting ( sif , m_ui . eeRoundingMode , " EmuCore/CPU " , " FPU.Roundmode " , static_cast < int > ( FPRoundMode : : ChopZero ) ) ;
SettingWidgetBinder : : BindWidgetToIntSetting ( sif , m_ui . eeDivRoundingMode , " EmuCore/CPU " , " FPUDiv.Roundmode " , static_cast < int > ( FPRoundMode : : Nearest ) ) ;
SettingWidgetBinder : : BindWidgetToIntSetting ( sif , m_ui . vu0RoundingMode , " EmuCore/CPU " , " VU0.Roundmode " , static_cast < int > ( FPRoundMode : : ChopZero ) ) ;
SettingWidgetBinder : : BindWidgetToIntSetting ( sif , m_ui . vu1RoundingMode , " EmuCore/CPU " , " VU1.Roundmode " , static_cast < int > ( FPRoundMode : : ChopZero ) ) ;
2022-11-23 13:20:49 +00:00
if ( m_dialog - > isPerGameSettings ( ) )
{
2022-12-28 04:44:34 +00:00
m_ui . eeClampMode - > insertItem ( 0 , tr ( " Use Global Setting [%1] " ) . arg ( m_ui . eeClampMode - > itemText ( getGlobalClampingModeIndex ( - 1 ) ) ) ) ;
m_ui . vu0ClampMode - > insertItem ( 0 , tr ( " Use Global Setting [%1] " ) . arg ( m_ui . vu0ClampMode - > itemText ( getGlobalClampingModeIndex ( 0 ) ) ) ) ;
m_ui . vu1ClampMode - > insertItem ( 0 , tr ( " Use Global Setting [%1] " ) . arg ( m_ui . vu1ClampMode - > itemText ( getGlobalClampingModeIndex ( 1 ) ) ) ) ;
2022-11-23 13:20:49 +00:00
}
2022-12-28 04:44:34 +00:00
m_ui . eeClampMode - > setCurrentIndex ( getClampingModeIndex ( - 1 ) ) ;
m_ui . vu0ClampMode - > setCurrentIndex ( getClampingModeIndex ( 0 ) ) ;
m_ui . vu1ClampMode - > setCurrentIndex ( getClampingModeIndex ( 1 ) ) ;
connect ( m_ui . eeClampMode , QOverload < int > : : of ( & QComboBox : : currentIndexChanged ) , [ this ] ( int index ) { setClampingMode ( - 1 , index ) ; } ) ;
connect ( m_ui . vu0ClampMode , QOverload < int > : : of ( & QComboBox : : currentIndexChanged ) , [ this ] ( int index ) { setClampingMode ( 0 , index ) ; } ) ;
connect ( m_ui . vu1ClampMode , QOverload < int > : : of ( & QComboBox : : currentIndexChanged ) , [ this ] ( int index ) { setClampingMode ( 1 , index ) ; } ) ;
2022-11-23 13:20:49 +00:00
2022-02-15 14:29:18 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . iopRecompiler , " EmuCore/CPU/Recompiler " , " EnableIOP " , true ) ;
2021-12-13 12:12:54 +00:00
2022-03-30 18:26:48 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . gameFixes , " EmuCore " , " EnableGameFixes " , true ) ;
2022-02-15 14:29:18 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . patches , " EmuCore " , " EnablePatches " , true ) ;
2021-12-13 12:12:54 +00:00
2022-02-15 14:29:18 +00:00
SettingWidgetBinder : : BindWidgetToFloatSetting ( sif , m_ui . ntscFrameRate , " EmuCore/GS " , " FramerateNTSC " , 59.94f ) ;
SettingWidgetBinder : : BindWidgetToFloatSetting ( sif , m_ui . palFrameRate , " EmuCore/GS " , " FrameratePAL " , 50.00f ) ;
2022-12-28 04:44:34 +00:00
2024-09-25 16:10:02 +00:00
SettingWidgetBinder : : BindWidgetToIntSetting (
sif , m_ui . savestateCompressionMethod , " EmuCore " , " SavestateCompressionType " , static_cast < int > ( SavestateCompressionMethod : : Zstandard ) ) ;
SettingWidgetBinder : : BindWidgetToIntSetting (
sif , m_ui . savestateCompressionLevel , " EmuCore " , " SavestateCompressionRatio " , static_cast < int > ( SavestateCompressionLevel : : Medium ) ) ;
connect ( m_ui . savestateCompressionMethod , QOverload < int > : : of ( & QComboBox : : currentIndexChanged ) , this ,
& AdvancedSettingsWidget : : onSavestateCompressionTypeChanged ) ;
2024-10-03 07:28:50 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . backupSaveStates , " EmuCore " , " BackupSavestate " , true ) ;
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . saveStateOnShutdown , " EmuCore " , " SaveStateOnShutdown " , false ) ;
2023-01-24 19:28:03 +00:00
SettingWidgetBinder : : BindWidgetToBoolSetting ( sif , m_ui . pineEnable , " EmuCore " , " EnablePINE " , false ) ;
SettingWidgetBinder : : BindWidgetToIntSetting ( sif , m_ui . pineSlot , " EmuCore " , " PINESlot " , 28011 ) ;
2023-11-10 15:08:17 +00:00
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; <b>modifying this setting when a game is not having a visible problem can cause instability.</b> " ) ) ;
2024-07-04 02:20:23 +00:00
dialog - > registerWidgetHelp ( m_ui . eeDivRoundingMode , tr ( " Division Rounding Mode " ) , tr ( " Nearest (Default) " ) , tr ( " Determines how the results of floating-point division are rounded. Some games need specific settings; <b>modifying this setting when a game is not having a visible problem can cause instability.</b> " ) ) ;
2022-12-08 09:54:57 +00:00
2023-11-10 15:08:17 +00:00
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; <b>modifying this setting when a game is not having a visible problem can cause instability.</b> " ) ) ;
2022-06-27 13:07:40 +00:00
dialog - > registerWidgetHelp ( m_ui . eeRecompiler , tr ( " Enable Recompiler " ) , tr ( " Checked " ) ,
2023-02-18 01:58:32 +00:00
tr ( " Performs just-in-time binary translation of 64-bit MIPS-IV machine code to x86. " ) ) ;
2022-06-27 13:07:40 +00:00
2023-03-18 21:14:55 +00:00
//: Wait loop: When the game makes the CPU do nothing (loop/spin) while it waits for something to happen (usually an interrupt).
2022-06-27 13:07:40 +00:00
dialog - > registerWidgetHelp ( m_ui . eeWaitLoopDetection , tr ( " Wait Loop Detection " ) , tr ( " Checked " ) ,
tr ( " Moderate speedup for some games, with no known side effects. " ) ) ;
2022-12-28 04:44:34 +00:00
dialog - > registerWidgetHelp ( m_ui . eeCache , tr ( " Enable Cache (Slow) " ) , tr ( " Unchecked " ) , tr ( " Interpreter only, provided for diagnostic. " ) ) ;
2022-06-27 13:07:40 +00:00
2023-03-18 21:14:55 +00:00
//: INTC = Name of a PS2 register, leave as-is. "spin" = to make a cpu (or gpu) actively do nothing while you wait for something. Like spinning in a circle, you're moving but not actually going anywhere.
2022-06-27 13:07:40 +00:00
dialog - > registerWidgetHelp ( m_ui . eeINTCSpinDetection , tr ( " INTC Spin Detection " ) , tr ( " Checked " ) ,
tr ( " Huge speedup for some games, with almost no compatibility side effects. " ) ) ;
2022-10-29 03:39:19 +00:00
dialog - > registerWidgetHelp ( m_ui . eeFastmem , tr ( " Enable Fast Memory Access " ) , tr ( " Checked " ) ,
2023-03-18 21:14:55 +00:00
//: "Backpatching" = To edit previously generated code to change what it does (in this case, we generate direct memory accesses, then backpatch them to jump to a fancier handler function when we realize they need the fancier handler function)
2022-10-29 03:39:19 +00:00
tr ( " Uses backpatching to avoid register flushing on every memory access. " ) ) ;
2023-01-25 15:13:55 +00:00
dialog - > registerWidgetHelp ( m_ui . pauseOnTLBMiss , tr ( " Pause On TLB Miss " ) , tr ( " Unchecked " ) ,
2023-02-18 01:58:32 +00:00
tr ( " Pauses the virtual machine when a TLB miss occurs, instead of ignoring it and continuing. Note that the VM will pause after the "
2023-01-25 15:13:55 +00:00
" end of the block, not on the instruction which caused the exception. Refer to the console to see the address where the invalid "
" access occurred. " ) ) ;
2024-04-29 05:33:58 +00:00
dialog - > registerWidgetHelp ( m_ui . extraMemory , tr ( " Enable 128MB RAM (Dev Console) " ) , tr ( " Unchecked " ) ,
tr ( " Exposes an additional 96MB of memory to the virtual machine. " ) ) ;
2023-11-10 15:08:17 +00:00
dialog - > registerWidgetHelp ( m_ui . vu0RoundingMode , tr ( " VU0 Rounding Mode " ) , tr ( " Chop/Zero (Default) " ) , tr ( " Changes how PCSX2 handles rounding while emulating the Emotion Engine's Vector Unit 0 (EE VU0). "
" The default value handles the vast majority of games; <b>modifying this setting when a game is not having a visible problem will cause stability issues and/or crashes.</b> " ) ) ;
2022-12-08 09:54:57 +00:00
2023-11-10 15:08:17 +00:00
dialog - > registerWidgetHelp ( m_ui . vu1RoundingMode , tr ( " VU1 Rounding Mode " ) , tr ( " Chop/Zero (Default) " ) , tr ( " Changes how PCSX2 handles rounding while emulating the Emotion Engine's Vector Unit 1 (EE VU1). "
" The default value handles the vast majority of games; <b>modifying this setting when a game is not having a visible problem will cause stability issues and/or crashes.</b> " ) ) ;
dialog - > registerWidgetHelp ( m_ui . vu0ClampMode , tr ( " VU0 Clamping Mode " ) , tr ( " Normal (Default) " ) , tr ( " Changes how PCSX2 handles keeping floats in a standard x86 range in the Emotion Engine's Vector Unit 0 (EE VU0). "
" The default value handles the vast majority of games; <b>modifying this setting when a game is not having a visible problem can cause instability.</b> " ) ) ;
dialog - > registerWidgetHelp ( m_ui . vu1ClampMode , tr ( " VU1 Clamping Mode " ) , tr ( " Normal (Default) " ) , tr ( " Changes how PCSX2 handles keeping floats in a standard x86 range in the Emotion Engine's Vector Unit 1 (EE VU1). "
" The default value handles the vast majority of games; <b>modifying this setting when a game is not having a visible problem can cause instability.</b> " ) ) ;
2022-12-08 09:54:57 +00:00
2024-06-15 13:34:50 +00:00
dialog - > registerWidgetHelp ( m_ui . instantVU1 , tr ( " Enable Instant VU1 " ) , tr ( " Checked " ) , tr ( " Runs VU1 instantly. Provides a modest speed improvement in most games. "
" Safe for most games, but a few games may exhibit graphical errors. " ) ) ;
2023-03-18 21:14:55 +00:00
//: VU0 = Vector Unit 0. One of the PS2's processors.
2022-12-28 04:44:34 +00:00
dialog - > registerWidgetHelp ( m_ui . vu0Recompiler , tr ( " Enable VU0 Recompiler (Micro Mode) " ) , tr ( " Checked " ) , tr ( " Enables VU0 Recompiler. " ) ) ;
2022-07-05 13:42:26 +00:00
2023-03-18 21:14:55 +00:00
//: VU1 = Vector Unit 1. One of the PS2's processors.
2022-12-28 04:44:34 +00:00
dialog - > registerWidgetHelp ( m_ui . vu1Recompiler , tr ( " Enable VU1 Recompiler " ) , tr ( " Checked " ) , tr ( " Enables VU1 Recompiler. " ) ) ;
2022-07-05 13:42:26 +00:00
2022-12-28 04:44:34 +00:00
dialog - > registerWidgetHelp (
2023-03-18 21:14:55 +00:00
//: mVU = PCSX2's recompiler for VU (Vector Unit) code (full name: microVU)
2022-12-28 04:44:34 +00:00
m_ui . vuFlagHack , tr ( " mVU Flag Hack " ) , tr ( " Checked " ) , tr ( " Good speedup and high compatibility, may cause graphical errors. " ) ) ;
2022-06-27 13:07:40 +00:00
dialog - > registerWidgetHelp ( m_ui . iopRecompiler , tr ( " Enable Recompiler " ) , tr ( " Checked " ) ,
tr ( " Performs just-in-time binary translation of 32-bit MIPS-I machine code to x86. " ) ) ;
dialog - > registerWidgetHelp ( m_ui . gameFixes , tr ( " Enable Game Fixes " ) , tr ( " Checked " ) ,
2023-03-13 00:34:20 +00:00
tr ( " Automatically loads and applies fixes to known problematic games on game start. " ) ) ;
2022-07-05 13:42:26 +00:00
dialog - > registerWidgetHelp ( m_ui . patches , tr ( " Enable Compatibility Patches " ) , tr ( " Checked " ) ,
tr ( " Automatically loads and applies compatibility patches to known problematic games. " ) ) ;
2024-09-25 16:10:02 +00:00
dialog - > registerWidgetHelp ( m_ui . savestateCompressionMethod , tr ( " Savestate Compression Method " ) , tr ( " Zstandard " ) ,
tr ( " Determines the algorithm to be used when compressing savestates. " ) ) ;
dialog - > registerWidgetHelp ( m_ui . savestateCompressionLevel , tr ( " Savestate Compression Level " ) , tr ( " Medium " ) ,
tr ( " Determines the level to be used when compressing savestates. " ) ) ;
2024-10-03 07:28:50 +00:00
dialog - > registerWidgetHelp ( m_ui . saveStateOnShutdown , tr ( " Save State On Shutdown " ) , tr ( " Unchecked " ) ,
tr ( " Automatically saves the emulator state when powering down or exiting. You can then "
" resume directly from where you left off next time. " ) ) ;
dialog - > registerWidgetHelp ( m_ui . backupSaveStates , tr ( " Create Save State Backups " ) , tr ( " Checked " ) ,
//: Do not translate the ".backup" extension.
tr ( " Creates a backup copy of a save state if it already exists when the save is created. The backup copy has a .backup suffix. " ) ) ;
2021-12-13 12:12:54 +00:00
}
2022-11-23 13:20:49 +00:00
AdvancedSettingsWidget : : ~ AdvancedSettingsWidget ( ) = default ;
2022-12-28 04:44:34 +00:00
int AdvancedSettingsWidget : : getGlobalClampingModeIndex ( int vunum ) const
2022-11-23 13:20:49 +00:00
{
2022-12-28 04:44:34 +00:00
if ( Host : : GetBaseBoolSettingValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0SignOverflow " : " vu1SignOverflow " ) : " fpuFullMode " ) , false ) )
2022-11-23 13:20:49 +00:00
return 3 ;
2022-12-28 04:44:34 +00:00
if ( Host : : GetBaseBoolSettingValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0ExtraOverflow " : " vu1ExtraOverflow " ) : " fpuExtraOverflow " ) , false ) )
2022-11-23 13:20:49 +00:00
return 2 ;
2022-12-28 04:44:34 +00:00
if ( Host : : GetBaseBoolSettingValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0Overflow " : " vu1Overflow " ) : " fpuOverflow " ) , true ) )
2022-11-23 13:20:49 +00:00
return 1 ;
return 0 ;
}
2022-12-28 04:44:34 +00:00
int AdvancedSettingsWidget : : getClampingModeIndex ( int vunum ) const
2022-11-23 13:20:49 +00:00
{
// This is so messy... maybe we should just make the mode an int in the settings too...
const bool base = m_dialog - > isPerGameSettings ( ) ? 1 : 0 ;
std : : optional < bool > default_false = m_dialog - > isPerGameSettings ( ) ? std : : nullopt : std : : optional < bool > ( false ) ;
std : : optional < bool > default_true = m_dialog - > isPerGameSettings ( ) ? std : : nullopt : std : : optional < bool > ( true ) ;
2022-12-28 04:44:34 +00:00
std : : optional < bool > third = m_dialog - > getBoolValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0SignOverflow " : " vu1SignOverflow " ) : " fpuFullMode " ) , default_false ) ;
std : : optional < bool > second = m_dialog - > getBoolValue ( " EmuCore/CPU/Recompiler " ,
( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0ExtraOverflow " : " vu1ExtraOverflow " ) : " fpuExtraOverflow " ) , default_false ) ;
std : : optional < bool > first = m_dialog - > getBoolValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0Overflow " : " vu1Overflow " ) : " fpuOverflow " ) , default_true ) ;
2022-11-23 13:20:49 +00:00
if ( third . has_value ( ) & & third . value ( ) )
return base + 3 ;
if ( second . has_value ( ) & & second . value ( ) )
return base + 2 ;
if ( first . has_value ( ) & & first . value ( ) )
return base + 1 ;
else if ( first . has_value ( ) )
return base + 0 ; // none
else
return 0 ; // no per game override
}
2022-12-28 04:44:34 +00:00
void AdvancedSettingsWidget : : setClampingMode ( int vunum , int index )
2022-11-23 13:20:49 +00:00
{
std : : optional < bool > first , second , third ;
if ( ! m_dialog - > isPerGameSettings ( ) | | index > 0 )
{
const bool base = m_dialog - > isPerGameSettings ( ) ? 1 : 0 ;
third = ( index > = ( base + 3 ) ) ;
second = ( index > = ( base + 2 ) ) ;
first = ( index > = ( base + 1 ) ) ;
}
2022-12-28 04:44:34 +00:00
m_dialog - > setBoolSettingValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0SignOverflow " : " vu1SignOverflow " ) : " fpuFullMode " ) , third ) ;
m_dialog - > setBoolSettingValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0ExtraOverflow " : " vu1ExtraOverflow " ) : " fpuExtraOverflow " ) , second ) ;
m_dialog - > setBoolSettingValue (
" EmuCore/CPU/Recompiler " , ( vunum > = 0 ? ( ( vunum = = 0 ) ? " vu0Overflow " : " vu1Overflow " ) : " fpuOverflow " ) , first ) ;
2022-11-23 13:20:49 +00:00
}
2024-09-25 16:10:02 +00:00
void AdvancedSettingsWidget : : onSavestateCompressionTypeChanged ( )
{
const bool uncompressed = ( m_dialog - > getEffectiveIntValue ( " EmuCore " , " SavestateCompressionType " , static_cast < int > ( SavestateCompressionMethod : : Zstandard ) ) = =
static_cast < int > ( SavestateCompressionMethod : : Uncompressed ) ) ;
m_ui . savestateCompressionLevel - > setDisabled ( uncompressed ) ;
}