From 20429ef4e32c0005b68acf60b224d38696056fc2 Mon Sep 17 00:00:00 2001 From: zilmar Date: Fri, 14 Nov 2008 20:51:06 +0000 Subject: [PATCH] git-svn-id: https://localhost/svn/Project64/trunk@6 111125ac-702d-7242-af9c-5ba8ae61c1ef --- Project64.ncb | Bin 1074176 -> 0 bytes Project64.opt | Bin 97792 -> 0 bytes .../Project64/3rd Party/HTML Help/vssver2.scc | Bin 142 -> 0 bytes Source/Project64/3rd Party/vssver2.scc | Bin 214 -> 0 bytes Source/Project64/3rd Party/zlib/vssver2.scc | Bin 323 -> 0 bytes Source/Project64/Multilanguage.h | 1 + .../Multilanguage/Language Class.cpp | 5 +- Source/Project64/Multilanguage/vssver2.scc | Bin 148 -> 0 bytes .../N64 System/C Core/C Core Interface.cpp | 57 +- Source/Project64/N64 System/C Core/Dma.cpp | 11 +- .../N64 System/C Core/Recompiler Ops.cpp | 28 +- .../Project64/N64 System/C Core/vssver2.scc | Bin 1874 -> 0 bytes Source/Project64/N64 System/Cheat Class.cpp | 100 +- Source/Project64/N64 System/Cheat Class.h | 1 + .../Project64/N64 System/Debugger/vssver2.scc | Bin 560 -> 0 bytes Source/Project64/N64 System/Mips/Memory.cpp | 62 +- .../N64 System/Mips/OpCode Class.cpp | 4 +- .../Project64/N64 System/Mips/TLB class.cpp | 8 +- Source/Project64/N64 System/Mips/vssver2.scc | Bin 631 -> 0 bytes Source/Project64/N64 System/N64 Class.cpp | 250 +++-- Source/Project64/N64 System/N64 Class.h | 2 +- Source/Project64/N64 System/N64 Rom Class.cpp | 71 +- Source/Project64/N64 System/N64 Rom Class.h | 2 +- Source/Project64/N64 System/N64 Types.h | 3 +- .../Recompiler/Recompiler Class.cpp | 89 +- .../N64 System/Recompiler/Recompiler Class.h | 10 +- .../N64 System/Recompiler/vssver2.scc | Bin 446 -> 0 bytes Source/Project64/N64 System/vssver2.scc | Bin 545 -> 0 bytes Source/Project64/Plugins/Audio Plugin.cpp | 6 +- .../Project64/Plugins/Controller Plugin.cpp | 6 +- Source/Project64/Plugins/GFX plugin.cpp | 10 +- Source/Project64/Plugins/Plugin Class.cpp | 46 +- Source/Project64/Plugins/Plugin Class.h | 3 +- Source/Project64/Plugins/Plugin List.cpp | 140 ++- Source/Project64/Plugins/Plugin List.h | 37 +- Source/Project64/Plugins/RSP Plugin.cpp | 6 +- Source/Project64/Plugins/vssver2.scc | Bin 458 -> 0 bytes Source/Project64/Project64.dsp | 175 +++- Source/Project64/Project64.plg | 415 ++++++-- Source/Project64/Settings.h | 229 ++++- Source/Project64/Settings/Gui Settings.cpp | 25 +- Source/Project64/Settings/Gui Settings.h | 16 +- .../Project64/Settings/N64System Settings.cpp | 100 +- .../Project64/Settings/N64System Settings.h | 43 +- .../Settings/Notification Settings.cpp | 12 +- .../Settings/Notification Settings.h | 12 +- .../Settings/Recompiler Settings.cpp | 83 +- .../Project64/Settings/Recompiler Settings.h | 47 +- .../SettingType/SettingsType-Application.cpp | 121 ++- .../SettingType/SettingsType-Application.h | 32 +- .../SettingsType-ApplicationIndex.cpp | 43 +- .../SettingsType-ApplicationIndex.h | 8 + .../Settings/SettingType/SettingsType-Base.h | 40 +- .../SettingType/SettingsType-Cheats.cpp | 114 +++ .../SettingType/SettingsType-Cheats.h | 55 ++ .../SettingType/SettingsType-GameSetting.cpp | 203 +++- .../SettingType/SettingsType-GameSetting.h | 38 +- .../SettingsType-GameSettingIndex.cpp | 93 ++ .../SettingsType-GameSettingIndex.h | 36 + .../SettingType/SettingsType-RDBCpuType.cpp | 109 +++ .../SettingType/SettingsType-RDBCpuType.h | 31 + .../SettingType/SettingsType-RDBOnOff.cpp | 99 ++ .../SettingType/SettingsType-RDBOnOff.h | 28 + .../SettingType/SettingsType-RDBRamSize.cpp | 91 ++ .../SettingType/SettingsType-RDBRamSize.h | 31 + .../SettingType/SettingsType-RDBSaveChip.cpp | 110 +++ .../SettingType/SettingsType-RDBSaveChip.h | 31 + .../SettingType/SettingsType-RDBYesNo.cpp | 94 ++ .../SettingType/SettingsType-RDBYesNo.h | 28 + .../SettingType/SettingsType-RelativePath.cpp | 32 +- .../SettingType/SettingsType-RelativePath.h | 25 +- .../SettingType/SettingsType-RomDatabase.cpp | 93 +- .../SettingType/SettingsType-RomDatabase.h | 37 +- .../SettingsType-RomDatabaseIndex.cpp | 97 ++ .../SettingsType-RomDatabaseIndex.h | 37 + .../SettingsType-SelectedDirectory.cpp | 77 ++ .../SettingsType-SelectedDirectory.h | 36 + .../SettingType/SettingsType-TempBool.cpp | 23 +- .../SettingType/SettingsType-TempBool.h | 26 +- .../SettingType/SettingsType-TempNumber.cpp | 23 +- .../SettingType/SettingsType-TempNumber.h | 25 +- .../SettingType/SettingsType-TempString.cpp | 21 + .../SettingType/SettingsType-TempString.h | 27 +- Source/Project64/Settings/Settings Class.cpp | 901 +++++++++++++----- Source/Project64/Settings/Settings Class.h | 80 +- Source/Project64/Settings/vssver2.scc | Bin 478 -> 0 bytes Source/Project64/Support/vssver2.scc | Bin 823 -> 0 bytes Source/Project64/User Interface.h | 4 +- .../User Interface/Bitmaps/vssver2.scc | Bin 471 -> 0 bytes .../User Interface/Frame Per Second Class.cpp | 16 +- Source/Project64/User Interface/Gui Class.cpp | 120 ++- Source/Project64/User Interface/Gui Class.h | 4 + .../User Interface/Icons/vssver2.scc | Bin 216 -> 0 bytes .../User Interface/Main Menu Class.cpp | 549 ++++------- .../User Interface/Main Menu Class.h | 19 +- .../Project64/User Interface/Menu Class.cpp | 213 +---- Source/Project64/User Interface/Menu Class.h | 54 +- .../User Interface/MenuShortCuts.cpp | 486 ++++++++++ .../Project64/User Interface/MenuShortCuts.h | 100 ++ .../User Interface/Notification Class.cpp | 97 +- .../User Interface/Notification Class.h | 9 +- .../User Interface/Rom Browser Class.cpp | 228 +++-- Source/Project64/User Interface/Rom Browser.h | 63 +- .../User Interface/Settings Config.cpp | 177 +++- .../User Interface/Settings Config.h | 8 +- .../Settings Page - Advanced Options.cpp | 52 + .../Settings Page - Advanced Options.h | 31 + .../Settings/Settings Page - Directories.cpp | 342 +++++++ .../Settings/Settings Page - Directories.h | 78 ++ .../Settings Page - Game - General.cpp | 70 +- .../Settings/Settings Page - Game - General.h | 25 +- .../Settings Page - Game - Plugin.cpp | 284 +++++- .../Settings/Settings Page - Game - Plugin.h | 50 +- .../Settings Page - Game - Recompiler.cpp | 53 +- .../Settings Page - Game - Recompiler.h | 24 +- .../Settings Page - Game - Status.cpp | 14 + .../Settings/Settings Page - Game - Status.h | 9 +- .../Settings/Settings Page - Game Browser.cpp | 247 +++++ .../Settings/Settings Page - Game Browser.h | 41 + .../Settings Page - Keyboard Shortcuts.cpp | 363 +++++++ .../Settings Page - Keyboard Shortcuts.h | 57 ++ .../Settings/Settings Page - Options.cpp | 43 + .../Settings/Settings Page - Options.h | 28 + .../Settings/Settings Page - Plugin.cpp | 294 ++++++ .../Settings/Settings Page - Plugin.h | 58 ++ .../User Interface/Settings/Settings Page.h | 289 +++++- .../Project64/User Interface/UI Resources.aps | Bin 310168 -> 309644 bytes .../Project64/User Interface/UI Resources.rc | 421 ++++---- .../WTL Controls/ModifiedCheckBox.h | 75 ++ .../WTL Controls/ModifiedComboBox.h | 140 +++ .../WTL Controls/ModifiedEditBox.cpp | 69 ++ .../WTL Controls/ModifiedEditBox.h | 30 + .../WTL Controls/PartialGroupBox.cpp | 97 ++ .../WTL Controls/PartialGroupBox.h | 26 + Source/Project64/User Interface/resource.h | 10 +- Source/Project64/ValidateBinary.cpp | 17 +- Source/Project64/WTL App.h | 4 + Source/Project64/main.cpp | 63 +- Source/Project64/res/vssver2.scc | Bin 153 -> 0 bytes 139 files changed, 8397 insertions(+), 2264 deletions(-) delete mode 100644 Project64.ncb delete mode 100644 Project64.opt delete mode 100644 Source/Project64/3rd Party/HTML Help/vssver2.scc delete mode 100644 Source/Project64/3rd Party/vssver2.scc delete mode 100644 Source/Project64/3rd Party/zlib/vssver2.scc delete mode 100644 Source/Project64/Multilanguage/vssver2.scc delete mode 100644 Source/Project64/N64 System/C Core/vssver2.scc delete mode 100644 Source/Project64/N64 System/Debugger/vssver2.scc delete mode 100644 Source/Project64/N64 System/Mips/vssver2.scc delete mode 100644 Source/Project64/N64 System/Recompiler/vssver2.scc delete mode 100644 Source/Project64/N64 System/vssver2.scc delete mode 100644 Source/Project64/Plugins/vssver2.scc create mode 100644 Source/Project64/Settings/SettingType/SettingsType-Cheats.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-Cheats.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.h create mode 100644 Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.cpp create mode 100644 Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.h delete mode 100644 Source/Project64/Settings/vssver2.scc delete mode 100644 Source/Project64/Support/vssver2.scc delete mode 100644 Source/Project64/User Interface/Bitmaps/vssver2.scc delete mode 100644 Source/Project64/User Interface/Icons/vssver2.scc create mode 100644 Source/Project64/User Interface/MenuShortCuts.cpp create mode 100644 Source/Project64/User Interface/MenuShortCuts.h create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Advanced Options.cpp create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Advanced Options.h create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Directories.cpp create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Directories.h create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Game Browser.cpp create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Game Browser.h create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.cpp create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.h create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Options.cpp create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Options.h create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Plugin.cpp create mode 100644 Source/Project64/User Interface/Settings/Settings Page - Plugin.h create mode 100644 Source/Project64/User Interface/WTL Controls/ModifiedCheckBox.h create mode 100644 Source/Project64/User Interface/WTL Controls/ModifiedComboBox.h create mode 100644 Source/Project64/User Interface/WTL Controls/ModifiedEditBox.cpp create mode 100644 Source/Project64/User Interface/WTL Controls/ModifiedEditBox.h create mode 100644 Source/Project64/User Interface/WTL Controls/PartialGroupBox.cpp create mode 100644 Source/Project64/User Interface/WTL Controls/PartialGroupBox.h delete mode 100644 Source/Project64/res/vssver2.scc diff --git a/Project64.ncb b/Project64.ncb deleted file mode 100644 index ad34d404846eac396a8658e4e67f0fc2c9ab8c5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1074176 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 z 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

qWWh{V6UsAYy?TbywP37{^(I*^3=t4% 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�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 diff --git a/Source/Project64/3rd Party/vssver2.scc b/Source/Project64/3rd Party/vssver2.scc deleted file mode 100644 index b6beb36eb31dc5328f7b3a771eaed2a14d941853..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAOeI2P3Mo{52hm4ShQg_(gtk?qp@w+}N7fkF(+ zf&9ey3+F^Lk_>@NhTT9SR(RHQ7~hbEfnnpcyUT-H%E9W5fP9VEUH?JyApI)(0Y&*) zsmUc~CNP$QnTdj-p1FQ-erZv1s=jeiib6nQQAs63Rc3)+27@^gm0VE30MwtHT3no8 Pq~MvCmam6JD1!k2VeXTMpDP6n8G(E* zAU{y1Y66VU4dlOE&FBo`1GO;l0QsLbdwh5rAPH8_3*^5QVDEzQ`GEY(bqe1)A8CWt z_W}8d=ifZrebfZ3UYUh~p-24jI+*z?Kz_)st;_8<$$;fmf&9E#hn!&Msptn3-`oa07Mail9#ziR#0f|K=mHJgVnMn+xeo>wQdd^VVgCWY<-_K3Y wgP|(3Krb0gW-vtgcsc=vK$M}Ou^y0Os7lGn(Mzo;fG|J?flSj&Nljw_00Ayrod5s; diff --git a/Source/Project64/Multilanguage.h b/Source/Project64/Multilanguage.h index d09137d61..4bed57f50 100644 --- a/Source/Project64/Multilanguage.h +++ b/Source/Project64/Multilanguage.h @@ -216,6 +216,7 @@ enum LanguageStringID{ PLUG_CTRL = 424, PLUG_HLE_GFX = 425, PLUG_HLE_AUDIO = 426, + PLUG_DEFAULT = 427, //Directory Dialog DIR_PLUGIN = 440, diff --git a/Source/Project64/Multilanguage/Language Class.cpp b/Source/Project64/Multilanguage/Language Class.cpp index 93d95a3ac..7ac1ca94f 100644 --- a/Source/Project64/Multilanguage/Language Class.cpp +++ b/Source/Project64/Multilanguage/Language Class.cpp @@ -167,6 +167,7 @@ void CLanguage::LoadDefaultStrings (void) { DEF_STR(PLUG_CTRL, " Input (controller) plugin: "); DEF_STR(PLUG_HLE_GFX, "Use High Level GFX?"); DEF_STR(PLUG_HLE_AUDIO,"Use High Level Audio?"); + DEF_STR(PLUG_DEFAULT, "** Use System Plugin **"); //Directory Dialog DEF_STR(DIR_PLUGIN, " Plugin Directoy: "); @@ -461,7 +462,7 @@ void CLanguage::LoadCurrentStrings ( bool ShowSelectDialog ) { if (ShowSelectDialog) { - m_SelectedLanguage = _Settings->LoadString(CurrentLanguage); + m_SelectedLanguage = _Settings->LoadString(Setting_CurrentLanguage); } LanguageList LangList = GetLangList(); @@ -917,9 +918,9 @@ LANG_STR CLanguage::GetNextLangString (void * OpenFile) { void CLanguage::SetLanguage ( char * LanguageName ) { - _Settings->SaveString(CurrentLanguage,LanguageName); m_SelectedLanguage = LanguageName; LoadCurrentStrings(false); + _Settings->SaveString(Setting_CurrentLanguage,LanguageName); } bool CLanguage::IsCurrentLang( LanguageFile & File ) diff --git a/Source/Project64/Multilanguage/vssver2.scc b/Source/Project64/Multilanguage/vssver2.scc deleted file mode 100644 index 02f978da589a0dfb6081d002085cda59efed850d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAO8=r5E0%*4O|L=61Q3=B&4p9R7qKJE|z@&$nW z{qxz@?LKN^$O7c6=m!+#XQd{Wn3=#>3T7q>hI;1u!TF^{$*KCjr8y;;If;4crHSdO W3_ehXf^$w{aj{-@l@1_J=Uj4#Uo diff --git a/Source/Project64/N64 System/C Core/C Core Interface.cpp b/Source/Project64/N64 System/C Core/C Core Interface.cpp index b288e5077..5a240cb54 100644 --- a/Source/Project64/N64 System/C Core/C Core Interface.cpp +++ b/Source/Project64/N64 System/C Core/C Core Interface.cpp @@ -176,35 +176,35 @@ void CC_Core::SetSettings ( ) g_Settings = _Settings; if (g_Settings) { - g_HaveDebugger = g_Settings->LoadDword(Debugger); + g_HaveDebugger = g_Settings->LoadBool(Debugger_Enabled); if (g_HaveDebugger) { - g_ShowUnhandledMemory = g_Settings->LoadDword(ShowUnhandledMemory); - g_ShowDListAListCount = g_Settings->LoadDword(ShowDListAListCount); + g_ShowUnhandledMemory = g_Settings->LoadBool(Debugger_ShowUnhandledMemory); + g_ShowDListAListCount = g_Settings->LoadDword(Debugger_ShowDListAListCount); } else { g_ShowUnhandledMemory = false; g_ShowUnhandledMemory = false; } - g_ShowCPUPer = g_Settings->LoadDword(ShowCPUPer); + g_ShowCPUPer = g_Settings->LoadDword(UserInterface_ShowCPUPer); g_ShowTLBMisses = false; - g_UseTlb = g_Settings->LoadDword(UseTLB); - g_CPU_Type = (CPU_TYPE)g_Settings->LoadDword(CPUType); - g_SaveUsing = (SAVE_CHIP_TYPE)g_Settings->LoadDword(SaveChipType); - g_AudioSignal = g_Settings->LoadDword(AudioSignal); - g_RdramSize = g_Settings->LoadDword(RamSize); - g_ShowPifRamErrors = g_Settings->LoadDword(ShowPifRamErrors); - g_CountPerOp = g_Settings->LoadDword(CounterFactor); - g_GenerateLog = g_Settings->LoadDword(GenerateDebugLog); - g_DelaySI = g_Settings->LoadDword(DelaySI); - g_SPHack = g_Settings->LoadDword(ROM_SPHack); - g_FixedAudio = g_Settings->LoadDword(ROM_FixedAudio); - g_LogX86Code = g_Settings->LoadDword(GenerateLogFiles); - g_LookUpMode = (FUNC_LOOKUP_METHOD)g_Settings->LoadDword(FuncLookupMode); - g_DisableRegCaching = !g_Settings->LoadDword(ROM_RegCache); - g_UseLinking = g_Settings->LoadDword(BlockLinking); + g_UseTlb = g_Settings->LoadBool(Game_UseTlb); + g_CPU_Type = (CPU_TYPE)g_Settings->LoadDword(Game_CpuType); + g_SaveUsing = (SAVE_CHIP_TYPE)g_Settings->LoadDword(Game_SaveChip); + g_AudioSignal = g_Settings->LoadBool(Game_RspAudioSignal); + g_RdramSize = g_Settings->LoadDword(Game_RDRamSize); + g_ShowPifRamErrors = g_Settings->LoadDword(Debugger_ShowPifErrors); + g_CountPerOp = g_Settings->LoadDword(Game_CounterFactor); + g_GenerateLog = g_Settings->LoadDword(Debugger_GenerateDebugLog); + g_DelaySI = g_Settings->LoadBool(Game_DelaySI); + g_SPHack = g_Settings->LoadBool(Game_SPHack); + g_FixedAudio = g_Settings->LoadBool(Game_FixedAudio); + g_LogX86Code = g_Settings->LoadBool(Debugger_GenerateLogFiles); + g_LookUpMode = (FUNC_LOOKUP_METHOD)g_Settings->LoadDword(Game_FuncLookupMode); + g_DisableRegCaching = !g_Settings->LoadBool(Game_RegCache); + g_UseLinking = g_Settings->LoadBool(Game_BlockLinking); g_ShowCompMem = false; - strcpy(g_RomName, g_Settings->LoadString(ROM_NAME).c_str()); + strcpy(g_RomName, g_Settings->LoadString(Game_GameName).c_str()); } } @@ -422,20 +422,18 @@ void DisplayMessage2 ( const char * Message, ... ) const char * GetAppName ( void ) { - static stdstr szAppName = g_Settings->LoadString(ApplicationName); + static stdstr szAppName = g_Settings->LoadString(Setting_ApplicationName); return szAppName.c_str(); } void GetAutoSaveDir( char * Directory ) { - SettingID Dir = g_Settings->LoadDword(UseSaveDirSelected) ? SelectedSaveDirectory : InitialSaveDirectory ; - strcpy(Directory,g_Settings->LoadString(Dir).c_str()); + strcpy(Directory,g_Settings->LoadString(Directory_NativeSave).c_str()); } void GetInstantSaveDir( char * Directory ) { - SettingID Dir = g_Settings->LoadDword(UseInstantDirSelected) ? SelectedInstantSaveDirectory : InitialInstantSaveDirectory ; - strcpy(Directory,g_Settings->LoadString(Dir).c_str()); + strcpy(Directory,g_Settings->LoadString(Directory_InstantSave).c_str()); } void SetFpuLocations( void ) @@ -445,7 +443,7 @@ void SetFpuLocations( void ) BOOL Limit_FPS ( void ) { - return g_Settings->LoadDword(LimitFPS); + return g_Settings->LoadDword(GameRunning_LimitFPS); } void DacrateChanged ( enum SystemType Type ) @@ -455,7 +453,7 @@ void DacrateChanged ( enum SystemType Type ) BOOL Close_C_CPU ( void ) { - if (g_Settings == NULL || !g_Settings->LoadDword(CPU_Running)) + if (g_Settings == NULL || !g_Settings->LoadBool(GameRunning_CPU_Running)) { return true; } @@ -533,7 +531,8 @@ void ApplyGSButtonCheats ( void ) void ChangePluginFunc ( void ) { g_Notify->DisplayMessage(0,MSG_PLUGIN_INIT); - if (g_Settings->LoadDword(GFX_PluginChanged)) + BreakPoint(__FILE__,__LINE__); + /*if (g_Settings->LoadDword(GFX_PluginChanged)) { g_Plugins->Reset(PLUGIN_TYPE_GFX); } @@ -555,7 +554,7 @@ void ChangePluginFunc ( void ) g_Settings->SaveDword(AUDIO_PluginChanged,(DWORD)false); g_Settings->SaveDword(GFX_PluginChanged, (DWORD)false); g_Settings->SaveDword(CONT_PluginChanged, (DWORD)false); - + */ g_Notify->RefreshMenu(); if (!g_Plugins->Initiate(g_N64System)) { g_Notify->DisplayMessage(5,MSG_PLUGIN_NOT_INIT); diff --git a/Source/Project64/N64 System/C Core/Dma.cpp b/Source/Project64/N64 System/C Core/Dma.cpp index 2284f166b..aeedb6182 100644 --- a/Source/Project64/N64 System/C Core/Dma.cpp +++ b/Source/Project64/N64 System/C Core/Dma.cpp @@ -100,10 +100,9 @@ void PI_DMA_WRITE (void) { DWORD i; PI_STATUS_REG |= PI_STATUS_DMA_BUSY; - if ( PI_DRAM_ADDR_REG + PI_WR_LEN_REG + 1 > RdramSize) { -#ifndef EXTERNAL_RELEASE - DisplayError("PI_DMA_WRITE not in Memory"); -#endif + if ( PI_DRAM_ADDR_REG + PI_WR_LEN_REG + 1 > RdramSize) + { + if (ShowUnhandledMemory) { DisplayError("PI_DMA_WRITE not in Memory"); } PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); @@ -164,7 +163,7 @@ void PI_DMA_WRITE (void) { CPU_Action.DMAUsed = TRUE; OnFirstDMA(); } - if (g_Recompiler && g_Recompiler->bSMM_PIDMA) + if (g_Recompiler && g_Recompiler->bSMM_PIDMA()) { g_Recompiler->ClearRecompCode_Phys(PI_DRAM_ADDR_REG, PI_WR_LEN_REG,CRecompiler::Remove_DMA); } @@ -176,9 +175,7 @@ void PI_DMA_WRITE (void) { return; } -#ifndef EXTERNAL_RELEASE if (ShowUnhandledMemory) { DisplayError("PI_DMA_WRITE not in ROM"); } -#endif PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; MI_INTR_REG |= MI_INTR_PI; CheckInterrupts(); diff --git a/Source/Project64/N64 System/C Core/Recompiler Ops.cpp b/Source/Project64/N64 System/C Core/Recompiler Ops.cpp index 4e2769144..587f0c5dc 100644 --- a/Source/Project64/N64 System/C Core/Recompiler Ops.cpp +++ b/Source/Project64/N64 System/C Core/Recompiler Ops.cpp @@ -135,7 +135,7 @@ void Compile_R4300i_Branch (CBlockSection * Section, void (*CompareFunc)(CBlockS CompareFunc(Section); if ((Section->CompilePC & 0xFFC) == 0xFFC) { - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; return; } @@ -220,7 +220,7 @@ void Compile_R4300i_Branch (CBlockSection * Section, void (*CompareFunc)(CBlockS memcpy(&Section->Cont.RegSet,&Section->RegWorking,sizeof(CRegInfo)); memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); } - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE @@ -276,7 +276,7 @@ void Compile_R4300i_BranchLikely (CBlockSection * Section, void (*CompareFunc)(C Section->JumpSection->DelaySlotSection = true; Section->Jump.TargetPC = Section->CompilePC + 4; Section->Jump.RegSet = Section->RegWorking; - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { if (Section->Cont.FallThrough) { @@ -285,7 +285,7 @@ void Compile_R4300i_BranchLikely (CBlockSection * Section, void (*CompareFunc)(C DisplayError("WTF .. problem with Compile_R4300i_BranchLikely"); #endif } - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { if ((Section->CompilePC & 0xFFC) == 0xFFC) { @@ -313,7 +313,7 @@ void Compile_R4300i_BranchLikely (CBlockSection * Section, void (*CompareFunc)(C g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC, Section->CompilePC + 8,Section->RegWorking,CExitInfo::Normal,TRUE,NULL); CPU_Message(" "); CPU_Message(" DoDelaySlot"); - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { NextInstruction = DO_DELAY_SLOT; @@ -323,7 +323,7 @@ void Compile_R4300i_BranchLikely (CBlockSection * Section, void (*CompareFunc)(C } else if (NextInstruction == DELAY_SLOT_DONE ) { Section->ResetX86Protection(); memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE @@ -1105,12 +1105,12 @@ void Compile_R4300i_J (CBlockSection * Section) { NextInstruction = DO_DELAY_SLOT; if ((Section->CompilePC & 0xFFC) == 0xFFC) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } } else if (NextInstruction == DELAY_SLOT_DONE ) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE @@ -1169,12 +1169,12 @@ void Compile_R4300i_JAL (CBlockSection * Section) { Section->Jump.LinkLocation2 = NULL; if ((Section->CompilePC & 0xFFC) == 0xFFC) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } } else if (NextInstruction == DELAY_SLOT_DONE ) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE @@ -2406,7 +2406,7 @@ void Compile_R4300i_SDR (CBlockSection * Section) { void Compile_R4300i_CACHE (CBlockSection * Section){ CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); - if (_Settings->LoadDword(SMM_Cache) == 0) + if (_Settings->LoadDword(Game_SMM_Cache) == 0) { return; } @@ -2933,7 +2933,7 @@ void Compile_R4300i_SPECIAL_JR (CBlockSection * Section) { Section->Cont.LinkLocation = NULL; Section->Cont.LinkLocation2 = NULL; if ((Section->CompilePC & 0xFFC) == 0xFFC) { - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; return; } @@ -2969,7 +2969,7 @@ void Compile_R4300i_SPECIAL_JR (CBlockSection * Section) { } else { if (Section->IsConst(Opcode.rs)) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); } else { if (Section->IsMapped(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rs),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); @@ -3027,7 +3027,7 @@ void Compile_R4300i_SPECIAL_JALR (CBlockSection * Section) { Section->Cont.LinkLocation = NULL; Section->Cont.LinkLocation2 = NULL; - GenerateSectionLinkage(Section); + g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); } else { if (Section->IsMapped(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rs),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); diff --git a/Source/Project64/N64 System/C Core/vssver2.scc b/Source/Project64/N64 System/C Core/vssver2.scc deleted file mode 100644 index 927f01fd7c39644683d7cfb570ee8848c24100fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1874 zcmZ|Ndu&rx90%|-V1Of0HWi}?yTZmpwyx09p=ATsZ5@=d((VOA+-<$Aw5>)!Xs#6Yxgig-*+qvwDPN5{46PDJj$2&oEDh zJ3B7i+VcGO`WV!c;Ka?d_n6}v!(-rNIAU&T@?QUm^-qCUn7b-Zy?KS5XDWQSS--93 z+cg40G7ZDo{1r2lqv!P_;ps4UH}*w(p0V(gaMRbL-gvb2qCOU$0V{5&LQVHife+Mw z(R%EMwXe~7DqOho@#@`wTx0v|;EAD?{LxLDSbrKU%k{StC)YC5rZU%tGt?t6eP&X8kDi&xUU-`fFVLV-2is zg5Ns-?)IyV+u8G_!_~(g@Z365&(@m*kF;O@%A8_jehRkvDidix-T!HLqi|Q3Z`#Aw zGs9c%^c=MEMeO`@;iT+C`!r|3$Bkp#s1cG(4EAfooT;M<*n0Ee(Wko#sp);qhu0sn z-3*sJ%jyf@RgqVkspGv|ruIG$KeKGuZM#IbV*PVPHA+cjj*oa1HRY&(4~W!X7)Tw;j%C5O1qje+5I_TsiS+mR(HX_sd055#J3yh`ze6;R+j%s zP4BA^roXKp*Q}@CQxSFEfgNqZ4*KbkVhph@v9q=Q5_s30Q^&RSmchSVUpDup<_KGV zIjpPSHDUkHjRv}2DZF=XjLEk1N48#4nnMk&5FaF&27kStZ;D;xpI9}4O`gCvsP7H*+GB&g-QN6>i`<-bX-Pe%i*FW}~VToJEI zyxS+RoXksptZm`!f*er8(N&_rBpict389eW_Xg<%ML1VJPm4EBoaHl1^fxJ!dIYT&#^le*mQZsA(ex46p6!Eg^4s! z1Lcyhca8p7B&yM%*GqVHvdsIRqq`5y^z~@Bt#$NWcyxwS@Jjd+)B%h1r$piuJONpe zeA-pu)elJx>d95AICdR_`~D|Ir}pj6W@r+Li@pm_?;jNQd!p~6FBD0^;w&y(3MxJx tpA!lB+A}N;qhFJxYjBmv=5F%MK$HbK@RY;f2F-1p_{0oKe7g_)S diff --git a/Source/Project64/N64 System/Cheat Class.cpp b/Source/Project64/N64 System/Cheat Class.cpp index 357b7f604..612d2e8bf 100644 --- a/Source/Project64/N64 System/Cheat Class.cpp +++ b/Source/Project64/N64 System/Cheat Class.cpp @@ -48,18 +48,18 @@ bool CCheats::LoadCode (int CheatNo, LPCSTR CheatString) if (strncmp(ReadPos,"????",4) == 0) { if (CheatNo < 0 || CheatNo > MaxCheats) { return false; } - stdstr CheatExt = _Settings->LoadString((SettingID)(CheatExtension + CheatNo)); + stdstr CheatExt = _Settings->LoadStringIndex(Cheat_Extension,CheatNo); if (CheatExt.empty()) { return false; } CodeEntry.Value = CheatExt[0] == '$'?(WORD)AsciiToHex(&CheatExt.c_str()[1]):(WORD)atol(CheatExt.c_str()); } else if (strncmp(ReadPos,"??",2) == 0) { if (CheatNo < 0 || CheatNo > MaxCheats) { return false; } - stdstr CheatExt = _Settings->LoadString((SettingID)(CheatExtension + CheatNo)); + stdstr CheatExt = _Settings->LoadStringIndex(Cheat_Extension,CheatNo); if (CheatExt.empty()) { return false; } CodeEntry.Value = (BYTE)(AsciiToHex(ReadPos)); CodeEntry.Value |= (CheatExt[0] == '$'?(BYTE)AsciiToHex(&CheatExt.c_str()[1]):(BYTE)atol(CheatExt.c_str())) << 16; } else if (strncmp(&ReadPos[2],"??",2) == 0) { if (CheatNo < 0 || CheatNo > MaxCheats) { return false; } - stdstr CheatExt = _Settings->LoadString((SettingID)(CheatExtension + CheatNo)); + stdstr CheatExt = _Settings->LoadStringIndex(Cheat_Extension,CheatNo); if (CheatExt.empty()) { return false; } CodeEntry.Value = (WORD)(AsciiToHex(ReadPos) << 16); CodeEntry.Value |= CheatExt[0] == '$'?(BYTE)AsciiToHex(&CheatExt.c_str()[1]):(BYTE)atol(CheatExt.c_str()); @@ -86,14 +86,17 @@ bool CCheats::LoadCode (int CheatNo, LPCSTR CheatString) void CCheats::LoadPermCheats (void) { - if (_Settings->LoadDword(DisableGameFixes)) + if (_Settings->LoadBool(Debugger_DisableGameFixes)) { return; } for (int CheatNo = 0; CheatNo < MaxCheats; CheatNo ++ ) { - stdstr LineEntry = _Settings->LoadString((SettingID)(CheatPermEntry + CheatNo)); - if (LineEntry.empty()) { break; } + stdstr LineEntry; + if (!_Settings->LoadStringIndex(Rdb_GameCheatFix,CheatNo,LineEntry) || LineEntry.empty()) + { + break; + } LoadCode(-1, LineEntry.c_str()); } } @@ -105,19 +108,19 @@ void CCheats::LoadCheats(bool DisableSelected) { for (int CheatNo = 0; CheatNo < MaxCheats; CheatNo ++ ) { - stdstr LineEntry = _Settings->LoadString((SettingID)(CheatEntry + CheatNo)); + stdstr LineEntry = _Settings->LoadStringIndex(Cheat_Entry,CheatNo); if (LineEntry.empty()) { break; } - if (!_Settings->LoadDword((SettingID)(CheatActive + CheatNo))) + if (!_Settings->LoadBoolIndex(Cheat_Active,CheatNo)) { continue; } if (DisableSelected) { - _Settings->SaveDword((SettingID)(CheatActive + CheatNo),(DWORD)false); + _Settings->SaveBoolIndex(Cheat_Active,CheatNo,false); continue; } - //Find the start and end of the name which is surronded in "" + //Find the start and end of the name which is surrounded in "" int StartOfName = LineEntry.find("\""); if (StartOfName == -1) { continue; } int EndOfName = LineEntry.find("\"",StartOfName + 1); @@ -514,12 +517,13 @@ void CCheats::AddCodeLayers (int CheatNumber, stdstr &CheatName, WND_HANDLE hPar AddCodeLayers(CheatNumber,(stdstr)(CheatName.substr(strlen(Text) + 1)), hParent, CheatActive); } -stdstr CCheats::GetCheatName(int CheatNo, bool AddExtension) const { +stdstr CCheats::GetCheatName(int CheatNo, bool AddExtension) const +{ if (CheatNo > MaxCheats) { _Notify->BreakPoint(__FILE__,__LINE__); } - stdstr LineEntry = _Settings->LoadString((SettingID)(CheatEntry + CheatNo)); + stdstr LineEntry = _Settings->LoadStringIndex(Cheat_Entry,CheatNo); if (LineEntry.length() == 0) { return LineEntry; } - //Find the start and end of the name which is surronded in "" + //Find the start and end of the name which is surrounded in "" int StartOfName = LineEntry.find("\""); if (StartOfName == -1) { return stdstr(""); } int EndOfName = LineEntry.find("\"",StartOfName + 1); @@ -533,7 +537,7 @@ stdstr CCheats::GetCheatName(int CheatNo, bool AddExtension) const { Name.replace("\\","\\*** "); } if (AddExtension && CheatUsesCodeExtensions(LineEntry)) { - stdstr CheatValue(_Settings->LoadString((SettingID)(CheatExtension + CheatNo))); + stdstr CheatValue(_Settings->LoadStringIndex(Cheat_Extension,CheatNo)); Name.Format("%s (=>%s)",Name.c_str(),CheatValue.c_str()); } @@ -563,7 +567,8 @@ bool CCheats::CheatUsesCodeExtensions (const stdstr &LineEntry) { return CodeExtension; } -void CCheats::RefreshCheatManager(void) { +void CCheats::RefreshCheatManager(void) +{ if (m_Window == NULL) { return; } int CurrentEdit = m_EditCheat; @@ -575,7 +580,7 @@ void CCheats::RefreshCheatManager(void) { stdstr Name = GetCheatName(count,true); if (Name.length() == 0) { break; } - AddCodeLayers(count,Name,(WND_HANDLE)TVI_ROOT, _Settings->LoadDword((SettingID)(CheatActive + count)) != 0); + AddCodeLayers(count,Name,(WND_HANDLE)TVI_ROOT, _Settings->LoadBoolIndex(Cheat_Active,count) != 0); } } @@ -771,9 +776,9 @@ int CALLBACK CCheats::CheatAddProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DWO stdstr_f Cheat("\"%s\"%s",NewCheatName.c_str(),ReadCodeString(hDlg,validcodes,validoptions,nooptions,CodeFormat).c_str()); stdstr Options = ReadOptionsString(hDlg,validcodes,validoptions,nooptions,CodeFormat); - _Settings->SaveString((SettingID)(CheatEntry + _this->m_EditCheat),Cheat.c_str()); - _Settings->SaveString((SettingID)(CheatNotes + _this->m_EditCheat),GetDlgItemStr(hDlg,IDC_NOTES).c_str()); - _Settings->SaveString((SettingID)(CheatOptions + _this->m_EditCheat),Options.c_str()); + _Settings->SaveStringIndex(Cheat_Entry, _this->m_EditCheat,Cheat.c_str()); + _Settings->SaveStringIndex(Cheat_Notes, _this->m_EditCheat,GetDlgItemStr(hDlg,IDC_NOTES)); + _Settings->SaveStringIndex(Cheat_Options, _this->m_EditCheat,Options); _this->RecordCheatValues(hDlg); _this->RefreshCheatManager(); } @@ -815,7 +820,7 @@ int CALLBACK CCheats::CheatAddProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DWO break; } - stdstr CheatEntryStr = _Settings->LoadString((SettingID)(CheatEntry + _this->m_EditCheat)); + stdstr CheatEntryStr = _Settings->LoadStringIndex(Cheat_Entry,_this->m_EditCheat); LPCSTR String = CheatEntryStr.c_str(); //Set Cheat Name @@ -845,7 +850,7 @@ int CALLBACK CCheats::CheatAddProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DWO SetDlgItemText((HWND)hDlg,IDC_CHEAT_CODES,Buffer.c_str()); //Add option values to screen - stdstr CheatOptionStr = _Settings->LoadString((SettingID)(CheatOptions + _this->m_EditCheat)); + stdstr CheatOptionStr = _Settings->LoadStringIndex(Cheat_Options,_this->m_EditCheat); ReadPos = strchr(CheatOptionStr.c_str(),'$'); Buffer.erase(); if (ReadPos) { @@ -868,7 +873,7 @@ int CALLBACK CCheats::CheatAddProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DWO SetDlgItemText((HWND)hDlg,IDC_CHEAT_OPTIONS,Buffer.c_str()); //Add cheat Notes - stdstr CheatNotesStr = _Settings->LoadString((SettingID)(CheatNotes + _this->m_EditCheat)); + stdstr CheatNotesStr = _Settings->LoadStringIndex(Cheat_Notes,_this->m_EditCheat); SetDlgItemText((HWND)hDlg,IDC_NOTES,CheatNotesStr.c_str()); @@ -984,7 +989,7 @@ int CALLBACK CCheats::CheatListProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DW TreeView_HitTest(lpnmh->hwndFrom, &ht); _this->m_hSelectedItem = (WND_HANDLE)ht.hItem; - if (_Settings->LoadDword(BasicMode)) { return true; } + if (_Settings->LoadBool(UserInterface_BasicMode)) { return true; } //Show Menu HMENU hMenu = LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_CHEAT_MENU)); @@ -1031,12 +1036,13 @@ int CALLBACK CCheats::CheatListProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DW item.mask = TVIF_PARAM ; item.hItem = (HTREEITEM)ht.hItem; TreeView_GetItem((HWND)_this->m_hCheatTree,&item); - stdstr LineEntry = _Settings->LoadString((SettingID)(CheatEntry + item.lParam)); - if (CheatUsesCodeExtensions(LineEntry)) { - if (_Settings->LoadString((SettingID)(CheatExtension + item.lParam)) ==_Settings->LoadString(Default_CheatExt)) { + stdstr LineEntry = _Settings->LoadStringIndex(Cheat_Entry,item.lParam); + if (CheatUsesCodeExtensions(LineEntry)) + { + stdstr CheatExtension; + if (!_Settings->LoadStringIndex(Cheat_Extension,item.lParam,CheatExtension)) + { SendMessage((HWND)hDlg, UM_CHANGECODEEXTENSION, 0, (LPARAM)ht.hItem); - } - if (_Settings->LoadString((SettingID)(CheatExtension + item.lParam)) ==_Settings->LoadString(Default_CheatExt)) { TV_SetCheckState(_this->m_hCheatTree,(WND_HANDLE)ht.hItem,TV_STATE_CLEAR); break; } @@ -1089,7 +1095,7 @@ int CALLBACK CCheats::CheatListProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DW item.hItem = hItem; TreeView_GetItem((HWND)_this->m_hCheatTree,&item); - stdstr Notes(_Settings->LoadString((SettingID)(CheatNotes + item.lParam))); + stdstr Notes(_Settings->LoadStringIndex(Cheat_Notes,item.lParam)); SetDlgItemText((HWND)hDlg,IDC_NOTES,Notes.c_str()); if (_this->m_AddCheat) { @@ -1113,15 +1119,17 @@ int CALLBACK CCheats::CheatListProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, DW TreeView_GetItem((HWND)_this->m_hCheatTree,&item); //Make sure the selected line can use code extensions - stdstr LineEntry = _Settings->LoadString((SettingID)(CheatEntry + item.lParam)); + stdstr LineEntry = _Settings->LoadStringIndex(Cheat_Entry,item.lParam); if (!CheatUsesCodeExtensions(LineEntry)) { break; } - stdstr Options(_Settings->LoadString((SettingID)(CheatOptions + item.lParam))); - if (Options.length() > 0) { + stdstr Options; + if (_Settings->LoadStringIndex(Cheat_Options,item.lParam,Options) && Options.length() > 0) + { DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_Cheats_CodeEx),(HWND)hDlg,(DLGPROC)CheatsCodeExProc,(LPARAM)_this); } else { - stdstr Range(_Settings->LoadString((SettingID)(CheatRange + item.lParam))); - if (Range.length() > 0) { + stdstr Range; + if (_Settings->LoadStringIndex(Cheat_Range,item.lParam,Range) && Range.length() > 0) + { DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_Cheats_Range),(HWND)hDlg,(DLGPROC)CheatsCodeQuantProc,(LPARAM)_this); } } @@ -1168,8 +1176,8 @@ int CALLBACK CCheats::CheatsCodeExProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, SetDlgItemText((HWND)hDlg,IDC_CHEAT_NAME,CheatName.c_str()); //Read through and add all options to the list box - stdstr Options(_Settings->LoadString((SettingID)(CheatOptions + item.lParam))); - stdstr CurrentExt(_Settings->LoadString((SettingID)(CheatExtension + item.lParam))); + stdstr Options(_Settings->LoadStringIndex(Cheat_Options,item.lParam)); + stdstr CurrentExt(_Settings->LoadStringIndex(Cheat_Extension,item.lParam)); const char * ReadPos = Options.c_str(); while (*ReadPos != 0) { const char * NextComma = strchr(ReadPos,','); @@ -1206,7 +1214,7 @@ int CALLBACK CCheats::CheatsCodeExProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, if (index < 0) { index = 0; } SendMessage(GetDlgItem((HWND)hDlg,IDC_CHEAT_LIST),LB_GETTEXT,index,(LPARAM)CheatExten); - _Settings->SaveString((SettingID)(CheatExtension + item.lParam),CheatExten); + _Settings->SaveStringIndex(Cheat_Extension,item.lParam,CheatExten); _this->m_CheatSelectionChanged = true; } RemoveProp((HWND)hDlg,"Class"); @@ -1238,9 +1246,9 @@ int CALLBACK CCheats::CheatsCodeQuantProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wPar item.mask = TVIF_PARAM ; TreeView_GetItem((HWND)_this->m_hCheatTree,&item); stdstr CheatName = _this->GetCheatName(item.lParam,false); - stdstr RangeNote(_Settings->LoadString((SettingID)(CheatRangeNotes + item.lParam))); - stdstr Range(_Settings->LoadString((SettingID)(CheatRange + item.lParam))); - stdstr Value(_Settings->LoadString((SettingID)(CheatExtension + item.lParam))); + stdstr RangeNote(_Settings->LoadStringIndex(Cheat_RangeNotes, item.lParam)); + stdstr Range(_Settings->LoadStringIndex(Cheat_Range,item.lParam)); + stdstr Value(_Settings->LoadStringIndex(Cheat_Extension,item.lParam)); //Set up language support for dialog SetWindowText((HWND)hDlg, GS(CHEAT_CODE_EXT_TITLE)); @@ -1306,7 +1314,7 @@ int CALLBACK CCheats::CheatsCodeQuantProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wPar if (Value < Start) { Value = Start; } sprintf(CheatExten,"$%X",Value); - _Settings->SaveString((SettingID)(CheatExtension + item.lParam),CheatExten); + _Settings->SaveStringIndex(Cheat_Extension, item.lParam,CheatExten); _this->m_CheatSelectionChanged = true; } RemoveProp((HWND)hDlg,"Class"); @@ -1350,7 +1358,7 @@ int CALLBACK CCheats::ManageCheatsProc (WND_HANDLE hDlg,DWORD uMsg,DWORD wParam, ShowWindow((HWND)_this->m_hSelectCheat,SW_SHOW); RECT * rc = &WndPlac.rcNormalPosition; - if (_Settings->LoadDword(BasicMode)) + if (_Settings->LoadDword(UserInterface_BasicMode)) { RECT * rcAdd = (RECT *)_this->m_rcAdd, * rcList = (RECT *)_this->m_rcList; GetWindowRect(GetDlgItem((HWND)_this->m_hSelectCheat, IDC_CHEATSFRAME), rcList); @@ -1538,16 +1546,18 @@ void CCheats::ChangeChildrenStatus(WND_HANDLE hParent, bool Checked) { //if cheat uses a extension and it is not set then do not set it if (Checked) { - stdstr LineEntry = _Settings->LoadString((SettingID)(CheatEntry + item.lParam)); + stdstr LineEntry = _Settings->LoadStringIndex(Cheat_Entry,item.lParam); if (CheatUsesCodeExtensions(LineEntry)) { - if (_Settings->LoadString((SettingID)(CheatExtension + item.lParam)) ==_Settings->LoadString(Default_CheatExt)) { + stdstr CheatExten; + if (!_Settings->LoadStringIndex(Cheat_Extension,item.lParam,CheatExten) || CheatExten.empty()) + { return; } } } //Save Cheat TV_SetCheckState(m_hCheatTree,hParent,Checked?TV_STATE_CHECKED:TV_STATE_CLEAR); - _Settings->SaveDword((SettingID)(CheatActive + item.lParam),Checked); + _Settings->SaveDwordIndex(Cheat_Active,item.lParam,Checked); return; } TV_CHECK_STATE state = TV_STATE_UNKNOWN; diff --git a/Source/Project64/N64 System/Cheat Class.h b/Source/Project64/N64 System/Cheat Class.h index 2f2605f28..807e01023 100644 --- a/Source/Project64/N64 System/Cheat Class.h +++ b/Source/Project64/N64 System/Cheat Class.h @@ -7,6 +7,7 @@ class CCheats { typedef std::vector CODES; typedef std::vector CODES_ARRAY; + enum { MaxCheats = 50000 }; CNotification * const _Notify; CN64Rom * const _Rom; diff --git a/Source/Project64/N64 System/Debugger/vssver2.scc b/Source/Project64/N64 System/Debugger/vssver2.scc deleted file mode 100644 index c44d89bdf0e1c32bc164979ae7812dd14a580223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 560 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAOmOrD)A!otA7%fP@O3Zzf{TNk?Y#vEf-AYTl~ z|9@KU(SNIX#>_yzIFPT>K1US92QnEXfW#-&)cDO0Cxg{X0{I_xGsJDf7J=1E0r@i% zc=m*ESPE7z!^6OkCoORe#0Qxt3*=8~zwZv?&*f)enD;t3qAUn_UPQV<_x z-+UlnyDz`tDennmCLn(SkPiZ%wayze0_lZ7{zB9JD;A{wZv&aHq90I{pOu8g06yZYHof}rGiUoZh>BM zK>;qQ42Be_X1xr!8gva|nW^Pa1Cdk#EkTw*vn0gF2~{mf08I_ljlrpjMadbcs!^rj Z`V?F;6La#@VQOJqxI8cr6hb|L(g1gUszm?* diff --git a/Source/Project64/N64 System/Mips/Memory.cpp b/Source/Project64/N64 System/Mips/Memory.cpp index ab460cccc..da5bb831e 100644 --- a/Source/Project64/N64 System/Mips/Memory.cpp +++ b/Source/Project64/N64 System/Mips/Memory.cpp @@ -86,7 +86,7 @@ void CMipsMemory::AllocateSystemMemory (void) } DWORD RdramMemorySize = 0x20000000; - if ((CPU_TYPE)_Settings->LoadDword(ROM_CPUType) == CPU_SyncCores) + if ((CPU_TYPE)_Settings->LoadDword(Game_CpuType) == CPU_SyncCores) { RdramMemorySize = 0x18000000; } @@ -107,7 +107,7 @@ void CMipsMemory::AllocateSystemMemory (void) DMEM = (unsigned char *)(RDRAM+0x04000000); IMEM = (unsigned char *)(RDRAM+0x04001000); - if (_Settings->LoadDword(RomInMemory)) + if (_Settings->LoadBool(Game_LoadRomToMemory)) { if(VirtualAlloc(RDRAM + 0x10000000, m_RomFileSize, MEM_COMMIT, PAGE_READWRITE)==NULL) { _Notify->FatalError(GS(MSG_MEM_ALLOC_ERROR)); @@ -129,7 +129,7 @@ bool CMipsMemory::AllocateRecompilerMemory ( bool AllocateJumpTable ) JumpTable = NULL; if (AllocateJumpTable) { - DWORD JumpTableSize = _Settings->LoadDword(RomInMemory) ? 0x20000000 : 0x10000000; + DWORD JumpTableSize = _Settings->LoadDword(Game_LoadRomToMemory) ? 0x20000000 : 0x10000000; JumpTable = (void **)VirtualAlloc( NULL, JumpTableSize, MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE ); if( JumpTable == NULL ) { _Notify->DisplayError(MSG_MEM_ALLOC_ERROR); @@ -147,7 +147,7 @@ bool CMipsMemory::AllocateRecompilerMemory ( bool AllocateJumpTable ) return FALSE; } - if (_Settings->LoadDword(RomInMemory)) + if (_Settings->LoadDword(Game_LoadRomToMemory)) { if(VirtualAlloc((BYTE *)JumpTable + 0x10000000, m_RomFileSize, MEM_COMMIT, PAGE_READWRITE)==NULL) { _Notify->DisplayError(MSG_MEM_ALLOC_ERROR); @@ -193,7 +193,7 @@ void CMipsMemory::CheckRecompMem( BYTE * RecompPos ) } void CMipsMemory::FixRDramSize ( void ) { - if (_Settings->LoadDword(RamSize) != m_AllocatedRdramSize) { + if (_Settings->LoadDword(Game_RDRamSize) != m_AllocatedRdramSize) { if (m_AllocatedRdramSize == 0x400000) { if (VirtualAlloc(RDRAM + 0x400000, 0x400000, MEM_COMMIT, PAGE_READWRITE)==NULL) { _Notify->FatalError(GS(MSG_MEM_ALLOC_ERROR)); @@ -213,25 +213,31 @@ bool CMipsMemory::Store64 ( DWORD VAddr, QWORD Value, MemorySize Size ) { _Notify->BreakPoint(__FILE__,__LINE__); return false; } - if (PAddr > _Settings->LoadDword(RamSize) && + if (PAddr > _Settings->LoadDword(Game_RDRamSize) && (PAddr < 0x04000000 || PAddr > 0x04002000)) { -// switch (Size) { -// case _16Bit: -// if (!StoreHalf_NonMemory(PAddr,static_cast(Value))) { -// MemoryFilterFailed("Store word",PAddr,PROGRAM_COUNTER, static_cast(Value)); -// } -// return true; -// break; -// case _32Bit: -// if (!StoreWord_NonMemory(PAddr,static_cast(Value))) { -// MemoryFilterFailed("Store word",PAddr,PROGRAM_COUNTER, static_cast(Value)); -// } -// return true; -// break; -// default: + switch (Size) { + case _8Bit: + if (!StoreByte_NonMemory(PAddr,static_cast(Value))) { + //MemoryFilterFailed("Store word",PAddr,PROGRAM_COUNTER, static_cast(Value)); + } + return true; + break; + case _16Bit: + if (!StoreHalf_NonMemory(PAddr,static_cast(Value))) { + //MemoryFilterFailed("Store word",PAddr,PROGRAM_COUNTER, static_cast(Value)); + } + return true; + break; + case _32Bit: + if (!StoreWord_NonMemory(PAddr,static_cast(Value))) { + //MemoryFilterFailed("Store word",PAddr,PROGRAM_COUNTER, static_cast(Value)); + } + return true; + break; + default: _Notify->BreakPoint(__FILE__,__LINE__); -// } + } return false; } @@ -356,7 +362,7 @@ bool CMipsMemory::LoadPhysical32 ( DWORD PAddr, DWORD & Variable, MemorySize Siz } void CMipsMemory::MemoryFilterFailed( char * FailureType, DWORD MipsAddress, DWORD x86Address, DWORD Value) { - if (_Settings->LoadDword(ShowUnhandledMemory)) { + if (_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { _Notify->DisplayError("Failed to %s\n\nProgram Counter: %X\nMIPS Address: %08X\nX86 Address: %X\n Value: %X", FailureType, _Reg->PROGRAM_COUNTER, MipsAddress, x86Address, Value); } @@ -373,7 +379,7 @@ bool CMipsMemory::Load64 ( DWORD VAddr, QWORD & Variable, MemorySize Size, bool if (!TranslateVaddr(VAddr,PAddr)) { return false; } - if (PAddr > _Settings->LoadDword(RamSize) && + if (PAddr > _Settings->LoadDword(Game_RDRamSize) && (PAddr < 0x04000000 || PAddr > 0x04002000)) { switch (Size) { @@ -629,7 +635,7 @@ bool CMipsMemory::Store64 ( DWORD VAddr, QWORD Value, MemorySize Size ) { _Notify->BreakPoint(__FILE__,__LINE__); return false; } - if (PAddr > _Settings->LoadDword(RamSize) && + if (PAddr > _Settings->LoadDword(Game_RDRamSize) && (PAddr < 0x04000000 || PAddr > 0x04002000)) { switch (Size) { @@ -699,7 +705,7 @@ bool CMipsMemory::StoreByte_NonMemory ( DWORD PAddr, BYTE Value ) { case 0x00500000: case 0x00600000: case 0x00700000: - if (PAddr < _Settings->LoadDword(RamSize)) { + if (PAddr < _Settings->LoadDword(Game_RDRamSize)) { // CRecompiler * Recomp = _System->GetRecompiler(); // if (Recomp) { // Recomp->ClearRecomplierCode(PAddr + 0x80000000,1); @@ -727,7 +733,7 @@ bool CMipsMemory::StoreHalf_NonMemory ( DWORD PAddr, WORD Value ) { case 0x00500000: case 0x00600000: case 0x00700000: - if (PAddr < _Settings->LoadDword(RamSize)) { + if (PAddr < _Settings->LoadDword(Game_RDRamSize)) { // CRecompiler * Recomp = _System->GetRecompiler(); // if (Recomp) { // Recomp->ClearRecomplierCode(PAddr + 0x80000000,1); @@ -765,7 +771,7 @@ bool CMipsMemory::StoreWord_NonMemory ( DWORD PAddr, DWORD Value ) { case 0x00500000: case 0x00600000: case 0x00700000: - if (PAddr < _Settings->LoadDword(RamSize)) { + if (PAddr < _Settings->LoadDword(Game_RDRamSize)) { // CRecompiler * Recomp = _System->GetRecompiler(); // if (Recomp) { // Recomp->ClearRecomplierCode(PAddr + 0x80000000,4); @@ -1144,7 +1150,7 @@ int CMipsMemory::SystemMemoryFilter( DWORD dwExptCode, void * lpExceptionPointer int End = (Start + (lpEP->ContextRecord->Ecx << 2) - 1); if ((int)Start < 0) { _Notify->BreakPoint(__FILE__,__LINE__); } - if ((int)End < _Settings->LoadDword(RamSize)) { + if ((int)End < _Settings->LoadDword(Game_RDRamSize)) { for ( int count = Start & ~0x1000; count < End; count += 0x1000 ) { CBClass->WriteToProtectedMemory(Start, 0xFFF); } diff --git a/Source/Project64/N64 System/Mips/OpCode Class.cpp b/Source/Project64/N64 System/Mips/OpCode Class.cpp index f51ca89a7..96a786860 100644 --- a/Source/Project64/N64 System/Mips/OpCode Class.cpp +++ b/Source/Project64/N64 System/Mips/OpCode Class.cpp @@ -27,8 +27,8 @@ COpcode::COpcode ( CMipsMemory * MMU, DWORD VirtualAddress ): _MMU(MMU), _Reg(MMU->SystemRegisters()), m_OpLen(OpCode_Size), - m_OpcodeCount(_Settings->LoadDword(CounterFactor)), - m_FixedOpcodeCount(_Settings->LoadDword(CounterFactor) != 0) + m_OpcodeCount(_Settings->LoadDword(Game_CounterFactor)), + m_FixedOpcodeCount(_Settings->LoadDword(Game_CounterFactor) != 0) { //setup details about handling opcodes m_NextStep = StepNormal; diff --git a/Source/Project64/N64 System/Mips/TLB class.cpp b/Source/Project64/N64 System/Mips/TLB class.cpp index ee42911d7..ca3cea9f1 100644 --- a/Source/Project64/N64 System/Mips/TLB class.cpp +++ b/Source/Project64/N64 System/Mips/TLB class.cpp @@ -55,11 +55,11 @@ void CTLB::TLB_Reset (bool InvalidateTLB) { for (count = 0; count < 32; count ++) { SetupTLB_Entry(count,false); } //GE Hack - if (_Settings->LoadDword(ROM_TLB_VAddrStart) != 0) + if (_Settings->LoadDword(Rdb_TLB_VAddrStart) != 0) { - DWORD Start = _Settings->LoadDword(ROM_TLB_VAddrStart); //0x7F000000; - DWORD Len = _Settings->LoadDword(ROM_TLB_VAddrLen); //0x01000000; - DWORD PAddr = _Settings->LoadDword(ROM_TLB_PAddrStart); //0x10034b30; + DWORD Start = _Settings->LoadDword(Rdb_TLB_VAddrStart); //0x7F000000; + DWORD Len = _Settings->LoadDword(Rdb_TLB_VAddrLen); //0x01000000; + DWORD PAddr = _Settings->LoadDword(Rdb_TLB_PAddrStart); //0x10034b30; DWORD End = Start + Len; for (count = Start; count < End; count += 0x1000) { TLB_ReadMap[count >> 12] = ((DWORD)m_BasePAddr + (count - Start + PAddr)) - count; diff --git a/Source/Project64/N64 System/Mips/vssver2.scc b/Source/Project64/N64 System/Mips/vssver2.scc deleted file mode 100644 index f0f405c7a65fe788940a83345b3bfd74172d6145..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAOuF1o`0lZk;rkb!|AhM9rkANMn}SPma!E+9V^ z$oJcrFlS@=`j@;wejJd$emNb11n(iD*6FM`B|ySC1xftmV%jyf}x(d zesF$iQF5xjACMbdSzMButM8jxP|V<)nwwu#soDoSomething = TRUE; break; case CPUUsageTimerChanged: - g_ShowCPUPer = _Settings->LoadDword(ShowCPUPer); + g_ShowCPUPer = _Settings->LoadDword(UserInterface_ShowCPUPer); break; case PauseCPU_FromMenu: - if (!_Settings->LoadDword(CPU_Paused)) + if (!_Settings->LoadBool(GameRunning_CPU_Paused)) { - _Settings->SaveDword(CPU_Paused_type, PauseType_FromMenu); + _Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_FromMenu); g_CPU_Action->Pause = TRUE; g_CPU_Action->DoSomething = TRUE; } break; case PauseCPU_AppLostFocus: - if (!_Settings->LoadDword(CPU_Paused) && !g_CPU_Action->Pause) + if (!_Settings->LoadBool(GameRunning_CPU_Paused) && !g_CPU_Action->Pause) { - _Settings->SaveDword(CPU_Paused_type, PauseType_AppLostFocus); + _Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostFocus); g_CPU_Action->Pause = TRUE; g_CPU_Action->DoSomething = TRUE; } break; case PauseCPU_AppLostActive: - if (!_Settings->LoadDword(CPU_Paused)) + if (!_Settings->LoadBool(GameRunning_CPU_Paused)) { g_CPU_Action->Pause = TRUE; g_CPU_Action->DoSomething = TRUE; - _Settings->SaveDword(CPU_Paused_type, PauseType_AppLostActive); + _Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostActive); } break; case PauseCPU_SaveGame: - if (!_Settings->LoadDword(CPU_Paused)) + if (!_Settings->LoadBool(GameRunning_CPU_Paused)) { - _Settings->SaveDword(CPU_Paused_type, PauseType_SaveGame); + _Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_SaveGame); g_CPU_Action->Pause = TRUE; g_CPU_Action->DoSomething = TRUE; } break; case PauseCPU_LoadGame: - if (!_Settings->LoadDword(CPU_Paused)) + if (!_Settings->LoadBool(GameRunning_CPU_Paused)) { - _Settings->SaveDword(CPU_Paused_type, PauseType_LoadGame); + _Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_LoadGame); g_CPU_Action->Pause = TRUE; g_CPU_Action->DoSomething = TRUE; } break; case PauseCPU_DumpMemory: - if (!_Settings->LoadDword(CPU_Paused)) + if (!_Settings->LoadBool(GameRunning_CPU_Paused)) { - _Settings->SaveDword(CPU_Paused_type, PauseType_DumpMemory); + _Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_DumpMemory); g_CPU_Action->Pause = TRUE; g_CPU_Action->DoSomething = TRUE; } break; case PauseCPU_SearchMemory: - if (!_Settings->LoadDword(CPU_Paused)) + if (!_Settings->LoadBool(GameRunning_CPU_Paused)) { - _Settings->SaveDword(CPU_Paused_type, PauseType_SearchMemory); + _Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_SearchMemory); g_CPU_Action->Pause = TRUE; g_CPU_Action->DoSomething = TRUE; } @@ -140,37 +141,37 @@ void CN64System::ExternalEvent ( SystemEvent Event ) { SetEvent(m_hPauseEvent); break; case ResumeCPU_AppGainedFocus: - if (_Settings->LoadDword(CPU_Paused_type) == PauseType_AppLostFocus ) + if (_Settings->LoadDword(GameRunning_CPU_PausedType) == PauseType_AppLostFocus ) { SetEvent(m_hPauseEvent); } break; case ResumeCPU_AppGainedActive: - if (_Settings->LoadDword(CPU_Paused_type) == PauseType_AppLostActive ) + if (_Settings->LoadDword(GameRunning_CPU_PausedType) == PauseType_AppLostActive ) { SetEvent(m_hPauseEvent); } break; case ResumeCPU_SaveGame: - if (_Settings->LoadDword(CPU_Paused_type) == PauseType_SaveGame ) + if (_Settings->LoadDword(GameRunning_CPU_PausedType) == PauseType_SaveGame ) { SetEvent(m_hPauseEvent); } break; case ResumeCPU_LoadGame: - if (_Settings->LoadDword(CPU_Paused_type) == PauseType_LoadGame ) + if (_Settings->LoadDword(GameRunning_CPU_PausedType) == PauseType_LoadGame ) { SetEvent(m_hPauseEvent); } break; case ResumeCPU_DumpMemory: - if (_Settings->LoadDword(CPU_Paused_type) == PauseType_DumpMemory ) + if (_Settings->LoadDword(GameRunning_CPU_PausedType) == PauseType_DumpMemory ) { SetEvent(m_hPauseEvent); } break; case ResumeCPU_SearchMemory: - if (_Settings->LoadDword(CPU_Paused_type) == PauseType_SearchMemory ) + if (_Settings->LoadDword(GameRunning_CPU_PausedType) == PauseType_SearchMemory ) { SetEvent(m_hPauseEvent); } @@ -188,7 +189,7 @@ void CN64System::ExternalEvent ( SystemEvent Event ) { Reset(); _Rom = TempRom; - m_Limitor.SetHertz(_Settings->LoadDword(ScreenHertz)); //Is set in LoadRomSettings + m_Limitor.SetHertz(_Settings->LoadDword(Game_ScreenHertz)); //Is set in LoadRomSettings //Recreate Memory _MMU = new CMipsMemory(this,this,_Rom,_Notify, new CRegisters(this, _Notify)); @@ -241,17 +242,17 @@ void CN64System::ExternalEvent ( SystemEvent Event ) { void CN64System::RunFileImage ( const char * FileLoc ) { - bool RomLoading = _Settings->LoadBool(LoadingRom); + bool RomLoading = _Settings->LoadBool(Info_RomLoading); if (!RomLoading) { - FileImageInfo * Info = new FileImageInfo; + _Settings->SaveBool(Info_RomLoading,true); + HANDLE * hThread = new HANDLE; *hThread = NULL; - _Settings->SaveDword(LoadingRom,(DWORD)true); - //create the needed info into a structure to pass as one paramater //for createing a thread + FileImageInfo * Info = new FileImageInfo; Info->_this = this; Info->FileName = FileLoc; Info->ThreadHandle = hThread; @@ -260,10 +261,11 @@ void CN64System::RunFileImage ( const char * FileLoc ) } } -void CN64System::LoadFileImage ( FileImageInfo * Info ) { +void CN64System::LoadFileImage ( FileImageInfo * Info ) +{ CoInitialize(NULL); - //Make a copy of the passed infomation on to the stack, then free + //Make a copy of the passed information on to the stack, then free //the memory used WriteTrace(TraceDebug,"CN64System::LoadFileImage 1"); FileImageInfo ImageInfo = *Info; @@ -275,7 +277,7 @@ void CN64System::LoadFileImage ( FileImageInfo * Info ) { WriteTrace(TraceDebug,"CN64System::LoadFileImage 2"); //Mark the rom as loading - _Settings->SaveDword(LoadingRom,(DWORD)true); + _Settings->SaveBool(Info_RomLoading,true); _this->_Notify->RefreshMenu(); WriteTrace(TraceDebug,"CN64System::LoadFileImage 3"); @@ -285,7 +287,7 @@ void CN64System::LoadFileImage ( FileImageInfo * Info ) { if (!Rom->LoadN64Image(ImageInfo.FileName.c_str())) { _this->_Notify->DisplayError(Rom->GetError()); delete Rom; - _Settings->SaveDword(LoadingRom,(DWORD)false); + _Settings->SaveBool(Info_RomLoading,false); _this->_Notify->RefreshMenu(); return; } @@ -296,19 +298,19 @@ void CN64System::LoadFileImage ( FileImageInfo * Info ) { WriteTrace(TraceDebug,"CN64System::LoadFileImage 5"); Rom->SaveRomSettingID(); - { + /*{ stdstr &Name = Rom->GetRomName(); _Settings->SaveString(ROM_InternalName,Name.c_str()); - } + }*/ WriteTrace(TraceDebug,"CN64System::LoadFileImage 6"); _this->_Notify->AddRecentRom(ImageInfo.FileName.c_str()); WriteTrace(TraceDebug,"CN64System::LoadFileImage 7"); _this->SetupSystem(Rom,true); WriteTrace(TraceDebug,"CN64System::LoadFileImage 8"); - _Settings->SaveDword(LoadingRom,(DWORD)false); + _Settings->SaveBool(Info_RomLoading,false); _this->_Notify->RefreshMenu(); WriteTrace(TraceDebug,"CN64System::LoadFileImage 9"); - if (_Settings->LoadDword(AutoStart) != 0) + if (_Settings->LoadDword(Setting_AutoStart) != 0) { _this->CPU_Handle = (void *)(*((DWORD *)ImageInfo.ThreadHandle)); _this->CPU_ThreadID = ImageInfo.ThreadID; @@ -332,7 +334,6 @@ void CN64System::LoadFileImage ( FileImageInfo * Info ) { } else { delete ImageInfo.ThreadHandle; //Load rom settings - _this->_Rom->LoadRomSettings(); _this->_Notify->DisplayMessage(5,MSG_WAITING_FOR_START); } WriteTrace(TraceDebug,"CN64System::LoadFileImage 10"); @@ -362,13 +363,13 @@ void CN64System::StartEmulation2 ( bool NewThread ) _Notify->HideRomBrowser(); WriteTrace(TraceDebug,"CN64System::StartEmulation 3"); - RefreshSettings(); + //RefreshSettings(); WriteTrace(TraceDebug,"CN64System::StartEmulation 4"); - m_Limitor.SetHertz(_Settings->LoadDword(ScreenHertz)); //Is set in LoadRomSettings + m_Limitor.SetHertz(_Settings->LoadDword(Game_ScreenHertz)); WriteTrace(TraceDebug,"CN64System::StartEmulation 5"); _MMU->FixRDramSize(); - _Notify->SetWindowCaption(_Settings->LoadString(ROM_NAME).c_str()); + _Notify->SetWindowCaption(_Settings->LoadString(Game_GoodName).c_str()); WriteTrace(TraceDebug,"CN64System::StartEmulation 6"); _Notify->DisplayMessage(5,MSG_PLUGIN_INIT); @@ -377,7 +378,7 @@ void CN64System::StartEmulation2 ( bool NewThread ) WriteTrace(TraceDebug,"CN64System::StartEmulation 8"); if (!_Plugins->Initiate(this)) { WriteTrace(TraceDebug,"CN64System::StartEmulation 8a"); - _Settings->SaveDword(LoadingRom,(DWORD)false); + _Settings->SaveBool(Info_RomLoading,false); _Notify->DisplayError(MSG_PLUGIN_NOT_INIT); //Set handle to NULL so this thread is not terminated CPU_Handle = NULL; @@ -392,15 +393,15 @@ void CN64System::StartEmulation2 ( bool NewThread ) WriteTrace(TraceDebug,"CN64System::StartEmulation 9"); _Cheats = new CCheats(_Rom,_Notify); WriteTrace(TraceDebug,"CN64System::StartEmulation 10"); - _Cheats->LoadCheats(!_Settings->LoadDword(RememberCheats)); + _Cheats->LoadCheats(!_Settings->LoadDword(Setting_RememberCheats)); WriteTrace(TraceDebug,"CN64System::StartEmulation 11"); _Notify->DisplayMessage(5,"Done"); WriteTrace(TraceDebug,"CN64System::StartEmulation 12"); - _Notify->MakeWindowOnTop(_Settings->LoadDword(AlwaysOnTop) != 0); + _Notify->MakeWindowOnTop(_Settings->LoadBool(UserInterface_AlwaysOnTop)); WriteTrace(TraceDebug,"CN64System::StartEmulation 13"); - if (!_Settings->LoadDword(IsValidExe)) + if (!_Settings->LoadBool(Beta_IsValidExe)) { Reset(); return; @@ -409,10 +410,10 @@ void CN64System::StartEmulation2 ( bool NewThread ) //mark the emulation as starting and fix up menus _Notify->DisplayMessage(5,MSG_EMULATION_STARTED); WriteTrace(TraceDebug,"CN64System::StartEmulation 15"); - if (_Settings->LoadDword(AutoFullScreen)) + if (_Settings->LoadBool(Setting_AutoFullscreen)) { - CIniFile RomIniFile(_Settings->LoadString(RomDatabaseFile).c_str()); - stdstr Status = _Settings->LoadString(ROM_Status); + CIniFile RomIniFile(_Settings->LoadString(SupportFile_RomDatabase).c_str()); + stdstr Status = _Settings->LoadString(Rdb_Status); char String[100]; RomIniFile.GetString("Rom Status",stdstr_f("%s.AutoFullScreen", Status.c_str).c_str(),"true",String,sizeof(String)); @@ -458,7 +459,7 @@ void CN64System::CloseCpu ( void ) { if (CPU_Handle == NULL) { return; } Debug_Reset(); - if (_Settings->LoadDword(CPU_Paused)) + if (_Settings->LoadBool(GameRunning_CPU_Paused)) { SetEvent(m_hPauseEvent); } @@ -515,12 +516,12 @@ void CN64System::DisplayRomInfo ( WND_HANDLE hParent ) { void CN64System::Pause(void) { ResetEvent(m_hPauseEvent); - _Settings->SaveDword(CPU_Paused,true); + _Settings->SaveBool(GameRunning_CPU_Paused,true); _Notify->RefreshMenu(); _Notify->DisplayMessage(5,MSG_CPU_PAUSED); WaitForSingleObject(m_hPauseEvent, INFINITE); ResetEvent(m_hPauseEvent); - _Settings->SaveDword(CPU_Paused,(DWORD)false); + _Settings->SaveBool(GameRunning_CPU_Paused,(DWORD)false); _Notify->RefreshMenu(); _Notify->DisplayMessage(5,MSG_CPU_RESUMED); } @@ -532,7 +533,7 @@ stdstr CN64System::ChooseFileToOpen ( WND_HANDLE hParent ) { memset(&FileName, 0, sizeof(FileName)); memset(&openfilename, 0, sizeof(openfilename)); - strcpy(Directory,_Settings->LoadString(RomDirectory).c_str()); + strcpy(Directory,_Settings->LoadString(Directory_Game).c_str()); openfilename.lStructSize = sizeof( openfilename ); openfilename.hwndOwner = (HWND)hParent; @@ -544,7 +545,7 @@ stdstr CN64System::ChooseFileToOpen ( WND_HANDLE hParent ) { if (GetOpenFileName (&openfilename)) { return stdstr(FileName); - } + } return stdstr(""); } @@ -614,9 +615,6 @@ void CN64System::SetupSystem ( CN64Rom * Rom, bool OwnRomObject, bool SavesRead m_OwnRomObject = OwnRomObject; _Rom = Rom; - //Load rom settings - _Rom->LoadRomSettings(); - //Create New system _MMU = new CMipsMemory(this,this,_Rom,_Notify,new CRegisters(this, _Notify),SavesReadOnly); _Reg = _MMU->SystemRegisters(); @@ -639,11 +637,10 @@ void CN64System::SetupSystem ( CN64Rom * Rom, bool OwnRomObject, bool SavesRead } -void CN64System::ExecuteCPU ( void ) { - m_SPHack = _Settings->LoadDword(ROM_SPHack) != 0; - - _Settings->SaveDword(CPU_Running,true); - _Settings->SaveDword(CPU_Paused,(DWORD)false); +void CN64System::ExecuteCPU ( void ) +{ + _Settings->SaveBool(GameRunning_CPU_Running,true); + _Settings->SaveBool(GameRunning_CPU_Paused,false); _Notify->DisplayMessage(5,MSG_EMULATION_STARTED); EndEmulation = false; @@ -654,7 +651,7 @@ void CN64System::ExecuteCPU ( void ) { // C_Core.SetN64System(NULL); C_Core.SetSyncCpu(NULL); - switch ((CPU_TYPE)_Settings->LoadDword(CPUType)) { + switch ((CPU_TYPE)_Settings->LoadDword(Game_CpuType)) { case CPU_Recompiler: ExecuteRecompiler(C_Core); break; case CPU_SyncCores: ExecuteSyncCPU(C_Core); break; default: ExecuteInterpret(C_Core); break; @@ -677,8 +674,10 @@ void CN64System::ExecuteRecompiler (CC_Core & C_Core) { Recompiler.Run(); } -void CN64System::ExecuteSyncCPU (CC_Core & C_Core) { - //execute opcodes while no errors +void CN64System::ExecuteSyncCPU (CC_Core & C_Core) +{ + Notify().BreakPoint(__FILE__,__LINE__); +/* //execute opcodes while no errors _Notify->DisplayMessage(5,"Copy Plugins"); _Plugins->CopyPlugins(_Settings->LoadString(SyncPluginDir)); //copy the plugins @@ -710,23 +709,20 @@ void CN64System::ExecuteSyncCPU (CC_Core & C_Core) { InitializeCPUCore(); Recompiler.Run(); SyncSystem._Rom = NULL; - } + }*/ } void CN64System::CpuStopped ( void ) { void * lCPU_Handle = CPU_Handle; - _Settings->SaveDword(CPU_Running,(DWORD)false); + _Settings->SaveBool(GameRunning_CPU_Running,(DWORD)false); CleanCMemory(); - if (_Settings->LoadDword(InFullScreen)) - { - _Notify->ChangeFullScreen(); - } + _Notify->WindowMode(); if (!m_InReset) { _Notify->RefreshMenu(); _Notify->MakeWindowOnTop(false); _Notify->DisplayMessage(5,MSG_EMULATION_ENDED); - if (_Settings->LoadDword(RomBrowser)) { + if (_Settings->LoadDword(RomBrowser_Enabled)) { _Notify->ShowRomBrowser(); } } @@ -785,7 +781,7 @@ void CN64System::SyncCPU (CN64System * const SecondCPU) { } } - if (m_SPHack) + if (bSPHack()) { if (_MMU->m_MemoryStack != (DWORD)(_MMU->RDRAM + (_Reg->GPR[29].W[0] & 0x1FFFFFFF))) { @@ -851,7 +847,7 @@ void CN64System::DumpSyncErrors (CN64System * SecondCPU) { { Error.LogF("Current Time Type is Different: %X %X\r\n",_Reg->GetCurrentTimerType(),SecondCPU->_Reg->GetCurrentTimerType()); } - if (_Settings->LoadDword(ROM_SPHack)) + if (_Settings->LoadDword(Game_SPHack)) { if (_MMU->m_MemoryStack != (DWORD)(_MMU->RDRAM + (_Reg->GPR[29].W[0] & 0x1FFFFFFF))) { @@ -909,7 +905,8 @@ void CN64System::DumpSyncErrors (CN64System * SecondCPU) { // AddEvent(CloseCPU); } -bool CN64System::SaveState(void) { +bool CN64System::SaveState(void) +{ WriteTrace(TraceDebug,"CN64System::SaveState 1"); if (_Reg->GetTimer(AiTimerDMA) != 0) { return false; } @@ -919,35 +916,35 @@ bool CN64System::SaveState(void) { if ((_Reg->STATUS_REGISTER & STATUS_EXL) != 0) { return false; } //Get the file Name - stdstr FileName, CurrentSaveName = _Settings->LoadString(InstantSaveFile); + stdstr FileName, CurrentSaveName = _Settings->LoadString(GameRunning_InstantSaveFile); if (CurrentSaveName.empty()) { - int Slot = _Settings->LoadDword(CurrentSaveState); + int Slot = _Settings->LoadDword(Game_CurrentSaveState); if (Slot != 0) { - CurrentSaveName.Format("%s.pj%d",_Settings->LoadString(ROM_GoodName).c_str(), Slot); + CurrentSaveName.Format("%s.pj%d",_Settings->LoadString(Game_GoodName).c_str(), Slot); } else { - CurrentSaveName.Format("%s.pj",_Settings->LoadString(ROM_GoodName).c_str()); + CurrentSaveName.Format("%s.pj",_Settings->LoadString(Game_GoodName).c_str()); } - FileName.Format("%s%s",_Settings->LoadString(InstantSaveDirectory).c_str(),CurrentSaveName.c_str()); + FileName.Format("%s%s",_Settings->LoadString(Directory_InstantSave).c_str(),CurrentSaveName.c_str()); stdstr_f ZipFileName("%s.zip",FileName.c_str()); //Make sure the target dir exists - CreateDirectory(_Settings->LoadString(InstantSaveDirectory).c_str(),NULL); + CreateDirectory(_Settings->LoadString(Directory_InstantSave).c_str(),NULL); //delete any old save DeleteFile(FileName.c_str()); DeleteFile(ZipFileName.c_str()); //If ziping save add .zip on the end - if (_Settings->LoadDword(AutoZip)) { + if (_Settings->LoadDword(Setting_AutoZipInstantSave)) { FileName = ZipFileName; } - _Settings->SaveDword(Game_LastSaveSlot,_Settings->LoadDword(CurrentSaveState)); + _Settings->SaveDword(Game_LastSaveSlot,_Settings->LoadDword(Game_CurrentSaveState)); } else { - FileName.Format("%s%s",CurrentSaveName.c_str(), _Settings->LoadDword(AutoZip) ? ".pj.zip" : ".pj"); + FileName.Format("%s%s",CurrentSaveName.c_str(), _Settings->LoadDword(Setting_AutoZipInstantSave) ? ".pj.zip" : ".pj"); } if (FileName.empty()) { return true; } //Open the file - if (_Settings->LoadDword(FuncLookupMode) == FuncFind_ChangeMemory) + if (_Settings->LoadDword(Game_FuncLookupMode) == FuncFind_ChangeMemory) { if (GetRecompiler()) { @@ -956,11 +953,11 @@ bool CN64System::SaveState(void) { } DWORD dwWritten, SaveID_0 = 0x23D8A6C8; - DWORD RdramSize = _Settings->LoadDword(RamSize); + DWORD RdramSize = _Settings->LoadDword(Game_RDRamSize); DWORD NextViTimer = _Reg->GetTimer(ViTimer); DWORD MiInterReg = _Reg->MI_INTR_REG; if (_Reg->GetTimer(AiTimer) != 0) { _Reg->MI_INTR_REG |= MI_INTR_AI; } - if (_Settings->LoadDword(AutoZip)) { + if (_Settings->LoadDword(Setting_AutoZipInstantSave)) { zipFile file; file = zipOpen(FileName.c_str(),0); @@ -1032,7 +1029,7 @@ bool CN64System::SaveState(void) { CloseHandle(hSaveFile); } _Reg->MI_INTR_REG = MiInterReg; - _Settings->SaveString(InstantSaveFile,""); + _Settings->SaveString(GameRunning_InstantSaveFile,""); stdstr SaveMessage = _Lang->GetString(MSG_SAVED_STATE); CPath SavedFileName(FileName); @@ -1043,27 +1040,28 @@ bool CN64System::SaveState(void) { return true; } -bool CN64System::LoadState(void) { - stdstr InstantFileName = _Settings->LoadString(InstantSaveFile); +bool CN64System::LoadState(void) +{ + stdstr InstantFileName = _Settings->LoadString(GameRunning_InstantSaveFile); if (!InstantFileName.empty()) { bool Result = LoadState(InstantFileName.c_str()); - _Settings->SaveString(InstantSaveFile,""); + _Settings->SaveString(GameRunning_InstantSaveFile,""); return Result; } CPath FileName; - FileName.SetDriveDirectory(_Settings->LoadString(InstantSaveDirectory).c_str()); - if (_Settings->LoadDword(CurrentSaveState) != 0) { - FileName.SetNameExtension(stdstr_f("%s.pj%d",_Settings->LoadString(ROM_GoodName).c_str(),_Settings->LoadDword(CurrentSaveState)).c_str()); + FileName.SetDriveDirectory(_Settings->LoadString(Directory_InstantSave).c_str()); + if (_Settings->LoadDword(Game_CurrentSaveState) != 0) { + FileName.SetNameExtension(stdstr_f("%s.pj%d",_Settings->LoadString(Game_GoodName).c_str(),_Settings->LoadDword(Game_CurrentSaveState)).c_str()); } else { - FileName.SetNameExtension(stdstr_f("%s.pj",_Settings->LoadString(ROM_GoodName).c_str()).c_str()); + FileName.SetNameExtension(stdstr_f("%s.pj",_Settings->LoadString(Game_GoodName).c_str()).c_str()); } CPath ZipFileName; ZipFileName = (stdstr&)FileName + ".zip"; - if ((_Settings->LoadDword(AutoZip) && ZipFileName.Exists()) || FileName.Exists()) + if ((_Settings->LoadDword(Setting_AutoZipInstantSave) && ZipFileName.Exists()) || FileName.Exists()) { if (LoadState(FileName)) { @@ -1072,10 +1070,10 @@ bool CN64System::LoadState(void) { } //Use old file Name - if (_Settings->LoadDword(CurrentSaveState) != 0) { - FileName.SetNameExtension(stdstr_f("%s.pj%d",_Settings->LoadString(ROM_NAME).c_str(),_Settings->LoadDword(CurrentSaveState)).c_str()); + if (_Settings->LoadDword(Game_CurrentSaveState) != 0) { + FileName.SetNameExtension(stdstr_f("%s.pj%d",_Settings->LoadString(Game_GameName).c_str(),_Settings->LoadDword(Game_CurrentSaveState)).c_str()); } else { - FileName.SetNameExtension(stdstr_f("%s.pj",_Settings->LoadString(ROM_NAME).c_str()).c_str()); + FileName.SetNameExtension(stdstr_f("%s.pj",_Settings->LoadString(Game_GameName).c_str()).c_str()); } return LoadState(FileName); } @@ -1090,7 +1088,7 @@ bool CN64System::LoadState(LPCSTR FileName) { _splitpath(FileName, drive, dir, fname, ext); stdstr FileNameStr(FileName); - if (_Settings->LoadDword(AutoZip) || _stricmp(ext,".zip") == 0) + if (_Settings->LoadDword(Setting_AutoZipInstantSave) || _stricmp(ext,".zip") == 0) { //If ziping save add .zip on the end if (_stricmp(ext,".zip") != 0) @@ -1137,10 +1135,10 @@ bool CN64System::LoadState(LPCSTR FileName) { MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2); if (result == IDNO) { return FALSE; } } - _MMU->UnProtectMemory(0x80000000,0x80000000 + _Settings->LoadDword(RamSize) - 4); + _MMU->UnProtectMemory(0x80000000,0x80000000 + _Settings->LoadDword(Game_RDRamSize) - 4); _MMU->UnProtectMemory(0xA4000000,0xA4001FFC); - if (SaveRDRAMSize != _Settings->LoadDword(RamSize)) { - _Settings->SaveDword(RamSize,SaveRDRAMSize); + if (SaveRDRAMSize != _Settings->LoadDword(Game_RDRamSize)) { + _Settings->SaveDword(Game_RDRamSize,SaveRDRAMSize); _MMU->FixRDramSize(); } unzReadCurrentFile(file,&NextVITimer,sizeof(NextVITimer)); @@ -1190,10 +1188,10 @@ bool CN64System::LoadState(LPCSTR FileName) { MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2); if (result == IDNO) { return FALSE; } } - _MMU->UnProtectMemory(0x80000000,0x80000000 + _Settings->LoadDword(RamSize) - 4); + _MMU->UnProtectMemory(0x80000000,0x80000000 + _Settings->LoadDword(Game_RDRamSize) - 4); _MMU->UnProtectMemory(0xA4000000,0xA4001FFC); - if (SaveRDRAMSize != _Settings->LoadDword(RamSize)) { - _Settings->SaveDword(RamSize,SaveRDRAMSize); + if (SaveRDRAMSize != _Settings->LoadDword(Game_RDRamSize)) { + _Settings->SaveDword(Game_RDRamSize,SaveRDRAMSize); _MMU->FixRDramSize(); } ReadFile( hSaveFile,&NextVITimer,sizeof(NextVITimer),&dwRead,NULL); @@ -1267,7 +1265,7 @@ bool CN64System::LoadState(LPCSTR FileName) { #endif _MMU->m_MemoryStack = (DWORD)(_MMU->RDRAM + (_Reg->GPR[29].W[0] & 0x1FFFFFFF)); - if (_Settings->LoadDword(CPUType) == CPU_SyncCores) { + if (_Settings->LoadDword(Game_CpuType) == CPU_SyncCores) { if (_SyncCPU) { for (int i = 0; i < (sizeof(m_LastSuccessSyncPC)/sizeof(m_LastSuccessSyncPC[0])); i++) { @@ -1285,7 +1283,7 @@ bool CN64System::LoadState(LPCSTR FileName) { // } } WriteTrace(TraceDebug,"CN64System::LoadState 13"); - _Settings->SaveDword(RamSize,SaveRDRAMSize); + _Settings->SaveDword(Game_RDRamSize,SaveRDRAMSize); WriteTrace(TraceDebug,"CN64System::LoadState 14"); stdstr LoadMsg = _Lang->GetString(MSG_LOADED_STATE); WriteTrace(TraceDebug,"CN64System::LoadState 15"); @@ -1322,10 +1320,10 @@ void CN64System::RunRSP ( void ) { m_UnknownCount += 1; break; } - if (bShowDListAListCount) { + if (bShowDListAListCount()) { _Notify->DisplayMessage(0,"Dlist: %d Alist: %d Unknown: %d",m_DlistCount,m_AlistCount,m_UnknownCount); } - if (bShowCPUPer) { + if (bShowCPUPer()) { switch (Task) { case 1: CPU_UsageAddr = m_CPU_Usage.StartTimer(Timer_RSP_Dlist); break; case 2: CPU_UsageAddr = m_CPU_Usage.StartTimer(Timer_RSP_Alist); break; @@ -1353,7 +1351,7 @@ void CN64System::RunRSP ( void ) { SP_STATUS_REG &= ~SP_STATUS_SIG2; }*/ - if (bShowCPUPer) { m_CPU_Usage.StartTimer(CPU_UsageAddr); } + if (bShowCPUPer()) { m_CPU_Usage.StartTimer(CPU_UsageAddr); } //if (bProfiling) { m_Profile.StartTimer(ProfileAddr); } WriteTrace(TraceRSP, "RunRSP: check interrupts"); @@ -1363,15 +1361,15 @@ void CN64System::RunRSP ( void ) { } void CN64System::SyncToAudio ( void ) { - if (!bBasicMode && !bLimitFPS ) + if (!bBasicMode() && !bLimitFPS() ) { return; } - if (!bFixedAudio) + if (!bFixedAudio()) { return; } - if (!bSyncToAudio) + if (!bSyncToAudio()) { return; } @@ -1391,7 +1389,7 @@ void CN64System::SyncToAudio ( void ) { } DWORD CPU_UsageAddr = Timer_None; - if (bShowCPUPer) + if (bShowCPUPer()) { CPU_UsageAddr = m_CPU_Usage.StartTimer(Timer_Idel); } @@ -1403,7 +1401,7 @@ void CN64System::SyncToAudio ( void ) { break; } } - if (bShowCPUPer) + if (bShowCPUPer()) { m_CPU_Usage.StartTimer(CPU_UsageAddr != Timer_None ? CPU_UsageAddr : Timer_R4300 ); } @@ -1414,7 +1412,7 @@ void CN64System::RefreshScreen ( void ) { DWORD CPU_UsageAddr = Timer_None, ProfilingAddr = Timer_None; DWORD OLD_VI_V_SYNC_REG = 0, VI_INTR_TIME = 500000; - if (bShowCPUPer) { CPU_UsageAddr = m_CPU_Usage.StartTimer(Timer_RefreshScreen); } + if (bShowCPUPer()) { CPU_UsageAddr = m_CPU_Usage.StartTimer(Timer_RefreshScreen); } //if (bProfiling) { ProfilingAddr = m_Profile.StartTimer(Timer_RefreshScreen); } //Calculate how many cycles to next refresh @@ -1433,7 +1431,7 @@ void CN64System::RefreshScreen ( void ) { } // _Plugins->Control()->UpdateKeys(); - if (bShowCPUPer) { m_CPU_Usage.StartTimer(Timer_UpdateScreen); } + if (bShowCPUPer()) { m_CPU_Usage.StartTimer(Timer_UpdateScreen); } // if (bProfiling) { m_Profile.StartTimer(Timer_UpdateScreen); } __try @@ -1446,26 +1444,26 @@ void CN64System::RefreshScreen ( void ) { WriteTrace(TraceError,"Exception caught in UpdateScreen"); } - if ((bBasicMode || bLimitFPS ) && !bSyncToAudio) { - if (bShowCPUPer) { m_CPU_Usage.StartTimer(Timer_Idel); } + if ((bBasicMode() || bLimitFPS() ) && !bSyncToAudio()) { + if (bShowCPUPer()) { m_CPU_Usage.StartTimer(Timer_Idel); } DWORD FrameRate; - if (m_Limitor.Timer_Process(&FrameRate) && bDisplayFrameRate) { + if (m_Limitor.Timer_Process(&FrameRate) && bDisplayFrameRate()) { FPS.DisplayViCounter(FrameRate); - bCleanFrameBox = true; + m_bCleanFrameBox = true; } - } else if (bDisplayFrameRate) { - if (bShowCPUPer) { m_CPU_Usage.StartTimer(Timer_UpdateFPS); } + } else if (bDisplayFrameRate()) { + if (bShowCPUPer()) { m_CPU_Usage.StartTimer(Timer_UpdateFPS); } FPS.UpdateViCounter(); - bCleanFrameBox = true; + m_bCleanFrameBox = true; } - if (bCleanFrameBox && !bDisplayFrameRate) + if (m_bCleanFrameBox && !bDisplayFrameRate()) { FPS.Reset (true); - bCleanFrameBox = false; + m_bCleanFrameBox = false; } - if (bShowCPUPer) { + if (bShowCPUPer()) { m_CPU_Usage.StopTimer(); m_CPU_Usage.ShowCPU_Usage(); m_CPU_Usage.StartTimer(CPU_UsageAddr != Timer_None ? CPU_UsageAddr : Timer_R4300 ); @@ -1491,7 +1489,7 @@ void CN64System::TLB_Changed ( void ) void CN64System::TLB_Unmapping ( int TlbEntry, int FastTlbEntry, DWORD Vaddr, DWORD Len ) { - if (_Recomp && _Recomp->bSMM_TLB) + if (_Recomp && _Recomp->bSMM_TLB()) { _Recomp->ClearRecompCode_Virt(Vaddr,Len,CRecompiler::Remove_TLB); } diff --git a/Source/Project64/N64 System/N64 Class.h b/Source/Project64/N64 System/N64 Class.h index 61a40d75b..eb164c88c 100644 --- a/Source/Project64/N64 System/N64 Class.h +++ b/Source/Project64/N64 System/N64 Class.h @@ -53,11 +53,11 @@ class CN64System : CSpeedLimitor m_Limitor; bool m_InReset; SystemType m_SystemType; + bool m_bCleanFrameBox; //When Syncing cores this is the PC where it last Sync'ed correctly DWORD m_LastSuccessSyncPC[10]; int m_CyclesToSkip; - bool m_SPHack; //List of Internal events that need to be acted on by CPU EVENT_LIST EventList; diff --git a/Source/Project64/N64 System/N64 Rom Class.cpp b/Source/Project64/N64 System/N64 Rom Class.cpp index 04de12998..694021ec9 100644 --- a/Source/Project64/N64 System/N64 Rom Class.cpp +++ b/Source/Project64/N64 System/N64 Rom Class.cpp @@ -456,69 +456,18 @@ bool CN64Rom::LoadN64Image ( const char * FileLoc, bool LoadBootCodeOnly ) { return true; } -void CN64Rom::LoadRomSettings (void) { - //Load Rom Settings - DWORD CPU_Type = _Settings->LoadDword(ROM_CPUType); - DWORD RDRamSize = _Settings->LoadDword(ROM_RamSize); - DWORD LookUpMode = _Settings->LoadDword(ROM_FunctionLookup); - bool UseCustomSMM = _Settings->LoadDword(ROM_CustomSMM) != 0; - - if (RDRamSize != -1 && RDRamSize != 8) { RDRamSize = 0x400000; } - if (RDRamSize == 8) { RDRamSize = 0x800000; } - - //Load system settings if need be - if (CPU_Type == -1) { CPU_Type = _Settings->LoadDword(SYSTEM_CPUType); } - if (RDRamSize == -1) { RDRamSize = _Settings->LoadDword(SYSTEM_RDRamSize); } - if (LookUpMode == -1) { LookUpMode = _Settings->LoadDword(SYSTEM_FunctionLookup); } - - //Save execution settings - _Settings->SaveDword(CPUType, CPU_Type); - _Settings->SaveDword(RamSize, RDRamSize); - _Settings->SaveDword(FuncLookupMode, LookUpMode); - _Settings->SaveDword(SaveChipType, _Settings->LoadDword(ROM_SaveChip)); - _Settings->SaveDword(SMM_Cache, _Settings->LoadDword(UseCustomSMM ? ROM_SMM_Cache : SYSTEM_SMM_Cache)); - _Settings->SaveDword(SMM_PIDMA, _Settings->LoadDword(UseCustomSMM ? ROM_SMM_PIDMA : SYSTEM_SMM_PIDMA)); - _Settings->SaveDword(SMM_TLB, _Settings->LoadDword(UseCustomSMM ? ROM_SMM_TLB : SYSTEM_SMM_TLB)); - _Settings->SaveDword(SMM_Protect, _Settings->LoadDword(UseCustomSMM ? ROM_SMM_Protect : SYSTEM_SMM_Protect)); - _Settings->SaveDword(SMM_ValidFunc, _Settings->LoadDword(UseCustomSMM ? ROM_SMM_ValidFunc : SYSTEM_SMM_ValidFunc)); - _Settings->SaveDword(CounterFactor, _Settings->LoadDword(ROM_CounterFactor)); - _Settings->SaveDword(BlockLinking, _Settings->LoadDword(ROM_BlockLinking)); - _Settings->SaveDword(DelayDlists, _Settings->LoadDword(ROM_DelayDlists)); - _Settings->SaveDword(DelaySI, _Settings->LoadDword(ROM_DelaySI)); - _Settings->SaveDword(UseTLB, _Settings->LoadDword(ROM_UseTlb)); - _Settings->SaveDword(AudioSignal, _Settings->LoadDword(ROM_AudioSignal)); - _Settings->SaveDword(UseJumpTable, _Settings->LoadDword(ROM_UseJumpTable)); - _Settings->SaveDword(RomInMemory, _Settings->LoadDword(ROM_RomInMemory)); - _Settings->SaveDword(SyncViaAudio, _Settings->LoadDword(ROM_SyncAudio)); - _Settings->SaveDword(FirstDMA, true); - _Settings->SaveDword(CurrentSaveState,_Settings->LoadDword(Game_LastSaveSlot)); - - if (_Settings->LoadDword(CounterFactor) == -1) { _Settings->SaveDword(CounterFactor, (DWORD)2); } - if (_Settings->LoadDword(BlockLinking) == -1) { _Settings->SaveDword(BlockLinking, _Settings->LoadDword(SYSTEM_BlockLinking)); } - - DWORD hertz = 60; - switch (m_Country) { - case 0x44: //Germany - case 0x46: //french - case 0x49: //Italian - case 0x50: //Europe - case 0x53: //Spanish - case 0x55: //Australia - case 0x58: // X (PAL) - case 0x59: // X (PAL) - hertz = 50; - break; - } - _Settings->SaveDword(ScreenHertz,hertz); - - -} - //Save the settings of the loaded rom, so all loaded settings about rom will be identified with //this rom -void CN64Rom::SaveRomSettingID ( void ) { - _Settings->SaveString(ROM_NAME,m_RomName.c_str()); - _Settings->SaveString(ROM_IniKey,m_RomIdent.c_str()); +void CN64Rom::SaveRomSettingID ( void ) +{ + _Settings->SaveString(Game_GameName,m_RomName.c_str()); + _Settings->SaveString(Game_IniKey,m_RomIdent.c_str()); +} + +void CN64Rom::ClearRomSettingID ( void ) +{ + _Settings->SaveString(Game_GameName,""); + _Settings->SaveString(Game_IniKey,""); } void CN64Rom::SetError ( LanguageStringID ErrorMsg ) { diff --git a/Source/Project64/N64 System/N64 Rom Class.h b/Source/Project64/N64 System/N64 Rom Class.h index a256576ec..ef839467f 100644 --- a/Source/Project64/N64 System/N64 Rom Class.h +++ b/Source/Project64/N64 System/N64 Rom Class.h @@ -28,7 +28,7 @@ public: ~CN64Rom ( void ); bool LoadN64Image ( const char * FileLoc, bool LoadBootCodeOnly = false ); void SaveRomSettingID ( void ); - void LoadRomSettings ( void ); + void ClearRomSettingID ( void ); CICChip CicChipID ( void ); BYTE * GetRomAddress ( void ) { return m_ROMImage; } DWORD GetRomSize ( void ) { return m_RomFileSize; } diff --git a/Source/Project64/N64 System/N64 Types.h b/Source/Project64/N64 System/N64 Types.h index b0aef3734..234c15b10 100644 --- a/Source/Project64/N64 System/N64 Types.h +++ b/Source/Project64/N64 System/N64 Types.h @@ -21,6 +21,7 @@ enum SystemEvent { CloseCPU, PauseCPU_FromMenu, PauseCPU_AppLostActive, + PauseCPU_AppLostActiveDelay, PauseCPU_AppLostFocus, PauseCPU_SaveGame, PauseCPU_LoadGame, @@ -68,7 +69,7 @@ enum FRAMERATE_TYPE { FR_VIs = 0, FR_DLs = 1, FR_PERCENT = 2, }; -enum SAVE_CHIP_TYPE { +enum SAVE_CHIP_TYPE { SaveChip_Auto = -1, SaveChip_Eeprom_4K, SaveChip_Eeprom_16K, SaveChip_Sram, SaveChip_FlashRam }; diff --git a/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp b/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp index 9f5733a39..abd8bac6d 100644 --- a/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp +++ b/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp @@ -6,8 +6,9 @@ #undef PROGRAM_COUNTER #undef RdramSize - -#define LinkBlocks +#undef LookUpMode +#undef LinkBlocks +#undef CountPerOp CRecompiler::CRecompiler(CMipsMemory * MMU, CProfiling & Profile, bool & EndEmulation, bool SyncSystem) : _MMU(MMU), @@ -16,12 +17,6 @@ CRecompiler::CRecompiler(CMipsMemory * MMU, CProfiling & Profile, bool & EndEmul PROGRAM_COUNTER(_Reg->PROGRAM_COUNTER), m_EndEmulation(EndEmulation), m_SyncSystem(SyncSystem), - m_LookUpMode((FUNC_LOOKUP_METHOD)_Settings->LoadDword(FuncLookupMode)), - m_LinkBlocks(_Settings->LoadDword(BlockLinking) != 0), - m_DisableRegCaching(_Settings->LoadDword(ROM_RegCache) == 0), - m_RdramSize(_Settings->LoadDword(RamSize)), - m_CountPerOp(_Settings->LoadDword(CounterFactor)), - m_ValidateFuncs(_Settings->LoadDword(SMM_ValidFunc) != 0), m_Functions(), m_FunctionsDelaySlot() { @@ -41,7 +36,7 @@ void CRecompiler::Run() Start_x86_Log(); } - if (!g_MMU->AllocateRecompilerMemory(m_LookUpMode != FuncFind_VirtualLookup && m_LookUpMode != FuncFind_ChangeMemory)) + if (!g_MMU->AllocateRecompilerMemory(LookUpMode() != FuncFind_VirtualLookup && LookUpMode() != FuncFind_ChangeMemory)) { return; } @@ -52,16 +47,16 @@ void CRecompiler::Run() m_EndEmulation = false; __try { - if (m_LookUpMode == FuncFind_VirtualLookup) + if (LookUpMode() == FuncFind_VirtualLookup) { - if (m_ValidateFuncs) + if (bSMM_ValidFunc()) { RecompilerMain_VirtualTable_validate(); } else { RecompilerMain_VirtualTable(); } } - else if (m_LookUpMode == FuncFind_ChangeMemory) + else if (LookUpMode() == FuncFind_ChangeMemory) { RecompilerMain_ChangeMemory(); } @@ -267,7 +262,7 @@ void CRecompiler::RecompilerMain_VirtualTable_validate ( void ) break; } } - if (m_ValidateFuncs) + if (bSMM_ValidFunc()) { if ((*Info->MemLocation[0] != Info->MemContents[0]) || (*Info->MemLocation[1] != Info->MemContents[1])) @@ -299,7 +294,7 @@ void CRecompiler::RecompilerMain_VirtualTable_validate ( void ) break; } } - if (m_ValidateFuncs) + if (bSMM_ValidFunc()) { if ((*Info->MemLocation[0] != Info->MemContents[0]) || (*Info->MemLocation[1] != Info->MemContents[1])) @@ -355,7 +350,7 @@ void CRecompiler::RecompilerMain_Lookup( void ) break; } } - if (m_ValidateFuncs) + if (bSMM_ValidFunc()) { if ((*Info->MemLocation[0] != Info->MemContents[0]) || (*Info->MemLocation[1] != Info->MemContents[1])) @@ -378,7 +373,7 @@ void CRecompiler::RecompilerMain_Lookup( void ) __try { if (Addr > 0x10000000) { - if (bRomInMemory) + if (bRomInMemory()) { if (Addr > 0x20000000) { @@ -429,7 +424,7 @@ void CRecompiler::RecompilerMain_Lookup( void ) // VirtualProtect(N64MEM + Addr, 4, PAGE_READONLY, &OldProtect); // } } - if (m_ValidateFuncs) + if (bSMM_ValidFunc()) { if ((*Info->MemLocation[0] != Info->MemContents[0]) || (*Info->MemLocation[1] != Info->MemContents[1])) @@ -479,7 +474,7 @@ void CRecompiler::ResetRecompCode() memset(JumpTable,0,g_MMU->RdramSize()); memset(JumpTable + (0x04000000 >> 2),0,0x1000); memset(JumpTable + (0x04001000 >> 2),0,0x1000); - if (bRomInMemory) + if (bRomInMemory()) { memset(JumpTable + (0x10000000 >> 2),0,RomFileSize); } @@ -559,7 +554,7 @@ FUNCTION_INFO * CRecompiler::CompileDelaySlot(DWORD PC) { return NULL; } - if (StartAddress < m_RdramSize) { + if (StartAddress < RdramSize()) { CPU_Message("====== RDRAM: Delay Slot ======"); } else if (StartAddress >= 0x04000000 && StartAddress <= 0x04000FFC) { CPU_Message("====== DMEM: Delay Slot ======"); @@ -575,7 +570,7 @@ FUNCTION_INFO * CRecompiler::CompileDelaySlot(DWORD PC) CPU_Message("====== recompiled code ======"); Section->AddParent(NULL); - Section->BlockCycleCount() += CountPerOp; + Section->BlockCycleCount() += CountPerOp(); Section->BlockRandomModifier() += 1; switch (Opcode.op) { @@ -738,7 +733,7 @@ FUNCTION_INFO * CRecompiler::CompileDelaySlot(DWORD PC) bool CRecompiler::AnalyseBlock ( CBlockInfo & BlockInfo) { - if (m_LinkBlocks) + if (bLinkBlocks()) { CBlockSection * Section = &BlockInfo.ParentSection; if (!CreateSectionLinkage (Section)) { return false; } @@ -1857,13 +1852,13 @@ bool CRecompiler::Compiler4300iBlock(FUNCTION_INFO * info) { DWORD StartTime = timeGetTime(); WriteTraceF(TraceRecompiler,"Compile Block-Start: %X-%X",info->VStartPC(),info->VEndPC()); - if (bProfiling) { m_Profile.StartTimer(Timer_GetBlockInfo); } + if (bProfiling()) { m_Profile.StartTimer(Timer_GetBlockInfo); } CBlockInfo BlockInfo(PROGRAM_COUNTER, RecompPos); - if (bProfiling) { m_Profile.StartTimer(Timer_AnalyseBlock); } + if (bProfiling()) { m_Profile.StartTimer(Timer_AnalyseBlock); } if (!AnalyseBlock(BlockInfo)) { return false; } - if (bProfiling) { m_Profile.StartTimer(Timer_CompileBlock); } + if (bProfiling()) { m_Profile.StartTimer(Timer_CompileBlock); } DWORD StartAddress; if (!_MMU->TranslateVaddr(BlockInfo.StartVAddr,StartAddress)) { @@ -1872,7 +1867,7 @@ bool CRecompiler::Compiler4300iBlock(FUNCTION_INFO * info) { } /* MarkCodeBlock(StartAddress); - if (StartAddress < m_RdramSize) { + if (StartAddress < RdramSize()) { CPU_Message("====== RDRAM: block (%X:%d) ======", StartAddress>>12,N64_Blocks.NoOfRDRamBlocks[StartAddress>>12]); } else if (StartAddress >= 0x04000000 && StartAddress <= 0x04000FFC) { CPU_Message("====== DMEM: block (%d) ======", N64_Blocks.NoOfDMEMBlocks); @@ -1892,7 +1887,7 @@ bool CRecompiler::Compiler4300iBlock(FUNCTION_INFO * info) { CPU_Message("Start of Block: %X",BlockInfo.StartVAddr ); CPU_Message("No of Sections: %d",BlockInfo.NoOfSections ); CPU_Message("====== recompiled code ======"); - if (m_LinkBlocks) { + if (bLinkBlocks()) { for (int count = 0; count < BlockInfo.NoOfSections; count ++) { DisplaySectionInformation(&BlockInfo.ParentSection,count + 1,CBlockSection::GetNewTestValue()); } @@ -1904,7 +1899,7 @@ bool CRecompiler::Compiler4300iBlock(FUNCTION_INFO * info) { BlockInfo.ParentSection.RegStart.Initilize(); BlockInfo.ParentSection.RegWorking = BlockInfo.ParentSection.RegStart; - if (m_LinkBlocks) { + if (bLinkBlocks()) { while (GenerateX86Code(BlockInfo,&BlockInfo.ParentSection,CBlockSection::GetNewTestValue())); } else { GenerateX86Code(BlockInfo,&BlockInfo.ParentSection,CBlockSection::GetNewTestValue()); @@ -1912,7 +1907,7 @@ bool CRecompiler::Compiler4300iBlock(FUNCTION_INFO * info) { CompileExitCode(BlockInfo); CPU_Message("====== End of recompiled code ======"); - if (bProfiling) { m_Profile.StartTimer(Timer_CompileDone); } + if (bProfiling()) { m_Profile.StartTimer(Timer_CompileDone); } info->SetVEndPC(BlockInfo.EndVAddr); info->SetFunctionAddr(BlockInfo.CompiledLocation); @@ -1920,13 +1915,13 @@ bool CRecompiler::Compiler4300iBlock(FUNCTION_INFO * info) { info->MemLocation[1] = info->MemLocation[0] + 1; info->MemContents[0] = *info->MemLocation[0]; info->MemContents[1] = *info->MemLocation[1]; - if (bSMM_Protect) + if (bSMM_Protect()) { _MMU->ProtectMemory(info->VStartPC(),info->VEndPC()); } NextInstruction = NORMAL; - if (bShowRecompMemSize) + if (bShowRecompMemSize()) { DWORD Size = RecompPos - RecompCode; DWORD MB = Size / 0x100000; @@ -1938,7 +1933,7 @@ bool CRecompiler::Compiler4300iBlock(FUNCTION_INFO * info) { DisplayMessage(0,"Memory used: %d mb %-3d kb %-3d bytes Total Available: %d mb",MB,KB,Size, TotalAvaliable); } - if (bProfiling) { m_Profile.StopTimer(); } + if (bProfiling()) { m_Profile.StopTimer(); } DWORD TimeTaken = timeGetTime() - StartTime; WriteTraceF(TraceRecompiler,"Compile Block-Done: %X-%X - Taken: %d",info->VStartPC(),info->VEndPC(),TimeTaken); @@ -2600,7 +2595,7 @@ bool CRecompiler::GenerateX86Code(CBlockInfo & BlockInfo, CBlockSection * Sectio { Section->BlockInfo->EndVAddr = Section->CompilePC; } - Section->BlockCycleCount() += m_CountPerOp; + Section->BlockCycleCount() += CountPerOp(); //CPU_Message("BlockCycleCount = %d",BlockCycleCount); Section->BlockRandomModifier() += 1; //CPU_Message("BlockRandomModifier = %d",BlockRandomModifier); @@ -2842,7 +2837,7 @@ bool CRecompiler::GenerateX86Code(CBlockInfo & BlockInfo, CBlockSection * Sectio Compile_R4300i_UnknownOpcode(Section); break; } - if (m_DisableRegCaching) { WriteBackRegisters(Section); } + if (!bRegCaching()) { WriteBackRegisters(Section); } Section->ResetX86Protection(); /*if ((DWORD)RecompPos > 0x60B452E6) { @@ -2899,7 +2894,7 @@ bool CRecompiler::GenerateX86Code(CBlockInfo & BlockInfo, CBlockSection * Sectio break; case DELAY_SLOT: NextInstruction = DELAY_SLOT_DONE; - Section->BlockCycleCount() -= m_CountPerOp; + Section->BlockCycleCount() -= CountPerOp(); Section->BlockRandomModifier() -= 1; Section->CompilePC -= 4; break; @@ -2967,7 +2962,7 @@ void CRecompiler::CompileExit ( CBlockSection * Section, DWORD JumpPC, DWORD Tar #ifdef LinkBlocks if (bSMM_ValidFunc == false) { - if (LookUpMode == FuncFind_ChangeMemory) + if (LookUpMode() == FuncFind_ChangeMemory) { BreakPoint(__FILE__,__LINE__); // BYTE * Jump, * Jump2; @@ -3002,7 +2997,7 @@ void CRecompiler::CompileExit ( CBlockSection * Section, DWORD JumpPC, DWORD Tar // *((BYTE *)(Jump2))=(BYTE)(RecompPos - Jump2 - 1); // } } - else if (LookUpMode == FuncFind_VirtualLookup) + else if (LookUpMode() == FuncFind_VirtualLookup) { MoveConstToX86reg(TargetPC,x86_EDX); MoveConstToX86reg((DWORD)&m_Functions,x86_ECX); @@ -3015,7 +3010,7 @@ void CRecompiler::CompileExit ( CBlockSection * Section, DWORD JumpPC, DWORD Tar CPU_Message(" NullPointer:"); *((BYTE *)(Jump))=(BYTE)(RecompPos - Jump - 1); } - else if (LookUpMode == FuncFind_PhysicalLookup) + else if (LookUpMode() == FuncFind_PhysicalLookup) { BYTE * Jump2 = NULL; if (TargetPC >= 0x80000000 && TargetPC < 0x90000000) { @@ -3370,7 +3365,7 @@ void SyncRegState (CBlockSection * Section, CRegInfo * SyncTo) { } } -void GenerateSectionLinkage (CBlockSection * Section) { +void CRecompiler::GenerateSectionLinkage (CBlockSection * Section) { CBlockSection ** TargetSection[2]; CJumpInfo * JumpInfo[2]; BYTE * Jump; @@ -3440,10 +3435,10 @@ void GenerateSectionLinkage (CBlockSection * Section) { CPU_Message("PermLoop *** a"); MoveConstToVariable(Section->CompilePC,g_PROGRAM_COUNTER,"PROGRAM_COUNTER"); WriteBackRegisters(Section); - Section->RegWorking.BlockCycleCount() -= CountPerOp; + Section->RegWorking.BlockCycleCount() -= CountPerOp(); g_N64System->GetRecompiler()->UpdateCounters(&Section->RegWorking.BlockCycleCount(),&Section->RegWorking.BlockRandomModifier(), false); Call_Direct(InPermLoop,"InPermLoop"); - Section->RegWorking.BlockCycleCount() += CountPerOp; + Section->RegWorking.BlockCycleCount() += CountPerOp(); g_N64System->GetRecompiler()->UpdateCounters(&Section->RegWorking.BlockCycleCount(),&Section->RegWorking.BlockRandomModifier(), true); g_N64System->GetRecompiler()->CompileSystemCheck(-1,Section->RegWorking); @@ -3514,10 +3509,10 @@ CPU_Message("PermLoop *** a"); if (JumpInfo[count]->PermLoop) { CPU_Message("PermLoop *** 1"); MoveConstToVariable(JumpInfo[count]->TargetPC,g_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - JumpInfo[count]->RegSet.BlockCycleCount() -= CountPerOp; + JumpInfo[count]->RegSet.BlockCycleCount() -= CountPerOp(); g_N64System->GetRecompiler()->UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), false); Call_Direct(InPermLoop,"InPermLoop"); - JumpInfo[count]->RegSet.BlockCycleCount() += CountPerOp; + JumpInfo[count]->RegSet.BlockCycleCount() += CountPerOp(); g_N64System->GetRecompiler()->UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), true); g_N64System->GetRecompiler()->CompileSystemCheck(-1,JumpInfo[count]->RegSet); } else { @@ -3550,10 +3545,10 @@ CPU_Message("PermLoop *** 1"); if (JumpInfo[count]->PermLoop) { CPU_Message("PermLoop *** 2"); MoveConstToVariable(JumpInfo[count]->TargetPC,g_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - JumpInfo[count]->RegSet.BlockCycleCount() -= CountPerOp; + JumpInfo[count]->RegSet.BlockCycleCount() -= CountPerOp(); g_N64System->GetRecompiler()->UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), false); Call_Direct(InPermLoop,"InPermLoop"); - JumpInfo[count]->RegSet.BlockCycleCount() += CountPerOp; + JumpInfo[count]->RegSet.BlockCycleCount() += CountPerOp(); g_N64System->GetRecompiler()->UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), true); g_N64System->GetRecompiler()->CompileSystemCheck(-1,JumpInfo[count]->RegSet); } @@ -3692,7 +3687,7 @@ void CRecompiler::RemoveFunction (FUNCTION_INFO * FunInfo, bool DelaySlot, REMOV } //if no more functions in this block then unprotect the memory - if (bSMM_Protect) + if (bSMM_Protect()) { for (DWORD Addr = StartBlock; Addr <= EndBlock; Addr += 0x1000 ){ FUNCTION_INFO * info = m_Functions.FindFunction(Addr,0xFFF); @@ -3721,7 +3716,7 @@ bool CRecompiler::ClearRecompCode_Phys(DWORD Address, int length, REMOVE_REASON } } } - if (LookUpMode == FuncFind_PhysicalLookup) + if (LookUpMode() == FuncFind_PhysicalLookup) { WriteTraceF(TraceRecompiler,"Reseting Jump Table, Addr: %X len: %d",Address,((length + 3) & ~3)); memset((BYTE *)JumpTable + Address,0,((length + 3) & ~3)); @@ -3750,7 +3745,7 @@ bool CRecompiler::ClearRecompCode_Virt(DWORD Address, int length,REMOVE_REASON R } } while (info != NULL); - if (bSMM_Protect) + if (bSMM_Protect()) { DWORD Start = Address & ~0xFFF; info = m_Functions.FindFunction(Start,0xFFF); diff --git a/Source/Project64/N64 System/Recompiler/Recompiler Class.h b/Source/Project64/N64 System/Recompiler/Recompiler Class.h index b7f56fab7..6541f301d 100644 --- a/Source/Project64/N64 System/Recompiler/Recompiler Class.h +++ b/Source/Project64/N64 System/Recompiler/Recompiler Class.h @@ -15,18 +15,13 @@ public: private: CMipsMemory * const _MMU; //Memory of the n64 CRegisters * const _Reg; + bool const m_SyncSystem; CProfiling & m_Profile; bool & m_EndEmulation; //Quick access to registers DWORD & PROGRAM_COUNTER; - - //Cached settings - bool const m_SyncSystem, m_LinkBlocks, m_DisableRegCaching, - m_ValidateFuncs; - DWORD const m_RdramSize, m_CountPerOp; - FUNC_LOOKUP_METHOD const m_LookUpMode; - + //Functions CDelaySlotFunctionMap m_FunctionsDelaySlot; CFunctionMap m_Functions; @@ -68,6 +63,7 @@ public: void UpdateCounters ( DWORD * Cycles, DWORD * RandomMod, BOOL CheckTimer); void CompileExit ( CBlockSection * Section, DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegSet, CExitInfo::EXIT_REASON reason, int CompileNow, void (*x86Jmp)(char * Label, DWORD Value)); bool GenerateX86Code (CBlockInfo & BlockInfo, CBlockSection * Section, DWORD Test ); + void GenerateSectionLinkage (CBlockSection * Section); //Self modifying code methods bool ClearRecompCode_Virt ( DWORD VirtualAddress, int length, REMOVE_REASON Reason ); diff --git a/Source/Project64/N64 System/Recompiler/vssver2.scc b/Source/Project64/N64 System/Recompiler/vssver2.scc deleted file mode 100644 index c7e6658888e7e756da17ec37c250df18f03f2caf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 446 zcmXpJVr2O5UJx$3wZX0T{E4-~cRANr-_dSYV_{(6VqjoU2hvZir>sd>;pq=#GH3va zlNG^NRGo!if%uw0qV8@HSL+-{ZdM>)3&=PAb@kt*Xobljd2JxU!@j)9XvGh(ejOnH zI>V(aTO$kGLGrpl!eZ9$eLK%BF=htx^?>|{>+h^59JZeel7FMl!0@afP3!u6?Q}*U z|1FSj?YhGFV!MwIh_9j_P?VpQnp|RL0%IwdnJ5_Qnd=AVmlh?b>iYq?!Ii}&sk!<= zsmb}d1(`XiMGOe0f^$w{aj{+ogIj4{a!F=>o`PpyT0W4Ep(MGWfFT%Y6_OehE=V5L g5EK#L!~#sa5P~4JE~z<*l?uT*`6UWONMtYo0P(erH~;_u diff --git a/Source/Project64/N64 System/vssver2.scc b/Source/Project64/N64 System/vssver2.scc deleted file mode 100644 index 8a346eb791d699f7bc5b0f37862c189809039917..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 545 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAO8HTK^Ag^7WIkAZoMXZF?W3C-QOt`NBYcM6y=$&Z7J86@YvZAb+;8^!vvA-;E&sqCoz-a}UlRzF8Xy zQZEMNKg=%PrB$&I%5~TPBrgf%3r_h_2;u{s z#2^LaI~Eijh4H0<{K+O!X|GotG++eE%K-T^F14SZ+k6Vl-w)(laM*WV_Pd?{WHKB8 z5_~ltDqB;)USv?w4=BpdN=+^?Gl8)b%uEyv_008y^Gl18Q}z9T+~CUMlGI!V=Zw_E z5(Vd+#NuMTfBz@S#GZ+Am0H%fj diff --git a/Source/Project64/Plugins/Audio Plugin.cpp b/Source/Project64/Plugins/Audio Plugin.cpp index bd63c4f4e..aa1554582 100644 --- a/Source/Project64/Plugins/Audio Plugin.cpp +++ b/Source/Project64/Plugins/Audio Plugin.cpp @@ -66,10 +66,10 @@ CAudioPlugin::CAudioPlugin ( const char * FileName) { info.DefaultStartRange = FirstAudioDefaultSet; info.SettingStartRange = FirstAudioSettings; info.MaximumSettings = MaxPluginSetting; - info.NoDefault = No_Default; - info.DefaultLocation = _Settings->LoadDword(UseSettingFromRegistry) ? SettingLocation_Registry : SettingLocation_CfgFile; + info.NoDefault = Default_None; + info.DefaultLocation = _Settings->LoadDword(Setting_UseFromRegistry) ? SettingType_Registry : SettingType_CfgFile; info.handle = _Settings; - info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingLocation,const char *,const char *, DWORD))CSettings::RegisterSetting; + info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingType,const char *,const char *, DWORD))CSettings::RegisterSetting; info.GetSetting = (unsigned int (*)( void * handle, int ID ))CSettings::GetSetting; info.GetSettingSz = (const char * (*)( void *, int, char *, int ))CSettings::GetSettingSz; info.SetSetting = (void (*)(void *,int,unsigned int))CSettings::SetSetting; diff --git a/Source/Project64/Plugins/Controller Plugin.cpp b/Source/Project64/Plugins/Controller Plugin.cpp index 8d56fbc5d..5bc937cea 100644 --- a/Source/Project64/Plugins/Controller Plugin.cpp +++ b/Source/Project64/Plugins/Controller Plugin.cpp @@ -67,10 +67,10 @@ CControl_Plugin::CControl_Plugin ( const char * FileName) { info.DefaultStartRange = FirstCtrlDefaultSet; info.SettingStartRange = FirstCtrlSettings; info.MaximumSettings = MaxPluginSetting; - info.NoDefault = No_Default; - info.DefaultLocation = _Settings->LoadDword(UseSettingFromRegistry) ? SettingLocation_Registry : SettingLocation_CfgFile; + info.NoDefault = Default_None; + info.DefaultLocation = _Settings->LoadDword(Setting_UseFromRegistry) ? SettingType_Registry : SettingType_CfgFile; info.handle = _Settings; - info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingLocation,const char *,const char *, DWORD))CSettings::RegisterSetting; + info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingType,const char *,const char *, DWORD))CSettings::RegisterSetting; info.GetSetting = (unsigned int (*)( void * handle, int ID ))CSettings::GetSetting; info.GetSettingSz = (const char * (*)( void *, int, char *, int ))CSettings::GetSettingSz; info.SetSetting = (void (*)(void *,int,unsigned int))CSettings::SetSetting; diff --git a/Source/Project64/Plugins/GFX plugin.cpp b/Source/Project64/Plugins/GFX plugin.cpp index f05a90fb1..4b6c5355e 100644 --- a/Source/Project64/Plugins/GFX plugin.cpp +++ b/Source/Project64/Plugins/GFX plugin.cpp @@ -93,10 +93,10 @@ CGfxPlugin::CGfxPlugin ( const char * FileName) { info.DefaultStartRange = FirstGfxDefaultSet; info.SettingStartRange = FirstGfxSettings; info.MaximumSettings = MaxPluginSetting; - info.NoDefault = No_Default; -/* info.DefaultLocation = _Settings->LoadDword(UseSettingFromRegistry) ? InRegistry : LocalSettings; + info.NoDefault = Default_None; + info.DefaultLocation = _Settings->LoadDword(Setting_UseFromRegistry) ? SettingType_Registry : SettingType_CfgFile; info.handle = _Settings; - info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingLocation,const char *,const char *, DWORD))CSettings::RegisterSetting; + info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingType,const char *,const char *, DWORD))CSettings::RegisterSetting; info.GetSetting = (unsigned int (*)( void * handle, int ID ))CSettings::GetSetting; info.GetSettingSz = (const char * (*)( void *, int, char *, int ))CSettings::GetSettingSz; info.SetSetting = (void (*)(void *,int,unsigned int))CSettings::SetSetting; @@ -104,8 +104,8 @@ CGfxPlugin::CGfxPlugin ( const char * FileName) { info.UseUnregisteredSetting = NULL; SetSettingInfo(&info); - _Settings->UnknownSetting_GFX = info.UseUnregisteredSetting; -*/ +// _Settings->UnknownSetting_GFX = info.UseUnregisteredSetting; + PluginOpened(); } // FrameBufferRead = (void (__cdecl *)(DWORD))GetProcAddress( (HMODULE)hDll, "FBRead" ); diff --git a/Source/Project64/Plugins/Plugin Class.cpp b/Source/Project64/Plugins/Plugin Class.cpp index 3fa255de2..66e7b76f7 100644 --- a/Source/Project64/Plugins/Plugin Class.cpp +++ b/Source/Project64/Plugins/Plugin Class.cpp @@ -18,7 +18,7 @@ void CPlugins::CreatePlugins( void ) { Reset(PLUGIN_TYPE_RSP); Reset(PLUGIN_TYPE_CONTROLLER); - if (_Settings->LoadDword(Debugger)) + if (_Settings->LoadBool(Debugger_Enabled)) { Notify().RefreshMenu(); } @@ -151,7 +151,8 @@ void CPlugins::Reset ( void ) { CreatePlugins(); } -void CPlugins::Reset ( PLUGIN_TYPE Type ) { +void CPlugins::Reset ( PLUGIN_TYPE Type ) +{ switch (Type) { case PLUGIN_TYPE_RSP: @@ -166,20 +167,20 @@ void CPlugins::Reset ( PLUGIN_TYPE Type ) { m_RSP = NULL; } { - stdstr_f RspPluginFile("%s%s",m_PluginDir.c_str(),_Settings->LoadString(CurrentRSP_Plugin).c_str()); + stdstr_f RspPluginFile("%s%s",m_PluginDir.c_str(),_Settings->LoadString(Plugin_RSP_Current).c_str()); WriteTraceF(TraceRSP,"Loading (%s): Starting",RspPluginFile.c_str()); m_RSP = new CRSP_Plugin(RspPluginFile.c_str()); WriteTrace(TraceRSP,"Loading Done"); } WriteTraceF(TraceRSP,"Current Ver: %s",m_RSP->PluginName().c_str()); - _Settings->SaveString(CurVerRSP_Plugin,m_RSP->PluginName().c_str()); + _Settings->SaveString(Plugin_RSP_CurVer,m_RSP->PluginName().c_str()); //Enable debugger if (m_RSP->EnableDebugging) { WriteTrace(TraceRSP,"EnableDebugging: starting"); - m_RSP->EnableDebugging(_Settings->LoadDword(Debugger)); + m_RSP->EnableDebugging(_Settings->LoadDword(Debugger_Enabled)); WriteTrace(TraceRSP,"EnableDebugging: done"); } break; @@ -195,49 +196,48 @@ void CPlugins::Reset ( PLUGIN_TYPE Type ) { m_Gfx = NULL; } { - stdstr_f GfxPluginFile("%s%s",m_PluginDir.c_str(),_Settings->LoadString(CurrentGFX_Plugin).c_str()); + stdstr_f GfxPluginFile("%s%s",m_PluginDir.c_str(),_Settings->LoadString(Game_Plugin_Gfx).c_str()); WriteTraceF(TraceGfxPlugin,"Loading (%s): Starting",GfxPluginFile.c_str()); m_Gfx = new CGfxPlugin(GfxPluginFile.c_str()); WriteTrace(TraceGfxPlugin,"Loading Done"); } WriteTraceF(TraceGfxPlugin,"Current Ver: %s",m_Gfx->PluginName().c_str()); - _Settings->SaveString(CurVerGFX_Plugin,m_Gfx->PluginName().c_str()); + _Settings->SaveString(Plugin_GFX_CurVer,m_Gfx->PluginName().c_str()); break; case PLUGIN_TYPE_AUDIO: WriteTrace(TraceDebug,"CPlugins::Reset 17"); if (m_Audio) { - WriteTrace(TraceDebug,"CPlugins::Reset 18"); + WriteTrace(TraceDebug,"CPlugins::Reset 18"); m_Audio->Close(); - WriteTrace(TraceDebug,"CPlugins::Reset 19"); + WriteTrace(TraceDebug,"CPlugins::Reset 19"); delete m_Audio; - WriteTrace(TraceDebug,"CPlugins::Reset 20"); + WriteTrace(TraceDebug,"CPlugins::Reset 20"); m_Audio = NULL; - WriteTrace(TraceDebug,"CPlugins::Reset 21"); + WriteTrace(TraceDebug,"CPlugins::Reset 21"); } WriteTrace(TraceDebug,"CPlugins::Reset 22"); - m_Audio = new CAudioPlugin(stdstr_f("%s%s",m_PluginDir.c_str(),_Settings->LoadString(CurrentAUDIO_Plugin).c_str()).c_str()); + m_Audio = new CAudioPlugin(stdstr_f("%s%s",m_PluginDir.c_str(),_Settings->LoadString(Game_Plugin_Audio).c_str()).c_str()); WriteTrace(TraceDebug,"CPlugins::Reset 23"); - _Settings->SaveString(CurVerAUDIO_Plugin,m_Audio->PluginName().c_str()); + _Settings->SaveString(Plugin_AUDIO_CurVer,m_Audio->PluginName().c_str()); WriteTrace(TraceDebug,"CPlugins::Reset 24"); break; case PLUGIN_TYPE_CONTROLLER: WriteTrace(TraceDebug,"CPlugins::Reset 25"); if (m_Control) { - WriteTrace(TraceDebug,"CPlugins::Reset 26"); + WriteTrace(TraceDebug,"CPlugins::Reset 26"); m_Control->Close(); - WriteTrace(TraceDebug,"CPlugins::Reset 27"); + WriteTrace(TraceDebug,"CPlugins::Reset 27"); delete m_Control; - WriteTrace(TraceDebug,"CPlugins::Reset 28"); + WriteTrace(TraceDebug,"CPlugins::Reset 28"); m_Control = NULL; - WriteTrace(TraceDebug,"CPlugins::Reset 29"); + WriteTrace(TraceDebug,"CPlugins::Reset 29"); } WriteTrace(TraceDebug,"CPlugins::Reset 30"); - m_Control = new CControl_Plugin(stdstr_f("%s%s",m_PluginDir.c_str(),_Settings->LoadString(CurrentCONT_Plugin).c_str()).c_str()); + m_Control = new CControl_Plugin(stdstr_f("%s%s",m_PluginDir.c_str(),_Settings->LoadString(Game_Plugin_Controller).c_str()).c_str()); WriteTrace(TraceDebug,"CPlugins::Reset 31"); - _Settings->SaveString(CurVerCONT_Plugin,m_Control->PluginName().c_str()); + _Settings->SaveString(Plugin_CONT_CurVer,m_Control->PluginName().c_str()); WriteTrace(TraceDebug,"CPlugins::Reset 32"); break; - } } @@ -305,8 +305,10 @@ void CPlugins::CreatePluginDir ( const stdstr & DstDir ) const { } void CPlugins::CopyPlugins ( const stdstr & DstDir ) const { + Notify().BreakPoint(__FILE__,__LINE__); + //Copy GFX Plugin - stdstr_f srcGfxPlugin("%s%s",m_PluginDir.c_str(),_Settings->LoadString(CurrentGFX_Plugin).c_str()); + /*stdstr_f srcGfxPlugin("%s%s",m_PluginDir.c_str(),_Settings->LoadString(CurrentGFX_Plugin).c_str()); stdstr_f dstGfxPlugin("%s%s",DstDir.c_str(),_Settings->LoadString(CurrentGFX_Plugin).c_str()); if (CopyFile(srcGfxPlugin.c_str(),dstGfxPlugin.c_str(),false) == 0) @@ -337,5 +339,5 @@ void CPlugins::CopyPlugins ( const stdstr & DstDir ) const { if (CopyFile(srcContPlugin.c_str(),dstContPlugin.c_str(),false) == 0) { if (GetLastError() == ERROR_PATH_NOT_FOUND) { CreatePluginDir(dstContPlugin); } CopyFile(srcContPlugin.c_str(),dstContPlugin.c_str(),false); - } + }*/ } diff --git a/Source/Project64/Plugins/Plugin Class.h b/Source/Project64/Plugins/Plugin Class.h index 1acd05f2b..4c9a70ffc 100644 --- a/Source/Project64/Plugins/Plugin Class.h +++ b/Source/Project64/Plugins/Plugin Class.h @@ -50,11 +50,12 @@ typedef struct { void (*SetSetting) ( void * handle, int ID, unsigned int Value ); void (*SetSettingSz) ( void * handle, int ID, const char * Value ); void (*RegisterSetting) ( void * handle, int ID, int DefaultID, SettingDataType Type, - SettingLocation Location, const char * Category, const char * DefaultStr, DWORD Value ); + SettingType Location, const char * Category, const char * DefaultStr, DWORD Value ); void (*UseUnregisteredSetting) (int ID); } PLUGIN_SETTINGS; enum PLUGIN_TYPE { + PLUGIN_TYPE_NONE = 0, PLUGIN_TYPE_RSP = 1, PLUGIN_TYPE_GFX = 2, PLUGIN_TYPE_AUDIO = 3, diff --git a/Source/Project64/Plugins/Plugin List.cpp b/Source/Project64/Plugins/Plugin List.cpp index e8a857626..eb8264ed9 100644 --- a/Source/Project64/Plugins/Plugin List.cpp +++ b/Source/Project64/Plugins/Plugin List.cpp @@ -1,5 +1,138 @@ #include "..\Plugin.h" +CPluginList::CPluginList(bool bAutoFill /* = true */) : + m_PluginDir(_Settings->LoadString(Directory_Plugin),"") +{ + if (bAutoFill) + { + LoadList(); + } +} + +CPluginList::~CPluginList() +{ +} + +int CPluginList::GetPluginCount() const +{ + return m_PluginList.size(); +} + +const CPluginList::PLUGIN * CPluginList::GetPluginInfo ( int indx ) const +{ + if (indx < 0 || indx >= m_PluginList.size()) + { + return NULL; + } + return &m_PluginList[indx]; + +} + +bool CPluginList::LoadList() +{ + m_PluginList.clear(); + AddPluginFromDir(m_PluginDir); + return true; +} + +void CPluginList::AddPluginFromDir ( CPath Dir) +{ + Dir.SetNameExtension("*.*"); + if (Dir.FindFirst(_A_SUBDIR)) + { + do { + AddPluginFromDir(Dir); + } while (Dir.FindNext()); + Dir.UpDirectory(); + } + + Dir.SetNameExtension("*.dll"); + if (Dir.FindFirst()) + { + HMODULE hLib = NULL; + do { + if (hLib) + { + FreeLibrary(hLib); + hLib = NULL; + } + + UINT LastErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS ); + hLib = LoadLibrary(Dir); + SetErrorMode(LastErrorMode); + + if (hLib == NULL) + { + continue; + } + + void (__cdecl *GetDllInfo) ( PLUGIN_INFO * PluginInfo ); + GetDllInfo = (void (__cdecl *)(PLUGIN_INFO *))GetProcAddress( hLib, "GetDllInfo" ); + if (GetDllInfo == NULL) + { + continue; + } + + PLUGIN Plugin; + GetDllInfo(&Plugin.Info); + if (!ValidPluginVersion(Plugin.Info)) + { + continue; + } + + Plugin.FullPath = Dir; + Plugin.FileName = ((stdstr &)Dir).substr(((stdstr &)m_PluginDir).length()); + + if (GetProcAddress(hLib,"DllAbout") != NULL) + { + Plugin.AboutFunction = true; + } + m_PluginList.push_back(Plugin); + } while (Dir.FindNext()); + + if (hLib) + { + FreeLibrary(hLib); + hLib = NULL; + } + } +} + +bool CPluginList::ValidPluginVersion ( PLUGIN_INFO & PluginInfo ) { + if (!PluginInfo.MemoryBswaped) + { + return false; + } + + switch (PluginInfo.Type) + { + case PLUGIN_TYPE_RSP: + if (PluginInfo.Version == 0x0001) { return true; } + if (PluginInfo.Version == 0x0100) { return true; } + if (PluginInfo.Version == 0x0101) { return true; } + if (PluginInfo.Version == 0x0102) { return true; } + break; + case PLUGIN_TYPE_GFX: + if (PluginInfo.Version == 0x0102) { return true; } + if (PluginInfo.Version == 0x0103) { return true; } + if (PluginInfo.Version == 0x0104) { return true; } + break; + case PLUGIN_TYPE_AUDIO: + if (PluginInfo.Version == 0x0101) { return true; } + if (PluginInfo.Version == 0x0102) { return true; } + break; + case PLUGIN_TYPE_CONTROLLER: + if (PluginInfo.Version == 0x0100) { return true; } + if (PluginInfo.Version == 0x0101) { return true; } + if (PluginInfo.Version == 0x0102) { return true; } + break; + } + return FALSE; +} + + + +#ifdef tofix CPluginList::CPluginList (CSettings * Settings) { _Settings = Settings; } @@ -98,12 +231,13 @@ PluginList CPluginList::GetPluginList (void) { PluginList Plugins; //Create search path for plugins - char SearchDir[300] = ""; + Notify().BreakPoint(__FILE__,__LINE__); +/* char SearchDir[300] = ""; _Settings->LoadString(PluginDirectory,SearchDir,sizeof(SearchDir)); //recursively scan search dir, and add files in that dir AddPluginFromDir(SearchDir,SearchDir,&Plugins); - + */ return Plugins; } @@ -132,3 +266,5 @@ bool CPluginList::ValidPluginVersion ( PLUGIN_INFO * PluginInfo ) { } return FALSE; } + +#endif \ No newline at end of file diff --git a/Source/Project64/Plugins/Plugin List.h b/Source/Project64/Plugins/Plugin List.h index bddac573b..8289123db 100644 --- a/Source/Project64/Plugins/Plugin List.h +++ b/Source/Project64/Plugins/Plugin List.h @@ -1,6 +1,6 @@ #include "..\\Settings.h" -typedef struct { +/*typedef struct { PLUGIN_INFO info; stdstr FullPath; stdstr FileName; @@ -9,15 +9,42 @@ typedef struct { typedef std::list PluginList; -class CPluginList { - CSettings * _Settings; - +class CPluginList { void AddPluginFromDir ( const char * PluginDir, const char * Dir, PluginList * Plugins ); bool ValidPluginVersion ( PLUGIN_INFO * PluginInfo ); public: - CPluginList ( CSettings * Settings); + CPluginList (); PluginList GetPluginList ( void ); void DllAbout ( void * hParent, const char * PluginFile ); }; +*/ + +class CPluginList +{ +public: + typedef struct { + PLUGIN_INFO Info; + bool AboutFunction; + CPath FullPath; + stdstr FileName; + } PLUGIN; + +private: + typedef std::vector PluginList; + + PluginList m_PluginList; + CPath m_PluginDir; + + void AddPluginFromDir ( CPath Dir); + bool ValidPluginVersion ( PLUGIN_INFO & PluginInfo ); + +public: + CPluginList(bool bAutoFill = true); + ~CPluginList(); + + bool LoadList ( void ); + int GetPluginCount ( void ) const; + const PLUGIN * GetPluginInfo ( int indx ) const; +}; diff --git a/Source/Project64/Plugins/RSP Plugin.cpp b/Source/Project64/Plugins/RSP Plugin.cpp index 580cf3a6d..360eb4ac2 100644 --- a/Source/Project64/Plugins/RSP Plugin.cpp +++ b/Source/Project64/Plugins/RSP Plugin.cpp @@ -63,10 +63,10 @@ CRSP_Plugin::CRSP_Plugin ( const char * FileName) { info.DefaultStartRange = FirstRSPDefaultSet; info.SettingStartRange = FirstRSPSettings; info.MaximumSettings = MaxPluginSetting; - info.NoDefault = No_Default; - info.DefaultLocation = _Settings->LoadDword(UseSettingFromRegistry) ? SettingLocation_Registry : SettingLocation_CfgFile; + info.NoDefault = Default_None; + info.DefaultLocation = _Settings->LoadDword(Setting_UseFromRegistry) ? SettingType_Registry : SettingType_CfgFile; info.handle = _Settings; - info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingLocation,const char *,const char *, DWORD))CSettings::RegisterSetting; + info.RegisterSetting = (void (*)(void *,int,int,SettingDataType,SettingType,const char *,const char *, DWORD))CSettings::RegisterSetting; info.GetSetting = (unsigned int (*)( void * handle, int ID ))CSettings::GetSetting; info.GetSettingSz = (const char * (*)( void *, int, char *, int ))CSettings::GetSettingSz; info.SetSetting = (void (*)(void *,int,unsigned int))CSettings::SetSetting; diff --git a/Source/Project64/Plugins/vssver2.scc b/Source/Project64/Plugins/vssver2.scc deleted file mode 100644 index e5344c87b5abfc9d60dd6863750e30b93112e08f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 458 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAND=oO3q%EZ9H!@$6h%FMtpL+tj=sxt?QIDq^# zAYVb;%<1&=>Cf4K{B$7y>d(ZU=%97+oIrjCkpJgp{IScIPJaf;X9D>tJVq-Rw=9h3 z1M;(g{E}{68;eOD$GCy~Y#{&Cy68Ib{t{%z279lIb z6wP38cZ*Oc0GkRn2Z@`(05M;|IVZ8W7%Yn-0GId4EG|Ko2J

Build Log

---------------------Configuration: Project64 - Win32 Debug-------------------- +--------------------Configuration: Project64 - Win32 External Release--------------------

Command Lines

-Creating command line "rc.exe /l 0xc09 /fo"../../Build/Project64/Debug/UI Resources.res" /i "User Interface" /d "_DEBUG" "D:\My Programs\Emulation\Project64\Source\Project64\User Interface\UI Resources.rc"" -Creating temporary file "C:\DOCUME~1\NICHOL~1\LOCALS~1\Temp\RSP508.tmp" with contents +Creating command line "rc.exe /l 0xc09 /fo"../../Build/Project64/External/UI Resources.res" /i "User Interface" /d "NDEBUG" "D:\My Programs\Emulation\Project64\Source\Project64\User Interface\UI Resources.rc"" +Creating temporary file "C:\DOCUME~1\NICHOL~1\LOCALS~1\Temp\RSPA1.tmp" with contents [ -kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:yes /pdb:"../../Bin/Debug/Project64.pdb" /debug /machine:I386 /out:"../../Bin/Debug/Project64.exe" /pdbtype:sept -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-Application.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-ApplicationIndex.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-GameSetting.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-RelativePath.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-RomDatabase.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-TempBool.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-TempNumber.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\SettingsType-TempString.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\N64System Settings.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Notification Settings.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Recompiler Settings.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Setting Config.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Settings Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Cheats.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Frame Per Second Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Gui Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Main Menu Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Menu Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Notification Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Rom Browser Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Language Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Audio.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Memory Labels Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Memory.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\OpCode Analysis Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\OpCode Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Register Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\System Timing.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\TLB class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\BreakPoints.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\C Core Interface.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\C main.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\C Memory.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\CPU Log.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\CPU.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Dma.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Eeprom.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Exception.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\FlashRam.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Interpreter CPU.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Interpreter Ops.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Logging.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Mempak.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Pif.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\r4300i Commands.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\r4300i Memory.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\r4300i Registers.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Recompiler CPU.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Recompiler Fpu Ops.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Recompiler Ops.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Registers.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Sram.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Sync CPU.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\TLB Display.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Tlb.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Win32Timer.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\x86 fpu.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\X86.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Debugger - Memory Dump.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Debugger - Memory Search.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Debugger - TLB.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Debugger - View Memory.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Debugger.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Delay Slot Map Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Function Info.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Function Map Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Recompiler Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Section Info.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Cheat Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\N64 Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\N64 Rom Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Profiling Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Rom Information Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Speed Limitor Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Audio Plugin.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Controller Plugin.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\GFX plugin.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Plugin Class.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Plugin List.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\RSP Plugin.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\UNZIP.OBJ" -"\My Programs\Emulation\Project64\Build\Project64\Debug\zip.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\7zip.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Processor Info.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Gui Settings.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\main.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\ValidateBinary.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\UI Resources.res" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Settings Config.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Settings Page.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Settings Page - Game - Recompiler.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Settings Page - Game - Status.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Settings Page - Game - General.obj" -"\My Programs\Emulation\Project64\Build\Project64\Debug\Settings Page - Game - Plugin.obj" -"\My Programs\Emulation\Project64\Bin\Debug\Common.lib" -"\My Programs\Emulation\Project64\Bin\Debug\7zip.lib" +/nologo /MD /W3 /GX /O2 /I "../" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "EXTERNAL_RELEASE" /Fp"../../Build/Project64/External/Project64.pch" /YX /Fo"../../Build/Project64/External/" /Fd"../../Build/Project64/External/" /FD /EHa /c +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-Application.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-ApplicationIndex.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-Cheats.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-GameSetting.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-GameSettingIndex.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RDBCpuType.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RDBOnOff.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RDBRamSize.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RDBSaveChip.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RDBYesNo.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RelativePath.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RomDatabase.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-RomDatabaseIndex.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-SelectedDirectory.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-TempBool.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-TempNumber.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\SettingType\SettingsType-TempString.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\N64System Settings.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\Notification Settings.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\Recompiler Settings.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\Settings Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Advanced Options.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Directories.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Game - General.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Game - Plugin.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Game - Recompiler.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Game - Status.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Game Browser.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Keyboard Shortcuts.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Options.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page - Plugin.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings\Settings Page.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\WTL Controls\ModifiedEditBox.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\WTL Controls\PartialGroupBox.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Cheats.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Frame Per Second Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Gui Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Main Menu Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Menu Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\MenuShortCuts.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Notification Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Rom Browser Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\User Interface\Settings Config.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Multilanguage\Language Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\Audio.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\Memory Labels Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\Memory.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\OpCode Analysis Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\OpCode Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\Register Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\System Timing.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Mips\TLB class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\BreakPoints.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\C Core Interface.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\C Memory.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\CPU.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Dma.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Eeprom.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\FlashRam.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Interpreter CPU.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Mempak.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Pif.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Recompiler CPU.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Recompiler Fpu Ops.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Recompiler Ops.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\C Core\Registers.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Debugger\Debugger - Memory Dump.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Debugger\Debugger - Memory Search.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Debugger\Debugger - TLB.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Debugger\Debugger - View Memory.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Debugger\Debugger.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Recompiler\Delay Slot Map Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Recompiler\Function Info.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Recompiler\Function Map Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Recompiler\Recompiler Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Recompiler\Section Info.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Cheat Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\N64 Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\N64 Rom Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Profiling Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Rom Information Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\N64 System\Speed Limitor Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Plugins\Audio Plugin.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Plugins\Controller Plugin.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Plugins\GFX plugin.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Plugins\Plugin Class.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Plugins\Plugin List.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Plugins\RSP Plugin.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\Settings\Gui Settings.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\main.cpp" +"D:\My Programs\Emulation\Project64\Source\Project64\ValidateBinary.cpp" ] -Creating command line "link.exe @C:\DOCUME~1\NICHOL~1\LOCALS~1\Temp\RSP508.tmp" +Creating command line "cl.exe @C:\DOCUME~1\NICHOL~1\LOCALS~1\Temp\RSPA1.tmp" +Creating temporary file "C:\DOCUME~1\NICHOL~1\LOCALS~1\Temp\RSPA2.tmp" with contents +[ +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no /pdb:"../../Bin/External/Project64.pdb" /machine:I386 /out:"../../Bin/External/Project64.exe" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-Application.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-ApplicationIndex.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-Cheats.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-GameSetting.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-GameSettingIndex.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RDBCpuType.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RDBOnOff.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RDBRamSize.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RDBSaveChip.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RDBYesNo.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RelativePath.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RomDatabase.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-RomDatabaseIndex.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-SelectedDirectory.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-TempBool.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-TempNumber.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\SettingsType-TempString.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\N64System Settings.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Notification Settings.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Recompiler Settings.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Setting Config.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Advanced Options.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Directories.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Game - General.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Game - Plugin.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Game - Recompiler.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Game - Status.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Game Browser.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Keyboard Shortcuts.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Options.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page - Plugin.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Page.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\ModifiedEditBox.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\PartialGroupBox.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Cheats.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Frame Per Second Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Gui Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Main Menu Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Menu Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\MenuShortCuts.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Notification Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Rom Browser Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Settings Config.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Language Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Audio.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Memory Labels Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Memory.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\OpCode Analysis Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\OpCode Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Register Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\System Timing.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\TLB class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\BreakPoints.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\C Core Interface.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\C main.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\C Memory.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\CPU Log.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\CPU.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Dma.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Eeprom.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Exception.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\FlashRam.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Interpreter CPU.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Interpreter Ops.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Logging.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Mempak.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Pif.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\r4300i Commands.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\r4300i Memory.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\r4300i Registers.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Recompiler CPU.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Recompiler Fpu Ops.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Recompiler Ops.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Registers.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Sram.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Sync CPU.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\TLB Display.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Tlb.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Win32Timer.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\x86 fpu.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\X86.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Debugger - Memory Dump.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Debugger - Memory Search.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Debugger - TLB.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Debugger - View Memory.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Debugger.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Delay Slot Map Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Function Info.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Function Map Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Recompiler Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Section Info.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Cheat Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\N64 Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\N64 Rom Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Profiling Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Rom Information Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Speed Limitor Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Audio Plugin.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Controller Plugin.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\GFX plugin.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Plugin Class.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Plugin List.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\RSP Plugin.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\UNZIP.OBJ" +"\My Programs\Emulation\Project64\Build\Project64\External\zip.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\7zip.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Processor Info.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\Gui Settings.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\main.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\ValidateBinary.obj" +"\My Programs\Emulation\Project64\Build\Project64\External\UI Resources.res" +"\My Programs\Emulation\Project64\Bin\External\Common.lib" +"\My Programs\Emulation\Project64\Bin\External\7zip.lib" +] +Creating command line "link.exe @C:\DOCUME~1\NICHOL~1\LOCALS~1\Temp\RSPA2.tmp"

Output Window

Compiling resources... +Compiling... +SettingsType-Application.cpp +SettingsType-ApplicationIndex.cpp +SettingsType-Cheats.cpp +SettingsType-GameSetting.cpp +SettingsType-GameSettingIndex.cpp +SettingsType-RDBCpuType.cpp +SettingsType-RDBOnOff.cpp +SettingsType-RDBRamSize.cpp +SettingsType-RDBSaveChip.cpp +SettingsType-RDBYesNo.cpp +SettingsType-RelativePath.cpp +SettingsType-RomDatabase.cpp +SettingsType-RomDatabaseIndex.cpp +SettingsType-SelectedDirectory.cpp +SettingsType-TempBool.cpp +SettingsType-TempNumber.cpp +SettingsType-TempString.cpp +N64System Settings.cpp +Notification Settings.cpp +Recompiler Settings.cpp +Settings Class.cpp +Settings Page - Advanced Options.cpp +Settings Page - Directories.cpp +Settings Page - Game - General.cpp +Settings Page - Game - Plugin.cpp +Settings Page - Game - Recompiler.cpp +Settings Page - Game - Status.cpp +Settings Page - Game Browser.cpp +Settings Page - Keyboard Shortcuts.cpp +Settings Page - Options.cpp +C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE\atlwin.h(2353) : warning C4247: 'StartDialogProc' not accessible because 'CSettingsPageImpl' uses 'public' to inherit from 'CDialogImpl' + C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE\atlwin.h(2231) : see declaration of 'StartDialogProc' + C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE\atlwin.h(2346) : while compiling class-template member function 'struct HWND__ *__thiscall ATL::CDialogImpl::Create(struct HWND__ *,long)' +Settings Page - Plugin.cpp +Settings Page.cpp +ModifiedEditBox.cpp +PartialGroupBox.cpp +Cheats.cpp +Frame Per Second Class.cpp +Gui Class.cpp +Main Menu Class.cpp +Menu Class.cpp +MenuShortCuts.cpp +Notification Class.cpp +Rom Browser Class.cpp +Settings Config.cpp +Language Class.cpp +Audio.cpp +Memory Labels Class.cpp +Memory.cpp +OpCode Analysis Class.cpp +OpCode Class.cpp +Register Class.cpp +System Timing.cpp +TLB class.cpp +BreakPoints.cpp +C Core Interface.cpp +C Memory.cpp +CPU.cpp +Dma.cpp +Eeprom.cpp +FlashRam.cpp +Interpreter CPU.cpp +Mempak.cpp +Pif.cpp +Recompiler CPU.cpp +Recompiler Fpu Ops.cpp +Recompiler Ops.cpp +Registers.cpp +Debugger - Memory Dump.cpp +Debugger - Memory Search.cpp +Debugger - TLB.cpp +Debugger - View Memory.cpp +Debugger.cpp +Delay Slot Map Class.cpp +Function Info.cpp +Function Map Class.cpp +Recompiler Class.cpp +Section Info.cpp +Cheat Class.cpp +N64 Class.cpp +N64 Rom Class.cpp +Profiling Class.cpp +Rom Information Class.cpp +Speed Limitor Class.cpp +Audio Plugin.cpp +Controller Plugin.cpp +GFX plugin.cpp +Plugin Class.cpp +Plugin List.cpp +RSP Plugin.cpp +Gui Settings.cpp +main.cpp +ValidateBinary.cpp Linking... -LINK : warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs; use /NODEFAULTLIB:library +LINK : warning LNK4089: all references to "OLEAUT32.dll" discarded by /OPT:REF

Results

-Project64.exe - 0 error(s), 1 warning(s) +Project64.exe - 0 error(s), 2 warning(s) diff --git a/Source/Project64/Settings.h b/Source/Project64/Settings.h index d36849df7..a2b5dfe3c 100644 --- a/Source/Project64/Settings.h +++ b/Source/Project64/Settings.h @@ -1,14 +1,221 @@ #ifndef __SETTINGS__H__ #define __SETTINGS__H__ -#define MaxRomBrowserFields 100 -#define MaxMD5_Per_Rom 10 -#define MaxCheats 500 #define MaxPluginSetting 65535 enum SettingID { //Default values - No_Default, Default_False, Default_True, Default_Language, Default_RdramSize, + Default_None, + Default_Constant, + + //information - temp keys + Info_RomLoading, + Info_ShortCutsChanged, + + //Support Files + SupportFile_Settings, + SupportFile_RomDatabase, + SupportFile_Cheats, + SupportFile_Notes, + SupportFile_ExtInfo, + SupportFile_ShortCuts, + SupportFile_RomListCache, + SupportFile_7zipCache, + + //Settings + Setting_ApplicationName, + Setting_UseFromRegistry, + Setting_RdbEditor, + Setting_DisableScrSaver, + Setting_AutoSleep, + Setting_AutoStart, + Setting_AutoFullscreen, + + Setting_AutoZipInstantSave, + Setting_RememberCheats, + Setting_CurrentLanguage, + + //RDB TLB Settings + Rdb_SaveChip, + Rdb_CpuType, + Rdb_RDRamSize, + Rdb_CounterFactor, + Rdb_UseTlb, + Rdb_DelaySi, + Rdb_SPHack, + Rdb_Status, + Rdb_FixedAudio, + Rdb_SyncViaAudio, + Rdb_RspAudioSignal, + Rdb_TLB_VAddrStart, + Rdb_TLB_VAddrLen, + Rdb_TLB_PAddrStart, + Rdb_UseHleGfx, + Rdb_UseHleAudio, + Rdb_LoadRomToMemory, + Rdb_ScreenHertz, + Rdb_FuncLookupMode, + Rdb_RegCache, + Rdb_BlockLinking, + Rdb_SMM_Cache, + Rdb_SMM_PIDMA, + Rdb_SMM_TLB, + Rdb_SMM_Protect, + Rdb_SMM_ValidFunc, + Rdb_GameCheatFix, + + //Individual Game Settings + Game_IniKey, + Game_GameName, + Game_GoodName, + Game_Plugin_Gfx, + Game_Plugin_Audio, + Game_Plugin_Controller, + Game_Plugin_RSP, + Game_SaveChip, + Game_CpuType, + Game_LastSaveSlot, + Game_FixedAudio, + Game_SyncViaAudio, + Game_SMM_Cache, + Game_SMM_Protect, + Game_SMM_ValidFunc, + Game_SMM_PIDMA, + Game_SMM_TLB, + Game_CurrentSaveState, + Game_RDRamSize, + Game_CounterFactor, + Game_UseTlb, + Game_DelaySI, + Game_SPHack, + Game_FuncLookupMode, + Game_RegCache, + Game_BlockLinking, + Game_ScreenHertz, + Game_RspAudioSignal, + Game_UseHleGfx, + Game_UseHleAudio, + Game_LoadRomToMemory, + + // General Game running info + GameRunning_LoadingInProgress, + GameRunning_CPU_Running, + GameRunning_CPU_Paused, + GameRunning_CPU_PausedType, + GameRunning_InstantSaveFile, + GameRunning_LimitFPS, + GameRunning_ScreenHertz, + + //User Interface + UserInterface_BasicMode, + UserInterface_ShowCPUPer, + UserInterface_DisplayFrameRate, + UserInterface_InFullScreen, + UserInterface_FrameDisplayType, + UserInterface_MainWindowTop, + UserInterface_MainWindowLeft, + UserInterface_AlwaysOnTop, + + RomBrowser_Enabled, + RomBrowser_ColoumnsChanged, + RomBrowser_Top, + RomBrowser_Left, + RomBrowser_Width, + RomBrowser_Height, + RomBrowser_PosIndex, + RomBrowser_WidthIndex, + RomBrowser_SortFieldIndex, + RomBrowser_SortAscendingIndex, + RomBrowser_Recursive, + RomBrowser_Maximized, + + //Directory Info + Directory_LastSave, + Directory_RecentGameDirCount, + Directory_RecentGameDirIndex, + Directory_Game, + Directory_GameInitial, + Directory_GameSelected, + Directory_GameUseSelected, + Directory_Plugin, + Directory_PluginInitial, + Directory_PluginSelected, + Directory_PluginUseSelected, + Directory_SnapShot, + Directory_SnapShotInitial, + Directory_SnapShotSelected, + Directory_SnapShotUseSelected, + Directory_NativeSave, + Directory_NativeSaveInitial, + Directory_NativeSaveSelected, + Directory_NativeSaveUseSelected, + Directory_InstantSave, + Directory_InstantSaveInitial, + Directory_InstantSaveSelected, + Directory_InstantSaveUseSelected, + Directory_Texture, + Directory_TextureInitial, + Directory_TextureSelected, + Directory_TextureUseSelected, + + //File Info + File_RecentGameFileCount, + File_RecentGameFileIndex, + + //Debugger + Debugger_Enabled, + Debugger_ShowUnhandledMemory, + Debugger_ShowPifErrors, + Debugger_ShowCheckOpUsageErrors, + Debugger_GenerateLogFiles, + Debugger_ProfileCode, + Debugger_DisableGameFixes, + Debugger_AppLogLevel, + Debugger_AppLogFlush, + Debugger_GenerateDebugLog, + Debugger_ShowDListAListCount, + Debugger_ShowRecompMemSize, + + //Beta Information + Beta_IsBetaVersion, + Beta_UserName, + Beta_UserNameMD5, + Beta_EmailAddress, + Beta_EmailAddressMD5, + Beta_IsValidExe, + + //Plugins + Plugin_RSP_Current, + Plugin_RSP_CurVer, + Plugin_GFX_Current, + Plugin_GFX_CurVer, + Plugin_AUDIO_Current, + Plugin_AUDIO_CurVer, + Plugin_CONT_Current, + Plugin_CONT_CurVer, + Plugin_UseHleGfx, + Plugin_UseHleAudio, + + //Cheats + Cheat_Entry, + Cheat_Active, + Cheat_Extension, + Cheat_Notes, + Cheat_Options, + Cheat_Range, + Cheat_RangeNotes, + + FirstRSPDefaultSet, LastRSPDefaultSet = FirstRSPDefaultSet + MaxPluginSetting, + FirstRSPSettings, LastRSPSettings = FirstRSPSettings + MaxPluginSetting, + FirstGfxDefaultSet, LastGfxDefaultSet = FirstGfxDefaultSet + MaxPluginSetting, + FirstGfxSettings, LastGfxSettings = FirstGfxSettings + MaxPluginSetting, + FirstAudioDefaultSet, LastAudioDefaultSet = FirstAudioDefaultSet + MaxPluginSetting, + FirstAudioSettings, LastAudioSettings = FirstAudioSettings + MaxPluginSetting, + FirstCtrlDefaultSet, LastCtrlDefaultSet = FirstCtrlDefaultSet + MaxPluginSetting, + FirstCtrlSettings, LastCtrlSettings = FirstCtrlSettings + MaxPluginSetting, + + +/* No_Default, Default_False, Default_True, Default_Language, Default_RdramSize, Default_RomStatus,Default_RomBrowserWidth,Default_RomBrowserHeight, Default_RememberedRomFiles, Default_RememberedRomDirs, Default_CheatExt, Default_SelfModCheck, Default_BlockLinking, Default_SaveSlot, Default_FunctionLookup, @@ -36,6 +243,7 @@ enum SettingID { LimitFPS, AlwaysOnTop, GenerateDebugLog, UseHighLevelGfx, UseHighLevelAudio, DisableGameFixes, AppLogLevel, AppLogFlush, DisplayFrameRate, FrameDisplayType, + //Debugger Debugger, ShowUnhandledMemory, ShowPifErrors, ShowDListAListCount, ShowCheckOpUsageErrors, ShowRecompMemSize, ShowPifRamErrors, @@ -79,12 +287,18 @@ enum SettingID { CheatActive, LastCheatActive = CheatActive + MaxCheats, CheatExtension, LastCheatExtension = CheatExtension + MaxCheats, - //Idvidual Game Settings + //Individual Game Settings + Game_SaveChip, Game_LastSaveSlot, + //RDB Settings + Rdb_SaveChip, + + //Default Values + System_SaveChip, + //Rom Settings Default_CPUType, - Default_SaveChip, Default_CFactor, ROM_IniKey, ROM_NAME, @@ -99,7 +313,6 @@ enum SettingID { ROM_Status, ROM_CoreNotes, ROM_PluginNotes, - ROM_SaveChip, ROM_CounterFactor, ROM_CustomSMM, ROM_SMM_Cache, @@ -141,7 +354,6 @@ enum SettingID { CPUType, //DWORD - Current CPU CPU_Paused, //bool - Is CPU Paused CPU_Paused_type, //DWORD - What type of pause is it - SaveChipType, //DWORD - Current Save Type SMM_ChangeMemory, SMM_CheckMemory2, SMM_CheckMemoryCache, @@ -170,6 +382,7 @@ enum SettingID { SMM_ValidFunc, //bool - Self mod method (Compare memory contents of function on finding) SMM_Protect, //bool - Self mod method (Protect Memory from any write to the code pages) SMM_TLB, //bool - Self mod method (clear code on TLB unmapping) +*/ }; #include "Support.h" diff --git a/Source/Project64/Settings/Gui Settings.cpp b/Source/Project64/Settings/Gui Settings.cpp index 0239f1c7e..900b148e3 100644 --- a/Source/Project64/Settings/Gui Settings.cpp +++ b/Source/Project64/Settings/Gui Settings.cpp @@ -1,34 +1,25 @@ #include "..\support.h" #include "..\Settings.h" -bool CGuiSettings::bCPURunning; -bool CGuiSettings::bAutoSleep; +bool CGuiSettings::m_bCPURunning; +bool CGuiSettings::m_bAutoSleep; CGuiSettings::CGuiSettings() { RefreshSettings(); - _Settings->RegisterChangeCB(CPU_Running,this,(CSettings::SettingChangedFunc)CPURunningChanged); - _Settings->RegisterChangeCB(AutoSleep,this,(CSettings::SettingChangedFunc)AutoSleepChanged); + _Settings->RegisterChangeCB(GameRunning_CPU_Running,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Setting_AutoSleep,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); } CGuiSettings::~CGuiSettings() { - _Settings->UnregisterChangeCB(CPU_Running,this,(CSettings::SettingChangedFunc)CPURunningChanged); - _Settings->UnregisterChangeCB(AutoSleep,this,(CSettings::SettingChangedFunc)AutoSleepChanged); + _Settings->UnregisterChangeCB(GameRunning_CPU_Running,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Setting_AutoSleep,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); } void CGuiSettings::RefreshSettings() { - bCPURunning = _Settings->LoadBool(CPU_Running); - bAutoSleep = _Settings->LoadBool(AutoSleep); + m_bCPURunning = _Settings->LoadBool(GameRunning_CPU_Running); + m_bAutoSleep = _Settings->LoadBool(Setting_AutoSleep); } -void CGuiSettings::CPURunningChanged (CGuiSettings * _this) -{ - _this->bCPURunning = _Settings->LoadBool(CPU_Running); -} - -void CGuiSettings::AutoSleepChanged (CGuiSettings * _this) -{ - _this->bAutoSleep = _Settings->LoadBool(AutoSleep); -} diff --git a/Source/Project64/Settings/Gui Settings.h b/Source/Project64/Settings/Gui Settings.h index eb33a11fd..d6de04de5 100644 --- a/Source/Project64/Settings/Gui Settings.h +++ b/Source/Project64/Settings/Gui Settings.h @@ -2,15 +2,21 @@ class CGuiSettings { - static void CPURunningChanged (CGuiSettings * _this); - static void AutoSleepChanged (CGuiSettings * _this); + static void StaticRefreshSettings (CGuiSettings * _this) + { + _this->RefreshSettings(); + } + + void RefreshSettings ( void ); + + static bool m_bCPURunning; + static bool m_bAutoSleep; protected: CGuiSettings(); virtual ~CGuiSettings(); - void RefreshSettings ( void ); + static inline bool bCPURunning ( void) { return m_bCPURunning; } + static inline bool bAutoSleep ( void) { return m_bAutoSleep; } - static bool bCPURunning; - static bool bAutoSleep; }; \ No newline at end of file diff --git a/Source/Project64/Settings/N64System Settings.cpp b/Source/Project64/Settings/N64System Settings.cpp index c2f8ecde9..b51387130 100644 --- a/Source/Project64/Settings/N64System Settings.cpp +++ b/Source/Project64/Settings/N64System Settings.cpp @@ -1,75 +1,61 @@ #include "..\support.h" #include "..\Settings.h" -bool CN64SystemSettings::bShowCPUPer; //= _Settings->LoadDword(ShowCPUPer) != 0; -bool CN64SystemSettings::bProfiling; //= _Settings->LoadDword(ProfileCode) != 0; -bool CN64SystemSettings::bBasicMode; //= _Settings->LoadDword(BasicMode) != 0; -bool CN64SystemSettings::bLimitFPS; //= _Settings->LoadDword(LimitFPS) != 0; -bool CN64SystemSettings::bShowDListAListCount; //= _Settings->LoadDword(ShowDListAListCount) != 0; -bool CN64SystemSettings::bFixedAudio; //= _Settings->LoadDword(ROM_FixedAudio) != 0; -bool CN64SystemSettings::bSyncToAudio; //7= _Settings->LoadDword(SyncViaAudio) != 0; -bool CN64SystemSettings::bDisplayFrameRate; //7= _Settings->LoadDword(SyncViaAudio) != 0; -bool CN64SystemSettings::bCleanFrameBox = false; //7= _Settings->LoadDword(SyncViaAudio) != 0; +bool CN64SystemSettings::m_bShowCPUPer; +bool CN64SystemSettings::m_bProfiling; +bool CN64SystemSettings::m_bBasicMode; +bool CN64SystemSettings::m_bLimitFPS; +bool CN64SystemSettings::m_bShowDListAListCount; +bool CN64SystemSettings::m_bFixedAudio; +bool CN64SystemSettings::m_bSyncToAudio; +bool CN64SystemSettings::m_bDisplayFrameRate; +bool CN64SystemSettings::m_SPHack; + CN64SystemSettings::CN64SystemSettings() { - _Settings->RegisterChangeCB(ShowCPUPer,this,(CSettings::SettingChangedFunc)ShowCPUPerChanged); - _Settings->RegisterChangeCB(ProfileCode,this,(CSettings::SettingChangedFunc)ProfilingChanged); - _Settings->RegisterChangeCB(BasicMode,this,(CSettings::SettingChangedFunc)BasicModeChanged); - _Settings->RegisterChangeCB(LimitFPS,this,(CSettings::SettingChangedFunc)LimitFPSChanged); - _Settings->RegisterChangeCB(ShowDListAListCount,this,(CSettings::SettingChangedFunc)ShowDListAListCountChanged); - _Settings->RegisterChangeCB(DisplayFrameRate,this,(CSettings::SettingChangedFunc)DisplayFrameRateChanged); + _Settings->RegisterChangeCB(UserInterface_BasicMode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(UserInterface_ShowCPUPer,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(UserInterface_DisplayFrameRate,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + + _Settings->RegisterChangeCB(Debugger_ProfileCode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Debugger_ShowDListAListCount,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + + _Settings->RegisterChangeCB(GameRunning_LimitFPS,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + + _Settings->RegisterChangeCB(Game_FixedAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_SyncViaAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_SPHack,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); RefreshSettings(); } CN64SystemSettings::~CN64SystemSettings() { - _Settings->UnregisterChangeCB(ShowCPUPer,this,(CSettings::SettingChangedFunc)ShowCPUPerChanged); - _Settings->UnregisterChangeCB(ProfileCode,this,(CSettings::SettingChangedFunc)ProfilingChanged); - _Settings->UnregisterChangeCB(BasicMode,this,(CSettings::SettingChangedFunc)BasicModeChanged); - _Settings->UnregisterChangeCB(LimitFPS,this,(CSettings::SettingChangedFunc)LimitFPSChanged); - _Settings->UnregisterChangeCB(ShowDListAListCount,this,(CSettings::SettingChangedFunc)ShowDListAListCountChanged); - _Settings->UnregisterChangeCB(DisplayFrameRate,this,(CSettings::SettingChangedFunc)DisplayFrameRateChanged); + _Settings->UnregisterChangeCB(UserInterface_BasicMode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(UserInterface_DisplayFrameRate,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(UserInterface_ShowCPUPer,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + + _Settings->UnregisterChangeCB(Debugger_ProfileCode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Debugger_ShowDListAListCount,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + + _Settings->UnregisterChangeCB(GameRunning_LimitFPS,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + + _Settings->UnregisterChangeCB(Game_FixedAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_SyncViaAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_SPHack,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); } void CN64SystemSettings::RefreshSettings() { - bShowCPUPer = _Settings->LoadDword(ShowCPUPer) != 0; - bProfiling = _Settings->LoadDword(ProfileCode) != 0; - bBasicMode = _Settings->LoadDword(BasicMode) != 0; - bLimitFPS = _Settings->LoadDword(LimitFPS) != 0; - bShowDListAListCount = _Settings->LoadDword(ShowDListAListCount) != 0; - bFixedAudio = _Settings->LoadDword(ROM_FixedAudio) != 0; - bSyncToAudio = bFixedAudio ? _Settings->LoadDword(SyncViaAudio) != 0 : false; - bDisplayFrameRate = _Settings->LoadDword(DisplayFrameRate) != 0; -} + m_bBasicMode = _Settings->LoadBool(UserInterface_BasicMode); + m_bDisplayFrameRate = _Settings->LoadBool(UserInterface_DisplayFrameRate); -void CN64SystemSettings::ShowCPUPerChanged (CN64SystemSettings * _this) -{ - _this->bShowCPUPer = _Settings->LoadDword(ShowCPUPer) != 0; -} + m_bShowCPUPer = _Settings->LoadBool(UserInterface_ShowCPUPer); + m_bProfiling = _Settings->LoadBool(Debugger_ProfileCode); + m_bShowDListAListCount = _Settings->LoadBool(Debugger_ShowDListAListCount); + m_bLimitFPS = _Settings->LoadBool(GameRunning_LimitFPS); -void CN64SystemSettings::ProfilingChanged (CN64SystemSettings * _this) -{ - _this->bProfiling = _Settings->LoadDword(ProfileCode) != 0; -} - -void CN64SystemSettings::BasicModeChanged (CN64SystemSettings * _this) -{ - _this->bBasicMode = _Settings->LoadDword(BasicMode) != 0; -} - -void CN64SystemSettings::LimitFPSChanged (CN64SystemSettings * _this) -{ - _this->bLimitFPS = _Settings->LoadDword(LimitFPS) != 0; -} - -void CN64SystemSettings::ShowDListAListCountChanged (CN64SystemSettings * _this) -{ - _this->bShowDListAListCount = _Settings->LoadDword(ShowDListAListCount) != 0; -} - -void CN64SystemSettings::DisplayFrameRateChanged (CN64SystemSettings * _this) -{ - _this->bDisplayFrameRate = _Settings->LoadDword(DisplayFrameRate) != 0; + m_bFixedAudio = _Settings->LoadBool(Game_FixedAudio); + m_bSyncToAudio = m_bFixedAudio ? _Settings->LoadBool(Game_SyncViaAudio) : false; + m_SPHack = _Settings->LoadBool(Game_SPHack); } diff --git a/Source/Project64/Settings/N64System Settings.h b/Source/Project64/Settings/N64System Settings.h index 4c59d0935..843103343 100644 --- a/Source/Project64/Settings/N64System Settings.h +++ b/Source/Project64/Settings/N64System Settings.h @@ -2,27 +2,34 @@ class CN64SystemSettings { - static void ShowCPUPerChanged (CN64SystemSettings * _this); - static void ProfilingChanged (CN64SystemSettings * _this); - static void BasicModeChanged (CN64SystemSettings * _this); - static void LimitFPSChanged (CN64SystemSettings * _this); - static void ShowDListAListCountChanged (CN64SystemSettings * _this); - static void DisplayFrameRateChanged (CN64SystemSettings * _this); - static void FrameRateTypeChanged (CN64SystemSettings * _this); + static void StaticRefreshSettings (CN64SystemSettings * _this) + { + _this->RefreshSettings(); + } + + void RefreshSettings ( void ); + + static bool m_bShowCPUPer; + static bool m_bProfiling; + static bool m_bBasicMode; + static bool m_bLimitFPS; + static bool m_bShowDListAListCount; + static bool m_bFixedAudio; + static bool m_bSyncToAudio; + static bool m_bDisplayFrameRate; + static bool m_SPHack; protected: CN64SystemSettings(); virtual ~CN64SystemSettings(); - void RefreshSettings ( void ); - - static bool bShowCPUPer; - static bool bProfiling; - static bool bBasicMode; - static bool bLimitFPS; - static bool bShowDListAListCount; - static bool bFixedAudio; - static bool bSyncToAudio; - static bool bDisplayFrameRate; - static bool bCleanFrameBox; + inline bool bBasicMode ( void ) const { return m_bBasicMode; } + inline bool bDisplayFrameRate ( void ) const { return m_bDisplayFrameRate; } + inline bool bShowCPUPer ( void ) const { return m_bShowCPUPer; } + inline bool bProfiling ( void ) const { return m_bProfiling; } + inline bool bShowDListAListCount ( void ) const { return m_bShowDListAListCount; } + inline bool bLimitFPS ( void ) const { return m_bLimitFPS; } + inline bool bFixedAudio ( void ) const { return m_bFixedAudio; } + inline bool bSyncToAudio ( void ) const { return m_bSyncToAudio; } + inline bool bSPHack ( void ) const { return m_SPHack; } }; \ No newline at end of file diff --git a/Source/Project64/Settings/Notification Settings.cpp b/Source/Project64/Settings/Notification Settings.cpp index f8d67aeea..3c72f3b91 100644 --- a/Source/Project64/Settings/Notification Settings.cpp +++ b/Source/Project64/Settings/Notification Settings.cpp @@ -1,23 +1,23 @@ #include "..\Settings.h" #include "Notification Settings.h" -bool CNotificationSettings::bInFullScreen; //= _Settings->Load(InFullScreen) != 0; +bool CNotificationSettings::m_bInFullScreen = false; CNotificationSettings::CNotificationSettings() { - bInFullScreen = _Settings->LoadBool(InFullScreen); - _Settings->RegisterChangeCB(InFullScreen,this,(CSettings::SettingChangedFunc)InFullScreenChanged); + _Settings->RegisterChangeCB(UserInterface_InFullScreen,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + RefreshSettings(); } CNotificationSettings::~CNotificationSettings() { if (_Settings) { - _Settings->UnregisterChangeCB(InFullScreen,this,(CSettings::SettingChangedFunc)InFullScreenChanged); + _Settings->UnregisterChangeCB(UserInterface_InFullScreen,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); } } -void CNotificationSettings::InFullScreenChanged (CNotificationSettings * _this) +void CNotificationSettings::RefreshSettings() { - bInFullScreen = _Settings->LoadBool(InFullScreen); + m_bInFullScreen = _Settings->LoadBool(UserInterface_InFullScreen); } diff --git a/Source/Project64/Settings/Notification Settings.h b/Source/Project64/Settings/Notification Settings.h index 49de38f47..bf0b1d7d2 100644 --- a/Source/Project64/Settings/Notification Settings.h +++ b/Source/Project64/Settings/Notification Settings.h @@ -1,11 +1,17 @@ class CNotificationSettings { - static void InFullScreenChanged (CNotificationSettings * _this); + static void StaticRefreshSettings (CNotificationSettings * _this) + { + _this->RefreshSettings(); + } + + void RefreshSettings ( void ); + + static bool m_bInFullScreen; protected: CNotificationSettings(); virtual ~CNotificationSettings(); - //Settings that can be changed on the fly - static bool bInFullScreen; + inline bool InFullScreen ( void ) const { return m_bInFullScreen; } }; diff --git a/Source/Project64/Settings/Recompiler Settings.cpp b/Source/Project64/Settings/Recompiler Settings.cpp index 7662d40b2..0ca1d8c70 100644 --- a/Source/Project64/Settings/Recompiler Settings.cpp +++ b/Source/Project64/Settings/Recompiler Settings.cpp @@ -1,47 +1,66 @@ #pragma once #include "..\Settings.h" -bool CRecompilerSettings::bShowRecompMemSize; //= _Settings->LoadDword(ShowRecompMemSize) != 0; -bool CRecompilerSettings::bSMM_Protect; //= _Settings->LoadDword(SMM_Protect) != 0; -bool CRecompilerSettings::bSMM_ValidFunc; //= _Settings->LoadDword(SMM_ValidFunc) != 0; -bool CRecompilerSettings::bSMM_PIDMA; //= _Settings->LoadDword(SMM_PIDMA) != 0; -bool CRecompilerSettings::bSMM_TLB; //= _Settings->LoadDword(SMM_TLB) != 0; -bool CRecompilerSettings::bProfiling; //= _Settings->LoadDword(ProfileCode) != 0; -bool CRecompilerSettings::bRomInMemory; //= _Settings->LoadDword(ProfileCode) != 0; +bool CRecompilerSettings::m_bShowRecompMemSize; +bool CRecompilerSettings::m_bSMM_Protect; +bool CRecompilerSettings::m_bSMM_ValidFunc; +bool CRecompilerSettings::m_bSMM_PIDMA; +bool CRecompilerSettings::m_bSMM_TLB; +bool CRecompilerSettings::m_bProfiling; +bool CRecompilerSettings::m_bRomInMemory; +bool CRecompilerSettings::m_RegCaching; +bool CRecompilerSettings::m_bLinkBlocks; +DWORD CRecompilerSettings::m_RdramSize; +DWORD CRecompilerSettings::m_CountPerOp; +DWORD CRecompilerSettings::m_LookUpMode; //FUNC_LOOKUP_METHOD CRecompilerSettings::CRecompilerSettings() { - bShowRecompMemSize = _Settings->LoadDword(ShowRecompMemSize) != 0; - bSMM_Protect = _Settings->LoadDword(SMM_Protect) != 0; - bSMM_ValidFunc = _Settings->LoadDword(SMM_ValidFunc) != 0; - bSMM_PIDMA = _Settings->LoadDword(SMM_PIDMA) != 0; - bSMM_TLB = _Settings->LoadDword(SMM_TLB) != 0; - bProfiling = _Settings->LoadDword(ProfileCode) != 0; - bRomInMemory = _Settings->LoadDword(RomInMemory) != 0; - _Settings->RegisterChangeCB(ShowRecompMemSize,this,(CSettings::SettingChangedFunc)ShowRecompMemSizeChanged); - _Settings->RegisterChangeCB(ProfileCode,this,(CSettings::SettingChangedFunc)ProfilingChanged); - _Settings->RegisterChangeCB(RomInMemory,this,(CSettings::SettingChangedFunc)RomInMemoryChanged); + _Settings->RegisterChangeCB(Game_SMM_Protect,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_SMM_ValidFunc,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_SMM_PIDMA,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_SMM_TLB,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_RegCache,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_BlockLinking,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_RDRamSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_CounterFactor,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_FuncLookupMode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Debugger_ShowRecompMemSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Debugger_ProfileCode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_LoadRomToMemory,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + + RefreshSettings(); } CRecompilerSettings::~CRecompilerSettings() { - _Settings->UnregisterChangeCB(ShowRecompMemSize,this,(CSettings::SettingChangedFunc)ShowRecompMemSizeChanged); - _Settings->UnregisterChangeCB(ProfileCode,this,(CSettings::SettingChangedFunc)ProfilingChanged); - _Settings->UnregisterChangeCB(RomInMemory,this,(CSettings::SettingChangedFunc)RomInMemoryChanged); + _Settings->UnregisterChangeCB(Game_SMM_Protect,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_SMM_ValidFunc,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_SMM_PIDMA,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_SMM_TLB,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_RegCache,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_BlockLinking,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_RDRamSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_CounterFactor,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_FuncLookupMode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Debugger_ShowRecompMemSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Debugger_ProfileCode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_LoadRomToMemory,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); } -void CRecompilerSettings::ShowRecompMemSizeChanged (CRecompilerSettings * _this) +void CRecompilerSettings::RefreshSettings() { - _this->bShowRecompMemSize = _Settings->LoadDword(ShowRecompMemSize) != 0; -} + m_bSMM_Protect = _Settings->LoadBool(Game_SMM_Protect); + m_bSMM_ValidFunc = _Settings->LoadBool(Game_SMM_ValidFunc); + m_bSMM_PIDMA = _Settings->LoadBool(Game_SMM_PIDMA); + m_bSMM_TLB = _Settings->LoadBool(Game_SMM_TLB); + m_bShowRecompMemSize = _Settings->LoadBool(Debugger_ShowRecompMemSize); + m_bProfiling = _Settings->LoadBool(Debugger_ProfileCode); + m_bRomInMemory = _Settings->LoadBool(Game_LoadRomToMemory); - -void CRecompilerSettings::ProfilingChanged (CRecompilerSettings * _this) -{ - _this->bProfiling = _Settings->LoadDword(ProfileCode) != 0; -} - -void CRecompilerSettings::RomInMemoryChanged (CRecompilerSettings * _this) -{ - _this->bRomInMemory = _Settings->LoadDword(RomInMemory) != 0; + m_RegCaching = _Settings->LoadBool(Game_RegCache); + m_bLinkBlocks = _Settings->LoadBool(Game_BlockLinking); + m_RdramSize = _Settings->LoadDword(Game_RDRamSize); + m_CountPerOp = _Settings->LoadDword(Game_CounterFactor); + m_LookUpMode = _Settings->LoadDword(Game_FuncLookupMode); } diff --git a/Source/Project64/Settings/Recompiler Settings.h b/Source/Project64/Settings/Recompiler Settings.h index 6c4bd0fd4..7d4a80ddc 100644 --- a/Source/Project64/Settings/Recompiler Settings.h +++ b/Source/Project64/Settings/Recompiler Settings.h @@ -1,19 +1,44 @@ +#include + class CRecompilerSettings { - static void ShowRecompMemSizeChanged (CRecompilerSettings * _this); - static void RomInMemoryChanged (CRecompilerSettings * _this); - static void ProfilingChanged (CRecompilerSettings * _this); + static void StaticRefreshSettings (CRecompilerSettings * _this) + { + _this->RefreshSettings(); + } + + void RefreshSettings ( void ); + + + //Settings that can be changed on the fly + static bool m_bShowRecompMemSize; + static bool m_bSMM_Protect; + static bool m_bSMM_ValidFunc; + static bool m_bSMM_PIDMA; + static bool m_bSMM_TLB; + static bool m_bProfiling; + static bool m_bRomInMemory; + + static bool m_RegCaching; + static bool m_bLinkBlocks; + static DWORD m_RdramSize; + static DWORD m_CountPerOp; + static DWORD m_LookUpMode; //FUNC_LOOKUP_METHOD public: CRecompilerSettings(); virtual ~CRecompilerSettings(); - //Settings that can be changed on the fly - static bool bShowRecompMemSize; - static bool bSMM_Protect; - static bool bSMM_ValidFunc; - static bool bSMM_PIDMA; - static bool bSMM_TLB; - static bool bProfiling; - static bool bRomInMemory; + inline bool bShowRecompMemSize ( void ) const { return m_bShowRecompMemSize; } + inline bool bSMM_Protect ( void ) const { return m_bSMM_Protect; } + inline bool bSMM_ValidFunc ( void ) const { return m_bSMM_ValidFunc; } + inline bool bSMM_PIDMA ( void ) const { return m_bSMM_PIDMA; } + inline bool bSMM_TLB ( void ) const { return m_bSMM_TLB; } + inline bool bProfiling ( void ) const { return m_bProfiling; } + inline bool bRomInMemory ( void ) const { return m_bRomInMemory; } + inline bool bRegCaching ( void ) const { return m_RegCaching; } + inline bool bLinkBlocks ( void ) const { return m_bLinkBlocks; } + inline DWORD RdramSize ( void ) const { return m_RdramSize; } + inline DWORD CountPerOp ( void ) const { return m_CountPerOp; } + inline FUNC_LOOKUP_METHOD LookUpMode ( void ) const { return (FUNC_LOOKUP_METHOD)m_LookUpMode; } }; \ No newline at end of file diff --git a/Source/Project64/Settings/SettingType/SettingsType-Application.cpp b/Source/Project64/Settings/SettingType/SettingsType-Application.cpp index 15020d1d2..ac81d89ae 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-Application.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-Application.cpp @@ -10,7 +10,7 @@ CSettingTypeApplication::CSettingTypeApplication(LPCSTR Section, LPCSTR Name, DW m_KeyName(Name), m_DefaultStr(""), m_DefaultValue(DefaultValue), - m_DefaultSetting(No_Default), + m_DefaultSetting(Default_Constant), m_KeyNameIdex(m_KeyName) { } @@ -20,7 +20,7 @@ CSettingTypeApplication::CSettingTypeApplication(LPCSTR Section, LPCSTR Name, bo m_KeyName(Name), m_DefaultStr(""), m_DefaultValue(DefaultValue), - m_DefaultSetting(No_Default), + m_DefaultSetting(Default_Constant), m_KeyNameIdex(m_KeyName) { } @@ -30,7 +30,7 @@ CSettingTypeApplication::CSettingTypeApplication(LPCSTR Section, LPCSTR Name, LP m_KeyName(Name), m_DefaultStr(DefaultValue), m_DefaultValue(0), - m_DefaultSetting(No_Default), + m_DefaultSetting(Default_Constant), m_KeyNameIdex(m_KeyName) { } @@ -52,8 +52,9 @@ CSettingTypeApplication::~CSettingTypeApplication() void CSettingTypeApplication::Initilize( const char * AppName ) { - m_SettingsIniFile = new CIniFile(_Settings->LoadString(SettingsIniName).c_str()); - m_UseRegistry = _Settings->LoadBool(UseSettingFromRegistry); + m_SettingsIniFile = new CIniFile(_Settings->LoadString(SupportFile_Settings).c_str()); + m_SettingsIniFile->SetAutoFlush(false); + m_UseRegistry = _Settings->LoadBool(Setting_UseFromRegistry); } @@ -61,6 +62,7 @@ void CSettingTypeApplication::CleanUp() { if (m_SettingsIniFile) { + m_SettingsIniFile->SetAutoFlush(true); delete m_SettingsIniFile; m_SettingsIniFile = NULL; } @@ -68,15 +70,30 @@ void CSettingTypeApplication::CleanUp() bool CSettingTypeApplication::Load ( int Index, bool & Value ) const { + bool bRes = false; + if (!m_UseRegistry) { DWORD dwValue; - bool bRes = m_SettingsIniFile->GetNumber(m_Section.c_str(),m_KeyNameIdex.c_str(),m_DefaultValue,dwValue); - Value = dwValue != 0; - return bRes; + bRes = m_SettingsIniFile->GetNumber(SectionName(),m_KeyNameIdex.c_str(),Value,dwValue); + if (bRes) + { + Value = dwValue != 0; + } + } else { + Notify().BreakPoint(__FILE__,__LINE__); } - Notify().BreakPoint(__FILE__,__LINE__); - return false; + + if (!bRes && m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } else { + _Settings->LoadBool(m_DefaultSetting,Value); + } + } + return bRes; } bool CSettingTypeApplication::Load ( int Index, ULONG & Value ) const @@ -84,45 +101,99 @@ bool CSettingTypeApplication::Load ( int Index, ULONG & Value ) const bool bRes; if (!m_UseRegistry) { - bRes = m_SettingsIniFile->GetNumber(m_Section.c_str(),m_KeyNameIdex.c_str(),m_DefaultValue,Value); + bRes = m_SettingsIniFile->GetNumber(SectionName(),m_KeyNameIdex.c_str(),Value,Value); } else { Notify().BreakPoint(__FILE__,__LINE__); } - if (!bRes && m_DefaultSetting != No_Default) + if (!bRes && m_DefaultSetting != Default_None) { - bRes = _Settings->LoadDword(m_DefaultSetting,Value); + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + _Settings->LoadDword(m_DefaultSetting,Value); + } } return bRes; } +LPCSTR CSettingTypeApplication::SectionName ( void ) const +{ + return m_Section.c_str(); +} + bool CSettingTypeApplication::Load ( int Index, stdstr & Value ) const { bool bRes; if (!m_UseRegistry) { - bRes = m_SettingsIniFile->GetString(m_Section.c_str(),m_KeyNameIdex.c_str(),m_DefaultStr,Value); + bRes = m_SettingsIniFile->GetString(SectionName(),m_KeyNameIdex.c_str(),m_DefaultStr,Value); } else { Notify().BreakPoint(__FILE__,__LINE__); } - if (!bRes && m_DefaultSetting != No_Default) + if (!bRes) { - bRes = _Settings->LoadString(m_DefaultSetting,Value); + CSettingTypeApplication::LoadDefault(Index,Value); } return bRes; } +//return the default values +void CSettingTypeApplication::LoadDefault ( int Index, bool & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } else { + _Settings->LoadBool(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeApplication::LoadDefault ( int Index, ULONG & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + _Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeApplication::LoadDefault ( int Index, stdstr & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultStr; + } else { + _Settings->LoadString(m_DefaultSetting,Value); + } + } +} //Update the settings void CSettingTypeApplication::Save ( int Index, bool Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + if (!m_UseRegistry) + { + m_SettingsIniFile->SaveNumber(SectionName(),m_KeyNameIdex.c_str(),Value); + } else { + Notify().BreakPoint(__FILE__,__LINE__); + } } void CSettingTypeApplication::Save ( int Index, ULONG Value ) { if (!m_UseRegistry) { - m_SettingsIniFile->SaveNumber(m_Section.c_str(),m_KeyNameIdex.c_str(),Value); + m_SettingsIniFile->SaveNumber(SectionName(),m_KeyNameIdex.c_str(),Value); } else { Notify().BreakPoint(__FILE__,__LINE__); } @@ -132,7 +203,7 @@ void CSettingTypeApplication::Save ( int Index, const stdstr & Value ) { if (!m_UseRegistry) { - m_SettingsIniFile->SaveString(m_Section.c_str(),m_KeyNameIdex.c_str(),Value.c_str()); + m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),Value.c_str()); } else { Notify().BreakPoint(__FILE__,__LINE__); } @@ -142,7 +213,7 @@ void CSettingTypeApplication::Save ( int Index, const char * Value ) { if (!m_UseRegistry) { - m_SettingsIniFile->SaveString(m_Section.c_str(),m_KeyNameIdex.c_str(),Value); + m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),Value); } else { Notify().BreakPoint(__FILE__,__LINE__); } @@ -162,3 +233,13 @@ stdstr CSettingTypeApplication::FixSectionName(LPCSTR Section) } return SectionName; } + +void CSettingTypeApplication::Delete( int Index ) +{ + if (!m_UseRegistry) + { + m_SettingsIniFile->SaveString(SectionName(),m_KeyNameIdex.c_str(),NULL); + } else { + Notify().BreakPoint(__FILE__,__LINE__); + } +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-Application.h b/Source/Project64/Settings/SettingType/SettingsType-Application.h index be2d13b3c..8c89e6c16 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-Application.h +++ b/Source/Project64/Settings/SettingType/SettingsType-Application.h @@ -4,19 +4,21 @@ class CSettingTypeApplication : public CSettingType { +protected: const LPCSTR m_DefaultStr; const DWORD m_DefaultValue; const SettingID m_DefaultSetting; stdstr FixSectionName (LPCSTR Section); -protected: static CIniFile * m_SettingsIniFile; static bool m_UseRegistry; const stdstr m_Section; - const LPCSTR m_KeyName; + const stdstr m_KeyName; mutable stdstr m_KeyNameIdex; + virtual LPCSTR SectionName ( void ) const; + public: CSettingTypeApplication(LPCSTR Section, LPCSTR Name, LPCSTR DefaultValue ); CSettingTypeApplication(LPCSTR Section, LPCSTR Name, bool DefaultValue ); @@ -24,19 +26,27 @@ public: CSettingTypeApplication(LPCSTR Section, LPCSTR Name, SettingID DefaultSetting ); ~CSettingTypeApplication(); - virtual bool IndexBasedSetting ( void ) const { return false; } - virtual SettingLocation GetSettingsLocation ( void ) const { return m_UseRegistry ? SettingLocation_Registry : SettingLocation_CfgFile; } + virtual bool IndexBasedSetting ( void ) const { return false; } + virtual SettingType GetSettingType ( void ) const { return m_UseRegistry ? SettingType_Registry : SettingType_CfgFile; } //return the values - virtual bool Load ( int Index, bool & Value ) const; - virtual bool Load ( int Index, ULONG & Value ) const; - virtual bool Load ( int Index, stdstr & Value ) const; + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; //Update the settings - virtual void Save ( int Index, bool Value ); - virtual void Save ( int Index, ULONG Value ); - virtual void Save ( int Index, const stdstr & Value ); - virtual void Save ( int Index, const char * Value ); + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); // Initilize this class to use ini or registry static void Initilize ( const char * AppName ); diff --git a/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.cpp b/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.cpp index 604c78613..749151c3e 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.cpp @@ -27,41 +27,68 @@ CSettingTypeApplicationIndex::CSettingTypeApplicationIndex(LPCSTR Section, LPCST bool CSettingTypeApplicationIndex::Load ( int Index, bool & Value ) const { - Notify().BreakPoint(__FILE__,__LINE__); - return false; + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + return CSettingTypeApplication::Load(0,Value); } bool CSettingTypeApplicationIndex::Load ( int Index, ULONG & Value ) const { - m_KeyNameIdex.Format("%s %d",m_KeyName,Index); + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); return CSettingTypeApplication::Load(0,Value); } bool CSettingTypeApplicationIndex::Load ( int Index, stdstr & Value ) const { - m_KeyNameIdex.Format("%s %d",m_KeyName,Index); + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); return CSettingTypeApplication::Load(0,Value); } +//return the default values +void CSettingTypeApplicationIndex::LoadDefault ( int Index, bool & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::LoadDefault(0,Value); +} + +void CSettingTypeApplicationIndex::LoadDefault ( int Index, ULONG & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::LoadDefault(0,Value); +} + +void CSettingTypeApplicationIndex::LoadDefault ( int Index, stdstr & Value ) const +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::LoadDefault(0,Value); +} + //Update the settings void CSettingTypeApplicationIndex::Save ( int Index, bool Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,Value); } void CSettingTypeApplicationIndex::Save ( int Index, ULONG Value ) { - m_KeyNameIdex.Format("%s %d",m_KeyName,Index); + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); CSettingTypeApplication::Save(0,Value); } void CSettingTypeApplicationIndex::Save ( int Index, const stdstr & Value ) { - m_KeyNameIdex.Format("%s %d",m_KeyName,Index); + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); CSettingTypeApplication::Save(0,Value); } void CSettingTypeApplicationIndex::Save ( int Index, const char * Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,Value); +} + +void CSettingTypeApplicationIndex::Delete ( int Index ) +{ + m_KeyNameIdex.Format("%s %d",m_KeyName.c_str(),Index); + CSettingTypeApplication::Save(0,(const char *)NULL); } diff --git a/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.h b/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.h index cc2834227..9a61c593f 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.h +++ b/Source/Project64/Settings/SettingType/SettingsType-ApplicationIndex.h @@ -18,10 +18,18 @@ public: virtual bool Load ( int Index, ULONG & Value ) const; virtual bool Load ( int Index, stdstr & Value ) const; + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + //Update the settings virtual void Save ( int Index, bool Value ); virtual void Save ( int Index, ULONG Value ); virtual void Save ( int Index, const stdstr & Value ); virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); }; diff --git a/Source/Project64/Settings/SettingType/SettingsType-Base.h b/Source/Project64/Settings/SettingType/SettingsType-Base.h index c002d7cef..fab2bba3f 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-Base.h +++ b/Source/Project64/Settings/SettingType/SettingsType-Base.h @@ -1,36 +1,46 @@ #pragma once -enum SettingLocation { - SettingLocation_ConstString = 0, - SettingLocation_ConstValue = 1, - SettingLocation_CfgFile = 2, - SettingLocation_Registry = 3, - SettingLocation_RelativePath = 4, - TemporarySetting = 5, - SettingLocation_RomDatabase = 6, - CheatSetting = 7, - SettingLocation_GameSetting = 8, - SettingLocation_BoolVariable = 9, - SettingLocation_NumberVariable = 10, - SettingLocation_StringVariable = 11, +enum SettingType { + SettingType_Unknown = -1, + SettingType_ConstString = 0, + SettingType_ConstValue = 1, + SettingType_CfgFile = 2, + SettingType_Registry = 3, + SettingType_RelativePath = 4, + TemporarySetting = 5, + SettingType_RomDatabase = 6, + SettingType_CheatSetting = 7, + SettingType_GameSetting = 8, + SettingType_BoolVariable = 9, + SettingType_NumberVariable = 10, + SettingType_StringVariable = 11, + SettingType_SelectedDirectory = 12, }; class CSettingType { public: - virtual SettingLocation GetSettingsLocation ( void ) const = 0; - virtual bool IndexBasedSetting ( void ) const = 0; + virtual SettingType GetSettingType ( void ) const = 0; + virtual bool IndexBasedSetting ( void ) const = 0; //return the values virtual bool Load ( int Index, bool & Value ) const = 0; virtual bool Load ( int Index, ULONG & Value ) const = 0; virtual bool Load ( int Index, stdstr & Value ) const = 0; + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const = 0; + virtual void LoadDefault ( int Index, ULONG & Value ) const = 0; + virtual void LoadDefault ( int Index, stdstr & Value ) const = 0; + //Update the settings virtual void Save ( int Index, bool Value ) = 0; virtual void Save ( int Index, ULONG Value ) = 0; virtual void Save ( int Index, const stdstr & Value ) = 0; virtual void Save ( int Index, const char * Value ) = 0; + // Delete the setting + virtual void Delete ( int Index ) = 0; + }; diff --git a/Source/Project64/Settings/SettingType/SettingsType-Cheats.cpp b/Source/Project64/Settings/SettingType/SettingsType-Cheats.cpp new file mode 100644 index 000000000..7a977649b --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-Cheats.cpp @@ -0,0 +1,114 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-Cheats.h" + +CIniFile * CSettingTypeCheats::m_CheatIniFile = NULL; +stdstr CSettingTypeCheats::m_SectionIdent; + +CSettingTypeCheats::CSettingTypeCheats(LPCSTR PostFix ) : + m_PostFix(PostFix) +{ +} + +void CSettingTypeCheats::Initilize ( void ) +{ + m_CheatIniFile = new CIniFile(_Settings->LoadString(SupportFile_Cheats).c_str()); + m_CheatIniFile->SetAutoFlush(false); + _Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged); + m_SectionIdent = _Settings->LoadString(Game_IniKey); + GameChanged(NULL); +} + +void CSettingTypeCheats::CleanUp ( void ) +{ + if (m_CheatIniFile) + { + m_CheatIniFile->SetAutoFlush(true); + delete m_CheatIniFile; + m_CheatIniFile = NULL; + } +} + +void CSettingTypeCheats::GameChanged ( void * /*Data */ ) +{ + m_SectionIdent = _Settings->LoadString(Game_IniKey); +} + + +/*stdstr CSettingTypeCheats::FixName ( LPCSTR Section, LPCSTR Name ) +{ +} + +LPCSTR CSettingTypeCheats::SectionName ( void ) const +{ + return ""; +} + +void CSettingTypeCheats::UpdateSettings ( void * ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +}*/ + +bool CSettingTypeCheats::Load ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeCheats::Load ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeCheats::Load ( int Index, stdstr & Value ) const +{ + if (m_CheatIniFile == NULL) + { + return false; + } + stdstr_f Key("Cheat%d%s",Index,m_PostFix); + return m_CheatIniFile->GetString(m_SectionIdent.c_str(),Key.c_str(),"",Value); +} + +//return the default values +void CSettingTypeCheats::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeCheats::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeCheats::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +//Update the settings +void CSettingTypeCheats::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeCheats::Save ( int Index, ULONG Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeCheats::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeCheats::Save ( int Index, const char * Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeCheats::Delete ( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-Cheats.h b/Source/Project64/Settings/SettingType/SettingsType-Cheats.h new file mode 100644 index 000000000..c8ea134f4 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-Cheats.h @@ -0,0 +1,55 @@ +#pragma once + +class CSettingTypeCheats : + public CSettingType +{ + +protected: + static CIniFile * m_CheatIniFile; + static stdstr m_SectionIdent; + const LPCSTR m_PostFix; +/* const LPCSTR m_DefaultStr; + const DWORD m_DefaultValue; + const SettingID m_DefaultSetting; + + stdstr FixSectionName (LPCSTR Section); + + static CIniFile * m_SettingsIniFile; + static bool m_UseRegistry; + const stdstr m_Section; + const stdstr m_KeyName; + + virtual LPCSTR SectionName ( void ) const;*/ + static void GameChanged ( void * /*Data */ ); + +public: + CSettingTypeCheats(LPCSTR PostFix ); + ~CSettingTypeCheats(); + + virtual bool IndexBasedSetting ( void ) const { return true; } + virtual SettingType GetSettingType ( void ) const { return SettingType_CheatSetting; } + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); + + // Initilize this class to use ini or registry + static void Initilize ( void ); + static void CleanUp ( void ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-GameSetting.cpp b/Source/Project64/Settings/SettingType/SettingsType-GameSetting.cpp index 392a74726..01059910d 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-GameSetting.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-GameSetting.cpp @@ -3,57 +3,220 @@ #include "SettingsType-Application.h" #include "SettingsType-GameSetting.h" +bool CSettingTypeGame::m_RdbEditor = false; +stdstr CSettingTypeGame::m_SectionIdent; + CSettingTypeGame::CSettingTypeGame(LPCSTR Section, LPCSTR Name, LPCSTR DefaultValue ) : - CSettingTypeApplication(Section,Name,DefaultValue) + CSettingTypeApplication("",FixName(Section,Name).c_str(),DefaultValue) { } CSettingTypeGame::CSettingTypeGame(LPCSTR Section, LPCSTR Name, DWORD DefaultValue ) : - CSettingTypeApplication(Section,Name,DefaultValue) + CSettingTypeApplication("",FixName(Section,Name).c_str(),DefaultValue) { } CSettingTypeGame::CSettingTypeGame(LPCSTR Section, LPCSTR Name, SettingID DefaultSetting ) : - CSettingTypeApplication(Section,Name,DefaultSetting) + CSettingTypeApplication("",FixName(Section,Name).c_str(),DefaultSetting) { } -bool CSettingTypeGame::Load ( bool & Value ) const +CSettingTypeGame::~CSettingTypeGame() { - Notify().BreakPoint(__FILE__,__LINE__); - return false; } -bool CSettingTypeGame::Load ( ULONG & Value ) const +void CSettingTypeGame::Initilize ( void ) { - Notify().BreakPoint(__FILE__,__LINE__); - return false; + UpdateSettings(NULL); + _Settings->RegisterChangeCB(Game_IniKey,NULL,UpdateSettings); } -bool CSettingTypeGame::Load ( stdstr & Value ) const +void CSettingTypeGame::CleanUp ( void ) { - Notify().BreakPoint(__FILE__,__LINE__); - return false; + _Settings->UnregisterChangeCB(Game_IniKey,NULL,UpdateSettings); } +stdstr CSettingTypeGame::FixName ( LPCSTR Section, LPCSTR Name ) +{ + stdstr FixedName; + if (Section !=- NULL && strlen(Section) > 0) + { + FixedName.Format("%s-%s",Section,Name); + } else { + FixedName.Format("%s",Name); + } + return FixedName; +} + +LPCSTR CSettingTypeGame::SectionName ( void ) const +{ + return m_SectionIdent.c_str(); +} + +void CSettingTypeGame::UpdateSettings ( void * /*Data */ ) +{ + m_RdbEditor = _Settings->LoadBool(Setting_RdbEditor); + stdstr SectionIdent = _Settings->LoadString(Game_IniKey); + + if (SectionIdent != m_SectionIdent) + { + m_SectionIdent = SectionIdent; + _Settings->SettingTypeChanged(SettingType_GameSetting); + _Settings->SettingTypeChanged(SettingType_RomDatabase); + } + +} + +bool CSettingTypeGame::Load ( int Index, bool & Value ) const +{ + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + return _Settings->LoadBoolIndex(m_DefaultSetting,Index,Value); + } else { + return _Settings->LoadBool(m_DefaultSetting,Value); + } + } + return CSettingTypeApplication::Load(Index,Value); +} + +bool CSettingTypeGame::Load ( int Index, ULONG & Value ) const +{ + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + return _Settings->LoadDwordIndex(m_DefaultSetting,Index,Value); + } else { + return _Settings->LoadDword(m_DefaultSetting,Value); + } + } + return CSettingTypeApplication::Load(Index,Value); +} + +bool CSettingTypeGame::Load ( int Index, stdstr & Value ) const +{ + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + return _Settings->LoadStringIndex(m_DefaultSetting,Index,Value); + } else { + return _Settings->LoadString(m_DefaultSetting,Value); + } + } + return CSettingTypeApplication::Load(Index,Value); +} + +//return the default values +void CSettingTypeGame::LoadDefault ( int Index, bool & Value ) const +{ + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + _Settings->LoadDefaultBoolIndex(m_DefaultSetting,Index,Value); + } else { + _Settings->LoadDefaultBool(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::LoadDefault(Index,Value); + } +} + +void CSettingTypeGame::LoadDefault ( int Index, ULONG & Value ) const +{ + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + _Settings->LoadDefaultDwordIndex(m_DefaultSetting,Index,Value); + } else { + _Settings->LoadDefaultDword(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::LoadDefault(Index,Value); + } +} + +void CSettingTypeGame::LoadDefault ( int Index, stdstr & Value ) const +{ + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + _Settings->LoadDefaultStringIndex(m_DefaultSetting,Index,Value); + } else { + _Settings->LoadDefaultString(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::Load(Index,Value); + } +} //Update the settings -void CSettingTypeGame::Save ( bool Value ) +void CSettingTypeGame::Save ( int Index, bool Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + _Settings->SaveBoolIndex(m_DefaultSetting,Index,Value); + } else { + _Settings->SaveBool(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::Save(Index,Value); + } } -void CSettingTypeGame::Save ( ULONG Value ) +void CSettingTypeGame::Save ( int Index, ULONG Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + _Settings->SaveDwordIndex(m_DefaultSetting,Index,Value); + } else { + _Settings->SaveDword(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::Save(Index,Value); + } } -void CSettingTypeGame::Save ( const stdstr & Value ) +void CSettingTypeGame::Save ( int Index, const stdstr & Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + Save(Index,Value.c_str()); } -void CSettingTypeGame::Save ( const char * Value ) +void CSettingTypeGame::Save ( int Index, const char * Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + _Settings->SaveStringIndex(m_DefaultSetting,Index,Value); + } else { + _Settings->SaveString(m_DefaultSetting,Value); + } + } else { + CSettingTypeApplication::Save(Index,Value); + } +} + +void CSettingTypeGame::Delete ( int Index ) +{ + if (m_RdbEditor && _Settings->GetSettingType(m_DefaultSetting) == SettingType_RomDatabase) + { + if (_Settings->IndexBasedSetting(m_DefaultSetting)) + { + _Settings->DeleteSettingIndex(m_DefaultSetting,Index); + } else { + _Settings->DeleteSetting(m_DefaultSetting); + } + } else { + CSettingTypeApplication::Delete(Index); + } } diff --git a/Source/Project64/Settings/SettingType/SettingsType-GameSetting.h b/Source/Project64/Settings/SettingType/SettingsType-GameSetting.h index 5a1b2002c..48f861d5e 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-GameSetting.h +++ b/Source/Project64/Settings/SettingType/SettingsType-GameSetting.h @@ -3,24 +3,44 @@ class CSettingTypeGame : public CSettingTypeApplication { +protected: + static bool m_RdbEditor; + static stdstr m_SectionIdent; + + static void UpdateSettings ( void * /*Data */ ); + static stdstr FixName ( LPCSTR Section, LPCSTR Name ); + + virtual LPCSTR SectionName ( void ) const; public: CSettingTypeGame(LPCSTR Section, LPCSTR Name, LPCSTR DefaultValue ); CSettingTypeGame(LPCSTR Section, LPCSTR Name, DWORD DefaultValue ); CSettingTypeGame(LPCSTR Section, LPCSTR Name, SettingID DefaultSetting ); - ~CSettingTypeGame(); + virtual ~CSettingTypeGame(); - SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_GameSetting; } + virtual bool IndexBasedSetting ( void ) const { return false; } + virtual SettingType GetSettingType ( void ) const { return SettingType_GameSetting; } + + static void Initilize ( void ); + static void CleanUp ( void ); //return the values - bool Load ( bool & Value ) const; - bool Load ( ULONG & Value ) const; - bool Load ( stdstr & Value ) const; + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; //Update the settings - void Save ( bool Value ); - void Save ( ULONG Value ); - void Save ( const stdstr & Value ); - void Save ( const char * Value ); + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); }; diff --git a/Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.cpp b/Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.cpp new file mode 100644 index 000000000..40c1972bc --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.cpp @@ -0,0 +1,93 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-Application.h" +#include "SettingsType-GameSetting.h" +#include "SettingsType-GameSettingIndex.h" + + +CSettingTypeGameIndex::CSettingTypeGameIndex(LPCSTR PreIndex, LPCSTR PostIndex, SettingID DefaultSetting ) : + CSettingTypeGame("","", DefaultSetting), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeGameIndex::CSettingTypeGameIndex(LPCSTR PreIndex, LPCSTR PostIndex, DWORD DefaultValue ) : + CSettingTypeGame("","", DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeGameIndex::CSettingTypeGameIndex(LPCSTR PreIndex, LPCSTR PostIndex, LPCSTR DefaultValue ) : + CSettingTypeGame("","", DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeGameIndex::~CSettingTypeGameIndex() +{ +} + +bool CSettingTypeGameIndex::Load ( int Index, bool & Value ) const +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + return CSettingTypeGame::Load(Index,Value); +} + +bool CSettingTypeGameIndex::Load ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeGameIndex::Load ( int Index, stdstr & Value ) const +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + return CSettingTypeGame::Load(0,Value); +} + +//return the default values +void CSettingTypeGameIndex::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeGameIndex::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeGameIndex::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +//Update the settings +void CSettingTypeGameIndex::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeGameIndex::Save ( int Index, ULONG Value ) +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeGame::Save(0,Value); +} + +void CSettingTypeGameIndex::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeGameIndex::Save ( int Index, const char * Value ) +{ + m_KeyNameIdex.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeGame::Save(0,Value); +} + +void CSettingTypeGameIndex::Delete ( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.h b/Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.h new file mode 100644 index 000000000..a55ec35c6 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-GameSettingIndex.h @@ -0,0 +1,36 @@ +#pragma once + +class CSettingTypeGameIndex : + public CSettingTypeGame +{ + stdstr m_PreIndex, m_PostIndex; + +public: + CSettingTypeGameIndex(LPCSTR PreIndex, LPCSTR PostIndex, LPCSTR DefaultValue ); + CSettingTypeGameIndex(LPCSTR PreIndex, LPCSTR PostIndex, DWORD DefaultValue ); + CSettingTypeGameIndex(LPCSTR PreIndex, LPCSTR PostIndex, SettingID DefaultSetting ); + ~CSettingTypeGameIndex(); + + virtual bool IndexBasedSetting ( void ) const { return true; } + virtual SettingType GetSettingType ( void ) const { return SettingType_GameSetting; } + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.cpp b/Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.cpp new file mode 100644 index 000000000..7d235dddf --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.cpp @@ -0,0 +1,109 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBCpuType.h" + +CSettingTypeRDBCpuType::CSettingTypeRDBCpuType(LPCSTR Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBCpuType::CSettingTypeRDBCpuType(LPCSTR Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + +CSettingTypeRDBCpuType::~CSettingTypeRDBCpuType() +{ +} + +bool CSettingTypeRDBCpuType::Load ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeRDBCpuType::Load ( int Index, ULONG & Value ) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent.c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); + if (!bRes) + { + LoadDefault(Index,Value); + return false; + } + LPCSTR String = strValue.c_str(); + + if (strcmp(String,"Interpreter") == 0) { Value = CPU_Interpreter; } + else if (strcmp(String,"Recompiler") == 0) { Value = CPU_Recompiler; } + else if (strcmp(String,"SyncCores") == 0) { Value = CPU_SyncCores; } + else { Notify().BreakPoint(__FILE__,__LINE__); } + + return true; +} + +bool CSettingTypeRDBCpuType::Load ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBCpuType::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBCpuType::LoadDefault ( int Index, ULONG & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + _Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRDBCpuType::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +//Update the settings +void CSettingTypeRDBCpuType::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBCpuType::Save ( int Index, ULONG Value ) +{ + + stdstr strValue; + switch (Value) + { + case CPU_Interpreter: strValue = "Interpreter"; break; + case CPU_Recompiler: strValue = "Recompiler"; break; + case CPU_SyncCores: strValue = "SyncCores"; break; + default: + Notify().BreakPoint(__FILE__,__LINE__); + } + m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),strValue.c_str()); +} + +void CSettingTypeRDBCpuType::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBCpuType::Save ( int Index, const char * Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBCpuType::Delete( int Index ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.h b/Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.h new file mode 100644 index 000000000..6c1e3a5ab --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBCpuType.h @@ -0,0 +1,31 @@ +#pragma once + +class CSettingTypeRDBCpuType : + public CSettingTypeRomDatabase +{ + +public: + CSettingTypeRDBCpuType(LPCSTR Name, SettingID DefaultSetting ); + CSettingTypeRDBCpuType(LPCSTR Name, int DefaultValue ); + ~CSettingTypeRDBCpuType(); + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.cpp b/Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.cpp new file mode 100644 index 000000000..61a5a36e9 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.cpp @@ -0,0 +1,99 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBOnOff.h" + +CSettingTypeRDBOnOff::CSettingTypeRDBOnOff(LPCSTR Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBOnOff::CSettingTypeRDBOnOff(LPCSTR Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + + CSettingTypeRDBOnOff::~CSettingTypeRDBOnOff() +{ +} + +bool CSettingTypeRDBOnOff::Load ( int Index, bool & Value ) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent.c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); + if (!bRes) + { + LoadDefault(Index,Value); + return false; + } + LPCSTR String = strValue.c_str(); + + if (strcmp(String,"On") == 0) { Value = true; } + else if (strcmp(String,"Off") == 0) { Value = false; } + else if (strcmp(String,"Global") == 0) + { + LoadDefault(Index,Value); + return false; + } + else { Notify().BreakPoint(__FILE__,__LINE__); } + + return true; +} + +bool CSettingTypeRDBOnOff::Load ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeRDBOnOff::Load ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBOnOff::LoadDefault ( int Index, bool & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } else { + _Settings->LoadBool(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRDBOnOff::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBOnOff::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + + +//Update the settings +void CSettingTypeRDBOnOff::Save ( int Index, bool Value ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),Value? "On" : "Off"); +} + +void CSettingTypeRDBOnOff::Save ( int Index, ULONG Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBOnOff::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBOnOff::Save ( int Index, const char * Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.h b/Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.h new file mode 100644 index 000000000..352590f67 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBOnOff.h @@ -0,0 +1,28 @@ +#pragma once + +class CSettingTypeRDBOnOff : + public CSettingTypeRomDatabase +{ + +public: + CSettingTypeRDBOnOff(LPCSTR Name, SettingID DefaultSetting ); + CSettingTypeRDBOnOff(LPCSTR Name, int DefaultValue ); + ~CSettingTypeRDBOnOff(); + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.cpp b/Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.cpp new file mode 100644 index 000000000..d79d39f70 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.cpp @@ -0,0 +1,91 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBRamSize.h" + +// == 8 ? 0x800000 : 0x400000 + +CSettingTypeRDBRDRamSize::CSettingTypeRDBRDRamSize(LPCSTR Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBRDRamSize::CSettingTypeRDBRDRamSize(LPCSTR Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + +CSettingTypeRDBRDRamSize::~CSettingTypeRDBRDRamSize() +{ +} + +bool CSettingTypeRDBRDRamSize::Load ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeRDBRDRamSize::Load ( int Index, ULONG & Value ) const +{ + ULONG ulValue; + bool bRes = m_SettingsIniFile->GetNumber(m_SectionIdent.c_str(),m_KeyName.c_str(),m_DefaultValue,ulValue); + if (!bRes) + { + LoadDefault(Index,ulValue); + } + Value = 0x400000; + if (ulValue == 8) + { + Value = 0x800000; + } + return bRes; +} + +bool CSettingTypeRDBRDRamSize::Load ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBRDRamSize::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBRDRamSize::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBRDRamSize::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +//Update the settings +void CSettingTypeRDBRDRamSize::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBRDRamSize::Save ( int Index, ULONG Value ) +{ + + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBRDRamSize::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBRDRamSize::Save ( int Index, const char * Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBRDRamSize::Delete( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.h b/Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.h new file mode 100644 index 000000000..295534eec --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBRamSize.h @@ -0,0 +1,31 @@ +#pragma once + +class CSettingTypeRDBRDRamSize : + public CSettingTypeRomDatabase +{ + +public: + CSettingTypeRDBRDRamSize(LPCSTR Name, SettingID DefaultSetting ); + CSettingTypeRDBRDRamSize(LPCSTR Name, int DefaultValue ); + ~CSettingTypeRDBRDRamSize(); + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.cpp b/Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.cpp new file mode 100644 index 000000000..6e333ff7f --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.cpp @@ -0,0 +1,110 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBSaveChip.h" + +CSettingTypeRDBSaveChip::CSettingTypeRDBSaveChip(LPCSTR Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBSaveChip::CSettingTypeRDBSaveChip(LPCSTR Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + + CSettingTypeRDBSaveChip::~CSettingTypeRDBSaveChip() +{ +} + +bool CSettingTypeRDBSaveChip::Load ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeRDBSaveChip::Load ( int Index, ULONG & Value ) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent.c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); + if (!bRes) + { + LoadDefault(Index,Value); + return false; + } + LPCSTR String = strValue.c_str(); + + if (strcmp(String,"First Save Type") == 0) { Value = SaveChip_Auto; } + else if (strcmp(String,"4kbit Eeprom") == 0) { Value = SaveChip_Eeprom_4K; } + else if (strcmp(String,"16kbit Eeprom") == 0) { Value = SaveChip_Eeprom_16K; } + else if (strcmp(String,"Sram") == 0) { Value = SaveChip_Sram; } + else if (strcmp(String,"FlashRam") == 0) { Value = SaveChip_FlashRam; } + else { Notify().BreakPoint(__FILE__,__LINE__); } + + return true; +} + +bool CSettingTypeRDBSaveChip::Load ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBSaveChip::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBSaveChip::LoadDefault ( int Index, ULONG & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + _Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRDBSaveChip::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +//Update the settings +void CSettingTypeRDBSaveChip::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBSaveChip::Save ( int Index, ULONG Value ) +{ + switch (Value) + { + case SaveChip_Auto: m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),"First Save Type"); break; + case SaveChip_Eeprom_4K: m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),"4kbit Eeprom"); break; + case SaveChip_Eeprom_16K: m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),"16kbit Eeprom"); break; + case SaveChip_Sram: m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),"Sram"); break; + case SaveChip_FlashRam: m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),"FlashRam"); break; + default: + Notify().BreakPoint(__FILE__,__LINE__); + } +} + +void CSettingTypeRDBSaveChip::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBSaveChip::Save ( int Index, const char * Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBSaveChip::Delete( int Index ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.h b/Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.h new file mode 100644 index 000000000..6f785eda5 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBSaveChip.h @@ -0,0 +1,31 @@ +#pragma once + +class CSettingTypeRDBSaveChip : + public CSettingTypeRomDatabase +{ + +public: + CSettingTypeRDBSaveChip(LPCSTR Name, SettingID DefaultSetting ); + CSettingTypeRDBSaveChip(LPCSTR Name, int DefaultValue ); + ~CSettingTypeRDBSaveChip(); + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.cpp b/Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.cpp new file mode 100644 index 000000000..c4f4c2535 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.cpp @@ -0,0 +1,94 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RDBYesNo.h" + +CSettingTypeRDBYesNo::CSettingTypeRDBYesNo(LPCSTR Name, SettingID DefaultSetting ) : + CSettingTypeRomDatabase(Name,DefaultSetting) +{ +} + +CSettingTypeRDBYesNo::CSettingTypeRDBYesNo(LPCSTR Name, int DefaultValue ) : + CSettingTypeRomDatabase(Name,DefaultValue) +{ +} + + CSettingTypeRDBYesNo::~CSettingTypeRDBYesNo() +{ +} + +bool CSettingTypeRDBYesNo::Load ( int Index, bool & Value ) const +{ + stdstr strValue; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent.c_str(),m_KeyName.c_str(),m_DefaultStr,strValue); + if (!bRes) + { + LoadDefault(Index,Value); + return false; + } + LPCSTR String = strValue.c_str(); + + if (strcmp(String,"Yes") == 0) { Value = true; } + else if (strcmp(String,"No") == 0) { Value = false; } + else { Notify().BreakPoint(__FILE__,__LINE__); } + + return true; +} + +bool CSettingTypeRDBYesNo::Load ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeRDBYesNo::Load ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +//return the default values +void CSettingTypeRDBYesNo::LoadDefault ( int Index, bool & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } else { + _Settings->LoadBool(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRDBYesNo::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBYesNo::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + + +//Update the settings +void CSettingTypeRDBYesNo::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBYesNo::Save ( int Index, ULONG Value ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),Value? "Yes" : "No"); +} + +void CSettingTypeRDBYesNo::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRDBYesNo::Save ( int Index, const char * Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.h b/Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.h new file mode 100644 index 000000000..ac6a2bf20 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RDBYesNo.h @@ -0,0 +1,28 @@ +#pragma once + +class CSettingTypeRDBYesNo : + public CSettingTypeRomDatabase +{ + +public: + CSettingTypeRDBYesNo(LPCSTR Name, SettingID DefaultSetting ); + CSettingTypeRDBYesNo(LPCSTR Name, int DefaultValue ); + ~CSettingTypeRDBYesNo(); + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-RelativePath.cpp b/Source/Project64/Settings/SettingType/SettingsType-RelativePath.cpp index e1f7323fe..fb16ef863 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-RelativePath.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-RelativePath.cpp @@ -1,4 +1,5 @@ #include "..\..\Settings.h" +#include "..\..\User Interface.h" #include "SettingsType-RelativePath.h" CSettingTypeRelativePath::CSettingTypeRelativePath(LPCSTR Path, LPCSTR FileName) @@ -13,6 +14,32 @@ bool CSettingTypeRelativePath::Load ( int Index, stdstr & value ) const return true; } +//return the default values +void CSettingTypeRelativePath::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRelativePath::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRelativePath::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRelativePath::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRelativePath::Save ( int Index, ULONG Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + void CSettingTypeRelativePath::Save ( int Index, const stdstr & Value ) { m_FileName = CPath(CPath::MODULE_DIRECTORY,Value); @@ -23,4 +50,7 @@ void CSettingTypeRelativePath::Save ( int Index, const char * Value ) m_FileName = CPath(CPath::MODULE_DIRECTORY,Value); } - +void CSettingTypeRelativePath::Delete ( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RelativePath.h b/Source/Project64/Settings/SettingType/SettingsType-RelativePath.h index 359ab13fa..088e8d260 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-RelativePath.h +++ b/Source/Project64/Settings/SettingType/SettingsType-RelativePath.h @@ -9,19 +9,26 @@ public: CSettingTypeRelativePath(LPCSTR Path, LPCSTR FileName); ~CSettingTypeRelativePath(); - bool IndexBasedSetting ( void ) const { return false; } - SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_RelativePath; } + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_RelativePath; } //return the values - bool Load ( int Index, bool & Value ) const { return false; }; - bool Load ( int Index, ULONG & Value ) const { return false; }; - bool Load ( int Index, stdstr & Value ) const; + bool Load ( int Index, bool & Value ) const { return false; }; + bool Load ( int Index, ULONG & Value ) const { return false; }; + bool Load ( int Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int Index, bool & Value ) const; + void LoadDefault ( int Index, ULONG & Value ) const; + void LoadDefault ( int Index, stdstr & Value ) const; //Update the settings - void Save ( int Index, bool Value ) {}; - void Save ( int Index, ULONG Value ) {}; - void Save ( int Index, const stdstr & Value ); - void Save ( int Index, const char * Value ); + void Save ( int Index, bool Value ); + void Save ( int Index, ULONG Value ); + void Save ( int Index, const stdstr & Value ); + void Save ( int Index, const char * Value ); + // Delete the setting + void Delete ( int Index ); }; diff --git a/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.cpp b/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.cpp index c3aab7777..2237a2679 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.cpp @@ -9,7 +9,7 @@ CSettingTypeRomDatabase::CSettingTypeRomDatabase(LPCSTR Name, int DefaultValue ) m_KeyName(Name), m_DefaultStr(""), m_DefaultValue(DefaultValue), - m_DefaultSetting(No_Default) + m_DefaultSetting(Default_Constant) { } @@ -17,7 +17,7 @@ CSettingTypeRomDatabase::CSettingTypeRomDatabase(LPCSTR Name, bool DefaultValue m_KeyName(Name), m_DefaultStr(""), m_DefaultValue(DefaultValue), - m_DefaultSetting(No_Default) + m_DefaultSetting(Default_Constant) { } @@ -25,7 +25,7 @@ CSettingTypeRomDatabase::CSettingTypeRomDatabase(LPCSTR Name, LPCSTR DefaultValu m_KeyName(Name), m_DefaultStr(DefaultValue), m_DefaultValue(0), - m_DefaultSetting(No_Default) + m_DefaultSetting(Default_Constant) { } @@ -37,18 +37,22 @@ CSettingTypeRomDatabase::CSettingTypeRomDatabase(LPCSTR Name, SettingID DefaultS { } +CSettingTypeRomDatabase::~CSettingTypeRomDatabase() +{ +} void CSettingTypeRomDatabase::Initilize( void ) { - m_SettingsIniFile = new CIniFile(_Settings->LoadString(RomDatabaseFile).c_str()); + m_SettingsIniFile = new CIniFile(_Settings->LoadString(SupportFile_RomDatabase).c_str()); - _Settings->RegisterChangeCB(ROM_IniKey,NULL,GameChanged); + _Settings->RegisterChangeCB(Game_IniKey,NULL,GameChanged); - m_SectionIdent = _Settings->LoadString(ROM_IniKey); + m_SectionIdent = _Settings->LoadString(Game_IniKey); } void CSettingTypeRomDatabase::CleanUp( void ) { + _Settings->UnregisterChangeCB(Game_IniKey,NULL,GameChanged); if (m_SettingsIniFile) { delete m_SettingsIniFile; @@ -58,45 +62,93 @@ void CSettingTypeRomDatabase::CleanUp( void ) void CSettingTypeRomDatabase::GameChanged ( void * /*Data */ ) { - m_SectionIdent = _Settings->LoadString(ROM_IniKey); + m_SectionIdent = _Settings->LoadString(Game_IniKey); } bool CSettingTypeRomDatabase::Load ( int Index, bool & Value ) const { - Notify().BreakPoint(__FILE__,__LINE__); - return false; + DWORD temp_value = Value; + bool bRes = Load(Index,temp_value); + Value = temp_value != 0; + return bRes; } bool CSettingTypeRomDatabase::Load ( int Index, ULONG & Value ) const { - if (m_SectionIdent.empty()) + bool bRes = m_SettingsIniFile->GetNumber(m_SectionIdent.c_str(),m_KeyName.c_str(),Value,Value); + if (!bRes) { - return false; + LoadDefault(Index,Value); } - Notify().BreakPoint(__FILE__,__LINE__); - return false; + return bRes; } bool CSettingTypeRomDatabase::Load ( int Index, stdstr & Value ) const { - bool bRes = m_SettingsIniFile->GetString(m_SectionIdent.c_str(),m_KeyName,m_DefaultStr,Value); - if (!bRes && m_DefaultSetting != No_Default) + stdstr temp_value; + bool bRes = m_SettingsIniFile->GetString(m_SectionIdent.c_str(),m_KeyName.c_str(),m_DefaultStr,temp_value); + if (bRes) { - _Settings->LoadString(m_DefaultSetting,Value); + Value = temp_value; + } + else + { + LoadDefault(Index,Value); } return bRes; } +//return the default values +void CSettingTypeRomDatabase::LoadDefault ( int Index, bool & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue != 0; + } else { + _Settings->LoadBool(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRomDatabase::LoadDefault ( int Index, ULONG & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultValue; + } else { + _Settings->LoadDword(m_DefaultSetting,Value); + } + } +} + +void CSettingTypeRomDatabase::LoadDefault ( int Index, stdstr & Value ) const +{ + if (m_DefaultSetting != Default_None) + { + if (m_DefaultSetting == Default_Constant) + { + Value = m_DefaultStr; + } else { + _Settings->LoadString(m_DefaultSetting,Value); + } + } +} + + //Update the settings void CSettingTypeRomDatabase::Save ( int Index, bool Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + m_SettingsIniFile->SaveNumber(m_SectionIdent.c_str(),m_KeyName.c_str(),Value); } void CSettingTypeRomDatabase::Save ( int Index, ULONG Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + m_SettingsIniFile->SaveNumber(m_SectionIdent.c_str(),m_KeyName.c_str(),Value); } void CSettingTypeRomDatabase::Save ( int Index, const stdstr & Value ) @@ -108,3 +160,8 @@ void CSettingTypeRomDatabase::Save ( int Index, const char * Value ) { Notify().BreakPoint(__FILE__,__LINE__); } + +void CSettingTypeRomDatabase::Delete ( int Index ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.h b/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.h index c906ea707..97dde2b4f 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.h +++ b/Source/Project64/Settings/SettingType/SettingsType-RomDatabase.h @@ -3,16 +3,12 @@ class CSettingTypeRomDatabase : public CSettingType { - - const LPCSTR m_KeyName; +protected: + mutable stdstr m_KeyName; const LPCSTR m_DefaultStr; const int m_DefaultValue; const SettingID m_DefaultSetting; - /* - static bool m_UseRegistry; - stdstr m_SectionIdent;*/ - static stdstr m_SectionIdent; static CIniFile * m_SettingsIniFile; @@ -23,21 +19,30 @@ public: CSettingTypeRomDatabase(LPCSTR Name, bool DefaultValue ); CSettingTypeRomDatabase(LPCSTR Name, int DefaultValue ); CSettingTypeRomDatabase(LPCSTR Name, SettingID DefaultSetting ); - ~CSettingTypeRomDatabase(); + + virtual ~CSettingTypeRomDatabase(); - virtual bool IndexBasedSetting ( void ) const { return false; } - virtual SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_RomDatabase; } + virtual bool IndexBasedSetting ( void ) const { return false; } + virtual SettingType GetSettingType ( void ) const { return SettingType_RomDatabase; } //return the values - virtual bool Load ( int Index, bool & Value ) const; - virtual bool Load ( int Index, ULONG & Value ) const; - virtual bool Load ( int Index, stdstr & Value ) const; + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; //Update the settings - virtual void Save ( int Index, bool Value ); - virtual void Save ( int Index, ULONG Value ); - virtual void Save ( int Index, const stdstr & Value ); - virtual void Save ( int Index, const char * Value ); + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); static void Initilize ( void ); static void CleanUp ( void ); diff --git a/Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp b/Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp new file mode 100644 index 000000000..b62d8b4fe --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.cpp @@ -0,0 +1,97 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-RomDatabase.h" +#include "SettingsType-RomDatabaseIndex.h" + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, LPCSTR DefaultValue ) : + CSettingTypeRomDatabase("",DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, bool DefaultValue ) : + CSettingTypeRomDatabase("",DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, int DefaultValue ) : + CSettingTypeRomDatabase("",DefaultValue), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, SettingID DefaultSetting ) : + CSettingTypeRomDatabase("",DefaultSetting), + m_PreIndex(PreIndex), + m_PostIndex(PostIndex) +{ +} + +CSettingTypeRomDatabaseIndex::~CSettingTypeRomDatabaseIndex() +{ +} + +bool CSettingTypeRomDatabaseIndex::Load ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeRomDatabaseIndex::Load ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeRomDatabaseIndex::Load ( int Index, stdstr & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + return CSettingTypeRomDatabase::Load(0,Value); +} + +void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, bool & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeRomDatabase::LoadDefault(0,Value); +} + +void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, ULONG & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeRomDatabase::LoadDefault(0,Value); +} + +void CSettingTypeRomDatabaseIndex::LoadDefault ( int Index, stdstr & Value ) const +{ + m_KeyName.Format("%s%d%s",m_PreIndex.c_str(),Index,m_PostIndex.c_str()); + CSettingTypeRomDatabase::LoadDefault(0,Value); +} + +void CSettingTypeRomDatabaseIndex::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRomDatabaseIndex::Save ( int Index, ULONG Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRomDatabaseIndex::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRomDatabaseIndex::Save ( int Index, const char * Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeRomDatabaseIndex::Delete ( int Index ) +{ + m_SettingsIniFile->SaveString(m_SectionIdent.c_str(),m_KeyName.c_str(),NULL); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.h b/Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.h new file mode 100644 index 000000000..d27df97a5 --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-RomDatabaseIndex.h @@ -0,0 +1,37 @@ +#pragma once + +class CSettingTypeRomDatabaseIndex : + public CSettingTypeRomDatabase +{ + stdstr m_PreIndex, m_PostIndex; + +public: + CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, LPCSTR DefaultValue ); + CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, bool DefaultValue ); + CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, int DefaultValue ); + CSettingTypeRomDatabaseIndex(LPCSTR PreIndex, LPCSTR PostIndex, SettingID DefaultSetting ); + + virtual ~CSettingTypeRomDatabaseIndex(); + + virtual bool IndexBasedSetting ( void ) const { return true; } + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.cpp b/Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.cpp new file mode 100644 index 000000000..915719e0c --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.cpp @@ -0,0 +1,77 @@ +#include "..\..\Settings.h" +#include "..\..\User Interface.h" +#include "SettingsType-SelectedDirectory.h" + + +CSettingTypeSelectedDirectory::CSettingTypeSelectedDirectory(SettingID InitialDir, SettingID SelectedDir, SettingID UseSelected ) : + m_InitialDir(InitialDir), + m_SelectedDir(SelectedDir), + m_UseSelected(UseSelected) +{ +} + + +CSettingTypeSelectedDirectory::~CSettingTypeSelectedDirectory() +{ +} + +bool CSettingTypeSelectedDirectory::Load ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeSelectedDirectory::Load ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +bool CSettingTypeSelectedDirectory::Load ( int Index, stdstr & Value ) const +{ + SettingID DirSettingId = _Settings->LoadBool(m_UseSelected) ? m_SelectedDir : m_InitialDir; + return _Settings->LoadString(DirSettingId, Value); +} + +//return the default values +void CSettingTypeSelectedDirectory::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +//Update the settings +void CSettingTypeSelectedDirectory::Save ( int Index, bool Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::Save ( int Index, ULONG Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::Save ( int Index, const stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeSelectedDirectory::Save ( int Index, const char * Value ) +{ + _Settings->SaveBool(m_UseSelected,true); + _Settings->SaveString(m_SelectedDir,Value); +} + +void CSettingTypeSelectedDirectory::Delete( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.h b/Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.h new file mode 100644 index 000000000..1d38f867e --- /dev/null +++ b/Source/Project64/Settings/SettingType/SettingsType-SelectedDirectory.h @@ -0,0 +1,36 @@ +#pragma once + +class CSettingTypeSelectedDirectory : + public CSettingType +{ + SettingID m_InitialDir; + SettingID m_SelectedDir; + SettingID m_UseSelected; + +public: + CSettingTypeSelectedDirectory(SettingID InitialDir, SettingID SelectedDir, SettingID UseSelected ); + ~CSettingTypeSelectedDirectory(); + + virtual bool IndexBasedSetting ( void ) const { return false; } + virtual SettingType GetSettingType ( void ) const { return SettingType_SelectedDirectory; } + + //return the values + virtual bool Load ( int Index, bool & Value ) const; + virtual bool Load ( int Index, ULONG & Value ) const; + virtual bool Load ( int Index, stdstr & Value ) const; + + //return the default values + virtual void LoadDefault ( int Index, bool & Value ) const; + virtual void LoadDefault ( int Index, ULONG & Value ) const; + virtual void LoadDefault ( int Index, stdstr & Value ) const; + + //Update the settings + virtual void Save ( int Index, bool Value ); + virtual void Save ( int Index, ULONG Value ); + virtual void Save ( int Index, const stdstr & Value ); + virtual void Save ( int Index, const char * Value ); + + // Delete the setting + virtual void Delete ( int Index ); +}; + diff --git a/Source/Project64/Settings/SettingType/SettingsType-TempBool.cpp b/Source/Project64/Settings/SettingType/SettingsType-TempBool.cpp index 71e398b1a..547c44d5d 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-TempBool.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-TempBool.cpp @@ -25,11 +25,27 @@ bool CSettingTypeTempBool::Load ( int Index, stdstr & Value ) const return false; } -void CSettingTypeTempBool::Save ( int Index, bool Value ) +//return the default values +void CSettingTypeTempBool::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeTempBool::LoadDefault ( int Index, ULONG & Value ) const { Notify().BreakPoint(__FILE__,__LINE__); } +void CSettingTypeTempBool::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeTempBool::Save ( int Index, bool Value ) +{ + m_value = Value; +} + void CSettingTypeTempBool::Save ( int Index, ULONG Value ) { Notify().BreakPoint(__FILE__,__LINE__); @@ -44,3 +60,8 @@ void CSettingTypeTempBool::Save ( int Index, const char * Value ) { Notify().BreakPoint(__FILE__,__LINE__); } + +void CSettingTypeTempBool::Delete( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-TempBool.h b/Source/Project64/Settings/SettingType/SettingsType-TempBool.h index ae64dce41..528d679fe 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-TempBool.h +++ b/Source/Project64/Settings/SettingType/SettingsType-TempBool.h @@ -9,18 +9,26 @@ public: CSettingTypeTempBool(bool initialValue ); ~CSettingTypeTempBool(); - bool IndexBasedSetting ( void ) const { return false; } - SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_BoolVariable; } + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_BoolVariable; } //return the values - bool Load ( int Index, bool & Value ) const; - bool Load ( int Index, ULONG & Value ) const; - bool Load ( int Index, stdstr & Value ) const; + bool Load ( int Index, bool & Value ) const; + bool Load ( int Index, ULONG & Value ) const; + bool Load ( int Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int Index, bool & Value ) const; + void LoadDefault ( int Index, ULONG & Value ) const; + void LoadDefault ( int Index, stdstr & Value ) const; //Update the settings - void Save ( int Index, bool Value ); - void Save ( int Index, ULONG Value ); - void Save ( int Index, const stdstr & Value ); - void Save ( int Index, const char * Value ); + void Save ( int Index, bool Value ); + void Save ( int Index, ULONG Value ); + void Save ( int Index, const stdstr & Value ); + void Save ( int Index, const char * Value ); + + // Delete the setting + void Delete ( int Index ); }; diff --git a/Source/Project64/Settings/SettingType/SettingsType-TempNumber.cpp b/Source/Project64/Settings/SettingType/SettingsType-TempNumber.cpp index 49fe648ad..fe74ee458 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-TempNumber.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-TempNumber.cpp @@ -25,6 +25,22 @@ bool CSettingTypeTempNumber::Load ( int Index, stdstr & Value ) const return false; } +//return the default values +void CSettingTypeTempNumber::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeTempNumber::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeTempNumber::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + void CSettingTypeTempNumber::Save ( int Index, bool Value ) { Notify().BreakPoint(__FILE__,__LINE__); @@ -32,7 +48,7 @@ void CSettingTypeTempNumber::Save ( int Index, bool Value ) void CSettingTypeTempNumber::Save ( int Index, ULONG Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + m_value = Value; } void CSettingTypeTempNumber::Save ( int Index, const stdstr & Value ) @@ -44,3 +60,8 @@ void CSettingTypeTempNumber::Save ( int Index, const char * Value ) { Notify().BreakPoint(__FILE__,__LINE__); } + +void CSettingTypeTempNumber::Delete( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-TempNumber.h b/Source/Project64/Settings/SettingType/SettingsType-TempNumber.h index edd0ff1cc..4096543cd 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-TempNumber.h +++ b/Source/Project64/Settings/SettingType/SettingsType-TempNumber.h @@ -10,19 +10,26 @@ public: CSettingTypeTempNumber(ULONG initialValue); ~CSettingTypeTempNumber(); - bool IndexBasedSetting ( void ) const { return false; } - SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_NumberVariable; } + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_NumberVariable; } //return the values - bool Load ( int Index, bool & Value ) const; - bool Load ( int Index, ULONG & Value ) const; - bool Load ( int Index, stdstr & Value ) const; + bool Load ( int Index, bool & Value ) const; + bool Load ( int Index, ULONG & Value ) const; + bool Load ( int Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int Index, bool & Value ) const; + void LoadDefault ( int Index, ULONG & Value ) const; + void LoadDefault ( int Index, stdstr & Value ) const; //Update the settings - void Save ( int Index, bool Value ); - void Save ( int Index, ULONG Value ); - void Save ( int Index, const stdstr & Value ); - void Save ( int Index, const char * Value ); + void Save ( int Index, bool Value ); + void Save ( int Index, ULONG Value ); + void Save ( int Index, const stdstr & Value ); + void Save ( int Index, const char * Value ); + // Delete the setting + void Delete ( int Index ); }; diff --git a/Source/Project64/Settings/SettingType/SettingsType-TempString.cpp b/Source/Project64/Settings/SettingType/SettingsType-TempString.cpp index 7f506ce73..ce6f4bfa4 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-TempString.cpp +++ b/Source/Project64/Settings/SettingType/SettingsType-TempString.cpp @@ -25,6 +25,22 @@ bool CSettingTypeTempString::Load ( int Index, stdstr & Value ) const return true; } +//return the default values +void CSettingTypeTempString::LoadDefault ( int Index, bool & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeTempString::LoadDefault ( int Index, ULONG & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettingTypeTempString::LoadDefault ( int Index, stdstr & Value ) const +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + void CSettingTypeTempString::Save ( int Index, bool Value ) { Notify().BreakPoint(__FILE__,__LINE__); @@ -44,3 +60,8 @@ void CSettingTypeTempString::Save ( int Index, const char * Value ) { m_value = Value; } + +void CSettingTypeTempString::Delete( int Index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} diff --git a/Source/Project64/Settings/SettingType/SettingsType-TempString.h b/Source/Project64/Settings/SettingType/SettingsType-TempString.h index e882db8c0..d9b5af16d 100644 --- a/Source/Project64/Settings/SettingType/SettingsType-TempString.h +++ b/Source/Project64/Settings/SettingType/SettingsType-TempString.h @@ -10,19 +10,26 @@ public: CSettingTypeTempString(LPCSTR initialValue); ~CSettingTypeTempString(); - bool IndexBasedSetting ( void ) const { return false; } - SettingLocation GetSettingsLocation ( void ) const { return SettingLocation_StringVariable; } - + bool IndexBasedSetting ( void ) const { return false; } + SettingType GetSettingType ( void ) const { return SettingType_StringVariable; } + //return the values - bool Load ( int Index, bool & Value ) const; - bool Load ( int Index, ULONG & Value ) const; - bool Load ( int Index, stdstr & Value ) const; + bool Load ( int Index, bool & Value ) const; + bool Load ( int Index, ULONG & Value ) const; + bool Load ( int Index, stdstr & Value ) const; + + //return the default values + void LoadDefault ( int Index, bool & Value ) const; + void LoadDefault ( int Index, ULONG & Value ) const; + void LoadDefault ( int Index, stdstr & Value ) const; //Update the settings - void Save ( int Index, bool Value ); - void Save ( int Index, ULONG Value ); - void Save ( int Index, const stdstr & Value ); - void Save ( int Index, const char * Value ); + void Save ( int Index, bool Value ); + void Save ( int Index, ULONG Value ); + void Save ( int Index, const stdstr & Value ); + void Save ( int Index, const char * Value ); + // Delete the setting + void Delete ( int Index ); }; diff --git a/Source/Project64/Settings/Settings Class.cpp b/Source/Project64/Settings/Settings Class.cpp index 20736c7cc..022a9b9aa 100644 --- a/Source/Project64/Settings/Settings Class.cpp +++ b/Source/Project64/Settings/Settings Class.cpp @@ -3,9 +3,18 @@ #include #include "SettingType/SettingsType-Application.h" #include "SettingType/SettingsType-ApplicationIndex.h" +#include "SettingType/SettingsType-Cheats.h" #include "SettingType/SettingsType-GameSetting.h" -#include "SettingType/SettingsType-RomDatabase.h" +#include "SettingType/SettingsType-GameSettingIndex.h" #include "SettingType/SettingsType-RelativePath.h" +#include "SettingType/SettingsType-RomDatabase.h" +#include "SettingType/SettingsType-RomDatabaseIndex.h" +#include "SettingType/SettingsType-RDBCpuType.h" +#include "SettingType/SettingsType-RDBRamSize.h" +#include "SettingType/SettingsType-RDBSaveChip.h" +#include "SettingType/SettingsType-RDBYesNo.h" +#include "SettingType/SettingsType-RDBOnOff.h" +#include "SettingType/SettingsType-SelectedDirectory.h" #include "SettingType/SettingsType-TempString.h" #include "SettingType/SettingsType-TempNumber.h" #include "SettingType/SettingsType-TempBool.h" @@ -37,31 +46,225 @@ CSettings::~CSettings() CSettingTypeApplication::CleanUp(); CSettingTypeRomDatabase::CleanUp(); - + CSettingTypeGame::CleanUp(); + CSettingTypeCheats::CleanUp(); } void CSettings::AddHandler ( SettingID TypeID, CSettingType * Handler ) { - m_SettingInfo.insert(SETTING_MAP::value_type(TypeID,Handler)); + SETTING_HANDLER FindInfo = m_SettingInfo.find(TypeID); + if (FindInfo == m_SettingInfo.end()) + { + m_SettingInfo.insert(SETTING_MAP::value_type(TypeID,Handler)); + } else { + delete Handler; + } } void CSettings::AddHowToHandleSetting () { + //information - temp keys + AddHandler(Info_RomLoading, new CSettingTypeTempBool(false)); + AddHandler(Info_ShortCutsChanged, new CSettingTypeTempBool(false)); + + //Support Files - AddHandler(SettingsIniName, new CSettingTypeRelativePath("","Project64.cfg")); - AddHandler(RomDatabaseFile, new CSettingTypeRelativePath("","Project64.rdb")); - AddHandler(CheatIniName, new CSettingTypeRelativePath("","Project64.cht")); - AddHandler(NotesIniName, new CSettingTypeRelativePath("","Project64.rdn")); - AddHandler(ExtIniName, new CSettingTypeRelativePath("","Project64.rdx")); - AddHandler(ShortCutFile, new CSettingTypeRelativePath("","Project64.sc2")); - AddHandler(RomListCache, new CSettingTypeRelativePath("","Project64.cache3")); - AddHandler(ZipCacheIniName, new CSettingTypeRelativePath("","Project64.zcache")); - AddHandler(SyncPluginDir, new CSettingTypeRelativePath("SyncPlugin","")); + AddHandler(SupportFile_Settings, new CSettingTypeRelativePath("","Project64.cfg")); + AddHandler(SupportFile_RomDatabase, new CSettingTypeRelativePath("","Project64.rdb")); + AddHandler(SupportFile_Cheats, new CSettingTypeRelativePath("","Project64.cht")); + AddHandler(SupportFile_Notes, new CSettingTypeRelativePath("","Project64.rdn")); + AddHandler(SupportFile_ExtInfo, new CSettingTypeRelativePath("","Project64.rdx")); + AddHandler(SupportFile_ShortCuts, new CSettingTypeRelativePath("","Project64.sc3")); + AddHandler(SupportFile_RomListCache,new CSettingTypeRelativePath("","Project64.cache3")); + AddHandler(SupportFile_7zipCache, new CSettingTypeRelativePath("","Project64.zcache")); + + //AddHandler(SyncPluginDir, new CSettingTypeRelativePath("SyncPlugin","")); //Settings location - AddHandler(UseSettingFromRegistry,new CSettingTypeApplication("Settings","Use Registry",(DWORD)false)); + AddHandler(Setting_ApplicationName, new CSettingTypeTempString("")); + AddHandler(Setting_UseFromRegistry, new CSettingTypeApplication("Settings","Use Registry",(DWORD)false)); + AddHandler(Setting_RdbEditor, new CSettingTypeApplication("","Rdb Editor", false)); + AddHandler(Setting_DisableScrSaver, new CSettingTypeApplication("","Disable Screen Saver",(DWORD)true)); + AddHandler(Setting_AutoSleep, new CSettingTypeApplication("","Auto Sleep", (DWORD)true)); + AddHandler(Setting_AutoStart, new CSettingTypeApplication("","Auto Start", (DWORD)true)); + AddHandler(Setting_AutoFullscreen, new CSettingTypeApplication("","Auto Full Screen", (DWORD)true)); + AddHandler(Setting_AutoZipInstantSave,new CSettingTypeApplication("","Auto Zip Saves", (DWORD)true)); -/* INFO(SettingsIniName,No_Default,Data_String,RelativePath,"Project64.cfg","",0); + AddHandler(Setting_RememberCheats, new CSettingTypeApplication("","Remember Cheats", (DWORD)false)); + AddHandler(Setting_CurrentLanguage, new CSettingTypeApplication("","Current Language","")); + + AddHandler(Rdb_SaveChip, new CSettingTypeRDBSaveChip("Save Type",SaveChip_Auto)); + AddHandler(Rdb_CpuType, new CSettingTypeRDBCpuType("CPU Type",CPU_Recompiler)); + AddHandler(Rdb_RDRamSize, new CSettingTypeRDBRDRamSize("RDRAM Size",4)); + AddHandler(Rdb_CounterFactor, new CSettingTypeRomDatabase("Counter Factor",2)); + AddHandler(Rdb_UseTlb, new CSettingTypeRDBYesNo("Use TLB",true)); + AddHandler(Rdb_DelaySi, new CSettingTypeRDBYesNo("Delay SI",false)); + AddHandler(Rdb_SPHack, new CSettingTypeRDBYesNo("SP Hack",false)); + AddHandler(Rdb_Status, new CSettingTypeRomDatabase("Status","Unknown")); + AddHandler(Rdb_FixedAudio, new CSettingTypeRomDatabase("Fixed Audio",true)); + AddHandler(Rdb_SyncViaAudio, new CSettingTypeRomDatabase("Sync Audio",false)); + AddHandler(Rdb_RspAudioSignal, new CSettingTypeRDBYesNo("Audio Signal",false)); + AddHandler(Rdb_TLB_VAddrStart, new CSettingTypeRomDatabase("TLB: Vaddr Start",0)); + AddHandler(Rdb_TLB_VAddrLen, new CSettingTypeRomDatabase("TLB: Vaddr Len",0)); + AddHandler(Rdb_TLB_PAddrStart, new CSettingTypeRomDatabase("TLB: PAddr Start",0)); + AddHandler(Rdb_UseHleGfx, new CSettingTypeRomDatabase("HLE GFX",Plugin_UseHleGfx)); + AddHandler(Rdb_UseHleAudio, new CSettingTypeRomDatabase("HLE Audio",Plugin_UseHleAudio)); + AddHandler(Rdb_LoadRomToMemory, new CSettingTypeRomDatabase("Rom In Memory",false)); + AddHandler(Rdb_ScreenHertz, new CSettingTypeRomDatabase("ScreenHertz",60)); + AddHandler(Rdb_FuncLookupMode, new CSettingTypeRomDatabase("FuncFind",FuncFind_PhysicalLookup)); + AddHandler(Rdb_RegCache, new CSettingTypeRDBYesNo("Reg Cache",true)); + AddHandler(Rdb_BlockLinking, new CSettingTypeRDBOnOff("Linking",false)); + AddHandler(Rdb_SMM_Cache, new CSettingTypeRomDatabase("SMM-Cache",true)); + AddHandler(Rdb_SMM_PIDMA, new CSettingTypeRomDatabase("SMM-PI DMA",true)); + AddHandler(Rdb_SMM_TLB, new CSettingTypeRomDatabase("SMM-TLB",true)); + AddHandler(Rdb_SMM_Protect, new CSettingTypeRomDatabase("SMM-Protect",false)); + AddHandler(Rdb_SMM_ValidFunc, new CSettingTypeRomDatabase("SMM-FUNC",true)); + AddHandler(Rdb_GameCheatFix, new CSettingTypeRomDatabaseIndex("Cheat","","")); + + + AddHandler(Game_IniKey, new CSettingTypeTempString("")); + AddHandler(Game_GameName, new CSettingTypeTempString("")); + AddHandler(Game_GoodName, new CSettingTypeRomDatabase("Good Name",Game_GameName)); + AddHandler(Game_Plugin_Gfx, new CSettingTypeGame("Plugin","Gfx",Plugin_GFX_Current)); + AddHandler(Game_Plugin_Audio, new CSettingTypeGame("Plugin","Audio",Plugin_AUDIO_Current)); + AddHandler(Game_Plugin_Controller, new CSettingTypeGame("Plugin","Controller",Plugin_CONT_Current)); + AddHandler(Game_Plugin_RSP, new CSettingTypeGame("Plugin","RSP",Plugin_RSP_Current)); + AddHandler(Game_SaveChip, new CSettingTypeGame("","SaveChip",Rdb_SaveChip)); + AddHandler(Game_CpuType, new CSettingTypeGame("","CpuType",Rdb_CpuType)); + AddHandler(Game_LastSaveSlot, new CSettingTypeGame("","Last Used Save Slot",(DWORD)0)); + AddHandler(Game_FixedAudio, new CSettingTypeGame("","Fixed Audio",Rdb_FixedAudio)); + AddHandler(Game_RDRamSize, new CSettingTypeGame("","RDRamSize",Rdb_RDRamSize)); + AddHandler(Game_CounterFactor, new CSettingTypeGame("","Counter Factor",Rdb_CounterFactor)); + AddHandler(Game_UseTlb, new CSettingTypeGame("","Use TLB",Rdb_UseTlb)); + AddHandler(Game_DelaySI, new CSettingTypeGame("","Delay SI",Rdb_DelaySi)); + AddHandler(Game_RspAudioSignal, new CSettingTypeGame("","Audio Signal",Rdb_RspAudioSignal)); + AddHandler(Game_SPHack, new CSettingTypeGame("","SP Hack",Rdb_SPHack)); + AddHandler(Game_CurrentSaveState, new CSettingTypeTempNumber(0)); + AddHandler(Game_SyncViaAudio, new CSettingTypeGame("","Sync Audio",Rdb_SyncViaAudio)); + AddHandler(Game_UseHleGfx, new CSettingTypeGame("RSP","HLE GFX",Rdb_UseHleGfx)); + AddHandler(Game_UseHleAudio, new CSettingTypeGame("RSP","HLE Audio",Rdb_UseHleAudio)); + AddHandler(Game_LoadRomToMemory, new CSettingTypeGame("","Rom In Memory",Rdb_LoadRomToMemory)); + AddHandler(Game_ScreenHertz, new CSettingTypeGame("","ScreenHertz",Rdb_ScreenHertz)); + AddHandler(Game_FuncLookupMode, new CSettingTypeGame("","FuncFind",Rdb_FuncLookupMode)); + AddHandler(Game_RegCache, new CSettingTypeGame("","Reg Cache",Rdb_RegCache)); + AddHandler(Game_BlockLinking, new CSettingTypeGame("","Linking",Rdb_BlockLinking)); + AddHandler(Game_SMM_Cache, new CSettingTypeGame("SMM","Cache",Rdb_SMM_Cache)); + AddHandler(Game_SMM_PIDMA, new CSettingTypeGame("SMM","PI DMA",Rdb_SMM_PIDMA)); + AddHandler(Game_SMM_TLB, new CSettingTypeGame("SMM","TLB",Rdb_SMM_TLB)); + AddHandler(Game_SMM_Protect, new CSettingTypeGame("SMM","Protect",Rdb_SMM_Protect)); + AddHandler(Game_SMM_ValidFunc, new CSettingTypeGame("SMM","FUNC",Rdb_SMM_ValidFunc)); + + //User Interface + AddHandler(UserInterface_BasicMode, new CSettingTypeApplication("","Basic Mode", (DWORD)true)); + AddHandler(UserInterface_ShowCPUPer, new CSettingTypeApplication("","Display CPU Usage", (DWORD)false)); + AddHandler(UserInterface_DisplayFrameRate, new CSettingTypeApplication("","Display Frame Rate", (DWORD)true)); + AddHandler(UserInterface_InFullScreen, new CSettingTypeTempBool(false)); + AddHandler(UserInterface_FrameDisplayType, new CSettingTypeApplication("","Frame Rate Display Type", (DWORD)FR_VIs)); + AddHandler(UserInterface_MainWindowTop, new CSettingTypeApplication("Main Window","Top" ,Default_None)); + AddHandler(UserInterface_MainWindowLeft, new CSettingTypeApplication("Main Window","Left" ,Default_None)); + AddHandler(UserInterface_AlwaysOnTop, new CSettingTypeApplication("","Always on top", (DWORD)false)); + + AddHandler(RomBrowser_Enabled, new CSettingTypeApplication("Rom Browser","Rom Browser",true)); + AddHandler(RomBrowser_ColoumnsChanged, new CSettingTypeTempBool(false)); + AddHandler(RomBrowser_Top, new CSettingTypeApplication("Rom Browser","Top" ,Default_None)); + AddHandler(RomBrowser_Left, new CSettingTypeApplication("Rom Browser","Left" ,Default_None)); + AddHandler(RomBrowser_Width, new CSettingTypeApplication("Rom Browser","Width", (DWORD)640)); + AddHandler(RomBrowser_Height, new CSettingTypeApplication("Rom Browser","Height", (DWORD)480)); + AddHandler(RomBrowser_PosIndex, new CSettingTypeApplicationIndex("Rom Browser\\Field Pos","Field",Default_None)); + AddHandler(RomBrowser_WidthIndex, new CSettingTypeApplicationIndex("Rom Browser\\Field Width","Field",Default_None)); + AddHandler(RomBrowser_SortFieldIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Field", Default_None)); + AddHandler(RomBrowser_SortAscendingIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Ascending", Default_None)); + AddHandler(RomBrowser_Recursive, new CSettingTypeApplication("Rom Browser","Recursive", false)); + AddHandler(RomBrowser_Maximized, new CSettingTypeApplication("Rom Browser","Maximized", false)); + + AddHandler(Directory_RecentGameDirCount, new CSettingTypeApplication("","Remembered Rom Dirs",(DWORD)10)); + AddHandler(Directory_RecentGameDirIndex, new CSettingTypeApplicationIndex("Recent Dir","Recent Dir",Default_None)); + + //Directory_Game, + AddHandler(Directory_Game, new CSettingTypeSelectedDirectory(Directory_GameInitial,Directory_GameSelected,Directory_GameUseSelected)); + AddHandler(Directory_GameInitial, new CSettingTypeRelativePath("Game Directory","")); + AddHandler(Directory_GameSelected, new CSettingTypeApplication("Directory","Game",Directory_GameInitial)); + AddHandler(Directory_GameUseSelected, new CSettingTypeApplication("Directory","Game - Use Selected",false)); + + AddHandler(Directory_Plugin, new CSettingTypeSelectedDirectory(Directory_PluginInitial,Directory_PluginSelected,Directory_PluginUseSelected)); + AddHandler(Directory_PluginInitial, new CSettingTypeRelativePath("Plugin","")); + AddHandler(Directory_PluginSelected, new CSettingTypeApplication("Directory","Plugin",Directory_PluginInitial)); + AddHandler(Directory_PluginUseSelected, new CSettingTypeApplication("Directory","Plugin - Use Selected",false)); + + AddHandler(Directory_SnapShot, new CSettingTypeSelectedDirectory(Directory_SnapShotInitial,Directory_SnapShotSelected,Directory_SnapShotUseSelected)); + AddHandler(Directory_SnapShotInitial, new CSettingTypeRelativePath("Screenshots","")); + AddHandler(Directory_SnapShotSelected, new CSettingTypeApplication("Directory","Snap Shot",Directory_SnapShotInitial)); + AddHandler(Directory_SnapShotUseSelected, new CSettingTypeApplication("Directory","Snap Shot - Use Selected",false)); + + AddHandler(Directory_NativeSave, new CSettingTypeSelectedDirectory(Directory_NativeSaveInitial,Directory_NativeSaveSelected,Directory_NativeSaveUseSelected)); + AddHandler(Directory_NativeSaveInitial, new CSettingTypeRelativePath("Save","")); + AddHandler(Directory_NativeSaveSelected, new CSettingTypeApplication("Directory","Save",Directory_NativeSaveInitial)); + AddHandler(Directory_NativeSaveUseSelected,new CSettingTypeApplication("Directory","Save - Use Selected",false)); + + AddHandler(Directory_InstantSave, new CSettingTypeSelectedDirectory(Directory_InstantSaveInitial,Directory_InstantSaveSelected,Directory_InstantSaveUseSelected)); + AddHandler(Directory_InstantSaveInitial, new CSettingTypeRelativePath("Save","")); + AddHandler(Directory_InstantSaveSelected, new CSettingTypeApplication("Directory","Instant Save",Directory_InstantSaveInitial)); + AddHandler(Directory_InstantSaveUseSelected,new CSettingTypeApplication("Directory","Instant Save - Use Selected",false)); + + AddHandler(Directory_Texture, new CSettingTypeSelectedDirectory(Directory_TextureInitial,Directory_TextureSelected,Directory_TextureUseSelected)); + AddHandler(Directory_TextureInitial, new CSettingTypeRelativePath("textures-load","")); + AddHandler(Directory_TextureSelected, new CSettingTypeApplication("Directory","Texture Dir",Directory_InstantSaveInitial)); + AddHandler(Directory_TextureUseSelected, new CSettingTypeApplication("Directory","Texture Dir - Use Selected",false)); + + AddHandler(GameRunning_LoadingInProgress, new CSettingTypeTempBool(false)); + AddHandler(GameRunning_CPU_Running, new CSettingTypeTempBool(false)); + AddHandler(GameRunning_CPU_Paused, new CSettingTypeTempBool(false)); + AddHandler(GameRunning_CPU_PausedType, new CSettingTypeTempNumber(Default_None)); + AddHandler(GameRunning_InstantSaveFile, new CSettingTypeTempString("")); + AddHandler(GameRunning_LimitFPS, new CSettingTypeTempBool(true)); + AddHandler(GameRunning_ScreenHertz, new CSettingTypeTempNumber(60)); + + AddHandler(File_RecentGameFileCount, new CSettingTypeApplication("","Remembered Rom Files",(DWORD)10)); + AddHandler(File_RecentGameFileIndex, new CSettingTypeApplicationIndex("Recent File","Recent Rom",Default_None)); + + AddHandler(Debugger_Enabled, new CSettingTypeApplication("Debugger","Debugger",false)); + AddHandler(Debugger_ShowUnhandledMemory, new CSettingTypeApplication("Debugger","Show Unhandled Memory",false)); + AddHandler(Debugger_ShowPifErrors, new CSettingTypeApplication("Debugger","Show Pif Errors",false)); + AddHandler(Debugger_DisableGameFixes, new CSettingTypeApplication("Debugger","Disable Game Fixes",false)); + AddHandler(Debugger_ShowDListAListCount, new CSettingTypeApplication("Debugger","Show Dlist Alist Count",false)); + AddHandler(Debugger_ShowRecompMemSize, new CSettingTypeApplication("Debugger","Show Recompiler Memory size",false)); + AddHandler(Debugger_ShowCheckOpUsageErrors, new CSettingTypeApplication("Debugger","Show Check Op Usage Errors",false)); + AddHandler(Debugger_GenerateDebugLog, new CSettingTypeApplication("Debugger","Generate Debug Code",false)); + AddHandler(Debugger_ProfileCode, new CSettingTypeApplication("Debugger","Profile Code", (DWORD)false)); + AddHandler(Debugger_AppLogLevel, new CSettingTypeApplication("Logging","Log Level",(DWORD)TraceError)); + AddHandler(Debugger_AppLogFlush, new CSettingTypeApplication("Logging","Log Auto Flush",(DWORD)false)); + AddHandler(Debugger_GenerateLogFiles, new CSettingTypeApplication("Debugger","Generate Log Files", false)); + + + AddHandler(Beta_IsBetaVersion, new CSettingTypeTempBool(true)); + AddHandler(Beta_UserName, new CSettingTypeTempString("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")); + AddHandler(Beta_EmailAddress, new CSettingTypeTempString("????????????????????????????????????????????????????????????????????????????????")); + AddHandler(Beta_UserNameMD5, new CSettingTypeTempString("CBBABA8D2262FF1F7A47CEAD87FC4304")); + AddHandler(Beta_EmailAddressMD5, new CSettingTypeTempString("47A3D7CBF1DA291D5EB30DCAAF21B9F8")); + AddHandler(Beta_IsValidExe, new CSettingTypeTempBool(true)); + + //Plugin + AddHandler(Plugin_RSP_Current, new CSettingTypeApplication("Plugin","RSP Dll", "RSP\\RSP 1.7.dll")); + AddHandler(Plugin_GFX_Current, new CSettingTypeApplication("Plugin","Graphics Dll", "GFX\\Jabo_Direct3D8.dll")); + AddHandler(Plugin_AUDIO_Current, new CSettingTypeApplication("Plugin","Audio Dll", "Audio\\Jabo_Dsound.dll")); + AddHandler(Plugin_CONT_Current, new CSettingTypeApplication("Plugin","Controller Dll","Input\\Jabo_DInput.dll")); + + AddHandler(Plugin_RSP_CurVer, new CSettingTypeApplication("Plugin","RSP Dll Ver", "")); + AddHandler(Plugin_GFX_CurVer, new CSettingTypeApplication("Plugin","Graphics Dll Ver", "")); + AddHandler(Plugin_AUDIO_CurVer, new CSettingTypeApplication("Plugin","Audio Dll Ver", "")); + AddHandler(Plugin_CONT_CurVer, new CSettingTypeApplication("Plugin","Controller Dll Ver", "")); + + AddHandler(Plugin_UseHleGfx, new CSettingTypeApplication("RSP","HLE GFX",true)); + AddHandler(Plugin_UseHleAudio, new CSettingTypeApplication("RSP","HLE Audio",false)); + + // cheats + AddHandler(Cheat_Entry, new CSettingTypeCheats("")); + AddHandler(Cheat_Active, new CSettingTypeGameIndex("Cheat","",(bool)false)); + AddHandler(Cheat_Extension, new CSettingTypeGameIndex("Cheat",".exten","??? - Not Set")); + AddHandler(Cheat_Notes, new CSettingTypeCheats("_N")); + AddHandler(Cheat_Options, new CSettingTypeCheats("_O")); + + /* INFO(SettingsIniName,Default_None,Data_String,RelativePath,"Project64.cfg","",0); if (SettingsIniFile == NULL) { SettingsIniFile = new CIniFile(LoadString(SettingsIniName).c_str()); @@ -76,28 +279,28 @@ void CSettings::AddHowToHandleSetting () #define INFO(ID,X,Y,Z,Q,W,E) SettingInfo.insert(SETTING_MAP::value_type(ID,CSettingInfo(ID,X,Y,Z,Q,W,E))) #define INF2(ID,X,Y,Z,Q,W,E,R) SettingInfo.insert(SETTING_MAP::value_type(ID,CSettingInfo(ID,X,Y,Z,Q,W,E,R))) //Default Values - INFO(Default_False, No_Default, Data_DWORD, ConstValue, "","",(DWORD)false); - INFO(Default_True, No_Default, Data_DWORD, ConstValue, "","",(DWORD)true); - INFO(Default_Language, No_Default, Data_String, ConstString, "","",0); - INFO(Default_RomStatus, No_Default, Data_String, ConstString, "Unknown","",0); - INFO(Default_RomBrowserWidth, No_Default, Data_DWORD, ConstValue, "","",640); - INFO(Default_RomBrowserHeight, No_Default, Data_DWORD, ConstValue, "","",480); - INFO(Default_RememberedRomFiles, No_Default, Data_DWORD, ConstValue, "","",MaxRememberedFiles); - INFO(Default_RememberedRomDirs, No_Default, Data_DWORD, ConstValue, "","",MaxRememberedDirs); - INFO(Default_CPUType, No_Default, Data_DWORD, ConstValue, "","",CPU_Recompiler); - INFO(Default_RdramSize, No_Default, Data_DWORD, ConstValue, "","",0x400000); - INFO(Default_SaveChip, No_Default, Data_DWORD, ConstValue, "","",SaveChip_Auto); - INFO(Default_CFactor, No_Default, Data_DWORD, ConstValue, "","",2); - INFO(Default_CheatExt, No_Default, Data_String, ConstString, "?","",0); - INFO(Default_FunctionLookup, No_Default, Data_DWORD, ConstValue, "","",FuncFind_PhysicalLookup); - INFO(Default_BlockLinking, No_Default, Data_DWORD, ConstValue, "","",(DWORD)false); - INFO(Default_SaveSlot, No_Default, Data_DWORD, ConstValue, "","",(DWORD)0); - INFO(Default_LogLevel, No_Default, Data_DWORD, ConstValue, "","",(DWORD)TraceError); - INFO(Default_FrameDisplayType, No_Default, Data_DWORD, ConstValue, "","",FR_VIs); + INFO(Default_False, Default_None, Data_DWORD, ConstValue, "","",(DWORD)false); + INFO(Default_True, Default_None, Data_DWORD, ConstValue, "","",(DWORD)true); + INFO(Default_Language, Default_None, Data_String, ConstString, "","",0); + INFO(Default_RomStatus, Default_None, Data_String, ConstString, "Unknown","",0); + INFO(Default_RomBrowserWidth, Default_None, Data_DWORD, ConstValue, "","",640); + INFO(Default_RomBrowserHeight, Default_None, Data_DWORD, ConstValue, "","",480); + INFO(Default_RememberedRomFiles, Default_None, Data_DWORD, ConstValue, "","",MaxRememberedFiles); + INFO(Default_RememberedRomDirs, Default_None, Data_DWORD, ConstValue, "","",MaxRememberedDirs); + INFO(Default_CPUType, Default_None, Data_DWORD, ConstValue, "","",CPU_Recompiler); + INFO(Default_RdramSize, Default_None, Data_DWORD, ConstValue, "","",0x400000); + INFO(Default_SaveChip, Default_None, Data_DWORD, ConstValue, "","",SaveChip_Auto); + INFO(Default_CFactor, Default_None, Data_DWORD, ConstValue, "","",2); + INFO(Default_CheatExt, Default_None, Data_String, ConstString, "?","",0); + INFO(Default_FunctionLookup, Default_None, Data_DWORD, ConstValue, "","",FuncFind_PhysicalLookup); + INFO(Default_BlockLinking, Default_None, Data_DWORD, ConstValue, "","",(DWORD)false); + INFO(Default_SaveSlot, Default_None, Data_DWORD, ConstValue, "","",(DWORD)0); + INFO(Default_LogLevel, Default_None, Data_DWORD, ConstValue, "","",(DWORD)TraceError); + INFO(Default_FrameDisplayType, Default_None, Data_DWORD, ConstValue, "","",FR_VIs); //Add setting to see if we get settings from file system or registry - INFO(SettingsIniName,No_Default,Data_String,RelativePath,"Project64.cfg","",0); + INFO(SettingsIniName,Default_None,Data_String,RelativePath,"Project64.cfg","",0); if (SettingsIniFile == NULL) { SettingsIniFile = new CIniFile(LoadString(SettingsIniName).c_str()); @@ -107,19 +310,17 @@ void CSettings::AddHowToHandleSetting () SettingLocation SettingLoc = LoadDword(UseSettingFromRegistry) ? InRegistry : LocalSettings; */ //Language - AddHandler(CurrentLanguage,new CSettingTypeApplication("","Current Language","")); +/* AddHandler(CurrentLanguage,new CSettingTypeApplication("","Current Language","")); //Gui Settings AddHandler(RomBrowser, new CSettingTypeApplication("Rom Browser","Rom Browser",true)); - AddHandler(MainWindowTop, new CSettingTypeApplication("Main Window","Top" ,No_Default)); - AddHandler(MainWindowLeft, new CSettingTypeApplication("Main Window","Left" ,No_Default)); - AddHandler(RomBrowserTop, new CSettingTypeApplication("Rom Browser","Top" ,No_Default)); - AddHandler(RomBrowserLeft, new CSettingTypeApplication("Rom Browser","Left" ,No_Default)); + AddHandler(RomBrowserTop, new CSettingTypeApplication("Rom Browser","Top" ,Default_None)); + AddHandler(RomBrowserLeft, new CSettingTypeApplication("Rom Browser","Left" ,Default_None)); AddHandler(RomBrowserHeight, new CSettingTypeApplication("Rom Browser","Height", (DWORD)480)); AddHandler(RomBrowserWidth, new CSettingTypeApplication("Rom Browser","Width", (DWORD)640)); AddHandler(RomBrowserRecursive, new CSettingTypeApplication("Rom Browser","Recursive", false)); AddHandler(RomBrowserMaximized, new CSettingTypeApplication("Rom Browser","Maximized", false)); - AddHandler(RomBrowserSortFieldIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Field", No_Default)); + AddHandler(RomBrowserSortFieldIndex, new CSettingTypeApplicationIndex("Rom Browser", "Sort Field", Default_None)); AddHandler(RomBrowserPosIndex, new CSettingTypeApplicationIndex("Rom Browser\\Field Pos","Field",(DWORD)0)); AddHandler(RomBrowserWidthIndex,new CSettingTypeApplicationIndex("Rom Browser\\Field Width","Field",(DWORD)100)); @@ -129,23 +330,23 @@ void CSettings::AddHowToHandleSetting () for (int SortID = 0; SortID <= NoOfSortKeys; SortID++ ) { char Name[300]; _snprintf(Name,sizeof(Name),"Sort Field %d",SortID); - INF2((SettingID)(SortField + SortID),No_Default,Data_String,SettingLoc,Name,"Rom Browser",0,SortField); + INF2((SettingID)(SortField + SortID),Default_None,Data_String,SettingLoc,Name,"Rom Browser",0,SortField); _snprintf(Name,sizeof(Name),"Sort Ascending %d",SortID); INF2((SettingID)(SortAscending + SortID),Default_True,Data_DWORD,SettingLoc,Name,"Rom Browser",0,SortAscending); } for (int Field = 0; Field <= MaxRomBrowserFields; Field++ ) { char Name[300]; _snprintf(Name,sizeof(Name),"Field %02d",Field); - INF2((SettingID)(FirstRomBrowserPos + Field),No_Default,Data_DWORD,SettingLoc,Name,"Rom Browser\\Field Pos",0,FirstRomBrowserPos); - INF2((SettingID)(FirstRomBrowserWidth + Field),No_Default,Data_DWORD,SettingLoc,Name,"Rom Browser\\Field Width",0,FirstRomBrowserWidth); + INF2((SettingID)(FirstRomBrowserPos + Field),Default_None,Data_DWORD,SettingLoc,Name,"Rom Browser\\Field Pos",0,FirstRomBrowserPos); + INF2((SettingID)(FirstRomBrowserWidth + Field),Default_None,Data_DWORD,SettingLoc,Name,"Rom Browser\\Field Width",0,FirstRomBrowserWidth); } - INFO(TLBWindowTop,No_Default,Data_DWORD,SettingLoc,"Rom Browser Top","Page Setup",0); - INFO(TLBWindowLeft,No_Default,Data_DWORD,SettingLoc,"Rom Browser Left","Page Setup",0); + INFO(TLBWindowTop,Default_None,Data_DWORD,SettingLoc,"Rom Browser Top","Page Setup",0); + INFO(TLBWindowLeft,Default_None,Data_DWORD,SettingLoc,"Rom Browser Left","Page Setup",0); */ //Beta settings - AddHandler(IsBetaVersion, new CSettingTypeTempBool(true)); +/* AddHandler(IsBetaVersion, new CSettingTypeTempBool(true)); AddHandler(BetaUserName, new CSettingTypeTempString("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")); AddHandler(BetaEmailAddress, new CSettingTypeTempString("????????????????????????????????????????????????????????????????????????????????")); @@ -161,12 +362,8 @@ void CSettings::AddHowToHandleSetting () AddHandler(LimitFPS, new CSettingTypeApplication("","Limit FPS", (DWORD)true)); AddHandler(ProfileCode, new CSettingTypeApplication("","Profile Code", (DWORD)false)); AddHandler(GenerateLogFiles, new CSettingTypeApplication("","Generate Log Files", (DWORD)false)); - AddHandler(AlwaysOnTop, new CSettingTypeApplication("","Always on top", (DWORD)false)); AddHandler(DisableGameFixes, new CSettingTypeApplication("","Disable Game Fixes", (DWORD)false)); - AddHandler(IsValidExe, new CSettingTypeTempBool(true)); - AddHandler(DisplayFrameRate, new CSettingTypeApplication("","Display Frame Rate", (DWORD)true)); - AddHandler(FrameDisplayType, new CSettingTypeApplication("","Frame Rate Display Type", (DWORD)FR_VIs)); //Logging AddHandler(AppLogLevel,new CSettingTypeApplication("Logging","Log Level",(DWORD)TraceError)); @@ -174,63 +371,60 @@ void CSettings::AddHowToHandleSetting () //Recent Files AddHandler(RememberedRomFilesCount, new CSettingTypeApplication("","Remembered Rom Files",(DWORD)10)); - AddHandler(RecentRomFileIndex, new CSettingTypeApplicationIndex("Recent File","Recent Rom",No_Default)); + AddHandler(RecentRomFileIndex, new CSettingTypeApplicationIndex("Recent File","Recent Rom",Default_None)); AddHandler(RememberedRomDirCount, new CSettingTypeApplication("","Remembered Rom Dirs",(DWORD)10)); - AddHandler(RecentRomDirIndex, new CSettingTypeApplicationIndex("Recent Dir","Recent Dir",No_Default)); + AddHandler(RecentRomDirIndex, new CSettingTypeApplicationIndex("Recent Dir","Recent Dir",Default_None)); /* for (count = FirstRecentRom; count != LastRecentRom; count++ ) { char Name[300]; _snprintf(Name,sizeof(Name)," %d",count - FirstRecentRom); - INF2((SettingID)count,No_Default,Data_String,SettingLoc,Name,"",0,FirstRecentRom); + INF2((SettingID)count,Default_None,Data_String,SettingLoc,Name,"",0,FirstRecentRom); } //Recent Dirs for (count = FirstRecentDir; count != LastRecentDir; count++ ) { char Name[300]; _snprintf(Name,sizeof(Name),"Recent Dir %d",count - FirstRecentDir); - INF2((SettingID)count,No_Default,Data_String,SettingLoc,Name,"Recent Dir",0,FirstRecentDir); + INF2((SettingID)count,Default_None,Data_String,SettingLoc,Name,"Recent Dir",0,FirstRecentDir); } INFO(RememberedRomDir,Default_RememberedRomDirs,Data_DWORD,SettingLoc,"Remembered Rom Dirs","",0); //Plugins */ - AddHandler(CurrentRSP_Plugin, new CSettingTypeApplication("Plugin","RSP Dll", "RSP\\RSP 1.7.dll")); - AddHandler(CurrentGFX_Plugin, new CSettingTypeApplication("Plugin","Graphics Dll", "GFX\\Jabo_Direct3D8.dll")); - AddHandler(CurrentAUDIO_Plugin, new CSettingTypeApplication("Plugin","Audio Dll", "Audio\\Jabo_Dsound.dll")); - AddHandler(CurrentCONT_Plugin, new CSettingTypeApplication("Plugin","Controller Dll","Input\\Jabo_DInput.dll")); +/* AddHandler(CurVerRSP_Plugin, new CSettingTypeApplication("Plugin","RSP Dll Ver", "")); AddHandler(CurVerGFX_Plugin, new CSettingTypeApplication("Plugin","Graphics Dll Ver", "")); AddHandler(CurVerAUDIO_Plugin, new CSettingTypeApplication("Plugin","Audio Dll Ver", "")); AddHandler(CurVerCONT_Plugin, new CSettingTypeApplication("Plugin","Controller Dll Ver", "")); - /*INFO(RSP_PluginChanged, No_Default,Data_DWORD,TemporarySetting,"","",0); - INFO(AUDIO_PluginChanged,No_Default,Data_DWORD,TemporarySetting,"","",0); - INFO(GFX_PluginChanged, No_Default,Data_DWORD,TemporarySetting,"","",0); - INFO(CONT_PluginChanged, No_Default,Data_DWORD,TemporarySetting,"","",0); + /*INFO(RSP_PluginChanged, Default_None,Data_DWORD,TemporarySetting,"","",0); + INFO(AUDIO_PluginChanged,Default_None,Data_DWORD,TemporarySetting,"","",0); + INFO(GFX_PluginChanged, Default_None,Data_DWORD,TemporarySetting,"","",0); + INFO(CONT_PluginChanged, Default_None,Data_DWORD,TemporarySetting,"","",0); //Cheats for (count = 0; count < MaxCheats; count++ ) { char Name[300]; _snprintf(Name,sizeof(Name),"Cheat%d",count); - INF2((SettingID)(count + CheatEntry), No_Default,Data_String,CheatSetting,Name,"",0,CheatEntry); + INF2((SettingID)(count + CheatEntry), Default_None,Data_String,CheatSetting,Name,"",0,CheatEntry); _snprintf(Name,sizeof(Name),"Cheat%d",count); - INF2((SettingID)(count + CheatPermEntry),No_Default,Data_String,RomSetting,Name,"",0,CheatEntry); + INF2((SettingID)(count + CheatPermEntry),Default_None,Data_String,RomSetting,Name,"",0,CheatEntry); _snprintf(Name,sizeof(Name),"Cheat%d_O",count); - INF2((SettingID)(count + CheatOptions), No_Default,Data_String,CheatSetting,Name,"",0,CheatOptions); + INF2((SettingID)(count + CheatOptions), Default_None,Data_String,CheatSetting,Name,"",0,CheatOptions); _snprintf(Name,sizeof(Name),"Cheat%d_R",count); - INF2((SettingID)(count + CheatRange), No_Default,Data_String,CheatSetting,Name,"",0,CheatRange); + INF2((SettingID)(count + CheatRange), Default_None,Data_String,CheatSetting,Name,"",0,CheatRange); _snprintf(Name,sizeof(Name),"Cheat%d_RN",count); - INF2((SettingID)(count + CheatRangeNotes), No_Default,Data_String,CheatSetting,Name,"",0,CheatRangeNotes); + INF2((SettingID)(count + CheatRangeNotes), Default_None,Data_String,CheatSetting,Name,"",0,CheatRangeNotes); _snprintf(Name,sizeof(Name),"Cheat%d_N",count); - INF2((SettingID)(count + CheatNotes), No_Default,Data_String,CheatSetting,Name,"",0,CheatNotes); + INF2((SettingID)(count + CheatNotes), Default_None,Data_String,CheatSetting,Name,"",0,CheatNotes); _snprintf(Name,sizeof(Name),"Cheat%d",count); INF2((SettingID)(count + CheatActive), Default_False,Data_DWORD,GameSetting,Name,"",0,CheatActive); @@ -243,6 +437,7 @@ void CSettings::AddHowToHandleSetting () */ //Directories +/* AddHandler(InitialPluginDirectory, new CSettingTypeRelativePath("Plugin","")); AddHandler(InitialRomDirectory, new CSettingTypeRelativePath("Rom Directory","")); AddHandler(InitialSaveDirectory, new CSettingTypeRelativePath("Save","")); @@ -271,10 +466,10 @@ void CSettings::AddHowToHandleSetting () AddHandler(UseInstantDirSelected, new CSettingTypeApplication("Directory","Use Default Instant Dir", InitialPluginDirectory)); AddHandler(UseSnapShotDirSelected, new CSettingTypeApplication("Directory","Use Default Snap Shot Dir", InitialPluginDirectory)); /* - INFO(ApplicationDir,No_Default,Data_String,RelativePath,"","",0); + INFO(ApplicationDir,Default_None,Data_String,RelativePath,"","",0); */ //Debugger - AddHandler(Debugger, new CSettingTypeApplication("Debugger","Debugger",false)); +/* AddHandler(Debugger, new CSettingTypeApplication("Debugger","Debugger",false)); AddHandler(ShowUnhandledMemory, new CSettingTypeApplication("Debugger","Show Unhandled Memory",false)); AddHandler(ShowPifErrors, new CSettingTypeApplication("Debugger","Show Pif Errors",false)); AddHandler(ShowDListAListCount, new CSettingTypeApplication("Debugger","Show Dlist Alist Count",false)); @@ -288,12 +483,15 @@ void CSettings::AddHowToHandleSetting () AddHandler(UseHighLevelAudio, new CSettingTypeApplication("Plugin Directory","RSP",false)); AddHandler(UseHighLevelGfx, new CSettingTypeApplication("Plugin Directory","RSP",true)); - //Idvidual Game Settings + //Indvidual Game Settings + AddHandler(Game_SaveChip, new CSettingTypeGame("","SaveChip",Rdb_SaveChip)); + + /* INFO(Game_LastSaveSlot,Default_SaveSlot,Data_DWORD,GameSetting,"Last Used Save Slot","",0); //Rom Settings */ - AddHandler(ROM_IniKey, new CSettingTypeTempString("")); +/* AddHandler(ROM_IniKey, new CSettingTypeTempString("")); AddHandler(ROM_NAME, new CSettingTypeTempString("")); //AddHandler(ROM_Default, new CSettingTypeTempNumber(-1)); AddHandler(ROM_MD5, new CSettingTypeRomDatabase("MD5","")); @@ -332,7 +530,7 @@ void CSettings::AddHowToHandleSetting () /* for (count = ROM_MD5 + 1; count != ROM_LastMD5; count++ ) { char Name[300]; _snprintf(Name,sizeof(Name),"MD5%d",count - ROM_LastMD5); - INFO((SettingID)count,No_Default,Data_String,RomSetting,Name,"",0); + INFO((SettingID)count,Default_None,Data_String,RomSetting,Name,"",0); } //System Settings @@ -348,42 +546,40 @@ void CSettings::AddHowToHandleSetting () INFO(SYSTEM_SMM_Protect, Default_False, Data_DWORD, SettingLoc,"SMM-Protect","",0); */ // Verifier - AddHandler(BetaUserNameMD5, new CSettingTypeTempString("CBBABA8D2262FF1F7A47CEAD87FC4304")); - AddHandler(BetaEmailAddressMD5, new CSettingTypeTempString("47A3D7CBF1DA291D5EB30DCAAF21B9F8")); - +/* //Currrent Running Information AddHandler(CPU_Paused, new CSettingTypeTempBool(false)); - AddHandler(CPU_Paused_type, new CSettingTypeTempNumber(No_Default)); -/* INFO(RamSize, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(CPUType, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(BlockLinking, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(DelayDlists, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(DelaySI, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(CounterFactor, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(UseJumpTable, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(RomInMemory, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(SyncViaAudio, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(UseTLB, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(AudioSignal, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(FuncLookupMode, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(ApplicationName, No_Default, Data_String, TemporarySetting,"","",0); - INFO(SaveChipType, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(FirstDMA, No_Default, Data_DWORD, TemporarySetting,"","",0); + AddHandler(CPU_Paused_type, new CSettingTypeTempNumber(Default_None)); +/* INFO(RamSize, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(CPUType, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(BlockLinking, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(DelayDlists, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(DelaySI, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(CounterFactor, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(UseJumpTable, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(RomInMemory, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(SyncViaAudio, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(UseTLB, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(AudioSignal, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(FuncLookupMode, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(ApplicationName, Default_None, Data_String, TemporarySetting,"","",0); + INFO(SaveChipType, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(FirstDMA, Default_None, Data_DWORD, TemporarySetting,"","",0); INFO(ShowPifErrors, Default_True, Data_DWORD, TemporarySetting,"","",0); - INFO(CurrentSaveState,No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(InstantSaveFile, No_Default, Data_String, TemporarySetting,"","",0); + INFO(CurrentSaveState,Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(InstantSaveFile, Default_None, Data_String, TemporarySetting,"","",0); */ - AddHandler(CurrentSaveState, new CSettingTypeTempNumber(0)); +/* AddHandler(CurrentSaveState, new CSettingTypeTempNumber(0)); AddHandler(LoadingRom, new CSettingTypeTempBool(false)); AddHandler(CPU_Running, new CSettingTypeTempBool(false)); AddHandler(ScreenHertz, new CSettingTypeTempNumber(60)); AddHandler(InFullScreen, new CSettingTypeTempBool(false)); /* INFO(InFullScreen, Default_False, Data_DWORD, TemporarySetting,"","",0); - INFO(SMM_Cache, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(SMM_PIDMA, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(SMM_TLB, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(SMM_Protect, No_Default, Data_DWORD, TemporarySetting,"","",0); - INFO(SMM_ValidFunc, No_Default, Data_DWORD, TemporarySetting,"","",0); + INFO(SMM_Cache, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(SMM_PIDMA, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(SMM_TLB, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(SMM_Protect, Default_None, Data_DWORD, TemporarySetting,"","",0); + INFO(SMM_ValidFunc, Default_None, Data_DWORD, TemporarySetting,"","",0); #undef INFO */ @@ -397,55 +593,52 @@ DWORD CSettings::GetSetting ( CSettings * _this, SettingID Type ) const char * CSettings::GetSettingSz ( CSettings * _this, SettingID Type, char * Buffer, int BufferSize ) { - Notify().BreakPoint(__FILE__,__LINE__); -/* if (Buffer && BufferSize > 0) + if (Buffer && BufferSize > 0) { Buffer[0] = 0; - _this->Load(Type, Buffer, BufferSize); - }*/ + _this->LoadString(Type, Buffer,BufferSize); + } return Buffer; } void CSettings::SetSetting ( CSettings * _this, SettingID ID, unsigned int Value ) { - Notify().BreakPoint(__FILE__,__LINE__); -// _this->SaveDword(ID,Value); + _this->SaveDword(ID,Value); } void CSettings::SetSettingSz ( CSettings * _this, SettingID ID, const char * Value ) { - Notify().BreakPoint(__FILE__,__LINE__); -// _this->SaveString(ID,Value); + _this->SaveString(ID,Value); } -void CSettings::RegisterSetting ( CSettings * _this, SettingID ID, SettingID DefaultID, SettingDataType Type, - SettingLocation Location, const char * Category, const char * DefaultStr, +void CSettings::RegisterSetting ( CSettings * _this, SettingID ID, SettingID DefaultID, SettingDataType DataType, + SettingType Type, const char * Category, const char * DefaultStr, DWORD Value ) { - switch (Location) + switch (Type) { - case SettingLocation_ConstValue: - if (Type != Data_DWORD) + case SettingType_ConstValue: + if (DataType != Data_DWORD) { Notify().BreakPoint(__FILE__,__LINE__); return; } _this->AddHandler(ID,new CSettingTypeTempNumber(Value)); break; - case SettingLocation_ConstString: - if (Type != Data_String) + case SettingType_ConstString: + if (DataType != Data_String) { Notify().BreakPoint(__FILE__,__LINE__); return; } _this->AddHandler(ID,new CSettingTypeTempString(DefaultStr)); break; - case SettingLocation_CfgFile: - case SettingLocation_Registry: - switch (Type) + case SettingType_CfgFile: + case SettingType_Registry: + switch (DataType) { case Data_DWORD: - if (DefaultID == No_Default) + if (DefaultID == Default_None) { _this->AddHandler(ID,new CSettingTypeApplication(Category,DefaultStr,Value)); } else { @@ -453,7 +646,7 @@ void CSettings::RegisterSetting ( CSettings * _this, SettingID ID, SettingID Def } break; case Data_String: - if (DefaultID == No_Default) + if (DefaultID == Default_None) { _this->AddHandler(ID,new CSettingTypeApplication(Category,DefaultStr,"")); } else { @@ -464,17 +657,48 @@ void CSettings::RegisterSetting ( CSettings * _this, SettingID ID, SettingID Def Notify().BreakPoint(__FILE__,__LINE__); } break; - case SettingLocation_GameSetting: - switch (Type) + case SettingType_GameSetting: + switch (DataType) { case Data_DWORD: - if (DefaultID == No_Default) + if (DefaultID == Default_None) { _this->AddHandler(ID,new CSettingTypeGame(Category,DefaultStr,Value)); } else { _this->AddHandler(ID,new CSettingTypeGame(Category,DefaultStr,DefaultID)); } break; + case Data_String: + if (DefaultID == Default_None) + { + _this->AddHandler(ID,new CSettingTypeGame(Category,DefaultStr,"")); + } else { + _this->AddHandler(ID,new CSettingTypeGame(Category,DefaultStr,DefaultID)); + } + break; + default: + Notify().BreakPoint(__FILE__,__LINE__); + } + break; + case SettingType_RomDatabase: + switch (DataType) + { + case Data_DWORD: + if (DefaultID == Default_None) + { + _this->AddHandler(ID,new CSettingTypeRomDatabase(DefaultStr,(int)Value)); + } else { + _this->AddHandler(ID,new CSettingTypeRomDatabase(DefaultStr,(SettingID)Value)); + } + break; + case Data_String: + if (DefaultID == Default_None) + { + _this->AddHandler(ID,new CSettingTypeRomDatabase(DefaultStr,"")); + } else { + _this->AddHandler(ID,new CSettingTypeRomDatabase(DefaultStr,DefaultID)); + } + break; default: Notify().BreakPoint(__FILE__,__LINE__); } @@ -506,61 +730,21 @@ bool CSettings::Initilize( const char * AppName ) AddHowToHandleSetting(); CSettingTypeApplication::Initilize(AppName); CSettingTypeRomDatabase::Initilize(); + CSettingTypeGame::Initilize(); + CSettingTypeCheats::Initilize(); -/* strncpy(Registrylocation,"Software\\N64 Emulation\\",sizeof(Registrylocation)); - strncat(Registrylocation,AppName,sizeof(Registrylocation)); - RegistryKey = (int)HKEY_CURRENT_USER; - - if (SettingInfo.size() == 0) { - AddHowToHandleSetting(); - } - - _Settings->SaveString(ApplicationName,AppName); - - RomIniFile = new CIniFile(LoadString(IniName).c_str()); - CheatIniFile = new CIniFile(LoadString(CheatIniName).c_str()); -*/ + _Settings->SaveString(Setting_ApplicationName,AppName); return true; } bool CSettings::LoadBool ( SettingID Type ) { - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } bool Value = false; - if (FindInfo->second->IndexBasedSetting()) - { - Notify().BreakPoint(__FILE__,__LINE__); - } else { - FindInfo->second->Load(0,Value); - } + LoadBool(Type,Value); return Value; } bool CSettings::LoadBool ( SettingID Type, bool & Value ) -{ - Notify().BreakPoint(__FILE__,__LINE__); - return false; -} - -bool CSettings::LoadBoolIndex( SettingID Type, int index ) -{ - Notify().BreakPoint(__FILE__,__LINE__); - return false; -} - -bool CSettings::LoadBoolIndex( SettingID Type, int index , bool & Value ) -{ - Notify().BreakPoint(__FILE__,__LINE__); - return false; -} - -DWORD CSettings::LoadDword ( SettingID Type ) { SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); if (FindInfo == m_SettingInfo.end()) @@ -569,13 +753,44 @@ DWORD CSettings::LoadDword ( SettingID Type ) UnknownSetting(Type); return 0; } - DWORD Value = 0; if (FindInfo->second->IndexBasedSetting()) { Notify().BreakPoint(__FILE__,__LINE__); } else { - FindInfo->second->Load(0,Value); + return FindInfo->second->Load(0,Value); } + return false; +} + +bool CSettings::LoadBoolIndex( SettingID Type, int index ) +{ + bool Value = false; + LoadBoolIndex(Type,index,Value); + return Value; +} + +bool CSettings::LoadBoolIndex( SettingID Type, int index , bool & Value ) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return false; + } + if (FindInfo->second->IndexBasedSetting()) + { + return FindInfo->second->Load(index,Value); + } else { + Notify().BreakPoint(__FILE__,__LINE__); + } + return false; +} + +DWORD CSettings::LoadDword ( SettingID Type ) +{ + DWORD Value = 0; + LoadDword(Type,Value); return Value; } @@ -592,32 +807,15 @@ bool CSettings::LoadDword ( SettingID Type, DWORD & Value) { Notify().BreakPoint(__FILE__,__LINE__); } else { - DWORD TempValue = 0; - if (FindInfo->second->Load(0,TempValue)) - { - Value = TempValue; - return true; - } + return FindInfo->second->Load(0,Value); } return false; } DWORD CSettings::LoadDwordIndex( SettingID Type, int index) { - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } - DWORD Value = 0; - if (FindInfo->second->IndexBasedSetting()) - { - FindInfo->second->Load(index,Value); - } else { - Notify().BreakPoint(__FILE__,__LINE__); - } + DWORD Value; + LoadDwordIndex(Type,index,Value); return Value; } @@ -632,12 +830,7 @@ bool CSettings::LoadDwordIndex( SettingID Type, int index, DWORD & Value) } if (FindInfo->second->IndexBasedSetting()) { - DWORD TempValue = 0; - if (FindInfo->second->Load(index,TempValue)) - { - Value = TempValue; - return true; - } + return FindInfo->second->Load(index,Value); } else { Notify().BreakPoint(__FILE__,__LINE__); } @@ -646,20 +839,8 @@ bool CSettings::LoadDwordIndex( SettingID Type, int index, DWORD & Value) stdstr CSettings::LoadString ( SettingID Type ) { - SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); - if (FindInfo == m_SettingInfo.end()) - { - //if not found do nothing - UnknownSetting(Type); - return 0; - } stdstr Value; - if (FindInfo->second->IndexBasedSetting()) - { - Notify().BreakPoint(__FILE__,__LINE__); - } else { - FindInfo->second->Load(0,Value); - } + LoadString(Type,Value); return Value; } @@ -683,11 +864,38 @@ bool CSettings::LoadString ( SettingID Type, stdstr & Value ) bool CSettings::LoadString ( SettingID Type, char * Buffer, int BufferSize ) { - Notify().BreakPoint(__FILE__,__LINE__); - return false; + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return 0; + } + bool bRes = false; + if (FindInfo->second->IndexBasedSetting()) + { + Notify().BreakPoint(__FILE__,__LINE__); + } else { + stdstr Value; + bRes = FindInfo->second->Load(0,Value); + int len = BufferSize; + if ((Value.length() + 1) < len) + { + len = Value.length() + 1; + } + strncpy(Buffer,Value.c_str(),len); + } + return bRes; } stdstr CSettings::LoadStringIndex ( SettingID Type, int index ) +{ + stdstr Value; + LoadStringIndex(Type,index,Value); + return Value; +} + +bool CSettings::LoadStringIndex ( SettingID Type, int index, stdstr & Value ) { SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); if (FindInfo == m_SettingInfo.end()) @@ -696,19 +904,12 @@ stdstr CSettings::LoadStringIndex ( SettingID Type, int index ) UnknownSetting(Type); return 0; } - stdstr Value; if (FindInfo->second->IndexBasedSetting()) { - FindInfo->second->Load(index,Value); + return FindInfo->second->Load(index,Value); } else { Notify().BreakPoint(__FILE__,__LINE__); } - return Value; -} - -bool CSettings::LoadStringIndex ( SettingID Type, int index, stdstr & Value ) -{ - Notify().BreakPoint(__FILE__,__LINE__); return false; } @@ -718,14 +919,156 @@ bool CSettings::LoadStringIndex ( SettingID Type, int index, char * Buffer, int return false; } -void CSettings::SaveBool ( SettingID Type, bool Value ) +//Load the default value for the setting +bool CSettings::LoadDefaultBool ( SettingID Type ) +{ + bool Value = false; + LoadDefaultBool(Type,Value); + return Value; +} + +void CSettings::LoadDefaultBool ( SettingID Type, bool & Value ) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } else { + if (FindInfo->second->IndexBasedSetting()) + { + Notify().BreakPoint(__FILE__,__LINE__); + } else { + FindInfo->second->LoadDefault(0,Value); + } + } +} + +bool CSettings::LoadDefaultBoolIndex ( SettingID Type, int index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +void CSettings::LoadDefaultBoolIndex ( SettingID Type, int index , bool & Value ) { Notify().BreakPoint(__FILE__,__LINE__); } -void CSettings::SaveBoolIndex( SettingID Type, int index, bool Value ) +DWORD CSettings::LoadDefaultDword ( SettingID Type ) +{ + DWORD Value = 0; + LoadDefaultDword(Type,Value); + return Value; +} + +void CSettings::LoadDefaultDword ( SettingID Type, DWORD & Value) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } else { + if (FindInfo->second->IndexBasedSetting()) + { + Notify().BreakPoint(__FILE__,__LINE__); + } else { + FindInfo->second->LoadDefault(0,Value); + } + } +} + +DWORD CSettings::LoadDefaultDwordIndex ( SettingID Type, int index ) { Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +void CSettings::LoadDefaultDwordIndex ( SettingID Type, int index, DWORD & Value) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +stdstr CSettings::LoadDefaultString ( SettingID Type ) +{ + stdstr Value; + LoadDefaultString(Type,Value); + return Value; +} + +void CSettings::LoadDefaultString ( SettingID Type, stdstr & Value ) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } else { + if (FindInfo->second->IndexBasedSetting()) + { + Notify().BreakPoint(__FILE__,__LINE__); + } else { + FindInfo->second->LoadDefault(0,Value); + } + } +} + +void CSettings::LoadDefaultString ( SettingID Type, char * Buffer, int BufferSize ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +stdstr CSettings::LoadDefaultStringIndex ( SettingID Type, int index ) +{ + Notify().BreakPoint(__FILE__,__LINE__); + return false; +} + +void CSettings::LoadDefaultStringIndex ( SettingID Type, int index, stdstr & Value ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettings::LoadDefaultStringIndex ( SettingID Type, int index, char * Buffer, int BufferSize ) +{ + Notify().BreakPoint(__FILE__,__LINE__); +} + +void CSettings::SaveBool ( SettingID Type, bool Value ) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + Notify().BreakPoint(__FILE__,__LINE__); + } else { + FindInfo->second->Save(0,Value); + } + NotifyCallBacks(Type); +} + +void CSettings::SaveBoolIndex( SettingID Type, int index, bool Value ) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + FindInfo->second->Save(index,Value); + } else { + Notify().BreakPoint(__FILE__,__LINE__); + } + NotifyCallBacks(Type); } void CSettings::SaveDword ( SettingID Type, DWORD Value ) @@ -764,9 +1107,22 @@ void CSettings::SaveDwordIndex ( SettingID Type, int index, DWORD Value ) NotifyCallBacks(Type); } -void CSettings::SaveString ( SettingID Type, const stdstr & value ) +void CSettings::SaveString ( SettingID Type, const stdstr & Value ) { - Notify().BreakPoint(__FILE__,__LINE__); + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + return; + } + if (FindInfo->second->IndexBasedSetting()) + { + Notify().BreakPoint(__FILE__,__LINE__); + } else { + FindInfo->second->Save(0,Value); + } + NotifyCallBacks(Type); } void CSettings::SaveString ( SettingID Type, const char * Buffer ) @@ -788,10 +1144,27 @@ void CSettings::SaveString ( SettingID Type, const char * Buffer ) void CSettings::SaveStringIndex( SettingID Type, int index, const char * Buffer ) { - Notify().BreakPoint(__FILE__,__LINE__); + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + if (FindInfo->second->IndexBasedSetting()) + { + FindInfo->second->Save(index,Buffer); + } else { + Notify().BreakPoint(__FILE__,__LINE__); + } + NotifyCallBacks(Type); } void CSettings::SaveStringIndex( SettingID Type, int index, const stdstr & Value ) +{ + SaveStringIndex(Type,index,Value.c_str()); +} + +void CSettings::DeleteSetting( SettingID Type ) { SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); if (FindInfo == m_SettingInfo.end()) @@ -801,13 +1174,67 @@ void CSettings::SaveStringIndex( SettingID Type, int index, const stdstr & Value } if (FindInfo->second->IndexBasedSetting()) { - FindInfo->second->Save(index,Value); + Notify().BreakPoint(__FILE__,__LINE__); + } else { + FindInfo->second->Delete(0); + } + NotifyCallBacks(Type); +} + +void CSettings::DeleteSettingIndex( SettingID Type, int index ) +{ + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + //if not found do nothing + UnknownSetting(Type); + } + if (FindInfo->second->IndexBasedSetting()) + { + FindInfo->second->Delete(index); } else { Notify().BreakPoint(__FILE__,__LINE__); } NotifyCallBacks(Type); } +SettingType CSettings::GetSettingType ( SettingID Type ) +{ + if (Type == Default_None || Type == Default_Constant) + { + return SettingType_Unknown; + } + + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + return SettingType_Unknown; + } + return FindInfo->second->GetSettingType(); +} + +bool CSettings::IndexBasedSetting ( SettingID Type ) +{ + + SETTING_HANDLER FindInfo = m_SettingInfo.find(Type); + if (FindInfo == m_SettingInfo.end()) + { + return false; + } + return FindInfo->second->IndexBasedSetting(); +} + + +void CSettings::SettingTypeChanged( SettingType Type ) +{ + for (SETTING_MAP::iterator iter = m_SettingInfo.begin(); iter != m_SettingInfo.end(); iter++) + { + if (iter->second->GetSettingType() == Type) + { + NotifyCallBacks(iter->first); + } + } +} void CSettings::UnknownSetting (SettingID Type) { #ifdef _DEBUG @@ -846,7 +1273,7 @@ void CSettings::Load(SettingID Type, char * Buffer, int BufferSize) { } CSettingInfo * Info = &FindInfo->second; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { Load(Info->DefaultValue,Buffer, BufferSize); } //Copy Default String @@ -916,7 +1343,7 @@ void CSettings::Load(SettingID Type, char * Buffer, int BufferSize) { lResult = RegQueryValueEx(hKeyResults,Info->Name.c_str(),0,&RegType,(LPBYTE)(Buffer),&Bytes); if (RegType != REG_SZ || lResult != ERROR_SUCCESS) { //Reload Defaults just in case data has changed - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { Load(Info->DefaultValue,Buffer, BufferSize); } } @@ -1064,7 +1491,7 @@ void CSettings::Load(SettingID Type, DWORD & Value) } CSettingInfo * Info = &FindInfo->second; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { Load(Info->DefaultValue,Value); } if (Info->Location == ConstValue) { @@ -1273,7 +1700,7 @@ void CSettings::SaveString(SettingID Type, const char * Buffer) { if (CheatIniFile == NULL) { return; } if (Info->DataType == Data_String) { stdstr DefaultValue; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { DefaultValue = LoadString(Info->DefaultValue); } if (DefaultValue == Buffer) { @@ -1300,7 +1727,7 @@ void CSettings::SaveString(SettingID Type, const char * Buffer) { } stdstr DefaultValue; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { DefaultValue = LoadString(Info->DefaultValue); } @@ -1321,7 +1748,7 @@ void CSettings::SaveString(SettingID Type, const char * Buffer) { } else if (Info->Location == LocalSettings) { if (SettingsIniFile == NULL) { return; } stdstr DefaultValue; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { DefaultValue = LoadString(Info->DefaultValue); } stdstr_f Ident("%s",Info->SubNode.c_str()); @@ -1365,7 +1792,7 @@ void CSettings::SaveDword(SettingID Type, DWORD Value) { if (SettingsIniFile == NULL) { return; } DWORD DefaultValue = 0; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { Load(Info->DefaultValue,DefaultValue); } stdstr_f Ident("%s",Info->SubNode.c_str()); @@ -1375,7 +1802,7 @@ void CSettings::SaveDword(SettingID Type, DWORD Value) { } Ident.replace("\\","-"); - if (Info->DefaultValue != No_Default && Value == DefaultValue) { + if (Info->DefaultValue != Default_None && Value == DefaultValue) { SettingsIniFile->SaveString(Ident.c_str(),Info->Name.c_str(),NULL); } else { SettingsIniFile->SaveNumber(Ident.c_str(),Info->Name.c_str(),Value); @@ -1405,10 +1832,10 @@ void CSettings::SaveDword(SettingID Type, DWORD Value) { if (RomIniFile == NULL) { return; } if (Info->DataType == Data_DWORD) { DWORD DefaultValue = 0; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { Load(Info->DefaultValue,DefaultValue); } - if (Info->DefaultValue != No_Default && Value == DefaultValue) { + if (Info->DefaultValue != Default_None && Value == DefaultValue) { RomIniFile->SaveString(LoadString(ROM_IniKey).c_str(),Info->Name.c_str(),NULL); } else { RomIniFile->SaveNumber(LoadString(ROM_IniKey).c_str(),Info->Name.c_str(),Value); @@ -1446,10 +1873,10 @@ void CSettings::SaveDword(SettingID Type, DWORD Value) { // RomIniFile->SaveString(LoadString(ROM_IniKey).c_str(),Info->Name.c_str(),String); } else if (Info->DataType == Data_YesNo) { DWORD DefaultValue = 0; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { Load(Info->DefaultValue,DefaultValue); } - if (Info->DefaultValue != No_Default && Value == DefaultValue) { + if (Info->DefaultValue != Default_None && Value == DefaultValue) { RomIniFile->SaveString(LoadString(ROM_IniKey).c_str(),Info->Name.c_str(),NULL); } else { RomIniFile->SaveString(LoadString(ROM_IniKey).c_str(),Info->Name.c_str(),Value ? "Yes" : "No"); @@ -1486,11 +1913,11 @@ void CSettings::SaveDword(SettingID Type, DWORD Value) { } DWORD DefaultValue = 0; - if (Info->DefaultValue != No_Default) { + if (Info->DefaultValue != Default_None) { Load(Info->DefaultValue,DefaultValue); } - if (Info->DefaultValue != No_Default && Value == DefaultValue) { + if (Info->DefaultValue != Default_None && Value == DefaultValue) { SettingsIniFile->SaveString(Ident,Info->Name.c_str(),NULL); } else { SettingsIniFile->SaveNumber(Ident,Info->Name.c_str(),Value); diff --git a/Source/Project64/Settings/Settings Class.h b/Source/Project64/Settings/Settings Class.h index fe4cd0c29..aeb22f409 100644 --- a/Source/Project64/Settings/Settings Class.h +++ b/Source/Project64/Settings/Settings Class.h @@ -217,46 +217,68 @@ public: bool Initilize ( const char * AppName ); -// void Config (void * ParentWindow, CN64System * System, CMainGui * Gui); -// void ConfigRom (void * ParentWindow, CMainGui * Gui); - //return the values - bool LoadBool ( SettingID Type ); - bool LoadBool ( SettingID Type, bool & Value ); - bool LoadBoolIndex ( SettingID Type, int index ); - bool LoadBoolIndex ( SettingID Type, int index , bool & Value ); - DWORD LoadDword ( SettingID Type ); - bool LoadDword ( SettingID Type, DWORD & Value); - DWORD LoadDwordIndex ( SettingID Type, int index ); - bool LoadDwordIndex ( SettingID Type, int index, DWORD & Value); - stdstr LoadString ( SettingID Type ); - bool LoadString ( SettingID Type, stdstr & Value ); - bool LoadString ( SettingID Type, char * Buffer, int BufferSize ); - stdstr LoadStringIndex ( SettingID Type, int index ); - bool LoadStringIndex ( SettingID Type, int index, stdstr & Value ); - bool LoadStringIndex ( SettingID Type, int index, char * Buffer, int BufferSize ); + bool LoadBool ( SettingID Type ); + bool LoadBool ( SettingID Type, bool & Value ); + bool LoadBoolIndex ( SettingID Type, int index ); + bool LoadBoolIndex ( SettingID Type, int index , bool & Value ); + DWORD LoadDword ( SettingID Type ); + bool LoadDword ( SettingID Type, DWORD & Value); + DWORD LoadDwordIndex ( SettingID Type, int index ); + bool LoadDwordIndex ( SettingID Type, int index, DWORD & Value); + stdstr LoadString ( SettingID Type ); + bool LoadString ( SettingID Type, stdstr & Value ); + bool LoadString ( SettingID Type, char * Buffer, int BufferSize ); + stdstr LoadStringIndex ( SettingID Type, int index ); + bool LoadStringIndex ( SettingID Type, int index, stdstr & Value ); + bool LoadStringIndex ( SettingID Type, int index, char * Buffer, int BufferSize ); + + //Load the default value for the setting + bool LoadDefaultBool ( SettingID Type ); + void LoadDefaultBool ( SettingID Type, bool & Value ); + bool LoadDefaultBoolIndex ( SettingID Type, int index ); + void LoadDefaultBoolIndex ( SettingID Type, int index , bool & Value ); + DWORD LoadDefaultDword ( SettingID Type ); + void LoadDefaultDword ( SettingID Type, DWORD & Value); + DWORD LoadDefaultDwordIndex ( SettingID Type, int index ); + void LoadDefaultDwordIndex ( SettingID Type, int index, DWORD & Value); + stdstr LoadDefaultString ( SettingID Type ); + void LoadDefaultString ( SettingID Type, stdstr & Value ); + void LoadDefaultString ( SettingID Type, char * Buffer, int BufferSize ); + stdstr LoadDefaultStringIndex ( SettingID Type, int index ); + void LoadDefaultStringIndex ( SettingID Type, int index, stdstr & Value ); + void LoadDefaultStringIndex ( SettingID Type, int index, char * Buffer, int BufferSize ); //Update the settings - void SaveBool ( SettingID Type, bool Value ); - void SaveBoolIndex ( SettingID Type, int index, bool Value ); - void SaveDword ( SettingID Type, DWORD Value ); - void SaveDwordIndex ( SettingID Type, int index, DWORD Value ); - void SaveString ( SettingID Type, const stdstr & Value ); - void SaveStringIndex ( SettingID Type, int index, const stdstr & Value ); - void SaveString ( SettingID Type, const char * Buffer ); - void SaveStringIndex ( SettingID Type, int index, const char * Buffer ); + void SaveBool ( SettingID Type, bool Value ); + void SaveBoolIndex ( SettingID Type, int index, bool Value ); + void SaveDword ( SettingID Type, DWORD Value ); + void SaveDwordIndex ( SettingID Type, int index, DWORD Value ); + void SaveString ( SettingID Type, const stdstr & Value ); + void SaveStringIndex ( SettingID Type, int index, const stdstr & Value ); + void SaveString ( SettingID Type, const char * Buffer ); + void SaveStringIndex ( SettingID Type, int index, const char * Buffer ); + // Delete a setting + void DeleteSetting ( SettingID Type ); + void DeleteSettingIndex ( SettingID Type, int index ); + //Register Notification of change - void RegisterChangeCB(SettingID Type,void * Data, SettingChangedFunc Func); - void UnregisterChangeCB(SettingID Type,void * Data, SettingChangedFunc Func); + void RegisterChangeCB ( SettingID Type, void * Data, SettingChangedFunc Func); + void UnregisterChangeCB ( SettingID Type, void * Data, SettingChangedFunc Func); + + // information about setting + SettingType GetSettingType ( SettingID Type ); + bool IndexBasedSetting ( SettingID Type ); + void SettingTypeChanged ( SettingType Type ); // static functions for plugins static DWORD GetSetting ( CSettings * _this, SettingID Type ); static LPCSTR GetSettingSz ( CSettings * _this, SettingID Type, char * Buffer, int BufferSize ); static void SetSetting ( CSettings * _this, SettingID ID, unsigned int Value ); static void SetSettingSz ( CSettings * _this, SettingID ID, const char * Value ); - static void RegisterSetting ( CSettings * _this, SettingID ID, SettingID DefaultID, SettingDataType Type, - SettingLocation Location, const char * Category, const char * DefaultStr, + static void RegisterSetting ( CSettings * _this, SettingID ID, SettingID DefaultID, SettingDataType DataType, + SettingType Type, const char * Category, const char * DefaultStr, DWORD Value ); private: void NotifyCallBacks ( SettingID Type ); diff --git a/Source/Project64/Settings/vssver2.scc b/Source/Project64/Settings/vssver2.scc deleted file mode 100644 index f0d859e6fa728a6b3c7b2886f13fc9f8fd717724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 478 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAOGui)tW#>BwD&A`A=%*?>Bbw%%`&r=TO3j+Bi zKz?_w>x}M)LOpUoekqXuaF*3y)(Z=b*nxa~76yhx)8#ZIbtK||QVa$_J_FaCo9$EQ zt_LwCco-Pw-ud?8Gy6XypcM>~K)%ajjWQ4)q+SZh4_oDX_(QGwIgom3Apd=XqeOK^ z3oD2}U5tU@wV1QR@SqA?6Kz*=!}u!t0Y&*)smUc~CNP$QnTdj-p1FQ-erZv1 zs(x^4Nl9j2dNBi(q2QdKmzJ5Xmt0T)6Dn44&PgmT#wL`(5R{snpIeZblUk$zGfEG; wD9A*={F2PH%;dz9%=|oL_1MM1I?POhD~n4~b5WFI3WC(Smu4cXLg9ks0k}k*9smFU diff --git a/Source/Project64/Support/vssver2.scc b/Source/Project64/Support/vssver2.scc deleted file mode 100644 index 6e4c9fa4267edacae43527b78edeb36346a74a0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 823 zcmY+<-%C?b902g|<`0Y#qL7M6E?Y6{VZ*gHl0xg+N|xlf(&}-|)6SLc-rK#`p;0lU zdXb3MgQk_Pnu`50YZw@j5EPW8L4`=sKM*}c&{OMsj=MHr?)iT1_k4dG-v%2L4r`HZ z`E>Bghqn(meqHl8)07?`E(6#K05&`)8(iX+GsnDkv>jc2-u9%hsnuJFzJ^Y(zm(Z| zYRX%V&Y;Vx&n_^t{0KV#ccJB_;_sU9SCCb$RDl|k1MGrK>8?wn7##P@mbo9F}mQ!|!t zp%;O^vfgtW?f6vpo0;u1j4r(HEAOt|-@x88g5LbODrL>fqURpD9ag_P=v}0~xGxs!l_QLnEiuo+Be~$iPhi{g*d)johlf+EF&x!=UPpEeXJd)a_$B0Mj z(lk{!K}tq-Q)p9V#U#3$f?;+DhN;U+9MMXW?ZhzMF-=>EDI6!dA*%}iYsC~qT{h)d zG$G+smZfk)vibz&1QEnU)G&C_Q8iwok|c%yDGJGsJ^Z>BH7O5Dc4Hg0>(LnDi55i` wR<&WJ6jUQsT$KWELO~~S8K2jK+2!)$*-TCwt18%lmCFpGrb%RZk77vSA4$yeO#lD@ diff --git a/Source/Project64/User Interface.h b/Source/Project64/User Interface.h index 6d030de5b..48e4bb855 100644 --- a/Source/Project64/User Interface.h +++ b/Source/Project64/User Interface.h @@ -41,10 +41,12 @@ typedef struct { class CN64System; -#include "./WTL App.h" +#include +#include #include ".\\User Interface\\Rom Browser.h" #include ".\\User Interface\\Gui Class.h" #include ".\\User Interface\\Menu Class.h" +#include ".\\User Interface\\Menu Class.h" #include ".\\User Interface\\Main Menu Class.h" #include ".\\User Interface\\Notification Class.h" #include ".\\User Interface\\Frame Per Second Class.h" diff --git a/Source/Project64/User Interface/Bitmaps/vssver2.scc b/Source/Project64/User Interface/Bitmaps/vssver2.scc deleted file mode 100644 index 422ced426c6bfcfe4767f66bd67e8ef0e3e6bf5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 471 zcmXpJVr2O5UJx$3wZX0T{E4-~cRANLOo?Fp#l*nC!@$7M!OXxQBA{zn`OMac5ylqQ(}PMv|lb%W2uDGy@yg4DkU@|7C7R`2gEu>e)AGUcpMd-i6BT1aH*G2ess9Y*&y{s(vibC#1H}IV;{wn3gq8o?Rs*%aNP}%{5K#!H?pQsY}?BxAij!zKv8~HYI2F035=y+W};xIXRaTd zUs{x$svlaMTBP8aSCU$kmI&lJWtQY778ElSWSN=hIr#=KloVy^7MCQJr0ON*7BKi^ z7MFOIq~;cbd5%f>r6s}1MX9NIdIiNP3`l&Z{F0LVTy#~wnJFnb5R;J9hU6E36*}kS r7pHpUm!%dVxPJLXxrsRlen4q)MrsO}?~|C9?(dDnj8Dlg&ja%T1M8ZR diff --git a/Source/Project64/User Interface/Frame Per Second Class.cpp b/Source/Project64/User Interface/Frame Per Second Class.cpp index 38dbf4716..f78a2c35c 100644 --- a/Source/Project64/User Interface/Frame Per Second Class.cpp +++ b/Source/Project64/User Interface/Frame Per Second Class.cpp @@ -6,10 +6,10 @@ CFramePerSecond::CFramePerSecond (CNotification * Notification): _Notify(Notification) { - m_iFrameRateType = _Settings->LoadDword(FrameDisplayType); - m_ScreenHertz = _Settings->LoadDword(ScreenHertz); - _Settings->RegisterChangeCB(FrameDisplayType,this,(CSettings::SettingChangedFunc)FrameRateTypeChanged); - _Settings->RegisterChangeCB(ScreenHertz,this,(CSettings::SettingChangedFunc)ScreenHertzChanged); + m_iFrameRateType = _Settings->LoadDword(UserInterface_FrameDisplayType); + m_ScreenHertz = _Settings->LoadDword(GameRunning_ScreenHertz); + _Settings->RegisterChangeCB(UserInterface_FrameDisplayType,this,(CSettings::SettingChangedFunc)FrameRateTypeChanged); + _Settings->RegisterChangeCB(GameRunning_ScreenHertz,this,(CSettings::SettingChangedFunc)ScreenHertzChanged); if (m_ScreenHertz == 0) { @@ -24,8 +24,8 @@ CFramePerSecond::CFramePerSecond (CNotification * Notification): CFramePerSecond::~CFramePerSecond() { - _Settings->UnregisterChangeCB(FrameDisplayType,this,(CSettings::SettingChangedFunc)FrameRateTypeChanged); - _Settings->UnregisterChangeCB(ScreenHertz,this,(CSettings::SettingChangedFunc)ScreenHertzChanged); + _Settings->UnregisterChangeCB(UserInterface_FrameDisplayType,this,(CSettings::SettingChangedFunc)FrameRateTypeChanged); + _Settings->UnregisterChangeCB(GameRunning_ScreenHertz,this,(CSettings::SettingChangedFunc)ScreenHertzChanged); } void CFramePerSecond::Reset (bool ClearDisplay) { @@ -107,13 +107,13 @@ void CFramePerSecond::DisplayViCounter(DWORD FrameRate) { void CFramePerSecond::FrameRateTypeChanged (CFramePerSecond * _this) { - _this->m_iFrameRateType = _Settings->LoadDword(FrameDisplayType); + _this->m_iFrameRateType = _Settings->LoadDword(UserInterface_FrameDisplayType); _this->Reset(true); } void CFramePerSecond::ScreenHertzChanged (CFramePerSecond * _this) { - _this->m_ScreenHertz = _Settings->LoadDword(ScreenHertz); + _this->m_ScreenHertz = _Settings->LoadDword(GameRunning_ScreenHertz); _this->Reset(true); } diff --git a/Source/Project64/User Interface/Gui Class.cpp b/Source/Project64/User Interface/Gui Class.cpp index 29d2810ef..dc2127278 100644 --- a/Source/Project64/User Interface/Gui Class.cpp +++ b/Source/Project64/User Interface/Gui Class.cpp @@ -44,8 +44,8 @@ CMainGui::CMainGui (const char * WindowTitle, CNotification * Notify, CN64System m_hacked = false; if (_Settings) { - if (MD5(_Settings->LoadString(BetaUserName)).hex_digest() != _Settings->LoadString(BetaUserNameMD5) || - MD5(_Settings->LoadString(BetaEmailAddress)).hex_digest() != _Settings->LoadString(BetaEmailAddressMD5)) + if (MD5(_Settings->LoadString(Beta_UserName)).hex_digest() != _Settings->LoadString(Beta_UserNameMD5) || + MD5(_Settings->LoadString(Beta_EmailAddress)).hex_digest() != _Settings->LoadString(Beta_EmailAddressMD5)) { m_hacked = true; } @@ -66,6 +66,13 @@ CMainGui::CMainGui (const char * WindowTitle, CNotification * Notify, CN64System m_InvalidExeMsg = RegisterWindowMessage("Invalid"); + if (m_System) + { + _Settings->RegisterChangeCB(RomBrowser_Enabled,this,(CSettings::SettingChangedFunc)RomBowserEnabledChanged); + _Settings->RegisterChangeCB(RomBrowser_ColoumnsChanged,this,(CSettings::SettingChangedFunc)RomBowserColoumnsChanged); + _Settings->RegisterChangeCB(RomBrowser_Recursive,this,(CSettings::SettingChangedFunc)RomBrowserRecursiveChanged); + } + //if this fails then it has already been created RegisterWinClass(); Create(WindowTitle); @@ -75,6 +82,12 @@ CMainGui::CMainGui (const char * WindowTitle, CNotification * Notify, CN64System CMainGui::~CMainGui (void) { WriteTrace(TraceDebug,"CMainGui::~CMainGui - start"); + if (m_System) + { + _Settings->UnregisterChangeCB(RomBrowser_Enabled,this,(CSettings::SettingChangedFunc)RomBowserEnabledChanged); + _Settings->UnregisterChangeCB(RomBrowser_ColoumnsChanged,this,(CSettings::SettingChangedFunc)RomBowserColoumnsChanged); + _Settings->UnregisterChangeCB(RomBrowser_Recursive,this,(CSettings::SettingChangedFunc)RomBrowserRecursiveChanged); + } if (m_hMainWindow) { DestroyWindow((HWND)m_hMainWindow); @@ -82,6 +95,33 @@ CMainGui::~CMainGui (void) WriteTrace(TraceDebug,"CMainGui::~CMainGui - Done"); } +void RomBowserEnabledChanged (CMainGui * Gui) +{ + if (Gui && _Settings->LoadBool(RomBrowser_Enabled)) + { + if (!Gui->RomBrowserVisible()) + { + Gui->ShowRomList(); + } + } else { + if (Gui->RomBrowserVisible()) + { + Gui->HideRomList(); + } + } +} + +void RomBowserColoumnsChanged (CMainGui * Gui) +{ + Gui->ResetRomBrowserColomuns(); +} + +void RomBrowserRecursiveChanged (CMainGui * Gui) +{ + Gui->RefreshRomBrowser(); + Gui->HighLightLastRom(); +} + void CMainGui::ChangeWinSize (long width, long height) { CGuard Guard(m_CS); WINDOWPLACEMENT wndpl; @@ -141,7 +181,7 @@ DWORD CALLBACK AboutIniBoxProc (WND_HANDLE WndHandle, DWORD uMsg, DWORD wParam, //RDB Notify().BreakPoint(__FILE__,__LINE__); - stdstr IniFile = _Settings->LoadString(RomDatabaseFile).c_str(); + stdstr IniFile = _Settings->LoadString(SupportFile_RomDatabase).c_str(); SetDlgItemText(hDlg,IDC_RDB,GS(INI_CURRENT_RDB)); GetPrivateProfileString("Meta","Author","",String,sizeof(String),IniFile.c_str()); if (strlen(String) == 0) { @@ -167,7 +207,7 @@ DWORD CALLBACK AboutIniBoxProc (WND_HANDLE WndHandle, DWORD uMsg, DWORD wParam, //Cheat SetDlgItemText(hDlg,IDC_CHT,GS(INI_CURRENT_CHT)); - IniFile = _Settings->LoadString(CheatIniName).c_str(); + IniFile = _Settings->LoadString(SupportFile_Cheats).c_str(); GetPrivateProfileString("Meta","Author","",String,sizeof(String),IniFile.c_str()); if (strlen(String) == 0) { EnableWindow(GetDlgItem(hDlg,IDC_CHT),FALSE); @@ -192,7 +232,7 @@ DWORD CALLBACK AboutIniBoxProc (WND_HANDLE WndHandle, DWORD uMsg, DWORD wParam, //Extended Info SetDlgItemText(hDlg,IDC_RDX,GS(INI_CURRENT_RDX)); - IniFile = _Settings->LoadString(ExtIniName).c_str();; + IniFile = _Settings->LoadString(SupportFile_ExtInfo).c_str();; GetPrivateProfileString("Meta","Author","",String,sizeof(String),IniFile.c_str()); if (strlen(String) == 0) { EnableWindow(GetDlgItem(hDlg,IDC_RDX),FALSE); @@ -388,15 +428,15 @@ void CMainGui::SaveWindowLoc ( void ) if (m_SaveMainWindowPos) { m_SaveMainWindowPos = false; - _Settings->SaveDword(MainWindowTop,m_SaveMainWindowTop); - _Settings->SaveDword(MainWindowLeft,m_SaveMainWindowLeft); + _Settings->SaveDword(UserInterface_MainWindowTop,m_SaveMainWindowTop); + _Settings->SaveDword(UserInterface_MainWindowLeft,m_SaveMainWindowLeft); } if (m_SaveRomBrowserPos) { m_SaveRomBrowserPos = false; - _Settings->SaveDword(RomBrowserTop,m_SaveRomBrowserTop); - _Settings->SaveDword(RomBrowserLeft,m_SaveRomBrowserLeft); + _Settings->SaveDword(RomBrowser_Top,m_SaveRomBrowserTop); + _Settings->SaveDword(RomBrowser_Left,m_SaveRomBrowserLeft); } } @@ -420,8 +460,8 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam //Move the Main window to the location last executed from or center the window int X = (GetSystemMetrics( SM_CXSCREEN ) - _this->Width()) / 2; int Y = (GetSystemMetrics( SM_CYSCREEN ) - _this->Height()) / 2; - _Settings->LoadDword(MainWindowTop,(DWORD &)Y); - _Settings->LoadDword(MainWindowLeft,(DWORD &)X); + _Settings->LoadDword(UserInterface_MainWindowTop,(DWORD &)Y); + _Settings->LoadDword(UserInterface_MainWindowLeft,(DWORD &)X); _this->SetPos(X,Y); _this->ChangeWinSize(640,480); @@ -439,9 +479,9 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam { CMainGui * _this = (CMainGui *)GetProp((HWND)hWnd,"Class"); if (_this && - _this->bCPURunning && - !_Settings->LoadDword(CPU_Paused) && - _Settings->LoadDword(DisableScrSaver)) + _this->bCPURunning() && + !_Settings->LoadBool(GameRunning_CPU_Paused) && + _Settings->LoadDword(Setting_DisableScrSaver)) { return 0; } @@ -487,7 +527,7 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam } } } - if (CGuiSettings::bCPURunning && System) { + if (CGuiSettings::bCPURunning() && System) { CPlugins * Plugins = System->Plugins(); if (Plugins->Gfx() && Plugins->Gfx()->MoveScreen) { WriteTrace(TraceGfxPlugin,"MoveScreen: Starting"); @@ -501,7 +541,7 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam { CMainGui * _this = (CMainGui *)GetProp((HWND)hWnd,"Class"); static DWORD CallCount = 0; - if (!_Settings->LoadDword(IsValidExe)) + if (!_Settings->LoadBool(Beta_IsValidExe)) { if (CallCount == 0) { @@ -565,7 +605,7 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam CMainGui * _this = (CMainGui *)GetProp((HWND)hWnd,"Class"); CN64System * System = _this->m_System; -// if (bCPURunning && Settings->Load(CPU_Paused)) { +// if (bCPURunning() && Settings->Load(CPU_Paused)) { // CPlugins * Plugins = System->Plugins(); // if (Plugins->Gfx()->DrawScreen) { // Plugins->Gfx()->DrawScreen(); @@ -578,7 +618,7 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam { CMainGui * _this = (CMainGui *)GetProp((HWND)hWnd,"Class"); - if (bCPURunning) { + if (bCPURunning()) { CN64System * System = _this->m_System; CPlugins * Plugins = System->Plugins(); if (Plugins && Plugins->Control()->WM_KeyUp) { @@ -591,7 +631,7 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam { CMainGui * _this = (CMainGui *)GetProp((HWND)hWnd,"Class"); - if (bCPURunning) { + if (bCPURunning()) { CN64System * System = _this->m_System; CPlugins * Plugins = System->Plugins(); if (Plugins && Plugins->Control()->WM_KeyDown) { @@ -609,8 +649,8 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam break; } - if (!bCPURunning) { break; } - if (!bAutoSleep) { break; } + if (!bCPURunning()) { break; } + if (!bAutoSleep()) { break; } CN64System * System = _this->m_System; if (System) { @@ -626,8 +666,8 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam break; } - if (!bCPURunning) { break; } - if (!bAutoSleep) { break; } + if (!bCPURunning()) { break; } + if (!bAutoSleep()) { break; } CN64System * System = _this->m_System; if (System) { @@ -643,9 +683,19 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam if (fActive && _this->RomBrowserVisible()) { PostMessage((HWND)hWnd,WM_BORWSER_TOP,0,0); } - if (!bCPURunning) { break; } - if (!bAutoSleep) { break; } + if (!bCPURunning()) { break; } + CN64System * System = _this->m_System; + if (!fActive && _Settings->LoadBool(UserInterface_InFullScreen)) + { + _this->m_Notify->WindowMode(); + if (bAutoSleep() && System) + { + //System->ExternalEvent(PauseCPU_AppLostActiveDelayed ); + } + break; + } + if (!bAutoSleep()) { break; } if (System) { System->ExternalEvent(fActive ? ResumeCPU_AppGainedActive : PauseCPU_AppLostActive ); @@ -716,7 +766,7 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam if (CurrentRom) { CurrentRom->SaveRomSettingID(); } else { - _Settings->SaveString(ROM_NAME,""); + Rom.ClearRomSettingID(); } } break; @@ -756,7 +806,7 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam if (CurrentRom) { CurrentRom->SaveRomSettingID(); } else { - _Settings->SaveString(ROM_NAME,""); + _Settings->SaveString(Game_IniKey,""); } } } else if (_this->m_Menu->ProcessMessage(hWnd,HIWORD(wParam), LOWORD(wParam))) { @@ -769,12 +819,20 @@ DWORD CALLBACK CMainGui::MainGui_Proc (WND_HANDLE hWnd, DWORD uMsg, DWORD wParam case WM_DESTROY: WriteTrace(TraceDebug,"WM_DESTROY - start"); { - CMainGui * _this = (CMainGui *)GetProp((HWND)hWnd,"Class"); + CMainGui * _this = (CMainGui *)GetProp((HWND)hWnd,"Class"); + if (_this->m_Notify) + { + _this->m_Notify->WindowMode(); + } + CN64System * System = _this->m_System; _this->m_hMainWindow = NULL; WriteTrace(TraceDebug,"WM_DESTROY - 1"); - _this->SaveRomListColoumnInfo(); - WriteTrace(TraceDebug,"WM_DESTROY - 2"); - _this->SaveWindowLoc(); + if (System) + { + _this->SaveRomListColoumnInfo(); + WriteTrace(TraceDebug,"WM_DESTROY - 2"); + _this->SaveWindowLoc(); + } } WriteTrace(TraceDebug,"WM_DESTROY - 3"); RemoveProp((HWND)hWnd,"Class"); diff --git a/Source/Project64/User Interface/Gui Class.h b/Source/Project64/User Interface/Gui Class.h index 334e7b426..648300b19 100644 --- a/Source/Project64/User Interface/Gui Class.h +++ b/Source/Project64/User Interface/Gui Class.h @@ -50,6 +50,10 @@ class CMainGui : friend DWORD CALLBACK AboutIniBoxProc ( WND_HANDLE, DWORD, DWORD, DWORD ); static DWORD CALLBACK MainGui_Proc ( WND_HANDLE, DWORD, DWORD, DWORD ); + friend void RomBowserEnabledChanged (CMainGui * Gui); + friend void RomBowserColoumnsChanged (CMainGui * Gui); + friend void RomBrowserRecursiveChanged (CMainGui * Gui); + public: CMainGui ( const char * WindowTitle = "", CNotification * Notify = 0, CN64System * System = 0 ); ~CMainGui ( void ); diff --git a/Source/Project64/User Interface/Icons/vssver2.scc b/Source/Project64/User Interface/Icons/vssver2.scc deleted file mode 100644 index 65af6577c70a58737f664579a11045118421e782..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAM^Xn)-On~8yem4Shwi zcjRe`{prIko+!D28M%uT_u&zY{BYx1NoN0#ZoZ+D*6FM z`B|ySC1xftmV%jyf}x(desF$iQF5w&XmM(hf@fYyYEfDukn5S8pI6L~lbTkdmzkW; l5a4BIqUY)C&rp<^o&ga`$t=rENiEV#E-hlnNX$zCGXPRCLtp>^ diff --git a/Source/Project64/User Interface/Main Menu Class.cpp b/Source/Project64/User Interface/Main Menu Class.cpp index c2fb57d71..5d5989fd0 100644 --- a/Source/Project64/User Interface/Main Menu Class.cpp +++ b/Source/Project64/User Interface/Main Menu Class.cpp @@ -1,6 +1,7 @@ #include "..\\User Interface.h" #include "..\\N64 System.h" #include "..\\Plugin.h" +#include "..\\User Interface\\Settings Config.h" #include #include "..\\3rd Party\\HTML Help\\HTMLHELP.H" #include @@ -14,10 +15,44 @@ CMainMenu::CMainMenu ( CMainGui * hMainWindow, CN64System * N64System ): ResetMenu(); hMainWindow->SetWindowMenu(this); + + m_ChangeSettingList.push_back(Info_ShortCutsChanged); + m_ChangeSettingList.push_back(GameRunning_LimitFPS); + m_ChangeSettingList.push_back(UserInterface_InFullScreen); + m_ChangeSettingList.push_back(UserInterface_AlwaysOnTop); + m_ChangeSettingList.push_back(UserInterface_ShowCPUPer); + m_ChangeSettingList.push_back(Debugger_ProfileCode); + m_ChangeSettingList.push_back(Debugger_ShowUnhandledMemory); + m_ChangeSettingList.push_back(Debugger_ShowPifErrors); + m_ChangeSettingList.push_back(Debugger_ShowDListAListCount); + m_ChangeSettingList.push_back(Debugger_ShowRecompMemSize); + m_ChangeSettingList.push_back(Debugger_ShowCheckOpUsageErrors); + m_ChangeSettingList.push_back(Debugger_GenerateLogFiles); + m_ChangeSettingList.push_back(Debugger_DisableGameFixes); + m_ChangeSettingList.push_back(Debugger_AppLogLevel); + m_ChangeSettingList.push_back(Debugger_AppLogFlush); + m_ChangeSettingList.push_back(Debugger_GenerateDebugLog); + m_ChangeSettingList.push_back(Game_CurrentSaveState); + m_ChangeSettingList.push_back(Setting_CurrentLanguage); + + for (SettingList::const_iterator iter = m_ChangeSettingList.begin(); iter != m_ChangeSettingList.end(); iter++) + { + _Settings->RegisterChangeCB(*iter,this,(CSettings::SettingChangedFunc)SettingsChanged); + } } CMainMenu::~CMainMenu() { + for (SettingList::const_iterator iter = m_ChangeSettingList.begin(); iter != m_ChangeSettingList.end(); iter++) + { + _Settings->UnregisterChangeCB(*iter,this,(CSettings::SettingChangedFunc)SettingsChanged); + } +} + + +void CMainMenu::SettingsChanged (CMainMenu * _this ) +{ + _this->ResetMenu(); } int CMainMenu::ProcessAccelerator ( WND_HANDLE hWnd, void * lpMsg ) { @@ -74,7 +109,7 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men case ID_SYSTEM_PAUSE: _Gui->SaveWindowLoc(); WriteTrace(TraceDebug,"ID_SYSTEM_PAUSE"); - if (_Settings->LoadDword(CPU_Paused)) + if (_Settings->LoadBool(GameRunning_CPU_Paused)) { _System->ExternalEvent(ResumeCPU_FromMenu); } else { @@ -84,7 +119,7 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men break; case ID_SYSTEM_BITMAP: { - stdstr Dir(_Settings->LoadString(SnapShotDir)); + stdstr Dir(_Settings->LoadString(Directory_SnapShot)); WriteTraceF(TraceGfxPlugin,"CaptureScreen(%s): Starting",Dir.c_str()); _System->Plugins()->Gfx()->CaptureScreen(Dir.c_str()); WriteTrace(TraceGfxPlugin,"CaptureScreen: Done"); @@ -92,9 +127,8 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men break; case ID_SYSTEM_LIMITFPS: WriteTrace(TraceDebug,"ID_SYSTEM_LIMITFPS"); - _Settings->SaveDword(LimitFPS,!_Settings->LoadDword(LimitFPS)); + _Settings->SaveBool(GameRunning_LimitFPS,!_Settings->LoadBool(GameRunning_LimitFPS)); WriteTrace(TraceDebug,"ID_SYSTEM_LIMITFPS 1"); - ResetMenu(); break; case ID_SYSTEM_SAVE: WriteTrace(TraceDebug,"ID_SYSTEM_SAVE"); _System->ExternalEvent(SaveMachineState); break; case ID_SYSTEM_SAVEAS: @@ -106,7 +140,7 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men memset(&SaveFile, 0, sizeof(SaveFile)); memset(&openfilename, 0, sizeof(openfilename)); - _Settings->LoadString(LastSaveDir, Directory,sizeof(Directory)); + _Settings->LoadString(Directory_LastSave, Directory,sizeof(Directory)); openfilename.lStructSize = sizeof( openfilename ); openfilename.hwndOwner = (HWND)hWnd; @@ -130,11 +164,11 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men _makepath( SaveFile, drive, dir, fname, NULL ); } } - _Settings->SaveString(InstantSaveFile,SaveFile); + _Settings->SaveString(GameRunning_InstantSaveFile,SaveFile); char SaveDir[MAX_PATH]; _makepath( SaveDir, drive, dir, NULL, NULL ); - _Settings->SaveString(LastSaveDir,SaveDir); + _Settings->SaveString(Directory_LastSave,SaveDir); _System->ExternalEvent(SaveMachineState); } @@ -151,7 +185,7 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men memset(&SaveFile, 0, sizeof(SaveFile)); memset(&openfilename, 0, sizeof(openfilename)); - _Settings->LoadString(LastSaveDir, Directory,sizeof(Directory)); + _Settings->LoadString(Directory_LastSave, Directory,sizeof(Directory)); openfilename.lStructSize = sizeof( openfilename ); openfilename.hwndOwner = (HWND)hWnd; @@ -164,12 +198,12 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men _System->ExternalEvent(PauseCPU_LoadGame); if (GetOpenFileName (&openfilename)) { - _Settings->SaveString(InstantSaveFile,SaveFile); + _Settings->SaveString(GameRunning_InstantSaveFile,SaveFile); char SaveDir[MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR], fname[_MAX_FNAME],ext[_MAX_EXT]; _splitpath( SaveFile, drive, dir, fname, ext ); _makepath( SaveDir, drive, dir, NULL, NULL ); - _Settings->SaveString(LastSaveDir,SaveDir); + _Settings->SaveString(Directory_LastSave,SaveDir); _System->ExternalEvent(LoadMachineState); } @@ -185,19 +219,19 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men _System->ExternalEvent(GSButtonPressed); break; case ID_OPTIONS_DISPLAY_FR: - _Settings->SaveDword(DisplayFrameRate,!_Settings->LoadDword(DisplayFrameRate)); + _Settings->SaveBool(UserInterface_DisplayFrameRate,!_Settings->LoadBool(UserInterface_DisplayFrameRate)); break; case ID_OPTIONS_CHANGE_FR: - switch (_Settings->LoadDword(FrameDisplayType)) + switch (_Settings->LoadDword(UserInterface_FrameDisplayType)) { case FR_VIs: - _Settings->SaveDword(FrameDisplayType,FR_DLs); + _Settings->SaveDword(UserInterface_FrameDisplayType,FR_DLs); break; case FR_DLs: - _Settings->SaveDword(FrameDisplayType,FR_PERCENT); + _Settings->SaveDword(UserInterface_FrameDisplayType,FR_PERCENT); break; default: - _Settings->SaveDword(FrameDisplayType,FR_VIs); + _Settings->SaveDword(UserInterface_FrameDisplayType,FR_VIs); } break; case ID_OPTIONS_INCREASE_SPEED: @@ -210,7 +244,7 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men _System->ExternalEvent(ChangingFullScreen); break; case ID_OPTIONS_FULLSCREEN2: - if (_Settings->LoadDword(InFullScreen)) + if (_Settings->LoadBool(UserInterface_InFullScreen)) { WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN a"); _Gui->MakeWindowOnTop(false); @@ -220,17 +254,14 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men WriteTrace(TraceGfxPlugin,"ChangeWindow: Done"); ShowCursor(true); _Gui->ShowStatusBar(true); - _Gui->MakeWindowOnTop(_Settings->LoadDword(AlwaysOnTop) != 0); - _Settings->SaveDword(InFullScreen,(DWORD)false); - ResetMenu(); + _Gui->MakeWindowOnTop(_Settings->LoadBool(UserInterface_AlwaysOnTop)); + _Settings->SaveBool(UserInterface_InFullScreen,(DWORD)false); } else { WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN b"); ShowCursor(false); WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN b 1"); _Gui->ShowStatusBar(false); WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN b 2"); - _Settings->SaveDword(InFullScreen,true); - WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN b 3"); try { WriteTrace(TraceGfxPlugin,"ChangeWindow: Starting"); _System->Plugins()->Gfx()->ChangeWindow(); @@ -247,20 +278,20 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men _Gui->MakeWindowOnTop(false); WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN b 5"); Notify().SetGfxPlugin(_System->Plugins()->Gfx()); + WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN b 3"); + _Settings->SaveBool(UserInterface_InFullScreen,true); WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN b 6"); - ResetMenu(); } WriteTrace(TraceDebug,"ID_OPTIONS_FULLSCREEN 1"); break; case ID_OPTIONS_ALWAYSONTOP: - if (_Settings->LoadDword(AlwaysOnTop)) { - _Settings->SaveDword(AlwaysOnTop,(DWORD)false); + if (_Settings->LoadDword(UserInterface_AlwaysOnTop)) { + _Settings->SaveBool(UserInterface_AlwaysOnTop,false); _Gui->MakeWindowOnTop(false); } else { - _Settings->SaveDword(AlwaysOnTop,true); - _Gui->MakeWindowOnTop(_Settings->LoadDword(CPU_Running) != 0); + _Settings->SaveBool(UserInterface_AlwaysOnTop,true); + _Gui->MakeWindowOnTop(_Settings->LoadBool(GameRunning_CPU_Running)); } - ResetMenu(); break; case ID_OPTIONS_CONFIG_RSP: WriteTrace(TraceDebug,"ID_OPTIONS_CONFIG_RSP"); _System->Plugins()->ConfigPlugin((DWORD)hWnd,PLUGIN_TYPE_RSP); break; case ID_OPTIONS_CONFIG_GFX: WriteTrace(TraceDebug,"ID_OPTIONS_CONFIG_GFX"); _System->Plugins()->ConfigPlugin((DWORD)hWnd,PLUGIN_TYPE_GFX); break; @@ -268,70 +299,65 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men case ID_OPTIONS_CONFIG_CONT: WriteTrace(TraceDebug,"ID_OPTIONS_CONFIG_CONT"); _System->Plugins()->ConfigPlugin((DWORD)hWnd,PLUGIN_TYPE_CONTROLLER); break; case ID_OPTIONS_CPU_USAGE: WriteTrace(TraceDebug,"ID_OPTIONS_CPU_USAGE"); - if (_Settings->LoadDword(ShowCPUPer)) { - _Settings->SaveDword(ShowCPUPer,(DWORD)false); + if (_Settings->LoadBool(UserInterface_ShowCPUPer)) + { + _Settings->SaveBool(UserInterface_ShowCPUPer,false); _Gui->GetNotifyClass()->DisplayMessage(0,""); } else { - _Settings->SaveDword(ShowCPUPer,true); + _Settings->SaveBool(UserInterface_ShowCPUPer,true); } _System->ExternalEvent(CPUUsageTimerChanged); - ResetMenu(); break; - //case ID_OPTIONS_SETTINGS: _Settings->Config((void *)hWnd,_System,_Gui); break; + case ID_OPTIONS_SETTINGS: + { + CSettingConfig SettingConfig; + SettingConfig.Display(hWnd); + } + break; case ID_PROFILE_PROFILE: - _Settings->SaveDword(ProfileCode,!_Settings->LoadDword(ProfileCode)); + _Settings->SaveBool(Debugger_ProfileCode,!_Settings->LoadBool(Debugger_ProfileCode)); _System->ExternalEvent(Profile_StartStop); - ResetMenu(); break; case ID_PROFILE_RESETCOUNTER: _System->ExternalEvent(Profile_ResetLogs); break; case ID_PROFILE_GENERATELOG: _System->ExternalEvent(Profile_GenerateLogs); break; case ID_DEBUG_SHOW_UNHANDLED_MEM: - _Settings->SaveDword(ShowUnhandledMemory,!_Settings->LoadDword(ShowUnhandledMemory)); - ResetMenu(); + _Settings->SaveBool(Debugger_ShowUnhandledMemory,!_Settings->LoadBool(Debugger_ShowUnhandledMemory)); break; case ID_DEBUG_SHOW_PIF_ERRORS: - _Settings->SaveDword(ShowPifErrors,!_Settings->LoadDword(ShowPifErrors)); - ResetMenu(); + _Settings->SaveBool(Debugger_ShowPifErrors,!_Settings->LoadBool(Debugger_ShowPifErrors)); break; case ID_DEBUG_SHOW_DLIST_COUNT: _Gui->GetNotifyClass()->DisplayMessage(0,""); - _Settings->SaveDword(ShowDListAListCount,!_Settings->LoadDword(ShowDListAListCount)); - ResetMenu(); + _Settings->SaveBool(Debugger_ShowDListAListCount,!_Settings->LoadBool(Debugger_ShowDListAListCount)); break; case ID_DEBUG_SHOW_RECOMP_MEM_SIZE: _Gui->GetNotifyClass()->DisplayMessage(0,""); - _Settings->SaveDword(ShowRecompMemSize,!_Settings->LoadDword(ShowRecompMemSize)); - ResetMenu(); + _Settings->SaveBool(Debugger_ShowRecompMemSize,!_Settings->LoadBool(Debugger_ShowRecompMemSize)); break; case ID_DEBUG_SHOW_CHECK_OPUSAGE: - _Settings->SaveDword(ShowCheckOpUsageErrors,!_Settings->LoadDword(ShowCheckOpUsageErrors)); - ResetMenu(); + _Settings->SaveBool(Debugger_ShowCheckOpUsageErrors,!_Settings->LoadBool(Debugger_ShowCheckOpUsageErrors)); break; case ID_DEBUG_GENERATE_LOG_FILES: - _Settings->SaveDword(GenerateLogFiles,!_Settings->LoadDword(GenerateLogFiles)); - ResetMenu(); + _Settings->SaveBool(Debugger_GenerateLogFiles,!_Settings->LoadBool(Debugger_GenerateLogFiles)); break; case ID_DEBUG_DISABLE_GAMEFIX: - _Settings->SaveDword(DisableGameFixes,!_Settings->LoadDword(DisableGameFixes)); - ResetMenu(); + _Settings->SaveBool(Debugger_DisableGameFixes,!_Settings->LoadBool(Debugger_DisableGameFixes)); break; case ID_DEBUGGER_APPLOG_ERRORS: { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); if ((LogLevel & TraceError) != 0) { LogLevel &= ~TraceError; } else { - LogLevel |= TraceError; } - _Settings->SaveDword(AppLogLevel, LogLevel ); + _Settings->SaveDword(Debugger_AppLogLevel, LogLevel ); } - ResetMenu(); break; case ID_DEBUGGER_APPLOG_SETTINGS: { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); if ((LogLevel & TraceSettings) != 0) { LogLevel &= ~TraceSettings; @@ -339,13 +365,12 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men LogLevel |= TraceSettings; } - _Settings->SaveDword(AppLogLevel, LogLevel ); + _Settings->SaveDword(Debugger_AppLogLevel, LogLevel ); } - ResetMenu(); break; case ID_DEBUGGER_APPLOG_RECOMPILER: { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); if ((LogLevel & TraceRecompiler) != 0) { LogLevel &= ~TraceRecompiler; @@ -353,13 +378,12 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men LogLevel |= TraceRecompiler; } - _Settings->SaveDword(AppLogLevel, LogLevel ); + _Settings->SaveDword(Debugger_AppLogLevel, LogLevel ); } - ResetMenu(); break; case ID_DEBUGGER_APPLOG_RSP: { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); if ((LogLevel & TraceRSP) != 0) { LogLevel &= ~TraceRSP; @@ -367,13 +391,12 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men LogLevel |= TraceRSP; } - _Settings->SaveDword(AppLogLevel, LogLevel ); + _Settings->SaveDword(Debugger_AppLogLevel, LogLevel ); } - ResetMenu(); break; case ID_DEBUGGER_APPLOG_TLB: { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); if ((LogLevel & TraceTLB) != 0) { LogLevel &= ~TraceTLB; @@ -381,13 +404,12 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men LogLevel |= TraceTLB; } - _Settings->SaveDword(AppLogLevel, LogLevel ); + _Settings->SaveDword(Debugger_AppLogLevel, LogLevel ); } - ResetMenu(); break; case ID_DEBUGGER_APPLOG_GFX_PLUGIN: { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); if ((LogLevel & TraceGfxPlugin) != 0) { LogLevel &= ~TraceGfxPlugin; @@ -395,13 +417,12 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men LogLevel |= TraceGfxPlugin; } - _Settings->SaveDword(AppLogLevel, LogLevel ); + _Settings->SaveDword(Debugger_AppLogLevel, LogLevel ); } - ResetMenu(); break; case ID_DEBUGGER_APPLOG_DEBUG: { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); if ((LogLevel & TraceDebug) != 0) { LogLevel &= ~TraceDebug; @@ -409,18 +430,15 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men LogLevel |= TraceDebug; } - _Settings->SaveDword(AppLogLevel, LogLevel ); + _Settings->SaveDword(Debugger_AppLogLevel, LogLevel ); } - ResetMenu(); break; case ID_DEBUGGER_APPLOG_FLUSH: - _Settings->SaveDword(AppLogFlush,!_Settings->LoadDword(AppLogFlush)); - ResetMenu(); + _Settings->SaveBool(Debugger_AppLogFlush,!_Settings->LoadBool(Debugger_AppLogFlush)); break; case ID_DEBUGGER_LOGOPTIONS: _Gui->EnterLogOptions(); break; case ID_DEBUGGER_GENERATELOG: - _Settings->SaveDword(GenerateDebugLog,!_Settings->LoadDword(GenerateDebugLog)); - ResetMenu(); + _Settings->SaveBool(Debugger_GenerateDebugLog,!_Settings->LoadBool(Debugger_GenerateDebugLog)); break; case ID_DEBUGGER_DUMPMEMORY: _System->Debug_ShowMemoryDump(); @@ -436,8 +454,7 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men case ID_DEBUGGER_INTERRUPT_DP: _System->ExternalEvent(Interrupt_DP); break; case ID_CURRENT_SAVE_DEFAULT: Notify().DisplayMessage(3,"Save Slot (%s) selected",GetSaveSlotString(MenuID - ID_CURRENT_SAVE_DEFAULT).c_str()); - _Settings->SaveDword(CurrentSaveState,(DWORD)(MenuID - ID_CURRENT_SAVE_DEFAULT)); - ResetMenu(); + _Settings->SaveDword(Game_CurrentSaveState,(DWORD)(MenuID - ID_CURRENT_SAVE_DEFAULT)); break; case ID_CURRENT_SAVE_1: case ID_CURRENT_SAVE_2: @@ -450,8 +467,7 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men case ID_CURRENT_SAVE_9: case ID_CURRENT_SAVE_10: Notify().DisplayMessage(3,"Save Slot (%s) selected",GetSaveSlotString((MenuID - ID_CURRENT_SAVE_1) + 1).c_str()); - _Settings->SaveDword(CurrentSaveState,(DWORD)((MenuID - ID_CURRENT_SAVE_1) + 1)); - ResetMenu(); + _Settings->SaveDword(Game_CurrentSaveState,(DWORD)((MenuID - ID_CURRENT_SAVE_1) + 1)); break; case ID_HELP_CONTENTS: { @@ -498,11 +514,9 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men } if (MenuID >= ID_RECENT_DIR_START && MenuID < ID_RECENT_DIR_END) { int Offset = MenuID - ID_RECENT_DIR_START; - stdstr Dir = _Settings->LoadStringIndex(RecentRomDirIndex,Offset); + stdstr Dir = _Settings->LoadStringIndex(Directory_RecentGameDirIndex,Offset); if (Dir.length() > 0) { - _Settings->SaveDword(UseRomDirSelected,true); - _Settings->SaveString(SelectedRomDir,Dir.c_str()); - _Settings->SaveString(RomDirectory,Dir.c_str()); + _Settings->SaveString(Directory_Game,Dir.c_str()); _Gui->GetNotifyClass()->AddRecentDir(Dir.c_str()); _Gui->RefreshMenu(); if (_Gui->RomBrowserVisible()) { @@ -524,7 +538,6 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men //See if the language has changed, if not do nothing //Set the language _Lang->SetLanguage(String); - ResetMenu(); _Gui->ResetRomBrowserColomuns(); break; } @@ -533,14 +546,15 @@ bool CMainMenu::ProcessMessage(WND_HANDLE hWnd, DWORD FromAccelerator, DWORD Men return true; } -stdstr CMainMenu::ShortCutString(MSC_MAP & ShortCuts, int MenuID, MENU_SHORT_CUT_KEY::ACCESS_MODE AccessLevel) { +/*stdstr CMainMenu::ShortCutString(MSC_MAP & ShortCuts, int MenuID, CMenuShortCutKey::ACCESS_MODE AccessLevel) { + Notify().BreakPoint(__FILE__,__LINE__); MSC_MAP::iterator MenuItem = ShortCuts.find(MenuID); if (MenuItem == ShortCuts.end()) { return ""; } const SHORTCUT_KEY_LIST & ShortCutList = MenuItem->second.GetAccelItems(); for (SHORTCUT_KEY_LIST::const_iterator item = ShortCutList.begin(); item != ShortCutList.end(); item++) { - MENU_SHORT_CUT_KEY::ACCESS_MODE ItemMode = item->AccessMode(); + CMenuShortCutKey::ACCESS_MODE ItemMode = item->AccessMode(); if ((ItemMode & AccessLevel) != AccessLevel ) { continue; @@ -548,7 +562,7 @@ stdstr CMainMenu::ShortCutString(MSC_MAP & ShortCuts, int MenuID, MENU_SHORT_CU return item->Name(); } return ""; -} +}*/ stdstr CMainMenu::GetFileLastMod (stdstr FileName) { @@ -594,13 +608,13 @@ stdstr CMainMenu::GetSaveSlotString (int Slot) case 10: SlotName = GS(MENU_SLOT_10); break; } - if (!_Settings->LoadBool(CPU_Running)) { return SlotName; } + if (!_Settings->LoadBool(GameRunning_CPU_Running)) { return SlotName; } stdstr LastSaveTime; //check first save name - stdstr & _GoodName = _Settings->LoadString(ROM_GoodName); - stdstr & _InstantSaveDirectory = _Settings->LoadString(InstantSaveDirectory); + stdstr & _GoodName = _Settings->LoadString(Game_GoodName); + stdstr & _InstantSaveDirectory = _Settings->LoadString(Directory_InstantSave); stdstr CurrentSaveName; if (Slot != 0) { CurrentSaveName.Format("%s.pj%d",_GoodName.c_str(), Slot); @@ -609,7 +623,7 @@ stdstr CMainMenu::GetSaveSlotString (int Slot) } stdstr_f FileName("%s%s",_InstantSaveDirectory.c_str(),CurrentSaveName.c_str()); - if (_Settings->LoadDword(AutoZip)) + if (_Settings->LoadDword(Setting_AutoZipInstantSave)) { stdstr_f ZipFileName("%s.zip",FileName.c_str()); LastSaveTime = GetFileLastMod(ZipFileName); @@ -623,14 +637,14 @@ stdstr CMainMenu::GetSaveSlotString (int Slot) // Check old file name if (LastSaveTime.empty()) { - stdstr & _RomName = _Settings->LoadString(ROM_NAME); + stdstr & _RomName = _Settings->LoadString(Game_GameName); if (Slot > 0) { FileName.Format("%s%s.pj%d", _InstantSaveDirectory.c_str(), _RomName.c_str(),Slot); } else { FileName.Format("%s%s.pj",_InstantSaveDirectory.c_str(),_RomName.c_str()); } - if (_Settings->LoadDword(AutoZip)) + if (_Settings->LoadBool(Setting_AutoZipInstantSave)) { stdstr_f ZipFileName("%s.zip",FileName.c_str()); LastSaveTime = GetFileLastMod(ZipFileName); @@ -648,21 +662,18 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { MENU_ITEM Item; //Get all flags - bool inBasicMode = _Settings->LoadBool(BasicMode); - bool CPURunning = _Settings->LoadBool(CPU_Running); - bool RomLoading = _Settings->LoadBool(LoadingRom); - bool RomLoaded = _Settings->LoadString(ROM_NAME).length() > 0; - bool RomList = _Settings->LoadBool(RomBrowser) && !CPURunning; + bool inBasicMode = _Settings->LoadBool(UserInterface_BasicMode); + bool CPURunning = _Settings->LoadBool(GameRunning_CPU_Running); + bool RomLoading = _Settings->LoadBool(GameRunning_LoadingInProgress); + bool RomLoaded = _Settings->LoadString(Game_GameName).length() > 0; + bool RomList = _Settings->LoadBool(RomBrowser_Enabled) && !CPURunning; - //Get Short Cut Info - MSC_MAP & ShortCut = GetShortCutInfo(false); - - MENU_SHORT_CUT_KEY::ACCESS_MODE AccessLevel = MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING; - if (_Settings->LoadBool(CPU_Running)) + CMenuShortCutKey::ACCESS_MODE AccessLevel = CMenuShortCutKey::GAME_NOT_RUNNING; + if (_Settings->LoadBool(GameRunning_CPU_Running)) { - AccessLevel = _Settings->LoadBool(InFullScreen) ? - MENU_SHORT_CUT_KEY::GAME_RUNNING_FULLSCREEN : - MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW; + AccessLevel = _Settings->LoadBool(UserInterface_InFullScreen) ? + CMenuShortCutKey::GAME_RUNNING_FULLSCREEN : + CMenuShortCutKey::GAME_RUNNING_WINDOW; } @@ -682,10 +693,10 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { //Go through the settings to create a list of Recent Roms MenuItemList RecentRomMenu; - DWORD count, RomsToRemember = _Settings->LoadDword(RememberedRomFilesCount); + DWORD count, RomsToRemember = _Settings->LoadDword(File_RecentGameFileCount); for (count = 0; count < RomsToRemember; count++) { - stdstr LastRom = _Settings->LoadStringIndex(RecentRomFileIndex,count); + stdstr LastRom = _Settings->LoadStringIndex(File_RecentGameFileIndex,count); if (LastRom.empty()) { break; @@ -698,11 +709,11 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { /* Recent Dir ****************/ MenuItemList RecentDirMenu; - DWORD DirsToRemember = _Settings->LoadDword(RememberedRomDirCount); + DWORD DirsToRemember = _Settings->LoadDword(Directory_RecentGameDirCount); for (count = 0; count < DirsToRemember; count++) { - stdstr LastDir = _Settings->LoadStringIndex(RecentRomDirIndex,count); + stdstr LastDir = _Settings->LoadStringIndex(Directory_RecentGameDirIndex,count); if (LastDir.empty()) { break; @@ -715,18 +726,18 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { /* File Menu ****************/ MenuItemList FileMenu; - Item.Reset(ID_FILE_OPEN_ROM, MENU_OPEN, ShortCutString(ShortCut,ID_FILE_OPEN_ROM,AccessLevel)); + Item.Reset(ID_FILE_OPEN_ROM, MENU_OPEN, m_ShortCuts.ShortCutString(ID_FILE_OPEN_ROM,AccessLevel)); FileMenu.push_back(Item); if (!inBasicMode) { - Item.Reset(ID_FILE_ROM_INFO, MENU_ROM_INFO,ShortCutString(ShortCut,ID_FILE_ROM_INFO,AccessLevel)); + Item.Reset(ID_FILE_ROM_INFO, MENU_ROM_INFO,m_ShortCuts.ShortCutString(ID_FILE_ROM_INFO,AccessLevel)); Item.ItemEnabled = RomLoaded; FileMenu.push_back(Item); FileMenu.push_back(MENU_ITEM(SPLITER )); - Item.Reset(ID_FILE_STARTEMULATION,MENU_START, ShortCutString(ShortCut,ID_FILE_STARTEMULATION,AccessLevel) ); + Item.Reset(ID_FILE_STARTEMULATION,MENU_START, m_ShortCuts.ShortCutString(ID_FILE_STARTEMULATION,AccessLevel) ); Item.ItemEnabled = RomLoaded && !CPURunning; FileMenu.push_back(Item); } - Item.Reset(ID_FILE_ENDEMULATION, MENU_END, ShortCutString(ShortCut,ID_FILE_ENDEMULATION,AccessLevel) ); + Item.Reset(ID_FILE_ENDEMULATION, MENU_END, m_ShortCuts.ShortCutString(ID_FILE_ENDEMULATION,AccessLevel) ); Item.ItemEnabled = CPURunning; FileMenu.push_back(Item); FileMenu.push_back(MENU_ITEM(SPLITER )); @@ -734,9 +745,9 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { FileMenu.push_back(Item); if (RomList) { FileMenu.push_back(MENU_ITEM(SPLITER )); - Item.Reset(ID_FILE_ROMDIRECTORY, MENU_CHOOSE_ROM,ShortCutString(ShortCut,ID_FILE_ROMDIRECTORY,AccessLevel) ); + Item.Reset(ID_FILE_ROMDIRECTORY, MENU_CHOOSE_ROM,m_ShortCuts.ShortCutString(ID_FILE_ROMDIRECTORY,AccessLevel) ); FileMenu.push_back(Item); - Item.Reset(ID_FILE_REFRESHROMLIST,MENU_REFRESH,ShortCutString(ShortCut,ID_FILE_REFRESHROMLIST,AccessLevel) ); + Item.Reset(ID_FILE_REFRESHROMLIST,MENU_REFRESH,m_ShortCuts.ShortCutString(ID_FILE_REFRESHROMLIST,AccessLevel) ); FileMenu.push_back(Item); } @@ -764,44 +775,44 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { } } FileMenu.push_back(MENU_ITEM(SPLITER )); - FileMenu.push_back(MENU_ITEM(ID_FILE_EXIT, MENU_EXIT,ShortCutString(ShortCut,ID_FILE_EXIT,AccessLevel) )); + FileMenu.push_back(MENU_ITEM(ID_FILE_EXIT, MENU_EXIT,m_ShortCuts.ShortCutString(ID_FILE_EXIT,AccessLevel) )); /* Current Save ****************/ MenuItemList CurrentSaveMenu; - DWORD _CurrentSaveState = _Settings->LoadDword(CurrentSaveState); - Item.Reset(ID_CURRENT_SAVE_DEFAULT, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_DEFAULT,AccessLevel),NULL,GetSaveSlotString(0)); + DWORD _CurrentSaveState = _Settings->LoadDword(Game_CurrentSaveState); + Item.Reset(ID_CURRENT_SAVE_DEFAULT, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_DEFAULT,AccessLevel),NULL,GetSaveSlotString(0)); if (_CurrentSaveState == 0) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); CurrentSaveMenu.push_back(MENU_ITEM(SPLITER)); - Item.Reset(ID_CURRENT_SAVE_1, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_1,AccessLevel),NULL,GetSaveSlotString(1)); + Item.Reset(ID_CURRENT_SAVE_1, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_1,AccessLevel),NULL,GetSaveSlotString(1)); if (_CurrentSaveState == 1) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_2, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_2,AccessLevel),NULL,GetSaveSlotString(2)); + Item.Reset(ID_CURRENT_SAVE_2, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_2,AccessLevel),NULL,GetSaveSlotString(2)); if (_CurrentSaveState == 2) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_3, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_3,AccessLevel),NULL,GetSaveSlotString(3)); + Item.Reset(ID_CURRENT_SAVE_3, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_3,AccessLevel),NULL,GetSaveSlotString(3)); if (_CurrentSaveState == 3) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_4, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_4,AccessLevel),NULL,GetSaveSlotString(4)); + Item.Reset(ID_CURRENT_SAVE_4, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_4,AccessLevel),NULL,GetSaveSlotString(4)); if (_CurrentSaveState == 4) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_5, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_5,AccessLevel),NULL,GetSaveSlotString(5)); + Item.Reset(ID_CURRENT_SAVE_5, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_5,AccessLevel),NULL,GetSaveSlotString(5)); if (_CurrentSaveState == 5) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_6, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_6,AccessLevel),NULL,GetSaveSlotString(6)); + Item.Reset(ID_CURRENT_SAVE_6, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_6,AccessLevel),NULL,GetSaveSlotString(6)); if (_CurrentSaveState == 6) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_7, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_7,AccessLevel),NULL,GetSaveSlotString(7)); + Item.Reset(ID_CURRENT_SAVE_7, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_7,AccessLevel),NULL,GetSaveSlotString(7)); if (_CurrentSaveState == 7) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_8, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_8,AccessLevel),NULL,GetSaveSlotString(8)); + Item.Reset(ID_CURRENT_SAVE_8, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_8,AccessLevel),NULL,GetSaveSlotString(8)); if (_CurrentSaveState == 8) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_9, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_9,AccessLevel),NULL,GetSaveSlotString(9)); + Item.Reset(ID_CURRENT_SAVE_9, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_9,AccessLevel),NULL,GetSaveSlotString(9)); if (_CurrentSaveState == 9) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); - Item.Reset(ID_CURRENT_SAVE_10, EMPTY_STRING,ShortCutString(ShortCut,ID_CURRENT_SAVE_10,AccessLevel),NULL,GetSaveSlotString(10)); + Item.Reset(ID_CURRENT_SAVE_10, EMPTY_STRING,m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_10,AccessLevel),NULL,GetSaveSlotString(10)); if (_CurrentSaveState == 10) { Item.ItemTicked = true; } CurrentSaveMenu.push_back(Item); @@ -811,74 +822,74 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { MenuItemList ResetMenu; if (inBasicMode) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET, ShortCutString(ShortCut,ID_SYSTEM_RESET_SOFT,AccessLevel) )); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT,AccessLevel) )); } else { - ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET_SOFT, ShortCutString(ShortCut,ID_SYSTEM_RESET_SOFT,AccessLevel) )); - ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_HARD, MENU_RESET_HARD, ShortCutString(ShortCut,ID_SYSTEM_RESET_HARD,AccessLevel))); + ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET_SOFT, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT,AccessLevel) )); + ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_HARD, MENU_RESET_HARD, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_HARD,AccessLevel))); SystemMenu.push_back(MENU_ITEM(SUB_MENU,MENU_RESET,EMPTY_STDSTR,&ResetMenu)); } - if (_Settings->LoadBool(CPU_Paused)) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_RESUME, ShortCutString(ShortCut,ID_SYSTEM_PAUSE,AccessLevel))); + if (_Settings->LoadBool(GameRunning_CPU_Paused)) { + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_RESUME, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE,AccessLevel))); } else { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_PAUSE, ShortCutString(ShortCut,ID_SYSTEM_PAUSE,AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_PAUSE, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE,AccessLevel))); } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_BITMAP, MENU_BITMAP, ShortCutString(ShortCut,ID_SYSTEM_BITMAP,AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_BITMAP, MENU_BITMAP, m_ShortCuts.ShortCutString(ID_SYSTEM_BITMAP,AccessLevel))); SystemMenu.push_back(MENU_ITEM(SPLITER )); if (!inBasicMode) { - Item.Reset(ID_SYSTEM_LIMITFPS, MENU_LIMIT_FPS,ShortCutString(ShortCut,ID_SYSTEM_LIMITFPS,AccessLevel) ); - if (_Settings->LoadDword(LimitFPS)) { Item.ItemTicked = true; } + Item.Reset(ID_SYSTEM_LIMITFPS, MENU_LIMIT_FPS,m_ShortCuts.ShortCutString(ID_SYSTEM_LIMITFPS,AccessLevel) ); + if (_Settings->LoadBool(GameRunning_LimitFPS)) { Item.ItemTicked = true; } SystemMenu.push_back(Item); SystemMenu.push_back(MENU_ITEM(SPLITER )); } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVE, MENU_SAVE, ShortCutString(ShortCut,ID_SYSTEM_SAVE,AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVE, MENU_SAVE, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVE,AccessLevel))); if (!inBasicMode) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVEAS, MENU_SAVE_AS, ShortCutString(ShortCut,ID_SYSTEM_SAVEAS,AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVEAS, MENU_SAVE_AS, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVEAS,AccessLevel))); } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESTORE, MENU_RESTORE, ShortCutString(ShortCut,ID_SYSTEM_RESTORE,AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESTORE, MENU_RESTORE, m_ShortCuts.ShortCutString(ID_SYSTEM_RESTORE,AccessLevel))); if (!inBasicMode) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_LOAD, MENU_LOAD, ShortCutString(ShortCut,ID_SYSTEM_LOAD,AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_LOAD, MENU_LOAD, m_ShortCuts.ShortCutString(ID_SYSTEM_LOAD,AccessLevel))); } SystemMenu.push_back(MENU_ITEM(SPLITER )); SystemMenu.push_back(MENU_ITEM(SUB_MENU, MENU_CURRENT_SAVE, EMPTY_STDSTR, &CurrentSaveMenu )); SystemMenu.push_back(MENU_ITEM(SPLITER )); - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_CHEAT, MENU_CHEAT, ShortCutString(ShortCut,ID_SYSTEM_CHEAT,AccessLevel))); - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_GSBUTTON, MENU_GS_BUTTON, ShortCutString(ShortCut,ID_SYSTEM_GSBUTTON,AccessLevel) )); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_CHEAT, MENU_CHEAT, m_ShortCuts.ShortCutString(ID_SYSTEM_CHEAT,AccessLevel))); + SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_GSBUTTON, MENU_GS_BUTTON, m_ShortCuts.ShortCutString(ID_SYSTEM_GSBUTTON,AccessLevel) )); /* Option Menu ****************/ MenuItemList OptionMenu; - Item.Reset(ID_OPTIONS_FULLSCREEN, MENU_FULL_SCREEN,ShortCutString(ShortCut,ID_OPTIONS_FULLSCREEN,AccessLevel) ); + Item.Reset(ID_OPTIONS_FULLSCREEN, MENU_FULL_SCREEN,m_ShortCuts.ShortCutString(ID_OPTIONS_FULLSCREEN,AccessLevel) ); Item.ItemEnabled = CPURunning; if (_System->Plugins()->Gfx() && _System->Plugins()->Gfx()->ChangeWindow == NULL) { Item.ItemEnabled = false; } OptionMenu.push_back(Item); if (!inBasicMode) { - Item.Reset(ID_OPTIONS_ALWAYSONTOP, MENU_ON_TOP,ShortCutString(ShortCut,ID_OPTIONS_ALWAYSONTOP,AccessLevel) ); - if (_Settings->LoadDword(AlwaysOnTop)) { Item.ItemTicked = true; } + Item.Reset(ID_OPTIONS_ALWAYSONTOP, MENU_ON_TOP,m_ShortCuts.ShortCutString(ID_OPTIONS_ALWAYSONTOP,AccessLevel) ); + if (_Settings->LoadDword(UserInterface_AlwaysOnTop)) { Item.ItemTicked = true; } Item.ItemEnabled = CPURunning; OptionMenu.push_back(Item); } OptionMenu.push_back(MENU_ITEM(SPLITER )); - Item.Reset(ID_OPTIONS_CONFIG_GFX, MENU_CONFG_GFX,ShortCutString(ShortCut,ID_OPTIONS_CONFIG_GFX,AccessLevel)); + Item.Reset(ID_OPTIONS_CONFIG_GFX, MENU_CONFG_GFX,m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_GFX,AccessLevel)); if (_System->Plugins()->Gfx() == NULL || _System->Plugins()->Gfx()->Config == NULL) { Item.ItemEnabled = false; } OptionMenu.push_back(Item); - Item.Reset(ID_OPTIONS_CONFIG_AUDIO, MENU_CONFG_AUDIO,ShortCutString(ShortCut,ID_OPTIONS_CONFIG_AUDIO,AccessLevel)); + Item.Reset(ID_OPTIONS_CONFIG_AUDIO, MENU_CONFG_AUDIO,m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_AUDIO,AccessLevel)); if (_System->Plugins()->Audio() == NULL || _System->Plugins()->Audio()->Config == NULL) { Item.ItemEnabled = false; } OptionMenu.push_back(Item); if (!inBasicMode) { - Item.Reset(ID_OPTIONS_CONFIG_RSP, MENU_CONFG_RSP,ShortCutString(ShortCut,ID_OPTIONS_CONFIG_RSP,AccessLevel)); + Item.Reset(ID_OPTIONS_CONFIG_RSP, MENU_CONFG_RSP,m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_RSP,AccessLevel)); if (_System->Plugins()->RSP() == NULL || _System->Plugins()->RSP()->Config == NULL) { Item.ItemEnabled = false; } OptionMenu.push_back(Item); } - Item.Reset(ID_OPTIONS_CONFIG_CONT, MENU_CONFG_CTRL,ShortCutString(ShortCut,ID_OPTIONS_CONFIG_CONT,AccessLevel)); + Item.Reset(ID_OPTIONS_CONFIG_CONT, MENU_CONFG_CTRL,m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_CONT,AccessLevel)); if (_System->Plugins()->Control() == NULL || _System->Plugins()->Control()->Config == NULL) { Item.ItemEnabled = false; } @@ -886,19 +897,19 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { OptionMenu.push_back(MENU_ITEM(SPLITER )); if (!inBasicMode) { - Item.Reset(ID_OPTIONS_CPU_USAGE, MENU_SHOW_CPU,ShortCutString(ShortCut,ID_OPTIONS_CPU_USAGE,AccessLevel) ); - if (_Settings->LoadDword(ShowCPUPer)) { Item.ItemTicked = true; } + Item.Reset(ID_OPTIONS_CPU_USAGE, MENU_SHOW_CPU,m_ShortCuts.ShortCutString(ID_OPTIONS_CPU_USAGE,AccessLevel) ); + if (_Settings->LoadDword(UserInterface_ShowCPUPer)) { Item.ItemTicked = true; } OptionMenu.push_back(Item); } - OptionMenu.push_back(MENU_ITEM(ID_OPTIONS_SETTINGS, MENU_SETTINGS,ShortCutString(ShortCut,ID_OPTIONS_SETTINGS,AccessLevel) )); + OptionMenu.push_back(MENU_ITEM(ID_OPTIONS_SETTINGS, MENU_SETTINGS,m_ShortCuts.ShortCutString(ID_OPTIONS_SETTINGS,AccessLevel) )); /* Profile Menu ****************/ MenuItemList DebugProfileMenu; - if (_Settings->LoadDword(Debugger)) + if (_Settings->LoadDword(Debugger_Enabled)) { Item.Reset(ID_PROFILE_PROFILE,EMPTY_STRING,EMPTY_STDSTR,NULL,"Profile Code" ); - if (_Settings->LoadDword(ProfileCode)) { Item.ItemTicked = true; } + if (_Settings->LoadBool(Debugger_ProfileCode)) { Item.ItemTicked = true; } DebugProfileMenu.push_back(Item); Item.Reset(ID_PROFILE_RESETCOUNTER,EMPTY_STRING,EMPTY_STDSTR,NULL,"Reset Counters" ); if (!CPURunning) { Item.ItemEnabled = false; } @@ -916,7 +927,7 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { MenuItemList DebugR4300Menu; MenuItemList DebugMemoryMenu; MenuItemList DebugInterrupt; - if (_Settings->LoadDword(Debugger)) { + if (_Settings->LoadDword(Debugger_Enabled)) { /* Debug - Interrupt *******************/ Item.Reset(ID_DEBUGGER_INTERRUPT_SP,EMPTY_STRING,EMPTY_STDSTR,NULL,"SP Interrupt" ); @@ -947,7 +958,7 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { Item.ItemEnabled = true; DebugR4300Menu.push_back(Item); Item.Reset(ID_DEBUG_DISABLE_GAMEFIX,EMPTY_STRING,EMPTY_STDSTR,NULL,"Disable Game Fixes" ); - if (_Settings->LoadDword(DisableGameFixes)) { + if (_Settings->LoadBool(Debugger_DisableGameFixes)) { Item.ItemTicked = true; } DebugR4300Menu.push_back(Item); @@ -968,7 +979,7 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { /* Debug - App logging *******************/ { - DWORD LogLevel = _Settings->LoadDword(AppLogLevel); + DWORD LogLevel = _Settings->LoadDword(Debugger_AppLogLevel); Item.Reset(ID_DEBUGGER_APPLOG_ERRORS,EMPTY_STRING,EMPTY_STDSTR,NULL,"Error Messages" ); if ((LogLevel & TraceError) != 0) { Item.ItemTicked = true; } @@ -1001,7 +1012,7 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { DebugAppLoggingMenu.push_back(MENU_ITEM(SPLITER )); Item.Reset(ID_DEBUGGER_APPLOG_FLUSH,EMPTY_STRING,EMPTY_STDSTR,NULL,"Auto flush file" ); - if (_Settings->LoadDword(AppLogFlush) != 0) { Item.ItemTicked = true; } + if (_Settings->LoadBool(Debugger_AppLogFlush)) { Item.ItemTicked = true; } DebugAppLoggingMenu.push_back(Item); } @@ -1013,7 +1024,7 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { Item.Reset(ID_DEBUGGER_GENERATELOG,EMPTY_STRING,EMPTY_STDSTR,NULL,"Generate Log" ); - if (_Settings->LoadDword(GenerateDebugLog)) { Item.ItemTicked = true; } + if (_Settings->LoadBool(Debugger_GenerateDebugLog)) { Item.ItemTicked = true; } DebugLoggingMenu.push_back(Item); /* Debugger Main Menu @@ -1053,33 +1064,33 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { DebugMenu.push_back(Item); DebugMenu.push_back(MENU_ITEM(SPLITER)); Item.Reset(ID_DEBUG_SHOW_UNHANDLED_MEM,EMPTY_STRING,EMPTY_STDSTR,NULL,"Show Unhandled Memory Actions" ); - if (_Settings->LoadDword(ShowUnhandledMemory)) { + if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { Item.ItemTicked = true; } DebugMenu.push_back(Item); Item.Reset(ID_DEBUG_SHOW_PIF_ERRORS,EMPTY_STRING,EMPTY_STDSTR,NULL,"Show PIF Errors" ); - if (_Settings->LoadDword(ShowPifErrors)) { + if (_Settings->LoadBool(Debugger_ShowPifErrors)) { Item.ItemTicked = true; } DebugMenu.push_back(Item); Item.Reset(ID_DEBUG_SHOW_DLIST_COUNT,EMPTY_STRING,EMPTY_STDSTR,NULL,"Show Alist/Dlist Counters" ); - if (_Settings->LoadDword(ShowDListAListCount)) { + if (_Settings->LoadBool(Debugger_ShowDListAListCount)) { Item.ItemTicked = true; } DebugMenu.push_back(Item); Item.Reset(ID_DEBUG_SHOW_RECOMP_MEM_SIZE,EMPTY_STRING,EMPTY_STDSTR,NULL,"Show Recompile Memory Buffer size" ); - if (_Settings->LoadDword(ShowRecompMemSize)) { + if (_Settings->LoadBool(Debugger_ShowRecompMemSize)) { Item.ItemTicked = true; } DebugMenu.push_back(Item); Item.Reset(ID_DEBUG_SHOW_CHECK_OPUSAGE,EMPTY_STRING,EMPTY_STDSTR,NULL,"Show Check Opcode Usage Errors" ); - if (_Settings->LoadDword(ShowCheckOpUsageErrors)) { + if (_Settings->LoadBool(Debugger_ShowCheckOpUsageErrors)) { Item.ItemTicked = true; } DebugMenu.push_back(Item); DebugMenu.push_back(MENU_ITEM(SPLITER)); Item.Reset(ID_DEBUG_GENERATE_LOG_FILES,EMPTY_STRING,EMPTY_STDSTR,NULL,"Generate Log Files" ); - if (_Settings->LoadDword(GenerateLogFiles)) { + if (_Settings->LoadBool(Debugger_GenerateLogFiles)) { Item.ItemTicked = true; } DebugMenu.push_back(Item); @@ -1088,10 +1099,10 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { /* Help Menu ****************/ MenuItemList HelpMenu; - if (_Settings->LoadBool(IsBetaVersion)) + if (_Settings->LoadBool(Beta_IsBetaVersion)) { - stdstr_f User("Beta For: %s",_Settings->LoadString(BetaUserName).c_str()); - stdstr_f Email("Email: %s",_Settings->LoadString(BetaEmailAddress).c_str()); + stdstr_f User("Beta For: %s",_Settings->LoadString(Beta_UserName).c_str()); + stdstr_f Email("Email: %s",_Settings->LoadString(Beta_EmailAddress).c_str()); HelpMenu.push_back(MENU_ITEM(NO_ID, EMPTY_STRING,EMPTY_STDSTR,NULL,User )); HelpMenu.push_back(MENU_ITEM(NO_ID, EMPTY_STRING,EMPTY_STDSTR,NULL,Email )); HelpMenu.push_back(MENU_ITEM(SPLITER )); @@ -1123,7 +1134,7 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { if (RomLoading) { Item.ItemEnabled = false; } MainTitleMenu.push_back(Item); if (!inBasicMode) { - if (_Settings->LoadDword(Debugger)) { + if (_Settings->LoadBool(Debugger_Enabled)) { Item.Reset(SUB_MENU, MENU_DEBUGGER, EMPTY_STDSTR, &DebugMenu); if (RomLoading) { Item.ItemEnabled = false; } MainTitleMenu.push_back(Item); @@ -1138,78 +1149,37 @@ void CMainMenu::FillOutMenu ( MENU_HANDLE hMenu ) { void CMainMenu::RebuildAccelerators(void) { //Delete the old accel list - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 6"); - if (m_AccelTable) { - DestroyAcceleratorTable((HACCEL)m_AccelTable); - m_AccelTable = NULL; + WriteTrace(TraceDebug,"CMainMenu::RebuildAccelerators - Start"); + + HACCEL m_OldAccelTable = (HACCEL)m_AccelTable; + m_AccelTable = m_ShortCuts.GetAcceleratorTable(); + if (m_OldAccelTable) { + DestroyAcceleratorTable(m_OldAccelTable); } - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 7"); - //Generate a ACCEL list - MENU_SHORT_CUT_KEY::ACCESS_MODE AccessLevel = MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING; - if (_Settings->LoadBool(CPU_Running)) - { - AccessLevel = _Settings->LoadDword(InFullScreen) != 0 ? - MENU_SHORT_CUT_KEY::GAME_RUNNING_FULLSCREEN : - MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW; - } - MSC_MAP & ShortCuts = GetShortCutInfo(false); - - int size = 0, MaxSize = ShortCuts.size() * 5; - ACCEL * AccelList = new ACCEL[MaxSize]; - - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 8"); - for (MSC_MAP::iterator Item = ShortCuts.begin(); Item != ShortCuts.end(); Item++) - { - MENU_SHORT_CUT & short_cut = Item->second; - - MENU_SHORT_CUT_KEY::ACCESS_MODE ItemMode = short_cut.AccessMode(); - if ((ItemMode & AccessLevel) != AccessLevel ) - { - continue; - } - - SHORTCUT_KEY_LIST ShortCutAccelList = short_cut.GetAccelItems(); - for (SHORTCUT_KEY_LIST::iterator AccelIter = ShortCutAccelList.begin(); AccelIter != ShortCutAccelList.end(); AccelIter++) - { - if (size >= MaxSize) { break; } - AccelList[size].cmd = Item->first; - AccelList[size].key = AccelIter->Key(); - AccelList[size].fVirt = FVIRTKEY; - if (AccelIter->Alt()) { AccelList[size].fVirt |= FALT; } - if (AccelIter->Ctrl()) { AccelList[size].fVirt |= FCONTROL; } - if (AccelIter->Shift()) { AccelList[size].fVirt |= FSHIFT; } - size += 1; - } - } - - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 9"); - m_AccelTable = CreateAcceleratorTable(AccelList,size); - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 10"); - - delete [] AccelList; + WriteTrace(TraceDebug,"CMainMenu::RebuildAccelerators - Done"); } void CMainMenu::ResetMenu(void) { - WriteTrace(TraceDebug,"CMainMenu::ResetMenu starting"); + WriteTrace(TraceDebug,"CMainMenu::ResetMenu - Start"); - if (!_Settings->LoadBool(InFullScreen)) + m_ShortCuts.Load(); + if (!_Settings->LoadBool(UserInterface_InFullScreen)) { //Create a new window with all the items - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 1"); + WriteTrace(TraceDebug,"CMainMenu::ResetMenu - Create Menu"); MENU_HANDLE hMenu = (MENU_HANDLE)CreateMenu(); FillOutMenu(hMenu); - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 2"); + WriteTrace(TraceDebug,"CMainMenu::ResetMenu - Create Menu Done"); //save old menu to destroy latter MENU_HANDLE OldMenuHandle = m_MenuHandle; //save handle and re-attach to a window - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 3"); + WriteTrace(TraceDebug,"CMainMenu::ResetMenu - Attach Menu"); m_MenuHandle = hMenu; _Gui->SetWindowMenu(this); - //Destroy the old menu - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 4"); + WriteTrace(TraceDebug,"CMainMenu::ResetMenu - Remove plugin menu"); if (_System->Plugins()->Gfx() != NULL && IsMenu((HMENU)_System->Plugins()->Gfx()->GetDebugMenu())) { RemoveMenu((HMENU)OldMenuHandle,(DWORD)_System->Plugins()->Gfx()->GetDebugMenu(), MF_BYCOMMAND); @@ -1218,7 +1188,9 @@ void CMainMenu::ResetMenu(void) { { RemoveMenu((HMENU)OldMenuHandle,(DWORD)_System->Plugins()->RSP()->GetDebugMenu(), MF_BYCOMMAND); } - WriteTrace(TraceDebug,"CMainMenu::ResetMenu 5"); + WriteTrace(TraceDebug,"CMainMenu::ResetMenu - Destroy Old Menu"); + + //Destroy the old menu DestroyMenu((HMENU)OldMenuHandle); } @@ -1227,122 +1199,10 @@ void CMainMenu::ResetMenu(void) { WriteTrace(TraceDebug,"CMainMenu::ResetMenu Done"); } -MSC_MAP CMainMenu::GetShortCutInfo(bool InitialSettings ) { -#define DEF_SCUT(ID,Section, LangID,AccessMode) ShortCuts.insert(MSC_MAP::value_type(ID,MENU_SHORT_CUT(Section,LangID,AccessMode))) - MSC_MAP ShortCuts; - - ShortCuts.clear(); - DEF_SCUT(ID_FILE_OPEN_ROM, STR_SHORTCUT_FILEMENU, MENU_OPEN, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_FILE_ROM_INFO, STR_SHORTCUT_FILEMENU, MENU_ROM_INFO, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_FILE_STARTEMULATION, STR_SHORTCUT_FILEMENU, MENU_START, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_FILE_ENDEMULATION, STR_SHORTCUT_FILEMENU, MENU_END, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_FILE_ROMDIRECTORY, STR_SHORTCUT_FILEMENU, MENU_CHOOSE_ROM, MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING ); - DEF_SCUT(ID_FILE_REFRESHROMLIST, STR_SHORTCUT_FILEMENU, MENU_REFRESH, MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING ); - DEF_SCUT(ID_FILE_EXIT, STR_SHORTCUT_FILEMENU, MENU_EXIT, MENU_SHORT_CUT_KEY::ANYTIME ); - - DEF_SCUT(ID_SYSTEM_RESET_SOFT, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_SOFT, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_SYSTEM_RESET_HARD, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_HARD, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_SYSTEM_PAUSE, STR_SHORTCUT_SYSTEMMENU, MENU_PAUSE, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_SYSTEM_BITMAP, STR_SHORTCUT_SYSTEMMENU, MENU_BITMAP, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_SYSTEM_LIMITFPS, STR_SHORTCUT_SYSTEMMENU, MENU_LIMIT_FPS, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_SYSTEM_SAVE, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_SYSTEM_SAVEAS, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE_AS, MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW ); - DEF_SCUT(ID_SYSTEM_RESTORE, STR_SHORTCUT_SYSTEMMENU, MENU_RESTORE, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_SYSTEM_LOAD, STR_SHORTCUT_SYSTEMMENU, MENU_LOAD, MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW ); - DEF_SCUT(ID_SYSTEM_CHEAT, STR_SHORTCUT_SYSTEMMENU, MENU_CHEAT, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_SYSTEM_GSBUTTON, STR_SHORTCUT_SYSTEMMENU, MENU_GS_BUTTON, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - - DEF_SCUT(ID_OPTIONS_DISPLAY_FR, STR_SHORTCUT_OPTIONS, OPTION_DISPLAY_FR,MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_OPTIONS_CHANGE_FR, STR_SHORTCUT_OPTIONS, OPTION_CHANGE_FR, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_OPTIONS_INCREASE_SPEED,STR_SHORTCUT_OPTIONS, STR_INSREASE_SPEED, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_OPTIONS_DECREASE_SPEED,STR_SHORTCUT_OPTIONS, STR_DECREASE_SPEED, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - - DEF_SCUT(ID_CURRENT_SAVE_DEFAULT,STR_SHORTCUT_SAVESLOT, SAVE_SLOT_DEFAULT,MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_1, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_1, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_2, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_2, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_3, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_3, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_4, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_4, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_5, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_5, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_6, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_6, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_7, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_7, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_8, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_8, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_9, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_9, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_CURRENT_SAVE_10, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_10, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - - //Option Menu - DEF_SCUT(ID_OPTIONS_FULLSCREEN, STR_SHORTCUT_OPTIONS, MENU_FULL_SCREEN, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_OPTIONS_ALWAYSONTOP, STR_SHORTCUT_OPTIONS, MENU_ON_TOP, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_OPTIONS_CONFIG_GFX, STR_SHORTCUT_OPTIONS, MENU_CONFG_GFX, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_OPTIONS_CONFIG_AUDIO,STR_SHORTCUT_OPTIONS, MENU_CONFG_AUDIO, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_OPTIONS_CONFIG_CONT, STR_SHORTCUT_OPTIONS, MENU_CONFG_CTRL, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_OPTIONS_CONFIG_RSP, STR_SHORTCUT_OPTIONS, MENU_CONFG_RSP, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - DEF_SCUT(ID_OPTIONS_CPU_USAGE, STR_SHORTCUT_OPTIONS, MENU_SHOW_CPU, MENU_SHORT_CUT_KEY::GAME_RUNNING ); - DEF_SCUT(ID_OPTIONS_SETTINGS, STR_SHORTCUT_OPTIONS, MENU_SETTINGS, MENU_SHORT_CUT_KEY::NOT_IN_FULLSCREEN ); - - stdstr FileName = _Settings->LoadString(ShortCutFile); - FILE *file = fopen(FileName.c_str(),"r"); - if (file == NULL || InitialSettings) { - ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O',TRUE,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O',TRUE,false,false,MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING); - ShortCuts.find(ID_FILE_STARTEMULATION)->second.AddShortCut(VK_F11,false,false,false,MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING); - ShortCuts.find(ID_FILE_ENDEMULATION)->second.AddShortCut(VK_F12,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_FILE_REFRESHROMLIST)->second.AddShortCut(VK_F5,false,false,false,MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING); - ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4,false,true,false,MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING); - ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4,false,true,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_DEFAULT)->second.AddShortCut(0xC0,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_1)->second.AddShortCut('1',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_2)->second.AddShortCut('2',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_3)->second.AddShortCut('3',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_4)->second.AddShortCut('4',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_5)->second.AddShortCut('5',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_6)->second.AddShortCut('6',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_7)->second.AddShortCut('7',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_8)->second.AddShortCut('8',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_9)->second.AddShortCut('9',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_CURRENT_SAVE_10)->second.AddShortCut('0',false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_RETURN,false,true,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_ESCAPE,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A',true,false,false,MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING); - ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A',true,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW); - ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T',true,false,false,MENU_SHORT_CUT_KEY::GAME_NOT_RUNNING); - ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T',true,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW); - ShortCuts.find(ID_SYSTEM_RESET_SOFT)->second.AddShortCut(VK_F1,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_RESET_HARD)->second.AddShortCut(VK_F1,false,false,true,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_F2,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_PAUSE,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_BITMAP)->second.AddShortCut(VK_F3,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_LIMITFPS)->second.AddShortCut(VK_F4,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_SAVE)->second.AddShortCut(VK_F5,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_RESTORE)->second.AddShortCut(VK_F7,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_SYSTEM_LOAD)->second.AddShortCut('L',true,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW); - ShortCuts.find(ID_SYSTEM_SAVEAS)->second.AddShortCut('S',true,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW); - ShortCuts.find(ID_SYSTEM_CHEAT)->second.AddShortCut('C',true,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING_WINDOW); - ShortCuts.find(ID_SYSTEM_GSBUTTON)->second.AddShortCut(VK_F9,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_OPTIONS_INCREASE_SPEED)->second.AddShortCut(VK_OEM_PLUS,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - ShortCuts.find(ID_OPTIONS_DECREASE_SPEED)->second.AddShortCut(VK_OEM_MINUS,false,false,false,MENU_SHORT_CUT_KEY::GAME_RUNNING); - - } else if (file) { - MENU_SHORT_CUT_KEY::ACCESS_MODE AccessMode; - int ID, key, bCtrl, bAlt, bShift; - - do { - char Line[300]; - if (fgets(Line,sizeof(Line),file) != NULL) { - sscanf(Line,"%d,%d,%d,%d,%d,%d", &ID,&key,&bCtrl,&bAlt,&bShift,&AccessMode); - - MENU_SHORT_CUT_MAP::iterator item = ShortCuts.find(ID); - if (item == ShortCuts.end()) { continue; } - item->second.AddShortCut(key,bCtrl == 1,bAlt == 1,bShift == 1,AccessMode); - } - } while (feof(file) == 0); - - } - return ShortCuts; -} - -LanguageStringID CMainMenu::GetShortCutMenuItemName(MSC_MAP * ShortCuts, WORD key, bool bCtrl, bool bAlt, bool bShift, MENU_SHORT_CUT_KEY::ACCESS_MODE Access) { - for (MSC_MAP::iterator Item = ShortCuts->begin(); Item != ShortCuts->end(); Item++) { - MENU_SHORT_CUT & short_cut = Item->second; +/*LanguageStringID CMainMenu::GetShortCutMenuItemName(MSC_MAP * ShortCuts, WORD key, bool bCtrl, bool bAlt, bool bShift, CMenuShortCutKey::ACCESS_MODE Access) { + Notify().BreakPoint(__FILE__,__LINE__); + /*for (MSC_MAP::iterator Item = ShortCuts->begin(); Item != ShortCuts->end(); Item++) { + CMenuShortCutKey & short_cut = Item->second; for (SHORTCUT_KEY_LIST::const_iterator AccelItem = short_cut.GetAccelItems().begin(); AccelItem != short_cut.GetAccelItems().end(); AccelItem++) { if (!AccelItem->Same(key,bCtrl,bAlt,bShift,Access)) { continue; } @@ -1353,7 +1213,8 @@ LanguageStringID CMainMenu::GetShortCutMenuItemName(MSC_MAP * ShortCuts, WORD ke } void CMainMenu::SaveShortCuts(MSC_MAP * ShortCuts) { - stdstr FileName = _Settings->LoadString(ShortCutFile); + Notify().BreakPoint(__FILE__,__LINE__); + stdstr FileName = _Settings->LoadString(SupportFile_ShortCuts); FILE *file = fopen(FileName.c_str(),"w"); for (MSC_MAP::iterator Item = ShortCuts->begin(); Item != ShortCuts->end(); Item++) { for (SHORTCUT_KEY_LIST::const_iterator ShortCut = Item->second.GetAccelItems().begin(); ShortCut != Item->second.GetAccelItems().end(); ShortCut++) { @@ -1362,4 +1223,4 @@ void CMainMenu::SaveShortCuts(MSC_MAP * ShortCuts) { } } fclose(file); -} +}*/ diff --git a/Source/Project64/User Interface/Main Menu Class.h b/Source/Project64/User Interface/Main Menu Class.h index a597be59a..1d1c1e169 100644 --- a/Source/Project64/User Interface/Main Menu Class.h +++ b/Source/Project64/User Interface/Main Menu Class.h @@ -49,29 +49,34 @@ enum MainMenuID { ID_HELP_CONTENTS, ID_HELP_GAMEFAQ, ID_HELP_SUPPORTFORUM, ID_HELP_HOMEPAGE, ID_HELP_ABOUTSETTINGFILES, ID_HELP_ABOUT, }; -class CMainMenu:public CBaseMenu { +class CMainMenu:public CBaseMenu +{ + typedef std::list SettingList; + CMainGui * _Gui; CN64System * _System; //MSC_MAP m_ShortCuts; void * m_AccelTable; bool m_ResetAccelerators; + CShortCuts m_ShortCuts; + SettingList m_ChangeSettingList; void FillOutMenu ( MENU_HANDLE hMenu ); - stdstr ShortCutString(MSC_MAP & ShortCuts, int MenuID, MENU_SHORT_CUT_KEY::ACCESS_MODE AccessLevel); + //stdstr ShortCutString(MSC_MAP & ShortCuts, int MenuID, CMenuShortCutKey::ACCESS_MODE AccessLevel); stdstr GetSaveSlotString ( int Slot ); stdstr GetFileLastMod ( stdstr FileName ); void RebuildAccelerators ( void ); - + + static void SettingsChanged (CMainMenu * _this ); public: CMainMenu ( CMainGui * Window, CN64System * N64System ); ~CMainMenu(); - int ProcessAccelerator ( WND_HANDLE hWnd, void * lpMsg ); + int ProcessAccelerator ( WND_HANDLE hWnd, void * lpMsg ); bool ProcessMessage ( WND_HANDLE hWnd, DWORD wNotifyCode, DWORD wID); void ResetMenu ( void ); void ResetAccelerators ( void ) { m_ResetAccelerators = true; } - MSC_MAP GetShortCutInfo ( bool InitialSettings ); - void SaveShortCuts ( MSC_MAP * ShortCuts ); - LanguageStringID GetShortCutMenuItemName (MSC_MAP * ShortCuts, WORD key, bool bCtrl, bool bAlt, bool bShift, MENU_SHORT_CUT_KEY::ACCESS_MODE Access); +// void SaveShortCuts ( MSC_MAP * ShortCuts ); +// LanguageStringID GetShortCutMenuItemName (MSC_MAP * ShortCuts, WORD key, bool bCtrl, bool bAlt, bool bShift, CMenuShortCutKey::ACCESS_MODE Access); }; diff --git a/Source/Project64/User Interface/Menu Class.cpp b/Source/Project64/User Interface/Menu Class.cpp index b41ce5fdf..546940017 100644 --- a/Source/Project64/User Interface/Menu Class.cpp +++ b/Source/Project64/User Interface/Menu Class.cpp @@ -64,217 +64,8 @@ bool CBaseMenu::AddMenu(MENU_HANDLE hMenu, MenuItemList Items ) { return true; } -VIRTUAL_KEY MENU_SHORT_CUT_KEY::m_VirtualKeyList[] = { - { "VK_LBUTTON", 0x01, "VK_LBUTTON" }, - { "VK_RBUTTON", 0x02, "VK_RBUTTON" }, - { "VK_CANCEL", 0x03, "VK_CANCEL" }, - { "VK_MBUTTON", 0x04, "VK_MBUTTON" }, - { "VK_XBUTTON1", 0x05, "VK_XBUTTON1" }, - { "VK_XBUTTON2", 0x06, "VK_XBUTTON2" }, - { "VK_BACK", 0x08, "VK_BACK" }, - { "VK_TAB", 0x09, "VK_TAB" }, - { "VK_CLEAR", 0x0C, "VK_CLEAR" }, - { "VK_RETURN", 0x0D, "Return" }, - { "VK_SHIFT", 0x10, "VK_SHIFT" }, - { "VK_CONTROL", 0x11, "VK_CONTROL" }, - { "VK_MENU", 0x12, "VK_MENU" }, - { "VK_PAUSE", 0x13, "Pause" }, - { "VK_CAPITAL", 0x14, "VK_CAPITAL" }, - { "VK_KANA", 0x15, "VK_KANA" }, - { "VK_HANGUL", 0x15, "VK_HANGUL" }, - { "VK_JUNJA", 0x17, "VK_JUNJA" }, - { "VK_FINAL", 0x18, "VK_FINAL" }, - { "VK_HANJA", 0x19, "VK_HANJA" }, - { "VK_KANJI", 0x19, "VK_KANJI" }, - { "VK_ESCAPE", 0x1B, "Esc" }, - { "VK_CONVERT", 0x1C, "VK_CONVERT" }, - { "VK_NONCONVERT", 0x1D, "VK_NONCONVERT" }, - { "VK_ACCEPT", 0x1E, "VK_ACCEPT" }, - { "VK_MODECHANGE", 0x1F, "VK_MODECHANGE" }, - { "VK_SPACE", 0x20, "Space" }, - { "VK_PRIOR", 0x21, "Page Up" }, - { "VK_NEXT", 0x22, "Page Down" }, - { "VK_END", 0x23, "End" }, - { "VK_HOME", 0x24, "Home" }, - { "VK_LEFT", 0x25, "Left" }, - { "VK_UP", 0x26, "Up" }, - { "VK_RIGHT", 0x27, "Right" }, - { "VK_DOWN", 0x28, "Down" }, - { "VK_SELECT", 0x29, "VK_SELECT" }, - { "VK_PRINT", 0x2A, "VK_PRINT" }, - { "VK_EXECUTE", 0x2B, "VK_EXECUTE" }, - { "VK_SNAPSHOT", 0x2C, "VK_SNAPSHOT" }, - { "VK_INSERT", 0x2D, "Insert" }, - { "VK_DELETE", 0x2E, "Delete" }, - { "VK_HELP", 0x2F, "Help" }, - { "VK_0", 0x30, "0" }, - { "VK_1", 0x31, "1" }, - { "VK_2", 0x32, "2" }, - { "VK_3", 0x33, "3" }, - { "VK_4", 0x34, "4" }, - { "VK_5", 0x35, "5" }, - { "VK_6", 0x36, "6" }, - { "VK_7", 0x37, "7" }, - { "VK_8", 0x38, "8" }, - { "VK_9", 0x39, "9" }, - { "VK_A", 0x41, "A" }, - { "VK_B", 0x42, "B" }, - { "VK_C", 0x43, "C" }, - { "VK_D", 0x44, "D" }, - { "VK_E", 0x45, "E" }, - { "VK_F", 0x46, "F" }, - { "VK_G", 0x47, "G" }, - { "VK_H", 0x48, "H" }, - { "VK_I", 0x49, "I" }, - { "VK_J", 0x4A, "J" }, - { "VK_K", 0x4B, "K" }, - { "VK_L", 0x4C, "L" }, - { "VK_M", 0x4D, "M" }, - { "VK_N", 0x4E, "N" }, - { "VK_O", 0x4F, "O" }, - { "VK_P", 0x50, "P" }, - { "VK_Q", 0x51, "Q" }, - { "VK_R", 0x52, "R" }, - { "VK_S", 0x53, "S" }, - { "VK_T", 0x54, "T" }, - { "VK_U", 0x55, "U" }, - { "VK_V", 0x56, "V" }, - { "VK_W", 0x57, "W" }, - { "VK_X", 0x58, "X" }, - { "VK_Y", 0x59, "Y" }, - { "VK_Z", 0x5A, "Z" }, - { "VK_LWIN", 0x5B, "VK_LWIN" }, - { "VK_RWIN", 0x5C, "VK_RWIN" }, - { "VK_APPS", 0x5D, "VK_APPS" }, - { "VK_SLEEP", 0x5D, "VK_SLEEP" }, - { "VK_NUMPAD0", 0x60, "Numpad0" }, - { "VK_NUMPAD1", 0x61, "Numpad1" }, - { "VK_NUMPAD2", 0x62, "Numpad2" }, - { "VK_NUMPAD3", 0x63, "Numpad3" }, - { "VK_NUMPAD4", 0x64, "Numpad4" }, - { "VK_NUMPAD5", 0x65, "Numpad5" }, - { "VK_NUMPAD6", 0x66, "Numpad6" }, - { "VK_NUMPAD7", 0x67, "Numpad7" }, - { "VK_NUMPAD8", 0x68, "Numpad8" }, - { "VK_NUMPAD9", 0x69, "Numpad9" }, - { "VK_MULTIPLY", 0x6A, "*" }, - { "VK_ADD", 0x6B, "+" }, - { "VK_SEPARATOR", 0x6C, "" }, - { "VK_SUBTRACT", 0x6D, "-" }, - { "VK_DECIMAL", 0x6E, "." }, - { "VK_DIVIDE", 0x6F, "/" }, - { "VK_F1", 0x70, "F1" }, - { "VK_F2", 0x71, "F2" }, - { "VK_F3", 0x72, "F3" }, - { "VK_F4", 0x73, "F4" }, - { "VK_F5", 0x74, "F5" }, - { "VK_F6", 0x75, "F6" }, - { "VK_F7", 0x76, "F7" }, - { "VK_F8", 0x77, "F8" }, - { "VK_F9", 0x78, "F9" }, - { "VK_F10", 0x79, "F10" }, - { "VK_F11", 0x7A, "F11" }, - { "VK_F12", 0x7B, "F12" }, - { "VK_F13", 0x7C, "F13" }, - { "VK_F14", 0x7D, "F14" }, - { "VK_F15", 0x7E, "F15" }, - { "VK_F16", 0x7F, "F16" }, - { "VK_F17", 0x80, "F17" }, - { "VK_F18", 0x81, "F18" }, - { "VK_F19", 0x82, "F19" }, - { "VK_F20", 0x83, "F20" }, - { "VK_F21", 0x84, "F21" }, - { "VK_F22", 0x85, "F22" }, - { "VK_F23", 0x86, "F23" }, - { "VK_F24", 0x87, "F24" }, - { "VK_NUMLOCK", 0x90, "Numlock" }, - { "VK_SCROLL", 0x91, "VK_SCROLL" }, - { "VK_LSHIFT", 0xA0, "VK_LSHIFT" }, - { "VK_RSHIFT", 0xA1, "VK_RSHIFT" }, - { "VK_LCONTROL", 0xA2, "VK_LCONTROL" }, - { "VK_RCONTROL", 0xA3, "VK_RCONTROL" }, - { "VK_LMENU", 0xA4, "VK_LMENU" }, - { "VK_RMENU", 0xA5, "VK_RMENU" }, - { "VK_BROWSER_BACK", 0xA6, "" }, - { "VK_BROWSER_FORWARD",0xA7, "" }, - { "VK_BROWSER_REFRESH",0xA8, "" }, - { "VK_BROWSER_STOP", 0xA9, "" }, - { "VK_BROWSER_SEARCH", 0xAA, "" }, - { "VK_BROWSER_FAVORITES",0xAB, "" }, - { "VK_BROWSER_HOME", 0xAC, "" }, - { "VK_VOLUME_MUTE", 0xAD, "" }, - { "VK_VOLUME_DOWN", 0xAE, "" }, - { "VK_VOLUME_UP", 0xAF, "" }, - { "VK_MEDIA_NEXT_TRACK",0xB0, "" }, - { "VK_MEDIA_PREV_TRACK",0xB1, "" }, - { "VK_MEDIA_STOP", 0xB2, "" }, - { "VK_MEDIA_PLAY_PAUSE",0xB3, "" }, - { "VK_LAUNCH_MAIL", 0xB4, "" }, - { "VK_LAUNCH_MEDIA_SELECT",0xB5, "" }, - { "VK_LAUNCH_APP1", 0xB6, "" }, - { "VK_LAUNCH_APP2", 0xB7, "" }, - { "VK_OEM_1 (;:)", 0xBA, "" }, - { "VK_OEM_PLUS", 0xBB, "+" }, - { "VK_OEM_COMMA", 0xBC, "" }, - { "VK_OEM_MINUS", 0xBD, "-" }, - { "VK_OEM_PERIOD", 0xBE, "." }, - { "VK_OEM_2 (/?)", 0xBF, "" }, - { "VK_OEM_3 (`~)", 0xC0, "~" }, - { "VK_ATTN", 0xF6, "" }, - { "VK_CRSEL", 0xF7, "" }, - { "VK_EXSEL", 0xF8, "" }, - { "VK_EREOF", 0xF9, "" }, - { "VK_PLAY", 0xFA, "" }, - { "VK_ZOOM", 0xFB, "" }, - { "VK_NONAME", 0xFC, "" }, - { "VK_PA1", 0xFD, "" }, - { "VK_OEM_CLEAR", 0xFE } -}; -MENU_SHORT_CUT_KEY::MENU_SHORT_CUT_KEY(void) : - m_key(0),m_bCtrl(false),m_bAlt(false),m_bShift(false),m_AccessMode(NONE) -{ -} - -MENU_SHORT_CUT_KEY::MENU_SHORT_CUT_KEY(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode ) { - m_key = key; - m_bCtrl = bCtrl; - m_bAlt = bAlt; - m_bShift = bShift; - m_AccessMode = AccessMode; - - m_ShortCutName = ""; - for (int count = 0; count < sizeof(m_VirtualKeyList)/sizeof(m_VirtualKeyList[0]);count++){ - if (key == m_VirtualKeyList[count].Key) { - m_ShortCutName = m_VirtualKeyList[count].KeyName; - break; - } - } - if (m_bShift) { m_ShortCutName.Format("Shift+%s",m_ShortCutName.c_str()); } - if (m_bCtrl) { m_ShortCutName.Format("Ctrl+%s",m_ShortCutName.c_str()); } - if (m_bAlt) { m_ShortCutName.Format("Alt+%s",m_ShortCutName.c_str()); } -} - -bool MENU_SHORT_CUT_KEY::Same(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode) const -{ - if (key != m_key) { return false; } - if (bShift != m_bShift) { return false; } - if (bCtrl != m_bCtrl) { return false; } - if (bAlt != m_bAlt) { return false; } - if ((m_AccessMode & AccessMode) != AccessMode ) { return false; } - return true; -} - -VIRTUAL_KEY * MENU_SHORT_CUT_KEY::VirtualKeyList(int &Size) { - Size = sizeof(m_VirtualKeyList) / sizeof(m_VirtualKeyList[0]); - return (VIRTUAL_KEY *)m_VirtualKeyList; -} - -void MENU_SHORT_CUT::AddShortCut(WORD key, bool bCtrl, bool bAlt, bool bShift, MENU_SHORT_CUT_KEY::ACCESS_MODE AccessMode) { - m_AccelList.push_back(MENU_SHORT_CUT_KEY(key,bCtrl,bAlt,bShift,AccessMode)); -} - -void MENU_SHORT_CUT::RemoveItem ( MENU_SHORT_CUT_KEY * ShortCut ) +/*void MENU_SHORT_CUT::RemoveItem ( MENU_SHORT_CUT_KEY * ShortCut ) { for (SHORTCUT_KEY_LIST::iterator item = m_AccelList.begin(); item != m_AccelList.end(); item++) { if (ShortCut == &*item) { @@ -283,5 +74,5 @@ void MENU_SHORT_CUT::RemoveItem ( MENU_SHORT_CUT_KEY * ShortCut ) } } -} +}*/ diff --git a/Source/Project64/User Interface/Menu Class.h b/Source/Project64/User Interface/Menu Class.h index 3bbee9653..3e65cd4d2 100644 --- a/Source/Project64/User Interface/Menu Class.h +++ b/Source/Project64/User Interface/Menu Class.h @@ -1,53 +1,9 @@ #ifndef __MENU_CLASS__H__ #define __MENU_CLASS__H__ -typedef struct { - LPCSTR Name; - int Key; - LPCSTR KeyName; -} VIRTUAL_KEY; - #include -class MENU_SHORT_CUT_KEY { -public: - enum ACCESS_MODE { - NONE = 0, - GAME_NOT_RUNNING = 1, - GAME_RUNNING_WINDOW = 2, - NOT_IN_FULLSCREEN = 3, - GAME_RUNNING_FULLSCREEN = 4, - GAME_RUNNING = 6, - ANYTIME = 7, - } ; -private: - static VIRTUAL_KEY m_VirtualKeyList[]; - - stdstr m_ShortCutName; - WORD m_key; - bool m_bCtrl; - bool m_bAlt; - bool m_bShift; - ACCESS_MODE m_AccessMode; - -public: - MENU_SHORT_CUT_KEY(void); - MENU_SHORT_CUT_KEY(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode ); - bool Same (WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode ) const; - - static VIRTUAL_KEY * VirtualKeyList(int &Size); - - inline stdstr Name ( void ) const { return m_ShortCutName; } - inline WORD Key ( void ) const { return m_key; } - inline bool Ctrl ( void ) const { return m_bCtrl; } - inline bool Alt ( void ) const { return m_bAlt; } - inline bool Shift ( void ) const { return m_bShift; } - inline ACCESS_MODE AccessMode ( void ) const { return m_AccessMode; } -}; - -typedef std::list SHORTCUT_KEY_LIST; - -class MENU_SHORT_CUT { +/*class MENU_SHORT_CUT { MENU_SHORT_CUT_KEY::ACCESS_MODE m_Access; LanguageStringID m_Section; LanguageStringID m_Title; @@ -74,7 +30,7 @@ public: }; typedef std::map MENU_SHORT_CUT_MAP; -typedef MENU_SHORT_CUT_MAP MSC_MAP; +typedef MENU_SHORT_CUT_MAP MSC_MAP;*/ enum Menu_ID { //ControlID @@ -129,9 +85,9 @@ public: virtual bool ProcessMessage(WND_HANDLE hWnd, DWORD wNotifyCode, DWORD wID) = 0; // pure virtual draw() function virtual void ResetMenu(void) = 0; // pure virtual draw() function MENU_HANDLE GetHandle (void) { return m_MenuHandle; } - virtual MSC_MAP GetShortCutInfo(bool InitialSettings) = 0; // pure virtual draw() function - virtual void SaveShortCuts ( MSC_MAP * ShortCuts ) = 0; - virtual LanguageStringID GetShortCutMenuItemName(MSC_MAP * ShortCuts, WORD key, bool bCtrl, bool bAlt, bool bShift, MENU_SHORT_CUT_KEY::ACCESS_MODE Access ) = 0; // pure virtual draw() function + //virtual MSC_MAP GetShortCutInfo(bool InitialSettings) = 0; // pure virtual draw() function + //virtual void SaveShortCuts ( MSC_MAP * ShortCuts ) = 0; + //virtual LanguageStringID GetShortCutMenuItemName(MSC_MAP * ShortCuts, WORD key, bool bCtrl, bool bAlt, bool bShift, CMenuShortCutKey::ACCESS_MODE Access ) = 0; // pure virtual draw() function }; #endif \ No newline at end of file diff --git a/Source/Project64/User Interface/MenuShortCuts.cpp b/Source/Project64/User Interface/MenuShortCuts.cpp new file mode 100644 index 000000000..be86b4b76 --- /dev/null +++ b/Source/Project64/User Interface/MenuShortCuts.cpp @@ -0,0 +1,486 @@ +#include "..\\User Interface.h" +#include + +VIRTUAL_KEY CMenuShortCutKey::m_VirtualKeyList[] = { + { "VK_LBUTTON", 0x01, "VK_LBUTTON" }, + { "VK_RBUTTON", 0x02, "VK_RBUTTON" }, + { "VK_CANCEL", 0x03, "VK_CANCEL" }, + { "VK_MBUTTON", 0x04, "VK_MBUTTON" }, + { "VK_XBUTTON1", 0x05, "VK_XBUTTON1" }, + { "VK_XBUTTON2", 0x06, "VK_XBUTTON2" }, + { "VK_BACK", 0x08, "VK_BACK" }, + { "VK_TAB", 0x09, "VK_TAB" }, + { "VK_CLEAR", 0x0C, "VK_CLEAR" }, + { "VK_RETURN", 0x0D, "Return" }, + { "VK_SHIFT", 0x10, "VK_SHIFT" }, + { "VK_CONTROL", 0x11, "VK_CONTROL" }, + { "VK_MENU", 0x12, "VK_MENU" }, + { "VK_PAUSE", 0x13, "Pause" }, + { "VK_CAPITAL", 0x14, "VK_CAPITAL" }, + { "VK_KANA", 0x15, "VK_KANA" }, + { "VK_HANGUL", 0x15, "VK_HANGUL" }, + { "VK_JUNJA", 0x17, "VK_JUNJA" }, + { "VK_FINAL", 0x18, "VK_FINAL" }, + { "VK_HANJA", 0x19, "VK_HANJA" }, + { "VK_KANJI", 0x19, "VK_KANJI" }, + { "VK_ESCAPE", 0x1B, "Esc" }, + { "VK_CONVERT", 0x1C, "VK_CONVERT" }, + { "VK_NONCONVERT", 0x1D, "VK_NONCONVERT" }, + { "VK_ACCEPT", 0x1E, "VK_ACCEPT" }, + { "VK_MODECHANGE", 0x1F, "VK_MODECHANGE" }, + { "VK_SPACE", 0x20, "Space" }, + { "VK_PRIOR", 0x21, "Page Up" }, + { "VK_NEXT", 0x22, "Page Down" }, + { "VK_END", 0x23, "End" }, + { "VK_HOME", 0x24, "Home" }, + { "VK_LEFT", 0x25, "Left" }, + { "VK_UP", 0x26, "Up" }, + { "VK_RIGHT", 0x27, "Right" }, + { "VK_DOWN", 0x28, "Down" }, + { "VK_SELECT", 0x29, "VK_SELECT" }, + { "VK_PRINT", 0x2A, "VK_PRINT" }, + { "VK_EXECUTE", 0x2B, "VK_EXECUTE" }, + { "VK_SNAPSHOT", 0x2C, "VK_SNAPSHOT" }, + { "VK_INSERT", 0x2D, "Insert" }, + { "VK_DELETE", 0x2E, "Delete" }, + { "VK_HELP", 0x2F, "Help" }, + { "VK_0", 0x30, "0" }, + { "VK_1", 0x31, "1" }, + { "VK_2", 0x32, "2" }, + { "VK_3", 0x33, "3" }, + { "VK_4", 0x34, "4" }, + { "VK_5", 0x35, "5" }, + { "VK_6", 0x36, "6" }, + { "VK_7", 0x37, "7" }, + { "VK_8", 0x38, "8" }, + { "VK_9", 0x39, "9" }, + { "VK_A", 0x41, "A" }, + { "VK_B", 0x42, "B" }, + { "VK_C", 0x43, "C" }, + { "VK_D", 0x44, "D" }, + { "VK_E", 0x45, "E" }, + { "VK_F", 0x46, "F" }, + { "VK_G", 0x47, "G" }, + { "VK_H", 0x48, "H" }, + { "VK_I", 0x49, "I" }, + { "VK_J", 0x4A, "J" }, + { "VK_K", 0x4B, "K" }, + { "VK_L", 0x4C, "L" }, + { "VK_M", 0x4D, "M" }, + { "VK_N", 0x4E, "N" }, + { "VK_O", 0x4F, "O" }, + { "VK_P", 0x50, "P" }, + { "VK_Q", 0x51, "Q" }, + { "VK_R", 0x52, "R" }, + { "VK_S", 0x53, "S" }, + { "VK_T", 0x54, "T" }, + { "VK_U", 0x55, "U" }, + { "VK_V", 0x56, "V" }, + { "VK_W", 0x57, "W" }, + { "VK_X", 0x58, "X" }, + { "VK_Y", 0x59, "Y" }, + { "VK_Z", 0x5A, "Z" }, + { "VK_LWIN", 0x5B, "VK_LWIN" }, + { "VK_RWIN", 0x5C, "VK_RWIN" }, + { "VK_APPS", 0x5D, "VK_APPS" }, + { "VK_SLEEP", 0x5D, "VK_SLEEP" }, + { "VK_NUMPAD0", 0x60, "Numpad0" }, + { "VK_NUMPAD1", 0x61, "Numpad1" }, + { "VK_NUMPAD2", 0x62, "Numpad2" }, + { "VK_NUMPAD3", 0x63, "Numpad3" }, + { "VK_NUMPAD4", 0x64, "Numpad4" }, + { "VK_NUMPAD5", 0x65, "Numpad5" }, + { "VK_NUMPAD6", 0x66, "Numpad6" }, + { "VK_NUMPAD7", 0x67, "Numpad7" }, + { "VK_NUMPAD8", 0x68, "Numpad8" }, + { "VK_NUMPAD9", 0x69, "Numpad9" }, + { "VK_MULTIPLY", 0x6A, "*" }, + { "VK_ADD", 0x6B, "+" }, + { "VK_SEPARATOR", 0x6C, "" }, + { "VK_SUBTRACT", 0x6D, "-" }, + { "VK_DECIMAL", 0x6E, "." }, + { "VK_DIVIDE", 0x6F, "/" }, + { "VK_F1", 0x70, "F1" }, + { "VK_F2", 0x71, "F2" }, + { "VK_F3", 0x72, "F3" }, + { "VK_F4", 0x73, "F4" }, + { "VK_F5", 0x74, "F5" }, + { "VK_F6", 0x75, "F6" }, + { "VK_F7", 0x76, "F7" }, + { "VK_F8", 0x77, "F8" }, + { "VK_F9", 0x78, "F9" }, + { "VK_F10", 0x79, "F10" }, + { "VK_F11", 0x7A, "F11" }, + { "VK_F12", 0x7B, "F12" }, + { "VK_F13", 0x7C, "F13" }, + { "VK_F14", 0x7D, "F14" }, + { "VK_F15", 0x7E, "F15" }, + { "VK_F16", 0x7F, "F16" }, + { "VK_F17", 0x80, "F17" }, + { "VK_F18", 0x81, "F18" }, + { "VK_F19", 0x82, "F19" }, + { "VK_F20", 0x83, "F20" }, + { "VK_F21", 0x84, "F21" }, + { "VK_F22", 0x85, "F22" }, + { "VK_F23", 0x86, "F23" }, + { "VK_F24", 0x87, "F24" }, + { "VK_NUMLOCK", 0x90, "Numlock" }, + { "VK_SCROLL", 0x91, "VK_SCROLL" }, + { "VK_LSHIFT", 0xA0, "VK_LSHIFT" }, + { "VK_RSHIFT", 0xA1, "VK_RSHIFT" }, + { "VK_LCONTROL", 0xA2, "VK_LCONTROL" }, + { "VK_RCONTROL", 0xA3, "VK_RCONTROL" }, + { "VK_LMENU", 0xA4, "VK_LMENU" }, + { "VK_RMENU", 0xA5, "VK_RMENU" }, + { "VK_BROWSER_BACK", 0xA6, "" }, + { "VK_BROWSER_FORWARD",0xA7, "" }, + { "VK_BROWSER_REFRESH",0xA8, "" }, + { "VK_BROWSER_STOP", 0xA9, "" }, + { "VK_BROWSER_SEARCH", 0xAA, "" }, + { "VK_BROWSER_FAVORITES",0xAB, "" }, + { "VK_BROWSER_HOME", 0xAC, "" }, + { "VK_VOLUME_MUTE", 0xAD, "" }, + { "VK_VOLUME_DOWN", 0xAE, "" }, + { "VK_VOLUME_UP", 0xAF, "" }, + { "VK_MEDIA_NEXT_TRACK",0xB0, "" }, + { "VK_MEDIA_PREV_TRACK",0xB1, "" }, + { "VK_MEDIA_STOP", 0xB2, "" }, + { "VK_MEDIA_PLAY_PAUSE",0xB3, "" }, + { "VK_LAUNCH_MAIL", 0xB4, "" }, + { "VK_LAUNCH_MEDIA_SELECT",0xB5, "" }, + { "VK_LAUNCH_APP1", 0xB6, "" }, + { "VK_LAUNCH_APP2", 0xB7, "" }, + { "VK_OEM_1 (;:)", 0xBA, "" }, + { "VK_OEM_PLUS", 0xBB, "+" }, + { "VK_OEM_COMMA", 0xBC, "" }, + { "VK_OEM_MINUS", 0xBD, "-" }, + { "VK_OEM_PERIOD", 0xBE, "." }, + { "VK_OEM_2 (/?)", 0xBF, "" }, + { "VK_OEM_3 (`~)", 0xC0, "~" }, + { "VK_ATTN", 0xF6, "" }, + { "VK_CRSEL", 0xF7, "" }, + { "VK_EXSEL", 0xF8, "" }, + { "VK_EREOF", 0xF9, "" }, + { "VK_PLAY", 0xFA, "" }, + { "VK_ZOOM", 0xFB, "" }, + { "VK_NONAME", 0xFC, "" }, + { "VK_PA1", 0xFD, "" }, + { "VK_OEM_CLEAR", 0xFE } +}; + +CMenuShortCutKey::CMenuShortCutKey (WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive ) : + m_key(key), + m_bCtrl(bCtrl), + m_bAlt(bAlt), + m_bShift(bShift), + m_AccessMode(AccessMode), + m_bUserAdded(bUserAdded), + m_bInactive(bInactive) +{ + m_ShortCutName = ""; + for (int i = 0, n = sizeof(m_VirtualKeyList)/sizeof(m_VirtualKeyList[0]); i < n;i++) + { + if (key == m_VirtualKeyList[i].Key) + { + m_ShortCutName = m_VirtualKeyList[i].KeyName; + break; + } + } + if (m_bShift) { m_ShortCutName.Format("Shift+%s",m_ShortCutName.c_str()); } + if (m_bCtrl) { m_ShortCutName.Format("Ctrl+%s",m_ShortCutName.c_str()); } + if (m_bAlt) { m_ShortCutName.Format("Alt+%s",m_ShortCutName.c_str()); } +} + +VIRTUAL_KEY * CMenuShortCutKey::VirtualKeyList(int &Size) { + Size = sizeof(m_VirtualKeyList) / sizeof(m_VirtualKeyList[0]); + return (VIRTUAL_KEY *)m_VirtualKeyList; +} + +bool CMenuShortCutKey::Same(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode) const +{ + if (key != m_key) { return false; } + if (bShift != m_bShift) { return false; } + if (bCtrl != m_bCtrl) { return false; } + if (bAlt != m_bAlt) { return false; } + if ((m_AccessMode & AccessMode) != AccessMode ) { return false; } + return true; +} + + +CShortCutItem::CShortCutItem(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access) +{ + Reset(Section, Title,Access); +} + +void CShortCutItem::Reset ( LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access) +{ + this->m_Section = Section; + this->m_Title = Title; + this->m_Access = Access; +} + +void CShortCutItem::AddShortCut (WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive) +{ + m_AccelList.push_back(CMenuShortCutKey(key,bCtrl,bAlt,bShift,AccessMode,bUserAdded,bInactive)); +} + +void CShortCutItem::RemoveItem ( CMenuShortCutKey * ShortCut ) +{ + if (ShortCut->UserAdded()) + { + for (SHORTCUT_KEY_LIST::iterator item = m_AccelList.begin(); item != m_AccelList.end(); item++) + { + if (ShortCut == &*item) + { + m_AccelList.erase(item); + break; + } + } + } else { + ShortCut->SetInactive(true); + } +} + +CShortCuts::CShortCuts () +{ + Load(); +} + +CShortCuts::~CShortCuts() +{ +} + +stdstr CShortCuts::ShortCutString( int MenuID, CMenuShortCutKey::ACCESS_MODE AccessLevel ) +{ + MSC_MAP::iterator MenuItem = m_ShortCuts.find(MenuID); + if (MenuItem == m_ShortCuts.end()) { return ""; } + + const SHORTCUT_KEY_LIST & ShortCutList = MenuItem->second.GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator item = ShortCutList.begin(); item != ShortCutList.end(); item++) + { + ACCESS_MODE ItemMode = item->AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel ) + { + continue; + } + if (item->Inactive()) + { + continue; + } + return item->Name(); + } + return ""; +} + +LanguageStringID CShortCuts::GetMenuItemName( WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE Access ) +{ + for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) + { + CShortCutItem & short_cut = Item->second; + + for (SHORTCUT_KEY_LIST::const_iterator AccelItem = short_cut.GetAccelItems().begin(); AccelItem != short_cut.GetAccelItems().end(); AccelItem++) + { + if (!AccelItem->Same(key,bCtrl,bAlt,bShift,Access)) { continue; } + return short_cut.Title(); + } + } + return EMPTY_STRING; +} + +void CShortCuts::AddShortCut( WORD ID, LanguageStringID Section, LanguageStringID LangID, CMenuShortCutKey::ACCESS_MODE AccessMode) +{ + m_ShortCuts.insert(MSC_MAP::value_type(ID,CShortCutItem(Section,LangID,AccessMode))); +} + +void CShortCuts::Load (bool InitialValues ) +{ + m_ShortCuts.clear(); + + AddShortCut(ID_FILE_OPEN_ROM, STR_SHORTCUT_FILEMENU, MENU_OPEN, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_FILE_ROM_INFO, STR_SHORTCUT_FILEMENU, MENU_ROM_INFO, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_FILE_STARTEMULATION, STR_SHORTCUT_FILEMENU, MENU_START, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_FILE_ENDEMULATION, STR_SHORTCUT_FILEMENU, MENU_END, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_FILE_ROMDIRECTORY, STR_SHORTCUT_FILEMENU, MENU_CHOOSE_ROM, CMenuShortCutKey::GAME_NOT_RUNNING ); + AddShortCut(ID_FILE_REFRESHROMLIST, STR_SHORTCUT_FILEMENU, MENU_REFRESH, CMenuShortCutKey::GAME_NOT_RUNNING ); + AddShortCut(ID_FILE_EXIT, STR_SHORTCUT_FILEMENU, MENU_EXIT, CMenuShortCutKey::ANYTIME ); + + AddShortCut(ID_SYSTEM_RESET_SOFT, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_SOFT, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_SYSTEM_RESET_HARD, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_HARD, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_SYSTEM_PAUSE, STR_SHORTCUT_SYSTEMMENU, MENU_PAUSE, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_SYSTEM_BITMAP, STR_SHORTCUT_SYSTEMMENU, MENU_BITMAP, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_SYSTEM_LIMITFPS, STR_SHORTCUT_SYSTEMMENU, MENU_LIMIT_FPS, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_SYSTEM_SAVE, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_SYSTEM_SAVEAS, STR_SHORTCUT_SYSTEMMENU, MENU_SAVE_AS, CMenuShortCutKey::GAME_RUNNING_WINDOW ); + AddShortCut(ID_SYSTEM_RESTORE, STR_SHORTCUT_SYSTEMMENU, MENU_RESTORE, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_SYSTEM_LOAD, STR_SHORTCUT_SYSTEMMENU, MENU_LOAD, CMenuShortCutKey::GAME_RUNNING_WINDOW ); + AddShortCut(ID_SYSTEM_CHEAT, STR_SHORTCUT_SYSTEMMENU, MENU_CHEAT, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_SYSTEM_GSBUTTON, STR_SHORTCUT_SYSTEMMENU, MENU_GS_BUTTON, CMenuShortCutKey::GAME_RUNNING ); + + AddShortCut(ID_OPTIONS_DISPLAY_FR, STR_SHORTCUT_OPTIONS, OPTION_DISPLAY_FR,CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_OPTIONS_CHANGE_FR, STR_SHORTCUT_OPTIONS, OPTION_CHANGE_FR, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_OPTIONS_INCREASE_SPEED,STR_SHORTCUT_OPTIONS, STR_INSREASE_SPEED, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_OPTIONS_DECREASE_SPEED,STR_SHORTCUT_OPTIONS, STR_DECREASE_SPEED, CMenuShortCutKey::GAME_RUNNING ); + + AddShortCut(ID_CURRENT_SAVE_DEFAULT,STR_SHORTCUT_SAVESLOT, SAVE_SLOT_DEFAULT,CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_1, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_1, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_2, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_2, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_3, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_3, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_4, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_4, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_5, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_5, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_6, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_6, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_7, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_7, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_8, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_8, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_9, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_9, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_CURRENT_SAVE_10, STR_SHORTCUT_SAVESLOT, SAVE_SLOT_10, CMenuShortCutKey::GAME_RUNNING ); + + //Option Menu + AddShortCut(ID_OPTIONS_FULLSCREEN, STR_SHORTCUT_OPTIONS, MENU_FULL_SCREEN, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_OPTIONS_ALWAYSONTOP, STR_SHORTCUT_OPTIONS, MENU_ON_TOP, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_OPTIONS_CONFIG_GFX, STR_SHORTCUT_OPTIONS, MENU_CONFG_GFX, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_OPTIONS_CONFIG_AUDIO,STR_SHORTCUT_OPTIONS, MENU_CONFG_AUDIO, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_OPTIONS_CONFIG_CONT, STR_SHORTCUT_OPTIONS, MENU_CONFG_CTRL, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_OPTIONS_CONFIG_RSP, STR_SHORTCUT_OPTIONS, MENU_CONFG_RSP, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + AddShortCut(ID_OPTIONS_CPU_USAGE, STR_SHORTCUT_OPTIONS, MENU_SHOW_CPU, CMenuShortCutKey::GAME_RUNNING ); + AddShortCut(ID_OPTIONS_SETTINGS, STR_SHORTCUT_OPTIONS, MENU_SETTINGS, CMenuShortCutKey::NOT_IN_FULLSCREEN ); + + stdstr FileName = _Settings->LoadString(SupportFile_ShortCuts); + FILE *file = fopen(FileName.c_str(),"r"); + if (file == NULL || InitialValues) + { + m_ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O',TRUE,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_FILE_OPEN_ROM)->second.AddShortCut('O',TRUE,false,false,CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_STARTEMULATION)->second.AddShortCut(VK_F11,false,false,false,CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_ENDEMULATION)->second.AddShortCut(VK_F12,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_FILE_REFRESHROMLIST)->second.AddShortCut(VK_F5,false,false,false,CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4,false,true,false,CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_FILE_EXIT)->second.AddShortCut(VK_F4,false,true,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_DEFAULT)->second.AddShortCut(0xC0,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_1)->second.AddShortCut('1',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_2)->second.AddShortCut('2',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_3)->second.AddShortCut('3',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_4)->second.AddShortCut('4',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_5)->second.AddShortCut('5',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_6)->second.AddShortCut('6',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_7)->second.AddShortCut('7',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_8)->second.AddShortCut('8',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_9)->second.AddShortCut('9',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_CURRENT_SAVE_10)->second.AddShortCut('0',false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_RETURN,false,true,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_FULLSCREEN)->second.AddShortCut(VK_ESCAPE,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A',true,false,false,CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_OPTIONS_ALWAYSONTOP)->second.AddShortCut('A',true,false,false,CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T',true,false,false,CMenuShortCutKey::GAME_NOT_RUNNING); + m_ShortCuts.find(ID_OPTIONS_SETTINGS)->second.AddShortCut('T',true,false,false,CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_RESET_SOFT)->second.AddShortCut(VK_F1,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_RESET_HARD)->second.AddShortCut(VK_F1,false,false,true,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_F2,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_PAUSE)->second.AddShortCut(VK_PAUSE,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_BITMAP)->second.AddShortCut(VK_F3,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_LIMITFPS)->second.AddShortCut(VK_F4,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_SAVE)->second.AddShortCut(VK_F5,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_RESTORE)->second.AddShortCut(VK_F7,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_SYSTEM_LOAD)->second.AddShortCut('L',true,false,false,CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_SAVEAS)->second.AddShortCut('S',true,false,false,CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_CHEAT)->second.AddShortCut('C',true,false,false,CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_ShortCuts.find(ID_SYSTEM_GSBUTTON)->second.AddShortCut(VK_F9,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_INCREASE_SPEED)->second.AddShortCut(VK_OEM_PLUS,false,false,false,CMenuShortCutKey::GAME_RUNNING); + m_ShortCuts.find(ID_OPTIONS_DECREASE_SPEED)->second.AddShortCut(VK_OEM_MINUS,false,false,false,CMenuShortCutKey::GAME_RUNNING); + } else if (file) { + CMenuShortCutKey::ACCESS_MODE AccessMode; + int ID, key, bCtrl, bAlt, bShift, bUserAdded, bInactive; + + do { + char Line[300]; + if (fgets(Line,sizeof(Line),file) != NULL) { + sscanf(Line,"%d,%d,%d,%d,%d,%d,%d,%d", &ID,&key,&bCtrl,&bAlt,&bShift,&AccessMode, + &bUserAdded,&bInactive); + + MSC_MAP::iterator item = m_ShortCuts.find(ID); + if (item == m_ShortCuts.end()) { continue; } + item->second.AddShortCut(key,bCtrl == 1,bAlt == 1,bShift == 1,AccessMode,bUserAdded == 1,bInactive == 1); + } + } while (feof(file) == 0); + + } +} + +void CShortCuts::Save( void ) +{ + stdstr FileName = _Settings->LoadString(SupportFile_ShortCuts); + FILE *file = fopen(FileName.c_str(),"w"); + if (file == NULL) + { + return; + } + + for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) + { + for (SHORTCUT_KEY_LIST::const_iterator ShortCut = Item->second.GetAccelItems().begin(); ShortCut != Item->second.GetAccelItems().end(); ShortCut++) + { + fprintf(file,"%d,%d,%d,%d,%d,%d,%d,%d\n", + Item->first, + ShortCut->Key(), + ShortCut->Ctrl(), + ShortCut->Alt(), + ShortCut->Shift(), + ShortCut->AccessMode(), + ShortCut->UserAdded(), + ShortCut->Inactive()); + } + } + fclose(file); +} + +HACCEL CShortCuts::GetAcceleratorTable ( void ) +{ + //Generate a ACCEL list + CMenuShortCutKey::ACCESS_MODE AccessLevel = CMenuShortCutKey::GAME_NOT_RUNNING; + if (_Settings->LoadBool(GameRunning_CPU_Running)) + { + AccessLevel = _Settings->LoadBool(UserInterface_InFullScreen) ? + CMenuShortCutKey::GAME_RUNNING_FULLSCREEN : + CMenuShortCutKey::GAME_RUNNING_WINDOW; + } + + int size = 0, MaxSize = m_ShortCuts.size() * 5; + ACCEL * AccelList = new ACCEL[MaxSize]; + + for (MSC_MAP::iterator Item = m_ShortCuts.begin(); Item != m_ShortCuts.end(); Item++) + { + CShortCutItem & short_cut = Item->second; + + CMenuShortCutKey::ACCESS_MODE ItemMode = short_cut.AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel ) + { + continue; + } + + SHORTCUT_KEY_LIST ShortCutAccelList = short_cut.GetAccelItems(); + for (SHORTCUT_KEY_LIST::iterator AccelIter = ShortCutAccelList.begin(); AccelIter != ShortCutAccelList.end(); AccelIter++) + { + CMenuShortCutKey & Key = *AccelIter; + if (Key.Inactive()) + { + continue; + } + if ((Key.AccessMode() & AccessLevel) != AccessLevel ) + { + continue; + } + if (size >= MaxSize) { break; } + AccelList[size].cmd = Item->first; + AccelList[size].key = Key.Key(); + AccelList[size].fVirt = FVIRTKEY; + if (Key.Alt()) { AccelList[size].fVirt |= FALT; } + if (Key.Ctrl()) { AccelList[size].fVirt |= FCONTROL; } + if (Key.Shift()) { AccelList[size].fVirt |= FSHIFT; } + size += 1; + } + } + + WriteTrace(TraceDebug,"CMainMenu::RebuildAccelerators - CreateAcceleratorTable"); + HACCEL AccelTable = CreateAcceleratorTable(AccelList,size); + WriteTrace(TraceDebug,"CMainMenu::RebuildAccelerators - Delete accel list"); + delete [] AccelList; + return AccelTable; +} diff --git a/Source/Project64/User Interface/MenuShortCuts.h b/Source/Project64/User Interface/MenuShortCuts.h new file mode 100644 index 000000000..0ff13686e --- /dev/null +++ b/Source/Project64/User Interface/MenuShortCuts.h @@ -0,0 +1,100 @@ +#pragma once + +typedef struct { + LPCSTR Name; + int Key; + LPCSTR KeyName; +} VIRTUAL_KEY; + +class CMenuShortCutKey { +public: + enum ACCESS_MODE { + NONE = 0, + GAME_NOT_RUNNING = 1, + GAME_RUNNING_WINDOW = 2, + NOT_IN_FULLSCREEN = 3, + GAME_RUNNING_FULLSCREEN = 4, + GAME_RUNNING = 6, + ANYTIME = 7, + } ; + +private: + static VIRTUAL_KEY m_VirtualKeyList[]; + + stdstr m_ShortCutName; + WORD m_key; + bool m_bCtrl; + bool m_bAlt; + bool m_bShift; + ACCESS_MODE m_AccessMode; + bool m_bUserAdded; + bool m_bInactive; + +public: + CMenuShortCutKey(void); + CMenuShortCutKey(WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded, bool bInactive ); + bool Same (WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode ) const; + + static VIRTUAL_KEY * VirtualKeyList(int &Size); + + inline stdstr Name ( void ) const { return m_ShortCutName; } + inline WORD Key ( void ) const { return m_key; } + inline bool Ctrl ( void ) const { return m_bCtrl; } + inline bool Alt ( void ) const { return m_bAlt; } + inline bool Shift ( void ) const { return m_bShift; } + inline bool UserAdded ( void ) const { return m_bUserAdded; } + inline bool Inactive ( void ) const { return m_bInactive; } + inline ACCESS_MODE AccessMode ( void ) const { return m_AccessMode; } + + inline void SetInactive ( bool Inactive ) { m_bInactive = Inactive; } +}; + +class CShortCutItem +{ +public: + typedef std::list SHORTCUT_KEY_LIST; + +private: + typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; + + ACCESS_MODE m_Access; + LanguageStringID m_Section; + LanguageStringID m_Title; + SHORTCUT_KEY_LIST m_AccelList; + +public: + CShortCutItem(LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access); + void Reset ( LanguageStringID Section, LanguageStringID Title, ACCESS_MODE Access); + void AddShortCut ( WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE AccessMode, bool bUserAdded = false, bool bInactive = false ); + void RemoveItem ( CMenuShortCutKey * ShortCut ); + + inline const SHORTCUT_KEY_LIST & GetAccelItems ( void ) const { return m_AccelList; } + inline LanguageStringID Section ( void ) const { return m_Section; } + inline LanguageStringID Title ( void ) const { return m_Title; } + inline ACCESS_MODE AccessMode ( void ) const { return m_Access; } +}; + +typedef std::map MSC_MAP; + +class CShortCuts +{ + typedef CShortCutItem::SHORTCUT_KEY_LIST SHORTCUT_KEY_LIST; + typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; + typedef LanguageStringID LangStr; + + MSC_MAP m_ShortCuts; + + void AddShortCut ( WORD ID, LangStr Section, LangStr LangID, CMenuShortCutKey::ACCESS_MODE AccessMode); + +public: + CShortCuts ( void ); + ~CShortCuts ( void ); + + stdstr ShortCutString ( int MenuID, ACCESS_MODE AccessLevel ); + LangStr GetMenuItemName ( WORD key, bool bCtrl, bool bAlt, bool bShift, ACCESS_MODE Access ); + HACCEL GetAcceleratorTable ( void ); + MSC_MAP &GetShortCuts ( void ) { return m_ShortCuts; } + + void Load ( bool InitialValues = false ); + void Save ( void ); +}; diff --git a/Source/Project64/User Interface/Notification Class.cpp b/Source/Project64/User Interface/Notification Class.cpp index abf12d6ea..b6445e011 100644 --- a/Source/Project64/User Interface/Notification Class.cpp +++ b/Source/Project64/User Interface/Notification Class.cpp @@ -22,6 +22,29 @@ void CNotification::SetMainWindow ( CMainGui * Gui ) { _hWnd = Gui; } +void CNotification::WindowMode ( void ) const +{ + static bool InsideFunc = false; + if (InsideFunc) + { + return; + } + InsideFunc = true; + if (InFullScreen()) + { + ChangeFullScreen(); + for (int i = 0; i < 5; i++) + { + Sleep(50); + if (ProcessGuiMessages()) + { + break; + } + } + } + InsideFunc = false; +} + void CNotification::DisplayError ( const char * Message, ... ) const { va_list ap; va_start( ap, Message ); @@ -32,6 +55,8 @@ void CNotification::DisplayError ( const char * Message, va_list ap ) const { if (this == NULL) { return; } char Msg[1000]; + WindowMode(); + _vsnprintf( Msg,sizeof(Msg) - 1,Message, ap ); va_end( ap ); HWND Parent = NULL; @@ -71,7 +96,7 @@ void CNotification::DisplayMessage ( int DisplayTime, const char * Message, va_ va_end( ap ); - if (bInFullScreen) + if (InFullScreen()) { if (_gfxPlugin && _gfxPlugin->DrawStatus) { @@ -107,7 +132,7 @@ void CNotification::SetGfxPlugin( CGfxPlugin * Plugin ) void CNotification::SetWindowCaption (const char * Caption) { char WinTitle[256]; - _snprintf( WinTitle, sizeof(WinTitle), "%s - %s", Caption, _Settings->LoadString(ApplicationName).c_str()); + _snprintf( WinTitle, sizeof(WinTitle), "%s - %s", Caption, _Settings->LoadString(Setting_ApplicationName).c_str()); WinTitle[sizeof(WinTitle) - 1] = 0; _hWnd->Caption(WinTitle); } @@ -116,6 +141,8 @@ void CNotification::FatalError ( const char * Message, ... ) const { char Msg[1000]; va_list ap; + WindowMode(); + va_start( ap, Message ); _vsnprintf( Msg,sizeof(Msg) - 1,Message, ap ); va_end( ap ); @@ -130,11 +157,12 @@ void CNotification::AddRecentDir ( const char * RomDir ) { if (HIWORD(RomDir) == NULL) { return; } //Get Information about the stored rom list + int MaxRememberedDirs = _Settings->LoadDword(Directory_RecentGameDirCount); strlist RecentDirs; int i; for (i = 0; i < MaxRememberedDirs; i ++ ) { - stdstr RecentDir = _Settings->LoadStringIndex(RecentRomDirIndex,i); + stdstr RecentDir = _Settings->LoadStringIndex(Directory_RecentGameDirIndex,i); if (RecentDir.empty()) { break; @@ -161,7 +189,7 @@ void CNotification::AddRecentDir ( const char * RomDir ) { for (i = 0, iter = RecentDirs.begin(); iter != RecentDirs.end(); iter++, i++) { - _Settings->SaveStringIndex(RecentRomDirIndex,i,*iter); + _Settings->SaveStringIndex(Directory_RecentGameDirIndex,i,*iter); } } @@ -169,38 +197,40 @@ void CNotification::AddRecentRom ( const char * ImagePath ) { if (HIWORD(ImagePath) == NULL) { return; } //Get Information about the stored rom list -/* int count; - char RecentRoms[MaxRememberedFiles][_MAX_PATH]; - Notify().BreakPoint(__FILE__,__LINE__); - for (count = 0; count < RememberedRomFilesCount; count ++ ) { - strcpy(RecentRoms[count],""); - //_Settings->LoadString((SettingID)(FirstRecentRom + count), RecentRoms[count], sizeof(RecentRoms[count])); - Notify().BreakPoint(__FILE__,__LINE__); + int MaxRememberedFiles = _Settings->LoadDword(File_RecentGameFileCount); + strlist RecentGames; + int i; + for (i = 0; i < MaxRememberedFiles; i ++ ) + { + stdstr RecentGame = _Settings->LoadStringIndex(File_RecentGameFileIndex,i); + if (RecentGame.empty()) + { + break; + } + RecentGames.push_back(RecentGame); } - //See if the Image Path is already in the list if so then move it to the top of the list - bool bFound = false; - for (count = 0; count < MaxRememberedFiles && !bFound; count ++ ) { - if (strcmp(ImagePath, RecentRoms[count]) == 0) { - if (count != 0) { - memmove(&RecentRoms[1],&RecentRoms[0],sizeof(RecentRoms[0]) * count); - } - bFound = true; + //See if the dir is already in the list if so then move it to the top of the list + strlist::iterator iter; + for (iter = RecentGames.begin(); iter != RecentGames.end(); iter++) + { + if (_stricmp(ImagePath,iter->c_str()) != 0) + { + continue; } + RecentGames.erase(iter); + break; } - if (bFound == false) { - memmove(&RecentRoms[1],&RecentRoms[0],sizeof(RecentRoms[0]) * (MaxRememberedFiles - 1)); + RecentGames.push_front(ImagePath); + if (RecentGames.size() > MaxRememberedFiles) + { + RecentGames.pop_back(); } - //Copy the image path to the list - strncpy(RecentRoms[0],ImagePath,sizeof(RecentRoms[0])); - RecentRoms[0][_MAX_PATH - 1] = 0; //Make sure it it is null terminated - - Notify().BreakPoint(__FILE__,__LINE__); - for (count = 0; count < MaxRememberedFiles; count ++ ) { - // _Settings->SaveString((SettingID)(FirstRecentRom + count), RecentRoms[count]); - }*/ - Notify().BreakPoint(__FILE__,__LINE__); + for (i = 0, iter = RecentGames.begin(); iter != RecentGames.end(); iter++, i++) + { + _Settings->SaveStringIndex(File_RecentGameFileIndex,i,*iter); + } } void CNotification::RefreshMenu ( void ) { @@ -215,7 +245,7 @@ void CNotification::HideRomBrowser ( void ) { void CNotification::ShowRomBrowser ( void ) { if (_hWnd == NULL) { return; } - if (_Settings->LoadDword(RomBrowser)) { + if (_Settings->LoadDword(RomBrowser_Enabled)) { //Display the rom browser _hWnd->ShowRomList(); _hWnd->HighLightLastRom(); @@ -232,13 +262,14 @@ void CNotification::MakeWindowOnTop ( bool OnTop ) { _hWnd->MakeWindowOnTop(OnTop); } -void CNotification::ChangeFullScreen ( void ) +void CNotification::ChangeFullScreen ( void ) const { if (_hWnd == NULL) { return; } SendMessage((HWND)(_hWnd->GetHandle()),WM_COMMAND,MAKELPARAM(ID_OPTIONS_FULLSCREEN2,false),0); } -bool CNotification::ProcessGuiMessages ( void ) { +bool CNotification::ProcessGuiMessages ( void ) const +{ if (_hWnd == NULL) { return false; } return _hWnd->ProcessGuiMessages(); } diff --git a/Source/Project64/User Interface/Notification Class.h b/Source/Project64/User Interface/Notification Class.h index 331190315..dc62974b6 100644 --- a/Source/Project64/User Interface/Notification Class.h +++ b/Source/Project64/User Interface/Notification Class.h @@ -12,12 +12,13 @@ class CNotification : CGfxPlugin * _gfxPlugin; mutable time_t m_NextMsg; - - enum { MaxRememberedDirs = 10 }; public: CNotification ( void ); + // Make sure we are not in full screen + void WindowMode ( void ) const; + //Error Messages void DisplayError ( const char * Message, ... ) const; void DisplayError ( const char * Message, va_list ap ) const; @@ -50,8 +51,8 @@ public: void MakeWindowOnTop ( bool OnTop ); void BringToTop ( void ); void BreakPoint ( const char * File, const int LineNumber); - bool ProcessGuiMessages ( void ); - void ChangeFullScreen ( void ); + bool ProcessGuiMessages ( void ) const; + void ChangeFullScreen ( void ) const; void SetGfxPlugin ( CGfxPlugin * Plugin ); }; diff --git a/Source/Project64/User Interface/Rom Browser Class.cpp b/Source/Project64/User Interface/Rom Browser Class.cpp index 5f026fb14..f89f94f2a 100644 --- a/Source/Project64/User Interface/Rom Browser Class.cpp +++ b/Source/Project64/User Interface/Rom Browser Class.cpp @@ -24,10 +24,10 @@ CRomBrowser::CRomBrowser (WND_HANDLE & MainWindow, WND_HANDLE & StatusWindow, CN m_Plugins(NULL) { if (_Settings) { - m_RomIniFile = new CIniFile(_Settings->LoadString(RomDatabaseFile).c_str()); - m_NotesIniFile = new CIniFile(_Settings->LoadString(NotesIniName).c_str()); - m_ExtIniFile = new CIniFile(_Settings->LoadString(ExtIniName).c_str()); - m_ZipIniFile = new CIniFile(_Settings->LoadString(ZipCacheIniName).c_str()); + m_RomIniFile = new CIniFile(_Settings->LoadString(SupportFile_RomDatabase).c_str()); + m_NotesIniFile = new CIniFile(_Settings->LoadString(SupportFile_Notes).c_str()); + m_ExtIniFile = new CIniFile(_Settings->LoadString(SupportFile_ExtInfo).c_str()); + m_ZipIniFile = new CIniFile(_Settings->LoadString(SupportFile_7zipCache).c_str()); } _System = System; @@ -36,41 +36,8 @@ CRomBrowser::CRomBrowser (WND_HANDLE & MainWindow, WND_HANDLE & StatusWindow, CN m_WatchThread = NULL; m_WatchStopEvent = NULL; - -#define AddField(Name,Pos,ID,Width,LangID) m_Fields.push_back(ROMBROWSER_FIELDS(Name,Pos,ID,Width,LangID)); - - AddField("File Name", -1, RB_FileName, 218,RB_FILENAME); - AddField("Internal Name", -1, RB_InternalName, 200,RB_INTERNALNAME); - AddField("Good Name", 0, RB_GoodName, 218,RB_GOODNAME); - AddField("Status", 1, RB_Status, 92, RB_STATUS); - AddField("Rom Size", -1, RB_RomSize, 100,RB_ROMSIZE); - AddField("Notes (Core)", 2, RB_CoreNotes, 120,RB_NOTES_CORE); - AddField("Notes (default plugins)", 3, RB_PluginNotes, 188,RB_NOTES_PLUGIN); - AddField("Notes (User)", -1, RB_UserNotes, 100,RB_NOTES_USER); - AddField("Cartridge ID", -1, RB_CartridgeID, 100,RB_CART_ID); - AddField("Manufacturer", -1, RB_Manufacturer, 100,RB_MANUFACTUER,); - AddField("Country", -1, RB_Country, 100,RB_COUNTRY,); - AddField("Developer", -1, RB_Developer, 100,RB_DEVELOPER,); - AddField("CRC1", -1, RB_Crc1, 100,RB_CRC1,); - AddField("CRC2", -1, RB_Crc2, 100,RB_CRC2,); - AddField("CIC Chip", -1, RB_CICChip, 100,RB_CICCHIP,); - AddField("Release Date", -1, RB_ReleaseDate, 100,RB_RELEASE_DATE,); - AddField("Genre", -1, RB_Genre, 100,RB_GENRE,); - AddField("Players", -1, RB_Players, 100,RB_PLAYERS); - AddField("Force Feedback", -1, RB_ForceFeedback, 100,RB_FORCE_FEEDBACK); - AddField("File Format", -1, RB_FileFormat, 100,RB_FILE_FORMAT); - -#undef AddField - m_FieldType.resize(m_Fields.size()); - - if (_Settings == NULL) { return; } - - //Load the real positions from the settings - for (int Field = 0; Field < m_Fields.size(); Field++) - { - _Settings->LoadDwordIndex(RomBrowserPosIndex,Field,(DWORD &)m_Fields[Field].Pos ); - _Settings->LoadDwordIndex(RomBrowserWidthIndex,Field,(DWORD &)m_Fields[Field].ColWidth); - } + GetFieldInfo(m_Fields); + m_FieldType.resize(m_Fields.size()); } CRomBrowser::~CRomBrowser (void){ @@ -100,6 +67,37 @@ CRomBrowser::~CRomBrowser (void){ } } +void CRomBrowser::AddField (ROMBROWSER_FIELDS_LIST & Fields, LPCSTR Name, int Pos,int ID,int Width,LanguageStringID LangID, bool UseDefault) +{ + Fields.push_back(ROMBROWSER_FIELDS(Name,Pos,ID,Width,LangID,UseDefault)); +} + +void CRomBrowser::GetFieldInfo ( ROMBROWSER_FIELDS_LIST & Fields, bool UseDefault /* = false */) +{ + Fields.clear(); + + AddField(Fields,"File Name", -1, RB_FileName, 218,RB_FILENAME, UseDefault); + AddField(Fields,"Internal Name", -1, RB_InternalName, 200,RB_INTERNALNAME, UseDefault); + AddField(Fields,"Good Name", 0, RB_GoodName, 218,RB_GOODNAME, UseDefault); + AddField(Fields,"Status", 1, RB_Status, 92, RB_STATUS, UseDefault); + AddField(Fields,"Rom Size", -1, RB_RomSize, 100,RB_ROMSIZE, UseDefault); + AddField(Fields,"Notes (Core)", 2, RB_CoreNotes, 120,RB_NOTES_CORE, UseDefault); + AddField(Fields,"Notes (default plugins)", 3, RB_PluginNotes, 188,RB_NOTES_PLUGIN, UseDefault); + AddField(Fields,"Notes (User)", -1, RB_UserNotes, 100,RB_NOTES_USER, UseDefault); + AddField(Fields,"Cartridge ID", -1, RB_CartridgeID, 100,RB_CART_ID, UseDefault); + AddField(Fields,"Manufacturer", -1, RB_Manufacturer, 100,RB_MANUFACTUER, UseDefault); + AddField(Fields,"Country", -1, RB_Country, 100,RB_COUNTRY, UseDefault); + AddField(Fields,"Developer", -1, RB_Developer, 100,RB_DEVELOPER, UseDefault); + AddField(Fields,"CRC1", -1, RB_Crc1, 100,RB_CRC1, UseDefault); + AddField(Fields,"CRC2", -1, RB_Crc2, 100,RB_CRC2, UseDefault); + AddField(Fields,"CIC Chip", -1, RB_CICChip, 100,RB_CICCHIP, UseDefault); + AddField(Fields,"Release Date", -1, RB_ReleaseDate, 100,RB_RELEASE_DATE, UseDefault); + AddField(Fields,"Genre", -1, RB_Genre, 100,RB_GENRE, UseDefault); + AddField(Fields,"Players", -1, RB_Players, 100,RB_PLAYERS, UseDefault); + AddField(Fields,"Force Feedback", -1, RB_ForceFeedback, 100,RB_FORCE_FEEDBACK, UseDefault); + AddField(Fields,"File Format", -1, RB_FileFormat, 100,RB_FILE_FORMAT, UseDefault); +} + int CRomBrowser::CalcSortPosition (DWORD lParam) { int Start = 0; @@ -112,7 +110,7 @@ int CRomBrowser::CalcSortPosition (DWORD lParam) int count; for (count = NoOfSortKeys; count >= 0; count --) { - stdstr SortFieldName = _Settings->LoadStringIndex(RomBrowserSortFieldIndex,count); + stdstr SortFieldName = _Settings->LoadStringIndex(RomBrowser_SortFieldIndex,count); if (SortFieldName.length() == 0) { continue; @@ -124,14 +122,15 @@ int CRomBrowser::CalcSortPosition (DWORD lParam) } int index; - for (index = 0; index < m_Fields.size(); index++) { - if (_stricmp(m_Fields[index].Name,SortFieldName.c_str()) == 0) { break; } + for (index = 0; index < m_Fields.size(); index++) + { + if (_stricmp(m_Fields[index].Name(),SortFieldName.c_str()) == 0) { break; } } if (index >= m_Fields.size()) { continue; } SORT_FIELD SortFieldInfo; SortFieldInfo._this = this; SortFieldInfo.Key = index; - SortFieldInfo.KeyAscend = _Settings->LoadBoolIndex(RomBrowserSortAscendingIndex,count); + SortFieldInfo.KeyAscend = _Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex,count); //calc new start and end int LastTestPos = -1; @@ -248,7 +247,7 @@ int CRomBrowser::CalcSortPosition (DWORD lParam) //Compare end with item to see if we should do it after or before it for (count = 0; count < NoOfSortKeys; count ++) { - stdstr SortFieldName = _Settings->LoadStringIndex(RomBrowserSortFieldIndex,count); + stdstr SortFieldName = _Settings->LoadStringIndex(RomBrowser_SortFieldIndex,count); if (SortFieldName.length() == 0) { continue; @@ -256,13 +255,13 @@ int CRomBrowser::CalcSortPosition (DWORD lParam) int index; for (index = 0; index < m_Fields.size(); index++) { - if (_stricmp(m_Fields[index].Name,SortFieldName.c_str()) == 0) { break; } + if (_stricmp(m_Fields[index].Name(),SortFieldName.c_str()) == 0) { break; } } if (index >= m_Fields.size()) { continue; } SORT_FIELD SortFieldInfo; SortFieldInfo._this = this; SortFieldInfo.Key = index; - SortFieldInfo.KeyAscend = _Settings->LoadBoolIndex(RomBrowserSortAscendingIndex,count) != 0; + SortFieldInfo.KeyAscend = _Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex,count) != 0; LV_ITEM lvItem; memset(&lvItem, 0, sizeof(LV_ITEM)); @@ -409,36 +408,36 @@ void CRomBrowser::FillRomExtensionInfo(ROM_INFO * pRomInfo) { sprintf(Identifier,"%08X-%08X-C:%X",pRomInfo->CRC1,pRomInfo->CRC2,pRomInfo->Country); //Rom Notes - if (m_Fields[RB_UserNotes].Pos >= 0) { + if (m_Fields[RB_UserNotes].Pos() >= 0) { m_NotesIniFile->GetString(Identifier,"Note","",pRomInfo->UserNotes,sizeof(pRomInfo->UserNotes)); } //Rom Extension info - if (m_Fields[RB_Developer].Pos >= 0) { + if (m_Fields[RB_Developer].Pos() >= 0) { m_ExtIniFile->GetString(Identifier,"Developer","",pRomInfo->Developer,sizeof(pRomInfo->Developer)); } - if (m_Fields[RB_ReleaseDate].Pos >= 0) { + if (m_Fields[RB_ReleaseDate].Pos() >= 0) { m_ExtIniFile->GetString(Identifier,"ReleaseDate","",pRomInfo->ReleaseDate,sizeof(pRomInfo->ReleaseDate)); } - if (m_Fields[RB_Genre].Pos >= 0) { + if (m_Fields[RB_Genre].Pos() >= 0) { m_ExtIniFile->GetString(Identifier,"Genre","",pRomInfo->Genre,sizeof(pRomInfo->Genre)); } - if (m_Fields[RB_Players].Pos >= 0) { + if (m_Fields[RB_Players].Pos() >= 0) { m_ExtIniFile->GetNumber(Identifier,"Players",1,(DWORD &)pRomInfo->Players); } - if (m_Fields[RB_ForceFeedback].Pos >= 0) { + if (m_Fields[RB_ForceFeedback].Pos() >= 0) { m_ExtIniFile->GetString(Identifier,"ForceFeedback","unknown",pRomInfo->ForceFeedback,sizeof(pRomInfo->ForceFeedback)); } //Rom Settings - if (m_Fields[RB_GoodName].Pos >= 0) { + if (m_Fields[RB_GoodName].Pos() >= 0) { m_RomIniFile->GetString(Identifier,"Good Name",pRomInfo->GoodName,pRomInfo->GoodName,sizeof(pRomInfo->GoodName)); } m_RomIniFile->GetString(Identifier,"Status",pRomInfo->Status,pRomInfo->Status,sizeof(pRomInfo->Status)); - if (m_Fields[RB_CoreNotes].Pos >= 0) { + if (m_Fields[RB_CoreNotes].Pos() >= 0) { m_RomIniFile->GetString(Identifier,"Core Note","",pRomInfo->CoreNotes,sizeof(pRomInfo->CoreNotes)); } - if (m_Fields[RB_PluginNotes].Pos >= 0) { + if (m_Fields[RB_PluginNotes].Pos() >= 0) { m_RomIniFile->GetString(Identifier,"Plugin Note","",pRomInfo->PluginNotes,sizeof(pRomInfo->PluginNotes)); } @@ -486,7 +485,7 @@ bool CRomBrowser::FillRomInfo2(ROM_INFO * pRomInfo, BYTE * RomData, DWORD RomDat char drive[_MAX_DRIVE] ,dir[_MAX_DIR], ext[_MAX_EXT]; _splitpath( pRomInfo->szFullFileName, drive, dir, pRomInfo->FileName, ext ); } - if (m_Fields[RB_InternalName].Pos >= 0) { + if (m_Fields[RB_InternalName].Pos() >= 0) { memcpy(pRomInfo->InternalName,(void *)(RomData + 0x20),20); for( count = 0 ; count < 20; count += 4 ) { pRomInfo->InternalName[count] ^= pRomInfo->InternalName[count+3]; @@ -537,7 +536,7 @@ void CRomBrowser::GetRomFileNames( strlist & FileList, CPath & BaseDirectory, st if (SearchPath.IsDirectory()) { - if (_Settings->LoadDword(RomBrowserRecursive)) + if (_Settings->LoadDword(RomBrowser_Recursive)) { stdstr CurrentDir = Directory + SearchPath.GetCurrentDirectory() + "\\"; GetRomFileNames(FileList,BaseDirectory,CurrentDir,InWatchThread); @@ -591,7 +590,7 @@ void CRomBrowser::FillRomList ( strlist & FileList, CPath & BaseDirectory, stdst if (SearchPath.IsDirectory()) { - if (_Settings->LoadDword(RomBrowserRecursive)) + if (_Settings->LoadDword(RomBrowser_Recursive)) { stdstr CurrentDir = Directory + SearchPath.GetCurrentDirectory() + "\\"; FillRomList(FileList,BaseDirectory,CurrentDir,lpLastRom); @@ -751,7 +750,7 @@ void CRomBrowser::HighLightLastRom(void) { if (!RomBrowserVisible()) { return; } //Get the string to the last rom - stdstr LastRom = _Settings->LoadStringIndex(RecentRomFileIndex,0); + stdstr LastRom = _Settings->LoadStringIndex(File_RecentGameFileIndex,0); LPCSTR lpLastRom = LastRom.c_str(); LV_ITEM lvItem; @@ -897,7 +896,7 @@ void CRomBrowser::ByteSwapRomData (BYTE * Data, int DataLen) } void CRomBrowser::LoadRomList (void) { - stdstr FileName = _Settings->LoadString(RomListCache); + stdstr FileName = _Settings->LoadString(SupportFile_RomListCache); //Open the cache file HANDLE hFile = CreateFile(FileName.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); @@ -988,7 +987,7 @@ void CRomBrowser::RefreshRomBrowserStatic (CRomBrowser * _this) if (_this->m_hRomList == NULL) { return; } //delete cache - stdstr CacheFileName = _Settings->LoadString(RomListCache); + stdstr CacheFileName = _Settings->LoadString(SupportFile_RomListCache); DeleteFile(CacheFileName.c_str()); //clear all current items @@ -1001,7 +1000,7 @@ void CRomBrowser::RefreshRomBrowserStatic (CRomBrowser * _this) Sleep(100); WriteTrace(TraceDebug,"CRomBrowser::RefreshRomBrowserStatic 3"); - if (_this->m_WatchRomDir != _Settings->LoadString(RomDirectory)) + if (_this->m_WatchRomDir != _Settings->LoadString(Directory_Game)) { WriteTrace(TraceDebug,"CRomBrowser::RefreshRomBrowserStatic 4"); _this->WatchThreadStop(); @@ -1011,8 +1010,8 @@ void CRomBrowser::RefreshRomBrowserStatic (CRomBrowser * _this) } WriteTrace(TraceDebug,"CRomBrowser::RefreshRomBrowserStatic 7"); - stdstr RomDir = _Settings->LoadString(RomDirectory); - stdstr LastRom = _Settings->LoadStringIndex(RecentRomFileIndex,0); + stdstr RomDir = _Settings->LoadString(Directory_Game); + stdstr LastRom = _Settings->LoadStringIndex(File_RecentGameFileIndex,0); WriteTrace(TraceDebug,"CRomBrowser::RefreshRomBrowserStatic 8"); strlist FileNames; @@ -1038,6 +1037,8 @@ void CRomBrowser::ResetRomBrowserColomuns (void) { LV_COLUMN lvColumn; char szString[300]; + GetFieldInfo(m_Fields); + //Remove all current coloumns memset(&lvColumn,0,sizeof(lvColumn)); lvColumn.mask = LVCF_FMT; @@ -1052,24 +1053,24 @@ void CRomBrowser::ResetRomBrowserColomuns (void) { for (Coloumn = 0; Coloumn < m_Fields.size(); Coloumn ++) { for (index = 0; index < m_Fields.size(); index ++) { - if (m_Fields[index].Pos == Coloumn) { break; } + if (m_Fields[index].Pos() == Coloumn) { break; } } - if (index == m_Fields.size() || m_Fields[index].Pos != Coloumn) { + if (index == m_Fields.size() || m_Fields[index].Pos() != Coloumn) { m_FieldType[Coloumn] = -1; break; } - m_FieldType[Coloumn] = m_Fields[index].ID; - lvColumn.cx = m_Fields[index].ColWidth; - strncpy(szString, GS(m_Fields[index].LangID), sizeof(szString)); + m_FieldType[Coloumn] = m_Fields[index].ID(); + lvColumn.cx = m_Fields[index].ColWidth(); + strncpy(szString, GS(m_Fields[index].LangID()), sizeof(szString)); ListView_InsertColumn((HWND)m_hRomList, Coloumn, &lvColumn); } } void CRomBrowser::ResizeRomList (WORD nWidth, WORD nHeight) { if (RomBrowserVisible()) { - if (_Settings->LoadDword(RomBrowserMaximized) == 0 && nHeight != 0) { - _Settings->SaveDword(RomBrowserWidth,nWidth); - _Settings->SaveDword(RomBrowserHeight,nHeight); + if (_Settings->LoadDword(RomBrowser_Maximized) == 0 && nHeight != 0) { + _Settings->SaveDword(RomBrowser_Width,nWidth); + _Settings->SaveDword(RomBrowser_Height,nHeight); } if (IsWindow((HWND)m_StatusWindow)) { RECT rc; @@ -1094,7 +1095,7 @@ void CRomBrowser::RomBrowserToTop(void) { } void CRomBrowser::RomBrowserMaximize(bool Mazimize) { - _Settings->SaveDword(RomBrowserMaximized,(DWORD)Mazimize); + _Settings->SaveDword(RomBrowser_Maximized,(DWORD)Mazimize); } bool CRomBrowser::RomListDrawItem(int idCtrl, DWORD lParam) { @@ -1187,20 +1188,20 @@ void CRomBrowser::RomList_ColoumnSortList(DWORD pnmh) { int index; for (index = 0; index < m_Fields.size(); index++) { - if (m_Fields[index].Pos == pnmv->iSubItem) { break; } + if (m_Fields[index].Pos() == pnmv->iSubItem) { break; } } if (m_Fields.size() == index) { return; } - if (_stricmp(_Settings->LoadStringIndex(RomBrowserSortFieldIndex,0).c_str(),m_Fields[index].Name) == 0) { - _Settings->SaveBoolIndex(RomBrowserSortAscendingIndex,0,!_Settings->LoadBoolIndex(RomBrowserSortAscendingIndex,0)); + if (_stricmp(_Settings->LoadStringIndex(RomBrowser_SortFieldIndex,0).c_str(),m_Fields[index].Name()) == 0) { + _Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex,0,!_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex,0)); } else { int count; for (count = NoOfSortKeys; count > 0; count --) { - _Settings->SaveStringIndex(RomBrowserSortFieldIndex,count,_Settings->LoadStringIndex(RomBrowserSortFieldIndex,count - 1).c_str()); - _Settings->SaveBoolIndex(RomBrowserSortAscendingIndex,count,_Settings->LoadBoolIndex(RomBrowserSortAscendingIndex, count - 1)); + _Settings->SaveStringIndex(RomBrowser_SortFieldIndex,count,_Settings->LoadStringIndex(RomBrowser_SortFieldIndex,count - 1).c_str()); + _Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex,count,_Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex, count - 1)); } - _Settings->SaveStringIndex(RomBrowserSortFieldIndex,0,m_Fields[index].Name); - _Settings->SaveBoolIndex(RomBrowserSortAscendingIndex,0,true); + _Settings->SaveStringIndex(RomBrowser_SortFieldIndex,0,m_Fields[index].Name()); + _Settings->SaveBoolIndex(RomBrowser_SortAscendingIndex,0,true); } RomList_SortList(); } @@ -1390,8 +1391,8 @@ void CRomBrowser::RomList_PopupMenu(DWORD pnmh) { DeleteMenu((HMENU)hPopupMenu,1,MF_BYPOSITION); DeleteMenu((HMENU)hPopupMenu,0,MF_BYPOSITION); } else { - bool inBasicMode = _Settings->LoadDword(BasicMode) != 0; - bool CheatsRemembered = _Settings->LoadDword(RememberCheats) != 0; + bool inBasicMode = _Settings->LoadDword(UserInterface_BasicMode) != 0; + bool CheatsRemembered = _Settings->LoadDword(Setting_RememberCheats) != 0; if (!CheatsRemembered) { DeleteMenu((HMENU)hPopupMenu,9,MF_BYPOSITION); } if (inBasicMode) { DeleteMenu((HMENU)hPopupMenu,8,MF_BYPOSITION); } if (inBasicMode && !CheatsRemembered) { DeleteMenu((HMENU)hPopupMenu,7,MF_BYPOSITION); } @@ -1424,16 +1425,16 @@ void CRomBrowser::RomList_SortList(void) { SORT_FIELD SortFieldInfo; for (int count = NoOfSortKeys; count >= 0; count --) { - stdstr SortFieldName = _Settings->LoadStringIndex(RomBrowserSortFieldIndex,count); + stdstr SortFieldName = _Settings->LoadStringIndex(RomBrowser_SortFieldIndex,count); int index; for (index = 0; index < m_Fields.size(); index++) { - if (_stricmp(m_Fields[index].Name,SortFieldName.c_str()) == 0) { break; } + if (_stricmp(m_Fields[index].Name(),SortFieldName.c_str()) == 0) { break; } } if (index >= m_Fields.size()) { continue; } SortFieldInfo._this = this; SortFieldInfo.Key = index; - SortFieldInfo.KeyAscend = _Settings->LoadBoolIndex(RomBrowserSortAscendingIndex,count) != 0; + SortFieldInfo.KeyAscend = _Settings->LoadBoolIndex(RomBrowser_SortAscendingIndex,count) != 0; ListView_SortItems((HWND)m_hRomList, RomList_CompareItems, &SortFieldInfo ); } } @@ -1453,7 +1454,7 @@ void CRomBrowser::SaveRomList ( strlist & FileList ) WriteTraceF(TraceDebug,"SaveRomList: %s",FileList.c_str()); MD5 md5((const unsigned char *)FileList.c_str(), FileList.length()); */ - stdstr FileName = _Settings->LoadString(RomListCache); + stdstr FileName = _Settings->LoadString(SupportFile_RomListCache); HANDLE hFile = CreateFile(FileName.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); DWORD dwWritten; @@ -1489,18 +1490,14 @@ void CRomBrowser::SaveRomListColoumnInfo(void) { for (int Coloumn = 0;ListView_GetColumn((HWND)m_hRomList,Coloumn,&lvColumn); Coloumn++) { for (int index = 0; index < m_Fields.size(); index++) { - if (m_Fields[index].Pos == Coloumn) { break; } + if (m_Fields[index].Pos() == Coloumn) { break; } + } + if (m_Fields[index].ColWidth() != lvColumn.cx) + { + m_Fields[index].SetColWidth(lvColumn.cx); } - m_Fields[index].ColWidth = lvColumn.cx; } - - //Save the real positions from the settings - WriteTrace(TraceDebug,"SaveRomListColoumnInfo - Update Settings"); - for (int Field = 0; Field < m_Fields.size(); Field++) { - _Settings->SaveDwordIndex(RomBrowserPosIndex,Field,m_Fields[Field].Pos ); - _Settings->SaveDwordIndex(RomBrowserWidthIndex,Field,m_Fields[Field].ColWidth); - } - WriteTrace(TraceDebug,"SaveRomListColoumnInfo - End"); + WriteTrace(TraceDebug,"SaveRomListColoumnInfo - Done"); } int CALLBACK CRomBrowser::SelectRomDirCallBack(WND_HANDLE hwnd,DWORD uMsg,DWORD lp, DWORD lpData) { @@ -1524,7 +1521,7 @@ void CRomBrowser::SelectRomDir(CNotification * Notify) { BROWSEINFO bi; WriteTrace(TraceDebug,"CRomBrowser::SelectRomDir 1"); - stdstr RomDir = _Settings->LoadString(RomDirectory); + stdstr RomDir = _Settings->LoadString(Directory_Game); bi.hwndOwner = (HWND)m_MainWindow; bi.pidlRoot = NULL; bi.pszDisplayName = SelectedDir; @@ -1544,11 +1541,8 @@ void CRomBrowser::SelectRomDir(CNotification * Notify) { strcat(Directory,"\\"); } WriteTrace(TraceDebug,"CRomBrowser::SelectRomDir 4"); - _Settings->SaveDword(UseRomDirSelected,true); - WriteTrace(TraceDebug,"CRomBrowser::SelectRomDir 5"); - _Settings->SaveString(SelectedRomDir,Directory); WriteTrace(TraceDebug,"CRomBrowser::SelectRomDir 6"); - _Settings->SaveString(RomDirectory,Directory); + _Settings->SaveString(Directory_Game,Directory); WriteTrace(TraceDebug,"CRomBrowser::SelectRomDir 7"); Notify->AddRecentDir(Directory); WriteTrace(TraceDebug,"CRomBrowser::SelectRomDir 8"); @@ -1564,8 +1558,8 @@ void CRomBrowser::FixRomListWindow (void) { SetWindowLong((HWND)m_MainWindow,GWL_STYLE,Style); //Fix height and width - int Width = _Settings->LoadDword(RomBrowserWidth); - int Height = _Settings->LoadDword(RomBrowserHeight); + int Width = _Settings->LoadDword(RomBrowser_Width); + int Height = _Settings->LoadDword(RomBrowser_Height); if (Width < 200) { Width = 200; } if (Height < 200) { Height = 200; } @@ -1584,22 +1578,22 @@ void CRomBrowser::FixRomListWindow (void) { //Fix window location DWORD Left = (GetSystemMetrics( SM_CXSCREEN ) - rcClient.right) / 2; DWORD Top = (GetSystemMetrics( SM_CYSCREEN ) - rcClient.bottom) / 2; - _Settings->LoadDword(RomBrowserTop, Top); - _Settings->LoadDword(RomBrowserLeft,Left); + _Settings->LoadDword(RomBrowser_Top, Top); + _Settings->LoadDword(RomBrowser_Left,Left); //Change the window to the correct location and dimensions MoveWindow( (HWND)m_MainWindow, Left, Top, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, TRUE ); //Make the screen maximized if it was - if (_Settings->LoadDword(RomBrowserMaximized)) { + if (_Settings->LoadDword(RomBrowser_Maximized)) { ShowWindow((HWND)m_MainWindow,SW_MAXIMIZE); } } void CRomBrowser::ShowRomList (void) { - if (_Settings->LoadBool(CPU_Running)) { return; } + if (_Settings->LoadBool(GameRunning_CPU_Running)) { return; } m_ShowingRomBrowser = true; WatchThreadStop(); FixRomListWindow(); @@ -1640,7 +1634,7 @@ void CRomBrowser::HideRomList (void) { EnableWindow((HWND)m_hRomList,FALSE); ShowWindow((HWND)m_hRomList,SW_HIDE); - if (_Settings->LoadDword(RomBrowserMaximized)) { ShowWindow((HWND)m_MainWindow,SW_RESTORE); } + if (_Settings->LoadBool(RomBrowser_Maximized)) { ShowWindow((HWND)m_MainWindow,SW_RESTORE); } //Change the window style long Style = GetWindowLong((HWND)m_MainWindow,GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX); @@ -1651,8 +1645,8 @@ void CRomBrowser::HideRomList (void) { GetWindowRect((HWND)m_MainWindow,&rect); int X = (GetSystemMetrics( SM_CXSCREEN ) - (rect.right - rect.left)) / 2; int Y = (GetSystemMetrics( SM_CYSCREEN ) - (rect.bottom - rect.top)) / 2; - _Settings->LoadDword(MainWindowTop,(DWORD &)Y); - _Settings->LoadDword(MainWindowLeft,(DWORD &)X); + _Settings->LoadDword(UserInterface_MainWindowTop,(DWORD &)Y); + _Settings->LoadDword(UserInterface_MainWindowLeft,(DWORD &)X); SetWindowPos((HWND)m_MainWindow,NULL,X,Y,0,0,SWP_NOZORDER|SWP_NOSIZE); //Mark the window as not visible @@ -1670,7 +1664,7 @@ bool CRomBrowser::RomDirNeedsRefresh ( void ) bool InWatchThread = (m_WatchThreadID == GetCurrentThreadId()); //Get Old MD5 of file names - stdstr FileName = _Settings->LoadString(RomListCache); + stdstr FileName = _Settings->LoadString(SupportFile_RomListCache); HANDLE hFile = CreateFile(FileName.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -1685,7 +1679,7 @@ bool CRomBrowser::RomDirNeedsRefresh ( void ) //Get Current MD5 of file names strlist FileNames; - GetRomFileNames(FileNames,CPath(_Settings->LoadString(RomDirectory)),stdstr(""), InWatchThread ); + GetRomFileNames(FileNames,CPath(_Settings->LoadString(Directory_Game)),stdstr(""), InWatchThread ); FileNames.sort(); MD5 NewMd5 = RomListHash(FileNames); @@ -1714,7 +1708,7 @@ void CRomBrowser::WatchRomDirChanged ( CRomBrowser * _this ) try { WriteTrace(TraceDebug,"CRomBrowser::WatchRomDirChanged 1"); - _this->m_WatchRomDir = _Settings->LoadString(RomDirectory); + _this->m_WatchRomDir = _Settings->LoadString(Directory_Game); WriteTrace(TraceDebug,"CRomBrowser::WatchRomDirChanged 2"); if (_this->RomDirNeedsRefresh()) { @@ -1724,7 +1718,7 @@ void CRomBrowser::WatchRomDirChanged ( CRomBrowser * _this ) WriteTrace(TraceDebug,"CRomBrowser::WatchRomDirChanged 3"); HANDLE hChange[] = { _this->m_WatchStopEvent, - FindFirstChangeNotification(_this->m_WatchRomDir.c_str(),_Settings->LoadDword(RomBrowserRecursive),FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE), + FindFirstChangeNotification(_this->m_WatchRomDir.c_str(),_Settings->LoadDword(RomBrowser_Recursive),FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE), }; WriteTrace(TraceDebug,"CRomBrowser::WatchRomDirChanged 4"); for (;;) @@ -1804,8 +1798,8 @@ void CRomBrowser::WatchThreadStop( void ) void CRomBrowser::Store7ZipInfo (CSettings * Settings, C7zip & ZipFile, int FileNo ) { - // if we have infomation about this file already then leave this function - CIniFile zipInfo(Settings->LoadString(ZipCacheIniName).c_str()); + // if we have information about this file already then leave this function + CIniFile zipInfo(Settings->LoadString(SupportFile_7zipCache).c_str()); CFileItem * cf = ZipFile.FileItem(FileNo); char FileName[260]; @@ -1843,7 +1837,7 @@ void CRomBrowser::Store7ZipInfo (CSettings * Settings, C7zip & ZipFile, int File } //delete cache - stdstr CacheFileName = Settings->LoadString(RomListCache); + stdstr CacheFileName = Settings->LoadString(SupportFile_RomListCache); DeleteFile(CacheFileName.c_str()); } diff --git a/Source/Project64/User Interface/Rom Browser.h b/Source/Project64/User Interface/Rom Browser.h index 6524476e3..8d9ac3341 100644 --- a/Source/Project64/User Interface/Rom Browser.h +++ b/Source/Project64/User Interface/Rom Browser.h @@ -5,20 +5,54 @@ class CNotification; class CPlugins; class ROMBROWSER_FIELDS { + stdstr m_Name; + int m_Pos, m_DefaultPos; + int m_ID; + ULONG m_ColWidth; + LanguageStringID m_LangID; + bool m_PosChanged; + public: - ROMBROWSER_FIELDS (char * Name, int Pos, int ID, int ColWidth, LanguageStringID LangID) { - strncpy(this->Name,Name,sizeof(this->Name)); - this->Name[sizeof(this->Name) - 1] = 0; - this->Pos = Pos; - this->ID = ID; - this->ColWidth = ColWidth; - this->LangID = LangID; + ROMBROWSER_FIELDS (const char * Name, int Pos, int ID, int ColWidth, LanguageStringID LangID, bool UseDefault) : + m_Name(Name), + m_Pos(Pos), + m_DefaultPos(Pos), + m_ID(ID), + m_ColWidth(ColWidth), + m_LangID(LangID), + m_PosChanged(false) + + { + if (!UseDefault) + { + m_PosChanged = _Settings->LoadDwordIndex(RomBrowser_PosIndex,m_ID,(ULONG &)m_Pos ); + _Settings->LoadDwordIndex(RomBrowser_WidthIndex,m_ID,m_ColWidth); + } + } + inline LPCSTR Name ( void ) const { return m_Name.c_str(); } + inline int Pos ( void ) const { return m_Pos; } + inline bool PosChanged ( void ) const { return m_PosChanged; } + inline int ID ( void ) const { return m_ID; } + inline int ColWidth ( void ) const { return m_ColWidth; } + inline LanguageStringID LangID ( void ) const { return m_LangID; } + + void SetColWidth ( int ColWidth ) + { + m_ColWidth = ColWidth; + _Settings->SaveDwordIndex(RomBrowser_WidthIndex,m_ID,m_ColWidth); + } + void SetColPos ( int Pos) + { + m_Pos = Pos; + _Settings->SaveDwordIndex(RomBrowser_PosIndex,m_ID,m_Pos); + m_PosChanged = true; + } + void ResetPos ( void ) + { + m_Pos = m_DefaultPos; + _Settings->DeleteSettingIndex(RomBrowser_PosIndex,m_ID); + m_PosChanged = false; } - char Name[50]; - int Pos; - int ID; - int ColWidth; - LanguageStringID LangID; }; typedef std::vector ROMBROWSER_FIELDS_LIST; @@ -143,13 +177,12 @@ class CRomBrowser { bool RomDirNeedsRefresh ( void ); // Called from watch thread static void WatchRomDirChanged ( CRomBrowser * _this ); static void RefreshRomBrowserStatic ( CRomBrowser * _this ); + static void AddField (ROMBROWSER_FIELDS_LIST & Fields, LPCSTR Name, int Pos,int ID,int Width,LanguageStringID LangID, bool UseDefault); //Callback static int CALLBACK SelectRomDirCallBack ( WND_HANDLE hwnd,DWORD uMsg,DWORD lp, DWORD lpData ); static int CALLBACK RomList_CompareItems ( DWORD lParam1, DWORD lParam2, DWORD lParamSort ); - //needs to access internal information for configuration - friend int CALLBACK RomBrowserConfigProc ( DWORD, DWORD, DWORD, DWORD ); public: CRomBrowser ( WND_HANDLE & hMainWindow, WND_HANDLE & StatusWindow, CNotification * Notify, CN64System * System ); ~CRomBrowser ( void ); @@ -170,4 +203,6 @@ public: LPCSTR CurrentedSelectedRom ( void ) { return m_SelectedRom.c_str(); } void SetPluginList ( CPlugins * Plugins); static void Store7ZipInfo ( CSettings * Settings, C7zip & ZipFile, int FileNo ); + + static void GetFieldInfo ( ROMBROWSER_FIELDS_LIST & Fields, bool UseDefault = false ); }; \ No newline at end of file diff --git a/Source/Project64/User Interface/Settings Config.cpp b/Source/Project64/User Interface/Settings Config.cpp index e07973f5c..84bd257a2 100644 --- a/Source/Project64/User Interface/Settings Config.cpp +++ b/Source/Project64/User Interface/Settings Config.cpp @@ -4,7 +4,8 @@ CSettingConfig::CSettingConfig(bool bJustGameSetting /* = false */) : - m_CurrentPage(NULL) + m_CurrentPage(NULL), + m_GameConfig(bJustGameSetting) { } @@ -24,24 +25,62 @@ void CSettingConfig::Display(void * ParentWindow) LRESULT CSettingConfig::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { - stdstr_f ConfigRomTitle("Config: %s",_Settings->LoadString(ROM_GoodName).c_str()); - + stdstr ConfigRomTitle, GameIni(_Settings->LoadString(Game_IniKey)); + + if (!GameIni.empty()) + { + ConfigRomTitle.Format("Config: %s",_Settings->LoadString(Game_GoodName).c_str()); + } + RECT rcSettingInfo; ::GetWindowRect(GetDlgItem(IDC_SETTING_INFO),&rcSettingInfo); ::MapWindowPoints(NULL,m_hWnd,(LPPOINT)&rcSettingInfo,2); - + CConfigSettingSection * SettingsSection; + + if (m_GameConfig) + { + SetWindowText(ConfigRomTitle.c_str()); + } else { + SetWindowText(GS(OPTIONS_TITLE)); + + SettingsSection = new CConfigSettingSection(GS(TAB_OPTIONS)); + SettingsSection->AddPage(new CGeneralOptionsPage(this->m_hWnd,rcSettingInfo )); + SettingsSection->AddPage(new CAdvancedOptionsPage(this->m_hWnd,rcSettingInfo )); + SettingsSection->AddPage(new COptionsDirectoriesPage(this->m_hWnd,rcSettingInfo )); + m_Sections.push_back(SettingsSection); + + SettingsSection = new CConfigSettingSection(GS(TAB_ROMSELECTION)); + SettingsSection->AddPage(new COptionsGameBrowserPage(this->m_hWnd,rcSettingInfo )); + m_Sections.push_back(SettingsSection); + + SettingsSection = new CConfigSettingSection(GS(TAB_SHORTCUTS)); + SettingsSection->AddPage(new COptionsShortCutsPage(this->m_hWnd,rcSettingInfo )); + m_Sections.push_back(SettingsSection); + + SettingsSection = new CConfigSettingSection(GS(TAB_PLUGIN)); + SettingsSection->AddPage(new COptionPluginPage(this->m_hWnd,rcSettingInfo )); + m_Sections.push_back(SettingsSection); + } + //Game Settings - CConfigSettingSection * GameSettings = new CConfigSettingSection(ConfigRomTitle.c_str()); - m_Sections.push_back(GameSettings); - GameSettings->AddPage(new CGameGeneralPage(this->m_hWnd,rcSettingInfo )); - GameSettings->AddPage(new CGameRecompilePage(this->m_hWnd,rcSettingInfo )); - GameSettings->AddPage(new CGamePluginPage(this->m_hWnd,rcSettingInfo )); - GameSettings->AddPage(new CGameStatusPage(this->m_hWnd,rcSettingInfo )); + if (!GameIni.empty()) + { + CConfigSettingSection * GameSettings = new CConfigSettingSection(ConfigRomTitle.c_str()); + GameSettings->AddPage(new CGameGeneralPage(this->m_hWnd,rcSettingInfo )); + GameSettings->AddPage(new CGameRecompilePage(this->m_hWnd,rcSettingInfo )); + GameSettings->AddPage(new CGamePluginPage(this->m_hWnd,rcSettingInfo )); + if (_Settings->LoadBool(Setting_RdbEditor)) + { + GameSettings->AddPage(new CGameStatusPage(this->m_hWnd,rcSettingInfo )); + } + m_Sections.push_back(GameSettings); + } m_PagesTreeList.Attach(GetDlgItem(IDC_PAGELIST)); + bool bFirstItem = true; for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) { CConfigSettingSection * Section = *iter; @@ -52,7 +91,8 @@ LRESULT CSettingConfig::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /* CSettingsPage * Page = Section->GetPage(i); if (i == 0) { - hSectionItem = m_PagesTreeList.InsertItem(TVIF_TEXT | TVIF_PARAM,Section->GetPageTitle(),0,0,0,0,(ULONG)Page,TVI_ROOT,TVI_LAST); + hSectionItem = m_PagesTreeList.InsertItem(TVIF_TEXT | TVIF_PARAM,Section->GetPageTitle(),0,0,0,0,(ULONG)Page,TVI_ROOT,TVI_LAST); + continue; } if (hSectionItem == NULL) { @@ -60,7 +100,15 @@ LRESULT CSettingConfig::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /* } m_PagesTreeList.InsertItem(TVIF_TEXT | TVIF_PARAM,GS(Page->PageTitle()),0,0,0,0,(ULONG)Page,hSectionItem,TVI_LAST); } + if (bFirstItem && hSectionItem != NULL) + { + bFirstItem = false; + m_PagesTreeList.Expand(hSectionItem); + m_PagesTreeList.SelectItem(hSectionItem); + } } + + BoldChangedPages(m_PagesTreeList.GetRootItem()); return TRUE; } @@ -68,13 +116,62 @@ LRESULT CSettingConfig::OnClicked (WORD wNotifyCode, WORD wID, HWND , BOOL& bHan { switch(wID) { + case IDAPPLY: + ApplySettings(true); + break; + case IDOK: + ApplySettings(false); + EndDialog(1); + break; case IDCANCEL: EndDialog(0); + break; + case IDC_RESET: + if (m_CurrentPage) + { + m_CurrentPage->ResetPage(); + } + break; + case IDC_RESET_ALL: + for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) + { + CConfigSettingSection * Section = *iter; + + for (int i = 0; i < Section->GetPageCount(); i++ ) + { + CSettingsPage * Page = Section->GetPage(i); + if (Page->EnableReset()) + { + Page->ResetPage(); + } + } + } + break; } return FALSE; } +void CSettingConfig::ApplySettings( bool UpdateScreen ) +{ + for (SETTING_SECTIONS::const_iterator iter = m_Sections.begin(); iter != m_Sections.end(); iter++) + { + CConfigSettingSection * Section = *iter; + + for (int i = 0; i < Section->GetPageCount(); i++ ) + { + CSettingsPage * Page = Section->GetPage(i); + Page->ApplySettings(UpdateScreen); + } + } + + if (UpdateScreen) + { + ::EnableWindow(GetDlgItem(IDAPPLY),false); + ::EnableWindow(GetDlgItem(IDC_RESET), m_CurrentPage->EnableReset()); + } +} + LRESULT CSettingConfig::OnPageListItemChanged(NMHDR* phdr) { NMLISTVIEW* pnmlv = (NMLISTVIEW*) phdr; @@ -88,21 +185,49 @@ LRESULT CSettingConfig::OnPageListItemChanged(NMHDR* phdr) m_CurrentPage->HidePage(); } m_CurrentPage = Page; - m_CurrentPage->ShowPage(); + m_CurrentPage->ShowPage(); + ::EnableWindow(GetDlgItem(IDC_RESET), m_CurrentPage->EnableReset()); } - //hItem = TreeView_GetSelection(hCheatTree); - //if (TreeView_GetChild(hCheatTree,hItem) == NULL) { - - //int nSelItem = m_wndList.GetSelectedIndex(); - //CString sMsg; - - // If no item is selected, show "none". Otherwise, show its index. - - //if ( -1 == nSelItem ) - // sMsg = _T("(none)"); - //else - // sMsg.Format ( _T("%d"), nSelItem ); - - //SetDlgItemText ( IDC_SEL_ITEM, sMsg ); return 0; // retval ignored } + +LRESULT CSettingConfig::OnSettingPageChanged ( UINT /*uMsg*/, WPARAM wPage, LPARAM /*lParam*/) +{ + ::EnableWindow(GetDlgItem(IDAPPLY),true); + ::EnableWindow(GetDlgItem(IDC_RESET), m_CurrentPage->EnableReset()); + BoldChangedPages(m_PagesTreeList.GetRootItem()); + return 0; +} + +void CSettingConfig::BoldChangedPages ( HTREEITEM hItem ) +{ + if (hItem == m_PagesTreeList.GetRootItem()) + { + ::EnableWindow(GetDlgItem(IDC_RESET_ALL), false); + } + bool bEnableResetAll = false; + + while (hItem) + { + CSettingsPage * Page = (CSettingsPage * )m_PagesTreeList.GetItemData(hItem); + if (Page) + { + m_PagesTreeList.SetItemState(hItem,Page->EnableReset() ? TVIS_BOLD : 0,TVIS_BOLD); + if (Page->EnableReset()) + { + bEnableResetAll = true; + } + } + + BoldChangedPages(m_PagesTreeList.GetChildItem(hItem)); + hItem = m_PagesTreeList.GetNextSiblingItem(hItem); + } + + if (bEnableResetAll) + { + ::EnableWindow(GetDlgItem(IDC_RESET_ALL), true); + } + + +} + diff --git a/Source/Project64/User Interface/Settings Config.h b/Source/Project64/User Interface/Settings Config.h index 948debaa4..8c0b87304 100644 --- a/Source/Project64/User Interface/Settings Config.h +++ b/Source/Project64/User Interface/Settings Config.h @@ -9,8 +9,9 @@ class CSettingConfig : BEGIN_MSG_MAP_EX(CSettingConfig) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_CODE_HANDLER(BN_CLICKED,OnClicked) + COMMAND_CODE_HANDLER(BN_CLICKED,OnClicked) NOTIFY_HANDLER_EX(IDC_PAGELIST, TVN_SELCHANGED, OnPageListItemChanged) + MESSAGE_HANDLER_EX(PSM_CHANGED,OnSettingPageChanged) REFLECT_NOTIFICATIONS() END_MSG_MAP() @@ -19,6 +20,7 @@ class CSettingConfig : LRESULT OnInitDialog ( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); LRESULT OnPageListItemChanged(NMHDR* phdr); + LRESULT OnSettingPageChanged ( UINT /*uMsg*/, WPARAM wPage, LPARAM /*lParam*/); public: CSettingConfig ( bool bJustGameSetting = false ); @@ -27,9 +29,13 @@ public: void Display ( void * ParentWindow ); private: + void ApplySettings ( bool UpdateScreen ); + void BoldChangedPages ( HTREEITEM hItem ); + typedef std::list SETTING_SECTIONS; CTreeViewCtrl m_PagesTreeList; SETTING_SECTIONS m_Sections; CSettingsPage * m_CurrentPage; + bool m_GameConfig; }; \ No newline at end of file diff --git a/Source/Project64/User Interface/Settings/Settings Page - Advanced Options.cpp b/Source/Project64/User Interface/Settings/Settings Page - Advanced Options.cpp new file mode 100644 index 000000000..be51223a4 --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Advanced Options.cpp @@ -0,0 +1,52 @@ +#include "../../User Interface.h" +#include "Settings Page.h" + +CAdvancedOptionsPage::CAdvancedOptionsPage (HWND hParent, const RECT & rcDispay ) +{ + if (!Create(hParent,rcDispay)) + { + return; + } + AddModCheckBox(GetDlgItem(IDC_START_ON_ROM_OPEN),Setting_AutoStart); + AddModCheckBox(GetDlgItem(IDC_ZIP),Setting_AutoZipInstantSave); + AddModCheckBox(GetDlgItem(IDC_DEBUGGER),Debugger_Enabled); + AddModCheckBox(GetDlgItem(IDC_REMEMBER_CHEAT),Setting_RememberCheats); + AddModCheckBox(GetDlgItem(IDC_DISPLAY_FRAMERATE),UserInterface_DisplayFrameRate); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(IDC_FRAME_DISPLAY_TYPE),UserInterface_FrameDisplayType); + if (ComboBox) + { + ComboBox->AddItem(GS(STR_FR_VIS), FR_VIs ); + ComboBox->AddItem(GS(STR_FR_DLS), FR_DLs ); + ComboBox->AddItem(GS(STR_FR_PERCENT), FR_PERCENT ); + } + + UpdatePageSettings(); +} + +void CAdvancedOptionsPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void CAdvancedOptionsPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void CAdvancedOptionsPage::ApplySettings( bool UpdateScreen ) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CAdvancedOptionsPage::EnableReset ( void ) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CAdvancedOptionsPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); +} diff --git a/Source/Project64/User Interface/Settings/Settings Page - Advanced Options.h b/Source/Project64/User Interface/Settings/Settings Page - Advanced Options.h new file mode 100644 index 000000000..ec86f4f5a --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Advanced Options.h @@ -0,0 +1,31 @@ +#pragma once + +class CAdvancedOptionsPage : + public CSettingsPageImpl, + public CSettingsPage +{ + + BEGIN_MSG_MAP_EX(CAdvancedOptionsPage) + COMMAND_ID_HANDLER_EX(IDC_START_ON_ROM_OPEN,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ZIP,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_DEBUGGER,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_REMEMBER_CHEAT,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_DISPLAY_FRAMERATE,CheckBoxChanged) + COMMAND_HANDLER_EX(IDC_FRAME_DISPLAY_TYPE,LBN_SELCHANGE,ComboBoxChanged) + + END_MSG_MAP() + + enum { IDD = IDD_Settings_Advanced }; + +public: + CAdvancedOptionsPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_ADVANCED; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: +}; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Directories.cpp b/Source/Project64/User Interface/Settings/Settings Page - Directories.cpp new file mode 100644 index 000000000..fc40415bd --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Directories.cpp @@ -0,0 +1,342 @@ +#include "../../User Interface.h" +#include "Settings Page.h" + +COptionsDirectoriesPage::COptionsDirectoriesPage (HWND hParent, const RECT & rcDispay ) : + m_InUpdateSettings(false) +{ + Create(hParent); + if (m_hWnd == NULL) + { + return; + } + SetWindowPos(HWND_TOP,&rcDispay,SWP_HIDEWINDOW); + + m_PluginGroup.Attach(GetDlgItem(IDC_DIR_FRAME1)); + m_AutoSaveGroup.Attach(GetDlgItem(IDC_DIR_FRAME3)); + m_InstantSaveGroup.Attach(GetDlgItem(IDC_DIR_FRAME4)); + m_ScreenShotGroup.Attach(GetDlgItem(IDC_DIR_FRAME5)); + m_TextureGroup.Attach(GetDlgItem(IDC_DIR_TEXTURE_FRAME)); + + m_PluginDir.Attach(GetDlgItem(IDC_PLUGIN_DIR)); + m_AutoSaveDir.Attach(GetDlgItem(IDC_AUTO_DIR)); + m_InstantSaveDir.Attach(GetDlgItem(IDC_INSTANT_DIR)); + m_ScreenShotDir.Attach(GetDlgItem(IDC_SNAP_DIR)); + m_TextureDir.Attach(GetDlgItem(IDC_TEXTURE_DIR)); + + m_PluginDefault.Attach(GetDlgItem(IDC_PLUGIN_DEFAULT)); + m_PluginSelected.Attach(GetDlgItem(IDC_PLUGIN_OTHER)); + m_AutoSaveDefault.Attach(GetDlgItem(IDC_AUTO_DEFAULT)); + m_AutoSaveSelected.Attach(GetDlgItem(IDC_AUTO_OTHER)); + m_InstantDefault.Attach(GetDlgItem(IDC_INSTANT_DEFAULT)); + m_InstantSelected.Attach(GetDlgItem(IDC_INSTANT_OTHER)); + m_ScreenShotDefault.Attach(GetDlgItem(IDC_SNAP_DEFAULT)); + m_ScreenShotSelected.Attach(GetDlgItem(IDC_SNAP_OTHER)); + m_TextureDefault.Attach(GetDlgItem(IDC_TEXTURE_DEFAULT)); + m_TextureSelected.Attach(GetDlgItem(IDC_TEXTURE_OTHER)); + + //Set Text language for the dialog box + m_PluginGroup.SetWindowText(GS(DIR_PLUGIN)); + m_AutoSaveGroup.SetWindowText(GS(DIR_AUTO_SAVE)); + m_InstantSaveGroup.SetWindowText(GS(DIR_INSTANT_SAVE)); + m_ScreenShotGroup.SetWindowText(GS(DIR_SCREEN_SHOT)); + m_TextureGroup.SetWindowText(GS(DIR_TEXTURE)); + + UpdatePageSettings(); +} + +int CALLBACK COptionsDirectoriesPage::SelectDirCallBack (HWND hwnd,DWORD uMsg,DWORD lp, DWORD lpData) +{ + switch(uMsg) + { + case BFFM_INITIALIZED: + // WParam is TRUE since you are passing a path. + // It would be FALSE if you were passing a pidl. + if (lpData) + { + SendMessage((HWND)hwnd,BFFM_SETSELECTION,TRUE,lpData); + } + break; + } + return 0; +} + +void COptionsDirectoriesPage::SelectDirectory( LanguageStringID Title, CModifiedEditBox & EditBox, CModifiedButton & Default, CModifiedButton & selected ) +{ + char Buffer[MAX_PATH], Directory[MAX_PATH]; + LPITEMIDLIST pidl; + BROWSEINFO bi; + + stdstr InitialDir = EditBox.GetWindowText(); + + bi.hwndOwner = m_hWnd; + bi.pidlRoot = NULL; + bi.pszDisplayName = Buffer; + bi.lpszTitle = GS(Title); + bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; + bi.lpfn = (BFFCALLBACK)SelectDirCallBack; + bi.lParam = (DWORD)InitialDir.c_str(); + if ((pidl = SHBrowseForFolder(&bi)) != NULL) + { + if (SHGetPathFromIDList(pidl, Directory)) + { + CPath SelectedDir(Directory,""); + EditBox.SetChanged(true); + EditBox.SetWindowText(SelectedDir); + Default.SetChanged(true); + Default.SetCheck(BST_UNCHECKED); + selected.SetCheck(BM_SETCHECK); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + } + } +} + +void COptionsDirectoriesPage::PluginDirChanged ( UINT Code, int id, HWND ctl ) +{ + if (m_InUpdateSettings) { return; } + m_PluginDir.SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); +} + +void COptionsDirectoriesPage::AutoSaveDirChanged ( UINT Code, int id, HWND ctl ) +{ + if (m_InUpdateSettings) { return; } + m_AutoSaveDir.SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); +} + +void COptionsDirectoriesPage::InstantSaveDirChanged ( UINT Code, int id, HWND ctl ) +{ + if (m_InUpdateSettings) { return; } + m_InstantSaveDir.SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); +} + +void COptionsDirectoriesPage::SnapShotDirChanged ( UINT Code, int id, HWND ctl ) +{ + if (m_InUpdateSettings) { return; } + m_ScreenShotDir.SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); +} + +void COptionsDirectoriesPage::TextureDirChanged ( UINT Code, int id, HWND ctl ) +{ + if (m_InUpdateSettings) { return; } + m_TextureDir.SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); +} + +void COptionsDirectoriesPage::SelectPluginDir ( UINT Code, int id, HWND ctl ) +{ + SelectDirectory(DIR_SELECT_PLUGIN,m_PluginDir,m_PluginDefault, m_PluginSelected); +} + +void COptionsDirectoriesPage::SelectAutoDir ( UINT Code, int id, HWND ctl ) +{ + SelectDirectory(DIR_SELECT_AUTO,m_AutoSaveDir,m_AutoSaveDefault, m_AutoSaveSelected); +} + +void COptionsDirectoriesPage::SelectInstantDir ( UINT Code, int id, HWND ctl ) +{ + SelectDirectory(DIR_SELECT_INSTANT,m_InstantSaveDir,m_InstantDefault, m_InstantSelected); +} + +void COptionsDirectoriesPage::SelectSnapShotDir ( UINT Code, int id, HWND ctl ) +{ + SelectDirectory(DIR_SELECT_SCREEN,m_ScreenShotDir,m_ScreenShotDefault, m_ScreenShotSelected); +} + +void COptionsDirectoriesPage::SelectTextureDir ( UINT Code, int id, HWND ctl ) +{ + SelectDirectory(DIR_SELECT_TEXTURE,m_TextureDir,m_TextureDefault, m_TextureSelected); +} + +void COptionsDirectoriesPage::UpdatePageSettings() +{ + stdstr Directory; + + m_InUpdateSettings = true; + m_PluginDir.SetChanged(_Settings->LoadString(Directory_PluginSelected,Directory)); + m_PluginDir.SetWindowText(Directory.c_str()); + m_AutoSaveDir.SetChanged(_Settings->LoadString(Directory_NativeSaveSelected,Directory)); + m_AutoSaveDir.SetWindowText(Directory.c_str()); + m_InstantSaveDir.SetChanged(_Settings->LoadString(Directory_InstantSaveSelected,Directory)); + m_InstantSaveDir.SetWindowText(Directory.c_str()); + m_ScreenShotDir.SetChanged(_Settings->LoadString(Directory_SnapShotSelected,Directory)); + m_ScreenShotDir.SetWindowText(Directory.c_str()); + m_TextureDir.SetChanged(_Settings->LoadString(Directory_TextureSelected,Directory)); + m_TextureDir.SetWindowText(Directory.c_str()); + + bool UseSelected; + m_PluginDefault.SetChanged(_Settings->LoadBool(Directory_PluginUseSelected,UseSelected)); + m_PluginDefault.SetCheck(!UseSelected); + m_PluginSelected.SetCheck(UseSelected); + + m_AutoSaveDefault.SetChanged(_Settings->LoadBool(Directory_NativeSaveUseSelected,UseSelected)); + m_AutoSaveDefault.SetCheck(!UseSelected); + m_AutoSaveSelected.SetCheck(UseSelected); + + m_InstantDefault.SetChanged(_Settings->LoadBool(Directory_InstantSaveUseSelected,UseSelected)); + m_InstantDefault.SetCheck(!UseSelected); + m_InstantSelected.SetCheck(UseSelected); + + m_ScreenShotDefault.SetChanged(_Settings->LoadBool(Directory_SnapShotUseSelected,UseSelected)); + m_ScreenShotDefault.SetCheck(!UseSelected); + m_ScreenShotSelected.SetCheck(UseSelected); + + m_TextureDefault.SetChanged(_Settings->LoadBool(Directory_TextureUseSelected,UseSelected)); + m_TextureDefault.SetCheck(!UseSelected); + m_TextureSelected.SetCheck(UseSelected); + + m_InUpdateSettings = false; +} + +void COptionsDirectoriesPage::UseSelectedClicked ( UINT Code, int id, HWND ctl ) +{ + CModifiedButton * Button = NULL; + switch (id) + { + case IDC_PLUGIN_DEFAULT: Button = &m_PluginDefault; break; + case IDC_PLUGIN_OTHER: Button = &m_PluginDefault; break; + case IDC_AUTO_DEFAULT: Button = &m_AutoSaveDefault; break; + case IDC_AUTO_OTHER: Button = &m_AutoSaveDefault; break; + case IDC_INSTANT_DEFAULT: Button = &m_InstantDefault; break; + case IDC_INSTANT_OTHER: Button = &m_InstantDefault; break; + case IDC_SNAP_DEFAULT: Button = &m_ScreenShotDefault; break; + case IDC_SNAP_OTHER: Button = &m_ScreenShotDefault; break; + case IDC_TEXTURE_DEFAULT: Button = &m_TextureDefault; break; + case IDC_TEXTURE_OTHER: Button = &m_TextureDefault; break; + } + + if (Button == NULL) + { + return; + } + + if (!Button->IsChanged() || Button->IsReset()) + { + if ((int)Button->GetMenu() == id) + { + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); +} + +void COptionsDirectoriesPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionsDirectoriesPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionsDirectoriesPage::ResetDirectory( CModifiedEditBox & EditBox, SettingID Type ) +{ + if (!EditBox.IsChanged()) + { + return; + } + stdstr dir; + _Settings->LoadDefaultString(Type,dir); + EditBox.SetWindowText(dir.c_str()); + EditBox.SetReset(true); +} + +void COptionsDirectoriesPage::ResetDefaultSelected ( CModifiedButton & ButtonDefault, CModifiedButton & ButtonSelected, SettingID Type ) +{ + if (!ButtonDefault.IsChanged()) + { + return; + } + bool UseSelected; + _Settings->LoadDefaultBool(Type,UseSelected); + ButtonDefault.SetCheck(!UseSelected); + ButtonSelected.SetCheck(UseSelected); + ButtonDefault.SetReset(true); +} + +void COptionsDirectoriesPage::UpdateDirectory( CModifiedEditBox & EditBox, SettingID Type ) +{ + if (EditBox.IsChanged()) + { + stdstr dir = EditBox.GetWindowText(); + _Settings->SaveString(Type,dir.c_str()); + } + if (EditBox.IsReset()) + { + _Settings->DeleteSetting(Type); + } +} + +void COptionsDirectoriesPage::UpdateDefaultSelected ( CModifiedButton & Button, SettingID Type ) +{ + if (Button.IsChanged()) + { + bool bUseSelected = (Button.GetCheck() & BST_CHECKED) == 0; + _Settings->SaveBool(Type,bUseSelected); + + if (Type == Directory_TextureUseSelected && !bUseSelected) + { + _Settings->DeleteSetting(Directory_TextureSelected); + } + } + if (Button.IsReset()) + { + _Settings->DeleteSetting(Type); + } +} + +void COptionsDirectoriesPage::ApplySettings( bool UpdateScreen ) +{ + UpdateDirectory(m_PluginDir,Directory_PluginSelected); + UpdateDirectory(m_AutoSaveDir,Directory_NativeSaveSelected); + UpdateDirectory(m_InstantSaveDir,Directory_InstantSaveSelected); + UpdateDirectory(m_ScreenShotDir,Directory_SnapShotSelected); + UpdateDirectory(m_TextureDir,Directory_TextureSelected); + + UpdateDefaultSelected(m_PluginDefault,Directory_PluginUseSelected); + UpdateDefaultSelected(m_AutoSaveDefault,Directory_NativeSaveUseSelected); + UpdateDefaultSelected(m_InstantDefault,Directory_InstantSaveUseSelected); + UpdateDefaultSelected(m_ScreenShotDefault,Directory_SnapShotUseSelected); + UpdateDefaultSelected(m_TextureDefault,Directory_TextureUseSelected); + + if (UpdateScreen) + { + UpdatePageSettings(); + } +} + +bool COptionsDirectoriesPage::EnableReset ( void ) +{ + if (m_PluginDir.IsChanged()) { return true; } + if (m_AutoSaveDir.IsChanged()) { return true; } + if (m_InstantSaveDir.IsChanged()) { return true; } + if (m_ScreenShotDir.IsChanged()) { return true; } + if (m_TextureDir.IsChanged()) { return true; } + if (m_PluginDefault.IsChanged()) { return true; } + if (m_AutoSaveDefault.IsChanged()) { return true; } + if (m_InstantDefault.IsChanged()) { return true; } + if (m_ScreenShotDefault.IsChanged()) { return true; } + if (m_TextureDefault.IsChanged()) { return true; } + return false; +} + +void COptionsDirectoriesPage::ResetPage() +{ + ResetDirectory(m_PluginDir,Directory_PluginSelected); + ResetDirectory(m_AutoSaveDir,Directory_NativeSaveSelected); + ResetDirectory(m_InstantSaveDir,Directory_InstantSaveSelected); + ResetDirectory(m_ScreenShotDir,Directory_SnapShotSelected); + ResetDirectory(m_TextureDir,Directory_TextureSelected); + + ResetDefaultSelected(m_PluginDefault,m_PluginSelected,Directory_PluginUseSelected); + ResetDefaultSelected(m_AutoSaveDefault,m_AutoSaveSelected,Directory_NativeSaveUseSelected); + ResetDefaultSelected(m_InstantDefault,m_InstantSelected,Directory_InstantSaveUseSelected); + ResetDefaultSelected(m_ScreenShotDefault,m_ScreenShotSelected,Directory_SnapShotUseSelected); + ResetDefaultSelected(m_TextureDefault,m_TextureSelected,Directory_TextureUseSelected); + + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); +} diff --git a/Source/Project64/User Interface/Settings/Settings Page - Directories.h b/Source/Project64/User Interface/Settings/Settings Page - Directories.h new file mode 100644 index 000000000..663993e4c --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Directories.h @@ -0,0 +1,78 @@ +#pragma once + +class COptionsDirectoriesPage : + private CDialogImpl, + public CSettingsPage +{ + + + BEGIN_MSG_MAP_EX(COptionsDirectoriesPage) + COMMAND_ID_HANDLER_EX(IDC_SELECT_PLUGIN_DIR,SelectPluginDir); + COMMAND_ID_HANDLER_EX(IDC_SELECT_AUTO_DIR,SelectAutoDir); + COMMAND_ID_HANDLER_EX(IDC_SELECT_INSTANT_DIR,SelectInstantDir); + COMMAND_ID_HANDLER_EX(IDC_SELECT_SNAP_DIR,SelectSnapShotDir); + COMMAND_ID_HANDLER_EX(IDC_SELECT_TEXTURE_DIR,SelectTextureDir); + COMMAND_HANDLER_EX(IDC_PLUGIN_DIR,EN_UPDATE,PluginDirChanged) + COMMAND_HANDLER_EX(IDC_AUTO_DIR,EN_UPDATE,AutoSaveDirChanged) + COMMAND_HANDLER_EX(IDC_INSTANT_DIR,EN_UPDATE,InstantSaveDirChanged) + COMMAND_HANDLER_EX(IDC_SNAP_DIR,EN_UPDATE,SnapShotDirChanged) + COMMAND_HANDLER_EX(IDC_TEXTURE_DIR,EN_UPDATE,TextureDirChanged) + + COMMAND_HANDLER_EX(IDC_PLUGIN_DEFAULT,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_PLUGIN_OTHER,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_AUTO_DEFAULT,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_AUTO_OTHER,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_INSTANT_DEFAULT,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_INSTANT_OTHER,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_SNAP_DEFAULT,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_SNAP_OTHER,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_TEXTURE_DEFAULT,BN_CLICKED,UseSelectedClicked) + COMMAND_HANDLER_EX(IDC_TEXTURE_OTHER,BN_CLICKED,UseSelectedClicked) + END_MSG_MAP() + + enum { IDD = IDD_Settings_Directory }; + +public: + COptionsDirectoriesPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_DIRECTORY; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + void SelectPluginDir ( UINT Code, int id, HWND ctl ); + void SelectAutoDir ( UINT Code, int id, HWND ctl ); + void SelectInstantDir ( UINT Code, int id, HWND ctl ); + void SelectSnapShotDir ( UINT Code, int id, HWND ctl ); + void SelectTextureDir ( UINT Code, int id, HWND ctl ); + void PluginDirChanged ( UINT Code, int id, HWND ctl ); + void AutoSaveDirChanged ( UINT Code, int id, HWND ctl ); + void InstantSaveDirChanged ( UINT Code, int id, HWND ctl ); + void SnapShotDirChanged ( UINT Code, int id, HWND ctl ); + void TextureDirChanged ( UINT Code, int id, HWND ctl ); + void UseSelectedClicked ( UINT Code, int id, HWND ctl ); + void UpdatePageSettings ( void ); + void SelectDirectory ( LanguageStringID Title, CModifiedEditBox & EditBox, CModifiedButton & Default, CModifiedButton & selected ); + + void UpdateDirectory ( CModifiedEditBox & EditBox, SettingID Type ); + void UpdateDefaultSelected ( CModifiedButton & Button, SettingID Type ); + + void ResetDirectory ( CModifiedEditBox & EditBox, SettingID Type ); + void ResetDefaultSelected ( CModifiedButton & ButtonDefault, CModifiedButton & ButtonSelected, SettingID Type ); + + static int CALLBACK SelectDirCallBack (HWND hwnd,DWORD uMsg,DWORD lp, DWORD lpData); + + CPartialGroupBox m_PluginGroup, m_AutoSaveGroup, m_InstantSaveGroup, + m_ScreenShotGroup, m_TextureGroup; + CModifiedEditBox m_PluginDir, m_AutoSaveDir, m_InstantSaveDir, + m_ScreenShotDir, m_TextureDir; + + CModifiedButton m_PluginDefault, m_PluginSelected, m_AutoSaveDefault, m_AutoSaveSelected, + m_InstantDefault, m_InstantSelected, m_ScreenShotDefault, m_ScreenShotSelected, + m_TextureDefault, m_TextureSelected; + + bool m_InUpdateSettings; +}; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - General.cpp b/Source/Project64/User Interface/Settings/Settings Page - Game - General.cpp index e5afbef6b..a460ee711 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - General.cpp +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - General.cpp @@ -4,12 +4,59 @@ CGameGeneralPage::CGameGeneralPage (HWND hParent, const RECT & rcDispay ) { - Create(hParent); - if (m_hWnd == NULL) + if (!Create(hParent,rcDispay)) { return; } - SetWindowPos(HWND_TOP,&rcDispay,SWP_HIDEWINDOW); + + AddModCheckBox(GetDlgItem(IDC_SYNC_AUDIO),Game_SyncViaAudio); + AddModCheckBox(GetDlgItem(IDC_ROM_SPHACK),Game_SPHack); + AddModCheckBox(GetDlgItem(IDC_ROM_FIXEDAUDIO),Game_FixedAudio); + AddModCheckBox(GetDlgItem(IDC_USE_TLB),Game_UseTlb); + AddModCheckBox(GetDlgItem(IDC_DELAY_SI),Game_DelaySI); + AddModCheckBox(GetDlgItem(IDC_AUDIO_SIGNAL),Game_RspAudioSignal); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(IDC_RDRAM_SIZE),Game_RDRamSize); + if (ComboBox) + { + ComboBox->SetTextField(GetDlgItem(IDC_MEMORY_SIZE_TEXT)); + if (_Settings->LoadBool(Setting_RdbEditor)) + { + ComboBox->AddItem(GS(RDRAM_4MB), 4 ); + ComboBox->AddItem(GS(RDRAM_8MB), 8 ); + } else { + ComboBox->AddItem(GS(RDRAM_4MB), 0x400000 ); + ComboBox->AddItem(GS(RDRAM_8MB), 0x800000 ); + } + } + + ComboBox = AddModComboBox(GetDlgItem(IDC_SAVE_TYPE),Game_SaveChip); + if (ComboBox) + { + ComboBox->SetTextField(GetDlgItem(IDC_SAVE_TYPE_TEXT)); + ComboBox->AddItem(GS(SAVE_FIRST_USED), SaveChip_Auto ); + ComboBox->AddItem(GS(SAVE_4K_EEPROM), SaveChip_Eeprom_4K ); + ComboBox->AddItem(GS(SAVE_16K_EEPROM), SaveChip_Eeprom_16K ); + ComboBox->AddItem(GS(SAVE_SRAM), SaveChip_Sram ); + ComboBox->AddItem(GS(SAVE_FLASHRAM), SaveChip_FlashRam ); + } + + ComboBox = AddModComboBox(GetDlgItem(IDC_COUNTFACT),Game_CounterFactor); + if (ComboBox) + { + ComboBox->SetTextField(GetDlgItem(IDC_COUNTFACT_TEXT)); + ComboBox->AddItem(GS(NUMBER_1), 1 ); + ComboBox->AddItem(GS(NUMBER_2), 2 ); + ComboBox->AddItem(GS(NUMBER_3), 3 ); + ComboBox->AddItem(GS(NUMBER_4), 4 ); + ComboBox->AddItem(GS(NUMBER_5), 5 ); + ComboBox->AddItem(GS(NUMBER_6), 6 ); + } + + SetDlgItemText(IDC_GOOD_NAME,_Settings->LoadString(Game_GoodName).c_str()); + + UpdatePageSettings(); } void CGameGeneralPage::ShowPage() @@ -20,4 +67,21 @@ void CGameGeneralPage::ShowPage() void CGameGeneralPage::HidePage() { ShowWindow(SW_HIDE); +} + +void CGameGeneralPage::ApplySettings( bool UpdateScreen ) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGameGeneralPage::EnableReset ( void ) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + + +void CGameGeneralPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); } \ No newline at end of file diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - General.h b/Source/Project64/User Interface/Settings/Settings Page - Game - General.h index 27825f20d..fc508b980 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - General.h +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - General.h @@ -1,11 +1,23 @@ #pragma once +#include "../WTL Controls/ModifiedCheckBox.h" +#include + class CGameGeneralPage : - private CDialogImpl, + public CSettingsPageImpl, public CSettingsPage { BEGIN_MSG_MAP_EX(CGameGeneralPage) + COMMAND_HANDLER_EX(IDC_RDRAM_SIZE,LBN_SELCHANGE,ComboBoxChanged) + COMMAND_HANDLER_EX(IDC_SAVE_TYPE,LBN_SELCHANGE,ComboBoxChanged) + COMMAND_HANDLER_EX(IDC_COUNTFACT,LBN_SELCHANGE,ComboBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SYNC_AUDIO,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_SPHACK,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_FIXEDAUDIO,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_USE_TLB,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_DELAY_SI,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_AUDIO_SIGNAL,CheckBoxChanged) END_MSG_MAP() enum { IDD = IDD_Settings_GameGeneral }; @@ -13,7 +25,12 @@ class CGameGeneralPage : public: CGameGeneralPage(HWND hParent, const RECT & rcDispay ); - LanguageStringID PageTitle ( void ) { return TAB_ROMSETTINGS; } - void HidePage ( void ); - void ShowPage ( void ); + LanguageStringID PageTitle ( void ) { return TAB_ROMSETTINGS; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: }; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.cpp b/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.cpp index 9c67072fe..c6145520c 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.cpp +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.cpp @@ -2,14 +2,181 @@ #include "Settings Page.h" #include "Settings Page - Game - Plugin.h" -CGamePluginPage::CGamePluginPage (HWND hParent, const RECT & rcDispay ) +CGamePluginPage::CGamePluginPage (HWND hParent, const RECT & rcDispay ) { - Create(hParent); - if (m_hWnd == NULL) + if (!Create(hParent,rcDispay)) { return; } - SetWindowPos(HWND_TOP,&rcDispay,SWP_HIDEWINDOW); + + //Set the text for all gui Items + SetDlgItemText(RSP_ABOUT,GS(PLUG_ABOUT)); + SetDlgItemText(GFX_ABOUT,GS(PLUG_ABOUT)); + SetDlgItemText(AUDIO_ABOUT,GS(PLUG_ABOUT)); + SetDlgItemText(CONT_ABOUT,GS(PLUG_ABOUT)); + + SetDlgItemText(IDC_RSP_NAME,GS(PLUG_RSP)); + SetDlgItemText(IDC_GFX_NAME,GS(PLUG_GFX)); + SetDlgItemText(IDC_AUDIO_NAME,GS(PLUG_AUDIO)); + SetDlgItemText(IDC_CONT_NAME,GS(PLUG_CTRL)); + + SetDlgItemText(IDC_HLE_GFX,GS(PLUG_HLE_GFX)); + SetDlgItemText(IDC_HLE_AUDIO,GS(PLUG_HLE_AUDIO)); + + m_GfxGroup.Attach(GetDlgItem(IDC_GRAPHICS_NAME)); + m_AudioGroup.Attach(GetDlgItem(IDC_AUDIO_NAME)); + m_ControlGroup.Attach(GetDlgItem(IDC_CONT_NAME)); + m_RspGroup.Attach(GetDlgItem(IDC_RSP_NAME)); + + AddPlugins(GFX_LIST,Game_Plugin_Gfx,PLUGIN_TYPE_GFX); + AddPlugins(AUDIO_LIST,Game_Plugin_Audio,PLUGIN_TYPE_AUDIO); + AddPlugins(CONT_LIST,Game_Plugin_Controller,PLUGIN_TYPE_CONTROLLER); + AddPlugins(RSP_LIST,Game_Plugin_RSP,PLUGIN_TYPE_RSP); + + AddModCheckBox(GetDlgItem(IDC_HLE_GFX),Game_UseHleGfx); + AddModCheckBox(GetDlgItem(IDC_HLE_AUDIO),Game_UseHleAudio); + + UpdatePageSettings(); +} + +void CGamePluginPage::AddPlugins (int ListId,SettingID Type, PLUGIN_TYPE PluginType ) +{ + stdstr Default = _Settings->LoadString(Type); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(ListId),Type); + for (int i = 0, n = m_PluginList.GetPluginCount(); i < n; i++ ) + { + const CPluginList::PLUGIN * Plugin = m_PluginList.GetPluginInfo(i); + if (Plugin == NULL) + { + continue; + } + if (Plugin->Info.Type != PluginType) + { + continue; + } + if (_stricmp(Default.c_str(),Plugin->FileName.c_str()) == 0) + { + ComboBox->SetDefault((WPARAM)Plugin); + } + ComboBox->AddItem(Plugin->Info.Name, (WPARAM)Plugin); + } +} + +void CGamePluginPage::ShowAboutButton ( int id ) +{ + CModifiedComboBox * ComboBox = NULL; + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + if ((int)(cb_iter->second->GetMenu()) != id) + { + continue; + } + ComboBox = cb_iter->second; + break; + } + if (ComboBox == NULL) + { + return; + } + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox->GetItemDataPtr(index); + if (Plugin == NULL) + { + return; + } + + //Load the plugin + UINT LastErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS ); + HMODULE hLib = LoadLibrary(Plugin->FullPath); + SetErrorMode(LastErrorMode); + if (hLib == NULL) + { + return; + } + + //Get DLL about + void (__cdecl *DllAbout) ( HWND hWnd ); + DllAbout = (void (__cdecl *)(HWND))GetProcAddress( hLib, "DllAbout" ); + + //call the function from the dll + DllAbout(m_hWnd); + + FreeLibrary(hLib); +} + +void CGamePluginPage::PluginItemChanged ( int id, int AboutID, bool bSetChanged ) +{ + CModifiedComboBox * ComboBox = NULL; + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + if ((int)(cb_iter->second->GetMenu()) != id) + { + continue; + } + ComboBox = cb_iter->second; + break; + } + if (ComboBox == NULL) + { + return; + } + + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox->GetItemDataPtr(index); + if (Plugin) + { + ::EnableWindow(GetDlgItem(AboutID),Plugin->AboutFunction); + } + if (bSetChanged) + { + ComboBox->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + } +} + +void CGamePluginPage::UpdatePageSettings ( void ) +{ + UpdateCheckBoxes(); + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + stdstr SelectedValue; + + ComboBox->SetChanged(_Settings->LoadString(cb_iter->first,SelectedValue)); + for (int i = 0, n = m_PluginList.GetPluginCount(); i < n; i++ ) + { + const CPluginList::PLUGIN * Plugin = m_PluginList.GetPluginInfo(i); + if (Plugin == NULL) + { + continue; + } + if (_stricmp(SelectedValue.c_str(),Plugin->FileName.c_str()) != 0) + { + continue; + } + ComboBox->SetDefault((WPARAM)Plugin); + } + } + PluginItemChanged(GFX_LIST,GFX_ABOUT,false); + PluginItemChanged(AUDIO_LIST,AUDIO_ABOUT,false); + PluginItemChanged(CONT_LIST,CONT_ABOUT,false); + PluginItemChanged(RSP_LIST,RSP_ABOUT,false); +} + +void CGamePluginPage::HidePage() +{ + ShowWindow(SW_HIDE); } void CGamePluginPage::ShowPage() @@ -17,7 +184,112 @@ void CGamePluginPage::ShowPage() ShowWindow(SW_SHOW); } -void CGamePluginPage::HidePage() +void CGamePluginPage::ApplySettings( bool UpdateScreen ) { - ShowWindow(SW_HIDE); + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGamePluginPage::EnableReset ( void ) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CGamePluginPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); +} + +void CGamePluginPage::ApplyComboBoxes ( void ) +{ + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if (ComboBox->IsChanged()) + { + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox->GetItemDataPtr(index); + + _Settings->SaveString(cb_iter->first,Plugin->FileName.c_str()); + } + if (ComboBox->IsReset()) + { + _Settings->DeleteSetting(cb_iter->first); + ComboBox->SetReset(false); + } + } +} + +bool CGamePluginPage::ResetComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) +{ + if (!ComboBox.IsChanged()) + { + return false; + } + + ComboBox.SetReset(true); + stdstr Value = _Settings->LoadDefaultString(Type); + for (int i = 0, n = ComboBox.GetCount(); i < n; i++) + { + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox.GetItemDataPtr(i); + if (Plugin->FileName != Value) + { + continue; + } + ComboBox.SetCurSel(i); + return true; + } + return false; +} + +void CGamePluginPage::HleGfxChanged ( UINT Code, int id, HWND ctl ) +{ + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + if ((Button->GetCheck() & BST_CHECKED) == 0) + { + int res = MessageBox(GS(MSG_SET_LLE_GFX_MSG),GS(MSG_SET_LLE_GFX_TITLE),MB_YESNO|MB_ICONWARNING); + if (res != IDYES) + { + Button->SetCheck(BST_CHECKED); + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } +} + +void CGamePluginPage::HleAudioChanged ( UINT Code, int id, HWND ctl ) +{ + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + if ((Button->GetCheck() & BST_CHECKED) != 0) + { + int res = MessageBox(GS(MSG_SET_HLE_AUD_MSG),GS(MSG_SET_HLE_AUD_TITLE),MB_ICONWARNING|MB_YESNO); + if (res != IDYES) + { + Button->SetCheck(BST_UNCHECKED); + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } } diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.h b/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.h index 73b1cb751..da0f7e387 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.h +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Plugin.h @@ -1,11 +1,22 @@ #pragma once +#include + class CGamePluginPage : - private CDialogImpl, + public CSettingsPageImpl, public CSettingsPage { - BEGIN_MSG_MAP_EX(CGamePluginPage) + COMMAND_HANDLER_EX(GFX_LIST,LBN_SELCHANGE,GfxPluginChanged) + COMMAND_HANDLER_EX(AUDIO_LIST,LBN_SELCHANGE,AudioPluginChanged) + COMMAND_HANDLER_EX(CONT_LIST,LBN_SELCHANGE,ControllerPluginChanged) + COMMAND_HANDLER_EX(RSP_LIST,LBN_SELCHANGE,RspPluginChanged) + COMMAND_ID_HANDLER_EX(GFX_ABOUT,GfxPluginAbout) + COMMAND_ID_HANDLER_EX(AUDIO_ABOUT,AudioPluginAbout) + COMMAND_ID_HANDLER_EX(CONT_ABOUT,ControllerPluginAbout) + COMMAND_ID_HANDLER_EX(RSP_ABOUT,RspPluginAbout) + COMMAND_ID_HANDLER_EX(IDC_HLE_GFX,HleGfxChanged) + COMMAND_ID_HANDLER_EX(IDC_HLE_AUDIO,HleAudioChanged) END_MSG_MAP() enum { IDD = IDD_Settings_GamePlugin }; @@ -13,8 +24,35 @@ class CGamePluginPage : public: CGamePluginPage(HWND hParent, const RECT & rcDispay ); - LanguageStringID PageTitle ( void ) { return TAB_PLUGIN; } - void HidePage ( void ); - void ShowPage ( void ); - + LanguageStringID PageTitle ( void ) { return TAB_PLUGIN; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + void GfxPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(GFX_LIST); } + void AudioPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(AUDIO_LIST); } + void ControllerPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(CONT_LIST); } + void RspPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(RSP_LIST); } + + void GfxPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(GFX_LIST,GFX_ABOUT); } + void AudioPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(AUDIO_LIST,AUDIO_ABOUT); } + void ControllerPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(CONT_LIST,CONT_ABOUT); } + void RspPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(RSP_LIST,RSP_ABOUT); } + + void HleGfxChanged ( UINT Code, int id, HWND ctl ); + void HleAudioChanged ( UINT Code, int id, HWND ctl ); + + void ShowAboutButton ( int id ); + void PluginItemChanged ( int id, int AboutID, bool bSetChanged = true ); + + void AddPlugins (int ListId,SettingID Type, PLUGIN_TYPE PluginType ); + void UpdatePageSettings ( void ); + void ApplyComboBoxes ( void ); + bool ResetComboBox ( CModifiedComboBox & ComboBox, SettingID Type ); + + CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup; + CPluginList m_PluginList; }; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp index f835067c4..376ea9c47 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp @@ -4,12 +4,41 @@ CGameRecompilePage::CGameRecompilePage (HWND hParent, const RECT & rcDispay ) { - Create(hParent); - if (m_hWnd == NULL) + if (!Create(hParent,rcDispay)) { return; } - SetWindowPos(HWND_TOP,&rcDispay,SWP_HIDEWINDOW); + + m_SelfModGroup.Attach(GetDlgItem(IDC_SMM_FRAME)); + + AddModCheckBox(GetDlgItem(IDC_ROM_REGCACHE),Game_RegCache); + AddModCheckBox(GetDlgItem(IDC_BLOCK_LINKING),Game_BlockLinking); + AddModCheckBox(GetDlgItem(IDC_SMM_CACHE),Game_SMM_Cache); + AddModCheckBox(GetDlgItem(IDC_SMM_DMA),Game_SMM_PIDMA); + AddModCheckBox(GetDlgItem(IDC_SMM_VALIDATE),Game_SMM_ValidFunc); + AddModCheckBox(GetDlgItem(IDC_SMM_TLB),Game_SMM_TLB); + AddModCheckBox(GetDlgItem(IDC_SMM_PROTECT),Game_SMM_Protect); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(IDC_CPU_TYPE),Game_CpuType); + if (ComboBox) + { + ComboBox->AddItem(GS(CORE_RECOMPILER), CPU_Recompiler); + ComboBox->AddItem(GS(CORE_INTERPTER), CPU_Interpreter); + if (_Settings->LoadBool(Debugger_Enabled)) + { + ComboBox->AddItem(GS(CORE_SYNC), CPU_SyncCores); + } + } + + ComboBox = AddModComboBox(GetDlgItem(IDC_FUNCFIND),Game_FuncLookupMode); + if (ComboBox) + { + ComboBox->AddItem(GS(FLM_PLOOKUP), FuncFind_PhysicalLookup); + ComboBox->AddItem(GS(FLM_VLOOKUP), FuncFind_VirtualLookup); + //ComboBox->AddItem(GS(FLM_CHANGEMEM), FuncFind_ChangeMemory); + } + UpdatePageSettings(); } void CGameRecompilePage::ShowPage() @@ -20,4 +49,20 @@ void CGameRecompilePage::ShowPage() void CGameRecompilePage::HidePage() { ShowWindow(SW_HIDE); -} \ No newline at end of file +} + +void CGameRecompilePage::ApplySettings( bool UpdateScreen ) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGameRecompilePage::EnableReset ( void ) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CGameRecompilePage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); +} diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h index b2e29d97e..0de5b0311 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h @@ -1,11 +1,20 @@ #pragma once class CGameRecompilePage : - private CDialogImpl, + public CSettingsPageImpl, public CSettingsPage { BEGIN_MSG_MAP_EX(CGameRecompilePage) + COMMAND_HANDLER_EX(IDC_CPU_TYPE,LBN_SELCHANGE,ComboBoxChanged) + COMMAND_HANDLER_EX(IDC_FUNCFIND,LBN_SELCHANGE,ComboBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_REGCACHE,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_BLOCK_LINKING,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_CACHE,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_DMA,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_VALIDATE,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_TLB,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SMM_PROTECT,CheckBoxChanged) END_MSG_MAP() enum { IDD = IDD_Settings_GameRecompiler }; @@ -13,8 +22,13 @@ class CGameRecompilePage : public: CGameRecompilePage(HWND hParent, const RECT & rcDispay ); - LanguageStringID PageTitle ( void ) { return TAB_RECOMPILER; } - void HidePage ( void ); - void ShowPage ( void ); - + LanguageStringID PageTitle ( void ) { return TAB_RECOMPILER; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + CPartialGroupBox m_SelfModGroup; }; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Status.cpp b/Source/Project64/User Interface/Settings/Settings Page - Game - Status.cpp index 0c554a524..05ecaa62e 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Status.cpp +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Status.cpp @@ -20,4 +20,18 @@ void CGameStatusPage::ShowPage() void CGameStatusPage::HidePage() { ShowWindow(SW_HIDE); +} + +void CGameStatusPage::ApplySettings( bool UpdateScreen ) +{ +} + +bool CGameStatusPage::EnableReset ( void ) +{ + return false; +} + +void CGameStatusPage::ResetPage() +{ + Notify().BreakPoint(__FILE__,__LINE__); } \ No newline at end of file diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Status.h b/Source/Project64/User Interface/Settings/Settings Page - Game - Status.h index bad45eba9..e0aac3649 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Status.h +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Status.h @@ -13,8 +13,11 @@ class CGameStatusPage : public: CGameStatusPage(HWND hParent, const RECT & rcDispay ); - LanguageStringID PageTitle ( void ) { return TAB_ROMNOTES; } - void HidePage ( void ); - void ShowPage ( void ); + LanguageStringID PageTitle ( void ) { return TAB_ROMNOTES; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); }; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game Browser.cpp b/Source/Project64/User Interface/Settings/Settings Page - Game Browser.cpp new file mode 100644 index 000000000..e3b305eec --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Game Browser.cpp @@ -0,0 +1,247 @@ +#include "../../User Interface.h" +#include "Settings Page.h" + +COptionsGameBrowserPage::COptionsGameBrowserPage (HWND hParent, const RECT & rcDispay ) : + m_OrderChanged(false), + m_OrderReset(false) +{ + if (!Create(hParent,rcDispay)) + { + return; + } + + SetDlgItemText(IDC_ROMSEL_TEXT1,GS(RB_MAX_ROMS)); + SetDlgItemText(IDC_ROMSEL_TEXT2,GS(RB_ROMS)); + SetDlgItemText(IDC_ROMSEL_TEXT3,GS(RB_MAX_DIRS)); + SetDlgItemText(IDC_ROMSEL_TEXT4,GS(RB_DIRS)); + SetDlgItemText(IDC_USE_ROMBROWSER,GS(RB_USE)); + SetDlgItemText(IDC_RECURSION,GS(RB_DIR_RECURSION)); + SetDlgItemText(IDC_ROMSEL_TEXT5,GS(RB_AVALIABLE_FIELDS)); + SetDlgItemText(IDC_ROMSEL_TEXT6,GS(RB_SHOW_FIELDS)); + SetDlgItemText(IDC_ADD,GS(RB_ADD)); + SetDlgItemText(IDC_REMOVE,GS(RB_REMOVE)); + SetDlgItemText(IDC_UP,GS(RB_UP)); + SetDlgItemText(IDC_DOWN,GS(RB_DOWN)); + + AddModCheckBox(GetDlgItem(IDC_USE_ROMBROWSER),RomBrowser_Enabled); + AddModCheckBox(GetDlgItem(IDC_RECURSION),RomBrowser_Recursive); + + m_Avaliable.Attach(GetDlgItem(IDC_AVALIABLE)); + m_Using.Attach(GetDlgItem(IDC_USING)); + + CRomBrowser::GetFieldInfo(m_Fields); + + UpdatePageSettings(); +} + +void COptionsGameBrowserPage::UpdateFieldList ( const ROMBROWSER_FIELDS_LIST & Fields ) +{ + m_Avaliable.ResetContent(); + m_Using.ResetContent(); + + m_OrderChanged = false; + for (int i = 0, n = Fields.size(); i < n; i++) + { + if (Fields[i].PosChanged()) + { + m_OrderChanged = true; + } + int Pos = Fields[i].Pos(); + if (Pos < 0) + { + m_Avaliable.SetItemData(m_Avaliable.AddString(GS(Fields[i].LangID())),i); + continue; + } + int listCount = m_Using.GetCount(); + if (Pos > listCount) { Pos = listCount; } + m_Using.SetItemData(m_Using.InsertString(Pos,GS(Fields[i].LangID())),i); + } +} + +void COptionsGameBrowserPage::UpdatePageSettings ( void ) +{ + UpdateFieldList(m_Fields); + CSettingsPageImpl::UpdatePageSettings(); + FixCtrlState(); +} + +void COptionsGameBrowserPage::UseRomBrowserChanged ( UINT Code, int id, HWND ctl ) +{ + CheckBoxChanged(Code,id,ctl); + FixCtrlState(); +} + +void COptionsGameBrowserPage::FixCtrlState ( void ) +{ + bool bEnabled = (SendDlgItemMessage(IDC_USE_ROMBROWSER,BM_GETCHECK,0,0) == BST_CHECKED); + ::EnableWindow(GetDlgItem(IDC_ROMSEL_TEXT5),bEnabled); + ::EnableWindow(GetDlgItem(IDC_ROMSEL_TEXT6),bEnabled); + ::EnableWindow(GetDlgItem(IDC_AVALIABLE),bEnabled); + ::EnableWindow(GetDlgItem(IDC_ADD),bEnabled); + ::EnableWindow(GetDlgItem(IDC_REMOVE),bEnabled); + ::EnableWindow(GetDlgItem(IDC_USING),bEnabled); + ::EnableWindow(GetDlgItem(IDC_UP),bEnabled); + ::EnableWindow(GetDlgItem(IDC_DOWN),bEnabled); + ::EnableWindow(GetDlgItem(IDC_RECURSION),bEnabled); +} + +void COptionsGameBrowserPage::AddFieldClicked ( UINT Code, int id, HWND ctl ) +{ + int index = m_Avaliable.GetCurSel(); + if (index < 0) + { + return; + } + //remove from list + int i = m_Avaliable.GetItemData(index); + m_Avaliable.DeleteString(index); + + //select next in list + int listCount = m_Avaliable.GetCount(); + if (index >= listCount) { index -= 1;} + m_Avaliable.SetCurSel(index); + + //Add to list + index = m_Using.AddString(GS(m_Fields[i].LangID())); + m_Using.SetItemData(index,i); + m_Using.SetCurSel(index); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(),PSM_CHANGED ,(WPARAM)m_hWnd,0); +} + +void COptionsGameBrowserPage::RemoveFieldClicked ( UINT Code, int id, HWND ctl ) +{ + int index = SendMessage(GetDlgItem(IDC_USING),LB_GETCURSEL,0,0); + if (index < 0) + { + return; + } + + //remove from list + int i = SendMessage(GetDlgItem(IDC_USING),LB_GETITEMDATA,index,0); + SendDlgItemMessage(IDC_USING,LB_DELETESTRING,index,0); + + //select next in list + int listCount = SendDlgItemMessage(IDC_USING,LB_GETCOUNT,0,0); + if (index >= listCount) { index -= 1;} + SendDlgItemMessage(IDC_USING,LB_SETCURSEL,index,0); + + //Add to list + index = SendDlgItemMessage(IDC_AVALIABLE,LB_ADDSTRING,0,(LPARAM)GS(m_Fields[i].LangID())); + SendDlgItemMessage(IDC_AVALIABLE,LB_SETITEMDATA,index,i); + SendDlgItemMessage(IDC_AVALIABLE,LB_SETCURSEL,index,0); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(),PSM_CHANGED ,(WPARAM)m_hWnd,0); +} + +void COptionsGameBrowserPage::MoveFieldUpClicked ( UINT Code, int id, HWND ctl ) +{ + int index = m_Using.GetCurSel(); + if (index <= 0) + { + return; + } + int i = m_Using.GetItemData(index); + m_Using.DeleteString(index); + + index = m_Using.InsertString(index - 1,GS(m_Fields[i].LangID())); + m_Using.SetItemData(index,i); + m_Using.SetCurSel(index); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(),PSM_CHANGED ,(WPARAM)m_hWnd,0); +} + +void COptionsGameBrowserPage::MoveFieldDownClicked ( UINT Code, int id, HWND ctl ) +{ + int index = m_Using.GetCurSel(); + if (index < 0 || index >= (m_Using.GetCount() - 1)) + { + return; + } + int i = m_Using.GetItemData(index); + m_Using.DeleteString(index); + + index = m_Using.InsertString(index + 1,GS(m_Fields[i].LangID())); + m_Using.SetItemData(index,i); + m_Using.SetCurSel(index); + + m_OrderChanged = true; + m_OrderReset = false; + SendMessage(GetParent(),PSM_CHANGED ,(WPARAM)m_hWnd,0); +} + +void COptionsGameBrowserPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionsGameBrowserPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionsGameBrowserPage::ApplySettings( bool UpdateScreen ) +{ + bool bColChanged = false; + if (m_OrderReset) + { + for (int i = 0; i < m_Fields.size(); i++ ) + { + m_Fields[i].ResetPos(); + } + bColChanged = true; + } else { + int Item, listCount = m_Using.GetCount(); + for (Item = 0; Item < listCount; Item ++ ) + { + int Pos = m_Using.GetItemData(Item); + if (m_OrderReset || m_Fields[Pos].Pos() != Item) + { + m_Fields[Pos].SetColPos(Item); + bColChanged = true; + } + } + + listCount = m_Avaliable.GetCount(); + for (Item = 0; Item < listCount; Item ++ ) + { + int Pos = m_Avaliable.GetItemData(Item); + if (m_OrderReset || m_Fields[Pos].Pos() != -1) + { + m_Fields[Pos].SetColPos(-1); + bColChanged = true; + } + } + } + if (bColChanged) + { + _Settings->SaveBool(RomBrowser_ColoumnsChanged,!_Settings->LoadBool(RomBrowser_ColoumnsChanged)); + } + + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool COptionsGameBrowserPage::EnableReset ( void ) +{ + if (m_OrderChanged) { return true; } + return CSettingsPageImpl::EnableReset(); +} + +void COptionsGameBrowserPage::ResetPage() +{ + if (m_OrderChanged) + { + ROMBROWSER_FIELDS_LIST Fields; + CRomBrowser::GetFieldInfo(Fields,true); + UpdateFieldList(Fields); + m_OrderReset = true; + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + } + CSettingsPageImpl::ResetPage(); +} diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game Browser.h b/Source/Project64/User Interface/Settings/Settings Page - Game Browser.h new file mode 100644 index 000000000..9903d447f --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Game Browser.h @@ -0,0 +1,41 @@ +#pragma once + +class COptionsGameBrowserPage : + public CSettingsPageImpl, + public CSettingsPage +{ + BEGIN_MSG_MAP_EX(COptionsGameBrowserPage) + COMMAND_HANDLER_EX(IDC_ADD,BN_CLICKED,AddFieldClicked) + COMMAND_HANDLER_EX(IDC_REMOVE,BN_CLICKED,RemoveFieldClicked) + COMMAND_HANDLER_EX(IDC_UP,BN_CLICKED,MoveFieldUpClicked) + COMMAND_HANDLER_EX(IDC_DOWN,BN_CLICKED,MoveFieldDownClicked) + COMMAND_ID_HANDLER_EX(IDC_USE_ROMBROWSER,UseRomBrowserChanged) + COMMAND_ID_HANDLER_EX(IDC_RECURSION,CheckBoxChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_RomBrowser }; + +public: + COptionsGameBrowserPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_ROMSELECTION; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + void UpdatePageSettings ( void ); + void UpdateFieldList ( const ROMBROWSER_FIELDS_LIST & Fields ); + void AddFieldClicked ( UINT Code, int id, HWND ctl ); + void RemoveFieldClicked ( UINT Code, int id, HWND ctl ); + void MoveFieldUpClicked ( UINT Code, int id, HWND ctl ); + void MoveFieldDownClicked ( UINT Code, int id, HWND ctl ); + void UseRomBrowserChanged ( UINT Code, int id, HWND ctl ); + void FixCtrlState ( void ); + + ROMBROWSER_FIELDS_LIST m_Fields; + CListBox m_Avaliable, m_Using; + bool m_OrderChanged, m_OrderReset; +}; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.cpp b/Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.cpp new file mode 100644 index 000000000..054a979c0 --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.cpp @@ -0,0 +1,363 @@ +#include "../../User Interface.h" +#include "Settings Page.h" + +COptionsShortCutsPage::COptionsShortCutsPage (HWND hParent, const RECT & rcDispay ) : + m_EnableReset(false) +{ + if (!Create(hParent,rcDispay)) + { + return; + } + + SetDlgItemText(IDC_S_CPU_STATE,GS(ACCEL_CPUSTATE_TITLE)); + SetDlgItemText(IDC_MENU_ITEM_TEXT,GS(ACCEL_MENUITEM_TITLE)); + SetDlgItemText(IDC_S_CURRENT_KEYS,GS(ACCEL_CURRENTKEYS_TITLE)); + SetDlgItemText(IDC_S_SELECT_SHORT,GS(ACCEL_SELKEY_TITLE)); + SetDlgItemText(IDC_S_CURRENT_ASSIGN,GS(ACCEL_ASSIGNEDTO_TITLE)); + SetDlgItemText(IDC_ASSIGN,GS(ACCEL_ASSIGN_BTN)); + SetDlgItemText(IDC_REMOVE,GS(ACCEL_REMOVE_BTN)); + + m_CreateNewShortCut.AttachToDlgItem(m_hWnd,IDC_S_SELECT_SHORT); + m_CpuState.Attach(GetDlgItem(IDC_C_CPU_STATE)); + m_MenuItems.Attach(GetDlgItem(IDC_MENU_ITEMS)); + m_CurrentKeys.Attach(GetDlgItem(IDC_CURRENT_KEYS)); + m_VirtualKeyList.Attach(GetDlgItem(IDC_VIRTUALKEY)); + + m_MenuItems.ModifyStyle(0,TVS_SHOWSELALWAYS); + + m_CpuState.SetItemData(m_CpuState.AddString(GS(ACCEL_CPUSTATE_1)),CMenuShortCutKey::GAME_NOT_RUNNING); + m_CpuState.SetItemData(m_CpuState.AddString(GS(ACCEL_CPUSTATE_3)),CMenuShortCutKey::GAME_RUNNING_WINDOW); + m_CpuState.SetItemData(m_CpuState.AddString(GS(ACCEL_CPUSTATE_4)),CMenuShortCutKey::GAME_RUNNING_FULLSCREEN); + m_CpuState.SetCurSel(0); + + int VirtualKeyListSize; + VIRTUAL_KEY * VirtualKeyList = CMenuShortCutKey::VirtualKeyList(VirtualKeyListSize); + for (int count = 0; count < VirtualKeyListSize; count++) + { + m_VirtualKeyList.SetItemData(m_VirtualKeyList.AddString(VirtualKeyList[count].Name),VirtualKeyList[count].Key); + } + + OnCpuStateChanged(LBN_SELCHANGE,IDC_C_CPU_STATE,GetDlgItem(IDC_C_CPU_STATE)); + CheckResetEnable(); + +} + +void COptionsShortCutsPage::CheckResetEnable ( void ) +{ + MSC_MAP & ShortCuts = m_ShortCuts.GetShortCuts(); + for (MSC_MAP::iterator Item = ShortCuts.begin(); Item != ShortCuts.end(); Item++) + { + const SHORTCUT_KEY_LIST & ShortCutList = Item->second.GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item ++) + { + if (!ShortCut_item->Inactive() && !ShortCut_item->UserAdded()) + { + continue; + } + m_EnableReset = true; + return; + } + + } + m_EnableReset = false; +} + +void COptionsShortCutsPage::OnCpuStateChanged(UINT Code, int id, HWND ctl) +{ + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + + MSC_MAP & ShortCuts = m_ShortCuts.GetShortCuts(); + m_MenuItems.DeleteAllItems(); + + for (MSC_MAP::iterator Item = ShortCuts.begin(); Item != ShortCuts.end(); Item++) + { + ACCESS_MODE ItemMode = Item->second.AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel ) + { + continue; + } + //find Parent + HTREEITEM hParent = m_MenuItems.GetChildItem(TVI_ROOT); + while (hParent) + { + if (m_MenuItems.GetItemData(hParent) == Item->second.Section()) + { + break; + } + hParent = m_MenuItems.GetNextSiblingItem(hParent); + } + + if (hParent == NULL) + { + hParent = m_MenuItems.InsertItem(TVIF_TEXT | TVIF_PARAM,GS(Item->second.Section()),0,0,0,0, + Item->second.Section(),TVI_ROOT,TVI_LAST); + } + + stdstr str = GS(Item->second.Title()); + str.replace("&",""); + str.replace("...",""); + + HTREEITEM hItem = m_MenuItems.InsertItem(TVIF_TEXT | TVIF_PARAM,str.c_str(),0,0,0,0, + (DWORD_PTR)&Item->second,hParent,TVI_LAST); + + const SHORTCUT_KEY_LIST & ShortCutList = Item->second.GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item ++) + { + if (!ShortCut_item->Inactive() && !ShortCut_item->UserAdded()) + { + continue; + } + m_MenuItems.SetItemState(hItem,TVIS_BOLD,TVIS_BOLD); + m_MenuItems.SetItemState(hParent,TVIS_BOLD,TVIS_BOLD); + break; + } + + } +} + +void COptionsShortCutsPage::OnRemoveClicked ( UINT Code, int id, HWND ctl ) +{ + HTREEITEM hSelectedItem = m_MenuItems.GetSelectedItem(); + if (hSelectedItem == NULL) + { + Notify().DisplayError(GS(MSG_NO_SEL_SHORTCUT)); + return; + } + HTREEITEM hParent = m_MenuItems.GetParentItem(hSelectedItem); + if (hParent == NULL) + { + Notify().DisplayError(GS(MSG_NO_SEL_SHORTCUT)); + return; + } + + CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hSelectedItem); + + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + + //Make sure an item is selected + int index = m_CurrentKeys.GetCurSel(); + if (index < 0) + { + Notify().DisplayError(GS(MSG_NO_SEL_SHORTCUT)); + return; + } + ShortCut->RemoveItem((CMenuShortCutKey *)m_CurrentKeys.GetItemData(index)); + m_MenuItems.SetItemState(hSelectedItem,TVIS_BOLD,TVIS_BOLD); + m_MenuItems.SetItemState(hParent,TVIS_BOLD,TVIS_BOLD); + m_EnableReset = true; + + RefreshShortCutOptions(hSelectedItem); + SendMessage(GetParent(),PSM_CHANGED ,(WPARAM)m_hWnd,0); +} + +void COptionsShortCutsPage::OnDetectKeyClicked ( UINT Code, int id, HWND ctl ) +{ + CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)stInputGetKeys,this,0,NULL)); +} + +void COptionsShortCutsPage::OnAssignClicked ( UINT Code, int id, HWND ctl ) +{ + //Get the virtual key info + int index = m_VirtualKeyList.GetCurSel(); + if (index < 0) + { + Notify().DisplayError(GS(MSG_NO_SHORTCUT_SEL)); + return; + } + + WORD key = SendDlgItemMessage(IDC_VIRTUALKEY,CB_GETITEMDATA,index,0); + bool bCtrl = (SendDlgItemMessage(IDC_CTL,BM_GETCHECK, 0,0) == BST_CHECKED); + bool bAlt = (SendDlgItemMessage(IDC_ALT,BM_GETCHECK, 0,0) == BST_CHECKED); + bool bShift = (SendDlgItemMessage(IDC_SHIFT,BM_GETCHECK, 0,0) == BST_CHECKED); + + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + + + HTREEITEM hSelectedItem = m_MenuItems.GetSelectedItem(); + if (hSelectedItem == NULL) + { + Notify().DisplayError(GS(MSG_NO_MENUITEM_SEL)); + return; + } + HTREEITEM hParent = m_MenuItems.GetParentItem(hSelectedItem); + if (hParent == NULL) + { + Notify().DisplayError(GS(MSG_NO_MENUITEM_SEL)); + return; + } + + CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hSelectedItem); + + LanguageStringID strid = m_ShortCuts.GetMenuItemName(key,bCtrl,bAlt,bShift,AccessLevel); + if (strid != EMPTY_STRING) + { + Notify().DisplayError(GS(MSG_MENUITEM_ASSIGNED)); + return; + } + ShortCut->AddShortCut(key,bCtrl,bAlt,bShift,AccessLevel,true,false); + m_MenuItems.SetItemState(hSelectedItem,TVIS_BOLD,TVIS_BOLD); + m_MenuItems.SetItemState(hParent,TVIS_BOLD,TVIS_BOLD); + m_EnableReset = true; + + RefreshShortCutOptions(hSelectedItem); + SendMessage(GetParent(),PSM_CHANGED ,(WPARAM)m_hWnd,0); +} + +void COptionsShortCutsPage::OnShortCutChanged ( UINT Code, int id, HWND ctl ) +{ + //Get the virtual key info + int index = m_VirtualKeyList.GetCurSel(); + if (index < 0) { return; } + WORD key = m_VirtualKeyList.GetItemData(index); + bool bCtrl = (SendDlgItemMessage(IDC_CTL,BM_GETCHECK, 0,0) == BST_CHECKED); + bool bAlt = (SendDlgItemMessage(IDC_ALT,BM_GETCHECK, 0,0) == BST_CHECKED); + bool bShift = (SendDlgItemMessage(IDC_SHIFT,BM_GETCHECK, 0,0) == BST_CHECKED); + + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + + stdstr str = GS(m_ShortCuts.GetMenuItemName(key,bCtrl,bAlt,bShift,AccessLevel)); + if (str.length() > 0) + { + str.resize(std::remove(str.begin(), str.end(), '&') - str.begin()); + } else { + str = "None"; + } + SetDlgItemText(IDC_ASSIGNED_MENU_ITEM,str.c_str()); +} + +LRESULT COptionsShortCutsPage::OnMenuItemChanged ( LPNMHDR lpnmh ) +{ + RefreshShortCutOptions(((LPNMTREEVIEW)lpnmh)->itemNew.hItem); + return true; +} + +void COptionsShortCutsPage::RefreshShortCutOptions ( HTREEITEM hItem ) +{ + HTREEITEM hParent = m_MenuItems.GetParentItem(hItem); + if (hParent == NULL) + { + return; + } + + + ACCESS_MODE AccessLevel = (ACCESS_MODE)m_CpuState.GetItemData(m_CpuState.GetCurSel()); + CShortCutItem * ShortCut = (CShortCutItem *)m_MenuItems.GetItemData(hItem); + + m_CurrentKeys.ResetContent(); + + const SHORTCUT_KEY_LIST & ShortCutList = ShortCut->GetAccelItems(); + for (SHORTCUT_KEY_LIST::const_iterator ShortCut_item = ShortCutList.begin(); ShortCut_item != ShortCutList.end(); ShortCut_item ++) + { + if (ShortCut_item->Inactive()) + { + continue; + } + + ACCESS_MODE ItemMode = ShortCut_item->AccessMode(); + if ((ItemMode & AccessLevel) != AccessLevel ) + { + continue; + } + stdstr Name = ShortCut_item->Name(); + m_CurrentKeys.SetItemData(m_CurrentKeys.AddString(Name.c_str()),(DWORD_PTR)&*ShortCut_item); + } +} + + +BOOL CALLBACK KeyPromptDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: + SetForegroundWindow(GetParent(hDlg)); + DestroyWindow(hDlg); + break; + } + break; + default: + return FALSE; + } + return TRUE; +} + +void COptionsShortCutsPage::InputGetKeys (void) +{ + HWND hKeyDlg = CreateDialogParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_Key_Prompt),m_hWnd,KeyPromptDlgProc,(LPARAM)GetDlgItem(IDC_VIRTUALKEY)); + ::EnableWindow(GetParent(),false); + MSG msg; + + for(bool fDone=false;!fDone;MsgWaitForMultipleObjects(0,NULL,false,45,QS_ALLINPUT)) { + while(PeekMessage(&msg,0,0,0,PM_REMOVE)) { + if(msg.message == WM_QUIT) { + fDone = true; + ::PostMessage(NULL,WM_QUIT,0,0); + break; + } + if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN ) { + int nVirtKey = (int)msg.wParam; + DWORD lKeyData = msg.lParam; + if (nVirtKey == VK_SHIFT) { continue; } + if (nVirtKey == VK_CONTROL) { continue; } + if (nVirtKey == VK_MENU) { continue; } + SendDlgItemMessage(IDC_VIRTUALKEY,CB_SETCURSEL,-1,0); + for (int count = 0; count < SendDlgItemMessage(IDC_VIRTUALKEY,CB_GETCOUNT,0,0); count++) { + int Data = (int)SendDlgItemMessage(IDC_VIRTUALKEY,CB_GETITEMDATA,count,0); + if (Data != nVirtKey) { continue; } + SendDlgItemMessage(IDC_VIRTUALKEY,CB_SETCURSEL,count,0); + SendDlgItemMessage(IDC_CTL,BM_SETCHECK, (GetKeyState(VK_CONTROL) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED,0); + SendDlgItemMessage(IDC_ALT,BM_SETCHECK, (GetKeyState(VK_MENU) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED,0); + SendDlgItemMessage(IDC_SHIFT,BM_SETCHECK, (GetKeyState(VK_SHIFT) & 0x80) != 0 ? BST_CHECKED : BST_UNCHECKED,0); + SendMessage(WM_COMMAND,MAKELPARAM(IDC_VIRTUALKEY,LBN_SELCHANGE),(LPARAM)GetDlgItem(IDC_VIRTUALKEY)); + SetForegroundWindow(GetParent()); + ::DestroyWindow(hKeyDlg); + } + continue; + } + if(!::IsDialogMessage(hKeyDlg,&msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + if(!::IsWindow(hKeyDlg)) { fDone = true; } + + } + ::SetFocus(GetParent()); + ::EnableWindow(GetParent(),true); +} + +void COptionsShortCutsPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionsShortCutsPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionsShortCutsPage::ApplySettings( bool UpdateScreen ) +{ + m_ShortCuts.Save(); + _Settings->SaveBool(Info_ShortCutsChanged,true); +} + +bool COptionsShortCutsPage::EnableReset ( void ) +{ + return m_EnableReset; +} + +void COptionsShortCutsPage::ResetPage() +{ + m_EnableReset = false; + m_ShortCuts.Load(true); + OnCpuStateChanged(LBN_SELCHANGE,IDC_C_CPU_STATE,GetDlgItem(IDC_C_CPU_STATE)); + SendMessage(GetParent(),PSM_CHANGED ,(WPARAM)m_hWnd,0); + m_CurrentKeys.ResetContent(); + CSettingsPageImpl::ResetPage(); +} diff --git a/Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.h b/Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.h new file mode 100644 index 000000000..10dca9dea --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Keyboard Shortcuts.h @@ -0,0 +1,57 @@ +#pragma once + +class COptionsShortCutsPage : + public CSettingsPageImpl, + public CSettingsPage +{ + typedef CMenuShortCutKey::ACCESS_MODE ACCESS_MODE; + typedef CShortCutItem::SHORTCUT_KEY_LIST SHORTCUT_KEY_LIST; + + BEGIN_MSG_MAP_EX(COptionsShortCutsPage) + COMMAND_HANDLER_EX(IDC_C_CPU_STATE,LBN_SELCHANGE,OnCpuStateChanged); + NOTIFY_HANDLER_EX(IDC_MENU_ITEMS,TVN_SELCHANGED,OnMenuItemChanged); + COMMAND_HANDLER_EX(IDC_REMOVE,BN_CLICKED,OnRemoveClicked) + COMMAND_HANDLER_EX(IDC_KEY_PROMPT,BN_CLICKED,OnDetectKeyClicked) + COMMAND_HANDLER_EX(IDC_ASSIGN,BN_CLICKED,OnAssignClicked) + COMMAND_HANDLER_EX(IDC_CTL,BN_CLICKED,OnShortCutChanged) + COMMAND_HANDLER_EX(IDC_ALT,BN_CLICKED,OnShortCutChanged) + COMMAND_HANDLER_EX(IDC_SHIFT,BN_CLICKED,OnShortCutChanged) + COMMAND_HANDLER_EX(IDC_VIRTUALKEY,LBN_SELCHANGE,OnShortCutChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_Accelerator }; + +public: + COptionsShortCutsPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_SHORTCUTS; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + void OnCpuStateChanged ( UINT Code, int id, HWND ctl ); + void OnRemoveClicked ( UINT Code, int id, HWND ctl ); + void OnDetectKeyClicked ( UINT Code, int id, HWND ctl ); + void OnAssignClicked ( UINT Code, int id, HWND ctl ); + void OnShortCutChanged ( UINT Code, int id, HWND ctl ); + LRESULT OnMenuItemChanged ( LPNMHDR lpnmh ); + + void RefreshShortCutOptions ( HTREEITEM hItem ); + void InputGetKeys ( void ); + void CheckResetEnable ( void ); + + static void stInputGetKeys (COptionsShortCutsPage * _this ) + { + _this->InputGetKeys(); + } + + CPartialGroupBox m_CreateNewShortCut; + CComboBox m_CpuState, m_VirtualKeyList; + CShortCuts m_ShortCuts; + CTreeViewCtrl m_MenuItems; + CListBox m_CurrentKeys; + bool m_EnableReset; +}; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Options.cpp b/Source/Project64/User Interface/Settings/Settings Page - Options.cpp new file mode 100644 index 000000000..e1724529f --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Options.cpp @@ -0,0 +1,43 @@ +#include "../../User Interface.h" +#include "Settings Page.h" + +CGeneralOptionsPage::CGeneralOptionsPage (HWND hParent, const RECT & rcDispay ) +{ + if (!Create(hParent,rcDispay)) + { + return; + } + + AddModCheckBox(GetDlgItem(IDC_AUTOSLEEP),Setting_AutoSleep); + AddModCheckBox(GetDlgItem(IDC_LOAD_FULLSCREEN),Setting_AutoFullscreen); + AddModCheckBox(GetDlgItem(IDC_SCREEN_SAVER),Setting_DisableScrSaver); + AddModCheckBox(GetDlgItem(IDC_BASIC_MODE),UserInterface_BasicMode); + + UpdatePageSettings(); +} + +void CGeneralOptionsPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void CGeneralOptionsPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void CGeneralOptionsPage::ApplySettings( bool UpdateScreen ) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool CGeneralOptionsPage::EnableReset ( void ) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void CGeneralOptionsPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); +} diff --git a/Source/Project64/User Interface/Settings/Settings Page - Options.h b/Source/Project64/User Interface/Settings/Settings Page - Options.h new file mode 100644 index 000000000..0025f99ec --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Options.h @@ -0,0 +1,28 @@ +#pragma once + +class CGeneralOptionsPage : + private CSettingsPageImpl, + public CSettingsPage +{ + + BEGIN_MSG_MAP_EX(CGeneralOptionsPage) + COMMAND_ID_HANDLER_EX(IDC_AUTOSLEEP,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_LOAD_FULLSCREEN,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_SCREEN_SAVER,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_BASIC_MODE,CheckBoxChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_General }; + +public: + CGeneralOptionsPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_OPTIONS; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: +}; diff --git a/Source/Project64/User Interface/Settings/Settings Page - Plugin.cpp b/Source/Project64/User Interface/Settings/Settings Page - Plugin.cpp new file mode 100644 index 000000000..c4714b2a8 --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Plugin.cpp @@ -0,0 +1,294 @@ +#include "../../User Interface.h" +#include "Settings Page.h" + +COptionPluginPage::COptionPluginPage (HWND hParent, const RECT & rcDispay ) +{ + if (!Create(hParent,rcDispay)) + { + return; + } + + //Set the text for all gui Items + SetDlgItemText(RSP_ABOUT,GS(PLUG_ABOUT)); + SetDlgItemText(GFX_ABOUT,GS(PLUG_ABOUT)); + SetDlgItemText(AUDIO_ABOUT,GS(PLUG_ABOUT)); + SetDlgItemText(CONT_ABOUT,GS(PLUG_ABOUT)); + + SetDlgItemText(IDC_RSP_NAME,GS(PLUG_RSP)); + SetDlgItemText(IDC_GFX_NAME,GS(PLUG_GFX)); + SetDlgItemText(IDC_AUDIO_NAME,GS(PLUG_AUDIO)); + SetDlgItemText(IDC_CONT_NAME,GS(PLUG_CTRL)); + + SetDlgItemText(IDC_HLE_GFX,GS(PLUG_HLE_GFX)); + SetDlgItemText(IDC_HLE_AUDIO,GS(PLUG_HLE_AUDIO)); + + m_GfxGroup.Attach(GetDlgItem(IDC_GRAPHICS_NAME)); + m_AudioGroup.Attach(GetDlgItem(IDC_AUDIO_NAME)); + m_ControlGroup.Attach(GetDlgItem(IDC_CONT_NAME)); + m_RspGroup.Attach(GetDlgItem(IDC_RSP_NAME)); + + AddPlugins(GFX_LIST,Plugin_GFX_Current,PLUGIN_TYPE_GFX); + AddPlugins(AUDIO_LIST,Plugin_AUDIO_Current,PLUGIN_TYPE_AUDIO); + AddPlugins(CONT_LIST,Plugin_CONT_Current,PLUGIN_TYPE_CONTROLLER); + AddPlugins(RSP_LIST,Plugin_RSP_Current,PLUGIN_TYPE_RSP); + + AddModCheckBox(GetDlgItem(IDC_HLE_GFX),Plugin_UseHleGfx); + AddModCheckBox(GetDlgItem(IDC_HLE_AUDIO),Plugin_UseHleAudio); + + UpdatePageSettings(); +} + +void COptionPluginPage::AddPlugins (int ListId,SettingID Type, PLUGIN_TYPE PluginType ) +{ + stdstr Default = _Settings->LoadString(Type); + + CModifiedComboBox * ComboBox; + ComboBox = AddModComboBox(GetDlgItem(ListId),Type); + for (int i = 0, n = m_PluginList.GetPluginCount(); i < n; i++ ) + { + const CPluginList::PLUGIN * Plugin = m_PluginList.GetPluginInfo(i); + if (Plugin == NULL) + { + continue; + } + if (Plugin->Info.Type != PluginType) + { + continue; + } + if (_stricmp(Default.c_str(),Plugin->FileName.c_str()) == 0) + { + ComboBox->SetDefault((WPARAM)Plugin); + } + ComboBox->AddItem(Plugin->Info.Name, (WPARAM)Plugin); + } +} + +void COptionPluginPage::ShowAboutButton ( int id ) +{ + CModifiedComboBox * ComboBox = NULL; + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + if ((int)(cb_iter->second->GetMenu()) != id) + { + continue; + } + ComboBox = cb_iter->second; + break; + } + if (ComboBox == NULL) + { + return; + } + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox->GetItemDataPtr(index); + if (Plugin == NULL) + { + return; + } + + //Load the plugin + UINT LastErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS ); + HMODULE hLib = LoadLibrary(Plugin->FullPath); + SetErrorMode(LastErrorMode); + if (hLib == NULL) + { + return; + } + + //Get DLL about + void (__cdecl *DllAbout) ( HWND hWnd ); + DllAbout = (void (__cdecl *)(HWND))GetProcAddress( hLib, "DllAbout" ); + + //call the function from the dll + DllAbout(m_hWnd); + + FreeLibrary(hLib); +} + +void COptionPluginPage::PluginItemChanged ( int id, int AboutID, bool bSetChanged ) +{ + CModifiedComboBox * ComboBox = NULL; + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + if ((int)(cb_iter->second->GetMenu()) != id) + { + continue; + } + ComboBox = cb_iter->second; + break; + } + if (ComboBox == NULL) + { + return; + } + + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox->GetItemDataPtr(index); + if (Plugin) + { + ::EnableWindow(GetDlgItem(AboutID),Plugin->AboutFunction); + } + if (bSetChanged) + { + ComboBox->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + } +} + +void COptionPluginPage::UpdatePageSettings ( void ) +{ + UpdateCheckBoxes(); + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + stdstr SelectedValue; + + ComboBox->SetChanged(_Settings->LoadString(cb_iter->first,SelectedValue)); + for (int i = 0, n = m_PluginList.GetPluginCount(); i < n; i++ ) + { + const CPluginList::PLUGIN * Plugin = m_PluginList.GetPluginInfo(i); + if (Plugin == NULL) + { + continue; + } + if (_stricmp(SelectedValue.c_str(),Plugin->FileName.c_str()) != 0) + { + continue; + } + ComboBox->SetDefault((WPARAM)Plugin); + } + } + PluginItemChanged(GFX_LIST,GFX_ABOUT,false); + PluginItemChanged(AUDIO_LIST,AUDIO_ABOUT,false); + PluginItemChanged(CONT_LIST,CONT_ABOUT,false); + PluginItemChanged(RSP_LIST,RSP_ABOUT,false); +} + +void COptionPluginPage::HidePage() +{ + ShowWindow(SW_HIDE); +} + +void COptionPluginPage::ShowPage() +{ + ShowWindow(SW_SHOW); +} + +void COptionPluginPage::ApplySettings( bool UpdateScreen ) +{ + CSettingsPageImpl::ApplySettings(UpdateScreen); +} + +bool COptionPluginPage::EnableReset ( void ) +{ + if (CSettingsPageImpl::EnableReset()) { return true; } + return false; +} + +void COptionPluginPage::ResetPage() +{ + CSettingsPageImpl::ResetPage(); +} + +void COptionPluginPage::ApplyComboBoxes ( void ) +{ + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if (ComboBox->IsChanged()) + { + int index = ComboBox->GetCurSel(); + if (index == CB_ERR) + { + return; + } + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox->GetItemDataPtr(index); + + _Settings->SaveString(cb_iter->first,Plugin->FileName.c_str()); + } + if (ComboBox->IsReset()) + { + _Settings->DeleteSetting(cb_iter->first); + ComboBox->SetReset(false); + } + } +} + +bool COptionPluginPage::ResetComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) +{ + if (!ComboBox.IsChanged()) + { + return false; + } + + ComboBox.SetReset(true); + stdstr Value = _Settings->LoadDefaultString(Type); + for (int i = 0, n = ComboBox.GetCount(); i < n; i++) + { + const CPluginList::PLUGIN * Plugin = (const CPluginList::PLUGIN *)ComboBox.GetItemDataPtr(i); + if (Plugin->FileName != Value) + { + continue; + } + ComboBox.SetCurSel(i); + return true; + } + return false; +} + +void COptionPluginPage::HleGfxChanged ( UINT Code, int id, HWND ctl ) +{ + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + if ((Button->GetCheck() & BST_CHECKED) == 0) + { + int res = MessageBox(GS(MSG_SET_LLE_GFX_MSG),GS(MSG_SET_LLE_GFX_TITLE),MB_YESNO|MB_ICONWARNING); + if (res != IDYES) + { + Button->SetCheck(BST_CHECKED); + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } +} + +void COptionPluginPage::HleAudioChanged ( UINT Code, int id, HWND ctl ) +{ + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + if ((Button->GetCheck() & BST_CHECKED) != 0) + { + int res = MessageBox(GS(MSG_SET_HLE_AUD_MSG),GS(MSG_SET_HLE_AUD_TITLE),MB_ICONWARNING|MB_YESNO); + if (res != IDYES) + { + Button->SetCheck(BST_UNCHECKED); + return; + } + } + Button->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } +} diff --git a/Source/Project64/User Interface/Settings/Settings Page - Plugin.h b/Source/Project64/User Interface/Settings/Settings Page - Plugin.h new file mode 100644 index 000000000..4fe38a77a --- /dev/null +++ b/Source/Project64/User Interface/Settings/Settings Page - Plugin.h @@ -0,0 +1,58 @@ +#pragma once + +#include + +class COptionPluginPage : + public CSettingsPageImpl, + public CSettingsPage +{ + BEGIN_MSG_MAP_EX(COptionPluginPage) + COMMAND_HANDLER_EX(GFX_LIST,LBN_SELCHANGE,GfxPluginChanged) + COMMAND_HANDLER_EX(AUDIO_LIST,LBN_SELCHANGE,AudioPluginChanged) + COMMAND_HANDLER_EX(CONT_LIST,LBN_SELCHANGE,ControllerPluginChanged) + COMMAND_HANDLER_EX(RSP_LIST,LBN_SELCHANGE,RspPluginChanged) + COMMAND_ID_HANDLER_EX(GFX_ABOUT,GfxPluginAbout) + COMMAND_ID_HANDLER_EX(AUDIO_ABOUT,AudioPluginAbout) + COMMAND_ID_HANDLER_EX(CONT_ABOUT,ControllerPluginAbout) + COMMAND_ID_HANDLER_EX(RSP_ABOUT,RspPluginAbout) + COMMAND_ID_HANDLER_EX(IDC_HLE_GFX,HleGfxChanged) + COMMAND_ID_HANDLER_EX(IDC_HLE_AUDIO,HleAudioChanged) + END_MSG_MAP() + + enum { IDD = IDD_Settings_PlugSel }; + +public: + COptionPluginPage(HWND hParent, const RECT & rcDispay ); + + LanguageStringID PageTitle ( void ) { return TAB_PLUGIN; } + void HidePage ( void ); + void ShowPage ( void ); + void ApplySettings ( bool UpdateScreen ); + bool EnableReset ( void ); + void ResetPage ( void ); + +private: + void GfxPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(GFX_LIST); } + void AudioPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(AUDIO_LIST); } + void ControllerPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(CONT_LIST); } + void RspPluginAbout ( UINT Code, int id, HWND ctl ) { ShowAboutButton(RSP_LIST); } + + void GfxPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(GFX_LIST,GFX_ABOUT); } + void AudioPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(AUDIO_LIST,AUDIO_ABOUT); } + void ControllerPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(CONT_LIST,CONT_ABOUT); } + void RspPluginChanged ( UINT Code, int id, HWND ctl ) { PluginItemChanged(RSP_LIST,RSP_ABOUT); } + + void HleGfxChanged ( UINT Code, int id, HWND ctl ); + void HleAudioChanged ( UINT Code, int id, HWND ctl ); + + void ShowAboutButton ( int id ); + void PluginItemChanged ( int id, int AboutID, bool bSetChanged = true ); + + void AddPlugins (int ListId,SettingID Type, PLUGIN_TYPE PluginType ); + void UpdatePageSettings ( void ); + void ApplyComboBoxes ( void ); + bool ResetComboBox ( CModifiedComboBox & ComboBox, SettingID Type ); + + CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup; + CPluginList m_PluginList; +}; diff --git a/Source/Project64/User Interface/Settings/Settings Page.h b/Source/Project64/User Interface/Settings/Settings Page.h index 1300b86c3..dbc64fdce 100644 --- a/Source/Project64/User Interface/Settings/Settings Page.h +++ b/Source/Project64/User Interface/Settings/Settings Page.h @@ -5,11 +5,288 @@ class CSettingsPage public: virtual ~CSettingsPage ( void ) = 0 {}; - virtual LanguageStringID PageTitle ( void ) = 0; - virtual void HidePage ( void ) = 0; - virtual void ShowPage ( void ) = 0; + virtual LanguageStringID PageTitle ( void ) = 0; + virtual void HidePage ( void ) = 0; + virtual void ShowPage ( void ) = 0; + virtual void ApplySettings ( bool UpdateScreen ) = 0; + virtual bool EnableReset ( void ) = 0; + virtual void ResetPage ( void ) = 0; }; +template +class CSettingsPageImpl : + public CDialogImpl +{ +protected: + typedef std::map ButtonList; + typedef std::map ComboBoxList; + + virtual ~CSettingsPageImpl() + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + delete iter->second; + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + delete cb_iter->second; + } + + } + bool Create(HWND hParent, const RECT & rcDispay) + { + CDialogImpl::Create(hParent); + if (m_hWnd == NULL) + { + return false; + } + SetWindowPos(HWND_TOP,&rcDispay,SWP_HIDEWINDOW); + return true; + } + + void CheckBoxChanged ( UINT Code, int id, HWND ctl ) + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if ((int)Button->GetMenu() != id) + { + continue; + } + Button->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } + } + + void UpdateModCheckBox ( CModifiedButton & CheckBox, SettingID Type ) + { + if (CheckBox.IsChanged()) + { + bool bValue = CheckBox.GetCheck() == BST_CHECKED; + if (bValue != _Settings->LoadBool(Type)) + { + _Settings->SaveBool(Type,bValue); + } + } + if (CheckBox.IsReset()) + { + _Settings->DeleteSetting(Type); + CheckBox.SetReset(false); + } + } + + bool ResetCheckBox ( CModifiedButton & CheckBox, SettingID Type ) + { + if (!CheckBox.IsChanged()) + { + return false; + } + + bool Value = _Settings->LoadDefaultBool(Type); + CheckBox.SetReset(true); + CheckBox.SetCheck(Value ? BST_CHECKED : BST_UNCHECKED); + return true; + } + + void AddModCheckBox ( HWND hWnd, SettingID Type ) + { + ButtonList::iterator item = m_ButtonList.find(Type); + if (item == m_ButtonList.end()) + { + CModifiedButton * Button = new CModifiedButton; + if (Button == NULL) + { + return; + } + Button->Attach(hWnd); + + m_ButtonList.insert(ButtonList::value_type(Type,Button)); + } + } + + CModifiedComboBox * AddModComboBox ( HWND hWnd, SettingID Type ) + { + ComboBoxList::iterator item = m_ComboBoxList.find(Type); + if (item != m_ComboBoxList.end()) + { + return item->second; + } + + CModifiedComboBox * ComboBox = new CModifiedComboBox; + if (ComboBox == NULL) + { + return NULL; + } + ComboBox->Attach(hWnd); + m_ComboBoxList.insert(ComboBoxList::value_type(Type,ComboBox)); + return ComboBox; + } + + void UpdateCheckBoxes ( void ) + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + bool SettingSelected; + + Button->SetChanged(_Settings->LoadBool(iter->first,SettingSelected)); + Button->SetCheck(SettingSelected ? BST_CHECKED : BST_UNCHECKED); + } + + } + + void UpdateComboBoxes ( void) + { + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + DWORD SelectedValue; + + ComboBox->SetChanged(_Settings->LoadDword(cb_iter->first,SelectedValue)); + ComboBox->SetDefault(SelectedValue); + } + } + + virtual void UpdatePageSettings ( void ) + { + UpdateCheckBoxes(); + UpdateComboBoxes(); + } + + void ComboBoxChanged ( UINT Code, int id, HWND ctl ) + { + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if ((int)ComboBox->GetMenu() != id) + { + continue; + } + ComboBox->SetChanged(true); + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + break; + } + } + + virtual bool ResetComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) + { + if (!ComboBox.IsChanged()) + { + return false; + } + + ComboBox.SetReset(true); + DWORD Value = _Settings->LoadDefaultDword(Type); + for (int i = 0, n = ComboBox.GetCount(); i < n; i++) + { + if (ComboBox.GetItemData(i) != Value) + { + continue; + } + ComboBox.SetCurSel(i); + return true; + } + return false; + } + + virtual void UpdateModComboBox ( CModifiedComboBox & ComboBox, SettingID Type ) + { + if (ComboBox.IsChanged()) + { + int index = ComboBox.GetCurSel(); + if (index == CB_ERR) + { + return; + } + _Settings->SaveDword(Type,(DWORD)ComboBox.GetItemData(index)); + } + if (ComboBox.IsReset()) + { + _Settings->DeleteSetting(Type); + ComboBox.SetReset(false); + } + } + +public: + virtual void ApplyCheckBoxes ( void ) + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + UpdateModCheckBox(*Button,iter->first); + } + } + virtual void ApplyComboBoxes ( void ) + { + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + UpdateModComboBox(*ComboBox,cb_iter->first); + } + } + void ApplySettings( bool UpdateScreen ) + { + ApplyCheckBoxes(); + ApplyComboBoxes(); + + if (UpdateScreen) + { + UpdatePageSettings(); + } + } + + bool EnableReset ( void ) + { + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if (Button->IsChanged()) + { + return true; + } + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if (ComboBox->IsChanged()) + { + return true; + } + } + return false; + } + + void ResetPage ( void ) + { + bool Changed = false; + for (ButtonList::iterator iter = m_ButtonList.begin(); iter != m_ButtonList.end(); iter ++) + { + CModifiedButton * Button = iter->second; + if (ResetCheckBox(*Button,iter->first)) + { + Changed = true; + } + } + for (ComboBoxList::iterator cb_iter = m_ComboBoxList.begin(); cb_iter != m_ComboBoxList.end(); cb_iter ++) + { + CModifiedComboBox * ComboBox = cb_iter->second; + if (ResetComboBox(*ComboBox,cb_iter->first)) + { + Changed = true; + } + } + if (Changed) + { + SendMessage(GetParent(),PSM_CHANGED,(WPARAM)m_hWnd,0); + } + } +protected: + ButtonList m_ButtonList; + ComboBoxList m_ComboBoxList; +}; + + typedef std::vector SETTING_PAGES; class CConfigSettingSection @@ -27,7 +304,13 @@ public: CSettingsPage * GetPage ( int PageNo ); }; +#include "Settings Page - Advanced Options.h" +#include "Settings Page - Directories.h" #include "Settings Page - Game - General.h" #include "Settings Page - Game - Plugin.h" #include "Settings Page - Game - Recompiler.h" #include "Settings Page - Game - Status.h" +#include "Settings Page - Game Browser.h" +#include "Settings Page - Keyboard Shortcuts.h" +#include "Settings Page - Options.h" +#include "Settings Page - Plugin.h" diff --git a/Source/Project64/User Interface/UI Resources.aps b/Source/Project64/User Interface/UI Resources.aps index 17106e8f2886823bb51a49fc255ee6b810a1fbb6..d2d5422a19aaebae068638a338db7c38725c988e 100644 GIT binary patch delta 12733 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 FzX4)VWRw5^ delta 13416 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 t$nq0{&Uo}(L8f>",IDC_ADD,93,97,45,12 - PUSHBUTTON "<- Remove",IDC_REMOVE,93,113,45,12 - PUSHBUTTON "Up",IDC_UP,141,166,38,11 - PUSHBUTTON "Down",IDC_DOWN,186,166,36,11 + PUSHBUTTON "Add ->",IDC_ADD,85,38,45,12 + PUSHBUTTON "<- Remove",IDC_REMOVE,85,54,45,12 + PUSHBUTTON "Up",IDC_UP,134,131,34,11 + PUSHBUTTON "Down",IDC_DOWN,175,131,34,11 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,6,19, + 208,1 END -IDD_Settings_General DIALOG DISCARDABLE 0, 0, 231, 210 -STYLE DS_MODALFRAME | WS_POPUP +IDD_Settings_General DIALOGEX 0, 0, 231, 210 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "",-1,10,24,209,147 CONTROL "Pause emulation when window is not active?", - IDC_AUTOSLEEP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18, - 46,198,8 + IDC_AUTOSLEEP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,9, + 198,8 CONTROL "On loading a ROM go to full screen",IDC_LOAD_FULLSCREEN, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,67,198,8 - CONTROL "Remember selected cheats",IDC_REMEMBER_CHEAT,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,18,88,198,8 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,25,198,8 CONTROL "Disable Screen Saver when running rom",IDC_SCREEN_SAVER, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,109,198,8 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,41,198,8 CONTROL "Hide Advanced Settings",IDC_BASIC_MODE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,18,151,198,8 - CONTROL "Frame rate display",IDC_DISPLAY_FRAMERATE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,18,130,86,9 - COMBOBOX IDC_FRAME_DISPLAY_TYPE,111,129,99,57,CBS_DROPDOWNLIST | - CBS_SORT | WS_VSCROLL | WS_TABSTOP + BS_AUTOCHECKBOX | WS_TABSTOP,8,57,198,8 + LTEXT "Max # of Roms Remembered (Max 10):",IDC_ROMSEL_TEXT1,6, + 81,145,8 + EDITTEXT IDC_REMEMBER,154,79,26,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "roms",IDC_ROMSEL_TEXT2,184,81,31,8 + LTEXT "Max # of Rom Dirs Remembered (Max 10):", + IDC_ROMSEL_TEXT3,6,96,145,8 + EDITTEXT IDC_REMEMBERDIR,154,94,26,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "dirs",IDC_ROMSEL_TEXT4,184,99,31,8 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,4,73, + 208,1 END IDD_Rom_Information DIALOGEX 0, 0, 239, 207 @@ -226,9 +223,10 @@ BEGIN WS_EX_CLIENTEDGE | WS_EX_STATICEDGE END -IDD_Settings_GameGeneral DIALOG DISCARDABLE 0, 0, 218, 158 +IDD_Settings_GameGeneral DIALOGEX 0, 0, 218, 158 STYLE WS_CHILD -FONT 8, "MS Shell Dlg" +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN LTEXT "Good Name:",IDC_GOOD_NAME_TEXT,6,8,91,10 EDITTEXT IDC_GOOD_NAME,102,7,109,12,ES_AUTOHSCROLL | ES_READONLY @@ -240,13 +238,13 @@ BEGIN LTEXT "Default Save type:",IDC_SAVE_TYPE_TEXT,6,48,91,10 COMBOBOX IDC_SAVE_TYPE,102,47,109,49,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Counter Factor:",IDC_COUNTFACT_TEXT2,6,64,91,10 + LTEXT "Counter Factor:",IDC_COUNTFACT_TEXT,6,64,91,10 COMBOBOX IDC_COUNTFACT,102,61,109,49,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Sync using Audio",IDC_SYNC_AUDIO,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,6,86,91,11 CONTROL "Use TLB",IDC_USE_TLB,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,102,86,91,11 + WS_TABSTOP,6,114,91,11 CONTROL "Delay SI Interrupt",IDC_DELAY_SI,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,102,100,91,11 CONTROL "SP Hack",IDC_ROM_SPHACK,"Button",BS_AUTOCHECKBOX | @@ -254,43 +252,42 @@ BEGIN CONTROL "RSP Audio Signal",IDC_AUDIO_SIGNAL,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,102,114,91,11 CONTROL "Fixed Audio Timing",IDC_ROM_FIXEDAUDIO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,6,114,91,8 + BS_AUTOCHECKBOX | WS_TABSTOP,102,86,91,11 CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,3,80, 208,1 END -IDD_Settings_Accelerator DIALOG DISCARDABLE 0, 0, 231, 206 -STYLE DS_MODALFRAME | WS_POPUP +IDD_Settings_Accelerator DIALOGEX 0, 0, 218, 183 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Menu Item:",IDC_MENU_ITEM_TEXT,11,31,84,10 - LTEXT "Current Keys:",IDC_S_CURRENT_KEYS,146,31,52,10 - LISTBOX IDC_CURRENT_KEYS,146,41,68,59,LBS_SORT | - LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Assign to Menu",IDC_ASSIGN,154,140,62,12 - PUSHBUTTON "Remove",IDC_REMOVE,146,105,68,12 - PUSHBUTTON "Reset All",IDC_RESET,168,188,53,12 - GROUPBOX "",IDC_STATIC,4,4,218,121 - COMBOBOX IDC_VIRTUALKEY,9,140,88,90,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - PUSHBUTTON "Detect Key",IDC_KEY_PROMPT,101,140,44,12 - CONTROL "&Ctrl",IDC_CTL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, - 157,23,9 - CONTROL "A<",IDC_ALT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41, - 157,21,9 - CONTROL "&Shift",IDC_SHIFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 71,157,26,10 - GROUPBOX "Create New Shortcut Key:",IDC_S_SELECT_SHORT,4,130,218, - 54 - LTEXT "",IDC_ASSIGNED_MENU_ITEM,93,170,118,9 - LTEXT "CPU State:",IDC_S_CPU_STATE,10,15,42,11 - COMBOBOX IDC_C_CPU_STATE,60,13,156,66,CBS_DROPDOWNLIST | + LTEXT "CPU State:",IDC_S_CPU_STATE,8,9,42,11 + COMBOBOX IDC_C_CPU_STATE,58,7,156,66,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Currently Assigned To:",IDC_S_CURRENT_ASSIGN,12,170,72, - 10 + LTEXT "Menu Item:",IDC_MENU_ITEM_TEXT,8,23,84,10 CONTROL "Tree1",IDC_MENU_ITEMS,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_NOTOOLTIPS | - TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,11,41,128,78 + TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,8,33,128,78 + LTEXT "Current Keys:",IDC_S_CURRENT_KEYS,142,23,52,10 + LISTBOX IDC_CURRENT_KEYS,144,33,68,59,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Remove",IDC_REMOVE,144,97,68,12 + GROUPBOX "Create New Shortcut Key:",IDC_S_SELECT_SHORT,8,115,207, + 57 + COMBOBOX IDC_VIRTUALKEY,8,125,91,90,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Detect Key",IDC_KEY_PROMPT,103,125,44,12 + PUSHBUTTON "Assign to Menu",IDC_ASSIGN,152,125,62,12 + CONTROL "&Ctrl",IDC_CTL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8, + 142,23,9 + CONTROL "A<",IDC_ALT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,39, + 142,21,9 + CONTROL "&Shift",IDC_SHIFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 69,142,26,10 + LTEXT "Currently Assigned To:",IDC_S_CURRENT_ASSIGN,8,155,72, + 10 + LTEXT "",IDC_ASSIGNED_MENU_ITEM,89,155,118,9 END IDD_Key_Prompt DIALOG DISCARDABLE 0, 0, 105, 43 @@ -302,9 +299,10 @@ BEGIN 3,96,19 END -IDD_Settings_GameStatus DIALOG DISCARDABLE 0, 0, 233, 206 +IDD_Settings_GameStatus DIALOGEX 0, 0, 233, 206 STYLE WS_CHILD -FONT 8, "MS Shell Dlg" +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN GROUPBOX "",IDC_STATIC,4,20,224,138 LTEXT "Status:",IDC_STATUS_TEXT,11,33,74,10 @@ -400,51 +398,29 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,126,106,50,14 END -IDD_Settings_Advanced DIALOG DISCARDABLE 0, 0, 231, 206 -STYLE DS_MODALFRAME | WS_POPUP +IDD_Settings_Advanced DIALOGEX 0, 0, 231, 206 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Core Defaults",IDC_CORE_DEFAULTS,4,28,223,72 - LTEXT "CPU core style:",IDC_TEXT2,9,38,108,12 - COMBOBOX IDC_CPU_TYPE,118,37,105,49,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP - LTEXT "Function lookup method:",IDC_TEXT3,9,53,108,12 - COMBOBOX IDC_FUNCFIND,118,52,105,49,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP - LTEXT "Default Memory Size:",IDC_TEXT4,9,69,108,12 - COMBOBOX IDC_RDRAM_SIZE,118,67,105,49,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP - LTEXT "Advanced Block Linking:",IDC_TEXT5,9,85,108,12 - COMBOBOX IDC_ABL,118,83,105,49,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP - GROUPBOX "",IDC_STATIC,4,134,223,58 CONTROL "Start Emulation when rom is opened?", IDC_START_ON_ROM_OPEN,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,12,140,207,11 - CONTROL "Always overwrite default settings with ones from ini?", - IDC_USEINI,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | - WS_TABSTOP,12,153,207,11 + WS_TABSTOP,8,8,191,11 CONTROL "Automatically compress instant saves",IDC_ZIP,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,12,166,207,11 + BS_AUTOCHECKBOX | WS_TABSTOP,8,24,191,11 CONTROL "Enable Debugger",IDC_DEBUGGER,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,12,179,207,8 - CTEXT "Most of these changes will not take effect till a new rom is opened or current rom is reset.", - IDC_INFO,4,10,223,19 - GROUPBOX "Default Self Mod Methods",IDC_STATIC,4,100,223,33 - CONTROL "Cache",IDC_SMM_CACHE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,12,111,64,9 - CONTROL "PI DMA",IDC_SMM_DMA,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,12,121,64,9 - CONTROL "Start Changed",IDC_SMM_VALIDATE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,151,111,64,8 - CONTROL "Protect Memory",IDC_SMM_PROTECT,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,76,121,64,8 - CONTROL "TLB Unmapping",IDC_SMM_TLB,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,76,111,64,8 + WS_TABSTOP,8,41,191,8 + CONTROL "Remember selected cheats",IDC_REMEMBER_CHEAT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,8,57,191,8 + CONTROL "Frame rate display",IDC_DISPLAY_FRAMERATE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,8,72,86,9 + COMBOBOX IDC_FRAME_DISPLAY_TYPE,101,71,99,57,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP END -IDD_Settings_ShellInt DIALOG DISCARDABLE 0, 0, 231, 206 -STYLE DS_MODALFRAME | WS_POPUP +IDD_Settings_ShellInt DIALOGEX 0, 0, 231, 206 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "",IDC_STATIC,5,13,218,168 @@ -732,103 +708,80 @@ BEGIN EDITTEXT IDC_INFO3,69,51,104,15,ES_AUTOHSCROLL | ES_READONLY END -IDD_Settings_Config DIALOG DISCARDABLE 0, 0, 357, 194 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_Settings_Config DIALOG DISCARDABLE 0, 0, 357, 207 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dialog" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK",IDOK,246,175,50,14 - PUSHBUTTON "Cancel",IDCANCEL,300,175,50,14 + DEFPUSHBUTTON "OK",IDOK,194,186,50,14 + PUSHBUTTON "Cancel",IDCANCEL,248,186,50,14 CONTROL "Tree1",IDC_PAGELIST,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | - WS_BORDER | WS_TABSTOP,8,7,116,158 - CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,7,169, + WS_BORDER | WS_TABSTOP,8,7,116,169 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,7,180, 343,1 - PUSHBUTTON "Reset",IDC_RESET,7,175,50,14 + PUSHBUTTON "Reset Page",IDC_RESET_PAGE,7,186,50,14,WS_DISABLED CONTROL "",IDC_SETTING_INFO,"Static",SS_ETCHEDFRAME,131,7,219, - 158 + 170 + PUSHBUTTON "Apply",IDAPPLY,301,186,50,14,WS_DISABLED + PUSHBUTTON "Reset All",IDC_RESET_ALL,63,186,50,14,WS_DISABLED END -IDD_Settings_GameRecompiler DIALOG DISCARDABLE 0, 0, 233, 206 +IDD_Settings_GameRecompiler DIALOGEX 0, 0, 230, 156 STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Good Name:",IDC_GOOD_NAME_TEXT,11,13,91,10 - EDITTEXT IDC_GOOD_NAME,124,12,99,12,ES_AUTOHSCROLL | ES_READONLY - GROUPBOX "",IDC_STATIC,4,4,224,23 - GROUPBOX "",IDC_STATIC,4,27,224,139 - LTEXT "CPU core style:",IDC_CPU_TYPE_TEXT,11,37,111,10 - COMBOBOX IDC_CPU_TYPE,124,35,99,49,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "CPU core style:",IDC_CPU_TYPE_TEXT,4,11,106,10 + COMBOBOX IDC_CPU_TYPE,113,8,99,49,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Function lookup method:",IDC_FUNCFIND_TEXT,11,51,111,10 - COMBOBOX IDC_FUNCFIND,124,50,99,49,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "Function lookup method:",IDC_FUNCFIND_TEXT,4,27,106,10 + COMBOBOX IDC_FUNCFIND,113,25,99,49,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Memory Size:",IDC_MEMORY_SIZE_TEXT,11,65,111,10 - COMBOBOX IDC_RDRAM_SIZE,124,64,99,49,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Advanced Block Linking:",IDC_BLOCK_LINKING_TEXT,11,80, - 111,10 - COMBOBOX IDC_BLOCK_LINKING,124,79,99,49,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Default Save type:",IDC_SAVE_TYPE_TEXT,11,94,111,10 - COMBOBOX IDC_SAVE_TYPE,124,93,99,49,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Counter Factor:",IDC_COUNTFACT_TEXT2,11,110,111,10 - COMBOBOX IDC_COUNTFACT,124,107,99,49,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - CONTROL "Sync using Audio",IDC_SYNC_AUDIO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,122,111,11 - CONTROL "Use TLB",IDC_USE_TLB,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,124,122,99,11 CONTROL "Register caching",IDC_ROM_REGCACHE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,133,111,11 - CONTROL "Delay SI Interrupt",IDC_DELAY_SI,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,124,132,99,11 - CONTROL "SP Hack",IDC_ROM_SPHACK,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,11,143,111,11 - CONTROL "RSP Audio Signal",IDC_AUDIO_SIGNAL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,124,143,99,11 - CONTROL "Fixed Audio Timing",IDC_ROM_FIXEDAUDIO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,154,102,8 - GROUPBOX "Self Mod Methods",IDC_SMM_FRAME,4,168,224,32 + BS_AUTOCHECKBOX | WS_TABSTOP,6,49,95,11 + GROUPBOX "Self Mod Methods",IDC_SMM_FRAME,6,63,208,54 CONTROL "Cache",IDC_SMM_CACHE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,12,177,64,9 + WS_TABSTOP,6,75,95,9 CONTROL "PI DMA",IDC_SMM_DMA,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,12,187,64,9 + WS_TABSTOP,6,87,95,9 CONTROL "Start Changed",IDC_SMM_VALIDATE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,151,177,64,8 + BS_AUTOCHECKBOX | WS_TABSTOP,6,99,95,8 CONTROL "Protect Memory",IDC_SMM_PROTECT,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,76,187,64,8 + BS_AUTOCHECKBOX | WS_TABSTOP,113,87,95,8 CONTROL "TLB Unmapping",IDC_SMM_TLB,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,76,177,64,8 - CONTROL "Custom Self Mod Method",IDC_CUSTOM_SMM,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,124,154,99,8 + WS_TABSTOP,113,75,95,8 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,6,42, + 208,1 + CONTROL "Advanced Block Linking",IDC_BLOCK_LINKING,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,113,49,95,11 END IDD_Settings_GamePlugin DIALOGEX 0, 0, 231, 206 STYLE DS_CENTER | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_TOOLWINDOW +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg" BEGIN - COMBOBOX GFX_LIST,17,30,155,79,CBS_DROPDOWNLIST | CBS_SORT | + COMBOBOX GFX_LIST,7,18,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - GROUPBOX " Audio: ",IDC_AUDIO_NAME,10,54,214,29 - COMBOBOX AUDIO_LIST,17,64,155,79,CBS_DROPDOWNLIST | CBS_SORT | + PUSHBUTTON "About",GFX_ABOUT,166,18,44,13,WS_DISABLED + COMBOBOX AUDIO_LIST,7,48,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - GROUPBOX " Controller: ",IDC_CONT_NAME,10,93,214,29 - COMBOBOX CONT_LIST,17,103,155,79,CBS_DROPDOWNLIST | CBS_SORT | + PUSHBUTTON "About",AUDIO_ABOUT,166,48,44,13,WS_DISABLED + COMBOBOX CONT_LIST,7,76,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - GROUPBOX " Reality Signal Processor: ",IDC_RSP_NAME,10,128,214,29 - COMBOBOX RSP_LIST,17,139,155,79,CBS_DROPDOWNLIST | CBS_SORT | + PUSHBUTTON "About",CONT_ABOUT,166,76,44,13,WS_DISABLED + COMBOBOX RSP_LIST,7,105,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "About",GFX_ABOUT,176,30,44,13,WS_DISABLED - PUSHBUTTON "About",AUDIO_ABOUT,176,64,44,13,WS_DISABLED - PUSHBUTTON "About",CONT_ABOUT,176,103,44,13,WS_DISABLED - PUSHBUTTON "About",RSP_ABOUT,176,139,44,13,WS_DISABLED + PUSHBUTTON "About",RSP_ABOUT,166,105,44,13,WS_DISABLED CONTROL "Use High Level GFX",IDC_HLE_GFX,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,9,164,215,8 + BS_AUTOCHECKBOX | WS_TABSTOP,9,127,193,8 CONTROL "Use High Level Audio",IDC_HLE_AUDIO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,9,177,215,8 + BS_AUTOCHECKBOX | WS_TABSTOP,9,140,188,8 + GROUPBOX "Graphics:",IDC_GRAPHICS_NAME,6,6,208,29 + GROUPBOX "Audio:",IDC_AUDIO_NAME,6,38,208,29 + GROUPBOX "Controller:",IDC_CONT_NAME,6,66,208,29 + GROUPBOX "Reality Signal Processor: ",IDC_RSP_NAME,6,96,208,29 END @@ -891,7 +844,7 @@ BEGIN BEGIN LEFTMARGIN, 4 TOPMARGIN, 4 - BOTTOMMARGIN, 200 + BOTTOMMARGIN, 177 END IDD_Key_Prompt, DIALOG @@ -1046,15 +999,15 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 350 TOPMARGIN, 7 - BOTTOMMARGIN, 187 + BOTTOMMARGIN, 200 END IDD_Settings_GameRecompiler, DIALOG BEGIN LEFTMARGIN, 4 - RIGHTMARGIN, 231 + RIGHTMARGIN, 228 TOPMARGIN, 4 - BOTTOMMARGIN, 200 + BOTTOMMARGIN, 150 END IDD_Settings_GamePlugin, DIALOG @@ -1062,7 +1015,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 222 TOPMARGIN, 7 - BOTTOMMARGIN, 131 + BOTTOMMARGIN, 172 END END #endif // APSTUDIO_INVOKED diff --git a/Source/Project64/User Interface/WTL Controls/ModifiedCheckBox.h b/Source/Project64/User Interface/WTL Controls/ModifiedCheckBox.h new file mode 100644 index 000000000..fc7b16749 --- /dev/null +++ b/Source/Project64/User Interface/WTL Controls/ModifiedCheckBox.h @@ -0,0 +1,75 @@ +#pragma once + +class CModifiedButton : + public CButton +{ + bool m_Changed; + bool m_Reset; + HFONT m_BoldFont; + HFONT m_OriginalFont; + + +public: + // Constructors + CModifiedButton(HWND hWnd = NULL) : + CButton(hWnd), + m_Changed(false), + m_Reset(false), + m_BoldFont(NULL), + m_OriginalFont(NULL) + { + } + + ~CModifiedButton() + { + if (m_BoldFont) + { + DeleteObject(m_BoldFont); + } + } + + void SetReset (bool Reset) + { + m_Reset = Reset; + if (m_Reset) + { + SetChanged(false); + } + } + + void SetChanged (bool Changed) + { + m_Changed = Changed; + if (m_Changed) + { + SetReset(false); + if (m_BoldFont == NULL) + { + m_OriginalFont = (HFONT)SendMessage(WM_GETFONT); + + LOGFONT lfSystemVariableFont; + GetObject ( m_OriginalFont, sizeof(LOGFONT), &lfSystemVariableFont ); + lfSystemVariableFont.lfWeight = FW_BOLD; + + m_BoldFont = CreateFontIndirect ( &lfSystemVariableFont ); + } + SendMessage(WM_SETFONT,(WPARAM)m_BoldFont); + InvalidateRect(NULL); + } else { + if (m_OriginalFont) + { + SendMessage(WM_SETFONT,(WPARAM)m_OriginalFont); + InvalidateRect(NULL); + } + } + } + + inline bool IsChanged ( void ) const + { + return m_Changed; + } + inline bool IsReset ( void ) const + { + return m_Reset; + } +}; diff --git a/Source/Project64/User Interface/WTL Controls/ModifiedComboBox.h b/Source/Project64/User Interface/WTL Controls/ModifiedComboBox.h new file mode 100644 index 000000000..1cfea28cb --- /dev/null +++ b/Source/Project64/User Interface/WTL Controls/ModifiedComboBox.h @@ -0,0 +1,140 @@ +#pragma once + +template +class CModifiedComboBoxT : + public CComboBox +{ + bool m_Changed; + bool m_Reset; + TParam m_defaultValue; + HFONT m_BoldFont; + HFONT m_OriginalFont; + HWND m_TextField; + +public: + // Constructors + CModifiedComboBoxT(HWND hWnd = NULL) : + CComboBox(hWnd), + m_Changed(false), + m_Reset(false), + m_BoldFont(NULL), + m_OriginalFont(NULL), + m_TextField(NULL) + { + } + + CModifiedComboBoxT(TParam defaultValue, HWND hWnd = NULL ) : + CComboBox(hWnd), + m_Changed(false), + m_Reset(false), + m_BoldFont(NULL), + m_OriginalFont(NULL), + m_defaultValue(), + m_TextField(NULL) + { + } + + ~CModifiedComboBoxT() + { + if (m_BoldFont) + { + DeleteObject(m_BoldFont); + } + } + + int AddItem (LPCSTR strItem, TParam lParam) + { + int indx = AddString(strItem); + SetItemData(indx,(DWORD_PTR)lParam); + if (GetCount() == 1 || m_defaultValue == lParam) + { + SetCurSel(indx); + } + return indx; + } + + void SetReset ( bool Reset ) + { + m_Reset = Reset; + if (m_Reset) + { + SetChanged(false); + } + } + + void SetChanged (bool Changed) + { + m_Changed = Changed; + if (m_Changed) + { + SetReset(false); + if (m_BoldFont == NULL) + { + m_OriginalFont = (HFONT)SendMessage(WM_GETFONT); + + LOGFONT lfSystemVariableFont; + GetObject ( m_OriginalFont, sizeof(LOGFONT), &lfSystemVariableFont ); + lfSystemVariableFont.lfWeight = FW_BOLD; + + m_BoldFont = CreateFontIndirect ( &lfSystemVariableFont ); + } + SendMessage(WM_SETFONT,(WPARAM)m_BoldFont); + InvalidateRect(NULL); + if (m_TextField) + { + ::SendMessage(m_TextField,WM_SETFONT,(WPARAM)m_BoldFont,0); + ::InvalidateRect(m_TextField, NULL, true); + + } + } else { + if (m_OriginalFont) + { + SendMessage(WM_SETFONT,(WPARAM)m_OriginalFont); + InvalidateRect(NULL); + if (m_TextField) + { + ::SendMessage(m_TextField,WM_SETFONT,(WPARAM)m_OriginalFont,0); + ::InvalidateRect(m_TextField, NULL, true); + } + } + } + } + + void SetTextField (HWND hWnd) + { + if (m_TextField && m_OriginalFont) + { + ::SendMessage(m_TextField,WM_SETFONT,(WPARAM)m_OriginalFont,0); + } + m_TextField = hWnd; + if (m_Changed && m_BoldFont) + { + ::SendMessage(m_TextField,WM_SETFONT,(WPARAM)m_BoldFont,0); + } + } + + inline void SetDefault (TParam defaultValue) + { + m_defaultValue = defaultValue; + for (int i = 0, n = GetCount(); i < n; i++) + { + if (GetItemData(i) == m_defaultValue) + { + SetCurSel(i); + break; + } + } + } + + inline bool IsChanged ( void ) const + { + return m_Changed; + } + inline bool IsReset ( void ) const + { + return m_Reset; + } + +}; + +typedef CModifiedComboBoxT CModifiedComboBox; diff --git a/Source/Project64/User Interface/WTL Controls/ModifiedEditBox.cpp b/Source/Project64/User Interface/WTL Controls/ModifiedEditBox.cpp new file mode 100644 index 000000000..a924b2722 --- /dev/null +++ b/Source/Project64/User Interface/WTL Controls/ModifiedEditBox.cpp @@ -0,0 +1,69 @@ +#include + +CModifiedEditBox::CModifiedEditBox(HWND hWnd) : + CEdit(hWnd), + m_Changed(false), + m_Reset(false), + m_BoldFont(NULL), + m_OriginalFont(NULL) +{ +} + +CModifiedEditBox::~CModifiedEditBox() +{ + if (m_BoldFont) + { + DeleteObject(m_BoldFont); + } +} + +void CModifiedEditBox::SetReset ( bool Reset ) +{ + m_Reset = Reset; + if (m_Reset) + { + SetChanged(false); + } +} + +void CModifiedEditBox::SetChanged (bool Changed) +{ + m_Changed = Changed; + if (m_Changed) + { + SetReset(false); + if (m_BoldFont == NULL) + { + m_OriginalFont = (HFONT)SendMessage(WM_GETFONT); + + LOGFONT lfSystemVariableFont; + GetObject ( m_OriginalFont, sizeof(LOGFONT), &lfSystemVariableFont ); + lfSystemVariableFont.lfWeight = FW_BOLD; + + m_BoldFont = CreateFontIndirect ( &lfSystemVariableFont ); + } + SendMessage(WM_SETFONT,(WPARAM)m_BoldFont); + InvalidateRect(NULL); + } else { + if (m_OriginalFont) + { + SendMessage(WM_SETFONT,(WPARAM)m_OriginalFont); + InvalidateRect(NULL); + } + } +} + +stdstr CModifiedEditBox::GetWindowText( void ) +{ + stdstr Result; + ATLASSERT(::IsWindow(m_hWnd)); + + int nLen = ::GetWindowTextLength(m_hWnd); + if(nLen == 0) + { + return Result; + } + Result.resize(nLen+1); + ::GetWindowText(m_hWnd,(char *)Result.c_str(),nLen+1); + return Result; +} diff --git a/Source/Project64/User Interface/WTL Controls/ModifiedEditBox.h b/Source/Project64/User Interface/WTL Controls/ModifiedEditBox.h new file mode 100644 index 000000000..f1b1cd43d --- /dev/null +++ b/Source/Project64/User Interface/WTL Controls/ModifiedEditBox.h @@ -0,0 +1,30 @@ +#pragma once + +class CModifiedEditBox : + public CEdit +{ + bool m_Changed; + bool m_Reset; + HFONT m_BoldFont; + HFONT m_OriginalFont; + +public: + // Constructors + CModifiedEditBox(HWND hWnd = NULL); + ~CModifiedEditBox(); + + void SetReset ( bool Reset ); + void SetChanged (bool Changed); + stdstr GetWindowText(); + + inline bool IsChanged ( void ) const + { + return m_Changed; + } + inline bool IsReset ( void ) const + { + return m_Reset; + } + +}; + diff --git a/Source/Project64/User Interface/WTL Controls/PartialGroupBox.cpp b/Source/Project64/User Interface/WTL Controls/PartialGroupBox.cpp new file mode 100644 index 000000000..ec805442b --- /dev/null +++ b/Source/Project64/User Interface/WTL Controls/PartialGroupBox.cpp @@ -0,0 +1,97 @@ +#include +//#include + +BOOL CPartialGroupBox::Attach(HWND hWndNew) +{ + return SubclassWindow(hWndNew); +} + +BOOL CPartialGroupBox::AttachToDlgItem(HWND parent, UINT dlgID) +{ + return SubclassWindow(::GetDlgItem(parent,dlgID)); +} + +void CPartialGroupBox::Draw3dLine(CPaintDC & dc, LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight) +{ + int x = lpRect->left; + int y = lpRect->top; + int cx = lpRect->right - lpRect->left; + int cy = lpRect->bottom - lpRect->top; + + dc.FillSolidRect(x, y, cx - 1, 1, clrTopLeft); + //dc.FillSolidRect(x, y, 1, cy - 1, clrTopLeft); + //dc.FillSolidRect(x + cx, y, -1, cy, clrBottomRight); + //dc.FillSolidRect(x, y + cy, cx, -1, clrBottomRight); +} + +void CPartialGroupBox::OnPaint(HDC hDC) +{ + CPaintDC dc(m_hWnd); + + //paint groupbox manually + CRect controlrect; + GetClientRect(controlrect); + //::MapWindowPoints(HWND_DESKTOP, GetParent(), (LPPOINT)(LPRECT)controlrect, (sizeof(RECT)/sizeof(POINT))); + + CFontHandle font = GetFont(); + + dc.SelectFont(font); + dc.SetMapMode(MM_TEXT); + dc.SelectBrush(GetSysColorBrush(COLOR_BTNFACE)); + + TCHAR grptext[MAX_PATH]; + GetWindowText(grptext,MAX_PATH); + + CRect fontsizerect(0,0,0,0); + dc.DrawText(grptext,-1,fontsizerect,DT_SINGLELINE|DT_LEFT|DT_CALCRECT); + + CRect framerect(controlrect); + framerect.top += (fontsizerect.Height())/2; + long Style = GetStyle(); + + if((Style & 0xF000) == BS_FLAT) + { + dc.Draw3dRect(framerect,RGB(0,0,0),RGB(0,0,0)); + framerect.DeflateRect(1,1); + dc.Draw3dRect(framerect,RGB(255,255,255),RGB(255,255,255)); + } + else + { + Draw3dLine(dc,framerect,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT)); + framerect.DeflateRect(1,1); + Draw3dLine(dc,framerect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW)); + } + + if(_tcslen(grptext)) + { + CRect fontrect(controlrect); + fontrect.bottom = controlrect.top+fontsizerect.Height(); + + if((Style & 0xF00) == BS_RIGHT) + { + fontrect.right -= 6; + fontrect.left = fontrect.right - fontsizerect.Width(); + } + else if((Style & 0xF00) == BS_CENTER) + { + fontrect.left += (controlrect.Width()-fontsizerect.Width())/2; + fontrect.right = fontrect.left + fontsizerect.Width(); + } + else //BS_LEFT or default + { + fontrect.left += 6; + fontrect.right = fontrect.left + fontsizerect.Width(); + } + + fontrect.InflateRect(2,0); + dc.FillRect(fontrect,GetSysColor(COLOR_BTNFACE)); + fontrect.DeflateRect(2,0); + + //Draw Caption + dc.SetBkMode(OPAQUE); + dc.SetBkColor(GetSysColor(COLOR_BTNFACE)); + + dc.DrawText(grptext,-1,fontrect,DT_SINGLELINE|DT_LEFT); + } + +} diff --git a/Source/Project64/User Interface/WTL Controls/PartialGroupBox.h b/Source/Project64/User Interface/WTL Controls/PartialGroupBox.h new file mode 100644 index 000000000..4f2ec00ad --- /dev/null +++ b/Source/Project64/User Interface/WTL Controls/PartialGroupBox.h @@ -0,0 +1,26 @@ +#pragma once + +class CPartialGroupBox : + public CWindowImpl +{ + void Draw3dLine(CPaintDC & dc, LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight); + +public: + BEGIN_MSG_MAP_EX(CPartialGroupBox) + MSG_WM_PAINT(OnPaint) + END_MSG_MAP() + + // Constructors + CPartialGroupBox() + { + } + + + virtual ~CPartialGroupBox() + { + } + + BOOL Attach(HWND hWndNew); + BOOL AttachToDlgItem(HWND parent, UINT dlgID); + void OnPaint(HDC hDC); +}; diff --git a/Source/Project64/User Interface/resource.h b/Source/Project64/User Interface/resource.h index 71d723b14..2a13b5a44 100644 --- a/Source/Project64/User Interface/resource.h +++ b/Source/Project64/User Interface/resource.h @@ -2,6 +2,7 @@ // Microsoft Developer Studio generated include file. // Used by UI Resources.rc // +#define IDAPPLY 3 #define IDI_PJ64_Icon 101 #define IDD_Rom_Information 104 #define IDD_Key_Prompt 108 @@ -66,10 +67,12 @@ #define IDC_INFO_ROMNAME 1008 #define IDC_BUTTON3 1008 #define IDC_RESET 1008 +#define IDC_RESET_PAGE 1008 #define IDC_INFO_CARTID 1009 #define IDC_VIRTUALKEY 1009 #define IDC_VALUE_ALIGN 1009 #define IDC_FRAME_DISPLAY_TYPE 1009 +#define IDC_RESET_ALL 1009 #define IDC_INFO_ROMSIZE 1010 #define IDC_KEY_PROMPT 1010 #define IDC_BTN_SPMEM 1010 @@ -82,13 +85,14 @@ #define IDC_HLE_GFX 1011 #define IDC_CHK_VADDR 1011 #define IDC_SEARCH_HEX 1011 -#define IDC_DISPLAY_FRAMERATE 1011 +#define IDC_DISPLAY_FRAMERATE 1012 #define IDC_INFO_MANUFACTURER 1012 #define IDC_ALT 1012 #define IDC_LIST 1012 #define IDC_HLE_AUDIO 1012 #define IDC_SMM_CACHE 1012 #define IDC_CASE_SENSITIVE 1012 +#define IDC_DISPLAY_FRAMERATE2 1013 #define IDC_INFO_COUNTRY 1013 #define IDC_SHIFT 1013 #define IDC_TLB 1013 @@ -229,10 +233,12 @@ #define IDC_ZIP 1092 #define IDC_SETTING_INFO 1092 #define IDC_GOOD_NAME_TEXT 1093 +#define IDC_GRAPHICS_NAME 1093 #define IDC_FUNCFIND_TEXT 1094 #define IDC_REMEMBER 1095 #define IDC_AUTOSLEEP 1096 #define IDC_COUNTFACT_TEXT2 1096 +#define IDC_COUNTFACT_TEXT 1096 #define IDC_RSP_NAME 1097 #define IDC_REMEMBERDIR 1097 #define IDC_GFX_NAME 1098 @@ -352,7 +358,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 150 #define _APS_NEXT_COMMAND_VALUE 40008 -#define _APS_NEXT_CONTROL_VALUE 1093 +#define _APS_NEXT_CONTROL_VALUE 1095 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/Source/Project64/ValidateBinary.cpp b/Source/Project64/ValidateBinary.cpp index f8acb7d68..89d3107df 100644 --- a/Source/Project64/ValidateBinary.cpp +++ b/Source/Project64/ValidateBinary.cpp @@ -103,7 +103,7 @@ void TestValidBinaryThread ( ) #ifdef DEBUG_VALIDATE WriteTrace(TraceError,"v3"); #endif - _Settings->SaveDword(IsValidExe,DefaultResult); + _Settings->SaveBool(Beta_IsValidExe,DefaultResult); return; } @@ -121,7 +121,7 @@ void TestValidBinaryThread ( ) #ifdef DEBUG_VALIDATE WriteTrace(TraceError,"v4"); #endif - _Settings->SaveDword(IsValidExe,DefaultResult); + _Settings->SaveBool(Beta_IsValidExe,DefaultResult); InternetCloseHandle (hSession); hSession = NULL; return; @@ -153,7 +153,7 @@ void TestValidBinaryThread ( ) #ifdef DEBUG_VALIDATE WriteTrace(TraceError,"v5"); #endif - _Settings->SaveDword(IsValidExe,DefaultResult); + _Settings->SaveBool(Beta_IsValidExe,DefaultResult); InternetCloseHandle (hRequest); return; } @@ -162,7 +162,7 @@ void TestValidBinaryThread ( ) DWORD Length = sizeof(ComputerName); GetComputerName(ComputerName,&Length); - stdstr_f PostInfo("1,%s,%s,%s,%s,%s,%s",VALIDATE_BIN_APP,File_md5.hex_digest(),ComputerName,VersionInfo(VERSION_PRODUCT_VERSION).c_str(),_Settings->LoadString(BetaUserName).c_str(),_Settings->LoadString(BetaEmailAddress).c_str()); + stdstr_f PostInfo("1,%s,%s,%s,%s,%s,%s",VALIDATE_BIN_APP,File_md5.hex_digest(),ComputerName,VersionInfo(VERSION_PRODUCT_VERSION).c_str(),_Settings->LoadString(Beta_UserName).c_str(),_Settings->LoadString(Beta_EmailAddress).c_str()); //"Content-Type: application/x-www-form-urlencoded" char ContentType[] = { "\xE9\x2C\x01\x1A\x11\x0B\x1A\x59\x79\x2D\x09\x15\x5F\x1A\x41\x11\x00\x1C\x05\x0A\x02\x15\x1D\x06\x01\x41\x57\x55\x5A\x00\x00\x5A\x4B\x09\x1D\x1F\x40\x58\x07\x1E\x09\x0B\x0D\x0C\x0B\x01\x01" }; @@ -185,7 +185,7 @@ void TestValidBinaryThread ( ) #ifdef DEBUG_VALIDATE WriteTrace(TraceError,"v6"); #endif - _Settings->SaveDword(IsValidExe,DefaultResult); + _Settings->SaveBool(Beta_IsValidExe,DefaultResult); InternetCloseHandle (hRequest); return; } @@ -198,7 +198,7 @@ void TestValidBinaryThread ( ) #ifdef DEBUG_VALIDATE WriteTrace(TraceError,"v7"); #endif - _Settings->SaveDword(IsValidExe,DefaultResult); + _Settings->SaveBool(Beta_IsValidExe,DefaultResult); InternetCloseHandle (hRequest); return; } @@ -236,7 +236,8 @@ void TestValidBinaryThread ( ) bSaveRunInfo = true; } DefaultResult = true; - } else if (Result_md5.hex_digest() == "9030FF575A9B687DC868B966CB7C02D4") // Bad MD5 + } + else if (Result_md5.hex_digest() == "9030FF575A9B687DC868B966CB7C02D4") // Bad MD5 { if (LastRunItem > 0) { @@ -313,7 +314,7 @@ void TestValidBinaryThread ( ) RegCloseKey(hKeyResults); } } - _Settings->SaveDword(IsValidExe,DefaultResult); + _Settings->SaveBool(Beta_IsValidExe,DefaultResult); } void TestValidBinary ( ) diff --git a/Source/Project64/WTL App.h b/Source/Project64/WTL App.h index 8c8b2bf1a..313232b21 100644 --- a/Source/Project64/WTL App.h +++ b/Source/Project64/WTL App.h @@ -36,3 +36,7 @@ extern CPj64Module _Module; #include "User Interface/resource.h" #include "User Interface/WTL Controls/numberctrl.h" #include "User Interface/WTL Controls/ClistCtrl/ListCtrl.h" +#include "User Interface/WTL Controls/ModifiedComboBox.h" +#include "User Interface/WTL Controls/PartialGroupBox.h" +#include "User Interface/WTL Controls/ModifiedEditBox.h" +#include "User Interface/WTL Controls/ModifiedCheckBox.h" diff --git a/Source/Project64/main.cpp b/Source/Project64/main.cpp index 3cec7258b..4cd30bbe6 100644 --- a/Source/Project64/main.cpp +++ b/Source/Project64/main.cpp @@ -139,12 +139,12 @@ void FixUPXIssue ( BYTE * ProgramLocation ) void LogLevelChanged (CTraceFileLog * LogFile) { - LogFile->SetTraceLevel((TraceLevel)_Settings->LoadDword(AppLogLevel)); + LogFile->SetTraceLevel((TraceLevel)_Settings->LoadDword(Debugger_AppLogLevel)); } void LogFlushChanged (CTraceFileLog * LogFile) { - LogFile->SetFlushFile(_Settings->LoadDword(AppLogFlush) != 0); + LogFile->SetFlushFile(_Settings->LoadDword(Debugger_AppLogFlush) != 0); } @@ -153,12 +153,12 @@ void InitializeLog ( void) CPath LogFilePath(CPath::MODULE_DIRECTORY,_T("Project64.log")); - CTraceFileLog * LogFile = new CTraceFileLog(LogFilePath, _Settings->LoadDword(AppLogFlush) != 0, Log_New); - LogFile->SetTraceLevel((TraceLevel)_Settings->LoadDword(AppLogLevel)); + CTraceFileLog * LogFile = new CTraceFileLog(LogFilePath, _Settings->LoadDword(Debugger_AppLogFlush) != 0, Log_New); + LogFile->SetTraceLevel((TraceLevel)_Settings->LoadDword(Debugger_AppLogLevel)); AddTraceModule(LogFile); - _Settings->RegisterChangeCB(AppLogLevel,LogFile,(CSettings::SettingChangedFunc)LogLevelChanged); - _Settings->RegisterChangeCB(AppLogFlush,LogFile,(CSettings::SettingChangedFunc)LogFlushChanged); + _Settings->RegisterChangeCB(Debugger_AppLogLevel,LogFile,(CSettings::SettingChangedFunc)LogLevelChanged); + _Settings->RegisterChangeCB(Debugger_AppLogFlush,LogFile,(CSettings::SettingChangedFunc)LogFlushChanged); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgs, int nWinMode) { @@ -174,77 +174,76 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgs, InitializeLog(); - WriteTrace(TraceDebug,"WinMain 1"); + WriteTrace(TraceDebug,"WinMain - Application Starting"); FixUPXIssue((BYTE *)hInstance); - WriteTrace(TraceDebug,"WinMain 2"); //Create the plugin container - WriteTrace(TraceDebug,"WinMain 3"); - CPlugins Plugins ( _Settings->LoadString(PluginDirectory) ); - WriteTrace(TraceDebug,"WinMain 4"); + WriteTrace(TraceDebug,"WinMain - Create Plugins"); + CPlugins Plugins ( _Settings->LoadString(Directory_Plugin) ); + WriteTrace(TraceDebug,"WinMain - Create N64 system"); CN64System N64System ( &Notify(), &Plugins ); //Create the backend n64 system //Select the language _Lang->LoadCurrentStrings(true); //Create the main window with Menu - WriteTrace(TraceDebug,"WinMain 6"); + WriteTrace(TraceDebug,"WinMain - Create Main Window"); stdstr WinTitle(AppName); - if (_Settings->LoadBool(IsBetaVersion)) + if (_Settings->LoadBool(Beta_IsBetaVersion)) { - WinTitle.Format("Project64 %s (%s)",VersionInfo(VERSION_PRODUCT_VERSION).c_str(),_Settings->LoadString(BetaUserName).c_str()); + WinTitle.Format("Project64 %s (%s)",VersionInfo(VERSION_PRODUCT_VERSION).c_str(),_Settings->LoadString(Beta_UserName).c_str()); } - WriteTrace(TraceDebug,"WinMain 7"); CMainGui MainWindow(WinTitle.c_str(),&Notify(),&N64System), HiddenWindow; - WriteTrace(TraceDebug,"WinMain 8"); CMainMenu MainMenu(&MainWindow, &N64System); + Plugins.SetRenderWindows(&MainWindow,&HiddenWindow); + Notify().SetMainWindow(&MainWindow); { - stdstr_f User("%s",_Settings->LoadString(BetaUserName).c_str()); - stdstr_f Email("%s",_Settings->LoadString(BetaEmailAddress).c_str()); + stdstr_f User("%s",_Settings->LoadString(Beta_UserName).c_str()); + stdstr_f Email("%s",_Settings->LoadString(Beta_EmailAddress).c_str()); - if (MD5(User).hex_digest() != _Settings->LoadString(BetaUserNameMD5) || - MD5(Email).hex_digest() != _Settings->LoadString(BetaEmailAddressMD5)) + if (MD5(User).hex_digest() != _Settings->LoadString(Beta_UserNameMD5) || + MD5(Email).hex_digest() != _Settings->LoadString(Beta_EmailAddressMD5)) { return false; } } - WriteTrace(TraceDebug,"WinMain 9"); - - Plugins.SetRenderWindows(&MainWindow,&HiddenWindow); - Notify().SetMainWindow(&MainWindow); - - WriteTrace(TraceDebug,"WinMain 10"); + if (__argc > 1) { + WriteTraceF(TraceDebug,"WinMain - Cmd line found \"%s\"",__argv[1]); MainWindow.Show(true); //Show the main window N64System.RunFileImage(__argv[1]); } else { - if (_Settings->LoadDword(RomBrowser)) { + if (_Settings->LoadDword(RomBrowser_Enabled)) + { + WriteTrace(TraceDebug,"WinMain - Show Rom Browser"); //Display the rom browser MainWindow.SetPluginList(&Plugins); MainWindow.ShowRomList(); MainWindow.Show(true); //Show the main window MainWindow.HighLightLastRom(); } else { + WriteTrace(TraceDebug,"WinMain - Show Main Window"); MainWindow.Show(true); //Show the main window } } - - //stdstr File = _Settings->LoadString(FirstRecentRom); - //if (File.length() > 0) { N64System.RunFileImage(File.c_str()); } //Process Messages till program is closed - WriteTrace(TraceDebug,"WinMain 13"); + WriteTrace(TraceDebug,"WinMain - Entering Message Loop"); MainWindow.ProcessAllMessages(); - WriteTrace(TraceDebug,"WinMain 14"); + WriteTrace(TraceDebug,"WinMain - Message Loop Finished"); N64System.CloseCpu(); //terminate the cpu thread before quiting + + WriteTrace(TraceDebug,"WinMain - System Closed"); } catch(...) { + WriteTraceF(TraceError,"WinMain - Exception caught (File: \"%s\" Line: %d)",__FILE__,__LINE__); MessageBox(NULL,stdstr_f("Exception caught\nFile: %s\nLine: %d",__FILE__,__LINE__).c_str(),"Exception",MB_OK); } + WriteTrace(TraceDebug,"WinMain - cleaning up global objects"); if (_Settings) { delete _Settings; diff --git a/Source/Project64/res/vssver2.scc b/Source/Project64/res/vssver2.scc deleted file mode 100644 index f8efecc4cbf4c0d17e6b8bced05a47496f6f5c2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmXpJVr2O5UJx$3wZX0T{E4-~cRAPFuTT58S(Jf+nSp^}3y@y6z{lXA&Q~KwAb%^6 zA6L6I4#wXG

+%s5@By4`8UQrDVj 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
H?BA?Gj*l_yEh?3ScQzH~ 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