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" };
103 strcpy( gszVersion, "1.05" );
104 strcpy( gszCaption, "GtkGenSurf" );
105 if ( strlen( gszVersion ) ) {
106 strcat( gszCaption, " v" );
107 strcat( gszCaption, gszVersion );
110 strcpy( gszIni, g_FuncTable.m_pfnProfileGetDirectory() );
111 strcat( gszIni, "gensurf.ini" );
113 /*if (g_FuncTable.m_pfnReadProjectKey != NULL)
117 basepath = g_FuncTable.m_pfnReadProjectKey("basepath");
120 g_strdown (basepath);
121 if (strstr(basepath,"baseq3"))
123 else if (strstr (basepath,"baseq2"))
125 else // Gotta have a game, might as well be Quake3
135 if ( g_pWnd == NULL ) {
136 g_pWnd = create_main_dialog();
139 ReadIniFile( gszIni );
144 // Reads default values
146 #define OPTS_SECTION "Options"
148 void ReadIniFile( const char *file ){
153 Text = g_FuncTable.m_pfnProfileLoadString( file, OPTS_SECTION, "Amplitude", "" );
154 if ( strlen( Text ) ) {
155 Amplitude = atof( Text );
161 Text = g_FuncTable.m_pfnProfileLoadString( file, OPTS_SECTION, "Roughness", "" );
162 if ( strlen( Text ) ) {
163 Roughness = atof( Text );
169 Text = g_FuncTable.m_pfnProfileLoadString( file, OPTS_SECTION, "WaveLength", "" );
170 if ( strlen( Text ) ) {
171 WaveLength = atof( Text );
177 Text = g_FuncTable.m_pfnProfileLoadString( file, OPTS_SECTION, "Extents", "" );
178 if ( strlen( Text ) ) {
179 sscanf( Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4 );
193 Text = g_FuncTable.m_pfnProfileLoadString( file, OPTS_SECTION, "CornerValues", "" );
194 if ( strlen( Text ) ) {
195 sscanf( Text,"%f,%f,%f,%f",&x1,&x2,&x3,&x4 );
209 Text = g_FuncTable.m_pfnProfileLoadString( file, OPTS_SECTION, "TextureOffset", "" );
210 if ( strlen( Text ) ) {
211 sscanf( Text,"%f,%f",&x1,&x2 );
221 Text = g_FuncTable.m_pfnProfileLoadString( file, OPTS_SECTION,"TextureScale","" );
222 if ( strlen( Text ) ) {
223 sscanf( Text,"%f,%f",&x1,&x2 );
226 if ( TexScale[0] == 0. ) {
229 if ( TexScale[1] == 0. ) {
239 NH = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"NH",8 );
240 NH = max( 1,min( NH,MAX_ROWS ) );
241 NV = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"NV",8 );
242 NV = max( 1,min( NV,MAX_ROWS ) );
244 // Decimate = GetPrivateProfileInt(OPTS_SECTION,"Decimate",0,file);
245 // Decimate = max(0,min(Decimate,100));
247 AddHints = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"AddHints",0 );
248 ArghRad2 = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"ArghRad2",0 );
249 AutoOverwrite = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"AutoOverwrite",0 );
250 FixBorders = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"FixBorders",1 );
251 HideBackFaces = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"HideBackFaces",0 );
252 Plane = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"Plane",0 );
253 Preview = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"Preview", 0 );
254 Antialiasing = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"Antialiasing",0 ); // ^Fishman - Antializing for the preview window.
255 RandomSeed = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"RandomSeed",1 );
256 Skybox = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"Skybox",0 );
257 UseDetail = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"UseDetail",0 );
258 AddTerrainKey = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"AddTerrainKey",0 ); // ^Fishman - Add terrain key to func_group.
259 UseLadder = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"UseLadder",0 );
260 WaveType = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"WaveType",0 );
261 vid_x = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"vid_x", 0 );
262 vid_y = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"vid_y", 0 );
263 view_x = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"view_x",0 );
264 view_y = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"view_y",0 );
265 view_cx = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"view_cx",0 );
266 view_cy = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"view_cy",0 );
268 UsePatches = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"UsePatches",0 );
270 SlantAngle = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"SlantAngle",60 );
271 GimpHints = g_FuncTable.m_pfnProfileLoadInt( file, OPTS_SECTION,"GimpHints",0 );
273 for ( i = 0; i < NUMGAMES; i++ )
275 // strcpy (gszOutputDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"OutputDir",""));
276 strcpy( Texture[i][0], g_FuncTable.m_pfnProfileLoadString( file, GameName[i], "Texture", "" ) );
277 strcpy( Texture[i][1], g_FuncTable.m_pfnProfileLoadString( file, GameName[i], "Texture2", "" ) );
278 strcpy( Texture[i][2], g_FuncTable.m_pfnProfileLoadString( file, GameName[i], "Texture3", "" ) );
279 // strcpy (gszTextureDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"TextureDir",""));
280 // UsePak[i] = GetPrivateProfileInt(GameName[i],"UsePak",0);
281 // strcpy (pakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"PakFile",""));
282 // strcpy (lastpakfile[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"LastPakFile",""));
283 // strcpy (GameDir[i], g_FuncTable.m_pfnProfileLoadString (file, GameName[i],"GameDir","\0"));
286 if(!strlen(gszTextureDir[QUAKE2]))
287 strcpy(gszTextureDir[QUAKE2],"c:\\quake2\\baseq2\\textures\\");
288 if(!strlen(gszTextureDir[KINGPIN]))
289 strcpy(gszTextureDir[KINGPIN],"c:\\kingpin\\main\\textures\\");
291 if ( !strlen( Texture[QUAKE2][0] ) ) {
292 strcpy( Texture[QUAKE2][0], "textures/e1u1/grass1_4" );
294 if ( !strlen( Texture[HALFLIFE][0] ) ) {
295 strcpy( Texture[HALFLIFE][0], "textures/OUT_GRND1" );
297 if ( !strlen( Texture[SIN][0] ) ) {
298 strcpy( Texture[SIN][0], "textures/generic/floor_organic/fl_grass" );
300 if ( !strlen( Texture[HERETIC2][0] ) ) {
301 strcpy( Texture[HERETIC2][0], "textures/canyon/canyon05" );
303 if ( !strlen( Texture[KINGPIN][0] ) ) {
304 strcpy( Texture[KINGPIN][0], "textures/bricks/s_sr_m3" );
306 if ( !strlen( Texture[GENESIS3D][0] ) ) {
307 strcpy( Texture[GENESIS3D][0],"textures/rock13" );
309 if ( !strlen( Texture[QUAKE3][0] ) ) {
310 strcpy( Texture[QUAKE3][0], "textures/organics/grass3" );
312 if ( !strlen( Texture[QUAKE3][1] ) ) {
313 strcpy( Texture[QUAKE3][1], "textures/common/caulk" );
315 strcpy( gbmp.name, g_FuncTable.m_pfnProfileLoadString( file, "Bitmap","Filename","" ) );
319 if ( strlen( gbmp.name ) ) {
323 strcpy( gbmp.defpath, g_FuncTable.m_pfnProfileLoadString( file, "Bitmap","DefaultPath","" ) );
325 Text = g_FuncTable.m_pfnProfileLoadString( file, "Bitmap","BlackValue","" );
326 if ( strlen( Text ) ) {
327 gbmp.black_value = atof( Text );
330 gbmp.black_value = 0;
333 Text = g_FuncTable.m_pfnProfileLoadString( file, "Bitmap","WhiteValue","" );
334 if ( strlen( Text ) ) {
335 gbmp.white_value = atof( Text );
338 gbmp.white_value = 256.;
346 does a varargs printf into a temp buffer, so I don't need to have
347 varargs versions of all text functions.
348 FIXME: make this buffer size safe someday
351 char *va( const char *format, ... ){
353 static char string[1024];
355 va_start( argptr, format );
356 vsprintf( string, format,argptr );
363 // Writes current values to INI file
364 void WriteIniFile( const char *file ){
367 g_FuncTable.m_pfnProfileSaveString( file, OPTS_SECTION, "Amplitude", va( "%g",Amplitude ) );
368 g_FuncTable.m_pfnProfileSaveString( file, OPTS_SECTION, "Roughness", va( "%g",Roughness ) );
369 g_FuncTable.m_pfnProfileSaveString( file, OPTS_SECTION, "WaveLength", va( "%g",WaveLength ) );
370 g_FuncTable.m_pfnProfileSaveString( file, OPTS_SECTION, "Extents", va( "%g,%g,%g,%g",Hll,Vll,Hur,Vur ) );
371 g_FuncTable.m_pfnProfileSaveString( file, OPTS_SECTION, "CornerValues", va( "%g,%g,%g,%g",Z00,Z01,Z10,Z11 ) );
372 g_FuncTable.m_pfnProfileSaveString( file, OPTS_SECTION, "TextureOffset",va( "%g,%g",TexOffset[0],TexOffset[1] ) );
373 g_FuncTable.m_pfnProfileSaveString( file, OPTS_SECTION, "TextureScale", va( "%g,%g",TexScale[0],TexScale[1] ) );
374 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "NH", NH );
375 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "NV", NV );
376 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "AddHints", AddHints );
377 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "ArghRad2", ArghRad2 );
378 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "AutoOverwrite", AutoOverwrite );
379 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "FixBorders", FixBorders );
380 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "Plane", Plane );
381 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "Preview", Preview );
382 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "Antialiasing", Antialiasing ); // ^Fishman - Antializing for the preview window.
383 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "RandomSeed", RandomSeed );
384 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "Skybox", Skybox );
385 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "UseDetail", UseDetail );
386 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "AddTerrainKey", AddTerrainKey ); // ^Fishman - Add terrain key to func_group.
387 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "UseLadder", UseLadder );
388 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "WaveType", WaveType );
389 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "vid_x", vid_x );
390 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "vid_y", vid_y );
391 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "view_x", view_x );
392 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "view_y", view_y );
393 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "view_cx", view_cx );
394 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "view_cy", view_cy );
395 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "UsePatches", UsePatches );
396 g_FuncTable.m_pfnProfileSaveInt( file, OPTS_SECTION, "SlantAngle", SlantAngle );
397 for ( i = 0; i < NUMGAMES; i++ )
399 g_FuncTable.m_pfnProfileSaveString( file, GameName[i], "Texture", Texture[i][0] );
400 g_FuncTable.m_pfnProfileSaveString( file, GameName[i], "Texture2", Texture[i][1] );
401 g_FuncTable.m_pfnProfileSaveString( file, GameName[i], "Texture3", Texture[i][2] );
404 g_FuncTable.m_pfnProfileSaveString( file, "Bitmap", "Filename", gbmp.name );
405 g_FuncTable.m_pfnProfileSaveString( file, "Bitmap", "DefaultPath", gbmp.defpath );
406 g_FuncTable.m_pfnProfileSaveString( file, "Bitmap", "BlackValue", va( "%g",gbmp.black_value ) );
407 g_FuncTable.m_pfnProfileSaveString( file, "Bitmap", "WhiteValue", va( "%g",gbmp.white_value ) );
408 //g_FuncTable.m_pfnProfileSaveString (file, "Formula", "Formula", ExcelFunc );
411 void UpdatePreview( bool DataChange ){
412 if ( g_pWndPreview && gtk_widget_get_visible( g_pWndPreview ) ) {
417 gtk_widget_draw( g_pPreviewWidget, NULL );
421 void SaveSetup( GtkWidget *parent ){
422 const char *name = g_FuncTable.m_pfnFileDialog( parent, false, "Save GenSurf Settings",
423 g_FuncTable.m_pfnProfileGetDirectory() );
425 if ( name != NULL ) {
426 char key[32], text[32];
429 WriteIniFile( name );
430 g_FuncTable.m_pfnProfileSaveString( name, OPTS_SECTION,"MapFile",gszMapFile );
431 sprintf( text,"0x%04x",FileAppend );
432 g_FuncTable.m_pfnProfileSaveString( name, OPTS_SECTION,"Append",text );
433 sprintf( text,"0x%04x",Decimate );
434 g_FuncTable.m_pfnProfileSaveString( name, OPTS_SECTION,"Decimate",text );
435 for ( i = 0; i <= NH; i++ )
437 for ( j = 0; j <= NV; j++ )
439 if ( xyz[i][j].fixed ) {
440 sprintf( key,"I%dJ%d",i,j );
441 sprintf( text,"%g %g %g", xyz[i][j].fixed_value, xyz[i][j].range, xyz[i][j].rate );
442 g_FuncTable.m_pfnProfileSaveString( name, "FixedPoints",key,text );
449 void OpenSetup( GtkWidget *parent, int UseDefaults ){
452 float value,range,rate;
456 name = g_strdup( "plugins/defaults.srf" ); // dummy string
459 name = g_FuncTable.m_pfnFileDialog( parent, true, "Open GenSurf Settings",
460 g_FuncTable.m_pfnProfileGetDirectory() );
463 if ( name != NULL ) {
465 Decimate = g_FuncTable.m_pfnProfileLoadInt( name, OPTS_SECTION,"Decimate",0 );
466 Decimate = max( 0,min( Decimate,100 ) );
468 for ( i = 0; i <= NH; i++ )
470 for ( j = 0; j <= NV; j++ )
472 sprintf( key,"I%dJ%d",i,j );
473 text = g_FuncTable.m_pfnProfileLoadString( name, "FixedPoints", key, "" );
474 if ( strlen( text ) ) {
477 sscanf( text,"%g %g %g",&value,&range,&rate );
478 xyz[i][j].fixed_value = value;
479 xyz[i][j].range = range;
480 xyz[i][j].rate = rate;