Merge pull request #51 from alexis-puska/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                 \r
594                 case CMD_QUERY_MODE :\r
595                         if(value==1){\r
596                                 memcpy(buf, resp4C_01, 8);\r
597                         }\r
598                         break;\r
599                 case CMD_VIBRATION_TOGGLE :\r
600                         //0x4D\r
601                         memcpy(buf, resp4D, 8);\r
602                         break;\r
603                 case CMD_READ_DATA_AND_VIBRATE:\r
604                         //mem the vibration value for small motor;\r
605                         pad[padIndex].Vib[0] = value;
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[4]) {\r
686     int i = 0;\r
687     int offset = 2;\r
688     PadDataS pad;\r
689     for(i = 0; i < 4; i++) {\r
690         offset = 2 + (i * 8);\r
691         pad = padd[i];\r
692                 _PADstartPoll(&pad);
693                 memcpy(multitappar+offset, stdpar, 8);\r
694     }\r
695     memcpy(bufMulti, multitappar, 34);\r
696     respSize = 34;\r
697 }
698 \r
699 \r
700 unsigned char _PADpoll(int port, unsigned char value) {
701         if(reqPos==0){
702                 //mem the request number
703                 req = value;\r
704                 //copy the default value of request response in buffer instead of the keystate\r
705                 initBufForRequest(port,value);
706         }\r
707         \r
708         //if no new request the pad return 0xff, for signaling connected\r
709         if ( reqPos >= respSize) return 0xff;\r
710         \r
711         switch(reqPos){\r
712                 case 2:\r
713                         reqIndex2Treatment(port, value);\r
714                 break;\r
715                 case 3:\r
716                         switch(req) {\r
717                                 case CMD_SET_MODE_AND_LOCK :\r
718                                         //change mode on pad\r
719                                 break;\r
720                                 case CMD_READ_DATA_AND_VIBRATE:\r
721                                 //mem the vibration value for Large motor;\r
722                                 pad[port].Vib[1] = value;\r
723                                 //vibration
724                                 vibrate(port);\r
725                                 break;\r
726                         \r
727                 break;\r
728                 }\r
729         }\r
730         return buf[reqPos++];\r
731 }
732
733
734 unsigned char _PADpollMultitap(int port, unsigned char value) {
735         if ( reqPos >= respSize) return 0xff;\r
736         return bufMulti[reqPos++];\r
737 }
738 \r
739 \r
740 // refresh the button state on port 1.\r
741 // int pad is not needed.\r
742 unsigned char CALLBACK PAD1__startPoll(int pad) {
743         reqPos = 0;\r
744         // first call the pad provide if a multitap is connected between the psx and himself\r
745         if(multitap1 == -1){\r
746                 PadDataS padd;
747                 padd.requestPadIndex = 0;\r
748                 PAD1_readPort1(&padd);\r
749                 multitap1 = padd.portMultitap;\r
750         }\r
751         // just one pad is on port 1 : NO MULTITAP\r
752         if (multitap1 == 0){\r
753                 PadDataS padd;
754                 padd.requestPadIndex = 0;\r
755                 PAD1_readPort1(&padd);\r
756                 _PADstartPoll(&padd);\r
757         } else {\r
758                 // a multitap is plugged : refresh all pad.\r
759                 int i=0;\r
760                 PadDataS padd[4];\r
761                 for(i = 0; i < 4; i++) {
762                         padd[i].requestPadIndex = i;\r
763                         PAD1_readPort1(&padd[i]);\r
764                 }
765                 _PADstartPollMultitap(padd);\r
766         }
767         //printf("\npad 1 : ");
768         return 0x00;\r
769 }\r
770 \r
771 unsigned char CALLBACK PAD1__poll(unsigned char value) {
772         char tmp;
773         if(multitap1 == 1){
774                 tmp = _PADpollMultitap(0, value);
775         }else{
776                 tmp = _PADpoll(0, value);
777         }
778         //printf("%2x:%2x, ",value,tmp);\r
779         return tmp;\r
780         \r
781 }\r
782 \r
783 \r
784 long CALLBACK PAD1__configure(void) { return 0; }\r
785 void CALLBACK PAD1__about(void) {}\r
786 long CALLBACK PAD1__test(void) { return 0; }\r
787 long CALLBACK PAD1__query(void) { return 3; }\r
788 long CALLBACK PAD1__keypressed() { return 0; }\r
789 \r
790 #define LoadPad1Sym1(dest, name) \\r
791         LoadSym(PAD1_##dest, PAD##dest, name, TRUE);\r
792 \r
793 #define LoadPad1SymN(dest, name) \\r
794         LoadSym(PAD1_##dest, PAD##dest, name, FALSE);\r
795 \r
796 #define LoadPad1Sym0(dest, name) \\r
797         LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \\r
798         if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;\r
799 \r
800 static int LoadPAD1plugin(const char *PAD1dll) {\r
801         void *drv;\r
802 \r
803         hPAD1Driver = SysLoadLibrary(PAD1dll);\r
804         if (hPAD1Driver == NULL) {\r
805                 PAD1_configure = NULL;\r
806                 SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;\r
807         }\r
808         drv = hPAD1Driver;\r
809         LoadPad1Sym1(init, "PADinit");\r
810         LoadPad1Sym1(shutdown, "PADshutdown");\r
811         LoadPad1Sym1(open, "PADopen");\r
812         LoadPad1Sym1(close, "PADclose");\r
813         LoadPad1Sym0(query, "PADquery");\r
814         LoadPad1Sym1(readPort1, "PADreadPort1");\r
815         LoadPad1Sym0(configure, "PADconfigure");\r
816         LoadPad1Sym0(test, "PADtest");\r
817         LoadPad1Sym0(about, "PADabout");\r
818         LoadPad1Sym0(keypressed, "PADkeypressed");\r
819         LoadPad1Sym0(startPoll, "PADstartPoll");\r
820         LoadPad1Sym0(poll, "PADpoll");\r
821         LoadPad1SymN(setSensitive, "PADsetSensitive");\r
822 \r
823         return 0;\r
824 }\r
825 \r
826 unsigned char CALLBACK PAD2__startPoll(int pad) {
827         reqPos = 0;\r
828         int pad_index = 0;
829         if(multitap1 == 0 && multitap2 == 0){
830                 pad_index += 1;
831         }else if(multitap1 == 1 && multitap2 == 0){
832                 pad_index += 4;
833         }else if(multitap1 == 0 && multitap2 == 2){
834                 pad_index += 1;
835         }else if(multitap1 == 1 && multitap2 == 2){
836                 pad_index += 4;
837         }
838
839         //first call the pad provide if a multitap is connected between the psx and himself
840         if(multitap2 == -1){
841                 PadDataS padd;
842                 padd.requestPadIndex = pad_index;
843                 PAD2_readPort2(&padd);
844                 multitap2 = padd.portMultitap;
845         }
846         \r
847         // just one pad is on port 1 : NO MULTITAP\r
848         if (multitap2 == 0){
849                 PadDataS padd;
850                 padd.requestPadIndex = pad_index;
851                 PAD2_readPort2(&padd);\r
852                 _PADstartPoll(&padd);\r
853         } else {\r
854                 // a multitap is plugged : refresh all pad.\r
855         //a multitap is plugged : refresh all pad.
856                 int i=0;
857                 PadDataS padd[4];
858                 for(i=0;i<4;i++){
859                         padd[i].requestPadIndex = i+pad_index;
860                         PAD2_readPort2(&padd[i]);
861                 }
862                 _PADstartPollMultitap(padd);\r
863         }
864         //printf("\npad 2 : ");
865         return 0x00;\r
866 }\r
867 \r
868 unsigned char CALLBACK PAD2__poll(unsigned char value) {\r
869         char tmp;
870         if(multitap2 == 2){
871                 tmp = _PADpollMultitap(1, value);
872         }else{
873                 tmp = _PADpoll(1, value);
874         }
875         //printf("%2x:%2x, ",value,tmp);\r
876         return tmp;\r
877 }\r
878 \r
879 long CALLBACK PAD2__configure(void) { return 0; }\r
880 void CALLBACK PAD2__about(void) {}\r
881 long CALLBACK PAD2__test(void) { return 0; }\r
882 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }\r
883 long CALLBACK PAD2__keypressed() { return 0; }\r
884 \r
885 #define LoadPad2Sym1(dest, name) \\r
886         LoadSym(PAD2_##dest, PAD##dest, name, TRUE);\r
887 \r
888 #define LoadPad2Sym0(dest, name) \\r
889         LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \\r
890         if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;\r
891 \r
892 #define LoadPad2SymN(dest, name) \\r
893         LoadSym(PAD2_##dest, PAD##dest, name, FALSE);\r
894 \r
895 static int LoadPAD2plugin(const char *PAD2dll) {\r
896         void *drv;\r
897 \r
898         hPAD2Driver = SysLoadLibrary(PAD2dll);\r
899         if (hPAD2Driver == NULL) {\r
900                 PAD2_configure = NULL;\r
901                 SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;\r
902         }\r
903         drv = hPAD2Driver;\r
904         LoadPad2Sym1(init, "PADinit");\r
905         LoadPad2Sym1(shutdown, "PADshutdown");\r
906         LoadPad2Sym1(open, "PADopen");\r
907         LoadPad2Sym1(close, "PADclose");\r
908         LoadPad2Sym0(query, "PADquery");\r
909         LoadPad2Sym1(readPort2, "PADreadPort2");\r
910         LoadPad2Sym0(configure, "PADconfigure");\r
911         LoadPad2Sym0(test, "PADtest");\r
912         LoadPad2Sym0(about, "PADabout");\r
913         LoadPad2Sym0(keypressed, "PADkeypressed");\r
914         LoadPad2Sym0(startPoll, "PADstartPoll");\r
915         LoadPad2Sym0(poll, "PADpoll");\r
916         LoadPad2SymN(setSensitive, "PADsetSensitive");\r
917 \r
918         return 0;\r
919 }\r
920 \r
921 void *hNETDriver = NULL;\r
922 \r
923 void CALLBACK NET__setInfo(netInfo *info) {}\r
924 void CALLBACK NET__keypressed(int key) {}\r
925 long CALLBACK NET__configure(void) { return 0; }\r
926 long CALLBACK NET__test(void) { return 0; }\r
927 void CALLBACK NET__about(void) {}\r
928 \r
929 #define LoadNetSym1(dest, name) \\r
930         LoadSym(NET_##dest, NET##dest, name, TRUE);\r
931 \r
932 #define LoadNetSymN(dest, name) \\r
933         LoadSym(NET_##dest, NET##dest, name, FALSE);\r
934 \r
935 #define LoadNetSym0(dest, name) \\r
936         LoadSym(NET_##dest, NET##dest, name, FALSE); \\r
937         if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;\r
938 \r
939 static int LoadNETplugin(const char *NETdll) {\r
940         void *drv;\r
941 \r
942         hNETDriver = SysLoadLibrary(NETdll);\r
943         if (hNETDriver == NULL) {\r
944                 SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;\r
945         }\r
946         drv = hNETDriver;\r
947         LoadNetSym1(init, "NETinit");\r
948         LoadNetSym1(shutdown, "NETshutdown");\r
949         LoadNetSym1(open, "NETopen");\r
950         LoadNetSym1(close, "NETclose");\r
951         LoadNetSymN(sendData, "NETsendData");\r
952         LoadNetSymN(recvData, "NETrecvData");\r
953         LoadNetSym1(sendPadData, "NETsendPadData");\r
954         LoadNetSym1(recvPadData, "NETrecvPadData");\r
955         LoadNetSym1(queryPlayer, "NETqueryPlayer");\r
956         LoadNetSym1(pause, "NETpause");\r
957         LoadNetSym1(resume, "NETresume");\r
958         LoadNetSym0(setInfo, "NETsetInfo");\r
959         LoadNetSym0(keypressed, "NETkeypressed");\r
960         LoadNetSym0(configure, "NETconfigure");\r
961         LoadNetSym0(test, "NETtest");\r
962         LoadNetSym0(about, "NETabout");\r
963 \r
964         return 0;\r
965 }\r
966 \r
967 #ifdef ENABLE_SIO1API\r
968 \r
969 void *hSIO1Driver = NULL;\r
970 \r
971 long CALLBACK SIO1__init(void) { return 0; }\r
972 long CALLBACK SIO1__shutdown(void) { return 0; }\r
973 long CALLBACK SIO1__open(void) { return 0; }\r
974 long CALLBACK SIO1__close(void) { return 0; }\r
975 long CALLBACK SIO1__configure(void) { return 0; }\r
976 long CALLBACK SIO1__test(void) { return 0; }\r
977 void CALLBACK SIO1__about(void) {}\r
978 void CALLBACK SIO1__pause(void) {}\r
979 void CALLBACK SIO1__resume(void) {}\r
980 long CALLBACK SIO1__keypressed(int key) { return 0; }\r
981 void CALLBACK SIO1__writeData8(unsigned char val) {}\r
982 void CALLBACK SIO1__writeData16(unsigned short val) {}\r
983 void CALLBACK SIO1__writeData32(unsigned long val) {}\r
984 void CALLBACK SIO1__writeStat16(unsigned short val) {}\r
985 void CALLBACK SIO1__writeStat32(unsigned long val) {}\r
986 void CALLBACK SIO1__writeMode16(unsigned short val) {}\r
987 void CALLBACK SIO1__writeMode32(unsigned long val) {}\r
988 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}\r
989 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}\r
990 void CALLBACK SIO1__writeBaud16(unsigned short val) {}\r
991 void CALLBACK SIO1__writeBaud32(unsigned long val) {}\r
992 unsigned char CALLBACK SIO1__readData8(void) { return 0; }\r
993 unsigned short CALLBACK SIO1__readData16(void) { return 0; }\r
994 unsigned long CALLBACK SIO1__readData32(void) { return 0; }\r
995 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }\r
996 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }\r
997 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }\r
998 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }\r
999 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }\r
1000 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }\r
1001 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }\r
1002 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }\r
1003 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};\r
1004 \r
1005 void CALLBACK SIO1irq(void) {\r
1006     psxHu32ref(0x1070) |= SWAPu32(0x100);\r
1007 }\r
1008 \r
1009 #define LoadSio1Sym1(dest, name) \\r
1010     LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);\r
1011 \r
1012 #define LoadSio1SymN(dest, name) \\r
1013     LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);\r
1014 \r
1015 #define LoadSio1Sym0(dest, name) \\r
1016     LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \\r
1017     if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;\r
1018 \r
1019 static int LoadSIO1plugin(const char *SIO1dll) {\r
1020     void *drv;\r
1021 \r
1022     hSIO1Driver = SysLoadLibrary(SIO1dll);\r
1023     if (hSIO1Driver == NULL) {\r
1024         SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;\r
1025     }\r
1026     drv = hSIO1Driver;\r
1027 \r
1028     LoadSio1Sym0(init, "SIO1init");\r
1029     LoadSio1Sym0(shutdown, "SIO1shutdown");\r
1030     LoadSio1Sym0(open, "SIO1open");\r
1031     LoadSio1Sym0(close, "SIO1close");\r
1032     LoadSio1Sym0(pause, "SIO1pause");\r
1033     LoadSio1Sym0(resume, "SIO1resume");\r
1034     LoadSio1Sym0(keypressed, "SIO1keypressed");\r
1035     LoadSio1Sym0(configure, "SIO1configure");\r
1036     LoadSio1Sym0(test, "SIO1test");\r
1037     LoadSio1Sym0(about, "SIO1about");\r
1038     LoadSio1Sym0(writeData8, "SIO1writeData8");\r
1039     LoadSio1Sym0(writeData16, "SIO1writeData16");\r
1040     LoadSio1Sym0(writeData32, "SIO1writeData32");\r
1041     LoadSio1Sym0(writeStat16, "SIO1writeStat16");\r
1042     LoadSio1Sym0(writeStat32, "SIO1writeStat32");\r
1043     LoadSio1Sym0(writeMode16, "SIO1writeMode16");\r
1044     LoadSio1Sym0(writeMode32, "SIO1writeMode32");\r
1045     LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");\r
1046     LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");\r
1047     LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");\r
1048     LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");\r
1049     LoadSio1Sym0(readData16, "SIO1readData16");\r
1050     LoadSio1Sym0(readData32, "SIO1readData32");\r
1051     LoadSio1Sym0(readStat16, "SIO1readStat16");\r
1052     LoadSio1Sym0(readStat32, "SIO1readStat32");\r
1053     LoadSio1Sym0(readMode16, "SIO1readMode16");\r
1054     LoadSio1Sym0(readMode32, "SIO1readMode32");\r
1055     LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");\r
1056     LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");\r
1057     LoadSio1Sym0(readBaud16, "SIO1readBaud16");\r
1058     LoadSio1Sym0(readBaud32, "SIO1readBaud32");\r
1059     LoadSio1Sym0(registerCallback, "SIO1registerCallback");\r
1060 \r
1061     return 0;\r
1062 }\r
1063 \r
1064 #endif\r
1065 \r
1066 void CALLBACK clearDynarec(void) {\r
1067         psxCpu->Reset();\r
1068 }\r
1069 \r
1070 int LoadPlugins() {\r
1071         int ret;\r
1072         char Plugin[MAXPATHLEN];\r
1073 \r
1074         ReleasePlugins();\r
1075         SysLibError();\r
1076 \r
1077         if (UsingIso()) {\r
1078                 LoadCDRplugin(NULL);\r
1079         } else {\r
1080                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);\r
1081                 if (LoadCDRplugin(Plugin) == -1) return -1;\r
1082         }\r
1083 \r
1084         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);\r
1085         if (LoadGPUplugin(Plugin) == -1) return -1;\r
1086 \r
1087         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);\r
1088         if (LoadSPUplugin(Plugin) == -1) return -1;\r
1089 \r
1090         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);\r
1091         if (LoadPAD1plugin(Plugin) == -1) return -1;\r
1092 \r
1093         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);\r
1094         if (LoadPAD2plugin(Plugin) == -1) return -1;\r
1095 \r
1096         if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)\r
1097                 Config.UseNet = FALSE;\r
1098         else {\r
1099                 Config.UseNet = TRUE;\r
1100                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);\r
1101                 if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;\r
1102         }\r
1103 \r
1104 #ifdef ENABLE_SIO1API\r
1105         sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);\r
1106         if (LoadSIO1plugin(Plugin) == -1) return -1;\r
1107 #endif\r
1108 \r
1109         ret = CDR_init();\r
1110         if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }\r
1111         ret = GPU_init();\r
1112         if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }\r
1113         ret = SPU_init();\r
1114         if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }\r
1115         ret = PAD1_init(1);\r
1116         if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }\r
1117         ret = PAD2_init(2);\r
1118         if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }\r
1119 \r
1120         if (Config.UseNet) {\r
1121                 ret = NET_init();\r
1122                 if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }\r
1123         }\r
1124 \r
1125 #ifdef ENABLE_SIO1API\r
1126         ret = SIO1_init();\r
1127         if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }\r
1128 #endif\r
1129 \r
1130         SysPrintf(_("Plugins loaded.\n"));\r
1131         return 0;\r
1132 }\r
1133 \r
1134 void ReleasePlugins() {\r
1135         if (Config.UseNet) {\r
1136                 int ret = NET_close();\r
1137                 if (ret < 0) Config.UseNet = FALSE;\r
1138         }\r
1139         NetOpened = FALSE;\r
1140 \r
1141         if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();\r
1142         if (hGPUDriver != NULL) GPU_shutdown();\r
1143         if (hSPUDriver != NULL) SPU_shutdown();\r
1144         if (hPAD1Driver != NULL) PAD1_shutdown();\r
1145         if (hPAD2Driver != NULL) PAD2_shutdown();\r
1146 \r
1147         if (Config.UseNet && hNETDriver != NULL) NET_shutdown(); \r
1148 \r
1149         if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;\r
1150         if (hGPUDriver != NULL) SysCloseLibrary(hGPUDriver); hGPUDriver = NULL;\r
1151         if (hSPUDriver != NULL) SysCloseLibrary(hSPUDriver); hSPUDriver = NULL;\r
1152         if (hPAD1Driver != NULL) SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL;\r
1153         if (hPAD2Driver != NULL) SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL;\r
1154 \r
1155         if (Config.UseNet && hNETDriver != NULL) {\r
1156                 SysCloseLibrary(hNETDriver); hNETDriver = NULL;\r
1157         }\r
1158 \r
1159 #ifdef ENABLE_SIO1API\r
1160         if (hSIO1Driver != NULL) {\r
1161                 SIO1_shutdown();\r
1162                 SysCloseLibrary(hSIO1Driver);\r
1163                 hSIO1Driver = NULL;\r
1164         }\r
1165 #endif\r
1166 }\r
1167 \r
1168 // for CD swap\r
1169 int ReloadCdromPlugin()\r
1170 {\r
1171         if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();\r
1172         if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL;\r
1173 \r
1174         if (UsingIso()) {\r
1175                 LoadCDRplugin(NULL);\r
1176         } else {\r
1177                 char Plugin[MAXPATHLEN];\r
1178                 sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);\r
1179                 if (LoadCDRplugin(Plugin) == -1) return -1;\r
1180         }\r
1181 \r
1182         return CDR_init();\r
1183 }\r
1184 \r
1185 void SetIsoFile(const char *filename) {\r
1186         if (filename == NULL) {\r
1187                 IsoFile[0] = '\0';\r
1188                 return;\r
1189         }\r
1190         strncpy(IsoFile, filename, MAXPATHLEN);\r
1191 }\r
1192 \r
1193 const char *GetIsoFile(void) {\r
1194         return IsoFile;\r
1195 }\r
1196 \r
1197 boolean UsingIso(void) {\r
1198         return (IsoFile[0] != '\0');\r
1199 }\r
1200 \r
1201 void SetCdOpenCaseTime(s64 time) {\r
1202         cdOpenCaseTime = time;\r
1203 }\r