diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2026-03-28 14:03:34 -0500 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2026-03-29 11:15:03 -0500 |
| commit | f103155658e1041bed914abd67327396ebf58fad (patch) | |
| tree | 007de1436683320e573f6e491463e53036b23e14 /Source/Core | |
| parent | 1ab57199e615f971732eeb0f1dd88b3a13ce94af (diff) | |
HW/GBACore: Expose the ability to run for a single frame.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/HW/GBACore.cpp | 32 | ||||
| -rw-r--r-- | Source/Core/Core/HW/GBACore.h | 18 |
2 files changed, 35 insertions, 15 deletions
diff --git a/Source/Core/Core/HW/GBACore.cpp b/Source/Core/Core/HW/GBACore.cpp index 5eaf204b21..5f2c3ff5b6 100644 --- a/Source/Core/Core/HW/GBACore.cpp +++ b/Source/Core/Core/HW/GBACore.cpp @@ -470,12 +470,20 @@ void Core::SetupEvent() m_event.priority = 0x80; } +void Core::RunFrame(u16 keys) +{ + PushEvent({ + .event_type = SyncEventType::RunFrame, + .keys = keys, + }); +} + void Core::SyncJoybus(u64 gc_ticks, u16 keys) { PushEvent({ - .run_until_ticks = gc_ticks, + .event_type = SyncEventType::TimeSync, .keys = keys, - .event_type = JoybusEventType::TimeSync, + .run_until_ticks = gc_ticks, }); } @@ -491,9 +499,9 @@ void Core::SendJoybusCommand(u64 gc_ticks, int transfer_time, u8* buffer, u16 ke m_command_pending.store(true, std::memory_order_relaxed); PushEvent({ - .run_until_ticks = gc_ticks, + .event_type = SyncEventType::RunCommand, .keys = keys, - .event_type = JoybusEventType::RunCommand, + .run_until_ticks = gc_ticks, }); } @@ -510,7 +518,7 @@ void Core::Flush() m_event_thread.WaitForCompletion(); } -void Core::PushEvent(JoybusEvent event) +void Core::PushEvent(SyncEvent event) { if (m_event_thread.IsRunning()) m_event_thread.Push(event); @@ -518,12 +526,22 @@ void Core::PushEvent(JoybusEvent event) HandleEvent(event); } -void Core::HandleEvent(JoybusEvent event) +void Core::HandleEvent(SyncEvent event) { m_keys = event.keys; + + if (event.event_type == SyncEventType::RunFrame) + { + m_last_gc_ticks = m_system.GetCoreTiming().GetTicks(); + m_gc_ticks_remainder = 0; + + m_core->runFrame(m_core); + return; + } + RunUntil(event.run_until_ticks); - if (event.event_type != JoybusEventType::RunCommand) + if (event.event_type != SyncEventType::RunCommand) return; if (m_link_enabled && !m_force_disconnect) diff --git a/Source/Core/Core/HW/GBACore.h b/Source/Core/Core/HW/GBACore.h index 64f61a0eb7..110b79a16a 100644 --- a/Source/Core/Core/HW/GBACore.h +++ b/Source/Core/Core/HW/GBACore.h @@ -72,6 +72,7 @@ public: void SetForceDisconnect(bool force_disconnect); void EReaderQueueCard(std::string_view card_path); + void RunFrame(u16 keys); void SyncJoybus(u64 gc_ticks, u16 keys); void SendJoybusCommand(u64 gc_ticks, int transfer_time, u8* buffer, u16 keys); int GetJoybusResponse(u8* data_out); @@ -90,19 +91,20 @@ private: void RunFor(u64 gc_ticks); void Flush(); - enum class JoybusEventType : u8 + enum class SyncEventType : u8 { TimeSync, RunCommand, + RunFrame, }; - struct JoybusEvent + struct SyncEvent { - u64 run_until_ticks{}; + SyncEventType event_type{}; u16 keys{}; - JoybusEventType event_type{}; + u64 run_until_ticks{}; // Not used by SyncEventType::RunFrame. }; - void PushEvent(JoybusEvent event); - void HandleEvent(JoybusEvent event); + void PushEvent(SyncEvent event); + void HandleEvent(SyncEvent event); bool LoadBIOS(const char* bios_path); bool LoadSave(const char* save_path); @@ -137,7 +139,7 @@ private: std::weak_ptr<GBAHostInterface> m_host; - // Set by the GC thread before issuing a JoybusEventType::RunCommand. + // Set by the GC thread before issuing a SyncEventType::RunCommand. int m_joybus_command_transfer_time{}; GBASIOJOYCommand m_joybus_command{}; @@ -149,7 +151,7 @@ private: std::atomic_bool m_command_pending{}; // The entire threaded GBA runs within events pushed to this queue. - Common::WorkQueueThreadSP<JoybusEvent> m_event_thread; + Common::WorkQueueThreadSP<SyncEvent> m_event_thread; ::Core::System& m_system; }; |
