2 GenSurf plugin for GtkRadiant
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #define FIXPOINTS_TAB 3
32 //#define BUFF_SIZE 32768
34 #define ENABLE_WIDGET( name,enable ) \
35 gtk_widget_set_sensitive( 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 )
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;
45 static GtkTooltips *tooltips;
46 static int FirstPassComplete = 0;
48 void About( GtkWidget *parent ){
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 "................................"
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"
94 "David Hyde (rascal@vicksburg.com)\n\n"
96 "Leonardo Zide (leo@lokigames.com)\n\n"
98 "Pablo Zurita (pablo@qeradiant.com)\n"
99 "Hydra (hydra@hydras-world.com)",
100 "About GtkGenSurf", eMB_OK );
103 // =============================================================================
106 static void SetupControls(){
107 switch ( current_tab )
113 if ( Game != QUAKE3 ) {
114 gtk_widget_hide( g_object_get_data( G_OBJECT( g_pWnd , "use_patches" ) ) );
115 ENABLE_WIDGET( "use_patches", FALSE );
119 gtk_widget_show( g_object_get_data( G_OBJECT( g_pWnd , "use_patches" ) ) );
120 ENABLE_WIDGET( "use_patches", TRUE );
123 if ( Game == QUAKE3 && UsePatches != 0 ) {
124 ENABLE_WIDGET( "decimate", FALSE );
126 gtk_label_set_text( GTK_LABEL( g_object_get_data( G_OBJECT( g_pWnd ), "snap_text" ) ), "Snap to grid:" ); // ^Fishman - Snap to grid.
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." );
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." );
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 ) ) );
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 ) );
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 );
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 ) );
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 );
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 );
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:" );
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:" );
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:" );
257 // SetDlgValues fills in text boxes and initializes other input controls
258 static void SetDlgValues( int tab ){
260 char RForm[16] = "%.5g";
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
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 ) );
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" ) ),
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 );
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.
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" ) ),
318 if ( Game == QUAKE3 && UsePatches ) {
319 gtk_widget_set_sensitive( g_object_get_data( G_OBJECT( g_pWnd , "decimate" ) ), FALSE );
323 if ( NH > MAX_ROWS ) {
326 SetDlgValues( current_tab );
331 if ( NV > MAX_ROWS ) {
334 SetDlgValues( current_tab );
342 if ( NH > MAX_ROWS ) {
351 if ( NV > MAX_ROWS ) {
355 gpointer spin = g_object_get_data( G_OBJECT( g_pWnd ), "nh" );
356 GtkAdjustment *adj = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( spin ) );
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 ) );
362 gtk_adjustment_changed( adj );
366 gtk_widget_set_sensitive( g_object_get_data( G_OBJECT( g_pWnd , "decimate" ) ), TRUE );
368 gpointer spin = g_object_get_data( G_OBJECT( g_pWnd ), "nh" );
369 GtkAdjustment *adj = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( spin ) );
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 ) );
375 gtk_adjustment_changed( adj );
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 );
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 );
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" ) ),
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 );
410 if ( Game == QUAKE3 ) {
411 ENABLE_WIDGET( "hint", FALSE );
415 ENABLE_WIDGET( "hint", TRUE );
417 CHECK_WIDGET( "hint", AddHints );
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:");
433 if ( Game == QUAKE3 ) {
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);
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:");
449 /*trix if(Game==HERETIC2)
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);
458 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use pak file");
459 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Pak:");
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);
481 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use wad file");
482 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Wad:");
483 SetDlgItemText(hwndDisplay,DLG_HINT,"Hint brushes");
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);
495 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use sin file");
496 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Sin:");
504 static void ReadDlgValues( int tab ){
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 ) );
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" ) ) ) );
524 if ( Game == QUAKE3 && UsePatches != 0 ) {
531 if ( NH > MAX_ROWS ) {
540 if ( NV > MAX_ROWS ) {
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 );
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++ )
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;
575 CheckDlgButton( ghwnd,DLG_PREVIEW,0 );
576 SendMessage( ghwnd,WM_COMMAND,DLG_PREVIEW,0 );
579 UpdatePreview( TRUE );
583 if ( UsePak[Game] ) {
584 i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETCURSEL, 0, 0 );
586 Texture[Game][0][0] = '\0';
589 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETLBTEXT, i,
590 (LPARAM)(LPCSTR)Texture[Game][0] );
593 i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETCURSEL, 0, 0 );
595 Texture[Game][1][0] = '\0';
598 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETLBTEXT, i,
599 (LPARAM)(LPCSTR)Texture[Game][1] );
602 i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETCURSEL, 0, 0 );
604 Texture[Game][2][0] = '\0';
607 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETLBTEXT, i,
608 (LPARAM)(LPCSTR)Texture[Game][2] );
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] ) );
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. ) {
629 GetDlgItemText( hwndDisplay,DLG_TEXSCALEY,Text,sizeof( Text ) );
630 TexScale[1] = atof( Text );
631 if ( TexScale[1] == 0. ) {
634 GetDlgItemText( hwndDisplay,DLG_ARGHRAD2,Text,sizeof( Text ) );
635 ArghRad2 = atoi( Text );
641 // =============================================================================
642 // main dialog callbacks
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 );
651 UpdatePreview( true );
652 NumVerticesSelected = 0;
655 if ( current_tab == FIXPOINTS_TAB ) {
657 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( g_pWnd ),
658 "main_preview" ) ), FALSE );
661 UpdatePreview( true );
662 NumVerticesSelected = 0;
665 if ( page_num == TEXTURE_TAB ) {
666 WasDetail = UseDetail;
669 ENABLE_WIDGET( "detail", FALSE );
673 ReadDlgValues( current_tab );
674 current_tab = page_num;
675 SetDlgValues( current_tab );
679 static gint main_close( GtkWidget *widget, gpointer data ){
680 gtk_widget_hide( g_pWnd );
681 gtk_widget_hide( g_pWndPreview );
686 static void main_save( GtkWidget *widget, gpointer data ){
687 ReadDlgValues( current_tab );
691 static void main_open( GtkWidget *widget, gpointer data ){
692 OpenSetup( g_pWnd, 0 );
693 for ( int i = 0; i < 5; i++ )
698 static void main_defaults( GtkWidget *widget, gpointer data ){
699 OpenSetup( g_pWnd, 1 );
700 for ( int i = 0; i < 5; i++ )
705 static void main_preview( GtkWidget *widget, gpointer data ){
706 Preview = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) );
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 );
716 static void main_about( GtkWidget *widget, gpointer data ){
720 static void main_go( GtkWidget *widget, gpointer data ){
721 GtkWidget *notebook = g_object_get_data( G_OBJECT( g_pWnd , "notebook" ) );
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 );
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 );
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 );
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 );
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 );
761 /* if (Decimate>0 && GimpHints!=0)
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);
770 gtk_widget_hide( g_pWnd );
771 if ( g_pWndPreview ) {
772 gtk_widget_hide( g_pWndPreview );
776 WriteIniFile( gszIni );
779 // =============================================================================
780 // general tab callbacks
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 );
789 static void general_plane( GtkToggleButton *widget, gpointer data ){
790 if ( gtk_toggle_button_get_active( widget ) ) {
791 Plane = GPOINTER_TO_INT( data );
793 UpdatePreview( TRUE );
797 static void general_wave( GtkToggleButton *widget, gpointer data ){
798 if ( gtk_toggle_button_get_active( widget ) ) {
799 WaveType = GPOINTER_TO_INT( data );
801 UpdatePreview( TRUE );
805 static void general_random( GtkAdjustment *adj, gpointer data ){
806 int nPos = (int)adj->value;
808 if ( RandomSeed != nPos ) {
810 UpdatePreview( true );
814 // =============================================================================
815 // extents tab callbacks
817 static void extents_linearborder( GtkToggleButton *check, gpointer data ){
818 FixBorders = gtk_toggle_button_get_active( check );
819 UpdatePreview( true );
822 static void extents_use_patches( GtkToggleButton *check, gpointer data ){
823 if ( Game != QUAKE3 ) {
827 UsePatches = gtk_toggle_button_get_active( check );
828 SetDlgValues( current_tab );
830 UpdatePreview( true );
833 static void extents_nhnv_spin( GtkAdjustment *adj, int *data ){
834 int nPos = (int)adj->value;
836 if ( *data != nPos ) {
837 if ( Game == QUAKE3 && UsePatches && ( nPos % 2 ) ) {
838 if ( *data < nPos ) {
844 gtk_adjustment_set_value( adj, *data );
849 UpdatePreview( true );
853 static void extents_decimate( GtkAdjustment *adj, gpointer data ){
854 int nPos = (int)adj->value;
857 UpdatePreview( true );
860 // Hydra : snap to grid begin
861 /*static void extents_snaptogrid (GtkAdjustment *adj, gpointer data)
863 int nPos = (int)adj->value;
866 UpdatePreview (true);
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;
873 UpdatePreview( true );
876 // =============================================================================
877 // bitmap tab callbacks
879 static gint bitmap_file_entryfocusout( GtkWidget* widget, GdkEventFocus* event, gpointer data ){
880 char filename[NAME_MAX];
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 ) ) {
888 ENABLE_WIDGET( "go", ( gbmp.colors != NULL ? TRUE : FALSE ) );
893 static void bitmap_browse( GtkWidget *widget, gpointer data ){
894 const char *filename;
897 filename = g_FuncTable.m_pfnFileDialog( g_pWnd, TRUE, "Bitmap File", gbmp.defpath );
899 if ( filename != NULL ) {
900 strcpy( gbmp.name, filename );
902 ptr = strrchr( filename, G_DIR_SEPARATOR );
905 strcpy( gbmp.defpath, filename );
909 ENABLE_WIDGET( "go", ( gbmp.colors != NULL ? TRUE : FALSE ) );
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 ) ) {
917 ENABLE_WIDGET( "go", ( gbmp.colors != NULL ? TRUE : FALSE ) );
920 ENABLE_WIDGET( "go", FALSE );
924 // =============================================================================
925 // fix points tab callbacks
927 static gint fix_value_entryfocusout( GtkWidget* widget, GdkEventFocus *event, gpointer data ){
928 int i = atoi( gtk_entry_get_text( GTK_ENTRY( widget ) ) ), k;
931 if ( i < -65536 || i > 65536 ) {
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( widget.window(), widget );
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;
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 );
950 static void fix_value_changed( GtkAdjustment *adj, gpointer data ){
951 int k, i = (int)adj->value;
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 );
960 static gint fix_range_entryfocusout( GtkWidget *widget, GdkEventFocus *event, gpointer data ){
961 int i = atoi( gtk_entry_get_text( GTK_ENTRY( widget ) ) ), k;
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 );
971 static gint fix_rate_entryfocusout( GtkWidget *widget, GdkEventFocus *event, gpointer data ){
972 double r = atof( gtk_entry_get_text( GTK_ENTRY( widget ) ) );
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 );
983 static void fix_free( GtkWidget *widget, gpointer data ){
986 for ( k = 0; k < NumVerticesSelected; k++ )
987 xyz[Vertex[k].i][Vertex[k].j].fixed = 0;
988 NumVerticesSelected = 0;
990 UpdatePreview( true );
993 static void fix_freeall( GtkWidget *widget, gpointer data ){
996 for ( i = 0; i <= NH; i++ )
998 for ( j = 0; j <= NV; j++ )
1001 fix_free( NULL, data ); // keep these together
1004 void vertex_selected(){
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];
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];
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];
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 );
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 );
1036 for ( k = 0; k < NumVerticesSelected; k++ )
1037 xyz[Vertex[k].i][Vertex[k].j].fixed = 1;
1039 UpdatePreview( true );
1042 // =============================================================================
1043 // texture tab callbacks
1045 static void texture_detail( GtkToggleButton *check, gpointer data ){
1046 UseDetail = gtk_toggle_button_get_active( check );
1047 WasDetail = UseDetail;
1050 static void texture_hint( GtkToggleButton *check, gpointer data ){
1051 AddHints = gtk_toggle_button_get_active( check );
1052 if ( AddHints == 1 ) {
1054 ENABLE_WIDGET( "detail", FALSE );
1058 UseDetail = WasDetail;
1059 ENABLE_WIDGET( "detail", FALSE );
1061 CHECK_WIDGET( "detail", UseDetail );
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 );
1069 static void texture_set( int index, const char* name ){
1070 strcpy( Texture[Game][index], name );
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 ) ) );
1078 // =============================================================================
1081 static void UpdateVariable( GtkEntry *entry, GdkEventFocus *event, double *data ){
1082 double x = atof( gtk_entry_get_text( entry ) );
1086 UpdatePreview( true );
1090 static gint doublevariable_entryfocusout( GtkWidget* widget, GdkEventFocus* event, gpointer data ){
1091 UpdateVariable( GTK_ENTRY( widget ), event, reinterpret_cast<double*>( data ) );
1095 // =============================================================================
1098 void create_tooltips(){
1099 tooltips = gtk_tooltips_new();
1102 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1103 g_object_get_data( G_OBJECT( g_pWnd , "go" ) ),
1104 "Accept all input and generate a surface in Q3Radiant",
1106 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1107 g_object_get_data( G_OBJECT( g_pWnd , "open" ) ),
1108 "Open a previously saved GenSurf settings file.",
1110 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1111 g_object_get_data( G_OBJECT( g_pWnd , "save" ) ),
1112 "Save all settings to a file.",
1114 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1115 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.",
1122 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1123 g_object_get_data( G_OBJECT( g_pWnd , "main_preview" ) ),
1124 "View a wire-frame representation of the surface",
1127 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1128 g_object_get_data( G_OBJECT( g_pWnd , "main_antialiasing" ) ),
1129 "The lines in the preview window are antialiased for better quality",
1133 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1135 "Builds a surface with alternating hills and valleys. Uses the general form Z=cos(X) "
1138 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1140 "Builds a surface with ridges parallel to the vertical axis.",
1142 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1144 "Builds a surface with ridges parallel to the horizontal axis.",
1146 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
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 "
1153 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
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.",
1159 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1160 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",
1166 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1167 g_object_get_data( G_OBJECT( g_pWnd , "amplitude" ) ),
1168 "Enter the height of hills/ridges.",
1170 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1171 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.",
1175 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1176 g_object_get_data( G_OBJECT( g_pWnd , "random" ) ),
1177 "Seed value for the pseudo-random number generator.",
1180 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1181 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.",
1187 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1188 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.",
1194 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1195 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.",
1201 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1202 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.",
1208 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1209 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 "
1214 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1215 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 "
1220 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1221 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.",
1228 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1229 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 "
1236 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1237 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.",
1241 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1242 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.",
1246 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1247 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.",
1251 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1252 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.",
1256 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1257 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.",
1262 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1263 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.",
1267 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1268 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.",
1271 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1272 g_object_get_data( G_OBJECT( g_pWnd , "bmp_reload" ) ),
1273 "Reload the selected bitmap file after making changes in an external image editor.",
1275 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1276 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.",
1280 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1281 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.",
1286 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1287 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.",
1293 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1294 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.",
1300 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1301 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\".",
1308 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1309 g_object_get_data( G_OBJECT( g_pWnd , "fix_free" ) ),
1310 "Click this to free (unlock the value of) the currently selected vertex.",
1312 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1313 g_object_get_data( G_OBJECT( g_pWnd , "fix_freeall" ) ),
1314 "Click this to free (unlock the values of) all vertices.",
1317 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1318 g_object_get_data( G_OBJECT( g_pWnd , "texture1" ) ),
1319 "Enter the name of the texture or shader used for the surface faces.",
1321 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1322 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\"",
1326 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1327 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\".",
1333 gtk_tooltips_set_tip( GTK_TOOLTIPS( tooltips ),
1334 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.",
1343 // =============================================================================
1344 // create main dialog
1346 GtkWidget* create_main_dialog(){
1347 GtkWidget *hbox2, *button, *notebook, *table2;
1348 GtkWidget *check, *spin, *radio, *label, *entry, *scale;
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" };
1358 auto dlg = g_pWnd = ui::Window( ui::window_type::TOP );
1359 gtk_window_set_title( dlg, gszCaption );
1360 dlg.connect( "delete_event", G_CALLBACK( main_close ), NULL );
1361 // dlg.connect( "destroy", G_CALLBACK (gtk_widget_destroy), NULL);
1362 gtk_window_set_transient_for( dlg, g_pRadiantWnd );
1364 auto hbox = ui::HBox( FALSE, 5 );
1367 gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
1369 notebook = gtk_notebook_new();
1371 hbox.pack_start( notebook, TRUE, TRUE, 0 );
1372 notebook.connect( "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 );
1377 table = ui::Table( 2, 2, FALSE );
1379 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1380 gtk_table_set_row_spacings(table, 5);
1381 gtk_table_set_col_spacings(table, 5);
1383 label = ui::Label( "General" );
1385 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), table, label );
1387 auto frame = ui::Frame( "Game" );
1389 table.attach(frame, {0, 1, 0, 1});
1391 auto vbox = ui::VBox( TRUE, 5 );
1394 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1396 for ( i = 0, group = NULL; i < NUMGAMES; i++ )
1398 radio = gtk_radio_button_new_with_label( group, games[i] );
1400 vbox.pack_start( radio, TRUE, TRUE, 0 );
1401 group = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radio ) );
1402 game_radios[i] = radio;
1403 radio.connect( "toggled", G_CALLBACK( general_game ), GINT_TO_POINTER( i ) );
1406 frame = ui::Frame( "Waveform" );
1408 table.attach(frame, {1, 2, 0, 1});
1410 vbox = ui::VBox( TRUE, 5 );
1413 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1415 for ( i = 0, group = NULL; i < 5; i++ )
1417 radio = gtk_radio_button_new_with_label( group, waveforms[i] );
1419 vbox.pack_start( radio, TRUE, TRUE, 0 );
1420 group = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radio ) );
1421 wave_radios[i] = radio;
1422 radio.connect( "toggled", G_CALLBACK( general_wave ), GINT_TO_POINTER( i ) );
1425 frame = ui::Frame( "Orientation" );
1427 table.attach(frame, {0, 1, 1, 2});
1429 vbox = ui::VBox( TRUE, 5 );
1432 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1434 for ( i = 0, group = NULL; i < 6; i++ )
1436 radio = gtk_radio_button_new_with_label( group, orientations[i] );
1438 vbox.pack_start( radio, TRUE, TRUE, 0 );
1439 group = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radio ) );
1440 plane_radios[i] = radio;
1441 radio.connect( "toggled", G_CALLBACK( general_plane ), GINT_TO_POINTER( i ) );
1444 table2 = ui::Table( 4, 2, FALSE );
1446 gtk_table_set_row_spacings(table2, 5);
1447 gtk_table_set_col_spacings(table2, 5);
1448 table.attach(table2, {1, 2, 1, 2});
1450 label = ui::Label( "Wavelength:" );
1452 table2.attach(label, {0, 1, 0, 1});
1453 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1454 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1456 label = ui::Label( "Max. amplitude:" );
1458 table2.attach(label, {0, 1, 1, 2});
1459 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1460 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1462 label = ui::Label( "Roughness:" );
1464 table2.attach(label, {0, 1, 2, 3});
1465 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1466 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1468 label = ui::Label( "Random seed:" );
1470 table2.attach(label, {0, 1, 3, 4});
1471 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1472 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1474 entry = ui::Entry();
1476 table2.attach(entry, {1, 2, 0, 1});
1477 entry.dimensions( 50, -1 );
1478 g_object_set_data( G_OBJECT( dlg ), "wavelength", entry );
1479 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &WaveLength );
1481 entry = ui::Entry();
1483 table2.attach(entry, {1, 2, 1, 2});
1484 entry.dimensions( 50, -1 );
1485 g_object_set_data( G_OBJECT( dlg ), "amplitude", entry );
1486 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Amplitude );
1488 entry = ui::Entry();
1490 table2.attach(entry, {1, 2, 2, 3});
1491 entry.dimensions( 50, -1 );
1492 g_object_set_data( G_OBJECT( dlg ), "roughness", entry );
1493 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Roughness );
1495 adj = ui::Adjustment( 1, 1, 32767, 1, 10, 0 );
1496 adj.connect( "value_changed", G_CALLBACK( general_random ), NULL );
1497 spin = ui::SpinButton( adj, 1, 0 );
1499 table2.attach(spin, {1, 2, 3, 4});
1500 spin.dimensions( 60, -1 );
1501 g_object_set_data( G_OBJECT( dlg ), "random", spin );
1503 vbox = ui::VBox( FALSE, 5 );
1505 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1507 label = ui::Label( "Extents" );
1509 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
1511 hbox2 = ui::HBox( FALSE, 5 );
1513 vbox.pack_start( hbox2, FALSE, TRUE, 0 );
1515 frame = ui::Frame( "Extents" );
1517 hbox2.pack_start( frame, TRUE, TRUE, 0 );
1519 auto table = ui::Table( 3, 4, FALSE );
1521 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1523 gtk_table_set_row_spacings(table, 5);
1524 gtk_table_set_col_spacings(table, 5);
1526 label = ui::Label( "X:" );
1528 table.attach( label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1529 g_object_set_data( G_OBJECT( dlg ), "hmin_text", label );
1531 label = ui::Label( "X:" );
1533 table.attach(label, {2, 3, 1, 2}, {GTK_FILL, GTK_FILL});
1534 g_object_set_data( G_OBJECT( dlg ), "hmax_text", label );
1536 label = ui::Label( "Y:" );
1538 table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1539 g_object_set_data( G_OBJECT( dlg ), "vmin_text", label );
1541 label = ui::Label( "Y:" );
1543 table.attach(label, {2, 3, 2, 3}, {GTK_FILL, GTK_FILL});
1544 g_object_set_data( G_OBJECT( dlg ), "vmax_text", label );
1546 label = ui::Label( "Lower-left" );
1548 table.attach(label, {1, 2, 0, 1}, {GTK_FILL, GTK_FILL});
1550 label = ui::Label( "Upper-right" );
1552 table.attach(label, {3, 4, 0, 1},, {GTK_FILL, GTK_FILL});
1554 entry = ui::Entry();
1556 table.attach(entry, {1, 2, 1, 2});
1557 entry.dimensions( 50, -1 );
1558 g_object_set_data( G_OBJECT( dlg ), "hmin", entry );
1559 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Hll );
1561 entry = ui::Entry();
1563 table.attach(entry, {3, 4, 1, 2});
1564 entry.dimensions( 50, -1 );
1565 g_object_set_data( G_OBJECT( dlg ), "hmax", entry );
1566 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Hur );
1568 entry = ui::Entry();
1570 table.attach(entry, {1, 2, 2, 3});
1571 entry.dimensions( 50, -1 );
1572 g_object_set_data( G_OBJECT( dlg ), "vmin", entry );
1573 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Vll );
1575 entry = ui::Entry();
1577 table.attach(entry, {3, 4, 2, 3});
1578 entry.dimensions( 50, -1 );
1579 g_object_set_data( G_OBJECT( dlg ), "vmax", entry );
1580 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Vur );
1582 frame = ui::Frame( "Divisions" );
1584 hbox2.pack_start( frame, TRUE, TRUE, 0 );
1586 table = ui::Table( 2, 2, FALSE );
1588 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1590 gtk_table_set_row_spacings(table, 5);
1591 gtk_table_set_col_spacings(table, 5);
1593 label = ui::Label( "X:" );
1595 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_EXPAND | GTK_FILL});
1596 g_object_set_data( G_OBJECT( dlg ), "nh_text", label );
1598 label = ui::Label( "Y:" );
1600 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_EXPAND | GTK_FILL});
1601 g_object_set_data( G_OBJECT( dlg ), "nv_text", label );
1603 adj = ui::Adjustment( 8, 1, MAX_ROWS, 1, 10, 0 );
1604 adj.connect( "value_changed", G_CALLBACK( extents_nhnv_spin ), &NH );
1605 spin = ui::SpinButton( adj, 1, 0 );
1607 table.attach(spin, {1, 2, 0, 1});
1608 spin.dimensions( 60, -1 );
1609 g_object_set_data( G_OBJECT( dlg ), "nh", spin );
1611 adj = ui::Adjustment( 8, 1, MAX_ROWS, 1, 10, 0 );
1612 adj.connect( "value_changed", G_CALLBACK( extents_nhnv_spin ), &NV );
1613 spin = ui::SpinButton( adj, 1, 0 );
1615 table.attach(spin, {1, 2, 1, 2});
1616 spin.dimensions( 60, -1 );
1617 g_object_set_data( G_OBJECT( dlg ), "nv", spin );
1619 check = ui::CheckButton( "Use Bezier patches" );
1621 vbox.pack_start( check, FALSE, TRUE, 0 );
1622 g_object_set_data( G_OBJECT( dlg ), "use_patches", check );
1623 check.connect( "toggled", G_CALLBACK( extents_use_patches ), NULL );
1625 // ^Fishman - Snap to grid, replaced scroll bar with a texbox.
1626 label = ui::Label( "Snap to grid:" );
1628 vbox.pack_start( label, FALSE, TRUE, 0 );
1629 gtk_object_set_data( GTK_OBJECT( dlg ), "snap_text", label );
1631 adj = ui::Adjustment( 8, 0, 256, 1, 10, 0 );
1632 adj.connect( "value_changed", G_CALLBACK( extents_snaptogrid_spin ), &SP );
1633 spin = ui::SpinButton( adj, 1, 0 );
1635 vbox.pack_start( spin, FALSE, TRUE, 0 );
1636 spin.dimensions( 60, -1 );
1637 g_object_set_data( G_OBJECT( dlg ), "sp", spin );
1638 // ^Fishman - End of Snap to grid code.
1640 hbox2 = ui::HBox( FALSE, 5 );
1642 vbox.pack_start( hbox2, FALSE, TRUE, 10 );
1644 label = ui::Label( "Decimate:" );
1646 hbox2.pack_start( label, FALSE, TRUE, 0 );
1648 adj = ui::Adjustment( 0, 0, 110, 1, 10, 0 );
1649 adj.connect( "value_changed", G_CALLBACK( extents_decimate ), NULL );
1650 g_object_set_data( G_OBJECT( dlg ), "decimate_adj", adj );
1651 scale = ui::HScale( adj );
1653 hbox2.pack_start( scale, TRUE, TRUE, 0 );
1654 gtk_scale_set_value_pos( GTK_SCALE( scale ), GTK_POS_RIGHT );
1655 gtk_scale_set_digits( GTK_SCALE( scale ), 0 );
1656 g_object_set_data( G_OBJECT( dlg ), "decimate", scale );
1658 frame = ui::Frame( "Corner values" );
1660 vbox.pack_start( frame, FALSE, TRUE, 0 );
1662 table = ui::Table( 3, 4, FALSE );
1664 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1666 gtk_table_set_row_spacings(table, 5);
1667 gtk_table_set_col_spacings(table, 5);
1669 label = ui::Label( "Upper-left:" );
1671 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1673 label = ui::Label( "Lower-left:" );
1675 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1677 label = ui::Label( "Upper-right:" );
1679 table.attach(label, {2, 3, 0, 1}, {GTK_FILL, GTK_FILL});
1681 label = ui::Label( "Lower-right:" );
1683 table.attach(label, {2, 3, 1, 2}, {GTK_FILL, GTK_FILL});
1685 entry = ui::Entry();
1687 table.attach(entry, {1, 2, 0, 1});
1688 entry.dimensions( 50, -1 );
1689 g_object_set_data( G_OBJECT( dlg ), "z01", entry );
1690 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z01 );
1692 entry = ui::Entry();
1694 table.attach(entry, {1, 2, 1, 2});
1695 entry.dimensions( 50, -1 );
1696 g_object_set_data( G_OBJECT( dlg ), "z00", entry );
1697 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z00 );
1699 entry = ui::Entry();
1701 table.attach(entry, {3, 4, 0, 1});
1702 entry.dimensions( 50, -1 );
1703 g_object_set_data( G_OBJECT( dlg ), "z11", entry );
1704 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z11 );
1706 entry = ui::Entry();
1708 table.attach(entry, {3, 4, 1, 2});
1709 entry.dimensions( 50, -1 );
1710 g_object_set_data( G_OBJECT( dlg ), "z10", entry );
1711 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &Z10 );
1713 check = ui::CheckButton( "Linear borders" );
1715 table.attach(check, {0, 4, 2, 3});
1716 g_object_set_data( G_OBJECT( dlg ), "linearborder", check );
1717 check.connect( "toggled", G_CALLBACK( extents_linearborder ), NULL );
1719 vbox = ui::VBox( FALSE, 10 );
1721 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1723 label = ui::Label( "Bitmap" );
1725 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
1727 label = ui::Label( "" );
1729 vbox.pack_start( label, FALSE, TRUE, 0 );
1730 g_object_set_data( G_OBJECT( dlg ), "bmp_note", label );
1732 table = ui::Table( 2, 2, FALSE );
1734 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1735 vbox.pack_start( table, FALSE, TRUE, 0 );
1736 gtk_table_set_row_spacings(table, 5);
1737 gtk_table_set_col_spacings(table, 5);
1739 label = ui::Label( "Filename:" );
1741 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1742 g_object_set_data( G_OBJECT( dlg ), "bmp_text1", label );
1744 entry = ui::Entry();
1746 table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1747 g_object_set_data( G_OBJECT( dlg ), "bmp_file", entry );
1748 entry.connect( "focus_out_event", G_CALLBACK( bitmap_file_entryfocusout ), NULL );
1750 hbox2 = ui::HBox( TRUE, 5 );
1752 table.attach(hbox2, {1, 2, 1, 2}, {0, GTK_EXPAND | GTK_FILL});
1754 button = ui::Button( "Browse..." );
1756 hbox2.pack_start( button, FALSE, FALSE, 0 );
1757 button.dimensions( 60, -1 );
1758 g_object_set_data( G_OBJECT( dlg ), "bmp_file_browse", button );
1759 button.connect( "clicked", G_CALLBACK( bitmap_browse ), NULL );
1761 button = ui::Button( "Reload" );
1763 hbox2.pack_start( button, FALSE, FALSE, 0 );
1764 button.dimensions( 60, -1 );
1765 g_object_set_data( G_OBJECT( dlg ), "bmp_reload", button );
1766 button.connect( "clicked", G_CALLBACK( bitmap_reload ), NULL );
1768 table = ui::Table( 2, 2, TRUE );
1770 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1771 vbox.pack_start( table, FALSE, TRUE, 0 );
1772 gtk_table_set_row_spacings(table, 5);
1773 gtk_table_set_col_spacings(table, 5);
1775 label = ui::Label( "Map color 0 to:" );
1777 table.attach(label, {0, 1, 0, 1}, {GTK_FILL | GTK_EXPAND, GTK_FILL});
1778 g_object_set_data( G_OBJECT( dlg ), "bmp_text2", label );
1779 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1780 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1782 label = ui::Label( "Map color 255 to:" );
1784 table.attach(label, {0, 1, 1, 2}, {GTK_FILL | GTK_EXPAND, GTK_FILL});
1785 g_object_set_data( G_OBJECT( dlg ), "bmp_text3", label );
1786 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1787 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT );
1789 hbox2 = ui::HBox( FALSE, 5 );
1791 table.attach(hbox2, {1, 2, 0, 1});
1793 entry = ui::Entry();
1795 hbox2.pack_start( entry, FALSE, FALSE, 0 );
1796 entry.dimensions( 50, -1 );
1797 g_object_set_data( G_OBJECT( dlg ), "bmp_black", entry );
1798 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &gbmp.black_value );
1800 hbox2 = ui::HBox( FALSE, 5 );
1802 table.attach(hbox2, {1, 2, 1, 2});
1804 entry = ui::Entry();
1806 hbox2.pack_start( entry, FALSE, FALSE, 0 );
1807 entry.dimensions( 50, -1 );
1808 g_object_set_data( G_OBJECT( dlg ), "bmp_white", entry );
1809 entry.connect( "focus_out_event", G_CALLBACK( doublevariable_entryfocusout ), &gbmp.white_value );
1811 vbox = ui::VBox( FALSE, 10 );
1813 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1815 label = ui::Label( "Fix Points" );
1817 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
1819 label = ui::Label( "Click on a vertex in the lower half of the preview window,\n"
1820 "then use the arrow keys or text box to assign a value.\n"
1821 "Use Ctrl+Click to select multiple vertices/toggle a\n"
1822 "selection. Use Shift+Click to select a range of vertices.\n\n"
1823 "Click \"Free\" to unlock a vertex. Vertices within \"Range\n"
1824 "affected\" will be influenced by this vertex." );
1826 vbox.pack_start( label, FALSE, TRUE, 0 );
1828 table = ui::Table( 3, 3, FALSE );
1830 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1831 vbox.pack_start( table, FALSE, TRUE, 0 );
1832 gtk_table_set_row_spacings(table, 5);
1833 gtk_table_set_col_spacings(table, 5);
1835 label = ui::Label( "Value:" );
1837 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1838 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1839 g_object_set_data( G_OBJECT( dlg ), "fix_value_text", label );
1841 label = ui::Label( "Range affected:" );
1843 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1844 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1845 g_object_set_data( G_OBJECT( dlg ), "fix_range_text", label );
1847 label = ui::Label( "Rate of change:" );
1849 table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1850 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1851 g_object_set_data( G_OBJECT( dlg ), "fix_rate_text", label );
1853 adj = ui::Adjustment( 0, -65536, 65536, 1, 16, 0 );
1854 adj.connect( "value_changed", G_CALLBACK( fix_value_changed ), NULL );
1855 spin = ui::SpinButton( adj, 1, 0 );
1857 table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND, GTK_EXPAND});
1858 spin.dimensions( 60, -1 );
1859 g_object_set_data( G_OBJECT( dlg ), "fix_value", spin );
1860 spin.connect( "focus_out_event", G_CALLBACK( fix_value_entryfocusout ), NULL );
1862 entry = ui::Entry();
1864 table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND, GTK_FILL});
1865 entry.dimensions( 60, -1 );
1866 g_object_set_data( G_OBJECT( dlg ), "fix_range", entry );
1867 entry.connect( "focus_out_event", G_CALLBACK( fix_range_entryfocusout ), NULL );
1869 entry = ui::Entry();
1871 table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND, GTK_FILL});
1872 entry.dimensions( 60, -1 );
1873 g_object_set_data( G_OBJECT( dlg ), "fix_rate", entry );
1874 entry.connect( "focus_out_event", G_CALLBACK( fix_rate_entryfocusout ), NULL );
1876 button = ui::Button( "Free" );
1878 table.attach(button, {2, 3, 0, 1}, {GTK_EXPAND, GTK_FILL});
1879 button.dimensions( 60, -1 );
1880 g_object_set_data( G_OBJECT( dlg ), "fix_free", button );
1881 button.connect( "clicked", G_CALLBACK( fix_free ), NULL );
1883 button = ui::Button( "Free All" );
1885 table.attach(button, {2, 3, 1, 2}, {GTK_EXPAND, GTK_FILL});
1886 button.dimensions( 60, -1 );
1887 g_object_set_data( G_OBJECT( dlg ), "fix_freeall", button );
1888 button.connect( "clicked", G_CALLBACK( fix_freeall ), NULL );
1890 vbox = ui::VBox( FALSE, 10 );
1892 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1894 label = ui::Label( "Texture" );
1896 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), vbox, label );
1898 // ^Fishman - Modified to add more labels and textboxes.
1899 table = ui::Table( 5, 2, FALSE );
1901 vbox.pack_start( table, FALSE, TRUE, 0 );
1902 gtk_table_set_row_spacings(table, 5);
1903 gtk_table_set_col_spacings(table, 5);
1905 label = ui::Label( "Surface:" );
1907 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1908 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1910 label = ui::Label( "Other:" );
1912 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1913 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1915 label = ui::Label( "Steep:" );
1917 table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1918 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
1920 entry = ui::Entry();
1922 table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1923 entry.dimensions( 60, -1 );
1924 g_object_set_data( G_OBJECT( dlg ), "texture1", entry );
1925 entry.connect( "focus_out_event", G_CALLBACK( texture_entryfocusout ), GINT_TO_POINTER( 0 ) );
1927 entry = ui::Entry();
1929 table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1930 entry.dimensions( 60, -1 );
1931 g_object_set_data( G_OBJECT( dlg ), "texture2", entry );
1932 entry.connect( "focus_out_event", G_CALLBACK( texture_entryfocusout ), GINT_TO_POINTER( 1 ) );
1934 entry = ui::Entry();
1936 table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1937 entry.dimensions( 60, -1 );
1938 g_object_set_data( G_OBJECT( dlg ), "texture3", entry );
1940 hbox2 = ui::HBox( FALSE, 5 );
1942 vbox.pack_start( hbox2, FALSE, TRUE, 0 );
1944 label = ui::Label( "\"Steep\" angle:" );
1946 hbox2.pack_start( label, FALSE, TRUE, 0 );
1948 adj = ui::Adjustment( 60, 0, 90, 1, 10, 0 );
1949 spin = ui::SpinButton( adj, 1, 0 );
1951 hbox2.pack_start( spin, FALSE, TRUE, 0 );
1952 g_object_set_data( G_OBJECT( dlg ), "tex_slant", spin );
1954 table = ui::Table( 2, 4, TRUE );
1956 vbox.pack_start( table, FALSE, TRUE, 0 );
1957 gtk_table_set_row_spacings(table, 5);
1958 gtk_table_set_col_spacings(table, 5);
1960 label = ui::Label( "Offset <h,v>" );
1962 table.attach(label, {0, 2, 0, 1}, {GTK_FILL, GTK_FILL});
1964 label = ui::Label( "Scale <h,v>" );
1966 table.attach(label, {2, 4, 0, 1}, {GTK_FILL, GTK_FILL});
1968 entry = ui::Entry();
1970 table.attach(entry, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1971 entry.dimensions( 60, -1 );
1972 g_object_set_data( G_OBJECT( dlg ), "texoffsetx", entry );
1974 entry = ui::Entry();
1976 table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1977 entry.dimensions( 60, -1 );
1978 g_object_set_data( G_OBJECT( dlg ), "texoffsety", entry );
1980 entry = ui::Entry();
1982 table.attach(entry, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1983 entry.dimensions( 60, -1 );
1984 g_object_set_data( G_OBJECT( dlg ), "texscalex", entry );
1986 entry = ui::Entry();
1988 table.attach(entry, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1989 entry.dimensions( 60, -1 );
1990 g_object_set_data( G_OBJECT( dlg ), "texscaley", entry );
1994 check = ui::CheckButton( "Use detail brushes" );
1996 vbox.pack_start( check, FALSE, TRUE, 0 );
1997 g_object_set_data( G_OBJECT( dlg ), "detail", check );
1998 check.connect( "toggled", G_CALLBACK( texture_detail ), NULL );
2000 check = ui::CheckButton( "Detail hint brushes" );
2002 vbox.pack_start( check, FALSE, TRUE, 0 );
2003 g_object_set_data( G_OBJECT( dlg ), "hint", check );
2004 check.connect( "toggled", G_CALLBACK( texture_hint ), NULL );
2006 // ^Fishman - Add terrain key to func_group.
2007 check = ui::CheckButton( "Add terrain key" );
2009 vbox.pack_start( check, FALSE, TRUE, 0 );
2010 g_object_set_data( G_OBJECT( dlg ), "terrain_ent", check );
2011 check.connect( "toggled", G_CALLBACK( texture_terrainent ), NULL );
2013 vbox = ui::VBox( FALSE, 5 );
2015 hbox.pack_start( vbox, FALSE, TRUE, 0 );
2017 button = ui::Button( "OK" );
2019 vbox.pack_start( button, FALSE, TRUE, 0 );
2020 button.dimensions( 60, -1 );
2021 g_object_set_data( G_OBJECT( dlg ), "go", button );
2022 button.connect( "clicked", G_CALLBACK( main_go ), NULL );
2024 label = ui::Label( "Settings:" );
2026 vbox.pack_start( label, FALSE, TRUE, 0 );
2028 button = ui::Button( "Open..." );
2030 vbox.pack_start( button, FALSE, TRUE, 0 );
2031 g_object_set_data( G_OBJECT( dlg ), "open", button );
2032 button.connect( "clicked", G_CALLBACK( main_open ), NULL );
2034 button = ui::Button( "Save as..." );
2036 vbox.pack_start( button, FALSE, TRUE, 0 );
2037 g_object_set_data( G_OBJECT( dlg ), "save", button );
2038 button.connect( "clicked", G_CALLBACK( main_save ), NULL );
2040 button = ui::Button( "Defaults" );
2042 vbox.pack_start( button, FALSE, TRUE, 0 );
2043 g_object_set_data( G_OBJECT( dlg ), "defaults", button );
2044 button.connect( "clicked", G_CALLBACK( main_defaults ), NULL );
2046 button = ui::Button( "About..." );
2048 vbox.pack_start( button, FALSE, TRUE, 0 );
2049 button.connect( "clicked", G_CALLBACK( main_about ), NULL );
2051 check = ui::CheckButton( "Preview" );
2053 vbox.pack_start( check, FALSE, TRUE, 0 );
2054 check.connect( "toggled", G_CALLBACK( main_preview ), NULL );
2055 g_object_set_data( G_OBJECT( dlg ), "main_preview", check );
2057 // ^Fishman - Antializing for the preview window.
2058 check = ui::CheckButton( "Antialised lines" );
2060 vbox.pack_start( check, FALSE, TRUE, 0 );
2061 g_object_set_data( G_OBJECT( dlg ), "main_antialiasing", check );
2062 check.connect( "toggled", G_CALLBACK( main_antialiasing ), NULL );
2064 for ( i = 0; i < 5; i++ )
2071 FirstPassComplete = 1;
2079 HWND hwndDisplay = (HWND)NULL;
2080 HWND ghwndTab = (HWND)NULL;
2085 char GenSurfURL[40] = {"http://tarot.telefragged.com/gensurf"};
2086 char GenSurfBoard[40] = {"http://tarot.telefragged.com/board"};
2089 * AboutDlgProc - processes messages for the about dialog.
2092 qboolean CALLBACK AboutDlgProc( HWND hwnd, unsigned msg, UINT wparam, LONG lparam ){
2094 DRAWITEMSTRUCT *dis;
2101 lparam = lparam; /* turn off warning */
2105 strcpy( szText,"About " );
2106 strcat( szText,gszCaption );
2107 SetWindowText( hwnd,gszCaption );
2108 SetDlgItemText( hwnd,DLG_ABOUT_APP,szText );
2109 /* Application icon: */
2110 SendDlgItemMessage( hwnd, DLG_ABOUT_ICON,
2111 STM_SETICON, (WPARAM)(HICON)LoadIcon( ghInst,"GENSURF" ),
2114 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_URL );
2115 hdc = GetDC( hwndURL );
2116 GetTextExtentPoint( hdc,GenSurfURL,strlen( GenSurfURL ),&size );
2117 ReleaseDC( hwndURL,hdc );
2118 GetWindowRect( hwndURL,&rc );
2119 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2120 SWP_NOMOVE | SWP_NOZORDER );
2122 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_BOARD );
2123 hdc = GetDC( hwndURL );
2124 GetTextExtentPoint( hdc,GenSurfBoard,strlen( GenSurfBoard ),&size );
2125 ReleaseDC( hwndURL,hdc );
2126 GetWindowRect( hwndURL,&rc );
2127 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2128 SWP_NOMOVE | SWP_NOZORDER );
2133 switch ( LOWORD( wparam ) )
2138 case DLG_ABOUT_BOARD:
2139 HTTP( GenSurfBoard );
2142 EndDialog( hwnd,1 );
2148 if ( wparam == DLG_ABOUT_URL ) {
2149 dis = (LPDRAWITEMSTRUCT)lparam;
2150 SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2151 TextOut( dis->hDC,0,0,GenSurfURL,strlen( GenSurfURL ) );
2152 GetWindowRect( dis->hwndItem,&rc );
2153 GetTextExtentPoint( dis->hDC,GenSurfURL,strlen( GenSurfURL ),&size );
2154 hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2155 SelectObject( dis->hDC,hpen );
2156 MoveToEx( dis->hDC,0,size.cy,NULL );
2157 LineTo( dis->hDC,size.cx,size.cy );
2158 SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2159 DeleteObject( hpen );
2161 else if ( wparam == DLG_ABOUT_BOARD ) {
2162 dis = (LPDRAWITEMSTRUCT)lparam;
2163 SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2164 TextOut( dis->hDC,0,0,GenSurfBoard,strlen( GenSurfBoard ) );
2165 GetWindowRect( dis->hwndItem,&rc );
2166 GetTextExtentPoint( dis->hDC,GenSurfBoard,strlen( GenSurfBoard ),&size );
2167 hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2168 SelectObject( dis->hDC,hpen );
2169 MoveToEx( dis->hDC,0,size.cy,NULL );
2170 LineTo( dis->hDC,size.cx,size.cy );
2171 SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2172 DeleteObject( hpen );
2177 EndDialog( hwnd,1 );
2185 } /* AboutDlgProc */
2188 if ( DialogBox( ghInst,"About", ghwnd_main, (DLGPROC)AboutDlgProc ) < 0 ) {
2190 sprintf( Text,"In About(), GetLastError()=0x%08x",GetLastError() );
2191 MessageBox( ghwnd_main,Text,"GenSurf",eMB_ICONWARNING );