nuclear@73: #include nuclear@73: #include nuclear@73: #include nuclear@73: #include nuclear@73: #include nuclear@73: #include nuclear@73: #include nuclear@73: #include "max.h" nuclear@73: #include "impexp.h" // SceneExport nuclear@73: #include "iparamb2.h" // ClassDesc2 nuclear@73: #include "plugapi.h" nuclear@73: #include "IGame.h" nuclear@73: #include "IGameExport.h" nuclear@73: #include "IConversionmanager.h" nuclear@73: nuclear@73: nuclear@73: #pragma comment (lib, "core.lib") nuclear@73: #pragma comment (lib, "geom.lib") nuclear@73: #pragma comment (lib, "gfx.lib") nuclear@73: #pragma comment (lib, "mesh.lib") nuclear@73: #pragma comment (lib, "maxutil.lib") nuclear@73: #pragma comment (lib, "maxscrpt.lib") nuclear@73: #pragma comment (lib, "paramblk2.lib") nuclear@73: #pragma comment (lib, "msxml2.lib") nuclear@73: #pragma comment (lib, "igame.lib") nuclear@73: #pragma comment (lib, "comctl32.lib") nuclear@73: nuclear@73: nuclear@73: #define VER_MAJOR 1 nuclear@73: #define VER_MINOR 0 nuclear@73: #define VERSION(major, minor) \ nuclear@73: ((major) * 100 + ((minor) < 10 ? (minor) * 10 : (minor))) nuclear@73: nuclear@73: typedef int (*PluginInitFunc)(); nuclear@73: typedef int (*PluginShutdownFunc)(); nuclear@73: typedef ClassDesc *(*PluginClassDescFunc)(int); nuclear@73: nuclear@73: static FILE *logfile; nuclear@73: static HINSTANCE hinst; nuclear@73: static const wchar_t *copyright_str = L"Copyright 2013 (C) John Tsiombikas - GNU General Public License v3, see COPYING for details."; nuclear@73: nuclear@73: class GoatExporterStub : public SceneExport { nuclear@73: public: nuclear@73: IGameScene *igame; nuclear@73: nuclear@73: int ExtCount() { return 1; } nuclear@73: const TCHAR *Ext(int n) { return L"goatsce"; } nuclear@73: const TCHAR *LongDesc() { return L"Goat3D Scene file"; } nuclear@73: const TCHAR *ShortDesc() { return L"Goat3D Scene"; } nuclear@73: const TCHAR *AuthorName() { return L"John Tsiombikas"; } nuclear@73: const TCHAR *CopyrightMessage() { return copyright_str; } nuclear@73: const TCHAR *OtherMessage1() { return L"foo1"; } nuclear@73: const TCHAR *OtherMessage2() { return L"foo2"; } nuclear@73: unsigned int Version() { return VERSION(VER_MAJOR, VER_MINOR); } nuclear@73: void ShowAbout(HWND win) { MessageBoxA(win, "Goat3D exporter", "About this plugin", 0); } nuclear@73: nuclear@73: int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0); nuclear@73: }; nuclear@73: nuclear@73: class GoatAnimExporterStub : public SceneExport { nuclear@73: public: nuclear@73: IGameScene *igame; nuclear@73: nuclear@73: int ExtCount() { return 1; } nuclear@73: const TCHAR *Ext(int n) { return L"goatanm"; } nuclear@73: const TCHAR *LongDesc() { return L"Goat3D Animation file"; } nuclear@73: const TCHAR *ShortDesc() { return L"Goat3D Animation"; } nuclear@73: const TCHAR *AuthorName() { return L"John Tsiombikas"; } nuclear@73: const TCHAR *CopyrightMessage() { return copyright_str; } nuclear@73: const TCHAR *OtherMessage1() { return L"bar1"; } nuclear@73: const TCHAR *OtherMessage2() { return L"bar2"; } nuclear@73: unsigned int Version() { return VERSION(VER_MAJOR, VER_MINOR); } nuclear@73: void ShowAbout(HWND win) { MessageBoxA(win, "Goat3D anim exporter", "About this plugin", 0); } nuclear@73: nuclear@73: int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0); nuclear@73: }; nuclear@73: nuclear@73: static const char *find_dll_dir() nuclear@73: { nuclear@73: static char path[MAX_PATH]; nuclear@73: nuclear@73: HMODULE dll; nuclear@73: if(!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nuclear@73: (LPCSTR)find_dll_dir, &dll)) { nuclear@73: return 0; nuclear@73: } nuclear@73: GetModuleFileNameA(dll, path, sizeof path); nuclear@73: nuclear@73: char *last_slash = strrchr(path, '\\'); nuclear@73: if(last_slash && last_slash[1]) { nuclear@73: *last_slash = 0; nuclear@73: } nuclear@73: nuclear@73: return path; nuclear@73: } nuclear@73: nuclear@73: static int do_export(int which, const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL non_int, DWORD opt) nuclear@73: { nuclear@73: const char *dll_fname = "maxgoat.dll"; nuclear@73: char *dll_path; nuclear@73: HMODULE dll = 0; nuclear@73: PluginInitFunc init; nuclear@73: PluginShutdownFunc shutdown; nuclear@73: PluginClassDescFunc get_class_desc; nuclear@73: ClassDesc *desc; nuclear@73: SceneExport *ex; nuclear@73: int result = IMPEXP_FAIL; nuclear@73: nuclear@73: const char *plugdir = find_dll_dir(); nuclear@73: if(plugdir) { nuclear@73: dll_path = new char[strlen(dll_fname) + strlen(plugdir) + 2]; nuclear@73: sprintf(dll_path, "%s\\%s", plugdir, dll_fname); nuclear@73: } else { nuclear@73: dll_path = new char[strlen(dll_fname) + 1]; nuclear@73: strcpy(dll_path, dll_fname); nuclear@73: } nuclear@73: nuclear@73: if(!(dll = LoadLibraryA(dll_path))) { nuclear@73: fprintf(logfile, "failed to load exporter: %s\n", dll_path); nuclear@73: goto done; nuclear@73: } nuclear@73: nuclear@73: if(!(get_class_desc = (PluginClassDescFunc)GetProcAddress(dll, "LibClassDesc"))) { nuclear@73: fprintf(logfile, "maxgoat.dll is invalid (no LibClassDesc function)\n"); nuclear@73: goto done; nuclear@73: } nuclear@73: nuclear@73: // first initialize the library nuclear@73: if((init = (PluginInitFunc)GetProcAddress(dll, "LibInitialize"))) { nuclear@73: if(!init()) { nuclear@73: fprintf(logfile, "exporter initialization failed!\n"); nuclear@73: goto done; nuclear@73: } nuclear@73: } nuclear@73: nuclear@73: if(!(desc = get_class_desc(which))) { nuclear@73: fprintf(logfile, "failed to get the class descriptor\n"); nuclear@73: goto done; nuclear@73: } nuclear@73: nuclear@73: if(!(ex = (SceneExport*)desc->Create())) { nuclear@73: fprintf(logfile, "failed to create exporter class instance\n"); nuclear@73: goto done; nuclear@73: } nuclear@73: nuclear@73: __try { nuclear@73: result = ex->DoExport(name, eiface, iface); nuclear@73: } nuclear@73: __except(EXCEPTION_EXECUTE_HANDLER) { nuclear@73: fprintf(logfile, "Exception caught!\n"); nuclear@73: delete ex; nuclear@73: goto done; nuclear@73: } nuclear@73: delete ex; nuclear@73: nuclear@73: if((shutdown = (PluginShutdownFunc)GetProcAddress(dll, "LibShutdown"))) { nuclear@73: shutdown(); nuclear@73: } nuclear@73: nuclear@73: done: nuclear@73: delete [] dll_path; nuclear@73: if(dll) { nuclear@73: FreeLibrary(dll); nuclear@73: } nuclear@73: return result; nuclear@73: } nuclear@73: nuclear@73: int GoatExporterStub::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, nuclear@73: BOOL non_interactive, DWORD opt) nuclear@73: { nuclear@73: return do_export(0, name, eiface, iface, non_interactive, opt); nuclear@73: } nuclear@73: nuclear@73: nuclear@73: int GoatAnimExporterStub::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, nuclear@73: BOOL non_interactive, DWORD opt) nuclear@73: { nuclear@73: return do_export(1, name, eiface, iface, non_interactive, opt); nuclear@73: } nuclear@73: nuclear@73: // ------------------------------------------ nuclear@73: nuclear@73: class GoatClassDesc : public ClassDesc2 { nuclear@73: public: nuclear@73: int IsPublic() { return TRUE; } nuclear@73: void *Create(BOOL loading = FALSE) { return new GoatExporterStub; } nuclear@73: const TCHAR *ClassName() { return L"GoatExporterStub"; } nuclear@73: SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } nuclear@73: Class_ID ClassID() { return Class_ID(0x2e4e6311, 0x2b154d91); } nuclear@73: const TCHAR *Category() { return L"Mutant Stargoat"; } nuclear@73: nuclear@73: const TCHAR *InternalName() { return L"GoatExporterStub"; } nuclear@73: HINSTANCE HInstance() { return hinst; } nuclear@73: }; nuclear@73: nuclear@73: class GoatAnimClassDesc : public ClassDesc2 { nuclear@73: public: nuclear@73: int IsPublic() { return TRUE; } nuclear@73: void *Create(BOOL loading = FALSE) { return new GoatAnimExporterStub; } nuclear@73: const TCHAR *ClassName() { return L"GoatAnimExporterStub"; } nuclear@73: SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } nuclear@73: Class_ID ClassID() { return Class_ID(0x75054666, 0x45487285); } nuclear@73: const TCHAR *Category() { return L"Mutant Stargoat"; } nuclear@73: nuclear@73: const TCHAR *InternalName() { return L"GoatAnimExporterStub"; } nuclear@73: HINSTANCE HInstance() { return hinst; } nuclear@73: }; nuclear@73: nuclear@73: nuclear@73: static GoatClassDesc class_desc; nuclear@73: static GoatAnimClassDesc anim_class_desc; nuclear@73: nuclear@73: BOOL WINAPI DllMain(HINSTANCE inst_handle, ULONG reason, void *reserved) nuclear@73: { nuclear@73: if(reason == DLL_PROCESS_ATTACH) { nuclear@73: hinst = inst_handle; nuclear@73: DisableThreadLibraryCalls(hinst); nuclear@73: } nuclear@73: return TRUE; nuclear@73: } nuclear@73: nuclear@73: extern "C" { nuclear@73: nuclear@73: __declspec(dllexport) const TCHAR *LibDescription() nuclear@73: { nuclear@73: return L"Goat3D exporter stub"; nuclear@73: } nuclear@73: nuclear@73: __declspec(dllexport) int LibNumberClasses() nuclear@73: { nuclear@73: return 2; nuclear@73: } nuclear@73: nuclear@73: __declspec(dllexport) ClassDesc *LibClassDesc(int i) nuclear@73: { nuclear@73: switch(i) { nuclear@73: case 0: nuclear@73: return &class_desc; nuclear@73: case 1: nuclear@73: return &anim_class_desc; nuclear@73: default: nuclear@73: break; nuclear@73: } nuclear@73: return 0; nuclear@73: } nuclear@73: nuclear@73: __declspec(dllexport) ULONG LibVersion() nuclear@73: { nuclear@73: return Get3DSMAXVersion(); nuclear@73: } nuclear@73: nuclear@73: __declspec(dllexport) int LibInitialize() nuclear@73: { nuclear@73: static char path[1024]; nuclear@73: nuclear@73: SHGetFolderPathA(0, CSIDL_PERSONAL, 0, 0, path); nuclear@73: strcat(path, "/testexpstub.log"); nuclear@73: nuclear@73: if((logfile = fopen(path, "w"))) { nuclear@73: setvbuf(logfile, 0, _IONBF, 0); nuclear@73: } nuclear@73: return TRUE; nuclear@73: } nuclear@73: nuclear@73: __declspec(dllexport) int LibShutdown() nuclear@73: { nuclear@73: if(logfile) { nuclear@73: fclose(logfile); nuclear@73: logfile = 0; nuclear@73: } nuclear@73: return TRUE; nuclear@73: } nuclear@73: nuclear@73: } // extern "C"