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