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