lovr/src/main.c

160 lines
3.8 KiB
C
Raw Normal View History

2019-05-18 00:11:22 +00:00
#include "api/api.h"
#include "event/event.h"
#include "core/os.h"
2022-03-22 07:13:21 +00:00
#include "util.h"
2022-03-30 19:13:53 +00:00
#include "boot.lua.h"
2021-03-16 00:54:27 +00:00
#include <lua.h>
#include <lauxlib.h>
2021-02-07 23:51:31 +00:00
#include <lualib.h>
2018-09-27 04:55:54 +00:00
#include <stdbool.h>
2018-05-15 04:38:50 +00:00
#include <string.h>
2018-02-17 17:18:08 +00:00
#include <stdlib.h>
2018-11-16 15:36:44 +00:00
#ifdef EMSCRIPTEN
#include <emscripten.h>
2018-11-16 15:36:44 +00:00
typedef struct {
lua_State* L;
lua_State* T;
int argc;
char** argv;
} lovrEmscriptenContext;
2020-12-25 19:18:57 +00:00
static void emscriptenLoop(void*);
2018-11-16 15:36:44 +00:00
#endif
2021-02-19 16:06:16 +00:00
static Variant cookie;
2016-08-08 20:51:22 +00:00
int main(int argc, char** argv) {
2018-09-27 04:45:45 +00:00
if (argc > 1 && (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-v"))) {
2021-02-25 16:00:12 +00:00
os_open_console();
2019-08-22 02:02:02 +00:00
printf("LOVR %d.%d.%d (%s)\n", LOVR_VERSION_MAJOR, LOVR_VERSION_MINOR, LOVR_VERSION_PATCH, LOVR_VERSION_ALIAS);
2018-02-17 17:18:08 +00:00
exit(0);
}
2022-03-25 07:59:57 +00:00
if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) {
os_open_console();
printf(
"usage: lovr [options] [<source>]\n\n"
"options:\n"
2022-03-25 07:59:57 +00:00
" -h, --help\t\tShow help and exit\n"
" -v, --version\t\tShow version and exit\n"
" --console\t\tAttach Windows console\n\n"
"<source> can be a Lua file, a folder, or a zip archive\n"
2022-03-25 07:59:57 +00:00
);
exit(0);
}
if (!os_init()) {
fprintf(stderr, "Failed to initialize platform");
exit(1);
}
2018-05-15 04:38:50 +00:00
int status;
2018-10-29 20:52:50 +00:00
bool restart;
do {
lua_State* L = luaL_newstate();
luax_setmainthread(L);
2018-10-29 20:52:50 +00:00
luaL_openlibs(L);
2021-03-16 00:54:27 +00:00
luax_preload(L);
2018-10-29 20:52:50 +00:00
// arg table
lua_newtable(L);
2020-12-25 19:18:57 +00:00
lua_pushstring(L, argc > 0 ? argv[0] : "lovr");
lua_setfield(L, -2, "exe");
luax_pushvariant(L, &cookie);
lua_setfield(L, -2, "restart");
2020-12-25 19:18:57 +00:00
int argOffset = 1;
for (int i = 1; i < argc; i++, argOffset++) {
if (!strcmp(argv[i], "--console")) {
2021-02-25 16:00:12 +00:00
os_open_console();
2020-12-25 19:18:57 +00:00
} else {
break; // This is the project path
}
}
2020-12-25 19:18:57 +00:00
// Now that we know the negative offset to start at, copy all args in the table
for (int i = 0; i < argc; i++) {
lua_pushstring(L, argv[i]);
2020-12-25 19:18:57 +00:00
lua_rawseti(L, -2, -argOffset + i);
}
lua_setglobal(L, "arg");
lua_pushcfunction(L, luax_getstack);
2022-03-30 19:13:53 +00:00
if (luaL_loadbuffer(L, (const char*) etc_boot_lua, etc_boot_lua_len, "@boot.lua") || lua_pcall(L, 0, 1, -2)) {
fprintf(stderr, "%s\n", lua_tostring(L, -1));
2018-10-29 20:52:50 +00:00
return 1;
}
2018-10-29 20:52:50 +00:00
lua_State* T = lua_newthread(L);
lua_pushvalue(L, -2);
lua_xmove(L, T, 1);
2019-09-24 14:28:34 +00:00
lovrSetErrorCallback(luax_vthrow, T);
lovrSetLogCallback(luax_vlog, T);
2018-10-29 20:52:50 +00:00
#ifdef EMSCRIPTEN
lovrEmscriptenContext context = { L, T, argc, argv };
emscripten_set_main_loop_arg(emscriptenLoop, (void*) &context, 0, 1);
return 0;
#endif
2020-08-19 19:12:06 +00:00
while (luax_resume(T, 0) == LUA_YIELD) {
2021-02-25 16:00:12 +00:00
os_sleep(0.);
2018-10-29 20:52:50 +00:00
}
restart = lua_type(T, 1) == LUA_TSTRING && !strcmp(lua_tostring(T, 1), "restart");
status = lua_tonumber(T, 1);
luax_checkvariant(T, 2, &cookie);
if (cookie.type == TYPE_OBJECT) {
cookie.type = TYPE_NIL;
memset(&cookie.value, 0, sizeof(cookie.value));
}
2018-10-29 20:52:50 +00:00
lua_close(L);
} while (restart);
2021-02-25 16:00:12 +00:00
os_destroy();
2018-10-29 20:52:50 +00:00
return status;
2016-07-07 07:04:24 +00:00
}
2020-12-25 19:18:57 +00:00
#ifdef EMSCRIPTEN
2021-03-16 00:54:27 +00:00
// Called by JS, don't delete
2020-12-25 19:18:57 +00:00
void lovrDestroy(void* arg) {
if (arg) {
lovrEmscriptenContext* context = arg;
lua_State* L = context->L;
emscripten_cancel_main_loop();
lua_close(L);
2021-02-25 16:00:12 +00:00
os_destroy();
2020-12-25 19:18:57 +00:00
}
}
static void emscriptenLoop(void* arg) {
lovrEmscriptenContext* context = arg;
lua_State* T = context->T;
if (luax_resume(T, 0) != LUA_YIELD) {
2021-02-19 16:06:16 +00:00
bool restart = lua_type(T, 1) == LUA_TSTRING && !strcmp(lua_tostring(T, 1), "restart");
int status = lua_tonumber(T, 1);
luax_checkvariant(T, 2, &cookie);
if (cookie.type == TYPE_OBJECT) {
cookie.type = TYPE_NIL;
memset(&cookie.value, 0, sizeof(cookie.value));
}
2020-12-25 19:18:57 +00:00
lua_close(context->L);
emscripten_cancel_main_loop();
if (restart) {
main(context->argc, context->argv);
} else {
2021-02-25 16:00:12 +00:00
os_destroy();
2020-12-25 19:18:57 +00:00
exit(status);
}
}
}
#endif