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
This commit is contained in:
Eduardo Bart 2012-06-06 11:10:35 -03:00
parent 7a529d23be
commit bb1fb939c4
17 changed files with 70 additions and 90 deletions

View File

@ -208,7 +208,7 @@ void Application::run()
m_foregroundFrameCounter.processNextFrame(); m_foregroundFrameCounter.processNextFrame();
// draw foreground // draw foreground
g_painter->clearScreen(); g_painter->clear(Color::black);
g_ui.render(true); g_ui.render(true);
// copy the foreground to a texture // copy the foreground to a texture

View File

@ -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() void FrameBuffer::bind()
{ {
g_painter->saveAndResetState();
internalBind(); internalBind();
Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f, Matrix3 projectionMatrix = { 2.0f/m_texture->getWidth(), 0.0f, 0.0f,
0.0f, -2.0f/m_texture->getHeight(), 0.0f, 0.0f, -2.0f/m_texture->getHeight(), 0.0f,
-1.0f, 1.0f, 1.0f }; -1.0f, 1.0f, 1.0f };
g_painter->saveAndResetState();
g_painter->setProjectionMatrix(projectionMatrix); g_painter->setProjectionMatrix(projectionMatrix);
m_oldViewportSize = g_graphics.getViewportSize(); m_oldViewportSize = g_graphics.getViewportSize();
@ -111,8 +99,8 @@ void FrameBuffer::bind()
void FrameBuffer::release() void FrameBuffer::release()
{ {
internalRelease(); internalRelease();
g_painter->restoreSavedState();
g_graphics.setViewportSize(m_oldViewportSize); g_graphics.setViewportSize(m_oldViewportSize);
g_painter->restoreSavedState();
} }
void FrameBuffer::draw() void FrameBuffer::draw()
@ -157,9 +145,10 @@ void FrameBuffer::internalRelease()
m_texture->copyFromScreen(screenRect); m_texture->copyFromScreen(screenRect);
// restore screen original content // restore screen original content
Painter::CompositionMode oldComposition = g_painter->getCompositionMode();
g_painter->setCompositionMode(Painter::CompositionMode_Replace); g_painter->setCompositionMode(Painter::CompositionMode_Replace);
g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect); g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect);
g_painter->resetCompositionMode(); g_painter->setCompositionMode(oldComposition);
} }
} }

View File

@ -35,7 +35,6 @@ public:
void resize(const Size& size); void resize(const Size& size);
void bind(); void bind();
void clear(const Color& color = Color::black, const Rect& rect = Rect());
void release(); void release();
void draw(); void draw();
void draw(const Rect& dest); void draw(const Rect& dest);

View File

@ -235,8 +235,7 @@ void Graphics::resize(const Size& size)
void Graphics::beginRender() void Graphics::beginRender()
{ {
//glClearColor(0, 0, 0, 1); //g_painter->clear(Color::black);
//glClear(GL_COLOR_BUFFER_BIT);
} }
void Graphics::endRender() void Graphics::endRender()

View File

@ -86,12 +86,21 @@ void Painter::restoreSavedState()
setTexture(m_olderStates[m_oldStateIndex].texture); 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); 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) void Painter::setCompositionMode(Painter::CompositionMode compositionMode)
{ {
if(m_compositionMode == compositionMode) if(m_compositionMode == compositionMode)

View File

@ -65,7 +65,9 @@ public:
void saveState(); void saveState();
void saveAndResetState(); void saveAndResetState();
void restoreSavedState(); 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 drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0;
virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0; virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0;

View File

@ -197,7 +197,7 @@ int LuaInterface::luaObjectGetEvent(LuaInterface* lua)
lua->remove(-2); // remove obj fieldmethods lua->remove(-2); // remove obj fieldmethods
if(!lua->isNil()) { // is the get method not nil? if(!lua->isNil()) { // is the get method not nil?
lua->insert(-2); // moves obj to the top 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; return 1;
} }
lua->pop(); // pops the nil get method 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? if(!lua->isNil()) { // is the set method not nil?
lua->insert(-3); // moves func to -3 lua->insert(-3); // moves func to -3
lua->insert(-2); // moves obj to -2, and value to -1 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; return 0;
} }
lua->pop(); // pops the nil set method lua->pop(); // pops the nil set method
@ -373,6 +373,15 @@ std::string LuaInterface::traceback(const std::string& errorMessage, int level)
return popString(); 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 LuaInterface::getCurrentSourcePath(int level)
{ {
std::string path; std::string path;
@ -425,7 +434,7 @@ int LuaInterface::safeCall(int numArgs)
return (stackSize() + numArgs + 1) - previousStackSize; return (stackSize() + numArgs + 1) - previousStackSize;
} }
int LuaInterface::protectedCall(int numArgs, int requestedResults) int LuaInterface::signalCall(int numArgs, int requestedResults)
{ {
int numRets = 0; int numRets = 0;
int funcIndex = -numArgs-1; int funcIndex = -numArgs-1;
@ -683,7 +692,7 @@ void LuaInterface::call(int numArgs, int numRets)
lua_call(L, numArgs, numRets); lua_call(L, numArgs, numRets);
} }
void LuaInterface::throwError() void LuaInterface::error()
{ {
assert(hasIndex(-1)); assert(hasIndex(-1));
lua_error(L); lua_error(L);

View File

@ -153,6 +153,11 @@ public:
/// @return the generated traceback message /// @return the generated traceback message
std::string traceback(const std::string& errorMessage = "", int level = 0); 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 /// Searches for the source of the current running function
std::string getCurrentSourcePath(int level = 0); 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 /// 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, /// @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 /// 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 /// @brief Creates a new environment table
/// The new environment table is redirected to the global environment (aka _G), /// 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); int pcall(int numArgs = 0, int numRets = 0, int errorFuncIndex = 0);
void call(int numArgs = 0, int numRets = 0); void call(int numArgs = 0, int numRets = 0);
void throwError(); void error();
int ref(); int ref();
int weakRef(); int weakRef();
@ -398,7 +403,7 @@ int LuaInterface::callGlobalField(const std::string& global, const std::string&
g_lua.getGlobalField(global, field); g_lua.getGlobalField(global, field);
if(!g_lua.isNil()) { if(!g_lua.isNil()) {
g_lua.polymorphicPush(args...); g_lua.polymorphicPush(args...);
return g_lua.protectedCall(sizeof...(args)); return g_lua.signalCall(sizeof...(args));
} else } else
g_lua.pop(1); g_lua.pop(1);
return 0; return 0;

View File

@ -94,7 +94,7 @@ int LuaObject::callLuaField(const std::string& field, const T&... args) {
// the first argument is always this object (self) // the first argument is always this object (self)
g_lua.insert(-2); g_lua.insert(-2);
g_lua.polymorphicPush(args...); g_lua.polymorphicPush(args...);
return g_lua.protectedCall(1 + sizeof...(args)); return g_lua.signalCall(1 + sizeof...(args));
} else { } else {
g_lua.pop(2); g_lua.pop(2);
} }

View File

@ -37,10 +37,12 @@ void InputMessage::reset()
void InputMessage::setBuffer(const std::string& buffer) 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_readPos = MAX_HEADER_SIZE;
m_headerPos = MAX_HEADER_SIZE; m_headerPos = MAX_HEADER_SIZE;
m_messageSize = buffer.size(); m_messageSize = len;
} }
uint8 InputMessage::getU8() 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) void InputMessage::fillBuffer(uint8 *buffer, uint16 size)
{ {
checkWrite(m_readPos + size);
memcpy(m_buffer + m_readPos, buffer, size); memcpy(m_buffer + m_readPos, buffer, size);
m_messageSize += size; m_messageSize += size;
} }
void InputMessage::setHeaderSize(uint16 size) void InputMessage::setHeaderSize(uint16 size)
{ {
assert(MAX_HEADER_SIZE - size >= 0);
m_headerPos = MAX_HEADER_SIZE - size; m_headerPos = MAX_HEADER_SIZE - size;
m_readPos = m_headerPos; m_readPos = m_headerPos;
} }
bool InputMessage::readChecksum() bool InputMessage::readChecksum()
{ {
uint32_t receivedCheck = getU32(); uint32 receivedCheck = getU32();
uint32 checksum = stdext::adler32(m_buffer + m_readPos, getUnreadSize()); uint32 checksum = stdext::adler32(m_buffer + m_readPos, getUnreadSize());
return receivedCheck == checksum; return receivedCheck == checksum;
} }
@ -115,10 +119,14 @@ bool InputMessage::canRead(int bytes)
return false; return false;
return true; return true;
} }
void InputMessage::checkRead(int bytes) void InputMessage::checkRead(int bytes)
{ {
if(!canRead(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");
}

View File

@ -24,7 +24,6 @@
#define INPUTMESSAGE_H #define INPUTMESSAGE_H
#include "declarations.h" #include "declarations.h"
#include "networkexception.h"
#include <framework/luascript/luaobject.h> #include <framework/luascript/luaobject.h>
class InputMessage : public LuaObject class InputMessage : public LuaObject
@ -79,6 +78,7 @@ protected:
private: private:
bool canRead(int bytes); bool canRead(int bytes);
void checkRead(int bytes); void checkRead(int bytes);
void checkWrite(int bytes);
uint16 m_headerPos; uint16 m_headerPos;
uint16 m_readPos; uint16 m_readPos;

View File

@ -1,34 +0,0 @@
/*
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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

View File

@ -71,7 +71,7 @@ void OutputMessage::addString(const std::string& buffer)
{ {
int len = buffer.length(); int len = buffer.length();
if(len > MAX_STRING_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); checkWrite(len + 2);
addU16(len); addU16(len);
memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), 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) void OutputMessage::encryptRSA(int size, const std::string& key)
{ {
if(m_writePos - size < 0) if(m_messageSize < size)
throw NetworkException("writePos - size < 0"); g_lua.throwError("insufficient bytes in buffer to encrypt");
RSA::encrypt((char*)m_buffer + m_writePos - size, size, key.c_str()); 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) void OutputMessage::checkWrite(int bytes)
{ {
if(!canWrite(bytes)) if(!canWrite(bytes))
throw NetworkException("OutputMessage max buffer size reached"); g_lua.throwError("OutputMessage max buffer size reached");
} }

View File

@ -24,7 +24,6 @@
#define OUTPUTMESSAGE_H #define OUTPUTMESSAGE_H
#include "declarations.h" #include "declarations.h"
#include "networkexception.h"
#include <framework/luascript/luaobject.h> #include <framework/luascript/luaobject.h>
class OutputMessage : public LuaObject class OutputMessage : public LuaObject

View File

@ -71,15 +71,16 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate)
if(m_showTimedSquare && animate) { if(m_showTimedSquare && animate) {
g_painter->setColor(m_timedSquareColor); 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->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) { if(m_showStaticSquare && animate) {
g_painter->setColor(m_staticSquareColor); 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->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); internalDrawOutfit(dest + animationOffset * scaleFactor, scaleFactor, animate, animate, m_direction);
} }
void Creature::internalDrawOutfit(const Point& dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction 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 = FrameBufferPtr(new FrameBuffer(Size(2*Otc::TILE_PIXELS, 2*Otc::TILE_PIXELS)));
outfitBuffer->bind(); 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); internalDrawOutfit(Point(Otc::TILE_PIXELS,Otc::TILE_PIXELS) + getDisplacement(), 1, false, true, Otc::South);
outfitBuffer->release(); outfitBuffer->release();

View File

@ -75,7 +75,7 @@ void MapView::draw(const Rect& rect)
if(m_mustCleanFramebuffer) { if(m_mustCleanFramebuffer) {
Rect clearRect = Rect(0, 0, m_drawDimension * m_tileSize); 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(); auto it = m_cachedVisibleTiles.begin();

View File

@ -319,7 +319,7 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
prevOpcode = opcode; prevOpcode = opcode;
} }
} catch(stdext::exception& e) { } catch(stdext::exception& e) {
g_logger.error(stdext::format("Network exception (%d bytes unread, last opcode is %d, prev opcode is %d): %s", 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())); msg->getUnreadSize(), opcode, prevOpcode, e.what()));
} }
} }
@ -1235,16 +1235,10 @@ void ProtocolGame::parseExtendedOpcode(const InputMessagePtr& msg)
int opcode = msg->getU8(); int opcode = msg->getU8();
std::string buffer = msg->getString(); std::string buffer = msg->getString();
if(opcode == 0) { if(opcode == 0)
m_enableSendExtendedOpcode = true; m_enableSendExtendedOpcode = true;
} else
else {
try {
callLuaField("onExtendedOpcode", opcode, buffer); callLuaField("onExtendedOpcode", opcode, buffer);
} catch(stdext::exception& e) {
g_logger.error(stdext::format("Network exception in extended opcode %d: %s", opcode, e.what()));
}
}
} }
void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height) void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height)