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