From 7154f501a2702b23f200607d07e427714a7551d6 Mon Sep 17 00:00:00 2001 From: jackun Date: Sun, 3 Jan 2021 16:04:28 +0200 Subject: [PATCH] USB: Add evdev support for keyboardmania --- pcsx2/USB/usb-pad/dx/dinput-config.cpp | 6 +- pcsx2/USB/usb-pad/evdev/evdev-gtk.cpp | 12 +- pcsx2/USB/usb-pad/evdev/evdev.cpp | 48 +- pcsx2/USB/usb-pad/evdev/shared-gtk.cpp | 556 +++++++++++++++++------- pcsx2/USB/usb-pad/evdev/shared.h | 51 ++- pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp | 4 +- pcsx2/USB/usb-pad/joydev/joydev.cpp | 18 +- pcsx2/USB/usb-pad/usb-pad.cpp | 14 +- pcsx2/USB/usb-pad/usb-pad.h | 21 +- 9 files changed, 484 insertions(+), 246 deletions(-) diff --git a/pcsx2/USB/usb-pad/dx/dinput-config.cpp b/pcsx2/USB/usb-pad/dx/dinput-config.cpp index 286729fb0e9c6..93b5f40b3c7d7 100644 --- a/pcsx2/USB/usb-pad/dx/dinput-config.cpp +++ b/pcsx2/USB/usb-pad/dx/dinput-config.cpp @@ -1280,7 +1280,7 @@ namespace usb_pad INVERTFORCES[port] = SendDlgItemMessage(hWnd, IDC_CHECK1, BM_GETCHECK, 0, 0); useRamp = !!SendDlgItemMessage(hWnd, IDC_CHECK3, BM_GETCHECK, 0, 0); GAINZ[port][0] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER4), TBM_GETPOS, 0, 0); - FFMULTI[port][0] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER5), TBM_GETPOS, 0, 0); + FFMULTI[port][0] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER5), TBM_GETPOS, 0, 0); } void SaveDInputConfig(int port, const char* dev_type) @@ -1424,11 +1424,11 @@ namespace usb_pad struct DXDlgSettings s; s.port = port; s.dev_type = dev_type; - if (strcmp(dev_type, "buzz_device") == 0) + if (strcmp(dev_type, BuzzDevice::TypeName()) == 0) { return DialogBoxParam(h.hInst, MAKEINTRESOURCE(IDD_DLG_BUZZ), h.hWnd, DxDialogProc, (LPARAM)&s); } - if (strcmp(dev_type, "keyboardmania") == 0) + if (strcmp(dev_type, KeyboardmaniaDevice::TypeName()) == 0) { return DialogBoxParam(h.hInst, MAKEINTRESOURCE(IDD_DLG_KEYBOARDMANIA), h.hWnd, DxDialogProc, (LPARAM)&s); } diff --git a/pcsx2/USB/usb-pad/evdev/evdev-gtk.cpp b/pcsx2/USB/usb-pad/evdev/evdev-gtk.cpp index 548f4aaae1239..d4770dfac99fb 100644 --- a/pcsx2/USB/usb-pad/evdev/evdev-gtk.cpp +++ b/pcsx2/USB/usb-pad/evdev/evdev-gtk.cpp @@ -559,12 +559,12 @@ namespace usb_pad "RFKILL", /* linux:524 (KEY_RFKILL) */ }; - static bool GetEventName(const char* dev_type, int map, int event, const char** name) + static bool GetEventName(const char* dev_type, int map, int event, bool is_button, const char** name) { if (!name) return false; - if (map < JOY_STEERING || !strcmp(dev_type, BuzzDevice::TypeName())) + if (is_button) { if (event < (int)key_to_str.size()) { @@ -593,7 +593,7 @@ namespace usb_pad }; AxisValue axisVal[ABS_MAX + 1]{}; unsigned long absbit[NBITS(ABS_MAX)]{}; - struct axis_correct abs_correct[ABS_MAX]{}; + axis_correct abs_correct[ABS_MAX]{}; inverted = false; @@ -616,9 +616,7 @@ namespace usb_pad while ((len = read(js.second.fd, &event, sizeof(event))) > 0) ; - struct timeval timeout - { - }; + timeval timeout{}; timeout.tv_sec = 5; int result = select(maxfd + 1, &fdset, NULL, NULL, &timeout); @@ -744,6 +742,8 @@ namespace usb_pad int ret = 0; if (!strcmp(dev_type, BuzzDevice::TypeName())) ret = GtkBuzzConfigure(port, dev_type, "Evdev Settings", evdev::APINAME, GTK_WINDOW(data), apicbs); + else if (!strcmp(dev_type, KeyboardmaniaDevice::TypeName())) + ret = GtkKeyboardmaniaConfigure(port, dev_type, "Evdev Settings", evdev::APINAME, GTK_WINDOW(data), apicbs); else ret = GtkPadConfigure(port, dev_type, "Evdev Settings", evdev::APINAME, GTK_WINDOW(data), apicbs); return ret; diff --git a/pcsx2/USB/usb-pad/evdev/evdev.cpp b/pcsx2/USB/usb-pad/evdev/evdev.cpp index 2b46f7b5ee8c4..8e455a71da466 100644 --- a/pcsx2/USB/usb-pad/evdev/evdev.cpp +++ b/pcsx2/USB/usb-pad/evdev/evdev.cpp @@ -108,7 +108,6 @@ namespace usb_pad } } } - //quit: closedir(dirp); return false; } @@ -183,7 +182,6 @@ namespace usb_pad } list.assign(list_cache.begin(), list_cache.end()); - //quit: closedir(dirp); } @@ -220,7 +218,7 @@ namespace usb_pad //case ABS_Y: mWheelData.clutch = NORM(value, 0xFF); break; //no wheel on PS2 has one, afaik //case ABS_RX: mWheelData.axis_rx = NORM(event.value, 0xFF); break; case ABS_RY: - //treat_me_like_ABS_RY: + //treat_me_like_ABS_RY: mWheelData.throttle = 0xFF; mWheelData.brake = 0xFF; if (value < 0) @@ -230,18 +228,10 @@ namespace usb_pad break; case 0x80 | JOY_THROTTLE: case ABS_Z: - /*if (mIsGamepad) - mWheelData.brake = 0xFF - NORM(value, 0xFF); - else*/ mWheelData.throttle = device.cfg.inverted[1] ? NORM(value, 0xFF) : 0xFF - NORM(value, 0xFF); break; case 0x80 | JOY_BRAKE: case ABS_RZ: - /*if (mIsGamepad) - mWheelData.throttle = 0xFF - NORM(value, 0xFF); - else if (mIsDualAnalog) - goto treat_me_like_ABS_RY; - else*/ mWheelData.brake = device.cfg.inverted[2] ? NORM(value, 0xFF) : 0xFF - NORM(value, 0xFF); break; @@ -323,9 +313,8 @@ namespace usb_pad break; value = AxisCorrect(device.abs_correct[event.code], event.value); - /*if (event.code == 0) - event.code, device.axis_map[event.code] & ~0x80, event.value, value); - */ + //if (event.code == 0) + // event.code, device.axis_map[event.code] & ~0x80, event.value, value); SetAxis(device, event.code, value); } break; @@ -333,7 +322,7 @@ namespace usb_pad { code = device.btn_map[event.code] != (uint16_t)-1 ? device.btn_map[event.code] : event.code; - if (mType == WT_BUZZ_CONTROLLER) + if (mType == WT_BUZZ_CONTROLLER || mType == WT_KEYBOARDMANIA_CONTROLLER) { if (device.btn_map[event.code] != (uint16_t)-1) { @@ -637,13 +626,6 @@ namespace usb_pad continue; } - /*unsigned int version; - if (ioctl(mHandle, EVIOCGVERSION, &version) < 0) - { - SysMessage("%s: Get version failed: %s\n", APINAME, strerror(errno)); - return false; - }*/ - int max_buttons = JOY_STEERING; switch (mType) { @@ -651,8 +633,13 @@ namespace usb_pad LoadBuzzMappings(mDevType, mPort, it.id, device.cfg); max_buttons = 20; break; + case WT_KEYBOARDMANIA_CONTROLLER: + max_buttons = 31; + LoadMappings(mDevType, mPort, it.id, max_buttons, 0, device.cfg); + break; default: - LoadMappings(mDevType, mPort, it.id, device.cfg); + max_buttons = JOY_STEERING; + LoadMappings(mDevType, mPort, it.id, max_buttons, 3, device.cfg); if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN_ENABLED, b_gain)) b_gain = 1; if (!LoadSetting(mDevType, mPort, APINAME, N_GAIN, gain)) @@ -715,12 +702,6 @@ namespace usb_pad } } -#ifndef NDEBUG - for (int i = 0; i < ABS_MAX; ++i) - { - } -#endif - for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) { if (test_bit(i, keybit)) @@ -776,9 +757,12 @@ namespace usb_pad if (mHidHandle != -1) { - uint8_t reset[7] = {0}; - reset[0] = 0xF3; //stop forces - write(mHidHandle, reset, sizeof(reset)); + if (mType <= WT_GT_FORCE) + { + uint8_t reset[7] = {0}; + reset[0] = 0xF3; //stop forces + write(mHidHandle, reset, sizeof(reset)); + } close(mHidHandle); } diff --git a/pcsx2/USB/usb-pad/evdev/shared-gtk.cpp b/pcsx2/USB/usb-pad/evdev/shared-gtk.cpp index 45c22349a2a53..2c53ccb3c4700 100644 --- a/pcsx2/USB/usb-pad/evdev/shared-gtk.cpp +++ b/pcsx2/USB/usb-pad/evdev/shared-gtk.cpp @@ -32,34 +32,37 @@ namespace usb_pad #define JOYTYPE "joytype" #define CFG "cfg" - bool LoadMappings(const char* dev_type, int port, const std::string& joyname, ConfigMapping& cfg) + // Buttons from 0, axes after buttons + bool LoadMappings(const char* dev_type, int port, const std::string& joyname, u32 max_buttons, u32 max_axes, ConfigMapping& cfg) { - assert(JOY_MAPS_COUNT == countof(JoystickMapNames)); std::stringstream str; if (joyname.empty()) return false; - int j = 0; - cfg.controls.resize(JOY_MAPS_COUNT); - for (auto& i : cfg.controls) + cfg.controls.resize(max_buttons + max_axes); + for (u32 i = 0; i < max_buttons + max_axes; i++) { str.clear(); str.str(""); - str << "map_" << JoystickMapNames[j++]; + if (i < max_buttons) + str << "button_" << i; + else + str << "axis_" << (i - max_buttons); + const std::string& name = str.str(); int32_t var; if (LoadSetting(dev_type, port, joyname, name.c_str(), var)) - i = var; + cfg.controls[i] = var; else - i = -1; + cfg.controls[i] = -1; } for (int i = 0; i < 3; i++) { str.clear(); str.str(""); - str << "inverted_" << JoystickMapNames[JOY_STEERING + i]; + str << "inverted_" << i; { const std::string& name = str.str(); if (!LoadSetting(dev_type, port, joyname, name.c_str(), cfg.inverted[i])) @@ -68,7 +71,7 @@ namespace usb_pad str.clear(); str.str(""); - str << "initial_" << JoystickMapNames[JOY_STEERING + i]; + str << "initial_" << i; { const std::string& name = str.str(); if (!LoadSetting(dev_type, port, joyname, name.c_str(), cfg.initial[i])) @@ -78,29 +81,31 @@ namespace usb_pad return true; } - bool SaveMappings(const char* dev_type, int port, const std::string& joyname, const ConfigMapping& cfg) + bool SaveMappings(const char* dev_type, int port, const std::string& joyname, u32 max_buttons, u32 max_axes, const ConfigMapping& cfg) { - assert(JOY_MAPS_COUNT == countof(JoystickMapNames)); - if (joyname.empty() || cfg.controls.size() != JOY_MAPS_COUNT) + if (joyname.empty() || cfg.controls.size() != max_buttons + max_axes) return false; RemoveSection(dev_type, port, joyname); std::stringstream str; - for (int i = 0; i < JOY_MAPS_COUNT; i++) + for (u32 i = 0; i < max_buttons + max_axes; i++) { str.clear(); str.str(""); - str << "map_" << JoystickMapNames[i]; + if (i < max_buttons) + str << "button_" << i; + else + str << "axis_" << (i - max_buttons); const std::string& name = str.str(); if (cfg.controls[i] >= 0 && !SaveSetting(dev_type, port, joyname, name.c_str(), static_cast(cfg.controls[i]))) return false; } - for (int i = 0; i < 3; i++) + for (u32 i = 0; i < 3; i++) { str.clear(); str.str(""); - str << "inverted_" << JoystickMapNames[JOY_STEERING + i]; + str << "inverted_" << i; { const std::string& name = str.str(); if (!SaveSetting(dev_type, port, joyname, name.c_str(), cfg.inverted[i])) @@ -109,7 +114,7 @@ namespace usb_pad str.clear(); str.str(""); - str << "initial_" << JoystickMapNames[JOY_STEERING + i]; + str << "initial_" << i; { const std::string& name = str.str(); if (!SaveSetting(dev_type, port, joyname, name.c_str(), cfg.initial[i])) @@ -169,48 +174,50 @@ namespace usb_pad static void refresh_store(ConfigData* cfg) { GtkTreeIter iter; + std::string name; gtk_list_store_clear(cfg->store); for (auto& it : cfg->jsconf) { - for (int i = 0; /*i < JOY_MAPS_COUNT && */ i < (int)it.second.controls.size(); i++) + for (size_t i = 0; i < it.second.controls.size(); i++) { if (it.second.controls[i] < 0) continue; const char* pc_name = "Unknown"; - cfg->cb->get_event_name(cfg->dev_type, i, it.second.controls[i], &pc_name); + bool is_button = (i < cfg->max_buttons); + cfg->cb->get_event_name(cfg->dev_type, i, it.second.controls[i], is_button, &pc_name); gtk_list_store_append(cfg->store, &iter); if (!strcmp(cfg->dev_type, BuzzDevice::TypeName())) { - std::stringstream ss; ss << (1 + i / countof(buzz_map_names)); ss << " "; ss << buzz_map_names[i % countof(buzz_map_names)]; - - std::string name = ss.str(); - - gtk_list_store_set(cfg->store, &iter, - COL_NAME, it.first.c_str(), - COL_PS2, name.c_str(), - COL_PC, pc_name, - COL_COLUMN_WIDTH, 50, - COL_BINDING, i, - -1); + name = ss.str(); } + else if (!strcmp(cfg->dev_type, PadDevice::TypeName())) + name = JoystickMapNames[i]; + else if (!strcmp(cfg->dev_type, KeyboardmaniaDevice::TypeName())) + name = kbdmania_key_labels[i]; else { - gtk_list_store_set(cfg->store, &iter, - COL_NAME, it.first.c_str(), - COL_PS2, JoystickMapNames[i], - COL_PC, pc_name, - COL_COLUMN_WIDTH, 50, - COL_BINDING, i, - -1); + std::stringstream ss; + if (is_button) + ss << "Button " << i; + else + ss << "Axis " << (i - cfg->max_buttons); + name = ss.str(); } + + gtk_list_store_set(cfg->store, &iter, + COL_NAME, it.first.c_str(), + COL_PS2, name.c_str(), + COL_PC, pc_name, + COL_BINDING, i, + -1); } } } @@ -231,7 +238,7 @@ namespace usb_pad } } - static void button_clicked(GtkComboBox* widget, gpointer data) + static void button_clicked_wheel(GtkWidget* widget, gpointer data) { int type = reinterpret_cast(g_object_get_data(G_OBJECT(widget), JOYTYPE)); ConfigData* cfg = (ConfigData*)g_object_get_data(G_OBJECT(widget), CFG); @@ -271,7 +278,7 @@ namespace usb_pad } } - static void button_clicked_buzz(GtkComboBox* widget, gpointer data) + static void button_clicked(GtkWidget* widget, gpointer data) { int type = reinterpret_cast(g_object_get_data(G_OBJECT(widget), JOYTYPE)); ConfigData* cfg = (ConfigData*)g_object_get_data(G_OBJECT(widget), CFG); @@ -349,13 +356,6 @@ namespace usb_pad gtk_tree_selection_selected_foreach(sel, view_selected_foreach_func, &rr_list); - /* // single row selection - GtkTreeIter iter; - - if (gtk_tree_selection_get_selected(sel, &model, &iter)) { - view_selected_foreach_func(model, nullptr, &iter, cfg); - }*/ - GList* list = gtk_tree_selection_get_selected_rows(sel, &model); // remove rows from store pointed to by row references for (node = g_list_first(rr_list); node != nullptr; node = node->next) @@ -364,14 +364,12 @@ namespace usb_pad if (path) { GtkTreeIter iter; - if (gtk_tree_model_get_iter(model, &iter, path)) { view_remove_binding(model, &iter, cfg); - //gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } } - }; + } g_list_free_full(rr_list, (GDestroyNotify)gtk_tree_row_reference_free); g_list_free_full(list, (GDestroyNotify)gtk_tree_path_free); @@ -394,14 +392,93 @@ namespace usb_pad } } + static GtkWidget* make_dialog(GtkWindow* parent, const std::string& title, int w = 1200, int h = 700) + { + auto dlg = gtk_dialog_new_with_buttons( + title.c_str(), parent, GTK_DIALOG_MODAL, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE); + gtk_window_set_default_size(GTK_WINDOW(dlg), w, h); + return dlg; + } + + static void create_panes(GtkWidget* container, GtkWidget*& left_vbox, GtkWidget*& right_vbox) + { + GtkWidget* paned = gtk_hpaned_new(); + gtk_container_add(GTK_CONTAINER(container), paned); + + left_vbox = gtk_vbox_new(FALSE, 5); + right_vbox = gtk_vbox_new(FALSE, 15); + gtk_paned_add1(GTK_PANED(paned), left_vbox); + + GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), right_vbox); + //gtk_container_add(GTK_CONTAINER(scrolled), right_vbox); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_paned_add2(GTK_PANED(paned), scrolled); +#if GTK_CHECK_VERSION(3, 0, 0) + gtk_widget_set_vexpand(left_vbox, TRUE); + gtk_widget_set_valign(right_vbox, GTK_ALIGN_START); +#endif + } + + GtkWidget* make_mappings_treeview(int port, ConfigData& cfg, GtkWidget* container) + { + GtkWidget* button; + auto treeview = gtk_tree_view_new(); + cfg.treeview = GTK_TREE_VIEW(treeview); + auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); + + GtkCellRenderer* render = gtk_cell_renderer_text_new(); + + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), + -1, "Name", render, "text", COL_NAME, NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), + -1, "PS2", render, "text", COL_PS2, NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), + -1, "PC", render, "text", COL_PC, NULL); + + gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(treeview), 0); + + gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0), TRUE); + gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 1), TRUE); + gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 2), TRUE); + + gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(cfg.store)); + g_object_unref(GTK_TREE_MODEL(cfg.store)); //treeview has its own ref + + GtkWidget* scwin = gtk_scrolled_window_new(NULL, NULL); + gtk_container_add(GTK_CONTAINER(scwin), treeview); + gtk_widget_set_size_request(GTK_WIDGET(scwin), 200, 100); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin), GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start(GTK_BOX(container), scwin, TRUE, TRUE, 5); + + button = gtk_button_new_with_label("Clear binding"); + gtk_box_pack_start(GTK_BOX(container), button, FALSE, FALSE, 5); + g_object_set_data(G_OBJECT(button), CFG, &cfg); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_binding_clicked), reinterpret_cast(port)); + + button = gtk_button_new_with_label("Clear All"); + gtk_box_pack_start(GTK_BOX(container), button, FALSE, FALSE, 5); + g_object_set_data(G_OBJECT(button), CFG, &cfg); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_all_clicked), reinterpret_cast(port)); + return treeview; + } + int GtkPadConfigure(int port, const char* dev_type, const char* apititle, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs) { GtkWidget *ro_frame, *rs_cb; - GtkWidget *main_hbox, *right_vbox, *left_vbox, *treeview; + GtkWidget *right_vbox, *left_vbox; GtkWidget* button; int fd; - ConfigData cfg; + ConfigData cfg{}; apicbs.populate(cfg.joysticks); @@ -411,6 +488,8 @@ namespace usb_pad G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); cfg.cb = &apicbs; cfg.dev_type = dev_type; + cfg.max_axes = 3; + cfg.max_buttons = JOY_STEERING; // 16 for (const auto& it : cfg.joysticks) { @@ -420,7 +499,7 @@ namespace usb_pad } ConfigMapping c(fd); - LoadMappings(cfg.dev_type, port, it.id, c); + LoadMappings(cfg.dev_type, port, it.id, cfg.max_buttons, cfg.max_axes, c); cfg.jsconf.push_back(std::make_pair(it.id, c)); } @@ -440,68 +519,12 @@ namespace usb_pad std::string title = (port ? "Player One " : "Player Two "); title += apititle; - GtkWidget* dlg = gtk_dialog_new_with_buttons( - title.c_str(), parent, GTK_DIALOG_MODAL, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); - gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE); - gtk_window_set_default_size(GTK_WINDOW(dlg), 320, 240); + GtkWidget* dlg = make_dialog(parent, title); // --------------------------- GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg)); - - main_hbox = gtk_hbox_new(FALSE, 5); - gtk_container_add(GTK_CONTAINER(dlg_area_box), main_hbox); - - left_vbox = gtk_vbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(main_hbox), left_vbox, TRUE, TRUE, 5); - right_vbox = gtk_vbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(main_hbox), right_vbox, TRUE, TRUE, 5); - - // --------------------------- - treeview = gtk_tree_view_new(); - cfg.treeview = GTK_TREE_VIEW(treeview); - auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - GtkCellRenderer* render = gtk_cell_renderer_text_new(); - - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), - -1, "Name", render, "text", COL_NAME, "width", COL_COLUMN_WIDTH, NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), - -1, "PS2", render, "text", COL_PS2, NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), - -1, "PC", render, "text", COL_PC, NULL); - - gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(treeview), 0); - - gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0), TRUE); - gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 1), TRUE); - gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 2), TRUE); - - gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(cfg.store)); - g_object_unref(GTK_TREE_MODEL(cfg.store)); //treeview has its own ref - - GtkWidget* scwin = gtk_scrolled_window_new(NULL, NULL); - gtk_container_add(GTK_CONTAINER(scwin), treeview); - //gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scwin), 200); - gtk_widget_set_size_request(GTK_WIDGET(scwin), 200, 100); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin), GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_box_pack_start(GTK_BOX(left_vbox), scwin, TRUE, TRUE, 5); - - button = gtk_button_new_with_label("Clear binding"); - gtk_box_pack_start(GTK_BOX(left_vbox), button, FALSE, FALSE, 5); - g_object_set_data(G_OBJECT(button), CFG, &cfg); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_binding_clicked), reinterpret_cast(port)); - - button = gtk_button_new_with_label("Clear All"); - gtk_box_pack_start(GTK_BOX(left_vbox), button, FALSE, FALSE, 5); - g_object_set_data(G_OBJECT(button), CFG, &cfg); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_all_clicked), reinterpret_cast(port)); - + create_panes(dlg_area_box, left_vbox, right_vbox); + make_mappings_treeview(port, cfg, left_vbox); // --------------------------- @@ -549,7 +572,7 @@ namespace usb_pad for (int i = 0; i < (int)countof(button_labels); i++) { GtkWidget* button = gtk_button_new_with_label(button_labels[i]); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked_wheel), reinterpret_cast(port)); g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(button_pos[i].type)); g_object_set_data(G_OBJECT(button), CFG, &cfg); @@ -567,19 +590,19 @@ namespace usb_pad gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5); g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(JOY_STEERING)); g_object_set_data(G_OBJECT(button), CFG, &cfg); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked_wheel), reinterpret_cast(port)); button = gtk_button_new_with_label("Throttle"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5); g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(JOY_THROTTLE)); g_object_set_data(G_OBJECT(button), CFG, &cfg); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked_wheel), reinterpret_cast(port)); button = gtk_button_new_with_label("Brake"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5); g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(JOY_BRAKE)); g_object_set_data(G_OBJECT(button), CFG, &cfg); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked_wheel), reinterpret_cast(port)); gtk_box_pack_start(GTK_BOX(right_vbox), cfg.label, TRUE, TRUE, 5); } @@ -688,7 +711,7 @@ namespace usb_pad } for (auto& it : cfg.jsconf) - SaveMappings(dev_type, port, it.first, it.second); + SaveMappings(dev_type, port, it.first, cfg.max_buttons, cfg.max_axes, it.second); if (is_evdev) { @@ -731,11 +754,10 @@ namespace usb_pad int GtkBuzzConfigure(int port, const char* dev_type, const char* apititle, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs) { - GtkWidget *main_hbox, *right_vbox, *left_vbox, *treeview; - GtkWidget* button; + GtkWidget *main_hbox, *right_vbox, *left_vbox; int fd; - ConfigData cfg; + ConfigData cfg{}; apicbs.populate(cfg.joysticks); @@ -765,14 +787,7 @@ namespace usb_pad std::string title = "Buzz "; title += apititle; - GtkWidget* dlg = gtk_dialog_new_with_buttons( - title.c_str(), parent, GTK_DIALOG_MODAL, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); - gtk_window_set_resizable(GTK_WINDOW(dlg), TRUE); - gtk_window_set_default_size(GTK_WINDOW(dlg), 320, 240); + GtkWidget* dlg = make_dialog(parent, title); // --------------------------- GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg)); @@ -781,50 +796,15 @@ namespace usb_pad gtk_container_add(GTK_CONTAINER(dlg_area_box), main_hbox); left_vbox = gtk_vbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(main_hbox), left_vbox, TRUE, TRUE, 5); right_vbox = gtk_vbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(main_hbox), left_vbox, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(main_hbox), right_vbox, TRUE, TRUE, 5); - // --------------------------- - treeview = gtk_tree_view_new(); - cfg.treeview = GTK_TREE_VIEW(treeview); - auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); - gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); - - GtkCellRenderer* render = gtk_cell_renderer_text_new(); - - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), - -1, "Name", render, "text", COL_NAME, "width", COL_COLUMN_WIDTH, NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), - -1, "PS2", render, "text", COL_PS2, NULL); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), - -1, "PC", render, "text", COL_PC, NULL); - - gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(treeview), 0); - - gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0), TRUE); - gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 1), TRUE); - gtk_tree_view_column_set_resizable(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 2), TRUE); - - gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(cfg.store)); - g_object_unref(GTK_TREE_MODEL(cfg.store)); //treeview has its own ref - - GtkWidget* scwin = gtk_scrolled_window_new(NULL, NULL); - gtk_container_add(GTK_CONTAINER(scwin), treeview); - gtk_widget_set_size_request(GTK_WIDGET(scwin), 200, 100); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin), GTK_POLICY_AUTOMATIC, - GTK_POLICY_ALWAYS); - gtk_box_pack_start(GTK_BOX(left_vbox), scwin, TRUE, TRUE, 5); - - button = gtk_button_new_with_label("Clear binding"); - gtk_box_pack_start(GTK_BOX(left_vbox), button, FALSE, FALSE, 5); - g_object_set_data(G_OBJECT(button), CFG, &cfg); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_binding_clicked), reinterpret_cast(port)); + make_mappings_treeview(port, cfg, left_vbox); - button = gtk_button_new_with_label("Clear All"); - gtk_box_pack_start(GTK_BOX(left_vbox), button, FALSE, FALSE, 5); - g_object_set_data(G_OBJECT(button), CFG, &cfg); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(clear_all_clicked), reinterpret_cast(port)); +#if GTK_CHECK_VERSION(3, 0, 0) + gtk_widget_set_vexpand(left_vbox, TRUE); +#endif // --------------------------- @@ -877,7 +857,7 @@ namespace usb_pad if (GTK_IS_ALIGNMENT(children->data)) gtk_alignment_set(GTK_ALIGNMENT(children->data), 0.0f, 0.5f, 0.2f, 0.f); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked_buzz), reinterpret_cast(port)); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(j * countof(buzz_btns) + buzz_btns[i])); g_object_set_data(G_OBJECT(button), CFG, &cfg); @@ -930,5 +910,243 @@ namespace usb_pad return ret; } + int GtkKeyboardmaniaConfigure(int port, const char* dev_type, const char* apititle, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs) + { + GtkWidget *right_vbox, *left_vbox; + + int fd; + ConfigData cfg{}; + + apicbs.populate(cfg.joysticks); + + cfg.js_iter = cfg.joysticks.end(); + cfg.label = gtk_label_new(""); + cfg.store = gtk_list_store_new(NUM_COLS, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); + cfg.cb = &apicbs; + cfg.dev_type = dev_type; + cfg.max_buttons = 31; + + for (const auto& it : cfg.joysticks) + { + if ((fd = open(it.path.c_str(), O_RDONLY | O_NONBLOCK)) < 0) + { + continue; + } + + ConfigMapping c; + c.fd = fd; + LoadMappings(cfg.dev_type, port, it.id, cfg.max_buttons, 0, c); + cfg.jsconf.push_back(std::make_pair(it.id, c)); + } + + refresh_store(&cfg); + + // --------------------------- + std::string title = "Keyboardmania "; + title += apititle; + + GtkWidget* dlg = make_dialog(parent, title); + + // --------------------------- + GtkWidget* dlg_area_box = gtk_dialog_get_content_area(GTK_DIALOG(dlg)); + create_panes(dlg_area_box, left_vbox, right_vbox); + make_mappings_treeview(port, cfg, left_vbox); + + // --------------------------- + // Remapping + { + GtkWidget* table = gtk_table_new(5, 14, true); + gtk_container_add(GTK_CONTAINER(right_vbox), table); + GtkAttachOptions opt = (GtkAttachOptions)(GTK_EXPAND | GTK_FILL); // default + + struct keys + { + u32 index; + bool sharp; + }; + + constexpr keys keys[]{ + {0, false}, + {1, true}, + {2, false}, + {3, true}, + {4, false}, + {5, false}, + {6, true}, + //{"padding", 7}, + {8, false}, + {9, true}, + {10, false}, + {11, true}, + {12, false}, + {13, false}, + //{"Select", 14}, + //{"padding", 15}, + {16, true}, + {17, false}, + {18, true}, + {19, false}, + {20, false}, + {21, true}, + //{"Start", 22}, + //{"padding", 23}, + {24, false}, + {25, true}, + {26, false}, + {27, true}, + {28, false}, + //{"Up", 29}, + //{"Down", 30}, + }; + + int attached = 0; + int voffset = 0; + for (auto& key : keys) + { + GtkWidget* button = gtk_button_new_with_label(kbdmania_key_labels[key.index]); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(key.index)); + g_object_set_data(G_OBJECT(button), CFG, &cfg); + + if (attached > 6) + { + voffset = 2; + attached = 0; + } + + if (!key.sharp) + { + gtk_table_attach(GTK_TABLE(table), button, + attached * 2, 2 + attached * 2, + 1 + voffset, 2 + voffset, + opt, opt, 5, 1); + attached++; + } + else + gtk_table_attach(GTK_TABLE(table), button, + attached * 2 - 1, attached * 2 + 2 - 1, + 0 + voffset, 1 + voffset, + opt, opt, 5, 1); + } + + GtkWidget *button, *frame_box, *frame; + GtkWidget* frame_container = gtk_hbox_new(FALSE, 5); + gtk_container_add(GTK_CONTAINER(right_vbox), frame_container); +#if GTK_CHECK_VERSION(3, 0, 0) + gtk_widget_set_valign(frame_container, GTK_ALIGN_START); +#endif + + frame = gtk_frame_new("Buttons"); + { + frame_box = gtk_hbox_new(FALSE, 5); + gtk_container_add(GTK_CONTAINER(frame), frame_box); + gtk_box_pack_start(GTK_BOX(frame_container), frame, FALSE, FALSE, 5); + + button = gtk_button_new_with_label("Start (22)"); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(22)); + g_object_set_data(G_OBJECT(button), CFG, &cfg); + gtk_box_pack_start(GTK_BOX(frame_box), button, FALSE, FALSE, 5); + + button = gtk_button_new_with_label("Select (14)"); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(14)); + g_object_set_data(G_OBJECT(button), CFG, &cfg); + gtk_box_pack_start(GTK_BOX(frame_box), button, FALSE, FALSE, 5); + } + + frame = gtk_frame_new("Wheel"); + { + frame_box = gtk_hbox_new(FALSE, 5); + gtk_container_add(GTK_CONTAINER(frame), frame_box); + gtk_box_pack_start(GTK_BOX(frame_container), frame, FALSE, FALSE, 5); + + button = gtk_button_new_with_label("Up (29)"); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(29)); + g_object_set_data(G_OBJECT(button), CFG, &cfg); + gtk_box_pack_start(GTK_BOX(frame_box), button, FALSE, FALSE, 5); + + button = gtk_button_new_with_label("Down (30)"); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), reinterpret_cast(port)); + g_object_set_data(G_OBJECT(button), JOYTYPE, reinterpret_cast(30)); + g_object_set_data(G_OBJECT(button), CFG, &cfg); + gtk_box_pack_start(GTK_BOX(frame_box), button, FALSE, FALSE, 5); + } + } + + gtk_box_pack_start(GTK_BOX(right_vbox), cfg.label, TRUE, TRUE, 5); + + bool is_evdev = (strncmp(apiname, "evdev", 5) == 0); + if (is_evdev) + { + std::string path; + LoadSetting(dev_type, port, apiname, N_JOYSTICK, path); + LoadSetting(dev_type, port, apiname, N_HIDRAW_FF_PT, cfg.use_hidraw_ff_pt); + + GtkWidget* ro_frame = gtk_frame_new("Device pass-through using hidraw"); + gtk_box_pack_start(GTK_BOX(right_vbox), ro_frame, FALSE, FALSE, 5); + + GtkWidget* frame_vbox = gtk_vbox_new(FALSE, 5); + gtk_container_add(GTK_CONTAINER(ro_frame), frame_vbox); + + GtkWidget* chk_btn = gtk_check_button_new_with_label("Enable"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_btn), (gboolean)cfg.use_hidraw_ff_pt); + //g_object_set_data(G_OBJECT(chk_btn), CFG, &cfg); + g_signal_connect(G_OBJECT(chk_btn), "toggled", G_CALLBACK(checkbox_toggled), reinterpret_cast(&cfg.use_hidraw_ff_pt)); + gtk_box_pack_start(GTK_BOX(frame_vbox), chk_btn, FALSE, FALSE, 5); + + GtkWidget* rs_cb = new_combobox("Device:", frame_vbox); + + int idx = 0, sel_idx = 0; + for (auto& it : cfg.joysticks) + { + std::stringstream str; + str << it.name; + if (!strcmp(apiname, "evdev") && !it.id.empty()) + str << " [" << it.id << "]"; + + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), str.str().c_str()); + if (path == it.path) + sel_idx = idx; + idx++; + } + + g_object_set_data(G_OBJECT(rs_cb), CFG, &cfg); + g_signal_connect(G_OBJECT(rs_cb), "changed", G_CALLBACK(joystick_changed), reinterpret_cast(port)); + gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), sel_idx); + } + + // --------------------------- + gtk_widget_show_all(dlg); + gint result = gtk_dialog_run(GTK_DIALOG(dlg)); + + int ret = RESULT_OK; + if (result == GTK_RESPONSE_OK) + { + if (cfg.js_iter != cfg.joysticks.end()) + { + if (!SaveSetting(dev_type, port, apiname, N_JOYSTICK, cfg.js_iter->path)) + ret = RESULT_FAILED; + } + if (is_evdev) + { + SaveSetting(dev_type, port, apiname, N_HIDRAW_FF_PT, cfg.use_hidraw_ff_pt); + } + + for (auto& it : cfg.jsconf) + SaveMappings(dev_type, port, it.first, cfg.max_buttons, 0, it.second); + } + else + ret = RESULT_CANCELED; + + for (auto& it : cfg.jsconf) + close(it.second.fd); + + gtk_widget_destroy(dlg); + return ret; + } + } // namespace evdev } // namespace usb_pad diff --git a/pcsx2/USB/usb-pad/evdev/shared.h b/pcsx2/USB/usb-pad/evdev/shared.h index 090cd6f76aaf2..08bd5f204ec17 100644 --- a/pcsx2/USB/usb-pad/evdev/shared.h +++ b/pcsx2/USB/usb-pad/evdev/shared.h @@ -16,6 +16,7 @@ #pragma once #include #include +#include "Pcsx2Types.h" #include "../../gtk.h" #include "../padproxy.h" #include "../../configuration.h" @@ -46,7 +47,6 @@ namespace usb_pad COL_NAME = 0, COL_PS2, COL_PC, - COL_COLUMN_WIDTH, COL_BINDING, NUM_COLS }; @@ -76,7 +76,7 @@ namespace usb_pad JOY_MAPS_COUNT }; - static constexpr const char* JoystickMapNames[] = { + constexpr const char* JoystickMapNames[]{ "cross", "square", "circle", @@ -95,9 +95,10 @@ namespace usb_pad "right", "steering", "throttle", - "brake"}; + "brake", + }; - static constexpr const char* buzz_map_names[] = { + constexpr const char* buzz_map_names[]{ "red", "yellow", "green", @@ -105,6 +106,40 @@ namespace usb_pad "blue", }; + constexpr const char* kbdmania_key_labels[]{ + "C 1 (0)", + "C# 1 (1)", + "D 1 (2)", + "D# 1 (3)", + "E 1 (4)", + "F 1 (5)", + "F# 1 (6)", + "", + "G 1 (8)", + "G# 1 (9)", + "A 1 (10)", + "A# 1 (11)", + "B 1 (12)", + "C 2 (13)", + "Select (14)", + "", + "C# 2 (16)", + "D 2 (17)", + "D# 2 (18)", + "E 2 (19)", + "F 2 (20)", + "F# 2 (21)", + "Start (22)", + "", + "G 2 (24)", + "G# 2 (25)", + "A 2 (26)", + "A# 2 (27)", + "B 2 (28)", + "Up (29)", + "Down (30)", + }; + struct Point { int x; @@ -128,7 +163,7 @@ namespace usb_pad struct ApiCallbacks { - bool (*get_event_name)(const char* dev_type, int map, int event, const char** name); + bool (*get_event_name)(const char* dev_type, int map, int event, bool is_button, const char** name); void (*populate)(device_list& jsdata); bool (*poll)(const std::vector>& jsconf, std::string& dev_name, bool isaxis, int& value, bool& inverted, int& initial); }; @@ -145,6 +180,7 @@ namespace usb_pad ApiCallbacks* cb; int use_hidraw_ff_pt; const char* dev_type; + u32 max_axes, max_buttons; }; struct axis_correct @@ -167,8 +203,9 @@ namespace usb_pad int GtkPadConfigure(int port, const char* dev_type, const char* title, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs); int GtkBuzzConfigure(int port, const char* dev_type, const char* title, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs); - bool LoadMappings(const char* dev_type, int port, const std::string& joyname, ConfigMapping& cfg); - bool SaveMappings(const char* dev_type, int port, const std::string& joyname, const ConfigMapping& cfg); + int GtkKeyboardmaniaConfigure(int port, const char* dev_type, const char* apititle, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs); + bool LoadMappings(const char* dev_type, int port, const std::string& joyname, u32 max_buttons, u32 max_axes, ConfigMapping& cfg); + bool SaveMappings(const char* dev_type, int port, const std::string& joyname, u32 max_buttons, u32 max_axes, const ConfigMapping& cfg); bool LoadBuzzMappings(const char* dev_type, int port, const std::string& joyname, ConfigMapping& cfg); bool SaveBuzzMappings(const char* dev_type, int port, const std::string& joyname, const ConfigMapping& cfg); } // namespace evdev diff --git a/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp b/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp index de2bdd91878d3..f4606a508fec6 100644 --- a/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp +++ b/pcsx2/USB/usb-pad/joydev/joydev-gtk.cpp @@ -32,10 +32,10 @@ namespace usb_pad #define JOYTYPE "joytype" #define CFG "cfg" - static bool GetEventName(const char* dev_type, int map, int event, const char** name) + static bool GetEventName(const char* dev_type, int map, int event, bool is_button, const char** name) { static char buf[256] = {0}; - if (map < evdev::JOY_STEERING) + if (is_button) { snprintf(buf, sizeof(buf), "Button %d", event); } diff --git a/pcsx2/USB/usb-pad/joydev/joydev.cpp b/pcsx2/USB/usb-pad/joydev/joydev.cpp index 3e3a9adc0177a..3cfee589ab9eb 100644 --- a/pcsx2/USB/usb-pad/joydev/joydev.cpp +++ b/pcsx2/USB/usb-pad/joydev/joydev.cpp @@ -73,7 +73,6 @@ namespace usb_pad close(fd); } } - //quit: closedir(dirp); } @@ -381,7 +380,7 @@ namespace usb_pad continue; } - LoadMappings(mDevType, mPort, device.name, device.cfg); + LoadMappings(mDevType, mPort, device.name, 3, 16, device.cfg); // Axis Mapping if (ioctl(device.cfg.fd, JSIOCGAXMAP, device.axis_map) < 0) @@ -394,16 +393,17 @@ namespace usb_pad if (ioctl(device.cfg.fd, JSIOCGAXES, &(count)) >= 0) { for (int i = 0; i < count; ++i) - - for (int k = 0; k < count; k++) { - for (int i = JOY_STEERING; i < JOY_MAPS_COUNT; i++) + for (int k = 0; k < count; k++) { - if (k == device.cfg.controls[i]) + for (int i = JOY_STEERING; i < JOY_MAPS_COUNT; i++) { - device.axis_map[k] = 0x80 | i; - if (i == JOY_STEERING) - has_steering = true; + if (k == device.cfg.controls[i]) + { + device.axis_map[k] = 0x80 | i; + if (i == JOY_STEERING) + has_steering = true; + } } } } diff --git a/pcsx2/USB/usb-pad/usb-pad.cpp b/pcsx2/USB/usb-pad/usb-pad.cpp index 7e72df4c73e24..6f86fed197079 100644 --- a/pcsx2/USB/usb-pad/usb-pad.cpp +++ b/pcsx2/USB/usb-pad/usb-pad.cpp @@ -93,7 +93,7 @@ namespace usb_pad std::list KeyboardmaniaDevice::ListAPIs() { - return PadDevice::ListAPIs(); + return {"evdev"}; } const TCHAR* KeyboardmaniaDevice::LongAPIName(const std::string& name) @@ -570,13 +570,13 @@ namespace usb_pad if (!proxy) { Console.WriteLn("USB: PAD: Invalid input API.\n"); - return NULL; + return nullptr; } Pad* pad = proxy->CreateObject(port, TypeName()); if (!pad) - return NULL; + return nullptr; pad->Type((PS2WheelTypes)conf.WheelType[port]); PADState* s = new PADState(); @@ -698,13 +698,13 @@ namespace usb_pad if (!proxy) { Console.WriteLn("RBDK: Invalid input API.\n"); - return NULL; + return nullptr; } Pad* pad = proxy->CreateObject(port, TypeName()); if (!pad) - return NULL; + return nullptr; pad->Type(WT_ROCKBAND1_DRUMKIT); PADState* s = new PADState(); @@ -844,13 +844,13 @@ namespace usb_pad if (!proxy) { Console.WriteLn("usb-pad: %s: Invalid input API.", TypeName()); - return NULL; + return nullptr; } Pad* pad = proxy->CreateObject(port, TypeName()); if (!pad) - return NULL; + return nullptr; pad->Type(WT_KEYBOARDMANIA_CONTROLLER); PADState* s = new PADState(); diff --git a/pcsx2/USB/usb-pad/usb-pad.h b/pcsx2/USB/usb-pad/usb-pad.h index 9805421c999d2..d95753fc2cda9 100644 --- a/pcsx2/USB/usb-pad/usb-pad.h +++ b/pcsx2/USB/usb-pad/usb-pad.h @@ -97,7 +97,6 @@ namespace usb_pad static const TCHAR* LongAPIName(const std::string& name); static int Configure(int port, const std::string& api, void* data); static int Freeze(int mode, USBDevice* dev, void* data); - static void Initialize(); }; class SeamicDevice @@ -455,16 +454,16 @@ namespace usb_pad static const int HATS_8TO4[] = {PAD_HAT_N, PAD_HAT_E, PAD_HAT_S, PAD_HAT_W}; #define PAD_VID 0x046D -#define PAD_PID 0xCA03 //black MOMO +#define PAD_PID 0xCA03 //black MOMO #define GENERIC_PID 0xC294 //actually Driving Force aka PID that most logitech wheels initially report #define PID_DF 0xC294 #define PID_DFP 0xC298 //SELECT + R3 + RIGHT SHIFT PADDLE (R1) ??? #define PID_DFGT 0xC29A #define PID_FORMULA 0xC202 //Yellow Wingman Formula -#define PID_FGP 0xC20E //Formula GP (maybe GT FORCE LPRC-1000) -#define PID_FFGP 0xC293 // Formula Force GP -#define PID_GTF 0xC293 // as is Formula Force GP -#define PID_G25 0xC299 // OutRun 2 (jp) supports it apparently +#define PID_FGP 0xC20E //Formula GP (maybe GT FORCE LPRC-1000) +#define PID_FFGP 0xC293 // Formula Force GP +#define PID_GTF 0xC293 // as is Formula Force GP +#define PID_G25 0xC299 // OutRun 2 (jp) supports it apparently #define MAX_BUTTONS 32 #define MAX_AXES 7 //random 7: axes + hatswitch #define MAX_JOYS 32 @@ -472,10 +471,10 @@ namespace usb_pad /** linux hid-lg4ff.c http://www.spinics.net/lists/linux-input/msg16570.html - Every Logitech wheel reports itself as generic Logitech Driving Force wheel (VID 046d, PID c294). This is done to ensure that the - wheel will work on every USB HID-aware system even when no Logitech driver is available. It however limits the capabilities of the - wheel - range is limited to 200 degrees, G25/G27 don't report the clutch pedal and there is only one combined axis for throttle and - brake. The switch to native mode is done via hardware-specific command which is different for each wheel. When the wheel + Every Logitech wheel reports itself as generic Logitech Driving Force wheel (VID 046d, PID c294). This is done to ensure that the + wheel will work on every USB HID-aware system even when no Logitech driver is available. It however limits the capabilities of the + wheel - range is limited to 200 degrees, G25/G27 don't report the clutch pedal and there is only one combined axis for throttle and + brake. The switch to native mode is done via hardware-specific command which is different for each wheel. When the wheel receives such command, it simulates reconnect and reports to the OS with its actual PID. Currently not emulating reattachment. Any games that expect to? **/ @@ -1125,7 +1124,7 @@ namespace usb_pad 0x03, // bmAttributes (Interrupt) 0x40, 0x00, // wMaxPacketSize 64 0x0A, // bInterval 10 (unit depends on device speed) - // 41 bytes + // 41 bytes }; //Wii Rock Band drum kit