Files
mini/source/lua.cpp

1489 lines
65 KiB
C++

#include "lua.h"
#include "lua/lua.hpp"
#include "lua.debug.h"
#include "mini.h"
#include "jfile.h"
#include "log.h"
#include <filesystem>
#include <algorithm>
#include <vector>
#include <stack>
#include <set>
#include <unordered_map>
#include <string>
#include <mutex>
#include <queue>
#include <thread>
#include <atomic>
#include <iostream>
#include <nlohmann/json.hpp>
//extern "C" {
namespace mini
{
namespace lua
{
lua_State *L;
bool is_playing = false;
bool init_exists = false;
bool update_exists = false;
namespace wrappers
{
namespace surf
{
static int create(lua_State *L) {
int w = luaL_checknumber(L, 1);
int h = luaL_checknumber(L, 2);
uint8_t s = mini::surf::create(w, h);
if (s==255) {
luaL_error(L, "Error while creating new surface: Max surfaces reached");
return 0;
}
lua_pushinteger(L, s);
return 1;
}
static int load(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
uint8_t s = mini::surf::load(str);
if (s==255) {
luaL_error(L, "Error while loading surface: Max surfaces reached");
return 0;
}
lua_pushinteger(L, s);
return 1;
}
static int loadex(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
uint8_t s = mini::surf::load(str, true);
if (s==255) {
luaL_error(L, "Error while loading surface: Max surfaces reached");
return 0;
}
lua_pushinteger(L, s);
return 1;
}
static int save(lua_State *L) {
uint8_t surface = luaL_checkinteger(L, 1);
const char* str = luaL_checkstring(L, 2);
if (lua_istable(L, -1)) {
const int len = SDL_min(256, lua_rawlen(L, -1));
uint8_t *pal = (uint8_t*)malloc(len*3);
uint8_t *p=pal;
for (int i=1;i<=len;++i) {
lua_rawgeti(L, -1, i);
lua_getfield(L, -1, "r");
*(p++) = luaL_checknumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "g");
*(p++) = luaL_checknumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "b");
*(p++) = luaL_checknumber(L, -1);
lua_pop(L, 1);
lua_pop(L, 1);
//pal[i-1] = (r<<16)+(g<<8)+b;
}
mini::surf::save(surface, str, pal, len);
} else {
mini::surf::save(surface, str, nullptr);
}
return 0;
}
static int free(lua_State *L) {
uint8_t surface = luaL_checkinteger(L, 1);
mini::surf::destroy(surface);
return 0;
}
static int size(lua_State *L) {
uint8_t surface = luaL_checkinteger(L, 1);
lua_pushinteger(L, mini::surf::width(surface));
lua_pushinteger(L, mini::surf::height(surface));
return 2;
}
static int target(lua_State *L) {
const int numargs = lua_gettop(L);
switch (numargs) {
case 0: {
lua_pushinteger(L, mini::surf::target::get());
return 1;
}
case 1: {
uint8_t surface = luaL_checkinteger(L, 1);
mini::surf::target::set(surface);
return 0;
}
default:
return luaL_error(L, "Function 'surface.target' Unexpected number of parameters.");
};
}
static int source(lua_State *L) {
const int numargs = lua_gettop(L);
switch (numargs) {
case 0: {
lua_pushinteger(L, mini::surf::source::get());
return 1;
}
case 1: {
uint8_t surface = luaL_checkinteger(L, 1);
mini::surf::source::set(surface);
return 0;
}
default:
return luaL_error(L, "Function 'surface.source' Unexpected number of parameters.");
};
}
static int cls(lua_State *L) {
uint8_t color = luaL_optinteger(L, 1, 0);
mini::surf::cls(color);
return 0;
}
static int pixel(lua_State *L) {
if (lua_gettop(L)==2) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
lua_pushinteger(L, mini::surf::pixel::get(x, y));
return 1;
} else {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
uint8_t color = luaL_checkinteger(L, 3);
mini::surf::pixel::set(x, y, color);
return 0;
}
}
}
namespace map
{
static int surf(lua_State *L) {
if (lua_gettop(L)==1) {
uint8_t surface = luaL_checkinteger(L, 1);
mini::map::surf::set(surface);
} else {
lua_pushinteger(L, mini::map::surf::get());
return 1;
}
return 0;
}
static int draw(lua_State *L) {
mini::map::draw();
return 0;
}
static int tile(lua_State *L) {
if (lua_gettop(L)==2) {
int celx = luaL_checknumber(L, 1);
int cely = luaL_checknumber(L, 2);
lua_pushinteger(L, mini::map::tile::get(celx, cely));
return 1;
} else {
int celx = luaL_checknumber(L, 1);
int cely = luaL_checknumber(L, 2);
uint8_t snum = luaL_checkinteger(L, 3);
mini::map::tile::set(celx, cely, snum);
return 0;
}
}
static int cell(lua_State *L) {
if (lua_gettop(L)==2) {
int celx = luaL_checknumber(L, 1);
int cely = luaL_checknumber(L, 2);
mini::map::cell::set(celx, cely);
return 0;
} else {
lua_pushinteger(L, mini::map::cell::getw());
lua_pushinteger(L, mini::map::cell::geth());
return 2;
}
}
}
namespace pal
{
static int load(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
uint16_t size;
uint32_t *pal = mini::pal::load(str, &size);
lua_createtable(L, 2, 0);
for (int i=0;i<size;++i) {
uint32_t color = pal[i];
lua_createtable(L, 0, 3);
lua_pushinteger(L, (color>>16)&0xff);
lua_setfield(L, -2, "r");
lua_pushinteger(L, (color>>8)&0xff);
lua_setfield(L, -2, "g");
lua_pushinteger(L, color&0xff);
lua_setfield(L, -2, "b");
lua_rawseti(L, -2, i+1);
}
free(pal);
return 1;
}
static int set(lua_State *L) {
int r,g,b;
if (lua_istable(L, -1)) {
uint32_t pal[256];
const int len = SDL_min(256, lua_rawlen(L, -1));
for (int i=0;i<len;++i) {
lua_rawgeti(L, -1, i+1);
lua_getfield(L, -1, "r");
r = luaL_checknumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "g");
g = luaL_checknumber(L, -1);
lua_pop(L, 1);
lua_getfield(L, -1, "b");
b = luaL_checknumber(L, -1);
lua_pop(L, 1);
lua_pop(L, 1);
pal[i] = (r<<16)+(g<<8)+b;
}
mini::pal::set(pal);
}
return 0;
}
static int color(lua_State *L) {
//if (lua_gettop(L) != 1) return luaL_error(L, "Function 'mini.palette.getColor' Unexpected number of parameters.");
if (lua_gettop(L) == 1) {
uint8_t index = luaL_checkinteger(L, 1);
uint32_t color = mini::pal::color::get(index);
lua_pushinteger(L, (color>>16)&0xff);
lua_pushinteger(L, (color>>8)&0xff);
lua_pushinteger(L, color&0xff);
return 3;
} else {
uint8_t index = luaL_checkinteger(L, 1);
uint8_t r = luaL_checkinteger(L, 2);
uint8_t g = luaL_optinteger(L, 3, 0);
uint8_t b = luaL_optinteger(L, 4, 0);
uint32_t color = (r<<16) + (g<<8) + b;
mini::pal::color::set(index, color);
return 0;
}
}
static int trans(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushinteger(L, mini::pal::trans::get());
return 1;
} else {
uint8_t index = luaL_checkinteger(L, 1);
mini::pal::trans::set(index);
return 0;
}
}
static int subpal(lua_State *L) {
const int num_params = lua_gettop(L);
uint8_t index, index2, color;
switch (num_params) {
case 0:
mini::pal::subpal::reset();
break;
case 1:
index = luaL_checkinteger(L, 1);
lua_pushinteger(L, mini::pal::subpal::set(index,index));
return 1;
break;
case 2:
index = luaL_checkinteger(L, 1);
color = luaL_checkinteger(L, 2);
lua_pushinteger(L, mini::pal::subpal::set(index, color));
return 1;
break;
case 3:
index = luaL_checkinteger(L, 1);
index2 = luaL_checkinteger(L, 2);
color = luaL_checkinteger(L, 3);
for (int i=index;i<=index2;++i) mini::pal::subpal::set(i, color);
break;
}
return 0;
}
}
namespace view
{
static int clip(lua_State *L) {
if (lua_gettop(L)==0) {
mini::view::clip::reset();
return 0;
} else {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int w = luaL_checknumber(L, 3);
int h = luaL_checknumber(L, 4);
mini::view::clip::set(x, y, w, h);
return 0;
}
}
static int origin(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushinteger(L, mini::view::origin::getx());
lua_pushinteger(L, mini::view::origin::gety());
return 2;
} else {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
mini::view::origin::set(x, y);
return 0;
}
}
static int tolocal(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
lua_pushinteger(L, x+mini::view::origin::getx());
lua_pushinteger(L, y+mini::view::origin::gety());
return 2;
}
}
namespace draw
{
static int line(lua_State *L) {
int x0 = luaL_checknumber(L, 1);
int y0 = luaL_checknumber(L, 2);
int x1 = luaL_checknumber(L, 3);
int y1 = luaL_checknumber(L, 4);
uint8_t color = luaL_checkinteger(L, 5);
mini::draw::line(x0, y0, x1, y1, color);
return 0;
}
static int hline(lua_State *L) {
int x0 = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int x1 = luaL_checknumber(L, 3);
uint8_t color = luaL_checkinteger(L, 4);
mini::draw::hline(x0, y, x1, color);
return 0;
}
static int vline(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y0 = luaL_checknumber(L, 2);
int y1 = luaL_checknumber(L, 3);
uint8_t color = luaL_checkinteger(L, 4);
mini::draw::vline(x, y0, y1, color);
return 0;
}
static int rect(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int w = luaL_checknumber(L, 3);
int h = luaL_checknumber(L, 4);
uint8_t color = luaL_checkinteger(L, 5);
mini::draw::rect(x, y, w, h, color);
return 0;
}
static int rectf(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int w = luaL_checknumber(L, 3);
int h = luaL_checknumber(L, 4);
uint8_t color = luaL_checkinteger(L, 5);
mini::draw::rectf(x, y, w, h, color);
return 0;
}
static int circ(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int r = luaL_optnumber(L, 3, 4);
uint8_t color = luaL_checkinteger(L, 4);
mini::draw::circ(x, y, r, color);
return 0;
}
static int circf(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int r = luaL_optnumber(L, 3, 4);
uint8_t color = luaL_checkinteger(L, 4);
mini::draw::circf(x, y, r, color);
return 0;
}
static int roundrect(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int w = luaL_checknumber(L, 3);
int h = luaL_checknumber(L, 4);
int r = luaL_optnumber(L, 5, 4);
uint8_t color = luaL_checkinteger(L, 6);
mini::draw::roundrect(x, y, w, h, r, color);
return 0;
}
static int roundrectf(lua_State *L) {
int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2);
int w = luaL_checknumber(L, 3);
int h = luaL_checknumber(L, 4);
int r = luaL_optnumber(L, 5, 4);
uint8_t color = luaL_checkinteger(L, 6);
mini::draw::roundrectf(x, y, w, h, r, color);
return 0;
}
static int oval(lua_State *L) {
int x0 = luaL_checknumber(L, 1);
int y0 = luaL_checknumber(L, 2);
int x1 = luaL_checknumber(L, 3);
int y1 = luaL_checknumber(L, 4);
uint8_t color = luaL_checkinteger(L, 5);
mini::draw::oval(x0, y0, x1, y1, color);
return 0;
}
static int ovalf(lua_State *L) {
int x0 = luaL_checknumber(L, 1);
int y0 = luaL_checknumber(L, 2);
int x1 = luaL_checknumber(L, 3);
int y1 = luaL_checknumber(L, 4);
uint8_t color = luaL_checkinteger(L, 5);
mini::draw::ovalf(x0, y0, x1, y1, color);
return 0;
}
static int pattern(lua_State *L) {
if (lua_gettop(L) == 0) {
mini::draw::pattern::set(0xffff);
} else {
uint16_t pat = luaL_checkinteger(L, 1);
bool transparent = lua_toboolean(L, 2);
mini::draw::pattern::set(pat, transparent);
}
return 0;
}
static int surf(lua_State *L) {
int sx = luaL_checknumber(L, 1);
int sy = luaL_checknumber(L, 2);
int sw = luaL_checknumber(L, 3);
int sh = luaL_checknumber(L, 4);
int dx = luaL_checknumber(L, 5);
int dy = luaL_checknumber(L, 6);
int dw = luaL_optnumber(L, 7, 0);
int dh = luaL_optnumber(L, 8, 0);
bool flip_x = lua_toboolean(L, 9);
bool flip_y = lua_toboolean(L, 10);
bool invert = lua_toboolean(L, 11);
mini::draw::surf(sx, sy, sw, sh, dx, dy, dw, dh, flip_x, flip_y, invert);
return 0;
}
static int surfrot(lua_State *L) {
int sx = luaL_checknumber(L, 1);
int sy = luaL_checknumber(L, 2);
int sw = luaL_checknumber(L, 3);
int sh = luaL_checknumber(L, 4);
int dx = luaL_checknumber(L, 5);
int dy = luaL_checknumber(L, 6);
float a = luaL_checknumber(L, 7);
int dw = luaL_optnumber(L, 8, 0);
int dh = luaL_optnumber(L, 9, 0);
bool flip_x = lua_toboolean(L, 10);
bool flip_y = lua_toboolean(L, 11);
mini::draw::surfrot(sx, sy, sw, sh, dx, dy, dw, dh, flip_x, flip_y, a);
return 0;
}
static int text(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
uint8_t color = luaL_checkinteger(L, 4);
mini::draw::text(str, x, y, color);
return 0;
}
static int mode(lua_State *L) {
int mode = luaL_checknumber(L, 1);
mini::draw::mode::set(mode);
return 0;
}
}
namespace shader
{
static int init(lua_State *L) {
const char* vstr = luaL_optstring(L, 1, NULL);
const char* fstr = luaL_optstring(L, 2, NULL);
mini::shader::init(vstr, fstr);
return 0;
}
static int enable(lua_State *L) {
mini::shader::enable();
return 0;
}
static int disable(lua_State *L) {
mini::shader::disable();
return 0;
}
}
namespace music
{
static int play(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
const int loop = luaL_optinteger(L, 2, -1);
mini::audio::music::play(str, loop);
return 0;
}
static int pause(lua_State *L) {
mini::audio::music::pause();
return 0;
}
static int resume(lua_State *L) {
mini::audio::music::resume();
return 0;
}
static int stop(lua_State *L) {
const int time = luaL_optinteger(L, 1, 1000);
mini::audio::music::stop(time);
return 0;
}
static int pos(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushnumber(L, mini::audio::music::pos::get());
return 1;
} else {
mini::audio::music::pos::set(luaL_checknumber(L, 1));
return 0;
}
}
static int enable(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushboolean(L, mini::audio::music::enable::get());
return 1;
} else {
mini::audio::music::enable::set(lua_toboolean(L, 1));
return 0;
}
}
}
namespace sound
{
static int load(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
lua_pushinteger(L, mini::audio::sound::load(str));
return 1;
}
static int free(lua_State *L) {
const int sound = luaL_checknumber(L, 1);
mini::audio::sound::free(sound);
return 0;
}
static int play(lua_State *L) {
const int sound = luaL_checknumber(L, 1);
const int volume = luaL_optinteger(L, 2, -1);
lua_pushinteger(L, mini::audio::sound::play(sound, volume));
return 1;
}
static int stop(lua_State *L) {
const int sound = luaL_checknumber(L, 1);
mini::audio::sound::stop(sound);
return 0;
}
static int enable(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushboolean(L, mini::audio::sound::enable::get());
return 1;
} else {
mini::audio::sound::enable::set(lua_toboolean(L, 1));
return 0;
}
}
}
namespace sys
{
static int delta(lua_State *L) {
lua_pushnumber(L, mini::sys::delta());
return 1;
}
static int time(lua_State *L) {
lua_pushnumber(L, mini::sys::time());
return 1;
}
static uint32_t chrono_time = 0;
static int chrono(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushnumber(L, float(SDL_GetTicks()-chrono_time)/1000.0f);
return 1;
} else {
chrono_time = SDL_GetTicks();
return 0;
}
}
static int beat(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushboolean(L, mini::sys::beat(-1));
return 1;
} else {
int16_t beats = luaL_optnumber(L, 1, -1);
mini::sys::beat(beats);
return 0;
}
}
static int update(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushinteger(L, mini::sys::update::get());
return 1;
} else {
int mode = luaL_checknumber(L, 1);
int interval = luaL_optinteger(L, 2, 0);
mini::sys::update::set(mode, interval);
return 0;
}
}
namespace fs = std::filesystem;
static int dir(lua_State *L) {
std::string path = "./data";
if (lua_gettop(L) > 0) path = luaL_checkstring(L, 1);
// Collect entries
std::vector<fs::directory_entry> entries;
for (const auto& entry : fs::directory_iterator(path)) {
entries.push_back(entry);
}
// Sort: directories first, then files; both alphabetically
std::sort(entries.begin(), entries.end(),
[](const fs::directory_entry& a, const fs::directory_entry& b) {
bool adir = a.is_directory();
bool bdir = b.is_directory();
if (adir != bdir) return adir > bdir; // directories before files
return a.path().filename().string() < b.path().filename().string();
});
// Build Lua table
lua_newtable(L);
int i = 1;
for (const auto& entry : entries) {
lua_newtable(L);
// name field (canonical absolute path)
lua_pushstring(L, (const char*)fs::canonical(entry.path()).u8string().c_str());
lua_setfield(L, -2, "name");
// dir field
lua_pushboolean(L, entry.is_directory());
lua_setfield(L, -2, "dir");
lua_rawseti(L, -2, i++);
}
return 1;
}
static int exit(lua_State *L) {
mini::sys::exit();
return 0;
}
static int fps(lua_State *L) {
lua_pushnumber(L, mini::sys::getfps());
return 1;
}
static int debug(lua_State *L) {
#ifdef DEBUG
lua_pushboolean(L, true);
#else
lua_pushboolean(L, false);
#endif
return 1;
}
static int clipboard(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushstring(L, SDL_GetClipboardText());
return 1;
} else {
const char* value = luaL_checkstring(L, 1);
SDL_SetClipboardText(value);
return 0;
}
}
static int version(lua_State *L) {
lua_pushstring(L, MINI_VERSION);
return 1;
}
}
namespace win
{
static int zoom(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushinteger(L, mini::win::zoom::get());
return 1;
} else {
const int value = luaL_optinteger(L, 1, 0);
mini::win::zoom::set(value);
return 0;
}
}
static int fullscreen(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushboolean(L, mini::win::fullscreen::get());
return 1;
} else {
mini::win::fullscreen::set(lua_toboolean(L, 1));
return 0;
}
}
static int cursor(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushboolean(L, mini::win::cursor::get());
return 1;
} else {
mini::win::cursor::set(lua_toboolean(L, 1));
return 0;
}
}
static int res(lua_State *L) {
if (lua_gettop(L) == 0) {
lua_pushinteger(L, mini::win::res::getw());
lua_pushinteger(L, mini::win::res::geth());
return 2;
} else {
const int w = luaL_optinteger(L, 1, 160);
const int h = luaL_optinteger(L, 2, 120);
mini::win::res::set(w, h);
return 0;
}
}
}
namespace conf
{
static int key(lua_State *L) {
const char* key = luaL_checkstring(L, 1);
if (lua_gettop(L) > 1) {
const char* value = luaL_checkstring(L, 2);
mini::config::key::set(key, value);
return 0;
} else {
const char* value = mini::config::key::get(key);
if (value==NULL) {
lua_pushnil(L);
} else {
lua_pushstring(L, value);
}
return 1;
}
}
static int folder(lua_State *L) {
lua_pushstring(L, mini::config::folder());
return 1;
}
}
namespace font
{
static int load(lua_State *L) {
const char* str = luaL_checkstring(L, 1);
uint8_t s = mini::font::load(str);
if (s==255) {
luaL_error(L, "Error while loading font: Max fonts reached");
return 0;
}
lua_pushinteger(L, s);
return 1;
}
static int current(lua_State *L) {
const int numargs = lua_gettop(L);
switch (numargs) {
case 0: {
lua_pushinteger(L, mini::font::current::get());
return 1;
}
case 1: {
uint8_t font = luaL_checkinteger(L, 1);
mini::font::current::set(font);
return 0;
}
default:
return luaL_error(L, "Function 'font.current' Unexpected number of parameters.");
};
}
static int spacing(lua_State *L) {
const int numargs = lua_gettop(L);
switch (numargs) {
case 0: {
lua_pushinteger(L, mini::font::spacing::get());
return 1;
}
case 1: {
uint8_t spacing = luaL_checkinteger(L, 1);
mini::font::spacing::set(spacing);
return 0;
}
default:
return luaL_error(L, "Function 'font.spacing' Unexpected number of parameters.");
};
}
}
namespace mouse
{
static int pos(lua_State *L) {
lua_pushinteger(L, mini::mouse::posx());
lua_pushinteger(L, mini::mouse::posy());
return 2;
}
static int wheel(lua_State *L) {
lua_pushinteger(L, mini::mouse::wheel());
return 1;
}
static int down(lua_State *L) {
uint8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, mini::mouse::down(i));
return 1;
}
static int press(lua_State *L) {
uint8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, mini::mouse::press(i));
return 1;
}
static int dblclick(lua_State *L) {
lua_pushboolean(L, mini::mouse::dblclick());
return 1;
}
static int discard(lua_State *L) {
mini::mouse::discard();
return 0;
}
static int inside(lua_State *L) {
int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2);
int w = luaL_checkinteger(L, 3);
int h = luaL_checkinteger(L, 4);
lua_pushboolean(L, mini::mouse::inside(x,y,w,h));
return 1;
}
}
namespace key
{
static int down(lua_State *L) {
uint8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, mini::key::down(i));
return 1;
}
static int press(lua_State *L) {
if (lua_gettop(L) >=1 ) {
uint8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, mini::key::press(i));
} else {
lua_pushinteger(L, mini::key::press());
}
return 1;
}
static int any(lua_State *L) {
lua_pushboolean(L, mini::key::any());
return 1;
}
static int text(lua_State *L) {
mini::key::text(lua_toboolean(L, 1));
return 0;
}
static int utf8char(lua_State *L) {
lua_pushstring(L, mini::key::utf8char());
return 1;
}
}
namespace pad
{
static int down(lua_State *L) {
int8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, mini::pad::down(i));
return 1;
}
static int press(lua_State *L) {
if (lua_gettop(L) >=1 ) {
int8_t i = luaL_checkinteger(L, 1);
lua_pushboolean(L, mini::pad::press(i));
} else {
lua_pushinteger(L, mini::pad::press());
}
return 1;
}
static int any(lua_State *L) {
lua_pushinteger(L, mini::pad::press());
return 1;
}
}
}
}
}
static int cpp_utf8_sub(lua_State *L) {
size_t slen;
const char *s = luaL_checklstring(L, 1, &slen);
int i = luaL_checkinteger(L, 2);
int j = luaL_optinteger(L, 3, -1);
// Get utf8.offset
lua_getglobal(L, "utf8");
lua_getfield(L, -1, "offset");
// Compute start byte index
lua_pushvalue(L, 1); // string
lua_pushinteger(L, i); // start index
lua_call(L, 2, 1); // utf8.offset(s, i)
lua_Integer start = lua_tointeger(L, -1);
lua_pop(L, 1);
if (start == 0) {
lua_pushliteral(L, "");
lua_pop(L, 1); // pop utf8 table
return 1;
}
// Compute end byte index (j+1)
lua_getfield(L, -1, "offset");
lua_pushvalue(L, 1);
lua_pushinteger(L, j + 1);
lua_call(L, 2, 1);
lua_Integer end = lua_tointeger(L, -1);
lua_pop(L, 2); // pop result + utf8 table
if (end == 0) {
// until end of string
lua_pushlstring(L, s + start - 1, slen - (start - 1));
return 1;
}
lua_pushlstring(L, s + start - 1, (end - 1) - (start - 1));
return 1;
}
namespace mini
{
namespace lua
{
bool running() {
debug::process_commands(L);
return is_playing;
}
void push_functions() {
lua_newtable(L);
lua_setglobal(L, "mini");
lua_newtable(L);
lua_pushcfunction(L,wrappers::surf::create); lua_setfield(L, -2, "new");
lua_pushcfunction(L,wrappers::surf::load); lua_setfield(L, -2, "load");
lua_pushcfunction(L,wrappers::surf::loadex); lua_setfield(L, -2, "loadex");
lua_pushcfunction(L,wrappers::surf::save); lua_setfield(L, -2, "save");
lua_pushcfunction(L,wrappers::surf::free); lua_setfield(L, -2, "free");
lua_pushcfunction(L,wrappers::surf::size); lua_setfield(L, -2, "size");
lua_pushcfunction(L,wrappers::surf::target); lua_setfield(L, -2, "target");
lua_pushcfunction(L,wrappers::surf::source); lua_setfield(L, -2, "source");
lua_pushcfunction(L,wrappers::surf::cls); lua_setfield(L, -2, "cls");
lua_pushcfunction(L,wrappers::surf::pixel); lua_setfield(L, -2, "pixel");
lua_pushinteger(L, 0); lua_setfield(L, -2, "SCREEN");
lua_setglobal(L, "surf");
lua_newtable(L);
lua_pushcfunction(L,wrappers::map::surf); lua_setfield(L, -2, "surf");
lua_pushcfunction(L,wrappers::map::draw); lua_setfield(L, -2, "draw");
lua_pushcfunction(L,wrappers::map::tile); lua_setfield(L, -2, "tile");
lua_pushcfunction(L,wrappers::map::cell); lua_setfield(L, -2, "cell");
lua_setglobal(L, "map");
lua_newtable(L);
lua_pushcfunction(L,wrappers::pal::load); lua_setfield(L, -2, "load");
lua_pushcfunction(L,wrappers::pal::set); lua_setfield(L, -2, "set");
lua_pushcfunction(L,wrappers::pal::color); lua_setfield(L, -2, "color");
lua_pushcfunction(L,wrappers::pal::trans); lua_setfield(L, -2, "trans");
lua_pushcfunction(L,wrappers::pal::subpal); lua_setfield(L, -2, "subpal");
lua_setglobal(L, "pal");
lua_newtable(L);
lua_pushcfunction(L,wrappers::view::clip); lua_setfield(L, -2, "clip");
lua_pushcfunction(L,wrappers::view::origin); lua_setfield(L, -2, "origin");
lua_pushcfunction(L,wrappers::view::tolocal); lua_setfield(L, -2, "tolocal");
lua_setglobal(L, "view");
lua_newtable(L);
lua_pushcfunction(L,wrappers::draw::line); lua_setfield(L, -2, "line");
lua_pushcfunction(L,wrappers::draw::hline); lua_setfield(L, -2, "hline");
lua_pushcfunction(L,wrappers::draw::vline); lua_setfield(L, -2, "vline");
lua_pushcfunction(L,wrappers::draw::rect); lua_setfield(L, -2, "rect");
lua_pushcfunction(L,wrappers::draw::rectf); lua_setfield(L, -2, "rectf");
lua_pushcfunction(L,wrappers::draw::circ); lua_setfield(L, -2, "circ");
lua_pushcfunction(L,wrappers::draw::circf); lua_setfield(L, -2, "circf");
lua_pushcfunction(L,wrappers::draw::roundrect); lua_setfield(L, -2, "rrect");
lua_pushcfunction(L,wrappers::draw::roundrectf); lua_setfield(L, -2, "rrectf");
lua_pushcfunction(L,wrappers::draw::oval); lua_setfield(L, -2, "oval");
lua_pushcfunction(L,wrappers::draw::ovalf); lua_setfield(L, -2, "ovalf");
lua_pushcfunction(L,wrappers::draw::pattern); lua_setfield(L, -2, "pattern");
lua_pushcfunction(L,wrappers::draw::surf); lua_setfield(L, -2, "surf");
lua_pushcfunction(L,wrappers::draw::surfrot); lua_setfield(L, -2, "surfrot");
lua_pushcfunction(L,wrappers::draw::text); lua_setfield(L, -2, "text");
lua_pushcfunction(L,wrappers::draw::mode); lua_setfield(L, -2, "mode");
lua_pushinteger(L, 0); lua_setfield(L, -2, "NORMAL");
lua_pushinteger(L, 1); lua_setfield(L, -2, "PATTERN");
lua_pushinteger(L, 2); lua_setfield(L, -2, "AND");
lua_pushinteger(L, 3); lua_setfield(L, -2, "OR");
lua_pushinteger(L, 4); lua_setfield(L, -2, "XOR");
lua_pushinteger(L, 5); lua_setfield(L, -2, "NOT");
lua_setglobal(L, "draw");
lua_newtable(L);
lua_pushcfunction(L,wrappers::shader::init); lua_setfield(L, -2, "init");
lua_pushcfunction(L,wrappers::shader::enable); lua_setfield(L, -2, "enable");
lua_pushcfunction(L,wrappers::shader::disable); lua_setfield(L, -2, "disable");
lua_setglobal(L, "shader");
lua_newtable(L);
lua_pushcfunction(L,wrappers::music::play); lua_setfield(L, -2, "play");
lua_pushcfunction(L,wrappers::music::pause); lua_setfield(L, -2, "pause");
lua_pushcfunction(L,wrappers::music::resume); lua_setfield(L, -2, "resume");
lua_pushcfunction(L,wrappers::music::stop); lua_setfield(L, -2, "stop");
lua_pushcfunction(L,wrappers::music::pos); lua_setfield(L, -2, "pos");
lua_pushcfunction(L,wrappers::music::enable); lua_setfield(L, -2, "enabled");
lua_setglobal(L, "music");
lua_newtable(L);
lua_pushcfunction(L,wrappers::sound::load); lua_setfield(L, -2, "load");
lua_pushcfunction(L,wrappers::sound::free); lua_setfield(L, -2, "free");
lua_pushcfunction(L,wrappers::sound::play); lua_setfield(L, -2, "play");
lua_pushcfunction(L,wrappers::sound::stop); lua_setfield(L, -2, "stop");
lua_pushcfunction(L,wrappers::sound::enable); lua_setfield(L, -2, "enabled");
lua_setglobal(L, "sound");
lua_newtable(L);
lua_pushcfunction(L,wrappers::sys::delta); lua_setfield(L, -2, "delta");
lua_pushcfunction(L,wrappers::sys::time); lua_setfield(L, -2, "time");
lua_pushcfunction(L,wrappers::sys::chrono); lua_setfield(L, -2, "chrono");
lua_pushcfunction(L,wrappers::sys::beat); lua_setfield(L, -2, "beat");
lua_pushcfunction(L,wrappers::sys::update); lua_setfield(L, -2, "update");
lua_pushcfunction(L,wrappers::sys::dir); lua_setfield(L, -2, "dir");
lua_pushcfunction(L,wrappers::sys::exit); lua_setfield(L, -2, "quit");
lua_pushcfunction(L,wrappers::sys::fps); lua_setfield(L, -2, "fps");
lua_pushcfunction(L,wrappers::sys::debug); lua_setfield(L, -2, "debug");
lua_pushcfunction(L,wrappers::sys::clipboard); lua_setfield(L, -2, "clipboard");
lua_pushcfunction(L,wrappers::sys::version); lua_setfield(L, -2, "version");
lua_pushinteger(L, 0); lua_setfield(L, -2, "UPDATE_ALWAYS");
lua_pushinteger(L, 1); lua_setfield(L, -2, "UPDATE_WAIT");
lua_pushinteger(L, 2); lua_setfield(L, -2, "UPDATE_TIMEOUT");
lua_setglobal(L, "sys");
lua_newtable(L);
lua_pushcfunction(L,wrappers::win::zoom); lua_setfield(L, -2, "zoom");
lua_pushcfunction(L,wrappers::win::fullscreen); lua_setfield(L, -2, "fullscreen");
lua_pushcfunction(L,wrappers::win::cursor); lua_setfield(L, -2, "cursor");
lua_pushcfunction(L,wrappers::win::res); lua_setfield(L, -2, "res");
lua_setglobal(L, "win");
lua_newtable(L);
lua_pushcfunction(L,wrappers::conf::key); lua_setfield(L, -2, "key");
lua_pushcfunction(L,wrappers::conf::folder); lua_setfield(L, -2, "folder");
lua_setglobal(L, "config");
lua_newtable(L);
lua_pushcfunction(L,wrappers::font::load); lua_setfield(L, -2, "load");
lua_pushcfunction(L,wrappers::font::current); lua_setfield(L, -2, "current");
lua_pushcfunction(L,wrappers::font::spacing); lua_setfield(L, -2, "spacing");
lua_pushinteger(L, 0); lua_setfield(L, -2, "DEFAULT");
lua_setglobal(L, "font");
lua_newtable(L);
lua_pushcfunction(L,wrappers::mouse::pos); lua_setfield(L, -2, "pos");
lua_pushcfunction(L,wrappers::mouse::wheel); lua_setfield(L, -2, "wheel");
lua_pushcfunction(L,wrappers::mouse::down); lua_setfield(L, -2, "down");
lua_pushcfunction(L,wrappers::mouse::press); lua_setfield(L, -2, "press");
lua_pushcfunction(L,wrappers::mouse::dblclick); lua_setfield(L, -2, "dblclick");
lua_pushcfunction(L,wrappers::mouse::discard); lua_setfield(L, -2, "discard");
lua_pushcfunction(L,wrappers::mouse::inside); lua_setfield(L, -2, "inside");
lua_pushinteger(L, 1); lua_setfield(L, -2, "LEFT");
lua_pushinteger(L, 2); lua_setfield(L, -2, "MIDDLE");
lua_pushinteger(L, 3); lua_setfield(L, -2, "RIGHT");
lua_setglobal(L, "mouse");
lua_newtable(L);
lua_pushcfunction(L,wrappers::key::down); lua_setfield(L, -2, "down");
lua_pushcfunction(L,wrappers::key::press); lua_setfield(L, -2, "press");
lua_pushcfunction(L,wrappers::key::any); lua_setfield(L, -2, "any");
lua_pushcfunction(L,wrappers::key::text); lua_setfield(L, -2, "text");
lua_pushcfunction(L,wrappers::key::utf8char); lua_setfield(L, -2, "utf8char");
//lua_setglobal(L, "key");
//lua_newtable(L);
lua_pushinteger(L, 0); lua_setfield(L, -2, "UNKNOWN");
lua_pushinteger(L, 4); lua_setfield(L, -2, "A");
lua_pushinteger(L, 5); lua_setfield(L, -2, "B");
lua_pushinteger(L, 6); lua_setfield(L, -2, "C");
lua_pushinteger(L, 7); lua_setfield(L, -2, "D");
lua_pushinteger(L, 8); lua_setfield(L, -2, "E");
lua_pushinteger(L, 9); lua_setfield(L, -2, "F");
lua_pushinteger(L, 10); lua_setfield(L, -2, "G");
lua_pushinteger(L, 11); lua_setfield(L, -2, "H");
lua_pushinteger(L, 12); lua_setfield(L, -2, "I");
lua_pushinteger(L, 13); lua_setfield(L, -2, "J");
lua_pushinteger(L, 14); lua_setfield(L, -2, "K");
lua_pushinteger(L, 15); lua_setfield(L, -2, "L");
lua_pushinteger(L, 16); lua_setfield(L, -2, "M");
lua_pushinteger(L, 17); lua_setfield(L, -2, "N");
lua_pushinteger(L, 18); lua_setfield(L, -2, "O");
lua_pushinteger(L, 19); lua_setfield(L, -2, "P");
lua_pushinteger(L, 20); lua_setfield(L, -2, "Q");
lua_pushinteger(L, 21); lua_setfield(L, -2, "R");
lua_pushinteger(L, 22); lua_setfield(L, -2, "S");
lua_pushinteger(L, 23); lua_setfield(L, -2, "T");
lua_pushinteger(L, 24); lua_setfield(L, -2, "U");
lua_pushinteger(L, 25); lua_setfield(L, -2, "V");
lua_pushinteger(L, 26); lua_setfield(L, -2, "W");
lua_pushinteger(L, 27); lua_setfield(L, -2, "X");
lua_pushinteger(L, 28); lua_setfield(L, -2, "Y");
lua_pushinteger(L, 29); lua_setfield(L, -2, "Z");
lua_pushinteger(L, 30); lua_setfield(L, -2, "N1");
lua_pushinteger(L, 31); lua_setfield(L, -2, "N2");
lua_pushinteger(L, 32); lua_setfield(L, -2, "N3");
lua_pushinteger(L, 33); lua_setfield(L, -2, "N4");
lua_pushinteger(L, 34); lua_setfield(L, -2, "N5");
lua_pushinteger(L, 35); lua_setfield(L, -2, "N6");
lua_pushinteger(L, 36); lua_setfield(L, -2, "N7");
lua_pushinteger(L, 37); lua_setfield(L, -2, "N8");
lua_pushinteger(L, 38); lua_setfield(L, -2, "N9");
lua_pushinteger(L, 39); lua_setfield(L, -2, "N0");
lua_pushinteger(L, 40); lua_setfield(L, -2, "RETURN");
lua_pushinteger(L, 41); lua_setfield(L, -2, "ESCAPE");
lua_pushinteger(L, 42); lua_setfield(L, -2, "BACKSPACE");
lua_pushinteger(L, 43); lua_setfield(L, -2, "TAB");
lua_pushinteger(L, 44); lua_setfield(L, -2, "SPACE");
lua_pushinteger(L, 45); lua_setfield(L, -2, "MINUS");
lua_pushinteger(L, 46); lua_setfield(L, -2, "EQUALS");
lua_pushinteger(L, 47); lua_setfield(L, -2, "LEFTBRACKET");
lua_pushinteger(L, 48); lua_setfield(L, -2, "RIGHTBRACKET");
lua_pushinteger(L, 49); lua_setfield(L, -2, "BACKSLASH");
lua_pushinteger(L, 50); lua_setfield(L, -2, "NONUSHASH");
lua_pushinteger(L, 51); lua_setfield(L, -2, "SEMICOLON");
lua_pushinteger(L, 52); lua_setfield(L, -2, "APOSTROPHE");
lua_pushinteger(L, 53); lua_setfield(L, -2, "GRAVE");
lua_pushinteger(L, 54); lua_setfield(L, -2, "COMMA");
lua_pushinteger(L, 55); lua_setfield(L, -2, "PERIOD");
lua_pushinteger(L, 56); lua_setfield(L, -2, "SLASH");
lua_pushinteger(L, 57); lua_setfield(L, -2, "CAPSLOCK");
lua_pushinteger(L, 58); lua_setfield(L, -2, "F1");
lua_pushinteger(L, 59); lua_setfield(L, -2, "F2");
lua_pushinteger(L, 60); lua_setfield(L, -2, "F3");
lua_pushinteger(L, 61); lua_setfield(L, -2, "F4");
lua_pushinteger(L, 62); lua_setfield(L, -2, "F5");
lua_pushinteger(L, 63); lua_setfield(L, -2, "F6");
lua_pushinteger(L, 64); lua_setfield(L, -2, "F7");
lua_pushinteger(L, 65); lua_setfield(L, -2, "F8");
lua_pushinteger(L, 66); lua_setfield(L, -2, "F9");
lua_pushinteger(L, 67); lua_setfield(L, -2, "F10");
lua_pushinteger(L, 68); lua_setfield(L, -2, "F11");
lua_pushinteger(L, 69); lua_setfield(L, -2, "F12");
lua_pushinteger(L, 70); lua_setfield(L, -2, "PRINTSCREEN");
lua_pushinteger(L, 71); lua_setfield(L, -2, "SCROLLLOCK");
lua_pushinteger(L, 72); lua_setfield(L, -2, "PAUSE");
lua_pushinteger(L, 73); lua_setfield(L, -2, "INSERT");
lua_pushinteger(L, 74); lua_setfield(L, -2, "HOME");
lua_pushinteger(L, 75); lua_setfield(L, -2, "PAGEUP");
lua_pushinteger(L, 76); lua_setfield(L, -2, "DELETE");
lua_pushinteger(L, 77); lua_setfield(L, -2, "END");
lua_pushinteger(L, 78); lua_setfield(L, -2, "PAGEDOWN");
lua_pushinteger(L, 79); lua_setfield(L, -2, "RIGHT");
lua_pushinteger(L, 80); lua_setfield(L, -2, "LEFT");
lua_pushinteger(L, 81); lua_setfield(L, -2, "DOWN");
lua_pushinteger(L, 82); lua_setfield(L, -2, "UP");
lua_pushinteger(L, 83); lua_setfield(L, -2, "NUMLOCKCLEAR");
lua_pushinteger(L, 84); lua_setfield(L, -2, "KP_DIVIDE");
lua_pushinteger(L, 85); lua_setfield(L, -2, "KP_MULTIPLY");
lua_pushinteger(L, 86); lua_setfield(L, -2, "KP_MINUS");
lua_pushinteger(L, 87); lua_setfield(L, -2, "KP_PLUS");
lua_pushinteger(L, 88); lua_setfield(L, -2, "KP_ENTER");
lua_pushinteger(L, 89); lua_setfield(L, -2, "KP_1");
lua_pushinteger(L, 90); lua_setfield(L, -2, "KP_2");
lua_pushinteger(L, 91); lua_setfield(L, -2, "KP_3");
lua_pushinteger(L, 92); lua_setfield(L, -2, "KP_4");
lua_pushinteger(L, 93); lua_setfield(L, -2, "KP_5");
lua_pushinteger(L, 94); lua_setfield(L, -2, "KP_6");
lua_pushinteger(L, 95); lua_setfield(L, -2, "KP_7");
lua_pushinteger(L, 96); lua_setfield(L, -2, "KP_8");
lua_pushinteger(L, 97); lua_setfield(L, -2, "KP_9");
lua_pushinteger(L, 98); lua_setfield(L, -2, "KP_0");
lua_pushinteger(L, 99); lua_setfield(L, -2, "KP_PERIOD");
lua_pushinteger(L, 100); lua_setfield(L, -2, "NONUSBACKSLASH");
lua_pushinteger(L, 101); lua_setfield(L, -2, "APPLICATION");
lua_pushinteger(L, 224); lua_setfield(L, -2, "LCTRL");
lua_pushinteger(L, 225); lua_setfield(L, -2, "LSHIFT");
lua_pushinteger(L, 226); lua_setfield(L, -2, "LALT");
lua_pushinteger(L, 227); lua_setfield(L, -2, "LGUI");
lua_pushinteger(L, 228); lua_setfield(L, -2, "RCTRL");
lua_pushinteger(L, 229); lua_setfield(L, -2, "RSHIFT");
lua_pushinteger(L, 230); lua_setfield(L, -2, "RALT");
lua_pushinteger(L, 231); lua_setfield(L, -2, "RGUI");
lua_setglobal(L, "key");
lua_newtable(L);
lua_pushcfunction(L,wrappers::pad::down); lua_setfield(L, -2, "down");
lua_pushcfunction(L,wrappers::pad::press); lua_setfield(L, -2, "press");
lua_pushcfunction(L,wrappers::pad::any); lua_setfield(L, -2, "any");
//lua_setglobal(L, "gamepad");
//lua_newtable(L);
lua_pushinteger(L, -1); lua_setfield(L, -2, "INVALID");
lua_pushinteger(L, 0); lua_setfield(L, -2, "A");
lua_pushinteger(L, 1); lua_setfield(L, -2, "B");
lua_pushinteger(L, 2); lua_setfield(L, -2, "X");
lua_pushinteger(L, 3); lua_setfield(L, -2, "Y");
lua_pushinteger(L, 4); lua_setfield(L, -2, "BACK");
lua_pushinteger(L, 5); lua_setfield(L, -2, "GUIDE");
lua_pushinteger(L, 6); lua_setfield(L, -2, "START");
lua_pushinteger(L, 7); lua_setfield(L, -2, "LEFTSTICK");
lua_pushinteger(L, 8); lua_setfield(L, -2, "RIGHTSTICK");
lua_pushinteger(L, 9); lua_setfield(L, -2, "LEFTSHOULDER");
lua_pushinteger(L, 10); lua_setfield(L, -2, "RIGHTSHOULDER");
lua_pushinteger(L, 11); lua_setfield(L, -2, "UP");
lua_pushinteger(L, 12); lua_setfield(L, -2, "DOWN");
lua_pushinteger(L, 13); lua_setfield(L, -2, "LEFT");
lua_pushinteger(L, 14); lua_setfield(L, -2, "RIGHT");
lua_pushinteger(L, 15); lua_setfield(L, -2, "MISC1");
lua_pushinteger(L, 16); lua_setfield(L, -2, "PADDLE1");
lua_pushinteger(L, 17); lua_setfield(L, -2, "PADDLE2");
lua_pushinteger(L, 18); lua_setfield(L, -2, "PADDLE3");
lua_pushinteger(L, 19); lua_setfield(L, -2, "PADDLE4");
lua_pushinteger(L, 20); lua_setfield(L, -2, "TOUCHPAD");
lua_setglobal(L, "pad");
lua_getglobal(L, "utf8"); // push utf8 table
lua_pushcfunction(L, cpp_utf8_sub); // push C function
lua_setfield(L, -2, "sub"); // utf8.sub = cpp_utf8_sub
lua_pop(L, 1); // pop utf8 table
}
int MiniLoader(lua_State *L) {
const char *name = luaL_checkstring(L, 1);
// 1. Convertir puntos en barras
std::string path(name);
std::string regpath(name);
std::replace(path.begin(), path.end(), '.', '/');
// 2. Detectar comodín "/*"
bool load_all = false;
if (path.size() >= 2 && path.substr(path.size()-2) == "/*") {
load_all = true;
path = path.substr(0, path.size()-2); // quitar "/*"
regpath = regpath.substr(0, regpath.size()-2); // quitar "/*"
}
if (load_all) {
std::vector<std::string> files = file_listdir(path.c_str(), "lua");
// Ejecutar todos los módulos
for (auto &f : files) {
std::string fullpath = path + "/" + f;
std::string registerpath = std::string(regpath + "." + f.substr(0,f.size()-4));
int size;
char* buffer = file_getfilebuffer(fullpath.c_str(), size);
if (!buffer) continue;
if (luaL_loadbuffer(L, buffer, size, registerpath.c_str()) == LUA_OK) {
lua_pcall(L, 0, 0, 0); // ejecutar módulo, sin devolver nada
lua_getglobal(L, "package");
lua_getfield(L, -1, "loaded");
lua_pushboolean(L, 1);
lua_setfield(L, -2, registerpath.c_str());
lua_pop(L, 2);
} else {
log_msg(LOG_LUALD, "Error cargando %s: %s\n", fullpath.c_str(), lua_tostring(L, -1));
lua_pop(L, 1);
}
free(buffer);
}
// Devolver un loader vacío
lua_pushcfunction(L, [](lua_State* L) -> int {
lua_pushboolean(L, 1); // require devuelve true
return 1;
});
return 1;
}
// 3. Cargar un único archivo
std::string filename = path + ".lua";
int size;
char* buffer = file_getfilebuffer(filename.c_str(), size);
if (!buffer) {
lua_pushnil(L);
return 1;
}
if (luaL_loadbuffer(L, buffer, size, name)) {
log_msg(LOG_LUALD, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
free(buffer);
lua_pushnil(L);
return 1;
}
free(buffer);
return 1;
}
void init(const char *main_lua_file) {
L = luaL_newstate();
luaL_openlibs(L);
push_functions();
lua_register(L, "mini_loader", MiniLoader);
luaL_dostring(L, "table.insert(package.searchers,2,mini_loader)\n");
int size;
char* buffer = file_getfilebuffer(main_lua_file, size);
if (luaL_loadbuffer(L, buffer, size, "main")) {
log_msg(LOG_LUALD, "%s\n", lua_tostring(L, -1));
lua_pop(L,1);
return;
}
free(buffer);
if (lua_pcall(L,0, LUA_MULTRET, 0)) {
//luaL_traceback(L, L, NULL, 1);
log_msg(LOG_LUART, "%s\n", lua_tostring(L, -1));
lua_pop(L,1);
return;
}
// Check if _init and _update exist
lua_getglobal(L, "mini");
lua_getfield(L, -1, "init");
if (lua_isfunction(L,-1)) init_exists = true;
lua_pop(L,1);
lua_pop(L,1);
lua_getglobal(L, "mini");
lua_getfield(L, -1, "update");
if (lua_isfunction(L,-1)) update_exists = true;
lua_pop(L,1);
lua_pop(L,1);
//std::thread(debugCommandThread).detach();
printf("stdin isatty: %d\n", isatty(0));
is_playing = true;
}
void quit() {
if (!is_playing) return;
is_playing = false;
lua_close(L);
}
void cleanup() {
debug::kill_thread();
}
namespace callbacks
{
void init() {
if (!init_exists) return;
debug::process_commands(L);
lua_getglobal(L, "mini");
lua_getfield(L, -1, "init");
is_playing = debug::call_and_handle_exceptions(L);
}
void update() {
if (!update_exists) return;
lua_getglobal(L, "mini");
lua_getfield(L, -1, "update");
is_playing = debug::call_and_handle_exceptions(L);
}
}
}
}