]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
strafehud: refactor the angle indicator code
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Mon, 9 Sep 2024 04:25:03 +0000 (06:25 +0200)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Mon, 9 Sep 2024 04:25:03 +0000 (06:25 +0200)
draw each indicator in a separate function call

the code is now simpler and some unnecssary logic got removed

qcsrc/client/hud/panel/strafehud.qc
qcsrc/client/hud/panel/strafehud/core.qc
qcsrc/client/hud/panel/strafehud/core.qh

index 8598fd7aeb87f7bb803df615b4fd8568762aaca6..dc6f90608dab69419d5131dba82ab21aa286c805 100644 (file)
@@ -397,19 +397,132 @@ void HUD_StrafeHUD()
 
                StrafeHUD_DrawDirectionIndicator(direction, opposite_direction, fwd);
 
-               vector angle_indicator_info = StrafeHUD_DrawAngleIndicator(
-                       angle, wishangle, bestangle, absolute_bestangle,
-                       absolute_prebestangle, opposite_bestangle, antiflicker_angle,
-                       moving, opposite_direction, direction, mode, hudangle);
-
-               // unpack return value from vector
-               float strafe_ratio = angle_indicator_info.x;
-               float angle_offset_top = angle_indicator_info.y;
-               float angle_offset_bottom = angle_indicator_info.z;
-
-               // make sure text does not draw inside the strafehud bar
-               text_offset_top = max(angle_offset_top, text_offset_top);
-               text_offset_bottom = max(angle_offset_bottom, text_offset_bottom);
+               // determine the strafing ratio and the angle indicator color
+               vector currentangle_color = autocvar_hud_panel_strafehud_angle_neutral_color;
+               float strafe_ratio = 0;
+               if(moving)
+               {
+                       float moveangle = fabs(angle + wishangle);
+
+                       // player is overturning
+                       if(moveangle >= 90)
+                       {
+                               currentangle_color = autocvar_hud_panel_strafehud_angle_overturn_color;
+                               strafe_ratio = (moveangle - 90) / 90;
+                               if(strafe_ratio > 1) strafe_ratio = 2 - strafe_ratio;
+                               strafe_ratio *= -1;
+                       }
+                       // player gains speed by strafing
+                       else if(moveangle >= absolute_bestangle)
+                       {
+                               currentangle_color = autocvar_hud_panel_strafehud_angle_accel_color;
+                               strafe_ratio = (90 - moveangle) / (90 - absolute_bestangle);
+                       }
+                       else if(moveangle >= absolute_prebestangle)
+                       {
+                               if(autocvar_hud_panel_strafehud_bar_preaccel)
+                                       currentangle_color = autocvar_hud_panel_strafehud_angle_accel_color;
+                               strafe_ratio = (moveangle - absolute_prebestangle) / (absolute_bestangle - absolute_prebestangle);
+                       }
+
+                       if(autocvar_hud_panel_strafehud_style == STRAFEHUD_STYLE_GRADIENT)
+                               currentangle_color = StrafeHUD_mixColors(
+                                       autocvar_hud_panel_strafehud_angle_neutral_color,
+                                       currentangle_color, fabs(strafe_ratio));
+               }
+
+               float currentangle = 0;
+               if(mode == STRAFEHUD_MODE_VELOCITY_CENTERED)
+               {
+                       // avoid switching side too much at ±180° if anti flicker is triggered
+                       if(fabs(angle) <= 180 - antiflicker_angle)
+                               currentangle = angle;
+               }
+
+               // current angle size calculation
+               vector currentangle_size;
+               currentangle_size.x = max(panel_size.x * min(autocvar_hud_panel_strafehud_angle_width, 10), 1);
+               currentangle_size.y = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_height, 10), 1);
+               currentangle_size.z = 0;
+
+               float num_dashes = nearbyint(autocvar_hud_panel_strafehud_angle_dashes);
+
+               // adjust angle indicator line depending on style
+               switch(autocvar_hud_panel_strafehud_angle_style)
+               {
+                       case STRAFEHUD_INDICATOR_DASHED:
+                               break;
+                       case STRAFEHUD_INDICATOR_SOLID:
+                               num_dashes = 1;
+                               break;
+                       case STRAFEHUD_INDICATOR_NONE:
+                       default:
+                               num_dashes = 0;
+                               break;
+               }
+
+               bool has_top_arrow = autocvar_hud_panel_strafehud_angle_arrow == 1 || autocvar_hud_panel_strafehud_angle_arrow >= 3;
+               bool has_bottom_arrow = autocvar_hud_panel_strafehud_angle_arrow >= 2;
+
+               // there's only one size cvar for the arrows, they will always have a 45° angle to ensure proper rendering without antialiasing
+               float arrow_size = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_size, 10), 1);
+
+               if(num_dashes > 0 || has_top_arrow || has_bottom_arrow)
+               {
+                       bool angle_indicator_visible = false;
+
+                       if(autocvar_hud_panel_strafehud_bestangle && direction != STRAFEHUD_DIRECTION_NONE)
+                       {
+                               float ghostangle = opposite_direction ? opposite_bestangle : bestangle;
+
+                               StrafeHUD_DrawAngleIndicator(
+                                       ghostangle, currentangle_size, arrow_size, num_dashes,
+                                       has_top_arrow, has_bottom_arrow, autocvar_hud_panel_strafehud_bestangle_color,
+                                       autocvar_hud_panel_strafehud_bestangle_alpha, hudangle);
+
+                               if(autocvar_hud_panel_strafehud_bestangle_alpha > 0)
+                                       angle_indicator_visible = true;
+                       }
+
+                       StrafeHUD_DrawAngleIndicator(
+                               currentangle, currentangle_size, arrow_size, num_dashes,
+                               has_top_arrow, has_bottom_arrow, currentangle_color,
+                               autocvar_hud_panel_strafehud_angle_alpha, hudangle);
+
+                       if(autocvar_hud_panel_strafehud_angle_alpha > 0)
+                               angle_indicator_visible = true;
+
+                       // offset text by amount the angle indicator extrudes from the strafehud bar
+                       if(angle_indicator_visible)
+                       {
+                               float line_height_offset = currentangle_size.y;
+
+                               // amount line extrudes from the strafehud bar
+                               line_height_offset = (line_height_offset - panel_size.y) / 2;
+
+                               // further offset the top text offset if the top arrow is drawn
+                               float angle_offset_top;
+                               if(has_top_arrow)
+                                       angle_offset_top = line_height_offset + arrow_size;
+                               else if(num_dashes > 0)
+                                       angle_offset_top = line_height_offset;
+                               else
+                                       angle_offset_top = 0;
+
+                               // further offset the bottom text offset if the bottom arrow is drawn
+                               float angle_offset_bottom;
+                               if(has_bottom_arrow)
+                                       angle_offset_bottom = line_height_offset + arrow_size;
+                               else if(num_dashes > 0)
+                                       angle_offset_bottom = line_height_offset;
+                               else
+                                       angle_offset_bottom = 0;
+
+                               // make sure text does not draw inside the strafehud bar
+                               text_offset_top = max(angle_offset_top, text_offset_top);
+                               text_offset_bottom = max(angle_offset_bottom, text_offset_bottom);
+                       }
+               }
 
                text_offset_bottom += StrafeHUD_drawVerticalAngle(text_offset_bottom);
 
index 30cccb7f3e217da030b089b30876e4f7529aa5eb..501fe018792a7dc1cafafb02ab1863df850e18dc 100644 (file)
@@ -184,187 +184,65 @@ void StrafeHUD_DrawStrafeMeter(
        }
 }
 
-// draw the actual strafe angle
-// TODO: break this apart so that each angle indicator is drawn in an individual function call
-vector StrafeHUD_DrawAngleIndicator(float angle, float wishangle,
-       float bestangle, float absolute_bestangle, float absolute_prebestangle,
-       float opposite_bestangle, float antiflicker_angle, bool moving, bool opposite_direction, int direction,
-       int mode, float hudangle)
+// draw the actual strafe angle indicator
+void StrafeHUD_DrawAngleIndicator(
+       float angle, vector line_size, float arrow_size, int num_dashes,
+       bool has_top_arrow, bool has_bottom_arrow, vector color, float alpha, float hudangle)
 {
-       float currentangle = 0;
-       if(mode == STRAFEHUD_MODE_VELOCITY_CENTERED)
-       {
-               // avoid switching side too much at ±180° if anti flicker is triggered
-               if(fabs(angle) <= (180 - antiflicker_angle))
-               {
-                       // bound to HUD area
-                       currentangle = bound(-hudangle / 2, angle, hudangle / 2);
-                       currentangle = StrafeHUD_projectAngle(currentangle, hudangle, false);
-               }
-       }
-       float currentangle_offset = StrafeHUD_angleToOffset(currentangle, hudangle);
+       if(alpha <= 0) return;
 
-       vector currentangle_color = autocvar_hud_panel_strafehud_angle_neutral_color;
-       float strafe_ratio = 0;
-       if(moving)
-       {
-               float moveangle = fabs(angle + wishangle);
+       // bound to HUD area
+       angle = bound(-hudangle / 2, angle, hudangle / 2);
+       angle = StrafeHUD_projectAngle(angle, hudangle, false);
 
-               // player is overturning
-               if(moveangle >= 90)
-               {
-                       currentangle_color = autocvar_hud_panel_strafehud_angle_overturn_color;
-                       strafe_ratio = (moveangle - 90) / 90;
-                       if(strafe_ratio > 1) strafe_ratio = 2 - strafe_ratio;
-                       strafe_ratio *= -1;
-               }
-               // player gains speed by strafing
-               else if(moveangle >= absolute_bestangle)
-               {
-                       currentangle_color = autocvar_hud_panel_strafehud_angle_accel_color;
-                       strafe_ratio = (90 - moveangle) / (90 - absolute_bestangle);
-               }
-               else if(moveangle >= absolute_prebestangle)
-               {
-                       if(autocvar_hud_panel_strafehud_bar_preaccel)
-                               currentangle_color = autocvar_hud_panel_strafehud_angle_accel_color;
-                       strafe_ratio = (moveangle - absolute_prebestangle) / (absolute_bestangle - absolute_prebestangle);
-               }
+       float offset = StrafeHUD_angleToOffset(angle, hudangle);
 
-               if(autocvar_hud_panel_strafehud_style == STRAFEHUD_STYLE_GRADIENT)
-                       currentangle_color = StrafeHUD_mixColors(autocvar_hud_panel_strafehud_angle_neutral_color, currentangle_color, fabs(strafe_ratio));
-       }
+       StrafeHUD_DrawAngleIndicatorLine(line_size, offset, num_dashes, color, alpha);
 
-       // current angle size calculation
-       vector currentangle_size;
-       currentangle_size.x = max(panel_size.x * min(autocvar_hud_panel_strafehud_angle_width, 10), 1);
-       currentangle_size.y = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_height, 10), 1);
-       currentangle_size.z = 0;
+       if(has_top_arrow)
+               StrafeHUD_DrawAngleIndicatorArrow(arrow_size, offset, line_size, color, alpha, true);
 
-       float angleheight_offset = currentangle_size.y;
-       float ghost_angle = 0;
-       if(autocvar_hud_panel_strafehud_bestangle && direction != STRAFEHUD_DIRECTION_NONE)
-       {
-               // bound to HUD area
-               ghost_angle = bound(-hudangle / 2, (opposite_direction ? opposite_bestangle : bestangle), hudangle / 2);
-               ghost_angle = StrafeHUD_projectAngle(ghost_angle, hudangle, false);
-       }
-       float ghost_offset = StrafeHUD_angleToOffset(ghost_angle, hudangle);
+       if(has_bottom_arrow)
+               StrafeHUD_DrawAngleIndicatorArrow(arrow_size, offset, line_size, color, alpha, false);
+}
 
-       switch(autocvar_hud_panel_strafehud_angle_style)
-       {
-               case STRAFEHUD_INDICATOR_SOLID:
-                       if(currentangle_size.x > 0 && currentangle_size.y > 0)
-                       {
-                               if(autocvar_hud_panel_strafehud_bestangle && direction != STRAFEHUD_DIRECTION_NONE)
-                                       drawfill(
-                                               panel_pos - eY * ((currentangle_size.y - panel_size.y) / 2) + eX * (ghost_offset - currentangle_size.x / 2),
-                                               currentangle_size, autocvar_hud_panel_strafehud_bestangle_color,
-                                               autocvar_hud_panel_strafehud_bestangle_alpha * panel_fg_alpha,
-                                               DRAWFLAG_NORMAL);
-                               drawfill(
-                                       panel_pos - eY * ((currentangle_size.y - panel_size.y) / 2) + eX * (currentangle_offset - currentangle_size.x / 2),
-                                       currentangle_size, currentangle_color,
-                                       autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha,
-                                       DRAWFLAG_NORMAL);
-                       }
-                       break;
-               case STRAFEHUD_INDICATOR_DASHED:
-                       if(currentangle_size.x > 0 && currentangle_size.y > 0)
-                       {
-                               vector line_size = currentangle_size;
-                               line_size.y = currentangle_size.y / (bound(2, autocvar_hud_panel_strafehud_angle_dashes, currentangle_size.y) * 2 - 1);
-                               for(float i = 0; i < currentangle_size.y; i += line_size.y * 2)
-                               {
-                                       if(i + line_size.y * 2 >= currentangle_size.y)
-                                               line_size.y = currentangle_size.y - i;
-                                       if(autocvar_hud_panel_strafehud_bestangle && direction != STRAFEHUD_DIRECTION_NONE)
-                                               drawfill(
-                                                       panel_pos - eY * ((currentangle_size.y - panel_size.y) / 2 - i) + eX * (ghost_offset - line_size.x / 2),
-                                                       line_size, autocvar_hud_panel_strafehud_bestangle_color,
-                                                       autocvar_hud_panel_strafehud_bestangle_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
-                                       drawfill(
-                                               panel_pos - eY * ((currentangle_size.y - panel_size.y) / 2 - i) + eX * (currentangle_offset - line_size.x / 2),
-                                               line_size, currentangle_color,
-                                               autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
-                               }
-                       }
-                       break;
-               case STRAFEHUD_INDICATOR_NONE:
-               default:
-                       // do not offset text and arrows if the angle indicator line is not drawn
-                       angleheight_offset = panel_size.y;
-                       currentangle_size = '0 0 0';
-       }
+// draw the line of the angle indicator
+void StrafeHUD_DrawAngleIndicatorLine(vector size, float offset, int num_dashes, vector color, float alpha)
+{
+       if(num_dashes <= 0 || size.x <= 0 || size.y <= 0) return;
 
-       vector angle_indicator_info = StrafeHUD_DrawAngleIndicatorArrow(
-               currentangle_offset, currentangle_size, currentangle_color, ghost_offset,
-               angleheight_offset, direction, hudangle);
+       vector segment_size = size;
+       segment_size.y = size.y / (bound(1, num_dashes, size.y) * 2 - 1);
 
-       // return infomration about the angle indicator packed into a vector
-       angle_indicator_info.x = strafe_ratio;
-       return angle_indicator_info;
+       for(float i = 0; i < size.y; i += segment_size.y * 2)
+       {
+               // check if last iteration
+               if(i + segment_size.y * 2 >= size.y)
+                       segment_size.y = size.y - i;
+
+               drawfill(
+                       panel_pos - eY * ((size.y - panel_size.y) / 2 - i) + eX * (offset - segment_size.x / 2),
+                       segment_size, color, alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+       }
 }
 
 // draw the arrows on the angle indicator
-// TODO: break this apart so that each angle indicator is drawn in an individual function call
-vector StrafeHUD_DrawAngleIndicatorArrow(float currentangle_offset, vector currentangle_size,
-       vector currentangle_color, float ghost_offset, float angleheight_offset,
-       int direction, float hudangle)
+void StrafeHUD_DrawAngleIndicatorArrow(float size, float offset, vector line_size, vector color, float alpha, bool top)
 {
-       float angle_offset_top = 0, angle_offset_bottom = 0;
+       if(size <= 0) return;
 
-       // offset text if any angle indicator is drawn
-       if((autocvar_hud_panel_strafehud_angle_alpha > 0) ||
-          (autocvar_hud_panel_strafehud_bestangle && autocvar_hud_panel_strafehud_bestangle_alpha > 0))
+       if(top)
        {
-               // offset text by amount the angle indicator extrudes from the strafehud bar
-               angle_offset_top = angle_offset_bottom = (angleheight_offset - panel_size.y) / 2;
+               StrafeHUD_drawStrafeArrow(
+                       panel_pos + eY * ((panel_size.y - line_size.y) / 2) + eX * offset,
+                       size, color, alpha * panel_fg_alpha, true, line_size.x);
        }
-
-       if(autocvar_hud_panel_strafehud_angle_arrow > 0)
+       else
        {
-               // there's only one size cvar for the arrows, they will always have a 45° angle to ensure proper rendering without antialiasing
-               float arrow_size = max(panel_size.y * min(autocvar_hud_panel_strafehud_angle_arrow_size, 10), 1);
-
-               if(arrow_size > 0)
-               {
-                       if(autocvar_hud_panel_strafehud_angle_arrow == 1 || autocvar_hud_panel_strafehud_angle_arrow >= 3)
-                       {
-                               if(autocvar_hud_panel_strafehud_bestangle && direction != STRAFEHUD_DIRECTION_NONE)
-                                       StrafeHUD_drawStrafeArrow(
-                                               panel_pos + eY * ((panel_size.y - angleheight_offset) / 2) + eX * ghost_offset,
-                                               arrow_size, autocvar_hud_panel_strafehud_bestangle_color,
-                                               autocvar_hud_panel_strafehud_bestangle_alpha * panel_fg_alpha, true, currentangle_size.x);
-                               StrafeHUD_drawStrafeArrow(
-                                       panel_pos + eY * ((panel_size.y - angleheight_offset) / 2) + eX * currentangle_offset,
-                                       arrow_size, currentangle_color,
-                                       autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha, true, currentangle_size.x);
-
-                               angle_offset_top += arrow_size; // further offset the top text offset if the top arrow is drawn
-                       }
-                       if(autocvar_hud_panel_strafehud_angle_arrow >= 2)
-                       {
-                               if(autocvar_hud_panel_strafehud_bestangle && direction != STRAFEHUD_DIRECTION_NONE)
-                                       StrafeHUD_drawStrafeArrow(
-                                               panel_pos + eY * ((panel_size.y - angleheight_offset) / 2 + angleheight_offset) + eX * ghost_offset,
-                                               arrow_size, autocvar_hud_panel_strafehud_bestangle_color,
-                                               autocvar_hud_panel_strafehud_bestangle_alpha * panel_fg_alpha, false, currentangle_size.x);
-                               StrafeHUD_drawStrafeArrow(
-                                       panel_pos + eY * ((panel_size.y - angleheight_offset) / 2 + angleheight_offset) + eX * currentangle_offset,
-                                       arrow_size, currentangle_color,
-                                       autocvar_hud_panel_strafehud_angle_alpha * panel_fg_alpha, false, currentangle_size.x);
-
-                               angle_offset_bottom += arrow_size; // further offset the bottom text offset if the bottom arrow is drawn
-                       }
-               }
+               StrafeHUD_drawStrafeArrow(
+                       panel_pos + eY * ((panel_size.y - line_size.y) / 2 + line_size.y) + eX * offset,
+                       size, color, alpha * panel_fg_alpha, false, line_size.x);
        }
-
-       // return top and bottom angle offsets packed into a vector
-       vector angle_offsets = '0 0 0';
-       angle_offsets.y = angle_offset_top;
-       angle_offsets.z = angle_offset_bottom;
-       return angle_offsets;
 }
 
 // direction indicator
index da527c1119d0acea8ce8fbbcc7bd10836ce664d2..9f9dd081a507b356c3844d2ba7b028e774a803aa 100644 (file)
@@ -1,11 +1,9 @@
 #pragma once
 #include "../strafehud.qh"
 
-vector StrafeHUD_DrawAngleIndicatorArrow(
-       float, vector, vector, float, float, int, float);
-vector StrafeHUD_DrawAngleIndicator(
-       float, float, float, float, float,
-       float, float, bool, bool, int, int, float);
+void StrafeHUD_DrawAngleIndicator(float, vector, float, int, bool, bool, vector, float, float);
+void StrafeHUD_DrawAngleIndicatorLine(vector, float, int, vector, float);
+void StrafeHUD_DrawAngleIndicatorArrow(float, float, vector, vector, float, bool);
 void StrafeHUD_DrawDirectionIndicator(int, bool, bool);
 void StrafeHUD_DrawStrafeMeter(
        float, float, float, float, float, float, float,