mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-09-09 20:06:17 -05:00
Merge pull request #14542 from jordan-woyak/gbacore-things
HW/GBACore: Improvements.
This commit is contained in:
@@ -5,9 +5,6 @@
|
||||
|
||||
#include "Core/HW/GBACore.h"
|
||||
|
||||
#define PYCPARSE // Remove static functions from the header
|
||||
#include <mgba/core/interface.h>
|
||||
#undef PYCPARSE
|
||||
#include <mgba-util/vfs.h>
|
||||
#include <mgba/core/log.h>
|
||||
#include <mgba/core/timing.h>
|
||||
@@ -163,11 +160,23 @@ Core::Core(::Core::System& system, int device_number)
|
||||
: m_device_number(device_number), m_system(system)
|
||||
{
|
||||
mLogSetDefaultLogger(&s_stub_logger);
|
||||
|
||||
MutexInit(&m_core_sync.videoFrameMutex);
|
||||
ConditionInit(&m_core_sync.videoFrameAvailableCond);
|
||||
ConditionInit(&m_core_sync.videoFrameRequiredCond);
|
||||
ConditionInit(&m_core_sync.audioRequiredCond);
|
||||
MutexInit(&m_core_sync.audioBufferMutex);
|
||||
}
|
||||
|
||||
Core::~Core()
|
||||
{
|
||||
Stop();
|
||||
|
||||
MutexDeinit(&m_core_sync.videoFrameMutex);
|
||||
ConditionDeinit(&m_core_sync.videoFrameAvailableCond);
|
||||
ConditionDeinit(&m_core_sync.videoFrameRequiredCond);
|
||||
ConditionDeinit(&m_core_sync.audioRequiredCond);
|
||||
MutexDeinit(&m_core_sync.audioBufferMutex);
|
||||
}
|
||||
|
||||
bool Core::Start(u64 gc_ticks)
|
||||
@@ -258,6 +267,8 @@ bool Core::Start(u64 gc_ticks)
|
||||
AddCallbacks();
|
||||
SetupEvent();
|
||||
|
||||
m_core->setSync(m_core, &m_core_sync);
|
||||
|
||||
m_core->reset(m_core);
|
||||
m_started = true;
|
||||
start_guard.Dismiss();
|
||||
@@ -450,34 +461,43 @@ void Core::AddCallbacks()
|
||||
m_core->addCoreCallbacks(m_core, &callbacks);
|
||||
}
|
||||
|
||||
static void ReadAudioBufferIntoMixer(mAudioBuffer* audio_buffer, Mixer* mixer,
|
||||
std::size_t device_number)
|
||||
{
|
||||
std::array<s16, AUDIO_BUFFER_SIZE> sample_buffer;
|
||||
const auto read_size = sample_buffer.size() / audio_buffer->channels;
|
||||
while (true)
|
||||
{
|
||||
const auto sample_count = mAudioBufferRead(audio_buffer, sample_buffer.data(), read_size);
|
||||
if (sample_count == 0)
|
||||
break;
|
||||
mixer->PushGBASamples(device_number, sample_buffer.data(), sample_count);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::SetAVStream()
|
||||
{
|
||||
m_stream = {};
|
||||
m_stream.core = this;
|
||||
m_stream.videoDimensionsChanged = [](mAVStream* stream, unsigned width, unsigned height) {
|
||||
auto core = static_cast<AVStream*>(stream)->core;
|
||||
m_stream = {
|
||||
.core = this,
|
||||
.mixer = m_system.GetSoundStream()->GetMixer(),
|
||||
};
|
||||
|
||||
m_stream.videoDimensionsChanged = [](mAVStream* stream, unsigned /*width*/, unsigned /*height*/) {
|
||||
auto* core = static_cast<AVStream*>(stream)->core;
|
||||
core->SetVideoBuffer();
|
||||
};
|
||||
m_stream.audioRateChanged = [](mAVStream* stream, unsigned rate) {
|
||||
auto* core = static_cast<AVStream*>(stream)->core;
|
||||
auto* const sound_stream = core->m_system.GetSoundStream();
|
||||
sound_stream->GetMixer()->SetGBAInputSampleRate(core->m_device_number, rate);
|
||||
auto* const av_stream = static_cast<AVStream*>(stream);
|
||||
auto* const core = av_stream->core;
|
||||
auto* const audio_buffer = core->GetAudioBuffer();
|
||||
ReadAudioBufferIntoMixer(audio_buffer, av_stream->mixer, av_stream->core->m_device_number);
|
||||
av_stream->mixer->SetGBAInputSampleRate(core->m_device_number, rate);
|
||||
};
|
||||
m_stream.postAudioBuffer = [](mAVStream* stream, mAudioBuffer* audio_buffer) {
|
||||
size_t sample_count = mAudioBufferAvailable(audio_buffer);
|
||||
const size_t required_buffer_size = sample_count * audio_buffer->channels;
|
||||
|
||||
auto* const av_stream = static_cast<AVStream*>(stream);
|
||||
if (required_buffer_size > av_stream->sample_buffer.size())
|
||||
av_stream->sample_buffer.reset(required_buffer_size);
|
||||
|
||||
sample_count = mAudioBufferRead(audio_buffer, av_stream->sample_buffer.data(), sample_count);
|
||||
|
||||
auto* const core = av_stream->core;
|
||||
auto* const sound_stream = core->m_system.GetSoundStream();
|
||||
sound_stream->GetMixer()->PushGBASamples(core->m_device_number, av_stream->sample_buffer.data(),
|
||||
sample_count);
|
||||
ReadAudioBufferIntoMixer(audio_buffer, av_stream->mixer, av_stream->core->m_device_number);
|
||||
};
|
||||
|
||||
m_core->setAVStream(m_core, &m_stream);
|
||||
}
|
||||
|
||||
@@ -485,12 +505,8 @@ void Core::SetupEvent()
|
||||
{
|
||||
m_event.context = this;
|
||||
m_event.name = "Dolphin Sync";
|
||||
m_event.callback = [](mTiming* timing, void* context, u32 cycles_late) {
|
||||
Core* core = static_cast<Core*>(context);
|
||||
if (core->m_core->platform(core->m_core) == mPLATFORM_GBA)
|
||||
static_cast<::GBA*>(core->m_core->board)->earlyExit = true;
|
||||
else if (core->m_core->platform(core->m_core) == mPLATFORM_GB)
|
||||
static_cast<::GB*>(core->m_core->board)->earlyExit = true;
|
||||
m_event.callback = [](mTiming* /*timing*/, void* context, u32 /*cycles_late*/) {
|
||||
auto* const core = static_cast<Core*>(context);
|
||||
core->m_waiting_for_event = false;
|
||||
};
|
||||
m_event.priority = 0x80;
|
||||
|
||||
@@ -12,18 +12,22 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#define PYCPARSE // Remove static functions from the header
|
||||
#include <mgba/core/interface.h>
|
||||
#undef PYCPARSE
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/interface.h>
|
||||
#if !defined(_WIN32)
|
||||
#define USE_PTHREADS // Required for Mutex/Condition in mCoreSync.
|
||||
#endif
|
||||
#include <mgba/core/sync.h>
|
||||
#undef USE_PTHREADS
|
||||
#include <mgba/gba/interface.h>
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/WorkQueueThread.h"
|
||||
|
||||
class GBAHostInterface;
|
||||
class Mixer;
|
||||
class PointerWrap;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class System;
|
||||
@@ -31,15 +35,18 @@ class System;
|
||||
|
||||
namespace HW::GBA
|
||||
{
|
||||
|
||||
class Core;
|
||||
|
||||
struct SIODriver : GBASIODriver
|
||||
{
|
||||
Core* core;
|
||||
};
|
||||
|
||||
struct AVStream : mAVStream
|
||||
{
|
||||
Core* core;
|
||||
Common::UniqueBuffer<s16> sample_buffer;
|
||||
Mixer* mixer;
|
||||
};
|
||||
|
||||
struct CoreInfo
|
||||
@@ -134,6 +141,7 @@ private:
|
||||
std::string m_game_title;
|
||||
|
||||
mCore* m_core{};
|
||||
mCoreSync m_core_sync{};
|
||||
mTimingEvent m_event{};
|
||||
bool m_waiting_for_event = false;
|
||||
SIODriver m_sio_driver{};
|
||||
@@ -164,5 +172,7 @@ private:
|
||||
|
||||
::Core::System& m_system;
|
||||
};
|
||||
|
||||
} // namespace HW::GBA
|
||||
|
||||
#endif // HAS_LIBMGBA
|
||||
|
||||
Reference in New Issue
Block a user