*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses>.
+ *
+ * this is only pure emulation code to handle analogs,
+ * extracted from dfinput.
*/
-#include "pad.h"
-
-char *PSEgetLibName(void) {
- return _("Gamepad/Keyboard Input");
-}
-
-uint32_t PSEgetLibType(void) {
- return PSE_LT_PAD;
-}
-
-uint32_t PSEgetLibVersion(void) {
- return (1 << 16) | (1 << 8);
-}
-
-long PADinit(long flags) {
- LoadPADConfig();
-
- g.PadState[0].PadMode = 0;
- g.PadState[0].PadID = 0x41;
- g.PadState[1].PadMode = 0;
- g.PadState[1].PadID = 0x41;
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-long PADshutdown(void) {
- PADclose();
- return PSE_PAD_ERR_SUCCESS;
-}
-
-static pthread_t ThreadID;
-static volatile uint8_t TerminateThread = 0;
-
-static void *JoyThread(void *param) {
- while (!TerminateThread) {
- CheckJoy();
- usleep(1000);
- }
- pthread_exit(0);
- return NULL;
-}
-
-long PADopen(unsigned long *Disp) {
- g.Disp = (Display *)*Disp;
+#include <stdint.h>
- 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;
+#include "../../libpcsxcore/psemu_plugin_defs.h"
+#include "main.h"
- if (g.cfg.Threaded) {
- TerminateThread = 0;
-
- if (pthread_create(&ThreadID, NULL, JoyThread, NULL) != 0) {
- // thread creation failed, fallback to polling
- g.cfg.Threaded = 0;
- }
- }
- }
+enum {
+ ANALOG_LEFT = 0,
+ ANALOG_RIGHT,
- g.Opened = 1;
-
- return PSE_PAD_ERR_SUCCESS;
-}
-
-long PADclose(void) {
- if (g.Opened) {
- if (g.cfg.Threaded) {
- TerminateThread = 1;
- pthread_join(ThreadID, NULL);
- }
-
- DestroySDLJoy();
- DestroyKeyboard();
-
- if (SDL_WasInit(SDL_INIT_EVERYTHING & ~SDL_INIT_JOYSTICK)) {
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- } else {
- SDL_Quit();
- }
- }
-
- g.Opened = 0;
-
- return PSE_PAD_ERR_SUCCESS;
-}
+ ANALOG_TOTAL
+};
-long PADquery(void) {
- return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2;
-}
+enum {
+ CMD_READ_DATA_AND_VIBRATE = 0x42,
+ CMD_CONFIG_MODE = 0x43,
+ CMD_SET_MODE_AND_LOCK = 0x44,
+ CMD_QUERY_MODEL_AND_MODE = 0x45,
+ CMD_QUERY_ACT = 0x46, // ??
+ CMD_QUERY_COMB = 0x47, // ??
+ CMD_QUERY_MODE = 0x4C, // QUERY_MODE ??
+ CMD_VIBRATION_TOGGLE = 0x4D,
+};
-static void UpdateInput(void) {
- if (!g.cfg.Threaded) CheckJoy();
- CheckKeyboard();
-}
+static struct {
+ uint8_t PadMode;
+ uint8_t PadID;
+ uint8_t ConfigMode;
+ PadDataS pad;
+} padstate[2];
static uint8_t stdpar[2][8] = {
{0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80},
0x00}
};
-static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0;
+static uint8_t *buf;
-unsigned char PADstartPoll(int pad) {
- CurPad = pad - 1;
- CurByte = 0;
-
- return 0xFF;
-}
+static uint8_t do_cmd(void)
+{
+ PadDataS *pad = &padstate[CurPad].pad;
+ int pad_num = CurPad;
-unsigned char PADpoll(unsigned char value) {
- static uint8_t *buf = NULL;
- uint16_t n;
+ CmdLen = 8;
+ switch (CurCmd) {
+ case CMD_SET_MODE_AND_LOCK:
+ buf = stdmode[pad_num];
+ return 0xF3;
- if (CurByte == 0) {
- CurByte++;
+ case CMD_QUERY_MODEL_AND_MODE:
+ buf = stdmodel[pad_num];
+ buf[4] = padstate[pad_num].PadMode;
+ return 0xF3;
- // 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:
+ buf = unk46[pad_num];
+ return 0xF3;
- case CMD_QUERY_ACT:
- CmdLen = 8;
- buf = unk46[CurPad];
- return 0xF3;
+ case CMD_QUERY_COMB:
+ buf = unk47[pad_num];
+ return 0xF3;
- case CMD_QUERY_COMB:
- CmdLen = 8;
- buf = unk47[CurPad];
- return 0xF3;
+ case CMD_QUERY_MODE:
+ buf = unk4c[pad_num];
+ return 0xF3;
- case CMD_QUERY_MODE:
- CmdLen = 8;
- buf = unk4c[CurPad];
- return 0xF3;
+ case CMD_VIBRATION_TOGGLE:
+ buf = unk4d[pad_num];
+ return 0xF3;
- case CMD_VIBRATION_TOGGLE:
- CmdLen = 8;
- buf = unk4d[CurPad];
+ case CMD_CONFIG_MODE:
+ if (padstate[pad_num].ConfigMode) {
+ buf = stdcfg[pad_num];
return 0xF3;
+ }
+ // else FALLTHROUGH
- case CMD_READ_DATA_AND_VIBRATE:
- default:
- UpdateInput();
-
- n = g.PadState[CurPad].KeyStatus;
- n &= g.PadState[CurPad].JoyKeyStatus;
-
- stdpar[CurPad][2] = n & 0xFF;
- stdpar[CurPad][3] = n >> 8;
-
- if (g.PadState[CurPad].PadMode == 1) {
- CmdLen = 8;
-
- stdpar[CurPad][4] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][0];
- stdpar[CurPad][5] = g.PadState[CurPad].AnalogStatus[ANALOG_RIGHT][1];
- stdpar[CurPad][6] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][0];
- stdpar[CurPad][7] = g.PadState[CurPad].AnalogStatus[ANALOG_LEFT][1];
- } else {
- CmdLen = 4;
- }
+ case CMD_READ_DATA_AND_VIBRATE:
+ default:
+ buf = stdpar[pad_num];
+
+ buf[2] = pad->buttonStatus;
+ buf[3] = pad->buttonStatus >> 8;
+
+ if (padstate[pad_num].PadMode == 1) {
+ buf[4] = pad->rightJoyX;
+ buf[5] = pad->rightJoyY;
+ buf[6] = pad->leftJoyX;
+ buf[7] = pad->leftJoyY;
+ } else {
+ CmdLen = 4;
+ }
- buf = stdpar[CurPad];
- return g.PadState[CurPad].PadID;
- }
+ return padstate[pad_num].PadID;
}
+}
+static void do_cmd2(unsigned char value)
+{
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;
- }
- }
+ padstate[CurPad].ConfigMode = value;
break;
case CMD_SET_MODE_AND_LOCK:
- if (CurByte == 2) {
- g.PadState[CurPad].PadMode = value;
- g.PadState[CurPad].PadID = value ? 0x73 : 0x41;
- }
+ padstate[CurPad].PadMode = value;
+ 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;
- }
+ 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;
- }
+ switch (value) {
+ case 0: // mode 0 - digital mode
+ buf[5] = PSE_PAD_TYPE_STANDARD;
+ break;
+
+ case 1: // mode 1 - analog mode
+ buf[5] = PSE_PAD_TYPE_ANALOGPAD;
+ break;
}
break;
+
+ case CMD_READ_DATA_AND_VIBRATE:
+ if (value == 1 && CurPad == 0 && in_enable_vibration)
+ plat_trigger_vibrate(0);
+ break;
}
+}
- if (CurByte >= CmdLen) return 0;
- return buf[CurByte++];
+static void do_cmd3(unsigned char value)
+{
+ if (in_enable_vibration && CurCmd == CMD_READ_DATA_AND_VIBRATE && CurPad == 0) {
+ if (value >= 0xf0)
+ plat_trigger_vibrate(1);
+ else if (value > 0x40)
+ plat_trigger_vibrate(0);
+ }
}
-static long PADreadPort(int num, PadDataS *pad) {
- UpdateInput();
+#if 0
+#include <stdio.h>
+unsigned char PADpoll_(unsigned char value);
+unsigned char PADpoll(unsigned char value) {
+ unsigned char b = CurByte, r = PADpoll_(value);
+ printf("poll[%d] %02x %02x\n", b, value, r);
+ return r;
+}
+#define PADpoll PADpoll_
+#endif
- pad->buttonStatus = (g.PadState[num].KeyStatus & g.PadState[num].JoyKeyStatus);
+unsigned char PADpoll_pad(unsigned char value) {
- // ePSXe different from pcsx, swap bytes
- pad->buttonStatus = (pad->buttonStatus >> 8) | (pad->buttonStatus << 8);
+ switch (CurByte) {
+ case 0:
+ CurCmd = value;
+ CurByte++;
- switch (g.cfg.PadDef[num].Type) {
- case PSE_PAD_TYPE_ANALOGPAD: // Analog Controller SCPH-1150
- pad->controllerType = PSE_PAD_TYPE_ANALOGPAD;
- pad->rightJoyX = g.PadState[num].AnalogStatus[ANALOG_RIGHT][0];
- pad->rightJoyY = g.PadState[num].AnalogStatus[ANALOG_RIGHT][1];
- pad->leftJoyX = g.PadState[num].AnalogStatus[ANALOG_LEFT][0];
- pad->leftJoyY = g.PadState[num].AnalogStatus[ANALOG_LEFT][1];
- break;
+ // Don't enable Analog/Vibration for a standard pad
+ if (padstate[CurPad].pad.controllerType != PSE_PAD_TYPE_ANALOGPAD)
+ CurCmd = CMD_READ_DATA_AND_VIBRATE;
- case PSE_PAD_TYPE_STANDARD: // Standard Pad SCPH-1080, SCPH-1150
- default:
- pad->controllerType = PSE_PAD_TYPE_STANDARD;
- break;
+ return do_cmd();
+ case 2:
+ do_cmd2(value);
+ break;
+ case 3:
+ do_cmd3(value);
+ break;
}
- return PSE_PAD_ERR_SUCCESS;
-}
-
-long PADreadPort1(PadDataS *pad) {
- return PADreadPort(0, pad);
-}
+ if (CurByte >= CmdLen)
+ return 0xff; // verified
-long PADreadPort2(PadDataS *pad) {
- return PADreadPort(1, pad);
+ return buf[CurByte++];
}
-long PADkeypressed(void) {
- long s;
-
- CheckKeyboard();
+unsigned char PADstartPoll_pad(int pad) {
+ CurPad = pad - 1;
+ CurByte = 0;
- s = g.KeyLeftOver;
- g.KeyLeftOver = 0;
+ if (pad == 1)
+ PAD1_readPort1(&padstate[0].pad);
+ else
+ PAD2_readPort2(&padstate[1].pad);
- return s;
+ return 0xFF;
}
-#ifndef _MACOSX
+void pad_init(void)
+{
+ int i;
-long PADconfigure(void) {
- if (fork() == 0) {
- execl("cfg/cfgDFInput", "cfgDFInput", NULL);
- exit(0);
- }
- return PSE_PAD_ERR_SUCCESS;
-}
+ PAD1_readPort1(&padstate[0].pad);
+ PAD2_readPort2(&padstate[1].pad);
-void PADabout(void) {
- if (fork() == 0) {
- execl("cfg/cfgDFInput", "cfgDFInput", "-about", NULL);
- exit(0);
+ for (i = 0; i < 2; i++) {
+ padstate[i].PadID = padstate[i].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD ? 0x73 : 0x41;
+ padstate[i].PadMode = padstate[i].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD;
}
}
-
-#endif
-
-long PADtest(void) {
- return PSE_PAD_ERR_SUCCESS;
-}