parent
a3901b0251
commit
e611734396
|
@ -55,8 +55,6 @@ ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||
SET(SOURCES
|
||||
# game sources
|
||||
src/main.cpp
|
||||
src/menustate.cpp
|
||||
src/teststate.cpp
|
||||
|
||||
# game net
|
||||
src/protocollogin.cpp
|
||||
|
@ -66,6 +64,7 @@ SET(SOURCES
|
|||
src/framework/core/configs.cpp
|
||||
src/framework/core/resources.cpp
|
||||
src/framework/core/engine.cpp
|
||||
src/framework/core/modules.cpp
|
||||
|
||||
# framework script
|
||||
src/framework/script/luascript.cpp
|
||||
|
|
|
@ -50,8 +50,8 @@ window#enterGameWindow:
|
|||
margin.bottom: 10
|
||||
margin.right: 13
|
||||
onClick: |
|
||||
enterGameWindow:destroy()
|
||||
enterGameWindow = nil
|
||||
self:getParent():destroy()
|
||||
self:getParent():getParent():unlock()
|
||||
|
||||
textEdit#accountNameTextEdit:
|
||||
anchors.right: parent.right
|
||||
|
|
|
@ -58,3 +58,5 @@ window#infoWindow:
|
|||
anchors.top: parent.top
|
||||
margin.top: 191
|
||||
margin.left: 188
|
||||
onClick: |
|
||||
self:getParent():destroy()
|
|
@ -1,6 +1,15 @@
|
|||
-- events
|
||||
-- main menu methods
|
||||
function MainMenu_create()
|
||||
mainMenu = loadUI("modules/mainmenu/mainmenu.yml")
|
||||
end
|
||||
|
||||
function MainMenu_destroy()
|
||||
mainMenu:destroy()
|
||||
end
|
||||
|
||||
function MainMenu_enterGameClicked()
|
||||
enterGameWindow = loadUI("modules/mainmenu/entergamewindow.yml")
|
||||
enterGameWindow:getParent():lock(enterGameWindow)
|
||||
end
|
||||
|
||||
function MainMenu_optionsClicked()
|
||||
|
@ -12,12 +21,5 @@ function MainMenu_infoClicked()
|
|||
end
|
||||
|
||||
function MainMenu_exitClicked()
|
||||
exitGame()
|
||||
onApplicationClose()
|
||||
end
|
||||
|
||||
-- create main menu
|
||||
function MainMenu_create()
|
||||
menuPanel = loadUI("modules/mainmenu/mainmenu.yml")
|
||||
end
|
||||
|
||||
MainMenu_create()
|
|
@ -1,4 +1,14 @@
|
|||
panel#mainMenu:
|
||||
panel#background:
|
||||
skin:
|
||||
image: background.png
|
||||
antialised: true
|
||||
size: [500, 500]
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
panel#mainMenu:
|
||||
skin: roundedGridPanel
|
||||
size: [117, 171]
|
||||
anchors.left: parent.left
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
-- menu state
|
||||
function onEnterMenuState()
|
||||
MainMenu_create()
|
||||
end
|
||||
|
||||
function onLeaveMenuState()
|
||||
MainMenu_destroy()
|
||||
end
|
||||
|
||||
function onApplicationClose()
|
||||
onLeaveMenuState()
|
||||
exitGame()
|
||||
end
|
||||
|
||||
-- here is where everything starts
|
||||
if not initialStateLoaded then
|
||||
onEnterMenuState()
|
||||
setOnApplicationClose(onApplicationClose)
|
||||
initialStateLoaded = true
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
title: Main menu
|
||||
notes: Used to create the main menu
|
||||
enabled: true
|
||||
#dependencies
|
||||
interface: 020
|
||||
author: edubart
|
||||
version: 0.2
|
||||
scripts:
|
||||
- menustate.lua
|
||||
- mainmenu.lua
|
|
@ -110,5 +110,4 @@ window#optionsWindow:
|
|||
margin.right: 10
|
||||
margin.bottom: 13
|
||||
onClick: |
|
||||
optionsWindow:destroy()
|
||||
optionsWindow = nil
|
||||
self:getParent():destroy()
|
|
@ -42,14 +42,23 @@ void Engine::init()
|
|||
|
||||
void Engine::terminate()
|
||||
{
|
||||
// force last state exit
|
||||
changeState(NULL);
|
||||
|
||||
// terminate stuff
|
||||
g_fonts.terminate();
|
||||
g_graphics.terminate();
|
||||
}
|
||||
|
||||
void Engine::poll()
|
||||
{
|
||||
// poll platform events
|
||||
Platform::poll();
|
||||
|
||||
// poll network events
|
||||
Connection::poll();
|
||||
|
||||
// poll diaptcher tasks
|
||||
g_dispatcher.poll();
|
||||
}
|
||||
|
||||
void Engine::run()
|
||||
{
|
||||
std::string fpsText;
|
||||
|
@ -65,14 +74,7 @@ void Engine::run()
|
|||
while(!m_stopping) {
|
||||
m_lastFrameTicks = Platform::getTicks();
|
||||
|
||||
// poll platform events
|
||||
Platform::poll();
|
||||
|
||||
// poll network events
|
||||
Connection::poll();
|
||||
|
||||
// poll diaptcher tasks
|
||||
g_dispatcher.poll();
|
||||
poll();
|
||||
|
||||
// render only when visible
|
||||
if(Platform::isWindowVisible()) {
|
||||
|
@ -93,8 +95,6 @@ void Engine::run()
|
|||
// render
|
||||
g_graphics.beginRender();
|
||||
|
||||
if(m_currentState)
|
||||
m_currentState->render();
|
||||
UIContainer::getRootContainer()->render();
|
||||
|
||||
// render fps
|
||||
|
@ -117,39 +117,19 @@ 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::onClose()
|
||||
{
|
||||
if(m_currentState)
|
||||
m_currentState->onClose();
|
||||
if(m_onCloseCallback)
|
||||
g_dispatcher.addTask(m_onCloseCallback);
|
||||
}
|
||||
|
||||
void Engine::onResize(const Size& size)
|
||||
{
|
||||
g_graphics.resize(size);
|
||||
UIContainer::getRootContainer()->setSize(size);
|
||||
|
||||
if(m_currentState)
|
||||
m_currentState->onResize(size);
|
||||
}
|
||||
|
||||
void Engine::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
bool eventCaptured = false;
|
||||
|
||||
// events goes to the state first
|
||||
if(m_currentState)
|
||||
eventCaptured = m_currentState->onInputEvent(event);
|
||||
|
||||
// if the state didn't capture the input then goes to the gui
|
||||
if(!eventCaptured)
|
||||
UIContainer::getRootContainer()->onInputEvent(event);
|
||||
}
|
||||
|
|
|
@ -26,19 +26,20 @@
|
|||
#define ENGINE_H
|
||||
|
||||
#include <prerequisites.h>
|
||||
#include <core/gamestate.h>
|
||||
#include <core/input.h>
|
||||
|
||||
class Engine
|
||||
{
|
||||
public:
|
||||
Engine() : m_stopping(false),
|
||||
m_running(false),
|
||||
m_calculateFps(false),
|
||||
m_currentState(NULL) { }
|
||||
m_calculateFps(false) { }
|
||||
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
/// Poll events
|
||||
void poll();
|
||||
/// Main loop
|
||||
void run();
|
||||
|
||||
|
@ -46,8 +47,6 @@ public:
|
|||
void stop();
|
||||
|
||||
/// Change current game state
|
||||
void changeState(GameState *newState);
|
||||
|
||||
bool isRunning() const { return m_running; }
|
||||
bool isStopping() const { return m_stopping; }
|
||||
|
||||
|
@ -64,13 +63,16 @@ public:
|
|||
/// Return the current ticks on this frame
|
||||
int getCurrentFrameTicks() const { return m_lastFrameTicks; }
|
||||
|
||||
void setOnClose(Callback onCloseCallback) { m_onCloseCallback = onCloseCallback; }
|
||||
|
||||
private:
|
||||
bool m_stopping;
|
||||
bool m_running;
|
||||
bool m_calculateFps;
|
||||
|
||||
GameState *m_currentState;
|
||||
int m_lastFrameTicks;
|
||||
|
||||
Callback m_onCloseCallback;
|
||||
};
|
||||
|
||||
extern Engine g_engine;
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/* 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
|
||||
|
||||
#include <prerequisites.h>
|
||||
#include <core/input.h>
|
||||
|
||||
struct InputEvent;
|
||||
|
||||
class GameState
|
||||
{
|
||||
public:
|
||||
GameState() { }
|
||||
virtual ~GameState() { }
|
||||
|
||||
/// Fired when enter the state
|
||||
virtual void onEnter() = 0;
|
||||
/// Fired when leaves the state
|
||||
virtual void onLeave() = 0;
|
||||
|
||||
/// Fired when user tries to close the window
|
||||
virtual void onClose() = 0;
|
||||
/// Fired for every user input event, this is called before processing UI input and if it returns false the input is not passed to the UI
|
||||
virtual bool onInputEvent(const InputEvent& event) = 0;
|
||||
/// Fired when main window is resized
|
||||
virtual void onResize(const Size& size) = 0;
|
||||
|
||||
/// Fired before redering the UI
|
||||
virtual void render() = 0;
|
||||
};
|
||||
|
||||
#endif // GAMESTATE_H
|
|
@ -22,26 +22,5 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef TESTSTATE_H
|
||||
#define TESTSTATE_H
|
||||
#include "modules.h"
|
||||
|
||||
#include <prerequisites.h>
|
||||
#include <core/gamestate.h>
|
||||
|
||||
class TestState : public GameState
|
||||
{
|
||||
public:
|
||||
TestState() { }
|
||||
|
||||
void onEnter();
|
||||
void onLeave();
|
||||
|
||||
void onClose();
|
||||
bool onInputEvent(const InputEvent& event);
|
||||
void onResize(const Size& size);
|
||||
|
||||
virtual void render();
|
||||
virtual void update(int ticks, int elapsedTicks);
|
||||
};
|
||||
|
||||
#endif // TESTSTATE_H
|
|
@ -22,41 +22,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <core/engine.h>
|
||||
#include <graphics/graphics.h>
|
||||
#include "teststate.h"
|
||||
#ifndef MODULES_H
|
||||
#define MODULES_H
|
||||
|
||||
void TestState::onEnter()
|
||||
class Modules
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void TestState::onLeave()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TestState::onClose()
|
||||
{
|
||||
g_engine.stop();
|
||||
}
|
||||
|
||||
bool TestState::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void TestState::onResize(const Size& size)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TestState::render()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TestState::update(int ticks, int elapsedTicks)
|
||||
{
|
||||
|
||||
}
|
||||
#endif // MODULES_H
|
|
@ -27,9 +27,16 @@
|
|||
#include <graphics/graphics.h>
|
||||
#include <graphics/textures.h>
|
||||
|
||||
Image::Image(TexturePtr texture)
|
||||
: m_texture(texture)
|
||||
{
|
||||
m_textureCoords = Rect(0, 0, m_texture->getSize());
|
||||
}
|
||||
|
||||
Image::Image(const std::string& texture)
|
||||
{
|
||||
m_texture = g_textures.get(texture);
|
||||
m_textureCoords = Rect(0, 0, m_texture->getSize());
|
||||
}
|
||||
|
||||
Image::Image(const std::string& texture, Rect textureCoords) :
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
class Image
|
||||
{
|
||||
public:
|
||||
Image(TexturePtr texture) : m_texture(texture) { }
|
||||
Image(TexturePtr texture);
|
||||
Image(TexturePtr texture, Rect textureCoords) : m_texture(texture), m_textureCoords(textureCoords) { }
|
||||
Image(const std::string& texture);
|
||||
Image(const std::string& texture, Rect textureCoords);
|
||||
|
|
|
@ -33,6 +33,7 @@ void LuaScript::registerFunctions()
|
|||
registerGlobalFunction("exitGame", &LuaScript::lua_exitGame);
|
||||
registerGlobalFunction("loadUI", &LuaScript::lua_loadUI);
|
||||
registerGlobalFunction("getUIRootContainer", &LuaScript::lua_getUIRootContainer);
|
||||
registerGlobalFunction("setOnApplicationClose", &LuaScript::lua_setOnApplicationClose);
|
||||
|
||||
registerClass("UILayout");
|
||||
registerClass("UIElement", "UILayout");
|
||||
|
@ -42,8 +43,11 @@ void LuaScript::registerFunctions()
|
|||
registerClass("UIContainer", "UIElement");
|
||||
registerClass("UIWindow", "UIContainer");
|
||||
|
||||
registerMemberFunction("UIElement", "getParent", &LuaScript::lua_UIElement_getParent);
|
||||
registerMemberFunction("UIElement", "destroy", &LuaScript::lua_UIElement_destroy);
|
||||
registerMemberFunction("UIContainer", "getChildByID", &LuaScript::lua_UIContainer_getChildByID);
|
||||
registerMemberFunction("UIContainer", "lock", &LuaScript::lua_UIContainer_lock);
|
||||
registerMemberFunction("UIContainer", "unlock", &LuaScript::lua_UIContainer_unlock);
|
||||
registerMemberFunction("UIButton", "setOnClick", &LuaScript::lua_UIButton_setOnClick);
|
||||
}
|
||||
|
||||
|
@ -74,10 +78,34 @@ int LuaScript::lua_getUIRootContainer()
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int LuaScript::lua_setOnApplicationClose()
|
||||
{
|
||||
int funcRef = popFunction();
|
||||
g_engine.setOnClose([this, funcRef] {
|
||||
pushFunction(funcRef);
|
||||
callFunction();
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScript::lua_UIElement_destroy()
|
||||
{
|
||||
UIElementPtr element = boost::static_pointer_cast<UIElement>(popClassInstance());
|
||||
if(element)
|
||||
element->destroy();
|
||||
else
|
||||
pushNil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScript::lua_UIElement_getParent()
|
||||
{
|
||||
UIElementPtr element = boost::static_pointer_cast<UIElement>(popClassInstance());
|
||||
if(element)
|
||||
pushClassInstance(element->getParent());
|
||||
else
|
||||
pushNil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -87,8 +115,9 @@ int LuaScript::lua_UIButton_setOnClick()
|
|||
UIButtonPtr button = boost::static_pointer_cast<UIButton>(popClassInstance());
|
||||
if(button) {
|
||||
int funcRef = popFunction();
|
||||
button->setOnClick([this, funcRef] {
|
||||
button->setOnClick([this, funcRef](UIButtonPtr button) {
|
||||
pushFunction(funcRef);
|
||||
setSelf(button);
|
||||
callFunction();
|
||||
});
|
||||
} else {
|
||||
|
@ -100,13 +129,29 @@ int LuaScript::lua_UIButton_setOnClick()
|
|||
int LuaScript::lua_UIContainer_getChildByID()
|
||||
{
|
||||
std::string id = popString();
|
||||
ScriptablePtr object = popClassInstance();
|
||||
if(object && strcmp("UIContainer", object->getScriptableName()) == 0) {
|
||||
UIContainerPtr container = boost::static_pointer_cast<UIContainer>(object);
|
||||
UIContainerPtr container = boost::static_pointer_cast<UIContainer>(popClassInstance());
|
||||
if(container)
|
||||
pushClassInstance(container->getChildById(id));
|
||||
} else {
|
||||
else
|
||||
pushNil();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScript::lua_UIContainer_lock()
|
||||
{
|
||||
UIElementPtr element = boost::static_pointer_cast<UIElement>(popClassInstance());
|
||||
UIContainerPtr container = boost::static_pointer_cast<UIContainer>(popClassInstance());
|
||||
if(container && element) {
|
||||
container->lockElement(element);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScript::lua_UIContainer_unlock()
|
||||
{
|
||||
UIContainerPtr container = boost::static_pointer_cast<UIContainer>(popClassInstance());
|
||||
if(container) {
|
||||
container->unlockElement();
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -49,10 +49,22 @@ LuaScript::~LuaScript()
|
|||
lua_close(L);
|
||||
}
|
||||
|
||||
void LuaScript::loadAllModules()
|
||||
{
|
||||
std::list<std::string> modules = g_resources.getDirectoryFiles("modules");
|
||||
foreach(const std::string& module, modules) {
|
||||
std::list<std::string> moduleFiles = g_resources.getDirectoryFiles(std::string("modules/") + module);
|
||||
foreach(const std::string& moduleFile, moduleFiles) {
|
||||
if(boost::ends_with(moduleFile, ".lua"))
|
||||
loadFile(std::string("modules/") + module + "/" + moduleFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LuaScript::loadFile(const std::string& fileName)
|
||||
{
|
||||
if(!g_resources.fileExists(fileName)) {
|
||||
logError("lua script file '%s' doesn't exist", fileName.c_str());
|
||||
logError("script file '%s' doesn't exist", fileName.c_str());
|
||||
return false;
|
||||
}
|
||||
std::string fileContents = g_resources.loadTextFile(fileName);
|
||||
|
@ -64,20 +76,19 @@ bool LuaScript::loadBuffer(const std::string& text, const std::string& what)
|
|||
// load buffer
|
||||
int ret = luaL_loadbuffer(L, text.c_str(), text.length(), what.c_str());
|
||||
if(ret != 0){
|
||||
logError((std::string("while parsing lua code: ") + popString()).c_str());
|
||||
reportError(popString());
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if that is loaded as a function
|
||||
// check if is loaded as a function
|
||||
if(lua_isfunction(L, -1) == 0) {
|
||||
logError("lua code not loaded as function");
|
||||
return false;
|
||||
}
|
||||
|
||||
// execute it
|
||||
ret = lua_pcall(L, 0, 0, 0);
|
||||
if(ret != 0){
|
||||
logError((std::string("while loading lua code: ") + popString()).c_str());
|
||||
reportError(popString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -86,21 +97,30 @@ bool LuaScript::loadBuffer(const std::string& text, const std::string& what)
|
|||
|
||||
int LuaScript::loadBufferAsFunction(const std::string& text, const std::string& what)
|
||||
{
|
||||
int ret = luaL_loadstring(L, text.c_str());
|
||||
int ret = luaL_loadbuffer(L, text.c_str(), text.length(), what.c_str());
|
||||
if(ret != 0){
|
||||
logError((std::string("while parsing lua code: ") + popString()).c_str());
|
||||
reportError(popString());
|
||||
return LUA_REFNIL;
|
||||
}
|
||||
|
||||
// check if that is loaded as a function
|
||||
// check if is loaded as a function
|
||||
if(lua_isfunction(L, -1) == 0) {
|
||||
logError("lua code not loaded as function");
|
||||
return LUA_REFNIL;
|
||||
}
|
||||
|
||||
return popFunction();
|
||||
}
|
||||
|
||||
void LuaScript::reportError(const std::string& errorDesc, const char *funcName)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "LUA script error";
|
||||
if(funcName)
|
||||
ss << " in " << funcName << "()";
|
||||
ss << ": " << errorDesc << std::endl;
|
||||
logError(ss.str().c_str());
|
||||
}
|
||||
|
||||
int LuaScript::getStackSize()
|
||||
{
|
||||
return lua_gettop(L);
|
||||
|
@ -120,23 +140,15 @@ bool LuaScript::popBoolean()
|
|||
|
||||
int32_t LuaScript::popInteger()
|
||||
{
|
||||
double d;
|
||||
if(lua_istable(L, -1)) {
|
||||
lua_getfield(L, -1, "__intValue");
|
||||
d = lua_tonumber(L, -1);
|
||||
pop(2);
|
||||
}
|
||||
else{
|
||||
d = lua_tonumber(L, -1);
|
||||
double d = lua_tonumber(L, -1);
|
||||
pop(1);
|
||||
}
|
||||
return (int)d;
|
||||
}
|
||||
|
||||
std::string LuaScript::popString()
|
||||
{
|
||||
size_t len;
|
||||
const char* cstr = lua_tolstring(L, -1, &len);
|
||||
const char *cstr = lua_tolstring(L, -1, &len);
|
||||
std::string str(cstr, len);
|
||||
pop();
|
||||
return str;
|
||||
|
@ -169,29 +181,30 @@ void LuaScript::pushUserdata(void* ptr)
|
|||
|
||||
void LuaScript::pushClassInstance(const ScriptablePtr& object)
|
||||
{
|
||||
if(object->getScriptableName()) {
|
||||
if(object && object->getScriptableName()) {
|
||||
new(lua_newuserdata(L, sizeof(ScriptableWeakPtr))) ScriptableWeakPtr(object);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, (std::string(object->getScriptableName()) + "_mt").c_str());
|
||||
lua_setmetatable(L, -2);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
|
||||
ScriptablePtr LuaScript::popClassInstance()
|
||||
{
|
||||
if(!lua_isuserdata(L, -1)) {
|
||||
logError("Couldn't pop a class instance, top objet is not a valid type (%s)", luaL_typename(L, -1));
|
||||
reportError(format("couldn't pop a class instance, top objet is not a valid type (%s)", luaL_typename(L, -1)));
|
||||
lua_pop(L, 1);
|
||||
return ScriptablePtr();
|
||||
}
|
||||
|
||||
ScriptableWeakPtr *objectRef = (ScriptableWeakPtr *)lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return objectRef->lock();
|
||||
}
|
||||
|
||||
int LuaScript::popFunction()
|
||||
{
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
ScriptablePtr object = objectRef->lock();
|
||||
if(!object)
|
||||
reportError(format("attempt to retrive class instance from a object that is already expired"));
|
||||
return object;
|
||||
}
|
||||
|
||||
void LuaScript::pushFunction(int functionRef)
|
||||
|
@ -199,9 +212,40 @@ void LuaScript::pushFunction(int functionRef)
|
|||
lua_rawgeti(L, LUA_REGISTRYINDEX, functionRef);
|
||||
}
|
||||
|
||||
void LuaScript::callFunction(int numArgs, bool itReturnsValue)
|
||||
int LuaScript::popFunction()
|
||||
{
|
||||
lua_call(L, numArgs, itReturnsValue ? 1 : 0);
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
void LuaScript::releaseFunction(int functionRef)
|
||||
{
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, functionRef);
|
||||
}
|
||||
|
||||
void LuaScript::callFunction(int numArgs)
|
||||
{
|
||||
int size = lua_gettop(L);
|
||||
int errorIndex = size - numArgs;
|
||||
lua_pushcfunction(L, &LuaScript::luaErrorHandler);
|
||||
lua_insert(L, errorIndex);
|
||||
|
||||
int ret = lua_pcall(L, numArgs, 0, errorIndex);
|
||||
if(ret != 0) {
|
||||
reportError(popString());
|
||||
}
|
||||
|
||||
lua_remove(L, errorIndex);
|
||||
|
||||
if(lua_gettop(L) + numArgs + 1 != size)
|
||||
reportError("stack size changed!");
|
||||
}
|
||||
|
||||
void LuaScript::setSelf(const ScriptablePtr& scriptable, int envIndex)
|
||||
{
|
||||
lua_getfenv(L, envIndex);
|
||||
pushClassInstance(scriptable);
|
||||
lua_setfield(L, -2, "self");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void LuaScript::setupPackageLoader()
|
||||
|
@ -342,3 +386,20 @@ int LuaScript::luaFunctionCallback(lua_State* L)
|
|||
return (g_lua.*(g_lua.m_functions[id]))();
|
||||
}
|
||||
|
||||
int LuaScript::luaErrorHandler(lua_State *L)
|
||||
{
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
||||
if(!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
lua_getfield(L, -1, "traceback");
|
||||
if(!lua_isfunction(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
return 1;
|
||||
}
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushinteger(L, 2);
|
||||
lua_call(L, 2, 1);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -29,15 +29,19 @@
|
|||
#include <script/scriptable.h>
|
||||
#include <lua.hpp>
|
||||
|
||||
#define reportFuncError(a) reportError(a, __FUNCTION__)
|
||||
|
||||
class LuaScript
|
||||
{
|
||||
public:
|
||||
LuaScript();
|
||||
virtual ~LuaScript();
|
||||
|
||||
void loadAllModules();
|
||||
bool loadFile(const std::string& fileName);
|
||||
bool loadBuffer(const std::string& text, const std::string& what = "luaBuffer");
|
||||
int loadBufferAsFunction(const std::string& text, const std::string& what = "luaBuffer");
|
||||
void reportError(const std::string& errorDesc, const char *funcName = NULL);
|
||||
|
||||
int getStackSize();
|
||||
|
||||
|
@ -52,9 +56,12 @@ public:
|
|||
int32_t popInteger();
|
||||
std::string popString();
|
||||
|
||||
int popFunction();
|
||||
void pushFunction(int functionRef);
|
||||
void callFunction(int numArgs = 0, bool itReturnsValue = false);
|
||||
int popFunction();
|
||||
void releaseFunction(int functionRef);
|
||||
void callFunction(int numArgs = 0);
|
||||
|
||||
void setSelf(const ScriptablePtr& scriptable, int envIndex = -1);
|
||||
|
||||
void pushClassInstance(const ScriptablePtr& object);
|
||||
ScriptablePtr popClassInstance();
|
||||
|
@ -70,20 +77,25 @@ public:
|
|||
static int luaPackageLoader(lua_State* L);
|
||||
static int luaCollectClassInstance(lua_State* L);
|
||||
static int luaCompareClassInstances(lua_State* L);
|
||||
static int luaErrorHandler(lua_State *L);
|
||||
|
||||
void registerFunctions();
|
||||
|
||||
int lua_UIButton_setOnClick();
|
||||
|
||||
int lua_UIElement_getParent();
|
||||
int lua_UIElement_destroy();
|
||||
|
||||
// container functions
|
||||
int lua_UIContainer_getChildByID();
|
||||
int lua_UIContainer_lock();
|
||||
int lua_UIContainer_unlock();
|
||||
|
||||
// global functions
|
||||
int lua_exitGame();
|
||||
int lua_loadUI();
|
||||
int lua_getUIRootContainer();
|
||||
int lua_setOnApplicationClose();
|
||||
|
||||
private:
|
||||
std::vector<LuaCFunction> m_functions;
|
||||
|
|
|
@ -33,8 +33,8 @@ void UIButton::onInputEvent(const InputEvent& event)
|
|||
} else if(event.type == EV_MOUSE_LUP && m_state == UI::ButtonDown) {
|
||||
m_state = UI::ButtonUp;
|
||||
if(getRect().contains(event.mousePos)) {
|
||||
if(m_buttonClickCallback) {
|
||||
g_dispatcher.addTask(m_buttonClickCallback);
|
||||
if(m_onClickCallback) {
|
||||
g_dispatcher.addTask(boost::bind(m_onClickCallback, boost::static_pointer_cast<UIButton>(shared_from_this())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,13 @@
|
|||
#include <ui/uielement.h>
|
||||
#include <graphics/borderedimage.h>
|
||||
|
||||
class UIButton;
|
||||
typedef boost::shared_ptr<UIButton> UIButtonPtr;
|
||||
|
||||
class UIButton : public UIElement
|
||||
{
|
||||
typedef boost::function<void(UIButtonPtr)> OnClick;
|
||||
|
||||
public:
|
||||
UIButton() :
|
||||
UIElement(UI::Button),
|
||||
|
@ -43,16 +48,14 @@ public:
|
|||
|
||||
UI::EButtonState getState() { return m_state; }
|
||||
|
||||
void setOnClick(const Callback& callback) { m_buttonClickCallback = callback; }
|
||||
void setOnClick(const OnClick& callback) { m_onClickCallback = callback; }
|
||||
|
||||
virtual const char *getScriptableName() const { return "UIButton"; }
|
||||
|
||||
private:
|
||||
std::string m_text;
|
||||
UI::EButtonState m_state;
|
||||
Callback m_buttonClickCallback;
|
||||
OnClick m_onClickCallback;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<UIButton> UIButtonPtr;
|
||||
|
||||
#endif // UIBUTTON_H
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <prerequisites.h>
|
||||
#include <core/resources.h>
|
||||
#include <ui/uicontainer.h>
|
||||
#include <core/dispatcher.h>
|
||||
|
||||
UIContainerPtr rootContainer(new UIContainer);
|
||||
|
||||
|
@ -71,6 +72,15 @@ UIElementPtr UIContainer::getChildById(const std::string& id)
|
|||
return UIElementPtr();
|
||||
}
|
||||
|
||||
UIElementPtr UIContainer::getChildByPos(const Point& pos)
|
||||
{
|
||||
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
|
||||
if((*it)->getRect().contains(pos))
|
||||
return (*it);
|
||||
}
|
||||
return UIElementPtr();
|
||||
}
|
||||
|
||||
UIElementPtr UIContainer::recursiveGetChildById(const std::string& id)
|
||||
{
|
||||
if(getId() == id)
|
||||
|
@ -93,6 +103,21 @@ UIElementPtr UIContainer::recursiveGetChildById(const std::string& id)
|
|||
return UIElementPtr();
|
||||
}
|
||||
|
||||
void UIContainer::pushChildToTop(const UIElementPtr& child)
|
||||
{
|
||||
bool removed = false;
|
||||
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
|
||||
if((*it) == child) {
|
||||
removed = true;
|
||||
m_children.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(removed) {
|
||||
m_children.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
void UIContainer::render()
|
||||
{
|
||||
UIElement::render();
|
||||
|
@ -119,9 +144,10 @@ void UIContainer::onInputEvent(const InputEvent& event)
|
|||
}
|
||||
// mouse events
|
||||
} else if(event.type & EV_MOUSE) {
|
||||
// mouse down and wheel events only go to elements that contains the mouse position and are not containers
|
||||
if((event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) && !child->asUIContainer()) {
|
||||
if(child->getRect().contains(event.mousePos)) {
|
||||
// mouse down and wheel events only go to elements that contains the mouse position
|
||||
if(event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) {
|
||||
// the child must contains the mouse position and be on top
|
||||
if(child->getRect().contains(event.mousePos) && child == getChildByPos(event.mousePos)) {
|
||||
// focus it
|
||||
if(event.type == EV_MOUSE_LDOWN && child->isFocusable())
|
||||
setFocusedElement(child);
|
||||
|
@ -171,10 +197,18 @@ void UIContainer::setFocusedElement(UIElementPtr focusedElement)
|
|||
m_focusedElement->setFocused(false);
|
||||
m_focusedElement->onFocusChange();
|
||||
}
|
||||
|
||||
m_focusedElement = focusedElement;
|
||||
if(m_focusedElement) {
|
||||
m_focusedElement->setFocused(true);
|
||||
m_focusedElement->onFocusChange();
|
||||
}
|
||||
}
|
||||
|
||||
// when containers are focused they go to the top
|
||||
if(focusedElement && focusedElement->asUIContainer()) {
|
||||
g_dispatcher.addTask(boost::bind(&UIContainer::pushChildToTop, asUIContainer(), m_focusedElement));
|
||||
}
|
||||
}
|
||||
|
||||
bool UIContainer::lockElement(UIElementPtr element)
|
||||
|
|
|
@ -44,8 +44,14 @@ public:
|
|||
void removeChild(UIElementPtr child);
|
||||
/// Find an element in this container by id
|
||||
UIElementPtr getChildById(const std::string& id);
|
||||
/// Find an element by position
|
||||
UIElementPtr getChildByPos(const Point& pos);
|
||||
/// Find an element in this container and in its children by id
|
||||
UIElementPtr recursiveGetChildById(const std::string& id);
|
||||
/// Pushs a child to the top
|
||||
void pushChildToTop(const UIElementPtr& child);
|
||||
|
||||
int getChildCount() const { return m_children.size(); }
|
||||
|
||||
/// Disable all children except the specified element
|
||||
bool lockElement(UIElementPtr element);
|
||||
|
|
|
@ -42,12 +42,21 @@ UIElement::UIElement(UI::EElementType type) :
|
|||
|
||||
void UIElement::destroy()
|
||||
{
|
||||
// we must always have a parent when destroying
|
||||
assert(getParent());
|
||||
// we cant delete now, as this call maybe in a event loop
|
||||
g_dispatcher.addTask(boost::bind(&UIContainer::removeChild, getParent(), asUIContainer()));
|
||||
// shared ptr must have 4 refs, (this + removeChild callback + parent + use_count call)
|
||||
assert(asUIElement().use_count() == 4);
|
||||
setVisible(false);
|
||||
setEnabled(false);
|
||||
|
||||
if(getParent()) {
|
||||
// schedule removal from parent
|
||||
g_dispatcher.addTask(boost::bind(&UIContainer::removeChild, getParent(), asUIElement()));
|
||||
}
|
||||
// schedule internal destroy (used to check for leaks)
|
||||
g_dispatcher.addTask(boost::bind(&UIElement::internalDestroy, asUIElement()));
|
||||
}
|
||||
|
||||
void UIElement::internalDestroy()
|
||||
{
|
||||
// check for leaks, the number of references must be always 2 here
|
||||
assert(asUIElement().use_count() == 2);
|
||||
}
|
||||
|
||||
void UIElement::setSkin(const UIElementSkinPtr& skin)
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
friend class UIContainer;
|
||||
|
||||
private:
|
||||
void internalDestroy();
|
||||
|
||||
UI::EElementType m_type;
|
||||
UIContainerWeakPtr m_parent;
|
||||
UIElementSkinPtr m_skin;
|
||||
|
|
|
@ -50,6 +50,8 @@ void UIElementSkin::draw(UIElement *element)
|
|||
ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
||||
{
|
||||
ImagePtr image;
|
||||
TexturePtr texture;
|
||||
|
||||
if(node.FindValue("bordered image")) {
|
||||
const YAML::Node& child = node["bordered image"];
|
||||
Rect left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, center;
|
||||
|
@ -72,7 +74,6 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
|||
if(child.FindValue("center"))
|
||||
child["center"] >> center;
|
||||
|
||||
TexturePtr texture;
|
||||
if(child.FindValue("image")) {
|
||||
std::string textureName;
|
||||
child["image"] >> textureName;
|
||||
|
@ -81,6 +82,7 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
|||
texture = g_uiSkins.getDefaultTexture();
|
||||
}
|
||||
|
||||
if(texture) {
|
||||
image = ImagePtr(new BorderedImage(texture,
|
||||
left,
|
||||
right,
|
||||
|
@ -92,6 +94,22 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
|||
bottomRight,
|
||||
center));
|
||||
}
|
||||
} else if(node.FindValue("image")) {
|
||||
std::string textureName;
|
||||
node["image"] >> textureName;
|
||||
texture = g_textures.get(textureName);
|
||||
if(texture) {
|
||||
image = ImagePtr(new Image(texture));
|
||||
}
|
||||
}
|
||||
|
||||
if(texture && node.FindValue("antialised")){
|
||||
bool antialised;
|
||||
node["antialised"] >> antialised;
|
||||
if(antialised)
|
||||
texture->enableBilinearFilter();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
UIElementSkin(const std::string& name, UI::EElementType elementType) :
|
||||
m_name(name),
|
||||
m_elementType(elementType) { }
|
||||
UIElementSkin() : m_elementType(UI::Element) { }
|
||||
virtual ~UIElementSkin() { }
|
||||
|
||||
/// Load the skin from a YAML node
|
||||
|
|
|
@ -133,8 +133,8 @@ void UILayout::recalculateLayout()
|
|||
m_rect.moveVerticalCenter(m_anchors[ANCHOR_VERTICAL_CENTER].getPos() + m_marginTop - m_marginBottom);
|
||||
} else {
|
||||
if(m_anchors[ANCHOR_TOP].isValid() && m_anchors[ANCHOR_BOTTOM].isValid()) {
|
||||
m_rect.setLeft(m_anchors[ANCHOR_TOP].getPos() + m_marginTop);
|
||||
m_rect.setRight(m_anchors[ANCHOR_BOTTOM].getPos() - m_marginBottom);
|
||||
m_rect.setTop(m_anchors[ANCHOR_TOP].getPos() + m_marginTop);
|
||||
m_rect.setBottom(m_anchors[ANCHOR_BOTTOM].getPos() - m_marginBottom);
|
||||
} else if(m_anchors[ANCHOR_TOP].isValid()) {
|
||||
m_rect.moveTop(m_anchors[ANCHOR_TOP].getPos() + m_marginTop);
|
||||
} else if(m_anchors[ANCHOR_BOTTOM].isValid()) {
|
||||
|
|
|
@ -67,7 +67,7 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
|
|||
{
|
||||
std::string fileContents = g_resources.loadTextFile(file);
|
||||
if(!fileContents.size()) {
|
||||
logFatal("Could not load ui file \"%s", file.c_str());
|
||||
logError("Could not load ui file \"%s", file.c_str());
|
||||
return UIElementPtr();
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
|
|||
|
||||
return element;
|
||||
} catch (YAML::Exception& e) {
|
||||
logFatal("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
|
||||
logError("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
|
||||
}
|
||||
|
||||
return UIElementPtr();
|
||||
|
@ -168,9 +168,15 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
|
|||
}
|
||||
|
||||
// set element skin
|
||||
if(node.FindValue("skin"))
|
||||
if(node.FindValue("skin")) {
|
||||
if(node["skin"].GetType() == YAML::CT_SCALAR) {
|
||||
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), node["skin"]));
|
||||
else // apply default skin
|
||||
} else {
|
||||
UIElementSkinPtr skin = UIElementSkinPtr(new UIElementSkin());
|
||||
skin->load(node["skin"]);
|
||||
element->setSkin(skin);
|
||||
}
|
||||
} else // apply default skin
|
||||
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), "default"));
|
||||
|
||||
// load elements common proprieties
|
||||
|
@ -252,6 +258,8 @@ void UILoader::loadElementAnchor(const UIElementPtr& element, EAnchorType type,
|
|||
UILayoutPtr relativeElement;
|
||||
if(relativeElementId == "parent" && element->getParent()) {
|
||||
relativeElement = element->getParent()->asUILayout();
|
||||
} else if(relativeElementId == "root") {
|
||||
relativeElement = UIContainer::getRootContainer();
|
||||
} else {
|
||||
UIElementPtr tmp = element->backwardsGetElementById(relativeElementId);
|
||||
if(tmp)
|
||||
|
@ -277,6 +285,8 @@ void UILoader::loadButton(const UIButtonPtr& button, const YAML::Node& node)
|
|||
g_lua.pushClassInstance(button);
|
||||
g_lua.pushFunction(funcRef);
|
||||
g_lua.lua_UIButton_setOnClick();
|
||||
} else {
|
||||
throw YAML::Exception(node["onClick"].GetMark(), "failed to parse lua script");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
|
||||
virtual const char *getScriptableName() const { return "UIWindow"; }
|
||||
|
||||
virtual bool isFocusable() const { return true; }
|
||||
|
||||
private:
|
||||
std::string m_title;
|
||||
bool m_moving;
|
||||
|
|
23
src/main.cpp
23
src/main.cpp
|
@ -29,9 +29,8 @@
|
|||
#include <core/platform.h>
|
||||
#include <core/dispatcher.h>
|
||||
#include <ui/uiskins.h>
|
||||
#include "menustate.h"
|
||||
#include "teststate.h"
|
||||
#include <script/luascript.h>
|
||||
#include <ui/uicontainer.h>
|
||||
|
||||
/// Catches signals so we can exit nicely
|
||||
void signal_handler(int sig)
|
||||
|
@ -43,7 +42,7 @@ void signal_handler(int sig)
|
|||
static bool stopping = false;
|
||||
if(!stopping) {
|
||||
stopping = true;
|
||||
g_engine.stop();
|
||||
g_engine.onClose();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -113,26 +112,30 @@ int main(int argc, const char *argv[])
|
|||
|
||||
// init engine
|
||||
g_engine.init();
|
||||
g_engine.enableFpsCounter();
|
||||
|
||||
// load ui skins
|
||||
g_uiSkins.load("skins/tibiaskin.yml");
|
||||
|
||||
// state scope
|
||||
{
|
||||
boost::scoped_ptr<MenuState> initialState(new MenuState);
|
||||
//boost::scoped_ptr<TestState> initialState(new TestState);
|
||||
g_dispatcher.addTask(boost::bind(&Engine::changeState, &g_engine, initialState.get()));
|
||||
// load script modules
|
||||
g_lua.loadAllModules();
|
||||
|
||||
if(!UIContainer::getRootContainer()->getChildCount())
|
||||
logFatal("no ui loaded at all, no reason to continue running");
|
||||
|
||||
Platform::showWindow();
|
||||
//Platform::hideMouseCursor();
|
||||
g_engine.enableFpsCounter();
|
||||
|
||||
// main loop, run everything
|
||||
g_engine.run();
|
||||
|
||||
// poll remaning events
|
||||
g_engine.poll();
|
||||
|
||||
// terminate stuff
|
||||
g_engine.terminate();
|
||||
|
||||
g_uiSkins.terminate();
|
||||
}
|
||||
|
||||
// save configurations before exiting
|
||||
saveConfigs();
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/* 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 <prerequisites.h>
|
||||
#include <core/engine.h>
|
||||
#include <core/dispatcher.h>
|
||||
#include <graphics/framebuffer.h>
|
||||
#include <graphics/graphics.h>
|
||||
#include <graphics/textures.h>
|
||||
#include <graphics/borderedimage.h>
|
||||
#include <graphics/fonts.h>
|
||||
#include <ui/ui.h>
|
||||
#include "menustate.h"
|
||||
#include <script/luascript.h>
|
||||
|
||||
void MenuState::onEnter()
|
||||
{
|
||||
m_background = g_textures.get("background.png");
|
||||
m_background->enableBilinearFilter();
|
||||
|
||||
g_lua.loadFile("modules/mainmenu/mainmenu.lua");
|
||||
}
|
||||
|
||||
void MenuState::onLeave()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MenuState::onClose()
|
||||
{
|
||||
g_engine.stop();
|
||||
}
|
||||
|
||||
bool MenuState::onInputEvent(const InputEvent& event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void MenuState::onResize(const Size& size)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MenuState::render()
|
||||
{
|
||||
// render background
|
||||
static Size minTexCoordsSize(1240, 880);
|
||||
const Size& screenSize = g_graphics.getScreenSize();
|
||||
const Size& texSize = m_background->getSize();
|
||||
Size texCoordsSize = screenSize;
|
||||
if(texCoordsSize < minTexCoordsSize)
|
||||
texCoordsSize.scale(minTexCoordsSize, KEEP_ASPECT_RATIO_BY_EXPANDING);
|
||||
texCoordsSize = texCoordsSize.boundedTo(texSize);
|
||||
Rect texCoords(0, 0, texCoordsSize);
|
||||
texCoords.moveBottomRight(texSize.toPoint());
|
||||
g_graphics.drawTexturedRect(Rect(0, 0, screenSize), m_background, texCoords);
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* 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 MENUSTATE_H
|
||||
#define MENUSTATE_H
|
||||
|
||||
#include <prerequisites.h>
|
||||
#include <core/gamestate.h>
|
||||
#include <graphics/texture.h>
|
||||
#include "protocollogin.h"
|
||||
|
||||
class MenuState : public GameState
|
||||
{
|
||||
|
||||
public:
|
||||
MenuState() { }
|
||||
|
||||
void onEnter();
|
||||
void onLeave();
|
||||
|
||||
void onClose();
|
||||
bool onInputEvent(const InputEvent& event);
|
||||
void onResize(const Size& size);
|
||||
|
||||
void render();
|
||||
|
||||
private:
|
||||
void enterGameButton_clicked();
|
||||
void infoButton_clicked();
|
||||
void optionsButton_clicked();
|
||||
|
||||
void enterGameWindowOkButton_clicked();
|
||||
|
||||
TexturePtr m_background;
|
||||
ProtocolLoginPtr m_protocolLogin;
|
||||
};
|
||||
|
||||
#endif // MENUSTATE_H
|
Loading…
Reference in New Issue