diff --git a/externals/fmt b/externals/fmt index 3e75ad982..9e554999c 160000 --- a/externals/fmt +++ b/externals/fmt @@ -1 +1 @@ -Subproject commit 3e75ad9822980e41bc591938f26548f24eb88907 +Subproject commit 9e554999ce02cf86fcdfe74fe740c4fe3f5a56d5 diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 29e353fe4..49bf3aaa9 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -26,7 +26,7 @@ struct CubebSink::Impl { static void LogCallback(char const* fmt, ...); }; -CubebSink::CubebSink(std::string target_device_name) : impl(std::make_unique()) { +CubebSink::CubebSink(std::string_view target_device_name) : impl(std::make_unique()) { if (cubeb_init(&impl->ctx, "Citra", nullptr) != CUBEB_OK) { LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); return; diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h index bee777010..cd967f369 100644 --- a/src/audio_core/cubeb_sink.h +++ b/src/audio_core/cubeb_sink.h @@ -12,7 +12,7 @@ namespace AudioCore { class CubebSink final : public Sink { public: - explicit CubebSink(std::string device_id); + explicit CubebSink(std::string_view device_id); ~CubebSink() override; unsigned int GetNativeSampleRate() const override; diff --git a/src/audio_core/dsp_interface.cpp b/src/audio_core/dsp_interface.cpp index d6343d332..2beb74343 100644 --- a/src/audio_core/dsp_interface.cpp +++ b/src/audio_core/dsp_interface.cpp @@ -15,8 +15,7 @@ DspInterface::DspInterface() = default; DspInterface::~DspInterface() = default; void DspInterface::SetSink(const std::string& sink_id, const std::string& audio_device) { - const SinkDetails& sink_details = GetSinkDetails(sink_id); - sink = sink_details.factory(audio_device); + sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id); sink->SetCallback( [this](s16* buffer, std::size_t num_frames) { OutputCallback(buffer, num_frames); }); time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate()); diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h index 8218b24ff..1718a1667 100644 --- a/src/audio_core/null_sink.h +++ b/src/audio_core/null_sink.h @@ -12,7 +12,7 @@ namespace AudioCore { class NullSink final : public Sink { public: - NullSink(std::string) {} + explicit NullSink(std::string_view) {} ~NullSink() override = default; unsigned int GetNativeSampleRate() const override { diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp index b85e56e51..25c71917e 100644 --- a/src/audio_core/sink_details.cpp +++ b/src/audio_core/sink_details.cpp @@ -17,34 +17,75 @@ #include "common/logging/log.h" namespace AudioCore { +namespace { +struct SinkDetails { + using FactoryFn = std::unique_ptr (*)(std::string_view); + using ListDevicesFn = std::vector (*)(); -// g_sink_details is ordered in terms of desirability, with the best choice at the top. -const std::vector g_sink_details = { + /// Name for this sink. + const char* id; + /// A method to call to construct an instance of this type of sink. + FactoryFn factory; + /// A method to call to list available devices. + ListDevicesFn list_devices; +}; + +// sink_details is ordered in terms of desirability, with the best choice at the top. +constexpr SinkDetails sink_details[] = { #ifdef HAVE_CUBEB - SinkDetails{"cubeb", &std::make_unique, &ListCubebSinkDevices}, + SinkDetails{"cubeb", + [](std::string_view device_id) -> std::unique_ptr { + return std::make_unique(device_id); + }, + &ListCubebSinkDevices}, #endif #ifdef HAVE_SDL2 - SinkDetails{"sdl2", &std::make_unique, &ListSDL2SinkDevices}, + SinkDetails{"sdl2", + [](std::string_view device_id) -> std::unique_ptr { + return std::make_unique(std::string(device_id)); + }, + &ListSDL2SinkDevices}, #endif - SinkDetails{"null", &std::make_unique, + SinkDetails{"null", + [](std::string_view device_id) -> std::unique_ptr { + return std::make_unique(device_id); + }, [] { return std::vector{"null"}; }}, }; const SinkDetails& GetSinkDetails(std::string_view sink_id) { auto iter = - std::find_if(g_sink_details.begin(), g_sink_details.end(), + std::find_if(std::begin(sink_details), std::end(sink_details), [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; }); - if (sink_id == "auto" || iter == g_sink_details.end()) { + if (sink_id == "auto" || iter == std::end(sink_details)) { if (sink_id != "auto") { LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id {}", sink_id); } // Auto-select. - // g_sink_details is ordered in terms of desirability, with the best choice at the front. - iter = g_sink_details.begin(); + // sink_details is ordered in terms of desirability, with the best choice at the front. + iter = std::begin(sink_details); } return *iter; } +} // Anonymous namespace + +std::vector GetSinkIDs() { + std::vector sink_ids(std::size(sink_details)); + + std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids), + [](const auto& sink) { return sink.id; }); + + return sink_ids; +} + +std::vector GetDeviceListForSink(std::string_view sink_id) { + return GetSinkDetails(sink_id).list_devices(); +} + +std::unique_ptr CreateSinkFromID(std::string_view sink_id, std::string_view device_id) { + return GetSinkDetails(sink_id).factory(device_id); +} } // namespace AudioCore diff --git a/src/audio_core/sink_details.h b/src/audio_core/sink_details.h index abad0f9a5..28f5d0446 100644 --- a/src/audio_core/sink_details.h +++ b/src/audio_core/sink_details.h @@ -4,34 +4,21 @@ #pragma once -#include -#include #include #include -#include #include namespace AudioCore { class Sink; -struct SinkDetails { - using FactoryFn = std::function(std::string)>; - using ListDevicesFn = std::function()>; +/// Retrieves the IDs for all available audio sinks. +std::vector GetSinkIDs(); - SinkDetails(const char* id_, FactoryFn factory_, ListDevicesFn list_devices_) - : id(id_), factory(std::move(factory_)), list_devices(std::move(list_devices_)) {} +/// Gets the list of devices for a particular sink identified by the given ID. +std::vector GetDeviceListForSink(std::string_view sink_id); - /// Name for this sink. - const char* id; - /// A method to call to construct an instance of this type of sink. - FactoryFn factory; - /// A method to call to list available devices. - ListDevicesFn list_devices; -}; - -extern const std::vector g_sink_details; - -const SinkDetails& GetSinkDetails(std::string_view sink_id); +/// Creates an audio sink identified by the given device ID. +std::unique_ptr CreateSinkFromID(std::string_view sink_id, std::string_view device_id); } // namespace AudioCore diff --git a/src/citra/config.cpp b/src/citra/config.cpp index 7b5d437ac..a8bc1a145 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -47,9 +47,9 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) { } static const std::array default_buttons = { - SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T, - SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W, - SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, + SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T, SDL_SCANCODE_G, + SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_M, SDL_SCANCODE_N, + SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, }; static const std::array, Settings::NativeAnalog::NumAnalogs> default_analogs{{ diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index 730809413..f75af9cc3 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -38,6 +38,8 @@ button_l= button_r= button_start= button_select= +button_debug= +button_gpio14= button_zl= button_zr= button_home= diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index 4d6e736e9..a167a47a0 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -28,8 +28,9 @@ Config::~Config() { } const std::array Config::default_buttons = { - Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H, - Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N, Qt::Key_1, Qt::Key_2, Qt::Key_B, + Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_T, Qt::Key_G, + Qt::Key_F, Qt::Key_H, Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N, + Qt::Key_O, Qt::Key_P, Qt::Key_1, Qt::Key_2, Qt::Key_B, }; const std::array, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{ diff --git a/src/citra_qt/configuration/configure_audio.cpp b/src/citra_qt/configuration/configure_audio.cpp index 0ab5a3ae4..0e1419017 100644 --- a/src/citra_qt/configuration/configure_audio.cpp +++ b/src/citra_qt/configuration/configure_audio.cpp @@ -15,8 +15,8 @@ ConfigureAudio::ConfigureAudio(QWidget* parent) ui->output_sink_combo_box->clear(); ui->output_sink_combo_box->addItem("auto"); - for (const auto& sink_detail : AudioCore::g_sink_details) { - ui->output_sink_combo_box->addItem(sink_detail.id); + for (const char* id : AudioCore::GetSinkIDs()) { + ui->output_sink_combo_box->addItem(id); } connect(ui->volume_slider, &QSlider::valueChanged, this, @@ -92,8 +92,7 @@ void ConfigureAudio::updateAudioDevices(int sink_index) { ui->audio_device_combo_box->addItem(AudioCore::auto_device_name); const std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString(); - const std::vector device_list = AudioCore::GetSinkDetails(sink_id).list_devices(); - for (const auto& device : device_list) { + for (const auto& device : AudioCore::GetDeviceListForSink(sink_id)) { ui->audio_device_combo_box->addItem(QString::fromStdString(device)); } } diff --git a/src/citra_qt/configuration/configure_input.cpp b/src/citra_qt/configuration/configure_input.cpp index 09a6a8330..c0df64bc9 100644 --- a/src/citra_qt/configuration/configure_input.cpp +++ b/src/citra_qt/configuration/configure_input.cpp @@ -106,9 +106,11 @@ ConfigureInput::ConfigureInput(QWidget* parent) ui->profile->setCurrentIndex(Settings::values.current_input_profile_index); button_map = { - ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY, ui->buttonDpadUp, - ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight, ui->buttonL, ui->buttonR, - ui->buttonStart, ui->buttonSelect, ui->buttonZL, ui->buttonZR, ui->buttonHome, + ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY, + ui->buttonDpadUp, ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight, + ui->buttonL, ui->buttonR, ui->buttonStart, ui->buttonSelect, + ui->buttonDebug, ui->buttonGpio14, ui->buttonZL, ui->buttonZR, + ui->buttonHome, }; analog_map_buttons = {{ @@ -317,7 +319,8 @@ void ConfigureInput::ClearAll() { void ConfigureInput::updateButtonLabels() { for (int button = 0; button < Settings::NativeButton::NumButtons; button++) { - button_map[button]->setText(ButtonToText(buttons_param[button])); + if (button_map[button]) + button_map[button]->setText(ButtonToText(buttons_param[button])); } for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) { diff --git a/src/citra_qt/configuration/configure_input.ui b/src/citra_qt/configuration/configure_input.ui index dcb915323..6d0cb8ac7 100644 --- a/src/citra_qt/configuration/configure_input.ui +++ b/src/citra_qt/configuration/configure_input.ui @@ -7,7 +7,7 @@ 0 0 374 - 535 + 595 @@ -597,6 +597,42 @@ + + + + + + GPIO14: + + + + + + + + + + + + + + + + + + Debug: + + + + + + + + + + + + diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 132594091..39ae4c43e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -91,6 +91,8 @@ void Module::UpdatePadCallback(u64 userdata, s64 cycles_late) { state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); state.start.Assign(buttons[Start - BUTTON_HID_BEGIN]->GetStatus()); state.select.Assign(buttons[Select - BUTTON_HID_BEGIN]->GetStatus()); + state.debug.Assign(buttons[Debug - BUTTON_HID_BEGIN]->GetStatus()); + state.gpio14.Assign(buttons[Gpio14 - BUTTON_HID_BEGIN]->GetStatus()); // Get current circle pad position and update circle pad direction float circle_pad_x_f, circle_pad_y_f; diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 07bd18230..2aba49b3a 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -52,6 +52,8 @@ struct PadState { BitField<9, 1, u32> l; BitField<10, 1, u32> x; BitField<11, 1, u32> y; + BitField<12, 1, u32> debug; + BitField<13, 1, u32> gpio14; BitField<28, 1, u32> circle_right; BitField<29, 1, u32> circle_left; diff --git a/src/core/movie.cpp b/src/core/movie.cpp index e103108f7..5f2835821 100644 --- a/src/core/movie.cpp +++ b/src/core/movie.cpp @@ -57,7 +57,9 @@ struct ControllerState { BitField<9, 1, u16_le> l; BitField<10, 1, u16_le> x; BitField<11, 1, u16_le> y; - // Bits 12-15 are currently unused + BitField<12, 1, u16_le> debug; + BitField<13, 1, u16_le> gpio14; + // Bits 14-15 are currently unused }; s16_le circle_pad_x; s16_le circle_pad_y; @@ -161,6 +163,8 @@ void Movie::Play(Service::HID::PadState& pad_state, s16& circle_pad_x, s16& circ pad_state.l.Assign(s.pad_and_circle.l); pad_state.x.Assign(s.pad_and_circle.x); pad_state.y.Assign(s.pad_and_circle.y); + pad_state.debug.Assign(s.pad_and_circle.debug); + pad_state.gpio14.Assign(s.pad_and_circle.gpio14); circle_pad_x = s.pad_and_circle.circle_pad_x; circle_pad_y = s.pad_and_circle.circle_pad_y; @@ -281,6 +285,8 @@ void Movie::Record(const Service::HID::PadState& pad_state, const s16& circle_pa s.pad_and_circle.l.Assign(static_cast(pad_state.l)); s.pad_and_circle.x.Assign(static_cast(pad_state.x)); s.pad_and_circle.y.Assign(static_cast(pad_state.y)); + s.pad_and_circle.debug.Assign(static_cast(pad_state.debug)); + s.pad_and_circle.gpio14.Assign(static_cast(pad_state.gpio14)); s.pad_and_circle.circle_pad_x = circle_pad_x; s.pad_and_circle.circle_pad_y = circle_pad_y; diff --git a/src/core/settings.h b/src/core/settings.h index 43c7b7d1f..feae642e5 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -39,6 +39,8 @@ enum Values { R, Start, Select, + Debug, + Gpio14, ZL, ZR, @@ -73,6 +75,8 @@ static const std::array mapping = {{ "button_r", "button_start", "button_select", + "button_debug", + "button_gpio14", "button_zl", "button_zr", "button_home", diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index b98cf1654..24f782653 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -13,4 +13,4 @@ add_library(network STATIC create_target_directory_groups(network) -target_link_libraries(network PRIVATE common cpp-jwt enet) +target_link_libraries(network PRIVATE common enet)