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)
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 "................................"
91 // leo: I'm too lazy to create a nice about box
92 // ^Fishman - I am lazy too :P.
93 g_FuncTable.m_pfnMessageBox(parent, "GtkGenSurf 1.05\n\n"
95 "David Hyde (rascal@vicksburg.com)\n\n"
97 "Leonardo Zide (leo@lokigames.com)\n\n"
99 "Pablo Zurita (pablo@qeradiant.com)\n"
100 "Hydra (hydra@hydras-world.com)",
101 "About GtkGenSurf", eMB_OK);
104 // =============================================================================
107 static void SetupControls()
109 switch (current_tab) {
114 if (Game != QUAKE3) {
115 gtk_widget_hide(g_object_get_data(G_OBJECT(g_pWnd, "use_patches")));
116 ENABLE_WIDGET("use_patches", FALSE);
118 gtk_widget_show(g_object_get_data(G_OBJECT(g_pWnd, "use_patches")));
119 ENABLE_WIDGET("use_patches", TRUE);
122 if (Game == QUAKE3 && UsePatches != 0) {
123 ENABLE_WIDGET("decimate", FALSE);
125 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "snap_text")),
126 "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.");
143 ENABLE_WIDGET("bmp_file", TRUE);
144 ENABLE_WIDGET("bmp_file_browse", TRUE);
145 ENABLE_WIDGET("bmp_black", TRUE);
146 ENABLE_WIDGET("bmp_white", TRUE);
147 ENABLE_WIDGET("bmp_text1", TRUE);
148 ENABLE_WIDGET("bmp_text2", TRUE);
149 ENABLE_WIDGET("bmp_text3", TRUE);
150 ENABLE_WIDGET("bmp_reload", strlen(gbmp.name) != 0);
151 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "bmp_note")),
152 "GenSurf works only with 8-bit bitmaps. Color indices are\n"
153 "mapped to values for each vertex. Generally, gray scale\n"
154 "images are stored with black as color 0, white as color 255.");
159 ENABLE_WIDGET("fix_value", (NumVerticesSelected != 0));
160 ENABLE_WIDGET("fix_value_text", (NumVerticesSelected != 0));
161 ENABLE_WIDGET("fix_free", (NumVerticesSelected != 0));
162 ENABLE_WIDGET("fix_range", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
163 ENABLE_WIDGET("fix_range_text", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
164 ENABLE_WIDGET("fix_rate", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
165 ENABLE_WIDGET("fix_rate_text", ((NumVerticesSelected != 0) && (WaveType != WAVE_ROUGH_ONLY)));
169 ENABLE_WIDGET("texture2", (UsePatches == 0));
170 ENABLE_WIDGET("texture3", (UsePatches == 0));
171 ENABLE_WIDGET("tex_slant", (UsePatches == 0));
172 ENABLE_WIDGET("detail", (UsePatches == 0));
173 if (Game != QUAKE3) {
174 ENABLE_WIDGET("terrain_ent", FALSE); // ^Fishman - Adds terrain key to func_group.
175 ENABLE_WIDGET("hint", (UsePatches == 0));
183 ENABLE_WIDGET("amplitude", TRUE);
184 ENABLE_WIDGET("wavelength", TRUE);
185 ENABLE_WIDGET("z00", TRUE);
186 ENABLE_WIDGET("z01", TRUE);
187 ENABLE_WIDGET("z10", TRUE);
188 ENABLE_WIDGET("z11", TRUE);
189 ENABLE_WIDGET("linearborder", TRUE);
190 ENABLE_WIDGET("go", TRUE);
193 ENABLE_WIDGET("amplitude", FALSE);
194 ENABLE_WIDGET("wavelength", FALSE);
195 ENABLE_WIDGET("z00", FALSE);
196 ENABLE_WIDGET("z01", FALSE);
197 ENABLE_WIDGET("z10", FALSE);
198 ENABLE_WIDGET("z11", FALSE);
199 ENABLE_WIDGET("linearborder", FALSE);
200 ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
202 case WAVE_ROUGH_ONLY:
203 ENABLE_WIDGET("amplitude", FALSE);
204 ENABLE_WIDGET("wavelength", FALSE);
205 ENABLE_WIDGET("z00", TRUE);
206 ENABLE_WIDGET("z01", TRUE);
207 ENABLE_WIDGET("z10", TRUE);
208 ENABLE_WIDGET("z11", TRUE);
209 ENABLE_WIDGET("linearborder", TRUE);
210 ENABLE_WIDGET("go", TRUE);
213 ENABLE_WIDGET("amplitude", TRUE);
214 ENABLE_WIDGET("wavelength", TRUE);
215 ENABLE_WIDGET("z00", TRUE);
216 ENABLE_WIDGET("z01", TRUE);
217 ENABLE_WIDGET("z10", TRUE);
218 ENABLE_WIDGET("z11", TRUE);
219 ENABLE_WIDGET("linearborder", TRUE);
220 ENABLE_WIDGET("go", TRUE);
226 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmin_text")), "X:");
227 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmax_text")), "X:");
228 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmin_text")), "Z:");
229 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmax_text")), "Z:");
230 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nh_text")), "X:");
231 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nv_text")), "Z:");
235 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmin_text")), "Y:");
236 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmax_text")), "Y:");
237 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmin_text")), "Z:");
238 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmax_text")), "Z:");
239 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nh_text")), "Y:");
240 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nv_text")), "Z:");
243 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmin_text")), "X:");
244 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "hmax_text")), "X:");
245 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmin_text")), "Y:");
246 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "vmax_text")), "Y:");
247 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nh_text")), "X:");
248 gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(g_pWnd), "nv_text")), "Y:");
253 // SetDlgValues fills in text boxes and initializes other input controls
254 static void SetDlgValues(int tab)
257 char RForm[16] = "%.5g";
262 // Hell if I know why, but in the release build the 2nd pass thru the
263 // set_sensitive loop for game_radios crashes. No need to do this more
265 if (!FirstPassComplete) {
266 for (i = 0; i < NUMGAMES; i++) {
267 gtk_widget_set_sensitive(game_radios[i], (i == Game ? TRUE : FALSE));
269 for (i = 0; i < 6; i++) {
270 gtk_widget_set_sensitive(plane_radios[i], (i == Plane ? TRUE : FALSE));
273 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(game_radios[Game]), TRUE);
274 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(plane_radios[Plane]), TRUE);
275 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wave_radios[WaveType]), TRUE);
276 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "random")),
278 sprintf(Text, RForm, WaveLength);
279 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "wavelength")), Text);
280 sprintf(Text, RForm, Amplitude);
281 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "amplitude")), Text);
282 sprintf(Text, RForm, Roughness);
283 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "roughness")), Text);
284 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data
285 (G_OBJECT(g_pWnd), "main_antialiasing")),
290 sprintf(Text, RForm, Hll);
291 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "hmin")), Text);
292 sprintf(Text, RForm, Vll);
293 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "vmin")), Text);
294 sprintf(Text, RForm, Hur);
295 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "hmax")), Text);
296 sprintf(Text, RForm, Vur);
297 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "vmax")), Text);
298 sprintf(Text, RForm, Z00);
299 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z00")), Text);
300 sprintf(Text, RForm, Z01);
301 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z01")), Text);
302 sprintf(Text, RForm, Z10);
303 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z10")), Text);
304 sprintf(Text, RForm, Z11);
305 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "z11")), Text);
306 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nh")), NH);
307 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nv")), NV);
308 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "sp")),
309 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);
326 SetDlgValues(current_tab);
334 SetDlgValues(current_tab);
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);
364 gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(g_pWnd, "decimate")), TRUE);
366 gpointer spin = g_object_get_data(G_OBJECT(g_pWnd), "nh");
367 GtkAdjustment *adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
369 gtk_adjustment_changed(adj);
370 spin = g_object_get_data(G_OBJECT(g_pWnd), "nv");
371 adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
373 gtk_adjustment_changed(adj);
376 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nh")), NH);
377 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "nv")), NV);
382 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_file")), gbmp.name);
383 sprintf(Text, "%g", gbmp.black_value);
384 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_black")), Text);
385 sprintf(Text, "%g", gbmp.white_value);
386 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_white")), Text);
393 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texture1")), Texture[Game][0]);
394 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texture2")), Texture[Game][1]);
395 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texture3")), Texture[Game][2]);
396 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "tex_slant")),
398 sprintf(Text, RForm, TexOffset[0]);
399 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texoffsetx")), Text);
400 sprintf(Text, RForm, TexOffset[1]);
401 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texoffsety")), Text);
402 sprintf(Text, RForm, TexScale[0]);
403 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texscalex")), Text);
404 sprintf(Text, RForm, TexScale[1]);
405 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "texscaley")), Text);
406 CHECK_WIDGET("detail", UseDetail);
408 if (Game == QUAKE3) {
409 ENABLE_WIDGET("hint", FALSE);
412 ENABLE_WIDGET("hint", TRUE);
414 CHECK_WIDGET("hint", AddHints);
419 // ArghRad doesn't currently support SiN
420 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), 0);
421 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), 0);
422 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT), SW_HIDE);
423 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), SW_HIDE);
424 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), SW_HIDE);
425 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use sin file");
426 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Sin:");
430 if (Game == QUAKE3) {
432 // ArghRad sun is inapplicable (so far)
433 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), 0);
434 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), 0);
435 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT), SW_HIDE);
436 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), SW_HIDE);
437 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), SW_HIDE);
439 EnableWindow(GetDlgItem(hwndDisplay,DLG_LADDER), 0);
440 ShowWindow(GetDlgItem(hwndDisplay,DLG_LADDER), SW_HIDE);
441 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use pk3 file");
442 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"PK3:");
446 /*trix if(Game==HERETIC2)
448 // ArghRad doesn't currently support Heretic2
449 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), 0);
450 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), 0);
451 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT), SW_HIDE);
452 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), SW_HIDE);
453 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), SW_HIDE);
455 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use pak file");
456 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Pak:");
461 // A bunch of controls aren't applicable to HL
462 EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE_BROWSE), 0);
463 EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE2_BROWSE),0);
464 EnableWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE3_BROWSE),0);
465 EnableWindow(GetDlgItem(hwndDisplay,DLG_DETAIL), 0);
466 EnableWindow(GetDlgItem(hwndDisplay,DLG_LADDER), 0);
467 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), 0);
468 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), 0);
469 ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE_BROWSE), SW_HIDE);
470 ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE2_BROWSE),SW_HIDE);
471 ShowWindow(GetDlgItem(hwndDisplay,DLG_TEXTURE3_BROWSE),SW_HIDE);
472 ShowWindow(GetDlgItem(hwndDisplay,DLG_DETAIL), SW_HIDE);
473 ShowWindow(GetDlgItem(hwndDisplay,DLG_LADDER), SW_HIDE);
474 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT), SW_HIDE);
475 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), SW_HIDE);
476 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), SW_HIDE);
478 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use wad file");
479 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Wad:");
480 SetDlgItemText(hwndDisplay,DLG_HINT,"Hint brushes");
485 // No Q2-type compilers support Genesis3D (including ArghRad)
486 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), 0);
487 EnableWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), 0);
488 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_TEXT), SW_HIDE);
489 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2), SW_HIDE);
490 ShowWindow(GetDlgItem(hwndDisplay,DLG_ARGHRAD2_SPIN), SW_HIDE);
492 SetDlgItemText(hwndDisplay,DLG_TEX_USEPAK,"Use sin file");
493 SetDlgItemText(hwndDisplay,DLG_TEX_PAK_TEXT,"Sin:");
501 static void ReadDlgValues(int tab)
509 Roughness = atof(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "roughness"))));
510 WaveLength = atof(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "wavelength"))));
511 Amplitude = atof(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "amplitude"))));
512 spin = g_object_get_data(G_OBJECT(g_pWnd), "random");
513 RandomSeed = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
517 SP = atoi(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "sp"))));
518 NH = atoi(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "nh"))));
519 NV = atoi(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "nv"))));
521 if (Game == QUAKE3 && UsePatches != 0) {
546 if ( WaveType == WAVE_BITMAP ) {
547 GetDlgItemText( hwnd,DLG_BMP_FILE,gbmp.name,sizeof( gbmp.name ) );
548 CheckValidDIB( hwnd );
549 GetDlgItemText( hwnd,DLG_BMP_BLACK,Text,sizeof( Text ) );
550 gbmp.black_value = atof( Text );
551 GetDlgItemText( hwnd,DLG_BMP_WHITE,Text,sizeof( Text ) );
552 gbmp.white_value = atof( Text );
553 UpdatePreview( TRUE );
558 GetDlgItemText( hwnd,DLG_FIX_VALUE,Text,sizeof( Text ) );
559 temp.fixed_value = atoi( Text );
560 GetDlgItemText( hwnd,DLG_FIX_RANGE,Text,sizeof( Text ) );
561 temp.range = atoi( Text );
562 GetDlgItemText( hwnd,DLG_FIX_RATE, Text,sizeof( Text ) );
563 temp.rate = atof( Text );
564 for ( k = 0; k < NumVerticesSelected; k++ )
566 xyz[Vertex[k].i][Vertex[k].j].fixed_value = temp.fixed_value;
567 xyz[Vertex[k].i][Vertex[k].j].range = temp.range;
568 xyz[Vertex[k].i][Vertex[k].j].rate = temp.rate;
572 CheckDlgButton( ghwnd,DLG_PREVIEW,0 );
573 SendMessage( ghwnd,WM_COMMAND,DLG_PREVIEW,0 );
576 UpdatePreview( TRUE );
580 if ( UsePak[Game] ) {
581 i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETCURSEL, 0, 0 );
583 Texture[Game][0][0] = '\0';
586 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST1, CB_GETLBTEXT, i,
587 (LPARAM)(LPCSTR)Texture[Game][0] );
590 i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETCURSEL, 0, 0 );
592 Texture[Game][1][0] = '\0';
595 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST2, CB_GETLBTEXT, i,
596 (LPARAM)(LPCSTR)Texture[Game][1] );
599 i = SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETCURSEL, 0, 0 );
601 Texture[Game][2][0] = '\0';
604 SendDlgItemMessage( hwndDisplay, DLG_TEX_LIST3, CB_GETLBTEXT, i,
605 (LPARAM)(LPCSTR)Texture[Game][2] );
610 GetDlgItemText( hwndDisplay,DLG_TEXTURE, Texture[Game][0],sizeof( Texture[Game][0] ) );
611 GetDlgItemText( hwndDisplay,DLG_TEXTURE2,Texture[Game][1],sizeof( Texture[Game][1] ) );
612 GetDlgItemText( hwndDisplay,DLG_TEXTURE3,Texture[Game][2],sizeof( Texture[Game][2] ) );
614 GetDlgItemText( hwndDisplay,DLG_TEX_SLANT,Text,sizeof( Text ) );
615 SlantAngle = atoi( Text );
616 SlantAngle = max( 0,min( SlantAngle,90 ) );
617 GetDlgItemText( hwndDisplay,DLG_TEXOFFSETX,Text,sizeof( Text ) );
618 TexOffset[0] = atof( Text );
619 GetDlgItemText( hwndDisplay,DLG_TEXOFFSETY,Text,sizeof( Text ) );
620 TexOffset[1] = atof( Text );
621 GetDlgItemText( hwndDisplay,DLG_TEXSCALEX,Text,sizeof( Text ) );
622 TexScale[0] = atof( Text );
623 if ( TexScale[0] == 0. ) {
626 GetDlgItemText( hwndDisplay,DLG_TEXSCALEY,Text,sizeof( Text ) );
627 TexScale[1] = atof( Text );
628 if ( TexScale[1] == 0. ) {
631 GetDlgItemText( hwndDisplay,DLG_ARGHRAD2,Text,sizeof( Text ) );
632 ArghRad2 = atoi( Text );
638 // =============================================================================
639 // main dialog callbacks
641 static void switch_page(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data)
643 if (current_tab != page_num) {
644 if (page_num == FIXPOINTS_TAB) {
645 OldPreview = Preview;
646 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(g_pWnd),
647 "main_preview")), TRUE);
650 NumVerticesSelected = 0;
653 if (current_tab == FIXPOINTS_TAB) {
655 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(g_pWnd),
656 "main_preview")), FALSE);
660 NumVerticesSelected = 0;
663 if (page_num == TEXTURE_TAB) {
664 WasDetail = UseDetail;
667 ENABLE_WIDGET("detail", FALSE);
671 ReadDlgValues(current_tab);
672 current_tab = page_num;
673 SetDlgValues(current_tab);
677 static gint main_close(GtkWidget *widget, gpointer data)
679 gtk_widget_hide(g_pWnd);
680 gtk_widget_hide(g_pWndPreview);
685 static void main_save(GtkWidget *widget, gpointer data)
687 ReadDlgValues(current_tab);
691 static void main_open(GtkWidget *widget, gpointer data)
693 OpenSetup(g_pWnd, 0);
694 for (int i = 0; i < 5; i++) {
700 static void main_defaults(GtkWidget *widget, gpointer data)
702 OpenSetup(g_pWnd, 1);
703 for (int i = 0; i < 5; i++) {
709 static void main_preview(GtkWidget *widget, gpointer data)
711 Preview = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
715 // ^Fishman - Antializing for the preview window.
716 static void main_antialiasing(GtkWidget *widget, gpointer data)
718 Antialiasing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
722 static void main_about(GtkWidget *widget, gpointer data)
727 static void main_go(GtkWidget *widget, gpointer data)
729 GtkWidget *notebook = g_object_get_data(G_OBJECT(g_pWnd, "notebook"));
732 ReadDlgValues(current_tab);
733 if (NH < 1 || NH > MAX_ROWS) {
734 sprintf(Text, "The number of divisions must be > 0 and no greater than %d.", MAX_ROWS);
735 g_FuncTable.m_pfnMessageBox(g_pWnd, Text, "GenSurf", eMB_OK, eMB_ICONWARNING);
736 gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
740 if (NV < 1 || NV > MAX_ROWS) {
741 sprintf(Text, "The number of divisions must be > 0 and no greater than %d.", MAX_ROWS);
742 g_FuncTable.m_pfnMessageBox(g_pWnd, Text, "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);
756 g_FuncTable.m_pfnMessageBox(g_pWnd, "The \"lower-left\" values must be less than "
757 "the corresponding \"upper-right\" values in "
758 "the \"Extent\" box.", "GenSurf", eMB_OK, eMB_ICONWARNING);
759 gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
763 if (!strlen(Texture[Game][0])) {
764 g_FuncTable.m_pfnMessageBox(g_pWnd, "You must supply a texture name.", "GenSurf", eMB_OK, eMB_ICONWARNING);
765 gtk_notebook_set_page(GTK_NOTEBOOK(notebook), EXTENTS_TAB);
769 /* if (Decimate>0 && GimpHints!=0)
771 MessageBox(hwnd,"You've elected to use a decimated grid and gimp's non-detail hint brushes. "
772 "This combination usually produces bizarre visual errors in the game, "
773 "so GenSurf has turned off the hint brush option.",
774 "GenSurf",eMB_ICONWARNING);
778 gtk_widget_hide(g_pWnd);
780 gtk_widget_hide(g_pWndPreview);
784 WriteIniFile(gszIni);
787 // =============================================================================
788 // general tab callbacks
790 static void general_game(GtkToggleButton *widget, gpointer data)
792 if (gtk_toggle_button_get_active(widget)) {
793 Game = GPOINTER_TO_INT(data);
798 static void general_plane(GtkToggleButton *widget, gpointer data)
800 if (gtk_toggle_button_get_active(widget)) {
801 Plane = GPOINTER_TO_INT(data);
807 static void general_wave(GtkToggleButton *widget, gpointer data)
809 if (gtk_toggle_button_get_active(widget)) {
810 WaveType = GPOINTER_TO_INT(data);
816 static void general_random(GtkAdjustment *adj, gpointer data)
818 int nPos = (int) adj->value;
820 if (RandomSeed != nPos) {
826 // =============================================================================
827 // extents tab callbacks
829 static void extents_linearborder(GtkToggleButton *check, gpointer data)
831 FixBorders = gtk_toggle_button_get_active(check);
835 static void extents_use_patches(GtkToggleButton *check, gpointer data)
837 if (Game != QUAKE3) {
841 UsePatches = gtk_toggle_button_get_active(check);
842 SetDlgValues(current_tab);
847 static void extents_nhnv_spin(GtkAdjustment *adj, int *data)
849 int nPos = (int) adj->value;
852 if (Game == QUAKE3 && UsePatches && (nPos % 2)) {
858 gtk_adjustment_set_value(adj, *data);
866 static void extents_decimate(GtkAdjustment *adj, gpointer data)
868 int nPos = (int) adj->value;
874 // Hydra : snap to grid begin
875 /*static void extents_snaptogrid (GtkAdjustment *adj, gpointer data)
877 int nPos = (int)adj->value;
880 UpdatePreview (true);
883 // ^Fishman - Modified version of Hydra's snap to grid code.
884 static void extents_snaptogrid_spin(GtkAdjustment *adj, int *data)
886 int nPos = (int) adj->value;
891 // =============================================================================
892 // bitmap tab callbacks
894 static gint bitmap_file_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
896 char filename[NAME_MAX];
898 strcpy(filename, gtk_entry_get_text(GTK_ENTRY(widget)));
899 if (strcmp(filename, gbmp.name)) {
900 strcpy(gbmp.name, filename);
901 if (strlen(gbmp.name)) {
904 ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
909 static void bitmap_browse(GtkWidget *widget, gpointer data)
911 const char *filename;
914 filename = g_FuncTable.m_pfnFileDialog(g_pWnd, TRUE, "Bitmap File", gbmp.defpath);
916 if (filename != NULL) {
917 strcpy(gbmp.name, filename);
919 ptr = strrchr(filename, G_DIR_SEPARATOR);
922 strcpy(gbmp.defpath, filename);
926 ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
930 static void bitmap_reload(GtkWidget *widget, gpointer data)
932 strcpy(gbmp.name, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "bmp_file"))));
933 if (strlen(gbmp.name)) {
935 ENABLE_WIDGET("go", (gbmp.colors != NULL ? TRUE : FALSE));
937 ENABLE_WIDGET("go", FALSE);
941 // =============================================================================
942 // fix points tab callbacks
944 static gint fix_value_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
946 int i = atoi(gtk_entry_get_text(GTK_ENTRY(widget))), k;
949 if (i < -65536 || i > 65536) {
951 g_FuncTable.m_pfnMessageBox(g_pWnd, "The value must be between -65536 and 65536, inclusive.",
952 "GenSurf", eMB_OK, eMB_ICONWARNING);
953 sprintf(Text, "%d", (int) xyz[Vertex[0].i][Vertex[0].j].fixed_value);
954 gtk_entry_set_text(GTK_ENTRY(widget), Text);
955 gtk_window_set_focus(widget.window(), widget);
956 } else if (i != xyz[Vertex[0].i][Vertex[0].j].fixed_value) {
957 for (k = 0; k < NumVerticesSelected; k++) {
958 xyz[Vertex[k].i][Vertex[k].j].fixed_value = i;
961 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "fix_value")),
962 (int) xyz[Vertex[0].i][Vertex[0].j].fixed_value);
968 static void fix_value_changed(GtkAdjustment *adj, gpointer data)
970 int k, i = (int) adj->value;
972 if (xyz[Vertex[0].i][Vertex[0].j].fixed_value != i) {
973 for (k = 0; k < NumVerticesSelected; k++) {
974 xyz[Vertex[k].i][Vertex[k].j].fixed_value = i;
980 static gint fix_range_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
982 int i = atoi(gtk_entry_get_text(GTK_ENTRY(widget))), k;
984 if (i != xyz[Vertex[0].i][Vertex[0].j].range) {
985 for (k = 0; k < NumVerticesSelected; k++) {
986 xyz[Vertex[k].i][Vertex[k].j].range = i;
993 static gint fix_rate_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
995 double r = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
998 if (r != xyz[Vertex[0].i][Vertex[0].j].rate) {
999 for (k = 0; k < NumVerticesSelected; k++) {
1000 xyz[Vertex[k].i][Vertex[k].j].rate = r;
1002 UpdatePreview(true);
1007 static void fix_free(GtkWidget *widget, gpointer data)
1011 for (k = 0; k < NumVerticesSelected; k++) {
1012 xyz[Vertex[k].i][Vertex[k].j].fixed = 0;
1014 NumVerticesSelected = 0;
1016 UpdatePreview(true);
1019 static void fix_freeall(GtkWidget *widget, gpointer data)
1023 for (i = 0; i <= NH; i++) {
1024 for (j = 0; j <= NV; j++) {
1025 xyz[i][j].fixed = 0;
1028 fix_free(NULL, data); // keep these together
1031 void vertex_selected()
1041 for (k = 0; k < NumVerticesSelected; k++) {
1042 xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[1];
1047 for (k = 0; k < NumVerticesSelected; k++) {
1048 xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[0];
1052 for (k = 0; k < NumVerticesSelected; k++) {
1053 xyz[Vertex[k].i][Vertex[k].j].fixed_value = xyz[Vertex[0].i][Vertex[0].j].p[2];
1058 gtk_spin_button_set_value(GTK_SPIN_BUTTON(g_object_get_data(G_OBJECT(g_pWnd), "fix_value")),
1059 (int) xyz[Vertex[0].i][Vertex[0].j].fixed_value);
1061 sprintf(Text, "%d", (int) xyz[Vertex[0].i][Vertex[0].j].range);
1062 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "fix_range")), Text);
1063 sprintf(Text, "%.5g", xyz[Vertex[0].i][Vertex[0].j].rate);
1064 gtk_entry_set_text(GTK_ENTRY(g_object_get_data(G_OBJECT(g_pWnd), "fix_rate")), Text);
1066 for (k = 0; k < NumVerticesSelected; k++) {
1067 xyz[Vertex[k].i][Vertex[k].j].fixed = 1;
1070 UpdatePreview(true);
1073 // =============================================================================
1074 // texture tab callbacks
1076 static void texture_detail(GtkToggleButton *check, gpointer data)
1078 UseDetail = gtk_toggle_button_get_active(check);
1079 WasDetail = UseDetail;
1082 static void texture_hint(GtkToggleButton *check, gpointer data)
1084 AddHints = gtk_toggle_button_get_active(check);
1085 if (AddHints == 1) {
1087 ENABLE_WIDGET("detail", FALSE);
1089 UseDetail = WasDetail;
1090 ENABLE_WIDGET("detail", FALSE);
1092 CHECK_WIDGET("detail", UseDetail);
1095 // ^Fishman - Add terrain key to func_group.
1096 static void texture_terrainent(GtkToggleButton *check, gpointer data)
1098 AddTerrainKey = gtk_toggle_button_get_active(check);
1101 static void texture_set(int index, const char *name)
1103 strcpy(Texture[Game][index], name);
1106 static gint texture_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
1108 texture_set(GPOINTER_TO_INT(data), gtk_entry_get_text(GTK_ENTRY(widget)));
1112 // =============================================================================
1115 static void UpdateVariable(GtkEntry *entry, GdkEventFocus *event, double *data)
1117 double x = atof(gtk_entry_get_text(entry));
1121 UpdatePreview(true);
1125 static gint doublevariable_entryfocusout(GtkWidget *widget, GdkEventFocus *event, gpointer data)
1127 UpdateVariable(GTK_ENTRY(widget), event, reinterpret_cast<double *>( data ));
1131 // =============================================================================
1134 void create_tooltips()
1136 tooltips = gtk_tooltips_new();
1139 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1140 g_object_get_data(G_OBJECT(g_pWnd, "go")),
1141 "Accept all input and generate a surface in Q3Radiant",
1143 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1144 g_object_get_data(G_OBJECT(g_pWnd, "open")),
1145 "Open a previously saved GenSurf settings file.",
1147 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1148 g_object_get_data(G_OBJECT(g_pWnd, "save")),
1149 "Save all settings to a file.",
1151 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1152 g_object_get_data(G_OBJECT(g_pWnd, "defaults")),
1153 "Restore default values from DEFAULTS.SRF. If this file does not exist, GenSurf "
1154 "initializes all input parameters to reasonable values. You can create your own "
1155 "default surface by setting all parameters to your liking, then saving a settings "
1156 "file as DEFAULTS.SRF with the Save As button.",
1159 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1160 g_object_get_data(G_OBJECT(g_pWnd, "main_preview")),
1161 "View a wire-frame representation of the surface",
1164 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1165 g_object_get_data(G_OBJECT(g_pWnd, "main_antialiasing")),
1166 "The lines in the preview window are antialiased for better quality",
1170 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1172 "Builds a surface with alternating hills and valleys. Uses the general form Z=cos(X) "
1175 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1177 "Builds a surface with ridges parallel to the vertical axis.",
1179 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1181 "Builds a surface with ridges parallel to the horizontal axis.",
1183 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1185 "Builds a map from a bitmap image representing a contour plot. Click the \"Bitmap\" "
1186 "tab to select the image. GenSurf only supports 256-color (8 bit) "
1187 "bitmaps. GenSurf will work with any 256-color bitmap, but gray scale bitmaps are a bit "
1190 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1192 "Builds a random surface using the Plasma Cloud technique. Variance is controlled "
1193 "by the Roughness input. To build a surface with completely random values not "
1194 "dependent on neighboring vertices, use one of the other waveforms with 0 amplitude.",
1196 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1197 g_object_get_data(G_OBJECT(g_pWnd, "wavelength")),
1198 "Enter the wavelength (distance between crests). NOTE: Wavelengths equal to the grid "
1199 "size or 2 times the grid size will result in 0 amplitudes. For best results, the "
1200 "wavelength value should be at least 4 times the grid size (extents divided by the "
1201 "number of divisions",
1203 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1204 g_object_get_data(G_OBJECT(g_pWnd, "amplitude")),
1205 "Enter the height of hills/ridges.",
1207 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1208 g_object_get_data(G_OBJECT(g_pWnd, "roughness")),
1209 "Enter the roughness value (noise) for the surface. For fractal surfaces, this value "
1210 "is used as a variance in the fractal calculations.",
1212 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1213 g_object_get_data(G_OBJECT(g_pWnd, "random")),
1214 "Seed value for the pseudo-random number generator.",
1217 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1218 g_object_get_data(G_OBJECT(g_pWnd, "hmin")),
1219 "Minimum horizontal coordinate of the surface, i.e. X for a surface parallel to "
1220 "the XY or XZ planes, Y for a surface parallel to the YZ plane. For best results, "
1221 "the extents (maximum-minimum values) in a given direction should be evenly "
1222 "divisible by the number of divisions in that direction.",
1224 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1225 g_object_get_data(G_OBJECT(g_pWnd, "hmax")),
1226 "Maximum horizontal coordinate of the surface, i.e. X for a surface parallel to "
1227 "the XY or XZ planes, Y for a surface parallel to the YZ plane. For best results, "
1228 "the extents (maximum-minimum values) in a given direction should be evenly "
1229 "divisible by the number of divisions in that direction.",
1231 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1232 g_object_get_data(G_OBJECT(g_pWnd, "vmin")),
1233 "Minimum vertical coordinate of the surface, i.e. Y for a surface parallel to "
1234 "the XY plane, Z for a surface parallel to the XZ or YZ planes. For best results, "
1235 "the extents (maximum-minimum values) in a given direction should be evenly "
1236 "divisible by the number of divisions in that direction.",
1238 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1239 g_object_get_data(G_OBJECT(g_pWnd, "vmax")),
1240 "Maximum vertical coordinate of the surface, i.e. Y for a surface parallel to "
1241 "the XY plane, Z for a surface parallel to the XZ or YZ planes. For best results, "
1242 "the extents (maximum-minimum values) in a given direction should be evenly "
1243 "divisible by the number of divisions in that direction.",
1245 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1246 g_object_get_data(G_OBJECT(g_pWnd, "nh")),
1247 "Number of divisions in the horizontal direction. For best results, the extents "
1248 "in a given direction should be evenly divisible by the number of divisions in "
1251 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1252 g_object_get_data(G_OBJECT(g_pWnd, "nv")),
1253 "Number of divisions in the vertical direction. For best results, the extents "
1254 "in a given direction should be evenly divisible by the number of divisions in "
1257 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1258 g_object_get_data(G_OBJECT(g_pWnd, "use_patches")),
1259 "Produce one or more curved patches in the shape of your selected surface rather "
1260 "than producing solid brushes. Depending on the size of your surface (and the "
1261 "user's graphic detail settings, which you cannot control), curved surfaces will "
1262 "be represented in the game by a very large number of polygons. Read the warnings "
1263 "concerning curved surfaces on the GenSurf web page before using this feature.",
1265 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1266 g_object_get_data(G_OBJECT(g_pWnd, "decimate")),
1267 "Use the slider to control the number of vertices discarded by GenSurf. For many "
1268 "surfaces, you can produce roughly the same shape surface with a high decimation "
1269 "value. This will generally result in a map with lower polygon counts (and better "
1270 "in-game performance). However, this feature should NOT be used for large terrain "
1273 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1274 g_object_get_data(G_OBJECT(g_pWnd, "z00")),
1275 "Enter the height of the surface at the lower left corner. This value will likely "
1276 "be modified unless \"Linear Borders\" is checked.",
1278 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1279 g_object_get_data(G_OBJECT(g_pWnd, "z01")),
1280 "Enter the height of the surface at the upper left corner. This value will likely "
1281 "be modified unless \"Linear Borders\" is checked.",
1283 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1284 g_object_get_data(G_OBJECT(g_pWnd, "z10")),
1285 "Enter the height of the surface at the lower right corner. This value will likely "
1286 "be modified unless \"Linear Borders\" is checked.",
1288 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1289 g_object_get_data(G_OBJECT(g_pWnd, "z11")),
1290 "Enter the height of the surface at the upper right corner. This value will likely "
1291 "be modified unless \"Linear Borders\" is checked.",
1293 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1294 g_object_get_data(G_OBJECT(g_pWnd, "linearborder")),
1295 "Restrict the edges of the surface to a straight line. This will help match up "
1296 "brush edges if you drop this surface into another map.",
1299 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1300 g_object_get_data(G_OBJECT(g_pWnd, "bmp_file")),
1301 "Type the name of an 8-bit bitmap image file, or click Browse to select an image "
1302 "from a list of those available on your system.",
1304 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1305 g_object_get_data(G_OBJECT(g_pWnd, "bmp_file_browse")),
1306 "Select a bitmap image file from a list of those available on your system.",
1308 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1309 g_object_get_data(G_OBJECT(g_pWnd, "bmp_reload")),
1310 "Reload the selected bitmap file after making changes in an external image editor.",
1312 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1313 g_object_get_data(G_OBJECT(g_pWnd, "bmp_black")),
1314 "Enter the value corresponding to color index 0 in the bitmap file. For gray scale "
1315 "images, color 0 is normally black.",
1317 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1318 g_object_get_data(G_OBJECT(g_pWnd, "bmp_white")),
1319 "Enter the value corresponding to color index 255 in the bitmap file. For gray scale "
1320 "images, color 255 is normally white.",
1323 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1324 g_object_get_data(G_OBJECT(g_pWnd, "fix_value")),
1325 "Enter a value for the selected vertex. This value will not be adjusted when applying "
1326 "a waveform or roughness to the surface. Unlock this vertex (so that it will be "
1327 "adjusted normally) by clicking \"Free\". This vertex will influence vertices within "
1328 "the \"Range affected\" of this vertex.",
1330 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1331 g_object_get_data(G_OBJECT(g_pWnd, "fix_range")),
1332 "Enter the range away from the selected vertex that other vertices will be affected. "
1333 "Use 0 if you don't want other vertices to be influenced by the currently selected "
1334 "one. Note: this box is disabled if you've chosen the fractal generator, as it uses "
1335 "a completely different method for determining values.",
1337 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1338 g_object_get_data(G_OBJECT(g_pWnd, "fix_rate")),
1339 "Enter a rate of change for the surface affected by the fixed value. 0 gives a smooth "
1340 "sinusoidal curve, values less than 0 give progressively sharper spikes, and values "
1341 "greater than 0 take on a square shape. Values less than -30 or greater than 30 are "
1342 "set to -30 and 30, respectively. Note that this entry will have no effect unless "
1343 "you also specify a \"range affected\".",
1345 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1346 g_object_get_data(G_OBJECT(g_pWnd, "fix_free")),
1347 "Click this to free (unlock the value of) the currently selected vertex.",
1349 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1350 g_object_get_data(G_OBJECT(g_pWnd, "fix_freeall")),
1351 "Click this to free (unlock the values of) all vertices.",
1354 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1355 g_object_get_data(G_OBJECT(g_pWnd, "texture1")),
1356 "Enter the name of the texture or shader used for the surface faces.",
1358 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1359 g_object_get_data(G_OBJECT(g_pWnd, "texture2")),
1360 "Enter the name of the texture or shader used for faces other than the surface. Under "
1361 "normal circumstances this should be \"common/caulk\"",
1363 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1364 g_object_get_data(G_OBJECT(g_pWnd, "texture3")),
1365 "Enter the name of the texture or shader used for \"steep\" surface faces, where \"steep\" "
1366 "is the angle specified below. If this entry is left blank or if the \"steep\" angle is 0, "
1367 "all surface faces will use the texture specified by \"Surface\".",
1370 gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips),
1371 g_object_get_data(G_OBJECT(g_pWnd, "detail")),
1372 "Check this box to use the detail content property on the generated brushes. Compile "
1373 "times will be considerably shorter if the detail property is used, though the surface "
1374 "will not block visibility at all. If you use the detail property, you should make sure "
1375 "that \"common/caulk\" is used for the non-surface faces, or the polygon count will be "
1376 "much higher than necessary.",
1380 // =============================================================================
1381 // create main dialog
1383 GtkWidget *create_main_dialog()
1385 GtkWidget *hbox2, *button, *notebook, *table2;
1386 GtkWidget *check, *spin, *radio, *label, *entry, *scale;
1390 const char *games[] = {"Quake 2", "Half-Life", "SiN", "Heretic 2", "Kingpin", "Genesis3D", "Quake 3 Arena"};
1391 const char *waveforms[] = {"Alternating hill/valley", "Cylindrical left-to-right", "Cylindrical top-to-bottom",
1392 "From bitmap", "Fractal"};
1393 const char *orientations[] = {"Ground surface", "Ceiling", "Wall facing 0", "Wall facing 90",
1394 "Wall facing 180", "Wall facing 270"};
1396 auto dlg = g_pWnd = ui::Window(ui::window_type::TOP);
1397 gtk_window_set_title(dlg, gszCaption);
1398 dlg.connect("delete_event", G_CALLBACK(main_close), NULL);
1399 // dlg.connect( "destroy", G_CALLBACK (gtk_widget_destroy), NULL);
1400 gtk_window_set_transient_for(dlg, g_pRadiantWnd);
1402 auto hbox = ui::HBox(FALSE, 5);
1405 gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
1407 notebook = gtk_notebook_new();
1409 hbox.pack_start(notebook, TRUE, TRUE, 0);
1410 notebook.connect("switch_page",
1411 G_CALLBACK(switch_page), NULL);
1412 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
1413 g_object_set_data(G_OBJECT(dlg), "notebook", notebook);
1415 table = ui::Table(2, 2, FALSE);
1417 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1418 gtk_table_set_row_spacings(table, 5);
1419 gtk_table_set_col_spacings(table, 5);
1421 label = ui::Label("General");
1423 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table, label);
1425 auto frame = ui::Frame("Game");
1427 table.attach(frame, {0, 1, 0, 1});
1429 auto vbox = ui::VBox(TRUE, 5);
1432 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1434 for (i = 0, group = NULL; i < NUMGAMES; i++) {
1435 radio = gtk_radio_button_new_with_label(group, games[i]);
1437 vbox.pack_start(radio, TRUE, TRUE, 0);
1438 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
1439 game_radios[i] = radio;
1440 radio.connect("toggled", G_CALLBACK(general_game), GINT_TO_POINTER(i));
1443 frame = ui::Frame("Waveform");
1445 table.attach(frame, {1, 2, 0, 1});
1447 vbox = ui::VBox(TRUE, 5);
1450 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1452 for (i = 0, group = NULL; i < 5; i++) {
1453 radio = gtk_radio_button_new_with_label(group, waveforms[i]);
1455 vbox.pack_start(radio, TRUE, TRUE, 0);
1456 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
1457 wave_radios[i] = radio;
1458 radio.connect("toggled", G_CALLBACK(general_wave), GINT_TO_POINTER(i));
1461 frame = ui::Frame("Orientation");
1463 table.attach(frame, {0, 1, 1, 2});
1465 vbox = ui::VBox(TRUE, 5);
1468 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1470 for (i = 0, group = NULL; i < 6; i++) {
1471 radio = gtk_radio_button_new_with_label(group, orientations[i]);
1473 vbox.pack_start(radio, TRUE, TRUE, 0);
1474 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio));
1475 plane_radios[i] = radio;
1476 radio.connect("toggled", G_CALLBACK(general_plane), GINT_TO_POINTER(i));
1479 table2 = ui::Table(4, 2, FALSE);
1481 gtk_table_set_row_spacings(table2, 5);
1482 gtk_table_set_col_spacings(table2, 5);
1483 table.attach(table2, {1, 2, 1, 2});
1485 label = ui::Label("Wavelength:");
1487 table2.attach(label, {0, 1, 0, 1});
1488 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1489 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1491 label = ui::Label("Max. amplitude:");
1493 table2.attach(label, {0, 1, 1, 2});
1494 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1495 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1497 label = ui::Label("Roughness:");
1499 table2.attach(label, {0, 1, 2, 3});
1500 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1501 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1503 label = ui::Label("Random seed:");
1505 table2.attach(label, {0, 1, 3, 4});
1506 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1507 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1509 entry = ui::Entry();
1511 table2.attach(entry, {1, 2, 0, 1});
1512 entry.dimensions(50, -1);
1513 g_object_set_data(G_OBJECT(dlg), "wavelength", entry);
1514 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &WaveLength);
1516 entry = ui::Entry();
1518 table2.attach(entry, {1, 2, 1, 2});
1519 entry.dimensions(50, -1);
1520 g_object_set_data(G_OBJECT(dlg), "amplitude", entry);
1521 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Amplitude);
1523 entry = ui::Entry();
1525 table2.attach(entry, {1, 2, 2, 3});
1526 entry.dimensions(50, -1);
1527 g_object_set_data(G_OBJECT(dlg), "roughness", entry);
1528 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Roughness);
1530 adj = ui::Adjustment(1, 1, 32767, 1, 10, 0);
1531 adj.connect("value_changed", G_CALLBACK(general_random), NULL);
1532 spin = ui::SpinButton(adj, 1, 0);
1534 table2.attach(spin, {1, 2, 3, 4});
1535 spin.dimensions(60, -1);
1536 g_object_set_data(G_OBJECT(dlg), "random", spin);
1538 vbox = ui::VBox(FALSE, 5);
1540 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1542 label = ui::Label("Extents");
1544 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1546 hbox2 = ui::HBox(FALSE, 5);
1548 vbox.pack_start(hbox2, FALSE, TRUE, 0);
1550 frame = ui::Frame("Extents");
1552 hbox2.pack_start(frame, TRUE, TRUE, 0);
1554 auto table = ui::Table(3, 4, FALSE);
1556 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1558 gtk_table_set_row_spacings(table, 5);
1559 gtk_table_set_col_spacings(table, 5);
1561 label = ui::Label("X:");
1563 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1564 g_object_set_data(G_OBJECT(dlg), "hmin_text", label);
1566 label = ui::Label("X:");
1568 table.attach(label, {2, 3, 1, 2}, {GTK_FILL, GTK_FILL});
1569 g_object_set_data(G_OBJECT(dlg), "hmax_text", label);
1571 label = ui::Label("Y:");
1573 table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1574 g_object_set_data(G_OBJECT(dlg), "vmin_text", label);
1576 label = ui::Label("Y:");
1578 table.attach(label, {2, 3, 2, 3}, {GTK_FILL, GTK_FILL});
1579 g_object_set_data(G_OBJECT(dlg), "vmax_text", label);
1581 label = ui::Label("Lower-left");
1583 table.attach(label, {1, 2, 0, 1}, {GTK_FILL, GTK_FILL});
1585 label = ui::Label("Upper-right");
1587 table.attach(label, {3, 4, 0, 1}, , {GTK_FILL, GTK_FILL});
1589 entry = ui::Entry();
1591 table.attach(entry, {1, 2, 1, 2});
1592 entry.dimensions(50, -1);
1593 g_object_set_data(G_OBJECT(dlg), "hmin", entry);
1594 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Hll);
1596 entry = ui::Entry();
1598 table.attach(entry, {3, 4, 1, 2});
1599 entry.dimensions(50, -1);
1600 g_object_set_data(G_OBJECT(dlg), "hmax", entry);
1601 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Hur);
1603 entry = ui::Entry();
1605 table.attach(entry, {1, 2, 2, 3});
1606 entry.dimensions(50, -1);
1607 g_object_set_data(G_OBJECT(dlg), "vmin", entry);
1608 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Vll);
1610 entry = ui::Entry();
1612 table.attach(entry, {3, 4, 2, 3});
1613 entry.dimensions(50, -1);
1614 g_object_set_data(G_OBJECT(dlg), "vmax", entry);
1615 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Vur);
1617 frame = ui::Frame("Divisions");
1619 hbox2.pack_start(frame, TRUE, TRUE, 0);
1621 table = ui::Table(2, 2, FALSE);
1623 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1625 gtk_table_set_row_spacings(table, 5);
1626 gtk_table_set_col_spacings(table, 5);
1628 label = ui::Label("X:");
1630 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_EXPAND | GTK_FILL});
1631 g_object_set_data(G_OBJECT(dlg), "nh_text", label);
1633 label = ui::Label("Y:");
1635 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_EXPAND | GTK_FILL});
1636 g_object_set_data(G_OBJECT(dlg), "nv_text", label);
1638 adj = ui::Adjustment(8, 1, MAX_ROWS, 1, 10, 0);
1639 adj.connect("value_changed", G_CALLBACK(extents_nhnv_spin), &NH);
1640 spin = ui::SpinButton(adj, 1, 0);
1642 table.attach(spin, {1, 2, 0, 1});
1643 spin.dimensions(60, -1);
1644 g_object_set_data(G_OBJECT(dlg), "nh", spin);
1646 adj = ui::Adjustment(8, 1, MAX_ROWS, 1, 10, 0);
1647 adj.connect("value_changed", G_CALLBACK(extents_nhnv_spin), &NV);
1648 spin = ui::SpinButton(adj, 1, 0);
1650 table.attach(spin, {1, 2, 1, 2});
1651 spin.dimensions(60, -1);
1652 g_object_set_data(G_OBJECT(dlg), "nv", spin);
1654 check = ui::CheckButton("Use Bezier patches");
1656 vbox.pack_start(check, FALSE, TRUE, 0);
1657 g_object_set_data(G_OBJECT(dlg), "use_patches", check);
1658 check.connect("toggled", G_CALLBACK(extents_use_patches), NULL);
1660 // ^Fishman - Snap to grid, replaced scroll bar with a texbox.
1661 label = ui::Label("Snap to grid:");
1663 vbox.pack_start(label, FALSE, TRUE, 0);
1664 gtk_object_set_data(GTK_OBJECT(dlg), "snap_text", label);
1666 adj = ui::Adjustment(8, 0, 256, 1, 10, 0);
1667 adj.connect("value_changed", G_CALLBACK(extents_snaptogrid_spin), &SP);
1668 spin = ui::SpinButton(adj, 1, 0);
1670 vbox.pack_start(spin, FALSE, TRUE, 0);
1671 spin.dimensions(60, -1);
1672 g_object_set_data(G_OBJECT(dlg), "sp", spin);
1673 // ^Fishman - End of Snap to grid code.
1675 hbox2 = ui::HBox(FALSE, 5);
1677 vbox.pack_start(hbox2, FALSE, TRUE, 10);
1679 label = ui::Label("Decimate:");
1681 hbox2.pack_start(label, FALSE, TRUE, 0);
1683 adj = ui::Adjustment(0, 0, 110, 1, 10, 0);
1684 adj.connect("value_changed", G_CALLBACK(extents_decimate), NULL);
1685 g_object_set_data(G_OBJECT(dlg), "decimate_adj", adj);
1686 scale = ui::HScale(adj);
1688 hbox2.pack_start(scale, TRUE, TRUE, 0);
1689 gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_RIGHT);
1690 gtk_scale_set_digits(GTK_SCALE(scale), 0);
1691 g_object_set_data(G_OBJECT(dlg), "decimate", scale);
1693 frame = ui::Frame("Corner values");
1695 vbox.pack_start(frame, FALSE, TRUE, 0);
1697 table = ui::Table(3, 4, FALSE);
1699 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1701 gtk_table_set_row_spacings(table, 5);
1702 gtk_table_set_col_spacings(table, 5);
1704 label = ui::Label("Upper-left:");
1706 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1708 label = ui::Label("Lower-left:");
1710 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1712 label = ui::Label("Upper-right:");
1714 table.attach(label, {2, 3, 0, 1}, {GTK_FILL, GTK_FILL});
1716 label = ui::Label("Lower-right:");
1718 table.attach(label, {2, 3, 1, 2}, {GTK_FILL, GTK_FILL});
1720 entry = ui::Entry();
1722 table.attach(entry, {1, 2, 0, 1});
1723 entry.dimensions(50, -1);
1724 g_object_set_data(G_OBJECT(dlg), "z01", entry);
1725 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z01);
1727 entry = ui::Entry();
1729 table.attach(entry, {1, 2, 1, 2});
1730 entry.dimensions(50, -1);
1731 g_object_set_data(G_OBJECT(dlg), "z00", entry);
1732 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z00);
1734 entry = ui::Entry();
1736 table.attach(entry, {3, 4, 0, 1});
1737 entry.dimensions(50, -1);
1738 g_object_set_data(G_OBJECT(dlg), "z11", entry);
1739 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z11);
1741 entry = ui::Entry();
1743 table.attach(entry, {3, 4, 1, 2});
1744 entry.dimensions(50, -1);
1745 g_object_set_data(G_OBJECT(dlg), "z10", entry);
1746 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &Z10);
1748 check = ui::CheckButton("Linear borders");
1750 table.attach(check, {0, 4, 2, 3});
1751 g_object_set_data(G_OBJECT(dlg), "linearborder", check);
1752 check.connect("toggled", G_CALLBACK(extents_linearborder), NULL);
1754 vbox = ui::VBox(FALSE, 10);
1756 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1758 label = ui::Label("Bitmap");
1760 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1762 label = ui::Label("");
1764 vbox.pack_start(label, FALSE, TRUE, 0);
1765 g_object_set_data(G_OBJECT(dlg), "bmp_note", label);
1767 table = ui::Table(2, 2, FALSE);
1769 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1770 vbox.pack_start(table, FALSE, TRUE, 0);
1771 gtk_table_set_row_spacings(table, 5);
1772 gtk_table_set_col_spacings(table, 5);
1774 label = ui::Label("Filename:");
1776 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1777 g_object_set_data(G_OBJECT(dlg), "bmp_text1", label);
1779 entry = ui::Entry();
1781 table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1782 g_object_set_data(G_OBJECT(dlg), "bmp_file", entry);
1783 entry.connect("focus_out_event", G_CALLBACK(bitmap_file_entryfocusout), NULL);
1785 hbox2 = ui::HBox(TRUE, 5);
1787 table.attach(hbox2, {1, 2, 1, 2}, {0, GTK_EXPAND | GTK_FILL});
1789 button = ui::Button("Browse...");
1791 hbox2.pack_start(button, FALSE, FALSE, 0);
1792 button.dimensions(60, -1);
1793 g_object_set_data(G_OBJECT(dlg), "bmp_file_browse", button);
1794 button.connect("clicked", G_CALLBACK(bitmap_browse), NULL);
1796 button = ui::Button("Reload");
1798 hbox2.pack_start(button, FALSE, FALSE, 0);
1799 button.dimensions(60, -1);
1800 g_object_set_data(G_OBJECT(dlg), "bmp_reload", button);
1801 button.connect("clicked", G_CALLBACK(bitmap_reload), NULL);
1803 table = ui::Table(2, 2, TRUE);
1805 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1806 vbox.pack_start(table, FALSE, TRUE, 0);
1807 gtk_table_set_row_spacings(table, 5);
1808 gtk_table_set_col_spacings(table, 5);
1810 label = ui::Label("Map color 0 to:");
1812 table.attach(label, {0, 1, 0, 1}, {GTK_FILL | GTK_EXPAND, GTK_FILL});
1813 g_object_set_data(G_OBJECT(dlg), "bmp_text2", label);
1814 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1815 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1817 label = ui::Label("Map color 255 to:");
1819 table.attach(label, {0, 1, 1, 2}, {GTK_FILL | GTK_EXPAND, GTK_FILL});
1820 g_object_set_data(G_OBJECT(dlg), "bmp_text3", label);
1821 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1822 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
1824 hbox2 = ui::HBox(FALSE, 5);
1826 table.attach(hbox2, {1, 2, 0, 1});
1828 entry = ui::Entry();
1830 hbox2.pack_start(entry, FALSE, FALSE, 0);
1831 entry.dimensions(50, -1);
1832 g_object_set_data(G_OBJECT(dlg), "bmp_black", entry);
1833 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &gbmp.black_value);
1835 hbox2 = ui::HBox(FALSE, 5);
1837 table.attach(hbox2, {1, 2, 1, 2});
1839 entry = ui::Entry();
1841 hbox2.pack_start(entry, FALSE, FALSE, 0);
1842 entry.dimensions(50, -1);
1843 g_object_set_data(G_OBJECT(dlg), "bmp_white", entry);
1844 entry.connect("focus_out_event", G_CALLBACK(doublevariable_entryfocusout), &gbmp.white_value);
1846 vbox = ui::VBox(FALSE, 10);
1848 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1850 label = ui::Label("Fix Points");
1852 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1854 label = ui::Label("Click on a vertex in the lower half of the preview window,\n"
1855 "then use the arrow keys or text box to assign a value.\n"
1856 "Use Ctrl+Click to select multiple vertices/toggle a\n"
1857 "selection. Use Shift+Click to select a range of vertices.\n\n"
1858 "Click \"Free\" to unlock a vertex. Vertices within \"Range\n"
1859 "affected\" will be influenced by this vertex.");
1861 vbox.pack_start(label, FALSE, TRUE, 0);
1863 table = ui::Table(3, 3, FALSE);
1865 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1866 vbox.pack_start(table, FALSE, TRUE, 0);
1867 gtk_table_set_row_spacings(table, 5);
1868 gtk_table_set_col_spacings(table, 5);
1870 label = ui::Label("Value:");
1872 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1873 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1874 g_object_set_data(G_OBJECT(dlg), "fix_value_text", label);
1876 label = ui::Label("Range affected:");
1878 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1879 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1880 g_object_set_data(G_OBJECT(dlg), "fix_range_text", label);
1882 label = ui::Label("Rate of change:");
1884 table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1885 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1886 g_object_set_data(G_OBJECT(dlg), "fix_rate_text", label);
1888 adj = ui::Adjustment(0, -65536, 65536, 1, 16, 0);
1889 adj.connect("value_changed", G_CALLBACK(fix_value_changed), NULL);
1890 spin = ui::SpinButton(adj, 1, 0);
1892 table.attach(spin, {1, 2, 0, 1}, {GTK_EXPAND, GTK_EXPAND});
1893 spin.dimensions(60, -1);
1894 g_object_set_data(G_OBJECT(dlg), "fix_value", spin);
1895 spin.connect("focus_out_event", G_CALLBACK(fix_value_entryfocusout), NULL);
1897 entry = ui::Entry();
1899 table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND, GTK_FILL});
1900 entry.dimensions(60, -1);
1901 g_object_set_data(G_OBJECT(dlg), "fix_range", entry);
1902 entry.connect("focus_out_event", G_CALLBACK(fix_range_entryfocusout), NULL);
1904 entry = ui::Entry();
1906 table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND, GTK_FILL});
1907 entry.dimensions(60, -1);
1908 g_object_set_data(G_OBJECT(dlg), "fix_rate", entry);
1909 entry.connect("focus_out_event", G_CALLBACK(fix_rate_entryfocusout), NULL);
1911 button = ui::Button("Free");
1913 table.attach(button, {2, 3, 0, 1}, {GTK_EXPAND, GTK_FILL});
1914 button.dimensions(60, -1);
1915 g_object_set_data(G_OBJECT(dlg), "fix_free", button);
1916 button.connect("clicked", G_CALLBACK(fix_free), NULL);
1918 button = ui::Button("Free All");
1920 table.attach(button, {2, 3, 1, 2}, {GTK_EXPAND, GTK_FILL});
1921 button.dimensions(60, -1);
1922 g_object_set_data(G_OBJECT(dlg), "fix_freeall", button);
1923 button.connect("clicked", G_CALLBACK(fix_freeall), NULL);
1925 vbox = ui::VBox(FALSE, 10);
1927 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1929 label = ui::Label("Texture");
1931 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
1933 // ^Fishman - Modified to add more labels and textboxes.
1934 table = ui::Table(5, 2, FALSE);
1936 vbox.pack_start(table, FALSE, TRUE, 0);
1937 gtk_table_set_row_spacings(table, 5);
1938 gtk_table_set_col_spacings(table, 5);
1940 label = ui::Label("Surface:");
1942 table.attach(label, {0, 1, 0, 1}, {GTK_FILL, GTK_FILL});
1943 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1945 label = ui::Label("Other:");
1947 table.attach(label, {0, 1, 1, 2}, {GTK_FILL, GTK_FILL});
1948 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1950 label = ui::Label("Steep:");
1952 table.attach(label, {0, 1, 2, 3}, {GTK_FILL, GTK_FILL});
1953 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1955 entry = ui::Entry();
1957 table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1958 entry.dimensions(60, -1);
1959 g_object_set_data(G_OBJECT(dlg), "texture1", entry);
1960 entry.connect("focus_out_event", G_CALLBACK(texture_entryfocusout), GINT_TO_POINTER(0));
1962 entry = ui::Entry();
1964 table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1965 entry.dimensions(60, -1);
1966 g_object_set_data(G_OBJECT(dlg), "texture2", entry);
1967 entry.connect("focus_out_event", G_CALLBACK(texture_entryfocusout), GINT_TO_POINTER(1));
1969 entry = ui::Entry();
1971 table.attach(entry, {1, 2, 2, 3}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
1972 entry.dimensions(60, -1);
1973 g_object_set_data(G_OBJECT(dlg), "texture3", entry);
1975 hbox2 = ui::HBox(FALSE, 5);
1977 vbox.pack_start(hbox2, FALSE, TRUE, 0);
1979 label = ui::Label("\"Steep\" angle:");
1981 hbox2.pack_start(label, FALSE, TRUE, 0);
1983 adj = ui::Adjustment(60, 0, 90, 1, 10, 0);
1984 spin = ui::SpinButton(adj, 1, 0);
1986 hbox2.pack_start(spin, FALSE, TRUE, 0);
1987 g_object_set_data(G_OBJECT(dlg), "tex_slant", spin);
1989 table = ui::Table(2, 4, TRUE);
1991 vbox.pack_start(table, FALSE, TRUE, 0);
1992 gtk_table_set_row_spacings(table, 5);
1993 gtk_table_set_col_spacings(table, 5);
1995 label = ui::Label("Offset <h,v>");
1997 table.attach(label, {0, 2, 0, 1}, {GTK_FILL, GTK_FILL});
1999 label = ui::Label("Scale <h,v>");
2001 table.attach(label, {2, 4, 0, 1}, {GTK_FILL, GTK_FILL});
2003 entry = ui::Entry();
2005 table.attach(entry, {0, 1, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2006 entry.dimensions(60, -1);
2007 g_object_set_data(G_OBJECT(dlg), "texoffsetx", entry);
2009 entry = ui::Entry();
2011 table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2012 entry.dimensions(60, -1);
2013 g_object_set_data(G_OBJECT(dlg), "texoffsety", entry);
2015 entry = ui::Entry();
2017 table.attach(entry, {2, 3, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2018 entry.dimensions(60, -1);
2019 g_object_set_data(G_OBJECT(dlg), "texscalex", entry);
2021 entry = ui::Entry();
2023 table.attach(entry, {3, 4, 1, 2}, {GTK_EXPAND | GTK_FILL, GTK_FILL});
2024 entry.dimensions(60, -1);
2025 g_object_set_data(G_OBJECT(dlg), "texscaley", entry);
2028 check = ui::CheckButton("Use detail brushes");
2030 vbox.pack_start(check, FALSE, TRUE, 0);
2031 g_object_set_data(G_OBJECT(dlg), "detail", check);
2032 check.connect("toggled", G_CALLBACK(texture_detail), NULL);
2034 check = ui::CheckButton("Detail hint brushes");
2036 vbox.pack_start(check, FALSE, TRUE, 0);
2037 g_object_set_data(G_OBJECT(dlg), "hint", check);
2038 check.connect("toggled", G_CALLBACK(texture_hint), NULL);
2040 // ^Fishman - Add terrain key to func_group.
2041 check = ui::CheckButton("Add terrain key");
2043 vbox.pack_start(check, FALSE, TRUE, 0);
2044 g_object_set_data(G_OBJECT(dlg), "terrain_ent", check);
2045 check.connect("toggled", G_CALLBACK(texture_terrainent), NULL);
2047 vbox = ui::VBox(FALSE, 5);
2049 hbox.pack_start(vbox, FALSE, TRUE, 0);
2051 button = ui::Button("OK");
2053 vbox.pack_start(button, FALSE, TRUE, 0);
2054 button.dimensions(60, -1);
2055 g_object_set_data(G_OBJECT(dlg), "go", button);
2056 button.connect("clicked", G_CALLBACK(main_go), NULL);
2058 label = ui::Label("Settings:");
2060 vbox.pack_start(label, FALSE, TRUE, 0);
2062 button = ui::Button("Open...");
2064 vbox.pack_start(button, FALSE, TRUE, 0);
2065 g_object_set_data(G_OBJECT(dlg), "open", button);
2066 button.connect("clicked", G_CALLBACK(main_open), NULL);
2068 button = ui::Button("Save as...");
2070 vbox.pack_start(button, FALSE, TRUE, 0);
2071 g_object_set_data(G_OBJECT(dlg), "save", button);
2072 button.connect("clicked", G_CALLBACK(main_save), NULL);
2074 button = ui::Button("Defaults");
2076 vbox.pack_start(button, FALSE, TRUE, 0);
2077 g_object_set_data(G_OBJECT(dlg), "defaults", button);
2078 button.connect("clicked", G_CALLBACK(main_defaults), NULL);
2080 button = ui::Button("About...");
2082 vbox.pack_start(button, FALSE, TRUE, 0);
2083 button.connect("clicked", G_CALLBACK(main_about), NULL);
2085 check = ui::CheckButton("Preview");
2087 vbox.pack_start(check, FALSE, TRUE, 0);
2088 check.connect("toggled", G_CALLBACK(main_preview), NULL);
2089 g_object_set_data(G_OBJECT(dlg), "main_preview", check);
2091 // ^Fishman - Antializing for the preview window.
2092 check = ui::CheckButton("Antialised lines");
2094 vbox.pack_start(check, FALSE, TRUE, 0);
2095 g_object_set_data(G_OBJECT(dlg), "main_antialiasing", check);
2096 check.connect("toggled", G_CALLBACK(main_antialiasing), NULL);
2098 for (i = 0; i < 5; i++) {
2106 FirstPassComplete = 1;
2114 HWND hwndDisplay = (HWND)NULL;
2115 HWND ghwndTab = (HWND)NULL;
2120 char GenSurfURL[40] = {"http://tarot.telefragged.com/gensurf"};
2121 char GenSurfBoard[40] = {"http://tarot.telefragged.com/board"};
2124 * AboutDlgProc - processes messages for the about dialog.
2127 qboolean CALLBACK AboutDlgProc( HWND hwnd, unsigned msg, UINT wparam, LONG lparam ){
2129 DRAWITEMSTRUCT *dis;
2136 lparam = lparam; /* turn off warning */
2140 strcpy( szText,"About " );
2141 strcat( szText,gszCaption );
2142 SetWindowText( hwnd,gszCaption );
2143 SetDlgItemText( hwnd,DLG_ABOUT_APP,szText );
2144 /* Application icon: */
2145 SendDlgItemMessage( hwnd, DLG_ABOUT_ICON,
2146 STM_SETICON, (WPARAM)(HICON)LoadIcon( ghInst,"GENSURF" ),
2149 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_URL );
2150 hdc = GetDC( hwndURL );
2151 GetTextExtentPoint( hdc,GenSurfURL,strlen( GenSurfURL ),&size );
2152 ReleaseDC( hwndURL,hdc );
2153 GetWindowRect( hwndURL,&rc );
2154 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2155 SWP_NOMOVE | SWP_NOZORDER );
2157 hwndURL = GetDlgItem( hwnd,DLG_ABOUT_BOARD );
2158 hdc = GetDC( hwndURL );
2159 GetTextExtentPoint( hdc,GenSurfBoard,strlen( GenSurfBoard ),&size );
2160 ReleaseDC( hwndURL,hdc );
2161 GetWindowRect( hwndURL,&rc );
2162 SetWindowPos( hwndURL,(HWND)NULL,0,0,size.cx,size.cy + 2,
2163 SWP_NOMOVE | SWP_NOZORDER );
2168 switch ( LOWORD( wparam ) )
2173 case DLG_ABOUT_BOARD:
2174 HTTP( GenSurfBoard );
2177 EndDialog( hwnd,1 );
2183 if ( wparam == DLG_ABOUT_URL ) {
2184 dis = (LPDRAWITEMSTRUCT)lparam;
2185 SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2186 TextOut( dis->hDC,0,0,GenSurfURL,strlen( GenSurfURL ) );
2187 GetWindowRect( dis->hwndItem,&rc );
2188 GetTextExtentPoint( dis->hDC,GenSurfURL,strlen( GenSurfURL ),&size );
2189 hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2190 SelectObject( dis->hDC,hpen );
2191 MoveToEx( dis->hDC,0,size.cy,NULL );
2192 LineTo( dis->hDC,size.cx,size.cy );
2193 SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2194 DeleteObject( hpen );
2196 else if ( wparam == DLG_ABOUT_BOARD ) {
2197 dis = (LPDRAWITEMSTRUCT)lparam;
2198 SetTextColor( dis->hDC,RGB( 0,0,255 ) );
2199 TextOut( dis->hDC,0,0,GenSurfBoard,strlen( GenSurfBoard ) );
2200 GetWindowRect( dis->hwndItem,&rc );
2201 GetTextExtentPoint( dis->hDC,GenSurfBoard,strlen( GenSurfBoard ),&size );
2202 hpen = CreatePen( PS_SOLID,0,RGB( 0,0,255 ) );
2203 SelectObject( dis->hDC,hpen );
2204 MoveToEx( dis->hDC,0,size.cy,NULL );
2205 LineTo( dis->hDC,size.cx,size.cy );
2206 SelectObject( dis->hDC,GetStockObject( BLACK_PEN ) );
2207 DeleteObject( hpen );
2212 EndDialog( hwnd,1 );
2220 } /* AboutDlgProc */
2223 if ( DialogBox( ghInst,"About", ghwnd_main, (DLGPROC)AboutDlgProc ) < 0 ) {
2225 sprintf( Text,"In About(), GetLastError()=0x%08x",GetLastError() );
2226 MessageBox( ghwnd_main,Text,"GenSurf",eMB_ICONWARNING );