summaryrefslogtreecommitdiff
path: root/plugins/dfinput/pad.c
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-10-25 14:21:02 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-10-25 14:21:02 +0000
commit7d0f136239c4dcee9f27adf9f7a8c262fcbfe95f (patch)
tree18b5c5292a39fcda65327e2dd32e44e70ef8e5ff /plugins/dfinput/pad.c
parent5408345d8b1cde19a19ddf324d3439ead6e80709 (diff)
downloadpcsxr-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.c1323
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