1 module m64p; 2 3 import dynalib; 4 5 private __gshared m64p_handle coreHandle; 6 private __gshared m64p_handle audioHandle; 7 private __gshared m64p_handle inputHandle; 8 private __gshared m64p_handle rspHandle; 9 private __gshared m64p_handle videoHandle; 10 11 public: 12 13 import m64p_common; 14 import m64p_config; 15 import m64p_debugger; 16 import m64p_frontend; 17 import m64p_plugin; 18 import m64p_types; 19 import m64p_vidext; 20 21 m64p_handle m64p_coreHandle() { return coreHandle; } 22 bool m64p_coreIsLoaded() { return coreHandle != null; } 23 24 m64p_error m64p_loadCore() 25 { 26 if (m64p_coreIsLoaded) return M64ERR_SUCCESS; 27 28 DynaLib lib; 29 if (!lib.loadFromConfig("mupen64plus", "mupen64plus-core")) 30 { 31 import std.stdio : writeln; 32 writeln("There was a problem loading mupen64plus-core"); 33 return M64ERR_NOT_INIT; 34 } coreHandle = lib.handle; 35 36 m64p_coreBind(&lib); 37 38 return M64ERR_SUCCESS; 39 } 40 41 m64p_error m64p_loadCore(string libDir = "", string depDir = "!") 42 { 43 if (m64p_coreIsLoaded) return M64ERR_SUCCESS; 44 45 DynaLib lib; 46 if (!lib.load("mupen64plus", libDir, depDir)) 47 { 48 import std.stdio : writeln; 49 writeln("There was a problem loading mupen64plus-core"); 50 return M64ERR_NOT_INIT; 51 } coreHandle = lib.handle; 52 53 m64p_coreBind(&lib); 54 55 return M64ERR_SUCCESS; 56 } 57 58 private void m64p_coreBind(DynaLib* lib) 59 { 60 /* Common */ 61 lib.bind(&PluginGetVersion,"PluginGetVersion"); 62 lib.bind(&CoreGetAPIVersions,"CoreGetAPIVersions"); 63 lib.bind(&CoreErrorMessage,"CoreErrorMessage"); 64 65 /* Config */ 66 lib.bind(&ConfigListSections,"ConfigListSections"); 67 lib.bind(&ConfigOpenSection,"ConfigOpenSection"); 68 lib.bind(&ConfigListParameters,"ConfigListParameters"); 69 lib.bind(&ConfigSaveFile,"ConfigSaveFile"); 70 lib.bind(&ConfigSaveSection,"ConfigSaveSection"); 71 lib.bind(&ConfigHasUnsavedChanges,"ConfigHasUnsavedChanges"); 72 lib.bind(&ConfigDeleteSection,"ConfigDeleteSection"); 73 lib.bind(&ConfigRevertChanges,"ConfigRevertChanges"); 74 lib.bind(&ConfigSetParameter,"ConfigSetParameter"); 75 lib.bind(&ConfigSetParameterHelp,"ConfigSetParameterHelp"); 76 lib.bind(&ConfigGetParameter,"ConfigGetParameter"); 77 lib.bind(&ConfigGetParameterType,"ConfigGetParameterType"); 78 lib.bind(&ConfigGetParameterHelp,"ConfigGetParameterHelp"); 79 lib.bind(&ConfigSetDefaultInt,"ConfigSetDefaultInt"); 80 lib.bind(&ConfigSetDefaultFloat,"ConfigSetDefaultFloat"); 81 lib.bind(&ConfigSetDefaultBool,"ConfigSetDefaultBool"); 82 lib.bind(&ConfigSetDefaultString,"ConfigSetDefaultString"); 83 lib.bind(&ConfigGetParamInt,"ConfigGetParamInt"); 84 lib.bind(&ConfigGetParamFloat,"ConfigGetParamFloat"); 85 lib.bind(&ConfigGetParamBool,"ConfigGetParamBool"); 86 lib.bind(&ConfigGetParamString,"ConfigGetParamString"); 87 lib.bind(&ConfigGetSharedDataFilepath,"ConfigGetSharedDataFilepath"); 88 lib.bind(&ConfigGetUserConfigPath,"ConfigGetUserConfigPath"); 89 lib.bind(&ConfigGetUserDataPath,"ConfigGetUserDataPath"); 90 lib.bind(&ConfigGetUserCachePath,"ConfigGetUserCachePath"); 91 lib.bind(&ConfigExternalOpen,"ConfigExternalOpen"); 92 lib.bind(&ConfigExternalClose,"ConfigExternalClose"); 93 lib.bind(&ConfigExternalGetParameter,"ConfigExternalGetParameter"); 94 lib.bind(&ConfigSendNetplayConfig,"ConfigSendNetplayConfig"); 95 lib.bind(&ConfigReceiveNetplayConfig,"ConfigReceiveNetplayConfig"); 96 lib.bind(&ConfigOverrideUserPaths,"ConfigOverrideUserPaths"); 97 98 /* Debug */ 99 lib.bind(&DebugSetCallbacks,"DebugSetCallbacks"); 100 lib.bind(&DebugSetCoreCompare,"DebugSetCoreCompare"); 101 lib.bind(&DebugSetRunState,"DebugSetRunState"); 102 lib.bind(&DebugGetState,"DebugGetState"); 103 lib.bind(&DebugStep,"DebugStep"); 104 lib.bind(&DebugDecodeOp,"DebugDecodeOp"); 105 lib.bind(&DebugMemGetRecompInfo,"DebugMemGetRecompInfo"); 106 lib.bind(&DebugMemGetMemInfo,"DebugMemGetMemInfo"); 107 lib.bind(&DebugMemGetPointer,"DebugMemGetPointer"); 108 lib.bind(&DebugMemRead64,"DebugMemRead64"); 109 lib.bind(&DebugMemRead32,"DebugMemRead32"); 110 lib.bind(&DebugMemRead16,"DebugMemRead16"); 111 lib.bind(&DebugMemRead8,"DebugMemRead8"); 112 lib.bind(&DebugMemWrite64,"DebugMemWrite64"); 113 lib.bind(&DebugMemWrite32,"DebugMemWrite32"); 114 lib.bind(&DebugMemWrite16,"DebugMemWrite16"); 115 lib.bind(&DebugMemWrite8,"DebugMemWrite8"); 116 lib.bind(&DebugGetCPUDataPtr,"DebugGetCPUDataPtr"); 117 lib.bind(&DebugBreakpointLookup,"DebugBreakpointLookup"); 118 lib.bind(&DebugBreakpointCommand,"DebugBreakpointCommand"); 119 lib.bind(&DebugBreakpointTriggeredBy,"DebugBreakpointTriggeredBy"); 120 lib.bind(&DebugVirtualToPhysical,"DebugVirtualToPhysical"); 121 122 /* Front-End */ 123 lib.bind(&CoreStartup,"CoreStartup"); 124 lib.bind(&CoreShutdown,"CoreShutdown"); 125 lib.bind(&CoreAttachPlugin,"CoreAttachPlugin"); 126 lib.bind(&CoreDetachPlugin,"CoreDetachPlugin"); 127 lib.bind(&CoreDoCommand,"CoreDoCommand"); 128 lib.bind(&CoreOverrideVidExt,"CoreOverrideVidExt"); 129 lib.bind(&CoreAddCheat,"CoreAddCheat"); 130 lib.bind(&CoreCheatEnabled,"CoreCheatEnabled"); 131 lib.bind(&CoreGetRomSettings,"CoreGetRomSettings"); 132 version(Modding) 133 { 134 lib.bind(&CoreSaveOverride,"CoreSaveOverride"); 135 lib.bind(&GetHeader,"GetHeader"); 136 lib.bind(&GetRdRam,"GetRdRam"); 137 lib.bind(&GetRom,"GetRom"); 138 lib.bind(&GetRdRamSize,"GetRdRamSize"); 139 lib.bind(&GetRomSize,"GetRomSize"); 140 lib.bind(&RefreshDynarec,"RefreshDynarec"); 141 } 142 143 /* Plugin */ 144 145 /* VidExt */ 146 lib.bind(&VidExt_Init,"VidExt_Init"); 147 lib.bind(&VidExt_Quit,"VidExt_Quit"); 148 lib.bind(&VidExt_ListFullscreenModes,"VidExt_ListFullscreenModes"); 149 lib.bind(&VidExt_ListFullscreenRates,"VidExt_ListFullscreenRates"); 150 lib.bind(&VidExt_SetVideoMode,"VidExt_SetVideoMode"); 151 lib.bind(&VidExt_SetVideoModeWithRate,"VidExt_SetVideoModeWithRate"); 152 lib.bind(&VidExt_ResizeWindow,"VidExt_ResizeWindow"); 153 lib.bind(&VidExt_SetCaption,"VidExt_SetCaption"); 154 lib.bind(&VidExt_ToggleFullScreen,"VidExt_ToggleFullScreen"); 155 lib.bind(&VidExt_GL_GetProcAddress,"VidExt_GL_GetProcAddress"); 156 lib.bind(&VidExt_GL_SetAttribute,"VidExt_GL_SetAttribute"); 157 lib.bind(&VidExt_GL_GetAttribute,"VidExt_GL_GetAttribute"); 158 lib.bind(&VidExt_GL_SwapBuffers,"VidExt_GL_SwapBuffers"); 159 lib.bind(&VidExt_GL_GetDefaultFramebuffer,"VidExt_GL_GetDefaultFramebuffer"); 160 } 161 162 m64p_error m64p_unloadCore() 163 { 164 if (!m64p_coreIsLoaded) return M64ERR_NOT_INIT; 165 166 /* In case plugins are attached */ 167 m64p_detachPlugins(); 168 169 unloadLib(coreHandle); 170 coreHandle = null; 171 172 /* Common */ 173 PluginGetVersion = null; 174 CoreGetAPIVersions = null; 175 CoreErrorMessage = null; 176 PluginStartup = null; 177 PluginShutdown = null; 178 179 /* Config */ 180 ConfigListSections = null; 181 ConfigOpenSection = null; 182 ConfigListParameters = null; 183 ConfigSaveFile = null; 184 ConfigSaveSection = null; 185 ConfigHasUnsavedChanges = null; 186 ConfigDeleteSection = null; 187 ConfigRevertChanges = null; 188 ConfigSetParameter = null; 189 ConfigSetParameterHelp = null; 190 ConfigGetParameter = null; 191 ConfigGetParameterType = null; 192 ConfigGetParameterHelp = null; 193 ConfigSetDefaultInt = null; 194 ConfigSetDefaultFloat = null; 195 ConfigSetDefaultBool = null; 196 ConfigSetDefaultString = null; 197 ConfigGetParamInt = null; 198 ConfigGetParamFloat = null; 199 ConfigGetParamBool = null; 200 ConfigGetParamString = null; 201 ConfigGetSharedDataFilepath = null; 202 ConfigGetUserConfigPath = null; 203 ConfigGetUserDataPath = null; 204 ConfigGetUserCachePath = null; 205 ConfigExternalOpen = null; 206 ConfigExternalClose = null; 207 ConfigExternalGetParameter = null; 208 ConfigSendNetplayConfig = null; 209 ConfigReceiveNetplayConfig = null; 210 ConfigOverrideUserPaths = null; 211 212 /* Debug */ 213 DebugSetCallbacks = null; 214 DebugSetCoreCompare = null; 215 DebugSetRunState = null; 216 DebugGetState = null; 217 DebugStep = null; 218 DebugDecodeOp = null; 219 DebugMemGetRecompInfo = null; 220 DebugMemGetMemInfo = null; 221 DebugMemGetPointer = null; 222 DebugMemRead64 = null; 223 DebugMemRead32 = null; 224 DebugMemRead16 = null; 225 DebugMemRead8 = null; 226 DebugMemWrite64 = null; 227 DebugMemWrite32 = null; 228 DebugMemWrite16 = null; 229 DebugMemWrite8 = null; 230 DebugGetCPUDataPtr = null; 231 DebugBreakpointLookup = null; 232 DebugBreakpointCommand = null; 233 DebugBreakpointTriggeredBy = null; 234 DebugVirtualToPhysical = null; 235 236 /* Front-End */ 237 CoreStartup = null; 238 CoreShutdown = null; 239 CoreAttachPlugin = null; 240 CoreDetachPlugin = null; 241 CoreDoCommand = null; 242 CoreOverrideVidExt = null; 243 CoreAddCheat = null; 244 CoreCheatEnabled = null; 245 version(Modding) 246 { 247 CoreSaveOverride = null; 248 GetHeader = null; 249 GetRdRam = null; 250 GetRom = null; 251 GetRdRamSize = null; 252 GetRomSize = null; 253 RefreshDynarec = null; 254 } 255 256 /* Plugin */ 257 258 /* VidExt */ 259 VidExt_Init = null; 260 VidExt_Quit = null; 261 VidExt_ListFullscreenModes = null; 262 VidExt_ListFullscreenRates = null; 263 VidExt_SetVideoMode = null; 264 VidExt_SetVideoModeWithRate = null; 265 VidExt_ResizeWindow = null; 266 VidExt_SetCaption = null; 267 VidExt_ToggleFullScreen = null; 268 VidExt_GL_GetProcAddress = null; 269 VidExt_GL_SetAttribute = null; 270 VidExt_GL_GetAttribute = null; 271 VidExt_GL_SwapBuffers = null; 272 VidExt_GL_GetDefaultFramebuffer = null; 273 274 return M64ERR_SUCCESS; 275 } 276 277 bool m64p_pluginIsLoaded(m64p_plugin_type type) 278 { 279 switch (type) 280 { 281 case M64PLUGIN_CORE: return coreHandle != null; 282 case M64PLUGIN_AUDIO: return audioHandle != null; 283 case M64PLUGIN_INPUT: return inputHandle != null; 284 case M64PLUGIN_RSP: return rspHandle != null; 285 case M64PLUGIN_GFX: return videoHandle != null; 286 default: return false; 287 } 288 } 289 290 m64p_error m64p_attachPlugins(DebugCallback debugCallback, 291 string videoPlugin, string audioPlugin, 292 string inputPlugin, string rspPlugin, 293 string libDir = "", string depDir = "!") 294 { 295 auto success = 296 ( 297 (m64p_loadPlugin(&videoHandle, M64PLUGIN_GFX, debugCallback, 298 libDir, videoPlugin, depDir) == M64ERR_SUCCESS) && 299 (m64p_loadPlugin(&audioHandle, M64PLUGIN_AUDIO, debugCallback, 300 libDir, audioPlugin, depDir) == M64ERR_SUCCESS) && 301 (m64p_loadPlugin(&inputHandle, M64PLUGIN_INPUT, debugCallback, 302 libDir, inputPlugin, depDir) == M64ERR_SUCCESS) && 303 (m64p_loadPlugin(&rspHandle, M64PLUGIN_RSP, debugCallback, 304 libDir, rspPlugin, depDir) == M64ERR_SUCCESS) 305 ); 306 307 /* Successfully loaded all plugins */ 308 if (success) return M64ERR_SUCCESS; 309 310 /* Failed horribly! Revert! */ 311 m64p_detachPlugins(); 312 return M64ERR_PLUGIN_FAIL; 313 } 314 315 void m64p_detachPlugins() 316 { 317 m64p_unloadPlugin(&rspHandle); 318 m64p_unloadPlugin(&inputHandle); 319 m64p_unloadPlugin(&audioHandle); 320 m64p_unloadPlugin(&videoHandle); 321 } 322 323 private m64p_error m64p_loadPlugin(m64p_handle* plug, m64p_plugin_type type, DebugCallback callback, 324 string path, string name, string depsPath = "!") 325 { 326 /* Check if core is attached */ 327 if (coreHandle == null) return M64ERR_NOT_INIT; 328 329 /* Check if already attached */ 330 if (*plug != null) return M64ERR_INVALID_STATE; 331 332 /* Load the lib */ 333 DynaLib lib; lib.load(name, path, depsPath); 334 if (!lib.isLoaded) 335 { 336 import std.stdio : writeln; 337 writeln("Mupen64Plus: failed to find ", name); 338 return M64ERR_INPUT_NOT_FOUND; 339 } 340 341 /* Initialize the plugin */ 342 lib.bind(&PluginStartup, "PluginStartup"); 343 PluginStartup(coreHandle, cast(void*) (name ~ 0x00), callback); 344 PluginStartup = null; 345 346 /* Attempt attaching it to core lib */ 347 if (CoreAttachPlugin(type, lib.handle) != M64ERR_SUCCESS) 348 { 349 lib.unload(); 350 return M64ERR_NOT_INIT; 351 } 352 353 *plug = lib.handle; 354 return M64ERR_SUCCESS; 355 } 356 357 private m64p_error m64p_unloadPlugin(m64p_handle* plug) 358 { 359 if (coreHandle == null) return M64ERR_NOT_INIT; 360 361 /* Check if not already attached */ 362 if (*plug == null) return M64ERR_INVALID_STATE; 363 364 /* Shutdown the plugin */ 365 bindSymbol(*plug, cast(void**)&PluginShutdown,"PluginShutdown"); 366 PluginShutdown(); 367 PluginShutdown = null; 368 369 /* Detach the lib */ 370 unloadLib(*plug); 371 *plug = null; 372 373 return M64ERR_SUCCESS; 374 }