mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
Merge d47b58e993
into 4704c03209
This commit is contained in:
commit
9c7462f2ce
12 changed files with 714 additions and 157 deletions
|
@ -394,6 +394,7 @@ target_sources(rpcs3_emu PRIVATE
|
|||
Io/Dimensions.cpp
|
||||
Io/evdev_gun_handler.cpp
|
||||
Io/GameTablet.cpp
|
||||
Io/gem_config.cpp
|
||||
Io/GHLtar.cpp
|
||||
Io/GunCon3.cpp
|
||||
Io/Infinity.cpp
|
||||
|
|
|
@ -27,39 +27,6 @@
|
|||
|
||||
LOG_CHANNEL(cellGem);
|
||||
|
||||
template <>
|
||||
void fmt_class_string<gem_btn>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](gem_btn value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case gem_btn::start: return "Start";
|
||||
case gem_btn::select: return "Select";
|
||||
case gem_btn::triangle: return "Triangle";
|
||||
case gem_btn::circle: return "Circle";
|
||||
case gem_btn::cross: return "Cross";
|
||||
case gem_btn::square: return "Square";
|
||||
case gem_btn::move: return "Move";
|
||||
case gem_btn::t: return "T";
|
||||
case gem_btn::x_axis: return "X-Axis";
|
||||
case gem_btn::y_axis: return "Y-Axis";
|
||||
case gem_btn::combo: return "Combo";
|
||||
case gem_btn::combo_start: return "Combo Start";
|
||||
case gem_btn::combo_select: return "Combo Select";
|
||||
case gem_btn::combo_triangle: return "Combo Triangle";
|
||||
case gem_btn::combo_circle: return "Combo Circle";
|
||||
case gem_btn::combo_cross: return "Combo Cross";
|
||||
case gem_btn::combo_square: return "Combo Square";
|
||||
case gem_btn::combo_move: return "Combo Move";
|
||||
case gem_btn::combo_t: return "Combo T";
|
||||
case gem_btn::count: return "Count";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<CellGemError>::format(std::string& out, u64 arg)
|
||||
{
|
||||
|
@ -234,7 +201,7 @@ public:
|
|||
struct gem_controller
|
||||
{
|
||||
u32 status = CELL_GEM_STATUS_DISCONNECTED; // Connection status (CELL_GEM_STATUS_DISCONNECTED or CELL_GEM_STATUS_READY)
|
||||
u32 ext_status = CELL_GEM_NO_EXTERNAL_PORT_DEVICE; // External port connection status
|
||||
u32 ext_status = 0; // External port connection status
|
||||
u32 ext_id = 0; // External device ID (type). For example SHARP_SHOOTER_DEVICE_ID
|
||||
u32 port = 0; // Assigned port
|
||||
bool enabled_magnetometer = true; // Whether the magnetometer is enabled (probably used for additional rotational precision)
|
||||
|
@ -1918,6 +1885,312 @@ static void ps_move_pos_to_gem_state(u32 gem_num, gem_config::gem_controller& co
|
|||
}
|
||||
}
|
||||
|
||||
static const std::unordered_map<gem_btn, u16> ext_btn_map =
|
||||
{
|
||||
{ gem_btn::sharpshooter_firing_mode_1, button_flags::ss_firing_mode_1 },
|
||||
{ gem_btn::sharpshooter_firing_mode_2, button_flags::ss_firing_mode_2 },
|
||||
{ gem_btn::sharpshooter_firing_mode_3, button_flags::ss_firing_mode_3 },
|
||||
{ gem_btn::sharpshooter_trigger, button_flags::ss_trigger },
|
||||
{ gem_btn::sharpshooter_reload, button_flags::ss_reload },
|
||||
{ gem_btn::racing_wheel_d_pad_up, CELL_PAD_CTRL_UP },
|
||||
{ gem_btn::racing_wheel_d_pad_right, CELL_PAD_CTRL_RIGHT },
|
||||
{ gem_btn::racing_wheel_d_pad_down, CELL_PAD_CTRL_DOWN },
|
||||
{ gem_btn::racing_wheel_d_pad_left, CELL_PAD_CTRL_LEFT },
|
||||
{ gem_btn::racing_wheel_throttle, 0 },
|
||||
{ gem_btn::racing_wheel_l1, CELL_PAD_CTRL_L1 },
|
||||
{ gem_btn::racing_wheel_r1, CELL_PAD_CTRL_R1 },
|
||||
{ gem_btn::racing_wheel_l2, 0 },
|
||||
{ gem_btn::racing_wheel_r2, 0 },
|
||||
{ gem_btn::racing_wheel_paddle_l, button_flags::rw_paddle_l },
|
||||
{ gem_btn::racing_wheel_paddle_r, button_flags::rw_paddle_r },
|
||||
{ gem_btn::combo_sharpshooter_firing_mode_1, button_flags::ss_firing_mode_1 },
|
||||
{ gem_btn::combo_sharpshooter_firing_mode_2, button_flags::ss_firing_mode_2 },
|
||||
{ gem_btn::combo_sharpshooter_firing_mode_3, button_flags::ss_firing_mode_3 },
|
||||
{ gem_btn::combo_sharpshooter_trigger, button_flags::ss_trigger },
|
||||
{ gem_btn::combo_sharpshooter_reload, button_flags::ss_reload },
|
||||
{ gem_btn::combo_racing_wheel_d_pad_up, CELL_PAD_CTRL_UP },
|
||||
{ gem_btn::combo_racing_wheel_d_pad_right, CELL_PAD_CTRL_RIGHT },
|
||||
{ gem_btn::combo_racing_wheel_d_pad_down, CELL_PAD_CTRL_DOWN },
|
||||
{ gem_btn::combo_racing_wheel_d_pad_left, CELL_PAD_CTRL_LEFT },
|
||||
{ gem_btn::combo_racing_wheel_throttle, 0 },
|
||||
{ gem_btn::combo_racing_wheel_l1, CELL_PAD_CTRL_L1 },
|
||||
{ gem_btn::combo_racing_wheel_r1, CELL_PAD_CTRL_R1 },
|
||||
{ gem_btn::combo_racing_wheel_l2, 0 },
|
||||
{ gem_btn::combo_racing_wheel_r2, 0 },
|
||||
{ gem_btn::combo_racing_wheel_paddle_l, button_flags::rw_paddle_l },
|
||||
{ gem_btn::combo_racing_wheel_paddle_r, button_flags::rw_paddle_r },
|
||||
};
|
||||
|
||||
static const std::unordered_map<gem_btn, u16> ext_btn_indices =
|
||||
{
|
||||
{ gem_btn::racing_wheel_throttle, 0 },
|
||||
{ gem_btn::racing_wheel_l2, 1 },
|
||||
{ gem_btn::racing_wheel_r2, 2 },
|
||||
{ gem_btn::racing_wheel_paddle_l, 3 },
|
||||
{ gem_btn::racing_wheel_paddle_r, 4 },
|
||||
{ gem_btn::combo_racing_wheel_throttle, 0 },
|
||||
{ gem_btn::combo_racing_wheel_l2, 1 },
|
||||
{ gem_btn::combo_racing_wheel_r2, 2 },
|
||||
{ gem_btn::combo_racing_wheel_paddle_l, 3 },
|
||||
{ gem_btn::combo_racing_wheel_paddle_r, 4 },
|
||||
};
|
||||
|
||||
static u32 ext_device_id(gem_ext_id id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case gem_ext_id::disconnected: return 0;
|
||||
case gem_ext_id::sharpshooter: return SHARP_SHOOTER_DEVICE_ID;
|
||||
case gem_ext_id::racing_wheel: return RACING_WHEEL_DEVICE_ID;
|
||||
}
|
||||
fmt::throw_exception("Mo ID found for id = %d", static_cast<s32>(id));
|
||||
}
|
||||
|
||||
template <bool has_combo, bool is_combo>
|
||||
static void input_to_ext(u32 external_device_id, CellGemExtPortData& ext, std::set<pad_button>& combos, gem_btn btn, pad_button pad_btn, u16 value, bool pressed)
|
||||
{
|
||||
if (!pressed)
|
||||
return;
|
||||
|
||||
if constexpr (has_combo && is_combo)
|
||||
{
|
||||
if (external_device_id == SHARP_SHOOTER_DEVICE_ID)
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case gem_btn::combo_sharpshooter_firing_mode_1:
|
||||
case gem_btn::combo_sharpshooter_firing_mode_2:
|
||||
case gem_btn::combo_sharpshooter_firing_mode_3:
|
||||
case gem_btn::combo_sharpshooter_trigger:
|
||||
case gem_btn::combo_sharpshooter_reload:
|
||||
ext.custom[0] |= ::at32(ext_btn_map, btn);
|
||||
combos.insert(pad_btn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (external_device_id == RACING_WHEEL_DEVICE_ID)
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case gem_btn::combo_racing_wheel_throttle:
|
||||
case gem_btn::combo_racing_wheel_l2:
|
||||
case gem_btn::combo_racing_wheel_r2:
|
||||
ext.custom[::at32(ext_btn_indices, btn)] = static_cast<u8>(value);
|
||||
combos.insert(pad_btn);
|
||||
break;
|
||||
case gem_btn::combo_racing_wheel_paddle_l:
|
||||
case gem_btn::combo_racing_wheel_paddle_r:
|
||||
ext.custom[::at32(ext_btn_indices, btn)] |= ::at32(ext_btn_map, btn);
|
||||
combos.insert(pad_btn);
|
||||
break;
|
||||
case gem_btn::combo_racing_wheel_d_pad_up:
|
||||
case gem_btn::combo_racing_wheel_d_pad_right:
|
||||
case gem_btn::combo_racing_wheel_d_pad_down:
|
||||
case gem_btn::combo_racing_wheel_d_pad_left:
|
||||
ext.digital1 |= ::at32(ext_btn_map, btn);
|
||||
combos.insert(pad_btn);
|
||||
break;
|
||||
case gem_btn::combo_racing_wheel_l1:
|
||||
case gem_btn::combo_racing_wheel_r1:
|
||||
ext.digital2 |= ::at32(ext_btn_map, btn);
|
||||
combos.insert(pad_btn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (has_combo)
|
||||
{
|
||||
if (combos.contains(pad_btn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (external_device_id == SHARP_SHOOTER_DEVICE_ID)
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case gem_btn::sharpshooter_firing_mode_1:
|
||||
case gem_btn::sharpshooter_firing_mode_2:
|
||||
case gem_btn::sharpshooter_firing_mode_3:
|
||||
case gem_btn::sharpshooter_trigger:
|
||||
case gem_btn::sharpshooter_reload:
|
||||
ext.custom[0] |= ::at32(ext_btn_map, btn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (external_device_id == RACING_WHEEL_DEVICE_ID)
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case gem_btn::combo_racing_wheel_throttle:
|
||||
case gem_btn::combo_racing_wheel_l2:
|
||||
case gem_btn::combo_racing_wheel_r2:
|
||||
ext.custom[::at32(ext_btn_indices, btn)] = static_cast<u8>(value);
|
||||
break;
|
||||
case gem_btn::combo_racing_wheel_paddle_l:
|
||||
case gem_btn::combo_racing_wheel_paddle_r:
|
||||
ext.custom[::at32(ext_btn_indices, btn)] |= ::at32(ext_btn_map, btn);
|
||||
break;
|
||||
case gem_btn::combo_racing_wheel_d_pad_up:
|
||||
case gem_btn::combo_racing_wheel_d_pad_right:
|
||||
case gem_btn::combo_racing_wheel_d_pad_down:
|
||||
case gem_btn::combo_racing_wheel_d_pad_left:
|
||||
ext.digital1 |= ::at32(ext_btn_map, btn);
|
||||
break;
|
||||
case gem_btn::combo_racing_wheel_l1:
|
||||
case gem_btn::combo_racing_wheel_r1:
|
||||
ext.digital2 |= ::at32(ext_btn_map, btn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void real_input_to_ext(u32 gem_num, gem_config::gem_controller& controller, CellGemExtPortData& ext)
|
||||
{
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (!pad->is_connected())
|
||||
{
|
||||
controller.ext_status = 0;
|
||||
controller.ext_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ps_move_data& move_data = pad->move_data;
|
||||
|
||||
controller.ext_status = move_data.external_device_connected ? CELL_GEM_EXT_CONNECTED : 0; // TODO: | CELL_GEM_EXT_EXT0 | CELL_GEM_EXT_EXT1
|
||||
controller.ext_id = move_data.external_device_connected ? move_data.external_device_id : 0;
|
||||
|
||||
if (!move_data.external_device_connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// ext.analog_left_x
|
||||
// ext.analog_left_y
|
||||
// ext.analog_right_x
|
||||
// ext.analog_right_y
|
||||
// ext.digital1
|
||||
// ext.digital2
|
||||
|
||||
ext.status = controller.ext_status;
|
||||
std::memcpy(ext.custom, move_data.external_device_data.data(), 5);
|
||||
}
|
||||
|
||||
static void fake_input_to_ext(u32 gem_num, gem_config::gem_controller& controller, CellGemExtPortData& ext)
|
||||
{
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (!pad->is_connected())
|
||||
{
|
||||
controller.ext_status = 0;
|
||||
controller.ext_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ps_move_data& move_data = pad->move_data;
|
||||
const auto& cfg = ::at32(g_cfg_gem_fake.players, gem_num);
|
||||
|
||||
move_data.external_device_id = ext_device_id(cfg->external_device);
|
||||
move_data.external_device_connected = move_data.external_device_id != 0;
|
||||
move_data.external_device_data = {};
|
||||
|
||||
controller.ext_status = move_data.external_device_connected ? CELL_GEM_EXT_CONNECTED : 0; // TODO: | CELL_GEM_EXT_EXT0 | CELL_GEM_EXT_EXT1
|
||||
controller.ext_id = move_data.external_device_connected ? move_data.external_device_id : 0;
|
||||
|
||||
if (!move_data.external_device_connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cfg->handle_input(pad, true, [&move_data, &ext](gem_btn btn, pad_button pad_btn, u16 value, bool pressed, bool& /*abort*/)
|
||||
{
|
||||
static std::set<pad_button> s_combos = {};
|
||||
input_to_ext<false, false>(move_data.external_device_id, ext, s_combos, btn, pad_btn, value, pressed);
|
||||
});
|
||||
|
||||
ext.status = controller.ext_status;
|
||||
std::memcpy(ext.custom, move_data.external_device_data.data(), 5);
|
||||
}
|
||||
|
||||
static void mouse_input_to_ext(u32 mouse_no, gem_config::gem_controller& controller, CellGemExtPortData& ext)
|
||||
{
|
||||
auto& handler = g_fxo->get<MouseHandlerBase>();
|
||||
|
||||
std::scoped_lock lock(handler.mutex);
|
||||
|
||||
// Make sure that the mouse handler is initialized
|
||||
handler.Init(std::min<u32>(g_fxo->get<gem_config>().attribute.max_connect, CELL_GEM_MAX_NUM));
|
||||
|
||||
if (mouse_no >= handler.GetMice().size())
|
||||
{
|
||||
controller.ext_status = 0;
|
||||
controller.ext_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const Mouse& mouse_data = ::at32(handler.GetMice(), mouse_no);
|
||||
const auto& cfg = ::at32(g_cfg_gem_mouse.players, mouse_no);
|
||||
|
||||
const u32 external_device_id = ext_device_id(cfg->external_device);
|
||||
const bool external_device_connected = external_device_id != 0;
|
||||
|
||||
controller.ext_status = external_device_connected ? CELL_GEM_EXT_CONNECTED : 0; // TODO: | CELL_GEM_EXT_EXT0 | CELL_GEM_EXT_EXT1
|
||||
controller.ext_id = external_device_connected ? external_device_id : 0;
|
||||
|
||||
if (!external_device_connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool combo_active = false;
|
||||
std::set<pad_button> combos;
|
||||
|
||||
// Check combo button first
|
||||
cfg->handle_input(mouse_data, [&combo_active](gem_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& abort)
|
||||
{
|
||||
if (pressed && btn == gem_btn::combo)
|
||||
{
|
||||
combo_active = true;
|
||||
abort = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Check combos
|
||||
if (combo_active)
|
||||
{
|
||||
cfg->handle_input(mouse_data, [external_device_id, &ext, &combos](gem_btn btn, pad_button pad_btn, u16 value, bool pressed, bool& /*abort*/)
|
||||
{
|
||||
input_to_ext<true, true>(external_device_id, ext, combos, btn, pad_btn, value, pressed);
|
||||
});
|
||||
}
|
||||
|
||||
// Check normal buttons
|
||||
cfg->handle_input(mouse_data, [external_device_id, &ext, &combos](gem_btn btn, pad_button pad_btn, u16 value, bool pressed, bool& /*abort*/)
|
||||
{
|
||||
input_to_ext<true, false>(external_device_id, ext, combos, btn, pad_btn, value, pressed);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Maps external Move controller data to DS3 input. (This can be input from any physical pad, not just the DS3)
|
||||
* Implementation detail: CellGemExtPortData's digital/analog fields map the same way as
|
||||
|
@ -1926,7 +2199,7 @@ static void ps_move_pos_to_gem_state(u32 gem_num, gem_config::gem_controller& co
|
|||
* \param ext External data to modify
|
||||
* \return true on success, false if controller is disconnected
|
||||
*/
|
||||
static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller, CellGemExtPortData& ext)
|
||||
static void get_external_device_input(u32 gem_num, gem_config::gem_controller& controller, CellGemExtPortData& ext)
|
||||
{
|
||||
ext = {};
|
||||
|
||||
|
@ -1935,53 +2208,6 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller
|
|||
return;
|
||||
}
|
||||
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
|
||||
const auto handler = pad::get_pad_thread();
|
||||
const auto& pad = ::at32(handler->GetPads(), pad_num(gem_num));
|
||||
|
||||
if (!pad->is_connected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& move_data = pad->move_data;
|
||||
|
||||
controller.ext_status = move_data.external_device_connected ? CELL_GEM_EXT_CONNECTED : 0; // TODO: | CELL_GEM_EXT_EXT0 | CELL_GEM_EXT_EXT1
|
||||
controller.ext_id = move_data.external_device_connected ? move_data.external_device_id : 0;
|
||||
|
||||
ext.status = controller.ext_status;
|
||||
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
{
|
||||
switch (stick.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: ext.analog_left_x = stick.m_value; break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: ext.analog_left_y = stick.m_value; break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: ext.analog_right_x = stick.m_value; break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: ext.analog_right_y = stick.m_value; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const Button& button : pad->m_buttons)
|
||||
{
|
||||
if (!button.m_pressed)
|
||||
continue;
|
||||
|
||||
switch (button.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_DIGITAL1: ext.digital1 |= button.m_outKeyCode; break;
|
||||
case CELL_PAD_BTN_OFFSET_DIGITAL2: ext.digital2 |= button.m_outKeyCode; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!move_data.external_device_connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// The sharpshooter only sets the custom bytes as follows:
|
||||
// custom[0] (0x01): Firing mode selector is in position 1.
|
||||
// custom[0] (0x02): Firing mode selector is in position 2.
|
||||
|
@ -1996,7 +2222,21 @@ static void ds3_input_to_ext(u32 gem_num, gem_config::gem_controller& controller
|
|||
// custom[3] (0x01): Left paddle
|
||||
// custom[3] (0x02): Right paddle
|
||||
|
||||
std::memcpy(ext.custom, move_data.external_device_data.data(), 5);
|
||||
switch (g_cfg.io.move)
|
||||
{
|
||||
case move_handler::real:
|
||||
real_input_to_ext(gem_num, controller, ext);
|
||||
break;
|
||||
case move_handler::fake:
|
||||
fake_input_to_ext(gem_num, controller, ext);
|
||||
break;
|
||||
case move_handler::mouse:
|
||||
case move_handler::raw_mouse:
|
||||
mouse_input_to_ext(gem_num, controller, ext);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2029,7 +2269,7 @@ static bool mouse_input_to_pad(u32 mouse_no, be_t<u16>& digital_buttons, be_t<u1
|
|||
}
|
||||
|
||||
const Mouse& mouse_data = ::at32(handler.GetMice(), mouse_no);
|
||||
auto& cfg = ::at32(g_cfg_gem_mouse.players, mouse_no);
|
||||
const auto& cfg = ::at32(g_cfg_gem_mouse.players, mouse_no);
|
||||
|
||||
bool combo_active = false;
|
||||
std::set<pad_button> combos;
|
||||
|
@ -2759,7 +2999,7 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
|
|||
|
||||
if (g_cfg.io.move != move_handler::null)
|
||||
{
|
||||
ds3_input_to_ext(gem_num, gem.controllers[gem_num], inertial_state->ext);
|
||||
get_external_device_input(gem_num, gem.controllers[gem_num], inertial_state->ext);
|
||||
|
||||
inertial_state->timestamp = (get_guest_system_time() - gem.start_timestamp_us);
|
||||
inertial_state->counter = gem.inertial_counter++;
|
||||
|
@ -2953,7 +3193,7 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
|
|||
|
||||
if (g_cfg.io.move != move_handler::null)
|
||||
{
|
||||
ds3_input_to_ext(gem_num, controller, gem_state->ext);
|
||||
get_external_device_input(gem_num, controller, gem_state->ext);
|
||||
|
||||
if (controller.enabled_tracking)
|
||||
{
|
||||
|
@ -3370,7 +3610,7 @@ error_code cellGemReadExternalPortDeviceInfo(u32 gem_num, vm::ptr<u32> ext_id, v
|
|||
{
|
||||
// Get external device status
|
||||
CellGemExtPortData ext_port_data{};
|
||||
ds3_input_to_ext(gem_num, controller, ext_port_data);
|
||||
get_external_device_input(gem_num, controller, ext_port_data);
|
||||
}
|
||||
|
||||
if (!(controller.ext_status & CELL_GEM_EXT_CONNECTED))
|
||||
|
|
|
@ -278,3 +278,37 @@ struct CellGemVideoConvertAttribute
|
|||
|
||||
ENABLE_BITWISE_SERIALIZATION;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
enum button_flags : u16
|
||||
{
|
||||
select = 0x01,
|
||||
start = 0x08,
|
||||
triangle = 0x10,
|
||||
circle = 0x20,
|
||||
cross = 0x40,
|
||||
square = 0x80,
|
||||
ps = 0x0001,
|
||||
move = 0x4008,
|
||||
t = 0x8010,
|
||||
ext_dev = 0x1000,
|
||||
|
||||
// Sharpshooter
|
||||
ss_firing_mode_1 = 0x01,
|
||||
ss_firing_mode_2 = 0x02,
|
||||
ss_firing_mode_3 = 0x04,
|
||||
ss_trigger = 0x40,
|
||||
ss_reload = 0x80,
|
||||
|
||||
// Racing Wheel
|
||||
rw_d_pad_up = 0x10,
|
||||
rw_d_pad_right = 0x20,
|
||||
rw_d_pad_down = 0x40,
|
||||
rw_d_pad_left = 0x80,
|
||||
rw_l1 = 0x04,
|
||||
rw_r1 = 0x08,
|
||||
rw_paddle_l = 0x01,
|
||||
rw_paddle_r = 0x02,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -464,7 +464,7 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
|
|||
case CELL_PAD_CTRL_DOWN: set_value(pad->m_press_down, value); break;
|
||||
case CELL_PAD_CTRL_RIGHT: set_value(pad->m_press_right, value); break;
|
||||
case CELL_PAD_CTRL_UP: set_value(pad->m_press_up, value); break;
|
||||
// These arent pressure btns
|
||||
// These aren't pressure btns
|
||||
case CELL_PAD_CTRL_R3:
|
||||
case CELL_PAD_CTRL_L3:
|
||||
case CELL_PAD_CTRL_START:
|
||||
|
|
83
rpcs3/Emu/Io/gem_config.cpp
Normal file
83
rpcs3/Emu/Io/gem_config.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "stdafx.h"
|
||||
#include "gem_config.h"
|
||||
|
||||
template <>
|
||||
void fmt_class_string<gem_ext_id>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](gem_ext_id value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case gem_ext_id::disconnected: return "Disconnected";
|
||||
case gem_ext_id::sharpshooter: return "Sharpshooter";
|
||||
case gem_ext_id::racing_wheel: return "Racing Wheel";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<gem_btn>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](gem_btn value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case gem_btn::start: return "Start";
|
||||
case gem_btn::select: return "Select";
|
||||
case gem_btn::triangle: return "Triangle";
|
||||
case gem_btn::circle: return "Circle";
|
||||
case gem_btn::cross: return "Cross";
|
||||
case gem_btn::square: return "Square";
|
||||
case gem_btn::move: return "Move";
|
||||
case gem_btn::t: return "T";
|
||||
case gem_btn::x_axis: return "X-Axis";
|
||||
case gem_btn::y_axis: return "Y-Axis";
|
||||
case gem_btn::combo: return "Combo";
|
||||
case gem_btn::combo_start: return "Combo Start";
|
||||
case gem_btn::combo_select: return "Combo Select";
|
||||
case gem_btn::combo_triangle: return "Combo Triangle";
|
||||
case gem_btn::combo_circle: return "Combo Circle";
|
||||
case gem_btn::combo_cross: return "Combo Cross";
|
||||
case gem_btn::combo_square: return "Combo Square";
|
||||
case gem_btn::combo_move: return "Combo Move";
|
||||
case gem_btn::combo_t: return "Combo T";
|
||||
case gem_btn::sharpshooter_firing_mode_1: return "Firing Mode 1";
|
||||
case gem_btn::sharpshooter_firing_mode_2: return "Firing Mode 2";
|
||||
case gem_btn::sharpshooter_firing_mode_3: return "Firing Mode 3";
|
||||
case gem_btn::sharpshooter_trigger: return "Trigger";
|
||||
case gem_btn::sharpshooter_reload: return "Reload";
|
||||
case gem_btn::racing_wheel_d_pad_up: return "Up";
|
||||
case gem_btn::racing_wheel_d_pad_right: return "Right";
|
||||
case gem_btn::racing_wheel_d_pad_down: return "Down";
|
||||
case gem_btn::racing_wheel_d_pad_left: return "Left";
|
||||
case gem_btn::racing_wheel_throttle: return "Throttle";
|
||||
case gem_btn::racing_wheel_l1: return "L1";
|
||||
case gem_btn::racing_wheel_r1: return "R1";
|
||||
case gem_btn::racing_wheel_l2: return "L2";
|
||||
case gem_btn::racing_wheel_r2: return "R2";
|
||||
case gem_btn::racing_wheel_paddle_l: return "Paddle L";
|
||||
case gem_btn::racing_wheel_paddle_r: return "Paddle R";
|
||||
case gem_btn::combo_sharpshooter_firing_mode_1: return "Combo Firing Mode 1";
|
||||
case gem_btn::combo_sharpshooter_firing_mode_2: return "Combo Firing Mode 2";
|
||||
case gem_btn::combo_sharpshooter_firing_mode_3: return "Combo Firing Mode 3";
|
||||
case gem_btn::combo_sharpshooter_trigger: return "Combo Trigger";
|
||||
case gem_btn::combo_sharpshooter_reload: return "Combo Reload";
|
||||
case gem_btn::combo_racing_wheel_d_pad_up: return "Combo Up";
|
||||
case gem_btn::combo_racing_wheel_d_pad_right: return "Combo Right";
|
||||
case gem_btn::combo_racing_wheel_d_pad_down: return "Combo Down";
|
||||
case gem_btn::combo_racing_wheel_d_pad_left: return "Combo Left";
|
||||
case gem_btn::combo_racing_wheel_throttle: return "Combo Throttle";
|
||||
case gem_btn::combo_racing_wheel_l1: return "Combo L1";
|
||||
case gem_btn::combo_racing_wheel_r1: return "Combo R1";
|
||||
case gem_btn::combo_racing_wheel_l2: return "Combo L2";
|
||||
case gem_btn::combo_racing_wheel_r2: return "Combo R2";
|
||||
case gem_btn::combo_racing_wheel_paddle_l: return "Combo Paddle L";
|
||||
case gem_btn::combo_racing_wheel_paddle_r: return "Combo Paddle R";
|
||||
case gem_btn::count: return "Count";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
#include "emulated_pad_config.h"
|
||||
|
||||
enum class gem_ext_id : u32
|
||||
{
|
||||
disconnected,
|
||||
sharpshooter,
|
||||
racing_wheel
|
||||
};
|
||||
|
||||
enum class gem_btn : u32
|
||||
{
|
||||
start,
|
||||
|
@ -17,7 +24,9 @@ enum class gem_btn : u32
|
|||
|
||||
combo_begin,
|
||||
combo = combo_begin,
|
||||
combo_start,
|
||||
|
||||
combo_buttons_begin,
|
||||
combo_start = combo_buttons_begin,
|
||||
combo_select,
|
||||
combo_triangle,
|
||||
combo_circle,
|
||||
|
@ -25,7 +34,52 @@ enum class gem_btn : u32
|
|||
combo_square,
|
||||
combo_move,
|
||||
combo_t,
|
||||
combo_end = combo_t,
|
||||
combo_buttons_end = combo_t,
|
||||
combo_end = combo_buttons_end,
|
||||
|
||||
sharpshooter_begin,
|
||||
sharpshooter_firing_mode_1 = sharpshooter_begin,
|
||||
sharpshooter_firing_mode_2,
|
||||
sharpshooter_firing_mode_3,
|
||||
sharpshooter_trigger,
|
||||
sharpshooter_reload,
|
||||
sharpshooter_end = sharpshooter_reload,
|
||||
|
||||
combo_sharpshooter_begin,
|
||||
combo_sharpshooter_firing_mode_1 = combo_sharpshooter_begin,
|
||||
combo_sharpshooter_firing_mode_2,
|
||||
combo_sharpshooter_firing_mode_3,
|
||||
combo_sharpshooter_trigger,
|
||||
combo_sharpshooter_reload,
|
||||
combo_sharpshooter_end = combo_sharpshooter_reload,
|
||||
|
||||
racing_wheel_begin,
|
||||
racing_wheel_d_pad_up = racing_wheel_begin,
|
||||
racing_wheel_d_pad_right,
|
||||
racing_wheel_d_pad_down,
|
||||
racing_wheel_d_pad_left,
|
||||
racing_wheel_throttle,
|
||||
racing_wheel_l1,
|
||||
racing_wheel_r1,
|
||||
racing_wheel_l2,
|
||||
racing_wheel_r2,
|
||||
racing_wheel_paddle_l,
|
||||
racing_wheel_paddle_r,
|
||||
racing_wheel_end = racing_wheel_paddle_r,
|
||||
|
||||
combo_racing_wheel_begin,
|
||||
combo_racing_wheel_d_pad_up = combo_racing_wheel_begin,
|
||||
combo_racing_wheel_d_pad_right,
|
||||
combo_racing_wheel_d_pad_down,
|
||||
combo_racing_wheel_d_pad_left,
|
||||
combo_racing_wheel_throttle,
|
||||
combo_racing_wheel_l1,
|
||||
combo_racing_wheel_r1,
|
||||
combo_racing_wheel_l2,
|
||||
combo_racing_wheel_r2,
|
||||
combo_racing_wheel_paddle_l,
|
||||
combo_racing_wheel_paddle_r,
|
||||
combo_racing_wheel_end = combo_racing_wheel_paddle_r,
|
||||
|
||||
count
|
||||
};
|
||||
|
@ -44,6 +98,26 @@ struct cfg_fake_gem final : public emulated_pad_config<gem_btn>
|
|||
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 };
|
||||
|
||||
cfg_pad_btn<gem_btn> sharpshooter_firing_mode_1{ this, "Sharpshooter Firing Mode 1", gem_btn::sharpshooter_firing_mode_1, pad_button::dpad_left };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_firing_mode_2{ this, "Sharpshooter Firing Mode 2", gem_btn::sharpshooter_firing_mode_2, pad_button::dpad_up };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_firing_mode_3{ this, "Sharpshooter Firing Mode 3", gem_btn::sharpshooter_firing_mode_3, pad_button::dpad_right };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_trigger{ this, "Sharpshooter Trigger", gem_btn::sharpshooter_trigger, pad_button::L1 };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_reload{ this, "Sharpshooter Reload", gem_btn::sharpshooter_reload, pad_button::L2 };
|
||||
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_up{ this, "Racing Wheel D-Pad Up", gem_btn::racing_wheel_d_pad_up, pad_button::dpad_up };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_right{ this, "Racing Wheel D-Pad Right", gem_btn::racing_wheel_d_pad_right, pad_button::dpad_right };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_down{ this, "Racing Wheel D-Pad Down", gem_btn::racing_wheel_d_pad_down, pad_button::dpad_down };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_left{ this, "Racing Wheel D-Pad Left", gem_btn::racing_wheel_d_pad_left, pad_button::dpad_left };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_throttle{ this, "Racing Wheel Throttle", gem_btn::racing_wheel_throttle, pad_button::rs_up };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_l1{ this, "Racing Wheel L1", gem_btn::racing_wheel_l1, pad_button::L1 };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_r1{ this, "Racing Wheel R1", gem_btn::racing_wheel_r1, pad_button::R1 };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_l2{ this, "Racing Wheel L2", gem_btn::racing_wheel_l2, pad_button::L2 };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_r2{ this, "Racing Wheel R2", gem_btn::racing_wheel_r2, pad_button::R2 };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_paddle_l{ this, "Racing Wheel Paddle L", gem_btn::racing_wheel_paddle_l, pad_button::L3 };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_paddle_r{ this, "Racing Wheel Paddle R", gem_btn::racing_wheel_paddle_r, pad_button::R3 };
|
||||
|
||||
cfg::_enum<gem_ext_id> external_device{ this, "External Device", gem_ext_id::disconnected };
|
||||
};
|
||||
|
||||
struct cfg_fake_gems final : public emulated_pads_config<cfg_fake_gem, 4>
|
||||
|
@ -72,6 +146,42 @@ struct cfg_mouse_gem final : public emulated_pad_config<gem_btn>
|
|||
cfg_pad_btn<gem_btn> combo_square{ this, "Combo Square", gem_btn::combo_square, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_move{ this, "Combo Move", gem_btn::combo_move, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_t{ this, "Combo T", gem_btn::combo_t, pad_button::pad_button_max_enum };
|
||||
|
||||
cfg_pad_btn<gem_btn> sharpshooter_firing_mode_1{ this, "Sharpshooter Firing Mode 1", gem_btn::sharpshooter_firing_mode_1, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_firing_mode_2{ this, "Sharpshooter Firing Mode 2", gem_btn::sharpshooter_firing_mode_2, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_firing_mode_3{ this, "Sharpshooter Firing Mode 3", gem_btn::sharpshooter_firing_mode_3, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_trigger{ this, "Sharpshooter Trigger", gem_btn::sharpshooter_trigger, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> sharpshooter_reload{ this, "Sharpshooter Reload", gem_btn::sharpshooter_reload, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_sharpshooter_firing_mode_1{ this, "Combo Sharpshooter Firing Mode 1", gem_btn::combo_sharpshooter_firing_mode_1, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_sharpshooter_firing_mode_2{ this, "Combo Sharpshooter Firing Mode 2", gem_btn::combo_sharpshooter_firing_mode_2, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_sharpshooter_firing_mode_3{ this, "Combo Sharpshooter Firing Mode 3", gem_btn::combo_sharpshooter_firing_mode_3, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_sharpshooter_trigger{ this, "Combo Sharpshooter Trigger", gem_btn::combo_sharpshooter_trigger, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_sharpshooter_reload{ this, "Combo Sharpshooter Reload", gem_btn::combo_sharpshooter_reload, pad_button::pad_button_max_enum };
|
||||
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_up{ this, "Racing Wheel D-Pad Up", gem_btn::racing_wheel_d_pad_up, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_right{ this, "Racing Wheel D-Pad Right", gem_btn::racing_wheel_d_pad_right, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_down{ this, "Racing Wheel D-Pad Down", gem_btn::racing_wheel_d_pad_down, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_d_pad_left{ this, "Racing Wheel D-Pad Left", gem_btn::racing_wheel_d_pad_left, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_throttle{ this, "Racing Wheel Throttle", gem_btn::racing_wheel_throttle, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_l1{ this, "Racing Wheel L1", gem_btn::racing_wheel_l1, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_r1{ this, "Racing Wheel R1", gem_btn::racing_wheel_r1, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_l2{ this, "Racing Wheel L2", gem_btn::racing_wheel_l2, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_r2{ this, "Racing Wheel R2", gem_btn::racing_wheel_r2, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_paddle_l{ this, "Racing Wheel Paddle L", gem_btn::racing_wheel_paddle_l, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> racing_wheel_paddle_r{ this, "Racing Wheel Paddle R", gem_btn::racing_wheel_paddle_r, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_d_pad_up{ this, "Combo Racing Wheel D-Pad Up", gem_btn::combo_racing_wheel_d_pad_up, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_d_pad_right{ this, "Combo Racing Wheel D-Pad Right", gem_btn::combo_racing_wheel_d_pad_right, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_d_pad_down{ this, "Combo Racing Wheel D-Pad Down", gem_btn::combo_racing_wheel_d_pad_down, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_d_pad_left{ this, "Combo Racing Wheel D-Pad Left", gem_btn::combo_racing_wheel_d_pad_left, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_throttle{ this, "Combo Racing Wheel Throttle", gem_btn::combo_racing_wheel_throttle, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_l1{ this, "Combo Racing Wheel L1", gem_btn::combo_racing_wheel_l1, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_r1{ this, "Combo Racing Wheel R1", gem_btn::combo_racing_wheel_r1, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_l2{ this, "Combo Racing Wheel L2", gem_btn::combo_racing_wheel_l2, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_r2{ this, "Combo Racing Wheel R2", gem_btn::combo_racing_wheel_r2, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_paddle_l{ this, "Combo Racing Wheel Paddle L", gem_btn::combo_racing_wheel_paddle_l, pad_button::pad_button_max_enum };
|
||||
cfg_pad_btn<gem_btn> combo_racing_wheel_paddle_r{ this, "Combo Racing Wheel Paddle R", gem_btn::combo_racing_wheel_paddle_r, pad_button::pad_button_max_enum };
|
||||
|
||||
cfg::_enum<gem_ext_id> external_device{ this, "External Device", gem_ext_id::disconnected };
|
||||
};
|
||||
|
||||
struct cfg_mouse_gems final : public emulated_pads_config<cfg_mouse_gem, 4>
|
||||
|
|
|
@ -13,37 +13,6 @@ namespace
|
|||
constexpr id_pair MOVE_ID_ZCM1 = {0x054C, 0x03D5};
|
||||
constexpr id_pair MOVE_ID_ZCM2 = {0x054C, 0x0c5e};
|
||||
|
||||
enum button_flags : u16
|
||||
{
|
||||
select = 0x01,
|
||||
start = 0x08,
|
||||
triangle = 0x10,
|
||||
circle = 0x20,
|
||||
cross = 0x40,
|
||||
square = 0x80,
|
||||
ps = 0x0001,
|
||||
move = 0x4008,
|
||||
t = 0x8010,
|
||||
ext_dev = 0x1000,
|
||||
|
||||
// Sharpshooter
|
||||
ss_firing_mode_1 = 0x01,
|
||||
ss_firing_mode_2 = 0x02,
|
||||
ss_firing_mode_3 = 0x04,
|
||||
ss_trigger = 0x40,
|
||||
ss_reload = 0x80,
|
||||
|
||||
// Racing Wheel
|
||||
rw_d_pad_up = 0x10,
|
||||
rw_d_pad_right = 0x20,
|
||||
rw_d_pad_down = 0x40,
|
||||
rw_d_pad_left = 0x80,
|
||||
rw_l1 = 0x04,
|
||||
rw_r1 = 0x08,
|
||||
rw_paddle_l = 0x01,
|
||||
rw_paddle_r = 0x02,
|
||||
};
|
||||
|
||||
enum battery_status : u8
|
||||
{
|
||||
charge_empty = 0x00,
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Io\GameTablet.cpp" />
|
||||
<ClCompile Include="Emu\Io\gem_config.cpp" />
|
||||
<ClCompile Include="Emu\Io\GHLtar.cpp" />
|
||||
<ClCompile Include="Emu\Io\GunCon3.cpp" />
|
||||
<ClCompile Include="Emu\Io\midi_config_types.cpp" />
|
||||
|
|
|
@ -1369,6 +1369,9 @@
|
|||
<ClCompile Include="Emu\Io\evdev_gun_handler.cpp">
|
||||
<Filter>Emu\Io</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Io\gem_config.cpp">
|
||||
<Filter>Emu\Io</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Crypto\aes.h">
|
||||
|
@ -2881,4 +2884,4 @@
|
|||
<Filter>Emu\GPU\RSX\Program\MSAA</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -13,11 +13,13 @@
|
|||
#include "Emu/Io/usio_config.h"
|
||||
#include "util/asm.hpp"
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
enum button_role
|
||||
|
@ -123,12 +125,35 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
|
|||
{
|
||||
ensure(!!tabs);
|
||||
|
||||
const bool show_mouse_legend = m_type == pad_type::mousegem;
|
||||
const bool show_external_device_selection = m_type == pad_type::mousegem || m_type == pad_type::ds3gem;
|
||||
|
||||
if (show_mouse_legend)
|
||||
{
|
||||
if (!g_cfg_mouse.load())
|
||||
{
|
||||
cfg_log.notice("Could not restore mouse config. Using defaults.");
|
||||
}
|
||||
|
||||
if (!g_cfg_raw_mouse.load())
|
||||
{
|
||||
cfg_log.notice("Could not restore raw mouse config. Using defaults.");
|
||||
}
|
||||
}
|
||||
|
||||
std::set<int> ignored_values;
|
||||
|
||||
const auto remove_value = [&ignored_values](int value)
|
||||
{
|
||||
ignored_values.insert(static_cast<int>(value));
|
||||
};
|
||||
const auto remove_values = [remove_value](int begin, int end)
|
||||
{
|
||||
for (int i = begin; i <= end; i++)
|
||||
{
|
||||
remove_value(i);
|
||||
}
|
||||
};
|
||||
|
||||
usz players = 0;
|
||||
switch (m_type)
|
||||
|
@ -148,22 +173,22 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
|
|||
case pad_type::gem:
|
||||
players = g_cfg_gem_real.players.size();
|
||||
|
||||
// Ignore combo, x and y axis
|
||||
// Ignore combo, sharpshooter, wheel, x and y axis
|
||||
remove_value(static_cast<int>(gem_btn::x_axis));
|
||||
remove_value(static_cast<int>(gem_btn::y_axis));
|
||||
for (int i = static_cast<int>(gem_btn::combo_begin); i <= static_cast<int>(gem_btn::combo_end); i++)
|
||||
{
|
||||
remove_value(i);
|
||||
}
|
||||
remove_values(static_cast<int>(gem_btn::sharpshooter_begin), static_cast<int>(gem_btn::sharpshooter_end));
|
||||
remove_values(static_cast<int>(gem_btn::racing_wheel_begin), static_cast<int>(gem_btn::racing_wheel_end));
|
||||
remove_values(static_cast<int>(gem_btn::combo_begin), static_cast<int>(gem_btn::combo_end));
|
||||
remove_values(static_cast<int>(gem_btn::combo_sharpshooter_begin), static_cast<int>(gem_btn::combo_sharpshooter_end));
|
||||
remove_values(static_cast<int>(gem_btn::combo_racing_wheel_begin), static_cast<int>(gem_btn::combo_racing_wheel_end));
|
||||
break;
|
||||
case pad_type::ds3gem:
|
||||
players = g_cfg_gem_fake.players.size();
|
||||
|
||||
// Ignore combo
|
||||
for (int i = static_cast<int>(gem_btn::combo_begin); i <= static_cast<int>(gem_btn::combo_end); i++)
|
||||
{
|
||||
remove_value(i);
|
||||
}
|
||||
remove_values(static_cast<int>(gem_btn::combo_begin), static_cast<int>(gem_btn::combo_end));
|
||||
remove_values(static_cast<int>(gem_btn::combo_sharpshooter_begin), static_cast<int>(gem_btn::combo_sharpshooter_end));
|
||||
remove_values(static_cast<int>(gem_btn::combo_racing_wheel_begin), static_cast<int>(gem_btn::combo_racing_wheel_end));
|
||||
break;
|
||||
case pad_type::mousegem:
|
||||
players = g_cfg_gem_mouse.players.size();
|
||||
|
@ -185,30 +210,18 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
|
|||
|
||||
constexpr u32 max_items_per_column = 6;
|
||||
const int count = static_cast<int>(T::count) - static_cast<int>(ignored_values.size());
|
||||
int rows = count;
|
||||
int rows = show_external_device_selection ? max_items_per_column : count;
|
||||
|
||||
for (u32 cols = 1; utils::aligned_div(static_cast<u32>(count), cols) > max_items_per_column;)
|
||||
if (!show_external_device_selection)
|
||||
{
|
||||
rows = utils::aligned_div(static_cast<u32>(count), ++cols);
|
||||
for (u32 cols = 1; utils::aligned_div(static_cast<u32>(count), cols) > max_items_per_column;)
|
||||
{
|
||||
rows = utils::aligned_div(static_cast<u32>(count), ++cols);
|
||||
}
|
||||
}
|
||||
|
||||
m_combos.resize(players);
|
||||
|
||||
const bool show_mouse_legend = m_type == pad_type::mousegem;
|
||||
|
||||
if (show_mouse_legend)
|
||||
{
|
||||
if (!g_cfg_mouse.load())
|
||||
{
|
||||
cfg_log.notice("Could not restore mouse config. Using defaults.");
|
||||
}
|
||||
|
||||
if (!g_cfg_raw_mouse.load())
|
||||
{
|
||||
cfg_log.notice("Could not restore raw mouse config. Using defaults.");
|
||||
}
|
||||
}
|
||||
|
||||
for (usz player = 0; player < players; player++)
|
||||
{
|
||||
// Create grid with all buttons
|
||||
|
@ -228,7 +241,9 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
|
|||
if constexpr (std::is_same_v<T, gem_btn>)
|
||||
{
|
||||
const gem_btn btn = static_cast<gem_btn>(i);
|
||||
if (btn >= gem_btn::combo_begin && btn <= gem_btn::combo_end)
|
||||
if ((btn >= gem_btn::combo_begin && btn <= gem_btn::combo_end) ||
|
||||
(btn >= gem_btn::combo_sharpshooter_begin && btn <= gem_btn::combo_sharpshooter_end) ||
|
||||
(btn >= gem_btn::combo_racing_wheel_begin && btn <= gem_btn::combo_racing_wheel_end))
|
||||
{
|
||||
gb->setToolTip(tr("Press the \"Combo\" button in combination with any of the other combo buttons to trigger their related PS Move button.\n"
|
||||
"This can be useful if your device does not have enough regular buttons."));
|
||||
|
@ -348,13 +363,19 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
|
|||
}
|
||||
});
|
||||
|
||||
if (row >= rows)
|
||||
if (row >= rows ||
|
||||
(show_external_device_selection &&
|
||||
(i == static_cast<int>(gem_btn::combo_buttons_begin) ||
|
||||
i == static_cast<int>(gem_btn::sharpshooter_begin) ||
|
||||
i == static_cast<int>(gem_btn::racing_wheel_begin) ||
|
||||
i == static_cast<int>(gem_btn::combo_sharpshooter_begin) ||
|
||||
i == static_cast<int>(gem_btn::combo_racing_wheel_begin))))
|
||||
{
|
||||
row = 0;
|
||||
col++;
|
||||
}
|
||||
|
||||
::at32(m_combos, player).push_back(combo);
|
||||
::at32(m_combos, player).push_back(std::make_pair(combo, gb));
|
||||
h_layout->addWidget(combo);
|
||||
gb->setLayout(h_layout);
|
||||
grid_layout->addWidget(gb, row, col);
|
||||
|
@ -364,6 +385,100 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
|
|||
|
||||
QVBoxLayout* v_layout = new QVBoxLayout(this);
|
||||
|
||||
// Allow to select external devices
|
||||
if (show_external_device_selection)
|
||||
{
|
||||
QRadioButton* rb_disconnected = new QRadioButton(tr("Disconnected"), this);
|
||||
QRadioButton* rb_sharpshooter = new QRadioButton(tr("Sharpshooter"), this);
|
||||
QRadioButton* rb_racing_wheel = new QRadioButton(tr("Racing Wheel"), this);
|
||||
QButtonGroup* bg = new QButtonGroup(this);
|
||||
bg->addButton(rb_disconnected, static_cast<int>(gem_ext_id::disconnected));
|
||||
bg->addButton(rb_sharpshooter, static_cast<int>(gem_ext_id::sharpshooter));
|
||||
bg->addButton(rb_racing_wheel, static_cast<int>(gem_ext_id::racing_wheel));
|
||||
QHBoxLayout* h_layout = new QHBoxLayout(this);
|
||||
h_layout->addWidget(rb_disconnected);
|
||||
h_layout->addWidget(rb_sharpshooter);
|
||||
h_layout->addWidget(rb_racing_wheel);
|
||||
QGroupBox* gb = new QGroupBox(tr("External Device"), this);
|
||||
gb->setToolTip(tr("Select an external device to emulate."));
|
||||
gb->setLayout(h_layout);
|
||||
v_layout->addWidget(gb);
|
||||
|
||||
const auto enable_buttons = [this, player](gem_ext_id id)
|
||||
{
|
||||
for (auto& [combo, gb] : m_combos.at(player))
|
||||
{
|
||||
if (!combo || !gb)
|
||||
continue;
|
||||
|
||||
const QVariant data = combo->itemData(0, button_role::emulated_button);
|
||||
if (!data.isValid() || !data.canConvert<int>())
|
||||
continue;
|
||||
|
||||
const int button = data.value<int>();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case gem_ext_id::disconnected:
|
||||
gb->setEnabled(!(
|
||||
(button >= static_cast<int>(gem_btn::sharpshooter_begin) && button <= static_cast<int>(gem_btn::sharpshooter_end)) ||
|
||||
(button >= static_cast<int>(gem_btn::racing_wheel_begin) && button <= static_cast<int>(gem_btn::racing_wheel_end)) ||
|
||||
(button >= static_cast<int>(gem_btn::combo_sharpshooter_begin) && button <= static_cast<int>(gem_btn::combo_sharpshooter_end)) ||
|
||||
(button >= static_cast<int>(gem_btn::combo_racing_wheel_begin) && button <= static_cast<int>(gem_btn::combo_racing_wheel_end))));
|
||||
break;
|
||||
case gem_ext_id::sharpshooter:
|
||||
gb->setEnabled(!(
|
||||
(button >= static_cast<int>(gem_btn::racing_wheel_begin) && button <= static_cast<int>(gem_btn::racing_wheel_end)) ||
|
||||
(button >= static_cast<int>(gem_btn::combo_racing_wheel_begin) && button <= static_cast<int>(gem_btn::combo_racing_wheel_end))));
|
||||
break;
|
||||
case gem_ext_id::racing_wheel:
|
||||
gb->setEnabled(!(
|
||||
(button >= static_cast<int>(gem_btn::sharpshooter_begin) && button <= static_cast<int>(gem_btn::sharpshooter_end)) ||
|
||||
(button >= static_cast<int>(gem_btn::combo_sharpshooter_begin) && button <= static_cast<int>(gem_btn::combo_sharpshooter_end))));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gem_ext_id ext_id = gem_ext_id::disconnected;
|
||||
switch (m_type)
|
||||
{
|
||||
case pad_type::ds3gem:
|
||||
ext_id = ::at32(g_cfg_gem_fake.players, player)->external_device.get();
|
||||
break;
|
||||
case pad_type::mousegem:
|
||||
ext_id = ::at32(g_cfg_gem_mouse.players, player)->external_device.get();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bg->button(static_cast<int>(ext_id))->setChecked(true);
|
||||
enable_buttons(ext_id);
|
||||
|
||||
connect(bg, &QButtonGroup::idToggled, [this, player, enable_buttons](int id, bool checked)
|
||||
{
|
||||
if (!checked) return;
|
||||
|
||||
const gem_ext_id ext_id = static_cast<gem_ext_id>(id);
|
||||
enable_buttons(ext_id);
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case pad_type::ds3gem:
|
||||
::at32(g_cfg_gem_fake.players, player)->external_device.set(ext_id);
|
||||
break;
|
||||
case pad_type::mousegem:
|
||||
::at32(g_cfg_gem_mouse.players, player)->external_device.set(ext_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Create a legend of the current mouse settings
|
||||
if (show_mouse_legend)
|
||||
{
|
||||
|
@ -558,7 +673,7 @@ void emulated_pad_settings_dialog::reset_config()
|
|||
|
||||
for (usz player = 0; player < m_combos.size(); player++)
|
||||
{
|
||||
for (QComboBox* combo : m_combos.at(player))
|
||||
for (auto& [combo, gb] : m_combos.at(player))
|
||||
{
|
||||
if (!combo)
|
||||
continue;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QTabWidget>
|
||||
|
||||
#include <vector>
|
||||
|
@ -37,5 +38,5 @@ private:
|
|||
|
||||
pad_type m_type;
|
||||
|
||||
std::vector<std::vector<QComboBox*>> m_combos;
|
||||
std::vector<std::vector<std::pair<QComboBox*, QGroupBox*>>> m_combos;
|
||||
};
|
||||
|
|
|
@ -359,7 +359,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
|||
SubscribeTooltip(ui->ppu__static, tooltips.settings.ppu__static);
|
||||
SubscribeTooltip(ui->ppu_llvm, tooltips.settings.ppu_llvm);
|
||||
|
||||
QButtonGroup *ppu_bg = new QButtonGroup(this);
|
||||
QButtonGroup* ppu_bg = new QButtonGroup(this);
|
||||
ppu_bg->addButton(ui->ppu__static, static_cast<int>(ppu_decoder_type::_static));
|
||||
ppu_bg->addButton(ui->ppu_llvm, static_cast<int>(ppu_decoder_type::llvm));
|
||||
|
||||
|
@ -695,7 +695,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
|||
SubscribeTooltip(ui->rb_async_with_shader_interpreter, tooltips.settings.async_with_shader_interpreter);
|
||||
SubscribeTooltip(ui->rb_shader_interpreter_only, tooltips.settings.shader_interpreter_only);
|
||||
|
||||
QButtonGroup *shader_mode_bg = new QButtonGroup(this);
|
||||
QButtonGroup* shader_mode_bg = new QButtonGroup(this);
|
||||
shader_mode_bg->addButton(ui->rb_legacy_recompiler, static_cast<int>(shader_mode::recompiler));
|
||||
shader_mode_bg->addButton(ui->rb_async_recompiler, static_cast<int>(shader_mode::async_recompiler));
|
||||
shader_mode_bg->addButton(ui->rb_async_with_shader_interpreter, static_cast<int>(shader_mode::async_with_interpreter));
|
||||
|
@ -1447,7 +1447,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
|||
// Radio Buttons
|
||||
|
||||
// creating this in ui file keeps scrambling the order...
|
||||
QButtonGroup *enter_button_assignment_bg = new QButtonGroup(this);
|
||||
QButtonGroup* enter_button_assignment_bg = new QButtonGroup(this);
|
||||
enter_button_assignment_bg->addButton(ui->enterButtonAssignCircle, 0);
|
||||
enter_button_assignment_bg->addButton(ui->enterButtonAssignCross, 1);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue