diff --git a/TODO b/TODO index f72330fd1..b679a5168 100644 --- a/TODO +++ b/TODO @@ -85,7 +85,7 @@ ☐ Fix the global weak_ptr to gsp ✔ HID @done(19-12-30 14:46) ✔ HTTP @done(19-12-30 15:18) - ☐ IR + ✔ IR @done(19-12-30 16:06) ☐ LDR_RO ☐ MIC ☐ MVD diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index d21cb393f..7924a1e12 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/bit_field.h" #include "common/swap.h" #include "core/frontend/input.h" @@ -65,6 +67,16 @@ private: std::unique_ptr zr; std::unique_ptr c_stick; std::atomic is_device_reload_pending; + + template + 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 + +BOOST_CLASS_EXPORT_KEY(Service::IR::ExtraHID) diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index d392c1983..fd6c1b905 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -15,6 +15,19 @@ namespace Service::IR { +template +void IR_USER::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*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 // InitializeIrNopShared service function. Otherwise the shared memory doesn't have this header if // it is initialized with InitializeIrNop service function. @@ -139,6 +152,16 @@ private: u32_le end_index; u32_le packet_count; u32_le unknown; + + private: + template + 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!"); @@ -179,6 +202,18 @@ private: u32 buffer_offset; u32 max_packet_count; u32 max_data_size; + +private: + template + 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 @@ -270,8 +305,8 @@ void IR_USER::RequireConnection(Kernel::HLERequestContext& ctx) { shared_memory_ptr[offsetof(SharedMemoryHeader, connection_role)] = 2; shared_memory_ptr[offsetof(SharedMemoryHeader, connected)] = 1; - connected_device = extra_hid.get(); - connected_device->OnConnect(); + connected_device = true; + extra_hid->OnConnect(); conn_status_event->Signal(); } else { 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) { if (connected_device) { - connected_device->OnDisconnect(); - connected_device = nullptr; + extra_hid->OnDisconnect(); + connected_device = false; conn_status_event->Signal(); } @@ -331,8 +366,8 @@ void IR_USER::GetConnectionStatusEvent(Kernel::HLERequestContext& ctx) { void IR_USER::FinalizeIrNop(Kernel::HLERequestContext& ctx) { if (connected_device) { - connected_device->OnDisconnect(); - connected_device = nullptr; + extra_hid->OnDisconnect(); + connected_device = false; } shared_memory = nullptr; @@ -352,7 +387,7 @@ void IR_USER::SendIrNop(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); if (connected_device) { - connected_device->OnReceive(buffer); + extra_hid->OnReceive(buffer); send_event->Signal(); rb.Push(RESULT_SUCCESS); } else { @@ -424,7 +459,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) { IR_USER::~IR_USER() { if (connected_device) { - connected_device->OnDisconnect(); + extra_hid->OnDisconnect(); } } diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h index 54a4f3e08..75bbeb779 100644 --- a/src/core/hle/service/ir/ir_user.h +++ b/src/core/hle/service/ir/ir_user.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "core/hle/service/service.h" namespace Kernel { @@ -45,6 +46,7 @@ protected: void Send(const std::vector& data); private: + // NOTE: This value is *not* serialized because it's always passed in the constructor const SendFunc send_func; }; @@ -164,9 +166,14 @@ private: std::shared_ptr conn_status_event, send_event, receive_event; std::shared_ptr shared_memory; - IRDevice* connected_device{nullptr}; + bool connected_device; std::unique_ptr receive_buffer; std::unique_ptr extra_hid; + +private: + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::IR