frontend: update libpicofe, fix missed callbacks
[pcsx_rearmed.git] / libpcsxcore / plugins.c
index fb0ea61..3cf1cf6 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "plugins.h"
 #include "cdriso.h"
+#include "cdrom-async.h"
+#include "psxcounters.h"
 
 static char IsoFile[MAXPATHLEN] = "";
 static s64 cdOpenCaseTime = 0;
@@ -30,9 +32,6 @@ static s64 cdOpenCaseTime = 0;
 GPUupdateLace         GPU_updateLace;
 GPUinit               GPU_init;
 GPUshutdown           GPU_shutdown;
-GPUconfigure          GPU_configure;
-GPUtest               GPU_test;
-GPUabout              GPU_about;
 GPUopen               GPU_open;
 GPUclose              GPU_close;
 GPUreadStatus         GPU_readStatus;
@@ -42,35 +41,10 @@ GPUwriteStatus        GPU_writeStatus;
 GPUwriteData          GPU_writeData;
 GPUwriteDataMem       GPU_writeDataMem;
 GPUdmaChain           GPU_dmaChain;
-GPUkeypressed         GPU_keypressed;
-GPUdisplayText        GPU_displayText;
-GPUmakeSnapshot       GPU_makeSnapshot;
 GPUfreeze             GPU_freeze;
-GPUgetScreenPic       GPU_getScreenPic;
-GPUshowScreenPic      GPU_showScreenPic;
 GPUvBlank             GPU_vBlank;
 GPUgetScreenInfo      GPU_getScreenInfo;
 
-CDRinit               CDR_init;
-CDRshutdown           CDR_shutdown;
-CDRopen               CDR_open;
-CDRclose              CDR_close;
-CDRtest               CDR_test;
-CDRgetTN              CDR_getTN;
-CDRgetTD              CDR_getTD;
-CDRreadTrack          CDR_readTrack;
-CDRgetBuffer          CDR_getBuffer;
-CDRplay               CDR_play;
-CDRstop               CDR_stop;
-CDRgetStatus          CDR_getStatus;
-CDRgetDriveLetter     CDR_getDriveLetter;
-CDRgetBufferSub       CDR_getBufferSub;
-CDRconfigure          CDR_configure;
-CDRabout              CDR_about;
-CDRsetfilename        CDR_setfilename;
-CDRreadCDDA           CDR_readCDDA;
-CDRgetTE              CDR_getTE;
-
 SPUinit               SPU_init;
 SPUshutdown           SPU_shutdown;
 SPUopen               SPU_open;
@@ -85,51 +59,7 @@ SPUregisterCallback   SPU_registerCallback;
 SPUregisterScheduleCb SPU_registerScheduleCb;
 SPUasync              SPU_async;
 SPUplayCDDAchannel    SPU_playCDDAchannel;
-
-PADconfigure          PAD1_configure;
-PADabout              PAD1_about;
-PADinit               PAD1_init;
-PADshutdown           PAD1_shutdown;
-PADtest               PAD1_test;
-PADopen               PAD1_open;
-PADclose              PAD1_close;
-PADquery              PAD1_query;
-PADreadPort1          PAD1_readPort1;
-PADkeypressed         PAD1_keypressed;
-PADstartPoll          PAD1_startPoll;
-PADpoll               PAD1_poll;
-PADsetSensitive       PAD1_setSensitive;
-
-PADconfigure          PAD2_configure;
-PADabout              PAD2_about;
-PADinit               PAD2_init;
-PADshutdown           PAD2_shutdown;
-PADtest               PAD2_test;
-PADopen               PAD2_open;
-PADclose              PAD2_close;
-PADquery              PAD2_query;
-PADreadPort2          PAD2_readPort2;
-PADkeypressed         PAD2_keypressed;
-PADstartPoll          PAD2_startPoll;
-PADpoll               PAD2_poll;
-PADsetSensitive       PAD2_setSensitive;
-
-NETinit               NET_init;
-NETshutdown           NET_shutdown;
-NETopen               NET_open;
-NETclose              NET_close;
-NETtest               NET_test;
-NETconfigure          NET_configure;
-NETabout              NET_about;
-NETpause              NET_pause;
-NETresume             NET_resume;
-NETqueryPlayer        NET_queryPlayer;
-NETsendData           NET_sendData;
-NETrecvData           NET_recvData;
-NETsendPadData        NET_sendPadData;
-NETrecvPadData        NET_recvPadData;
-NETsetInfo            NET_setInfo;
-NETkeypressed         NET_keypressed;
+SPUsetCDvol           SPU_setCDvol;
 
 #ifdef ENABLE_SIO1API
 
@@ -178,24 +108,13 @@ static const char *err;
 
 #define LoadSym(dest, src, name, checkerr) { \
        dest = (src)SysLoadSym(drv, name); \
-       if (checkerr) { CheckErr(name); } else SysLibError(); \
+       if (checkerr) { CheckErr(name); } \
 }
 
 void *hGPUDriver = NULL;
 
-void CALLBACK GPU__displayText(char *pText) {
-       SysPrintf("%s\n", pText);
-}
-
-long CALLBACK GPU__configure(void) { return 0; }
-long CALLBACK GPU__test(void) { return 0; }
-void CALLBACK GPU__about(void) {}
-void CALLBACK GPU__makeSnapshot(void) {}
-void CALLBACK GPU__keypressed(int key) {}
-long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; }
-long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; }
-void CALLBACK GPU__vBlank(int val) {}
-void CALLBACK GPU__getScreenInfo(int *y, int *base_hres) {}
+static void CALLBACK GPU__vBlank(int val) {}
+static void CALLBACK GPU__getScreenInfo(int *y, int *base_hres) {}
 
 #define LoadGpuSym1(dest, name) \
        LoadSym(GPU_##dest, GPU##dest, name, TRUE);
@@ -212,7 +131,6 @@ static int LoadGPUplugin(const char *GPUdll) {
 
        hGPUDriver = SysLoadLibrary(GPUdll);
        if (hGPUDriver == NULL) {
-               GPU_configure = NULL;
                SysMessage (_("Could not load GPU plugin %s!"), GPUdll); return -1;
        }
        drv = hGPUDriver;
@@ -228,27 +146,14 @@ static int LoadGPUplugin(const char *GPUdll) {
        LoadGpuSym1(writeStatus, "GPUwriteStatus");
        LoadGpuSym1(dmaChain, "GPUdmaChain");
        LoadGpuSym1(updateLace, "GPUupdateLace");
-       LoadGpuSym0(keypressed, "GPUkeypressed");
-       LoadGpuSym0(displayText, "GPUdisplayText");
-       LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot");
        LoadGpuSym1(freeze, "GPUfreeze");
-       LoadGpuSym0(getScreenPic, "GPUgetScreenPic");
-       LoadGpuSym0(showScreenPic, "GPUshowScreenPic");
        LoadGpuSym0(vBlank, "GPUvBlank");
        LoadGpuSym0(getScreenInfo, "GPUgetScreenInfo");
-       LoadGpuSym0(configure, "GPUconfigure");
-       LoadGpuSym0(test, "GPUtest");
-       LoadGpuSym0(about, "GPUabout");
 
        return 0;
 }
 
-void *hCDRDriver = NULL;
-
-long CALLBACK CDR__play(unsigned char *sector) { return 0; }
-long CALLBACK CDR__stop(void) { return 0; }
-
-long CALLBACK CDR__getStatus(struct CdrStat *stat) {
+int CDR__getStatus(struct CdrStat *stat) {
        if (cdOpenCaseTime < 0 || cdOpenCaseTime > (s64)time(NULL))
                stat->Status = 0x10;
        else
@@ -257,68 +162,17 @@ long CALLBACK CDR__getStatus(struct CdrStat *stat) {
        return 0;
 }
 
-char* CALLBACK CDR__getDriveLetter(void) { return NULL; }
-long CALLBACK CDR__configure(void) { return 0; }
-long CALLBACK CDR__test(void) { return 0; }
-void CALLBACK CDR__about(void) {}
-long CALLBACK CDR__setfilename(char*filename) { return 0; }
-
-#define LoadCdrSym1(dest, name) \
-       LoadSym(CDR_##dest, CDR##dest, name, TRUE);
-
-#define LoadCdrSym0(dest, name) \
-       LoadSym(CDR_##dest, CDR##dest, name, FALSE); \
-       if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest;
-
-#define LoadCdrSymN(dest, name) \
-       LoadSym(CDR_##dest, CDR##dest, name, FALSE);
-
-static int LoadCDRplugin(const char *CDRdll) {
-       void *drv;
-
-       if (CDRdll == NULL) {
-               cdrIsoInit();
-               return 0;
-       }
-
-       hCDRDriver = SysLoadLibrary(CDRdll);
-       if (hCDRDriver == NULL) {
-               CDR_configure = NULL;
-               SysMessage (_("Could not load CD-ROM plugin %s!"), CDRdll);  return -1;
-       }
-       drv = hCDRDriver;
-       LoadCdrSym1(init, "CDRinit");
-       LoadCdrSym1(shutdown, "CDRshutdown");
-       LoadCdrSym1(open, "CDRopen");
-       LoadCdrSym1(close, "CDRclose");
-       LoadCdrSym1(getTN, "CDRgetTN");
-       LoadCdrSym1(getTD, "CDRgetTD");
-       LoadCdrSym1(readTrack, "CDRreadTrack");
-       LoadCdrSym1(getBuffer, "CDRgetBuffer");
-       LoadCdrSym1(getBufferSub, "CDRgetBufferSub");
-       LoadCdrSym0(play, "CDRplay");
-       LoadCdrSym0(stop, "CDRstop");
-       LoadCdrSym0(getStatus, "CDRgetStatus");
-       LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter");
-       LoadCdrSym0(configure, "CDRconfigure");
-       LoadCdrSym0(test, "CDRtest");
-       LoadCdrSym0(about, "CDRabout");
-       LoadCdrSym0(setfilename, "CDRsetfilename");
-       LoadCdrSymN(readCDDA, "CDRreadCDDA");
-       LoadCdrSymN(getTE, "CDRgetTE");
-
-       return 0;
-}
-
 static void *hSPUDriver = NULL;\r
 static void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}\r
+static void CALLBACK SPU__setCDvol(unsigned char ll, unsigned char lr,
+               unsigned char rl, unsigned char rr, unsigned int cycle) {}
 
 #define LoadSpuSym1(dest, name) \
        LoadSym(SPU_##dest, SPU##dest, name, TRUE);
 
 #define LoadSpuSym0(dest, name) \
        LoadSym(SPU_##dest, SPU##dest, name, FALSE); \
-       if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest;
+       if (SPU_##dest == NULL) SPU_##dest = SPU__##dest;
 
 #define LoadSpuSymN(dest, name) \
        LoadSym(SPU_##dest, SPU##dest, name, FALSE);
@@ -345,15 +199,13 @@ static int LoadSPUplugin(const char *SPUdll) {
        LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");
        LoadSpuSymN(async, "SPUasync");
        LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");
+       LoadSpuSym0(setCDvol, "SPUsetCDvol");
 
        return 0;
 }
 
 extern int in_type[8];
 
-void *hPAD1Driver = NULL;
-void *hPAD2Driver = NULL;
-
 // Pad information, keystate, mode, config mode, vibration
 static PadDataS pads[8];
 
@@ -480,7 +332,7 @@ enum {
 
 
 static void initBufForRequest(int padIndex, char value) {
-       if (pads[padIndex].configMode) {
+       if (pads[padIndex].ds.configMode) {
                buf[0] = 0xf3; buf[1] = 0x5a;
                respSize = 8;
        }
@@ -489,12 +341,36 @@ static void initBufForRequest(int padIndex, char value) {
                return;
        }
 
+       if ((u32)(frame_counter - pads[padIndex].ds.lastUseFrame) > 2*60u
+           && pads[padIndex].ds.configModeUsed
+           && !Config.hacks.dualshock_init_analog)
+       {
+               //SysPrintf("Pad reset\n");
+               pads[padIndex].ds.padMode = 0; // according to nocash
+               pads[padIndex].ds.autoAnalogTried = 0;
+       }
+       else if (pads[padIndex].ds.padMode == 0 && value == CMD_READ_DATA_AND_VIBRATE
+                && pads[padIndex].ds.configModeUsed
+                && !pads[padIndex].ds.configMode
+                && !pads[padIndex].ds.userToggled)
+       {
+               if (pads[padIndex].ds.autoAnalogTried == 16) {
+                       // auto-enable for convenience
+                       SysPrintf("Auto-enabling dualshock analog mode.\n");
+                       pads[padIndex].ds.padMode = 1;
+                       pads[padIndex].ds.autoAnalogTried = 255;
+               }
+               else if (pads[padIndex].ds.autoAnalogTried < 16)
+                       pads[padIndex].ds.autoAnalogTried++;
+       }
+       pads[padIndex].ds.lastUseFrame = frame_counter;
+
        switch (value) {
                // keystate already in buffer, set by PADstartPoll_()
                //case CMD_READ_DATA_AND_VIBRATE :
                //      break;
                case CMD_CONFIG_MODE :
-                       if (pads[padIndex].configMode) {
+                       if (pads[padIndex].ds.configMode) {
                                memcpy(buf, resp43, 8);
                                break;
                        }
@@ -505,7 +381,7 @@ static void initBufForRequest(int padIndex, char value) {
                        break;
                case CMD_QUERY_MODEL_AND_MODE :
                        memcpy(buf, resp45, 8);
-                       buf[4] = pads[padIndex].PadMode;
+                       buf[4] = pads[padIndex].ds.padMode;
                        break;
                case CMD_QUERY_ACT :
                        memcpy(buf, resp46_00, 8);
@@ -517,7 +393,7 @@ static void initBufForRequest(int padIndex, char value) {
                        memcpy(buf, resp4C_00, 8);
                        break;
                case CMD_VIBRATION_TOGGLE: // 4d
-                       memcpy(buf + 2, pads[padIndex].cmd4dConfig, 6);
+                       memcpy(buf + 2, pads[padIndex].ds.cmd4dConfig, 6);
                        break;
                case REQ40 :
                        memcpy(buf, resp40, 8);
@@ -548,9 +424,10 @@ static void reqIndex2Treatment(int padIndex, u8 value) {
                case CMD_CONFIG_MODE :
                        //0x43
                        if (value == 0) {
-                               pads[padIndex].configMode = 0;
-                       } else {
-                               pads[padIndex].configMode = 1;
+                               pads[padIndex].ds.configMode = 0;
+                       } else if (value == 1) {
+                               pads[padIndex].ds.configMode = 1;
+                               pads[padIndex].ds.configModeUsed = 1;
                        }
                        break;
                case CMD_SET_MODE_AND_LOCK :
@@ -558,7 +435,7 @@ static void reqIndex2Treatment(int padIndex, u8 value) {
                        //0x01 analog ON
                        //0x00 analog OFF
                        if ((value & ~1) == 0)
-                               pads[padIndex].PadMode = value;
+                               pads[padIndex].ds.padMode = value;
                        break;
                case CMD_QUERY_ACT :
                        //0x46
@@ -571,21 +448,25 @@ static void reqIndex2Treatment(int padIndex, u8 value) {
                                memcpy(buf, resp4C_01, 8);
                        }
                        break;
-               case CMD_READ_DATA_AND_VIBRATE:
-                       //mem the vibration value for small motor;
-                       pads[padIndex].Vib[0] = value;
-                       break;
        }
 }
 
-static void vibrate(int padIndex) {
+static void ds_update_vibrate(int padIndex) {
        PadDataS *pad = &pads[padIndex];
+       if (pad->ds.configModeUsed) {
+               pad->Vib[0] = (pad->Vib[0] == 1) ? 1 : 0;
+       }
+       else {
+               // compat mode
+               pad->Vib[0] = (pad->Vib[0] & 0xc0) == 0x40 && (pad->Vib[1] & 1);
+               pad->Vib[1] = 0;
+       }
        if (pad->Vib[0] != pad->VibF[0] || pad->Vib[1] != pad->VibF[1]) {
                //value is different update Value and call libretro for vibration
                pad->VibF[0] = pad->Vib[0];
                pad->VibF[1] = pad->Vib[1];
                plat_trigger_vibrate(padIndex, pad->VibF[0], pad->VibF[1]);
-               //printf("vibration pad %i\n", padIndex);
+               //printf("vib%i %02x %02x\n", padIndex, pad->VibF[0], pad->VibF[1]);
        }
 }
 
@@ -604,6 +485,15 @@ static void log_pad(int port, int pos)
 #endif
 }
 
+static void adjust_analog(unsigned char *b)
+{
+       // ff8 hates 0x80 for whatever reason (broken in 2d area menus),
+       // or is this caused by something else we do wrong??
+       // Also S.C.A.R.S. treats 0x7f as turning left.
+       if (b[6] == 0x7f || b[6] == 0x80)
+               b[6] = 0x81;
+}
+
 // Build response for 0x42 request Pad in port
 static void PADstartPoll_(PadDataS *pad) {
        switch (pad->controllerType) {
@@ -671,7 +561,7 @@ static void PADstartPoll_(PadDataS *pad) {
                        respSize = 4;
                        break;
                case PSE_PAD_TYPE_ANALOGPAD: // scph1150
-                       if (pad->PadMode == 0)
+                       if (pad->ds.padMode == 0)
                                goto standard;
                        stdpar[0] = 0x73;
                        stdpar[1] = 0x5a;
@@ -681,6 +571,7 @@ static void PADstartPoll_(PadDataS *pad) {
                        stdpar[5] = pad->rightJoyY;
                        stdpar[6] = pad->leftJoyX;
                        stdpar[7] = pad->leftJoyY;
+                       adjust_analog(stdpar);
                        memcpy(buf, stdpar, 8);
                        respSize = 8;
                        break;
@@ -693,6 +584,7 @@ static void PADstartPoll_(PadDataS *pad) {
                        stdpar[5] = pad->rightJoyY;
                        stdpar[6] = pad->leftJoyX;
                        stdpar[7] = pad->leftJoyY;
+                       adjust_analog(stdpar);
                        memcpy(buf, stdpar, 8);
                        respSize = 8;
                        break;
@@ -720,19 +612,28 @@ static void PADpoll_dualshock(int port, unsigned char value, int pos)
                case 2:
                        reqIndex2Treatment(port, value);
                        break;
-               case 3:
-                       if (pads[port].txData[0] == CMD_READ_DATA_AND_VIBRATE) {
-                               // vibration value for the Large motor
-                               pads[port].Vib[1] = value;
-
-                               vibrate(port);
-                       }
-                       break;
                case 7:
                        if (pads[port].txData[0] == CMD_VIBRATION_TOGGLE)
-                               memcpy(pads[port].cmd4dConfig, pads[port].txData + 2, 6);
+                               memcpy(pads[port].ds.cmd4dConfig, pads[port].txData + 2, 6);
                        break;
        }
+
+       if (pads[port].txData[0] == CMD_READ_DATA_AND_VIBRATE
+           && !pads[port].ds.configModeUsed && 2 <= pos && pos < 4)
+       {
+               // "compat" single motor mode
+               pads[port].Vib[pos - 2] = value;
+       }
+       else if (pads[port].txData[0] == CMD_READ_DATA_AND_VIBRATE
+                && 2 <= pos && pos < 8)
+       {
+               // 0 - weak motor, 1 - strong motor
+               int dev = pads[port].ds.cmd4dConfig[pos - 2];
+               if (dev < 2)
+                       pads[port].Vib[dev] = value;
+       }
+       if (pos == respSize - 1)
+               ds_update_vibrate(port);
 }
 
 static unsigned char PADpoll_(int port, unsigned char value, int pos, int *more_data) {
@@ -795,12 +696,12 @@ static unsigned char PADpollMain(int port, unsigned char value, int *more_data)
 
 // refresh the button state on port 1.
 // int pad is not needed.
-unsigned char CALLBACK PAD1__startPoll(int unused) {
+unsigned char PAD1_startPoll(int unused) {
        int i;
 
        reqPos = 0;
        pads[0].requestPadIndex = 0;
-       PAD1_readPort1(&pads[0]);
+       PAD1_readPort(&pads[0]);
 
        pads[0].multitapLongModeEnabled = 0;
        if (pads[0].portMultitap)
@@ -812,72 +713,24 @@ unsigned char CALLBACK PAD1__startPoll(int unused) {
                // a multitap is plugged and enabled: refresh pads 1-3
                for (i = 1; i < 4; i++) {
                        pads[i].requestPadIndex = i;
-                       PAD1_readPort1(&pads[i]);
+                       PAD1_readPort(&pads[i]);
                }
        }
        return 0xff;
 }
 
-unsigned char CALLBACK PAD1__poll(unsigned char value, int *more_data) {
+unsigned char PAD1_poll(unsigned char value, int *more_data) {
        return PADpollMain(0, value, more_data);
 }
 
 
-long CALLBACK PAD1__configure(void) { return 0; }
-void CALLBACK PAD1__about(void) {}
-long CALLBACK PAD1__test(void) { return 0; }
-long CALLBACK PAD1__query(void) { return 3; }
-long CALLBACK PAD1__keypressed() { return 0; }
-
-#define LoadPad1Sym1(dest, name) \
-       LoadSym(PAD1_##dest, PAD##dest, name, TRUE);
-
-#define LoadPad1SymN(dest, name) \
-       LoadSym(PAD1_##dest, PAD##dest, name, FALSE);
-
-#define LoadPad1Sym0(dest, name) \
-       LoadSym(PAD1_##dest, PAD##dest, name, FALSE); \
-       if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest;
-
-static int LoadPAD1plugin(const char *PAD1dll) {
-       void *drv;
-       size_t p;
-
-       hPAD1Driver = SysLoadLibrary(PAD1dll);
-       if (hPAD1Driver == NULL) {
-               PAD1_configure = NULL;
-               SysMessage (_("Could not load Controller 1 plugin %s!"), PAD1dll); return -1;
-       }
-       drv = hPAD1Driver;
-       LoadPad1Sym1(init, "PADinit");
-       LoadPad1Sym1(shutdown, "PADshutdown");
-       LoadPad1Sym1(open, "PADopen");
-       LoadPad1Sym1(close, "PADclose");
-       LoadPad1Sym0(query, "PADquery");
-       LoadPad1Sym1(readPort1, "PADreadPort1");
-       LoadPad1Sym0(configure, "PADconfigure");
-       LoadPad1Sym0(test, "PADtest");
-       LoadPad1Sym0(about, "PADabout");
-       LoadPad1Sym0(keypressed, "PADkeypressed");
-       LoadPad1Sym0(startPoll, "PADstartPoll");
-       LoadPad1Sym0(poll, "PADpoll");
-       LoadPad1SymN(setSensitive, "PADsetSensitive");
-
-       memset(pads, 0, sizeof(pads));
-       for (p = 0; p < sizeof(pads) / sizeof(pads[0]); p++) {
-               memset(pads[p].cmd4dConfig, 0xff, sizeof(pads[p].cmd4dConfig));
-       }
-
-       return 0;
-}
-
-unsigned char CALLBACK PAD2__startPoll(int pad) {
+unsigned char PAD2_startPoll(int pad) {
        int pad_index = pads[0].portMultitap ? 4 : 1;
        int i;
 
        reqPos = 0;
        pads[pad_index].requestPadIndex = pad_index;
-       PAD2_readPort2(&pads[pad_index]);
+       PAD2_readPort(&pads[pad_index]);
 
        pads[pad_index].multitapLongModeEnabled = 0;
        if (pads[pad_index].portMultitap)
@@ -888,102 +741,47 @@ unsigned char CALLBACK PAD2__startPoll(int pad) {
        } else {
                for (i = 1; i < 4; i++) {
                        pads[pad_index + i].requestPadIndex = pad_index + i;
-                       PAD2_readPort2(&pads[pad_index + i]);
+                       PAD2_readPort(&pads[pad_index + i]);
                }
        }
        return 0xff;
 }
 
-unsigned char CALLBACK PAD2__poll(unsigned char value, int *more_data) {
+unsigned char PAD2_poll(unsigned char value, int *more_data) {
        return PADpollMain(pads[0].portMultitap ? 4 : 1, value, more_data);
 }
 
-long CALLBACK PAD2__configure(void) { return 0; }
-void CALLBACK PAD2__about(void) {}
-long CALLBACK PAD2__test(void) { return 0; }
-long CALLBACK PAD2__query(void) { return PSE_PAD_USE_PORT1 | PSE_PAD_USE_PORT2; }
-long CALLBACK PAD2__keypressed() { return 0; }
-
-#define LoadPad2Sym1(dest, name) \
-       LoadSym(PAD2_##dest, PAD##dest, name, TRUE);
-
-#define LoadPad2Sym0(dest, name) \
-       LoadSym(PAD2_##dest, PAD##dest, name, FALSE); \
-       if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest;
+static void PAD_init(void) {
+       size_t p;
 
-#define LoadPad2SymN(dest, name) \
-       LoadSym(PAD2_##dest, PAD##dest, name, FALSE);
+       memset(pads, 0, sizeof(pads));
+       for (p = 0; p < sizeof(pads) / sizeof(pads[0]); p++) {
+               memset(pads[p].ds.cmd4dConfig, 0xff, sizeof(pads[p].ds.cmd4dConfig));
+       }
+}
 
-static int LoadPAD2plugin(const char *PAD2dll) {
-       void *drv;
+int padFreeze(void *f, int Mode) {
+       size_t i;
 
-       hPAD2Driver = SysLoadLibrary(PAD2dll);
-       if (hPAD2Driver == NULL) {
-               PAD2_configure = NULL;
-               SysMessage (_("Could not load Controller 2 plugin %s!"), PAD2dll); return -1;
+       for (i = 0; i < sizeof(pads) / sizeof(pads[0]); i++) {
+               pads[i].saveSize = sizeof(pads[i]);
+               gzfreeze(&pads[i], sizeof(pads[i]));
+               if (Mode == 0 && pads[i].saveSize != sizeof(pads[i]))
+                       SaveFuncs.seek(f, pads[i].saveSize - sizeof(pads[i]), SEEK_CUR);
        }
-       drv = hPAD2Driver;
-       LoadPad2Sym1(init, "PADinit");
-       LoadPad2Sym1(shutdown, "PADshutdown");
-       LoadPad2Sym1(open, "PADopen");
-       LoadPad2Sym1(close, "PADclose");
-       LoadPad2Sym0(query, "PADquery");
-       LoadPad2Sym1(readPort2, "PADreadPort2");
-       LoadPad2Sym0(configure, "PADconfigure");
-       LoadPad2Sym0(test, "PADtest");
-       LoadPad2Sym0(about, "PADabout");
-       LoadPad2Sym0(keypressed, "PADkeypressed");
-       LoadPad2Sym0(startPoll, "PADstartPoll");
-       LoadPad2Sym0(poll, "PADpoll");
-       LoadPad2SymN(setSensitive, "PADsetSensitive");
 
        return 0;
 }
 
-void *hNETDriver = NULL;
-
-void CALLBACK NET__setInfo(netInfo *info) {}
-void CALLBACK NET__keypressed(int key) {}
-long CALLBACK NET__configure(void) { return 0; }
-long CALLBACK NET__test(void) { return 0; }
-void CALLBACK NET__about(void) {}
-
-#define LoadNetSym1(dest, name) \
-       LoadSym(NET_##dest, NET##dest, name, TRUE);
-
-#define LoadNetSymN(dest, name) \
-       LoadSym(NET_##dest, NET##dest, name, FALSE);
-
-#define LoadNetSym0(dest, name) \
-       LoadSym(NET_##dest, NET##dest, name, FALSE); \
-       if (NET_##dest == NULL) NET_##dest = (NET##dest) NET__##dest;
-
-static int LoadNETplugin(const char *NETdll) {
-       void *drv;
+int padToggleAnalog(unsigned int index)
+{
+       int r = -1;
 
-       hNETDriver = SysLoadLibrary(NETdll);
-       if (hNETDriver == NULL) {
-               SysMessage (_("Could not load NetPlay plugin %s!"), NETdll); return -1;
+       if (index < sizeof(pads) / sizeof(pads[0])) {
+               r = (pads[index].ds.padMode ^= 1);
+               pads[index].ds.userToggled = 1;
        }
-       drv = hNETDriver;
-       LoadNetSym1(init, "NETinit");
-       LoadNetSym1(shutdown, "NETshutdown");
-       LoadNetSym1(open, "NETopen");
-       LoadNetSym1(close, "NETclose");
-       LoadNetSymN(sendData, "NETsendData");
-       LoadNetSymN(recvData, "NETrecvData");
-       LoadNetSym1(sendPadData, "NETsendPadData");
-       LoadNetSym1(recvPadData, "NETrecvPadData");
-       LoadNetSym1(queryPlayer, "NETqueryPlayer");
-       LoadNetSym1(pause, "NETpause");
-       LoadNetSym1(resume, "NETresume");
-       LoadNetSym0(setInfo, "NETsetInfo");
-       LoadNetSym0(keypressed, "NETkeypressed");
-       LoadNetSym0(configure, "NETconfigure");
-       LoadNetSym0(test, "NETtest");
-       LoadNetSym0(about, "NETabout");
-
-       return 0;
+       return r;
 }
 
 #ifdef ENABLE_SIO1API
@@ -1086,59 +884,30 @@ static int LoadSIO1plugin(const char *SIO1dll) {
 #endif
 
 int LoadPlugins() {
-       int ret;
        char Plugin[MAXPATHLEN * 2];
+       int ret;
 
        ReleasePlugins();
        SysLibError();
 
-       if (UsingIso()) {
-               LoadCDRplugin(NULL);
-       } else {
-               sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
-               if (LoadCDRplugin(Plugin) == -1) return -1;
-       }
-
        sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Gpu);
        if (LoadGPUplugin(Plugin) == -1) return -1;
 
        sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Spu);
        if (LoadSPUplugin(Plugin) == -1) return -1;
 
-       sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad1);
-       if (LoadPAD1plugin(Plugin) == -1) return -1;
-
-       sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Pad2);
-       if (LoadPAD2plugin(Plugin) == -1) return -1;
-
-       if (strcmp("Disabled", Config.Net) == 0 || strcmp("", Config.Net) == 0)
-               Config.UseNet = FALSE;
-       else {
-               Config.UseNet = TRUE;
-               sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Net);
-               if (LoadNETplugin(Plugin) == -1) Config.UseNet = FALSE;
-       }
-
 #ifdef ENABLE_SIO1API
        sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Sio1);
        if (LoadSIO1plugin(Plugin) == -1) return -1;
 #endif
 
-       ret = CDR_init();
+       ret = cdra_init();
        if (ret < 0) { SysMessage (_("Error initializing CD-ROM plugin: %d"), ret); return -1; }
        ret = GPU_init();
        if (ret < 0) { SysMessage (_("Error initializing GPU plugin: %d"), ret); return -1; }
        ret = SPU_init();
        if (ret < 0) { SysMessage (_("Error initializing SPU plugin: %d"), ret); return -1; }
-       ret = PAD1_init(1);
-       if (ret < 0) { SysMessage (_("Error initializing Controller 1 plugin: %d"), ret); return -1; }
-       ret = PAD2_init(2);
-       if (ret < 0) { SysMessage (_("Error initializing Controller 2 plugin: %d"), ret); return -1; }
-
-       if (Config.UseNet) {
-               ret = NET_init();
-               if (ret < 0) { SysMessage (_("Error initializing NetPlay plugin: %d"), ret); return -1; }
-       }
+       PAD_init();
 
 #ifdef ENABLE_SIO1API
        ret = SIO1_init();
@@ -1150,29 +919,12 @@ int LoadPlugins() {
 }
 
 void ReleasePlugins() {
-       if (Config.UseNet) {
-               int ret = NET_close();
-               if (ret < 0) Config.UseNet = FALSE;
-       }
-       NetOpened = FALSE;
-
-       if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
+       cdra_shutdown();
        if (hGPUDriver != NULL) GPU_shutdown();
        if (hSPUDriver != NULL) SPU_shutdown();
-       if (hPAD1Driver != NULL) PAD1_shutdown();
-       if (hPAD2Driver != NULL) PAD2_shutdown();
-
-       if (Config.UseNet && hNETDriver != NULL) NET_shutdown();
 
-       if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
        if (hGPUDriver != NULL) { SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; }
        if (hSPUDriver != NULL) { SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; }
-       if (hPAD1Driver != NULL) { SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; }
-       if (hPAD2Driver != NULL) { SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; }
-
-       if (Config.UseNet && hNETDriver != NULL) {
-               SysCloseLibrary(hNETDriver); hNETDriver = NULL;
-       }
 
 #ifdef ENABLE_SIO1API
        if (hSIO1Driver != NULL) {
@@ -1186,18 +938,8 @@ void ReleasePlugins() {
 // for CD swap
 int ReloadCdromPlugin()
 {
-       if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown();
-       if (hCDRDriver != NULL) { SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; }
-
-       if (UsingIso()) {
-               LoadCDRplugin(NULL);
-       } else {
-               char Plugin[MAXPATHLEN * 2];
-               sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr);
-               if (LoadCDRplugin(Plugin) == -1) return -1;
-       }
-
-       return CDR_init();
+       cdra_shutdown();
+       return cdra_init();
 }
 
 void SetIsoFile(const char *filename) {