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