diff --git a/application.cpp b/application.cpp index 4f5ac88..a4e1b32 100644 --- a/application.cpp +++ b/application.cpp @@ -56,6 +56,16 @@ void Application::Init(int argc, char* argv[]) { //set the hook for the renderer BaseScene::SetRenderer(renderer); + + //setup lua + lua = luaL_newstate(); + if (!lua) { + std::ostringstream msg; + msg << "Failed to create the lua state"; + throw(std::runtime_error(msg.str())); + } + + luaL_openlibs(lua); } void Application::Proc() { @@ -103,7 +113,9 @@ void Application::Proc() { } void Application::Quit() { - //cleran up after the program + lua_close(lua); + + //clean up after the program BaseScene::SetRenderer(nullptr); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); @@ -125,7 +137,7 @@ void Application::ProcessSceneSignal(SceneSignal signal) { switch(signal) { case SceneSignal::FIRST: case SceneSignal::EXAMPLE_SCENE: - activeScene = new ExampleScene(); + activeScene = new ExampleScene(lua); break; default: { std::ostringstream msg; diff --git a/application.hpp b/application.hpp index 8a7f487..9ec19ca 100644 --- a/application.hpp +++ b/application.hpp @@ -24,6 +24,7 @@ #include "base_scene.hpp" #include "scene_signal.hpp" +#include "lua.hpp" #include "SDL2/SDL.h" //TODO: do something with these @@ -50,4 +51,6 @@ private: //TODO: build a "window" class? SDL_Window* window = nullptr; SDL_Renderer* renderer = nullptr; + + lua_State* lua = nullptr; }; \ No newline at end of file diff --git a/example_scene.cpp b/example_scene.cpp index 33be9ab..8267a15 100644 --- a/example_scene.cpp +++ b/example_scene.cpp @@ -21,8 +21,24 @@ */ #include "example_scene.hpp" -ExampleScene::ExampleScene() { - // +#include + +ExampleScene::ExampleScene(lua_State* L) { + lua = L; + + tileSheet.Load(GetRenderer(), "./rsc/terrain.bmp", 32, 32); + + //set the pager's hook + regionPager.SetLuaState(lua); + + //load the file as a chunk + luaL_loadfile(lua, "./rsc/startup.lua"); + + //push the pager as an arg + lua_pushlightuserdata(lua, static_cast(®ionPager)); + + //run the function + lua_pcall(lua, 1, LUA_MULTRET, 0); } ExampleScene::~ExampleScene() { @@ -46,7 +62,9 @@ void ExampleScene::FrameEnd() { } void ExampleScene::RenderFrame(SDL_Renderer* renderer) { - // + for (std::list::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) { + tileSheet.DrawRegionTo(renderer, &(*it), camera.x, camera.y, camera.scale, camera.scale); + } } //------------------------- @@ -54,11 +72,20 @@ void ExampleScene::RenderFrame(SDL_Renderer* renderer) { //------------------------- void ExampleScene::MouseMotion(SDL_MouseMotionEvent const& event) { - // + //right mouse button moves the camera + if (event.state & SDL_BUTTON_RMASK) { + camera.x -= event.xrel; + camera.y -= event.yrel; + } } void ExampleScene::MouseButtonDown(SDL_MouseButtonEvent const& event) { - // + switch(event.button) { + case SDL_BUTTON_LEFT: + //change the selected tile + regionPager.SetTile((event.x + camera.x) / 32, (event.y + camera.y) / 32, layer, selection); + break; + } } void ExampleScene::MouseButtonUp(SDL_MouseButtonEvent const& event) { diff --git a/example_scene.hpp b/example_scene.hpp index 2f18af1..c9ed5c7 100644 --- a/example_scene.hpp +++ b/example_scene.hpp @@ -22,10 +22,14 @@ #pragma once #include "base_scene.hpp" +#include "region_pager_lua.hpp" +#include "tile_sheet.hpp" + +#include "lua.hpp" class ExampleScene : public BaseScene { public: - ExampleScene(); + ExampleScene(lua_State* L); ~ExampleScene(); void RenderFrame(SDL_Renderer* renderer) override; @@ -43,4 +47,17 @@ private: void MouseWheel(SDL_MouseWheelEvent const& event) override; void KeyDown(SDL_KeyboardEvent const& event) override; void KeyUp(SDL_KeyboardEvent const& event) override; + + //members + lua_State* lua = nullptr; + RegionPagerLua regionPager; + TileSheet tileSheet; + struct { + int x = 0; + int y = 0; + double scale = 1.0; + } camera; + + int selection = 1; + int layer = 0; }; diff --git a/libmap/region_pager_api.cpp b/libmap/region_pager_api.cpp index fd366db..10eaf95 100644 --- a/libmap/region_pager_api.cpp +++ b/libmap/region_pager_api.cpp @@ -104,6 +104,8 @@ static int unloadRegion(lua_State* L) { return 0; } +//TODO: check that parameters are not null + static int setOnLoad(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); luaL_unref(L, LUA_REGISTRYINDEX, pager->GetLoadReference()); diff --git a/libmap/region_pager_base.cpp b/libmap/region_pager_base.cpp index 857dabd..24b2858 100644 --- a/libmap/region_pager_base.cpp +++ b/libmap/region_pager_base.cpp @@ -28,6 +28,8 @@ RegionPagerBase::~RegionPagerBase() { UnloadAll(); }; +//TODO: add nullptr checks to the calls to GetRegion() + Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) { Region* ptr = GetRegion(x, y); return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v); diff --git a/libmap/region_pager_lua.hpp b/libmap/region_pager_lua.hpp index 0b64b0a..3789ff0 100644 --- a/libmap/region_pager_lua.hpp +++ b/libmap/region_pager_lua.hpp @@ -28,6 +28,8 @@ #include #include +//NOTE: set the lua hook before use + class RegionPagerLua : public RegionPagerBase { public: RegionPagerLua() = default; diff --git a/linit.cpp b/linit.cpp new file mode 100644 index 0000000..bf54db3 --- /dev/null +++ b/linit.cpp @@ -0,0 +1,67 @@ +/* +** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $ +** Initialization of libraries for lua.c and other clients +** See Copyright Notice in lua.h +*/ +/* +** If you embed Lua in your program and need to open the standard +** libraries, call luaL_openlibs in your program. If you need a +** different set of libraries, copy this file to your project and edit +** it to suit your needs. +*/ + + +#define linit_c +#define LUA_LIB + +#include "lua.hpp" + +#include "region_api.hpp" +#include "region_pager_api.hpp" + +/* +** these libs are loaded by lua.c and are readily available to any Lua +** program +*/ +static const luaL_Reg loadedlibs[] = { + {"_G", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_BITLIBNAME, luaopen_bit32}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + + //custom stuff + {TORTUGA_REGION_API, openRegionAPI}, + {TORTUGA_REGION_PAGER_API, openRegionPagerAPI}, + {NULL, NULL} +}; + +/* +** these libs are preloaded and must be required before used +*/ +static const luaL_Reg preloadedlibs[] = { + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib; + /* call open functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } + /* add open functions from 'preloadedlibs' into 'package.preload' table */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + for (lib = preloadedlibs; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_setfield(L, -2, lib->name); + } + lua_pop(L, 1); /* remove _PRELOAD table */ +} + diff --git a/makefile b/makefile index 180faa3..11ac490 100644 --- a/makefile +++ b/makefile @@ -1,3 +1,7 @@ +#NOTE: I know it's a wonky spot, sue me +debug: export CXXFLAGS+=-g +debug: clean all + #include directories INCLUDES+=. common libmap @@ -8,6 +12,10 @@ ifeq ($(OS),Windows_NT) LIBS+=-lmingw32 endif LIBS+=-lSDL2main -lSDL2 -lSDL2_image -llua +ifeq ($(shell uname), Linux) + #I don't know what this does, but Ubuntu needs it (dynamic linking for lua) + LIBS+=-ldl +endif #flags CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/rsc/startup.lua b/rsc/startup.lua new file mode 100644 index 0000000..f03e295 --- /dev/null +++ b/rsc/startup.lua @@ -0,0 +1,25 @@ +--args are: userdata RegionPagerLua; + +print("Running startup script") + +pager = ... + +---[[ + +--BUG: RegionPagerLua fails without these +region_pager.SetOnLoad(pager, function(r) + print("Calling SetOnLoad's lambda") +end) +region_pager.SetOnSave(pager, function(r) + print("Calling SetOnSave's lambda") +end) +region_pager.SetOnCreate(pager, function(r) + print("Calling SetOnCreate's lambda") +end) +region_pager.SetOnUnload(pager, function(r) + print("Calling SetOnUnload's lambda") +end) + +--]] + +print("Finished startup script") \ No newline at end of file diff --git a/rsc/terrain.bmp b/rsc/terrain.bmp new file mode 100644 index 0000000..0a39c74 Binary files /dev/null and b/rsc/terrain.bmp differ