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