From bb1fb939c4f60d03ad91129bcad892cf12ba7336 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Wed, 6 Jun 2012 11:10:35 -0300 Subject: [PATCH] just fixes * fix battle rendering * fix rendering glitch when following creatures * properly throw exceptions from C++ to lua and avoid exception crashs * fixes rendering states in framebuffer --- src/framework/application.cpp | 2 +- src/framework/graphics/framebuffer.cpp | 21 ++++----------- src/framework/graphics/framebuffer.h | 1 - src/framework/graphics/graphics.cpp | 3 +-- src/framework/graphics/painter.cpp | 13 +++++++-- src/framework/graphics/painter.h | 4 ++- src/framework/luascript/luainterface.cpp | 17 +++++++++--- src/framework/luascript/luainterface.h | 11 +++++--- src/framework/luascript/luaobject.h | 2 +- src/framework/net/inputmessage.cpp | 18 +++++++++---- src/framework/net/inputmessage.h | 2 +- src/framework/net/networkexception.h | 34 ------------------------ src/framework/net/outputmessage.cpp | 8 +++--- src/framework/net/outputmessage.h | 1 - src/otclient/core/creature.cpp | 5 ++-- src/otclient/core/mapview.cpp | 2 +- src/otclient/net/protocolgameparse.cpp | 16 ++++------- 17 files changed, 70 insertions(+), 90 deletions(-) delete mode 100644 src/framework/net/networkexception.h diff --git a/src/framework/application.cpp b/src/framework/application.cpp index cb53299d..8ff344c3 100644 --- a/src/framework/application.cpp +++ b/src/framework/application.cpp @@ -208,7 +208,7 @@ void Application::run() m_foregroundFrameCounter.processNextFrame(); // draw foreground - g_painter->clearScreen(); + g_painter->clear(Color::black); g_ui.render(true); // copy the foreground to a texture diff --git a/src/framework/graphics/framebuffer.cpp b/src/framework/graphics/framebuffer.cpp index dfb32dec..5824f0c3 100644 --- a/src/framework/graphics/framebuffer.cpp +++ b/src/framework/graphics/framebuffer.cpp @@ -81,27 +81,15 @@ void FrameBuffer::resize(const Size& size) } } -void FrameBuffer::clear(const Color& color, const Rect& rect) -{ - bool clip = rect.isValid(); - if(clip) - g_painter->setClipRect(Rect(0, 0, m_texture->getSize())); - - glClearColor(color.rF(), color.gF(), color.bF(), color.aF()); - glClear(GL_COLOR_BUFFER_BIT); - - if(clip) - g_painter->resetClipRect(); -} - void FrameBuffer::bind() { + g_painter->saveAndResetState(); + internalBind(); Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f, 0.0f, -2.0f/m_texture->getHeight(), 0.0f, -1.0f, 1.0f, 1.0f }; - g_painter->saveAndResetState(); g_painter->setProjectionMatrix(projectionMatrix); m_oldViewportSize = g_graphics.getViewportSize(); @@ -111,8 +99,8 @@ void FrameBuffer::bind() void FrameBuffer::release() { internalRelease(); - g_painter->restoreSavedState(); g_graphics.setViewportSize(m_oldViewportSize); + g_painter->restoreSavedState(); } void FrameBuffer::draw() @@ -157,9 +145,10 @@ void FrameBuffer::internalRelease() m_texture->copyFromScreen(screenRect); // restore screen original content + Painter::CompositionMode oldComposition = g_painter->getCompositionMode(); g_painter->setCompositionMode(Painter::CompositionMode_Replace); g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect); - g_painter->resetCompositionMode(); + g_painter->setCompositionMode(oldComposition); } } diff --git a/src/framework/graphics/framebuffer.h b/src/framework/graphics/framebuffer.h index 3afbe925..68f26709 100644 --- a/src/framework/graphics/framebuffer.h +++ b/src/framework/graphics/framebuffer.h @@ -35,7 +35,6 @@ public: void resize(const Size& size); void bind(); - void clear(const Color& color = Color::black, const Rect& rect = Rect()); void release(); void draw(); void draw(const Rect& dest); diff --git a/src/framework/graphics/graphics.cpp b/src/framework/graphics/graphics.cpp index ea09d382..32a6c6cd 100644 --- a/src/framework/graphics/graphics.cpp +++ b/src/framework/graphics/graphics.cpp @@ -235,8 +235,7 @@ void Graphics::resize(const Size& size) void Graphics::beginRender() { - //glClearColor(0, 0, 0, 1); - //glClear(GL_COLOR_BUFFER_BIT); + //g_painter->clear(Color::black); } void Graphics::endRender() diff --git a/src/framework/graphics/painter.cpp b/src/framework/graphics/painter.cpp index 0496b1eb..88e5fe8b 100644 --- a/src/framework/graphics/painter.cpp +++ b/src/framework/graphics/painter.cpp @@ -86,12 +86,21 @@ void Painter::restoreSavedState() setTexture(m_olderStates[m_oldStateIndex].texture); } -void Painter::clearScreen() +void Painter::clear(const Color& color) { - glClearColor(0,0,0,1); + glClearColor(color.rF(), color.gF(), color.bF(), color.aF()); glClear(GL_COLOR_BUFFER_BIT); } +void Painter::clearRect(const Color& color, const Rect& rect) +{ + Rect oldClipRect = m_clipRect; + setClipRect(rect); + glClearColor(color.rF(), color.gF(), color.bF(), color.aF()); + glClear(GL_COLOR_BUFFER_BIT); + setClipRect(oldClipRect); +} + void Painter::setCompositionMode(Painter::CompositionMode compositionMode) { if(m_compositionMode == compositionMode) diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index cba838a5..5e327cd5 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -65,7 +65,9 @@ public: void saveState(); void saveAndResetState(); void restoreSavedState(); - void clearScreen(); + + void clear(const Color& color); + void clearRect(const Color& color, const Rect& rect); virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0; virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0; diff --git a/src/framework/luascript/luainterface.cpp b/src/framework/luascript/luainterface.cpp index ce94f1a3..60969599 100644 --- a/src/framework/luascript/luainterface.cpp +++ b/src/framework/luascript/luainterface.cpp @@ -197,7 +197,7 @@ int LuaInterface::luaObjectGetEvent(LuaInterface* lua) lua->remove(-2); // remove obj fieldmethods if(!lua->isNil()) { // is the get method not nil? lua->insert(-2); // moves obj to the top - lua->protectedCall(1, 1); // calls get method, arguments: obj + lua->signalCall(1, 1); // calls get method, arguments: obj return 1; } lua->pop(); // pops the nil get method @@ -242,7 +242,7 @@ int LuaInterface::luaObjectSetEvent(LuaInterface* lua) if(!lua->isNil()) { // is the set method not nil? lua->insert(-3); // moves func to -3 lua->insert(-2); // moves obj to -2, and value to -1 - lua->protectedCall(2, 0); // calls set method, arguments: obj, value + lua->signalCall(2, 0); // calls set method, arguments: obj, value return 0; } lua->pop(); // pops the nil set method @@ -373,6 +373,15 @@ std::string LuaInterface::traceback(const std::string& errorMessage, int level) return popString(); } +void LuaInterface::throwError(const std::string& message) +{ + if(isInCppCallback()) { + pushString(message); + error(); + } else + throw stdext::exception(message); +} + std::string LuaInterface::getCurrentSourcePath(int level) { std::string path; @@ -425,7 +434,7 @@ int LuaInterface::safeCall(int numArgs) return (stackSize() + numArgs + 1) - previousStackSize; } -int LuaInterface::protectedCall(int numArgs, int requestedResults) +int LuaInterface::signalCall(int numArgs, int requestedResults) { int numRets = 0; int funcIndex = -numArgs-1; @@ -683,7 +692,7 @@ void LuaInterface::call(int numArgs, int numRets) lua_call(L, numArgs, numRets); } -void LuaInterface::throwError() +void LuaInterface::error() { assert(hasIndex(-1)); lua_error(L); diff --git a/src/framework/luascript/luainterface.h b/src/framework/luascript/luainterface.h index 9ca63c7b..a6a26939 100644 --- a/src/framework/luascript/luainterface.h +++ b/src/framework/luascript/luainterface.h @@ -153,6 +153,11 @@ public: /// @return the generated traceback message std::string traceback(const std::string& errorMessage = "", int level = 0); + /// Throw a lua error if inside a lua call or generates an C++ stdext::exception + /// @param message is the error message wich will be displayed before the error traceback + /// @exception stdext::exception is thrown with the error message if the error is not captured by lua + void throwError(const std::string& message); + /// Searches for the source of the current running function std::string getCurrentSourcePath(int level = 0); @@ -167,7 +172,7 @@ public: /// if any error occurs it will be reported to stdout and returns 0 results /// @param requestedResults is the number of results requested to pushes onto the stack, /// if supplied, the call will always pushes that number of results, even if it fails - int protectedCall(int numArgs = 0, int requestedResults = -1); + int signalCall(int numArgs = 0, int requestedResults = -1); /// @brief Creates a new environment table /// The new environment table is redirected to the global environment (aka _G), @@ -207,7 +212,7 @@ public: int pcall(int numArgs = 0, int numRets = 0, int errorFuncIndex = 0); void call(int numArgs = 0, int numRets = 0); - void throwError(); + void error(); int ref(); int weakRef(); @@ -398,7 +403,7 @@ int LuaInterface::callGlobalField(const std::string& global, const std::string& g_lua.getGlobalField(global, field); if(!g_lua.isNil()) { g_lua.polymorphicPush(args...); - return g_lua.protectedCall(sizeof...(args)); + return g_lua.signalCall(sizeof...(args)); } else g_lua.pop(1); return 0; diff --git a/src/framework/luascript/luaobject.h b/src/framework/luascript/luaobject.h index 8d6abcbb..84ee214d 100644 --- a/src/framework/luascript/luaobject.h +++ b/src/framework/luascript/luaobject.h @@ -94,7 +94,7 @@ int LuaObject::callLuaField(const std::string& field, const T&... args) { // the first argument is always this object (self) g_lua.insert(-2); g_lua.polymorphicPush(args...); - return g_lua.protectedCall(1 + sizeof...(args)); + return g_lua.signalCall(1 + sizeof...(args)); } else { g_lua.pop(2); } diff --git a/src/framework/net/inputmessage.cpp b/src/framework/net/inputmessage.cpp index a4f1839c..4abaea87 100644 --- a/src/framework/net/inputmessage.cpp +++ b/src/framework/net/inputmessage.cpp @@ -37,10 +37,12 @@ void InputMessage::reset() void InputMessage::setBuffer(const std::string& buffer) { - memcpy(m_buffer + MAX_HEADER_SIZE, buffer.c_str(), buffer.size()); + int len = buffer.size(); + checkWrite(MAX_HEADER_SIZE + len); + memcpy(m_buffer + MAX_HEADER_SIZE, buffer.c_str(), len); m_readPos = MAX_HEADER_SIZE; m_headerPos = MAX_HEADER_SIZE; - m_messageSize = buffer.size(); + m_messageSize = len; } uint8 InputMessage::getU8() @@ -92,19 +94,21 @@ void InputMessage::decryptRSA(int size, const std::string& p, const std::string& void InputMessage::fillBuffer(uint8 *buffer, uint16 size) { + checkWrite(m_readPos + size); memcpy(m_buffer + m_readPos, buffer, size); m_messageSize += size; } void InputMessage::setHeaderSize(uint16 size) { + assert(MAX_HEADER_SIZE - size >= 0); m_headerPos = MAX_HEADER_SIZE - size; m_readPos = m_headerPos; } bool InputMessage::readChecksum() { - uint32_t receivedCheck = getU32(); + uint32 receivedCheck = getU32(); uint32 checksum = stdext::adler32(m_buffer + m_readPos, getUnreadSize()); return receivedCheck == checksum; } @@ -115,10 +119,14 @@ bool InputMessage::canRead(int bytes) return false; return true; } - void InputMessage::checkRead(int bytes) { if(!canRead(bytes)) - throw NetworkException("InputMessage eof reached"); + g_lua.throwError("InputMessage eof reached"); } +void InputMessage::checkWrite(int bytes) +{ + if(bytes > BUFFER_MAXSIZE) + g_lua.throwError("InputMessage max buffer size reached"); +} diff --git a/src/framework/net/inputmessage.h b/src/framework/net/inputmessage.h index 4e23c98e..08509281 100644 --- a/src/framework/net/inputmessage.h +++ b/src/framework/net/inputmessage.h @@ -24,7 +24,6 @@ #define INPUTMESSAGE_H #include "declarations.h" -#include "networkexception.h" #include class InputMessage : public LuaObject @@ -79,6 +78,7 @@ protected: private: bool canRead(int bytes); void checkRead(int bytes); + void checkWrite(int bytes); uint16 m_headerPos; uint16 m_readPos; diff --git a/src/framework/net/networkexception.h b/src/framework/net/networkexception.h deleted file mode 100644 index 3b3c1063..00000000 --- a/src/framework/net/networkexception.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2010-2012 OTClient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef NETWORKEXCEPTION_H -#define NETWORKEXCEPTION_H - -#include "declarations.h" - -class NetworkException : public stdext::exception -{ -public: - NetworkException(const std::string& what) : stdext::exception(what) { } -}; - -#endif diff --git a/src/framework/net/outputmessage.cpp b/src/framework/net/outputmessage.cpp index 9f52f3fe..d2df8581 100644 --- a/src/framework/net/outputmessage.cpp +++ b/src/framework/net/outputmessage.cpp @@ -71,7 +71,7 @@ void OutputMessage::addString(const std::string& buffer) { int len = buffer.length(); if(len > MAX_STRING_LENGTH) - throw NetworkException("string length > MAX_STRING_LENGTH"); + g_lua.throwError(stdext::format("string length > %d", MAX_STRING_LENGTH)); checkWrite(len + 2); addU16(len); memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len); @@ -91,8 +91,8 @@ void OutputMessage::addPaddingBytes(int bytes, uint8 byte) void OutputMessage::encryptRSA(int size, const std::string& key) { - if(m_writePos - size < 0) - throw NetworkException("writePos - size < 0"); + if(m_messageSize < size) + g_lua.throwError("insufficient bytes in buffer to encrypt"); RSA::encrypt((char*)m_buffer + m_writePos - size, size, key.c_str()); } @@ -124,5 +124,5 @@ bool OutputMessage::canWrite(int bytes) void OutputMessage::checkWrite(int bytes) { if(!canWrite(bytes)) - throw NetworkException("OutputMessage max buffer size reached"); + g_lua.throwError("OutputMessage max buffer size reached"); } diff --git a/src/framework/net/outputmessage.h b/src/framework/net/outputmessage.h index 0f5a3869..c0abb954 100644 --- a/src/framework/net/outputmessage.h +++ b/src/framework/net/outputmessage.h @@ -24,7 +24,6 @@ #define OUTPUTMESSAGE_H #include "declarations.h" -#include "networkexception.h" #include class OutputMessage : public LuaObject diff --git a/src/otclient/core/creature.cpp b/src/otclient/core/creature.cpp index bd39db22..c45a853b 100644 --- a/src/otclient/core/creature.cpp +++ b/src/otclient/core/creature.cpp @@ -71,15 +71,16 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate) if(m_showTimedSquare && animate) { g_painter->setColor(m_timedSquareColor); g_painter->drawBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 2)*scaleFactor, Size(28, 28)*scaleFactor), std::max((int)(2*scaleFactor), 1)); + g_painter->setColor(Color::white); } if(m_showStaticSquare && animate) { g_painter->setColor(m_staticSquareColor); g_painter->drawBoundingRect(Rect(dest + (animationOffset - getDisplacement())*scaleFactor, Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS)*scaleFactor), std::max((int)(2*scaleFactor), 1)); + g_painter->setColor(Color::white); } internalDrawOutfit(dest + animationOffset * scaleFactor, scaleFactor, animate, animate, m_direction); - } void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction) @@ -202,7 +203,7 @@ void Creature::drawOutfit(const Rect& destRect, bool resize) outfitBuffer = FrameBufferPtr(new FrameBuffer(Size(2*Otc::TILE_PIXELS, 2*Otc::TILE_PIXELS))); outfitBuffer->bind(); - outfitBuffer->clear(Color::alpha); + g_painter->clear(Color::alpha); internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South); outfitBuffer->release(); diff --git a/src/otclient/core/mapview.cpp b/src/otclient/core/mapview.cpp index c4f5728b..93f56171 100644 --- a/src/otclient/core/mapview.cpp +++ b/src/otclient/core/mapview.cpp @@ -75,7 +75,7 @@ void MapView::draw(const Rect& rect) if(m_mustCleanFramebuffer) { Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize); - m_framebuffer->clear(Color::black, clearRect); + g_painter->clearRect(Color::black, clearRect); } auto it = m_cachedVisibleTiles.begin(); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 4354f68a..fdad297a 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -319,8 +319,8 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg) prevOpcode = opcode; } } catch(stdext::exception& e) { - g_logger.error(stdext::format("Network exception (%d bytes unread, last opcode is %d, prev opcode is %d): %s", - msg->getUnreadSize(), opcode, prevOpcode, e.what())); + g_logger.error(stdext::format("ProtocolGame parse message exception (%d bytes unread, last opcode is %d, prev opcode is %d): %s", + msg->getUnreadSize(), opcode, prevOpcode, e.what())); } } @@ -1235,16 +1235,10 @@ void ProtocolGame::parseExtendedOpcode(const InputMessagePtr& msg) int opcode = msg->getU8(); std::string buffer = msg->getString(); - if(opcode == 0) { + if(opcode == 0) m_enableSendExtendedOpcode = true; - } - else { - try { - callLuaField("onExtendedOpcode", opcode, buffer); - } catch(stdext::exception& e) { - g_logger.error(stdext::format("Network exception in extended opcode %d: %s", opcode, e.what())); - } - } + else + callLuaField("onExtendedOpcode", opcode, buffer); } void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height)