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
This commit is contained in:
arcum42 2009-05-29 06:33:56 +00:00
parent 65b90bce83
commit 71480b3124
13 changed files with 568 additions and 433 deletions

View File

@ -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<JoystickInfo*>::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<JoystickInfo*>::iterator itjoy;
char *tmp;
if (PollKeyboard(tmp, conf.keys[pad][key]))
if (PollX11Keyboard(tmp, conf.keys[pad][key]))
{
strcpy(str, tmp);
captured = true;

View File

@ -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 <string.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <pthread.h>
#include "joystick.h"
#include "zeropad.h"
extern "C"
{

View File

@ -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

View File

@ -246,6 +246,10 @@
RelativePath=".\win.cpp"
>
</File>
<File
RelativePath=".\gui.cpp"
>
</File>
<File
RelativePath="..\zeropad.cpp"
>
@ -254,12 +258,20 @@
RelativePath="..\analog.cpp"
>
</File>
<File
RelativePath="..\keyboard.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\win.h"
>
</File>
<File
RelativePath="..\PS2Edefs.h"
>
@ -280,6 +292,10 @@
RelativePath="..\analog.h"
>
</File>
<File
RelativePath="..\keyboard.h"
>
</File>
<File
RelativePath="..\bitwise.h"
>

View File

@ -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);
}

View File

@ -16,22 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "resource.h"
#include "../zeropad.h"
#include <pthread.h>
#include <string>
#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;

View File

@ -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 <string.h>
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "resource.h"
#include "../zeropad.h"
#include <pthread.h>
#include <string>
extern void SaveConfig();
extern void LoadConfig();
extern void SysMessage(char *fmt, ...);
extern LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

View File

@ -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<JoystickInfo*>& vjoysticks)
{

View File

@ -139,4 +139,5 @@ extern int s_selectedpad;
extern vector<JoystickInfo*> s_vjoysticks;
extern void UpdateJoysticks();
extern const char *HatName(int value);
extern bool JoystickIdWithinBounds(int joyid);
#endif

View File

@ -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

View File

@ -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

View File

@ -23,6 +23,7 @@
#include <stdarg.h>
#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

View File

@ -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