1 /***************************************************************************
2 * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
18 ***************************************************************************/
21 * Plugin library callback/access functions.
26 #include "../plugins/dfinput/externals.h"
28 static char IsoFile[MAXPATHLEN] = "";
29 static s64 cdOpenCaseTime = 0;
31 GPUupdateLace GPU_updateLace;
33 GPUshutdown GPU_shutdown;
34 GPUconfigure GPU_configure;
39 GPUreadStatus GPU_readStatus;
40 GPUreadData GPU_readData;
41 GPUreadDataMem GPU_readDataMem;
42 GPUwriteStatus GPU_writeStatus;
43 GPUwriteData GPU_writeData;
44 GPUwriteDataMem GPU_writeDataMem;
45 GPUdmaChain GPU_dmaChain;
46 GPUkeypressed GPU_keypressed;
47 GPUdisplayText GPU_displayText;
48 GPUmakeSnapshot GPU_makeSnapshot;
50 GPUgetScreenPic GPU_getScreenPic;
51 GPUshowScreenPic GPU_showScreenPic;
52 GPUclearDynarec GPU_clearDynarec;
56 CDRshutdown CDR_shutdown;
62 CDRreadTrack CDR_readTrack;
63 CDRgetBuffer CDR_getBuffer;
66 CDRgetStatus CDR_getStatus;
67 CDRgetDriveLetter CDR_getDriveLetter;
68 CDRgetBufferSub CDR_getBufferSub;
69 CDRconfigure CDR_configure;
71 CDRsetfilename CDR_setfilename;
72 CDRreadCDDA CDR_readCDDA;
75 SPUconfigure SPU_configure;
78 SPUshutdown SPU_shutdown;
82 SPUplaySample SPU_playSample;
83 SPUwriteRegister SPU_writeRegister;
84 SPUreadRegister SPU_readRegister;
85 SPUwriteDMA SPU_writeDMA;
86 SPUreadDMA SPU_readDMA;
87 SPUwriteDMAMem SPU_writeDMAMem;
88 SPUreadDMAMem SPU_readDMAMem;
89 SPUplayADPCMchannel SPU_playADPCMchannel;
91 SPUregisterCallback SPU_registerCallback;
92 SPUregisterScheduleCb SPU_registerScheduleCb;
94 SPUplayCDDAchannel SPU_playCDDAchannel;
96 PADconfigure PAD1_configure;
99 PADshutdown PAD1_shutdown;
104 PADreadPort1 PAD1_readPort1;
105 PADkeypressed PAD1_keypressed;
106 PADstartPoll PAD1_startPoll;
108 PADsetSensitive PAD1_setSensitive;
110 PADconfigure PAD2_configure;
113 PADshutdown PAD2_shutdown;
118 PADreadPort2 PAD2_readPort2;
119 PADkeypressed PAD2_keypressed;
120 PADstartPoll PAD2_startPoll;
122 PADsetSensitive PAD2_setSensitive;
125 NETshutdown NET_shutdown;
129 NETconfigure NET_configure;
132 NETresume NET_resume;
133 NETqueryPlayer NET_queryPlayer;
134 NETsendData NET_sendData;
135 NETrecvData NET_recvData;
136 NETsendPadData NET_sendPadData;
137 NETrecvPadData NET_recvPadData;
138 NETsetInfo NET_setInfo;
139 NETkeypressed NET_keypressed;
141 #ifdef ENABLE_SIO1API
144 SIO1shutdown SIO1_shutdown;
146 SIO1close SIO1_close;
148 SIO1configure SIO1_configure;
149 SIO1about SIO1_about;
150 SIO1pause SIO1_pause;
151 SIO1resume SIO1_resume;
152 SIO1keypressed SIO1_keypressed;
153 SIO1writeData8 SIO1_writeData8;
154 SIO1writeData16 SIO1_writeData16;
155 SIO1writeData32 SIO1_writeData32;
156 SIO1writeStat16 SIO1_writeStat16;
157 SIO1writeStat32 SIO1_writeStat32;
158 SIO1writeMode16 SIO1_writeMode16;
159 SIO1writeMode32 SIO1_writeMode32;
160 SIO1writeCtrl16 SIO1_writeCtrl16;
161 SIO1writeCtrl32 SIO1_writeCtrl32;
162 SIO1writeBaud16 SIO1_writeBaud16;
163 SIO1writeBaud32 SIO1_writeBaud32;
164 SIO1readData8 SIO1_readData8;
165 SIO1readData16 SIO1_readData16;
166 SIO1readData32 SIO1_readData32;
167 SIO1readStat16 SIO1_readStat16;
168 SIO1readStat32 SIO1_readStat32;
169 SIO1readMode16 SIO1_readMode16;
170 SIO1readMode32 SIO1_readMode32;
171 SIO1readCtrl16 SIO1_readCtrl16;
172 SIO1readCtrl32 SIO1_readCtrl32;
173 SIO1readBaud16 SIO1_readBaud16;
174 SIO1readBaud32 SIO1_readBaud32;
175 SIO1registerCallback SIO1_registerCallback;
179 static const char *err;
181 #define CheckErr(func) { \
182 err = SysLibError(); \
183 if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; } \
186 #define LoadSym(dest, src, name, checkerr) { \
187 dest = (src)SysLoadSym(drv, name); \
188 if (checkerr) { CheckErr(name); } else SysLibError(); \
191 void *hGPUDriver = NULL;
193 void CALLBACK GPU__displayText(char *pText) {
194 SysPrintf("%s\n", pText);
197 long CALLBACK GPU__configure(void) { return 0; }
198 long CALLBACK GPU__test(void) { return 0; }
199 void CALLBACK GPU__about(void) {}
200 void CALLBACK GPU__makeSnapshot(void) {}
201 void CALLBACK GPU__keypressed(int key) {}
202 long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
203 long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
204 void CALLBACK GPU__clearDynarec(void (CALLBACK *callback)(void)) {}
205 void CALLBACK GPU__vBlank(int val) {}
207 #define LoadGpuSym1(dest, name) \
208 LoadSym(GPU_##dest, GPU##dest, name, TRUE);
210 #define LoadGpuSym0(dest, name) \
211 LoadSym(GPU_##dest, GPU##dest, name, FALSE); \
212 if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;
214 #define LoadGpuSymN(dest, name) \
215 LoadSym(GPU_##dest, GPU##dest, name, FALSE);
217 static int LoadGPUplugin(const char *GPUdll) {
220 hGPUDriver = SysLoadLibrary(GPUdll);
221 if (hGPUDriver == NULL) {
222 GPU_configure = NULL;
223 SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
226 LoadGpuSym1(init, "GPUinit");
227 LoadGpuSym1(shutdown, "GPUshutdown");
228 LoadGpuSym1(open, "GPUopen");
229 LoadGpuSym1(close, "GPUclose");
230 LoadGpuSym1(readData, "GPUreadData");
231 LoadGpuSym1(readDataMem, "GPUreadDataMem");
232 LoadGpuSym1(readStatus, "GPUreadStatus");
233 LoadGpuSym1(writeData, "GPUwriteData");
234 LoadGpuSym1(writeDataMem, "GPUwriteDataMem");
235 LoadGpuSym1(writeStatus, "GPUwriteStatus");
236 LoadGpuSym1(dmaChain, "GPUdmaChain");
237 LoadGpuSym1(updateLace, "GPUupdateLace");
238 LoadGpuSym0(keypressed, "GPUkeypressed");
239 LoadGpuSym0(displayText, "GPUdisplayText");
240 LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
241 LoadGpuSym1(freeze, "GPUfreeze");
242 LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
243 LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
244 LoadGpuSym0(clearDynarec, "GPUclearDynarec");
245 LoadGpuSym0(vBlank, "GPUvBlank");
246 LoadGpuSym0(configure, "GPUconfigure");
247 LoadGpuSym0(test, "GPUtest");
248 LoadGpuSym0(about, "GPUabout");
253 void *hCDRDriver = NULL;
255 long CALLBACK CDR__play(unsigned char *sector) { return 0; }
256 long CALLBACK CDR__stop(void) { return 0; }
258 long CALLBACK CDR__getStatus(struct CdrStat *stat) {
259 if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))
267 char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
268 long CALLBACK CDR__configure(void) { return 0; }
269 long CALLBACK CDR__test(void) { return 0; }
270 void CALLBACK CDR__about(void) {}
271 long CALLBACK CDR__setfilename(char*filename) { return 0; }
273 #define LoadCdrSym1(dest, name) \
274 LoadSym(CDR_##dest, CDR##dest, name, TRUE);
276 #define LoadCdrSym0(dest, name) \
277 LoadSym(CDR_##dest, CDR##dest, name, FALSE); \
278 if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
280 #define LoadCdrSymN(dest, name) \
281 LoadSym(CDR_##dest, CDR##dest, name, FALSE);
283 static int LoadCDRplugin(const char *CDRdll) {
286 if (CDRdll == NULL) {
291 hCDRDriver = SysLoadLibrary(CDRdll);
292 if (hCDRDriver == NULL) {
293 CDR_configure = NULL;
294 SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll); return -1;
297 LoadCdrSym1(init, "CDRinit");
298 LoadCdrSym1(shutdown, "CDRshutdown");
299 LoadCdrSym1(open, "CDRopen");
300 LoadCdrSym1(close, "CDRclose");
301 LoadCdrSym1(getTN, "CDRgetTN");
302 LoadCdrSym1(getTD, "CDRgetTD");
303 LoadCdrSym1(readTrack, "CDRreadTrack");
304 LoadCdrSym1(getBuffer, "CDRgetBuffer");
305 LoadCdrSym1(getBufferSub, "CDRgetBufferSub");
306 LoadCdrSym0(play, "CDRplay");
307 LoadCdrSym0(stop, "CDRstop");
308 LoadCdrSym0(getStatus, "CDRgetStatus");
309 LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
310 LoadCdrSym0(configure, "CDRconfigure");
311 LoadCdrSym0(test, "CDRtest");
312 LoadCdrSym0(about, "CDRabout");
313 LoadCdrSym0(setfilename, "CDRsetfilename");
314 LoadCdrSymN(readCDDA, "CDRreadCDDA");
315 LoadCdrSymN(getTE, "CDRgetTE");
320 void *hSPUDriver = NULL;
322 long CALLBACK SPU__configure(void) { return 0; }
323 void CALLBACK SPU__about(void) {}
324 long CALLBACK SPU__test(void) { return 0; }
325 void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}
327 #define LoadSpuSym1(dest, name) \
328 LoadSym(SPU_##dest, SPU##dest, name, TRUE);
330 #define LoadSpuSym0(dest, name) \
331 LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
332 if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
334 #define LoadSpuSymN(dest, name) \
335 LoadSym(SPU_##dest, SPU##dest, name, FALSE);
337 static int LoadSPUplugin(const char *SPUdll) {
340 hSPUDriver = SysLoadLibrary(SPUdll);
341 if (hSPUDriver == NULL) {
342 SPU_configure = NULL;
343 SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
346 LoadSpuSym1(init, "SPUinit");
347 LoadSpuSym1(shutdown, "SPUshutdown");
348 LoadSpuSym1(open, "SPUopen");
349 LoadSpuSym1(close, "SPUclose");
350 LoadSpuSym0(configure, "SPUconfigure");
351 LoadSpuSym0(about, "SPUabout");
352 LoadSpuSym0(test, "SPUtest");
353 LoadSpuSym1(writeRegister, "SPUwriteRegister");
354 LoadSpuSym1(readRegister, "SPUreadRegister");
355 LoadSpuSym1(writeDMA, "SPUwriteDMA");
356 LoadSpuSym1(readDMA, "SPUreadDMA");
357 LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
358 LoadSpuSym1(readDMAMem, "SPUreadDMAMem");
359 LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");
360 LoadSpuSym1(freeze, "SPUfreeze");
361 LoadSpuSym1(registerCallback, "SPUregisterCallback");
362 LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
363 LoadSpuSymN(async, "SPUasync");
364 LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
369 extern int in_type[8];
371 void *hPAD1Driver = NULL;
372 void *hPAD2Driver = NULL;
374 static int multitap1 = -1;
375 static int multitap2 = -1;
376 //Pad information, keystate, mode, config mode, vibration
377 static PadDataS pad[8];
379 static int reqPos, respSize, req;
380 static int ledStateReq44[8];
381 static int PadMode[8]; /* 0 : digital 1: analog */
383 static unsigned char buf[256];
384 static unsigned char bufMulti[34] = { 0x80, 0x5a,
385 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
386 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
387 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
388 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
390 unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
391 unsigned char multitappar[34] = { 0x80, 0x5a,
392 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
393 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
394 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
395 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
397 //response for request 44, 45, 46, 47, 4C, 4D
398 static unsigned char resp45[8] = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
399 static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
400 static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
401 static unsigned char resp47[8] = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
402 static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
403 static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
404 static unsigned char resp4D[8] = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};
406 //fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
407 static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
408 static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
409 static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
410 static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
411 static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
412 static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
413 static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
414 static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
415 static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
417 // Resquest of psx core
420 // first call of this request for the pad, the pad is configured as an digital pad.
421 // 0x0X, 0x42, 0x0Y, 0xZZ, 0xAA, 0x00, 0x00, 0x00, 0x00
422 // X pad number (used for the multitap, first request response 0x00, 0x80, 0x5A, (8 bytes pad A), (8 bytes pad B), (8 bytes pad C), (8 bytes pad D)
423 // Y if 1 : psx request the full length response for the multitap, 3 bytes header and 4 block of 8 bytes per pad
424 // Y if 0 : psx request a pad key state
425 // ZZ rumble small motor 00-> OFF, 01 -> ON
426 // AA rumble large motor speed 0x00 -> 0xFF
430 // PadId -> 0x41 for digital pas, 0x73 for analog pad
431 // 0x5A mode has not change (no press on analog button on the center of pad), 0x00 the analog button have been pressed and the mode switch
432 // 6 Bytes for keystates
433 CMD_READ_DATA_AND_VIBRATE = 0x42,
437 // 0x0N, 0x43, 0x00, XX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
438 // XX = 00 -> Normal mode : Seconde bytes of response = padId
439 // XX = 01 -> Configuration mode : Seconde bytes of response = 0xF3
441 // enter in config mode example :
442 // req : 01 43 00 01 00 00 00 00 00 00
443 // res : 00 41 5A buttons state, analog states
444 // exit config mode :
445 // req : 01 43 00 00 00 00 00 00 00 00
446 // res : 00 F3 5A buttons state, analog states
447 CMD_CONFIG_MODE = 0x43,
451 // 0x0N, 0x44, 0x00, VAL, SEL, 0x00, 0x00, 0x00, 0x00
456 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
457 CMD_SET_MODE_AND_LOCK = 0x44,
459 // Get Analog Led state
461 // 0x0N, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
463 // 0x00, 0xF3, 0x5A, 0x01, 0x02, VAL, 0x02, 0x01, 0x00
466 CMD_QUERY_MODEL_AND_MODE = 0x45,
470 // 0x0N, 0x46, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
473 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A
475 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14
476 CMD_QUERY_ACT = 0x46,
479 // 0x0N, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
481 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00
482 CMD_QUERY_COMB = 0x47,
485 // 0x0N, 0x4C, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
488 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
490 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00
491 CMD_QUERY_MODE = 0x4C,
494 // 0x0N, 0x4D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
496 // 0x00, 0xF3, 0x5A, old value or
497 // AA = 01 unlock large motor (and swap VAL1 and VAL2)
498 // BB = 01 unlock large motor (default)
499 // CC, DD, EE, FF = all FF -> unlock small motor
501 // default repsonse for analog pad with 2 motor : 0x00 0xF3 0x5A 0x00 0x01 0xFF 0xFF 0xFF 0xFF
503 CMD_VIBRATION_TOGGLE = 0x4D,
518 void initBufForRequest(int padIndex, char value){
520 //Pad keystate already in buffer
521 //case CMD_READ_DATA_AND_VIBRATE :
523 case CMD_CONFIG_MODE :
524 if (pad[padIndex].configMode == 1) {
525 memcpy(buf, resp43, 8);
528 //else, not in config mode, pad keystate return (already in the buffer)
530 case CMD_SET_MODE_AND_LOCK :
531 memcpy(buf, resp44, 8);
533 case CMD_QUERY_MODEL_AND_MODE :
534 memcpy(buf, resp45, 8);
535 buf[4] = PadMode[padIndex];
538 memcpy(buf, resp46_00, 8);
540 case CMD_QUERY_COMB :
541 memcpy(buf, resp47, 8);
543 case CMD_QUERY_MODE :
544 memcpy(buf, resp4C_00, 8);
546 case CMD_VIBRATION_TOGGLE :
547 memcpy(buf, resp4D, 8);
550 memcpy(buf, resp40, 8);
553 memcpy(buf, resp41, 8);
556 memcpy(buf, resp49, 8);
559 memcpy(buf, resp4A, 8);
562 memcpy(buf, resp4B, 8);
565 memcpy(buf, resp4E, 8);
568 memcpy(buf, resp4F, 8);
576 void reqIndex2Treatment(int padIndex, char value){
578 case CMD_CONFIG_MODE :
581 pad[padIndex].configMode = 0;
583 pad[padIndex].configMode = 1;
586 case CMD_SET_MODE_AND_LOCK :
587 //0x44 store the led state for change mode if the next value = 0x02
590 ledStateReq44[padIndex] = value;
591 PadMode[padIndex] = value;
596 memcpy(buf, resp46_01, 8);
599 case CMD_QUERY_MODE :
601 memcpy(buf, resp4C_01, 8);
604 case CMD_VIBRATION_TOGGLE :
606 memcpy(buf, resp4D, 8);
608 case CMD_READ_DATA_AND_VIBRATE:
609 //mem the vibration value for small motor;
610 pad[padIndex].Vib[0] = value;
615 void vibrate(int padIndex){
616 if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
617 //value is different update Value and call libretro for vibration
618 pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
619 pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
620 plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
621 //printf("vibration pad %i", padIndex);
628 //Build response for 0x42 request Pad in port
629 void _PADstartPoll(PadDataS *pad) {
630 switch (pad->controllerType) {
631 case PSE_PAD_TYPE_MOUSE:
634 stdpar[2] = pad->buttonStatus & 0xff;
635 stdpar[3] = pad->buttonStatus >> 8;
636 stdpar[4] = pad->moveX;
637 stdpar[5] = pad->moveY;
638 memcpy(buf, stdpar, 6);
641 case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
644 stdpar[2] = pad->buttonStatus & 0xff;
645 stdpar[3] = pad->buttonStatus >> 8;
646 stdpar[4] = pad->rightJoyX;
647 stdpar[5] = pad->rightJoyY;
648 stdpar[6] = pad->leftJoyX;
649 stdpar[7] = pad->leftJoyY;
650 memcpy(buf, stdpar, 8);
653 case PSE_PAD_TYPE_GUNCON: // GUNCON - gun controller SLPH-00034 from Namco
656 stdpar[2] = pad->buttonStatus & 0xff;
657 stdpar[3] = pad->buttonStatus >> 8;
659 //This code assumes an X resolution of 256 and a Y resolution of 240
663 //The code wants an input range for x and y of 0-1023 we passed in -32767 -> 32767
664 int absX = (pad->absoluteX / 64) + 512;
665 int absY = (pad->absoluteY / 64) + 512;
668 if (absX > 1023) absX = 1023;
669 if (absX < 0) absX = 0;
670 if (absY > 1023) absY = 1023;
671 if (absY < 0) absY = 0;
673 stdpar[4] = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10);
674 stdpar[5] = (0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10)) >> 8;
675 stdpar[6] = 0x20 + (yres * absY >> 10);
676 stdpar[7] = (0x20 + (yres * absY >> 10)) >> 8;
678 //Offscreen - Point at the side of the screen so PSX thinks you are pointing offscreen
679 //Required as a mouse can't be offscreen
680 //Coordinates X=0001h, Y=000Ah indicates "no light"
681 //This will mean you cannot shoot the very each of the screen
682 //ToDo read offscreen range from settings if useful to change
683 int OffscreenRange = 2;
684 if (absX < (OffscreenRange) || absX > (1023 - OffscreenRange) || absY < (OffscreenRange) || absY > (1023 - OffscreenRange)) {
691 memcpy(buf, stdpar, 8);
694 case PSE_PAD_TYPE_ANALOGPAD: // scph1150
697 stdpar[2] = pad->buttonStatus & 0xff;
698 stdpar[3] = pad->buttonStatus >> 8;
699 stdpar[4] = pad->rightJoyX;
700 stdpar[5] = pad->rightJoyY;
701 stdpar[6] = pad->leftJoyX;
702 stdpar[7] = pad->leftJoyY;
703 memcpy(buf, stdpar, 8);
706 case PSE_PAD_TYPE_ANALOGJOY: // scph1110
709 stdpar[2] = pad->buttonStatus & 0xff;
710 stdpar[3] = pad->buttonStatus >> 8;
711 stdpar[4] = pad->rightJoyX;
712 stdpar[5] = pad->rightJoyY;
713 stdpar[6] = pad->leftJoyX;
714 stdpar[7] = pad->leftJoyY;
715 memcpy(buf, stdpar, 8);
718 case PSE_PAD_TYPE_STANDARD:
721 stdpar[2] = pad->buttonStatus & 0xff;
722 stdpar[3] = pad->buttonStatus >> 8;
723 //avoid analog value in multitap mode if change pad type in game.
728 memcpy(buf, stdpar, 8);
740 memcpy(buf, stdpar, 8);
747 //Build response for 0x42 request Multitap in port
748 //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)
749 void _PADstartPollMultitap(PadDataS* padd) {
751 for(i = 0; i < 4; i++) {
752 offset = 2 + (i * 8);
753 _PADstartPoll(&padd[i]);
754 memcpy(multitappar+offset, stdpar, 8);
756 memcpy(bufMulti, multitappar, 34);
761 unsigned char _PADpoll(int port, unsigned char value) {
763 //mem the request number
766 // Don't enable Analog/Vibration for a standard pad
767 if (in_type[port] == PSE_PAD_TYPE_STANDARD ||
768 in_type[port] == PSE_PAD_TYPE_NEGCON) {
769 ; // Pad keystate already in buffer
773 //copy the default value of request response in buffer instead of the keystate
774 initBufForRequest(port, value);
778 //if no new request the pad return 0xff, for signaling connected
779 if (reqPos >= respSize
780 #ifdef ICACHE_EMULATION
787 reqIndex2Treatment(port, value);
791 case CMD_SET_MODE_AND_LOCK :
794 case CMD_READ_DATA_AND_VIBRATE:
795 //mem the vibration value for Large motor;
796 pad[port].Vib[1] = value;
798 if (in_type[port] == PSE_PAD_TYPE_STANDARD &&
799 in_type[port] == PSE_PAD_TYPE_NEGCON)
808 return buf[reqPos++];
812 unsigned char _PADpollMultitap(int port, unsigned char value) {
813 if (reqPos >= respSize) return 0xff;
814 return bufMulti[reqPos++];
818 // refresh the button state on port 1.
819 // int pad is not needed.
820 unsigned char CALLBACK PAD1__startPoll(int pad) {
822 // first call the pad provide if a multitap is connected between the psx and himself
823 if (multitap1 == -1) {
825 padd.requestPadIndex = 0;
826 PAD1_readPort1(&padd);
827 multitap1 = padd.portMultitap;
829 // just one pad is on port 1 : NO MULTITAP
830 if (multitap1 == 0) {
832 padd.requestPadIndex = 0;
833 PAD1_readPort1(&padd);
834 _PADstartPoll(&padd);
836 // a multitap is plugged : refresh all pad.
839 for(i = 0; i < 4; i++) {
840 padd[i].requestPadIndex = i;
841 PAD1_readPort1(&padd[i]);
843 _PADstartPollMultitap(padd);
845 //printf("\npad 1 : ");
849 unsigned char CALLBACK PAD1__poll(unsigned char value) {
851 if (multitap1 == 1) {
852 tmp = _PADpollMultitap(0, value);
854 tmp = _PADpoll(0, value);
856 //printf("%2x:%2x, ",value,tmp);
862 long CALLBACK PAD1__configure(void) { return 0; }
863 void CALLBACK PAD1__about(void) {}
864 long CALLBACK PAD1__test(void) { return 0; }
865 long CALLBACK PAD1__query(void) { return 3; }
866 long CALLBACK PAD1__keypressed() { return 0; }
868 #define LoadPad1Sym1(dest, name) \
869 LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
871 #define LoadPad1SymN(dest, name) \
872 LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
874 #define LoadPad1Sym0(dest, name) \
875 LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
876 if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
878 static int LoadPAD1plugin(const char *PAD1dll) {
881 hPAD1Driver = SysLoadLibrary(PAD1dll);
882 if (hPAD1Driver == NULL) {
883 PAD1_configure = NULL;
884 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
887 LoadPad1Sym1(init, "PADinit");
888 LoadPad1Sym1(shutdown, "PADshutdown");
889 LoadPad1Sym1(open, "PADopen");
890 LoadPad1Sym1(close, "PADclose");
891 LoadPad1Sym0(query, "PADquery");
892 LoadPad1Sym1(readPort1, "PADreadPort1");
893 LoadPad1Sym0(configure, "PADconfigure");
894 LoadPad1Sym0(test, "PADtest");
895 LoadPad1Sym0(about, "PADabout");
896 LoadPad1Sym0(keypressed, "PADkeypressed");
897 LoadPad1Sym0(startPoll, "PADstartPoll");
898 LoadPad1Sym0(poll, "PADpoll");
899 LoadPad1SymN(setSensitive, "PADsetSensitive");
904 unsigned char CALLBACK PAD2__startPoll(int pad) {
908 if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
910 } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
916 //first call the pad provide if a multitap is connected between the psx and himself
917 if (multitap2 == -1) {
919 padd.requestPadIndex = pad_index;
920 PAD2_readPort2(&padd);
921 multitap2 = padd.portMultitap;
924 // just one pad is on port 1 : NO MULTITAP
925 if (multitap2 == 0) {
927 padd.requestPadIndex = pad_index;
928 PAD2_readPort2(&padd);
929 _PADstartPoll(&padd);
931 // a multitap is plugged : refresh all pad.
934 for(i = 0; i < 4; i++) {
935 padd[i].requestPadIndex = i+pad_index;
936 PAD2_readPort2(&padd[i]);
938 _PADstartPollMultitap(padd);
940 //printf("\npad 2 : ");
944 unsigned char CALLBACK PAD2__poll(unsigned char value) {
946 if (multitap2 == 2) {
947 tmp = _PADpollMultitap(1, value);
949 tmp = _PADpoll(1, value);
951 //printf("%2x:%2x, ",value,tmp);
955 long CALLBACK PAD2__configure(void) { return 0; }
956 void CALLBACK PAD2__about(void) {}
957 long CALLBACK PAD2__test(void) { return 0; }
958 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
959 long CALLBACK PAD2__keypressed() { return 0; }
961 #define LoadPad2Sym1(dest, name) \
962 LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
964 #define LoadPad2Sym0(dest, name) \
965 LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
966 if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
968 #define LoadPad2SymN(dest, name) \
969 LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
971 static int LoadPAD2plugin(const char *PAD2dll) {
974 hPAD2Driver = SysLoadLibrary(PAD2dll);
975 if (hPAD2Driver == NULL) {
976 PAD2_configure = NULL;
977 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
980 LoadPad2Sym1(init, "PADinit");
981 LoadPad2Sym1(shutdown, "PADshutdown");
982 LoadPad2Sym1(open, "PADopen");
983 LoadPad2Sym1(close, "PADclose");
984 LoadPad2Sym0(query, "PADquery");
985 LoadPad2Sym1(readPort2, "PADreadPort2");
986 LoadPad2Sym0(configure, "PADconfigure");
987 LoadPad2Sym0(test, "PADtest");
988 LoadPad2Sym0(about, "PADabout");
989 LoadPad2Sym0(keypressed, "PADkeypressed");
990 LoadPad2Sym0(startPoll, "PADstartPoll");
991 LoadPad2Sym0(poll, "PADpoll");
992 LoadPad2SymN(setSensitive, "PADsetSensitive");
997 void *hNETDriver = NULL;
999 void CALLBACK NET__setInfo(netInfo *info) {}
1000 void CALLBACK NET__keypressed(int key) {}
1001 long CALLBACK NET__configure(void) { return 0; }
1002 long CALLBACK NET__test(void) { return 0; }
1003 void CALLBACK NET__about(void) {}
1005 #define LoadNetSym1(dest, name) \
1006 LoadSym(NET_##dest, NET##dest, name, TRUE);
1008 #define LoadNetSymN(dest, name) \
1009 LoadSym(NET_##dest, NET##dest, name, FALSE);
1011 #define LoadNetSym0(dest, name) \
1012 LoadSym(NET_##dest, NET##dest, name, FALSE); \
1013 if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
1015 static int LoadNETplugin(const char *NETdll) {
1018 hNETDriver = SysLoadLibrary(NETdll);
1019 if (hNETDriver == NULL) {
1020 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
1023 LoadNetSym1(init, "NETinit");
1024 LoadNetSym1(shutdown, "NETshutdown");
1025 LoadNetSym1(open, "NETopen");
1026 LoadNetSym1(close, "NETclose");
1027 LoadNetSymN(sendData, "NETsendData");
1028 LoadNetSymN(recvData, "NETrecvData");
1029 LoadNetSym1(sendPadData, "NETsendPadData");
1030 LoadNetSym1(recvPadData, "NETrecvPadData");
1031 LoadNetSym1(queryPlayer, "NETqueryPlayer");
1032 LoadNetSym1(pause, "NETpause");
1033 LoadNetSym1(resume, "NETresume");
1034 LoadNetSym0(setInfo, "NETsetInfo");
1035 LoadNetSym0(keypressed, "NETkeypressed");
1036 LoadNetSym0(configure, "NETconfigure");
1037 LoadNetSym0(test, "NETtest");
1038 LoadNetSym0(about, "NETabout");
1043 #ifdef ENABLE_SIO1API
1045 void *hSIO1Driver = NULL;
1047 long CALLBACK SIO1__init(void) { return 0; }
1048 long CALLBACK SIO1__shutdown(void) { return 0; }
1049 long CALLBACK SIO1__open(void) { return 0; }
1050 long CALLBACK SIO1__close(void) { return 0; }
1051 long CALLBACK SIO1__configure(void) { return 0; }
1052 long CALLBACK SIO1__test(void) { return 0; }
1053 void CALLBACK SIO1__about(void) {}
1054 void CALLBACK SIO1__pause(void) {}
1055 void CALLBACK SIO1__resume(void) {}
1056 long CALLBACK SIO1__keypressed(int key) { return 0; }
1057 void CALLBACK SIO1__writeData8(unsigned char val) {}
1058 void CALLBACK SIO1__writeData16(unsigned short val) {}
1059 void CALLBACK SIO1__writeData32(unsigned long val) {}
1060 void CALLBACK SIO1__writeStat16(unsigned short val) {}
1061 void CALLBACK SIO1__writeStat32(unsigned long val) {}
1062 void CALLBACK SIO1__writeMode16(unsigned short val) {}
1063 void CALLBACK SIO1__writeMode32(unsigned long val) {}
1064 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
1065 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
1066 void CALLBACK SIO1__writeBaud16(unsigned short val) {}
1067 void CALLBACK SIO1__writeBaud32(unsigned long val) {}
1068 unsigned char CALLBACK SIO1__readData8(void) { return 0; }
1069 unsigned short CALLBACK SIO1__readData16(void) { return 0; }
1070 unsigned long CALLBACK SIO1__readData32(void) { return 0; }
1071 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
1072 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
1073 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
1074 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
1075 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
1076 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
1077 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
1078 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
1079 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
1081 void CALLBACK SIO1irq(void) {
1082 psxHu32ref(0x1070) |= SWAPu32(0x100);
1085 #define LoadSio1Sym1(dest, name) \
1086 LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
1088 #define LoadSio1SymN(dest, name) \
1089 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
1091 #define LoadSio1Sym0(dest, name) \
1092 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
1093 if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
1095 static int LoadSIO1plugin(const char *SIO1dll) {
1098 hSIO1Driver = SysLoadLibrary(SIO1dll);
1099 if (hSIO1Driver == NULL) {
1100 SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
1104 LoadSio1Sym0(init, "SIO1init");
1105 LoadSio1Sym0(shutdown, "SIO1shutdown");
1106 LoadSio1Sym0(open, "SIO1open");
1107 LoadSio1Sym0(close, "SIO1close");
1108 LoadSio1Sym0(pause, "SIO1pause");
1109 LoadSio1Sym0(resume, "SIO1resume");
1110 LoadSio1Sym0(keypressed, "SIO1keypressed");
1111 LoadSio1Sym0(configure, "SIO1configure");
1112 LoadSio1Sym0(test, "SIO1test");
1113 LoadSio1Sym0(about, "SIO1about");
1114 LoadSio1Sym0(writeData8, "SIO1writeData8");
1115 LoadSio1Sym0(writeData16, "SIO1writeData16");
1116 LoadSio1Sym0(writeData32, "SIO1writeData32");
1117 LoadSio1Sym0(writeStat16, "SIO1writeStat16");
1118 LoadSio1Sym0(writeStat32, "SIO1writeStat32");
1119 LoadSio1Sym0(writeMode16, "SIO1writeMode16");
1120 LoadSio1Sym0(writeMode32, "SIO1writeMode32");
1121 LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
1122 LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
1123 LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
1124 LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
1125 LoadSio1Sym0(readData16, "SIO1readData16");
1126 LoadSio1Sym0(readData32, "SIO1readData32");
1127 LoadSio1Sym0(readStat16, "SIO1readStat16");
1128 LoadSio1Sym0(readStat32, "SIO1readStat32");
1129 LoadSio1Sym0(readMode16, "SIO1readMode16");
1130 LoadSio1Sym0(readMode32, "SIO1readMode32");
1131 LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
1132 LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
1133 LoadSio1Sym0(readBaud16, "SIO1readBaud16");
1134 LoadSio1Sym0(readBaud32, "SIO1readBaud32");
1135 LoadSio1Sym0(registerCallback, "SIO1registerCallback");
1142 void CALLBACK clearDynarec(void) {
1148 char Plugin[MAXPATHLEN * 2];
1154 LoadCDRplugin(NULL);
1156 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1157 if (LoadCDRplugin(Plugin) == -1) return -1;
1160 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
1161 if (LoadGPUplugin(Plugin) == -1) return -1;
1163 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
1164 if (LoadSPUplugin(Plugin) == -1) return -1;
1166 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
1167 if (LoadPAD1plugin(Plugin) == -1) return -1;
1169 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
1170 if (LoadPAD2plugin(Plugin) == -1) return -1;
1172 if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
1173 Config.UseNet = FALSE;
1175 Config.UseNet = TRUE;
1176 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
1177 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
1180 #ifdef ENABLE_SIO1API
1181 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
1182 if (LoadSIO1plugin(Plugin) == -1) return -1;
1186 if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
1188 if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
1190 if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
1192 if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
1194 if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
1196 if (Config.UseNet) {
1198 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
1201 #ifdef ENABLE_SIO1API
1203 if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
1206 SysPrintf(_("Plugins loaded.\n"));
1210 void ReleasePlugins() {
1211 if (Config.UseNet) {
1212 int ret = NET_close();
1213 if (ret < 0) Config.UseNet = FALSE;
1217 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1218 if (hGPUDriver != NULL) GPU_shutdown();
1219 if (hSPUDriver != NULL) SPU_shutdown();
1220 if (hPAD1Driver != NULL) PAD1_shutdown();
1221 if (hPAD2Driver != NULL) PAD2_shutdown();
1223 if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
1225 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1226 if (hGPUDriver != NULL) { SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; }
1227 if (hSPUDriver != NULL) { SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; }
1228 if (hPAD1Driver != NULL) { SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; }
1229 if (hPAD2Driver != NULL) { SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; }
1231 if (Config.UseNet && hNETDriver != NULL) {
1232 SysCloseLibrary(hNETDriver); hNETDriver = NULL;
1235 #ifdef ENABLE_SIO1API
1236 if (hSIO1Driver != NULL) {
1238 SysCloseLibrary(hSIO1Driver);
1245 int ReloadCdromPlugin()
1247 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1248 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1251 LoadCDRplugin(NULL);
1253 char Plugin[MAXPATHLEN * 2];
1254 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1255 if (LoadCDRplugin(Plugin) == -1) return -1;
1261 void SetIsoFile(const char *filename) {
1262 if (filename == NULL) {
1266 strncpy(IsoFile, filename, MAXPATHLEN - 1);
1269 const char *GetIsoFile(void) {
1273 boolean UsingIso(void) {
1274 return (IsoFile[0] != '\0');
1277 void SetCdOpenCaseTime(s64 time) {
1278 cdOpenCaseTime = time;