Merge pull request #86 from andrewlxer/master
[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;
377 static int ledStateReq44[8];
378 \r
379 static unsigned char buf[256];
380 static unsigned char bufMulti[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};
385                                                                         \r
386 unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
387 unsigned char multitappar[34] = { 0x80, 0x5a, 
388                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
389                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
390                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
391                                                                         0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
392                                                                         \r
393 //response for request 44, 45, 46, 47, 4C, 4D\r
394 static unsigned char resp45[8]    = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};\r
395 static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};\r
396 static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};\r
397 static unsigned char resp47[8]    = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};\r
398 static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};\r
399 static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};\r
400 static unsigned char resp4D[8]    = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};\r
401
402 //fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
403 static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
404 static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
405 static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
406 static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
407 static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
408 static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
409 static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
410 static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
411 static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
412
413 // Resquest of psx core
414 enum {
415         // REQUEST
416         // first call of this request for the pad, the pad is configured as an digital pad.
417         // 0x0X, 0x42, 0x0Y, 0xZZ, 0xAA, 0x00, 0x00, 0x00, 0x00
418         // 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)
419         // Y if 1 : psx request the full length response for the multitap, 3 bytes header and 4 block of 8 bytes per pad
420         // Y if 0 : psx request a pad key state
421         // ZZ rumble small motor 00-> OFF, 01 -> ON
422         // AA rumble large motor speed 0x00 -> 0xFF
423         // RESPONSE
424         // header 3 Bytes
425         // 0x00 
426         // PadId -> 0x41 for digital pas, 0x73 for analog pad 
427         // 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
428         // 6 Bytes for keystates
429         CMD_READ_DATA_AND_VIBRATE = 0x42,
430         
431         // REQUEST
432         // Header
433         // 0x0N, 0x43, 0x00, XX, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
434         // XX = 00 -> Normal mode : Seconde bytes of response = padId
435         // XX = 01 -> Configuration mode : Seconde bytes of response = 0xF3
436         // RESPONSE
437         // enter in config mode example : 
438         // req : 01 43 00 01 00 00 00 00 00 00
439         // res : 00 41 5A buttons state, analog states
440         // exit config mode : 
441         // req : 01 43 00 00 00 00 00 00 00 00
442         // res : 00 F3 5A buttons state, analog states
443         CMD_CONFIG_MODE = 0x43,
444         
445         // Set led State
446         // REQUEST
447         // 0x0N, 0x44, 0x00, VAL, SEL, 0x00, 0x00, 0x00, 0x00
448         // If sel = 2 then
449         // VAL = 00 -> OFF
450         // VAL = 01 -> ON
451         // RESPONSE
452         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
453         CMD_SET_MODE_AND_LOCK = 0x44,
454         
455         // Get Analog Led state
456         // REQUEST
457         // 0x0N, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
458         // RESPONSE
459         // 0x00, 0xF3, 0x5A, 0x01, 0x02, VAL, 0x02, 0x01, 0x00
460         // VAL = 00 Led OFF
461         // VAL = 01 Led ON
462         CMD_QUERY_MODEL_AND_MODE = 0x45,
463         
464         //Get Variable A
465         // REQUEST
466         // 0x0N, 0x46, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
467         // RESPONSE
468         // XX=00
469         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A
470         // XX=01
471         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14
472         CMD_QUERY_ACT = 0x46,
473         
474         // REQUEST
475         // 0x0N, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
476         // RESPONSE
477         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00
478         CMD_QUERY_COMB = 0x47,
479         
480         // REQUEST
481         // 0x0N, 0x4C, 0x00, 0xXX, 0x00, 0x00, 0x00, 0x00, 0x00
482         // RESPONSE
483         // XX = 0
484         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00
485         // XX = 1
486         // 0x00, 0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00
487         CMD_QUERY_MODE = 0x4C,
488         
489         // REQUEST
490         // 0x0N, 0x4D, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
491         // RESPONSE
492         // 0x00, 0xF3, 0x5A, old value or
493         // AA = 01 unlock large motor (and swap VAL1 and VAL2)
494         // BB = 01 unlock large motor (default)
495         // CC, DD, EE, FF = all FF -> unlock small motor
496         //
497         // default repsonse for analog pad with 2 motor : 0x00 0xF3 0x5A 0x00 0x01 0xFF 0xFF 0xFF 0xFF
498         //
499         CMD_VIBRATION_TOGGLE = 0x4D,
500         REQ40 = 0x40,
501         REQ41 = 0x41,
502         REQ49 = 0x49,
503         REQ4A = 0x4A,
504         REQ4B = 0x4B,
505         REQ4E = 0x4E,
506         REQ4F = 0x4F
507 };
508
509
510
511
512 //NO MULTITAP
513
514 void initBufForRequest(int padIndex, char value){
515         switch (value){\r
516                 //Pad keystate already in buffer\r
517                 //case CMD_READ_DATA_AND_VIBRATE :\r
518                 //      break;\r
519                 case CMD_CONFIG_MODE :\r
520                         if (pad[padIndex].configMode == 1) {\r
521                                 memcpy(buf, resp43, 8);\r
522                                 break;\r
523                         }\r
524                         //else, not in config mode, pad keystate return (already in the buffer)\r
525                         break;\r
526                 case CMD_SET_MODE_AND_LOCK :\r
527                         memcpy(buf, resp44, 8);\r
528                         break;\r
529                 case CMD_QUERY_MODEL_AND_MODE :\r
530                         memcpy(buf, resp45, 8);\r
531                         break;\r
532                 case CMD_QUERY_ACT :\r
533                         memcpy(buf, resp46_00, 8);\r
534                         break;\r
535                 case CMD_QUERY_COMB :\r
536                         memcpy(buf, resp47, 8);\r
537                         break;\r
538                 case CMD_QUERY_MODE :\r
539                         memcpy(buf, resp4C_00, 8);\r
540                         break;\r
541                 case CMD_VIBRATION_TOGGLE :\r
542                         memcpy(buf, resp4D, 8);\r
543                         break;\r
544                 case REQ40 :\r
545                         memcpy(buf, resp40, 8);\r
546                         break;\r
547                 case REQ41 :\r
548                         memcpy(buf, resp41, 8);\r
549                         break;\r
550                 case REQ49 :\r
551                         memcpy(buf, resp49, 8);\r
552                         break;\r
553                 case REQ4A :\r
554                         memcpy(buf, resp4A, 8);\r
555                         break;\r
556                 case REQ4B :\r
557                         memcpy(buf, resp4B, 8);\r
558                         break;\r
559                 case REQ4E :\r
560                         memcpy(buf, resp4E, 8);\r
561                         break;\r
562                 case REQ4F :\r
563                         memcpy(buf, resp4F, 8);\r
564                         break;\r
565         }
566 }
567
568
569 \r
570 \r
571 void reqIndex2Treatment(int padIndex, char value){\r
572         switch (req){\r
573                 case CMD_CONFIG_MODE :\r
574                         //0x43\r
575                         if (value == 0) {\r
576                                 pad[padIndex].configMode = 0;\r
577                         } else {\r
578                                 pad[padIndex].configMode = 1;\r
579                         }\r
580                         break;\r
581                 case CMD_SET_MODE_AND_LOCK :\r
582                         //0x44 store the led state for change mode if the next value = 0x02\r
583                         //0x01 analog ON\r
584                         //0x00 analog OFF\r
585                         ledStateReq44[padIndex] = value;\r
586                         break;\r
587                 case CMD_QUERY_ACT :\r
588                         //0x46\r
589                         if (value == 1) {\r
590                                 memcpy(buf, resp46_01, 8);\r
591                         }\r
592                         break;\r
593                 case CMD_QUERY_MODE :\r
594                         if (value == 1) {\r
595                                 memcpy(buf, resp4C_01, 8);\r
596                         }\r
597                         break;\r
598                 case CMD_VIBRATION_TOGGLE :\r
599                         //0x4D\r
600                         memcpy(buf, resp4D, 8);\r
601                         break;\r
602                 case CMD_READ_DATA_AND_VIBRATE:\r
603                         //mem the vibration value for small motor;\r
604                         pad[padIndex].Vib[0] = value;
605                         break;
606         }\r
607 }\r
608         
609 void vibrate(int padIndex){
610         if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
611                 //value is different update Value and call libretro for vibration
612                 pad[padIndex].VibF[0] = pad[padIndex].Vib[0];
613                 pad[padIndex].VibF[1] = pad[padIndex].Vib[1];
614                 plat_trigger_vibrate(padIndex, pad[padIndex].VibF[0], pad[padIndex].VibF[1]);
615                 //printf("vibration pad %i", padIndex);
616         }
617 }
618
619
620
621
622 //Build response for 0x42 request Pad in port\r
623 void _PADstartPoll(PadDataS *pad) {\r
624     switch (pad->controllerType) {\r
625         case PSE_PAD_TYPE_MOUSE:\r
626                         stdpar[0] = 0x12;\r
627             stdpar[2] = pad->buttonStatus & 0xff;\r
628             stdpar[3] = pad->buttonStatus >> 8;\r
629             stdpar[4] = pad->moveX;\r
630             stdpar[5] = pad->moveY;\r
631             memcpy(buf, stdpar, 6);\r
632             respSize = 6;\r
633             break;\r
634         case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)\r
635             stdpar[0] = 0x23;\r
636             stdpar[2] = pad->buttonStatus & 0xff;\r
637             stdpar[3] = pad->buttonStatus >> 8;\r
638             stdpar[4] = pad->rightJoyX;\r
639             stdpar[5] = pad->rightJoyY;\r
640             stdpar[6] = pad->leftJoyX;\r
641             stdpar[7] = pad->leftJoyY;\r
642             memcpy(buf, stdpar, 8);\r
643             respSize = 8;\r
644             break;\r
645         case PSE_PAD_TYPE_ANALOGPAD: // scph1150\r
646             stdpar[0] = 0x73;\r
647             stdpar[2] = pad->buttonStatus & 0xff;\r
648             stdpar[3] = pad->buttonStatus >> 8;\r
649             stdpar[4] = pad->rightJoyX;\r
650             stdpar[5] = pad->rightJoyY;\r
651             stdpar[6] = pad->leftJoyX;\r
652             stdpar[7] = pad->leftJoyY;\r
653             memcpy(buf, stdpar, 8);\r
654             respSize = 8;\r
655             break;\r
656         case PSE_PAD_TYPE_ANALOGJOY: // scph1110\r
657             stdpar[0] = 0x53;\r
658             stdpar[2] = pad->buttonStatus & 0xff;\r
659             stdpar[3] = pad->buttonStatus >> 8;\r
660             stdpar[4] = pad->rightJoyX;\r
661             stdpar[5] = pad->rightJoyY;\r
662             stdpar[6] = pad->leftJoyX;\r
663             stdpar[7] = pad->leftJoyY;\r
664             memcpy(buf, stdpar, 8);\r
665             respSize = 8;\r
666             break;\r
667         case PSE_PAD_TYPE_STANDARD:\r
668         default:
669                 stdpar[0] = 0x41;\r
670             stdpar[2] = pad->buttonStatus & 0xff;\r
671             stdpar[3] = pad->buttonStatus >> 8;
672             //avoid analog value in multitap mode if change pad type in game.
673             stdpar[4] = 0xff;
674             stdpar[5] = 0xff;
675             stdpar[6] = 0xff;
676             stdpar[7] = 0xff;\r
677                 memcpy(buf, stdpar, 8);\r
678                 respSize = 8;\r
679     }\r
680 }\r
681 \r
682
683 //Build response for 0x42 request Multitap in port
684 //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)\r
685 void _PADstartPollMultitap(PadDataS* padd) {\r
686     int i, offset;\r
687     for(i = 0; i < 4; i++) {\r
688         offset = 2 + (i * 8);\r
689         _PADstartPoll(&padd[i]);
690         memcpy(multitappar+offset, stdpar, 8);\r
691     }\r
692     memcpy(bufMulti, multitappar, 34);\r
693     respSize = 34;\r
694 }
695 \r
696 \r
697 unsigned char _PADpoll(int port, unsigned char value) {
698         if (reqPos == 0) {
699                 //mem the request number
700                 req = value;\r
701                 //copy the default value of request response in buffer instead of the keystate\r
702                 initBufForRequest(port, value);
703         }\r
704         \r
705         //if no new request the pad return 0xff, for signaling connected\r
706         if (reqPos >= respSize) return 0xff;\r
707         \r
708         switch(reqPos){\r
709                 case 2:\r
710                         reqIndex2Treatment(port, value);\r
711                 break;\r
712                 case 3:\r
713                         switch(req) {\r
714                                 case CMD_SET_MODE_AND_LOCK :\r
715                                         //change mode on pad\r
716                                 break;\r
717                                 case CMD_READ_DATA_AND_VIBRATE:\r
718                                 //mem the vibration value for Large motor;\r
719                                 pad[port].Vib[1] = value;\r
720                                 //vibration
721                                 vibrate(port);\r
722                                 break;\r
723                         }\r
724                 break;\r
725         }\r
726         return buf[reqPos++];\r
727 }
728
729
730 unsigned char _PADpollMultitap(int port, unsigned char value) {
731         if (reqPos >= respSize) return 0xff;\r
732         return bufMulti[reqPos++];\r
733 }
734 \r
735 \r
736 // refresh the button state on port 1.\r
737 // int pad is not needed.\r
738 unsigned char CALLBACK PAD1__startPoll(int pad) {
739         reqPos = 0;\r
740         // first call the pad provide if a multitap is connected between the psx and himself\r
741         if (multitap1 == -1) {\r
742                 PadDataS padd;
743                 padd.requestPadIndex = 0;\r
744                 PAD1_readPort1(&padd);\r
745                 multitap1 = padd.portMultitap;\r
746         }\r
747         // just one pad is on port 1 : NO MULTITAP\r
748         if (multitap1 == 0) {\r
749                 PadDataS padd;
750                 padd.requestPadIndex = 0;\r
751                 PAD1_readPort1(&padd);\r
752                 _PADstartPoll(&padd);\r
753         } else {\r
754                 // a multitap is plugged : refresh all pad.\r
755                 int i;\r
756                 PadDataS padd[4];\r
757                 for(i = 0; i < 4; i++) {
758                         padd[i].requestPadIndex = i;\r
759                         PAD1_readPort1(&padd[i]);\r
760                 }
761                 _PADstartPollMultitap(padd);\r
762         }
763         //printf("\npad 1 : ");
764         return 0x00;\r
765 }\r
766 \r
767 unsigned char CALLBACK PAD1__poll(unsigned char value) {
768         char tmp;
769         if (multitap1 == 1) {
770                 tmp = _PADpollMultitap(0, value);
771         } else {
772                 tmp = _PADpoll(0, value);
773         }
774         //printf("%2x:%2x, ",value,tmp);\r
775         return tmp;\r
776         \r
777 }\r
778 \r
779 \r
780 long CALLBACK PAD1__configure(void) { return 0; }\r
781 void CALLBACK PAD1__about(void) {}\r
782 long CALLBACK PAD1__test(void) { return 0; }\r
783 long CALLBACK PAD1__query(void) { return 3; }\r
784 long CALLBACK PAD1__keypressed() { return 0; }\r
785 \r
786 #define LoadPad1Sym1(dest, name) \\r
787         LoadSym(PAD1_##dest, PAD##dest, name, TRUE);\r
788 \r
789 #define LoadPad1SymN(dest, name) \\r
790         LoadSym(PAD1_##dest, PAD##dest, name, FALSE);\r
791 \r
792 #define LoadPad1Sym0(dest, name) \\r
793         LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \\r
794         if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;\r
795 \r
796 static int LoadPAD1plugin(const char *PAD1dll) {\r
797         void *drv;\r
798 \r
799         hPAD1Driver = SysLoadLibrary(PAD1dll);\r
800         if (hPAD1Driver == NULL) {\r
801                 PAD1_configure = NULL;\r
802                 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;\r
803         }\r
804         drv = hPAD1Driver;\r
805         LoadPad1Sym1(init, "PADinit");\r
806         LoadPad1Sym1(shutdown, "PADshutdown");\r
807         LoadPad1Sym1(open, "PADopen");\r
808         LoadPad1Sym1(close, "PADclose");\r
809         LoadPad1Sym0(query, "PADquery");\r
810         LoadPad1Sym1(readPort1, "PADreadPort1");\r
811         LoadPad1Sym0(configure, "PADconfigure");\r
812         LoadPad1Sym0(test, "PADtest");\r
813         LoadPad1Sym0(about, "PADabout");\r
814         LoadPad1Sym0(keypressed, "PADkeypressed");\r
815         LoadPad1Sym0(startPoll, "PADstartPoll");\r
816         LoadPad1Sym0(poll, "PADpoll");\r
817         LoadPad1SymN(setSensitive, "PADsetSensitive");\r
818 \r
819         return 0;\r
820 }\r
821 \r
822 unsigned char CALLBACK PAD2__startPoll(int pad) {
823         int pad_index;
824
825         reqPos = 0;\r
826         if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
827                 pad_index = 1;
828         } else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
829                 pad_index = 4;
830         } else {
831                 pad_index = 0;
832         }
833
834         //first call the pad provide if a multitap is connected between the psx and himself
835         if (multitap2 == -1) {
836                 PadDataS padd;
837                 padd.requestPadIndex = pad_index;
838                 PAD2_readPort2(&padd);
839                 multitap2 = padd.portMultitap;
840         }
841         \r
842         // just one pad is on port 1 : NO MULTITAP\r
843         if (multitap2 == 0) {
844                 PadDataS padd;
845                 padd.requestPadIndex = pad_index;
846                 PAD2_readPort2(&padd);\r
847                 _PADstartPoll(&padd);\r
848         } else {\r
849                 // a multitap is plugged : refresh all pad.\r
850                 int i;
851                 PadDataS padd[4];
852                 for(i = 0; i < 4; i++) {
853                         padd[i].requestPadIndex = i+pad_index;
854                         PAD2_readPort2(&padd[i]);
855                 }
856                 _PADstartPollMultitap(padd);\r
857         }
858         //printf("\npad 2 : ");
859         return 0x00;\r
860 }\r
861 \r
862 unsigned char CALLBACK PAD2__poll(unsigned char value) {\r
863         char tmp;
864         if (multitap2 == 2) {
865                 tmp = _PADpollMultitap(1, value);
866         } else {
867                 tmp = _PADpoll(1, value);
868         }
869         //printf("%2x:%2x, ",value,tmp);\r
870         return tmp;\r
871 }\r
872 \r
873 long CALLBACK PAD2__configure(void) { return 0; }\r
874 void CALLBACK PAD2__about(void) {}\r
875 long CALLBACK PAD2__test(void) { return 0; }\r
876 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }\r
877 long CALLBACK PAD2__keypressed() { return 0; }\r
878 \r
879 #define LoadPad2Sym1(dest, name) \\r
880         LoadSym(PAD2_##dest, PAD##dest, name, TRUE);\r
881 \r
882 #define LoadPad2Sym0(dest, name) \\r
883         LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \\r
884         if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;\r
885 \r
886 #define LoadPad2SymN(dest, name) \\r
887         LoadSym(PAD2_##dest, PAD##dest, name, FALSE);\r
888 \r
889 static int LoadPAD2plugin(const char *PAD2dll) {\r
890         void *drv;\r
891 \r
892         hPAD2Driver = SysLoadLibrary(PAD2dll);\r
893         if (hPAD2Driver == NULL) {\r
894                 PAD2_configure = NULL;\r
895                 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;\r
896         }\r
897         drv = hPAD2Driver;\r
898         LoadPad2Sym1(init, "PADinit");\r
899         LoadPad2Sym1(shutdown, "PADshutdown");\r
900         LoadPad2Sym1(open, "PADopen");\r
901         LoadPad2Sym1(close, "PADclose");\r
902         LoadPad2Sym0(query, "PADquery");\r
903         LoadPad2Sym1(readPort2, "PADreadPort2");\r
904         LoadPad2Sym0(configure, "PADconfigure");\r
905         LoadPad2Sym0(test, "PADtest");\r
906         LoadPad2Sym0(about, "PADabout");\r
907         LoadPad2Sym0(keypressed, "PADkeypressed");\r
908         LoadPad2Sym0(startPoll, "PADstartPoll");\r
909         LoadPad2Sym0(poll, "PADpoll");\r
910         LoadPad2SymN(setSensitive, "PADsetSensitive");\r
911 \r
912         return 0;\r
913 }\r
914 \r
915 void *hNETDriver = NULL;\r
916 \r
917 void CALLBACK NET__setInfo(netInfo *info) {}\r
918 void CALLBACK NET__keypressed(int key) {}\r
919 long CALLBACK NET__configure(void) { return 0; }\r
920 long CALLBACK NET__test(void) { return 0; }\r
921 void CALLBACK NET__about(void) {}\r
922 \r
923 #define LoadNetSym1(dest, name) \\r
924         LoadSym(NET_##dest, NET##dest, name, TRUE);\r
925 \r
926 #define LoadNetSymN(dest, name) \\r
927         LoadSym(NET_##dest, NET##dest, name, FALSE);\r
928 \r
929 #define LoadNetSym0(dest, name) \\r
930         LoadSym(NET_##dest, NET##dest, name, FALSE); \\r
931         if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;\r
932 \r
933 static int LoadNETplugin(const char *NETdll) {\r
934         void *drv;\r
935 \r
936         hNETDriver = SysLoadLibrary(NETdll);\r
937         if (hNETDriver == NULL) {\r
938                 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;\r
939         }\r
940         drv = hNETDriver;\r
941         LoadNetSym1(init, "NETinit");\r
942         LoadNetSym1(shutdown, "NETshutdown");\r
943         LoadNetSym1(open, "NETopen");\r
944         LoadNetSym1(close, "NETclose");\r
945         LoadNetSymN(sendData, "NETsendData");\r
946         LoadNetSymN(recvData, "NETrecvData");\r
947         LoadNetSym1(sendPadData, "NETsendPadData");\r
948         LoadNetSym1(recvPadData, "NETrecvPadData");\r
949         LoadNetSym1(queryPlayer, "NETqueryPlayer");\r
950         LoadNetSym1(pause, "NETpause");\r
951         LoadNetSym1(resume, "NETresume");\r
952         LoadNetSym0(setInfo, "NETsetInfo");\r
953         LoadNetSym0(keypressed, "NETkeypressed");\r
954         LoadNetSym0(configure, "NETconfigure");\r
955         LoadNetSym0(test, "NETtest");\r
956         LoadNetSym0(about, "NETabout");\r
957 \r
958         return 0;\r
959 }\r
960 \r
961 #ifdef ENABLE_SIO1API\r
962 \r
963 void *hSIO1Driver = NULL;\r
964 \r
965 long CALLBACK SIO1__init(void) { return 0; }\r
966 long CALLBACK SIO1__shutdown(void) { return 0; }\r
967 long CALLBACK SIO1__open(void) { return 0; }\r
968 long CALLBACK SIO1__close(void) { return 0; }\r
969 long CALLBACK SIO1__configure(void) { return 0; }\r
970 long CALLBACK SIO1__test(void) { return 0; }\r
971 void CALLBACK SIO1__about(void) {}\r
972 void CALLBACK SIO1__pause(void) {}\r
973 void CALLBACK SIO1__resume(void) {}\r
974 long CALLBACK SIO1__keypressed(int key) { return 0; }\r
975 void CALLBACK SIO1__writeData8(unsigned char val) {}\r
976 void CALLBACK SIO1__writeData16(unsigned short val) {}\r
977 void CALLBACK SIO1__writeData32(unsigned long val) {}\r
978 void CALLBACK SIO1__writeStat16(unsigned short val) {}\r
979 void CALLBACK SIO1__writeStat32(unsigned long val) {}\r
980 void CALLBACK SIO1__writeMode16(unsigned short val) {}\r
981 void CALLBACK SIO1__writeMode32(unsigned long val) {}\r
982 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}\r
983 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}\r
984 void CALLBACK SIO1__writeBaud16(unsigned short val) {}\r
985 void CALLBACK SIO1__writeBaud32(unsigned long val) {}\r
986 unsigned char CALLBACK SIO1__readData8(void) { return 0; }\r
987 unsigned short CALLBACK SIO1__readData16(void) { return 0; }\r
988 unsigned long CALLBACK SIO1__readData32(void) { return 0; }\r
989 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }\r
990 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }\r
991 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }\r
992 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }\r
993 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }\r
994 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }\r
995 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }\r
996 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }\r
997 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};\r
998 \r
999 void CALLBACK SIO1irq(void) {\r
1000     psxHu32ref(0x1070) |= SWAPu32(0x100);\r
1001 }\r
1002 \r
1003 #define LoadSio1Sym1(dest, name) \\r
1004     LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);\r
1005 \r
1006 #define LoadSio1SymN(dest, name) \\r
1007     LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);\r
1008 \r
1009 #define LoadSio1Sym0(dest, name) \\r
1010     LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \\r
1011     if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;\r
1012 \r
1013 static int LoadSIO1plugin(const char *SIO1dll) {\r
1014     void *drv;\r
1015 \r
1016     hSIO1Driver = SysLoadLibrary(SIO1dll);\r
1017     if (hSIO1Driver == NULL) {\r
1018         SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;\r
1019     }\r
1020     drv = hSIO1Driver;\r
1021 \r
1022     LoadSio1Sym0(init, "SIO1init");\r
1023     LoadSio1Sym0(shutdown, "SIO1shutdown");\r
1024     LoadSio1Sym0(open, "SIO1open");\r
1025     LoadSio1Sym0(close, "SIO1close");\r
1026     LoadSio1Sym0(pause, "SIO1pause");\r
1027     LoadSio1Sym0(resume, "SIO1resume");\r
1028     LoadSio1Sym0(keypressed, "SIO1keypressed");\r
1029     LoadSio1Sym0(configure, "SIO1configure");\r
1030     LoadSio1Sym0(test, "SIO1test");\r
1031     LoadSio1Sym0(about, "SIO1about");\r
1032     LoadSio1Sym0(writeData8, "SIO1writeData8");\r
1033     LoadSio1Sym0(writeData16, "SIO1writeData16");\r
1034     LoadSio1Sym0(writeData32, "SIO1writeData32");\r
1035     LoadSio1Sym0(writeStat16, "SIO1writeStat16");\r
1036     LoadSio1Sym0(writeStat32, "SIO1writeStat32");\r
1037     LoadSio1Sym0(writeMode16, "SIO1writeMode16");\r
1038     LoadSio1Sym0(writeMode32, "SIO1writeMode32");\r
1039     LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");\r
1040     LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");\r
1041     LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");\r
1042     LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");\r
1043     LoadSio1Sym0(readData16, "SIO1readData16");\r
1044     LoadSio1Sym0(readData32, "SIO1readData32");\r
1045     LoadSio1Sym0(readStat16, "SIO1readStat16");\r
1046     LoadSio1Sym0(readStat32, "SIO1readStat32");\r
1047     LoadSio1Sym0(readMode16, "SIO1readMode16");\r
1048     LoadSio1Sym0(readMode32, "SIO1readMode32");\r
1049     LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");\r
1050     LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");\r
1051     LoadSio1Sym0(readBaud16, "SIO1readBaud16");\r
1052     LoadSio1Sym0(readBaud32, "SIO1readBaud32");\r
1053     LoadSio1Sym0(registerCallback, "SIO1registerCallback");\r
1054 \r
1055     return 0;\r
1056 }\r
1057 \r
1058 #endif\r
1059 \r
1060 void CALLBACK clearDynarec(void) {\r
1061         psxCpu->Reset();\r
1062 }\r
1063 \r
1064 int LoadPlugins() {\r
1065         int ret;\r
1066         char Plugin[MAXPATHLEN];\r
1067 \r
1068         ReleasePlugins();\r
1069         SysLibError();\r
1070 \r
1071         if (UsingIso()) {\r
1072                 LoadCDRplugin(NULL);\r
1073         } else {\r
1074                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);\r
1075                 if (LoadCDRplugin(Plugin) == -1) return -1;\r
1076         }\r
1077 \r
1078         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);\r
1079         if (LoadGPUplugin(Plugin) == -1) return -1;\r
1080 \r
1081         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);\r
1082         if (LoadSPUplugin(Plugin) == -1) return -1;\r
1083 \r
1084         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);\r
1085         if (LoadPAD1plugin(Plugin) == -1) return -1;\r
1086 \r
1087         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);\r
1088         if (LoadPAD2plugin(Plugin) == -1) return -1;\r
1089 \r
1090         if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)\r
1091                 Config.UseNet = FALSE;\r
1092         else {\r
1093                 Config.UseNet = TRUE;\r
1094                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);\r
1095                 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;\r
1096         }\r
1097 \r
1098 #ifdef ENABLE_SIO1API\r
1099         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);\r
1100         if (LoadSIO1plugin(Plugin) == -1) return -1;\r
1101 #endif\r
1102 \r
1103         ret = CDR_init();\r
1104         if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }\r
1105         ret = GPU_init();\r
1106         if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }\r
1107         ret = SPU_init();\r
1108         if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }\r
1109         ret = PAD1_init(1);\r
1110         if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }\r
1111         ret = PAD2_init(2);\r
1112         if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }\r
1113 \r
1114         if (Config.UseNet) {\r
1115                 ret = NET_init();\r
1116                 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }\r
1117         }\r
1118 \r
1119 #ifdef ENABLE_SIO1API\r
1120         ret = SIO1_init();\r
1121         if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }\r
1122 #endif\r
1123 \r
1124         SysPrintf(_("Plugins loaded.\n"));\r
1125         return 0;\r
1126 }\r
1127 \r
1128 void ReleasePlugins() {\r
1129         if (Config.UseNet) {\r
1130                 int ret = NET_close();\r
1131                 if (ret < 0) Config.UseNet = FALSE;\r
1132         }\r
1133         NetOpened = FALSE;\r
1134 \r
1135         if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();\r
1136         if (hGPUDriver != NULL) GPU_shutdown();\r
1137         if (hSPUDriver != NULL) SPU_shutdown();\r
1138         if (hPAD1Driver != NULL) PAD1_shutdown();\r
1139         if (hPAD2Driver != NULL) PAD2_shutdown();\r
1140 \r
1141         if (Config.UseNet && hNETDriver != NULL) NET_shutdown(); \r
1142 \r
1143         if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;\r
1144         if (hGPUDriver != NULL) SysCloseLibrary(hGPUDriver); hGPUDriver = NULL;\r
1145         if (hSPUDriver != NULL) SysCloseLibrary(hSPUDriver); hSPUDriver = NULL;\r
1146         if (hPAD1Driver != NULL) SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL;\r
1147         if (hPAD2Driver != NULL) SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL;\r
1148 \r
1149         if (Config.UseNet && hNETDriver != NULL) {\r
1150                 SysCloseLibrary(hNETDriver); hNETDriver = NULL;\r
1151         }\r
1152 \r
1153 #ifdef ENABLE_SIO1API\r
1154         if (hSIO1Driver != NULL) {\r
1155                 SIO1_shutdown();\r
1156                 SysCloseLibrary(hSIO1Driver);\r
1157                 hSIO1Driver = NULL;\r
1158         }\r
1159 #endif\r
1160 }\r
1161 \r
1162 // for CD swap\r
1163 int ReloadCdromPlugin()\r
1164 {\r
1165         if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();\r
1166         if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;\r
1167 \r
1168         if (UsingIso()) {\r
1169                 LoadCDRplugin(NULL);\r
1170         } else {\r
1171                 char Plugin[MAXPATHLEN];\r
1172                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);\r
1173                 if (LoadCDRplugin(Plugin) == -1) return -1;\r
1174         }\r
1175 \r
1176         return CDR_init();\r
1177 }\r
1178 \r
1179 void SetIsoFile(const char *filename) {\r
1180         if (filename == NULL) {\r
1181                 IsoFile[0] = '\0';\r
1182                 return;\r
1183         }\r
1184         strncpy(IsoFile, filename, MAXPATHLEN);\r
1185 }\r
1186 \r
1187 const char *GetIsoFile(void) {\r
1188         return IsoFile;\r
1189 }\r
1190 \r
1191 boolean UsingIso(void) {\r
1192         return (IsoFile[0] != '\0');\r
1193 }\r
1194 \r
1195 void SetCdOpenCaseTime(s64 time) {\r
1196         cdOpenCaseTime = time;\r
1197 }\r