#include "plugins.h"
#include "cdriso.h"
-#include "../plugins/dfinput/externals.h"
+#include "psxcounters.h"
static char IsoFile[MAXPATHLEN] = "";
static s64 cdOpenCaseTime = 0;
GPUupdateLace GPU_updateLace;
GPUinit GPU_init;
GPUshutdown GPU_shutdown;
-GPUconfigure GPU_configure;
-GPUtest GPU_test;
-GPUabout GPU_about;
GPUopen GPU_open;
GPUclose GPU_close;
GPUreadStatus GPU_readStatus;
GPUfreeze GPU_freeze;
GPUgetScreenPic GPU_getScreenPic;
GPUshowScreenPic GPU_showScreenPic;
-GPUclearDynarec GPU_clearDynarec;
GPUvBlank GPU_vBlank;
+GPUgetScreenInfo GPU_getScreenInfo;
CDRinit CDR_init;
CDRshutdown CDR_shutdown;
CDRreadCDDA CDR_readCDDA;
CDRgetTE CDR_getTE;
-SPUconfigure SPU_configure;
-SPUabout SPU_about;
SPUinit SPU_init;
SPUshutdown SPU_shutdown;
-SPUtest SPU_test;
SPUopen SPU_open;
SPUclose SPU_close;
-SPUplaySample SPU_playSample;
SPUwriteRegister SPU_writeRegister;
SPUreadRegister SPU_readRegister;
-SPUwriteDMA SPU_writeDMA;
-SPUreadDMA SPU_readDMA;
SPUwriteDMAMem SPU_writeDMAMem;
SPUreadDMAMem SPU_readDMAMem;
SPUplayADPCMchannel SPU_playADPCMchannel;
SPUregisterScheduleCb SPU_registerScheduleCb;
SPUasync SPU_async;
SPUplayCDDAchannel SPU_playCDDAchannel;
+SPUsetCDvol SPU_setCDvol;
PADconfigure PAD1_configure;
PADabout PAD1_about;
#define LoadSym(dest, src, name, checkerr) { \
dest = (src)SysLoadSym(drv, name); \
- if (checkerr) { CheckErr(name); } else SysLibError(); \
+ if (checkerr) { CheckErr(name); } \
}
void *hGPUDriver = NULL;
void CALLBACK GPU__keypressed(int key) {}
long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
-void CALLBACK GPU__clearDynarec(void (CALLBACK *callback)(void)) {}
void CALLBACK GPU__vBlank(int val) {}
+void CALLBACK GPU__getScreenInfo(int *y, int *base_hres) {}
#define LoadGpuSym1(dest, name) \
LoadSym(GPU_##dest, GPU##dest, name, TRUE);
hGPUDriver = SysLoadLibrary(GPUdll);
if (hGPUDriver == NULL) {
- GPU_configure = NULL;
SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
}
drv = hGPUDriver;
LoadGpuSym1(freeze, "GPUfreeze");
LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
- LoadGpuSym0(clearDynarec, "GPUclearDynarec");
LoadGpuSym0(vBlank, "GPUvBlank");
- LoadGpuSym0(configure, "GPUconfigure");
- LoadGpuSym0(test, "GPUtest");
- LoadGpuSym0(about, "GPUabout");
+ LoadGpuSym0(getScreenInfo, "GPUgetScreenInfo");
return 0;
}
return 0;
}
-void *hSPUDriver = NULL;
-
-long CALLBACK SPU__configure(void) { return 0; }
-void CALLBACK SPU__about(void) {}
-long CALLBACK SPU__test(void) { return 0; }
-void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}
+static void *hSPUDriver = NULL;\r
+static void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}\r
+static void CALLBACK SPU__setCDvol(unsigned char ll, unsigned char lr,
+ unsigned char rl, unsigned char rr, unsigned int cycle) {}
#define LoadSpuSym1(dest, name) \
LoadSym(SPU_##dest, SPU##dest, name, TRUE);
#define LoadSpuSym0(dest, name) \
LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
- if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
+ if (SPU_##dest == NULL) SPU_##dest = SPU__##dest;
#define LoadSpuSymN(dest, name) \
LoadSym(SPU_##dest, SPU##dest, name, FALSE);
hSPUDriver = SysLoadLibrary(SPUdll);
if (hSPUDriver == NULL) {
- SPU_configure = NULL;
SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
}
drv = hSPUDriver;
LoadSpuSym1(shutdown, "SPUshutdown");
LoadSpuSym1(open, "SPUopen");
LoadSpuSym1(close, "SPUclose");
- LoadSpuSym0(configure, "SPUconfigure");
- LoadSpuSym0(about, "SPUabout");
- LoadSpuSym0(test, "SPUtest");
LoadSpuSym1(writeRegister, "SPUwriteRegister");
LoadSpuSym1(readRegister, "SPUreadRegister");
- LoadSpuSym1(writeDMA, "SPUwriteDMA");
- LoadSpuSym1(readDMA, "SPUreadDMA");
LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
LoadSpuSym1(readDMAMem, "SPUreadDMAMem");
LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");
LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
LoadSpuSymN(async, "SPUasync");
LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
+ LoadSpuSym0(setCDvol, "SPUsetCDvol");
return 0;
}
void *hPAD1Driver = NULL;
void *hPAD2Driver = NULL;
-static int multitap1;
-static int multitap2;
-//Pad information, keystate, mode, config mode, vibration
-static PadDataS pad[8];
+// Pad information, keystate, mode, config mode, vibration
+static PadDataS pads[8];
-static int reqPos, respSize, req;
-static int ledStateReq44[8];
-static int PadMode[8]; /* 0 : digital 1: analog */
+static int reqPos, respSize;
static unsigned char buf[256];
-static unsigned char bufMulti[34] = { 0x80, 0x5a,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-unsigned char multitappar[34] = { 0x80, 0x5a,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+static unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
//response for request 44, 45, 46, 47, 4C, 4D
-static unsigned char resp45[8] = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
-static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
-static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
-static unsigned char resp47[8] = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
-static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
-static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
-static unsigned char resp4D[8] = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};
+static const u8 resp45[8] = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
+static const u8 resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
+static const u8 resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
+static const u8 resp47[8] = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
+static const u8 resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
+static const u8 resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
//fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
-static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const u8 resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Resquest of psx core
enum {
};
+static void initBufForRequest(int padIndex, char value) {
+ if (pads[padIndex].ds.configMode) {
+ buf[0] = 0xf3; buf[1] = 0x5a;
+ respSize = 8;
+ }
+ else if (value != 0x42 && value != 0x43) {
+ respSize = 1;
+ return;
+ }
+ if ((u32)(frame_counter - pads[padIndex].ds.lastUseFrame) > 2*60u
+ && pads[padIndex].ds.configModeUsed
+ && !Config.hacks.dualshock_init_analog)
+ {
+ //SysPrintf("Pad reset\n");
+ pads[padIndex].ds.padMode = 0; // according to nocash
+ pads[padIndex].ds.autoAnalogTried = 0;
+ }
+ else if (pads[padIndex].ds.padMode == 0 && value == CMD_READ_DATA_AND_VIBRATE
+ && pads[padIndex].ds.configModeUsed
+ && !pads[padIndex].ds.configMode
+ && !pads[padIndex].ds.userToggled)
+ {
+ if (pads[padIndex].ds.autoAnalogTried == 16) {
+ // auto-enable for convenience
+ SysPrintf("Auto-enabling dualshock analog mode.\n");
+ pads[padIndex].ds.padMode = 1;
+ pads[padIndex].ds.autoAnalogTried = 255;
+ }
+ else if (pads[padIndex].ds.autoAnalogTried < 16)
+ pads[padIndex].ds.autoAnalogTried++;
+ }
+ pads[padIndex].ds.lastUseFrame = frame_counter;
-//NO MULTITAP
-
-void initBufForRequest(int padIndex, char value){
- switch (value){
- //Pad keystate already in buffer
+ switch (value) {
+ // keystate already in buffer, set by PADstartPoll_()
//case CMD_READ_DATA_AND_VIBRATE :
// break;
case CMD_CONFIG_MODE :
- if (pad[padIndex].configMode == 1) {
+ if (pads[padIndex].ds.configMode) {
memcpy(buf, resp43, 8);
break;
}
- //else, not in config mode, pad keystate return (already in the buffer)
+ // else not in config mode, pad keystate return
break;
case CMD_SET_MODE_AND_LOCK :
memcpy(buf, resp44, 8);
break;
case CMD_QUERY_MODEL_AND_MODE :
memcpy(buf, resp45, 8);
- buf[4] = PadMode[padIndex];
+ buf[4] = pads[padIndex].ds.padMode;
break;
case CMD_QUERY_ACT :
memcpy(buf, resp46_00, 8);
case CMD_QUERY_MODE :
memcpy(buf, resp4C_00, 8);
break;
- case CMD_VIBRATION_TOGGLE :
- memcpy(buf, resp4D, 8);
+ case CMD_VIBRATION_TOGGLE: // 4d
+ memcpy(buf + 2, pads[padIndex].ds.cmd4dConfig, 6);
break;
case REQ40 :
memcpy(buf, resp40, 8);
}
}
-
-
-
-void reqIndex2Treatment(int padIndex, char value){
- switch (req){
+static void reqIndex2Treatment(int padIndex, u8 value) {
+ switch (pads[padIndex].txData[0]) {
case CMD_CONFIG_MODE :
//0x43
if (value == 0) {
- pad[padIndex].configMode = 0;
- } else {
- pad[padIndex].configMode = 1;
+ pads[padIndex].ds.configMode = 0;
+ } else if (value == 1) {
+ pads[padIndex].ds.configMode = 1;
+ pads[padIndex].ds.configModeUsed = 1;
}
break;
case CMD_SET_MODE_AND_LOCK :
//0x44 store the led state for change mode if the next value = 0x02
//0x01 analog ON
//0x00 analog OFF
- ledStateReq44[padIndex] = value;
- PadMode[padIndex] = value;
+ if ((value & ~1) == 0)
+ pads[padIndex].ds.padMode = value;
break;
case CMD_QUERY_ACT :
//0x46
memcpy(buf, resp4C_01, 8);
}
break;
- case CMD_VIBRATION_TOGGLE :
- //0x4D
- memcpy(buf, resp4D, 8);
- break;
- case CMD_READ_DATA_AND_VIBRATE:
- //mem the vibration value for small motor;
- pad[padIndex].Vib[0] = value;
- break;
}
}
-void vibrate(int padIndex){
- if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
+static void ds_update_vibrate(int padIndex) {
+ PadDataS *pad = &pads[padIndex];
+ if (pad->ds.configModeUsed) {
+ pad->Vib[0] = (pad->Vib[0] == 1) ? 1 : 0;
+ }
+ else {
+ // compat mode
+ pad->Vib[0] = (pad->Vib[0] & 0xc0) == 0x40 && (pad->Vib[1] & 1);
+ pad->Vib[1] = 0;
+ }
+ if (pad->Vib[0] != pad->VibF[0] || pad->Vib[1] != pad->VibF[1]) {
//value is different update Value and call libretro for vibration
- pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
- pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
- plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
- //printf("vibration pad %i", padIndex);
+ pad->VibF[0] = pad->Vib[0];
+ pad->VibF[1] = pad->Vib[1];
+ plat_trigger_vibrate(padIndex, pad->VibF[0], pad->VibF[1]);
+ //printf("vib%i %02x %02x\n", padIndex, pad->VibF[0], pad->VibF[1]);
}
}
+static void log_pad(int port, int pos)
+{
+#if 0
+ if (port == 0 && pos == respSize - 1) {
+ int i;
+ for (i = 0; i < respSize; i++)
+ printf("%02x ", pads[port].txData[i]);
+ printf("|");
+ for (i = 0; i < respSize; i++)
+ printf(" %02x", buf[i]);
+ printf("\n");
+ }
+#endif
+}
+static void adjust_analog(unsigned char *b)
+{
+ // ff8 hates 0x80 for whatever reason (broken in 2d area menus),
+ // or is this caused by something else we do wrong??
+ // Also S.C.A.R.S. treats 0x7f as turning left.
+ if (b[6] == 0x7f || b[6] == 0x80)
+ b[6] = 0x81;
+}
-
-//Build response for 0x42 request Pad in port
-void _PADstartPoll(PadDataS *pad) {
+// Build response for 0x42 request Pad in port
+static void PADstartPoll_(PadDataS *pad) {
switch (pad->controllerType) {
case PSE_PAD_TYPE_MOUSE:
stdpar[0] = 0x12;
stdpar[2] = pad->buttonStatus & 0xff;
stdpar[3] = pad->buttonStatus >> 8;
- //This code assumes an X resolution of 256 and a Y resolution of 240
- int xres = 256;
- int yres = 240;
-
- //The code wants an input range for x and y of 0-1023 we passed in -32767 -> 32767
- int absX = (pad->absoluteX / 64) + 512;
- int absY = (pad->absoluteY / 64) + 512;
+ int absX = pad->absoluteX; // 0-1023
+ int absY = pad->absoluteY;
if (absX == 65536 || absY == 65536) {
- stdpar[4] = 0x01;
- stdpar[5] = 0x00;
- stdpar[6] = 0x0A;
- stdpar[7] = 0x00;
+ stdpar[4] = 0x01;
+ stdpar[5] = 0x00;
+ stdpar[6] = 0x0A;
+ stdpar[7] = 0x00;
}
else {
- stdpar[4] = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10);
- stdpar[5] = (0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10)) >> 8;
- stdpar[6] = 0x20 + (yres * absY >> 10);
- stdpar[7] = (0x20 + (yres * absY >> 10)) >> 8;
+ int y_ofs = 0, yres = 240;
+ GPU_getScreenInfo(&y_ofs, &yres);
+ int y_top = (Config.PsxType ? 0x30 : 0x19) + y_ofs;
+ int w = Config.PsxType ? 385 : 378;
+ int x = 0x40 + (w * absX >> 10);
+ int y = y_top + (yres * absY >> 10);
+ //printf("%3d %3d %4x %4x\n", absX, absY, x, y);
+
+ stdpar[4] = x;
+ stdpar[5] = x >> 8;
+ stdpar[6] = y;
+ stdpar[7] = y >> 8;
}
memcpy(buf, stdpar, 8);
respSize = 8;
break;
+ case PSE_PAD_TYPE_GUN: // GUN CONTROLLER - gun controller SLPH-00014 from Konami
+ stdpar[0] = 0x31;
+ stdpar[1] = 0x5a;
+ stdpar[2] = pad->buttonStatus & 0xff;
+ stdpar[3] = pad->buttonStatus >> 8;
+ memcpy(buf, stdpar, 4);
+ respSize = 4;
+ break;
case PSE_PAD_TYPE_ANALOGPAD: // scph1150
+ if (pad->ds.padMode == 0)
+ goto standard;
stdpar[0] = 0x73;
stdpar[1] = 0x5a;
stdpar[2] = pad->buttonStatus & 0xff;
stdpar[5] = pad->rightJoyY;
stdpar[6] = pad->leftJoyX;
stdpar[7] = pad->leftJoyY;
+ adjust_analog(stdpar);
memcpy(buf, stdpar, 8);
respSize = 8;
break;
stdpar[5] = pad->rightJoyY;
stdpar[6] = pad->leftJoyX;
stdpar[7] = pad->leftJoyY;
+ adjust_analog(stdpar);
memcpy(buf, stdpar, 8);
respSize = 8;
break;
case PSE_PAD_TYPE_STANDARD:
+ standard:
stdpar[0] = 0x41;
stdpar[1] = 0x5a;
stdpar[2] = pad->buttonStatus & 0xff;
stdpar[3] = pad->buttonStatus >> 8;
- //avoid analog value in multitap mode if change pad type in game.
- stdpar[4] = 0xff;
- stdpar[5] = 0xff;
- stdpar[6] = 0xff;
- stdpar[7] = 0xff;
- memcpy(buf, stdpar, 8);
- respSize = 8;
+ memcpy(buf, stdpar, 4);
+ respSize = 4;
break;
default:
- stdpar[0] = 0xff;
- stdpar[1] = 0xff;
- stdpar[2] = 0xff;
- stdpar[3] = 0xff;
- stdpar[4] = 0xff;
- stdpar[5] = 0xff;
- stdpar[6] = 0xff;
- stdpar[7] = 0xff;
- memcpy(buf, stdpar, 8);
- respSize = 8;
+ respSize = 0;
break;
}
}
+static void PADpoll_dualshock(int port, unsigned char value, int pos)
+{
+ switch (pos) {
+ case 0:
+ initBufForRequest(port, value);
+ break;
+ case 2:
+ reqIndex2Treatment(port, value);
+ break;
+ case 7:
+ if (pads[port].txData[0] == CMD_VIBRATION_TOGGLE)
+ memcpy(pads[port].ds.cmd4dConfig, pads[port].txData + 2, 6);
+ break;
+ }
-//Build response for 0x42 request Multitap in port
-//Response header for multitap : 0x80, 0x5A, (Pad information port 1-2A), (Pad information port 1-2B), (Pad information port 1-2C), (Pad information port 1-2D)
-void _PADstartPollMultitap(PadDataS* padd) {
- int i, offset;
- for(i = 0; i < 4; i++) {
- offset = 2 + (i * 8);
- _PADstartPoll(&padd[i]);
- memcpy(multitappar+offset, stdpar, 8);
+ if (pads[port].txData[0] == CMD_READ_DATA_AND_VIBRATE
+ && !pads[port].ds.configModeUsed && 2 <= pos && pos < 4)
+ {
+ // "compat" single motor mode
+ pads[port].Vib[pos - 2] = value;
}
- memcpy(bufMulti, multitappar, 34);
- respSize = 34;
+ else if (pads[port].txData[0] == CMD_READ_DATA_AND_VIBRATE
+ && 2 <= pos && pos < 8)
+ {
+ // 0 - weak motor, 1 - strong motor
+ int dev = pads[port].ds.cmd4dConfig[pos - 2];
+ if (dev < 2)
+ pads[port].Vib[dev] = value;
+ }
+ if (pos == respSize - 1)
+ ds_update_vibrate(port);
}
+static unsigned char PADpoll_(int port, unsigned char value, int pos, int *more_data) {
+ if (pos == 0 && value != 0x42 && in_type[port] != PSE_PAD_TYPE_ANALOGPAD)
+ respSize = 1;
-unsigned char _PADpoll(int port, unsigned char value) {
- if (reqPos == 0) {
- //mem the request number
- req = value;
-
- // Don't enable Analog/Vibration for a standard pad
- if (in_type[port] == PSE_PAD_TYPE_STANDARD ||
- in_type[port] == PSE_PAD_TYPE_NEGCON) {
- ; // Pad keystate already in buffer
- }
- else
- {
- //copy the default value of request response in buffer instead of the keystate
- initBufForRequest(port, value);
- }
+ switch (in_type[port]) {
+ case PSE_PAD_TYPE_ANALOGPAD:
+ PADpoll_dualshock(port, value, pos);
+ break;
+ case PSE_PAD_TYPE_GUN:
+ if (pos == 2)
+ pl_gun_byte2(port, value);
+ break;
}
- //if no new request the pad return 0xff, for signaling connected
- if (reqPos >= respSize)
- return 0xff;
+ *more_data = pos < respSize - 1;
+ if (pos >= respSize)
+ return 0xff; // no response/HiZ
- switch(reqPos){
- case 2:
- reqIndex2Treatment(port, value);
- break;
- case 3:
- switch(req) {
- case CMD_SET_MODE_AND_LOCK :
- //change mode on pad
- break;
- case CMD_READ_DATA_AND_VIBRATE:
- //mem the vibration value for Large motor;
- pad[port].Vib[1] = value;
+ log_pad(port, pos);
+ return buf[pos];
+}
- if (in_type[port] != PSE_PAD_TYPE_ANALOGPAD)
- break;
+// response: 0x80, 0x5A, 8 bytes each for ports A, B, C, D
+static unsigned char PADpollMultitap(int port, unsigned char value, int pos, int *more_data) {
+ unsigned int devByte, dev;
+ int unused = 0;
- //vibration
- vibrate(port);
- break;
- }
- break;
+ if (pos == 0) {
+ *more_data = (value == 0x42);
+ return 0x80;
}
- return buf[reqPos++];
+ *more_data = pos < 34 - 1;
+ if (pos == 1)
+ return 0x5a;
+ if (pos >= 34)
+ return 0xff;
+
+ devByte = pos - 2;
+ dev = devByte / 8;
+ if (devByte % 8 == 0)
+ PADstartPoll_(&pads[port + dev]);
+ return PADpoll_(port + dev, value, devByte % 8, &unused);
}
+static unsigned char PADpollMain(int port, unsigned char value, int *more_data) {
+ unsigned char ret;
+ int pos = reqPos++;
-unsigned char _PADpollMultitap(int port, unsigned char value) {
- if (reqPos >= respSize) return 0xff;
- return bufMulti[reqPos++];
-}
+ if (pos < sizeof(pads[port].txData))
+ pads[port].txData[pos] = value;
+ if (!pads[port].portMultitap || !pads[port].multitapLongModeEnabled)
+ ret = PADpoll_(port, value, pos, more_data);
+ else
+ ret = PADpollMultitap(port, value, pos, more_data);
+ return ret;
+}
// refresh the button state on port 1.
// int pad is not needed.
-unsigned char CALLBACK PAD1__startPoll(int pad) {
+unsigned char CALLBACK PAD1__startPoll(int unused) {
+ int i;
+
reqPos = 0;
- // first call the pad provide if a multitap is connected between the psx and himself
- // just one pad is on port 1 : NO MULTITAP
- if (multitap1 == 0) {
- PadDataS padd;
- padd.requestPadIndex = 0;
- PAD1_readPort1(&padd);
- _PADstartPoll(&padd);
+ pads[0].requestPadIndex = 0;
+ PAD1_readPort1(&pads[0]);
+
+ pads[0].multitapLongModeEnabled = 0;
+ if (pads[0].portMultitap)
+ pads[0].multitapLongModeEnabled = pads[0].txData[1] & 1;
+
+ if (!pads[0].portMultitap || !pads[0].multitapLongModeEnabled) {
+ PADstartPoll_(&pads[0]);
} else {
- // a multitap is plugged : refresh all pad.
- int i;
- PadDataS padd[4];
- for(i = 0; i < 4; i++) {
- padd[i].requestPadIndex = i;
- PAD1_readPort1(&padd[i]);
+ // a multitap is plugged and enabled: refresh pads 1-3
+ for (i = 1; i < 4; i++) {
+ pads[i].requestPadIndex = i;
+ PAD1_readPort1(&pads[i]);
}
- _PADstartPollMultitap(padd);
}
- //printf("\npad 1 : ");
- return 0x00;
+ return 0xff;
}
-unsigned char CALLBACK PAD1__poll(unsigned char value) {
- char tmp;
- if (multitap1 == 1) {
- tmp = _PADpollMultitap(0, value);
- } else {
- tmp = _PADpoll(0, value);
- }
- //printf("%2x:%2x, ",value,tmp);
- return tmp;
-
+unsigned char CALLBACK PAD1__poll(unsigned char value, int *more_data) {
+ return PADpollMain(0, value, more_data);
}
if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
static int LoadPAD1plugin(const char *PAD1dll) {
- PadDataS padd;
void *drv;
+ size_t p;
hPAD1Driver = SysLoadLibrary(PAD1dll);
if (hPAD1Driver == NULL) {
LoadPad1Sym0(poll, "PADpoll");
LoadPad1SymN(setSensitive, "PADsetSensitive");
- padd.requestPadIndex = 0;
- PAD1_readPort1(&padd);
- multitap1 = padd.portMultitap;
+ memset(pads, 0, sizeof(pads));
+ for (p = 0; p < sizeof(pads) / sizeof(pads[0]); p++) {
+ memset(pads[p].ds.cmd4dConfig, 0xff, sizeof(pads[p].ds.cmd4dConfig));
+ }
return 0;
}
unsigned char CALLBACK PAD2__startPoll(int pad) {
- int pad_index;
+ int pad_index = pads[0].portMultitap ? 4 : 1;
+ int i;
reqPos = 0;
- if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
- pad_index = 1;
- } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
- pad_index = 4;
- } else {
- pad_index = 0;
- }
+ pads[pad_index].requestPadIndex = pad_index;
+ PAD2_readPort2(&pads[pad_index]);
+
+ pads[pad_index].multitapLongModeEnabled = 0;
+ if (pads[pad_index].portMultitap)
+ pads[pad_index].multitapLongModeEnabled = pads[pad_index].txData[1] & 1;
- // just one pad is on port 1 : NO MULTITAP
- if (multitap2 == 0) {
- PadDataS padd;
- padd.requestPadIndex = pad_index;
- PAD2_readPort2(&padd);
- _PADstartPoll(&padd);
+ if (!pads[pad_index].portMultitap || !pads[pad_index].multitapLongModeEnabled) {
+ PADstartPoll_(&pads[pad_index]);
} else {
- // a multitap is plugged : refresh all pad.
- int i;
- PadDataS padd[4];
- for(i = 0; i < 4; i++) {
- padd[i].requestPadIndex = i+pad_index;
- PAD2_readPort2(&padd[i]);
+ for (i = 1; i < 4; i++) {
+ pads[pad_index + i].requestPadIndex = pad_index + i;
+ PAD2_readPort2(&pads[pad_index + i]);
}
- _PADstartPollMultitap(padd);
}
- //printf("\npad 2 : ");
- return 0x00;
+ return 0xff;
}
-unsigned char CALLBACK PAD2__poll(unsigned char value) {
- char tmp;
- if (multitap2 == 2) {
- tmp = _PADpollMultitap(1, value);
- } else {
- tmp = _PADpoll(1, value);
- }
- //printf("%2x:%2x, ",value,tmp);
- return tmp;
+unsigned char CALLBACK PAD2__poll(unsigned char value, int *more_data) {
+ return PADpollMain(pads[0].portMultitap ? 4 : 1, value, more_data);
}
long CALLBACK PAD2__configure(void) { return 0; }
LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
static int LoadPAD2plugin(const char *PAD2dll) {
- PadDataS padd;
void *drv;
hPAD2Driver = SysLoadLibrary(PAD2dll);
LoadPad2Sym0(poll, "PADpoll");
LoadPad2SymN(setSensitive, "PADsetSensitive");
- padd.requestPadIndex = 0;
- PAD2_readPort2(&padd);
- multitap2 = padd.portMultitap;
+ return 0;
+}
+
+int padFreeze(void *f, int Mode) {
+ size_t i;
+
+ for (i = 0; i < sizeof(pads) / sizeof(pads[0]); i++) {
+ pads[i].saveSize = sizeof(pads[i]);
+ gzfreeze(&pads[i], sizeof(pads[i]));
+ if (Mode == 0 && pads[i].saveSize != sizeof(pads[i]))
+ SaveFuncs.seek(f, pads[i].saveSize - sizeof(pads[i]), SEEK_CUR);
+ }
return 0;
}
+int padToggleAnalog(unsigned int index)
+{
+ int r = -1;
+
+ if (index < sizeof(pads) / sizeof(pads[0])) {
+ r = (pads[index].ds.padMode ^= 1);
+ pads[index].ds.userToggled = 1;
+ }
+ return r;
+}
+
+
void *hNETDriver = NULL;
void CALLBACK NET__setInfo(netInfo *info) {}
#endif
-void CALLBACK clearDynarec(void) {
- psxCpu->Reset();
-}
-
int LoadPlugins() {
int ret;
char Plugin[MAXPATHLEN * 2];