mirror of https://github.com/PCSX2/pcsx2.git
SaveState: Partial migration to StateWrapper for USB
This commit is contained in:
parent
8abe5b42e5
commit
a8faf2eb6e
|
@ -40,6 +40,7 @@
|
|||
#include "GS.h"
|
||||
#include "GS/GS.h"
|
||||
#include "SPU2/spu2.h"
|
||||
#include "StateWrapper.h"
|
||||
#include "PAD/Gamepad.h"
|
||||
#include "USB/USB.h"
|
||||
#include "VMManager.h"
|
||||
|
@ -355,7 +356,6 @@ static int SysState_MTGSFreeze(FreezeAction mode, freezeData* fP)
|
|||
|
||||
static constexpr SysState_Component SPU2{ "SPU2", SPU2freeze };
|
||||
static constexpr SysState_Component PAD_{ "PAD", PADfreeze };
|
||||
static constexpr SysState_Component USB_{ "USB", USBfreeze };
|
||||
static constexpr SysState_Component GS{ "GS", SysState_MTGSFreeze };
|
||||
|
||||
|
||||
|
@ -404,6 +404,43 @@ static void SysState_ComponentFreezeOut(SaveStateBase& writer, SysState_Componen
|
|||
return;
|
||||
}
|
||||
|
||||
static void SysState_ComponentFreezeInNew(zip_file_t* zf, const char* name, bool(*do_state_func)(StateWrapper&))
|
||||
{
|
||||
// TODO: We could decompress on the fly here for a little bit more speed.
|
||||
std::vector<u8> data;
|
||||
if (zf)
|
||||
{
|
||||
std::optional<std::vector<u8>> optdata(ReadBinaryFileInZip(zf));
|
||||
if (optdata.has_value())
|
||||
data = std::move(optdata.value());
|
||||
}
|
||||
|
||||
StateWrapper::ReadOnlyMemoryStream stream(data.empty() ? nullptr : data.data(), data.size());
|
||||
StateWrapper sw(&stream, StateWrapper::Mode::Read, g_SaveVersion);
|
||||
|
||||
// TODO: Get rid of the bloody exceptions.
|
||||
if (!do_state_func(sw))
|
||||
throw std::runtime_error(fmt::format(" * {}: Error loading state!", name));
|
||||
}
|
||||
|
||||
static void SysState_ComponentFreezeOutNew(SaveStateBase& writer, const char* name, u32 reserve, bool (*do_state_func)(StateWrapper&))
|
||||
{
|
||||
StateWrapper::VectorMemoryStream stream(reserve);
|
||||
StateWrapper sw(&stream, StateWrapper::Mode::Write, g_SaveVersion);
|
||||
|
||||
// TODO: Get rid of the bloody exceptions.
|
||||
if (!do_state_func(sw))
|
||||
throw std::runtime_error(fmt::format(" * {}: Error saving state!", name));
|
||||
|
||||
const int size = static_cast<int>(stream.GetBuffer().size());
|
||||
if (size > 0)
|
||||
{
|
||||
writer.PrepBlock(size);
|
||||
std::memcpy(writer.GetBlockPtr(), stream.GetBuffer().data(), size);
|
||||
writer.CommitBlock(size);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// BaseSavestateEntry
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -575,8 +612,8 @@ public:
|
|||
virtual ~SavestateEntry_USB() = default;
|
||||
|
||||
const char* GetFilename() const { return "USB.bin"; }
|
||||
void FreezeIn(zip_file_t* zf) const { return SysState_ComponentFreezeIn(zf, USB_); }
|
||||
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOut(writer, USB_); }
|
||||
void FreezeIn(zip_file_t* zf) const { return SysState_ComponentFreezeInNew(zf, "USB", &USB::DoState); }
|
||||
void FreezeOut(SaveStateBase& writer) const { return SysState_ComponentFreezeOutNew(writer, "USB", 16 * 1024, &USB::DoState); }
|
||||
bool IsRequired() const { return false; }
|
||||
};
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@ public:
|
|||
VectorMemoryStream();
|
||||
VectorMemoryStream(u32 reserve);
|
||||
|
||||
const std::vector<u8>& GetBuffer() const { return m_buf; }
|
||||
|
||||
u32 Read(void* buf, u32 count) override;
|
||||
u32 Write(const void* buf, u32 count) override;
|
||||
u32 GetPosition() override;
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace USB
|
|||
static void DestroyDevice(u32 port);
|
||||
static void UpdateDevice(u32 port);
|
||||
|
||||
static void DoOHCIState(StateWrapper& sw);
|
||||
static bool DoOHCIState(StateWrapper& sw);
|
||||
static void DoEndpointState(USBEndpoint* ep, StateWrapper& sw);
|
||||
static void DoDeviceState(USBDevice* dev, StateWrapper& sw);
|
||||
static void DoPacketState(USBPacket* p, StateWrapper& sw, const std::array<bool, 2>& valid_devices);
|
||||
|
@ -199,10 +199,10 @@ void USBwrite32(u32 addr, u32 value)
|
|||
ohci_mem_write(s_qemu_ohci, addr, value);
|
||||
}
|
||||
|
||||
void USB::DoOHCIState(StateWrapper& sw)
|
||||
bool USB::DoOHCIState(StateWrapper& sw)
|
||||
{
|
||||
if (!sw.DoMarker("USBOHCI"))
|
||||
return;
|
||||
return false;
|
||||
|
||||
sw.Do(&g_usb_last_cycle);
|
||||
sw.Do(&s_usb_clocks);
|
||||
|
@ -243,6 +243,7 @@ void USB::DoOHCIState(StateWrapper& sw)
|
|||
sw.DoArray(s_qemu_ohci->usb_buf, sizeof(s_qemu_ohci->usb_buf));
|
||||
sw.Do(&s_qemu_ohci->async_td);
|
||||
sw.Do(&s_qemu_ohci->async_complete);
|
||||
return true;
|
||||
}
|
||||
|
||||
void USB::DoDeviceState(USBDevice* dev, StateWrapper& sw)
|
||||
|
@ -378,24 +379,19 @@ void USB::DoPacketState(USBPacket* p, StateWrapper& sw, const std::array<bool, 2
|
|||
}
|
||||
}
|
||||
|
||||
s32 USBfreeze(FreezeAction mode, freezeData* data)
|
||||
bool USB::DoState(StateWrapper& sw)
|
||||
{
|
||||
std::array<bool, 2> valid_devices = {};
|
||||
|
||||
if (mode == FreezeAction::Load)
|
||||
if (!sw.DoMarker("USB") || !USB::DoOHCIState(sw))
|
||||
{
|
||||
StateWrapper::ReadOnlyMemoryStream swstream(data->data, data->size);
|
||||
StateWrapper sw(&swstream, StateWrapper::Mode::Read, g_SaveVersion);
|
||||
|
||||
if (!sw.DoMarker("USB"))
|
||||
{
|
||||
Console.Error("USB state is invalid, resetting.");
|
||||
USBreset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
USB::DoOHCIState(sw);
|
||||
Console.Error("USB state is invalid, resetting.");
|
||||
USBreset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sw.IsReading())
|
||||
{
|
||||
for (u32 port = 0; port < USB::NUM_PORTS; port++)
|
||||
{
|
||||
s32 state_devtype;
|
||||
|
@ -443,21 +439,11 @@ s32 USBfreeze(FreezeAction mode, freezeData* data)
|
|||
{
|
||||
Console.WriteLn("Failed to read USB packet, resetting all devices.");
|
||||
USBreset();
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (mode == FreezeAction::Save)
|
||||
else
|
||||
{
|
||||
std::memset(data->data, 0, data->size);
|
||||
|
||||
StateWrapper::MemoryStream swstream(data->data, data->size);
|
||||
StateWrapper sw(&swstream, StateWrapper::Mode::Write, g_SaveVersion);
|
||||
|
||||
if (!sw.DoMarker("USB"))
|
||||
return -1;
|
||||
|
||||
USB::DoOHCIState(sw);
|
||||
|
||||
for (u32 port = 0; port < USB::NUM_PORTS; port++)
|
||||
{
|
||||
s32 state_devtype = EmuConfig.USB.Ports[port].DeviceType;
|
||||
|
@ -465,12 +451,12 @@ s32 USBfreeze(FreezeAction mode, freezeData* data)
|
|||
sw.Do(&state_devtype);
|
||||
sw.Do(&state_devsubtype);
|
||||
|
||||
const u32 size_pos = swstream.GetPosition();
|
||||
const u32 size_pos = sw.GetStream()->GetPosition();
|
||||
u32 state_size = 0;
|
||||
sw.Do(&state_size);
|
||||
|
||||
if (sw.HasError())
|
||||
return -1;
|
||||
return false;
|
||||
|
||||
if (!s_usb_device[port])
|
||||
{
|
||||
|
@ -478,33 +464,28 @@ s32 USBfreeze(FreezeAction mode, freezeData* data)
|
|||
continue;
|
||||
}
|
||||
|
||||
const u32 start_pos = swstream.GetPosition();
|
||||
const u32 start_pos = sw.GetStream()->GetPosition();
|
||||
USB::DoDeviceState(s_usb_device[port], sw);
|
||||
if (!s_usb_device_proxy[port]->Freeze(s_usb_device[port], sw) || sw.HasError())
|
||||
{
|
||||
Console.Error("Failed to serialize USB port %u.", port);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 end_pos = swstream.GetPosition();
|
||||
const u32 end_pos = sw.GetStream()->GetPosition();
|
||||
state_size = end_pos - start_pos;
|
||||
if (!swstream.SeekAbsolute(size_pos) || (sw.Do(&state_size), sw.HasError()) || !swstream.SeekAbsolute(end_pos))
|
||||
return -1;
|
||||
if (!sw.GetStream()->SeekAbsolute(size_pos) || (sw.Do(&state_size), sw.HasError()) || !sw.GetStream()->SeekAbsolute(end_pos))
|
||||
return false;
|
||||
|
||||
valid_devices[port] = true;
|
||||
}
|
||||
|
||||
USB::DoPacketState(&s_qemu_ohci->usb_packet, sw, valid_devices);
|
||||
if (sw.HasError())
|
||||
return -1;
|
||||
}
|
||||
else if (mode == FreezeAction::Size)
|
||||
{
|
||||
// I don't like this, but until we move everything over to state wrapper, it'll have to do.
|
||||
data->size = 0x10000;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void USBasync(u32 cycles)
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
#include "gsl/span"
|
||||
|
||||
#include "Config.h"
|
||||
#include "SaveState.h"
|
||||
|
||||
class SettingsInterface;
|
||||
class StateWrapper;
|
||||
|
||||
namespace USB
|
||||
{
|
||||
|
@ -84,6 +84,9 @@ namespace USB
|
|||
|
||||
/// Reads a device-specific configuration string.
|
||||
std::string GetConfigString(SettingsInterface& si, u32 port, const char* devname, const char* key, const char* default_value = "");
|
||||
|
||||
/// Handles loading/saving save state.
|
||||
bool DoState(StateWrapper& sw);
|
||||
} // namespace USB
|
||||
|
||||
struct WindowInfo;
|
||||
|
@ -96,7 +99,6 @@ void USBshutdown();
|
|||
void USBclose();
|
||||
bool USBopen();
|
||||
void USBreset();
|
||||
s32 USBfreeze(FreezeAction mode, freezeData* data);
|
||||
|
||||
u8 USBread8(u32 addr);
|
||||
u16 USBread16(u32 addr);
|
||||
|
|
Loading…
Reference in New Issue