don't use __ARM_ARCH_7A__
[pcsx_rearmed.git] / plugins / dfinput / pad.c
index a0207aa..7e00a11 100644 (file)
  *
  * 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 "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},
@@ -175,218 +103,202 @@ static uint8_t stdmodel[2][8] = {
         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;
        }
-
-       if (CurByte >= CmdLen) return 0;
-       return buf[CurByte++];
 }
 
-static long PADreadPort(int num, PadDataS *pad) {
-       UpdateInput();
+static void do_vibration(unsigned char value)
+{
+    int changed = 0;
+    int i;
+
+    switch (CurCmd) {
+        case CMD_READ_DATA_AND_VIBRATE:
+            for (i = 0; i < 2; i++) {
+                if (padstate[CurPad].pad.Vib[i] == CurByte
+                     && padstate[CurPad].pad.VibF[i] != value) {
+                    padstate[CurPad].pad.VibF[i] = value;
+                    changed = 1;
+                }
+            }
+
+            if (!in_enable_vibration || !changed)
+                break;
+
+            plat_trigger_vibrate(CurPad,
+                                 padstate[CurPad].pad.VibF[0],
+                                 padstate[CurPad].pad.VibF[1]);
+            break;
+        case CMD_VIBRATION_TOGGLE:
+            for (i = 0; i < 2; i++) {
+                if (padstate[CurPad].pad.Vib[i] == CurByte)
+                    buf[CurByte] = 0;
+            }
+            if (value < 2) {
+                padstate[CurPad].pad.Vib[value] = CurByte;
+                if((padstate[CurPad].PadID & 0x0f) < (CurByte - 1) / 2) {
+                    padstate[CurPad].PadID = (padstate[CurPad].PadID & 0xf0) + (CurByte - 1) / 2;
+                }
+            }
+            break;
+    }
+}
 
-       pad->buttonStatus = (g.PadState[num].KeyStatus & g.PadState[num].JoyKeyStatus);
+#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
 
-       // ePSXe different from pcsx, swap bytes
-       pad->buttonStatus = (pad->buttonStatus >> 8) | (pad->buttonStatus << 8);
+unsigned char PADpoll_pad(unsigned char value) {
+       if (CurByte == 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();
        }
 
-       return PSE_PAD_ERR_SUCCESS;
-}
+       if (CurByte >= CmdLen)
+               return 0xff;    // verified
 
-long PADreadPort1(PadDataS *pad) {
-       return PADreadPort(0, pad);
-}
+       if (CurByte == 2)
+               do_cmd2(value);
 
-long PADreadPort2(PadDataS *pad) {
-       return PADreadPort(1, pad);
-}
+       if (padstate[CurPad].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD)
+               do_vibration(value);
 
-long PADkeypressed(void) {
-       long s;
+       return buf[CurByte++];
+}
 
-       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;
-}