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 void *hPAD1Driver = NULL;
370 void *hPAD2Driver = NULL;
372 static int multitap1 = -1;
373 static int multitap2 = -1;
374 //Pad information, keystate, mode, config mode, vibration
375 static PadDataS pad[8];
377 static int reqPos, respSize, req;
378 static int ledStateReq44[8];
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,
512 static void initBufForRequest(int padIndex, char value) {
514 //Pad keystate already in buffer
515 //case CMD_READ_DATA_AND_VIBRATE :
517 case CMD_CONFIG_MODE :
518 if (pad[padIndex].configMode == 1) {
519 memcpy(buf, resp43, 8);
521 //else, not in config mode, pad keystate return (already in the buffer)
523 case CMD_SET_MODE_AND_LOCK :
524 memcpy(buf, resp44, 8);
526 case CMD_QUERY_MODEL_AND_MODE :
527 memcpy(buf, resp45, 8);
530 memcpy(buf, resp46_00, 8);
532 case CMD_QUERY_COMB :
533 memcpy(buf, resp47, 8);
535 case CMD_QUERY_MODE :
536 memcpy(buf, resp4C_00, 8);
538 case CMD_VIBRATION_TOGGLE :
539 memcpy(buf, resp4D, 8);
542 memcpy(buf, resp40, 8);
545 memcpy(buf, resp41, 8);
548 memcpy(buf, resp49, 8);
551 memcpy(buf, resp4A, 8);
554 memcpy(buf, resp4B, 8);
557 memcpy(buf, resp4E, 8);
560 memcpy(buf, resp4F, 8);
565 static void reqIndex2Treatment(int padIndex, char value) {
567 case CMD_CONFIG_MODE :
570 pad[padIndex].configMode = 0;
572 pad[padIndex].configMode = 1;
575 case CMD_SET_MODE_AND_LOCK :
576 //0x44 store the led state for change mode if the next value = 0x02
579 ledStateReq44[padIndex] = value;
584 memcpy(buf, resp46_01, 8);
587 case CMD_QUERY_MODE :
589 memcpy(buf, resp4C_01, 8);
592 case CMD_VIBRATION_TOGGLE :
594 memcpy(buf, resp4D, 8);
596 case CMD_READ_DATA_AND_VIBRATE:
597 //mem the vibration value for small motor;
598 pad[padIndex].Vib[0] = value;
603 void vibrate(int padIndex) {
604 if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
605 //value is different update Value and call libretro for vibration
606 pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
607 pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
608 plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
609 //printf("vibration pad %i", padIndex);
613 //Build response for 0x42 request Pad in port
614 void _PADstartPoll(PadDataS *pad) {
615 switch (pad->controllerType) {
616 case PSE_PAD_TYPE_MOUSE:
618 stdpar[2] = pad->buttonStatus & 0xff;
619 stdpar[3] = pad->buttonStatus >> 8;
620 stdpar[4] = pad->moveX;
621 stdpar[5] = pad->moveY;
622 memcpy(buf, stdpar, 6);
625 case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
627 stdpar[2] = pad->buttonStatus & 0xff;
628 stdpar[3] = pad->buttonStatus >> 8;
629 stdpar[4] = pad->rightJoyX;
630 stdpar[5] = pad->rightJoyY;
631 stdpar[6] = pad->leftJoyX;
632 stdpar[7] = pad->leftJoyY;
633 memcpy(buf, stdpar, 8);
636 case PSE_PAD_TYPE_ANALOGPAD: // scph1150
638 stdpar[2] = pad->buttonStatus & 0xff;
639 stdpar[3] = pad->buttonStatus >> 8;
640 stdpar[4] = pad->rightJoyX;
641 stdpar[5] = pad->rightJoyY;
642 stdpar[6] = pad->leftJoyX;
643 stdpar[7] = pad->leftJoyY;
644 memcpy(buf, stdpar, 8);
647 case PSE_PAD_TYPE_ANALOGJOY: // scph1110
649 stdpar[2] = pad->buttonStatus & 0xff;
650 stdpar[3] = pad->buttonStatus >> 8;
651 stdpar[4] = pad->rightJoyX;
652 stdpar[5] = pad->rightJoyY;
653 stdpar[6] = pad->leftJoyX;
654 stdpar[7] = pad->leftJoyY;
655 memcpy(buf, stdpar, 8);
658 case PSE_PAD_TYPE_STANDARD:
661 stdpar[2] = pad->buttonStatus & 0xff;
662 stdpar[3] = pad->buttonStatus >> 8;
663 //avoid analog value in multitap mode if change pad type in game.
668 memcpy(buf, stdpar, 8);
673 //Build response for 0x42 request Multitap in port
674 //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)
675 void _PADstartPollMultitap(PadDataS* padd) {
677 for(i = 0; i < 4; i++) {
678 offset = 2 + (i * 8);
679 _PADstartPoll(&padd[i]);
680 memcpy(multitappar+offset, stdpar, 8);
682 memcpy(bufMulti, multitappar, 34);
686 unsigned char _PADpoll(int port, unsigned char value) {
688 //mem the request number
690 //copy the default value of request response in buffer instead of the keystate
691 initBufForRequest(port, value);
694 //if no new request the pad return 0xff, for signaling connected
695 if (reqPos >= respSize) return 0xff;
699 reqIndex2Treatment(port, value);
703 case CMD_SET_MODE_AND_LOCK :
706 case CMD_READ_DATA_AND_VIBRATE:
707 //mem the vibration value for Large motor;
708 pad[port].Vib[1] = value;
715 return buf[reqPos++];
718 unsigned char _PADpollMultitap(int port, unsigned char value) {
719 if (reqPos >= respSize)
722 return bufMulti[reqPos++];
725 // refresh the button state on port 1.
726 // int pad is not needed.
727 unsigned char CALLBACK PAD1__startPoll(int pad) {
729 // first call the pad provide if a multitap is connected between the psx and himself
730 if (multitap1 == -1) {
732 padd.requestPadIndex = 0;
733 PAD1_readPort1(&padd);
734 multitap1 = padd.portMultitap;
736 // just one pad is on port 1 : NO MULTITAP
737 if (multitap1 == 0) {
739 padd.requestPadIndex = 0;
740 PAD1_readPort1(&padd);
741 _PADstartPoll(&padd);
743 // a multitap is plugged : refresh all pad.
746 for(i = 0; i < 4; i++) {
747 padd[i].requestPadIndex = i;
748 PAD1_readPort1(&padd[i]);
750 _PADstartPollMultitap(padd);
752 //printf("\npad 1 : ");
756 unsigned char CALLBACK PAD1__poll(unsigned char value) {
758 if (multitap1 == 1) {
759 tmp = _PADpollMultitap(0, value);
761 tmp = _PADpoll(0, value);
763 //printf("%2x:%2x, ",value,tmp);
768 long CALLBACK PAD1__configure(void) { return 0; }
769 void CALLBACK PAD1__about(void) {}
770 long CALLBACK PAD1__test(void) { return 0; }
771 long CALLBACK PAD1__query(void) { return 3; }
772 long CALLBACK PAD1__keypressed() { return 0; }
774 #define LoadPad1Sym1(dest, name) \
775 LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
777 #define LoadPad1SymN(dest, name) \
778 LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
780 #define LoadPad1Sym0(dest, name) \
781 LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
782 if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
784 static int LoadPAD1plugin(const char *PAD1dll) {
787 hPAD1Driver = SysLoadLibrary(PAD1dll);
788 if (hPAD1Driver == NULL) {
789 PAD1_configure = NULL;
790 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
793 LoadPad1Sym1(init, "PADinit");
794 LoadPad1Sym1(shutdown, "PADshutdown");
795 LoadPad1Sym1(open, "PADopen");
796 LoadPad1Sym1(close, "PADclose");
797 LoadPad1Sym0(query, "PADquery");
798 LoadPad1Sym1(readPort1, "PADreadPort1");
799 LoadPad1Sym0(configure, "PADconfigure");
800 LoadPad1Sym0(test, "PADtest");
801 LoadPad1Sym0(about, "PADabout");
802 LoadPad1Sym0(keypressed, "PADkeypressed");
803 LoadPad1Sym0(startPoll, "PADstartPoll");
804 LoadPad1Sym0(poll, "PADpoll");
805 LoadPad1SymN(setSensitive, "PADsetSensitive");
810 unsigned char CALLBACK PAD2__startPoll(int pad) {
814 if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
816 } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
822 //first call the pad provide if a multitap is connected between the psx and himself
823 if (multitap2 == -1) {
825 padd.requestPadIndex = pad_index;
826 PAD2_readPort2(&padd);
827 multitap2 = padd.portMultitap;
830 // just one pad is on port 1 : NO MULTITAP
831 if (multitap2 == 0) {
833 padd.requestPadIndex = pad_index;
834 PAD2_readPort2(&padd);
835 _PADstartPoll(&padd);
837 // a multitap is plugged : refresh all pad.
840 for(i = 0; i < 4; i++) {
841 padd[i].requestPadIndex = i+pad_index;
842 PAD2_readPort2(&padd[i]);
844 _PADstartPollMultitap(padd);
846 //printf("\npad 2 : ");
850 unsigned char CALLBACK PAD2__poll(unsigned char value) {
852 if (multitap2 == 2) {
853 tmp = _PADpollMultitap(1, value);
855 tmp = _PADpoll(1, value);
857 //printf("%2x:%2x, ",value,tmp);
861 long CALLBACK PAD2__configure(void) { return 0; }
862 void CALLBACK PAD2__about(void) {}
863 long CALLBACK PAD2__test(void) { return 0; }
864 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
865 long CALLBACK PAD2__keypressed() { return 0; }
867 #define LoadPad2Sym1(dest, name) \
868 LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
870 #define LoadPad2Sym0(dest, name) \
871 LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
872 if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
874 #define LoadPad2SymN(dest, name) \
875 LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
877 static int LoadPAD2plugin(const char *PAD2dll) {
880 hPAD2Driver = SysLoadLibrary(PAD2dll);
881 if (hPAD2Driver == NULL) {
882 PAD2_configure = NULL;
883 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
886 LoadPad2Sym1(init, "PADinit");
887 LoadPad2Sym1(shutdown, "PADshutdown");
888 LoadPad2Sym1(open, "PADopen");
889 LoadPad2Sym1(close, "PADclose");
890 LoadPad2Sym0(query, "PADquery");
891 LoadPad2Sym1(readPort2, "PADreadPort2");
892 LoadPad2Sym0(configure, "PADconfigure");
893 LoadPad2Sym0(test, "PADtest");
894 LoadPad2Sym0(about, "PADabout");
895 LoadPad2Sym0(keypressed, "PADkeypressed");
896 LoadPad2Sym0(startPoll, "PADstartPoll");
897 LoadPad2Sym0(poll, "PADpoll");
898 LoadPad2SymN(setSensitive, "PADsetSensitive");
903 void *hNETDriver = NULL;
905 void CALLBACK NET__setInfo(netInfo *info) {}
906 void CALLBACK NET__keypressed(int key) {}
907 long CALLBACK NET__configure(void) { return 0; }
908 long CALLBACK NET__test(void) { return 0; }
909 void CALLBACK NET__about(void) {}
911 #define LoadNetSym1(dest, name) \
912 LoadSym(NET_##dest, NET##dest, name, TRUE);
914 #define LoadNetSymN(dest, name) \
915 LoadSym(NET_##dest, NET##dest, name, FALSE);
917 #define LoadNetSym0(dest, name) \
918 LoadSym(NET_##dest, NET##dest, name, FALSE); \
919 if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
921 static int LoadNETplugin(const char *NETdll) {
924 hNETDriver = SysLoadLibrary(NETdll);
925 if (hNETDriver == NULL) {
926 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
929 LoadNetSym1(init, "NETinit");
930 LoadNetSym1(shutdown, "NETshutdown");
931 LoadNetSym1(open, "NETopen");
932 LoadNetSym1(close, "NETclose");
933 LoadNetSymN(sendData, "NETsendData");
934 LoadNetSymN(recvData, "NETrecvData");
935 LoadNetSym1(sendPadData, "NETsendPadData");
936 LoadNetSym1(recvPadData, "NETrecvPadData");
937 LoadNetSym1(queryPlayer, "NETqueryPlayer");
938 LoadNetSym1(pause, "NETpause");
939 LoadNetSym1(resume, "NETresume");
940 LoadNetSym0(setInfo, "NETsetInfo");
941 LoadNetSym0(keypressed, "NETkeypressed");
942 LoadNetSym0(configure, "NETconfigure");
943 LoadNetSym0(test, "NETtest");
944 LoadNetSym0(about, "NETabout");
949 #ifdef ENABLE_SIO1API
951 void *hSIO1Driver = NULL;
953 long CALLBACK SIO1__init(void) { return 0; }
954 long CALLBACK SIO1__shutdown(void) { return 0; }
955 long CALLBACK SIO1__open(void) { return 0; }
956 long CALLBACK SIO1__close(void) { return 0; }
957 long CALLBACK SIO1__configure(void) { return 0; }
958 long CALLBACK SIO1__test(void) { return 0; }
959 void CALLBACK SIO1__about(void) {}
960 void CALLBACK SIO1__pause(void) {}
961 void CALLBACK SIO1__resume(void) {}
962 long CALLBACK SIO1__keypressed(int key) { return 0; }
963 void CALLBACK SIO1__writeData8(unsigned char val) {}
964 void CALLBACK SIO1__writeData16(unsigned short val) {}
965 void CALLBACK SIO1__writeData32(unsigned long val) {}
966 void CALLBACK SIO1__writeStat16(unsigned short val) {}
967 void CALLBACK SIO1__writeStat32(unsigned long val) {}
968 void CALLBACK SIO1__writeMode16(unsigned short val) {}
969 void CALLBACK SIO1__writeMode32(unsigned long val) {}
970 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
971 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
972 void CALLBACK SIO1__writeBaud16(unsigned short val) {}
973 void CALLBACK SIO1__writeBaud32(unsigned long val) {}
974 unsigned char CALLBACK SIO1__readData8(void) { return 0; }
975 unsigned short CALLBACK SIO1__readData16(void) { return 0; }
976 unsigned long CALLBACK SIO1__readData32(void) { return 0; }
977 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
978 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
979 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
980 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
981 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
982 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
983 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
984 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
985 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
987 void CALLBACK SIO1irq(void) {
988 psxHu32ref(0x1070) |= SWAPu32(0x100);
991 #define LoadSio1Sym1(dest, name) \
992 LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
994 #define LoadSio1SymN(dest, name) \
995 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
997 #define LoadSio1Sym0(dest, name) \
998 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
999 if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
1001 static int LoadSIO1plugin(const char *SIO1dll) {
1004 hSIO1Driver = SysLoadLibrary(SIO1dll);
1005 if (hSIO1Driver == NULL) {
1006 SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
1010 LoadSio1Sym0(init, "SIO1init");
1011 LoadSio1Sym0(shutdown, "SIO1shutdown");
1012 LoadSio1Sym0(open, "SIO1open");
1013 LoadSio1Sym0(close, "SIO1close");
1014 LoadSio1Sym0(pause, "SIO1pause");
1015 LoadSio1Sym0(resume, "SIO1resume");
1016 LoadSio1Sym0(keypressed, "SIO1keypressed");
1017 LoadSio1Sym0(configure, "SIO1configure");
1018 LoadSio1Sym0(test, "SIO1test");
1019 LoadSio1Sym0(about, "SIO1about");
1020 LoadSio1Sym0(writeData8, "SIO1writeData8");
1021 LoadSio1Sym0(writeData16, "SIO1writeData16");
1022 LoadSio1Sym0(writeData32, "SIO1writeData32");
1023 LoadSio1Sym0(writeStat16, "SIO1writeStat16");
1024 LoadSio1Sym0(writeStat32, "SIO1writeStat32");
1025 LoadSio1Sym0(writeMode16, "SIO1writeMode16");
1026 LoadSio1Sym0(writeMode32, "SIO1writeMode32");
1027 LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
1028 LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
1029 LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
1030 LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
1031 LoadSio1Sym0(readData16, "SIO1readData16");
1032 LoadSio1Sym0(readData32, "SIO1readData32");
1033 LoadSio1Sym0(readStat16, "SIO1readStat16");
1034 LoadSio1Sym0(readStat32, "SIO1readStat32");
1035 LoadSio1Sym0(readMode16, "SIO1readMode16");
1036 LoadSio1Sym0(readMode32, "SIO1readMode32");
1037 LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
1038 LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
1039 LoadSio1Sym0(readBaud16, "SIO1readBaud16");
1040 LoadSio1Sym0(readBaud32, "SIO1readBaud32");
1041 LoadSio1Sym0(registerCallback, "SIO1registerCallback");
1048 void CALLBACK clearDynarec(void) {
1054 char Plugin[MAXPATHLEN];
1060 LoadCDRplugin(NULL);
1062 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1063 if (LoadCDRplugin(Plugin) == -1) return -1;
1066 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
1067 if (LoadGPUplugin(Plugin) == -1) return -1;
1069 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
1070 if (LoadSPUplugin(Plugin) == -1) return -1;
1072 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
1073 if (LoadPAD1plugin(Plugin) == -1) return -1;
1075 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
1076 if (LoadPAD2plugin(Plugin) == -1) return -1;
1078 if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
1079 Config.UseNet = FALSE;
1081 Config.UseNet = TRUE;
1082 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
1083 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
1086 #ifdef ENABLE_SIO1API
1087 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
1088 if (LoadSIO1plugin(Plugin) == -1) return -1;
1092 if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
1094 if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
1096 if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
1098 if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
1100 if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
1102 if (Config.UseNet) {
1104 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
1107 #ifdef ENABLE_SIO1API
1109 if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
1112 SysPrintf(_("Plugins loaded.\n"));
1116 void ReleasePlugins() {
1117 if (Config.UseNet) {
1118 int ret = NET_close();
1119 if (ret < 0) Config.UseNet = FALSE;
1123 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1124 if (hGPUDriver != NULL) GPU_shutdown();
1125 if (hSPUDriver != NULL) SPU_shutdown();
1126 if (hPAD1Driver != NULL) PAD1_shutdown();
1127 if (hPAD2Driver != NULL) PAD2_shutdown();
1129 if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
1131 if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;
1132 if (hGPUDriver != NULL) SysCloseLibrary(hGPUDriver); hGPUDriver = NULL;
1133 if (hSPUDriver != NULL) SysCloseLibrary(hSPUDriver); hSPUDriver = NULL;
1134 if (hPAD1Driver != NULL) SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL;
1135 if (hPAD2Driver != NULL) SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL;
1137 if (Config.UseNet && hNETDriver != NULL) {
1138 SysCloseLibrary(hNETDriver); hNETDriver = NULL;
1141 #ifdef ENABLE_SIO1API
1142 if (hSIO1Driver != NULL) {
1144 SysCloseLibrary(hSIO1Driver);
1151 int ReloadCdromPlugin()
1153 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1154 if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;
1157 LoadCDRplugin(NULL);
1159 char Plugin[MAXPATHLEN];
1160 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1161 if (LoadCDRplugin(Plugin) == -1) return -1;
1167 void SetIsoFile(const char *filename) {
1168 if (filename == NULL) {
1172 strncpy(IsoFile, filename, MAXPATHLEN);
1175 const char *GetIsoFile(void) {
1179 boolean UsingIso(void) {
1180 return (IsoFile[0] != '\0');
1183 void SetCdOpenCaseTime(s64 time) {
1184 cdOpenCaseTime = time;