]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/gensurf.cpp
* fixed a lot of compiler warnings (mostly const char * stuff and use of uninitialize...
[xonotic/netradiant.git] / contrib / gtkgensurf / gensurf.cpp
1 /*
2 GenSurf plugin for GtkRadiant
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
4
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.
9
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.
14
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
18 */
19
20 #include <gtk/gtk.h>
21 #include <glib/gi18n.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 /*
25 #include <string.h>
26 #include <tchar.h>
27 #include <math.h>
28 */
29 #include "gensurf.h"
30
31 char      gszAppDir[NAME_MAX];
32 char      gszCaption[64];
33 char      gszIni[NAME_MAX];
34 char      gszHelpFile[NAME_MAX];
35 char      gszMapFile[NAME_MAX];
36 char      gszVersion[64];
37 double    Amplitude;
38 double    Roughness;
39 double    TexOffset[2];
40 double    TexScale[2];
41 double    WaveLength;
42 double    Hll, Hur, Vll, Vur;
43 double    Z00, Z01, Z10, Z11;
44 ELEMENT   Vertex[(MAX_ROWS+1)*(MAX_ROWS+1)];
45 int       AddHints;
46 int       ArghRad2;
47 int       AutoOverwrite;
48 int       Decimate=0;
49 int                             SnapToGrid=0; // 0, or the grid size to snap to. // Hydra : snap to grid
50 int       FileAppend=0;
51 int       FixBorders;
52 int       HideBackFaces=0;
53 int       NH, NV;
54 int       NumVerticesSelected;
55 int       Plane;
56 int       Preview;
57 int       RandomSeed=1;
58 int       Skybox;
59 int       UseDetail;
60 int       UseLadder;
61 int       VertexMode=0;
62 int       WaveType;
63 int       gNumNodes=0;
64 int       gNumTris=0;
65 int       vid_x, vid_y;
66 int       view_x, view_y;
67 int       view_cx, view_cy;
68 int       UsePatches;
69 int       SlantAngle;
70 int       GimpHints;
71 int                             Antialiasing; // ^Fishman - Antializing for the preview window.
72 int                             AddTerrainKey; // ^Fishman - Add terrain key to func_group.
73 int                             SP; // ^Fishman - Snap to grid.
74
75 GtkWidget *g_pWnd;        // ghwnd;
76 GtkWidget *g_pRadiantWnd; // ghwnd_main;
77 /*HWND      ghwndAngles;
78 */GtkWidget *g_pWndPreview;
79 GtkWidget *g_pPreviewWidget;
80 MYBITMAP  gbmp;
81 NODE      *gNode=(NODE *)NULL;
82 TRI       *gTri=(TRI *)NULL;
83
84 int       Game;
85 bounding_box PlayerBox[NUMGAMES] = { {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Quake2
86                                      {{-16., 16.}, {-16., 16.}, {-36., 36.}},    // Half-Life
87                                      {{-16., 16.}, {-16., 16.}, {-32., 32.}},    // SiN
88                                      {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // Heretic2 (guess)
89                                      {{-16., 16.}, {-16., 16.}, {-24., 32.}},    // KingPin (guess)
90                                      {{-30., 30.}, {-30., 30.}, {-10.,160.}},    // Genesis3D (no idea)
91                                      {{-16., 16.}, {-16., 16.}, {-24., 32.}}};   // Quake3 (not sure)
92 //char      gszOutputDir[NUMGAMES][NAME_MAX];
93 //char      gszTextureDir[NUMGAMES][NAME_MAX];
94 char      Texture[NUMGAMES][3][64];
95 //char      pakfile[NUMGAMES][NAME_MAX];
96 //char      lastpakfile[NUMGAMES][NAME_MAX];
97 //int       UsePak[NUMGAMES];
98 //char      GameDir[NUMGAMES][NAME_MAX];
99
100 char GameName[NUMGAMES][16] = {"Quake2", "Half-Life", "SiN", "Heretic2", "Kingpin", "Genesis3D", "Quake3" };
101
102
103 bool GenSurfInit ()
104 {
105   strcpy (gszVersion, "1.05");
106   strcpy (gszCaption, "GtkGenSurf");
107   if (strlen (gszVersion))
108   {
109     strcat (gszCaption, " v");
110     strcat (gszCaption, gszVersion);
111   }
112
113   strcpy (gszIni, g_FuncTable.m_pfnProfileGetDirectory ());
114   strcat (gszIni, "gensurf.ini");
115
116 /*if (g_FuncTable.m_pfnReadProjectKey != NULL)
117   {
118     char *basepath;
119
120     basepath = g_FuncTable.m_pfnReadProjectKey("basepath");
121     if (basepath)
122     {
123       g_strdown (basepath);
124       if (strstr(basepath,"baseq3"))
125         Game = QUAKE3;
126       else if (strstr (basepath,"baseq2"))
127         Game = QUAKE2;
128       else // Gotta have a game, might as well be Quake3
129         Game = QUAKE3;
130     }
131     else
132       Game = QUAKE3;
133   }
134   else */
135     Game = QUAKE3;
136
137   ReadIniFile (gszIni);
138
139   if (g_pWnd == NULL)
140     g_pWnd = create_main_dialog ();
141
142   return true;
143 }
144
145 // Reads default values
146
147 #define OPTS_SECTION "Options"
148
149 void ReadIniFile (const char *file)
150 {
151   char *Text;
152   float x1,x2,x3,x4;
153   int   i;
154
155   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Amplitude", "");
156   if (strlen (Text))
157     Amplitude = atof (Text);
158   else
159     Amplitude = 128;
160
161   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Roughness", "");
162   if (strlen (Text))
163     Roughness = atof (Text);
164   else
165     Roughness = 16;
166
167   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "WaveLength", "");
168   if (strlen (Text))
169     WaveLength = atof (Text);
170   else
171     WaveLength = 1024;
172
173   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "Extents", "");
174   if (strlen (Text))
175   {
176     sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);
177     Hll = x1;
178     Vll = x2;
179     Hur = x3;
180     Vur = x4;
181   }
182   else
183   {
184     Hll = -512;
185     Vll = -512;
186     Hur =  512;
187     Vur =  512;
188   }
189
190   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "CornerValues", "");
191   if (strlen (Text))
192   {
193     sscanf(Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4);
194     Z00 = x1;
195     Z01 = x2;
196     Z10 = x3;
197     Z11 = x4;
198   }
199   else
200   {
201     Z00 = 0.;
202     Z01 = 0.;
203     Z10 = 0.;
204     Z11 = 0.;
205   }
206
207   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION, "TextureOffset", "");
208   if (strlen (Text))
209   {
210     sscanf(Text,"%f,%f",&x1,&x2);
211     TexOffset[0] = x1;
212     TexOffset[1] = x2;
213   }
214   else
215   {
216     TexOffset[0] = 0.;
217     TexOffset[1] = 0.;
218   }
219
220   Text = g_FuncTable.m_pfnProfileLoadString (file, OPTS_SECTION,"TextureScale","");
221   if (strlen (Text))
222   {
223     sscanf(Text,"%f,%f",&x1,&x2);
224     TexScale[0] = x1;
225     TexScale[1] = x2;
226     if(TexScale[0] == 0.) TexScale[0] = 1.0;
227     if(TexScale[1] == 0.) TexScale[1] = 1.0;
228   }
229   else
230   {
231     TexScale[0] = 1.;
232     TexScale[1] = 1.;
233   }
234
235   NH = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NH",8);
236   NH = max(1,min(NH,MAX_ROWS));
237   NV = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"NV",8);
238   NV = max(1,min(NV,MAX_ROWS));
239
240 //      Decimate   = GetPrivateProfileInt(OPTS_SECTION,"Decimate",0,file);
241 //      Decimate = max(0,min(Decimate,100));
242
243   AddHints                      = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddHints",0);
244   ArghRad2                      = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"ArghRad2",0);
245   AutoOverwrite = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AutoOverwrite",0);
246   FixBorders            = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"FixBorders",1);
247   HideBackFaces = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"HideBackFaces",0);
248   Plane                                 = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Plane",0);
249   Preview                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Preview", 0);
250         Antialiasing    = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Antialiasing",0); // ^Fishman - Antializing for the preview window.
251   RandomSeed            = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"RandomSeed",1);
252   Skybox                                = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"Skybox",0);
253   UseDetail                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseDetail",0);
254         AddTerrainKey   =       g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"AddTerrainKey",0); // ^Fishman - Add terrain key to func_group.
255   UseLadder                     = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UseLadder",0);
256   WaveType                      = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"WaveType",0);
257   vid_x                                 = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_x", 0);
258   vid_y                                 = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"vid_y", 0);
259   view_x                                = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_x",0);
260   view_y                                = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_y",0);
261   view_cx                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cx",0);
262   view_cy                               = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"view_cy",0);
263
264   UsePatches            = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"UsePatches",0);
265
266   SlantAngle = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"SlantAngle",60);
267   GimpHints  = g_FuncTable.m_pfnProfileLoadInt (file, OPTS_SECTION,"GimpHints",0);
268
269   for(i=0; i<NUMGAMES; i++)
270   {
271     //    strcpy (gszOutputDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"OutputDir",""));
272     strcpy (Texture[i][0], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture", ""));
273     strcpy (Texture[i][1], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture2", ""));
274     strcpy (Texture[i][2], g_FuncTable.m_pfnProfileLoadString (file, GameName[i], "Texture3", ""));
275     //    strcpy (gszTextureDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"TextureDir",""));
276     //    UsePak[i] = GetPrivateProfileInt(GameName[i],"UsePak",0);
277     //    strcpy (pakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"PakFile",""));
278     //    strcpy (lastpakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"LastPakFile",""));
279     //    strcpy (GameDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"GameDir","\0"));
280   }
281   /*
282         if(!strlen(gszTextureDir[QUAKE2]))
283                 strcpy(gszTextureDir[QUAKE2],"c:\\quake2\\baseq2\\textures\\");
284         if(!strlen(gszTextureDir[KINGPIN]))
285                 strcpy(gszTextureDir[KINGPIN],"c:\\kingpin\\main\\textures\\");
286   */
287   if(!strlen(Texture[QUAKE2][0]))    strcpy(Texture[QUAKE2][0],   "textures/e1u1/grass1_4");
288   if(!strlen(Texture[HALFLIFE][0]))  strcpy(Texture[HALFLIFE][0], "textures/OUT_GRND1");
289   if(!strlen(Texture[SIN][0]))       strcpy(Texture[SIN][0],      "textures/generic/floor_organic/fl_grass");
290   if(!strlen(Texture[HERETIC2][0]))  strcpy(Texture[HERETIC2][0], "textures/canyon/canyon05");
291   if(!strlen(Texture[KINGPIN][0]))   strcpy(Texture[KINGPIN][0],  "textures/bricks/s_sr_m3");
292   if(!strlen(Texture[GENESIS3D][0])) strcpy(Texture[GENESIS3D][0],"textures/rock13");
293   if(!strlen(Texture[QUAKE3][0]))    strcpy(Texture[QUAKE3][0],   "textures/organics/grass3");
294   if(!strlen(Texture[QUAKE3][1]))    strcpy(Texture[QUAKE3][1],   "textures/common/caulk");
295
296   strcpy (gbmp.name, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","Filename",""));
297
298   if (strlen(gbmp.name))
299     OpenBitmap ();
300
301   strcpy (gbmp.defpath, g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","DefaultPath",""));
302
303   Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","BlackValue","");
304   if (strlen (Text))
305     gbmp.black_value = atof (Text);
306   else
307     gbmp.black_value = 0;
308
309   Text = g_FuncTable.m_pfnProfileLoadString (file, "Bitmap","WhiteValue","");
310   if (strlen (Text))
311     gbmp.white_value = atof (Text);
312   else
313     gbmp.white_value = 256.;
314 }
315
316 /*
317 ============
318 va
319
320 does a varargs printf into a temp buffer, so I don't need to have
321 varargs versions of all text functions.
322 FIXME: make this buffer size safe someday
323 ============
324 */
325 char *va (char *format, ...)
326 {
327   va_list argptr;
328   static char string[1024];
329
330   va_start (argptr, format);
331   vsprintf (string, format,argptr);
332   va_end (argptr);
333
334   return string;
335 }
336
337
338 // Writes current values to INI file
339 void WriteIniFile(const char *file)
340 {
341   int i;
342
343   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Amplitude",    va("%g",Amplitude));
344   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Roughness",    va("%g",Roughness));
345   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "WaveLength",   va("%g",WaveLength));
346   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "Extents",      va("%g,%g,%g,%g",Hll,Vll,Hur,Vur));
347   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "CornerValues", va("%g,%g,%g,%g",Z00,Z01,Z10,Z11));
348   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureOffset",va("%g,%g",TexOffset[0],TexOffset[1]));
349   g_FuncTable.m_pfnProfileSaveString (file, OPTS_SECTION, "TextureScale", va("%g,%g",TexScale[0],TexScale[1]));
350   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NH", NH);
351   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "NV", NV);
352   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddHints", AddHints);
353   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "ArghRad2", ArghRad2);
354   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AutoOverwrite", AutoOverwrite);
355   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "FixBorders", FixBorders);
356   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Plane", Plane);
357   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Preview", Preview);
358         g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Antialiasing", Antialiasing); // ^Fishman - Antializing for the preview window.
359   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "RandomSeed", RandomSeed);
360   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "Skybox", Skybox);
361   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseDetail", UseDetail);
362   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "AddTerrainKey", AddTerrainKey); // ^Fishman - Add terrain key to func_group.
363   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UseLadder", UseLadder);
364   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "WaveType", WaveType);
365   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_x", vid_x);
366   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "vid_y", vid_y);
367   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_x", view_x);
368   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_y", view_y);
369   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cx", view_cx);
370   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "view_cy", view_cy);
371   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "UsePatches", UsePatches);
372   g_FuncTable.m_pfnProfileSaveInt (file, OPTS_SECTION, "SlantAngle", SlantAngle);
373   for(i=0; i<NUMGAMES; i++)
374   {
375     g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture",   Texture[i][0] );
376     g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture2",  Texture[i][1] );
377     g_FuncTable.m_pfnProfileSaveString (file, GameName[i], "Texture3",  Texture[i][2] );
378   }
379
380   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "Filename", gbmp.name );
381   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "DefaultPath", gbmp.defpath );
382   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "BlackValue", va("%g",gbmp.black_value));
383   g_FuncTable.m_pfnProfileSaveString (file, "Bitmap", "WhiteValue", va("%g",gbmp.white_value));
384 //g_FuncTable.m_pfnProfileSaveString (file, "Formula", "Formula", ExcelFunc );
385 }
386
387 void UpdatePreview (bool DataChange)
388 {
389   if (g_pWndPreview && GTK_WIDGET_VISIBLE (g_pWndPreview))
390   {
391     if (DataChange)
392       GenerateXYZ ();
393
394     gtk_widget_draw (g_pPreviewWidget, NULL);
395   }
396 }
397
398 void SaveSetup (GtkWidget *parent)
399 {
400   const char *name = g_FuncTable.m_pfnFileDialog (parent, false, "Save GenSurf Settings",
401                                              g_FuncTable.m_pfnProfileGetDirectory (), "gtkgensurf");
402
403   if (name != NULL)
404   {
405     char key[32], text[32];
406     int i, j;
407
408     WriteIniFile (name);
409     g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"MapFile",gszMapFile);
410     sprintf(text,"0x%04x",FileAppend);
411     g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Append",text);
412     sprintf(text,"0x%04x",Decimate);
413     g_FuncTable.m_pfnProfileSaveString (name, OPTS_SECTION,"Decimate",text);
414     for(i=0; i<=NH; i++)
415     {
416       for(j=0; j<=NV; j++)
417       {
418         if(xyz[i][j].fixed)
419         {
420           sprintf(key,"I%dJ%d",i,j);
421           sprintf(text,"%g %g %g", xyz[i][j].fixed_value, xyz[i][j].range, xyz[i][j].rate);
422           g_FuncTable.m_pfnProfileSaveString (name, "FixedPoints",key,text);
423         }
424       }
425     }
426   }
427 }
428
429 void OpenSetup (GtkWidget *parent, int UseDefaults)
430 {
431   const char *name;
432   char key[32], *text;
433   float value,range,rate;
434   int i, j;
435
436   if (UseDefaults)
437     name = g_strdup ("plugins/defaults.srf"); // dummy string
438   else
439     name = g_FuncTable.m_pfnFileDialog (parent, true, "Open GenSurf Settings",
440                                         g_FuncTable.m_pfnProfileGetDirectory (), "gtkgensurf");
441
442   if(name != NULL)
443   {
444     ReadIniFile (name);
445     Decimate   = g_FuncTable.m_pfnProfileLoadInt (name, OPTS_SECTION,"Decimate",0);
446     Decimate   = max(0,min(Decimate,100));
447
448     for (i=0; i<=NH; i++)
449     {
450       for (j=0; j<=NV; j++)
451       {
452         sprintf(key,"I%dJ%d",i,j);
453         text = g_FuncTable.m_pfnProfileLoadString (name, "FixedPoints", key, "");
454         if (strlen (text))
455         {
456           xyz[i][j].fixed = 1;
457           xyz[i][j].rate        = 0.;
458           sscanf(text,"%g %g %g",&value,&range,&rate);
459           xyz[i][j].fixed_value = value;
460           xyz[i][j].range       = range;
461           xyz[i][j].rate        = rate;
462         }
463         else
464           xyz[i][j].fixed = 0;
465       }
466     }
467   }
468 }