goat3d

annotate exporters/maxgoat_stub/src/stub.cc @ 58:d317eb4f83da

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