Initial commit

This commit is contained in:
rxi
2019-12-28 11:17:56 +00:00
commit d8c4bfa6ba
486 changed files with 146040 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
#include "api.h"
int luaopen_system(lua_State *L);
int luaopen_renderer(lua_State *L);
static const luaL_Reg libs[] = {
{ "system", luaopen_system },
{ "renderer", luaopen_renderer },
{ NULL, NULL }
};
void api_load_libs(lua_State *L) {
for (int i = 0; libs[i].name; i++) {
luaL_requiref(L, libs[i].name, libs[i].func, 1);
}
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef API_H
#define API_H
#include "lib/lua52/lua.h"
#include "lib/lua52/lauxlib.h"
#include "lib/lua52/lualib.h"
#define API_TYPE_FONT "Font"
void api_load_libs(lua_State *L);
#endif
+107
View File
@@ -0,0 +1,107 @@
#include "api.h"
#include "renderer.h"
#include "rencache.h"
#include "xalloc.h"
static RenColor checkcolor(lua_State *L, int idx, int def) {
RenColor color;
if (lua_isnoneornil(L, idx)) {
return (RenColor) { def, def, def, 255 };
}
lua_rawgeti(L, idx, 1);
lua_rawgeti(L, idx, 2);
lua_rawgeti(L, idx, 3);
lua_rawgeti(L, idx, 4);
color.r = luaL_checknumber(L, -4);
color.g = luaL_checknumber(L, -3);
color.b = luaL_checknumber(L, -2);
color.a = luaL_optnumber(L, -1, 255);
lua_pop(L, 4);
return color;
}
static int f_show_debug(lua_State *L) {
luaL_checkany(L, 1);
rencache_show_debug(lua_toboolean(L, 1));
return 0;
}
static int f_get_size(lua_State *L) {
int w, h;
ren_get_size(&w, &h);
lua_pushnumber(L, w);
lua_pushnumber(L, h);
return 2;
}
static int f_begin_frame(lua_State *L) {
rencache_begin_frame();
return 0;
}
static int f_end_frame(lua_State *L) {
rencache_end_frame();
return 0;
}
static int f_set_clip_rect(lua_State *L) {
RenRect rect;
rect.x = luaL_checknumber(L, 1);
rect.y = luaL_checknumber(L, 2);
rect.width = luaL_checknumber(L, 3);
rect.height = luaL_checknumber(L, 4);
rencache_set_clip_rect(rect);
return 0;
}
static int f_draw_rect(lua_State *L) {
RenRect rect;
rect.x = luaL_checknumber(L, 1);
rect.y = luaL_checknumber(L, 2);
rect.width = luaL_checknumber(L, 3);
rect.height = luaL_checknumber(L, 4);
RenColor color = checkcolor(L, 5, 255);
rencache_draw_rect(rect, color);
return 0;
}
static int f_draw_text(lua_State *L) {
RenFont **font = luaL_checkudata(L, 1, API_TYPE_FONT);
const char *text = luaL_checkstring(L, 2);
int x = luaL_checknumber(L, 3);
int y = luaL_checknumber(L, 4);
RenColor color = checkcolor(L, 5, 255);
x = rencache_draw_text(*font, text, x, y, color);
lua_pushnumber(L, x);
return 1;
}
static const luaL_Reg lib[] = {
{ "show_debug", f_show_debug },
{ "get_size", f_get_size },
{ "begin_frame", f_begin_frame },
{ "end_frame", f_end_frame },
{ "set_clip_rect", f_set_clip_rect },
{ "draw_rect", f_draw_rect },
{ "draw_text", f_draw_text },
{ NULL, NULL }
};
int luaopen_renderer_font(lua_State *L);
int luaopen_renderer(lua_State *L) {
luaL_newlib(L, lib);
luaopen_renderer_font(L);
lua_setfield(L, -2, "font");
return 1;
}
+62
View File
@@ -0,0 +1,62 @@
#include "api.h"
#include "renderer.h"
#include "rencache.h"
static int f_load(lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
float size = luaL_checknumber(L, 2);
RenFont **self = lua_newuserdata(L, sizeof(*self));
luaL_setmetatable(L, API_TYPE_FONT);
*self = ren_load_font(filename, size);
if (!*self) { luaL_error(L, "failed to load font"); }
return 1;
}
static int f_set_tab_width(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
int n = luaL_checknumber(L, 2);
ren_set_font_tab_width(*self, n);
return 0;
}
static int f_gc(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
rencache_free_font(*self);
return 0;
}
static int f_get_width(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
const char *text = luaL_checkstring(L, 2);
lua_pushnumber(L, ren_get_font_width(*self, text) );
return 1;
}
static int f_get_height(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
lua_pushnumber(L, ren_get_font_height(*self) );
return 1;
}
static const luaL_Reg lib[] = {
{ "__gc", f_gc },
{ "load", f_load },
{ "set_tab_width", f_set_tab_width },
{ "get_width", f_get_width },
{ "get_height", f_get_height },
{ NULL, NULL }
};
int luaopen_renderer_font(lua_State *L) {
luaL_newmetatable(L, API_TYPE_FONT);
luaL_setfuncs(L, lib, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
return 1;
}
+338
View File
@@ -0,0 +1,338 @@
#include <SDL2/SDL.h>
#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
#include "api.h"
#ifdef _WIN32
#include <windows.h>
#endif
extern SDL_Window *window;
static const char* button_name(int button) {
switch (button) {
case 1 : return "left";
case 2 : return "middle";
case 3 : return "right";
default : return "?";
}
}
static char* key_name(char *dst, int sym) {
strcpy(dst, SDL_GetKeyName(sym));
char *p = dst;
while (*p) {
*p = tolower(*p);
p++;
}
return dst;
}
static int f_poll_event(lua_State *L) {
char buf[16];
SDL_Event e;
top:
if ( !SDL_PollEvent(&e) ) {
return 0;
}
switch (e.type) {
case SDL_QUIT:
lua_pushstring(L, "quit");
return 1;
case SDL_WINDOWEVENT:
if (e.window.event == SDL_WINDOWEVENT_RESIZED) {
lua_pushstring(L, "resized");
lua_pushnumber(L, e.window.data1);
lua_pushnumber(L, e.window.data2);
return 3;
} else if (e.window.event == SDL_WINDOWEVENT_EXPOSED) {
SDL_UpdateWindowSurface(window);
}
/* on some systems, when alt-tabbing to the window SDL will queue up
** several KEYDOWN events for the `tab` key; we flush all keydown
** events on focus so these are discarded */
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
SDL_FlushEvent(SDL_KEYDOWN);
}
goto top;
case SDL_DROPFILE:
lua_pushstring(L, "filedropped");
lua_pushstring(L, e.drop.file);
SDL_free(e.drop.file);
return 2;
case SDL_KEYDOWN:
lua_pushstring(L, "keypressed");
lua_pushstring(L, key_name(buf, e.key.keysym.sym));
return 2;
case SDL_KEYUP:
lua_pushstring(L, "keyreleased");
lua_pushstring(L, key_name(buf, e.key.keysym.sym));
return 2;
case SDL_TEXTINPUT:
lua_pushstring(L, "textinput");
lua_pushstring(L, e.text.text);
return 2;
case SDL_MOUSEBUTTONDOWN:
if (e.button.button == 1) { SDL_CaptureMouse(1); }
lua_pushstring(L, "mousepressed");
lua_pushstring(L, button_name(e.button.button));
lua_pushnumber(L, e.button.x);
lua_pushnumber(L, e.button.y);
lua_pushnumber(L, e.button.clicks);
return 5;
case SDL_MOUSEBUTTONUP:
if (e.button.button == 1) { SDL_CaptureMouse(0); }
lua_pushstring(L, "mousereleased");
lua_pushstring(L, button_name(e.button.button));
lua_pushnumber(L, e.button.x);
lua_pushnumber(L, e.button.y);
return 4;
case SDL_MOUSEMOTION:
lua_pushstring(L, "mousemoved");
lua_pushnumber(L, e.motion.x);
lua_pushnumber(L, e.motion.y);
lua_pushnumber(L, e.motion.xrel);
lua_pushnumber(L, e.motion.yrel);
return 5;
case SDL_MOUSEWHEEL:
lua_pushstring(L, "mousewheel");
lua_pushnumber(L, e.wheel.y);
return 2;
default:
goto top;
}
return 0;
}
static SDL_Cursor* cursor_cache[SDL_SYSTEM_CURSOR_HAND + 1];
static const char *cursor_opts[] = {
"arrow",
"ibeam",
"sizeh",
"sizev",
"hand",
NULL
};
static const int cursor_enums[] = {
SDL_SYSTEM_CURSOR_ARROW,
SDL_SYSTEM_CURSOR_IBEAM,
SDL_SYSTEM_CURSOR_SIZEWE,
SDL_SYSTEM_CURSOR_SIZENS,
SDL_SYSTEM_CURSOR_HAND
};
static int f_set_cursor(lua_State *L) {
int opt = luaL_checkoption(L, 1, "arrow", cursor_opts);
int n = cursor_enums[opt];
SDL_Cursor *cursor = cursor_cache[n];
if (!cursor) {
cursor = SDL_CreateSystemCursor(n);
cursor_cache[n] = cursor;
}
SDL_SetCursor(cursor);
return 0;
}
static int f_set_window_title(lua_State *L) {
const char *title = luaL_checkstring(L, 1);
SDL_SetWindowTitle(window, title);
return 0;
}
static int f_window_has_focus(lua_State *L) {
unsigned flags = SDL_GetWindowFlags(window);
lua_pushboolean(L, flags & SDL_WINDOW_INPUT_FOCUS);
return 1;
}
static int f_show_confirm_dialog(lua_State *L) {
const char *title = luaL_checkstring(L, 1);
const char *msg = luaL_checkstring(L, 2);
#if _WIN32
int id = MessageBox(0, msg, title, MB_YESNO | MB_ICONWARNING);
lua_pushboolean(L, id == IDYES);
#else
SDL_MessageBoxButtonData buttons[] = {
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" },
{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "No" },
};
SDL_MessageBoxData data = {
.title = title,
.message = msg,
.numbuttons = 2,
.buttons = buttons,
};
int buttonid;
SDL_ShowMessageBox(&data, &buttonid);
lua_pushboolean(L, buttonid == 1);
#endif
return 1;
}
static int f_list_dir(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
DIR *dir = opendir(path);
if (!dir) { luaL_error(L, "could not open directory: %s", path); }
lua_newtable(L);
int i = 1;
struct dirent *entry;
while ( (entry = readdir(dir)) ) {
if (strcmp(entry->d_name, "." ) == 0) { continue; }
if (strcmp(entry->d_name, "..") == 0) { continue; }
lua_pushstring(L, entry->d_name);
lua_rawseti(L, -2, i);
i++;
}
closedir(dir);
return 1;
}
#ifdef _WIN32
#include <windows.h>
#define realpath(x, y) _fullpath(y, x, MAX_PATH)
#endif
static int f_absolute_path(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
char *res = realpath(path, NULL);
if (!res) { return 0; }
lua_pushstring(L, res);
free(res);
return 1;
}
static int f_get_file_info(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
struct stat s;
int err = stat(path, &s);
if (err < 0) { return 0; }
lua_newtable(L);
lua_pushnumber(L, s.st_mtime);
lua_setfield(L, -2, "modified");
lua_pushnumber(L, s.st_size);
lua_setfield(L, -2, "size");
if (S_ISREG(s.st_mode)) {
lua_pushstring(L, "file");
} else if (S_ISDIR(s.st_mode)) {
lua_pushstring(L, "dir");
} else {
lua_pushnil(L);
}
lua_setfield(L, -2, "type");
return 1;
}
static int f_get_clipboard(lua_State *L) {
char *text = SDL_GetClipboardText();
if (!text) { return 0; }
lua_pushstring(L, text);
SDL_free(text);
return 1;
}
static int f_set_clipboard(lua_State *L) {
const char *text = luaL_checkstring(L, 1);
SDL_SetClipboardText(text);
return 0;
}
static int f_get_time(lua_State *L) {
double n = SDL_GetPerformanceCounter() / (double) SDL_GetPerformanceFrequency();
lua_pushnumber(L, n);
return 1;
}
static int f_sleep(lua_State *L) {
double n = luaL_checknumber(L, 1);
SDL_Delay(n * 1000);
return 0;
}
static int f_fuzzy_match(lua_State *L) {
const char *str = luaL_checkstring(L, 1);
const char *ptn = luaL_checkstring(L, 2);
int score = 0;
int run = 0;
while (*str && *ptn) {
while (*str == ' ') { str++; }
while (*ptn == ' ') { ptn++; }
if (tolower(*str) == tolower(*ptn)) {
score += run;
run++;
ptn++;
} else {
score--;
run = 0;
}
str++;
}
if (*ptn) { return 0; }
lua_pushnumber(L, score - (int) strlen(str));
return 1;
}
static const luaL_Reg lib[] = {
{ "poll_event", f_poll_event },
{ "set_cursor", f_set_cursor },
{ "set_window_title", f_set_window_title },
{ "window_has_focus", f_window_has_focus },
{ "show_confirm_dialog", f_show_confirm_dialog },
{ "list_dir", f_list_dir },
{ "absolute_path", f_absolute_path },
{ "get_file_info", f_get_file_info },
{ "get_clipboard", f_get_clipboard },
{ "set_clipboard", f_set_clipboard },
{ "get_time", f_get_time },
{ "sleep", f_sleep },
{ "fuzzy_match", f_fuzzy_match },
{ NULL, NULL }
};
int luaopen_system(lua_State *L) {
luaL_newlib(L, lib);
return 1;
}