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