2 GenSurf plugin for GtkRadiant
\r
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
\r
5 This library is free software; you can redistribute it and/or
\r
6 modify it under the terms of the GNU Lesser General Public
\r
7 License as published by the Free Software Foundation; either
\r
8 version 2.1 of the License, or (at your option) any later version.
\r
10 This library is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
13 Lesser General Public License for more details.
\r
15 You should have received a copy of the GNU Lesser General Public
\r
16 License along with this library; if not, write to the Free Software
\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 #include <gtk/gtk.h>
\r
28 #include "gensurf.h"
\r
30 char gszAppDir[NAME_MAX];
\r
31 char gszCaption[64];
\r
32 char gszIni[NAME_MAX];
\r
33 char gszHelpFile[NAME_MAX];
\r
34 char gszMapFile[NAME_MAX];
\r
35 char gszVersion[64];
\r
38 double TexOffset[2];
\r
41 double Hll, Hur, Vll, Vur;
\r
42 double Z00, Z01, Z10, Z11;
\r
43 ELEMENT Vertex[(MAX_ROWS+1)*(MAX_ROWS+1)];
\r
48 int SnapToGrid=0; // 0, or the grid size to snap to. // Hydra : snap to grid
\r
51 int HideBackFaces=0;
\r
53 int NumVerticesSelected;
\r
66 int view_cx, view_cy;
\r
70 int Antialiasing; // ^Fishman - Antializing for the preview window.
\r
71 int AddTerrainKey; // ^Fishman - Add terrain key to func_group.
\r
72 int SP; // ^Fishman - Snap to grid.
\r
74 GtkWidget *g_pWnd; // ghwnd;
\r
75 GtkWidget *g_pRadiantWnd; // ghwnd_main;
\r
77 */GtkWidget *g_pWndPreview;
\r
78 GtkWidget *g_pPreviewWidget;
\r
80 NODE *gNode=(NODE *)NULL;
\r
81 TRI *gTri=(TRI *)NULL;
\r
84 bounding_box PlayerBox[NUMGAMES] = { {{-16., 16.}, {-16., 16.}, {-24., 32.}}, // Quake2
\r
85 {{-16., 16.}, {-16., 16.}, {-36., 36.}}, // Half-Life
\r
86 {{-16., 16.}, {-16., 16.}, {-32., 32.}}, // SiN
\r
87 {{-16., 16.}, {-16., 16.}, {-24., 32.}}, // Heretic2 (guess)
\r
88 {{-16., 16.}, {-16., 16.}, {-24., 32.}}, // KingPin (guess)
\r
89 {{-30., 30.}, {-30., 30.}, {-10.,160.}}, // Genesis3D (no idea)
\r
90 {{-16., 16.}, {-16., 16.}, {-24., 32.}}}; // Quake3 (not sure)
\r
91 //char gszOutputDir[NUMGAMES][NAME_MAX];
\r
92 //char gszTextureDir[NUMGAMES][NAME_MAX];
\r
93 char Texture[NUMGAMES][3][64];
\r
94 //char pakfile[NUMGAMES][NAME_MAX];
\r
95 //char lastpakfile[NUMGAMES][NAME_MAX];
\r
96 //int UsePak[NUMGAMES];
\r
97 //char GameDir[NUMGAMES][NAME_MAX];
\r
99 char GameName[NUMGAMES][16] = {"Quake2", "Half-Life", "SiN", "Heretic2", "Kingpin", "Genesis3D", "Quake3" };
\r
102 bool GenSurfInit ()
\r
104 strcpy (gszVersion, "1.05");
\r
105 strcpy (gszCaption, "GtkGenSurf");
\r
106 if (strlen (gszVersion))
\r
108 strcat (gszCaption, " v");
\r
109 strcat (gszCaption, gszVersion);
\r
112 strcpy (gszIni, g_FuncTable.m_pfnProfileGetDirectory ());
\r
113 strcat (gszIni, "gensurf.ini");
\r
115 /*if (g_FuncTable.m_pfnReadProjectKey != NULL)
\r
119 basepath = g_FuncTable.m_pfnReadProjectKey("basepath");
\r
122 g_strdown (basepath);
\r
123 if (strstr(basepath,"baseq3"))
\r
125 else if (strstr (basepath,"baseq2"))
\r
127 else // Gotta have a game, might as well be Quake3
\r
136 ReadIniFile (gszIni);
\r
138 if (g_pWnd == NULL)
\r
139 g_pWnd = create_main_dialog ();
\r
144 // Reads default values
\r
146 #define OPTS_SECTION "Options"
\r
148 void ReadIniFile (const char *file)
\r
154 Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Amplitude", "");
\r
156 Amplitude = atof (Text);
\r
160 Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Roughness", "");
\r
162 Roughness = atof (Text);
\r
166 Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "WaveLength", "");
\r
168 WaveLength = atof (Text);
\r
172 Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Extents", "");
\r
175 sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);
\r
189 Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "CornerValues", "");
\r
192 sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);
\r
206 Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "TextureOffset", "");
\r
209 sscanf(Text,"%f,%f",&x1,&x2);
\r
219 Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION,"TextureScale","");
\r
222 sscanf(Text,"%f,%f",&x1,&x2);
\r
225 if(TexScale[0] == 0.) TexScale[0] = 1.0;
\r
226 if(TexScale[1] == 0.) TexScale[1] = 1.0;
\r
234 NH = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NH",8);
\r
235 NH = max(1,min(NH,MAX_ROWS));
\r
236 NV = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NV",8);
\r
237 NV = max(1,min(NV,MAX_ROWS));
\r
239 // Decimate = GetPrivateProfileInt(OPTS_SECTION,"Decimate",0,file);
\r
240 // Decimate = max(0,min(Decimate,100));
\r
242 AddHints = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddHints",0);
\r
243 ArghRad2 = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"ArghRad2",0);
\r
244 AutoOverwrite = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AutoOverwrite",0);
\r
245 FixBorders = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"FixBorders",1);
\r
246 HideBackFaces = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"HideBackFaces",0);
\r
247 Plane = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Plane",0);
\r
248 Preview = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Preview", 0);
\r
249 Antialiasing = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Antialiasing",0); // ^Fishman - Antializing for the preview window.
\r
250 RandomSeed = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"RandomSeed",1);
\r
251 Skybox = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Skybox",0);
\r
252 UseDetail = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseDetail",0);
\r
253 AddTerrainKey = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddTerrainKey",0); // ^Fishman - Add terrain key to func_group.
\r
254 UseLadder = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseLadder",0);
\r
255 WaveType = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"WaveType",0);
\r
256 vid_x = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_x", 0);
\r
257 vid_y = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_y", 0);
\r
258 view_x = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_x",0);
\r
259 view_y = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_y",0);
\r
260 view_cx = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cx",0);
\r
261 view_cy = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cy",0);
\r
263 UsePatches = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UsePatches",0);
\r
265 SlantAngle = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"SlantAngle",60);
\r
266 GimpHints = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"GimpHints",0);
\r
268 for(i=0; i<NUMGAMES; i++)
\r
270 // strcpy (gszOutputDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"OutputDir",""));
\r
271 strcpy (Texture[i][0], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture", ""));
\r
272 strcpy (Texture[i][1], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture2", ""));
\r
273 strcpy (Texture[i][2], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture3", ""));
\r
274 // strcpy (gszTextureDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"TextureDir",""));
\r
275 // UsePak[i] = GetPrivateProfileInt(GameName[i],"UsePak",0);
\r
276 // strcpy (pakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"PakFile",""));
\r
277 // strcpy (lastpakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"LastPakFile",""));
\r
278 // strcpy (GameDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"GameDir","\0"));
\r
281 if(!strlen(gszTextureDir[QUAKE2]))
\r
282 strcpy(gszTextureDir[QUAKE2],"c:\\quake2\\baseq2\\textures\\");
\r
283 if(!strlen(gszTextureDir[KINGPIN]))
\r
284 strcpy(gszTextureDir[KINGPIN],"c:\\kingpin\\main\\textures\\");
\r
286 if(!strlen(Texture[QUAKE2][0])) strcpy(Texture[QUAKE2][0], "textures/e1u1/grass1_4");
\r
287 if(!strlen(Texture[HALFLIFE][0])) strcpy(Texture[HALFLIFE][0], "textures/OUT_GRND1");
\r
288 if(!strlen(Texture[SIN][0])) strcpy(Texture[SIN][0], "textures/generic/floor_organic/fl_grass");
\r
289 if(!strlen(Texture[HERETIC2][0])) strcpy(Texture[HERETIC2][0], "textures/canyon/canyon05");
\r
290 if(!strlen(Texture[KINGPIN][0])) strcpy(Texture[KINGPIN][0], "textures/bricks/s_sr_m3");
\r
291 if(!strlen(Texture[GENESIS3D][0])) strcpy(Texture[GENESIS3D][0],"textures/rock13");
\r
292 if(!strlen(Texture[QUAKE3][0])) strcpy(Texture[QUAKE3][0], "textures/organics/grass3");
\r
293 if(!strlen(Texture[QUAKE3][1])) strcpy(Texture[QUAKE3][1], "textures/common/caulk");
\r
295 strcpy (gbmp.name, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","Filename",""));
\r
297 if (strlen(gbmp.name))
\r
300 strcpy (gbmp.defpath, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","DefaultPath",""));
\r
302 Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","BlackValue","");
\r
304 gbmp.black_value = atof (Text);
\r
306 gbmp.black_value = 0;
\r
308 Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","WhiteValue","");
\r
310 gbmp.white_value = atof (Text);
\r
312 gbmp.white_value = 256.;
\r
319 does a varargs printf into a temp buffer, so I don't need to have
\r
320 varargs versions of all text functions.
\r
321 FIXME: make this buffer size safe someday
\r
324 char *va (char *format, ...)
\r
327 static char string[1024];
\r
329 va_start (argptr, format);
\r
330 vsprintf (string, format,argptr);
\r
337 // Writes current values to INI file
\r
338 void WriteIniFile(const char *file)
\r
342 g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Amplitude", va("%g",Amplitude));
\r
343 g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Roughness", va("%g",Roughness));
\r
344 g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "WaveLength", va("%g",WaveLength));
\r
345 g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Extents", va("%g,%g,%g,%g",Hll,Vll,Hur,Vur));
\r
346 g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "CornerValues", va("%g,%g,%g,%g",Z00,Z01,Z10,Z11));
\r
347 g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureOffset",va("%g,%g",TexOffset[0],TexOffset[1]));
\r
348 g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureScale", va("%g,%g",TexScale[0],TexScale[1]));
\r
349 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NH", NH);
\r
350 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NV", NV);
\r
351 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddHints", AddHints);
\r
352 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "ArghRad2", ArghRad2);
\r
353 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AutoOverwrite", AutoOverwrite);
\r
354 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "FixBorders", FixBorders);
\r
355 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Plane", Plane);
\r
356 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Preview", Preview);
\r
357 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Antialiasing", Antialiasing); // ^Fishman - Antializing for the preview window.
\r
358 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "RandomSeed", RandomSeed);
\r
359 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Skybox", Skybox);
\r
360 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseDetail", UseDetail);
\r
361 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddTerrainKey", AddTerrainKey); // ^Fishman - Add terrain key to func_group.
\r
362 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseLadder", UseLadder);
\r
363 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "WaveType", WaveType);
\r
364 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_x", vid_x);
\r
365 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_y", vid_y);
\r
366 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_x", view_x);
\r
367 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_y", view_y);
\r
368 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cx", view_cx);
\r
369 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cy", view_cy);
\r
370 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UsePatches", UsePatches);
\r
371 g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "SlantAngle", SlantAngle);
\r
372 for(i=0; i<NUMGAMES; i++)
\r
374 g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture", Texture[i][0] );
\r
375 g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture2", Texture[i][1] );
\r
376 g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture3", Texture[i][2] );
\r
379 g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "Filename", gbmp.name );
\r
380 g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "DefaultPath", gbmp.defpath );
\r
381 g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "BlackValue", va("%g",gbmp.black_value));
\r
382 g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "WhiteValue", va("%g",gbmp.white_value));
\r
383 //g_FuncTable.m_pfnProfileSaveString (file, "Formula", "Formula", ExcelFunc );
\r
386 void UpdatePreview (bool DataChange)
\r
388 if (g_pWndPreview && GTK_WIDGET_VISIBLE (g_pWndPreview))
\r
393 gtk_widget_draw (g_pPreviewWidget, NULL);
\r
397 void SaveSetup (GtkWidget *parent)
\r
399 const char *name = g_FuncTable.m_pfnFileDialog (parent, false, "Save GenSurf Settings",
\r
400 g_FuncTable.m_pfnProfileGetDirectory ());
\r
404 char key[32], text[32];
\r
407 WriteIniFile (name);
\r
408 g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"MapFile",gszMapFile);
\r
409 sprintf(text,"0x%04x",FileAppend);
\r
410 g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Append",text);
\r
411 sprintf(text,"0x%04x",Decimate);
\r
412 g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Decimate",text);
\r
413 for(i=0; i<=NH; i++)
\r
415 for(j=0; j<=NV; j++)
\r
417 if(xyz[i][j].fixed)
\r
419 sprintf(key,"I%dJ%d",i,j);
\r
420 sprintf(text,"%g %g %g", xyz[i][j].fixed_value, xyz[i][j].range, xyz[i][j].rate);
\r
421 g_FuncTable.m_pfnProfileSaveString (name, "FixedPoints",key,text);
\r
428 void OpenSetup (GtkWidget *parent, int UseDefaults)
\r
431 char key[32], *text;
\r
432 float value,range,rate;
\r
436 name = g_strdup ("plugins/defaults.srf"); // dummy string
\r
438 name = g_FuncTable.m_pfnFileDialog (parent, true, "Open GenSurf Settings",
\r
439 g_FuncTable.m_pfnProfileGetDirectory ());
\r
443 ReadIniFile (name);
\r
444 Decimate = g_FuncTable.m_pfnProfileLoadInt (name, OPTS_SECTION,"Decimate",0);
\r
445 Decimate = max(0,min(Decimate,100));
\r
447 for (i=0; i<=NH; i++)
\r
449 for (j=0; j<=NV; j++)
\r
451 sprintf(key,"I%dJ%d",i,j);
\r
452 text = g_FuncTable.m_pfnProfileLoadString (name, "FixedPoints", key, "");
\r
455 xyz[i][j].fixed = 1;
\r
456 xyz[i][j].rate = 0.;
\r
457 sscanf(text,"%g %g %g",&value,&range,&rate);
\r
458 xyz[i][j].fixed_value = value;
\r
459 xyz[i][j].range = range;
\r
460 xyz[i][j].rate = rate;
\r
463 xyz[i][j].fixed = 0;
\r