This commit is contained in:
Dentomologist 2024-12-21 16:34:43 -05:00 committed by GitHub
commit 07a4fd4c40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 236 additions and 39 deletions

View File

@ -193,6 +193,14 @@ void Host_YieldToUI()
{
}
void Host_UpdateWiimoteExtension(int, int)
{
}
void Host_UpdateWiimoteMotionPlus(int, bool)
{
}
void Host_TitleChanged()
{
s_game_metadata_is_valid = true;

View File

@ -604,7 +604,7 @@ ExtensionNumber Wiimote::GetActiveExtensionNumber() const
bool Wiimote::IsMotionPlusAttached() const
{
return m_is_motion_plus_attached;
return m_motion_plus_setting.GetValue();
}
} // namespace WiimoteEmu

View File

@ -22,6 +22,7 @@
#include "Core/Config/MainSettings.h"
#include "Core/Core.h"
#include "Core/HW/Wiimote.h"
#include "Core/Host.h"
#include "Core/Movie.h"
#include "Core/System.h"
@ -269,7 +270,7 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), m_bt_device_index(i
m_hotkeys->AddInput(_trans("Upright Hold"), false);
// Extension
groups.emplace_back(m_attachments = new ControllerEmu::Attachments(_trans("Extension")));
groups.emplace_back(m_attachments = new ControllerEmu::Attachments(_trans("Extension"), index));
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::None>());
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::Nunchuk>());
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::Classic>());
@ -282,6 +283,8 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), m_bt_device_index(i
m_attachments->AddAttachment(std::make_unique<WiimoteEmu::Shinkansen>());
m_attachments->AddSetting(&m_motion_plus_setting, {_trans("Attach MotionPlus")}, true);
m_motion_plus_setting.AddCallback(
[index](const bool attached) { Host_UpdateWiimoteMotionPlus(index, attached); });
// Rumble
groups.emplace_back(m_rumble = new ControllerEmu::ControlGroup(_trans("Rumble")));

View File

@ -308,7 +308,7 @@ private:
ControllerEmu::SettingValue<bool> m_sideways_setting;
ControllerEmu::SettingValue<bool> m_upright_setting;
ControllerEmu::SettingValue<double> m_battery_setting;
ControllerEmu::SettingValue<bool> m_motion_plus_setting;
ControllerEmu::SubscribableSettingValue<bool> m_motion_plus_setting;
ControllerEmu::SettingValue<double> m_fov_x_setting;
ControllerEmu::SettingValue<double> m_fov_y_setting;

View File

@ -66,6 +66,8 @@ void Host_JitProfileDataWiped();
void Host_UpdateMainFrame();
void Host_UpdateTitle(const std::string& title);
void Host_YieldToUI();
void Host_UpdateWiimoteExtension(int controller, int extension);
void Host_UpdateWiimoteMotionPlus(int controller, bool attached);
void Host_TitleChanged();
void Host_UpdateDiscordClientID(const std::string& client_id = {});

View File

@ -132,6 +132,14 @@ void Host_YieldToUI()
{
}
void Host_UpdateWiimoteExtension(int, int)
{
}
void Host_UpdateWiimoteMotionPlus(int, bool)
{
}
void Host_TitleChanged()
{
#ifdef USE_DISCORD_PRESENCE

View File

@ -298,6 +298,22 @@ void Host_RefreshDSPDebuggerWindow()
{
}
void Host_UpdateWiimoteExtension(const int controller, const int extension)
{
Settings& settings = Settings::Instance();
QueueOnObject(&settings, [&settings, controller, extension] {
settings.UpdateWiimoteExtension(controller, extension);
});
}
void Host_UpdateWiimoteMotionPlus(const int controller, const bool attached)
{
Settings& settings = Settings::Instance();
QueueOnObject(&settings, [&settings, controller, attached] {
settings.UpdateWiimoteMotionPlus(controller, attached);
});
}
void Host_TitleChanged()
{
#ifdef USE_DISCORD_PRESENCE

View File

@ -519,6 +519,15 @@ void MainWindow::CreateComponents()
&MemoryWidget::SetAddress);
connect(m_cheats_manager, &CheatsManager::ShowMemory, m_memory_widget, &MemoryWidget::SetAddress);
connect(m_cheats_manager, &CheatsManager::RequestWatch, request_watch);
connect(&Settings::Instance(), &Settings::UpdateWiimoteExtension,
[this](const int controller_number, const int extension_index) {
m_wii_tas_input_windows[controller_number]->UpdateExtension(extension_index);
});
connect(&Settings::Instance(), &Settings::UpdateWiimoteMotionPlus,
[this](const int controller_number, const bool attached) {
m_wii_tas_input_windows[controller_number]->UpdateMotionPlus(attached);
});
}
void MainWindow::ConnectMenuBar()

View File

@ -224,6 +224,8 @@ signals:
void USBKeyboardConnectionChanged(bool connected);
void EnableGfxModsChanged(bool enabled);
void HardcoreStateChanged();
void UpdateWiimoteExtension(int controller_number, int extension_index);
void UpdateWiimoteMotionPlus(int controller_number, bool attached);
private:
Settings();

View File

@ -347,32 +347,6 @@ WiiTASInputWindow::WiiTASInputWindow(QWidget* parent, int num) : TASInputWindow(
layout->addWidget(m_settings_box);
setLayout(layout);
if (Core::IsRunning(Core::System::GetInstance()))
{
m_active_extension = GetWiimote()->GetActiveExtensionNumber();
m_is_motion_plus_attached = GetWiimote()->IsMotionPlusAttached();
}
else
{
Common::IniFile ini;
ini.Load(File::GetUserPath(D_CONFIG_IDX) + "WiimoteNew.ini");
const std::string section_name = "Wiimote" + std::to_string(num + 1);
std::string extension;
ini.GetIfExists(section_name, "Extension", &extension);
if (extension == "Nunchuk")
m_active_extension = WiimoteEmu::ExtensionNumber::NUNCHUK;
else if (extension == "Classic")
m_active_extension = WiimoteEmu::ExtensionNumber::CLASSIC;
else
m_active_extension = WiimoteEmu::ExtensionNumber::NONE;
m_is_motion_plus_attached = true;
ini.GetIfExists(section_name, "Extension/Attach MotionPlus", &m_is_motion_plus_attached);
}
UpdateExt();
}
WiimoteEmu::Wiimote* WiiTASInputWindow::GetWiimote()
@ -392,7 +366,60 @@ WiimoteEmu::Extension* WiiTASInputWindow::GetExtension()
GetAttachments()->GetAttachmentList()[m_active_extension].get());
}
void WiiTASInputWindow::UpdateExt()
void WiiTASInputWindow::UpdateExtension(const int extension)
{
const auto new_extension = static_cast<WiimoteEmu::ExtensionNumber>(extension);
if (new_extension == m_active_extension)
return;
m_active_extension = new_extension;
UpdateControlVisibility();
UpdateInputOverrideFunction();
}
void WiiTASInputWindow::UpdateMotionPlus(const bool attached)
{
if (attached == m_is_motion_plus_attached)
return;
m_is_motion_plus_attached = attached;
UpdateControlVisibility();
}
void WiiTASInputWindow::LoadExtensionAndMotionPlus()
{
if (Core::IsRunning(Core::System::GetInstance()))
{
m_active_extension = GetWiimote()->GetActiveExtensionNumber();
m_is_motion_plus_attached = GetWiimote()->IsMotionPlusAttached();
}
else
{
Common::IniFile ini;
ini.Load(File::GetUserPath(D_CONFIG_IDX) + "WiimoteNew.ini");
const std::string section_name = "Wiimote" + std::to_string(m_num + 1);
std::string extension;
ini.GetIfExists(section_name, "Extension", &extension);
if (extension == "Nunchuk")
m_active_extension = WiimoteEmu::ExtensionNumber::NUNCHUK;
else if (extension == "Classic")
m_active_extension = WiimoteEmu::ExtensionNumber::CLASSIC;
else
m_active_extension = WiimoteEmu::ExtensionNumber::NONE;
m_is_motion_plus_attached = true;
ini.GetIfExists(section_name, "Extension/Attach MotionPlus", &m_is_motion_plus_attached);
}
UpdateControlVisibility();
UpdateInputOverrideFunction();
}
void WiiTASInputWindow::UpdateControlVisibility()
{
if (m_active_extension == WiimoteEmu::ExtensionNumber::NUNCHUK)
{
@ -451,17 +478,31 @@ void WiiTASInputWindow::UpdateExt()
m_nunchuk_buttons_box->hide();
m_classic_buttons_box->hide();
}
// Without these calls, switching between attachments can result in the Stick/IRWidgets being
// surrounded by large amounts of empty space in one dimension.
adjustSize();
resize(sizeHint());
}
void WiiTASInputWindow::hideEvent(QHideEvent* event)
void WiiTASInputWindow::hideEvent(QHideEvent* const event)
{
GetWiimote()->ClearInputOverrideFunction();
GetExtension()->ClearInputOverrideFunction();
TASInputWindow::hideEvent(event);
}
void WiiTASInputWindow::showEvent(QShowEvent* event)
void WiiTASInputWindow::showEvent(QShowEvent* const event)
{
WiimoteEmu::Wiimote* wiimote = GetWiimote();
LoadExtensionAndMotionPlus();
TASInputWindow::showEvent(event);
}
void WiiTASInputWindow::UpdateInputOverrideFunction()
{
WiimoteEmu::Wiimote* const wiimote = GetWiimote();
if (m_active_extension != WiimoteEmu::ExtensionNumber::CLASSIC)
wiimote->SetInputOverrideFunction(m_wiimote_overrider.GetInputOverrideFunction());

View File

@ -34,12 +34,17 @@ public:
void hideEvent(QHideEvent* event) override;
void showEvent(QShowEvent* event) override;
void UpdateExtension(int extension);
void UpdateMotionPlus(bool attached);
private:
WiimoteEmu::Wiimote* GetWiimote();
ControllerEmu::Attachments* GetAttachments();
WiimoteEmu::Extension* GetExtension();
void UpdateExt();
void LoadExtensionAndMotionPlus();
void UpdateControlVisibility();
void UpdateInputOverrideFunction();
WiimoteEmu::ExtensionNumber m_active_extension;
bool m_is_motion_plus_attached;

View File

@ -105,6 +105,14 @@ void Host_YieldToUI()
{
}
void Host_UpdateWiimoteExtension(int, int)
{
}
void Host_UpdateWiimoteMotionPlus(int, bool)
{
}
void Host_TitleChanged()
{
}

View File

@ -3,10 +3,15 @@
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
#include "Core/Host.h"
namespace ControllerEmu
{
Attachments::Attachments(const std::string& name_) : ControlGroup(name_, GroupType::Attachments)
Attachments::Attachments(const std::string& name_, const int index)
: ControlGroup(name_, GroupType::Attachments)
{
m_selection_value.AddCallback(
[index](const int extension) { Host_UpdateWiimoteExtension(index, extension); });
}
void Attachments::AddAttachment(std::unique_ptr<EmulatedController> att)

View File

@ -21,7 +21,7 @@ namespace ControllerEmu
class Attachments : public ControlGroup
{
public:
explicit Attachments(const std::string& name);
explicit Attachments(const std::string& name, int index);
void AddAttachment(std::unique_ptr<EmulatedController> att);
@ -33,7 +33,7 @@ public:
const std::vector<std::unique_ptr<EmulatedController>>& GetAttachmentList() const;
private:
SettingValue<int> m_selection_value;
SubscribableSettingValue<int> m_selection_value;
// This is here and not added to the list of numeric_settings because it's serialized differently,
// by string (to be independent from the enum), and visualized differently in the UI.
// For the rest, it's treated similarly to other numeric_settings in the group.

View File

@ -3,7 +3,10 @@
#pragma once
#include <algorithm>
#include <atomic>
#include <functional>
#include <mutex>
#include <string>
#include "Common/CommonTypes.h"
@ -173,7 +176,8 @@ class SettingValue
friend class NumericSetting<T>;
public:
ValueType GetValue() const
virtual ~SettingValue() = default;
virtual ValueType GetValue() const
{
// Only update dynamic values when the input gate is enabled.
// Otherwise settings will all change to 0 when window focus is lost.
@ -184,9 +188,11 @@ public:
return m_value;
}
ValueType GetCachedValue() const { return m_value; }
bool IsSimpleValue() const { return m_input.GetExpression().empty(); }
void SetValue(ValueType value)
virtual void SetValue(const ValueType value)
{
m_value = value;
@ -202,4 +208,76 @@ private:
mutable InputReference m_input;
};
template <typename ValueType>
class SubscribableSettingValue final : public SettingValue<ValueType>
{
public:
using Base = SettingValue<ValueType>;
ValueType GetValue() const override
{
const ValueType cached_value = this->GetCachedValue();
if (this->IsSimpleValue())
return cached_value;
const ValueType updated_value = Base::GetValue();
if (updated_value != cached_value)
TriggerCallbacks();
return updated_value;
}
void SetValue(const ValueType value) override
{
if (!this->IsSimpleValue() || (value != this->GetCachedValue()))
{
Base::SetValue(value);
TriggerCallbacks();
}
}
struct CallbackID
{
size_t id;
bool operator==(const CallbackID&) const = default;
};
using SettingChangedCallback = std::function<void(ValueType)>;
CallbackID AddCallback(const SettingChangedCallback& callback)
{
const CallbackID callback_id{.id = m_next_callback_id};
++m_next_callback_id;
std::lock_guard lock(m_mutex);
m_callback_pairs.emplace_back(callback_id, callback);
return callback_id;
}
void RemoveCallback(const CallbackID& id)
{
std::lock_guard lock(m_mutex);
const auto iter = std::ranges::find(m_callback_pairs, id, &IDCallbackPair::first);
if (iter != m_callback_pairs.end())
m_callback_pairs.erase(iter);
}
void TriggerCallbacks() const
{
const ValueType value = Base::GetValue();
std::lock_guard lock(m_mutex);
for (const auto& pair : m_callback_pairs)
pair.second(value);
}
private:
using IDCallbackPair = std::pair<CallbackID, SettingChangedCallback>;
std::vector<IDCallbackPair> m_callback_pairs;
size_t m_next_callback_id = 0;
mutable std::mutex m_mutex;
};
} // namespace ControllerEmu

View File

@ -75,6 +75,12 @@ bool Host_TASInputHasFocus()
void Host_YieldToUI()
{
}
void Host_UpdateWiimoteExtension(int, int)
{
}
void Host_UpdateWiimoteMotionPlus(int, bool)
{
}
void Host_TitleChanged()
{
}

View File

@ -79,6 +79,12 @@ bool Host_TASInputHasFocus()
void Host_YieldToUI()
{
}
void Host_UpdateWiimoteExtension(int, int)
{
}
void Host_UpdateWiimoteMotionPlus(int, bool)
{
}
void Host_TitleChanged()
{
}