mirror of https://github.com/PCSX2/pcsx2.git
Presets: Bug fixes, code cleanups, better documentation:
1. Bugfix: Some configs were affected by presets although they shouldn't have (e.g. MultitapEnabled and few more). 2. Bugfix: GUI: moving the presets slider was forcing unaffected values to last applied settings (would override settings changes which took place at the GUI while presets are enabled, e.g. most GSWindow options). 3. Better code resilience for future SysConfigDialog panels which might not be affected by presets. 4. Removed unused code and improved comments. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4237 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
3d6ac25f3c
commit
6d4fd157b8
|
@ -731,7 +731,7 @@ void AppConfig::FramerateOptions::LoadSave( IniInterface& ini )
|
||||||
IniEntry( SkipOnTurbo );
|
IniEntry( SkipOnTurbo );
|
||||||
}
|
}
|
||||||
|
|
||||||
int AppConfig::GeMaxPresetIndex()
|
int AppConfig::GetMaxPresetIndex()
|
||||||
{
|
{
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
@ -747,7 +747,7 @@ bool AppConfig::isOkGetPresetTextAndColor( int n, wxString& label, wxColor& c )
|
||||||
{ _t("Aggressive plus"), L"Orange"},
|
{ _t("Aggressive plus"), L"Orange"},
|
||||||
{ _t("Mostly Harmful"), L"Red" }
|
{ _t("Mostly Harmful"), L"Red" }
|
||||||
};
|
};
|
||||||
if( n<0 || n>GeMaxPresetIndex() )
|
if( n<0 || n>GetMaxPresetIndex() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
label = wxsFormat(L"%d - ", n+1) + presetNamesAndColors[n][0];
|
label = wxsFormat(L"%d - ", n+1) + presetNamesAndColors[n][0];
|
||||||
|
@ -757,43 +757,54 @@ bool AppConfig::isOkGetPresetTextAndColor( int n, wxString& label, wxColor& c )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Apply one of several (currently 6) configuration subsets.
|
||||||
|
//The scope of the subset which each preset controlls is hardcoded here.
|
||||||
bool AppConfig::IsOkApplyPreset(int n)
|
bool AppConfig::IsOkApplyPreset(int n)
|
||||||
{
|
{
|
||||||
if (n < 0 || n > GeMaxPresetIndex() )
|
if (n < 0 || n > GetMaxPresetIndex() )
|
||||||
{
|
{
|
||||||
Console.WriteLn("Warning: ApplyPreset(%d): index too big, Aborting.", n);
|
Console.WriteLn("DEV Warning: ApplyPreset(%d): index out of range, Aborting.", n);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLn("Applying Preset %d ...", n);
|
Console.WriteLn("Applying Preset %d ...", n);
|
||||||
|
|
||||||
AppConfig default_AppConfig;
|
//Have some original and default values at hand to be used later.
|
||||||
Pcsx2Config default_Pcsx2Config;
|
Pcsx2Config::GSOptions original_GS = EmuOptions.GS;
|
||||||
|
AppConfig default_AppConfig;
|
||||||
|
Pcsx2Config default_Pcsx2Config;
|
||||||
|
|
||||||
Pcsx2Config original_Pcsx2Config = EmuOptions;
|
|
||||||
EmuOptions = default_Pcsx2Config; //reset EmuOptions.
|
|
||||||
|
|
||||||
//restore the original Pcsx2Config settings which we don't want to override with the application default dettings.
|
// NOTE: Because the system currently only supports passing of an entire AppConfig to the GUI panels to apply,
|
||||||
//The ugly part of this is that while most panels are entirely disabled from manual tweaking when a preset is used,
|
// the GUI panels should be aware of the settings which the presets control, such that when presets are used:
|
||||||
// the options that are not overriden by presets need to be manually excluded from disabling.
|
// 1. The panels should prevent manual modifications (by graying out) of settings which the presets control.
|
||||||
// So the Gui panels need to have intimate knowledge of this exclusion list. Bahh..
|
// 2. The panels should not apply values which the presets don't control.
|
||||||
EmuOptions.EnableCheats = original_Pcsx2Config.EnableCheats;
|
// Currently controlled by the presets:
|
||||||
EmuOptions.GS.FrameLimitEnable = original_Pcsx2Config.GS.FrameLimitEnable;
|
// - AppConfig: Framerate, EnableSpeedHacks, EnableGameFixes.
|
||||||
EmuOptions.BackupSavestate = original_Pcsx2Config.BackupSavestate;
|
// - EmuOptions: Cpu, Gamefixes, SpeedHacks, EnablePatches, GS (except FrameLimitEnable).
|
||||||
|
//
|
||||||
|
// This essentially currently covers all the options on all the panels except for framelimiter which isn't
|
||||||
|
// controlled by the presets, and almost the entire GSWindow panel which also isn't controlled by presets
|
||||||
|
// (however, vsync IS controlled by the presets).
|
||||||
|
|
||||||
//Make sure these options are forced as a base even if in the future they default to other values.
|
|
||||||
//Also, as with the exclusions list, the gui needs to know what sections are affected by presets
|
|
||||||
// such that it can disable them from manual tweaking when a preset is used. This includes most panels BTW.
|
|
||||||
EnableSpeedHacks =false;
|
|
||||||
EmuOptions.Speedhacks.bitset=0; //Turn off individual hacks to make it visually clear they're not used
|
|
||||||
EnableGameFixes =false;
|
|
||||||
EmuOptions.EnablePatches =true;
|
|
||||||
|
|
||||||
//Note that AppConfig was not reset, so if we need some default options for it, we need to set them.
|
//Force some settings as a (current) base for all presets.
|
||||||
this->Framerate = default_AppConfig.Framerate;
|
|
||||||
|
|
||||||
//Actual application of current preset.
|
Framerate = default_AppConfig.Framerate;
|
||||||
//The presets themselves probably need some voodoo tuning to be reasonably useful.
|
EnableSpeedHacks = false;
|
||||||
|
EnableGameFixes = false;
|
||||||
|
|
||||||
|
EmuOptions.EnablePatches = true;
|
||||||
|
EmuOptions.GS = default_Pcsx2Config.GS;
|
||||||
|
EmuOptions.GS.FrameLimitEnable = original_GS.FrameLimitEnable; //although GS is reset, frameLimiter isn't touched.
|
||||||
|
EmuOptions.Cpu = default_Pcsx2Config.Cpu;
|
||||||
|
EmuOptions.Gamefixes = default_Pcsx2Config.Gamefixes;
|
||||||
|
EmuOptions.Speedhacks = default_Pcsx2Config.Speedhacks;
|
||||||
|
EmuOptions.Speedhacks.bitset = 0; //Turn off individual hacks to make it visually clear they're not used.
|
||||||
|
|
||||||
|
|
||||||
|
//Actual application of current preset over the base settings which all presets use (mostly pcsx2's default values).
|
||||||
|
//The presets themselves might need some voodoo tuning to be even more useful. Currently they mostly modify Speedhacks.
|
||||||
|
|
||||||
bool vuUsed=false, eeUsed=false;//used to prevent application of specific lower preset values on fallthrough.
|
bool vuUsed=false, eeUsed=false;//used to prevent application of specific lower preset values on fallthrough.
|
||||||
switch (n){ //currently implemented such that any preset also applies all lower presets, with few exceptions.
|
switch (n){ //currently implemented such that any preset also applies all lower presets, with few exceptions.
|
||||||
|
@ -806,27 +817,24 @@ bool AppConfig::IsOkApplyPreset(int n)
|
||||||
|
|
||||||
case 3 : //Set VU cycle steal to 1 click, enable (m)vuBlockHack, set VU clamp mode to 'none'
|
case 3 : //Set VU cycle steal to 1 click, enable (m)vuBlockHack, set VU clamp mode to 'none'
|
||||||
vuUsed?0:(vuUsed=true, EmuOptions.Speedhacks.VUCycleSteal = 1);
|
vuUsed?0:(vuUsed=true, EmuOptions.Speedhacks.VUCycleSteal = 1);
|
||||||
EmuOptions.Speedhacks.vuBlockHack=true;
|
EmuOptions.Speedhacks.vuBlockHack = true;
|
||||||
//EmuOptions.Cpu.Recompiler.fpuOverflow=
|
EmuOptions.Cpu.Recompiler.vuOverflow =
|
||||||
//EmuOptions.Cpu.Recompiler.fpuExtraOverflow=
|
EmuOptions.Cpu.Recompiler.vuExtraOverflow =
|
||||||
//EmuOptions.Cpu.Recompiler.fpuFullMode= //EE clamp mode to 'None' : Better default for presets
|
EmuOptions.Cpu.Recompiler.vuSignOverflow = false; //VU Clamp mode to 'none'
|
||||||
EmuOptions.Cpu.Recompiler.vuOverflow=
|
|
||||||
EmuOptions.Cpu.Recompiler.vuExtraOverflow=
|
|
||||||
EmuOptions.Cpu.Recompiler.vuSignOverflow=false; //VU Clamp mode to 'none'
|
|
||||||
|
|
||||||
//best balanced hacks combo?
|
//best balanced hacks combo?
|
||||||
case 2 : //enable EE timing hack, set EE cyclerate to 1 click, enable mvu flag hack
|
case 2 : //enable mvu flag hack, enable EE timing hack, set EE cyclerate to 1 click.
|
||||||
eeUsed?0:(eeUsed=true, EmuOptions.Speedhacks.EECycleRate = 1);
|
eeUsed?0:(eeUsed=true, EmuOptions.Speedhacks.EECycleRate = 1);
|
||||||
EnableGameFixes = true;
|
EnableGameFixes = true;
|
||||||
EmuOptions.Gamefixes.EETimingHack = true;
|
EmuOptions.Gamefixes.EETimingHack = true;
|
||||||
EmuOptions.Speedhacks.vuFlagHack = true;
|
EmuOptions.Speedhacks.vuFlagHack = true;
|
||||||
|
|
||||||
case 1 : //Apply recommended speed hacks (which are individually "ckecked" by default) without mvu flag hack.
|
case 1 : //Recommended speed hacks without mvu flag hack.
|
||||||
EnableSpeedHacks = true;
|
EnableSpeedHacks = true;
|
||||||
EmuOptions.Speedhacks.IntcStat = true;
|
EmuOptions.Speedhacks.IntcStat = true;
|
||||||
EmuOptions.Speedhacks.WaitLoop = true;
|
EmuOptions.Speedhacks.WaitLoop = true;
|
||||||
|
|
||||||
case 0 : //default application config. + all individual speed hacks unticked to make it visually clear none is used.
|
case 0 : //Base preset: Mostly pcsx2's defaults.
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -303,7 +303,7 @@ public:
|
||||||
void LoadSaveRootItems( IniInterface& ini );
|
void LoadSaveRootItems( IniInterface& ini );
|
||||||
void LoadSaveMemcards( IniInterface& ini );
|
void LoadSaveMemcards( IniInterface& ini );
|
||||||
|
|
||||||
static int GeMaxPresetIndex();
|
static int GetMaxPresetIndex();
|
||||||
static bool isOkGetPresetTextAndColor(int n, wxString& label, wxColor& c);
|
static bool isOkGetPresetTextAndColor(int n, wxString& label, wxColor& c);
|
||||||
bool IsOkApplyPreset(int n);
|
bool IsOkApplyPreset(int n);
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,8 @@ public:
|
||||||
virtual void AppStatusEvent_OnVmSettingsLoadSave( const AppSettingsEventInfo& ) {}
|
virtual void AppStatusEvent_OnVmSettingsLoadSave( const AppSettingsEventInfo& ) {}
|
||||||
virtual void AppStatusEvent_OnExit() {}
|
virtual void AppStatusEvent_OnExit() {}
|
||||||
|
|
||||||
|
virtual bool IsSpecificConfig(){return false;} //lame RTTI
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnSettingsApplied( wxCommandEvent& evt );
|
virtual void OnSettingsApplied( wxCommandEvent& evt );
|
||||||
};
|
};
|
||||||
|
@ -212,6 +214,7 @@ class BaseApplicableConfigPanel_SpecificConfig : public BaseApplicableConfigPane
|
||||||
//but multiple inheritance sucks. So, subclass.
|
//but multiple inheritance sucks. So, subclass.
|
||||||
//NOTE: because ApplyConfigToGui is called manually and not via an event, it must consider manuallyPropagate and call sub panels.
|
//NOTE: because ApplyConfigToGui is called manually and not via an event, it must consider manuallyPropagate and call sub panels.
|
||||||
public:
|
public:
|
||||||
|
virtual bool IsSpecificConfig(){return true;};
|
||||||
BaseApplicableConfigPanel_SpecificConfig( wxWindow* parent, wxOrientation orient=wxVERTICAL );
|
BaseApplicableConfigPanel_SpecificConfig( wxWindow* parent, wxOrientation orient=wxVERTICAL );
|
||||||
BaseApplicableConfigPanel_SpecificConfig( wxWindow* parent, wxOrientation orient, const wxString& staticLabel );
|
BaseApplicableConfigPanel_SpecificConfig( wxWindow* parent, wxOrientation orient, const wxString& staticLabel );
|
||||||
|
|
||||||
|
|
|
@ -65,48 +65,44 @@ static void CheckPluginsOverrides()
|
||||||
pxIssueConfirmation( dialog, MsgButtons().OK(), L"Dialog.ComponentsConfig.Overrides" );
|
pxIssueConfirmation( dialog, MsgButtons().OK(), L"Dialog.ComponentsConfig.Overrides" );
|
||||||
}
|
}
|
||||||
|
|
||||||
//Current behavior when unchecking 'Presets' is to keep the GUI settings at the last preset (even if not applied).
|
//Behavior when unchecking 'Presets' is to keep the GUI settings at the last preset (even if not yet applied).
|
||||||
//
|
//
|
||||||
//Alternative GUI behavior is that when 'Preset' is unchecked,
|
//Alternative possible behavior when unchecking 'Presets' (currently not implemented) is to set the GUI to
|
||||||
// the GUI settings return to the last applied settings.
|
// the last applied settings. If such behavior is to be implemented, g_Conf->EnablePresets should be set to
|
||||||
// This allows the user to keep tweaking his "personal' settings and toggling 'Presets' for comparison,
|
// false before it's applied to the GUI and then restored to it's original state such that the GUI reflects
|
||||||
// or start tweaking from a specific preset by clicking Apply before unchecking 'Presets'
|
// g_Conf's settings as if it doesn't force presets. (if a settings which has presets enable is applied to the
|
||||||
// However, I think it's more confusing. Uncomment the next line to use the alternative behavior.
|
// GUI then most of the GUI is disabled).
|
||||||
//#define PRESETS_USE_APPLIED_CONFIG_ON_UNCHECK
|
|
||||||
void Dialogs::SysConfigDialog::UpdateGuiForPreset ( int presetIndex, bool presetsEnabled )
|
void Dialogs::SysConfigDialog::UpdateGuiForPreset ( int presetIndex, bool presetsEnabled )
|
||||||
{
|
{
|
||||||
|
if( !m_listbook )
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Console.WriteLn("Applying config to Gui: preset #%d, presets enabled: %s", presetIndex, presetsEnabled?"true":"false");
|
||||||
|
|
||||||
AppConfig preset = *g_Conf;
|
AppConfig preset = *g_Conf;
|
||||||
preset.IsOkApplyPreset(presetIndex);
|
preset.IsOkApplyPreset( presetIndex ); //apply a preset to a copy of g_Conf.
|
||||||
preset.EnablePresets=presetsEnabled;//override IsOkApplyPreset to actual required state
|
preset.EnablePresets = presetsEnabled; //override IsOkApplyPreset (which always applies/enabled) to actual required state
|
||||||
|
|
||||||
if( m_listbook ){
|
size_t pages = m_labels.GetCount();
|
||||||
//Console.WriteLn("Applying config to Gui: preset #%d, presets enabled: %s", presetIndex, presetsEnabled?"true":"false");
|
for( size_t i=0; i<pages; ++i )
|
||||||
size_t pages = m_labels.GetCount();
|
{
|
||||||
for( size_t i=0; i<pages; ++i ){
|
//NOTE: We should only apply the preset to panels of class BaseApplicableConfigPanel_SpecificConfig
|
||||||
bool origPresetsEnabled = g_Conf->EnablePresets;
|
// which supports it, and BaseApplicableConfigPanel implements IsSpecificConfig() as lame RTTI to detect it.
|
||||||
if( !presetsEnabled )
|
// However, the panels in general (m_listbook->GetPage(i)) are of type wxNotebookPage which doesn't
|
||||||
g_Conf->EnablePresets = false; // unly used when PRESETS_USE_APPLIED_CONFIG_WHEN_UNCHECKED is NOT defined
|
// support IsSpecificConfig(), so the panels (pages) that SysConfigDialog holds must be of class
|
||||||
|
// BaseApplicableConfigPanel or derived, and not of the parent class wxNotebookPage.
|
||||||
(
|
if ( ((BaseApplicableConfigPanel*)(m_listbook->GetPage(i)))->IsSpecificConfig() )
|
||||||
(BaseApplicableConfigPanel_SpecificConfig*)(m_listbook->GetPage(i))
|
{
|
||||||
|
((BaseApplicableConfigPanel_SpecificConfig*)(m_listbook->GetPage(i)))
|
||||||
#ifdef PRESETS_USE_APPLIED_CONFIG_ON_UNCHECK
|
->ApplyConfigToGui( preset, true );
|
||||||
)->ApplyConfigToGui( presetsEnabled?preset:*g_Conf, true );
|
|
||||||
//Console.WriteLn("SysConfigDialog::UpdateGuiForPreset: Using object: %s", presetsEnabled?"preset":"*g_Conf");
|
|
||||||
#else
|
|
||||||
)->ApplyConfigToGui( preset, true );
|
|
||||||
//Console.WriteLn("SysConfigDialog::UpdateGuiForPreset: Using object: %s", "preset");
|
|
||||||
#endif
|
|
||||||
g_Conf->EnablePresets = origPresetsEnabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialogs::SysConfigDialog::AddPresetsControl()
|
void Dialogs::SysConfigDialog::AddPresetsControl()
|
||||||
{
|
{
|
||||||
m_slider_presets = new wxSlider( this, wxID_ANY, g_Conf->PresetIndex, 0, AppConfig::GeMaxPresetIndex(),
|
m_slider_presets = new wxSlider( this, wxID_ANY, g_Conf->PresetIndex, 0, AppConfig::GetMaxPresetIndex(),
|
||||||
wxDefaultPosition, wxDefaultSize, wxHORIZONTAL /*| wxSL_AUTOTICKS | wxSL_LABELS */);
|
wxDefaultPosition, wxDefaultSize, wxHORIZONTAL /*| wxSL_AUTOTICKS | wxSL_LABELS */);
|
||||||
|
|
||||||
m_slider_presets->SetToolTip(
|
m_slider_presets->SetToolTip(
|
||||||
|
@ -202,6 +198,8 @@ Dialogs::SysConfigDialog::SysConfigDialog(wxWindow* parent)
|
||||||
CreateListbook( wxGetApp().GetImgList_Config() );
|
CreateListbook( wxGetApp().GetImgList_Config() );
|
||||||
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
|
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
|
||||||
|
|
||||||
|
//NOTE: all pages which are added to SysConfigDialog must be of class BaseApplicableConfigPanel or derived.
|
||||||
|
// see comment inside UpdateGuiForPreset implementation for more info.
|
||||||
AddPage<CpuPanelEE> ( pxL("EE/IOP"), cfgid.Cpu );
|
AddPage<CpuPanelEE> ( pxL("EE/IOP"), cfgid.Cpu );
|
||||||
AddPage<CpuPanelVU> ( pxL("VUs"), cfgid.Cpu );
|
AddPage<CpuPanelVU> ( pxL("VUs"), cfgid.Cpu );
|
||||||
AddPage<VideoPanel> ( pxL("GS"), cfgid.Cpu );
|
AddPage<VideoPanel> ( pxL("GS"), cfgid.Cpu );
|
||||||
|
|
|
@ -120,19 +120,22 @@ void Panels::GSWindowSettingsPanel::ApplyConfigToGui( AppConfig& configToApply,
|
||||||
{
|
{
|
||||||
const AppConfig::GSWindowOptions& conf( configToApply.GSWindow );
|
const AppConfig::GSWindowOptions& conf( configToApply.GSWindow );
|
||||||
|
|
||||||
m_check_CloseGS ->SetValue( conf.CloseOnEsc );
|
if( !manuallyPropagate ) //Presets don't control these: only change if config doesn't come from preset.
|
||||||
m_check_Fullscreen ->SetValue( conf.DefaultToFullscreen );
|
{
|
||||||
m_check_HideMouse ->SetValue( conf.AlwaysHideMouse );
|
m_check_CloseGS ->SetValue( conf.CloseOnEsc );
|
||||||
m_check_SizeLock ->SetValue( conf.DisableResizeBorders );
|
m_check_Fullscreen ->SetValue( conf.DefaultToFullscreen );
|
||||||
|
m_check_HideMouse ->SetValue( conf.AlwaysHideMouse );
|
||||||
|
m_check_SizeLock ->SetValue( conf.DisableResizeBorders );
|
||||||
|
|
||||||
m_combo_AspectRatio ->SetSelection( (int)conf.AspectRatio );
|
m_combo_AspectRatio ->SetSelection( (int)conf.AspectRatio );
|
||||||
|
|
||||||
m_check_VsyncEnable ->SetValue( configToApply.EmuOptions.GS.VsyncEnable );
|
m_check_VsyncEnable ->SetValue( configToApply.EmuOptions.GS.VsyncEnable );
|
||||||
|
|
||||||
m_check_DclickFullscreen ->SetValue ( conf.IsToggleFullscreenOnDoubleClick );
|
m_check_DclickFullscreen ->SetValue ( conf.IsToggleFullscreenOnDoubleClick );
|
||||||
|
|
||||||
m_text_WindowWidth ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetWidth() ) );
|
m_text_WindowWidth ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetWidth() ) );
|
||||||
m_text_WindowHeight ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetHeight() ) );
|
m_text_WindowHeight ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetHeight() ) );
|
||||||
|
}
|
||||||
|
|
||||||
m_check_VsyncEnable->Enable(!configToApply.EnablePresets);
|
m_check_VsyncEnable->Enable(!configToApply.EnablePresets);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,8 @@ void Panels::FramelimiterPanel::ApplyConfigToGui( AppConfig& configToApply, bool
|
||||||
const AppConfig::FramerateOptions& appfps( configToApply.Framerate );
|
const AppConfig::FramerateOptions& appfps( configToApply.Framerate );
|
||||||
const Pcsx2Config::GSOptions& gsconf( configToApply.EmuOptions.GS );
|
const Pcsx2Config::GSOptions& gsconf( configToApply.EmuOptions.GS );
|
||||||
|
|
||||||
m_check_LimiterDisable->SetValue( !gsconf.FrameLimitEnable );
|
if( !manuallyPropagate ) //Presets don't control this: only change if config doesn't come from preset.
|
||||||
|
m_check_LimiterDisable->SetValue( !gsconf.FrameLimitEnable );
|
||||||
|
|
||||||
m_spin_NominalPct ->SetValue( appfps.NominalScalar.Raw );
|
m_spin_NominalPct ->SetValue( appfps.NominalScalar.Raw );
|
||||||
m_spin_TurboPct ->SetValue( appfps.TurboScalar.Raw );
|
m_spin_TurboPct ->SetValue( appfps.TurboScalar.Raw );
|
||||||
|
|
Loading…
Reference in New Issue