From 69c46f6289af3318a8da6c30daad6c8f33aefaed Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 13 Aug 2026 00:39:33 +0200 Subject: [PATCH 1/2] Fix font AdvanceWidths initialization --- src/profile/fonts.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/profile/fonts.cpp b/src/profile/fonts.cpp index 31fadc5b9..e1cf4e351 100644 --- a/src/profile/fonts.cpp +++ b/src/profile/fonts.cpp @@ -104,7 +104,8 @@ void LoadFonts() { } assert(widthSz % bytesPerGlyph == 0); - baseFont->AdvanceWidths.reserve(widthSz / bytesPerGlyph); + const size_t widthCount = widthSz / bytesPerGlyph; + baseFont->AdvanceWidths.reserve(widthCount); const auto readEntry = [&](size_t idx) -> uint64_t { uint64_t value = 0; for (size_t byte = 0; byte < bytesPerGlyph; byte++) { @@ -113,7 +114,7 @@ void LoadFonts() { return value; }; - for (uint16_t i = 0; i < widthSz; i++) { + for (size_t i = 0; i < widthCount; i++) { baseFont->AdvanceWidths.emplace_back( static_cast(readEntry(i) + extraLetterSpacing) * baseFont->BitmapEmWidth / emWidth); From c2204ca61bc6e8772d7478de1c66c929dc217b5e Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 13 Aug 2026 00:40:00 +0200 Subject: [PATCH 2/2] Introduce TopRightQuadrantMask BgEff type --- profiles/cclcc/bgeff.lua | 3 +++ profiles/cclcc/game.lua | 2 -- src/background2d.cpp | 42 +++++++++++++++++++++++--------------- src/character2d.cpp | 36 +++++++++++++++++++++++--------- src/game.cpp | 4 +--- src/profile/data/bgeff.cpp | 12 ++++++++++- src/profile/data/bgeff.h | 9 ++++++++ src/profile/game.cpp | 2 -- src/profile/game.h | 2 -- src/profile/profile.cpp | 2 ++ 10 files changed, 78 insertions(+), 36 deletions(-) diff --git a/profiles/cclcc/bgeff.lua b/profiles/cclcc/bgeff.lua index 6c7e29ffe..ef4f9f72d 100644 --- a/profiles/cclcc/bgeff.lua +++ b/profiles/cclcc/bgeff.lua @@ -1,4 +1,7 @@ root.BgEffData = { + BgChaEffectType = BgEffTypeEnum.TopRightQuadrantMask; + BgFrameEffectType = BgEffTypeEnum.Disabled; + -- bgId, eff1Shader, eff2Shader, eff3Shader, effChaShader BgEffShaderData = { {0, ShaderProgramType.Sprite, ShaderProgramType.Sprite, ShaderProgramType.Sprite, ShaderProgramType.ColorDodgeMaskedSprite}, diff --git a/profiles/cclcc/game.lua b/profiles/cclcc/game.lua index da7a7484d..12ee2230e 100644 --- a/profiles/cclcc/game.lua +++ b/profiles/cclcc/game.lua @@ -13,8 +13,6 @@ root.CursorPointerPath = "resources/cclcc/icondata/cursor_pointer.png"; root.CharaIsMvl = true; root.UseMoviePriority = true; -root.UseBgChaEffects = true; -root.UseBgFrameEffects = false; root.UseWaveEffects = true; root.ScreenCaptureCount = 2; diff --git a/src/background2d.cpp b/src/background2d.cpp index 19b8a2510..593e8244d 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -11,12 +11,14 @@ #include "util.h" #include "profile/scriptvars.h" #include "profile/vm.h" +#include "profile/data/bgeff.h" // #include "window.h" #include "renderer/renderer.h" #include "effects/wave.h" namespace Impacto { +using namespace Impacto::Profile::BgEff; using namespace Impacto::Profile::ScriptVars; using namespace Impacto::Profile::Vm; @@ -84,7 +86,8 @@ bool Background2D::LoadSync(uint32_t bgId) { delete stream; } - if (Profile::Game::UseBgFrameEffects && BgEffTextureIdMap.contains(bgId)) { + if (BgFrameEffectType != BgEffTypeEnum::Disabled && + BgEffTextureIdMap.contains(bgId)) { std::for_each(FrameBgEffs.begin(), FrameBgEffs.end(), [](auto& bgEff) { bgEff.Loaded = false; }); @@ -107,7 +110,8 @@ bool Background2D::LoadSync(uint32_t bgId) { } } - if (Profile::Game::UseBgChaEffects && BgEffTextureIdMap.contains(bgId)) { + if (BgChaEffectType != BgEffTypeEnum::Disabled && + BgEffTextureIdMap.contains(bgId)) { ChaBgEff.Loaded = false; const int textureId = BgEffTextureIdMap[bgId][3]; @@ -142,7 +146,7 @@ void Background2D::UnloadSync() { BgSprite.Sheet.Texture = 0; BgSprite.Sheet.IsScreenCap = false; - if (Profile::Game::UseBgFrameEffects) { + if (BgFrameEffectType != BgEffTypeEnum::Disabled) { for (BgEff& bgEff : FrameBgEffs) { bgEff.Loaded = false; @@ -153,7 +157,7 @@ void Background2D::UnloadSync() { } } - if (Profile::Game::UseBgChaEffects) { + if (BgChaEffectType != BgEffTypeEnum::Disabled) { ChaBgEff.Loaded = false; Renderer->FreeTexture(ChaBgEff.BgEffSprite.Sheet.Texture); @@ -182,7 +186,7 @@ void Background2D::MainThreadOnLoad(bool result) { BgSprite.Bounds = RectF(0.0f, 0.0f, BgSprite.Sheet.DesignWidth, BgSprite.Sheet.DesignHeight); - if (Profile::Game::UseBgFrameEffects) { + if (BgFrameEffectType != BgEffTypeEnum::Disabled) { for (BgEff& bgEff : FrameBgEffs) { if (!bgEff.Loaded) continue; @@ -197,7 +201,7 @@ void Background2D::MainThreadOnLoad(bool result) { } } - if (Profile::Game::UseBgChaEffects && ChaBgEff.Loaded) { + if (BgChaEffectType != BgEffTypeEnum::Disabled && ChaBgEff.Loaded) { ChaBgEff.BgEffSprite.Sheet.Texture = ChaBgEff.BgEffTexture.Submit(); ChaBgEff.BgEffSprite.Sheet.DesignWidth = (float)ChaBgEff.BgEffTexture.Width; @@ -492,19 +496,20 @@ void Background2D::UpdateState(const int bgId) { } } - if (Profile::Game::UseBgChaEffects || Profile::Game::UseBgFrameEffects) { + if (BgFrameEffectType != BgEffTypeEnum::Disabled || + BgChaEffectType != BgEffTypeEnum::Disabled) { BgEffsLayers = {ScrWork[SW_BG1EFFPRI + structOffset], ScrWork[SW_BG1EFFPRI2 + structOffset]}; } - if (Profile::Game::UseBgFrameEffects) { + if (BgFrameEffectType != BgEffTypeEnum::Disabled) { const int bgNo = ScrWork[SW_BG1NO + structOffset]; for (size_t bgEffId = 0; bgEffId < FrameBgEffs.size(); bgEffId++) { FrameBgEffs[bgEffId].Shader = GetBgEffShader(bgNo, bgEffId); } } - if (Profile::Game::UseBgChaEffects) { + if (BgChaEffectType != BgEffTypeEnum::Disabled) { ChaBgEff.Shader = GetBgEffShader(ScrWork[SW_BG1NO + structOffset], 3); } } @@ -516,7 +521,8 @@ void Background2D::Render(const int layer) { return; } - if (Profile::Game::UseBgChaEffects || Profile::Game::UseBgFrameEffects) { + if (BgFrameEffectType != BgEffTypeEnum::Disabled || + BgChaEffectType != BgEffTypeEnum::Disabled) { bool renderBgEffs = false; for (size_t i = 0; i < BgEffsLayers.size(); i++) { @@ -526,14 +532,14 @@ void Background2D::Render(const int layer) { if (renderBgEffs) { bool nonSpriteShader = false; - if (Profile::Game::UseBgFrameEffects) { + if (BgFrameEffectType != BgEffTypeEnum::Disabled) { nonSpriteShader |= std::any_of( FrameBgEffs.begin(), FrameBgEffs.end() - 1, [](const auto bgEff) { return bgEff.Shader != ShaderProgramType::Sprite; }); } - if (Profile::Game::UseBgChaEffects) { + if (BgChaEffectType != BgEffTypeEnum::Disabled) { nonSpriteShader |= ChaBgEff.Shader != ShaderProgramType::Sprite; } @@ -547,7 +553,7 @@ void Background2D::Render(const int layer) { } void Background2D::RenderBgEff(const int layer) { - if (!Profile::Game::UseBgFrameEffects || layer == 0 || + if (BgFrameEffectType == BgEffTypeEnum::Disabled || layer == 0 || std::find(BgEffsLayers.begin(), BgEffsLayers.end(), layer) == BgEffsLayers.end()) { return; @@ -562,21 +568,25 @@ void Background2D::RenderBgEff(const int layer) { // I am aware this leaks a texture at shutdown } + using enum BgEffTypeEnum; const std::array vertices{ VertexBufferSprites{ .Position = {0.0f, Profile::Game::DesignHeight}, .UV = {0.0f, 1.0f}, - .MaskUV = {0.0f, 0.0f}, + .MaskUV = BgFrameEffectType == FullscreenMask ? glm::vec2{0.0f, 0.0f} + : glm::vec2{0.5f, 0.0f}, }, VertexBufferSprites{ .Position = {0.0f, 0.0f}, .UV = {0.0f, 0.0f}, - .MaskUV = {0.0f, 1.0f}, + .MaskUV = BgFrameEffectType == FullscreenMask ? glm::vec2{0.0f, 1.0f} + : glm::vec2{0.5f, 0.5f}, }, VertexBufferSprites{ .Position = {Profile::Game::DesignWidth, 0.0f}, .UV = {1.0f, 0.0f}, - .MaskUV = {1.0f, 1.0f}, + .MaskUV = BgFrameEffectType == FullscreenMask ? glm::vec2{1.0f, 1.0f} + : glm::vec2{1.0f, 0.5f}, }, VertexBufferSprites{ .Position = {Profile::Game::DesignWidth, Profile::Game::DesignHeight}, diff --git a/src/character2d.cpp b/src/character2d.cpp index 11232d160..2d8462abb 100644 --- a/src/character2d.cpp +++ b/src/character2d.cpp @@ -4,6 +4,7 @@ #include "io/io.h" #include "io/vfs.h" #include "util.h" +#include "profile/data/bgeff.h" #include "profile/scriptvars.h" #include "profile/vm.h" #include "profile/configsystem.h" @@ -15,6 +16,7 @@ namespace Impacto { +using namespace Impacto::Profile::BgEff; using namespace Impacto::Profile::ScriptVars; using namespace Impacto::Profile::Vm; @@ -421,7 +423,7 @@ void Character2D::Render(const int layer) { {0.0f, 0.0f}, Scale, glm::vec3(0.0f), Rotation, Position); const bool renderWithBgEffect = - Profile::Game::UseBgChaEffects && + BgChaEffectType != BgEffTypeEnum::Disabled && Background2D::LastRenderedBackground && Background2D::LastRenderedBackground->ChaBgEff.Loaded && UseBgEffect; if (!renderWithBgEffect) { @@ -430,15 +432,29 @@ void Character2D::Render(const int layer) { } else { const BgEff& bgEff = Background2D::LastRenderedBackground->ChaBgEff; - const glm::mat4 maskTransformation = - glm::scale(glm::mat4(1.0f), - {1.0f / Profile::Game::DesignWidth, - 1.0f / Profile::Game::DesignHeight, 1.0f}) * - transformation; - - Renderer->DrawPrimitives(CharaSpriteSheet, &bgEff.BgEffSprite.Sheet, - bgEff.Shader, MvlVertices, MvlIndices, - transformation, maskTransformation); + const static glm::mat4 maskTransformation = []() { + switch (BgChaEffectType) { + using enum BgEffTypeEnum; + case Disabled: + break; + case FullscreenMask: + return glm::scale(glm::mat4(1.0f), + {1.0f / Profile::Game::DesignWidth, + 1.0f / Profile::Game::DesignHeight, 1.0f}); + case TopRightQuadrantMask: + return TransformationMatrix( + glm::vec2(0.0f), + glm::vec2(0.5f / Profile::Game::DesignWidth, + 0.5f / Profile::Game::DesignHeight), + glm::vec3(), glm::quat(), glm::vec2(0.5f, 0.5f)); + } + assert(false); + return glm::mat4(1.0f); + }(); + + Renderer->DrawPrimitives( + CharaSpriteSheet, &bgEff.BgEffSprite.Sheet, bgEff.Shader, MvlVertices, + MvlIndices, transformation, maskTransformation * transformation); } } else { diff --git a/src/game.cpp b/src/game.cpp index a41ed378f..07a8326e6 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -127,9 +127,7 @@ void Init() { Background2D::Init(); Mask2D::Init(); - if (Profile::Game::UseBgChaEffects || Profile::Game::UseBgFrameEffects) { - Profile::BgEff::Load(); - } + Profile::BgEff::Load(); if (Profile::Game::UseWaveEffects) { Profile::WaveEffects::Load(); diff --git a/src/profile/data/bgeff.cpp b/src/profile/data/bgeff.cpp index 13b5b7d8e..d4eaf715b 100644 --- a/src/profile/data/bgeff.cpp +++ b/src/profile/data/bgeff.cpp @@ -9,8 +9,18 @@ namespace Profile { namespace BgEff { void Load() { + if (!TryPushMember("BgEffData")) return; + AssertIs(LUA_TTABLE); + + BgFrameEffectType = EnsureGetMember("BgFrameEffectType"); + BgChaEffectType = EnsureGetMember("BgChaEffectType"); + + if (BgChaEffectType == BgEffTypeEnum::Disabled && + BgFrameEffectType == BgEffTypeEnum::Disabled) { + return; + } + using magic_enum::enum_cast; - EnsurePushMemberOfType("BgEffData", LUA_TTABLE); { EnsurePushMemberOfType("BgEffShaderData", LUA_TTABLE); diff --git a/src/profile/data/bgeff.h b/src/profile/data/bgeff.h index ef2f886b5..940448fbf 100644 --- a/src/profile/data/bgeff.h +++ b/src/profile/data/bgeff.h @@ -4,6 +4,15 @@ namespace Impacto { namespace Profile { namespace BgEff { +enum class BgEffTypeEnum : uint8_t { + Disabled, + FullscreenMask, + TopRightQuadrantMask, +}; + +inline BgEffTypeEnum BgFrameEffectType = BgEffTypeEnum::Disabled; +inline BgEffTypeEnum BgChaEffectType = BgEffTypeEnum::Disabled; + void Load(); } // namespace BgEff diff --git a/src/profile/game.cpp b/src/profile/game.cpp index 3301c54d9..7a45b5fd1 100644 --- a/src/profile/game.cpp +++ b/src/profile/game.cpp @@ -31,8 +31,6 @@ void Configure() { ScreenCaptureCount = TryGetMember("ScreenCaptureCount").value_or(0); TryGetMember("UseMoviePriority", UseMoviePriority); - TryGetMember("UseBgChaEffects", UseBgChaEffects); - TryGetMember("UseBgFrameEffects", UseBgFrameEffects); TryGetMember("UseWaveEffects", UseWaveEffects); ActiveAudioBackend = diff --git a/src/profile/game.h b/src/profile/game.h index 717d2a23d..a6af03ffe 100644 --- a/src/profile/game.h +++ b/src/profile/game.h @@ -33,8 +33,6 @@ inline bool CharaIsMvl; inline size_t ScreenCaptureCount = 0; inline bool UseMoviePriority = false; -inline bool UseBgChaEffects = false; -inline bool UseBgFrameEffects = false; inline bool UseWaveEffects = false; inline float LayFileTexXMultiplier; diff --git a/src/profile/profile.cpp b/src/profile/profile.cpp index 77415eff5..ccb7bf6cd 100644 --- a/src/profile/profile.cpp +++ b/src/profile/profile.cpp @@ -29,6 +29,7 @@ #include "../hud/skipicondisplay.h" #include "../hud/tipsnotification.h" #include "../profile/hud/saveicon.h" +#include "../profile/data/bgeff.h" #include "../inputsystem.h" namespace Impacto { @@ -203,6 +204,7 @@ static void DefineEnums() { DefineEnum(LuaState); DefineEnum(LuaState); DefineEnum(LuaState); + DefineEnum(LuaState); } void Init() {