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