SI: Allow devices to schedule events

This commit is contained in:
Bonta 2021-07-04 12:44:02 +02:00
parent 44aaf108d1
commit 1b27f22cbc
4 changed files with 47 additions and 3 deletions

View File

@ -209,6 +209,7 @@ union USIEXIClockCount
static CoreTiming::EventType* s_change_device_event;
static CoreTiming::EventType* s_tranfer_pending_event;
static std::array<CoreTiming::EventType*, MAX_SI_CHANNELS> s_device_events;
// User-configured device type. possibly overridden by TAS/Netplay
static std::array<std::atomic<SIDevices>, MAX_SI_CHANNELS> s_desired_device_types;
@ -369,8 +370,44 @@ void DoState(PointerWrap& p)
p.Do(s_si_buffer);
}
template <int device_number>
static void DeviceEventCallback(u64 userdata, s64 cyclesLate)
{
s_channel[device_number].device->OnEvent(userdata, cyclesLate);
}
static void RegisterEvents()
{
s_change_device_event = CoreTiming::RegisterEvent("ChangeSIDevice", ChangeDeviceCallback);
s_tranfer_pending_event = CoreTiming::RegisterEvent("SITransferPending", RunSIBuffer);
constexpr std::array<CoreTiming::TimedCallback, MAX_SI_CHANNELS> event_callbacks = {
DeviceEventCallback<0>,
DeviceEventCallback<1>,
DeviceEventCallback<2>,
DeviceEventCallback<3>,
};
for (int i = 0; i < MAX_SI_CHANNELS; ++i)
{
s_device_events[i] =
CoreTiming::RegisterEvent(fmt::format("SIEventChannel{}", i), event_callbacks[i]);
}
}
void ScheduleEvent(int device_number, s64 cycles_into_future, u64 userdata)
{
CoreTiming::ScheduleEvent(cycles_into_future, s_device_events[device_number], userdata);
}
void RemoveEvent(int device_number)
{
CoreTiming::RemoveEvent(s_device_events[device_number]);
}
void Init()
{
RegisterEvents();
for (int i = 0; i < MAX_SI_CHANNELS; i++)
{
s_channel[i].out.hex = 0;
@ -415,9 +452,6 @@ void Init()
// s_exi_clock_count.LOCK = 1;
s_si_buffer = {};
s_change_device_event = CoreTiming::RegisterEvent("ChangeSIDevice", ChangeDeviceCallback);
s_tranfer_pending_event = CoreTiming::RegisterEvent("SITransferPending", RunSIBuffer);
}
void Shutdown()

View File

@ -30,6 +30,9 @@ void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void ScheduleEvent(int device_number, s64 cycles_into_future, u64 userdata = 0);
void RemoveEvent(int device_number);
void UpdateDevices();
void RemoveDevice(int device_number);

View File

@ -97,6 +97,10 @@ void ISIDevice::DoState(PointerWrap& p)
{
}
void ISIDevice::OnEvent(u64 userdata, s64 cycles_late)
{
}
// Check if a device class is inheriting from CSIDevice_GCController
// The goal of this function is to avoid special casing a long list of
// device types when there is no "real" input device, e.g. when playing

View File

@ -88,6 +88,9 @@ public:
// Savestate support
virtual void DoState(PointerWrap& p);
// Schedulable event
virtual void OnEvent(u64 userdata, s64 cycles_late);
protected:
int m_device_number;
SIDevices m_device_type;