add missing SI device state to saves

This commit is contained in:
nitsuja 2011-12-26 05:15:23 -06:00 committed by skidau
parent 5423bca79c
commit 8ef75dac67
10 changed files with 114 additions and 44 deletions

View File

@ -229,7 +229,35 @@ static u8 g_SIBuffer[128];
void DoState(PointerWrap &p) 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_Poll);
p.Do(g_ComCSR); p.Do(g_ComCSR);
p.Do(g_StatusReg); p.Do(g_StatusReg);
@ -536,15 +564,23 @@ void RemoveDevice(int _iDeviceNumber)
g_Channel[_iDeviceNumber].m_pDevice = NULL; 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); //_dbg_assert_(SERIALINTERFACE, _iDeviceNumber < NUMBER_OF_CHANNELS);
// delete the old device // delete the old device
RemoveDevice(_iDeviceNumber); RemoveDevice(_iDeviceNumber);
// create the new one // 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) void SetNoResponse(u32 channel)

View File

@ -20,6 +20,7 @@
#include "Common.h" #include "Common.h"
#include "SI_Device.h" #include "SI_Device.h"
class PointerWrap; class PointerWrap;
class ISIDevice;
namespace SerialInterface namespace SerialInterface
{ {
@ -32,6 +33,7 @@ void UpdateDevices();
void RemoveDevice(int _iDeviceNumber); void RemoveDevice(int _iDeviceNumber);
void AddDevice(const SIDevices _device, int _iDeviceNumber); void AddDevice(const SIDevices _device, int _iDeviceNumber);
void AddDevice(ISIDevice* pDevice);
void ChangeDeviceCallback(u64 userdata, int cyclesLate); void ChangeDeviceCallback(u64 userdata, int cyclesLate);
void ChangeDevice(SIDevices device, int channel); void ChangeDevice(SIDevices device, int channel);

View File

@ -52,7 +52,7 @@ int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength)
class CSIDevice_Null : public ISIDevice class CSIDevice_Null : public ISIDevice
{ {
public: public:
CSIDevice_Null(int _iDeviceNumber) : ISIDevice(_iDeviceNumber) {} CSIDevice_Null(SIDevices device, int _iDeviceNumber) : ISIDevice(device, _iDeviceNumber) {}
virtual ~CSIDevice_Null() {} virtual ~CSIDevice_Null() {}
int RunBuffer(u8* _pBuffer, int _iLength) { int RunBuffer(u8* _pBuffer, int _iLength) {
@ -73,24 +73,24 @@ ISIDevice* SIDevice_Create(const SIDevices device, const int port_number)
switch (device) switch (device)
{ {
case SIDEVICE_GC_CONTROLLER: case SIDEVICE_GC_CONTROLLER:
return new CSIDevice_GCController(port_number); return new CSIDevice_GCController(device, port_number);
break; break;
case SIDEVICE_GC_TARUKONGA: case SIDEVICE_GC_TARUKONGA:
return new CSIDevice_TaruKonga(port_number); return new CSIDevice_TaruKonga(device, port_number);
break; break;
case SIDEVICE_GC_GBA: case SIDEVICE_GC_GBA:
return new CSIDevice_GBA(port_number); return new CSIDevice_GBA(device, port_number);
break; break;
case SIDEVICE_AM_BASEBOARD: case SIDEVICE_AM_BASEBOARD:
return new CSIDevice_AMBaseboard(port_number); return new CSIDevice_AMBaseboard(device, port_number);
break; break;
case SIDEVICE_NONE: case SIDEVICE_NONE:
default: default:
return new CSIDevice_Null(port_number); return new CSIDevice_Null(device, port_number);
break; break;
} }
} }

View File

@ -20,6 +20,8 @@
#include "Common.h" #include "Common.h"
class PointerWrap;
// Devices can reply with these // Devices can reply with these
#define SI_ERROR_NO_RESPONSE 0x0008 // Nothing is attached #define SI_ERROR_NO_RESPONSE 0x0008 // Nothing is attached
#define SI_ERROR_UNKNOWN 0x0040 // Unknown device 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_NOMOTOR 0x20000000u // No rumble motor
#define SI_GC_STANDARD 0x01000000u #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 // SI Device IDs for emulator use
enum TSIDevices enum TSIDevices
{ {
@ -88,6 +66,47 @@ enum SIDevices
SIDEVICE_AM_BASEBOARD 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); extern ISIDevice* SIDevice_Create(const SIDevices device, const int port_number);
#endif #endif

View File

@ -89,8 +89,8 @@ public:
// AM-Baseboard device on SI // AM-Baseboard device on SI
CSIDevice_AMBaseboard::CSIDevice_AMBaseboard(int _iDeviceNumber) CSIDevice_AMBaseboard::CSIDevice_AMBaseboard(SIDevices device, int _iDeviceNumber)
: ISIDevice(_iDeviceNumber) : ISIDevice(device, _iDeviceNumber)
{ {
} }

View File

@ -30,7 +30,7 @@ private:
public: public:
// constructor // constructor
CSIDevice_AMBaseboard(int _iDeviceNumber); CSIDevice_AMBaseboard(SIDevices device, int _iDeviceNumber);
// run the SI Buffer // run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength); virtual int RunBuffer(u8* _pBuffer, int _iLength);

View File

@ -135,8 +135,8 @@ void GBASockServer::Transfer(char* si_buffer)
si_buffer[i ^ 3] = current_data[i]; si_buffer[i ^ 3] = current_data[i];
} }
CSIDevice_GBA::CSIDevice_GBA(int _iDeviceNumber) CSIDevice_GBA::CSIDevice_GBA(SIDevices _device, int _iDeviceNumber)
: ISIDevice(_iDeviceNumber) : ISIDevice(_device, _iDeviceNumber)
, GBASockServer() , GBASockServer()
{ {
} }

View File

@ -48,7 +48,7 @@ private:
class CSIDevice_GBA : public ISIDevice, private GBASockServer class CSIDevice_GBA : public ISIDevice, private GBASockServer
{ {
public: public:
CSIDevice_GBA(int _iDeviceNumber); CSIDevice_GBA(SIDevices device, int _iDeviceNumber);
~CSIDevice_GBA() {} ~CSIDevice_GBA() {}
// Run the SI Buffer // Run the SI Buffer

View File

@ -35,8 +35,8 @@
#include "../Core.h" #include "../Core.h"
// --- standard gamecube controller --- // --- standard gamecube controller ---
CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) CSIDevice_GCController::CSIDevice_GCController(SIDevices device, int _iDeviceNumber)
: ISIDevice(_iDeviceNumber) : ISIDevice(device, _iDeviceNumber)
, m_TButtonComboStart(0) , m_TButtonComboStart(0)
, m_TButtonCombo(0) , m_TButtonCombo(0)
, m_LastButtonCombo(COMBO_NONE) , m_LastButtonCombo(COMBO_NONE)
@ -268,3 +268,13 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll)
break; 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);
}

View File

@ -95,7 +95,7 @@ private:
public: public:
// Constructor // Constructor
CSIDevice_GCController(int _iDeviceNumber); CSIDevice_GCController(SIDevices device, int _iDeviceNumber);
// Run the SI Buffer // Run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength); virtual int RunBuffer(u8* _pBuffer, int _iLength);
@ -109,6 +109,9 @@ public:
// Send a command directly // Send a command directly
virtual void SendCommand(u32 _Cmd, u8 _Poll); 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 class CSIDevice_TaruKonga : public CSIDevice_GCController
{ {
public: 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) virtual bool GetData(u32& _Hi, u32& _Low)
{ {