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)
{
// 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)

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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

View File

@ -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)
{
}

View File

@ -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);

View File

@ -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()
{
}

View File

@ -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

View File

@ -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)
@ -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);
}

View File

@ -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)
{