From 9cc4d759b698a42b62d0ea8cbfe2a9354adb7538 Mon Sep 17 00:00:00 2001 From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Fri, 20 Jan 2023 22:40:12 +0100 Subject: [PATCH] Add patch from Juhu/strafehud-features branch: "strafehud: implement different projection modes and allow the range to be set to the current fov" --- _hud_common.cfg | 3 +- qcsrc/client/hud/panel/strafehud.qc | 81 ++++++++++++++++++++++++----- qcsrc/client/hud/panel/strafehud.qh | 13 +++-- 3 files changed, 79 insertions(+), 18 deletions(-) diff --git a/_hud_common.cfg b/_hud_common.cfg index b85631d80..1089cac64 100644 --- a/_hud_common.cfg +++ b/_hud_common.cfg @@ -150,7 +150,7 @@ seta hud_panel_scoreboard_itemstats_showdelay_minpos 0.75 "delay displaying the seta _hud_panel_strafehud_demo "0" "strafehud changes angle during configure" seta hud_panel_strafehud_mode "0" "strafehud mode which controls whether the strafehud is centered at \"0\" = view angle, \"1\" = velocity angle" -seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the strafehud, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)" +seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the strafehud, \"-1\" = current fov, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)" seta hud_panel_strafehud_style "2" "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = gradient for the strafe bar" seta hud_panel_strafehud_unit "1" "speed unit (1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots), length unit (1 = qu, 2 = m, 3 = km, 4 = mi, 5 = nmi)" seta hud_panel_strafehud_unit_show "1" "show units" @@ -216,6 +216,7 @@ seta hud_panel_strafehud_sonar_pitch_range "0.1" "dynamic playback speed range o seta hud_panel_strafehud_vangle "0" "set to \"1\" to enable the vertical angle indicator" seta hud_panel_strafehud_vangle_color "0.75 0.75 0.75" "color of the vertical angle text" seta hud_panel_strafehud_vangle_size "1" "size of the vertical angle text (relative to the panel height)" +seta hud_panel_strafehud_projection "0" "strafehud projection mode, \"0\" = Linear, \"1\" = Perspective, \"2\" = Panoramic" // hud panel aliases alias quickmenu "cl_cmd hud quickmenu ${* ?}" diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index cf2e36cb3..6d8248127 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -199,6 +199,7 @@ void HUD_StrafeHUD() float arrow_size = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_size, 10), 0); // there's only one size cvar for the arrows, they will always have a 45° angle to ensure proper rendering without antialiasing float text_offset_top = 0; float text_offset_bottom = 0; + float hfov = getproperty(VF_FOVX); if(onground) { @@ -377,11 +378,25 @@ void HUD_StrafeHUD() hudangle = range_minangle; // use minimum angle required if dynamically setting hud angle } } + else if(autocvar_hud_panel_strafehud_range < 0) + { + hudangle = hfov; + } else { hudangle = bound(0, fabs(autocvar_hud_panel_strafehud_range), 360); // limit HUD range to 360 degrees, higher values don't make sense } + // limit strafe-meter angle to values suitable for the current projection mode + switch(autocvar_hud_panel_strafehud_projection) { + case STRAFEHUD_PROJECTION_PERSPECTIVE: + hudangle = min(hudangle, 170); + break; + case STRAFEHUD_PROJECTION_PANORAMIC: + hudangle = min(hudangle, 350); + break; + } + // detect air strafe turning if((!strafekeys && vlen(vec2(movement)) > 0) || onground || autocvar__hud_configure) { @@ -707,20 +722,20 @@ void HUD_StrafeHUD() overturn_offset += shift_offset; // draw left acceleration zone - HUD_Panel_DrawStrafeHUD(accelzone_left_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT); + HUD_Panel_DrawStrafeHUD(accelzone_left_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, true, hudangle); if(autocvar_hud_panel_strafehud_bar_preaccel) - HUD_Panel_DrawStrafeHUD(preaccelzone_left_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT); + HUD_Panel_DrawStrafeHUD(preaccelzone_left_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, true, hudangle); // draw right acceleration zone - HUD_Panel_DrawStrafeHUD(accelzone_right_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT); + HUD_Panel_DrawStrafeHUD(accelzone_right_offset, accelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_RIGHT, true, hudangle); if(autocvar_hud_panel_strafehud_bar_preaccel) - HUD_Panel_DrawStrafeHUD(preaccelzone_right_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT); + HUD_Panel_DrawStrafeHUD(preaccelzone_right_offset, preaccelzone_width, hidden_width, autocvar_hud_panel_strafehud_bar_accel_color, autocvar_hud_panel_strafehud_bar_accel_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_LEFT, true, hudangle); // draw overturn zone (technically incorrect, acceleration decreases at 90 degrees but speed loss happens a little bit after 90 degrees, however due to sv_airstopaccelerate that's hard to calculate) - HUD_Panel_DrawStrafeHUD(overturn_offset, overturn_width, hidden_width, autocvar_hud_panel_strafehud_bar_overturn_color, autocvar_hud_panel_strafehud_bar_overturn_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_BOTH); + HUD_Panel_DrawStrafeHUD(overturn_offset, overturn_width, hidden_width, autocvar_hud_panel_strafehud_bar_overturn_color, autocvar_hud_panel_strafehud_bar_overturn_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_BOTH, true, hudangle); // draw neutral zone - HUD_Panel_DrawStrafeHUD(neutral_offset, neutral_width, hidden_width, autocvar_hud_panel_strafehud_bar_neutral_color, autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_NONE); + HUD_Panel_DrawStrafeHUD(neutral_offset, neutral_width, hidden_width, autocvar_hud_panel_strafehud_bar_neutral_color, autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, autocvar_hud_panel_strafehud_style, STRAFEHUD_GRADIENT_NONE, true, hudangle); if(autocvar_hud_panel_strafehud_switch && speed >= minspeed && bestangle_width > 0 && autocvar_hud_panel_strafehud_switch_alpha > 0) // only draw indicators if minspeed is reached { @@ -744,8 +759,8 @@ void HUD_StrafeHUD() offset -= bestangle_width; } - HUD_Panel_DrawStrafeHUD(switch_offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE); - if(direction == STRAFEHUD_DIRECTION_NONE) HUD_Panel_DrawStrafeHUD(offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE); + HUD_Panel_DrawStrafeHUD(switch_offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE, false, hudangle); + if(direction == STRAFEHUD_DIRECTION_NONE) HUD_Panel_DrawStrafeHUD(offset, bestangle_width, hidden_width, autocvar_hud_panel_strafehud_switch_color, autocvar_hud_panel_strafehud_switch_alpha * panel_fg_alpha, STRAFEHUD_STYLE_DRAWFILL, STRAFEHUD_GRADIENT_NONE, false, hudangle); } } @@ -910,6 +925,9 @@ void HUD_StrafeHUD() ghost_offset = bound(0, (odd_angles ? odd_bestangle_offset : bestangle_offset), panel_size.x); } + currentangle_offset = StrafeHUD_projectOffset(currentangle_offset, hudangle); + ghost_offset = StrafeHUD_projectOffset(ghost_offset, hudangle); + switch(autocvar_hud_panel_strafehud_angle_style) { case STRAFEHUD_INDICATOR_SOLID: @@ -1050,8 +1068,30 @@ void HUD_StrafeHUD() hud_lasttime = time; } +float StrafeHUD_projectOffset(float offset, float range) { + range *= DEG2RAD / 2; + float angle = (offset - (panel_size.x/2)) / (panel_size.x/2) * range; + switch(autocvar_hud_panel_strafehud_projection) { + default: + case STRAFEHUD_PROJECTION_LINEAR: + return offset; + case STRAFEHUD_PROJECTION_PERSPECTIVE: + offset = tan(angle) / tan(range); + break; + case STRAFEHUD_PROJECTION_PANORAMIC: + offset = tan(angle/2) / tan(range/2); + break; + } + offset = offset * (panel_size.x/2) + (panel_size.x/2); + return offset; +} + +float StrafeHUD_projectWidth(float offset, float width, float range) { + return StrafeHUD_projectOffset(offset + width, range) - StrafeHUD_projectOffset(offset, range); +} + // functions to make hud elements align perfectly in the hud area -void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vector color, float alpha, int type, int gradientType) +void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vector color, float alpha, int type, int gradientType, bool projectWidth, float range) { float mirror_offset, mirror_width; vector size = panel_size; @@ -1084,6 +1124,11 @@ void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vect } size.x = width; + vector original_size = size; + float original_offset = offset; + if(projectWidth && size.x > 0) size.x = StrafeHUD_projectWidth(offset, size.x, range); + offset = StrafeHUD_projectOffset(offset, range); + if(mirror_offset < 0) { mirror_width += mirror_offset; @@ -1098,6 +1143,11 @@ void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vect } mirror_size.x = mirror_width; + vector original_mirror_size = mirror_size; + float original_mirror_offset = mirror_offset; + if(projectWidth && mirror_size.x > 0) mirror_size.x = StrafeHUD_projectWidth(mirror_offset, mirror_size.x, range); + mirror_offset = StrafeHUD_projectOffset(mirror_offset, range); + switch(type) { default: @@ -1136,8 +1186,8 @@ void HUD_Panel_DrawStrafeHUD(float offset, float width, float hidden_width, vect gradient_mirror_offset = 0; } - StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, mirror_size, original_width, mirror_offset, alpha, gradient_mirror_offset, gradientType); - StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, size, original_width, offset, alpha, gradient_offset, gradientType); + StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, original_mirror_size, original_width, original_mirror_offset, alpha, gradient_mirror_offset, gradientType, range); + StrafeHUD_drawGradient(color, autocvar_hud_panel_strafehud_bar_neutral_color, original_size, original_width, original_offset, alpha, gradient_offset, gradientType, range); } } @@ -1152,7 +1202,7 @@ vector StrafeHUD_mixColors(vector color1, vector color2, float ratio) return mixedColor; } -void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float original_width, float offset, float alpha, float gradientOffset, int gradientType) +void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float original_width, float offset, float alpha, float gradientOffset, int gradientType, float range) { float color_ratio, alpha1, alpha2; vector segment_size = size; @@ -1162,8 +1212,11 @@ void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float ori color_ratio = alpha1/(alpha1+alpha2); for(int i = 0; i < size.x; ++i) { - float ratio, alpha_ratio, combine_ratio1, combine_ratio2; + float ratio, alpha_ratio, combine_ratio1, combine_ratio2, segment_offset; + segment_offset = offset + i; segment_size.x = min(size.x - i, 1); // each gradient segment is 1 unit wide except if there is less than 1 unit of gradient remaining + segment_size.x = StrafeHUD_projectWidth(segment_offset, segment_size.x, range); + segment_offset = StrafeHUD_projectOffset(segment_offset, range); ratio = (i + gradientOffset) / original_width * (gradientType == STRAFEHUD_GRADIENT_BOTH ? 2 : 1); if(ratio > 1) ratio = 2 - ratio; if(gradientType != STRAFEHUD_GRADIENT_RIGHT) ratio = 1 - ratio; @@ -1171,7 +1224,7 @@ void StrafeHUD_drawGradient(vector color1, vector color2, vector size, float ori combine_ratio1 = ratio*(1-color_ratio); combine_ratio2 = (1-ratio)*color_ratio; ratio = (combine_ratio1 + combine_ratio2) == 0 ? 1 : combine_ratio1/(combine_ratio1 + combine_ratio2); - if(alpha_ratio > 0) drawfill(panel_pos + eX * (offset + i), segment_size, StrafeHUD_mixColors(color1, color2, ratio), alpha_ratio, DRAWFLAG_NORMAL); + if(alpha_ratio > 0) drawfill(panel_pos + eX * segment_offset, segment_size, StrafeHUD_mixColors(color1, color2, ratio), alpha_ratio, DRAWFLAG_NORMAL); } } diff --git a/qcsrc/client/hud/panel/strafehud.qh b/qcsrc/client/hud/panel/strafehud.qh index 295fa83a8..afa53f5d4 100644 --- a/qcsrc/client/hud/panel/strafehud.qh +++ b/qcsrc/client/hud/panel/strafehud.qh @@ -5,7 +5,7 @@ AUTOCVAR_SAVE(hud_panel_strafehud, int, 3, "enable this panel, 1 = show if not o AUTOCVAR_SAVE(_hud_panel_strafehud_demo, bool, false, "strafehud changes angle during configure"); AUTOCVAR_SAVE(hud_panel_strafehud_dynamichud, bool, true, "apply the dynamic hud effects to this panel"); AUTOCVAR_SAVE(hud_panel_strafehud_mode, int, 0, "strafehud mode which controls whether the strafehud is centered at \"0\" = view angle, \"1\" = velocity angle"); -AUTOCVAR_SAVE(hud_panel_strafehud_range, float, 90, "the angle range up to 360 degrees displayed on the strafehud, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)"); +AUTOCVAR_SAVE(hud_panel_strafehud_range, float, 90, "the angle range up to 360 degrees displayed on the strafehud, \"-1\" = current fov, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)"); AUTOCVAR_SAVE(hud_panel_strafehud_style, int, 2, "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = gradient for the strafe bar"); AUTOCVAR_SAVE(hud_panel_strafehud_unit, int, 1, "speed unit (1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots), length unit (1 = qu, 2 = m, 3 = km, 4 = mi, 5 = nmi)"); AUTOCVAR_SAVE(hud_panel_strafehud_unit_show, bool, true, "show units"); @@ -71,14 +71,17 @@ AUTOCVAR_SAVE(hud_panel_strafehud_sonar_pitch_range, float, 0.1, "dynamic playba AUTOCVAR_SAVE(hud_panel_strafehud_vangle, bool, false, "set to \"1\" to enable the vertical angle indicator"); AUTOCVAR_SAVE(hud_panel_strafehud_vangle_color, vector, '0.75 0.75 0.75', "color of the vertical angle text"); AUTOCVAR_SAVE(hud_panel_strafehud_vangle_size, float, 1, "size of the vertical angle text (relative to the panel height)"); +AUTOCVAR_SAVE(hud_panel_strafehud_projection, int, 1, "strafehud projection mode, \"0\" = Linear, \"1\" = Perspective, \"2\" = Panoramic"); -void HUD_Panel_DrawStrafeHUD(float, float, float, vector, float, int, int); +void HUD_Panel_DrawStrafeHUD(float, float, float, vector, float, int, int, bool, float); vector StrafeHUD_mixColors(vector, vector, float); -void StrafeHUD_drawGradient(vector, vector, vector, float, float, float, float, int); +void StrafeHUD_drawGradient(vector, vector, vector, float, float, float, float, int, float); float GetLengthUnitFactor(int); string GetLengthUnit(int); void StrafeHUD_drawStrafeArrow(vector, float, vector, float, bool); bool StrafeHUD_drawTextIndicator(string, float, vector, float, float, float, int); +float StrafeHUD_projectOffset(float, float); +float StrafeHUD_projectWidth(float, float, float); const int STRAFEHUD_MODE_VIEW_CENTERED = 0; const int STRAFEHUD_MODE_VELOCITY_CENTERED = 1; @@ -106,3 +109,7 @@ const int STRAFEHUD_INDICATOR_DASHED = 2; const int STRAFEHUD_TEXT_TOP = 0; const int STRAFEHUD_TEXT_BOTTOM = 1; + +const int STRAFEHUD_PROJECTION_LINEAR = 0; +const int STRAFEHUD_PROJECTION_PERSPECTIVE = 1; +const int STRAFEHUD_PROJECTION_PANORAMIC = 2; -- 2.39.2