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