twnlua: bindgen.py capable of converting share/twn_api.h spec to lua bindings

This commit is contained in:
veclavtalica
2024-12-23 20:59:00 +03:00
parent c4c097f050
commit e7ed72dfc0
6 changed files with 540 additions and 212 deletions

View File

@ -10,6 +10,10 @@
#include <malloc.h>
/* 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);
@ -37,201 +41,6 @@ static int physfs_loader(lua_State *L) {
}
static Rect table_to_rect(lua_State *L, int idx, const char *name) {
/* types are checked here to help prevent unexpected results */
Rect rect;
int is_num;
lua_getfield(L, idx, "x");
rect.x = (float)lua_tonumberx(L, -1, &is_num);
if (!is_num)
luaL_error(L, "bad field 'x' in '%s' (number expected, got %s)", name, luaL_typename(L, -1));
lua_pop(L, 1);
lua_getfield(L, idx, "y");
rect.y = (float)lua_tonumberx(L, -1, &is_num);
if (!is_num)
luaL_error(L, "bad field 'y' in '%s' (number expected, got %s)", name, luaL_typename(L, -1));
lua_pop(L, 1);
lua_getfield(L, idx, "w");
rect.w = (float)lua_tonumberx(L, -1, &is_num);
if (!is_num)
luaL_error(L, "bad field 'w' in '%s' (number expected, got %s)", name, luaL_typename(L, -1));
lua_pop(L, 1);
lua_getfield(L, idx, "h");
rect.h = (float)lua_tonumberx(L, -1, &is_num);
if (!is_num)
luaL_error(L, "bad field 'h' in '%s' (number expected, got %s)", name, luaL_typename(L, -1));
lua_pop(L, 1);
return rect;
}
static Color table_to_color(lua_State *L, int idx) {
Color color;
lua_getfield(L, idx, "r");
color.r = (uint8_t)lua_tointeger(L, -1);
lua_pop(L, 1);
lua_getfield(L, idx, "g");
color.g = (uint8_t)lua_tointeger(L, -1);
lua_pop(L, 1);
lua_getfield(L, idx, "b");
color.b = (uint8_t)lua_tointeger(L, -1);
lua_pop(L, 1);
lua_getfield(L, idx, "a");
color.a = (uint8_t)lua_tointeger(L, -1);
lua_pop(L, 1);
return color;
}
/* sprite(data [table]) */
/* data should contain the following fields: */
/*
* path [string]
* rect [table]
* texture_region [table], optional
* color [table], optional
* rotation [number], optional
* flip_x [boolean], optional
* flip_y [boolean], optional
* stretch [boolean], optional
*/
static int b_sprite(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
DrawSpriteArgs args = { 0 };
lua_getfield(L, 1, "path");
const char *field_path = lua_tostring(L, -1);
if (field_path == NULL)
luaL_error(L, "bad field 'path' in 'data' (string expected, got %s)", luaL_typename(L, -1));
args.path = field_path;
lua_getfield(L, 1, "rect");
if (!lua_istable(L, -1))
luaL_error(L, "bad field 'rect' in 'data' (table expected, got %s)", luaL_typename(L, -1));
args.rect = table_to_rect(L, -1, "data.rect");
lua_getfield(L, 1, "texture_region");
if (lua_istable(L, -1)) {
args.texture_region_opt = table_to_rect(L, -1, "data.texture_region");
args.texture_region_opt_set = true;
}
lua_getfield(L, 1, "color");
if (lua_istable(L, -1)) {
args.color_opt = table_to_color(L, -1);
args.color_opt_set = true;
}
lua_getfield(L, 1, "rotation");
if (lua_isnumber(L, -1)) {
args.rotation_opt = (float)lua_tonumber(L, -1);
args.rotation_opt_set = true;
}
lua_getfield(L, 1, "flip_x");
if (lua_isboolean(L, -1)) {
args.flip_x_opt = lua_toboolean(L, -1);
args.flip_x_opt_set = true;
}
lua_getfield(L, 1, "flip_y");
if (lua_isboolean(L, -1)) {
args.flip_y_opt = lua_toboolean(L, -1);
args.flip_y_opt_set = true;
}
lua_getfield(L, 1, "stretch");
if (lua_isboolean(L, -1)) {
args.stretch_opt = lua_toboolean(L, -1);
args.stretch_opt_set = true;
}
draw_sprite_args(args);
return 0;
}
/* rectangle(data [table]) */
/* data should contain the following fields: */
/*
* rect [table]
* color [table], optional, defaults to white
*/
static int b_rectangle(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_getfield(L, 1, "rect");
if (!lua_istable(L, -1))
luaL_error(L, "bad field 'rect' in 'data' (table expected, got %s)", luaL_typename(L, -1));
Rect rect = table_to_rect(L, -1, "data.rect");
Color color = { 255, 255, 255, 255 };
lua_getfield(L, 1, "color");
if (lua_istable(L, -1))
color = table_to_color(L, -1);
draw_rectangle(rect, color);
return 0;
}
/* text(data [table]) */
/* data should contain the following fields: */
/*
* string [string]
* position [table]
* height_px [number], optional, defaults to 22
* color [table], optional, defaults to black
* font [string]
*/
static int b_text(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_getfield(L, 1, "string");
const char *string = lua_tostring(L, -1);
if (string == NULL)
luaL_error(L, "bad field 'string' in 'data' (string expected, got %s)", luaL_typename(L, -1));
lua_getfield(L, 1, "position");
if (!lua_istable(L, -1))
luaL_error(L, "bad field 'position' in 'data' (table expected, got %s)", luaL_typename(L, -1));
lua_getfield(L, -1, "x");
float x = (float)lua_tonumber(L, -1);
lua_getfield(L, -2, "y");
float y = (float)lua_tonumber(L, -1);
lua_getfield(L, 1, "height_px");
int is_num;
int height_px = (int)lua_tointegerx(L, -1, &is_num);
if (!is_num)
height_px = 22;
lua_getfield(L, 1, "color");
Color color = { 0, 0, 0, 255 };
if (lua_istable(L, -1))
color = table_to_color(L, -1);
lua_getfield(L, 1, "font");
const char *font = lua_tostring(L, -1);
if (font == NULL)
luaL_error(L, "bad field 'font' in 'data' (string expected, got %s)", luaL_typename(L, -1));
draw_text(string, (Vec2) { x, y }, height_px, color, font);
return 0;
}
void game_tick(void) {
if (ctx.initialization_needed) {
if (!ctx.udata)
@ -246,14 +55,13 @@ void game_tick(void) {
}
state->L = luaL_newstate();
/* fakey version of luaL_openlibs() that excludes file i/o */
/* 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_OSLIBNAME, luaopen_os },
{ LUA_STRLIBNAME, luaopen_string },
{ LUA_MATHLIBNAME, luaopen_math },
{ LUA_UTF8LIBNAME, luaopen_utf8 },
@ -280,9 +88,11 @@ void game_tick(void) {
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);
// 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;