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.
27 static char IsoFile[MAXPATHLEN] = "";
28 static s64 cdOpenCaseTime = 0;
30 GPUupdateLace GPU_updateLace;
32 GPUshutdown GPU_shutdown;
33 GPUconfigure GPU_configure;
38 GPUreadStatus GPU_readStatus;
39 GPUreadData GPU_readData;
40 GPUreadDataMem GPU_readDataMem;
41 GPUwriteStatus GPU_writeStatus;
42 GPUwriteData GPU_writeData;
43 GPUwriteDataMem GPU_writeDataMem;
44 GPUdmaChain GPU_dmaChain;
45 GPUkeypressed GPU_keypressed;
46 GPUdisplayText GPU_displayText;
47 GPUmakeSnapshot GPU_makeSnapshot;
49 GPUgetScreenPic GPU_getScreenPic;
50 GPUshowScreenPic GPU_showScreenPic;
54 CDRshutdown CDR_shutdown;
60 CDRreadTrack CDR_readTrack;
61 CDRgetBuffer CDR_getBuffer;
64 CDRgetStatus CDR_getStatus;
65 CDRgetDriveLetter CDR_getDriveLetter;
66 CDRgetBufferSub CDR_getBufferSub;
67 CDRconfigure CDR_configure;
69 CDRsetfilename CDR_setfilename;
70 CDRreadCDDA CDR_readCDDA;
74 SPUshutdown SPU_shutdown;
77 SPUwriteRegister SPU_writeRegister;
78 SPUreadRegister SPU_readRegister;
79 SPUwriteDMAMem SPU_writeDMAMem;
80 SPUreadDMAMem SPU_readDMAMem;
81 SPUplayADPCMchannel SPU_playADPCMchannel;
83 SPUregisterCallback SPU_registerCallback;
84 SPUregisterScheduleCb SPU_registerScheduleCb;
86 SPUplayCDDAchannel SPU_playCDDAchannel;
88 PADconfigure PAD1_configure;
91 PADshutdown PAD1_shutdown;
96 PADreadPort1 PAD1_readPort1;
97 PADkeypressed PAD1_keypressed;
98 PADstartPoll PAD1_startPoll;
100 PADsetSensitive PAD1_setSensitive;
102 PADconfigure PAD2_configure;
105 PADshutdown PAD2_shutdown;
110 PADreadPort2 PAD2_readPort2;
111 PADkeypressed PAD2_keypressed;
112 PADstartPoll PAD2_startPoll;
114 PADsetSensitive PAD2_setSensitive;
117 NETshutdown NET_shutdown;
121 NETconfigure NET_configure;
124 NETresume NET_resume;
125 NETqueryPlayer NET_queryPlayer;
126 NETsendData NET_sendData;
127 NETrecvData NET_recvData;
128 NETsendPadData NET_sendPadData;
129 NETrecvPadData NET_recvPadData;
130 NETsetInfo NET_setInfo;
131 NETkeypressed NET_keypressed;
133 #ifdef ENABLE_SIO1API
136 SIO1shutdown SIO1_shutdown;
138 SIO1close SIO1_close;
140 SIO1configure SIO1_configure;
141 SIO1about SIO1_about;
142 SIO1pause SIO1_pause;
143 SIO1resume SIO1_resume;
144 SIO1keypressed SIO1_keypressed;
145 SIO1writeData8 SIO1_writeData8;
146 SIO1writeData16 SIO1_writeData16;
147 SIO1writeData32 SIO1_writeData32;
148 SIO1writeStat16 SIO1_writeStat16;
149 SIO1writeStat32 SIO1_writeStat32;
150 SIO1writeMode16 SIO1_writeMode16;
151 SIO1writeMode32 SIO1_writeMode32;
152 SIO1writeCtrl16 SIO1_writeCtrl16;
153 SIO1writeCtrl32 SIO1_writeCtrl32;
154 SIO1writeBaud16 SIO1_writeBaud16;
155 SIO1writeBaud32 SIO1_writeBaud32;
156 SIO1readData8 SIO1_readData8;
157 SIO1readData16 SIO1_readData16;
158 SIO1readData32 SIO1_readData32;
159 SIO1readStat16 SIO1_readStat16;
160 SIO1readStat32 SIO1_readStat32;
161 SIO1readMode16 SIO1_readMode16;
162 SIO1readMode32 SIO1_readMode32;
163 SIO1readCtrl16 SIO1_readCtrl16;
164 SIO1readCtrl32 SIO1_readCtrl32;
165 SIO1readBaud16 SIO1_readBaud16;
166 SIO1readBaud32 SIO1_readBaud32;
167 SIO1registerCallback SIO1_registerCallback;
171 static const char *err;
173 #define CheckErr(func) { \
174 err = SysLibError(); \
175 if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; } \
178 #define LoadSym(dest, src, name, checkerr) { \
179 dest = (src)SysLoadSym(drv, name); \
180 if (checkerr) { CheckErr(name); } else SysLibError(); \
183 void *hGPUDriver = NULL;
185 void CALLBACK GPU__displayText(char *pText) {
186 SysPrintf("%s\n", pText);
189 long CALLBACK GPU__configure(void) { return 0; }
190 long CALLBACK GPU__test(void) { return 0; }
191 void CALLBACK GPU__about(void) {}
192 void CALLBACK GPU__makeSnapshot(void) {}
193 void CALLBACK GPU__keypressed(int key) {}
194 long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
195 long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
196 void CALLBACK GPU__vBlank(int val) {}
198 #define LoadGpuSym1(dest, name) \
199 LoadSym(GPU_##dest, GPU##dest, name, TRUE);
201 #define LoadGpuSym0(dest, name) \
202 LoadSym(GPU_##dest, GPU##dest, name, FALSE); \
203 if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;
205 #define LoadGpuSymN(dest, name) \
206 LoadSym(GPU_##dest, GPU##dest, name, FALSE);
208 static int LoadGPUplugin(const char *GPUdll) {
211 hGPUDriver = SysLoadLibrary(GPUdll);
212 if (hGPUDriver == NULL) {
213 GPU_configure = NULL;
214 SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
217 LoadGpuSym1(init, "GPUinit");
218 LoadGpuSym1(shutdown, "GPUshutdown");
219 LoadGpuSym1(open, "GPUopen");
220 LoadGpuSym1(close, "GPUclose");
221 LoadGpuSym1(readData, "GPUreadData");
222 LoadGpuSym1(readDataMem, "GPUreadDataMem");
223 LoadGpuSym1(readStatus, "GPUreadStatus");
224 LoadGpuSym1(writeData, "GPUwriteData");
225 LoadGpuSym1(writeDataMem, "GPUwriteDataMem");
226 LoadGpuSym1(writeStatus, "GPUwriteStatus");
227 LoadGpuSym1(dmaChain, "GPUdmaChain");
228 LoadGpuSym1(updateLace, "GPUupdateLace");
229 LoadGpuSym0(keypressed, "GPUkeypressed");
230 LoadGpuSym0(displayText, "GPUdisplayText");
231 LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
232 LoadGpuSym1(freeze, "GPUfreeze");
233 LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
234 LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
235 LoadGpuSym0(vBlank, "GPUvBlank");
236 LoadGpuSym0(configure, "GPUconfigure");
237 LoadGpuSym0(test, "GPUtest");
238 LoadGpuSym0(about, "GPUabout");
243 void *hCDRDriver = NULL;
245 long CALLBACK CDR__play(unsigned char *sector) { return 0; }
246 long CALLBACK CDR__stop(void) { return 0; }
248 long CALLBACK CDR__getStatus(struct CdrStat *stat) {
249 if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))
257 char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
258 long CALLBACK CDR__configure(void) { return 0; }
259 long CALLBACK CDR__test(void) { return 0; }
260 void CALLBACK CDR__about(void) {}
261 long CALLBACK CDR__setfilename(char*filename) { return 0; }
263 #define LoadCdrSym1(dest, name) \
264 LoadSym(CDR_##dest, CDR##dest, name, TRUE);
266 #define LoadCdrSym0(dest, name) \
267 LoadSym(CDR_##dest, CDR##dest, name, FALSE); \
268 if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
270 #define LoadCdrSymN(dest, name) \
271 LoadSym(CDR_##dest, CDR##dest, name, FALSE);
273 static int LoadCDRplugin(const char *CDRdll) {
276 if (CDRdll == NULL) {
281 hCDRDriver = SysLoadLibrary(CDRdll);
282 if (hCDRDriver == NULL) {
283 CDR_configure = NULL;
284 SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll); return -1;
287 LoadCdrSym1(init, "CDRinit");
288 LoadCdrSym1(shutdown, "CDRshutdown");
289 LoadCdrSym1(open, "CDRopen");
290 LoadCdrSym1(close, "CDRclose");
291 LoadCdrSym1(getTN, "CDRgetTN");
292 LoadCdrSym1(getTD, "CDRgetTD");
293 LoadCdrSym1(readTrack, "CDRreadTrack");
294 LoadCdrSym1(getBuffer, "CDRgetBuffer");
295 LoadCdrSym1(getBufferSub, "CDRgetBufferSub");
296 LoadCdrSym0(play, "CDRplay");
297 LoadCdrSym0(stop, "CDRstop");
298 LoadCdrSym0(getStatus, "CDRgetStatus");
299 LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
300 LoadCdrSym0(configure, "CDRconfigure");
301 LoadCdrSym0(test, "CDRtest");
302 LoadCdrSym0(about, "CDRabout");
303 LoadCdrSym0(setfilename, "CDRsetfilename");
304 LoadCdrSymN(readCDDA, "CDRreadCDDA");
305 LoadCdrSymN(getTE, "CDRgetTE");
310 static void *hSPUDriver = NULL;
\r
311 static void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}
\r
313 #define LoadSpuSym1(dest, name) \
314 LoadSym(SPU_##dest, SPU##dest, name, TRUE);
316 #define LoadSpuSym0(dest, name) \
317 LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
318 if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
320 #define LoadSpuSymN(dest, name) \
321 LoadSym(SPU_##dest, SPU##dest, name, FALSE);
323 static int LoadSPUplugin(const char *SPUdll) {
326 hSPUDriver = SysLoadLibrary(SPUdll);
327 if (hSPUDriver == NULL) {
328 SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
331 LoadSpuSym1(init, "SPUinit");
332 LoadSpuSym1(shutdown, "SPUshutdown");
333 LoadSpuSym1(open, "SPUopen");
334 LoadSpuSym1(close, "SPUclose");
335 LoadSpuSym1(writeRegister, "SPUwriteRegister");
336 LoadSpuSym1(readRegister, "SPUreadRegister");
337 LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
338 LoadSpuSym1(readDMAMem, "SPUreadDMAMem");
339 LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");
340 LoadSpuSym1(freeze, "SPUfreeze");
341 LoadSpuSym1(registerCallback, "SPUregisterCallback");
342 LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
343 LoadSpuSymN(async, "SPUasync");
344 LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
349 extern int in_type[8];
351 void *hPAD1Driver = NULL;
352 void *hPAD2Driver = NULL;
354 static int multitap1;
355 static int multitap2;
356 //Pad information, keystate, mode, config mode, vibration
357 static PadDataS pad[8];
359 static int reqPos, respSize;
360 static int ledStateReq44[8];
361 static int PadMode[8]; /* 0 : digital 1: analog */
363 static unsigned char buf[256];
364 static unsigned char bufMulti[34] = { 0x80, 0x5a,
365 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
366 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
367 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
368 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
370 unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
371 unsigned char multitappar[34] = { 0x80, 0x5a,
372 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
373 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
374 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
375 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
377 //response for request 44, 45, 46, 47, 4C, 4D
378 static unsigned char resp45[8] = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
379 static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
380 static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
381 static unsigned char resp47[8] = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
382 static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
383 static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
384 static unsigned char resp4D[8] = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};
386 //fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
387 static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
388 static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
389 static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
390 static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
391 static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
392 static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
393 static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
394 static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
395 static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
397 // Resquest of psx core
400 // first call of this request for the pad, the pad is configured as an digital pad.
401 // 0x0X, 0x42, 0x0Y, 0xZZ, 0xAA, 0x00, 0x00, 0x00, 0x00
402 // 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)
403 // Y if 1 : psx request the full length response for the multitap, 3 bytes header and 4 block of 8 bytes per pad
404 // Y if 0 : psx request a pad key state
405 // ZZ rumble small motor 00-> OFF, 01 -> ON
406 // AA rumble large motor speed 0x00 -> 0xFF
410 // PadId -> 0x41 for digital pas, 0x73 for analog pad
411 // 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
412 // 6 Bytes for keystates
413 CMD_READ_DATA_AND_VIBRATE = 0x42,
417 // 0x0N, 0x43, 0x00, XX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
418 // XX = 00 -> Normal mode : Seconde bytes of response = padId
419 // XX = 01 -> Configuration mode : Seconde bytes of response = 0xF3
421 // enter in config mode example :
422 // req : 01 43 00 01 00 00 00 00 00 00
423 // res : 00 41 5A buttons state, analog states
424 // exit config mode :
425 // req : 01 43 00 00 00 00 00 00 00 00
426 // res : 00 F3 5A buttons state, analog states
427 CMD_CONFIG_MODE = 0x43,
431 // 0x0N, 0x44, 0x00, VAL, SEL, 0x00, 0x00, 0x00, 0x00
436 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
437 CMD_SET_MODE_AND_LOCK = 0x44,
439 // Get Analog Led state
441 // 0x0N, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
443 // 0x00, 0xF3, 0x5A, 0x01, 0x02, VAL, 0x02, 0x01, 0x00
446 CMD_QUERY_MODEL_AND_MODE = 0x45,
450 // 0x0N, 0x46, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
453 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A
455 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14
456 CMD_QUERY_ACT = 0x46,
459 // 0x0N, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
461 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00
462 CMD_QUERY_COMB = 0x47,
465 // 0x0N, 0x4C, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
468 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
470 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00
471 CMD_QUERY_MODE = 0x4C,
474 // 0x0N, 0x4D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
476 // 0x00, 0xF3, 0x5A, old value or
477 // AA = 01 unlock large motor (and swap VAL1 and VAL2)
478 // BB = 01 unlock large motor (default)
479 // CC, DD, EE, FF = all FF -> unlock small motor
481 // default repsonse for analog pad with 2 motor : 0x00 0xF3 0x5A 0x00 0x01 0xFF 0xFF 0xFF 0xFF
483 CMD_VIBRATION_TOGGLE = 0x4D,
498 void initBufForRequest(int padIndex, char value){
500 //Pad keystate already in buffer
501 //case CMD_READ_DATA_AND_VIBRATE :
503 case CMD_CONFIG_MODE :
504 if (pad[padIndex].configMode == 1) {
505 memcpy(buf, resp43, 8);
508 //else, not in config mode, pad keystate return (already in the buffer)
510 case CMD_SET_MODE_AND_LOCK :
511 memcpy(buf, resp44, 8);
513 case CMD_QUERY_MODEL_AND_MODE :
514 memcpy(buf, resp45, 8);
515 buf[4] = PadMode[padIndex];
518 memcpy(buf, resp46_00, 8);
520 case CMD_QUERY_COMB :
521 memcpy(buf, resp47, 8);
523 case CMD_QUERY_MODE :
524 memcpy(buf, resp4C_00, 8);
526 case CMD_VIBRATION_TOGGLE :
527 memcpy(buf, resp4D, 8);
530 memcpy(buf, resp40, 8);
533 memcpy(buf, resp41, 8);
536 memcpy(buf, resp49, 8);
539 memcpy(buf, resp4A, 8);
542 memcpy(buf, resp4B, 8);
545 memcpy(buf, resp4E, 8);
548 memcpy(buf, resp4F, 8);
556 static void reqIndex2Treatment(int padIndex, char value) {
557 switch (pad[padIndex].txData[0]) {
558 case CMD_CONFIG_MODE :
561 pad[padIndex].configMode = 0;
563 pad[padIndex].configMode = 1;
566 case CMD_SET_MODE_AND_LOCK :
567 //0x44 store the led state for change mode if the next value = 0x02
570 ledStateReq44[padIndex] = value;
571 PadMode[padIndex] = value;
576 memcpy(buf, resp46_01, 8);
579 case CMD_QUERY_MODE :
581 memcpy(buf, resp4C_01, 8);
584 case CMD_VIBRATION_TOGGLE :
586 memcpy(buf, resp4D, 8);
588 case CMD_READ_DATA_AND_VIBRATE:
589 //mem the vibration value for small motor;
590 pad[padIndex].Vib[0] = value;
595 void vibrate(int padIndex){
596 if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
597 //value is different update Value and call libretro for vibration
598 pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
599 pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
600 plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
601 //printf("vibration pad %i", padIndex);
608 //Build response for 0x42 request Pad in port
609 void _PADstartPoll(PadDataS *pad) {
610 switch (pad->controllerType) {
611 case PSE_PAD_TYPE_MOUSE:
614 stdpar[2] = pad->buttonStatus & 0xff;
615 stdpar[3] = pad->buttonStatus >> 8;
616 stdpar[4] = pad->moveX;
617 stdpar[5] = pad->moveY;
618 memcpy(buf, stdpar, 6);
621 case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
624 stdpar[2] = pad->buttonStatus & 0xff;
625 stdpar[3] = pad->buttonStatus >> 8;
626 stdpar[4] = pad->rightJoyX;
627 stdpar[5] = pad->rightJoyY;
628 stdpar[6] = pad->leftJoyX;
629 stdpar[7] = pad->leftJoyY;
630 memcpy(buf, stdpar, 8);
633 case PSE_PAD_TYPE_GUNCON: // GUNCON - gun controller SLPH-00034 from Namco
636 stdpar[2] = pad->buttonStatus & 0xff;
637 stdpar[3] = pad->buttonStatus >> 8;
639 //This code assumes an X resolution of 256 and a Y resolution of 240
643 //The code wants an input range for x and y of 0-1023 we passed in -32767 -> 32767
644 int absX = (pad->absoluteX / 64) + 512;
645 int absY = (pad->absoluteY / 64) + 512;
647 if (absX == 65536 || absY == 65536) {
654 stdpar[4] = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10);
655 stdpar[5] = (0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10)) >> 8;
656 stdpar[6] = 0x20 + (yres * absY >> 10);
657 stdpar[7] = (0x20 + (yres * absY >> 10)) >> 8;
660 memcpy(buf, stdpar, 8);
663 case PSE_PAD_TYPE_GUN: // GUN CONTROLLER - gun controller SLPH-00014 from Konami
666 stdpar[2] = pad->buttonStatus & 0xff;
667 stdpar[3] = pad->buttonStatus >> 8;
668 memcpy(buf, stdpar, 4);
671 case PSE_PAD_TYPE_ANALOGPAD: // scph1150
674 stdpar[2] = pad->buttonStatus & 0xff;
675 stdpar[3] = pad->buttonStatus >> 8;
676 stdpar[4] = pad->rightJoyX;
677 stdpar[5] = pad->rightJoyY;
678 stdpar[6] = pad->leftJoyX;
679 stdpar[7] = pad->leftJoyY;
680 memcpy(buf, stdpar, 8);
683 case PSE_PAD_TYPE_ANALOGJOY: // scph1110
686 stdpar[2] = pad->buttonStatus & 0xff;
687 stdpar[3] = pad->buttonStatus >> 8;
688 stdpar[4] = pad->rightJoyX;
689 stdpar[5] = pad->rightJoyY;
690 stdpar[6] = pad->leftJoyX;
691 stdpar[7] = pad->leftJoyY;
692 memcpy(buf, stdpar, 8);
695 case PSE_PAD_TYPE_STANDARD:
698 stdpar[2] = pad->buttonStatus & 0xff;
699 stdpar[3] = pad->buttonStatus >> 8;
700 memcpy(buf, stdpar, 4);
710 //Build response for 0x42 request Multitap in port
711 //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)
712 void _PADstartPollMultitap(PadDataS* padd) {
714 for(i = 0; i < 4; i++) {
715 offset = 2 + (i * 8);
716 _PADstartPoll(&padd[i]);
717 memcpy(multitappar+offset, stdpar, 8);
719 memcpy(bufMulti, multitappar, 34);
723 static void PADpoll_dualshock(int port, unsigned char value)
727 initBufForRequest(port, value);
730 reqIndex2Treatment(port, value);
733 if (pad[port].txData[0] == CMD_READ_DATA_AND_VIBRATE) {
734 // vibration value for the Large motor
735 pad[port].Vib[1] = value;
743 static unsigned char PADpoll_(int port, unsigned char value, int *more_data) {
744 if (reqPos < sizeof(pad[port].txData))
745 pad[port].txData[reqPos] = value;
747 if (reqPos == 0 && value != 0x42 && in_type[port] != PSE_PAD_TYPE_ANALOGPAD)
750 switch (in_type[port]) {
751 case PSE_PAD_TYPE_ANALOGPAD:
752 PADpoll_dualshock(port, value);
754 case PSE_PAD_TYPE_GUN:
756 pl_gun_byte2(port, value);
760 *more_data = reqPos < respSize - 1;
761 if (reqPos >= respSize)
762 return 0xff; // no response/HiZ
764 return buf[reqPos++];
767 static unsigned char PADpollMultitap(int port, unsigned char value, int *more_data) {
768 *more_data = reqPos < respSize - 1;
769 if (reqPos >= respSize) return 0xff;
770 return bufMulti[reqPos++];
774 // refresh the button state on port 1.
775 // int pad is not needed.
776 unsigned char CALLBACK PAD1__startPoll(int pad) {
778 // first call the pad provide if a multitap is connected between the psx and himself
779 // just one pad is on port 1 : NO MULTITAP
780 if (multitap1 == 0) {
782 padd.requestPadIndex = 0;
783 PAD1_readPort1(&padd);
784 _PADstartPoll(&padd);
786 // a multitap is plugged : refresh all pad.
789 for(i = 0; i < 4; i++) {
790 padd[i].requestPadIndex = i;
791 PAD1_readPort1(&padd[i]);
793 _PADstartPollMultitap(padd);
795 //printf("\npad 1 : ");
799 unsigned char CALLBACK PAD1__poll(unsigned char value, int *more_data) {
801 if (multitap1 == 1) {
802 tmp = PADpollMultitap(0, value, more_data);
804 tmp = PADpoll_(0, value, more_data);
806 //printf("%2x:%2x, ",value,tmp);
812 long CALLBACK PAD1__configure(void) { return 0; }
813 void CALLBACK PAD1__about(void) {}
814 long CALLBACK PAD1__test(void) { return 0; }
815 long CALLBACK PAD1__query(void) { return 3; }
816 long CALLBACK PAD1__keypressed() { return 0; }
818 #define LoadPad1Sym1(dest, name) \
819 LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
821 #define LoadPad1SymN(dest, name) \
822 LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
824 #define LoadPad1Sym0(dest, name) \
825 LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
826 if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
828 static int LoadPAD1plugin(const char *PAD1dll) {
832 hPAD1Driver = SysLoadLibrary(PAD1dll);
833 if (hPAD1Driver == NULL) {
834 PAD1_configure = NULL;
835 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
838 LoadPad1Sym1(init, "PADinit");
839 LoadPad1Sym1(shutdown, "PADshutdown");
840 LoadPad1Sym1(open, "PADopen");
841 LoadPad1Sym1(close, "PADclose");
842 LoadPad1Sym0(query, "PADquery");
843 LoadPad1Sym1(readPort1, "PADreadPort1");
844 LoadPad1Sym0(configure, "PADconfigure");
845 LoadPad1Sym0(test, "PADtest");
846 LoadPad1Sym0(about, "PADabout");
847 LoadPad1Sym0(keypressed, "PADkeypressed");
848 LoadPad1Sym0(startPoll, "PADstartPoll");
849 LoadPad1Sym0(poll, "PADpoll");
850 LoadPad1SymN(setSensitive, "PADsetSensitive");
852 padd.requestPadIndex = 0;
853 PAD1_readPort1(&padd);
854 multitap1 = padd.portMultitap;
859 unsigned char CALLBACK PAD2__startPoll(int pad) {
863 if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
865 } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
871 // just one pad is on port 1 : NO MULTITAP
872 if (multitap2 == 0) {
874 padd.requestPadIndex = pad_index;
875 PAD2_readPort2(&padd);
876 _PADstartPoll(&padd);
878 // a multitap is plugged : refresh all pad.
881 for(i = 0; i < 4; i++) {
882 padd[i].requestPadIndex = i+pad_index;
883 PAD2_readPort2(&padd[i]);
885 _PADstartPollMultitap(padd);
887 //printf("\npad 2 : ");
891 unsigned char CALLBACK PAD2__poll(unsigned char value, int *more_data) {
893 if (multitap2 == 2) {
894 tmp = PADpollMultitap(1, value, more_data);
896 tmp = PADpoll_(1, value, more_data);
898 //printf("%2x:%2x, ",value,tmp);
902 long CALLBACK PAD2__configure(void) { return 0; }
903 void CALLBACK PAD2__about(void) {}
904 long CALLBACK PAD2__test(void) { return 0; }
905 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
906 long CALLBACK PAD2__keypressed() { return 0; }
908 #define LoadPad2Sym1(dest, name) \
909 LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
911 #define LoadPad2Sym0(dest, name) \
912 LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
913 if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
915 #define LoadPad2SymN(dest, name) \
916 LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
918 static int LoadPAD2plugin(const char *PAD2dll) {
922 hPAD2Driver = SysLoadLibrary(PAD2dll);
923 if (hPAD2Driver == NULL) {
924 PAD2_configure = NULL;
925 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
928 LoadPad2Sym1(init, "PADinit");
929 LoadPad2Sym1(shutdown, "PADshutdown");
930 LoadPad2Sym1(open, "PADopen");
931 LoadPad2Sym1(close, "PADclose");
932 LoadPad2Sym0(query, "PADquery");
933 LoadPad2Sym1(readPort2, "PADreadPort2");
934 LoadPad2Sym0(configure, "PADconfigure");
935 LoadPad2Sym0(test, "PADtest");
936 LoadPad2Sym0(about, "PADabout");
937 LoadPad2Sym0(keypressed, "PADkeypressed");
938 LoadPad2Sym0(startPoll, "PADstartPoll");
939 LoadPad2Sym0(poll, "PADpoll");
940 LoadPad2SymN(setSensitive, "PADsetSensitive");
942 padd.requestPadIndex = 0;
943 PAD2_readPort2(&padd);
944 multitap2 = padd.portMultitap;
949 void *hNETDriver = NULL;
951 void CALLBACK NET__setInfo(netInfo *info) {}
952 void CALLBACK NET__keypressed(int key) {}
953 long CALLBACK NET__configure(void) { return 0; }
954 long CALLBACK NET__test(void) { return 0; }
955 void CALLBACK NET__about(void) {}
957 #define LoadNetSym1(dest, name) \
958 LoadSym(NET_##dest, NET##dest, name, TRUE);
960 #define LoadNetSymN(dest, name) \
961 LoadSym(NET_##dest, NET##dest, name, FALSE);
963 #define LoadNetSym0(dest, name) \
964 LoadSym(NET_##dest, NET##dest, name, FALSE); \
965 if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
967 static int LoadNETplugin(const char *NETdll) {
970 hNETDriver = SysLoadLibrary(NETdll);
971 if (hNETDriver == NULL) {
972 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
975 LoadNetSym1(init, "NETinit");
976 LoadNetSym1(shutdown, "NETshutdown");
977 LoadNetSym1(open, "NETopen");
978 LoadNetSym1(close, "NETclose");
979 LoadNetSymN(sendData, "NETsendData");
980 LoadNetSymN(recvData, "NETrecvData");
981 LoadNetSym1(sendPadData, "NETsendPadData");
982 LoadNetSym1(recvPadData, "NETrecvPadData");
983 LoadNetSym1(queryPlayer, "NETqueryPlayer");
984 LoadNetSym1(pause, "NETpause");
985 LoadNetSym1(resume, "NETresume");
986 LoadNetSym0(setInfo, "NETsetInfo");
987 LoadNetSym0(keypressed, "NETkeypressed");
988 LoadNetSym0(configure, "NETconfigure");
989 LoadNetSym0(test, "NETtest");
990 LoadNetSym0(about, "NETabout");
995 #ifdef ENABLE_SIO1API
997 void *hSIO1Driver = NULL;
999 long CALLBACK SIO1__init(void) { return 0; }
1000 long CALLBACK SIO1__shutdown(void) { return 0; }
1001 long CALLBACK SIO1__open(void) { return 0; }
1002 long CALLBACK SIO1__close(void) { return 0; }
1003 long CALLBACK SIO1__configure(void) { return 0; }
1004 long CALLBACK SIO1__test(void) { return 0; }
1005 void CALLBACK SIO1__about(void) {}
1006 void CALLBACK SIO1__pause(void) {}
1007 void CALLBACK SIO1__resume(void) {}
1008 long CALLBACK SIO1__keypressed(int key) { return 0; }
1009 void CALLBACK SIO1__writeData8(unsigned char val) {}
1010 void CALLBACK SIO1__writeData16(unsigned short val) {}
1011 void CALLBACK SIO1__writeData32(unsigned long val) {}
1012 void CALLBACK SIO1__writeStat16(unsigned short val) {}
1013 void CALLBACK SIO1__writeStat32(unsigned long val) {}
1014 void CALLBACK SIO1__writeMode16(unsigned short val) {}
1015 void CALLBACK SIO1__writeMode32(unsigned long val) {}
1016 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
1017 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
1018 void CALLBACK SIO1__writeBaud16(unsigned short val) {}
1019 void CALLBACK SIO1__writeBaud32(unsigned long val) {}
1020 unsigned char CALLBACK SIO1__readData8(void) { return 0; }
1021 unsigned short CALLBACK SIO1__readData16(void) { return 0; }
1022 unsigned long CALLBACK SIO1__readData32(void) { return 0; }
1023 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
1024 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
1025 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
1026 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
1027 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
1028 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
1029 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
1030 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
1031 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
1033 void CALLBACK SIO1irq(void) {
1034 psxHu32ref(0x1070) |= SWAPu32(0x100);
1037 #define LoadSio1Sym1(dest, name) \
1038 LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
1040 #define LoadSio1SymN(dest, name) \
1041 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
1043 #define LoadSio1Sym0(dest, name) \
1044 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
1045 if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
1047 static int LoadSIO1plugin(const char *SIO1dll) {
1050 hSIO1Driver = SysLoadLibrary(SIO1dll);
1051 if (hSIO1Driver == NULL) {
1052 SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
1056 LoadSio1Sym0(init, "SIO1init");
1057 LoadSio1Sym0(shutdown, "SIO1shutdown");
1058 LoadSio1Sym0(open, "SIO1open");
1059 LoadSio1Sym0(close, "SIO1close");
1060 LoadSio1Sym0(pause, "SIO1pause");
1061 LoadSio1Sym0(resume, "SIO1resume");
1062 LoadSio1Sym0(keypressed, "SIO1keypressed");
1063 LoadSio1Sym0(configure, "SIO1configure");
1064 LoadSio1Sym0(test, "SIO1test");
1065 LoadSio1Sym0(about, "SIO1about");
1066 LoadSio1Sym0(writeData8, "SIO1writeData8");
1067 LoadSio1Sym0(writeData16, "SIO1writeData16");
1068 LoadSio1Sym0(writeData32, "SIO1writeData32");
1069 LoadSio1Sym0(writeStat16, "SIO1writeStat16");
1070 LoadSio1Sym0(writeStat32, "SIO1writeStat32");
1071 LoadSio1Sym0(writeMode16, "SIO1writeMode16");
1072 LoadSio1Sym0(writeMode32, "SIO1writeMode32");
1073 LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
1074 LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
1075 LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
1076 LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
1077 LoadSio1Sym0(readData16, "SIO1readData16");
1078 LoadSio1Sym0(readData32, "SIO1readData32");
1079 LoadSio1Sym0(readStat16, "SIO1readStat16");
1080 LoadSio1Sym0(readStat32, "SIO1readStat32");
1081 LoadSio1Sym0(readMode16, "SIO1readMode16");
1082 LoadSio1Sym0(readMode32, "SIO1readMode32");
1083 LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
1084 LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
1085 LoadSio1Sym0(readBaud16, "SIO1readBaud16");
1086 LoadSio1Sym0(readBaud32, "SIO1readBaud32");
1087 LoadSio1Sym0(registerCallback, "SIO1registerCallback");
1096 char Plugin[MAXPATHLEN * 2];
1102 LoadCDRplugin(NULL);
1104 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1105 if (LoadCDRplugin(Plugin) == -1) return -1;
1108 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
1109 if (LoadGPUplugin(Plugin) == -1) return -1;
1111 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
1112 if (LoadSPUplugin(Plugin) == -1) return -1;
1114 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
1115 if (LoadPAD1plugin(Plugin) == -1) return -1;
1117 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
1118 if (LoadPAD2plugin(Plugin) == -1) return -1;
1120 if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
1121 Config.UseNet = FALSE;
1123 Config.UseNet = TRUE;
1124 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
1125 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
1128 #ifdef ENABLE_SIO1API
1129 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
1130 if (LoadSIO1plugin(Plugin) == -1) return -1;
1134 if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
1136 if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
1138 if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
1140 if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
1142 if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
1144 if (Config.UseNet) {
1146 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
1149 #ifdef ENABLE_SIO1API
1151 if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
1154 SysPrintf(_("Plugins loaded.\n"));
1158 void ReleasePlugins() {
1159 if (Config.UseNet) {
1160 int ret = NET_close();
1161 if (ret < 0) Config.UseNet = FALSE;
1165 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1166 if (hGPUDriver != NULL) GPU_shutdown();
1167 if (hSPUDriver != NULL) SPU_shutdown();
1168 if (hPAD1Driver != NULL) PAD1_shutdown();
1169 if (hPAD2Driver != NULL) PAD2_shutdown();
1171 if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
1173 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1174 if (hGPUDriver != NULL) { SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; }
1175 if (hSPUDriver != NULL) { SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; }
1176 if (hPAD1Driver != NULL) { SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; }
1177 if (hPAD2Driver != NULL) { SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; }
1179 if (Config.UseNet && hNETDriver != NULL) {
1180 SysCloseLibrary(hNETDriver); hNETDriver = NULL;
1183 #ifdef ENABLE_SIO1API
1184 if (hSIO1Driver != NULL) {
1186 SysCloseLibrary(hSIO1Driver);
1193 int ReloadCdromPlugin()
1195 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1196 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1199 LoadCDRplugin(NULL);
1201 char Plugin[MAXPATHLEN * 2];
1202 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1203 if (LoadCDRplugin(Plugin) == -1) return -1;
1209 void SetIsoFile(const char *filename) {
1210 if (filename == NULL) {
1214 strncpy(IsoFile, filename, MAXPATHLEN - 1);
1217 const char *GetIsoFile(void) {
1221 boolean UsingIso(void) {
1222 return (IsoFile[0] != '\0');
1225 void SetCdOpenCaseTime(s64 time) {
1226 cdOpenCaseTime = time;