diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-10-25 14:21:02 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2009-10-25 14:21:02 +0000 |
| commit | 7d0f136239c4dcee9f27adf9f7a8c262fcbfe95f (patch) | |
| tree | 18b5c5292a39fcda65327e2dd32e44e70ef8e5ff /plugins/dfinput/pad.c | |
| parent | 5408345d8b1cde19a19ddf324d3439ead6e80709 (diff) | |
| download | pcsxr-7d0f136239c4dcee9f27adf9f7a8c262fcbfe95f.tar.gz | |
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@32889 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins/dfinput/pad.c')
| -rw-r--r-- | plugins/dfinput/pad.c | 1323 |
1 files changed, 397 insertions, 926 deletions
diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c index d67a3a7b..564aa324 100644 --- a/plugins/dfinput/pad.c +++ b/plugins/dfinput/pad.c @@ -1,1001 +1,472 @@ /* - * Pad for Psemu Pro like Emulators - * This is the plugin + * Copyright (c) 2009, Wei Mingzhi <whistler@openoffice.org>. + * All Rights Reserved. * - * Modified for PCSX-df by Ryan Schultz + * 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 3 of the License, or + * (at your option) any later version. * - * Written by Erich Kitzmuller <ammoq@ammoq.com> - * Based on padXwin by linuzappz <linuzappz@hotmail.com> + * 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. * - * Copyright 2002,2003 by Erich Kitzmuller - * - * 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 + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses>. */ -#include "config.h" +#include "pad.h" -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#ifdef __linux__ -#include <linux/joystick.h> -#endif -#include <sys/stat.h> -#include <sys/time.h> -#include <unistd.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/keysym.h> -#include <X11/XKBlib.h> -#include <pthread.h> -#include <errno.h> -#include "padjoy.h" -#ifdef ENABLE_NLS -#include <libintl.h> -#include <locale.h> -#define _(x) gettext(x) -#define N_(x) (x) -#else -#define _(x) (x) -#define N_(x) (x) -#endif - -#ifdef __linux__ -char *LibName = N_("Gamepad/Keyboard Input"); +char *PSEgetLibName(void) { +#ifdef EPSXE + return _("Gamepad/Keyboard Input (ePSXe)"); #else -char *LibName = N_("Keyboard Input"); + return _("Gamepad/Keyboard Input"); #endif - -// Prototypes -static void loadConfig(); -static void *thread_check_joydevice(void *arg); -static void initPadtime(); -static PadJoyEvent *EventCode2PadJoyEvent(EventCode p_e); - -// Filenames for device files, e.g. "/dev/input/js0" -static char devicefilename[MAXDEVICES][FILENAME_MAX+1] = {"/dev/input/js0", "/dev/input/js1"}; - -// File desciptors for device files -static int devicefile[MAXDEVICES] = { -1, -1 }; - -// Use Threading for joy device input? -static int use_threads = 1; -static pthread_t joy_thread; -static int die_thread_die = 0; - -// Emulate Dualshock(TM) analog pad? -static int use_analog = 0; - -// any joydevice open? -static int joydevice_open = 0; - -// initialisation already done? -static int init_done = 0; - -// calibration data -int minzero[MAXAXES]; -int maxzero[MAXAXES]; - -// axes status - so only changing status are reported -int axestatus[MAXDEVICES][MAXAXES]; - -// Assignment of PSX buttons to Events -static EventCode PadButtons[MAXDEVICES][MAXPSXBUTTONS] = -{ - { - KEY_EVENT(XK_e), // L2 - KEY_EVENT(XK_t), // R2 - KEY_EVENT(XK_w), // L1 - KEY_EVENT(XK_r), // R1 - KEY_EVENT(XK_d), // Triangle - KEY_EVENT(XK_x), // Circle - KEY_EVENT(XK_z), // Cross - KEY_EVENT(XK_s), // Square - KEY_EVENT(XK_c), // Select - NO_EVENT, // Left Analog - NO_EVENT, // Right Analog - KEY_EVENT(XK_v), // Start - KEY_EVENT(XK_Up), // Up - KEY_EVENT(XK_Right), // Right - KEY_EVENT(XK_Down), // Down - KEY_EVENT(XK_Left), // Left - NO_EVENT, // Left Analog X - NO_EVENT, // Left Analog Y - NO_EVENT, // Right Analog X - NO_EVENT // Right Analog Y - }, - { - NO_EVENT, // L2 - NO_EVENT, // R2 - NO_EVENT, // L1 - NO_EVENT, // R1 - NO_EVENT, // Triangle - NO_EVENT, // Circle - NO_EVENT, // Cross - NO_EVENT, // Square - NO_EVENT, // Select - NO_EVENT, // Left Analog - NO_EVENT, // Right Analog - NO_EVENT, // Start - NO_EVENT, // Up - NO_EVENT, // Right - NO_EVENT, // Down - NO_EVENT, // Left - NO_EVENT, // Left Analog X - NO_EVENT, // Left Analog Y - NO_EVENT, // Right Analog X - NO_EVENT // Right Analog Y - } -}; - -static Display *Dsp; -static Atom wmprotocols, wmdelwindow; - -static EventCode macroLaunch[MAXDEVICES][MAXMACROS]; -static EventCode macroEvents[MAXDEVICES][MAXMACROS][MAXMACROLENGTH]; -static long macroInterval[MAXDEVICES][MAXMACROS][MAXMACROLENGTH]; -static int macroActive[MAXDEVICES]; -static int macroIndex[MAXDEVICES]; -static long macroNext[MAXDEVICES]; - -unsigned short PadStat[MAXDEVICES] = {0xffff, 0xffff}; - -int AnalogValue[MAXDEVICES][MAXPSXBUTTONS-4] = {{127,127,127,127}, {127,127,127,127}}; - -char *PSEgetLibName(void) { - return _(LibName); } uint32_t PSEgetLibType(void) { - return 8; // PSE_LT_PAD + return PSE_LT_PAD; } uint32_t PSEgetLibVersion(void) { - return 1 << 16; -} - -void init_macros() { - int i,j; - - for (i=0; i<MAXDEVICES; i++) { - for (j=0; j<MAXMACROS; j++) { - macroLaunch[i][j] = NO_EVENT; - macroEvents[i][j][0] = NO_EVENT; - macroInterval[i][j][0] = 0; - } - macroActive[i] = -1; - macroIndex[i] = 0; - macroNext[i] = 0; - } + return (1 << 16) | (1 << 8); } long PADinit(long flags) { - int i,j; + LoadConfig(); - init_macros(); - initPadtime(); - for (i = 0; i < MAXDEVICES; i++) { - maxzero[i] = 250; - minzero[i] = -250; + g.PadState[0].PadMode = 0; + g.PadState[0].PadID = 0x41; + g.PadState[1].PadMode = 0; + g.PadState[1].PadID = 0x41; - for (j = 0; j < MAXAXES; j++) { - axestatus[i][j] = AXESTS_UNKNOWN; - } - } - loadConfig(); - - return 0; + return PSE_PAD_ERR_SUCCESS; } long PADshutdown(void) { - return 0; + PADclose(); + return PSE_PAD_ERR_SUCCESS; } -long PADopen(unsigned long *Disp) { - int i,j; - int res; - PadJoyEvent *pje; - - if (init_done) { -// fprintf(stderr, "DFInput warning: device already initialized.\n"); - return 0; - } - - Dsp = (Display *)*Disp; - XkbSetDetectableAutoRepeat(Dsp, 1, NULL); - - // TODO: find a way to grab the window, and set protocol WM_DELETE_WINDOW if not already set by the video plugin - wmprotocols = XInternAtom(Dsp,"WM_PROTOCOLS",0); - wmdelwindow = XInternAtom(Dsp,"WM_DELETE_WINDOW",0); - //XSetWMProtocols(Dsp, window, &wmdelwindow, 1); //need window! - - joydevice_open = 0; - -#ifdef __linux__ - for (i = 0; i < MAXDEVICES; i++) { - if (devicefilename[i][0]) { - devicefile[i] = open(devicefilename[i], O_RDONLY); - if (devicefile[i] == -1) { - fprintf(stderr, "DFInput error: could not open device %s!\n", devicefilename[i]); - } - else { - joydevice_open = 1; - } - } - else { - devicefile [i] = -1; - } - } -#endif +static pthread_t ThreadID; +static uint8_t TerminateThread = 0; - for (i = 0; i < MAXDEVICES; i++) { - for (j = 0; j < MAXAXES; j++) { - axestatus[i][j] = AXESTS_UNUSED; - } - } - - for (i=0; i<MAXDEVICES; i++) { - for (j = 0; j < MAXPSXBUTTONS; j++) { - pje = EventCode2PadJoyEvent(PadButtons[i][j]); - - if (pje->event_type == EVENTTYPE_AXISPLUS || pje->event_type == EVENTTYPE_AXISMINUS) { - axestatus[pje->pad][pje->no] = AXESTS_UNKNOWN; - } -#ifdef __linux__ - else if (pje->event_type == EVENTTYPE_ANALOG && use_analog) { - axestatus[pje->pad][pje->no] = AXESTS_ANALOG; - } -#endif - } - } - -#ifdef __linux__ - if (use_threads) { - die_thread_die = 0; - if (joydevice_open) { - fprintf(stderr, "DFInput: starting thread...\n"); - sleep(1); - res = pthread_create(&joy_thread, NULL, thread_check_joydevice, (void *) NULL); - - if (res!=0) { - fprintf(stderr, "DFInput warning: thread failure, switching to polling!\n"); - use_threads = 0; - } - } - } -#endif +static void *JoyThread(void *param) { + while (!TerminateThread) { + CheckJoy(); + usleep(1000); + } + pthread_exit(0); + return NULL; +} - init_done = 1; +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 0; + return PSE_PAD_ERR_SUCCESS; } long PADclose(void) { - int i; - -#ifdef __linux__ - for (i=0; i<2; i++) { - if (devicefile[i] > -1) { - close (devicefile[i]); - } - } - - if (use_threads) { - die_thread_die = 1; - if (joydevice_open) { - pthread_join(joy_thread, (void **) NULL); - } - } -#endif - - init_done = 0; + 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(); + } + } - XAutoRepeatOn(Dsp); + g.Opened = 0; - return 0; + return PSE_PAD_ERR_SUCCESS; } long PADquery(void) { - return 3; // both pads + return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; } -static long firstsecond = 0; - -static void initPadtime() { - struct timeval tv; - gettimeofday(&tv, NULL); - firstsecond = tv.tv_sec; +static void UpdateInput(void) { + if (!g.cfg.Threaded) CheckJoy(); + CheckKeyboard(); } -// construct a time on our own -long getPadtime() { - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec-firstsecond)*10000+tv.tv_usec/100; -} +#ifndef EPSXE -// get pending events -static int getPendingEvents(int millisecondstowait, EventCode *events, int maxevents, int checkJoydevice, int checkXKeyboard, long *timing) { - fd_set rfds; - int retval; - int i; - int md; - int eventsread=0; - XEvent xe; - XClientMessageEvent *xce; - int cntopen; - struct timeval tv; - int oldstatus; - -#ifdef __linux__ - struct js_event je; - - if (checkJoydevice) { - FD_ZERO(&rfds); - md = -1; - cntopen=0; - for (i=0; i<MAXDEVICES; i++) { - if (devicefile[i] > -1) { - FD_SET(devicefile[i], &rfds); - cntopen++; - } - if (devicefile[i] > md) md = devicefile[i]; - } - tv.tv_sec = millisecondstowait / 1000; - tv.tv_usec = 1000 * (millisecondstowait % 1000); - - retval = select(md + 1, &rfds, NULL, NULL, &tv); - - while (retval && eventsread < maxevents - 2 * checkXKeyboard) { - for (i = 0; i < MAXDEVICES; i++) { - if (devicefile[i] > -1 && FD_ISSET(devicefile[i], &rfds)) { - read (devicefile[i], &je, 8); - - if (je.type == JS_EVENT_AXIS && je.number < MAXAXES) { - if (axestatus[i][je.number] == AXESTS_ANALOG) { - /* this axe should be reported analog */ - events[eventsread++] = ANALOGAXIS_EVENT(i,je.number, (je.value + 32768) >> 8); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - - } - else if (je.value > maxzero[i]) { - if (axestatus[i][je.number] != AXESTS_PLUS && - axestatus[i][je.number] != AXESTS_UNUSED) { - - oldstatus = axestatus[i][je.number]; - - axestatus[i][je.number] = AXESTS_PLUS; - - events[eventsread++] = AXISPLUS_EVENT(i, je.number); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread==maxevents) return eventsread; - - if (oldstatus == AXESTS_MINUS) { - events[eventsread++] = RELEASE_EVENT + AXISMINUS_EVENT(i, je.number); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - } - - } - } - else if (je.value < minzero[i]) { - if (axestatus[i][je.number] != AXESTS_MINUS && - axestatus[i][je.number] != AXESTS_UNUSED) { - - oldstatus = axestatus[i][je.number]; - - axestatus[i][je.number] = AXESTS_MINUS; - - events[eventsread++] = AXISMINUS_EVENT(i, je.number); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - - if (oldstatus == AXESTS_PLUS) { - events[eventsread++] = RELEASE_EVENT+AXISPLUS_EVENT(i, je.number); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - } - } - } - else { - if (axestatus[i][je.number] != AXESTS_CENTER && - axestatus[i][je.number] != AXESTS_UNUSED) { - - oldstatus = axestatus[i][je.number]; - - axestatus[i][je.number] = AXESTS_CENTER; - - if (oldstatus == AXESTS_PLUS) { - events[eventsread++] = RELEASE_EVENT+AXISPLUS_EVENT(i,je.number); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - } - else if (oldstatus == AXESTS_MINUS) { - events[eventsread++] = RELEASE_EVENT+AXISMINUS_EVENT(i,je.number); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - } - } - } - } - else if (je.type == JS_EVENT_BUTTON && je.number<MAXBUTTONS) { - events[eventsread++] = (je.value ? 0 : RELEASE_EVENT) + BUTTON_EVENT(i, je.number); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - } - } - } - tv.tv_sec = 0; - tv.tv_usec = 0; - - retval = select(md + 1, &rfds, NULL, NULL, &tv); - } - - } -#endif +static uint8_t stdpar[2][20] = { + {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; - if (checkXKeyboard) { - while ((i = XPending(Dsp))) { - while (i--) { - XNextEvent(Dsp, &xe); - switch (xe.type) { - case KeyPress: - events[eventsread++] = KEY_EVENT(XLookupKeysym((XKeyEvent *)&xe, 0)); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - break; - case KeyRelease: - events[eventsread++] = RELEASE_EVENT + KEY_EVENT(XLookupKeysym((XKeyEvent *)&xe, 0)); - if (timing) { - (*timing) = getPadtime(); - timing++; - } - if (eventsread == maxevents) return eventsread; - break; - case ClientMessage: - xce = (XClientMessageEvent *)&xe; - if (xce->message_type == wmprotocols && (Atom)xce->data.l[0] == wmdelwindow) { - events[eventsread++] = KEY_EVENT(XK_Escape); - if (eventsread == maxevents) return eventsread; - } - break; -/* - case FocusIn: - XAutoRepeatOff(Dsp); - break; - case FocusOut: - XAutoRepeatOn(Dsp); - break; -*/ - } - } - } - } - - return eventsread; -} +static uint8_t unk46[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}, + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A} +}; -// Key Event not used... -static EventCode keyLeftOver = NO_EVENT; - -static void CheckPads(int checkJoydevice, int checkXKeyboard, int blocking) { - EventCode events[MAXCNT]; - int cnt; - int release; - EventCode e; - int i,j,k,l; - int notfound; - long now; - int v; - - if (checkJoydevice || checkXKeyboard) { - cnt = getPendingEvents(blocking<<8, events, MAXCNT, checkJoydevice, checkXKeyboard, NULL); - } - else { - cnt = 0; - } - - // more events come from the macros - // only process makros when blocking is not set, since - // this cannot be done by the joy device thread - - if (!blocking) { - now= -1; - for (j = 0; j < MAXDEVICES; j++) { - if (macroActive[j] > -1) { - if (now < 0) { - now = getPadtime(); - } - - while (now >= macroNext[j] && cnt < MAXCNT && macroActive[j] > -1) { - events[cnt++]=macroEvents[j][macroActive[j]][macroIndex[j]]; - macroIndex[j]++; - if (macroIndex[j] == MAXMACROLENGTH || macroEvents[j][macroActive[j]][macroIndex[j]] == NO_EVENT) { - macroActive[j] = -1; - } - else { - macroNext[j] += macroInterval[j][macroActive[j]][macroIndex[j]]; - } - } - } - } - } - - for (i = 0; i < cnt; i++) { - e = events[i]; - if (e >= RELEASE_EVENT) { - release = 1; - e -= RELEASE_EVENT; - } - else { - release = 0; - } - - notfound = 1; - if (e >= FIRST_ANALOG_EVENT) { - v = e & 0xff; - e -= v; - for (j = 0; j < MAXDEVICES && notfound; j++) { - for (k = 16; k < MAXPSXBUTTONS && notfound; k++) { - if (PadButtons[j][k] == e) { - AnalogValue[j][k - 16] = v; - notfound = 0; - } - } - } - } - else - { - for (j=0; j<MAXDEVICES && notfound; j++) { - for (k=0; k<MAXPSXBUTTONS && notfound; k++) { - if (PadButtons[j][k] == e) { - notfound = 0; - if (release) { - PadStat[j]|=(1<<k); - } - else { - PadStat[j]&=~(1<<k); - } - } - } - for (k=0; k<MAXMACROS && notfound; k++) { - if (macroLaunch[j][k] == e) { - notfound=0; - if (release) { - // release all buttons pressed by the macro - for (l=macroIndex[j]; l<MAXMACROLENGTH && macroEvents[j][macroActive[j]][l] != NO_EVENT; l++) { - if (macroEvents[j][macroActive[j]][l] >= RELEASE_EVENT) { - if (cnt<MAXCNT) { - events[cnt++]=macroEvents[j][macroActive[j]][l]; - } - } - - } - - macroActive[j]= -1; // stop Makro from running - } - else { - macroActive[j]=k; - macroIndex[j]=0; - macroNext[j]=getPadtime(); - } - } - } - } - } - if (notfound && e < FIRST_JOY_EVENT) { - keyLeftOver = e + (release << 30); - } - } -} +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} +}; -long PADreadPort1(PadDataS *pad) { - if (!use_threads) { - CheckPads(joydevice_open, 1, 0); - } - else { - CheckPads(0, 1, 0); - } - - pad->buttonStatus = PadStat[0]; -#ifdef __linux__ - if (use_analog) { - pad->controllerType = 7; // analog Pad - pad->leftJoyX = AnalogValue[0][0]; - pad->leftJoyY = AnalogValue[0][1]; - pad->rightJoyX = AnalogValue[0][2]; - pad->rightJoyY = AnalogValue[0][3]; - } - else { -#endif - pad->controllerType = 4; // standard -#ifdef __linux__ - } -#endif - // ePSXe different from pcsx, swap bytes - pad->buttonStatus = (pad->buttonStatus>>8)|(pad->buttonStatus<<8); +static uint8_t unk4d[2][8] = { + {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; - return 0; -} +static uint8_t stdcfg[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; -long PADreadPort2(PadDataS *pad) { - if (!use_threads) { - CheckPads(joydevice_open, 1, 0); - } - else { - CheckPads(0, 1, 0); - } - - pad->buttonStatus = PadStat[1]; -#ifdef __linux__ - if (use_analog) { - pad->controllerType = 7; // analog Pad - pad->leftJoyX = AnalogValue[1][0]; - pad->leftJoyY = AnalogValue[1][1]; - pad->rightJoyX = AnalogValue[1][2]; - pad->rightJoyY = AnalogValue[1][3]; - } - else { -#endif - pad->controllerType = 4; // standard -#ifdef __linux__ - } -#endif +static uint8_t stdmode[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; - // ePSXe different from pcsx, swap bytes - pad->buttonStatus = (pad->buttonStatus>>8)|(pad->buttonStatus<<8); +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} +}; - return 0; -} +static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0; -long PADkeypressed(void) { - int ksym; +unsigned char PADstartPoll(int pad) { + CurPad = pad - 1; + CurByte = 0; - CheckPads(0, 1, 1); + 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 = 20; + + stdpar[CurPad][4] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][ANALOG_X]; + stdpar[CurPad][5] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][ANALOG_Y]; + stdpar[CurPad][6] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][ANALOG_X]; + stdpar[CurPad][7] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][ANALOG_Y]; + + switch (stdpar[CurPad][3]) { + case 0xBF: // X + stdpar[CurPad][14] = 0xFF; + break; + + case 0xDF: // Circle + stdpar[CurPad][13] = 0xFF; + break; + + case 0xEF: // Triangle + stdpar[CurPad][12] = 0xFF; + break; + + case 0x7F: // Square + stdpar[CurPad][15] = 0xFF; + break; + + case 0xFB: // L1 + stdpar[CurPad][16] = 0xFF; + break; + + case 0xF7: // R1 + stdpar[CurPad][17] = 0xFF; + break; + + case 0xFE: // L2 + stdpar[CurPad][18] = 0xFF; + break; + + case 0xFD: // R2 + stdpar[CurPad][19] = 0xFF; + break; + + default: + stdpar[CurPad][14] = 0x00; // Not pressed + stdpar[CurPad][13] = 0x00; // Not pressed + stdpar[CurPad][12] = 0x00; // Not pressed + stdpar[CurPad][15] = 0x00; // Not pressed + stdpar[CurPad][16] = 0x00; // Not pressed + stdpar[CurPad][17] = 0x00; // Not pressed + stdpar[CurPad][18] = 0x00; // Not pressed + stdpar[CurPad][19] = 0x00; // Not pressed + break; + } + + switch (stdpar[CurPad][2] >> 4) { + case 0x0E: // UP + stdpar[CurPad][10] = 0xFF; + break; + + case 0x0B: // DOWN + stdpar[CurPad][11] = 0xFF; + break; + + case 0x07: // LEFT + stdpar[CurPad][9] = 0xFF; + break; + + case 0x0D: // RIGHT + stdpar[CurPad][8] = 0xFF; + break; + + default: + stdpar[CurPad][8] = 0x00; // Not pressed + stdpar[CurPad][9] = 0x00; // Not pressed + stdpar[CurPad][10] = 0x00; // Not pressed + stdpar[CurPad][11] = 0x00; // Not pressed + break; + } + } else { + CmdLen = 4; + } - if (keyLeftOver == NO_EVENT) return 0; + buf = stdpar[CurPad]; + return g.PadState[CurPad].PadID; + } + } - ksym = keyLeftOver-FIRST_KEY_EVENT; - keyLeftOver = NO_EVENT; + switch (CurCmd) { + 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) { + g.PadState[CurPad].PadMode = value; + g.PadState[CurPad].PadID = value ? 0x73 : 0x41; + } + 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; + } - return ksym; + if (CurByte >= CmdLen) return 0; + return buf[CurByte++]; } -#ifdef __linux__ +#endif -static void *thread_check_joydevice(void *arg) { - while (!die_thread_die) { - CheckPads(1, 0, 1); - } - return NULL; -} +static long PADreadPort(int num, PadDataS *pad) { + UpdateInput(); -#endif + pad->buttonStatus = (g.PadState[num].KeyStatus & g.PadState[num].JoyKeyStatus); -// analyse Eventcode -static PadJoyEvent *EventCode2PadJoyEvent(EventCode p_e) { - static PadJoyEvent event; - EventCode e; - int i,p; - - event.event_type = EVENTTYPE_NONE; - event.pad = 0; - event.no = 0; - event.value = 0; - - if (!p_e) { - return &event; - } - - e = p_e; - - if (e > RELEASE_EVENT) { - event.value = 0; - e -= RELEASE_EVENT; - } - else { - event.value = 1; - } - - if (e && e<FIRST_JOY_EVENT) { - event.event_type = EVENTTYPE_KEY; - event.no = e; - return &event; - } - - if (e >= FIRST_ANALOG_EVENT) { - event.event_type = EVENTTYPE_ANALOG; - event.pad = (e-FIRST_ANALOG_EVENT)/(256*MAXAXES); - event.no = (e-ANALOGAXIS_EVENT(event.pad,0,0))/256; - event.value = e & 0xff; - return &event; - } - - - for (p=0; p<MAXDEVICES; p++) { - for (i=0; i<MAXAXES; i++) { - if (e == AXISPLUS_EVENT(p,i)) { - event.event_type = EVENTTYPE_AXISPLUS; - event.pad = p; - event.no = i; - return &event; - } - if (e == AXISMINUS_EVENT(p,i)) { - event.event_type = EVENTTYPE_AXISMINUS; - event.pad = p; - event.no = i; - return &event; - } - } - - for (i=0; i<MAXBUTTONS; i++) { - if (e == BUTTON_EVENT(p,i)) { - event.event_type = EVENTTYPE_BUTTON; - event.pad = p; - event.no = i; - return &event; - } - } - } - - return &event; -} +#ifdef EPSXE + // ePSXe different from pcsx, swap bytes + pad->buttonStatus = (pad->buttonStatus >> 8) | (pad->buttonStatus << 8); +#endif + 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][ANALOG_X]; + pad->rightJoyY = g.PadState[num].AnalogStatus[ANALOG_RIGHT][ANALOG_Y]; + pad->leftJoyX = g.PadState[num].AnalogStatus[ANALOG_LEFT][ANALOG_X]; + pad->leftJoyY = g.PadState[num].AnalogStatus[ANALOG_LEFT][ANALOG_Y]; + break; + + case PSE_PAD_TYPE_STANDARD: // Standard Pad SCPH-1080, SCPH-1150 + default: + pad->controllerType = PSE_PAD_TYPE_STANDARD; + break; + } -// reversal of EventCode2String -static EventCode String2EventCode(char *s) { - static char buffer[256]; - int i,p; - char *q; - char push_release; - EventCode e; - - if (s[0] >= '0' && s[0] <= '9') return atoi(s); // allow numeric input - - e=0; - push_release = 'P'; - - switch(s[0]) { - case 'K': - push_release = s[1]; - strncpy(buffer, s + 3, 255); - q=buffer; - i=1; - while (*q) { - if (*q=='"') i = !i; - if (*q==' ' && !i) - *q='\0'; - else - q++; - } - if (s[2]=='"' && buffer[0] && buffer[strlen(buffer)-1]=='"') { - buffer[strlen(buffer)-1] = '\0'; - e = KEY_EVENT(XStringToKeysym(buffer)); - } - break; - case 'A': - if (s[1] >= '0' && s[1] <= '1' && strlen(s) >= 5) { - p = s[1] - '0'; - push_release = s[2]; - i = atoi(s+3); - q=s+3; - while (*q && *q != '+' && *q != '-') q++; - if (*q == '+') - e = AXISPLUS_EVENT(p,i); - else if (*q == '-') - e = AXISMINUS_EVENT(p,i); - } - break; - case 'B': - if (s[1] >= '0' && s[1] <= '1' && strlen(s) >= 4) { - p = s[1] - '0'; - push_release = s[2]; - i = atoi(s + 3); - e = BUTTON_EVENT(p, i); - } - break; - case 'X': - if (s[1] >= '0' && s[1] <= '1' && strlen(s) >= 5) { - p = s[1] - '0'; - i = atoi(s + 3); - q = s + 3; - while (*q && *q != 'v') q++; - if (*q == 'v') - e = ANALOGAXIS_EVENT(p,i,atoi(q + 1)); - } - break; - } - - if (push_release == 'R') - return e + RELEASE_EVENT; - else - return e; + return PSE_PAD_ERR_SUCCESS; } -static void loadConfig() { - FILE *f; - int i; - char line[FILENAME_MAX+30]; - int pad=0; - int macronr=0; - char *val; - - f = fopen("dfinput.cfg", "r"); - if (f == NULL) { -// fprintf(stderr, "DFInput warning: config file not found.\n"); - return; - } - - while(!feof(f)) { - fgets(line, FILENAME_MAX+29, f); - i=strlen(line)-1; - while (i>0 && line[i]<32) line[i--]='\0'; - - val=NULL; - while(i>0) { - if (line[i]=='=') val = line+(i+1); - i--; - } - if (val) { - while (*val==' ') val++; - } - - if (!strcmp(line, "[general]")) { - // nothing to do - } - else if (!strncmp(line, "use_threads", 11)) { - use_threads = atoi(val); - } - else if (!strncmp(line, "use_analog", 10)) { - use_analog = atoi(val); - } - - else if (!strcmp(line, "[pad 1]")) { - pad = 0; - } - else if (!strcmp(line, "[pad 2]")) { - pad = 1; - } - else if (!strncmp(line, "[macro ", 7)) { - macronr = atoi(line+7)-1; - if (macronr<0 || macronr>=MAXMACROS) macronr=0; - } - else if (!strncmp(line, "devicefilename", 14)) { - strcpy(devicefilename[pad], val); - } - else if (!strncmp(line, "minzero", 7)) { - minzero[pad] = atoi(val); - } - else if (!strncmp(line, "maxzero", 7)) { - maxzero[pad] = atoi(val); - } - else if (!strncmp(line, "event_l2", 8)) PadButtons[pad][0] = String2EventCode(val); - else if (!strncmp(line, "event_r2", 8)) PadButtons[pad][1] = String2EventCode(val); - else if (!strncmp(line, "event_l1", 8)) PadButtons[pad][2] = String2EventCode(val); - else if (!strncmp(line, "event_r1", 8)) PadButtons[pad][3] = String2EventCode(val); - else if (!strncmp(line, "event_triangle", 14)) PadButtons[pad][4] = String2EventCode(val); - else if (!strncmp(line, "event_circle", 12)) PadButtons[pad][5] = String2EventCode(val); - else if (!strncmp(line, "event_cross", 11)) PadButtons[pad][6] = String2EventCode(val); - else if (!strncmp(line, "event_square", 12)) PadButtons[pad][7] = String2EventCode(val); - else if (!strncmp(line, "event_select", 12)) PadButtons[pad][8] = String2EventCode(val); - else if (!strncmp(line, "event_lanalog", 13)) PadButtons[pad][9] = String2EventCode(val); - else if (!strncmp(line, "event_ranalog", 13)) PadButtons[pad][10] = String2EventCode(val); - else if (!strncmp(line, "event_start", 11)) PadButtons[pad][11] = String2EventCode(val); - else if (!strncmp(line, "event_up", 8)) PadButtons[pad][12] = String2EventCode(val); - else if (!strncmp(line, "event_right", 11)) PadButtons[pad][13] = String2EventCode(val); - else if (!strncmp(line, "event_down", 10)) PadButtons[pad][14] = String2EventCode(val); - else if (!strncmp(line, "event_left", 10)) PadButtons[pad][15] = String2EventCode(val); - else if (!strncmp(line, "event_lanax", 11)) PadButtons[pad][16] = String2EventCode(val); - else if (!strncmp(line, "event_lanay", 11)) PadButtons[pad][17] = String2EventCode(val); - else if (!strncmp(line, "event_ranax", 11)) PadButtons[pad][18] = String2EventCode(val); - else if (!strncmp(line, "event_ranay", 11)) PadButtons[pad][19] = String2EventCode(val); - else if (!strncmp(line, "event_launch", 12)) macroLaunch[pad][macronr] = String2EventCode(val); - else if (!strncmp(line, "events", 6)) { - i=0; - while (*val) { - macroEvents[pad][macronr][i++]=String2EventCode(val); - while (*val && *val!=' ') val++; - if (*val==' ') val++; - } - macroEvents[pad][macronr][i]=NO_EVENT; - } - else if (!strncmp(line, "interval", 8)) { - i=0; - while (*val) { - macroInterval[pad][macronr][i++]=atol(val); - while (*val && *val!=' ') val++; - if (*val==' ') val++; - } - } -// else fprintf(stderr, "DFInput error: can't interpret %s\n", line); - } +long PADreadPort1(PadDataS *pad) { + return PADreadPort(0, pad); } -long PADconfigure(void) { - if (fork() == 0) { - execl("cfg/cfgDFInput", "cfgDFInput", NULL); - exit(0); - } - return 0; +long PADreadPort2(PadDataS *pad) { + return PADreadPort(1, pad); } +long PADkeypressed(void) { + long s; + + CheckKeyboard(); -/*---------------------------------------------------------------------*/ -/* About dialogue stuff */ -/*---------------------------------------------------------------------*/ + s = g.KeyLeftOver; + g.KeyLeftOver = 0; + return s; +} -void PADabout(void) { - if (fork() == 0) { - execl("cfg/cfgDFInput", "cfgDFInput", "-about", NULL); - } +long PADconfigure(void) { + if (fork() == 0) { + execl("cfg/cfgDFInput", "cfgDFInput", NULL); + exit(0); + } + return PSE_PAD_ERR_SUCCESS; } -#ifdef __linux__ +void PADabout(void) { + if (fork() == 0) { + execl("cfg/cfgDFInput", "cfgDFInput", "-about", NULL); + exit(0); + } +} long PADtest(void) { - int i; - int f; - - int r=1; - - loadConfig(); - for (i=0; i<2; i++) { - if (devicefilename[i][0]) { - r = 0; - f = open(devicefilename[i], O_RDONLY); - if (f == -1) { - return -1; - } - close (f); - } - } - - return r; + return PSE_PAD_ERR_SUCCESS; } - -#endif |
