mirror of
https://github.com/edubart/otclient.git
synced 2025-10-17 04:53:27 +02:00
framework
This commit is contained in:
62
src/framework/color.h
Normal file
62
src/framework/color.h
Normal 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
|
152
src/framework/configmanager.cpp
Normal file
152
src/framework/configmanager.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "configmanager.h"
|
||||
#include "resourcemanager.h"
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
ConfigManager g_config;
|
||||
|
||||
ConfigManager::ConfigManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ConfigManager::~ConfigManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ConfigManager::load(const std::string& fileName)
|
||||
{
|
||||
m_fileName = fileName;
|
||||
|
||||
if(!g_resources.fileExists(fileName))
|
||||
return false;
|
||||
|
||||
std::string fileContents = g_resources.loadTextFile(fileName);
|
||||
if(fileContents.size() == 0)
|
||||
return false;
|
||||
|
||||
std::istringstream fin(fileContents);
|
||||
|
||||
try {
|
||||
YAML::Parser parser(fin);
|
||||
|
||||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
for(YAML::Iterator it = doc.begin(); it != doc.end(); it++) {
|
||||
std::string key, value;
|
||||
it.first() >> key;
|
||||
it.second() >> value;
|
||||
m_confsMap[key] = value;
|
||||
dump() << key << value;
|
||||
}
|
||||
} catch (YAML::ParserException& e) {
|
||||
error("Malformed configuration file!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfigManager::save()
|
||||
{
|
||||
if(!m_fileName.empty()) {
|
||||
YAML::Emitter out;
|
||||
out << m_confsMap;
|
||||
g_resources.saveFile(m_fileName, (const unsigned char*)out.c_str(), out.size());
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string &key, const std::string &value)
|
||||
{
|
||||
m_confsMap[key] = value;
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string &key, const char *value)
|
||||
{
|
||||
m_confsMap[key] = value;
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string &key, int value)
|
||||
{
|
||||
setValue(key, boost::lexical_cast<std::string>(value));
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string &key, float value)
|
||||
{
|
||||
setValue(key, boost::lexical_cast<std::string>(value));
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string &key, bool value)
|
||||
{
|
||||
if(value)
|
||||
setValue(key,"true");
|
||||
else
|
||||
setValue(key,"false");
|
||||
}
|
||||
|
||||
const std::string &ConfigManager::getString(const std::string &key)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator iter = m_confsMap.find(key);
|
||||
if(iter == m_confsMap.end()) {
|
||||
warning("Config value %s not found", key.c_str());
|
||||
static std::string emptystr;
|
||||
return emptystr;
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
float ConfigManager::getFloat(const std::string &key)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator iter = m_confsMap.find(key);
|
||||
if(iter == m_confsMap.end()) {
|
||||
warning("Config value %s not found", key.c_str());
|
||||
return 0;
|
||||
}
|
||||
return boost::lexical_cast<float>(iter->second);
|
||||
}
|
||||
|
||||
bool ConfigManager::getBoolean(const std::string &key)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator iter = m_confsMap.find(key);
|
||||
if(iter == m_confsMap.end()) {
|
||||
warning("Config value %s not found", key.c_str());
|
||||
return 0;
|
||||
}
|
||||
return (iter->second == "true");
|
||||
}
|
||||
|
||||
int ConfigManager::getInteger(const std::string &key)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator iter = m_confsMap.find(key);
|
||||
if(iter == m_confsMap.end()) {
|
||||
warning("Config value %s not found", key.c_str());
|
||||
return 0;
|
||||
}
|
||||
return boost::lexical_cast<int>(iter->second);
|
||||
}
|
60
src/framework/configmanager.h
Normal file
60
src/framework/configmanager.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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 CONFIGMANAGER_H
|
||||
#define CONFIGMANAGER_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
class ConfigManager
|
||||
{
|
||||
public:
|
||||
ConfigManager();
|
||||
~ConfigManager();
|
||||
|
||||
/// Read configuration file and parse all settings to memory
|
||||
bool load(const std::string& fileName);
|
||||
|
||||
/// Dump all settings to configuration file
|
||||
void save();
|
||||
|
||||
void setValue(const std::string &key, const std::string &value);
|
||||
void setValue(const std::string &key, const char *value);
|
||||
void setValue(const std::string &key, float value);
|
||||
void setValue(const std::string &key, bool value);
|
||||
void setValue(const std::string &key, int value);
|
||||
|
||||
const std::string &getString(const std::string &key);
|
||||
float getFloat(const std::string &key);
|
||||
bool getBoolean(const std::string &key);
|
||||
int getInteger(const std::string &key);
|
||||
|
||||
private:
|
||||
std::string m_fileName;
|
||||
std::map<std::string, std::string> m_confsMap;
|
||||
};
|
||||
|
||||
extern ConfigManager g_config;
|
||||
|
||||
#endif // CONFIGMANAGER_H
|
151
src/framework/engine.cpp
Normal file
151
src/framework/engine.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "engine.h"
|
||||
#include "platform.h"
|
||||
#include "graphics.h"
|
||||
#include "input.h"
|
||||
#include "configmanager.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
Engine g_engine;
|
||||
|
||||
Engine::Engine() :
|
||||
m_stopping(false),
|
||||
m_running(false),
|
||||
m_currentState(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Engine::~Engine()
|
||||
{
|
||||
}
|
||||
|
||||
void Engine::init()
|
||||
{
|
||||
Platform::init();
|
||||
|
||||
int width = g_config.getInteger("width");
|
||||
int height = g_config.getInteger("height");
|
||||
|
||||
// create the window
|
||||
Platform::createWindow(width, height, 550, 450);
|
||||
Platform::setWindowTitle(APP_NAME);
|
||||
Platform::setVsync();
|
||||
|
||||
// initialize graphics stuff
|
||||
g_graphics.init();
|
||||
|
||||
// finally show the window
|
||||
onResize(width, height);
|
||||
Platform::showWindow();
|
||||
Platform::hideMouseCursor();
|
||||
}
|
||||
|
||||
void Engine::terminate()
|
||||
{
|
||||
changeState(NULL);
|
||||
|
||||
// save configs
|
||||
g_config.setValue("width", Platform::getWindowWidth());
|
||||
g_config.setValue("height", Platform::getWindowHeight());
|
||||
|
||||
Platform::showMouseCursor();
|
||||
Platform::terminate();
|
||||
g_graphics.terminate();
|
||||
}
|
||||
|
||||
void Engine::run()
|
||||
{
|
||||
unsigned long ticks;
|
||||
static unsigned long lastFrameTicks;
|
||||
|
||||
m_running = true;
|
||||
|
||||
lastFrameTicks = Platform::getTicks();
|
||||
while(!m_stopping) {
|
||||
// fire platform events
|
||||
Platform::poll();
|
||||
|
||||
// update
|
||||
ticks = Platform::getTicks();
|
||||
update(ticks - lastFrameTicks);
|
||||
lastFrameTicks = ticks;
|
||||
|
||||
// render
|
||||
render();
|
||||
|
||||
// swap buffers
|
||||
Platform::swapBuffers();
|
||||
}
|
||||
|
||||
lastFrameTicks = 0;
|
||||
m_stopping = false;
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
void Engine::stop()
|
||||
{
|
||||
m_stopping = true;
|
||||
}
|
||||
|
||||
void Engine::changeState(GameState* newState)
|
||||
{
|
||||
if(m_currentState)
|
||||
m_currentState->onLeave();
|
||||
m_currentState = newState;
|
||||
if(m_currentState)
|
||||
m_currentState->onEnter();
|
||||
}
|
||||
|
||||
void Engine::render()
|
||||
{
|
||||
g_graphics.beginRender();
|
||||
if(m_currentState)
|
||||
m_currentState->render();
|
||||
g_graphics.endRender();
|
||||
}
|
||||
|
||||
void Engine::update(int elapsedTicks)
|
||||
{
|
||||
if(m_currentState)
|
||||
m_currentState->update(elapsedTicks);
|
||||
}
|
||||
|
||||
void Engine::onClose()
|
||||
{
|
||||
if(m_currentState)
|
||||
m_currentState->onClose();
|
||||
}
|
||||
|
||||
void Engine::onResize(int width, int height)
|
||||
{
|
||||
g_graphics.resize(width, height);
|
||||
}
|
||||
|
||||
void Engine::onInputEvent(InputEvent *event)
|
||||
{
|
||||
if(m_currentState)
|
||||
m_currentState->onInputEvent(event);
|
||||
}
|
77
src/framework/engine.h
Normal file
77
src/framework/engine.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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 ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
struct InputEvent;
|
||||
|
||||
class GameState;
|
||||
|
||||
class Engine
|
||||
{
|
||||
public:
|
||||
Engine();
|
||||
~Engine();
|
||||
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
/// Main loop
|
||||
void run();
|
||||
|
||||
/// Stops main loop
|
||||
void stop();
|
||||
|
||||
/// Change current game state
|
||||
void changeState(GameState *newState);
|
||||
|
||||
bool isRunning() const { return m_running; }
|
||||
bool isStopping() const { return m_stopping; }
|
||||
|
||||
/// Fired by platform on window close
|
||||
void onClose();
|
||||
/// Fired by platform on window resize
|
||||
void onResize(int width, int height);
|
||||
/// Fired by platform on mouse/keyboard input
|
||||
void onInputEvent(InputEvent *event);
|
||||
|
||||
private:
|
||||
/// Called to render every frame
|
||||
void render();
|
||||
/// Called between renders
|
||||
void update(int elapsedTicks);
|
||||
|
||||
bool m_stopping;
|
||||
bool m_running;
|
||||
|
||||
GameState *m_currentState;
|
||||
};
|
||||
|
||||
extern Engine g_engine;
|
||||
|
||||
#endif // ENGINE_H
|
||||
|
133
src/framework/framebuffer.cpp
Normal file
133
src/framework/framebuffer.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "framebuffer.h"
|
||||
#include "platform.h"
|
||||
#include "graphics.h"
|
||||
|
||||
FrameBuffer::FrameBuffer(int width, int height)
|
||||
{
|
||||
m_fbo = 0;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
// create FBO texture
|
||||
glGenTextures(1, &m_fboTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// we want bilinear filtering (for a smooth framebuffer)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// use FBO ext only if supported
|
||||
if(Platform::isExtensionSupported("EXT_framebuffer_object")) {
|
||||
m_fallbackOldImp = false;
|
||||
|
||||
// generate FBO
|
||||
glGenFramebuffersEXT(1, &m_fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
|
||||
// attach 2D texture to this FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_fboTexture, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
//ok
|
||||
break;
|
||||
default: // fallback to old implementation
|
||||
m_fallbackOldImp = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// otherwise fallback to copy texture from screen implementation
|
||||
m_fallbackOldImp = true;
|
||||
}
|
||||
}
|
||||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
glDeleteTextures(1, &m_fboTexture);
|
||||
if(m_fbo)
|
||||
glDeleteFramebuffersEXT(1, &m_fbo);
|
||||
}
|
||||
|
||||
void FrameBuffer::bind()
|
||||
{
|
||||
if(!m_fallbackOldImp) {
|
||||
// bind framebuffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
}
|
||||
|
||||
// setup framebuffer viewport
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0.0f, m_width, 0, m_height);
|
||||
|
||||
// back to model view
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// clear framebuffer
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void FrameBuffer::unbind()
|
||||
{
|
||||
if(!m_fallbackOldImp) {
|
||||
// bind back buffer again
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
// restore graphics viewport
|
||||
g_graphics.restoreViewport();
|
||||
} else {
|
||||
// copy screen to texture
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||
|
||||
// restore graphics viewport
|
||||
g_graphics.restoreViewport();
|
||||
|
||||
// clear screen
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBuffer::draw(int x, int y, int width, int height)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
|
||||
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();
|
||||
}
|
53
src/framework/framebuffer.h
Normal file
53
src/framework/framebuffer.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 FRAMEBUFFER_H
|
||||
#define FRAMEBUFFER_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
class FrameBuffer
|
||||
{
|
||||
public:
|
||||
FrameBuffer(int width, int height);
|
||||
virtual ~FrameBuffer();
|
||||
|
||||
/// Bind the framebuffer, everything rendered will be draw on it
|
||||
void bind();
|
||||
|
||||
/// Unbind the framebuffer, render on back buffer again
|
||||
void unbind();
|
||||
|
||||
/// Draw framebuffer
|
||||
void draw(int x, int y, int width, int height);
|
||||
|
||||
private:
|
||||
GLuint m_fboTexture;
|
||||
GLuint m_fbo;
|
||||
bool m_fallbackOldImp;
|
||||
int m_width;
|
||||
int m_height;
|
||||
};
|
||||
|
||||
#endif // FRAMEBUFFER_H
|
46
src/framework/gamestate.h
Normal file
46
src/framework/gamestate.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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 GAMESTATE_H
|
||||
#define GAMESTATE_H
|
||||
|
||||
struct InputEvent;
|
||||
|
||||
class GameState
|
||||
{
|
||||
public:
|
||||
GameState() { }
|
||||
virtual ~GameState() { }
|
||||
|
||||
virtual void onEnter() = 0;
|
||||
virtual void onLeave() = 0;
|
||||
|
||||
virtual void onClose() = 0;
|
||||
virtual void onInputEvent(InputEvent *event) = 0;
|
||||
|
||||
virtual void render() = 0;
|
||||
virtual void update(int elapsedTicks) = 0;
|
||||
};
|
||||
|
||||
#endif // GAMESTATE_H
|
207
src/framework/graphics.cpp
Normal file
207
src/framework/graphics.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "graphics.h"
|
||||
#include "logger.h"
|
||||
#include "texture.h"
|
||||
|
||||
Graphics g_graphics;
|
||||
|
||||
Graphics::Graphics()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Graphics::init()
|
||||
{
|
||||
// setup opengl
|
||||
glEnable(GL_ALPHA_TEST); // enable alpha by default
|
||||
glAlphaFunc(GL_GREATER, 0.0f); // default alpha mode
|
||||
glDisable(GL_DEPTH_TEST); // we are rendering 2D only, we don't need it
|
||||
glEnable(GL_TEXTURE_2D); // enable textures by default
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
notice("GPU %s", (const char*)glGetString(GL_RENDERER));
|
||||
notice("OpenGL %s", (const char*)glGetString(GL_VERSION));
|
||||
}
|
||||
|
||||
void Graphics::terminate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Graphics::resize(int width, int height)
|
||||
{
|
||||
m_screenSize.setWidth(width);
|
||||
m_screenSize.setHeight(height);
|
||||
restoreViewport();
|
||||
}
|
||||
|
||||
void Graphics::restoreViewport()
|
||||
{
|
||||
const int& width = m_screenSize.width();
|
||||
const int& height = m_screenSize.height();
|
||||
|
||||
// resize gl viewport
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
/*
|
||||
0,0---------0,w
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
h,0---------h,w
|
||||
*/
|
||||
// setup view region like above
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0.0f, width, height, 0.0f);
|
||||
|
||||
// back to model view
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void Graphics::beginRender()
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
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 innerLineWidth)
|
||||
{
|
||||
if(2*innerLineWidth > 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+innerLineWidth);
|
||||
glVertex2i(right, top+innerLineWidth);
|
||||
glVertex2i(right, top);
|
||||
|
||||
// left
|
||||
glVertex2i(left, screenCoords.top()+innerLineWidth);
|
||||
glVertex2i(left, bottom-innerLineWidth);
|
||||
glVertex2i(left+innerLineWidth, bottom-innerLineWidth);
|
||||
glVertex2i(left+innerLineWidth, screenCoords.top()+innerLineWidth);
|
||||
|
||||
// bottom line
|
||||
glVertex2i(left, bottom);
|
||||
glVertex2i(left, bottom-innerLineWidth);
|
||||
glVertex2i(right, bottom-innerLineWidth);
|
||||
glVertex2i(right, bottom);
|
||||
|
||||
// right line
|
||||
glVertex2i(right, top+innerLineWidth);
|
||||
glVertex2i(right, bottom-innerLineWidth);
|
||||
glVertex2i(right-innerLineWidth, bottom-innerLineWidth);
|
||||
glVertex2i(right-innerLineWidth, top+innerLineWidth);
|
||||
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
68
src/framework/graphics.h
Normal file
68
src/framework/graphics.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 GRAPHICS_H
|
||||
#define GRAPHICS_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
#include "rect.h"
|
||||
#include "size.h"
|
||||
#include "color.h"
|
||||
|
||||
class Texture;
|
||||
|
||||
class Graphics
|
||||
{
|
||||
public:
|
||||
Graphics();
|
||||
~Graphics();
|
||||
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
/// Called after every window resize
|
||||
void resize(int width, int height);
|
||||
|
||||
/// Restore original viewport
|
||||
void restoreViewport();
|
||||
|
||||
/// Called before every render
|
||||
void beginRender();
|
||||
|
||||
/// Called after every render
|
||||
void endRender();
|
||||
|
||||
const Size& getScreenSize() const { return m_screenSize; }
|
||||
|
||||
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 innerLineWidth);
|
||||
|
||||
private:
|
||||
Size m_screenSize;
|
||||
};
|
||||
|
||||
extern Graphics g_graphics;
|
||||
|
||||
#endif // GRAPHICS_H
|
211
src/framework/input.h
Normal file
211
src/framework/input.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/* 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 INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
enum EKeyCode {
|
||||
KC_UNKNOWN = 0x00,
|
||||
KC_ESCAPE = 0x01,
|
||||
KC_1 = 0x02,
|
||||
KC_2 = 0x03,
|
||||
KC_3 = 0x04,
|
||||
KC_4 = 0x05,
|
||||
KC_5 = 0x06,
|
||||
KC_6 = 0x07,
|
||||
KC_7 = 0x08,
|
||||
KC_8 = 0x09,
|
||||
KC_9 = 0x0A,
|
||||
KC_0 = 0x0B,
|
||||
KC_MINUS = 0x0C, // - on main keyboard
|
||||
KC_EQUALS = 0x0D,
|
||||
KC_BACK = 0x0E, // backspace
|
||||
KC_TAB = 0x0F,
|
||||
KC_Q = 0x10,
|
||||
KC_W = 0x11,
|
||||
KC_E = 0x12,
|
||||
KC_R = 0x13,
|
||||
KC_T = 0x14,
|
||||
KC_Y = 0x15,
|
||||
KC_U = 0x16,
|
||||
KC_I = 0x17,
|
||||
KC_O = 0x18,
|
||||
KC_P = 0x19,
|
||||
KC_LBRACKET = 0x1A,
|
||||
KC_RBRACKET = 0x1B,
|
||||
KC_RETURN = 0x1C, // Enter on main keyboard
|
||||
KC_LCONTROL = 0x1D,
|
||||
KC_A = 0x1E,
|
||||
KC_S = 0x1F,
|
||||
KC_D = 0x20,
|
||||
KC_F = 0x21,
|
||||
KC_G = 0x22,
|
||||
KC_H = 0x23,
|
||||
KC_J = 0x24,
|
||||
KC_K = 0x25,
|
||||
KC_L = 0x26,
|
||||
KC_SEMICOLON = 0x27,
|
||||
KC_APOSTROPHE = 0x28,
|
||||
KC_GRAVE = 0x29, // accent
|
||||
KC_LSHIFT = 0x2A,
|
||||
KC_BACKSLASH = 0x2B,
|
||||
KC_Z = 0x2C,
|
||||
KC_X = 0x2D,
|
||||
KC_C = 0x2E,
|
||||
KC_V = 0x2F,
|
||||
KC_B = 0x30,
|
||||
KC_N = 0x31,
|
||||
KC_M = 0x32,
|
||||
KC_COMMA = 0x33,
|
||||
KC_PERIOD = 0x34, // . on main keyboard
|
||||
KC_SLASH = 0x35, // / on main keyboard
|
||||
KC_RSHIFT = 0x36,
|
||||
KC_MULTIPLY = 0x37, // * on numeric keypad
|
||||
KC_LALT = 0x38, // left Alt
|
||||
KC_SPACE = 0x39,
|
||||
KC_CAPITAL = 0x3A,
|
||||
KC_F1 = 0x3B,
|
||||
KC_F2 = 0x3C,
|
||||
KC_F3 = 0x3D,
|
||||
KC_F4 = 0x3E,
|
||||
KC_F5 = 0x3F,
|
||||
KC_F6 = 0x40,
|
||||
KC_F7 = 0x41,
|
||||
KC_F8 = 0x42,
|
||||
KC_F9 = 0x43,
|
||||
KC_F10 = 0x44,
|
||||
KC_NUMLOCK = 0x45,
|
||||
KC_SCROLL = 0x46, // Scroll Lock
|
||||
KC_NUMPAD7 = 0x47,
|
||||
KC_NUMPAD8 = 0x48,
|
||||
KC_NUMPAD9 = 0x49,
|
||||
KC_SUBTRACT = 0x4A, // - on numeric keypad
|
||||
KC_NUMPAD4 = 0x4B,
|
||||
KC_NUMPAD5 = 0x4C,
|
||||
KC_NUMPAD6 = 0x4D,
|
||||
KC_ADD = 0x4E, // + on numeric keypad
|
||||
KC_NUMPAD1 = 0x4F,
|
||||
KC_NUMPAD2 = 0x50,
|
||||
KC_NUMPAD3 = 0x51,
|
||||
KC_NUMPAD0 = 0x52,
|
||||
KC_DECIMAL = 0x53, // . on numeric keypad
|
||||
KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards
|
||||
KC_F11 = 0x57,
|
||||
KC_F12 = 0x58,
|
||||
KC_F13 = 0x64, // (NEC PC98)
|
||||
KC_F14 = 0x65, // (NEC PC98)
|
||||
KC_F15 = 0x66, // (NEC PC98)
|
||||
KC_KANA = 0x70, // (Japanese keyboard)
|
||||
KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards
|
||||
KC_CONVERT = 0x79, // (Japanese keyboard)
|
||||
KC_NOCONVERT = 0x7B, // (Japanese keyboard)
|
||||
KC_YEN = 0x7D, // (Japanese keyboard)
|
||||
KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards
|
||||
KC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98)
|
||||
KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
|
||||
KC_AT = 0x91, // (NEC PC98)
|
||||
KC_COLON = 0x92, // (NEC PC98)
|
||||
KC_UNDERLINE = 0x93, // (NEC PC98)
|
||||
KC_KANJI = 0x94, // (Japanese keyboard)
|
||||
KC_STOP = 0x95, // (NEC PC98)
|
||||
KC_AX = 0x96, // (Japan AX)
|
||||
KC_UNLABELED = 0x97, // (J3100)
|
||||
KC_NEXTTRACK = 0x99, // Next Track
|
||||
KC_NUMPADENTER = 0x9C, // Enter on numeric keypad
|
||||
KC_RCONTROL = 0x9D,
|
||||
KC_MUTE = 0xA0, // Mute
|
||||
KC_CALCULATOR = 0xA1, // Calculator
|
||||
KC_PLAYPAUSE = 0xA2, // Play / Pause
|
||||
KC_MEDIASTOP = 0xA4, // Media Stop
|
||||
KC_VOLUMEDOWN = 0xAE, // Volume -
|
||||
KC_VOLUMEUP = 0xB0, // Volume +
|
||||
KC_WEBHOME = 0xB2, // Web home
|
||||
KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98)
|
||||
KC_DIVIDE = 0xB5, // / on numeric keypad
|
||||
KC_SYSRQ = 0xB7,
|
||||
KC_RALT = 0xB8, // right Alt
|
||||
KC_PAUSE = 0xC5, // Pause
|
||||
KC_HOME = 0xC7, // Home on arrow keypad
|
||||
KC_UP = 0xC8, // UpArrow on arrow keypad
|
||||
KC_PGUP = 0xC9, // PgUp on arrow keypad
|
||||
KC_LEFT = 0xCB, // LeftArrow on arrow keypad
|
||||
KC_RIGHT = 0xCD, // RightArrow on arrow keypad
|
||||
KC_END = 0xCF, // End on arrow keypad
|
||||
KC_DOWN = 0xD0, // DownArrow on arrow keypad
|
||||
KC_PGDOWN = 0xD1, // PgDn on arrow keypad
|
||||
KC_INSERT = 0xD2, // Insert on arrow keypad
|
||||
KC_DELETE = 0xD3, // Delete on arrow keypad
|
||||
KC_LWIN = 0xDB, // Left Windows key
|
||||
KC_RWIN = 0xDC, // Right Windows key
|
||||
KC_APPS = 0xDD, // AppMenu key
|
||||
KC_POWER = 0xDE, // System Power
|
||||
KC_SLEEP = 0xDF, // System Sleep
|
||||
KC_WAKE = 0xE3, // System Wake
|
||||
KC_WEBSEARCH = 0xE5, // Web Search
|
||||
KC_WEBFAVORITES= 0xE6, // Web Favorites
|
||||
KC_WEBREFRESH = 0xE7, // Web Refresh
|
||||
KC_WEBSTOP = 0xE8, // Web Stop
|
||||
KC_WEBFORWARD = 0xE9, // Web Forward
|
||||
KC_WEBBACK = 0xEA, // Web Back
|
||||
KC_MYCOMPUTER = 0xEB, // My Computer
|
||||
KC_MAIL = 0xEC, // Mail
|
||||
KC_MEDIASELECT = 0xED // Media Select
|
||||
};
|
||||
|
||||
enum EEvent {
|
||||
EV_KEY_DOWN = 0,
|
||||
EV_KEY_UP,
|
||||
EV_TEXT_ENTER,
|
||||
EV_MOUSE_LDOWN,
|
||||
EV_MOUSE_LUP,
|
||||
EV_MOUSE_MDOWN,
|
||||
EV_MOUSE_MUP,
|
||||
EV_MOUSE_RDOWN,
|
||||
EV_MOUSE_RUP,
|
||||
EV_MOUSE_WHEEL_UP,
|
||||
EV_MOUSE_WHEEL_DOWN,
|
||||
EV_MOUSE_MOVE
|
||||
};
|
||||
|
||||
struct KeyEvent {
|
||||
char keychar;
|
||||
unsigned char keycode;
|
||||
bool ctrl;
|
||||
bool shift;
|
||||
bool alt;
|
||||
};
|
||||
|
||||
struct MouseEvent {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct InputEvent {
|
||||
EEvent type;
|
||||
union {
|
||||
KeyEvent key;
|
||||
MouseEvent mouse;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // INPUT_H
|
66
src/framework/logger.cpp
Normal file
66
src/framework/logger.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
void Logger::log(int level, const char *trace, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
std::string strace;
|
||||
|
||||
va_start(args, format);
|
||||
std::string text = vformat(format, args);
|
||||
va_end(args);
|
||||
|
||||
if(trace) {
|
||||
strace = trace;
|
||||
strace = strace.substr(0, strace.find_first_of('('));
|
||||
if(strace.find_last_of(' ') != std::string::npos)
|
||||
strace = strace.substr(strace.find_last_of(' ') + 1);
|
||||
}
|
||||
|
||||
#ifdef linux
|
||||
static char const *colors[] = { "\033[01;31m ", "\033[01;31m", "\033[01;33m", "\033[0;32m", "\033[01;34m" };
|
||||
static bool colored = getenv("COLORED_OUTPUT");
|
||||
if(colored)
|
||||
std::cout << colors[level];
|
||||
#endif
|
||||
|
||||
if(!strace.empty())
|
||||
std::cout << "[" << strace << "] ";
|
||||
|
||||
static char const *prefixes[] = { "FATAL ERROR: ", "ERROR: ", "WARNING: ", "", "", "" };
|
||||
std::cout << prefixes[level];
|
||||
std::cout << text;
|
||||
|
||||
#ifdef linux
|
||||
if(colored)
|
||||
std::cout << "\033[0m";
|
||||
#endif
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
if(level == LFATAL)
|
||||
exit(-1);
|
||||
}
|
64
src/framework/logger.h
Normal file
64
src/framework/logger.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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 LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
namespace Logger {
|
||||
|
||||
enum ELogLevel {
|
||||
LFATAL = 0,
|
||||
LERROR,
|
||||
LWARNING,
|
||||
LNOTICE,
|
||||
LDEBUG
|
||||
};
|
||||
|
||||
void log(int level, const char *trace, const char *format, ...);
|
||||
|
||||
}
|
||||
|
||||
#define fatal(...) Logger::log(Logger::LFATAL, NULL, __VA_ARGS__)
|
||||
#define error(...) Logger::log(Logger::LERROR, NULL, __VA_ARGS__)
|
||||
#define warning(...) Logger::log(Logger::LWARNING, NULL, __VA_ARGS__)
|
||||
#define debug(...) Logger::log(Logger::LDEBUG, NULL, __VA_ARGS__)
|
||||
#define notice(...) Logger::log(Logger::LNOTICE, NULL, __VA_ARGS__)
|
||||
|
||||
#define trace() Logger::log(Logger::LDEBUG, __PRETTY_FUNCTION__, "")
|
||||
#define tdebug(...) Logger::log(Logger::LDEBUG, __PRETTY_FUNCTION__, __VA_ARGS__)
|
||||
|
||||
struct Dump {
|
||||
public:
|
||||
Dump() { }
|
||||
~Dump() { debug(m_buf.str().c_str()); }
|
||||
template<class T> Dump &operator<<(const T &x) { m_buf << x << " "; return *this; }
|
||||
private:
|
||||
std::ostringstream m_buf;
|
||||
};
|
||||
|
||||
#define dump() Dump()
|
||||
|
||||
#endif
|
72
src/framework/platform.h
Normal file
72
src/framework/platform.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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 PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
/// Poll platform input/window events
|
||||
void poll();
|
||||
|
||||
/// Get current time in milliseconds since first frame render
|
||||
unsigned long getTicks();
|
||||
/// Sleep in current thread
|
||||
void sleep(unsigned long miliseconds);
|
||||
|
||||
bool createWindow(int width, int height, int minWidth, int minHeight);
|
||||
void destroyWindow();
|
||||
void showWindow();
|
||||
void setWindowTitle(const char *title);
|
||||
bool isWindowFocused();
|
||||
bool isWindowVisible();
|
||||
int getWindowWidth();
|
||||
int getWindowHeight();
|
||||
|
||||
/// Get GL extension function address
|
||||
void *getExtensionProcAddress(const char *ext);
|
||||
/// Check if GL extension is supported
|
||||
bool isExtensionSupported(const char *ext);
|
||||
|
||||
const char *getTextFromClipboard();
|
||||
void copyToClipboard(const char *text);
|
||||
|
||||
void hideMouseCursor();
|
||||
void showMouseCursor();
|
||||
|
||||
/// Enable/disable vertical synchronization
|
||||
void setVsync(bool enable = true);
|
||||
/// Swap GL buffers
|
||||
void swapBuffers();
|
||||
|
||||
/// Get the app user directory, the place to save files configurations files
|
||||
const char *getAppUserDir();
|
||||
}
|
||||
|
||||
#endif // PLATFORM_H
|
80
src/framework/point.h
Normal file
80
src/framework/point.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* 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 T manhattanLength() const { return std::abs(x) + std::abs(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
|
95
src/framework/prerequisites.h
Normal file
95
src/framework/prerequisites.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* 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 PREREQUISITES_H
|
||||
#define PREREQUISITES_H
|
||||
|
||||
// app name and version
|
||||
#define APP_NAME "OTClient"
|
||||
#define APP_LONGNAME APP_NAME " " APP_VERSION
|
||||
#define APP_VERSION "0.1.0"
|
||||
|
||||
// easy typing
|
||||
#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 <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <csignal>
|
||||
|
||||
// STL headers
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <tr1/cinttypes>
|
||||
|
||||
// additional string algorithms
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
// easy casting
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
// smart pointers
|
||||
#include <boost/smart_ptr.hpp>
|
||||
|
||||
// foreach
|
||||
#include <boost/foreach.hpp>
|
||||
#define foreach BOOST_FOREACH
|
||||
|
||||
// GL stuff
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
// internal logger
|
||||
#include "logger.h"
|
||||
|
||||
// additional utilities
|
||||
#include "util.h"
|
||||
|
||||
#endif // PREREQUISITES_H
|
284
src/framework/rect.h
Normal file
284
src/framework/rect.h
Normal 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
|
118
src/framework/resourcemanager.cpp
Normal file
118
src/framework/resourcemanager.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "resourcemanager.h"
|
||||
|
||||
#include <physfs.h>
|
||||
|
||||
ResourceManager g_resources;
|
||||
|
||||
ResourceManager::ResourceManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ResourceManager::~ResourceManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ResourceManager::init(const char *argv0)
|
||||
{
|
||||
PHYSFS_init(argv0);
|
||||
}
|
||||
|
||||
void ResourceManager::terminate()
|
||||
{
|
||||
PHYSFS_deinit();
|
||||
}
|
||||
|
||||
bool ResourceManager::setWriteDir(const std::string& path)
|
||||
{
|
||||
bool ret = (bool)PHYSFS_setWriteDir(path.c_str());
|
||||
|
||||
if(!ret)
|
||||
error("Could not set the path %s as write directory, file write will not work.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ResourceManager::addToSearchPath(const std::string& path, bool insertInFront)
|
||||
{
|
||||
if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1)) {
|
||||
error("Error while adding %s to resources search path: %s", PHYSFS_getLastError());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceManager::fileExists(const std::string& filePath)
|
||||
{
|
||||
return PHYSFS_exists(filePath.c_str());
|
||||
}
|
||||
|
||||
unsigned char *ResourceManager::loadFile(const std::string& fileName, unsigned int *fileSize)
|
||||
{
|
||||
PHYSFS_file *file = PHYSFS_openRead(fileName.c_str());
|
||||
if(!file) {
|
||||
error("Failed to load file %s: %s", fileName.c_str(), PHYSFS_getLastError());
|
||||
*fileSize = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*fileSize = PHYSFS_fileLength(file);
|
||||
unsigned char *buffer = new unsigned char[*fileSize];
|
||||
PHYSFS_read(file, (void*)buffer, 1, *fileSize);
|
||||
PHYSFS_close(file);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::string ResourceManager::loadTextFile(const std::string& fileName)
|
||||
{
|
||||
std::string text;
|
||||
unsigned int fileSize;
|
||||
char *buffer = (char *)loadFile(fileName, &fileSize);
|
||||
if(buffer) {
|
||||
text.assign(buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
bool ResourceManager::saveFile(const std::string &fileName, const unsigned char *data, unsigned int size)
|
||||
{
|
||||
PHYSFS_file *file = PHYSFS_openWrite(fileName.c_str());
|
||||
if(!file) {
|
||||
error("Failed to save file %s: %s", fileName.c_str(), PHYSFS_getLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
PHYSFS_write(file, (void*)data, size, 1);
|
||||
PHYSFS_close(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceManager::saveTextFile(const std::string &fileName, std::string text)
|
||||
{
|
||||
return saveFile(fileName, (const unsigned char*)text.c_str(), text.size());
|
||||
}
|
70
src/framework/resourcemanager.h
Normal file
70
src/framework/resourcemanager.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* 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 RESOURCEMANAGER_H
|
||||
#define RESOURCEMANAGER_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
public:
|
||||
ResourceManager();
|
||||
~ResourceManager();
|
||||
|
||||
void init(const char *argv0);
|
||||
void terminate();
|
||||
|
||||
/// Sets the write directory
|
||||
bool setWriteDir(const std::string &path);
|
||||
|
||||
/// Adds a directory or zip archive to the search path
|
||||
bool addToSearchPath(const std::string& path, bool insertInFront = true);
|
||||
|
||||
/// Checks whether the given file exists in the search path
|
||||
bool fileExists(const std::string& filePath);
|
||||
|
||||
/// Searches for zip files and adds them to the search path
|
||||
void searchAndAddArchives(const std::string &path,
|
||||
const std::string &ext,
|
||||
const bool append);
|
||||
|
||||
/** Load a file by allocating a buffer and filling it with the file contents
|
||||
* where fileSize will be set to the file size.
|
||||
* The returned buffer must be freed with delete[]. */
|
||||
unsigned char *loadFile(const std::string &fileName, unsigned int *fileSize);
|
||||
|
||||
/// Loads a text file into a std::string
|
||||
std::string loadTextFile(const std::string &fileName);
|
||||
|
||||
/// Save a file into write directory
|
||||
bool saveFile(const std::string &fileName, const unsigned char *data, unsigned int size);
|
||||
|
||||
/// Save a text file into write directory
|
||||
bool saveTextFile(const std::string &fileName, std::string text);
|
||||
};
|
||||
|
||||
extern ResourceManager g_resources;
|
||||
|
||||
#endif // RESOURCEMANAGER_H
|
113
src/framework/size.h
Normal file
113
src/framework/size.h
Normal 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
|
71
src/framework/texture.cpp
Normal file
71
src/framework/texture.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
Texture::Texture(int width, int height, int components, unsigned char *pixels)
|
||||
{
|
||||
m_size.setWidth(width);
|
||||
m_size.setHeight(height);
|
||||
|
||||
glGenTextures(1, &m_textureId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||
|
||||
GLenum format = 0;
|
||||
switch(components) {
|
||||
case 4:
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
case 3:
|
||||
format = GL_RGB;
|
||||
break;
|
||||
case 2:
|
||||
format = GL_LUMINANCE_ALPHA;
|
||||
break;
|
||||
case 1:
|
||||
format = GL_LUMINANCE;
|
||||
break;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
if(m_textureId)
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
}
|
||||
|
||||
void Texture::enableBilinearFilter()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
53
src/framework/texture.h
Normal file
53
src/framework/texture.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 TEXTURE_H
|
||||
#define TEXTURE_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
#include "size.h"
|
||||
|
||||
class TextureManager;
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
/// Create a texture, width and height must be a multiple of 2
|
||||
Texture(int width, int height, int components, unsigned char *pixels = NULL);
|
||||
virtual ~Texture();
|
||||
|
||||
/// Enable texture bilinear filter (smooth scaled textures)
|
||||
void enableBilinearFilter();
|
||||
|
||||
const Size& getSize() const { return m_size; }
|
||||
GLuint getTextureId() const { return m_textureId; }
|
||||
|
||||
private:
|
||||
GLuint m_textureId;
|
||||
Size m_size;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<Texture> TexturePtr;
|
||||
|
||||
#endif // TEXTURE_H
|
124
src/framework/textureloader.cpp
Normal file
124
src/framework/textureloader.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "textureloader.h"
|
||||
#include "texture.h"
|
||||
|
||||
#include <png.h>
|
||||
|
||||
Texture *TextureLoader::loadPNG(const unsigned char *fileData, unsigned int fileSize)
|
||||
{
|
||||
FILE *pngFile = fmemopen((void*)fileData, fileSize, "rb");
|
||||
|
||||
if(!pngFile)
|
||||
return NULL;
|
||||
|
||||
png_byte sig[8];
|
||||
if(!fread(&sig, 8, 1, pngFile))
|
||||
return NULL;
|
||||
|
||||
if(png_sig_cmp(sig, 0, 8))
|
||||
return NULL;
|
||||
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if(!png_ptr)
|
||||
return NULL;
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if(!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, pngFile);
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
int bitDepth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
int colourType = png_get_color_type(png_ptr, info_ptr);
|
||||
|
||||
if(colourType == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_palette_to_rgb(png_ptr);
|
||||
|
||||
if(bitDepth < 8 && (colourType == PNG_COLOR_TYPE_GRAY || colourType == PNG_COLOR_TYPE_GRAY_ALPHA))
|
||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||
|
||||
if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
|
||||
if(bitDepth < 8)
|
||||
png_set_packing(png_ptr);
|
||||
else if(bitDepth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
png_uint_32 width, height;
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colourType, NULL, NULL, NULL);
|
||||
|
||||
int components;
|
||||
switch(colourType)
|
||||
{
|
||||
case PNG_COLOR_TYPE_GRAY:
|
||||
components = 1;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||
components = 2;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
components = 3;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
components = 4;
|
||||
break;
|
||||
default:
|
||||
if(png_ptr)
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
unsigned char *pixels = new unsigned char[width * height * components];
|
||||
|
||||
png_bytep *row_pointers = new png_bytep[height];
|
||||
for(unsigned int i = 0; i < height; ++i)
|
||||
row_pointers[i] = (png_bytep)(pixels + (i * width * components));
|
||||
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
png_read_end(png_ptr, NULL);
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(pngFile);
|
||||
delete[] row_pointers;
|
||||
|
||||
Texture *texture = new Texture(width, height, components, pixels);
|
||||
|
||||
delete[] pixels;
|
||||
|
||||
return texture;
|
||||
}
|
38
src/framework/textureloader.h
Normal file
38
src/framework/textureloader.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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 TEXTURELOADER_H
|
||||
#define TEXTURELOADER_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
class Texture;
|
||||
|
||||
namespace TextureLoader
|
||||
{
|
||||
/// Load a png textures using libpng
|
||||
Texture *loadPNG(const unsigned char *fileData, unsigned int fileSize);
|
||||
}
|
||||
|
||||
#endif // TEXTURELOADER_H
|
68
src/framework/texturemanager.cpp
Normal file
68
src/framework/texturemanager.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "texturemanager.h"
|
||||
#include "resourcemanager.h"
|
||||
#include "textureloader.h"
|
||||
|
||||
TextureManager g_textures;
|
||||
|
||||
TextureManager::TextureManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TextureManager::~TextureManager()
|
||||
{
|
||||
m_texturesMap.clear();
|
||||
}
|
||||
|
||||
TexturePtr TextureManager::get(const std::string& textureFile)
|
||||
{
|
||||
TexturePtr texture;
|
||||
|
||||
// check if the texture is already loaded
|
||||
TexturesMap::iterator it = m_texturesMap.find(textureFile);
|
||||
if(it != m_texturesMap.end())
|
||||
texture = it->second;
|
||||
else { // load texture
|
||||
// currently only png textures are supported
|
||||
if(!boost::ends_with(textureFile, ".png")) {
|
||||
error("Unable to load texture %s, file format no supported.", textureFile.c_str());
|
||||
return texture;
|
||||
}
|
||||
|
||||
unsigned int fileSize;
|
||||
unsigned char *textureFileData = g_resources.loadFile(textureFile, &fileSize);
|
||||
if(!textureFileData)
|
||||
return texture;
|
||||
|
||||
texture = TexturePtr(TextureLoader::loadPNG(textureFileData, fileSize));
|
||||
if(!texture)
|
||||
error("Unable to load texture %s, loading error.", textureFile.c_str());
|
||||
delete[] textureFileData;
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
47
src/framework/texturemanager.h
Normal file
47
src/framework/texturemanager.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 TEXTUREMANAGER_H
|
||||
#define TEXTUREMANAGER_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
#include "texture.h"
|
||||
|
||||
class TextureManager
|
||||
{
|
||||
public:
|
||||
TextureManager();
|
||||
~TextureManager();
|
||||
|
||||
/// Load a texture from file, if it was already loaded it will be retrieved from cache
|
||||
TexturePtr get(const std::string& textureFile);
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, TexturePtr> TexturesMap;
|
||||
TexturesMap m_texturesMap;
|
||||
};
|
||||
|
||||
extern TextureManager g_textures;
|
||||
|
||||
#endif // TEXTUREMANAGER_H
|
52
src/framework/util.cpp
Normal file
52
src/framework/util.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "util.h"
|
||||
|
||||
std::string vformat(const char *format, va_list args)
|
||||
{
|
||||
if(!format)
|
||||
return "";
|
||||
int result = -1, length = 256;
|
||||
char *buffer = 0;
|
||||
while(result == -1) {
|
||||
if(buffer)
|
||||
delete [] buffer;
|
||||
buffer = new char [length + 1];
|
||||
result = vsnprintf(buffer, length, format, args);
|
||||
length *= 2;
|
||||
}
|
||||
std::string s(buffer);
|
||||
delete [] buffer;
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string format(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
std::string s = vformat(format, args);
|
||||
va_end(args);
|
||||
return s;
|
||||
}
|
36
src/framework/util.h
Normal file
36
src/framework/util.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* 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 UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include "prerequisites.h"
|
||||
|
||||
/// Formatting like printf for std::string, va_list input version
|
||||
std::string vformat(const char *format, va_list args);
|
||||
|
||||
/// Formatting like printf for std::string
|
||||
std::string format(const char *format, ...);
|
||||
|
||||
#endif
|
727
src/framework/x11platform.cpp
Normal file
727
src/framework/x11platform.cpp
Normal file
@@ -0,0 +1,727 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
#include "engine.h"
|
||||
#include "input.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <GL/glx.h>
|
||||
#include <physfs.h>
|
||||
|
||||
struct X11PlatformPrivate {
|
||||
Display *display;
|
||||
XVisualInfo *visual;
|
||||
GLXContext glxContext;
|
||||
XIM xim;
|
||||
XIC xic;
|
||||
Colormap colormap;
|
||||
Window window;
|
||||
Cursor cursor;
|
||||
Atom atomDeleteWindow;
|
||||
Atom atomClipboard;
|
||||
Atom atomTargets;
|
||||
Atom atomText;
|
||||
Atom atomCompoundText;
|
||||
Atom atomUTF8String;
|
||||
bool visible;
|
||||
bool focused;
|
||||
int width;
|
||||
int height;
|
||||
std::string clipboardText;
|
||||
std::map<int, unsigned char> keyMap;
|
||||
} x11;
|
||||
|
||||
void Platform::init()
|
||||
{
|
||||
x11.display = NULL;
|
||||
x11.visual = NULL;
|
||||
x11.glxContext = NULL;
|
||||
x11.xim = NULL;
|
||||
x11.xic = NULL;
|
||||
x11.colormap = None;
|
||||
x11.window = None;
|
||||
x11.cursor = None;
|
||||
x11.visible = false;
|
||||
x11.focused = false;
|
||||
x11.width = 0;
|
||||
x11.height = 0;
|
||||
|
||||
// setup keymap
|
||||
x11.keyMap[XK_1] = KC_1;
|
||||
x11.keyMap[XK_2] = KC_2;
|
||||
x11.keyMap[XK_3] = KC_3;
|
||||
x11.keyMap[XK_4] = KC_4;
|
||||
x11.keyMap[XK_5] = KC_5;
|
||||
x11.keyMap[XK_6] = KC_6;
|
||||
x11.keyMap[XK_7] = KC_7;
|
||||
x11.keyMap[XK_8] = KC_8;
|
||||
x11.keyMap[XK_9] = KC_9;
|
||||
x11.keyMap[XK_0] = KC_0;
|
||||
|
||||
x11.keyMap[XK_BackSpace] = KC_BACK;
|
||||
|
||||
x11.keyMap[XK_minus] = KC_MINUS;
|
||||
x11.keyMap[XK_equal] = KC_EQUALS;
|
||||
x11.keyMap[XK_space] = KC_SPACE;
|
||||
x11.keyMap[XK_comma] = KC_COMMA;
|
||||
x11.keyMap[XK_period] = KC_PERIOD;
|
||||
|
||||
x11.keyMap[XK_backslash] = KC_BACKSLASH;
|
||||
x11.keyMap[XK_slash] = KC_SLASH;
|
||||
x11.keyMap[XK_bracketleft] = KC_LBRACKET;
|
||||
x11.keyMap[XK_bracketright] = KC_RBRACKET;
|
||||
|
||||
x11.keyMap[XK_Escape] = KC_ESCAPE;
|
||||
x11.keyMap[XK_Caps_Lock] = KC_CAPITAL;
|
||||
|
||||
x11.keyMap[XK_Tab] = KC_TAB;
|
||||
x11.keyMap[XK_Return] = KC_RETURN;
|
||||
x11.keyMap[XK_Control_L] = KC_LCONTROL;
|
||||
x11.keyMap[XK_Control_R] = KC_RCONTROL;
|
||||
|
||||
x11.keyMap[XK_colon] = KC_COLON;
|
||||
x11.keyMap[XK_semicolon] = KC_SEMICOLON;
|
||||
x11.keyMap[XK_apostrophe] = KC_APOSTROPHE;
|
||||
x11.keyMap[XK_grave] = KC_GRAVE;
|
||||
|
||||
x11.keyMap[XK_b] = KC_B;
|
||||
x11.keyMap[XK_a] = KC_A;
|
||||
x11.keyMap[XK_c] = KC_C;
|
||||
x11.keyMap[XK_d] = KC_D;
|
||||
x11.keyMap[XK_e] = KC_E;
|
||||
x11.keyMap[XK_f] = KC_F;
|
||||
x11.keyMap[XK_g] = KC_G;
|
||||
x11.keyMap[XK_h] = KC_H;
|
||||
x11.keyMap[XK_i] = KC_I;
|
||||
x11.keyMap[XK_j] = KC_J;
|
||||
x11.keyMap[XK_k] = KC_K;
|
||||
x11.keyMap[XK_l] = KC_L;
|
||||
x11.keyMap[XK_m] = KC_M;
|
||||
x11.keyMap[XK_n] = KC_N;
|
||||
x11.keyMap[XK_o] = KC_O;
|
||||
x11.keyMap[XK_p] = KC_P;
|
||||
x11.keyMap[XK_q] = KC_Q;
|
||||
x11.keyMap[XK_r] = KC_R;
|
||||
x11.keyMap[XK_s] = KC_S;
|
||||
x11.keyMap[XK_t] = KC_T;
|
||||
x11.keyMap[XK_u] = KC_U;
|
||||
x11.keyMap[XK_v] = KC_V;
|
||||
x11.keyMap[XK_w] = KC_W;
|
||||
x11.keyMap[XK_x] = KC_X;
|
||||
x11.keyMap[XK_y] = KC_Y;
|
||||
x11.keyMap[XK_z] = KC_Z;
|
||||
|
||||
x11.keyMap[XK_F1] = KC_F1;
|
||||
x11.keyMap[XK_F2] = KC_F2;
|
||||
x11.keyMap[XK_F3] = KC_F3;
|
||||
x11.keyMap[XK_F4] = KC_F4;
|
||||
x11.keyMap[XK_F5] = KC_F5;
|
||||
x11.keyMap[XK_F6] = KC_F6;
|
||||
x11.keyMap[XK_F7] = KC_F7;
|
||||
x11.keyMap[XK_F8] = KC_F8;
|
||||
x11.keyMap[XK_F9] = KC_F9;
|
||||
x11.keyMap[XK_F10] = KC_F10;
|
||||
x11.keyMap[XK_F11] = KC_F11;
|
||||
x11.keyMap[XK_F12] = KC_F12;
|
||||
x11.keyMap[XK_F13] = KC_F13;
|
||||
x11.keyMap[XK_F14] = KC_F14;
|
||||
x11.keyMap[XK_F15] = KC_F15;
|
||||
|
||||
// keypad
|
||||
x11.keyMap[XK_KP_0] = KC_NUMPAD0;
|
||||
x11.keyMap[XK_KP_1] = KC_NUMPAD1;
|
||||
x11.keyMap[XK_KP_2] = KC_NUMPAD2;
|
||||
x11.keyMap[XK_KP_3] = KC_NUMPAD3;
|
||||
x11.keyMap[XK_KP_4] = KC_NUMPAD4;
|
||||
x11.keyMap[XK_KP_5] = KC_NUMPAD5;
|
||||
x11.keyMap[XK_KP_6] = KC_NUMPAD6;
|
||||
x11.keyMap[XK_KP_7] = KC_NUMPAD7;
|
||||
x11.keyMap[XK_KP_8] = KC_NUMPAD8;
|
||||
x11.keyMap[XK_KP_9] = KC_NUMPAD9;
|
||||
x11.keyMap[XK_KP_Add] = KC_ADD;
|
||||
x11.keyMap[XK_KP_Subtract] = KC_SUBTRACT;
|
||||
x11.keyMap[XK_KP_Decimal] = KC_DECIMAL;
|
||||
x11.keyMap[XK_KP_Equal] = KC_NUMPADEQUALS;
|
||||
x11.keyMap[XK_KP_Divide] = KC_DIVIDE;
|
||||
x11.keyMap[XK_KP_Multiply] = KC_MULTIPLY;
|
||||
x11.keyMap[XK_KP_Enter] = KC_NUMPADENTER;
|
||||
|
||||
// keypad with numlock off
|
||||
x11.keyMap[XK_KP_Home] = KC_NUMPAD7;
|
||||
x11.keyMap[XK_KP_Up] = KC_NUMPAD8;
|
||||
x11.keyMap[XK_KP_Page_Up] = KC_NUMPAD9;
|
||||
x11.keyMap[XK_KP_Left] = KC_NUMPAD4;
|
||||
x11.keyMap[XK_KP_Begin] = KC_NUMPAD5;
|
||||
x11.keyMap[XK_KP_Right] = KC_NUMPAD6;
|
||||
x11.keyMap[XK_KP_End] = KC_NUMPAD1;
|
||||
x11.keyMap[XK_KP_Down] = KC_NUMPAD2;
|
||||
x11.keyMap[XK_KP_Page_Down] = KC_NUMPAD3;
|
||||
x11.keyMap[XK_KP_Insert] = KC_NUMPAD0;
|
||||
x11.keyMap[XK_KP_Delete] = KC_DECIMAL;
|
||||
|
||||
x11.keyMap[XK_Up] = KC_UP;
|
||||
x11.keyMap[XK_Down] = KC_DOWN;
|
||||
x11.keyMap[XK_Left] = KC_LEFT;
|
||||
x11.keyMap[XK_Right] = KC_RIGHT;
|
||||
|
||||
x11.keyMap[XK_Page_Up] = KC_PGUP;
|
||||
x11.keyMap[XK_Page_Down] = KC_PGDOWN;
|
||||
x11.keyMap[XK_Home] = KC_HOME;
|
||||
x11.keyMap[XK_End] = KC_END;
|
||||
|
||||
x11.keyMap[XK_Num_Lock] = KC_NUMLOCK;
|
||||
x11.keyMap[XK_Print] = KC_SYSRQ;
|
||||
x11.keyMap[XK_Scroll_Lock] = KC_SCROLL;
|
||||
x11.keyMap[XK_Pause] = KC_PAUSE;
|
||||
|
||||
x11.keyMap[XK_Shift_R] = KC_RSHIFT;
|
||||
x11.keyMap[XK_Shift_L] = KC_LSHIFT;
|
||||
x11.keyMap[XK_Alt_R] = KC_RALT;
|
||||
x11.keyMap[XK_Alt_L] = KC_LALT;
|
||||
|
||||
x11.keyMap[XK_Insert] = KC_INSERT;
|
||||
x11.keyMap[XK_Delete] = KC_DELETE;
|
||||
|
||||
x11.keyMap[XK_Super_L] = KC_LWIN;
|
||||
x11.keyMap[XK_Super_R] = KC_RWIN;
|
||||
x11.keyMap[XK_Menu] = KC_APPS;
|
||||
|
||||
// try to set a latin1 locales otherwise fallback to standard C locale
|
||||
static char locales[][32] = { "en_US.iso88591", "iso88591", "en_US", "C" };
|
||||
for(int i=0;i<4;++i) {
|
||||
if(setlocale(LC_ALL, locales[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
// open display
|
||||
x11.display = XOpenDisplay(0);
|
||||
if(!x11.display)
|
||||
fatal("Failed to open X display");
|
||||
|
||||
// check if GLX is supported on this display
|
||||
if(!glXQueryExtension(x11.display, 0, 0))
|
||||
fatal("GLX not supported");
|
||||
|
||||
// retrieve GLX version
|
||||
int glxMajor;
|
||||
int glxMinor;
|
||||
if(!glXQueryVersion(x11.display, &glxMajor, &glxMinor))
|
||||
fatal("Unable to query GLX version");
|
||||
notice("GLX version %d.%d", glxMajor, glxMinor);
|
||||
|
||||
// clipboard related atoms
|
||||
x11.atomClipboard = XInternAtom(x11.display, "CLIPBOARD", False);
|
||||
x11.atomTargets = XInternAtom(x11.display, "TARGETS", False);
|
||||
x11.atomUTF8String = XInternAtom(x11.display, "UTF8_STRING", False);
|
||||
x11.atomText = XInternAtom(x11.display, "TEXT", False);
|
||||
x11.atomCompoundText = XInternAtom(x11.display, "COMPOUND_TEXT", False);
|
||||
}
|
||||
|
||||
void Platform::terminate()
|
||||
{
|
||||
if(x11.window) {
|
||||
destroyWindow();
|
||||
x11.window = None;
|
||||
}
|
||||
|
||||
// close display
|
||||
if(x11.display) {
|
||||
XCloseDisplay(x11.display);
|
||||
x11.display = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Platform::poll()
|
||||
{
|
||||
XEvent event, peekevent;
|
||||
static InputEvent inputEvent;
|
||||
while(XPending(x11.display) > 0) {
|
||||
XNextEvent(x11.display, &event);
|
||||
|
||||
// call filter because xim will discard KeyPress events when keys still composing
|
||||
if(XFilterEvent(&event, x11.window))
|
||||
continue;
|
||||
|
||||
// discard events of repeated key releases
|
||||
if(event.type == KeyRelease && XPending(x11.display)) {
|
||||
XPeekEvent(x11.display, &peekevent);
|
||||
if((peekevent.type == KeyPress) &&
|
||||
(peekevent.xkey.keycode == event.xkey.keycode) &&
|
||||
((peekevent.xkey.time-event.xkey.time) < 2))
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(event.type) {
|
||||
case ConfigureNotify:
|
||||
// window resize
|
||||
if(x11.width != event.xconfigure.width || x11.height != event.xconfigure.height) {
|
||||
x11.width = event.xconfigure.width;
|
||||
x11.height = event.xconfigure.height;
|
||||
g_engine.onResize(x11.width, x11.height);
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyPress:
|
||||
case KeyRelease: {
|
||||
KeySym keysym;
|
||||
char buf[32];
|
||||
int len;
|
||||
|
||||
inputEvent.key.ctrl = (event.xkey.state & ControlMask);
|
||||
inputEvent.key.shift = (event.xkey.state & ShiftMask);
|
||||
inputEvent.key.alt = (event.xkey.state & Mod1Mask);
|
||||
|
||||
// fire enter text event
|
||||
if(event.type == KeyPress && !inputEvent.key.ctrl && !inputEvent.key.alt) {
|
||||
if(x11.xic) { // with xim we can get latin1 input correctly
|
||||
Status status;
|
||||
len = XmbLookupString(x11.xic, &event.xkey, buf, sizeof(buf), &keysym, &status);
|
||||
} else { // otherwise use XLookupString, but it doesn't work right with dead keys often
|
||||
static XComposeStatus compose = {NULL, 0};
|
||||
len = XLookupString(&event.xkey, buf, sizeof(buf), &keysym, &compose);
|
||||
}
|
||||
if(len > 0 &&
|
||||
// for some reason these keys produces characters and we don't want that
|
||||
keysym != XK_BackSpace &&
|
||||
keysym != XK_Return &&
|
||||
keysym != XK_Delete &&
|
||||
keysym != XK_Escape
|
||||
) {
|
||||
//debug("char: %c code: %d", buf[0], (unsigned char)buf[0]);
|
||||
inputEvent.type = EV_TEXT_ENTER;
|
||||
inputEvent.key.keychar = buf[0];
|
||||
inputEvent.key.keycode = KC_UNKNOWN;
|
||||
g_engine.onInputEvent(&inputEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// unmask Shift/Lock to get expected results
|
||||
event.xkey.state &= ~(ShiftMask | LockMask);
|
||||
len = XLookupString(&event.xkey, buf, sizeof(buf), &keysym, 0);
|
||||
|
||||
// fire key up/down event
|
||||
if(x11.keyMap.find(keysym) != x11.keyMap.end()) {
|
||||
inputEvent.key.keycode = x11.keyMap[keysym];
|
||||
inputEvent.type = (event.type == KeyPress) ? EV_KEY_DOWN : EV_KEY_UP;
|
||||
inputEvent.key.keychar = (len > 0) ? buf[0] : 0;
|
||||
g_engine.onInputEvent(&inputEvent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
switch(event.xbutton.button) {
|
||||
case Button1:
|
||||
inputEvent.type = (event.type == ButtonPress) ? EV_MOUSE_LDOWN : EV_MOUSE_LUP;
|
||||
break;
|
||||
case Button3:
|
||||
inputEvent.type = (event.type == ButtonPress) ? EV_MOUSE_RDOWN : EV_MOUSE_RUP;
|
||||
break;
|
||||
case Button2:
|
||||
inputEvent.type = (event.type == ButtonPress) ? EV_MOUSE_MDOWN : EV_MOUSE_MUP;
|
||||
break;
|
||||
case Button4:
|
||||
inputEvent.type = EV_MOUSE_WHEEL_UP;
|
||||
break;
|
||||
case Button5:
|
||||
inputEvent.type = EV_MOUSE_WHEEL_DOWN;
|
||||
break;
|
||||
}
|
||||
g_engine.onInputEvent(&inputEvent);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
inputEvent.type = EV_MOUSE_MOVE;
|
||||
inputEvent.mouse.x = event.xbutton.x;
|
||||
inputEvent.mouse.y = event.xbutton.y;
|
||||
g_engine.onInputEvent(&inputEvent);
|
||||
break;
|
||||
|
||||
case MapNotify:
|
||||
x11.visible = true;
|
||||
break;
|
||||
|
||||
case UnmapNotify:
|
||||
x11.visible = false;
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
x11.focused = true;
|
||||
break;
|
||||
|
||||
case FocusOut:
|
||||
x11.focused = false;
|
||||
break;
|
||||
|
||||
// clipboard data request
|
||||
case SelectionRequest:
|
||||
{
|
||||
XEvent respond;
|
||||
XSelectionRequestEvent *req = &(event.xselectionrequest);
|
||||
|
||||
if(req->target == x11.atomTargets ) {
|
||||
Atom typeList[] = {x11.atomText, x11.atomCompoundText, x11.atomUTF8String, XA_STRING};
|
||||
|
||||
XChangeProperty(x11.display, req->requestor,
|
||||
req->property, req->target,
|
||||
8, PropModeReplace,
|
||||
(unsigned char *) &typeList,
|
||||
sizeof(typeList));
|
||||
respond.xselection.property = req->property;
|
||||
} else {
|
||||
XChangeProperty(x11.display,
|
||||
req->requestor,
|
||||
req->property, req->target,
|
||||
8,
|
||||
PropModeReplace,
|
||||
(unsigned char*) x11.clipboardText.c_str(),
|
||||
x11.clipboardText.size());
|
||||
respond.xselection.property = req->property;
|
||||
}
|
||||
|
||||
respond.xselection.type = SelectionNotify;
|
||||
respond.xselection.display = req->display;
|
||||
respond.xselection.requestor = req->requestor;
|
||||
respond.xselection.selection = req->selection;
|
||||
respond.xselection.target = req->target;
|
||||
respond.xselection.time = req->time;
|
||||
XSendEvent(x11.display, req->requestor, 0, 0, &respond);
|
||||
XFlush(x11.display);
|
||||
break;
|
||||
}
|
||||
|
||||
case ClientMessage:
|
||||
{
|
||||
if((Atom)event.xclient.data.l[0] == x11.atomDeleteWindow)
|
||||
g_engine.onClose();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long Platform::getTicks()
|
||||
{
|
||||
static timeval tv;
|
||||
static unsigned long firstTick = 0;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
if(!firstTick)
|
||||
firstTick = tv.tv_sec;
|
||||
|
||||
return ((tv.tv_sec - firstTick) * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void Platform::sleep(unsigned long miliseconds)
|
||||
{
|
||||
timespec tv;
|
||||
tv.tv_sec = miliseconds / 1000;
|
||||
tv.tv_nsec = (miliseconds % 1000) * 1000000;
|
||||
nanosleep(&tv, NULL);
|
||||
}
|
||||
|
||||
bool Platform::createWindow(int width, int height, int minWidth, int minHeight)
|
||||
{
|
||||
static int attrList[] = {
|
||||
GLX_USE_GL,
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
None
|
||||
};
|
||||
|
||||
// choose OpenGL, RGBA, double buffered, visual
|
||||
x11.visual = glXChooseVisual(x11.display, DefaultScreen(x11.display), attrList);
|
||||
if(!x11.visual)
|
||||
fatal("RGBA/Double buffered visual not supported");
|
||||
|
||||
// create GLX context
|
||||
x11.glxContext = glXCreateContext(x11.display, x11.visual, 0, GL_TRUE);
|
||||
if(!x11.glxContext)
|
||||
fatal("Unable to create GLX context");
|
||||
|
||||
// color map
|
||||
x11.colormap = XCreateColormap(x11.display,
|
||||
RootWindow(x11.display, x11.visual->screen),
|
||||
x11.visual->visual,
|
||||
AllocNone);
|
||||
|
||||
// setup window attributes
|
||||
XSetWindowAttributes wa;
|
||||
wa.colormap = x11.colormap;
|
||||
wa.border_pixel = 0;
|
||||
wa.event_mask = KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
|
||||
ExposureMask | VisibilityChangeMask |
|
||||
StructureNotifyMask | FocusChangeMask;
|
||||
|
||||
// calculate center position
|
||||
int x = (XDisplayHeight(x11.display, DefaultScreen(x11.display)) - width) / 2;
|
||||
int y = (XDisplayHeight(x11.display, DefaultScreen(x11.display)) - height) / 2;
|
||||
|
||||
// create the window
|
||||
x11.window = XCreateWindow(x11.display,
|
||||
RootWindow(x11.display, x11.visual->screen),
|
||||
x, y,
|
||||
width, height,
|
||||
0,
|
||||
x11.visual->depth,
|
||||
InputOutput,
|
||||
x11.visual->visual,
|
||||
CWBorderPixel | CWColormap | CWEventMask,
|
||||
&wa);
|
||||
|
||||
if(!x11.window)
|
||||
fatal("Unable to create X window");
|
||||
|
||||
// create input context (to have better key input handling)
|
||||
if(XSupportsLocale()) {
|
||||
XSetLocaleModifiers("");
|
||||
x11.xim = XOpenIM(x11.display, NULL, NULL, NULL);
|
||||
if(x11.xim) {
|
||||
x11.xic = XCreateIC(x11.xim,
|
||||
XNInputStyle,
|
||||
XIMPreeditNothing | XIMStatusNothing,
|
||||
XNClientWindow, x11.window, NULL);
|
||||
if(!x11.xic)
|
||||
error("Unable to create the input context");
|
||||
} else
|
||||
error("Failed to open an input method");
|
||||
} else
|
||||
error("X11 does not support the current locale");
|
||||
|
||||
if(!x11.xic)
|
||||
warning("Input of special keys maybe messed up because we couldn't create an input context");
|
||||
|
||||
|
||||
// set window minimum size
|
||||
XSizeHints xsizehints;
|
||||
xsizehints.flags = PMinSize;
|
||||
xsizehints.min_width = minWidth;
|
||||
xsizehints.min_height= minHeight;
|
||||
XSetWMSizeHints(x11.display, x11.window, &xsizehints, XA_WM_NORMAL_HINTS);
|
||||
|
||||
// handle delete window event
|
||||
x11.atomDeleteWindow = XInternAtom(x11.display, "WM_DELETE_WINDOW", True);
|
||||
XSetWMProtocols(x11.display, x11.window, &x11.atomDeleteWindow , 1);
|
||||
|
||||
// connect the GLX-context to the window
|
||||
glXMakeCurrent(x11.display, x11.window, x11.glxContext);
|
||||
|
||||
x11.width = width;
|
||||
x11.height = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Platform::destroyWindow()
|
||||
{
|
||||
if(x11.glxContext) {
|
||||
glXMakeCurrent(x11.display, None, NULL);
|
||||
glXDestroyContext(x11.display, x11.glxContext);
|
||||
x11.glxContext = NULL;
|
||||
}
|
||||
|
||||
if(x11.visual) {
|
||||
XFree(x11.visual);
|
||||
x11.visual = NULL;
|
||||
}
|
||||
|
||||
if(x11.colormap != None) {
|
||||
XFreeColormap(x11.display, x11.colormap);
|
||||
x11.colormap = 0;
|
||||
}
|
||||
|
||||
if(x11.window != None) {
|
||||
XUnmapWindow(x11.display, x11.window);
|
||||
XDestroyWindow(x11.display, x11.window);
|
||||
x11.window = None;
|
||||
}
|
||||
|
||||
if(x11.xic) {
|
||||
XDestroyIC(x11.xic);
|
||||
x11.xic = NULL;
|
||||
}
|
||||
|
||||
if(x11.xim) {
|
||||
XCloseIM(x11.xim);
|
||||
x11.xim = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Platform::showWindow()
|
||||
{
|
||||
XMapWindow(x11.display, x11.window);
|
||||
}
|
||||
|
||||
void Platform::setWindowTitle(const char *title)
|
||||
{
|
||||
XStoreName(x11.display, x11.window, title);
|
||||
XSetIconName(x11.display, x11.window, title);
|
||||
}
|
||||
|
||||
void *Platform::getExtensionProcAddress(const char *ext)
|
||||
{
|
||||
return (void*)glXGetProcAddressARB((const GLubyte*)ext);
|
||||
}
|
||||
|
||||
bool Platform::isExtensionSupported(const char *ext)
|
||||
{
|
||||
const char *exts = glXQueryExtensionsString(x11.display, DefaultScreen(x11.display));
|
||||
if(strstr(exts, ext))
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *Platform::getTextFromClipboard()
|
||||
{
|
||||
Window ownerWindow = XGetSelectionOwner(x11.display, x11.atomClipboard);
|
||||
if(ownerWindow == x11.window)
|
||||
return x11.clipboardText.c_str();
|
||||
|
||||
std::string clipboard = "";
|
||||
if(ownerWindow != None) {
|
||||
XConvertSelection(x11.display, x11.atomClipboard, XA_STRING, 0, ownerWindow, CurrentTime);
|
||||
XFlush(x11.display);
|
||||
|
||||
// hack to wait SelectioNotify event, otherwise we will get wrong clipboard pastes
|
||||
sleep(100);
|
||||
|
||||
// check for data
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long numItems, bytesLeft, dummy;
|
||||
unsigned char *data;
|
||||
XGetWindowProperty(x11.display, ownerWindow,
|
||||
XA_STRING,
|
||||
0, 0, 0,
|
||||
AnyPropertyType,
|
||||
&type,
|
||||
&format,
|
||||
&numItems,
|
||||
&bytesLeft,
|
||||
&data);
|
||||
if(bytesLeft > 0) {
|
||||
// get the data get
|
||||
int result = XGetWindowProperty(x11.display, ownerWindow,
|
||||
XA_STRING,
|
||||
0,
|
||||
bytesLeft,
|
||||
0,
|
||||
AnyPropertyType,
|
||||
&type,
|
||||
&format,
|
||||
&numItems,
|
||||
&dummy,
|
||||
&data);
|
||||
if(result == Success)
|
||||
clipboard = (const char*)data;
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
return clipboard.c_str();
|
||||
}
|
||||
|
||||
void Platform::copyToClipboard(const char *text)
|
||||
{
|
||||
x11.clipboardText = text;
|
||||
XSetSelectionOwner(x11.display, x11.atomClipboard, x11.window, CurrentTime);
|
||||
XFlush(x11.display);
|
||||
}
|
||||
|
||||
void Platform::hideMouseCursor()
|
||||
{
|
||||
if(x11.cursor == None) {
|
||||
char bm[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
Pixmap pix = XCreateBitmapFromData(x11.display, x11.window, bm, 8, 8);
|
||||
XColor black;
|
||||
memset(&black, 0, sizeof(XColor));
|
||||
black.flags = DoRed | DoGreen | DoBlue;
|
||||
x11.cursor = XCreatePixmapCursor(x11.display, pix, pix, &black, &black, 0, 0);
|
||||
XFreePixmap(x11.display, pix);
|
||||
}
|
||||
XDefineCursor(x11.display, x11.window, x11.cursor);
|
||||
}
|
||||
|
||||
void Platform::showMouseCursor()
|
||||
{
|
||||
XUndefineCursor(x11.display, x11.window);
|
||||
if(x11.cursor != None) {
|
||||
XFreeCursor(x11.display, x11.cursor);
|
||||
x11.cursor = None;
|
||||
}
|
||||
}
|
||||
|
||||
void Platform::setVsync(bool enable)
|
||||
{
|
||||
typedef GLint (*glSwapIntervalProc)(GLint);
|
||||
glSwapIntervalProc glSwapInterval = NULL;
|
||||
|
||||
if(isExtensionSupported("GLX_MESA_swap_control"))
|
||||
glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalMESA");
|
||||
else if(isExtensionSupported("GLX_SGI_swap_control"))
|
||||
glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalSGI");
|
||||
|
||||
if(glSwapInterval)
|
||||
glSwapInterval(enable ? 1 : 0);
|
||||
}
|
||||
|
||||
void Platform::swapBuffers()
|
||||
{
|
||||
glXSwapBuffers(x11.display, x11.window);
|
||||
}
|
||||
|
||||
bool Platform::isWindowFocused()
|
||||
{
|
||||
return x11.focused;
|
||||
}
|
||||
|
||||
bool Platform::isWindowVisible()
|
||||
{
|
||||
return x11.visible;
|
||||
}
|
||||
|
||||
int Platform::getWindowWidth()
|
||||
{
|
||||
return x11.width;
|
||||
}
|
||||
|
||||
int Platform::getWindowHeight()
|
||||
{
|
||||
return x11.height;
|
||||
}
|
||||
|
||||
const char *Platform::getAppUserDir()
|
||||
{
|
||||
std::stringstream sdir;
|
||||
sdir << PHYSFS_getUserDir() << "/." << APP_NAME << "/";
|
||||
if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST))
|
||||
error("Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
|
||||
return sdir.str().c_str();
|
||||
}
|
Reference in New Issue
Block a user