IR: Move to scheduler

This commit is contained in:
wheremyfoodat 2025-07-03 02:42:43 +03:00
parent b2904f391f
commit dc7f8a48bd
7 changed files with 29 additions and 14 deletions

View file

@ -7,15 +7,20 @@
using namespace IR;
void CirclePadPro::connect() {}
void CirclePadPro::disconnect() {}
void CirclePadPro::disconnect() { scheduler.removeEvent(Scheduler::EventType::UpdateIR); }
void CirclePadPro::receivePayload(Payload payload) {
const u8 type = payload[0];
switch (type) {
case CPPRequestID::ConfigurePolling: {
[[maybe_unused]] const u8 pollingPeriodMs = payload[1];
// TODO
// Convert polling period from ms to ns for easier use with the scheduler
const s64 periodNs = s64(payload[1]) * 1000ll;
// Convert to cycles
period = Scheduler::nsToCycles(periodNs);
scheduler.removeEvent(Scheduler::EventType::UpdateIR);
scheduler.addEvent(Scheduler::EventType::UpdateIR, scheduler.currentTimestamp + period);
break;
}

View file

@ -28,6 +28,9 @@ namespace IRUserCommands {
};
}
IRUserService::IRUserService(Memory& mem, HIDService& hid, const EmulatorConfig& config, Kernel& kernel)
: mem(mem), hid(hid), config(config), kernel(kernel), cpp([&](IR::Device::Payload payload) { sendPayload(payload); }, kernel.getScheduler()) {}
void IRUserService::reset() {
connectionStatusEvent = std::nullopt;
receiveEvent = std::nullopt;
@ -285,7 +288,7 @@ void IRUserService::clearSendBuffer(u32 messagePointer) {
mem.write32(messagePointer + 4, Result::Success);
}
void IRUserService::sendPayload(std::span<const u8> payload) {
void IRUserService::sendPayload(IRUserService::Payload payload) {
if (!receiveBuffer) {
return;
}
@ -343,4 +346,8 @@ void IRUserService::updateCirclePadPro() {
std::vector<u8> response(sizeof(cppState));
std::memcpy(response.data(), &cppState, sizeof(cppState));
sendPayload(response);
// Schedule next IR event. TODO: Maybe account for cycle drift.
auto& scheduler = kernel.getScheduler();
scheduler.addEvent(Scheduler::EventType::UpdateIR, scheduler.currentTimestamp + cpp.period);
}

View file

@ -139,8 +139,6 @@ void Emulator::runFrame() {
if (cheats.haveCheats()) [[unlikely]] {
cheats.run();
}
getServiceManager().getIRUser().updateCirclePadPro();
} else if (romType != ROMType::None) {
// If the emulator is not running and a game is loaded, we still want to display the framebuffer otherwise we will get weird
// double-buffering issues
@ -182,6 +180,7 @@ void Emulator::pollScheduler() {
}
case Scheduler::EventType::SignalY2R: kernel.getServiceManager().getY2R().signalConversionDone(); break;
case Scheduler::EventType::UpdateIR: kernel.getServiceManager().getIRUser().updateCirclePadPro(); break;
default: {
Helpers::panic("Scheduler: Unimplemented event type received: %d\n", static_cast<int>(eventType));