]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/dynamic_hud
authorterencehill <piuntn@gmail.com>
Sun, 1 May 2016 07:56:58 +0000 (09:56 +0200)
committerterencehill <piuntn@gmail.com>
Sun, 1 May 2016 07:56:58 +0000 (09:56 +0200)
39 files changed:
_hud_common.cfg
defaultXonotic.cfg
qcsrc/client/autocvars.qh
qcsrc/client/hud/hud.qc
qcsrc/client/hud/hud.qh
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/ammo.qc
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/chat.qc
qcsrc/client/hud/panel/engineinfo.qc
qcsrc/client/hud/panel/healtharmor.qc
qcsrc/client/hud/panel/infomessages.qc
qcsrc/client/hud/panel/modicons.qc
qcsrc/client/hud/panel/notify.qc
qcsrc/client/hud/panel/physics.qc
qcsrc/client/hud/panel/powerups.qc
qcsrc/client/hud/panel/pressedkeys.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/racetimer.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/score.qc
qcsrc/client/hud/panel/timer.qc
qcsrc/client/hud/panel/vote.qc
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/main.qc
qcsrc/client/mapvoting.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/miscfunctions.qh
qcsrc/client/scoreboard.qc
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/common/debug.qh
qcsrc/common/minigames/cl_minigames_hud.qc
qcsrc/common/mutators/mutator/damagetext/damagetext.qc
qcsrc/common/mutators/mutator/itemstime.qc
qcsrc/dpdefs/upstream/csprogsdefs.qc
qcsrc/lib/draw.qh
qcsrc/lib/string.qh
qcsrc/menu/xonotic/dialog_settings_game_hud.qc

index 0fbf103d5542771a10077518df1bf40f4c55d08f..0f3f24ba19a43d299e7ca9f8a64fd61dc1b29692 100644 (file)
@@ -45,6 +45,24 @@ seta hud_panel_mapvote          1 "enable this panel"
 seta hud_panel_itemstime        2 "enable this panel, 1 = show when spectating, 2 = even playing in warmup stage"
 seta hud_panel_quickmenu        1 "enable this panel"
 
+seta hud_panel_weapons_dynamichud          1 "apply the dynamic hud effects to this panel"
+seta hud_panel_ammo_dynamichud             1 "apply the dynamic hud effects to this panel"
+seta hud_panel_powerups_dynamichud         1 "apply the dynamic hud effects to this panel"
+seta hud_panel_healtharmor_dynamichud      1 "apply the dynamic hud effects to this panel"
+seta hud_panel_notify_dynamichud           1 "apply the dynamic hud effects to this panel"
+seta hud_panel_timer_dynamichud            1 "apply the dynamic hud effects to this panel"
+seta hud_panel_radar_dynamichud            1 "apply the dynamic hud effects to this panel"
+seta hud_panel_score_dynamichud            1 "apply the dynamic hud effects to this panel"
+seta hud_panel_racetimer_dynamichud        1 "apply the dynamic hud effects to this panel"
+seta hud_panel_vote_dynamichud             1 "apply the dynamic hud effects to this panel"
+seta hud_panel_modicons_dynamichud         1 "apply the dynamic hud effects to this panel"
+seta hud_panel_pressedkeys_dynamichud      1 "apply the dynamic hud effects to this panel"
+seta hud_panel_engineinfo_dynamichud       1 "apply the dynamic hud effects to this panel"
+seta hud_panel_infomessages_dynamichud     0 "apply the dynamic hud effects to this panel"
+seta hud_panel_physics_dynamichud          1 "apply the dynamic hud effects to this panel"
+seta hud_panel_centerprint_dynamichud      1 "apply the dynamic hud effects to this panel"
+seta hud_panel_itemstime_dynamichud        1 "apply the dynamic hud effects to this panel"
+
 seta hud_panel_weapons_ammo_full_shells 60 "show 100% of the status bar at this ammo count"
 seta hud_panel_weapons_ammo_full_nails 320 "show 100% of the status bar at this ammo count"
 seta hud_panel_weapons_ammo_full_cells 180 "show 100% of the status bar at this ammo count"
@@ -88,6 +106,15 @@ alias hud_panel_radar_maximized "cl_cmd hud radar"
 // other hud cvars
 seta hud_panel_update_interval 2 "how often (in seconds) common panel cvars are reloaded"
 
+seta hud_dynamic_follow 1 "HUD moves around following player's movement (effect shared with cl_followmodel, can be enabled independently from it though)"
+seta hud_dynamic_follow_scale 0.01 "HUD following scale"
+seta hud_dynamic_follow_scale_xyz "1 1 1" "HUD following scale for the x, y and z axis"
+
+seta hud_dynamic_shake 1 "shake the HUD when hurt"
+seta hud_dynamic_shake_damage_max 90 "damage value at which the HUD shake effect is maximum"
+seta hud_dynamic_shake_damage_min 10 "damage value at which the HUD shake effect is minimum"
+seta hud_dynamic_shake_scale 0.4 "HUD shake scale"
+
 seta hud_showbinds 1   "what to show in the HUD to indicate certain keys to press: 0 display commands, 1 bound keys, 2 both"
 seta hud_showbinds_limit 2     "maximum number of bound keys to show for a command. 0 for unlimited"
 set _hud_showbinds_reload 0    "set it to 1 to reload binds if you changed any. It is reset to 0 automatically"
index 2056f15115d79f83f170c5128fc9a38ea0b4d040..1f4cf16be8458a5bc0c76f4ad4f298861c27137a 100644 (file)
@@ -852,6 +852,7 @@ seta scoreboard_offset_right 0.15 "how far (by percent) the scoreboard is offset
 seta scoreboard_offset_vertical 0.05 "how far (by percent) the scoreboard is offset from the top and bottom of the screen"
 seta scoreboard_bg_scale 0.25 "scale for the tiled scoreboard background"
 seta scoreboard_respawntime_decimals 1 "decimal places to show for the respawntime countdown display on the scoreboard"
+seta scoreboard_dynamichud 1 "apply the dynamic hud effects to the scoreboard"
 
 seta accuracy_color_levels "0 20 100" "accuracy values at which a specified color (accuracy_color<X>) will be used. If your accuracy is between 2 of these values then a mix of the Xth and X+1th colors will be used. You can specify up to 10 values, in increasing order"
 seta accuracy_color0 "1 0 0"
index d797cee330f4c6dbb358aab71d6c9dbf79f0114e..e63c9e4cd9331b6211c3155fa95ae217f3626f39 100644 (file)
@@ -193,6 +193,23 @@ string autocvar_hud_dock;
 float autocvar_hud_dock_alpha;
 string autocvar_hud_dock_color;
 bool autocvar_hud_dock_color_team;
+bool autocvar_hud_panel_weapons_dynamichud      = true;
+bool autocvar_hud_panel_ammo_dynamichud         = true;
+bool autocvar_hud_panel_powerups_dynamichud     = true;
+bool autocvar_hud_panel_healtharmor_dynamichud  = true;
+bool autocvar_hud_panel_notify_dynamichud       = true;
+bool autocvar_hud_panel_timer_dynamichud        = true;
+bool autocvar_hud_panel_radar_dynamichud        = true;
+bool autocvar_hud_panel_score_dynamichud        = true;
+bool autocvar_hud_panel_racetimer_dynamichud    = true;
+bool autocvar_hud_panel_vote_dynamichud         = true;
+bool autocvar_hud_panel_modicons_dynamichud     = true;
+bool autocvar_hud_panel_pressedkeys_dynamichud  = true;
+bool autocvar_hud_panel_engineinfo_dynamichud   = true;
+bool autocvar_hud_panel_infomessages_dynamichud = false;
+bool autocvar_hud_panel_physics_dynamichud      = true;
+bool autocvar_hud_panel_centerprint_dynamichud  = true;
+bool autocvar_hud_panel_itemstime_dynamichud    = true;
 bool autocvar_hud_panel_ammo;
 bool autocvar_hud_panel_ammo_iconalign;
 int autocvar_hud_panel_ammo_maxammo;
@@ -372,6 +389,7 @@ float autocvar_hud_shownames_offset;
 string autocvar_hud_skin;
 float autocvar_menu_mouse_speed;
 string autocvar_menu_skin;
+float autocvar_r_drawviewmodel;
 int autocvar_r_fakelight;
 int autocvar_r_fullbright;
 float autocvar_r_letterbox;
@@ -398,6 +416,7 @@ float autocvar_scoreboard_offset_left;
 float autocvar_scoreboard_offset_right;
 float autocvar_scoreboard_offset_vertical;
 float autocvar_scoreboard_respawntime_decimals;
+float autocvar_scoreboard_dynamichud = 1;
 bool autocvar_v_flipped;
 float autocvar_vid_conheight;
 float autocvar_vid_conwidth;
index d89f3106454f1a29abbc5d015438b9cdbd94a679..c87cb5a89cd853e3561826106d9b31fd2dd4ac2c 100644 (file)
@@ -136,6 +136,9 @@ void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, flo
        else if(length_ratio < 0)
                return;
 
+       theOrigin = HUD_Shift(theOrigin);
+       theSize = HUD_Scale(theSize);
+
        vector square;
        vector width, height;
        if(vertical) {
@@ -231,6 +234,9 @@ void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float theA
        if(!theAlpha)
                return;
 
+       pos = HUD_Shift(pos);
+       mySize = HUD_Scale(mySize);
+
        string pic;
        pic = strcat(hud_skin_path, "/num_leading");
        if(precache_pic(pic) == "") {
@@ -381,6 +387,106 @@ void HUD_Reset()
                HUD_Mod_CTF_Reset();
 }
 
+float autocvar_hud_dynamic_shake;
+float autocvar_hud_dynamic_shake_damage_max;
+float autocvar_hud_dynamic_shake_damage_min;
+float autocvar_hud_dynamic_shake_scale;
+float hud_dynamic_shake_x[10] = {0,    1, -0.7,  0.5, -0.3,  0.2, -0.1,  0.1,  0.0, 0};
+float hud_dynamic_shake_y[10] = {0,  0.4,  0.8, -0.2, -0.6,  0.0,  0.3,  0.1, -0.1, 0};
+bool Hud_Shake_Update()
+{
+       if(time - hud_dynamic_shake_time < 0)
+               return false;
+
+       float anim_speed = 17 + 9 * hud_dynamic_shake_factor;
+       float elapsed_time = (time - hud_dynamic_shake_time) * anim_speed;
+       int i = floor(elapsed_time);
+       if(i >= 9)
+               return false;
+
+       float f = elapsed_time - i;
+       hud_dynamic_shake_realofs.x = (1 - f) * hud_dynamic_shake_x[i] + f * hud_dynamic_shake_x[i+1];
+       hud_dynamic_shake_realofs.y = (1 - f) * hud_dynamic_shake_y[i] + f * hud_dynamic_shake_y[i+1];
+       hud_dynamic_shake_realofs.z = 0;
+       hud_dynamic_shake_realofs *= hud_dynamic_shake_factor * autocvar_hud_dynamic_shake_scale;
+       hud_dynamic_shake_realofs.x = bound(-0.1, hud_dynamic_shake_realofs.x, 0.1) * vid_conwidth;
+       hud_dynamic_shake_realofs.y = bound(-0.1, hud_dynamic_shake_realofs.y, 0.1) * vid_conheight;
+       return true;
+}
+
+void calc_followmodel_ofs(entity view);
+void Hud_Dynamic_Frame()
+{
+       vector ofs = '0 0 0';
+       hud_scale = '1 1 0';
+       hud_shift = '0 0 0';
+       if (autocvar_hud_dynamic_follow)
+       {
+               entity view = CSQCModel_server2csqc(player_localentnum - 1);
+               calc_followmodel_ofs(view);
+               ofs = -cl_followmodel_ofs * autocvar_hud_dynamic_follow_scale;
+               ofs.x *= autocvar_hud_dynamic_follow_scale_xyz.z;
+               ofs.y *= autocvar_hud_dynamic_follow_scale_xyz.x;
+               ofs.z *= autocvar_hud_dynamic_follow_scale_xyz.y;
+
+               if (fabs(ofs.x) < 0.001) ofs.x = 0;
+               if (fabs(ofs.y) < 0.001) ofs.y = 0;
+               if (fabs(ofs.z) < 0.001) ofs.z = 0;
+               ofs.x = bound(-0.1, ofs.x, 0.1);
+               ofs.y = bound(-0.1, ofs.y, 0.1);
+               ofs.z = bound(-0.1, ofs.z, 0.1);
+
+               hud_shift.x = ofs.y * vid_conwidth;
+               hud_shift.y = ofs.z * vid_conheight;
+               hud_shift.z = ofs.x;
+
+               hud_scale.x = (1 + hud_shift.z);
+               hud_scale.y = hud_scale.x;
+       }
+
+       if(autocvar_hud_dynamic_shake > 0)
+       {
+               if(hud_dynamic_shake_factor == -1) // don't allow the effect for this frame
+                       hud_dynamic_shake_factor = 0;
+               else
+               {
+                       static float old_health = 0;
+                       float health = max(-1, STAT(HEALTH));
+                       float new_hud_dynamic_shake_factor = 0;
+                       if (old_health - health >= autocvar_hud_dynamic_shake_damage_min
+                               && autocvar_hud_dynamic_shake_damage_max > autocvar_hud_dynamic_shake_damage_min
+                               && old_health > 0 && !intermission)
+                       {
+                               float m = max(autocvar_hud_dynamic_shake_damage_min, 1);
+                               new_hud_dynamic_shake_factor = (old_health - health - m) / (autocvar_hud_dynamic_shake_damage_max - m);
+                               if(new_hud_dynamic_shake_factor >= 1)
+                                       new_hud_dynamic_shake_factor = 1;
+                               if(new_hud_dynamic_shake_factor >= hud_dynamic_shake_factor)
+                               {
+                                       hud_dynamic_shake_factor = new_hud_dynamic_shake_factor;
+                                       hud_dynamic_shake_time = time;
+                               }
+                       }
+                       old_health = health;
+                       if(hud_dynamic_shake_factor)
+                               if(!Hud_Shake_Update())
+                                       hud_dynamic_shake_factor = 0;
+               }
+
+               if(hud_dynamic_shake_factor > 0)
+               {
+                       hud_shift.x += hud_dynamic_shake_realofs.x;
+                       hud_shift.y += hud_dynamic_shake_realofs.y;
+               }
+       }
+
+       hud_scale_center.x = 0.5 * vid_conwidth;
+       hud_scale_center.y = 0.5 * vid_conheight;
+
+       hud_scale_current = hud_scale;
+       hud_shift_current = hud_shift;
+}
+
 void HUD_Main()
 {
        int i;
@@ -395,6 +501,8 @@ void HUD_Main()
 
        HUD_Configure_Frame();
 
+       Hud_Dynamic_Frame();
+
        // panels that we want to be active together with the scoreboard
        // they must fade only when the menu does
        if(scoreboard_fade_alpha == 1)
index d46b11db571a7044d2acfec43562a8da05cbdb3f..2a53444669b7829c9818ca342ae8bf6484f0fafa 100644 (file)
@@ -22,9 +22,16 @@ REGISTER_REGISTRY(hud_panels)
 #define HUD_PANEL(NAME) HUD_PANEL_##NAME
 
 // draw the background/borders
-#define HUD_Panel_DrawBg(theAlpha) MACRO_BEGIN {                                                                                                                                                               \
-       if(panel.current_panel_bg != "0" && panel.current_panel_bg != "")                                                                                               \
-               draw_BorderPicture(panel_pos - '1 1 0' * panel_bg_border, panel.current_panel_bg, panel_size + '1 1 0' * 2 * panel_bg_border, panel_bg_color, panel_bg_alpha * theAlpha, '1 1 0' * (panel_bg_border/BORDER_MULTIPLIER));\
+#define HUD_Panel_DrawBg(theAlpha) MACRO_BEGIN { \
+       if(panel.current_panel_bg != "0" && panel.current_panel_bg != "") \
+               draw_BorderPicture( \
+                       HUD_Shift(panel_pos - '1 1 0' * panel_bg_border), \
+                       panel.current_panel_bg, \
+                       HUD_Scale(panel_size + '1 1 0' * 2 * panel_bg_border), \
+                       panel_bg_color, \
+                       panel_bg_alpha * theAlpha, \
+                       HUD_Scale('1 1 0' * (panel_bg_border/BORDER_MULTIPLIER)) \
+               ); \
 } MACRO_END
 
 int panel_order[hud_panels_MAX];
@@ -155,6 +162,24 @@ float chat_sizey;
 
 float current_player;
 
+float autocvar_hud_dynamic_follow;
+float autocvar_hud_dynamic_follow_scale;
+vector autocvar_hud_dynamic_follow_scale_xyz;
+
+vector hud_dynamic_shake_realofs;
+float hud_dynamic_shake_factor;
+float hud_dynamic_shake_time;
+
+// shared across viewmodel effects and dynamic hud code
+vector cl_followmodel_ofs;
+float cl_followmodel_time;
+
+vector hud_scale;
+vector hud_scale_current;
+vector hud_shift;
+vector hud_shift_current;
+vector hud_scale_center;
+
 float stringwidth_colors(string s, vector theSize);
 float stringwidth_nocolors(string s, vector theSize);
 void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float length_ratio, bool vertical, float baralign, vector theColor, float theAlpha, int drawflag);
index e7d74cf3e585690912667cd49df5c825456dc497..5ffec682c0cf0868cd8dc0df1baeb138393c43ed 100644 (file)
@@ -1262,6 +1262,7 @@ void HUD_Configure_Frame()
                        menu_enabled = 0;
                if(autocvar_hud_cursormode)
                        setcursormode(0);
+               hud_dynamic_shake_factor = -1;
        }
 }
 
index fda7887b1641d74d55f3b8a2e3c9ded8e36d7874..5c45ff0f331a1544be55bf6b4f3a262d7f704022 100644 (file)
@@ -110,6 +110,10 @@ void HUD_Ammo()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_ammo_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index 99e8baaa65807a2a390b85050a1f53a1c70838a7..afda329838c623f9d1e8b98712de71b82d8f5014 100644 (file)
@@ -186,6 +186,10 @@ void HUD_CenterPrint ()
                }
        }
 
+       if (autocvar_hud_panel_centerprint_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
 
        if (!centerprint_showing)
@@ -263,7 +267,7 @@ void HUD_CenterPrint ()
 
                // finally set the size based on the new theAlpha from subsequent fading
                sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize));
-               drawfontscale = sz * '1 1 0';
+               drawfontscale = hud_scale * sz;
 
                if (centerprint_countdown_num[j])
                        n = tokenizebyseparator(strreplace("^COUNT", count_seconds(centerprint_countdown_num[j]), centerprint_messages[j]), "\n");
@@ -278,7 +282,7 @@ void HUD_CenterPrint ()
                                getWrappedLine_remaining = argv(k);
                                while(getWrappedLine_remaining)
                                {
-                                       ts = getWrappedLine(panel_size.x * sz, fontsize, stringwidth_colors);
+                                       ts = getWrappedLine(panel_size.x * hud_scale.x * sz, fontsize, stringwidth_colors);
                                        if (ts != "")
                                                pos.y -= fontsize.y;
                                        else
@@ -294,13 +298,13 @@ void HUD_CenterPrint ()
                        getWrappedLine_remaining = argv(k);
                        while(getWrappedLine_remaining)
                        {
-                               ts = getWrappedLine(panel_size.x * sz, fontsize, stringwidth_colors);
+                               ts = getWrappedLine(panel_size.x * hud_scale.x * sz, fontsize, stringwidth_colors);
                                if (ts != "")
                                {
                                        if (align)
-                                               pos.x = panel_pos.x + (panel_size.x - stringwidth(ts, true, fontsize)) * align;
+                                               pos.x = panel_pos.x + (panel_size.x - stringwidth(ts, true, fontsize) * sz) * align;
                                        if (a > 0.5/255.0)  // Otherwise guaranteed invisible - don't show. This is checked a second time after some multiplications with other factors were done so temporary changes of these cannot cause flicker.
-                                               drawcolorcodedstring(pos + eY * 0.5 * (1 - sz) * fontsize.y, ts, fontsize, a, DRAWFLAG_NORMAL);
+                                               drawcolorcodedstring(pos + eY * 0.5 * (1 - sz * hud_scale.x) * fontsize.y, ts, fontsize, a, DRAWFLAG_NORMAL);
                                        pos.y += fontsize.y;
                                }
                                else
@@ -319,7 +323,7 @@ void HUD_CenterPrint ()
 
                        if (pos.y < panel_pos.y) // check if the next message can be shown
                        {
-                               drawfontscale = '1 1 0';
+                               drawfontscale = hud_scale;
                                return;
                        }
                }
@@ -331,12 +335,12 @@ void HUD_CenterPrint ()
 
                        if(pos.y > panel_pos.y + panel_size.y - fontsize.y) // check if the next message can be shown
                        {
-                               drawfontscale = '1 1 0';
+                               drawfontscale = hud_scale;
                                return;
                        }
                }
        }
-       drawfontscale = '1 1 0';
+       drawfontscale = hud_scale;
        if (all_messages_expired)
        {
                centerprint_showing = false;
index dd89b791ce2c2362513a86c03fee66894e68bb12..a27e7b9070f109e2786edde44affdf1ff7f9193d 100644 (file)
@@ -54,6 +54,8 @@ void HUD_Chat()
        pos = panel_pos;
        mySize = panel_size;
 
+       // chat messages don't scale properly since they are displayed directly by the engine
+       HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
 
        if(panel_bg_padding)
index ea136a21489abd1c111b457ec27855cd23a673fc..773c751d82680fd826b00ece67514a3891134935 100644 (file)
@@ -23,6 +23,10 @@ void HUD_EngineInfo()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_engineinfo_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index 8f279f2aadc2e1e1c46db7d7118af4da94a75c12..bc4291a948648e8eb5f8cf843c683cdc17d7ba1c 100644 (file)
@@ -62,6 +62,10 @@ void HUD_HealthArmor()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_healtharmor_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index 8199bd8dd6d82f10dfb9a031f3feea8266e63a02..a197963e75492145545a315b9de468585059cdce 100644 (file)
@@ -23,6 +23,10 @@ void HUD_InfoMessages()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_infomessages_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index 5b4665f563f8f10ceb22f94316cb8562da5219d3..f442d2df5253b62d1a86dd617d119c6572c6adde 100644 (file)
@@ -769,6 +769,10 @@ void HUD_ModIcons()
        else
                mod_alpha = bound(0, 1 - (time - mod_change) * 2, 1);
 
+       if (autocvar_hud_panel_modicons_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        if(mod_alpha)
                HUD_Panel_DrawBg(mod_alpha);
 
index 1f0e26b9a5e7274f8559ab7c402e6d619519e478..a5e923825a989fc13e9b76b9c077de5b4ce97c31 100644 (file)
@@ -48,6 +48,10 @@ void HUD_Notify()
                        return;
 
        HUD_Panel_UpdateCvars();
+       if (autocvar_hud_panel_notify_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
 
        if (!autocvar__hud_configure)
index 7a9f664eb233d89a9342d8838fb7f934f6a13299..371a9f344bf2990bfda62a2a3730d771f6f4d60b 100644 (file)
@@ -21,6 +21,10 @@ void HUD_Physics()
 
        draw_beginBoldFont();
 
+       if (autocvar_hud_panel_physics_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index 31a00794e3ed7977c2eb4bb04480831a2791191b..223bf72ce8efae4a679f8c6405673deaf1aac283 100644 (file)
@@ -109,6 +109,10 @@ void HUD_Powerups()
 
        // Draw panel background
        HUD_Panel_UpdateCvars();
+       if (autocvar_hud_panel_powerups_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
 
        // Set drawing area
index 3b512b1c33a622107fe73b558e32f8f425dd3a53..d0a4f39fdfd8fc956ce202376af7f5b55f90ac17 100644 (file)
@@ -13,6 +13,10 @@ void HUD_PressedKeys()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_pressedkeys_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index de4a05f132d185505b08c7e34c2dfcc94e6839f9..08d97ffd2e5a64027eb730017bce4f2ad9b2d17a 100644 (file)
@@ -621,6 +621,7 @@ void HUD_QuickMenu()
 
        HUD_Panel_UpdateCvars();
 
+       HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
 
        if(panel_bg_padding)
index 365ba01dd74babd7540df066241633f9001255fe..dd8bbdfec9375597df95e0f755309b21454af9e7 100644 (file)
@@ -89,6 +89,10 @@ void HUD_RaceTimer ()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_racetimer_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index 4a2e7ee2b345165afc75e18399b9c1de8147ab2f..7a8cb96e77a1f7cb0b3a8ee2277f92cd63ae0bf0 100644 (file)
@@ -275,6 +275,10 @@ void HUD_Radar()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_radar_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
@@ -285,7 +289,7 @@ void HUD_Radar()
        int color2;
        float scale2d, normalsize, bigsize;
 
-       teamradar_origin2d = pos + 0.5 * mySize;
+       teamradar_origin2d = HUD_Shift(pos + 0.5 * mySize);
        teamradar_size2d = mySize;
 
        if(minimapname == "")
@@ -294,7 +298,7 @@ void HUD_Radar()
        teamradar_loadcvars();
 
        scale2d = vlen_maxnorm2d(mi_picmax - mi_picmin);
-       teamradar_size2d = mySize;
+       teamradar_size2d = HUD_Scale(mySize);
 
        teamradar_extraclip_mins = teamradar_extraclip_maxs = '0 0 0'; // we always center
 
index 12114b4e356a712d8306439c8df0708da753eb3a..49a8fa5b7a465f2e362098031df2dce86a05a178 100644 (file)
@@ -144,6 +144,10 @@ void HUD_Score()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_score_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index b61f3c4c177ff2b8bafa7d280167dac7b898548d..5a7194a45849ee7967f97e2a9694fccaf3b97c0c 100644 (file)
@@ -14,6 +14,10 @@ void HUD_Timer()
        pos = panel_pos;
        mySize = panel_size;
 
+       if (autocvar_hud_panel_timer_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
index 502b237f7882efdb22662e33398b63890b3037f1..89c784a1083be4e0ece863ca00419549520c05de 100644 (file)
@@ -69,6 +69,10 @@ void HUD_Vote()
        mySize = panel_size;
 
        a = vote_alpha * (vote_highlighted ? autocvar_hud_panel_vote_alreadyvoted_alpha : 1);
+       if (autocvar_hud_panel_vote_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(a);
        a = panel_fg_alpha * a;
 
index cfacd59b60f831085e5216c8c86154f2c5d0cefe..7aac7a39e3d418929620db41e6beab51681b3840 100644 (file)
@@ -302,6 +302,10 @@ void HUD_Weapons()
        }
 
        // draw the background, then change the virtual size of it to better fit other items inside
+       if (autocvar_hud_panel_weapons_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
 
        if(center.x == -1)
index 7cbe6e125f14c5c7642bf8b3c039f4df2dc7ac70..7caf6905be1d0f47c36271f44e8c3f09d26fc4ba 100644 (file)
@@ -537,6 +537,7 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
                // clear race stuff
                race_laptime = 0;
                race_checkpointtime = 0;
+               hud_dynamic_shake_factor = -1;
        }
        if (autocvar_hud_panel_healtharmor_progressbar_gfx)
        {
index 3223bf120aa7cc012f9143e21bc671f12ee9031b..6773bd1553d371c3c9a9e40991bbcaa39cd933f9 100644 (file)
@@ -341,7 +341,6 @@ void MapVote_Draw()
                if ( mpos.x != mv_mousepos.x || mpos.y != mv_mousepos.y )
                        mv_selection_keyboard = 0;
                mv_mousepos = mpos;
-
        }
 
        center = (vid_conwidth - 1)/2;
@@ -360,6 +359,7 @@ void MapVote_Draw()
        pos.y = ymin;
        pos.z = 0;
 
+       HUD_Scale_Disable();
        draw_beginBoldFont();
 
        map = ((gametypevote) ? _("Decide the gametype") : _("Vote for a map"));
@@ -373,10 +373,8 @@ void MapVote_Draw()
                pos.x = center - stringwidth(mapvote_chosenmap, false, hud_fontsize * 1.5) * 0.5;
                drawstring(pos, mapvote_chosenmap, hud_fontsize * 1.5, '1 1 1', 1, DRAWFLAG_NORMAL);
                pos.y += hud_fontsize.y * 1.5;
-               pos.y += hud_fontsize.y * 0.5;
        }
-       else
-               pos.y += hud_fontsize.y * 0.5;
+       pos.y += hud_fontsize.y * 0.5;
 
        draw_endBoldFont();
 
index 970a681e37b202f9bfc2a49c6f2c6377b0a13715..8c0bf14ea432a2c120f9f6bbb80a8ab381875436 100644 (file)
@@ -224,6 +224,10 @@ void drawborderlines(float thickness, vector pos, vector dim, vector color, floa
 
 void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float theAlpha, float drawflag)
 {
+       pos = HUD_Shift(pos);
+       sz = HUD_Scale(sz);
+       area = HUD_Scale(area);
+
        vector current_pos = '0 0 0', end_pos, new_size = '0 0 0', ratio = '0 0 0';
        end_pos = pos + area;
 
@@ -258,6 +262,43 @@ void drawpic_aspect_skin_expanding_two(vector position, string pic, vector theSc
        drawpic_skin(position, pic, theScale, rgb, theAlpha * fadelerp, flag);
 }
 
+void HUD_Scale_Disable()
+{
+       hud_scale = '1 1 0';
+       hud_shift = '0 0 0';
+       drawfontscale = hud_scale;
+}
+
+void HUD_Scale_Enable()
+{
+       hud_scale = hud_scale_current;
+       hud_shift = hud_shift_current;
+       drawfontscale = hud_scale;
+}
+
+vector HUD_Scale(vector v)
+{
+       v.x = HUD_ScaleX(v.x);
+       v.y = HUD_ScaleY(v.y);
+       return v;
+}
+
+vector HUD_Shift(vector v)
+{
+       v.x = HUD_ShiftX(v.x);
+       v.y = HUD_ShiftY(v.y);
+       return v;
+}
+
+float stringwidth(string text, float handleColors, vector sz)
+{
+       vector dfs = drawfontscale;
+       drawfontscale = '1 1 0';
+       float r = stringwidth_builtin(text, handleColors, sz);
+       drawfontscale = dfs;
+       return r;
+}
+
 // drawstring wrapper to draw a string as large as possible with preserved aspect ratio into a box
 void drawstring_aspect(vector pos, string text, vector sz, vector color, float theAlpha, float drawflag) {
        SET_POS_AND_SZ_Y_ASPECT(false);
@@ -275,12 +316,16 @@ void drawstring_expanding(vector position, string text, vector theScale, vector
        float sz;
        sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
 
+       drawfontscale = hud_scale * sz;
+       vector dfs = drawfontscale;
        drawfontscale = sz * '1 1 0';
-       drawstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth(text, false, theScale * (sz / drawfontscale.x)) / (theScale.x * sz)), text, theScale * (sz / drawfontscale.x), rgb, theAlpha * (1 - fadelerp), flag);
+       float textaspect = stringwidth_builtin(text, false, theScale * (sz / drawfontscale.x)) / (theScale.x * sz);
+       drawfontscale = dfs;
+       drawstring(position + expandingbox_resize_centered_box_offset(sz, theScale, textaspect), text, HUD_Scale(theScale * (sz / drawfontscale.x)), rgb, theAlpha * (1 - fadelerp), flag);
        // width parameter:
-       //    (scale_x * sz / drawfontscale_x) * drawfontscale_x * SIZE1 / (scale_x * sz)
+       //    (scale_x * sz / drawfontscale.x) * drawfontscale.x * SIZE1 / (scale_x * sz)
        //    SIZE1
-       drawfontscale = '1 1 0';
+       drawfontscale = hud_scale;
 }
 
 // drawstring wrapper to draw a string as large as possible with preserved aspect ratio into a box
@@ -294,9 +339,10 @@ void drawcolorcodedstring_expanding(vector position, string text, vector theScal
        float sz;
        sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
 
-       drawfontscale = sz * '1 1 0';
-       drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth(text, true, theScale * (sz / drawfontscale.x)) / (theScale.x * sz)), text, theScale * (sz / drawfontscale.x), theAlpha * (1 - fadelerp), flag);
-       drawfontscale = '1 1 0';
+       drawfontscale = hud_scale * sz;
+       // eventually replace with drawcolorcodedstring
+       drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth_builtin(text, true, theScale * (sz / drawfontscale.x)) / (theScale.x * sz)), text, theScale * (sz / drawfontscale.x), theAlpha * (1 - fadelerp), flag);
+       drawfontscale = hud_scale;
 }
 
 void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, float theAlpha, float drawflag, float fadelerp) {
index 32563598b3f79ad2189aa2f2b48d54c9ea0e3b24..1f8790481f1a8d88a0193d9971d8b65b2dcbad4b 100644 (file)
@@ -44,6 +44,7 @@ float cvar_or(string cv, float v);
 
 vector project_3d_to_2d(vector vec);
 
+vector drawfontscale;
 #define draw_beginBoldFont()    MACRO_BEGIN { drawfont = FONT_USER + 2; } MACRO_END
 #define draw_endBoldFont()      MACRO_BEGIN { drawfont = FONT_USER + 1; } MACRO_END
 
@@ -55,6 +56,53 @@ void drawborderlines(float thickness, vector pos, vector dim, vector color, floa
 
 void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float theAlpha, float drawflag);
 
+void HUD_Scale_Disable();
+void HUD_Scale_Enable();
+
+#define HUD_ScaleX(f) (f * hud_scale.x)
+#define HUD_ScaleY(f) (f * hud_scale.y)
+#define HUD_ShiftX(f) (f + hud_shift.x + hud_shift.z * (f - hud_scale_center.x))
+#define HUD_ShiftY(f) (f + hud_shift.y + hud_shift.z * (f - hud_scale_center.y))
+vector HUD_Scale(vector v);
+vector HUD_Shift(vector v);
+
+// The following functions / macros must be called from within
+// the panel HUD / scoreboard code so that pos and size are scaled
+// when the hud_dynamic code is running.
+// Make use of stringwidth_builtin and draw*_builtin everywhere else.
+
+float stringwidth(string text, float handleColors, vector sz);
+
+#define drawpic(position, pic, size, rgb, alpha, flag) \
+       drawpic_builtin(HUD_Shift(position), pic, HUD_Scale(size), rgb, alpha, flag)
+
+#define drawcharacter(position, character, scale, rgb, alpha, flag) \
+       drawcharacter_builtin(HUD_Shift(position), text, scale, rgb, alpha, flag)
+
+#define drawstring(position, text, scale, rgb, alpha, flag) \
+       drawstring_builtin(HUD_Shift(position), text, scale, rgb, alpha, flag)
+
+#define drawcolorcodedstring(position, text, scale, alpha, flag) \
+       drawcolorcodedstring_builtin(HUD_Shift(position), text, scale, alpha, flag)
+
+#define drawcolorcodedstring2(position, text, scale, rgb, alpha, flag) \
+       drawcolorcodedstring2_builtin(HUD_Shift(position), text, scale, rgb, alpha, flag)
+
+#define drawfill(position, size, rgb, alpha, flag) \
+       drawfill_builtin(HUD_Shift(position), HUD_Scale(size), rgb, alpha, flag)
+
+#define drawsetcliparea(xposition, yposition, w, h) \
+       drawsetcliparea_builtin(HUD_ShiftX(xposition), HUD_ShiftY(yposition), HUD_ScaleX(w), HUD_ScaleY(h))
+
+// Since drawsubpic usually gets called multiple times from within an
+// utility function, instead of scaling pos and size in every call
+// we scale them once for all in the beginning of that utility function.
+// That's why drawsubpic isn't remapped.
+/*
+#define drawsubpic(position, size, pic, srcPosition, srcSize, rgb, alpha, flag) \
+       drawsubpic_builtin(HUD_Shift(position), HUD_Scale(size), pic, HUD_Shift(srcPosition), HUD_Scale(srcSize), rgb, alpha, flag)
+*/
+
 // drawpic wrapper to draw an image as large as possible with preserved aspect ratio into a box
 float _drawpic_imgaspect;
 vector _drawpic_imgsize;
@@ -109,7 +157,10 @@ void drawpic_aspect_skin_expanding_two(vector position, string pic, vector theSc
 
 #define SET_POS_AND_SZ_Y_ASPECT(allow_colors) MACRO_BEGIN {                                                                                                                    \
        float textaspect, oldsz;                                                                                                                                                                                \
+       vector dfs = drawfontscale; \
+       drawfontscale = '1 1 0'; \
        textaspect = stringwidth(text, allow_colors, '1 1 1' * sz.y) / sz.y;                                                                                    \
+       drawfontscale = dfs; \
        if(sz.x/sz.y > textaspect) {                                                                                                                                                                    \
                oldsz = sz.x;                                                                                                                                                                                           \
                sz.x = sz.y * textaspect;                                                                                                                                                                       \
@@ -127,7 +178,6 @@ void drawstring_aspect(vector pos, string text, vector sz, vector color, float t
 // drawstring wrapper to draw a colorcodedstring as large as possible with preserved aspect ratio into a box
 void drawcolorcodedstring_aspect(vector pos, string text, vector sz, float theAlpha, float drawflag);
 
-vector drawfontscale;
 void drawstring_expanding(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp);
 
 // drawstring wrapper to draw a string as large as possible with preserved aspect ratio into a box
index cf43e7c1d585cf565f7dad46e614216e3f9c3137..2fb239ba10e21932239c8463d1d48c7dd6fd00c6 100644 (file)
@@ -1278,6 +1278,11 @@ void HUD_DrawScoreboard()
        if (!scoreboard_fade_alpha)
                return;
 
+       if (autocvar_scoreboard_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
+
        HUD_UpdatePlayerTeams();
 
        scoreboard_alpha_bg = autocvar_scoreboard_alpha_bg * scoreboard_fade_alpha * (1 - autocvar__menu_alpha);
index 01388fdd2ff7ad69609cc6f00ea671df7df98724..a8708f2460f809a579f96db0428fbc1522432c61 100644 (file)
@@ -128,7 +128,7 @@ void draw_teamradar_player(vector coord3d, vector pangles, vector rgb)
 void draw_teamradar_icon(vector coord, entity icon, entity pingdata, vector rgb, float a)
 {
        coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(coord));
-       drawpic(coord - '4 4 0', strcat("gfx/teamradar_icon_", ftos(icon.m_radaricon)), '8 8 0', rgb, a, 0);
+       drawpic_builtin(coord - '4 4 0', strcat("gfx/teamradar_icon_", ftos(icon.m_radaricon)), '8 8 0', rgb, a, 0);
 
        if(pingdata)
        {
@@ -141,7 +141,7 @@ void draw_teamradar_icon(vector coord, entity icon, entity pingdata, vector rgb,
                        if(dt >= 1 || dt <= 0)
                                continue;
                        vector v = '2 2 0' * teamradar_size * dt;
-                       drawpic(coord - 0.5 * v, "gfx/teamradar_ping", v, '1 1 1', (1 - dt) * a, DRAWFLAG_ADDITIVE);
+                       drawpic_builtin(coord - 0.5 * v, "gfx/teamradar_ping", v, '1 1 1', (1 - dt) * a, DRAWFLAG_ADDITIVE);
                }
        }
 }
index 68711ef3b1ec29b0eebd0719b5ff5cd8702f8138..4ddfee12f96ff7f95a32b90c03fb7cd29167c584 100644 (file)
@@ -114,117 +114,152 @@ float autocvar_cl_leanmodel_lowpass = 0.05;
        highpass(value.z, frac, ref_store.z, ref_out.z); \
 } MACRO_END
 
-void viewmodel_animate(entity this)
+void calc_followmodel_ofs(entity view)
 {
-       static float prevtime;
-       float frametime = (time - prevtime);
-       prevtime = time;
+       if(cl_followmodel_time == time)
+               return; // cl_followmodel_ofs already calculated for this frame
 
-       if (autocvar_chase_active) return;
-       if (STAT(HEALTH) <= 0) return;
+       float frac;
+       vector gunorg = '0 0 0';
+       static vector vel_average;
+       static vector gunorg_prev = '0 0 0';
+       static vector gunorg_adjustment_highpass;
+       static vector gunorg_adjustment_lowpass;
+
+       vector vel;
+       if (autocvar_cl_followmodel_velocity_absolute)
+               vel = view.velocity;
+       else
+       {
+               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
+               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               vel.x = view.velocity * forward;
+               vel.y = view.velocity * right * -1;
+               vel.z = view.velocity * up;
+       }
 
-       entity view = CSQCModel_server2csqc(player_localentnum - 1);
+       vel.x = bound(vel_average.x - autocvar_cl_followmodel_limit, vel.x, vel_average.x + autocvar_cl_followmodel_limit);
+       vel.y = bound(vel_average.y - autocvar_cl_followmodel_limit, vel.y, vel_average.y + autocvar_cl_followmodel_limit);
+       vel.z = bound(vel_average.z - autocvar_cl_followmodel_limit, vel.z, vel_average.z + autocvar_cl_followmodel_limit);
 
-       bool clonground = !(view.anim_implicit_state & ANIMIMPLICITSTATE_INAIR);
-       static bool oldonground;
-       static float hitgroundtime;
-       if (clonground)
+       frac = avg_factor(autocvar_cl_followmodel_velocity_lowpass);
+       lowpass3(vel, frac, vel_average, gunorg);
+
+       gunorg *= -autocvar_cl_followmodel_speed * 0.042;
+
+       // perform highpass/lowpass on the adjustment vectors (turning velocity into acceleration!)
+       // trick: we must do the lowpass LAST, so the lowpass vector IS the final vector!
+       frac = avg_factor(autocvar_cl_followmodel_highpass);
+       highpass3(gunorg, frac, gunorg_adjustment_highpass, gunorg);
+       frac = avg_factor(autocvar_cl_followmodel_lowpass);
+       lowpass3(gunorg, frac, gunorg_adjustment_lowpass, gunorg);
+
+       if (autocvar_cl_followmodel_velocity_absolute)
        {
-               float f = time; // cl.movecmd[0].time
-               if (!oldonground)
-                       hitgroundtime = f;
+               vector fixed_gunorg;
+               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
+               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               fixed_gunorg.x = gunorg * forward;
+               fixed_gunorg.y = gunorg * right * -1;
+               fixed_gunorg.z = gunorg * up;
+               gunorg = fixed_gunorg;
        }
-       oldonground = clonground;
 
+       cl_followmodel_ofs = gunorg;
+       cl_followmodel_time = time;
+}
 
-       bool teleported = view.csqcmodel_teleported;
-
+vector leanmodel_ofs(entity view)
+{
        float frac;
-       if(autocvar_cl_followmodel)
-       {
-               vector gunorg = '0 0 0';
-               static vector vel_average;
-               static vector gunorg_prev = '0 0 0';
-               static vector gunorg_adjustment_highpass;
-               static vector gunorg_adjustment_lowpass;
+       vector gunangles = '0 0 0';
+       static vector gunangles_prev = '0 0 0';
+       static vector gunangles_highpass = '0 0 0';
+       static vector gunangles_adjustment_highpass;
+       static vector gunangles_adjustment_lowpass;
 
-               vector vel;
-               if(autocvar_cl_followmodel_velocity_absolute)
-                       vel = view.velocity;
-               else
-               {
-                       vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-                       MAKEVECTORS(makevectors, view_angles, forward, right, up);
-                       vel.x = view.velocity * forward;
-                       vel.y = view.velocity * right * -1;
-                       vel.z = view.velocity * up;
-               }
+       if (view.csqcmodel_teleported)
+               gunangles_prev = view_angles;
 
-               vel.x = bound(vel_average.x - autocvar_cl_followmodel_limit, vel.x, vel_average.x + autocvar_cl_followmodel_limit);
-               vel.y = bound(vel_average.y - autocvar_cl_followmodel_limit, vel.y, vel_average.y + autocvar_cl_followmodel_limit);
-               vel.z = bound(vel_average.z - autocvar_cl_followmodel_limit, vel.z, vel_average.z + autocvar_cl_followmodel_limit);
+       // in the highpass, we _store_ the DIFFERENCE to the actual view angles...
+       gunangles_highpass += gunangles_prev;
+       PITCH(gunangles_highpass) += 360 * floor((PITCH(view_angles) - PITCH(gunangles_highpass)) / 360 + 0.5);
+       YAW(gunangles_highpass) += 360 * floor((YAW(view_angles) - YAW(gunangles_highpass)) / 360 + 0.5);
+       ROLL(gunangles_highpass) += 360 * floor((ROLL(view_angles) - ROLL(gunangles_highpass)) / 360 + 0.5);
+       frac = avg_factor(autocvar_cl_leanmodel_highpass1);
+       highpass2_limited(view_angles, frac, autocvar_cl_leanmodel_limit, gunangles_highpass, gunangles);
+       gunangles_prev = view_angles;
+       gunangles_highpass -= gunangles_prev;
 
-               frac = avg_factor(autocvar_cl_followmodel_velocity_lowpass);
-               lowpass3(vel, frac, vel_average, gunorg);
+       PITCH(gunangles) *= -autocvar_cl_leanmodel_speed;
+       YAW(gunangles) *= -autocvar_cl_leanmodel_speed;
 
-               gunorg *= -autocvar_cl_followmodel_speed * 0.042;
+       // we assume here: PITCH = 0, YAW = 1, ROLL = 2
+       frac = avg_factor(autocvar_cl_leanmodel_highpass);
+       highpass2(gunangles, frac, gunangles_adjustment_highpass, gunangles);
+       frac = avg_factor(autocvar_cl_leanmodel_lowpass);
+       lowpass2(gunangles, frac, gunangles_adjustment_lowpass, gunangles);
 
-               // perform highpass/lowpass on the adjustment vectors (turning velocity into acceleration!)
-               // trick: we must do the lowpass LAST, so the lowpass vector IS the final vector!
-               frac = avg_factor(autocvar_cl_followmodel_highpass);
-               highpass3(gunorg, frac, gunorg_adjustment_highpass, gunorg);
-               frac = avg_factor(autocvar_cl_followmodel_lowpass);
-               lowpass3(gunorg, frac, gunorg_adjustment_lowpass, gunorg);
+       gunangles.x = -gunangles.x; // pitch was inverted, now that actually matters
 
-               if(autocvar_cl_followmodel_velocity_absolute)
-               {
-                       vector fixed_gunorg;
-                       vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-                       MAKEVECTORS(makevectors, view_angles, forward, right, up);
-                       fixed_gunorg.x = gunorg * forward;
-                       fixed_gunorg.y = gunorg * right * -1;
-                       fixed_gunorg.z = gunorg * up;
-                       gunorg = fixed_gunorg;
-               }
+       return gunangles;
+}
 
-               this.origin += gunorg;
+vector bobmodel_ofs(entity view)
+{
+       bool clonground = !(view.anim_implicit_state & ANIMIMPLICITSTATE_INAIR);
+       static bool oldonground;
+       static float hitgroundtime;
+       if (clonground)
+       {
+               float f = time; // cl.movecmd[0].time
+               if (!oldonground)
+                       hitgroundtime = f;
        }
+       oldonground = clonground;
 
-       if(autocvar_cl_leanmodel)
+       // calculate for swinging gun model
+       // the gun bobs when running on the ground, but doesn't bob when you're in the air.
+       vector gunorg = '0 0 0';
+       static float bobmodel_scale = 0;
+       static float time_ofs = 0; // makes the effect always restart in the same way
+       if (clonground)
        {
-               vector gunangles = '0 0 0';
-               static vector gunangles_prev = '0 0 0';
-               static vector gunangles_highpass = '0 0 0';
-               static vector gunangles_adjustment_highpass;
-               static vector gunangles_adjustment_lowpass;
+               if (time - hitgroundtime > 0.05)
+                       bobmodel_scale = min(1, bobmodel_scale + frametime * 5);
+       }
+       else
+               bobmodel_scale = max(0, bobmodel_scale - frametime * 5);
 
-               if (teleported)
-                       gunangles_prev = view_angles;
+       float xyspeed = bound(0, vlen(vec2(view.velocity)), 400);
+       if (bobmodel_scale && xyspeed)
+       {
+               float bspeed = xyspeed * 0.01 * autocvar_cl_viewmodel_scale * bobmodel_scale;
+               float s = (time - time_ofs) * autocvar_cl_bobmodel_speed;
+               gunorg.y = bspeed * autocvar_cl_bobmodel_side * sin(s);
+               gunorg.z = bspeed * autocvar_cl_bobmodel_up * cos(s * 2);
+       }
+       else
+               time_ofs = time;
 
-               // in the highpass, we _store_ the DIFFERENCE to the actual view angles...
-               gunangles_highpass += gunangles_prev;
-               PITCH(gunangles_highpass) += 360 * floor((PITCH(view_angles) - PITCH(gunangles_highpass)) / 360 + 0.5);
-               YAW(gunangles_highpass) += 360 * floor((YAW(view_angles) - YAW(gunangles_highpass)) / 360 + 0.5);
-               ROLL(gunangles_highpass) += 360 * floor((ROLL(view_angles) - ROLL(gunangles_highpass)) / 360 + 0.5);
-               frac = avg_factor(autocvar_cl_leanmodel_highpass1);
-               highpass2_limited(view_angles, frac, autocvar_cl_leanmodel_limit, gunangles_highpass, gunangles);
-               gunangles_prev = view_angles;
-               gunangles_highpass -= gunangles_prev;
+       return gunorg;
+}
 
-               PITCH(gunangles) *= -autocvar_cl_leanmodel_speed;
-               YAW(gunangles) *= -autocvar_cl_leanmodel_speed;
+void viewmodel_animate(entity this)
+{
+       if (autocvar_chase_active) return;
+       if (STAT(HEALTH) <= 0) return;
 
-               // we assume here: PITCH = 0, YAW = 1, ROLL = 2
-               frac = avg_factor(autocvar_cl_leanmodel_highpass);
-               highpass2(gunangles, frac, gunangles_adjustment_highpass, gunangles);
-               frac = avg_factor(autocvar_cl_leanmodel_lowpass);
-               lowpass2(gunangles, frac, gunangles_adjustment_lowpass, gunangles);
+       entity view = CSQCModel_server2csqc(player_localentnum - 1);
 
-               gunangles.x = -gunangles.x; // pitch was inverted, now that actually matters
-               this.angles += gunangles;
+       if (autocvar_cl_followmodel)
+       {
+               calc_followmodel_ofs(view);
+               this.origin += cl_followmodel_ofs;
        }
 
-       float xyspeed = bound(0, vlen(vec2(view.velocity)), 400);
+       if (autocvar_cl_leanmodel)
+               this.angles += leanmodel_ofs(view);
 
        // vertical view bobbing code
        // TODO: cl_bob
@@ -238,31 +273,7 @@ void viewmodel_animate(entity this)
 
        // gun model bobbing code
        if (autocvar_cl_bobmodel)
-       {
-               // calculate for swinging gun model
-               // the gun bobs when running on the ground, but doesn't bob when you're in the air.
-               static float bobmodel_scale = 0;
-               static float time_ofs = 0; // makes the effect always restart in the same way
-               if (clonground)
-               {
-                       if (time - hitgroundtime > 0.05)
-                               bobmodel_scale = min(1, bobmodel_scale + frametime * 5);
-               }
-               else
-                       bobmodel_scale = max(0, bobmodel_scale - frametime * 5);
-               if(bobmodel_scale && xyspeed)
-               {
-                       float bspeed = xyspeed * 0.01 * autocvar_cl_viewmodel_scale * bobmodel_scale;
-                       float s = (time - time_ofs) * autocvar_cl_bobmodel_speed;
-                       vector gunorg = '0 0 0';
-                       gunorg.y = bspeed * autocvar_cl_bobmodel_side * sin(s);
-                       gunorg.z = bspeed * autocvar_cl_bobmodel_up * cos(s * 2);
-
-                       this.origin += gunorg;
-               }
-               else
-                       time_ofs = time;
-       }
+               this.origin += bobmodel_ofs(view);
 }
 
 .vector viewmodel_origin, viewmodel_angles;
@@ -272,7 +283,7 @@ void viewmodel_animate(entity this)
 
 void viewmodel_draw(entity this)
 {
-       if(!activeweapon)
+       if(!activeweapon || !autocvar_r_drawviewmodel)
                return;
        int mask = (intermission || (STAT(HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL;
        float a = this.alpha;
@@ -1338,6 +1349,7 @@ void HUD_Draw()
 
                        HUD_Main();
                        HUD_DrawScoreboard();
+                       HUD_Scale_Disable();
                }
 
        // crosshair goes VERY LAST
@@ -1380,6 +1392,8 @@ void CSQC_UpdateView(float w, float h)
 
        lasthud = hud;
 
+       HUD_Scale_Disable();
+
        if(autocvar__hud_showbinds_reload) // menu can set this one
        {
                db_close(binddb);
index 40b2b3547ef16116994ef2ce879f0a497fa6125d..9aca8e774c34a669cf3439f6656914c703b7a0a3 100644 (file)
@@ -142,7 +142,7 @@ bool autocvar_debugdraw;
                                if (pos.z < 0) continue;
                                pos.z = 0;
                                pos.y += ofs * sz;
-                               drawcolorcodedstring2(pos,
+                               drawcolorcodedstring2_builtin(pos,
                                        sprintf("%d: '%s'@%s", (it.debug ? it.sv_entnum : etof(it)),
                                        it.classname, it.sourceLoc),
                                        sz * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL);
index 56cae3c228867df92a9ee7d39fd9c5957cf68826..1c85489c0aeded4379d64e97f3ba293f999d117e 100644 (file)
@@ -74,6 +74,7 @@ void HUD_MinigameStatus ()
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
+       HUD_Scale_Disable();
        hud_minigame.minigame_hud_status(pos,mySize);
 }
 
@@ -476,6 +477,7 @@ void HUD_MinigameMenu ()
 
        HUD_Panel_UpdateCvars();
 
+       HUD_Scale_Disable();
        HUD_Panel_DrawBg(1);
 
        if(panel_bg_padding)
index 3c01fa88a92b64c5c6366386eeb213b390a50d06..0d9cb73e9caf05bb131c07b186ced0a790083a82 100644 (file)
@@ -58,7 +58,7 @@ CLASS(DamageText, Object)
             s = strreplace("{health}", sprintf("%d", this.m_damage), s);
             s = strreplace("{armor}",  sprintf("%d", this.m_armordamage), s);
             s = strreplace("{total}",  sprintf("%d", this.m_damage + this.m_armordamage), s);
-            drawcolorcodedstring2(pos, s, this.m_size * '1 1 0', rgb, this.alpha, DRAWFLAG_NORMAL);
+            drawcolorcodedstring2_builtin(pos, s, this.m_size * '1 1 0', rgb, this.alpha, DRAWFLAG_NORMAL);
         }
     }
     ATTRIB(DamageText, draw2d, void(DamageText), DamageText_draw2d)
index 6c7eb4d76f0f42d01a5dd25fd2c1a264e05c2ada..34e6e3275a69b75a904f94bae1fc7f47b3650ac3 100644 (file)
@@ -357,6 +357,7 @@ void HUD_ItemsTime()
         }
     }
 
+    HUD_Scale_Enable();
     HUD_Panel_DrawBg(1);
 
     float row = 0, column = 0;
index 21b7c5433b15224b67846b6c44ebe20bf997da34..3748b8df79cd47ddf5eb9150d705ff0186f0d3a9 100644 (file)
@@ -476,14 +476,14 @@ string(string name, ...) precache_pic = #317;
 string(string name) precache_cubemap = #317;
 vector(string picname) draw_getimagesize = #318;
 void(string name) freepic = #319;
-float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter = #320;
-float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #321;
-float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic = #322;
-float(vector position, vector size, vector rgb, float alpha, float flag) drawfill = #323;
-void(float x, float y, float width, float height) drawsetcliparea = #324;
+float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter_builtin = #320;
+float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring_builtin = #321;
+float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic_builtin = #322;
+float(vector position, vector size, vector rgb, float alpha, float flag) drawfill_builtin = #323;
+void(float x, float y, float width, float height) drawsetcliparea_builtin = #324;
 void(void) drawresetcliparea = #325;
-float(vector position, string text, vector scale, float alpha, float flag) drawcolorcodedstring = #326;
-vector(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawcolorcodedstring2 = #326;
+float(vector position, string text, vector scale, float alpha, float flag) drawcolorcodedstring_builtin = #326;
+vector(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawcolorcodedstring2_builtin = #326;
 
 float(float stnum) getstatf = #330;
 float(float stnum, ...) getstati = #331; // can optionally take first bit and count
@@ -846,7 +846,7 @@ float loadfont(string fontname, string fontmaps, string sizes, float slot, float
 // fix_* parms let you fix badly made fonts by applying some transformations to them
 // fix_scale : per-character center-oriented scale (doesn't change line height at all)
 // fix_voffset : vertical offset for each character, it's a multiplier to character height
-float stringwidth(string text, float allowColorCodes, vector size) = #327; // get a width of string with given font and char size
+float stringwidth_builtin(string text, float allowColorCodes, vector size) = #327; // get a width of string with given font and char size
 float stringwidth_menu(string text, float allowColorCodes, vector size) = #468; // in menu.dat it has different builtin #
 //description: engine support for custom fonts in console, hud, qc etc.
 // limits:
index c8d9ae8de9b4dedee783b3ac3d4f0e531cef9286..698c9262370974781c1f0585caaba18103d19ff7 100644 (file)
@@ -46,7 +46,7 @@
        {
                if (theBorderSize.x < 0 && theBorderSize.y < 0)  // draw whole image as it is
                {
-                       drawpic(theOrigin, pic, theSize, theColor, theAlpha, 0);
+                       drawpic_builtin(theOrigin, pic, theSize, theColor, theAlpha, 0);
                        return;
                }
                if (theBorderSize.x == 0 && theBorderSize.y == 0)  // no border
        void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
        {
                position.x -= 2 / 3 * strlen(text) * theScale.x;
-               drawstring(position, text, theScale, rgb, theAlpha, flag);
+               drawstring_builtin(position, text, theScale, rgb, theAlpha, flag);
        }
 
        void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
        {
                position.x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale.x);
-               drawstring(position, text, theScale, rgb, theAlpha, flag);
+               drawstring_builtin(position, text, theScale, rgb, theAlpha, flag);
        }
 
 #endif
index 384188091d0c4b0c92917bacafd3253707be3fe6..2ade29691280beb373c05170f00b9e8d47667190 100644 (file)
@@ -4,7 +4,18 @@
 #include "sort.qh"
 #include "oo.qh"
 
-#ifndef SVQC
+#ifdef CSQC
+       float stringwidth_colors(string s, vector theSize)
+       {
+               return stringwidth_builtin(s, true, theSize);
+       }
+
+       float stringwidth_nocolors(string s, vector theSize)
+       {
+               return stringwidth_builtin(s, false, theSize);
+       }
+#endif
+#ifdef MENUQC
        float stringwidth_colors(string s, vector theSize)
        {
                return stringwidth(s, true, theSize);
index becefc6607f2f8202cbe7963eefdaa3e80963630..6525e2779c5139f1e80b278eeff797dd85d09976 100644 (file)
@@ -158,6 +158,11 @@ void XonoticGameHUDSettingsTab_fill(entity me)
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Damage overlay:")));
                me.TD(me, 1, 2, e = makeXonoticSlider(0, 1, 0.05, "hud_damage"));
+       me.TR(me);
+               me.TD(me, 1, 3, e = makeXonoticCheckBox_T(0, "hud_dynamic_follow", _("Dynamic HUD"),
+                       _("HUD moves around following player's movement")));
+       me.TR(me);
+               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "hud_dynamic_shake", _("Shake the HUD when hurt")));
        me.TR(me);
        me.TR(me);
                me.TDempty(me, 0.5);