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