diff --git a/CMakeLists.txt b/CMakeLists.txt index da1a9eec10..2fa3769f8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -756,7 +756,7 @@ if(NOT ENABLE_QT) set(USE_MGBA 0) endif() if(USE_MGBA) - dolphin_find_optional_system_library(LIBMGBA Externals/mGBA) + dolphin_find_optional_system_library(LIBMGBA Externals/mGBA 0.11) endif() find_package(SYSTEMD) diff --git a/Externals/mGBA/CMakeLists.txt b/Externals/mGBA/CMakeLists.txt index f48231e352..122e484b2d 100644 --- a/Externals/mGBA/CMakeLists.txt +++ b/Externals/mGBA/CMakeLists.txt @@ -3,7 +3,7 @@ set(USE_LZMA ON) add_subdirectory(mgba EXCLUDE_FROM_ALL) dolphin_disable_warnings(mgba) -target_compile_definitions(mgba PUBLIC HAVE_CRC32) +target_compile_definitions(mgba PUBLIC HAVE_CRC32 ENABLE_VFS ENABLE_DIRECTORIES) target_link_libraries(mgba ZLIB::ZLIB) if(NOT MSVC) diff --git a/Externals/mGBA/exports.props b/Externals/mGBA/exports.props index 34e6c4f02d..ddc8446c6d 100644 --- a/Externals/mGBA/exports.props +++ b/Externals/mGBA/exports.props @@ -3,6 +3,7 @@ $(ExternalsDir)mGBA\mgba\include;%(AdditionalIncludeDirectories) + ENABLE_VFS;ENABLE_DIRECTORIES;%(PreprocessorDefinitions) diff --git a/Externals/mGBA/mgba b/Externals/mGBA/mgba index 8739b22fbc..0b40863f64 160000 --- a/Externals/mGBA/mgba +++ b/Externals/mGBA/mgba @@ -1 +1 @@ -Subproject commit 8739b22fbc90fdf0b4f6612ef9c0520f0ba44a51 +Subproject commit 0b40863f64d0940f333fa1c638e75f86f8a26a33 diff --git a/Externals/mGBA/mgba.vcxproj b/Externals/mGBA/mgba.vcxproj index d1235246e3..026b9b9267 100644 --- a/Externals/mGBA/mgba.vcxproj +++ b/Externals/mGBA/mgba.vcxproj @@ -18,7 +18,7 @@ mgba\include;mgba\src;mgba\src\third-party\lzma;%(AdditionalIncludeDirectories) - BUILD_STATIC;M_CORE_GB;M_CORE_GBA;USE_LZMA;_7ZIP_PPMD_SUPPPORT;HAVE_STRDUP;HAVE_SETLOCALE;HAVE_CHMOD;HAVE_UMASK;HAVE_CRC32;%(PreprocessorDefinitions) + BUILD_STATIC;M_CORE_GB;M_CORE_GBA;USE_LZMA;_7ZIP_PPMD_SUPPPORT;HAVE_STRDUP;HAVE_SETLOCALE;HAVE_CHMOD;HAVE_UMASK;HAVE_CRC32;ENABLE_VFS;ENABLE_VFS_FD;ENABLE_DIRECTORIES;%(PreprocessorDefinitions) "$(CScript)" /nologo /E:JScript "make_version.c.js" @@ -67,7 +67,9 @@ - + + $(IntDir)obj2\ + @@ -95,6 +97,7 @@ + $(IntDir)obj3\ @@ -138,13 +141,14 @@ $(IntDir)obj2\ - $(IntDir)obj2\ $(IntDir)obj2\ + + @@ -153,6 +157,9 @@ + + + @@ -177,7 +184,6 @@ $(IntDir)obj3\ - @@ -206,7 +212,6 @@ $(IntDir)obj3\ - diff --git a/Source/Core/Core/HW/GBACore.cpp b/Source/Core/Core/HW/GBACore.cpp index b25414f3b1..272b458fc5 100644 --- a/Source/Core/Core/HW/GBACore.cpp +++ b/Source/Core/Core/HW/GBACore.cpp @@ -9,19 +9,19 @@ #include #undef PYCPARSE #include -#include #include #include #include #include + #include #include #include #include #include "AudioCommon/AudioCommon.h" + #include "Common/ChunkFile.h" -#include "Common/CommonPaths.h" #include "Common/CommonTypes.h" #include "Common/Config/Config.h" #include "Common/Crypto/SHA1.h" @@ -30,6 +30,7 @@ #include "Common/MinizipUtil.h" #include "Common/ScopeGuard.h" #include "Common/Thread.h" + #include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" @@ -46,8 +47,7 @@ mLogger s_stub_logger = { [](mLogger*, int category, mLogLevel level, const char* format, va_list args) {}, nullptr}; } // namespace -constexpr auto SAMPLES = 512; -constexpr auto SAMPLE_RATE = 48000; +constexpr size_t AUDIO_BUFFER_SIZE = 512; // libmGBA does not return the correct frequency for some GB models static u32 GetCoreFrequency(mCore* core) @@ -225,9 +225,9 @@ bool Core::Start(u64 gc_ticks) } rom_guard.Dismiss(); - std::array game_title{}; - m_core->getGameTitle(m_core, game_title.data()); - m_game_title = game_title.data(); + mGameInfo info; + m_core->getGameInfo(m_core, &info); + m_game_title = info.title; m_save_path = NetPlay::IsNetPlayRunning() ? NetPlay::GetGBASavePath(m_device_number) : GetSavePath(m_rom_path, m_device_number); @@ -241,7 +241,7 @@ bool Core::Start(u64 gc_ticks) SetSIODriver(); SetVideoBuffer(); - SetSampleRates(); + SetAudioBufferSize(); AddCallbacks(); SetAVStream(); SetupEvent(); @@ -386,18 +386,19 @@ void Core::SetSIODriver() if (m_core->platform(m_core) != mPLATFORM_GBA) return; - GBASIOJOYCreate(&m_sio_driver); - GBASIOSetDriver(&static_cast<::GBA*>(m_core->board)->sio, &m_sio_driver, SIO_JOYBUS); - m_sio_driver.core = this; - m_sio_driver.load = [](GBASIODriver* driver) { + m_sio_driver.init = [](GBASIODriver* driver) { static_cast(driver)->core->m_link_enabled = true; return true; }; - m_sio_driver.unload = [](GBASIODriver* driver) { - static_cast(driver)->core->m_link_enabled = false; - return true; + m_sio_driver.handlesMode = [](GBASIODriver* driver, GBASIOMode mode) { + return mode == GBA_SIO_JOYBUS; }; + m_sio_driver.deinit = [](GBASIODriver* driver) { + static_cast(driver)->core->m_link_enabled = false; + }; + + GBASIOSetDriver(&static_cast<::GBA*>(m_core->board)->sio, &m_sio_driver); } void Core::SetVideoBuffer() @@ -410,15 +411,9 @@ void Core::SetVideoBuffer() host->GameChanged(); } -void Core::SetSampleRates() +void Core::SetAudioBufferSize() { - m_core->setAudioBufferSize(m_core, SAMPLES); - blip_set_rates(m_core->getAudioChannel(m_core, 0), m_core->frequency(m_core), SAMPLE_RATE); - blip_set_rates(m_core->getAudioChannel(m_core, 1), m_core->frequency(m_core), SAMPLE_RATE); - - SoundStream* sound_stream = m_system.GetSoundStream(); - sound_stream->GetMixer()->SetGBAInputSampleRateDivisors( - m_device_number, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / SAMPLE_RATE); + m_core->setAudioBufferSize(m_core, AUDIO_BUFFER_SIZE); } void Core::AddCallbacks() @@ -445,14 +440,26 @@ void Core::SetAVStream() auto core = static_cast(stream)->core; core->SetVideoBuffer(); }; - m_stream.postAudioBuffer = [](mAVStream* stream, blip_t* left, blip_t* right) { - auto core = static_cast(stream)->core; - std::vector buffer(SAMPLES * 2); - blip_read_samples(left, &buffer[0], SAMPLES, 1); - blip_read_samples(right, &buffer[1], SAMPLES, 1); + m_stream.audioRateChanged = [](mAVStream* stream, unsigned rate) { + auto* core = static_cast(stream)->core; + auto* const sound_stream = core->m_system.GetSoundStream(); + sound_stream->GetMixer()->SetGBAInputSampleRateDivisors( + core->m_device_number, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 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; - SoundStream* sound_stream = core->m_system.GetSoundStream(); - sound_stream->GetMixer()->PushGBASamples(core->m_device_number, &buffer[0], SAMPLES); + auto* const av_stream = static_cast(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); }; m_core->setAVStream(m_core, &m_stream); } @@ -733,9 +740,9 @@ bool Core::GetRomInfo(const char* rom_path, std::array& hash, std::strin return false; } - std::array game_title{}; - core->getGameTitle(core, game_title.data()); - title = game_title.data(); + mGameInfo info; + core->getGameInfo(core, &info); + title = info.title; core->deinit(core); return true; diff --git a/Source/Core/Core/HW/GBACore.h b/Source/Core/Core/HW/GBACore.h index 6fd4b86e0c..72faa1bec5 100644 --- a/Source/Core/Core/HW/GBACore.h +++ b/Source/Core/Core/HW/GBACore.h @@ -21,6 +21,7 @@ #include #include +#include "Common/Buffer.h" #include "Common/CommonTypes.h" class GBAHostInterface; @@ -40,6 +41,7 @@ struct SIODriver : GBASIODriver struct AVStream : mAVStream { Core* core; + Common::UniqueBuffer sample_buffer; }; struct CoreInfo @@ -106,7 +108,7 @@ private: void SetSIODriver(); void SetVideoBuffer(); - void SetSampleRates(); + void SetAudioBufferSize(); void AddCallbacks(); void SetAVStream(); void SetupEvent();