bool am_load_config() { free_config(); am_engine *eng = am_init_engine(true, 0, NULL); if (eng == NULL) return false; // remove globals metatable, so we can set conf options as globals lua_getglobal(eng->L, "_G"); lua_pushnil(eng->L); lua_setmetatable(eng->L, -2); lua_pop(eng->L, 1); int len; char *errmsg; void *data = am_read_resource("conf.lua", &len, &errmsg); if (data == NULL) { // assume conf.lua doesn't exist free(errmsg); } else { bool res = am_run_script(eng->L, (char*)data, len, "conf.lua"); free(data); if (!res) { return false; } } read_string_setting(eng->L, "title", &am_conf_app_title, "Untitled"); read_string_setting(eng->L, "shortname", &am_conf_app_shortname, am_conf_app_title); read_string_setting(eng->L, "org", &am_conf_app_org, "Unknown"); read_string_setting(eng->L, "appid", &am_conf_app_id, "null"); read_string_setting(eng->L, "version", &am_conf_app_version, "0.0.0"); am_destroy_engine(eng); return true; }
static int load_image(lua_State *L) { am_check_nargs(L, 1); char *errmsg; int len; const char *filename = luaL_checkstring(L, 1); void *data = am_read_resource(filename, &len, &errmsg); if (data == NULL) { lua_pushstring(L, errmsg); free(errmsg); return lua_error(L); } int width, height; int components = 4; stbi_set_flip_vertically_on_load(1); stbi_uc *img_data = stbi_load_from_memory((stbi_uc const *)data, len, &width, &height, &components, 4); free(data); if (img_data == NULL) { return luaL_error(L, "error loading image %s: %s", filename, stbi_failure_reason()); } am_image_buffer *img = am_new_userdata(L, am_image_buffer); img->width = width; img->height = height; img->format = AM_PIXEL_FORMAT_RGBA8; int sz = width * height * pixel_format_size(img->format); am_buffer *imgbuf = am_new_userdata(L, am_buffer); imgbuf->size = sz; imgbuf->data = img_data; img->buffer = imgbuf; img->buffer_ref = img->ref(L, -1); lua_pop(L, 1); // pop imgbuf return 1; }
bool am_load_config() { free_config(); am_engine *eng = am_init_engine(true, 0, NULL); if (eng == NULL) return false; // remove globals metatable, so we can set conf options as globals lua_getglobal(eng->L, "_G"); lua_pushnil(eng->L); lua_setmetatable(eng->L, -2); lua_pop(eng->L, 1); int len; char *errmsg; void *data = am_read_resource("conf.lua", &len, &errmsg); if (data == NULL) { // assume conf.lua doesn't exist free(errmsg); } else { bool res = am_run_script(eng->L, (char*)data, len, "conf.lua"); free(data); if (!res) { am_destroy_engine(eng); return false; } } read_string_setting(eng->L, "title", &am_conf_app_title, "Untitled"); read_string_setting(eng->L, "author", &am_conf_app_author, "Unknown"); read_string_setting(eng->L, "shortname", &am_conf_app_shortname, am_conf_app_title); read_string_setting(eng->L, "appid", &am_conf_app_id, "null"); read_string_setting(eng->L, "version", &am_conf_app_version, "0.0.0"); read_string_setting(eng->L, "display_name", &am_conf_app_display_name, am_conf_app_title); read_string_setting(eng->L, "dev_region", &am_conf_app_dev_region, "en"); read_string_setting(eng->L, "supported_languages", &am_conf_app_supported_languages, "en"); const char *orientation_str = NULL; read_string_setting(eng->L, "orientation", &orientation_str, "any"); if (strcmp(orientation_str, "any") == 0) { am_conf_app_display_orientation = AM_DISPLAY_ORIENTATION_ANY; } else if (strcmp(orientation_str, "portrait") == 0) { am_conf_app_display_orientation = AM_DISPLAY_ORIENTATION_PORTRAIT; } else if (strcmp(orientation_str, "landscape") == 0) { am_conf_app_display_orientation = AM_DISPLAY_ORIENTATION_LANDSCAPE; } else { fprintf(stderr, "Invalid orientation in conf.lua: %s\n", orientation_str); am_destroy_engine(eng); return false; } read_string_setting(eng->L, "icon", &am_conf_app_icon, NULL); read_string_setting(eng->L, "launch_image", &am_conf_app_launch_image, NULL); am_destroy_engine(eng); return true; }
int am_require(lua_State *L) { am_check_nargs(L, 1); char tmpbuf1[TMP_BUF_SZ]; char tmpbuf2[TMP_BUF_SZ]; size_t len; const char *modname = lua_tolstring(L, 1, &len); // check for string argument if (modname == NULL) { return luaL_error(L, "require expects a string as its single argument"); } // check module name not too long if (len > TMP_BUF_SZ - 10) { return luaL_error(L, "module name '%s' too long", modname); } // check if module has already been loaded lua_rawgeti(L, LUA_REGISTRYINDEX, AM_MODULE_TABLE); lua_pushvalue(L, 1); // module name lua_rawget(L, -2); if (!lua_isnil(L, -1)) { // already loaded, or busy loading lua_remove(L, -2); // module table return 1; } lua_pop(L, 1); // nil // create exports table and add to module table: lua_newtable(L); lua_pushvalue(L, 1); // module name lua_pushvalue(L, -2); // export table lua_rawset(L, -4); // set it // export table now on top // read in the module int sz; strncpy(tmpbuf1, modname, TMP_BUF_SZ); am_replchr(tmpbuf1, '.', AM_PATH_SEP); snprintf(tmpbuf2, TMP_BUF_SZ, "%s.lua", tmpbuf1); char *errmsg; void *buf = am_read_resource(tmpbuf2, &sz, &errmsg); if (buf == NULL) { lua_pushfstring(L, "unable to load module '%s': %s", modname, errmsg); free(errmsg); return lua_error(L); } // replace "#!" at start with "--" char *cbuf = (char*)buf; if (sz >= 2 && cbuf[0] == '#' && cbuf[1] == '!') { cbuf[0] = '-'; cbuf[1] = '-'; } // parse and load the module snprintf(tmpbuf2, TMP_BUF_SZ, "@%s.lua", tmpbuf1); int res = luaL_loadbuffer(L, (const char*)buf, sz, tmpbuf2); free(buf); if (res != 0) return lua_error(L); // pass export table as arg lua_pushvalue(L, -2); // export table lua_call(L, 1, 1); if (!lua_isnil(L, -1)) { // replace export table with returned value in module table lua_pushvalue(L, 1); // module name lua_pushvalue(L, -2); // returned value lua_rawset(L, -5); lua_remove(L, -2); // export table lua_remove(L, -2); // module table // return value now on top } else { lua_pop(L, 1); // nil lua_remove(L, -2); // module table // export table now on top } return 1; }