input: add emulated axis configs

This commit is contained in:
Megamouse 2023-05-21 21:44:55 +02:00
parent c84d10686f
commit b82dd61a0c
9 changed files with 177 additions and 67 deletions

View File

@ -38,6 +38,8 @@ void fmt_class_string<gem_btn>::format(std::string& out, u64 arg)
case gem_btn::move: return "Move"; case gem_btn::move: return "Move";
case gem_btn::t: return "T"; case gem_btn::t: return "T";
case gem_btn::count: return "Count"; case gem_btn::count: return "Count";
case gem_btn::x_axis: return "X-Axis";
case gem_btn::y_axis: return "Y-Axis";
} }
return unknown; return unknown;
@ -709,6 +711,8 @@ static void ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t
digital_buttons |= CELL_GEM_CTRL_T; digital_buttons |= CELL_GEM_CTRL_T;
analog_t = std::max<u16>(analog_t, button.m_value); analog_t = std::max<u16>(analog_t, button.m_value);
break; break;
case gem_btn::x_axis:
case gem_btn::y_axis:
case gem_btn::count: case gem_btn::count:
break; break;
} }
@ -719,24 +723,46 @@ static void ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t
constexpr u16 ds3_max_x = 255; constexpr u16 ds3_max_x = 255;
constexpr u16 ds3_max_y = 255; constexpr u16 ds3_max_y = 255;
static inline void ds3_get_stick_values(const std::shared_ptr<Pad>& pad, s32& x_pos, s32& y_pos) static inline void ds3_get_stick_values(u32 port_no, const std::shared_ptr<Pad>& pad, s32& x_pos, s32& y_pos)
{ {
x_pos = 0; x_pos = 0;
y_pos = 0; y_pos = 0;
const auto& cfg = ::at32(g_cfg_gem.players, port_no);
std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
{
if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value())
{
switch (btn.value()->btn_id())
{
case gem_btn::x_axis:
x_pos = value;
break;
case gem_btn::y_axis:
y_pos = value;
break;
default:
break;
}
}
else if (check_axis)
{
switch (offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
default: break;
}
}
};
for (const AnalogStick& stick : pad->m_sticks) for (const AnalogStick& stick : pad->m_sticks)
{ {
switch (stick.m_offset) handle_input(stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true);
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
x_pos = stick.m_value;
break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
y_pos = stick.m_value;
break;
default:
break;
}
} }
} }
@ -759,7 +785,7 @@ static void ds3_pos_to_gem_state(const u32 port_no, const gem_config::gem_contro
} }
s32 ds3_pos_x, ds3_pos_y; s32 ds3_pos_x, ds3_pos_y;
ds3_get_stick_values(pad, ds3_pos_x, ds3_pos_y); ds3_get_stick_values(port_no, pad, ds3_pos_x, ds3_pos_y);
if constexpr (std::is_same<T, vm::ptr<CellGemState>>::value) if constexpr (std::is_same<T, vm::ptr<CellGemState>>::value)
{ {

View File

@ -28,6 +28,8 @@ void fmt_class_string<ghltar_btn>::format(std::string& out, u64 arg)
case ghltar_btn::strum_up: return "Strum Up"; case ghltar_btn::strum_up: return "Strum Up";
case ghltar_btn::dpad_left: return "D-Pad Left"; case ghltar_btn::dpad_left: return "D-Pad Left";
case ghltar_btn::dpad_right: return "D-Pad Right"; case ghltar_btn::dpad_right: return "D-Pad Right";
case ghltar_btn::whammy: return "Whammy";
case ghltar_btn::tilt: return "Tilt";
case ghltar_btn::count: return "Count"; case ghltar_btn::count: return "Count";
} }
@ -145,14 +147,10 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
return; return;
} }
for (const Button& button : pad->m_buttons) std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
{ {
if (!button.m_pressed) if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value())
{
continue;
}
if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value())
{ {
switch (btn.value()->btn_id()) switch (btn.value()->btn_id())
{ {
@ -195,28 +193,43 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
case ghltar_btn::ghtv: case ghltar_btn::ghtv:
buf[1] += 0x04; // GHTV Button buf[1] += 0x04; // GHTV Button
break; break;
case ghltar_btn::whammy:
buf[6] = ~(value) + 0x01; // Whammy
break;
case ghltar_btn::tilt:
buf[19] = static_cast<u8>(value); // Tilt
if (buf[19] >= 0xF0)
buf[5] = 0xFF;
else if (buf[19] <= 0x10)
buf[5] = 0x00;
break;
case ghltar_btn::count: case ghltar_btn::count:
break; break;
} }
} }
else if (check_axis)
{
switch (offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
default: break;
}
}
};
for (const Button& button : pad->m_buttons)
{
if (button.m_pressed)
{
handle_input(button.m_offset, button.m_outKeyCode, button.m_value, true);
}
} }
for (const AnalogStick& stick : pad->m_sticks) for (const AnalogStick& stick : pad->m_sticks)
{ {
switch (stick.m_offset) handle_input(stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true);
{
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
buf[6] = ~(stick.m_value) + 0x01; // Whammy
break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
buf[19] = static_cast<u8>(stick.m_value); // Tilt
if (buf[19] >= 0xF0)
buf[5] = 0xFF;
if (buf[19] <= 0x10)
buf[5] = 0x00;
break;
default:
break;
}
} }
} }

View File

@ -28,6 +28,9 @@ void fmt_class_string<turntable_btn>::format(std::string& out, u64 arg)
case turntable_btn::circle: return "Circle"; case turntable_btn::circle: return "Circle";
case turntable_btn::cross: return "Cross"; case turntable_btn::cross: return "Cross";
case turntable_btn::triangle: return "Triangle"; case turntable_btn::triangle: return "Triangle";
case turntable_btn::right_turntable: return "Right Turntable";
case turntable_btn::crossfader: return "Crossfader";
case turntable_btn::effects_dial: return "Effects Dial";
case turntable_btn::count: return "Count"; case turntable_btn::count: return "Count";
} }
@ -156,12 +159,10 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return; return;
for (const Button& button : pad->m_buttons) std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
{ {
if (!button.m_pressed) if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value())
continue;
if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value())
{ {
switch (btn.value()->btn_id()) switch (btn.value()->btn_id())
{ {
@ -262,18 +263,8 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
case turntable_btn::select: case turntable_btn::select:
buf[1] |= 0x01; // Select buf[1] |= 0x01; // Select
break; break;
case turntable_btn::count: case turntable_btn::right_turntable:
break; buf[6] = 255 - value; // Right Turntable
}
}
}
for (const AnalogStick& stick : pad->m_sticks)
{
switch (stick.m_offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
buf[6] = 255 - stick.m_value; // Right Turntable
// DJ Hero requires turntables to be centered at 128. // DJ Hero requires turntables to be centered at 128.
// If this axis ends up centered at 127, force it to 128. // If this axis ends up centered at 127, force it to 128.
if (buf[6] == 127) if (buf[6] == 127)
@ -281,16 +272,41 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
buf[6] = 128; buf[6] = 128;
} }
break; break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: case turntable_btn::crossfader:
buf[21] = ((255 - stick.m_value) & 0x3F) << 2; // Crossfader, lower 6 bits buf[21] = ((255 - value) & 0x3F) << 2; // Crossfader, lower 6 bits
buf[22] = ((255 - stick.m_value) & 0xC0) >> 6; // Crossfader, upper 2 bits buf[22] = ((255 - value) & 0xC0) >> 6; // Crossfader, upper 2 bits
break; break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: case turntable_btn::effects_dial:
buf[19] = (stick.m_value & 0x3F) << 2; // Effects Dial, lower 6 bits buf[19] = (value & 0x3F) << 2; // Effects Dial, lower 6 bits
buf[20] = (stick.m_value & 0xC0) >> 6; // Effects Dial, upper 2 bits buf[20] = (value & 0xC0) >> 6; // Effects Dial, upper 2 bits
break; break;
default: case turntable_btn::count:
break; break;
}
}
else if (check_axis)
{
switch (offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
default: break;
}
}
};
for (const Button& button : pad->m_buttons)
{
if (button.m_pressed)
{
handle_input(button.m_offset, button.m_outKeyCode, button.m_value, true);
} }
} }
for (const AnalogStick& stick : pad->m_sticks)
{
handle_input(stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true);
}
} }

View File

@ -14,6 +14,8 @@ enum class gem_btn
square, square,
move, move,
t, t,
x_axis,
y_axis,
count count
}; };
@ -30,6 +32,8 @@ struct cfg_gem final : public emulated_pad_config<gem_btn>
cfg_pad_btn<gem_btn> square{ this, "Square", gem_btn::square, pad_button::square }; cfg_pad_btn<gem_btn> square{ this, "Square", gem_btn::square, pad_button::square };
cfg_pad_btn<gem_btn> move{ this, "Move", gem_btn::move, pad_button::R1 }; cfg_pad_btn<gem_btn> move{ this, "Move", gem_btn::move, pad_button::R1 };
cfg_pad_btn<gem_btn> t{ this, "T", gem_btn::t, pad_button::R2 }; cfg_pad_btn<gem_btn> t{ this, "T", gem_btn::t, pad_button::R2 };
cfg_pad_btn<gem_btn> x_axis{ this, "X-Axis", gem_btn::x_axis, pad_button::ls_x };
cfg_pad_btn<gem_btn> y_axis{ this, "Y-Axis", gem_btn::y_axis, pad_button::ls_y };
}; };
struct cfg_gems final : public emulated_pads_config<cfg_gem> struct cfg_gems final : public emulated_pads_config<cfg_gem>

View File

@ -19,6 +19,8 @@ enum class ghltar_btn
strum_up, strum_up,
dpad_left, dpad_left,
dpad_right, dpad_right,
whammy,
tilt,
count count
}; };
@ -40,6 +42,8 @@ struct cfg_ghltar final : public emulated_pad_config<ghltar_btn>
cfg_pad_btn<ghltar_btn> strum_up{ this, "Strum Up", ghltar_btn::strum_up, pad_button::dpad_up }; cfg_pad_btn<ghltar_btn> strum_up{ this, "Strum Up", ghltar_btn::strum_up, pad_button::dpad_up };
cfg_pad_btn<ghltar_btn> dpad_left{ this, "D-Pad Left", ghltar_btn::dpad_left, pad_button::dpad_left }; cfg_pad_btn<ghltar_btn> dpad_left{ this, "D-Pad Left", ghltar_btn::dpad_left, pad_button::dpad_left };
cfg_pad_btn<ghltar_btn> dpad_right{ this, "D-Pad Right", ghltar_btn::dpad_right, pad_button::dpad_right }; cfg_pad_btn<ghltar_btn> dpad_right{ this, "D-Pad Right", ghltar_btn::dpad_right, pad_button::dpad_right };
cfg_pad_btn<ghltar_btn> whammy{ this, "Whammy", ghltar_btn::whammy, pad_button::rs_y };
cfg_pad_btn<ghltar_btn> tilt{ this, "tilt", ghltar_btn::whammy, pad_button::rs_x };
}; };
struct cfg_ghltars final : public emulated_pads_config<cfg_ghltar> struct cfg_ghltars final : public emulated_pads_config<cfg_ghltar>

View File

@ -29,10 +29,14 @@ void fmt_class_string<pad_button>::format(std::string& out, u64 arg)
case pad_button::ls_down: return "Left Stick Down"; case pad_button::ls_down: return "Left Stick Down";
case pad_button::ls_left: return "Left Stick Left"; case pad_button::ls_left: return "Left Stick Left";
case pad_button::ls_right: return "Left Stick Right"; case pad_button::ls_right: return "Left Stick Right";
case pad_button::ls_x: return "Left Stick X-Axis";
case pad_button::ls_y: return "Left Stick Y-Axis";
case pad_button::rs_up: return "Right Stick Up"; case pad_button::rs_up: return "Right Stick Up";
case pad_button::rs_down: return "Right Stick Down"; case pad_button::rs_down: return "Right Stick Down";
case pad_button::rs_left: return "Right Stick Left"; case pad_button::rs_left: return "Right Stick Left";
case pad_button::rs_right: return "Right Stick Right"; case pad_button::rs_right: return "Right Stick Right";
case pad_button::rs_x: return "Right Stick X-Axis";
case pad_button::rs_y: return "Right Stick Y-Axis";
case pad_button::pad_button_max_enum: return unknown; case pad_button::pad_button_max_enum: return unknown;
} }
@ -65,10 +69,14 @@ u32 pad_button_offset(pad_button button)
case pad_button::ls_down: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y; case pad_button::ls_down: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y;
case pad_button::ls_left: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X; case pad_button::ls_left: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X;
case pad_button::ls_right: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X; case pad_button::ls_right: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X;
case pad_button::ls_x: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X;
case pad_button::ls_y: return CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y;
case pad_button::rs_up: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y; case pad_button::rs_up: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y;
case pad_button::rs_down: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y; case pad_button::rs_down: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y;
case pad_button::rs_left: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X; case pad_button::rs_left: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X;
case pad_button::rs_right: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X; case pad_button::rs_right: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X;
case pad_button::rs_x: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X;
case pad_button::rs_y: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y;
case pad_button::pad_button_max_enum: return 0; case pad_button::pad_button_max_enum: return 0;
} }
return 0; return 0;
@ -95,15 +103,31 @@ u32 pad_button_keycode(pad_button button)
case pad_button::R2: return CELL_PAD_CTRL_R2; case pad_button::R2: return CELL_PAD_CTRL_R2;
case pad_button::L3: return CELL_PAD_CTRL_L3; case pad_button::L3: return CELL_PAD_CTRL_L3;
case pad_button::R3: return CELL_PAD_CTRL_R3; case pad_button::R3: return CELL_PAD_CTRL_R3;
case pad_button::ls_up: return 0; case pad_button::ls_up: return static_cast<u32>(axis_direction::positive);
case pad_button::ls_down: return 0; case pad_button::ls_down: return static_cast<u32>(axis_direction::negative);
case pad_button::ls_left: return 0; case pad_button::ls_left: return static_cast<u32>(axis_direction::negative);
case pad_button::ls_right: return 0; case pad_button::ls_right: return static_cast<u32>(axis_direction::positive);
case pad_button::rs_up: return 0; case pad_button::ls_x: return static_cast<u32>(axis_direction::both);
case pad_button::rs_down: return 0; case pad_button::ls_y: return static_cast<u32>(axis_direction::both);
case pad_button::rs_left: return 0; case pad_button::rs_up: return static_cast<u32>(axis_direction::positive);
case pad_button::rs_right: return 0; case pad_button::rs_down: return static_cast<u32>(axis_direction::negative);
case pad_button::rs_left: return static_cast<u32>(axis_direction::negative);
case pad_button::rs_right: return static_cast<u32>(axis_direction::positive);
case pad_button::rs_x: return static_cast<u32>(axis_direction::both);
case pad_button::rs_y: return static_cast<u32>(axis_direction::both);
case pad_button::pad_button_max_enum: return 0; case pad_button::pad_button_max_enum: return 0;
} }
return 0; return 0;
} }
u32 get_axis_keycode(u32 offset, u16 value)
{
switch (offset)
{
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: return static_cast<u32>(value > 127 ? axis_direction::positive : axis_direction::negative);
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: return static_cast<u32>(value > 127 ? axis_direction::positive : axis_direction::negative);
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: return static_cast<u32>(value > 127 ? axis_direction::positive : axis_direction::negative);
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: return static_cast<u32>(value > 127 ? axis_direction::positive : axis_direction::negative);
default: return static_cast<u32>(axis_direction::both);
}
}

View File

@ -30,10 +30,14 @@ enum class pad_button : u8
ls_down, ls_down,
ls_left, ls_left,
ls_right, ls_right,
ls_x,
ls_y,
rs_up, rs_up,
rs_down, rs_down,
rs_left, rs_left,
rs_right, rs_right,
rs_x,
rs_y,
pad_button_max_enum pad_button_max_enum
}; };
@ -41,6 +45,15 @@ enum class pad_button : u8
u32 pad_button_offset(pad_button button); u32 pad_button_offset(pad_button button);
u32 pad_button_keycode(pad_button button); u32 pad_button_keycode(pad_button button);
enum class axis_direction : u8
{
both = 0,
negative,
positive
};
u32 get_axis_keycode(u32 offset, u16 value);
enum SystemInfo enum SystemInfo
{ {
CELL_PAD_INFO_INTERCEPTED = 0x00000001 CELL_PAD_INFO_INTERCEPTED = 0x00000001

View File

@ -19,6 +19,9 @@ enum class turntable_btn
circle, circle,
cross, cross,
triangle, triangle,
right_turntable,
crossfader,
effects_dial,
count count
}; };
@ -40,6 +43,9 @@ struct cfg_turntable final : public emulated_pad_config<turntable_btn>
cfg_pad_btn<turntable_btn> circle{ this, "Circle", turntable_btn::circle, pad_button::L1 }; cfg_pad_btn<turntable_btn> circle{ this, "Circle", turntable_btn::circle, pad_button::L1 };
cfg_pad_btn<turntable_btn> cross{ this, "Cross", turntable_btn::cross, pad_button::R1 }; cfg_pad_btn<turntable_btn> cross{ this, "Cross", turntable_btn::cross, pad_button::R1 };
cfg_pad_btn<turntable_btn> triangle{ this, "Triangle", turntable_btn::triangle, pad_button::triangle }; cfg_pad_btn<turntable_btn> triangle{ this, "Triangle", turntable_btn::triangle, pad_button::triangle };
cfg_pad_btn<turntable_btn> right_turntable{ this, "Right Turntable", turntable_btn::right_turntable, pad_button::ls_y };
cfg_pad_btn<turntable_btn> crossfader{ this, "Crossfader", turntable_btn::crossfader, pad_button::rs_y };
cfg_pad_btn<turntable_btn> effects_dial{ this, "Effects Dial", turntable_btn::effects_dial, pad_button::rs_x };
}; };
struct cfg_turntables final : public emulated_pads_config<cfg_turntable> struct cfg_turntables final : public emulated_pads_config<cfg_turntable>

View File

@ -26,10 +26,14 @@ QString localized_emu::translated_pad_button(pad_button btn)
case pad_button::ls_down: return tr("Left Stick Down"); case pad_button::ls_down: return tr("Left Stick Down");
case pad_button::ls_left: return tr("Left Stick Left"); case pad_button::ls_left: return tr("Left Stick Left");
case pad_button::ls_right: return tr("Left Stick Right"); case pad_button::ls_right: return tr("Left Stick Right");
case pad_button::ls_x: return tr("Left Stick X-Axis");
case pad_button::ls_y: return tr("Left Stick Y-Axis");
case pad_button::rs_up: return tr("Right Stick Up"); case pad_button::rs_up: return tr("Right Stick Up");
case pad_button::rs_down: return tr("Right Stick Down"); case pad_button::rs_down: return tr("Right Stick Down");
case pad_button::rs_left: return tr("Right Stick Left"); case pad_button::rs_left: return tr("Right Stick Left");
case pad_button::rs_right: return tr("Right Stick Right"); case pad_button::rs_right: return tr("Right Stick Right");
case pad_button::rs_x: return tr("Right Stick X-Axis");
case pad_button::rs_y: return tr("Right Stick Y-Axis");
case pad_button::pad_button_max_enum: return ""; case pad_button::pad_button_max_enum: return "";
} }
return ""; return "";