Add dual shop request/response
[pcsx_rearmed.git] / libpcsxcore / plugins.c
1 /***************************************************************************\r
2  *   Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team              *\r
3  *                                                                         *\r
4  *   This program is free software; you can redistribute it and/or modify  *\r
5  *   it under the terms of the GNU General Public License as published by  *\r
6  *   the Free Software Foundation; either version 2 of the License, or     *\r
7  *   (at your option) any later version.                                   *\r
8  *                                                                         *\r
9  *   This program is distributed in the hope that it will be useful,       *\r
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
12  *   GNU General Public License for more details.                          *\r
13  *                                                                         *\r
14  *   You should have received a copy of the GNU General Public License     *\r
15  *   along with this program; if not, write to the                         *\r
16  *   Free Software Foundation, Inc.,                                       *\r
17  *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *\r
18  ***************************************************************************/\r
19 \r
20 /*\r
21 * Plugin library callback/access functions.\r
22 */\r
23 \r
24 #include "plugins.h"\r
25 #include "cdriso.h"\r
26 \r
27 static char IsoFile[MAXPATHLEN] = "";\r
28 static s64 cdOpenCaseTime = 0;\r
29 \r
30 GPUupdateLace         GPU_updateLace;\r
31 GPUinit               GPU_init;\r
32 GPUshutdown           GPU_shutdown; \r
33 GPUconfigure          GPU_configure;\r
34 GPUtest               GPU_test;\r
35 GPUabout              GPU_about;\r
36 GPUopen               GPU_open;\r
37 GPUclose              GPU_close;\r
38 GPUreadStatus         GPU_readStatus;\r
39 GPUreadData           GPU_readData;\r
40 GPUreadDataMem        GPU_readDataMem;\r
41 GPUwriteStatus        GPU_writeStatus; \r
42 GPUwriteData          GPU_writeData;\r
43 GPUwriteDataMem       GPU_writeDataMem;\r
44 GPUdmaChain           GPU_dmaChain;\r
45 GPUkeypressed         GPU_keypressed;\r
46 GPUdisplayText        GPU_displayText;\r
47 GPUmakeSnapshot       GPU_makeSnapshot;\r
48 GPUfreeze             GPU_freeze;\r
49 GPUgetScreenPic       GPU_getScreenPic;\r
50 GPUshowScreenPic      GPU_showScreenPic;\r
51 GPUclearDynarec       GPU_clearDynarec;\r
52 GPUvBlank             GPU_vBlank;\r
53 \r
54 CDRinit               CDR_init;\r
55 CDRshutdown           CDR_shutdown;\r
56 CDRopen               CDR_open;\r
57 CDRclose              CDR_close; \r
58 CDRtest               CDR_test;\r
59 CDRgetTN              CDR_getTN;\r
60 CDRgetTD              CDR_getTD;\r
61 CDRreadTrack          CDR_readTrack;\r
62 CDRgetBuffer          CDR_getBuffer;\r
63 CDRplay               CDR_play;\r
64 CDRstop               CDR_stop;\r
65 CDRgetStatus          CDR_getStatus;\r
66 CDRgetDriveLetter     CDR_getDriveLetter;\r
67 CDRgetBufferSub       CDR_getBufferSub;\r
68 CDRconfigure          CDR_configure;\r
69 CDRabout              CDR_about;\r
70 CDRsetfilename        CDR_setfilename;\r
71 CDRreadCDDA           CDR_readCDDA;\r
72 CDRgetTE              CDR_getTE;\r
73 \r
74 SPUconfigure          SPU_configure;\r
75 SPUabout              SPU_about;\r
76 SPUinit               SPU_init;\r
77 SPUshutdown           SPU_shutdown;\r
78 SPUtest               SPU_test;\r
79 SPUopen               SPU_open;\r
80 SPUclose              SPU_close;\r
81 SPUplaySample         SPU_playSample;\r
82 SPUwriteRegister      SPU_writeRegister;\r
83 SPUreadRegister       SPU_readRegister;\r
84 SPUwriteDMA           SPU_writeDMA;\r
85 SPUreadDMA            SPU_readDMA;\r
86 SPUwriteDMAMem        SPU_writeDMAMem;\r
87 SPUreadDMAMem         SPU_readDMAMem;\r
88 SPUplayADPCMchannel   SPU_playADPCMchannel;\r
89 SPUfreeze             SPU_freeze;\r
90 SPUregisterCallback   SPU_registerCallback;\r
91 SPUregisterScheduleCb SPU_registerScheduleCb;\r
92 SPUasync              SPU_async;\r
93 SPUplayCDDAchannel    SPU_playCDDAchannel;\r
94 \r
95 PADconfigure          PAD1_configure;\r
96 PADabout              PAD1_about;\r
97 PADinit               PAD1_init;\r
98 PADshutdown           PAD1_shutdown;\r
99 PADtest               PAD1_test;\r
100 PADopen               PAD1_open;\r
101 PADclose              PAD1_close;\r
102 PADquery              PAD1_query;\r
103 PADreadPort1          PAD1_readPort1;\r
104 PADkeypressed         PAD1_keypressed;\r
105 PADstartPoll          PAD1_startPoll;\r
106 PADpoll               PAD1_poll;\r
107 PADsetSensitive       PAD1_setSensitive;\r
108 \r
109 PADconfigure          PAD2_configure;\r
110 PADabout              PAD2_about;\r
111 PADinit               PAD2_init;\r
112 PADshutdown           PAD2_shutdown;\r
113 PADtest               PAD2_test;\r
114 PADopen               PAD2_open;\r
115 PADclose              PAD2_close;\r
116 PADquery              PAD2_query;\r
117 PADreadPort2          PAD2_readPort2;\r
118 PADkeypressed         PAD2_keypressed;\r
119 PADstartPoll          PAD2_startPoll;\r
120 PADpoll               PAD2_poll;\r
121 PADsetSensitive       PAD2_setSensitive;\r
122 \r
123 NETinit               NET_init;\r
124 NETshutdown           NET_shutdown;\r
125 NETopen               NET_open;\r
126 NETclose              NET_close; \r
127 NETtest               NET_test;\r
128 NETconfigure          NET_configure;\r
129 NETabout              NET_about;\r
130 NETpause              NET_pause;\r
131 NETresume             NET_resume;\r
132 NETqueryPlayer        NET_queryPlayer;\r
133 NETsendData           NET_sendData;\r
134 NETrecvData           NET_recvData;\r
135 NETsendPadData        NET_sendPadData;\r
136 NETrecvPadData        NET_recvPadData;\r
137 NETsetInfo            NET_setInfo;\r
138 NETkeypressed         NET_keypressed;\r
139 \r
140 #ifdef ENABLE_SIO1API\r
141 \r
142 SIO1init              SIO1_init;\r
143 SIO1shutdown          SIO1_shutdown;\r
144 SIO1open              SIO1_open;\r
145 SIO1close             SIO1_close; \r
146 SIO1test              SIO1_test;\r
147 SIO1configure         SIO1_configure;\r
148 SIO1about             SIO1_about;\r
149 SIO1pause             SIO1_pause;\r
150 SIO1resume            SIO1_resume;\r
151 SIO1keypressed        SIO1_keypressed;\r
152 SIO1writeData8        SIO1_writeData8;\r
153 SIO1writeData16       SIO1_writeData16;\r
154 SIO1writeData32       SIO1_writeData32;\r
155 SIO1writeStat16       SIO1_writeStat16;\r
156 SIO1writeStat32       SIO1_writeStat32;\r
157 SIO1writeMode16       SIO1_writeMode16;\r
158 SIO1writeMode32       SIO1_writeMode32;\r
159 SIO1writeCtrl16       SIO1_writeCtrl16;\r
160 SIO1writeCtrl32       SIO1_writeCtrl32;\r
161 SIO1writeBaud16       SIO1_writeBaud16;\r
162 SIO1writeBaud32       SIO1_writeBaud32;\r
163 SIO1readData8         SIO1_readData8;\r
164 SIO1readData16        SIO1_readData16;\r
165 SIO1readData32        SIO1_readData32;\r
166 SIO1readStat16        SIO1_readStat16;\r
167 SIO1readStat32        SIO1_readStat32;\r
168 SIO1readMode16        SIO1_readMode16;\r
169 SIO1readMode32        SIO1_readMode32;\r
170 SIO1readCtrl16        SIO1_readCtrl16;\r
171 SIO1readCtrl32        SIO1_readCtrl32;\r
172 SIO1readBaud16        SIO1_readBaud16;\r
173 SIO1readBaud32        SIO1_readBaud32;\r
174 SIO1registerCallback  SIO1_registerCallback;\r
175 \r
176 #endif\r
177 \r
178 static const char *err;\r
179 \r
180 #define CheckErr(func) { \\r
181         err = SysLibError(); \\r
182         if (err != NULL) { SysMessage(_("Error loading %s: %s"), func, err); return -1; } \\r
183 }\r
184 \r
185 #define LoadSym(dest, src, name, checkerr) { \\r
186         dest = (src)SysLoadSym(drv, name); \\r
187         if (checkerr) { CheckErr(name); } else SysLibError(); \\r
188 }\r
189 \r
190 void *hGPUDriver = NULL;\r
191 \r
192 void CALLBACK GPU__displayText(char *pText) {\r
193         SysPrintf("%s\n", pText);\r
194 }\r
195 \r
196 long CALLBACK GPU__configure(void) { return 0; }\r
197 long CALLBACK GPU__test(void) { return 0; }\r
198 void CALLBACK GPU__about(void) {}\r
199 void CALLBACK GPU__makeSnapshot(void) {}\r
200 void CALLBACK GPU__keypressed(int key) {}\r
201 long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }\r
202 long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }\r
203 void CALLBACK GPU__clearDynarec(void (CALLBACK *callback)(void)) {}\r
204 void CALLBACK GPU__vBlank(int val) {}\r
205 \r
206 #define LoadGpuSym1(dest, name) \\r
207         LoadSym(GPU_##dest, GPU##dest, name, TRUE);\r
208
209 #define LoadGpuSym0(dest, name) \\r
210         LoadSym(GPU_##dest, GPU##dest, name, FALSE); \\r
211         if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest;\r
212 \r
213 #define LoadGpuSymN(dest, name) \\r
214         LoadSym(GPU_##dest, GPU##dest, name, FALSE);\r
215 \r
216 static int LoadGPUplugin(const char *GPUdll) {\r
217         void *drv;\r
218 \r
219         hGPUDriver = SysLoadLibrary(GPUdll);\r
220         if (hGPUDriver == NULL) { \r
221                 GPU_configure = NULL;\r
222                 SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1; \r
223         }\r
224         drv = hGPUDriver;\r
225         LoadGpuSym1(init, "GPUinit");\r
226         LoadGpuSym1(shutdown, "GPUshutdown");\r
227         LoadGpuSym1(open, "GPUopen");\r
228         LoadGpuSym1(close, "GPUclose");\r
229         LoadGpuSym1(readData, "GPUreadData");\r
230         LoadGpuSym1(readDataMem, "GPUreadDataMem");\r
231         LoadGpuSym1(readStatus, "GPUreadStatus");\r
232         LoadGpuSym1(writeData, "GPUwriteData");\r
233         LoadGpuSym1(writeDataMem, "GPUwriteDataMem");\r
234         LoadGpuSym1(writeStatus, "GPUwriteStatus");\r
235         LoadGpuSym1(dmaChain, "GPUdmaChain");\r
236         LoadGpuSym1(updateLace, "GPUupdateLace");\r
237         LoadGpuSym0(keypressed, "GPUkeypressed");\r
238         LoadGpuSym0(displayText, "GPUdisplayText");\r
239         LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");\r
240         LoadGpuSym1(freeze, "GPUfreeze");\r
241         LoadGpuSym0(getScreenPic, "GPUgetScreenPic");\r
242         LoadGpuSym0(showScreenPic, "GPUshowScreenPic");\r
243         LoadGpuSym0(clearDynarec, "GPUclearDynarec");\r
244     LoadGpuSym0(vBlank, "GPUvBlank");\r
245         LoadGpuSym0(configure, "GPUconfigure");\r
246         LoadGpuSym0(test, "GPUtest");\r
247         LoadGpuSym0(about, "GPUabout");\r
248 \r
249         return 0;\r
250 }\r
251 \r
252 void *hCDRDriver = NULL;\r
253 \r
254 long CALLBACK CDR__play(unsigned char *sector) { return 0; }\r
255 long CALLBACK CDR__stop(void) { return 0; }\r
256 \r
257 long CALLBACK CDR__getStatus(struct CdrStat *stat) {\r
258         if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))\r
259                 stat->Status = 0x10;\r
260         else\r
261                 stat->Status = 0;\r
262 \r
263         return 0;\r
264 }\r
265 \r
266 char* CALLBACK CDR__getDriveLetter(void) { return NULL; }\r
267 long CALLBACK CDR__configure(void) { return 0; }\r
268 long CALLBACK CDR__test(void) { return 0; }\r
269 void CALLBACK CDR__about(void) {}\r
270 long CALLBACK CDR__setfilename(char*filename) { return 0; }\r
271 \r
272 #define LoadCdrSym1(dest, name) \\r
273         LoadSym(CDR_##dest, CDR##dest, name, TRUE);\r
274 \r
275 #define LoadCdrSym0(dest, name) \\r
276         LoadSym(CDR_##dest, CDR##dest, name, FALSE); \\r
277         if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;\r
278 \r
279 #define LoadCdrSymN(dest, name) \\r
280         LoadSym(CDR_##dest, CDR##dest, name, FALSE);\r
281 \r
282 static int LoadCDRplugin(const char *CDRdll) {\r
283         void *drv;\r
284 \r
285         if (CDRdll == NULL) {\r
286                 cdrIsoInit();\r
287                 return 0;\r
288         }\r
289 \r
290         hCDRDriver = SysLoadLibrary(CDRdll);\r
291         if (hCDRDriver == NULL) {\r
292                 CDR_configure = NULL;\r
293                 SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll);  return -1;\r
294         }\r
295         drv = hCDRDriver;\r
296         LoadCdrSym1(init, "CDRinit");\r
297         LoadCdrSym1(shutdown, "CDRshutdown");\r
298         LoadCdrSym1(open, "CDRopen");\r
299         LoadCdrSym1(close, "CDRclose");\r
300         LoadCdrSym1(getTN, "CDRgetTN");\r
301         LoadCdrSym1(getTD, "CDRgetTD");\r
302         LoadCdrSym1(readTrack, "CDRreadTrack");\r
303         LoadCdrSym1(getBuffer, "CDRgetBuffer");\r
304         LoadCdrSym1(getBufferSub, "CDRgetBufferSub");\r
305         LoadCdrSym0(play, "CDRplay");\r
306         LoadCdrSym0(stop, "CDRstop");\r
307         LoadCdrSym0(getStatus, "CDRgetStatus");\r
308         LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");\r
309         LoadCdrSym0(configure, "CDRconfigure");\r
310         LoadCdrSym0(test, "CDRtest");\r
311         LoadCdrSym0(about, "CDRabout");\r
312         LoadCdrSym0(setfilename, "CDRsetfilename");\r
313         LoadCdrSymN(readCDDA, "CDRreadCDDA");\r
314         LoadCdrSymN(getTE, "CDRgetTE");\r
315 \r
316         return 0;\r
317 }\r
318 \r
319 void *hSPUDriver = NULL;\r
320 \r
321 long CALLBACK SPU__configure(void) { return 0; }\r
322 void CALLBACK SPU__about(void) {}\r
323 long CALLBACK SPU__test(void) { return 0; }\r
324 void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}\r
325 \r
326 #define LoadSpuSym1(dest, name) \\r
327         LoadSym(SPU_##dest, SPU##dest, name, TRUE);\r
328 \r
329 #define LoadSpuSym0(dest, name) \\r
330         LoadSym(SPU_##dest, SPU##dest, name, FALSE); \\r
331         if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;\r
332 \r
333 #define LoadSpuSymN(dest, name) \\r
334         LoadSym(SPU_##dest, SPU##dest, name, FALSE);\r
335 \r
336 static int LoadSPUplugin(const char *SPUdll) {\r
337         void *drv;\r
338 \r
339         hSPUDriver = SysLoadLibrary(SPUdll);\r
340         if (hSPUDriver == NULL) {\r
341                 SPU_configure = NULL;\r
342                 SysMessage (_("Could not load SPU plugin %s!"), SPUdll); return -1;\r
343         }\r
344         drv = hSPUDriver;\r
345         LoadSpuSym1(init, "SPUinit");\r
346         LoadSpuSym1(shutdown, "SPUshutdown");\r
347         LoadSpuSym1(open, "SPUopen");\r
348         LoadSpuSym1(close, "SPUclose");\r
349         LoadSpuSym0(configure, "SPUconfigure");\r
350         LoadSpuSym0(about, "SPUabout");\r
351         LoadSpuSym0(test, "SPUtest");\r
352         LoadSpuSym1(writeRegister, "SPUwriteRegister");\r
353         LoadSpuSym1(readRegister, "SPUreadRegister");           \r
354         LoadSpuSym1(writeDMA, "SPUwriteDMA");\r
355         LoadSpuSym1(readDMA, "SPUreadDMA");\r
356         LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");\r
357         LoadSpuSym1(readDMAMem, "SPUreadDMAMem");\r
358         LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");\r
359         LoadSpuSym1(freeze, "SPUfreeze");\r
360         LoadSpuSym1(registerCallback, "SPUregisterCallback");\r
361         LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");\r
362         LoadSpuSymN(async, "SPUasync");\r
363         LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");\r
364 \r
365         return 0;\r
366 }\r
367 \r
368 void *hPAD1Driver = NULL;\r
369 void *hPAD2Driver = NULL;\r
370 \r
371 static int multitap1 = -1;\r
372 static int multitap2 = -1;\r
373 //Pad information, keystate, mode, config mode, vibration\r
374 static PadDataS pad[8];
375
376 static int reqPos, respSize, req, ledStateReq44;\r
377 \r
378 static unsigned char buf[256];\r
379 unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
380 unsigned char multitappar[34] = { 0x80, 0x5a, 
381                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
382                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
383                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
384                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
385                                                                         \r
386 //response for request 44, 45, 46, 47, 4C, 4D\r
387 static unsigned char resp45[8]    = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};\r
388 static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};\r
389 static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};\r
390 static unsigned char resp47[8]    = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};\r
391 static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};\r
392 static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};\r
393 static unsigned char resp4D[8]    = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};\r
394
395 //fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
396 static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
397 static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
398 static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
399 static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
400 static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
401 static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
402 static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
403 static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
404
405 // Resquest of psx core
406 enum {
407         // REQUEST
408         // first call of this request for the pad, the pad is configured as an digital pad.
409         // 0x0X, 0x42, 0x0Y, 0xZZ, 0xAA, 0x00, 0x00, 0x00, 0x00
410         // 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)
411         // Y if 1 : psx request the full length response for the multitap, 3 bytes header and 4 block of 8 bytes per pad
412         // Y if 0 : psx request a pad key state
413         // ZZ rumble small motor 00-> OFF, 01 -> ON
414         // AA rumble large motor speed 0x00 -> 0xFF
415         // RESPONSE
416         // header 3 Bytes
417         // 0x00 
418         // PadId -> 0x41 for digital pas, 0x73 for analog pad 
419         // 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
420         // 6 Bytes for keystates
421         CMD_READ_DATA_AND_VIBRATE = 0x42,
422         
423         // REQUEST
424         // Header
425         // 0x0N, 0x43, 0x00, XX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
426         // XX = 00 -> Normal mode : Seconde bytes of response = padId
427         // XX = 01 -> Configuration mode : Seconde bytes of response = 0xF3
428         // RESPONSE
429         // enter in config mode example : 
430         // req : 01 43 00 01 00 00 00 00 00 00
431         // res : 00 41 5A buttons state, analog states
432         // exit config mode : 
433         // req : 01 43 00 00 00 00 00 00 00 00
434         // res : 00 F3 5A buttons state, analog states
435         CMD_CONFIG_MODE = 0x43,
436         
437         // Set led State
438         // REQUEST
439         // 0x0N, 0x44, 0x00, VAL, SEL, 0x00, 0x00, 0x00, 0x00
440         // If sel = 2 then
441         // VAL = 00 -> OFF
442         // VAL = 01 -> ON
443         // RESPONSE
444         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
445         CMD_SET_MODE_AND_LOCK = 0x44,
446         
447         // Get Analog Led state
448         // REQUEST
449         // 0x0N, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
450         // RESPONSE
451         // 0x00, 0xF3, 0x5A, 0x01, 0x02, VAL, 0x02, 0x01, 0x00
452         // VAL = 00 Led OFF
453         // VAL = 01 Led ON
454         CMD_QUERY_MODEL_AND_MODE = 0x45,
455         
456         //Get Variable A
457         // REQUEST
458         // 0x0N, 0x46, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
459         // RESPONSE
460         // XX=00
461         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A
462         // XX=01
463         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14
464         CMD_QUERY_ACT = 0x46,
465         
466         // REQUEST
467         // 0x0N, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
468         // RESPONSE
469         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00
470         CMD_QUERY_COMB = 0x47,
471         
472         // REQUEST
473         // 0x0N, 0x4C, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
474         // RESPONSE
475         // XX = 0
476         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
477         // XX = 1
478         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00
479         CMD_QUERY_MODE = 0x4C,
480         
481         // REQUEST
482         // 0x0N, 0x4D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
483         // RESPONSE
484         // 0x00, 0xF3, 0x5A, old value or
485         // AA = 01 unlock large motor (and swap VAL1 and VAL2)
486         // BB = 01 unlock large motor (default)
487         // CC, DD, EE, FF = all FF -> unlock small motor
488         //
489         // default repsonse for analog pad with 2 motor : 0x00 0xF3 0x5A 0x00 0x01 0xFF 0xFF 0xFF 0xFF
490         //
491         CMD_VIBRATION_TOGGLE = 0x4D,
492         REQ40 = 0x40,
493         REQ41 = 0x41,
494         REQ49 = 0x49,
495         REQ4A = 0x4A,
496         REQ4B = 0x4B,
497         REQ4E = 0x4E,
498         REQ4F = 0x4F
499 };
500
501 void initBufForRequest(int padIndex, char value){
502         switch (value){\r
503                 //Pad keystate already in buffer\r
504                 //case CMD_READ_DATA_AND_VIBRATE :\r
505                 //      break;\r
506                 case CMD_CONFIG_MODE :\r
507                         if(pad[padIndex].configMode == TRUE){\r
508                                 buf[0] = 0xF3;
509                                 buf[1] = 0x53;\r
510                         }\r
511                         //else, not in config mode, pad keystate return (already in the buffer)\r
512                         break;\r
513                 case CMD_SET_MODE_AND_LOCK :\r
514                         memcpy(buf, resp44, 8);\r
515                         break;\r
516                 case CMD_QUERY_MODEL_AND_MODE :\r
517                         memcpy(buf, resp45, 8);\r
518                         break;\r
519                 case CMD_QUERY_ACT :\r
520                         memcpy(buf, resp46_00, 8);\r
521                         break;\r
522                 case CMD_QUERY_COMB :\r
523                         memcpy(buf, resp47, 8);\r
524                         break;\r
525                 case CMD_QUERY_MODE :\r
526                         memcpy(buf, resp4C_00, 8);\r
527                         break;\r
528                 case CMD_VIBRATION_TOGGLE :\r
529                         memcpy(buf, resp4D, 8);\r
530                         break;\r
531                 case REQ40 :\r
532                         memcpy(buf, resp40, 8);\r
533                         break;\r
534                 case REQ41 :\r
535                         memcpy(buf, resp41, 8);\r
536                         break;\r
537                 case REQ49 :\r
538                         memcpy(buf, resp49, 8);\r
539                         break;\r
540                 case REQ4A :\r
541                         memcpy(buf, resp4A, 8);\r
542                         break;\r
543                 case REQ4B :\r
544                         memcpy(buf, resp4B, 8);\r
545                         break;\r
546                 case REQ4E :\r
547                         memcpy(buf, resp4E, 8);\r
548                         break;\r
549                 case REQ4F :\r
550                         memcpy(buf, resp4F, 8);\r
551                         break;\r
552         }
553 }\r
554 \r
555 void reqIndex2Treatment(int padIndex, char value){\r
556         switch (value){\r
557                 case CMD_CONFIG_MODE :\r
558                         //0x43\r
559                         if(value == 0){\r
560                                 pad[padIndex].configMode = FALSE;\r
561                         }else{\r
562                                 pad->configMode = TRUE;\r
563                         }\r
564                         break;\r
565                 case CMD_SET_MODE_AND_LOCK :\r
566                         //0x44 store the led state for change mode if the next value = 0x02\r
567                         //0x01 analog ON\r
568                         //0x00 analog OFF\r
569                         ledStateReq44 = value;\r
570                         break;\r
571                 case CMD_QUERY_ACT :\r
572                         //0x46\r
573                         if(value==1){\r
574                                 memcpy(buf, resp46_01, 8);\r
575                         }\r
576                         break;\r
577                 \r
578                 case CMD_QUERY_MODE :\r
579                         if(value==1){\r
580                                 memcpy(buf, resp4C_01, 8);\r
581                         }\r
582                         break;\r
583                 case CMD_VIBRATION_TOGGLE :\r
584                         //0x4D\r
585                         memcpy(buf, resp4D, 8);\r
586                         break;\r
587                 case CMD_READ_DATA_AND_VIBRATE:\r
588                         //mem the vibration value for small motor;\r
589                         pad[padIndex].Vib[0] = value;
590         }\r
591 }\r
592         
593 void vibrate(int padIndex){
594         if(pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]){
595                 //value is different update Value and call libretro for vibration
596                 pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
597                 pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
598                 plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
599                 printf("new value for vibration pad %i", padIndex);
600         }
601 }\r
602         
603 \r
604 \r
605 //Build response for 0x42 request Multitap in port\r
606 void _PADstartPollMultitap(PadDataS padd[4]) {\r
607     int i = 0;\r
608     int offset = 2;\r
609     PadDataS pad;\r
610     for(i = 0; i < 4; i++) {\r
611         offset = 2 + (i * 8);\r
612         pad = padd[i];\r
613                 switch (pad.controllerType) {\r
614                         case PSE_PAD_TYPE_MOUSE:\r
615                                 multitappar[offset] = 0x12;\r
616                                 multitappar[offset + 1] = 0x5a;\r
617                                 multitappar[offset + 2] = pad.buttonStatus & 0xff;\r
618                                 multitappar[offset + 3] = pad.buttonStatus >> 8;\r
619                                 multitappar[offset + 4] = pad.moveX;\r
620                                 multitappar[offset + 5] = pad.moveY;\r
621 \r
622                                 break;\r
623                         case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)\r
624                                 multitappar[offset] = 0x23;\r
625                                 multitappar[offset + 1] = 0x5a;\r
626                                 multitappar[offset + 2] = pad.buttonStatus & 0xff;\r
627                                 multitappar[offset + 3] = pad.buttonStatus >> 8;\r
628                                 multitappar[offset + 4] = pad.rightJoyX;\r
629                                 multitappar[offset + 5] = pad.rightJoyY;\r
630                                 multitappar[offset + 6] = pad.leftJoyX;\r
631                                 multitappar[offset + 7] = pad.leftJoyY;\r
632 \r
633                                 break;\r
634                         case PSE_PAD_TYPE_ANALOGPAD: // scph1150\r
635                                 multitappar[offset] = 0x73;\r
636                                 multitappar[offset + 1] = 0x5a;\r
637                                 multitappar[offset + 2] = pad.buttonStatus & 0xff;\r
638                                 multitappar[offset + 3] = pad.buttonStatus >> 8;\r
639                                 multitappar[offset + 4] = pad.rightJoyX;\r
640                                 multitappar[offset + 5] = pad.rightJoyY;\r
641                                 multitappar[offset + 6] = pad.leftJoyX;\r
642                                 multitappar[offset + 7] = pad.leftJoyY;\r
643 \r
644                                 break;\r
645                         case PSE_PAD_TYPE_ANALOGJOY: // scph1110\r
646                                 multitappar[offset] = 0x53;\r
647                                 multitappar[offset + 1] = 0x5a;\r
648                                 multitappar[offset + 2] = pad.buttonStatus & 0xff;\r
649                                 multitappar[offset + 3] = pad.buttonStatus >> 8;\r
650                                 multitappar[offset + 4] = pad.rightJoyX;\r
651                                 multitappar[offset + 5] = pad.rightJoyY;\r
652                                 multitappar[offset + 6] = pad.leftJoyX;\r
653                                 multitappar[offset + 7] = pad.leftJoyY;\r
654 \r
655                                 break;\r
656                         case PSE_PAD_TYPE_STANDARD:\r
657                         default:\r
658                                 multitappar[offset] = 0x41;\r
659                                 multitappar[offset + 1] = 0x5a;\r
660                                 multitappar[offset + 2] = pad.buttonStatus & 0xff;\r
661                                 multitappar[offset + 3] = pad.buttonStatus >> 8;\r
662                 }\r
663     }\r
664     memcpy(buf, multitappar, 34);\r
665     respSize = 34;\r
666 }\r
667
668 //Build response for 0x42 request Pad in port\r
669 void _PADstartPoll(PadDataS *pad) {\r
670     switch (pad->controllerType) {\r
671         case PSE_PAD_TYPE_MOUSE:\r
672                         stdpar[0] = 0x12;\r
673             stdpar[2] = pad->buttonStatus & 0xff;\r
674             stdpar[3] = pad->buttonStatus >> 8;\r
675             stdpar[4] = pad->moveX;\r
676             stdpar[5] = pad->moveY;\r
677             memcpy(buf, stdpar, 6);\r
678             respSize = 6;\r
679             break;\r
680         case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)\r
681             stdpar[0] = 0x23;\r
682             stdpar[2] = pad->buttonStatus & 0xff;\r
683             stdpar[3] = pad->buttonStatus >> 8;\r
684             stdpar[4] = pad->rightJoyX;\r
685             stdpar[5] = pad->rightJoyY;\r
686             stdpar[6] = pad->leftJoyX;\r
687             stdpar[7] = pad->leftJoyY;\r
688             memcpy(buf, stdpar, 8);\r
689             respSize = 8;\r
690             break;\r
691         case PSE_PAD_TYPE_ANALOGPAD: // scph1150\r
692             stdpar[0] = 0x73;\r
693             stdpar[2] = pad->buttonStatus & 0xff;\r
694             stdpar[3] = pad->buttonStatus >> 8;\r
695             stdpar[4] = pad->rightJoyX;\r
696             stdpar[5] = pad->rightJoyY;\r
697             stdpar[6] = pad->leftJoyX;\r
698             stdpar[7] = pad->leftJoyY;\r
699             memcpy(buf, stdpar, 8);\r
700             respSize = 8;\r
701             break;\r
702         case PSE_PAD_TYPE_ANALOGJOY: // scph1110\r
703             stdpar[0] = 0x53;\r
704             stdpar[2] = pad->buttonStatus & 0xff;\r
705             stdpar[3] = pad->buttonStatus >> 8;\r
706             stdpar[4] = pad->rightJoyX;\r
707             stdpar[5] = pad->rightJoyY;\r
708             stdpar[6] = pad->leftJoyX;\r
709             stdpar[7] = pad->leftJoyY;\r
710             memcpy(buf, stdpar, 8);\r
711             respSize = 8;\r
712             break;\r
713         case PSE_PAD_TYPE_STANDARD:\r
714         default:\r
715             stdpar[2] = pad->buttonStatus & 0xff;\r
716             stdpar[3] = pad->buttonStatus >> 8;\r
717                 memcpy(buf, stdpar, 4);\r
718                 respSize = 8;\r
719     }\r
720 }\r
721 \r
722 \r
723 \r
724 unsigned char _PADpoll(int padIndex, unsigned char value) {
725                 \r
726         //If no multitap on the port, we made the full implementation of dualshock protocol\r
727         if(multitap1 == 0){
728                 if(reqPos==0){
729                         //mem the request number
730                         req = value;\r
731                         //copy the default value of request response in buffer instead of the keystate\r
732                         initBufForRequest(padIndex,value);
733                 }\r
734                 \r
735                 //if no new request the pad return 0xff, for signaling connected\r
736                 if ( reqPos >= respSize) return 0xff;\r
737                 \r
738                 switch(reqPos){\r
739                         case 2:\r
740                                 reqIndex2Treatment(padIndex, value);\r
741                         break;\r
742                         case 3:\r
743                                 switch(req) {\r
744                                         case CMD_SET_MODE_AND_LOCK :\r
745                                                 //change mode on pad\r
746                                         break;\r
747                                         case CMD_READ_DATA_AND_VIBRATE:\r
748                                         //mem the vibration value for Large motor;\r
749                                         pad[padIndex].Vib[1] = value;\r
750                                         //vibration
751                                         vibrate(padIndex);\r
752                                         break;\r
753                                 \r
754                         break;\r
755                         }\r
756                 }\r
757         }\r
758         return buf[reqPos++];\r
759 }\r
760 \r
761 // refresh the button state on port 1.\r
762 // int pad is not needed.\r
763 unsigned char CALLBACK PAD1__startPoll(int pad) {
764         reqPos = 0;\r
765         // first call the pad provide if a multitap is connected between the psx and himself\r
766         if(multitap1 == -1){\r
767                 PadDataS padd;
768                 padd.requestPadIndex = 0;\r
769                 PAD1_readPort1(&padd);\r
770                 multitap1 = padd.portMultitap;\r
771         }\r
772         // just one pad is on port 1 : NO MULTITAP\r
773         if (multitap1 == 0){\r
774                 PadDataS padd;
775                 padd.requestPadIndex = 0;\r
776                 PAD1_readPort1(&padd);\r
777                 _PADstartPoll(&padd);\r
778         } else {\r
779                 // a multitap is plugged : refresh all pad.\r
780                 int i=0;\r
781                 PadDataS padd[4];\r
782                 for(i = 0; i < 4; i++) {
783                         padd[i].requestPadIndex = i;\r
784                         PAD1_readPort1(&padd[i]);\r
785                 }
786                 _PADstartPollMultitap(padd);\r
787         }
788         printf("\n");
789         return 0x00;\r
790 }\r
791 \r
792 unsigned char CALLBACK PAD1__poll(unsigned char value) {
793         char tmp = _PADpoll(0, value);
794         printf("%2x:%2x , ",value,tmp);\r
795         return tmp;\r
796         \r
797 }\r
798 \r
799 \r
800 long CALLBACK PAD1__configure(void) { return 0; }\r
801 void CALLBACK PAD1__about(void) {}\r
802 long CALLBACK PAD1__test(void) { return 0; }\r
803 long CALLBACK PAD1__query(void) { return 3; }\r
804 long CALLBACK PAD1__keypressed() { return 0; }\r
805 \r
806 #define LoadPad1Sym1(dest, name) \\r
807         LoadSym(PAD1_##dest, PAD##dest, name, TRUE);\r
808 \r
809 #define LoadPad1SymN(dest, name) \\r
810         LoadSym(PAD1_##dest, PAD##dest, name, FALSE);\r
811 \r
812 #define LoadPad1Sym0(dest, name) \\r
813         LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \\r
814         if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;\r
815 \r
816 static int LoadPAD1plugin(const char *PAD1dll) {\r
817         void *drv;\r
818 \r
819         hPAD1Driver = SysLoadLibrary(PAD1dll);\r
820         if (hPAD1Driver == NULL) {\r
821                 PAD1_configure = NULL;\r
822                 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;\r
823         }\r
824         drv = hPAD1Driver;\r
825         LoadPad1Sym1(init, "PADinit");\r
826         LoadPad1Sym1(shutdown, "PADshutdown");\r
827         LoadPad1Sym1(open, "PADopen");\r
828         LoadPad1Sym1(close, "PADclose");\r
829         LoadPad1Sym0(query, "PADquery");\r
830         LoadPad1Sym1(readPort1, "PADreadPort1");\r
831         LoadPad1Sym0(configure, "PADconfigure");\r
832         LoadPad1Sym0(test, "PADtest");\r
833         LoadPad1Sym0(about, "PADabout");\r
834         LoadPad1Sym0(keypressed, "PADkeypressed");\r
835         LoadPad1Sym0(startPoll, "PADstartPoll");\r
836         LoadPad1Sym0(poll, "PADpoll");\r
837         LoadPad1SymN(setSensitive, "PADsetSensitive");\r
838 \r
839         return 0;\r
840 }\r
841 \r
842 unsigned char CALLBACK PAD2__startPoll(int pad) {
843         reqPos = 0;\r
844         int pad_index = 0;
845         if(multitap1 == 1){
846                 pad_index+=4;
847         }else{
848                 pad_index=1;
849         }
850         //first call the pad provide if a multitap is connected between the psx and himself
851         if(multitap2 == -1){
852                 PadDataS padd;
853                 padd.requestPadIndex = pad_index;
854                 PAD2_readPort2(&padd);
855                 multitap2 = padd.portMultitap;
856         }
857         \r
858         // just one pad is on port 1 : NO MULTITAP\r
859         if (multitap2 == 0){
860                 PadDataS padd;
861                 padd.requestPadIndex = pad_index;
862                 PAD2_readPort2(&padd);\r
863                 _PADstartPoll(&padd);\r
864         } else {\r
865                 // a multitap is plugged : refresh all pad.\r
866         //a multitap is plugged : refresh all pad.
867                 int i=0;
868                 PadDataS padd[4];
869                 for(i=0;i<4;i++){
870                         padd[i].requestPadIndex = i+pad_index;
871                         PAD2_readPort2(&padd[i]);
872                 }
873                 _PADstartPollMultitap(padd);\r
874         }
875         return 0x00;\r
876 }\r
877 \r
878 unsigned char CALLBACK PAD2__poll(unsigned char value) {\r
879         return _PADpoll(1,value);\r
880 }\r
881 \r
882 long CALLBACK PAD2__configure(void) { return 0; }\r
883 void CALLBACK PAD2__about(void) {}\r
884 long CALLBACK PAD2__test(void) { return 0; }\r
885 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }\r
886 long CALLBACK PAD2__keypressed() { return 0; }\r
887 \r
888 #define LoadPad2Sym1(dest, name) \\r
889         LoadSym(PAD2_##dest, PAD##dest, name, TRUE);\r
890 \r
891 #define LoadPad2Sym0(dest, name) \\r
892         LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \\r
893         if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;\r
894 \r
895 #define LoadPad2SymN(dest, name) \\r
896         LoadSym(PAD2_##dest, PAD##dest, name, FALSE);\r
897 \r
898 static int LoadPAD2plugin(const char *PAD2dll) {\r
899         void *drv;\r
900 \r
901         hPAD2Driver = SysLoadLibrary(PAD2dll);\r
902         if (hPAD2Driver == NULL) {\r
903                 PAD2_configure = NULL;\r
904                 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;\r
905         }\r
906         drv = hPAD2Driver;\r
907         LoadPad2Sym1(init, "PADinit");\r
908         LoadPad2Sym1(shutdown, "PADshutdown");\r
909         LoadPad2Sym1(open, "PADopen");\r
910         LoadPad2Sym1(close, "PADclose");\r
911         LoadPad2Sym0(query, "PADquery");\r
912         LoadPad2Sym1(readPort2, "PADreadPort2");\r
913         LoadPad2Sym0(configure, "PADconfigure");\r
914         LoadPad2Sym0(test, "PADtest");\r
915         LoadPad2Sym0(about, "PADabout");\r
916         LoadPad2Sym0(keypressed, "PADkeypressed");\r
917         LoadPad2Sym0(startPoll, "PADstartPoll");\r
918         LoadPad2Sym0(poll, "PADpoll");\r
919         LoadPad2SymN(setSensitive, "PADsetSensitive");\r
920 \r
921         return 0;\r
922 }\r
923 \r
924 void *hNETDriver = NULL;\r
925 \r
926 void CALLBACK NET__setInfo(netInfo *info) {}\r
927 void CALLBACK NET__keypressed(int key) {}\r
928 long CALLBACK NET__configure(void) { return 0; }\r
929 long CALLBACK NET__test(void) { return 0; }\r
930 void CALLBACK NET__about(void) {}\r
931 \r
932 #define LoadNetSym1(dest, name) \\r
933         LoadSym(NET_##dest, NET##dest, name, TRUE);\r
934 \r
935 #define LoadNetSymN(dest, name) \\r
936         LoadSym(NET_##dest, NET##dest, name, FALSE);\r
937 \r
938 #define LoadNetSym0(dest, name) \\r
939         LoadSym(NET_##dest, NET##dest, name, FALSE); \\r
940         if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;\r
941 \r
942 static int LoadNETplugin(const char *NETdll) {\r
943         void *drv;\r
944 \r
945         hNETDriver = SysLoadLibrary(NETdll);\r
946         if (hNETDriver == NULL) {\r
947                 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;\r
948         }\r
949         drv = hNETDriver;\r
950         LoadNetSym1(init, "NETinit");\r
951         LoadNetSym1(shutdown, "NETshutdown");\r
952         LoadNetSym1(open, "NETopen");\r
953         LoadNetSym1(close, "NETclose");\r
954         LoadNetSymN(sendData, "NETsendData");\r
955         LoadNetSymN(recvData, "NETrecvData");\r
956         LoadNetSym1(sendPadData, "NETsendPadData");\r
957         LoadNetSym1(recvPadData, "NETrecvPadData");\r
958         LoadNetSym1(queryPlayer, "NETqueryPlayer");\r
959         LoadNetSym1(pause, "NETpause");\r
960         LoadNetSym1(resume, "NETresume");\r
961         LoadNetSym0(setInfo, "NETsetInfo");\r
962         LoadNetSym0(keypressed, "NETkeypressed");\r
963         LoadNetSym0(configure, "NETconfigure");\r
964         LoadNetSym0(test, "NETtest");\r
965         LoadNetSym0(about, "NETabout");\r
966 \r
967         return 0;\r
968 }\r
969 \r
970 #ifdef ENABLE_SIO1API\r
971 \r
972 void *hSIO1Driver = NULL;\r
973 \r
974 long CALLBACK SIO1__init(void) { return 0; }\r
975 long CALLBACK SIO1__shutdown(void) { return 0; }\r
976 long CALLBACK SIO1__open(void) { return 0; }\r
977 long CALLBACK SIO1__close(void) { return 0; }\r
978 long CALLBACK SIO1__configure(void) { return 0; }\r
979 long CALLBACK SIO1__test(void) { return 0; }\r
980 void CALLBACK SIO1__about(void) {}\r
981 void CALLBACK SIO1__pause(void) {}\r
982 void CALLBACK SIO1__resume(void) {}\r
983 long CALLBACK SIO1__keypressed(int key) { return 0; }\r
984 void CALLBACK SIO1__writeData8(unsigned char val) {}\r
985 void CALLBACK SIO1__writeData16(unsigned short val) {}\r
986 void CALLBACK SIO1__writeData32(unsigned long val) {}\r
987 void CALLBACK SIO1__writeStat16(unsigned short val) {}\r
988 void CALLBACK SIO1__writeStat32(unsigned long val) {}\r
989 void CALLBACK SIO1__writeMode16(unsigned short val) {}\r
990 void CALLBACK SIO1__writeMode32(unsigned long val) {}\r
991 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}\r
992 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}\r
993 void CALLBACK SIO1__writeBaud16(unsigned short val) {}\r
994 void CALLBACK SIO1__writeBaud32(unsigned long val) {}\r
995 unsigned char CALLBACK SIO1__readData8(void) { return 0; }\r
996 unsigned short CALLBACK SIO1__readData16(void) { return 0; }\r
997 unsigned long CALLBACK SIO1__readData32(void) { return 0; }\r
998 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }\r
999 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }\r
1000 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }\r
1001 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }\r
1002 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }\r
1003 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }\r
1004 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }\r
1005 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }\r
1006 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};\r
1007 \r
1008 void CALLBACK SIO1irq(void) {\r
1009     psxHu32ref(0x1070) |= SWAPu32(0x100);\r
1010 }\r
1011 \r
1012 #define LoadSio1Sym1(dest, name) \\r
1013     LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);\r
1014 \r
1015 #define LoadSio1SymN(dest, name) \\r
1016     LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);\r
1017 \r
1018 #define LoadSio1Sym0(dest, name) \\r
1019     LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \\r
1020     if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;\r
1021 \r
1022 static int LoadSIO1plugin(const char *SIO1dll) {\r
1023     void *drv;\r
1024 \r
1025     hSIO1Driver = SysLoadLibrary(SIO1dll);\r
1026     if (hSIO1Driver == NULL) {\r
1027         SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;\r
1028     }\r
1029     drv = hSIO1Driver;\r
1030 \r
1031     LoadSio1Sym0(init, "SIO1init");\r
1032     LoadSio1Sym0(shutdown, "SIO1shutdown");\r
1033     LoadSio1Sym0(open, "SIO1open");\r
1034     LoadSio1Sym0(close, "SIO1close");\r
1035     LoadSio1Sym0(pause, "SIO1pause");\r
1036     LoadSio1Sym0(resume, "SIO1resume");\r
1037     LoadSio1Sym0(keypressed, "SIO1keypressed");\r
1038     LoadSio1Sym0(configure, "SIO1configure");\r
1039     LoadSio1Sym0(test, "SIO1test");\r
1040     LoadSio1Sym0(about, "SIO1about");\r
1041     LoadSio1Sym0(writeData8, "SIO1writeData8");\r
1042     LoadSio1Sym0(writeData16, "SIO1writeData16");\r
1043     LoadSio1Sym0(writeData32, "SIO1writeData32");\r
1044     LoadSio1Sym0(writeStat16, "SIO1writeStat16");\r
1045     LoadSio1Sym0(writeStat32, "SIO1writeStat32");\r
1046     LoadSio1Sym0(writeMode16, "SIO1writeMode16");\r
1047     LoadSio1Sym0(writeMode32, "SIO1writeMode32");\r
1048     LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");\r
1049     LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");\r
1050     LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");\r
1051     LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");\r
1052     LoadSio1Sym0(readData16, "SIO1readData16");\r
1053     LoadSio1Sym0(readData32, "SIO1readData32");\r
1054     LoadSio1Sym0(readStat16, "SIO1readStat16");\r
1055     LoadSio1Sym0(readStat32, "SIO1readStat32");\r
1056     LoadSio1Sym0(readMode16, "SIO1readMode16");\r
1057     LoadSio1Sym0(readMode32, "SIO1readMode32");\r
1058     LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");\r
1059     LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");\r
1060     LoadSio1Sym0(readBaud16, "SIO1readBaud16");\r
1061     LoadSio1Sym0(readBaud32, "SIO1readBaud32");\r
1062     LoadSio1Sym0(registerCallback, "SIO1registerCallback");\r
1063 \r
1064     return 0;\r
1065 }\r
1066 \r
1067 #endif\r
1068 \r
1069 void CALLBACK clearDynarec(void) {\r
1070         psxCpu->Reset();\r
1071 }\r
1072 \r
1073 int LoadPlugins() {\r
1074         int ret;\r
1075         char Plugin[MAXPATHLEN];\r
1076 \r
1077         ReleasePlugins();\r
1078         SysLibError();\r
1079 \r
1080         if (UsingIso()) {\r
1081                 LoadCDRplugin(NULL);\r
1082         } else {\r
1083                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);\r
1084                 if (LoadCDRplugin(Plugin) == -1) return -1;\r
1085         }\r
1086 \r
1087         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);\r
1088         if (LoadGPUplugin(Plugin) == -1) return -1;\r
1089 \r
1090         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);\r
1091         if (LoadSPUplugin(Plugin) == -1) return -1;\r
1092 \r
1093         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);\r
1094         if (LoadPAD1plugin(Plugin) == -1) return -1;\r
1095 \r
1096         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);\r
1097         if (LoadPAD2plugin(Plugin) == -1) return -1;\r
1098 \r
1099         if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)\r
1100                 Config.UseNet = FALSE;\r
1101         else {\r
1102                 Config.UseNet = TRUE;\r
1103                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);\r
1104                 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;\r
1105         }\r
1106 \r
1107 #ifdef ENABLE_SIO1API\r
1108         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);\r
1109         if (LoadSIO1plugin(Plugin) == -1) return -1;\r
1110 #endif\r
1111 \r
1112         ret = CDR_init();\r
1113         if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }\r
1114         ret = GPU_init();\r
1115         if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }\r
1116         ret = SPU_init();\r
1117         if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }\r
1118         ret = PAD1_init(1);\r
1119         if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }\r
1120         ret = PAD2_init(2);\r
1121         if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }\r
1122 \r
1123         if (Config.UseNet) {\r
1124                 ret = NET_init();\r
1125                 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }\r
1126         }\r
1127 \r
1128 #ifdef ENABLE_SIO1API\r
1129         ret = SIO1_init();\r
1130         if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }\r
1131 #endif\r
1132 \r
1133         SysPrintf(_("Plugins loaded.\n"));\r
1134         return 0;\r
1135 }\r
1136 \r
1137 void ReleasePlugins() {\r
1138         if (Config.UseNet) {\r
1139                 int ret = NET_close();\r
1140                 if (ret < 0) Config.UseNet = FALSE;\r
1141         }\r
1142         NetOpened = FALSE;\r
1143 \r
1144         if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();\r
1145         if (hGPUDriver != NULL) GPU_shutdown();\r
1146         if (hSPUDriver != NULL) SPU_shutdown();\r
1147         if (hPAD1Driver != NULL) PAD1_shutdown();\r
1148         if (hPAD2Driver != NULL) PAD2_shutdown();\r
1149 \r
1150         if (Config.UseNet && hNETDriver != NULL) NET_shutdown(); \r
1151 \r
1152         if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;\r
1153         if (hGPUDriver != NULL) SysCloseLibrary(hGPUDriver); hGPUDriver = NULL;\r
1154         if (hSPUDriver != NULL) SysCloseLibrary(hSPUDriver); hSPUDriver = NULL;\r
1155         if (hPAD1Driver != NULL) SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL;\r
1156         if (hPAD2Driver != NULL) SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL;\r
1157 \r
1158         if (Config.UseNet && hNETDriver != NULL) {\r
1159                 SysCloseLibrary(hNETDriver); hNETDriver = NULL;\r
1160         }\r
1161 \r
1162 #ifdef ENABLE_SIO1API\r
1163         if (hSIO1Driver != NULL) {\r
1164                 SIO1_shutdown();\r
1165                 SysCloseLibrary(hSIO1Driver);\r
1166                 hSIO1Driver = NULL;\r
1167         }\r
1168 #endif\r
1169 }\r
1170 \r
1171 // for CD swap\r
1172 int ReloadCdromPlugin()\r
1173 {\r
1174         if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();\r
1175         if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;\r
1176 \r
1177         if (UsingIso()) {\r
1178                 LoadCDRplugin(NULL);\r
1179         } else {\r
1180                 char Plugin[MAXPATHLEN];\r
1181                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);\r
1182                 if (LoadCDRplugin(Plugin) == -1) return -1;\r
1183         }\r
1184 \r
1185         return CDR_init();\r
1186 }\r
1187 \r
1188 void SetIsoFile(const char *filename) {\r
1189         if (filename == NULL) {\r
1190                 IsoFile[0] = '\0';\r
1191                 return;\r
1192         }\r
1193         strncpy(IsoFile, filename, MAXPATHLEN);\r
1194 }\r
1195 \r
1196 const char *GetIsoFile(void) {\r
1197         return IsoFile;\r
1198 }\r
1199 \r
1200 boolean UsingIso(void) {\r
1201         return (IsoFile[0] != '\0');\r
1202 }\r
1203 \r
1204 void SetCdOpenCaseTime(s64 time) {\r
1205         cdOpenCaseTime = time;\r
1206 }\r