From 71480b31242cee2cb216f27797f96e4220ab2ed2 Mon Sep 17 00:00:00 2001 From: arcum42 Date: Fri, 29 May 2009 06:33:56 +0000 Subject: [PATCH] Zeropad: A bunch of refactoring and cleanup. The Windows port probably won't compile right now. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1286 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/zeropad/Linux/linux.cpp | 200 ++------------ plugins/zeropad/Linux/linux.h | 7 +- plugins/zeropad/Makefile.am | 2 +- plugins/zeropad/Windows/ZeroPAD_2008.vcproj | 16 ++ plugins/zeropad/Windows/gui.cpp | 110 ++++++++ plugins/zeropad/Windows/win.cpp | 268 ++----------------- plugins/zeropad/Windows/win.h | 33 +++ plugins/zeropad/joystick.cpp | 4 + plugins/zeropad/joystick.h | 1 + plugins/zeropad/keyboard.cpp | 277 ++++++++++++++++++++ plugins/zeropad/keyboard.h | 44 ++++ plugins/zeropad/zeropad.cpp | 30 +++ plugins/zeropad/zeropad.h | 9 +- 13 files changed, 568 insertions(+), 433 deletions(-) create mode 100644 plugins/zeropad/Windows/gui.cpp create mode 100644 plugins/zeropad/Windows/win.h create mode 100644 plugins/zeropad/keyboard.cpp create mode 100644 plugins/zeropad/keyboard.h diff --git a/plugins/zeropad/Linux/linux.cpp b/plugins/zeropad/Linux/linux.cpp index 250e956fd1..55100bde96 100644 --- a/plugins/zeropad/Linux/linux.cpp +++ b/plugins/zeropad/Linux/linux.cpp @@ -19,8 +19,6 @@ #include "linux.h" Display *GSdsp; -static pthread_spinlock_t s_mutexStatus; -static u32 s_keyPress[2], s_keyRelease[2]; // thread safe static const char* s_pGuiKeyMap[] = { @@ -43,20 +41,14 @@ string GetLabelFromButton(const char* buttonname) s32 _PADopen(void *pDsp) { GSdsp = *(Display**)pDsp; - pthread_spin_init(&s_mutexStatus, PTHREAD_PROCESS_PRIVATE); - s_keyPress[0] = s_keyPress[1] = 0; - s_keyRelease[0] = s_keyRelease[1] = 0; - XAutoRepeatOff(GSdsp); - - JoystickInfo::EnumerateJoysticks(s_vjoysticks); + SetAutoRepeat(false); return 0; } void _PADclose() { - pthread_spin_destroy(&s_mutexStatus); - XAutoRepeatOn(GSdsp); + SetAutoRepeat(true); vector::iterator it = s_vjoysticks.begin(); @@ -70,16 +62,6 @@ void _PADclose() s_vjoysticks.clear(); } -void _PADupdate(int pad) -{ - pthread_spin_lock(&s_mutexStatus); - status[pad] |= s_keyRelease[pad]; - status[pad] &= ~s_keyPress[pad]; - s_keyRelease[pad] = 0; - s_keyPress[pad] = 0; - pthread_spin_unlock(&s_mutexStatus); -} - int _GetJoystickIdFromPAD(int pad) { // select the right joystick id @@ -99,7 +81,7 @@ int _GetJoystickIdFromPAD(int pad) } } - if ((joyid < 0) || (joyid >= (int)s_vjoysticks.size())) + if (JoystickIdWithinBounds(joyid)) { // get first unused joystick for (joyid = 0; joyid < s_vjoysticks.size(); ++joyid) @@ -113,85 +95,8 @@ int _GetJoystickIdFromPAD(int pad) void CALLBACK PADupdate(int pad) { - int i; - XEvent E; - int keyPress = 0, keyRelease = 0; - KeySym key; - - // keyboard input - while (XPending(GSdsp) > 0) - { - XNextEvent(GSdsp, &E); - switch (E.type) - { - case KeyPress: - key = XLookupKeysym((XKeyEvent *) & E, 0); - - i = FindKey(key, pad); - - // Analog controls. - if ((i > PAD_RY) && (i <= PAD_R_LEFT)) - { - switch (i) - { - case PAD_R_LEFT: - case PAD_R_UP: - case PAD_L_LEFT: - case PAD_L_UP: - Analog::ConfigurePad(Analog::AnalogToPad(i), pad, DEF_VALUE); - break; - case PAD_R_RIGHT: - case PAD_R_DOWN: - case PAD_L_RIGHT: - case PAD_L_DOWN: - Analog::ConfigurePad(Analog::AnalogToPad(i), pad, -DEF_VALUE); - break; - } - i += 0xff00; - } - - if (i != -1) - { - clear_bit(keyRelease, i); - set_bit(keyPress, i); - } - //PAD_LOG("Key pressed:%d\n", i); - - event.evt = KEYPRESS; - event.key = key; - break; - - case KeyRelease: - key = XLookupKeysym((XKeyEvent *) & E, 0); - - i = FindKey(key, pad); - - // Analog Controls. - if ((i > PAD_RY) && (i <= PAD_R_LEFT)) - { - Analog::ResetPad(Analog::AnalogToPad(i), pad); - i += 0xff00; - } - - if (i != -1) - { - clear_bit(keyPress, i); - set_bit(keyRelease, i); - } - - event.evt = KEYRELEASE; - event.key = key; - break; - - case FocusIn: - XAutoRepeatOff(GSdsp); - break; - - case FocusOut: - XAutoRepeatOn(GSdsp); - break; - } - } + // Poll keyboard. + PollForKeyboardInput(pad); // joystick info SDL_JoystickUpdate(); @@ -199,34 +104,25 @@ void CALLBACK PADupdate(int pad) for (int i = 0; i < PADKEYS; i++) { int key = conf.keys[PadEnum[pad][0]][i]; - JoystickInfo* pjoy = NULL; - - if (IS_JOYBUTTONS(key)) - { - int joyid = PAD_GETJOYID(key); - if ((joyid >= 0) && (joyid < (int)s_vjoysticks.size())) + if (JoystickIdWithinBounds(PAD_GETJOYID(key))) + { + JoystickInfo* pjoy = s_vjoysticks[PAD_GETJOYID(key)]; + int pad = (pjoy)->GetPAD(); + + if (IS_JOYBUTTONS(key)) { - pjoy = s_vjoysticks[joyid]; - int pad = (pjoy)->GetPAD(); int value = SDL_JoystickGetButton((pjoy)->GetJoy(), PAD_GETJOYBUTTON(key)); - + if (value) - clear_bit(status[pad], i); // pressed + clear_bit(status[pad], i); // released else set_bit(status[pad], i); // pressed } - } - else if (IS_JOYSTICK(key)) - { - int joyid = PAD_GETJOYID(key); - - if ((joyid >= 0) && (joyid < (int)s_vjoysticks.size())) + else if (IS_JOYSTICK(key)) { - pjoy = s_vjoysticks[joyid]; - int pad = (pjoy)->GetPAD(); int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); - + switch (i) { case PAD_LX: @@ -240,18 +136,11 @@ void CALLBACK PADupdate(int pad) break; } } - } -#ifdef EXPERIMENTAL_POV_CODE - else if (IS_HAT(key)) - { - int joyid = PAD_GETJOYID(key); - - if ((joyid >= 0) && (joyid < (int)s_vjoysticks.size())) + #ifdef EXPERIMENTAL_POV_CODE + else if (IS_HAT(key)) { - pjoy = s_vjoysticks[joyid]; - int pad = (pjoy)->GetPAD(); int value = SDL_JoystickGetHat((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); - + //PAD_LOG("Hat = %d for key %d\n", PAD_GETPOVDIR(key), key); if ((value != SDL_HAT_CENTERED) && (PAD_GETHATDIR(key) == value)) { @@ -270,16 +159,9 @@ void CALLBACK PADupdate(int pad) clear_bit(status[pad], i); } } - } -#endif - else if (IS_POV(key)) - { - int joyid = PAD_GETJOYID(key); - - if (joyid >= 0 && (joyid < (int)s_vjoysticks.size())) + #endif + else if (IS_POV(key)) { - pjoy = s_vjoysticks[joyid]; - int pad = (pjoy)->GetPAD(); int value = SDL_JoystickGetAxis((pjoy)->GetJoy(), PAD_GETJOYSTICK_AXIS(key)); if (PAD_GETPOVSIGN(key) && (value < -2048)) @@ -288,18 +170,9 @@ void CALLBACK PADupdate(int pad) clear_bit(status[pad], i); else set_bit(status[pad], i); - - } } } - - pthread_spin_lock(&s_mutexStatus); - s_keyPress[pad] |= keyPress; - s_keyPress[pad] &= ~keyRelease; - s_keyRelease[pad] |= keyRelease; - s_keyRelease[pad] &= ~keyPress; - pthread_spin_unlock(&s_mutexStatus); } void UpdateConf(int pad) @@ -324,7 +197,7 @@ void UpdateConf(int pad) if (IS_KEYBOARD(conf.keys[pad][i])) { - char* pstr = XKeysymToString(PAD_GETKEY(conf.keys[pad][i])); + char* pstr = KeysymToChar(PAD_GETKEY(conf.keys[pad][i])); if (pstr != NULL) tmp = pstr; } else if (IS_JOYBUTTONS(conf.keys[pad][i])) @@ -386,7 +259,7 @@ void UpdateConf(int pad) // check bounds int joyid = _GetJoystickIdFromPAD(pad); - if ((joyid >= 0) && (joyid < (int)s_vjoysticks.size())) + if (JoystickIdWithinBounds(joyid)) gtk_combo_box_set_active(GTK_COMBO_BOX(s_devicecombo), joyid); // select the combo else gtk_combo_box_set_active(GTK_COMBO_BOX(s_devicecombo), s_vjoysticks.size()); // no gamepad @@ -418,33 +291,6 @@ int GetLabelId(GtkWidget *label) return (int)(uptr)gtk_object_get_user_data(GTK_OBJECT(label)); } -bool PollKeyboard(char* &temp, u32 &pkey) -{ - GdkEvent *ev = gdk_event_get(); - - if (ev != NULL) - { - if (ev->type == GDK_KEY_PRESS) - { - - if (ev->key.keyval == GDK_Escape) - { - temp = "Unknown"; - pkey = NULL; - } - else - { - temp = XKeysymToString(ev->key.keyval); - pkey = ev->key.keyval; - } - - return true; - } - } - - return false; -} - void OnConf_Key(GtkButton *button, gpointer user_data) { GtkWidget* label = GetLabelWidget(button); @@ -465,7 +311,7 @@ void OnConf_Key(GtkButton *button, gpointer user_data) vector::iterator itjoy; char *tmp; - if (PollKeyboard(tmp, conf.keys[pad][key])) + if (PollX11Keyboard(tmp, conf.keys[pad][key])) { strcpy(str, tmp); captured = true; diff --git a/plugins/zeropad/Linux/linux.h b/plugins/zeropad/Linux/linux.h index 5a12f8c145..26de22f1b6 100644 --- a/plugins/zeropad/Linux/linux.h +++ b/plugins/zeropad/Linux/linux.h @@ -16,14 +16,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "joystick.h" +#include "keyboard.h" +#include "zeropad.h" + #include #include #include #include -#include "joystick.h" - -#include "zeropad.h" extern "C" { diff --git a/plugins/zeropad/Makefile.am b/plugins/zeropad/Makefile.am index 3937ec3c90..8d383d794f 100644 --- a/plugins/zeropad/Makefile.am +++ b/plugins/zeropad/Makefile.am @@ -23,4 +23,4 @@ libZeroPAD_LDFLAGS+=-Wl,-soname,@ZEROPAD_SONAME@ libZeroPAD_LDADD=$(libZeroPAD_a_OBJECTS) libZeroPAD_a_SOURCES = joystick.cpp analog.cpp analog.h zeropad.cpp zeropad.h \ -Linux/gui.cpp Linux/linux.cpp Linux/support.c Linux/interface.c +Linux/gui.cpp Linux/linux.cpp Linux/support.c Linux/interface.c keyboard.cpp keyboard.h diff --git a/plugins/zeropad/Windows/ZeroPAD_2008.vcproj b/plugins/zeropad/Windows/ZeroPAD_2008.vcproj index d5927633ca..48f0aaf2d6 100644 --- a/plugins/zeropad/Windows/ZeroPAD_2008.vcproj +++ b/plugins/zeropad/Windows/ZeroPAD_2008.vcproj @@ -246,6 +246,10 @@ RelativePath=".\win.cpp" > + + @@ -254,12 +258,20 @@ RelativePath="..\analog.cpp" > + + + + @@ -280,6 +292,10 @@ RelativePath="..\analog.h" > + + diff --git a/plugins/zeropad/Windows/gui.cpp b/plugins/zeropad/Windows/gui.cpp new file mode 100644 index 0000000000..a2a6a07fcf --- /dev/null +++ b/plugins/zeropad/Windows/gui.cpp @@ -0,0 +1,110 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #include "win.h" + + void SaveConfig() +{ + char *szTemp; + char szIniFile[256], szValue[256], szProf[256]; + int i, j; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if (!szTemp) return; + strcpy(szTemp, "\\inis\\zeropad.ini"); + + for (j = 0; j < 2; j++) + { + for (i = 0; i < PADKEYS; i++) + { + sprintf(szProf, "%d_%d", j, i); + sprintf(szValue, "%d", conf.keys[j][i]); + WritePrivateProfileString("Interface", szProf, szValue, szIniFile); + } + } + + sprintf(szValue, "%u", conf.log); + WritePrivateProfileString("Interface", "Logging", szValue, szIniFile); +} + +void LoadConfig() +{ + FILE *fp; + char *szTemp; + char szIniFile[256], szValue[256], szProf[256]; + int i, j; + + memset(&conf, 0, sizeof(conf)); +#ifdef _WIN32 + conf.keys[0][0] = 'W'; // L2 + conf.keys[0][1] = 'O'; // R2 + conf.keys[0][2] = 'A'; // L1 + conf.keys[0][3] = ';'; // R1 + conf.keys[0][4] = 'I'; // TRIANGLE + conf.keys[0][5] = 'L'; // CIRCLE + conf.keys[0][6] = 'K'; // CROSS + conf.keys[0][7] = 'J'; // SQUARE + conf.keys[0][8] = 'V'; // SELECT + conf.keys[0][11] = 'N'; // START + conf.keys[0][12] = 'E'; // UP + conf.keys[0][13] = 'F'; // RIGHT + conf.keys[0][14] = 'D'; // DOWN + conf.keys[0][15] = 'S'; // LEFT +#endif + conf.log = 0; + + GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); + szTemp = strrchr(szIniFile, '\\'); + + if (!szTemp) return ; + strcpy(szTemp, "\\inis\\zeropad.ini"); + fp = fopen("inis\\zeropad.ini", "rt");//check if usbnull.ini really exists + if (!fp) + { + CreateDirectory("inis", NULL); + SaveConfig();//save and return + return ; + } + fclose(fp); + + for (j = 0; j < 2; j++) + { + for (i = 0; i < PADKEYS; i++) + { + sprintf(szProf, "%d_%d", j, i); + GetPrivateProfileString("Interface", szProf, NULL, szValue, 20, szIniFile); + conf.keys[j][i] = strtoul(szValue, NULL, 10); + } + } + + GetPrivateProfileString("Interface", "Logging", NULL, szValue, 20, szIniFile); + conf.log = strtoul(szValue, NULL, 10); +} + +void SysMessage(char *fmt, ...) +{ + va_list list; + char tmp[512]; + + va_start(list, fmt); + vsprintf(tmp, fmt, list); + va_end(list); + MessageBox(0, tmp, "PADwinKeyb Msg", 0); +} \ No newline at end of file diff --git a/plugins/zeropad/Windows/win.cpp b/plugins/zeropad/Windows/win.cpp index 959f65fedc..6bf8e79275 100644 --- a/plugins/zeropad/Windows/win.cpp +++ b/plugins/zeropad/Windows/win.cpp @@ -16,22 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include - -#include "resource.h" -#include "../zeropad.h" - -#include -#include +#include "win.h" using namespace std; HINSTANCE hInst = NULL; -static pthread_spinlock_t s_mutexStatus; -static u32 s_keyPress[2], s_keyRelease[2]; extern u16 status[2]; extern string s_strIniPath; @@ -41,105 +30,9 @@ HWND GShwnd = NULL; extern keyEvent event; - -void SaveConfig() -{ - char *szTemp; - char szIniFile[256], szValue[256], szProf[256]; - int i, j; - - GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); - szTemp = strrchr(szIniFile, '\\'); - - if (!szTemp) return; - strcpy(szTemp, "\\inis\\zeropad.ini"); - - for (j = 0; j < 2; j++) - { - for (i = 0; i < PADKEYS; i++) - { - sprintf(szProf, "%d_%d", j, i); - sprintf(szValue, "%d", conf.keys[j][i]); - WritePrivateProfileString("Interface", szProf, szValue, szIniFile); - } - } - - sprintf(szValue, "%u", conf.log); - WritePrivateProfileString("Interface", "Logging", szValue, szIniFile); -} - -void LoadConfig() -{ - FILE *fp; - char *szTemp; - char szIniFile[256], szValue[256], szProf[256]; - int i, j; - - memset(&conf, 0, sizeof(conf)); -#ifdef _WIN32 - conf.keys[0][0] = 'W'; // L2 - conf.keys[0][1] = 'O'; // R2 - conf.keys[0][2] = 'A'; // L1 - conf.keys[0][3] = ';'; // R1 - conf.keys[0][4] = 'I'; // TRIANGLE - conf.keys[0][5] = 'L'; // CIRCLE - conf.keys[0][6] = 'K'; // CROSS - conf.keys[0][7] = 'J'; // SQUARE - conf.keys[0][8] = 'V'; // SELECT - conf.keys[0][11] = 'N'; // START - conf.keys[0][12] = 'E'; // UP - conf.keys[0][13] = 'F'; // RIGHT - conf.keys[0][14] = 'D'; // DOWN - conf.keys[0][15] = 'S'; // LEFT -#endif - conf.log = 0; - - GetModuleFileName(GetModuleHandle((LPCSTR)hInst), szIniFile, 256); - szTemp = strrchr(szIniFile, '\\'); - - if (!szTemp) return ; - strcpy(szTemp, "\\inis\\zeropad.ini"); - fp = fopen("inis\\zeropad.ini", "rt");//check if usbnull.ini really exists - if (!fp) - { - CreateDirectory("inis", NULL); - SaveConfig();//save and return - return ; - } - fclose(fp); - - for (j = 0; j < 2; j++) - { - for (i = 0; i < PADKEYS; i++) - { - sprintf(szProf, "%d_%d", j, i); - GetPrivateProfileString("Interface", szProf, NULL, szValue, 20, szIniFile); - conf.keys[j][i] = strtoul(szValue, NULL, 10); - } - } - - GetPrivateProfileString("Interface", "Logging", NULL, szValue, 20, szIniFile); - conf.log = strtoul(szValue, NULL, 10); -} - -void SysMessage(char *fmt, ...) -{ - va_list list; - char tmp[512]; - - va_start(list, fmt); - vsprintf(tmp, fmt, list); - va_end(list); - MessageBox(0, tmp, "PADwinKeyb Msg", 0); -} - s32 _PADopen(void *pDsp) { - memset(&event, 0, sizeof(event)); LoadConfig(); - pthread_spin_init(&s_mutexStatus, PTHREAD_PROCESS_PRIVATE); - s_keyPress[0] = s_keyPress[1] = 0; - s_keyRelease[0] = s_keyRelease[1] = 0; if (GShwnd != NULL && GSwndProc != NULL) { @@ -162,167 +55,48 @@ void _PADclose() GSwndProc = NULL; GShwnd = NULL; } - pthread_spin_destroy(&s_mutexStatus); -} - -void _PADupdate(int pad) -{ - pthread_spin_lock(&s_mutexStatus); - status[pad] |= s_keyRelease[pad]; - status[pad] &= ~s_keyPress[pad]; - s_keyRelease[pad] = 0; - s_keyPress[pad] = 0; - pthread_spin_unlock(&s_mutexStatus); } +// Yes, let's not do anything when pcsx2 asks for us for an update. +// We certainly don't want to update the gamepad information... void CALLBACK PADupdate(int pad) { } -LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i, pad, keyPress[2] = {0}, keyRelease[2] = {0}; - static bool lbutton = false, rbutton = false; - - switch (msg) - { - case WM_KEYDOWN: - if (lParam & 0x40000000) - return TRUE; - - for (pad = 0; pad < 2; ++pad) - { - for (i = 0; i < PADKEYS; i++) - { - if (wParam == conf.keys[pad][i]) - { - keyPress[pad] |= (1 << i); - keyRelease[pad] &= ~(1 << i); - break; - } - } - } - - event.evt = KEYPRESS; - event.key = wParam; - break; - - case WM_KEYUP: - for (pad = 0; pad < 2; ++pad) - { - for (i = 0; i < PADKEYS; i++) - { - if (wParam == conf.keys[pad][i]) - { - keyPress[pad] &= ~(1 << i); - keyRelease[pad] |= (1 << i); - break; - } - } - } - - - event.evt = KEYRELEASE; - event.key = wParam; - break; - - case WM_LBUTTONDOWN: - lbutton = true; - break; - - case WM_LBUTTONUP: - g_lanalog[0].x = 0x80; - g_lanalog[0].y = 0x80; - g_lanalog[1].x = 0x80; - g_lanalog[1].y = 0x80; - lbutton = false; - break; - - case WM_RBUTTONDOWN: - rbutton = true; - break; - - case WM_RBUTTONUP: - g_ranalog[0].x = 0x80; - g_ranalog[0].y = 0x80; - g_ranalog[1].x = 0x80; - g_ranalog[1].y = 0x80; - rbutton = false; - break; - - case WM_MOUSEMOVE: - if (lbutton) - { - g_lanalog[0].x = LOWORD(lParam) & 254; - g_lanalog[0].y = HIWORD(lParam) & 254; - g_lanalog[1].x = LOWORD(lParam) & 254; - g_lanalog[1].y = HIWORD(lParam) & 254; - } - if (rbutton) - { - g_ranalog[0].x = LOWORD(lParam) & 254; - g_ranalog[0].y = HIWORD(lParam) & 254; - g_ranalog[1].x = LOWORD(lParam) & 254; - g_ranalog[1].y = HIWORD(lParam) & 254; - } - break; - - case WM_DESTROY: - case WM_QUIT: - event.evt = KEYPRESS; - event.key = VK_ESCAPE; - return GSwndProc(hWnd, msg, wParam, lParam); - - default: - return GSwndProc(hWnd, msg, wParam, lParam); - } - - pthread_spin_lock(&s_mutexStatus); - for (pad = 0; pad < 2; ++pad) - { - s_keyPress[pad] |= keyPress[pad]; - s_keyPress[pad] &= ~keyRelease[pad]; - s_keyRelease[pad] |= keyRelease[pad]; - s_keyRelease[pad] &= ~keyPress[pad]; - } - pthread_spin_unlock(&s_mutexStatus); - - return TRUE; -} - +// Most of the values look off in here by either a factor of 10 or 100. string GetKeyLabel(const int pad, const int index) { const int key = conf.keys[pad][index]; char buff[16] = "NONE)"; - if (key < 0x100) + if (key < 0x100) //IS_KEYBOARD; should be 0x10000 { if (key == 0) strcpy(buff, "NONE"); else { if (key >= 0x60 && key <= 0x69) - { sprintf(buff, "NumPad %c", '0' + key - 0x60); - } - else sprintf(buff, "%c", key); + else + sprintf(buff, "%c", key); } } - else if (key >= 0x1000 && key < 0x2000) + else if (key >= 0x1000 && key < 0x2000) //IS_JOYBUTTONS; 0x10000 - 0x20000 { sprintf(buff, "J%d_%d", (key & 0xfff) / 0x100, (key & 0xff) + 1); } - else if (key >= 0x2000 && key < 0x3000) + else if (key >= 0x2000 && key < 0x3000) // IS_JOYSTICK; 0x20000 - 0x30000 { static const char name[][4] = { "MIN", "MAX" }; const int axis = (key & 0xff); + sprintf(buff, "J%d_AXIS%d_%s", (key & 0xfff) / 0x100, axis / 2, name[axis % 2]); - if (index >= 17 && index <= 20) - buff[strlen(buff) -4] = '\0'; + if (index >= 17 && index <= 20) buff[strlen(buff) -4] = '\0'; } - else if (key >= 0x3000 && key < 0x4000) + else if (key >= 0x3000 && key < 0x4000) // IS_POV; 0x30000 - 0x50000 { - static const char name[][7] = { "FOWARD", "RIGHT", "BACK", "LEFT" }; + static const char name[][7] = { "FORWARD", "RIGHT", "BACK", "LEFT" }; const int pov = (key & 0xff); + sprintf(buff, "J%d_POV%d_%s", (key & 0xfff) / 0x100, pov / 4, name[pov % 4]); } @@ -343,7 +117,7 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_INITDIALOG: LoadConfig(); padn = 0; - if (conf.log) CheckDlgButton(hW, IDC_LOG, TRUE); + if (conf.log) CheckDlgButton(hW, IDC_LOG, TRUE); for (i = 0; i < PADKEYS; i++) { @@ -369,6 +143,7 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { key = 0; //pkeyboard = SDL_GetKeyState(&numkeys); + // Yeah, there's no way this will work, given that it's disabled. for (int i = 0; i < numkeys; ++i) { if (pkeyboard[i]) @@ -382,9 +157,10 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { // check joystick } - - if (key != 0) + else { + // Get rid of the expired timer, try to configure the keys, fail horribly, + // and either crash or don't register a keypress. KillTimer(hW, 0x80); hWC = GetDlgItem(hW, disabled); conf.keys[padn][disabled-IDC_L2] = key; @@ -401,11 +177,13 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (LOWORD(wParam) == i) { + // A button was pressed if (disabled)//change selection EnableWindow(GetDlgItem(hW, disabled), TRUE); EnableWindow(GetDlgItem(hW, disabled = wParam), FALSE); + // Wait a silly amount of time for a keypress. SetTimer(hW, 0x80, 250, NULL); return TRUE; @@ -418,11 +196,13 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) KillTimer(hW, 0x80); EndDialog(hW, TRUE); return TRUE; + case IDOK: KillTimer(hW, 0x80); if (IsDlgButtonChecked(hW, IDC_LOG)) conf.log = 1; - else conf.log = 0; + else + conf.log = 0; SaveConfig(); EndDialog(hW, FALSE); return TRUE; diff --git a/plugins/zeropad/Windows/win.h b/plugins/zeropad/Windows/win.h new file mode 100644 index 0000000000..ed468e2c64 --- /dev/null +++ b/plugins/zeropad/Windows/win.h @@ -0,0 +1,33 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #include +#include +#include +#include + +#include "resource.h" +#include "../zeropad.h" + +#include +#include + +extern void SaveConfig(); +extern void LoadConfig(); +extern void SysMessage(char *fmt, ...); +extern LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); \ No newline at end of file diff --git a/plugins/zeropad/joystick.cpp b/plugins/zeropad/joystick.cpp index 579490b694..1878abb18f 100644 --- a/plugins/zeropad/joystick.cpp +++ b/plugins/zeropad/joystick.cpp @@ -69,6 +69,10 @@ const char *HatName(int value) return "Unknown"; } +bool JoystickIdWithinBounds(int joyid) +{ + return (!((joyid < 0) || (joyid >= (int)s_vjoysticks.size()))); +} // opens handles to all possible joysticks void JoystickInfo::EnumerateJoysticks(vector& vjoysticks) { diff --git a/plugins/zeropad/joystick.h b/plugins/zeropad/joystick.h index 4f9d5b0052..1cecd8e23c 100644 --- a/plugins/zeropad/joystick.h +++ b/plugins/zeropad/joystick.h @@ -139,4 +139,5 @@ extern int s_selectedpad; extern vector s_vjoysticks; extern void UpdateJoysticks(); extern const char *HatName(int value); +extern bool JoystickIdWithinBounds(int joyid); #endif diff --git a/plugins/zeropad/keyboard.cpp b/plugins/zeropad/keyboard.cpp new file mode 100644 index 0000000000..bdcf1a6986 --- /dev/null +++ b/plugins/zeropad/keyboard.cpp @@ -0,0 +1,277 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + /* + * Theoretically, this header is for anything to do with keyboard input. + * Pragmatically, event handing's going in here too. + */ + + #include "keyboard.h" + + __forceinline int FindKey(int key, int pad) +{ + for (int p = 0; p < PADSUBKEYS; p++) + for (int i = 0; i < PADKEYS; i++) + if (key == conf.keys[(PadEnum[pad][p])][i]) return i; + return -1; +} + +char* KeysymToChar(int keysym) +{ + #ifdef __LINUX__ + return XKeysymToString(keysym); +#else + return; + #endif +} + +void PollForKeyboardInput(int pad) +{ + #ifdef __LINUX__ + PollForX11KeyboardInput(pad); +#endif +} + +void SetAutoRepeat(bool autorep) +{ + #ifdef __LINUX__ + if (autorep) + XAutoRepeatOn(GSdsp); + else + XAutoRepeatOff(GSdsp); +#endif +} + + #ifdef __LINUX__ +void PollForX11KeyboardInput(int pad) +{ + XEvent E; + KeySym key; + int keyPress = 0, keyRelease = 0; + int i; + + // keyboard input + while (XPending(GSdsp) > 0) + { + XNextEvent(GSdsp, &E); + switch (E.type) + { + case KeyPress: + key = XLookupKeysym((XKeyEvent *) & E, 0); + + i = FindKey(key, pad); + + // Analog controls. + if ((i > PAD_RY) && (i <= PAD_R_LEFT)) + { + switch (i) + { + case PAD_R_LEFT: + case PAD_R_UP: + case PAD_L_LEFT: + case PAD_L_UP: + Analog::ConfigurePad(Analog::AnalogToPad(i), pad, DEF_VALUE); + break; + case PAD_R_RIGHT: + case PAD_R_DOWN: + case PAD_L_RIGHT: + case PAD_L_DOWN: + Analog::ConfigurePad(Analog::AnalogToPad(i), pad, -DEF_VALUE); + break; + } + i += 0xff00; + } + + if (i != -1) + { + clear_bit(keyRelease, i); + set_bit(keyPress, i); + } + //PAD_LOG("Key pressed:%d\n", i); + + event.evt = KEYPRESS; + event.key = key; + break; + + case KeyRelease: + key = XLookupKeysym((XKeyEvent *) & E, 0); + + i = FindKey(key, pad); + + // Analog Controls. + if ((i > PAD_RY) && (i <= PAD_R_LEFT)) + { + Analog::ResetPad(Analog::AnalogToPad(i), pad); + i += 0xff00; + } + + if (i != -1) + { + clear_bit(keyPress, i); + set_bit(keyRelease, i); + } + + event.evt = KEYRELEASE; + event.key = key; + break; + + case FocusIn: + XAutoRepeatOff(GSdsp); + break; + + case FocusOut: + XAutoRepeatOn(GSdsp); + break; + } + } + + UpdateKeys(pad, keyPress, keyRelease); +} + +bool PollX11Keyboard(char* &temp, u32 &pkey) +{ + GdkEvent *ev = gdk_event_get(); + + if (ev != NULL) + { + if (ev->type == GDK_KEY_PRESS) + { + + if (ev->key.keyval == GDK_Escape) + { + temp = "Unknown"; + pkey = NULL; + } + else + { + temp = KeysymToChar(ev->key.keyval); + pkey = ev->key.keyval; + } + + return true; + } + } + + return false; +} +#else +LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i, pad, keyPress[2] = {0}, keyRelease[2] = {0}; + static bool lbutton = false, rbutton = false; + + switch (msg) + { + case WM_KEYDOWN: + if (lParam & 0x40000000) return TRUE; + + for (pad = 0; pad < 2; ++pad) + { + for (i = 0; i < PADKEYS; i++) + { + if (wParam == conf.keys[pad][i]) + { + set_bit(keyPress[pad], i); + clear_bit(keyRelease[pad], i); + break; + } + } + } + + event.evt = KEYPRESS; + event.key = wParam; + break; + + case WM_KEYUP: + for (pad = 0; pad < 2; ++pad) + { + for (i = 0; i < PADKEYS; i++) + { + if (wParam == conf.keys[pad][i]) + { + set_bit(keyRelease[pad], i); + clear_bit(keyPress[pad], i); + break; + } + } + } + + + event.evt = KEYRELEASE; + event.key = wParam; + break; + + /*case WM_LBUTTONDOWN: + lbutton = true; + break; + + case WM_LBUTTONUP: + g_lanalog[0].x = 0x80; + g_lanalog[0].y = 0x80; + g_lanalog[1].x = 0x80; + g_lanalog[1].y = 0x80; + lbutton = false; + break; + + case WM_RBUTTONDOWN: + rbutton = true; + break; + + case WM_RBUTTONUP: + g_ranalog[0].x = 0x80; + g_ranalog[0].y = 0x80; + g_ranalog[1].x = 0x80; + g_ranalog[1].y = 0x80; + rbutton = false; + break; + + case WM_MOUSEMOVE: + if (lbutton) + { + g_lanalog[0].x = LOWORD(lParam) & 254; + g_lanalog[0].y = HIWORD(lParam) & 254; + g_lanalog[1].x = LOWORD(lParam) & 254; + g_lanalog[1].y = HIWORD(lParam) & 254; + } + if (rbutton) + { + g_ranalog[0].x = LOWORD(lParam) & 254; + g_ranalog[0].y = HIWORD(lParam) & 254; + g_ranalog[1].x = LOWORD(lParam) & 254; + g_ranalog[1].y = HIWORD(lParam) & 254; + } + break;*/ + + case WM_DESTROY: + case WM_QUIT: + event.evt = KEYPRESS; + event.key = VK_ESCAPE; + return GSwndProc(hWnd, msg, wParam, lParam); + + default: + return GSwndProc(hWnd, msg, wParam, lParam); + } + + for (pad = 0; pad < 2; ++pad) + { + UpdateKeys(pad, keyPress, keyRelease) + } + + return TRUE; +} +#endif diff --git a/plugins/zeropad/keyboard.h b/plugins/zeropad/keyboard.h new file mode 100644 index 0000000000..471b8eddcd --- /dev/null +++ b/plugins/zeropad/keyboard.h @@ -0,0 +1,44 @@ +/* ZeroPAD - author: zerofrog(@gmail.com) + * Copyright (C) 2006-2007 + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #ifndef __KEYBOARD_H__ + #define __KEYBOARD_H__ + +#include "zeropad.h" + +#ifdef __LINUX__ + +#include "Linux/linux.h" + +extern Display *GSdsp; +extern void PollForX11KeyboardInput(int pad); +extern bool PollX11Keyboard(char* &temp, u32 &pkey); + +#else + +extern WNDPROC GSwndProc = NULL; +extern HWND GShwnd = NULL; + +#endif + +extern char* KeysymToChar(int keysym); +extern void PollForKeyboardInput(int pad); +extern void SetAutoRepeat(bool autorep); +extern __forceinline int FindKey(int key, int pad); + + #endif \ No newline at end of file diff --git a/plugins/zeropad/zeropad.cpp b/plugins/zeropad/zeropad.cpp index 13582dfe27..493778a0fa 100644 --- a/plugins/zeropad/zeropad.cpp +++ b/plugins/zeropad/zeropad.cpp @@ -23,6 +23,7 @@ #include #include "zeropad.h" +#include "joystick.h" #ifndef _WIN32 @@ -122,6 +123,9 @@ int cmdLen; int ds2mode = 0; // DS Mode at start FILE *padLog = NULL; +pthread_spinlock_t s_mutexStatus; +u32 s_keyPress[2], s_keyRelease[2]; + static void InitLibraryName() { #ifdef _WIN32 @@ -262,14 +266,40 @@ s32 CALLBACK PADopen(void *pDsp) { memset(&event, 0, sizeof(event)); + pthread_spin_init(&s_mutexStatus, PTHREAD_PROCESS_PRIVATE); + s_keyPress[0] = s_keyPress[1] = 0; + s_keyRelease[0] = s_keyRelease[1] = 0; + + JoystickInfo::EnumerateJoysticks(s_vjoysticks); return _PADopen(pDsp); } void CALLBACK PADclose() { + pthread_spin_destroy(&s_mutexStatus); _PADclose(); } +void _PADupdate(int pad) +{ + pthread_spin_lock(&s_mutexStatus); + status[pad] |= s_keyRelease[pad]; + status[pad] &= ~s_keyPress[pad]; + s_keyRelease[pad] = 0; + s_keyPress[pad] = 0; + pthread_spin_unlock(&s_mutexStatus); +} + +void UpdateKeys(int pad, int keyPress, int keyRelease) +{ + pthread_spin_lock(&s_mutexStatus); + s_keyPress[pad] |= keyPress; + s_keyPress[pad] &= ~keyRelease; + s_keyRelease[pad] |= keyRelease; + s_keyRelease[pad] &= ~keyPress; + pthread_spin_unlock(&s_mutexStatus); +} + u32 CALLBACK PADquery() { return 3; // both diff --git a/plugins/zeropad/zeropad.h b/plugins/zeropad/zeropad.h index 8e3127b1f0..f22316ccc4 100644 --- a/plugins/zeropad/zeropad.h +++ b/plugins/zeropad/zeropad.h @@ -183,14 +183,7 @@ void LoadConfig(); void SaveConfig(); void SysMessage(char *fmt, ...); - -inline int FindKey(int key, int pad) -{ - for (int p = 0; p < PADSUBKEYS; p++) - for (int i = 0; i < PADKEYS; i++) - if (key == conf.keys[(PadEnum[pad][p])][i]) return i; - return -1; -} +void UpdateKeys(int pad, int keyPress, int keyRelease); #endif