goat3d

annotate exporters/maxgoat_stub/src/stub.cc @ 88:7941e89798e5

selections
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 15 May 2014 06:52:01 +0300
parents 3751aabbc5b3
children
rev   line source
nuclear@73 1 #include <stdio.h>
nuclear@73 2 #include <string.h>
nuclear@73 3 #include <stdlib.h>
nuclear@73 4 #include <errno.h>
nuclear@73 5 #include <map>
nuclear@73 6 #include <windows.h>
nuclear@73 7 #include <shlobj.h>
nuclear@73 8 #include "max.h"
nuclear@73 9 #include "impexp.h" // SceneExport
nuclear@73 10 #include "iparamb2.h" // ClassDesc2
nuclear@73 11 #include "plugapi.h"
nuclear@73 12 #include "IGame.h"
nuclear@73 13 #include "IGameExport.h"
nuclear@73 14 #include "IConversionmanager.h"
nuclear@73 15
nuclear@73 16
nuclear@73 17 #pragma comment (lib, "core.lib")
nuclear@73 18 #pragma comment (lib, "geom.lib")
nuclear@73 19 #pragma comment (lib, "gfx.lib")
nuclear@73 20 #pragma comment (lib, "mesh.lib")
nuclear@73 21 #pragma comment (lib, "maxutil.lib")
nuclear@73 22 #pragma comment (lib, "maxscrpt.lib")
nuclear@73 23 #pragma comment (lib, "paramblk2.lib")
nuclear@73 24 #pragma comment (lib, "msxml2.lib")
nuclear@73 25 #pragma comment (lib, "igame.lib")
nuclear@73 26 #pragma comment (lib, "comctl32.lib")
nuclear@73 27
nuclear@73 28
nuclear@73 29 #define VER_MAJOR 1
nuclear@73 30 #define VER_MINOR 0
nuclear@73 31 #define VERSION(major, minor) \
nuclear@73 32 ((major) * 100 + ((minor) < 10 ? (minor) * 10 : (minor)))
nuclear@73 33
nuclear@73 34 typedef int (*PluginInitFunc)();
nuclear@73 35 typedef int (*PluginShutdownFunc)();
nuclear@73 36 typedef ClassDesc *(*PluginClassDescFunc)(int);
nuclear@73 37
nuclear@73 38 static FILE *logfile;
nuclear@73 39 static HINSTANCE hinst;
nuclear@73 40 static const wchar_t *copyright_str = L"Copyright 2013 (C) John Tsiombikas - GNU General Public License v3, see COPYING for details.";
nuclear@73 41
nuclear@73 42 class GoatExporterStub : public SceneExport {
nuclear@73 43 public:
nuclear@73 44 IGameScene *igame;
nuclear@73 45
nuclear@73 46 int ExtCount() { return 1; }
nuclear@73 47 const TCHAR *Ext(int n) { return L"goatsce"; }
nuclear@73 48 const TCHAR *LongDesc() { return L"Goat3D Scene file"; }
nuclear@73 49 const TCHAR *ShortDesc() { return L"Goat3D Scene"; }
nuclear@73 50 const TCHAR *AuthorName() { return L"John Tsiombikas"; }
nuclear@73 51 const TCHAR *CopyrightMessage() { return copyright_str; }
nuclear@73 52 const TCHAR *OtherMessage1() { return L"foo1"; }
nuclear@73 53 const TCHAR *OtherMessage2() { return L"foo2"; }
nuclear@73 54 unsigned int Version() { return VERSION(VER_MAJOR, VER_MINOR); }
nuclear@73 55 void ShowAbout(HWND win) { MessageBoxA(win, "Goat3D exporter", "About this plugin", 0); }
nuclear@73 56
nuclear@73 57 int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0);
nuclear@73 58 };
nuclear@73 59
nuclear@73 60 class GoatAnimExporterStub : public SceneExport {
nuclear@73 61 public:
nuclear@73 62 IGameScene *igame;
nuclear@73 63
nuclear@73 64 int ExtCount() { return 1; }
nuclear@73 65 const TCHAR *Ext(int n) { return L"goatanm"; }
nuclear@73 66 const TCHAR *LongDesc() { return L"Goat3D Animation file"; }
nuclear@73 67 const TCHAR *ShortDesc() { return L"Goat3D Animation"; }
nuclear@73 68 const TCHAR *AuthorName() { return L"John Tsiombikas"; }
nuclear@73 69 const TCHAR *CopyrightMessage() { return copyright_str; }
nuclear@73 70 const TCHAR *OtherMessage1() { return L"bar1"; }
nuclear@73 71 const TCHAR *OtherMessage2() { return L"bar2"; }
nuclear@73 72 unsigned int Version() { return VERSION(VER_MAJOR, VER_MINOR); }
nuclear@73 73 void ShowAbout(HWND win) { MessageBoxA(win, "Goat3D anim exporter", "About this plugin", 0); }
nuclear@73 74
nuclear@73 75 int DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL silent = FALSE, DWORD opt = 0);
nuclear@73 76 };
nuclear@73 77
nuclear@73 78 static const char *find_dll_dir()
nuclear@73 79 {
nuclear@73 80 static char path[MAX_PATH];
nuclear@73 81
nuclear@73 82 HMODULE dll;
nuclear@73 83 if(!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
nuclear@73 84 (LPCSTR)find_dll_dir, &dll)) {
nuclear@73 85 return 0;
nuclear@73 86 }
nuclear@73 87 GetModuleFileNameA(dll, path, sizeof path);
nuclear@73 88
nuclear@73 89 char *last_slash = strrchr(path, '\\');
nuclear@73 90 if(last_slash && last_slash[1]) {
nuclear@73 91 *last_slash = 0;
nuclear@73 92 }
nuclear@73 93
nuclear@73 94 return path;
nuclear@73 95 }
nuclear@73 96
nuclear@73 97 static int do_export(int which, const MCHAR *name, ExpInterface *eiface, Interface *iface, BOOL non_int, DWORD opt)
nuclear@73 98 {
nuclear@73 99 const char *dll_fname = "maxgoat.dll";
nuclear@73 100 char *dll_path;
nuclear@73 101 HMODULE dll = 0;
nuclear@73 102 PluginInitFunc init;
nuclear@73 103 PluginShutdownFunc shutdown;
nuclear@73 104 PluginClassDescFunc get_class_desc;
nuclear@73 105 ClassDesc *desc;
nuclear@73 106 SceneExport *ex;
nuclear@73 107 int result = IMPEXP_FAIL;
nuclear@73 108
nuclear@73 109 const char *plugdir = find_dll_dir();
nuclear@73 110 if(plugdir) {
nuclear@73 111 dll_path = new char[strlen(dll_fname) + strlen(plugdir) + 2];
nuclear@73 112 sprintf(dll_path, "%s\\%s", plugdir, dll_fname);
nuclear@73 113 } else {
nuclear@73 114 dll_path = new char[strlen(dll_fname) + 1];
nuclear@73 115 strcpy(dll_path, dll_fname);
nuclear@73 116 }
nuclear@73 117
nuclear@73 118 if(!(dll = LoadLibraryA(dll_path))) {
nuclear@73 119 fprintf(logfile, "failed to load exporter: %s\n", dll_path);
nuclear@73 120 goto done;
nuclear@73 121 }
nuclear@73 122
nuclear@73 123 if(!(get_class_desc = (PluginClassDescFunc)GetProcAddress(dll, "LibClassDesc"))) {
nuclear@73 124 fprintf(logfile, "maxgoat.dll is invalid (no LibClassDesc function)\n");
nuclear@73 125 goto done;
nuclear@73 126 }
nuclear@73 127
nuclear@73 128 // first initialize the library
nuclear@73 129 if((init = (PluginInitFunc)GetProcAddress(dll, "LibInitialize"))) {
nuclear@73 130 if(!init()) {
nuclear@73 131 fprintf(logfile, "exporter initialization failed!\n");
nuclear@73 132 goto done;
nuclear@73 133 }
nuclear@73 134 }
nuclear@73 135
nuclear@73 136 if(!(desc = get_class_desc(which))) {
nuclear@73 137 fprintf(logfile, "failed to get the class descriptor\n");
nuclear@73 138 goto done;
nuclear@73 139 }
nuclear@73 140
nuclear@73 141 if(!(ex = (SceneExport*)desc->Create())) {
nuclear@73 142 fprintf(logfile, "failed to create exporter class instance\n");
nuclear@73 143 goto done;
nuclear@73 144 }
nuclear@73 145
nuclear@73 146 __try {
nuclear@73 147 result = ex->DoExport(name, eiface, iface);
nuclear@73 148 }
nuclear@73 149 __except(EXCEPTION_EXECUTE_HANDLER) {
nuclear@73 150 fprintf(logfile, "Exception caught!\n");
nuclear@73 151 delete ex;
nuclear@73 152 goto done;
nuclear@73 153 }
nuclear@73 154 delete ex;
nuclear@73 155
nuclear@73 156 if((shutdown = (PluginShutdownFunc)GetProcAddress(dll, "LibShutdown"))) {
nuclear@73 157 shutdown();
nuclear@73 158 }
nuclear@73 159
nuclear@73 160 done:
nuclear@73 161 delete [] dll_path;
nuclear@73 162 if(dll) {
nuclear@73 163 FreeLibrary(dll);
nuclear@73 164 }
nuclear@73 165 return result;
nuclear@73 166 }
nuclear@73 167
nuclear@73 168 int GoatExporterStub::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface,
nuclear@73 169 BOOL non_interactive, DWORD opt)
nuclear@73 170 {
nuclear@73 171 return do_export(0, name, eiface, iface, non_interactive, opt);
nuclear@73 172 }
nuclear@73 173
nuclear@73 174
nuclear@73 175 int GoatAnimExporterStub::DoExport(const MCHAR *name, ExpInterface *eiface, Interface *iface,
nuclear@73 176 BOOL non_interactive, DWORD opt)
nuclear@73 177 {
nuclear@73 178 return do_export(1, name, eiface, iface, non_interactive, opt);
nuclear@73 179 }
nuclear@73 180
nuclear@73 181 // ------------------------------------------
nuclear@73 182
nuclear@73 183 class GoatClassDesc : public ClassDesc2 {
nuclear@73 184 public:
nuclear@73 185 int IsPublic() { return TRUE; }
nuclear@73 186 void *Create(BOOL loading = FALSE) { return new GoatExporterStub; }
nuclear@73 187 const TCHAR *ClassName() { return L"GoatExporterStub"; }
nuclear@73 188 SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
nuclear@73 189 Class_ID ClassID() { return Class_ID(0x2e4e6311, 0x2b154d91); }
nuclear@73 190 const TCHAR *Category() { return L"Mutant Stargoat"; }
nuclear@73 191
nuclear@73 192 const TCHAR *InternalName() { return L"GoatExporterStub"; }
nuclear@73 193 HINSTANCE HInstance() { return hinst; }
nuclear@73 194 };
nuclear@73 195
nuclear@73 196 class GoatAnimClassDesc : public ClassDesc2 {
nuclear@73 197 public:
nuclear@73 198 int IsPublic() { return TRUE; }
nuclear@73 199 void *Create(BOOL loading = FALSE) { return new GoatAnimExporterStub; }
nuclear@73 200 const TCHAR *ClassName() { return L"GoatAnimExporterStub"; }
nuclear@73 201 SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
nuclear@73 202 Class_ID ClassID() { return Class_ID(0x75054666, 0x45487285); }
nuclear@73 203 const TCHAR *Category() { return L"Mutant Stargoat"; }
nuclear@73 204
nuclear@73 205 const TCHAR *InternalName() { return L"GoatAnimExporterStub"; }
nuclear@73 206 HINSTANCE HInstance() { return hinst; }
nuclear@73 207 };
nuclear@73 208
nuclear@73 209
nuclear@73 210 static GoatClassDesc class_desc;
nuclear@73 211 static GoatAnimClassDesc anim_class_desc;
nuclear@73 212
nuclear@73 213 BOOL WINAPI DllMain(HINSTANCE inst_handle, ULONG reason, void *reserved)
nuclear@73 214 {
nuclear@73 215 if(reason == DLL_PROCESS_ATTACH) {
nuclear@73 216 hinst = inst_handle;
nuclear@73 217 DisableThreadLibraryCalls(hinst);
nuclear@73 218 }
nuclear@73 219 return TRUE;
nuclear@73 220 }
nuclear@73 221
nuclear@73 222 extern "C" {
nuclear@73 223
nuclear@73 224 __declspec(dllexport) const TCHAR *LibDescription()
nuclear@73 225 {
nuclear@73 226 return L"Goat3D exporter stub";
nuclear@73 227 }
nuclear@73 228
nuclear@73 229 __declspec(dllexport) int LibNumberClasses()
nuclear@73 230 {
nuclear@73 231 return 2;
nuclear@73 232 }
nuclear@73 233
nuclear@73 234 __declspec(dllexport) ClassDesc *LibClassDesc(int i)
nuclear@73 235 {
nuclear@73 236 switch(i) {
nuclear@73 237 case 0:
nuclear@73 238 return &class_desc;
nuclear@73 239 case 1:
nuclear@73 240 return &anim_class_desc;
nuclear@73 241 default:
nuclear@73 242 break;
nuclear@73 243 }
nuclear@73 244 return 0;
nuclear@73 245 }
nuclear@73 246
nuclear@73 247 __declspec(dllexport) ULONG LibVersion()
nuclear@73 248 {
nuclear@73 249 return Get3DSMAXVersion();
nuclear@73 250 }
nuclear@73 251
nuclear@73 252 __declspec(dllexport) int LibInitialize()
nuclear@73 253 {
nuclear@73 254 static char path[1024];
nuclear@73 255
nuclear@73 256 SHGetFolderPathA(0, CSIDL_PERSONAL, 0, 0, path);
nuclear@73 257 strcat(path, "/testexpstub.log");
nuclear@73 258
nuclear@73 259 if((logfile = fopen(path, "w"))) {
nuclear@73 260 setvbuf(logfile, 0, _IONBF, 0);
nuclear@73 261 }
nuclear@73 262 return TRUE;
nuclear@73 263 }
nuclear@73 264
nuclear@73 265 __declspec(dllexport) int LibShutdown()
nuclear@73 266 {
nuclear@73 267 if(logfile) {
nuclear@73 268 fclose(logfile);
nuclear@73 269 logfile = 0;
nuclear@73 270 }
nuclear@73 271 return TRUE;
nuclear@73 272 }
nuclear@73 273
nuclear@73 274 } // extern "C"