From 379a8879f7dae1a9074317c0270e12dd203b32c0 Mon Sep 17 00:00:00 2001 From: "SND\\weimingzhi_cp" Date: Sun, 13 Mar 2011 08:26:16 +0000 Subject: Temporarily reverted r64524 until I (or someone else) find the time to sort out the stuff. git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64536 e17a0e51-4ae3-4d35-97c3-1a29b211df97 --- plugins/dfinput/cfg-gtk2.c | 1446 ++++++++++++++++++++++---------------------- plugins/dfinput/pad.c | 914 ++++++++++++++-------------- plugins/dfinput/pad.h | 370 ++++++------ 3 files changed, 1378 insertions(+), 1352 deletions(-) (limited to 'plugins/dfinput') diff --git a/plugins/dfinput/cfg-gtk2.c b/plugins/dfinput/cfg-gtk2.c index f56ed5ac..a3626873 100644 --- a/plugins/dfinput/cfg-gtk2.c +++ b/plugins/dfinput/cfg-gtk2.c @@ -1,723 +1,723 @@ -/* - * Copyright (c) 2009, Wei Mingzhi . - * 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 . - */ - -#include "cfg.c" - -#include -#include -#include - -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; - - if (g.cfg.PadDef[i].Type == PSE_PAD_TYPE_ANALOGPAD) { - total = DKEY_TOTAL; - } else { - total = DKEY_TOTAL - 3; - } - - widget = GTK_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_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(); - - 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)(long)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)(long)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)(long)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)(long)user_data, current = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); - g.cfg.PadDef[n].Type = (current == 0 ? PSE_PAD_TYPE_STANDARD : PSE_PAD_TYPE_ANALOGPAD); - - UpdateKeyList(); -} - -static void OnThreadedToggled(GtkWidget *widget, gpointer user_data) { - g.cfg.Threaded = 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]; - - 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 - while ((ge = gdk_event_get()) != NULL) { - if (ge->type == GDK_KEY_PRESS) { - if (ge->key.keyval != XK_Escape) { - g.cfg.PadDef[padnum].KeyDef[key].Key = ge->key.keyval; - } - gdk_event_free(ge); - goto end; - } - gdk_event_free(ge); - } - - 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]; - - 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 - while ((ge = gdk_event_get()) != NULL) { - if (ge->type == GDK_KEY_PRESS) { - if (ge->key.keyval != XK_Escape) { - g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].Key = ge->key.keyval; - } - gdk_event_free(ge); - goto end; - } - gdk_event_free(ge); - } - - usleep(5000); - } - -end: - if (js != NULL) { - SDL_JoystickClose(js); - } -} - -static void OnChangeClicked(GtkWidget *widget, gpointer user_data) { - int pad = (int)(long)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)(long)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_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; - } - - 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_WIDGET(gtk_builder_get_object(xml, "CfgWnd")); - gtk_window_set_title(GTK_WINDOW(MainWindow), _("Gamepad/Keyboard Input Configuration")); - - widget = GTK_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_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_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_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_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_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_WIDGET(gtk_builder_get_object(xml, "combodev2")); - g_signal_connect_data(GTK_OBJECT(widget), "changed", - G_CALLBACK(OnDeviceChanged), (gpointer)1, NULL, G_CONNECT_AFTER); - - widget = GTK_WIDGET(gtk_builder_get_object(xml, "combotype1")); - gtk_combo_box_set_active(GTK_COMBO_BOX(widget), - g.cfg.PadDef[0].Type == PSE_PAD_TYPE_ANALOGPAD ? 1 : 0); - g_signal_connect_data(GTK_OBJECT(widget), "changed", - G_CALLBACK(OnTypeChanged), (gpointer)0, NULL, G_CONNECT_AFTER); - - widget = GTK_WIDGET(gtk_builder_get_object(xml, "combotype2")); - gtk_combo_box_set_active(GTK_COMBO_BOX(widget), - g.cfg.PadDef[1].Type == PSE_PAD_TYPE_ANALOGPAD ? 1 : 0); - g_signal_connect_data(GTK_OBJECT(widget), "changed", - G_CALLBACK(OnTypeChanged), (gpointer)1, NULL, G_CONNECT_AFTER); - - widget = GTK_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_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_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_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 ", 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 . + * 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 . + */ + +#include "cfg.c" + +#include +#include +#include + +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; + + if (g.cfg.PadDef[i].Type == PSE_PAD_TYPE_ANALOGPAD) { + total = DKEY_TOTAL; + } else { + total = DKEY_TOTAL - 3; + } + + 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(); + + 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)); + g.cfg.PadDef[n].Type = (current == 0 ? PSE_PAD_TYPE_STANDARD : PSE_PAD_TYPE_ANALOGPAD); + + UpdateKeyList(); +} + +static void OnThreadedToggled(GtkWidget *widget, gpointer user_data) { + g.cfg.Threaded = 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]; + + 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 + while ((ge = gdk_event_get()) != NULL) { + if (ge->type == GDK_KEY_PRESS) { + if (ge->key.keyval != XK_Escape) { + g.cfg.PadDef[padnum].KeyDef[key].Key = ge->key.keyval; + } + gdk_event_free(ge); + goto end; + } + gdk_event_free(ge); + } + + 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]; + + 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 + while ((ge = gdk_event_get()) != NULL) { + if (ge->type == GDK_KEY_PRESS) { + if (ge->key.keyval != XK_Escape) { + g.cfg.PadDef[padnum].AnalogDef[analognum][analogdir].Key = ge->key.keyval; + } + gdk_event_free(ge); + goto end; + } + gdk_event_free(ge); + } + + 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; + } + + 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, "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); + + widget = gtk_builder_get_object(xml, "combotype1"); + gtk_combo_box_set_active(GTK_COMBO_BOX(widget), + g.cfg.PadDef[0].Type == PSE_PAD_TYPE_ANALOGPAD ? 1 : 0); + 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), + g.cfg.PadDef[1].Type == PSE_PAD_TYPE_ANALOGPAD ? 1 : 0); + g_signal_connect_data(GTK_OBJECT(widget), "changed", + G_CALLBACK(OnTypeChanged), (gpointer)1, 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 ", 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 c6089f12..302560e8 100644 --- a/plugins/dfinput/pad.c +++ b/plugins/dfinput/pad.c @@ -1,457 +1,457 @@ -/* - * Copyright (c) 2009, Wei Mingzhi . - * 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 . - */ - -#include "pad.h" - -static void (*gpuVisualVibration)(uint32_t, uint32_t) = NULL; - -char *PSEgetLibName(void) { - return _("Gamepad/Keyboard Input"); -} - -unsigned long CALLBACK PSEgetLibType(void) { - return PSE_LT_PAD; -} - -unsigned long CALLBACK PSEgetLibVersion(void) { - return (1 << 16) | (1 << 8); -} - -static void PADsetMode(const int pad, const int mode) { - g.PadState[pad].PadMode = mode; - g.PadState[pad].PadID = mode ? 0x73 : 0x41; - - 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; - } - - 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} -}; - -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: - UpdateInput(); - - 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 { - CmdLen = 4; - } - - buf = stdpar[CurPad]; - return g.PadState[CurPad].PadID; - } - } - - 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 (gpuVisualVibration != NULL && (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0)) { - gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]); - } - } - - if (CurByte == g.PadState[CurPad].Vib1) { - g.PadState[CurPad].VibF[1] = value; - - if (gpuVisualVibration != NULL && (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0)) { - 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; - return buf[CurByte++]; -} - -static long PADreadPort(int num, PadDataS *pad) { - UpdateInput(); - - pad->buttonStatus = (g.PadState[num].KeyStatus & g.PadState[num].JoyKeyStatus); - - // ePSXe different from pcsx, 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; - - CheckKeyboard(); - - s = g.KeyLeftOver; - g.KeyLeftOver = 0; - - return s; -} - -void PADregisterVibration(void (*callback)(uint32_t, uint32_t)) { - gpuVisualVibration = callback; -} - -#ifndef _MACOSX - -long PADconfigure(void) { - if (fork() == 0) { - execl("cfg/cfgDFInput", "cfgDFInput", NULL); - exit(0); - } - return PSE_PAD_ERR_SUCCESS; -} - -void PADabout(void) { - if (fork() == 0) { - execl("cfg/cfgDFInput", "cfgDFInput", "-about", NULL); - exit(0); - } -} - -#endif - -long PADtest(void) { - return PSE_PAD_ERR_SUCCESS; -} +/* + * Copyright (c) 2009, Wei Mingzhi . + * 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 . + */ + +#include "pad.h" + +static void (*gpuVisualVibration)(uint32_t, uint32_t) = NULL; + +char *PSEgetLibName(void) { + return _("Gamepad/Keyboard Input"); +} + +uint32_t PSEgetLibType(void) { + return PSE_LT_PAD; +} + +uint32_t PSEgetLibVersion(void) { + return (1 << 16) | (1 << 8); +} + +void PADsetMode(const int pad, const int mode) { + g.PadState[pad].PadMode = mode; + g.PadState[pad].PadID = mode ? 0x73 : 0x41; + + 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; + } + + 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} +}; + +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: + UpdateInput(); + + 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 { + CmdLen = 4; + } + + buf = stdpar[CurPad]; + return g.PadState[CurPad].PadID; + } + } + + 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 (gpuVisualVibration != NULL && (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0)) { + gpuVisualVibration(g.PadState[CurPad].VibF[0], g.PadState[CurPad].VibF[1]); + } + } + + if (CurByte == g.PadState[CurPad].Vib1) { + g.PadState[CurPad].VibF[1] = value; + + if (gpuVisualVibration != NULL && (g.PadState[CurPad].VibF[0] != 0 || g.PadState[CurPad].VibF[1] != 0)) { + 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; + return buf[CurByte++]; +} + +static long PADreadPort(int num, PadDataS *pad) { + UpdateInput(); + + pad->buttonStatus = (g.PadState[num].KeyStatus & g.PadState[num].JoyKeyStatus); + + // ePSXe different from pcsx, 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; + + CheckKeyboard(); + + s = g.KeyLeftOver; + g.KeyLeftOver = 0; + + return s; +} + +void PADregisterVibration(void (*callback)(uint32_t, uint32_t)) { + gpuVisualVibration = callback; +} + +#ifndef _MACOSX + +long PADconfigure(void) { + if (fork() == 0) { + execl("cfg/cfgDFInput", "cfgDFInput", NULL); + exit(0); + } + return PSE_PAD_ERR_SUCCESS; +} + +void PADabout(void) { + if (fork() == 0) { + execl("cfg/cfgDFInput", "cfgDFInput", "-about", NULL); + exit(0); + } +} + +#endif + +long PADtest(void) { + return PSE_PAD_ERR_SUCCESS; +} diff --git a/plugins/dfinput/pad.h b/plugins/dfinput/pad.h index ae30c391..7c1b0e64 100644 --- a/plugins/dfinput/pad.h +++ b/plugins/dfinput/pad.h @@ -1,172 +1,198 @@ -/* - * Copyright (c) 2009, Wei Mingzhi . - * 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 . - */ - -#ifndef PAD_H_ -#define PAD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _MACOSX -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef _MACOSX -#include -typedef void *Display; -#define ThreadID ThreadID_MACOSX -#else -#include -#include -#include -#include -#endif - -#include "psemu_plugin_defs.h" - -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; - KEYDEF KeyDef[DKEY_TOTAL]; - KEYDEF AnalogDef[ANALOG_TOTAL][4]; -} PADDEF; - -typedef struct tagConfig { - uint8_t Threaded; - 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]; - uint8_t Vib0, Vib1; - volatile uint8_t VibF[2]; -} 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); - -#include "psemu_plugin_defs.h" - -#ifdef __cplusplus -} -#endif - -#endif +/* + * Copyright (c) 2009, Wei Mingzhi . + * 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 . + */ + +#ifndef PAD_H_ +#define PAD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _MACOSX +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef _MACOSX +#include +typedef void *Display; +#define ThreadID ThreadID_MACOSX +#else +#include +#include +#include +#include +#endif + +#include "psemu_plugin_defs.h" + +#ifdef ENABLE_NLS +#include +#include +#define _(x) gettext(x) +#define N_(x) (x) +#else +#define _(x) (x) +#define N_(x) (x) +#endif + +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; + KEYDEF KeyDef[DKEY_TOTAL]; + KEYDEF AnalogDef[ANALOG_TOTAL][4]; +} PADDEF; + +typedef struct tagConfig { + uint8_t Threaded; + 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]; + uint8_t Vib0, Vib1; + volatile uint8_t VibF[2]; +} 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 -- cgit v1.2.3