#include "twn_game_api.h" #include "state.h" #include #include #include #include #include /* generated by bindgen.py */ void bindgen_load_twn(lua_State *L); /* require will go through physicsfs exclusively so that scripts can be in the data dir */ static int physfs_loader(lua_State *L) { const char *name = luaL_checkstring(L, 1); char *final_path = NULL; SDL_asprintf(&final_path, "%s.lua", name); if (!file_exists(final_path)) { char *error_message = NULL; SDL_asprintf(&error_message, "could not find module %s in filesystem", name); lua_pushstring(L, error_message); free(error_message); free(final_path); return 1; } unsigned char *buf = NULL; int64_t buf_size = file_to_bytes(final_path, &buf); free(final_path); luaL_loadbuffer(L, (char *)buf, buf_size, name); free(buf); return 1; } void game_tick(void) { if (ctx.initialization_needed) { if (!ctx.udata) ctx.udata = ccalloc(1, sizeof (State)); State *state = ctx.udata; /* let's init lua */ /* state existed already */ if (state->L != NULL) { lua_close(state->L); } state->L = luaL_newstate(); /* fakey version of luaL_openlibs() that excludes file i/o and os stuff */ { static const luaL_Reg loaded_libs[] = { { LUA_GNAME, luaopen_base }, { LUA_LOADLIBNAME, luaopen_package }, { LUA_COLIBNAME, luaopen_coroutine }, { LUA_TABLIBNAME, luaopen_table }, { LUA_STRLIBNAME, luaopen_string }, { LUA_MATHLIBNAME, luaopen_math }, { LUA_UTF8LIBNAME, luaopen_utf8 }, { LUA_DBLIBNAME, luaopen_debug }, { NULL, NULL }, }; for (const luaL_Reg *lib = loaded_libs; lib->func; ++lib) { luaL_requiref(state->L, lib->name, lib->func, true); lua_pop(state->L, 1); /* already stored, don't need the copy */ } } /* package.searchers = { physfs_loader } */ lua_getglobal(state->L, "package"); lua_newtable(state->L); lua_setfield(state->L, -2, "searchers"); lua_getfield(state->L, -1, "searchers"); lua_pushcfunction(state->L, physfs_loader); lua_seti(state->L, -2, 1); /* pop package, package.searchers */ lua_pop(state->L, 2); /* binding */ // lua_register(state->L, "sprite", b_sprite); // lua_register(state->L, "rectangle", b_rectangle); // lua_register(state->L, "text", b_text); bindgen_load_twn(state->L); /* now finally get to running the code */ unsigned char *game_buf = NULL; size_t game_buf_size = file_to_bytes("/scripts/game.lua", &game_buf); if (luaL_loadbuffer(state->L, (char *)game_buf, game_buf_size, "game.lua") == LUA_OK) { if (lua_pcall(state->L, 0, 0, 0) != LUA_OK) { log_critical("%s", lua_tostring(state->L, -1)); lua_pop(state->L, 1); } } free(game_buf); /* from this point we have access to everything defined in lua */ } State *state = ctx.udata; lua_getglobal(state->L, "game_tick"); if (lua_pcall(state->L, 0, 0, 0) != LUA_OK) { log_critical("%s", lua_tostring(state->L, -1)); lua_pop(state->L, 1); } } void game_end(void) { State *state = ctx.udata; lua_close(state->L); free(state); }