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;
55 CDRshutdown CDR_shutdown;
61 CDRreadTrack CDR_readTrack;
62 CDRgetBuffer CDR_getBuffer;
65 CDRgetStatus CDR_getStatus;
66 CDRgetDriveLetter CDR_getDriveLetter;
67 CDRgetBufferSub CDR_getBufferSub;
68 CDRconfigure CDR_configure;
70 CDRsetfilename CDR_setfilename;
71 CDRreadCDDA CDR_readCDDA;
74 SPUconfigure SPU_configure;
77 SPUshutdown SPU_shutdown;
81 SPUplaySample SPU_playSample;
82 SPUwriteRegister SPU_writeRegister;
83 SPUreadRegister SPU_readRegister;
84 SPUwriteDMA SPU_writeDMA;
85 SPUreadDMA SPU_readDMA;
86 SPUwriteDMAMem SPU_writeDMAMem;
87 SPUreadDMAMem SPU_readDMAMem;
88 SPUplayADPCMchannel SPU_playADPCMchannel;
90 SPUregisterCallback SPU_registerCallback;
91 SPUregisterScheduleCb SPU_registerScheduleCb;
93 SPUplayCDDAchannel SPU_playCDDAchannel;
95 PADconfigure PAD1_configure;
98 PADshutdown PAD1_shutdown;
103 PADreadPort1 PAD1_readPort1;
104 PADkeypressed PAD1_keypressed;
105 PADstartPoll PAD1_startPoll;
107 PADsetSensitive PAD1_setSensitive;
109 PADconfigure PAD2_configure;
112 PADshutdown PAD2_shutdown;
117 PADreadPort2 PAD2_readPort2;
118 PADkeypressed PAD2_keypressed;
119 PADstartPoll PAD2_startPoll;
121 PADsetSensitive PAD2_setSensitive;
124 NETshutdown NET_shutdown;
128 NETconfigure NET_configure;
131 NETresume NET_resume;
132 NETqueryPlayer NET_queryPlayer;
133 NETsendData NET_sendData;
134 NETrecvData NET_recvData;
135 NETsendPadData NET_sendPadData;
136 NETrecvPadData NET_recvPadData;
137 NETsetInfo NET_setInfo;
138 NETkeypressed NET_keypressed;
140 #ifdef ENABLE_SIO1API
143 SIO1shutdown SIO1_shutdown;
145 SIO1close SIO1_close;
147 SIO1configure SIO1_configure;
148 SIO1about SIO1_about;
149 SIO1pause SIO1_pause;
150 SIO1resume SIO1_resume;
151 SIO1keypressed SIO1_keypressed;
152 SIO1writeData8 SIO1_writeData8;
153 SIO1writeData16 SIO1_writeData16;
154 SIO1writeData32 SIO1_writeData32;
155 SIO1writeStat16 SIO1_writeStat16;
156 SIO1writeStat32 SIO1_writeStat32;
157 SIO1writeMode16 SIO1_writeMode16;
158 SIO1writeMode32 SIO1_writeMode32;
159 SIO1writeCtrl16 SIO1_writeCtrl16;
160 SIO1writeCtrl32 SIO1_writeCtrl32;
161 SIO1writeBaud16 SIO1_writeBaud16;
162 SIO1writeBaud32 SIO1_writeBaud32;
163 SIO1readData8 SIO1_readData8;
164 SIO1readData16 SIO1_readData16;
165 SIO1readData32 SIO1_readData32;
166 SIO1readStat16 SIO1_readStat16;
167 SIO1readStat32 SIO1_readStat32;
168 SIO1readMode16 SIO1_readMode16;
169 SIO1readMode32 SIO1_readMode32;
170 SIO1readCtrl16 SIO1_readCtrl16;
171 SIO1readCtrl32 SIO1_readCtrl32;
172 SIO1readBaud16 SIO1_readBaud16;
173 SIO1readBaud32 SIO1_readBaud32;
174 SIO1registerCallback SIO1_registerCallback;
178 static const char *err;
180 #define CheckErr(func) { \
181 err = SysLibError(); \
182 if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; } \
185 #define LoadSym(dest, src, name, checkerr) { \
186 dest = (src)SysLoadSym(drv, name); \
187 if (checkerr) { CheckErr(name); } else SysLibError(); \
190 void *hGPUDriver = NULL;
192 void CALLBACK GPU__displayText(char *pText) {
193 SysPrintf("%s\n", pText);
196 long CALLBACK GPU__configure(void) { return 0; }
197 long CALLBACK GPU__test(void) { return 0; }
198 void CALLBACK GPU__about(void) {}
199 void CALLBACK GPU__makeSnapshot(void) {}
200 void CALLBACK GPU__keypressed(int key) {}
201 long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
202 long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
203 void CALLBACK GPU__vBlank(int val) {}
205 #define LoadGpuSym1(dest, name) \
206 LoadSym(GPU_##dest, GPU##dest, name, TRUE);
208 #define LoadGpuSym0(dest, name) \
209 LoadSym(GPU_##dest, GPU##dest, name, FALSE); \
210 if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;
212 #define LoadGpuSymN(dest, name) \
213 LoadSym(GPU_##dest, GPU##dest, name, FALSE);
215 static int LoadGPUplugin(const char *GPUdll) {
218 hGPUDriver = SysLoadLibrary(GPUdll);
219 if (hGPUDriver == NULL) {
220 GPU_configure = NULL;
221 SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
224 LoadGpuSym1(init, "GPUinit");
225 LoadGpuSym1(shutdown, "GPUshutdown");
226 LoadGpuSym1(open, "GPUopen");
227 LoadGpuSym1(close, "GPUclose");
228 LoadGpuSym1(readData, "GPUreadData");
229 LoadGpuSym1(readDataMem, "GPUreadDataMem");
230 LoadGpuSym1(readStatus, "GPUreadStatus");
231 LoadGpuSym1(writeData, "GPUwriteData");
232 LoadGpuSym1(writeDataMem, "GPUwriteDataMem");
233 LoadGpuSym1(writeStatus, "GPUwriteStatus");
234 LoadGpuSym1(dmaChain, "GPUdmaChain");
235 LoadGpuSym1(updateLace, "GPUupdateLace");
236 LoadGpuSym0(keypressed, "GPUkeypressed");
237 LoadGpuSym0(displayText, "GPUdisplayText");
238 LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
239 LoadGpuSym1(freeze, "GPUfreeze");
240 LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
241 LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
242 LoadGpuSym0(vBlank, "GPUvBlank");
243 LoadGpuSym0(configure, "GPUconfigure");
244 LoadGpuSym0(test, "GPUtest");
245 LoadGpuSym0(about, "GPUabout");
250 void *hCDRDriver = NULL;
252 long CALLBACK CDR__play(unsigned char *sector) { return 0; }
253 long CALLBACK CDR__stop(void) { return 0; }
255 long CALLBACK CDR__getStatus(struct CdrStat *stat) {
256 if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))
264 char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
265 long CALLBACK CDR__configure(void) { return 0; }
266 long CALLBACK CDR__test(void) { return 0; }
267 void CALLBACK CDR__about(void) {}
268 long CALLBACK CDR__setfilename(char*filename) { return 0; }
270 #define LoadCdrSym1(dest, name) \
271 LoadSym(CDR_##dest, CDR##dest, name, TRUE);
273 #define LoadCdrSym0(dest, name) \
274 LoadSym(CDR_##dest, CDR##dest, name, FALSE); \
275 if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
277 #define LoadCdrSymN(dest, name) \
278 LoadSym(CDR_##dest, CDR##dest, name, FALSE);
280 static int LoadCDRplugin(const char *CDRdll) {
283 if (CDRdll == NULL) {
288 hCDRDriver = SysLoadLibrary(CDRdll);
289 if (hCDRDriver == NULL) {
290 CDR_configure = NULL;
291 SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll); return -1;
294 LoadCdrSym1(init, "CDRinit");
295 LoadCdrSym1(shutdown, "CDRshutdown");
296 LoadCdrSym1(open, "CDRopen");
297 LoadCdrSym1(close, "CDRclose");
298 LoadCdrSym1(getTN, "CDRgetTN");
299 LoadCdrSym1(getTD, "CDRgetTD");
300 LoadCdrSym1(readTrack, "CDRreadTrack");
301 LoadCdrSym1(getBuffer, "CDRgetBuffer");
302 LoadCdrSym1(getBufferSub, "CDRgetBufferSub");
303 LoadCdrSym0(play, "CDRplay");
304 LoadCdrSym0(stop, "CDRstop");
305 LoadCdrSym0(getStatus, "CDRgetStatus");
306 LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
307 LoadCdrSym0(configure, "CDRconfigure");
308 LoadCdrSym0(test, "CDRtest");
309 LoadCdrSym0(about, "CDRabout");
310 LoadCdrSym0(setfilename, "CDRsetfilename");
311 LoadCdrSymN(readCDDA, "CDRreadCDDA");
312 LoadCdrSymN(getTE, "CDRgetTE");
317 void *hSPUDriver = NULL;
319 long CALLBACK SPU__configure(void) { return 0; }
320 void CALLBACK SPU__about(void) {}
321 long CALLBACK SPU__test(void) { return 0; }
322 void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}
324 #define LoadSpuSym1(dest, name) \
325 LoadSym(SPU_##dest, SPU##dest, name, TRUE);
327 #define LoadSpuSym0(dest, name) \
328 LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
329 if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
331 #define LoadSpuSymN(dest, name) \
332 LoadSym(SPU_##dest, SPU##dest, name, FALSE);
334 static int LoadSPUplugin(const char *SPUdll) {
337 hSPUDriver = SysLoadLibrary(SPUdll);
338 if (hSPUDriver == NULL) {
339 SPU_configure = NULL;
340 SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
343 LoadSpuSym1(init, "SPUinit");
344 LoadSpuSym1(shutdown, "SPUshutdown");
345 LoadSpuSym1(open, "SPUopen");
346 LoadSpuSym1(close, "SPUclose");
347 LoadSpuSym0(configure, "SPUconfigure");
348 LoadSpuSym0(about, "SPUabout");
349 LoadSpuSym0(test, "SPUtest");
350 LoadSpuSym1(writeRegister, "SPUwriteRegister");
351 LoadSpuSym1(readRegister, "SPUreadRegister");
352 LoadSpuSym1(writeDMA, "SPUwriteDMA");
353 LoadSpuSym1(readDMA, "SPUreadDMA");
354 LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
355 LoadSpuSym1(readDMAMem, "SPUreadDMAMem");
356 LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");
357 LoadSpuSym1(freeze, "SPUfreeze");
358 LoadSpuSym1(registerCallback, "SPUregisterCallback");
359 LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
360 LoadSpuSymN(async, "SPUasync");
361 LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
366 extern int in_type[8];
368 void *hPAD1Driver = NULL;
369 void *hPAD2Driver = NULL;
371 static int multitap1;
372 static int multitap2;
373 //Pad information, keystate, mode, config mode, vibration
374 static PadDataS pad[8];
376 static int reqPos, respSize, req;
377 static int ledStateReq44[8];
378 static int PadMode[8]; /* 0 : digital 1: analog */
380 static unsigned char buf[256];
381 static unsigned char bufMulti[34] = { 0x80, 0x5a,
382 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
383 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
384 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
385 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
387 unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
388 unsigned char multitappar[34] = { 0x80, 0x5a,
389 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
390 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
391 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
392 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
394 //response for request 44, 45, 46, 47, 4C, 4D
395 static unsigned char resp45[8] = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
396 static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
397 static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
398 static unsigned char resp47[8] = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
399 static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
400 static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
401 static unsigned char resp4D[8] = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};
403 //fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
404 static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
405 static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
406 static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
407 static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
408 static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
409 static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
410 static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
411 static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
412 static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
414 // Resquest of psx core
417 // first call of this request for the pad, the pad is configured as an digital pad.
418 // 0x0X, 0x42, 0x0Y, 0xZZ, 0xAA, 0x00, 0x00, 0x00, 0x00
419 // 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)
420 // Y if 1 : psx request the full length response for the multitap, 3 bytes header and 4 block of 8 bytes per pad
421 // Y if 0 : psx request a pad key state
422 // ZZ rumble small motor 00-> OFF, 01 -> ON
423 // AA rumble large motor speed 0x00 -> 0xFF
427 // PadId -> 0x41 for digital pas, 0x73 for analog pad
428 // 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
429 // 6 Bytes for keystates
430 CMD_READ_DATA_AND_VIBRATE = 0x42,
434 // 0x0N, 0x43, 0x00, XX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
435 // XX = 00 -> Normal mode : Seconde bytes of response = padId
436 // XX = 01 -> Configuration mode : Seconde bytes of response = 0xF3
438 // enter in config mode example :
439 // req : 01 43 00 01 00 00 00 00 00 00
440 // res : 00 41 5A buttons state, analog states
441 // exit config mode :
442 // req : 01 43 00 00 00 00 00 00 00 00
443 // res : 00 F3 5A buttons state, analog states
444 CMD_CONFIG_MODE = 0x43,
448 // 0x0N, 0x44, 0x00, VAL, SEL, 0x00, 0x00, 0x00, 0x00
453 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
454 CMD_SET_MODE_AND_LOCK = 0x44,
456 // Get Analog Led state
458 // 0x0N, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
460 // 0x00, 0xF3, 0x5A, 0x01, 0x02, VAL, 0x02, 0x01, 0x00
463 CMD_QUERY_MODEL_AND_MODE = 0x45,
467 // 0x0N, 0x46, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
470 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A
472 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14
473 CMD_QUERY_ACT = 0x46,
476 // 0x0N, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
478 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00
479 CMD_QUERY_COMB = 0x47,
482 // 0x0N, 0x4C, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
485 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
487 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00
488 CMD_QUERY_MODE = 0x4C,
491 // 0x0N, 0x4D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
493 // 0x00, 0xF3, 0x5A, old value or
494 // AA = 01 unlock large motor (and swap VAL1 and VAL2)
495 // BB = 01 unlock large motor (default)
496 // CC, DD, EE, FF = all FF -> unlock small motor
498 // default repsonse for analog pad with 2 motor : 0x00 0xF3 0x5A 0x00 0x01 0xFF 0xFF 0xFF 0xFF
500 CMD_VIBRATION_TOGGLE = 0x4D,
515 void initBufForRequest(int padIndex, char value){
517 //Pad keystate already in buffer
518 //case CMD_READ_DATA_AND_VIBRATE :
520 case CMD_CONFIG_MODE :
521 if (pad[padIndex].configMode == 1) {
522 memcpy(buf, resp43, 8);
525 //else, not in config mode, pad keystate return (already in the buffer)
527 case CMD_SET_MODE_AND_LOCK :
528 memcpy(buf, resp44, 8);
530 case CMD_QUERY_MODEL_AND_MODE :
531 memcpy(buf, resp45, 8);
532 buf[4] = PadMode[padIndex];
535 memcpy(buf, resp46_00, 8);
537 case CMD_QUERY_COMB :
538 memcpy(buf, resp47, 8);
540 case CMD_QUERY_MODE :
541 memcpy(buf, resp4C_00, 8);
543 case CMD_VIBRATION_TOGGLE :
544 memcpy(buf, resp4D, 8);
547 memcpy(buf, resp40, 8);
550 memcpy(buf, resp41, 8);
553 memcpy(buf, resp49, 8);
556 memcpy(buf, resp4A, 8);
559 memcpy(buf, resp4B, 8);
562 memcpy(buf, resp4E, 8);
565 memcpy(buf, resp4F, 8);
573 void reqIndex2Treatment(int padIndex, char value){
575 case CMD_CONFIG_MODE :
578 pad[padIndex].configMode = 0;
580 pad[padIndex].configMode = 1;
583 case CMD_SET_MODE_AND_LOCK :
584 //0x44 store the led state for change mode if the next value = 0x02
587 ledStateReq44[padIndex] = value;
588 PadMode[padIndex] = value;
593 memcpy(buf, resp46_01, 8);
596 case CMD_QUERY_MODE :
598 memcpy(buf, resp4C_01, 8);
601 case CMD_VIBRATION_TOGGLE :
603 memcpy(buf, resp4D, 8);
605 case CMD_READ_DATA_AND_VIBRATE:
606 //mem the vibration value for small motor;
607 pad[padIndex].Vib[0] = value;
612 void vibrate(int padIndex){
613 if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
614 //value is different update Value and call libretro for vibration
615 pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
616 pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
617 plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
618 //printf("vibration pad %i", padIndex);
625 //Build response for 0x42 request Pad in port
626 void _PADstartPoll(PadDataS *pad) {
627 switch (pad->controllerType) {
628 case PSE_PAD_TYPE_MOUSE:
631 stdpar[2] = pad->buttonStatus & 0xff;
632 stdpar[3] = pad->buttonStatus >> 8;
633 stdpar[4] = pad->moveX;
634 stdpar[5] = pad->moveY;
635 memcpy(buf, stdpar, 6);
638 case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
641 stdpar[2] = pad->buttonStatus & 0xff;
642 stdpar[3] = pad->buttonStatus >> 8;
643 stdpar[4] = pad->rightJoyX;
644 stdpar[5] = pad->rightJoyY;
645 stdpar[6] = pad->leftJoyX;
646 stdpar[7] = pad->leftJoyY;
647 memcpy(buf, stdpar, 8);
650 case PSE_PAD_TYPE_GUNCON: // GUNCON - gun controller SLPH-00034 from Namco
653 stdpar[2] = pad->buttonStatus & 0xff;
654 stdpar[3] = pad->buttonStatus >> 8;
656 //This code assumes an X resolution of 256 and a Y resolution of 240
660 //The code wants an input range for x and y of 0-1023 we passed in -32767 -> 32767
661 int absX = (pad->absoluteX / 64) + 512;
662 int absY = (pad->absoluteY / 64) + 512;
664 if (absX == 65536 || absY == 65536) {
671 stdpar[4] = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10);
672 stdpar[5] = (0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10)) >> 8;
673 stdpar[6] = 0x20 + (yres * absY >> 10);
674 stdpar[7] = (0x20 + (yres * absY >> 10)) >> 8;
677 memcpy(buf, stdpar, 8);
680 case PSE_PAD_TYPE_ANALOGPAD: // scph1150
683 stdpar[2] = pad->buttonStatus & 0xff;
684 stdpar[3] = pad->buttonStatus >> 8;
685 stdpar[4] = pad->rightJoyX;
686 stdpar[5] = pad->rightJoyY;
687 stdpar[6] = pad->leftJoyX;
688 stdpar[7] = pad->leftJoyY;
689 memcpy(buf, stdpar, 8);
692 case PSE_PAD_TYPE_ANALOGJOY: // scph1110
695 stdpar[2] = pad->buttonStatus & 0xff;
696 stdpar[3] = pad->buttonStatus >> 8;
697 stdpar[4] = pad->rightJoyX;
698 stdpar[5] = pad->rightJoyY;
699 stdpar[6] = pad->leftJoyX;
700 stdpar[7] = pad->leftJoyY;
701 memcpy(buf, stdpar, 8);
704 case PSE_PAD_TYPE_STANDARD:
707 stdpar[2] = pad->buttonStatus & 0xff;
708 stdpar[3] = pad->buttonStatus >> 8;
709 //avoid analog value in multitap mode if change pad type in game.
714 memcpy(buf, stdpar, 8);
726 memcpy(buf, stdpar, 8);
733 //Build response for 0x42 request Multitap in port
734 //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)
735 void _PADstartPollMultitap(PadDataS* padd) {
737 for(i = 0; i < 4; i++) {
738 offset = 2 + (i * 8);
739 _PADstartPoll(&padd[i]);
740 memcpy(multitappar+offset, stdpar, 8);
742 memcpy(bufMulti, multitappar, 34);
747 unsigned char _PADpoll(int port, unsigned char value) {
749 //mem the request number
752 // Don't enable Analog/Vibration for a standard pad
753 if (in_type[port] == PSE_PAD_TYPE_STANDARD ||
754 in_type[port] == PSE_PAD_TYPE_NEGCON) {
755 ; // Pad keystate already in buffer
759 //copy the default value of request response in buffer instead of the keystate
760 initBufForRequest(port, value);
764 //if no new request the pad return 0xff, for signaling connected
765 if (reqPos >= respSize)
770 reqIndex2Treatment(port, value);
774 case CMD_SET_MODE_AND_LOCK :
777 case CMD_READ_DATA_AND_VIBRATE:
778 //mem the vibration value for Large motor;
779 pad[port].Vib[1] = value;
781 if (in_type[port] != PSE_PAD_TYPE_ANALOGPAD)
790 return buf[reqPos++];
794 unsigned char _PADpollMultitap(int port, unsigned char value) {
795 if (reqPos >= respSize) return 0xff;
796 return bufMulti[reqPos++];
800 // refresh the button state on port 1.
801 // int pad is not needed.
802 unsigned char CALLBACK PAD1__startPoll(int pad) {
804 // first call the pad provide if a multitap is connected between the psx and himself
805 // just one pad is on port 1 : NO MULTITAP
806 if (multitap1 == 0) {
808 padd.requestPadIndex = 0;
809 PAD1_readPort1(&padd);
810 _PADstartPoll(&padd);
812 // a multitap is plugged : refresh all pad.
815 for(i = 0; i < 4; i++) {
816 padd[i].requestPadIndex = i;
817 PAD1_readPort1(&padd[i]);
819 _PADstartPollMultitap(padd);
821 //printf("\npad 1 : ");
825 unsigned char CALLBACK PAD1__poll(unsigned char value) {
827 if (multitap1 == 1) {
828 tmp = _PADpollMultitap(0, value);
830 tmp = _PADpoll(0, value);
832 //printf("%2x:%2x, ",value,tmp);
838 long CALLBACK PAD1__configure(void) { return 0; }
839 void CALLBACK PAD1__about(void) {}
840 long CALLBACK PAD1__test(void) { return 0; }
841 long CALLBACK PAD1__query(void) { return 3; }
842 long CALLBACK PAD1__keypressed() { return 0; }
844 #define LoadPad1Sym1(dest, name) \
845 LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
847 #define LoadPad1SymN(dest, name) \
848 LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
850 #define LoadPad1Sym0(dest, name) \
851 LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
852 if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
854 static int LoadPAD1plugin(const char *PAD1dll) {
858 hPAD1Driver = SysLoadLibrary(PAD1dll);
859 if (hPAD1Driver == NULL) {
860 PAD1_configure = NULL;
861 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
864 LoadPad1Sym1(init, "PADinit");
865 LoadPad1Sym1(shutdown, "PADshutdown");
866 LoadPad1Sym1(open, "PADopen");
867 LoadPad1Sym1(close, "PADclose");
868 LoadPad1Sym0(query, "PADquery");
869 LoadPad1Sym1(readPort1, "PADreadPort1");
870 LoadPad1Sym0(configure, "PADconfigure");
871 LoadPad1Sym0(test, "PADtest");
872 LoadPad1Sym0(about, "PADabout");
873 LoadPad1Sym0(keypressed, "PADkeypressed");
874 LoadPad1Sym0(startPoll, "PADstartPoll");
875 LoadPad1Sym0(poll, "PADpoll");
876 LoadPad1SymN(setSensitive, "PADsetSensitive");
878 padd.requestPadIndex = 0;
879 PAD1_readPort1(&padd);
880 multitap1 = padd.portMultitap;
885 unsigned char CALLBACK PAD2__startPoll(int pad) {
889 if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
891 } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
897 // just one pad is on port 1 : NO MULTITAP
898 if (multitap2 == 0) {
900 padd.requestPadIndex = pad_index;
901 PAD2_readPort2(&padd);
902 _PADstartPoll(&padd);
904 // a multitap is plugged : refresh all pad.
907 for(i = 0; i < 4; i++) {
908 padd[i].requestPadIndex = i+pad_index;
909 PAD2_readPort2(&padd[i]);
911 _PADstartPollMultitap(padd);
913 //printf("\npad 2 : ");
917 unsigned char CALLBACK PAD2__poll(unsigned char value) {
919 if (multitap2 == 2) {
920 tmp = _PADpollMultitap(1, value);
922 tmp = _PADpoll(1, value);
924 //printf("%2x:%2x, ",value,tmp);
928 long CALLBACK PAD2__configure(void) { return 0; }
929 void CALLBACK PAD2__about(void) {}
930 long CALLBACK PAD2__test(void) { return 0; }
931 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
932 long CALLBACK PAD2__keypressed() { return 0; }
934 #define LoadPad2Sym1(dest, name) \
935 LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
937 #define LoadPad2Sym0(dest, name) \
938 LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
939 if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
941 #define LoadPad2SymN(dest, name) \
942 LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
944 static int LoadPAD2plugin(const char *PAD2dll) {
948 hPAD2Driver = SysLoadLibrary(PAD2dll);
949 if (hPAD2Driver == NULL) {
950 PAD2_configure = NULL;
951 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
954 LoadPad2Sym1(init, "PADinit");
955 LoadPad2Sym1(shutdown, "PADshutdown");
956 LoadPad2Sym1(open, "PADopen");
957 LoadPad2Sym1(close, "PADclose");
958 LoadPad2Sym0(query, "PADquery");
959 LoadPad2Sym1(readPort2, "PADreadPort2");
960 LoadPad2Sym0(configure, "PADconfigure");
961 LoadPad2Sym0(test, "PADtest");
962 LoadPad2Sym0(about, "PADabout");
963 LoadPad2Sym0(keypressed, "PADkeypressed");
964 LoadPad2Sym0(startPoll, "PADstartPoll");
965 LoadPad2Sym0(poll, "PADpoll");
966 LoadPad2SymN(setSensitive, "PADsetSensitive");
968 padd.requestPadIndex = 0;
969 PAD2_readPort2(&padd);
970 multitap2 = padd.portMultitap;
975 void *hNETDriver = NULL;
977 void CALLBACK NET__setInfo(netInfo *info) {}
978 void CALLBACK NET__keypressed(int key) {}
979 long CALLBACK NET__configure(void) { return 0; }
980 long CALLBACK NET__test(void) { return 0; }
981 void CALLBACK NET__about(void) {}
983 #define LoadNetSym1(dest, name) \
984 LoadSym(NET_##dest, NET##dest, name, TRUE);
986 #define LoadNetSymN(dest, name) \
987 LoadSym(NET_##dest, NET##dest, name, FALSE);
989 #define LoadNetSym0(dest, name) \
990 LoadSym(NET_##dest, NET##dest, name, FALSE); \
991 if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
993 static int LoadNETplugin(const char *NETdll) {
996 hNETDriver = SysLoadLibrary(NETdll);
997 if (hNETDriver == NULL) {
998 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
1001 LoadNetSym1(init, "NETinit");
1002 LoadNetSym1(shutdown, "NETshutdown");
1003 LoadNetSym1(open, "NETopen");
1004 LoadNetSym1(close, "NETclose");
1005 LoadNetSymN(sendData, "NETsendData");
1006 LoadNetSymN(recvData, "NETrecvData");
1007 LoadNetSym1(sendPadData, "NETsendPadData");
1008 LoadNetSym1(recvPadData, "NETrecvPadData");
1009 LoadNetSym1(queryPlayer, "NETqueryPlayer");
1010 LoadNetSym1(pause, "NETpause");
1011 LoadNetSym1(resume, "NETresume");
1012 LoadNetSym0(setInfo, "NETsetInfo");
1013 LoadNetSym0(keypressed, "NETkeypressed");
1014 LoadNetSym0(configure, "NETconfigure");
1015 LoadNetSym0(test, "NETtest");
1016 LoadNetSym0(about, "NETabout");
1021 #ifdef ENABLE_SIO1API
1023 void *hSIO1Driver = NULL;
1025 long CALLBACK SIO1__init(void) { return 0; }
1026 long CALLBACK SIO1__shutdown(void) { return 0; }
1027 long CALLBACK SIO1__open(void) { return 0; }
1028 long CALLBACK SIO1__close(void) { return 0; }
1029 long CALLBACK SIO1__configure(void) { return 0; }
1030 long CALLBACK SIO1__test(void) { return 0; }
1031 void CALLBACK SIO1__about(void) {}
1032 void CALLBACK SIO1__pause(void) {}
1033 void CALLBACK SIO1__resume(void) {}
1034 long CALLBACK SIO1__keypressed(int key) { return 0; }
1035 void CALLBACK SIO1__writeData8(unsigned char val) {}
1036 void CALLBACK SIO1__writeData16(unsigned short val) {}
1037 void CALLBACK SIO1__writeData32(unsigned long val) {}
1038 void CALLBACK SIO1__writeStat16(unsigned short val) {}
1039 void CALLBACK SIO1__writeStat32(unsigned long val) {}
1040 void CALLBACK SIO1__writeMode16(unsigned short val) {}
1041 void CALLBACK SIO1__writeMode32(unsigned long val) {}
1042 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
1043 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
1044 void CALLBACK SIO1__writeBaud16(unsigned short val) {}
1045 void CALLBACK SIO1__writeBaud32(unsigned long val) {}
1046 unsigned char CALLBACK SIO1__readData8(void) { return 0; }
1047 unsigned short CALLBACK SIO1__readData16(void) { return 0; }
1048 unsigned long CALLBACK SIO1__readData32(void) { return 0; }
1049 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
1050 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
1051 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
1052 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
1053 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
1054 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
1055 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
1056 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
1057 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
1059 void CALLBACK SIO1irq(void) {
1060 psxHu32ref(0x1070) |= SWAPu32(0x100);
1063 #define LoadSio1Sym1(dest, name) \
1064 LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
1066 #define LoadSio1SymN(dest, name) \
1067 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
1069 #define LoadSio1Sym0(dest, name) \
1070 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
1071 if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
1073 static int LoadSIO1plugin(const char *SIO1dll) {
1076 hSIO1Driver = SysLoadLibrary(SIO1dll);
1077 if (hSIO1Driver == NULL) {
1078 SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
1082 LoadSio1Sym0(init, "SIO1init");
1083 LoadSio1Sym0(shutdown, "SIO1shutdown");
1084 LoadSio1Sym0(open, "SIO1open");
1085 LoadSio1Sym0(close, "SIO1close");
1086 LoadSio1Sym0(pause, "SIO1pause");
1087 LoadSio1Sym0(resume, "SIO1resume");
1088 LoadSio1Sym0(keypressed, "SIO1keypressed");
1089 LoadSio1Sym0(configure, "SIO1configure");
1090 LoadSio1Sym0(test, "SIO1test");
1091 LoadSio1Sym0(about, "SIO1about");
1092 LoadSio1Sym0(writeData8, "SIO1writeData8");
1093 LoadSio1Sym0(writeData16, "SIO1writeData16");
1094 LoadSio1Sym0(writeData32, "SIO1writeData32");
1095 LoadSio1Sym0(writeStat16, "SIO1writeStat16");
1096 LoadSio1Sym0(writeStat32, "SIO1writeStat32");
1097 LoadSio1Sym0(writeMode16, "SIO1writeMode16");
1098 LoadSio1Sym0(writeMode32, "SIO1writeMode32");
1099 LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
1100 LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
1101 LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
1102 LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
1103 LoadSio1Sym0(readData16, "SIO1readData16");
1104 LoadSio1Sym0(readData32, "SIO1readData32");
1105 LoadSio1Sym0(readStat16, "SIO1readStat16");
1106 LoadSio1Sym0(readStat32, "SIO1readStat32");
1107 LoadSio1Sym0(readMode16, "SIO1readMode16");
1108 LoadSio1Sym0(readMode32, "SIO1readMode32");
1109 LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
1110 LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
1111 LoadSio1Sym0(readBaud16, "SIO1readBaud16");
1112 LoadSio1Sym0(readBaud32, "SIO1readBaud32");
1113 LoadSio1Sym0(registerCallback, "SIO1registerCallback");
1122 char Plugin[MAXPATHLEN * 2];
1128 LoadCDRplugin(NULL);
1130 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1131 if (LoadCDRplugin(Plugin) == -1) return -1;
1134 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
1135 if (LoadGPUplugin(Plugin) == -1) return -1;
1137 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
1138 if (LoadSPUplugin(Plugin) == -1) return -1;
1140 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
1141 if (LoadPAD1plugin(Plugin) == -1) return -1;
1143 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
1144 if (LoadPAD2plugin(Plugin) == -1) return -1;
1146 if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
1147 Config.UseNet = FALSE;
1149 Config.UseNet = TRUE;
1150 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
1151 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
1154 #ifdef ENABLE_SIO1API
1155 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
1156 if (LoadSIO1plugin(Plugin) == -1) return -1;
1160 if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
1162 if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
1164 if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
1166 if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
1168 if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
1170 if (Config.UseNet) {
1172 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
1175 #ifdef ENABLE_SIO1API
1177 if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
1180 SysPrintf(_("Plugins loaded.\n"));
1184 void ReleasePlugins() {
1185 if (Config.UseNet) {
1186 int ret = NET_close();
1187 if (ret < 0) Config.UseNet = FALSE;
1191 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1192 if (hGPUDriver != NULL) GPU_shutdown();
1193 if (hSPUDriver != NULL) SPU_shutdown();
1194 if (hPAD1Driver != NULL) PAD1_shutdown();
1195 if (hPAD2Driver != NULL) PAD2_shutdown();
1197 if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
1199 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1200 if (hGPUDriver != NULL) { SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; }
1201 if (hSPUDriver != NULL) { SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; }
1202 if (hPAD1Driver != NULL) { SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; }
1203 if (hPAD2Driver != NULL) { SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; }
1205 if (Config.UseNet && hNETDriver != NULL) {
1206 SysCloseLibrary(hNETDriver); hNETDriver = NULL;
1209 #ifdef ENABLE_SIO1API
1210 if (hSIO1Driver != NULL) {
1212 SysCloseLibrary(hSIO1Driver);
1219 int ReloadCdromPlugin()
1221 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1222 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1225 LoadCDRplugin(NULL);
1227 char Plugin[MAXPATHLEN * 2];
1228 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1229 if (LoadCDRplugin(Plugin) == -1) return -1;
1235 void SetIsoFile(const char *filename) {
1236 if (filename == NULL) {
1240 strncpy(IsoFile, filename, MAXPATHLEN - 1);
1243 const char *GetIsoFile(void) {
1247 boolean UsingIso(void) {
1248 return (IsoFile[0] != '\0');
1251 void SetCdOpenCaseTime(s64 time) {
1252 cdOpenCaseTime = time;