1 /***************************************************************************
2  *   Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team              *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *
18  ***************************************************************************/
19 
20 /*
21 * Plugin library callback/access functions.
22 */
23 
24 #include "plugins.h"
25 #include "cdriso.h"
26 #include "../plugins/dfinput/externals.h"
27 
28 static char IsoFile[MAXPATHLEN] = "";
29 static s64 cdOpenCaseTime = 0;
30 
31 GPUupdateLace         GPU_updateLace;
32 GPUinit               GPU_init;
33 GPUshutdown           GPU_shutdown;
34 GPUconfigure          GPU_configure;
35 GPUtest               GPU_test;
36 GPUabout              GPU_about;
37 GPUopen               GPU_open;
38 GPUclose              GPU_close;
39 GPUreadStatus         GPU_readStatus;
40 GPUreadData           GPU_readData;
41 GPUreadDataMem        GPU_readDataMem;
42 GPUwriteStatus        GPU_writeStatus;
43 GPUwriteData          GPU_writeData;
44 GPUwriteDataMem       GPU_writeDataMem;
45 GPUdmaChain           GPU_dmaChain;
46 GPUkeypressed         GPU_keypressed;
47 GPUdisplayText        GPU_displayText;
48 GPUmakeSnapshot       GPU_makeSnapshot;
49 GPUfreeze             GPU_freeze;
50 GPUgetScreenPic       GPU_getScreenPic;
51 GPUshowScreenPic      GPU_showScreenPic;
52 GPUclearDynarec       GPU_clearDynarec;
53 GPUvBlank             GPU_vBlank;
54 
55 CDRinit               CDR_init;
56 CDRshutdown           CDR_shutdown;
57 CDRopen               CDR_open;
58 CDRclose              CDR_close;
59 CDRtest               CDR_test;
60 CDRgetTN              CDR_getTN;
61 CDRgetTD              CDR_getTD;
62 CDRreadTrack          CDR_readTrack;
63 CDRgetBuffer          CDR_getBuffer;
64 CDRplay               CDR_play;
65 CDRstop               CDR_stop;
66 CDRgetStatus          CDR_getStatus;
67 CDRgetDriveLetter     CDR_getDriveLetter;
68 CDRgetBufferSub       CDR_getBufferSub;
69 CDRconfigure          CDR_configure;
70 CDRabout              CDR_about;
71 CDRsetfilename        CDR_setfilename;
72 CDRreadCDDA           CDR_readCDDA;
73 CDRgetTE              CDR_getTE;
74 
75 SPUconfigure          SPU_configure;
76 SPUabout              SPU_about;
77 SPUinit               SPU_init;
78 SPUshutdown           SPU_shutdown;
79 SPUtest               SPU_test;
80 SPUopen               SPU_open;
81 SPUclose              SPU_close;
82 SPUplaySample         SPU_playSample;
83 SPUwriteRegister      SPU_writeRegister;
84 SPUreadRegister       SPU_readRegister;
85 SPUwriteDMA           SPU_writeDMA;
86 SPUreadDMA            SPU_readDMA;
87 SPUwriteDMAMem        SPU_writeDMAMem;
88 SPUreadDMAMem         SPU_readDMAMem;
89 SPUplayADPCMchannel   SPU_playADPCMchannel;
90 SPUfreeze             SPU_freeze;
91 SPUregisterCallback   SPU_registerCallback;
92 SPUregisterScheduleCb SPU_registerScheduleCb;
93 SPUasync              SPU_async;
94 SPUplayCDDAchannel    SPU_playCDDAchannel;
95 
96 PADconfigure          PAD1_configure;
97 PADabout              PAD1_about;
98 PADinit               PAD1_init;
99 PADshutdown           PAD1_shutdown;
100 PADtest               PAD1_test;
101 PADopen               PAD1_open;
102 PADclose              PAD1_close;
103 PADquery              PAD1_query;
104 PADreadPort1          PAD1_readPort1;
105 PADkeypressed         PAD1_keypressed;
106 PADstartPoll          PAD1_startPoll;
107 PADpoll               PAD1_poll;
108 PADsetSensitive       PAD1_setSensitive;
109 
110 PADconfigure          PAD2_configure;
111 PADabout              PAD2_about;
112 PADinit               PAD2_init;
113 PADshutdown           PAD2_shutdown;
114 PADtest               PAD2_test;
115 PADopen               PAD2_open;
116 PADclose              PAD2_close;
117 PADquery              PAD2_query;
118 PADreadPort2          PAD2_readPort2;
119 PADkeypressed         PAD2_keypressed;
120 PADstartPoll          PAD2_startPoll;
121 PADpoll               PAD2_poll;
122 PADsetSensitive       PAD2_setSensitive;
123 
124 NETinit               NET_init;
125 NETshutdown           NET_shutdown;
126 NETopen               NET_open;
127 NETclose              NET_close;
128 NETtest               NET_test;
129 NETconfigure          NET_configure;
130 NETabout              NET_about;
131 NETpause              NET_pause;
132 NETresume             NET_resume;
133 NETqueryPlayer        NET_queryPlayer;
134 NETsendData           NET_sendData;
135 NETrecvData           NET_recvData;
136 NETsendPadData        NET_sendPadData;
137 NETrecvPadData        NET_recvPadData;
138 NETsetInfo            NET_setInfo;
139 NETkeypressed         NET_keypressed;
140 
141 #ifdef ENABLE_SIO1API
142 
143 SIO1init              SIO1_init;
144 SIO1shutdown          SIO1_shutdown;
145 SIO1open              SIO1_open;
146 SIO1close             SIO1_close;
147 SIO1test              SIO1_test;
148 SIO1configure         SIO1_configure;
149 SIO1about             SIO1_about;
150 SIO1pause             SIO1_pause;
151 SIO1resume            SIO1_resume;
152 SIO1keypressed        SIO1_keypressed;
153 SIO1writeData8        SIO1_writeData8;
154 SIO1writeData16       SIO1_writeData16;
155 SIO1writeData32       SIO1_writeData32;
156 SIO1writeStat16       SIO1_writeStat16;
157 SIO1writeStat32       SIO1_writeStat32;
158 SIO1writeMode16       SIO1_writeMode16;
159 SIO1writeMode32       SIO1_writeMode32;
160 SIO1writeCtrl16       SIO1_writeCtrl16;
161 SIO1writeCtrl32       SIO1_writeCtrl32;
162 SIO1writeBaud16       SIO1_writeBaud16;
163 SIO1writeBaud32       SIO1_writeBaud32;
164 SIO1readData8         SIO1_readData8;
165 SIO1readData16        SIO1_readData16;
166 SIO1readData32        SIO1_readData32;
167 SIO1readStat16        SIO1_readStat16;
168 SIO1readStat32        SIO1_readStat32;
169 SIO1readMode16        SIO1_readMode16;
170 SIO1readMode32        SIO1_readMode32;
171 SIO1readCtrl16        SIO1_readCtrl16;
172 SIO1readCtrl32        SIO1_readCtrl32;
173 SIO1readBaud16        SIO1_readBaud16;
174 SIO1readBaud32        SIO1_readBaud32;
175 SIO1registerCallback  SIO1_registerCallback;
176 
177 #endif
178 
179 static 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 
191 void *hGPUDriver = NULL;
192 
GPU__displayText(char * pText)193 void CALLBACK GPU__displayText(char *pText) {
194 	SysPrintf("%s\n", pText);
195 }
196 
GPU__configure(void)197 long CALLBACK GPU__configure(void) { return 0; }
GPU__test(void)198 long CALLBACK GPU__test(void) { return 0; }
GPU__about(void)199 void CALLBACK GPU__about(void) {}
GPU__makeSnapshot(void)200 void CALLBACK GPU__makeSnapshot(void) {}
GPU__keypressed(int key)201 void CALLBACK GPU__keypressed(int key) {}
GPU__getScreenPic(unsigned char * pMem)202 long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
GPU__showScreenPic(unsigned char * pMem)203 long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
GPU__clearDynarec(void (CALLBACK * callback)(void))204 void CALLBACK GPU__clearDynarec(void (CALLBACK *callback)(void)) {}
GPU__vBlank(int val)205 void 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 
LoadGPUplugin(const char * GPUdll)217 static int LoadGPUplugin(const char *GPUdll) {
218 	void *drv;
219 
220 	hGPUDriver = SysLoadLibrary(GPUdll);
221 	if (hGPUDriver == NULL) {
222 		GPU_configure = NULL;
223 		SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
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 
253 void *hCDRDriver = NULL;
254 
CDR__play(unsigned char * sector)255 long CALLBACK CDR__play(unsigned char *sector) { return 0; }
CDR__stop(void)256 long CALLBACK CDR__stop(void) { return 0; }
257 
CDR__getStatus(struct CdrStat * stat)258 long 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 
CDR__getDriveLetter(void)267 char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
CDR__configure(void)268 long CALLBACK CDR__configure(void) { return 0; }
CDR__test(void)269 long CALLBACK CDR__test(void) { return 0; }
CDR__about(void)270 void CALLBACK CDR__about(void) {}
CDR__setfilename(char * filename)271 long 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 
LoadCDRplugin(const char * CDRdll)283 static 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 
320 void *hSPUDriver = NULL;
321 
SPU__configure(void)322 long CALLBACK SPU__configure(void) { return 0; }
SPU__about(void)323 void CALLBACK SPU__about(void) {}
SPU__test(void)324 long CALLBACK SPU__test(void) { return 0; }
SPU__registerScheduleCb(void (CALLBACK * cb)(unsigned int))325 void 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 
LoadSPUplugin(const char * SPUdll)337 static 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");
354 	LoadSpuSym1(readRegister, "SPUreadRegister");
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 
369 extern int in_type[8];
370 
371 void *hPAD1Driver = NULL;
372 void *hPAD2Driver = NULL;
373 
374 static int multitap1 = -1;
375 static int multitap2 = -1;
376 //Pad information, keystate, mode, config mode, vibration
377 static PadDataS pad[8];
378 
379 static int reqPos, respSize, req;
380 static int ledStateReq44[8];
381 static int PadMode[8]; /* 0 : digital 1: analog */
382 
383 static unsigned char buf[256];
384 static unsigned char bufMulti[34] = { 0x80, 0x5a,
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,
388 									0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
389 
390 unsigned char stdpar[8] = { 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
391 unsigned char multitappar[34] = { 0x80, 0x5a,
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};
396 
397 //response for request 44, 45, 46, 47, 4C, 4D
398 static unsigned char resp45[8]    = {0xF3, 0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00};
399 static unsigned char resp46_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A};
400 static unsigned char resp46_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14};
401 static unsigned char resp47[8]    = {0xF3, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
402 static unsigned char resp4C_00[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00};
403 static unsigned char resp4C_01[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00};
404 static unsigned char resp4D[8]    = {0xF3, 0x5A, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF};
405 
406 //fixed reponse of request number 41, 48, 49, 4A, 4B, 4E, 4F
407 static unsigned char resp40[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
408 static unsigned char resp41[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
409 static unsigned char resp43[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
410 static unsigned char resp44[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
411 static unsigned char resp49[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
412 static unsigned char resp4A[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
413 static unsigned char resp4B[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
414 static unsigned char resp4E[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
415 static unsigned char resp4F[8] = {0xF3, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
416 
417 // Resquest of psx core
418 enum {
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
429 	// 0x00
430 	// PadId -> 0x41 for digital pas, 0x73 for analog pad
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,
434 
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
441 	// enter in config mode example :
442 	// req : 01 43 00 01 00 00 00 00 00 00
443 	// res : 00 41 5A buttons state, analog states
444 	// exit config mode :
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,
448 
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,
458 
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,
467 
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,
477 
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,
483 
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,
492 
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 
513 
514 
515 
516 //NO MULTITAP
517 
initBufForRequest(int padIndex,char value)518 void initBufForRequest(int padIndex, char value){
519 	switch (value){
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);
526 				break;
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);
535 			buf[4] = PadMode[padIndex];
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;
570 	}
571 }
572 
573 
574 
575 
reqIndex2Treatment(int padIndex,char value)576 void reqIndex2Treatment(int padIndex, char value){
577 	switch (req){
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;
591 			PadMode[padIndex] = value;
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;
610 			pad[padIndex].Vib[0] = value;
611 			break;
612 	}
613 }
614 
vibrate(int padIndex)615 void vibrate(int padIndex){
616 	if (pad[padIndex].Vib[0] != pad[padIndex].VibF[0] || pad[padIndex].Vib[1] != pad[padIndex].VibF[1]) {
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]);
621 		//printf("vibration pad %i", padIndex);
622 	}
623 }
624 
625 
626 
627 
628 //Build response for 0x42 request Pad in port
_PADstartPoll(PadDataS * pad)629 void _PADstartPoll(PadDataS *pad) {
630 	switch (pad->controllerType) {
631 		case PSE_PAD_TYPE_MOUSE:
632 			stdpar[0] = 0x12;
633 			stdpar[2] = pad->buttonStatus & 0xff;
634 			stdpar[3] = pad->buttonStatus >> 8;
635 			stdpar[4] = pad->moveX;
636 			stdpar[5] = pad->moveY;
637 			memcpy(buf, stdpar, 6);
638 			respSize = 6;
639 			break;
640 		case PSE_PAD_TYPE_NEGCON: // npc101/npc104(slph00001/slph00069)
641 			stdpar[0] = 0x23;
642 			stdpar[2] = pad->buttonStatus & 0xff;
643 			stdpar[3] = pad->buttonStatus >> 8;
644 			stdpar[4] = pad->rightJoyX;
645 			stdpar[5] = pad->rightJoyY;
646 			stdpar[6] = pad->leftJoyX;
647 			stdpar[7] = pad->leftJoyY;
648 			memcpy(buf, stdpar, 8);
649 			respSize = 8;
650 			break;
651 	case PSE_PAD_TYPE_GUNCON: // GUNCON - gun controller SLPH-00034 from Namco
652 			stdpar[0] = 0x63;
653 			stdpar[1] = 0x5a;
654 			stdpar[2] = pad->buttonStatus & 0xff;
655 			stdpar[3] = pad->buttonStatus >> 8;
656 
657 			//This code assumes an X resolution of 256 and a Y resolution of 240
658 			int xres = 256;
659 			int yres = 240;
660 
661 			//The code wants an input range for x and y of 0-1023 we passed in -32767 -> 32767
662 			int absX = (pad->absoluteX / 64) + 512;
663 			int absY = (pad->absoluteY / 64) + 512;
664 
665 			//Keep within limits
666 			if (absX > 1023) absX = 1023;
667 			if (absX < 0) absX = 0;
668 			if (absY > 1023) absY = 1023;
669 			if (absY < 0) absY = 0;
670 
671 			stdpar[4] = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10);
672 			stdpar[5] = (0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * absX >> 10)) >> 8;
673 			stdpar[6] = 0x20 + (yres * absY >> 10);
674 			stdpar[7] = (0x20 + (yres * absY >> 10)) >> 8;
675 
676 			//Offscreen - Point at the side of the screen so PSX thinks you are pointing offscreen
677 			//Required as a mouse can't be offscreen
678 			//Coordinates X=0001h, Y=000Ah indicates "no light"
679 			//This will mean you cannot shoot the very each of the screen
680 			//ToDo read offscreen range from settings if useful to change
681 			int OffscreenRange = 2;
682 			if (absX < (OffscreenRange) || absX > (1023 - OffscreenRange) || absY < (OffscreenRange) || absY > (1023 - OffscreenRange)) {
683 				stdpar[4] = 0x01;
684 				stdpar[5] = 0x00;
685 				stdpar[6] = 0x0A;
686 				stdpar[7] = 0x00;
687 			}
688 
689 			memcpy(buf, stdpar, 8);
690 			respSize = 8;
691 			break;
692 		case PSE_PAD_TYPE_ANALOGPAD: // scph1150
693 			stdpar[0] = 0x73;
694 			stdpar[2] = pad->buttonStatus & 0xff;
695 			stdpar[3] = pad->buttonStatus >> 8;
696 			stdpar[4] = pad->rightJoyX;
697 			stdpar[5] = pad->rightJoyY;
698 			stdpar[6] = pad->leftJoyX;
699 			stdpar[7] = pad->leftJoyY;
700 			memcpy(buf, stdpar, 8);
701 			respSize = 8;
702 			break;
703 		case PSE_PAD_TYPE_ANALOGJOY: // scph1110
704 			stdpar[0] = 0x53;
705 			stdpar[2] = pad->buttonStatus & 0xff;
706 			stdpar[3] = pad->buttonStatus >> 8;
707 			stdpar[4] = pad->rightJoyX;
708 			stdpar[5] = pad->rightJoyY;
709 			stdpar[6] = pad->leftJoyX;
710 			stdpar[7] = pad->leftJoyY;
711 			memcpy(buf, stdpar, 8);
712 			respSize = 8;
713 			break;
714 		case PSE_PAD_TYPE_STANDARD:
715 		default:
716 			stdpar[0] = 0x41;
717 			stdpar[2] = pad->buttonStatus & 0xff;
718 			stdpar[3] = pad->buttonStatus >> 8;
719 			//avoid analog value in multitap mode if change pad type in game.
720 			stdpar[4] = 0xff;
721 			stdpar[5] = 0xff;
722 			stdpar[6] = 0xff;
723 			stdpar[7] = 0xff;
724 			memcpy(buf, stdpar, 8);
725 			respSize = 8;
726 	}
727 }
728 
729 
730 //Build response for 0x42 request Multitap in port
731 //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)
_PADstartPollMultitap(PadDataS * padd)732 void _PADstartPollMultitap(PadDataS* padd) {
733 	int i, offset;
734 	for(i = 0; i < 4; i++) {
735 		offset = 2 + (i * 8);
736 	_PADstartPoll(&padd[i]);
737 	memcpy(multitappar+offset, stdpar, 8);
738 	}
739 	memcpy(bufMulti, multitappar, 34);
740 	respSize = 34;
741 }
742 
743 
_PADpoll(int port,unsigned char value)744 unsigned char _PADpoll(int port, unsigned char value) {
745 	if (reqPos == 0) {
746 		//mem the request number
747 		req = value;
748 
749 		// Don't enable Analog/Vibration for a standard pad
750 		if (in_type[port] == PSE_PAD_TYPE_STANDARD ||
751 			in_type[port] == PSE_PAD_TYPE_NEGCON) {
752 			; // Pad keystate already in buffer
753 		}
754 		else
755 		{
756 			//copy the default value of request response in buffer instead of the keystate
757 			initBufForRequest(port, value);
758 		}
759 	}
760 
761 	//if no new request the pad return 0xff, for signaling connected
762 	if (reqPos >= respSize) return 0xff;
763 
764 	switch(reqPos){
765 		case 2:
766 			reqIndex2Treatment(port, value);
767 		break;
768 		case 3:
769 			switch(req) {
770 				case CMD_SET_MODE_AND_LOCK :
771 					//change mode on pad
772 				break;
773 				case CMD_READ_DATA_AND_VIBRATE:
774 				//mem the vibration value for Large motor;
775 				pad[port].Vib[1] = value;
776 
777 				if (in_type[port] == PSE_PAD_TYPE_STANDARD &&
778 					in_type[port] == PSE_PAD_TYPE_NEGCON)
779 					break;
780 
781 				//vibration
782 				vibrate(port);
783 				break;
784 			}
785 		break;
786 	}
787 	return buf[reqPos++];
788 }
789 
790 
_PADpollMultitap(int port,unsigned char value)791 unsigned char _PADpollMultitap(int port, unsigned char value) {
792 	if (reqPos >= respSize) return 0xff;
793 	return bufMulti[reqPos++];
794 }
795 
796 
797 // refresh the button state on port 1.
798 // int pad is not needed.
PAD1__startPoll(int pad)799 unsigned char CALLBACK PAD1__startPoll(int pad) {
800 	reqPos = 0;
801 	// first call the pad provide if a multitap is connected between the psx and himself
802 	if (multitap1 == -1) {
803 		PadDataS padd;
804 		padd.requestPadIndex = 0;
805 		PAD1_readPort1(&padd);
806 		multitap1 = padd.portMultitap;
807 	}
808 	// just one pad is on port 1 : NO MULTITAP
809 	if (multitap1 == 0) {
810 		PadDataS padd;
811 		padd.requestPadIndex = 0;
812 		PAD1_readPort1(&padd);
813 		_PADstartPoll(&padd);
814 	} else {
815 		// a multitap is plugged : refresh all pad.
816 		int i;
817 		PadDataS padd[4];
818 		for(i = 0; i < 4; i++) {
819 			padd[i].requestPadIndex = i;
820 			PAD1_readPort1(&padd[i]);
821 		}
822 		_PADstartPollMultitap(padd);
823 	}
824 	//printf("\npad 1 : ");
825 	return 0x00;
826 }
827 
PAD1__poll(unsigned char value)828 unsigned char CALLBACK PAD1__poll(unsigned char value) {
829 	char tmp;
830 	if (multitap1 == 1) {
831 		tmp = _PADpollMultitap(0, value);
832 	} else {
833 		tmp = _PADpoll(0, value);
834 	}
835 	//printf("%2x:%2x, ",value,tmp);
836 	return tmp;
837 
838 }
839 
840 
PAD1__configure(void)841 long CALLBACK PAD1__configure(void) { return 0; }
PAD1__about(void)842 void CALLBACK PAD1__about(void) {}
PAD1__test(void)843 long CALLBACK PAD1__test(void) { return 0; }
PAD1__query(void)844 long CALLBACK PAD1__query(void) { return 3; }
PAD1__keypressed()845 long CALLBACK PAD1__keypressed() { return 0; }
846 
847 #define LoadPad1Sym1(dest, name) \
848 	LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
849 
850 #define LoadPad1SymN(dest, name) \
851 	LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
852 
853 #define LoadPad1Sym0(dest, name) \
854 	LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
855 	if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
856 
LoadPAD1plugin(const char * PAD1dll)857 static int LoadPAD1plugin(const char *PAD1dll) {
858 	void *drv;
859 
860 	hPAD1Driver = SysLoadLibrary(PAD1dll);
861 	if (hPAD1Driver == NULL) {
862 		PAD1_configure = NULL;
863 		SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
864 	}
865 	drv = hPAD1Driver;
866 	LoadPad1Sym1(init, "PADinit");
867 	LoadPad1Sym1(shutdown, "PADshutdown");
868 	LoadPad1Sym1(open, "PADopen");
869 	LoadPad1Sym1(close, "PADclose");
870 	LoadPad1Sym0(query, "PADquery");
871 	LoadPad1Sym1(readPort1, "PADreadPort1");
872 	LoadPad1Sym0(configure, "PADconfigure");
873 	LoadPad1Sym0(test, "PADtest");
874 	LoadPad1Sym0(about, "PADabout");
875 	LoadPad1Sym0(keypressed, "PADkeypressed");
876 	LoadPad1Sym0(startPoll, "PADstartPoll");
877 	LoadPad1Sym0(poll, "PADpoll");
878 	LoadPad1SymN(setSensitive, "PADsetSensitive");
879 
880 	return 0;
881 }
882 
PAD2__startPoll(int pad)883 unsigned char CALLBACK PAD2__startPoll(int pad) {
884 	int pad_index;
885 
886 	reqPos = 0;
887 	if (multitap1 == 0 && (multitap2 == 0 || multitap2 == 2)) {
888 		pad_index = 1;
889 	} else if(multitap1 == 1 && (multitap2 == 0 || multitap2 == 2)) {
890 		pad_index = 4;
891 	} else {
892 		pad_index = 0;
893 	}
894 
895 	//first call the pad provide if a multitap is connected between the psx and himself
896 	if (multitap2 == -1) {
897 		PadDataS padd;
898 		padd.requestPadIndex = pad_index;
899 		PAD2_readPort2(&padd);
900 		multitap2 = padd.portMultitap;
901 	}
902 
903 	// just one pad is on port 1 : NO MULTITAP
904 	if (multitap2 == 0) {
905 		PadDataS padd;
906 		padd.requestPadIndex = pad_index;
907 		PAD2_readPort2(&padd);
908 		_PADstartPoll(&padd);
909 	} else {
910 		// a multitap is plugged : refresh all pad.
911 		int i;
912 		PadDataS padd[4];
913 		for(i = 0; i < 4; i++) {
914 			padd[i].requestPadIndex = i+pad_index;
915 			PAD2_readPort2(&padd[i]);
916 		}
917 		_PADstartPollMultitap(padd);
918 	}
919 	//printf("\npad 2 : ");
920 	return 0x00;
921 }
922 
PAD2__poll(unsigned char value)923 unsigned char CALLBACK PAD2__poll(unsigned char value) {
924 	char tmp;
925 	if (multitap2 == 2) {
926 		tmp = _PADpollMultitap(1, value);
927 	} else {
928 		tmp = _PADpoll(1, value);
929 	}
930 	//printf("%2x:%2x, ",value,tmp);
931 	return tmp;
932 }
933 
PAD2__configure(void)934 long CALLBACK PAD2__configure(void) { return 0; }
PAD2__about(void)935 void CALLBACK PAD2__about(void) {}
PAD2__test(void)936 long CALLBACK PAD2__test(void) { return 0; }
PAD2__query(void)937 long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
PAD2__keypressed()938 long CALLBACK PAD2__keypressed() { return 0; }
939 
940 #define LoadPad2Sym1(dest, name) \
941 	LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
942 
943 #define LoadPad2Sym0(dest, name) \
944 	LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
945 	if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
946 
947 #define LoadPad2SymN(dest, name) \
948 	LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
949 
LoadPAD2plugin(const char * PAD2dll)950 static int LoadPAD2plugin(const char *PAD2dll) {
951 	void *drv;
952 
953 	hPAD2Driver = SysLoadLibrary(PAD2dll);
954 	if (hPAD2Driver == NULL) {
955 		PAD2_configure = NULL;
956 		SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
957 	}
958 	drv = hPAD2Driver;
959 	LoadPad2Sym1(init, "PADinit");
960 	LoadPad2Sym1(shutdown, "PADshutdown");
961 	LoadPad2Sym1(open, "PADopen");
962 	LoadPad2Sym1(close, "PADclose");
963 	LoadPad2Sym0(query, "PADquery");
964 	LoadPad2Sym1(readPort2, "PADreadPort2");
965 	LoadPad2Sym0(configure, "PADconfigure");
966 	LoadPad2Sym0(test, "PADtest");
967 	LoadPad2Sym0(about, "PADabout");
968 	LoadPad2Sym0(keypressed, "PADkeypressed");
969 	LoadPad2Sym0(startPoll, "PADstartPoll");
970 	LoadPad2Sym0(poll, "PADpoll");
971 	LoadPad2SymN(setSensitive, "PADsetSensitive");
972 
973 	return 0;
974 }
975 
976 void *hNETDriver = NULL;
977 
NET__setInfo(netInfo * info)978 void CALLBACK NET__setInfo(netInfo *info) {}
NET__keypressed(int key)979 void CALLBACK NET__keypressed(int key) {}
NET__configure(void)980 long CALLBACK NET__configure(void) { return 0; }
NET__test(void)981 long CALLBACK NET__test(void) { return 0; }
NET__about(void)982 void CALLBACK NET__about(void) {}
983 
984 #define LoadNetSym1(dest, name) \
985 	LoadSym(NET_##dest, NET##dest, name, TRUE);
986 
987 #define LoadNetSymN(dest, name) \
988 	LoadSym(NET_##dest, NET##dest, name, FALSE);
989 
990 #define LoadNetSym0(dest, name) \
991 	LoadSym(NET_##dest, NET##dest, name, FALSE); \
992 	if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
993 
LoadNETplugin(const char * NETdll)994 static int LoadNETplugin(const char *NETdll) {
995 	void *drv;
996 
997 	hNETDriver = SysLoadLibrary(NETdll);
998 	if (hNETDriver == NULL) {
999 		SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
1000 	}
1001 	drv = hNETDriver;
1002 	LoadNetSym1(init, "NETinit");
1003 	LoadNetSym1(shutdown, "NETshutdown");
1004 	LoadNetSym1(open, "NETopen");
1005 	LoadNetSym1(close, "NETclose");
1006 	LoadNetSymN(sendData, "NETsendData");
1007 	LoadNetSymN(recvData, "NETrecvData");
1008 	LoadNetSym1(sendPadData, "NETsendPadData");
1009 	LoadNetSym1(recvPadData, "NETrecvPadData");
1010 	LoadNetSym1(queryPlayer, "NETqueryPlayer");
1011 	LoadNetSym1(pause, "NETpause");
1012 	LoadNetSym1(resume, "NETresume");
1013 	LoadNetSym0(setInfo, "NETsetInfo");
1014 	LoadNetSym0(keypressed, "NETkeypressed");
1015 	LoadNetSym0(configure, "NETconfigure");
1016 	LoadNetSym0(test, "NETtest");
1017 	LoadNetSym0(about, "NETabout");
1018 
1019 	return 0;
1020 }
1021 
1022 #ifdef ENABLE_SIO1API
1023 
1024 void *hSIO1Driver = NULL;
1025 
SIO1__init(void)1026 long CALLBACK SIO1__init(void) { return 0; }
SIO1__shutdown(void)1027 long CALLBACK SIO1__shutdown(void) { return 0; }
SIO1__open(void)1028 long CALLBACK SIO1__open(void) { return 0; }
SIO1__close(void)1029 long CALLBACK SIO1__close(void) { return 0; }
SIO1__configure(void)1030 long CALLBACK SIO1__configure(void) { return 0; }
SIO1__test(void)1031 long CALLBACK SIO1__test(void) { return 0; }
SIO1__about(void)1032 void CALLBACK SIO1__about(void) {}
SIO1__pause(void)1033 void CALLBACK SIO1__pause(void) {}
SIO1__resume(void)1034 void CALLBACK SIO1__resume(void) {}
SIO1__keypressed(int key)1035 long CALLBACK SIO1__keypressed(int key) { return 0; }
SIO1__writeData8(unsigned char val)1036 void CALLBACK SIO1__writeData8(unsigned char val) {}
SIO1__writeData16(unsigned short val)1037 void CALLBACK SIO1__writeData16(unsigned short val) {}
SIO1__writeData32(unsigned long val)1038 void CALLBACK SIO1__writeData32(unsigned long val) {}
SIO1__writeStat16(unsigned short val)1039 void CALLBACK SIO1__writeStat16(unsigned short val) {}
SIO1__writeStat32(unsigned long val)1040 void CALLBACK SIO1__writeStat32(unsigned long val) {}
SIO1__writeMode16(unsigned short val)1041 void CALLBACK SIO1__writeMode16(unsigned short val) {}
SIO1__writeMode32(unsigned long val)1042 void CALLBACK SIO1__writeMode32(unsigned long val) {}
SIO1__writeCtrl16(unsigned short val)1043 void CALLBACK SIO1__writeCtrl16(unsigned short val) {}
SIO1__writeCtrl32(unsigned long val)1044 void CALLBACK SIO1__writeCtrl32(unsigned long val) {}
SIO1__writeBaud16(unsigned short val)1045 void CALLBACK SIO1__writeBaud16(unsigned short val) {}
SIO1__writeBaud32(unsigned long val)1046 void CALLBACK SIO1__writeBaud32(unsigned long val) {}
SIO1__readData8(void)1047 unsigned char CALLBACK SIO1__readData8(void) { return 0; }
SIO1__readData16(void)1048 unsigned short CALLBACK SIO1__readData16(void) { return 0; }
SIO1__readData32(void)1049 unsigned long CALLBACK SIO1__readData32(void) { return 0; }
SIO1__readStat16(void)1050 unsigned short CALLBACK SIO1__readStat16(void) { return 0; }
SIO1__readStat32(void)1051 unsigned long CALLBACK SIO1__readStat32(void) { return 0; }
SIO1__readMode16(void)1052 unsigned short CALLBACK SIO1__readMode16(void) { return 0; }
SIO1__readMode32(void)1053 unsigned long CALLBACK SIO1__readMode32(void) { return 0; }
SIO1__readCtrl16(void)1054 unsigned short CALLBACK SIO1__readCtrl16(void) { return 0; }
SIO1__readCtrl32(void)1055 unsigned long CALLBACK SIO1__readCtrl32(void) { return 0; }
SIO1__readBaud16(void)1056 unsigned short CALLBACK SIO1__readBaud16(void) { return 0; }
SIO1__readBaud32(void)1057 unsigned long CALLBACK SIO1__readBaud32(void) { return 0; }
SIO1__registerCallback(void (CALLBACK * callback)(void))1058 void CALLBACK SIO1__registerCallback(void (CALLBACK *callback)(void)) {};
1059 
SIO1irq(void)1060 void CALLBACK SIO1irq(void) {
1061 	psxHu32ref(0x1070) |= SWAPu32(0x100);
1062 }
1063 
1064 #define LoadSio1Sym1(dest, name) \
1065 	LoadSym(SIO1_##dest, SIO1##dest, name, TRUE);
1066 
1067 #define LoadSio1SymN(dest, name) \
1068 	LoadSym(SIO1_##dest, SIO1##dest, name, FALSE);
1069 
1070 #define LoadSio1Sym0(dest, name) \
1071 	LoadSym(SIO1_##dest, SIO1##dest, name, FALSE); \
1072 	if (SIO1_##dest == NULL) SIO1_##dest = (SIO1##dest) SIO1__##dest;
1073 
LoadSIO1plugin(const char * SIO1dll)1074 static int LoadSIO1plugin(const char *SIO1dll) {
1075 	void *drv;
1076 
1077 	hSIO1Driver = SysLoadLibrary(SIO1dll);
1078 	if (hSIO1Driver == NULL) {
1079 		SysMessage (_("Could not load SIO1 plugin %s!"), SIO1dll); return -1;
1080 	}
1081 	drv = hSIO1Driver;
1082 
1083 	LoadSio1Sym0(init, "SIO1init");
1084 	LoadSio1Sym0(shutdown, "SIO1shutdown");
1085 	LoadSio1Sym0(open, "SIO1open");
1086 	LoadSio1Sym0(close, "SIO1close");
1087 	LoadSio1Sym0(pause, "SIO1pause");
1088 	LoadSio1Sym0(resume, "SIO1resume");
1089 	LoadSio1Sym0(keypressed, "SIO1keypressed");
1090 	LoadSio1Sym0(configure, "SIO1configure");
1091 	LoadSio1Sym0(test, "SIO1test");
1092 	LoadSio1Sym0(about, "SIO1about");
1093 	LoadSio1Sym0(writeData8, "SIO1writeData8");
1094 	LoadSio1Sym0(writeData16, "SIO1writeData16");
1095 	LoadSio1Sym0(writeData32, "SIO1writeData32");
1096 	LoadSio1Sym0(writeStat16, "SIO1writeStat16");
1097 	LoadSio1Sym0(writeStat32, "SIO1writeStat32");
1098 	LoadSio1Sym0(writeMode16, "SIO1writeMode16");
1099 	LoadSio1Sym0(writeMode32, "SIO1writeMode32");
1100 	LoadSio1Sym0(writeCtrl16, "SIO1writeCtrl16");
1101 	LoadSio1Sym0(writeCtrl32, "SIO1writeCtrl32");
1102 	LoadSio1Sym0(writeBaud16, "SIO1writeBaud16");
1103 	LoadSio1Sym0(writeBaud32, "SIO1writeBaud32");
1104 	LoadSio1Sym0(readData16, "SIO1readData16");
1105 	LoadSio1Sym0(readData32, "SIO1readData32");
1106 	LoadSio1Sym0(readStat16, "SIO1readStat16");
1107 	LoadSio1Sym0(readStat32, "SIO1readStat32");
1108 	LoadSio1Sym0(readMode16, "SIO1readMode16");
1109 	LoadSio1Sym0(readMode32, "SIO1readMode32");
1110 	LoadSio1Sym0(readCtrl16, "SIO1readCtrl16");
1111 	LoadSio1Sym0(readCtrl32, "SIO1readCtrl32");
1112 	LoadSio1Sym0(readBaud16, "SIO1readBaud16");
1113 	LoadSio1Sym0(readBaud32, "SIO1readBaud32");
1114 	LoadSio1Sym0(registerCallback, "SIO1registerCallback");
1115 
1116 	return 0;
1117 }
1118 
1119 #endif
1120 
clearDynarec(void)1121 void CALLBACK clearDynarec(void) {
1122 	psxCpu->Reset();
1123 }
1124 
LoadPlugins()1125 int LoadPlugins() {
1126 	int ret;
1127 	char Plugin[MAXPATHLEN * 2];
1128 
1129 	ReleasePlugins();
1130 	SysLibError();
1131 
1132 	if (UsingIso()) {
1133 		LoadCDRplugin(NULL);
1134 	} else {
1135 		sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1136 		if (LoadCDRplugin(Plugin) == -1) return -1;
1137 	}
1138 
1139 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
1140 	if (LoadGPUplugin(Plugin) == -1) return -1;
1141 
1142 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
1143 	if (LoadSPUplugin(Plugin) == -1) return -1;
1144 
1145 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
1146 	if (LoadPAD1plugin(Plugin) == -1) return -1;
1147 
1148 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
1149 	if (LoadPAD2plugin(Plugin) == -1) return -1;
1150 
1151 	if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
1152 		Config.UseNet = FALSE;
1153 	else {
1154 		Config.UseNet = TRUE;
1155 		sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
1156 		if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
1157 	}
1158 
1159 #ifdef ENABLE_SIO1API
1160 	sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
1161 	if (LoadSIO1plugin(Plugin) == -1) return -1;
1162 #endif
1163 
1164 	ret = CDR_init();
1165 	if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
1166 	ret = GPU_init();
1167 	if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
1168 	ret = SPU_init();
1169 	if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
1170 	ret = PAD1_init(1);
1171 	if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
1172 	ret = PAD2_init(2);
1173 	if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
1174 
1175 	if (Config.UseNet) {
1176 		ret = NET_init();
1177 		if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
1178 	}
1179 
1180 #ifdef ENABLE_SIO1API
1181 	ret = SIO1_init();
1182 	if (ret < 0) { SysMessage (_("Error initializing SIO1 plugin: %d"), ret); return -1; }
1183 #endif
1184 
1185 	SysPrintf(_("Plugins loaded.\n"));
1186 	return 0;
1187 }
1188 
ReleasePlugins()1189 void ReleasePlugins() {
1190 	if (Config.UseNet) {
1191 		int ret = NET_close();
1192 		if (ret < 0) Config.UseNet = FALSE;
1193 	}
1194 	NetOpened = FALSE;
1195 
1196 	if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1197 	if (hGPUDriver != NULL) GPU_shutdown();
1198 	if (hSPUDriver != NULL) SPU_shutdown();
1199 	if (hPAD1Driver != NULL) PAD1_shutdown();
1200 	if (hPAD2Driver != NULL) PAD2_shutdown();
1201 
1202 	if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
1203 
1204 	if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1205 	if (hGPUDriver != NULL) { SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; }
1206 	if (hSPUDriver != NULL) { SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; }
1207 	if (hPAD1Driver != NULL) { SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; }
1208 	if (hPAD2Driver != NULL) { SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; }
1209 
1210 	if (Config.UseNet && hNETDriver != NULL) {
1211 		SysCloseLibrary(hNETDriver); hNETDriver = NULL;
1212 	}
1213 
1214 #ifdef ENABLE_SIO1API
1215 	if (hSIO1Driver != NULL) {
1216 		SIO1_shutdown();
1217 		SysCloseLibrary(hSIO1Driver);
1218 		hSIO1Driver = NULL;
1219 	}
1220 #endif
1221 }
1222 
1223 // for CD swap
ReloadCdromPlugin()1224 int ReloadCdromPlugin()
1225 {
1226 	if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
1227 	if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
1228 
1229 	if (UsingIso()) {
1230 		LoadCDRplugin(NULL);
1231 	} else {
1232 		char Plugin[MAXPATHLEN * 2];
1233 		sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
1234 		if (LoadCDRplugin(Plugin) == -1) return -1;
1235 	}
1236 
1237 	return CDR_init();
1238 }
1239 
SetIsoFile(const char * filename)1240 void SetIsoFile(const char *filename) {
1241 	if (filename == NULL) {
1242 		IsoFile[0] = '\0';
1243 		return;
1244 	}
1245 	strncpy(IsoFile, filename, MAXPATHLEN - 1);
1246 }
1247 
GetIsoFile(void)1248 const char *GetIsoFile(void) {
1249 	return IsoFile;
1250 }
1251 
UsingIso(void)1252 boolean UsingIso(void) {
1253 	return (IsoFile[0] != '\0');
1254 }
1255 
SetCdOpenCaseTime(s64 time)1256 void SetCdOpenCaseTime(s64 time) {
1257 	cdOpenCaseTime = time;
1258 }
1259