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();
// draw foreground
g_painter->clearScreen();
g_painter->clear(Color::black);
g_ui.render(true);
// 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()
{
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);
}
}

View File

@ -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);

View File

@ -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()

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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");
}

View File

@ -24,7 +24,6 @@
#define INPUTMESSAGE_H
#include "declarations.h"
#include "networkexception.h"
#include <framework/luascript/luaobject.h>
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;

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();
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");
}

View File

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

View File

@ -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();

View File

@ -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();

View File

@ -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)