From 1d3cdec48db6ae15fdbd00d17276737aa09f3cf1 Mon Sep 17 00:00:00 2001 From: Vantha Date: Mon, 23 Feb 2026 23:52:43 +0100 Subject: [PATCH] Move cutscene mode to renderer This patch splits "cutscene mode" (disabling silhouttes, territory borders and other visual overlays) from the cinema manager component and moves it to the renderer, since it doesn't influence the simulation anyway. The mode can now be independently controlled by the GUI. This is done so it can also be used for other narrative elements like speech or dialogue in the future. Cutscene mode is still always enabled while cinema paths are playing, though. By design, this also fixes the issue that range overlays weren't hidden during cutscene mode. --- .../data/mods/public/gui/session/session.js | 18 ++++++------- source/renderer/RenderingOptions.cpp | 3 ++- source/renderer/RenderingOptions.h | 6 +++++ source/renderer/SceneRenderer.cpp | 25 +++++++++++-------- .../scripting/JSInterface_Renderer.cpp | 4 ++- .../components/CCmpCinemaManager.cpp | 5 ---- .../components/CCmpOverlayRenderer.cpp | 4 +-- .../simulation2/components/CCmpSelectable.cpp | 6 +---- .../components/ICmpOverlayRenderer.cpp | 4 +-- 9 files changed, 37 insertions(+), 38 deletions(-) diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index 68125bb204..8bd672926e 100644 --- a/binaries/data/mods/public/gui/session/session.js +++ b/binaries/data/mods/public/gui/session/session.js @@ -697,25 +697,23 @@ function toggleGUI() updateCinemaPath(); } -var g_HasHiddenSilhouettes = false; +// 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; - // TODO: This isn't great and should use a different system. - if (isPlayingCinemaPath && Engine.ConfigDB_GetValue("user", "silhouettes") == "true") + if (isPlayingCinemaPath && !g_CutsceneModeEnabled) { - Engine.ConfigDB_CreateValue("user", "silhouettes", "false"); - g_HasHiddenSilhouettes = true; + Engine.Renderer_SetCutsceneModeEnabled(true); + g_CutsceneModeEnabled = true; } - else if (!isPlayingCinemaPath && g_HasHiddenSilhouettes) + else if (!isPlayingCinemaPath && g_CutsceneModeEnabled) { - // TODO: Keyboard shortcuts can still try to toggle silhouettes - // which would behave incorrectly on reset. - Engine.ConfigDB_Reload("user"); - g_HasHiddenSilhouettes = false; + Engine.Renderer_SetCutsceneModeEnabled(false); + g_CutsceneModeEnabled = false; } } diff --git a/source/renderer/RenderingOptions.cpp b/source/renderer/RenderingOptions.cpp index 237eee0a06..772efa85b1 100644 --- a/source/renderer/RenderingOptions.cpp +++ b/source/renderer/RenderingOptions.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -138,6 +138,7 @@ CRenderingOptions::CRenderingOptions() : m_ConfigHooks(new ConfigHooks()) m_DisplayFrustum = false; m_DisplayShadowsFrustum = false; m_RenderActors = true; + m_CutsceneMode = false; } CRenderingOptions::~CRenderingOptions() diff --git a/source/renderer/RenderingOptions.h b/source/renderer/RenderingOptions.h index b907553ed1..05ab6dc52b 100644 --- a/source/renderer/RenderingOptions.h +++ b/source/renderer/RenderingOptions.h @@ -120,6 +120,12 @@ OPTION_CUSTOM_SETTER(NAME, TYPE); OPTION_GETTER(NAME, TYPE); OPTION_DEF(NAME, TY OPTION(DisplayFrustum, bool); OPTION(DisplayShadowsFrustum, bool); + // Cutscene Mode: while active, (most) visual overlays aren't rendered in order to give the scene a more "pure" + // and real feel, like a movie. + // The idea is for it to be inactive during normal gameplay, but enabled while playing cinema paths and + // potentially during other scripted story events/cutscenes as well, like speech/dialogue. + OPTION(CutsceneMode, bool); + OPTION(RenderActors, bool); #undef OPTION_DEFAULT_SETTER diff --git a/source/renderer/SceneRenderer.cpp b/source/renderer/SceneRenderer.cpp index 5d3111fd79..4d440e39f0 100644 --- a/source/renderer/SceneRenderer.cpp +++ b/source/renderer/SceneRenderer.cpp @@ -874,7 +874,8 @@ void CSceneRenderer::RenderSubmissions( ITerrainOverlay::RenderOverlaysBeforeWater(deviceCommandContext); // render other debug-related overlays before water (so they can be seen when underwater) - m->overlayRenderer.RenderOverlaysBeforeWater(deviceCommandContext); + if (!g_RenderingOptions.GetCutsceneMode()) + m->overlayRenderer.RenderOverlaysBeforeWater(deviceCommandContext); RenderModels(deviceCommandContext, context, cullGroup); @@ -908,8 +909,9 @@ void CSceneRenderer::RenderSubmissions( // render debug-related terrain overlays ITerrainOverlay::RenderOverlaysAfterWater(deviceCommandContext, cullGroup); - // render some other overlays after water (so they can be displayed on top of water) - m->overlayRenderer.RenderOverlaysAfterWater(deviceCommandContext); + if (!g_RenderingOptions.GetCutsceneMode()) + // render some other overlays after water (so they can be displayed on top of water) + m->overlayRenderer.RenderOverlaysAfterWater(deviceCommandContext); // particles are transparent so render after water if (g_RenderingOptions.GetParticles()) @@ -1087,7 +1089,7 @@ void CSceneRenderer::PrepareScene( m->particleManager.RenderSubmit(*this, frustum); - if (g_RenderingOptions.GetSilhouettes()) + if (!g_RenderingOptions.GetCutsceneMode() && g_RenderingOptions.GetSilhouettes()) { m->silhouetteRenderer.ComputeSubmissions(m_ViewCamera); @@ -1159,16 +1161,17 @@ void CSceneRenderer::RenderScene( void CSceneRenderer::RenderSceneOverlays( Renderer::Backend::IDeviceCommandContext* deviceCommandContext) { - if (g_RenderingOptions.GetSilhouettes()) + if (!g_RenderingOptions.GetCutsceneMode()) { - RenderSilhouettes(deviceCommandContext, m->globalContext); + if (g_RenderingOptions.GetSilhouettes()) + RenderSilhouettes(deviceCommandContext, m->globalContext); + + m->silhouetteRenderer.RenderDebugOverlays(deviceCommandContext); + + // Render overlays that should appear on top of all other objects. + m->overlayRenderer.RenderForegroundOverlays(deviceCommandContext, m_ViewCamera); } - m->silhouetteRenderer.RenderDebugOverlays(deviceCommandContext); - - // Render overlays that should appear on top of all other objects. - m->overlayRenderer.RenderForegroundOverlays(deviceCommandContext, m_ViewCamera); - m_CurrentScene = nullptr; } diff --git a/source/renderer/scripting/JSInterface_Renderer.cpp b/source/renderer/scripting/JSInterface_Renderer.cpp index e1664b7f9c..f1175a3555 100644 --- a/source/renderer/scripting/JSInterface_Renderer.cpp +++ b/source/renderer/scripting/JSInterface_Renderer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -41,6 +41,7 @@ void Set##NAME##Enabled(bool enabled) \ g_RenderingOptions.Set##NAME(enabled); \ } +IMPLEMENT_BOOLEAN_SCRIPT_SETTING(CutsceneMode); IMPLEMENT_BOOLEAN_SCRIPT_SETTING(DisplayFrustum); IMPLEMENT_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum); @@ -76,6 +77,7 @@ void RegisterScriptFunctions(const ScriptRequest& rq) ScriptFunction::Register<&TextureExists>(rq, "TextureExists"); ScriptFunction::Register<&GetRenderDebugMode>(rq, "Renderer_GetRenderDebugMode"); ScriptFunction::Register<&SetRenderDebugMode>(rq, "Renderer_SetRenderDebugMode"); + REGISTER_BOOLEAN_SCRIPT_SETTING(CutsceneMode); REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayFrustum); REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum); } diff --git a/source/simulation2/components/CCmpCinemaManager.cpp b/source/simulation2/components/CCmpCinemaManager.cpp index be15731d28..bc416e1e20 100644 --- a/source/simulation2/components/CCmpCinemaManager.cpp +++ b/source/simulation2/components/CCmpCinemaManager.cpp @@ -248,7 +248,6 @@ public: return; CmpPtr cmpRangeManager(GetSimContext().GetSystemEntity()); - CmpPtr cmpTerritoryManager(GetSimContext().GetSystemEntity()); if (cmpRangeManager) { if (enabled) @@ -256,10 +255,6 @@ public: // TODO: improve m_MapRevealed state and without fade in cmpRangeManager->SetLosRevealWholeMapForAll(enabled); } - if (cmpTerritoryManager) - cmpTerritoryManager->SetVisibility(!enabled); - ICmpSelectable::SetOverrideVisibility(!enabled); - ICmpOverlayRenderer::SetOverrideVisibility(!enabled); m_Enabled = enabled; } diff --git a/source/simulation2/components/CCmpOverlayRenderer.cpp b/source/simulation2/components/CCmpOverlayRenderer.cpp index c9e2882358..904c2852fc 100644 --- a/source/simulation2/components/CCmpOverlayRenderer.cpp +++ b/source/simulation2/components/CCmpOverlayRenderer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -201,7 +201,7 @@ public: void RenderSubmit(SceneCollector &collector) { - if (!m_Enabled || !ICmpOverlayRenderer::m_OverrideVisible) + if (!m_Enabled) return; for (size_t i = 0; i < m_Sprites.size(); ++i) diff --git a/source/simulation2/components/CCmpSelectable.cpp b/source/simulation2/components/CCmpSelectable.cpp index a144e26ca5..44cf2eba1b 100644 --- a/source/simulation2/components/CCmpSelectable.cpp +++ b/source/simulation2/components/CCmpSelectable.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -632,10 +632,6 @@ void CCmpSelectable::UpdateDynamicOverlay(float frameOffset) void CCmpSelectable::RenderSubmit(SceneCollector& collector, const CFrustum& frustum, bool culling) { - // don't render selection overlay if it's not gonna be visible - if (!ICmpSelectable::m_OverrideVisible) - return; - if (m_Visible && m_Color.a > 0) { if (!m_Cached) diff --git a/source/simulation2/components/ICmpOverlayRenderer.cpp b/source/simulation2/components/ICmpOverlayRenderer.cpp index 21f5efd355..1ab2a22d1d 100644 --- a/source/simulation2/components/ICmpOverlayRenderer.cpp +++ b/source/simulation2/components/ICmpOverlayRenderer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -25,5 +25,3 @@ BEGIN_INTERFACE_WRAPPER(OverlayRenderer) DEFINE_INTERFACE_METHOD("Reset", ICmpOverlayRenderer, Reset) DEFINE_INTERFACE_METHOD("AddSprite", ICmpOverlayRenderer, AddSprite) END_INTERFACE_WRAPPER(OverlayRenderer) - -bool ICmpOverlayRenderer::m_OverrideVisible = true;