1 /*
2 * Created by WMCoolmon for the FreeSpace2 Source Code Project.
3 * You may not sell or otherwise commercially exploit the source or things you
4 * create based on the source.
5 */
6
7
8
9 #include <cstddef>
10
11 #include "cmdline/cmdline.h"
12 #include "graphics/font.h" //for gr_force_fit_string
13 #include "hud/hud.h"
14 #include "hud/hudbrackets.h"
15 #include "hud/hudconfig.h" // for retrieving user's hud config
16 #include "hud/hudescort.h"
17 #include "hud/hudets.h"
18 #include "hud/hudlock.h"
19 #include "hud/hudmessage.h"
20 #include "hud/hudparse.h" //Duh.
21 #include "hud/hudreticle.h"
22 #include "hud/hudscripting.h"
23 #include "hud/hudshield.h"
24 #include "hud/hudsquadmsg.h"
25 #include "hud/hudtarget.h"
26 #include "hud/hudtargetbox.h"
27 #include "hud/hudwingmanstatus.h"
28 #include "localization/localize.h"
29 #include "mission/missionmessage.h"
30 #include "mission/missiontraining.h"
31 #include "parse/parselo.h"
32 #include "radar/radar.h"
33 #include "radar/radardradis.h"
34 #include "radar/radarngon.h"
35 #include "radar/radarorb.h"
36 #include "radar/radarsetup.h"
37 #include "ship/ship.h" //for ship struct
38
39 //Global stuffs
40 extern bool Ships_inited; //Need this
41
42 float Hud_unit_multiplier = 1.0f; //Backslash
43 float Hud_speed_multiplier = 1.0f; //The E
44
45 // Goober5000
46 int Hud_reticle_style = HUD_RETICLE_STYLE_FS2;
47
48 bool Hud_retail = true;
49 bool Scale_retail_gauges = true;
50 int Force_scaling_above_res_global[2] = {-1, -1};
51
52 int Hud_font = -1;
53
54 bool Chase_view_only_ex = false;
55
56 //WARNING: If you add gauges to this array, make sure to bump Num_builtin_gauges!
57 const int Num_builtin_gauges = 42;
58 static int Builtin_gauges[Num_builtin_gauges] = {
59 HUD_OBJECT_MESSAGES,
60 HUD_OBJECT_TRAINING_MESSAGES,
61 HUD_OBJECT_SUPPORT,
62 HUD_OBJECT_DAMAGE,
63 HUD_OBJECT_WINGMAN_STATUS,
64 HUD_OBJECT_AUTO_SPEED,
65 HUD_OBJECT_AUTO_TARGET,
66 HUD_OBJECT_CMEASURES,
67 HUD_OBJECT_TALKING_HEAD,
68 HUD_OBJECT_DIRECTIVES,
69 HUD_OBJECT_WEAPONS,
70 HUD_OBJECT_OBJ_NOTIFY,
71 HUD_OBJECT_SQUAD_MSG,
72 HUD_OBJECT_LAG,
73 HUD_OBJECT_MINI_SHIELD,
74 HUD_OBJECT_PLAYER_SHIELD,
75 HUD_OBJECT_TARGET_SHIELD,
76 HUD_OBJECT_ESCORT,
77 HUD_OBJECT_MISSION_TIME,
78 HUD_OBJECT_TARGET_MONITOR,
79 HUD_OBJECT_EXTRA_TARGET_DATA,
80 HUD_OBJECT_AFTERBURNER,
81 HUD_OBJECT_WEAPON_ENERGY,
82 HUD_OBJECT_TEXT_WARNINGS,
83 HUD_OBJECT_CENTER_RETICLE,
84 HUD_OBJECT_THROTTLE,
85 HUD_OBJECT_THREAT,
86 HUD_OBJECT_LEAD,
87 HUD_OBJECT_LOCK,
88 HUD_OBJECT_MULTI_MSG,
89 HUD_OBJECT_VOICE_STATUS,
90 HUD_OBJECT_PING,
91 HUD_OBJECT_SUPERNOVA,
92 HUD_OBJECT_OFFSCREEN,
93 HUD_OBJECT_BRACKETS,
94 HUD_OBJECT_ORIENTATION_TEE,
95 HUD_OBJECT_HOSTILE_TRI,
96 HUD_OBJECT_TARGET_TRI,
97 HUD_OBJECT_MISSILE_TRI,
98 HUD_OBJECT_KILLS,
99 HUD_OBJECT_FIXED_MESSAGES,
100 HUD_OBJECT_ETS_RETAIL
101 };
102
103 Legacy_HUD_gauge_pair Legacy_HUD_gauges[NUM_HUD_GAUGES] =
104 {
105 { "LEAD_INDICATOR", HUD_OBJECT_LEAD },
106 { "ORIENTATION_TEE", HUD_OBJECT_ORIENTATION_TEE },
107 { "HOSTILE_TRIANGLE", HUD_OBJECT_HOSTILE_TRI },
108 { "TARGET_TRIANGLE", HUD_OBJECT_TARGET_TRI },
109 { "MISSION_TIME", HUD_OBJECT_MISSION_TIME },
110 { "RETICLE_CIRCLE", -1 },
111 { "THROTTLE_GAUGE", HUD_OBJECT_THROTTLE },
112 { "RADAR", HUD_OBJECT_RADAR_STD },
113 { "TARGET_MONITOR", HUD_OBJECT_TARGET_MONITOR },
114 { "CENTER_RETICLE", HUD_OBJECT_CENTER_RETICLE },
115 { "TARGET_MONITOR_EXTRA_DATA", HUD_OBJECT_EXTRA_TARGET_DATA },
116 { "TARGET_SHIELD_ICON", HUD_OBJECT_TARGET_SHIELD },
117 { "PLAYER_SHIELD_ICON", HUD_OBJECT_PLAYER_SHIELD },
118 { "ETS_GAUGE", HUD_OBJECT_ETS_RETAIL },
119 { "AUTO_TARGET", HUD_OBJECT_AUTO_TARGET },
120 { "AUTO_SPEED", HUD_OBJECT_AUTO_SPEED },
121 { "WEAPONS_GAUGE", HUD_OBJECT_WEAPONS },
122 { "ESCORT_VIEW", HUD_OBJECT_ESCORT },
123 { "DIRECTIVES_VIEW", HUD_OBJECT_DIRECTIVES },
124 { "THREAT_GAUGE", HUD_OBJECT_THREAT },
125 { "AFTERBURNER_ENERGY", HUD_OBJECT_AFTERBURNER },
126 { "WEAPONS_ENERGY", HUD_OBJECT_WEAPON_ENERGY },
127 { "WEAPON_LINKING_GAUGE", HUD_OBJECT_WEAPON_LINKING },
128 { "TARGER_MINI_ICON", HUD_OBJECT_MINI_SHIELD },
129 { "OFFSCREEN_INDICATOR", HUD_OBJECT_OFFSCREEN },
130 { "TALKING_HEAD", HUD_OBJECT_TALKING_HEAD },
131 { "DAMAGE_GAUGE", HUD_OBJECT_DAMAGE },
132 { "MESSAGE_LINES", HUD_OBJECT_MESSAGES },
133 { "MISSILE_WARNING_ARROW", HUD_OBJECT_MISSILE_TRI },
134 { "CMEASURE_GAUGE", HUD_OBJECT_CMEASURES },
135 { "OBJECTIVES_NOTIFY_GAUGE", HUD_OBJECT_OBJ_NOTIFY },
136 { "WINGMEN_STATUS", HUD_OBJECT_WINGMAN_STATUS },
137 { "OFFSCREEN RANGE", -1 },
138 { "KILLS GAUGE", HUD_OBJECT_KILLS },
139 { "ATTACKING TARGET COUNT", -1 },
140 { "TEXT FLASH", HUD_OBJECT_TEXT_WARNINGS },
141 { "MESSAGE BOX", HUD_OBJECT_SQUAD_MSG },
142 { "SUPPORT GUAGE", HUD_OBJECT_SUPPORT },
143 { "LAG GUAGE", HUD_OBJECT_LAG },
144 };
145
146 flag_def_list Hud_gauge_types[] = {
147 { "Messages", HUD_OBJECT_MESSAGES, 0},
148 { "Training messages", HUD_OBJECT_TRAINING_MESSAGES, 0}, // Not in legacy list
149 { "Support", HUD_OBJECT_SUPPORT, 0},
150 { "Damage", HUD_OBJECT_DAMAGE, 0},
151 { "Wingman status", HUD_OBJECT_WINGMAN_STATUS, 0},
152 { "Auto speed", HUD_OBJECT_AUTO_SPEED, 0},
153 { "Auto target", HUD_OBJECT_AUTO_TARGET, 0},
154 { "Countermeasures", HUD_OBJECT_CMEASURES, 0},
155 { "Talking head", HUD_OBJECT_TALKING_HEAD, 0},
156 { "Directives", HUD_OBJECT_DIRECTIVES, 0},
157 { "Weapons", HUD_OBJECT_WEAPONS, 0},
158 { "Objective notifier", HUD_OBJECT_OBJ_NOTIFY, 0},
159 { "Comm menu", HUD_OBJECT_SQUAD_MSG, 0},
160 { "Lag indicator", HUD_OBJECT_LAG, 0},
161 { "Mini shield", HUD_OBJECT_MINI_SHIELD, 0},
162 { "Player shield", HUD_OBJECT_PLAYER_SHIELD, 0},
163 { "Target shield", HUD_OBJECT_TARGET_SHIELD, 0},
164 { "Escort list", HUD_OBJECT_ESCORT, 0},
165 { "Mission time", HUD_OBJECT_MISSION_TIME, 0},
166 { "Ets weapons", HUD_OBJECT_ETS_WEAPONS, 0}, // Not in legacy list
167 { "Ets shields", HUD_OBJECT_ETS_SHIELDS, 0}, // Not in legacy list
168 { "Ets engines", HUD_OBJECT_ETS_ENGINES, 0}, // Not in legacy list
169 { "Target monitor", HUD_OBJECT_TARGET_MONITOR, 0},
170 { "Extra target data", HUD_OBJECT_EXTRA_TARGET_DATA, 0},
171 { "Radar", HUD_OBJECT_RADAR_STD, 0},
172 { "Radar orb", HUD_OBJECT_RADAR_ORB, 0}, // Not in legacy list
173 { "Radar BSG", HUD_OBJECT_RADAR_BSG, 0}, // Not in legacy list
174 { "Afterburner energy", HUD_OBJECT_AFTERBURNER, 0},
175 { "Weapon energy", HUD_OBJECT_WEAPON_ENERGY, 0},
176 { "Text warnings", HUD_OBJECT_TEXT_WARNINGS, 0},
177 { "Center reticle", HUD_OBJECT_CENTER_RETICLE, 0},
178 { "Throttle", HUD_OBJECT_THROTTLE, 0},
179 { "Threat indicator", HUD_OBJECT_THREAT, 0},
180 { "Lead indicator", HUD_OBJECT_LEAD, 0},
181 { "Lead sight", HUD_OBJECT_LEAD_SIGHT, 0},
182 { "Lock indicator", HUD_OBJECT_LOCK, 0}, // Not in legacy list
183 { "Weapon linking", HUD_OBJECT_WEAPON_LINKING, 0},
184 { "Multiplayer messages", HUD_OBJECT_MULTI_MSG, 0}, // Not in legacy list
185 { "Voice status", HUD_OBJECT_VOICE_STATUS, 0}, // Not in legacy list
186 { "Ping", HUD_OBJECT_PING, 0}, // Not in legacy list
187 { "Supernova", HUD_OBJECT_SUPERNOVA, 0}, // Not in legacy list
188 { "Offscreen indicator", HUD_OBJECT_OFFSCREEN, 0},
189 { "Targeting brackets", HUD_OBJECT_BRACKETS, 0},
190 { "Orientation", HUD_OBJECT_ORIENTATION_TEE, 0},
191 { "Hostile direction", HUD_OBJECT_HOSTILE_TRI, 0},
192 { "Target direction", HUD_OBJECT_TARGET_TRI, 0},
193 { "Missile indicator", HUD_OBJECT_MISSILE_TRI, 0},
194 { "Kills", HUD_OBJECT_KILLS, 0},
195 { "Fixed messages", HUD_OBJECT_FIXED_MESSAGES, 0}, // Not in legacy list
196 { "Ets retail", HUD_OBJECT_ETS_RETAIL, 0}
197 };
198 int Num_hud_gauge_types = sizeof(Hud_gauge_types)/sizeof(flag_def_list);
199
parse_ship_start()200 int parse_ship_start()
201 {
202 char shipname[NAME_LENGTH];
203 int ship_index;
204
205 stuff_string(shipname, F_NAME, NAME_LENGTH);
206 ship_index = ship_info_lookup(shipname);
207
208 return ship_index;
209 }
210
parse_hud_gauges_tbl(const char * filename)211 void parse_hud_gauges_tbl(const char *filename)
212 {
213 int i;
214 char *saved_Mp = NULL;
215
216 int colors[3] = {255, 255, 255};
217 color hud_color;
218 color ship_color;
219 color *hud_clr_p = NULL;
220 color *ship_clr_p = NULL;
221 bool scale_gauge = true;
222 bool chase_view_only = false;
223
224 try
225 {
226 read_file_text(filename, CF_TYPE_TABLES);
227 reset_parse();
228
229 if (optional_string("$Load Retail Configuration:")) {
230 stuff_boolean(&Hud_retail);
231 }
232
233 if (optional_string("$Color:")) {
234 stuff_int_list(colors, 3);
235
236 check_color(colors);
237 gr_init_alphacolor(&hud_color, colors[0], colors[1], colors[2], 255);
238 hud_clr_p = &hud_color;
239 }
240
241 if (optional_string("$Font:")) {
242 Hud_font = font::parse_font();
243 }
244
245 if (optional_string("$Chase View Only:")) {
246 stuff_boolean(&chase_view_only);
247 Chase_view_only_ex = chase_view_only;
248 }
249
250 if(optional_string("$Max Directives:")) {
251 stuff_int(&Max_directives);
252 }
253
254 if (optional_string("$Max Escort Ships:")) {
255 stuff_int(&Max_escort_ships);
256 }
257
258 if (optional_string("$Length Unit Multiplier:")) {
259 stuff_float(&Hud_unit_multiplier);
260
261 if (Hud_unit_multiplier <= 0.0f) {
262 Warning(LOCATION, "\"$Length Unit Multiplier:\" value of \"%f\" is invalid! Resetting to default.", Hud_unit_multiplier);
263 Hud_unit_multiplier = 1.0f;
264 }
265 }
266
267 if (optional_string("$Speed Unit Multiplier:")) {
268 stuff_float(&Hud_speed_multiplier);
269
270 if (Hud_speed_multiplier <= 0.0f) {
271 Warning(LOCATION, "\"$Speed Unit Multiplier:\" value of \"%f\" is invalid! Resetting to default.", Hud_speed_multiplier);
272 Hud_speed_multiplier = 1.0f;
273 }
274 }
275 else {
276 Hud_speed_multiplier = Hud_unit_multiplier;
277 }
278
279 if (optional_string("$Wireframe Targetbox:")) {
280 stuff_int(&Targetbox_wire);
281 if ((Targetbox_wire < 0) || (Targetbox_wire > 3)) {
282 Targetbox_wire = 0;
283 }
284 }
285
286 if (optional_string("$Targetbox Shader Effect:")) {
287 stuff_int(&Targetbox_shader_effect);
288 if (Targetbox_shader_effect < 0) {
289 Targetbox_shader_effect = 0;
290 }
291 }
292
293 if (optional_string("$Lock Wireframe Mode:")) {
294 stuff_boolean(&Lock_targetbox_mode);
295 }
296
297 if (optional_string("$Scale Gauges:")) {
298 stuff_boolean(&scale_gauge);
299 Scale_retail_gauges = scale_gauge;
300 }
301
302 if (optional_string("$Force Scaling Above:")) {
303 stuff_int_list(Force_scaling_above_res_global, 2);
304 }
305
306 if (optional_string("$Reticle Style:")) {
307 int temp = required_string_either("FS1", "FS2");
308
309 // using require_string_either won't advance the Mp pointer to the next token so force it instead
310 skip_to_start_of_string("#Gauge Config");
311
312 if (temp < 0)
313 Warning(LOCATION, "Undefined reticle style in hud_gauges.tbl!");
314 else
315 Hud_reticle_style = temp;
316 }
317
318 int base_res[2];
319 int force_scaling_above_res[2];
320 int ship_idx = -1;
321 int ship_font = -1;
322 int gauge_type = -1;
323 int use_font = -1;
324 color *use_clr_p = NULL;
325 SCP_vector<int> ship_classes;
326 bool retail_config = false;
327 int n_ships = 0;
328
329 while (optional_string("#Gauge Config")) {
330 ship_classes.clear();
331 switch (optional_string_either("$Ship:", "$Ships:")) {
332 case 0:
333 mprintf(("$Ship in hud_gauges.tbl and -hdg.tbms is deprecated. Use \"$Ships: (\"Some ship class\") instead.\n"));
334
335 if (!Ships_inited) {
336 // just in case ship info has not been initialized.
337 skip_to_start_of_string("#Gauge Config");
338 continue;
339 }
340
341 // get the ship number for this HUD configuration.
342 ship_idx = parse_ship_start();
343 ship_classes.push_back(ship_idx);
344
345 if (ship_idx >= 0) {
346 Ship_info[ship_idx].hud_enabled = true;
347
348 // see if we need to load defaults for this configuration
349 if (optional_string("$Load Retail Configuration:")) {
350 stuff_boolean(&Ship_info[ship_idx].hud_retail);
351 }
352
353 if (optional_string("$Color:")) {
354 stuff_int_list(colors, 3);
355
356 check_color(colors);
357 gr_init_alphacolor(&ship_color, colors[0], colors[1], colors[2], 255);
358 ship_clr_p = &ship_color;
359 }
360
361 if (optional_string("$Font:")) {
362 ship_font = font::parse_font();
363 }
364
365 if (optional_string("$Chase View Only:")) {
366 stuff_boolean(&chase_view_only);
367 }
368 }
369 else {
370 // can't find ship class. move on.
371 ship_classes.push_back(-1);
372 skip_to_start_of_string("#Gauge Config");
373 //skip_to_start_of_string_either("#Gauge Config", "#End");
374 continue;
375 }
376 break;
377 case 1:
378 int shiparray[256];
379
380 n_ships = (int)stuff_int_list(shiparray, 256, SHIP_INFO_TYPE);
381
382 if (optional_string("$Load Retail Configuration:")) {
383 stuff_boolean(&retail_config);
384 }
385
386 for (i = 0; i < n_ships; ++i) {
387 ship_classes.push_back(shiparray[i]);
388 Ship_info[shiparray[i]].hud_enabled = true;
389 Ship_info[shiparray[i]].hud_retail = retail_config;
390 }
391
392 if (optional_string("$Color:")) {
393 stuff_int_list(colors, 3);
394
395 check_color(colors);
396 gr_init_alphacolor(&ship_color, colors[0], colors[1], colors[2], 255);
397 ship_clr_p = &ship_color;
398 }
399
400 if (optional_string("$Font:")) {
401 ship_font = font::parse_font();
402 }
403 if (optional_string("$Chase View Only:")) {
404 stuff_boolean(&chase_view_only);
405 }
406 break;
407 default:
408 // No particular ship. -1 for default HUD configuration.
409 ship_classes.push_back(-1);
410 ship_font = -1;
411 ship_clr_p = NULL;
412 break;
413 }
414
415 if (ship_clr_p != NULL) {
416 use_clr_p = ship_clr_p;
417 }
418 else {
419 use_clr_p = hud_clr_p;
420 }
421
422 if (ship_font >= 0) {
423 use_font = ship_font;
424 }
425 else {
426 use_font = Hud_font;
427 }
428
429 // Now start going through resolution info for this HUD layout
430 required_string("$Base:");
431
432 // get the base width and height describing this HUD
433 stuff_int_list(base_res, 2, RAW_INTEGER_TYPE);
434
435 // gauge scaling for this base res?
436 if (optional_string("$Scale Gauges:")) {
437 stuff_boolean(&scale_gauge);
438 }
439
440 // maximum res at which scaling can be disabled
441 if (optional_string("$Force Scaling Above:")) {
442 stuff_int_list(force_scaling_above_res, 2);
443 } else {
444 memcpy(force_scaling_above_res, Force_scaling_above_res_global, sizeof(force_scaling_above_res));
445 }
446
447 // Pruning time. Let's see if the current resolution defined by the user matches the conditions set by this entry
448 if (optional_string("$Required Aspect:")) {
449 // filter aspect ratio.
450 if (optional_string("Full Screen")) {
451 if( (float)gr_screen.center_w / (float)gr_screen.center_h > 1.5) {
452 skip_to_start_of_string("#Gauge Config");
453 //skip_to_start_of_string_either("#Gauge Config", "#End");
454 continue;
455 }
456 }
457 else if (optional_string("Wide Screen")) {
458 if( (float)gr_screen.center_w / (float)gr_screen.center_h <= 1.5) {
459 skip_to_start_of_string("#Gauge Config");
460 //skip_to_start_of_string_either("#Gauge Config", "#End");
461 continue;
462 }
463 }
464 }
465
466 // check minimum resolution
467 if (optional_string("$Min:")) {
468 int min_res[2];
469 stuff_int_list(min_res, 2, RAW_INTEGER_TYPE);
470
471 if (min_res[0] > gr_screen.max_w) {
472 skip_to_start_of_string("#Gauge Config");
473 continue;
474 }
475 else if (min_res[0] == gr_screen.center_w) {
476 if (min_res[1] > gr_screen.center_h) {
477 skip_to_start_of_string("#Gauge Config");
478 continue;
479 }
480 }
481 }
482
483 // check maximum resolution
484 if (optional_string("$Max:")) {
485 int max_res[2];
486 stuff_int_list(max_res, 2, RAW_INTEGER_TYPE);
487
488 if (max_res[0] < gr_screen.max_w) {
489 skip_to_start_of_string("#Gauge Config");
490 continue;
491 }
492 else if (max_res[0] == gr_screen.center_w) {
493 if (max_res[1] < gr_screen.center_h) {
494 skip_to_start_of_string("#Gauge Config");
495 continue;
496 }
497 }
498 }
499
500 // let's start parsing for gauges.
501 required_string("$Gauges:");
502
503 while ((gauge_type = parse_gauge_type()) >= 0) {
504 // change some of the default gauge settings to the appropriate values.
505 gauge_settings settings;
506 settings.font_num = use_font;
507 settings.scale_gauge = scale_gauge;
508 memcpy(settings.force_scaling_above_res, force_scaling_above_res, sizeof(settings.force_scaling_above_res));
509 settings.ship_idx = &ship_classes;
510 settings.use_clr = use_clr_p;
511 settings.chase_view_only = chase_view_only;
512
513 // if "default" is specified, then the base resolution is {-1, -1},
514 // indicating GR_640 or GR_1024 to the handlers. otherwise, change it
515 // to the given base resolution.
516 if (!optional_string("default")) {
517 memcpy(settings.base_res, base_res, sizeof(settings.base_res));
518 }
519
520 // then call the specific gauge load handler function for this gauge type.
521 load_gauge(gauge_type, &settings);
522
523 if (saved_Mp && (saved_Mp == Mp)) {
524 Mp++;
525 }
526
527 // HACK: The previous code simply skipped invalid entries but now we try to generate a warning for that.
528 // If we don't see either $ or + then it means that there was an invalid token somewhere in between
529 if (!check_for_string("$") && !check_for_string("+")) {
530 error_display(0, "Detected invalid tokens while parsing HUD gauges: [%.32s]", next_tokens());
531 skip_to_start_of_string_either("$", "+");
532 }
533
534 // stolened from AI_profiles
535 // if we've been through once already and are at the same place, force a move
536 saved_Mp = Mp;
537 }
538
539 required_string("$End Gauges");
540 required_string("#End");
541 }
542 }
543 catch (const parse::ParseException& e)
544 {
545 mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what()));
546 return;
547 }
548 }
549
hud_positions_init()550 void hud_positions_init()
551 {
552 if(!Ships_inited)
553 {
554 Error(LOCATION, "Could not initialize hudparse.cpp as ships were not inited first.");
555 return;
556 }
557
558 default_hud_gauges.clear();
559
560 if (cf_exists_full("hud_gauges.tbl", CF_TYPE_TABLES))
561 parse_hud_gauges_tbl("hud_gauges.tbl");
562
563 parse_modular_table(NOX("*-hdg.tbm"), parse_hud_gauges_tbl);
564
565 // load missing retail gauges for the default and ship-specific HUDs
566 load_missing_retail_gauges();
567 }
568
load_missing_retail_gauges()569 void load_missing_retail_gauges()
570 {
571 bool retail_gauge_loaded = false;
572
573 // load missing retail gauges for the retail HUD if needed
574 if(Hud_retail) {
575 int num_loaded_gauges = (int)default_hud_gauges.size();
576
577 for(int i = 0; i < Num_builtin_gauges; i++) {
578 retail_gauge_loaded = false;
579
580 for(int j = 0; j < num_loaded_gauges; j++) {
581 if(Builtin_gauges[i] == default_hud_gauges[j]->getObjectType()) {
582 retail_gauge_loaded = true;
583 break;
584 }
585 }
586
587 if(!retail_gauge_loaded) {
588 gauge_settings settings;
589 load_gauge(Builtin_gauges[i], &settings);
590 }
591 }
592
593 // if we're missing a radar gauge, load either orb or standard
594 retail_gauge_loaded = false;
595 for(int j = 0; j < num_loaded_gauges; j++) {
596 if(HUD_OBJECT_RADAR_STD == default_hud_gauges[j]->getObjectType() ||
597 HUD_OBJECT_RADAR_ORB == default_hud_gauges[j]->getObjectType() ||
598 HUD_OBJECT_RADAR_BSG == default_hud_gauges[j]->getObjectType()) {
599 retail_gauge_loaded = true;
600 }
601 }
602
603 // load radar gauge if not loaded.
604 if(!retail_gauge_loaded) {
605 gauge_settings settings;
606 load_gauge((Cmdline_orb_radar ? HUD_OBJECT_RADAR_ORB : HUD_OBJECT_RADAR_STD), &settings);
607 }
608
609 // Throw in the weapon linking reticle gauge if using FS1 defaults
610 retail_gauge_loaded = false;
611 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
612 for(int j = 0; j < num_loaded_gauges; j++) {
613 if(HUD_OBJECT_WEAPON_LINKING == default_hud_gauges[j]->getObjectType()) {
614 retail_gauge_loaded = true;
615 }
616 }
617
618 if(!retail_gauge_loaded) {
619 gauge_settings settings;
620 load_gauge(HUD_OBJECT_WEAPON_LINKING, &settings);
621 }
622 }
623 }
624
625 // for each ship class, check if their specific HUD config is enabled
626 int k = 0;
627 for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); k++, ++it) {
628 SCP_vector<int> sindex;
629 sindex.push_back(k);
630 if(it->hud_enabled && it->hud_retail) {
631 int num_loaded_gauges = (int)it->hud_gauges.size();
632
633 for(int i = 0; i < Num_builtin_gauges; i++) {
634 for(int j = 0; j < num_loaded_gauges; j++) {
635 if(Builtin_gauges[i] == it->hud_gauges[j]->getObjectType()) {
636 retail_gauge_loaded = true;
637 }
638 }
639
640 if(!retail_gauge_loaded) {
641 gauge_settings settings;
642 settings.ship_idx = &sindex;
643 load_gauge(Builtin_gauges[i], &settings);
644 }
645 }
646
647 // if we're missing a radar gauge, load either orb or standard
648 retail_gauge_loaded = false;
649 for(int j = 0; j < num_loaded_gauges; j++) {
650 if(HUD_OBJECT_RADAR_ORB == it->hud_gauges[j]->getObjectType() ||
651 HUD_OBJECT_RADAR_STD == it->hud_gauges[j]->getObjectType() ||
652 HUD_OBJECT_RADAR_BSG == it->hud_gauges[j]->getObjectType()) {
653 retail_gauge_loaded = true;
654 }
655 }
656
657 // load radar gauge if not loaded.
658 if(!retail_gauge_loaded) {
659 gauge_settings settings;
660 settings.ship_idx = &sindex;
661 load_gauge((Cmdline_orb_radar ? HUD_OBJECT_RADAR_ORB : HUD_OBJECT_RADAR_STD), &settings);
662 }
663
664 // Throw in the weapon linking reticle gauge if using FS1 defaults
665 retail_gauge_loaded = false;
666 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
667 for(int j = 0; j < num_loaded_gauges; j++) {
668 if(HUD_OBJECT_WEAPON_LINKING == it->hud_gauges[j]->getObjectType()) {
669 retail_gauge_loaded = true;
670 }
671 }
672
673 if(!retail_gauge_loaded) {
674 gauge_settings settings;
675 settings.ship_idx = &sindex;
676 load_gauge(HUD_OBJECT_WEAPON_LINKING, &settings);
677 }
678 }
679 }
680 }
681 }
682
683 // Called once after mission load is complete. Sets initial gauge activity states.
init_hud()684 void init_hud() {
685 int config_type;
686 size_t i, num_gauges;
687
688 if(!Ship_info[Player_ship->ship_info_index].hud_gauges.empty()) {
689 num_gauges = Ship_info[Player_ship->ship_info_index].hud_gauges.size();
690
691 for(i = 0; i < num_gauges; i++) {
692 config_type = Ship_info[Player_ship->ship_info_index].hud_gauges[i]->getConfigType();
693
694 if ( !Ship_info[Player_ship->ship_info_index].hud_gauges[i]->isOffbyDefault() && hud_config_show_flag_is_set(config_type) )
695 Ship_info[Player_ship->ship_info_index].hud_gauges[i]->updateActive(true);
696 else
697 Ship_info[Player_ship->ship_info_index].hud_gauges[i]->updateActive(false);
698
699 Ship_info[Player_ship->ship_info_index].hud_gauges[i]->updatePopUp(hud_config_popup_flag_is_set(config_type) ? true : false);
700 Ship_info[Player_ship->ship_info_index].hud_gauges[i]->updateColor(
701 HUD_config.clr[config_type].red,
702 HUD_config.clr[config_type].green,
703 HUD_config.clr[config_type].blue,
704 HUD_config.clr[config_type].alpha
705 );
706 }
707 } else {
708 num_gauges = default_hud_gauges.size();
709
710 for(i = 0; i < num_gauges; i++) {
711 config_type = default_hud_gauges[i]->getConfigType();
712
713 if ( !default_hud_gauges[i]->isOffbyDefault() && hud_config_show_flag_is_set(config_type) )
714 default_hud_gauges[i]->updateActive(true);
715 else
716 default_hud_gauges[i]->updateActive(false);
717
718 default_hud_gauges[i]->updatePopUp(hud_config_popup_flag_is_set(config_type) ? true : false);
719 default_hud_gauges[i]->updateColor(
720 HUD_config.clr[config_type].red,
721 HUD_config.clr[config_type].green,
722 HUD_config.clr[config_type].blue,
723 HUD_config.clr[config_type].alpha
724 );
725 }
726 }
727 }
728
729 extern void hud_init_ballistic_index();
730
set_current_hud()731 void set_current_hud()
732 {
733 int config_type;
734 size_t i, num_gauges;
735
736 // before we load any hud gauges, see whether we're carring a ballistic weapon (Mantis #2962)
737 hud_init_ballistic_index();
738
739 // go through all HUD gauges. Load gauge properties defined in the HUD config if gauge is not customized.
740 if(!Ship_info[Player_ship->ship_info_index].hud_gauges.empty()) {
741 num_gauges = Ship_info[Player_ship->ship_info_index].hud_gauges.size();
742
743 for(i = 0; i < num_gauges; i++) {
744 HudGauge* hgp = Ship_info[Player_ship->ship_info_index].hud_gauges[i].get();
745 config_type = hgp->getConfigType();
746
747 if ( ( (!hgp->isOffbyDefault() || hgp->isActive()) && hud_config_show_flag_is_set(config_type)) )
748 hgp->updateActive(true);
749 else
750 hgp->updateActive(false);
751
752 //hgp->updateActive(hud_config_show_flag_is_set(config_type) ? true : false);
753 hgp->updatePopUp(hud_config_popup_flag_is_set(config_type) ? true : false);
754 hgp->updateColor(
755 HUD_config.clr[config_type].red,
756 HUD_config.clr[config_type].green,
757 HUD_config.clr[config_type].blue,
758 HUD_config.clr[config_type].alpha
759 );
760 }
761 } else {
762 num_gauges = default_hud_gauges.size();
763
764 for(i = 0; i < num_gauges; i++) {
765 config_type = default_hud_gauges[i]->getConfigType();
766
767 if ( ( (!default_hud_gauges[i]->isOffbyDefault() || default_hud_gauges[i]->isActive()) && hud_config_show_flag_is_set(config_type)) )
768 default_hud_gauges[i]->updateActive(true);
769 else
770 default_hud_gauges[i]->updateActive(false);
771
772 //default_hud_gauges[i]->updateActive(hud_config_show_flag_is_set(config_type) ? true : false);
773 default_hud_gauges[i]->updatePopUp(hud_config_popup_flag_is_set(config_type) ? true : false);
774 default_hud_gauges[i]->updateColor(
775 HUD_config.clr[config_type].red,
776 HUD_config.clr[config_type].green,
777 HUD_config.clr[config_type].blue,
778 HUD_config.clr[config_type].alpha
779 );
780 }
781 }
782 }
783
parse_gauge_type()784 int parse_gauge_type()
785 {
786 // probably a more elegant way to do this.
787 // Likely involving a for loop, an array of strings and only one if statement with a strcmp.
788 if(optional_string("+Custom:"))
789 return HUD_OBJECT_CUSTOM;
790
791 if(optional_string("+Messages:"))
792 return HUD_OBJECT_MESSAGES;
793
794 if(optional_string("+Training Messages:"))
795 return HUD_OBJECT_TRAINING_MESSAGES;
796
797 if(optional_string("+Support:"))
798 return HUD_OBJECT_SUPPORT;
799
800 if(optional_string("+Damage:"))
801 return HUD_OBJECT_DAMAGE;
802
803 if(optional_string("+Wingman Status:"))
804 return HUD_OBJECT_WINGMAN_STATUS;
805
806 if(optional_string("+Auto Speed:"))
807 return HUD_OBJECT_AUTO_SPEED;
808
809 if(optional_string("+Auto Target:"))
810 return HUD_OBJECT_AUTO_TARGET;
811
812 if(optional_string("+Countermeasures:"))
813 return HUD_OBJECT_CMEASURES;
814
815 if(optional_string("+Talking Head:"))
816 return HUD_OBJECT_TALKING_HEAD;
817
818 if(optional_string("+Directives:"))
819 return HUD_OBJECT_DIRECTIVES;
820
821 if(optional_string("+Weapons:"))
822 return HUD_OBJECT_WEAPONS;
823
824 if(optional_string("+Objective Notify:"))
825 return HUD_OBJECT_OBJ_NOTIFY;
826
827 if(optional_string("+Squad Message:"))
828 return HUD_OBJECT_SQUAD_MSG;
829
830 if(optional_string("+Lag:"))
831 return HUD_OBJECT_LAG;
832
833 if(optional_string("+Mini Target Shields:"))
834 return HUD_OBJECT_MINI_SHIELD;
835
836 if(optional_string("+Player Shields:"))
837 return HUD_OBJECT_PLAYER_SHIELD;
838
839 if(optional_string("+Target Shields:"))
840 return HUD_OBJECT_TARGET_SHIELD;
841
842 if(optional_string("+Escort View:"))
843 return HUD_OBJECT_ESCORT;
844
845 if(optional_string("+Mission Time:"))
846 return HUD_OBJECT_MISSION_TIME;
847
848 if(optional_string("+ETS Weapons:"))
849 return HUD_OBJECT_ETS_WEAPONS;
850
851 if(optional_string("+ETS Shields:"))
852 return HUD_OBJECT_ETS_SHIELDS;
853
854 if(optional_string("+ETS Engines:"))
855 return HUD_OBJECT_ETS_ENGINES;
856
857 if(optional_string("+ETS Retail:"))
858 return HUD_OBJECT_ETS_RETAIL;
859
860 if(optional_string("+Target Monitor:"))
861 return HUD_OBJECT_TARGET_MONITOR;
862
863 if(optional_string("+Extra Target Data:"))
864 return HUD_OBJECT_EXTRA_TARGET_DATA;
865
866 if(optional_string("+Radar:")) {
867 if(Cmdline_orb_radar) {
868 return HUD_OBJECT_RADAR_ORB;
869 } else {
870 return HUD_OBJECT_RADAR_STD;
871 }
872 }
873
874 if(optional_string("+Radar Orb:"))
875 return HUD_OBJECT_RADAR_ORB;
876
877 if(optional_string("+Radar BSG:"))
878 return HUD_OBJECT_RADAR_BSG;
879
880 if(optional_string("+Afterburner Energy:"))
881 return HUD_OBJECT_AFTERBURNER;
882
883 if(optional_string("+Weapon Energy:"))
884 return HUD_OBJECT_WEAPON_ENERGY;
885
886 if(optional_string("+Text Warnings:"))
887 return HUD_OBJECT_TEXT_WARNINGS;
888
889 if(optional_string("+Center Reticle:"))
890 return HUD_OBJECT_CENTER_RETICLE;
891
892 if(optional_string("+Throttle:"))
893 return HUD_OBJECT_THROTTLE;
894
895 if(optional_string("+Threat Indicator:"))
896 return HUD_OBJECT_THREAT;
897
898 if(optional_string("+Lead Indicator:"))
899 return HUD_OBJECT_LEAD;
900
901 if(optional_string("+Lead Sight:"))
902 return HUD_OBJECT_LEAD_SIGHT;
903
904 if(optional_string("+Lock Indicator:"))
905 return HUD_OBJECT_LOCK;
906
907 if(optional_string("+Weapon Linking:"))
908 return HUD_OBJECT_WEAPON_LINKING;
909
910 if(optional_string("+Multiplayer Messages:"))
911 return HUD_OBJECT_MULTI_MSG;
912
913 if(optional_string("+Voice Status:"))
914 return HUD_OBJECT_VOICE_STATUS;
915
916 if(optional_string("+Ping:"))
917 return HUD_OBJECT_PING;
918
919 if(optional_string("+Supernova:"))
920 return HUD_OBJECT_SUPERNOVA;
921
922 if(optional_string("+Orientation Tee:"))
923 return HUD_OBJECT_ORIENTATION_TEE;
924
925 if(optional_string("+Offscreen Indicator:"))
926 return HUD_OBJECT_OFFSCREEN;
927
928 if(optional_string("+Target Brackets:"))
929 return HUD_OBJECT_BRACKETS;
930
931 if(optional_string("+Hostile Triangle:"))
932 return HUD_OBJECT_HOSTILE_TRI;
933
934 if(optional_string("+Target Triangle:"))
935 return HUD_OBJECT_TARGET_TRI;
936
937 if(optional_string("+Missile Triangles:"))
938 return HUD_OBJECT_MISSILE_TRI;
939
940 if(optional_string("+Kills:"))
941 return HUD_OBJECT_KILLS;
942
943 if(optional_string("+Fixed Messages:"))
944 return HUD_OBJECT_FIXED_MESSAGES;
945
946 if(optional_string("+Flight Path Marker:"))
947 return HUD_OBJECT_FLIGHT_PATH;
948
949 if ( optional_string("+Warhead Count:") )
950 return HUD_OBJECT_WARHEAD_COUNT;
951
952 if ( optional_string("+Hardpoints:") )
953 return HUD_OBJECT_HARDPOINTS;
954
955 if ( optional_string("+Primary Weapons:") )
956 return HUD_OBJECT_PRIMARY_WEAPONS;
957
958 if ( optional_string("+Secondary Weapons:") )
959 return HUD_OBJECT_SECONDARY_WEAPONS;
960
961 if ( optional_string("+Scripted Gauge:") )
962 return HUD_OBJECT_SCRIPTING;
963
964 return -1;
965 }
966
load_gauge(int gauge,gauge_settings * settings)967 void load_gauge(int gauge, gauge_settings* settings)
968 {
969 SCP_vector<int> ship_index;
970 ship_index.push_back(-1);
971 if (settings->ship_idx == NULL) {
972 settings->ship_idx = &ship_index;
973 }
974 switch(gauge) {
975 case HUD_OBJECT_CUSTOM:
976 load_gauge_custom(settings);
977 break;
978 case HUD_OBJECT_MESSAGES:
979 load_gauge_messages(settings);
980 break;
981 case HUD_OBJECT_TRAINING_MESSAGES:
982 load_gauge_training_messages(settings);
983 break;
984 case HUD_OBJECT_SUPPORT:
985 load_gauge_support(settings);
986 break;
987 case HUD_OBJECT_DAMAGE:
988 load_gauge_damage(settings);
989 break;
990 case HUD_OBJECT_WINGMAN_STATUS:
991 load_gauge_wingman_status(settings);
992 break;
993 case HUD_OBJECT_AUTO_SPEED:
994 load_gauge_auto_speed(settings);
995 break;
996 case HUD_OBJECT_AUTO_TARGET:
997 load_gauge_auto_target(settings);
998 break;
999 case HUD_OBJECT_CMEASURES:
1000 load_gauge_countermeasures(settings);
1001 break;
1002 case HUD_OBJECT_TALKING_HEAD:
1003 load_gauge_talking_head(settings);
1004 break;
1005 case HUD_OBJECT_DIRECTIVES:
1006 load_gauge_directives(settings);
1007 break;
1008 case HUD_OBJECT_WEAPONS:
1009 load_gauge_weapons(settings);
1010 break;
1011 case HUD_OBJECT_OBJ_NOTIFY:
1012 load_gauge_objective_notify(settings);
1013 break;
1014 case HUD_OBJECT_SQUAD_MSG:
1015 load_gauge_squad_message(settings);
1016 break;
1017 case HUD_OBJECT_LAG:
1018 load_gauge_lag(settings);
1019 break;
1020 case HUD_OBJECT_MINI_SHIELD:
1021 load_gauge_mini_shields(settings);
1022 break;
1023 case HUD_OBJECT_PLAYER_SHIELD:
1024 load_gauge_player_shields(settings);
1025 break;
1026 case HUD_OBJECT_TARGET_SHIELD:
1027 load_gauge_target_shields(settings);
1028 break;
1029 case HUD_OBJECT_ESCORT:
1030 load_gauge_escort_view(settings);
1031 break;
1032 case HUD_OBJECT_MISSION_TIME:
1033 load_gauge_mission_time(settings);
1034 break;
1035 case HUD_OBJECT_ETS_WEAPONS:
1036 load_gauge_ets_weapons(settings);
1037 break;
1038 case HUD_OBJECT_ETS_SHIELDS:
1039 load_gauge_ets_shields(settings);
1040 break;
1041 case HUD_OBJECT_ETS_ENGINES:
1042 load_gauge_ets_engines(settings);
1043 break;
1044 case HUD_OBJECT_ETS_RETAIL:
1045 load_gauge_ets_retail(settings);
1046 break;
1047 case HUD_OBJECT_TARGET_MONITOR:
1048 load_gauge_target_monitor(settings);
1049 break;
1050 case HUD_OBJECT_EXTRA_TARGET_DATA:
1051 load_gauge_extra_target_data(settings);
1052 break;
1053 case HUD_OBJECT_RADAR_STD:
1054 load_gauge_radar_std(settings);
1055 break;
1056 case HUD_OBJECT_RADAR_ORB:
1057 load_gauge_radar_orb(settings);
1058 break;
1059 case HUD_OBJECT_RADAR_BSG:
1060 load_gauge_radar_dradis(settings);
1061 break;
1062 case HUD_OBJECT_AFTERBURNER:
1063 load_gauge_afterburner(settings);
1064 break;
1065 case HUD_OBJECT_WEAPON_ENERGY:
1066 load_gauge_weapon_energy(settings);
1067 break;
1068 case HUD_OBJECT_TEXT_WARNINGS:
1069 load_gauge_text_warnings(settings);
1070 break;
1071 case HUD_OBJECT_CENTER_RETICLE:
1072 load_gauge_center_reticle(settings);
1073 break;
1074 case HUD_OBJECT_THROTTLE:
1075 load_gauge_throttle(settings);
1076 break;
1077 case HUD_OBJECT_THREAT:
1078 load_gauge_threat_indicator(settings);
1079 break;
1080 case HUD_OBJECT_LEAD:
1081 load_gauge_lead(settings);
1082 break;
1083 case HUD_OBJECT_LEAD_SIGHT:
1084 load_gauge_lead_sight(settings);
1085 break;
1086 case HUD_OBJECT_LOCK:
1087 load_gauge_lock(settings);
1088 break;
1089 case HUD_OBJECT_WEAPON_LINKING:
1090 load_gauge_weapon_linking(settings);
1091 break;
1092 case HUD_OBJECT_MULTI_MSG:
1093 load_gauge_multi_msg(settings);
1094 break;
1095 case HUD_OBJECT_VOICE_STATUS:
1096 load_gauge_voice_status(settings);
1097 break;
1098 case HUD_OBJECT_PING:
1099 load_gauge_ping(settings);
1100 break;
1101 case HUD_OBJECT_SUPERNOVA:
1102 load_gauge_supernova(settings);
1103 break;
1104 case HUD_OBJECT_OFFSCREEN:
1105 load_gauge_offscreen(settings);
1106 break;
1107 case HUD_OBJECT_BRACKETS:
1108 load_gauge_brackets(settings);
1109 break;
1110 case HUD_OBJECT_ORIENTATION_TEE:
1111 load_gauge_orientation_tee(settings);
1112 break;
1113 case HUD_OBJECT_HOSTILE_TRI:
1114 load_gauge_hostile_tri(settings);
1115 break;
1116 case HUD_OBJECT_TARGET_TRI:
1117 load_gauge_target_tri(settings);
1118 break;
1119 case HUD_OBJECT_MISSILE_TRI:
1120 load_gauge_missile_tri(settings);
1121 break;
1122 case HUD_OBJECT_KILLS:
1123 load_gauge_kills(settings);
1124 break;
1125 case HUD_OBJECT_FIXED_MESSAGES:
1126 load_gauge_fixed_messages(settings);
1127 break;
1128 case HUD_OBJECT_FLIGHT_PATH:
1129 load_gauge_flight_path(settings);
1130 break;
1131 case HUD_OBJECT_WARHEAD_COUNT:
1132 load_gauge_warhead_count(settings);
1133 break;
1134 case HUD_OBJECT_HARDPOINTS:
1135 load_gauge_hardpoints(settings);
1136 break;
1137 case HUD_OBJECT_PRIMARY_WEAPONS:
1138 load_gauge_primary_weapons(settings);
1139 break;
1140 case HUD_OBJECT_SECONDARY_WEAPONS:
1141 load_gauge_secondary_weapons(settings);
1142 break;
1143 case HUD_OBJECT_SCRIPTING:
1144 load_gauge_scripting(settings);
1145 break;
1146 default:
1147 // It's either -1, indicating we're ignoring a parse error, or it's a coding error.
1148 Assertion(gauge == -1, "Invalid value '%d' passed to load_gauge(); get a coder!\n", gauge);
1149 break;
1150 }
1151 }
1152
check_base_res(int * res)1153 inline bool check_base_res(int *res)
1154 {
1155 return (res[0] >= 640) && (res[1] >= 480);
1156 }
1157
check_color(int * colorp)1158 void check_color(int *colorp)
1159 {
1160 int i;
1161
1162 for ( i = 0; i < 3; ++i ) {
1163 if ( colorp[i] > 255 ) {
1164 colorp[i] = 255;
1165 } else if ( colorp[i] < 0 ) {
1166 colorp[i] = 0;
1167 }
1168 }
1169 }
1170
adjust_base_res(int * base_res,int * force_scaling_above_res,bool scaling=true)1171 void adjust_base_res(int *base_res, int *force_scaling_above_res, bool scaling = true)
1172 {
1173 // Don't scale gauge if:
1174 // no scaling is set and current res is between base res and "force scaling above res"
1175 // Avoid HUD blurring caused solely by rounding errors
1176 if ((!scaling && gr_screen.center_w >= base_res[0] && gr_screen.center_h >= base_res[1] &&
1177 (force_scaling_above_res[0] <= 0 || force_scaling_above_res[1] <= 0 ||
1178 gr_screen.center_w <= force_scaling_above_res[0] || gr_screen.center_h <= force_scaling_above_res[1])) ||
1179 (gr_screen.center_w >= base_res[0] && gr_screen.center_h == base_res[1]) ||
1180 (gr_screen.center_w == base_res[0] && gr_screen.center_h >= base_res[1])) {
1181 base_res[0] = gr_screen.center_w;
1182 base_res[1] = gr_screen.center_h;
1183 return;
1184 }
1185
1186 if (!scaling && force_scaling_above_res[0] > base_res[0] && force_scaling_above_res[1] > base_res[1] &&
1187 gr_screen.center_w > force_scaling_above_res[0] && gr_screen.center_h > force_scaling_above_res[1]) {
1188 base_res[0] = force_scaling_above_res[0];
1189 base_res[1] = force_scaling_above_res[1];
1190 }
1191
1192 float aspect_quotient = ((float)gr_screen.center_w / (float)gr_screen.center_h) / ((float)base_res[0] / (float)base_res[1]);
1193 if (aspect_quotient >= 1.0) {
1194 base_res[0] = (int)(base_res[0] * aspect_quotient);
1195 } else {
1196 base_res[1] = (int)(base_res[1] / aspect_quotient);
1197 }
1198 }
1199
adjust_for_multimonitor(int * base_res,bool set_position,int * coords)1200 void adjust_for_multimonitor(int *base_res, bool set_position, int *coords)
1201 {
1202 float scale_w = (float)gr_screen.center_w / (float)base_res[0];
1203 float scale_h = (float)gr_screen.center_h / (float)base_res[1];
1204
1205 base_res[0] = fl2ir(base_res[0] * ((float)gr_screen.max_w / (float)gr_screen.center_w));
1206 base_res[1] = fl2ir(base_res[1] * ((float)gr_screen.max_h / (float)gr_screen.center_h));
1207
1208 if (set_position) {
1209 coords[0] += fl2ir(gr_screen.center_offset_x / scale_w);
1210 coords[1] += fl2ir(gr_screen.center_offset_y / scale_h);
1211 }
1212 }
1213
1214 template<class T>
gauge_load_common(gauge_settings * settings,T * preAllocated=NULL)1215 std::unique_ptr<T> gauge_load_common(gauge_settings* settings, T* preAllocated = NULL)
1216 {
1217 int colors[3] = {255, 255, 255};
1218 bool lock_color = false;
1219
1220 // render to texture parameters
1221 char display_name[MAX_FILENAME_LEN] = "";
1222 int display_size[2] = {0, 0};
1223 int display_offset[2] = {0, 0};
1224 int canvas_size[2] = {0, 0};
1225
1226 if(check_base_res(settings->base_res)) {
1227 if (settings->set_position) {
1228 if(optional_string("Position:")) {
1229 stuff_int_list(settings->coords, 2);
1230 settings->use_coords = true;
1231 } else {
1232 if(optional_string("Scale Gauge:")) {
1233 stuff_boolean(&settings->scale_gauge);;
1234 }
1235
1236 if(optional_string("Force Scaling Above:")) {
1237 stuff_int_list(settings->force_scaling_above_res, 2);
1238 }
1239
1240 adjust_base_res(settings->base_res, settings->force_scaling_above_res, settings->scale_gauge);
1241
1242 // If no positioning information is specified, use the default position
1243 bool use_default_pos = true;
1244
1245 if(optional_string("Origin:")) {
1246 stuff_float_list(settings->origin, 2);
1247 use_default_pos = false;
1248
1249 required_string("Offset:");
1250 stuff_int_list(settings->offset, 2);
1251 }
1252
1253 if(optional_string("Offset:")) {
1254 Error(LOCATION, "HUD gauges table: Offset must also have Origin defined");
1255 }
1256
1257 if ( !(settings->use_coords && use_default_pos) ) {
1258 settings->coords[0] = (int)(settings->base_res[0] * settings->origin[0]) + settings->offset[0];
1259 settings->coords[1] = (int)(settings->base_res[1] * settings->origin[1]) + settings->offset[1];
1260 settings->use_coords = true;
1261 }
1262 }
1263 } else {
1264 adjust_base_res(settings->base_res, settings->force_scaling_above_res, settings->scale_gauge);
1265 }
1266 } else {
1267 if(gr_screen.res == GR_640) {
1268 settings->base_res[0] = 640;
1269 settings->base_res[1] = 480;
1270 } else {
1271 settings->base_res[0] = 1024;
1272 settings->base_res[1] = 768;
1273 }
1274
1275 adjust_base_res(settings->base_res, settings->force_scaling_above_res, settings->scale_gauge);
1276
1277 if (settings->set_position && !settings->use_coords) {
1278 settings->coords[0] = (int)(settings->base_res[0] * settings->origin[0]) + settings->offset[0];
1279 settings->coords[1] = (int)(settings->base_res[1] * settings->origin[1]) + settings->offset[1];
1280 settings->use_coords = true;
1281 }
1282 }
1283
1284 if (settings->set_position) {
1285 if ( optional_string("Cockpit Target:") && settings->ship_idx->at(0) >= 0 ) {
1286 stuff_string(display_name, F_NAME, MAX_FILENAME_LEN);
1287
1288 if ( optional_string("Canvas Size:") ) {
1289 stuff_int_list(canvas_size, 2);
1290 }
1291
1292 if ( optional_string("Display Offset:") ) {
1293 stuff_int_list(display_offset, 2);
1294 }
1295
1296 required_string("Display Size:");
1297 stuff_int_list(display_size, 2);
1298 } else {
1299 // adjust for multimonitor setups ONLY if not rendering gauge to a texture
1300 adjust_for_multimonitor(settings->base_res, true, settings->coords);
1301 }
1302 } else {
1303 adjust_for_multimonitor(settings->base_res, true, settings->coords);
1304 }
1305
1306 if (settings->set_colour) {
1307 if ( settings->use_clr != NULL ) {
1308 colors[0] = settings->use_clr->red;
1309 colors[1] = settings->use_clr->green;
1310 colors[2] = settings->use_clr->blue;
1311
1312 lock_color = true;
1313 } else if ( optional_string("Color:") ) {
1314 stuff_int_list(colors, 3);
1315
1316 check_color(colors);
1317
1318 lock_color = true;
1319 }
1320 }
1321
1322 if (optional_string("Font:")) {
1323 settings->font_num = font::parse_font();
1324 } else {
1325 if ( settings->font_num < 0 ) {
1326 settings->font_num = font::FONT1;
1327 }
1328 }
1329
1330 if (optional_string("Chase View Only:")) {
1331 stuff_boolean(&settings->chase_view_only);
1332 }
1333
1334 if (settings->set_position) {
1335 if(optional_string("Slew:")) {
1336 stuff_boolean(&settings->slew);
1337 }
1338 }
1339
1340 std::unique_ptr<T> instance(preAllocated);
1341
1342 if (instance == NULL)
1343 {
1344 instance.reset(new T());
1345 }
1346
1347 instance->initBaseResolution(settings->base_res[0], settings->base_res[1]);
1348 instance->initFont(settings->font_num);
1349 instance->initChase_view_only(settings->chase_view_only);
1350 if (settings->set_position) {
1351 instance->initPosition(settings->coords[0], settings->coords[1]);
1352 instance->initSlew(settings->slew);
1353 instance->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
1354 }
1355 if (settings->set_colour) {
1356 instance->updateColor(colors[0], colors[1], colors[2]);
1357 instance->lockConfigColor(lock_color);
1358 }
1359
1360 return instance;
1361 }
1362
1363 template<typename T>
gauge_assign_common(const gauge_settings * settings,std::unique_ptr<T> && hud_gauge)1364 void gauge_assign_common(const gauge_settings* settings, std::unique_ptr<T>&& hud_gauge) {
1365 if(settings->ship_idx->at(0) >= 0) {
1366 for (auto ship_index = settings->ship_idx->begin(); ship_index != settings->ship_idx->end(); ++ship_index) {
1367 std::unique_ptr<T> instance(new T());
1368 *instance = *hud_gauge;
1369 Ship_info[*ship_index].hud_gauges.push_back(move(instance));
1370 }
1371 // Previous instance goes out of scope here and is destructed
1372 } else {
1373 default_hud_gauges.push_back(move(hud_gauge));
1374 }
1375 }
1376
load_gauge_custom(gauge_settings * settings)1377 void load_gauge_custom(gauge_settings* settings)
1378 {
1379 int i;
1380 char gauge_string[MAX_FILENAME_LEN];
1381 char name[MAX_FILENAME_LEN];
1382 char text[MAX_FILENAME_LEN];
1383 char filename[MAX_FILENAME_LEN];
1384 int gauge_type = HUD_CENTER_RETICLE;
1385 bool active_by_default = true;
1386 int txtoffset_x = 0, txtoffset_y = 0;
1387 ubyte r = 255, g = 255, b = 255;
1388 int colors[3] = {255, 255, 255};
1389 bool lock_color = false;
1390
1391 // render to texture parameters
1392 char display_name[MAX_FILENAME_LEN] = "";
1393 int display_size[2] = {0, 0};
1394 int display_offset[2] = {0, 0};
1395 int canvas_size[2] = {0, 0};
1396
1397 if(check_base_res(settings->base_res)) {
1398 if(optional_string("Position:")) {
1399 stuff_int_list(settings->coords, 2);
1400 settings->use_coords = true;
1401 } else {
1402 if(optional_string("Scale Gauge:")) {
1403 stuff_boolean(&settings->scale_gauge);;
1404 }
1405
1406 if(optional_string("Force Scaling Above:")) {
1407 stuff_int_list(settings->force_scaling_above_res, 2);
1408 }
1409
1410 adjust_base_res(settings->base_res, settings->force_scaling_above_res, settings->scale_gauge);
1411
1412 // If no positioning information is specified, use the default position
1413 bool use_default_pos = true;
1414
1415 if(optional_string("Origin:")) {
1416 stuff_float_list(settings->origin, 2);
1417 use_default_pos = false;
1418
1419 required_string("Offset:");
1420 stuff_int_list(settings->offset, 2);
1421 }
1422
1423 if(optional_string("Offset:")) {
1424 Error(LOCATION, "HUD gauges table: Offset must also have Origin defined");
1425 }
1426
1427 if (!use_default_pos) {
1428 settings->coords[0] = (int)(settings->base_res[0] * settings->origin[0]) + settings->offset[0];
1429 settings->coords[1] = (int)(settings->base_res[1] * settings->origin[1]) + settings->offset[1];
1430 settings->use_coords = true;
1431 }
1432 }
1433
1434 if ( optional_string("Cockpit Target:") && settings->ship_idx->at(0) >= 0 ) {
1435 stuff_string(display_name, F_NAME, MAX_FILENAME_LEN);
1436
1437 if ( optional_string("Canvas Size:") ) {
1438 stuff_int_list(canvas_size, 2);
1439 }
1440
1441 if ( optional_string("Display Offset:") ) {
1442 stuff_int_list(display_offset, 2);
1443 }
1444
1445 required_string("Display Size:");
1446 stuff_int_list(display_size, 2);
1447 } else {
1448 // adjust for multimonitor setups ONLY if not rendering gauge to a texture
1449 adjust_for_multimonitor(settings->base_res, true, settings->coords);
1450 }
1451
1452 if ( settings->use_clr != NULL ) {
1453 colors[0] = settings->use_clr->red;
1454 colors[1] = settings->use_clr->green;
1455 colors[2] = settings->use_clr->blue;
1456
1457 lock_color = true;
1458 } else if ( optional_string("Color:") ) {
1459 stuff_int_list(colors, 3);
1460
1461 check_color(colors);
1462
1463 lock_color = true;
1464 }
1465
1466 if (optional_string("Font:")) {
1467 settings->font_num = font::parse_font();
1468 } else {
1469 if ( settings->font_num < 0 ) {
1470 settings->font_num = font::FONT1;
1471 }
1472 }
1473
1474 if (optional_string("Chase View Only:")) {
1475 stuff_boolean(&settings->chase_view_only);
1476 }
1477
1478 required_string("Name:");
1479 stuff_string(name, F_NAME, MAX_FILENAME_LEN);
1480
1481 required_string("Text:");
1482 stuff_string(text, F_NAME, MAX_FILENAME_LEN);
1483
1484 if (optional_string("X Offset:")) {
1485 stuff_int(&txtoffset_x);
1486 }
1487
1488 if (optional_string("Y Offset:")) {
1489 stuff_int(&txtoffset_y);
1490 }
1491
1492 required_string("Gauge Type:");
1493 stuff_string(gauge_string, F_NAME, MAX_FILENAME_LEN);
1494
1495 for(i = 0; i < NUM_HUD_GAUGES; i++) {
1496 if(!strcmp(Legacy_HUD_gauges[i].hud_gauge_text, gauge_string)) {
1497 gauge_type = i;
1498 break;
1499 }
1500 }
1501
1502 if(optional_string("Slew:")) {
1503 stuff_boolean(&settings->slew);
1504 }
1505
1506 if(optional_string("Active by default:")) {
1507 stuff_boolean(&active_by_default);
1508 }
1509
1510 required_string("Filename:");
1511 stuff_string(filename, F_NAME, MAX_FILENAME_LEN);
1512 } else {
1513 settings->base_res[0] = 640;
1514 settings->base_res[1] = 480;
1515
1516 if ( settings->font_num < 0 ) {
1517 settings->font_num = font::FONT1;
1518 }
1519 }
1520
1521 std::unique_ptr<HudGauge> hud_gauge(new HudGauge(gauge_type, settings->slew, r, g, b, name, text, filename, txtoffset_x, txtoffset_y));
1522 hud_gauge->initBaseResolution(settings->base_res[0], settings->base_res[1]);
1523 hud_gauge->initPosition(settings->coords[0], settings->coords[1]);
1524 hud_gauge->initFont(settings->font_num);
1525 hud_gauge->initRenderStatus(active_by_default);
1526 hud_gauge->updateColor(colors[0], colors[1], colors[2]);
1527 hud_gauge->lockConfigColor(lock_color);
1528 hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
1529 hud_gauge->initChase_view_only(settings->chase_view_only);
1530
1531 gauge_assign_common(settings, std::move(hud_gauge));
1532 }
1533
load_gauge_lag(gauge_settings * settings)1534 void load_gauge_lag(gauge_settings* settings)
1535 {
1536 char fname[MAX_FILENAME_LEN] = "netlag1";
1537
1538 settings->origin[0] = 0.5f;
1539 settings->origin[1] = 0.5f;
1540
1541 if(gr_screen.res == GR_640) {
1542 settings->offset[0] = 66;
1543 settings->offset[1] = 91;
1544 } else {
1545 settings->offset[0] = 115;
1546 settings->offset[1] = 145;
1547 }
1548
1549 auto hud_gauge = gauge_load_common<HudGaugeLag>(settings);
1550
1551 if(optional_string("Filename:")) {
1552 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
1553 }
1554
1555 hud_gauge->initBitmaps(fname);
1556
1557 gauge_assign_common(settings, std::move(hud_gauge));
1558 }
load_gauge_mini_shields(gauge_settings * settings)1559 void load_gauge_mini_shields(gauge_settings* settings)
1560 {
1561 int Mini_3digit_offsets[2];
1562 int Mini_1digit_offsets[2];
1563 int Mini_2digit_offsets[2];
1564 char fname[MAX_FILENAME_LEN] = "targhit1";
1565
1566 settings->origin[0] = 0.5f;
1567 settings->origin[1] = 0.5f;
1568 settings->slew = true;
1569
1570 if(gr_screen.res == GR_640) {
1571 settings->offset[0] = -15;
1572 settings->offset[1] = 51;
1573
1574 Mini_3digit_offsets[0] = 5;
1575 Mini_3digit_offsets[1] = 7;
1576 Mini_1digit_offsets[0] = 11;
1577 Mini_1digit_offsets[1] = 7;
1578 Mini_2digit_offsets[0] = 8;
1579 Mini_2digit_offsets[1] = 7;
1580 } else {
1581 settings->offset[0] = -15;
1582 settings->offset[1] = 86;
1583
1584 Mini_3digit_offsets[0] = 5;
1585 Mini_3digit_offsets[1] = 7;
1586 Mini_1digit_offsets[0] = 14;
1587 Mini_1digit_offsets[1] = 7;
1588 Mini_2digit_offsets[0] = 9;
1589 Mini_2digit_offsets[1] = 7;
1590 }
1591
1592 auto hud_gauge = gauge_load_common<HudGaugeShieldMini>(settings);
1593
1594 if(optional_string("Filename:")) {
1595 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
1596 }
1597 if(optional_string("3 Digit Hull Offsets:")) {
1598 stuff_int_list(Mini_3digit_offsets, 2);
1599 }
1600 if(optional_string("2 Digit Hull Offsets:")) {
1601 stuff_int_list(Mini_2digit_offsets, 2);
1602 }
1603 if(optional_string("1 Digit Hull Offsets:")) {
1604 stuff_int_list(Mini_1digit_offsets, 2);
1605 }
1606
1607 hud_gauge->init1DigitOffsets(Mini_1digit_offsets[0], Mini_1digit_offsets[1]);
1608 hud_gauge->init2DigitOffsets(Mini_2digit_offsets[0], Mini_2digit_offsets[1]);
1609 hud_gauge->init3DigitOffsets(Mini_3digit_offsets[0], Mini_3digit_offsets[1]);
1610 hud_gauge->initBitmaps(fname);
1611
1612 gauge_assign_common(settings, std::move(hud_gauge));
1613 }
1614
load_gauge_weapon_energy(gauge_settings * settings)1615 void load_gauge_weapon_energy(gauge_settings* settings)
1616 {
1617 int Wenergy_text_offsets[2];
1618 int Wenergy_h;
1619 HudAlignment text_alignment = HudAlignment::NONE;
1620 bool always_show_text = false;
1621 bool show_ballistic = false;
1622 bool moving_text = false;
1623 int armed_weapon_offsets[2] = {0, 0};
1624 int armed_weapon_h = 12;
1625 HudAlignment weapon_alignment = HudAlignment::NONE;
1626 bool show_weapons = false;
1627 char fname[MAX_FILENAME_LEN];
1628
1629 settings->origin[0] = 0.5f;
1630 settings->origin[1] = 0.5f;
1631 settings->slew = true;
1632
1633 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
1634 if(gr_screen.res == GR_640) {
1635 strcpy_s(fname, "energy2_fs1");
1636 } else {
1637 strcpy_s(fname, "2_energy2_fs1");
1638 }
1639 } else {
1640 if(gr_screen.res == GR_640) {
1641 strcpy_s(fname, "energy2");
1642 } else {
1643 strcpy_s(fname, "2_energy2");
1644 }
1645 }
1646
1647 if(gr_screen.res == GR_640) {
1648 settings->offset[0] = 96;
1649 settings->offset[1] = 25;
1650
1651 Wenergy_text_offsets[0] = 23;
1652 Wenergy_text_offsets[1] = 53;
1653
1654 Wenergy_h = 60;
1655 } else {
1656 settings->offset[0] = 154;
1657 settings->offset[1] = 40;
1658
1659 Wenergy_text_offsets[0] = 43;
1660 Wenergy_text_offsets[1] = 85;
1661
1662 Wenergy_h = 96;
1663 }
1664
1665 auto hud_gauge = gauge_load_common<HudGaugeWeaponEnergy>(settings);
1666
1667 if(optional_string("Filename:")) {
1668 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
1669 }
1670 if(optional_string("Foreground Clip Height:")) {
1671 stuff_int(&Wenergy_h);
1672 }
1673 if(optional_string("Text Offsets:")) {
1674 stuff_int_list(Wenergy_text_offsets, 2);
1675
1676 if(optional_string("Text Alignment:")) {
1677 char temp[NAME_LENGTH];
1678 stuff_string(temp, F_NAME, NAME_LENGTH);
1679 text_alignment = hud_alignment_lookup(temp);
1680 }
1681 }
1682 if(optional_string("Always Show Text:")) {
1683 stuff_boolean(&always_show_text);
1684 }
1685 if(optional_string("Text Follows:")) {
1686 stuff_boolean(&moving_text);
1687 }
1688 if(optional_string("Show Ballistic Ammo:")) {
1689 stuff_boolean(&show_ballistic);
1690 }
1691 if(optional_string("Armed Guns List Offsets:")) {
1692 stuff_int_list(armed_weapon_offsets, 2);
1693 show_weapons = true;
1694
1695 if(optional_string("Armed Guns List Alignment:")) {
1696 char temp[NAME_LENGTH];
1697 stuff_string(temp, F_NAME, NAME_LENGTH);
1698 weapon_alignment = hud_alignment_lookup(temp);
1699 }
1700
1701 if(optional_string("Armed Guns List Entry Height:")) {
1702 stuff_int(&armed_weapon_h);
1703 }
1704 }
1705
1706 hud_gauge->initBitmaps(fname);
1707 hud_gauge->initEnergyHeight(Wenergy_h);
1708 hud_gauge->initTextOffsets(Wenergy_text_offsets[0], Wenergy_text_offsets[1]);
1709 hud_gauge->initAlignments(text_alignment, weapon_alignment);
1710 hud_gauge->initAlwaysShowText(always_show_text);
1711 hud_gauge->initMoveText(moving_text);
1712 hud_gauge->initShowBallistics(show_ballistic);
1713 hud_gauge->initArmedOffsets(armed_weapon_offsets[0], armed_weapon_offsets[1], armed_weapon_h, show_weapons);
1714
1715 gauge_assign_common(settings, std::move(hud_gauge));
1716 }
1717
load_gauge_target_shields(gauge_settings * settings)1718 void load_gauge_target_shields(gauge_settings* settings)
1719 {
1720 settings->origin[0] = 0.5f;
1721 settings->origin[1] = 1.0f;
1722
1723 if(gr_screen.res == GR_640) {
1724 settings->offset[0] = -178;
1725 settings->offset[1] = -101;
1726 } else {
1727 settings->offset[0] = -220;
1728 settings->offset[1] = -98;
1729 }
1730
1731 auto hud_gauge = gauge_load_common<HudGaugeShieldTarget>(settings);
1732
1733 gauge_assign_common(settings, std::move(hud_gauge));
1734 }
1735
load_gauge_player_shields(gauge_settings * settings)1736 void load_gauge_player_shields(gauge_settings* settings)
1737 {
1738 settings->origin[0] = 0.5f;
1739 settings->origin[1] = 1.0f;
1740
1741 if(gr_screen.res == GR_640) {
1742 settings->offset[0] = 76;
1743 settings->offset[1] = -101;
1744 } else {
1745 settings->offset[0] = 122;
1746 settings->offset[1] = -98;
1747 }
1748
1749 auto hud_gauge = gauge_load_common<HudGaugeShieldPlayer>(settings);
1750
1751 gauge_assign_common(settings, std::move(hud_gauge));
1752 }
1753
load_gauge_escort_view(gauge_settings * settings)1754 void load_gauge_escort_view(gauge_settings* settings)
1755 {
1756 int header_text_offsets[2];
1757 int list_start_offsets[2];
1758 int entry_h;
1759 int entry_stagger_w;
1760 int bottom_bg_offset = 0;
1761 int ship_name_offsets[2];
1762 int ship_name_max_w = 100;
1763 int ship_integrity_offsets[2];
1764 int ship_status_offsets[2];
1765 bool right_align_names = false;
1766 char header_text[MAX_FILENAME_LEN] = "";
1767 char fname_top[MAX_FILENAME_LEN] = "escort1";
1768 char fname_middle[MAX_FILENAME_LEN] = "escort2";
1769 char fname_bottom[MAX_FILENAME_LEN] = "escort3";
1770
1771 settings->origin[0] = 1.0f;
1772 settings->origin[1] = 0.5f;
1773
1774 if(gr_screen.res == GR_640) {
1775 settings->offset[0] = -154;
1776 settings->offset[1] = -40;
1777
1778 header_text_offsets[0] = 3;
1779 header_text_offsets[1] = 2;
1780 list_start_offsets[0] = 0;
1781 list_start_offsets[1] = 13;
1782 entry_h = 11;
1783 entry_stagger_w = 0;
1784 ship_name_offsets[0] = 3;
1785 ship_name_offsets[1] = 0;
1786 ship_integrity_offsets[0] = 118;
1787 ship_integrity_offsets[1] = 0;
1788 ship_status_offsets[0] = -12;
1789 ship_status_offsets[1] = 0;
1790 } else {
1791 settings->offset[0] = -159;
1792 settings->offset[1] = -54;
1793
1794 header_text_offsets[0] = 3;
1795 header_text_offsets[1] = 2;
1796 list_start_offsets[0] = 0;
1797 list_start_offsets[1] = 13;
1798 entry_h = 11;
1799 entry_stagger_w = 0;
1800 ship_name_offsets[0] = 4;
1801 ship_name_offsets[1] = 0;
1802 ship_integrity_offsets[0] = 116;
1803 ship_integrity_offsets[1] = 0;
1804 ship_status_offsets[0] = -11;
1805 ship_status_offsets[1] = 0;
1806 }
1807
1808 auto hud_gauge = gauge_load_common<HudGaugeEscort>(settings);
1809
1810 if(optional_string("Top Background Filename:")) {
1811 stuff_string(fname_top, F_NAME, MAX_FILENAME_LEN);
1812 }
1813 if(optional_string("Entry Background Filename:")) {
1814 stuff_string(fname_middle, F_NAME, MAX_FILENAME_LEN);
1815 }
1816 if(optional_string("Bottom Background Filename:")) {
1817 stuff_string(fname_bottom, F_NAME, MAX_FILENAME_LEN);
1818 }
1819 if(optional_string("Entry Height:")) {
1820 stuff_int(&entry_h);
1821 }
1822 if(optional_string("Entry Stagger Width:")) {
1823 stuff_int(&entry_stagger_w);
1824 }
1825 if(optional_string("Bottom Background Offset:")) {
1826 stuff_int(&bottom_bg_offset);
1827 }
1828 if(optional_string("Header Text:")) {
1829 stuff_string(header_text, F_NAME, MAX_FILENAME_LEN);
1830 }
1831 if(optional_string("Header Offsets:")) {
1832 stuff_int_list(header_text_offsets, 2);
1833 }
1834 if(optional_string("List Start Offsets:")) {
1835 stuff_int_list(list_start_offsets, 2);
1836 }
1837 if(optional_string("Hull X-offset:")) {
1838 stuff_int(&ship_integrity_offsets[0]);
1839 }
1840 if(optional_string("Name X-offset:")) {
1841 stuff_int(&ship_name_offsets[0]);
1842 }
1843 if(optional_string("Status X-offset:")) {
1844 stuff_int(&ship_status_offsets[0]);
1845 }
1846
1847 if ( optional_string("Ship Name Max Width:") ) {
1848 stuff_int(&ship_name_max_w);
1849 }
1850
1851 if ( optional_string("Right-Align Ship Names:") ) {
1852 stuff_boolean(&right_align_names);
1853 }
1854
1855 if (header_text[0] == '\0') {
1856 strcpy_s(header_text, XSTR("monitoring", 285));
1857 }
1858
1859 hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
1860 hud_gauge->initEntryHeight(entry_h);
1861 hud_gauge->initEntryStaggerWidth(entry_stagger_w);
1862 hud_gauge->initBottomBgOffset(bottom_bg_offset);
1863 hud_gauge->initHeaderText(header_text);
1864 hud_gauge->initHeaderTextOffsets(header_text_offsets[0], header_text_offsets[1]);
1865 hud_gauge->initListStartOffsets(list_start_offsets[0], list_start_offsets[1]);
1866 hud_gauge->initShipIntegrityOffsets(ship_integrity_offsets[0], ship_integrity_offsets[1]);
1867 hud_gauge->initShipNameOffsets(ship_name_offsets[0], ship_name_offsets[1]);
1868 hud_gauge->initShipStatusOffsets(ship_status_offsets[0], ship_status_offsets[1]);
1869 hud_gauge->initShipNameMaxWidth(ship_name_max_w);
1870 hud_gauge->initRightAlignNames(right_align_names);
1871
1872 gauge_assign_common(settings, std::move(hud_gauge));
1873 }
1874
load_gauge_afterburner(gauge_settings * settings)1875 void load_gauge_afterburner(gauge_settings* settings)
1876 {
1877 int energy_h;
1878 char fname[MAX_FILENAME_LEN];
1879
1880 settings->origin[0] = 0.5f;
1881 settings->origin[1] = 0.5f;
1882 settings->slew = true;
1883
1884 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
1885 if(gr_screen.res == GR_640) {
1886 strcpy_s(fname, "energy2_fs1");
1887 } else {
1888 strcpy_s(fname, "2_energy2_fs1");
1889 }
1890 } else {
1891 if(gr_screen.res == GR_640) {
1892 strcpy_s(fname, "energy2");
1893 } else {
1894 strcpy_s(fname, "2_energy2");
1895 }
1896 }
1897
1898 if(gr_screen.res == GR_640) {
1899 settings->offset[0] = -149;
1900 settings->offset[1] = 25;
1901
1902 energy_h = 60;
1903 } else {
1904 settings->offset[0] = -238;
1905 settings->offset[1] = 40;
1906
1907 energy_h = 96;
1908 }
1909
1910 auto hud_gauge = gauge_load_common<HudGaugeAfterburner>(settings);
1911
1912 if(optional_string("Filename:")) {
1913 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
1914 }
1915 if(optional_string("Foreground Clip Height:")) {
1916 stuff_int(&energy_h);
1917 }
1918
1919 hud_gauge->initEnergyHeight(energy_h);
1920 hud_gauge->initBitmaps(fname);
1921
1922 gauge_assign_common(settings, std::move(hud_gauge));
1923 }
1924
1925
load_gauge_mission_time(gauge_settings * settings)1926 void load_gauge_mission_time(gauge_settings* settings)
1927 {
1928 int time_text_offsets[2];
1929 int time_val_offsets[2];
1930 char fname[MAX_FILENAME_LEN] = "time1";
1931
1932 settings->origin[0] = 1.0f;
1933 settings->origin[1] = 1.0f;
1934
1935 if(gr_screen.res == GR_640) {
1936 settings->offset[0] = -53;
1937 settings->offset[1] = -32;
1938 } else {
1939 settings->offset[0] = -55;
1940 settings->offset[1] = -52;
1941 }
1942 time_text_offsets[0] = 4;
1943 time_text_offsets[1] = 4;
1944
1945 time_val_offsets[0] = 26;
1946 time_val_offsets[1] = 12;
1947
1948 auto hud_gauge = gauge_load_common<HudGaugeMissionTime>(settings);
1949
1950 if(optional_string("Filename:")) {
1951 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
1952 }
1953 if(optional_string("Text Offsets:")) {
1954 stuff_int_list(time_text_offsets, 2);
1955 }
1956 if(optional_string("Value Offsets:")) {
1957 stuff_int_list(time_val_offsets, 2);
1958 }
1959
1960 hud_gauge->initTextOffsets(time_text_offsets[0], time_text_offsets[1]);
1961 hud_gauge->initValueOffsets(time_val_offsets[0], time_val_offsets[1]);
1962 hud_gauge->initBitmaps(fname);
1963
1964 gauge_assign_common(settings, std::move(hud_gauge));
1965 }
1966
load_gauge_threat_indicator(gauge_settings * settings)1967 void load_gauge_threat_indicator(gauge_settings* settings)
1968 {
1969 int Laser_warn_offsets[2];
1970 int Lock_warn_offsets[2];
1971 char fname_arc[MAX_FILENAME_LEN];
1972 char fname_laser[MAX_FILENAME_LEN];
1973 char fname_lock[MAX_FILENAME_LEN];
1974
1975 settings->origin[0] = 0.5f;
1976 settings->origin[1] = 0.5f;
1977 settings->slew = true;
1978
1979 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
1980 if(gr_screen.res == GR_640) {
1981 settings->offset[0] = -79;
1982 settings->offset[1] = -103;
1983
1984 Laser_warn_offsets[0] = 59;
1985 Laser_warn_offsets[1] = 0;
1986
1987 Lock_warn_offsets[0] = 79;
1988 Lock_warn_offsets[1] = 0;
1989
1990 strcpy_s(fname_arc, "toparc1_fs1");
1991 strcpy_s(fname_laser, "toparc2_fs1");
1992 strcpy_s(fname_lock, "toparc3_fs1");
1993 } else {
1994 settings->offset[0] = -126;
1995 settings->offset[1] = -165;
1996
1997 Laser_warn_offsets[0] = 94;
1998 Laser_warn_offsets[1] = 0;
1999
2000 Lock_warn_offsets[0] = 126;
2001 Lock_warn_offsets[1] = 0;
2002
2003 strcpy_s(fname_arc, "2_toparc1_fs1");
2004 strcpy_s(fname_laser, "2_toparc2_fs1");
2005 strcpy_s(fname_lock, "2_toparc3_fs1");
2006 }
2007 } else {
2008 if(gr_screen.res == GR_640) {
2009 settings->offset[0] = 39;
2010 settings->offset[1] = -72;
2011
2012 Laser_warn_offsets[0] = 41;
2013 Laser_warn_offsets[1] = 77;
2014
2015 Lock_warn_offsets[0] = 35;
2016 Lock_warn_offsets[1] = 93;
2017
2018 strcpy_s(fname_arc, "rightarc1");
2019 strcpy_s(fname_laser, "toparc2");
2020 strcpy_s(fname_lock, "toparc3");
2021 } else {
2022 settings->offset[0] = 62;
2023 settings->offset[1] = -115;
2024
2025 Laser_warn_offsets[0] = 66;
2026 Laser_warn_offsets[1] = 124;
2027
2028 Lock_warn_offsets[0] = 57;
2029 Lock_warn_offsets[1] = 150;
2030
2031 strcpy_s(fname_arc, "2_rightarc1");
2032 strcpy_s(fname_laser, "2_toparc2");
2033 strcpy_s(fname_lock, "2_toparc3");
2034 }
2035 }
2036
2037 auto hud_gauge = gauge_load_common<HudGaugeThreatIndicator>(settings);
2038
2039 if(optional_string("Arc Filename:")) {
2040 stuff_string(fname_arc, F_NAME, MAX_FILENAME_LEN);
2041 }
2042 if(optional_string("Dumbfire Filename:")) {
2043 stuff_string(fname_laser, F_NAME, MAX_FILENAME_LEN);
2044 }
2045 if(optional_string("Lock Filename:")) {
2046 stuff_string(fname_lock, F_NAME, MAX_FILENAME_LEN);
2047 }
2048 if(optional_string("Dumbfire Offsets:")) {
2049 stuff_int_list(Laser_warn_offsets, 2);
2050 }
2051 if(optional_string("Lock Offsets:")) {
2052 stuff_int_list(Lock_warn_offsets, 2);
2053 }
2054
2055 hud_gauge->initBitmaps(fname_arc, fname_laser, fname_lock);
2056 hud_gauge->initLaserWarnOffsets(Laser_warn_offsets[0], Laser_warn_offsets[1]);
2057 hud_gauge->initLockWarnOffsets(Lock_warn_offsets[0], Lock_warn_offsets[1]);
2058
2059 gauge_assign_common(settings, std::move(hud_gauge));
2060 }
2061
load_gauge_center_reticle(gauge_settings * settings)2062 void load_gauge_center_reticle(gauge_settings* settings)
2063 {
2064 char fname[MAX_FILENAME_LEN];
2065 bool firepoints = false;
2066 int scaleX = 15;
2067 int scaleY = 10;
2068 int size = 5;
2069 int autoaim_frame = -1;
2070
2071 settings->origin[0] = 0.5f;
2072 settings->origin[1] = 0.5f;
2073 settings->slew = true;
2074
2075 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
2076 if(gr_screen.res == GR_640) {
2077 settings->offset[0] = -12;
2078 settings->offset[1] = -5;
2079
2080 strcpy_s(fname, "reticle1_fs1");
2081 } else {
2082 settings->offset[0] = -19;
2083 settings->offset[1] = -8;
2084
2085 strcpy_s(fname, "2_reticle1_fs1");
2086 }
2087 } else {
2088 if(gr_screen.res == GR_640) {
2089 settings->offset[0] = -12;
2090 settings->offset[1] = -5;
2091
2092 strcpy_s(fname, "reticle1");
2093 } else {
2094 settings->offset[0] = -19;
2095 settings->offset[1] = -14;
2096
2097 strcpy_s(fname, "2_reticle1");
2098 }
2099 }
2100
2101 auto hud_gauge = gauge_load_common<HudGaugeReticle>(settings);
2102
2103 if(optional_string("Filename:")) {
2104 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2105 }
2106
2107 if(optional_string("Firepoint display:"))
2108 stuff_boolean(&firepoints);
2109
2110 if (optional_string("Firepoint size:"))
2111 stuff_int(&size);
2112
2113 if (optional_string("Firepoint X coordinate multiplier:"))
2114 stuff_int(&scaleX);
2115
2116 if (optional_string("Firepoint Y coordinate multiplier:"))
2117 stuff_int(&scaleY);
2118
2119 if(optional_string("Autoaim Frame:"))
2120 stuff_int(&autoaim_frame);
2121
2122 hud_gauge->initBitmaps(fname);
2123 hud_gauge->initFirepointDisplay(firepoints, scaleX, scaleY, size);
2124 hud_gauge->setAutoaimFrame(autoaim_frame);
2125
2126 gauge_assign_common(settings, std::move(hud_gauge));
2127 }
2128
load_gauge_throttle(gauge_settings * settings)2129 void load_gauge_throttle(gauge_settings* settings)
2130 {
2131 int bottom_offset_y;
2132 int throttle_h, throttle_w;
2133 int throttle_aburn_h;
2134 int max_speed_offset[2];
2135 bool show_max_speed = true;
2136 int zero_speed_offset[2];
2137 bool show_min_speed = true;
2138 bool orbit = true;
2139 int orbit_center_offset[2];
2140 int orbit_radius;
2141 int target_speed_offset[2] = {0, 0};
2142 bool show_target_speed = false;
2143 bool show_target_speed_percent = false;
2144 int glide_offset[2] = {0, 0};
2145 bool custom_glide = false;
2146 int match_speed_offset[2] = {0, 0};
2147 bool custom_match = false;
2148 char fname[MAX_FILENAME_LEN];
2149 bool show_background = false;
2150
2151 settings->origin[0] = 0.5f;
2152 settings->origin[1] = 0.5f;
2153 settings->slew = true;
2154
2155 // default values for the throttle
2156 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
2157 if(gr_screen.res == GR_640) {
2158 settings->offset[0] = -103;
2159 settings->offset[1] = 4;
2160
2161 bottom_offset_y = 65;
2162 throttle_h = 50;
2163 throttle_w = 49;
2164 throttle_aburn_h = 17;
2165 max_speed_offset[0] = 14;
2166 max_speed_offset[1] = 14;
2167 zero_speed_offset[0] = 33;
2168 zero_speed_offset[1] = 63;
2169 orbit_center_offset[0] = 103;
2170 orbit_center_offset[1] = -1;
2171 orbit_radius = 104;
2172 strcpy_s(fname, "leftarc_fs1");
2173 } else {
2174 settings->offset[0] = -165;
2175 settings->offset[1] = 6;
2176
2177 bottom_offset_y = 104;
2178 throttle_h = 80;
2179 throttle_w = 78;
2180 throttle_aburn_h = 27;
2181 max_speed_offset[0] = 22;
2182 max_speed_offset[1] = 22;
2183 zero_speed_offset[0] = 53;
2184 zero_speed_offset[1] = 101;
2185 orbit_center_offset[0] = 165;
2186 orbit_center_offset[1] = -1;
2187 orbit_radius = 166;
2188 strcpy_s(fname, "2_leftarc_fs1");
2189 }
2190 show_background = true;
2191 } else {
2192 if(gr_screen.res == GR_640) {
2193 settings->offset[0] = -104;
2194 settings->offset[1] = -72;
2195
2196 bottom_offset_y = 139;
2197 throttle_h = 50;
2198 throttle_w = 49;
2199 throttle_aburn_h = 17;
2200 max_speed_offset[0] = 20;
2201 max_speed_offset[1] = 86;
2202 zero_speed_offset[0] = 36;
2203 zero_speed_offset[1] = 135;
2204 orbit_center_offset[0] = 104;
2205 orbit_center_offset[1] = 75;
2206 orbit_radius = 104;
2207 strcpy_s(fname, "leftarc");
2208 } else {
2209 settings->offset[0] = -166;
2210 settings->offset[1] = -115;
2211
2212 bottom_offset_y = 222;
2213 throttle_h = 80;
2214 throttle_w = 78;
2215 throttle_aburn_h = 27;
2216 max_speed_offset[0] = 31;
2217 max_speed_offset[1] = 137;
2218 zero_speed_offset[0] = 57;
2219 zero_speed_offset[1] = 216;
2220 orbit_center_offset[0] = 166;
2221 orbit_center_offset[1] = 118;
2222 orbit_radius = 166;
2223 strcpy_s(fname, "2_leftarc");
2224 }
2225 }
2226
2227 auto hud_gauge = gauge_load_common<HudGaugeThrottle>(settings);
2228
2229 if(optional_string("Filename:")) {
2230 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2231 }
2232 if(optional_string("Foreground Clip Bottom Y-offset:")) {
2233 stuff_int(&bottom_offset_y);
2234 }
2235 if(optional_string("Foreground Clip Width:")) {
2236 stuff_int(&throttle_w);
2237 }
2238 if(optional_string("Foreground Clip Height:")) {
2239 stuff_int(&throttle_h);
2240 }
2241 if(optional_string("Afterburner Clip Height:")) {
2242 stuff_int(&throttle_aburn_h);
2243 }
2244 if(optional_string("Show Background:")) {
2245 stuff_boolean(&show_background);
2246 }
2247 if(optional_string("Max Speed Label Offsets:")) {
2248 stuff_int_list(max_speed_offset, 2);
2249 }
2250 if(optional_string("Show Max Speed Label:")) {
2251 stuff_boolean(&show_max_speed);
2252 }
2253 if(optional_string("Min Speed Label Offsets:")) {
2254 stuff_int_list(zero_speed_offset, 2);
2255 }
2256 if(optional_string("Show Min Speed Label:")) {
2257 stuff_boolean(&show_min_speed);
2258 }
2259 if(optional_string("Orbit Center Offsets:")) {
2260 stuff_int_list(orbit_center_offset, 2);
2261 }
2262 if(optional_string("Orbit Radius:")) {
2263 stuff_int(&orbit_radius);
2264 }
2265 if(optional_string("Current Speed Offsets:")) {
2266 stuff_int_list(orbit_center_offset, 2);
2267 orbit = false;
2268 }
2269 if(optional_string("Target Speed Offsets:")) {
2270 stuff_int_list(target_speed_offset, 2);
2271 show_target_speed = true;
2272 }
2273 if ( optional_string("Show Percentage:") ) {
2274 stuff_boolean(&show_target_speed_percent);
2275 }
2276 if(optional_string("Glide Status Offsets:")) {
2277 stuff_int_list(glide_offset, 2);
2278 custom_glide = true;
2279 }
2280 if(optional_string("Match Speed Status Offsets:")) {
2281 stuff_int_list(match_speed_offset, 2);
2282 custom_match = true;
2283 }
2284
2285 hud_gauge->initThrottleStartY(bottom_offset_y);
2286 hud_gauge->initThrottleSizes(throttle_w, throttle_h);
2287 hud_gauge->initAburnHeight(throttle_aburn_h);
2288 hud_gauge->initMaxSpeedOffsets(max_speed_offset[0], max_speed_offset[1], show_max_speed);
2289 hud_gauge->initZeroSpeedOffsets(zero_speed_offset[0], zero_speed_offset[1], show_min_speed);
2290 hud_gauge->initOrbitCenterOffsets(orbit_center_offset[0], orbit_center_offset[1], orbit);
2291 hud_gauge->initOrbitRadius(orbit_radius);
2292 hud_gauge->initTargetSpeedOffsets(target_speed_offset[0], target_speed_offset[1], show_target_speed, show_target_speed_percent);
2293 hud_gauge->initGlideOffsets(glide_offset[0], glide_offset[1], custom_glide);
2294 hud_gauge->initMatchSpeedOffsets(match_speed_offset[0], match_speed_offset[1], custom_match);
2295 hud_gauge->initBitmaps(fname);
2296 hud_gauge->showBackground(show_background);
2297
2298 gauge_assign_common(settings, std::move(hud_gauge));
2299 }
2300
2301 /**
2302 * Load retail style ETS gauge
2303 * i.e. treats weapons, shields & engines gauges as a single gauge
2304 */
load_gauge_ets_retail(gauge_settings * settings)2305 void load_gauge_ets_retail(gauge_settings* settings)
2306 {
2307 int bar_h;
2308 int letter_offsets[2];
2309 int top_offsets[2];
2310 int bottom_offsets[2];
2311 char ets_letters[num_retail_ets_gauges];
2312 char fname[MAX_FILENAME_LEN] = "energy1";
2313 int gauge_offset; // distance between micro gauges
2314 int i;
2315 int gauge_positions[num_retail_ets_gauges];
2316
2317 settings->origin[0] = 1.0f;
2318 settings->origin[1] = 1.0f;
2319
2320 if (Lcl_gr) {
2321 ets_letters[0] = 'G'; ets_letters[1] = 'S'; ets_letters[2] = 'A'; // German
2322 } else if (Lcl_fr) {
2323 ets_letters[0] = 'C'; ets_letters[1] = 'B'; ets_letters[2] = 'M'; // French
2324 } else {
2325 ets_letters[0] = 'G'; ets_letters[1] = 'S'; ets_letters[2] = 'E'; // English
2326 }
2327
2328 // default values which may be overwritten by .tbl
2329 if(gr_screen.res == GR_640) {
2330 settings->offset[0] = -117;
2331 settings->offset[1] = -100;
2332
2333 gauge_offset = 17;
2334 } else {
2335 settings->offset[0] = -144;
2336 settings->offset[1] = -120;
2337
2338 gauge_offset = 18;
2339 }
2340 bar_h = 41;
2341 letter_offsets[0] = 2;
2342 letter_offsets[1] = 42;
2343 top_offsets[0] = 0;
2344 top_offsets[1] = 0;
2345 bottom_offsets[0] = 0;
2346 bottom_offsets[1] = 50;
2347
2348 auto hud_gauge = gauge_load_common<HudGaugeEtsRetail>(settings);
2349
2350 if(optional_string("Filename:")) {
2351 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2352 }
2353 if(optional_string("Foreground Clip Height:")) {
2354 stuff_int(&bar_h);
2355 }
2356 if(optional_string("Letter Offsets:")) {
2357 stuff_int_list(letter_offsets, 2);
2358 }
2359 if(optional_string("Top Offsets:")) {
2360 stuff_int_list(top_offsets, 2);
2361 }
2362 if(optional_string("Bottom Offsets:")) {
2363 stuff_int_list(bottom_offsets, 2);
2364 }
2365 if(optional_string("Gauge Offset:")) {
2366 stuff_int(&gauge_offset);
2367 }
2368
2369 // calculate offsets for the three gauges from settings->coords[0], which was set by gauge_load_common
2370 for (i = 0; i < num_retail_ets_gauges; ++i) {
2371 gauge_positions[i] = settings->coords[0] + gauge_offset * i;
2372 }
2373
2374 hud_gauge->initLetters(ets_letters);
2375 hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
2376 hud_gauge->initTopOffsets(top_offsets[0], top_offsets[1]);
2377 hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
2378 hud_gauge->initBarHeight(bar_h);
2379 hud_gauge->initBitmaps(fname);
2380 hud_gauge->initGaugePositions(gauge_positions);
2381
2382 gauge_assign_common(settings, std::move(hud_gauge));
2383 }
2384
load_gauge_ets_weapons(gauge_settings * settings)2385 void load_gauge_ets_weapons(gauge_settings* settings)
2386 {
2387 int bar_h;
2388 int letter_offsets[2];
2389 int top_offsets[2];
2390 int bottom_offsets[2];
2391 char letter;
2392 char fname[MAX_FILENAME_LEN] = "energy1";
2393
2394 settings->origin[0] = 1.0f;
2395 settings->origin[1] = 1.0f;
2396
2397 if(Lcl_gr) {
2398 // German
2399 letter = 'G';
2400 } else if(Lcl_fr) {
2401 // French
2402 letter = 'C';
2403 } else {
2404 // English
2405 letter = 'G';
2406 }
2407
2408 if(gr_screen.res == GR_640) {
2409 settings->offset[0] = -117;
2410 settings->offset[1] = -100;
2411 } else {
2412 settings->offset[0] = -144;
2413 settings->offset[1] = -120;
2414 }
2415 bar_h = 41;
2416 letter_offsets[0] = 2;
2417 letter_offsets[1] = 42;
2418 top_offsets[0] = 0;
2419 top_offsets[1] = 0;
2420 bottom_offsets[0] = 0;
2421 bottom_offsets[1] = 50;
2422
2423 auto hud_gauge = gauge_load_common<HudGaugeEtsWeapons>(settings);
2424
2425 if(optional_string("Filename:")) {
2426 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2427 }
2428 if(optional_string("Foreground Clip Height:")) {
2429 stuff_int(&bar_h);
2430 }
2431 if(optional_string("Letter Offsets:")) {
2432 stuff_int_list(letter_offsets, 2);
2433 }
2434 if(optional_string("Top Offsets:")) {
2435 stuff_int_list(top_offsets, 2);
2436 }
2437 if(optional_string("Bottom Offsets:")) {
2438 stuff_int_list(bottom_offsets, 2);
2439 }
2440
2441 hud_gauge->initLetter(letter);
2442 hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
2443 hud_gauge->initTopOffsets(top_offsets[0], top_offsets[1]);
2444 hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
2445 hud_gauge->initBarHeight(bar_h);
2446 hud_gauge->initBitmaps(fname);
2447
2448 gauge_assign_common(settings, std::move(hud_gauge));
2449 }
2450
load_gauge_ets_shields(gauge_settings * settings)2451 void load_gauge_ets_shields(gauge_settings* settings)
2452 {
2453 int bar_h;
2454 int letter_offsets[2];
2455 int top_offsets[2];
2456 int bottom_offsets[2];
2457 char letter;
2458 char fname[MAX_FILENAME_LEN] = "energy1";
2459
2460 settings->origin[0] = 1.0f;
2461 settings->origin[1] = 1.0f;
2462
2463 if(Lcl_gr){
2464 // German
2465 letter = 'S';
2466 } else if(Lcl_fr){
2467 // French
2468 letter = 'B';
2469 } else {
2470 // English
2471 letter = 'S';
2472 }
2473
2474 if(gr_screen.res == GR_640) {
2475 settings->offset[0] = -100;
2476 settings->offset[1] = -100;
2477 } else {
2478 settings->offset[0] = -126;
2479 settings->offset[1] = -120;
2480 }
2481 bar_h = 41;
2482
2483 letter_offsets[0] = 2;
2484 letter_offsets[1] = 42;
2485 top_offsets[0] = 0;
2486 top_offsets[1] = 0;
2487 bottom_offsets[0] = 0;
2488 bottom_offsets[1] = 50;
2489
2490 auto hud_gauge = gauge_load_common<HudGaugeEtsShields>(settings);
2491
2492 if(optional_string("Filename:")) {
2493 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2494 }
2495 if(optional_string("Foreground Clip Height:")) {
2496 stuff_int(&bar_h);
2497 }
2498 if(optional_string("Letter Offsets:")) {
2499 stuff_int_list(letter_offsets, 2);
2500 }
2501 if(optional_string("Top Offsets:")) {
2502 stuff_int_list(top_offsets, 2);
2503 }
2504 if(optional_string("Bottom Offsets:")) {
2505 stuff_int_list(bottom_offsets, 2);
2506 }
2507
2508 hud_gauge->initBarHeight(bar_h);
2509 hud_gauge->initBitmaps(fname);
2510 hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
2511 hud_gauge->initLetter(letter);
2512 hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
2513 hud_gauge->initTopOffsets(top_offsets[0], top_offsets[1]);
2514
2515 gauge_assign_common(settings, std::move(hud_gauge));
2516 }
2517
load_gauge_ets_engines(gauge_settings * settings)2518 void load_gauge_ets_engines(gauge_settings* settings)
2519 {
2520 int bar_h;
2521 int letter_offsets[2];
2522 int top_offsets[2];
2523 int bottom_offsets[2];
2524 char letter;
2525 char fname[MAX_FILENAME_LEN] = "energy1";
2526
2527 settings->origin[0] = 1.0f;
2528 settings->origin[1] = 1.0f;
2529
2530 if(Lcl_gr){
2531 // German
2532 letter = 'A';
2533 } else if(Lcl_fr){
2534 // French
2535 letter = 'M';
2536 } else {
2537 // English
2538 letter = 'E';
2539 }
2540
2541 if(gr_screen.res == GR_640) {
2542 settings->offset[0] = -83;
2543 settings->offset[1] = -100;
2544 } else {
2545 settings->offset[0] = -108;
2546 settings->offset[1] = -120;
2547 }
2548
2549 bar_h = 41;
2550
2551 letter_offsets[0] = 2;
2552 letter_offsets[1] = 42;
2553 top_offsets[0] = 0;
2554 top_offsets[1] = 0;
2555 bottom_offsets[0] = 0;
2556 bottom_offsets[1] = 50;
2557
2558 auto hud_gauge = gauge_load_common<HudGaugeEtsEngines>(settings);
2559
2560 if(optional_string("Filename:")) {
2561 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2562 }
2563 if(optional_string("Foreground Clip Height:")) {
2564 stuff_int(&bar_h);
2565 }
2566 if(optional_string("Letter Offsets:")) {
2567 stuff_int_list(letter_offsets, 2);
2568 }
2569 if(optional_string("Top Offsets:")) {
2570 stuff_int_list(top_offsets, 2);
2571 }
2572 if(optional_string("Bottom Offsets:")) {
2573 stuff_int_list(bottom_offsets, 2);
2574 }
2575
2576 hud_gauge->initBarHeight(bar_h);
2577 hud_gauge->initBitmaps(fname);
2578 hud_gauge->initBottomOffsets(bottom_offsets[0], bottom_offsets[1]);
2579 hud_gauge->initLetter(letter);
2580 hud_gauge->initLetterOffsets(letter_offsets[0], letter_offsets[1]);
2581 hud_gauge->initTopOffsets(top_offsets[0], top_offsets[1]);
2582
2583 gauge_assign_common(settings, std::move(hud_gauge));
2584 }
2585
load_gauge_extra_target_data(gauge_settings * settings)2586 void load_gauge_extra_target_data(gauge_settings* settings)
2587 {
2588 int dock_offsets[2];
2589 int dock_max_w;
2590 int time_offsets[2];
2591 int bracket_offsets[2];
2592 int order_offsets[2];
2593 int order_max_w;
2594 char fname[MAX_FILENAME_LEN] = "targetview3";
2595
2596 settings->origin[0] = 0.0f;
2597 settings->origin[1] = 1.0f;
2598
2599 if(gr_screen.res == GR_640) {
2600 settings->offset[0] = 5;
2601 settings->offset[1] = -200;
2602
2603 dock_offsets[0] = 8;
2604 dock_offsets[1] = 19;
2605
2606 time_offsets[0] = 8;
2607 time_offsets[1] = 10;
2608 } else {
2609 settings->offset[0] = 5;
2610 settings->offset[1] = -216;
2611
2612 dock_offsets[0] = 8;
2613 dock_offsets[1] = 18;
2614
2615 time_offsets[0] = 8;
2616 time_offsets[1] = 9;
2617 }
2618
2619 bracket_offsets[0] = 0;
2620 bracket_offsets[1] = 3;
2621
2622 order_offsets[0] = 8;
2623 order_offsets[1] = 0;
2624
2625 dock_max_w = 173;
2626 order_max_w = 162;
2627
2628 auto hud_gauge = gauge_load_common<HudGaugeExtraTargetData>(settings);
2629
2630 if(optional_string("Filename:")) {
2631 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2632 }
2633 if(optional_string("Bracket Offsets:")) {
2634 stuff_int_list(bracket_offsets, 2);
2635 }
2636 if(optional_string("Dock Offsets:")) {
2637 stuff_int_list(dock_offsets, 2);
2638 }
2639 if(optional_string("Dock Max Width:")) {
2640 stuff_int(&dock_max_w);
2641 }
2642 if(optional_string("Order Offsets:")) {
2643 stuff_int_list(order_offsets, 2);
2644 }
2645 if(optional_string("Order Max Width:")) {
2646 stuff_int(&order_max_w);
2647 }
2648 if(optional_string("Time Offsets:")) {
2649 stuff_int_list(time_offsets, 2);
2650 }
2651
2652 hud_gauge->initBitmaps(fname);
2653 hud_gauge->initBracketOffsets(bracket_offsets[0], bracket_offsets[1]);
2654 hud_gauge->initDockOffsets(dock_offsets[0], dock_offsets[1]);
2655 hud_gauge->initDockMaxWidth(dock_max_w);
2656 hud_gauge->initOrderOffsets(order_offsets[0], order_offsets[1]);
2657 hud_gauge->initOrderMaxWidth(order_max_w);
2658 hud_gauge->initTimeOffsets(time_offsets[0], time_offsets[1]);
2659
2660 gauge_assign_common(settings, std::move(hud_gauge));
2661 }
2662
load_gauge_radar_std(gauge_settings * settings)2663 void load_gauge_radar_std(gauge_settings* settings)
2664 {
2665 int Radar_blip_radius_normal;
2666 int Radar_blip_radius_target;
2667 int Radar_radius[2];
2668 int Radar_dist_offsets[RR_MAX_RANGES][2];
2669 float Radar_center_offsets[2];
2670 char fname[MAX_FILENAME_LEN];
2671
2672 settings->origin[0] = 0.5f;
2673 settings->origin[1] = 1.0f;
2674
2675 if(gr_screen.res == GR_640) {
2676 settings->offset[0] = -63;
2677 settings->offset[1] = -111;
2678
2679 Radar_blip_radius_normal = 2;
2680 Radar_blip_radius_target = 5;
2681
2682 Radar_center_offsets[0] = 64.0f;
2683 Radar_center_offsets[1] = 53.0f;
2684
2685 Radar_radius[0] = 120;
2686 Radar_radius[1] = 100;
2687
2688 Radar_dist_offsets[0][0] = 110;
2689 Radar_dist_offsets[0][1] = 92;
2690
2691 Radar_dist_offsets[1][0] = 107;
2692 Radar_dist_offsets[1][1] = 92;
2693
2694 Radar_dist_offsets[2][0] = 111;
2695 Radar_dist_offsets[2][1] = 92;
2696
2697 strcpy_s(fname, "radar1");
2698 } else {
2699 settings->offset[0] = -101;
2700 settings->offset[1] = -178;
2701
2702 Radar_blip_radius_normal = 4;
2703 Radar_blip_radius_target = 8;
2704
2705 Radar_center_offsets[0] = 104.0f;
2706 Radar_center_offsets[1] = 85.0f;
2707
2708 Radar_radius[0] = 192;
2709 Radar_radius[1] = 160;
2710
2711 Radar_dist_offsets[0][0] = 184;
2712 Radar_dist_offsets[0][1] = 150;
2713
2714 Radar_dist_offsets[1][0] = 181;
2715 Radar_dist_offsets[1][1] = 150;
2716
2717 Radar_dist_offsets[2][0] = 185;
2718 Radar_dist_offsets[2][1] = 150;
2719
2720 strcpy_s(fname, "2_radar1");
2721 }
2722
2723 // Ngon radar -- Cyborg17 - to fit this into gauge_load_common, we have to have this right before origin and Offset
2724 int num_sides = 0;
2725 float offset = 0.0f;
2726
2727 if (optional_string("Ngon Sides:")) {
2728 stuff_int(&num_sides);
2729 if ((num_sides < RADAR_NGON_MIN_SIDES)) {
2730 Warning(LOCATION,
2731 "Invalid value for 'Ngon Sides'! Value must be greater than %i.\n Using standard radar instead.\n",
2732 RADAR_NGON_MIN_SIDES);
2733 num_sides = 0;
2734 }
2735
2736 if (optional_string("Ngon Offset:")) {
2737 stuff_float(&offset);
2738 }
2739 }
2740
2741 //=======================================================================================================
2742 // Cyborg17 - not using auto here is a huge pain to get exactly right and to read. If we put this in a
2743 // normal if block, either auto will break or hud_gauge will go out of scope before the last block below.
2744 // The ternery operator lets us circumvent this problem by allowing us to use auto, while also loading
2745 // the radar, creating the unique_ptr, and staying in scope.
2746
2747 // did we have a normal radar? If so, load the regular radar.
2748 auto hud_gauge = (num_sides == 0)
2749 ? gauge_load_common<HudGaugeRadarStd>(settings)
2750 // if not *construct* and then load the ngon radar
2751 : gauge_load_common<HudGaugeRadarNgon>(settings, new HudGaugeRadarNgon(num_sides, offset));
2752
2753 if(optional_string("Filename:")) {
2754 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2755 }
2756 if(optional_string("Radar Center Offsets:")) {
2757 stuff_float_list(Radar_center_offsets, 2);
2758 }
2759 if(optional_string("Radar Size:")) {
2760 stuff_int_list(Radar_radius, 2);
2761 }
2762 if(optional_string("Infinity Distance Offsets:")) {
2763 stuff_int_list(Radar_dist_offsets[2], 2);
2764 }
2765 if(optional_string("Long Distance Offsets:")) {
2766 stuff_int_list(Radar_dist_offsets[1], 2);
2767 }
2768 if(optional_string("Short Distance Offsets:")) {
2769 stuff_int_list(Radar_dist_offsets[0], 2);
2770 }
2771
2772 // Only load this if the user hasn't specified a preference
2773 if (Cmdline_orb_radar == 0) {
2774 hud_gauge->initBitmaps(fname);
2775 hud_gauge->initBlipRadius(Radar_blip_radius_normal, Radar_blip_radius_target);
2776 hud_gauge->initCenterOffsets(Radar_center_offsets[0], Radar_center_offsets[1]);
2777 hud_gauge->initDistanceInfinityOffsets(Radar_dist_offsets[2][0], Radar_dist_offsets[2][1]);
2778 hud_gauge->initDistanceLongOffsets(Radar_dist_offsets[1][0], Radar_dist_offsets[1][1]);
2779 hud_gauge->initDistanceShortOffsets(Radar_dist_offsets[0][0], Radar_dist_offsets[0][1]);
2780 hud_gauge->initRadius(Radar_radius[0], Radar_radius[1]);
2781 hud_gauge->initInfinityIcon();
2782
2783 gauge_assign_common(settings, std::move(hud_gauge));
2784 }
2785 }
2786
load_gauge_radar_orb(gauge_settings * settings)2787 void load_gauge_radar_orb(gauge_settings* settings)
2788 {
2789 int Radar_blip_radius_normal;
2790 int Radar_blip_radius_target;
2791 int Radar_radius[2];
2792 int Radar_dist_offsets[RR_MAX_RANGES][2];
2793 float Radar_center_offsets[2];
2794 char fname[MAX_FILENAME_LEN];
2795
2796 settings->origin[0] = 0.5f;
2797 settings->origin[1] = 1.0f;
2798
2799 if(gr_screen.res == GR_640) {
2800 settings->offset[0] = -63;
2801 settings->offset[1] = -111;
2802
2803 Radar_blip_radius_normal = 2;
2804 Radar_blip_radius_target = 5;
2805
2806 Radar_center_offsets[0] = 65.0f;
2807 Radar_center_offsets[1] = 53.0f;
2808
2809 Radar_radius[0] = 120;
2810 Radar_radius[1] = 100;
2811
2812 Radar_dist_offsets[0][0]=110;
2813 Radar_dist_offsets[0][1]=92;
2814
2815 Radar_dist_offsets[1][0]=107;
2816 Radar_dist_offsets[1][1]=92;
2817
2818 Radar_dist_offsets[2][0]=111;
2819 Radar_dist_offsets[2][1]=92;
2820
2821 strcpy_s(fname, "radar1");
2822 } else {
2823 settings->offset[0] = -101;
2824 settings->offset[1] = -178;
2825
2826 Radar_blip_radius_normal = 4;
2827 Radar_blip_radius_target = 8;
2828
2829 Radar_center_offsets[0] = 104.0f;
2830 Radar_center_offsets[1] = 85.0f;
2831
2832 Radar_radius[0] = 192;
2833 Radar_radius[1] = 160;
2834
2835 Radar_dist_offsets[0][0]=184;
2836 Radar_dist_offsets[0][1]=150;
2837
2838 Radar_dist_offsets[1][0]=181;
2839 Radar_dist_offsets[1][1]=150;
2840
2841 Radar_dist_offsets[2][0]=185;
2842 Radar_dist_offsets[2][1]=150;
2843
2844 strcpy_s(fname, "2_radar1");
2845 }
2846
2847 auto hud_gauge = gauge_load_common<HudGaugeRadarOrb>(settings);
2848
2849 if(optional_string("Filename:")) {
2850 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
2851 }
2852 if(optional_string("Radar Center Offsets:")) {
2853 stuff_float_list(Radar_center_offsets, 2);
2854 }
2855 if(optional_string("Radar Size:")) {
2856 stuff_int_list(Radar_radius, 2);
2857 }
2858 if(optional_string("Infinity Distance Offsets:")) {
2859 stuff_int_list(Radar_dist_offsets[2], 2);
2860 }
2861 if(optional_string("Long Distance Offsets:")) {
2862 stuff_int_list(Radar_dist_offsets[1], 2);
2863 }
2864 if(optional_string("Short Distance Offsets:")) {
2865 stuff_int_list(Radar_dist_offsets[0], 2);
2866 }
2867
2868 //only load this if the user actually wants to use the orb radar.
2869 if (Cmdline_orb_radar == 1) {
2870 hud_gauge->initBitmaps(fname);
2871 hud_gauge->initBlipRadius(Radar_blip_radius_normal, Radar_blip_radius_target);
2872 hud_gauge->initCenterOffsets(Radar_center_offsets[0], Radar_center_offsets[1]);
2873 hud_gauge->initDistanceInfinityOffsets(Radar_dist_offsets[2][0], Radar_dist_offsets[2][1]);
2874 hud_gauge->initDistanceLongOffsets(Radar_dist_offsets[1][0], Radar_dist_offsets[1][1]);
2875 hud_gauge->initDistanceShortOffsets(Radar_dist_offsets[0][0], Radar_dist_offsets[0][1]);
2876 hud_gauge->initRadius(Radar_radius[0], Radar_radius[1]);
2877 hud_gauge->initInfinityIcon();
2878
2879 gauge_assign_common(settings, std::move(hud_gauge));
2880 }
2881 }
2882
2883 /**
2884 * BSG style DRADIS as used by Diaspora
2885 * Unfortunately, I can't see how to make this fit the gauge_load_common function
2886 */
load_gauge_radar_dradis(gauge_settings * settings)2887 void load_gauge_radar_dradis(gauge_settings* settings)
2888 {
2889 // basic radar gauge info
2890 int Radar_radius[2];
2891
2892 // bitmap filenames for the effect
2893 char xy_fname[MAX_FILENAME_LEN] = "dradis_xy";
2894 char xz_yz_fname[MAX_FILENAME_LEN] = "dradis_xz_yz";
2895 char sweep_fname[MAX_FILENAME_LEN] = "dradis_sweep";
2896 char target_fname[MAX_FILENAME_LEN] = "dradis_target";
2897 char unknown_fname[MAX_FILENAME_LEN] = "dradis_unknown";
2898
2899 // render to texture parameters
2900 char display_name[MAX_FILENAME_LEN] = "";
2901 int display_offset[2] = {0, 0};
2902 int display_size[2] = {0, 0};
2903 int canvas_size[2] = {0, 0};
2904
2905 gamesnd_id loop_snd;
2906 float loop_snd_volume = 1.0f;
2907
2908 gamesnd_id arrival_beep_snd;
2909 gamesnd_id departure_beep_snd;
2910
2911 gamesnd_id stealth_arrival_snd;
2912 gamesnd_id stealth_departure_snd;
2913
2914 float arrival_beep_delay = 0.0f;
2915 float departure_beep_delay = 0.0f;
2916
2917 settings->origin[0] = 0.5f;
2918 settings->origin[1] = 1.0f;
2919
2920 if(gr_screen.res == GR_640) {
2921 settings->offset[0] = -89;
2922 settings->offset[1] = -148;
2923 } else {
2924 settings->offset[0] = -143;
2925 settings->offset[1] = -237;
2926 }
2927
2928 Radar_radius[0] = 281;
2929 Radar_radius[1] = 233;
2930
2931 if(check_base_res(settings->base_res)) {
2932 if(optional_string("Position:")) {
2933 stuff_int_list(settings->coords, 2);
2934 settings->use_coords = true;
2935 } else {
2936 if (optional_string("Scale Gauge:")) {
2937 stuff_boolean(&settings->scale_gauge);
2938 }
2939
2940 if (optional_string("Force Scaling Above:")) {
2941 stuff_int_list(settings->force_scaling_above_res, 2);
2942 }
2943
2944 adjust_base_res(settings->base_res, settings->force_scaling_above_res, settings->scale_gauge);
2945
2946 if(optional_string("Origin:")) {
2947 stuff_float_list(settings->origin, 2);
2948
2949 required_string("Offset:");
2950 stuff_int_list(settings->offset, 2);
2951 }
2952
2953 if(optional_string("Offset:")) {
2954 Error(LOCATION, "HUD gauges table: Offset must also have Origin defined");
2955 }
2956
2957 settings->coords[0] = (int)(settings->base_res[0] * settings->origin[0]) + settings->offset[0];
2958 settings->coords[1] = (int)(settings->base_res[1] * settings->origin[1]) + settings->offset[1];
2959 settings->use_coords = true;
2960 }
2961 } else {
2962 if(gr_screen.res == GR_640) {
2963 settings->base_res[0] = 640;
2964 settings->base_res[1] = 480;
2965 } else {
2966 settings->base_res[0] = 1024;
2967 settings->base_res[1] = 768;
2968 }
2969
2970 adjust_base_res(settings->base_res, settings->force_scaling_above_res, settings->scale_gauge);
2971
2972 settings->coords[0] = (int)(settings->base_res[0] * settings->origin[0]) + settings->offset[0];
2973 settings->coords[1] = (int)(settings->base_res[1] * settings->origin[1]) + settings->offset[1];
2974 settings->use_coords = true;
2975 }
2976
2977 if (optional_string("Font:")) {
2978 settings->font_num = font::parse_font();
2979 } else {
2980 if ( settings->font_num < 0 ) {
2981 settings->font_num = font::FONT1;
2982 }
2983 }
2984
2985 if(optional_string("Size:")) {
2986 stuff_int_list(Radar_radius, 2);
2987 }
2988 if(optional_string("XY Disc Filename:")) {
2989 stuff_string(xy_fname, F_NAME, MAX_FILENAME_LEN);
2990 }
2991 if(optional_string("XZ YZ Disc Filename:")) {
2992 stuff_string(xz_yz_fname, F_NAME, MAX_FILENAME_LEN);
2993 }
2994 if(optional_string("Sweep Disc Filename:")) {
2995 stuff_string(sweep_fname, F_NAME, MAX_FILENAME_LEN);
2996 }
2997 if(optional_string("Default Contact Filename:")) {
2998 stuff_string(target_fname, F_NAME, MAX_FILENAME_LEN);
2999 }
3000 if(optional_string("Unknown Contact Filename:")) {
3001 stuff_string(unknown_fname, F_NAME, MAX_FILENAME_LEN);
3002 }
3003 if(optional_string("Cockpit Target:") && settings->ship_idx->at(0) >= 0) {
3004 stuff_string(display_name, F_NAME, MAX_FILENAME_LEN);
3005
3006 if(optional_string("Canvas Size:")) {
3007 stuff_int_list(canvas_size, 2);
3008 }
3009
3010 if ( optional_string("Display Offset:") ) {
3011 stuff_int_list(display_offset, 2);
3012 }
3013
3014 required_string("Display Size:");
3015 stuff_int_list(display_size, 2);
3016 } else {
3017 // adjust for multimonitor setups ONLY if not rendering gauge to a texture
3018 adjust_for_multimonitor(settings->base_res, true, settings->coords);
3019 }
3020
3021 parse_game_sound("Loop Sound:", &loop_snd);
3022
3023 if (optional_string("Loop Volume:"))
3024 {
3025 stuff_float(&loop_snd_volume);
3026
3027 if (loop_snd_volume <= 0.0f)
3028 {
3029 Warning(LOCATION, "\"Loop Volume:\" value of \"%f\" is invalid! Must be more than zero! Resetting to default.", arrival_beep_delay);
3030 loop_snd_volume = 1.0f;
3031 }
3032 }
3033
3034 parse_game_sound("Arrival Beep Sound:", &arrival_beep_snd);
3035 parse_game_sound("Stealth arrival Beep Sound:", &stealth_arrival_snd);
3036
3037 if (optional_string("Minimum Beep Delay:"))
3038 {
3039 stuff_float(&arrival_beep_delay);
3040
3041 if (arrival_beep_delay < 0.0f)
3042 {
3043 Warning(LOCATION, "\"Minimum Beep Delay:\" value of \"%f\" is invalid! Must be more than or equal to zero! Resetting to default.", arrival_beep_delay);
3044 arrival_beep_delay = 0.0f;
3045 }
3046 }
3047
3048 parse_game_sound("Departure Beep Sound:", &departure_beep_snd);
3049 parse_game_sound("Stealth departure Beep Sound:", &stealth_departure_snd);
3050
3051 if (optional_string("Minimum Beep Delay:"))
3052 {
3053 stuff_float(&departure_beep_delay);
3054
3055 if (departure_beep_delay < 0.0f)
3056 {
3057 Warning(LOCATION, "\"Minimum Beep Delay:\" value of \"%f\" is invalid! Must be more than or equal to zero! Resetting to default.", departure_beep_delay);
3058 departure_beep_delay = 0.0f;
3059 }
3060 }
3061
3062 std::unique_ptr<HudGaugeRadarDradis> hud_gauge(new HudGaugeRadarDradis());
3063 hud_gauge->initBaseResolution(settings->base_res[0], settings->base_res[1]);
3064 hud_gauge->initPosition(settings->coords[0], settings->coords[1]);
3065 hud_gauge->initRadius(Radar_radius[0], Radar_radius[1]);
3066 hud_gauge->initBitmaps(xy_fname, xz_yz_fname, sweep_fname, target_fname, unknown_fname);
3067 hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
3068 hud_gauge->initFont(settings->font_num);
3069 hud_gauge->initSound(loop_snd, loop_snd_volume, arrival_beep_snd, departure_beep_snd, stealth_arrival_snd, stealth_departure_snd, arrival_beep_delay, departure_beep_delay);
3070 hud_gauge->initChase_view_only(settings->chase_view_only);
3071
3072 gauge_assign_common(settings, std::move(hud_gauge));
3073 }
3074
load_gauge_text_warnings(gauge_settings * settings)3075 void load_gauge_text_warnings(gauge_settings* settings)
3076 {
3077 settings->origin[0] = 0.5f;
3078 settings->origin[1] = 0.5f;
3079 settings->slew = true;
3080
3081 if(gr_screen.res == GR_640) {
3082 settings->offset[0] = 0;
3083 settings->offset[1] = -68;
3084 } else {
3085 settings->offset[0] = 0;
3086 settings->offset[1] = -109;
3087 }
3088
3089 auto hud_gauge = gauge_load_common<HudGaugeTextWarnings>(settings);
3090
3091 gauge_assign_common(settings, std::move(hud_gauge));
3092 }
3093
load_gauge_target_monitor(gauge_settings * settings)3094 void load_gauge_target_monitor(gauge_settings* settings)
3095 {
3096 int Viewport_size[2];
3097 int Viewport_offsets[2];
3098 int Integrity_bar_offsets[2];
3099 int Integrity_bar_h;
3100 int Status_offsets[2];
3101 int Name_offsets[2];
3102 int Class_offsets[2];
3103 int Dist_offsets[2];
3104 int Speed_offsets[2];
3105 int Cargo_string_offsets[2];
3106 int Hull_offsets[2];
3107 int Cargo_scan_start_offsets[2];
3108 int Cargo_scan_size[2];
3109
3110 int Subsys_name_offsets[2] = {0, 0};
3111 bool Use_subsys_name_offsets = false;
3112
3113 int Subsys_integrity_offsets[2] = {0, 0};
3114 bool Use_subsys_integrity_offsets = false;
3115
3116 int Disabled_status_offsets[2] = {0, 0};
3117 bool Use_disabled_status_offsets = false;
3118
3119 bool desaturate = false;
3120
3121 char fname_monitor[MAX_FILENAME_LEN] = "targetview1";
3122 char fname_integrity[MAX_FILENAME_LEN] = "targetview2";
3123 char fname_static[MAX_FILENAME_LEN] = "TargetStatic";
3124 char fname_monitor_mask[MAX_FILENAME_LEN] = "";
3125
3126 settings->origin[0] = 0.0f;
3127 settings->origin[1] = 1.0f;
3128
3129 if(gr_screen.res == GR_640) {
3130 settings->offset[0] = 5;
3131 settings->offset[1] = -161;
3132 } else {
3133 settings->offset[0] = 5;
3134 settings->offset[1] = -178;
3135 }
3136
3137 Viewport_size[0] = 131;
3138 Viewport_size[1] = 112;
3139 Viewport_offsets[0] = 3;
3140 Viewport_offsets[1] = 39;
3141
3142 Integrity_bar_offsets[0] = 133;
3143 Integrity_bar_offsets[1] = 52;
3144 Integrity_bar_h = 88;
3145 Status_offsets[0] = 107;
3146 Status_offsets[1] = 53;
3147
3148 Name_offsets[0] = 8;
3149 Name_offsets[1] = -3;
3150 Class_offsets[0] = 8;
3151 Class_offsets[1] = 7;
3152 Dist_offsets[0] = 8;
3153 Dist_offsets[1] = 18;
3154 Speed_offsets[0] = 85;
3155 Speed_offsets[1] = 18;
3156 Cargo_string_offsets[0] = 8;
3157 Cargo_string_offsets[1] = 30;
3158
3159 // remember, below coords describe the rightmost position of their respective sub-element, not leftmost like it usually does.
3160 Hull_offsets[0] = 134;
3161 Hull_offsets[1] = 42;
3162
3163 Cargo_scan_start_offsets[0] = 2;
3164 Cargo_scan_start_offsets[1] = 45;
3165 Cargo_scan_size[0] = 130;
3166 Cargo_scan_size[1] = 109;
3167
3168 auto hud_gauge = gauge_load_common<HudGaugeTargetBox>(settings);
3169
3170 if(optional_string("Monitor Filename:")) {
3171 stuff_string(fname_monitor, F_NAME, MAX_FILENAME_LEN);
3172 }
3173 if(optional_string("Monitor Alpha Mask Filename:")) {
3174 stuff_string(fname_monitor_mask, F_NAME, MAX_FILENAME_LEN);
3175 }
3176 if(optional_string("Integrity Bar Filename:")) {
3177 stuff_string(fname_integrity, F_NAME, MAX_FILENAME_LEN);
3178 }
3179 if(optional_string("Viewport Offsets:")) {
3180 stuff_int_list(Viewport_offsets, 2);
3181 }
3182 if(optional_string("Viewport Size:")) {
3183 stuff_int_list(Viewport_size, 2);
3184 }
3185 if(optional_string("Integrity Bar Offsets:")) {
3186 stuff_int_list(Integrity_bar_offsets, 2);
3187 }
3188 if(optional_string("Integrity Bar Foreground Clip Height:")) {
3189 stuff_int(&Integrity_bar_h);
3190 }
3191 if(optional_string("Status Offsets:")) {
3192 stuff_int_list(Status_offsets, 2);
3193 }
3194 if(optional_string("Name Offsets:")) {
3195 stuff_int_list(Name_offsets, 2);
3196 }
3197 if(optional_string("Class Offsets:")) {
3198 stuff_int_list(Class_offsets, 2);
3199 }
3200 if(optional_string("Distance Offsets:")) {
3201 stuff_int_list(Dist_offsets, 2);
3202 }
3203 if(optional_string("Speed Offsets:")) {
3204 stuff_int_list(Speed_offsets, 2);
3205 }
3206 if(optional_string("Hull Offsets:")) {
3207 stuff_int_list(Hull_offsets, 2);
3208 }
3209 if(optional_string("Cargo Contents Offsets:")) {
3210 stuff_int_list(Cargo_string_offsets, 2);
3211 }
3212 if(optional_string("Cargo Scan Start Offsets:")) {
3213 stuff_int_list(Cargo_scan_start_offsets, 2);
3214 }
3215 if(optional_string("Cargo Scan Size:")) {
3216 stuff_int_list(Cargo_scan_size, 2);
3217 }
3218 if ( optional_string("Subsystem Name Offsets:") ) {
3219 stuff_int_list(Subsys_name_offsets, 2);
3220 Use_subsys_name_offsets = true;
3221 }
3222 if ( optional_string("Subsystem Integrity Offsets:") ) {
3223 stuff_int_list(Subsys_integrity_offsets, 2);
3224 Use_subsys_integrity_offsets = true;
3225 }
3226 if ( optional_string("Disabled Status Offsets:") ) {
3227 stuff_int_list(Disabled_status_offsets, 2);
3228 Use_disabled_status_offsets = true;
3229 }
3230 if ( optional_string("Desaturate:") ) {
3231 stuff_boolean(&desaturate);
3232 }
3233
3234 hud_gauge->initViewportOffsets(Viewport_offsets[0], Viewport_offsets[1]);
3235 hud_gauge->initViewportSize(Viewport_size[0], Viewport_size[1]);
3236 hud_gauge->initIntegrityOffsets(Integrity_bar_offsets[0], Integrity_bar_offsets[1]);
3237 hud_gauge->initIntegrityHeight(Integrity_bar_h);
3238 hud_gauge->initStatusOffsets(Status_offsets[0], Status_offsets[1]);
3239 hud_gauge->initNameOffsets(Name_offsets[0], Name_offsets[1]);
3240 hud_gauge->initClassOffsets(Class_offsets[0], Class_offsets[1]);
3241 hud_gauge->initDistOffsets(Dist_offsets[0], Dist_offsets[1]);
3242 hud_gauge->initSpeedOffsets(Speed_offsets[0], Speed_offsets[1]);
3243 hud_gauge->initCargoStringOffsets(Cargo_string_offsets[0], Cargo_string_offsets[1]);
3244 hud_gauge->initHullOffsets(Hull_offsets[0], Hull_offsets[1]);
3245 hud_gauge->initCargoScanStartOffsets(Cargo_scan_start_offsets[0], Cargo_scan_start_offsets[1]);
3246 hud_gauge->initCargoScanSize(Cargo_scan_size[0], Cargo_scan_size[1]);
3247 hud_gauge->initSubsysNameOffsets(Subsys_name_offsets[0], Subsys_name_offsets[1], Use_subsys_name_offsets);
3248 hud_gauge->initSubsysIntegrityOffsets(Subsys_integrity_offsets[0], Subsys_integrity_offsets[1], Use_subsys_integrity_offsets);
3249 hud_gauge->initDisabledStatusOffsets(Disabled_status_offsets[0], Disabled_status_offsets[1], Use_disabled_status_offsets);
3250 hud_gauge->initDesaturate(desaturate);
3251 hud_gauge->initBitmaps(fname_monitor, fname_monitor_mask, fname_integrity, fname_static);
3252
3253 gauge_assign_common(settings, std::move(hud_gauge));
3254 }
3255
load_gauge_squad_message(gauge_settings * settings)3256 void load_gauge_squad_message(gauge_settings* settings)
3257 {
3258 int Pgup_offsets[2];
3259 int Pgdn_offsets[2];
3260 int Header_offsets[2];
3261 int Item_start_offsets[2];
3262 int Middle_frame_start_offset_y;
3263 int bottom_bg_offset = 0;
3264 int Item_h;
3265 int Item_offset_x;
3266 char fname_top[MAX_FILENAME_LEN] = "message1";
3267 char fname_middle[MAX_FILENAME_LEN] = "message2";
3268 char fname_bottom[MAX_FILENAME_LEN] = "message3";
3269
3270 settings->origin[0] = 1.0f;
3271 settings->origin[1] = 0.0f;
3272
3273 if(gr_screen.res == GR_640) {
3274 settings->offset[0] = -195;
3275 settings->offset[1] = 5;
3276
3277 Pgup_offsets[0] = 145;
3278 Pgup_offsets[1] = 4;
3279 Pgdn_offsets[0] = 145;
3280 Pgdn_offsets[1] = 115;
3281 } else {
3282 settings->offset[0] = -197;
3283 settings->offset[1] = 5;
3284
3285 Pgup_offsets[0] = 110;
3286 Pgup_offsets[1] = 5;
3287 Pgdn_offsets[0] = 110;
3288 Pgdn_offsets[1] = 115;
3289 }
3290
3291 Header_offsets[0] = 2;
3292 Header_offsets[1] = 1;
3293 Item_start_offsets[0] = 4;
3294 Item_start_offsets[1] = 13;
3295 Middle_frame_start_offset_y = 12;
3296 Item_h = 10;
3297 Item_offset_x = 17;
3298
3299 auto hud_gauge = gauge_load_common<HudGaugeSquadMessage>(settings);
3300
3301 if(optional_string("Top Background Filename:")) {
3302 stuff_string(fname_top, F_NAME, MAX_FILENAME_LEN);
3303 }
3304 if(optional_string("Entry Background Filename:")) {
3305 stuff_string(fname_middle, F_NAME, MAX_FILENAME_LEN);
3306 }
3307 if(optional_string("Bottom Background Filename:")) {
3308 stuff_string(fname_bottom, F_NAME, MAX_FILENAME_LEN);
3309 }
3310 if(optional_string("Header Offsets:")) {
3311 stuff_int_list(Header_offsets, 2);
3312 }
3313 if(optional_string("List Start Offsets:")) {
3314 stuff_int_list(Item_start_offsets, 2);
3315 }
3316 if(optional_string("Top Background Height:")) {
3317 stuff_int(&Middle_frame_start_offset_y);
3318 }
3319 if(optional_string("Entry Height:")) {
3320 stuff_int(&Item_h);
3321 }
3322 if(optional_string("Bottom Background Offset:")) {
3323 stuff_int(&bottom_bg_offset);
3324 }
3325 if(optional_string("Command X-offset:")) {
3326 stuff_int(&Item_offset_x);
3327 }
3328 if(optional_string("Page Up Offsets:")) {
3329 stuff_int_list(Pgup_offsets, 2);
3330 }
3331 if(optional_string("Page Down Offsets:")) {
3332 stuff_int_list(Pgdn_offsets, 2);
3333 }
3334
3335 hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
3336 hud_gauge->initHeaderOffsets(Header_offsets[0], Header_offsets[1]);
3337 hud_gauge->initItemStartOffsets(Item_start_offsets[0], Item_start_offsets[1]);
3338 hud_gauge->initMiddleFrameStartOffsetY(Middle_frame_start_offset_y);
3339 hud_gauge->initBottomBgOffset(bottom_bg_offset);
3340 hud_gauge->initItemHeight(Item_h);
3341 hud_gauge->initItemOffsetX(Item_offset_x);
3342 hud_gauge->initPgUpOffsets(Pgup_offsets[0], Pgup_offsets[1]);
3343 hud_gauge->initPgDnOffsets(Pgdn_offsets[0], Pgdn_offsets[1]);
3344
3345 gauge_assign_common(settings, std::move(hud_gauge));
3346 }
3347
load_gauge_objective_notify(gauge_settings * settings)3348 void load_gauge_objective_notify(gauge_settings* settings)
3349 {
3350 int Objective_text_offset_y;
3351 int Objective_text_val_offset_y;
3352 int Subspace_text_offset_y;
3353 int Subspace_text_val_offset_y;
3354 int Red_text_offset_y;
3355 int Red_text_val_offset_y;
3356 char fname[MAX_FILENAME_LEN] = "objective1";
3357
3358 settings->origin[0] = 0.5f;
3359 settings->origin[1] = 0.5f;
3360
3361 if(gr_screen.res == GR_640) {
3362 settings->offset[0] = -75;
3363 settings->offset[1] = -126;
3364
3365 Objective_text_offset_y = 2;
3366 Objective_text_val_offset_y = 11;
3367 Subspace_text_offset_y = 2;
3368 Subspace_text_val_offset_y = 10;
3369 Red_text_offset_y = 2;
3370 Red_text_val_offset_y = 10;
3371 } else {
3372 settings->offset[0] = -76;
3373 settings->offset[1] = -200;
3374
3375 Objective_text_offset_y = 2;
3376 Objective_text_val_offset_y = 11;
3377 Subspace_text_offset_y = 2;
3378 Subspace_text_val_offset_y = 10;
3379 Red_text_offset_y = 2;
3380 Red_text_val_offset_y = 10;
3381 }
3382
3383 auto hud_gauge = gauge_load_common<HudGaugeObjectiveNotify>(settings);
3384
3385 if(optional_string("Filename:")) {
3386 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
3387 }
3388 if(optional_string("Objective Text Y-offset:")) {
3389 stuff_int(&Objective_text_offset_y);
3390 }
3391 if(optional_string("Objective Value Y-offset:")) {
3392 stuff_int(&Objective_text_val_offset_y);
3393 }
3394 if(optional_string("Subspace Text Y-offset:")) {
3395 stuff_int(&Subspace_text_offset_y);
3396 }
3397 if(optional_string("Subspace Value Y-offset:")) {
3398 stuff_int(&Subspace_text_val_offset_y);
3399 }
3400 if(optional_string("Red Alert Text Y-offset:")) {
3401 stuff_int(&Red_text_offset_y);
3402 }
3403 if(optional_string("Red Alert Value Y-offset:")) {
3404 stuff_int(&Red_text_val_offset_y);
3405 }
3406
3407 hud_gauge->initBitmaps(fname);
3408 hud_gauge->initObjTextOffsetY(Objective_text_offset_y);
3409 hud_gauge->initObjValueOffsetY(Objective_text_val_offset_y);
3410 hud_gauge->initSubspaceTextOffsetY(Subspace_text_offset_y);
3411 hud_gauge->initSubspaceValueOffsetY(Subspace_text_val_offset_y);
3412 hud_gauge->initRedAlertTextOffsetY(Red_text_offset_y);
3413 hud_gauge->initRedAlertValueOffsetY(Red_text_val_offset_y);
3414
3415 gauge_assign_common(settings, std::move(hud_gauge));
3416 }
3417
load_gauge_weapons(gauge_settings * settings)3418 void load_gauge_weapons(gauge_settings* settings)
3419 {
3420 int top_offset_x[NUM_HUD_SETTINGS];
3421 int Weapon_header_offsets[NUM_HUD_SETTINGS][2];
3422 int frame_offset_x[NUM_HUD_SETTINGS];
3423 int Weapon_plink_offset_x;
3424 int Weapon_pname_offset_x;
3425 int Weapon_pammo_offset_x;
3426 int Weapon_sammo_offset_x;
3427 int Weapon_sname_offset_x;
3428 int Weapon_sreload_offset_x;
3429 int Weapon_slinked_offset_x;
3430 int Weapon_sunlinked_offset_x;
3431 int top_primary_h;
3432 int top_secondary_h;
3433 int pname_start_offset_y;
3434 int sname_start_offset_y;
3435 int primary_text_h;
3436 int secondary_text_h;
3437
3438 // thank god both GR640 and GR1024 use the same weapons gauge bitmaps
3439 char fname_p_top[MAX_FILENAME_LEN] = "weapons1";
3440 char fname_p_top_b[MAX_FILENAME_LEN] = "weapons1_b";
3441 char fname_p_middle[MAX_FILENAME_LEN] = "weapons2";
3442 char fname_p_middle_b[MAX_FILENAME_LEN] = "weapons2_b";
3443 char fname_p_last[MAX_FILENAME_LEN] = "weapons6";
3444 // The bottom portion of the primary weapons listing for the ballistic ammo version of this gauge can simply use the middle portion.
3445 char fname_p_last_b[MAX_FILENAME_LEN] = "weapons2_b";
3446 char fname_s_top[MAX_FILENAME_LEN] = "weapons3";
3447 char fname_s_top_b[MAX_FILENAME_LEN] = "weapons3_b";
3448 char fname_s_middle[MAX_FILENAME_LEN] = "weapons4";
3449 char fname_s_middle_b[MAX_FILENAME_LEN] = "weapons4_b";
3450 char fname_s_bottom[MAX_FILENAME_LEN] = "weapons5";
3451 char fname_s_bottom_b[MAX_FILENAME_LEN] = "weapons5_b";
3452
3453 settings->origin[0] = 1.0f;
3454 settings->origin[1] = 1.0f;
3455
3456 if(gr_screen.res == GR_640) {
3457 settings->offset[0] = -143;
3458 settings->offset[1] = -228;
3459 } else {
3460 settings->offset[0] = -144;
3461 settings->offset[1] = -257;
3462 }
3463
3464 top_offset_x[0] = 12;
3465 top_offset_x[1] = -12;
3466
3467 Weapon_header_offsets[0][0] = 21;
3468 Weapon_header_offsets[0][1] = 2;
3469 Weapon_header_offsets[1][0] = -10;
3470 Weapon_header_offsets[1][1] = 2;
3471
3472 frame_offset_x[0] = 0;
3473 frame_offset_x[1] = -12;
3474
3475 Weapon_plink_offset_x = 33;
3476 Weapon_pname_offset_x = 39;
3477 Weapon_pammo_offset_x = 28;
3478 Weapon_sammo_offset_x = 28;
3479 Weapon_sname_offset_x = 39;
3480 Weapon_sreload_offset_x = 118;
3481 Weapon_slinked_offset_x = 28;
3482 Weapon_sunlinked_offset_x = 33;
3483
3484 top_primary_h = 20;
3485 top_secondary_h = 12;
3486 pname_start_offset_y = 12;
3487 sname_start_offset_y = 4;
3488
3489 primary_text_h = 12;
3490 secondary_text_h = 9;
3491
3492 auto hud_gauge = gauge_load_common<HudGaugeWeapons>(settings);
3493
3494 if(optional_string("Primary List Top Background Filename:")) {
3495 stuff_string(fname_p_top, F_NAME, MAX_FILENAME_LEN);
3496 if(optional_string("Alt Ballistic Filename:")) {
3497 stuff_string(fname_p_top_b, F_NAME, MAX_FILENAME_LEN);
3498 }
3499 }
3500 if(optional_string("Primary List Middle Background Filename:")) {
3501 stuff_string(fname_p_middle, F_NAME, MAX_FILENAME_LEN);
3502 if(optional_string("Alt Ballistic Filename:")) {
3503 stuff_string(fname_p_middle_b, F_NAME, MAX_FILENAME_LEN);
3504 }
3505 }
3506 if(optional_string("Primary List Bottom Background Filename:")) {
3507 stuff_string(fname_p_last, F_NAME, MAX_FILENAME_LEN);
3508 if(optional_string("Alt Ballistic Filename:")) {
3509 stuff_string(fname_p_last_b, F_NAME, MAX_FILENAME_LEN);
3510 }
3511 }
3512 if(optional_string("Secondary List Top Background Filename:")) {
3513 stuff_string(fname_s_top, F_NAME, MAX_FILENAME_LEN);
3514 if(optional_string("Alt Ballistic Filename:")) {
3515 stuff_string(fname_s_top_b, F_NAME, MAX_FILENAME_LEN);
3516 }
3517 }
3518 if(optional_string("Secondary List Entry Background Filename:")) {
3519 stuff_string(fname_s_middle, F_NAME, MAX_FILENAME_LEN);
3520 if(optional_string("Alt Ballistic Filename:")) {
3521 stuff_string(fname_s_middle_b, F_NAME, MAX_FILENAME_LEN);
3522 }
3523 }
3524 if(optional_string("Secondary List Bottom Background Filename:")) {
3525 stuff_string(fname_s_bottom, F_NAME, MAX_FILENAME_LEN);
3526 if(optional_string("Alt Ballistic Filename:")) {
3527 stuff_string(fname_s_bottom_b, F_NAME, MAX_FILENAME_LEN);
3528 }
3529 }
3530 if(optional_string("Header Offsets:")) {
3531 stuff_int_list(Weapon_header_offsets[0], 2);
3532 if(optional_string("Alt Ballistic Offsets:")) {
3533 stuff_int_list(Weapon_header_offsets[1], 2);
3534 }
3535 }
3536 if(optional_string("Top Primary Background X-offset:")) {
3537 stuff_int(&top_offset_x[0]);
3538 if(optional_string("Alt Ballistic X-offset:")) {
3539 stuff_int(&top_offset_x[1]);
3540 }
3541 }
3542 if(optional_string("Text X-offset:")) {
3543 stuff_int(&frame_offset_x[0]);
3544 if(optional_string("Alt Ballistic X-offset:")) {
3545 stuff_int(&frame_offset_x[1]);
3546 }
3547 }
3548 if(optional_string("Top Primary Frame Height:")) {
3549 stuff_int(&top_primary_h);
3550 }
3551 if(optional_string("Top Secondary Frame Height:")) {
3552 stuff_int(&top_secondary_h);
3553 }
3554 if(optional_string("Primary List Start Y-offset:")) {
3555 stuff_int(&pname_start_offset_y);
3556 }
3557 if(optional_string("Secondary List Start Y-offset:")) {
3558 stuff_int(&sname_start_offset_y);
3559 }
3560 if(optional_string("Primary Weapon Ammo X-offset:")) {
3561 stuff_int(&Weapon_pammo_offset_x);
3562 }
3563 if(optional_string("Primary Weapon Link X-offset:")) {
3564 stuff_int(&Weapon_plink_offset_x);
3565 }
3566 if(optional_string("Primary Weapon Name X-offset:")) {
3567 stuff_int(&Weapon_pname_offset_x);
3568 }
3569 if(optional_string("Secondary Weapon Ammo X-offset:")) {
3570 stuff_int(&Weapon_sammo_offset_x);
3571 }
3572 if(optional_string("Secondary Weapon Unlinked X-offset:")) {
3573 stuff_int(&Weapon_sunlinked_offset_x);
3574 }
3575 if(optional_string("Secondary Weapon Linked X-offset:")) {
3576 stuff_int(&Weapon_slinked_offset_x);
3577 }
3578 if(optional_string("Secondary Weapon Name X-offset:")) {
3579 stuff_int(&Weapon_sname_offset_x);
3580 }
3581 if(optional_string("Secondary Weapon Reload X-offset:")) {
3582 stuff_int(&Weapon_sreload_offset_x);
3583 }
3584 if(optional_string("Primary Weapon Entry Height:")) {
3585 stuff_int(&primary_text_h);
3586 }
3587 if(optional_string("Secondary Weapon Entry Height:")) {
3588 stuff_int(&secondary_text_h);
3589 }
3590
3591 hud_gauge->initBitmapsPrimaryTop(fname_p_top, fname_p_top_b);
3592 hud_gauge->initBitmapsPrimaryMiddle(fname_p_middle, fname_p_middle_b);
3593 hud_gauge->initBitmapsPrimaryLast(fname_p_last, fname_p_last_b);
3594 hud_gauge->initBitmapsSecondaryTop(fname_s_top, fname_s_top_b);
3595 hud_gauge->initBitmapsSecondaryMiddle(fname_s_middle, fname_s_middle_b);
3596 hud_gauge->initBitmapsSecondaryBottom(fname_s_bottom, fname_s_bottom_b);
3597 hud_gauge->initTopOffsetX(top_offset_x[0], top_offset_x[1]);
3598 hud_gauge->initHeaderOffsets(Weapon_header_offsets[0][0], Weapon_header_offsets[0][1],
3599 Weapon_header_offsets[1][0], Weapon_header_offsets[1][1]);
3600 hud_gauge->initFrameOffsetX(frame_offset_x[0], frame_offset_x[1]);
3601 hud_gauge->initStartNameOffsetsY(pname_start_offset_y, sname_start_offset_y);
3602 hud_gauge->initPrimaryWeaponOffsets(Weapon_plink_offset_x, Weapon_pname_offset_x, Weapon_pammo_offset_x);
3603 hud_gauge->initSecondaryWeaponOffsets(Weapon_sammo_offset_x, Weapon_sname_offset_x, Weapon_sreload_offset_x, Weapon_slinked_offset_x, Weapon_sunlinked_offset_x);
3604 hud_gauge->initPrimaryHeights(top_primary_h, primary_text_h);
3605 hud_gauge->initSecondaryHeights(top_secondary_h, secondary_text_h);
3606 hud_gauge->initLinkIcon();
3607
3608 gauge_assign_common(settings, std::move(hud_gauge));
3609 }
3610
load_gauge_directives(gauge_settings * settings)3611 void load_gauge_directives(gauge_settings* settings)
3612 {
3613 int header_offsets[2];
3614 int middle_frame_offset_y;
3615 int text_start_offsets[2];
3616 int text_h;
3617 int max_line_width = 167;
3618 char fname_top[MAX_FILENAME_LEN] = "directives1";
3619 char fname_middle[MAX_FILENAME_LEN] = "directives2";
3620 char fname_bottom[MAX_FILENAME_LEN] = "directives3";
3621 int bottom_bg_offset = 0;
3622
3623 settings->origin[0] = 0.0f;
3624 settings->origin[1] = 0.5f;
3625
3626 if(gr_screen.res == GR_640) {
3627 settings->offset[0] = 5;
3628 settings->offset[1] = -62;
3629 } else {
3630 settings->offset[0] = 5;
3631 settings->offset[1] = -106;
3632 }
3633
3634 header_offsets[0] = 2;
3635 header_offsets[1] = 2;
3636 middle_frame_offset_y = 12;
3637 text_start_offsets[0] = 3;
3638 text_start_offsets[1] = 14;
3639 text_h = 9;
3640
3641 auto hud_gauge = gauge_load_common<HudGaugeDirectives>(settings);
3642
3643 if(optional_string("Top Background Filename:")) {
3644 stuff_string(fname_top, F_NAME, MAX_FILENAME_LEN);
3645 }
3646 if(optional_string("Entry Background Filename:")) {
3647 stuff_string(fname_middle, F_NAME, MAX_FILENAME_LEN);
3648 }
3649 if(optional_string("Bottom Background Filename:")) {
3650 stuff_string(fname_bottom, F_NAME, MAX_FILENAME_LEN);
3651 }
3652 if(optional_string("Header Offsets:")) {
3653 stuff_int_list(header_offsets, 2);
3654 }
3655 if(optional_string("Top Background Height:")) {
3656 stuff_int(&middle_frame_offset_y);
3657 }
3658 if(optional_string("List Start Offsets:")) {
3659 stuff_int_list(text_start_offsets, 2);
3660 }
3661 if(optional_string("Entry Height:")) {
3662 stuff_int(&text_h);
3663 }
3664 if(optional_string("Bottom Background Offset:")) {
3665 stuff_int(&bottom_bg_offset);
3666 }
3667 if ( optional_string("Max Line Width:") ) {
3668 stuff_int(&max_line_width);
3669 }
3670
3671 hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
3672 hud_gauge->initMiddleFrameOffsetY(middle_frame_offset_y);
3673 hud_gauge->initTextHeight(text_h);
3674 hud_gauge->initBottomBgOffset(bottom_bg_offset);
3675 hud_gauge->initTextStartOffsets(text_start_offsets[0], text_start_offsets[1]);
3676 hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
3677 hud_gauge->initMaxLineWidth(max_line_width);
3678
3679 gauge_assign_common(settings, std::move(hud_gauge));
3680 }
3681
load_gauge_talking_head(gauge_settings * settings)3682 void load_gauge_talking_head(gauge_settings* settings)
3683 {
3684 int Header_offsets[2];
3685 int Anim_offsets[2];
3686 int Anim_size[2];
3687 char fname[MAX_FILENAME_LEN] = "head1";
3688
3689 settings->origin[0] = 0.0f;
3690 settings->origin[1] = 0.0f;
3691
3692 if(gr_screen.res == GR_640) {
3693 settings->offset[0] = 5;
3694 settings->offset[1] = 35;
3695 } else {
3696 settings->offset[0] = 5;
3697 settings->offset[1] = 56;
3698 }
3699
3700 Header_offsets[0] = 2;
3701 Header_offsets[1] = 2;
3702 Anim_offsets[0] = 2;
3703 Anim_offsets[1] = 10;
3704 Anim_size[0] = 160;
3705 Anim_size[1] = 120;
3706
3707 auto hud_gauge = gauge_load_common<HudGaugeTalkingHead>(settings);
3708
3709 if(optional_string("Filename:")) {
3710 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
3711 }
3712 if(optional_string("Header Offsets:")) {
3713 stuff_int_list(Header_offsets, 2);
3714 }
3715 if(optional_string("Animation Offsets:")) {
3716 stuff_int_list(Anim_offsets, 2);
3717 }
3718 if(optional_string("Animation Background Size:")) {
3719 mprintf(("Animation Background Size in hud_gauges.tbl and -hdg.tbms is deprecated. Use \"Animation Size\" instead.\n"));
3720 stuff_int_list(Anim_size, 2);
3721 }
3722 if(optional_string("Animation Size:")) {
3723 stuff_int_list(Anim_size, 2);
3724 }
3725
3726 hud_gauge->initAnimOffsets(Anim_offsets[0], Anim_offsets[1]);
3727 hud_gauge->initAnimSizes(Anim_size[0], Anim_size[1]);
3728 hud_gauge->initBitmaps(fname);
3729 hud_gauge->initHeaderOffsets(Header_offsets[0], Header_offsets[1]);
3730
3731 gauge_assign_common(settings, std::move(hud_gauge));
3732 }
3733
load_gauge_countermeasures(gauge_settings * settings)3734 void load_gauge_countermeasures(gauge_settings* settings)
3735 {
3736 int cm_text_offset[2];
3737 int cm_text_val_offset[2];
3738 char fname[MAX_FILENAME_LEN] = "countermeasure1";
3739
3740 settings->origin[0] = 1.0f;
3741 settings->origin[1] = 1.0f;
3742
3743 if(gr_screen.res == GR_640) {
3744 settings->offset[0] = -143;
3745 settings->offset[1] = -137;
3746 } else {
3747 settings->offset[0] = -144;
3748 settings->offset[1] = -166;
3749 }
3750 cm_text_offset[0] = 36;
3751 cm_text_offset[1] = 4;
3752 cm_text_val_offset[0] = 9;
3753 cm_text_val_offset[1] = 4;
3754
3755 auto hud_gauge = gauge_load_common<HudGaugeCmeasures>(settings);
3756
3757 if(optional_string("Filename:")) {
3758 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
3759 }
3760 if(optional_string("Text Offsets:")) {
3761 stuff_int_list(cm_text_offset, 2);
3762 }
3763 if(optional_string("Value Offsets:")) {
3764 stuff_int_list(cm_text_val_offset, 2);
3765 }
3766
3767 hud_gauge->initBitmaps(fname);
3768 hud_gauge->initCountTextOffsets(cm_text_offset[0], cm_text_offset[1]);
3769 hud_gauge->initCountValueOffsets(cm_text_val_offset[0], cm_text_val_offset[1]);
3770
3771 gauge_assign_common(settings, std::move(hud_gauge));
3772 }
3773
load_gauge_auto_target(gauge_settings * settings)3774 void load_gauge_auto_target(gauge_settings* settings)
3775 {
3776 int auto_text_offset[2];
3777 int target_text_offset[2];
3778 char fname[MAX_FILENAME_LEN] = "toggle1";
3779
3780 int on_color[4] = {0, 0, 0, 255};
3781 int off_color[4] = {-1, -1, -1, -1};
3782
3783 settings->origin[0] = 1.0f;
3784 settings->origin[1] = 1.0f;
3785
3786 if(gr_screen.res == GR_640) {
3787 settings->offset[0] = -63;
3788 settings->offset[1] = -100;
3789 } else {
3790 settings->offset[0] = -64;
3791 settings->offset[1] = -120;
3792 }
3793
3794 auto_text_offset[0] = 13;
3795 auto_text_offset[1] = 2;
3796 if (Lcl_pl) {
3797 target_text_offset[0] = 2;
3798 target_text_offset[1] = 10;
3799 } else {
3800 target_text_offset[0] = 7;
3801 target_text_offset[1] = 10;
3802 }
3803
3804 auto hud_gauge = gauge_load_common<HudGaugeAutoTarget>(settings);
3805
3806 if(optional_string("Filename:")) {
3807 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
3808 }
3809 if(optional_string("Auto Offsets:")) {
3810 stuff_int_list(auto_text_offset, 2);
3811 }
3812 if(optional_string("Target Offsets:")) {
3813 stuff_int_list(target_text_offset, 2);
3814 }
3815
3816 if ( optional_string("On Text Color:") ) {
3817 stuff_int_list(on_color, 4);
3818 }
3819
3820 if ( optional_string("Off Text Color:") ) {
3821 stuff_int_list(off_color, 4);
3822 }
3823
3824 hud_gauge->initAutoTextOffsets(auto_text_offset[0], auto_text_offset[1]);
3825 hud_gauge->initBitmaps(fname);
3826 hud_gauge->initTargetTextOffsets(target_text_offset[0], target_text_offset[1]);
3827 hud_gauge->initOnColor(on_color[0], on_color[1], on_color[2], on_color[3]);
3828 hud_gauge->initOffColor(off_color[0], off_color[1], off_color[2], off_color[3]);
3829
3830 gauge_assign_common(settings, std::move(hud_gauge));
3831 }
3832
load_gauge_auto_speed(gauge_settings * settings)3833 void load_gauge_auto_speed(gauge_settings* settings)
3834 {
3835 int auto_text_offset[2];
3836 int speed_text_offset[2];
3837 char fname[MAX_FILENAME_LEN] = "toggle1";
3838 int on_color[4] = {0, 0, 0, 255};
3839 int off_color[4] = {-1, -1, -1, -1};
3840
3841 settings->origin[0] = 1.0f;
3842 settings->origin[1] = 1.0f;
3843
3844 if(gr_screen.res == GR_640) {
3845 settings->offset[0] = -63;
3846 settings->offset[1] = -76;
3847 } else {
3848 settings->offset[0] = -64;
3849 settings->offset[1] = -96;
3850 }
3851
3852 auto_text_offset[0] = 13;
3853 auto_text_offset[1] = 2;
3854 if (Lcl_pl) {
3855 speed_text_offset[0] = 9;
3856 speed_text_offset[1] = 10;
3857 } else {
3858 speed_text_offset[0] = 10;
3859 speed_text_offset[1] = 10;
3860 }
3861
3862 auto hud_gauge = gauge_load_common<HudGaugeAutoSpeed>(settings);
3863
3864 if(optional_string("Filename:")) {
3865 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
3866 }
3867 if(optional_string("Auto Offsets:")) {
3868 stuff_int_list(auto_text_offset, 2);
3869 }
3870 if(optional_string("Speed Offsets:")) {
3871 stuff_int_list(speed_text_offset, 2);
3872 }
3873
3874 if ( optional_string("On Text Color:") ) {
3875 stuff_int_list(on_color, 4);
3876 }
3877
3878 if ( optional_string("Off Text Color:") ) {
3879 stuff_int_list(off_color, 4);
3880 }
3881
3882 hud_gauge->initAutoTextOffsets(auto_text_offset[0], auto_text_offset[1]);
3883 hud_gauge->initBitmaps(fname);
3884 hud_gauge->initSpeedTextOffsets(speed_text_offset[0], speed_text_offset[1]);
3885 hud_gauge->initOnColor(on_color[0], on_color[1], on_color[2], on_color[3]);
3886 hud_gauge->initOffColor(off_color[0], off_color[1], off_color[2], off_color[3]);
3887
3888 gauge_assign_common(settings, std::move(hud_gauge));
3889 }
3890
load_gauge_wingman_status(gauge_settings * settings)3891 void load_gauge_wingman_status(gauge_settings* settings)
3892 {
3893 int header_offsets[2];
3894 bool fixed_header_position;
3895 int left_frame_end_x;
3896
3897 int single_wing_offsets[2];
3898 int multiple_wing_offsets[2];
3899 int wing_width;
3900 int right_bg_offset = 0;
3901 int wing_name_offsets[2];
3902
3903 int wingmate_offsets[MAX_SHIPS_PER_WING][2];
3904 char fname_left[MAX_FILENAME_LEN] = "wingman1";
3905 char fname_middle[MAX_FILENAME_LEN] = "wingman2";
3906 char fname_right[MAX_FILENAME_LEN] = "wingman3";
3907 char fname_dots[MAX_FILENAME_LEN] = "wingman4";
3908 // "wingman5" isn't used anymore since Goober implemented string based wing names
3909
3910 settings->origin[0] = 1.0f;
3911 settings->origin[1] = 0.0f;
3912
3913 if(gr_screen.res == GR_640) {
3914 settings->offset[0] = -90;
3915 settings->offset[1] = 144;
3916 } else {
3917 settings->offset[0] = -92;
3918 settings->offset[1] = 144;
3919 }
3920
3921 header_offsets[0] = 2;
3922 header_offsets[1] = 2;
3923 fixed_header_position = false;
3924 left_frame_end_x = 71;
3925
3926 single_wing_offsets[0] = 28;
3927 single_wing_offsets[1] = 15;
3928 multiple_wing_offsets[0] = 46;
3929 multiple_wing_offsets[1] = 15;
3930 wing_width = 35;
3931 wing_name_offsets[0] = 15;
3932 wing_name_offsets[1] = 26;
3933
3934 wingmate_offsets[0][0] = 11;
3935 wingmate_offsets[0][1] = 0;
3936 wingmate_offsets[1][0] = 4;
3937 wingmate_offsets[1][1] = 8;
3938 wingmate_offsets[2][0] = 18;
3939 wingmate_offsets[2][1] = 8;
3940 wingmate_offsets[3][0] = 11;
3941 wingmate_offsets[3][1] = 16;
3942 wingmate_offsets[4][0] = 0;
3943 wingmate_offsets[4][1] = 16;
3944 wingmate_offsets[5][0] = 22;
3945 wingmate_offsets[5][1] = 16;
3946
3947 auto hud_gauge = gauge_load_common<HudGaugeWingmanStatus>(settings);
3948
3949 if(optional_string("Left Background Filename:")) {
3950 stuff_string(fname_left, F_NAME, MAX_FILENAME_LEN);
3951 }
3952 if(optional_string("First Background Filename:")) {
3953 stuff_string(fname_left, F_NAME, MAX_FILENAME_LEN);
3954 }
3955 if(optional_string("Entry Background Filename:")) {
3956 stuff_string(fname_middle, F_NAME, MAX_FILENAME_LEN);
3957 }
3958 if(optional_string("Right Background Filename:") || optional_string("Last Background Filename:")) {
3959 stuff_string(fname_right, F_NAME, MAX_FILENAME_LEN);
3960 }
3961 if(optional_string("Dot Filename:")) {
3962 stuff_string(fname_dots, F_NAME, MAX_FILENAME_LEN);
3963 }
3964 if(optional_string("Header Offsets:")) {
3965 stuff_int_list(header_offsets, 2);
3966 }
3967 if(optional_string("Fixed Header Position:")) {
3968 stuff_boolean(&fixed_header_position);
3969 }
3970 if(optional_string("Left Background Width:")) {
3971 stuff_int(&left_frame_end_x);
3972 }
3973 if(optional_string("First Background Size:")) {
3974 stuff_int(&left_frame_end_x);
3975 }
3976 if(optional_string("Entry Width:")) {
3977 stuff_int(&wing_width);
3978 }
3979 if(optional_string("Entry Size:")) {
3980 stuff_int(&wing_width);
3981 }
3982 if(optional_string("Right Background Offset:") || optional_string("Last Background Offset:")) {
3983 stuff_int(&right_bg_offset);
3984 }
3985 if(optional_string("Single Wing Offsets:")) {
3986 stuff_int_list(single_wing_offsets, 2);
3987 }
3988 if(optional_string("Multiple Wing Start Offsets:")) {
3989 stuff_int_list(multiple_wing_offsets, 2);
3990 }
3991 if(optional_string("Wing Name Offsets:")) {
3992 stuff_int_list(wing_name_offsets, 2);
3993 }
3994 if(optional_string("Dot Offsets:")) {
3995 stuff_int_list(wingmate_offsets[0], 2);
3996 stuff_int_list(wingmate_offsets[1], 2);
3997 stuff_int_list(wingmate_offsets[2], 2);
3998 stuff_int_list(wingmate_offsets[3], 2);
3999 stuff_int_list(wingmate_offsets[4], 2);
4000 stuff_int_list(wingmate_offsets[5], 2);
4001 }
4002
4003 int grow_mode = 0; //By default, expand the gauge to the left (in -x direction)
4004
4005 if(optional_string("Expansion Mode:")) {
4006 if(optional_string("Right"))
4007 grow_mode = 1;
4008 else if(optional_string("Down"))
4009 grow_mode = 2;
4010 }
4011
4012 hud_gauge->initBitmaps(fname_left, fname_middle, fname_right, fname_dots);
4013 hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
4014 hud_gauge->initFixedHeaderPosition(fixed_header_position);
4015 hud_gauge->initLeftFrameEndX(left_frame_end_x);
4016 hud_gauge->initMultipleWingOffsets(multiple_wing_offsets[0], multiple_wing_offsets[1]);
4017 hud_gauge->initSingleWingOffsets(single_wing_offsets[0], single_wing_offsets[1]);
4018 hud_gauge->initWingmate1Offsets(wingmate_offsets[0][0], wingmate_offsets[0][1]);
4019 hud_gauge->initWingmate2Offsets(wingmate_offsets[1][0], wingmate_offsets[1][1]);
4020 hud_gauge->initWingmate3Offsets(wingmate_offsets[2][0], wingmate_offsets[2][1]);
4021 hud_gauge->initWingmate4Offsets(wingmate_offsets[3][0], wingmate_offsets[3][1]);
4022 hud_gauge->initWingmate5Offsets(wingmate_offsets[4][0], wingmate_offsets[4][1]);
4023 hud_gauge->initWingmate6Offsets(wingmate_offsets[5][0], wingmate_offsets[5][1]);
4024 hud_gauge->initWingNameOffsets(wing_name_offsets[0], wing_name_offsets[1]);
4025 hud_gauge->initWingWidth(wing_width);
4026 hud_gauge->initRightBgOffset(right_bg_offset);
4027 hud_gauge->initGrowMode(grow_mode);
4028
4029 gauge_assign_common(settings, std::move(hud_gauge));
4030 }
4031
load_gauge_damage(gauge_settings * settings)4032 void load_gauge_damage(gauge_settings* settings)
4033 {
4034 int header_offsets[2];
4035 int hull_integ_offsets[2];
4036 int hull_integ_val_offset_x;
4037 int middle_frame_start_offset_y;
4038 int subsys_integ_start_offsets[2];
4039 int subsys_integ_val_offset_x;
4040 int bottom_bg_offset = 0;
4041 int line_h;
4042 char fname_top[MAX_FILENAME_LEN] = "damage1";
4043 char fname_middle[MAX_FILENAME_LEN] = "damage2";
4044 char fname_bottom[MAX_FILENAME_LEN] = "damage3";
4045
4046 settings->origin[0] = 0.5f;
4047 settings->origin[1] = 0.0f;
4048
4049 if(gr_screen.res == GR_640) {
4050 settings->offset[0] = -75;
4051 settings->offset[1] = 38;
4052 } else {
4053 settings->offset[0] = -72;
4054 settings->offset[1] = 61;
4055 }
4056 header_offsets[0] = 3;
4057 header_offsets[1] = 2;
4058 hull_integ_offsets[0] = 4;
4059 hull_integ_offsets[1] = 15;
4060 hull_integ_val_offset_x = 142;
4061 middle_frame_start_offset_y = 25;
4062 subsys_integ_start_offsets[0] = 4;
4063 subsys_integ_start_offsets[1] = 27;
4064 subsys_integ_val_offset_x = 142;
4065 line_h = 9;
4066
4067 auto hud_gauge = gauge_load_common<HudGaugeDamage>(settings);
4068
4069 if(optional_string("Top Background Filename:")) {
4070 stuff_string(fname_top, F_NAME, MAX_FILENAME_LEN);
4071 }
4072 if(optional_string("Entry Background Filename:")) {
4073 stuff_string(fname_middle, F_NAME, MAX_FILENAME_LEN);
4074 }
4075 if(optional_string("Bottom Background Filename:")) {
4076 stuff_string(fname_bottom, F_NAME, MAX_FILENAME_LEN);
4077 }
4078 if(optional_string("Header Offsets:")) {
4079 stuff_int_list(header_offsets, 2);
4080 }
4081 if(optional_string("Hull Integrity Offsets:")) {
4082 stuff_int_list(hull_integ_offsets, 2);
4083 }
4084 if(optional_string("Hull Integrity Value X-offset:")) {
4085 stuff_int(&hull_integ_val_offset_x);
4086 }
4087 if(optional_string("Top Background Height:")) {
4088 stuff_int(&middle_frame_start_offset_y);
4089 }
4090 if(optional_string("Subsystem Entry Height:")) {
4091 stuff_int(&line_h);
4092 }
4093 if(optional_string("Subsystem List Start Offsets:")) {
4094 stuff_int_list(subsys_integ_start_offsets, 2);
4095 }
4096 if(optional_string("Subsystem Entry Value X-offset:")) {
4097 stuff_int(&subsys_integ_val_offset_x);
4098 }
4099 if(optional_string("Bottom Background Offset:")) {
4100 stuff_int(&bottom_bg_offset);
4101 }
4102
4103 hud_gauge->initBitmaps(fname_top, fname_middle, fname_bottom);
4104 hud_gauge->initHullIntegOffsets(hull_integ_offsets[0], hull_integ_offsets[1]);
4105 hud_gauge->initHullIntegValueOffsetX(hull_integ_val_offset_x);
4106 hud_gauge->initLineHeight(line_h);
4107 hud_gauge->initMiddleFrameStartOffsetY(middle_frame_start_offset_y);
4108 hud_gauge->initSubsysIntegStartOffsets(subsys_integ_start_offsets[0], subsys_integ_start_offsets[1]);
4109 hud_gauge->initSubsysIntegValueOffsetX(subsys_integ_val_offset_x);
4110 hud_gauge->initBottomBgOffset(bottom_bg_offset);
4111 hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
4112
4113 gauge_assign_common(settings, std::move(hud_gauge));
4114 }
4115
load_gauge_support(gauge_settings * settings)4116 void load_gauge_support(gauge_settings* settings)
4117 {
4118 int header_offsets[2];
4119 int text_val_offset_y;
4120 int text_dock_offset_x;
4121 int text_dock_val_offset_x;
4122 char fname[MAX_FILENAME_LEN] = "support1";
4123
4124 settings->origin[0] = 0.5f;
4125 settings->origin[1] = 0.5f;
4126
4127 if(gr_screen.res == GR_640) {
4128 settings->offset[0] = -55;
4129 settings->offset[1] = 94;
4130
4131 header_offsets[0] = 2;
4132 header_offsets[1] = 1;
4133 text_val_offset_y = 14;
4134 text_dock_offset_x = 5;
4135 text_dock_val_offset_x = 63;
4136 } else {
4137 settings->offset[0] = -53;
4138 settings->offset[1] = 150;
4139
4140 header_offsets[0] = 3;
4141 header_offsets[1] = 2;
4142 text_val_offset_y = 12;
4143 text_dock_offset_x = 6;
4144 text_dock_val_offset_x = 65;
4145 }
4146
4147 auto hud_gauge = gauge_load_common<HudGaugeSupport>(settings);
4148
4149 if(optional_string("Filename:")) {
4150 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
4151 }
4152 if(optional_string("Header Offsets:")) {
4153 stuff_int_list(header_offsets, 2);
4154 }
4155 if(optional_string("Text Y-offset:")) {
4156 stuff_int(&text_val_offset_y);
4157 }
4158 if(optional_string("Dock Status X-offset:")) {
4159 stuff_int(&text_dock_offset_x);
4160 }
4161 if(optional_string("Dock Time X-offset:")) {
4162 stuff_int(&text_dock_val_offset_x);
4163 }
4164
4165 hud_gauge->initBitmaps(fname);
4166 hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
4167 hud_gauge->initTextDockOffsetX(text_dock_offset_x);
4168 hud_gauge->initTextDockValueOffsetX(text_dock_val_offset_x);
4169 hud_gauge->initTextValueOffsetY(text_val_offset_y);
4170
4171 gauge_assign_common(settings, std::move(hud_gauge));
4172 }
4173
load_gauge_training_messages(gauge_settings * settings)4174 void load_gauge_training_messages(gauge_settings* settings)
4175 {
4176 settings->origin[0] = 0.5f;
4177 settings->origin[1] = 0.5f;
4178
4179 if(gr_screen.res == GR_640) {
4180 settings->offset[0] = -146;
4181 settings->offset[1] = -200;
4182 } else {
4183 settings->offset[0] = -133;
4184 settings->offset[1] = -259;
4185 }
4186
4187 auto hud_gauge = gauge_load_common<HudGaugeTrainingMessages>(settings);
4188
4189 gauge_assign_common(settings, std::move(hud_gauge));
4190 }
4191
load_gauge_messages(gauge_settings * settings)4192 void load_gauge_messages(gauge_settings* settings)
4193 {
4194 int max_lines = 3;
4195 int max_width;
4196 int scroll_time = 30;
4197 int step_size = 3;
4198 int total_life = 14000;
4199 int line_height = 9;
4200 bool hidden_by_comms_menu = true;
4201
4202 settings->origin[0] = 0.0f;
4203 settings->origin[1] = 0.0f;
4204 settings->offset[0] = 8;
4205 settings->offset[1] = 5;
4206
4207 if(gr_screen.res == GR_640) {
4208 max_width = 620;
4209 } else {
4210 max_width = 1004;
4211 }
4212
4213 auto hud_gauge = gauge_load_common<HudGaugeMessages>(settings);
4214
4215 if ( optional_string("Max Lines:") ) {
4216 stuff_int(&max_lines);
4217 }
4218 if ( optional_string("Max Width:") ) {
4219 stuff_int(&max_width);
4220 }
4221 if ( optional_string("Line Height:") ) {
4222 stuff_int(&line_height);
4223 }
4224 if ( optional_string("Total Lifetime:") ) {
4225 stuff_int(&total_life);
4226 }
4227 if ( optional_string("Scroll Time:") ) {
4228 stuff_int(&scroll_time);
4229 }
4230 if ( optional_string("Step Size:") ) {
4231 stuff_int(&step_size);
4232 }
4233 if ( optional_string("Hidden By Comms Menu:") ) {
4234 stuff_boolean(&hidden_by_comms_menu);
4235 }
4236
4237 hud_gauge->initMaxLines(max_lines);
4238 hud_gauge->initMaxWidth(max_width);
4239 hud_gauge->initScrollTime(scroll_time);
4240 hud_gauge->initStepSize(step_size);
4241 hud_gauge->initTotalLife(total_life);
4242 hud_gauge->initLineHeight(line_height);
4243 hud_gauge->initHiddenByCommsMenu(hidden_by_comms_menu);
4244
4245 gauge_assign_common(settings, std::move(hud_gauge));
4246 }
4247
load_gauge_fixed_messages(gauge_settings * settings)4248 void load_gauge_fixed_messages(gauge_settings* settings)
4249 {
4250 font::set_font(font::FONT1);
4251
4252 int h = gr_get_font_height();
4253
4254 bool center_text;
4255
4256 settings->use_coords = true;
4257 // set both coords to INT_MIN so that it's possible to check whether a HUD table has overridden them
4258 // (this is necessary to determine the default value for center_text)
4259 settings->coords[0] = INT_MIN;
4260 settings->coords[1] = INT_MIN;
4261
4262 auto hud_gauge = gauge_load_common<HudGaugeFixedMessages>(settings);
4263
4264 if(settings->coords[0] == INT_MIN && settings->coords[1] == INT_MIN) {
4265 // coords have almost certainly not been overridden; set them to their true defaults and set center_text to true
4266 settings->coords[0] = settings->base_res[0] / 2;
4267 settings->coords[1] = 5 + (h * 3);
4268 hud_gauge->initPosition(settings->coords[0], settings->coords[1]);
4269 center_text = true;
4270 } else {
4271 // coords have been overridden; set center_text to false
4272 center_text = false;
4273 }
4274
4275 if(optional_string("Center Text On Gauge X-Position:")) {
4276 stuff_boolean(¢er_text);
4277 }
4278
4279 hud_gauge->initCenterText(center_text);
4280
4281 gauge_assign_common(settings, std::move(hud_gauge));
4282 }
4283
load_gauge_weapon_linking(gauge_settings * settings)4284 void load_gauge_weapon_linking(gauge_settings* settings)
4285 {
4286 int Weapon_link_offsets[NUM_WEAPON_LINK_MODES][2];
4287 char fname_arc[MAX_FILENAME_LEN];
4288 char fname_primary_link_1[MAX_FILENAME_LEN];
4289 char fname_primary_link_2[MAX_FILENAME_LEN];
4290 char fname_secondary_link_1[MAX_FILENAME_LEN];
4291 char fname_secondary_link_2[MAX_FILENAME_LEN];
4292 char fname_secondary_link_3[MAX_FILENAME_LEN];
4293
4294 settings->origin[0] = 0.5f;
4295 settings->origin[1] = 0.5f;
4296 settings->slew = true;
4297
4298 if(gr_screen.res == GR_640) {
4299 settings->offset[0] = 54;
4300 settings->offset[1] = 2;
4301
4302 Weapon_link_offsets[LINK_ONE_PRIMARY][0] = 32;
4303 Weapon_link_offsets[LINK_ONE_PRIMARY][1] = 11;
4304 Weapon_link_offsets[LINK_TWO_PRIMARY][0] = 32;
4305 Weapon_link_offsets[LINK_TWO_PRIMARY][1] = 11;
4306 Weapon_link_offsets[LINK_ONE_SECONDARY][0] = 17;
4307 Weapon_link_offsets[LINK_ONE_SECONDARY][1] = 34;
4308 Weapon_link_offsets[LINK_TWO_SECONDARY][0] = 17;
4309 Weapon_link_offsets[LINK_TWO_SECONDARY][1] = 34;
4310 Weapon_link_offsets[LINK_THREE_SECONDARY][0] = 17;
4311 Weapon_link_offsets[LINK_THREE_SECONDARY][1] = 34;
4312
4313 strcpy_s(fname_arc, "rightarc1_fs1");
4314 strcpy_s(fname_primary_link_1, "rightarc2_fs1");
4315 strcpy_s(fname_primary_link_2, "rightarc3_fs1");
4316 strcpy_s(fname_secondary_link_1, "rightarc4_fs1");
4317 strcpy_s(fname_secondary_link_2, "rightarc5_fs1");
4318 strcpy_s(fname_secondary_link_3, "rightarc6_fs1");
4319 } else {
4320 settings->offset[0] = 86;
4321 settings->offset[1] = 3;
4322
4323 Weapon_link_offsets[LINK_ONE_PRIMARY][0] = 52;
4324 Weapon_link_offsets[LINK_ONE_PRIMARY][1] = 18;
4325 Weapon_link_offsets[LINK_TWO_PRIMARY][0] = 52;
4326 Weapon_link_offsets[LINK_TWO_PRIMARY][1] = 18;
4327 Weapon_link_offsets[LINK_ONE_SECONDARY][0] = 28;
4328 Weapon_link_offsets[LINK_ONE_SECONDARY][1] = 55;
4329 Weapon_link_offsets[LINK_TWO_SECONDARY][0] = 28;
4330 Weapon_link_offsets[LINK_TWO_SECONDARY][1] = 55;
4331 Weapon_link_offsets[LINK_THREE_SECONDARY][0] = 28;
4332 Weapon_link_offsets[LINK_THREE_SECONDARY][1] = 55;
4333
4334 strcpy_s(fname_arc, "2_rightarc1_fs1");
4335 strcpy_s(fname_primary_link_1, "2_rightarc2_fs1");
4336 strcpy_s(fname_primary_link_2, "2_rightarc3_fs1");
4337 strcpy_s(fname_secondary_link_1, "2_rightarc4_fs1");
4338 strcpy_s(fname_secondary_link_2, "2_rightarc5_fs1");
4339 strcpy_s(fname_secondary_link_3, "2_rightarc6_fs1");
4340 }
4341
4342 auto hud_gauge = gauge_load_common<HudGaugeWeaponLinking>(settings);
4343
4344 if(optional_string("Arc Filename:")) {
4345 stuff_string(fname_arc, F_NAME, MAX_FILENAME_LEN);
4346 }
4347 if(optional_string("Single Primary Filename:")) {
4348 stuff_string(fname_primary_link_1, F_NAME, MAX_FILENAME_LEN);
4349 }
4350 if(optional_string("Double Primary Filename:")) {
4351 stuff_string(fname_primary_link_2, F_NAME, MAX_FILENAME_LEN);
4352 }
4353 if(optional_string("Single Secondary Filename:")) {
4354 stuff_string(fname_secondary_link_1, F_NAME, MAX_FILENAME_LEN);
4355 }
4356 if(optional_string("Double Secondary Filename:")) {
4357 stuff_string(fname_secondary_link_2, F_NAME, MAX_FILENAME_LEN);
4358 }
4359 if(optional_string("Triple Secondary Filename:")) {
4360 stuff_string(fname_secondary_link_3, F_NAME, MAX_FILENAME_LEN);
4361 }
4362 if(optional_string("Single Primary Offsets:")) {
4363 stuff_int_list(Weapon_link_offsets[LINK_ONE_PRIMARY], 2);
4364 }
4365 if(optional_string("Double Primary Offsets:")) {
4366 stuff_int_list(Weapon_link_offsets[LINK_TWO_PRIMARY], 2);
4367 }
4368 if(optional_string("Single Secondary Offsets:")) {
4369 stuff_int_list(Weapon_link_offsets[LINK_ONE_SECONDARY], 2);
4370 }
4371 if(optional_string("Double Secondary Offsets:")) {
4372 stuff_int_list(Weapon_link_offsets[LINK_TWO_SECONDARY], 2);
4373 }
4374 if(optional_string("Triple Secondary Offsets:")) {
4375 stuff_int_list(Weapon_link_offsets[LINK_THREE_SECONDARY], 2);
4376 }
4377
4378 hud_gauge->init1PrimaryOffsets(Weapon_link_offsets[LINK_ONE_PRIMARY][0], Weapon_link_offsets[LINK_ONE_PRIMARY][1]);
4379 hud_gauge->init2PrimaryOffsets(Weapon_link_offsets[LINK_TWO_PRIMARY][0], Weapon_link_offsets[LINK_TWO_PRIMARY][1]);
4380 hud_gauge->init1SecondaryOffsets(Weapon_link_offsets[LINK_ONE_SECONDARY][0], Weapon_link_offsets[LINK_ONE_SECONDARY][1]);
4381 hud_gauge->init2SecondaryOffsets(Weapon_link_offsets[LINK_TWO_SECONDARY][0], Weapon_link_offsets[LINK_TWO_SECONDARY][1]);
4382 hud_gauge->init3SecondaryOffsets(Weapon_link_offsets[LINK_THREE_SECONDARY][0], Weapon_link_offsets[LINK_THREE_SECONDARY][1]);
4383 hud_gauge->initBitmaps(fname_arc, fname_primary_link_1, fname_primary_link_2, fname_secondary_link_1, fname_secondary_link_2, fname_secondary_link_3);
4384
4385 gauge_assign_common(settings, std::move(hud_gauge));
4386 }
4387
load_gauge_multi_msg(gauge_settings * settings)4388 void load_gauge_multi_msg(gauge_settings* settings)
4389 {
4390 settings->origin[0] = 0.0f;
4391 settings->origin[1] = 0.5f;
4392
4393 if(gr_screen.res == GR_640) {
4394 settings->offset[0] = 5;
4395 settings->offset[1] = -90;
4396 } else {
4397 settings->offset[0] = 8;
4398 settings->offset[1] = -144;
4399 }
4400
4401 auto hud_gauge = gauge_load_common<HudGaugeMultiMsg>(settings);
4402
4403 gauge_assign_common(settings, std::move(hud_gauge));
4404 }
4405
load_gauge_voice_status(gauge_settings * settings)4406 void load_gauge_voice_status(gauge_settings* settings)
4407 {
4408 settings->origin[0] = 0.0f;
4409 settings->origin[1] = 0.5f;
4410
4411 if(gr_screen.res == GR_640) {
4412 settings->offset[0] = 5;
4413 settings->offset[1] = -75;
4414 } else {
4415 settings->offset[0] = 8;
4416 settings->offset[1] = -129;
4417 }
4418
4419 auto hud_gauge = gauge_load_common<HudGaugeVoiceStatus>(settings);
4420
4421 gauge_assign_common(settings, std::move(hud_gauge));
4422 }
4423
load_gauge_ping(gauge_settings * settings)4424 void load_gauge_ping(gauge_settings* settings)
4425 {
4426 settings->origin[0] = 1.0f;
4427 settings->origin[1] = 0.0f;
4428
4429 if(gr_screen.res == GR_640) {
4430 settings->offset[0] = -80;
4431 settings->offset[1] = 3;
4432 } else {
4433 settings->offset[0] = -128;
4434 settings->offset[1] = 5;
4435 }
4436
4437 auto hud_gauge = gauge_load_common<HudGaugePing>(settings);
4438
4439 gauge_assign_common(settings, std::move(hud_gauge));
4440 }
4441
load_gauge_supernova(gauge_settings * settings)4442 void load_gauge_supernova(gauge_settings* settings)
4443 {
4444 settings->origin[0] = 0.5f;
4445 settings->origin[1] = 0.5f;
4446
4447 if(gr_screen.res == GR_640) {
4448 settings->offset[0] = -220;
4449 settings->offset[1] = -140;
4450 } else {
4451 settings->offset[0] = -342;
4452 settings->offset[1] = -214;
4453 }
4454
4455 auto hud_gauge = gauge_load_common<HudGaugeSupernova>(settings);
4456
4457 gauge_assign_common(settings, std::move(hud_gauge));
4458 }
4459
load_gauge_lock(gauge_settings * settings)4460 void load_gauge_lock(gauge_settings* settings)
4461 {
4462 int Lock_gauge_half_w;
4463 int Lock_gauge_half_h;
4464 int Lockspin_half_w;
4465 int Lockspin_half_h;
4466 float Lock_triangle_height;
4467 float Lock_triangle_base;
4468 int Lock_target_box_width;
4469 int Lock_target_box_height;
4470 bool loop_locked_anim;
4471 bool blink_locked_anim;
4472 char fname_lock[MAX_FILENAME_LEN];
4473 char fname_spin[MAX_FILENAME_LEN];
4474
4475 settings->set_position = false;
4476 settings->set_colour = false;
4477
4478 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
4479 if(gr_screen.res == GR_640) {
4480 Lock_gauge_half_w = 15;
4481 Lock_gauge_half_h = 15;
4482 Lockspin_half_w = 16;
4483 Lockspin_half_h = 16;
4484 Lock_triangle_height = 4.0f;
4485 Lock_triangle_base = 4.0f;
4486 Lock_target_box_width = 19;
4487 Lock_target_box_height = 30;
4488 loop_locked_anim = true;
4489 blink_locked_anim = false;
4490
4491 strcpy_s(fname_lock, "lock1_fs1");
4492 strcpy_s(fname_spin, "lockspin_fs1");
4493 } else {
4494 Lock_gauge_half_w = 24;
4495 Lock_gauge_half_h = 25;
4496 Lockspin_half_w = 26;
4497 Lockspin_half_h = 26;
4498 Lock_triangle_height = 6.5f;
4499 Lock_triangle_base = 6.5f;
4500 Lock_target_box_width = 19;
4501 Lock_target_box_height = 30;
4502 loop_locked_anim = true;
4503 blink_locked_anim = false;
4504
4505 strcpy_s(fname_lock, "2_lock1_fs1");
4506 strcpy_s(fname_spin, "2_lockspin_fs1");
4507 }
4508 } else {
4509 if(gr_screen.res == GR_640) {
4510 Lock_gauge_half_w = 17;
4511 Lock_gauge_half_h = 15;
4512 Lockspin_half_w = 31;
4513 Lockspin_half_h = 32;
4514 Lock_triangle_height = 4.0f;
4515 Lock_triangle_base = 4.0f;
4516 Lock_target_box_width = 19;
4517 Lock_target_box_height = 30;
4518 loop_locked_anim = false;
4519 blink_locked_anim = true;
4520
4521 strcpy_s(fname_lock, "lock1");
4522 strcpy_s(fname_spin, "lockspin");
4523 } else {
4524 Lock_gauge_half_w = 28;
4525 Lock_gauge_half_h = 25;
4526 Lockspin_half_w = 50;
4527 Lockspin_half_h = 52;
4528 Lock_triangle_height = 6.5f;
4529 Lock_triangle_base = 6.5f;
4530 Lock_target_box_width = 19;
4531 Lock_target_box_height = 30;
4532 loop_locked_anim = false;
4533 blink_locked_anim = true;
4534
4535 strcpy_s(fname_lock, "2_lock1");
4536 strcpy_s(fname_spin, "2_lockspin");
4537 }
4538 }
4539
4540 auto hud_gauge = gauge_load_common<HudGaugeLock>(settings);
4541
4542 if(optional_string("Lock Filename:")) {
4543 stuff_string(fname_lock, F_NAME, MAX_FILENAME_LEN);
4544 }
4545 if(optional_string("Locked Filename:")) {
4546 stuff_string(fname_spin, F_NAME, MAX_FILENAME_LEN);
4547 }
4548 if(optional_string("Lock Center Offsets:")) {
4549 int temp[2];
4550
4551 stuff_int_list(temp, 2);
4552
4553 Lock_gauge_half_w = temp[0];
4554 Lock_gauge_half_h = temp[1];
4555 }
4556 if(optional_string("Locked Center Offsets:")) {
4557 int temp[2];
4558
4559 stuff_int_list(temp, 2);
4560
4561 Lockspin_half_w = temp[0];
4562 Lockspin_half_h = temp[1];
4563 }
4564
4565 hud_gauge->initBitmaps(fname_lock, fname_spin);
4566 hud_gauge->initLoopLockedAnim(loop_locked_anim);
4567 hud_gauge->initBlinkLockedAnim(blink_locked_anim);
4568 hud_gauge->initGaugeHalfSize(Lock_gauge_half_w, Lock_gauge_half_h);
4569 hud_gauge->initSpinHalfSize(Lockspin_half_w, Lockspin_half_h);
4570 hud_gauge->initTriHeight(Lock_triangle_height);
4571 hud_gauge->initTriBase(Lock_triangle_base);
4572 hud_gauge->initTargetBoxSize(Lock_target_box_width, Lock_target_box_height);
4573
4574 gauge_assign_common(settings, std::move(hud_gauge));
4575 }
4576
load_gauge_offscreen(gauge_settings * settings)4577 void load_gauge_offscreen(gauge_settings* settings)
4578 {
4579 float Max_offscreen_tri_seperation;
4580 float Max_front_seperation;
4581 float Offscreen_tri_base;
4582 float Offscreen_tri_height;
4583
4584 settings->set_position = false;
4585 settings->set_colour = false;
4586
4587 if(gr_screen.res == GR_640) {
4588 Max_offscreen_tri_seperation = 10.0f;
4589 Max_front_seperation = 10.0f;
4590 Offscreen_tri_base = 6.0f;
4591 Offscreen_tri_height = 7.0f;
4592 } else {
4593 Max_offscreen_tri_seperation = 16.0f;
4594 Max_front_seperation = 16.0f;
4595 Offscreen_tri_base = 9.5f;
4596 Offscreen_tri_height = 11.0f;
4597 }
4598
4599 auto hud_gauge = gauge_load_common<HudGaugeOffscreen>(settings);
4600
4601 hud_gauge->initMaxTriSeperation(Max_offscreen_tri_seperation);
4602 hud_gauge->initMaxFrontSeperation(Max_front_seperation);
4603 hud_gauge->initTriBase(Offscreen_tri_base);
4604 hud_gauge->initTriHeight(Offscreen_tri_height);
4605
4606 gauge_assign_common(settings, std::move(hud_gauge));
4607 }
4608
load_gauge_brackets(gauge_settings * settings)4609 void load_gauge_brackets(gauge_settings* settings)
4610 {
4611 int min_target_box[2];
4612 int min_subtarget_box[2];
4613 char fname[MAX_FILENAME_LEN] = "attacker";
4614
4615 settings->set_position = false;
4616 settings->set_colour = false;
4617
4618 if(gr_screen.res == GR_640) {
4619 min_target_box[0] = 20;
4620 min_target_box[1] = 20;
4621 min_subtarget_box[0] = 12;
4622 min_subtarget_box[1] = 12;
4623 } else {
4624 min_target_box[0] = 30;
4625 min_target_box[1] = 30;
4626 min_subtarget_box[0] = 24;
4627 min_subtarget_box[1] = 24;
4628 }
4629
4630 auto hud_gauge = gauge_load_common<HudGaugeBrackets>(settings);
4631
4632 if(optional_string("Dot Filename:")) {
4633 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
4634 }
4635
4636 hud_gauge->initBitmaps(fname);
4637 hud_gauge->initMinSubTargetBoxSizes(min_subtarget_box[0], min_subtarget_box[1]);
4638 hud_gauge->initMinTargetBoxSizes(min_target_box[0], min_target_box[1]);
4639
4640 gauge_assign_common(settings, std::move(hud_gauge));
4641 }
4642
load_gauge_hostile_tri(gauge_settings * settings)4643 void load_gauge_hostile_tri(gauge_settings* settings)
4644 {
4645 int Radius;
4646 float Target_triangle_base;
4647 float Target_triangle_height;
4648
4649 settings->origin[0] = 0.5f;
4650 settings->origin[1] = 0.5f;
4651 settings->slew = true;
4652
4653 if(gr_screen.res == GR_640) {
4654 settings->offset[0] = 0;
4655 settings->offset[1] = 2;
4656
4657 Target_triangle_base = 6.0f;
4658 Target_triangle_height = 7.0f;
4659 Radius = 104;
4660 } else {
4661 settings->offset[0] = 0;
4662 settings->offset[1] = 3;
4663
4664 Target_triangle_base = 9.5f;
4665 Target_triangle_height = 11.0f;
4666 Radius = 166;
4667 }
4668
4669 auto hud_gauge = gauge_load_common<HudGaugeHostileTriangle>(settings);
4670
4671 if(optional_string("Radius:")) {
4672 stuff_int(&Radius);
4673 }
4674 if(optional_string("Triangle Base:")) {
4675 stuff_float(&Target_triangle_base);
4676 }
4677 if(optional_string("Triangle Height:")) {
4678 stuff_float(&Target_triangle_height);
4679 }
4680
4681 hud_gauge->initRadius(Radius);
4682 hud_gauge->initTriBase(Target_triangle_base);
4683 hud_gauge->initTriHeight(Target_triangle_height);
4684
4685 gauge_assign_common(settings, std::move(hud_gauge));
4686 }
4687
load_gauge_target_tri(gauge_settings * settings)4688 void load_gauge_target_tri(gauge_settings* settings)
4689 {
4690 int Radius;
4691 float Target_triangle_base;
4692 float Target_triangle_height;
4693
4694 settings->origin[0] = 0.5f;
4695 settings->origin[1] = 0.5f;
4696 settings->slew = true;
4697
4698 if(gr_screen.res == GR_640) {
4699 settings->offset[0] = 0;
4700 settings->offset[1] = 2;
4701
4702 Target_triangle_base = 6.0f;
4703 Target_triangle_height = 7.0f;
4704 Radius = 104;
4705 } else {
4706 settings->offset[0] = 0;
4707 settings->offset[1] = 3;
4708
4709 Target_triangle_base = 9.5f;
4710 Target_triangle_height = 11.0f;
4711 Radius = 166;
4712 }
4713
4714 auto hud_gauge = gauge_load_common<HudGaugeTargetTriangle>(settings);
4715
4716 if(optional_string("Radius:")) {
4717 stuff_int(&Radius);
4718 }
4719 if(optional_string("Triangle Base:")) {
4720 stuff_float(&Target_triangle_base);
4721 }
4722 if(optional_string("Triangle Height:")) {
4723 stuff_float(&Target_triangle_height);
4724 }
4725
4726 hud_gauge->initRadius(Radius);
4727 hud_gauge->initTriBase(Target_triangle_base);
4728 hud_gauge->initTriHeight(Target_triangle_height);
4729
4730 gauge_assign_common(settings, std::move(hud_gauge));
4731 }
4732
load_gauge_missile_tri(gauge_settings * settings)4733 void load_gauge_missile_tri(gauge_settings* settings)
4734 {
4735 int Radius;
4736 float Target_triangle_base;
4737 float Target_triangle_height;
4738
4739 settings->origin[0] = 0.5f;
4740 settings->origin[1] = 0.5f;
4741 settings->slew = true;
4742
4743 if(gr_screen.res == GR_640) {
4744 settings->offset[0] = 0;
4745 settings->offset[1] = 2;
4746
4747 Target_triangle_base = 6.0f;
4748 Target_triangle_height = 7.0f;
4749 Radius = 104;
4750 } else {
4751 settings->offset[0] = 0;
4752 settings->offset[1] = 3;
4753
4754 Target_triangle_base = 9.5f;
4755 Target_triangle_height = 11.0f;
4756 Radius = 166;
4757 }
4758
4759 auto hud_gauge = gauge_load_common<HudGaugeMissileTriangles>(settings);
4760
4761 if(optional_string("Radius:")) {
4762 stuff_int(&Radius);
4763 }
4764 if(optional_string("Triangle Base:")) {
4765 stuff_float(&Target_triangle_base);
4766 }
4767 if(optional_string("Triangle Height:")) {
4768 stuff_float(&Target_triangle_height);
4769 }
4770
4771 hud_gauge->initRadius(Radius);
4772 hud_gauge->initTriBase(Target_triangle_base);
4773 hud_gauge->initTriHeight(Target_triangle_height);
4774
4775 gauge_assign_common(settings, std::move(hud_gauge));
4776 }
4777
load_gauge_lead(gauge_settings * settings)4778 void load_gauge_lead(gauge_settings* settings)
4779 {
4780 float Lead_indicator_half[2];
4781 char fname[MAX_FILENAME_LEN];
4782
4783 settings->set_position = false;
4784 settings->set_colour = false;
4785
4786 if(Hud_reticle_style == HUD_RETICLE_STYLE_FS1) {
4787 if(gr_screen.res == GR_640) {
4788 Lead_indicator_half[0] = 12.5f;
4789 Lead_indicator_half[1] = 12.5f;
4790
4791 strcpy_s(fname, "lead1_fs1");
4792 } else {
4793 Lead_indicator_half[0] = 20.0f;
4794 Lead_indicator_half[1] = 20.0f;
4795
4796 strcpy_s(fname, "2_lead1_fs1");
4797 }
4798 } else {
4799 if(gr_screen.res == GR_640) {
4800 Lead_indicator_half[0] = 8.0f;
4801 Lead_indicator_half[1] = 8.0f;
4802
4803 strcpy_s(fname, "lead1");
4804 } else {
4805 Lead_indicator_half[0] = 13.0f;
4806 Lead_indicator_half[1] = 13.0f;
4807
4808 strcpy_s(fname, "2_lead1");
4809 }
4810 }
4811
4812 auto hud_gauge = gauge_load_common<HudGaugeLeadIndicator>(settings);
4813
4814 if(optional_string("Filename:")) {
4815 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
4816 }
4817 if(optional_string("Center Offsets:")) {
4818 int temp[2];
4819
4820 stuff_int_list(temp, 2);
4821
4822 Lead_indicator_half[0] = i2fl(temp[0]);
4823 Lead_indicator_half[1] = i2fl(temp[1]);
4824 }
4825
4826 hud_gauge->initHalfSize(Lead_indicator_half[0], Lead_indicator_half[1]);
4827 hud_gauge->initBitmaps(fname);
4828
4829 gauge_assign_common(settings, std::move(hud_gauge));
4830 }
4831
load_gauge_orientation_tee(gauge_settings * settings)4832 void load_gauge_orientation_tee(gauge_settings* settings)
4833 {
4834 int Radius;
4835
4836 settings->origin[0] = 0.5f;
4837 settings->origin[1] = 0.5f;
4838 settings->slew = true;
4839
4840 if(gr_screen.res == GR_640) {
4841 settings->offset[0] = 0;
4842 settings->offset[1] = 2;
4843
4844 Radius = 104;
4845 } else {
4846 settings->offset[0] = 0;
4847 settings->offset[1] = 3;
4848
4849 Radius = 166;
4850 }
4851
4852 auto hud_gauge = gauge_load_common<HudGaugeOrientationTee>(settings);
4853
4854 if(optional_string("Radius:")) {
4855 stuff_int(&Radius);
4856 }
4857
4858 hud_gauge->initRadius(Radius);
4859
4860 gauge_assign_common(settings, std::move(hud_gauge));
4861 }
4862
load_gauge_lead_sight(gauge_settings * settings)4863 void load_gauge_lead_sight(gauge_settings* settings)
4864 {
4865 char fname[MAX_FILENAME_LEN] = "leadsight";
4866
4867 settings->origin[0] = 0.5f;
4868 settings->origin[1] = 0.5f;
4869 settings->slew = true;
4870
4871 if(gr_screen.res == GR_640) {
4872 settings->offset[0] = 0;
4873 settings->offset[1] = 2;
4874 } else {
4875 settings->offset[0] = 0;
4876 settings->offset[1] = 3;
4877 }
4878
4879 auto hud_gauge = gauge_load_common<HudGaugeLeadSight>(settings);
4880
4881 if(optional_string("Filename:")) {
4882 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
4883 }
4884
4885 hud_gauge->initBitmaps(fname);
4886
4887 gauge_assign_common(settings, std::move(hud_gauge));
4888 }
4889
load_gauge_kills(gauge_settings * settings)4890 void load_gauge_kills(gauge_settings* settings)
4891 {
4892 int text_offsets[2] = {6, 4};
4893 int text_value_offsets[2] = {74, 4};
4894 char fname[MAX_FILENAME_LEN] = "kills1";
4895
4896 settings->origin[0] = 1.0f;
4897 settings->origin[1] = 1.0f;
4898
4899 if(gr_screen.res == GR_640) {
4900 settings->offset[0] = -143;
4901 settings->offset[1] = -119;
4902
4903 if(Lcl_gr) {
4904 text_value_offsets[0] = 118;
4905 text_value_offsets[1] = 4;
4906 }
4907 } else {
4908 settings->offset[0] = -144;
4909 settings->offset[1] = -144;
4910
4911 if(Lcl_gr) {
4912 text_value_offsets[0] = 104;
4913 text_value_offsets[1] = 4;
4914 }
4915 }
4916
4917 auto hud_gauge = gauge_load_common<HudGaugeKills>(settings);
4918
4919 if(optional_string("Filename:")) {
4920 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
4921 }
4922 if(optional_string("Text Offsets:")) {
4923 stuff_int_list(text_offsets, 2);
4924 }
4925 if(optional_string("Value Offsets:")) {
4926 stuff_int_list(text_value_offsets, 2);
4927 }
4928
4929 hud_gauge->initBitmaps(fname);
4930 hud_gauge->initTextOffsets(text_offsets[0], text_offsets[1]);
4931 hud_gauge->initTextValueOffsets(text_value_offsets[0], text_value_offsets[1]);
4932
4933 gauge_assign_common(settings, std::move(hud_gauge));
4934 }
4935
load_gauge_flight_path(gauge_settings * settings)4936 void load_gauge_flight_path(gauge_settings* settings)
4937 {
4938 int Marker_half[2];
4939 char fname[MAX_FILENAME_LEN] = "flight_path";
4940
4941 Marker_half[0] = 21;
4942 Marker_half[1] = 21;
4943
4944 settings->set_position = false;
4945
4946 auto hud_gauge = gauge_load_common<HudGaugeFlightPath>(settings);
4947
4948 if(optional_string("Filename:")) {
4949 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
4950 }
4951 if(optional_string("Center Offsets:")) {
4952 stuff_int_list(Marker_half, 2);
4953 }
4954
4955 hud_gauge->initHalfSize(Marker_half[0], Marker_half[1]);
4956 hud_gauge->initBitmap(fname);
4957
4958 gauge_assign_common(settings, std::move(hud_gauge));
4959 }
4960
load_gauge_warhead_count(gauge_settings * settings)4961 void load_gauge_warhead_count(gauge_settings* settings)
4962 {
4963 int warhead_name_offsets[2] = {6, 4};
4964 int warhead_count_offsets[2] = {74, 4};
4965 int icon_width = 0;
4966 int icon_height = 0;
4967 int max_icons = 0;
4968 int max_columns = 0;
4969 HudAlignment alignment = HudAlignment::NONE;
4970 char fname[MAX_FILENAME_LEN] = "warhead_icon";
4971
4972 settings->origin[0] = 1.0f;
4973 settings->origin[1] = 1.0f;
4974 settings->slew = true;
4975
4976 if ( gr_screen.res == GR_640 ) {
4977 settings->offset[0] = -143;
4978 settings->offset[1] = -119;
4979 } else {
4980 settings->offset[0] = -144;
4981 settings->offset[1] = -144;
4982 }
4983
4984 auto hud_gauge = gauge_load_common<HudGaugeWarheadCount>(settings);
4985
4986 if ( optional_string("Filename:") ) {
4987 stuff_string(fname, F_NAME, MAX_FILENAME_LEN);
4988 }
4989
4990 if ( optional_string("Name Offsets:") ) {
4991 stuff_int_list(warhead_name_offsets, 2);
4992 }
4993
4994 if ( optional_string("Count Offsets:") ) {
4995 stuff_int_list(warhead_count_offsets, 2);
4996 }
4997
4998 if ( optional_string("Icon Width:") ) {
4999 stuff_int(&icon_width);
5000 }
5001
5002 if ( optional_string("Icon Height:") ) {
5003 stuff_int(&icon_height);
5004 }
5005
5006 if ( optional_string("Max Icons:") ) {
5007 stuff_int(&max_icons);
5008 }
5009
5010 if ( optional_string("Max Columns:") ) {
5011 stuff_int(&max_columns);
5012 }
5013
5014 if ( optional_string("Name Alignment:") ) {
5015 char temp[NAME_LENGTH];
5016 stuff_string(temp, F_NAME, NAME_LENGTH);
5017 alignment = hud_alignment_lookup(temp);
5018 }
5019
5020 hud_gauge->initBitmap(fname);
5021 hud_gauge->initNameOffsets(warhead_name_offsets[0], warhead_name_offsets[1]);
5022 hud_gauge->initCountOffsets(warhead_count_offsets[0], warhead_count_offsets[1]);
5023 hud_gauge->initCountSizes(icon_width, icon_height);
5024 hud_gauge->initMaxSymbols(max_icons);
5025 hud_gauge->initMaxColumns(max_columns);
5026 hud_gauge->initTextAlign(alignment);
5027
5028 gauge_assign_common(settings, std::move(hud_gauge));
5029 }
5030
load_gauge_hardpoints(gauge_settings * settings)5031 void load_gauge_hardpoints(gauge_settings* settings)
5032 {
5033 int sizes[2] = {150, 150};
5034 float line_width = 1.0f;
5035 int view_dir = HudGaugeHardpoints::TOP;
5036 bool show_primary = false;
5037 bool show_secondary = true;
5038
5039 settings->origin[0] = 1.0f;
5040 settings->origin[1] = 1.0f;
5041
5042 if(gr_screen.res == GR_640) {
5043 settings->offset[0] = -244;
5044 settings->offset[1] = -101;
5045 } else {
5046 settings->offset[0] = -390;
5047 settings->offset[1] = -98;
5048 }
5049
5050 auto hud_gauge = gauge_load_common<HudGaugeHardpoints>(settings);
5051
5052 if ( optional_string("Size:") ) {
5053 stuff_int_list(sizes, 2);
5054 }
5055
5056 if ( optional_string("Line Width:") ) {
5057 stuff_float(&line_width);
5058 }
5059
5060 if ( optional_string("View Direction:") ) {
5061 if ( optional_string("Top") ) {
5062 view_dir = HudGaugeHardpoints::TOP;
5063 } else if ( optional_string("Front") ) {
5064 view_dir = HudGaugeHardpoints::FRONT;
5065 }
5066 }
5067
5068 if ( optional_string("Show Primary Weapons:") ) {
5069 stuff_boolean(&show_primary);
5070 }
5071
5072 if ( optional_string("Show Secondary Weapons:") ) {
5073 stuff_boolean(&show_secondary);
5074 }
5075
5076 hud_gauge->initSizes(sizes[0], sizes[1]);
5077 hud_gauge->initLineWidth(line_width);
5078 hud_gauge->initViewDir(view_dir);
5079 hud_gauge->initDrawOptions(show_primary, show_secondary);
5080
5081 gauge_assign_common(settings, std::move(hud_gauge));
5082 }
5083
load_gauge_primary_weapons(gauge_settings * settings)5084 void load_gauge_primary_weapons(gauge_settings* settings)
5085 {
5086 char fname_first[MAX_FILENAME_LEN] = "weapon_list1";
5087 char fname_entry[MAX_FILENAME_LEN] = "weapon_list2";
5088 char fname_last[MAX_FILENAME_LEN] = "weapon_list3";
5089 int header_offsets[2] = {2, 2};
5090 char header_text[NAME_LENGTH] = "Primary Weapons";
5091 int first_bg_h = 12;
5092 int first_bg_offset_x = 0;
5093 int entry_bg_h = 12;
5094 int entry_bg_offset_x = 0;
5095 int last_bg_offset_x = 0;
5096 int last_bg_offset_y = 0;
5097 int entry_h = 10;
5098 int entry_start_offset_y = 12;
5099 int ammo_x = 28;
5100 int link_x = 33;
5101 int name_x = 35;
5102
5103 auto hud_gauge = gauge_load_common<HudGaugePrimaryWeapons>(settings);
5104
5105 if ( optional_string("Header Offsets:") ) {
5106 stuff_int_list(header_offsets, 2);
5107 }
5108
5109 if ( optional_string("Header Text:") ) {
5110 stuff_string(header_text, F_NAME, NAME_LENGTH);
5111 }
5112
5113 if ( optional_string("First Background Filename:") ) {
5114 stuff_string(fname_first, F_NAME, MAX_FILENAME_LEN);
5115 }
5116
5117 if ( optional_string("First Background Height:") ) {
5118 stuff_int(&first_bg_h);
5119 }
5120
5121 if ( optional_string("First Background X-offset:") ) {
5122 stuff_int(&first_bg_offset_x);
5123 }
5124
5125 if ( optional_string("Entry Background Filename:") ) {
5126 stuff_string(fname_entry, F_NAME, MAX_FILENAME_LEN);
5127 }
5128
5129 if ( optional_string("Entry Background Height:") ) {
5130 stuff_int(&entry_bg_h);
5131 }
5132
5133 if ( optional_string("Entry Background X-offset:") ) {
5134 stuff_int(&entry_bg_offset_x);
5135 }
5136
5137 if ( optional_string("Last Background Filename:") ) {
5138 stuff_string(fname_last, F_NAME, MAX_FILENAME_LEN);
5139 }
5140
5141 if ( optional_string("Last Background X-offset:") ) {
5142 stuff_int(&last_bg_offset_x);
5143 }
5144
5145 if ( optional_string("Last Background Y-offset:") ) {
5146 stuff_int(&last_bg_offset_y);
5147 }
5148
5149 if ( optional_string("Entry Height:") ) {
5150 stuff_int(&entry_h);
5151 }
5152
5153 if ( optional_string("List Start Y-offset:") ) {
5154 stuff_int(&entry_start_offset_y);
5155 }
5156
5157 if ( optional_string("Ammo X-offset:") ) {
5158 stuff_int(&ammo_x);
5159 }
5160
5161 if ( optional_string("Link X-offset:") ) {
5162 stuff_int(&link_x);
5163 }
5164
5165 if ( optional_string("Name X-offset:") ) {
5166 stuff_int(&name_x);
5167 }
5168
5169 hud_gauge->initBitmaps(fname_first, fname_entry, fname_last);
5170 hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
5171 hud_gauge->initHeaderText(header_text);
5172 hud_gauge->initBgFirstHeight(first_bg_h);
5173 hud_gauge->initBgFirstOffsetX(first_bg_offset_x);
5174 hud_gauge->initBgEntryHeight(entry_bg_h);
5175 hud_gauge->initBgEntryOffsetX(entry_bg_offset_x);
5176 hud_gauge->initBgLastOffsetX(last_bg_offset_x);
5177 hud_gauge->initBgLastOffsetY(last_bg_offset_y);
5178 hud_gauge->initEntryHeight(entry_h);
5179 hud_gauge->initEntryStartY(entry_start_offset_y);
5180 hud_gauge->initPrimaryAmmoOffsetX(ammo_x);
5181 hud_gauge->initPrimaryLinkOffsetX(link_x);
5182 hud_gauge->initPrimaryNameOffsetX(name_x);
5183 hud_gauge->initLinkIcon();
5184
5185 gauge_assign_common(settings, std::move(hud_gauge));
5186 }
5187
load_gauge_secondary_weapons(gauge_settings * settings)5188 void load_gauge_secondary_weapons(gauge_settings* settings)
5189 {
5190 char fname_first[MAX_FILENAME_LEN] = "weapon_list1";
5191 char fname_entry[MAX_FILENAME_LEN] = "weapon_list2";
5192 char fname_last[MAX_FILENAME_LEN] = "weapon_list3";
5193 int header_offsets[2] = {2, 2};
5194 char header_text[NAME_LENGTH] = "Secondary Weapons";
5195 int first_bg_h = 12;
5196 int first_bg_offset_x = 0;
5197 int entry_bg_h = 12;
5198 int entry_bg_offset_x = 0;
5199 int last_bg_offset_x = 0;
5200 int last_bg_offset_y = 0;
5201 int entry_h = 10;
5202 int entry_start_offset_y = 12;
5203 int ammo_x = 28;
5204 int link_x = 28;
5205 int name_x = 39;
5206 int reload_x = 118;
5207 int unlink_x = 33;
5208
5209 auto hud_gauge = gauge_load_common<HudGaugeSecondaryWeapons>(settings);
5210
5211 if ( optional_string("Header Offsets:") ) {
5212 stuff_int_list(header_offsets, 2);
5213 }
5214
5215 if ( optional_string("Header Text:") ) {
5216 stuff_string(header_text, F_NAME, NAME_LENGTH);
5217 }
5218
5219 if ( optional_string("First Background Filename:") ) {
5220 stuff_string(fname_first, F_NAME, MAX_FILENAME_LEN);
5221 }
5222
5223 if ( optional_string("First Background Height:") ) {
5224 stuff_int(&first_bg_h);
5225 }
5226
5227 if ( optional_string("First Background X-offset:") ) {
5228 stuff_int(&first_bg_offset_x);
5229 }
5230
5231 if ( optional_string("Entry Background Filename:") ) {
5232 stuff_string(fname_entry, F_NAME, MAX_FILENAME_LEN);
5233 }
5234
5235 if ( optional_string("Entry Background Height:") ) {
5236 stuff_int(&entry_bg_h);
5237 }
5238
5239 if ( optional_string("Entry Background X-offset:") ) {
5240 stuff_int(&entry_bg_offset_x);
5241 }
5242
5243 if ( optional_string("Last Background Filename:") ) {
5244 stuff_string(fname_last, F_NAME, MAX_FILENAME_LEN);
5245 }
5246
5247 if ( optional_string("Last Background X-offset:") ) {
5248 stuff_int(&last_bg_offset_x);
5249 }
5250
5251 if ( optional_string("Last Background Y-offset:") ) {
5252 stuff_int(&last_bg_offset_y);
5253 }
5254
5255 if ( optional_string("Entry Height:") ) {
5256 stuff_int(&entry_h);
5257 }
5258
5259 if ( optional_string("List Start Y-offset:") ) {
5260 stuff_int(&entry_start_offset_y);
5261 }
5262
5263 if ( optional_string("Ammo X-offset:") ) {
5264 stuff_int(&ammo_x);
5265 }
5266
5267 if ( optional_string("Link X-offset:") ) {
5268 stuff_int(&link_x);
5269 }
5270
5271 if ( optional_string("Name X-offset:") ) {
5272 stuff_int(&name_x);
5273 }
5274
5275 if ( optional_string("Unlink X-offset:") ) {
5276 stuff_int(&unlink_x);
5277 }
5278
5279 if ( optional_string("Reload X-offset:") ) {
5280 stuff_int(&reload_x);
5281 }
5282
5283 hud_gauge->initBitmaps(fname_first, fname_entry, fname_last);
5284 hud_gauge->initHeaderOffsets(header_offsets[0], header_offsets[1]);
5285 hud_gauge->initHeaderText(header_text);
5286 hud_gauge->initBgFirstHeight(first_bg_h);
5287 hud_gauge->initBgFirstOffsetX(first_bg_offset_x);
5288 hud_gauge->initBgEntryHeight(entry_bg_h);
5289 hud_gauge->initBgEntryOffsetX(entry_bg_offset_x);
5290 hud_gauge->initBgLastOffsetX(last_bg_offset_x);
5291 hud_gauge->initBgLastOffsetY(last_bg_offset_y);
5292 hud_gauge->initEntryHeight(entry_h);
5293 hud_gauge->initEntryStartY(entry_start_offset_y);
5294 hud_gauge->initSecondaryAmmoOffsetX(ammo_x);
5295 hud_gauge->initSecondaryLinkedOffsetX(link_x);
5296 hud_gauge->initSecondaryNameOffsetX(name_x);
5297 hud_gauge->initSecondaryReloadOffsetX(reload_x);
5298 hud_gauge->initSecondaryUnlinkedOffsetX(unlink_x);
5299 hud_gauge->initLinkIcon();
5300
5301 gauge_assign_common(settings, std::move(hud_gauge));
5302 }
5303
load_gauge_scripting(gauge_settings * settings)5304 void load_gauge_scripting(gauge_settings* settings) {
5305 auto hud_gauge = gauge_load_common<HudGaugeScripting>(settings);
5306
5307 required_string("Name:");
5308 SCP_string name;
5309 stuff_string(name, F_NAME);
5310
5311 hud_gauge->initName(name);
5312
5313 gauge_assign_common(settings, std::move(hud_gauge));
5314 }
5315