mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 14:55:46 -04:00
HostInterface: Support per-controller-type settings
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
#include "analog_controller.h"
|
||||
#include "common/log.h"
|
||||
#include "common/state_wrapper.h"
|
||||
#include "common/string_util.h"
|
||||
#include "host_interface.h"
|
||||
#include "system.h"
|
||||
Log_SetChannel(AnalogController);
|
||||
@ -23,6 +24,9 @@ void AnalogController::Reset()
|
||||
m_rumble_unlocked = false;
|
||||
m_configuration_mode = false;
|
||||
m_command_param = 0;
|
||||
|
||||
if (m_auto_enable_analog)
|
||||
SetAnalogMode(true);
|
||||
}
|
||||
|
||||
bool AnalogController::DoState(StateWrapper& sw)
|
||||
@ -474,3 +478,18 @@ u32 AnalogController::StaticGetVibrationMotorCount()
|
||||
{
|
||||
return NUM_MOTORS;
|
||||
}
|
||||
|
||||
Controller::SettingList AnalogController::StaticGetSettings()
|
||||
{
|
||||
static constexpr std::array<SettingInfo, 1> settings = {
|
||||
{{SettingInfo::Type::Boolean, "AutoEnableAnalog", "Enable Analog Mode on Reset",
|
||||
"Automatically enables analog mode when the console is reset/powered on.", "false"}}};
|
||||
|
||||
return SettingList(settings.begin(), settings.end());
|
||||
}
|
||||
|
||||
void AnalogController::LoadSettings(HostInterface* host_interface, const char* section)
|
||||
{
|
||||
Controller::LoadSettings(host_interface, section);
|
||||
m_auto_enable_analog = host_interface->GetBooleanSettingValue(section, "AutoEnableAnalog", false);
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
static AxisList StaticGetAxisNames();
|
||||
static ButtonList StaticGetButtonNames();
|
||||
static u32 StaticGetVibrationMotorCount();
|
||||
static SettingList StaticGetSettings();
|
||||
|
||||
ControllerType GetType() const override;
|
||||
std::optional<s32> GetAxisCodeByName(std::string_view axis_name) const override;
|
||||
@ -70,6 +71,8 @@ public:
|
||||
u32 GetVibrationMotorCount() const override;
|
||||
float GetVibrationMotorStrength(u32 motor) override;
|
||||
|
||||
void LoadSettings(HostInterface* host_interface, const char* section) override;
|
||||
|
||||
private:
|
||||
using MotorState = std::array<u8, NUM_MOTORS>;
|
||||
|
||||
@ -132,6 +135,8 @@ private:
|
||||
System* m_system;
|
||||
u32 m_index;
|
||||
|
||||
bool m_auto_enable_analog = false;
|
||||
|
||||
bool m_analog_mode = false;
|
||||
bool m_analog_locked = false;
|
||||
bool m_rumble_unlocked = false;
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include "common/state_wrapper.h"
|
||||
#include "digital_controller.h"
|
||||
#include "namco_guncon.h"
|
||||
#include "playstation_mouse.h"
|
||||
#include "negcon.h"
|
||||
#include "playstation_mouse.h"
|
||||
|
||||
Controller::Controller() = default;
|
||||
|
||||
@ -39,6 +39,8 @@ float Controller::GetVibrationMotorStrength(u32 motor)
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void Controller::LoadSettings(HostInterface* host_interface, const char* section) {}
|
||||
|
||||
std::unique_ptr<Controller> Controller::Create(System* system, ControllerType type, u32 index)
|
||||
{
|
||||
switch (type)
|
||||
@ -198,3 +200,15 @@ std::optional<s32> Controller::GetButtonCodeByName(ControllerType type, std::str
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
Controller::SettingList Controller::GetSettings(ControllerType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetSettings();
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "settings.h"
|
||||
#include "types.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@ -8,12 +9,14 @@
|
||||
|
||||
class StateWrapper;
|
||||
class System;
|
||||
class HostInterface;
|
||||
|
||||
class Controller
|
||||
{
|
||||
public:
|
||||
using ButtonList = std::vector<std::pair<std::string, s32>>;
|
||||
using AxisList = std::vector<std::pair<std::string, s32>>;
|
||||
using SettingList = std::vector<SettingInfo>;
|
||||
|
||||
Controller();
|
||||
virtual ~Controller();
|
||||
@ -48,6 +51,9 @@ public:
|
||||
/// Queries the state of the specified vibration motor. Values are normalized from 0..1.
|
||||
virtual float GetVibrationMotorStrength(u32 motor);
|
||||
|
||||
/// Loads/refreshes any per-controller settings.
|
||||
virtual void LoadSettings(HostInterface* host_interface, const char* section);
|
||||
|
||||
/// Creates a new controller of the specified type.
|
||||
static std::unique_ptr<Controller> Create(System* system, ControllerType type, u32 index);
|
||||
|
||||
@ -65,4 +71,7 @@ public:
|
||||
|
||||
/// Returns the number of vibration motors.
|
||||
static u32 GetVibrationMotorCount(ControllerType type);
|
||||
|
||||
/// Returns settings for the controller.
|
||||
static SettingList GetSettings(ControllerType type);
|
||||
};
|
||||
|
@ -480,6 +480,9 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
||||
|
||||
OnControllerTypeChanged(i);
|
||||
}
|
||||
|
||||
if (m_system && !controllers_updated)
|
||||
m_system->UpdateControllerSettings();
|
||||
}
|
||||
|
||||
if (m_display && m_settings.display_linear_filtering != old_settings.display_linear_filtering)
|
||||
@ -566,6 +569,36 @@ std::string HostInterface::GetGameMemoryCardPath(const char* game_code, u32 slot
|
||||
return GetUserDirectoryRelativePath("memcards/%s_%d.mcd", game_code, slot + 1);
|
||||
}
|
||||
|
||||
bool HostInterface::GetBooleanSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
std::string value = GetSettingValue(section, key, "");
|
||||
if (value.empty())
|
||||
return default_value;
|
||||
|
||||
std::optional<bool> bool_value = StringUtil::FromChars<bool>(value);
|
||||
return bool_value.value_or(default_value);
|
||||
}
|
||||
|
||||
bool HostInterface::GetIntegerSettingValue(const char* section, const char* key, s32 default_value /*= 0*/)
|
||||
{
|
||||
std::string value = GetSettingValue(section, key, "");
|
||||
if (value.empty())
|
||||
return default_value;
|
||||
|
||||
std::optional<s32> int_value = StringUtil::FromChars<s32>(value);
|
||||
return int_value.value_or(default_value);
|
||||
}
|
||||
|
||||
bool HostInterface::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::string value = GetSettingValue(section, key, "");
|
||||
if (value.empty())
|
||||
return default_value;
|
||||
|
||||
std::optional<float> float_value = StringUtil::FromChars<float>(value);
|
||||
return float_value.value_or(default_value);
|
||||
}
|
||||
|
||||
void HostInterface::ToggleSoftwareRendering()
|
||||
{
|
||||
if (!m_system || m_settings.gpu_renderer == GPURenderer::Software)
|
||||
|
@ -91,7 +91,8 @@ public:
|
||||
|
||||
/// Displays a loading screen with the logo, rendered with ImGui. Use when executing possibly-time-consuming tasks
|
||||
/// such as compiling shaders when starting up.
|
||||
virtual void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1, int progress_value = -1);
|
||||
virtual void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1,
|
||||
int progress_value = -1);
|
||||
|
||||
/// Retrieves information about specified game from game list.
|
||||
virtual void GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title);
|
||||
@ -102,7 +103,20 @@ public:
|
||||
/// Returns the default path to a memory card for a specific game.
|
||||
virtual std::string GetGameMemoryCardPath(const char* game_code, u32 slot) const;
|
||||
|
||||
/// Enables the software cursor. Can be called multiple times, but must be matched by a call to DisableSoftwareCursor().
|
||||
/// Returns a setting value from the configuration.
|
||||
virtual std::string GetSettingValue(const char* section, const char* key, const char* default_value = "") = 0;
|
||||
|
||||
/// Returns a boolean setting from the configuration.
|
||||
bool GetBooleanSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
|
||||
/// Returns an integer setting from the configuration.
|
||||
bool GetIntegerSettingValue(const char* section, const char* key, s32 default_value = 0);
|
||||
|
||||
/// Returns a float setting from the configuration.
|
||||
bool GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
|
||||
/// Enables the software cursor. Can be called multiple times, but must be matched by a call to
|
||||
/// DisableSoftwareCursor().
|
||||
void EnableSoftwareCursor();
|
||||
|
||||
/// Disables the software cursor, preventing it from being renderered.
|
||||
|
@ -4,6 +4,62 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
const char* SettingInfo::StringDefaultValue() const
|
||||
{
|
||||
return default_value ? default_value : "";
|
||||
}
|
||||
|
||||
bool SettingInfo::BooleanDefaultValue() const
|
||||
{
|
||||
return default_value ? StringUtil::FromChars<bool>(default_value).value_or(false) : false;
|
||||
}
|
||||
|
||||
s32 SettingInfo::IntegerDefaultValue() const
|
||||
{
|
||||
return default_value ? StringUtil::FromChars<s32>(default_value).value_or(0) : 0;
|
||||
}
|
||||
|
||||
s32 SettingInfo::IntegerMinValue() const
|
||||
{
|
||||
static constexpr s32 fallback_value = std::numeric_limits<s32>::min();
|
||||
return min_value ? StringUtil::FromChars<s32>(min_value).value_or(fallback_value) : fallback_value;
|
||||
}
|
||||
|
||||
s32 SettingInfo::IntegerMaxValue() const
|
||||
{
|
||||
static constexpr s32 fallback_value = std::numeric_limits<s32>::max();
|
||||
return max_value ? StringUtil::FromChars<s32>(max_value).value_or(fallback_value) : fallback_value;
|
||||
}
|
||||
|
||||
s32 SettingInfo::IntegerStepValue() const
|
||||
{
|
||||
static constexpr s32 fallback_value = 1;
|
||||
return step_value ? StringUtil::FromChars<s32>(step_value).value_or(fallback_value) : fallback_value;
|
||||
}
|
||||
|
||||
float SettingInfo::FloatDefaultValue() const
|
||||
{
|
||||
return default_value ? StringUtil::FromChars<float>(default_value).value_or(0.0f) : 0.0f;
|
||||
}
|
||||
|
||||
float SettingInfo::FloatMinValue() const
|
||||
{
|
||||
static constexpr float fallback_value = std::numeric_limits<float>::min();
|
||||
return min_value ? StringUtil::FromChars<float>(min_value).value_or(fallback_value) : fallback_value;
|
||||
}
|
||||
|
||||
float SettingInfo::FloatMaxValue() const
|
||||
{
|
||||
static constexpr float fallback_value = std::numeric_limits<float>::max();
|
||||
return max_value ? StringUtil::FromChars<float>(max_value).value_or(fallback_value) : fallback_value;
|
||||
}
|
||||
|
||||
float SettingInfo::FloatStepValue() const
|
||||
{
|
||||
static constexpr float fallback_value = 0.1f;
|
||||
return step_value ? StringUtil::FromChars<float>(step_value).value_or(fallback_value) : fallback_value;
|
||||
}
|
||||
|
||||
Settings::Settings() = default;
|
||||
|
||||
bool Settings::HasAnyPerGameMemoryCards() const
|
||||
|
@ -30,6 +30,38 @@ public:
|
||||
virtual void DeleteValue(const char* section, const char* key) = 0;
|
||||
};
|
||||
|
||||
struct SettingInfo
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
Boolean,
|
||||
Integer,
|
||||
Float,
|
||||
String,
|
||||
Path,
|
||||
};
|
||||
|
||||
Type type;
|
||||
const char* key;
|
||||
const char* visible_name;
|
||||
const char* description;
|
||||
const char* default_value;
|
||||
const char* min_value;
|
||||
const char* max_value;
|
||||
const char* step_value;
|
||||
|
||||
const char* StringDefaultValue() const;
|
||||
bool BooleanDefaultValue() const;
|
||||
s32 IntegerDefaultValue() const;
|
||||
s32 IntegerMinValue() const;
|
||||
s32 IntegerMaxValue() const;
|
||||
s32 IntegerStepValue() const;
|
||||
float FloatDefaultValue() const;
|
||||
float FloatMinValue() const;
|
||||
float FloatMaxValue() const;
|
||||
float FloatStepValue() const;
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
Settings();
|
||||
|
@ -832,11 +832,24 @@ void System::UpdateControllers()
|
||||
{
|
||||
std::unique_ptr<Controller> controller = Controller::Create(this, type, i);
|
||||
if (controller)
|
||||
{
|
||||
controller->LoadSettings(m_host_interface, TinyString::FromFormat("Controller%u", i + 1u));
|
||||
m_pad->SetController(i, std::move(controller));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void System::UpdateControllerSettings()
|
||||
{
|
||||
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
||||
{
|
||||
Controller* controller = m_pad->GetController(i);
|
||||
if (controller)
|
||||
controller->LoadSettings(m_host_interface, TinyString::FromFormat("Controller%u", i + 1u));
|
||||
}
|
||||
}
|
||||
|
||||
void System::UpdateMemoryCards()
|
||||
{
|
||||
const Settings& settings = m_host_interface->GetSettings();
|
||||
|
@ -139,6 +139,7 @@ public:
|
||||
// Access controllers for simulating input.
|
||||
Controller* GetController(u32 slot) const;
|
||||
void UpdateControllers();
|
||||
void UpdateControllerSettings();
|
||||
void UpdateMemoryCards();
|
||||
|
||||
bool HasMedia() const;
|
||||
|
Reference in New Issue
Block a user