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;
75 SPUshutdown SPU_shutdown;
78 SPUwriteRegister SPU_writeRegister;
79 SPUreadRegister SPU_readRegister;
80 SPUwriteDMAMem SPU_writeDMAMem;
81 SPUreadDMAMem SPU_readDMAMem;
82 SPUplayADPCMchannel SPU_playADPCMchannel;
84 SPUregisterCallback SPU_registerCallback;
85 SPUregisterScheduleCb SPU_registerScheduleCb;
87 SPUplayCDDAchannel SPU_playCDDAchannel;
89 PADconfigure PAD1_configure;
92 PADshutdown PAD1_shutdown;
97 PADreadPort1 PAD1_readPort1;
98 PADkeypressed PAD1_keypressed;
99 PADstartPoll PAD1_startPoll;
101 PADsetSensitive PAD1_setSensitive;
103 PADconfigure PAD2_configure;
106 PADshutdown PAD2_shutdown;
111 PADreadPort2 PAD2_readPort2;
112 PADkeypressed PAD2_keypressed;
113 PADstartPoll PAD2_startPoll;
115 PADsetSensitive PAD2_setSensitive;
118 NETshutdown NET_shutdown;
122 NETconfigure NET_configure;
125 NETresume NET_resume;
126 NETqueryPlayer NET_queryPlayer;
127 NETsendData NET_sendData;
128 NETrecvData NET_recvData;
129 NETsendPadData NET_sendPadData;
130 NETrecvPadData NET_recvPadData;
131 NETsetInfo NET_setInfo;
132 NETkeypressed NET_keypressed;
134 #ifdef ENABLE_SIO1API
137 SIO1shutdown SIO1_shutdown;
139 SIO1close SIO1_close;
141 SIO1configure SIO1_configure;
142 SIO1about SIO1_about;
143 SIO1pause SIO1_pause;
144 SIO1resume SIO1_resume;
145 SIO1keypressed SIO1_keypressed;
146 SIO1writeData8 SIO1_writeData8;
147 SIO1writeData16 SIO1_writeData16;
148 SIO1writeData32 SIO1_writeData32;
149 SIO1writeStat16 SIO1_writeStat16;
150 SIO1writeStat32 SIO1_writeStat32;
151 SIO1writeMode16 SIO1_writeMode16;
152 SIO1writeMode32 SIO1_writeMode32;
153 SIO1writeCtrl16 SIO1_writeCtrl16;
154 SIO1writeCtrl32 SIO1_writeCtrl32;
155 SIO1writeBaud16 SIO1_writeBaud16;
156 SIO1writeBaud32 SIO1_writeBaud32;
157 SIO1readData8 SIO1_readData8;
158 SIO1readData16 SIO1_readData16;
159 SIO1readData32 SIO1_readData32;
160 SIO1readStat16 SIO1_readStat16;
161 SIO1readStat32 SIO1_readStat32;
162 SIO1readMode16 SIO1_readMode16;
163 SIO1readMode32 SIO1_readMode32;
164 SIO1readCtrl16 SIO1_readCtrl16;
165 SIO1readCtrl32 SIO1_readCtrl32;
166 SIO1readBaud16 SIO1_readBaud16;
167 SIO1readBaud32 SIO1_readBaud32;
168 SIO1registerCallback SIO1_registerCallback;
172 static const char *err;
174 #define CheckErr(func) { \
175 err = SysLibError(); \
176 if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; } \
179 #define LoadSym(dest, src, name, checkerr) { \
180 dest = (src)SysLoadSym(drv, name); \
181 if (checkerr) { CheckErr(name); } else SysLibError(); \
184 void *hGPUDriver = NULL;
186 void CALLBACK GPU__displayText(char *pText) {
187 SysPrintf("%s\n", pText);
190 long CALLBACK GPU__configure(void) { return 0; }
191 long CALLBACK GPU__test(void) { return 0; }
192 void CALLBACK GPU__about(void) {}
193 void CALLBACK GPU__makeSnapshot(void) {}
194 void CALLBACK GPU__keypressed(int key) {}
195 long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
196 long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
197 void CALLBACK GPU__vBlank(int val) {}
199 #define LoadGpuSym1(dest, name) \
200 LoadSym(GPU_##dest, GPU##dest, name, TRUE);
202 #define LoadGpuSym0(dest, name) \
203 LoadSym(GPU_##dest, GPU##dest, name, FALSE); \
204 if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;
206 #define LoadGpuSymN(dest, name) \
207 LoadSym(GPU_##dest, GPU##dest, name, FALSE);
209 static int LoadGPUplugin(const char *GPUdll) {
212 hGPUDriver = SysLoadLibrary(GPUdll);
213 if (hGPUDriver == NULL) {
214 GPU_configure = NULL;
215 SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
218 LoadGpuSym1(init, "GPUinit");
219 LoadGpuSym1(shutdown, "GPUshutdown");
220 LoadGpuSym1(open, "GPUopen");
221 LoadGpuSym1(close, "GPUclose");
222 LoadGpuSym1(readData, "GPUreadData");
223 LoadGpuSym1(readDataMem, "GPUreadDataMem");
224 LoadGpuSym1(readStatus, "GPUreadStatus");
225 LoadGpuSym1(writeData, "GPUwriteData");
226 LoadGpuSym1(writeDataMem, "GPUwriteDataMem");
227 LoadGpuSym1(writeStatus, "GPUwriteStatus");
228 LoadGpuSym1(dmaChain, "GPUdmaChain");
229 LoadGpuSym1(updateLace, "GPUupdateLace");
230 LoadGpuSym0(keypressed, "GPUkeypressed");
231 LoadGpuSym0(displayText, "GPUdisplayText");
232 LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
233 LoadGpuSym1(freeze, "GPUfreeze");
234 LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
235 LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
236 LoadGpuSym0(vBlank, "GPUvBlank");
237 LoadGpuSym0(configure, "GPUconfigure");
238 LoadGpuSym0(test, "GPUtest");
239 LoadGpuSym0(about, "GPUabout");
244 void *hCDRDriver = NULL;
246 long CALLBACK CDR__play(unsigned char *sector) { return 0; }
247 long CALLBACK CDR__stop(void) { return 0; }
249 long CALLBACK CDR__getStatus(struct CdrStat *stat) {
250 if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))
258 char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
259 long CALLBACK CDR__configure(void) { return 0; }
260 long CALLBACK CDR__test(void) { return 0; }
261 void CALLBACK CDR__about(void) {}
262 long CALLBACK CDR__setfilename(char*filename) { return 0; }
264 #define LoadCdrSym1(dest, name) \
265 LoadSym(CDR_##dest, CDR##dest, name, TRUE);
267 #define LoadCdrSym0(dest, name) \
268 LoadSym(CDR_##dest, CDR##dest, name, FALSE); \
269 if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
271 #define LoadCdrSymN(dest, name) \
272 LoadSym(CDR_##dest, CDR##dest, name, FALSE);
274 static int LoadCDRplugin(const char *CDRdll) {
277 if (CDRdll == NULL) {
282 hCDRDriver = SysLoadLibrary(CDRdll);
283 if (hCDRDriver == NULL) {
284 CDR_configure = NULL;
285 SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll); return -1;
288 LoadCdrSym1(init, "CDRinit");
289 LoadCdrSym1(shutdown, "CDRshutdown");
290 LoadCdrSym1(open, "CDRopen");
291 LoadCdrSym1(close, "CDRclose");
292 LoadCdrSym1(getTN, "CDRgetTN");
293 LoadCdrSym1(getTD, "CDRgetTD");
294 LoadCdrSym1(readTrack, "CDRreadTrack");
295 LoadCdrSym1(getBuffer, "CDRgetBuffer");
296 LoadCdrSym1(getBufferSub, "CDRgetBufferSub");
297 LoadCdrSym0(play, "CDRplay");
298 LoadCdrSym0(stop, "CDRstop");
299 LoadCdrSym0(getStatus, "CDRgetStatus");
300 LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
301 LoadCdrSym0(configure, "CDRconfigure");
302 LoadCdrSym0(test, "CDRtest");
303 LoadCdrSym0(about, "CDRabout");
304 LoadCdrSym0(setfilename, "CDRsetfilename");
305 LoadCdrSymN(readCDDA, "CDRreadCDDA");
306 LoadCdrSymN(getTE, "CDRgetTE");
311 static void *hSPUDriver = NULL;
\r
312 static void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}
\r
314 #define LoadSpuSym1(dest, name) \
315 LoadSym(SPU_##dest, SPU##dest, name, TRUE);
317 #define LoadSpuSym0(dest, name) \
318 LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
319 if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
321 #define LoadSpuSymN(dest, name) \
322 LoadSym(SPU_##dest, SPU##dest, name, FALSE);
324 static int LoadSPUplugin(const char *SPUdll) {
327 hSPUDriver = SysLoadLibrary(SPUdll);
328 if (hSPUDriver == NULL) {
329 SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;
332 LoadSpuSym1(init, "SPUinit");
333 LoadSpuSym1(shutdown, "SPUshutdown");
334 LoadSpuSym1(open, "SPUopen");
335 LoadSpuSym1(close, "SPUclose");
336 LoadSpuSym1(writeRegister, "SPUwriteRegister");
337 LoadSpuSym1(readRegister, "SPUreadRegister");
338 LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
339 LoadSpuSym1(readDMAMem, "SPUreadDMAMem");
340 LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");
341 LoadSpuSym1(freeze, "SPUfreeze");
342 LoadSpuSym1(registerCallback, "SPUregisterCallback");
343 LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
344 LoadSpuSymN(async, "SPUasync");
345 LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
350 extern int in_type[8];
352 void *hPAD1Driver = NULL;
353 void *hPAD2Driver = NULL;
355 static int multitap1;
356 static int multitap2;
357 //Pad information, keystate, mode, config mode, vibration
358 static PadDataS pad[8];
360 static int reqPos, respSize, req;
361 static int ledStateReq44[8];
362 static int PadMode[8]; /* 0 : digital 1: analog */
364 static unsigned char buf[256];
365 static unsigned char bufMulti[34] = { 0x80, 0x5a,
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,
369 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
371 unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
372 unsigned char multitappar[34] = { 0x80, 0x5a,
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,
376 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
378 //response for request 44, 45, 46, 47, 4C, 4D
379 static unsigned char resp45[8] = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
380 static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
381 static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
382 static unsigned char resp47[8] = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
383 static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
384 static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
385 static unsigned char resp4D[8] = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};
387 //fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
388 static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
389 static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
390 static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
391 static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
392 static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
393 static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
394 static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
395 static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
396 static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
398 // Resquest of psx core
401 // first call of this request for the pad, the pad is configured as an digital pad.
402 // 0x0X, 0x42, 0x0Y, 0xZZ, 0xAA, 0x00, 0x00, 0x00, 0x00
403 // 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)
404 // Y if 1 : psx request the full length response for the multitap, 3 bytes header and 4 block of 8 bytes per pad
405 // Y if 0 : psx request a pad key state
406 // ZZ rumble small motor 00-> OFF, 01 -> ON
407 // AA rumble large motor speed 0x00 -> 0xFF
411 // PadId -> 0x41 for digital pas, 0x73 for analog pad
412 // 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
413 // 6 Bytes for keystates
414 CMD_READ_DATA_AND_VIBRATE = 0x42,
418 // 0x0N, 0x43, 0x00, XX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
419 // XX = 00 -> Normal mode : Seconde bytes of response = padId
420 // XX = 01 -> Configuration mode : Seconde bytes of response = 0xF3
422 // enter in config mode example :
423 // req : 01 43 00 01 00 00 00 00 00 00
424 // res : 00 41 5A buttons state, analog states
425 // exit config mode :
426 // req : 01 43 00 00 00 00 00 00 00 00
427 // res : 00 F3 5A buttons state, analog states
428 CMD_CONFIG_MODE = 0x43,
432 // 0x0N, 0x44, 0x00, VAL, SEL, 0x00, 0x00, 0x00, 0x00
437 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
438 CMD_SET_MODE_AND_LOCK = 0x44,
440 // Get Analog Led state
442 // 0x0N, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
444 // 0x00, 0xF3, 0x5A, 0x01, 0x02, VAL, 0x02, 0x01, 0x00
447 CMD_QUERY_MODEL_AND_MODE = 0x45,
451 // 0x0N, 0x46, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
454 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A
456 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14
457 CMD_QUERY_ACT = 0x46,
460 // 0x0N, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
462 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00
463 CMD_QUERY_COMB = 0x47,
466 // 0x0N, 0x4C, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
469 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
471 // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00
472 CMD_QUERY_MODE = 0x4C,
475 // 0x0N, 0x4D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
477 // 0x00, 0xF3, 0x5A, old value or
478 // AA = 01 unlock large motor (and swap VAL1 and VAL2)
479 // BB = 01 unlock large motor (default)
480 // CC, DD, EE, FF = all FF -> unlock small motor
482 // default repsonse for analog pad with 2 motor : 0x00 0xF3 0x5A 0x00 0x01 0xFF 0xFF 0xFF 0xFF
484 CMD_VIBRATION_TOGGLE = 0x4D,
499 void initBufForRequest(int padIndex, char value){
501 //Pad keystate already in buffer
502 //case CMD_READ_DATA_AND_VIBRATE :
504 case CMD_CONFIG_MODE :
505 if (pad[padIndex].configMode == 1) {
506 memcpy(buf, resp43, 8);
509 //else, not in config mode, pad keystate return (already in the buffer)
511 case CMD_SET_MODE_AND_LOCK :
512 memcpy(buf, resp44, 8);
514 case CMD_QUERY_MODEL_AND_MODE :
515 memcpy(buf, resp45, 8);
516 buf[4] = PadMode[padIndex];
519 memcpy(buf, resp46_00, 8);
521 case CMD_QUERY_COMB :
522 memcpy(buf, resp47, 8);
524 case CMD_QUERY_MODE :
525 memcpy(buf, resp4C_00, 8);
527 case CMD_VIBRATION_TOGGLE :
528 memcpy(buf, resp4D, 8);
531 memcpy(buf, resp40, 8);
534 memcpy(buf, resp41, 8);
537 memcpy(buf, resp49, 8);
540 memcpy(buf, resp4A, 8);
543 memcpy(buf, resp4B, 8);
546 memcpy(buf, resp4E, 8);
549 memcpy(buf, resp4F, 8);
557 void reqIndex2Treatment(int padIndex, char value){
559 case CMD_CONFIG_MODE :
562 pad[padIndex].configMode = 0;
564 pad[padIndex].configMode = 1;
567 case CMD_SET_MODE_AND_LOCK :
568 //0x44 store the led state for change mode if the next value = 0x02
571 ledStateReq44[padIndex] = value;
572 PadMode[padIndex] = value;
577 memcpy(buf, resp46_01, 8);
580 case CMD_QUERY_MODE :
582 memcpy(buf, resp4C_01, 8);
585 case CMD_VIBRATION_TOGGLE :
587 memcpy(buf, resp4D, 8);
589 case CMD_READ_DATA_AND_VIBRATE:
590 //mem the vibration value for small motor;
591 pad[padIndex].Vib[0] = value;
596 void vibrate(int padIndex){
597 if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
598 //value is different update Value and call libretro for vibration
599 pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
600 pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
601 plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
602 //printf("vibration pad %i", padIndex);
609 //Build response for 0x42 request Pad in port
610 void _PADstartPoll(PadDataS *pad) {
611 switch (pad->controllerType) {
612 case PSE_PAD_TYPE_MOUSE:
615 stdpar[2] = pad->buttonStatus & 0xff;
616 stdpar[3] = pad->buttonStatus >> 8;
617 stdpar[4] = pad->moveX;
618 stdpar[5] = pad->moveY;
619 memcpy(buf, stdpar, 6);
622 case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
625 stdpar[2] = pad->buttonStatus & 0xff;
626 stdpar[3] = pad->buttonStatus >> 8;
627 stdpar[4] = pad->rightJoyX;
628 stdpar[5] = pad->rightJoyY;
629 stdpar[6] = pad->leftJoyX;
630 stdpar[7] = pad->leftJoyY;
631 memcpy(buf, stdpar, 8);
634 case PSE_PAD_TYPE_GUNCON: // GUNCON - gun controller SLPH-00034 from Namco
637 stdpar[2] = pad->buttonStatus & 0xff;
638 stdpar[3] = pad->buttonStatus >> 8;
640 //This code assumes an X resolution of 256 and a Y resolution of 240
644 //The code wants an input range for x and y of 0-1023 we passed in -32767 -> 32767
645 int absX = (pad->absoluteX / 64) + 512;
646 int absY = (pad->absoluteY / 64) + 512;
648 if (absX == 65536 || absY == 65536) {
655 stdpar[4] = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10);
656 stdpar[5] = (0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10)) >> 8;
657 stdpar[6] = 0x20 + (yres * absY >> 10);
658 stdpar[7] = (0x20 + (yres * absY >> 10)) >> 8;
661 memcpy(buf, stdpar, 8);
664 case PSE_PAD_TYPE_ANALOGPAD: // scph1150
667 stdpar[2] = pad->buttonStatus & 0xff;
668 stdpar[3] = pad->buttonStatus >> 8;
669 stdpar[4] = pad->rightJoyX;
670 stdpar[5] = pad->rightJoyY;
671 stdpar[6] = pad->leftJoyX;
672 stdpar[7] = pad->leftJoyY;
673 memcpy(buf, stdpar, 8);
676 case PSE_PAD_TYPE_ANALOGJOY: // scph1110
679 stdpar[2] = pad->buttonStatus & 0xff;
680 stdpar[3] = pad->buttonStatus >> 8;
681 stdpar[4] = pad->rightJoyX;
682 stdpar[5] = pad->rightJoyY;
683 stdpar[6] = pad->leftJoyX;
684 stdpar[7] = pad->leftJoyY;
685 memcpy(buf, stdpar, 8);
688 case PSE_PAD_TYPE_STANDARD:
691 stdpar[2] = pad->buttonStatus & 0xff;
692 stdpar[3] = pad->buttonStatus >> 8;
693 //avoid analog value in multitap mode if change pad type in game.
698 memcpy(buf, stdpar, 8);
710 memcpy(buf, stdpar, 8);
717 //Build response for 0x42 request Multitap in port
718 //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)
719 void _PADstartPollMultitap(PadDataS* padd) {
721 for(i = 0; i < 4; i++) {
722 offset = 2 + (i * 8);
723 _PADstartPoll(&padd[i]);
724 memcpy(multitappar+offset, stdpar, 8);
726 memcpy(bufMulti, multitappar, 34);
731 unsigned char _PADpoll(int port, unsigned char value) {
733 //mem the request number
736 // Don't enable Analog/Vibration for a standard pad
737 if (in_type[port] == PSE_PAD_TYPE_STANDARD ||
738 in_type[port] == PSE_PAD_TYPE_NEGCON) {
739 ; // Pad keystate already in buffer
743 //copy the default value of request response in buffer instead of the keystate
744 initBufForRequest(port, value);
748 if (reqPos < sizeof(pad[port].txData))
749 pad[port].txData[reqPos] = value;
751 //if no new request the pad return 0xff, for signaling connected
752 if (reqPos >= respSize)
755 if (in_type[port] == PSE_PAD_TYPE_GUN) {
757 pl_gun_byte2(port, value);
762 reqIndex2Treatment(port, value);
766 case CMD_SET_MODE_AND_LOCK :
769 case CMD_READ_DATA_AND_VIBRATE:
770 //mem the vibration value for Large motor;
771 pad[port].Vib[1] = value;
773 if (in_type[port] != PSE_PAD_TYPE_ANALOGPAD)
782 return buf[reqPos++];
786 unsigned char _PADpollMultitap(int port, unsigned char value) {
787 if (reqPos >= respSize) return 0xff;
788 return bufMulti[reqPos++];
792 // refresh the button state on port 1.
793 // int pad is not needed.
794 unsigned char CALLBACK PAD1__startPoll(int pad) {
796 // first call the pad provide if a multitap is connected between the psx and himself
797 // just one pad is on port 1 : NO MULTITAP
798 if (multitap1 == 0) {
800 padd.requestPadIndex = 0;
801 PAD1_readPort1(&padd);
802 _PADstartPoll(&padd);
804 // a multitap is plugged : refresh all pad.
807 for(i = 0; i < 4; i++) {
808 padd[i].requestPadIndex = i;
809 PAD1_readPort1(&padd[i]);
811 _PADstartPollMultitap(padd);
813 //printf("\npad 1 : ");
817 unsigned char CALLBACK PAD1__poll(unsigned char value) {
819 if (multitap1 == 1) {
820 tmp = _PADpollMultitap(0, value);
822 tmp = _PADpoll(0, value);
824 //printf("%2x:%2x, ",value,tmp);
830 long CALLBACK PAD1__configure(void) { return 0; }
831 void CALLBACK PAD1__about(void) {}
832 long CALLBACK PAD1__test(void) { return 0; }
833 long CALLBACK PAD1__query(void) { return 3; }
834 long CALLBACK PAD1__keypressed() { return 0; }
836 #define LoadPad1Sym1(dest, name) \
837 LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
839 #define LoadPad1SymN(dest, name) \
840 LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
842 #define LoadPad1Sym0(dest, name) \
843 LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
844 if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
846 static int LoadPAD1plugin(const char *PAD1dll) {
850 hPAD1Driver = SysLoadLibrary(PAD1dll);
851 if (hPAD1Driver == NULL) {
852 PAD1_configure = NULL;
853 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
856 LoadPad1Sym1(init, "PADinit");
857 LoadPad1Sym1(shutdown, "PADshutdown");
858 LoadPad1Sym1(open, "PADopen");
859 LoadPad1Sym1(close, "PADclose");
860 LoadPad1Sym0(query, "PADquery");
861 LoadPad1Sym1(readPort1, "PADreadPort1");
862 LoadPad1Sym0(configure, "PADconfigure");
863 LoadPad1Sym0(test, "PADtest");
864 LoadPad1Sym0(about, "PADabout");
865 LoadPad1Sym0(keypressed, "PADkeypressed");
866 LoadPad1Sym0(startPoll, "PADstartPoll");
867 LoadPad1Sym0(poll, "PADpoll");
868 LoadPad1SymN(setSensitive, "PADsetSensitive");
870 padd.requestPadIndex = 0;
871 PAD1_readPort1(&padd);
872 multitap1 = padd.portMultitap;
877 unsigned char CALLBACK PAD2__startPoll(int pad) {
881 if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
883 } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
889 // just one pad is on port 1 : NO MULTITAP
890 if (multitap2 == 0) {
892 padd.requestPadIndex = pad_index;
893 PAD2_readPort2(&padd);
894 _PADstartPoll(&padd);
896 // a multitap is plugged : refresh all pad.
899 for(i = 0; i < 4; i++) {
900 padd[i].requestPadIndex = i+pad_index;
901 PAD2_readPort2(&padd[i]);
903 _PADstartPollMultitap(padd);
905 //printf("\npad 2 : ");
909 unsigned char CALLBACK PAD2__poll(unsigned char value) {
911 if (multitap2 == 2) {
912 tmp = _PADpollMultitap(1, value);
914 tmp = _PADpoll(1, value);
916 //printf("%2x:%2x, ",value,tmp);
920 long CALLBACK PAD2__configure(void) { return 0; }
921 void CALLBACK PAD2__about(void) {}
922 long CALLBACK PAD2__test(void) { return 0; }
923 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
924 long CALLBACK PAD2__keypressed() { return 0; }
926 #define LoadPad2Sym1(dest, name) \
927 LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
929 #define LoadPad2Sym0(dest, name) \
930 LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
931 if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
933 #define LoadPad2SymN(dest, name) \
934 LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
936 static int LoadPAD2plugin(const char *PAD2dll) {
940 hPAD2Driver = SysLoadLibrary(PAD2dll);
941 if (hPAD2Driver == NULL) {
942 PAD2_configure = NULL;
943 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
946 LoadPad2Sym1(init, "PADinit");
947 LoadPad2Sym1(shutdown, "PADshutdown");
948 LoadPad2Sym1(open, "PADopen");
949 LoadPad2Sym1(close, "PADclose");
950 LoadPad2Sym0(query, "PADquery");
951 LoadPad2Sym1(readPort2, "PADreadPort2");
952 LoadPad2Sym0(configure, "PADconfigure");
953 LoadPad2Sym0(test, "PADtest");
954 LoadPad2Sym0(about, "PADabout");
955 LoadPad2Sym0(keypressed, "PADkeypressed");
956 LoadPad2Sym0(startPoll, "PADstartPoll");
957 LoadPad2Sym0(poll, "PADpoll");
958 LoadPad2SymN(setSensitive, "PADsetSensitive");
960 padd.requestPadIndex = 0;
961 PAD2_readPort2(&padd);
962 multitap2 = padd.portMultitap;
967 void *hNETDriver = NULL;
969 void CALLBACK NET__setInfo(netInfo *info) {}
970 void CALLBACK NET__keypressed(int key) {}
971 long CALLBACK NET__configure(void) { return 0; }
972 long CALLBACK NET__test(void) { return 0; }
973 void CALLBACK NET__about(void) {}
975 #define LoadNetSym1(dest, name) \
976 LoadSym(NET_##dest, NET##dest, name, TRUE);
978 #define LoadNetSymN(dest, name) \
979 LoadSym(NET_##dest, NET##dest, name, FALSE);
981 #define LoadNetSym0(dest, name) \
982 LoadSym(NET_##dest, NET##dest, name, FALSE); \
983 if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
985 static int LoadNETplugin(const char *NETdll) {
988 hNETDriver = SysLoadLibrary(NETdll);
989 if (hNETDriver == NULL) {
990 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
993 LoadNetSym1(init, "NETinit");
994 LoadNetSym1(shutdown, "NETshutdown");
995 LoadNetSym1(open, "NETopen");
996 LoadNetSym1(close, "NETclose");
997 LoadNetSymN(sendData, "NETsendData");
998 LoadNetSymN(recvData, "NETrecvData");
999 LoadNetSym1(sendPadData, "NETsendPadData");
1000 LoadNetSym1(recvPadData, "NETrecvPadData");
1001 LoadNetSym1(queryPlayer, "NETqueryPlayer");
1002 LoadNetSym1(pause, "NETpause");
1003 LoadNetSym1(resume, "NETresume");
1004 LoadNetSym0(setInfo, "NETsetInfo");
1005 LoadNetSym0(keypressed, "NETkeypressed");
1006 LoadNetSym0(configure, "NETconfigure");
1007 LoadNetSym0(test, "NETtest");
1008 LoadNetSym0(about, "NETabout");
1013 #ifdef ENABLE_SIO1API
1015 void *hSIO1Driver = NULL;
1017 long CALLBACK SIO1__init(void) { return 0; }
1018 long CALLBACK SIO1__shutdown(void) { return 0; }
1019 long CALLBACK SIO1__open(void) { return 0; }
1020 long CALLBACK SIO1__close(void) { return 0; }
1021 long CALLBACK SIO1__configure(void) { return 0; }
1022 long CALLBACK SIO1__test(void) { return 0; }
1023 void CALLBACK SIO1__about(void) {}
1024 void CALLBACK SIO1__pause(void) {}
1025 void CALLBACK SIO1__resume(void) {}
1026 long CALLBACK SIO1__keypressed(int key) { return 0; }
1027 void CALLBACK SIO1__writeData8(unsigned char val) {}
1028 void CALLBACK SIO1__writeData16(unsigned short val) {}
1029 void CALLBACK SIO1__writeData32(unsigned long val) {}
1030 void CALLBACK SIO1__writeStat16(unsigned short val) {}
1031 void CALLBACK SIO1__writeStat32(unsigned long val) {}
1032 void CALLBACK SIO1__writeMode16(unsigned short val) {}
1033 void CALLBACK SIO1__writeMode32(unsigned long val) {}
1034 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
1035 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
1036 void CALLBACK SIO1__writeBaud16(unsigned short val) {}
1037 void CALLBACK SIO1__writeBaud32(unsigned long val) {}
1038 unsigned char CALLBACK SIO1__readData8(void) { return 0; }
1039 unsigned short CALLBACK SIO1__readData16(void) { return 0; }
1040 unsigned long CALLBACK SIO1__readData32(void) { return 0; }
1041 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
1042 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
1043 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
1044 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
1045 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
1046 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
1047 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
1048 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
1049 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
1051 void CALLBACK SIO1irq(void) {
1052 psxHu32ref(0x1070) |= SWAPu32(0x100);
1055 #define LoadSio1Sym1(dest, name) \
1056 LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
1058 #define LoadSio1SymN(dest, name) \
1059 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
1061 #define LoadSio1Sym0(dest, name) \
1062 LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
1063 if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
1065 static int LoadSIO1plugin(const char *SIO1dll) {
1068 hSIO1Driver = SysLoadLibrary(SIO1dll);
1069 if (hSIO1Driver == NULL) {
1070 SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
1074 LoadSio1Sym0(init, "SIO1init");
1075 LoadSio1Sym0(shutdown, "SIO1shutdown");
1076 LoadSio1Sym0(open, "SIO1open");
1077 LoadSio1Sym0(close, "SIO1close");
1078 LoadSio1Sym0(pause, "SIO1pause");
1079 LoadSio1Sym0(resume, "SIO1resume");
1080 LoadSio1Sym0(keypressed, "SIO1keypressed");
1081 LoadSio1Sym0(configure, "SIO1configure");
1082 LoadSio1Sym0(test, "SIO1test");
1083 LoadSio1Sym0(about, "SIO1about");
1084 LoadSio1Sym0(writeData8, "SIO1writeData8");
1085 LoadSio1Sym0(writeData16, "SIO1writeData16");
1086 LoadSio1Sym0(writeData32, "SIO1writeData32");
1087 LoadSio1Sym0(writeStat16, "SIO1writeStat16");
1088 LoadSio1Sym0(writeStat32, "SIO1writeStat32");
1089 LoadSio1Sym0(writeMode16, "SIO1writeMode16");
1090 LoadSio1Sym0(writeMode32, "SIO1writeMode32");
1091 LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
1092 LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
1093 LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
1094 LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
1095 LoadSio1Sym0(readData16, "SIO1readData16");
1096 LoadSio1Sym0(readData32, "SIO1readData32");
1097 LoadSio1Sym0(readStat16, "SIO1readStat16");
1098 LoadSio1Sym0(readStat32, "SIO1readStat32");
1099 LoadSio1Sym0(readMode16, "SIO1readMode16");
1100 LoadSio1Sym0(readMode32, "SIO1readMode32");
1101 LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
1102 LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
1103 LoadSio1Sym0(readBaud16, "SIO1readBaud16");
1104 LoadSio1Sym0(readBaud32, "SIO1readBaud32");
1105 LoadSio1Sym0(registerCallback, "SIO1registerCallback");
1114 char Plugin[MAXPATHLEN * 2];
1120 LoadCDRplugin(NULL);
1122 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1123 if (LoadCDRplugin(Plugin) == -1) return -1;
1126 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
1127 if (LoadGPUplugin(Plugin) == -1) return -1;
1129 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
1130 if (LoadSPUplugin(Plugin) == -1) return -1;
1132 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
1133 if (LoadPAD1plugin(Plugin) == -1) return -1;
1135 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
1136 if (LoadPAD2plugin(Plugin) == -1) return -1;
1138 if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
1139 Config.UseNet = FALSE;
1141 Config.UseNet = TRUE;
1142 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
1143 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
1146 #ifdef ENABLE_SIO1API
1147 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
1148 if (LoadSIO1plugin(Plugin) == -1) return -1;
1152 if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
1154 if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
1156 if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
1158 if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
1160 if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
1162 if (Config.UseNet) {
1164 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
1167 #ifdef ENABLE_SIO1API
1169 if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
1172 SysPrintf(_("Plugins loaded.\n"));
1176 void ReleasePlugins() {
1177 if (Config.UseNet) {
1178 int ret = NET_close();
1179 if (ret < 0) Config.UseNet = FALSE;
1183 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1184 if (hGPUDriver != NULL) GPU_shutdown();
1185 if (hSPUDriver != NULL) SPU_shutdown();
1186 if (hPAD1Driver != NULL) PAD1_shutdown();
1187 if (hPAD2Driver != NULL) PAD2_shutdown();
1189 if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
1191 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1192 if (hGPUDriver != NULL) { SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; }
1193 if (hSPUDriver != NULL) { SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; }
1194 if (hPAD1Driver != NULL) { SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; }
1195 if (hPAD2Driver != NULL) { SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; }
1197 if (Config.UseNet && hNETDriver != NULL) {
1198 SysCloseLibrary(hNETDriver); hNETDriver = NULL;
1201 #ifdef ENABLE_SIO1API
1202 if (hSIO1Driver != NULL) {
1204 SysCloseLibrary(hSIO1Driver);
1211 int ReloadCdromPlugin()
1213 if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1214 if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1217 LoadCDRplugin(NULL);
1219 char Plugin[MAXPATHLEN * 2];
1220 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1221 if (LoadCDRplugin(Plugin) == -1) return -1;
1227 void SetIsoFile(const char *filename) {
1228 if (filename == NULL) {
1232 strncpy(IsoFile, filename, MAXPATHLEN - 1);
1235 const char *GetIsoFile(void) {
1239 boolean UsingIso(void) {
1240 return (IsoFile[0] != '\0');
1243 void SetCdOpenCaseTime(s64 time) {
1244 cdOpenCaseTime = time;