]> icculus.org git repositories - taylor/freespace2.git/blob - src/menuui/optionsmenu.cpp
bunch of cleanup
[taylor/freespace2.git] / src / menuui / optionsmenu.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
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
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/MenuUI/OptionsMenu.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C module that contains functions to drive the Options user interface
16  *
17  * $Log$
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
24  *
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
31  *
32  * Revision 1.5  2004/09/20 01:31:44  theoddone33
33  * GCC 3.4 fixes.
34  *
35  * Revision 1.4  2003/05/25 02:30:42  taylor
36  * Freespace 1 support
37  *
38  * Revision 1.3  2002/06/09 04:41:22  relnev
39  * added copyright header
40  *
41  * Revision 1.2  2002/05/26 22:06:17  relnev
42  * makefile: disable stand_gui for now.
43  *
44  * rest: staticize some globals
45  *
46  * Revision 1.1.1.1  2002/05/03 03:28:09  root
47  * Initial import.
48  *
49  * 
50  * 31    10/25/99 5:47p Jefff
51  * reassigned some xstr ids
52  * 
53  * 30    10/14/99 2:50p Jefff
54  * localization fixes
55  * 
56  * 29    9/13/99 6:07p Jefff
57  * took out audiostream pausing to allow for correct volume adjustments
58  * 
59  * 28    9/09/99 2:28p Jefff
60  * some detail slider #defines were switched around
61  * 
62  * 27    9/08/99 2:38p Jefff
63  * sound pausing going to menu from game
64  * 
65  * 26    8/05/99 3:40p Jefff
66  * hi-res text adjustments
67  * 
68  * 25    8/04/99 4:06p Jefff
69  * fixed volume sliders blacking out at master volume of 1.0
70  * 
71  * 24    8/02/99 6:05p Jefff
72  * failure sound on skill slider when disabled in game
73  * 
74  * 23    7/19/99 3:29p Dave
75  * Fixed gamma bitmap in the options screen.
76  * 
77  * 22    7/19/99 2:13p Dave
78  * Added some new strings for Heiko.
79  * 
80  * 21    7/18/99 9:54p Andsager
81  * Demo build clean up
82  * 
83  * 20    7/15/99 7:15p Jefff
84  * Added sounds for skill select
85  * 
86  * 19    7/15/99 4:10p Andsager
87  * Disable control_config hud_config in FS2_DEMO
88  * 
89  * 18    7/15/99 9:20a Andsager
90  * FS2_DEMO initial checkin
91  * 
92  * 17    7/13/99 1:15p Dave
93  * 32 bit support. Whee!
94  * 
95  * 16    7/09/99 5:54p Dave
96  * Seperated cruiser types into individual types. Added tons of new
97  * briefing icons. Campaign screen.
98  * 
99  * 15    6/25/99 11:59a Dave
100  * Multi options screen.
101  * 
102  * 14    6/24/99 12:34a Dave
103  * Main options screen.
104  * 
105  * 13    6/22/99 7:03p Dave
106  * New detail options screen.
107  * 
108  * 12    6/16/99 4:06p Dave
109  * New pilot info popup. Added new draw-bitmap-as-poly function.
110  * 
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.
114  * 
115  * 10    4/02/99 4:44p Jasenw
116  * 
117  * 9     2/05/99 7:22p Neilk
118  * Fixed gamma bitmap and converted coordinates for multiple resolutions
119  * 
120  * 8     1/30/99 5:08p Dave
121  * More new hi-res stuff.Support for nice D3D textures.
122  * 
123  * 7     12/18/98 1:13a Dave
124  * Rough 1024x768 support for Direct3D. Proper detection and usage through
125  * the launcher.
126  * 
127  * 6     11/30/98 1:07p Dave
128  * 16 bit conversion, first run.
129  * 
130  * 5     11/05/98 5:55p Dave
131  * Big pass at reducing #includes
132  * 
133  * 4     10/13/98 9:28a Dave
134  * Started neatening up freespace.h. Many variables renamed and
135  * reorganized. Added AlphaColors.[h,cpp]
136  * 
137  * 3     10/09/98 2:57p Dave
138  * Starting splitting up OS stuff.
139  * 
140  * 2     10/07/98 10:53a Dave
141  * Initial checkin.
142  * 
143  * 1     10/07/98 10:49a Dave
144  * 
145  * 123   6/12/98 7:13p Hoffoss
146  * Fixed options screen problem where it wasn't showing tooltips.
147  * 
148  * 122   6/12/98 4:52p Hoffoss
149  * Added support for special characters in in forgeign languages.
150  * 
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
155  * XSTR_SIZE).
156  * 
157  * 120   6/05/98 9:50a Lawrance
158  * OEM changes
159  * 
160  * 119   6/01/98 11:43a John
161  * JAS & MK:  Classified all strings for localization.
162  * 
163  * 118   5/24/98 4:42p Dan
164  * AL: Fix several bugs related to pausing and enabling/disabling event
165  * music
166  * 
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.
170  * 
171  * 116   5/19/98 1:21p Duncan
172  * Use 'InterfacePalette' instad of 'OptionsMainPalette'
173  * 
174  * 115   5/18/98 9:14p Dave
175  * Put in network config files support.
176  * 
177  * 114   5/18/98 5:16p Hoffoss
178  * Changed code to use new palette Jasen told me to use.
179  * 
180  * 113   5/16/98 3:40p Lawrance
181  * Don't restore the original details unless they've been stored!
182  * 
183  * 112   5/13/98 10:03a Mitri
184  * AL: Fix some bugs as a result of recent rearranging of code
185  * 
186  * 111   5/13/98 12:24a Lawrance
187  * Only load required bitmaps and masks for the options screen
188  * 
189  * 110   5/08/98 3:52p Hoffoss
190  * Fixed placement of gamma graphic.
191  * 
192  * 109   5/07/98 12:41p Hoffoss
193  * Added joystick deadzone slider support and mouse on/off support.
194  * 
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.
199  * 
200  * 107   5/05/98 8:38p Hoffoss
201  * Added sensitivity adjustment to options menu and made it save to pilot
202  * file.
203  * 
204  * 106   4/27/98 9:00a Jasen
205  * Updated coords for button change.
206  * 
207  * 105   4/25/98 3:33p Allender
208  * do exit confirmation
209  * 
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
213  * screen.
214  * 
215  * 103   4/21/98 12:14a Allender
216  * disable skill level buttons for multiplayer games
217  * 
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. 
222  * 
223  * 101   4/18/98 12:45p Dave
224  * Aesthetic changes to multi options screen. Put in missing exit button.
225  * oops.
226  * 
227  * 100   4/17/98 5:27p Dave
228  * More work on the multi options screen. Fixed many minor ui todo bugs.
229  *  
230  *
231  * $NoKeywords: $
232  *
233 */
234
235 #include "grinternal.h"
236 #include "ui.h"
237 #include "missionscreencommon.h"
238 #include "bmpman.h"
239 #include "gamesequence.h"
240 #include "key.h"
241 #include "managepilot.h"
242 #include "freespace.h"
243 #include "gamesnd.h"
244 #include "sound.h"
245 #include "eventmusic.h"
246 #include "mainhallmenu.h"
247 #include "audiostr.h"
248 #include "multi.h"
249 #include "psnet.h"
250 #include "popup.h"
251 #include "popupdead.h"
252 #include "missionbriefcommon.h"
253 #include "optionsmenu.h"
254 #include "optionsmenumulti.h"
255 #include "joy.h"
256 #include "mouse.h"
257 #include "osregistry.h"
258 #include "alphacolors.h"
259 #include "timer.h"
260 #include "neb.h"
261 #include "beam.h"
262
263
264 // will display a notification warning message
265 #define OPTIONS_NOTIFY_TIME                     3500
266 #define OPTIONS_NOTIFY_Y            450
267
268 #ifdef MAKE_FS1
269 #define NUM_BUTTONS 26
270 #else
271 #define NUM_BUTTONS     24
272 #endif
273 #define NUM_ANIS                4
274 #define NUM_TABS                3
275 #define NUM_COMMONS     10
276
277 #define TABLESS                                                 999
278
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
286
287 #define BRIEF_VOICE_OFF                                 7
288 #define BRIEF_VOICE_ON                                  8
289 #define MOUSE_OFF                                                       9
290 #define MOUSE_ON                                                        10
291 #define GAMMA_DOWN                                              11
292 #define GAMMA_UP                                                        12
293
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
299 #define WEAPON_EXTRAS_ON                                17
300 #define WEAPON_EXTRAS_OFF                               18
301
302 #ifdef MAKE_FS1
303 #define ENGINE_GLOWS_ON                                 24
304 #define ENGINE_GLOWS_OFF                                25
305 #endif
306
307 #define LOW_DETAIL_N                                            19
308 #define MEDIUM_DETAIL_N                                 20
309 #define HIGH_DETAIL_N                                   21
310 #define VERY_HIGH_DETAIL_N                              22
311 #define CUSTOM_DETAIL_N                                 23
312
313 #define REPEAT                                          (1<<0)
314 #define NO_MOUSE_OVER_SOUND     (1<<1)
315
316 // indicies for options coordinates
317 #define OPTIONS_X_COORD 0
318 #define OPTIONS_Y_COORD 1
319 #define OPTIONS_W_COORD 2
320 #define OPTIONS_H_COORD 3
321
322 struct options_buttons {
323         const char *filename;
324         int x, y;
325         int hotspot;
326         int tab;
327         int flags;
328         UI_BUTTON button;  // because we have a class inside this struct, we need the constructor below..
329
330         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) {}
331 };
332
333 static options_buttons Buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = {
334         {       // GR_640
335 #ifdef MAKE_FS1
336                 options_buttons("OPa_00",       84,             25,             0,      -1),    // options tab
337                 options_buttons("OPa_01",       173,    25,             1,      -1),    // multiplayer tab
338                 options_buttons("OPa_02",       256,    25,             2,      -1),    // detail levels tab
339                 options_buttons("OPa_03",       6,              380,    3,      -1),    // abort game button
340                 options_buttons("OPa_05",       448,    335,    5,      -1),    // control config button
341                 options_buttons("OPa_06",       541,    335,    6,      -1),    // hud config
342                 options_buttons("OPa_07",       560,    411,    7,      -1),    // accept button                
343
344                 options_buttons("OPa_58",       39,             99,             58,     OPTIONS_TAB,    2),     // Briefing / debriefing voice toggle off
345                 options_buttons("OPa_59",       104,    99,             59,     OPTIONS_TAB,    2),     // Briefing / debriefing voice toggle on
346                 options_buttons("OPa_62",       359,    274,    62,     OPTIONS_TAB,    2),     // Mouse off
347                 options_buttons("OPa_63",       424,    274,    63,     OPTIONS_TAB,    2),     // Mouse on
348                 options_buttons("OPa_56",       451,    79,             56,     OPTIONS_TAB,    1),     // Gamma Down
349                 options_buttons("OPa_57",       484,    79,             57,     OPTIONS_TAB,    1),     // Gamma Up
350         
351                 options_buttons("OPc_40",       321,    237,    40,     DETAIL_LEVELS_TAB,      2),     // Planets On (Nebula)
352                 options_buttons("OPc_39",       264,    237,    39,     DETAIL_LEVELS_TAB,      2),     // Planets Off (Nebula)
353                 options_buttons("OPc_42",       321,    284,    42,     DETAIL_LEVELS_TAB,      2),     // Target View Rendering On
354                 options_buttons("OPc_41",       264,    284,    41,     DETAIL_LEVELS_TAB,      2),     // Target View Rendering Off
355                 options_buttons("OPc_44",       321,    331,    44,     DETAIL_LEVELS_TAB,      2),     // Weapon Extras On
356                 options_buttons("OPc_43",       264,    331,    43,     DETAIL_LEVELS_TAB,      2),     // Weapon Extras Off
357
358                 options_buttons("OPc_50",       516,    194,    50,     DETAIL_LEVELS_TAB,      2),     // Low Preset Detail
359                 options_buttons("OPc_51",       516,    213,    51,     DETAIL_LEVELS_TAB,      2),     // Medium Preset Detail
360                 options_buttons("OPc_52",       516,    232,    52,     DETAIL_LEVELS_TAB,      2),     // High Preset Detail
361                 options_buttons("OPc_53",       498,    251,    53,     DETAIL_LEVELS_TAB,      2),     // Highest Preset Detail
362                 options_buttons("OPc_54",       516,    270,    54,     DETAIL_LEVELS_TAB,      2),     // Custom Detail
363
364                 options_buttons("OPc_38",       321,    190,    38,     DETAIL_LEVELS_TAB,      2),     // Engine Glow On
365                 options_buttons("OPc_37",       264,    190,    37,     DETAIL_LEVELS_TAB,      2),     // Engine Glow Off
366 #else
367                 options_buttons("OPT_00",       17,     2,              0,              -1),                                                    // options tab
368                 options_buttons("OPT_01",       102,    2,              1,              -1),                                                    // multiplayer tab
369                 options_buttons("OPT_02",       170,    2,              2,              -1),                                                    // detail levels tab
370                 options_buttons("OPT_03",       10,     444,    3,              -1),                                                    // abort game button
371                 options_buttons("OPT_04",       411,    444,    4,              -1),                                                    // control config button
372                 options_buttons("OPT_05",       506,    444,    5,              -1),                                                    // hud config
373                 options_buttons("OPT_06",       576,    434,    6,              -1),                                                    // accept button                                
374
375                 options_buttons("OMB_07",       51,     74,     7,              OPTIONS_TAB, 2),                        // Briefing / debriefing voice toggle off
376                 options_buttons("OMB_08",       106,    74,     8,              OPTIONS_TAB, 2),                        // Briefing / debriefing voice toggle on
377                 options_buttons("OMB_18",       51,     266,    18,     OPTIONS_TAB, 2),                        // Mouse off
378                 options_buttons("OMB_19",       106,    266,    19,     OPTIONS_TAB, 2),                        // Mouse on
379                 options_buttons("OMB_26",       578,    149,    26,     OPTIONS_TAB, 1),                        // Gamma Down
380                 options_buttons("OMB_27",       607,    149,    27,     OPTIONS_TAB, 1),                        // Gamma Up
381                 
382                 options_buttons("ODB_21",       597,    261,    21,     DETAIL_LEVELS_TAB, 2),  // Planets On
383                 options_buttons("ODB_20",       539,    261,    20,     DETAIL_LEVELS_TAB, 2),  // Planets Off
384                 options_buttons("ODB_23",       597,    307,    23,     DETAIL_LEVELS_TAB, 2),  // Target View Rendering On
385                 options_buttons("ODB_22",       539,    307,    22,     DETAIL_LEVELS_TAB, 2),  // Target View Rendering Off
386                 options_buttons("ODB_25",       597,    354,    25,     DETAIL_LEVELS_TAB, 2),  // Weapon Extras On
387                 options_buttons("ODB_24",       539,    354,    24,     DETAIL_LEVELS_TAB, 2),  // Weapon Extras Off
388
389                 options_buttons("ODB_14",       614,    76,     14,     DETAIL_LEVELS_TAB, 2),  // Low Preset Detail
390                 options_buttons("ODB_15",       614,    96,     15,     DETAIL_LEVELS_TAB, 2),  // Medium Preset Detail
391                 options_buttons("ODB_16",       614,    114,    16,     DETAIL_LEVELS_TAB, 2),  // High Preset Detail
392                 options_buttons("ODB_17",       614,    133,    17,     DETAIL_LEVELS_TAB, 2),  // Highest Preset Detail
393                 options_buttons("ODB_18",       614,    152,    18,     DETAIL_LEVELS_TAB, 2),  // Custom Detail
394 #endif
395         },
396         {       // GR_1024
397                 options_buttons("2_OPT_00",     27,     4,              0,              -1),                                            // options tab
398                 options_buttons("2_OPT_01",     164,    4,              1,              -1),                                            // multiplayer tab
399                 options_buttons("2_OPT_02",     272,    4,              2,              -1),                                            // detail levels tab
400                 options_buttons("2_OPT_03",     16,     711,    3,              -1),                                            // abort game
401                 options_buttons("2_OPT_04",     657,    711,    4,              -1),                                            // control config button
402                 options_buttons("2_OPT_05",     809,    711,    5,              -1),                                            // hud config button
403                 options_buttons("2_OPT_06",     922,    694,    6,              -1),                                            // accept button                
404
405                 options_buttons("2_OMB_07",     81,     118,    7,              OPTIONS_TAB, 2),                        // Briefing / debriefing voice toggle off
406                 options_buttons("2_OMB_08",     170,    118,    8,              OPTIONS_TAB, 2),                        // Briefing / debriefing voice toggle on
407                 options_buttons("2_OMB_18",     81,     425,    18,     OPTIONS_TAB, 2),                        // Mouse off
408                 options_buttons("2_OMB_19",     170,    425,    19,     OPTIONS_TAB, 2),                        // Mouse on
409                 options_buttons("2_OMB_26",     925,    238,    26,     OPTIONS_TAB, 1),                        // Gamma Down
410                 options_buttons("2_OMB_27",     971,    238,    27,     OPTIONS_TAB, 1),                        // Gamma Up
411                 
412                 options_buttons("2_ODB_21",     956,    417,    21,     DETAIL_LEVELS_TAB, 2),  // Planets On
413                 options_buttons("2_ODB_20",     863,    417,    20,     DETAIL_LEVELS_TAB, 2),  // Planets Off
414                 options_buttons("2_ODB_23",     956,    492,    23,     DETAIL_LEVELS_TAB, 2),  // Target View Rendering On
415                 options_buttons("2_ODB_22",     863,    492,    22,     DETAIL_LEVELS_TAB, 2),  // Target View Rendering Off
416                 options_buttons("2_ODB_25",     956,    567,    25,     DETAIL_LEVELS_TAB, 2),  // Weapon Extras On
417                 options_buttons("2_ODB_24",     863,    567,    24,     DETAIL_LEVELS_TAB, 2),  // Weapon Extras Off
418
419                 options_buttons("2_ODB_14",     983,    122,    14,     DETAIL_LEVELS_TAB, 2),  // Low Preset Detail
420                 options_buttons("2_ODB_15",     983,    153,    15,     DETAIL_LEVELS_TAB, 2),  // Medium Preset Detail
421                 options_buttons("2_ODB_16",     983,    183,    16,     DETAIL_LEVELS_TAB, 2),  // High Preset Detail
422                 options_buttons("2_ODB_17",     983,    213,    17,     DETAIL_LEVELS_TAB, 2),  // Highest Preset Detail
423                 options_buttons("2_ODB_18",     983,    243,    18,     DETAIL_LEVELS_TAB, 2),  // Custom Detail
424 #ifdef MAKE_FS1 // just filler
425                 options_buttons("OPc_38",       321,    290,    38,     DETAIL_LEVELS_TAB,      2),     // Engine Glow On
426                 options_buttons("OPc_37",       264,    290,    37,     DETAIL_LEVELS_TAB,      2),     // Engine Glow Off
427 #endif
428         }       
429 };
430
431 #define NUM_OPTIONS_SLIDERS                     7
432 #define OPT_SOUND_VOLUME_SLIDER         0
433 #define OPT_MUSIC_VOLUME_SLIDER         1
434 #define OPT_VOICE_VOLUME_SLIDER         2
435 #define OPT_MOUSE_SENS_SLIDER                   3
436 #define OPT_JOY_SENS_SLIDER                     4
437 #define OPT_JOY_DEADZONE_SLIDER         5
438 #define OPT_SKILL_SLIDER                                6
439
440 op_sliders Options_sliders[GR_NUM_RESOLUTIONS][NUM_OPTIONS_SLIDERS] = {
441         { // GR_640             
442 #ifdef MAKE_FS1
443 // slider, right arrow, left arrow
444 // 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)
445                 op_sliders("OPa_09",    53,     160,    -1,     -1,     9,      20,     11,
446                                         "OPa_10",       10,     245,    159,
447                                         "OPa_08",       8,      29,             159),   // sound fx volume slider
448                 op_sliders("OPa_17",    53,     195,    -1,     -1,     17,     20,     11,
449                                         "OPa_18",       18,     245,    194,
450                                         "OPa_16",       16,     29,             194),   // music volume slider
451                 op_sliders("OPa_20",    53,     229,    -1,     -1,     20,     20,     11,
452                                         "OPa_21",       21,     245,    228,
453                                         "OPa_19",       19,     29,             228),   // voice volume slider
454                 op_sliders("OPa_64",    358,    301,    -1,     -1,     64,     20,     10,     NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // mouse sensitivity    
455                 op_sliders("OPa_60",    358,    194,    -1,     -1,     60,     20,     10,     NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // joystick sensitivity
456                 op_sliders("OPa_61",    358,    226,    -1,     -1,     61,     20,     10,     NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // joystick deadzone
457                 op_sliders("OPa_11",    28,             285,    -1,     -1,     -1,     42,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1)             // skill
458 #else
459                 op_sliders("OMB_10",            31,     139,    -1,     -1,     10,     20,     10,
460                                           "OMB_11",             11,     226,    137,
461                                           "OMB_09",             9,              4,              137 ),                                                          // sound fx volume slider
462                 op_sliders("OMB_13",            31,     174,    -1,     -1,     13,     20,     10,
463                                           "OMB_14",             14,     226,    172,
464                                           "OMB_12",             12,     4,              172 ),                                                          // music volume slider
465                 op_sliders("OMB_16",            31,     209,    -1,     -1,     16,     20,     10,
466                                           "OMB_17",             17,     226,    206,
467                                           "OMB_15",             15,     4,              206 ),                                                          // voice volume slider
468                 op_sliders("OMB_20",            6,              316,    -1,     -1,     20,     20,     10, NULL, -1, -1, -1, NULL, -1, -1, -1),        // mouse sensitivity    
469                 op_sliders("OMB_28",            440,    259,    -1,     -1,     28,     20,     10, NULL, -1, -1, -1, NULL, -1, -1, -1),        // joystick sensitivity
470                 op_sliders("OMB_29",            440,    290,    -1,     -1,     29,     20,     10, NULL, -1, -1, -1, NULL, -1, -1, -1),        // joystick deadzone
471                 op_sliders("OMB_21",            440,    75,     -1,     -1,     21,     36,     5,      NULL, -1, -1, -1, NULL, -1, -1, -1)
472 #endif  // MAKE_FS1
473         },      
474         { // GR_1024            
475                 op_sliders("2_OMB_10",          50,     223,    -1,     -1,     10,     32,     10,
476                                           "2_OMB_11",           11,     361,    219,
477                                           "2_OMB_09",           9,              7,              219 ),                                                          // sound fx volume slider
478                 op_sliders("2_OMB_13",          50,     281,    -1,     -1,     13,     32,     10,
479                                           "2_OMB_14",           14,     361,    275,
480                                           "2_OMB_12",           12,     7,              275 ),                                                          // music volume slider
481                 op_sliders("2_OMB_16",          50,     335,    -1,     -1,     16,     32,     10,
482                                           "2_OMB_17",           17,     361,    330,
483                                           "2_OMB_15",           15,     7,              330 ),                                                          // voice volume slider
484                 op_sliders("2_OMB_20",          9,              505,    -1,     -1,     20,     32,     10, NULL, -1, -1, -1, NULL, -1, -1, -1),        // mouse sensitivity    
485                 op_sliders("2_OMB_28",          704,    414,    -1,     -1,     28,     32,     10, NULL, -1, -1, -1, NULL, -1, -1, -1),        // joystick sensitivity
486                 op_sliders("2_OMB_29",          704,    464,    -1,     -1,     29,     32,     10, NULL, -1, -1, -1, NULL, -1, -1, -1),        // joystick deadzone
487                 op_sliders("2_OMB_21",          704,    120,    -1,     -1,     21,     60,     5,      NULL, -1, -1, -1, NULL, -1, -1, -1)
488         }
489 };
490
491 static struct {
492         const char *filename;
493         const char *mask_filename;
494         int bitmap;
495         int mask;
496         
497 } Backgrounds[GR_NUM_RESOLUTIONS][NUM_TABS] = {
498 //XSTR:OFF
499         {       // GR_640
500                 { "OptionsMain", "OptionsMain-M", -1, -1 },
501                 { "OptionsMulti", "OptionsMulti-M", -1, -1 },
502                 { "OptionsDetail", "OptionsDetail-M", -1, -1 },
503         },
504         {       // GR_1024
505                 { "2_OptionsMain", "2_OptionsMain-M", -1, -1 },
506                 { "2_OptionsMulti", "2_OptionsMulti-M", -1, -1 },
507                 { "2_OptionsDetail", "2_OptionsDetail-M", -1, -1 },
508         }
509 //XSTR:ON
510 };
511
512 static int Tab = 0;
513 static int Options_menu_inited = 0;
514 static int Options_multi_inited = 0;
515 static int Options_detail_inited = 0;
516 static int Button_bms[NUM_COMMONS][MAX_BMAPS_PER_GADGET];
517
518 static UI_WINDOW Ui_window;
519 UI_GADGET Options_bogus;
520
521 static int Backup_skill_level;
522 static float Backup_sound_volume;
523 static float Backup_music_volume;
524 static float Backup_voice_volume;
525
526 static int Backup_briefing_voice_enabled;
527 static int Backup_use_mouse_to_fly;
528
529 static int Sound_volume_int;
530 static int Music_volume_int;
531 static int Voice_volume_int;
532
533 static int Voice_vol_handle = -1;
534 int Options_notify_stamp = -1;
535 char Options_notify_string[200];
536
537 // called whenever accept is hit
538 // do any processing, etc in here.
539 void options_accept();
540 void options_force_button_frame(int n, int frame_num);
541
542 extern float Freespace_gamma;
543
544 void options_add_notify(const char *str);
545 void options_notify_do_frame();
546
547 int Options_gamma_coords[GR_NUM_RESOLUTIONS][4] = {
548         {
549 #ifdef MAKE_FS1
550                 376, 116, 203, 34
551 #else
552                 435, 179, 195,  28      // GR_640
553 #endif  // MAKE_FS1
554         },
555         {
556                 692, 287, 308, 44               // GR_1024
557         }
558 };
559
560 #define MAX_GAMMA_BITMAP_SIZE 17500
561
562 int Options_gamma_num_coords[GR_NUM_RESOLUTIONS][4] = {
563         {
564 #ifdef MAKE_FS1
565                 390, 87, 45, 10
566 #else
567                 489, 159, 65, 17                // GR_640
568 #endif  // MAKE_FS1
569         },
570         {
571                 779, 254, 65, 17                // GR_1024
572         }
573 };
574
575 int Options_skills_text_coords[GR_NUM_RESOLUTIONS][4] = {
576         {
577 #ifdef MAKE_FS1
578                 41, 326, 186, 10
579 #else
580                 468, 104, 155, 10               // GR_640
581 #endif
582         },
583         {
584                 750, 169, 246, 21               // GR_1024
585         }
586 };
587
588
589 // ---------------------------------------------------------------------------------------------------------
590 // DETAIL LEVEL OPTIONS definitions  BEGIN
591 //
592
593 #ifdef MAKE_FS1
594         #define NUM_DETAIL_SLIDERS              9
595 #else
596         #define NUM_DETAIL_SLIDERS              8
597 #endif
598
599 /*
600 #define DETAIL_DISTANCE_SLIDER  0
601 #define NEBULA_DETAIL_SLIDER            1
602 #define HARDWARE_TEXTURES_SLIDER        2
603 #define NUM_PARTICLES_SLIDER            6
604 #define SHARD_CULLING_SLIDER            3
605 #define SHIELD_DETAIL_SLIDER            4
606 #define NUM_STARS_SLIDER                        5
607 #define LIGHTING_SLIDER                         7
608 */
609 #define DETAIL_DISTANCE_SLIDER  0
610 #define NEBULA_DETAIL_SLIDER            1
611 #define HARDWARE_TEXTURES_SLIDER        2
612 #define NUM_PARTICLES_SLIDER            3
613 #define SHARD_CULLING_SLIDER            4
614 #define SHIELD_DETAIL_SLIDER            5
615 #define NUM_STARS_SLIDER                        6
616 #define LIGHTING_SLIDER                         7
617 #ifdef MAKE_FS1
618 #define WEAPON_RENDERING_SLIDER         8
619 #endif
620 op_sliders Detail_sliders[GR_NUM_RESOLUTIONS][NUM_DETAIL_SLIDERS] = {
621         { // GR_640
622 #ifdef MAKE_FS1
623                 op_sliders("OPc_29",    38,             96,             -1,     -1,     29,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // model detail
624                 op_sliders("OPc_30",    38,             143,    -1,     -1,     30,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // nebula detail
625                 op_sliders("OPc_31",    38,             176,    -1,     -1,     31,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // textures
626                 op_sliders("OPc_36",    273,    143,    -1,     -1,     36,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // particles
627                 op_sliders("Opc_33",    38,             284,    -1,     -1,     33,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // impact effects
628                 op_sliders("OPc_34",    38,             333,    -1,     -1,     34,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // shield hit
629                 op_sliders("OPc_35",    273,    96,             -1,     -1,     35,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // stars
630                 op_sliders("OPc_45",    496,    96,             -1,     -1,     45,     20,     5,      NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),    // lighting
631                 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
632 #else
633                 op_sliders("ODB_07",    21,     71,     -1,     -1,     7,              20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // model detail
634                 op_sliders("ODB_08",    21,     119,    -1,     -1,     8,              20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // nebula detail
635                 op_sliders("ODB_09",    21,     166,    -1,     -1,     9,              20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // textures
636                 op_sliders("ODB_10",    21,     212,    -1,     -1,     10,     20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // particles
637                 op_sliders("ODB_11",    21,     260,    -1,     -1,     11,     20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // debris
638                 op_sliders("ODB_12",    21,     307,    -1,     -1,     12,     20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // shield hit
639                 op_sliders("ODB_13",    21,     354,    -1,     -1,     13,     20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // stars
640                 op_sliders("ODB_19",    518,    212,    -1,     -1,     19,     20,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),                 // lighting             
641 #endif
642         },      
643         { // GR_1024
644                 op_sliders("2_ODB_07",  34,     114,    -1,     -1,     7,              32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // model detail
645                 op_sliders("2_ODB_08",  34,     190,    -1,     -1,     8,              32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // nebula detail
646                 op_sliders("2_ODB_09",  34,     265,    -1,     -1,     9,              32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // textures
647                 op_sliders("2_ODB_10",  34,     340,    -1,     -1,     10,     32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // particles
648                 op_sliders("2_ODB_11",  34,     416,    -1,     -1,     11,     32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // debris
649                 op_sliders("2_ODB_12",  34,     492,    -1,     -1,     12,     32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // shield hit
650                 op_sliders("2_ODB_13",  34,     567,    -1,     -1,     13,     32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // stars
651                 op_sliders("2_ODB_19",  829,    340,    -1,     -1,     19,     32,     5, NULL, -1, -1, -1, NULL, -1, -1, -1),         // lighting
652 #ifdef MAKE_FS1 // filler
653                 op_sliders("none",              -1,     -1,             -1,     -1,     -1,     -1,     -1,     NULL,   -1,     -1,     -1,     NULL,   -1,     -1,     -1),
654 #endif
655         }
656 };
657 int Detail_slider_pos[NUM_DETAIL_SLIDERS];
658 detail_levels Detail_original;  // backup of Detail settings when screen is first entered
659 UI_GADGET Detail_bogus;
660 void options_detail_init();
661 void options_detail_hide_stuff();
662 void options_detail_unhide_stuff();
663 void options_detail_do_frame();
664 void options_detail_set_level(int level);
665
666 // text
667 #ifndef MAKE_FS1
668 #define OPTIONS_NUM_TEXT                                49
669
670 UI_XSTR Options_text[GR_NUM_RESOLUTIONS][OPTIONS_NUM_TEXT] = {
671         { // GR_640
672                 // common text
673                 { "Options",    1036,           10,     35,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][OPTIONS_TAB].button },
674                 { "Multi",              1042,           97,     35,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][MULTIPLAYER_TAB].button },
675                 { "Detail",             1351,           166,    35,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][DETAIL_LEVELS_TAB].button },
676                 { "Exit",               1059,           8,              417,    UI_XSTR_COLOR_PINK,     -1, &Buttons[0][ABORT_GAME_BUTTON].button },
677                 { "Game",               1412,           8,              430,    UI_XSTR_COLOR_PINK,     -1, &Buttons[0][ABORT_GAME_BUTTON].button },
678                 { "Control",    1352,           409,    418,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][CONTROL_CONFIG_BUTTON].button },
679                 { "Config",             1353,           409,    430,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][CONTROL_CONFIG_BUTTON].button },
680                 { "HUD",                        1354,           504,    418,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][HUD_CONFIG_BUTTON].button },
681                 { "Config",             1415,           504,    430,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][HUD_CONFIG_BUTTON].button },
682                 { "Accept",             1035,           573,    412,    UI_XSTR_COLOR_PINK,     -1, &Buttons[0][ACCEPT_BUTTON].button },
683
684                 // text for the detail level screen 
685                 { "Preset Detail Levels",       1355,   455,    56,     UI_XSTR_COLOR_GREEN,    -1, &Detail_bogus },
686                 { "Low",                        1160,           570,    82,     UI_XSTR_COLOR_GREEN, -1, &Buttons[0][LOW_DETAIL_N].button },
687                 { "Medium",             1161,           550,    100,    UI_XSTR_COLOR_GREEN, -1, &Buttons[0][MEDIUM_DETAIL_N].button },
688                 { "High",               1162,           568,    120,    UI_XSTR_COLOR_GREEN, -1, &Buttons[0][HIGH_DETAIL_N].button },
689                 { "Very High",  1163,           530,    139,    UI_XSTR_COLOR_GREEN, -1, &Buttons[0][VERY_HIGH_DETAIL_N].button },
690                 { "Custom",             1356,           546,    158,    UI_XSTR_COLOR_GREEN, -1, &Buttons[0][CUSTOM_DETAIL_N].button },         
691                 { "Off",                        1286,           509,    267,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][PLANETS_OFF].button },
692                 { "On",                 1285,           573,    267,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][PLANETS_ON].button },
693                 { "Off",                        1286,           509,    314,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][HUD_TARGETVIEW_RENDER_OFF].button },
694                 { "On",                 1285,           573,    314,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][HUD_TARGETVIEW_RENDER_ON].button },
695                 { "Off",                        1286,           509,    361,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][WEAPON_EXTRAS_OFF].button },
696                 { "On",                 1285,           573,    361,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][WEAPON_EXTRAS_ON].button },
697                 { "Planets/Backgrounds",                1357,   455,    244, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
698                 { "Target View Rendering",              1358,   446,    291, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
699                 { "Weapon Extras",                              1359,   497,    338, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
700                 { "Model Detail",                                       1360,   27,     56,     UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
701                 { "Nebula Detail",                              1361,   27,     103,    UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
702                 { "3D Hardware Textures",               1362,   27,     150,    UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
703                 { "Particles",                                          1363,   27,     197,    UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
704                 { "Impact Effects",                             1364,   27,     244,    UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
705                 { "Shield Hit Effects",                 1365,   27,     291,    UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
706                 { "Stars",                                                      1366,   27,     338,    UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
707                 { "Lighting",                                           1367, 549,      197,    UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
708
709                 // main options screen text
710                 { "Briefing Voice",     1368,   14,     58,     UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
711                 { "Off",                                        1286,   20,     81,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][BRIEF_VOICE_OFF].button },
712                 { "On",                                 1285,   83,     81,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][BRIEF_VOICE_ON].button },
713                 { "Volume",                             1369,   14,     111,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
714                 { "Effects",                    1370,   20,     130,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
715                 { "Music",                              1371,   20,     165,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
716                 { "Voice",                              1372,   20,     199,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
717                 { "Mouse",                              1373,   14,     249,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
718                 { "Off",                                        1286,   20,     273,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][MOUSE_OFF].button },
719                 { "On",                                 1285,   83,     273,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[0][MOUSE_ON].button },
720                 { "Sensitivity",                1529,   20,     297,    UI_XSTR_COLOR_GREEN,    -1, &Options_sliders[0][OPT_MOUSE_SENS_SLIDER].slider },
721                 { "Skill Level",                1509,   533,    58,     UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
722                 { "Brightness",         1375,   532,    133,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
723                 { "Joystick",                   1376,   556,    231,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
724                 { "Sensitivity",                1374,   538,    250,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
725                 { "Deadzone",                   1377,   538,    281,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
726         },
727         { // GR_1024
728                 // common text
729                 { "Options",    1036,           16,     57,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][OPTIONS_TAB].button },
730                 { "Multi",              1042,           172,    57,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][MULTIPLAYER_TAB].button },
731                 { "Detail",             1351,           283,    57,     UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][DETAIL_LEVELS_TAB].button },
732                 { "Exit",               1059,           13,     685,    UI_XSTR_COLOR_PINK,     -1, &Buttons[1][ABORT_GAME_BUTTON].button },
733                 { "Game",               1412,           13,     696,    UI_XSTR_COLOR_PINK,     -1, &Buttons[1][ABORT_GAME_BUTTON].button },
734                 { "Control",    1352,           655,    685,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][CONTROL_CONFIG_BUTTON].button },
735                 { "Config",             1353,           655,    696,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][CONTROL_CONFIG_BUTTON].button },
736                 { "HUD",                        1354,           806,    685,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][HUD_CONFIG_BUTTON].button },
737                 { "Config",             1415,           806,    696,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][HUD_CONFIG_BUTTON].button },
738                 { "Accept",             1035,           927,    672,    UI_XSTR_COLOR_PINK,     -1, &Buttons[1][ACCEPT_BUTTON].button },
739
740                 // text for the detail level screen 
741                 { "Preset Detail Levels",       1355,   809,    90,     UI_XSTR_COLOR_GREEN,    -1, &Detail_bogus },
742                 { "Low",                        1160,           944,    131,    UI_XSTR_COLOR_GREEN, -1, &Buttons[1][LOW_DETAIL_N].button },
743                 { "Medium",             1161,           924,    161,    UI_XSTR_COLOR_GREEN, -1, &Buttons[1][MEDIUM_DETAIL_N].button },
744                 { "High",               1162,           942,    192,    UI_XSTR_COLOR_GREEN, -1, &Buttons[1][HIGH_DETAIL_N].button },
745                 { "Very High",  1163,           903,    222,    UI_XSTR_COLOR_GREEN, -1, &Buttons[1][VERY_HIGH_DETAIL_N].button },
746                 { "Custom",             1356,           922,    252,    UI_XSTR_COLOR_GREEN, -1, &Buttons[1][CUSTOM_DETAIL_N].button },         
747                 { "Off",                        1286,           835,    427,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][PLANETS_OFF].button },
748                 { "On",                 1285,           936,    427,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][PLANETS_ON].button },
749                 { "Off",                        1286,           835,    503,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][HUD_TARGETVIEW_RENDER_OFF].button },
750                 { "On",                 1285,           936,    503,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][HUD_TARGETVIEW_RENDER_ON].button },
751                 { "Off",                        1286,           835,    578,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][WEAPON_EXTRAS_OFF].button },
752                 { "On",                 1285,           936,    578,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][WEAPON_EXTRAS_ON].button },
753                 { "Planets/Backgrounds",        1357,   808,    391, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
754                 { "Target View Rendering",      1358,   799,    466, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },
755                 { "Weapon Extras",                      1359,   850,    542, UI_XSTR_COLOR_GREEN, -1, &Detail_bogus },                          
756                 { "Model Detail",                                       1360,   44,     99,     UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][DETAIL_DISTANCE_SLIDER].slider },
757                 { "Nebula Detail",                              1361,   44,     175,    UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][NEBULA_DETAIL_SLIDER].slider },
758                 { "3D Hardware Textures",               1362,   44,     250,    UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][HARDWARE_TEXTURES_SLIDER].slider },
759                 { "Particles",                                          1363,   44,     325,    UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][NUM_PARTICLES_SLIDER].slider },
760                 { "Impact Effects",                             1364,   44,     401,    UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][SHARD_CULLING_SLIDER].slider },
761                 { "Shield Hit Effects",                 1365,   44,     476,    UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][SHIELD_DETAIL_SLIDER].slider },
762                 { "Stars",                                                      1366, 44,       552,    UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][NUM_STARS_SLIDER].slider },
763                 { "Lighting",                                           1367, 903,      326,    UI_XSTR_COLOR_GREEN, -1, &Detail_sliders[1][LIGHTING_SLIDER].slider },
764
765                 // main options screen text
766                 { "Briefing Voice",     1368,   23,     93,     UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
767                 { "Off",                                        1286,   32,     130,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][BRIEF_VOICE_OFF].button },
768                 { "On",                                 1285,   134,    130,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][BRIEF_VOICE_ON].button },
769                 { "Volume",                             1369,   23,     178,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
770                 { "Effects",                    1370,   33,     209,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
771                 { "Music",                              1371,   33,     264,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
772                 { "Voice",                              1372,   33,     319,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
773                 { "Mouse",                              1373,   23,     399,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
774                 { "Off",                                        1286,   32,     437,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][MOUSE_OFF].button },
775                 { "On",                                 1285,   134,    437,    UI_XSTR_COLOR_GREEN,    -1, &Buttons[1][MOUSE_ON].button },
776                 { "Sensitivity",                1529,   34,     477,    UI_XSTR_COLOR_GREEN,    -1, &Options_sliders[1][OPT_MOUSE_SENS_SLIDER].slider },
777                 { "Skill Level",                1509,   854,    93,     UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
778                 { "Brightness",         1375,   852,    214,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
779                 { "Joystick",                   1376,   891,    370,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
780                 { "Sensitivity",                1374,   861,    400,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
781                 { "Deadzone",                   1377,   861,    451,    UI_XSTR_COLOR_GREEN,    -1, &Options_bogus },
782         }
783 };
784 #endif
785
786
787 //
788 // DETAIL LEVEL tab definitions END
789 // ---------------------------------------------------------------------------------------------------------
790
791 void options_play_voice_clip()
792 {
793         int snd_id;
794
795         if ( snd_is_playing(Voice_vol_handle) ) {
796                 snd_stop(Voice_vol_handle);
797                 Voice_vol_handle=-1;
798         }
799
800         snd_id = snd_load(&Snds_iface[SND_VOICE_SLIDER_CLIP]);
801         Voice_vol_handle = snd_play_raw( snd_id, 0.0f, 1.0f, SND_PRIORITY_SINGLE_INSTANCE );
802 }
803
804 void options_add_notify(const char *str)
805 {
806         strcpy(Options_notify_string, str);
807         Options_notify_stamp = timestamp(OPTIONS_NOTIFY_TIME);
808 }
809
810 void options_notify_do_frame()
811 {
812         int w,h;
813
814         if (Options_notify_stamp != -1) {
815                 if (timestamp_elapsed(Options_notify_stamp)) {
816                         Options_notify_stamp = -1;
817
818                 } else {
819                         gr_get_string_size(&w, &h, Options_notify_string);
820                         gr_printf((gr_screen.max_w - w) / 2, OPTIONS_NOTIFY_Y, Options_notify_string);
821                 }
822         }
823 }
824
825 /*
826 void options_set_bmaps(int btn, int bm_index)
827 {
828         int j;
829
830         for (j=0; j<MAX_BMAPS_PER_GADGET; j++){
831                 Buttons[gr_screen.res][btn].button.bmap_ids[j] = Button_bms[bm_index][j];
832         }
833 }
834 */
835
836 void options_tab_setup(int set_palette)
837 {
838         // char *pal;
839         int i;
840         int flags[256];
841
842         if (Tab != MULTIPLAYER_TAB) {
843                 SDL_assert(Backgrounds[gr_screen.res][Tab].mask >= 0);
844                 Ui_window.set_mask_bmap(Backgrounds[gr_screen.res][Tab].mask, Backgrounds[gr_screen.res][Tab].mask_filename);
845         }
846
847         for (i=0; i<256; i++){
848                 flags[i] = 0;
849         }
850
851         // activate, deactivate any necessary controls
852         for (i=0; i<NUM_BUTTONS; i++) {
853                 if ( ((Buttons[gr_screen.res][i].tab == Tab) || (Buttons[gr_screen.res][i].tab == -1)) && !flags[Buttons[gr_screen.res][i].hotspot] ) {
854                         flags[Buttons[gr_screen.res][i].hotspot] = 1;
855                         Buttons[gr_screen.res][i].button.enable();
856                         if (Buttons[gr_screen.res][i].filename)
857                                 Buttons[gr_screen.res][i].button.unhide();
858
859                 } else {
860                         Buttons[gr_screen.res][i].button.disable();
861                         Buttons[gr_screen.res][i].button.hide();
862                 }
863         }
864
865         // maybe enable/disable controls based upon current tab
866         if (Tab == OPTIONS_TAB) {
867                 for(i=0; i<NUM_OPTIONS_SLIDERS; i++){
868                         Options_sliders[gr_screen.res][i].slider.enable();
869                         Options_sliders[gr_screen.res][i].slider.unhide();
870                 }               
871         } else {
872                 for(i=0; i<NUM_OPTIONS_SLIDERS; i++){
873                         Options_sliders[gr_screen.res][i].slider.hide();
874                         Options_sliders[gr_screen.res][i].slider.disable();
875                 }               
876         }       
877
878         if( ((Game_mode & GM_IN_MISSION) && (!popupdead_is_active())) || (Game_mode & GM_MULTIPLAYER) ){
879                 Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.disable();
880                 Ui_window.use_hack_to_get_around_stupid_problem_flag = 0;
881         }
882
883         // do other special processing
884         switch (Tab) {
885                 case MULTIPLAYER_TAB:
886 #if !defined(DEMO) && !defined(OEM_BUILD) // not for FS2_DEMO
887                         options_multi_select();
888 #ifdef MAKE_FS1         
889                         // need to hide the hud config and control config buttons
890                         Buttons[gr_screen.res][CONTROL_CONFIG_BUTTON].button.hide();
891                         Buttons[gr_screen.res][HUD_CONFIG_BUTTON].button.hide();
892 #endif // MAKE_FS1
893 #endif // DEMO
894                         break;
895
896                 case DETAIL_LEVELS_TAB:
897                         options_detail_unhide_stuff();  
898                         break;
899         }
900 }
901
902 // call this function to close down, do other processing of data in the tab that's being left
903 void options_tab_close()
904 {
905         switch (Tab) {
906                 case MULTIPLAYER_TAB:
907 #if !defined(DEMO) && !defined(OEM_BUILD) // not for FS2_DEMO
908                         options_multi_unselect();               
909 #endif
910                         break;
911
912                 case DETAIL_LEVELS_TAB:
913                         options_detail_hide_stuff();
914                         break;
915         }
916 }
917
918 void options_change_tab(int n)
919 {
920         int idx;
921
922 #if defined(DEMO) || defined(OEM_BUILD) // not for FS2_DEMO
923         if (n == MULTIPLAYER_TAB) {
924                 game_feature_not_in_demo_popup();
925                 return;
926         }
927 #endif
928
929         switch (n) {
930                 case MULTIPLAYER_TAB:
931                         if ( !Options_multi_inited ) {
932                                 // init multiplayer
933 #if !defined(DEMO) && !defined(OEM_BUILD) // not for FS2_DEMO
934                                 options_multi_init(&Ui_window);
935                                 options_multi_unselect();
936 #endif
937                                 Options_multi_inited = 1;
938                         }
939
940                         break;
941
942                 case DETAIL_LEVELS_TAB:
943                         if (!Options_detail_inited) {
944                                 // init detail levels
945                                 options_detail_init();
946                                 options_detail_hide_stuff();
947                                 Options_detail_inited = 1;
948                         }
949
950                         break;
951         }
952
953         // if we're going into the main screen
954         if(n == OPTIONS_TAB){
955                 Options_bogus.enable();
956                 Options_bogus.unhide();
957                 for(idx=0; idx<NUM_OPTIONS_SLIDERS; idx++){
958                         Options_sliders[gr_screen.res][idx].slider.enable();
959                         Options_sliders[gr_screen.res][idx].slider.unhide();
960                 }
961         } else {
962                 Options_bogus.hide();
963                 Options_bogus.disable();
964                 for(idx=0; idx<NUM_OPTIONS_SLIDERS; idx++){
965                         Options_sliders[gr_screen.res][idx].slider.hide();
966                         Options_sliders[gr_screen.res][idx].slider.disable();
967                 }
968         }
969
970         if (n != MULTIPLAYER_TAB) {
971                 if (Backgrounds[gr_screen.res][n].mask < 0) {
972                         gamesnd_play_iface(SND_GENERAL_FAIL);
973                         return;
974                 }
975         }
976
977         options_tab_close();
978
979         Tab = n;
980         options_tab_setup(1);
981         gamesnd_play_iface(SND_SCREEN_MODE_PRESSED);
982 }
983
984 void set_sound_volume()
985 {
986         main_hall_reset_ambient_vol();
987 }
988
989 void set_music_volume()
990 {
991         event_music_set_volume_all(Master_event_music_volume);
992 }
993
994 void set_voice_volume()
995 {
996         audiostream_set_volume_all(Master_voice_volume, ASF_VOICE);
997 }
998
999 void options_cancel_exit()
1000 {
1001         Master_sound_volume = Backup_sound_volume;
1002         set_sound_volume();
1003         Master_event_music_volume = Backup_music_volume;
1004         set_music_volume();
1005         Master_voice_volume = Backup_voice_volume;
1006         set_voice_volume();
1007
1008         if(!(Game_mode & GM_MULTIPLAYER)){
1009                 Game_skill_level = Backup_skill_level;
1010         }
1011
1012         Briefing_voice_enabled = Backup_briefing_voice_enabled;
1013         Use_mouse_to_fly = Backup_use_mouse_to_fly;
1014
1015         if ( Options_detail_inited ) {
1016                 Detail = Detail_original;
1017         }
1018
1019         gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
1020 }
1021
1022 void options_change_gamma(float delta)
1023 {
1024         char tmp_gamma_string[32];
1025
1026         Freespace_gamma += delta;
1027         if (Freespace_gamma < 0.1f) {
1028                 Freespace_gamma = 0.1f;
1029                 gamesnd_play_iface(SND_GENERAL_FAIL);
1030
1031         } else if (Freespace_gamma > 5.0f) {
1032                 Freespace_gamma = 5.0f;
1033                 gamesnd_play_iface(SND_GENERAL_FAIL);
1034
1035         } else {
1036                 gamesnd_play_iface(SND_USER_SELECT);
1037         }
1038
1039         gr_set_gamma(Freespace_gamma);
1040         sprintf(tmp_gamma_string, NOX("%.2f"), Freespace_gamma);
1041         os_config_write_string(NULL, NOX("Gamma"), tmp_gamma_string);
1042 }
1043
1044 void options_button_pressed(int n)
1045 {
1046         int choice;     
1047
1048         switch (n) {            
1049                 case OPTIONS_TAB:
1050                 case MULTIPLAYER_TAB:
1051                 case DETAIL_LEVELS_TAB: 
1052                         if (Tab != n)
1053                                 options_change_tab(n);
1054
1055                         break;
1056
1057                 case ABORT_GAME_BUTTON:
1058                         gamesnd_play_iface(SND_USER_SELECT);
1059                         choice = popup( PF_NO_NETWORKING | PF_BODY_BIG, 2, POPUP_NO, POPUP_YES, XSTR( "Exit Game?", 374));
1060                         if ( choice == 1 )
1061                                 gameseq_post_event(GS_EVENT_QUIT_GAME);
1062                         break;
1063
1064                 case CONTROL_CONFIG_BUTTON:
1065                         gamesnd_play_iface(SND_SWITCH_SCREENS);
1066                         gameseq_post_event(GS_EVENT_CONTROL_CONFIG);
1067                         break;                          
1068
1069                 case HUD_CONFIG_BUTTON:
1070 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1071                         game_feature_not_in_demo_popup();
1072 #else
1073                         // can't go to the hud config screen when a multiplayer observer
1074                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_OBSERVER)){
1075                                 gamesnd_play_iface(SND_GENERAL_FAIL);
1076                                 options_add_notify(XSTR( "Cannot use HUD config when an observer!", 375));
1077                                 break;
1078                         }
1079
1080                         gamesnd_play_iface(SND_SWITCH_SCREENS);
1081                         gameseq_post_event(GS_EVENT_HUD_CONFIG);
1082 #endif
1083                         break;
1084
1085                 case ACCEPT_BUTTON:
1086                         options_accept();
1087                         break;          
1088
1089                         // BEGIN - detail level tab buttons
1090
1091                 case HUD_TARGETVIEW_RENDER_ON:
1092                         Detail.targetview_model = 1;
1093                         gamesnd_play_iface(SND_USER_SELECT);
1094                         break;
1095
1096                 case HUD_TARGETVIEW_RENDER_OFF:
1097                         Detail.targetview_model = 0;
1098                         gamesnd_play_iface(SND_USER_SELECT);
1099                         break;
1100
1101                 case PLANETS_ON:
1102                         Detail.planets_suns = 1;
1103                         gamesnd_play_iface(SND_USER_SELECT);
1104                         break;
1105
1106                 case PLANETS_OFF:
1107                         Detail.planets_suns = 0;
1108                         gamesnd_play_iface(SND_USER_SELECT);
1109                         break;
1110
1111                 case WEAPON_EXTRAS_ON:
1112                         Detail.weapon_extras = 1;
1113                         gamesnd_play_iface(SND_USER_SELECT);
1114                         break;
1115
1116                 case WEAPON_EXTRAS_OFF:
1117                         Detail.weapon_extras = 0;
1118                         gamesnd_play_iface(SND_USER_SELECT);
1119                         break;          
1120
1121 #ifdef MAKE_FS1
1122                 case ENGINE_GLOWS_ON:
1123                         Detail.engine_glows = 1;
1124                         gamesnd_play_iface(SND_USER_SELECT);
1125                         break;
1126                 
1127                 case ENGINE_GLOWS_OFF:
1128                         Detail.engine_glows = 0;
1129                         gamesnd_play_iface(SND_USER_SELECT);
1130                         break;
1131 #endif
1132
1133                 case LOW_DETAIL_N:
1134                         options_detail_set_level(0);
1135                         gamesnd_play_iface(SND_USER_SELECT);
1136                         break;
1137
1138                 case MEDIUM_DETAIL_N:
1139                         options_detail_set_level(1);
1140                         gamesnd_play_iface(SND_USER_SELECT);
1141                         break;
1142
1143                 case HIGH_DETAIL_N:
1144                         options_detail_set_level(2);
1145                         gamesnd_play_iface(SND_USER_SELECT);
1146                         break;
1147
1148                 case VERY_HIGH_DETAIL_N:
1149                         options_detail_set_level(3);
1150                         gamesnd_play_iface(SND_USER_SELECT);
1151                         break;
1152
1153                 case CUSTOM_DETAIL_N:
1154                         options_detail_set_level(-1);
1155                         gamesnd_play_iface(SND_USER_SELECT);
1156                         break;
1157                         // END - detail level tab buttons
1158
1159                 case GAMMA_DOWN:
1160                         options_change_gamma(-0.05f);
1161                         break;
1162
1163                 case GAMMA_UP:
1164                         options_change_gamma(0.05f);
1165                         break;
1166
1167                 case BRIEF_VOICE_ON:
1168                         Briefing_voice_enabled = 1;
1169                         gamesnd_play_iface(SND_USER_SELECT);
1170                         break;
1171
1172                 case BRIEF_VOICE_OFF:
1173                         Briefing_voice_enabled = 0;
1174                         gamesnd_play_iface(SND_USER_SELECT);
1175                         break;
1176
1177                 case MOUSE_ON:
1178                         Use_mouse_to_fly = 1;
1179                         gamesnd_play_iface(SND_USER_SELECT);
1180                         break;
1181
1182                 case MOUSE_OFF:
1183                         Use_mouse_to_fly = 0;
1184                         gamesnd_play_iface(SND_USER_SELECT);
1185                         break;
1186         }
1187 }
1188
1189 void options_sliders_update()
1190 {
1191         // sound slider
1192         if (Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos != Sound_volume_int) {
1193                 Sound_volume_int = Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos;
1194                 Master_sound_volume = ((float) (Sound_volume_int) / 9.0f);
1195                 set_sound_volume();
1196                 gamesnd_play_iface(SND_USER_SELECT);
1197         }
1198
1199         // music slider
1200         if (Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos != Music_volume_int) {
1201                 Music_volume_int = Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos;
1202                 Master_event_music_volume = ((float) (Music_volume_int) / 9.0f);
1203                 if (Master_event_music_volume > 0.0f) {
1204                         event_music_enable();
1205                 }
1206
1207                 set_music_volume();
1208                 gamesnd_play_iface(SND_USER_SELECT);
1209         }
1210
1211         // voice slider
1212         if (Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos != Voice_volume_int) {
1213                 Voice_volume_int = Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos;
1214                 Master_voice_volume = ((float) (Voice_volume_int) / 9.0f);
1215                 set_voice_volume();
1216                 options_play_voice_clip();
1217         }
1218
1219         if (Mouse_sensitivity != Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos) {
1220                 Mouse_sensitivity = Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos;
1221                 gamesnd_play_iface(SND_USER_SELECT);
1222         }
1223
1224         if (Joy_sensitivity != Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos) {
1225                 Joy_sensitivity = Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos;
1226                 gamesnd_play_iface(SND_USER_SELECT);
1227         }
1228
1229         if (Dead_zone_size != Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5) {
1230                 Dead_zone_size = Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos * 5;
1231                 gamesnd_play_iface(SND_USER_SELECT);
1232         }
1233
1234         if (Game_skill_level != Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos) {
1235                 Game_skill_level = Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos;
1236                 gamesnd_play_iface(SND_USER_SELECT);
1237         }
1238 }
1239
1240 void options_accept()
1241 {
1242         // apply the selected multiplayer options
1243         if ( Options_multi_inited ) {
1244                 #if !defined(DEMO) && !defined(OEM_BUILD) // not for FS2_DEMO
1245                 options_multi_accept();
1246                 #endif
1247         }
1248
1249         // If music is zero volume, disable
1250         if ( Master_event_music_volume <= 0.0f ) {
1251 //              event_music_disable();
1252                 event_music_level_close();
1253         }
1254
1255         // apply other options (display options, etc)
1256         // note: return in here (and play failed sound) if they can't accept yet for some reason
1257
1258         gamesnd_play_iface(SND_COMMIT_PRESSED);
1259         gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
1260 }
1261
1262 void options_load_background_and_mask(int tab)
1263 {
1264         SDL_assert(tab == OPTIONS_TAB || tab == DETAIL_LEVELS_TAB );
1265         Backgrounds[gr_screen.res][tab].bitmap = bm_load(Backgrounds[gr_screen.res][tab].filename);
1266         Backgrounds[gr_screen.res][tab].mask = bm_load(Backgrounds[gr_screen.res][tab].mask_filename);
1267 }
1268
1269 int Gamma_last_set = -1;
1270 int Gamma_colors_inited = 0;
1271
1272 void options_menu_init()
1273 {
1274         int i, j;
1275         options_buttons *b;
1276
1277         SDL_assert(!Options_menu_inited);
1278
1279         // pause all sounds, since we could get here through the game
1280         beam_pause_sounds();
1281         //audiostream_pause_all();
1282
1283         Tab = 0;
1284         Gamma_last_set = -1;
1285
1286         common_set_interface_palette("InterfacePalette");  // set the interface palette
1287         Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0);
1288
1289         for (i=0; i<PLANETS_ON; i++) {
1290                 b = &Buttons[gr_screen.res][i];
1291
1292                 b->button.create(&Ui_window, "", b->x, b->y, 60, 30, b->flags & REPEAT, 1);
1293                 // set up callback for when a mouse first goes over a button
1294                 if (b->filename) {
1295                         b->button.set_bmaps(b->filename);
1296                         if ( !(b->flags & NO_MOUSE_OVER_SOUND) ) {
1297                                 b->button.set_highlight_action(common_play_highlight_sound);
1298                         }
1299
1300                 } else {
1301                         b->button.hide();
1302                 }
1303
1304                 b->button.link_hotspot(b->hotspot);
1305                 if (i < NUM_COMMONS) {
1306                         for (j=0; j<MAX_BMAPS_PER_GADGET; j++){
1307                                 Button_bms[i][j] = b->button.bmap_ids[j];
1308                         }
1309                 }
1310         }
1311
1312 #ifndef MAKE_FS1
1313         // add all xstr text
1314         for(i=0; i<OPTIONS_NUM_TEXT; i++){
1315                 Ui_window.add_XSTR(&Options_text[gr_screen.res][i]);
1316         }
1317 #endif
1318
1319         // bogus controls
1320         Detail_bogus.base_create(&Ui_window, UI_KIND_ICON, 0, 0, 0, 0);
1321         Options_bogus.base_create(&Ui_window, UI_KIND_ICON, 0, 0, 0, 0);
1322
1323         Buttons[gr_screen.res][GAMMA_DOWN].button.set_hotkey(SDLK_COMMA);
1324         Buttons[gr_screen.res][GAMMA_UP].button.set_hotkey(SDLK_PERIOD);
1325
1326         /*
1327         Skill_control.first_frame = bm_load_animation("OPa_11", &Skill_control.total_frames);
1328         if (Skill_control.first_frame < 0) {
1329                 Error(LOCATION, "Could not load OPa_11.ani\n");
1330                 return;
1331         }
1332         */
1333
1334         for (i=0; i<NUM_TABS; i++) {
1335                 Backgrounds[gr_screen.res][i].bitmap = -1;
1336                 Backgrounds[gr_screen.res][i].mask = -1;
1337         }
1338
1339         options_load_background_and_mask(OPTIONS_TAB);
1340         options_tab_setup(0);
1341
1342         Backup_skill_level = Game_skill_level;
1343         Backup_sound_volume = Master_sound_volume;
1344         Backup_music_volume = Master_event_music_volume;
1345         Backup_voice_volume = Master_voice_volume;
1346         Backup_briefing_voice_enabled = Briefing_voice_enabled;
1347         Backup_use_mouse_to_fly = Use_mouse_to_fly;
1348         
1349         // create slider        
1350         for ( i = 0; i < NUM_OPTIONS_SLIDERS; i++ ) {
1351                  Options_sliders[gr_screen.res][i].slider.create(&Ui_window, Options_sliders[gr_screen.res][i].x, Options_sliders[gr_screen.res][i].y,
1352                                                                                                                                                 Options_sliders[gr_screen.res][i].dots, Options_sliders[gr_screen.res][i].filename,
1353                                                                                                                                                 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,
1354                                                                                                                                                 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,
1355                                                                                                                                                 Options_sliders[gr_screen.res][i].dot_w);
1356         }       
1357
1358         // maybe disable the skill slider
1359         if( ((Game_mode & GM_IN_MISSION) && (!popupdead_is_active())) || (Game_mode & GM_MULTIPLAYER) ) {
1360                 Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.disable();
1361                 Ui_window.use_hack_to_get_around_stupid_problem_flag = 0;
1362         }
1363         
1364         // setup slider values 
1365         // note slider scale is 0-9, while Master_ values calc with 1-10 scale (hence the -1)
1366         Sound_volume_int = Options_sliders[gr_screen.res][OPT_SOUND_VOLUME_SLIDER].slider.pos = (int) (Master_sound_volume * 9.0f + 0.5f);
1367         Music_volume_int = Options_sliders[gr_screen.res][OPT_MUSIC_VOLUME_SLIDER].slider.pos = (int) (Master_event_music_volume * 9.0f + 0.5f);        
1368         Voice_volume_int = Options_sliders[gr_screen.res][OPT_VOICE_VOLUME_SLIDER].slider.pos = (int) (Master_voice_volume * 9.0f + 0.5f);
1369         Options_sliders[gr_screen.res][OPT_JOY_SENS_SLIDER].slider.pos = Joy_sensitivity;       
1370         Options_sliders[gr_screen.res][OPT_JOY_DEADZONE_SLIDER].slider.pos = Dead_zone_size / 5;        
1371         Options_sliders[gr_screen.res][OPT_MOUSE_SENS_SLIDER].slider.pos = Mouse_sensitivity;
1372         Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos = Game_skill_level;
1373
1374         Gamma_colors_inited = 0;
1375
1376         // used to allow all keystrokes, even when called from a demo playback
1377         key_clear_filter();
1378         Options_menu_inited = 1;
1379
1380         // hide options crap
1381         options_detail_hide_stuff();
1382 }
1383
1384 void options_menu_close()
1385 {
1386         int i;  
1387
1388         SDL_assert(Options_menu_inited);        
1389
1390         for (i=0; i<NUM_TABS; i++) {
1391                 if (Backgrounds[gr_screen.res][i].bitmap >= 0){
1392                         bm_unload(Backgrounds[gr_screen.res][i].bitmap);
1393                 }
1394                 if ((Backgrounds[gr_screen.res][i].mask >= 0) && (i != Tab)){  // Ui_window.destroy() expects to release current tab's mask.
1395                         bm_unload(Backgrounds[gr_screen.res][i].mask);
1396                 }
1397         }
1398
1399         if ( Voice_vol_handle >= 0 ) {
1400                 snd_stop(Voice_vol_handle);
1401                 Voice_vol_handle = -1;
1402         }
1403
1404 #if !defined(DEMO) && !defined(OEM_BUILD) // not for FS2_DEMO
1405         options_multi_close();
1406 #endif
1407
1408         Ui_window.destroy();
1409         common_free_interface_palette();                // restore game palette
1410         write_pilot_file();
1411         game_flush();
1412         
1413         // unpause all sounds, since we could be headed back to the game
1414         beam_unpause_sounds();
1415         //audiostream_unpause_all();
1416         
1417         Options_menu_inited = 0;
1418         Options_multi_inited = 0;
1419         Options_detail_inited = 0;
1420
1421
1422 }
1423
1424
1425 void draw_gamma_box()
1426 {
1427         int x, y, v;
1428
1429 // 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)
1430 // TODO: change MAX size to maximum size for a 1024x768 bitmap
1431 //      ushort Gamma_data[Options_gamma_coords[gr_screen.res][OPTIONS_W_COORD]*Options_gamma_coords[gr_screen.res][OPTIONS_H_COORD]*2];
1432         ushort Gamma_data[MAX_GAMMA_BITMAP_SIZE];
1433
1434         v = fl2i( pow(0.5f, 1.0f / Freespace_gamma) * 255.0f );
1435         if (v > 255){
1436                 v = 255;
1437         } else if (v < 0){
1438                 v = 0;
1439         }
1440
1441         int Gamma_changed = 0;
1442         if ( v != Gamma_last_set )      {
1443                 Gamma_changed = 1;
1444         } else {
1445                 Gamma_changed = 0;
1446         }
1447         Gamma_last_set = v;
1448
1449         {
1450                 ushort clr_full_white = 0;
1451                 ushort clr_half_white = 0;
1452                 ubyte r, g, b, a;
1453
1454                 BM_SELECT_TEX_FORMAT();
1455
1456                 // set full white
1457                 r = g = b = a = 255;            
1458                 bm_set_components((ubyte*)&clr_full_white, &r, &g, &b, &a);
1459
1460                 // set half white
1461                 r = g = b = (ubyte)v;
1462                 bm_set_components((ubyte*)&clr_half_white, &r, &g, &b, &a);
1463
1464                 ushort *dptr = Gamma_data;
1465                 for (y=0; y<Options_gamma_coords[gr_screen.res][OPTIONS_H_COORD]; y++) {
1466                         for (x=0; x<Options_gamma_coords[gr_screen.res][OPTIONS_W_COORD]; x++) {
1467                                 if ((x / 20) & 1) {
1468                                         *dptr = clr_half_white;
1469                                 } else {
1470                                         if ((x & 1) == (y & 1)) {
1471                                                 *dptr = clr_full_white;
1472                                         } else {
1473                                                 *dptr = 0;
1474                                         }
1475                                 }
1476                                 dptr++;
1477                         }
1478                 }
1479
1480                 // always go back to screen format
1481                 BM_SELECT_SCREEN_FORMAT();
1482
1483                 // if we're in bitmap poly mode         
1484                 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 );
1485                 gr_set_bitmap(Gamma_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1486                 gr_bitmap( Options_gamma_coords[gr_screen.res][OPTIONS_X_COORD], Options_gamma_coords[gr_screen.res][OPTIONS_Y_COORD] );
1487
1488                 bm_release( Gamma_bitmap );
1489
1490         }
1491 }
1492
1493
1494 void options_menu_do_frame(float frametime)
1495 {
1496         int i, k, x, y; 
1497
1498         SDL_assert(Options_menu_inited);
1499         k = Ui_window.process() & ~KEY_DEBUGGED;
1500         switch (k) {
1501                 case KEY_SHIFTED | SDLK_TAB:
1502                 case SDLK_LEFT:  // activate previous tab
1503                         i = Tab - 1;
1504                         if (i < 0)
1505                                 i = NUM_TABS - 1;
1506
1507                         options_change_tab(i);
1508                         break;
1509
1510                 case SDLK_TAB:
1511                 case SDLK_RIGHT:  // activate next tab
1512                         // check to see if the multiplayer options screen wants to eat the tab kay
1513                         if ((k == SDLK_TAB) && (Tab == MULTIPLAYER_TAB)) {
1514                                 if (options_multi_eat_tab()) {
1515                                         break;
1516                                 }
1517                         }
1518
1519                         i = Tab + 1;
1520                         if (i >= NUM_TABS)
1521                                 i = 0;
1522
1523                         options_change_tab(i);
1524                         break;
1525
1526                 case SDLK_c:
1527                         if (Tab == OPTIONS_TAB) {
1528                                 gamesnd_play_iface(SND_SWITCH_SCREENS);
1529                                 gameseq_post_event(GS_EVENT_CONTROL_CONFIG);
1530                         }
1531
1532                         break;
1533
1534                 case SDLK_h:
1535                         if (Tab == OPTIONS_TAB) {
1536                                 gamesnd_play_iface(SND_SWITCH_SCREENS);
1537                                 gameseq_post_event(GS_EVENT_HUD_CONFIG);
1538                         }
1539
1540                         break;
1541
1542                 case SDLK_ESCAPE:
1543                         // if(Tab != MULTIPLAYER_TAB){
1544                                 options_cancel_exit();
1545                         // }
1546                         break;
1547
1548                 case KEY_CTRLED | SDLK_RETURN:
1549                         options_accept();
1550                         break;
1551
1552                 case SDLK_DELETE:
1553                         break;
1554
1555                 case SDLK_RETURN:
1556                         break;
1557         }       
1558
1559         for (i=0; i<NUM_BUTTONS; i++) {
1560                 if (Buttons[gr_screen.res][i].button.pressed())
1561                         options_button_pressed(i);
1562         }
1563
1564         options_sliders_update();
1565
1566         // if we're in the multiplayer options tab, get the background bitmap from the options multi module
1567         if(Tab == MULTIPLAYER_TAB){
1568                 i = options_multi_background_bitmap();
1569         } else {
1570                 i = Backgrounds[gr_screen.res][Tab].bitmap;
1571         }
1572
1573         GR_MAYBE_CLEAR_RES(i);
1574         if (i >= 0) {
1575                 gr_set_bitmap(i, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1576                 gr_bitmap(0, 0);
1577         } 
1578
1579         Ui_window.draw();
1580
1581         // NOTE : this must be done here so that any special drawing crap we do is not overwritten by the UI_WINDOW::draw() call
1582         // do specific processing for the multiplayer tab
1583         switch (Tab) {
1584                 case MULTIPLAYER_TAB:
1585 #if !defined(DEMO) && !defined(OEM_BUILD) // not for FS2_DEMO
1586                         options_multi_do(k);
1587 #endif
1588                         break;
1589
1590                 case DETAIL_LEVELS_TAB:
1591                         options_detail_do_frame();
1592                         break;
1593
1594                 default:
1595                         Game_skill_level = Options_sliders[gr_screen.res][OPT_SKILL_SLIDER].slider.pos;
1596                         break;
1597         }
1598
1599         // handle the displaying of any notification messages
1600         options_notify_do_frame();
1601
1602         for (i=0; i<NUM_TABS; i++){
1603                 if (Buttons[gr_screen.res][i].button.button_down()){
1604                         break;
1605                 }
1606         }
1607
1608         if ((i == NUM_TABS) /*&& (Tab != MULTIPLAYER_TAB)*/ ){
1609                 Buttons[gr_screen.res][Tab].button.draw_forced(2);
1610         }
1611
1612         if (Tab == OPTIONS_TAB) {
1613                 // draw correct frame for briefing voice radio buttons
1614                 if (Briefing_voice_enabled) {
1615                         options_force_button_frame(BRIEF_VOICE_ON, 2);
1616                         options_force_button_frame(BRIEF_VOICE_OFF, 0);
1617
1618                 } else {
1619                         options_force_button_frame(BRIEF_VOICE_OFF, 2);
1620                         options_force_button_frame(BRIEF_VOICE_ON, 0);
1621                 }
1622
1623                 if (Use_mouse_to_fly) {
1624                         options_force_button_frame(MOUSE_ON, 2);
1625                         options_force_button_frame(MOUSE_OFF, 0);
1626
1627                 } else {
1628                         options_force_button_frame(MOUSE_OFF, 2);
1629                         options_force_button_frame(MOUSE_ON, 0);
1630                 }               
1631
1632                 int w;
1633                 gr_get_string_size(&w, NULL, Skill_level_names(Game_skill_level));
1634                 x = Options_skills_text_coords[gr_screen.res][OPTIONS_X_COORD];
1635                 y = Options_skills_text_coords[gr_screen.res][OPTIONS_Y_COORD];
1636                 gr_set_color_fast(&Color_bright_white);
1637                 gr_string(x + (Options_skills_text_coords[gr_screen.res][OPTIONS_W_COORD] / 2) - (w/2), y, Skill_level_names(Game_skill_level));
1638         }
1639
1640         
1641         //==============================================================================
1642         // Draw the gamma adjustment grid.
1643         if (Tab == OPTIONS_TAB) {
1644
1645                 draw_gamma_box();
1646                 
1647                 gr_set_color_fast(&Color_white);
1648                 x = Options_gamma_num_coords[gr_screen.res][OPTIONS_X_COORD]; //  + Options_gamma_num_coords[gr_screen.res][OPTIONS_W_COORD] / 2 - 12;
1649                 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;
1650
1651                 gr_printf(x, y, NOX("%.2f"), Freespace_gamma);
1652                 //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.");
1653         }
1654         //==============================================================================
1655
1656         // maybe blit a waveform
1657         if(Tab == MULTIPLAYER_TAB){
1658                 options_multi_vox_process_waveform();
1659         }
1660         
1661 /*  Debug code: Graphs the joystick range scaling
1662 {
1663 int joy_get_scaled_reading(int raw, int axn);
1664         int x, y;
1665
1666         gr_set_color_fast(&Color_white);
1667         for (x=0; x<256; x+=16) {
1668                 gr_line(x + 15, 0, x + 15, 255);
1669                 gr_line(0, x + 15, 255, x + 15);
1670         }
1671
1672         gr_set_color_fast(&Color_bright_white);
1673         for (x=0; x<256; x++) {
1674                 y = joy_get_scaled_reading(x * 256, 0) / 512;
1675                 gr_line(x, 128, x, 128 + y);
1676         }
1677 }*/     
1678
1679         gr_flip();
1680 }
1681
1682
1683 // ---------------------------------------------------------------------------------------------------------
1684 // DETAIL LEVEL OPTIONS definitions  BEGIN
1685 //
1686
1687 void options_detail_synch_sliders()
1688 {
1689         Detail_slider_pos[DETAIL_DISTANCE_SLIDER] = Detail_sliders[gr_screen.res][DETAIL_DISTANCE_SLIDER].slider.pos = Detail.detail_distance;
1690         Detail_slider_pos[NEBULA_DETAIL_SLIDER] = Detail_sliders[gr_screen.res][NEBULA_DETAIL_SLIDER].slider.pos = Detail.nebula_detail;
1691         Detail_slider_pos[HARDWARE_TEXTURES_SLIDER] = Detail_sliders[gr_screen.res][HARDWARE_TEXTURES_SLIDER].slider.pos = Detail.hardware_textures;    
1692         Detail_slider_pos[SHARD_CULLING_SLIDER] = Detail_sliders[gr_screen.res][SHARD_CULLING_SLIDER].slider.pos = Detail.num_small_debris;
1693         Detail_slider_pos[SHIELD_DETAIL_SLIDER] = Detail_sliders[gr_screen.res][SHIELD_DETAIL_SLIDER].slider.pos = Detail.shield_effects;
1694         Detail_slider_pos[NUM_STARS_SLIDER] = Detail_sliders[gr_screen.res][NUM_STARS_SLIDER].slider.pos = Detail.num_stars;
1695         Detail_slider_pos[NUM_PARTICLES_SLIDER] = Detail_sliders[gr_screen.res][NUM_PARTICLES_SLIDER].slider.pos = Detail.num_particles;
1696         Detail_slider_pos[LIGHTING_SLIDER] = Detail_sliders[gr_screen.res][LIGHTING_SLIDER].slider.pos = Detail.lighting;
1697 #ifdef MAKE_FS1
1698         // this doesn't do anything since it's affects are included in the other sliders now
1699         // so lets just max it out to avoid it looking bad at 0
1700         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;
1701 #endif
1702 }
1703
1704 void options_detail_init()
1705 {
1706         int i;
1707         options_buttons *b;
1708
1709         Detail_original = Detail;
1710
1711         options_load_background_and_mask(DETAIL_LEVELS_TAB);
1712
1713         for (i=PLANETS_ON; i<NUM_BUTTONS; i++) {
1714                 b = &Buttons[gr_screen.res][i];
1715
1716                 b->button.create(&Ui_window, "", b->x, b->y, 60, 30, b->flags & REPEAT, 1);
1717                 // set up callback for when a mouse first goes over a button
1718                 if (b->filename) {
1719                         b->button.set_bmaps(b->filename);
1720                         if ( !(b->flags & NO_MOUSE_OVER_SOUND) ) {
1721                                 b->button.set_highlight_action(common_play_highlight_sound);
1722                         }
1723
1724                 } else {
1725                         b->button.hide();
1726                 }
1727
1728                 b->button.link_hotspot(b->hotspot);
1729         }
1730
1731         // create detail level sliders  
1732         for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1733                 Detail_sliders[gr_screen.res][i].slider.create(&Ui_window, Detail_sliders[gr_screen.res][i].x, Detail_sliders[gr_screen.res][i].y,
1734                                                                                                                                                 Detail_sliders[gr_screen.res][i].dots, Detail_sliders[gr_screen.res][i].filename,
1735                                                                                                                                                 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,
1736                                                                                                                                                 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,
1737                                                                                                                                                 Detail_sliders[gr_screen.res][i].dot_w);
1738         }
1739
1740         // init the actual slider positions and our internal positions
1741         options_detail_synch_sliders();
1742 }
1743
1744 void options_detail_sliders_update()
1745 {
1746         int i;
1747
1748         for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1749                 if ( Detail_sliders[gr_screen.res][i].slider.pos != Detail_slider_pos[i] ) {
1750                         Detail_slider_pos[i] = Detail_sliders[gr_screen.res][i].slider.pos;
1751                         gamesnd_play_iface(SND_USER_SELECT);
1752                 }
1753         }
1754
1755         // set Detail based on slider positions
1756         Detail.detail_distance = Detail_sliders[gr_screen.res][DETAIL_DISTANCE_SLIDER].slider.pos;
1757
1758         // modify nebula stuff
1759         Detail.nebula_detail = Detail_sliders[gr_screen.res][NEBULA_DETAIL_SLIDER].slider.pos;
1760         neb2_set_detail_level(Detail.nebula_detail);
1761
1762         Detail.hardware_textures = Detail_sliders[gr_screen.res][HARDWARE_TEXTURES_SLIDER].slider.pos;  
1763         Detail.num_small_debris = Detail_sliders[gr_screen.res][SHARD_CULLING_SLIDER].slider.pos;
1764         Detail.shield_effects = Detail_sliders[gr_screen.res][SHIELD_DETAIL_SLIDER].slider.pos;
1765         Detail.num_stars = Detail_sliders[gr_screen.res][NUM_STARS_SLIDER].slider.pos;
1766         Detail.num_particles = Detail_sliders[gr_screen.res][NUM_PARTICLES_SLIDER].slider.pos;
1767         Detail.lighting = Detail_sliders[gr_screen.res][LIGHTING_SLIDER].slider.pos;
1768 }
1769
1770 void options_detail_hide_stuff()
1771 {
1772         int i;
1773
1774         for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1775                 Detail_sliders[gr_screen.res][i].slider.disable();
1776                 Detail_sliders[gr_screen.res][i].slider.hide();
1777         }
1778
1779         // this will hide text unassociated with any real control
1780         Detail_bogus.hide();
1781 }
1782
1783 void options_detail_unhide_stuff()
1784 {
1785         int i;
1786
1787         for ( i = 0; i < NUM_DETAIL_SLIDERS; i++ ) {
1788                 Detail_sliders[gr_screen.res][i].slider.enable();
1789                 Detail_sliders[gr_screen.res][i].slider.unhide();
1790         }
1791
1792         // this will hide text unassociated with any real control
1793         Detail_bogus.unhide();
1794 }
1795
1796 void options_force_button_frame(int n, int frame_num)
1797 {
1798         if ( !Buttons[gr_screen.res][n].button.button_down() ) {
1799                 Buttons[gr_screen.res][n].button.draw_forced(frame_num);
1800         }
1801 }
1802
1803 // called once per frame to set lit buttons
1804 void options_detail_do_frame()
1805 {
1806         options_detail_sliders_update();        
1807
1808         // force on/off buttons to draw their correct setting
1809
1810         if ( Detail.targetview_model ) {
1811                 options_force_button_frame(HUD_TARGETVIEW_RENDER_ON, 2);
1812                 options_force_button_frame(HUD_TARGETVIEW_RENDER_OFF, 0);
1813         } else {
1814                 options_force_button_frame(HUD_TARGETVIEW_RENDER_OFF, 2);
1815                 options_force_button_frame(HUD_TARGETVIEW_RENDER_ON, 0);
1816         }
1817
1818         if ( Detail.planets_suns == 1 ) {
1819                 options_force_button_frame(PLANETS_ON, 2);
1820                 options_force_button_frame(PLANETS_OFF, 0);
1821         } else {
1822                 options_force_button_frame(PLANETS_OFF, 2);
1823                 options_force_button_frame(PLANETS_ON, 0);
1824         }
1825
1826         if ( Detail.weapon_extras) {
1827                 options_force_button_frame(WEAPON_EXTRAS_ON, 2);
1828                 options_force_button_frame(WEAPON_EXTRAS_OFF, 0);
1829         } else {
1830                 options_force_button_frame(WEAPON_EXTRAS_OFF, 2);
1831                 options_force_button_frame(WEAPON_EXTRAS_ON, 0);
1832         }       
1833
1834 #ifdef MAKE_FS1
1835         if ( Detail.engine_glows) {
1836                 options_force_button_frame(ENGINE_GLOWS_ON, 2);
1837                 options_force_button_frame(ENGINE_GLOWS_OFF, 0);
1838         } else {
1839                 options_force_button_frame(ENGINE_GLOWS_OFF, 2);
1840                 options_force_button_frame(ENGINE_GLOWS_ON, 0);
1841         }
1842 #endif
1843
1844         int current_detail;
1845
1846         if ( Detail.setting >= 0 ) {
1847                 current_detail = current_detail_level();
1848                 Detail.setting = current_detail;
1849         } else {
1850                 current_detail = -1;
1851         }
1852
1853         options_force_button_frame(LOW_DETAIL_N, 0);
1854         options_force_button_frame(MEDIUM_DETAIL_N, 0);
1855         options_force_button_frame(HIGH_DETAIL_N, 0);
1856         options_force_button_frame(VERY_HIGH_DETAIL_N, 0);
1857         options_force_button_frame(CUSTOM_DETAIL_N, 0);
1858
1859         switch ( current_detail ) {
1860         case -1:
1861                 options_force_button_frame(CUSTOM_DETAIL_N, 2);
1862                 break;
1863         case 0:
1864                 options_force_button_frame(LOW_DETAIL_N, 2);
1865                 break;
1866         case 1:
1867                 options_force_button_frame(MEDIUM_DETAIL_N, 2);
1868                 break;
1869         case 2:
1870                 options_force_button_frame(HIGH_DETAIL_N, 2);
1871                 break;
1872         case 3:
1873                 options_force_button_frame(VERY_HIGH_DETAIL_N, 2);
1874                 break;
1875         }
1876 }
1877
1878 // Set all the detail settings to a predefined level
1879 void options_detail_set_level(int level)
1880 {
1881         detail_level_set(level);
1882         options_detail_synch_sliders();
1883 }
1884
1885 //
1886 // DETAIL LEVEL tab definitions END
1887 // ---------------------------------------------------------------------------------------------------------
1888
1889