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"
|