]> icculus.org git repositories - taylor/freespace2.git/blob - src/hud/hudconfig.cpp
clean up and simplify effects and updating
[taylor/freespace2.git] / src / hud / hudconfig.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/Hud/HUDconfig.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C module to handle HUD configuration
16  *
17  * $Log$
18  * Revision 1.7  2005/03/29 02:18:47  taylor
19  * Various 64-bit platform fixes
20  * Fix compiler errors with MAKE_FS1 and fix gr_set_bitmap() too
21  * Make sure that turrets can fire at asteroids for FS1 (needed for a couple missions)
22  * Streaming audio support (big thanks to Pierre Willenbrock!!)
23  * Removed dependance on strings.tbl for FS1 since we don't actually need it now
24  *
25  * Revision 1.6  2004/09/20 01:31:44  theoddone33
26  * GCC 3.4 fixes.
27  *
28  * Revision 1.5  2003/05/25 02:30:42  taylor
29  * Freespace 1 support
30  *
31  * Revision 1.4  2002/06/09 04:41:21  relnev
32  * added copyright header
33  *
34  * Revision 1.3  2002/06/01 07:12:33  relnev
35  * a few NDEBUG updates.
36  *
37  * removed a few warnings.
38  *
39  * Revision 1.2  2002/05/07 03:16:45  theoddone33
40  * The Great Newline Fix
41  *
42  * Revision 1.1.1.1  2002/05/03 03:28:09  root
43  * Initial import.
44  *
45  * 
46  * 19    10/25/99 5:43p Jefff
47  * reassigned some xstr ids
48  * 
49  * 18    10/14/99 2:50p Jefff
50  * localization fixes
51  * 
52  * 17    9/02/99 5:09p Jefff
53  * disabled options now draw as a dark gray color
54  * 
55  * 16    9/01/99 11:16a Dave
56  * Reverse direction of HUD config RGB sliders.
57  * 
58  * 15    8/19/99 3:17p Dave
59  * Fixed talking head disappearing.
60  * 
61  * 14    8/19/99 2:33p Dave
62  * Make sure support gauge and net lag gauge are configurable.
63  * 
64  * 13    8/16/99 5:25p Dave
65  * New hud config. Whee!
66  * 
67  * 12    8/16/99 4:04p Dave
68  * Big honking checkin.
69  * 
70  * 11    7/30/99 10:31p Dave
71  * Added comm menu to the configurable hud files.
72  * 
73  * 10    7/30/99 11:05a Jasenw
74  * Fixed hud config for new text warning gauge,
75  * 
76  * 9     7/24/99 1:54p Dave
77  * Hud text flash gauge. Reworked dead popup to use 4 buttons in red-alert
78  * missions.
79  * 
80  * 8     7/15/99 9:20a Andsager
81  * FS2_DEMO initial checkin
82  * 
83  * 7     6/08/99 2:33p Dave
84  * Fixed release build warning. Put in hud config stuff.
85  * 
86  * 6     6/08/99 1:14a Dave
87  * Multi colored hud test.
88  * 
89  * 5     1/30/99 5:08p Dave
90  * More new hi-res stuff.Support for nice D3D textures.
91  * 
92  * 4     10/13/98 9:28a Dave
93  * Started neatening up freespace.h. Many variables renamed and
94  * reorganized. Added AlphaColors.[h,cpp]
95  * 
96  * 3     10/07/98 11:28a Dave
97  * Removed wacky pragma.
98  * 
99  * 2     10/07/98 10:53a Dave
100  * Initial checkin.
101  * 
102  * 1     10/07/98 10:49a Dave
103  * 
104  * 72    8/25/98 1:48p Dave
105  * First rev of EMP effect. Player side stuff basically done. Next comes
106  * AI code.
107  * 
108  * 71    6/09/98 10:31a Hoffoss
109  * Created index numbers for all xstr() references.  Any new xstr() stuff
110  * added from here on out should be added to the end if the list.  The
111  * current list count can be found in FreeSpace.cpp (search for
112  * XSTR_SIZE).
113  * 
114  * 70    6/01/98 11:43a John
115  * JAS & MK:  Classified all strings for localization.
116  * 
117  * 69    5/24/98 9:01p Lawrance
118  * Add commit sounds when accept is pressed
119  * 
120  * 68    5/23/98 3:31p Dave
121  * Tweaked pxo code. Fixed observer HUD stuff.
122  * 
123  * 67    5/08/98 10:12a Lawrance
124  * play sound for auto-target toggle, don't display HUD message
125  * 
126  * 66    4/29/98 6:00p Dave
127  * Fixed chatbox font colors. Made observer offscreen indicators work.
128  * Numerous small UI fixes. Fix rank limitations for mp games. 
129  * 
130  * 65    4/20/98 12:04a Lawrance
131  * tweak how button light up 
132  * 
133  * 64    4/16/98 4:07p Hoffoss
134  * Fixed bug with palette reseting when loading a new pilot.  Also made
135  * barracks default to palette merging mode.
136  * 
137  * 63    4/16/98 10:48a Lawrance
138  * reposition a couple of gauges
139  * 
140  * 62    4/14/98 6:16p Lawrance
141  * Fix bug that was preventing non-green HUD color from getting set.
142  * 
143  * 61    4/12/98 5:32p Lawrance
144  * don't show talking head in demo version of hud config
145  * 
146  * 60    4/10/98 12:07a Lawrance
147  * Fix up talking head gauge.
148  * 
149  * 59    4/08/98 10:15a Lawrance
150  * allow kills gauge to be popup
151  * 
152  * 58    4/08/98 1:18a Lawrance
153  * Add in kills gauge art to HUD config.
154  * 
155  * 57    4/05/98 7:42p Lawrance
156  * Add kills gauge
157  * 
158  * 56    4/03/98 3:13p Dave
159  * More work on udp reliable transport. Fixed observer hud offset problem.
160  * Made observer join and ingame join work again. Put subnet broadcasting
161  * in for TCP.
162  * 
163  * 55    4/01/98 6:46p Lawrance
164  * default damage popup to on
165  * 
166  * 54    3/31/98 11:47p Lawrance
167  * Add popup functionality for the countermeasure gauge.
168  * 
169  * 53    3/30/98 4:48p Lawrance
170  * Turn on offscreen indicator range by default
171  * 
172  * 52    3/26/98 5:45p Lawrance
173  * Added new gauges to HUD config
174  * 
175  * 51    3/15/98 4:17p Dave
176  * Fixed oberver hud problems. Put in handy netplayer macros. Reduced size
177  * of network orientation matrices.
178  * 
179  * 50    3/12/98 5:45p Dave
180  * Put in new observer HUD. Made it possible for observers to join at the
181  * beginning of a game and follow it around as an observer full-time.
182  * 
183  * 49    3/11/98 12:13a Lawrance
184  * redraw pressed buttons
185  * 
186  * 48    3/05/98 12:39a Lawrance
187  * show comma in 10000
188  * 
189  * 47    2/22/98 4:30p John
190  * More string externalization classification
191  * 
192  * 46    2/22/98 4:17p John
193  * More string externalization classification... 190 left to go!
194  * 
195  * 45    2/22/98 12:19p John
196  * Externalized some strings
197  * 
198  * 44    1/23/98 6:24p Lawrance
199  * Implement wingman status gauge
200  * 
201  * 43    1/22/98 10:45p Lawrance
202  * Add coutermeasures and objective display to hud config.
203  * 
204  * 42    1/19/98 11:37p Lawrance
205  * Fixing Optimization build warnings
206  * 
207  * 41    1/17/98 10:02p Lawrance
208  * Fix bug with damage popup that would sometimes display with <none>.
209  * 
210  * 40    1/17/98 1:30a Lawrance
211  * Add countermeasure gauge
212  * 
213  * 39    1/15/98 5:10p Allender
214  * ton of interface changes.  chatbox in multiplayer now behaves
215  * differently than before.  It's always active in any screen that uses
216  * it.  Only non-printatble characters will get passed back out from
217  * chatbox
218  * 
219  * 38    1/14/98 11:07p Lawrance
220  * Hook in brightness slider to HUD config.
221  * 
222  * 37    1/14/98 6:42p Hoffoss
223  * Massive changes to UI code.  A lot cleaner and better now.  Did all
224  * this to get the new UI_DOT_SLIDER to work properly, which the old code
225  * wasn't flexible enough to handle.
226  * 
227  * 36    1/14/98 12:25p Lawrance
228  * center gauge text, use correct game palette.
229  * 
230  * 35    1/13/98 5:33p Lawrance
231  * Tweaking HUD config.
232  * 
233  * 34    1/13/98 2:20p John
234  * Added code to load palette based on hud color.  Added code to turn off
235  * nebulas using detail.  Added code in WinMain to time out after waiting
236  * too long for window creation.    
237  * 
238  * 33    1/13/98 10:22a Lawrance
239  * Integrate new art changes.
240  * 
241  * 32    1/12/98 11:16p Lawrance
242  * Wonderful HUD config.
243  * 
244  * 31    1/10/98 12:41a Lawrance
245  * start work on new HUD config
246  * 
247  * 30    1/05/98 9:38p Lawrance
248  * Implement flashing HUD gauges.
249  * 
250  * 29    1/02/98 9:10p Lawrance
251  * Big changes to how colors get set on the HUD.
252  * 
253  * 28    12/16/97 9:13p Lawrance
254  * Integrate new gauges into HUD config.
255  * 
256  * 27    12/01/97 12:27a Lawrance
257  * redo default alpha color for HUD, make it easy to modify in the future
258  * 
259  *
260  * $NoKeywords: $
261  *
262 */
263
264 #include "hud.h"
265 #include "hudconfig.h"
266 #include "freespace.h"
267 #include "gamesequence.h"
268 #include "player.h"
269 #include "2d.h"
270
271 #include "key.h"
272 #include "timer.h"
273 #include "math.h"
274 #include "mouse.h"
275 #include "ui.h"
276 #include "bmpman.h"
277 #include "palman.h"
278 #include "hudobserver.h"
279 #include "ui.h"
280 #include "missionshipchoice.h"
281 #include "gamesnd.h"
282 #include "alphacolors.h"
283 #include "popup.h"
284
285
286 //////////////////////////////////////////////////////////////////////////////
287 // Game-wide Globals
288 //////////////////////////////////////////////////////////////////////////////
289
290 #define MAX_HCF_FILES                   30
291 int HC_num_files = -1;                                          // num known hcf files
292 int HC_current_file = -1;                                       // current hcf file
293 char *HC_filenames[MAX_HCF_FILES];
294
295 char HC_fname[MAX_FILENAME_LEN+1] = "";
296 UI_INPUTBOX HC_fname_input;
297 int HC_fname_coords[GR_NUM_RESOLUTIONS][4] = {
298         { // GR_640
299                 44,     449,    218,    17
300         },
301         { // GR_1024
302                 101,    730,    319,    27
303         }
304 };
305
306 HUD_CONFIG_TYPE HUD_config;     // Player HUD configuration
307
308 // specify the max distance that the radar should detect objects
309 // See RR_ #defines in HUDconfig.h.
310 float Radar_ranges[RR_MAX_RANGES] = {
311         2000.0f,                        // short
312         10000.0f,               // med
313         10000000.0f,    // infinity
314 };
315
316 const char *Radar_range_text(int n)
317 {
318         #if RR_MAX_RANGES != 3
319         #error Number of ranges is wrong!
320         #endif
321
322         switch(n)       {
323         case 0:
324                 return XSTR( "2000 M", 246);
325         case 1:
326                 return XSTR( "10,000 M", 247);
327         case 2:
328                 return XSTR( "infinity", 248);
329         }
330         return NULL;
331 };
332
333 // default flags for observer HUD
334 int HUD_observer_default_flags = 
335 {
336         (1<<HUD_CENTER_RETICLE)                 |       
337         (1<<HUD_OFFSCREEN_INDICATOR)    |
338         (1<<HUD_MESSAGE_LINES)                  |
339         (1<<HUD_HOSTILE_TRIANGLE)               |
340         (1<<HUD_TARGET_TRIANGLE)                |
341         (1<<HUD_TARGET_MINI_ICON)               |
342         (1<<HUD_TARGET_MONITOR)                         
343 };
344
345 int HUD_observer_default_flags2 = {
346         (1<<(HUD_OFFSCREEN_RANGE - 32))
347 };
348
349 // default flags for regular HUD
350 int HUD_config_default_flags = 
351 {
352         (1<<HUD_LEAD_INDICATOR) |
353         (1<<HUD_ORIENTATION_TEE) |
354         (1<<HUD_HOSTILE_TRIANGLE) |
355         (1<<HUD_TARGET_TRIANGLE) |
356         (1<<HUD_MISSION_TIME) |
357         (1<<HUD_RETICLE_CIRCLE) |
358         (1<<HUD_THROTTLE_GAUGE) |
359         (1<<HUD_RADAR) |
360         (1<<HUD_TARGET_MONITOR) |
361         (1<<HUD_CENTER_RETICLE) |
362         (1<<HUD_TARGET_MONITOR_EXTRA_DATA) |
363         (1<<HUD_TARGET_SHIELD_ICON) |
364         (1<<HUD_PLAYER_SHIELD_ICON) |
365         (1<<HUD_ETS_GAUGE) |
366         (1<<HUD_AUTO_TARGET) |
367         (1<<HUD_AUTO_SPEED) |
368         (1<<HUD_WEAPONS_GAUGE) |
369         (1<<HUD_ESCORT_VIEW) |
370         (1<<HUD_DIRECTIVES_VIEW) |
371         (1<<HUD_THREAT_GAUGE) |
372         (1<<HUD_AFTERBURNER_ENERGY) |
373         (1<<HUD_WEAPONS_ENERGY) |
374         (1<<HUD_WEAPON_LINKING_GAUGE) |
375         (1<<HUD_TARGET_MINI_ICON) |
376         (1<<HUD_OFFSCREEN_INDICATOR) |
377         (1<<HUD_TALKING_HEAD) |
378         (1<<HUD_DAMAGE_GAUGE) |
379         (1<<HUD_MESSAGE_LINES) |
380         (1<<HUD_MISSILE_WARNING_ARROW) |
381         (1<<HUD_CMEASURE_GAUGE) |
382         (1<<HUD_OBJECTIVES_NOTIFY_GAUGE) |
383         (1<<HUD_WINGMEN_STATUS)
384 };
385
386 int HUD_config_default_flags2 = 
387 {
388         (1<<(HUD_OFFSCREEN_RANGE-32)) |
389         (1<<(HUD_KILLS_GAUGE-32)) |
390 #if defined(FS2_DEMO) || defined(MAKE_FS1)
391         (1<<(HUD_ATTACKING_TARGET_COUNT-32))
392 #else
393         (1<<(HUD_ATTACKING_TARGET_COUNT-32)) | 
394         (1<<(HUD_SUPPORT_GAUGE-32)) | 
395         (1<<(HUD_LAG_GAUGE-32))
396 #endif
397 };
398
399 // bits to tell whether a given gauge should be treated as pop-up or not
400 int HUD_default_popup_mask =
401 {
402         0       |                                                                                       // (1<<HUD_LEAD_INDICATOR) |
403         0       |                                                                                       // (1<<HUD_ORIENTATION_TEE) |
404         0       |                                                                                       //      (1<<HUD_HOSTILE_TRIANGLE) |
405         0       |                                                                                       // (1<<HUD_TARGET_TRIANGLE) |
406         0       |                                                                                       //      (1<<HUD_MISSION_TIME) |
407         0       |                                                                                       //      (1<<HUD_RETICLE_CIRCLE) |
408         0       |                                                                                       //      (1<<HUD_THROTTLE_GAUGE) |
409         0       |                                                                                       //      (1<<HUD_RADAR) |
410         0       |                                                                                       //      (1<<HUD_TARGET_MONITOR) |
411         0       |                                                                                       //      (1<<HUD_CENTER_RETICLE) |
412         0       |                                                                                       //      (1<<HUD_TARGET_MONITOR_EXTRA_DATA) |
413         0       |                                                                                       //      (1<<HUD_TARGET_SHIELD_ICON) |
414         0       |                                                                                       //      (1<<HUD_PLAYER_SHIELD_ICON) |
415         0       |                                                                                       //      (1<<HUD_ETS_GAUGE) |
416         0       |                                                                                       //      (1<<HUD_AUTO_TARGET) |
417         0       |                                                                                       //      (1<<HUD_AUTO_SPEED) |
418         0       |                                                                                       //      (1<<HUD_WEAPONS_GAUGE) |
419         0       |                                                                                       //      (1<<HUD_ESCORT_VIEW) |
420         0       |                                                                                       //      (1<<HUD_DIRECTIVES_VIEW) |
421         0       |                                                                                       //      (1<<HUD_THREAT_GAUGE) |
422         0       |                                                                                       //      (1<<HUD_AFTERBURNER_ENERGY) |
423         0       |                                                                                       //      (1<<HUD_WEAPONS_ENERGY) |
424         0       |                                                                                       //      (1<<HUD_WEAPON_LINKING_GAUGE) |
425         0       |                                                                                       //      (1<<HUD_TARGET_MINI_ICON) |
426         0       |                                                                                       //(1<<HUD_OFFSCREEN_INDICATOR)
427         0  |                                                                                    // talking head
428         0       |                                                                                       // damage gauge
429         0       |                                                                                       // message lines                                
430         0       |                                                                                       // missile warning arrow
431         0       |                                                                                       // countermeasures
432         0                                                                                               // wingman status
433 };
434
435 int HUD_default_popup_mask2 =
436 {
437         0  |                                                                                    // offscreen indicator range
438         0       |
439         0                                                                                       // kills gauge
440 };
441
442 void hud_config_color_save(const char *name);
443 void hud_config_select_all_toggle(int toggle);
444
445 int HC_select_all = 0;
446
447 //////////////////////////////////////////////////////////////////////////////
448 // Module Globals
449 //////////////////////////////////////////////////////////////////////////////
450
451 const char *Hud_config_fname[GR_NUM_RESOLUTIONS] = {
452         "HUDConfig",
453         "2_HUDConfig"
454 };
455
456 const char *Hud_config_mask_fname[GR_NUM_RESOLUTIONS] = {
457         "HUDConfig-m",
458         "2_HUDConfig-m"
459 };
460
461 struct HC_gauge_region
462 {
463         const char              *filename;
464         int                     x,y;
465         int                     hotspot;
466         int                     use_iff;
467         int                     can_popup;
468         int                     bitmap;
469         int                     nframes;
470         int                     color;
471         UI_BUTTON       button;
472
473         HC_gauge_region(const char *name, int x1, int y1, int h, int iff, int cp, int b, int nf, int cl) : filename(name), x(x1), y(y1), hotspot(h), use_iff(iff), can_popup(cp), bitmap(b), nframes(nf), color(cl){}
474 };
475
476 // hud config gauges
477 struct HC_gauge_region  HC_gauge_regions[GR_NUM_RESOLUTIONS][NUM_HUD_GAUGES] =
478 {
479         { // GR_640
480         //XSTR:OFF
481 #ifdef MAKE_FS1
482                 HC_gauge_region("HG_07",        377,    106,    7,      1,  0,  -1, 4,  2),      // lead indicator
483                 HC_gauge_region("HG_08",        288,    153,    8,      1,  0,  -1, 4,  2),      // orientation tee
484                 HC_gauge_region("HG_09",        312,    141,    9,      1,  0,  -1, 4,  1),      // hostile triangle
485                 HC_gauge_region("HG_11",        362,    141,    11,     1,  0,  -1, 4,  2),      // target triangle
486                 HC_gauge_region("HG_41",        530,    364,    41,     0,  0,  -1, 0,  0),      // mission time
487                 HC_gauge_region("none",         -1,             -1,             0,      0,  0,  -1, 0,  0),      // reticle circle?
488                 HC_gauge_region("HG_14",        272,    218,    14,     0,  0,  -1, 0,  0),      // throttle gauge
489                 HC_gauge_region("HG_20",        301,    307,    20,     0,  0,  -1, 0,  0),      // radar
490                 HC_gauge_region("HG_04",        126,    271,    4,      0,  0,  -1, 0,  0),      // target monitor
491                 HC_gauge_region("HG_12",        335,    212,    12,     0,  0,  -1, 0,  0),      // center of reticle
492                 HC_gauge_region("HG_03",        126,    246,    3,      0,  0,  -1, 0,  0),      // extra target data
493                 HC_gauge_region("HG_19",        224,    322,    19,     0,  0,  -1, 0,  0),      // target shield icon
494                 HC_gauge_region("HG_21",        403,    322,    21,     0,  0,  -1, 0,  0),      // player shield icon
495                 HC_gauge_region("HG_24",        485,    315,    24,     0,  1,  -1, 0,  0),      // ets gauge
496                 HC_gauge_region("HG_25",        523,    315,    25,     0,  1,  -1, 0,  0),      // auto target
497                 HC_gauge_region("HG_26",        523,    332,    26,     0,  1,  -1, 0,  0),      // auto speed
498                 HC_gauge_region("HG_23",        467,    241,    23,     0,  1,  -1, 0,  0),      // weapons gauge
499                 HC_gauge_region("HG_22",        460,    196,    22,     0,  1,  -1, 0,  0),      // escort view
500                 HC_gauge_region("HG_02",        126,    175,    2,      0,  0,  -1, 0,  0),      // directives view
501                 HC_gauge_region("HG_10",        331,    149,    10,     0,  0,  -1, 0,  0),      // threat gauge
502                 HC_gauge_region("HG_13",        241,    235,    13,     0,  0,  -1, 0,  0),      // afterburner energy
503                 HC_gauge_region("HG_17",        412,    235,    17,     0,  0,  -1, 0,  0),      // weapons energy
504                 HC_gauge_region("HG_16",        396,    226,    16,     0,  0,  -1, 0,  0),      // weapon linking
505                 HC_gauge_region("HG_15",        333,    253,    15,     0,  1,  -1, 0,  0),      // target mini icon (shield)
506                 HC_gauge_region("HG_05",        405,    52,             5,      1,  0,  -1, 4,  2),      // offscreen indicator
507                 HC_gauge_region("HG_01",        126,    76,             1,      0,  0,  -1, 0,  0),      // talking head
508                 HC_gauge_region("HG_06",        292,    78,             6,      0,  1,  -1, 0,  0),      // damage gauge
509                 HC_gauge_region("HG_00",        126,    63,             0,      0,  0,  -1, 0,  0),      // message lines
510                 HC_gauge_region("HG_18",        313,    283,    18,     1,  0,  -1, 4,  3),      // locked missile direction
511                 HC_gauge_region("HG_40",        467,    291,    40,     0,  1,  -1, 0,  0),      // cmeasure gauge
512                 HC_gauge_region("none",         -1,             -1,             -1,     0,  0,  -1, 0,  0),      // objectives notify gauge
513                 HC_gauge_region("HG_39",        504,    153,    39,     0,  0,  -1, 0,  0),      // wingman status gauge
514                 HC_gauge_region("HG_38",        405,    59,             38,     1,  0,  -1, 4,  2),      // offscreen indicator range
515                 HC_gauge_region("HG_42",        467,    303,    42,     0,  1,  -1, 0,  0),      // kills gauge
516                 HC_gauge_region("HG_45",        317,    106,    45,     1,  0,  -1, 4,  1),      // attacking target count
517                 HC_gauge_region("none",         -1,             -1,             -1,     0,  0,  -1, 0,  0),      // text flash gauge
518                 HC_gauge_region("none",         -1,             -1,             -1,     0,  0,  -1, 0,  0),      // comm menu
519                 HC_gauge_region("none",         -1,             -1,             -1,     0,  0,  -1, 0,  0),      // support view gauge
520                 HC_gauge_region("none",         -1,             -1,             -1,     0,  0,  -1, 0,  0),      // netlag icon gauge
521 #else
522                 HC_gauge_region("HCB_35",       407,    69,     35,     1,      0,      -1, 0,  2),                     // lead indicator
523                 HC_gauge_region("HCB_36",       305,    119,    36,     1,      0,      -1, 0,  2),                     // orientation tee
524                 HC_gauge_region("none",         1,              1,              -1,     1,      0,      -1, 0,  0),                     // hostile triangle
525                 HC_gauge_region("HCB_37",       391,    107,    37,     1,      0,      -1, 0,  2),                     // target triangle
526                 HC_gauge_region("HCB_63",       575,    352,    63,     0,      0,      -1, 0,  0),                     // mission time
527                 HC_gauge_region("none",         1,              1,              1,              0,      0,      -1, 0,  0),                     // reticle circle?
528                 HC_gauge_region("HCB_40",       285,    146,    40,     0,      0,      -1, 0,  0),                     // throttle gauge
529                 HC_gauge_region("HCB_50",       317,    291,    50,     0,      0,      -1, 0,  0),                     // radar
530                 HC_gauge_region("HCB_31",       123,    249,    31,     0,      0,      -1, 0,  0),                     // target monitor
531                 HC_gauge_region("HCB_41",       361,    188,    41,     0,      0,      -1, 0,  0),                     // center of reticle
532                 HC_gauge_region("HCB_30",       123,    221,    30,     0,      0,      -1, 0,  0),                     // extra target data
533                 HC_gauge_region("HCB_49",       237,    303,    49,     0,      0,      -1, 0,  0),                     // target shield icon
534                 HC_gauge_region("HCB_51",       435,    304,    51,     0,      0,      -1, 0,  0),                     // player shield icon
535                 HC_gauge_region("HCB_58",       524,    299,    58,     0,      1, -1, 0,       0),                     // ets gauge
536                 HC_gauge_region("HCB_61",       566,    299,    61,     0,      1, -1, 0,       0),                     // auto target
537                 HC_gauge_region("HCB_62",       566,    317,    62,     0,      1, -1, 0,       0),                     // auto speed
538                 HC_gauge_region("HCB_55",       504,    216,    55,     0,      1, -1, 0,       0),                     // weapons gauge
539                 HC_gauge_region("HCB_54",       496,    166,    54,     0,      1, -1, 0,       0),                     // escort view
540                 HC_gauge_region("HCB_29",       123,    142,    29,     0,      0, -1, 0,       0),                     // directives view
541                 HC_gauge_region("HCB_43",       398,    147,    43,     0,      0, -1, 0,       0),                     // threat gauge
542                 HC_gauge_region("HCB_39",       250,    212,    39,     0,      0, -1, 0,       0),                     // afterburner energy
543                 HC_gauge_region("HCB_44",       449,    212,    44,     0,      0, -1, 0,       0),                     // weapons energy
544                 HC_gauge_region("none",         1,              1,              -1,     0,      0, -1, 0,       0),                     // weapon linking
545                 HC_gauge_region("HCB_42",       356,    232,    42,     0,      1, -1, 0,       0),                     // target mini icon (shield)
546                 HC_gauge_region("HCB_34",       438,    5,              34,     1,      0, -1, 0,       2),                     // offscreen indicator
547                 HC_gauge_region("HCB_28",       123,    31,     28,     0,      0, -1, 0,       0),                     // talking head
548                 HC_gauge_region("HCB_32",       309,    33,     32,     0,      1, -1, 0,       0),                     // damage gauge
549                 HC_gauge_region("HCB_27",       124,    19,     27,     0,      0, -1, 0,       0),                     // message lines
550                 HC_gauge_region("HCB_45",       307,    249,    45,     1,      0, -1, 0,       1),                     // missile warnings
551                 HC_gauge_region("HCB_56",       505,    271,    56,     0,      1,      -1, 0,  0),                     // cmeasure gauge
552                 HC_gauge_region("HCB_33",       309,    87,     33,     0,      0,      -1, 0,  0),                     // objectives notify gauge
553                 HC_gauge_region("HCB_53",       546,    117,    53,     0,      0,      -1, 0,  0),                     // wingman status gauge
554                 HC_gauge_region("none",         1,              1,              -1,     0,      0,      -1, 0,  0),                     // offscreen indicator range
555                 HC_gauge_region("HCB_57",       505,    285,    57,     0,      1,      -1, 0,  0),                     // kills gauge
556                 HC_gauge_region("none",         1,              1,              -1,     0,      0,      -1, 0,  0),                     // attacking target count
557                 HC_gauge_region("HCB_38",       342,    138,    38,     0,      0,      -1, 0,  0),                     // text flash gauge
558                 HC_gauge_region("HCB_52",       465,    8,              52,     0,      0,      -1, 0,  0),                     // comm menu
559 #ifndef FS2_DEMO
560                 HC_gauge_region("HCB_46",       324,    264,    46,     0,      0,      -1, 0,  0),                     // support view gauge
561                 HC_gauge_region("HCB_47",       418,    262,    47,     0,      0,      -1, 0,  0),                     // netlag icon gauge
562 #endif
563 #endif
564         //XSTR:ON
565         },
566         { // GR_1024
567         //XSTR:OFF
568                 HC_gauge_region("2_HCB_35",     652,    112,    35,     1,      0,      -1, 0,  2),                     // lead indicator
569                 HC_gauge_region("2_HCB_36",     489,    191,    36,     1,      0,      -1, 0,  2),                     // orientation tee
570                 HC_gauge_region("none",                 1,              1,              -1,     1,      0,      -1, 0,  0),                     // hostile triangle
571                 HC_gauge_region("2_HCB_37",     626,    173,    37,     1,      0,      -1, 0,  2),                     // target triangle
572                 HC_gauge_region("2_HCB_63",     920,    564,    63,     0,      0,      -1, 0,  0),                     // mission time
573                 HC_gauge_region("none",                 1,              1,              1,              0,      0,      -1, 0,  0),                     // reticle circle?
574                 HC_gauge_region("2_HCB_40",     456,    235,    40,     0,      0,      -1, 0,  0),                     // throttle gauge
575                 HC_gauge_region("2_HCB_50",     508,    466,    50,     0,      0,      -1, 0,  0),                     // radar
576                 HC_gauge_region("2_HCB_31",     198,    399,    31,     0,      0,      -1, 0,  0),                     // target monitor
577                 HC_gauge_region("2_HCB_41",     578,    302,    41,     0,      0,      -1, 0,  0),                     // center of reticle
578                 HC_gauge_region("2_HCB_30",     198,    354,    30,     0,      0,      -1, 0,  0),                     // extra target data
579                 HC_gauge_region("2_HCB_49",     380,    485,    49,     0,      0,      -1, 0,  0),                     // target shield icon
580                 HC_gauge_region("2_HCB_51",     696,    486,    51,     0,      0,      -1, 0,  0),                     // player shield icon
581                 HC_gauge_region("2_HCB_58",     839,    479,    58,     0,      1, -1, 0,       0),                     // ets gauge
582                 HC_gauge_region("2_HCB_61",     906,    479,    61,     0,      1, -1, 0,       0),                     // auto target
583                 HC_gauge_region("2_HCB_62",     906,    508,    62,     0,      1, -1, 0,       0),                     // auto speed
584                 HC_gauge_region("2_HCB_55",     807,    346,    55,     0,      1, -1, 0,       0),                     // weapons gauge
585                 HC_gauge_region("2_HCB_54",     794,    265,    54,     0,      1, -1, 0,       0),                     // escort view
586                 HC_gauge_region("2_HCB_29",     198,    228,    29,     0,      0, -1, 0,       0),                     // directives view
587                 HC_gauge_region("2_HCB_43",     637,    237,    43,     0,      0, -1, 0,       0),                     // threat gauge
588                 HC_gauge_region("2_HCB_39",     403,    339,    39,     0,      0, -1, 0,       0),                     // afterburner energy
589                 HC_gauge_region("2_HCB_44",     719,    339,    44,     0,      0, -1, 0,       0),                     // weapons energy
590                 HC_gauge_region("none",                 1,              1,              -1,     0,      0, -1, 0,       0),                     // weapon linking
591                 HC_gauge_region("2_HCB_42",     569,    371,    42,     0,      1, -1, 0,       0),                     // target mini icon (shield)
592                 HC_gauge_region("2_HCB_34",     701,    9,              34,     1,      0, -1, 0,       2),                     // offscreen indicator
593                 HC_gauge_region("2_HCB_28",     198,    50,     28,     0,      0, -1, 0,       0),                     // talking head
594                 HC_gauge_region("2_HCB_32",     495,    55,     32,     0,      1, -1, 0,       0),                     // damage gauge
595                 HC_gauge_region("2_HCB_27",     199,    30,     27,     0,      0, -1, 0,       0),                     // message lines
596                 HC_gauge_region("2_HCB_45",     491,    399,    45,     1,      0, -1, 0,       1),                     // missile warnings
597                 HC_gauge_region("2_HCB_56",     808,    433,    56,     0,      1,      -1, 0,  0),                     // cmeasure gauge
598                 HC_gauge_region("2_HCB_33",     495,    141,    33,     0,      0,      -1, 0,  0),                     // objectives notify gauge
599                 HC_gauge_region("2_HCB_53",     873,    188,    53,     0,      0,      -1, 0,  0),                     // wingman status gauge
600                 HC_gauge_region("none",                 1,              1,              -1,     0,      0,      -1, 0,  0),                     // offscreen indicator range
601                 HC_gauge_region("2_HCB_57",     808,    456,    57,     0,      1,      -1, 0,  0),                     // kills gauge
602                 HC_gauge_region("none",                 1,              1,              -1,     0,      0,      -1, 0,  0),                     // attacking target count
603                 HC_gauge_region("2_HCB_38",     548,    222,    38,     0,      0,      -1, 0,  0),                     // text flash gauge
604                 HC_gauge_region("2_HCB_52",     744,    14,     52,     0,      0,      -1, 0,  0),                     // comm menu
605 #ifndef FS2_DEMO
606                 HC_gauge_region("2_HCB_46",     520,    422,    46,     0,      0,      -1, 0,  0),                     // support view gauge
607                 HC_gauge_region("2_HCB_47",     670,    419,    47,     0,      0,      -1, 0,  0),                     // netlag icon gauge
608 #endif
609         //XSTR:ON
610         }
611 };
612
613 int HC_gauge_description_coords[GR_NUM_RESOLUTIONS][3] = {
614         {       // GR_640
615 #ifdef MAKE_FS1
616                 186, 410, 185
617 #else
618                 35, 397, 197
619 #endif
620         },
621         {       // GR_1024
622                 56, 632, 307
623         }
624 };
625
626 const char *HC_gauge_descriptions(int n)
627 {
628         switch(n)       {
629         case 0:
630                 return XSTR( "lead indicator", 249);
631         case 1:
632                 return XSTR( "target orientation", 250);
633         case 2:
634                 return XSTR( "closest attacking hostile", 251);
635         case 3:
636                 return XSTR( "current target direction", 252);
637         case 4:
638                 return XSTR( "mission time", 253);
639         case 5:
640                 return XSTR( "reticle", 254);
641         case 6:
642                 return XSTR( "throttle", 255);
643         case 7:
644                 return XSTR( "radar", 256);
645         case 8:
646                 return XSTR( "target monitor", 257);
647         case 9:
648                 return XSTR( "center of reticle", 258);
649         case 10:
650                 return XSTR( "extra target info", 259);
651         case 11:
652                 return XSTR( "target shield", 260);
653         case 12:
654                 return XSTR( "player shield", 261);
655         case 13:
656                 return XSTR( "power management", 262);
657         case 14:
658                 return XSTR( "auto-target icon", 263);
659         case 15:
660                 return XSTR( "auto-speed-match icon", 264);
661         case 16:
662                 return XSTR( "weapons display", 265);
663         case 17:
664                 return XSTR( "monitoring view", 266);
665         case 18:
666                 return XSTR( "directives view", 267);
667         case 19:
668                 return XSTR( "threat gauge", 268);
669         case 20:
670                 return XSTR( "afterburner energy", 269);
671         case 21:
672                 return XSTR( "weapons energy", 270);
673         case 22:
674                 return XSTR( "weapon linking", 271);
675         case 23:
676                 return XSTR( "target hull/shield icon", 272);
677         case 24:
678                 return XSTR( "offscreen indicator", 273);
679         case 25:
680                 return XSTR( "comm video", 274);
681         case 26:
682                 return XSTR( "damage display", 275);
683         case 27:
684                 return XSTR( "message output", 276);
685         case 28:
686                 return XSTR( "locked missile direction", 277);
687         case 29:
688                 return XSTR( "countermeasures", 278);
689         case 30:
690                 return XSTR( "objective notify", 279);
691         case 31:
692                 return XSTR( "wingmen status", 280);
693         case 32:
694                 return XSTR( "offscreen range", 281);
695         case 33:
696                 return XSTR( "kills gauge", 282);
697         case 34:
698                 return XSTR( "attacking target count", 283);
699         case 35: 
700                 return XSTR("warning flash", 1459);
701         case 36:
702                 return XSTR("comm menu", 1460);
703         case 37: 
704                 return XSTR("support gauge", 1461);
705         case 38:
706                 return XSTR("lag gauge", 1462);
707         }
708         return NULL;
709 }
710
711 #ifdef MAKE_FS1
712         #define NUM_HUD_BUTTONS                 8
713 #else
714         #define NUM_HUD_BUTTONS                 20
715 #endif
716
717 #ifndef MAKE_FS1
718 #define HCB_RED_UP                              0
719 #define HCB_GREEN_UP                            1
720 #define HCB_BLUE_UP                             2
721 #define HCB_I_UP                                        3
722 #define HCB_RED_DOWN                            4
723 #define HCB_GREEN_DOWN                  5
724 #define HCB_BLUE_DOWN                   6
725 #define HCB_I_DOWN                              7
726 #define HCB_ON                                          8
727 #define HCB_OFF                                 9
728 #define HCB_POPUP                                       10
729 #define HCB_SAVE_HCF                            11
730 #define HCB_PREV_HCF                            12
731 #define HCB_NEXT_HCF                            13
732 #define HCB_AMBER                                       14
733 #define HCB_BLUE                                        15
734 #define HCB_GREEN                                       16
735 #define HCB_SELECT_ALL                  17
736 #define HCB_RESET                                       18
737 #define HCB_ACCEPT                              19
738 #else
739 #define HCB_AMBER                               0
740 #define HCB_BLUE                                1
741 #define HCB_GREEN                               2
742 #define HCB_ON                                  3
743 #define HCB_OFF                                 4
744 #define HCB_POPUP                               5
745 #define HCB_RESET                               6
746 #define HCB_ACCEPT                              7
747 #endif
748
749
750 ui_button_info HC_buttons[GR_NUM_RESOLUTIONS][NUM_HUD_BUTTONS] = {
751         { // GR_640
752 #ifdef MAKE_FS1
753                 ui_button_info("HG_27",                 31,             92,             -1,     -1,     27),    // amber
754                 ui_button_info("HG_28",                 31,             113,    -1,     -1,     28),    // blue
755                 ui_button_info("HG_29",                 31,             133,    -1,     -1,     29),    // green
756                 ui_button_info("HG_30",                 31,             385,    -1,     -1,     30),    // on
757                 ui_button_info("HG_31",                 31,             405,    -1,     -1,     31),    // off
758                 ui_button_info("HG_32",                 31,             424,    -1,     -1,     32),    // popup
759                 ui_button_info("HG_36",                 504,    411,    -1,     -1,     36),    // reset
760                 ui_button_info("HG_37",                 561,    411,    -1,     -1,     37),    // accept
761 #else
762                 ui_button_info("HCB_00",                6,              27,     -1,     -1,     0),
763                 ui_button_info("HCB_01",                30,     27,     -1,     -1,     1),
764                 ui_button_info("HCB_02",                55,     27,     -1,     -1,     2),
765                 ui_button_info("HCB_03",                80,     27,     -1,     -1,     3),
766                 ui_button_info("HCB_08",                6,              291,    -1,     -1,     8),
767                 ui_button_info("HCB_09",                30,     291,    -1,     -1,     9),
768                 ui_button_info("HCB_10",                55,     291,    -1,     -1,     10),
769                 ui_button_info("HCB_11",                80,     291,    -1,     -1,     11),
770                 ui_button_info("HCB_12",                4,              329,    -1,     -1,     12),
771                 ui_button_info("HCB_13",                4,              348,    -1,     -1,     13),
772                 ui_button_info("HCB_14",                4,              367,    -1,     -1,     14),
773                 ui_button_info("HCB_15",                2,              439,    -1,     -1,     15),
774                 ui_button_info("HCB_16",                266,    456,    -1,     -1,     16),
775                 ui_button_info("HCB_17",                292,    456,    -1,     -1,     17),
776                 ui_button_info("HCB_18",                327,    421,    -1,     -1,     18),
777                 ui_button_info("HCB_19",                327,    440,    -1,     -1,     19),
778                 ui_button_info("HCB_20",                327,    459,    -1,     -1,     20),
779                 ui_button_info("HCB_24",                472,    436,    -1,     -1,     24),
780                 ui_button_info("HCB_25",                523,    433,    -1,     -1,     25),
781                 ui_button_info("HCB_26",                576,    434,    -1,     -1,     26),
782 #endif
783         },
784         { // GR_1024
785                 ui_button_info("2_HCB_00",              9,              44,     -1,     -1,     0),
786                 ui_button_info("2_HCB_01",              48,     44,     -1,     -1,     1),
787                 ui_button_info("2_HCB_02",              88,     44,     -1,     -1,     2),
788                 ui_button_info("2_HCB_03",              127,    44,     -1,     -1,     3),
789                 ui_button_info("2_HCB_08",              9,              466,    -1,     -1,     8),
790                 ui_button_info("2_HCB_09",              48,     466,    -1,     -1,     9),
791                 ui_button_info("2_HCB_10",              88,     466,    -1,     -1,     10),
792                 ui_button_info("2_HCB_11",              127,    466,    -1,     -1,     11),
793 #ifndef MAKE_FS1
794                 ui_button_info("2_HCB_12",              6,              526,    -1,     -1,     12),
795                 ui_button_info("2_HCB_13",              6,              556,    -1,     -1,     13),
796                 ui_button_info("2_HCB_14",              6,              586,    -1,     -1,     14),
797                 ui_button_info("2_HCB_15",              3,              703,    -1,     -1,     15),
798                 ui_button_info("2_HCB_16",              426,    730,    -1,     -1,     16),
799                 ui_button_info("2_HCB_17",              467,    730,    -1,     -1,     17),
800                 ui_button_info("2_HCB_18",              524,    674,    -1,     -1,     18),
801                 ui_button_info("2_HCB_19",              524,    704,    -1,     -1,     19),
802                 ui_button_info("2_HCB_20",              524,    734,    -1,     -1,     20),
803                 ui_button_info("2_HCB_24",              755,    698,    -1,     -1,     24),
804                 ui_button_info("2_HCB_25",              837,    693,    -1,     -1,     25),
805                 ui_button_info("2_HCB_26",              922,    695,    -1,     -1,     26),
806 #endif
807         },
808 };
809
810 // text
811 #ifndef MAKE_FS1
812 #define NUM_HUD_TEXT                                    15
813
814 UI_XSTR HC_text[GR_NUM_RESOLUTIONS][NUM_HUD_TEXT] = {
815         { // GR_640
816                 { "R",                          1512,   14,     8,              UI_XSTR_COLOR_GREEN,    -1, NULL },
817                 { "G",                          1513,   37,     8,              UI_XSTR_COLOR_GREEN,    -1, NULL },
818                 { "B",                          1514,   62,     8,              UI_XSTR_COLOR_GREEN,    -1, NULL },
819                 { "I",                          1515,   90,     8,              UI_XSTR_COLOR_GREEN,    -1, NULL },
820                 { "On",                         1285,   36,     334,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_ON].button },
821                 { "Off",                                1286,   36,     353,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_OFF].button },
822                 { "Popup",                      1453,   36,     372,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_POPUP].button },
823                 { "Save",                       1454,   51,     428,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_SAVE_HCF].button },
824                 { "Amber",                      1455,   364,    426,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_AMBER].button },
825                 { "Blue",                       1456,   364,    445,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_BLUE].button },
826                 { "Green",                      1457,   364,    464,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_GREEN].button },         
827                 { "Select",                     1550,   442,    413,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_SELECT_ALL].button },
828                 { "All",                                1551,   442,    424,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_SELECT_ALL].button },
829                 { "Reset",                      1337,   515,    413,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[0][HCB_RESET].button },
830                 { "Accept",                     1035,   573,    413,    UI_XSTR_COLOR_PINK,     -1, &HC_buttons[0][HCB_ACCEPT].button },
831         },
832         { // GR_1024
833                 { "R",                          1512,   23,     14,     UI_XSTR_COLOR_GREEN,    -1, NULL },
834                 { "G",                          1513,   60,     14,     UI_XSTR_COLOR_GREEN,    -1, NULL },
835                 { "B",                          1514,   100,    14,     UI_XSTR_COLOR_GREEN,    -1, NULL },
836                 { "I",                          1515,   144,    14,     UI_XSTR_COLOR_GREEN,    -1, NULL },
837                 { "On",                         1285,   58,     536,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_ON].button },
838                 { "Off",                                1286,   58,     566,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_OFF].button },
839                 { "Popup",                      1453,   58,     596,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_POPUP].button },
840                 { "Save",                       1454,   82,     688,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_SAVE_HCF].button },
841                 { "Amber",                      1455,   582,    685,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_AMBER].button },
842                 { "Blue",                       1456,   582,    715,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_BLUE].button },
843                 { "Green",                      1457,   582,    745,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_GREEN].button },         
844                 { "Select",                     1550,   760,    671,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_SELECT_ALL].button },
845                 { "All",                                1551,   760,    682,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_SELECT_ALL].button },
846                 { "Reset",                      1337,   850,    669,    UI_XSTR_COLOR_GREEN,    -1, &HC_buttons[1][HCB_RESET].button },
847                 { "Accept",                     1035,   930,    670,    UI_XSTR_COLOR_PINK,     -1, &HC_buttons[1][HCB_ACCEPT].button },
848         }
849 };
850 #endif
851
852 void hud_config_set_rgb(int gauge, int r, int g, int b);
853 void hud_config_set_alpha(int gauge, int a);
854
855 #ifdef MAKE_FS1
856 #define NUM_HC_SPECIAL_BITMAPS  2
857 #define HC_SPECIAL_RETICLE                      0
858 #define HC_SPECIAL_TEXT                         1
859 typedef struct HC_special_bitmap
860 {
861         const char *filename;
862         int x,y;
863         int bitmap;
864 } HC_special_bitmap;
865
866 HC_special_bitmap HC_special_bitmaps[NUM_HC_SPECIAL_BITMAPS] =
867 {
868 //XSTR:OFF
869         {"HG_00a", 272, 146, -1},
870         {"HG_04a", 132, 271, -1},
871 //XSTR:ON
872 };
873 #endif // MAKE_FS1
874
875 static int                                                      HC_background_bitmap;
876 static UI_WINDOW                                        HC_ui_window;
877
878 static int                                                      HC_gauge_hot;                   // mouse is over this gauge
879 static int                                                      HC_gauge_selected;      // gauge is selected
880
881 // slider controls
882 #ifdef MAKE_FS1
883 #define HC_NUM_SLIDERS                                                  1
884 #define HC_BRIGHTNESS_SLIDER                                    0
885 struct hc_sliders {
886         // base slider
887         const char *filename;
888         int x, y, xt, yt;
889         int hotspot;
890         int dot_w;
891         int dots;
892
893         // left and right buttons
894         const char *left_filename;
895         int left_mask, left_x, left_y;
896         const char *right_filename;
897         int right_mask, right_x, right_y;
898
899         // slider control
900         UI_DOT_SLIDER_NEW slider;  // because we have a class inside this struct, we need the constructor below..
901
902         hc_sliders(const char *name, int x1, int y1, int xt1, int yt1, int h, int _dot_w, int _dots, const char *_left_filename, int _left_mask, int _left_x, int _left_y, const char *_right_filename, int _right_mask, int _right_x, int _right_y) : 
903                                  filename(name), x(x1), y(y1), xt(xt1), yt(yt1), hotspot(h), dot_w(_dot_w), dots(_dots), left_filename(_left_filename), left_mask(_left_mask), left_x(_left_x), left_y(_left_y), right_filename(_right_filename), right_mask(_right_mask), right_x(_right_x), right_y(_right_y) {}
904 };
905
906 hc_sliders HC_sliders[GR_NUM_RESOLUTIONS][HC_NUM_SLIDERS] = {
907         { // GR_640
908                 /*
909                 hc_sliders( "HCB_22",   419,    379,    -1,     -1,     22,     20,     10,
910                                                 "HCB_23",       23,     611,    379,
911                                                 "HCB_21",       21,     391,    379)
912                 */
913                 // ten dots but 11 frames, use frame count
914                 hc_sliders(     "HG_34",        373,    21,             -1,     -1,     34,     20,     11,                                                     
915                                                 "HG_35",        35,     565,    20,
916                                                 "HG_33",        33,     349,    20)
917         },
918         { // GR_1024
919                 hc_sliders(     "2_HCB_22",     670,    606,    -1,     -1,     22,     32,     10,                                                     
920                                                 "2_HCB_23",     23,     698,    606,
921                                                 "2_HCB_21",     21,     625,    606),
922         }       
923 };
924 #endif  // MAKE_FS1
925
926
927 // HUD colors
928 typedef struct hc_col {
929         ubyte   r, g, b;
930 } hc_col;
931
932 hc_col HC_colors[3] =
933 {
934         {0, 255, 0},            // Green - get RGB from Adam so it matches palette?-??.pcx
935         {67, 123, 203}, // Blue - get RGB from Adam so it matches palette?-??.pcx
936         {255, 197, 0},          // Amber - get RGB from Adam so it matches palette?-??.pcx
937 };
938
939 static HUD_CONFIG_TYPE  HUD_config_backup;              // backup HUD config, used to restore old config if changes not applied
940 static int                                      HUD_config_inited = 0;
941
942 // rgba slider stuff
943 void hud_config_red_slider();
944 void hud_config_green_slider();
945 void hud_config_blue_slider();
946 void hud_config_alpha_slider_up();
947 void hud_config_alpha_slider_down();
948 void hud_config_recalc_alpha_slider();
949 void hud_config_process_colors();
950 void hud_config_color_init();
951 void hud_config_color_close();
952 #define NUM_HC_SLIDERS                  4
953 #define HCS_RED                                 0
954 #define HCS_GREEN                                       1
955 #define HCS_BLUE                                        2
956 #define HCS_ALPHA                                       3
957 UI_SLIDER2 HC_color_sliders[NUM_HC_SLIDERS];
958 int HC_slider_coords[GR_NUM_RESOLUTIONS][NUM_HC_SLIDERS][4] = {
959         { // GR_640
960                 { 8,    53,     15, 225 },
961                 { 33, 53,       15, 225 },
962                 { 58, 53,       15, 225 },
963                 { 83, 53,       15, 225 },
964         },
965         { // GR_1024
966                 { 13,   85, 32, 350 },
967                 { 53, 85, 32, 350 },
968                 { 93, 85, 32, 350 },
969                 { 133, 85, 32, 350 },
970         },      
971 };
972 #define HCS_CONV(__v)                   ( 255 - (__v) )
973
974 const char *HC_slider_fname[GR_NUM_RESOLUTIONS] = {
975         "slider",
976         "2_slider"
977 };
978
979 // sync sliders
980 void hud_config_synch_sliders(int i)
981 {
982 #ifndef MAKE_FS1
983         if(i >= 0){
984                 HC_color_sliders[HCS_RED].force_currentItem( HCS_CONV(HUD_config.clr[i].red) );
985                 HC_color_sliders[HCS_GREEN].force_currentItem( HCS_CONV(HUD_config.clr[i].green) );
986                 HC_color_sliders[HCS_BLUE].force_currentItem( HCS_CONV(HUD_config.clr[i].blue) );
987                 HC_color_sliders[HCS_ALPHA].force_currentItem( HCS_CONV(HUD_config.clr[i].alpha) );
988         }
989 #endif
990 }
991
992 // reset some ui components based on HUD config data
993 void hud_config_synch_ui()
994 {
995 #ifdef MAKE_FS1
996         game_load_palette();
997 #endif
998         HUD_init_hud_color_array();
999 #ifdef MAKE_FS1
1000         HC_sliders[gr_screen.res][HC_BRIGHTNESS_SLIDER].slider.pos = HUD_color_alpha -3;                // convert to value from 0-10   
1001 #else
1002
1003         // sync sliders to currently selected gauge
1004         hud_config_synch_sliders(HC_gauge_selected);
1005 #endif
1006 }
1007
1008 // Init the UI components
1009 void hud_config_init_ui()
1010 {
1011         int i;
1012         struct HC_gauge_region  *hg;
1013         struct ui_button_info                   *hb;
1014
1015 #ifdef MAKE_FS1
1016         common_set_interface_palette("HUDConfigPalette");  // set the interface palette
1017 #endif
1018         hud_config_synch_ui();
1019         HC_background_bitmap = bm_load(Hud_config_fname[gr_screen.res]);
1020
1021         HC_ui_window.create( 0, 0, gr_screen.max_w, gr_screen.max_h, 0 );
1022         HC_ui_window.set_mask_bmap(Hud_config_mask_fname[gr_screen.res]);
1023
1024         for (i=0; i<NUM_HUD_GAUGES; i++) {
1025                 hg = &HC_gauge_regions[gr_screen.res][i];
1026                 if ( !SDL_strcasecmp(hg->filename, NOX("none")) ) {
1027                         continue;
1028                 }
1029                 hg->button.create(&HC_ui_window, "", hg->x, hg->y, 60, 30, 0, 1);
1030                 // set up callback for when a mouse first goes over a button
1031 //              hg->button.set_highlight_action(common_play_highlight_sound);
1032                 hg->button.hide();
1033                 hg->button.link_hotspot(hg->hotspot);
1034
1035 #ifdef MAKE_FS1
1036                 if ( hg->use_iff ) {
1037                         hg->bitmap = bm_load_animation(hg->filename, &hg->nframes);
1038                 } else {
1039                         hg->bitmap = bm_load(hg->filename);
1040                         hg->nframes = 1;
1041                 }
1042 #else
1043                         hg->bitmap = bm_load(hg->filename);
1044                         hg->nframes = 1;
1045 #endif
1046         }
1047
1048 #ifndef MAKE_FS1
1049         // add text
1050         for(i=0; i<NUM_HUD_TEXT; i++){
1051                 HC_ui_window.add_XSTR(&HC_text[gr_screen.res][i]);
1052         }
1053
1054         // initialize sliders
1055         HC_color_sliders[HCS_RED].create(&HC_ui_window, HC_slider_coords[gr_screen.res][HCS_RED][0], HC_slider_coords[gr_screen.res][HCS_RED][1], HC_slider_coords[gr_screen.res][HCS_RED][2], HC_slider_coords[gr_screen.res][HCS_RED][3],
1056                                                                                 255, HC_slider_fname[gr_screen.res], hud_config_red_slider, hud_config_red_slider, hud_config_red_slider);
1057
1058         HC_color_sliders[HCS_GREEN].create(&HC_ui_window, HC_slider_coords[gr_screen.res][HCS_GREEN][0], HC_slider_coords[gr_screen.res][HCS_GREEN][1], HC_slider_coords[gr_screen.res][HCS_GREEN][2], HC_slider_coords[gr_screen.res][HCS_GREEN][3],
1059                                                                                 255, HC_slider_fname[gr_screen.res], hud_config_green_slider, hud_config_green_slider, hud_config_green_slider);
1060
1061         HC_color_sliders[HCS_BLUE].create(&HC_ui_window, HC_slider_coords[gr_screen.res][HCS_BLUE][0], HC_slider_coords[gr_screen.res][HCS_BLUE][1], HC_slider_coords[gr_screen.res][HCS_BLUE][2], HC_slider_coords[gr_screen.res][HCS_BLUE][3],
1062                                                                                 255, HC_slider_fname[gr_screen.res], hud_config_blue_slider, hud_config_blue_slider, hud_config_blue_slider);
1063
1064         HC_color_sliders[HCS_ALPHA].create(&HC_ui_window, HC_slider_coords[gr_screen.res][HCS_ALPHA][0], HC_slider_coords[gr_screen.res][HCS_ALPHA][1], HC_slider_coords[gr_screen.res][HCS_ALPHA][2], HC_slider_coords[gr_screen.res][HCS_ALPHA][3],
1065                                                                                 255, HC_slider_fname[gr_screen.res], hud_config_alpha_slider_up, hud_config_alpha_slider_down, NULL);
1066 #endif
1067         
1068         hud_config_color_init();
1069
1070         for (i=0; i<NUM_HUD_BUTTONS; i++) {
1071                 hb = &HC_buttons[gr_screen.res][i];
1072                 hb->button.create(&HC_ui_window, "", hb->x, hb->y, 60, 30, 0, 1);
1073                 // set up callback for when a mouse first goes over a button
1074                 hb->button.set_bmaps(hb->filename);
1075                 hb->button.set_highlight_action(common_play_highlight_sound);
1076                 hb->button.link_hotspot(hb->hotspot);
1077         }
1078
1079         // config file input name       
1080         HC_fname_input.create(&HC_ui_window, HC_fname_coords[gr_screen.res][0], HC_fname_coords[gr_screen.res][1], HC_fname_coords[gr_screen.res][2], MAX_FILENAME_LEN, "", UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_ESC_FOC); 
1081         HC_fname_input.set_text("");
1082
1083 #ifdef MAKE_FS1
1084         for (i=0; i<NUM_HC_SPECIAL_BITMAPS; i++) {
1085                 HC_special_bitmaps[i].bitmap = bm_load(HC_special_bitmaps[i].filename);
1086         }
1087
1088         // create sliders
1089         for(i=0; i<HC_NUM_SLIDERS; i++){
1090                 HC_sliders[gr_screen.res][i].slider.create(&HC_ui_window, HC_sliders[gr_screen.res][i].x, HC_sliders[gr_screen.res][i].y,
1091                                                                                                                                                 HC_sliders[gr_screen.res][i].dots, HC_sliders[gr_screen.res][i].filename,
1092                                                                                                                                                 HC_sliders[gr_screen.res][i].hotspot, HC_sliders[gr_screen.res][i].right_filename, HC_sliders[gr_screen.res][i].right_mask, HC_sliders[gr_screen.res][i].right_x, HC_sliders[gr_screen.res][i].right_y,
1093                                                                                                                                                 HC_sliders[gr_screen.res][i].left_filename, HC_sliders[gr_screen.res][i].left_mask, HC_sliders[gr_screen.res][i].left_x, HC_sliders[gr_screen.res][i].left_y,
1094                                                                                                                                                 HC_sliders[gr_screen.res][i].dot_w);
1095         }
1096         HC_sliders[gr_screen.res][HC_BRIGHTNESS_SLIDER].slider.pos = HUD_color_alpha - 3;
1097 #endif
1098         
1099         
1100         HC_gauge_hot = -1;
1101         HC_gauge_selected = -1;
1102
1103         HC_select_all = 0;
1104
1105         SDL_strlcpy(HC_fname, "", SDL_arraysize(HC_fname));
1106 }
1107
1108 int hud_config_show_flag_is_set(int i)
1109 {
1110         int show_flag_set;
1111
1112         if ( i < 32 ) {
1113                 show_flag_set = HUD_config.show_flags & (1<<i);
1114         } else {
1115                 show_flag_set = HUD_config.show_flags2 & (1<<(i-32));
1116         }
1117
1118         return show_flag_set;
1119 }
1120
1121 void hud_config_show_flag_set(int i)
1122 {
1123         if ( i < 32 ) {
1124                 HUD_config.show_flags |= (1<<i);
1125         } else {
1126                 HUD_config.show_flags2 |= (1<<(i-32));
1127         }
1128 }
1129
1130 void hud_config_show_flag_clear(int i)
1131 {
1132         if ( i < 32 ) {
1133                 HUD_config.show_flags &= ~(1<<i);
1134         } else {
1135                 HUD_config.show_flags2 &= ~(1<<(i-32));
1136         }
1137 }
1138
1139 int hud_config_popup_flag_is_set(int i)
1140 {
1141         int popup_flag_set;
1142
1143         if ( i < 32 ) {
1144                 popup_flag_set = HUD_config.popup_flags & (1<<i);
1145         } else {
1146                 popup_flag_set = HUD_config.popup_flags2 & (1<<(i-32));
1147         }
1148
1149         return popup_flag_set;
1150 }
1151
1152 void hud_config_popup_flag_set(int i)
1153 {
1154         if ( i < 32 ) {
1155                 HUD_config.popup_flags |= (1<<i);
1156         } else {
1157                 HUD_config.popup_flags2 |= (1<<(i-32));
1158         }
1159 }
1160
1161 void hud_config_popup_flag_clear(int i)
1162 {
1163         if ( i < 32 ) {
1164                 HUD_config.popup_flags &= ~(1<<i);
1165         } else {
1166                 HUD_config.popup_flags2 &= ~(1<<(i-32));
1167         }
1168 }
1169
1170 // render all the hud config gauges
1171 void hud_config_render_gauges()
1172 {
1173         int i;
1174         color use_color;
1175 #ifndef MAKE_FS1
1176         int alpha;
1177 #endif
1178
1179         for ( i=0; i<NUM_HUD_GAUGES; i++ ) {
1180                 if ( (hud_config_show_flag_is_set(i)) ) {
1181                         // set the correct color
1182                         if(!HC_gauge_regions[gr_screen.res][i].use_iff){
1183                                 use_color = HUD_config.clr[i];                  
1184                         } else {
1185 #ifndef MAKE_FS1
1186                                 if(HC_gauge_regions[gr_screen.res][i].color == 1){
1187                                         use_color = IFF_colors[IFF_COLOR_TAGGED][0];
1188                                 } else {
1189                                         use_color = IFF_colors[IFF_COLOR_HOSTILE][0];
1190                                 }
1191                         }
1192
1193                         if ( (HC_gauge_selected == i) || HC_select_all ) {
1194                                 alpha = 255;                            
1195                         } else if ( HC_gauge_hot == i ) {
1196                                 alpha = 200;                            
1197                         } else {                        
1198                                 alpha = 150;                            
1199                         }
1200                         gr_init_alphacolor(&use_color, use_color.red, use_color.green, use_color.blue, alpha, AC_TYPE_HUD);
1201                         gr_set_color_fast(&use_color);                  
1202 #else
1203                                 // set correct frame if using iff
1204                                 if ( HC_gauge_regions[gr_screen.res][i].use_iff ) {
1205                                         int offset=0;
1206                                         
1207                                         if ( HC_gauge_selected == i ) {
1208                                                 offset=2;
1209                                         } else if ( HC_gauge_hot == i ) {
1210                                                 offset=1;
1211                                         }       
1212         
1213                                         // If gauge is disabled, then draw disabled frame
1214                                         if ( !(hud_config_show_flag_is_set(i)) ) {
1215                                                 offset=3;
1216                                         }
1217
1218                                         if ( HC_gauge_regions[gr_screen.res][i].bitmap >= 0 ) {
1219                                                 SDL_assert(offset < HC_gauge_regions[gr_screen.res][i].nframes);
1220                                                 gr_set_bitmap(HC_gauge_regions[gr_screen.res][i].bitmap+offset, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1221                                                 gr_bitmap(HC_gauge_regions[gr_screen.res][i].x, HC_gauge_regions[gr_screen.res][i].y);
1222                                         }
1223                                 }
1224                         }
1225 #endif
1226                 } else {
1227                         // if its off, make it dark gray
1228                         gr_init_alphacolor(&use_color, 127, 127, 127, 64, AC_TYPE_HUD);
1229                         gr_set_color_fast(&use_color);                  
1230                 }
1231
1232                 // draw
1233                 if ( HC_gauge_regions[gr_screen.res][i].bitmap >= 0 ) {
1234                         gr_set_bitmap(HC_gauge_regions[gr_screen.res][i].bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1235                         gr_aabitmap(HC_gauge_regions[gr_screen.res][i].x, HC_gauge_regions[gr_screen.res][i].y);
1236                 }
1237                 
1238                 /*
1239                 else {
1240
1241                         int offset=0;
1242                                 // set correct frame if using iff
1243                         if ( HC_gauge_regions[i].use_iff ) {
1244                                 if ( HC_gauge_selected == i ) {
1245                                         offset=2;
1246                                 } else if ( HC_gauge_hot == i ) {
1247                                         offset=1;
1248                                 }
1249
1250                                 // If gauge is disabled, then draw disabled frame
1251                                 if ( !(hud_config_show_flag_is_set(i)) ) {
1252                                         offset=3;
1253                                 }
1254                         }
1255
1256                         if ( HC_gauge_regions[i].bitmap >= 0 ) {
1257                                 SDL_assert(offset < HC_gauge_regions[i].nframes);
1258                                 gr_set_bitmap(HC_gauge_regions[i].bitmap+offset);
1259                                 gr_bitmap(HC_gauge_regions[i].x, HC_gauge_regions[i].y);
1260                         }
1261                 }
1262                 */
1263         }
1264 }
1265
1266 // hud_config_init() is called when the game enters the state GS_STATE_HUD_CONFIG
1267 void hud_config_init()
1268 {
1269         hud_config_init_ui();
1270         hud_config_backup(); // save the HUD configuration in case the player decides to cancel changes
1271         HUD_config_inited = 1;
1272 }
1273
1274 // check for the mouse over gauge regions
1275 void hud_config_check_regions()
1276 {
1277         int                     i;
1278         UI_BUTTON       *b;
1279
1280         for ( i=0; i<NUM_HUD_GAUGES; i++ ) {
1281                 b = &HC_gauge_regions[gr_screen.res][i].button;
1282
1283                 // check for mouse over gauges
1284                 if ( b->button_hilighted() ) {
1285                         HC_gauge_hot = i;
1286                 }
1287
1288                 if ( b->pressed() ) {
1289                         gamesnd_play_iface(SND_USER_SELECT);
1290                         HC_gauge_selected = i;
1291
1292                         // turn off select all
1293                         hud_config_select_all_toggle(0);                        
1294                         
1295                         // maybe setup rgb sliders
1296 #ifndef MAKE_FS1
1297                         if(HC_gauge_regions[gr_screen.res][i].use_iff){
1298                                 HC_color_sliders[HCS_RED].hide();
1299                                 HC_color_sliders[HCS_GREEN].hide();
1300                                 HC_color_sliders[HCS_BLUE].hide();
1301                                 HC_color_sliders[HCS_ALPHA].hide();
1302
1303                                 HC_color_sliders[HCS_RED].disable();
1304                                 HC_color_sliders[HCS_GREEN].disable();
1305                                 HC_color_sliders[HCS_BLUE].disable();
1306                                 HC_color_sliders[HCS_ALPHA].disable();
1307                         } else {
1308                                 HC_color_sliders[HCS_RED].enable();
1309                                 HC_color_sliders[HCS_GREEN].enable();
1310                                 HC_color_sliders[HCS_BLUE].enable();
1311                                 HC_color_sliders[HCS_ALPHA].enable();                   
1312
1313                                 HC_color_sliders[HCS_RED].unhide();
1314                                 HC_color_sliders[HCS_GREEN].unhide();
1315                                 HC_color_sliders[HCS_BLUE].unhide();
1316                                 HC_color_sliders[HCS_ALPHA].unhide();                           
1317
1318                                 HC_color_sliders[HCS_RED].force_currentItem( HCS_CONV(HUD_config.clr[i].red) );
1319                                 HC_color_sliders[HCS_GREEN].force_currentItem( HCS_CONV(HUD_config.clr[i].green) );
1320                                 HC_color_sliders[HCS_BLUE].force_currentItem( HCS_CONV(HUD_config.clr[i].blue) );
1321                                 HC_color_sliders[HCS_ALPHA].force_currentItem( HCS_CONV(HUD_config.clr[i].alpha) );
1322                         }
1323 #endif
1324
1325                         // recalc alpha slider
1326                         hud_config_recalc_alpha_slider();
1327                 }
1328         }
1329 }
1330
1331 // set the display flags for a HUD gauge
1332 void hud_config_set_gauge_flags(int gauge_index, int on_flag, int popup_flag)
1333 {
1334         if ( on_flag ) {
1335                 hud_config_show_flag_set(gauge_index);
1336         } else {
1337                 hud_config_show_flag_clear(gauge_index);
1338         }
1339
1340         if ( popup_flag ) {
1341                 hud_config_popup_flag_set(gauge_index);
1342         } else {
1343                 hud_config_popup_flag_clear(gauge_index);
1344         }
1345 }
1346
1347 void hud_config_record_color(int color)
1348 {
1349         HUD_config.main_color = color;
1350         HUD_color_red = HC_colors[color].r;
1351         HUD_color_green = HC_colors[color].g;
1352         HUD_color_blue = HC_colors[color].b;
1353 }
1354
1355 // Set the HUD color
1356 void hud_config_set_color(int color)
1357 {
1358         int idx;        
1359
1360         hud_config_record_color(color);
1361
1362 #ifdef MAKE_FS1
1363         game_load_palette();
1364 #endif
1365
1366         HUD_init_hud_color_array();
1367
1368         // apply the color to all gauges
1369         for(idx=0; idx<NUM_HUD_GAUGES; idx++){
1370                 gr_init_alphacolor(&HUD_config.clr[idx], HC_colors[color].r, HC_colors[color].g, HC_colors[color].b, (HUD_color_alpha+1)*16, AC_TYPE_HUD);
1371         }
1372 }
1373
1374 void hud_config_stuff_colors(int r, int g, int b)
1375 {
1376         int idx;
1377
1378         // apply the color to all gauges
1379         for(idx=0; idx<NUM_HUD_GAUGES; idx++){
1380                 gr_init_alphacolor(&HUD_config.clr[idx], r, g, b, 255, AC_TYPE_HUD);
1381         }
1382 }
1383
1384 // leave hud config without accepting changes
1385 void hud_config_cancel()
1386 {
1387         hud_config_restore();
1388         gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
1389 }
1390
1391 // leave hud config with accepting changes
1392 void hud_config_commit()
1393 {
1394         gamesnd_play_iface(SND_COMMIT_PRESSED);
1395         gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
1396 }
1397
1398 // move gauge state from on->off->popup
1399 void hud_cycle_gauge_status()
1400 {
1401         if ( HC_gauge_selected < 0 ) {
1402                 return;
1403         }
1404
1405         // gauge is off, move to popup
1406         if ( !(hud_config_show_flag_is_set(HC_gauge_selected)) ) {
1407                 if ( HC_gauge_regions[gr_screen.res][HC_gauge_selected].can_popup ) {
1408                         hud_config_set_gauge_flags(HC_gauge_selected, 1, 1);    
1409                 } else {
1410                         hud_config_set_gauge_flags(HC_gauge_selected, 1, 0);    
1411                 }
1412                 return;
1413         }
1414
1415         // if gauge is popup, move to on
1416         if ( hud_config_popup_flag_is_set(HC_gauge_selected) ) {
1417                 hud_config_set_gauge_flags(HC_gauge_selected, 1, 0);
1418                 return;
1419         }
1420         
1421         // gauge must be on, move to off
1422         hud_config_set_gauge_flags(HC_gauge_selected, 0, 0);
1423 }
1424
1425 // handle keyboard input while in hud config
1426 void hud_config_handle_keypresses(int k)
1427 {
1428         switch(k) {
1429         case SDLK_ESCAPE:
1430                 hud_config_cancel();
1431                 break;
1432         case KEY_CTRLED+SDLK_RETURN:
1433                 hud_config_commit();
1434                 break;
1435         case SDLK_TAB:
1436                 gamesnd_play_iface(SND_USER_SELECT);
1437                 hud_cycle_gauge_status();
1438                 break;
1439         }
1440 }
1441
1442 // Handlers for when buttons get pressed
1443 void hud_config_button_do(int n)
1444 {
1445 #ifndef MAKE_FS1
1446         int idx;
1447         char name[256] = "";
1448 #endif
1449
1450         switch (n) {
1451         case HCB_AMBER:
1452                 hud_config_set_color(HUD_COLOR_AMBER);
1453                 gamesnd_play_iface(SND_USER_SELECT);
1454                 break;
1455         case HCB_BLUE:
1456                 hud_config_set_color(HUD_COLOR_BLUE);
1457                 gamesnd_play_iface(SND_USER_SELECT);
1458                 break;
1459         case HCB_GREEN:
1460                 hud_config_set_color(HUD_COLOR_GREEN);
1461                 gamesnd_play_iface(SND_USER_SELECT);
1462                 break;
1463         case HCB_ON:
1464                 if ( HC_gauge_selected < 0 ) {
1465                         break;
1466                 }
1467                 gamesnd_play_iface(SND_USER_SELECT);
1468                 hud_config_set_gauge_flags(HC_gauge_selected,1,0);
1469                 break;
1470         case HCB_OFF:
1471                 if ( HC_gauge_selected < 0 ) {
1472                         break;
1473                 }
1474                 gamesnd_play_iface(SND_USER_SELECT);
1475                 hud_config_set_gauge_flags(HC_gauge_selected,0,0);
1476                 break;
1477         case HCB_POPUP:
1478                 if ( HC_gauge_selected < 0 ) {
1479                         break;
1480                 }
1481                 gamesnd_play_iface(SND_USER_SELECT);
1482                 hud_config_set_gauge_flags(HC_gauge_selected,1,1);
1483                 break;
1484         case HCB_RESET:
1485                 gamesnd_play_iface(SND_RESET_PRESSED);
1486                 hud_config_select_all_toggle(0);
1487                 hud_set_default_hud_config(Player);
1488                 hud_config_synch_ui();
1489                 break;
1490         case HCB_ACCEPT:
1491                 hud_config_commit();
1492                 break;
1493
1494         // new stuff
1495 #ifndef MAKE_FS1
1496         case HCB_RED_UP:
1497                 if( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()) >= 255){
1498                         gamesnd_play_iface(SND_GENERAL_FAIL);
1499                 } else {
1500                         gamesnd_play_iface(SND_USER_SELECT);
1501                         HC_color_sliders[HCS_RED].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()) + 1)  );
1502                         hud_config_red_slider();                        
1503                 }               
1504                 break;
1505
1506         case HCB_GREEN_UP:
1507                 if( HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) >= 255){
1508                         gamesnd_play_iface(SND_GENERAL_FAIL);
1509                 } else {
1510                         gamesnd_play_iface(SND_USER_SELECT);
1511                         HC_color_sliders[HCS_GREEN].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) + 1) );
1512                         hud_config_green_slider();
1513                 }               
1514                 break;
1515
1516         case HCB_BLUE_UP:
1517                 if( HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) >= 255){
1518                         gamesnd_play_iface(SND_GENERAL_FAIL);
1519                 } else {
1520                         gamesnd_play_iface(SND_USER_SELECT);
1521                         HC_color_sliders[HCS_BLUE].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) + 1) );
1522                         hud_config_blue_slider();
1523                 }               
1524                 break;
1525
1526         case HCB_I_UP:
1527                 if( HCS_CONV(HC_color_sliders[HCS_ALPHA].get_currentItem()) >= 255){
1528                         gamesnd_play_iface(SND_GENERAL_FAIL);
1529                 } else {
1530                         gamesnd_play_iface(SND_USER_SELECT);
1531                         HC_color_sliders[HCS_ALPHA].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_ALPHA].get_currentItem()) + 1) );
1532                         hud_config_alpha_slider_up();
1533                 }               
1534                 break;
1535
1536         case HCB_RED_DOWN:
1537                 if( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()) <= 0){
1538                         gamesnd_play_iface(SND_GENERAL_FAIL);
1539                 } else {
1540                         gamesnd_play_iface(SND_USER_SELECT);
1541                         HC_color_sliders[HCS_RED].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()) - 1) );
1542                         hud_config_red_slider();
1543                 }               
1544                 break;
1545
1546         case HCB_GREEN_DOWN:
1547                 if( HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) <= 0){
1548                         gamesnd_play_iface(SND_GENERAL_FAIL);
1549                 } else {
1550                         gamesnd_play_iface(SND_USER_SELECT);
1551                         HC_color_sliders[HCS_GREEN].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) - 1) );
1552                         hud_config_green_slider();
1553                 }               
1554                 break;
1555
1556         case HCB_BLUE_DOWN:
1557                 if( HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) <= 0){
1558                         gamesnd_play_iface(SND_GENERAL_FAIL);
1559                 } else {
1560                         gamesnd_play_iface(SND_USER_SELECT);
1561                         HC_color_sliders[HCS_BLUE].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) - 1) );
1562                         hud_config_blue_slider();
1563                 }               
1564                 break;
1565
1566         case HCB_I_DOWN:
1567                 if( HCS_CONV(HC_color_sliders[HCS_ALPHA].get_currentItem()) <= 0){
1568                         gamesnd_play_iface(SND_GENERAL_FAIL);
1569                 } else {
1570                         gamesnd_play_iface(SND_USER_SELECT);
1571                         HC_color_sliders[HCS_ALPHA].force_currentItem( HCS_CONV( HCS_CONV(HC_color_sliders[HCS_ALPHA].get_currentItem()) - 1) );
1572                         hud_config_alpha_slider_down();
1573                 }               
1574                 break;
1575
1576         case HCB_SAVE_HCF:              
1577                 int exists;
1578                 char *out;
1579
1580                 // get the text in the input control
1581                 exists = 0;
1582                 HC_fname_input.get_text(name);
1583                 if(strlen(name) > 0){
1584                         // if the filename in there already exists
1585                         for(idx=0; idx<HC_num_files; idx++){
1586                                 if(!SDL_strcasecmp(HC_filenames[idx], name)){
1587                                         exists = 1;
1588                                 }
1589                         }
1590                 }
1591
1592                 // already exists?
1593                 if(exists){
1594                         // save the file                        
1595                         out = cf_add_ext(name, ".hcf");
1596                         hud_config_color_save(out);
1597                         break;
1598                 }
1599
1600                 // otherwise we have to create a new file
1601                 if(HC_num_files >= MAX_HCF_FILES){
1602                         popup(PF_USE_AFFIRMATIVE_ICON, 1, "OK", "Max number of hud config files reached!");
1603                         break;
1604                 }
1605
1606                 // save the file, maybe generating a new filename
1607                 if(strlen(name) <= 0){
1608                         SDL_snprintf(name, SDL_arraysize(name), "hud_%d.hcf", HC_num_files + 1);
1609                         out = name;
1610                 } else {
1611                         out = cf_add_ext(name, ".hcf");
1612                 }
1613                 HC_filenames[HC_num_files++] = strdup(out);
1614                 hud_config_color_save(out);             
1615
1616                 HC_fname_input.set_text(out);
1617                 break;
1618
1619         case HCB_PREV_HCF:
1620                 if(HC_num_files <= 0){
1621                         break;
1622                 }
1623
1624                 if(HC_current_file <= 0){
1625                         HC_current_file = HC_num_files - 1;
1626                 } else {
1627                         HC_current_file--;
1628                 }
1629                 // load em up
1630                 hud_config_color_load(HC_filenames[HC_current_file]);
1631                 hud_config_synch_ui();
1632
1633                 HC_fname_input.set_text(HC_filenames[HC_current_file]);
1634                 break;
1635
1636         case HCB_NEXT_HCF:
1637                 if(HC_num_files <= 0){
1638                         break;
1639                 }
1640
1641                 if(HC_current_file >= HC_num_files - 1){
1642                         HC_current_file = 0;
1643                 } else {
1644                         HC_current_file++;
1645                 }
1646
1647                 // load em up           
1648                 hud_config_color_load(HC_filenames[HC_current_file]);
1649                 hud_config_synch_ui();
1650
1651                 HC_fname_input.set_text(HC_filenames[HC_current_file]);
1652                 break;
1653
1654         case HCB_SELECT_ALL:                            
1655                 hud_config_select_all_toggle(!HC_select_all);
1656                 break;  
1657 #endif  // MAKE_FS1
1658
1659         default:
1660                 Int3();
1661                 break;
1662         }
1663 }
1664
1665 // Check if any buttons have been pressed
1666 void hud_config_check_buttons()
1667 {
1668         int                     i;
1669         UI_BUTTON       *b;
1670
1671         for ( i=0; i<NUM_HUD_BUTTONS; i++ ) {
1672                 b = &HC_buttons[gr_screen.res][i].button;
1673                 if ( b->pressed() ) {
1674                         hud_config_button_do(i);
1675                 }
1676         }
1677 }
1678
1679 // set the hud color button
1680 void hud_config_draw_color_status()
1681 {
1682         if ( HC_buttons[gr_screen.res][HCB_AMBER].button.button_down() || HC_buttons[gr_screen.res][HCB_GREEN].button.button_down() || HC_buttons[gr_screen.res][HCB_BLUE].button.button_down() ) {
1683                 return;
1684         }
1685
1686         switch(HUD_config.main_color) {
1687         case HUD_COLOR_AMBER:
1688                 HC_buttons[gr_screen.res][HCB_AMBER].button.draw_forced(2);
1689                 break;
1690         case HUD_COLOR_GREEN:
1691                 HC_buttons[gr_screen.res][HCB_GREEN].button.draw_forced(2);
1692                 break;
1693         case HUD_COLOR_BLUE:
1694                 HC_buttons[gr_screen.res][HCB_BLUE].button.draw_forced(2);
1695                 break;
1696         }
1697 }
1698
1699 // set the status (on/off/popup) for the selected gauge
1700 void hud_config_draw_gauge_status()
1701 {
1702         if ( HC_gauge_selected < 0 ) {
1703                 return;
1704         }
1705
1706         if ( HC_buttons[gr_screen.res][HCB_OFF].button.button_down() || HC_buttons[gr_screen.res][HCB_POPUP].button.button_down() || HC_buttons[gr_screen.res][HCB_ON].button.button_down() ) {
1707                 return;
1708         }
1709
1710         // check if off
1711         if ( !(hud_config_show_flag_is_set(HC_gauge_selected)) ) {
1712                 HC_buttons[gr_screen.res][HCB_OFF].button.draw_forced(2);
1713                 return;
1714         }
1715
1716         // check if popup
1717         if ( hud_config_popup_flag_is_set(HC_gauge_selected) ) {
1718                 HC_buttons[gr_screen.res][HCB_POPUP].button.draw_forced(2);
1719                 return;
1720         }
1721
1722         // check if on
1723         if ( hud_config_show_flag_is_set(HC_gauge_selected) ) {
1724                 HC_buttons[gr_screen.res][HCB_ON].button.draw_forced(2);
1725                 return;
1726         }
1727
1728         Int3(); // should never get here
1729 }
1730
1731 // disable a HUD config button
1732 void hud_config_button_disable(int index)
1733 {
1734         // HC_buttons[gr_screen.res][index].button.hide();
1735         HC_buttons[gr_screen.res][index].button.disable();
1736 }
1737
1738 // enable a HUD config button
1739 void hud_config_button_enable(int index)
1740 {
1741         // HC_buttons[gr_screen.res][index].button.unhide();
1742         HC_buttons[gr_screen.res][index].button.enable();
1743 }
1744
1745 // determine if on/off/popup buttons should be shown
1746 void hud_config_set_button_state()
1747 {
1748         if ( HC_gauge_selected < 0 ) {
1749                 hud_config_button_disable(HCB_ON);
1750                 hud_config_button_disable(HCB_OFF);
1751                 hud_config_button_disable(HCB_POPUP);
1752                 return;
1753         }
1754
1755         // on/off are always on
1756         hud_config_button_enable(HCB_ON);
1757         hud_config_button_enable(HCB_OFF);
1758
1759         // popup is maybe available
1760         if ( HC_gauge_regions[gr_screen.res][HC_gauge_selected].can_popup ) {
1761                 hud_config_button_enable(HCB_POPUP);
1762         } else {
1763                 hud_config_button_disable(HCB_POPUP);
1764         }
1765 }
1766
1767 void hud_config_render_description()
1768 {
1769         int w,h,sx,sy;
1770
1771         if ( HC_gauge_selected >= 0 ) {
1772                 gr_set_color_fast(&Color_normal);
1773
1774                 gr_get_string_size(&w, &h, HC_gauge_descriptions(HC_gauge_selected));
1775                 sx = fl2i(HC_gauge_description_coords[gr_screen.res][0] + (HC_gauge_description_coords[gr_screen.res][2] - w)/2.0f);
1776                 sy = HC_gauge_description_coords[gr_screen.res][1];
1777                 gr_string(sx, sy, HC_gauge_descriptions(HC_gauge_selected));
1778         }
1779 }
1780
1781 void hud_config_render_special_bitmaps()
1782 {
1783 #ifdef MAKE_FS1
1784         int i;
1785         for (i=1; i<NUM_HC_SPECIAL_BITMAPS; i++) {
1786                 if (HC_special_bitmaps[i].bitmap >= 0) {
1787                         gr_set_bitmap(HC_special_bitmaps[i].bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1788                         gr_bitmap(HC_special_bitmaps[i].x, HC_special_bitmaps[i].y);
1789                 }
1790         }
1791 #endif
1792 }
1793
1794 // update HUD_color_alpha based on brightness slider
1795 void hud_config_update_brightness()
1796 {
1797 #ifdef MAKE_FS1
1798         HUD_color_alpha = HC_sliders[gr_screen.res][HC_BRIGHTNESS_SLIDER].slider.pos+3;
1799         SDL_assert(HUD_color_alpha >= HUD_COLOR_ALPHA_USER_MIN);
1800         SDL_assert(HUD_color_alpha <= HUD_COLOR_ALPHA_USER_MAX);
1801 #endif
1802 }
1803
1804 // redraw any pressed buttons, needed since the glow on pressed buttons might get clipped off by
1805 // adjacent buttons otherwise
1806 void hud_config_redraw_pressed_buttons()
1807 {
1808         int                     i;
1809         UI_BUTTON       *b;
1810
1811         for ( i = 0; i < NUM_HUD_BUTTONS; i++ ) {
1812                 b = &HC_buttons[gr_screen.res][i].button;
1813                 if ( b->button_down() ) {
1814                         b->draw_forced(2);
1815                 }
1816         }
1817 }
1818
1819 // hud_config_do_frame() is called from the main freespace loop while the game is in the state
1820 // GS_STATE_HUD_CONFIG.
1821 //
1822 void hud_config_do_frame(float frametime) 
1823 {
1824         int k;
1825
1826         if (!HUD_config_inited) {
1827                 hud_config_init();
1828         }
1829
1830         HC_gauge_hot = -1;
1831
1832         hud_config_set_button_state();
1833
1834         k = HC_ui_window.process();
1835
1836         hud_config_handle_keypresses(k);
1837         hud_config_check_regions();
1838         hud_config_check_buttons();
1839         hud_config_update_brightness();
1840
1841         // set the background
1842         GR_MAYBE_CLEAR_RES(HC_background_bitmap);
1843         if ( HC_background_bitmap > 0 ) {
1844                 gr_set_bitmap(HC_background_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1845                 gr_bitmap(0,0);
1846         }
1847
1848         // rgb slider/button stuff
1849         hud_config_process_colors();
1850
1851         HC_ui_window.draw();
1852         hud_config_redraw_pressed_buttons();
1853
1854         hud_config_draw_gauge_status();
1855         hud_config_draw_color_status();
1856
1857 #ifdef MAKE_FS1
1858         if (HC_special_bitmaps[HC_SPECIAL_RETICLE].bitmap >= 0) {
1859                 hud_set_default_color();
1860                 gr_set_bitmap(HC_special_bitmaps[HC_SPECIAL_RETICLE].bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1861                 gr_aabitmap(HC_special_bitmaps[HC_SPECIAL_RETICLE].x, HC_special_bitmaps[HC_SPECIAL_RETICLE].y);
1862         }
1863 #endif
1864
1865         // maybe force draw the select all button
1866 #ifndef MAKE_FS1
1867         if(HC_select_all){
1868                 HC_buttons[gr_screen.res][HCB_SELECT_ALL].button.draw_forced(2);
1869         }
1870 #endif
1871
1872         hud_config_render_gauges();
1873         hud_config_render_special_bitmaps();
1874         hud_config_render_description();        
1875
1876         gr_flip();
1877 }
1878
1879 void hud_config_unload_gauges()
1880 {
1881         int                                     i, j;
1882         HC_gauge_region *hg;
1883
1884         for (i=0; i<NUM_HUD_GAUGES; i++) {
1885                 hg = &HC_gauge_regions[gr_screen.res][i];
1886
1887                 if ( hg->bitmap >= 0 ) {
1888                         for ( j=0; j<hg->nframes; j++ ) {
1889                                 bm_unload(hg->bitmap+j);
1890                         }
1891                 }
1892
1893                 hg->bitmap=-1;
1894                 hg->nframes=0;
1895         }
1896 }
1897
1898 // hud_config_close() is called when the player leaves the hud configuration screen
1899 //
1900 void hud_config_close()
1901 {
1902 #ifdef MAKE_FS1
1903         common_free_interface_palette();                // restore game palette
1904 #endif
1905         hud_config_unload_gauges();
1906         hud_init_popup_timers();                                // ensure no popup gauges are active
1907
1908         hud_config_color_close();
1909
1910         HC_ui_window.destroy();
1911 }
1912
1913 // hud_set_default_hud_config() will set the hud configuration to default values
1914 void hud_set_default_hud_config(player *p)
1915 {
1916         int idx;
1917
1918         HUD_color_alpha = HUD_COLOR_ALPHA_DEFAULT;
1919         HUD_config.main_color = HUD_COLOR_GREEN;
1920         HUD_color_red = HC_colors[HUD_config.main_color].r;
1921         HUD_color_green = HC_colors[HUD_config.main_color].g;
1922         HUD_color_blue = HC_colors[HUD_config.main_color].b;
1923
1924         for(idx=0; idx<NUM_HUD_GAUGES; idx++){
1925                 gr_init_alphacolor(&HUD_config.clr[idx], HUD_color_red, HUD_color_green, HUD_color_blue, (HUD_color_alpha+1)*16, AC_TYPE_HUD);
1926         }
1927
1928         HUD_config.show_flags = HUD_config_default_flags;
1929         HUD_config.show_flags2 = HUD_config_default_flags2;
1930         HUD_config.popup_flags = HUD_default_popup_mask;
1931         HUD_config.popup_flags2 = HUD_default_popup_mask2;
1932         HUD_config.num_msg_window_lines                 = 4;    // one more than is actually visible
1933         HUD_config.rp_flags = RP_DEFAULT;
1934         HUD_config.rp_dist = RR_INFINITY;
1935         HUD_config.is_observer = 0;
1936 }
1937
1938 // hud_config_restore() will restore the hud configuration the player started with when the 
1939 // hud configuration screen was started
1940 //
1941 void hud_config_restore()
1942 {
1943         HUD_config = HUD_config_backup;
1944 }
1945
1946 // hud_config_backup() will save the players hud configuration when they enter the hud configuration
1947 // screen.  This is done in case the player decides to cancel the changes that were made.
1948 //
1949 void hud_config_backup()
1950 {
1951         HUD_config_backup = HUD_config;
1952 }
1953
1954 void hud_config_as_observer(ship *shipp,ai_info *aif)
1955 {
1956         // store the current hus
1957         hud_config_backup();
1958
1959         // bash these values so the HUD is not offset incorrectly
1960         HUD_offset_x = 0.0f;
1961         HUD_offset_y = 0.0f;
1962
1963         // initialize the observer HUD
1964         hud_observer_init(shipp,aif);   
1965 }
1966
1967 void hud_config_as_player()
1968 {
1969
1970
1971 // ---------------------------------------------------------------------------------------------------------------
1972 // RGB color stuff
1973 //
1974
1975 void hud_config_color_save(const char *name)
1976 {
1977         int idx;
1978         CFILE *out = cfopen(name, "wt", CFILE_NORMAL, CF_TYPE_PLAYERS);
1979         char vals[255] = "";
1980
1981         // bad
1982         if(out == NULL){
1983                 Int3();
1984                 return;
1985         }       
1986
1987         // write out all gauges
1988         for(idx=0; idx<NUM_HUD_GAUGES; idx++){
1989                 cfputs("+Gauge: ", out);
1990                 cfputs(HC_gauge_descriptions(idx), out);                
1991                 cfputs("\n", out);
1992                 cfputs("+RGBA: ", out);
1993                 SDL_snprintf(vals, SDL_arraysize(vals), "%d %d %d %d\n\n", HUD_config.clr[idx].red, HUD_config.clr[idx].green, HUD_config.clr[idx].blue, HUD_config.clr[idx].alpha);
1994                 cfputs(vals, out);
1995         }
1996         
1997         // close the file
1998         cfclose(out);   
1999 }
2000
2001 void hud_config_color_load(const char *name)
2002 {
2003         int idx;
2004         char str[1024] = "";
2005         char *fname;
2006
2007         fname = cf_add_ext(name, ".hcf");
2008
2009         try {
2010                 read_file_text(fname);
2011                 reset_parse();
2012
2013                 // write out all gauges
2014                 for(idx=0; idx<NUM_HUD_GAUGES; idx++){
2015                         required_string("+Gauge:");
2016                         stuff_string(str, F_NAME, NULL, 1023);
2017
2018                         required_string("+RGBA:");
2019                         stuff_byte(&HUD_config.clr[idx].red);
2020                         stuff_byte(&HUD_config.clr[idx].green);
2021                         stuff_byte(&HUD_config.clr[idx].blue);
2022                         stuff_byte(&HUD_config.clr[idx].alpha);
2023                 }
2024         } catch (parse_error_t) {
2025                 mprintf(("Error opening hud config file!\n"));
2026         }
2027 }
2028
2029 void hud_config_alpha_slider_up()
2030 {       
2031 #ifndef MAKE_FS1
2032         int pos = HCS_CONV(HC_color_sliders[HCS_ALPHA].get_currentItem());
2033         int max = SDL_max(SDL_max( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) ), HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) );
2034
2035         // if this would put the brightest element past its limit, skip
2036         if(max >= 255){
2037                 HC_color_sliders[HCS_ALPHA].force_currentItem( HCS_CONV(pos - 1) );
2038                 return;
2039         }
2040         
2041         // otherwise bump everybody up by one
2042         HC_color_sliders[HCS_RED].force_currentItem( HCS_CONV(HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()) + 1) );     
2043         HC_color_sliders[HCS_GREEN].force_currentItem( HCS_CONV(HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) + 1) );
2044         HC_color_sliders[HCS_BLUE].force_currentItem( HCS_CONV(HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) + 1) );
2045         
2046         // apply
2047         if(HC_select_all){
2048                 hud_config_stuff_colors( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) );
2049         } else {
2050                 gr_init_alphacolor(&HUD_config.clr[HC_gauge_selected], HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()), 255, AC_TYPE_HUD);
2051         }
2052 #endif
2053 }
2054
2055 void hud_config_alpha_slider_down()
2056 {       
2057 #ifndef MAKE_FS1
2058         int pos = HCS_CONV(HC_color_sliders[HCS_ALPHA].get_currentItem());
2059         int min = SDL_min(SDL_min( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) ), HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) );
2060
2061         // if this would put the brightest element past its limit, skip
2062         if(min <= 0){
2063                 HC_color_sliders[HCS_ALPHA].force_currentItem( HCS_CONV(pos + 1) );
2064                 return;
2065         }
2066         
2067         // otherwise bump everybody up by one
2068         HC_color_sliders[HCS_RED].force_currentItem( HCS_CONV(HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()) - 1) );     
2069         HC_color_sliders[HCS_GREEN].force_currentItem( HCS_CONV(HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) - 1) );
2070         HC_color_sliders[HCS_BLUE].force_currentItem( HCS_CONV(HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) - 1) );   
2071
2072         // apply
2073         if(HC_select_all){
2074                 hud_config_stuff_colors( HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()) );
2075         } else {
2076                 gr_init_alphacolor(&HUD_config.clr[HC_gauge_selected], HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()), HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem()), 255, AC_TYPE_HUD);
2077         }
2078 #endif
2079 }
2080
2081 void hud_config_recalc_alpha_slider()
2082 {
2083 #ifndef MAKE_FS1
2084         int avg =HC_color_sliders[HCS_RED].get_currentItem() + HC_color_sliders[HCS_GREEN].get_currentItem() + HC_color_sliders[HCS_BLUE].get_currentItem();
2085         avg /= 3;
2086         HC_color_sliders[HCS_ALPHA].force_currentItem( avg );
2087 #endif
2088 }
2089
2090 void hud_config_red_slider()
2091 {
2092 #ifndef MAKE_FS1
2093         int idx;
2094         int pos = HCS_CONV(HC_color_sliders[HCS_RED].get_currentItem()) ;
2095
2096         // select all ?
2097         if(HC_select_all){
2098                 for(idx=0; idx<NUM_HUD_GAUGES; idx++){
2099                         gr_init_alphacolor(&HUD_config.clr[idx], pos, HUD_config.clr[idx].green, HUD_config.clr[idx].blue, HUD_config.clr[idx].alpha, AC_TYPE_HUD);
2100                 }
2101         }
2102         // individual gauge
2103         else {
2104                 if(HC_gauge_selected < 0){
2105                         return;
2106                 }
2107
2108                 // get slider position  
2109                 gr_init_alphacolor(&HUD_config.clr[HC_gauge_selected], pos, HUD_config.clr[HC_gauge_selected].green, HUD_config.clr[HC_gauge_selected].blue, HUD_config.clr[HC_gauge_selected].alpha, AC_TYPE_HUD);
2110         }       
2111
2112         hud_config_recalc_alpha_slider();
2113 #endif
2114 }
2115
2116 void hud_config_green_slider()
2117 {
2118 #ifndef MAKE_FS1
2119         int idx;
2120         int pos = HCS_CONV(HC_color_sliders[HCS_GREEN].get_currentItem()) ;
2121
2122         // select all ?
2123         if(HC_select_all){
2124                 for(idx=0; idx<NUM_HUD_GAUGES; idx++){
2125                         gr_init_alphacolor(&HUD_config.clr[idx], HUD_config.clr[idx].red, pos, HUD_config.clr[idx].blue, HUD_config.clr[idx].alpha, AC_TYPE_HUD);
2126                 }
2127         }
2128         // individual gauge
2129         else {
2130                 if(HC_gauge_selected < 0){
2131                         return;
2132                 }
2133
2134                 // get slider position  
2135                 gr_init_alphacolor(&HUD_config.clr[HC_gauge_selected], HUD_config.clr[HC_gauge_selected].red, pos, HUD_config.clr[HC_gauge_selected].blue, HUD_config.clr[HC_gauge_selected].alpha, AC_TYPE_HUD);
2136         }       
2137
2138         hud_config_recalc_alpha_slider();
2139 #endif
2140 }
2141
2142 void hud_config_blue_slider()
2143 {
2144 #ifndef MAKE_FS1
2145         int idx;
2146         int pos = HCS_CONV(HC_color_sliders[HCS_BLUE].get_currentItem());
2147
2148         // select all ?
2149         if(HC_select_all){
2150                 for(idx=0; idx<NUM_HUD_GAUGES; idx++){
2151                         gr_init_alphacolor(&HUD_config.clr[idx], HUD_config.clr[idx].red, HUD_config.clr[idx].green, pos, HUD_config.clr[idx].alpha, AC_TYPE_HUD);
2152                 }
2153         }
2154         // individual gauge
2155         else {
2156                 if(HC_gauge_selected < 0){
2157                         return;
2158                 }
2159
2160                 // get slider position  
2161                 gr_init_alphacolor(&HUD_config.clr[HC_gauge_selected], HUD_config.clr[HC_gauge_selected].red, HUD_config.clr[HC_gauge_selected].green, pos, HUD_config.clr[HC_gauge_selected].alpha, AC_TYPE_HUD);
2162         }       
2163
2164         hud_config_recalc_alpha_slider();
2165 #endif
2166 }
2167
2168 void hud_config_process_colors()
2169 {       
2170 }
2171
2172 void hud_config_color_init()
2173 {
2174         HC_current_file = -1;
2175
2176         // get a list of all hcf files
2177         memset(HC_filenames, 0, sizeof(char*) * MAX_HCF_FILES);
2178         HC_num_files = cf_get_file_list(MAX_HCF_FILES, HC_filenames, CF_TYPE_PLAYERS, "*.hcf", CF_SORT_NAME);
2179 }
2180
2181 void hud_config_color_close()
2182 {
2183         int idx;
2184
2185         // free all 
2186         for(idx=0; idx<HC_num_files; idx++){
2187                 if(HC_filenames[idx] != NULL){
2188                         free(HC_filenames[idx]);
2189                         HC_filenames[idx] = NULL;
2190                 }
2191         }
2192 }
2193
2194 void hud_config_select_all_toggle(int toggle)
2195 {       
2196 #ifndef MAKE_FS1
2197         int r, g, b, a;
2198
2199         // if we're turning off
2200         if(!toggle){                            
2201                 // determine if on/off/popup buttons should be shown
2202                 hud_config_set_button_state();
2203
2204                 HC_select_all = 0;
2205         } else {
2206                 // synch stuff up
2207                 hud_config_synch_ui();
2208                 
2209                 // if we had a gauge previously selected, use its color everywhere
2210                 if(HC_gauge_selected < 0){
2211                         r = HUD_config.clr[HUD_RADAR].red;
2212                         g = HUD_config.clr[HUD_RADAR].green;
2213                         b = HUD_config.clr[HUD_RADAR].blue;                     
2214                         a = HUD_config.clr[HUD_RADAR].alpha;
2215                 } else {
2216                         r = HUD_config.clr[HC_gauge_selected].red;
2217                         g = HUD_config.clr[HC_gauge_selected].green;
2218                         b = HUD_config.clr[HC_gauge_selected].blue;                     
2219                         a = HUD_config.clr[HC_gauge_selected].alpha;
2220                 }
2221                 hud_config_stuff_colors(r, g, b);
2222
2223                 // no gauge selected
2224                 HC_gauge_selected = -1;         
2225
2226                 // enable all sliders
2227                 HC_color_sliders[HCS_RED].enable();
2228                 HC_color_sliders[HCS_GREEN].enable();
2229                 HC_color_sliders[HCS_BLUE].enable();
2230                 HC_color_sliders[HCS_ALPHA].enable();
2231                 HC_color_sliders[HCS_RED].unhide();
2232                 HC_color_sliders[HCS_GREEN].unhide();
2233                 HC_color_sliders[HCS_BLUE].unhide();
2234                 HC_color_sliders[HCS_ALPHA].unhide();
2235                 HC_color_sliders[HCS_RED].force_currentItem( HCS_CONV(r) );
2236                 HC_color_sliders[HCS_GREEN].force_currentItem( HCS_CONV(g) );
2237                 HC_color_sliders[HCS_BLUE].force_currentItem( HCS_CONV(b) );
2238                 HC_color_sliders[HCS_ALPHA].force_currentItem( HCS_CONV(a) );
2239
2240                 // recalc alpha
2241                 hud_config_recalc_alpha_slider();
2242
2243                 // disable all three buttons
2244                 hud_config_button_disable(HCB_ON);
2245                 hud_config_button_disable(HCB_OFF);
2246                 hud_config_button_disable(HCB_POPUP);
2247
2248                 HC_select_all = 1;
2249         }
2250 #endif
2251 }