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