summaryrefslogtreecommitdiff
path: root/plugins/dfinput
diff options
context:
space:
mode:
authorSND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2012-11-18 18:15:59 +0000
committerSND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2012-11-18 18:15:59 +0000
commit065ccce6e919353d1e746057521e8e317b9acf12 (patch)
treed08f773fe1d980faf8ca88c445da5b1b1c919874 /plugins/dfinput
parentadc29a23861e66c104fb411e67e04019c8888ec9 (diff)
Unix style EOL (thanks to darktjm);
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@81299 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins/dfinput')
-rwxr-xr-x[-rw-r--r--]plugins/dfinput/cfg-gtk2.c1574
-rwxr-xr-x[-rw-r--r--]plugins/dfinput/pad.c1374
-rwxr-xr-x[-rw-r--r--]plugins/dfinput/pad.h482
-rwxr-xr-x[-rw-r--r--]plugins/dfinput/xkb.c0
4 files changed, 1715 insertions, 1715 deletions
diff --git a/plugins/dfinput/cfg-gtk2.c b/plugins/dfinput/cfg-gtk2.c
index 4c06f5b0..18f746d3 100644..100755
--- a/plugins/dfinput/cfg-gtk2.c
+++ b/plugins/dfinput/cfg-gtk2.c
@@ -1,787 +1,787 @@
-/*
- * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses>.
- */
-
-#include "cfg.c"
-
-#include <time.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-GtkWidget *MainWindow;
-GtkBuilder *xml;
-
-const int DPad[DKEY_TOTAL] = {
- DKEY_UP,
- DKEY_DOWN,
- DKEY_LEFT,
- DKEY_RIGHT,
- DKEY_CROSS,
- DKEY_CIRCLE,
- DKEY_SQUARE,
- DKEY_TRIANGLE,
- DKEY_L1,
- DKEY_R1,
- DKEY_L2,
- DKEY_R2,
- DKEY_SELECT,
- DKEY_START,
- DKEY_L3,
- DKEY_R3,
- DKEY_ANALOG
-};
-
-const char *DPadText[DKEY_TOTAL] = {
- N_("D-Pad Up"),
- N_("D-Pad Down"),
- N_("D-Pad Left"),
- N_("D-Pad Right"),
- N_("Cross"),
- N_("Circle"),
- N_("Square"),
- N_("Triangle"),
- N_("L1"),
- N_("R1"),
- N_("L2"),
- N_("R2"),
- N_("Select"),
- N_("Start"),
- N_("L3"),
- N_("R3"),
- N_("Analog")
-};
-
-const char *AnalogText[] = {
- N_("L-Stick Right"),
- N_("L-Stick Left"),
- N_("L-Stick Down"),
- N_("L-Stick Up"),
- N_("R-Stick Right"),
- N_("R-Stick Left"),
- N_("R-Stick Down"),
- N_("R-Stick Up")
-};
-
-static int GetSelectedKeyIndex(int padnum) {
- GtkTreeSelection *selection;
- GtkTreeIter iter;
- GtkTreeModel *model;
- GtkTreePath *path;
- gboolean selected;
- int i;
-
- selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk_builder_get_object(xml, padnum == 0 ? "treeview1" : "treeview2")));
- selected = gtk_tree_selection_get_selected(selection, &model, &iter);
-
- if (!selected) {
- return -1;
- }
-
- path = gtk_tree_model_get_path(model, &iter);
- i = *gtk_tree_path_get_indices(path);
- gtk_tree_path_free(path);
-
- return i;
-}
-
-static void GetKeyDescription(char *buf, int joynum, int key) {
- const char *hatname[16] = {_("Centered"), _("Up"), _("Right"), _("Rightup"),
- _("Down"), "", _("Rightdown"), "", _("Left"), _("Leftup"), "", "",
- _("Leftdown"), "", "", ""};
-
- switch (g.cfg.PadDef[joynum].KeyDef[key].JoyEvType) {
- case BUTTON:
- sprintf(buf, _("Joystick: Button %d"), g.cfg.PadDef[joynum].KeyDef[key].J.Button);
- break;
-
- case AXIS:
- sprintf(buf, _("Joystick: Axis %d%c"), abs(g.cfg.PadDef[joynum].KeyDef[key].J.Axis) - 1,
- g.cfg.PadDef[joynum].KeyDef[key].J.Axis > 0 ? '+' : '-');
- break;
-
- case HAT:
- sprintf(buf, _("Joystick: Hat %d %s"), (g.cfg.PadDef[joynum].KeyDef[key].J.Hat >> 8),
- hatname[g.cfg.PadDef[joynum].KeyDef[key].J.Hat & 0x0F]);
- break;
-
- case NONE:
- default:
- buf[0] = '\0';
- break;
- }
-
- if (g.cfg.PadDef[joynum].KeyDef[key].Key != 0) {
- if (buf[0] != '\0') {
- strcat(buf, " / ");
- }
-
- strcat(buf, _("Keyboard:"));
- strcat(buf, " ");
- strcat(buf, XKeysymToString(g.cfg.PadDef[joynum].KeyDef[key].Key));
- } else if (buf[0] == '\0') {
- strcpy(buf, _("(Not Set)"));
- }
-}
-
-static void GetAnalogDescription(char *buf, int joynum, int analognum, int dir) {
- const char *hatname[16] = {_("Centered"), _("Up"), _("Right"), _("Rightup"),
- _("Down"), "", _("Rightdown"), "", _("Left"), _("Leftup"), "", "",
- _("Leftdown"), "", "", ""};
-
- switch (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].JoyEvType) {
- case BUTTON:
- sprintf(buf, _("Joystick: Button %d"), g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Button);
- break;
-
- case AXIS:
- sprintf(buf, _("Joystick: Axis %d%c"), abs(g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Axis) - 1,
- g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Axis > 0 ? '+' : '-');
- break;
-
- case HAT:
- sprintf(buf, _("Joystick: Hat %d %s"), (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Hat >> 8),
- hatname[g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Hat & 0x0F]);
- break;
-
- case NONE:
- default:
- buf[0] = '\0';
- break;
- }
-
- if (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].Key != 0) {
- if (buf[0] != '\0') {
- strcat(buf, " / ");
- }
-
- strcat(buf, _("Keyboard:"));
- strcat(buf, " ");
- strcat(buf, XKeysymToString(g.cfg.PadDef[joynum].AnalogDef[analognum][dir].Key));
- } else if (buf[0] == '\0') {
- strcpy(buf, _("(Not Set)"));
- }
-}
-
-static void UpdateKeyList() {
- const char *widgetname[2] = {"treeview1", "treeview2"};
-
- GtkWidget *widget;
- GtkListStore *store;
- GtkTreeIter iter;
- int i, j;
- char buf[256];
-
- for (i = 0; i < 2; i++) {
- int total;
-
- switch(g.cfg.PadDef[i].Type)
- {
- case PSE_PAD_TYPE_MOUSE:
- total = 0;
- break;
- case PSE_PAD_TYPE_STANDARD:
- total = DKEY_TOTAL - 3;
- break;
- case PSE_PAD_TYPE_ANALOGPAD:
- total = DKEY_TOTAL;
- break;
- }
-
- widget = gtk_builder_get_object(xml, widgetname[i]);
-
- store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-
- for (j = 0; j < total; j++) {
- gtk_list_store_append(store, &iter);
- GetKeyDescription(buf, i, DPad[j]);
- gtk_list_store_set(store, &iter, 0, _(DPadText[j]), 1, buf, -1);
- }
-
- if (g.cfg.PadDef[i].Type == PSE_PAD_TYPE_ANALOGPAD) {
- for (j = 0; j < 8; j++) {
- gtk_list_store_append(store, &iter);
- GetAnalogDescription(buf, i, j / 4, j % 4);
- gtk_list_store_set(store, &iter, 0, _(AnalogText[j]), 1, buf, -1);
- }
- }
-
- gtk_tree_view_set_model(GTK_TREE_VIEW(widget), GTK_TREE_MODEL(store));
- g_object_unref(G_OBJECT(store));
- gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(widget), TRUE);
- gtk_widget_show(widget);
- }
-}
-
-static void UpdateKey() {
- const char *widgetname[2] = {"treeview1", "treeview2"};
- int i, index;
- GtkWidget *widget;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GValue value = {0, };
- char buf[256];
-
- for (i = 0; i < 2; i++) {
- index = GetSelectedKeyIndex(i);
- if (index == -1) continue;
-
- widget = gtk_builder_get_object(xml, widgetname[i]);
- gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)), &model, &iter);
-
- if (index < DKEY_TOTAL) {
- GetKeyDescription(buf, i, DPad[index]);
- } else {
- GetAnalogDescription(buf, i, (index - DKEY_TOTAL) / 4, (index - DKEY_TOTAL) % 4);
- }
-
- g_value_init(&value, G_TYPE_STRING);
- g_value_set_string(&value, buf);
- gtk_list_store_set_value(GTK_LIST_STORE(model), &iter, 1, &value);
- }
-}
-
-static void OnConfigExit(GtkWidget *widget, gpointer user_data) {
- SavePADConfig();
-
- gtk_widget_destroy(widget);
- SDL_Quit();
- XCloseDisplay(g.Disp);
-
- gtk_exit(0);
-}
-
-static void TreeSelectionChanged(GtkTreeSelection *selection, gpointer user_data) {
- GtkTreeIter iter;
- GtkTreeModel *model;
- GtkTreePath *path;
-
- gboolean selected;
- int i;
-
- selected = gtk_tree_selection_get_selected(selection, &model, &iter);
-
- if (selected) {
- path = gtk_tree_model_get_path(model, &iter);
- i = *gtk_tree_path_get_indices(path);
- gtk_tree_path_free(path);
-
- // If a row was selected, and the row is not blank, we can now enable
- // some of the disabled widgets
- if ((int)user_data == 0) {
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange1")), TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset1")), TRUE);
- } else {
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange2")), TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset2")), TRUE);
- }
- } else {
- if ((int)user_data == 0) {
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange1")), FALSE);
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset1")), FALSE);
- } else {
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange2")), FALSE);
- gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset2")), FALSE);
- }
- }
-}
-
-static void OnDeviceChanged(GtkWidget *widget, gpointer user_data) {
- int n = (int)user_data, current = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
- current--;
- g.cfg.PadDef[n].DevNum = current;
-}
-
-static void OnTypeChanged(GtkWidget *widget, gpointer user_data) {
- int n = (int)user_data, current = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
-
- int padTypeList[] = {
- PSE_PAD_TYPE_STANDARD,
- PSE_PAD_TYPE_ANALOGPAD,
- PSE_PAD_TYPE_MOUSE
- };
-
- g.cfg.PadDef[n].Type = padTypeList[current];
-
- UpdateKeyList();
-}
-
-static void OnThreadedToggled(GtkWidget *widget, gpointer user_data) {
- g.cfg.Threaded = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-}
-
-static void OnVisualVibration1Toggled(GtkWidget *widget, gpointer user_data) {
- g.cfg.PadDef[0].VisualVibration = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-}
-
-static void OnVisualVibration2Toggled(GtkWidget *widget, gpointer user_data) {
- g.cfg.PadDef[1].VisualVibration = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-}
-
-static void OnHideCursorToggled(GtkWidget *widget, gpointer user_data) {
- g.cfg.HideCursor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-}
-
-static void ReadDKeyEvent(int padnum, int key) {
- SDL_Joystick *js;
- time_t t;
- GdkEvent *ge;
- int i;
- Sint16 axis, numAxes = 0, InitAxisPos[256], PrevAxisPos[256];
- unsigned char buttons[32];
- uint16_t Key;
-
- if (g.cfg.PadDef[padnum].DevNum >= 0) {
- js = SDL_JoystickOpen(g.cfg.PadDef[padnum].DevNum);
- SDL_JoystickEventState(SDL_IGNORE);
-
- SDL_JoystickUpdate();
-
- numAxes = SDL_JoystickNumAxes(js);
- if (numAxes > 256) numAxes = 256;
-
- for (i = 0; i < numAxes; i++) {
- InitAxisPos[i] = PrevAxisPos[i] = SDL_JoystickGetAxis(js, i);
- }
- } else {
- js = NULL;
- }
-
- t = time(NULL);
-
- while (time(NULL) < t + 10) {
- // check joystick events
- if (js != NULL) {
- SDL_JoystickUpdate();
-
- for (i = 0; i < SDL_JoystickNumButtons(js); i++) {
- if (SDL_JoystickGetButton(js, i)) {
- g.cfg.PadDef[padnum].KeyDef[key].JoyEvType = BUTTON;
- g.cfg.PadDef[padnum].KeyDef[key].J.Button = i;
- goto end;
- }
- }
-
- for (i = 0; i < numAxes; i++) {
- axis = SDL_JoystickGetAxis(js, i);
- if (abs(axis) > 16383 && (abs(axis - InitAxisPos[i]) > 4096 || abs(axis - PrevAxisPos[i]) > 4096)) {
- g.cfg.PadDef[padnum].KeyDef[key].JoyEvType = AXIS;
- g.cfg.PadDef[padnum].KeyDef[key].J.Axis = (i + 1) * (axis > 0 ? 1 : -1);
- goto end;
- }
- PrevAxisPos[i] = axis;
- }
-
- for (i = 0; i < SDL_JoystickNumHats(js); i++) {
- axis = SDL_JoystickGetHat(js, i);
- if (axis != SDL_HAT_CENTERED) {
- g.cfg.PadDef[padnum].KeyDef[key].JoyEvType = HAT;
-
- if (axis & SDL_HAT_UP) {
- g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_UP);
- } else if (axis & SDL_HAT_DOWN) {
- g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_DOWN);
- } else if (axis & SDL_HAT_LEFT) {
- g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_LEFT);
- } else if (axis & SDL_HAT_RIGHT) {
- g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_RIGHT);
- }
-
- goto end;
- }
- }
- }
-
- // check keyboard events
- XQueryKeymap(g.Disp, buttons);
- for (i = 0; i < 256; ++i) {
- if(buttons[i >> 3] & (1 << (i & 7))) {
- Key = XkbKeycodeToKeysym(g.Disp, i, 0, 0);
- if(Key != XK_Escape) {
- g.cfg.PadDef[padnum].KeyDef[key].Key = Key;
- }
- goto end;
- }
- }
-
- usleep(5000);
- }
-
-end:
- if (js != NULL) {
- SDL_JoystickClose(js);
- }
-}
-
-static void ReadAnalogEvent(int padnum, int analognum, int analogdir) {
- SDL_Joystick *js;
- time_t t;
- GdkEvent *ge;
- int i;
- Sint16 axis, numAxes = 0, InitAxisPos[256], PrevAxisPos[256];
- unsigned char buttons[32];
- uint16_t Key;
-
- if (g.cfg.PadDef[padnum].DevNum >= 0) {
- js = SDL_JoystickOpen(g.cfg.PadDef[padnum].DevNum);
- SDL_JoystickEventState(SDL_IGNORE);
-
- SDL_JoystickUpdate();
-
- numAxes = SDL_JoystickNumAxes(js);
- if (numAxes > 256) numAxes = 256;
-
- for (i = 0; i < SDL_JoystickNumAxes(js); i++) {
- InitAxisPos[i] = PrevAxisPos[i] = SDL_JoystickGetAxis(js, i);
- }
- } else {
- js = NULL;
- }
-
- t = time(NULL);
-
- while (time(NULL) < t + 10) {
- // check joystick events
- if (js != NULL) {
- SDL_JoystickUpdate();
-
- for (i = 0; i < SDL_JoystickNumButtons(js); i++) {
- if (SDL_JoystickGetButton(js, i)) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].JoyEvType = BUTTON;
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Button = i;
- goto end;
- }
- }
-
- for (i = 0; i < numAxes; i++) {
- axis = SDL_JoystickGetAxis(js, i);
- if (abs(axis) > 16383 && (abs(axis - InitAxisPos[i]) > 4096 || abs(axis - PrevAxisPos[i]) > 4096)) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].JoyEvType = AXIS;
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Axis = (i + 1) * (axis > 0 ? 1 : -1);
- goto end;
- }
- PrevAxisPos[i] = axis;
- }
-
- for (i = 0; i < SDL_JoystickNumHats(js); i++) {
- axis = SDL_JoystickGetHat(js, i);
- if (axis != SDL_HAT_CENTERED) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].JoyEvType = HAT;
-
- if (axis & SDL_HAT_UP) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_UP);
- } else if (axis & SDL_HAT_DOWN) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_DOWN);
- } else if (axis & SDL_HAT_LEFT) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_LEFT);
- } else if (axis & SDL_HAT_RIGHT) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_RIGHT);
- }
-
- goto end;
- }
- }
- }
-
- // check keyboard events
- XQueryKeymap(g.Disp, buttons);
- for (i = 0; i < 256; ++i) {
- if(buttons[i >> 3] & (1 << (i & 7))) {
- Key = XkbKeycodeToKeysym(g.Disp, i, 0, 0);
- if(Key != XK_Escape) {
- g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].Key = Key;
- }
- goto end;
- }
- }
-
- usleep(5000);
- }
-
-end:
- if (js != NULL) {
- SDL_JoystickClose(js);
- }
-}
-
-static void OnChangeClicked(GtkWidget *widget, gpointer user_data) {
- int pad = (int)user_data;
- int index = GetSelectedKeyIndex(pad);
-
- if (index == -1) return;
-
- if (index < DKEY_TOTAL) {
- ReadDKeyEvent(pad, DPad[index]);
- } else {
- index -= DKEY_TOTAL;
- ReadAnalogEvent(pad, index / 4, index % 4);
- }
-
- UpdateKey();
-}
-
-static void OnResetClicked(GtkWidget *widget, gpointer user_data) {
- int pad = (int)user_data;
- int index = GetSelectedKeyIndex(pad);
-
- if (index == -1) return;
-
- if (index < DKEY_TOTAL) {
- g.cfg.PadDef[pad].KeyDef[DPad[index]].Key = 0;
- g.cfg.PadDef[pad].KeyDef[DPad[index]].JoyEvType = NONE;
- g.cfg.PadDef[pad].KeyDef[DPad[index]].J.Button = 0;
- } else {
- index -= DKEY_TOTAL;
- g.cfg.PadDef[pad].AnalogDef[index / 4][index % 4].Key = 0;
- g.cfg.PadDef[pad].AnalogDef[index / 4][index % 4].JoyEvType = NONE;
- g.cfg.PadDef[pad].AnalogDef[index / 4][index % 4].J.Button = 0;
- }
-
- UpdateKey();
-}
-
-static void PopulateDevList() {
- const char *widgetname[2] = {"combodev1", "combodev2"};
- int i, j, n;
- GtkWidget *widget;
- GtkTreeIter iter;
- GtkListStore *store;
- GtkCellRenderer *renderer;
- char buf[256];
-
- for (i = 0; i < 2; i++) {
- widget = gtk_builder_get_object(xml, widgetname[i]);
-
- renderer = gtk_cell_renderer_text_new();
- gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, FALSE);
- gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0);
-
- store = gtk_list_store_new(1, G_TYPE_STRING);
-
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter, 0, _("None"), -1);
-
- n = SDL_NumJoysticks();
- for (j = 0; j < n; j++) {
- sprintf(buf, "%d: %s", j + 1, SDL_JoystickName(j));
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter, 0, buf, -1);
- }
-
- gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(store));
-
- n = g.cfg.PadDef[i].DevNum + 1;
- if (n > SDL_NumJoysticks()) {
- n = 0;
- g.cfg.PadDef[i].DevNum = -1;
- }
-
- gtk_combo_box_set_active(GTK_COMBO_BOX(widget), n);
- }
-}
-
-long PADconfigure() {
- GtkWidget *widget;
- GtkTreeSelection *treesel;
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
-
- if (SDL_Init(SDL_INIT_JOYSTICK) == -1) {
- fprintf(stderr, "Failed to initialize SDL!\n");
- return -1;
- }
-
- g.Disp = XOpenDisplay(NULL);
- if (!g.Disp) {
- fprintf(stderr, "XOpenDisplay failed!\n");
- return -1;
- }
-
- LoadPADConfig();
-
- xml = gtk_builder_new();
-
- if (!gtk_builder_add_from_file(xml, DATADIR "dfinput.ui", NULL)) {
- g_warning("We could not load the interface!");
- return -1;
- }
-
- MainWindow = gtk_builder_get_object(xml, "CfgWnd");
- gtk_window_set_title(GTK_WINDOW(MainWindow), _("Gamepad/Keyboard Input Configuration"));
-
- widget = gtk_builder_get_object(xml, "treeview1");
-
- // column for key
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Key"),
- renderer, "text", 0, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
-
- // column for button
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Button"),
- renderer, "text", 1, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
-
- treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
- gtk_tree_selection_set_mode(treesel, GTK_SELECTION_SINGLE);
-
- g_signal_connect_data(G_OBJECT(treesel), "changed",
- G_CALLBACK(TreeSelectionChanged), (gpointer)0, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "treeview2");
-
- // column for key
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Key"),
- renderer, "text", 0, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
-
- // column for button
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Button"),
- renderer, "text", 1, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
-
- treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
- gtk_tree_selection_set_mode(treesel, GTK_SELECTION_SINGLE);
-
- g_signal_connect_data(G_OBJECT(treesel), "changed",
- G_CALLBACK(TreeSelectionChanged), (gpointer)1, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "CfgWnd");
- g_signal_connect_data(GTK_OBJECT(widget), "delete_event",
- G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "btnclose");
- g_signal_connect_data(GTK_OBJECT(widget), "clicked",
- G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER);
-
- PopulateDevList();
- UpdateKeyList();
-
- widget = gtk_builder_get_object(xml, "checkmt");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.Threaded);
- g_signal_connect_data(GTK_OBJECT(widget), "toggled",
- G_CALLBACK(OnThreadedToggled), NULL, NULL, G_CONNECT_AFTER);
-
-/*
- widget = gtk_builder_get_object(xml, "checkcg");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.HideCursor);
- g_signal_connect_data(GTK_OBJECT(widget), "toggled",
- G_CALLBACK(OnHideCursorToggled), NULL, NULL, G_CONNECT_AFTER);
-*/
- widget = gtk_builder_get_object(xml, "combodev1");
- g_signal_connect_data(GTK_OBJECT(widget), "changed",
- G_CALLBACK(OnDeviceChanged), (gpointer)0, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "combodev2");
- g_signal_connect_data(GTK_OBJECT(widget), "changed",
- G_CALLBACK(OnDeviceChanged), (gpointer)1, NULL, G_CONNECT_AFTER);
-
- int padTypeList[] = {
- 0,
- 2, // PSE_PAD_TYPE_MOUSE
- 0, // PSE_PAD_TYPE_NEGCON
- 0, // PSE_PAD_TYPE_GUN
- 0, // PSE_PAD_TYPE_STANDARD
- 1, // PSE_PAD_TYPE_ANALOGJOY
- 0, // PSE_PAD_TYPE_GUNCON
- 1, //PSE_PAD_TYPE_ANALOGPAD
- };
-
- widget = gtk_builder_get_object(xml, "combotype1");
- gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
- padTypeList[g.cfg.PadDef[0].Type]);
- g_signal_connect_data(GTK_OBJECT(widget), "changed",
- G_CALLBACK(OnTypeChanged), (gpointer)0, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "combotype2");
- gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
- padTypeList[g.cfg.PadDef[1].Type]);
- g_signal_connect_data(GTK_OBJECT(widget), "changed",
- G_CALLBACK(OnTypeChanged), (gpointer)1, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "checkvv1");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.PadDef[0].VisualVibration);
- g_signal_connect_data(GTK_OBJECT(widget), "toggled",
- G_CALLBACK(OnVisualVibration1Toggled), NULL, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "checkvv2");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.PadDef[1].VisualVibration);
- g_signal_connect_data(GTK_OBJECT(widget), "toggled",
- G_CALLBACK(OnVisualVibration2Toggled), NULL, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "btnchange1");
- gtk_widget_set_sensitive(widget, FALSE);
- g_signal_connect_data(GTK_OBJECT(widget), "clicked",
- G_CALLBACK(OnChangeClicked), (gpointer)0, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "btnreset1");
- gtk_widget_set_sensitive(widget, FALSE);
- g_signal_connect_data(GTK_OBJECT(widget), "clicked",
- G_CALLBACK(OnResetClicked), (gpointer)0, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "btnchange2");
- gtk_widget_set_sensitive(widget, FALSE);
- g_signal_connect_data(GTK_OBJECT(widget), "clicked",
- G_CALLBACK(OnChangeClicked), (gpointer)1, NULL, G_CONNECT_AFTER);
-
- widget = gtk_builder_get_object(xml, "btnreset2");
- gtk_widget_set_sensitive(widget, FALSE);
- g_signal_connect_data(GTK_OBJECT(widget), "clicked",
- G_CALLBACK(OnResetClicked), (gpointer)1, NULL, G_CONNECT_AFTER);
-
- gtk_widget_show(MainWindow);
- gtk_main();
-
- return 0;
-}
-
-void PADabout() {
- const char *authors[]= {"Wei Mingzhi <weimingzhi@gmail.com>", NULL};
- GtkWidget *widget;
-
- widget = gtk_about_dialog_new();
- gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(widget), "Gamepad/Keyboard Input");
- gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.1");
- gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors);
- gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://www.codeplex.com/pcsxr/");
-
- gtk_dialog_run(GTK_DIALOG(widget));
- gtk_widget_destroy(widget);
-}
-
-int main(int argc, char *argv[]) {
-#ifdef ENABLE_NLS
- setlocale(LC_ALL, "");
- bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
- textdomain(GETTEXT_PACKAGE);
-#endif
-
- gtk_set_locale();
- gtk_init(&argc, &argv);
-
- if (argc > 1 && !strcmp(argv[1], "-about")) {
- PADabout();
- } else {
- PADconfigure();
- }
-
- gtk_exit(0);
- return 0;
-}
+/*
+ * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include "cfg.c"
+
+#include <time.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+GtkWidget *MainWindow;
+GtkBuilder *xml;
+
+const int DPad[DKEY_TOTAL] = {
+ DKEY_UP,
+ DKEY_DOWN,
+ DKEY_LEFT,
+ DKEY_RIGHT,
+ DKEY_CROSS,
+ DKEY_CIRCLE,
+ DKEY_SQUARE,
+ DKEY_TRIANGLE,
+ DKEY_L1,
+ DKEY_R1,
+ DKEY_L2,
+ DKEY_R2,
+ DKEY_SELECT,
+ DKEY_START,
+ DKEY_L3,
+ DKEY_R3,
+ DKEY_ANALOG
+};
+
+const char *DPadText[DKEY_TOTAL] = {
+ N_("D-Pad Up"),
+ N_("D-Pad Down"),
+ N_("D-Pad Left"),
+ N_("D-Pad Right"),
+ N_("Cross"),
+ N_("Circle"),
+ N_("Square"),
+ N_("Triangle"),
+ N_("L1"),
+ N_("R1"),
+ N_("L2"),
+ N_("R2"),
+ N_("Select"),
+ N_("Start"),
+ N_("L3"),
+ N_("R3"),
+ N_("Analog")
+};
+
+const char *AnalogText[] = {
+ N_("L-Stick Right"),
+ N_("L-Stick Left"),
+ N_("L-Stick Down"),
+ N_("L-Stick Up"),
+ N_("R-Stick Right"),
+ N_("R-Stick Left"),
+ N_("R-Stick Down"),
+ N_("R-Stick Up")
+};
+
+static int GetSelectedKeyIndex(int padnum) {
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ gboolean selected;
+ int i;
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk_builder_get_object(xml, padnum == 0 ? "treeview1" : "treeview2")));
+ selected = gtk_tree_selection_get_selected(selection, &model, &iter);
+
+ if (!selected) {
+ return -1;
+ }
+
+ path = gtk_tree_model_get_path(model, &iter);
+ i = *gtk_tree_path_get_indices(path);
+ gtk_tree_path_free(path);
+
+ return i;
+}
+
+static void GetKeyDescription(char *buf, int joynum, int key) {
+ const char *hatname[16] = {_("Centered"), _("Up"), _("Right"), _("Rightup"),
+ _("Down"), "", _("Rightdown"), "", _("Left"), _("Leftup"), "", "",
+ _("Leftdown"), "", "", ""};
+
+ switch (g.cfg.PadDef[joynum].KeyDef[key].JoyEvType) {
+ case BUTTON:
+ sprintf(buf, _("Joystick: Button %d"), g.cfg.PadDef[joynum].KeyDef[key].J.Button);
+ break;
+
+ case AXIS:
+ sprintf(buf, _("Joystick: Axis %d%c"), abs(g.cfg.PadDef[joynum].KeyDef[key].J.Axis) - 1,
+ g.cfg.PadDef[joynum].KeyDef[key].J.Axis > 0 ? '+' : '-');
+ break;
+
+ case HAT:
+ sprintf(buf, _("Joystick: Hat %d %s"), (g.cfg.PadDef[joynum].KeyDef[key].J.Hat >> 8),
+ hatname[g.cfg.PadDef[joynum].KeyDef[key].J.Hat & 0x0F]);
+ break;
+
+ case NONE:
+ default:
+ buf[0] = '\0';
+ break;
+ }
+
+ if (g.cfg.PadDef[joynum].KeyDef[key].Key != 0) {
+ if (buf[0] != '\0') {
+ strcat(buf, " / ");
+ }
+
+ strcat(buf, _("Keyboard:"));
+ strcat(buf, " ");
+ strcat(buf, XKeysymToString(g.cfg.PadDef[joynum].KeyDef[key].Key));
+ } else if (buf[0] == '\0') {
+ strcpy(buf, _("(Not Set)"));
+ }
+}
+
+static void GetAnalogDescription(char *buf, int joynum, int analognum, int dir) {
+ const char *hatname[16] = {_("Centered"), _("Up"), _("Right"), _("Rightup"),
+ _("Down"), "", _("Rightdown"), "", _("Left"), _("Leftup"), "", "",
+ _("Leftdown"), "", "", ""};
+
+ switch (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].JoyEvType) {
+ case BUTTON:
+ sprintf(buf, _("Joystick: Button %d"), g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Button);
+ break;
+
+ case AXIS:
+ sprintf(buf, _("Joystick: Axis %d%c"), abs(g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Axis) - 1,
+ g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Axis > 0 ? '+' : '-');
+ break;
+
+ case HAT:
+ sprintf(buf, _("Joystick: Hat %d %s"), (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Hat >> 8),
+ hatname[g.cfg.PadDef[joynum].AnalogDef[analognum][dir].J.Hat & 0x0F]);
+ break;
+
+ case NONE:
+ default:
+ buf[0] = '\0';
+ break;
+ }
+
+ if (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].Key != 0) {
+ if (buf[0] != '\0') {
+ strcat(buf, " / ");
+ }
+
+ strcat(buf, _("Keyboard:"));
+ strcat(buf, " ");
+ strcat(buf, XKeysymToString(g.cfg.PadDef[joynum].AnalogDef[analognum][dir].Key));
+ } else if (buf[0] == '\0') {
+ strcpy(buf, _("(Not Set)"));
+ }
+}
+
+static void UpdateKeyList() {
+ const char *widgetname[2] = {"treeview1", "treeview2"};
+
+ GtkWidget *widget;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ int i, j;
+ char buf[256];
+
+ for (i = 0; i < 2; i++) {
+ int total;
+
+ switch(g.cfg.PadDef[i].Type)
+ {
+ case PSE_PAD_TYPE_MOUSE:
+ total = 0;
+ break;
+ case PSE_PAD_TYPE_STANDARD:
+ total = DKEY_TOTAL - 3;
+ break;
+ case PSE_PAD_TYPE_ANALOGPAD:
+ total = DKEY_TOTAL;
+ break;
+ }
+
+ widget = gtk_builder_get_object(xml, widgetname[i]);
+
+ store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+
+ for (j = 0; j < total; j++) {
+ gtk_list_store_append(store, &iter);
+ GetKeyDescription(buf, i, DPad[j]);
+ gtk_list_store_set(store, &iter, 0, _(DPadText[j]), 1, buf, -1);
+ }
+
+ if (g.cfg.PadDef[i].Type == PSE_PAD_TYPE_ANALOGPAD) {
+ for (j = 0; j < 8; j++) {
+ gtk_list_store_append(store, &iter);
+ GetAnalogDescription(buf, i, j / 4, j % 4);
+ gtk_list_store_set(store, &iter, 0, _(AnalogText[j]), 1, buf, -1);
+ }
+ }
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(widget), GTK_TREE_MODEL(store));
+ g_object_unref(G_OBJECT(store));
+ gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(widget), TRUE);
+ gtk_widget_show(widget);
+ }
+}
+
+static void UpdateKey() {
+ const char *widgetname[2] = {"treeview1", "treeview2"};
+ int i, index;
+ GtkWidget *widget;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GValue value = {0, };
+ char buf[256];
+
+ for (i = 0; i < 2; i++) {
+ index = GetSelectedKeyIndex(i);
+ if (index == -1) continue;
+
+ widget = gtk_builder_get_object(xml, widgetname[i]);
+ gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)), &model, &iter);
+
+ if (index < DKEY_TOTAL) {
+ GetKeyDescription(buf, i, DPad[index]);
+ } else {
+ GetAnalogDescription(buf, i, (index - DKEY_TOTAL) / 4, (index - DKEY_TOTAL) % 4);
+ }
+
+ g_value_init(&value, G_TYPE_STRING);
+ g_value_set_string(&value, buf);
+ gtk_list_store_set_value(GTK_LIST_STORE(model), &iter, 1, &value);
+ }
+}
+
+static void OnConfigExit(GtkWidget *widget, gpointer user_data) {
+ SavePADConfig();
+
+ gtk_widget_destroy(widget);
+ SDL_Quit();
+ XCloseDisplay(g.Disp);
+
+ gtk_exit(0);
+}
+
+static void TreeSelectionChanged(GtkTreeSelection *selection, gpointer user_data) {
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+
+ gboolean selected;
+ int i;
+
+ selected = gtk_tree_selection_get_selected(selection, &model, &iter);
+
+ if (selected) {
+ path = gtk_tree_model_get_path(model, &iter);
+ i = *gtk_tree_path_get_indices(path);
+ gtk_tree_path_free(path);
+
+ // If a row was selected, and the row is not blank, we can now enable
+ // some of the disabled widgets
+ if ((int)user_data == 0) {
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange1")), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset1")), TRUE);
+ } else {
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange2")), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset2")), TRUE);
+ }
+ } else {
+ if ((int)user_data == 0) {
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange1")), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset1")), FALSE);
+ } else {
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnchange2")), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(xml, "btnreset2")), FALSE);
+ }
+ }
+}
+
+static void OnDeviceChanged(GtkWidget *widget, gpointer user_data) {
+ int n = (int)user_data, current = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+ current--;
+ g.cfg.PadDef[n].DevNum = current;
+}
+
+static void OnTypeChanged(GtkWidget *widget, gpointer user_data) {
+ int n = (int)user_data, current = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+
+ int padTypeList[] = {
+ PSE_PAD_TYPE_STANDARD,
+ PSE_PAD_TYPE_ANALOGPAD,
+ PSE_PAD_TYPE_MOUSE
+ };
+
+ g.cfg.PadDef[n].Type = padTypeList[current];
+
+ UpdateKeyList();
+}
+
+static void OnThreadedToggled(GtkWidget *widget, gpointer user_data) {
+ g.cfg.Threaded = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+static void OnVisualVibration1Toggled(GtkWidget *widget, gpointer user_data) {
+ g.cfg.PadDef[0].VisualVibration = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+static void OnVisualVibration2Toggled(GtkWidget *widget, gpointer user_data) {
+ g.cfg.PadDef[1].VisualVibration = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+static void OnHideCursorToggled(GtkWidget *widget, gpointer user_data) {
+ g.cfg.HideCursor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+static void ReadDKeyEvent(int padnum, int key) {
+ SDL_Joystick *js;
+ time_t t;
+ GdkEvent *ge;
+ int i;
+ Sint16 axis, numAxes = 0, InitAxisPos[256], PrevAxisPos[256];
+ unsigned char buttons[32];
+ uint16_t Key;
+
+ if (g.cfg.PadDef[padnum].DevNum >= 0) {
+ js = SDL_JoystickOpen(g.cfg.PadDef[padnum].DevNum);
+ SDL_JoystickEventState(SDL_IGNORE);
+
+ SDL_JoystickUpdate();
+
+ numAxes = SDL_JoystickNumAxes(js);
+ if (numAxes > 256) numAxes = 256;
+
+ for (i = 0; i < numAxes; i++) {
+ InitAxisPos[i] = PrevAxisPos[i] = SDL_JoystickGetAxis(js, i);
+ }
+ } else {
+ js = NULL;
+ }
+
+ t = time(NULL);
+
+ while (time(NULL) < t + 10) {
+ // check joystick events
+ if (js != NULL) {
+ SDL_JoystickUpdate();
+
+ for (i = 0; i < SDL_JoystickNumButtons(js); i++) {
+ if (SDL_JoystickGetButton(js, i)) {
+ g.cfg.PadDef[padnum].KeyDef[key].JoyEvType = BUTTON;
+ g.cfg.PadDef[padnum].KeyDef[key].J.Button = i;
+ goto end;
+ }
+ }
+
+ for (i = 0; i < numAxes; i++) {
+ axis = SDL_JoystickGetAxis(js, i);
+ if (abs(axis) > 16383 && (abs(axis - InitAxisPos[i]) > 4096 || abs(axis - PrevAxisPos[i]) > 4096)) {
+ g.cfg.PadDef[padnum].KeyDef[key].JoyEvType = AXIS;
+ g.cfg.PadDef[padnum].KeyDef[key].J.Axis = (i + 1) * (axis > 0 ? 1 : -1);
+ goto end;
+ }
+ PrevAxisPos[i] = axis;
+ }
+
+ for (i = 0; i < SDL_JoystickNumHats(js); i++) {
+ axis = SDL_JoystickGetHat(js, i);
+ if (axis != SDL_HAT_CENTERED) {
+ g.cfg.PadDef[padnum].KeyDef[key].JoyEvType = HAT;
+
+ if (axis & SDL_HAT_UP) {
+ g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_UP);
+ } else if (axis & SDL_HAT_DOWN) {
+ g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_DOWN);
+ } else if (axis & SDL_HAT_LEFT) {
+ g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_LEFT);
+ } else if (axis & SDL_HAT_RIGHT) {
+ g.cfg.PadDef[padnum].KeyDef[key].J.Hat = ((i << 8) | SDL_HAT_RIGHT);
+ }
+
+ goto end;
+ }
+ }
+ }
+
+ // check keyboard events
+ XQueryKeymap(g.Disp, buttons);
+ for (i = 0; i < 256; ++i) {
+ if(buttons[i >> 3] & (1 << (i & 7))) {
+ Key = XkbKeycodeToKeysym(g.Disp, i, 0, 0);
+ if(Key != XK_Escape) {
+ g.cfg.PadDef[padnum].KeyDef[key].Key = Key;
+ }
+ goto end;
+ }
+ }
+
+ usleep(5000);
+ }
+
+end:
+ if (js != NULL) {
+ SDL_JoystickClose(js);
+ }
+}
+
+static void ReadAnalogEvent(int padnum, int analognum, int analogdir) {
+ SDL_Joystick *js;
+ time_t t;
+ GdkEvent *ge;
+ int i;
+ Sint16 axis, numAxes = 0, InitAxisPos[256], PrevAxisPos[256];
+ unsigned char buttons[32];
+ uint16_t Key;
+
+ if (g.cfg.PadDef[padnum].DevNum >= 0) {
+ js = SDL_JoystickOpen(g.cfg.PadDef[padnum].DevNum);
+ SDL_JoystickEventState(SDL_IGNORE);
+
+ SDL_JoystickUpdate();
+
+ numAxes = SDL_JoystickNumAxes(js);
+ if (numAxes > 256) numAxes = 256;
+
+ for (i = 0; i < SDL_JoystickNumAxes(js); i++) {
+ InitAxisPos[i] = PrevAxisPos[i] = SDL_JoystickGetAxis(js, i);
+ }
+ } else {
+ js = NULL;
+ }
+
+ t = time(NULL);
+
+ while (time(NULL) < t + 10) {
+ // check joystick events
+ if (js != NULL) {
+ SDL_JoystickUpdate();
+
+ for (i = 0; i < SDL_JoystickNumButtons(js); i++) {
+ if (SDL_JoystickGetButton(js, i)) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].JoyEvType = BUTTON;
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Button = i;
+ goto end;
+ }
+ }
+
+ for (i = 0; i < numAxes; i++) {
+ axis = SDL_JoystickGetAxis(js, i);
+ if (abs(axis) > 16383 && (abs(axis - InitAxisPos[i]) > 4096 || abs(axis - PrevAxisPos[i]) > 4096)) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].JoyEvType = AXIS;
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Axis = (i + 1) * (axis > 0 ? 1 : -1);
+ goto end;
+ }
+ PrevAxisPos[i] = axis;
+ }
+
+ for (i = 0; i < SDL_JoystickNumHats(js); i++) {
+ axis = SDL_JoystickGetHat(js, i);
+ if (axis != SDL_HAT_CENTERED) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].JoyEvType = HAT;
+
+ if (axis & SDL_HAT_UP) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_UP);
+ } else if (axis & SDL_HAT_DOWN) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_DOWN);
+ } else if (axis & SDL_HAT_LEFT) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_LEFT);
+ } else if (axis & SDL_HAT_RIGHT) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].J.Hat = ((i << 8) | SDL_HAT_RIGHT);
+ }
+
+ goto end;
+ }
+ }
+ }
+
+ // check keyboard events
+ XQueryKeymap(g.Disp, buttons);
+ for (i = 0; i < 256; ++i) {
+ if(buttons[i >> 3] & (1 << (i & 7))) {
+ Key = XkbKeycodeToKeysym(g.Disp, i, 0, 0);
+ if(Key != XK_Escape) {
+ g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].Key = Key;
+ }
+ goto end;
+ }
+ }
+
+ usleep(5000);
+ }
+
+end:
+ if (js != NULL) {
+ SDL_JoystickClose(js);
+ }
+}
+
+static void OnChangeClicked(GtkWidget *widget, gpointer user_data) {
+ int pad = (int)user_data;
+ int index = GetSelectedKeyIndex(pad);
+
+ if (index == -1) return;
+
+ if (index < DKEY_TOTAL) {
+ ReadDKeyEvent(pad, DPad[index]);
+ } else {
+ index -= DKEY_TOTAL;
+ ReadAnalogEvent(pad, index / 4, index % 4);
+ }
+
+ UpdateKey();
+}
+
+static void OnResetClicked(GtkWidget *widget, gpointer user_data) {
+ int pad = (int)user_data;
+ int index = GetSelectedKeyIndex(pad);
+
+ if (index == -1) return;
+
+ if (index < DKEY_TOTAL) {
+ g.cfg.PadDef[pad].KeyDef[DPad[index]].Key = 0;
+ g.cfg.PadDef[pad].KeyDef[DPad[index]].JoyEvType = NONE;
+ g.cfg.PadDef[pad].KeyDef[DPad[index]].J.Button = 0;
+ } else {
+ index -= DKEY_TOTAL;
+ g.cfg.PadDef[pad].AnalogDef[index / 4][index % 4].Key = 0;
+ g.cfg.PadDef[pad].AnalogDef[index / 4][index % 4].JoyEvType = NONE;
+ g.cfg.PadDef[pad].AnalogDef[index / 4][index % 4].J.Button = 0;
+ }
+
+ UpdateKey();
+}
+
+static void PopulateDevList() {
+ const char *widgetname[2] = {"combodev1", "combodev2"};
+ int i, j, n;
+ GtkWidget *widget;
+ GtkTreeIter iter;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ char buf[256];
+
+ for (i = 0; i < 2; i++) {
+ widget = gtk_builder_get_object(xml, widgetname[i]);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, FALSE);
+ gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0);
+
+ store = gtk_list_store_new(1, G_TYPE_STRING);
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, _("None"), -1);
+
+ n = SDL_NumJoysticks();
+ for (j = 0; j < n; j++) {
+ sprintf(buf, "%d: %s", j + 1, SDL_JoystickName(j));
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, buf, -1);
+ }
+
+ gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(store));
+
+ n = g.cfg.PadDef[i].DevNum + 1;
+ if (n > SDL_NumJoysticks()) {
+ n = 0;
+ g.cfg.PadDef[i].DevNum = -1;
+ }
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(widget), n);
+ }
+}
+
+long PADconfigure() {
+ GtkWidget *widget;
+ GtkTreeSelection *treesel;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ if (SDL_Init(SDL_INIT_JOYSTICK) == -1) {
+ fprintf(stderr, "Failed to initialize SDL!\n");
+ return -1;
+ }
+
+ g.Disp = XOpenDisplay(NULL);
+ if (!g.Disp) {
+ fprintf(stderr, "XOpenDisplay failed!\n");
+ return -1;
+ }
+
+ LoadPADConfig();
+
+ xml = gtk_builder_new();
+
+ if (!gtk_builder_add_from_file(xml, DATADIR "dfinput.ui", NULL)) {
+ g_warning("We could not load the interface!");
+ return -1;
+ }
+
+ MainWindow = gtk_builder_get_object(xml, "CfgWnd");
+ gtk_window_set_title(GTK_WINDOW(MainWindow), _("Gamepad/Keyboard Input Configuration"));
+
+ widget = gtk_builder_get_object(xml, "treeview1");
+
+ // column for key
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Key"),
+ renderer, "text", 0, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
+
+ // column for button
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Button"),
+ renderer, "text", 1, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
+
+ treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+ gtk_tree_selection_set_mode(treesel, GTK_SELECTION_SINGLE);
+
+ g_signal_connect_data(G_OBJECT(treesel), "changed",
+ G_CALLBACK(TreeSelectionChanged), (gpointer)0, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "treeview2");
+
+ // column for key
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Key"),
+ renderer, "text", 0, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
+
+ // column for button
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Button"),
+ renderer, "text", 1, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
+
+ treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+ gtk_tree_selection_set_mode(treesel, GTK_SELECTION_SINGLE);
+
+ g_signal_connect_data(G_OBJECT(treesel), "changed",
+ G_CALLBACK(TreeSelectionChanged), (gpointer)1, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "CfgWnd");
+ g_signal_connect_data(GTK_OBJECT(widget), "delete_event",
+ G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "btnclose");
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER);
+
+ PopulateDevList();
+ UpdateKeyList();
+
+ widget = gtk_builder_get_object(xml, "checkmt");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.Threaded);
+ g_signal_connect_data(GTK_OBJECT(widget), "toggled",
+ G_CALLBACK(OnThreadedToggled), NULL, NULL, G_CONNECT_AFTER);
+
+/*
+ widget = gtk_builder_get_object(xml, "checkcg");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.HideCursor);
+ g_signal_connect_data(GTK_OBJECT(widget), "toggled",
+ G_CALLBACK(OnHideCursorToggled), NULL, NULL, G_CONNECT_AFTER);
+*/
+ widget = gtk_builder_get_object(xml, "combodev1");
+ g_signal_connect_data(GTK_OBJECT(widget), "changed",
+ G_CALLBACK(OnDeviceChanged), (gpointer)0, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "combodev2");
+ g_signal_connect_data(GTK_OBJECT(widget), "changed",
+ G_CALLBACK(OnDeviceChanged), (gpointer)1, NULL, G_CONNECT_AFTER);
+
+ int padTypeList[] = {
+ 0,
+ 2, // PSE_PAD_TYPE_MOUSE
+ 0, // PSE_PAD_TYPE_NEGCON
+ 0, // PSE_PAD_TYPE_GUN
+ 0, // PSE_PAD_TYPE_STANDARD
+ 1, // PSE_PAD_TYPE_ANALOGJOY
+ 0, // PSE_PAD_TYPE_GUNCON
+ 1, //PSE_PAD_TYPE_ANALOGPAD
+ };
+
+ widget = gtk_builder_get_object(xml, "combotype1");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
+ padTypeList[g.cfg.PadDef[0].Type]);
+ g_signal_connect_data(GTK_OBJECT(widget), "changed",
+ G_CALLBACK(OnTypeChanged), (gpointer)0, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "combotype2");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
+ padTypeList[g.cfg.PadDef[1].Type]);
+ g_signal_connect_data(GTK_OBJECT(widget), "changed",
+ G_CALLBACK(OnTypeChanged), (gpointer)1, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "checkvv1");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.PadDef[0].VisualVibration);
+ g_signal_connect_data(GTK_OBJECT(widget), "toggled",
+ G_CALLBACK(OnVisualVibration1Toggled), NULL, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "checkvv2");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), g.cfg.PadDef[1].VisualVibration);
+ g_signal_connect_data(GTK_OBJECT(widget), "toggled",
+ G_CALLBACK(OnVisualVibration2Toggled), NULL, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "btnchange1");
+ gtk_widget_set_sensitive(widget, FALSE);
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ G_CALLBACK(OnChangeClicked), (gpointer)0, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "btnreset1");
+ gtk_widget_set_sensitive(widget, FALSE);
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ G_CALLBACK(OnResetClicked), (gpointer)0, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "btnchange2");
+ gtk_widget_set_sensitive(widget, FALSE);
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ G_CALLBACK(OnChangeClicked), (gpointer)1, NULL, G_CONNECT_AFTER);
+
+ widget = gtk_builder_get_object(xml, "btnreset2");
+ gtk_widget_set_sensitive(widget, FALSE);
+ g_signal_connect_data(GTK_OBJECT(widget), "clicked",
+ G_CALLBACK(OnResetClicked), (gpointer)1, NULL, G_CONNECT_AFTER);
+
+ gtk_widget_show(MainWindow);
+ gtk_main();
+
+ return 0;
+}
+
+void PADabout() {
+ const char *authors[]= {"Wei Mingzhi <weimingzhi@gmail.com>", NULL};
+ GtkWidget *widget;
+
+ widget = gtk_about_dialog_new();
+ gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(widget), "Gamepad/Keyboard Input");
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.1");
+ gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors);
+ gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://www.codeplex.com/pcsxr/");
+
+ gtk_dialog_run(GTK_DIALOG(widget));
+ gtk_widget_destroy(widget);
+}
+
+int main(int argc, char *argv[]) {
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ textdomain(GETTEXT_PACKAGE);
+#endif
+
+ gtk_set_locale();
+ gtk_init(&argc, &argv);
+
+ if (argc > 1 && !strcmp(argv[1], "-about")) {
+ PADabout();
+ } else {
+ PADconfigure();
+ }
+
+ gtk_exit(0);
+ return 0;
+}
diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c
index ea07b554..e4dc52b0 100644..100755
--- a/plugins/dfinput/pad.c
+++ b/plugins/dfinput/pad.c
@@ -1,687 +1,687 @@
-/*
- * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses>.
- */
-
-#include "pad.h"
-#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
-#include <linux/input.h>
-#include <sys/file.h>
-#include <time.h>
-#endif
-
-#if SDL_VERSION_ATLEAST(1,3,0)
-int has_haptic;
-#endif
-
-static void (*gpuVisualVibration)(uint32_t, uint32_t) = NULL;
-
-char *PSEgetLibName(void) {
- return _("Gamepad/Keyboard/Mouse Input");
-}
-
-uint32_t PSEgetLibType(void) {
- return PSE_LT_PAD;
-}
-
-uint32_t PSEgetLibVersion(void) {
- return (1 << 16) | (2 << 8);
-}
-
-static int padDataLenght[] = {0, 2, 3, 1, 1, 3, 3, 3};
-void PADsetMode(const int pad, const int mode) {
- g.PadState[pad].PadMode = mode;
-
- if (g.cfg.PadDef[pad].Type == PSE_PAD_TYPE_ANALOGPAD) {
- g.PadState[pad].PadID = mode ? 0x73 : 0x41;
- }
- else {
- g.PadState[pad].PadID = (g.cfg.PadDef[pad].Type << 4) |
- padDataLenght[g.cfg.PadDef[pad].Type];
- }
-
- g.PadState[pad].Vib0 = 0;
- g.PadState[pad].Vib1 = 0;
- g.PadState[pad].VibF[0] = 0;
- g.PadState[pad].VibF[1] = 0;
-}
-
-long PADinit(long flags) {
- LoadPADConfig();
-
- PADsetMode(0, 0);
- PADsetMode(1, 0);
-
- gpuVisualVibration = NULL;
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-long PADshutdown(void) {
- PADclose();
- return PSE_PAD_ERR_SUCCESS;
-}
-
-static pthread_t ThreadID;
-static volatile uint8_t TerminateThread = 0;
-
-static void *JoyThread(void *param) {
- while (!TerminateThread) {
- CheckJoy();
- usleep(1000);
- }
- pthread_exit(0);
- return NULL;
-}
-
-long PADopen(unsigned long *Disp) {
- g.Disp = (Display *)*Disp;
-
- if (!g.Opened) {
- if (SDL_WasInit(SDL_INIT_EVERYTHING)) {
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
- return PSE_PAD_ERR_FAILURE;
- }
- } else if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE) == -1) {
- return PSE_PAD_ERR_FAILURE;
- }
-
-#if SDL_VERSION_ATLEAST(1,3,0)
- has_haptic = 0;
- if (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0)
- has_haptic = 1;
-#endif
-
- InitSDLJoy();
- InitKeyboard();
-
- g.KeyLeftOver = 0;
-
- if (g.cfg.Threaded) {
- TerminateThread = 0;
-
- if (pthread_create(&ThreadID, NULL, JoyThread, NULL) != 0) {
- // thread creation failed, fallback to polling
- g.cfg.Threaded = 0;
- }
- }
- }
-
- g.Opened = 1;
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-long PADclose(void) {
- if (g.Opened) {
- if (g.cfg.Threaded) {
- TerminateThread = 1;
- pthread_join(ThreadID, NULL);
- }
-
- DestroySDLJoy();
- DestroyKeyboard();
-
- if (SDL_WasInit(SDL_INIT_EVERYTHING & ~SDL_INIT_JOYSTICK)) {
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- } else {
- SDL_Quit();
- }
- }
-
- g.Opened = 0;
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-long PADquery(void) {
- return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2;
-}
-
-static void UpdateInput(void) {
- int pad;
- if (!g.cfg.Threaded) CheckJoy();
- for(pad = 0; pad < 2; pad++) {
- if(g.PadState[pad].PadModeSwitch) {
- g.PadState[pad].PadModeSwitch = 0;
- PADsetMode(pad, 1 - g.PadState[pad].PadMode);
- }
- }
- CheckKeyboard();
-}
-
-static uint8_t stdpar[2][8] = {
- {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80},
- {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}
-};
-
-static uint8_t unk46[2][8] = {
- {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A},
- {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}
-};
-
-static uint8_t unk47[2][8] = {
- {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00},
- {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}
-};
-
-static uint8_t unk4c[2][8] = {
- {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-
-static uint8_t unk4d[2][8] = {
- {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
-};
-
-static uint8_t stdcfg[2][8] = {
- {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-
-static uint8_t stdmode[2][8] = {
- {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-};
-
-static uint8_t stdmodel[2][8] = {
- {0xFF,
- 0x5A,
- 0x01, // 03 - dualshock2, 01 - dualshock
- 0x02, // number of modes
- 0x01, // current mode: 01 - analog, 00 - digital
- 0x02,
- 0x01,
- 0x00},
- {0xFF,
- 0x5A,
- 0x01, // 03 - dualshock2, 01 - dualshock
- 0x02, // number of modes
- 0x01, // current mode: 01 - analog, 00 - digital
- 0x02,
- 0x01,
- 0x00}
-};
-
-#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
-/* lifted from SDL; but it's GPL as well */
-/* added ffbit, though */
-#define test_bit(nr, addr) \
- (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
-#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
-static int EV_IsJoystick(int fd)
-{
- unsigned long evbit[NBITS(EV_MAX)] = { 0 };
- unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
- unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
- unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
-
- if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
- (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
- (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) {
- return(0);
- }
- if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
- test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&
- (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0;
- if ( (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) < 0) ||
- !test_bit(FF_RUMBLE, ffbit) )
- return(1);
- return(2);
-}
-
-static void linux_set_vibrate(int pad)
-{
- int jno = 0, devno, dev;
- const char *sdlj;
- int tjno = g.cfg.PadDef[pad].DevNum;
-
- g.PadState[pad].VibrateDev = -2;
- /* simulate SDL device opening; probably not very accurate */
- /* works for me, though */
- sdlj = getenv("SDL_JOYSTICK_DEVICE");
- if(sdlj) {
- dev = open(sdlj, O_RDONLY);
- if(dev >= 0) {
- if(!tjno) {
- close(dev);
- dev = open(sdlj, O_RDWR);
- if(dev < 0) {
- printf("%s has no permission to rumble\n", sdlj);
- return;
- }
- if(EV_IsJoystick(dev) != 2) {
- printf("%s has no rumble\n", sdlj);
- close(dev);
- return;
- }
- g.PadState[pad].VibrateDev = dev;
- return;
- }
- close(dev);
- jno++;
- } else
- perror(sdlj);
- }
- for(devno = 0; devno < 32; devno++) {
- char buf[20];
-
- sprintf(buf, "/dev/input/event%d", devno);
- dev = open(buf, O_RDONLY);
- if(dev >= 0) {
- int isj = EV_IsJoystick(dev);
- if(isj) {
- if(tjno == jno) {
- close(dev);
- if(isj != 2) {
- printf("%s has no rumble\n", buf);
- return;
- }
- dev = open(buf, O_RDWR);
- if(dev < 0) {
- printf("%s has no permission to rumble\n", buf);
- return;
- }
- g.PadState[pad].VibrateDev = dev;
- return;
- }
- jno++;
- }
- close(dev);
- }
- }
-}
-
-static int linux_vibrate(PADSTATE *pad)
-{
- struct ff_effect ffe = { 0 };
- struct input_event ev = { { 0 } };
- struct timespec t;
- uint32_t stime;
-
- if(pad->VibrateDev < 0)
- return 0;
- ev.type = EV_FF;
- if(!pad->VibF[0] && !pad->VibF[1] && pad->VibrateEffect < 0) {
- return 1;
- }
- clock_gettime(CLOCK_REALTIME, &t);
- stime = (uint32_t)(t.tv_sec * 1000 + t.tv_nsec / 1000000);
- if(pad->VibrateEffect >= 0 &&
- pad->VibrLow == pad->VibF[0] && pad->VibrHigh == pad->VibF[1]) {
- if(stime - pad->VibrSetTime < 300)
- return 1;
- }
- if(pad->VibrateEffect < 0 || pad->VibrLow != pad->VibF[0] ||
- pad->VibrHigh != pad->VibF[1]) {
- if(pad->VibrateEffect >= 0) {
- ev.code = pad->VibrateEffect;
- ev.value = 0;
- if(write(pad->VibrateDev, &ev, sizeof(ev)) < 0)
- perror("ev write");
- }
- ffe.type = FF_RUMBLE;
- ffe.id = pad->VibrateEffect;
- /* DG says refresh 1/vsync = 166, but add for delays/etc. */
- ffe.replay.length = 500;
- ffe.replay.delay = 0;
- ffe.u.rumble.strong_magnitude = pad->VibF[1] * 256;
- ffe.u.rumble.weak_magnitude = pad->VibF[0] * 256;
- pad->VibrLow = pad->VibF[0];
- pad->VibrHigh = pad->VibF[1];
- if(ioctl(pad->VibrateDev, EVIOCSFF,&ffe) < 0) {
- perror("SFF ioctl");
- close(pad->VibrateDev);
- pad->VibrateDev = -2;
- return 0;
- }
- }
- pad->VibrSetTime = stime;
- ev.code = pad->VibrateEffect = ffe.id;
- ev.value = 1;
- if(write(pad->VibrateDev, &ev, sizeof(ev)) != sizeof(ev)) {
- close(pad->VibrateDev);
- pad->VibrateDev = -2;
- perror("ev write");
- return 0;
- }
- return 1;
-}
-#endif
-
-static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0;
-
-unsigned char PADstartPoll(int pad) {
- CurPad = pad - 1;
- CurByte = 0;
-
- return 0xFF;
-}
-
-unsigned char PADpoll(unsigned char value) {
- static uint8_t *buf = NULL;
- uint16_t n;
-
- if (CurByte == 0) {
- CurByte++;
-
- // Don't enable Analog/Vibration for a standard pad
- if (g.cfg.PadDef[CurPad].Type != PSE_PAD_TYPE_ANALOGPAD) {
- CurCmd = CMD_READ_DATA_AND_VIBRATE;
- } else {
- CurCmd = value;
- }
-
- switch (CurCmd) {
- case CMD_CONFIG_MODE:
- CmdLen = 8;
- buf = stdcfg[CurPad];
- if (stdcfg[CurPad][3] == 0xFF) return 0xF3;
- else return g.PadState[CurPad].PadID;
-
- case CMD_SET_MODE_AND_LOCK:
- CmdLen = 8;
- buf = stdmode[CurPad];
- return 0xF3;
-
- case CMD_QUERY_MODEL_AND_MODE:
- CmdLen = 8;
- buf = stdmodel[CurPad];
- buf[4] = g.PadState[CurPad].PadMode;
- return 0xF3;
-
- case CMD_QUERY_ACT:
- CmdLen = 8;
- buf = unk46[CurPad];
- return 0xF3;
-
- case CMD_QUERY_COMB:
- CmdLen = 8;
- buf = unk47[CurPad];
- return 0xF3;
-
- case CMD_QUERY_MODE:
- CmdLen = 8;
- buf = unk4c[CurPad];
- return 0xF3;
-
- case CMD_VIBRATION_TOGGLE:
- CmdLen = 8;
- buf = unk4d[CurPad];
- return 0xF3;
-
- case CMD_READ_DATA_AND_VIBRATE:
- default:
- n = g.PadState[CurPad].KeyStatus;
- n &= g.PadState[CurPad].JoyKeyStatus;
-
- stdpar[CurPad][2] = n & 0xFF;
- stdpar[CurPad][3] = n >> 8;
-
- if (g.PadState[CurPad].PadMode == 1) {
- CmdLen = 8;
-
- stdpar[CurPad][4] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][0];
- stdpar[CurPad][5] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][1];
- stdpar[CurPad][6] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][0];
- stdpar[CurPad][7] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][1];
- }
- else if(g.PadState[CurPad].PadID == 0x12)
- {
- CmdLen = 6;
-
- stdpar[CurPad][4] = g.PadState[0].MouseAxis[0][0];
- stdpar[CurPad][5] = g.PadState[0].MouseAxis[0][1];
- }
- else {
- CmdLen = 4;
- }
-
- buf = stdpar[CurPad];
- return g.PadState[CurPad].PadID;
- }
- }
-
- //makes it so that the following switch doesn't try to dereference a null pointer
- //quiets a warning in the Clang static analyzer.
- if (buf == NULL) {
- return 0;
- }
-
- switch (CurCmd) {
- case CMD_READ_DATA_AND_VIBRATE:
- if (g.cfg.PadDef[CurPad].Type == PSE_PAD_TYPE_ANALOGPAD) {
- if (CurByte == g.PadState[CurPad].Vib0) {
- g.PadState[CurPad].VibF[0] = value;
-
- if (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0) {
-#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
- if (g.PadState[CurPad].VibrateDev == -1 &&
- g.PadState[CurPad].JoyDev != NULL) {
- linux_set_vibrate(CurPad);
- }
- if (!linux_vibrate(&g.PadState[CurPad]))
- /* only do visual if joy fails */
-#endif
- if (!JoyHapticRumble(CurPad, g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1])) {
- //gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
- }
-
- if(gpuVisualVibration != NULL &&
- g.cfg.PadDef[CurPad].VisualVibration) {
- gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
- }
- }
- }
-
- if (CurByte == g.PadState[CurPad].Vib1) {
- g.PadState[CurPad].VibF[1] = value;
-
- if (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0) {
-#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
- if (g.PadState[CurPad].VibrateDev == -1 &&
- g.PadState[CurPad].JoyDev != NULL) {
- linux_set_vibrate(CurPad);
- }
- if (!linux_vibrate(&g.PadState[CurPad]))
- /* only do visual if joy fails */
-#endif
- if (!JoyHapticRumble(CurPad, g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1])) {
- //gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
- }
-
- if(gpuVisualVibration != NULL &&
- g.cfg.PadDef[CurPad].VisualVibration) {
- gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
- }
- }
- }
- }
- break;
-
- case CMD_CONFIG_MODE:
- if (CurByte == 2) {
- switch (value) {
- case 0:
- buf[2] = 0;
- buf[3] = 0;
- break;
-
- case 1:
- buf[2] = 0xFF;
- buf[3] = 0xFF;
- break;
- }
- }
- break;
-
- case CMD_SET_MODE_AND_LOCK:
- if (CurByte == 2) {
- PADsetMode(CurPad, value);
- }
- break;
-
- case CMD_QUERY_ACT:
- if (CurByte == 2) {
- switch (value) {
- case 0: // default
- buf[5] = 0x02;
- buf[6] = 0x00;
- buf[7] = 0x0A;
- break;
-
- case 1: // Param std conf change
- buf[5] = 0x01;
- buf[6] = 0x01;
- buf[7] = 0x14;
- break;
- }
- }
- break;
-
- case CMD_QUERY_MODE:
- if (CurByte == 2) {
- switch (value) {
- case 0: // mode 0 - digital mode
- buf[5] = PSE_PAD_TYPE_STANDARD;
- break;
-
- case 1: // mode 1 - analog mode
- buf[5] = PSE_PAD_TYPE_ANALOGPAD;
- break;
- }
- }
- break;
-
- case CMD_VIBRATION_TOGGLE:
- if (CurByte >= 2 && CurByte < CmdLen) {
- if (CurByte == g.PadState[CurPad].Vib0) {
- buf[CurByte] = 0;
- }
- if (CurByte == g.PadState[CurPad].Vib1) {
- buf[CurByte] = 1;
- }
-
- if (value == 0) {
- g.PadState[CurPad].Vib0 = CurByte;
- if ((g.PadState[CurPad].PadID & 0x0f) < (CurByte - 1) / 2) {
- g.PadState[CurPad].PadID = (g.PadState[CurPad].PadID & 0xf0) + (CurByte - 1) / 2;
- }
- } else if (value == 1) {
- g.PadState[CurPad].Vib1 = CurByte;
- if ((g.PadState[CurPad].PadID & 0x0f) < (CurByte - 1) / 2) {
- g.PadState[CurPad].PadID = (g.PadState[CurPad].PadID & 0xf0) + (CurByte - 1) / 2;
- }
- }
- }
- break;
- }
-
- if (CurByte >= CmdLen) return 0;
- if (buf == NULL) return 0;
- return buf[CurByte++];
-}
-
-static long PADreadPort(int num, PadDataS *pad) {
- UpdateInput();
-
- pad->buttonStatus = (g.PadState[num].KeyStatus & g.PadState[num].JoyKeyStatus);
-
- // ePSXe different from pcsxr, swap bytes
- pad->buttonStatus = (pad->buttonStatus >> 8) | (pad->buttonStatus << 8);
-
- switch (g.cfg.PadDef[num].Type) {
- case PSE_PAD_TYPE_ANALOGPAD: // Analog Controller SCPH-1150
- pad->controllerType = PSE_PAD_TYPE_ANALOGPAD;
- pad->rightJoyX = g.PadState[num].AnalogStatus[ANALOG_RIGHT][0];
- pad->rightJoyY = g.PadState[num].AnalogStatus[ANALOG_RIGHT][1];
- pad->leftJoyX = g.PadState[num].AnalogStatus[ANALOG_LEFT][0];
- pad->leftJoyY = g.PadState[num].AnalogStatus[ANALOG_LEFT][1];
- break;
-
- case PSE_PAD_TYPE_STANDARD: // Standard Pad SCPH-1080, SCPH-1150
- default:
- pad->controllerType = PSE_PAD_TYPE_STANDARD;
- break;
- }
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-long PADreadPort1(PadDataS *pad) {
- return PADreadPort(0, pad);
-}
-
-long PADreadPort2(PadDataS *pad) {
- return PADreadPort(1, pad);
-}
-
-long PADkeypressed(void) {
- long s;
-
- static int frame = 0;
- if( !frame )
- UpdateInput();
- frame ^= 1;
-
- s = g.KeyLeftOver;
- g.KeyLeftOver = 0;
-
- return s;
-}
-
-void PADregisterVibration(void (*callback)(uint32_t, uint32_t)) {
- gpuVisualVibration = callback;
-}
-
-#ifndef _MACOSX
-
-long PADconfigure(void) {
- int pid = fork();
-
- if (pid == 0) {
- if (fork() == 0) {
- execl("cfg/cfgDFInput", "cfgDFInput", NULL);
- }
- exit(0);
- } else if (pid > 0) {
- waitpid(pid, NULL, 0);
- }
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-void PADabout(void) {
- int pid = fork();
-
- if (pid == 0) {
- if (fork() == 0) {
- execl("cfg/cfgDFInput", "cfgDFInput", "-about", NULL);
- }
- exit(0);
- } else if (pid > 0) {
- waitpid(pid, NULL, 0);
- }
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-#endif
-
-long PADtest(void) {
- return PSE_PAD_ERR_SUCCESS;
-}
+/*
+ * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include "pad.h"
+#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
+#include <linux/input.h>
+#include <sys/file.h>
+#include <time.h>
+#endif
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+int has_haptic;
+#endif
+
+static void (*gpuVisualVibration)(uint32_t, uint32_t) = NULL;
+
+char *PSEgetLibName(void) {
+ return _("Gamepad/Keyboard/Mouse Input");
+}
+
+uint32_t PSEgetLibType(void) {
+ return PSE_LT_PAD;
+}
+
+uint32_t PSEgetLibVersion(void) {
+ return (1 << 16) | (2 << 8);
+}
+
+static int padDataLenght[] = {0, 2, 3, 1, 1, 3, 3, 3};
+void PADsetMode(const int pad, const int mode) {
+ g.PadState[pad].PadMode = mode;
+
+ if (g.cfg.PadDef[pad].Type == PSE_PAD_TYPE_ANALOGPAD) {
+ g.PadState[pad].PadID = mode ? 0x73 : 0x41;
+ }
+ else {
+ g.PadState[pad].PadID = (g.cfg.PadDef[pad].Type << 4) |
+ padDataLenght[g.cfg.PadDef[pad].Type];
+ }
+
+ g.PadState[pad].Vib0 = 0;
+ g.PadState[pad].Vib1 = 0;
+ g.PadState[pad].VibF[0] = 0;
+ g.PadState[pad].VibF[1] = 0;
+}
+
+long PADinit(long flags) {
+ LoadPADConfig();
+
+ PADsetMode(0, 0);
+ PADsetMode(1, 0);
+
+ gpuVisualVibration = NULL;
+
+ return PSE_PAD_ERR_SUCCESS;
+}
+
+long PADshutdown(void) {
+ PADclose();
+ return PSE_PAD_ERR_SUCCESS;
+}
+
+static pthread_t ThreadID;
+static volatile uint8_t TerminateThread = 0;
+
+static void *JoyThread(void *param) {
+ while (!TerminateThread) {
+ CheckJoy();
+ usleep(1000);
+ }
+ pthread_exit(0);
+ return NULL;
+}
+
+long PADopen(unsigned long *Disp) {
+ g.Disp = (Display *)*Disp;
+
+ if (!g.Opened) {
+ if (SDL_WasInit(SDL_INIT_EVERYTHING)) {
+ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) {
+ return PSE_PAD_ERR_FAILURE;
+ }
+ } else if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE) == -1) {
+ return PSE_PAD_ERR_FAILURE;
+ }
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+ has_haptic = 0;
+ if (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0)
+ has_haptic = 1;
+#endif
+
+ InitSDLJoy();
+ InitKeyboard();
+
+ g.KeyLeftOver = 0;
+
+ if (g.cfg.Threaded) {
+ TerminateThread = 0;
+
+ if (pthread_create(&ThreadID, NULL, JoyThread, NULL) != 0) {
+ // thread creation failed, fallback to polling
+ g.cfg.Threaded = 0;
+ }
+ }
+ }
+
+ g.Opened = 1;
+
+ return PSE_PAD_ERR_SUCCESS;
+}
+
+long PADclose(void) {
+ if (g.Opened) {
+ if (g.cfg.Threaded) {
+ TerminateThread = 1;
+ pthread_join(ThreadID, NULL);
+ }
+
+ DestroySDLJoy();
+ DestroyKeyboard();
+
+ if (SDL_WasInit(SDL_INIT_EVERYTHING & ~SDL_INIT_JOYSTICK)) {
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ } else {
+ SDL_Quit();
+ }
+ }
+
+ g.Opened = 0;
+
+ return PSE_PAD_ERR_SUCCESS;
+}
+
+long PADquery(void) {
+ return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2;
+}
+
+static void UpdateInput(void) {
+ int pad;
+ if (!g.cfg.Threaded) CheckJoy();
+ for(pad = 0; pad < 2; pad++) {
+ if(g.PadState[pad].PadModeSwitch) {
+ g.PadState[pad].PadModeSwitch = 0;
+ PADsetMode(pad, 1 - g.PadState[pad].PadMode);
+ }
+ }
+ CheckKeyboard();
+}
+
+static uint8_t stdpar[2][8] = {
+ {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80},
+ {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}
+};
+
+static uint8_t unk46[2][8] = {
+ {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A},
+ {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}
+};
+
+static uint8_t unk47[2][8] = {
+ {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00},
+ {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}
+};
+
+static uint8_t unk4c[2][8] = {
+ {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+
+static uint8_t unk4d[2][8] = {
+ {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
+};
+
+static uint8_t stdcfg[2][8] = {
+ {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+
+static uint8_t stdmode[2][8] = {
+ {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+
+static uint8_t stdmodel[2][8] = {
+ {0xFF,
+ 0x5A,
+ 0x01, // 03 - dualshock2, 01 - dualshock
+ 0x02, // number of modes
+ 0x01, // current mode: 01 - analog, 00 - digital
+ 0x02,
+ 0x01,
+ 0x00},
+ {0xFF,
+ 0x5A,
+ 0x01, // 03 - dualshock2, 01 - dualshock
+ 0x02, // number of modes
+ 0x01, // current mode: 01 - analog, 00 - digital
+ 0x02,
+ 0x01,
+ 0x00}
+};
+
+#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
+/* lifted from SDL; but it's GPL as well */
+/* added ffbit, though */
+#define test_bit(nr, addr) \
+ (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
+#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
+static int EV_IsJoystick(int fd)
+{
+ unsigned long evbit[NBITS(EV_MAX)] = { 0 };
+ unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
+ unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
+ unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
+
+ if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
+ (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
+ (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) ) {
+ return(0);
+ }
+ if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
+ test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) &&
+ (test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_A, keybit) || test_bit(BTN_1, keybit)))) return 0;
+ if ( (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) < 0) ||
+ !test_bit(FF_RUMBLE, ffbit) )
+ return(1);
+ return(2);
+}
+
+static void linux_set_vibrate(int pad)
+{
+ int jno = 0, devno, dev;
+ const char *sdlj;
+ int tjno = g.cfg.PadDef[pad].DevNum;
+
+ g.PadState[pad].VibrateDev = -2;
+ /* simulate SDL device opening; probably not very accurate */
+ /* works for me, though */
+ sdlj = getenv("SDL_JOYSTICK_DEVICE");
+ if(sdlj) {
+ dev = open(sdlj, O_RDONLY);
+ if(dev >= 0) {
+ if(!tjno) {
+ close(dev);
+ dev = open(sdlj, O_RDWR);
+ if(dev < 0) {
+ printf("%s has no permission to rumble\n", sdlj);
+ return;
+ }
+ if(EV_IsJoystick(dev) != 2) {
+ printf("%s has no rumble\n", sdlj);
+ close(dev);
+ return;
+ }
+ g.PadState[pad].VibrateDev = dev;
+ return;
+ }
+ close(dev);
+ jno++;
+ } else
+ perror(sdlj);
+ }
+ for(devno = 0; devno < 32; devno++) {
+ char buf[20];
+
+ sprintf(buf, "/dev/input/event%d", devno);
+ dev = open(buf, O_RDONLY);
+ if(dev >= 0) {
+ int isj = EV_IsJoystick(dev);
+ if(isj) {
+ if(tjno == jno) {
+ close(dev);
+ if(isj != 2) {
+ printf("%s has no rumble\n", buf);
+ return;
+ }
+ dev = open(buf, O_RDWR);
+ if(dev < 0) {
+ printf("%s has no permission to rumble\n", buf);
+ return;
+ }
+ g.PadState[pad].VibrateDev = dev;
+ return;
+ }
+ jno++;
+ }
+ close(dev);
+ }
+ }
+}
+
+static int linux_vibrate(PADSTATE *pad)
+{
+ struct ff_effect ffe = { 0 };
+ struct input_event ev = { { 0 } };
+ struct timespec t;
+ uint32_t stime;
+
+ if(pad->VibrateDev < 0)
+ return 0;
+ ev.type = EV_FF;
+ if(!pad->VibF[0] && !pad->VibF[1] && pad->VibrateEffect < 0) {
+ return 1;
+ }
+ clock_gettime(CLOCK_REALTIME, &t);
+ stime = (uint32_t)(t.tv_sec * 1000 + t.tv_nsec / 1000000);
+ if(pad->VibrateEffect >= 0 &&
+ pad->VibrLow == pad->VibF[0] && pad->VibrHigh == pad->VibF[1]) {
+ if(stime - pad->VibrSetTime < 300)
+ return 1;
+ }
+ if(pad->VibrateEffect < 0 || pad->VibrLow != pad->VibF[0] ||
+ pad->VibrHigh != pad->VibF[1]) {
+ if(pad->VibrateEffect >= 0) {
+ ev.code = pad->VibrateEffect;
+ ev.value = 0;
+ if(write(pad->VibrateDev, &ev, sizeof(ev)) < 0)
+ perror("ev write");
+ }
+ ffe.type = FF_RUMBLE;
+ ffe.id = pad->VibrateEffect;
+ /* DG says refresh 1/vsync = 166, but add for delays/etc. */
+ ffe.replay.length = 500;
+ ffe.replay.delay = 0;
+ ffe.u.rumble.strong_magnitude = pad->VibF[1] * 256;
+ ffe.u.rumble.weak_magnitude = pad->VibF[0] * 256;
+ pad->VibrLow = pad->VibF[0];
+ pad->VibrHigh = pad->VibF[1];
+ if(ioctl(pad->VibrateDev, EVIOCSFF,&ffe) < 0) {
+ perror("SFF ioctl");
+ close(pad->VibrateDev);
+ pad->VibrateDev = -2;
+ return 0;
+ }
+ }
+ pad->VibrSetTime = stime;
+ ev.code = pad->VibrateEffect = ffe.id;
+ ev.value = 1;
+ if(write(pad->VibrateDev, &ev, sizeof(ev)) != sizeof(ev)) {
+ close(pad->VibrateDev);
+ pad->VibrateDev = -2;
+ perror("ev write");
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0;
+
+unsigned char PADstartPoll(int pad) {
+ CurPad = pad - 1;
+ CurByte = 0;
+
+ return 0xFF;
+}
+
+unsigned char PADpoll(unsigned char value) {
+ static uint8_t *buf = NULL;
+ uint16_t n;
+
+ if (CurByte == 0) {
+ CurByte++;
+
+ // Don't enable Analog/Vibration for a standard pad
+ if (g.cfg.PadDef[CurPad].Type != PSE_PAD_TYPE_ANALOGPAD) {
+ CurCmd = CMD_READ_DATA_AND_VIBRATE;
+ } else {
+ CurCmd = value;
+ }
+
+ switch (CurCmd) {
+ case CMD_CONFIG_MODE:
+ CmdLen = 8;
+ buf = stdcfg[CurPad];
+ if (stdcfg[CurPad][3] == 0xFF) return 0xF3;
+ else return g.PadState[CurPad].PadID;
+
+ case CMD_SET_MODE_AND_LOCK:
+ CmdLen = 8;
+ buf = stdmode[CurPad];
+ return 0xF3;
+
+ case CMD_QUERY_MODEL_AND_MODE:
+ CmdLen = 8;
+ buf = stdmodel[CurPad];
+ buf[4] = g.PadState[CurPad].PadMode;
+ return 0xF3;
+
+ case CMD_QUERY_ACT:
+ CmdLen = 8;
+ buf = unk46[CurPad];
+ return 0xF3;
+
+ case CMD_QUERY_COMB:
+ CmdLen = 8;
+ buf = unk47[CurPad];
+ return 0xF3;
+
+ case CMD_QUERY_MODE:
+ CmdLen = 8;
+ buf = unk4c[CurPad];
+ return 0xF3;
+
+ case CMD_VIBRATION_TOGGLE:
+ CmdLen = 8;
+ buf = unk4d[CurPad];
+ return 0xF3;
+
+ case CMD_READ_DATA_AND_VIBRATE:
+ default:
+ n = g.PadState[CurPad].KeyStatus;
+ n &= g.PadState[CurPad].JoyKeyStatus;
+
+ stdpar[CurPad][2] = n & 0xFF;
+ stdpar[CurPad][3] = n >> 8;
+
+ if (g.PadState[CurPad].PadMode == 1) {
+ CmdLen = 8;
+
+ stdpar[CurPad][4] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][0];
+ stdpar[CurPad][5] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][1];
+ stdpar[CurPad][6] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][0];
+ stdpar[CurPad][7] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][1];
+ }
+ else if(g.PadState[CurPad].PadID == 0x12)
+ {
+ CmdLen = 6;
+
+ stdpar[CurPad][4] = g.PadState[0].MouseAxis[0][0];
+ stdpar[CurPad][5] = g.PadState[0].MouseAxis[0][1];
+ }
+ else {
+ CmdLen = 4;
+ }
+
+ buf = stdpar[CurPad];
+ return g.PadState[CurPad].PadID;
+ }
+ }
+
+ //makes it so that the following switch doesn't try to dereference a null pointer
+ //quiets a warning in the Clang static analyzer.
+ if (buf == NULL) {
+ return 0;
+ }
+
+ switch (CurCmd) {
+ case CMD_READ_DATA_AND_VIBRATE:
+ if (g.cfg.PadDef[CurPad].Type == PSE_PAD_TYPE_ANALOGPAD) {
+ if (CurByte == g.PadState[CurPad].Vib0) {
+ g.PadState[CurPad].VibF[0] = value;
+
+ if (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0) {
+#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
+ if (g.PadState[CurPad].VibrateDev == -1 &&
+ g.PadState[CurPad].JoyDev != NULL) {
+ linux_set_vibrate(CurPad);
+ }
+ if (!linux_vibrate(&g.PadState[CurPad]))
+ /* only do visual if joy fails */
+#endif
+ if (!JoyHapticRumble(CurPad, g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1])) {
+ //gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
+ }
+
+ if(gpuVisualVibration != NULL &&
+ g.cfg.PadDef[CurPad].VisualVibration) {
+ gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
+ }
+ }
+ }
+
+ if (CurByte == g.PadState[CurPad].Vib1) {
+ g.PadState[CurPad].VibF[1] = value;
+
+ if (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0) {
+#if !SDL_VERSION_ATLEAST(1,3,0) && defined(__linux__)
+ if (g.PadState[CurPad].VibrateDev == -1 &&
+ g.PadState[CurPad].JoyDev != NULL) {
+ linux_set_vibrate(CurPad);
+ }
+ if (!linux_vibrate(&g.PadState[CurPad]))
+ /* only do visual if joy fails */
+#endif
+ if (!JoyHapticRumble(CurPad, g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1])) {
+ //gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
+ }
+
+ if(gpuVisualVibration != NULL &&
+ g.cfg.PadDef[CurPad].VisualVibration) {
+ gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]);
+ }
+ }
+ }
+ }
+ break;
+
+ case CMD_CONFIG_MODE:
+ if (CurByte == 2) {
+ switch (value) {
+ case 0:
+ buf[2] = 0;
+ buf[3] = 0;
+ break;
+
+ case 1:
+ buf[2] = 0xFF;
+ buf[3] = 0xFF;
+ break;
+ }
+ }
+ break;
+
+ case CMD_SET_MODE_AND_LOCK:
+ if (CurByte == 2) {
+ PADsetMode(CurPad, value);
+ }
+ break;
+
+ case CMD_QUERY_ACT:
+ if (CurByte == 2) {
+ switch (value) {
+ case 0: // default
+ buf[5] = 0x02;
+ buf[6] = 0x00;
+ buf[7] = 0x0A;
+ break;
+
+ case 1: // Param std conf change
+ buf[5] = 0x01;
+ buf[6] = 0x01;
+ buf[7] = 0x14;
+ break;
+ }
+ }
+ break;
+
+ case CMD_QUERY_MODE:
+ if (CurByte == 2) {
+ switch (value) {
+ case 0: // mode 0 - digital mode
+ buf[5] = PSE_PAD_TYPE_STANDARD;
+ break;
+
+ case 1: // mode 1 - analog mode
+ buf[5] = PSE_PAD_TYPE_ANALOGPAD;
+ break;
+ }
+ }
+ break;
+
+ case CMD_VIBRATION_TOGGLE:
+ if (CurByte >= 2 && CurByte < CmdLen) {
+ if (CurByte == g.PadState[CurPad].Vib0) {
+ buf[CurByte] = 0;
+ }
+ if (CurByte == g.PadState[CurPad].Vib1) {
+ buf[CurByte] = 1;
+ }
+
+ if (value == 0) {
+ g.PadState[CurPad].Vib0 = CurByte;
+ if ((g.PadState[CurPad].PadID & 0x0f) < (CurByte - 1) / 2) {
+ g.PadState[CurPad].PadID = (g.PadState[CurPad].PadID & 0xf0) + (CurByte - 1) / 2;
+ }
+ } else if (value == 1) {
+ g.PadState[CurPad].Vib1 = CurByte;
+ if ((g.PadState[CurPad].PadID & 0x0f) < (CurByte - 1) / 2) {
+ g.PadState[CurPad].PadID = (g.PadState[CurPad].PadID & 0xf0) + (CurByte - 1) / 2;
+ }
+ }
+ }
+ break;
+ }
+
+ if (CurByte >= CmdLen) return 0;
+ if (buf == NULL) return 0;
+ return buf[CurByte++];
+}
+
+static long PADreadPort(int num, PadDataS *pad) {
+ UpdateInput();
+
+ pad->buttonStatus = (g.PadState[num].KeyStatus & g.PadState[num].JoyKeyStatus);
+
+ // ePSXe different from pcsxr, swap bytes
+ pad->buttonStatus = (pad->buttonStatus >> 8) | (pad->buttonStatus << 8);
+
+ switch (g.cfg.PadDef[num].Type) {
+ case PSE_PAD_TYPE_ANALOGPAD: // Analog Controller SCPH-1150
+ pad->controllerType = PSE_PAD_TYPE_ANALOGPAD;
+ pad->rightJoyX = g.PadState[num].AnalogStatus[ANALOG_RIGHT][0];
+ pad->rightJoyY = g.PadState[num].AnalogStatus[ANALOG_RIGHT][1];
+ pad->leftJoyX = g.PadState[num].AnalogStatus[ANALOG_LEFT][0];
+ pad->leftJoyY = g.PadState[num].AnalogStatus[ANALOG_LEFT][1];
+ break;
+
+ case PSE_PAD_TYPE_STANDARD: // Standard Pad SCPH-1080, SCPH-1150
+ default:
+ pad->controllerType = PSE_PAD_TYPE_STANDARD;
+ break;
+ }
+
+ return PSE_PAD_ERR_SUCCESS;
+}
+
+long PADreadPort1(PadDataS *pad) {
+ return PADreadPort(0, pad);
+}
+
+long PADreadPort2(PadDataS *pad) {
+ return PADreadPort(1, pad);
+}
+
+long PADkeypressed(void) {
+ long s;
+
+ static int frame = 0;
+ if( !frame )
+ UpdateInput();
+ frame ^= 1;
+
+ s = g.KeyLeftOver;
+ g.KeyLeftOver = 0;
+
+ return s;
+}
+
+void PADregisterVibration(void (*callback)(uint32_t, uint32_t)) {
+ gpuVisualVibration = callback;
+}
+
+#ifndef _MACOSX
+
+long PADconfigure(void) {
+ int pid = fork();
+
+ if (pid == 0) {
+ if (fork() == 0) {
+ execl("cfg/cfgDFInput", "cfgDFInput", NULL);
+ }
+ exit(0);
+ } else if (pid > 0) {
+ waitpid(pid, NULL, 0);
+ }
+
+ return PSE_PAD_ERR_SUCCESS;
+}
+
+void PADabout(void) {
+ int pid = fork();
+
+ if (pid == 0) {
+ if (fork() == 0) {
+ execl("cfg/cfgDFInput", "cfgDFInput", "-about", NULL);
+ }
+ exit(0);
+ } else if (pid > 0) {
+ waitpid(pid, NULL, 0);
+ }
+
+ return PSE_PAD_ERR_SUCCESS;
+}
+
+#endif
+
+long PADtest(void) {
+ return PSE_PAD_ERR_SUCCESS;
+}
diff --git a/plugins/dfinput/pad.h b/plugins/dfinput/pad.h
index 40fb50fa..5e66f9ae 100644..100755
--- a/plugins/dfinput/pad.h
+++ b/plugins/dfinput/pad.h
@@ -1,241 +1,241 @@
-/*
- * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses>.
- */
-
-#ifndef PAD_H_
-#define PAD_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _MACOSX
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <pthread.h>
-
-#include <SDL.h>
-#include <SDL_joystick.h>
-#if SDL_VERSION_ATLEAST(1,3,0)
-#include <SDL_haptic.h>
-#endif
-
-#ifdef _MACOSX
-#include <Carbon/Carbon.h>
-typedef void *Display;
-#define ThreadID ThreadID_MACOSX
-#else
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/keysym.h>
-#include <X11/XKBlib.h>
-#endif
-
-#include "psemu_plugin_defs.h"
-
-#ifdef ENABLE_NLS
-#include <libintl.h>
-#include <locale.h>
-#define _(x) gettext(x)
-#define N_(x) (x)
-//If running under Mac OS X, use the Localizable.strings file instead.
-#elif defined(_MACOSX)
-#ifdef PCSXRCORE
-extern const char* Pcsxr_locale_text(char* toloc);
-#define _(String) Pcsxr_locale_text(String)
-#define N_(String) String
-#else
-#ifndef PCSXRPLUG
-#warning please define the plug being built to use Mac OS X localization!
-#define _(msgid) msgid
-#define N_(msgid) msgid
-#else
-//Kludge to get the preprocessor to accept PCSXRPLUG as a variable.
-#define PLUGLOC_x(x,y) x ## y
-#define PLUGLOC_y(x,y) PLUGLOC_x(x,y)
-#define PLUGLOC PLUGLOC_y(PCSXRPLUG,_locale_text)
-extern const char* PLUGLOC(char* toloc);
-#define _(String) PLUGLOC(String)
-#define N_(String) String
-#endif
-#endif
-#else
-#define _(x) (x)
-#define N_(x) (x)
-#endif
-
-#if SDL_VERSION_ATLEAST(1,3,0)
-extern int has_haptic;
-#endif
-
-int JoyHapticRumble(int pad, uint32_t low, uint32_t high);
-
-enum {
- DKEY_SELECT = 0,
- DKEY_L3,
- DKEY_R3,
- DKEY_START,
- DKEY_UP,
- DKEY_RIGHT,
- DKEY_DOWN,
- DKEY_LEFT,
- DKEY_L2,
- DKEY_R2,
- DKEY_L1,
- DKEY_R1,
- DKEY_TRIANGLE,
- DKEY_CIRCLE,
- DKEY_CROSS,
- DKEY_SQUARE,
- DKEY_ANALOG,
-
- DKEY_TOTAL
-};
-
-enum {
- ANALOG_LEFT = 0,
- ANALOG_RIGHT,
-
- ANALOG_TOTAL
-};
-
-enum { NONE = 0, AXIS, HAT, BUTTON };
-
-typedef struct tagKeyDef {
- uint8_t JoyEvType;
- union {
- int16_t d;
- int16_t Axis; // positive=axis+, negative=axis-, abs(Axis)-1=axis index
- uint16_t Hat; // 8-bit for hat number, 8-bit for direction
- uint16_t Button; // button number
- } J;
- uint16_t Key;
-} KEYDEF;
-
-enum { ANALOG_XP = 0, ANALOG_XM, ANALOG_YP, ANALOG_YM };
-
-typedef struct tagPadDef {
- int8_t DevNum;
- uint16_t Type;
- uint8_t VisualVibration;
- KEYDEF KeyDef[DKEY_TOTAL];
- KEYDEF AnalogDef[ANALOG_TOTAL][4];
-} PADDEF;
-
-typedef struct tagConfig {
- uint8_t Threaded;
- uint8_t HideCursor;
- PADDEF PadDef[2];
-} CONFIG;
-
-typedef struct tagPadState {
- SDL_Joystick *JoyDev;
- uint8_t PadMode;
- uint8_t PadID;
- uint8_t PadModeKey;
- volatile uint8_t PadModeSwitch;
- volatile uint16_t KeyStatus;
- volatile uint16_t JoyKeyStatus;
- volatile uint8_t AnalogStatus[ANALOG_TOTAL][2]; // 0-255 where 127 is center position
- volatile uint8_t AnalogKeyStatus[ANALOG_TOTAL][4];
- volatile int8_t MouseAxis[2][2];
- uint8_t Vib0, Vib1;
- volatile uint8_t VibF[2];
-#if SDL_VERSION_ATLEAST(1,3,0)
- SDL_Haptic *haptic;
-#else
-#ifdef __linux__
- int VibrateDev;
- int VibrateEffect;
- uint8_t VibrLow, VibrHigh;
- uint32_t VibrSetTime;
-#endif
-#endif
-} PADSTATE;
-
-typedef struct tagGlobalData {
- CONFIG cfg;
-
- uint8_t Opened;
- Display *Disp;
-
- PADSTATE PadState[2];
- volatile long KeyLeftOver;
-} GLOBALDATA;
-
-extern GLOBALDATA g;
-
-enum {
- CMD_READ_DATA_AND_VIBRATE = 0x42,
- CMD_CONFIG_MODE = 0x43,
- CMD_SET_MODE_AND_LOCK = 0x44,
- CMD_QUERY_MODEL_AND_MODE = 0x45,
- CMD_QUERY_ACT = 0x46, // ??
- CMD_QUERY_COMB = 0x47, // ??
- CMD_QUERY_MODE = 0x4C, // QUERY_MODE ??
- CMD_VIBRATION_TOGGLE = 0x4D,
-};
-
-// cfg.c functions...
-void LoadPADConfig();
-void SavePADConfig();
-
-// sdljoy.c functions...
-void InitSDLJoy();
-void DestroySDLJoy();
-void CheckJoy();
-
-// xkb.c functions...
-void InitKeyboard();
-void DestroyKeyboard();
-void CheckKeyboard();
-
-// analog.c functions...
-void InitAnalog();
-void CheckAnalog();
-int AnalogKeyPressed(uint16_t Key);
-int AnalogKeyReleased(uint16_t Key);
-
-// pad.c functions...
-char *PSEgetLibName(void);
-uint32_t PSEgetLibType(void);
-uint32_t PSEgetLibVersion(void);
-long PADinit(long flags);
-long PADshutdown(void);
-long PADopen(unsigned long *Disp);
-long PADclose(void);
-long PADquery(void);
-unsigned char PADstartPoll(int pad);
-unsigned char PADpoll(unsigned char value);
-long PADreadPort1(PadDataS *pad);
-long PADreadPort2(PadDataS *pad);
-long PADkeypressed(void);
-long PADconfigure(void);
-void PADabout(void);
-long PADtest(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#ifndef PAD_H_
+#define PAD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _MACOSX
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <SDL.h>
+#include <SDL_joystick.h>
+#if SDL_VERSION_ATLEAST(1,3,0)
+#include <SDL_haptic.h>
+#endif
+
+#ifdef _MACOSX
+#include <Carbon/Carbon.h>
+typedef void *Display;
+#define ThreadID ThreadID_MACOSX
+#else
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/XKBlib.h>
+#endif
+
+#include "psemu_plugin_defs.h"
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#define _(x) gettext(x)
+#define N_(x) (x)
+//If running under Mac OS X, use the Localizable.strings file instead.
+#elif defined(_MACOSX)
+#ifdef PCSXRCORE
+extern const char* Pcsxr_locale_text(char* toloc);
+#define _(String) Pcsxr_locale_text(String)
+#define N_(String) String
+#else
+#ifndef PCSXRPLUG
+#warning please define the plug being built to use Mac OS X localization!
+#define _(msgid) msgid
+#define N_(msgid) msgid
+#else
+//Kludge to get the preprocessor to accept PCSXRPLUG as a variable.
+#define PLUGLOC_x(x,y) x ## y
+#define PLUGLOC_y(x,y) PLUGLOC_x(x,y)
+#define PLUGLOC PLUGLOC_y(PCSXRPLUG,_locale_text)
+extern const char* PLUGLOC(char* toloc);
+#define _(String) PLUGLOC(String)
+#define N_(String) String
+#endif
+#endif
+#else
+#define _(x) (x)
+#define N_(x) (x)
+#endif
+
+#if SDL_VERSION_ATLEAST(1,3,0)
+extern int has_haptic;
+#endif
+
+int JoyHapticRumble(int pad, uint32_t low, uint32_t high);
+
+enum {
+ DKEY_SELECT = 0,
+ DKEY_L3,
+ DKEY_R3,
+ DKEY_START,
+ DKEY_UP,
+ DKEY_RIGHT,
+ DKEY_DOWN,
+ DKEY_LEFT,
+ DKEY_L2,
+ DKEY_R2,
+ DKEY_L1,
+ DKEY_R1,
+ DKEY_TRIANGLE,
+ DKEY_CIRCLE,
+ DKEY_CROSS,
+ DKEY_SQUARE,
+ DKEY_ANALOG,
+
+ DKEY_TOTAL
+};
+
+enum {
+ ANALOG_LEFT = 0,
+ ANALOG_RIGHT,
+
+ ANALOG_TOTAL
+};
+
+enum { NONE = 0, AXIS, HAT, BUTTON };
+
+typedef struct tagKeyDef {
+ uint8_t JoyEvType;
+ union {
+ int16_t d;
+ int16_t Axis; // positive=axis+, negative=axis-, abs(Axis)-1=axis index
+ uint16_t Hat; // 8-bit for hat number, 8-bit for direction
+ uint16_t Button; // button number
+ } J;
+ uint16_t Key;
+} KEYDEF;
+
+enum { ANALOG_XP = 0, ANALOG_XM, ANALOG_YP, ANALOG_YM };
+
+typedef struct tagPadDef {
+ int8_t DevNum;
+ uint16_t Type;
+ uint8_t VisualVibration;
+ KEYDEF KeyDef[DKEY_TOTAL];
+ KEYDEF AnalogDef[ANALOG_TOTAL][4];
+} PADDEF;
+
+typedef struct tagConfig {
+ uint8_t Threaded;
+ uint8_t HideCursor;
+ PADDEF PadDef[2];
+} CONFIG;
+
+typedef struct tagPadState {
+ SDL_Joystick *JoyDev;
+ uint8_t PadMode;
+ uint8_t PadID;
+ uint8_t PadModeKey;
+ volatile uint8_t PadModeSwitch;
+ volatile uint16_t KeyStatus;
+ volatile uint16_t JoyKeyStatus;
+ volatile uint8_t AnalogStatus[ANALOG_TOTAL][2]; // 0-255 where 127 is center position
+ volatile uint8_t AnalogKeyStatus[ANALOG_TOTAL][4];
+ volatile int8_t MouseAxis[2][2];
+ uint8_t Vib0, Vib1;
+ volatile uint8_t VibF[2];
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_Haptic *haptic;
+#else
+#ifdef __linux__
+ int VibrateDev;
+ int VibrateEffect;
+ uint8_t VibrLow, VibrHigh;
+ uint32_t VibrSetTime;
+#endif
+#endif
+} PADSTATE;
+
+typedef struct tagGlobalData {
+ CONFIG cfg;
+
+ uint8_t Opened;
+ Display *Disp;
+
+ PADSTATE PadState[2];
+ volatile long KeyLeftOver;
+} GLOBALDATA;
+
+extern GLOBALDATA g;
+
+enum {
+ CMD_READ_DATA_AND_VIBRATE = 0x42,
+ CMD_CONFIG_MODE = 0x43,
+ CMD_SET_MODE_AND_LOCK = 0x44,
+ CMD_QUERY_MODEL_AND_MODE = 0x45,
+ CMD_QUERY_ACT = 0x46, // ??
+ CMD_QUERY_COMB = 0x47, // ??
+ CMD_QUERY_MODE = 0x4C, // QUERY_MODE ??
+ CMD_VIBRATION_TOGGLE = 0x4D,
+};
+
+// cfg.c functions...
+void LoadPADConfig();
+void SavePADConfig();
+
+// sdljoy.c functions...
+void InitSDLJoy();
+void DestroySDLJoy();
+void CheckJoy();
+
+// xkb.c functions...
+void InitKeyboard();
+void DestroyKeyboard();
+void CheckKeyboard();
+
+// analog.c functions...
+void InitAnalog();
+void CheckAnalog();
+int AnalogKeyPressed(uint16_t Key);
+int AnalogKeyReleased(uint16_t Key);
+
+// pad.c functions...
+char *PSEgetLibName(void);
+uint32_t PSEgetLibType(void);
+uint32_t PSEgetLibVersion(void);
+long PADinit(long flags);
+long PADshutdown(void);
+long PADopen(unsigned long *Disp);
+long PADclose(void);
+long PADquery(void);
+unsigned char PADstartPoll(int pad);
+unsigned char PADpoll(unsigned char value);
+long PADreadPort1(PadDataS *pad);
+long PADreadPort2(PadDataS *pad);
+long PADkeypressed(void);
+long PADconfigure(void);
+void PADabout(void);
+long PADtest(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins/dfinput/xkb.c b/plugins/dfinput/xkb.c
index 9592f340..9592f340 100644..100755
--- a/plugins/dfinput/xkb.c
+++ b/plugins/dfinput/xkb.c