diff --git a/images/hud/spinner_saving_strip.tga b/images/hud/spinner_saving_strip.tga
new file mode 100644
index 00000000..fa877b85
Binary files /dev/null and b/images/hud/spinner_saving_strip.tga differ
diff --git a/layout/hud/hud.xml b/layout/hud/hud.xml
index 4304f3df..8988483f 100644
--- a/layout/hud/hud.xml
+++ b/layout/hud/hud.xml
@@ -17,6 +17,7 @@
+
diff --git a/layout/hud/save-indicator.xml b/layout/hud/save-indicator.xml
new file mode 100644
index 00000000..53482d2b
--- /dev/null
+++ b/layout/hud/save-indicator.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/pages/settings/interface.xml b/layout/pages/settings/interface.xml
index 221dbc90..6e72e182 100644
--- a/layout/pages/settings/interface.xml
+++ b/layout/pages/settings/interface.xml
@@ -135,6 +135,11 @@
hasdocspage="false"
viewgameduringedit="true"
/>
+
+
+
+
+
diff --git a/localization/panorama_english.txt b/localization/panorama_english.txt
index 62255d41..af66b3e9 100644
--- a/localization/panorama_english.txt
+++ b/localization/panorama_english.txt
@@ -94,9 +94,6 @@
"HL2_Grenade" "Fragmentation Grenade"
"HL2_RPG" "RPG\n(Rocket-Propelled Grenade)"
"HL2_Bugbait" "Pheropod\n(Bugbait)"
-
- "HL2_SAVING" "Saving..."
- "HL2_Saved" "Saved."
"HL2_SetupMicrophone" "Configure Advanced Microphone Settings"
"HL2_SetupMicrophoneSteam" "The Steam Overlay is currently disabled.\nPlease enable the Steam Overlay or configure your microphone settings through the Steam client."
@@ -271,6 +268,15 @@
"Instructor_SS_Control" "Press to Control Other Player"
"Paint_Instructor_teach_bounce_suppression" "Hold to prevent bouncing"
+
+ "PORTAL2_Hud_SavingGame" "Saving Game..."
+ "PORTAL2_Hud_GameSaved" "Game Saved."
+
+ "PORTAL2_Hud_AutoSavingGame" "Autosaving Game..."
+ "PORTAL2_Hud_GameAutoSaved" "Game Autosaved."
+
+ "PORTAL2_Hud_SavingProfile" "Saving Profile..."
+ "PORTAL2_Hud_ProfileSaved" "Profile Saved."
// Invites
"P2COOP_Invite_Title" "Portal 2: Commnuity Edition Invite"
@@ -795,6 +801,9 @@
"Settings_Menu_Movie" "Main Menu Video Background"
"Settings_Menu_Movie_Info" "Enables the animated main menu background. May be a minor performance loss when the menu is open."
+ "Settings_Hud_Autosave" "Autosave Indicator"
+ "Settings_Hud_Autosave_Info" "Show an on-screen indicator when the game is automatically saved."
+
// Settings - Personalization
"Settings_Customization" "Customization"
diff --git a/scripts/hud/save-indicator.ts b/scripts/hud/save-indicator.ts
new file mode 100644
index 00000000..0745e953
--- /dev/null
+++ b/scripts/hud/save-indicator.ts
@@ -0,0 +1,62 @@
+'use strict';
+
+class SaveIndicator {
+ static fadeTimer: uuid | undefined = undefined;
+ static isAutoSave: boolean = false;
+
+ static {
+ $.RegisterForUnhandledEvent('GameSaved', this.onSaveStarted.bind(this));
+ $.RegisterForUnhandledEvent('LayoutReloaded', this.hide.bind(this));
+ $.RegisterForUnhandledEvent('LevelInitPostEntity', this.hide.bind(this));
+
+ // Workaround for animation sometimes getting stuck when pausing/unpausing
+ $.RegisterForUnhandledEvent('GameUIStateChanged', (old: GameUIState, now: GameUIState) => {
+ if (now === GameUIState.INGAME) {
+ $('#Spinner')!.SetReadyForDisplay(false);
+ }
+ });
+ }
+
+ static onSaveStarted(save_name: string, save_type: SaveType) {
+ if (!GameInterfaceAPI.GetSettingBool("save_hud")) return;
+
+ if (save_type == SaveType.Autosave) {
+ if (!GameInterfaceAPI.GetSettingBool("save_hud_autosave")) return;
+ this.isAutoSave = true;
+ } else {
+ this.isAutoSave = false;
+ }
+
+ const label = $