mirror of https://github.com/PCSX2/pcsx2.git
1549 lines
41 KiB
C++
1549 lines
41 KiB
C++
/* Pcsx2 - Pc Ps2 Emulator
|
|
* Copyright (C) 2002-2009 Pcsx2 Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "PrecompiledHeader.h"
|
|
#include "Utilities/RedtapeWindows.h"
|
|
|
|
#include <wx/dir.h>
|
|
#include <wx/file.h>
|
|
|
|
#include "IopCommon.h"
|
|
#include "GS.h"
|
|
#include "HostGui.h"
|
|
#include "CDVD/CDVDisoReader.h"
|
|
#include "AppConfig.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Yay, order of this array shouldn't be important. :)
|
|
//
|
|
const PluginInfo tbl_PluginInfo[] =
|
|
{
|
|
{ "GS", PluginId_GS, PS2E_LT_GS, PS2E_GS_VERSION },
|
|
{ "PAD", PluginId_PAD, PS2E_LT_PAD, PS2E_PAD_VERSION },
|
|
{ "SPU2", PluginId_SPU2, PS2E_LT_SPU2, PS2E_SPU2_VERSION },
|
|
{ "CDVD", PluginId_CDVD, PS2E_LT_CDVD, PS2E_CDVD_VERSION },
|
|
{ "DEV9", PluginId_DEV9, PS2E_LT_DEV9, PS2E_DEV9_VERSION },
|
|
{ "USB", PluginId_USB, PS2E_LT_USB, PS2E_USB_VERSION },
|
|
{ "FW", PluginId_FW, PS2E_LT_FW, PS2E_FW_VERSION },
|
|
|
|
// SIO is currently unused (legacy?)
|
|
//{ "SIO", PluginId_SIO, PS2E_LT_SIO, PS2E_SIO_VERSION }
|
|
|
|
};
|
|
|
|
typedef void CALLBACK VoidMethod();
|
|
typedef void CALLBACK vMeth(); // shorthand for VoidMethod
|
|
; // extra semicolon fixes VA-X intellisense breakage caused by CALLBACK in the above typedef >_<
|
|
|
|
// ----------------------------------------------------------------------------
|
|
struct LegacyApi_CommonMethod
|
|
{
|
|
const char* MethodName;
|
|
|
|
// fallback is used if the method is null. If the method is null and fallback is null
|
|
// also, the plugin is considered incomplete or invalid, and an error is generated.
|
|
VoidMethod* Fallback;
|
|
|
|
// returns the method name as a wxString, converted from UTF8.
|
|
wxString GetMethodName( PluginsEnum_t pid ) const
|
|
{
|
|
return wxString::FromUTF8( tbl_PluginInfo[pid].shortname) + wxString::FromUTF8( MethodName );
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
struct LegacyApi_ReqMethod
|
|
{
|
|
const char* MethodName;
|
|
VoidMethod** Dest; // Target function where the binding is saved.
|
|
|
|
// fallback is used if the method is null. If the method is null and fallback is null
|
|
// also, the plugin is considered incomplete or invalid, and an error is generated.
|
|
VoidMethod* Fallback;
|
|
|
|
// returns the method name as a wxString, converted from UTF8.
|
|
wxString GetMethodName( ) const
|
|
{
|
|
return wxString::FromUTF8( MethodName );
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
struct LegacyApi_OptMethod
|
|
{
|
|
const char* MethodName;
|
|
VoidMethod** Dest; // Target function where the binding is saved.
|
|
|
|
// returns the method name as a wxString, converted from UTF8.
|
|
wxString GetMethodName() const { return wxString::FromUTF8( MethodName ); }
|
|
};
|
|
|
|
|
|
static s32 CALLBACK fallback_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
|
|
static void CALLBACK fallback_keyEvent(keyEvent *ev) {}
|
|
static void CALLBACK fallback_configure() {}
|
|
static void CALLBACK fallback_about() {}
|
|
static s32 CALLBACK fallback_test() { return 0; }
|
|
|
|
_GSvsync GSvsync;
|
|
_GSopen GSopen;
|
|
_GSgifTransfer1 GSgifTransfer1;
|
|
_GSgifTransfer2 GSgifTransfer2;
|
|
_GSgifTransfer3 GSgifTransfer3;
|
|
_GSgifSoftReset GSgifSoftReset;
|
|
_GSreadFIFO GSreadFIFO;
|
|
_GSreadFIFO2 GSreadFIFO2;
|
|
_GSchangeSaveState GSchangeSaveState;
|
|
_GSmakeSnapshot GSmakeSnapshot;
|
|
_GSmakeSnapshot2 GSmakeSnapshot2;
|
|
_GSirqCallback GSirqCallback;
|
|
_GSprintf GSprintf;
|
|
_GSsetBaseMem GSsetBaseMem;
|
|
_GSsetGameCRC GSsetGameCRC;
|
|
_GSsetFrameSkip GSsetFrameSkip;
|
|
_GSsetFrameLimit GSsetFrameLimit;
|
|
_GSsetupRecording GSsetupRecording;
|
|
_GSreset GSreset;
|
|
_GSwriteCSR GSwriteCSR;
|
|
|
|
static void CALLBACK GS_makeSnapshot(const char *path) {}
|
|
static void CALLBACK GS_irqCallback(void (*callback)()) {}
|
|
static void CALLBACK GS_printf(int timeout, char *fmt, ...)
|
|
{
|
|
va_list list;
|
|
char msg[512];
|
|
|
|
va_start(list, fmt);
|
|
vsprintf(msg, fmt, list);
|
|
va_end(list);
|
|
|
|
Console::WriteLn(msg);
|
|
}
|
|
|
|
// PAD
|
|
_PADopen PADopen;
|
|
_PADstartPoll PADstartPoll;
|
|
_PADpoll PADpoll;
|
|
_PADquery PADquery;
|
|
_PADupdate PADupdate;
|
|
_PADkeyEvent PADkeyEvent;
|
|
_PADsetSlot PADsetSlot;
|
|
_PADqueryMtap PADqueryMtap;
|
|
|
|
void PAD_update( u32 padslot ) { }
|
|
|
|
// SIO[2]
|
|
/*
|
|
_SIOinit SIOinit[2][9];
|
|
_SIOopen SIOopen[2][9];
|
|
_SIOclose SIOclose[2][9];
|
|
_SIOshutdown SIOshutdown[2][9];
|
|
_SIOstartPoll SIOstartPoll[2][9];
|
|
_SIOpoll SIOpoll[2][9];
|
|
_SIOquery SIOquery[2][9];
|
|
|
|
_SIOconfigure SIOconfigure[2][9];
|
|
_SIOtest SIOtest[2][9];
|
|
_SIOabout SIOabout[2][9];*/
|
|
|
|
// SPU2
|
|
_SPU2open SPU2open;
|
|
_SPU2write SPU2write;
|
|
_SPU2read SPU2read;
|
|
_SPU2readDMA4Mem SPU2readDMA4Mem;
|
|
_SPU2writeDMA4Mem SPU2writeDMA4Mem;
|
|
_SPU2interruptDMA4 SPU2interruptDMA4;
|
|
_SPU2readDMA7Mem SPU2readDMA7Mem;
|
|
_SPU2writeDMA7Mem SPU2writeDMA7Mem;
|
|
_SPU2setDMABaseAddr SPU2setDMABaseAddr;
|
|
_SPU2interruptDMA7 SPU2interruptDMA7;
|
|
_SPU2ReadMemAddr SPU2ReadMemAddr;
|
|
_SPU2setupRecording SPU2setupRecording;
|
|
_SPU2WriteMemAddr SPU2WriteMemAddr;
|
|
_SPU2irqCallback SPU2irqCallback;
|
|
|
|
_SPU2setClockPtr SPU2setClockPtr;
|
|
_SPU2async SPU2async;
|
|
|
|
|
|
// DEV9
|
|
_DEV9open DEV9open;
|
|
_DEV9read8 DEV9read8;
|
|
_DEV9read16 DEV9read16;
|
|
_DEV9read32 DEV9read32;
|
|
_DEV9write8 DEV9write8;
|
|
_DEV9write16 DEV9write16;
|
|
_DEV9write32 DEV9write32;
|
|
_DEV9readDMA8Mem DEV9readDMA8Mem;
|
|
_DEV9writeDMA8Mem DEV9writeDMA8Mem;
|
|
_DEV9irqCallback DEV9irqCallback;
|
|
_DEV9irqHandler DEV9irqHandler;
|
|
|
|
// USB
|
|
_USBopen USBopen;
|
|
_USBread8 USBread8;
|
|
_USBread16 USBread16;
|
|
_USBread32 USBread32;
|
|
_USBwrite8 USBwrite8;
|
|
_USBwrite16 USBwrite16;
|
|
_USBwrite32 USBwrite32;
|
|
_USBasync USBasync;
|
|
|
|
_USBirqCallback USBirqCallback;
|
|
_USBirqHandler USBirqHandler;
|
|
_USBsetRAM USBsetRAM;
|
|
|
|
// FW
|
|
_FWopen FWopen;
|
|
_FWread32 FWread32;
|
|
_FWwrite32 FWwrite32;
|
|
_FWirqCallback FWirqCallback;
|
|
|
|
DEV9handler dev9Handler;
|
|
USBhandler usbHandler;
|
|
uptr pDsp;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Important: Contents of this array must match the order of the contents of the
|
|
// LegacyPluginAPI_Common structure defined in Plugins.h.
|
|
//
|
|
static const LegacyApi_CommonMethod s_MethMessCommon[] =
|
|
{
|
|
{ "init", NULL },
|
|
{ "close", NULL },
|
|
{ "shutdown", NULL },
|
|
|
|
{ "freeze", (vMeth*)fallback_freeze },
|
|
{ "test", (vMeth*)fallback_test },
|
|
{ "configure", fallback_configure },
|
|
{ "about", fallback_about },
|
|
|
|
{ NULL }
|
|
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GS Mess!
|
|
// ----------------------------------------------------------------------------
|
|
static const LegacyApi_ReqMethod s_MethMessReq_GS[] =
|
|
{
|
|
{ "GSopen", (vMeth**)&GSopen, NULL },
|
|
{ "GSvsync", (vMeth**)&GSvsync, NULL },
|
|
{ "GSgifTransfer1", (vMeth**)&GSgifTransfer1, NULL },
|
|
{ "GSgifTransfer2", (vMeth**)&GSgifTransfer2, NULL },
|
|
{ "GSgifTransfer3", (vMeth**)&GSgifTransfer3, NULL },
|
|
{ "GSreadFIFO2", (vMeth**)&GSreadFIFO2, NULL },
|
|
|
|
{ "GSmakeSnapshot", (vMeth**)&GSmakeSnapshot, (vMeth*)GS_makeSnapshot },
|
|
{ "GSirqCallback", (vMeth**)&GSirqCallback, (vMeth*)GS_irqCallback },
|
|
{ "GSprintf", (vMeth**)&GSprintf, (vMeth*)GS_printf },
|
|
{ "GSsetBaseMem", (vMeth**)&GSsetBaseMem, NULL },
|
|
{ "GSwriteCSR", (vMeth**)&GSwriteCSR, NULL },
|
|
{ NULL }
|
|
};
|
|
|
|
static const LegacyApi_OptMethod s_MethMessOpt_GS[] =
|
|
{
|
|
{ "GSreset", (vMeth**)&GSreset },
|
|
{ "GSsetupRecording", (vMeth**)&GSsetupRecording },
|
|
{ "GSsetGameCRC", (vMeth**)&GSsetGameCRC },
|
|
{ "GSsetFrameSkip", (vMeth**)&GSsetFrameSkip },
|
|
{ "GSsetFrameLimit", (vMeth**)&GSsetFrameLimit },
|
|
{ "GSchangeSaveState",(vMeth**)&GSchangeSaveState },
|
|
{ "GSmakeSnapshot2", (vMeth**)&GSmakeSnapshot2 },
|
|
{ "GSgifSoftReset", (vMeth**)&GSgifSoftReset },
|
|
{ "GSreadFIFO", (vMeth**)&GSreadFIFO },
|
|
{ NULL }
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// PAD Mess!
|
|
// ----------------------------------------------------------------------------
|
|
static const LegacyApi_ReqMethod s_MethMessReq_PAD[] =
|
|
{
|
|
{ "PADopen", (vMeth**)&PADopen, NULL },
|
|
{ "PADstartPoll", (vMeth**)&PADstartPoll, NULL },
|
|
{ "PADpoll", (vMeth**)&PADpoll, NULL },
|
|
{ "PADquery", (vMeth**)&PADquery, NULL },
|
|
{ "PADkeyEvent", (vMeth**)&PADkeyEvent, NULL },
|
|
|
|
// fixme - Following functions are new as of some revison post-0.9.6, and
|
|
// are for multitap support only. They should either be optional or offer
|
|
// NOP fallbacks, to allow older plugins to retain functionality.
|
|
{ "PADsetSlot", (vMeth**)&PADsetSlot, NULL },
|
|
{ "PADqueryMtap", (vMeth**)&PADqueryMtap, NULL },
|
|
{ NULL },
|
|
};
|
|
|
|
static const LegacyApi_OptMethod s_MethMessOpt_PAD[] =
|
|
{
|
|
{ "PADupdate", (vMeth**)&PADupdate },
|
|
{ NULL },
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// CDVD Mess!
|
|
// ----------------------------------------------------------------------------
|
|
void CALLBACK CDVD_newDiskCB(void (*callback)()) {}
|
|
|
|
extern int lastReadSize;
|
|
s32 CALLBACK CDVD_getBuffer2(u8* buffer)
|
|
{
|
|
int ret;
|
|
|
|
// TEMP: until I fix all the plugins to use this function style
|
|
u8* pb = CDVD->getBuffer();
|
|
if(pb != NULL)
|
|
{
|
|
memcpy(buffer,pb,lastReadSize);
|
|
ret = 0;
|
|
}
|
|
else ret = -2;
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode)
|
|
{
|
|
if(CDVD->readTrack(lsn,mode) < 0)
|
|
return -1;
|
|
|
|
// TEMP: until all the plugins use the new CDVDgetBuffer style
|
|
switch (mode)
|
|
{
|
|
case CDVD_MODE_2352:
|
|
lastReadSize = 2352;
|
|
break;
|
|
case CDVD_MODE_2340:
|
|
lastReadSize = 2340;
|
|
break;
|
|
case CDVD_MODE_2328:
|
|
lastReadSize = 2328;
|
|
break;
|
|
case CDVD_MODE_2048:
|
|
lastReadSize = 2048;
|
|
break;
|
|
}
|
|
return CDVD->getBuffer2(buffer);
|
|
}
|
|
|
|
s32 CALLBACK CDVD_getDualInfo(s32* dualType, u32* layer1Start)
|
|
{
|
|
u8 toc[2064];
|
|
|
|
// if error getting toc, settle for single layer disc ;)
|
|
if(CDVD->getTOC(toc))
|
|
return 0;
|
|
|
|
if(toc[14] & 0x60)
|
|
{
|
|
if(toc[14] & 0x10)
|
|
{
|
|
// otp dvd
|
|
*dualType = 2;
|
|
*layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1;
|
|
}
|
|
else
|
|
{
|
|
// ptp dvd
|
|
*dualType = 1;
|
|
*layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// single layer dvd
|
|
*dualType = 0;
|
|
*layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void CALLBACK CDVDplugin_Close()
|
|
{
|
|
g_plugins->Close( PluginId_CDVD );
|
|
}
|
|
|
|
CDVD_API CDVDapi_Plugin =
|
|
{
|
|
CDVDplugin_Close,
|
|
|
|
// The rest are filled in by the plugin manager
|
|
NULL
|
|
};
|
|
CDVD_API* CDVD = NULL;
|
|
|
|
static const LegacyApi_ReqMethod s_MethMessReq_CDVD[] =
|
|
{
|
|
{ "CDVDopen", (vMeth**)&CDVDapi_Plugin.open, NULL },
|
|
{ "CDVDreadTrack", (vMeth**)&CDVDapi_Plugin.readTrack, NULL },
|
|
{ "CDVDgetBuffer", (vMeth**)&CDVDapi_Plugin.getBuffer, NULL },
|
|
{ "CDVDreadSubQ", (vMeth**)&CDVDapi_Plugin.readSubQ, NULL },
|
|
{ "CDVDgetTN", (vMeth**)&CDVDapi_Plugin.getTN, NULL },
|
|
{ "CDVDgetTD", (vMeth**)&CDVDapi_Plugin.getTD, NULL },
|
|
{ "CDVDgetTOC", (vMeth**)&CDVDapi_Plugin.getTOC, NULL },
|
|
{ "CDVDgetDiskType", (vMeth**)&CDVDapi_Plugin.getDiskType, NULL },
|
|
{ "CDVDgetTrayStatus",(vMeth**)&CDVDapi_Plugin.getTrayStatus, NULL },
|
|
{ "CDVDctrlTrayOpen", (vMeth**)&CDVDapi_Plugin.ctrlTrayOpen, NULL },
|
|
{ "CDVDctrlTrayClose",(vMeth**)&CDVDapi_Plugin.ctrlTrayClose, NULL },
|
|
{ "CDVDnewDiskCB", (vMeth**)&CDVDapi_Plugin.newDiskCB, (vMeth*)CDVD_newDiskCB },
|
|
|
|
{ "CDVDreadSector", (vMeth**)&CDVDapi_Plugin.readSector, (vMeth*)CDVD_readSector },
|
|
{ "CDVDgetBuffer2", (vMeth**)&CDVDapi_Plugin.getBuffer2, (vMeth*)CDVD_getBuffer2 },
|
|
{ "CDVDgetDualInfo", (vMeth**)&CDVDapi_Plugin.getDualInfo, (vMeth*)CDVD_getDualInfo },
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
static const LegacyApi_OptMethod s_MethMessOpt_CDVD[] =
|
|
{
|
|
{ NULL }
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SPU2 Mess!
|
|
// ----------------------------------------------------------------------------
|
|
static const LegacyApi_ReqMethod s_MethMessReq_SPU2[] =
|
|
{
|
|
{ "SPU2open", (vMeth**)SPU2open, NULL },
|
|
{ "SPU2write", (vMeth**)SPU2write, NULL },
|
|
{ "SPU2read", (vMeth**)SPU2read, NULL },
|
|
{ "SPU2readDMA4Mem", (vMeth**)SPU2readDMA4Mem, NULL },
|
|
{ "SPU2readDMA7Mem", (vMeth**)SPU2readDMA7Mem, NULL },
|
|
{ "SPU2writeDMA4Mem", (vMeth**)SPU2writeDMA4Mem, NULL },
|
|
{ "SPU2writeDMA7Mem", (vMeth**)SPU2writeDMA7Mem, NULL },
|
|
{ "SPU2interruptDMA4", (vMeth**)SPU2interruptDMA4, NULL },
|
|
{ "SPU2interruptDMA7", (vMeth**)SPU2interruptDMA7, NULL },
|
|
{ "SPU2setDMABaseAddr", (vMeth**)SPU2setDMABaseAddr,NULL },
|
|
{ "SPU2ReadMemAddr", (vMeth**)SPU2ReadMemAddr, NULL },
|
|
{ "SPU2irqCallback", (vMeth**)SPU2irqCallback, NULL },
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
static const LegacyApi_OptMethod s_MethMessOpt_SPU2[] =
|
|
{
|
|
{ "SPU2setClockPtr", (vMeth**)SPU2setClockPtr },
|
|
{ "SPU2async", (vMeth**)SPU2async },
|
|
{ "SPU2WriteMemAddr", (vMeth**)SPU2WriteMemAddr },
|
|
{ "SPU2setupRecording", (vMeth**)SPU2setupRecording },
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// DEV9 Mess!
|
|
// ----------------------------------------------------------------------------
|
|
static const LegacyApi_ReqMethod s_MethMessReq_DEV9[] =
|
|
{
|
|
{ "DEV9open", (vMeth**)&DEV9open, NULL },
|
|
{ "DEV9read8", (vMeth**)&DEV9read8, NULL },
|
|
{ "DEV9read16", (vMeth**)&DEV9read16, NULL },
|
|
{ "DEV9read32", (vMeth**)&DEV9read32, NULL },
|
|
{ "DEV9write8", (vMeth**)&DEV9write8, NULL },
|
|
{ "DEV9write16", (vMeth**)&DEV9write16, NULL },
|
|
{ "DEV9write32", (vMeth**)&DEV9write32, NULL },
|
|
{ "DEV9readDMA8Mem", (vMeth**)&DEV9readDMA8Mem, NULL },
|
|
{ "DEV9writeDMA8Mem", (vMeth**)&DEV9writeDMA8Mem, NULL },
|
|
{ "DEV9irqCallback", (vMeth**)&DEV9irqCallback, NULL },
|
|
{ "DEV9irqHandler", (vMeth**)&DEV9irqHandler, NULL },
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
static const LegacyApi_OptMethod s_MethMessOpt_DEV9[] =
|
|
{
|
|
{ NULL }
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// USB Mess!
|
|
// ----------------------------------------------------------------------------
|
|
static const LegacyApi_ReqMethod s_MethMessReq_USB[] =
|
|
{
|
|
{ "USBopen", (vMeth**)&USBopen, NULL },
|
|
{ "USBread8", (vMeth**)&USBread8, NULL },
|
|
{ "USBread16", (vMeth**)&USBread16, NULL },
|
|
{ "USBread32", (vMeth**)&USBread32, NULL },
|
|
{ "USBwrite8", (vMeth**)&USBwrite8, NULL },
|
|
{ "USBwrite16", (vMeth**)&USBwrite16, NULL },
|
|
{ "USBwrite32", (vMeth**)&USBwrite32, NULL },
|
|
{ "USBirqCallback", (vMeth**)&USBirqCallback, NULL },
|
|
{ "USBirqHandler", (vMeth**)&USBirqHandler, NULL },
|
|
};
|
|
|
|
static const LegacyApi_OptMethod s_MethMessOpt_USB[] =
|
|
{
|
|
{ "USBasync", (vMeth**)&USBasync },
|
|
{ NULL }
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// FW Mess!
|
|
// ----------------------------------------------------------------------------
|
|
static const LegacyApi_ReqMethod s_MethMessReq_FW[] =
|
|
{
|
|
{ "FWopen", (vMeth**)&FWopen, NULL },
|
|
{ "FWread32", (vMeth**)&FWread32, NULL },
|
|
{ "FWwrite32", (vMeth**)&FWwrite32, NULL },
|
|
{ "FWirqCallback", (vMeth**)&FWirqCallback, NULL },
|
|
};
|
|
|
|
static const LegacyApi_OptMethod s_MethMessOpt_FW[] =
|
|
{
|
|
{ NULL }
|
|
};
|
|
|
|
static const LegacyApi_ReqMethod* const s_MethMessReq[] =
|
|
{
|
|
s_MethMessReq_CDVD,
|
|
s_MethMessReq_GS,
|
|
s_MethMessReq_PAD,
|
|
s_MethMessReq_SPU2,
|
|
s_MethMessReq_USB,
|
|
s_MethMessReq_FW,
|
|
s_MethMessReq_DEV9
|
|
};
|
|
|
|
static const LegacyApi_OptMethod* const s_MethMessOpt[] =
|
|
{
|
|
s_MethMessOpt_CDVD,
|
|
s_MethMessOpt_GS,
|
|
s_MethMessOpt_PAD,
|
|
s_MethMessOpt_SPU2,
|
|
s_MethMessOpt_USB,
|
|
s_MethMessOpt_FW,
|
|
s_MethMessOpt_DEV9
|
|
};
|
|
|
|
PluginManager *g_plugins = NULL;
|
|
|
|
Exception::NotPcsxPlugin::NotPcsxPlugin( const wxString& objname ) :
|
|
Stream( objname, wxLt("File is not a PCSX2 plugin") ) {}
|
|
|
|
Exception::NotPcsxPlugin::NotPcsxPlugin( const PluginsEnum_t& pid ) :
|
|
Stream( wxString::FromUTF8( tbl_PluginInfo[pid].shortname ), wxLt("File is not a PCSX2 plugin") ) {}
|
|
|
|
|
|
void PluginManager::BindCommon( PluginsEnum_t pid )
|
|
{
|
|
const LegacyApi_CommonMethod* current = s_MethMessCommon;
|
|
int fid = 0; // function id
|
|
VoidMethod** target = (VoidMethod**)&m_CommonBindings[pid];
|
|
|
|
while( current->MethodName != NULL )
|
|
{
|
|
*target = (VoidMethod*)m_libs[pid].GetSymbol( current->GetMethodName( pid ) );
|
|
target++;
|
|
current++;
|
|
}
|
|
}
|
|
|
|
void PluginManager::BindRequired( PluginsEnum_t pid )
|
|
{
|
|
const LegacyApi_ReqMethod* current = s_MethMessReq[pid];
|
|
const wxDynamicLibrary& lib = m_libs[pid];
|
|
|
|
while( current->MethodName != NULL )
|
|
{
|
|
*(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );
|
|
|
|
if( *(current->Dest) == NULL )
|
|
*(current->Dest) = current->Fallback;
|
|
|
|
if( *(current->Dest) == NULL )
|
|
{
|
|
throw Exception::NotPcsxPlugin( pid );
|
|
}
|
|
current++;
|
|
}
|
|
}
|
|
|
|
void PluginManager::BindOptional( PluginsEnum_t pid )
|
|
{
|
|
const LegacyApi_OptMethod* current = s_MethMessOpt[pid];
|
|
const wxDynamicLibrary& lib = m_libs[pid];
|
|
|
|
while( current->MethodName != NULL )
|
|
{
|
|
*(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );
|
|
current++;
|
|
}
|
|
}
|
|
|
|
// Exceptions:
|
|
// FileNotFound - Thrown if one of th configured plugins doesn't exist.
|
|
// NotPcsxPlugin - Thrown if one of the configured plugins is an invalid or unsupported DLL
|
|
void PluginManager::LoadPlugins()
|
|
{
|
|
if( m_loaded ) return;
|
|
m_loaded = true;
|
|
|
|
for( int i=0; i<PluginId_Count; ++i )
|
|
{
|
|
PluginsEnum_t pid = (PluginsEnum_t)i;
|
|
wxString plugpath( g_Conf->FullpathTo( pid ) );
|
|
|
|
if( !wxFile::Exists( plugpath ) )
|
|
throw Exception::FileNotFound( plugpath );
|
|
|
|
if( !m_libs[i].Load( plugpath ) )
|
|
throw Exception::NotPcsxPlugin( plugpath );
|
|
|
|
// Try to enumerate the new v2.0 plugin interface first.
|
|
// If that fails, fall back on the old style interface.
|
|
|
|
//m_libs[i].GetSymbol( L"PS2E_InitAPI" );
|
|
|
|
// Bind Required Functions
|
|
// (generate critical error if binding fails)
|
|
|
|
BindCommon( pid );
|
|
BindRequired( pid );
|
|
BindOptional( pid );
|
|
|
|
// Bind Optional Functions
|
|
// (leave pointer null and do not generate error)
|
|
|
|
}
|
|
}
|
|
|
|
void PluginManager::Open( PluginsEnum_t pid )
|
|
{
|
|
// Each Open needs to be called explicitly. >_<
|
|
}
|
|
|
|
void PluginManager::Close( PluginsEnum_t pid )
|
|
{
|
|
if( m_IsOpened[pid] )
|
|
{
|
|
m_IsOpened[pid] = false;
|
|
m_CommonBindings[pid].Close();
|
|
}
|
|
}
|
|
|
|
void PluginManager::Init( PluginsEnum_t pid )
|
|
{
|
|
if( !m_IsInitialized[pid] )
|
|
{
|
|
m_IsInitialized[pid] = true;
|
|
m_CommonBindings[pid].Init();
|
|
}
|
|
}
|
|
|
|
void PluginManager::Shutdown( PluginsEnum_t pid )
|
|
{
|
|
if( m_IsInitialized[pid] )
|
|
{
|
|
m_IsInitialized[pid] = false;
|
|
m_CommonBindings[pid].Shutdown();
|
|
}
|
|
}
|
|
|
|
void PluginManager::Freeze( PluginsEnum_t pid, int mode, freezeData* data )
|
|
{
|
|
m_CommonBindings[pid].Freeze( mode, data );
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Thread Safety:
|
|
// This function should only be called by the Main GUI thread and the GS thread (for GS states only),
|
|
// as it has special handlers to ensure that GS freeze commands are executed appropriately on the
|
|
// GS thread.
|
|
//
|
|
void PluginManager::Freeze( PluginsEnum_t pid, SaveState& state )
|
|
{
|
|
if( pid == PluginId_GS && wxThread::IsMain() )
|
|
{
|
|
// Need to send the GS freeze request on the GS thread.
|
|
}
|
|
else
|
|
{
|
|
state.FreezePlugin( tbl_PluginInfo[pid].shortname, m_CommonBindings[pid].Freeze );
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// This overload of Freeze performs savestate freeze operation on *all* plugins,
|
|
// as according to the order in PluignsEnum_t.
|
|
//
|
|
// Thread Safety:
|
|
// This function should only be called by the Main GUI thread and the GS thread (for GS states only),
|
|
// as it has special handlers to ensure that GS freeze commands are executed appropriately on the
|
|
// GS thread.
|
|
//
|
|
void PluginManager::Freeze( SaveState& state )
|
|
{
|
|
for( int i=0; i<PluginId_Count; ++i )
|
|
Freeze( (PluginsEnum_t)i, state );
|
|
}
|
|
|
|
void InitPlugins()
|
|
{
|
|
/*if (plugins_initialized) return;
|
|
|
|
// Ensure plugins have been loaded....
|
|
LoadPlugins();*/
|
|
|
|
//if( !plugins_loaded ) throw Exception::InvalidOperation( "Bad coder mojo - InitPlugins called prior to plugins having been loaded." );
|
|
|
|
/*if (ReportError(GSinit(), "GSinit")) return -1;
|
|
if (ReportError(PAD1init(1), "PAD1init")) return -1;
|
|
if (ReportError(PAD2init(2), "PAD2init")) return -1;
|
|
if (ReportError(SPU2init(), "SPU2init")) return -1;
|
|
|
|
if (ReportError(DoCDVDinit(), "CDVDinit")) return -1;
|
|
|
|
if (ReportError(DEV9init(), "DEV9init")) return -1;
|
|
if (ReportError(USBinit(), "USBinit")) return -1;
|
|
if (ReportError(FWinit(), "FWinit")) return -1;
|
|
|
|
only_loading_elf = false;
|
|
plugins_initialized = true;
|
|
return 0;*/
|
|
}
|
|
|
|
void OpenPlugins()
|
|
{
|
|
/*if (!plugins_initialized)
|
|
{
|
|
if( InitPlugins() == -1 ) return -1;
|
|
}*/
|
|
|
|
/*if ((!OpenCDVD(pTitleFilename)) || (!OpenGS()) || (!OpenPAD1()) || (!OpenPAD2()) ||
|
|
(!OpenSPU2()) || (!OpenDEV9()) || (!OpenUSB()) || (!OpenFW()))
|
|
return -1;
|
|
|
|
if (!only_loading_elf) cdvdDetectDisk();
|
|
|
|
return 0;*/
|
|
}
|
|
|
|
|
|
void ClosePlugins( bool closegs )
|
|
{
|
|
}
|
|
|
|
void ShutdownPlugins()
|
|
{
|
|
}
|
|
|
|
void CloseGS()
|
|
{
|
|
}
|
|
|
|
|
|
#ifdef _not_wxWidgets_Land_
|
|
|
|
namespace PluginTypes
|
|
{
|
|
enum PluginTypes
|
|
{
|
|
GS = 0,
|
|
PAD,
|
|
PAD1,
|
|
PAD2,
|
|
SPU2,
|
|
CDVD,
|
|
DEV9,
|
|
USB,
|
|
FW
|
|
};
|
|
}
|
|
|
|
int PS2E_LT[9] = {
|
|
PS2E_LT_GS,
|
|
PS2E_LT_PAD,PS2E_LT_PAD, PS2E_LT_PAD,
|
|
PS2E_LT_SPU2,
|
|
PS2E_LT_CDVD,
|
|
PS2E_LT_DEV9,
|
|
PS2E_LT_USB,
|
|
PS2E_LT_FW};
|
|
|
|
int PS2E_VERSION[9] = {
|
|
PS2E_GS_VERSION,
|
|
PS2E_PAD_VERSION,PS2E_PAD_VERSION, PS2E_PAD_VERSION,
|
|
PS2E_SPU2_VERSION,
|
|
PS2E_CDVD_VERSION,
|
|
PS2E_DEV9_VERSION,
|
|
PS2E_USB_VERSION,
|
|
PS2E_FW_VERSION};
|
|
|
|
#define Sfy(x) #x
|
|
#define Strfy(x) Sfy(x)
|
|
#define MapSymbolVarType(var,type,name) var = (type)SysLoadSym(drv,Strfy(name))
|
|
#define MapSymbolVar(var,name) MapSymbolVarType(var,_##name,name)
|
|
#define MapSymbolVar_Fallback(var,name,fallback) if((MapSymbolVar(var,name))==NULL) var = fallback
|
|
#define MapSymbolVar_Error(var,name) if((MapSymbolVar(var,name))==NULL) \
|
|
{ \
|
|
const char* errString = SysLibError(); \
|
|
Msgbox::Alert("%s: Error loading %hs: %s", params &filename, #name, errString); \
|
|
return -1; \
|
|
}
|
|
|
|
#define MapSymbol(name) MapSymbolVar(name,name)
|
|
#define MapSymbol_Fallback(name,fallback) MapSymbolVar_Fallback(name,name,fallback)
|
|
#define MapSymbol_Error(name) MapSymbolVar_Error(name,name)
|
|
|
|
#define MapSymbol2(base,name) MapSymbolVar(base##_plugin.name,base##name)
|
|
#define MapSymbol2_Fallback(base,name,fallback) MapSymbolVar_Fallback(base##_plugin.name,base##name,fallback)
|
|
#define MapSymbol2_Error(base,name) MapSymbolVar_Error(base##_plugin.name,base##name)
|
|
|
|
// for pad1/2
|
|
#define MapSymbolPAD(var,name) MapSymbolVar(var##name,PAD##name)
|
|
#define MapSymbolPAD_Fallback(var,name) if((MapSymbolVarType(var##name,_PAD##name,PAD##name))==NULL) var##name = var##_##name
|
|
#define MapSymbolPAD_Error(var,name) MapSymbolVar_Error(var##name,PAD##name)
|
|
|
|
void *GSplugin;
|
|
|
|
static int _TestPS2Esyms(void* drv, int type, int expected_version, const wxString& filename)
|
|
{
|
|
_PS2EgetLibType PS2EgetLibType;
|
|
_PS2EgetLibVersion2 PS2EgetLibVersion2;
|
|
_PS2EgetLibName PS2EgetLibName;
|
|
|
|
MapSymbol_Error(PS2EgetLibType);
|
|
MapSymbol_Error(PS2EgetLibVersion2);
|
|
MapSymbol_Error(PS2EgetLibName);
|
|
|
|
int actual_version = ((PS2EgetLibVersion2(type) >> 16)&0xff);
|
|
|
|
if( actual_version != expected_version) {
|
|
Msgbox::Alert("Can't load '%s', wrong PS2E version (%x != %x)", params filename.c_str(), actual_version, expected_version);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static __forceinline bool TestPS2Esyms(void* &drv, PluginTypes::PluginTypes type, const string& filename)
|
|
{
|
|
if (_TestPS2Esyms(drv, PS2E_LT[type],PS2E_VERSION[type],filename) < 0) return false;
|
|
return true;
|
|
}
|
|
|
|
s32 CALLBACK GS_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
|
|
void CALLBACK GS_keyEvent(keyEvent *ev) {}
|
|
void CALLBACK GS_makeSnapshot(const char *path) {}
|
|
void CALLBACK GS_irqCallback(void (*callback)()) {}
|
|
void CALLBACK GS_configure() {}
|
|
void CALLBACK GS_about() {}
|
|
s32 CALLBACK GS_test() { return 0; }
|
|
|
|
int LoadGSplugin(const wxString& filename)
|
|
{
|
|
void *drv;
|
|
|
|
GSplugin = SysLoadLibrary(filename.c_str());
|
|
if (GSplugin == NULL) { Msgbox::Alert ("Could Not Load GS Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = GSplugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::GS, filename)) return -1;
|
|
MapSymbol_Error(GSinit);
|
|
MapSymbol_Error(GSshutdown);
|
|
MapSymbol_Error(GSopen);
|
|
MapSymbol_Error(GSclose);
|
|
MapSymbol_Error(GSgifTransfer1);
|
|
MapSymbol_Error(GSgifTransfer2);
|
|
MapSymbol_Error(GSgifTransfer3);
|
|
MapSymbol_Error(GSreadFIFO);
|
|
MapSymbol(GSgetLastTag);
|
|
MapSymbol(GSreadFIFO2); // optional
|
|
MapSymbol_Error(GSvsync);
|
|
|
|
MapSymbol_Fallback(GSkeyEvent,GS_keyEvent);
|
|
MapSymbol(GSchangeSaveState);
|
|
MapSymbol(GSgifSoftReset);
|
|
MapSymbol_Fallback(GSmakeSnapshot,GS_makeSnapshot);
|
|
MapSymbol_Fallback(GSirqCallback,GS_irqCallback);
|
|
MapSymbol_Fallback(GSprintf,GS_printf);
|
|
MapSymbol_Error(GSsetBaseMem);
|
|
MapSymbol(GSsetGameCRC);
|
|
MapSymbol_Error(GSreset);
|
|
MapSymbol_Error(GSwriteCSR);
|
|
MapSymbol(GSmakeSnapshot2);
|
|
MapSymbol(GSgetDriverInfo);
|
|
|
|
MapSymbol(GSsetFrameSkip);
|
|
MapSymbol(GSsetFrameLimit);
|
|
MapSymbol(GSsetupRecording);
|
|
|
|
#ifdef _WIN32
|
|
MapSymbol(GSsetWindowInfo);
|
|
#endif
|
|
MapSymbol_Fallback(GSfreeze,GS_freeze);
|
|
MapSymbol_Fallback(GSconfigure,GS_configure);
|
|
MapSymbol_Fallback(GSabout,GS_about);
|
|
MapSymbol_Fallback(GStest,GS_test);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *PAD1plugin;
|
|
|
|
void CALLBACK PAD1_configure() {}
|
|
void CALLBACK PAD1_about() {}
|
|
s32 CALLBACK PAD1_test() { return 0; }
|
|
s32 CALLBACK PAD1_freeze(int mode, freezeData *data) { if (mode == FREEZE_SIZE) data->size = 0; return 0; }
|
|
s32 CALLBACK PAD1_setSlot(u8 port, u8 slot) { return slot == 1; }
|
|
s32 CALLBACK PAD1_queryMtap(u8 port) { return 0; }
|
|
|
|
int LoadPAD1plugin(const wxString& filename) {
|
|
void *drv;
|
|
|
|
PAD1plugin = SysLoadLibrary(filename.c_str());
|
|
if (PAD1plugin == NULL) { Msgbox::Alert("Could Not Load PAD1 Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = PAD1plugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::PAD, filename)) return -1;
|
|
MapSymbolPAD_Error(PAD1,init);
|
|
MapSymbolPAD_Error(PAD1,shutdown);
|
|
MapSymbolPAD_Error(PAD1,open);
|
|
MapSymbolPAD_Error(PAD1,close);
|
|
MapSymbolPAD_Error(PAD1,keyEvent);
|
|
MapSymbolPAD_Error(PAD1,startPoll);
|
|
MapSymbolPAD_Error(PAD1,poll);
|
|
MapSymbolPAD_Error(PAD1,query);
|
|
MapSymbolPAD(PAD1,update);
|
|
|
|
MapSymbolPAD(PAD1,gsDriverInfo);
|
|
MapSymbolPAD_Fallback(PAD1,configure);
|
|
MapSymbolPAD_Fallback(PAD1,about);
|
|
MapSymbolPAD_Fallback(PAD1,test);
|
|
MapSymbolPAD_Fallback(PAD1,freeze);
|
|
MapSymbolPAD_Fallback(PAD1,setSlot);
|
|
MapSymbolPAD_Fallback(PAD1,queryMtap);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *PAD2plugin;
|
|
|
|
void CALLBACK PAD2_configure() {}
|
|
void CALLBACK PAD2_about() {}
|
|
s32 CALLBACK PAD2_test() { return 0; }
|
|
s32 CALLBACK PAD2_freeze(int mode, freezeData *data) { if (mode == FREEZE_SIZE) data->size = 0; return 0; }
|
|
s32 CALLBACK PAD2_setSlot(u8 port, u8 slot) { return slot == 1; }
|
|
s32 CALLBACK PAD2_queryMtap(u8 port) { return 0; }
|
|
|
|
int LoadPAD2plugin(const wxString& filename) {
|
|
void *drv;
|
|
|
|
PAD2plugin = SysLoadLibrary(filename.c_str());
|
|
if (PAD2plugin == NULL) { Msgbox::Alert("Could Not Load PAD2 Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = PAD2plugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::PAD, filename)) return -1;
|
|
MapSymbolPAD_Error(PAD2,init);
|
|
MapSymbolPAD_Error(PAD2,shutdown);
|
|
MapSymbolPAD_Error(PAD2,open);
|
|
MapSymbolPAD_Error(PAD2,close);
|
|
MapSymbolPAD_Error(PAD2,keyEvent);
|
|
MapSymbolPAD_Error(PAD2,startPoll);
|
|
MapSymbolPAD_Error(PAD2,poll);
|
|
MapSymbolPAD_Error(PAD2,query);
|
|
MapSymbolPAD(PAD2,update);
|
|
|
|
MapSymbolPAD(PAD2,gsDriverInfo);
|
|
MapSymbolPAD_Fallback(PAD2,configure);
|
|
MapSymbolPAD_Fallback(PAD2,about);
|
|
MapSymbolPAD_Fallback(PAD2,test);
|
|
MapSymbolPAD_Fallback(PAD2,freeze);
|
|
MapSymbolPAD_Fallback(PAD2,setSlot);
|
|
MapSymbolPAD_Fallback(PAD2,queryMtap);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *SPU2plugin;
|
|
|
|
s32 CALLBACK SPU2_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
|
|
void CALLBACK SPU2_configure() {}
|
|
void CALLBACK SPU2_about() {}
|
|
s32 CALLBACK SPU2_test() { return 0; }
|
|
|
|
int LoadSPU2plugin(const wxString& filename) {
|
|
void *drv;
|
|
|
|
SPU2plugin = SysLoadLibrary(filename.c_str());
|
|
if (SPU2plugin == NULL) { Msgbox::Alert("Could Not Load SPU2 Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = SPU2plugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::SPU2, filename)) return -1;
|
|
MapSymbol_Error(SPU2init);
|
|
MapSymbol_Error(SPU2shutdown);
|
|
MapSymbol_Error(SPU2open);
|
|
MapSymbol_Error(SPU2close);
|
|
MapSymbol_Error(SPU2write);
|
|
MapSymbol_Error(SPU2read);
|
|
MapSymbol_Error(SPU2readDMA4Mem);
|
|
MapSymbol_Error(SPU2writeDMA4Mem);
|
|
MapSymbol_Error(SPU2interruptDMA4);
|
|
MapSymbol_Error(SPU2readDMA7Mem);
|
|
MapSymbol_Error(SPU2writeDMA7Mem);
|
|
MapSymbol_Error(SPU2interruptDMA7);
|
|
MapSymbol(SPU2setDMABaseAddr);
|
|
MapSymbol_Error(SPU2ReadMemAddr);
|
|
MapSymbol_Error(SPU2WriteMemAddr);
|
|
MapSymbol_Error(SPU2irqCallback);
|
|
|
|
MapSymbol(SPU2setClockPtr);
|
|
|
|
MapSymbol(SPU2setupRecording);
|
|
|
|
MapSymbol_Fallback(SPU2freeze,SPU2_freeze);
|
|
MapSymbol_Fallback(SPU2configure,SPU2_configure);
|
|
MapSymbol_Fallback(SPU2about,SPU2_about);
|
|
MapSymbol_Fallback(SPU2test,SPU2_test);
|
|
MapSymbol(SPU2async);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *CDVDplugin;
|
|
|
|
|
|
int LoadCDVDplugin(const wxString& filename) {
|
|
void *drv;
|
|
|
|
CDVDplugin = SysLoadLibrary(filename.c_str());
|
|
if (CDVDplugin == NULL) { Msgbox::Alert("Could Not Load CDVD Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = CDVDplugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::CDVD, filename)) return -1;
|
|
MapSymbol2_Error(CDVD,init);
|
|
MapSymbol2_Error(CDVD,shutdown);
|
|
MapSymbol2_Error(CDVD,open);
|
|
MapSymbol2_Error(CDVD,close);
|
|
MapSymbol2_Error(CDVD,readTrack);
|
|
MapSymbol2_Error(CDVD,getBuffer);
|
|
MapSymbol2_Error(CDVD,readSubQ);
|
|
MapSymbol2_Error(CDVD,getTN);
|
|
MapSymbol2_Error(CDVD,getTD);
|
|
MapSymbol2_Error(CDVD,getTOC);
|
|
MapSymbol2_Error(CDVD,getDiskType);
|
|
MapSymbol2_Error(CDVD,getTrayStatus);
|
|
MapSymbol2_Error(CDVD,ctrlTrayOpen);
|
|
MapSymbol2_Error(CDVD,ctrlTrayClose);
|
|
|
|
MapSymbol2_Fallback(CDVD,configure,CDVD_configure);
|
|
MapSymbol2_Fallback(CDVD,about,CDVD_about);
|
|
MapSymbol2_Fallback(CDVD,test,CDVD_test);
|
|
MapSymbol2_Fallback(CDVD,newDiskCB,CDVD_newDiskCB);
|
|
|
|
MapSymbol2_Fallback(CDVD,readSector,CDVD_readSector);
|
|
MapSymbol2_Fallback(CDVD,getBuffer2,CDVD_getBuffer2);
|
|
MapSymbol2_Fallback(CDVD,getDualInfo,CDVD_getDualInfo);
|
|
|
|
CDVD->initCount = &cdvdInitCount;
|
|
cdvdInitCount=0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *DEV9plugin;
|
|
|
|
s32 CALLBACK DEV9_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
|
|
void CALLBACK DEV9_configure() {}
|
|
void CALLBACK DEV9_about() {}
|
|
s32 CALLBACK DEV9_test() { return 0; }
|
|
|
|
int LoadDEV9plugin(const wxString& filename) {
|
|
void *drv;
|
|
|
|
DEV9plugin = SysLoadLibrary(filename.c_str());
|
|
if (DEV9plugin == NULL) { Msgbox::Alert("Could Not Load DEV9 Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = DEV9plugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::DEV9, filename)) return -1;
|
|
MapSymbol_Error(DEV9init);
|
|
MapSymbol_Error(DEV9shutdown);
|
|
MapSymbol_Error(DEV9open);
|
|
MapSymbol_Error(DEV9close);
|
|
MapSymbol_Error(DEV9read8);
|
|
MapSymbol_Error(DEV9read16);
|
|
MapSymbol_Error(DEV9read32);
|
|
MapSymbol_Error(DEV9write8);
|
|
MapSymbol_Error(DEV9write16);
|
|
MapSymbol_Error(DEV9write32);
|
|
MapSymbol_Error(DEV9readDMA8Mem);
|
|
MapSymbol_Error(DEV9writeDMA8Mem);
|
|
MapSymbol_Error(DEV9irqCallback);
|
|
MapSymbol_Error(DEV9irqHandler);
|
|
|
|
MapSymbol_Fallback(DEV9freeze,DEV9_freeze);
|
|
MapSymbol_Fallback(DEV9configure,DEV9_configure);
|
|
MapSymbol_Fallback(DEV9about,DEV9_about);
|
|
MapSymbol_Fallback(DEV9test,DEV9_test);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *USBplugin;
|
|
|
|
s32 CALLBACK USB_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
|
|
void CALLBACK USB_configure() {}
|
|
void CALLBACK USB_about() {}
|
|
s32 CALLBACK USB_test() { return 0; }
|
|
|
|
int LoadUSBplugin(const wxString& filename) {
|
|
void *drv;
|
|
|
|
USBplugin = SysLoadLibrary(filename.c_str());
|
|
if (USBplugin == NULL) { Msgbox::Alert("Could Not Load USB Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = USBplugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::USB, filename)) return -1;
|
|
MapSymbol_Error(USBinit);
|
|
MapSymbol_Error(USBshutdown);
|
|
MapSymbol_Error(USBopen);
|
|
MapSymbol_Error(USBclose);
|
|
MapSymbol_Error(USBread8);
|
|
MapSymbol_Error(USBread16);
|
|
MapSymbol_Error(USBread32);
|
|
MapSymbol_Error(USBwrite8);
|
|
MapSymbol_Error(USBwrite16);
|
|
MapSymbol_Error(USBwrite32);
|
|
MapSymbol_Error(USBirqCallback);
|
|
MapSymbol_Error(USBirqHandler);
|
|
MapSymbol_Error(USBsetRAM);
|
|
|
|
MapSymbol(USBasync);
|
|
|
|
MapSymbol_Fallback(USBfreeze,USB_freeze);
|
|
MapSymbol_Fallback(USBconfigure,USB_configure);
|
|
MapSymbol_Fallback(USBabout,USB_about);
|
|
MapSymbol_Fallback(USBtest,USB_test);
|
|
|
|
return 0;
|
|
}
|
|
void *FWplugin;
|
|
|
|
s32 CALLBACK FW_freeze(int mode, freezeData *data) { data->size = 0; return 0; }
|
|
void CALLBACK FW_configure() {}
|
|
void CALLBACK FW_about() {}
|
|
s32 CALLBACK FW_test() { return 0; }
|
|
|
|
int LoadFWplugin(const wxString& filename) {
|
|
void *drv;
|
|
|
|
FWplugin = SysLoadLibrary(filename.c_str());
|
|
if (FWplugin == NULL) { Msgbox::Alert("Could Not Load FW Plugin '%hs': %s", params &filename, SysLibError()); return -1; }
|
|
drv = FWplugin;
|
|
if (!TestPS2Esyms(drv, PluginTypes::FW, filename)) return -1;
|
|
MapSymbol_Error(FWinit);
|
|
MapSymbol_Error(FWshutdown);
|
|
MapSymbol_Error(FWopen);
|
|
MapSymbol_Error(FWclose);
|
|
MapSymbol_Error(FWread32);
|
|
MapSymbol_Error(FWwrite32);
|
|
MapSymbol_Error(FWirqCallback);
|
|
|
|
MapSymbol_Fallback(FWfreeze,FW_freeze);
|
|
MapSymbol_Fallback(FWconfigure,FW_configure);
|
|
MapSymbol_Fallback(FWabout,FW_about);
|
|
MapSymbol_Fallback(FWtest,FW_test);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct PluginOpenStatusFlags
|
|
{
|
|
u8 GS : 1
|
|
, CDVD : 1
|
|
, DEV9 : 1
|
|
, USB : 1
|
|
, SPU2 : 1
|
|
, PAD1 : 1
|
|
, PAD2 : 1
|
|
, FW : 1;
|
|
|
|
};
|
|
|
|
static PluginOpenStatusFlags OpenStatus = {0};
|
|
|
|
static bool plugins_loaded = false;
|
|
static bool plugins_initialized = false;
|
|
static bool only_loading_elf = false;
|
|
|
|
int LoadPlugins()
|
|
{
|
|
if (plugins_loaded) return 0;
|
|
|
|
if (LoadGSplugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.GS )) == -1) return -1;
|
|
if (LoadPAD1plugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.PAD1 )) == -1) return -1;
|
|
if (LoadPAD2plugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.PAD2 )) == -1) return -1;
|
|
if (LoadSPU2plugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.SPU2 )) == -1) return -1;
|
|
if (LoadCDVDplugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.CDVD )) == -1) return -1;
|
|
if (LoadDEV9plugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.DEV9 )) == -1) return -1;
|
|
if (LoadUSBplugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.USB )) == -1) return -1;
|
|
if (LoadFWplugin( Path::Combine( Config.Paths.Plugins, Config.Plugins.FW )) == -1) return -1;
|
|
|
|
plugins_loaded = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool ReportError(int err, const char *str)
|
|
{
|
|
if (err != 0)
|
|
{
|
|
Msgbox::Alert("%s error: %d", params str, err);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ReportError2(int err, const char *str)
|
|
{
|
|
if (err != 0)
|
|
{
|
|
Msgbox::Alert("Error Opening %s Plugin", params str, err);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int InitPlugins()
|
|
{
|
|
if (plugins_initialized) return 0;
|
|
|
|
// Ensure plugins have been loaded....
|
|
if (LoadPlugins() == -1) return -1;
|
|
|
|
//if( !plugins_loaded ) throw Exception::InvalidOperation( "Bad coder mojo - InitPlugins called prior to plugins having been loaded." );
|
|
|
|
if (ReportError(GSinit(), "GSinit")) return -1;
|
|
if (ReportError(PAD1init(1), "PAD1init")) return -1;
|
|
if (ReportError(PAD2init(2), "PAD2init")) return -1;
|
|
if (ReportError(SPU2init(), "SPU2init")) return -1;
|
|
|
|
if (ReportError(DoCDVDinit(), "CDVDinit")) return -1;
|
|
|
|
if (ReportError(DEV9init(), "DEV9init")) return -1;
|
|
if (ReportError(USBinit(), "USBinit")) return -1;
|
|
if (ReportError(FWinit(), "FWinit")) return -1;
|
|
|
|
only_loading_elf = false;
|
|
plugins_initialized = true;
|
|
return 0;
|
|
}
|
|
|
|
void ShutdownPlugins()
|
|
{
|
|
if (!plugins_initialized) return;
|
|
|
|
mtgsWaitGS();
|
|
ClosePlugins( true );
|
|
|
|
if (GSshutdown != NULL) GSshutdown();
|
|
|
|
if (PAD1shutdown != NULL) PAD1shutdown();
|
|
if (PAD2shutdown != NULL) PAD2shutdown();
|
|
|
|
if (SPU2shutdown != NULL) SPU2shutdown();
|
|
|
|
//if (CDVDshutdown != NULL) CDVDshutdown();
|
|
DoCDVDshutdown();
|
|
|
|
// safety measures, in case ISO is currently loaded.
|
|
if(cdvdInitCount>0)
|
|
CDVD_plugin.shutdown();
|
|
|
|
if (DEV9shutdown != NULL) DEV9shutdown();
|
|
if (USBshutdown != NULL) USBshutdown();
|
|
if (FWshutdown != NULL) FWshutdown();
|
|
|
|
plugins_initialized = false;
|
|
}
|
|
|
|
extern void spu2DMA4Irq();
|
|
extern void spu2DMA7Irq();
|
|
extern void spu2Irq();
|
|
|
|
bool OpenGS()
|
|
{
|
|
GSdriverInfo info;
|
|
|
|
if (!OpenStatus.GS)
|
|
{
|
|
if (ReportError2(gsOpen(), "GS"))
|
|
{
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
|
|
//Get the user input.
|
|
if (GSgetDriverInfo)
|
|
{
|
|
GSgetDriverInfo(&info);
|
|
if (PAD1gsDriverInfo) PAD1gsDriverInfo(&info);
|
|
if (PAD2gsDriverInfo) PAD2gsDriverInfo(&info);
|
|
}
|
|
OpenStatus.GS = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OpenCDVD(const char* pTitleFilename)
|
|
{
|
|
// Don't repetitively open the CDVD plugin if directly loading an elf file and open failed once already.
|
|
if (!OpenStatus.CDVD && !only_loading_elf)
|
|
{
|
|
//First, we need the data.
|
|
CDVD->newDiskCB(cdvdNewDiskCB);
|
|
|
|
if (DoCDVDopen(pTitleFilename) != 0)
|
|
{
|
|
if (g_Startup.BootMode != BootMode_Elf)
|
|
{
|
|
Msgbox::Alert("Error Opening CDVD Plugin");
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
Console::Notice("Running ELF File Without CDVD Plugin Support!");
|
|
only_loading_elf = true;
|
|
}
|
|
}
|
|
OpenStatus.CDVD = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OpenPAD1()
|
|
{
|
|
if (!OpenStatus.PAD1)
|
|
{
|
|
if (ReportError2(PAD1open((void *)&pDsp), "PAD1"))
|
|
{
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
OpenStatus.PAD1 = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OpenPAD2()
|
|
{
|
|
if (!OpenStatus.PAD2)
|
|
{
|
|
if (ReportError2(PAD2open((void *)&pDsp), "PAD2"))
|
|
{
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
OpenStatus.PAD2 = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OpenSPU2()
|
|
{
|
|
if (!OpenStatus.SPU2)
|
|
{
|
|
SPU2irqCallback(spu2Irq,spu2DMA4Irq,spu2DMA7Irq);
|
|
|
|
if (SPU2setDMABaseAddr != NULL) SPU2setDMABaseAddr((uptr)psxM);
|
|
if (SPU2setClockPtr != NULL) SPU2setClockPtr(&psxRegs.cycle);
|
|
|
|
if (ReportError2(SPU2open((void*)&pDsp), "SPU2"))
|
|
{
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
OpenStatus.SPU2 = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OpenDEV9()
|
|
{
|
|
if (!OpenStatus.DEV9)
|
|
{
|
|
DEV9irqCallback(dev9Irq);
|
|
dev9Handler = DEV9irqHandler();
|
|
|
|
if (ReportError2(DEV9open(&psxRegs.pc)/*((void *)&pDsp)*/, "DEV9"))
|
|
{
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
OpenStatus.DEV9 = true;
|
|
}
|
|
return true;
|
|
}
|
|
bool OpenUSB()
|
|
{
|
|
if (!OpenStatus.USB)
|
|
{
|
|
USBirqCallback(usbIrq);
|
|
usbHandler = USBirqHandler();
|
|
USBsetRAM(psxM);
|
|
|
|
if (ReportError2(USBopen((void *)&pDsp), "USB"))
|
|
{
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
OpenStatus.USB = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OpenFW()
|
|
{
|
|
if (!OpenStatus.FW)
|
|
{
|
|
FWirqCallback(fwIrq);
|
|
|
|
if (ReportError2(FWopen((void *)&pDsp), "FW"))
|
|
{
|
|
ClosePlugins(true);
|
|
return false;
|
|
}
|
|
OpenStatus.FW = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int OpenPlugins(const char* pTitleFilename)
|
|
{
|
|
if (!plugins_initialized)
|
|
{
|
|
// prevent a crash
|
|
if(CDVD.init == NULL)
|
|
CDVD = ISO; // CDVD_plugin;
|
|
|
|
if( InitPlugins() == -1 ) return -1;
|
|
}
|
|
|
|
if ((!OpenCDVD(pTitleFilename)) || (!OpenGS()) || (!OpenPAD1()) || (!OpenPAD2()) ||
|
|
(!OpenSPU2()) || (!OpenDEV9()) || (!OpenUSB()) || (!OpenFW()))
|
|
return -1;
|
|
|
|
if (!only_loading_elf) cdvdDetectDisk();
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define CLOSE_PLUGIN( name ) \
|
|
if( OpenStatus.name ) { \
|
|
name##close(); \
|
|
OpenStatus.name = false; \
|
|
}
|
|
|
|
#define CLOSE_PLUGIN2( name ) \
|
|
if( OpenStatus.name ) { \
|
|
name.close(); \
|
|
OpenStatus.name = false; \
|
|
}
|
|
|
|
|
|
void ClosePlugins( bool closegs )
|
|
{
|
|
// Close pads first since they attach to the GS's window.
|
|
|
|
CLOSE_PLUGIN( PAD1 );
|
|
CLOSE_PLUGIN( PAD2 );
|
|
|
|
// GS plugin is special and is not always closed during emulation pauses.
|
|
// (that's because the GS is the most complicated plugin and to close it would
|
|
// require we save the GS state)
|
|
|
|
if( OpenStatus.GS )
|
|
{
|
|
if( closegs )
|
|
{
|
|
gsClose();
|
|
OpenStatus.GS = false;
|
|
}
|
|
else
|
|
{
|
|
mtgsWaitGS();
|
|
}
|
|
}
|
|
|
|
if( OpenStatus.CDVD )
|
|
{
|
|
DoCDVDclose();
|
|
OpenStatus.CDVD=false;
|
|
}
|
|
|
|
CLOSE_PLUGIN( DEV9 );
|
|
CLOSE_PLUGIN( USB );
|
|
CLOSE_PLUGIN( FW );
|
|
CLOSE_PLUGIN( SPU2 );
|
|
}
|
|
|
|
//used to close the GS plugin window and pads, to switch gsdx renderer
|
|
void CloseGS()
|
|
{
|
|
if( CHECK_MULTIGS ) mtgsWaitGS();
|
|
|
|
CLOSE_PLUGIN( PAD1 );
|
|
CLOSE_PLUGIN( PAD2 );
|
|
|
|
if( OpenStatus.GS )
|
|
{
|
|
gsClose();
|
|
OpenStatus.GS = false;
|
|
}
|
|
}
|
|
|
|
void ReleasePlugins()
|
|
{
|
|
if (!plugins_loaded) return;
|
|
|
|
if ((GSplugin == NULL) || (PAD1plugin == NULL) || (PAD2plugin == NULL) ||
|
|
(SPU2plugin == NULL) || (CDVDplugin == NULL) || (DEV9plugin == NULL) ||
|
|
(USBplugin == NULL) || (FWplugin == NULL)) return;
|
|
|
|
ShutdownPlugins();
|
|
|
|
SysCloseLibrary(GSplugin); GSplugin = NULL;
|
|
SysCloseLibrary(PAD1plugin); PAD1plugin = NULL;
|
|
SysCloseLibrary(PAD2plugin); PAD2plugin = NULL;
|
|
SysCloseLibrary(SPU2plugin); SPU2plugin = NULL;
|
|
SysCloseLibrary(CDVDplugin); CDVDplugin = NULL;
|
|
SysCloseLibrary(DEV9plugin); DEV9plugin = NULL;
|
|
SysCloseLibrary(USBplugin); USBplugin = NULL;
|
|
SysCloseLibrary(FWplugin); FWplugin = NULL;
|
|
|
|
plugins_loaded = false;
|
|
}
|
|
|
|
void PluginsResetGS()
|
|
{
|
|
// PADs are tied to the GS window, so shut them down together with the GS.
|
|
|
|
CLOSE_PLUGIN( PAD1 );
|
|
CLOSE_PLUGIN( PAD2 );
|
|
|
|
if( OpenStatus.GS )
|
|
{
|
|
gsClose();
|
|
OpenStatus.GS = false;
|
|
}
|
|
|
|
GSshutdown();
|
|
|
|
int ret = GSinit();
|
|
if (ret != 0) { Msgbox::Alert("GSinit error: %d", params ret); }
|
|
}
|
|
|
|
#else
|
|
|
|
#endif |