diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 3ad6ad82e..fca3e50b3 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -1303,25 +1303,30 @@ void Graphics::push(StackType type) stackTypeStack.push_back(type); } -void Graphics::pop() +void Graphics::pop(PopMode mode) { - if (stackTypeStack.size() < 1) + size_t amount = mode == POP_ALL ? stackTypeStack.size() : 1; + + if (stackTypeStack.size() < amount) throw Exception("Minimum stack depth reached (more pops than pushes?)"); - popTransform(); - pixelScaleStack.pop_back(); - - if (stackTypeStack.back() == STACK_ALL) + for (size_t i = 0; i < amount; ++i) { - DisplayState &newstate = states[states.size() - 2]; + popTransform(); + pixelScaleStack.pop_back(); - restoreStateChecked(newstate); + if (stackTypeStack.back() == STACK_ALL) + { + DisplayState &newstate = states[states.size() - 2]; - // The last two states in the stack should be equal now. - states.pop_back(); + restoreStateChecked(newstate); + + // The last two states in the stack should be equal now. + states.pop_back(); + } + + stackTypeStack.pop_back(); } - - stackTypeStack.pop_back(); } /** @@ -1515,6 +1520,16 @@ bool Graphics::getConstant(StackType in, const char *&out) return stackTypes.find(in, out); } +bool Graphics::getConstant(const char *in, PopMode &out) +{ + return popModes.find(in, out); +} + +bool Graphics::getConstant(PopMode in, const char *&out) +{ + return popModes.find(in, out); +} + StringMap::Entry Graphics::drawModeEntries[] = { { "line", DRAW_LINE }, @@ -1608,5 +1623,13 @@ StringMap::Entry Graphics::stackT StringMap Graphics::stackTypes(Graphics::stackTypeEntries, sizeof(Graphics::stackTypeEntries)); +StringMap::Entry Graphics::popModeEntries[] = +{ + { "one", POP_ONE }, + { "all", POP_ALL }, +}; + +StringMap Graphics::popModes(Graphics::popModeEntries, sizeof(Graphics::popModeEntries)); + } // graphics } // love diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 33ca4c59e..f824d2119 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -194,6 +194,13 @@ public: STACK_MAX_ENUM }; + enum PopMode + { + POP_ONE, + POP_ALL, + POP_MAX_ENUM + }; + enum TemporaryRenderTargetFlags { TEMPORARY_RT_DEPTH = (1 << 0), @@ -735,7 +742,7 @@ public: Stats getStats() const; void push(StackType type = STACK_TRANSFORM); - void pop(); + void pop(PopMode mode = POP_ONE); const Matrix4 &getTransform() const; const Matrix4 &getProjection() const; @@ -798,6 +805,9 @@ public: static bool getConstant(const char *in, StackType &out); static bool getConstant(StackType in, const char *&out); + static bool getConstant(const char *in, PopMode &out); + static bool getConstant(PopMode in, const char *&out); + // Default shader code (a shader is always required internally.) static Shader::ShaderSource defaultShaderCode[Shader::STANDARD_MAX_ENUM][Shader::LANGUAGE_MAX_ENUM][2]; @@ -946,6 +956,9 @@ private: static StringMap::Entry stackTypeEntries[]; static StringMap stackTypes; + static StringMap::Entry popModeEntries[]; + static StringMap popModes; + }; // Graphics } // graphics diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 8da39ea79..e213bab32 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -2648,7 +2648,12 @@ int w_push(lua_State *L) int w_pop(lua_State *L) { - luax_catchexcept(L, [&](){ instance()->pop(); }); + Graphics::PopMode mode = Graphics::POP_ONE; + const char *modestring = lua_isnoneornil(L, 1) ? nullptr : luaL_checkstring(L, 1); + if (modestring && !Graphics::getConstant(modestring, mode)) + return luaL_error(L, "Invalid pop mode: %s", modestring); + + luax_catchexcept(L, [&](){ instance()->pop(mode); }); return 0; }