From: terencehill <piuntn@gmail.com>
Date: Thu, 21 May 2020 20:46:43 +0000 (+0200)
Subject: HUD: allow panels to define in their own files their own saved cvars
X-Git-Tag: xonotic-v0.8.5~1041^2~1
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=23a5f74a3f11338f69eca57558fdac9520c3ee34;p=xonotic%2Fxonotic-data.pk3dir.git

HUD: allow panels to define in their own files their own saved cvars
---

diff --git a/qcsrc/client/hud/hud.qh b/qcsrc/client/hud/hud.qh
index d05b04090..58f46b8af 100644
--- a/qcsrc/client/hud/hud.qh
+++ b/qcsrc/client/hud/hud.qh
@@ -14,16 +14,21 @@ REGISTRY(hud_panels, BITS(6))
 #define hud_panels_from(i) _hud_panels_from(i, NULL)
 REGISTER_REGISTRY(hud_panels)
 
-#define REGISTER_HUD_PANEL(id, draw_func, configflags, showflags) \
+#define _REGISTER_HUD_PANEL(id, draw_func, export_func, configflags, showflags) \
 	void draw_func(); \
+	void export_func(entity panel, int fh); \
 	REGISTER(hud_panels, HUD_PANEL, id, m_id, new_pure(hud_panel)) { \
 		this.panel_id = this.m_id; \
 		this.panel_draw = draw_func; \
+		this.panel_export = export_func; \
 		this.panel_name = strzone(strtolower(#id)); \
 		this.panel_configflags = configflags; \
 		this.panel_showflags = showflags; \
 	}
 
+#define REGISTER_HUD_PANEL(id, draw_func, configflags, showflags) \
+	_REGISTER_HUD_PANEL(id, draw_func, draw_func##_Export, configflags, showflags)
+
 #define HUD_PANEL(NAME) HUD_PANEL_##NAME
 
 // draw the background/borders
@@ -149,6 +154,7 @@ float panel_bg_padding;
 string panel_bg_padding_str;
 
 classfield(HUDPanel) .void() panel_draw;
+classfield(HUDPanel) .void(entity panel, int fh) panel_export;
 
 // chat panel can be reduced / moved while the mapvote is active
 // let know the mapvote panel about chat pos and size
diff --git a/qcsrc/client/hud/hud_config.qc b/qcsrc/client/hud/hud_config.qc
index e23647fb3..6858a84b2 100644
--- a/qcsrc/client/hud/hud_config.qc
+++ b/qcsrc/client/hud/hud_config.qc
@@ -7,9 +7,6 @@
 #include <client/miscfunctions.qh>
 #include <client/view.qh>
 
-#define HUD_Write(s) fputs(fh, s)
-#define HUD_Write_Cvar(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n"))
-#define HUD_Write_PanelCvar(cvar_suf) str = strcat("hud_panel_", panel.panel_name, cvar_suf), HUD_Write_Cvar(str)
 // Save the config
 void HUD_Panel_ExportCfg(string cfgname)
 {
@@ -75,167 +72,7 @@ void HUD_Panel_ExportCfg(string cfgname)
 			HUD_Write_PanelCvar("_bg_alpha");
 			HUD_Write_PanelCvar("_bg_border");
 			HUD_Write_PanelCvar("_bg_padding");
-			switch(panel) {
-				case HUD_PANEL_WEAPONS:
-					HUD_Write_Cvar("hud_panel_weapons_accuracy");
-					HUD_Write_Cvar("hud_panel_weapons_label");
-					HUD_Write_Cvar("hud_panel_weapons_label_scale");
-					HUD_Write_Cvar("hud_panel_weapons_complainbubble");
-					HUD_Write_Cvar("hud_panel_weapons_complainbubble_padding");
-					HUD_Write_Cvar("hud_panel_weapons_complainbubble_time");
-					HUD_Write_Cvar("hud_panel_weapons_complainbubble_fadetime");
-					HUD_Write_Cvar("hud_panel_weapons_complainbubble_color_outofammo");
-					HUD_Write_Cvar("hud_panel_weapons_complainbubble_color_donthave");
-					HUD_Write_Cvar("hud_panel_weapons_complainbubble_color_unavailable");
-					HUD_Write_Cvar("hud_panel_weapons_ammo");
-					HUD_Write_Cvar("hud_panel_weapons_ammo_color");
-					HUD_Write_Cvar("hud_panel_weapons_ammo_alpha");
-					HUD_Write_Cvar("hud_panel_weapons_aspect");
-					HUD_Write_Cvar("hud_panel_weapons_timeout");
-					HUD_Write_Cvar("hud_panel_weapons_timeout_effect");
-					HUD_Write_Cvar("hud_panel_weapons_timeout_fadebgmin");
-					HUD_Write_Cvar("hud_panel_weapons_timeout_fadefgmin");
-					HUD_Write_Cvar("hud_panel_weapons_timeout_speed_in");
-					HUD_Write_Cvar("hud_panel_weapons_timeout_speed_out");
-					HUD_Write_Cvar("hud_panel_weapons_onlyowned");
-					HUD_Write_Cvar("hud_panel_weapons_noncurrent_alpha");
-					HUD_Write_Cvar("hud_panel_weapons_noncurrent_scale");
-					HUD_Write_Cvar("hud_panel_weapons_selection_radius");
-					HUD_Write_Cvar("hud_panel_weapons_selection_speed");
-					break;
-				case HUD_PANEL_AMMO:
-					HUD_Write_Cvar("hud_panel_ammo_onlycurrent");
-					HUD_Write_Cvar("hud_panel_ammo_noncurrent_alpha");
-					HUD_Write_Cvar("hud_panel_ammo_noncurrent_scale");
-					HUD_Write_Cvar("hud_panel_ammo_iconalign");
-					HUD_Write_Cvar("hud_panel_ammo_progressbar");
-					HUD_Write_Cvar("hud_panel_ammo_progressbar_name");
-					HUD_Write_Cvar("hud_panel_ammo_progressbar_xoffset");
-					HUD_Write_Cvar("hud_panel_ammo_text");
-					break;
-				case HUD_PANEL_POWERUPS:
-					HUD_Write_Cvar("hud_panel_powerups_iconalign");
-					HUD_Write_Cvar("hud_panel_powerups_baralign");
-					HUD_Write_Cvar("hud_panel_powerups_progressbar");
-					HUD_Write_Cvar("hud_panel_powerups_text");
-					break;
-				case HUD_PANEL_HEALTHARMOR:
-					HUD_Write_Cvar("hud_panel_healtharmor_combined");
-					HUD_Write_Cvar("hud_panel_healtharmor_flip");
-					HUD_Write_Cvar("hud_panel_healtharmor_iconalign");
-					HUD_Write_Cvar("hud_panel_healtharmor_baralign");
-					HUD_Write_Cvar("hud_panel_healtharmor_progressbar");
-					HUD_Write_Cvar("hud_panel_healtharmor_progressbar_health");
-					HUD_Write_Cvar("hud_panel_healtharmor_progressbar_armor");
-					HUD_Write_Cvar("hud_panel_healtharmor_progressbar_gfx");
-					HUD_Write_Cvar("hud_panel_healtharmor_progressbar_gfx_smooth");
-					HUD_Write_Cvar("hud_panel_healtharmor_text");
-					break;
-				case HUD_PANEL_NOTIFY:
-					HUD_Write_Cvar("hud_panel_notify_flip");
-					HUD_Write_Cvar("hud_panel_notify_fontsize");
-					HUD_Write_Cvar("hud_panel_notify_time");
-					HUD_Write_Cvar("hud_panel_notify_fadetime");
-					HUD_Write_Cvar("hud_panel_notify_icon_aspect");
-					break;
-				case HUD_PANEL_TIMER:
-					break;
-				case HUD_PANEL_RADAR:
-					HUD_Write_Cvar("hud_panel_radar_foreground_alpha");
-					HUD_Write_Cvar("hud_panel_radar_rotation");
-					HUD_Write_Cvar("hud_panel_radar_zoommode");
-					HUD_Write_Cvar("hud_panel_radar_scale");
-					HUD_Write_Cvar("hud_panel_radar_maximized_scale");
-					HUD_Write_Cvar("hud_panel_radar_maximized_size");
-					HUD_Write_Cvar("hud_panel_radar_maximized_rotation");
-					HUD_Write_Cvar("hud_panel_radar_maximized_zoommode");
-					break;
-				case HUD_PANEL_SCORE:
-					HUD_Write_Cvar("hud_panel_score_rankings");
-					break;
-				case HUD_PANEL_VOTE:
-					HUD_Write_Cvar("hud_panel_vote_alreadyvoted_alpha");
-					break;
-				case HUD_PANEL_MODICONS:
-					HUD_Write_Cvar("hud_panel_modicons_ca_layout");
-					HUD_Write_Cvar("hud_panel_modicons_dom_layout");
-					HUD_Write_Cvar("hud_panel_modicons_freezetag_layout");
-					break;
-				case HUD_PANEL_PRESSEDKEYS:
-					HUD_Write_Cvar("hud_panel_pressedkeys_aspect");
-					HUD_Write_Cvar("hud_panel_pressedkeys_attack");
-					break;
-				case HUD_PANEL_ENGINEINFO:
-					HUD_Write_Cvar("hud_panel_engineinfo_framecounter_time");
-					HUD_Write_Cvar("hud_panel_engineinfo_framecounter_decimals");
-					break;
-				case HUD_PANEL_INFOMESSAGES:
-					HUD_Write_Cvar("hud_panel_infomessages_flip");
-					break;
-				case HUD_PANEL_PHYSICS:
-					HUD_Write_Cvar("hud_panel_physics_speed_unit_show");
-					HUD_Write_Cvar("hud_panel_physics_speed_max");
-					HUD_Write_Cvar("hud_panel_physics_speed_vertical");
-					HUD_Write_Cvar("hud_panel_physics_topspeed");
-					HUD_Write_Cvar("hud_panel_physics_topspeed_time");
-					HUD_Write_Cvar("hud_panel_physics_acceleration_max");
-					HUD_Write_Cvar("hud_panel_physics_acceleration_vertical");
-					HUD_Write_Cvar("hud_panel_physics_flip");
-					HUD_Write_Cvar("hud_panel_physics_baralign");
-					HUD_Write_Cvar("hud_panel_physics_progressbar");
-					HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_mode");
-					HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_scale");
-					HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_nonlinear");
-					HUD_Write_Cvar("hud_panel_physics_text");
-					HUD_Write_Cvar("hud_panel_physics_text_scale");
-					break;
-				case HUD_PANEL_CENTERPRINT:
-					HUD_Write_Cvar("hud_panel_centerprint_align");
-					HUD_Write_Cvar("hud_panel_centerprint_flip");
-					HUD_Write_Cvar("hud_panel_centerprint_fontscale");
-					HUD_Write_Cvar("hud_panel_centerprint_fontscale_bold");
-					HUD_Write_Cvar("hud_panel_centerprint_time");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_in");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_out");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passone");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passone_minalpha");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passtwo");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passtwo_minalpha");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_minfontsize");
-					HUD_Write_Cvar("hud_panel_centerprint_fade_minfontsize");
-					break;
-				case HUD_PANEL_ITEMSTIME:
-					HUD_Write_Cvar("hud_panel_itemstime_iconalign");
-					HUD_Write_Cvar("hud_panel_itemstime_progressbar");
-					HUD_Write_Cvar("hud_panel_itemstime_progressbar_name");
-					HUD_Write_Cvar("hud_panel_itemstime_progressbar_reduced");
-					HUD_Write_Cvar("hud_panel_itemstime_text");
-					HUD_Write_Cvar("hud_panel_itemstime_ratio");
-					HUD_Write_Cvar("hud_panel_itemstime_dynamicsize");
-					break;
-				case HUD_PANEL_MAPVOTE:
-					HUD_Write_Cvar("hud_panel_mapvote_highlight_border");
-					break;
-				case HUD_PANEL_QUICKMENU:
-					HUD_Write_Cvar("hud_panel_quickmenu_align");
-					break;
-				case HUD_PANEL_SCOREBOARD:
-					HUD_Write_Cvar("hud_panel_scoreboard_fadeinspeed");
-					HUD_Write_Cvar("hud_panel_scoreboard_fadeoutspeed");
-					HUD_Write_Cvar("hud_panel_scoreboard_respawntime_decimals");
-					HUD_Write_Cvar("hud_panel_scoreboard_table_bg_alpha");
-					HUD_Write_Cvar("hud_panel_scoreboard_table_bg_scale");
-					HUD_Write_Cvar("hud_panel_scoreboard_table_fg_alpha");
-					HUD_Write_Cvar("hud_panel_scoreboard_table_fg_alpha_self");
-					HUD_Write_Cvar("hud_panel_scoreboard_table_highlight");
-					HUD_Write_Cvar("hud_panel_scoreboard_table_highlight_alpha");
-					HUD_Write_Cvar("hud_panel_scoreboard_table_highlight_alpha_self");
-					HUD_Write_Cvar("hud_panel_scoreboard_bg_teams_color_team");
-					HUD_Write_Cvar("hud_panel_scoreboard_accuracy_doublerows");
-					HUD_Write_Cvar("hud_panel_scoreboard_accuracy_nocolors");
-					break;
-			}
+			panel.panel_export(panel, fh);
 			HUD_Write("\n");
 		}
 		MUTATOR_CALLHOOK(HUD_WriteCvars, fh);
diff --git a/qcsrc/client/hud/hud_config.qh b/qcsrc/client/hud/hud_config.qh
index d91fe370e..f3f3d8b00 100644
--- a/qcsrc/client/hud/hud_config.qh
+++ b/qcsrc/client/hud/hud_config.qh
@@ -27,3 +27,7 @@ float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary);
 void HUD_Panel_EnableMenu();
 
 void HUD_Panel_FirstInDrawQ(float id);
+
+#define HUD_Write(s) fputs(fh, s)
+#define HUD_Write_Cvar(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n"))
+#define HUD_Write_PanelCvar(cvar_suf) str = strcat("hud_panel_", panel.panel_name, cvar_suf), HUD_Write_Cvar(str)
diff --git a/qcsrc/client/hud/panel/ammo.qc b/qcsrc/client/hud/panel/ammo.qc
index 95ceced82..fbe1aa5ce 100644
--- a/qcsrc/client/hud/panel/ammo.qc
+++ b/qcsrc/client/hud/panel/ammo.qc
@@ -10,6 +10,19 @@
 
 // Ammo (#1)
 
+void HUD_Ammo_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_ammo_onlycurrent");
+	HUD_Write_Cvar("hud_panel_ammo_noncurrent_alpha");
+	HUD_Write_Cvar("hud_panel_ammo_noncurrent_scale");
+	HUD_Write_Cvar("hud_panel_ammo_iconalign");
+	HUD_Write_Cvar("hud_panel_ammo_progressbar");
+	HUD_Write_Cvar("hud_panel_ammo_progressbar_name");
+	HUD_Write_Cvar("hud_panel_ammo_progressbar_xoffset");
+	HUD_Write_Cvar("hud_panel_ammo_text");
+}
+
 void DrawNadeProgressBar(vector myPos, vector mySize, float progress, vector color)
 {
 	HUD_Panel_DrawProgressBar(
diff --git a/qcsrc/client/hud/panel/centerprint.qc b/qcsrc/client/hud/panel/centerprint.qc
index 446a64ec6..1b2f3fe04 100644
--- a/qcsrc/client/hud/panel/centerprint.qc
+++ b/qcsrc/client/hud/panel/centerprint.qc
@@ -6,6 +6,26 @@
 #include <client/miscfunctions.qh>
 
 // CenterPrint (#16)
+
+void HUD_CenterPrint_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_centerprint_align");
+	HUD_Write_Cvar("hud_panel_centerprint_flip");
+	HUD_Write_Cvar("hud_panel_centerprint_fontscale");
+	HUD_Write_Cvar("hud_panel_centerprint_fontscale_bold");
+	HUD_Write_Cvar("hud_panel_centerprint_time");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_in");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_out");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passone");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passone_minalpha");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passtwo");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_passtwo_minalpha");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_subsequent_minfontsize");
+	HUD_Write_Cvar("hud_panel_centerprint_fade_minfontsize");
+}
+
 // These are the functions that draw the text at the center of the screen (e.g. frag messages and server MOTDs).
 // Usually local_notification_centerprint_generic() is called, which in turn calls centerprint_generic(), which
 // uses some kind of macro magic to call HUD_CenterPrint, which draws them on screen using drawcolorcodedstring().
diff --git a/qcsrc/client/hud/panel/chat.qc b/qcsrc/client/hud/panel/chat.qc
index 5f309d0b0..7b405d5bb 100644
--- a/qcsrc/client/hud/panel/chat.qc
+++ b/qcsrc/client/hud/panel/chat.qc
@@ -6,6 +6,11 @@
 
 // Chat (#12)
 
+void HUD_Chat_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+}
+
 void HUD_Chat()
 {
 	if(!autocvar__hud_configure)
diff --git a/qcsrc/client/hud/panel/engineinfo.qc b/qcsrc/client/hud/panel/engineinfo.qc
index ed7966c16..db376a2ce 100644
--- a/qcsrc/client/hud/panel/engineinfo.qc
+++ b/qcsrc/client/hud/panel/engineinfo.qc
@@ -5,6 +5,13 @@
 
 // Engine info (#13)
 
+void HUD_EngineInfo_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_engineinfo_framecounter_time");
+	HUD_Write_Cvar("hud_panel_engineinfo_framecounter_decimals");
+}
+
 float prevfps;
 float prevfps_time;
 int framecounter;
diff --git a/qcsrc/client/hud/panel/healtharmor.qc b/qcsrc/client/hud/panel/healtharmor.qc
index 1a61a96d3..d63b3d97b 100644
--- a/qcsrc/client/hud/panel/healtharmor.qc
+++ b/qcsrc/client/hud/panel/healtharmor.qc
@@ -7,6 +7,21 @@
 
 // Health/armor (#3)
 
+void HUD_HealthArmor_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_healtharmor_combined");
+	HUD_Write_Cvar("hud_panel_healtharmor_flip");
+	HUD_Write_Cvar("hud_panel_healtharmor_iconalign");
+	HUD_Write_Cvar("hud_panel_healtharmor_baralign");
+	HUD_Write_Cvar("hud_panel_healtharmor_progressbar");
+	HUD_Write_Cvar("hud_panel_healtharmor_progressbar_health");
+	HUD_Write_Cvar("hud_panel_healtharmor_progressbar_armor");
+	HUD_Write_Cvar("hud_panel_healtharmor_progressbar_gfx");
+	HUD_Write_Cvar("hud_panel_healtharmor_progressbar_gfx_smooth");
+	HUD_Write_Cvar("hud_panel_healtharmor_text");
+}
+
 void HUD_HealthArmor()
 {
 	int armor, health, fuel, air_time;
diff --git a/qcsrc/client/hud/panel/infomessages.qc b/qcsrc/client/hud/panel/infomessages.qc
index 131d62efe..803491f84 100644
--- a/qcsrc/client/hud/panel/infomessages.qc
+++ b/qcsrc/client/hud/panel/infomessages.qc
@@ -8,6 +8,12 @@
 
 // Info messages (#14)
 
+void HUD_InfoMessages_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_infomessages_flip");
+}
+
 float autocvar_hud_panel_infomessages_group0 = 1;
 float autocvar_hud_panel_infomessages_group_fadetime = 0.4;
 float autocvar_hud_panel_infomessages_group_time = 6;
diff --git a/qcsrc/client/hud/panel/modicons.qc b/qcsrc/client/hud/panel/modicons.qc
index 18ec37d47..b206609b3 100644
--- a/qcsrc/client/hud/panel/modicons.qc
+++ b/qcsrc/client/hud/panel/modicons.qc
@@ -9,6 +9,14 @@
 
 // Mod icons (#10)
 
+void HUD_ModIcons_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_modicons_ca_layout");
+	HUD_Write_Cvar("hud_panel_modicons_dom_layout");
+	HUD_Write_Cvar("hud_panel_modicons_freezetag_layout");
+}
+
 void DrawCAItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
 {
 	TC(int, layout); TC(int, i);
diff --git a/qcsrc/client/hud/panel/notify.qc b/qcsrc/client/hud/panel/notify.qc
index 82690bee7..b562fdb61 100644
--- a/qcsrc/client/hud/panel/notify.qc
+++ b/qcsrc/client/hud/panel/notify.qc
@@ -5,6 +5,16 @@
 
 // Notifications (#4)
 
+void HUD_Notify_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_notify_flip");
+	HUD_Write_Cvar("hud_panel_notify_fontsize");
+	HUD_Write_Cvar("hud_panel_notify_time");
+	HUD_Write_Cvar("hud_panel_notify_fadetime");
+	HUD_Write_Cvar("hud_panel_notify_icon_aspect");
+}
+
 void HUD_Notify_Push(string icon, string attacker, string victim)
 {
 	if (icon == "")
diff --git a/qcsrc/client/hud/panel/physics.qc b/qcsrc/client/hud/panel/physics.qc
index aa77690a6..e2be0de00 100644
--- a/qcsrc/client/hud/panel/physics.qc
+++ b/qcsrc/client/hud/panel/physics.qc
@@ -9,6 +9,26 @@
 
 // Physics (#15)
 
+void HUD_Physics_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_physics_speed_unit_show");
+	HUD_Write_Cvar("hud_panel_physics_speed_max");
+	HUD_Write_Cvar("hud_panel_physics_speed_vertical");
+	HUD_Write_Cvar("hud_panel_physics_topspeed");
+	HUD_Write_Cvar("hud_panel_physics_topspeed_time");
+	HUD_Write_Cvar("hud_panel_physics_acceleration_max");
+	HUD_Write_Cvar("hud_panel_physics_acceleration_vertical");
+	HUD_Write_Cvar("hud_panel_physics_flip");
+	HUD_Write_Cvar("hud_panel_physics_baralign");
+	HUD_Write_Cvar("hud_panel_physics_progressbar");
+	HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_mode");
+	HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_scale");
+	HUD_Write_Cvar("hud_panel_physics_acceleration_progressbar_nonlinear");
+	HUD_Write_Cvar("hud_panel_physics_text");
+	HUD_Write_Cvar("hud_panel_physics_text_scale");
+}
+
 vector acc_prevspeed;
 float acc_prevtime, acc_avg, top_speed, top_speed_time;
 float physics_update_time, discrete_speed, discrete_acceleration;
diff --git a/qcsrc/client/hud/panel/powerups.qc b/qcsrc/client/hud/panel/powerups.qc
index 49b7a9701..d68a60f31 100644
--- a/qcsrc/client/hud/panel/powerups.qc
+++ b/qcsrc/client/hud/panel/powerups.qc
@@ -7,6 +7,15 @@
 
 // Powerups (#2)
 
+void HUD_Powerups_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_powerups_iconalign");
+	HUD_Write_Cvar("hud_panel_powerups_baralign");
+	HUD_Write_Cvar("hud_panel_powerups_progressbar");
+	HUD_Write_Cvar("hud_panel_powerups_text");
+}
+
 // Powerup item fields (reusing existing fields)
 .string message;  // Human readable name
 .string netname;  // Icon name
diff --git a/qcsrc/client/hud/panel/pressedkeys.qc b/qcsrc/client/hud/panel/pressedkeys.qc
index 3c87a1c1d..ed9ab7ded 100644
--- a/qcsrc/client/hud/panel/pressedkeys.qc
+++ b/qcsrc/client/hud/panel/pressedkeys.qc
@@ -6,6 +6,13 @@
 
 // Pressed keys (#11)
 
+void HUD_PressedKeys_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_pressedkeys_aspect");
+	HUD_Write_Cvar("hud_panel_pressedkeys_attack");
+}
+
 void HUD_PressedKeys()
 {
 	if(!autocvar__hud_configure)
diff --git a/qcsrc/client/hud/panel/quickmenu.qc b/qcsrc/client/hud/panel/quickmenu.qc
index a0bd8727a..de7489ca8 100644
--- a/qcsrc/client/hud/panel/quickmenu.qc
+++ b/qcsrc/client/hud/panel/quickmenu.qc
@@ -10,6 +10,12 @@
 
 // QuickMenu (#23)
 
+void HUD_QuickMenu_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_quickmenu_align");
+}
+
 // QUICKMENU_MAXLINES must be <= 10
 const int QUICKMENU_MAXLINES = 10;
 // visible entries are loaded from QuickMenu_Buffer into QuickMenu_Page_* arrays
diff --git a/qcsrc/client/hud/panel/racetimer.qc b/qcsrc/client/hud/panel/racetimer.qc
index ecf8f9f33..326d77653 100644
--- a/qcsrc/client/hud/panel/racetimer.qc
+++ b/qcsrc/client/hud/panel/racetimer.qc
@@ -7,6 +7,11 @@
 
 // Race timer (#8)
 
+void HUD_RaceTimer_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+}
+
 // return the string of the onscreen race timer
 string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname)
 {
diff --git a/qcsrc/client/hud/panel/radar.qc b/qcsrc/client/hud/panel/radar.qc
index 612dc12e9..073715695 100644
--- a/qcsrc/client/hud/panel/radar.qc
+++ b/qcsrc/client/hud/panel/radar.qc
@@ -12,6 +12,19 @@
 
 // Radar (#6)
 
+void HUD_Radar_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_radar_foreground_alpha");
+	HUD_Write_Cvar("hud_panel_radar_rotation");
+	HUD_Write_Cvar("hud_panel_radar_zoommode");
+	HUD_Write_Cvar("hud_panel_radar_scale");
+	HUD_Write_Cvar("hud_panel_radar_maximized_scale");
+	HUD_Write_Cvar("hud_panel_radar_maximized_size");
+	HUD_Write_Cvar("hud_panel_radar_maximized_rotation");
+	HUD_Write_Cvar("hud_panel_radar_maximized_zoommode");
+}
+
 bool HUD_Radar_Clickable()
 {
 	return hud_panel_radar_mouse && !hud_panel_radar_temp_hidden;
diff --git a/qcsrc/client/hud/panel/score.qc b/qcsrc/client/hud/panel/score.qc
index 525bf614b..a4820d74c 100644
--- a/qcsrc/client/hud/panel/score.qc
+++ b/qcsrc/client/hud/panel/score.qc
@@ -10,6 +10,12 @@
 
 // Score (#7)
 
+void HUD_Score_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_score_rankings");
+}
+
 void HUD_Score_Rankings(vector pos, vector mySize, entity me)
 {
 	float score;
diff --git a/qcsrc/client/hud/panel/scoreboard.qc b/qcsrc/client/hud/panel/scoreboard.qc
index 08a1a73bb..5ab3688f3 100644
--- a/qcsrc/client/hud/panel/scoreboard.qc
+++ b/qcsrc/client/hud/panel/scoreboard.qc
@@ -16,6 +16,24 @@
 
 // Scoreboard (#24)
 
+void Scoreboard_Draw_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_scoreboard_fadeinspeed");
+	HUD_Write_Cvar("hud_panel_scoreboard_fadeoutspeed");
+	HUD_Write_Cvar("hud_panel_scoreboard_respawntime_decimals");
+	HUD_Write_Cvar("hud_panel_scoreboard_table_bg_alpha");
+	HUD_Write_Cvar("hud_panel_scoreboard_table_bg_scale");
+	HUD_Write_Cvar("hud_panel_scoreboard_table_fg_alpha");
+	HUD_Write_Cvar("hud_panel_scoreboard_table_fg_alpha_self");
+	HUD_Write_Cvar("hud_panel_scoreboard_table_highlight");
+	HUD_Write_Cvar("hud_panel_scoreboard_table_highlight_alpha");
+	HUD_Write_Cvar("hud_panel_scoreboard_table_highlight_alpha_self");
+	HUD_Write_Cvar("hud_panel_scoreboard_bg_teams_color_team");
+	HUD_Write_Cvar("hud_panel_scoreboard_accuracy_doublerows");
+	HUD_Write_Cvar("hud_panel_scoreboard_accuracy_nocolors");
+}
+
 const int MAX_SBT_FIELDS = MAX_SCORE;
 
 PlayerScoreField sbt_field[MAX_SBT_FIELDS + 1];
diff --git a/qcsrc/client/hud/panel/timer.qc b/qcsrc/client/hud/panel/timer.qc
index e01aa7517..3cb587c0b 100644
--- a/qcsrc/client/hud/panel/timer.qc
+++ b/qcsrc/client/hud/panel/timer.qc
@@ -6,6 +6,11 @@
 
 // Timer (#5)
 
+void HUD_Timer_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+}
+
 void HUD_Timer()
 {
 	if(!autocvar__hud_configure)
diff --git a/qcsrc/client/hud/panel/vote.qc b/qcsrc/client/hud/panel/vote.qc
index 0337eccfc..0dd509163 100644
--- a/qcsrc/client/hud/panel/vote.qc
+++ b/qcsrc/client/hud/panel/vote.qc
@@ -7,6 +7,12 @@
 
 // Vote (#9)
 
+void HUD_Vote_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_vote_alreadyvoted_alpha");
+}
+
 void HUD_Vote()
 {
 	if(autocvar_cl_allow_uid2name == -1 && (ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || (serverflags & SERVERFLAG_PLAYERSTATS)))
diff --git a/qcsrc/client/hud/panel/weapons.qc b/qcsrc/client/hud/panel/weapons.qc
index 8668886a9..4f452e04b 100644
--- a/qcsrc/client/hud/panel/weapons.qc
+++ b/qcsrc/client/hud/panel/weapons.qc
@@ -8,6 +8,35 @@
 
 // Weapons (#0)
 
+void HUD_Weapons_Export(entity panel, int fh)
+{
+	HUD_Write_Cvar("hud_panel_weapons_accuracy");
+	HUD_Write_Cvar("hud_panel_weapons_label");
+	HUD_Write_Cvar("hud_panel_weapons_label_scale");
+	HUD_Write_Cvar("hud_panel_weapons_complainbubble");
+	HUD_Write_Cvar("hud_panel_weapons_complainbubble_padding");
+	HUD_Write_Cvar("hud_panel_weapons_complainbubble_time");
+	HUD_Write_Cvar("hud_panel_weapons_complainbubble_fadetime");
+	HUD_Write_Cvar("hud_panel_weapons_complainbubble_color_outofammo");
+	HUD_Write_Cvar("hud_panel_weapons_complainbubble_color_donthave");
+	HUD_Write_Cvar("hud_panel_weapons_complainbubble_color_unavailable");
+	HUD_Write_Cvar("hud_panel_weapons_ammo");
+	HUD_Write_Cvar("hud_panel_weapons_ammo_color");
+	HUD_Write_Cvar("hud_panel_weapons_ammo_alpha");
+	HUD_Write_Cvar("hud_panel_weapons_aspect");
+	HUD_Write_Cvar("hud_panel_weapons_timeout");
+	HUD_Write_Cvar("hud_panel_weapons_timeout_effect");
+	HUD_Write_Cvar("hud_panel_weapons_timeout_fadebgmin");
+	HUD_Write_Cvar("hud_panel_weapons_timeout_fadefgmin");
+	HUD_Write_Cvar("hud_panel_weapons_timeout_speed_in");
+	HUD_Write_Cvar("hud_panel_weapons_timeout_speed_out");
+	HUD_Write_Cvar("hud_panel_weapons_onlyowned");
+	HUD_Write_Cvar("hud_panel_weapons_noncurrent_alpha");
+	HUD_Write_Cvar("hud_panel_weapons_noncurrent_scale");
+	HUD_Write_Cvar("hud_panel_weapons_selection_radius");
+	HUD_Write_Cvar("hud_panel_weapons_selection_speed");
+}
+
 entity weaponorder[Weapons_MAX];
 void weaponorder_swap(int i, int j, entity pass)
 {
diff --git a/qcsrc/client/mapvoting.qc b/qcsrc/client/mapvoting.qc
index d0bab24b5..c206e773f 100644
--- a/qcsrc/client/mapvoting.qc
+++ b/qcsrc/client/mapvoting.qc
@@ -8,6 +8,13 @@
 
 #include <common/mapinfo.qh>
 
+// MapVote (#21)
+
+void MapVote_Draw_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_mapvote_highlight_border");
+}
 
 int mv_num_maps;
 
diff --git a/qcsrc/common/minigames/cl_minigames_hud.qc b/qcsrc/common/minigames/cl_minigames_hud.qc
index fd9e3941e..a1d9a2577 100644
--- a/qcsrc/common/minigames/cl_minigames_hud.qc
+++ b/qcsrc/common/minigames/cl_minigames_hud.qc
@@ -10,6 +10,26 @@
 #include <client/hud/hud_config.qh>
 #include <client/mapvoting.qh>
 
+void HUD_MinigameBoard_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+}
+
+void HUD_MinigameStatus_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+}
+
+void HUD_MinigameHelp_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+}
+
+void HUD_MinigameMenu_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+}
+
 // whether the mouse is over the given panel
 bool HUD_mouse_over(entity somepanel)
 {
diff --git a/qcsrc/common/mutators/mutator/itemstime/itemstime.qc b/qcsrc/common/mutators/mutator/itemstime/itemstime.qc
index 5add006c3..5ee7faae8 100644
--- a/qcsrc/common/mutators/mutator/itemstime/itemstime.qc
+++ b/qcsrc/common/mutators/mutator/itemstime/itemstime.qc
@@ -185,6 +185,20 @@ MUTATOR_HOOKFUNCTION(itemstime, PlayerSpawn)
 
 #ifdef CSQC
 
+// ItemsTime (#22)
+
+void HUD_ItemsTime_Export(entity panel, int fh)
+{
+	// allow saving cvars that aesthetically change the panel into hud skin files
+	HUD_Write_Cvar("hud_panel_itemstime_iconalign");
+	HUD_Write_Cvar("hud_panel_itemstime_progressbar");
+	HUD_Write_Cvar("hud_panel_itemstime_progressbar_name");
+	HUD_Write_Cvar("hud_panel_itemstime_progressbar_reduced");
+	HUD_Write_Cvar("hud_panel_itemstime_text");
+	HUD_Write_Cvar("hud_panel_itemstime_ratio");
+	HUD_Write_Cvar("hud_panel_itemstime_dynamicsize");
+}
+
 void DrawItemsTimeItem(vector myPos, vector mySize, float ar, string item_icon, float item_time, bool item_available, float item_availableTime)
 {
     float t = 0;