citra-emu
/
citra-canary
Archived
1
0
Fork 0

Serialize IR service

This commit is contained in:
Hamish Milne 2019-12-30 16:07:03 +00:00 committed by zhupengfei
parent 8bd3e8cd27
commit eb67167b7c
4 changed files with 64 additions and 10 deletions

2
TODO
View File

@ -85,7 +85,7 @@
☐ Fix the global weak_ptr to gsp ☐ Fix the global weak_ptr to gsp
✔ HID @done(19-12-30 14:46) ✔ HID @done(19-12-30 14:46)
✔ HTTP @done(19-12-30 15:18) ✔ HTTP @done(19-12-30 15:18)
☐ IR ✔ IR @done(19-12-30 16:06)
☐ LDR_RO ☐ LDR_RO
☐ MIC ☐ MIC
☐ MVD ☐ MVD

View File

@ -6,6 +6,8 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <boost/serialization/array.hpp>
#include <boost/serialization/export.hpp>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/frontend/input.h" #include "core/frontend/input.h"
@ -65,6 +67,16 @@ private:
std::unique_ptr<Input::ButtonDevice> zr; std::unique_ptr<Input::ButtonDevice> zr;
std::unique_ptr<Input::AnalogDevice> c_stick; std::unique_ptr<Input::AnalogDevice> c_stick;
std::atomic<bool> is_device_reload_pending; std::atomic<bool> is_device_reload_pending;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& hid_period;
ar& calibration_data; // This isn't writeable for now, but might be in future
RequestInputDevicesReload(); // zl, zr, c_stick are loaded here
}
friend class boost::serialization::access;
}; };
} // namespace Service::IR } // namespace Service::IR
BOOST_CLASS_EXPORT_KEY(Service::IR::ExtraHID)

View File

@ -15,6 +15,19 @@
namespace Service::IR { namespace Service::IR {
template <class Archive>
void IR_USER::serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
ar& conn_status_event;
ar& send_event;
ar& receive_event;
ar& shared_memory;
ar& connected_device;
ar& *receive_buffer.get();
ar& *extra_hid.get();
}
SERIALIZE_IMPL(IR_USER)
// This is a header that will present in the ir:USER shared memory if it is initialized with // This is a header that will present in the ir:USER shared memory if it is initialized with
// InitializeIrNopShared service function. Otherwise the shared memory doesn't have this header if // InitializeIrNopShared service function. Otherwise the shared memory doesn't have this header if
// it is initialized with InitializeIrNop service function. // it is initialized with InitializeIrNop service function.
@ -139,6 +152,16 @@ private:
u32_le end_index; u32_le end_index;
u32_le packet_count; u32_le packet_count;
u32_le unknown; u32_le unknown;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& begin_index;
ar& end_index;
ar& packet_count;
ar& unknown;
}
friend class boost::serialization::access;
}; };
static_assert(sizeof(BufferInfo) == 16, "BufferInfo has wrong size!"); static_assert(sizeof(BufferInfo) == 16, "BufferInfo has wrong size!");
@ -179,6 +202,18 @@ private:
u32 buffer_offset; u32 buffer_offset;
u32 max_packet_count; u32 max_packet_count;
u32 max_data_size; u32 max_data_size;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& info;
ar& shared_memory;
ar& info_offset;
ar& buffer_offset;
ar& max_packet_count;
ar& max_data_size;
}
friend class boost::serialization::access;
}; };
/// Wraps the payload into packet and puts it to the receive buffer /// Wraps the payload into packet and puts it to the receive buffer
@ -270,8 +305,8 @@ void IR_USER::RequireConnection(Kernel::HLERequestContext& ctx) {
shared_memory_ptr[offsetof(SharedMemoryHeader, connection_role)] = 2; shared_memory_ptr[offsetof(SharedMemoryHeader, connection_role)] = 2;
shared_memory_ptr[offsetof(SharedMemoryHeader, connected)] = 1; shared_memory_ptr[offsetof(SharedMemoryHeader, connected)] = 1;
connected_device = extra_hid.get(); connected_device = true;
connected_device->OnConnect(); extra_hid->OnConnect();
conn_status_event->Signal(); conn_status_event->Signal();
} else { } else {
LOG_WARNING(Service_IR, "unknown device id {}. Won't connect.", device_id); LOG_WARNING(Service_IR, "unknown device id {}. Won't connect.", device_id);
@ -305,8 +340,8 @@ void IR_USER::GetSendEvent(Kernel::HLERequestContext& ctx) {
void IR_USER::Disconnect(Kernel::HLERequestContext& ctx) { void IR_USER::Disconnect(Kernel::HLERequestContext& ctx) {
if (connected_device) { if (connected_device) {
connected_device->OnDisconnect(); extra_hid->OnDisconnect();
connected_device = nullptr; connected_device = false;
conn_status_event->Signal(); conn_status_event->Signal();
} }
@ -331,8 +366,8 @@ void IR_USER::GetConnectionStatusEvent(Kernel::HLERequestContext& ctx) {
void IR_USER::FinalizeIrNop(Kernel::HLERequestContext& ctx) { void IR_USER::FinalizeIrNop(Kernel::HLERequestContext& ctx) {
if (connected_device) { if (connected_device) {
connected_device->OnDisconnect(); extra_hid->OnDisconnect();
connected_device = nullptr; connected_device = false;
} }
shared_memory = nullptr; shared_memory = nullptr;
@ -352,7 +387,7 @@ void IR_USER::SendIrNop(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
if (connected_device) { if (connected_device) {
connected_device->OnReceive(buffer); extra_hid->OnReceive(buffer);
send_event->Signal(); send_event->Signal();
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} else { } else {
@ -424,7 +459,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) {
IR_USER::~IR_USER() { IR_USER::~IR_USER() {
if (connected_device) { if (connected_device) {
connected_device->OnDisconnect(); extra_hid->OnDisconnect();
} }
} }

View File

@ -7,6 +7,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <boost/serialization/shared_ptr.hpp>
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Kernel { namespace Kernel {
@ -45,6 +46,7 @@ protected:
void Send(const std::vector<u8>& data); void Send(const std::vector<u8>& data);
private: private:
// NOTE: This value is *not* serialized because it's always passed in the constructor
const SendFunc send_func; const SendFunc send_func;
}; };
@ -164,9 +166,14 @@ private:
std::shared_ptr<Kernel::Event> conn_status_event, send_event, receive_event; std::shared_ptr<Kernel::Event> conn_status_event, send_event, receive_event;
std::shared_ptr<Kernel::SharedMemory> shared_memory; std::shared_ptr<Kernel::SharedMemory> shared_memory;
IRDevice* connected_device{nullptr}; bool connected_device;
std::unique_ptr<BufferManager> receive_buffer; std::unique_ptr<BufferManager> receive_buffer;
std::unique_ptr<ExtraHID> extra_hid; std::unique_ptr<ExtraHID> extra_hid;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int);
friend class boost::serialization::access;
}; };
} // namespace Service::IR } // namespace Service::IR