Core: Remove SerialInterfaceManager::ChangeDevice

Now SerialInterfaceManager::UpdateDevices reads the configured SI
devices directly from Config instead.

The main reason why I wanted to do this is so that Android can change SI
devices while emulation is running. (Android didn't have the code for
calling ChangeDevice.) But when implementing the change, I noticed that
NetPlay and Movie were using ChangeDevice as a way of overriding the SI
devices configured by the user. Replacing this ended up making the change
larger than I first anticipated.

For Wii Remotes, there was no equivalent to ChangeDevice, so NetPlay and
Movie were using Config::SetCurrent to override the Wii Remote source
configured by the user. If we can use the config system to override Wii
Remote sources, why not do the same for SI devices? This commit makes
NetPlay and Movie set SI devices and Wii Remote sources in the NetPlay
and Movie config layers, as that is the conceptually appropriate place
to do it.

As far as I can tell, the old Movie code for overriding SI devices and
Wii Remote sources didn't actually work. This new code does. I didn't
investigate exactly why it didn't work, but maybe it's because loading
a movie happens before emulation actually starts.
This commit is contained in:
JosJuice 2026-04-25 14:57:58 +02:00
parent a94854309b
commit 7ece00e328
11 changed files with 147 additions and 202 deletions

View File

@ -185,11 +185,7 @@ enum class IntSetting(
MAIN_SLOT_A,
MAIN_SLOT_B,
MAIN_SERIAL_PORT_1,
MAIN_FALLBACK_REGION,
MAIN_SI_DEVICE_0,
MAIN_SI_DEVICE_1,
MAIN_SI_DEVICE_2,
MAIN_SI_DEVICE_3
MAIN_FALLBACK_REGION
)
private val NOT_RUNTIME_EDITABLE: Set<IntSetting> =

View File

@ -14,6 +14,10 @@
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/Config/WiimoteSettings.h"
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/HW/Wiimote.h"
#include "Core/Movie.h"
namespace PowerPC
@ -50,6 +54,38 @@ static void LoadFromDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm)
config_layer->Set(Config::SESSION_USE_FMA, dtm->bUseFMA);
config_layer->Set(Config::MAIN_JIT_FOLLOW_BRANCH, dtm->bFollowBranch);
for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i)
{
SerialInterface::SIDevices device = SerialInterface::SIDEVICE_NONE;
const auto config_info = Config::GetInfoForSIDevice(i);
if (dtm->GBAControllers & (1 << i))
{
device = SerialInterface::SIDEVICE_GC_GBA_EMULATED;
}
else if (dtm->controllers & (1 << i))
{
const SerialInterface::SIDevices si_device = Config::Get(config_info);
if (SerialInterface::SIDevice_IsGCController(si_device))
{
device = si_device;
}
else
{
device = (dtm->bongos & (1 << i)) != 0 ? SerialInterface::SIDEVICE_GC_TARUKONGA :
SerialInterface::SIDEVICE_GC_CONTROLLER;
}
}
config_layer->Set(config_info, device);
}
for (int i = 0; i < MAX_WIIMOTES; ++i)
{
const bool is_using_wiimote = (dtm->controllers & (1 << (i + 4))) != 0;
config_layer->Set(Config::GetInfoForWiimoteSource(i),
is_using_wiimote ? WiimoteSource::Emulated : WiimoteSource::None);
}
}
void SaveToDTM(Movie::DTMHeader* dtm)

View File

@ -16,9 +16,15 @@
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/Config/WiimoteSettings.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/HW/Wiimote.h"
#include "Core/NetPlayProto.h"
#include "InputCommon/GCAdapter.h"
namespace ConfigLoaders
{
class NetPlayConfigLayerLoader final : public Config::ConfigLayerLoader
@ -127,6 +133,54 @@ public:
layer->Set(Config::GFX_SSAA, false);
}
u8 local_pad = 0;
for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i)
{
const NetPlay::PlayerId player_id = m_settings.pad_map[i];
const SerialInterface::SIDevices si_device =
Config::Get(Config::GetInfoForSIDevice(local_pad));
const auto config_info = Config::GetInfoForSIDevice(i);
if (m_settings.gba_config[i].enabled && player_id > 0)
{
layer->Set(config_info, SerialInterface::SIDEVICE_GC_GBA_EMULATED);
}
else if (player_id == m_settings.local_player_id)
{
// Use local controller types for local controllers if they are compatible
if (SerialInterface::SIDevice_IsGCController(si_device))
{
layer->Set(config_info, si_device);
if (si_device == SerialInterface::SIDEVICE_WIIU_ADAPTER)
{
GCAdapter::ResetDeviceType(local_pad);
}
}
else
{
layer->Set(config_info, SerialInterface::SIDEVICE_GC_CONTROLLER);
}
local_pad++;
}
else if (player_id > 0)
{
if (si_device != SerialInterface::SIDEVICE_AM_BASEBOARD)
layer->Set(config_info, SerialInterface::SIDEVICE_GC_CONTROLLER);
}
else
{
layer->Set(config_info, SerialInterface::SIDEVICE_NONE);
}
}
for (int i = 0; i < MAX_WIIMOTES; ++i)
{
NetPlay::PlayerId player_id = m_settings.wiimote_map[i];
layer->Set(Config::GetInfoForWiimoteSource(i),
player_id > 0 ? WiimoteSource::Emulated : WiimoteSource::None);
}
if (m_settings.savedata_load)
{
if (!m_settings.is_hosting)

View File

@ -269,33 +269,7 @@ void SerialInterfaceManager::Init()
m_channel[i].in_lo.hex = 0;
m_channel[i].has_recent_device_unplug = false;
auto& movie = m_system.GetMovie();
if (movie.IsMovieActive())
{
m_desired_device_types[i] = SIDEVICE_NONE;
if (movie.IsUsingGBA(i))
{
m_desired_device_types[i] = SIDEVICE_GC_GBA_EMULATED;
}
else if (movie.IsUsingPad(i))
{
const SIDevices current = Config::Get(Config::GetInfoForSIDevice(i));
// GC pad-compatible devices can be used for both playing and recording
if (movie.IsUsingBongo(i))
m_desired_device_types[i] = SIDEVICE_GC_TARUKONGA;
else if (SIDevice_IsGCController(current))
m_desired_device_types[i] = current;
else
m_desired_device_types[i] = SIDEVICE_GC_CONTROLLER;
}
}
else if (!NetPlay::IsNetPlayRunning())
{
m_desired_device_types[i] = Config::Get(Config::GetInfoForSIDevice(i));
}
AddDevice(m_desired_device_types[i], i);
AddDevice(Config::Get(Config::GetInfoForSIDevice(i)), i);
}
m_poll.hex = 0;
@ -499,12 +473,6 @@ void SerialInterfaceManager::AddDevice(const SIDevices device, int device_number
AddDevice(SIDevice_Create(m_system, device, device_number));
}
void SerialInterfaceManager::ChangeDevice(SIDevices device, int channel)
{
// Actual device change will happen in UpdateDevices.
m_desired_device_types[channel] = device;
}
void SerialInterfaceManager::ChangeDeviceDeterministic(SIDevices device, int channel)
{
if (channel < 0 || channel >= MAX_SI_CHANNELS)
@ -540,7 +508,7 @@ void SerialInterfaceManager::UpdateDevices()
for (int i = 0; i != MAX_SI_CHANNELS; ++i)
{
const SIDevices current_type = GetDeviceType(i);
const SIDevices desired_type = m_desired_device_types[i];
const SIDevices desired_type = Config::Get(Config::GetInfoForSIDevice(i));
if (current_type != desired_type)
{

View File

@ -62,8 +62,6 @@ public:
void AddDevice(SIDevices device, int device_number);
void AddDevice(std::unique_ptr<ISIDevice> device);
void ChangeDevice(SIDevices device, int channel);
SIDevices GetDeviceType(int channel) const;
u32 GetPollXLines();
@ -233,9 +231,6 @@ private:
CoreTiming::EventType* m_event_type_tranfer_pending = nullptr;
std::array<CoreTiming::EventType*, MAX_SI_CHANNELS> m_event_types_device{};
// User-configured device type. possibly overridden by TAS/Netplay
std::array<std::atomic<SIDevices>, MAX_SI_CHANNELS> m_desired_device_types{};
std::array<SSIChannel, MAX_SI_CHANNELS> m_channel;
USIPoll m_poll;
USIComCSR m_com_csr;

View File

@ -427,38 +427,10 @@ void MovieManager::ChangePads()
else
controllers[i] = ControllerType::None;
}
if (m_controllers == controllers)
return;
auto& si = m_system.GetSerialInterface();
for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i)
{
SerialInterface::SIDevices device = SerialInterface::SIDEVICE_NONE;
if (IsUsingGBA(i))
{
device = SerialInterface::SIDEVICE_GC_GBA_EMULATED;
}
else if (IsUsingPad(i))
{
const SerialInterface::SIDevices si_device = Config::Get(Config::GetInfoForSIDevice(i));
if (SerialInterface::SIDevice_IsGCController(si_device))
{
device = si_device;
}
else
{
device = IsUsingBongo(i) ? SerialInterface::SIDEVICE_GC_TARUKONGA :
SerialInterface::SIDEVICE_GC_CONTROLLER;
}
}
si.ChangeDevice(device, i);
}
}
// NOTE: Host / Emu Threads
void MovieManager::ChangeWiiPads(bool instantly)
void MovieManager::ChangeWiiPads()
{
WiimoteEnabledArray wiimotes{};
@ -466,21 +438,6 @@ void MovieManager::ChangeWiiPads(bool instantly)
{
wiimotes[i] = Config::Get(Config::GetInfoForWiimoteSource(i)) != WiimoteSource::None;
}
// This is important for Wiimotes, because they can desync easily if they get re-activated
if (instantly && m_wiimotes == wiimotes)
return;
const auto bt = WiiUtils::GetBluetoothEmuDevice();
for (int i = 0; i < MAX_WIIMOTES; ++i)
{
const bool is_using_wiimote = IsUsingWiimote(i);
Config::SetCurrent(Config::GetInfoForWiimoteSource(i),
is_using_wiimote ? WiimoteSource::Emulated : WiimoteSource::None);
if (bt != nullptr)
bt->AccessWiimoteByIndex(i)->Activate(is_using_wiimote);
}
}
// NOTE: Host Thread
@ -1011,7 +968,7 @@ void MovieManager::LoadInput(const std::string& movie_path)
ChangePads();
if (m_system.IsWii())
ChangeWiiPads(true);
ChangeWiiPads();
u64 totalSavedBytes = t_record.GetSize() - 256;

View File

@ -198,7 +198,7 @@ public:
bool IsUsingBongo(int controller) const;
bool IsUsingGBA(int controller) const;
void ChangePads();
void ChangeWiiPads(bool instantly = false);
void ChangeWiiPads();
void SetReadOnly(bool bEnabled);

View File

@ -40,7 +40,6 @@
#include "Core/Config/MainSettings.h"
#include "Core/Config/NetplaySettings.h"
#include "Core/Config/SessionSettings.h"
#include "Core/Config/WiimoteSettings.h"
#include "Core/ConfigManager.h"
#include "Core/GeckoCode.h"
#include "Core/HW/EXI/EXI.h"
@ -627,17 +626,15 @@ void NetPlayClient::OnChunkedDataAbort(sf::Packet& packet)
void NetPlayClient::OnPadMapping(sf::Packet& packet)
{
for (PlayerId& mapping : m_pad_map)
for (PlayerId& mapping : m_net_settings.pad_map)
packet >> mapping;
UpdateDevices();
m_dialog->Update();
}
void NetPlayClient::OnWiimoteMapping(sf::Packet& packet)
{
for (PlayerId& mapping : m_wiimote_map)
for (PlayerId& mapping : m_net_settings.wiimote_map)
packet >> mapping;
m_dialog->Update();
@ -645,9 +642,9 @@ void NetPlayClient::OnWiimoteMapping(sf::Packet& packet)
void NetPlayClient::OnGBAConfig(sf::Packet& packet)
{
for (size_t i = 0; i < m_gba_config.size(); ++i)
for (size_t i = 0; i < m_net_settings.gba_config.size(); ++i)
{
auto& config = m_gba_config[i];
auto& config = m_net_settings.gba_config[i];
const auto old_config = config;
packet >> config.enabled >> config.has_rom >> config.title;
@ -666,7 +663,6 @@ void NetPlayClient::OnGBAConfig(sf::Packet& packet)
}
SendGameStatus();
UpdateDevices();
m_dialog->Update();
}
@ -680,7 +676,7 @@ void NetPlayClient::OnPadData(sf::Packet& packet)
GCPadStatus pad;
packet >> pad.button;
if (!m_gba_config.at(map).enabled)
if (!m_net_settings.gba_config.at(map).enabled)
{
packet >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >> pad.substickX >>
pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected;
@ -702,7 +698,7 @@ void NetPlayClient::OnPadHostData(sf::Packet& packet)
GCPadStatus pad;
packet >> pad.button;
if (!m_gba_config.at(map).enabled)
if (!m_net_settings.gba_config.at(map).enabled)
{
packet >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >> pad.substickX >>
pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected;
@ -1699,7 +1695,7 @@ void NetPlayClient::AddPadStateToPacket(const int in_game_pad, const GCPadStatus
{
packet << static_cast<PadIndex>(in_game_pad);
packet << pad.button;
if (!m_gba_config[in_game_pad].enabled)
if (!m_net_settings.gba_config[in_game_pad].enabled)
{
packet << pad.analogA << pad.analogB << pad.stickX << pad.stickY << pad.substickX
<< pad.substickY << pad.triggerLeft << pad.triggerRight << pad.isConnected;
@ -1769,23 +1765,17 @@ bool NetPlayClient::StartGame(const std::string& path)
Movie::WiimoteEnabledArray wiimotes{};
for (unsigned int i = 0; i < 4; ++i)
{
if (m_pad_map[i] > 0 && m_gba_config[i].enabled)
if (m_net_settings.pad_map[i] > 0 && m_net_settings.gba_config[i].enabled)
controllers[i] = Movie::ControllerType::GBA;
else if (m_pad_map[i] > 0)
else if (m_net_settings.pad_map[i] > 0)
controllers[i] = Movie::ControllerType::GC;
else
controllers[i] = Movie::ControllerType::None;
wiimotes[i] = m_wiimote_map[i] > 0;
wiimotes[i] = m_net_settings.wiimote_map[i] > 0;
}
movie.BeginRecordingInput(controllers, wiimotes);
}
for (unsigned int i = 0; i < 4; ++i)
{
Config::SetCurrent(Config::GetInfoForWiimoteSource(i),
m_wiimote_map[i] > 0 ? WiimoteSource::Emulated : WiimoteSource::None);
}
// boot game
auto boot_session_data = std::make_unique<BootSessionData>();
@ -1807,12 +1797,12 @@ bool NetPlayClient::StartGame(const std::string& path)
if (File::Exists(redirect_path))
File::DeleteDirRecursively(redirect_path);
});
m_net_settings.local_player_id = m_local_player->pid;
boot_session_data->SetNetplaySettings(std::make_unique<NetPlay::NetSettings>(m_net_settings));
m_dialog->BootGame(path, std::move(boot_session_data));
UpdateDevices();
return true;
}
@ -1876,52 +1866,6 @@ bool NetPlayClient::ChangeGame(const std::string&)
return true;
}
// called from ---NETPLAY--- thread
void NetPlayClient::UpdateDevices()
{
u8 local_pad = 0;
u8 pad = 0;
auto& si = Core::System::GetInstance().GetSerialInterface();
for (auto player_id : m_pad_map)
{
const SerialInterface::SIDevices si_device = Config::Get(Config::GetInfoForSIDevice(local_pad));
if (m_gba_config[pad].enabled && player_id > 0)
{
si.ChangeDevice(SerialInterface::SIDEVICE_GC_GBA_EMULATED, pad);
}
else if (player_id == m_local_player->pid)
{
// Use local controller types for local controllers if they are compatible
if (SerialInterface::SIDevice_IsGCController(si_device))
{
si.ChangeDevice(si_device, pad);
if (si_device == SerialInterface::SIDEVICE_WIIU_ADAPTER)
{
GCAdapter::ResetDeviceType(local_pad);
}
}
else
{
si.ChangeDevice(SerialInterface::SIDEVICE_GC_CONTROLLER, pad);
}
local_pad++;
}
else if (player_id > 0)
{
if (si_device != SerialInterface::SIDEVICE_AM_BASEBOARD)
si.ChangeDevice(SerialInterface::SIDEVICE_GC_CONTROLLER, pad);
}
else
{
si.ChangeDevice(SerialInterface::SIDEVICE_NONE, pad);
}
pad++;
}
}
// called from ---NETPLAY--- thread
void NetPlayClient::ClearBuffers()
{
@ -2178,7 +2122,7 @@ bool NetPlayClient::PollLocalPad(const int local_pad, sf::Packet& packet)
bool data_added = false;
GCPadStatus pad_status;
if (m_gba_config[ingame_pad].enabled)
if (m_net_settings.gba_config[ingame_pad].enabled)
{
pad_status = Pad::GetGBAStatus(local_pad);
}
@ -2269,9 +2213,9 @@ void NetPlayClient::SendPadHostPoll(const PadIndex pad_num)
if (pad_num < 0)
{
for (size_t i = 0; i < m_pad_map.size(); i++)
for (size_t i = 0; i < m_net_settings.pad_map.size(); i++)
{
if (m_pad_map[i] <= 0)
if (m_net_settings.pad_map[i] <= 0)
continue;
while (!m_first_pad_status_received[i])
@ -2283,9 +2227,9 @@ void NetPlayClient::SendPadHostPoll(const PadIndex pad_num)
}
}
for (size_t i = 0; i < m_pad_map.size(); i++)
for (size_t i = 0; i < m_net_settings.pad_map.size(); i++)
{
if (m_pad_map[i] == 0 || m_pad_buffer[i].Size() > 0)
if (m_net_settings.pad_map[i] == 0 || m_pad_buffer[i].Size() > 0)
continue;
const GCPadStatus& pad_status = m_last_pad_status[i];
@ -2293,7 +2237,7 @@ void NetPlayClient::SendPadHostPoll(const PadIndex pad_num)
AddPadStateToPacket(static_cast<int>(i), pad_status, packet);
}
}
else if (m_pad_map[pad_num] != 0)
else if (m_net_settings.pad_map[pad_num] != 0)
{
while (!m_first_pad_status_received[pad_num])
{
@ -2400,18 +2344,18 @@ bool NetPlayClient::LocalPlayerHasControllerMapped() const
bool NetPlayClient::IsFirstInGamePad(int ingame_pad) const
{
return std::none_of(m_pad_map.begin(), m_pad_map.begin() + ingame_pad,
return std::none_of(m_net_settings.pad_map.begin(), m_net_settings.pad_map.begin() + ingame_pad,
[](auto mapping) { return mapping > 0; });
}
int NetPlayClient::NumLocalPads() const
{
return std::ranges::count(m_pad_map, m_local_player->pid);
return std::ranges::count(m_net_settings.pad_map, m_local_player->pid);
}
int NetPlayClient::NumLocalWiimotes() const
{
return std::ranges::count(m_wiimote_map, m_local_player->pid);
return std::ranges::count(m_net_settings.wiimote_map, m_local_player->pid);
}
static int InGameToLocal(int ingame_pad, const PadMappingArray& pad_map, PlayerId local_player_pid)
@ -2453,30 +2397,30 @@ static int LocalToInGame(int local_pad, const PadMappingArray& pad_map, PlayerId
int NetPlayClient::InGamePadToLocalPad(int ingame_pad) const
{
return InGameToLocal(ingame_pad, m_pad_map, m_local_player->pid);
return InGameToLocal(ingame_pad, m_net_settings.pad_map, m_local_player->pid);
}
int NetPlayClient::LocalPadToInGamePad(int local_pad) const
{
return LocalToInGame(local_pad, m_pad_map, m_local_player->pid);
return LocalToInGame(local_pad, m_net_settings.pad_map, m_local_player->pid);
}
int NetPlayClient::InGameWiimoteToLocalWiimote(int ingame_wiimote) const
{
return InGameToLocal(ingame_wiimote, m_wiimote_map, m_local_player->pid);
return InGameToLocal(ingame_wiimote, m_net_settings.wiimote_map, m_local_player->pid);
}
int NetPlayClient::LocalWiimoteToInGameWiimote(int local_wiimote) const
{
return LocalToInGame(local_wiimote, m_wiimote_map, m_local_player->pid);
return LocalToInGame(local_wiimote, m_net_settings.wiimote_map, m_local_player->pid);
}
bool NetPlayClient::PlayerHasControllerMapped(const PlayerId pid) const
{
const auto mapping_matches_player_id = [pid](const PlayerId& mapping) { return mapping == pid; };
return std::ranges::any_of(m_pad_map, mapping_matches_player_id) ||
std::ranges::any_of(m_wiimote_map, mapping_matches_player_id);
return std::ranges::any_of(m_net_settings.pad_map, mapping_matches_player_id) ||
std::ranges::any_of(m_net_settings.wiimote_map, mapping_matches_player_id);
}
bool NetPlayClient::IsLocalPlayer(const PlayerId pid) const
@ -2498,7 +2442,7 @@ void NetPlayClient::SendGameStatus()
m_dialog->FindGameFile(m_selected_game, &result);
for (size_t i = 0; i < 4; ++i)
{
if (m_gba_config[i].enabled && m_gba_config[i].has_rom &&
if (m_net_settings.gba_config[i].enabled && m_net_settings.gba_config[i].has_rom &&
m_net_settings.gba_rom_paths[i].empty())
{
result = SyncIdentifierComparison::DifferentGame;
@ -2611,17 +2555,17 @@ void NetPlayClient::ComputeGameDigest(const SyncIdentifier& sync_identifier)
const PadMappingArray& NetPlayClient::GetPadMapping() const
{
return m_pad_map;
return m_net_settings.pad_map;
}
const GBAConfigArray& NetPlayClient::GetGBAConfig() const
{
return m_gba_config;
return m_net_settings.gba_config;
}
const PadMappingArray& NetPlayClient::GetWiimoteMapping() const
{
return m_wiimote_map;
return m_net_settings.wiimote_map;
}
void NetPlayClient::AdjustPadBufferSize(const unsigned int size)

View File

@ -232,10 +232,6 @@ protected:
u32 m_current_game = 0;
PadMappingArray m_pad_map{};
GBAConfigArray m_gba_config{};
PadMappingArray m_wiimote_map{};
bool m_is_recording = false;
private:
@ -261,7 +257,6 @@ private:
bool AddLocalWiimoteToBuffer(int local_wiimote, const WiimoteEmu::SerializedWiimoteState& state,
sf::Packet& packet);
void UpdateDevices();
void AddPadStateToPacket(int in_game_pad, const GCPadStatus& np, sf::Packet& packet);
void AddWiimoteStateToPacket(int in_game_pad, const WiimoteEmu::SerializedWiimoteState& np,
sf::Packet& packet);

View File

@ -29,6 +29,20 @@ enum class CPUCore;
namespace NetPlay
{
struct GBAConfig
{
bool enabled = false;
bool has_rom = false;
std::string title;
std::array<u8, 20> hash{};
};
using PlayerId = u8;
using FrameNum = u32;
using PadIndex = s8;
using PadMappingArray = std::array<PlayerId, 4>;
using GBAConfigArray = std::array<GBAConfig, 4>;
struct NetSettings
{
bool cpu_thread = false;
@ -111,8 +125,14 @@ struct NetSettings
Sram sram;
// These are sent separately from the other settings
PadMappingArray pad_map{};
GBAConfigArray gba_config{};
PadMappingArray wiimote_map{};
// These aren't sent over the network directly
bool is_hosting = false;
PlayerId local_player_id;
std::array<std::string, 4> gba_rom_paths{};
};
@ -234,19 +254,6 @@ enum : u8
CHANNEL_COUNT
};
using PlayerId = u8;
using FrameNum = u32;
using PadIndex = s8;
using PadMappingArray = std::array<PlayerId, 4>;
struct GBAConfig
{
bool enabled = false;
bool has_rom = false;
std::string title;
std::array<u8, 20> hash{};
};
using GBAConfigArray = std::array<GBAConfig, 4>;
struct PadDetails
{
std::string player_name{};

View File

@ -15,7 +15,6 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h"
#include "Core/NetPlayProto.h"
#include "Core/System.h"
@ -190,17 +189,11 @@ void GamecubeControllersWidget::SaveSettings()
{
Config::ConfigChangeCallbackGuard config_guard;
auto& system = Core::System::GetInstance();
for (size_t i = 0; i < m_gc_groups.size(); ++i)
{
const SerialInterface::SIDevices si_device =
FromGCMenuIndex(m_gc_controller_boxes[i]->currentIndex());
Config::SetBaseOrCurrent(Config::GetInfoForSIDevice(static_cast<int>(i)), si_device);
if (Core::IsRunning(system))
{
system.GetSerialInterface().ChangeDevice(si_device, static_cast<s32>(i));
}
}
}