From: Juhu <5894800-Juhu_@users.noreply.gitlab.com> Date: Mon, 9 Sep 2024 04:25:03 +0000 (+0200) Subject: strafehud: refactor the angle indicator code X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=bb642cb6f04528cb7fb81ef2aff2698b47e29ff2;p=xonotic%2Fxonotic-data.pk3dir.git strafehud: refactor the angle indicator code draw each indicator in a separate function call the code is now simpler and some unnecssary logic got removed --- diff --git a/qcsrc/client/hud/panel/strafehud.qc b/qcsrc/client/hud/panel/strafehud.qc index 8598fd7ae..dc6f90608 100644 --- a/qcsrc/client/hud/panel/strafehud.qc +++ b/qcsrc/client/hud/panel/strafehud.qc @@ -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); diff --git a/qcsrc/client/hud/panel/strafehud/core.qc b/qcsrc/client/hud/panel/strafehud/core.qc index 30cccb7f3..501fe0187 100644 --- a/qcsrc/client/hud/panel/strafehud/core.qc +++ b/qcsrc/client/hud/panel/strafehud/core.qc @@ -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 diff --git a/qcsrc/client/hud/panel/strafehud/core.qh b/qcsrc/client/hud/panel/strafehud/core.qh index da527c111..9f9dd081a 100644 --- a/qcsrc/client/hud/panel/strafehud/core.qh +++ b/qcsrc/client/hud/panel/strafehud/core.qh @@ -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,