mirror of
https://github.com/gligli/nulldc-360.git
synced 2025-04-02 11:11:56 -04:00
1344 lines
No EOL
32 KiB
C++
1344 lines
No EOL
32 KiB
C++
/*
|
|
--nullDC plugin managment code--
|
|
Does plugin enumeration and handles dynamic lib loading.
|
|
Also has code for plugin init/reset/term calls :).
|
|
*/
|
|
#include "types.h"
|
|
#include "plugin_manager.h"
|
|
#include "dc/pvr/pvr_if.h"
|
|
#include "dc/pvr/pvrLock.h"
|
|
#include "dc/aica/aica_if.h"
|
|
#include "dc/asic/asic.h"
|
|
#include "dc/gdrom/gdrom_if.h"
|
|
#include "gui/base.h"
|
|
#include "dc/maple/maple_if.h"
|
|
#include "config/config.h"
|
|
#include "gui/base.h"
|
|
#include "naomi/naomi.h"
|
|
|
|
#include <string.h>
|
|
#include "dc/mem/sb.h"
|
|
|
|
//to avoid including windows.h
|
|
#define EXCEPTION_EXECUTE_HANDLER 1
|
|
#define EXCEPTION_CONTINUE_SEARCH 0
|
|
#define EXCEPTION_CONTINUE_EXECUTION -1
|
|
|
|
char* lcp_name;
|
|
s32 lcp_error=0;
|
|
|
|
//Currently Loaded plugins
|
|
nullDC_PowerVR_plugin libPvr;
|
|
nullDC_GDRom_plugin libGDR;
|
|
nullDC_AICA_plugin libAICA;
|
|
nullDC_ARM_plugin libARM;
|
|
vector<nullDC_Maple_plugin*> libMaple;
|
|
nullDC_ExtDevice_plugin libExtDevice;
|
|
gui_plugin_info libgui;
|
|
|
|
sh4_if* sh4_cpu;
|
|
emu_info eminf;
|
|
//more to come
|
|
|
|
bool plugins_inited=false;
|
|
char plugins_path[1000]=("");
|
|
bool plugins_enumerated=false;
|
|
bool plugins_first_load=false;
|
|
|
|
vector<PluginLoadInfo> PluginList_cached;
|
|
vector<MapleDeviceDefinition> MapleDeviceList_cached;
|
|
vector<cDllHandler*> LoadedTempDlls;
|
|
|
|
const char* pluginDefaults[]=
|
|
{
|
|
"drkPvr_Win32.dll",
|
|
"ImgReader_Win32.dll",
|
|
"nullAica_Win32.dll",
|
|
"vbaARM_Win32.dll",
|
|
"nullExtDev_Win32.dll",
|
|
|
|
|
|
"NUL",//gli "drkMapleDevices_Win32.dll:2",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"drkMapleDevices_Win32.dll:0",
|
|
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
"NUL",
|
|
};
|
|
|
|
//Plugin Enumeration/Validation
|
|
enum PluginValidationErrors
|
|
{
|
|
pve_invalid_pointer=-200,
|
|
pve_invalid_cif_ver=-201,
|
|
pve_invalid_sif_ver=-202,
|
|
pve_missing_pointers=-203,
|
|
pve_invalid_plugin_type=-204,
|
|
};
|
|
void EXPORT_CALL plgmng_nileh(u32 nid,void* p)
|
|
{
|
|
}
|
|
void EXPORT_CALL BroadcastEvent(u32 target,u32 eid,void* pdata,u32 ldata)
|
|
{
|
|
if (libPvr.Loaded)
|
|
libPvr.EventHandler(eid,pdata);
|
|
|
|
if (libGDR.Loaded)
|
|
libGDR.EventHandler(eid,pdata);
|
|
|
|
if (libAICA.Loaded)
|
|
libAICA.EventHandler(eid,pdata);
|
|
|
|
if (libARM.Loaded)
|
|
libARM.EventHandler(eid,pdata);
|
|
|
|
for (u32 i=0;i<libMaple.size();i++)
|
|
if (libMaple[i]->Loaded)
|
|
libMaple[i]->EventHandler(eid,pdata);
|
|
|
|
if (libExtDevice.Loaded)
|
|
libExtDevice.EventHandler(eid,pdata);
|
|
|
|
|
|
libgui.EventHandler(eid,pdata);
|
|
}
|
|
s32 ValidatePlugin(plugin_interface* plugin)
|
|
{
|
|
if (plugin==0)
|
|
return pve_invalid_pointer;
|
|
|
|
if (plugin->InterfaceVersion!=PLUGIN_I_F_VERSION)
|
|
{
|
|
dlog("%X != %X\n",plugin->InterfaceVersion,PLUGIN_I_F_VERSION);
|
|
return pve_invalid_cif_ver;
|
|
}
|
|
|
|
|
|
switch(plugin->common.Type)
|
|
{
|
|
case Plugin_PowerVR:
|
|
{
|
|
if (plugin->common.InterfaceVersion!=PVR_PLUGIN_I_F_VERSION)
|
|
return pve_invalid_sif_ver;
|
|
}
|
|
break;
|
|
|
|
case Plugin_GDRom:
|
|
{
|
|
if (plugin->common.InterfaceVersion!=GDR_PLUGIN_I_F_VERSION)
|
|
return pve_invalid_sif_ver;
|
|
}
|
|
break;
|
|
|
|
case Plugin_AICA:
|
|
{
|
|
if (plugin->common.InterfaceVersion!=AICA_PLUGIN_I_F_VERSION)
|
|
return pve_invalid_sif_ver;
|
|
}
|
|
break;
|
|
|
|
case Plugin_ARM:
|
|
{
|
|
if (plugin->common.InterfaceVersion!=ARM_PLUGIN_I_F_VERSION)
|
|
return pve_invalid_sif_ver;
|
|
}
|
|
break;
|
|
|
|
case Plugin_Maple:
|
|
{
|
|
if (plugin->common.InterfaceVersion!=MAPLE_PLUGIN_I_F_VERSION)
|
|
return pve_invalid_sif_ver;
|
|
}
|
|
break;
|
|
|
|
case Plugin_ExtDevice:
|
|
{
|
|
if (plugin->common.InterfaceVersion!=EXTDEVICE_PLUGIN_I_F_VERSION)
|
|
return pve_invalid_sif_ver;
|
|
}
|
|
break;
|
|
default:
|
|
return pve_invalid_plugin_type;
|
|
}
|
|
|
|
return rv_ok;
|
|
}
|
|
bool AddToPluginList(char* dll)
|
|
{
|
|
cDllHandler* lib=new cDllHandler();
|
|
LoadedTempDlls.push_back(lib);
|
|
|
|
//load dll
|
|
if (!lib->Load(dll))
|
|
return false;
|
|
|
|
//Get functions
|
|
dcGetInterfaceFP* dcGetInterface=(dcGetInterfaceFP*)lib->GetProcAddress("dcGetInterface");
|
|
|
|
if (dcGetInterface==0)
|
|
return false;
|
|
|
|
|
|
//Get plugin list
|
|
plugin_interface info;
|
|
memset(&info,0,sizeof(info));
|
|
|
|
dcGetInterface(&info);
|
|
|
|
//Make sure the plugin is valid :)
|
|
if (ValidatePlugin(&info))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
PluginLoadInfo load_info;
|
|
|
|
load_info.Type=(PluginType)info.common.Type;
|
|
|
|
//load_info.subdev_info=info.maple.subdev_info;
|
|
strcpy(load_info.Name,info.common.Name);
|
|
GetFileNameFromPath(dll,load_info.dll);
|
|
|
|
//if correct ver , add em to plugins list :)
|
|
PluginList_cached.push_back(load_info);
|
|
|
|
if (info.common.Type==Plugin_Maple)
|
|
{
|
|
MapleDeviceDefinition t;
|
|
strcpy(t.dll_file,load_info.dll);
|
|
for (int i=0;i<16;i++)
|
|
{
|
|
if (info.maple.devices[i].Type==MDT_EndOfList)
|
|
break;
|
|
t.id=i;
|
|
sprintf(t.dll,("%s:%d"),load_info.dll,i);
|
|
maple_device_definition* mdd=&t;
|
|
memcpy(mdd,&info.maple.devices[i],sizeof(maple_device_definition));
|
|
|
|
MapleDeviceList_cached.push_back(t);
|
|
}
|
|
}
|
|
|
|
//lib.Unload();
|
|
return true;
|
|
}
|
|
|
|
void plugin_FileIsFound(char* file,void* param)
|
|
{
|
|
char dllfile[1024]=("");
|
|
strcat(dllfile,plugins_path);
|
|
strcat(dllfile,file);
|
|
AddToPluginList(dllfile);
|
|
}
|
|
//Get a list of all plugins that exist on plugin directory and can be loaded
|
|
vector<PluginLoadInfo>* GetPluginList(PluginType type)
|
|
{
|
|
vector<PluginLoadInfo>* rv=new vector<PluginLoadInfo>();
|
|
|
|
for (u32 i=0;i<PluginList_cached.size();i++)
|
|
{
|
|
PluginLoadInfo* t=&PluginList_cached[i];
|
|
if (t->Type == type)
|
|
rv->push_back(*t);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
vector<MapleDeviceDefinition>* GetMapleDeviceList(MapleDeviceType type)
|
|
{
|
|
vector<MapleDeviceDefinition>* rv = new vector<MapleDeviceDefinition>();
|
|
for (size_t i=0;i<MapleDeviceList_cached.size();i++)
|
|
{
|
|
if ((type==MDT_EndOfList) || MapleDeviceList_cached[i].Type==(u32)type)
|
|
{
|
|
rv->push_back(MapleDeviceList_cached[i]);
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
void EnumeratePlugins()
|
|
{
|
|
if (plugins_enumerated)
|
|
return;
|
|
plugins_enumerated=true;
|
|
|
|
cfgLoadStr(("emu"),("PluginPath"),plugins_path,0);
|
|
|
|
PluginList_cached.clear();
|
|
MapleDeviceList_cached.clear();
|
|
|
|
|
|
char dllfile[1024]=("");
|
|
strcat(dllfile,plugins_path);
|
|
strcat(dllfile,("*.dll"));
|
|
//Look & load all dll's :)
|
|
FindAllFiles(plugin_FileIsFound,dllfile,0);
|
|
|
|
//gli
|
|
AddToPluginList("int:/nulldc-360/plugins/drkMapleDevices_Win32.dll");
|
|
|
|
//We unload all dll's at once :) this gives a HUGE speedup , as it does not reload common
|
|
//dll's while enumerating ...
|
|
for (size_t i=0;i<LoadedTempDlls.size();i++)
|
|
{
|
|
if (LoadedTempDlls[i]->IsLoaded())
|
|
LoadedTempDlls[i]->Unload();
|
|
delete LoadedTempDlls[i];
|
|
}
|
|
LoadedTempDlls.clear();
|
|
}
|
|
//
|
|
//
|
|
//Implementation of the plugin classes
|
|
//
|
|
//
|
|
//-101 -> null Plugin
|
|
//-102 path too long
|
|
//-103 -> invalid name (split failed)
|
|
//-104 dll load failed
|
|
//-105 some of the exports are missing
|
|
//-106 wrong i/f version
|
|
//-107 LoadI (plugin specialised interface) failed
|
|
//-108 Invalid id (id >= count)
|
|
//0 (rv_ok) -> ok :)
|
|
s32 nullDC_plugin::Open(char* plugin)
|
|
{
|
|
Inited=false;
|
|
Loaded=false;
|
|
|
|
if (!strcmp(plugin,("NUL")))
|
|
{
|
|
return -101;
|
|
}
|
|
|
|
if (strlen(plugin)>480)
|
|
{
|
|
msgboxf(("Plugin dll path is way too long"),MBX_ICONERROR | MBX_OK);
|
|
return -102;
|
|
}
|
|
|
|
char ttt[512];
|
|
strcpy(dll_file,plugin);
|
|
size_t dllfl=strlen(dll_file);
|
|
size_t pathl=strlen(plugins_path);
|
|
if (dllfl<=pathl || (memcmp(dll_file,plugins_path,pathl)!=0))
|
|
{
|
|
strcpy(ttt,plugins_path);
|
|
strcat(ttt,dll_file);
|
|
strcpy(dll_file,plugin);
|
|
}
|
|
else
|
|
{
|
|
strcpy(ttt,dll_file);
|
|
strcpy(dll_file,&dll_file[pathl]);
|
|
}
|
|
if (!dll.Load(ttt))
|
|
return -104;
|
|
dcGetInterfaceFP* getplugin=(dcGetInterfaceFP*)dll.GetProcAddress("dcGetInterface");
|
|
|
|
|
|
if (getplugin==0)
|
|
{
|
|
dll.Unload();
|
|
return -105;
|
|
}
|
|
|
|
plugin_interface t;
|
|
memset(&t,0,sizeof(t));
|
|
getplugin(&t);
|
|
|
|
if (s32 rv=ValidatePlugin(&t))
|
|
{
|
|
dll.Unload();
|
|
return rv;
|
|
}
|
|
|
|
if (t.common.EventHandler==0)
|
|
t.common.EventHandler=plgmng_nileh;
|
|
|
|
LoadI(&t);
|
|
|
|
return rv_ok;
|
|
}
|
|
bool nullDC_plugin::IsOpened()
|
|
{
|
|
return dll.IsLoaded();
|
|
}
|
|
void nullDC_plugin::Close()
|
|
{
|
|
if (IsOpened())
|
|
dll.Unload();
|
|
}
|
|
//*::LoadI
|
|
void nullDC_PowerVR_plugin::LoadI(plugin_interface* t)
|
|
{
|
|
common_info* p1= this;
|
|
pvr_plugin_if* p2= this;
|
|
memcpy(p1,&t->common,sizeof(*p1));
|
|
memcpy(p2,&t->pvr,sizeof(*p2));
|
|
}
|
|
void nullDC_GDRom_plugin::LoadI(plugin_interface* t)
|
|
{
|
|
common_info* p1= this;
|
|
gdr_plugin_if* p2= this;
|
|
memcpy(p1,&t->common,sizeof(*p1));
|
|
memcpy(p2,&t->gdr,sizeof(*p2));
|
|
}
|
|
void nullDC_AICA_plugin::LoadI(plugin_interface* t)
|
|
{
|
|
common_info* p1= this;
|
|
aica_plugin_if* p2= this;
|
|
memcpy(p1,&t->common,sizeof(*p1));
|
|
memcpy(p2,&t->aica,sizeof(*p2));
|
|
}
|
|
void nullDC_ARM_plugin::LoadI(plugin_interface* t)
|
|
{
|
|
common_info* p1= this;
|
|
arm_plugin_if* p2= this;
|
|
memcpy(p1,&t->common,sizeof(*p1));
|
|
memcpy(p2,&t->arm,sizeof(*p2));
|
|
}
|
|
void nullDC_Maple_plugin::LoadI(plugin_interface* t)
|
|
{
|
|
common_info* p1= this;
|
|
maple_plugin_if* p2= this;
|
|
memcpy(p1,&t->common,sizeof(*p1));
|
|
memcpy(p2,&t->maple,sizeof(*p2));
|
|
|
|
ReferenceCount=0;
|
|
}
|
|
void nullDC_ExtDevice_plugin::LoadI(plugin_interface* t)
|
|
{
|
|
common_info* p1= this;
|
|
ext_device_plugin_if* p2= this;
|
|
memcpy(p1,&t->common,sizeof(*p1));
|
|
memcpy(p2,&t->ext_dev,sizeof(*p2));
|
|
}
|
|
//
|
|
//Maple Plugins :
|
|
/*
|
|
when nullDC is started , ALL maple plugins are loaded.Thats why its good to not allocate much things on
|
|
Load().Then , right after Load() , the devices are created(using CreateMain/Sub()).As the user may edit the
|
|
config , devices can be deleted (using DestroyMain/Sub) and recrated.On CreateMain/Sub the plugin should
|
|
add the menus (if any) and allocate resources as needed.
|
|
|
|
When emulation starts , InitMain/Sub is called.Befor Term* is called before Destroy*.If a device is
|
|
hotplugable , it can go into many Create->Init->Term->Destroy cycles while the emulation is running.
|
|
|
|
Its quite simple :
|
|
|
|
Load
|
|
|
|
a:
|
|
Create* ->Destroy* -> a or b
|
|
|
|
->Init* -> Term* ->Destroy*-> if(hotplug) (a or b) else b
|
|
|
|
b:
|
|
Unload
|
|
*/
|
|
void maple_cfg_name(int i,int j,char * out)
|
|
{
|
|
sprintf(out,("Current_maple%d_%d"),i,j);
|
|
}
|
|
void maple_cfg_plug(int i,int j,char * out)
|
|
{
|
|
char temp[512];
|
|
maple_cfg_name(i,j,temp);
|
|
cfgLoadStr(("nullDC_plugins"),temp,out,pluginDefaults[NDCS_PLUGIN_MAPLE_0_0-NDCS_PLUGIN_PVR + i*6+j]);
|
|
}
|
|
u8 GetMaplePort(u32 port,u32 device)
|
|
{
|
|
u32 rv=port<<6;
|
|
|
|
rv|=1<<device;
|
|
return (u8)rv;
|
|
}
|
|
|
|
nullDC_Maple_plugin* FindMaplePlugin(MapleDeviceDefinition* mdd)
|
|
{
|
|
for (u32 i=0;i<libMaple.size();i++)
|
|
{
|
|
if (strcmp(libMaple[i]->dll_file,mdd->dll_file)==0)
|
|
return libMaple[i];
|
|
}
|
|
msgboxf(("Fatal error :nullDC_Maple_plugin* FindMaplePlugin(MapleDeviceDefinition* mdd) failed"),MBX_ICONERROR);
|
|
return 0;
|
|
}
|
|
MapleDeviceDefinition* FindMapleDevice(char* mfdn)
|
|
{
|
|
for (u32 i=0;i<MapleDeviceList_cached.size();i++)
|
|
{
|
|
if (strcmp(MapleDeviceList_cached[i].dll,mfdn)==0)
|
|
return &MapleDeviceList_cached[i];
|
|
}
|
|
msgboxf(("Fatal error :MapleDeviceDefinition* FindMapleDevice(char* mfdn=%s) failed"),MBX_ICONERROR,mfdn);
|
|
return 0;
|
|
}
|
|
|
|
s32 CreateMapleDevice(u32 pos,char* device,bool hotplug);
|
|
s32 CreateMapleSubDevice(u32 pos,u32 subport,char* device,bool hotplug);
|
|
s32 DestroyMapleDevice(u32 pos);
|
|
s32 DestroyMapleSubDevice(u32 pos,u32 subport);
|
|
u32 GetMaplePort(u32 addr);
|
|
void EXPORT_CALL menu_handle_attach_sub(u32 id,void* win,void* p)
|
|
{
|
|
size_t offs=(u8*)p-(u8*)0;
|
|
u32 plid=(u32)offs&0xFFFFFF;
|
|
|
|
u32 prt=((u32)offs>>24);
|
|
|
|
u32 port=prt&3;
|
|
u32 subport=prt>>2;
|
|
|
|
verify(MapleDevices_dd[port][subport].Created==false && MapleDevices[port].subdevices[subport].connected==false);
|
|
|
|
int rv=CreateMapleSubDevice(port,subport,MapleDeviceList_cached[plid].dll,true);
|
|
|
|
if (rv<0)
|
|
return;
|
|
|
|
MapleDevices_dd[port][subport].Created=true;
|
|
|
|
if (plugins_inited)
|
|
{
|
|
MapleDeviceDefinition* mdd=MapleDevices_dd[port][subport].mdd;
|
|
|
|
FindMaplePlugin(mdd)->Init(MapleDevices[port].subdevices[subport].data,mdd->id,0);
|
|
MapleDevices_dd[port][subport].Inited=true;
|
|
}
|
|
}
|
|
void EXPORT_CALL menu_handle_detach_sub(u32 id,void* win,void* p)
|
|
{
|
|
size_t offs=(u8*)p-(u8*)0;
|
|
|
|
u32 prt=((u32)offs>>24);
|
|
|
|
u32 port=prt&3;
|
|
u32 subport=prt>>2;
|
|
|
|
verify(MapleDevices_dd[port][subport].Created==true);
|
|
|
|
if (MapleDevices_dd[port][subport].Inited)
|
|
{
|
|
MapleDeviceDefinition* mdd=MapleDevices_dd[port][subport].mdd;
|
|
|
|
FindMaplePlugin(mdd)->Term(MapleDevices[port].subdevices[subport].data,mdd->id);
|
|
MapleDevices_dd[port][subport].Inited=false;
|
|
}
|
|
|
|
if (MapleDevices_dd[port][subport].Created)
|
|
{
|
|
DestroyMapleSubDevice(port,subport);
|
|
MapleDevices_dd[port][subport].Created=false;
|
|
}
|
|
}
|
|
void cm_MampleSubEmpty(u32 root,u32 port,u32 subport)
|
|
{
|
|
libgui.DeleteAllMenuItemChilds(root);
|
|
//l8r
|
|
for (size_t i=0;i<MapleDeviceList_cached.size();i++)
|
|
{
|
|
if (!(MapleDeviceList_cached[i].Flags & MDTF_Hotplug))
|
|
continue;
|
|
if (MapleDeviceList_cached[i].Type!=MDT_Sub)
|
|
continue;
|
|
char text[512];
|
|
sprintf(text,("Attach %s"),MapleDeviceList_cached[i].Name);
|
|
//Attach NAME
|
|
u32 menu=libgui.AddMenuItem(root,-1,text,menu_handle_attach_sub,0);
|
|
MenuItem mi;
|
|
u8* t=0;
|
|
t+=i;
|
|
t+=(port<<24)|(subport<<26);
|
|
mi.PUser=t;
|
|
libgui.SetMenuItem(menu,&mi,MIM_PUser);
|
|
}
|
|
}
|
|
void cm_MampleSubUsed(u32 root,u32 port,u32 subport)
|
|
{
|
|
libgui.DeleteAllMenuItemChilds(root);
|
|
//l8r
|
|
u32 menu=libgui.AddMenuItem(root,-1,("Unplug"),menu_handle_detach_sub,0);
|
|
MenuItem mi;
|
|
u8* t=0;
|
|
t+=(port<<24);
|
|
t+=(subport<<26);
|
|
mi.PUser=t;
|
|
libgui.SetMenuItem(menu,&mi,MIM_PUser);
|
|
|
|
libgui.AddMenuItem(root,-1,0,0,0);
|
|
}
|
|
void EXPORT_CALL menu_handle_attach_main(u32 id,void* win,void* p)
|
|
{
|
|
size_t offs=(u8*)p-(u8*)0;
|
|
u32 plid=(u32)offs&0xFFFFFF;
|
|
u32 port=((u32)offs>>24);
|
|
|
|
verify(MapleDevices_dd[port][5].Created==false);
|
|
|
|
int rv = CreateMapleDevice(port,MapleDeviceList_cached[plid].dll,true);
|
|
if (rv<0)
|
|
return;
|
|
|
|
MapleDevices_dd[port][5].Created=true;
|
|
|
|
if (plugins_inited)
|
|
{
|
|
MapleDeviceDefinition* mdd=MapleDevices_dd[port][5].mdd;
|
|
|
|
FindMaplePlugin(mdd)->Init(MapleDevices[port].data,mdd->id,0);
|
|
MapleDevices_dd[port][5].Inited=true;
|
|
}
|
|
}
|
|
void EXPORT_CALL menu_handle_detach_main(u32 id,void* win,void* p)
|
|
{
|
|
size_t offs=(u8*)p-(u8*)0;
|
|
|
|
u32 port=((u32)offs>>24);
|
|
|
|
verify(MapleDevices_dd[port][5].Created==true);
|
|
|
|
if (MapleDevices_dd[port][5].Inited)
|
|
{
|
|
MapleDeviceDefinition* mdd=MapleDevices_dd[port][5].mdd;
|
|
|
|
FindMaplePlugin(mdd)->Term(MapleDevices[port].data,mdd->id);
|
|
MapleDevices_dd[port][5].Inited=false;
|
|
}
|
|
|
|
if (MapleDevices_dd[port][5].Created)
|
|
{
|
|
DestroyMapleDevice(port);
|
|
MapleDevices_dd[port][5].Created=false;
|
|
}
|
|
}
|
|
void cm_MampleMainEmpty(u32 root,u32 port)
|
|
{
|
|
libgui.DeleteAllMenuItemChilds(root);
|
|
for (int i=0;i<5;i++)
|
|
MenuIDs.Maple_port[port][i]=0;
|
|
//Add the
|
|
|
|
for (size_t i=0;i<MapleDeviceList_cached.size();i++)
|
|
{
|
|
if (!(MapleDeviceList_cached[i].Flags & MDTF_Hotplug))
|
|
continue;
|
|
if (MapleDeviceList_cached[i].Type!=MDT_Main)
|
|
continue;
|
|
char text[512];
|
|
sprintf(text,("Attach %s"),MapleDeviceList_cached[i].Name);
|
|
//Attach NAME
|
|
u32 menu=libgui.AddMenuItem(root,-1,text,menu_handle_attach_main,0);
|
|
MenuItem mi;
|
|
u8* t=0;
|
|
t+=i;
|
|
t+=(port<<24);
|
|
mi.PUser=t;
|
|
libgui.SetMenuItem(menu,&mi,MIM_PUser);
|
|
}
|
|
}
|
|
void cm_MampleMainUsed(u32 root,u32 port,u32 flags)
|
|
{
|
|
libgui.DeleteAllMenuItemChilds(root);
|
|
|
|
if (flags&0x1f)
|
|
{
|
|
//add the
|
|
//Subdevice X ->[default empty]
|
|
for (u32 i=0;i<5;i++)
|
|
{
|
|
if (flags & (1<<i))
|
|
{
|
|
char temp[512];
|
|
sprintf(temp,("Subdevice %d"),i+1);
|
|
u32 sdr=libgui.AddMenuItem(root,-1,temp,0,0);
|
|
MenuIDs.Maple_port[port][i]=sdr;
|
|
cm_MampleSubEmpty(sdr,port,i);
|
|
}
|
|
else
|
|
{
|
|
MenuIDs.Maple_port[port][i]=0;
|
|
}
|
|
}
|
|
|
|
|
|
//-
|
|
libgui.AddMenuItem(root,-1,0,0,0);
|
|
}
|
|
//Unplug
|
|
u32 menu=libgui.AddMenuItem(root,-1,("Unplug"),menu_handle_detach_main,0);
|
|
MenuItem mi;
|
|
u8* t=0;
|
|
t+=(port<<24);
|
|
mi.PUser=t;
|
|
libgui.SetMenuItem(menu,&mi,MIM_PUser);
|
|
}
|
|
//These are the 'raw' functions , they handle creation/destruction of a device *only*
|
|
enum pmd_errors
|
|
{
|
|
pmde_device_state=-250, //device allready connected/disconected
|
|
pmde_invalid_pos=-251, //invalid device pos (0~3 , 0~4 are valid only)
|
|
pmde_failed_create=-252, //failed to create device
|
|
pmde_failed_create_s=-253, //failed to create device , silent error
|
|
pmde_failed_find_mdd_s=-254,//failed to find maple device definition
|
|
pmde_failed_find_maple_plugin_s=-255,//failed to find maple plugin
|
|
|
|
};
|
|
s32 CreateMapleDevice(u32 pos,char* device,bool hotplug)
|
|
{
|
|
if (pos>3)
|
|
return pmde_invalid_pos;
|
|
|
|
if (MapleDevices[pos].connected)
|
|
return pmde_device_state;
|
|
|
|
MapleDeviceDefinition* mdd=FindMapleDevice(device);
|
|
if (!mdd)
|
|
return pmde_failed_find_mdd_s;
|
|
nullDC_Maple_plugin* plg =FindMaplePlugin(mdd);
|
|
if (!mdd)
|
|
return pmde_failed_find_maple_plugin_s;
|
|
cm_MampleMainUsed(MenuIDs.Maple_port[pos][5],pos,mdd->Flags);
|
|
MapleDevices[pos].port=GetMaplePort(pos,5);
|
|
|
|
if (s32 rv= plg->CreateMain(&MapleDevices[pos],mdd->id,hotplug?MDCF_Hotplug:MDCF_None,MenuIDs.Maple_port[pos][5]))
|
|
{
|
|
cm_MampleMainEmpty(MenuIDs.Maple_port[pos][5],pos);
|
|
if (rv==rv_error)
|
|
return pmde_failed_create;
|
|
else
|
|
return pmde_failed_create_s;
|
|
}
|
|
MapleDevices_dd[pos][5].mdd=mdd;
|
|
MapleDevices[pos].connected=true;
|
|
|
|
return rv_ok;
|
|
}
|
|
s32 DestroyMapleDevice(u32 pos)
|
|
{
|
|
if (pos>3)
|
|
return pmde_invalid_pos;
|
|
|
|
if (!MapleDevices[pos].connected)
|
|
return pmde_device_state;
|
|
|
|
if (!MapleDevices_dd[pos][5].Created)
|
|
return pmde_device_state;
|
|
|
|
|
|
//MapleDevices_dd[pos][5].Inited
|
|
|
|
MapleDeviceDefinition* mdd=MapleDevices_dd[pos][5].mdd;
|
|
MapleDevices_dd[pos][5].mdd=0;
|
|
nullDC_Maple_plugin* plg =FindMaplePlugin(mdd);
|
|
|
|
plg->Destroy(MapleDevices[pos].data,mdd->id);
|
|
cm_MampleMainEmpty(MenuIDs.Maple_port[pos][5],pos);
|
|
|
|
MapleDevices[pos].connected=false;
|
|
|
|
return rv_ok;
|
|
}
|
|
s32 CreateMapleSubDevice(u32 pos,u32 subport,char* device,bool hotplug)
|
|
{
|
|
if (pos>3)
|
|
return pmde_invalid_pos;
|
|
if (subport>4)
|
|
return pmde_invalid_pos;
|
|
|
|
if (!MapleDevices[pos].connected)
|
|
return pmde_device_state;
|
|
|
|
if (MapleDevices[pos].subdevices[subport].connected)
|
|
return pmde_device_state;
|
|
|
|
MapleDeviceDefinition* mdd=FindMapleDevice(device);
|
|
if (!mdd)
|
|
return pmde_failed_create_s;
|
|
|
|
nullDC_Maple_plugin* plg =FindMaplePlugin(mdd);
|
|
|
|
cm_MampleSubUsed(MenuIDs.Maple_port[pos][subport],pos,subport);
|
|
MapleDevices[pos].subdevices[subport].port=GetMaplePort(pos,subport);
|
|
|
|
if (s32 rv= plg->CreateSub(&MapleDevices[pos].subdevices[subport],mdd->id,hotplug?MDCF_Hotplug:MDCF_None,MenuIDs.Maple_port[pos][subport]))
|
|
{
|
|
cm_MampleSubEmpty(MenuIDs.Maple_port[pos][subport],pos,subport);
|
|
if (rv==rv_error)
|
|
return pmde_failed_create;
|
|
else
|
|
return pmde_failed_create_s;
|
|
}
|
|
MapleDevices_dd[pos][subport].mdd=mdd;
|
|
MapleDevices[pos].subdevices[subport].connected=true;
|
|
|
|
return rv_ok;
|
|
}
|
|
s32 DestroyMapleSubDevice(u32 pos,u32 subport)
|
|
{
|
|
if (pos>3)
|
|
return pmde_invalid_pos;
|
|
|
|
if (!MapleDevices[pos].connected)
|
|
return pmde_device_state;
|
|
|
|
if (!MapleDevices[pos].subdevices[subport].connected)
|
|
return pmde_device_state;
|
|
|
|
if (!MapleDevices_dd[pos][subport].Created)
|
|
return pmde_device_state;
|
|
|
|
MapleDeviceDefinition* mdd=MapleDevices_dd[pos][subport].mdd;
|
|
MapleDevices_dd[pos][subport].mdd=0;
|
|
nullDC_Maple_plugin* plg =FindMaplePlugin(mdd);
|
|
|
|
plg->Destroy(MapleDevices[pos].subdevices[subport].data,mdd->id);
|
|
cm_MampleSubEmpty(MenuIDs.Maple_port[pos][subport],pos,subport);
|
|
MapleDevices[pos].subdevices[subport].connected=false;
|
|
return rv_ok;
|
|
}
|
|
|
|
//Misc handling code ~
|
|
/************************************/
|
|
/*********Plugin Load/Unload*********/
|
|
/************************************/
|
|
template<typename T>
|
|
s32 load_plugin(char* dll,T* plug,u32 rootmenu)
|
|
{
|
|
lcp_error=-100;
|
|
lcp_name=dll;
|
|
if (!plug->Loaded)
|
|
{
|
|
SetMenuItemHandler(rootmenu,0);
|
|
eminf.RootMenu=rootmenu;
|
|
if ((lcp_error=plug->Open(dll))!=rv_ok)
|
|
{
|
|
return rv_error;
|
|
}
|
|
if (s32 rv = plug->Load(&eminf))
|
|
{
|
|
return rv;
|
|
}
|
|
plug->Loaded=true;
|
|
printf("Loaded %s[%s]\n",plug->Name,lcp_name);
|
|
}
|
|
|
|
return rv_ok;
|
|
}
|
|
template<typename T>
|
|
void unload_plugin(T* plug,u32 rootmenu)
|
|
{
|
|
lcp_name=plug->Name;
|
|
libgui.DeleteAllMenuItemChilds(rootmenu);
|
|
SetMenuItemHandler(rootmenu,0);
|
|
if (plug->IsOpened())
|
|
{
|
|
if (plug->Loaded)
|
|
{
|
|
plug->Unload();
|
|
plug->Loaded=false;
|
|
printf("Unloaded %s[%s]\n",plug->Name,plug->dll_file);
|
|
}
|
|
plug->Close();
|
|
}
|
|
}
|
|
|
|
#define load_plugin_(cfg_name,to,menu,def) \
|
|
{ \
|
|
char dllf[512]; \
|
|
dllf[0]=0; \
|
|
cfgLoadStr(("nullDC_plugins"),cfg_name,dllf,def); \
|
|
if (s32 rv=load_plugin(dllf,to,menu)) \
|
|
return rv; \
|
|
}
|
|
|
|
//Internal function for load/unload w/ error checking :)
|
|
s32 plugins_Load_()
|
|
{
|
|
if (!plugins_first_load)
|
|
{
|
|
//if first time load , init the maple menus
|
|
plugins_first_load=true;
|
|
for (u32 i=0;i<4;i++)
|
|
cm_MampleMainEmpty(MenuIDs.Maple_port[i][5],i);
|
|
}
|
|
eminf.ConfigLoadStr=cfgLoadStr;
|
|
eminf.ConfigSaveStr=cfgSaveStr;
|
|
eminf.ConfigLoadInt=cfgLoadInt;
|
|
eminf.ConfigSaveInt=cfgSaveInt;
|
|
eminf.ConfigExists=cfgExists;
|
|
|
|
eminf.AddMenuItem=libgui.AddMenuItem;
|
|
eminf.SetMenuItemStyle=libgui.SetMenuItemStyle;
|
|
eminf.GetMenuItem=libgui.GetMenuItem;
|
|
eminf.SetMenuItem=libgui.SetMenuItem;
|
|
eminf.DeleteMenuItem=libgui.DeleteMenuItem;
|
|
|
|
eminf.GetRenderTarget=GetRenderTargetHandle;
|
|
eminf.DebugMenu=MenuIDs.Debug;
|
|
eminf.BroardcastEvent=BroadcastEvent;
|
|
|
|
load_plugin_(("Current_PVR"),&libPvr,MenuIDs.PowerVR,pluginDefaults[NDCS_PLUGIN_PVR-NDCS_PLUGIN_PVR]);
|
|
load_plugin_(("Current_GDR"),&libGDR,MenuIDs.GDRom,pluginDefaults[NDCS_PLUGIN_GDR-NDCS_PLUGIN_PVR]);
|
|
load_plugin_(("Current_AICA"),&libAICA,MenuIDs.Aica,pluginDefaults[NDCS_PLUGIN_AICA-NDCS_PLUGIN_PVR]);
|
|
load_plugin_(("Current_ARM"),&libARM,MenuIDs.Arm,pluginDefaults[NDCS_PLUGIN_ARM-NDCS_PLUGIN_PVR]);
|
|
load_plugin_(("Current_ExtDevice"),&libExtDevice,MenuIDs.ExtDev,pluginDefaults[NDCS_PLUGIN_EXTDEV-NDCS_PLUGIN_PVR]);
|
|
|
|
vector<PluginLoadInfo>* mpl= GetPluginList(Plugin_Maple);
|
|
|
|
if (libMaple.size()!=mpl->size())
|
|
{
|
|
for (size_t i=0;i<mpl->size();i++)
|
|
{
|
|
char fname[512];
|
|
nullDC_Maple_plugin* cmp= new nullDC_Maple_plugin();
|
|
|
|
GetFileNameFromPath((*mpl)[i].dll,fname);
|
|
|
|
if (s32 rv=load_plugin(fname,cmp,MenuIDs.Maple))
|
|
{
|
|
delete cmp;
|
|
return rv;
|
|
}
|
|
libMaple.push_back(cmp);
|
|
}
|
|
}
|
|
delete mpl;
|
|
|
|
//Create Maple Devices
|
|
|
|
for (int port=0;port<4;port++)
|
|
{
|
|
MapleDevices[port].port=GetMaplePort(port,5);
|
|
for (int sub=0;sub<5;sub++)
|
|
{
|
|
MapleDevices[port].subdevices[sub].port=GetMaplePort(port,sub);
|
|
}
|
|
}
|
|
|
|
char plug_name[512];
|
|
for (int port=0;port<4;port++)
|
|
{
|
|
maple_cfg_plug(port,5,plug_name);
|
|
lcp_name=plug_name;
|
|
if (strcmp(plug_name,"NUL")!=0)
|
|
{
|
|
if (!MapleDevices_dd[port][5].Created)
|
|
{
|
|
s32 rv=CreateMapleDevice(port,plug_name,false);
|
|
if (rv!=rv_ok)
|
|
{
|
|
return rv;
|
|
}
|
|
MapleDevices_dd[port][5].Created=true;
|
|
}
|
|
u32 flags=MapleDevices_dd[port][5].mdd->Flags;
|
|
|
|
for (int subport=0;subport<5;subport++)
|
|
{
|
|
if (!(flags & (1<<subport)))
|
|
{
|
|
MapleDevices_dd[port][subport].Created=false;
|
|
continue;
|
|
}
|
|
|
|
maple_cfg_plug(port,subport,plug_name);
|
|
lcp_name=plug_name;
|
|
if (strcmp(plug_name,"NUL")!=0)
|
|
{
|
|
if (!MapleDevices_dd[port][subport].Created)
|
|
{
|
|
//Create it
|
|
s32 rv=CreateMapleSubDevice(port,subport,plug_name,false);
|
|
if (rv!=rv_ok)
|
|
{
|
|
return rv;
|
|
}
|
|
|
|
MapleDevices_dd[port][subport].Created=true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MapleDevices_dd[port][5].Created=false;
|
|
}
|
|
}
|
|
|
|
return rv_ok;
|
|
}
|
|
|
|
//Loads plugins , if allready loaded does nothing :)
|
|
bool plugins_Load()
|
|
{
|
|
//__try
|
|
{
|
|
if (s32 rv=plugins_Load_())
|
|
{
|
|
if (rv==rv_error)
|
|
{
|
|
msgboxf(("Unable to load %s plugin , errorlevel=%d"),MBX_ICONERROR,lcp_name,lcp_error);
|
|
}
|
|
|
|
plugins_Unload();
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
/*__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
msgboxf(("Unhandled exeption while loading %s plugin"),MBX_ICONERROR,lcp_name);
|
|
plugins_Unload();
|
|
return false;
|
|
}*/
|
|
}
|
|
|
|
//Unloads plugins , if allready unloaded does nothing
|
|
void plugins_Unload()
|
|
{
|
|
__try
|
|
{
|
|
for (int port=3;port>=0;port--)
|
|
{
|
|
if (MapleDevices_dd[port][5].Created)
|
|
{
|
|
for (int subport=4;subport>=0;subport--)
|
|
{
|
|
if (MapleDevices_dd[port][subport].Created)
|
|
{
|
|
MapleDevices_dd[port][subport].Created=false;
|
|
|
|
s32 rv=DestroyMapleSubDevice(port,subport);
|
|
if (rv!=rv_ok)
|
|
{
|
|
dlog("DestroyMapleSubDevice(port,subport) failed: %d\n",rv);
|
|
}
|
|
}
|
|
}
|
|
MapleDevices_dd[port][5].Created=false;
|
|
s32 rv=DestroyMapleDevice(port);
|
|
if (rv!=rv_ok)
|
|
{
|
|
dlog("DestroyMapleDevice(port) failed: %d\n",rv);
|
|
}
|
|
/*
|
|
for (int subport=0;subport<4;subport++)
|
|
{
|
|
if (MapleDevices_dd[port][subport].Created)
|
|
{
|
|
//destroy it
|
|
MapleDevices_dd[port][subport].Created=false;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
for (size_t i=libMaple.size();i>0;i--)
|
|
{
|
|
unload_plugin(libMaple[i-1],MenuIDs.Maple);
|
|
}
|
|
libMaple.clear();
|
|
|
|
unload_plugin(&libExtDevice,MenuIDs.ExtDev);
|
|
unload_plugin(&libARM,MenuIDs.Arm);
|
|
unload_plugin(&libAICA,MenuIDs.Aica);
|
|
unload_plugin(&libGDR,MenuIDs.GDRom);
|
|
unload_plugin(&libPvr,MenuIDs.PowerVR);
|
|
}
|
|
//gli__except(EXCEPTION_EXECUTE_HANDLER)
|
|
catch(...)
|
|
{
|
|
msgboxf(("Unhandled exeption while unloading %s\n"),MBX_ICONERROR,lcp_name);
|
|
}
|
|
}
|
|
/************************************/
|
|
/******Plugin selection-switch*******/
|
|
/************************************/
|
|
template<typename T>
|
|
void CheckPlugin(char*cfg_name, T* plug,u32 rootmenu)
|
|
{
|
|
char dllf[512];
|
|
dllf[0]=0;
|
|
cfgLoadStr(("nullDC_plugins"),cfg_name,dllf,("NUL"));
|
|
if (strcmp(plug->dll_file,dllf)!=0)
|
|
{
|
|
unload_plugin(plug,rootmenu);
|
|
}
|
|
}
|
|
void CheckMapleMD()
|
|
{
|
|
|
|
}
|
|
bool plugins_Select()
|
|
{
|
|
if (plugins_inited)
|
|
{
|
|
if (msgboxf(("Emulation is started , plugins can't be changed now ..\r\nWant to Continue anyway ? (Changes will will take effect after retart)"),MBX_YESNO | MBX_ICONEXCLAMATION | MBX_TASKMODAL)==MBX_RV_NO)
|
|
return false;
|
|
}
|
|
|
|
bool rv= SelectPluginsGui();
|
|
|
|
if (rv && plugins_inited==false)
|
|
{
|
|
CheckPlugin(("Current_PVR"),&libPvr,MenuIDs.PowerVR);
|
|
CheckPlugin(("Current_GDR"),&libGDR,MenuIDs.GDRom);
|
|
CheckPlugin(("Current_AICA"),&libAICA,MenuIDs.Aica);
|
|
CheckPlugin(("Current_ARM"),&libARM,MenuIDs.Arm);
|
|
CheckPlugin(("Current_ExtDevice"),&libExtDevice,MenuIDs.ExtDev);
|
|
|
|
//Maple plugins
|
|
for (int port =0;port<4;port++)
|
|
{
|
|
char dllf[512];
|
|
maple_cfg_plug(port,5,dllf);
|
|
if (MapleDevices_dd[port][5].Created)
|
|
{
|
|
//Check if main device is changed
|
|
if (strcmp(dllf,MapleDevices_dd[port][5].mdd->dll)!=0)
|
|
{
|
|
//if it is destroy it & its childs
|
|
for (int i=4;i>=0;i--)
|
|
{
|
|
DestroyMapleSubDevice(port,i);
|
|
MapleDevices_dd[port][i].Created=false;
|
|
}
|
|
DestroyMapleDevice(port);
|
|
MapleDevices_dd[port][5].Created=false;
|
|
}
|
|
else
|
|
{
|
|
for (int i=4;i>=0;i--)
|
|
{
|
|
if (!MapleDevices_dd[port][i].Created)
|
|
continue;
|
|
maple_cfg_plug(port,i,dllf);
|
|
//else , check if a child is changed & destroy it
|
|
if (strcmp(dllf,MapleDevices_dd[port][i].mdd->dll)!=0)
|
|
{
|
|
DestroyMapleSubDevice(port,i);
|
|
MapleDevices_dd[port][i].Created=false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return plugins_Load();
|
|
}
|
|
return rv;
|
|
}
|
|
/************************************/
|
|
/*******Plugin Init/Term/Reset*******/
|
|
/************************************/
|
|
s32 plugins_Init_()
|
|
{
|
|
if (plugins_inited)
|
|
return rv_ok;
|
|
plugins_inited=true;
|
|
|
|
gdr_init_params gdr_info;
|
|
gdr_info.DriveNotifyEvent=NotifyEvent_gdrom;
|
|
|
|
lcp_name=libGDR.Name;
|
|
if (s32 rv = libGDR.Init(&gdr_info))
|
|
return rv;
|
|
libGDR.Inited=true;
|
|
|
|
#ifdef BUILD_NAOMI
|
|
if (!NaomiSelectFile(GetRenderTargetHandle()))
|
|
return rv_serror;
|
|
#endif
|
|
|
|
|
|
aica_init_params aica_info;
|
|
aica_info.RaiseInterrupt=asic_RaiseInterrupt;
|
|
aica_info.SB_ISTEXT=&SB_ISTEXT;
|
|
aica_info.CancelInterrupt=asic_CancelInterrupt;
|
|
aica_info.CDDA_Sector=gdrom_get_cdda;
|
|
aica_info.aica_ram=aica_ram.data;
|
|
aica_info.ArmInterruptChange=libARM.ArmInterruptChange;
|
|
|
|
lcp_name=libAICA.Name;
|
|
if (s32 rv = libAICA.Init(&aica_info))
|
|
return rv;
|
|
libAICA.Inited=true;
|
|
|
|
arm_init_params arm_info;
|
|
arm_info.ReadMem_aica_reg=libAICA.ReadMem_aica_reg;
|
|
arm_info.WriteMem_aica_reg=libAICA.WriteMem_aica_reg;
|
|
arm_info.aica_ram=aica_ram.data;
|
|
|
|
lcp_name=libARM.Name;
|
|
if (s32 rv = libARM.Init(&arm_info))
|
|
return rv;
|
|
libARM.Inited=true;
|
|
|
|
ext_device_init_params ext_device_info;
|
|
ext_device_info.RaiseInterrupt=asic_RaiseInterrupt;
|
|
ext_device_info.SB_ISTEXT=&SB_ISTEXT;
|
|
ext_device_info.CancelInterrupt=asic_CancelInterrupt;
|
|
|
|
lcp_name=libExtDevice.Name;
|
|
if (s32 rv = libExtDevice.Init(&ext_device_info))
|
|
return rv;
|
|
libExtDevice.Inited=true;
|
|
|
|
maple_init_params& mip=*(maple_init_params*)0;
|
|
|
|
//Init Created maple devices
|
|
for ( int i=0;i<4;i++)
|
|
{
|
|
if (MapleDevices_dd[i][5].Created)
|
|
{
|
|
lcp_name=("Made Device");
|
|
verify(MapleDevices_dd[i][5].mdd!=0);
|
|
//Init
|
|
nullDC_Maple_plugin *nmp=FindMaplePlugin(MapleDevices_dd[i][5].mdd);
|
|
lcp_name=MapleDevices_dd[i][5].mdd->Name;
|
|
if (s32 rv=nmp->Init(MapleDevices[i].data,MapleDevices_dd[i][5].mdd->id,&mip))
|
|
return rv;
|
|
|
|
MapleDevices_dd[i][5].Inited=true;
|
|
|
|
for (int j=0;j<5;j++)
|
|
{
|
|
if (MapleDevices_dd[i][j].Created)
|
|
{
|
|
lcp_name=("Made SubDevice");
|
|
verify(MapleDevices_dd[i][j].mdd!=0);
|
|
//Init
|
|
nullDC_Maple_plugin *nmp=FindMaplePlugin(MapleDevices_dd[i][j].mdd);
|
|
lcp_name=MapleDevices_dd[i][j].mdd->Name;
|
|
if (s32 rv=nmp->Init(MapleDevices[i].subdevices[j].data,MapleDevices_dd[i][j].mdd->id,&mip))
|
|
return rv;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
MapleDevices_dd[i][5].Inited=false;
|
|
}
|
|
|
|
//pvr
|
|
pvr_init_params pvr_info;
|
|
pvr_info.RaiseInterrupt=asic_RaiseInterrupt;
|
|
pvr_info.vram=&vram[0];
|
|
pvr_info.vram_lock_32=vramlock_Lock_32;
|
|
pvr_info.vram_lock_64=vramlock_Lock_64;
|
|
pvr_info.vram_unlock=vramlock_Unlock_block;
|
|
pvr_info.osdDraw=0;
|
|
|
|
lcp_name=libPvr.Name;
|
|
if (s32 rv = libPvr.Init(&pvr_info))
|
|
return rv;
|
|
libPvr.Inited=true;
|
|
|
|
return rv_ok;
|
|
}
|
|
|
|
|
|
bool plugins_Init()
|
|
{
|
|
__try
|
|
{
|
|
if (s32 rv = plugins_Init_())
|
|
{
|
|
if (rv==rv_error)
|
|
{
|
|
msgboxf(("Failed to init %s"),MBX_ICONERROR,lcp_name);
|
|
}
|
|
plugins_Term();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
//gli __except(EXCEPTION_EXECUTE_HANDLER)
|
|
catch(...)
|
|
{
|
|
msgboxf(("Unhandled exeption while Initing %s plugin"),MBX_ICONERROR,lcp_name);
|
|
plugins_Term();
|
|
return false;
|
|
}
|
|
}
|
|
template<typename T>
|
|
void term_plugin(T& pl)
|
|
{
|
|
if (pl.Inited)
|
|
{
|
|
pl.Inited=false;
|
|
pl.Term();
|
|
}
|
|
}
|
|
void plugins_Term()
|
|
{
|
|
if (!plugins_inited)
|
|
return;
|
|
plugins_inited=false;
|
|
|
|
//Term inited maple devices
|
|
for ( int i=3;i>=0;i--)
|
|
{
|
|
if (MapleDevices_dd[i][5].Inited)
|
|
{
|
|
for (int j=4;j>=0;j--)
|
|
{
|
|
if (MapleDevices_dd[i][j].Inited)
|
|
{
|
|
MapleDevices_dd[i][j].Inited=false;
|
|
|
|
verify(MapleDevices_dd[i][j].mdd!=0);
|
|
//term
|
|
nullDC_Maple_plugin *nmp=FindMaplePlugin(MapleDevices_dd[i][j].mdd);
|
|
nmp->Term(MapleDevices[i].subdevices[j].data,MapleDevices_dd[i][j].mdd->id);
|
|
}
|
|
}
|
|
|
|
MapleDevices_dd[i][5].Inited=false;
|
|
|
|
verify(MapleDevices_dd[i][5].mdd!=0);
|
|
//term
|
|
nullDC_Maple_plugin *nmp=FindMaplePlugin(MapleDevices_dd[i][5].mdd);
|
|
nmp->Term(MapleDevices[i].data,MapleDevices_dd[i][5].mdd->id);
|
|
}
|
|
}
|
|
|
|
//term all plugins
|
|
term_plugin(libExtDevice);
|
|
term_plugin(libARM);
|
|
term_plugin(libAICA);
|
|
term_plugin(libGDR);
|
|
term_plugin(libPvr);
|
|
}
|
|
|
|
void plugins_Reset(bool Manual)
|
|
{
|
|
libPvr.Reset(Manual);
|
|
libGDR.Reset(Manual);
|
|
libAICA.Reset(Manual);
|
|
libARM.Reset(Manual);
|
|
libExtDevice.Reset(Manual);
|
|
} |