2 GenSurf plugin for GtkRadiant
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 char gszAppDir[NAME_MAX];
32 char gszIni[NAME_MAX];
33 char gszHelpFile[NAME_MAX];
34 char gszMapFile[NAME_MAX];
41 double Hll, Hur, Vll, Vur;
42 double Z00, Z01, Z10, Z11;
43 ELEMENT Vertex[(MAX_ROWS + 1) * (MAX_ROWS + 1)];
48 int SnapToGrid = 0; // 0, or the grid size to snap to. // Hydra : snap to grid
51 int HideBackFaces = 0;
53 int NumVerticesSelected;
70 int Antialiasing; // ^Fishman - Antializing for the preview window.
71 int AddTerrainKey; // ^Fishman - Add terrain key to func_group.
72 int SP; // ^Fishman - Snap to grid.
74 ui::Window g_pWnd{ui::null}; // ghwnd;
75 GtkWidget *g_pRadiantWnd; // ghwnd_main;
77 */GtkWidget *g_pWndPreview;
78 GtkWidget *g_pPreviewWidget;
80 NODE *gNode = (NODE *) NULL;
81 TRI *gTri = (TRI *) NULL;
84 bounding_box PlayerBox[NUMGAMES] = {{{-16., 16.}, {-16., 16.}, {-24., 32.}}, // Quake2
85 {{-16., 16.}, {-16., 16.}, {-36., 36.}}, // Half-Life
86 {{-16., 16.}, {-16., 16.}, {-32., 32.}}, // SiN
87 {{-16., 16.}, {-16., 16.}, {-24., 32.}}, // Heretic2 (guess)
88 {{-16., 16.}, {-16., 16.}, {-24., 32.}}, // KingPin (guess)
89 {{-30., 30.}, {-30., 30.}, {-10., 160.}}, // Genesis3D (no idea)
90 {{-16., 16.}, {-16., 16.}, {-24., 32.}}}; // Quake3 (not sure)
91 //char gszOutputDir[NUMGAMES][NAME_MAX];
92 //char gszTextureDir[NUMGAMES][NAME_MAX];
93 char Texture[NUMGAMES][3][64];
94 //char pakfile[NUMGAMES][NAME_MAX];
95 //char lastpakfile[NUMGAMES][NAME_MAX];
96 //int UsePak[NUMGAMES];
97 //char GameDir[NUMGAMES][NAME_MAX];
99 char GameName[NUMGAMES][16] = {"Quake2", "Half-Life", "SiN", "Heretic2", "Kingpin", "Genesis3D", "Quake3"};
104 strcpy(gszVersion, "1.05");
105 strcpy(gszCaption, "GtkGenSurf");
106 if (strlen(gszVersion)) {
107 strcat(gszCaption, " v");
108 strcat(gszCaption, gszVersion);
111 strcpy(gszIni, g_FuncTable.m_pfnProfileGetDirectory());
112 strcat(gszIni, "gensurf.ini");
114 /*if (g_FuncTable.m_pfnReadProjectKey != NULL)
118 basepath = g_FuncTable.m_pfnReadProjectKey("basepath");
121 g_strdown (basepath);
122 if (strstr(basepath,"baseq3"))
124 else if (strstr (basepath,"baseq2"))
126 else // Gotta have a game, might as well be Quake3
136 if (g_pWnd == NULL) {
137 g_pWnd = create_main_dialog();
145 // Reads default values
147 #define OPTS_SECTION "Options"
149 void ReadIniFile(const char *file)
152 float x1, x2, x3, x4;
155 Text = g_FuncTable.m_pfnProfileLoadString(file, OPTS_SECTION, "Amplitude", "");
157 Amplitude = atof(Text);
162 Text = g_FuncTable.m_pfnProfileLoadString(file, OPTS_SECTION, "Roughness", "");
164 Roughness = atof(Text);
169 Text = g_FuncTable.m_pfnProfileLoadString(file, OPTS_SECTION, "WaveLength", "");
171 WaveLength = atof(Text);
176 Text = g_FuncTable.m_pfnProfileLoadString(file, OPTS_SECTION, "Extents", "");
178 sscanf(Text, "%f,%f,%f,%f", &x1, &x2, &x3, &x4);
190 Text = g_FuncTable.m_pfnProfileLoadString(file, OPTS_SECTION, "CornerValues", "");
192 sscanf(Text, "%f,%f,%f,%f", &x1, &x2, &x3, &x4);
204 Text = g_FuncTable.m_pfnProfileLoadString(file, OPTS_SECTION, "TextureOffset", "");
206 sscanf(Text, "%f,%f", &x1, &x2);
214 Text = g_FuncTable.m_pfnProfileLoadString(file, OPTS_SECTION, "TextureScale", "");
216 sscanf(Text, "%f,%f", &x1, &x2);
219 if (TexScale[0] == 0.) {
222 if (TexScale[1] == 0.) {
230 NH = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "NH", 8);
231 NH = max(1, min(NH, MAX_ROWS));
232 NV = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "NV", 8);
233 NV = max(1, min(NV, MAX_ROWS));
235 // Decimate = GetPrivateProfileInt(OPTS_SECTION,"Decimate",0,file);
236 // Decimate = max(0,min(Decimate,100));
238 AddHints = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "AddHints", 0);
239 ArghRad2 = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "ArghRad2", 0);
240 AutoOverwrite = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "AutoOverwrite", 0);
241 FixBorders = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "FixBorders", 1);
242 HideBackFaces = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "HideBackFaces", 0);
243 Plane = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "Plane", 0);
244 Preview = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "Preview", 0);
245 Antialiasing = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "Antialiasing",
246 0); // ^Fishman - Antializing for the preview window.
247 RandomSeed = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "RandomSeed", 1);
248 Skybox = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "Skybox", 0);
249 UseDetail = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "UseDetail", 0);
250 AddTerrainKey = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "AddTerrainKey",
251 0); // ^Fishman - Add terrain key to func_group.
252 UseLadder = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "UseLadder", 0);
253 WaveType = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "WaveType", 0);
254 vid_x = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "vid_x", 0);
255 vid_y = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "vid_y", 0);
256 view_x = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "view_x", 0);
257 view_y = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "view_y", 0);
258 view_cx = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "view_cx", 0);
259 view_cy = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "view_cy", 0);
261 UsePatches = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "UsePatches", 0);
263 SlantAngle = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "SlantAngle", 60);
264 GimpHints = g_FuncTable.m_pfnProfileLoadInt(file, OPTS_SECTION, "GimpHints", 0);
266 for (i = 0; i < NUMGAMES; i++) {
267 // strcpy (gszOutputDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"OutputDir",""));
268 strcpy(Texture[i][0], g_FuncTable.m_pfnProfileLoadString(file, GameName[i], "Texture", ""));
269 strcpy(Texture[i][1], g_FuncTable.m_pfnProfileLoadString(file, GameName[i], "Texture2", ""));
270 strcpy(Texture[i][2], g_FuncTable.m_pfnProfileLoadString(file, GameName[i], "Texture3", ""));
271 // strcpy (gszTextureDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"TextureDir",""));
272 // UsePak[i] = GetPrivateProfileInt(GameName[i],"UsePak",0);
273 // strcpy (pakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"PakFile",""));
274 // strcpy (lastpakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"LastPakFile",""));
275 // strcpy (GameDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"GameDir","\0"));
278 if(!strlen(gszTextureDir[QUAKE2]))
279 strcpy(gszTextureDir[QUAKE2],"c:\\quake2\\baseq2\\textures\\");
280 if(!strlen(gszTextureDir[KINGPIN]))
281 strcpy(gszTextureDir[KINGPIN],"c:\\kingpin\\main\\textures\\");
283 if (!strlen(Texture[QUAKE2][0])) {
284 strcpy(Texture[QUAKE2][0], "textures/e1u1/grass1_4");
286 if (!strlen(Texture[HALFLIFE][0])) {
287 strcpy(Texture[HALFLIFE][0], "textures/OUT_GRND1");
289 if (!strlen(Texture[SIN][0])) {
290 strcpy(Texture[SIN][0], "textures/generic/floor_organic/fl_grass");
292 if (!strlen(Texture[HERETIC2][0])) {
293 strcpy(Texture[HERETIC2][0], "textures/canyon/canyon05");
295 if (!strlen(Texture[KINGPIN][0])) {
296 strcpy(Texture[KINGPIN][0], "textures/bricks/s_sr_m3");
298 if (!strlen(Texture[GENESIS3D][0])) {
299 strcpy(Texture[GENESIS3D][0], "textures/rock13");
301 if (!strlen(Texture[QUAKE3][0])) {
302 strcpy(Texture[QUAKE3][0], "textures/organics/grass3");
304 if (!strlen(Texture[QUAKE3][1])) {
305 strcpy(Texture[QUAKE3][1], "textures/common/caulk");
307 strcpy(gbmp.name, g_FuncTable.m_pfnProfileLoadString(file, "Bitmap", "Filename", ""));
311 if (strlen(gbmp.name)) {
315 strcpy(gbmp.defpath, g_FuncTable.m_pfnProfileLoadString(file, "Bitmap", "DefaultPath", ""));
317 Text = g_FuncTable.m_pfnProfileLoadString(file, "Bitmap", "BlackValue", "");
319 gbmp.black_value = atof(Text);
321 gbmp.black_value = 0;
324 Text = g_FuncTable.m_pfnProfileLoadString(file, "Bitmap", "WhiteValue", "");
326 gbmp.white_value = atof(Text);
328 gbmp.white_value = 256.;
336 does a varargs printf into a temp buffer, so I don't need to have
337 varargs versions of all text functions.
338 FIXME: make this buffer size safe someday
341 char *va(const char *format, ...)
344 static char string[1024];
346 va_start(argptr, format);
347 vsprintf(string, format, argptr);
354 // Writes current values to INI file
355 void WriteIniFile(const char *file)
359 g_FuncTable.m_pfnProfileSaveString(file, OPTS_SECTION, "Amplitude", va("%g", Amplitude));
360 g_FuncTable.m_pfnProfileSaveString(file, OPTS_SECTION, "Roughness", va("%g", Roughness));
361 g_FuncTable.m_pfnProfileSaveString(file, OPTS_SECTION, "WaveLength", va("%g", WaveLength));
362 g_FuncTable.m_pfnProfileSaveString(file, OPTS_SECTION, "Extents", va("%g,%g,%g,%g", Hll, Vll, Hur, Vur));
363 g_FuncTable.m_pfnProfileSaveString(file, OPTS_SECTION, "CornerValues", va("%g,%g,%g,%g", Z00, Z01, Z10, Z11));
364 g_FuncTable.m_pfnProfileSaveString(file, OPTS_SECTION, "TextureOffset", va("%g,%g", TexOffset[0], TexOffset[1]));
365 g_FuncTable.m_pfnProfileSaveString(file, OPTS_SECTION, "TextureScale", va("%g,%g", TexScale[0], TexScale[1]));
366 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "NH", NH);
367 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "NV", NV);
368 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "AddHints", AddHints);
369 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "ArghRad2", ArghRad2);
370 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "AutoOverwrite", AutoOverwrite);
371 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "FixBorders", FixBorders);
372 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "Plane", Plane);
373 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "Preview", Preview);
374 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "Antialiasing",
375 Antialiasing); // ^Fishman - Antializing for the preview window.
376 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "RandomSeed", RandomSeed);
377 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "Skybox", Skybox);
378 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "UseDetail", UseDetail);
379 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "AddTerrainKey",
380 AddTerrainKey); // ^Fishman - Add terrain key to func_group.
381 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "UseLadder", UseLadder);
382 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "WaveType", WaveType);
383 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "vid_x", vid_x);
384 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "vid_y", vid_y);
385 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "view_x", view_x);
386 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "view_y", view_y);
387 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "view_cx", view_cx);
388 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "view_cy", view_cy);
389 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "UsePatches", UsePatches);
390 g_FuncTable.m_pfnProfileSaveInt(file, OPTS_SECTION, "SlantAngle", SlantAngle);
391 for (i = 0; i < NUMGAMES; i++) {
392 g_FuncTable.m_pfnProfileSaveString(file, GameName[i], "Texture", Texture[i][0]);
393 g_FuncTable.m_pfnProfileSaveString(file, GameName[i], "Texture2", Texture[i][1]);
394 g_FuncTable.m_pfnProfileSaveString(file, GameName[i], "Texture3", Texture[i][2]);
397 g_FuncTable.m_pfnProfileSaveString(file, "Bitmap", "Filename", gbmp.name);
398 g_FuncTable.m_pfnProfileSaveString(file, "Bitmap", "DefaultPath", gbmp.defpath);
399 g_FuncTable.m_pfnProfileSaveString(file, "Bitmap", "BlackValue", va("%g", gbmp.black_value));
400 g_FuncTable.m_pfnProfileSaveString(file, "Bitmap", "WhiteValue", va("%g", gbmp.white_value));
401 //g_FuncTable.m_pfnProfileSaveString (file, "Formula", "Formula", ExcelFunc );
404 void UpdatePreview(bool DataChange)
406 if (g_pWndPreview && gtk_widget_get_visible(g_pWndPreview)) {
411 gtk_widget_draw(g_pPreviewWidget, NULL);
415 void SaveSetup(GtkWidget *parent)
417 const char *name = g_FuncTable.m_pfnFileDialog(parent, false, "Save GenSurf Settings",
418 g_FuncTable.m_pfnProfileGetDirectory());
421 char key[32], text[32];
425 g_FuncTable.m_pfnProfileSaveString(name, OPTS_SECTION, "MapFile", gszMapFile);
426 sprintf(text, "0x%04x", FileAppend);
427 g_FuncTable.m_pfnProfileSaveString(name, OPTS_SECTION, "Append", text);
428 sprintf(text, "0x%04x", Decimate);
429 g_FuncTable.m_pfnProfileSaveString(name, OPTS_SECTION, "Decimate", text);
430 for (i = 0; i <= NH; i++) {
431 for (j = 0; j <= NV; j++) {
432 if (xyz[i][j].fixed) {
433 sprintf(key, "I%dJ%d", i, j);
434 sprintf(text, "%g %g %g", xyz[i][j].fixed_value, xyz[i][j].range, xyz[i][j].rate);
435 g_FuncTable.m_pfnProfileSaveString(name, "FixedPoints", key, text);
442 void OpenSetup(GtkWidget *parent, int UseDefaults)
446 float value, range, rate;
450 name = g_strdup("plugins/defaults.srf"); // dummy string
452 name = g_FuncTable.m_pfnFileDialog(parent, true, "Open GenSurf Settings",
453 g_FuncTable.m_pfnProfileGetDirectory());
458 Decimate = g_FuncTable.m_pfnProfileLoadInt(name, OPTS_SECTION, "Decimate", 0);
459 Decimate = max(0, min(Decimate, 100));
461 for (i = 0; i <= NH; i++) {
462 for (j = 0; j <= NV; j++) {
463 sprintf(key, "I%dJ%d", i, j);
464 text = g_FuncTable.m_pfnProfileLoadString(name, "FixedPoints", key, "");
468 sscanf(text, "%g %g %g", &value, &range, &rate);
469 xyz[i][j].fixed_value = value;
470 xyz[i][j].range = range;
471 xyz[i][j].rate = rate;