/** * @brief Used by Sys_LoadDll to get handle on a mod library * @return Handle to a mod library */ static void *Sys_TryLibraryLoad(const char *base, const char *gamedir, const char *fname) { void *libHandle; char *fn; fn = FS_BuildOSPath(base, gamedir, fname); #ifdef __APPLE__ if (FS_Unzip(fn, qtrue)) { char buffer[MAX_OSPATH]; Com_sprintf(buffer, sizeof(buffer), "%s.bundle/Contents/MacOS/%s", fname, fname); fn = FS_BuildOSPath(Cvar_VariableString("fs_homepath"), gamedir, buffer); } #endif // __APPLE__ Com_Printf("Sys_LoadDll(%s)... ", fn); libHandle = Sys_LoadLibrary(fn); if (!libHandle) { Com_Printf("failed: \"%s\"\n", Sys_LibraryError()); return NULL; } Com_Printf("succeeded\n"); return libHandle; }
/** * @brief Used by Sys_LoadGameDll to get handle on a mod library * @return Handle to a mod library */ static void *Sys_TryLibraryLoad(const char *base, const char *gamedir, const char *fname) { void *libHandle; char *fn; #ifdef __MORPHOS__ int (*morphos_so_init)(void); void (*morphos_so_deinit)(void); #endif #ifdef __APPLE__ Com_Printf("Sys_LoadDll -> Sys_TryLibraryLoad(%s, %s, %s)... \n", base, gamedir, fname); libHandle = NULL; // Incoming is (for example) "cgame_mac" // What we may actually have is: // 1) A zipped .bundle package // 2) A .dylib without an extension // 3) A .dylib with an extension we need to append. // // In older versions of OS X (pre 10.5), dylibs could not be unloaded allowing the host process to reclaim that address space. // This is why .bundles were used instead. When W:ET originally shipped, it used used .bundle packages for the VM libraries, // but to make them single files, it zipped that .bundle package and had no extension at all (ie just "cgame_mac"). But now // that dylibs can be unloaded, there's no practical difference between the two (for W:ET's purposes), so using a single file // dylib is simpler. That's why we now support a dylib with some backward compatibility to allow .bundles. // 1: The zipped .bundle package { Com_Printf("-- Trying zipped .bundle... "); fn = FS_BuildOSPath(base, gamedir, fname); if (FS_Unzip(fn, qtrue)) { char buffer[MAX_OSPATH]; Com_sprintf(buffer, sizeof(buffer), "%s.bundle/Contents/MacOS/%s", fname, fname); fn = FS_BuildOSPath(Cvar_VariableString("fs_homepath"), gamedir, buffer); libHandle = Sys_LoadLibrary(fn); if (!libHandle) { Com_Printf("failed: \"%s\"\n", Sys_LibraryError()); } else { Com_Printf("succeeded\n"); } } else { Com_Printf("failed. (Not a zip).\n"); } } // 2: The dylib without an extension if (!libHandle) { fn = FS_BuildOSPath(base, gamedir, fname); Com_Printf("-- Trying extension-less dylib... "); libHandle = Sys_LoadLibrary(fn); if (!libHandle) { Com_Printf("failed: \"%s\"\n", Sys_LibraryError()); } else { Com_Printf("succeeded\n"); } } // 3: The dylib with an extension if (!libHandle) { char buffer[MAX_OSPATH]; Com_sprintf(buffer, sizeof(buffer), "%s.dylib", fname); fn = FS_BuildOSPath(Cvar_VariableString("fs_homepath"), gamedir, buffer); Com_Printf("-- Trying dylib with extension... "); libHandle = Sys_LoadLibrary(fn); if (!libHandle) { Com_Printf("failed: \"%s\"\n", Sys_LibraryError()); } else { Com_Printf("succeeded\n"); } } return libHandle; #else // __APPLE__ fn = FS_BuildOSPath(base, gamedir, fname); Com_Printf("Sys_LoadDll(%s)... ", fn); libHandle = Sys_LoadLibrary(fn); if (!libHandle) { Com_Printf("failed: \"%s\"\n", Sys_LibraryError()); return NULL; } #endif // __APPLE__ #ifdef __MORPHOS__ morphos_so_init = dlsym(libHandle, "morphos_so_init"); morphos_so_deinit = dlsym(libHandle, "morphos_so_deinit"); if (!(morphos_so_init && morphos_so_deinit && morphos_so_init())) { Com_Printf("failed: \"can't find the morphos_so_init and morphos_so_deinit symbols\"\n"); Sys_UnloadLibrary(libHandle); return NULL; } #endif Com_Printf("succeeded\n"); return libHandle; }