diff --git a/binaries/data/mods/public/gui/session/cinema/CinemaOverlay.js b/binaries/data/mods/public/gui/session/cinema/CinemaOverlay.js
new file mode 100644
index 0000000000..8d11956adc
--- /dev/null
+++ b/binaries/data/mods/public/gui/session/cinema/CinemaOverlay.js
@@ -0,0 +1,92 @@
+/**
+ * This class manages the cinematic overlay, which is responsible for showing black bars at the top and bottom while
+ * cinema paths are playing. Cinema paths are predefined camera animations, which block player input of any kind while
+ * playing; cutscenes, essentially. Whether one is playing is communicated through the simulation state.
+ */
+class CinemaOverlay
+{
+ constructor()
+ {
+ this.overlay = Engine.GetGUIObjectByName("cinemaOverlay");
+ this.barTop = Engine.GetGUIObjectByName("cinemaOverlayBarTop");
+ this.barBottom = Engine.GetGUIObjectByName("cinemaOverlayBarBottom");
+
+ // Objects to hide while showing the overlay.
+ this.primarySessionOverlays = Engine.GetGUIObjectByName("primaryOverlays");
+ this.bandbox = Engine.GetGUIObjectByName("bandbox");
+ this.hotkeys = Engine.GetGUIObjectByName("hotkeys");
+
+ this.overlay.onSimulationUpdate = this.onSimulationUpdate.bind(this);
+ this.overlay.onWindowResized = () =>
+ {
+ this.recalculateBarSizes();
+ };
+ this.overlay.hidden = true;
+ this.isCutsceneModeEnabled = Engine.Renderer_GetCutsceneModeEnabled();
+
+ this.recalculateBarSizes();
+ }
+
+ /**
+ * Enable or disable cutscene mode and remember it in order to save unnecessary calls to the engine.
+ * This, however, assumes that the mode isn't modified anywhere else.
+ */
+ setCutsceneModeEnabled(enabled)
+ {
+ if (this.isCutsceneModeEnabled == enabled)
+ return;
+
+ Engine.Renderer_SetCutsceneModeEnabled(!!enabled);
+ this.isCutsceneModeEnabled = enabled;
+ }
+
+ isInCutsceneMode()
+ {
+ return this.isCutsceneModeEnabled;
+ }
+
+ onSimulationUpdate()
+ {
+ const cinemaPathPlaying = GetSimState().cinemaPathPlaying;
+ if (this.overlay.hidden && cinemaPathPlaying)
+ this.show();
+ else if (!this.overlay.hidden && !cinemaPathPlaying)
+ this.hide();
+ }
+
+ show()
+ {
+ if (!this.overlay.hidden)
+ return;
+
+ this.primarySessionOverlays.hidden = true;
+ this.bandbox.hidden = true;
+ this.hotkeys.hidden = true;
+ this.overlay.hidden = false;
+
+ this.setCutsceneModeEnabled(true);
+ }
+
+ hide()
+ {
+ if (this.overlay.hidden)
+ return;
+
+ this.primarySessionOverlays.hidden = !g_ShowGUI;
+ this.hotkeys.hidden = false;
+ this.overlay.hidden = true;
+
+ this.setCutsceneModeEnabled(false);
+ }
+
+ recalculateBarSizes()
+ {
+ const minHeight = 115;
+ const width = this.overlay.getComputedSize().right;
+ const height = this.overlay.getComputedSize().bottom;
+ // The aspect ratio of 2.39:1 is typical in films and has a cinematic feel to it.
+ const barHeight = Math.max(minHeight, (height - width / 2.39) / 2);
+ this.barTop.size.bottom = barHeight;
+ this.barBottom.size.top = -barHeight;
+ }
+}
diff --git a/binaries/data/mods/public/gui/session/cinema/CinemaOverlay.xml b/binaries/data/mods/public/gui/session/cinema/CinemaOverlay.xml
new file mode 100644
index 0000000000..d0afe5b825
--- /dev/null
+++ b/binaries/data/mods/public/gui/session/cinema/CinemaOverlay.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index a8f453faa5..2585b80c16 100644
--- a/binaries/data/mods/public/gui/session/input.js
+++ b/binaries/data/mods/public/gui/session/input.js
@@ -527,7 +527,7 @@ function getPreferredEntities(ents)
function handleInputBeforeGui(ev, hoveredObject)
{
- if (GetSimState().cinemaPlaying)
+ if (g_CinemaOverlay.isInCutsceneMode())
return false;
// Capture cursor position so we can use it for displaying cursors,
@@ -843,7 +843,7 @@ function handleInputBeforeGui(ev, hoveredObject)
}
function handleInputAfterGui(ev)
{
- if (GetSimState().cinemaPlaying)
+ if (g_CinemaOverlay.isInCutsceneMode())
return false;
if (ev.hotkey === undefined)
ev.hotkey = null;
diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js
index 34952dda32..4b9bf16e70 100644
--- a/binaries/data/mods/public/gui/session/messages.js
+++ b/binaries/data/mods/public/gui/session/messages.js
@@ -444,7 +444,6 @@ function handleNetStatusMessage(message)
if (message.status == "disconnected")
{
g_Disconnected = true;
- updateCinemaPath();
closeOpenDialogs();
}
diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js
index 8bd672926e..c3b437ef4d 100644
--- a/binaries/data/mods/public/gui/session/session.js
+++ b/binaries/data/mods/public/gui/session/session.js
@@ -12,6 +12,7 @@ var g_Ambient;
var g_AutoFormation;
var g_Chat;
var g_Cheats;
+var g_CinemaOverlay;
var g_DeveloperOverlay;
var g_DiplomacyColors;
var g_DiplomacyDialog;
@@ -296,6 +297,7 @@ function init(initData, hotloadData)
g_Ambient = new Ambient();
g_AutoFormation = new AutoFormation();
g_Chat = new Chat(g_PlayerViewControl, g_Cheats);
+ g_CinemaOverlay = new CinemaOverlay();
g_DeveloperOverlay = new DeveloperOverlay(g_PlayerViewControl, g_Selection);
g_DiplomacyDialog = new DiplomacyDialog(g_PlayerViewControl, g_DiplomacyColors);
g_GameSpeedControl = new GameSpeedControl(g_PlayerViewControl);
@@ -631,6 +633,10 @@ function onTick()
handleNetMessages();
updateCursorAndTooltip();
+ updateTimers();
+
+ if (g_CinemaOverlay.isInCutsceneMode())
+ return;
if (g_Selection.dirty)
{
@@ -650,12 +656,7 @@ function onTick()
else if (g_ShowAllStatusBars && now % g_StatusBarUpdate <= tickLength)
recalculateStatusBarDisplay();
- updateTimers();
Engine.GuiInterfaceCall("ClearRenamedEntities");
-
- const isPlayingCinemaPath = GetSimState().cinemaPlaying && !g_Disconnected;
- if (isPlayingCinemaPath)
- updateCinemaOverlay();
}
function onSimulationUpdate()
@@ -686,7 +687,6 @@ function onSimulationUpdate()
handler();
// TODO: Move to handlers
- updateCinemaPath();
handleNotifications();
updateGUIObjects();
}
@@ -694,40 +694,8 @@ function onSimulationUpdate()
function toggleGUI()
{
g_ShowGUI = !g_ShowGUI;
- updateCinemaPath();
-}
-
-// TODO: The whole cinema UI should be handled by its own class.
-var g_CutsceneModeEnabled = false;
-function updateCinemaPath()
-{
- const isPlayingCinemaPath = GetSimState().cinemaPlaying && !g_Disconnected;
-
- Engine.GetGUIObjectByName("session").hidden = !g_ShowGUI || isPlayingCinemaPath;
- Engine.GetGUIObjectByName("cinemaOverlay").hidden = !isPlayingCinemaPath;
- if (isPlayingCinemaPath && !g_CutsceneModeEnabled)
- {
- Engine.Renderer_SetCutsceneModeEnabled(true);
- g_CutsceneModeEnabled = true;
- }
- else if (!isPlayingCinemaPath && g_CutsceneModeEnabled)
- {
- Engine.Renderer_SetCutsceneModeEnabled(false);
- g_CutsceneModeEnabled = false;
- }
-}
-
-function updateCinemaOverlay()
-{
- const cinemaOverlay = Engine.GetGUIObjectByName("cinemaOverlay");
- const width = cinemaOverlay.getComputedSize().right;
- const height = cinemaOverlay.getComputedSize().bottom;
- let barHeight = (height - width / 2.39) / 2;
- if (barHeight < 0)
- barHeight = 0;
-
- Engine.GetGUIObjectByName("cinemaBarTop").size.bottom = barHeight;
- Engine.GetGUIObjectByName("cinemaBarBottom").size.top = -barHeight;
+ Engine.GetGUIObjectByName("primaryOverlays").hidden = !g_ShowGUI;
+ Engine.GetGUIObjectByName("supplementaryOverlays").hidden = !g_ShowGUI;
}
// TODO: Use event subscription onSimulationUpdate, onEntitySelectionChange, onPlayerViewChange, ... instead
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
index 179b663213..e5bc790821 100644
--- a/binaries/data/mods/public/gui/session/session.xml
+++ b/binaries/data/mods/public/gui/session/session.xml
@@ -8,6 +8,7 @@
+
@@ -34,93 +35,99 @@
onSimulationUpdate();
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
index d3cdcde055..37d61f1c95 100644
--- a/binaries/data/mods/public/simulation/components/GuiInterface.js
+++ b/binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -155,7 +155,7 @@ GuiInterface.prototype.GetSimulationState = function()
const cmpCinemaManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_CinemaManager);
if (cmpCinemaManager)
- ret.cinemaPlaying = cmpCinemaManager.IsPlayingQueue();
+ ret.cinemaPathPlaying = cmpCinemaManager.IsPlayingQueue();
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
ret.victoryConditions = cmpEndGameManager.GetVictoryConditions();