mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-03-28 13:10:51 -05:00
The Setting class was used for both numeric values and booleans, and other parts of the code had hacks to make it work with booleans. By splitting Setting into NumericSetting and BooleanSetting, it is clear which settings are numeric, and which are boolean, so there is no need to guess by checking the default values or anything like that. Also, booleans are stored as booleans in config files, instead of 1.0.
195 lines
6.4 KiB
C++
195 lines
6.4 KiB
C++
// Copyright 2010 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include "Core/HW/GCPadEmu.h"
|
|
#include "Common/Common.h"
|
|
#include "Common/CommonTypes.h"
|
|
#include "Core/Host.h"
|
|
|
|
static const u16 button_bitmasks[] = {
|
|
PAD_BUTTON_A,
|
|
PAD_BUTTON_B,
|
|
PAD_BUTTON_X,
|
|
PAD_BUTTON_Y,
|
|
PAD_TRIGGER_Z,
|
|
PAD_BUTTON_START,
|
|
0 // MIC HAX
|
|
};
|
|
|
|
static const u16 trigger_bitmasks[] = {
|
|
PAD_TRIGGER_L, PAD_TRIGGER_R,
|
|
};
|
|
|
|
static const u16 dpad_bitmasks[] = {PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT,
|
|
PAD_BUTTON_RIGHT};
|
|
|
|
static const char* const named_buttons[] = {"A", "B", "X", "Y", "Z", _trans("Start"),
|
|
_trans("Mic")};
|
|
|
|
static const char* const named_triggers[] = {
|
|
// i18n: Left
|
|
_trans("L"),
|
|
// i18n: Right
|
|
_trans("R"),
|
|
// i18n: Left-Analog
|
|
_trans("L-Analog"),
|
|
// i18n: Right-Analog
|
|
_trans("R-Analog")};
|
|
|
|
GCPad::GCPad(const unsigned int index) : m_index(index)
|
|
{
|
|
int const mic_hax = index > 1;
|
|
|
|
// buttons
|
|
groups.emplace_back(m_buttons = new Buttons(_trans("Buttons")));
|
|
for (unsigned int i = 0; i < sizeof(named_buttons) / sizeof(*named_buttons) - mic_hax; ++i)
|
|
m_buttons->controls.emplace_back(new ControlGroup::Input(named_buttons[i]));
|
|
|
|
// sticks
|
|
groups.emplace_back(m_main_stick = new AnalogStick("Main Stick", _trans("Control Stick"),
|
|
DEFAULT_PAD_STICK_RADIUS));
|
|
groups.emplace_back(m_c_stick =
|
|
new AnalogStick("C-Stick", _trans("C Stick"), DEFAULT_PAD_STICK_RADIUS));
|
|
|
|
// triggers
|
|
groups.emplace_back(m_triggers = new MixedTriggers(_trans("Triggers")));
|
|
for (auto& named_trigger : named_triggers)
|
|
m_triggers->controls.emplace_back(new ControlGroup::Input(named_trigger));
|
|
|
|
// rumble
|
|
groups.emplace_back(m_rumble = new ControlGroup(_trans("Rumble")));
|
|
m_rumble->controls.emplace_back(new ControlGroup::Output(_trans("Motor")));
|
|
|
|
// dpad
|
|
groups.emplace_back(m_dpad = new Buttons(_trans("D-Pad")));
|
|
for (auto& named_direction : named_directions)
|
|
m_dpad->controls.emplace_back(new ControlGroup::Input(named_direction));
|
|
|
|
// options
|
|
groups.emplace_back(m_options = new ControlGroup(_trans("Options")));
|
|
m_options->boolean_settings.emplace_back(
|
|
std::make_unique<ControlGroup::BackgroundInputSetting>(_trans("Background Input")));
|
|
m_options->boolean_settings.emplace_back(std::make_unique<ControlGroup::BooleanSetting>(
|
|
_trans("Iterative Input"), false, ControlGroup::SettingType::VIRTUAL));
|
|
}
|
|
|
|
std::string GCPad::GetName() const
|
|
{
|
|
return std::string("GCPad") + char('1' + m_index);
|
|
}
|
|
|
|
void GCPad::GetInput(GCPadStatus* const pad)
|
|
{
|
|
ControlState x, y, triggers[2];
|
|
|
|
// buttons
|
|
m_buttons->GetState(&pad->button, button_bitmasks);
|
|
|
|
// set analog A/B analog to full or w/e, prolly not needed
|
|
if (pad->button & PAD_BUTTON_A)
|
|
pad->analogA = 0xFF;
|
|
if (pad->button & PAD_BUTTON_B)
|
|
pad->analogB = 0xFF;
|
|
|
|
// dpad
|
|
m_dpad->GetState(&pad->button, dpad_bitmasks);
|
|
|
|
// sticks
|
|
m_main_stick->GetState(&x, &y);
|
|
pad->stickX =
|
|
static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_X + (x * GCPadStatus::MAIN_STICK_RADIUS));
|
|
pad->stickY =
|
|
static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_Y + (y * GCPadStatus::MAIN_STICK_RADIUS));
|
|
|
|
m_c_stick->GetState(&x, &y);
|
|
pad->substickX =
|
|
static_cast<u8>(GCPadStatus::C_STICK_CENTER_X + (x * GCPadStatus::C_STICK_RADIUS));
|
|
pad->substickY =
|
|
static_cast<u8>(GCPadStatus::C_STICK_CENTER_Y + (y * GCPadStatus::C_STICK_RADIUS));
|
|
|
|
// triggers
|
|
m_triggers->GetState(&pad->button, trigger_bitmasks, triggers);
|
|
pad->triggerLeft = static_cast<u8>(triggers[0] * 0xFF);
|
|
pad->triggerRight = static_cast<u8>(triggers[1] * 0xFF);
|
|
}
|
|
|
|
void GCPad::SetOutput(const ControlState strength)
|
|
{
|
|
m_rumble->controls[0]->control_ref->State(strength);
|
|
}
|
|
|
|
void GCPad::LoadDefaults(const ControllerInterface& ciface)
|
|
{
|
|
ControllerEmu::LoadDefaults(ciface);
|
|
|
|
// Buttons
|
|
m_buttons->SetControlExpression(0, "X"); // A
|
|
m_buttons->SetControlExpression(1, "Z"); // B
|
|
m_buttons->SetControlExpression(2, "C"); // X
|
|
m_buttons->SetControlExpression(3, "S"); // Y
|
|
m_buttons->SetControlExpression(4, "D"); // Z
|
|
#ifdef _WIN32
|
|
m_buttons->SetControlExpression(5, "!LMENU & RETURN"); // Start
|
|
#else
|
|
// OS X/Linux
|
|
m_buttons->SetControlExpression(5, "!`Alt_L` & Return"); // Start
|
|
#endif
|
|
|
|
// stick modifiers to 50 %
|
|
m_main_stick->controls[4]->control_ref->range = 0.5f;
|
|
m_c_stick->controls[4]->control_ref->range = 0.5f;
|
|
|
|
// D-Pad
|
|
m_dpad->SetControlExpression(0, "T"); // Up
|
|
m_dpad->SetControlExpression(1, "G"); // Down
|
|
m_dpad->SetControlExpression(2, "F"); // Left
|
|
m_dpad->SetControlExpression(3, "H"); // Right
|
|
|
|
// C Stick
|
|
m_c_stick->SetControlExpression(0, "I"); // Up
|
|
m_c_stick->SetControlExpression(1, "K"); // Down
|
|
m_c_stick->SetControlExpression(2, "J"); // Left
|
|
m_c_stick->SetControlExpression(3, "L"); // Right
|
|
#ifdef _WIN32
|
|
m_c_stick->SetControlExpression(4, "LCONTROL"); // Modifier
|
|
|
|
// Control Stick
|
|
m_main_stick->SetControlExpression(0, "UP"); // Up
|
|
m_main_stick->SetControlExpression(1, "DOWN"); // Down
|
|
m_main_stick->SetControlExpression(2, "LEFT"); // Left
|
|
m_main_stick->SetControlExpression(3, "RIGHT"); // Right
|
|
m_main_stick->SetControlExpression(4, "LSHIFT"); // Modifier
|
|
|
|
#elif __APPLE__
|
|
m_c_stick->SetControlExpression(4, "Left Control"); // Modifier
|
|
|
|
// Control Stick
|
|
m_main_stick->SetControlExpression(0, "Up Arrow"); // Up
|
|
m_main_stick->SetControlExpression(1, "Down Arrow"); // Down
|
|
m_main_stick->SetControlExpression(2, "Left Arrow"); // Left
|
|
m_main_stick->SetControlExpression(3, "Right Arrow"); // Right
|
|
m_main_stick->SetControlExpression(4, "Left Shift"); // Modifier
|
|
#else
|
|
// not sure if these are right
|
|
|
|
m_c_stick->SetControlExpression(4, "Control_L"); // Modifier
|
|
|
|
// Control Stick
|
|
m_main_stick->SetControlExpression(0, "Up"); // Up
|
|
m_main_stick->SetControlExpression(1, "Down"); // Down
|
|
m_main_stick->SetControlExpression(2, "Left"); // Left
|
|
m_main_stick->SetControlExpression(3, "Right"); // Right
|
|
m_main_stick->SetControlExpression(4, "Shift_L"); // Modifier
|
|
#endif
|
|
|
|
// Triggers
|
|
m_triggers->SetControlExpression(0, "Q"); // L
|
|
m_triggers->SetControlExpression(1, "W"); // R
|
|
}
|
|
|
|
bool GCPad::GetMicButton() const
|
|
{
|
|
return (0.0f != m_buttons->controls.back()->control_ref->State());
|
|
}
|