mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 17:48:46 -10:00
Unique pointers need to be constructed in very particular ways, but so did this NGON radar class, so we just had to put the constructor function inside unique pointer constructor.
And to keep that special pointer from going out of scope, we switched to the ternery operator.
Also made these changes:
Change to hypotf()
Fix Shadowing, Zero Vector macro not working at all.
Offset changed to offset_incoming
blip changed to blip_instance
Offset changed to = {} to initialize the struct without a problem.
clampBlip() required an override
Give offset a default initializer.
Switch to <cmath>
(Apparently <math.h> was deprecated and needs to be replaced with <cmath>.)
One last complaint from travis about a redundant default value.
Thank you Travis!
426 lines
10 KiB
C++
426 lines
10 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "bmpman/bmpman.h"
|
|
#include "freespace.h"
|
|
#include "gamesnd/gamesnd.h"
|
|
#include "globalincs/linklist.h"
|
|
#include "graphics/font.h"
|
|
#include "graphics/matrix.h"
|
|
#include "iff_defs/iff_defs.h"
|
|
#include "io/timer.h"
|
|
#include "jumpnode/jumpnode.h"
|
|
#include "localization/localize.h"
|
|
#include "network/multi.h"
|
|
#include "object/object.h"
|
|
#include "playerman/player.h"
|
|
#include "radar/radar.h"
|
|
#include "ship/awacs.h"
|
|
#include "ship/ship.h"
|
|
#include "ship/subsysdamage.h"
|
|
#include "weapon/emp.h"
|
|
#include "weapon/weapon.h"
|
|
|
|
extern int radar_target_id_flags;
|
|
|
|
HudGaugeRadarStd::HudGaugeRadarStd():
|
|
HudGaugeRadar(HUD_OBJECT_RADAR_STD, 255, 255, 255)
|
|
{
|
|
gr_init_alphacolor( &radar_crosshairs, 255, 255, 255, 196);
|
|
}
|
|
|
|
void HudGaugeRadarStd::initCenterOffsets(float x, float y)
|
|
{
|
|
Radar_center_offsets[0] = x;
|
|
Radar_center_offsets[1] = y;
|
|
}
|
|
|
|
void HudGaugeRadarStd::initBitmaps(char *fname)
|
|
{
|
|
Radar_gauge.first_frame = bm_load_animation(fname, &Radar_gauge.num_frames);
|
|
if ( Radar_gauge.first_frame < 0 ) {
|
|
Warning(LOCATION,"Cannot load hud ani: %s\n", fname);
|
|
}
|
|
}
|
|
|
|
void HudGaugeRadarStd::blipDrawDistorted(blip *b, int x, int y)
|
|
{
|
|
int xdiff, ydiff;
|
|
float scale;
|
|
xdiff = -10 + rand()%20;
|
|
ydiff = -10 + rand()%20;
|
|
|
|
// maybe scale the effect if EMP is active
|
|
if(emp_active_local()){
|
|
scale = emp_current_intensity();
|
|
|
|
xdiff = (int)((float)xdiff * scale);
|
|
ydiff = (int)((float)ydiff * scale);
|
|
}
|
|
|
|
drawContactCircle(x + xdiff, y + ydiff, b->rad);
|
|
}
|
|
void HudGaugeRadarStd::blipDrawFlicker(blip *b, int x, int y)
|
|
{
|
|
int xdiff=0, ydiff=0, flicker_index;
|
|
|
|
if ( (b-Blips) & 1 ) {
|
|
flicker_index=0;
|
|
} else {
|
|
flicker_index=1;
|
|
}
|
|
|
|
if ( timestamp_elapsed(Radar_flicker_timer[flicker_index]) ) {
|
|
Radar_flicker_timer[flicker_index] = timestamp_rand(50,1000);
|
|
Radar_flicker_on[flicker_index] ^= 1;
|
|
}
|
|
|
|
if ( !Radar_flicker_on[flicker_index] ) {
|
|
return;
|
|
}
|
|
|
|
if ( rand() & 1 ) {
|
|
xdiff = -2 + rand()%4;
|
|
ydiff = -2 + rand()%4;
|
|
}
|
|
|
|
drawContactCircle(x + xdiff, y + ydiff, b->rad);
|
|
}
|
|
void HudGaugeRadarStd::blitGauge()
|
|
{
|
|
renderBitmap(Radar_gauge.first_frame+1, position[0], position[1] );
|
|
}
|
|
void HudGaugeRadarStd::drawBlips(int blip_type, int bright, int distort)
|
|
{
|
|
blip *b = NULL;
|
|
blip *blip_head = NULL;
|
|
int x, y;
|
|
|
|
Assert((blip_type >= 0) && (blip_type < MAX_BLIP_TYPES));
|
|
|
|
|
|
// Need to set font.
|
|
font::set_font(font::FONT1);
|
|
|
|
|
|
// get the appropriate blip list
|
|
if (bright)
|
|
blip_head = &Blip_bright_list[blip_type];
|
|
else
|
|
blip_head = &Blip_dim_list[blip_type];
|
|
|
|
|
|
// draw all blips of this type
|
|
for (b = GET_FIRST(blip_head); b != END_OF_LIST(blip_head); b = GET_NEXT(b))
|
|
{
|
|
gr_set_color_fast(b->blip_color);
|
|
plotBlip(b, &x, &y);
|
|
|
|
// maybe draw cool blip to indicate current target
|
|
if (b->flags & BLIP_CURRENT_TARGET)
|
|
{
|
|
b->rad = Radar_blip_radius_target;
|
|
current_target_x = x;
|
|
current_target_y = y;
|
|
}
|
|
else
|
|
{
|
|
b->rad = Radar_blip_radius_normal;
|
|
}
|
|
|
|
// maybe distort blip
|
|
if (distort)
|
|
{
|
|
blipDrawDistorted(b, x, y);
|
|
}
|
|
else if (b->flags & BLIP_DRAW_DISTORTED)
|
|
{
|
|
blipDrawFlicker(b, x, y);
|
|
}
|
|
else
|
|
{
|
|
if (b->radar_image_2d == -1 && b->radar_color_image_2d == -1)
|
|
drawContactCircle(x, y, b->rad);
|
|
else
|
|
drawContactImage(x, y, b->rad, b->radar_image_2d, b->radar_color_image_2d, b->radar_image_size);
|
|
}
|
|
}
|
|
}
|
|
void HudGaugeRadarStd::drawBlipsSorted(int distort)
|
|
{
|
|
current_target_x = 0;
|
|
current_target_y = 0;
|
|
// draw dim blips first, then bright blips
|
|
for (int is_bright = 0; is_bright < 2; is_bright++)
|
|
{
|
|
drawBlips(BLIP_TYPE_JUMP_NODE, is_bright, distort);
|
|
drawBlips(BLIP_TYPE_WARPING_SHIP, is_bright, distort);
|
|
drawBlips(BLIP_TYPE_NAVBUOY_CARGO, is_bright, distort);
|
|
drawBlips(BLIP_TYPE_NORMAL_SHIP, is_bright, distort);
|
|
drawBlips(BLIP_TYPE_BOMB, is_bright, distort);
|
|
drawBlips(BLIP_TYPE_TAGGED_SHIP, is_bright, distort);
|
|
}
|
|
// draw crosshairs last - if at all.
|
|
if(radar_target_id_flags & RTIF_CROSSHAIRS) {
|
|
drawCrosshairs(current_target_x, current_target_y);
|
|
}
|
|
}
|
|
void HudGaugeRadarStd::drawContactCircle( int x, int y, int rad )
|
|
{
|
|
if ( rad == Radar_blip_radius_target ) {
|
|
if (radar_target_id_flags & RTIF_BLINK) {
|
|
if (Missiontime & 8192)
|
|
return;
|
|
}
|
|
renderCircle(x, y, 6);
|
|
} else {
|
|
// rad = RADAR_BLIP_RADIUS_NORMAL;
|
|
renderCircle(x, y, 4);
|
|
}
|
|
}
|
|
void HudGaugeRadarStd::drawContactImage( int x, int y, int rad, int idx, int clr_idx, int size )
|
|
{
|
|
// this we will move as ships.tbl option (or use for radar scaling etc etc)
|
|
//int size = 24;
|
|
|
|
int w, h, old_bottom, old_bottom_unscaled, old_right, old_right_unscaled;
|
|
float scalef, wf, hf, xf, yf;
|
|
vec3d blip_scaler;
|
|
|
|
if(bm_get_info(idx, &w, &h) < 0)
|
|
{
|
|
// Just if something goes terribly wrong
|
|
drawContactCircle(x, y, rad);
|
|
return;
|
|
}
|
|
|
|
// just to make sure the missing casts wont screw the math
|
|
wf = (float) w;
|
|
hf = (float) h;
|
|
xf = (float) x;
|
|
yf = (float) y;
|
|
|
|
// make sure we use the larger dimension for the scaling
|
|
// lets go case by case to make sure there are no probs
|
|
if (size == -1)
|
|
scalef = 1.0f;
|
|
else if ((h == w) && (size == h))
|
|
scalef = 1.0f;
|
|
else if ( h > w)
|
|
scalef = ((float) size) / hf;
|
|
else
|
|
scalef = ((float) size) / wf;
|
|
|
|
Assert(scalef != 0);
|
|
|
|
// animate the targeted icon - option 1 of highlighting the targets
|
|
if ( rad == Radar_blip_radius_target ) {
|
|
if (radar_target_id_flags & RTIF_PULSATE) {
|
|
scalef *= 1.3f + (sinf(10 * f2fl(Missiontime)) * 0.3f);
|
|
}
|
|
if (radar_target_id_flags & RTIF_BLINK) {
|
|
if (Missiontime & 8192)
|
|
return;
|
|
}
|
|
if (radar_target_id_flags & RTIF_ENLARGE) {
|
|
scalef *= 1.3f;
|
|
}
|
|
}
|
|
|
|
// setup the scaler
|
|
blip_scaler.xyz.x = scalef;
|
|
blip_scaler.xyz.y = scalef;
|
|
blip_scaler.xyz.z = 1.0f;
|
|
|
|
old_bottom = gr_screen.clip_bottom;
|
|
old_bottom_unscaled = gr_screen.clip_bottom_unscaled;
|
|
gr_screen.clip_bottom = (int) (old_bottom/scalef);
|
|
gr_screen.clip_bottom_unscaled = (int) (old_bottom_unscaled/scalef);
|
|
|
|
old_right = gr_screen.clip_right;
|
|
old_right_unscaled = gr_screen.clip_right_unscaled;
|
|
gr_screen.clip_right = (int) (old_right/scalef);
|
|
gr_screen.clip_right_unscaled = (int) (old_right_unscaled/scalef);
|
|
|
|
// scale the drawing coordinates
|
|
x = (int) ((xf / scalef) - wf/2.0f);
|
|
y = (int) ((yf / scalef) - hf/2.0f);
|
|
|
|
gr_push_scale_matrix(&blip_scaler);
|
|
|
|
if ( idx >= 0 ) {
|
|
gr_set_bitmap(idx,GR_ALPHABLEND_NONE,GR_BITBLT_MODE_NORMAL,1.0f);
|
|
renderBitmap( x, y );
|
|
}
|
|
|
|
if ( clr_idx >= 0 ) {
|
|
gr_set_screen_scale(base_w, base_h);
|
|
gr_bitmap(x, y);
|
|
gr_reset_screen_scale();
|
|
}
|
|
|
|
gr_pop_scale_matrix();
|
|
|
|
gr_screen.clip_bottom = old_bottom;
|
|
gr_screen.clip_bottom_unscaled = old_bottom_unscaled;
|
|
|
|
gr_screen.clip_right = old_right;
|
|
gr_screen.clip_right_unscaled = old_right_unscaled;
|
|
}
|
|
|
|
void HudGaugeRadarStd::render(float /*frametime*/)
|
|
{
|
|
//WMC - This strikes me as a bit hackish
|
|
bool g3_yourself = !g3_in_frame();
|
|
if(g3_yourself)
|
|
g3_start_frame(1);
|
|
|
|
float sensors_str;
|
|
int ok_to_blit_radar;
|
|
|
|
ok_to_blit_radar = 1;
|
|
|
|
sensors_str = ship_get_subsystem_strength( Player_ship, SUBSYSTEM_SENSORS );
|
|
|
|
if ( ship_subsys_disrupted(Player_ship, SUBSYSTEM_SENSORS) ) {
|
|
sensors_str = MIN_SENSOR_STR_TO_RADAR-1;
|
|
}
|
|
|
|
// note that on lowest skill level, there is no radar effects due to sensors damage
|
|
if ( (Game_skill_level == 0) || (sensors_str > SENSOR_STR_RADAR_NO_EFFECTS) ) {
|
|
Radar_static_playing = 0;
|
|
Radar_static_next = 0;
|
|
Radar_death_timer = 0;
|
|
Radar_avail_prev_frame = 1;
|
|
} else if ( sensors_str < MIN_SENSOR_STR_TO_RADAR ) {
|
|
if ( Radar_avail_prev_frame ) {
|
|
Radar_death_timer = timestamp(2000);
|
|
Radar_static_next = 1;
|
|
}
|
|
Radar_avail_prev_frame = 0;
|
|
} else {
|
|
Radar_death_timer = 0;
|
|
if ( Radar_static_next == 0 )
|
|
Radar_static_next = 1;
|
|
}
|
|
|
|
if ( timestamp_elapsed(Radar_death_timer) ) {
|
|
ok_to_blit_radar = 0;
|
|
}
|
|
|
|
setGaugeColor();
|
|
blitGauge();
|
|
drawRange();
|
|
|
|
if ( timestamp_elapsed(Radar_static_next) ) {
|
|
Radar_static_playing ^= 1;
|
|
Radar_static_next = timestamp_rand(50, 750);
|
|
}
|
|
|
|
// if the emp effect is active, always draw the radar wackily
|
|
if(emp_active_local()){
|
|
Radar_static_playing = 1;
|
|
}
|
|
|
|
if ( ok_to_blit_radar ) {
|
|
if ( Radar_static_playing ) {
|
|
drawBlipsSorted(1); // passing 1 means to draw distorted
|
|
if (!Radar_static_looping.isValid()) {
|
|
Radar_static_looping = snd_play_looping(gamesnd_get_game_sound(GameSounds::STATIC));
|
|
}
|
|
} else {
|
|
drawBlipsSorted(0);
|
|
if (Radar_static_looping.isValid()) {
|
|
snd_stop(Radar_static_looping);
|
|
Radar_static_looping = sound_handle::invalid();
|
|
}
|
|
}
|
|
} else {
|
|
if (Radar_static_looping.isValid()) {
|
|
snd_stop(Radar_static_looping);
|
|
Radar_static_looping = sound_handle::invalid();
|
|
}
|
|
}
|
|
|
|
if(g3_yourself)
|
|
g3_end_frame();
|
|
}
|
|
void HudGaugeRadarStd::pageIn()
|
|
{
|
|
bm_page_in_aabitmap( Radar_gauge.first_frame, Radar_gauge.num_frames );
|
|
}
|
|
|
|
void HudGaugeRadarStd::clampBlip(vec3d* b)
|
|
{
|
|
float max_radius;
|
|
float hypotenuse;
|
|
|
|
max_radius = i2fl(Radar_radius[0] - 5);
|
|
|
|
// Scale blip to radar size
|
|
vm_vec_scale(b, i2fl(Radar_radius[0])/2.0f);
|
|
|
|
hypotenuse = hypotf(b->xyz.x, b->xyz.y);
|
|
|
|
// Clamp to inside of plot area, if needed
|
|
if (hypotenuse > max_radius) {
|
|
vm_vec_scale2(b, max_radius, hypotenuse);
|
|
}
|
|
|
|
// Scale Y to respect aspect ratio
|
|
b->xyz.y *= (i2fl(Radar_radius[1]) / i2fl(Radar_radius[0]));
|
|
}
|
|
|
|
void HudGaugeRadarStd::plotBlip(blip *b, int *x, int *y)
|
|
{
|
|
float zdist, rscale;
|
|
vec3d *pos = &b->position;
|
|
|
|
if (b->dist < pos->xyz.z) {
|
|
rscale = 0.0f;
|
|
} else {
|
|
rscale = (float) acosf(pos->xyz.z / b->dist) / PI;
|
|
}
|
|
|
|
zdist = hypotf(pos->xyz.x, pos->xyz.y);
|
|
|
|
vec3d new_pos = {};
|
|
|
|
if (zdist >= 0.01f)
|
|
{
|
|
new_pos = *pos;
|
|
new_pos.xyz.z = 0.0f;
|
|
vm_vec_scale(&new_pos, rscale / zdist); // Values are within +/- 1.0f
|
|
clampBlip(&new_pos);
|
|
}
|
|
|
|
*x = fl2i(position[0] + Radar_center_offsets[0] + new_pos.xyz.x);
|
|
*y = fl2i(position[1] + Radar_center_offsets[1] - new_pos.xyz.y);
|
|
}
|
|
|
|
void HudGaugeRadarStd::drawCrosshairs(int x, int y)
|
|
{
|
|
int i,j,m;
|
|
|
|
gr_set_color_fast(&radar_crosshairs);
|
|
|
|
for(i = 0; i < 2; i++) {
|
|
m = (i * 2) - 1;
|
|
renderGradientLine(x + m*4,y,x + m*8,y);
|
|
}
|
|
for(j = 0; j < 2; j++) {
|
|
m = (j * 2) - 1;
|
|
renderGradientLine(x,y + m*4,x,y + m*8);
|
|
}
|
|
}
|