From 8ef75dac6722ce6b9950cf91d4f9fd98356c44d6 Mon Sep 17 00:00:00 2001 From: nitsuja Date: Mon, 26 Dec 2011 05:15:23 -0600 Subject: [PATCH] add missing SI device state to saves --- Source/Core/Core/Src/HW/SI.cpp | 42 +++++++++++- Source/Core/Core/Src/HW/SI.h | 2 + Source/Core/Core/Src/HW/SI_Device.cpp | 12 ++-- Source/Core/Core/Src/HW/SI_Device.h | 67 ++++++++++++------- .../Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp | 4 +- .../Core/Core/Src/HW/SI_DeviceAMBaseboard.h | 2 +- Source/Core/Core/Src/HW/SI_DeviceGBA.cpp | 4 +- Source/Core/Core/Src/HW/SI_DeviceGBA.h | 2 +- .../Core/Src/HW/SI_DeviceGCController.cpp | 16 ++++- .../Core/Core/Src/HW/SI_DeviceGCController.h | 7 +- 10 files changed, 114 insertions(+), 44 deletions(-) diff --git a/Source/Core/Core/Src/HW/SI.cpp b/Source/Core/Core/Src/HW/SI.cpp index 09697f4965..7250a003b3 100644 --- a/Source/Core/Core/Src/HW/SI.cpp +++ b/Source/Core/Core/Src/HW/SI.cpp @@ -229,7 +229,35 @@ static u8 g_SIBuffer[128]; void DoState(PointerWrap &p) { - // p.DoArray(g_Channel); + bool reloadOnState = SConfig::GetInstance().b_reloadMCOnState; + + for(int i = 0; i < NUMBER_OF_CHANNELS; i++) + { + p.Do(g_Channel[i].m_InHi.Hex); + p.Do(g_Channel[i].m_InLo.Hex); + p.Do(g_Channel[i].m_Out.Hex); + + ISIDevice* pDevice = g_Channel[i].m_pDevice; + SIDevices type = pDevice->GetDeviceType(); + p.Do(type); + ISIDevice* pSaveDevice = (type == pDevice->GetDeviceType()) ? pDevice : SIDevice_Create(type, i); + pSaveDevice->DoState(p); + if(pSaveDevice != pDevice) + { + // if we had to create a temporary device, discard it if we're not loading. + // also, if no movie is active, we'll assume the user wants to keep their current devices + // instead of the ones they had when the savestate was created. + if(p.GetMode() != PointerWrap::MODE_READ || + (reloadOnState && !Movie::IsRecordingInput() && !Movie::IsPlayingInput())) + { + delete pSaveDevice; + } + else + { + AddDevice(pSaveDevice); + } + } + } p.Do(g_Poll); p.Do(g_ComCSR); p.Do(g_StatusReg); @@ -536,15 +564,23 @@ void RemoveDevice(int _iDeviceNumber) g_Channel[_iDeviceNumber].m_pDevice = NULL; } -void AddDevice(const SIDevices _device, int _iDeviceNumber) +void AddDevice(ISIDevice* pDevice) { + int _iDeviceNumber = pDevice->GetDeviceNumber(); + //_dbg_assert_(SERIALINTERFACE, _iDeviceNumber < NUMBER_OF_CHANNELS); // delete the old device RemoveDevice(_iDeviceNumber); // create the new one - g_Channel[_iDeviceNumber].m_pDevice = SIDevice_Create(_device, _iDeviceNumber); + g_Channel[_iDeviceNumber].m_pDevice = pDevice; +} + +void AddDevice(const SIDevices _device, int _iDeviceNumber) +{ + ISIDevice* pDevice = SIDevice_Create(_device, _iDeviceNumber); + AddDevice(pDevice); } void SetNoResponse(u32 channel) diff --git a/Source/Core/Core/Src/HW/SI.h b/Source/Core/Core/Src/HW/SI.h index c1eb336798..26ec8f1218 100644 --- a/Source/Core/Core/Src/HW/SI.h +++ b/Source/Core/Core/Src/HW/SI.h @@ -20,6 +20,7 @@ #include "Common.h" #include "SI_Device.h" class PointerWrap; +class ISIDevice; namespace SerialInterface { @@ -32,6 +33,7 @@ void UpdateDevices(); void RemoveDevice(int _iDeviceNumber); void AddDevice(const SIDevices _device, int _iDeviceNumber); +void AddDevice(ISIDevice* pDevice); void ChangeDeviceCallback(u64 userdata, int cyclesLate); void ChangeDevice(SIDevices device, int channel); diff --git a/Source/Core/Core/Src/HW/SI_Device.cpp b/Source/Core/Core/Src/HW/SI_Device.cpp index 6c0c40f40d..8abddbe472 100644 --- a/Source/Core/Core/Src/HW/SI_Device.cpp +++ b/Source/Core/Core/Src/HW/SI_Device.cpp @@ -52,7 +52,7 @@ int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength) class CSIDevice_Null : public ISIDevice { public: - CSIDevice_Null(int _iDeviceNumber) : ISIDevice(_iDeviceNumber) {} + CSIDevice_Null(SIDevices device, int _iDeviceNumber) : ISIDevice(device, _iDeviceNumber) {} virtual ~CSIDevice_Null() {} int RunBuffer(u8* _pBuffer, int _iLength) { @@ -73,24 +73,24 @@ ISIDevice* SIDevice_Create(const SIDevices device, const int port_number) switch (device) { case SIDEVICE_GC_CONTROLLER: - return new CSIDevice_GCController(port_number); + return new CSIDevice_GCController(device, port_number); break; case SIDEVICE_GC_TARUKONGA: - return new CSIDevice_TaruKonga(port_number); + return new CSIDevice_TaruKonga(device, port_number); break; case SIDEVICE_GC_GBA: - return new CSIDevice_GBA(port_number); + return new CSIDevice_GBA(device, port_number); break; case SIDEVICE_AM_BASEBOARD: - return new CSIDevice_AMBaseboard(port_number); + return new CSIDevice_AMBaseboard(device, port_number); break; case SIDEVICE_NONE: default: - return new CSIDevice_Null(port_number); + return new CSIDevice_Null(device, port_number); break; } } diff --git a/Source/Core/Core/Src/HW/SI_Device.h b/Source/Core/Core/Src/HW/SI_Device.h index 2ed982ad0a..ee7357f84e 100644 --- a/Source/Core/Core/Src/HW/SI_Device.h +++ b/Source/Core/Core/Src/HW/SI_Device.h @@ -20,6 +20,8 @@ #include "Common.h" +class PointerWrap; + // Devices can reply with these #define SI_ERROR_NO_RESPONSE 0x0008 // Nothing is attached #define SI_ERROR_UNKNOWN 0x0040 // Unknown device is attached @@ -33,30 +35,6 @@ #define SI_GC_NOMOTOR 0x20000000u // No rumble motor #define SI_GC_STANDARD 0x01000000u -class ISIDevice -{ -protected: - int m_iDeviceNumber; - -public: - // Constructor - ISIDevice(int _iDeviceNumber) : - m_iDeviceNumber(_iDeviceNumber) - {} - - // Destructor - virtual ~ISIDevice() {} - - // Run the SI Buffer - virtual int RunBuffer(u8* _pBuffer, int _iLength); - - // Return true on new data - virtual bool GetData(u32& _Hi, u32& _Low) = 0; - - // Send a command directly (no detour per buffer) - virtual void SendCommand(u32 _Cmd, u8 _Poll) = 0; -}; - // SI Device IDs for emulator use enum TSIDevices { @@ -88,6 +66,47 @@ enum SIDevices SIDEVICE_AM_BASEBOARD }; + +class ISIDevice +{ +protected: + int m_iDeviceNumber; + SIDevices m_deviceType; + +public: + // Constructor + ISIDevice(SIDevices deviceType, int _iDeviceNumber) + : m_iDeviceNumber(_iDeviceNumber) + , m_deviceType(deviceType) + {} + + // Destructor + virtual ~ISIDevice() {} + + // Run the SI Buffer + virtual int RunBuffer(u8* _pBuffer, int _iLength); + + // Return true on new data + virtual bool GetData(u32& _Hi, u32& _Low) = 0; + + // Send a command directly (no detour per buffer) + virtual void SendCommand(u32 _Cmd, u8 _Poll) = 0; + + // Savestate support + virtual void DoState(PointerWrap& p) {} + + + int GetDeviceNumber() + { + return m_iDeviceNumber; + } + + SIDevices GetDeviceType() + { + return m_deviceType; + } +}; + extern ISIDevice* SIDevice_Create(const SIDevices device, const int port_number); #endif diff --git a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp index dd86f0a234..897b6d1227 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.cpp @@ -89,8 +89,8 @@ public: // AM-Baseboard device on SI -CSIDevice_AMBaseboard::CSIDevice_AMBaseboard(int _iDeviceNumber) - : ISIDevice(_iDeviceNumber) +CSIDevice_AMBaseboard::CSIDevice_AMBaseboard(SIDevices device, int _iDeviceNumber) + : ISIDevice(device, _iDeviceNumber) { } diff --git a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.h b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.h index 4838007423..f2c8b1e8a9 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.h +++ b/Source/Core/Core/Src/HW/SI_DeviceAMBaseboard.h @@ -30,7 +30,7 @@ private: public: // constructor - CSIDevice_AMBaseboard(int _iDeviceNumber); + CSIDevice_AMBaseboard(SIDevices device, int _iDeviceNumber); // run the SI Buffer virtual int RunBuffer(u8* _pBuffer, int _iLength); diff --git a/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp b/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp index 57e99f6372..3818c5bd12 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGBA.cpp @@ -135,8 +135,8 @@ void GBASockServer::Transfer(char* si_buffer) si_buffer[i ^ 3] = current_data[i]; } -CSIDevice_GBA::CSIDevice_GBA(int _iDeviceNumber) - : ISIDevice(_iDeviceNumber) +CSIDevice_GBA::CSIDevice_GBA(SIDevices _device, int _iDeviceNumber) + : ISIDevice(_device, _iDeviceNumber) , GBASockServer() { } diff --git a/Source/Core/Core/Src/HW/SI_DeviceGBA.h b/Source/Core/Core/Src/HW/SI_DeviceGBA.h index 395cb1be10..58d5a4f153 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGBA.h +++ b/Source/Core/Core/Src/HW/SI_DeviceGBA.h @@ -48,7 +48,7 @@ private: class CSIDevice_GBA : public ISIDevice, private GBASockServer { public: - CSIDevice_GBA(int _iDeviceNumber); + CSIDevice_GBA(SIDevices device, int _iDeviceNumber); ~CSIDevice_GBA() {} // Run the SI Buffer diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp index abb4bf8dec..a9b708324d 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.cpp @@ -35,8 +35,8 @@ #include "../Core.h" // --- standard gamecube controller --- -CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) - : ISIDevice(_iDeviceNumber) +CSIDevice_GCController::CSIDevice_GCController(SIDevices device, int _iDeviceNumber) + : ISIDevice(device, _iDeviceNumber) , m_TButtonComboStart(0) , m_TButtonCombo(0) , m_LastButtonCombo(COMBO_NONE) @@ -115,7 +115,7 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) { SPADStatus PadStatus; memset(&PadStatus, 0, sizeof(PadStatus)); - + Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); Movie::CallInputManip(&PadStatus, ISIDevice::m_iDeviceNumber); @@ -268,3 +268,13 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll) break; } } + +// Savestate support +void CSIDevice_GCController::DoState(PointerWrap& p) +{ + p.Do(m_Origin); + p.Do(m_Mode); + p.Do(m_TButtonComboStart); + p.Do(m_TButtonCombo); + p.Do(m_LastButtonCombo); +} diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCController.h b/Source/Core/Core/Src/HW/SI_DeviceGCController.h index 81e0d9d03f..058dde3582 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCController.h +++ b/Source/Core/Core/Src/HW/SI_DeviceGCController.h @@ -95,7 +95,7 @@ private: public: // Constructor - CSIDevice_GCController(int _iDeviceNumber); + CSIDevice_GCController(SIDevices device, int _iDeviceNumber); // Run the SI Buffer virtual int RunBuffer(u8* _pBuffer, int _iLength); @@ -109,6 +109,9 @@ public: // Send a command directly virtual void SendCommand(u32 _Cmd, u8 _Poll); + + // Savestate support + virtual void DoState(PointerWrap& p); }; @@ -116,7 +119,7 @@ public: class CSIDevice_TaruKonga : public CSIDevice_GCController { public: - CSIDevice_TaruKonga(int _iDeviceNumber) : CSIDevice_GCController(_iDeviceNumber) { } + CSIDevice_TaruKonga(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber) { } virtual bool GetData(u32& _Hi, u32& _Low) {