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