]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/gendlgs.cpp
5766aa90a98d0743069b47b156cf52f48301675f
[xonotic/netradiant.git] / contrib / gtkgensurf / gendlgs.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 <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25 #include "gensurf.h"
26 #include <glib/gi18n.h>
27
28 #define GENERAL_TAB   0
29 #define EXTENTS_TAB   1
30 #define BITMAP_TAB    2
31 #define FIXPOINTS_TAB 3
32 #define TEXTURE_TAB   4
33 //#define BUFF_SIZE     32768
34
35 #define ENABLE_WIDGET( name,enable ) \
36         gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), ( name ) ) ), ( enable ) )
37 #define CHECK_WIDGET( name,check ) \
38         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), name ) ), check )
39
40 static GtkWidget *game_radios[NUMGAMES];
41 static GtkWidget *wave_radios[5];
42 static GtkWidget *plane_radios[6];
43 static guint current_tab;
44 static int OldPreview;
45 static int WasDetail;
46 static GtkTooltips *tooltips;
47 static int FirstPassComplete = 0;
48
49 void About( GtkWidget *parent ){
50 /*
51    char *icon_xpm[] = {
52    "32 32 4 1",
53    "    c None",
54    ".   c #000000",
55    "+   c #FFFFFF",
56    "@   c #838183",
57    "................................",
58    "................................",
59    "................................",
60    "................................",
61    "................................",
62    "................................",
63    "................................",
64    "...............++...............",
65    ".............++++++.............",
66    "............++@+++@+............",
67    "..........+++..++..+++..........",
68    "........++.+.++..++.+.@+........",
69    ".......+..+..+.++.+..+..++......",
70    ".....++..++.+..++..+.++..++.....",
71    "...++..++...+.+..+.++..++..++...",
72    "..++.+.++....++..++....++.+..+..",
73    ".+.+..+..++....++....++..++.+.+.",
74    "..+++....+.++++++++++.+....+++..",
75    "....++.@@+++++.++.++++@++.++....",
76    "......+++++++......++@+++++.....",
77    ".......+++.+.++..++.+..++.......",
78    ".........++..+.++.+..++.........",
79    "...........++..++..++...........",
80    ".............++..+.+............",
81    "..............+..+@.............",
82    "...............@@...............",
83    "................................",
84    "................................",
85    "................................",
86    "................................",
87    "................................",
88    "................................"
89    };
90  */
91         // leo: I'm too lazy to create a nice about box
92         // ^Fishman - I am lazy too :P.
93         g_FuncTable.m_pfnMessageBox( parent, "GtkGenSurf 1.05\n\n"
94                                                                                  "Original version\n"
95                                                                                  "David Hyde (rascal@vicksburg.com)\n\n"
96                                                                                  "Porting\n"
97                                                                                  "Leonardo Zide (leo@lokigames.com)\n\n"
98                                                                                  "Enhancements\n"
99                                                                                  "Pablo Zurita (pablo@qeradiant.com)\n"
100                                                                                  "Hydra (hydra@hydras-world.com)",
101                                                                  "About GtkGenSurf", MB_OK, NULL );
102 }
103
104 // =============================================================================
105 // main dialog
106
107 static void SetupControls(){
108         switch ( current_tab )
109         {
110         case GENERAL_TAB:
111                 break;
112
113         case EXTENTS_TAB:
114                 if ( Game != QUAKE3 ) {
115                         gtk_widget_hide( GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "use_patches" ) ) );
116                         ENABLE_WIDGET( "use_patches", FALSE );
117                 }
118                 else
119                 {
120                         gtk_widget_show( GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "use_patches" ) ) );
121                         ENABLE_WIDGET( "use_patches", TRUE );
122                 }
123
124                 if ( Game == QUAKE3 && UsePatches != 0 ) {
125                         ENABLE_WIDGET( "decimate", FALSE );
126                 }
127                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "snap_text" ) ), "Snap to grid:" ); // ^Fishman - Snap to grid.
128                 break;
129
130         case BITMAP_TAB:
131                 if ( WaveType != WAVE_BITMAP ) {
132                         ENABLE_WIDGET( "bmp_file", FALSE );
133                         ENABLE_WIDGET( "bmp_file_browse", FALSE );
134                         ENABLE_WIDGET( "bmp_black", FALSE );
135                         ENABLE_WIDGET( "bmp_white", FALSE );
136                         ENABLE_WIDGET( "bmp_text1", FALSE );
137                         ENABLE_WIDGET( "bmp_text2", FALSE );
138                         ENABLE_WIDGET( "bmp_text3", FALSE );
139                         ENABLE_WIDGET( "bmp_reload", FALSE );
140                         gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_note" ) ),
141                                                                 "These options are disabled unless \"From Bitmap\"\n"
142                                                                 "is selected as the Waveform on the General tab." );
143                 }
144                 else
145                 {
146                         ENABLE_WIDGET( "bmp_file", TRUE );
147                         ENABLE_WIDGET( "bmp_file_browse", TRUE );
148                         ENABLE_WIDGET( "bmp_black", TRUE );
149                         ENABLE_WIDGET( "bmp_white", TRUE );
150                         ENABLE_WIDGET( "bmp_text1", TRUE );
151                         ENABLE_WIDGET( "bmp_text2", TRUE );
152                         ENABLE_WIDGET( "bmp_text3", TRUE );
153                         ENABLE_WIDGET( "bmp_reload", strlen( gbmp.name ) != 0 );
154                         gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_note" ) ),
155                                                                 "GenSurf works only with 8-bit bitmaps. Color indices are\n"
156                                                                 "mapped to values for each vertex. Generally, gray scale\n"
157                                                                 "images are stored with black as color 0, white as color 255." );
158                 }
159                 break;
160
161         case FIXPOINTS_TAB:
162                 ENABLE_WIDGET( "fix_value", ( NumVerticesSelected != 0 ) );
163                 ENABLE_WIDGET( "fix_value_text", ( NumVerticesSelected != 0 ) );
164                 ENABLE_WIDGET( "fix_free", ( NumVerticesSelected != 0 ) );
165                 ENABLE_WIDGET( "fix_range", ( ( NumVerticesSelected != 0 ) && ( WaveType != WAVE_ROUGH_ONLY ) ) );
166                 ENABLE_WIDGET( "fix_range_text", ( ( NumVerticesSelected != 0 ) && ( WaveType != WAVE_ROUGH_ONLY ) ) );
167                 ENABLE_WIDGET( "fix_rate", ( ( NumVerticesSelected != 0 ) && ( WaveType != WAVE_ROUGH_ONLY ) ) );
168                 ENABLE_WIDGET( "fix_rate_text", ( ( NumVerticesSelected != 0 ) && ( WaveType != WAVE_ROUGH_ONLY ) ) );
169                 break;
170
171         case TEXTURE_TAB:
172                 ENABLE_WIDGET( "texture2", ( UsePatches == 0 ) );
173                 ENABLE_WIDGET( "texture3", ( UsePatches == 0 ) );
174                 ENABLE_WIDGET( "tex_slant", ( UsePatches == 0 ) );
175                 ENABLE_WIDGET( "detail", ( UsePatches == 0 ) );
176                 if ( Game != QUAKE3 ) {
177                         ENABLE_WIDGET( "terrain_ent", FALSE ); // ^Fishman - Adds terrain key to func_group.
178                         ENABLE_WIDGET( "hint", ( UsePatches == 0 ) );
179                 }
180                 break;
181         }
182
183         switch ( WaveType )
184         {
185         case WAVE_HCYLINDER:
186         case WAVE_VCYLINDER:
187                 ENABLE_WIDGET( "amplitude", TRUE );
188                 ENABLE_WIDGET( "wavelength", TRUE );
189                 ENABLE_WIDGET( "z00", TRUE );
190                 ENABLE_WIDGET( "z01", TRUE );
191                 ENABLE_WIDGET( "z10", TRUE );
192                 ENABLE_WIDGET( "z11", TRUE );
193                 ENABLE_WIDGET( "linearborder", TRUE );
194                 ENABLE_WIDGET( "go", TRUE );
195                 break;
196         case WAVE_BITMAP:
197                 ENABLE_WIDGET( "amplitude", FALSE );
198                 ENABLE_WIDGET( "wavelength", FALSE );
199                 ENABLE_WIDGET( "z00", FALSE );
200                 ENABLE_WIDGET( "z01", FALSE );
201                 ENABLE_WIDGET( "z10", FALSE );
202                 ENABLE_WIDGET( "z11", FALSE );
203                 ENABLE_WIDGET( "linearborder", FALSE );
204                 ENABLE_WIDGET( "go", ( gbmp.colors != NULL ? TRUE : FALSE ) );
205                 break;
206         case WAVE_ROUGH_ONLY:
207                 ENABLE_WIDGET( "amplitude", FALSE );
208                 ENABLE_WIDGET( "wavelength", FALSE );
209                 ENABLE_WIDGET( "z00", TRUE );
210                 ENABLE_WIDGET( "z01", TRUE );
211                 ENABLE_WIDGET( "z10", TRUE );
212                 ENABLE_WIDGET( "z11", TRUE );
213                 ENABLE_WIDGET( "linearborder", TRUE );
214                 ENABLE_WIDGET( "go", TRUE );
215                 break;
216         default:
217                 ENABLE_WIDGET( "amplitude", TRUE );
218                 ENABLE_WIDGET( "wavelength", TRUE );
219                 ENABLE_WIDGET( "z00", TRUE );
220                 ENABLE_WIDGET( "z01", TRUE );
221                 ENABLE_WIDGET( "z10", TRUE );
222                 ENABLE_WIDGET( "z11", TRUE );
223                 ENABLE_WIDGET( "linearborder", TRUE );
224                 ENABLE_WIDGET( "go", TRUE );
225         }
226
227         switch ( Plane )
228         {
229         case PLANE_XZ0:
230         case PLANE_XZ1:
231                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "hmin_text" ) ), "X:" );
232                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "hmax_text" ) ), "X:" );
233                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "vmin_text" ) ), "Z:" );
234                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "vmax_text" ) ), "Z:" );
235                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "nh_text" ) ), "X:" );
236                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "nv_text" ) ), "Z:" );
237                 break;
238         case PLANE_YZ0:
239         case PLANE_YZ1:
240                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "hmin_text" ) ), "Y:" );
241                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "hmax_text" ) ), "Y:" );
242                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "vmin_text" ) ), "Z:" );
243                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "vmax_text" ) ), "Z:" );
244                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "nh_text" ) ), "Y:" );
245                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "nv_text" ) ), "Z:" );
246                 break;
247         default:
248                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "hmin_text" ) ), "X:" );
249                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "hmax_text" ) ), "X:" );
250                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "vmin_text" ) ), "Y:" );
251                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "vmax_text" ) ), "Y:" );
252                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "nh_text" ) ), "X:" );
253                 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "nv_text" ) ), "Y:" );
254                 break;
255         }
256 }
257
258 // SetDlgValues fills in text boxes and initializes other input controls
259 static void SetDlgValues( int tab ){
260         char Text[256];
261         char RForm[16] = "%.5g";
262
263         switch ( tab )
264         {
265         case GENERAL_TAB:
266                 // mattn: Deactivated because one wasn't able to switch the gametype or orientation
267 #if 0
268                 // Hell if I know why, but in the release build the 2nd pass thru the
269                 // set_sensitive loop for game_radios crashes. No need to do this more
270                 // than once anyhow.
271                 if ( !FirstPassComplete ) {
272                         int i;
273                         for ( i = 0; i < NUMGAMES; i++ )
274                                 gtk_widget_set_sensitive( game_radios[i], ( i == Game ? TRUE : FALSE ) );
275                         for ( i = 0; i < 6; i++ )
276                                 gtk_widget_set_sensitive( plane_radios[i], ( i == Plane ? TRUE : FALSE ) );
277                 }
278 #endif
279                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( game_radios[Game] ), TRUE );
280                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( plane_radios[Plane] ), TRUE );
281                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( wave_radios[WaveType] ), TRUE );
282                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "random" ) ),
283                                                                    RandomSeed );
284                 sprintf( Text, RForm, WaveLength );
285                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "wavelength" ) ), Text );
286                 sprintf( Text, RForm, Amplitude );
287                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "amplitude" ) ), Text );
288                 sprintf( Text, RForm, Roughness );
289                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "roughness" ) ), Text );
290                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data
291                                                                                                                          ( G_OBJECT( g_pWnd ), "main_antialiasing" ) ), Antialiasing );
292                 break;
293
294         case EXTENTS_TAB:
295                 sprintf( Text,RForm,Hll );
296                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "hmin" ) ), Text );
297                 sprintf( Text,RForm,Vll );
298                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "vmin" ) ), Text );
299                 sprintf( Text,RForm,Hur );
300                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "hmax" ) ), Text );
301                 sprintf( Text,RForm,Vur );
302                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "vmax" ) ), Text );
303                 sprintf( Text,RForm,Z00 );
304                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "z00" ) ), Text );
305                 sprintf( Text,RForm,Z01 );
306                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "z01" ) ), Text );
307                 sprintf( Text,RForm,Z10 );
308                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "z10" ) ), Text );
309                 sprintf( Text,RForm,Z11 );
310                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "z11" ) ), Text );
311                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "nh" ) ), NH );
312                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "nv" ) ), NV );
313                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "sp" ) ), SP ); // ^Fishman - Snap to grid.
314
315                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data
316                                                                                                                          ( G_OBJECT( g_pWnd ), "linearborder" ) ), FixBorders );
317                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data
318                                                                                                                          ( G_OBJECT( g_pWnd ), "use_patches" ) ), UsePatches );
319                 gtk_adjustment_set_value( GTK_ADJUSTMENT( g_object_get_data( G_OBJECT( g_pWnd ), "decimate_adj" ) ),
320                                                                   Decimate );
321
322                 if ( Game == QUAKE3 && UsePatches ) {
323                         gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "decimate" ) ), FALSE );
324
325                         if ( NH % 2 ) {
326                                 NH++;
327                                 if ( NH > MAX_ROWS ) {
328                                         NH -= 2;
329                                 }
330                                 SetDlgValues( current_tab );
331                         }
332
333                         if ( NV % 2 ) {
334                                 NV++;
335                                 if ( NV > MAX_ROWS ) {
336                                         NV -= 2;
337                                 }
338                                 SetDlgValues( current_tab );
339                         }
340                         if ( NH % 2 ) {
341                                 NH++;
342                         }
343                         if ( NH < 2 ) {
344                                 NH = 2;
345                         }
346                         if ( NH > MAX_ROWS ) {
347                                 NH = MAX_ROWS;
348                         }
349                         if ( NV % 2 ) {
350                                 NV++;
351                         }
352                         if ( NV < 2 ) {
353                                 NV = 2;
354                         }
355                         if ( NV > MAX_ROWS ) {
356                                 NV = MAX_ROWS;
357                         }
358
359                         gpointer spin = g_object_get_data( G_OBJECT( g_pWnd ), "nh" );
360                         GtkAdjustment *adj = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( spin ) );
361                         adj->lower = 2;
362                         gtk_adjustment_changed( adj );
363                         spin = g_object_get_data( G_OBJECT( g_pWnd ), "nv" );
364                         adj = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( spin ) );
365                         adj->lower = 2;
366                         gtk_adjustment_changed( adj );
367                 }
368                 else
369                 {
370                         gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "decimate" ) ), TRUE );
371
372                         gpointer spin = g_object_get_data( G_OBJECT( g_pWnd ), "nh" );
373                         GtkAdjustment *adj = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( spin ) );
374                         adj->lower = 1;
375                         gtk_adjustment_changed( adj );
376                         spin = g_object_get_data( G_OBJECT( g_pWnd ), "nv" );
377                         adj = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( spin ) );
378                         adj->lower = 1;
379                         gtk_adjustment_changed( adj );
380                 }
381
382                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "nh" ) ), NH );
383                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "nv" ) ), NV );
384
385                 break;
386
387         case BITMAP_TAB:
388                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_file" ) ), gbmp.name );
389                 sprintf( Text,"%g",gbmp.black_value );
390                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_black" ) ), Text );
391                 sprintf( Text,"%g",gbmp.white_value );
392                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_white" ) ), Text );
393                 break;
394
395         case FIXPOINTS_TAB:
396                 break;
397
398         case TEXTURE_TAB:
399                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "texture1" ) ), Texture[Game][0] );
400                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "texture2" ) ), Texture[Game][1] );
401                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "texture3" ) ), Texture[Game][2] );
402                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "tex_slant" ) ),
403                                                                    SlantAngle );
404                 sprintf( Text,RForm,TexOffset[0] );
405                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "texoffsetx" ) ), Text );
406                 sprintf( Text,RForm,TexOffset[1] );
407                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "texoffsety" ) ), Text );
408                 sprintf( Text,RForm,TexScale[0] );
409                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "texscalex" ) ), Text );
410                 sprintf( Text,RForm,TexScale[1] );
411                 gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "texscaley" ) ), Text );
412                 CHECK_WIDGET( "detail", UseDetail );
413
414                 if ( Game == QUAKE3 ) {
415                         ENABLE_WIDGET( "hint", FALSE );
416                         AddHints = 0;
417                 }
418                 else{
419                         ENABLE_WIDGET( "hint", TRUE );
420                 }
421                 CHECK_WIDGET( "hint", AddHints );
422
423                 /*
424                    if (Game==SIN)
425                    {
426                    // ArghRad doesn't currently support SiN
427                    EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
428                    EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
429                    ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
430                    ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
431                    ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
432                    SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use sin file");
433                    SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Sin:");
434                    }
435                  */
436
437                 if ( Game == QUAKE3 ) {
438                         /*
439                            // ArghRad sun is inapplicable (so far)
440                            EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
441                            EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
442                            ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
443                            ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
444                            ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
445                            // No ladders in Q3
446                            EnableWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         0);
447                            ShowWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         SW_HIDE);
448                            SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use pk3 file");
449                            SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"PK3:");
450                          */
451                 }
452
453 /*trix  if(Game==HERETIC2)
454         {
455             // ArghRad doesn't currently support Heretic2
456             EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
457             EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
458             ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
459             ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
460             ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
461
462             SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use pak file");
463             SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Pak:");
464         } */
465                 /*
466                     if(Game==HALFLIFE)
467                     {
468                         // A bunch of controls aren't applicable to HL
469                         EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE_BROWSE), 0);
470                         EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE2_BROWSE),0);
471                         EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE3_BROWSE),0);
472                         EnableWindow(GetDlgItem(hwndDisplay,DLG_DETAIL),         0);
473                         EnableWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         0);
474                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
475                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
476                         ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE_BROWSE), SW_HIDE);
477                         ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE2_BROWSE),SW_HIDE);
478                         ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE3_BROWSE),SW_HIDE);
479                         ShowWindow(GetDlgItem(hwndDisplay,DLG_DETAIL),         SW_HIDE);
480                         ShowWindow(GetDlgItem(hwndDisplay,DLG_LADDER),         SW_HIDE);
481                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
482                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
483                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
484
485                         SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use wad file");
486                         SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Wad:");
487                         SetDlgItemText(hwndDisplay,DLG_HINT,"Hint brushes");
488                     }
489
490                     if(Game==GENESIS3D)
491                     {
492                         // No Q2-type compilers support Genesis3D (including ArghRad)
493                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       0);
494                         EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  0);
495                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT),  SW_HIDE);
496                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2),       SW_HIDE);
497                         ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN),  SW_HIDE);
498
499                         SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use sin file");
500                         SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Sin:");
501                     }
502                  */
503                 break;
504         }
505         SetupControls();
506 }
507
508 static void ReadDlgValues( int tab ){
509         //  char Text[256];
510         //  int i;
511
512         switch ( tab )
513         {
514         case GENERAL_TAB:
515                 gpointer spin;
516                 Roughness  = atof( gtk_entry_get_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "roughness" ) ) ) );
517                 WaveLength = atof( gtk_entry_get_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "wavelength" ) ) ) );
518                 Amplitude  = atof( gtk_entry_get_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "amplitude" ) ) ) );
519                 spin = g_object_get_data( G_OBJECT( g_pWnd ), "random" );
520                 RandomSeed = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
521                 break;
522
523         case EXTENTS_TAB:
524                 SP = atoi( gtk_entry_get_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "sp" ) ) ) );
525                 NH = atoi( gtk_entry_get_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "nh" ) ) ) );
526                 NV = atoi( gtk_entry_get_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "nv" ) ) ) );
527
528                 if ( Game == QUAKE3 && UsePatches != 0 ) {
529                         if ( NH % 2 ) {
530                                 NH++;
531                         }
532                         if ( NH < 2 ) {
533                                 NH = 2;
534                         }
535                         if ( NH > MAX_ROWS ) {
536                                 NH = MAX_ROWS;
537                         }
538                         if ( NV % 2 ) {
539                                 NV++;
540                         }
541                         if ( NV < 2 ) {
542                                 NV = 2;
543                         }
544                         if ( NV > MAX_ROWS ) {
545                                 NV = MAX_ROWS;
546                         }
547                 }
548                 break;
549
550 #if 0
551         case BITMAP_TAB:
552
553                 if ( WaveType == WAVE_BITMAP ) {
554                         GetDlgItemText( hwnd,DLG_BMP_FILE,gbmp.name,sizeof( gbmp.name ) );
555                         CheckValidDIB( hwnd );
556                         GetDlgItemText( hwnd,DLG_BMP_BLACK,Text,sizeof( Text ) );
557                         gbmp.black_value = atof( Text );
558                         GetDlgItemText( hwnd,DLG_BMP_WHITE,Text,sizeof( Text ) );
559                         gbmp.white_value = atof( Text );
560                         UpdatePreview( TRUE );
561                 }
562                 break;
563
564         case FIXPOINTS_TAB:
565                 GetDlgItemText( hwnd,DLG_FIX_VALUE,Text,sizeof( Text ) );
566                 temp.fixed_value = atoi( Text );
567                 GetDlgItemText( hwnd,DLG_FIX_RANGE,Text,sizeof( Text ) );
568                 temp.range = atoi( Text );
569                 GetDlgItemText( hwnd,DLG_FIX_RATE, Text,sizeof( Text ) );
570                 temp.rate = atof( Text );
571                 for ( k = 0; k < NumVerticesSelected; k++ )
572                 {
573                         xyz[Vertex[k].i][Vertex[k].j].fixed_value = temp.fixed_value;
574                         xyz[Vertex[k].i][Vertex[k].j].range       = temp.range;
575                         xyz[Vertex[k].i][Vertex[k].j].rate        = temp.rate;
576                 }
577                 if ( !OldPreview ) {
578                         Preview = 0;
579                         CheckDlgButton( ghwnd,DLG_PREVIEW,0 );
580                         SendMessage( ghwnd,WM_COMMAND,DLG_PREVIEW,0 );
581                 }
582                 VertexMode = 0;
583                 UpdatePreview( TRUE );
584                 break;
585
586         case TEXTURE_TAB:
587                 if ( UsePak[Game] ) {
588                         i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETCURSEL, 0, 0 );
589                         if ( i == CB_ERR ) {
590                                 Texture[Game][0][0] = '\0';
591                         }
592                         else{
593                                 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETLBTEXT, i,
594                                                                         (LPARAM)(LPCSTR)Texture[Game][0] );
595                         }
596
597                         i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETCURSEL, 0, 0 );
598                         if ( i == CB_ERR ) {
599                                 Texture[Game][1][0] = '\0';
600                         }
601                         else{
602                                 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETLBTEXT, i,
603                                                                         (LPARAM)(LPCSTR)Texture[Game][1] );
604                         }
605
606                         i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETCURSEL, 0, 0 );
607                         if ( i == CB_ERR ) {
608                                 Texture[Game][2][0] = '\0';
609                         }
610                         else{
611                                 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETLBTEXT, i,
612                                                                         (LPARAM)(LPCSTR)Texture[Game][2] );
613                         }
614                 }
615                 else
616                 {
617                         GetDlgItemText( hwndDisplay,DLG_TEXTURE, Texture[Game][0],sizeof( Texture[Game][0] ) );
618                         GetDlgItemText( hwndDisplay,DLG_TEXTURE2,Texture[Game][1],sizeof( Texture[Game][1] ) );
619                         GetDlgItemText( hwndDisplay,DLG_TEXTURE3,Texture[Game][2],sizeof( Texture[Game][2] ) );
620                 }
621                 GetDlgItemText( hwndDisplay,DLG_TEX_SLANT,Text,sizeof( Text ) );
622                 SlantAngle = atoi( Text );
623                 SlantAngle = max( 0,min( SlantAngle,90 ) );
624                 GetDlgItemText( hwndDisplay,DLG_TEXOFFSETX,Text,sizeof( Text ) );
625                 TexOffset[0] = atof( Text );
626                 GetDlgItemText( hwndDisplay,DLG_TEXOFFSETY,Text,sizeof( Text ) );
627                 TexOffset[1] = atof( Text );
628                 GetDlgItemText( hwndDisplay,DLG_TEXSCALEX,Text,sizeof( Text ) );
629                 TexScale[0] = atof( Text );
630                 if ( TexScale[0] == 0. ) {
631                         TexScale[0] = 1.0;
632                 }
633                 GetDlgItemText( hwndDisplay,DLG_TEXSCALEY,Text,sizeof( Text ) );
634                 TexScale[1] = atof( Text );
635                 if ( TexScale[1] == 0. ) {
636                         TexScale[1] = 1.0;
637                 }
638                 GetDlgItemText( hwndDisplay,DLG_ARGHRAD2,Text,sizeof( Text ) );
639                 ArghRad2 = atoi( Text );
640                 break;
641 #endif
642         }
643 }
644
645 // =============================================================================
646 // main dialog callbacks
647
648 static void switch_page( GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data ){
649         if ( current_tab != page_num ) {
650                 if ( page_num == FIXPOINTS_TAB ) {
651                         OldPreview = Preview;
652                         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ),
653                                                                                                                                                                 "main_preview" ) ), TRUE );
654                         VertexMode = 1;
655                         UpdatePreview( true );
656                         NumVerticesSelected = 0;
657                 }
658
659                 if ( current_tab == FIXPOINTS_TAB ) {
660                         if ( !OldPreview ) {
661                                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ),
662                                                                                                                                                                         "main_preview" ) ), FALSE );
663                         }
664                         VertexMode = 0;
665                         UpdatePreview( true );
666                         NumVerticesSelected = 0;
667                 }
668
669                 if ( page_num == TEXTURE_TAB ) {
670                         WasDetail = UseDetail;
671                         if ( AddHints ) {
672                                 UseDetail = 1;
673                                 ENABLE_WIDGET( "detail", FALSE );
674                         }
675                 }
676
677                 ReadDlgValues( current_tab );
678                 current_tab = page_num;
679                 SetDlgValues( current_tab );
680         }
681 }
682
683 static gint main_close( GtkWidget *widget, gpointer data ){
684         gtk_widget_hide( g_pWnd );
685         gtk_widget_hide( g_pWndPreview );
686
687         return TRUE;
688 }
689
690 static void main_save( GtkWidget *widget, gpointer data ){
691         ReadDlgValues( current_tab );
692         SaveSetup( g_pWnd );
693 }
694
695 static void main_open( GtkWidget *widget, gpointer data ){
696         OpenSetup( g_pWnd, 0 );
697         for ( int i = 0; i < 5; i++ )
698                 SetDlgValues( i );
699         ShowPreview();
700 }
701
702 static void main_defaults( GtkWidget *widget, gpointer data ){
703         OpenSetup( g_pWnd, 1 );
704         for ( int i = 0; i < 5; i++ )
705                 SetDlgValues( i );
706         ShowPreview();
707 }
708
709 static void main_preview( GtkWidget *widget, gpointer data ){
710         Preview = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) );
711         ShowPreview();
712 }
713
714 // ^Fishman - Antializing for the preview window.
715 static void main_antialiasing( GtkWidget *widget, gpointer data ){
716         Antialiasing = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) );
717         UpdatePreview( true );
718 }
719
720 static void main_about( GtkWidget *widget, gpointer data ){
721         About( g_pWnd );
722 }
723
724 static void main_go( GtkWidget *widget, gpointer data ){
725         GtkWidget *notebook = GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "notebook" ) );
726         char Text[256];
727
728         ReadDlgValues( current_tab );
729         if ( NH < 1 || NH > MAX_ROWS ) {
730                 sprintf( Text, "The number of divisions must be > 0 and no greater than %d.", MAX_ROWS );
731                 g_FuncTable.m_pfnMessageBox( g_pWnd, Text, "GenSurf", MB_ICONEXCLAMATION, NULL );
732                 gtk_notebook_set_page( GTK_NOTEBOOK( notebook ), EXTENTS_TAB );
733                 return;
734         }
735
736         if ( NV < 1 || NV > MAX_ROWS ) {
737                 sprintf( Text, "The number of divisions must be > 0 and no greater than %d.", MAX_ROWS );
738                 g_FuncTable.m_pfnMessageBox( g_pWnd, Text, "GenSurf", MB_ICONEXCLAMATION, NULL );
739                 gtk_notebook_set_page( GTK_NOTEBOOK( notebook ), EXTENTS_TAB );
740                 return;
741         }
742
743         if ( Hll >= Hur ) {
744                 g_FuncTable.m_pfnMessageBox( g_pWnd, "The \"lower-left\" values must be less than "
745                                                                                          "the corresponding \"upper-right\" values in "
746                                                                                          "the \"Extent\" box.","GenSurf", MB_OK | MB_ICONEXCLAMATION, NULL );
747                 gtk_notebook_set_page( GTK_NOTEBOOK( notebook ), EXTENTS_TAB );
748                 return;
749         }
750
751         if ( Vll >= Vur ) {
752                 g_FuncTable.m_pfnMessageBox( g_pWnd,"The \"lower-left\" values must be less than "
753                                                                                         "the corresponding \"upper-right\" values in "
754                                                                                         "the \"Extent\" box.","GenSurf", MB_OK | MB_ICONEXCLAMATION, NULL );
755                 gtk_notebook_set_page( GTK_NOTEBOOK( notebook ), EXTENTS_TAB );
756                 return;
757         }
758
759         if ( !strlen( Texture[Game][0] ) ) {
760                 g_FuncTable.m_pfnMessageBox( g_pWnd, "You must supply a texture name.", "GenSurf", MB_ICONEXCLAMATION, NULL );
761                 gtk_notebook_set_page( GTK_NOTEBOOK( notebook ), EXTENTS_TAB );
762                 return;
763         }
764
765 /*  if (Decimate>0 && GimpHints!=0)
766    {
767     MessageBox(hwnd,"You've elected to use a decimated grid and gimp's non-detail hint brushes. "
768                "This combination usually produces bizarre visual errors in the game, "
769                "so GenSurf has turned off the hint brush option.",
770                "GenSurf",MB_ICONEXCLAMATION);
771     GimpHints = 0;
772    } */
773
774         gtk_widget_hide( g_pWnd );
775         if ( g_pWndPreview ) {
776                 gtk_widget_hide( g_pWndPreview );
777         }
778
779         GenerateMap();
780         WriteIniFile( gszIni );
781 }
782
783 // =============================================================================
784 // general tab callbacks
785
786 static void general_game( GtkToggleButton *widget, gpointer data ){
787         if ( gtk_toggle_button_get_active( widget ) ) {
788                 Game = GPOINTER_TO_INT( data );
789                 UpdatePreview( TRUE );
790         }
791 }
792
793 static void general_plane( GtkToggleButton *widget, gpointer data ){
794         if ( gtk_toggle_button_get_active( widget ) ) {
795                 Plane = GPOINTER_TO_INT( data );
796                 SetupControls();
797                 UpdatePreview( TRUE );
798         }
799 }
800
801 static void general_wave( GtkToggleButton *widget, gpointer data ){
802         if ( gtk_toggle_button_get_active( widget ) ) {
803                 WaveType = GPOINTER_TO_INT( data );
804                 SetupControls();
805                 UpdatePreview( TRUE );
806         }
807 }
808
809 static void general_random( GtkAdjustment *adj, gpointer data ){
810         int nPos = (int)adj->value;
811
812         if ( RandomSeed != nPos ) {
813                 RandomSeed = nPos;
814                 UpdatePreview( true );
815         }
816 }
817
818 // =============================================================================
819 // extents tab callbacks
820
821 static void extents_linearborder( GtkToggleButton *check, gpointer data ){
822         FixBorders = gtk_toggle_button_get_active( check );
823         UpdatePreview( true );
824 }
825
826 static void extents_use_patches( GtkToggleButton *check, gpointer data ){
827         if ( Game != QUAKE3 ) {
828                 return;
829         }
830
831         UsePatches = gtk_toggle_button_get_active( check );
832         SetDlgValues( current_tab );
833         SetupControls();
834         UpdatePreview( true );
835 }
836
837 static void extents_nhnv_spin( GtkAdjustment *adj, int *data ){
838         int nPos = (int)adj->value;
839
840         if ( *data != nPos ) {
841                 if ( Game == QUAKE3 && UsePatches && ( nPos % 2 ) ) {
842                         if ( *data < nPos ) {
843                                 *data += 2;
844                         }
845                         else{
846                                 *data -= 2;
847                         }
848                         gtk_adjustment_set_value( adj, *data );
849                 }
850                 else{
851                         *data = nPos;
852                 }
853                 UpdatePreview( true );
854         }
855 }
856
857 static void extents_decimate( GtkAdjustment *adj, gpointer data ){
858         int nPos = (int)adj->value;
859
860         Decimate = nPos;
861         UpdatePreview( true );
862 }
863
864 // Hydra : snap to grid begin
865 /*static void extents_snaptogrid (GtkAdjustment *adj, gpointer data)
866    {
867    int nPos = (int)adj->value;
868
869    SnapToGrid = nPos;
870    UpdatePreview (true);
871    }*/
872
873 // ^Fishman - Modified version of Hydra's snap to grid code.
874 static void extents_snaptogrid_spin( GtkAdjustment *adj, int *data ){
875         int nPos = (int)adj->value;
876         SnapToGrid = nPos;
877         UpdatePreview( true );
878 }
879
880 // =============================================================================
881 // bitmap tab callbacks
882
883 static gint bitmap_file_entryfocusout( GtkWidget* widget, GdkEventFocus* event, gpointer data ){
884         char filename[NAME_MAX];
885
886         strcpy( filename, gtk_entry_get_text( GTK_ENTRY( widget ) ) );
887         if ( strcmp( filename,gbmp.name ) ) {
888                 strcpy( gbmp.name,filename );
889                 if ( strlen( gbmp.name ) ) {
890                         OpenBitmap();
891                 }
892                 ENABLE_WIDGET( "go", ( gbmp.colors != NULL ? TRUE : FALSE ) );
893         }
894         return FALSE;
895 }
896
897 static void bitmap_browse( GtkWidget *widget, gpointer data ){
898         const char *filename;
899         char *ptr;
900
901         filename = g_FuncTable.m_pfnFileDialog( g_pWnd, TRUE, "Bitmap File", gbmp.defpath, "gtkgensurf", NULL );
902
903         if ( filename != NULL ) {
904                 strcpy( gbmp.name, filename );
905
906                 ptr = (char *) strrchr( filename, G_DIR_SEPARATOR );
907                 if ( ptr != NULL ) {
908                         *( ptr + 1 ) = '\0';
909                         strcpy( gbmp.defpath, filename );
910                 }
911
912                 OpenBitmap();
913                 ENABLE_WIDGET( "go", ( gbmp.colors != NULL ? TRUE : FALSE ) );
914         }
915 }
916
917 static void bitmap_reload( GtkWidget *widget, gpointer data ){
918         strcpy( gbmp.name, gtk_entry_get_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_file" ) ) ) );
919         if ( strlen( gbmp.name ) ) {
920                 OpenBitmap();
921                 ENABLE_WIDGET( "go", ( gbmp.colors != NULL ? TRUE : FALSE ) );
922         }
923         else{
924                 ENABLE_WIDGET( "go", FALSE );
925         }
926 }
927
928 // =============================================================================
929 // fix points tab callbacks
930
931 static gint fix_value_entryfocusout( GtkWidget* widget, GdkEventFocus *event, gpointer data ){
932         int i = atoi( gtk_entry_get_text( GTK_ENTRY( widget ) ) ), k;
933         char Text[32];
934
935         if ( i < -65536 || i > 65536 ) {
936                 gdk_beep();
937                 g_FuncTable.m_pfnMessageBox( g_pWnd, "The value must be between -65536 and 65536, inclusive.",
938                                                                          "GenSurf", MB_OK | MB_ICONEXCLAMATION, NULL );
939                 sprintf( Text, "%d", (int)xyz[Vertex[0].i][Vertex[0].j].fixed_value );
940                 gtk_entry_set_text( GTK_ENTRY( widget ), Text );
941                 gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( widget ) ), widget );
942         }
943         else if ( i != xyz[Vertex[0].i][Vertex[0].j].fixed_value ) {
944                 for ( k = 0; k < NumVerticesSelected; k++ )
945                         xyz[Vertex[k].i][Vertex[k].j].fixed_value = i;
946
947                 gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "fix_value" ) ),
948                                                                    (int)xyz[Vertex[0].i][Vertex[0].j].fixed_value );
949                 UpdatePreview( true );
950         }
951         return FALSE;
952 }
953
954 static void fix_value_changed( GtkAdjustment *adj, gpointer data ){
955         int k, i = (int)adj->value;
956
957         if ( xyz[Vertex[0].i][Vertex[0].j].fixed_value != i ) {
958                 for ( k = 0; k < NumVerticesSelected; k++ )
959                         xyz[Vertex[k].i][Vertex[k].j].fixed_value = i;
960                 UpdatePreview( true );
961         }
962 }
963
964 static gint fix_range_entryfocusout( GtkWidget *widget, GdkEventFocus *event, gpointer data ){
965         int i = atoi( gtk_entry_get_text( GTK_ENTRY( widget ) ) ), k;
966
967         if ( i != xyz[Vertex[0].i][Vertex[0].j].range ) {
968                 for ( k = 0; k < NumVerticesSelected; k++ )
969                         xyz[Vertex[k].i][Vertex[k].j].range = i;
970                 UpdatePreview( true );
971         }
972         return FALSE;
973 }
974
975 static gint fix_rate_entryfocusout( GtkWidget *widget, GdkEventFocus *event, gpointer data ){
976         double r = atof( gtk_entry_get_text( GTK_ENTRY( widget ) ) );
977         int k;
978
979         if ( r != xyz[Vertex[0].i][Vertex[0].j].rate ) {
980                 for ( k = 0; k < NumVerticesSelected; k++ )
981                         xyz[Vertex[k].i][Vertex[k].j].rate = r;
982                 UpdatePreview( true );
983         }
984         return FALSE;
985 }
986
987 static void fix_free( GtkWidget *widget, gpointer data ){
988         int k;
989
990         for ( k = 0; k < NumVerticesSelected; k++ )
991                 xyz[Vertex[k].i][Vertex[k].j].fixed = 0;
992         NumVerticesSelected = 0;
993         SetupControls();
994         UpdatePreview( true );
995 }
996
997 static void fix_freeall( GtkWidget *widget, gpointer data ){
998         int i, j;
999
1000         for ( i = 0; i <= NH; i++ )
1001         {
1002                 for ( j = 0; j <= NV; j++ )
1003                         xyz[i][j].fixed = 0;
1004         }
1005         fix_free( NULL, data ); // keep these together
1006 }
1007
1008 void vertex_selected(){
1009         char Text[32];
1010         int k;
1011
1012         SetupControls();
1013
1014         switch ( Plane )
1015         {
1016         case PLANE_XZ0:
1017         case PLANE_XZ1:
1018                 for ( k = 0; k < NumVerticesSelected; k++ )
1019                         xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[1];
1020                 break;
1021         case PLANE_YZ0:
1022         case PLANE_YZ1:
1023                 for ( k = 0; k < NumVerticesSelected; k++ )
1024                         xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[0];
1025                 break;
1026         default:
1027                 for ( k = 0; k < NumVerticesSelected; k++ )
1028                         xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[2];
1029                 break;
1030         }
1031
1032         gtk_spin_button_set_value( GTK_SPIN_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ), "fix_value" ) ),
1033                                                            (int)xyz[Vertex[0].i][Vertex[0].j].fixed_value );
1034
1035         sprintf( Text,"%d",(int)xyz[Vertex[0].i][Vertex[0].j].range );
1036         gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "fix_range" ) ), Text );
1037         sprintf( Text,"%.5g",xyz[Vertex[0].i][Vertex[0].j].rate );
1038         gtk_entry_set_text( GTK_ENTRY( g_object_get_data( G_OBJECT( g_pWnd ), "fix_rate" ) ), Text );
1039
1040         for ( k = 0; k < NumVerticesSelected; k++ )
1041                 xyz[Vertex[k].i][Vertex[k].j].fixed = 1;
1042
1043         UpdatePreview( true );
1044 }
1045
1046 // =============================================================================
1047 // texture tab callbacks
1048
1049 static void texture_detail( GtkToggleButton *check, gpointer data ){
1050         UseDetail = gtk_toggle_button_get_active( check );
1051         WasDetail = UseDetail;
1052 }
1053
1054 static void texture_hint( GtkToggleButton *check, gpointer data ){
1055         AddHints = gtk_toggle_button_get_active( check );
1056         if ( AddHints == 1 ) {
1057                 UseDetail = 1;
1058                 ENABLE_WIDGET( "detail", FALSE );
1059         }
1060         else
1061         {
1062                 UseDetail = WasDetail;
1063                 ENABLE_WIDGET( "detail", FALSE );
1064         }
1065         CHECK_WIDGET( "detail", UseDetail );
1066 }
1067
1068 // ^Fishman - Add terrain key to func_group.
1069 static void texture_terrainent( GtkToggleButton *check, gpointer data ){
1070         AddTerrainKey = gtk_toggle_button_get_active( check );
1071 }
1072
1073 static void texture_set( int index, const char* name ){
1074         strcpy( Texture[Game][index], name );
1075 }
1076
1077 static gint texture_entryfocusout( GtkWidget* widget, GdkEventFocus* event, gpointer data ){
1078         texture_set( GPOINTER_TO_INT( data ), gtk_entry_get_text( GTK_ENTRY( widget ) ) );
1079         return FALSE;
1080 }
1081
1082 // =============================================================================
1083 // misc stuff
1084
1085 static void UpdateVariable( GtkEntry *entry, GdkEventFocus *event, double *data ){
1086         double x = atof( gtk_entry_get_text( entry ) );
1087
1088         if ( x != *data ) {
1089                 *data = x;
1090                 UpdatePreview( true );
1091         }
1092 }
1093
1094 static gint doublevariable_entryfocusout( GtkWidget* widget, GdkEventFocus* event, gpointer data ){
1095         UpdateVariable( GTK_ENTRY( widget ), event, reinterpret_cast<double*>( data ) );
1096         return FALSE;
1097 }
1098
1099 // =============================================================================
1100 // create tooltips
1101
1102 void create_tooltips(){
1103         tooltips = gtk_tooltips_new();
1104
1105         // Main
1106         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1107                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "go" ) ),
1108                                                   "Accept all input and generate a surface in Q3Radiant",
1109                                                   "" );
1110         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1111                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "open" ) ),
1112                                                   "Open a previously saved GenSurf settings file.",
1113                                                   "" );
1114         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1115                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "save" ) ),
1116                                                   "Save all settings to a file.",
1117                                                   "" );
1118         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1119                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "defaults" ) ),
1120                                                   "Restore default values from DEFAULTS.SRF. If this file does not exist, GenSurf "
1121                                                   "initializes all input parameters to reasonable values. You can create your own "
1122                                                   "default surface by setting all parameters to your liking, then saving a settings "
1123                                                   "file as DEFAULTS.SRF with the Save As button.",
1124                                                   "" );
1125
1126         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1127                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "main_preview" ) ),
1128                                                   "View a wire-frame representation of the surface",
1129                                                   "" );
1130
1131         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1132                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "main_antialiasing" ) ),
1133                                                   "The lines in the preview window are antialiased for better quality",
1134                                                   "" );
1135
1136         // General tab
1137         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1138                                                   GTK_WIDGET( wave_radios[0] ),
1139                                                   "Builds a surface with alternating hills and valleys. Uses the general form Z=cos(X) "
1140                                                   "x sin(Y)",
1141                                                   "" );
1142         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1143                                                   GTK_WIDGET( wave_radios[1] ),
1144                                                   "Builds a surface with ridges parallel to the vertical axis.",
1145                                                   "" );
1146         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1147                                                   GTK_WIDGET( wave_radios[2] ),
1148                                                   "Builds a surface with ridges parallel to the horizontal axis.",
1149                                                   "" );
1150         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1151                                                   GTK_WIDGET( wave_radios[3] ),
1152                                                   "Builds a map from a bitmap image representing a contour plot. Click the \"Bitmap\" "
1153                                                   "tab to select the image. GenSurf only supports 256-color (8 bit) "
1154                                                   "bitmaps. GenSurf will work with any 256-color bitmap, but gray scale bitmaps are a bit "
1155                                                   "more intuitive.",
1156                                                   "" );
1157         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1158                                                   GTK_WIDGET( wave_radios[4] ),
1159                                                   "Builds a random surface using the Plasma Cloud technique. Variance is controlled "
1160                                                   "by the Roughness input. To build a surface with completely random values not "
1161                                                   "dependent on neighboring vertices, use one of the other waveforms with 0 amplitude.",
1162                                                   "" );
1163         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1164                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "wavelength" ) ),
1165                                                   "Enter the wavelength (distance between crests). NOTE: Wavelengths equal to the grid "
1166                                                   "size or 2 times the grid size will result in 0 amplitudes. For best results, the "
1167                                                   "wavelength value should be at least 4 times the grid size (extents divided by the "
1168                                                   "number of divisions",
1169                                                   "" );
1170         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1171                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "amplitude" ) ),
1172                                                   "Enter the height of hills/ridges.",
1173                                                   "" );
1174         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1175                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "roughness" ) ),
1176                                                   "Enter the roughness value (noise) for the surface. For fractal surfaces, this value "
1177                                                   "is used as a variance in the fractal calculations.",
1178                                                   "" );
1179         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1180                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "random" ) ),
1181                                                   "Seed value for the pseudo-random number generator.",
1182                                                   "" );
1183         // Extents tab
1184         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1185                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "hmin" ) ),
1186                                                   "Minimum horizontal coordinate of the surface, i.e. X for a surface parallel to "
1187                                                   "the XY or XZ planes, Y for a surface parallel to the YZ plane. For best results, "
1188                                                   "the extents (maximum-minimum values) in a given direction should be evenly "
1189                                                   "divisible by the number of divisions in that direction.",
1190                                                   "" );
1191         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1192                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "hmax" ) ),
1193                                                   "Maximum horizontal coordinate of the surface, i.e. X for a surface parallel to "
1194                                                   "the XY or XZ planes, Y for a surface parallel to the YZ plane. For best results, "
1195                                                   "the extents (maximum-minimum values) in a given direction should be evenly "
1196                                                   "divisible by the number of divisions in that direction.",
1197                                                   "" );
1198         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1199                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "vmin" ) ),
1200                                                   "Minimum vertical coordinate of the surface, i.e. Y for a surface parallel to "
1201                                                   "the XY plane, Z for a surface parallel to the XZ or YZ planes. For best results, "
1202                                                   "the extents (maximum-minimum values) in a given direction should be evenly "
1203                                                   "divisible by the number of divisions in that direction.",
1204                                                   "" );
1205         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1206                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "vmax" ) ),
1207                                                   "Maximum vertical coordinate of the surface, i.e. Y for a surface parallel to "
1208                                                   "the XY plane, Z for a surface parallel to the XZ or YZ planes. For best results, "
1209                                                   "the extents (maximum-minimum values) in a given direction should be evenly "
1210                                                   "divisible by the number of divisions in that direction.",
1211                                                   "" );
1212         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1213                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "nh" ) ),
1214                                                   "Number of divisions in the horizontal direction. For best results, the extents "
1215                                                   "in a given direction should be evenly divisible by the number of divisions in "
1216                                                   "that direction.",
1217                                                   "" );
1218         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1219                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "nv" ) ),
1220                                                   "Number of divisions in the vertical direction. For best results, the extents "
1221                                                   "in a given direction should be evenly divisible by the number of divisions in "
1222                                                   "that direction.",
1223                                                   "" );
1224         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1225                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "use_patches" ) ),
1226                                                   "Produce one or more curved patches in the shape of your selected surface rather "
1227                                                   "than producing solid brushes. Depending on the size of your surface (and the "
1228                                                   "user's graphic detail settings, which you cannot control), curved surfaces will "
1229                                                   "be represented in the game by a very large number of polygons. Read the warnings "
1230                                                   "concerning curved surfaces on the GenSurf web page before using this feature.",
1231                                                   "" );
1232         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1233                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "decimate" ) ),
1234                                                   "Use the slider to control the number of vertices discarded by GenSurf. For many "
1235                                                   "surfaces, you can produce roughly the same shape surface with a high decimation "
1236                                                   "value. This will generally result in a map with lower polygon counts (and better "
1237                                                   "in-game performance). However, this feature should NOT be used for large terrain "
1238                                                   "surfaces in Q3",
1239                                                   "" );
1240         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1241                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "z00" ) ),
1242                                                   "Enter the height of the surface at the lower left corner. This value will likely "
1243                                                   "be modified unless \"Linear Borders\" is checked.",
1244                                                   "" );
1245         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1246                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "z01" ) ),
1247                                                   "Enter the height of the surface at the upper left corner. This value will likely "
1248                                                   "be modified unless \"Linear Borders\" is checked.",
1249                                                   "" );
1250         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1251                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "z10" ) ),
1252                                                   "Enter the height of the surface at the lower right corner. This value will likely "
1253                                                   "be modified unless \"Linear Borders\" is checked.",
1254                                                   "" );
1255         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1256                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "z11" ) ),
1257                                                   "Enter the height of the surface at the upper right corner. This value will likely "
1258                                                   "be modified unless \"Linear Borders\" is checked.",
1259                                                   "" );
1260         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1261                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "linearborder" ) ),
1262                                                   "Restrict the edges of the surface to a straight line. This will help match up "
1263                                                   "brush edges if you drop this surface into another map.",
1264                                                   "" );
1265         // Bitmap tab
1266         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1267                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_file" ) ),
1268                                                   "Type the name of an 8-bit bitmap image file, or click Browse to select an image "
1269                                                   "from a list of those available on your system.",
1270                                                   "" );
1271         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1272                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_file_browse" ) ),
1273                                                   "Select a bitmap image file from a list of those available on your system.",
1274                                                   "" );
1275         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1276                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_reload" ) ),
1277                                                   "Reload the selected bitmap file after making changes in an external image editor.",
1278                                                   "" );
1279         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1280                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_black" ) ),
1281                                                   "Enter the value corresponding to color index 0 in the bitmap file. For gray scale "
1282                                                   "images, color 0 is normally black.",
1283                                                   "" );
1284         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1285                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "bmp_white" ) ),
1286                                                   "Enter the value corresponding to color index 255 in the bitmap file. For gray scale "
1287                                                   "images, color 255 is normally white.",
1288                                                   "" );
1289         // Fixpoints tab
1290         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1291                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "fix_value" ) ),
1292                                                   "Enter a value for the selected vertex. This value will not be adjusted when applying "
1293                                                   "a waveform or roughness to the surface. Unlock this vertex (so that it will be "
1294                                                   "adjusted normally) by clicking \"Free\". This vertex will influence vertices within "
1295                                                   "the \"Range affected\" of this vertex.",
1296                                                   "" );
1297         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1298                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "fix_range" ) ),
1299                                                   "Enter the range away from the selected vertex that other vertices will be affected. "
1300                                                   "Use 0 if you don't want other vertices to be influenced by the currently selected "
1301                                                   "one. Note: this box is disabled if you've chosen the fractal generator, as it uses "
1302                                                   "a completely different method for determining values.",
1303                                                   "" );
1304         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1305                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "fix_rate" ) ),
1306                                                   "Enter a rate of change for the surface affected by the fixed value. 0 gives a smooth "
1307                                                   "sinusoidal curve, values less than 0 give progressively sharper spikes, and values "
1308                                                   "greater than 0 take on a square shape. Values less than -30 or greater than 30 are "
1309                                                   "set to -30 and 30, respectively. Note that this entry will have no effect unless "
1310                                                   "you also specify a \"range affected\".",
1311                                                   "" );
1312         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1313                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "fix_free" ) ),
1314                                                   "Click this to free (unlock the value of) the currently selected vertex.",
1315                                                   "" );
1316         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1317                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "fix_freeall" ) ),
1318                                                   "Click this to free (unlock the values of) all vertices.",
1319                                                   "" );
1320         // Texture tab
1321         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1322                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "texture1" ) ),
1323                                                   "Enter the name of the texture or shader used for the surface faces.",
1324                                                   "" );
1325         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1326                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "texture2" ) ),
1327                                                   "Enter the name of the texture or shader used for faces other than the surface. Under "
1328                                                   "normal circumstances this should be \"common/caulk\"",
1329                                                   "" );
1330         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1331                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "texture3" ) ),
1332                                                   "Enter the name of the texture or shader used for \"steep\" surface faces, where \"steep\" "
1333                                                   "is the angle specified below. If this entry is left blank or if the \"steep\" angle is 0, "
1334                                                   "all surface faces will use the texture specified by \"Surface\".",
1335                                                   "" );
1336
1337         gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1338                                                   GTK_WIDGET( g_object_get_data( G_OBJECT( g_pWnd ), "detail" ) ),
1339                                                   "Check this box to use the detail content property on the generated brushes. Compile "
1340                                                   "times will be considerably shorter if the detail property is used, though the surface "
1341                                                   "will not block visibility at all. If you use the detail property, you should make sure "
1342                                                   "that \"common/caulk\" is used for the non-surface faces, or the polygon count will be "
1343                                                   "much higher than necessary.",
1344                                                   "" );
1345 }
1346
1347 // =============================================================================
1348 // create main dialog
1349
1350 GtkWidget* create_main_dialog(){
1351         GtkWidget *dlg, *vbox, *hbox, *hbox2, *button, *notebook, *frame, *table, *table2;
1352         GtkWidget *check, *spin, *radio, *label, *entry, *scale;
1353         GtkObject *adj;
1354         GSList *group;
1355         int i;
1356         const char *games[] = { "Quake 2", "Half-Life", "SiN", "Heretic 2", "Kingpin", "Genesis3D", "Quake 3 Arena" };
1357         const char *waveforms[] = { "Alternating hill/valley", "Cylindrical left-to-right", "Cylindrical top-to-bottom",
1358                                                                 "From bitmap", "Fractal" };
1359         const char *orientations[] = { "Ground surface", "Ceiling", "Wall facing 0", "Wall facing 90",
1360                                                                    "Wall facing 180","Wall facing 270" };
1361
1362         g_pWnd = dlg = gtk_window_new( GTK_WINDOW_TOPLEVEL );
1363         gtk_window_set_title( GTK_WINDOW( dlg ), gszCaption );
1364         g_signal_connect( G_OBJECT( dlg ), "delete_event", G_CALLBACK( main_close ), NULL );
1365         //  g_signal_connect (G_OBJECT (dlg), "destroy", G_CALLBACK (gtk_widget_destroy), NULL);
1366         gtk_window_set_transient_for( GTK_WINDOW( dlg ), GTK_WINDOW( g_pRadiantWnd ) );
1367
1368         hbox = gtk_hbox_new( FALSE, 5 );
1369         gtk_widget_show( hbox );
1370         gtk_container_add( GTK_CONTAINER( dlg ), hbox );
1371         gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
1372
1373         notebook = gtk_notebook_new();
1374         gtk_widget_show( notebook );
1375         gtk_box_pack_start( GTK_BOX( hbox ), notebook, TRUE, TRUE, 0 );
1376         g_signal_connect( G_OBJECT( notebook ), "switch_page",
1377                                           G_CALLBACK( switch_page ), NULL );
1378         gtk_notebook_set_tab_pos( GTK_NOTEBOOK( notebook ), GTK_POS_TOP );
1379         g_object_set_data( G_OBJECT( dlg ), "notebook", notebook );
1380
1381         table = gtk_table_new( 2, 2, FALSE );
1382         gtk_widget_show( table );
1383         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1384         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1385         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1386
1387         label = gtk_label_new( _( "General" ) );
1388         gtk_widget_show( label );
1389         gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), table, label );
1390
1391         frame = gtk_frame_new( _( "Game" ) );
1392         gtk_widget_show( frame );
1393         gtk_table_attach( GTK_TABLE( table ), frame, 0, 1, 0, 1,
1394                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1395                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1396
1397         vbox = gtk_vbox_new( TRUE, 5 );
1398         gtk_widget_show( vbox );
1399         gtk_container_add( GTK_CONTAINER( frame ), vbox );
1400         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1401
1402         for ( i = 0, group = NULL; i < NUMGAMES; i++ )
1403         {
1404                 radio = gtk_radio_button_new_with_label( group, games[i] );
1405                 gtk_widget_show( radio );
1406                 gtk_box_pack_start( GTK_BOX( vbox ), radio, TRUE, TRUE, 0 );
1407                 group = gtk_radio_button_group( GTK_RADIO_BUTTON( radio ) );
1408                 game_radios[i] = radio;
1409                 g_signal_connect( G_OBJECT( radio ), "toggled", G_CALLBACK( general_game ), GINT_TO_POINTER( i ) );
1410         }
1411
1412         frame = gtk_frame_new( _( "Waveform" ) );
1413         gtk_widget_show( frame );
1414         gtk_table_attach( GTK_TABLE( table ), frame, 1, 2, 0, 1,
1415                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1416                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1417
1418         vbox = gtk_vbox_new( TRUE, 5 );
1419         gtk_widget_show( vbox );
1420         gtk_container_add( GTK_CONTAINER( frame ), vbox );
1421         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1422
1423         for ( i = 0, group = NULL; i < 5; i++ )
1424         {
1425                 radio = gtk_radio_button_new_with_label( group, waveforms[i] );
1426                 gtk_widget_show( radio );
1427                 gtk_box_pack_start( GTK_BOX( vbox ), radio, TRUE, TRUE, 0 );
1428                 group = gtk_radio_button_group( GTK_RADIO_BUTTON( radio ) );
1429                 wave_radios[i] = radio;
1430                 g_signal_connect( G_OBJECT( radio ), "toggled", G_CALLBACK( general_wave ), GINT_TO_POINTER( i ) );
1431         }
1432
1433         frame = gtk_frame_new( _( "Orientation" ) );
1434         gtk_widget_show( frame );
1435         gtk_table_attach( GTK_TABLE( table ), frame, 0, 1, 1, 2,
1436                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1437                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1438
1439         vbox = gtk_vbox_new( TRUE, 5 );
1440         gtk_widget_show( vbox );
1441         gtk_container_add( GTK_CONTAINER( frame ), vbox );
1442         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1443
1444         for ( i = 0, group = NULL; i < 6; i++ )
1445         {
1446                 radio = gtk_radio_button_new_with_label( group, orientations[i] );
1447                 gtk_widget_show( radio );
1448                 gtk_box_pack_start( GTK_BOX( vbox ), radio, TRUE, TRUE, 0 );
1449                 group = gtk_radio_button_group( GTK_RADIO_BUTTON( radio ) );
1450                 plane_radios[i] = radio;
1451                 g_signal_connect( G_OBJECT( radio ), "toggled", G_CALLBACK( general_plane ), GINT_TO_POINTER( i ) );
1452         }
1453
1454         table2 = gtk_table_new( 4, 2, FALSE );
1455         gtk_widget_show( table2 );
1456         gtk_table_set_row_spacings( GTK_TABLE( table2 ), 5 );
1457         gtk_table_set_col_spacings( GTK_TABLE( table2 ), 5 );
1458         gtk_table_attach( GTK_TABLE( table ), table2, 1, 2, 1, 2,
1459                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1460                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1461
1462         label = gtk_label_new( _( "Wavelength:" ) );
1463         gtk_widget_show( label );
1464         gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 0, 1,
1465                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1466                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1467         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1468         gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1469
1470         label = gtk_label_new( _( "Max. amplitude:" ) );
1471         gtk_widget_show( label );
1472         gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 1, 2,
1473                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1474                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1475         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1476         gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1477
1478         label = gtk_label_new( _( "Roughness:" ) );
1479         gtk_widget_show( label );
1480         gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 2, 3,
1481                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1482                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1483         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1484         gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1485
1486         label = gtk_label_new( _( "Random seed:" ) );
1487         gtk_widget_show( label );
1488         gtk_table_attach( GTK_TABLE( table2 ), label, 0, 1, 3, 4,
1489                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1490                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1491         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1492         gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1493
1494         entry = gtk_entry_new();
1495         gtk_widget_show( entry );
1496         gtk_table_attach( GTK_TABLE( table2 ), entry, 1, 2, 0, 1,
1497                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1498                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1499         gtk_widget_set_usize( entry, 50, -2 );
1500         g_object_set_data( G_OBJECT( dlg ), "wavelength", entry );
1501         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &WaveLength );
1502
1503         entry = gtk_entry_new();
1504         gtk_widget_show( entry );
1505         gtk_table_attach( GTK_TABLE( table2 ), entry, 1, 2, 1, 2,
1506                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1507                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1508         gtk_widget_set_usize( entry, 50, -2 );
1509         g_object_set_data( G_OBJECT( dlg ), "amplitude", entry );
1510         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Amplitude );
1511
1512         entry = gtk_entry_new();
1513         gtk_widget_show( entry );
1514         gtk_table_attach( GTK_TABLE( table2 ), entry, 1, 2, 2, 3,
1515                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1516                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1517         gtk_widget_set_usize( entry, 50, -2 );
1518         g_object_set_data( G_OBJECT( dlg ), "roughness", entry );
1519         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Roughness );
1520
1521         adj = gtk_adjustment_new( 1, 1, 32767, 1, 10, 10 );
1522         g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( general_random ), NULL );
1523         spin = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
1524         gtk_widget_show( spin );
1525         gtk_table_attach( GTK_TABLE( table2 ), spin, 1, 2, 3, 4,
1526                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1527                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1528         gtk_widget_set_usize( spin, 60, -2 );
1529         g_object_set_data( G_OBJECT( dlg ), "random", spin );
1530
1531         vbox = gtk_vbox_new( FALSE, 5 );
1532         gtk_widget_show( vbox );
1533         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1534
1535         label = gtk_label_new( _( "Extents" ) );
1536         gtk_widget_show( label );
1537         gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
1538
1539         hbox2 = gtk_hbox_new( FALSE, 5 );
1540         gtk_widget_show( hbox2 );
1541         gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, TRUE, 0 );
1542
1543         frame = gtk_frame_new( _( "Extents" ) );
1544         gtk_widget_show( frame );
1545         gtk_box_pack_start( GTK_BOX( hbox2 ), frame, TRUE, TRUE, 0 );
1546
1547         table = gtk_table_new( 3, 4, FALSE );
1548         gtk_widget_show( table );
1549         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1550         gtk_container_add( GTK_CONTAINER( frame ), table );
1551         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1552         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1553
1554         label = gtk_label_new( _( "X:" ) );
1555         gtk_widget_show( label );
1556         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
1557                                           (GtkAttachOptions) ( GTK_FILL ),
1558                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1559         g_object_set_data( G_OBJECT( dlg ), "hmin_text", label );
1560
1561         label = gtk_label_new( _( "X:" ) );
1562         gtk_widget_show( label );
1563         gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2,
1564                                           (GtkAttachOptions) ( GTK_FILL ),
1565                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1566         g_object_set_data( G_OBJECT( dlg ), "hmax_text", label );
1567
1568         label = gtk_label_new( _( "Y:" ) );
1569         gtk_widget_show( label );
1570         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
1571                                           (GtkAttachOptions) ( GTK_FILL ),
1572                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1573         g_object_set_data( G_OBJECT( dlg ), "vmin_text", label );
1574
1575         label = gtk_label_new( _( "Y:" ) );
1576         gtk_widget_show( label );
1577         gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 2, 3,
1578                                           (GtkAttachOptions) ( GTK_FILL ),
1579                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1580         g_object_set_data( G_OBJECT( dlg ), "vmax_text", label );
1581
1582         label = gtk_label_new( _( "Lower-left" ) );
1583         gtk_widget_show( label );
1584         gtk_table_attach( GTK_TABLE( table ), label, 1, 2, 0, 1,
1585                                           (GtkAttachOptions) ( GTK_FILL ),
1586                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1587
1588         label = gtk_label_new( _( "Upper-right" ) );
1589         gtk_widget_show( label );
1590         gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 0, 1,
1591                                           (GtkAttachOptions) ( GTK_FILL ),
1592                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1593
1594         entry = gtk_entry_new();
1595         gtk_widget_show( entry );
1596         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2,
1597                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1598                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1599         gtk_widget_set_usize( entry, 50, -2 );
1600         g_object_set_data( G_OBJECT( dlg ), "hmin", entry );
1601         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Hll );
1602
1603         entry = gtk_entry_new();
1604         gtk_widget_show( entry );
1605         gtk_table_attach( GTK_TABLE( table ), entry, 3, 4, 1, 2,
1606                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1607                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1608         gtk_widget_set_usize( entry, 50, -2 );
1609         g_object_set_data( G_OBJECT( dlg ), "hmax", entry );
1610         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Hur );
1611
1612         entry = gtk_entry_new();
1613         gtk_widget_show( entry );
1614         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 2, 3,
1615                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1616                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1617         gtk_widget_set_usize( entry, 50, -2 );
1618         g_object_set_data( G_OBJECT( dlg ), "vmin", entry );
1619         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Vll );
1620
1621         entry = gtk_entry_new();
1622         gtk_widget_show( entry );
1623         gtk_table_attach( GTK_TABLE( table ), entry, 3, 4, 2, 3,
1624                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1625                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1626         gtk_widget_set_usize( entry, 50, -2 );
1627         g_object_set_data( G_OBJECT( dlg ), "vmax", entry );
1628         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Vur );
1629
1630         frame = gtk_frame_new( _( "Divisions" ) );
1631         gtk_widget_show( frame );
1632         gtk_box_pack_start( GTK_BOX( hbox2 ), frame, TRUE, TRUE, 0 );
1633
1634         table = gtk_table_new( 2, 2, FALSE );
1635         gtk_widget_show( table );
1636         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1637         gtk_container_add( GTK_CONTAINER( frame ), table );
1638         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1639         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1640
1641         label = gtk_label_new( _( "X:" ) );
1642         gtk_widget_show( label );
1643         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
1644                                           (GtkAttachOptions) ( GTK_FILL ),
1645                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1646         g_object_set_data( G_OBJECT( dlg ), "nh_text", label );
1647
1648         label = gtk_label_new( _( "Y:" ) );
1649         gtk_widget_show( label );
1650         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
1651                                           (GtkAttachOptions) ( GTK_FILL ),
1652                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1653         g_object_set_data( G_OBJECT( dlg ), "nv_text", label );
1654
1655         adj = gtk_adjustment_new( 8, 1, MAX_ROWS, 1, 10, 10 );
1656         g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( extents_nhnv_spin ), &NH );
1657         spin = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
1658         gtk_widget_show( spin );
1659         gtk_table_attach( GTK_TABLE( table ), spin, 1, 2, 0, 1,
1660                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1661                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1662         gtk_widget_set_usize( spin, 60, -2 );
1663         g_object_set_data( G_OBJECT( dlg ), "nh", spin );
1664
1665         adj = gtk_adjustment_new( 8, 1, MAX_ROWS, 1, 10, 10 );
1666         g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( extents_nhnv_spin ), &NV );
1667         spin = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
1668         gtk_widget_show( spin );
1669         gtk_table_attach( GTK_TABLE( table ), spin, 1, 2, 1, 2,
1670                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1671                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1672         gtk_widget_set_usize( spin, 60, -2 );
1673         g_object_set_data( G_OBJECT( dlg ), "nv", spin );
1674
1675         check = gtk_check_button_new_with_label( "Use Bezier patches" );
1676         gtk_widget_show( check );
1677         gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, TRUE, 0 );
1678         g_object_set_data( G_OBJECT( dlg ), "use_patches", check );
1679         g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( extents_use_patches ), NULL );
1680
1681         // ^Fishman - Snap to grid, replaced scroll bar with a texbox.
1682         label = gtk_label_new( _( "Snap to grid:" ) );
1683         gtk_widget_show( label );
1684         gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, TRUE, 0 );
1685         gtk_object_set_data( GTK_OBJECT( dlg ), "snap_text", label );
1686
1687         adj = gtk_adjustment_new( 8, 0, 256, 1, 10, 10 );
1688         g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( extents_snaptogrid_spin ), &SP );
1689         spin = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
1690         gtk_widget_show( spin );
1691         gtk_box_pack_start( GTK_BOX( vbox ), spin, FALSE, TRUE, 0 );
1692         gtk_widget_set_usize( spin, 60, -2 );
1693         g_object_set_data( G_OBJECT( dlg ), "sp", spin );
1694         // ^Fishman - End of Snap to grid code.
1695
1696         hbox2 = gtk_hbox_new( FALSE, 5 );
1697         gtk_widget_show( hbox2 );
1698         gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, TRUE, 10 );
1699
1700         label = gtk_label_new( _( "Decimate:" ) );
1701         gtk_widget_show( label );
1702         gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, TRUE, 0 );
1703
1704         adj = gtk_adjustment_new( 0, 0, 110, 1, 10, 10 );
1705         g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( extents_decimate ), NULL );
1706         g_object_set_data( G_OBJECT( dlg ), "decimate_adj", adj );
1707         scale = gtk_hscale_new( GTK_ADJUSTMENT( adj ) );
1708         gtk_widget_show( scale );
1709         gtk_box_pack_start( GTK_BOX( hbox2 ), scale, TRUE, TRUE, 0 );
1710         gtk_scale_set_value_pos( GTK_SCALE( scale ), GTK_POS_RIGHT );
1711         gtk_scale_set_digits( GTK_SCALE( scale ), 0 );
1712         g_object_set_data( G_OBJECT( dlg ), "decimate", scale );
1713
1714         frame = gtk_frame_new( _( "Corner values" ) );
1715         gtk_widget_show( frame );
1716         gtk_box_pack_start( GTK_BOX( vbox ), frame, FALSE, TRUE, 0 );
1717
1718         table = gtk_table_new( 3, 4, FALSE );
1719         gtk_widget_show( table );
1720         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1721         gtk_container_add( GTK_CONTAINER( frame ), table );
1722         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1723         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1724
1725         label = gtk_label_new( _( "Upper-left:" ) );
1726         gtk_widget_show( label );
1727         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
1728                                           (GtkAttachOptions) ( GTK_FILL ),
1729                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1730
1731         label = gtk_label_new( _( "Lower-left:" ) );
1732         gtk_widget_show( label );
1733         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
1734                                           (GtkAttachOptions) ( GTK_FILL ),
1735                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1736
1737         label = gtk_label_new( _( "Upper-right:" ) );
1738         gtk_widget_show( label );
1739         gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1,
1740                                           (GtkAttachOptions) ( GTK_FILL ),
1741                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1742
1743         label = gtk_label_new( _( "Lower-right:" ) );
1744         gtk_widget_show( label );
1745         gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2,
1746                                           (GtkAttachOptions) ( GTK_FILL ),
1747                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1748
1749         entry = gtk_entry_new();
1750         gtk_widget_show( entry );
1751         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1,
1752                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1753                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1754         gtk_widget_set_usize( entry, 50, -2 );
1755         g_object_set_data( G_OBJECT( dlg ), "z01", entry );
1756         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z01 );
1757
1758         entry = gtk_entry_new();
1759         gtk_widget_show( entry );
1760         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2,
1761                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1762                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1763         gtk_widget_set_usize( entry, 50, -2 );
1764         g_object_set_data( G_OBJECT( dlg ), "z00", entry );
1765         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z00 );
1766
1767         entry = gtk_entry_new();
1768         gtk_widget_show( entry );
1769         gtk_table_attach( GTK_TABLE( table ), entry, 3, 4, 0, 1,
1770                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1771                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1772         gtk_widget_set_usize( entry, 50, -2 );
1773         g_object_set_data( G_OBJECT( dlg ), "z11", entry );
1774         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z11 );
1775
1776         entry = gtk_entry_new();
1777         gtk_widget_show( entry );
1778         gtk_table_attach( GTK_TABLE( table ), entry, 3, 4, 1, 2,
1779                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1780                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1781         gtk_widget_set_usize( entry, 50, -2 );
1782         g_object_set_data( G_OBJECT( dlg ), "z10", entry );
1783         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z10 );
1784
1785         check = gtk_check_button_new_with_label( "Linear borders" );
1786         gtk_widget_show( check );
1787         gtk_table_attach( GTK_TABLE( table ), check, 0, 4, 2, 3,
1788                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1789                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1790         g_object_set_data( G_OBJECT( dlg ), "linearborder", check );
1791         g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( extents_linearborder ), NULL );
1792
1793         vbox = gtk_vbox_new( FALSE, 10 );
1794         gtk_widget_show( vbox );
1795         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1796
1797         label = gtk_label_new( _( "Bitmap" ) );
1798         gtk_widget_show( label );
1799         gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
1800
1801         label = gtk_label_new( "" );
1802         gtk_widget_show( label );
1803         gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, TRUE, 0 );
1804         g_object_set_data( G_OBJECT( dlg ), "bmp_note", label );
1805
1806         table = gtk_table_new( 2, 2, FALSE );
1807         gtk_widget_show( table );
1808         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1809         gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
1810         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1811         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1812
1813         label = gtk_label_new( _( "Filename:" ) );
1814         gtk_widget_show( label );
1815         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
1816                                           (GtkAttachOptions) ( GTK_FILL ),
1817                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1818         g_object_set_data( G_OBJECT( dlg ), "bmp_text1", label );
1819
1820         entry = gtk_entry_new();
1821         gtk_widget_show( entry );
1822         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1,
1823                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1824                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1825         g_object_set_data( G_OBJECT( dlg ), "bmp_file", entry );
1826         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( bitmap_file_entryfocusout ), NULL );
1827
1828         hbox2 = gtk_hbox_new( TRUE, 5 );
1829         gtk_widget_show( hbox2 );
1830         gtk_table_attach( GTK_TABLE( table ), hbox2, 1, 2, 1, 2,
1831                                           (GtkAttachOptions) ( 0 ),
1832                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1833
1834         button = gtk_button_new_with_label( _( "Browse..." ) );
1835         gtk_widget_show( button );
1836         gtk_box_pack_start( GTK_BOX( hbox2 ), button, FALSE, FALSE, 0 );
1837         gtk_widget_set_usize( button, 60, -2 );
1838         g_object_set_data( G_OBJECT( dlg ), "bmp_file_browse", button );
1839         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( bitmap_browse ), NULL );
1840
1841         button = gtk_button_new_with_label( _( "Reload" ) );
1842         gtk_widget_show( button );
1843         gtk_box_pack_start( GTK_BOX( hbox2 ), button, FALSE, FALSE, 0 );
1844         gtk_widget_set_usize( button, 60, -2 );
1845         g_object_set_data( G_OBJECT( dlg ), "bmp_reload", button );
1846         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( bitmap_reload ), NULL );
1847
1848         table = gtk_table_new( 2, 2, TRUE );
1849         gtk_widget_show( table );
1850         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1851         gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
1852         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1853         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1854
1855         label = gtk_label_new( _( "Map color 0 to:" ) );
1856         gtk_widget_show( label );
1857         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
1858                                           (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
1859                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1860         g_object_set_data( G_OBJECT( dlg ), "bmp_text2", label );
1861         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1862         gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1863
1864         label = gtk_label_new( _( "Map color 255 to:" ) );
1865         gtk_widget_show( label );
1866         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
1867                                           (GtkAttachOptions) ( GTK_FILL | GTK_EXPAND ),
1868                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1869         g_object_set_data( G_OBJECT( dlg ), "bmp_text3", label );
1870         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1871         gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1872
1873         hbox2 = gtk_hbox_new( FALSE, 5 );
1874         gtk_widget_show( hbox2 );
1875         gtk_table_attach( GTK_TABLE( table ), hbox2, 1, 2, 0, 1,
1876                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1877                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1878
1879         entry = gtk_entry_new();
1880         gtk_widget_show( entry );
1881         gtk_box_pack_start( GTK_BOX( hbox2 ), entry, FALSE, FALSE, 0 );
1882         gtk_widget_set_usize( entry, 50, -2 );
1883         g_object_set_data( G_OBJECT( dlg ), "bmp_black", entry );
1884         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &gbmp.black_value );
1885
1886         hbox2 = gtk_hbox_new( FALSE, 5 );
1887         gtk_widget_show( hbox2 );
1888         gtk_table_attach( GTK_TABLE( table ), hbox2, 1, 2, 1, 2,
1889                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1890                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
1891
1892         entry = gtk_entry_new();
1893         gtk_widget_show( entry );
1894         gtk_box_pack_start( GTK_BOX( hbox2 ), entry, FALSE, FALSE, 0 );
1895         gtk_widget_set_usize( entry, 50, -2 );
1896         g_object_set_data( G_OBJECT( dlg ), "bmp_white", entry );
1897         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &gbmp.white_value );
1898
1899         vbox = gtk_vbox_new( FALSE, 10 );
1900         gtk_widget_show( vbox );
1901         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1902
1903         label = gtk_label_new( _( "Fix Points" ) );
1904         gtk_widget_show( label );
1905         gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
1906
1907         label = gtk_label_new( _( "Click on a vertex in the lower half of the preview window,\n"
1908                                                           "then use the arrow keys or text box to assign a value.\n"
1909                                                           "Use Ctrl+Click to select multiple vertices/toggle a\n"
1910                                                           "selection. Use Shift+Click to select a range of vertices.\n\n"
1911                                                           "Click \"Free\" to unlock a vertex. Vertices within \"Range\n"
1912                                                           "affected\" will be influenced by this vertex." ) );
1913         gtk_widget_show( label );
1914         gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, TRUE, 0 );
1915
1916         table = gtk_table_new( 3, 3, FALSE );
1917         gtk_widget_show( table );
1918         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1919         gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
1920         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1921         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1922
1923         label = gtk_label_new( _( "Value:" ) );
1924         gtk_widget_show( label );
1925         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
1926                                           (GtkAttachOptions) ( GTK_FILL ),
1927                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1928         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1929         g_object_set_data( G_OBJECT( dlg ), "fix_value_text", label );
1930
1931         label = gtk_label_new( _( "Range affected:" ) );
1932         gtk_widget_show( label );
1933         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
1934                                           (GtkAttachOptions) ( GTK_FILL ),
1935                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1936         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1937         g_object_set_data( G_OBJECT( dlg ), "fix_range_text", label );
1938
1939         label = gtk_label_new( _( "Rate of change:" ) );
1940         gtk_widget_show( label );
1941         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
1942                                           (GtkAttachOptions) ( GTK_FILL ),
1943                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1944         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1945         g_object_set_data( G_OBJECT( dlg ), "fix_rate_text", label );
1946
1947         adj = gtk_adjustment_new( 0, -65536, 65536, 1, 16, 16 );
1948         g_signal_connect( G_OBJECT( adj ), "value_changed", G_CALLBACK( fix_value_changed ), NULL );
1949         spin = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
1950         gtk_widget_show( spin );
1951         gtk_table_attach( GTK_TABLE( table ), spin, 1, 2, 0, 1,
1952                                           (GtkAttachOptions) ( GTK_EXPAND ),
1953                                           (GtkAttachOptions) ( GTK_EXPAND ), 0, 0 );
1954         gtk_widget_set_usize( spin, 60, -2 );
1955         g_object_set_data( G_OBJECT( dlg ), "fix_value", spin );
1956         g_signal_connect( G_OBJECT( spin ), "focus_out_event", G_CALLBACK( fix_value_entryfocusout ), NULL );
1957
1958         entry = gtk_entry_new();
1959         gtk_widget_show( entry );
1960         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2,
1961                                           (GtkAttachOptions) ( GTK_EXPAND ),
1962                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1963         gtk_widget_set_usize( entry, 60, -2 );
1964         g_object_set_data( G_OBJECT( dlg ), "fix_range", entry );
1965         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( fix_range_entryfocusout ), NULL );
1966
1967         entry = gtk_entry_new();
1968         gtk_widget_show( entry );
1969         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 2, 3,
1970                                           (GtkAttachOptions) ( GTK_EXPAND ),
1971                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1972         gtk_widget_set_usize( entry, 60, -2 );
1973         g_object_set_data( G_OBJECT( dlg ), "fix_rate", entry );
1974         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( fix_rate_entryfocusout ), NULL );
1975
1976         button = gtk_button_new_with_label( _( "Free" ) );
1977         gtk_widget_show( button );
1978         gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 0, 1,
1979                                           (GtkAttachOptions) ( GTK_EXPAND ),
1980                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1981         gtk_widget_set_usize( button, 60, -2 );
1982         g_object_set_data( G_OBJECT( dlg ), "fix_free", button );
1983         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( fix_free ), NULL );
1984
1985         button = gtk_button_new_with_label( _( "Free All" ) );
1986         gtk_widget_show( button );
1987         gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 1, 2,
1988                                           (GtkAttachOptions) ( GTK_EXPAND ),
1989                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1990         gtk_widget_set_usize( button, 60, -2 );
1991         g_object_set_data( G_OBJECT( dlg ), "fix_freeall", button );
1992         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( fix_freeall ), NULL );
1993
1994         vbox = gtk_vbox_new( FALSE, 10 );
1995         gtk_widget_show( vbox );
1996         gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1997
1998         label = gtk_label_new( _( "Texture" ) );
1999         gtk_widget_show( label );
2000         gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
2001
2002         // ^Fishman - Modified to add more labels and textboxes.
2003         table = gtk_table_new( 5, 2, FALSE );
2004         gtk_widget_show( table );
2005         gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2006         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2007         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2008
2009         label = gtk_label_new( _( "Surface:" ) );
2010         gtk_widget_show( label );
2011         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
2012                                           (GtkAttachOptions) ( GTK_FILL ),
2013                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2014         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
2015
2016         label = gtk_label_new( _( "Other:" ) );
2017         gtk_widget_show( label );
2018         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
2019                                           (GtkAttachOptions) ( GTK_FILL ),
2020                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2021         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
2022
2023         label = gtk_label_new( _( "Steep:" ) );
2024         gtk_widget_show( label );
2025         gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
2026                                           (GtkAttachOptions) ( GTK_FILL ),
2027                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2028         gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
2029
2030         entry = gtk_entry_new();
2031         gtk_widget_show( entry );
2032         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1,
2033                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
2034                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2035         gtk_widget_set_usize( entry, 60, -2 );
2036         g_object_set_data( G_OBJECT( dlg ), "texture1", entry );
2037         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( texture_entryfocusout ), GINT_TO_POINTER( 0 ) );
2038
2039         entry = gtk_entry_new();
2040         gtk_widget_show( entry );
2041         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2,
2042                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
2043                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2044         gtk_widget_set_usize( entry, 60, -2 );
2045         g_object_set_data( G_OBJECT( dlg ), "texture2", entry );
2046         g_signal_connect( G_OBJECT( entry ), "focus_out_event", G_CALLBACK( texture_entryfocusout ), GINT_TO_POINTER( 1 ) );
2047
2048         entry = gtk_entry_new();
2049         gtk_widget_show( entry );
2050         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 2, 3,
2051                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
2052                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2053         gtk_widget_set_usize( entry, 60, -2 );
2054         g_object_set_data( G_OBJECT( dlg ), "texture3", entry );
2055
2056         hbox2 = gtk_hbox_new( FALSE, 5 );
2057         gtk_widget_show( hbox2 );
2058         gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, TRUE, 0 );
2059
2060         label = gtk_label_new( _( "\"Steep\" angle:" ) );
2061         gtk_widget_show( label );
2062         gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, TRUE, 0 );
2063
2064         adj = gtk_adjustment_new( 60, 0, 90, 1, 10, 10 );
2065         spin = gtk_spin_button_new( GTK_ADJUSTMENT( adj ), 1, 0 );
2066         gtk_widget_show( spin );
2067         gtk_box_pack_start( GTK_BOX( hbox2 ), spin, FALSE, TRUE, 0 );
2068         g_object_set_data( G_OBJECT( dlg ), "tex_slant", spin );
2069
2070         table = gtk_table_new( 2, 4, TRUE );
2071         gtk_widget_show( table );
2072         gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2073         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2074         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2075
2076         label = gtk_label_new( _( "Offset <h,v>" ) );
2077         gtk_widget_show( label );
2078         gtk_table_attach( GTK_TABLE( table ), label, 0, 2, 0, 1,
2079                                           (GtkAttachOptions) ( GTK_FILL ),
2080                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2081
2082         label = gtk_label_new( _( "Scale <h,v>" ) );
2083         gtk_widget_show( label );
2084         gtk_table_attach( GTK_TABLE( table ), label, 2, 4, 0, 1,
2085                                           (GtkAttachOptions) ( GTK_FILL ),
2086                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2087
2088         entry = gtk_entry_new();
2089         gtk_widget_show( entry );
2090         gtk_table_attach( GTK_TABLE( table ), entry, 0, 1, 1, 2,
2091                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
2092                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2093         gtk_widget_set_usize( entry, 60, -2 );
2094         g_object_set_data( G_OBJECT( dlg ), "texoffsetx", entry );
2095
2096         entry = gtk_entry_new();
2097         gtk_widget_show( entry );
2098         gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2,
2099                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
2100                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2101         gtk_widget_set_usize( entry, 60, -2 );
2102         g_object_set_data( G_OBJECT( dlg ), "texoffsety", entry );
2103
2104         entry = gtk_entry_new();
2105         gtk_widget_show( entry );
2106         gtk_table_attach( GTK_TABLE( table ), entry, 2, 3, 1, 2,
2107                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
2108                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2109         gtk_widget_set_usize( entry, 60, -2 );
2110         g_object_set_data( G_OBJECT( dlg ), "texscalex", entry );
2111
2112         entry = gtk_entry_new();
2113         gtk_widget_show( entry );
2114         gtk_table_attach( GTK_TABLE( table ), entry, 3, 4, 1, 2,
2115                                           (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
2116                                           (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
2117         gtk_widget_set_usize( entry, 60, -2 );
2118         g_object_set_data( G_OBJECT( dlg ), "texscaley", entry );
2119
2120
2121
2122         check = gtk_check_button_new_with_label( _( "Use detail brushes" ) );
2123         gtk_widget_show( check );
2124         gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, TRUE, 0 );
2125         g_object_set_data( G_OBJECT( dlg ), "detail", check );
2126         g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( texture_detail ), NULL );
2127
2128         check = gtk_check_button_new_with_label( _( "Detail hint brushes" ) );
2129         gtk_widget_show( check );
2130         gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, TRUE, 0 );
2131         g_object_set_data( G_OBJECT( dlg ), "hint", check );
2132         g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( texture_hint ), NULL );
2133
2134         // ^Fishman - Add terrain key to func_group.
2135         check = gtk_check_button_new_with_label( _( "Add terrain key" ) );
2136         gtk_widget_show( check );
2137         gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, TRUE, 0 );
2138         g_object_set_data( G_OBJECT( dlg ), "terrain_ent", check );
2139         g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( texture_terrainent ), NULL );
2140
2141         vbox = gtk_vbox_new( FALSE, 5 );
2142         gtk_widget_show( vbox );
2143         gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, TRUE, 0 );
2144
2145         button = gtk_button_new_with_label( _( "OK" ) );
2146         gtk_widget_show( button );
2147         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, TRUE, 0 );
2148         gtk_widget_set_usize( button, 60, -2 );
2149         g_object_set_data( G_OBJECT( dlg ), "go", button );
2150         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( main_go ), NULL );
2151
2152         label = gtk_label_new( _( "Settings:" ) );
2153         gtk_widget_show( label );
2154         gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, TRUE, 0 );
2155
2156         button = gtk_button_new_with_label( "Open..." );
2157         gtk_widget_show( button );
2158         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, TRUE, 0 );
2159         g_object_set_data( G_OBJECT( dlg ), "open", button );
2160         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( main_open ), NULL );
2161
2162         button = gtk_button_new_with_label( _( "Save as..." ) );
2163         gtk_widget_show( button );
2164         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, TRUE, 0 );
2165         g_object_set_data( G_OBJECT( dlg ), "save", button );
2166         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( main_save ), NULL );
2167
2168         button = gtk_button_new_with_label( _( "Defaults" ) );
2169         gtk_widget_show( button );
2170         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, TRUE, 0 );
2171         g_object_set_data( G_OBJECT( dlg ), "defaults", button );
2172         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( main_defaults ), NULL );
2173
2174         button = gtk_button_new_with_label( _( "About..." ) );
2175         gtk_widget_show( button );
2176         gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, TRUE, 0 );
2177         g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( main_about ), NULL );
2178
2179         check = gtk_check_button_new_with_label( _( "Preview" ) );
2180         gtk_widget_show( check );
2181         gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, TRUE, 0 );
2182         g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( main_preview ), NULL );
2183         g_object_set_data( G_OBJECT( dlg ), "main_preview", check );
2184
2185         // ^Fishman - Antializing for the preview window.
2186         check = gtk_check_button_new_with_label( _( "Antialised lines" ) );
2187         gtk_widget_show( check );
2188         gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, TRUE, 0 );
2189         g_object_set_data( G_OBJECT( dlg ), "main_antialiasing", check );
2190         g_signal_connect( G_OBJECT( check ), "toggled", G_CALLBACK( main_antialiasing ), NULL );
2191
2192         for ( i = 0; i < 5; i++ )
2193                 SetDlgValues( i );
2194
2195         CreateViewWindow();
2196
2197         create_tooltips();
2198
2199         FirstPassComplete = 1;
2200
2201         return dlg;
2202 }
2203
2204
2205 #if 0
2206
2207 HWND hwndDisplay = (HWND)NULL;
2208 HWND ghwndTab    = (HWND)NULL;
2209 int iTab = 0;
2210 RECT rcTab;
2211 FILE *ftex;
2212
2213 char GenSurfURL[40] = {"http://tarot.telefragged.com/gensurf"};
2214 char GenSurfBoard[40] = {"http://tarot.telefragged.com/board"};
2215
2216 /*
2217  * AboutDlgProc - processes messages for the about dialog.
2218  */
2219
2220 qboolean CALLBACK AboutDlgProc( HWND hwnd, unsigned msg, UINT wparam, LONG lparam ){
2221         char szText[256];
2222         DRAWITEMSTRUCT *dis;
2223         HDC hdc;
2224         HPEN hpen;
2225         HWND hwndURL;
2226         RECT rc;
2227         SIZE size;
2228
2229         lparam = lparam;                    /* turn off warning */
2230
2231         switch ( msg ) {
2232         case WM_INITDIALOG:
2233                 strcpy( szText,"About " );
2234                 strcat( szText,gszCaption );
2235                 SetWindowText( hwnd,gszCaption );
2236                 SetDlgItemText( hwnd,DLG_ABOUT_APP,szText );
2237                 /*      Application icon: */
2238                 SendDlgItemMessage( hwnd, DLG_ABOUT_ICON,
2239                                                         STM_SETICON, (WPARAM)(HICON)LoadIcon( ghInst,"GENSURF" ),
2240                                                         (LPARAM) NULL );
2241
2242                 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_URL );
2243                 hdc = GetDC( hwndURL );
2244                 GetTextExtentPoint( hdc,GenSurfURL,strlen( GenSurfURL ),&size );
2245                 ReleaseDC( hwndURL,hdc );
2246                 GetWindowRect( hwndURL,&rc );
2247                 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2248                                           SWP_NOMOVE | SWP_NOZORDER );
2249
2250                 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_BOARD );
2251                 hdc = GetDC( hwndURL );
2252                 GetTextExtentPoint( hdc,GenSurfBoard,strlen( GenSurfBoard ),&size );
2253                 ReleaseDC( hwndURL,hdc );
2254                 GetWindowRect( hwndURL,&rc );
2255                 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2256                                           SWP_NOMOVE | SWP_NOZORDER );
2257
2258                 return TRUE;
2259
2260         case WM_COMMAND:
2261                 switch ( LOWORD( wparam ) )
2262                 {
2263                 case DLG_ABOUT_URL:
2264                         HTTP( GenSurfURL );
2265                         break;
2266                 case DLG_ABOUT_BOARD:
2267                         HTTP( GenSurfBoard );
2268                         break;
2269                 case IDOK:
2270                         EndDialog( hwnd,1 );
2271                         return TRUE;
2272                 }
2273                 break;
2274
2275         case WM_DRAWITEM:
2276                 if ( wparam == DLG_ABOUT_URL ) {
2277                         dis = (LPDRAWITEMSTRUCT)lparam;
2278                         SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2279                         TextOut( dis->hDC,0,0,GenSurfURL,strlen( GenSurfURL ) );
2280                         GetWindowRect( dis->hwndItem,&rc );
2281                         GetTextExtentPoint( dis->hDC,GenSurfURL,strlen( GenSurfURL ),&size );
2282                         hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2283                         SelectObject( dis->hDC,hpen );
2284                         MoveToEx( dis->hDC,0,size.cy,NULL );
2285                         LineTo( dis->hDC,size.cx,size.cy );
2286                         SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2287                         DeleteObject( hpen );
2288                 }
2289                 else if ( wparam == DLG_ABOUT_BOARD ) {
2290                         dis = (LPDRAWITEMSTRUCT)lparam;
2291                         SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2292                         TextOut( dis->hDC,0,0,GenSurfBoard,strlen( GenSurfBoard ) );
2293                         GetWindowRect( dis->hwndItem,&rc );
2294                         GetTextExtentPoint( dis->hDC,GenSurfBoard,strlen( GenSurfBoard ),&size );
2295                         hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2296                         SelectObject( dis->hDC,hpen );
2297                         MoveToEx( dis->hDC,0,size.cy,NULL );
2298                         LineTo( dis->hDC,size.cx,size.cy );
2299                         SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2300                         DeleteObject( hpen );
2301                 }
2302                 break;
2303
2304         case WM_CLOSE:
2305                 EndDialog( hwnd,1 );
2306                 return TRUE;
2307
2308         default:
2309                 return FALSE;
2310         }
2311         return FALSE;
2312
2313 } /* AboutDlgProc */
2314
2315 void About(){
2316         if ( DialogBox( ghInst,"About", ghwnd_main, (DLGPROC)AboutDlgProc ) < 0 ) {
2317                 char Text[256];
2318                 sprintf( Text,"In About(), GetLastError()=0x%08x",GetLastError() );
2319                 MessageBox( ghwnd_main,Text,"GenSurf",MB_ICONEXCLAMATION );
2320         }
2321 }
2322
2323 #endif