glerminal/source/glerminal-main.cpp

241 lines
5.2 KiB
C++

#include <glerminal.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
extern "C"
{
#include <lualib.h>
#include <lauxlib.h>
}
#include <iostream>
#include <string>
#ifdef _WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <Windows.h>
#define CHANGE_WORKING_DIRECTORY(path) !(SetCurrentDirectory(path))
#else
#include <unistd.h>
#define CHANGE_WORKING_DIRECTORY(path) chdir(path)
#endif
namespace
{
int lglerminal_quit(lua_State* L)
{
glerminal_quit();
return 0;
}
int lglerminal_flush(lua_State* L)
{
glerminal_flush();
return 0;
}
int lglerminal_set(lua_State* L)
{
const unsigned char x = luaL_checkinteger(L, 1) - 1;
const unsigned char y = luaL_checkinteger(L, 2) - 1;
const unsigned char layer = luaL_checkinteger(L, 3) - 1;
const unsigned short sprite = luaL_checkinteger(L, 4) - 1;
glerminal_set(x, y, layer, sprite);
return 0;
}
int lglerminal_get(lua_State* L)
{
const unsigned char x = luaL_checkinteger(L, 1) - 1;
const unsigned char y = luaL_checkinteger(L, 2) - 1;
const unsigned char layer = luaL_checkinteger(L, 3) - 1;
lua_pushnumber(L, glerminal_get(x, y, layer) + 1);
return 1;
}
int lglerminal_offset(lua_State* L)
{
const unsigned char x = luaL_checkinteger(L, 1) - 1;
const unsigned char y = luaL_checkinteger(L, 2) - 1;
const unsigned char layer = luaL_checkinteger(L, 3) - 1;
const float ox = luaL_checknumber(L, 4);
const float oy = luaL_checknumber(L, 5);
glerminal_offset(x, y, layer, ox, oy);
return 0;
}
int lglerminal_layer_color(lua_State* L)
{
const unsigned char x = luaL_checkinteger(L, 1) - 1;
const unsigned char y = luaL_checkinteger(L, 2) - 1;
const unsigned char layer = luaL_checkinteger(L, 3) - 1;
const unsigned int color = luaL_checkinteger(L, 4);
glerminal_color(x, y, layer, color);
return 0;
}
int lglerminal_layer_scale(lua_State* L)
{
const unsigned char x = luaL_checkinteger(L, 1) - 1;
const unsigned char y = luaL_checkinteger(L, 2) - 1;
const unsigned char layer = luaL_checkinteger(L, 3) - 1;
const float scale = luaL_checknumber(L, 4);
glerminal_scale(x, y, layer, scale);
return 0;
}
int lglerminal_load_sprites_file(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
lua_pushboolean(L, glerminal_load_sprites_file(path));
return 1;
}
const luaL_Reg lglerminal_methods[] =
{
{ "quit", lglerminal_quit },
{ "flush", lglerminal_flush },
{ "set", lglerminal_set },
{ "get", lglerminal_get },
{ "offset", lglerminal_offset },
{ "tint", lglerminal_layer_color },
{ "scale", lglerminal_layer_scale },
{ "sprites", lglerminal_load_sprites_file },
{ nullptr, nullptr }
};
int message_handler(lua_State* L)
{
luaL_traceback(L, L, lua_tostring(L, -1), 1);
lua_remove(L, -2);
glerminal_quit();
return true;
}
lua_State* L;
void init()
{
lua_pushcfunction(L, message_handler);
const int handler = lua_gettop(L);
lua_getglobal(L, "glerminal");
lua_getfield(L, -1, "init");
lua_remove(L, -2);
if (lua_pcall(L, 0, 0, handler) != LUA_OK)
{
std::cout << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
lua_remove(L, handler);
}
void mainloop(float dt)
{
lua_pushcfunction(L, message_handler);
const int handler = lua_gettop(L);
lua_getglobal(L, "glerminal");
lua_getfield(L, -1, "main");
lua_remove(L, -2);
lua_pushnumber(L, dt);
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
{
std::cout << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
lua_remove(L, handler);
}
void pressed(int key)
{
const char* const name = glfwGetKeyName(key, 0);
if (name)
{
lua_pushcfunction(L, message_handler);
const int handler = lua_gettop(L);
lua_getglobal(L, "glerminal");
lua_getfield(L, -1, "pressed");
lua_remove(L, -2);
lua_pushstring(L, name);
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
{
std::cout << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
lua_remove(L, handler);
}
}
void released(int key)
{
const char* const name = glfwGetKeyName(key, 0);
if (name)
{
lua_pushcfunction(L, message_handler);
const int handler = lua_gettop(L);
lua_getglobal(L, "glerminal");
lua_getfield(L, -1, "released");
lua_remove(L, -2);
lua_pushstring(L, name);
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
{
std::cout << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1);
}
lua_remove(L, handler);
}
}
}
int main(int argc, char** argv)
{
if (argc == 1)
{
std::cout << "Usage: " << argv[0] << " <project directory>" << std::endl;
return 0;
}
if (CHANGE_WORKING_DIRECTORY(argv[1]))
{
std::cout << "Failed to find project directory" << std::endl;
return 1;
}
L = luaL_newstate();
luaL_openlibs(L);
luaL_newlib(L, lglerminal_methods);
lua_setglobal(L, "glerminal");
lua_pushcfunction(L, message_handler);
const int handler = lua_gettop(L);
if (luaL_loadfile(L, "main.lua") != LUA_OK)
{
const char* str = lua_tostring(L, -1);
std::cout << str << std::endl;
lua_pop(L, 1);
}
else if (lua_pcall(L, 0, LUA_MULTRET, handler) != LUA_OK)
{
const char* str = lua_tostring(L, -1);
std::cout << str << std::endl;
lua_pop(L, 1);
}
else
{
glerminal_run(init, mainloop, pressed, released);
}
lua_close(L);
return 0;
}