diff --git a/Source/Project64-core/AppInit.cpp b/Source/Project64-core/AppInit.cpp index 36f73cc48f..0395530afc 100644 --- a/Source/Project64-core/AppInit.cpp +++ b/Source/Project64-core/AppInit.cpp @@ -62,6 +62,8 @@ void SetTraceModuleNames(void) TraceSetModuleName(TraceAudioPlugin, "Audio Plugin"); TraceSetModuleName(TraceControllerPlugin, "Controller Plugin"); TraceSetModuleName(TraceRSPPlugin, "RSP Plugin"); + TraceSetModuleName(TraceNetplayPlugin, "Netplay Plugin"); + TraceSetModuleName(TraceNetplay, "Netplay"); TraceSetModuleName(TraceRSP, "RSP"); TraceSetModuleName(TraceAudio, "Audio"); TraceSetModuleName(TraceRegisterCache, "Register Cache"); @@ -88,6 +90,8 @@ void UpdateTraceLevel(void * /*NotUsed*/) g_ModuleLogLevel[TraceAudioPlugin] = (uint8_t)g_Settings->LoadDword(Debugger_TraceAudioPlugin); g_ModuleLogLevel[TraceControllerPlugin] = (uint8_t)g_Settings->LoadDword(Debugger_TraceControllerPlugin); g_ModuleLogLevel[TraceRSPPlugin] = (uint8_t)g_Settings->LoadDword(Debugger_TraceRSPPlugin); + g_ModuleLogLevel[TraceNetplayPlugin] = (uint8_t)g_Settings->LoadDword(Debugger_TraceNetplayPlugin); + g_ModuleLogLevel[TraceNetplay] = (uint8_t)g_Settings->LoadDword(Debugger_TraceNetplay); g_ModuleLogLevel[TraceRSP] = (uint8_t)g_Settings->LoadDword(Debugger_TraceRSP); g_ModuleLogLevel[TraceAudio] = (uint8_t)g_Settings->LoadDword(Debugger_TraceAudio); g_ModuleLogLevel[TraceRegisterCache] = (uint8_t)g_Settings->LoadDword(Debugger_TraceRegisterCache); @@ -116,6 +120,8 @@ void SetupTrace(void) g_Settings->RegisterChangeCB(Debugger_TraceAudioPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->RegisterChangeCB(Debugger_TraceControllerPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->RegisterChangeCB(Debugger_TraceRSPPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); + g_Settings->RegisterChangeCB(Debugger_TraceNetplayPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); + g_Settings->RegisterChangeCB(Debugger_TraceNetplay, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->RegisterChangeCB(Debugger_TraceRSP, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->RegisterChangeCB(Debugger_TraceAudio, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->RegisterChangeCB(Debugger_TraceRegisterCache, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); @@ -148,6 +154,8 @@ void CleanupTrace(void) g_Settings->UnregisterChangeCB(Debugger_TraceAudioPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->UnregisterChangeCB(Debugger_TraceControllerPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->UnregisterChangeCB(Debugger_TraceRSPPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); + g_Settings->UnregisterChangeCB(Debugger_TraceNetplayPlugin, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); + g_Settings->UnregisterChangeCB(Debugger_TraceNetplay, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->UnregisterChangeCB(Debugger_TraceRSP, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->UnregisterChangeCB(Debugger_TraceAudio, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); g_Settings->UnregisterChangeCB(Debugger_TraceRegisterCache, NULL, (CSettings::SettingChangedFunc)UpdateTraceLevel); diff --git a/Source/Project64-core/Multilanguage.h b/Source/Project64-core/Multilanguage.h index bed85934f4..1bddd776c0 100644 --- a/Source/Project64-core/Multilanguage.h +++ b/Source/Project64-core/Multilanguage.h @@ -64,6 +64,7 @@ enum LanguageStringID MENU_RECENT_ROM = 107, MENU_RECENT_DIR = 108, MENU_EXIT = 109, + MENU_NETPLAY = 110, //System Menu MENU_SYSTEM = 120, @@ -93,6 +94,7 @@ enum LanguageStringID MENU_CONFG_RSP = 146, MENU_SHOW_CPU = 147, MENU_SETTINGS = 148, + MENU_CONFG_NET = 149, //Debugger Menu MENU_DEBUGGER = 160, @@ -180,6 +182,7 @@ enum LanguageStringID MENUDES_GAME_INFO = 284, MENUDES_GAME_SETTINGS = 285, MENUDES_GAME_CHEATS = 286, + MENUDES_CONFG_NET = 287, /********************************************************************************* * Rom Browser * @@ -240,6 +243,7 @@ enum LanguageStringID PLUG_HLE_GFX = 425, PLUG_HLE_AUDIO = 426, PLUG_DEFAULT = 427, + PLUG_NET = 428, //Directory Dialog DIR_PLUGIN = 440, @@ -549,6 +553,7 @@ enum LanguageStringID MSG_SET_LLE_GFX_MSG = 2055, MSG_SET_HLE_AUD_TITLE = 2056, MSG_SET_HLE_AUD_MSG = 2057, + MSG_CLOSE_NETPLAY = 2058, /********************************************************************************* * Android * diff --git a/Source/Project64-core/Multilanguage/LanguageClass.cpp b/Source/Project64-core/Multilanguage/LanguageClass.cpp index 645755eaff..07877c3020 100644 --- a/Source/Project64-core/Multilanguage/LanguageClass.cpp +++ b/Source/Project64-core/Multilanguage/LanguageClass.cpp @@ -70,6 +70,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(MENU_REFRESH, "Refresh ROM List"); DEF_STR(MENU_RECENT_ROM, "Recent ROM"); DEF_STR(MENU_RECENT_DIR, "Recent ROM Directories"); + DEF_STR(MENU_NETPLAY, "Start &Netplay..."); DEF_STR(MENU_EXIT, "E&xit"); //System Menu @@ -98,6 +99,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(MENU_CONFG_AUDIO, "Configure Audio Plugin..."); DEF_STR(MENU_CONFG_CTRL, "Configure Controller Plugin..."); DEF_STR(MENU_CONFG_RSP, "Configure RSP Plugin..."); + DEF_STR(MENU_CONFG_NET, "Configure Netplay Plugin..."); DEF_STR(MENU_SHOW_CPU, "Show CPU Usage"); DEF_STR(MENU_SETTINGS, "&Settings..."); @@ -205,6 +207,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(PLUG_GFX, " Video (graphics) plugin: "); DEF_STR(PLUG_AUDIO, " Audio (sound) plugin: "); DEF_STR(PLUG_CTRL, " Input (controller) plugin: "); + DEF_STR(PLUG_NET, " Netplay (online) plugin: "); DEF_STR(PLUG_HLE_GFX, "Graphics HLE"); DEF_STR(PLUG_HLE_AUDIO, "Audio HLE"); DEF_STR(PLUG_DEFAULT, "** Use System Plugin **"); @@ -517,6 +520,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(MSG_SET_LLE_GFX_MSG, "Graphics LLE is not for general use!!!\nIt is advisable that you only use this for testing and not for playing games.\n\nChange to graphics LLE?"); DEF_STR(MSG_SET_HLE_AUD_TITLE, "Audio High-Level Emulation"); DEF_STR(MSG_SET_HLE_AUD_MSG, "Audio HLE requires a third-party plugin!!!\nIf you do not use a third-party audio plugin that supports HLE, you will hear no sound.\n\nChange to audio HLE?"); + DEF_STR(MSG_CLOSE_NETPLAY, "Please close the Netplay window first"); /********************************************************************************* * Android * @@ -823,4 +827,4 @@ const std::wstring wGS(LanguageStringID StringID) { return stdstr(g_Lang->GetString(StringID)).ToUTF16(); } -#endif \ No newline at end of file +#endif diff --git a/Source/Project64-core/N64System/CheatClass.cpp b/Source/Project64-core/N64System/CheatClass.cpp index 61d433a9f6..128b9e5bb8 100644 --- a/Source/Project64-core/N64System/CheatClass.cpp +++ b/Source/Project64-core/N64System/CheatClass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -101,6 +102,10 @@ bool CCheats::LoadCode(const stdstr & CheatEntry, SettingID ExtensionSetting, in } m_Codes.push_back(Code); + + if (g_Settings->LoadBool(Plugin_NET_Running)) + g_Plugins->Netplay()->LoadCode(Code); + return true; } @@ -148,6 +153,11 @@ void CCheats::LoadPermCheats(CPlugins * Plugins) LoadEntry = true; break; } + if (Plugins->Netplay() != NULL && strstr(Plugins->Netplay()->PluginName(), PluginName.c_str()) != NULL) + { + LoadEntry = true; + break; + } } } @@ -221,9 +231,17 @@ uint16_t ConvertXP64Value(uint16_t Value) void CCheats::ApplyCheats() { - for (size_t CurrentCheat = 0; CurrentCheat < m_Codes.size(); CurrentCheat++) + if (g_Settings->LoadBool(Plugin_NET_Running)) + ApplyCheatsArray(g_Plugins->Netplay()->GetCodes()); + else + ApplyCheatsArray(m_Codes); +} + +void CCheats::ApplyCheatsArray(CODES_ARRAY Codes) +{ + for (size_t CurrentCheat = 0; CurrentCheat < Codes.size(); CurrentCheat++) { - CODES & CodeEntry = m_Codes[CurrentCheat]; + CODES & CodeEntry = Codes[CurrentCheat]; for (size_t CurrentEntry = 0; CurrentEntry < CodeEntry.size();) { ApplyCheatEntry(CodeEntry, CurrentEntry); diff --git a/Source/Project64-core/N64System/CheatClass.h b/Source/Project64-core/N64System/CheatClass.h index 77e54fa5bb..f92493243a 100644 --- a/Source/Project64-core/N64System/CheatClass.h +++ b/Source/Project64-core/N64System/CheatClass.h @@ -32,6 +32,8 @@ class CCheats static bool IsValid16BitCode(const char * CheatString); private: + friend class CNetplay_Plugin; + struct GAMESHARK_CODE { uint32_t Command; @@ -55,6 +57,7 @@ class CCheats typedef std::map ORIGINAL_VALUES16; typedef std::map ORIGINAL_VALUES8; + void ApplyCheatsArray(CODES_ARRAY Codes); void LoadPermCheats(CPlugins * Plugins); int32_t EntrySize(const CODES & CodeEntry, int32_t CurrentEntry); diff --git a/Source/Project64-core/N64System/Mips/Eeprom.cpp b/Source/Project64-core/N64System/Mips/Eeprom.cpp index 7de9eaa9e8..23f9e8f329 100644 --- a/Source/Project64-core/N64System/Mips/Eeprom.cpp +++ b/Source/Project64-core/N64System/Mips/Eeprom.cpp @@ -141,6 +141,12 @@ void CEeprom::EepromCommand(uint8_t * Command) void CEeprom::LoadEeprom() { + if (g_Settings->LoadBool(Plugin_NET_Running) && ! g_Settings->LoadBool(Plugin_NET_CanSave)) + { + WriteTrace(TraceNetplayPlugin, TraceInfo, "Loading Sram is disabled during Netplay"); + return; + } + memset(m_EEPROM, 0xFF, sizeof(m_EEPROM)); CPath FileName(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.eep", g_Settings->LoadStringVal(Game_GameName).c_str()).c_str()); diff --git a/Source/Project64-core/N64System/Mips/FlashRam.cpp b/Source/Project64-core/N64System/Mips/FlashRam.cpp index d20d2554b2..e9315c45f6 100644 --- a/Source/Project64-core/N64System/Mips/FlashRam.cpp +++ b/Source/Project64-core/N64System/Mips/FlashRam.cpp @@ -120,6 +120,12 @@ uint32_t CFlashram::ReadFromFlashStatus(uint32_t PAddr) bool CFlashram::LoadFlashram() { + if (g_Settings->LoadBool(Plugin_NET_Running) && ! g_Settings->LoadBool(Plugin_NET_CanSave)) + { + WriteTrace(TraceNetplayPlugin, TraceInfo, "Loading Flashram is disabled during Netplay"); + return false; + } + CPath FileName(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.fla", g_Settings->LoadStringVal(Game_GameName).c_str()).c_str()); if (g_Settings->LoadBool(Setting_UniqueSaveDir)) { diff --git a/Source/Project64-core/N64System/Mips/PifRam.cpp b/Source/Project64-core/N64System/Mips/PifRam.cpp index 3e102ad5aa..61e462eb6b 100644 --- a/Source/Project64-core/N64System/Mips/PifRam.cpp +++ b/Source/Project64-core/N64System/Mips/PifRam.cpp @@ -77,7 +77,15 @@ void CPifRam::PifRamRead() return; } - CONTROL * Controllers = g_Plugins->Control()->PluginControllers(); + CONTROL * Controllers; + if (g_Settings->LoadBool(Plugin_NET_Running)) + { + Controllers = g_Plugins->Netplay()->PluginControllers(); + } + else + { + Controllers = g_Plugins->Control()->PluginControllers(); + } int32_t Channel = 0; for (int32_t CurPos = 0; CurPos < 0x40; CurPos++) @@ -102,9 +110,16 @@ void CPifRam::PifRamRead() { if (Controllers[Channel].Present && Controllers[Channel].RawData) { - if (g_Plugins->Control()->ReadController) + if (g_Settings->LoadBool(Plugin_NET_Running)) { - g_Plugins->Control()->ReadController(Channel, &m_PifRam[CurPos]); + g_Plugins->Netplay()->ReadController(Channel, &m_PifRam[CurPos]); + } + else + { + if (g_Plugins->Control()->ReadController) + { + g_Plugins->Control()->ReadController(Channel, &m_PifRam[CurPos]); + } } } else @@ -134,7 +149,15 @@ void CPifRam::PifRamRead() void CPifRam::PifRamWrite() { - CONTROL * Controllers = g_Plugins->Control()->PluginControllers(); + CONTROL * Controllers; + if (g_Settings->LoadBool(Plugin_NET_Running)) + { + Controllers = g_Plugins->Netplay()->PluginControllers(); + } + else + { + Controllers = g_Plugins->Control()->PluginControllers(); + } int32_t Channel = 0, CurPos; if (m_PifRam[0x3F] > 0x1) @@ -433,7 +456,15 @@ void CPifRam::SI_DMA_WRITE() void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command) { - CONTROL * Controllers = g_Plugins->Control()->PluginControllers(); + CONTROL * Controllers; + if (g_Settings->LoadBool(Plugin_NET_Running)) + { + Controllers = g_Plugins->Netplay()->PluginControllers(); + } + else + { + Controllers = g_Plugins->Control()->PluginControllers(); + } switch (Command[2]) { @@ -572,7 +603,15 @@ void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command) void CPifRam::ReadControllerCommand(int32_t Control, uint8_t * Command) { - CONTROL * Controllers = g_Plugins->Control()->PluginControllers(); + CONTROL * Controllers; + if (g_Settings->LoadBool(Plugin_NET_Running)) + { + Controllers = g_Plugins->Netplay()->PluginControllers(); + } + else + { + Controllers = g_Plugins->Control()->PluginControllers(); + } switch (Command[2]) { diff --git a/Source/Project64-core/N64System/Mips/Sram.cpp b/Source/Project64-core/N64System/Mips/Sram.cpp index 1d9525f053..babf2573be 100644 --- a/Source/Project64-core/N64System/Mips/Sram.cpp +++ b/Source/Project64-core/N64System/Mips/Sram.cpp @@ -23,6 +23,12 @@ CSram::~CSram() bool CSram::LoadSram() { + if (g_Settings->LoadBool(Plugin_NET_Running) && ! g_Settings->LoadBool(Plugin_NET_CanSave)) + { + WriteTrace(TraceNetplayPlugin, TraceInfo, "Loading Sram is disabled during Netplay"); + return false; + } + CPath FileName(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.sra", g_Settings->LoadStringVal(Game_GameName).c_str()).c_str()); if (g_Settings->LoadBool(Setting_UniqueSaveDir)) { diff --git a/Source/Project64-core/N64System/Mips/SystemEvents.cpp b/Source/Project64-core/N64System/Mips/SystemEvents.cpp index e5e0c46321..fd75d2f829 100644 --- a/Source/Project64-core/N64System/Mips/SystemEvents.cpp +++ b/Source/Project64-core/N64System/Mips/SystemEvents.cpp @@ -102,6 +102,9 @@ void CSystemEvents::ExecuteEvents() m_Events.clear(); } + bool NetplayRunning = g_Settings->LoadBool(Plugin_NET_Running); + bool NetplayCanPause = g_Settings->LoadBool(Plugin_NET_CanPause); + bool bPause = false, bLoadedSave = false; for (EventList::const_iterator iter = Events.begin(); !bLoadedSave && iter != Events.end(); iter++) { @@ -196,17 +199,23 @@ void CSystemEvents::ExecuteEvents() case SysEvent_PauseCPU_AppLostFocus: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { - g_Settings->SaveBool(GameRunning_CPU_Paused, true); - g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostFocus); - bPause = true; + if (!NetplayRunning || (NetplayRunning && NetplayCanPause)) + { + g_Settings->SaveBool(GameRunning_CPU_Paused, true); + g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostFocus); + bPause = true; + } } break; case SysEvent_PauseCPU_AppLostActive: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { - g_Settings->SaveBool(GameRunning_CPU_Paused, true); - g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostActive); - bPause = true; + if (!NetplayRunning || (NetplayRunning && NetplayCanPause)) + { + g_Settings->SaveBool(GameRunning_CPU_Paused, true); + g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostActive); + bPause = true; + } } break; case SysEvent_PauseCPU_SaveGame: @@ -244,17 +253,23 @@ void CSystemEvents::ExecuteEvents() case SysEvent_PauseCPU_Settings: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { - g_Settings->SaveBool(GameRunning_CPU_Paused, true); - g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_Settings); - bPause = true; + if (!NetplayRunning || (NetplayRunning && NetplayCanPause)) + { + g_Settings->SaveBool(GameRunning_CPU_Paused, true); + g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_Settings); + bPause = true; + } } break; case SysEvent_PauseCPU_Cheats: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { - g_Settings->SaveBool(GameRunning_CPU_Paused, true); - g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_Cheats); - bPause = true; + if (!NetplayRunning || (NetplayRunning && NetplayCanPause)) + { + g_Settings->SaveBool(GameRunning_CPU_Paused, true); + g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_Cheats); + bPause = true; + } } break; case SysEvent_ResetRecompilerCode: diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index dd05b49ecc..19a60da585 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -70,7 +70,17 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR } m_Limiter.SetHertz(gameHertz); g_Settings->SaveDword(GameRunning_ScreenHertz, gameHertz); + + if (g_Settings->LoadBool(Plugin_NET_Running)) + g_Plugins->Netplay()->ResetCodes(); m_Cheats.LoadCheats(!g_Settings->LoadDword(Setting_RememberCheats), Plugins); + + if (g_Settings->LoadDword(Setting_RememberCheats)) + { + if (g_Settings->LoadBool(Plugin_NET_Running)) + g_Plugins->Netplay()->ForwardCheats(); + } + WriteTrace(TraceN64System, TraceDebug, "Setting up system"); CInterpreterCPU::BuildCPU(); @@ -345,6 +355,11 @@ bool CN64System::LoadFileImage(const char * FileLoc) } bool CN64System::RunFileImage(const char * FileLoc) +{ + return RunFileImage(FileLoc, NULL, NULL); +} + +bool CN64System::RunFileImage(const char * FileLoc, uint32_t randomizer_seed, bool SavesReadOnly) { if (!LoadFileImage(FileLoc)) { @@ -353,15 +368,20 @@ bool CN64System::RunFileImage(const char * FileLoc) if (g_Settings->LoadBool(Setting_AutoStart) != 0) { WriteTrace(TraceN64System, TraceDebug, "Automattically starting rom"); - RunLoadedImage(); + RunLoadedImage(randomizer_seed, SavesReadOnly); } return true; } void CN64System::RunLoadedImage(void) +{ + RunLoadedImage(NULL, NULL); +} + +void CN64System::RunLoadedImage(uint32_t randomizer_seed = time(NULL), bool SavesReadOnly = false) { WriteTrace(TraceN64System, TraceDebug, "Start"); - g_BaseSystem = new CN64System(g_Plugins, (uint32_t)time(NULL), false, false); + g_BaseSystem = new CN64System(g_Plugins, (uint32_t)randomizer_seed, SavesReadOnly, false); if (g_BaseSystem) { g_BaseSystem->StartEmulation(true); @@ -2104,17 +2124,34 @@ void CN64System::RefreshScreen() { g_Audio->SetViIntr(VI_INTR_TIME); } - if (g_Plugins->Control()->GetKeys) + if (g_Settings->LoadBool(Plugin_NET_Running)) { + g_Plugins->Netplay()->ForwardInputs(); + BUTTONS Keys; memset(&Keys, 0, sizeof(Keys)); for (int Control = 0; Control < 4; Control++) { - g_Plugins->Control()->GetKeys(Control, &Keys); + if (g_Plugins->Control()->GetKeys) { g_Plugins->Control()->GetKeys(Control, &Keys); } + g_Plugins->Netplay()->GetKeys(Control, &Keys); m_Buttons[Control] = Keys.Value; } } + else + { + if (g_Plugins->Control()->GetKeys) + { + BUTTONS Keys; + memset(&Keys, 0, sizeof(Keys)); + + for (int Control = 0; Control < 4; Control++) + { + g_Plugins->Control()->GetKeys(Control, &Keys); + m_Buttons[Control] = Keys.Value; + } + } + } if (bShowCPUPer()) { m_CPU_Usage.StartTimer(Timer_UpdateScreen); } @@ -2169,8 +2206,16 @@ void CN64System::RefreshScreen() g_SyncSystem->SetCheatsSlectionChanged(true); } SetCheatsSlectionChanged(false); + + if (g_Settings->LoadBool(Plugin_NET_Running)) + g_Plugins->Netplay()->ResetCodes(); + m_Cheats.LoadCheats(false, g_BaseSystem->m_Plugins); + + if (g_Settings->LoadBool(Plugin_NET_Running)) + g_Plugins->Netplay()->ForwardCheats(); } + m_Cheats.ApplyCheats(); } // if (bProfiling) { m_Profile.StartTimer(ProfilingAddr != Timer_None ? ProfilingAddr : Timer_R4300); } @@ -2196,4 +2241,4 @@ void CN64System::TLB_Changed() { g_Debugger->TLBChanged(); } -} \ No newline at end of file +} diff --git a/Source/Project64-core/N64System/N64Class.h b/Source/Project64-core/N64System/N64Class.h index 962fc376c8..abe2c8003e 100644 --- a/Source/Project64-core/N64System/N64Class.h +++ b/Source/Project64-core/N64System/N64Class.h @@ -59,9 +59,11 @@ class CN64System : //Methods static bool LoadFileImage(const char * FileLoc); static bool RunFileImage(const char * FileLoc); + static bool RunFileImage(const char * FileLoc, uint32_t randomizer_seed, bool SavesReadOnly); static bool RunFileImageIPL(const char * FileLoc); static bool RunDiskImage(const char * FileLoc); static void RunLoadedImage(void); + static void RunLoadedImage(uint32_t randomizer_seed, bool SavesReadOnly); static void CloseSystem(void); void CloseCpu(); @@ -105,6 +107,7 @@ class CN64System : friend class CAudioPlugin; friend class CRSP_Plugin; friend class CControl_Plugin; + friend class CNetplay_Plugin; //Recompiler has access to manipulate and call functions friend class CSystemTimer; diff --git a/Source/Project64-core/Plugin.h b/Source/Project64-core/Plugin.h index e17ce51cdd..1cfd22ae5d 100644 --- a/Source/Project64-core/Plugin.h +++ b/Source/Project64-core/Plugin.h @@ -20,3 +20,4 @@ #include #include "Plugins/ControllerPlugin.h" #include "Plugins/RSPPlugin.h" +#include "Plugins/NetplayPlugin.h" diff --git a/Source/Project64-core/Plugins/NetplayPlugin.cpp b/Source/Project64-core/Plugins/NetplayPlugin.cpp new file mode 100644 index 0000000000..92afc5605f --- /dev/null +++ b/Source/Project64-core/Plugins/NetplayPlugin.cpp @@ -0,0 +1,552 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +CNetplay_Plugin::CNetplay_Plugin() : +SyncCheats(NULL), +SyncEvents(NULL), +SyncInputs(NULL), +SyncSettings(NULL) +{ +} + +CNetplay_Plugin::~CNetplay_Plugin() +{ + Close(NULL); + UnloadPlugin(); +} + +bool CNetplay_Plugin::LoadFunctions(void) +{ + //Find entries for functions in DLL + void(CALL *InitiateNetplay)(void); + LoadFunction(InitiateNetplay); + + LoadFunction(SyncCheats); + LoadFunction(SyncEvents); + LoadFunction(SyncInputs); + LoadFunction(SyncSettings); + + //Make sure dll has all needed functions + if (InitiateNetplay == NULL) { UnloadPlugin(); return false; } + if (SyncInputs == NULL) { UnloadPlugin(); return false; } + + if (m_PluginInfo.Version >= 0x0102) + { + if (PluginOpened == NULL) { UnloadPlugin(); return false; } + } + + return true; +} + +bool CNetplay_Plugin::Initiate(CN64System * System, RenderWindow * Window) +{ + //Get Function from DLL + int32_t(CALL *InitiateNetplay)(NETPLAY_INFO Netplay_Info, NETPLAY_SUPPORT * Netplay_Support); + LoadFunction(InitiateNetplay); + if (InitiateNetplay == NULL) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Failed to find InitiateNetplay"); + return false; + } + + NETPLAY_SUPPORT Support = { 0 }; + NETPLAY_INFO Info = { 0 }; + SetNetplayInfo(&Info); + +#ifdef _WIN32 + Info.hwnd = Window ? Window->GetWindowHandle() : NULL; +#else + Info.hwnd = NULL; +#endif + m_Initialized = InitiateNetplay(Info, &Support) != 0; + SetNetplaySupport(&Support); + m_System = System; + + memset(&m_Buttons, 0, sizeof(m_Buttons)); + memset(&m_Commands, 0, sizeof(m_Commands)); + memset(&m_Controls, 0, sizeof(m_Controls)); + + return m_Initialized; +} + +bool CNetplay_Plugin::OpenNetplay(void* hParent) +{ + //Get Function from DLL + void(CALL *OpenNetplay)(void); + LoadFunction(OpenNetplay); + void(CALL *CloseNetplay)(void); + LoadFunction(CloseNetplay); + + if (OpenNetplay == NULL) { UnloadPlugin(); return false; } + if (CloseNetplay == NULL) { UnloadPlugin(); return false; } + + m_hParent = hParent; + +#ifdef _WIN32 + if (m_hParent != NULL) + { + if (m_hNetplayThread) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Terminate Netplay Thread"); + TerminateThread(m_hNetplayThread, 0); + } + DWORD ThreadID; + m_hNetplayThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NetplayThread, (LPVOID) this, 0, &ThreadID); + } +#endif + + if (m_hNetplayThread == NULL) { return false; } + return true; +} + +bool CNetplay_Plugin::CloseNetplay(void) +{ + //Get Function from DLL + int32_t(CALL *CloseNetplay)(void); + LoadFunction(CloseNetplay); + if (CloseNetplay == NULL) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Failed to find CloseNetplay"); + return false; + } + + bool Opened = CloseNetplay(); + g_Settings->SaveBool(Plugin_NET_Loaded, !Opened); + +#ifdef _WIN32 + if (m_hNetplayThread) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Terminate Netplay Thread"); + TerminateThread(m_hNetplayThread, 0); + m_hNetplayThread = NULL; + } +#endif + + return true; +} + +void CNetplay_Plugin::SetNetplayInfo(NETPLAY_INFO * Netplay_Info) +{ + WriteTrace(TraceNetplayPlugin, TraceDebug, "SetNetplayInfo"); + + LoadRomList(); + int index; + int RomLimit = m_RomInfo.size() > ROM_LIMIT ? ROM_LIMIT : (int) m_RomInfo.size(); + + for (index = 0; index < RomLimit; index++) + Netplay_Info->romInfo[index] = &m_RomInfo[index]; + + Netplay_Info->appName = VER_FILE_VERSION_STR; + Netplay_Info->chatCallback = NetplayChatCallback; + Netplay_Info->cheatCallback = NetplayCheatCallback; + Netplay_Info->eventCallback = NetplayEventCallback; + Netplay_Info->inputCallback = NetplayInputCallback; + Netplay_Info->settingCallback = NetplaySettingCallback; +} + +void CNetplay_Plugin::ForwardCheats(void) +{ + WriteTrace(TraceNetplayPlugin, TraceDebug, "Forwarding Cheat Codes"); + + if (m_CheatsLocked) + { + m_ForwardCheats = true; + return; + } + else + { + m_CheatsLocked = true; + m_ForwardCheats = false; + } + + NETPLAY_CHEAT Netplay_Reset_Cheat = { 0 }; + Netplay_Reset_Cheat.PlayerId = m_PlayerId; + Netplay_Reset_Cheat.Action = Cheat_Action_Reset; + if (SyncCheats) { SyncCheats(&Netplay_Reset_Cheat); } + + for (size_t CurrentCheat = 0; CurrentCheat < m_CodesLocal.size(); CurrentCheat++) + { + const CCheats::CODES & CodeEntry = m_CodesLocal[CurrentCheat]; + for (size_t CurrentEntry = 0; CurrentEntry < CodeEntry.size(); CurrentEntry++) + { + NETPLAY_CHEAT Netplay_Cheat = { 0 }; + Netplay_Cheat.PlayerId = m_PlayerId; + + // cheats with the same index will be appended to the CodeEntry + Netplay_Cheat.Action = Cheat_Action_Load; + Netplay_Cheat.Index = CurrentCheat; + Netplay_Cheat.Command = CodeEntry[CurrentEntry].Command; + Netplay_Cheat.Value = CodeEntry[CurrentEntry].Value; + if (SyncCheats) { SyncCheats(&Netplay_Cheat); } + } + } + + NETPLAY_CHEAT Netplay_Apply_Cheat = { 0 }; + Netplay_Apply_Cheat.PlayerId = m_PlayerId; + Netplay_Apply_Cheat.Action = Cheat_Action_Apply; + if (SyncCheats) { SyncCheats(&Netplay_Apply_Cheat); } + + m_CheatsLocked = false; + if (m_ForwardCheats) { ForwardCheats(); } +} + +void CNetplay_Plugin::ForwardEvents(NETPLAY_EVENT Netplay_Event) +{ + SyncEvents(&Netplay_Event); +} + +void CNetplay_Plugin::ForwardInputs(void) +{ + NETPLAY_INPUT Netplay_Input = { 0 }; + Netplay_Input.PlayerId = m_PlayerId; + + BUTTONS Keys; + uint8_t PifRam[8]; + int32_t Command; + CONTROL * Controllers; + memset(&Keys, 0, sizeof(Keys)); + + if (g_Plugins->Control()->PluginControllers()) + Controllers = g_Plugins->Control()->PluginControllers(); + + for (int Control = 0; Control < CONTROL_LIMIT; Control++) + { + memset(&Keys, 0, sizeof(Keys)); + memset(&PifRam, 0, sizeof(PifRam)); + + if (g_Plugins->Control()->GetKeys) + g_Plugins->Control()->GetKeys(Control, &Keys); + + //TODO: Clean this up + try + { + memset(&PifRam, 0xFF, sizeof(PifRam)); + PifRam[1] = 0x01; PifRam[2] = 0x04; PifRam[3] = 0x01; + + if (Controllers[Control].Present && Controllers[Control].RawData) { + if (g_Plugins->Control()->ReadController) + g_Plugins->Control()->ReadController(Control, &PifRam[1]); + } + + Command = (Command << 8) + PifRam[7]; + Command = (Command << 8) + PifRam[6]; + Command = (Command << 8) + PifRam[5]; + Command = (Command << 8) + PifRam[4]; + } + catch (...) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Unable to read controller data"); + } + + Netplay_Input.Buttons[Control].Value = Keys.Value; + Netplay_Input.Command[Control] = Command; + Netplay_Input.Control[Control] = Controllers[Control]; + } + + if (g_Plugins->Control()->ReadController) + g_Plugins->Control()->ReadController(-1, NULL); + + if (SyncInputs) + SyncInputs(&Netplay_Input); +} + +void CNetplay_Plugin::ProcessInputs(NETPLAY_INPUT Netplay_Inputs) { + for (int Control = 0; Control < CONTROL_LIMIT; Control++) + { + m_Buttons[Control] = Netplay_Inputs.Buttons[Control]; + m_Commands[Control] = Netplay_Inputs.Command[Control]; + m_Controls[Control] = Netplay_Inputs.Control[Control]; + } +} + +void CNetplay_Plugin::ForwardSettings(void) +{ + std::vector Settings_Array; + + Settings_Array.push_back({ Setting_First, Setting_First }); + Settings_Array.push_back({ Setting_PlayerCount, (uint32_t)m_PlayerCount }); + Settings_Array.push_back({ Setting_RDRamSize, g_Settings->LoadDword(Game_RDRamSize) }); + Settings_Array.push_back({ Setting_CounterFactor, g_Settings->LoadDword(Game_CounterFactor) }); + Settings_Array.push_back({ Setting_UseTlb, g_Settings->LoadBool(Game_UseTlb) }); + Settings_Array.push_back({ Setting_DelayDP, g_Settings->LoadBool(Game_DelayDP) }); + Settings_Array.push_back({ Setting_DelaySI, g_Settings->LoadBool(Game_DelaySI) }); + Settings_Array.push_back({ Setting_32Bit, g_Settings->LoadBool(Game_32Bit) }); + Settings_Array.push_back({ Setting_FixedAudio, g_Settings->LoadBool(Game_FixedAudio) }); + Settings_Array.push_back({ Setting_SyncViaAudio, g_Settings->LoadBool(Game_SyncViaAudio) }); + Settings_Array.push_back({ Setting_RspAudioSignal, g_Settings->LoadBool(Game_RspAudioSignal) }); + Settings_Array.push_back({ Setting_ViRefreshRate, g_Settings->LoadDword(Game_ViRefreshRate) }); + Settings_Array.push_back({ Setting_AiCountPerBytes, g_Settings->LoadDword(Game_AiCountPerBytes) }); + Settings_Array.push_back({ Setting_OverClockModifier, g_Settings->LoadDword(Game_OverClockModifier) }); + Settings_Array.push_back({ Setting_FullSpeed, g_Settings->LoadBool(Game_FullSpeed) }); + Settings_Array.push_back({ Setting_Randomizer_Seed, (uint32_t)time(NULL) }); + Settings_Array.push_back({ Setting_Last, Setting_Last }); + + for (size_t CurrentSetting = 0; CurrentSetting < Settings_Array.size(); CurrentSetting++) + { + NETPLAY_SETTING Netplay_Setting = { 0 }; + Netplay_Setting.PlayerId = m_PlayerId; + Netplay_Setting.Setting = Settings_Array[CurrentSetting].Setting; + Netplay_Setting.Value = Settings_Array[CurrentSetting].Value; + if (SyncSettings) { SyncSettings(&Netplay_Setting); } + } +} + +void CNetplay_Plugin::GetKeys(int32_t Control, BUTTONS * Keys) +{ + *Keys = m_Buttons[Control]; +} + +void CNetplay_Plugin::ReadController(int32_t Control, uint8_t * Command) +{ + //TODO: Clean this up + int x = 6; + for (int i = 3; i >= 0; i--) + { + uint8_t byte = (m_Commands[Control] >> 8 * i) & 0xFF; + Command[x] = byte; + x--; + } +} + +void CNetplay_Plugin::InitializeCodes() +{ + m_CheatsLocked = false; + m_ForwardCheats = false; + + m_CodesLocal.clear(); + m_Codes.clear(); + m_CodesFinal.clear(); +} + +void CNetplay_Plugin::LoadCode(CCheats::CODES Code) +{ + m_CodesLocal.push_back(Code); +} + +void CNetplay_Plugin::ResetCodes() +{ + m_CodesLocal.clear(); +} + +void CNetplay_Plugin::ProcessCheats(NETPLAY_CHEAT Netplay_Cheat) { + CCheats::GAMESHARK_CODE CodeEntry; + CCheats::CODES Code; + + switch(Netplay_Cheat.Action) + { + case Cheat_Action_Reset: + { + m_Codes.clear(); + break; + } + + case Cheat_Action_Load: + { + size_t CodesSize = m_Codes.size(); + + CodeEntry.Command = Netplay_Cheat.Command; + CodeEntry.Value = Netplay_Cheat.Value; + + if (CodesSize == 0 || Netplay_Cheat.Index + 1 > CodesSize) + { + Code.push_back(CodeEntry); + m_Codes.push_back(Code); + } + else + { + m_Codes[Netplay_Cheat.Index].push_back(CodeEntry); + } + break; + } + + case Cheat_Action_Confirm: + { + //TODO: Add confirmation that all the cheats have been distributed + break; + } + + case Cheat_Action_Apply: + { + m_CodesFinal.clear(); + m_CodesFinal = m_Codes; + break; + } + + default: + WriteTrace(TraceNetplayPlugin, TraceDebug, "Unknown cheat action: %i", Netplay_Cheat.Action); + break; + } +} + +void CNetplay_Plugin::SetNetplaySupport(NETPLAY_SUPPORT * Netplay_Support) +{ + WriteTrace(TraceNetplayPlugin, TraceDebug, "SetNetplaySupport"); + g_Settings->SaveBool(Plugin_NET_CanPause, Netplay_Support->canPause); + g_Settings->SaveBool(Plugin_NET_CanReset, Netplay_Support->canReset); + g_Settings->SaveBool(Plugin_NET_CanSave, Netplay_Support->canSave); + g_Settings->SaveBool(Plugin_NET_CanSaveState, Netplay_Support->canSaveState); + g_Settings->SaveBool(Plugin_NET_CanCheat, Netplay_Support->canCheat); + g_Settings->SaveBool(Plugin_NET_CanDebug, Netplay_Support->canDebug); +} + +void CNetplay_Plugin::UnloadPluginDetails(void) +{ + SyncCheats = NULL; + SyncEvents = NULL; + SyncInputs = NULL; + SyncSettings = NULL; +} + +#ifdef _WIN32 +void CNetplay_Plugin::NetplayThread(CNetplay_Plugin * _this) +{ + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + + //Get Function from DLL + int32_t(CALL *OpenNetplay)(NETPLAY_INFO Netplay_Info); + _this->LoadFunction(OpenNetplay); + if (OpenNetplay == NULL) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Failed to find OpenNetplay"); + return; + } + + NETPLAY_INFO Info = { 0 }; + _this->SetNetplayInfo(&Info); + Info.hwnd = _this->m_hParent; + + g_Settings->SaveBool(Plugin_NET_Loaded, true); + OpenNetplay(Info); + g_Settings->SaveBool(Plugin_NET_Loaded, false); +} +#endif + +int CALL NetplayChatCallback(NETPLAY_CHAT Netplay_Chat) +{ + WriteTrace(TraceNetplayPlugin, TraceDebug, "<%s>: %s", Netplay_Chat.Name, Netplay_Chat.Message); + g_Notify->DisplayMessage(0, stdstr_f("<%s>: %s", Netplay_Chat.Name, Netplay_Chat.Message).c_str()); + return 0; +} + +int CALL NetplayCheatCallback(NETPLAY_CHEAT Netplay_Cheat) +{ + g_Plugins->Netplay()->ProcessCheats(Netplay_Cheat); + return 0; +} + +int CALL NetplayEventCallback(NETPLAY_EVENT Netplay_Event) +{ + bool AutoStart = g_Settings->LoadBool(Setting_AutoStart); + NETPLAY_SUPPORT Support = { 0 }; + + switch (Netplay_Event.Type) + { + case Event_Type_Load: + g_Plugins->Netplay()->SetPlayerId(Netplay_Event.PlayerId); + g_Plugins->Netplay()->SetPlayerCount(Netplay_Event.EventData); + g_Plugins->Netplay()->SetPlayerRom(Netplay_Event.EventString); + + WriteTrace(TraceNetplayPlugin, TraceDebug, "[Load] Player %i of %i", Netplay_Event.PlayerId + 1, Netplay_Event.EventData); + if (! g_BaseSystem->LoadFileImage(Netplay_Event.EventString)) + return -1; + + g_Plugins->Netplay()->InitializeCodes(); + g_Plugins->Netplay()->ForwardSettings(); + break; + + case Event_Type_Open: + g_Plugins->Netplay()->SetPlayerId(Netplay_Event.PlayerId); + g_Plugins->Netplay()->SetPlayerRom(Netplay_Event.EventString); + + WriteTrace(TraceNetplayPlugin, TraceDebug, "[Open] Player %i of %i", Netplay_Event.PlayerId + 1, g_Plugins->Netplay()->PlayerCount()); + g_Settings->SaveBool(Plugin_NET_Running, true); + g_BaseSystem->RunFileImage(Netplay_Event.EventString, g_Plugins->Netplay()->GetRandomizerSeed(), true); + break; + + case Event_Type_Close: + g_Plugins->Netplay()->SetPlayerId(NULL); + g_Plugins->Netplay()->SetPlayerCount(NULL); + g_Plugins->Netplay()->SetPlayerRom(NULL); + + g_Settings->SaveBool(Plugin_NET_Running, false); + if (g_BaseSystem) + g_BaseSystem->CloseCpu(); + break; + + default: + WriteTrace(TraceNetplayPlugin, TraceDebug, "Unknown event type: %i", Netplay_Event.Type); + break; + } + + return 0; +} + +int CALL NetplayInputCallback(NETPLAY_INPUT Netplay_Input) +{ + g_Plugins->Netplay()->ProcessInputs(Netplay_Input); + return 0; +} + +int CALL NetplaySettingCallback(NETPLAY_SETTING Netplay_Setting) +{ + switch (Netplay_Setting.Setting) + { + case Setting_First: + break; + + case Setting_PlayerCount: g_Plugins->Netplay()->SetPlayerCount(Netplay_Setting.Value); break; + case Setting_RDRamSize: g_Settings->SaveDword(Netplay_RDRamSize, Netplay_Setting.Value); break; + case Setting_CounterFactor: g_Settings->SaveDword(Netplay_CounterFactor, Netplay_Setting.Value); break; + case Setting_UseTlb: g_Settings->SaveBool(Netplay_UseTlb, (bool)Netplay_Setting.Value); break; + case Setting_DelayDP: g_Settings->SaveBool(Netplay_DelayDP, (bool)Netplay_Setting.Value); break; + case Setting_DelaySI: g_Settings->SaveBool(Netplay_DelaySI, (bool)Netplay_Setting.Value); break; + case Setting_32Bit: g_Settings->SaveBool(Netplay_32Bit, (bool)Netplay_Setting.Value); break; + case Setting_FixedAudio: g_Settings->SaveBool(Netplay_FixedAudio, (bool)Netplay_Setting.Value); break; + case Setting_SyncViaAudio: g_Settings->SaveBool(Netplay_SyncViaAudio, (bool)Netplay_Setting.Value); break; + case Setting_RspAudioSignal: g_Settings->SaveBool(Netplay_RspAudioSignal, (bool)Netplay_Setting.Value); break; + case Setting_ViRefreshRate: g_Settings->SaveDword(Netplay_ViRefreshRate, Netplay_Setting.Value); break; + case Setting_AiCountPerBytes: g_Settings->SaveDword(Netplay_AiCountPerBytes, Netplay_Setting.Value); break; + case Setting_OverClockModifier: g_Settings->SaveDword(Netplay_OverClockModifier, Netplay_Setting.Value); break; + case Setting_FullSpeed: g_Settings->SaveBool(Netplay_FullSpeed, (bool)Netplay_Setting.Value); break; + case Setting_Randomizer_Seed: g_Plugins->Netplay()->SetRandomizerSeed(Netplay_Setting.Value); break; + + case Setting_Last: + { + NETPLAY_EVENT Netplay_Event = { 0 }; + Netplay_Event.PlayerId = g_Plugins->Netplay()->PlayerId(); + Netplay_Event.Type = Event_Type_Open; + Netplay_Event.EventData = g_Plugins->Netplay()->PlayerCount(); + Netplay_Event.EventString = g_Plugins->Netplay()->PlayerRom(); + g_Plugins->Netplay()->ForwardEvents(Netplay_Event); + break; + } + + default: + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Unknown setting: %i", Netplay_Setting.Setting); + break; + } + + } + return 0; +} diff --git a/Source/Project64-core/Plugins/NetplayPlugin.h b/Source/Project64-core/Plugins/NetplayPlugin.h new file mode 100644 index 0000000000..649c72f92b --- /dev/null +++ b/Source/Project64-core/Plugins/NetplayPlugin.h @@ -0,0 +1,120 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include +#include +#include +#include +#include +#if defined(ANDROID) +#include +#endif + +#define ROM_LIMIT 2048 + +class CNetplay_Plugin : public CPlugin, public CRomList +{ + typedef struct + { + void * hwnd; + char * appName; + ROM_INFO * romInfo[ROM_LIMIT]; + + int(CALL *chatCallback)(NETPLAY_CHAT Netplay_Chat); + int(CALL *cheatCallback)(NETPLAY_CHEAT Netplay_Cheat); + int(CALL *eventCallback)(NETPLAY_EVENT Netplay_Event); + int(CALL *inputCallback)(NETPLAY_INPUT Netplay_Input); + int(CALL *settingCallback)(NETPLAY_SETTING Netplay_Setting); + } NETPLAY_INFO; +public: + CNetplay_Plugin(void); + ~CNetplay_Plugin(); + + bool Initiate(CN64System * System, RenderWindow * Window); + bool OpenNetplay(void * hParent); + bool CloseNetplay(void); + void SetNetplaySupport(NETPLAY_SUPPORT * Netplay_Support); + + void ForwardCheats(void); + void ForwardEvents(NETPLAY_EVENT Netplay_Event); + void ForwardInputs(void); + void ForwardSettings(void); + + void ProcessCheats(NETPLAY_CHEAT Netplay_Cheats); + void ProcessEvents(NETPLAY_EVENT Netplay_Events); + void ProcessInputs(NETPLAY_INPUT Netplay_Inputs); + void ProcessSettings(NETPLAY_SETTING Netplay_Settings); + + void(CALL *SyncCheats)(NETPLAY_CHEAT * Netplay_Cheats); + void(CALL *SyncEvents)(NETPLAY_EVENT * Netplay_Events); + void(CALL *SyncInputs)(NETPLAY_INPUT * Netplay_Inputs); + void(CALL *SyncSettings)(NETPLAY_SETTING * Netplay_Settings); + + void GetKeys(int32_t Control, BUTTONS * Keys); + inline CONTROL * PluginControllers(void) { return m_Controls; } + void ReadController(int32_t Control, uint8_t * Command); + + void InitializeCodes(); + void LoadCode(CCheats::CODES Code); + void ResetCodes(void); + inline CCheats::CODES_ARRAY GetCodes(void) { return m_CodesFinal; }; + + inline uint32_t GetRandomizerSeed() { return m_RandomizerSeed; } + inline void SetRandomizerSeed(uint32_t seed) { m_RandomizerSeed = seed; } + + inline int32_t PlayerCount(void) { return m_PlayerCount; } + inline void SetPlayerCount(int32_t playerCount) { m_PlayerCount = playerCount; } + inline int32_t PlayerId(void) { return m_PlayerId; } + inline void SetPlayerId(int32_t playerId) { m_PlayerId = playerId; } + inline char * PlayerRom(void) { return m_PlayerRom; } + inline void SetPlayerRom(char * playerRom) { m_PlayerRom = playerRom; } + +private: + CNetplay_Plugin(const CNetplay_Plugin&); // Disable copy constructor + CNetplay_Plugin& operator=(const CNetplay_Plugin&); // Disable assignment + + virtual int32_t GetDefaultSettingStartRange() const { return FirstNetDefaultSet; } + virtual int32_t GetSettingStartRange() const { return FirstNetSettings; } + PLUGIN_TYPE type() { return PLUGIN_TYPE_NETPLAY; } + bool LoadFunctions(void); + void UnloadPluginDetails(void); + + // Function used in a thread for opening netplay UI + static void NetplayThread(CNetplay_Plugin * _this); + + CN64System * m_System; + void * m_hNetplayThread; + void * m_hParent; + int32_t m_PlayerId; + int32_t m_PlayerCount; + char * m_PlayerRom; + + BUTTONS m_Buttons[CONTROL_LIMIT]; + int32_t m_Commands[CONTROL_LIMIT]; + CONTROL m_Controls[CONTROL_LIMIT]; + + bool m_CheatsLocked = false; + bool m_ForwardCheats = false; + CCheats::CODES_ARRAY m_CodesLocal; + CCheats::CODES_ARRAY m_Codes; + CCheats::CODES_ARRAY m_CodesFinal; + + void SetNetplayInfo(NETPLAY_INFO * Netplay_Info); + typedef std::vector SETTINGS_ARRAY; + SETTINGS_ARRAY m_SettingsArray; + uint32_t m_RandomizerSeed = (uint32_t) time(NULL); +}; + +int CALL NetplayChatCallback(NETPLAY_CHAT Netplay_Chat); +int CALL NetplayCheatCallback(NETPLAY_CHEAT Netplay_Cheat); +int CALL NetplayEventCallback(NETPLAY_EVENT Netplay_Event); +int CALL NetplayInputCallback(NETPLAY_INPUT Netplay_Input); +int CALL NetplaySettingCallback(NETPLAY_SETTING Netplay_Setting); diff --git a/Source/Project64-core/Plugins/NetplayTypes.h b/Source/Project64-core/Plugins/NetplayTypes.h new file mode 100644 index 0000000000..f5cc1af781 --- /dev/null +++ b/Source/Project64-core/Plugins/NetplayTypes.h @@ -0,0 +1,108 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once + +#define CONTROL_LIMIT 4 + +enum NETPLAY_ID { + // netplay types + Datatype_Chat, + Datatype_Cheat, + Datatype_Event, + Datatype_Input, + Datatype_Setting, + + // cheat actions + Cheat_Action_Reset, + Cheat_Action_Load, + Cheat_Action_Confirm, + Cheat_Action_Apply, + + // event types + Event_Type_Load, + Event_Type_Open, + Event_Type_Close, + + // settings + Setting_First, + Setting_PlayerCount, + Setting_RDRamSize, + Setting_CounterFactor, + Setting_UseTlb, + Setting_DelayDP, + Setting_DelaySI, + Setting_32Bit, + Setting_FixedAudio, + Setting_SyncViaAudio, + Setting_RspAudioSignal, + Setting_ViRefreshRate, + Setting_AiCountPerBytes, + Setting_OverClockModifier, + Setting_FullSpeed, + Setting_Randomizer_Seed, + Setting_Last, +}; + +typedef struct +{ + int32_t PlayerId; + char * Name; + char * Message; + time_t Timestamp; +} NETPLAY_CHAT; + +typedef struct +{ + int32_t PlayerId; + int8_t Action; + uint16_t Index; + uint32_t Command; + uint16_t Value; +} NETPLAY_CHEAT; + +typedef struct +{ + int32_t PlayerId; + int8_t Type; + int32_t EventData; + char * EventString; +} NETPLAY_EVENT; + +typedef struct +{ + int32_t PlayerId; + CONTROL Control[CONTROL_LIMIT]; + BUTTONS Buttons[CONTROL_LIMIT]; + int32_t Command[CONTROL_LIMIT]; +} NETPLAY_INPUT; + +typedef struct +{ + int32_t PlayerId; + int32_t Setting; + uint32_t Value; +} NETPLAY_SETTING; + +typedef struct +{ + int32_t Setting; + uint32_t Value; +} NETPLAY_SETTING_ITEM; + +typedef struct +{ + bool canPause; + bool canReset; + bool canSave; + bool canSaveState; + bool canCheat; + bool canDebug; +} NETPLAY_SUPPORT; diff --git a/Source/Project64-core/Plugins/PluginBase.cpp b/Source/Project64-core/Plugins/PluginBase.cpp index 78e037f73f..c99efa684b 100644 --- a/Source/Project64-core/Plugins/PluginBase.cpp +++ b/Source/Project64-core/Plugins/PluginBase.cpp @@ -272,6 +272,7 @@ const char * CPlugin::PluginType() const case PLUGIN_TYPE_GFX: return "GFX"; case PLUGIN_TYPE_AUDIO: return "Audio"; case PLUGIN_TYPE_CONTROLLER: return "Control"; + case PLUGIN_TYPE_NETPLAY: return "Netplay"; } return "Unknown"; } @@ -284,6 +285,7 @@ TraceModuleProject64 CPlugin::PluginTraceType() const case PLUGIN_TYPE_GFX: return TraceGFXPlugin; case PLUGIN_TYPE_AUDIO: return TraceAudioPlugin; case PLUGIN_TYPE_CONTROLLER: return TraceControllerPlugin; + case PLUGIN_TYPE_NETPLAY: return TraceNetplayPlugin; } return TracePlugins; } @@ -316,6 +318,10 @@ bool CPlugin::ValidPluginVersion(PLUGIN_INFO & PluginInfo) if (PluginInfo.Version == 0x0101) { return true; } if (PluginInfo.Version == 0x0102) { return true; } break; + case PLUGIN_TYPE_NETPLAY: + if (PluginInfo.Version == 0x0100) { return true; } + if (PluginInfo.Version == 0x0101) { return true; } + break; } return false; } diff --git a/Source/Project64-core/Plugins/PluginClass.cpp b/Source/Project64-core/Plugins/PluginClass.cpp index faefa5b33b..bc39deaef8 100644 --- a/Source/Project64-core/Plugins/PluginClass.cpp +++ b/Source/Project64-core/Plugins/PluginClass.cpp @@ -23,6 +23,7 @@ m_Gfx(NULL), m_Audio(NULL), m_RSP(NULL), m_Control(NULL), +m_Netplay(NULL), m_initilized(false), m_SyncPlugins(SyncPlugins) { @@ -31,12 +32,14 @@ m_SyncPlugins(SyncPlugins) g_Settings->RegisterChangeCB(Plugin_GFX_Current, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Plugin_AUDIO_Current, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Plugin_CONT_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Plugin_NET_Current, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Plugin_UseHleGfx, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Plugin_UseHleAudio, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Game_EditPlugin_Gfx, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Game_EditPlugin_Audio, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Game_EditPlugin_Contr, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(Game_EditPlugin_RSP, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->RegisterChangeCB(Game_EditPlugin_NET, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->RegisterChangeCB(m_PluginDirSetting, this, (CSettings::SettingChangedFunc)PluginChanged); } @@ -46,18 +49,21 @@ CPlugins::~CPlugins(void) g_Settings->UnregisterChangeCB(Plugin_GFX_Current, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Plugin_AUDIO_Current, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Plugin_CONT_Current, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Plugin_NET_Current, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Plugin_UseHleGfx, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Plugin_UseHleAudio, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Game_EditPlugin_Gfx, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Game_EditPlugin_Audio, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Game_EditPlugin_Contr, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(Game_EditPlugin_RSP, this, (CSettings::SettingChangedFunc)PluginChanged); + g_Settings->UnregisterChangeCB(Game_EditPlugin_NET, this, (CSettings::SettingChangedFunc)PluginChanged); g_Settings->UnregisterChangeCB(m_PluginDirSetting, this, (CSettings::SettingChangedFunc)PluginChanged); DestroyGfxPlugin(); DestroyAudioPlugin(); DestroyRspPlugin(); DestroyControlPlugin(); + DestroyNetplayPlugin(); } void CPlugins::PluginChanged(CPlugins * _this) @@ -73,11 +79,13 @@ void CPlugins::PluginChanged(CPlugins * _this) bool bAudioChange = _stricmp(_this->m_AudioFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()) != 0; bool bRspChange = _stricmp(_this->m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()) != 0; bool bContChange = _stricmp(_this->m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()) != 0; + bool bNetChange = _stricmp(_this->m_NetplayFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Netplay).c_str()) != 0; bool bDirChange = _stricmp(_this->m_PluginDir.c_str(), g_Settings->LoadStringVal(_this->m_PluginDirSetting).c_str()) != 0; WriteTrace(TracePlugins, TraceVerbose, "m_GfxFile: \"%s\" Game_Plugin_Gfx: \"%s\" changed: %s", _this->m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str(), bGfxChange ? "true" : "false"); - WriteTrace(TracePlugins, TraceVerbose, "m_AudioFile: \"%s\" Game_Plugin_Audio: \"%s\" changed: %s", _this->m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str(), bAudioChange ? "true" : "false"); - WriteTrace(TracePlugins, TraceVerbose, "m_RSPFile: \"%s\" Game_Plugin_RSP: \"%s\" changed: %s", _this->m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str(), bRspChange ? "true" : "false"); - WriteTrace(TracePlugins, TraceVerbose, "m_ControlFile: \"%s\" Game_Plugin_Controller: \"%s\" changed: %s", _this->m_GfxFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Gfx).c_str(), bContChange ? "true" : "false"); + WriteTrace(TracePlugins, TraceVerbose, "m_AudioFile: \"%s\" Game_Plugin_Audio: \"%s\" changed: %s", _this->m_AudioFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str(), bAudioChange ? "true" : "false"); + WriteTrace(TracePlugins, TraceVerbose, "m_RSPFile: \"%s\" Game_Plugin_RSP: \"%s\" changed: %s", _this->m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str(), bRspChange ? "true" : "false"); + WriteTrace(TracePlugins, TraceVerbose, "m_ControlFile: \"%s\" Game_Plugin_Controller: \"%s\" changed: %s", _this->m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str(), bContChange ? "true" : "false"); + WriteTrace(TracePlugins, TraceVerbose, "m_NetplayFile: \"%s\" Game_Plugin_Netplay: \"%s\" changed: %s", _this->m_NetplayFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Netplay).c_str(), bNetChange ? "true" : "false"); WriteTrace(TracePlugins, TraceVerbose, "m_PluginDir: \"%s\" m_PluginDirSetting: \"%s\" changed: %s", _this->m_PluginDir.c_str(), g_Settings->LoadStringVal(_this->m_PluginDirSetting).c_str(), bDirChange ? "true" : "false"); if (bDirChange) { @@ -86,15 +94,19 @@ void CPlugins::PluginChanged(CPlugins * _this) bAudioChange = true; bRspChange = true; bContChange = true; + bNetChange = true; _this->m_PluginDir = g_Settings->LoadStringVal(_this->m_PluginDirSetting); } - if (bGfxChange || bAudioChange || bRspChange || bContChange) + if (bGfxChange || bAudioChange || bRspChange || bContChange || bNetChange) { - if (bGfxChange) { WriteTrace(TracePlugins, TraceDebug, "Gfx plugin changed"); } + if (bGfxChange) { + WriteTrace(TracePlugins, TraceDebug, "Gfx plugin changed"); + } if (bAudioChange) { WriteTrace(TracePlugins, TraceDebug, "Audio plugin changed"); } if (bRspChange) { WriteTrace(TracePlugins, TraceDebug, "RSP plugin changed"); } if (bContChange) { WriteTrace(TracePlugins, TraceDebug, "Controller plugin changed"); } + if (bNetChange) { WriteTrace(TracePlugins, TraceDebug, "Netplay plugin changed"); } if (g_Settings->LoadBool(GameRunning_CPU_Running)) { //Ensure that base system actually exists before we go triggering the event @@ -156,6 +168,11 @@ void CPlugins::CreatePlugins(void) LoadPlugin(Game_Plugin_RSP, Plugin_RSP_CurVer, m_RSP, m_PluginDir.c_str(), m_RSPFile, TraceRSPPlugin, "RSP", m_SyncPlugins); LoadPlugin(Game_Plugin_Controller, Plugin_CONT_CurVer, m_Control, m_PluginDir.c_str(), m_ControlFile, TraceControllerPlugin, "Control", m_SyncPlugins); + if (g_Settings->LoadStringVal(Game_Plugin_Netplay) != "") + { + LoadPlugin(Game_Plugin_Netplay, Plugin_NET_CurVer, m_Netplay, m_PluginDir.c_str(), m_NetplayFile, TraceNetplayPlugin, "Netplay", m_SyncPlugins); + } + //Enable debugger if (m_RSP != NULL && m_RSP->EnableDebugging) { @@ -184,6 +201,10 @@ void CPlugins::GameReset(void) { m_Control->GameReset(m_MainWindow); } + if (m_Netplay) + { + m_Netplay->GameReset(m_MainWindow); + } } void CPlugins::DestroyGfxPlugin(void) @@ -251,6 +272,21 @@ void CPlugins::DestroyControlPlugin(void) // g_Settings->UnknownSetting_CTRL = NULL; } +void CPlugins::DestroyNetplayPlugin(void) +{ + if (m_Netplay == NULL) + { + return; + } + WriteTrace(TraceNetplayPlugin, TraceDebug, "before close"); + m_Netplay->Close(m_MainWindow); + WriteTrace(TraceNetplayPlugin, TraceDebug, "before delete"); + delete m_Netplay; + m_Netplay = NULL; + WriteTrace(TraceNetplayPlugin, TraceDebug, "after delete"); + // g_Settings->UnknownSetting_CTRL = NULL; +} + void CPlugins::SetRenderWindows(RenderWindow * MainWindow, RenderWindow * SyncWindow) { WriteTrace(TracePlugins, TraceDebug, "MainWindow = %p SyncWindow = %p", MainWindow, SyncWindow); @@ -266,6 +302,7 @@ void CPlugins::RomOpened(void) m_RSP->RomOpened(m_MainWindow); m_Audio->RomOpened(m_MainWindow); m_Control->RomOpened(m_MainWindow); + if (m_Netplay != NULL) { m_Netplay->RomOpened(m_MainWindow); } WriteTrace(TracePlugins, TraceDebug, "Done"); } @@ -278,6 +315,7 @@ void CPlugins::RomClosed(void) m_RSP->RomClose(m_MainWindow); m_Audio->RomClose(m_MainWindow); m_Control->RomClose(m_MainWindow); + if (m_Netplay != NULL) { m_Netplay->RomClose(m_MainWindow); } WriteTrace(TracePlugins, TraceDebug, "Done"); } @@ -290,6 +328,7 @@ bool CPlugins::Initiate(CN64System * System) if (m_Audio == NULL) { return false; } if (m_RSP == NULL) { return false; } if (m_Control == NULL) { return false; } + //if (m_Netplay == NULL) { return false; } WriteTrace(TraceGFXPlugin, TraceDebug, "Gfx Initiate Starting"); if (!m_Gfx->Initiate(System, m_MainWindow)) { return false; } @@ -303,6 +342,13 @@ bool CPlugins::Initiate(CN64System * System) WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Starting"); if (!m_RSP->Initiate(this, System)) { return false; } WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Done"); + if (m_Netplay != NULL) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Netplay Initiate Starting"); + if (!m_Netplay->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceNetplayPlugin, TraceDebug, "Netplay Initiate Done"); + } + WriteTrace(TracePlugins, TraceDebug, "Done"); m_initilized = true; return true; @@ -325,6 +371,7 @@ bool CPlugins::Reset(CN64System * System) bool bAudioChange = _stricmp(m_AudioFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Audio).c_str()) != 0; bool bRspChange = _stricmp(m_RSPFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_RSP).c_str()) != 0; bool bContChange = _stricmp(m_ControlFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Controller).c_str()) != 0; + bool bNetChange = _stricmp(m_NetplayFile.c_str(), g_Settings->LoadStringVal(Game_Plugin_Netplay).c_str()) != 0; //if GFX and Audio has changed we also need to force reset of RSP if (bGfxChange || bAudioChange) @@ -336,6 +383,7 @@ bool CPlugins::Reset(CN64System * System) if (bAudioChange) { DestroyAudioPlugin(); } if (bRspChange) { DestroyRspPlugin(); } if (bContChange) { DestroyControlPlugin(); } + if (bNetChange) { DestroyNetplayPlugin(); } CreatePlugins(); @@ -363,6 +411,14 @@ bool CPlugins::Reset(CN64System * System) if (!m_RSP->Initiate(this, System)) { return false; } WriteTrace(TraceRSPPlugin, TraceDebug, "RSP Initiate Done"); } + + if (m_Netplay && bNetChange) + { + WriteTrace(TraceNetplayPlugin, TraceDebug, "Netplay Initiate Starting"); + if (!m_Netplay->Initiate(System, m_MainWindow)) { return false; } + WriteTrace(TraceNetplayPlugin, TraceDebug, "Netplay Initiate Done"); + } + WriteTrace(TracePlugins, TraceDebug, "Done"); return true; } @@ -420,6 +476,17 @@ void CPlugins::ConfigPlugin(void* hParent, PLUGIN_TYPE Type) } m_Control->DllConfig(hParent); break; + case PLUGIN_TYPE_NETPLAY: + if (m_Netplay == NULL || m_Netplay->DllConfig == NULL) { break; } + if (!m_Netplay->Initialized()) + { + if (!m_Netplay->Initiate(NULL, m_MainWindow)) + { + break; + } + } + m_Netplay->DllConfig(hParent); + break; case PLUGIN_TYPE_NONE: default: g_Notify->BreakPoint(__FILE__, __LINE__); @@ -493,5 +560,22 @@ bool CPlugins::CopyPlugins(const stdstr & DstDir) const { return false; } + + //Copy Netplay Plugin + if (g_Settings->LoadStringVal(Game_Plugin_Netplay) != "") + { + CPath srcNetPlugin(m_PluginDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Netplay).c_str()); + CPath dstNetPlugin(DstDir.c_str(), g_Settings->LoadStringVal(Game_Plugin_Netplay).c_str()); + dstNetPlugin.SetName(stdstr_f("%s-copy", dstNetPlugin.GetName().c_str()).c_str()); + if (!dstNetPlugin.DirectoryExists()) + { + dstNetPlugin.DirectoryCreate(); + } + if (!srcNetPlugin.CopyTo(dstNetPlugin)) + { + return false; + } + } + return true; } \ No newline at end of file diff --git a/Source/Project64-core/Plugins/PluginClass.h b/Source/Project64-core/Plugins/PluginClass.h index 34d3b2775e..4824cb6353 100644 --- a/Source/Project64-core/Plugins/PluginClass.h +++ b/Source/Project64-core/Plugins/PluginClass.h @@ -96,10 +96,11 @@ enum PLUGIN_TYPE PLUGIN_TYPE_GFX = 2, PLUGIN_TYPE_AUDIO = 3, PLUGIN_TYPE_CONTROLLER = 4, + PLUGIN_TYPE_NETPLAY = 5, }; class CSettings; -class CGfxPlugin; class CAudioPlugin; class CRSP_Plugin; class CControl_Plugin; +class CGfxPlugin; class CAudioPlugin; class CRSP_Plugin; class CControl_Plugin; class CNetplay_Plugin; class CN64System; class CPlugins; @@ -146,6 +147,7 @@ class CPlugins : inline CAudioPlugin * Audio(void) const { return m_Audio; } inline CRSP_Plugin * RSP(void) const { return m_RSP; } inline CControl_Plugin * Control(void) const { return m_Control; } + inline CNetplay_Plugin * Netplay(void) const { return m_Netplay; } inline RenderWindow * MainWindow(void) const { return m_MainWindow; } inline RenderWindow * SyncWindow(void) const { return m_SyncWindow; } @@ -161,6 +163,7 @@ class CPlugins : void DestroyAudioPlugin(void); void DestroyRspPlugin(void); void DestroyControlPlugin(void); + void DestroyNetplayPlugin(void); static void PluginChanged(CPlugins * _this); @@ -175,11 +178,13 @@ class CPlugins : CAudioPlugin * m_Audio; CRSP_Plugin * m_RSP; CControl_Plugin * m_Control; + CNetplay_Plugin * m_Netplay; stdstr m_GfxFile; stdstr m_AudioFile; stdstr m_RSPFile; stdstr m_ControlFile; + stdstr m_NetplayFile; bool m_initilized; bool m_SyncPlugins; }; diff --git a/Source/Project64-core/Project64-core.vcxproj b/Source/Project64-core/Project64-core.vcxproj index d6c3e9fdc0..897f29be14 100644 --- a/Source/Project64-core/Project64-core.vcxproj +++ b/Source/Project64-core/Project64-core.vcxproj @@ -1,4 +1,4 @@ - + @@ -92,6 +92,7 @@ + @@ -196,6 +197,8 @@ + + diff --git a/Source/Project64-core/Project64-core.vcxproj.filters b/Source/Project64-core/Project64-core.vcxproj.filters index 64b467f2db..3343968df8 100644 --- a/Source/Project64-core/Project64-core.vcxproj.filters +++ b/Source/Project64-core/Project64-core.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -339,6 +339,9 @@ Source Files\N64 System\Recompiler\Arm + + Source Files\Plugins + @@ -656,6 +659,12 @@ Header Files + + Header Files\Plugins + + + Header Files\Plugins + diff --git a/Source/Project64-core/Settings/GameSettings.cpp b/Source/Project64-core/Settings/GameSettings.cpp index cddb68ab22..de1c980774 100644 --- a/Source/Project64-core/Settings/GameSettings.cpp +++ b/Source/Project64-core/Settings/GameSettings.cpp @@ -43,42 +43,81 @@ uint32_t CGameSettings::m_OverClockModifier = 1; void CGameSettings::RefreshGameSettings() { WriteTrace(TraceN64System, TraceDebug, "start"); - m_UseHleGfx = g_Settings->LoadBool(Game_UseHleGfx); - m_bSMM_StoreInstruc = false /*g_Settings->LoadBool(Game_SMM_StoreInstruc)*/; - m_bSMM_Protect = g_Settings->LoadBool(Game_SMM_Protect); - m_bSMM_ValidFunc = g_Settings->LoadBool(Game_SMM_ValidFunc); - m_bSMM_PIDMA = g_Settings->LoadBool(Game_SMM_PIDMA); - m_bSMM_TLB = g_Settings->LoadBool(Game_SMM_TLB); - m_bUseTlb = g_Settings->LoadBool(Game_UseTlb); - m_ViRefreshRate = g_Settings->LoadDword(Game_ViRefreshRate); - m_AiCountPerBytes = g_Settings->LoadDword(Game_AiCountPerBytes); - m_CountPerOp = g_Settings->LoadDword(Game_CounterFactor); - m_RdramSize = g_Settings->LoadDword(Game_RDRamSize); - m_DelaySI = g_Settings->LoadBool(Game_DelaySI); - m_DelayDP = g_Settings->LoadBool(Game_DelayDP); - m_bFixedAudio = g_Settings->LoadBool(Game_FixedAudio); - m_bSyncToAudio = g_Settings->LoadBool(Game_SyncViaAudio); - m_FullSpeed = g_Settings->LoadBool(Game_FullSpeed); - m_b32Bit = g_Settings->LoadBool(Game_32Bit); + + if (g_Settings->LoadBool(Plugin_NET_Running)) + { + m_UseHleGfx = g_Settings->LoadBool(Netplay_UseHleGfx); + m_bSMM_StoreInstruc = false /*g_Settings->LoadBool(Netplay_SMM_StoreInstruc)*/; + m_bSMM_Protect = g_Settings->LoadBool(Netplay_SMM_Protect); + m_bSMM_ValidFunc = g_Settings->LoadBool(Netplay_SMM_ValidFunc); + m_bSMM_PIDMA = g_Settings->LoadBool(Netplay_SMM_PIDMA); + m_bSMM_TLB = g_Settings->LoadBool(Netplay_SMM_TLB); + m_bUseTlb = g_Settings->LoadBool(Netplay_UseTlb); + m_ViRefreshRate = g_Settings->LoadDword(Netplay_ViRefreshRate); + m_AiCountPerBytes = g_Settings->LoadDword(Netplay_AiCountPerBytes); + m_CountPerOp = g_Settings->LoadDword(Netplay_CounterFactor); + m_RdramSize = g_Settings->LoadDword(Netplay_RDRamSize); + m_DelaySI = g_Settings->LoadBool(Netplay_DelaySI); + m_DelayDP = g_Settings->LoadBool(Netplay_DelayDP); + m_bFixedAudio = true /*g_Settings->LoadBool(Netplay_FixedAudio)*/; + m_bSyncToAudio = g_Settings->LoadBool(Netplay_SyncViaAudio); + m_FullSpeed = g_Settings->LoadBool(Netplay_FullSpeed); + m_b32Bit = g_Settings->LoadBool(Netplay_32Bit); +#ifdef ANDROID + m_bFastSP = false; +#else + m_bFastSP = g_Settings->LoadBool(Netplay_FastSP); +#endif + m_RspAudioSignal = g_Settings->LoadBool(Netplay_RspAudioSignal); + m_bRomInMemory = g_Settings->LoadBool(Netplay_LoadRomToMemory); + m_RegCaching = g_Settings->LoadBool(Netplay_RegCache); + m_bLinkBlocks = g_Settings->LoadBool(Netplay_BlockLinking); + m_LookUpMode = g_Settings->LoadDword(Netplay_FuncLookupMode); + m_SystemType = (SYSTEM_TYPE)g_Settings->LoadDword(Netplay_SystemType); + m_CpuType = (CPU_TYPE)g_Settings->LoadDword(Netplay_CpuType); + m_OverClockModifier = g_Settings->LoadDword(Netplay_OverClockModifier); + } + else + { + m_UseHleGfx = g_Settings->LoadBool(Game_UseHleGfx); + m_bSMM_StoreInstruc = false /*g_Settings->LoadBool(Game_SMM_StoreInstruc)*/; + m_bSMM_Protect = g_Settings->LoadBool(Game_SMM_Protect); + m_bSMM_ValidFunc = g_Settings->LoadBool(Game_SMM_ValidFunc); + m_bSMM_PIDMA = g_Settings->LoadBool(Game_SMM_PIDMA); + m_bSMM_TLB = g_Settings->LoadBool(Game_SMM_TLB); + m_bUseTlb = g_Settings->LoadBool(Game_UseTlb); + m_ViRefreshRate = g_Settings->LoadDword(Game_ViRefreshRate); + m_AiCountPerBytes = g_Settings->LoadDword(Game_AiCountPerBytes); + m_CountPerOp = g_Settings->LoadDword(Game_CounterFactor); + m_RdramSize = g_Settings->LoadDword(Game_RDRamSize); + m_DelaySI = g_Settings->LoadBool(Game_DelaySI); + m_DelayDP = g_Settings->LoadBool(Game_DelayDP); + m_bFixedAudio = g_Settings->LoadBool(Game_FixedAudio); + m_bSyncToAudio = g_Settings->LoadBool(Game_SyncViaAudio); + m_FullSpeed = g_Settings->LoadBool(Game_FullSpeed); + m_b32Bit = g_Settings->LoadBool(Game_32Bit); #ifdef ANDROID - m_bFastSP = false; + m_bFastSP = false; #else - m_bFastSP = g_Settings->LoadBool(Game_FastSP); + m_bFastSP = g_Settings->LoadBool(Game_FastSP); #endif - m_RspAudioSignal = g_Settings->LoadBool(Game_RspAudioSignal); - m_bRomInMemory = g_Settings->LoadBool(Game_LoadRomToMemory); - m_RegCaching = g_Settings->LoadBool(Game_RegCache); - m_bLinkBlocks = g_Settings->LoadBool(Game_BlockLinking); - m_LookUpMode = g_Settings->LoadDword(Game_FuncLookupMode); - m_SystemType = (SYSTEM_TYPE)g_Settings->LoadDword(Game_SystemType); - m_CpuType = (CPU_TYPE)g_Settings->LoadDword(Game_CpuType); - m_OverClockModifier = g_Settings->LoadDword(Game_OverClockModifier); + m_RspAudioSignal = g_Settings->LoadBool(Game_RspAudioSignal); + m_bRomInMemory = g_Settings->LoadBool(Game_LoadRomToMemory); + m_RegCaching = g_Settings->LoadBool(Game_RegCache); + m_bLinkBlocks = g_Settings->LoadBool(Game_BlockLinking); + m_LookUpMode = g_Settings->LoadDword(Game_FuncLookupMode); + m_SystemType = (SYSTEM_TYPE)g_Settings->LoadDword(Game_SystemType); + m_CpuType = (CPU_TYPE)g_Settings->LoadDword(Game_CpuType); + m_OverClockModifier = g_Settings->LoadDword(Game_OverClockModifier); + } + if (m_CountPerOp == 0) { m_CountPerOp = 2; } if (m_OverClockModifier < 1) { m_OverClockModifier = 1; } if (m_OverClockModifier > 20) { m_OverClockModifier = 20; } + WriteTrace(TraceN64System, TraceDebug, "Done"); } diff --git a/Source/Project64-core/Settings/Settings.h b/Source/Project64-core/Settings/Settings.h index dfb1bcdde9..866a77d241 100644 --- a/Source/Project64-core/Settings/Settings.h +++ b/Source/Project64-core/Settings/Settings.h @@ -112,10 +112,12 @@ enum SettingID Game_EditPlugin_Audio, Game_EditPlugin_Contr, Game_EditPlugin_RSP, + Game_EditPlugin_NET, Game_Plugin_Gfx, Game_Plugin_Audio, Game_Plugin_Controller, Game_Plugin_RSP, + Game_Plugin_Netplay, Game_SaveChip, Game_CpuType, Game_LastSaveSlot, @@ -155,6 +157,47 @@ enum SettingID Game_OverClockModifier, Game_FullSpeed, + //Netplay Settings + Netplay_GoodName, + Netplay_SystemType, + Netplay_SaveChip, + Netplay_CpuType, + Netplay_RDRamSize, + Netplay_CounterFactor, + Netplay_UseTlb, + Netplay_DelayDP, + Netplay_DelaySI, + Netplay_32Bit, + Netplay_FastSP, + Netplay_FixedAudio, + Netplay_SyncViaAudio, + Netplay_RspAudioSignal, + Netplay_TLB_VAddrStart, + Netplay_TLB_VAddrLen, + Netplay_TLB_PAddrStart, + Netplay_UseHleGfx, + Netplay_UseHleAudio, + Netplay_LoadRomToMemory, + Netplay_ScreenHertz, + Netplay_FuncLookupMode, + Netplay_RegCache, + Netplay_BlockLinking, + Netplay_SMM_StoreInstruc, + Netplay_SMM_Cache, + Netplay_SMM_PIDMA, + Netplay_SMM_TLB, + Netplay_SMM_Protect, + Netplay_SMM_ValidFunc, + Netplay_GameCheatFix, + Netplay_GameCheatFixPlugin, + Netplay_ViRefreshRate, + Netplay_AiCountPerBytes, + Netplay_AudioResetOnLoad, + Netplay_AllowROMWrites, + Netplay_CRC_Recalc, + Netplay_OverClockModifier, + Netplay_FullSpeed, + // General Game running info GameRunning_LoadingInProgress, GameRunning_CPU_Running, @@ -250,8 +293,10 @@ enum SettingID Debugger_TraceAudioPlugin, Debugger_TraceControllerPlugin, Debugger_TraceRSPPlugin, + Debugger_TraceNetplayPlugin, Debugger_TraceRSP, Debugger_TraceAudio, + Debugger_TraceNetplay, Debugger_TraceRegisterCache, Debugger_TraceRecompiler, Debugger_TraceTLB, @@ -269,6 +314,17 @@ enum SettingID Plugin_AUDIO_CurVer, Plugin_CONT_Current, Plugin_CONT_CurVer, + Plugin_NET_Current, + Plugin_NET_CurVer, + Plugin_NET_Open, + Plugin_NET_Loaded, + Plugin_NET_Running, + Plugin_NET_CanPause, + Plugin_NET_CanReset, + Plugin_NET_CanSave, + Plugin_NET_CanSaveState, + Plugin_NET_CanCheat, + Plugin_NET_CanDebug, Plugin_UseHleGfx, Plugin_UseHleAudio, Plugin_EnableAudio, @@ -317,4 +373,6 @@ enum SettingID FirstAudioSettings, LastAudioSettings = FirstAudioSettings + MaxPluginSetting, FirstCtrlDefaultSet, LastCtrlDefaultSet = FirstCtrlDefaultSet + MaxPluginSetting, FirstCtrlSettings, LastCtrlSettings = FirstCtrlSettings + MaxPluginSetting, + FirstNetDefaultSet, LastNetDefaultSet = FirstNetDefaultSet + MaxPluginSetting, + FirstNetSettings, LastNetSettings = FirstNetSettings + MaxPluginSetting, }; diff --git a/Source/Project64-core/Settings/SettingsClass.cpp b/Source/Project64-core/Settings/SettingsClass.cpp index d9c184fd73..b45284474a 100644 --- a/Source/Project64-core/Settings/SettingsClass.cpp +++ b/Source/Project64-core/Settings/SettingsClass.cpp @@ -181,10 +181,12 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Game_EditPlugin_Audio, new CSettingTypeGame("Plugin-Audio", Default_None)); AddHandler(Game_EditPlugin_Contr, new CSettingTypeGame("Plugin-Controller", Default_None)); AddHandler(Game_EditPlugin_RSP, new CSettingTypeGame("Plugin-RSP", Default_None)); + AddHandler(Game_EditPlugin_NET, new CSettingTypeGame("Plugin-NET", Default_None)); 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_Plugin_Netplay, new CSettingTypeGame("Plugin-NET", Plugin_NET_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", (uint32_t)0)); @@ -228,6 +230,40 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Game_OverClockModifier, new CSettingTypeGame("OverClockModifier", Rdb_OverClockModifier)); AddHandler(Game_FullSpeed, new CSettingTypeTempBool(true, "Full Speed")); + AddHandler(Netplay_SystemType, new CSettingTypeTempNumber(SYSTEM_NTSC)); + AddHandler(Netplay_SaveChip, new CSettingTypeApplication("Netplay", "SaveChip", Game_SaveChip)); + AddHandler(Netplay_CpuType, new CSettingTypeApplication("Netplay", "CpuType", Game_CpuType)); + AddHandler(Netplay_FixedAudio, new CSettingTypeApplication("Netplay", "Fixed Audio", Game_FixedAudio)); + AddHandler(Netplay_RDRamSize, new CSettingTypeApplication("Netplay", "RDRamSize", Game_RDRamSize)); + AddHandler(Netplay_CounterFactor, new CSettingTypeApplication("Netplay", "Counter Factor", Game_CounterFactor)); + AddHandler(Netplay_UseTlb, new CSettingTypeApplication("Netplay", "Use TLB", Game_UseTlb)); + AddHandler(Netplay_DelayDP, new CSettingTypeApplication("Netplay", "Delay DP", Game_DelayDP)); + AddHandler(Netplay_DelaySI, new CSettingTypeApplication("Netplay", "Delay SI", Game_DelaySI)); + AddHandler(Netplay_RspAudioSignal, new CSettingTypeApplication("Netplay", "Audio Signal", Game_RspAudioSignal)); + AddHandler(Netplay_32Bit, new CSettingTypeApplication("Netplay", "32bit", Game_32Bit)); + AddHandler(Netplay_FastSP, new CSettingTypeApplication("Netplay", "Fast SP", Game_FastSP)); + AddHandler(Netplay_SyncViaAudio, new CSettingTypeApplication("Netplay", "Sync Audio", Game_SyncViaAudio)); + AddHandler(Netplay_UseHleGfx, new CSettingTypeApplication("Netplay", "HLE GFX", Game_UseHleGfx)); + AddHandler(Netplay_UseHleAudio, new CSettingTypeApplication("Netplay", "HLE Audio", Game_UseHleAudio)); + AddHandler(Netplay_LoadRomToMemory, new CSettingTypeApplication("Netplay", "Rom In Memory", Game_LoadRomToMemory)); + AddHandler(Netplay_ScreenHertz, new CSettingTypeApplication("Netplay", "ScreenHertz", Game_ScreenHertz)); + AddHandler(Netplay_FuncLookupMode, new CSettingTypeApplication("Netplay", "FuncFind", Game_FuncLookupMode)); + AddHandler(Netplay_RegCache, new CSettingTypeApplication("Netplay", "Reg Cache", Game_RegCache)); + AddHandler(Netplay_BlockLinking, new CSettingTypeApplication("Netplay", "Linking", Game_BlockLinking)); + AddHandler(Netplay_SMM_StoreInstruc, new CSettingTypeApplication("Netplay", "SMM-StoreInst", Game_SMM_StoreInstruc)); + AddHandler(Netplay_SMM_Cache, new CSettingTypeApplication("Netplay", "SMM-Cache", Game_SMM_Cache)); + AddHandler(Netplay_SMM_PIDMA, new CSettingTypeApplication("Netplay", "SMM-PI DMA", Game_SMM_PIDMA)); + AddHandler(Netplay_SMM_TLB, new CSettingTypeApplication("Netplay", "SMM-TLB", Game_SMM_TLB)); + AddHandler(Netplay_SMM_Protect, new CSettingTypeApplication("Netplay", "SMM-Protect", Game_SMM_Protect)); + AddHandler(Netplay_SMM_ValidFunc, new CSettingTypeApplication("Netplay", "SMM-FUNC", Game_SMM_ValidFunc)); + AddHandler(Netplay_ViRefreshRate, new CSettingTypeApplication("Netplay", "ViRefresh", Game_ViRefreshRate)); + AddHandler(Netplay_AiCountPerBytes, new CSettingTypeApplication("Netplay", "AiCountPerBytes", Game_AiCountPerBytes)); + AddHandler(Netplay_AudioResetOnLoad, new CSettingTypeApplication("Netplay", "AudioResetOnLoad", Game_AudioResetOnLoad)); + AddHandler(Netplay_AllowROMWrites, new CSettingTypeApplication("Netplay", "AllowROMWrites", Game_AllowROMWrites)); + AddHandler(Netplay_CRC_Recalc, new CSettingTypeApplication("Netplay", "CRC-Recalc", Game_CRC_Recalc)); + AddHandler(Netplay_OverClockModifier, new CSettingTypeApplication("Netplay", "OverClockModifier", Game_OverClockModifier)); + AddHandler(Netplay_FullSpeed, new CSettingTypeTempBool(true, "Netplay Full Speed")); + //User Interface AddHandler(UserInterface_ShowCPUPer, new CSettingTypeApplication("", "Display CPU Usage", (uint32_t)false)); #ifdef ANDROID @@ -303,6 +339,15 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(GameRunning_ScreenHertz, new CSettingTypeTempNumber(60)); AddHandler(GameRunning_InReset, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_Loaded, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_Running, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_CanPause, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_CanReset, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_CanSave, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_CanSaveState, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_CanCheat, new CSettingTypeTempBool(false)); + AddHandler(Plugin_NET_CanDebug, new CSettingTypeTempBool(false)); + AddHandler(UserInterface_BasicMode, new CSettingTypeApplication("", "Basic Mode", (uint32_t)true)); AddHandler(File_DiskIPLPath, new CSettingTypeApplicationPath("", "Disk IPL ROM Path", Default_None)); @@ -339,6 +384,8 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Debugger_TraceAudioPlugin, new CSettingTypeApplication("Logging", "Audio Plugin", (uint32_t)g_ModuleLogLevel[TraceAudioPlugin])); AddHandler(Debugger_TraceControllerPlugin, new CSettingTypeApplication("Logging", "Controller Plugin", (uint32_t)g_ModuleLogLevel[TraceControllerPlugin])); AddHandler(Debugger_TraceRSPPlugin, new CSettingTypeApplication("Logging", "RSP Plugin", (uint32_t)g_ModuleLogLevel[TraceRSPPlugin])); + AddHandler(Debugger_TraceNetplayPlugin, new CSettingTypeApplication("Logging", "Netplay Plugin", (uint32_t)g_ModuleLogLevel[TraceNetplayPlugin])); + AddHandler(Debugger_TraceNetplay, new CSettingTypeApplication("Logging", "Netplay", (uint32_t)g_ModuleLogLevel[TraceNetplay])); AddHandler(Debugger_TraceRSP, new CSettingTypeApplication("Logging", "RSP", (uint32_t)g_ModuleLogLevel[TraceRSP])); AddHandler(Debugger_TraceAudio, new CSettingTypeApplication("Logging", "Audio", (uint32_t)g_ModuleLogLevel[TraceAudio])); AddHandler(Debugger_TraceRegisterCache, new CSettingTypeApplication("Logging", "Register Cache", (uint32_t)g_ModuleLogLevel[TraceRegisterCache])); @@ -359,16 +406,19 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Plugin_AUDIO_Current, new CSettingTypeApplication("Plugin", "Audio Dll", "Audio\\Project64-Audio.dll")); #endif AddHandler(Plugin_CONT_Current, new CSettingTypeApplication("Plugin", "Controller Dll", "Input\\PJ64_NRage.dll")); + AddHandler(Plugin_NET_Current, new CSettingTypeApplication("Plugin", "Netplay Dll", "")); #else AddHandler(Plugin_RSP_Current, new CSettingTypeApplication("Plugin", "RSP Dll", "libProject64-rsp-hle.so")); AddHandler(Plugin_GFX_Current, new CSettingTypeApplication("Plugin", "Graphics Dll", "libProject64-gfx.so")); AddHandler(Plugin_AUDIO_Current, new CSettingTypeApplication("Plugin", "Audio Dll", "libProject64-audio-android.so")); AddHandler(Plugin_CONT_Current, new CSettingTypeApplication("Plugin", "Controller Dll", "libProject64-input-android.so")); + AddHandler(Plugin_NET_Current, new CSettingTypeApplication("Plugin", "Netplay Dll", "")); #endif 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_NET_CurVer, new CSettingTypeApplication("Plugin", "Netplay Dll Ver", "")); AddHandler(Plugin_UseHleGfx, new CSettingTypeApplication("RSP", "HLE GFX", true)); AddHandler(Plugin_UseHleAudio, new CSettingTypeApplication("RSP", "HLE Audio", false)); diff --git a/Source/Project64-core/TraceModulesProject64.h b/Source/Project64-core/TraceModulesProject64.h index 7eaa2fa886..ef80c55477 100644 --- a/Source/Project64-core/TraceModulesProject64.h +++ b/Source/Project64-core/TraceModulesProject64.h @@ -13,6 +13,8 @@ enum TraceModuleProject64 TraceAudioPlugin, TraceControllerPlugin, TraceRSPPlugin, + TraceNetplayPlugin, + TraceNetplay, TraceRSP, TraceAudio, TraceRegisterCache, diff --git a/Source/Project64/UserInterface/CheatClassUI.cpp b/Source/Project64/UserInterface/CheatClassUI.cpp index fc5cb35a74..37bd5936de 100644 --- a/Source/Project64/UserInterface/CheatClassUI.cpp +++ b/Source/Project64/UserInterface/CheatClassUI.cpp @@ -123,9 +123,15 @@ stdstr CCheatsUI::GetDlgItemStr(HWND hDlg, int nIDDlgItem) void CCheatsUI::SelectCheats(HWND hParent, bool BlockExecution) { + bool NetplayRunning = g_Settings->LoadBool(Plugin_NET_Running); + bool NetplayCanPause = g_Settings->LoadBool(Plugin_NET_CanPause); + if (g_BaseSystem) { - g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_Cheats); + if (!NetplayRunning || (NetplayRunning && NetplayCanPause)) + { + g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_Cheats); + } } if (m_Window != NULL) { diff --git a/Source/Project64/UserInterface/MainMenu.cpp b/Source/Project64/UserInterface/MainMenu.cpp index 6b58dc09a0..e55a0aaafd 100644 --- a/Source/Project64/UserInterface/MainMenu.cpp +++ b/Source/Project64/UserInterface/MainMenu.cpp @@ -43,8 +43,10 @@ CMainMenu::CMainMenu(CMainGui * hMainWindow) : m_ChangeSettingList.push_back(Debugger_TraceAudioPlugin); m_ChangeSettingList.push_back(Debugger_TraceControllerPlugin); m_ChangeSettingList.push_back(Debugger_TraceRSPPlugin); + m_ChangeSettingList.push_back(Debugger_TraceNetplayPlugin); m_ChangeSettingList.push_back(Debugger_TraceRSP); m_ChangeSettingList.push_back(Debugger_TraceAudio); + m_ChangeSettingList.push_back(Debugger_TraceNetplay); m_ChangeSettingList.push_back(Debugger_TraceRegisterCache); m_ChangeSettingList.push_back(Debugger_TraceRecompiler); m_ChangeSettingList.push_back(Debugger_TraceTLB); @@ -273,7 +275,25 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_ROMDIRECTORY 3"); break; case ID_FILE_REFRESHROMLIST: m_Gui->RefreshRomList(); break; - case ID_FILE_EXIT: DestroyWindow((HWND)hWnd); break; + case ID_FILE_STARTNETPLAY: + WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_STARTNETPLAY"); + g_Plugins->Netplay()->OpenNetplay(hWnd); + break; + case ID_FILE_EXIT: + if (g_Settings->LoadBool(Plugin_NET_Loaded)) + { + bool NetplayClosed = g_Plugins->Netplay()->CloseNetplay(); + + if (! NetplayClosed) + { + WriteTrace(TraceUserInterface, TraceDebug, "ID_FILE_EXIT - Netplay must be closed first"); + g_Notify->DisplayError(GS(MSG_CLOSE_NETPLAY)); + break; + } + } + + DestroyWindow((HWND)hWnd); + break; case ID_SYSTEM_RESET_SOFT: WriteTrace(TraceUserInterface, TraceDebug, "ID_SYSTEM_RESET_SOFT"); g_BaseSystem->ExternalEvent(SysEvent_ResetCPU_Soft); @@ -339,10 +359,12 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI } break; case ID_OPTIONS_INCREASE_SPEED: - g_BaseSystem->AlterSpeed(CSpeedLimiter::INCREASE_SPEED); + if (!g_Settings->LoadBool(Plugin_NET_Running)) + g_BaseSystem->AlterSpeed(CSpeedLimiter::INCREASE_SPEED); break; case ID_OPTIONS_DECREASE_SPEED: - g_BaseSystem->AlterSpeed(CSpeedLimiter::DECREASE_SPEED); + if (!g_Settings->LoadBool(Plugin_NET_Running)) + g_BaseSystem->AlterSpeed(CSpeedLimiter::DECREASE_SPEED); break; case ID_OPTIONS_FULLSCREEN: g_BaseSystem->ExternalEvent(SysEvent_ChangingFullScreen); @@ -419,6 +441,10 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_CONT"); g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_CONTROLLER); break; + case ID_OPTIONS_CONFIG_NET: + WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CONFIG_NET"); + g_Plugins->ConfigPlugin(hWnd, PLUGIN_TYPE_NETPLAY); + break; case ID_OPTIONS_CPU_USAGE: WriteTrace(TraceUserInterface, TraceDebug, "ID_OPTIONS_CPU_USAGE"); if (g_Settings->LoadBool(UserInterface_ShowCPUPer)) @@ -481,6 +507,7 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI case ID_DEBUGGER_TRACE_AUDIOPLUGIN: SetTraceModuleSetttings(Debugger_TraceAudioPlugin); break; case ID_DEBUGGER_TRACE_CONTROLLERPLUGIN: SetTraceModuleSetttings(Debugger_TraceControllerPlugin); break; case ID_DEBUGGER_TRACE_RSPPLUGIN: SetTraceModuleSetttings(Debugger_TraceRSPPlugin); break; + case ID_DEBUGGER_TRACE_NETPLAYPLUGIN: SetTraceModuleSetttings(Debugger_TraceNetplayPlugin); break; case ID_DEBUGGER_TRACE_RSP: SetTraceModuleSetttings(Debugger_TraceRSP); break; case ID_DEBUGGER_TRACE_AUDIO: SetTraceModuleSetttings(Debugger_TraceAudio); break; case ID_DEBUGGER_TRACE_REGISTERCACHE: SetTraceModuleSetttings(Debugger_TraceRegisterCache); break; @@ -689,6 +716,15 @@ void CMainMenu::FillOutMenu(HMENU hMenu) bool RomLoading = g_Settings->LoadBool(GameRunning_LoadingInProgress); bool RomLoaded = g_Settings->LoadStringVal(Game_GameName).length() > 0; bool RomList = UISettingsLoadBool(RomBrowser_Enabled) && !CPURunning; + bool NetplayExists = g_Plugins->Netplay() != NULL; + bool NetplayLoaded = g_Settings->LoadBool(Plugin_NET_Loaded); + bool NetplayRunning = g_Settings->LoadBool(Plugin_NET_Running); + + bool haveDebugger = HaveDebugger(); + if (NetplayRunning) + { + haveDebugger = HaveDebugger() && g_Settings->LoadBool(Plugin_NET_CanDebug); + } CMenuShortCutKey::RUNNING_STATE RunningState = CMenuShortCutKey::RUNNING_STATE_NOT_RUNNING; if (g_Settings->LoadBool(GameRunning_CPU_Running)) @@ -749,6 +785,7 @@ void CMainMenu::FillOutMenu(HMENU hMenu) ****************/ MenuItemList FileMenu; Item.Reset(ID_FILE_OPEN_ROM, MENU_OPEN, m_ShortCuts.ShortCutString(ID_FILE_OPEN_ROM, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(false); } FileMenu.push_back(Item); if (!inBasicMode) { @@ -770,8 +807,10 @@ void CMainMenu::FillOutMenu(HMENU hMenu) { FileMenu.push_back(MENU_ITEM(SPLITER)); Item.Reset(ID_FILE_ROMDIRECTORY, MENU_CHOOSE_ROM, m_ShortCuts.ShortCutString(ID_FILE_ROMDIRECTORY, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(false); } FileMenu.push_back(Item); Item.Reset(ID_FILE_REFRESHROMLIST, MENU_REFRESH, m_ShortCuts.ShortCutString(ID_FILE_REFRESHROMLIST, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(false); } FileMenu.push_back(Item); } @@ -784,6 +823,7 @@ void CMainMenu::FillOutMenu(HMENU hMenu) RecentRomMenu.push_back(MENU_ITEM(SPLITER)); Item.SetItemEnabled(false); } + if (NetplayRunning) { Item.SetItemEnabled(false); } FileMenu.push_back(Item); Item.Reset(SUB_MENU, MENU_RECENT_DIR, EMPTY_STDSTR, &RecentDirMenu); if (RecentDirMenu.size() == 0) @@ -791,6 +831,7 @@ void CMainMenu::FillOutMenu(HMENU hMenu) RecentDirMenu.push_back(MENU_ITEM(SPLITER)); Item.SetItemEnabled(false); } + if (NetplayRunning) { Item.SetItemEnabled(false); } FileMenu.push_back(Item); } else @@ -800,11 +841,16 @@ void CMainMenu::FillOutMenu(HMENU hMenu) FileMenu.push_back(MENU_ITEM(SPLITER)); for (MenuItemList::iterator MenuItem = RecentRomMenu.begin(); MenuItem != RecentRomMenu.end(); MenuItem++) { + if (NetplayRunning) { MenuItem->SetItemEnabled(false); } FileMenu.push_back(*MenuItem); } } } FileMenu.push_back(MENU_ITEM(SPLITER)); + Item.Reset(ID_FILE_STARTNETPLAY, MENU_NETPLAY, m_ShortCuts.ShortCutString(ID_FILE_STARTNETPLAY, RunningState)); + Item.SetItemEnabled(!CPURunning && NetplayExists && !NetplayLoaded && !NetplayRunning); + FileMenu.push_back(Item); + FileMenu.push_back(MENU_ITEM(SPLITER)); FileMenu.push_back(MENU_ITEM(ID_FILE_EXIT, MENU_EXIT, m_ShortCuts.ShortCutString(ID_FILE_EXIT, RunningState))); /* Current Save @@ -813,37 +859,48 @@ void CMainMenu::FillOutMenu(HMENU hMenu) DWORD _CurrentSaveState = g_Settings->LoadDword(Game_CurrentSaveState); Item.Reset(ID_CURRENT_SAVE_DEFAULT, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_DEFAULT, RunningState), NULL, GetSaveSlotString(0)); if (_CurrentSaveState == 0) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); CurrentSaveMenu.push_back(MENU_ITEM(SPLITER)); Item.Reset(ID_CURRENT_SAVE_1, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_1, RunningState), NULL, GetSaveSlotString(1)); if (_CurrentSaveState == 1) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_2, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_2, RunningState), NULL, GetSaveSlotString(2)); if (_CurrentSaveState == 2) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_3, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_3, RunningState), NULL, GetSaveSlotString(3)); if (_CurrentSaveState == 3) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_4, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_4, RunningState), NULL, GetSaveSlotString(4)); if (_CurrentSaveState == 4) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_5, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_5, RunningState), NULL, GetSaveSlotString(5)); if (_CurrentSaveState == 5) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_6, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_6, RunningState), NULL, GetSaveSlotString(6)); if (_CurrentSaveState == 6) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_7, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_7, RunningState), NULL, GetSaveSlotString(7)); if (_CurrentSaveState == 7) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_8, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_8, RunningState), NULL, GetSaveSlotString(8)); if (_CurrentSaveState == 8) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_9, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_9, RunningState), NULL, GetSaveSlotString(9)); if (_CurrentSaveState == 9) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); Item.Reset(ID_CURRENT_SAVE_10, EMPTY_STRING, m_ShortCuts.ShortCutString(ID_CURRENT_SAVE_10, RunningState), NULL, GetSaveSlotString(10)); if (_CurrentSaveState == 10) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } CurrentSaveMenu.push_back(Item); /* System Menu @@ -852,50 +909,79 @@ void CMainMenu::FillOutMenu(HMENU hMenu) MenuItemList ResetMenu; if (inBasicMode) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, RunningState))); + Item.Reset(ID_SYSTEM_RESET_SOFT, MENU_RESET, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanReset)); } + SystemMenu.push_back(Item); } else { - ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_SOFT, MENU_RESET_SOFT, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, RunningState))); - ResetMenu.push_back(MENU_ITEM(ID_SYSTEM_RESET_HARD, MENU_RESET_HARD, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_HARD, RunningState))); - SystemMenu.push_back(MENU_ITEM(SUB_MENU, MENU_RESET, EMPTY_STDSTR, &ResetMenu)); + Item.Reset(ID_SYSTEM_RESET_SOFT, MENU_RESET_SOFT, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_SOFT, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanReset)); } + ResetMenu.push_back(Item); + + Item.Reset(ID_SYSTEM_RESET_HARD, MENU_RESET_HARD, m_ShortCuts.ShortCutString(ID_SYSTEM_RESET_HARD, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanReset)); } + ResetMenu.push_back(Item); + + Item.Reset(SUB_MENU, MENU_RESET, EMPTY_STDSTR, &ResetMenu); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanReset)); } + SystemMenu.push_back(Item); } if (g_Settings->LoadBool(GameRunning_CPU_Paused)) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_RESUME, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, RunningState))); + Item.Reset(ID_SYSTEM_PAUSE, MENU_RESUME, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, RunningState)); } else { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_PAUSE, MENU_PAUSE, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, RunningState))); + Item.Reset(ID_SYSTEM_PAUSE, MENU_PAUSE, m_ShortCuts.ShortCutString(ID_SYSTEM_PAUSE, RunningState)); } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_BITMAP, MENU_BITMAP, m_ShortCuts.ShortCutString(ID_SYSTEM_BITMAP, RunningState))); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanPause)); } + SystemMenu.push_back(Item); + Item.Reset(ID_SYSTEM_BITMAP, MENU_BITMAP, m_ShortCuts.ShortCutString(ID_SYSTEM_BITMAP, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanPause)); } + SystemMenu.push_back(Item); SystemMenu.push_back(MENU_ITEM(SPLITER)); if (!inBasicMode) { Item.Reset(ID_SYSTEM_LIMITFPS, MENU_LIMIT_FPS, m_ShortCuts.ShortCutString(ID_SYSTEM_LIMITFPS, RunningState)); if (g_Settings->LoadBool(GameRunning_LimitFPS)) { Item.SetItemTicked(true); } + if (NetplayRunning) { Item.SetItemEnabled(false); } SystemMenu.push_back(Item); SystemMenu.push_back(MENU_ITEM(SPLITER)); } Item.Reset(ID_SYSTEM_SWAPDISK, MENU_SWAPDISK, m_ShortCuts.ShortCutString(ID_SYSTEM_SWAPDISK, RunningState)); - if (g_Disk == NULL) { Item.SetItemEnabled(false); } + if (g_Disk == NULL || NetplayRunning) { Item.SetItemEnabled(false); } SystemMenu.push_back(Item); SystemMenu.push_back(MENU_ITEM(SPLITER)); - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVE, MENU_SAVE, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVE, RunningState))); + Item.Reset(ID_SYSTEM_SAVE, MENU_SAVE, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVE, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } + SystemMenu.push_back(Item); if (!inBasicMode) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_SAVEAS, MENU_SAVE_AS, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVEAS, RunningState))); + Item.Reset(ID_SYSTEM_SAVEAS, MENU_SAVE_AS, m_ShortCuts.ShortCutString(ID_SYSTEM_SAVEAS, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } + SystemMenu.push_back(Item); } - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_RESTORE, MENU_RESTORE, m_ShortCuts.ShortCutString(ID_SYSTEM_RESTORE, RunningState))); + Item.Reset(ID_SYSTEM_RESTORE, MENU_RESTORE, m_ShortCuts.ShortCutString(ID_SYSTEM_RESTORE, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } + SystemMenu.push_back(Item); if (!inBasicMode) { - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_LOAD, MENU_LOAD, m_ShortCuts.ShortCutString(ID_SYSTEM_LOAD, RunningState))); + Item.Reset(ID_SYSTEM_LOAD, MENU_LOAD, m_ShortCuts.ShortCutString(ID_SYSTEM_LOAD, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } + SystemMenu.push_back(Item); } SystemMenu.push_back(MENU_ITEM(SPLITER)); - SystemMenu.push_back(MENU_ITEM(SUB_MENU, MENU_CURRENT_SAVE, EMPTY_STDSTR, &CurrentSaveMenu)); + Item.Reset(SUB_MENU, MENU_CURRENT_SAVE, EMPTY_STDSTR, &CurrentSaveMenu); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanSaveState)); } + SystemMenu.push_back(Item); SystemMenu.push_back(MENU_ITEM(SPLITER)); - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_CHEAT, MENU_CHEAT, m_ShortCuts.ShortCutString(ID_SYSTEM_CHEAT, RunningState))); - SystemMenu.push_back(MENU_ITEM(ID_SYSTEM_GSBUTTON, MENU_GS_BUTTON, m_ShortCuts.ShortCutString(ID_SYSTEM_GSBUTTON, RunningState))); + Item.Reset(ID_SYSTEM_CHEAT, MENU_CHEAT, m_ShortCuts.ShortCutString(ID_SYSTEM_CHEAT, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanCheat)); } + SystemMenu.push_back(Item); + Item.Reset(ID_SYSTEM_GSBUTTON, MENU_GS_BUTTON, m_ShortCuts.ShortCutString(ID_SYSTEM_GSBUTTON, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(g_Settings->LoadBool(Plugin_NET_CanCheat)); } + SystemMenu.push_back(Item); /* Option Menu ****************/ @@ -943,6 +1029,16 @@ void CMainMenu::FillOutMenu(HMENU hMenu) Item.SetItemEnabled(false); } OptionMenu.push_back(Item); + Item.Reset(ID_OPTIONS_CONFIG_NET, MENU_CONFG_NET, m_ShortCuts.ShortCutString(ID_OPTIONS_CONFIG_NET, RunningState)); + if (g_Plugins && g_Plugins->Netplay() == NULL || g_Plugins->Netplay()->DllConfig == NULL) + { + Item.SetItemEnabled(false); + } + else + { + Item.SetItemEnabled(!NetplayLoaded && !NetplayRunning); + } + OptionMenu.push_back(Item); OptionMenu.push_back(MENU_ITEM(SPLITER)); if (!inBasicMode) @@ -951,12 +1047,15 @@ void CMainMenu::FillOutMenu(HMENU hMenu) if (g_Settings->LoadDword(UserInterface_ShowCPUPer)) { Item.SetItemTicked(true); } OptionMenu.push_back(Item); } - OptionMenu.push_back(MENU_ITEM(ID_OPTIONS_SETTINGS, MENU_SETTINGS, m_ShortCuts.ShortCutString(ID_OPTIONS_SETTINGS, RunningState))); + Item.Reset(ID_OPTIONS_SETTINGS, MENU_SETTINGS, m_ShortCuts.ShortCutString(ID_OPTIONS_SETTINGS, RunningState)); + if (NetplayRunning) { Item.SetItemEnabled(false); } + OptionMenu.push_back(Item); /* Profile Menu ****************/ MenuItemList DebugProfileMenu; - if (HaveDebugger()) + + if (haveDebugger) { Item.Reset(ID_PROFILE_PROFILE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Record Execution Times"); if (g_Settings->LoadBool(Debugger_RecordExecutionTimes)) { Item.SetItemTicked(true); } @@ -978,7 +1077,7 @@ void CMainMenu::FillOutMenu(HMENU hMenu) MenuItemList DebugMemoryMenu; MenuItemList DebugInterrupt; MenuItemList DebugNotificationMenu; - if (HaveDebugger()) + if (haveDebugger) { /* Debug - Interrupt *******************/ @@ -1078,6 +1177,10 @@ void CMainMenu::FillOutMenu(HMENU hMenu) Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRSPPlugin) == TraceVerbose);; DebugAppLoggingMenu.push_back(Item); + Item.Reset(ID_DEBUGGER_TRACE_NETPLAYPLUGIN, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Netplay Plugin"); + Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceNetplayPlugin) == TraceVerbose);; + DebugAppLoggingMenu.push_back(Item); + Item.Reset(ID_DEBUGGER_TRACE_RSP, EMPTY_STRING, EMPTY_STDSTR, NULL, L"RSP"); Item.SetItemTicked(g_Settings->LoadDword(Debugger_TraceRSP) == TraceVerbose); DebugAppLoggingMenu.push_back(Item); @@ -1275,7 +1378,7 @@ void CMainMenu::FillOutMenu(HMENU hMenu) if (HaveDebugger()) { Item.Reset(SUB_MENU, MENU_DEBUGGER, EMPTY_STDSTR, &DebugMenu); - if (RomLoading) { Item.SetItemEnabled(false); } + if (RomLoading || !haveDebugger) { Item.SetItemEnabled(false); } MainTitleMenu.push_back(Item); } } @@ -1290,8 +1393,8 @@ void CMainMenu::RebuildAccelerators(void) { CGuard Guard(m_CS); - //Delete the old accel list - WriteTrace(TraceUserInterface, TraceDebug, "Start"); + //Delete the old accel list WriteTrace(TraceUserInterface, TraceDebug, "Start"); + HACCEL m_OldAccelTable = (HACCEL)m_AccelTable; m_AccelTable = m_ShortCuts.GetAcceleratorTable(); diff --git a/Source/Project64/UserInterface/MainMenu.h b/Source/Project64/UserInterface/MainMenu.h index ade58f2361..16aca4cc96 100644 --- a/Source/Project64/UserInterface/MainMenu.h +++ b/Source/Project64/UserInterface/MainMenu.h @@ -5,7 +5,7 @@ enum MainMenuID { //File Menu ID_FILE_OPEN_ROM = 4000, ID_FILE_ROM_INFO, ID_FILE_STARTEMULATION, ID_FILE_ENDEMULATION, - ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_EXIT, + ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_STARTNETPLAY, ID_FILE_EXIT, //language ID_LANG_START, ID_LANG_END = ID_LANG_START + 100, @@ -28,9 +28,9 @@ enum MainMenuID //Option Menu ID_OPTIONS_FULLSCREEN, ID_OPTIONS_FULLSCREEN2, ID_OPTIONS_ALWAYSONTOP, ID_OPTIONS_CONFIG_GFX, - ID_OPTIONS_CONFIG_AUDIO, ID_OPTIONS_CONFIG_CONT, ID_OPTIONS_CONFIG_RSP, ID_OPTIONS_CPU_USAGE, - ID_OPTIONS_SETTINGS, ID_OPTIONS_DISPLAY_FR, ID_OPTIONS_CHANGE_FR, ID_OPTIONS_INCREASE_SPEED, - ID_OPTIONS_DECREASE_SPEED, + ID_OPTIONS_CONFIG_AUDIO, ID_OPTIONS_CONFIG_CONT, ID_OPTIONS_CONFIG_RSP, ID_OPTIONS_CONFIG_NET, + ID_OPTIONS_CPU_USAGE, ID_OPTIONS_SETTINGS, ID_OPTIONS_DISPLAY_FR, ID_OPTIONS_CHANGE_FR, + ID_OPTIONS_INCREASE_SPEED, ID_OPTIONS_DECREASE_SPEED, //Debugger Menu ID_DEBUG_SHOW_TLB_MISSES, ID_DEBUG_SHOW_UNHANDLED_MEM, ID_DEBUG_SHOW_PIF_ERRORS, @@ -45,8 +45,8 @@ enum MainMenuID // App logging ID_DEBUGGER_APPLOG_FLUSH, ID_DEBUGGER_TRACE_MD5, ID_DEBUGGER_TRACE_SETTINGS, ID_DEBUGGER_TRACE_UNKNOWN, ID_DEBUGGER_TRACE_APPINIT, ID_DEBUGGER_TRACE_APPCLEANUP, ID_DEBUGGER_TRACE_N64SYSTEM, ID_DEBUGGER_TRACE_PLUGINS, ID_DEBUGGER_TRACE_GFXPLUGIN, - ID_DEBUGGER_TRACE_AUDIOPLUGIN, ID_DEBUGGER_TRACE_CONTROLLERPLUGIN, ID_DEBUGGER_TRACE_RSPPLUGIN, ID_DEBUGGER_TRACE_RSP, - ID_DEBUGGER_TRACE_AUDIO, ID_DEBUGGER_TRACE_REGISTERCACHE, ID_DEBUGGER_TRACE_RECOMPILER, ID_DEBUGGER_TRACE_TLB, + ID_DEBUGGER_TRACE_AUDIOPLUGIN, ID_DEBUGGER_TRACE_CONTROLLERPLUGIN, ID_DEBUGGER_TRACE_RSPPLUGIN, ID_DEBUGGER_TRACE_NETPLAYPLUGIN, + ID_DEBUGGER_TRACE_RSP, ID_DEBUGGER_TRACE_AUDIO, ID_DEBUGGER_TRACE_REGISTERCACHE, ID_DEBUGGER_TRACE_RECOMPILER, ID_DEBUGGER_TRACE_TLB, ID_DEBUGGER_TRACE_PROTECTEDMEM, ID_DEBUGGER_TRACE_USERINTERFACE, //Profile Menu diff --git a/Source/Project64/UserInterface/MainWindow.cpp b/Source/Project64/UserInterface/MainWindow.cpp index a657b1377e..6643ac2a1e 100644 --- a/Source/Project64/UserInterface/MainWindow.cpp +++ b/Source/Project64/UserInterface/MainWindow.cpp @@ -54,6 +54,8 @@ CMainGui::CMainGui(bool bMainWindow, const char * WindowTitle) : g_Settings->RegisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunning); g_Settings->RegisterChangeCB(GameRunning_CPU_Paused, this, (CSettings::SettingChangedFunc)GamePaused); g_Settings->RegisterChangeCB(Game_File, this, (CSettings::SettingChangedFunc)GameLoaded); + g_Settings->RegisterChangeCB(Plugin_NET_Loaded, this, (CSettings::SettingChangedFunc)NetplayLoaded); + g_Settings->RegisterChangeCB(Plugin_NET_Running, this, (CSettings::SettingChangedFunc)NetplayRunning); } //if this fails then it has already been created @@ -73,6 +75,8 @@ CMainGui::~CMainGui(void) g_Settings->UnregisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunning); g_Settings->UnregisterChangeCB(GameRunning_CPU_Paused, this, (CSettings::SettingChangedFunc)GamePaused); g_Settings->UnregisterChangeCB(Game_File, this, (CSettings::SettingChangedFunc)GameLoaded); + g_Settings->UnregisterChangeCB(Plugin_NET_Loaded, this, (CSettings::SettingChangedFunc)NetplayLoaded); + g_Settings->UnregisterChangeCB(Plugin_NET_Running, this, (CSettings::SettingChangedFunc)NetplayRunning); } if (m_hMainWindow) { @@ -238,6 +242,16 @@ void CMainGui::GameCpuRunning(CMainGui * Gui) } } +void CMainGui::NetplayLoaded(CMainGui * Gui) +{ + Gui->RefreshMenu(); +} + +void CMainGui::NetplayRunning(CMainGui * Gui) +{ + Gui->RefreshMenu(); +} + void RomBowserColoumnsChanged(CMainGui * Gui) { Gui->ResetRomBrowserColomuns(); @@ -881,6 +895,11 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO case WM_KILLFOCUS: { CMainGui * _this = (CMainGui *)GetProp(hWnd, "Class"); + if (_this == NULL) + { + break; + } + if (_this->RomBrowserVisible()) { break; @@ -1143,6 +1162,31 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO } } break; + case WM_CLOSE: + if (g_Settings->LoadBool(Plugin_NET_Running)) + { + if (g_BaseSystem) + { + g_BaseSystem->CloseCpu(); + g_Settings->SaveBool(Plugin_NET_Running, false); + return true; + } + } + + if (g_Settings->LoadBool(Plugin_NET_Loaded)) + { + bool NetplayClosed = g_Plugins->Netplay()->CloseNetplay(); + + if (!NetplayClosed) + { + WriteTrace(TraceUserInterface, TraceDebug, "WM_CLOSE - Netplay must be closed first"); + g_Notify->DisplayError(GS(MSG_CLOSE_NETPLAY)); + return true; + } + } + + DestroyWindow((HWND)hWnd); + break; case WM_DESTROY: WriteTrace(TraceUserInterface, TraceDebug, "WM_DESTROY - start"); { diff --git a/Source/Project64/UserInterface/MainWindow.h b/Source/Project64/UserInterface/MainWindow.h index bef3f93ab1..4c115ea6bb 100644 --- a/Source/Project64/UserInterface/MainWindow.h +++ b/Source/Project64/UserInterface/MainWindow.h @@ -119,6 +119,8 @@ class CMainGui : static void GameLoaded(CMainGui * Gui); static void GamePaused(CMainGui * Gui); static void GameCpuRunning(CMainGui * Gui); + static void NetplayLoaded(CMainGui * Gui); + static void NetplayRunning(CMainGui * Gui); CBaseMenu * m_Menu; diff --git a/Source/Project64/UserInterface/MenuShortCuts.cpp b/Source/Project64/UserInterface/MenuShortCuts.cpp index 715065d821..34f60d2cc8 100644 --- a/Source/Project64/UserInterface/MenuShortCuts.cpp +++ b/Source/Project64/UserInterface/MenuShortCuts.cpp @@ -384,6 +384,7 @@ void CShortCuts::Load(bool InitialValues) AddShortCut(ID_FILE_ENDEMULATION, STR_SHORTCUT_FILEMENU, MENU_END, CMenuShortCutKey::ACCESS_GAME_RUNNING); AddShortCut(ID_FILE_ROMDIRECTORY, STR_SHORTCUT_FILEMENU, MENU_CHOOSE_ROM, CMenuShortCutKey::ACCESS_GAME_NOT_RUNNING); AddShortCut(ID_FILE_REFRESHROMLIST, STR_SHORTCUT_FILEMENU, MENU_REFRESH, CMenuShortCutKey::ACCESS_GAME_NOT_RUNNING); + AddShortCut(ID_FILE_STARTNETPLAY, STR_SHORTCUT_FILEMENU, MENU_NETPLAY, CMenuShortCutKey::ACCESS_GAME_NOT_RUNNING); AddShortCut(ID_FILE_EXIT, STR_SHORTCUT_FILEMENU, MENU_EXIT, CMenuShortCutKey::ACCESS_ANYTIME); AddShortCut(ID_SYSTEM_RESET_SOFT, STR_SHORTCUT_SYSTEMMENU, MENU_RESET_SOFT, CMenuShortCutKey::ACCESS_GAME_RUNNING); @@ -423,6 +424,7 @@ void CShortCuts::Load(bool InitialValues) AddShortCut(ID_OPTIONS_CONFIG_AUDIO, STR_SHORTCUT_OPTIONS, MENU_CONFG_AUDIO, CMenuShortCutKey::ACCESS_NOT_IN_FULLSCREEN); AddShortCut(ID_OPTIONS_CONFIG_CONT, STR_SHORTCUT_OPTIONS, MENU_CONFG_CTRL, CMenuShortCutKey::ACCESS_NOT_IN_FULLSCREEN); AddShortCut(ID_OPTIONS_CONFIG_RSP, STR_SHORTCUT_OPTIONS, MENU_CONFG_RSP, CMenuShortCutKey::ACCESS_NOT_IN_FULLSCREEN); + AddShortCut(ID_OPTIONS_CONFIG_NET, STR_SHORTCUT_OPTIONS, MENU_CONFG_NET, CMenuShortCutKey::ACCESS_NOT_IN_FULLSCREEN); AddShortCut(ID_OPTIONS_CPU_USAGE, STR_SHORTCUT_OPTIONS, MENU_SHOW_CPU, CMenuShortCutKey::ACCESS_GAME_RUNNING); AddShortCut(ID_OPTIONS_SETTINGS, STR_SHORTCUT_OPTIONS, MENU_SETTINGS, CMenuShortCutKey::ACCESS_NOT_IN_FULLSCREEN); diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.cpp index 64f3c5d271..f5fb12e0ae 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.cpp @@ -20,34 +20,38 @@ CGamePluginPage::CGamePluginPage(HWND hParent, const RECT & rcDispay) return; } - //Set the text for all gui Items - SetDlgItemTextW(m_hWnd, RSP_ABOUT, wGS(PLUG_ABOUT).c_str()); - SetDlgItemTextW(m_hWnd, GFX_ABOUT, wGS(PLUG_ABOUT).c_str()); - SetDlgItemTextW(m_hWnd, AUDIO_ABOUT, wGS(PLUG_ABOUT).c_str()); - SetDlgItemTextW(m_hWnd, CONT_ABOUT, wGS(PLUG_ABOUT).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_RSP_NAME, wGS(PLUG_RSP).c_str()); - SetDlgItemTextW(m_hWnd, IDC_GFX_NAME, wGS(PLUG_GFX).c_str()); - SetDlgItemTextW(m_hWnd, IDC_AUDIO_NAME, wGS(PLUG_AUDIO).c_str()); - SetDlgItemTextW(m_hWnd, IDC_CONT_NAME, wGS(PLUG_CTRL).c_str()); - - SetDlgItemTextW(m_hWnd, IDC_HLE_GFX, wGS(PLUG_HLE_GFX).c_str()); - SetDlgItemTextW(m_hWnd, IDC_HLE_AUDIO, wGS(PLUG_HLE_AUDIO).c_str()); - - m_GfxGroup.Attach(GetDlgItem(IDC_GFX_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_EditPlugin_Gfx, PLUGIN_TYPE_GFX); - AddPlugins(AUDIO_LIST, Game_EditPlugin_Audio, PLUGIN_TYPE_AUDIO); - AddPlugins(CONT_LIST, Game_EditPlugin_Contr, PLUGIN_TYPE_CONTROLLER); - AddPlugins(RSP_LIST, Game_EditPlugin_RSP, PLUGIN_TYPE_RSP); - - AddModCheckBox(GetDlgItem(IDC_HLE_GFX), Game_UseHleGfx); - AddModCheckBox(GetDlgItem(IDC_HLE_AUDIO), Game_UseHleAudio); - - UpdatePageSettings(); + //Set the text for all gui Items + SetDlgItemTextW(m_hWnd, RSP_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, GFX_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, AUDIO_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, CONT_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, NET_ABOUT, wGS(PLUG_ABOUT).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_RSP_NAME, wGS(PLUG_RSP).c_str()); + SetDlgItemTextW(m_hWnd, IDC_GFX_NAME, wGS(PLUG_GFX).c_str()); + SetDlgItemTextW(m_hWnd, IDC_AUDIO_NAME, wGS(PLUG_AUDIO).c_str()); + SetDlgItemTextW(m_hWnd, IDC_CONT_NAME, wGS(PLUG_CTRL).c_str()); + SetDlgItemTextW(m_hWnd, IDC_NET_NAME, wGS(PLUG_NET).c_str()); + + SetDlgItemTextW(m_hWnd, IDC_HLE_GFX, wGS(PLUG_HLE_GFX).c_str()); + SetDlgItemTextW(m_hWnd, IDC_HLE_AUDIO, wGS(PLUG_HLE_AUDIO).c_str()); + + m_GfxGroup.Attach(GetDlgItem(IDC_GFX_NAME)); + m_AudioGroup.Attach(GetDlgItem(IDC_AUDIO_NAME)); + m_ControlGroup.Attach(GetDlgItem(IDC_CONT_NAME)); + m_RspGroup.Attach(GetDlgItem(IDC_RSP_NAME)); + m_NetGroup.Attach(GetDlgItem(IDC_NET_NAME)); + + AddPlugins(GFX_LIST, Game_EditPlugin_Gfx, PLUGIN_TYPE_GFX); + AddPlugins(AUDIO_LIST, Game_EditPlugin_Audio, PLUGIN_TYPE_AUDIO); + AddPlugins(CONT_LIST, Game_EditPlugin_Contr, PLUGIN_TYPE_CONTROLLER); + AddPlugins(RSP_LIST, Game_EditPlugin_RSP, PLUGIN_TYPE_RSP); + AddPlugins(NET_LIST, Game_EditPlugin_NET, PLUGIN_TYPE_NETPLAY); + + 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) @@ -208,6 +212,7 @@ void CGamePluginPage::UpdatePageSettings(void) PluginItemChanged(AUDIO_LIST, AUDIO_ABOUT, false); PluginItemChanged(CONT_LIST, CONT_ABOUT, false); PluginItemChanged(RSP_LIST, RSP_ABOUT, false); + PluginItemChanged(NET_LIST, NET_ABOUT, false); } void CGamePluginPage::HidePage() diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.h b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.h index 11e3d0eef5..3903df4e1c 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Game-Plugin.h @@ -22,10 +22,12 @@ class CGamePluginPage : 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_HANDLER_EX(NET_LIST, LBN_SELCHANGE, NetPluginChanged) 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(NET_ABOUT, NetPluginAbout) COMMAND_ID_HANDLER_EX(IDC_HLE_GFX, HleGfxChanged) COMMAND_ID_HANDLER_EX(IDC_HLE_AUDIO, HleAudioChanged) END_MSG_MAP() @@ -47,11 +49,13 @@ class CGamePluginPage : 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 NetPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(NET_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 NetPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(NET_LIST, NET_ABOUT); } void HleGfxChanged(UINT Code, int id, HWND ctl); void HleAudioChanged(UINT Code, int id, HWND ctl); @@ -64,6 +68,6 @@ class CGamePluginPage : void ApplyComboBoxes(void); bool ResetComboBox(CModifiedComboBox & ComboBox, SettingID Type); - CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup; + CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup, m_NetGroup; CPluginList m_PluginList; }; diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp index c6697dd523..804d945878 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.cpp @@ -24,11 +24,13 @@ COptionPluginPage::COptionPluginPage(HWND hParent, const RECT & rcDispay) SetDlgItemTextW(m_hWnd, GFX_ABOUT, wGS(PLUG_ABOUT).c_str()); SetDlgItemTextW(m_hWnd, AUDIO_ABOUT, wGS(PLUG_ABOUT).c_str()); SetDlgItemTextW(m_hWnd, CONT_ABOUT, wGS(PLUG_ABOUT).c_str()); + SetDlgItemTextW(m_hWnd, NET_ABOUT, wGS(PLUG_ABOUT).c_str()); SetDlgItemTextW(m_hWnd, IDC_RSP_NAME, wGS(PLUG_RSP).c_str()); SetDlgItemTextW(m_hWnd, IDC_GFX_NAME, wGS(PLUG_GFX).c_str()); SetDlgItemTextW(m_hWnd, IDC_AUDIO_NAME, wGS(PLUG_AUDIO).c_str()); SetDlgItemTextW(m_hWnd, IDC_CONT_NAME, wGS(PLUG_CTRL).c_str()); + SetDlgItemTextW(m_hWnd, IDC_NET_NAME, wGS(PLUG_NET).c_str()); SetDlgItemTextW(m_hWnd, IDC_HLE_GFX, wGS(PLUG_HLE_GFX).c_str()); SetDlgItemTextW(m_hWnd, IDC_HLE_AUDIO, wGS(PLUG_HLE_AUDIO).c_str()); @@ -37,11 +39,13 @@ COptionPluginPage::COptionPluginPage(HWND hParent, const RECT & rcDispay) m_AudioGroup.Attach(GetDlgItem(IDC_AUDIO_NAME)); m_ControlGroup.Attach(GetDlgItem(IDC_CONT_NAME)); m_RspGroup.Attach(GetDlgItem(IDC_RSP_NAME)); + m_NetGroup.Attach(GetDlgItem(IDC_NET_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); + AddPlugins(NET_LIST, Plugin_NET_Current, PLUGIN_TYPE_NETPLAY); AddModCheckBox(GetDlgItem(IDC_HLE_GFX), Plugin_UseHleGfx); AddModCheckBox(GetDlgItem(IDC_HLE_AUDIO), Plugin_UseHleAudio); @@ -198,6 +202,7 @@ void COptionPluginPage::UpdatePageSettings(void) PluginItemChanged(AUDIO_LIST, AUDIO_ABOUT, false); PluginItemChanged(CONT_LIST, CONT_ABOUT, false); PluginItemChanged(RSP_LIST, RSP_ABOUT, false); + PluginItemChanged(NET_LIST, NET_ABOUT, false); } void COptionPluginPage::HidePage() diff --git a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h index e234f360f9..da0ecc0008 100644 --- a/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h +++ b/Source/Project64/UserInterface/Settings/SettingsPage-Plugin.h @@ -21,10 +21,12 @@ class COptionPluginPage : 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_HANDLER_EX(NET_LIST, LBN_SELCHANGE, NetPluginChanged) 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(NET_ABOUT, NetPluginAbout) COMMAND_ID_HANDLER_EX(IDC_HLE_GFX, HleGfxChanged) COMMAND_ID_HANDLER_EX(IDC_HLE_AUDIO, HleAudioChanged) END_MSG_MAP() @@ -46,11 +48,13 @@ class COptionPluginPage : 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 NetPluginAbout(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { ShowAboutButton(NET_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 NetPluginChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { PluginItemChanged(NET_LIST, NET_ABOUT); } void HleGfxChanged(UINT Code, int id, HWND ctl); void HleAudioChanged(UINT Code, int id, HWND ctl); @@ -63,6 +67,6 @@ class COptionPluginPage : void ApplyComboBoxes(void); bool ResetComboBox(CModifiedComboBox & ComboBox, SettingID Type); - CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup; + CPartialGroupBox m_GfxGroup, m_AudioGroup, m_ControlGroup, m_RspGroup, m_NetGroup; CPluginList m_PluginList; }; diff --git a/Source/Project64/UserInterface/UIResources.rc b/Source/Project64/UserInterface/UIResources.rc index ce280bcbe0..d8e0be074b 100644 --- a/Source/Project64/UserInterface/UIResources.rc +++ b/Source/Project64/UserInterface/UIResources.rc @@ -25,6 +25,12 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) +///////////////////////////////////////////////////////////////////////////// +// +// RT_MANIFEST +// + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "..\\Project64.exe.manifest" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -89,12 +95,15 @@ BEGIN 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",RSP_ABOUT,166,105,44,13,WS_DISABLED - CONTROL "Use High Level GFX",IDC_HLE_GFX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,127,193,10 - CONTROL "Use High Level Audio",IDC_HLE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,140,188,10 + CONTROL "Use High Level GFX",IDC_HLE_GFX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,157,193,10 + CONTROL "Use High Level Audio",IDC_HLE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,170,188,10 GROUPBOX "Graphics:",IDC_GFX_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 + GROUPBOX "Reality Signal Processor:",IDC_RSP_NAME,6,96,208,29 + GROUPBOX "Netplay:",IDC_NET_NAME,6,125,208,29 + COMBOBOX NET_LIST,7,135,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "About",NET_ABOUT,166,135,44,13,WS_DISABLED END IDD_Settings_Directory DIALOGEX 0, 0, 231, 206 @@ -580,19 +589,19 @@ BEGIN EDITTEXT IDC_INFO3,69,51,104,15,ES_AUTOHSCROLL | ES_READONLY END -IDD_Settings_Config DIALOGEX 0, 0, 357, 207 +IDD_Settings_Config DIALOGEX 0, 0, 357, 237 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dialog" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - 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_HSCROLL | WS_TABSTOP,8,7,116,169 - CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,7,180,343,1 - PUSHBUTTON "Reset Page",IDC_RESET_PAGE,7,186,58,14,WS_DISABLED - CONTROL "",IDC_SETTING_INFO,"Static",SS_ETCHEDFRAME,131,7,219,170 - PUSHBUTTON "Apply",IDAPPLY,301,186,50,14,WS_DISABLED - PUSHBUTTON "Reset All",IDC_RESET_ALL,68,186,52,14,WS_DISABLED + DEFPUSHBUTTON "OK",IDOK,194,216,50,14 + PUSHBUTTON "Cancel",IDCANCEL,248,216,50,14 + CONTROL "Tree1",IDC_PAGELIST,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,8,7,116,199 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME | SS_SUNKEN,7,209,343,1 + PUSHBUTTON "Reset Page",IDC_RESET_PAGE,7,216,58,14,WS_DISABLED + CONTROL "",IDC_SETTING_INFO,"Static",SS_ETCHEDFRAME,131,7,219,199 + PUSHBUTTON "Apply",IDAPPLY,301,216,50,14,WS_DISABLED + PUSHBUTTON "Reset All",IDC_RESET_ALL,68,216,52,14,WS_DISABLED END IDD_Settings_GameRecompiler DIALOGEX 0, 0, 230, 156 @@ -630,12 +639,15 @@ BEGIN 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",RSP_ABOUT,166,105,44,13,WS_DISABLED - CONTROL "Use High Level GFX",IDC_HLE_GFX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,127,193,10 - CONTROL "Use High Level Audio",IDC_HLE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,140,188,10 + CONTROL "Use High Level GFX",IDC_HLE_GFX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,157,193,10 + CONTROL "Use High Level Audio",IDC_HLE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,170,188,10 GROUPBOX "Graphics:",IDC_GFX_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 + GROUPBOX "Reality Signal Processor:",IDC_RSP_NAME,6,96,208,29 + GROUPBOX "Netplay:",IDC_NET_NAME,6,125,208,29 + COMBOBOX NET_LIST,7,135,155,79,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "About",NET_ABOUT,166,135,44,13,WS_DISABLED END IDD_Settings_GameStatus DIALOGEX 0, 0, 218, 158 @@ -1270,7 +1282,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 222 TOPMARGIN, 7 - BOTTOMMARGIN, 131 + BOTTOMMARGIN, 160 END IDD_Settings_Directory, DIALOG @@ -1468,7 +1480,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 350 TOPMARGIN, 7 - BOTTOMMARGIN, 200 + BOTTOMMARGIN, 230 END IDD_Settings_GameRecompiler, DIALOG @@ -1887,6 +1899,20 @@ END // IDR_JSAPI_TEXT TEXT "API.js" +IDD_Settings_Config AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IDD_Settings_PlugSel AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IDD_Settings_GamePlugin AFX_DIALOG_LAYOUT +BEGIN + 0 +END #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/Source/Project64/UserInterface/resource.h b/Source/Project64/UserInterface/resource.h index 5c87a4f7ad..9ea052c989 100644 --- a/Source/Project64/UserInterface/resource.h +++ b/Source/Project64/UserInterface/resource.h @@ -78,6 +78,7 @@ #define IDC_CURRENT_KEYS 1003 #define RSP_LIST 1004 #define IDC_CURRENT_KEYS2 1004 +#define NET_LIST 1005 #define RSP_ABOUT 1006 #define IDC_ASSIGN 1006 #define IDC_BTN_CHOOSE_FILE 1006 @@ -85,6 +86,7 @@ #define IDC_INFO_FILENAME 1007 #define IDC_BTN_RDRAM 1007 #define IDC_REFRSH_MEM 1007 +#define NET_ABOUT 1007 #define IDC_INFO_ROMNAME 1008 #define IDC_RESET_PAGE 1008 #define IDC_INFO_CARTID 1009 @@ -262,6 +264,7 @@ #define IDC_REMEMBERDIR 1097 #define IDC_VIREFESH_TEXT 1097 #define IDC_VIREFRESH 1098 +#define IDC_NET_NAME 1098 #define IDC_AUDIO_NAME 1099 #define IDC_ROM_REGCACHE 1099 #define IDC_COUNTPERBYTE_TEXT 1099 diff --git a/Source/UpdateVersion/UpdateVersion.cpp b/Source/UpdateVersion/UpdateVersion.cpp index 20fb32617d..fd9ba1d83d 100644 --- a/Source/UpdateVersion/UpdateVersion.cpp +++ b/Source/UpdateVersion/UpdateVersion.cpp @@ -34,7 +34,16 @@ int main() uint32_t FileLen = InFile.GetLength(); std::auto_ptr InputData(new uint8_t[FileLen]); InFile.Read(InputData.get(), FileLen); - strvector VersionData = stdstr(std::string((char *)InputData.get(), FileLen)).Tokenize("\r\n"); + + strvector VersionData; + try + { + VersionData = stdstr(std::string((char *)InputData.get(), FileLen)).Tokenize("\r\n"); + } + catch(std::out_of_range e) + { + VersionData = stdstr(std::string((char *)InputData.get(), FileLen)).Tokenize("\n"); + } strvector verinfo = stdstr(__argv[3]).Tokenize('-'); if (verinfo.size() < 3 || verinfo.size() > 4)