basic drawing functions

powerfull Point, Rect, Size, Color classes
prerequesites header
This commit is contained in:
Eduardo Bart 2010-11-24 21:36:15 -02:00
parent 4102ae093c
commit 3d0b191199
30 changed files with 775 additions and 160 deletions

62
src/color.h Normal file
View File

@ -0,0 +1,62 @@
/* The MIT License
*
* Copyright (c) 2010 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 COLOR_H
#define COLOR_H
#include "prerequisites.h"
typedef uint32 RGBA;
class Color
{
public:
Color() : color(0) { }
Color(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) : color(((r & 0xff)<<24) | ((g & 0xff)<<16) | ((b & 0xff)<<8) | (a & 0xff)) { }
Color(const Color& other) : color(other.color) { }
Color(RGBA rgba) : color(rgba) { }
uint8 red() const { return (color >> 24) & 0xFF; }
uint8 green() const { return (color >> 16) & 0xFF; }
uint8 blue() const { return (color >> 8) & 0xFF; }
uint8 alpha() const { return color & 0xFF; }
RGBA rgba() const { return color; }
const uint8* rgbaPtr() const { return (const uint8*)&color; }
void setRed(uint8 r) { color = ((r & 0xff)<<24) | (color & 0x00ffffff); }
void setGreen(uint8 g) { color = ((g & 0xff)<<16) | (color & 0xff00ffff); }
void setBlue(uint8 b) { color = ((b & 0xff)<<8) | (color & 0xffff00ff); }
void setAlpha(uint8 a) { color = (a & 0xff) | (color & 0xffffff00); }
void setRGBA(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) { color = ((r & 0xff)<<24) | ((g & 0xff)<<16) | ((b & 0xff)<<8) | (a & 0xff); }
void setRGBA(uint32 rgba) { color = rgba; }
Color& operator=(const Color& other) { color = other.color; return *this; }
bool operator==(const Color& other) const { return other.color == color; }
bool operator!=(const Color& other) const { return other.color != color; }
private:
RGBA color;
};
#endif // COLOR_H

View File

@ -23,13 +23,10 @@
#include "configmanager.h" #include "configmanager.h"
#include "logger.h"
#include "util.h"
#include <fstream>
#include <yaml-cpp/yaml.h>
#include "resourcemanager.h" #include "resourcemanager.h"
#include <yaml-cpp/yaml.h>
ConfigManager g_config; ConfigManager g_config;
ConfigManager::ConfigManager() ConfigManager::ConfigManager()
@ -77,9 +74,11 @@ bool ConfigManager::load(const std::string& fileName)
void ConfigManager::save() void ConfigManager::save()
{ {
if(!m_fileName.empty()) {
YAML::Emitter out; YAML::Emitter out;
out << m_confsMap; out << m_confsMap;
g_resources.saveFile(m_fileName, (const unsigned char*)out.c_str(), out.size()); g_resources.saveFile(m_fileName, (const unsigned char*)out.c_str(), out.size());
}
} }
void ConfigManager::setValue(const std::string &key, const std::string &value) void ConfigManager::setValue(const std::string &key, const std::string &value)

View File

@ -25,8 +25,7 @@
#ifndef CONFIGMANAGER_H #ifndef CONFIGMANAGER_H
#define CONFIGMANAGER_H #define CONFIGMANAGER_H
#include <string> #include "prerequisites.h"
#include <map>
class ConfigManager class ConfigManager
{ {

View File

@ -25,10 +25,8 @@
#include "engine.h" #include "engine.h"
#include "platform.h" #include "platform.h"
#include "graphics.h" #include "graphics.h"
#include "const.h"
#include "input.h" #include "input.h"
#include "configmanager.h" #include "configmanager.h"
#include "logger.h"
#include "gamestate.h" #include "gamestate.h"
Engine g_engine; Engine g_engine;
@ -36,7 +34,6 @@ Engine g_engine;
Engine::Engine() : Engine::Engine() :
m_stopping(false), m_stopping(false),
m_running(false), m_running(false),
m_lastFrameTicks(0),
m_currentState(NULL) m_currentState(NULL)
{ {
} }
@ -82,18 +79,19 @@ void Engine::terminate()
void Engine::run() void Engine::run()
{ {
unsigned long ticks; unsigned long ticks;
static unsigned long lastFrameTicks;
m_running = true; m_running = true;
m_lastFrameTicks = Platform::getTicks();
lastFrameTicks = Platform::getTicks();
while(!m_stopping) { while(!m_stopping) {
// fire platform events // fire platform events
Platform::poll(); Platform::poll();
// update // update
ticks = Platform::getTicks(); ticks = Platform::getTicks();
update(ticks - m_lastFrameTicks); update(ticks - lastFrameTicks);
m_lastFrameTicks = ticks; lastFrameTicks = ticks;
// render // render
render(); render();
@ -102,7 +100,7 @@ void Engine::run()
Platform::swapBuffers(); Platform::swapBuffers();
} }
m_lastFrameTicks = 0; lastFrameTicks = 0;
m_stopping = false; m_stopping = false;
m_running = false; m_running = false;
} }
@ -117,6 +115,7 @@ void Engine::changeState(GameState* newState)
if(m_currentState) if(m_currentState)
m_currentState->onLeave(); m_currentState->onLeave();
m_currentState = newState; m_currentState = newState;
if(m_currentState)
m_currentState->onEnter(); m_currentState->onEnter();
} }

View File

@ -25,6 +25,8 @@
#ifndef ENGINE_H #ifndef ENGINE_H
#define ENGINE_H #define ENGINE_H
#include "prerequisites.h"
struct InputEvent; struct InputEvent;
class GameState; class GameState;
@ -66,8 +68,6 @@ private:
bool m_stopping; bool m_stopping;
bool m_running; bool m_running;
unsigned long m_lastFrameTicks;
GameState *m_currentState; GameState *m_currentState;
}; };

View File

@ -21,15 +21,9 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#define GL_GLEXT_PROTOTYPES
#include "framebuffer.h" #include "framebuffer.h"
#include "platform.h" #include "platform.h"
#include "graphics.h" #include "graphics.h"
#include "logger.h"
#include <GL/glext.h>
#include <GL/glu.h>
FrameBuffer::FrameBuffer(int width, int height) FrameBuffer::FrameBuffer(int width, int height)
{ {

View File

@ -25,7 +25,7 @@
#ifndef FRAMEBUFFER_H #ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H #define FRAMEBUFFER_H
#include <GL/gl.h> #include "prerequisites.h"
class FrameBuffer class FrameBuffer
{ {

View File

@ -24,9 +24,6 @@
#include "graphics.h" #include "graphics.h"
#include "logger.h" #include "logger.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include "texture.h" #include "texture.h"
Graphics g_graphics; Graphics g_graphics;
@ -60,15 +57,18 @@ void Graphics::terminate()
void Graphics::resize(int width, int height) void Graphics::resize(int width, int height)
{ {
m_width = width; m_screenSize.setWidth(width);
m_height = height; m_screenSize.setHeight(height);
restoreViewport(); restoreViewport();
} }
void Graphics::restoreViewport() void Graphics::restoreViewport()
{ {
const int& width = m_screenSize.width();
const int& height = m_screenSize.height();
// resize gl viewport // resize gl viewport
glViewport(0, 0, m_width, m_height); glViewport(0, 0, width, height);
/* /*
0,0---------0,w 0,0---------0,w
@ -80,7 +80,7 @@ void Graphics::restoreViewport()
// setup view region like above // setup view region like above
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluOrtho2D(0.0f, m_width, m_height, 0.0f); gluOrtho2D(0.0f, width, height, 0.0f);
// back to model view // back to model view
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
@ -98,3 +98,107 @@ void Graphics::endRender()
{ {
} }
void Graphics::drawTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& texCoords)
{
// rect correction for opengl
int right = screenCoords.right()+1;
int bottom = screenCoords.bottom()+1;
int top = screenCoords.top();
int left = screenCoords.left();
float tright;
float tbottom;
float ttop;
float tleft;
if(!texCoords.isEmpty()) {
const Size& textureSize = texture->getSize();
tright = (float)(texCoords.right()+1)/textureSize.width();
tbottom = (float)(texCoords.bottom()+1)/textureSize.height();
ttop = (float)texCoords.top()/textureSize.height();
tleft = (float)texCoords.left()/textureSize.width();
} else {
tright = 0.0f;
tbottom = 1.0f;
ttop = 0.0f;
tleft = 1.0f;
}
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
glBegin(GL_QUADS);
glTexCoord2f(tleft, ttop); glVertex2i(left, top);
glTexCoord2f(tleft, tbottom); glVertex2i(left, bottom);
glTexCoord2f(tright, tbottom); glVertex2i(right, bottom);
glTexCoord2f(tright, ttop); glVertex2i(right, top);
glEnd();
}
void Graphics::drawColoredRect(const Rect& screenCoords, const Color& color)
{
glDisable(GL_TEXTURE_2D);
glColor4ubv(color.rgbaPtr());
// rect correction for opengl
int right = screenCoords.right()+1;
int bottom = screenCoords.bottom()+1;
int top = screenCoords.top();
int left = screenCoords.left();
glBegin(GL_QUADS);
glVertex2i(left, top);
glVertex2i(left, bottom);
glVertex2i(right, bottom);
glVertex2i(right, top);
glEnd();
glEnable(GL_TEXTURE_2D);
}
void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, int lineWidth)
{
if(2*lineWidth > screenCoords.height())
return;
glDisable(GL_TEXTURE_2D);
glColor4ubv(color.rgbaPtr());
// rect correction for opengl
int right = screenCoords.right()+1;
int bottom = screenCoords.bottom()+1;
int top = screenCoords.top();
int left = screenCoords.left();
glBegin(GL_QUADS);
// top line
glVertex2i(left, top);
glVertex2i(left, top+lineWidth);
glVertex2i(right, top+lineWidth);
glVertex2i(right, top);
// left
glVertex2i(left, screenCoords.top()+lineWidth);
glVertex2i(left, bottom-lineWidth);
glVertex2i(left+lineWidth, bottom-lineWidth);
glVertex2i(left+lineWidth, screenCoords.top()+lineWidth);
// bottom line
glVertex2i(left, bottom);
glVertex2i(left, bottom-lineWidth);
glVertex2i(right, bottom-lineWidth);
glVertex2i(right, bottom);
// right line
glVertex2i(right, top+lineWidth);
glVertex2i(right, bottom-lineWidth);
glVertex2i(right-lineWidth, bottom-lineWidth);
glVertex2i(right-lineWidth, top+lineWidth);
glEnd();
glEnable(GL_TEXTURE_2D);
}

View File

@ -25,6 +25,11 @@
#ifndef GRAPHICS_H #ifndef GRAPHICS_H
#define GRAPHICS_H #define GRAPHICS_H
#include "prerequisites.h"
#include "rect.h"
#include "size.h"
#include "color.h"
class Texture; class Texture;
class Graphics class Graphics
@ -48,12 +53,13 @@ public:
/// Called after every render /// Called after every render
void endRender(); void endRender();
int getWidth() { return m_width; } const Size& getScreenSize() const { return m_screenSize; }
int getHeight() { return m_height; } void drawTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& texCoords = Rect());
void drawColoredRect(const Rect& screenCoords, const Color& color);
void drawBoundingRect(const Rect& screenCoords, const Color& color, int lineWidth);
private: private:
int m_width; Size m_screenSize;
int m_height;
}; };
extern Graphics g_graphics; extern Graphics g_graphics;

View File

@ -23,10 +23,6 @@
#include "logger.h" #include "logger.h"
#include "util.h"
#include <cstdarg>
#include <cstdlib>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
void Logger::log(int level, const char *trace, const char *format, ...) void Logger::log(int level, const char *trace, const char *format, ...)

View File

@ -25,9 +25,7 @@
#ifndef LOGGER_H #ifndef LOGGER_H
#define LOGGER_H #define LOGGER_H
#include <iostream> #include "prerequisites.h"
#include <sstream>
#include <string>
namespace Logger { namespace Logger {

View File

@ -23,8 +23,6 @@
#include "engine.h" #include "engine.h"
#include "const.h"
#include "logger.h"
#include "configmanager.h" #include "configmanager.h"
#include "resourcemanager.h" #include "resourcemanager.h"
#include "platform.h" #include "platform.h"

View File

@ -28,8 +28,8 @@
#include "texturemanager.h" #include "texturemanager.h"
#include "logger.h" #include "logger.h"
#include "engine.h" #include "engine.h"
#include "rect.h"
FrameBuffer *fbo;
TexturePtr background; TexturePtr background;
MenuState::MenuState() MenuState::MenuState()
@ -44,8 +44,8 @@ MenuState::~MenuState()
void MenuState::onEnter() void MenuState::onEnter()
{ {
background = g_textures.get("background.png"); m_background = g_textures.get("background.png");
background->enableBilinearFilter(); m_background->enableBilinearFilter();
} }
void MenuState::onLeave() void MenuState::onLeave()
@ -64,43 +64,19 @@ void MenuState::onInputEvent(InputEvent* event)
void MenuState::render() void MenuState::render()
{ {
// draw background static Size minTexCoordsSize(1240, 880);
background->bind(); const Size& screenSize = g_graphics.getScreenSize();
Size texSize = m_background->getSize();
int x = 0; Size texCoordsSize = screenSize;
int y = 0; if(texCoordsSize < minTexCoordsSize)
int screenWidth = g_graphics.getWidth(); texCoordsSize.scale(minTexCoordsSize, KEEP_ASPECT_RATIO_BY_EXPANDING);
int screenHeight = g_graphics.getHeight(); texCoordsSize = texCoordsSize.boundedTo(texSize);
int textureWidth = background->getWidth();
int textureHeight = background->getHeight();
int texCoordX; Rect texCoords(0, 0, texCoordsSize);
int texCoordY; texCoords.moveBottomRight(texSize.toPoint());
int texCoordWidth;
int texCoordHeight;
int wantedWidth = 1240; g_graphics.drawTexturedRect(Rect(0, 0, screenSize), m_background.get(), texCoords);
int wantedHeight = 880;
float originalRatio = (float)wantedWidth/wantedHeight;
float screenRatio = (float)screenWidth/screenHeight;
if(screenRatio >= originalRatio) {
texCoordHeight = wantedHeight;
texCoordWidth = std::min((int)(wantedHeight*screenRatio), textureWidth);
} else {
texCoordWidth = wantedWidth;
texCoordHeight = std::min((int)(wantedWidth/screenRatio), textureHeight);
}
texCoordX = textureWidth - texCoordWidth;
texCoordY = textureHeight - texCoordHeight;
glBegin(GL_QUADS);
glTexCoord2f((float)texCoordX/textureWidth, (float)texCoordY/textureHeight); glVertex2i(x, y);
glTexCoord2f((float)texCoordX/textureWidth, (float)(texCoordY+texCoordHeight)/textureHeight); glVertex2i(x, y+screenHeight);
glTexCoord2f((float)(texCoordX+texCoordWidth)/textureWidth, (float)(texCoordY+texCoordHeight)/textureHeight); glVertex2i(x+screenWidth, y+screenHeight);
glTexCoord2f((float)(texCoordX+texCoordWidth)/textureWidth, (float)texCoordY/textureHeight); glVertex2i(x+screenWidth, y);
glEnd();
} }
void MenuState::update(int elapsedTicks) void MenuState::update(int elapsedTicks)

View File

@ -25,7 +25,9 @@
#ifndef MENUSTATE_H #ifndef MENUSTATE_H
#define MENUSTATE_H #define MENUSTATE_H
#include "prerequisites.h"
#include "gamestate.h" #include "gamestate.h"
#include "texture.h"
class MenuState : public GameState class MenuState : public GameState
{ {
@ -42,6 +44,9 @@ public:
void render(); void render();
void update(int elapsedTicks); void update(int elapsedTicks);
private:
TexturePtr m_background;
}; };
#endif // MENUSTATE_H #endif // MENUSTATE_H

View File

@ -25,7 +25,8 @@
#ifndef PLATFORM_H #ifndef PLATFORM_H
#define PLATFORM_H #define PLATFORM_H
// namespace with platform specific stuff #include "prerequisites.h"
namespace Platform namespace Platform
{ {
void init(); void init();

79
src/point.h Normal file
View File

@ -0,0 +1,79 @@
/* The MIT License
*
* Copyright (c) 2010 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 POINT_H
#define POINT_H
#include "prerequisites.h"
template <class T>
class TSize;
template <class T>
class TPoint
{
public:
inline TPoint() : x(0), y(0) {};
inline TPoint(T x, T y) : x(x), y(y) { };
inline TPoint(const TPoint<T>& other) : x(other.x), y(other.y) { };
inline bool isNull() const { return x==0 && y==0; }
inline TSize<T> toSize() const { return TSize<T>(x, y); }
inline TPoint<T> operator-() const { return TPoint<T>(-x, -y); }
inline TPoint<T> operator+(const TPoint<T>& other) const { return TPoint<T>(x + other.x, y + other.y); }
inline TPoint<T>& operator+=(const TPoint<T>& other) { x+=other.x; y+=other.y; return *this; }
inline TPoint<T> operator-(const TPoint<T>& other) const { return TPoint<T>(x - other.x, y - other.y); }
inline TPoint<T>& operator-=(const TPoint<T>& other) { x-=other.x; y-=other.y; return *this; }
inline TPoint<T> operator*(const TPoint<T>& other) const { return TPoint<T>(x * other.x, y * other.y); }
inline TPoint<T>& operator*=(const TPoint<T>& other) { x*=other.x; y*=other.y; return *this; }
inline TPoint<T> operator*(const T v) const { return TPoint<T>(x * v, y * v); }
inline TPoint<T>& operator*=(const T v) { x*=v; y*=v; return *this; }
inline TPoint<T> operator/(const TPoint<T>& other) const { return TPoint<T>(x/other.x, y/other.y); }
inline TPoint<T>& operator/=(const TPoint<T>& other) { x/=other.x; y/=other.y; return *this; }
inline TPoint<T> operator/(const T v) const { return TPoint<T>(x/v, y/v); }
inline TPoint<T>& operator/=(const T v) { x/=v; y/=v; return *this; }
inline bool operator<=(const TPoint<T>&other) const { return x<=other.x && y<=other.y; }
inline bool operator>=(const TPoint<T>&other) const { return x>=other.x && y>=other.y; }
inline bool operator<(const TPoint<T>&other) const { return x<other.x && y<other.y; }
inline bool operator>(const TPoint<T>&other) const { return x>other.x && y>other.y; }
inline TPoint<T>& operator=(const TPoint<T>& other) { x = other.x; y = other.y; return *this; }
inline bool operator==(const TPoint<T>& other) const { return other.x==x && other.y==y; }
inline bool operator!=(const TPoint<T>& other) const { return other.x!=x || other.y!=y; }
inline float length() const { return sqrtf((float)(x*x + y*y)); }
inline float distanceFrom(const TPoint<T>& other) const {
return TPoint<T>(x - other.x, y - other.y).getLength();
}
T x, y;
};
typedef TPoint<int> Point;
typedef TPoint<float> PointF;
#endif

View File

@ -22,13 +22,60 @@
*/ */
#ifndef VERSION_H #ifndef PREREQUISITES_H
#define VERSION_H #define PREREQUISITES_H
#define APP_VERSION "0.1.0" // app name
#define APP_NAME "OTClient" #define APP_NAME "OTClient"
#define APP_LONGNAME APP_NAME " " APP_VERSION #define APP_LONGNAME APP_NAME " " APP_VERSION
#define APP_ICON "data/otclient.bmp"
#endif // app version
#define APP_VERSION "0.1.0"
// int types
#include <stdint.h>
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef uint32_t uint32;
typedef uint16_t uint16;
typedef uint8_t uint8;
typedef int32_t int32;
typedef int16_t int16;
typedef int8_t int8;
// c headers
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cstdarg>
#include <cmath>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
// stl headers
#include <string>
#include <vector>
#include <map>
#include <string>
#include <list>
// GL stuff
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
// utilities
#include "logger.h"
#include "util.h"
#endif // PREREQUISITES_H

284
src/rect.h Normal file
View File

@ -0,0 +1,284 @@
/* The MIT License
*
* Copyright (c) 2010 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 RECT_H
#define RECT_H
#include "prerequisites.h"
#include "point.h"
#include "size.h"
template <class T>
class TPoint;
template <class T>
class TSize;
template <class T>
class TRect
{
public:
inline TRect() : x1(0), y1(0), x2(-1), y2(-1) { }
inline TRect(T x, T y, T width, T height) : x1(x), y1(y), x2(x+width-1), y2(y+height-1) { }
inline TRect(const TPoint<T>& topLeft, const TPoint<T>& bottomRight) : x1(topLeft.x), y1(topLeft.y), x2(bottomRight.x), y2(bottomRight.y) { }
inline TRect(const TRect<T>& other) : x1(other.x1), y1(other.y1), x2(other.x2), y2(other.y2) { }
inline TRect(T x, T y, const TSize<T>& size) : x1(x), y1(y), x2(x+size.width()-1), y2(y+size.height()-1) { }
inline TRect(const TPoint<T>& topLeft, const TSize<T>& size) : x1(topLeft.x), y1(topLeft.y), x2(x+size.width()-1), y2(y+size.height()-1) { }
inline bool isNull() const { return x2 == x1 - 1 && y2 == y1 - 1; }
inline bool isEmpty() const { return x1 > x2 || y1 > y2; }
inline bool isValid() const { return x1 <= x2 && y1 <= y2; }
inline T left() const { return x1; }
inline T top() const { return y1; }
inline T right() const { return x2; }
inline T bottom() const { return y2; }
inline T x() const { return x1; }
inline T y() const { return y1; }
inline TPoint<T> topLeft() const { return TPoint<T>(x1, y1); }
inline TPoint<T> bottomRight() const { return TPoint<T>(x2, y2); }
inline TPoint<T> topRight() const { return TPoint<T>(x2, y1); }
inline TPoint<T> bottomLeft() const { return TPoint<T>(x1, y2); }
inline TPoint<T> center() const { return TPoint<T>((x1+x2)/2, (y1+y2)/2); }
inline T width() const { return x2 - x1 + 1; }
inline T height() const { return y2 - y1 + 1; }
inline TSize<T> size() const { return TSize<T>(width(), height()); }
inline void setLeft(T pos) { x1 = pos; }
inline void setTop(T pos) { y1 = pos; }
inline void setRight(T pos) { x2 = pos; }
inline void setBottom(T pos) { y2 = pos; }
inline void setX(T x) { x1 = x; }
inline void setY(T y) { y1 = y; }
inline void setTopLeft(const TPoint<T> &p) { x1 = p.x; y1 = p.y; }
inline void setBottomRight(const TPoint<T> &p) { x2 = p.x; y2 = p.y; }
inline void setTopRight(const TPoint<T> &p) { x2 = p.x; y1 = p.y; }
inline void setBottomLeft(const TPoint<T> &p) { x1 = p.x; y2 = p.y; }
inline void setWidth(T width) { x2 = x1 + width - 1; }
inline void setHeight(T height) { y2 = y1 + height- 1; }
inline void setSize(T width, T height) { x2 = x1 + width; y2 = y1 + height; }
inline void setSize(const TSize<T>& size) { x2 = x1 + size.width(); y2 = y1 + size.height(); }
inline void setRect(T x, T y, T width, T height) { x1 = x; y1 = y; x2 = (x + width - 1); y2 = (y + height - 1); }
inline void setCoords(int left, int top, int right, int bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; }
inline void translate(T x, T y) { x1 += x; y1 += y; x2 += x; y2 += y; }
inline void translate(const TPoint<T> &p) { x1 += p.x; y1 += p.y; x2 += p.x; y2 += p.y; }
inline void moveTo(T x, T y) { x2 += x - x1; y2 += y - y1; x1 = x; y1 = y; }
inline void moveTo(const TPoint<T> &p) { x2 += p.x - x1; y2 += p.y - y1; x1 = p.x; y1 = p.y; }
inline void moveLeft(T pos) { x2 += (pos - x1); x1 = pos; }
inline void moveTop(T pos) { y2 += (pos - y1); y1 = pos; }
inline void moveRight(T pos) { x1 += (pos - x2); x2 = pos; }
inline void moveBottom(T pos) { y1 += (pos - y2); y2 = pos; }
inline void moveTopLeft(const TPoint<T> &p) { moveLeft(p.x); moveTop(p.y); }
inline void moveBottomRight(const TPoint<T> &p) { moveRight(p.x); moveBottom(p.y); }
inline void moveTopRight(const TPoint<T> &p) { moveRight(p.x); moveTop(p.y); }
inline void moveBottomLeft(const TPoint<T> &p) { moveLeft(p.x); moveBottom(p.y); }
inline TRect<T> translated(int x, int y) const { return TRect<T>(TPoint<T>(x1 + x, y1 + y), TPoint<T>(x2 + x, y2 + y)); }
inline TRect<T> translated(const TPoint<T> &p) const { return TRect<T>(TPoint<T>(x1 + p.x(), y1 + p.y()), TPoint<T>(x2 + p.x(), y2 + p.y())); }
void moveCenter(const TPoint<T> &p) {
T w = x2 - x1;
T h = y2 - y1;
x1 = p.x() - w/2;
y1 = p.y() - h/2;
x2 = x1 + w;
y2 = y1 + h;
}
bool contains(const TPoint<T> &p, bool insideOnly = false) const {
T l, r;
if(x2 < x1 - 1) {
l = x2;
r = x1;
} else {
l = x1;
r = x2;
}
if(insideOnly) {
if(p.x() <= l || p.x() >= r)
return false;
} else {
if(p.x() < l || p.x() > r)
return false;
}
int t, b;
if(y2 < y1 - 1) {
t = y2;
b = y1;
} else {
t = y1;
b = y2;
}
if(insideOnly) {
if(p.y() <= t || p.y() >= b)
return false;
} else {
if(p.y() < t || p.y() > b)
return false;
}
return true;
}
bool intersects(const TRect<T> &r) const {
if(isNull() || r.isNull())
return false;
int l1 = x1;
int r1 = x1;
if(x2 - x1 + 1 < 0)
l1 = x2;
else
r1 = x2;
int l2 = r.x1;
int r2 = r.x1;
if(r.x2 - r.x1 + 1 < 0)
l2 = r.x2;
else
r2 = r.x2;
if (l1 > r2 || l2 > r1)
return false;
int t1 = y1;
int b1 = y1;
if(y2 - y1 + 1 < 0)
t1 = y2;
else
b1 = y2;
int t2 = r.y1;
int b2 = r.y1;
if (r.y2 - r.y1 + 1 < 0)
t2 = r.y2;
else
b2 = r.y2;
if(t1 > b2 || t2 > b1)
return false;
return true;
}
TRect<T> united(const TRect<T> &r) const {
if(isNull() || r.isNull())
return TRect<T>();
int l1 = x1;
int r1 = x1;
if (x2 - x1 + 1 < 0)
l1 = x2;
else
r1 = x2;
int l2 = r.x1;
int r2 = r.x1;
if(r.x2 - r.x1 + 1 < 0)
l2 = r.x2;
else
r2 = r.x2;
if(l1 > r2 || l2 > r1)
return TRect<T>();
int t1 = y1;
int b1 = y1;
if(y2 - y1 + 1 < 0)
t1 = y2;
else
b1 = y2;
int t2 = r.y1;
int b2 = r.y1;
if(r.y2 - r.y1 + 1 < 0)
t2 = r.y2;
else
b2 = r.y2;
if(t1 > b2 || t2 > b1)
return TRect<T>();
TRect<T> tmp;
tmp.x1 = std::max(l1, l2);
tmp.x2 = std::min(r1, r2);
tmp.y1 = std::max(t1, t2);
tmp.y2 = std::min(b1, b2);
return tmp;
}
TRect<T> intersection(const TRect<T> &r) const {
if(isNull())
return r;
if(r.isNull())
return *this;
int l1 = x1;
int r1 = x1;
if(x2 - x1 + 1 < 0)
l1 = x2;
else
r1 = x2;
int l2 = r.x1;
int r2 = r.x1;
if(r.x2 - r.x1 + 1 < 0)
l2 = r.x2;
else
r2 = r.x2;
int t1 = y1;
int b1 = y1;
if(y2 - y1 + 1 < 0)
t1 = y2;
else
b1 = y2;
int t2 = r.y1;
int b2 = r.y1;
if(r.y2 - r.y1 + 1 < 0)
t2 = r.y2;
else
b2 = r.y2;
TRect<T> tmp;
tmp.x1 = std::min(l1, l2);
tmp.x2 = std::max(r1, r2);
tmp.y1 = std::min(t1, t2);
tmp.y2 = std::max(b1, b2);
return tmp;
}
inline TRect<T>& operator=(const TRect<T>& other) { x1 = other.x1; y1 = other.y1; x2 = other.x2; y2 = other.y2; return *this; }
inline bool operator==(const TRect<T>& other) const { return (x1 == other.x1 && y1 == other.y1 && x2 == other.x2 && y2 == other.y2); }
inline bool operator!=(const TRect<T>& other) const { return (x1 != other.x1 || y1 != other.y1 || x2 != other.x2 || y2 != other.y2); }
private:
T x1, y1, x2, y2;
};
typedef TRect<int> Rect;
typedef TRect<float> RectF;
#endif // RECT_H

View File

@ -23,7 +23,6 @@
#include "resourcemanager.h" #include "resourcemanager.h"
#include "logger.h"
#include <physfs.h> #include <physfs.h>

View File

@ -25,7 +25,7 @@
#ifndef RESOURCEMANAGER_H #ifndef RESOURCEMANAGER_H
#define RESOURCEMANAGER_H #define RESOURCEMANAGER_H
#include <string> #include "prerequisites.h"
class ResourceManager class ResourceManager
{ {

113
src/size.h Normal file
View File

@ -0,0 +1,113 @@
/* The MIT License
*
* Copyright (c) 2010 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 SIZE_H
#define SIZE_H
#include "prerequisites.h"
#include "point.h"
enum ESizeScaleMode {
IGNORE_ASPECT_RATIO,
KEEP_ASPECT_RATIO,
KEEP_ASPECT_RATIO_BY_EXPANDING
};
template <class T>
class TSize
{
public:
TSize() : wd(-1), ht(-1) {};
TSize(T width, T height) : wd(width), ht(height) { };
TSize(const TSize<T>& other) : wd(other.wd), ht(other.ht) { };
inline TPoint<T> toPoint() const { return TPoint<T>(wd, ht); }
inline bool isNull() const { return wd==0 && ht==0; }
inline bool isEmpty() const { return wd<1 || ht<1; }
inline bool isValid() const { return wd>=0 && ht>=0; }
inline int width() const { return wd; }
inline int height() const { return ht; }
inline void setWidth(T w) { wd = w; }
inline void setHeight(T h) { ht = h; }
inline TSize<T> operator-() const { return TSize<T>(-wd, -ht); }
inline TSize<T> operator+(const TSize<T>& other) const { return TSize<T>(wd + other.wd, ht + other.ht); }
inline TSize<T>& operator+=(const TSize<T>& other) { wd+=other.wd; ht+=other.ht; return *this; }
inline TSize<T> operator-(const TSize<T>& other) const { return TSize<T>(wd - other.wd, ht - other.ht); }
inline TSize<T>& operator-=(const TSize<T>& other) { wd-=other.wd; ht-=other.ht; return *this; }
inline TSize<T> operator*(const float v) const { return TSize<T>((T)v*wd, (T)ht*v); }
inline TSize<T>& operator*=(const float v) { wd=(T)v*wd; ht=(T)ht*v; return *this; }
inline TSize<T> operator/(const float v) const { return TSize<T>((T)wd/v, (T)ht/v); }
inline TSize<T>& operator/=(const float v) { (T)wd/=v; (T)ht/=v; return *this; }
inline bool operator<=(const TSize<T>&other) const { return wd<=other.wd || ht<=other.ht; }
inline bool operator>=(const TSize<T>&other) const { return wd>=other.wd || ht>=other.ht; }
inline bool operator<(const TSize<T>&other) const { return wd<other.wd || ht<other.ht; }
inline bool operator>(const TSize<T>&other) const { return wd>other.wd || ht>other.ht; }
inline TSize<T>& operator=(const TSize<T>& other) { wd = other.wd; ht = other.ht; return *this; }
inline bool operator==(const TSize<T>& other) const { return other.wd==wd && other.ht==ht; }
inline bool operator!=(const TSize<T>& other) const { return other.wd!=wd || other.ht!=ht; }
inline TSize<T> expandedTo(const TSize<T>& other) const { return TSize<T>(std::max(wd,other.wd), std::max(ht,other.ht)); }
inline TSize<T> boundedTo(const TSize<T>& other) const { return TSize<T>(std::min(wd,other.wd), std::min(ht,other.ht)); }
void scale(const TSize<T>& s, ESizeScaleMode mode) {
if(mode == IGNORE_ASPECT_RATIO || wd == 0 || ht == 0) {
wd = s.wd;
ht = s.ht;
} else {
bool useHeight;
T rw = (s.ht * wd) / ht;
if(mode == KEEP_ASPECT_RATIO)
useHeight = (rw <= s.wd);
else // mode == KEEP_ASPECT_RATIO_BY_EXPANDING
useHeight = (rw >= s.wd);
if(useHeight) {
wd = rw;
ht = s.ht;
} else {
ht = (s.wd * ht)/wd;
wd = s.wd;
}
}
}
void scale(int w, int h, ESizeScaleMode mode) { scale(TSize<T>(w, h)); }
inline float ratio() const { return (float)wd/ht; }
inline T area() const { return wd*ht; }
private:
T wd, ht;
};
typedef TSize<int> Size;
typedef TSize<float> SizeF;
#endif

View File

@ -24,13 +24,10 @@
#include "texture.h" #include "texture.h"
#include <GL/gl.h>
#include <GL/glu.h>
Texture::Texture(int width, int height, int components, unsigned char *pixels) Texture::Texture(int width, int height, int components, unsigned char *pixels)
{ {
m_width = width; m_size.setWidth(width);
m_height = height; m_size.setHeight(height);
glGenTextures(1, &m_textureId); glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId); glBindTexture(GL_TEXTURE_2D, m_textureId);
@ -66,30 +63,9 @@ Texture::~Texture()
glDeleteTextures(1, &m_textureId); glDeleteTextures(1, &m_textureId);
} }
void Texture::bind()
{
glBindTexture(GL_TEXTURE_2D, m_textureId);
}
void Texture::enableBilinearFilter() void Texture::enableBilinearFilter()
{ {
glBindTexture(GL_TEXTURE_2D, m_textureId); glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} }
void Texture::draw(int x, int y)
{
draw(x, y, m_width, m_height);
}
void Texture::draw(int x, int y, int width, int height)
{
glBindTexture(GL_TEXTURE_2D, m_textureId);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(x, y);
glTexCoord2i(0, 1); glVertex2i(x, y+height);
glTexCoord2i(1, 1); glVertex2i(x+width, y+height);
glTexCoord2i(1, 0); glVertex2i(x+width, y);
glEnd();
}

View File

@ -25,7 +25,8 @@
#ifndef TEXTURE_H #ifndef TEXTURE_H
#define TEXTURE_H #define TEXTURE_H
#include <GL/gl.h> #include "prerequisites.h"
#include "size.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
class TextureManager; class TextureManager;
@ -37,22 +38,15 @@ public:
Texture(int width, int height, int components, unsigned char *pixels = NULL); Texture(int width, int height, int components, unsigned char *pixels = NULL);
virtual ~Texture(); virtual ~Texture();
/// Bind texture for drawing
void bind();
/// Enable texture bilinear filter (smooth scaled textures) /// Enable texture bilinear filter (smooth scaled textures)
void enableBilinearFilter(); void enableBilinearFilter();
void draw(int x, int y); const Size& getSize() const { return m_size; }
void draw(int x, int y, int width, int height); GLuint getTextureId() const { return m_textureId; }
int getWidth() const { return m_width; }
int getHeight() const { return m_height; }
private: private:
GLuint m_textureId; GLuint m_textureId;
int m_width; Size m_size;
int m_height;
}; };
typedef boost::shared_ptr<Texture> TexturePtr; typedef boost::shared_ptr<Texture> TexturePtr;

View File

@ -23,38 +23,37 @@
#include "textureloader.h" #include "textureloader.h"
#include "texture.h"
#include <cstdio>
#include <png.h> #include <png.h>
TexturePtr TextureLoader::loadPNG(const unsigned char *fileData, unsigned int fileSize) Texture *TextureLoader::loadPNG(const unsigned char *fileData, unsigned int fileSize)
{ {
TexturePtr texture;
FILE *pngFile = fmemopen((void*)fileData, fileSize, "rb"); FILE *pngFile = fmemopen((void*)fileData, fileSize, "rb");
if(!pngFile) if(!pngFile)
return texture; return NULL;
png_byte sig[8]; png_byte sig[8];
if(!fread(&sig, 8, 1, pngFile)) if(!fread(&sig, 8, 1, pngFile))
return texture; return NULL;
if(png_sig_cmp(sig, 0, 8)) if(png_sig_cmp(sig, 0, 8))
return texture; return NULL;
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr) if(!png_ptr)
return texture; return NULL;
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr) { if(!info_ptr) {
png_destroy_read_struct(&png_ptr, NULL, NULL); png_destroy_read_struct(&png_ptr, NULL, NULL);
return texture; return NULL;
} }
if(setjmp(png_jmpbuf(png_ptr))) { if(setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return texture; return NULL;
} }
png_init_io(png_ptr, pngFile); png_init_io(png_ptr, pngFile);
@ -101,7 +100,7 @@ TexturePtr TextureLoader::loadPNG(const unsigned char *fileData, unsigned int fi
default: default:
if(png_ptr) if(png_ptr)
png_destroy_read_struct(&png_ptr, &info_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return texture; return NULL;
}; };
unsigned char *pixels = new unsigned char[width * height * components]; unsigned char *pixels = new unsigned char[width * height * components];
@ -117,7 +116,7 @@ TexturePtr TextureLoader::loadPNG(const unsigned char *fileData, unsigned int fi
fclose(pngFile); fclose(pngFile);
delete[] row_pointers; delete[] row_pointers;
texture = TexturePtr(new Texture(width, height, components, pixels)); Texture *texture = new Texture(width, height, components, pixels);
delete[] pixels; delete[] pixels;

View File

@ -25,12 +25,14 @@
#ifndef TEXTURELOADER_H #ifndef TEXTURELOADER_H
#define TEXTURELOADER_H #define TEXTURELOADER_H
#include "texture.h" #include "prerequisites.h"
class Texture;
namespace TextureLoader namespace TextureLoader
{ {
/// Load a png textures using libpng /// Load a png textures using libpng
TexturePtr loadPNG(const unsigned char *fileData, unsigned int fileSize); Texture *loadPNG(const unsigned char *fileData, unsigned int fileSize);
} }
#endif // TEXTURELOADER_H #endif // TEXTURELOADER_H

View File

@ -25,7 +25,6 @@
#include "texturemanager.h" #include "texturemanager.h"
#include "resourcemanager.h" #include "resourcemanager.h"
#include "textureloader.h" #include "textureloader.h"
#include "logger.h"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@ -61,7 +60,7 @@ TexturePtr TextureManager::get(const std::string& textureFile)
if(!textureFileData) if(!textureFileData)
return texture; return texture;
texture = TextureLoader::loadPNG(textureFileData, fileSize); texture = TexturePtr(TextureLoader::loadPNG(textureFileData, fileSize));
if(!texture) if(!texture)
error("Unable to load texture %s, loading error.", textureFile.c_str()); error("Unable to load texture %s, loading error.", textureFile.c_str());
delete[] textureFileData; delete[] textureFileData;

View File

@ -25,11 +25,9 @@
#ifndef TEXTUREMANAGER_H #ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H #define TEXTUREMANAGER_H
#include "prerequisites.h"
#include "texture.h" #include "texture.h"
#include <string>
#include <map>
class TextureManager class TextureManager
{ {
public: public:

View File

@ -24,8 +24,6 @@
#include "util.h" #include "util.h"
#include <cstdio>
std::string vformat(const char *format, va_list args) std::string vformat(const char *format, va_list args)
{ {
if(!format) if(!format)

View File

@ -25,9 +25,7 @@
#ifndef UTIL_H #ifndef UTIL_H
#define UTIL_H #define UTIL_H
#include <string> #include "prerequisites.h"
#include <sstream>
#include <cstdarg>
/// Formatting like printf for std::string, va_list input version /// Formatting like printf for std::string, va_list input version
std::string vformat(const char *format, va_list args); std::string vformat(const char *format, va_list args);

View File

@ -26,19 +26,11 @@
#include "engine.h" #include "engine.h"
#include "input.h" #include "input.h"
#include "logger.h" #include "logger.h"
#include "const.h"
#include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <map>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <GL/glx.h> #include <GL/glx.h>