Duckstation/src/core/controller.h

152 lines
4.8 KiB
C
Raw Normal View History

// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
#include "common/image.h"
#include "settings.h"
#include "types.h"
2019-12-10 13:05:19 +00:00
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>
class SettingsInterface;
2019-09-29 15:59:35 +00:00
class StateWrapper;
class HostInterface;
2019-09-29 15:59:35 +00:00
enum class GenericInputBinding : u8;
class Controller
{
public:
enum class ControllerBindingType : u8
{
Unknown,
Button,
Axis,
HalfAxis,
Motor,
Macro
};
enum class VibrationCapabilities : u8
{
NoVibration,
LargeSmallMotors,
SingleMotor,
Count
};
struct ControllerBindingInfo
{
const char* name;
const char* display_name;
u32 bind_index;
ControllerBindingType type;
GenericInputBinding generic_mapping;
};
struct ControllerInfo
{
ControllerType type;
const char* name;
const char* display_name;
const ControllerBindingInfo* bindings;
u32 num_bindings;
const SettingInfo* settings;
u32 num_settings;
VibrationCapabilities vibration_caps;
};
/// Default stick deadzone/sensitivity.
static constexpr float DEFAULT_STICK_DEADZONE = 0.0f;
static constexpr float DEFAULT_STICK_SENSITIVITY = 1.33f;
static constexpr float DEFAULT_BUTTON_DEADZONE = 0.25f;
Controller(u32 index);
virtual ~Controller();
/// Returns the type of controller.
virtual ControllerType GetType() const = 0;
2019-09-29 15:59:35 +00:00
virtual void Reset();
virtual bool DoState(StateWrapper& sw, bool apply_input_state);
2019-09-29 15:59:35 +00:00
2019-09-29 15:07:38 +00:00
// Resets all state for the transferring to/from the device.
virtual void ResetTransferState();
// Returns the value of ACK, as well as filling out_data.
virtual bool Transfer(const u8 data_in, u8* data_out);
/// Changes the specified axis state. Values are normalized from -1..1.
virtual float GetBindState(u32 index) const;
/// Changes the specified bind state. Values are normalized from -1..1.
virtual void SetBindState(u32 index, float value);
2020-12-06 05:47:00 +00:00
/// Returns a bitmask of the current button states, 1 = on.
virtual u32 GetButtonStateBits() const;
/// Returns true if the controller supports analog mode, and it is active.
virtual bool InAnalogMode() const;
/// Returns analog input bytes packed as a u32. Values are specific to controller type.
virtual std::optional<u32> GetAnalogInputBytes() const;
/// Loads/refreshes any per-controller settings.
virtual void LoadSettings(SettingsInterface& si, const char* section);
/// Returns the software cursor to use for this controller, if any.
2020-12-27 04:08:13 +00:00
virtual bool GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale, bool* relative_mode);
/// Creates a new controller of the specified type.
JIT optimizations and refactoring (#675) * CPU/Recompiler: Use rel32 call where possible for no-args * JitCodeBuffer: Support using preallocated buffer * CPU/Recompiler/AArch64: Use bl instead of blr for short branches * CPU/CodeCache: Allocate recompiler buffer in program space This means we don't need 64-bit moves for every call out of the recompiler. * GTE: Don't store as u16 and load as u32 * CPU/Recompiler: Add methods to emit global load/stores * GTE: Convert class to namespace * CPU/Recompiler: Call GTE functions directly * Settings: Turn into a global variable * GPU: Replace local pointers with global * InterruptController: Turn into a global pointer * System: Replace local pointers with global * Timers: Turn into a global instance * DMA: Turn into a global instance * SPU: Turn into a global instance * CDROM: Turn into a global instance * MDEC: Turn into a global instance * Pad: Turn into a global instance * SIO: Turn into a global instance * CDROM: Move audio FIFO to the heap * CPU/Recompiler: Drop ASMFunctions No longer needed since we have code in the same 4GB window. * CPUCodeCache: Turn class into namespace * Bus: Local pointer -> global pointers * CPU: Turn class into namespace * Bus: Turn into namespace * GTE: Store registers in CPU state struct Allows relative addressing on ARM. * CPU/Recompiler: Align code storage to page size * CPU/Recompiler: Fix relative branches on A64 * HostInterface: Local references to global * System: Turn into a namespace, move events out * Add guard pages * Android: Fix build
2020-07-31 07:09:18 +00:00
static std::unique_ptr<Controller> Create(ControllerType type, u32 index);
/// Returns the default type for the specified port.
static const char* GetDefaultPadType(u32 pad);
/// Returns a list of controller type names. Pair of [name, display name].
static std::vector<std::pair<std::string, std::string>> GetControllerTypeNames();
/// Returns the list of binds for the specified controller type.
static std::vector<std::string> GetControllerBinds(const std::string_view& type);
static std::vector<std::string> GetControllerBinds(ControllerType type);
/// Gets the integer code for an axis in the specified controller type.
static std::optional<u32> GetBindIndex(ControllerType type, const std::string_view& bind_name);
/// Returns the vibration configuration for the specified controller type.
static VibrationCapabilities GetControllerVibrationCapabilities(const std::string_view& type);
/// Returns general information for the specified controller type.
static const ControllerInfo* GetControllerInfo(ControllerType type);
static const ControllerInfo* GetControllerInfo(const std::string_view& name);
/// Converts a global pad index to a multitap port and slot.
static std::tuple<u32, u32> ConvertPadToPortAndSlot(u32 index);
/// Converts a multitap port and slot to a global pad index.
static u32 ConvertPortAndSlotToPad(u32 port, u32 slot);
/// Returns true if the given pad index is a multitap slot.
static bool PadIsMultitapSlot(u32 index);
static bool PortAndSlotIsMultitap(u32 port, u32 slot);
/// Returns the configuration section for the specified gamepad.
static std::string GetSettingsSection(u32 pad);
/// Applies an analog deadzone/sensitivity.
static float ApplyAnalogDeadzoneSensitivity(float deadzone, float sensitivity, float value)
{
return (value < deadzone) ? 0.0f : ((value - deadzone) / (1.0f - deadzone) * sensitivity);
}
2022-10-21 11:14:27 +00:00
/// Returns true if the specified coordinates are inside a circular deadzone.
static bool InCircularDeadzone(float deadzone, float pos_x, float pos_y);
protected:
u32 m_index;
};