1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 #ifndef __HUD_H__
11 #define __HUD_H__
12 
13 #include "globalincs/vmallocator.h"
14 #include "graphics/2d.h"
15 #include "graphics/font.h"
16 #include "hud/hudgauges.h"
17 #include "hud/hudparse.h"
18 
19 class object;
20 struct cockpit_display;
21 
22 typedef struct hud_anim {
23 	char filename[MAX_FILENAME_LEN];
24 	int first_frame;	// the bitmap id for the first frame in the animation... note that
25 						// all bitmap id's following this frame are numbered sequentially
26 	int num_frames;		// number of frames in the animation
27 	int sx, sy;			// screen (x,y) of top-left corner of animation
28 	float total_time;	// total time in seconds for the animation (depends on animation fps)
29 	float time_elapsed;	// time that has elapsed (in seconds) since animation started playing
30 } hud_anim;
31 
32 typedef struct hud_frames {
33 	int	first_frame;
34 	int	num_frames;
35 } hud_frames;
36 
37 // Objective display
38 typedef struct objective_display_info
39 {
40 	int display_timer;
41 	int goal_type;
42 	int goal_status;
43 	int goal_ntotal;
44 	int goal_nresolved;
45 
46 } objective_display_info;
47 
48 // used to track how player subsystems are getting damaged
49 typedef struct hud_subsys_info
50 {
51 	float	last_str;
52 	int	flash_duration_timestamp;
53 } hud_subsys_info;
54 
55 // used for the display of damaged subsystems
56 typedef struct hud_subsys_damage
57 {
58 	int	str;
59 	int	type;
60 	char* name;
61 } hud_subsys_damage;
62 
63 // used for hudtarget
64 enum class HudAlignment
65 {
66 	NONE,
67 	LEFT,
68 	RIGHT
69 };
70 
71 extern int HUD_draw;
72 extern int HUD_contrast;
73 
74 #define HUD_NUM_COLOR_LEVELS	16
75 extern color HUD_color_defaults[HUD_NUM_COLOR_LEVELS];
76 
77 // extern globals that will control the color of the HUD gauges
78 #define HUD_COLOR_ALPHA_USER_MAX		13		// max user-settable alpha, absolute max is 15
79 #define HUD_COLOR_ALPHA_USER_MIN		3		// min user-settable alpha, absolute min is 0
80 
81 #define HUD_COLOR_ALPHA_MAX			15
82 #define HUD_COLOR_ALPHA_DEFAULT		8
83 
84 #define HUD_BRIGHT_DELTA				7		// Level added to HUD_color_alpha to make brightness used for flashing
85 
86 // hud macro for maybe flickering all gauges
87 #define GR_AABITMAP(a, b, c)						{ int jx, jy; if(emp_should_blit_gauge()) { gr_set_bitmap(a); jx = b; jy = c; emp_hud_jitter(&jx, &jy); gr_aabitmap(jx, jy); } }
88 #define GR_AABITMAP_EX(a, b, c, d, e, f, g)	{ int jx, jy; if(emp_should_blit_gauge()) { gr_set_bitmap(a); jx = b; jy = c; emp_hud_jitter(&jx, &jy); gr_aabitmap_ex(jx, jy, d, e, f, g); } }
89 
90 // radar target identification flags
91 #define RTIF_CROSSHAIRS	(1<<0)		// draw crosshairs
92 #define RTIF_BLINK		(1<<1)		// make targeted blip blink
93 #define RTIF_PULSATE	(1<<2)		// make targeted blips size pulsate
94 #define RTIF_ENLARGE	(1<<3)		// make targeted blip appear larger than the other blips
95 
96 extern int radar_target_id_flags;
97 
98 extern int HUD_color_red;
99 extern int HUD_color_green;
100 extern int HUD_color_blue;
101 extern int HUD_color_alpha;
102 
103 extern color HUD_color_debug;
104 
105 // Values used "wiggle" the HUD.  In the 2D HUD case, the clip region accounts
106 // for these, but for the 3d-type hud stuff, you need to add these in manually.
107 extern float HUD_offset_x;
108 extern float HUD_offset_y;
109 
110 // the offset of the player's view vector and the ship forward vector in pixels (Swifty)
111 extern int HUD_nose_x;
112 extern int HUD_nose_y;
113 // Global: integrity of player's target
114 extern float Pl_target_integrity;
115 extern float Player_rearm_eta;
116 
117 extern int Hud_max_targeting_range;
118 
119 void HUD_init_colors();
120 void HUD_init();
121 void hud_scripting_close(lua_State*);
122 void hud_close();
123 void hud_level_close();
124 void hud_update_frame(float frametime);		// updates hud systems not dependant on rendering
125 void hud_render_preprocess(float frametime);			// renders 3d dependant gauges
126 void hud_render_all();
127 void hud_render_gauges(int cockpit_display_num = -1);
128 void hud_stop_looped_engine_sounds();
129 
130 // set the offset values for this render frame
131 void HUD_set_offsets(object *viewer_obj, int wiggedy_wack, matrix *eye_orient);
132 // returns the offset between the player's view vector and the forward vector of the ship in pixels (Swifty)
133 void HUD_get_nose_coordinates(int *x, int *y);
134 
135 // Basically like gr_reset_clip only it accounts for hud jittering
136 void HUD_reset_clip();
137 void hud_save_restore_camera_data(int save);
138 
139 // Basically like gr_set_clip only it accounts for hud jittering
140 void HUD_set_clip(int x, int y, int w, int h);
141 
142 // do flashing text gauge
143 void hud_start_text_flash(const char *txt, int t, int interval = 200);
144 
145 // convert a string to use mono spaced numbers
146 void hud_num_make_mono(char *num_str, int font_num = font::FONT1);
147 
148 // functions for handling hud animations
149 void hud_anim_init(hud_anim *ha, int sx, int sy, const char *filename);
150 void hud_frames_init(hud_frames *hf);
151 int	hud_anim_render(hud_anim *ha, float frametime, int draw_alpha=0, int loop=1, int hold_last=0, int reverse=0,int resize_mode=GR_RESIZE_FULL, bool mirror = false);
152 int	hud_anim_load(hud_anim *ha);
153 
154 // functions for displaying the support view popup
155 void hud_support_view_start();
156 void hud_support_view_stop(int stop_now=0);
157 void hud_support_view_abort();
158 void hud_support_view_update();
159 
160 void HUD_init_hud_color_array();
161 
162 // setting HUD colors
163 void hud_set_default_color();
164 void hud_set_iff_color(object *objp, int is_bright=0);
165 color* hud_get_iff_color(object *objp, int is_bright=0);
166 void hud_set_bright_color();
167 void hud_set_dim_color();
168 
169 // HUD gauge functions
170 #define HUD_C_NONE				-4
171 #define HUD_C_BRIGHT			-3
172 #define HUD_C_DIM				-2
173 #define HUD_C_NORMAL			-1
174 void	hud_set_gauge_color(int gauge_index, int bright_index = HUD_C_NONE);
175 int	hud_gauge_active(int gauge_index);
176 void	hud_gauge_start_flash(int gauge_index);
177 int	hud_gauge_maybe_flash(int gauge_index);
178 
179 HudAlignment hud_alignment_lookup(const char *name);
180 
181 // popup gauges
182 void	hud_gauge_popup_start(int gauge_index, int time=4000);
183 int	hud_gauge_is_popup(int gauge_index);
184 
185 // objective status gauge
186 void hud_update_objective_message();
187 void hud_add_objective_messsage(int type, int status);
188 
189 int	hud_get_dock_time( object *docker_objp );
190 void	hud_show_target_model();
191 void	hud_show_voice_status();
192 
193 void	hud_subspace_notify_abort();
194 
195 // render multiplayer text message currently being entered if any
196 void hud_maybe_render_multi_text();
197 
198 int hud_get_draw();
199 void hud_toggle_draw();
200 int	hud_disabled();
201 int hud_support_find_closest( int objnum );
202 
203 // Goober5000
204 void hud_set_draw(int draw);
205 void hud_disable_except_messages(int disable);
206 int hud_disabled_except_messages();
207 
208 // contrast stuff
209 void hud_toggle_contrast();
210 void hud_set_contrast(int high);
211 
212 class HudGauge
213 {
214 protected:
215 	int position[2];
216 	int base_w, base_h;
217 	color gauge_color;
218 	int gauge_config;
219 	int gauge_object;
220 
221 	int font_num;
222 
223 	bool lock_color;
224 	bool sexp_lock_color;
225 	bool reticle_follow;
226 	bool active;
227 	bool off_by_default;
228 	bool sexp_override;
229 	bool pop_up;
230 	int popup_timer;
231 	bool message_gauge;
232 	int disabled_views;
233 
234 	int flash_duration;
235 	int flash_next;
236 	bool flash_status;
237 	bool only_render_in_chase_view;
238 
239 	// custom gauge specific stuff
240 	bool custom_gauge;
241 	hud_frames custom_frame;
242 	int custom_frame_offset;
243 	int textoffset_x, textoffset_y;
244 	char custom_name[NAME_LENGTH];
245 	SCP_string custom_text;
246 
247 	SCP_string default_text;
248 
249 	// Render to texture stuff
250 	char texture_target_fname[MAX_FILENAME_LEN];
251 	int texture_target;
252 	int canvas_w, canvas_h;
253 	int target_w, target_h;
254 	int target_x, target_y;
255 	int display_offset_x, display_offset_y;
256 public:
257 	// constructors
258 	HudGauge();
259 	HudGauge(int _gauge_object, int _gauge_config, bool _slew, bool _message, int _disabled_views, int r, int g, int b);
260 	// constructor for custom gauges
261 	HudGauge(int _gauge_config, bool _slew, int r, int g, int b, char* _custom_name, char* _custom_text, char* frame_fname, int txtoffset_x, int txtoffset_y);
262 	virtual ~HudGauge();
263 
264 	void initPosition(int x, int y);
265 	void initBaseResolution(int w, int h);
266 	void initSlew(bool slew);
267 	void initFont(int input_font_num);
268 	void initCockpitTarget(const char* display_name, int _target_x, int _target_y, int _target_w, int _target_h, int _canvas_w, int _canvas_h);
269 	void initRenderStatus(bool render);
270 
271 	int getConfigType();
272 	int getObjectType();
273 	void getPosition(int *x, int *y);
274 	bool isOffbyDefault();
275 	bool isActive();
276 
277 	void updateColor(int r, int g, int b, int a = 255);
278 	const color& getColor();
279 	void lockConfigColor(bool lock);
280 	void sexpLockConfigColor(bool lock);
281 	void updateActive(bool show);
282 	void updatePopUp(bool pop_up_flag);
283 	void updateSexpOverride(bool sexp);
284 	void initChase_view_only(bool chase_view_only);
285 
286 	// SEXP interfacing functions
287 	// For flashing gauges in training missions
288 	void startFlashSexp();
289 	int maybeFlashSexp();
290 	bool flashExpiredSexp();
291 	void resetTimers();
292 
293 	// For updating custom gauges
294 	const char* getCustomGaugeName();
295 	void updateCustomGaugeCoords(int _x, int _y);
296 	void updateCustomGaugeFrame(int frame_offset);
297 	void updateCustomGaugeText(const char* txt);
298 	void updateCustomGaugeText(const SCP_string& txt);
299 	const char* getCustomGaugeText();
300 
301 	void startPopUp(int time=4000);
302 	int popUpActive();
303 
304 	virtual void preprocess();
305 	virtual void render(float frametime);
306 	virtual bool canRender();
307 	virtual void pageIn();
308 	virtual void initialize();
309 	virtual void onFrame(float frametime);
310 
311 	bool setupRenderCanvas(int render_target = -1);
312 	void setCockpitTarget(const cockpit_display *display);
313 	void resetCockpitTarget();
314 
315 	void setFont();
316 	void setGaugeColor(int bright_index = HUD_C_NONE);
317 
318 	// rendering functions
319 	void renderBitmap(int x, int y);
320 	void renderBitmap(int frame, int x, int y);
321 	void renderBitmapColor(int frame, int x, int y);
322 	void renderBitmapUv(int frame, int x, int y, int w, int h, float u0, float v0, float u1, float v1);
323 	void renderBitmapEx(int frame, int x, int y, int w, int h, int sx, int sy);
324 	void renderString(int x, int y, const char *str);
325 	void renderString(int x, int y, int gauge_id, const char *str);
326 	void renderStringAlignCenter(int x, int y, int area_width, const char *s);
327 	void renderPrintf(int x, int y, SCP_FORMAT_STRING const char* format, ...) SCP_FORMAT_STRING_ARGS(4, 5);
328 	void renderPrintf(int x, int y, int gauge_id, SCP_FORMAT_STRING const char* format, ...)  SCP_FORMAT_STRING_ARGS(5, 6);
329 	void renderLine(int x1, int y1, int x2, int y2);
330 	void renderGradientLine(int x1, int y1, int x2, int y2);
331 	void renderRect(int x, int y, int w, int h);
332 	void renderCircle(int x, int y, int diameter, bool filled = true);
333 
334 	void unsize(int *x, int *y);
335 	void unsize(float *x, float *y);
336 	void resize(int *x, int *y);
337 	void resize(float *x, float *y);
338 	void setClip(int x, int y, int w, int h);
339 	void resetClip();
340 };
341 
342 class HudGaugeMissionTime: public HudGauge // HUD_MISSION_TIME
343 {
344 	hud_frames time_gauge;
345 
346 	int time_text_offsets[2]; // Mission_time_text_coords[gr_screen.res]
347 	int time_val_offsets[2]; // Mission_time_text_val_coords[gr_screen.res]
348 public:
349 	HudGaugeMissionTime();
350 	void initBitmaps(const char *fname);
351 	void initTextOffsets(int x, int y);
352 	void initValueOffsets(int x, int y);
353 	void render(float frametime) override;
354 	void pageIn() override;
355 };
356 
357 class HudGaugeTextWarnings: public HudGauge // HUD_TEXT_FLASH
358 {
359 	int next_flash;
360 	bool flash_flags;
361 public:
362 	HudGaugeTextWarnings();
363 	void render(float frametime) override;
364 	void initialize() override;
365 	int maybeTextFlash();
366 };
367 
368 class HudGaugeKills: public HudGauge
369 {
370 	hud_frames Kills_gauge;
371 
372 	int text_offsets[2];
373 	int text_value_offsets[2];
374 public:
375 	HudGaugeKills();
376 	void initBitmaps(const char *fname);
377 	void initTextOffsets(int x, int y);
378 	void initTextValueOffsets(int x, int y);
379 	void render(float frametime) override;
380 	void pageIn() override;
381 };
382 
383 class HudGaugeLag: public HudGauge
384 {
385 	hud_frames Netlag_icon;
386 
387 	int flash_timer[2];
388 	bool flash_flag;
389 public:
390 	HudGaugeLag();
391 	void initBitmaps(const char *fname);
392 	void render(float frametime) override;
393 	void pageIn() override;
394 
395 	void startFlashLag(int duration = 1400);
396 	bool maybeFlashLag(bool flash_fast = false);
397 };
398 
399 class HudGaugeObjectiveNotify: public HudGauge
400 {
401 protected:
402 	hud_frames	Objective_display_gauge;
403 
404 	int Objective_text_offset_y;
405 	int Objective_text_val_offset_y;
406 	int Subspace_text_offset_y;
407 	int Subspace_text_val_offset_y;
408 	int Red_text_offset_y;
409 	int Red_text_val_offset_y;
410 
411 	int flash_timer[2];
412 	bool flash_flag;
413 public:
414 	HudGaugeObjectiveNotify();
415 	void initBitmaps(const char *fname);
416 	void initObjTextOffsetY(int y);
417 	void initObjValueOffsetY(int y);
418 	void initSubspaceTextOffsetY(int y);
419 	void initSubspaceValueOffsetY(int y);
420 	void initRedAlertTextOffsetY(int y);
421 	void initRedAlertValueOffsetY(int y);
422 
423 	void render(float frametime) override;
424 	void startFlashNotify(int duration = 1400);
425 	bool maybeFlashNotify(bool flash_fast = false);
426 	void renderObjective();
427 	void renderRedAlert();
428 	void renderSubspace();
429 	void pageIn() override;
430 	void initialize() override;
431 };
432 
433 class HudGaugeDamage: public HudGauge
434 {
435 	struct DamageInfo {
436 		SCP_string name;
437 		int strength = -1;
438 
439 		int bright_index = HUD_C_NONE;
440 		color* color_override = nullptr;
441 
442 		int name_x = -1;
443 		int name_y = -1;
444 
445 		int value_x = -1;
446 		int value_y = -1;
447 
448 		bool draw_background = false;
449 		int background_x = -1;
450 		int background_y = -1;
451 	};
452 
453 protected:
454 	hud_frames damage_top;
455 	hud_frames damage_middle;
456 	hud_frames damage_bottom;
457 
458 	int header_offsets[2];
459 	int hull_integ_offsets[2];
460 	int hull_integ_val_offset_x;
461 	int middle_frame_start_offset_y;
462 	int subsys_integ_start_offsets[2];
463 	int subsys_integ_val_offset_x;
464 	int bottom_bg_offset;
465 	int line_h;
466 
467 	int Damage_flash_timer;
468 	bool Damage_flash_bright;
469 
470 	int next_flash;
471 	bool flash_status;
472 public:
473 	HudGaugeDamage();
474 	void initBitmaps(const char *fname_top, const char *fname_middle, const char *fname_bottom);
475 	void initHeaderOffsets(int x, int y);
476 	void initHullIntegOffsets(int x, int y);
477 	void initHullIntegValueOffsetX(int x);
478 	void initMiddleFrameStartOffsetY(int y);
479 	void initSubsysIntegStartOffsets(int x, int y);
480 	void initSubsysIntegValueOffsetX(int x);
481 	void initBottomBgOffset(int offset);
482 	void initLineHeight(int h);
483 	void render(float frametime) override;
484 	void pageIn() override;
485 	void initialize() override;
486 };
487 
488 class HudGaugeSupport: public HudGauge
489 {
490 protected:
491 	hud_frames background;
492 
493 	int Header_offsets[2];
494 	int text_val_offset_y;
495 	int text_dock_offset_x;
496 	int text_dock_val_offset_x;
497 public:
498 	HudGaugeSupport();
499 	void initBitmaps(const char *fname);
500 	void initHeaderOffsets(int x, int y);
501 	void initTextValueOffsetY(int y);
502 	void initTextDockOffsetX(int x);
503 	void initTextDockValueOffsetX(int x);
504 	void render(float frametime) override;
505 	void pageIn() override;
506 };
507 
508 class HudGaugeMultiMsg: public HudGauge
509 {
510 protected:
511 public:
512 	HudGaugeMultiMsg();
513 	bool canRender() override;
514 	void render(float frametime) override;
515 };
516 
517 class HudGaugeVoiceStatus: public HudGauge
518 {
519 protected:
520 public:
521 	HudGaugeVoiceStatus();
522 	void render(float frametime) override;
523 };
524 
525 class HudGaugePing: public HudGauge
526 {
527 protected:
528 public:
529 	HudGaugePing();
530 	void render(float frametime) override;
531 };
532 
533 class HudGaugeSupernova: public HudGauge
534 {
535 public:
536 	HudGaugeSupernova();
537 	void render(float frametime) override;
538 };
539 
540 class HudGaugeFlightPath: public HudGauge
541 {
542 	hud_frames Marker;
543 
544 	int Marker_half[2];
545 public:
546 	HudGaugeFlightPath();
547 	void initBitmap(const char *fname);
548 	void initHalfSize(int w, int h);
549 	void render(float frametime) override;
550 };
551 
552 HudGauge* hud_get_gauge(const char* name);
553 
554 extern SCP_vector<std::unique_ptr<HudGauge>> default_hud_gauges;
555 
556 extern flag_def_list Hud_gauge_types[];
557 extern int Num_hud_gauge_types;
558 
559 #endif	/* __HUD_H__ */
560 
561