From d0dd51a23567d271bd4a0db7e8a8c938b58b7676 Mon Sep 17 00:00:00 2001 From: Jean-Philip Desjardins Date: Tue, 18 Jun 2024 17:00:13 -0400 Subject: [PATCH] Save/load buzzer state. --- Source/PadHandler.cpp | 9 +++++++-- Source/PadHandler.h | 6 ++---- Source/iop/Iop_Usbd.cpp | 37 ++++++++++++++++++++++++++++++++++ Source/iop/Iop_Usbd.h | 3 +++ Source/iop/UsbBuzzerDevice.cpp | 33 ++++++++++++++++++++++++++++++ Source/iop/UsbBuzzerDevice.h | 3 +++ Source/iop/UsbDevice.h | 5 +++++ 7 files changed, 90 insertions(+), 6 deletions(-) diff --git a/Source/PadHandler.cpp b/Source/PadHandler.cpp index c3309a792..42b0064a7 100644 --- a/Source/PadHandler.cpp +++ b/Source/PadHandler.cpp @@ -1,8 +1,13 @@ #include "PadHandler.h" -void CPadHandler::InsertListener(CPadInterface* pListener) +void CPadHandler::InsertListener(CPadInterface* listener) { - m_interfaces.push_back(pListener); + m_interfaces.push_back(listener); +} + +bool CPadHandler::HasListener(CPadInterface* listener) const +{ + return std::find(m_interfaces.begin(), m_interfaces.end(), listener) != m_interfaces.end(); } void CPadHandler::RemoveAllListeners() diff --git a/Source/PadHandler.h b/Source/PadHandler.h index 60099fb99..6afdfdb95 100644 --- a/Source/PadHandler.h +++ b/Source/PadHandler.h @@ -1,5 +1,4 @@ -#ifndef _PADHANDLER_H_ -#define _PADHANDLER_H_ +#pragma once #include "PadInterface.h" #include @@ -14,11 +13,10 @@ public: virtual ~CPadHandler() = default; virtual void Update(uint8*) = 0; void InsertListener(CPadInterface*); + bool HasListener(CPadInterface*) const; void RemoveAllListeners(); protected: typedef std::list ListenerList; ListenerList m_interfaces; }; - -#endif diff --git a/Source/iop/Iop_Usbd.cpp b/Source/iop/Iop_Usbd.cpp index 41c88099c..9edc3c51f 100644 --- a/Source/iop/Iop_Usbd.cpp +++ b/Source/iop/Iop_Usbd.cpp @@ -1,12 +1,17 @@ #include "Iop_Usbd.h" #include "IopBios.h" #include "../Log.h" +#include "string_format.h" +#include "lexical_cast_ex.h" #include "UsbBuzzerDevice.h" +#include "states/RegisterStateCollectionFile.h" using namespace Iop; #define LOG_NAME "iop_usbd" +#define STATE_XML ("iop_usbd/state.xml") + #define FUNCTION_REGISTERLLD "RegisterLld" #define FUNCTION_SCANSTATICDESCRIPTOR "ScanStaticDescriptor" #define FUNCTION_OPENPIPE "OpenPipe" @@ -83,6 +88,38 @@ void CUsbd::Invoke(CMIPS& context, unsigned int functionId) } } +void CUsbd::SaveState(Framework::CZipArchiveWriter& writer) const +{ + auto devicesStateFile = std::make_unique(STATE_XML); + for(auto activeDeviceId : m_activeDeviceIds) + { + auto devicePairIterator = m_devices.find(activeDeviceId); + assert(devicePairIterator != m_devices.end()); + auto& device = devicePairIterator->second; + auto deviceStateId = string_format("%08x", device->GetId()); + CRegisterState deviceState; + device->SaveState(deviceState); + devicesStateFile->InsertRegisterState(deviceStateId.c_str(), std::move(deviceState)); + } + writer.InsertFile(std::move(devicesStateFile)); +} + +void CUsbd::LoadState(Framework::CZipArchiveReader& reader) +{ + m_activeDeviceIds.clear(); + auto deviceStateFile = CRegisterStateCollectionFile(*reader.BeginReadFile(STATE_XML)); + for(const auto& deviceStatePair : deviceStateFile) + { + uint32 deviceId = lexical_cast_hex(deviceStatePair.first); + auto devicePairIterator = m_devices.find(deviceId); + if(devicePairIterator == std::end(m_devices)) continue; + const auto& deviceState = deviceStatePair.second; + auto& device = devicePairIterator->second; + device->LoadState(deviceState); + m_activeDeviceIds.push_back(deviceId); + } +} + void CUsbd::CountTicks(uint32 ticks) { for(auto activeDeviceId : m_activeDeviceIds) diff --git a/Source/iop/Iop_Usbd.h b/Source/iop/Iop_Usbd.h index b0deafa8d..3892c4837 100644 --- a/Source/iop/Iop_Usbd.h +++ b/Source/iop/Iop_Usbd.h @@ -17,6 +17,9 @@ namespace Iop std::string GetFunctionName(unsigned int) const override; void Invoke(CMIPS&, unsigned int) override; + void SaveState(Framework::CZipArchiveWriter&) const override; + void LoadState(Framework::CZipArchiveReader&) override; + void CountTicks(uint32); template diff --git a/Source/iop/UsbBuzzerDevice.cpp b/Source/iop/UsbBuzzerDevice.cpp index ffc718a51..68385100a 100644 --- a/Source/iop/UsbBuzzerDevice.cpp +++ b/Source/iop/UsbBuzzerDevice.cpp @@ -3,15 +3,48 @@ #include "IopBios.h" #include "PadHandler.h" #include "Ps2Const.h" +#include "states/RegisterState.h" using namespace Iop; +#define STATE_REG_DESCRIPTORMEMPTR ("descriptorMemPtr") +#define STATE_REG_NEXTTRANSFERTICKS ("nextTransferTicks") +#define STATE_REG_TRANSFERBUFFERPTR ("transferBufferPtr") +#define STATE_REG_TRANSFERSIZE ("transferSize") +#define STATE_REG_TRANSFERCB ("transferCb") +#define STATE_REG_TRANSFERCBARG ("transferCbArg") + CBuzzerUsbDevice::CBuzzerUsbDevice(CIopBios& bios, uint8* ram) : m_bios(bios) , m_ram(ram) { } +void CBuzzerUsbDevice::SaveState(CRegisterState& state) const +{ + state.SetRegister32(STATE_REG_DESCRIPTORMEMPTR, m_descriptorMemPtr); + state.SetRegister32(STATE_REG_NEXTTRANSFERTICKS, m_nextTransferTicks); + state.SetRegister32(STATE_REG_TRANSFERBUFFERPTR, m_transferBufferPtr); + state.SetRegister32(STATE_REG_TRANSFERSIZE, m_transferSize); + state.SetRegister32(STATE_REG_TRANSFERCB, m_transferCb); + state.SetRegister32(STATE_REG_TRANSFERCBARG, m_transferCbArg); +} + +void CBuzzerUsbDevice::LoadState(const CRegisterState& state) +{ + m_descriptorMemPtr = state.GetRegister32(STATE_REG_DESCRIPTORMEMPTR); + m_nextTransferTicks = state.GetRegister32(STATE_REG_NEXTTRANSFERTICKS); + m_transferBufferPtr = state.GetRegister32(STATE_REG_TRANSFERBUFFERPTR); + m_transferSize = state.GetRegister32(STATE_REG_TRANSFERSIZE); + m_transferCb = state.GetRegister32(STATE_REG_TRANSFERCB); + m_transferCbArg = state.GetRegister32(STATE_REG_TRANSFERCBARG); + + if(!m_padHandler->HasListener(this)) + { + m_padHandler->InsertListener(this); + } +} + void CBuzzerUsbDevice::SetPadHandler(CPadHandler* padHandler) { m_padHandler = padHandler; diff --git a/Source/iop/UsbBuzzerDevice.h b/Source/iop/UsbBuzzerDevice.h index a78b47cbe..21b045fcd 100644 --- a/Source/iop/UsbBuzzerDevice.h +++ b/Source/iop/UsbBuzzerDevice.h @@ -25,6 +25,9 @@ namespace Iop uint16 GetId() const override; const char* GetLldName() const override; + void SaveState(CRegisterState&) const override; + void LoadState(const CRegisterState&); + void CountTicks(uint32) override; void OnLldRegistered() override; diff --git a/Source/iop/UsbDevice.h b/Source/iop/UsbDevice.h index 4d72543bf..b2fc1202a 100644 --- a/Source/iop/UsbDevice.h +++ b/Source/iop/UsbDevice.h @@ -3,6 +3,8 @@ #include "Types.h" #include +class CRegisterState; + namespace Iop { class CUsbDevice @@ -13,6 +15,9 @@ namespace Iop virtual uint16 GetId() const = 0; virtual const char* GetLldName() const = 0; + virtual void SaveState(CRegisterState&) const {}; + virtual void LoadState(const CRegisterState&){}; + virtual void CountTicks(uint32) = 0; virtual void OnLldRegistered() = 0;