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