2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/MenuUI/OptionsMenu.cpp $
15 * C module that contains functions to drive the Options user interface
18 * Revision 1.7 2005/10/01 22:04:58 taylor
19 * fix FS1 (de)briefing voices, the directory names are different in FS1
20 * hard code the table values so that the fs1.vp file isn't needed
21 * hard code a mission fix for sm2-08a since a have no idea how to fix it otherwise
22 * generally cleanup some FS1 code
23 * fix volume sliders in the options screen that never went all the way up
25 * Revision 1.6 2005/03/29 02:18:47 taylor
26 * Various 64-bit platform fixes
27 * Fix compiler errors with MAKE_FS1 and fix gr_set_bitmap() too
28 * Make sure that turrets can fire at asteroids for FS1 (needed for a couple missions)
29 * Streaming audio support (big thanks to Pierre Willenbrock!!)
30 * Removed dependance on strings.tbl for FS1 since we don't actually need it now
32 * Revision 1.5 2004/09/20 01:31:44 theoddone33
35 * Revision 1.4 2003/05/25 02:30:42 taylor
38 * Revision 1.3 2002/06/09 04:41:22 relnev
39 * added copyright header
41 * Revision 1.2 2002/05/26 22:06:17 relnev
42 * makefile: disable stand_gui for now.
44 * rest: staticize some globals
46 * Revision 1.1.1.1 2002/05/03 03:28:09 root
50 * 31 10/25/99 5:47p Jefff
51 * reassigned some xstr ids
53 * 30 10/14/99 2:50p Jefff
56 * 29 9/13/99 6:07p Jefff
57 * took out audiostream pausing to allow for correct volume adjustments
59 * 28 9/09/99 2:28p Jefff
60 * some detail slider #defines were switched around
62 * 27 9/08/99 2:38p Jefff
63 * sound pausing going to menu from game
65 * 26 8/05/99 3:40p Jefff
66 * hi-res text adjustments
68 * 25 8/04/99 4:06p Jefff
69 * fixed volume sliders blacking out at master volume of 1.0
71 * 24 8/02/99 6:05p Jefff
72 * failure sound on skill slider when disabled in game
74 * 23 7/19/99 3:29p Dave
75 * Fixed gamma bitmap in the options screen.
77 * 22 7/19/99 2:13p Dave
78 * Added some new strings for Heiko.
80 * 21 7/18/99 9:54p Andsager
83 * 20 7/15/99 7:15p Jefff
84 * Added sounds for skill select
86 * 19 7/15/99 4:10p Andsager
87 * Disable control_config hud_config in FS2_DEMO
89 * 18 7/15/99 9:20a Andsager
90 * FS2_DEMO initial checkin
92 * 17 7/13/99 1:15p Dave
93 * 32 bit support. Whee!
95 * 16 7/09/99 5:54p Dave
96 * Seperated cruiser types into individual types. Added tons of new
97 * briefing icons. Campaign screen.
99 * 15 6/25/99 11:59a Dave
100 * Multi options screen.
102 * 14 6/24/99 12:34a Dave
103 * Main options screen.
105 * 13 6/22/99 7:03p Dave
106 * New detail options screen.
108 * 12 6/16/99 4:06p Dave
109 * New pilot info popup. Added new draw-bitmap-as-poly function.
111 * 11 5/24/99 5:45p Dave
112 * Added detail levels to the nebula, with a decent speedup. Split nebula
113 * lightning into its own section.
115 * 10 4/02/99 4:44p Jasenw
117 * 9 2/05/99 7:22p Neilk
118 * Fixed gamma bitmap and converted coordinates for multiple resolutions
120 * 8 1/30/99 5:08p Dave
121 * More new hi-res stuff.Support for nice D3D textures.
123 * 7 12/18/98 1:13a Dave
124 * Rough 1024x768 support for Direct3D. Proper detection and usage through
127 * 6 11/30/98 1:07p Dave
128 * 16 bit conversion, first run.
130 * 5 11/05/98 5:55p Dave
131 * Big pass at reducing #includes
133 * 4 10/13/98 9:28a Dave
134 * Started neatening up freespace.h. Many variables renamed and
135 * reorganized. Added AlphaColors.[h,cpp]
137 * 3 10/09/98 2:57p Dave
138 * Starting splitting up OS stuff.
140 * 2 10/07/98 10:53a Dave
143 * 1 10/07/98 10:49a Dave
145 * 123 6/12/98 7:13p Hoffoss
146 * Fixed options screen problem where it wasn't showing tooltips.
148 * 122 6/12/98 4:52p Hoffoss
149 * Added support for special characters in in forgeign languages.
151 * 121 6/09/98 10:31a Hoffoss
152 * Created index numbers for all xstr() references. Any new xstr() stuff
153 * added from here on out should be added to the end if the list. The
154 * current list count can be found in FreeSpace.cpp (search for
157 * 120 6/05/98 9:50a Lawrance
160 * 119 6/01/98 11:43a John
161 * JAS & MK: Classified all strings for localization.
163 * 118 5/24/98 4:42p Dan
164 * AL: Fix several bugs related to pausing and enabling/disabling event
167 * 117 5/20/98 5:18p John
168 * Made the gamma box draw as a bitmap, not a bunch of pixels. Speeds up
169 * the menu dramatically.
171 * 116 5/19/98 1:21p Duncan
172 * Use 'InterfacePalette' instad of 'OptionsMainPalette'
174 * 115 5/18/98 9:14p Dave
175 * Put in network config files support.
177 * 114 5/18/98 5:16p Hoffoss
178 * Changed code to use new palette Jasen told me to use.
180 * 113 5/16/98 3:40p Lawrance
181 * Don't restore the original details unless they've been stored!
183 * 112 5/13/98 10:03a Mitri
184 * AL: Fix some bugs as a result of recent rearranging of code
186 * 111 5/13/98 12:24a Lawrance
187 * Only load required bitmaps and masks for the options screen
189 * 110 5/08/98 3:52p Hoffoss
190 * Fixed placement of gamma graphic.
192 * 109 5/07/98 12:41p Hoffoss
193 * Added joystick deadzone slider support and mouse on/off support.
195 * 108 5/06/98 8:06p Dave
196 * Made standalone reset properly under weird conditions. Tweak
197 * optionsmulti screen. Upped MAX_WEAPONS to 350. Put in new launch
198 * countdown anim. Minro ui fixes/tweaks.
200 * 107 5/05/98 8:38p Hoffoss
201 * Added sensitivity adjustment to options menu and made it save to pilot
204 * 106 4/27/98 9:00a Jasen
205 * Updated coords for button change.
207 * 105 4/25/98 3:33p Allender
208 * do exit confirmation
210 * 104 4/22/98 12:34a Dave
211 * Make sure hud config and control config buttons draw properly in all
212 * tab modes. Make small tab buttons light up correctly in multi options
215 * 103 4/21/98 12:14a Allender
216 * disable skill level buttons for multiplayer games
218 * 102 4/20/98 6:04p Dave
219 * Implement multidata cache flushing and xferring mission files to
220 * multidata. Make sure observers can't change hud config. Fix pilot image
221 * viewing in popup. Put in game status field. Tweaked multi options.
223 * 101 4/18/98 12:45p Dave
224 * Aesthetic changes to multi options screen. Put in missing exit button.
227 * 100 4/17/98 5:27p Dave
228 * More work on the multi options screen. Fixed many minor ui todo bugs.
235 #include "grinternal.h"
237 #include "missionscreencommon.h"
239 #include "gamesequence.h"
241 #include "managepilot.h"
242 #include "freespace.h"
245 #include "eventmusic.h"
246 #include "mainhallmenu.h"
247 #include "audiostr.h"
251 #include "popupdead.h"
252 #include "missionbriefcommon.h"
253 #include "optionsmenu.h"
254 #include "optionsmenumulti.h"
257 #include "osregistry.h"
258 #include "alphacolors.h"
264 // will display a notification warning message
265 #define OPTIONS_NOTIFY_TIME 3500
266 #define OPTIONS_NOTIFY_Y 450
269 #define NUM_BUTTONS 26
271 #define NUM_BUTTONS 24
275 #define NUM_COMMONS 10
279 #define OPTIONS_TAB 0
280 #define MULTIPLAYER_TAB 1
281 #define DETAIL_LEVELS_TAB 2
282 #define ABORT_GAME_BUTTON 3
283 #define CONTROL_CONFIG_BUTTON 4
284 #define HUD_CONFIG_BUTTON 5
285 #define ACCEPT_BUTTON 6
287 #define BRIEF_VOICE_OFF 7
288 #define BRIEF_VOICE_ON 8
291 #define GAMMA_DOWN 11
294 // detail level screen buttons
295 #define PLANETS_ON 13
296 #define PLANETS_OFF 14
297 #define HUD_TARGETVIEW_RENDER_ON 15
298 #define HUD_TARGETVIEW_RENDER_OFF 16
301 #define WEAPON_EXTRAS_ON 17
302 #define WEAPON_EXTRAS_OFF 18
304 #define ENGINE_GLOWS_ON 17
305 #define ENGINE_GLOWS_OFF 18
306 #define ALPHA_EFFECTS_ON 24 // ** intentionally out of order **
307 #define ALPHA_EFFECTS_OFF 25 // ** intentionally out of order **
310 #define LOW_DETAIL_N 19
311 #define MEDIUM_DETAIL_N 20
312 #define HIGH_DETAIL_N 21
313 #define VERY_HIGH_DETAIL_N 22
314 #define CUSTOM_DETAIL_N 23
316 #define REPEAT (1<<0)
317 #define NO_MOUSE_OVER_SOUND (1<<1)
319 // indicies for options coordinates
320 #define OPTIONS_X_COORD 0
321 #define OPTIONS_Y_COORD 1
322 #define OPTIONS_W_COORD 2
323 #define OPTIONS_H_COORD 3
325 struct options_buttons {
326 const char *filename;
331 UI_BUTTON button; // because we have a class inside this struct, we need the constructor below..
333 options_buttons(const char *name, int x1, int y1, int h, int t, int f = 0) : filename(name), x(x1), y(y1), hotspot(h), tab(t), flags(f) {}
336 static options_buttons Buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = {
339 options_buttons("OPa_00", 84, 25, 0, -1), // options tab
340 options_buttons("OPa_01", 173, 25, 1, -1), // multiplayer tab
341 options_buttons("OPa_02", 256, 25, 2, -1), // detail levels tab
342 options_buttons("OPa_03", 6, 380, 3, -1), // abort game button
343 options_buttons("OPa_05", 448, 335, 5, -1), // control config button
344 options_buttons("OPa_06", 541, 335, 6, -1), // hud config
345 options_buttons("OPa_07", 560, 411, 7, -1), // accept button
347 options_buttons("OPa_58", 39, 99, 58, OPTIONS_TAB, 2), // Briefing / debriefing voice toggle off
348 options_buttons("OPa_59", 104, 99, 59, OPTIONS_TAB, 2), // Briefing / debriefing voice toggle on
349 options_buttons("OPa_62", 359, 274, 62, OPTIONS_TAB, 2), // Mouse off
350 options_buttons("OPa_63", 424, 274, 63, OPTIONS_TAB, 2), // Mouse on
351 options_buttons("OPa_56", 451, 79, 56, OPTIONS_TAB, 1), // Gamma Down
352 options_buttons("OPa_57", 484, 79, 57, OPTIONS_TAB, 1), // Gamma Up
354 options_buttons("OPc_40", 321, 237, 40, DETAIL_LEVELS_TAB, 2), // Planets On (Nebula)
355 options_buttons("OPc_39", 264, 237, 39, DETAIL_LEVELS_TAB, 2), // Planets Off (Nebula)
356 options_buttons("OPc_42", 321, 284, 42, DETAIL_LEVELS_TAB, 2), // Target View Rendering On
357 options_buttons("OPc_41", 264, 284, 41, DETAIL_LEVELS_TAB, 2), // Target View Rendering Off
358 options_buttons("OPc_44", 321, 331, 44, DETAIL_LEVELS_TAB, 2), // Weapon Extras On
359 options_buttons("OPc_43", 264, 331, 43, DETAIL_LEVELS_TAB, 2), // Weapon Extras Off
361 options_buttons("OPc_50", 516, 194, 50, DETAIL_LEVELS_TAB, 2), // Low Preset Detail
362 options_buttons("OPc_51", 516, 213, 51, DETAIL_LEVELS_TAB, 2), // Medium Preset Detail
363 options_buttons("OPc_52", 516, 232, 52, DETAIL_LEVELS_TAB, 2), // High Preset Detail
364 options_buttons("OPc_53", 498, 251, 53, DETAIL_LEVELS_TAB, 2), // Highest Preset Detail
365 options_buttons("OPc_54", 516, 270, 54, DETAIL_LEVELS_TAB, 2), // Custom Detail
367 options_buttons("OPc_38", 321, 190, 38, DETAIL_LEVELS_TAB, 2), // Engine Glow On
368 options_buttons("OPc_37", 264, 190, 37, DETAIL_LEVELS_TAB, 2), // Engine Glow Off
370 options_buttons("OPT_00", 17, 2, 0, -1), // options tab
371 options_buttons("OPT_01", 102, 2, 1, -1), // multiplayer tab
372 options_buttons("OPT_02", 170, 2, 2, -1), // detail levels tab
373 options_buttons("OPT_03", 10, 444, 3, -1), // abort game button
374 options_buttons("OPT_04", 411, 444, 4, -1), // control config button
375 options_buttons("OPT_05", 506, 444, 5, -1), // hud config
376 options_buttons("OPT_06", 576, 434, 6, -1), // accept button
378 options_buttons("OMB_07", 51, 74, 7, OPTIONS_TAB, 2), // Briefing / debriefing voice toggle off
379 options_buttons("OMB_08", 106, 74, 8, OPTIONS_TAB, 2), // Briefing / debriefing voice toggle on
380 options_buttons("OMB_18", 51, 266, 18, OPTIONS_TAB, 2), // Mouse off
381 options_buttons("OMB_19", 106, 266, 19, OPTIONS_TAB, 2), // Mouse on
382 options_buttons("OMB_26", 578, 149, 26, OPTIONS_TAB, 1), // Gamma Down
383 options_buttons("OMB_27", 607, 149, 27, OPTIONS_TAB, 1), // Gamma Up
385 options_buttons("ODB_21", 597, 261, 21, DETAIL_LEVELS_TAB, 2), // Planets On
386 options_buttons("ODB_20", 539, 261, 20, DETAIL_LEVELS_TAB, 2), // Planets Off
387 options_buttons("ODB_23", 597, 307, 23, DETAIL_LEVELS_TAB, 2), // Target View Rendering On
388 options_buttons("ODB_22", 539, 307, 22, DETAIL_LEVELS_TAB, 2), // Target View Rendering Off
389 options_buttons("ODB_25", 597, 354, 25, DETAIL_LEVELS_TAB, 2), // Weapon Extras On
390 options_buttons("ODB_24", 539, 354, 24, DETAIL_LEVELS_TAB, 2), // Weapon Extras Off
392 options_buttons("ODB_14", 614, 76, 14, DETAIL_LEVELS_TAB, 2), // Low Preset Detail
393 options_buttons("ODB_15", 614, 96, 15, DETAIL_LEVELS_TAB, 2), // Medium Preset Detail
394 options_buttons("ODB_16", 614, 114, 16, DETAIL_LEVELS_TAB, 2), // High Preset Detail
395 options_buttons("ODB_17", 614, 133, 17, DETAIL_LEVELS_TAB, 2), // Highest Preset Detail
396 options_buttons("ODB_18", 614, 152, 18, DETAIL_LEVELS_TAB, 2), // Custom Detail
400 options_buttons("2_OPT_00", 27, 4, 0, -1), // options tab
401 options_buttons("2_OPT_01", 164, 4, 1, -1), // multiplayer tab
402 options_buttons("2_OPT_02", 272, 4, 2, -1), // detail levels tab
403 options_buttons("2_OPT_03", 16, 711, 3, -1), // abort game
404 options_buttons("2_OPT_04", 657, 711, 4, -1), // control config button
405 options_buttons("2_OPT_05", 809, 711, 5, -1), // hud config button
406 options_buttons("2_OPT_06", 922, 694, 6, -1), // accept button
408 options_buttons("2_OMB_07", 81, 118, 7, OPTIONS_TAB, 2), // Briefing / debriefing voice toggle off
409 options_buttons("2_OMB_08", 170, 118, 8, OPTIONS_TAB, 2), // Briefing / debriefing voice toggle on
410 options_buttons("2_OMB_18", 81, 425, 18, OPTIONS_TAB, 2), // Mouse off
411 options_buttons("2_OMB_19", 170, 425, 19, OPTIONS_TAB, 2), // Mouse on
412 options_buttons("2_OMB_26", 925, 238, 26, OPTIONS_TAB, 1), // Gamma Down
413 options_buttons("2_OMB_27", 971, 238, 27, OPTIONS_TAB, 1), // Gamma Up
415 options_buttons("2_ODB_21", 956, 417, 21, DETAIL_LEVELS_TAB, 2), // Planets On
416 options_buttons("2_ODB_20", 863, 417, 20, DETAIL_LEVELS_TAB, 2), // Planets Off
417 options_buttons("2_ODB_23", 956, 492, 23, DETAIL_LEVELS_TAB, 2), // Target View Rendering On
418 options_buttons("2_ODB_22", 863, 492, 22, DETAIL_LEVELS_TAB, 2), // Target View Rendering Off
419 options_buttons("2_ODB_25", 956, 567, 25, DETAIL_LEVELS_TAB, 2), // Weapon Extras On
420 options_buttons("2_ODB_24", 863, 567, 24, DETAIL_LEVELS_TAB, 2), // Weapon Extras Off
422 options_buttons("2_ODB_14", 983, 122, 14, DETAIL_LEVELS_TAB, 2), // Low Preset Detail
423 options_buttons("2_ODB_15", 983, 153, 15, DETAIL_LEVELS_TAB, 2), // Medium Preset Detail
424 options_buttons("2_ODB_16", 983, 183, 16, DETAIL_LEVELS_TAB, 2), // High Preset Detail
425 options_buttons("2_ODB_17", 983, 213, 17, DETAIL_LEVELS_TAB, 2), // Highest Preset Detail
426 options_buttons("2_ODB_18", 983, 243, 18, DETAIL_LEVELS_TAB, 2), // Custom Detail
427 #ifdef MAKE_FS1 // just filler
428 options_buttons("OPc_38", 321, 290, 38, DETAIL_LEVELS_TAB, 2), // Engine Glow On
429 options_buttons("OPc_37", 264, 290, 37, DETAIL_LEVELS_TAB, 2), // Engine Glow Off
434 #define NUM_OPTIONS_SLIDERS 7
435 #define OPT_SOUND_VOLUME_SLIDER 0
436 #define OPT_MUSIC_VOLUME_SLIDER 1
437 #define OPT_VOICE_VOLUME_SLIDER 2
438 #define OPT_MOUSE_SENS_SLIDER 3
439 #define OPT_JOY_SENS_SLIDER 4
440 #define OPT_JOY_DEADZONE_SLIDER 5
441 #define OPT_SKILL_SLIDER 6
443 op_sliders Options_sliders[GR_NUM_RESOLUTIONS][NUM_OPTIONS_SLIDERS] = {
446 // slider, right arrow, left arrow
447 // s(name), s(x), s(y), s(?), s(?), s(h), s(?), s(?), ra(name), ra(h), ra(x), ra(y), la(name), la(h), la(x), la(y)
448 op_sliders("OPa_09", 53, 160, -1, -1, 9, 20, 11,
449 "OPa_10", 10, 245, 159,
450 "OPa_08", 8, 29, 159), // sound fx volume slider
451 op_sliders("OPa_17", 53, 195, -1, -1, 17, 20, 11,
452 "OPa_18", 18, 245, 194,
453 "OPa_16", 16, 29, 194), // music volume slider
454 op_sliders("OPa_20", 53, 229, -1, -1, 20, 20, 11,
455 "OPa_21", 21, 245, 228,
456 "OPa_19", 19, 29, 228), // voice volume slider
457 op_sliders("OPa_64", 358, 301, -1, -1, 64, 20, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // mouse sensitivity
458 op_sliders("OPa_60", 358, 194, -1, -1, 60, 20, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // joystick sensitivity
459 op_sliders("OPa_61", 358, 226, -1, -1, 61, 20, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // joystick deadzone
460 op_sliders("OPa_11", 28, 285, -1, -1, -1, 42, 5, NULL, -1, -1, -1, NULL, -1, -1, -1) // skill
462 op_sliders("OMB_10", 31, 139, -1, -1, 10, 20, 10,
463 "OMB_11", 11, 226, 137,
464 "OMB_09", 9, 4, 137 ), // sound fx volume slider
465 op_sliders("OMB_13", 31, 174, -1, -1, 13, 20, 10,
466 "OMB_14", 14, 226, 172,
467 "OMB_12", 12, 4, 172 ), // music volume slider
468 op_sliders("OMB_16", 31, 209, -1, -1, 16, 20, 10,
469 "OMB_17", 17, 226, 206,
470 "OMB_15", 15, 4, 206 ), // voice volume slider
471 op_sliders("OMB_20", 6, 316, -1, -1, 20, 20, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // mouse sensitivity
472 op_sliders("OMB_28", 440, 259, -1, -1, 28, 20, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // joystick sensitivity
473 op_sliders("OMB_29", 440, 290, -1, -1, 29, 20, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // joystick deadzone
474 op_sliders("OMB_21", 440, 75, -1, -1, 21, 36, 5, NULL, -1, -1, -1, NULL, -1, -1, -1)
478 op_sliders("2_OMB_10", 50, 223, -1, -1, 10, 32, 10,
479 "2_OMB_11", 11, 361, 219,
480 "2_OMB_09", 9, 7, 219 ), // sound fx volume slider
481 op_sliders("2_OMB_13", 50, 281, -1, -1, 13, 32, 10,
482 "2_OMB_14", 14, 361, 275,
483 "2_OMB_12", 12, 7, 275 ), // music volume slider
484 op_sliders("2_OMB_16", 50, 335, -1, -1, 16, 32, 10,
485 "2_OMB_17", 17, 361, 330,
486 "2_OMB_15", 15, 7, 330 ), // voice volume slider
487 op_sliders("2_OMB_20", 9, 505, -1, -1, 20, 32, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // mouse sensitivity
488 op_sliders("2_OMB_28", 704, 414, -1, -1, 28, 32, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // joystick sensitivity
489 op_sliders("2_OMB_29", 704, 464, -1, -1, 29, 32, 10, NULL, -1, -1, -1, NULL, -1, -1, -1), // joystick deadzone
490 op_sliders("2_OMB_21", 704, 120, -1, -1, 21, 60, 5, NULL, -1, -1, -1, NULL, -1, -1, -1)
495 const char *filename;
496 const char *mask_filename;
500 } Backgrounds[GR_NUM_RESOLUTIONS][NUM_TABS] = {
503 { "OptionsMain", "OptionsMain-M", -1, -1 },
504 { "OptionsMulti", "OptionsMulti-M", -1, -1 },
505 { "OptionsDetail", "OptionsDetail-M", -1, -1 },
508 { "2_OptionsMain", "2_OptionsMain-M", -1, -1 },
509 { "2_OptionsMulti", "2_OptionsMulti-M", -1, -1 },
510 { "2_OptionsDetail", "2_OptionsDetail-M", -1, -1 },
516 static int Options_menu_inited = 0;
517 static int Options_multi_inited = 0;
518 static int Options_detail_inited = 0;
519 static int Button_bms[NUM_COMMONS][MAX_BMAPS_PER_GADGET];
521 static UI_WINDOW Ui_window;
522 UI_GADGET Options_bogus;
524 static int Backup_skill_level;
525 static float Backup_sound_volume;
526 static float Backup_music_volume;
527 static float Backup_voice_volume;
529 static int Backup_briefing_voice_enabled;
530 static int Backup_use_mouse_to_fly;
532 static int Sound_volume_int;
533 static int Music_volume_int;
534 static int Voice_volume_int;
536 static int Voice_vol_handle = -1;
537 int Options_notify_stamp = -1;
538 char Options_notify_string[200];
541 static const float VOL_SLIDER_MAX = 9.0f;
543 static const float VOL_SLIDER_MAX = 10.0f;
546 // called whenever accept is hit
547 // do any processing, etc in here.
548 void options_accept();
549 void options_force_button_frame(int n, int frame_num);
551 extern float Freespace_gamma;
553 void options_add_notify(const char *str);
554 void options_notify_do_frame();
556 int Options_gamma_coords[GR_NUM_RESOLUTIONS][4] = {
561 435, 179, 195, 28 // GR_640
565 692, 287, 308, 44 // GR_1024
569 #define MAX_GAMMA_BITMAP_SIZE 17500
571 int Options_gamma_num_coords[GR_NUM_RESOLUTIONS][4] = {
576 489, 159, 65, 17 // GR_640
580 779, 254, 65, 17 // GR_1024
584 int Options_skills_text_coords[GR_NUM_RESOLUTIONS][4] = {
589 468, 104, 155, 10 // GR_640
593 750, 169, 246, 21 // GR_1024
598 // ---------------------------------------------------------------------------------------------------------
599 // DETAIL LEVEL OPTIONS definitions BEGIN
603 #define NUM_DETAIL_SLIDERS 9
605 #define NUM_DETAIL_SLIDERS 8
609 #define DETAIL_DISTANCE_SLIDER 0
610 #define NEBULA_DETAIL_SLIDER 1
611 #define HARDWARE_TEXTURES_SLIDER 2
612 #define NUM_PARTICLES_SLIDER 6
613 #define SHARD_CULLING_SLIDER 3
614 #define SHIELD_DETAIL_SLIDER 4
615 #define NUM_STARS_SLIDER 5
616 #define LIGHTING_SLIDER 7
618 #define DETAIL_DISTANCE_SLIDER 0
619 #define NEBULA_DETAIL_SLIDER 1
620 #define HARDWARE_TEXTURES_SLIDER 2
621 #define NUM_PARTICLES_SLIDER 3
622 #define SHARD_CULLING_SLIDER 4
623 #define SHIELD_DETAIL_SLIDER 5
624 #define NUM_STARS_SLIDER 6
625 #define LIGHTING_SLIDER 7
627 #define WEAPON_RENDERING_SLIDER 8
629 op_sliders Detail_sliders[GR_NUM_RESOLUTIONS][NUM_DETAIL_SLIDERS] = {
632 op_sliders("OPc_29", 38, 96, -1, -1, 29, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // model detail
633 op_sliders("OPc_30", 38, 143, -1, -1, 30, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // nebula detail
634 op_sliders("OPc_31", 38, 176, -1, -1, 31, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // textures
635 op_sliders("OPc_36", 273, 143, -1, -1, 36, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // particles
636 op_sliders("Opc_33", 38, 284, -1, -1, 33, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // impact effects
637 op_sliders("OPc_34", 38, 333, -1, -1, 34, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // shield hit
638 op_sliders("OPc_35", 273, 96, -1, -1, 35, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // stars
639 op_sliders("OPc_45", 496, 96, -1, -1, 45, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // lighting
640 op_sliders("OPc_32", 38, 223, -1, -1, 32, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // weapon rendering - doesn't actually do anything
642 op_sliders("ODB_07", 21, 71, -1, -1, 7, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // model detail
643 op_sliders("ODB_08", 21, 119, -1, -1, 8, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // nebula detail
644 op_sliders("ODB_09", 21, 166, -1, -1, 9, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // textures
645 op_sliders("ODB_10", 21, 212, -1, -1, 10, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // particles
646 op_sliders("ODB_11", 21, 260, -1, -1, 11, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // debris
647 op_sliders("ODB_12", 21, 307, -1, -1, 12, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // shield hit
648 op_sliders("ODB_13", 21, 354, -1, -1, 13, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // stars
649 op_sliders("ODB_19", 518, 212, -1, -1, 19, 20, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // lighting
653 op_sliders("2_ODB_07", 34, 114, -1, -1, 7, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // model detail
654 op_sliders("2_ODB_08", 34, 190, -1, -1, 8, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // nebula detail
655 op_sliders("2_ODB_09", 34, 265, -1, -1, 9, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // textures
656 op_sliders("2_ODB_10", 34, 340, -1, -1, 10, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // particles
657 op_sliders("2_ODB_11", 34, 416, -1, -1, 11, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // debris
658 op_sliders("2_ODB_12", 34, 492, -1, -1, 12, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // shield hit
659 op_sliders("2_ODB_13", 34, 567, -1, -1, 13, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // stars
660 op_sliders("2_ODB_19", 829, 340, -1, -1, 19, 32, 5, NULL, -1, -1, -1, NULL, -1, -1, -1), // lighting
661 #ifdef MAKE_FS1 // filler
662 op_sliders("none", -1, -1, -1, -1, -1, -1, -1, NULL, -1, -1, -1, NULL, -1, -1, -1),
666 int Detail_slider_pos[NUM_DETAIL_SLIDERS];
667 detail_levels Detail_original; // backup of Detail settings when screen is first entered
668 UI_GADGET Detail_bogus;
669 void options_detail_init();
670 void options_detail_hide_stuff();
671 void options_detail_unhide_stuff();
672 void options_detail_do_frame();
673 void options_detail_set_level(int level);
677 #define OPTIONS_NUM_TEXT 49
679 UI_XSTR Options_text[GR_NUM_RESOLUTIONS][OPTIONS_NUM_TEXT] = {
682 { "Options", 1036, 10, 35, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][OPTIONS_TAB].button },
683 { "Multi", 1042, 97, 35, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][MULTIPLAYER_TAB].button },
684 { "Detail", 1351, 166, 35, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][DETAIL_LEVELS_TAB].button },
685 { "Exit", 1059, 8, 417, UI_XSTR_COLOR_PINK, -1, &Buttons[0][ABORT_GAME_BUTTON].button },
686 { "Game", 1412, 8, 430, UI_XSTR_COLOR_PINK, -1, &Buttons[0][ABORT_GAME_BUTTON].button },
687 { "Control", 1352, 409, 418, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][CONTROL_CONFIG_BUTTON].button },
688 { "Config", 1353, 409, 430, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][CONTROL_CONFIG_BUTTON].button },
689 { "HUD", 1354, 504, 418, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][HUD_CONFIG_BUTTON].button },
690 { "Config", 1415, 504, 430, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][HUD_CONFIG_BUTTON].button },
691 { "Accept", 1035, 573, 412, UI_XSTR_COLOR_PINK, -1, &Buttons[0][ACCEPT_BUTTON].button },
693 // text for the detail level screen
694 { "Preset Detail Levels", 1355, 455, 56, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
695 { "Low", 1160, 570, 82, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][LOW_DETAIL_N].button },
696 { "Medium", 1161, 550, 100, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][MEDIUM_DETAIL_N].button },
697 { "High", 1162, 568, 120, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][HIGH_DETAIL_N].button },
698 { "Very High", 1163, 530, 139, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][VERY_HIGH_DETAIL_N].button },
699 { "Custom", 1356, 546, 158, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][CUSTOM_DETAIL_N].button },
700 { "Off", 1286, 509, 267, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][PLANETS_OFF].button },
701 { "On", 1285, 573, 267, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][PLANETS_ON].button },
702 { "Off", 1286, 509, 314, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][HUD_TARGETVIEW_RENDER_OFF].button },
703 { "On", 1285, 573, 314, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][HUD_TARGETVIEW_RENDER_ON].button },
704 { "Off", 1286, 509, 361, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][WEAPON_EXTRAS_OFF].button },
705 { "On", 1285, 573, 361, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][WEAPON_EXTRAS_ON].button },
706 { "Planets/Backgrounds", 1357, 455, 244, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
707 { "Target View Rendering", 1358, 446, 291, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
708 { "Weapon Extras", 1359, 497, 338, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
709 { "Model Detail", 1360, 27, 56, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
710 { "Nebula Detail", 1361, 27, 103, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
711 { "3D Hardware Textures", 1362, 27, 150, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
712 { "Particles", 1363, 27, 197, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
713 { "Impact Effects", 1364, 27, 244, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
714 { "Shield Hit Effects", 1365, 27, 291, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
715 { "Stars", 1366, 27, 338, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
716 { "Lighting", 1367, 549, 197, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
718 // main options screen text
719 { "Briefing Voice", 1368, 14, 58, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
720 { "Off", 1286, 20, 81, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][BRIEF_VOICE_OFF].button },
721 { "On", 1285, 83, 81, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][BRIEF_VOICE_ON].button },
722 { "Volume", 1369, 14, 111, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
723 { "Effects", 1370, 20, 130, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
724 { "Music", 1371, 20, 165, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
725 { "Voice", 1372, 20, 199, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
726 { "Mouse", 1373, 14, 249, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
727 { "Off", 1286, 20, 273, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][MOUSE_OFF].button },
728 { "On", 1285, 83, 273, UI_XSTR_COLOR_GREEN, -1, &Buttons[0][MOUSE_ON].button },
729 { "Sensitivity", 1529, 20, 297, UI_XSTR_COLOR_GREEN, -1, &Options_sliders[0][OPT_MOUSE_SENS_SLIDER].slider },
730 { "Skill Level", 1509, 533, 58, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
731 { "Brightness", 1375, 532, 133, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
732 { "Joystick", 1376, 556, 231, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
733 { "Sensitivity", 1374, 538, 250, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
734 { "Deadzone", 1377, 538, 281, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
738 { "Options", 1036, 16, 57, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][OPTIONS_TAB].button },
739 { "Multi", 1042, 172, 57, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][MULTIPLAYER_TAB].button },
740 { "Detail", 1351, 283, 57, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][DETAIL_LEVELS_TAB].button },
741 { "Exit", 1059, 13, 685, UI_XSTR_COLOR_PINK, -1, &Buttons[1][ABORT_GAME_BUTTON].button },
742 { "Game", 1412, 13, 696, UI_XSTR_COLOR_PINK, -1, &Buttons[1][ABORT_GAME_BUTTON].button },
743 { "Control", 1352, 655, 685, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][CONTROL_CONFIG_BUTTON].button },
744 { "Config", 1353, 655, 696, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][CONTROL_CONFIG_BUTTON].button },
745 { "HUD", 1354, 806, 685, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][HUD_CONFIG_BUTTON].button },
746 { "Config", 1415, 806, 696, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][HUD_CONFIG_BUTTON].button },
747 { "Accept", 1035, 927, 672, UI_XSTR_COLOR_PINK, -1, &Buttons[1][ACCEPT_BUTTON].button },
749 // text for the detail level screen
750 { "Preset Detail Levels", 1355, 809, 90, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
751 { "Low", 1160, 944, 131, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][LOW_DETAIL_N].button },
752 { "Medium", 1161, 924, 161, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][MEDIUM_DETAIL_N].button },
753 { "High", 1162, 942, 192, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][HIGH_DETAIL_N].button },
754 { "Very High", 1163, 903, 222, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][VERY_HIGH_DETAIL_N].button },
755 { "Custom", 1356, 922, 252, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][CUSTOM_DETAIL_N].button },
756 { "Off", 1286, 835, 427, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][PLANETS_OFF].button },
757 { "On", 1285, 936, 427, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][PLANETS_ON].button },
758 { "Off", 1286, 835, 503, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][HUD_TARGETVIEW_RENDER_OFF].button },
759 { "On", 1285, 936, 503, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][HUD_TARGETVIEW_RENDER_ON].button },
760 { "Off", 1286, 835, 578, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][WEAPON_EXTRAS_OFF].button },
761 { "On", 1285, 936, 578, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][WEAPON_EXTRAS_ON].button },
762 { "Planets/Backgrounds", 1357, 808, 391, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
763 { "Target View Rendering", 1358, 799, 466, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
764 { "Weapon Extras", 1359, 850, 542, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
765 { "Model Detail", 1360, 44, 99, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][DETAIL_DISTANCE_SLIDER].slider },
766 { "Nebula Detail", 1361, 44, 175, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][NEBULA_DETAIL_SLIDER].slider },
767 { "3D Hardware Textures", 1362, 44, 250, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][HARDWARE_TEXTURES_SLIDER].slider },
768 { "Particles", 1363, 44, 325, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][NUM_PARTICLES_SLIDER].slider },
769 { "Impact Effects", 1364, 44, 401, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][SHARD_CULLING_SLIDER].slider },
770 { "Shield Hit Effects", 1365, 44, 476, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][SHIELD_DETAIL_SLIDER].slider },
771 { "Stars", 1366, 44, 552, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][NUM_STARS_SLIDER].slider },
772 { "Lighting", 1367, 903, 326, UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][LIGHTING_SLIDER].slider },
774 // main options screen text
775 { "Briefing Voice", 1368, 23, 93, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
776 { "Off", 1286, 32, 130, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][BRIEF_VOICE_OFF].button },
777 { "On", 1285, 134, 130, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][BRIEF_VOICE_ON].button },
778 { "Volume", 1369, 23, 178, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
779 { "Effects", 1370, 33, 209, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
780 { "Music", 1371, 33, 264, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
781 { "Voice", 1372, 33, 319, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
782 { "Mouse", 1373, 23, 399, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
783 { "Off", 1286, 32, 437, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][MOUSE_OFF].button },
784 { "On", 1285, 134, 437, UI_XSTR_COLOR_GREEN, -1, &Buttons[1][MOUSE_ON].button },
785 { "Sensitivity", 1529, 34, 477, UI_XSTR_COLOR_GREEN, -1, &Options_sliders[1][OPT_MOUSE_SENS_SLIDER].slider },
786 { "Skill Level", 1509, 854, 93, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
787 { "Brightness", 1375, 852, 214, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
788 { "Joystick", 1376, 891, 370, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
789 { "Sensitivity", 1374, 861, 400, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
790 { "Deadzone", 1377, 861, 451, UI_XSTR_COLOR_GREEN, -1, &Options_bogus },
797 // DETAIL LEVEL tab definitions END
798 // ---------------------------------------------------------------------------------------------------------
800 void options_play_voice_clip()
804 if ( snd_is_playing(Voice_vol_handle) ) {
805 snd_stop(Voice_vol_handle);
809 snd_id = snd_load(&Snds_iface[SND_VOICE_SLIDER_CLIP]);
810 Voice_vol_handle = snd_play_raw( snd_id, 0.0f, 1.0f, SND_PRIORITY_SINGLE_INSTANCE );
813 void options_add_notify(const char *str)
815 SDL_strlcpy(Options_notify_string, str, SDL_arraysize(Options_notify_string));
816 Options_notify_stamp = timestamp(OPTIONS_NOTIFY_TIME);
819 void options_notify_do_frame()
823 if (Options_notify_stamp != -1) {
824 if (timestamp_elapsed(Options_notify_stamp)) {
825 Options_notify_stamp = -1;
828 gr_get_string_size(&w, &h, Options_notify_string);
829 gr_printf((gr_screen.max_w - w) / 2, OPTIONS_NOTIFY_Y, Options_notify_string);
835 void options_set_bmaps(int btn, int bm_index)
839 for (j=0; j<MAX_BMAPS_PER_GADGET; j++){
840 Buttons[gr_screen.res][btn].button.bmap_ids[j] = Button_bms[bm_index][j];
845 void options_tab_setup(int set_palette)
851 if (Tab != MULTIPLAYER_TAB) {
852 SDL_assert(Backgrounds[gr_screen.res][Tab].mask >= 0);
853 Ui_window.set_mask_bmap(Backgrounds[gr_screen.res][Tab].mask, Backgrounds[gr_screen.res][Tab].mask_filename);
856 for (i=0; i<256; i++){
860 // activate, deactivate any necessary controls
861 for (i=0; i<NUM_BUTTONS; i++) {
862 if ( ((Buttons[gr_screen.res][i].tab == Tab) || (Buttons[gr_screen.res][i].tab == -1)) && !flags[Buttons[gr_screen.res][i].hotspot] ) {
863 flags[Buttons[gr_screen.res][i].hotspot] = 1;
864 Buttons[gr_screen.res][i].button.enable();
865 if (Buttons[gr_screen.res][i].filename)
866 Buttons[gr_screen.res][i].button.unhide();
869 Buttons[gr_screen.res][i].button.disable();
870 Buttons[gr_screen.res][i].button.hide();
874 // maybe enable/disable controls based upon current tab
875 if (Tab == OPTIONS_TAB) {
876 for(i=0; i<NUM_OPTIONS_SLIDERS; i++){
877 Options_sliders[gr_screen.res][i].slider.enable();
878 Options_sliders[gr_screen.res][i].slider.unhide();
881 for(i=0; i<NUM_OPTIONS_SLIDERS; i++){
882 Options_sliders[gr_screen.res][i].slider.hide();
883 Options_sliders[gr_screen.res][i].slider.disable();
887 if( ((Game_mode & GM_IN_MISSION) && (!popupdead_is_active())) || (Game_mode & GM_MULTIPLAYER) ){
888 Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.disable();
889 Ui_window.use_hack_to_get_around_stupid_problem_flag = 0;
892 // do other special processing
894 case MULTIPLAYER_TAB:
895 #if !defined(DEMO) && !defined(OEM_BUILD) && !defined(__EMSCRIPTEN__) // not for FS2_DEMO
896 options_multi_select();
898 // need to hide the hud config and control config buttons
899 Buttons[gr_screen.res][CONTROL_CONFIG_BUTTON].button.hide();
900 Buttons[gr_screen.res][HUD_CONFIG_BUTTON].button.hide();
905 case DETAIL_LEVELS_TAB:
906 options_detail_unhide_stuff();
911 // call this function to close down, do other processing of data in the tab that's being left
912 void options_tab_close()
915 case MULTIPLAYER_TAB:
916 #if !defined(DEMO) && !defined(OEM_BUILD) && !defined(__EMSCRIPTEN__) // not for FS2_DEMO
917 options_multi_unselect();
921 case DETAIL_LEVELS_TAB:
922 options_detail_hide_stuff();
927 void options_change_tab(int n)
931 #if defined(DEMO) || defined(OEM_BUILD) || defined(__EMSCRIPTEN__) // not for FS2_DEMO
932 if (n == MULTIPLAYER_TAB) {
933 game_feature_not_in_demo_popup();
939 case MULTIPLAYER_TAB:
940 if ( !Options_multi_inited ) {
942 #if !defined(DEMO) && !defined(OEM_BUILD) && !defined(__EMSCRIPTEN__) // not for FS2_DEMO
943 options_multi_init(&Ui_window);
944 options_multi_unselect();
946 Options_multi_inited = 1;
951 case DETAIL_LEVELS_TAB:
952 if (!Options_detail_inited) {
953 // init detail levels
954 options_detail_init();
955 options_detail_hide_stuff();
956 Options_detail_inited = 1;
962 // if we're going into the main screen
963 if(n == OPTIONS_TAB){
964 Options_bogus.enable();
965 Options_bogus.unhide();
966 for(idx=0; idx<NUM_OPTIONS_SLIDERS; idx++){
967 Options_sliders[gr_screen.res][idx].slider.enable();
968 Options_sliders[gr_screen.res][idx].slider.unhide();
971 Options_bogus.hide();
972 Options_bogus.disable();
973 for(idx=0; idx<NUM_OPTIONS_SLIDERS; idx++){
974 Options_sliders[gr_screen.res][idx].slider.hide();
975 Options_sliders[gr_screen.res][idx].slider.disable();
979 if (n != MULTIPLAYER_TAB) {
980 if (Backgrounds[gr_screen.res][n].mask < 0) {
981 gamesnd_play_iface(SND_GENERAL_FAIL);
989 options_tab_setup(1);
990 gamesnd_play_iface(SND_SCREEN_MODE_PRESSED);
993 void set_sound_volume()
995 main_hall_reset_ambient_vol();
998 void set_music_volume()
1000 event_music_set_volume_all(Master_event_music_volume);
1003 void set_voice_volume()
1005 audiostream_set_volume_all(Master_voice_volume, ASF_VOICE);
1008 void options_cancel_exit()
1010 Master_sound_volume = Backup_sound_volume;
1012 Master_event_music_volume = Backup_music_volume;
1014 Master_voice_volume = Backup_voice_volume;
1017 if(!(Game_mode & GM_MULTIPLAYER)){
1018 Game_skill_level = Backup_skill_level;
1021 Briefing_voice_enabled = Backup_briefing_voice_enabled;
1022 Use_mouse_to_fly = Backup_use_mouse_to_fly;
1024 if ( Options_detail_inited ) {
1025 Detail = Detail_original;
1028 gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
1031 void options_change_gamma(float delta)
1033 Freespace_gamma += delta;
1034 if (Freespace_gamma < 0.1f) {
1035 Freespace_gamma = 0.1f;
1036 gamesnd_play_iface(SND_GENERAL_FAIL);
1038 } else if (Freespace_gamma > 5.0f) {
1039 Freespace_gamma = 5.0f;
1040 gamesnd_play_iface(SND_GENERAL_FAIL);
1043 gamesnd_play_iface(SND_USER_SELECT);
1046 gr_set_gamma(Freespace_gamma);
1049 static void options_abort_game_callback(int choice)
1054 gameseq_post_event(GS_EVENT_QUIT_GAME);
1058 void options_button_pressed(int n)
1062 case MULTIPLAYER_TAB:
1063 case DETAIL_LEVELS_TAB:
1065 options_change_tab(n);
1069 case ABORT_GAME_BUTTON:
1070 gamesnd_play_iface(SND_USER_SELECT);
1071 popup_callback(options_abort_game_callback, PF_NO_NETWORKING | PF_BODY_BIG, 2, POPUP_NO, POPUP_YES, XSTR( "Exit Game?", 374));
1074 case CONTROL_CONFIG_BUTTON:
1075 gamesnd_play_iface(SND_SWITCH_SCREENS);
1076 gameseq_post_event(GS_EVENT_CONTROL_CONFIG);
1079 case HUD_CONFIG_BUTTON:
1080 #if defined(FS2_DEMO)
1081 game_feature_not_in_demo_popup();
1083 // can't go to the hud config screen when a multiplayer observer
1084 if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_OBSERVER)){
1085 gamesnd_play_iface(SND_GENERAL_FAIL);
1086 options_add_notify(XSTR( "Cannot use HUD config when an observer!", 375));
1090 gamesnd_play_iface(SND_SWITCH_SCREENS);
1091 gameseq_post_event(GS_EVENT_HUD_CONFIG);
1099 // BEGIN - detail level tab buttons
1101 case HUD_TARGETVIEW_RENDER_ON:
1102 Detail.targetview_model = 1;
1103 gamesnd_play_iface(SND_USER_SELECT);
1106 case HUD_TARGETVIEW_RENDER_OFF:
1107 Detail.targetview_model = 0;
1108 gamesnd_play_iface(SND_USER_SELECT);
1112 Detail.planets_suns = 1;
1113 gamesnd_play_iface(SND_USER_SELECT);
1117 Detail.planets_suns = 0;
1118 gamesnd_play_iface(SND_USER_SELECT);
1122 case WEAPON_EXTRAS_ON:
1123 Detail.weapon_extras = 1;
1124 gamesnd_play_iface(SND_USER_SELECT);
1127 case WEAPON_EXTRAS_OFF:
1128 Detail.weapon_extras = 0;
1129 gamesnd_play_iface(SND_USER_SELECT);
1132 case ENGINE_GLOWS_ON:
1133 Detail.engine_glows = 1;
1134 gamesnd_play_iface(SND_USER_SELECT);
1137 case ENGINE_GLOWS_OFF:
1138 Detail.engine_glows = 0;
1139 gamesnd_play_iface(SND_USER_SELECT);
1142 case ALPHA_EFFECTS_ON:
1143 Detail.alpha_effects = 1;
1144 gamesnd_play_iface(SND_USER_SELECT);
1147 case ALPHA_EFFECTS_OFF:
1148 Detail.alpha_effects = 0;
1149 gamesnd_play_iface(SND_USER_SELECT);
1154 options_detail_set_level(0);
1155 gamesnd_play_iface(SND_USER_SELECT);
1158 case MEDIUM_DETAIL_N:
1159 options_detail_set_level(1);
1160 gamesnd_play_iface(SND_USER_SELECT);
1164 options_detail_set_level(2);
1165 gamesnd_play_iface(SND_USER_SELECT);
1168 case VERY_HIGH_DETAIL_N:
1169 options_detail_set_level(3);
1170 gamesnd_play_iface(SND_USER_SELECT);
1173 case CUSTOM_DETAIL_N:
1174 options_detail_set_level(-1);
1175 gamesnd_play_iface(SND_USER_SELECT);
1177 // END - detail level tab buttons
1180 options_change_gamma(-0.05f);
1184 options_change_gamma(0.05f);
1187 case BRIEF_VOICE_ON:
1188 Briefing_voice_enabled = 1;
1189 gamesnd_play_iface(SND_USER_SELECT);
1192 case BRIEF_VOICE_OFF:
1193 Briefing_voice_enabled = 0;
1194 gamesnd_play_iface(SND_USER_SELECT);
1198 Use_mouse_to_fly = 1;
1199 gamesnd_play_iface(SND_USER_SELECT);
1203 Use_mouse_to_fly = 0;
1204 gamesnd_play_iface(SND_USER_SELECT);
1209 void options_sliders_update()
1212 if (Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos != Sound_volume_int) {
1213 Sound_volume_int = Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos;
1214 Master_sound_volume = ((float) (Sound_volume_int) / VOL_SLIDER_MAX);
1216 gamesnd_play_iface(SND_USER_SELECT);
1220 if (Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos != Music_volume_int) {
1221 Music_volume_int = Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos;
1222 Master_event_music_volume = ((float) (Music_volume_int) / VOL_SLIDER_MAX);
1223 if (Master_event_music_volume > 0.0f) {
1224 event_music_enable();
1228 gamesnd_play_iface(SND_USER_SELECT);
1232 if (Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos != Voice_volume_int) {
1233 Voice_volume_int = Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos;
1234 Master_voice_volume = ((float) (Voice_volume_int) / VOL_SLIDER_MAX);
1236 options_play_voice_clip();
1239 if (Mouse_sensitivity != Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos) {
1240 Mouse_sensitivity = Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos;
1241 gamesnd_play_iface(SND_USER_SELECT);
1244 if (Joy_sensitivity != Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos) {
1245 Joy_sensitivity = Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos;
1246 gamesnd_play_iface(SND_USER_SELECT);
1249 if (Dead_zone_size != Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5) {
1250 Dead_zone_size = Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5;
1251 gamesnd_play_iface(SND_USER_SELECT);
1254 if (Game_skill_level != Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos) {
1255 Game_skill_level = Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos;
1256 gamesnd_play_iface(SND_USER_SELECT);
1260 void options_accept()
1262 // apply the selected multiplayer options
1263 if ( Options_multi_inited ) {
1264 #if !defined(DEMO) && !defined(OEM_BUILD) && !defined(__EMSCRIPTEN__) // not for FS2_DEMO
1265 options_multi_accept();
1269 // If music is zero volume, disable
1270 if ( Master_event_music_volume <= 0.0f ) {
1271 // event_music_disable();
1272 event_music_level_close();
1275 // apply other options (display options, etc)
1276 // note: return in here (and play failed sound) if they can't accept yet for some reason
1278 gamesnd_play_iface(SND_COMMIT_PRESSED);
1279 gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
1282 void options_load_background_and_mask(int tab)
1284 SDL_assert(tab == OPTIONS_TAB || tab == DETAIL_LEVELS_TAB );
1285 Backgrounds[gr_screen.res][tab].bitmap = bm_load(Backgrounds[gr_screen.res][tab].filename);
1286 Backgrounds[gr_screen.res][tab].mask = bm_load(Backgrounds[gr_screen.res][tab].mask_filename);
1289 int Gamma_last_set = -1;
1290 int Gamma_colors_inited = 0;
1292 void options_menu_init()
1297 SDL_assert(!Options_menu_inited);
1299 // pause all sounds, since we could get here through the game
1300 beam_pause_sounds();
1301 //audiostream_pause_all();
1304 Gamma_last_set = -1;
1306 common_set_interface_palette("InterfacePalette"); // set the interface palette
1307 Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0);
1309 for (i=0; i<PLANETS_ON; i++) {
1310 b = &Buttons[gr_screen.res][i];
1312 b->button.create(&Ui_window, "", b->x, b->y, 60, 30, b->flags & REPEAT, 1);
1313 // set up callback for when a mouse first goes over a button
1315 b->button.set_bmaps(b->filename);
1316 if ( !(b->flags & NO_MOUSE_OVER_SOUND) ) {
1317 b->button.set_highlight_action(common_play_highlight_sound);
1324 b->button.link_hotspot(b->hotspot);
1325 if (i < NUM_COMMONS) {
1326 for (j=0; j<MAX_BMAPS_PER_GADGET; j++){
1327 Button_bms[i][j] = b->button.bmap_ids[j];
1333 // add all xstr text
1334 for(i=0; i<OPTIONS_NUM_TEXT; i++){
1335 Ui_window.add_XSTR(&Options_text[gr_screen.res][i]);
1340 Detail_bogus.base_create(&Ui_window, UI_KIND_ICON, 0, 0, 0, 0);
1341 Options_bogus.base_create(&Ui_window, UI_KIND_ICON, 0, 0, 0, 0);
1343 Buttons[gr_screen.res][GAMMA_DOWN].button.set_hotkey(SDLK_COMMA);
1344 Buttons[gr_screen.res][GAMMA_UP].button.set_hotkey(SDLK_PERIOD);
1347 Skill_control.first_frame = bm_load_animation("OPa_11", &Skill_control.total_frames);
1348 if (Skill_control.first_frame < 0) {
1349 Error(LOCATION, "Could not load OPa_11.ani\n");
1354 for (i=0; i<NUM_TABS; i++) {
1355 Backgrounds[gr_screen.res][i].bitmap = -1;
1356 Backgrounds[gr_screen.res][i].mask = -1;
1359 options_load_background_and_mask(OPTIONS_TAB);
1360 options_tab_setup(0);
1362 Backup_skill_level = Game_skill_level;
1363 Backup_sound_volume = Master_sound_volume;
1364 Backup_music_volume = Master_event_music_volume;
1365 Backup_voice_volume = Master_voice_volume;
1366 Backup_briefing_voice_enabled = Briefing_voice_enabled;
1367 Backup_use_mouse_to_fly = Use_mouse_to_fly;
1370 for ( i = 0; i < NUM_OPTIONS_SLIDERS; i++ ) {
1371 Options_sliders[gr_screen.res][i].slider.create(&Ui_window, Options_sliders[gr_screen.res][i].x, Options_sliders[gr_screen.res][i].y,
1372 Options_sliders[gr_screen.res][i].dots, Options_sliders[gr_screen.res][i].filename,
1373 Options_sliders[gr_screen.res][i].hotspot, Options_sliders[gr_screen.res][i].right_filename, Options_sliders[gr_screen.res][i].right_mask, Options_sliders[gr_screen.res][i].right_x, Options_sliders[gr_screen.res][i].right_y,
1374 Options_sliders[gr_screen.res][i].left_filename, Options_sliders[gr_screen.res][i].left_mask, Options_sliders[gr_screen.res][i].left_x, Options_sliders[gr_screen.res][i].left_y,
1375 Options_sliders[gr_screen.res][i].dot_w);
1378 // maybe disable the skill slider
1379 if( ((Game_mode & GM_IN_MISSION) && (!popupdead_is_active())) || (Game_mode & GM_MULTIPLAYER) ) {
1380 Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.disable();
1381 Ui_window.use_hack_to_get_around_stupid_problem_flag = 0;
1384 // setup slider values
1385 // note slider scale is 0-9, while Master_ values calc with 1-10 scale (hence the -1)
1386 Sound_volume_int = Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos = (int) (Master_sound_volume * VOL_SLIDER_MAX + 0.5f);
1387 Music_volume_int = Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos = (int) (Master_event_music_volume * VOL_SLIDER_MAX + 0.5f);
1388 Voice_volume_int = Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos = (int) (Master_voice_volume * VOL_SLIDER_MAX + 0.5f);
1389 Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos = Joy_sensitivity;
1390 Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos = Dead_zone_size / 5;
1391 Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos = Mouse_sensitivity;
1392 Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos = Game_skill_level;
1394 Gamma_colors_inited = 0;
1396 // used to allow all keystrokes, even when called from a demo playback
1398 Options_menu_inited = 1;
1400 // hide options crap
1401 options_detail_hide_stuff();
1404 void options_menu_close()
1408 SDL_assert(Options_menu_inited);
1410 for (i=0; i<NUM_TABS; i++) {
1411 if (Backgrounds[gr_screen.res][i].bitmap >= 0){
1412 bm_unload(Backgrounds[gr_screen.res][i].bitmap);
1414 if ((Backgrounds[gr_screen.res][i].mask >= 0) && (i != Tab)){ // Ui_window.destroy() expects to release current tab's mask.
1415 bm_unload(Backgrounds[gr_screen.res][i].mask);
1419 if ( Voice_vol_handle >= 0 ) {
1420 snd_stop(Voice_vol_handle);
1421 Voice_vol_handle = -1;
1424 #if !defined(DEMO) && !defined(OEM_BUILD) && !defined(__EMSCRIPTEN__) // not for FS2_DEMO
1425 options_multi_close();
1428 Ui_window.destroy();
1429 common_free_interface_palette(); // restore game palette
1433 // unpause all sounds, since we could be headed back to the game
1434 beam_unpause_sounds();
1435 //audiostream_unpause_all();
1437 Options_menu_inited = 0;
1438 Options_multi_inited = 0;
1439 Options_detail_inited = 0;
1445 void draw_gamma_box()
1449 // NEILK: i had to change this declaration because the size is determined dynamically. I just picked an arbitrary large number to data size (although we should always be using less)
1450 // TODO: change MAX size to maximum size for a 1024x768 bitmap
1451 // ushort Gamma_data[Options_gamma_coords[gr_screen.res][OPTIONS_W_COORD]*Options_gamma_coords[gr_screen.res][OPTIONS_H_COORD]*2];
1452 ushort Gamma_data[MAX_GAMMA_BITMAP_SIZE];
1454 v = fl2i( pow(0.5f, 1.0f / Freespace_gamma) * 255.0f );
1464 ushort clr_full_white = 0;
1465 ushort clr_half_white = 0;
1468 BM_SELECT_TEX_FORMAT();
1471 r = g = b = a = 255;
1472 bm_set_components((ubyte*)&clr_full_white, &r, &g, &b, &a);
1475 r = g = b = (ubyte)v;
1476 bm_set_components((ubyte*)&clr_half_white, &r, &g, &b, &a);
1478 ushort *dptr = Gamma_data;
1479 for (y=0; y<Options_gamma_coords[gr_screen.res][OPTIONS_H_COORD]; y++) {
1480 for (x=0; x<Options_gamma_coords[gr_screen.res][OPTIONS_W_COORD]; x++) {
1482 *dptr = clr_half_white;
1484 if ((x & 1) == (y & 1)) {
1485 *dptr = clr_full_white;
1494 // always go back to screen format
1495 BM_SELECT_SCREEN_FORMAT();
1497 // if we're in bitmap poly mode
1498 int Gamma_bitmap = bm_create( 16, Options_gamma_coords[gr_screen.res][OPTIONS_W_COORD], Options_gamma_coords[gr_screen.res][OPTIONS_H_COORD], Gamma_data );
1499 gr_set_bitmap(Gamma_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1500 gr_bitmap( Options_gamma_coords[gr_screen.res][OPTIONS_X_COORD], Options_gamma_coords[gr_screen.res][OPTIONS_Y_COORD] );
1502 bm_release( Gamma_bitmap );
1508 void options_menu_do_frame(float frametime)
1512 SDL_assert(Options_menu_inited);
1513 k = Ui_window.process() & ~KEY_DEBUGGED;
1515 case KEY_SHIFTED | SDLK_TAB:
1516 case SDLK_LEFT: // activate previous tab
1521 options_change_tab(i);
1525 case SDLK_RIGHT: // activate next tab
1526 // check to see if the multiplayer options screen wants to eat the tab kay
1527 if ((k == SDLK_TAB) && (Tab == MULTIPLAYER_TAB)) {
1528 if (options_multi_eat_tab()) {
1537 options_change_tab(i);
1541 if (Tab == OPTIONS_TAB) {
1542 gamesnd_play_iface(SND_SWITCH_SCREENS);
1543 gameseq_post_event(GS_EVENT_CONTROL_CONFIG);
1549 if (Tab == OPTIONS_TAB) {
1550 gamesnd_play_iface(SND_SWITCH_SCREENS);
1551 gameseq_post_event(GS_EVENT_HUD_CONFIG);
1557 // if(Tab != MULTIPLAYER_TAB){
1558 options_cancel_exit();
1562 case KEY_CTRLED | SDLK_RETURN:
1573 for (i=0; i<NUM_BUTTONS; i++) {
1574 if (Buttons[gr_screen.res][i].button.pressed())
1575 options_button_pressed(i);
1578 options_sliders_update();
1580 // if we're in the multiplayer options tab, get the background bitmap from the options multi module
1581 if(Tab == MULTIPLAYER_TAB){
1582 i = options_multi_background_bitmap();
1584 i = Backgrounds[gr_screen.res][Tab].bitmap;
1587 GR_MAYBE_CLEAR_RES(i);
1589 gr_set_bitmap(i, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1595 // NOTE : this must be done here so that any special drawing crap we do is not overwritten by the UI_WINDOW::draw() call
1596 // do specific processing for the multiplayer tab
1598 case MULTIPLAYER_TAB:
1599 #if !defined(DEMO) && !defined(OEM_BUILD) && !defined(__EMSCRIPTEN__) // not for FS2_DEMO
1600 options_multi_do(k);
1604 case DETAIL_LEVELS_TAB:
1605 options_detail_do_frame();
1609 Game_skill_level = Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos;
1613 // handle the displaying of any notification messages
1614 options_notify_do_frame();
1616 for (i=0; i<NUM_TABS; i++){
1617 if (Buttons[gr_screen.res][i].button.button_down()){
1622 if (i == NUM_TABS /*&& (Tab != MULTIPLAYER_TAB)*/ ){
1623 Buttons[gr_screen.res][Tab].button.draw_forced(2);
1626 if (Tab == OPTIONS_TAB) {
1627 // draw correct frame for briefing voice radio buttons
1628 if (Briefing_voice_enabled) {
1629 options_force_button_frame(BRIEF_VOICE_ON, 2);
1630 options_force_button_frame(BRIEF_VOICE_OFF, 0);
1633 options_force_button_frame(BRIEF_VOICE_OFF, 2);
1634 options_force_button_frame(BRIEF_VOICE_ON, 0);
1637 if (Use_mouse_to_fly) {
1638 options_force_button_frame(MOUSE_ON, 2);
1639 options_force_button_frame(MOUSE_OFF, 0);
1642 options_force_button_frame(MOUSE_OFF, 2);
1643 options_force_button_frame(MOUSE_ON, 0);
1647 gr_get_string_size(&w, NULL, Skill_level_names(Game_skill_level));
1648 x = Options_skills_text_coords[gr_screen.res][OPTIONS_X_COORD];
1649 y = Options_skills_text_coords[gr_screen.res][OPTIONS_Y_COORD];
1650 gr_set_color_fast(&Color_bright_white);
1651 gr_string(x + (Options_skills_text_coords[gr_screen.res][OPTIONS_W_COORD] / 2) - (w/2), y, Skill_level_names(Game_skill_level));
1655 //==============================================================================
1656 // Draw the gamma adjustment grid.
1657 if (Tab == OPTIONS_TAB) {
1661 gr_set_color_fast(&Color_white);
1662 x = Options_gamma_num_coords[gr_screen.res][OPTIONS_X_COORD]; // + Options_gamma_num_coords[gr_screen.res][OPTIONS_W_COORD] / 2 - 12;
1663 y = Options_gamma_num_coords[gr_screen.res][OPTIONS_Y_COORD]; // + Options_gamma_num_coords[gr_screen.res][OPTIONS_H_COORD] / 2 - gr_get_font_height() / 2;
1665 gr_printf(x, y, NOX("%.2f"), Freespace_gamma);
1666 //gr_printf(GAMMA_TEXT_X, GAMMA_TEXT_Y, "Squint and try to make the above\nbar appear to be one solid color.\nThere are more 'ranges' to see\nif you set this in Glide mode.");
1668 //==============================================================================
1670 // maybe blit a waveform
1671 if(Tab == MULTIPLAYER_TAB){
1672 options_multi_vox_process_waveform();
1675 /* Debug code: Graphs the joystick range scaling
1677 int joy_get_scaled_reading(int raw, int axn);
1680 gr_set_color_fast(&Color_white);
1681 for (x=0; x<256; x+=16) {
1682 gr_line(x + 15, 0, x + 15, 255);
1683 gr_line(0, x + 15, 255, x + 15);
1686 gr_set_color_fast(&Color_bright_white);
1687 for (x=0; x<256; x++) {
1688 y = joy_get_scaled_reading(x * 256, 0) / 512;
1689 gr_line(x, 128, x, 128 + y);
1697 // ---------------------------------------------------------------------------------------------------------
1698 // DETAIL LEVEL OPTIONS definitions BEGIN
1701 void options_detail_synch_sliders()
1703 Detail_slider_pos[DETAIL_DISTANCE_SLIDER] = Detail_sliders[gr_screen.res][DETAIL_DISTANCE_SLIDER].slider.pos = Detail.detail_distance;
1704 Detail_slider_pos[NEBULA_DETAIL_SLIDER] = Detail_sliders[gr_screen.res][NEBULA_DETAIL_SLIDER].slider.pos = Detail.nebula_detail;
1705 Detail_slider_pos[HARDWARE_TEXTURES_SLIDER] = Detail_sliders[gr_screen.res][HARDWARE_TEXTURES_SLIDER].slider.pos = Detail.hardware_textures;
1706 Detail_slider_pos[SHARD_CULLING_SLIDER] = Detail_sliders[gr_screen.res][SHARD_CULLING_SLIDER].slider.pos = Detail.num_small_debris;
1707 Detail_slider_pos[SHIELD_DETAIL_SLIDER] = Detail_sliders[gr_screen.res][SHIELD_DETAIL_SLIDER].slider.pos = Detail.shield_effects;
1708 Detail_slider_pos[NUM_STARS_SLIDER] = Detail_sliders[gr_screen.res][NUM_STARS_SLIDER].slider.pos = Detail.num_stars;
1709 Detail_slider_pos[NUM_PARTICLES_SLIDER] = Detail_sliders[gr_screen.res][NUM_PARTICLES_SLIDER].slider.pos = Detail.num_particles;
1710 Detail_slider_pos[LIGHTING_SLIDER] = Detail_sliders[gr_screen.res][LIGHTING_SLIDER].slider.pos = Detail.lighting;
1712 // this doesn't do anything since it's affects are included in the other sliders now
1713 // so lets just max it out to avoid it looking bad at 0
1714 Detail_slider_pos[WEAPON_RENDERING_SLIDER] = Detail_sliders[gr_screen.res][WEAPON_RENDERING_SLIDER].slider.pos = Detail_sliders[gr_screen.res][WEAPON_RENDERING_SLIDER].dots - 1;
1718 void options_detail_init()
1723 Detail_original = Detail;
1725 options_load_background_and_mask(DETAIL_LEVELS_TAB);
1727 for (i=PLANETS_ON; i<NUM_BUTTONS; i++) {
1728 b = &Buttons[gr_screen.res][i];
1730 b->button.create(&Ui_window, "", b->x, b->y, 60, 30, b->flags & REPEAT, 1);
1731 // set up callback for when a mouse first goes over a button
1733 b->button.set_bmaps(b->filename);
1734 if ( !(b->flags & NO_MOUSE_OVER_SOUND) ) {
1735 b->button.set_highlight_action(common_play_highlight_sound);
1742 b->button.link_hotspot(b->hotspot);
1745 // create detail level sliders
1746 for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1747 Detail_sliders[gr_screen.res][i].slider.create(&Ui_window, Detail_sliders[gr_screen.res][i].x, Detail_sliders[gr_screen.res][i].y,
1748 Detail_sliders[gr_screen.res][i].dots, Detail_sliders[gr_screen.res][i].filename,
1749 Detail_sliders[gr_screen.res][i].hotspot, Detail_sliders[gr_screen.res][i].right_filename, Detail_sliders[gr_screen.res][i].right_mask, Detail_sliders[gr_screen.res][i].right_x, Detail_sliders[gr_screen.res][i].right_y,
1750 Detail_sliders[gr_screen.res][i].left_filename, Detail_sliders[gr_screen.res][i].left_mask, Detail_sliders[gr_screen.res][i].left_x, Detail_sliders[gr_screen.res][i].left_y,
1751 Detail_sliders[gr_screen.res][i].dot_w);
1754 // init the actual slider positions and our internal positions
1755 options_detail_synch_sliders();
1758 void options_detail_sliders_update()
1762 for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1763 if ( Detail_sliders[gr_screen.res][i].slider.pos != Detail_slider_pos[i] ) {
1764 Detail_slider_pos[i] = Detail_sliders[gr_screen.res][i].slider.pos;
1765 gamesnd_play_iface(SND_USER_SELECT);
1769 // set Detail based on slider positions
1770 Detail.detail_distance = Detail_sliders[gr_screen.res][DETAIL_DISTANCE_SLIDER].slider.pos;
1772 // modify nebula stuff
1773 Detail.nebula_detail = Detail_sliders[gr_screen.res][NEBULA_DETAIL_SLIDER].slider.pos;
1774 neb2_set_detail_level(Detail.nebula_detail);
1776 Detail.hardware_textures = Detail_sliders[gr_screen.res][HARDWARE_TEXTURES_SLIDER].slider.pos;
1777 Detail.num_small_debris = Detail_sliders[gr_screen.res][SHARD_CULLING_SLIDER].slider.pos;
1778 Detail.shield_effects = Detail_sliders[gr_screen.res][SHIELD_DETAIL_SLIDER].slider.pos;
1779 Detail.num_stars = Detail_sliders[gr_screen.res][NUM_STARS_SLIDER].slider.pos;
1780 Detail.num_particles = Detail_sliders[gr_screen.res][NUM_PARTICLES_SLIDER].slider.pos;
1781 Detail.lighting = Detail_sliders[gr_screen.res][LIGHTING_SLIDER].slider.pos;
1784 void options_detail_hide_stuff()
1788 for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1789 Detail_sliders[gr_screen.res][i].slider.disable();
1790 Detail_sliders[gr_screen.res][i].slider.hide();
1793 // this will hide text unassociated with any real control
1794 Detail_bogus.hide();
1797 void options_detail_unhide_stuff()
1801 for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1802 Detail_sliders[gr_screen.res][i].slider.enable();
1803 Detail_sliders[gr_screen.res][i].slider.unhide();
1806 // this will hide text unassociated with any real control
1807 Detail_bogus.unhide();
1810 void options_force_button_frame(int n, int frame_num)
1812 if ( !Buttons[gr_screen.res][n].button.button_down() ) {
1813 Buttons[gr_screen.res][n].button.draw_forced(frame_num);
1817 // called once per frame to set lit buttons
1818 void options_detail_do_frame()
1820 options_detail_sliders_update();
1822 // force on/off buttons to draw their correct setting
1824 if ( Detail.targetview_model ) {
1825 options_force_button_frame(HUD_TARGETVIEW_RENDER_ON, 2);
1826 options_force_button_frame(HUD_TARGETVIEW_RENDER_OFF, 0);
1828 options_force_button_frame(HUD_TARGETVIEW_RENDER_OFF, 2);
1829 options_force_button_frame(HUD_TARGETVIEW_RENDER_ON, 0);
1832 if ( Detail.planets_suns == 1 ) {
1833 options_force_button_frame(PLANETS_ON, 2);
1834 options_force_button_frame(PLANETS_OFF, 0);
1836 options_force_button_frame(PLANETS_OFF, 2);
1837 options_force_button_frame(PLANETS_ON, 0);
1841 if ( Detail.weapon_extras) {
1842 options_force_button_frame(WEAPON_EXTRAS_ON, 2);
1843 options_force_button_frame(WEAPON_EXTRAS_OFF, 0);
1845 options_force_button_frame(WEAPON_EXTRAS_OFF, 2);
1846 options_force_button_frame(WEAPON_EXTRAS_ON, 0);
1849 if ( Detail.engine_glows ) {
1850 options_force_button_frame(ENGINE_GLOWS_ON, 2);
1851 options_force_button_frame(ENGINE_GLOWS_OFF, 0);
1853 options_force_button_frame(ENGINE_GLOWS_OFF, 2);
1854 options_force_button_frame(ENGINE_GLOWS_ON, 0);
1857 if ( Detail.alpha_effects ) {
1858 options_force_button_frame(ALPHA_EFFECTS_ON, 2);
1859 options_force_button_frame(ALPHA_EFFECTS_OFF, 0);
1861 options_force_button_frame(ALPHA_EFFECTS_OFF, 2);
1862 options_force_button_frame(ALPHA_EFFECTS_ON, 0);
1868 if ( Detail.setting >= 0 ) {
1869 current_detail = current_detail_level();
1870 Detail.setting = current_detail;
1872 current_detail = -1;
1875 options_force_button_frame(LOW_DETAIL_N, 0);
1876 options_force_button_frame(MEDIUM_DETAIL_N, 0);
1877 options_force_button_frame(HIGH_DETAIL_N, 0);
1878 options_force_button_frame(VERY_HIGH_DETAIL_N, 0);
1879 options_force_button_frame(CUSTOM_DETAIL_N, 0);
1881 switch ( current_detail ) {
1883 options_force_button_frame(CUSTOM_DETAIL_N, 2);
1886 options_force_button_frame(LOW_DETAIL_N, 2);
1889 options_force_button_frame(MEDIUM_DETAIL_N, 2);
1892 options_force_button_frame(HIGH_DETAIL_N, 2);
1895 options_force_button_frame(VERY_HIGH_DETAIL_N, 2);
1900 // Set all the detail settings to a predefined level
1901 void options_detail_set_level(int level)
1903 detail_level_set(level);
1904 options_detail_synch_sliders();
1908 // DETAIL LEVEL tab definitions END
1909 // ---------------------------------------------------------------------------------------------------------