2016-07-07 07:04:24 +00:00
|
|
|
#include "lovr.h"
|
2017-03-11 11:08:07 +00:00
|
|
|
#include "api/lovr.h"
|
2016-11-29 06:59:27 +00:00
|
|
|
#include "glfw.h"
|
2016-11-19 09:28:01 +00:00
|
|
|
#include "util.h"
|
|
|
|
#include <stdlib.h>
|
2016-07-16 05:39:17 +00:00
|
|
|
|
2017-03-31 00:22:06 +00:00
|
|
|
static int getStackTrace(lua_State* L) {
|
2016-11-29 06:59:27 +00:00
|
|
|
const char* message = luaL_checkstring(L, -1);
|
2017-03-31 00:22:06 +00:00
|
|
|
lua_getglobal(L, "debug");
|
|
|
|
lua_getfield(L, -1, "traceback");
|
|
|
|
lua_pushstring(L, message);
|
|
|
|
lua_pushinteger(L, 3);
|
|
|
|
lua_call(L, 2, 1);
|
|
|
|
return 1;
|
2016-11-29 06:59:27 +00:00
|
|
|
}
|
|
|
|
|
2017-03-11 21:51:15 +00:00
|
|
|
static int lovrGetOS(lua_State* L) {
|
|
|
|
#ifdef _WIN32
|
|
|
|
lua_pushstring(L, "Windows");
|
|
|
|
return 1;
|
|
|
|
#elif __APPLE__
|
|
|
|
lua_pushstring(L, "macOS");
|
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-12-02 01:39:10 +00:00
|
|
|
static int lovrGetVersion(lua_State* L) {
|
|
|
|
lua_pushnumber(L, LOVR_VERSION_MAJOR);
|
|
|
|
lua_pushnumber(L, LOVR_VERSION_MINOR);
|
|
|
|
lua_pushnumber(L, LOVR_VERSION_PATCH);
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
2016-11-29 06:59:27 +00:00
|
|
|
void lovrInit(lua_State* L, int argc, char** argv) {
|
2017-02-18 10:48:38 +00:00
|
|
|
if (argc > 1 && strcmp(argv[1], "--version") == 0) {
|
|
|
|
printf("LOVR %d.%d.%d (%s)\n", LOVR_VERSION_MAJOR, LOVR_VERSION_MINOR, LOVR_VERSION_PATCH, LOVR_VERSION_ALIAS);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2016-11-29 06:59:27 +00:00
|
|
|
initGlfw();
|
2016-11-26 01:31:41 +00:00
|
|
|
|
2016-11-01 00:14:31 +00:00
|
|
|
// arg global
|
|
|
|
lua_newtable(L);
|
|
|
|
if (argc > 0) {
|
|
|
|
lua_pushstring(L, argv[0]);
|
|
|
|
lua_rawseti(L, -2, -2);
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_pushstring(L, "lovr");
|
|
|
|
lua_rawseti(L, -2, -1);
|
|
|
|
for (int i = 1; i < argc; i++) {
|
|
|
|
lua_pushstring(L, argv[i]);
|
|
|
|
lua_rawseti(L, -2, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_setglobal(L, "arg");
|
2016-07-07 07:04:24 +00:00
|
|
|
|
2016-11-29 09:33:53 +00:00
|
|
|
// lovr
|
2016-07-07 07:04:24 +00:00
|
|
|
lua_newtable(L);
|
2017-03-11 21:51:15 +00:00
|
|
|
lua_pushcfunction(L, lovrGetOS);
|
|
|
|
lua_setfield(L, -2, "getOS");
|
2016-12-02 01:39:10 +00:00
|
|
|
lua_pushcfunction(L, lovrGetVersion);
|
|
|
|
lua_setfield(L, -2, "getVersion");
|
2016-07-07 07:04:24 +00:00
|
|
|
lua_setglobal(L, "lovr");
|
|
|
|
|
2016-08-05 21:02:09 +00:00
|
|
|
// Preload modules
|
2017-01-03 03:09:33 +00:00
|
|
|
luax_preloadmodule(L, "lovr.audio", l_lovrAudioInit);
|
2016-11-19 08:37:43 +00:00
|
|
|
luax_preloadmodule(L, "lovr.event", l_lovrEventInit);
|
|
|
|
luax_preloadmodule(L, "lovr.filesystem", l_lovrFilesystemInit);
|
|
|
|
luax_preloadmodule(L, "lovr.graphics", l_lovrGraphicsInit);
|
|
|
|
luax_preloadmodule(L, "lovr.headset", l_lovrHeadsetInit);
|
2017-01-19 09:56:17 +00:00
|
|
|
luax_preloadmodule(L, "lovr.math", l_lovrMathInit);
|
2016-11-19 08:37:43 +00:00
|
|
|
luax_preloadmodule(L, "lovr.timer", l_lovrTimerInit);
|
2016-08-01 00:21:04 +00:00
|
|
|
|
|
|
|
// Bootstrap
|
2017-02-19 00:07:45 +00:00
|
|
|
char buffer[8192];
|
2016-07-16 06:43:57 +00:00
|
|
|
snprintf(buffer, sizeof(buffer), "%s",
|
2017-03-31 00:22:06 +00:00
|
|
|
"-- boot.lua\n"
|
2016-08-01 00:21:04 +00:00
|
|
|
"local conf = { "
|
|
|
|
" modules = { "
|
2017-01-03 03:09:33 +00:00
|
|
|
" audio = true, "
|
2016-08-01 00:21:04 +00:00
|
|
|
" event = true, "
|
|
|
|
" graphics = true, "
|
2016-08-11 04:17:14 +00:00
|
|
|
" headset = true, "
|
2017-01-19 09:56:17 +00:00
|
|
|
" math = true, "
|
2016-08-01 00:21:04 +00:00
|
|
|
" timer = true "
|
2017-03-12 03:12:03 +00:00
|
|
|
" }, "
|
|
|
|
" headset = { "
|
|
|
|
" mirror = true "
|
2016-08-01 00:21:04 +00:00
|
|
|
" } "
|
|
|
|
"} "
|
2016-08-08 07:34:19 +00:00
|
|
|
|
2016-11-01 00:14:31 +00:00
|
|
|
"lovr.filesystem = require('lovr.filesystem') "
|
|
|
|
|
2016-08-01 00:21:04 +00:00
|
|
|
"local success, err = pcall(require, 'conf') "
|
|
|
|
"if lovr.conf then "
|
|
|
|
" success, err = pcall(lovr.conf, conf) "
|
|
|
|
"end "
|
2016-08-08 07:34:19 +00:00
|
|
|
|
2017-01-19 09:56:17 +00:00
|
|
|
"local modules = { 'audio', 'event', 'graphics', 'headset', 'math', 'timer' } "
|
2016-08-01 00:21:04 +00:00
|
|
|
"for _, module in ipairs(modules) do "
|
|
|
|
" if conf.modules[module] then "
|
|
|
|
" lovr[module] = require('lovr.' .. module) "
|
|
|
|
" end "
|
|
|
|
"end "
|
2016-08-08 07:34:19 +00:00
|
|
|
|
2016-11-07 22:30:32 +00:00
|
|
|
"lovr.filesystem.setIdentity(conf.identity or 'default') "
|
2017-03-12 03:12:03 +00:00
|
|
|
"if lovr.headset then lovr.headset.setMirrored(conf.headset and conf.headset.mirror) end "
|
2016-11-07 22:30:32 +00:00
|
|
|
|
2016-11-29 06:59:27 +00:00
|
|
|
"lovr.handlers = setmetatable({ "
|
2016-12-01 07:03:58 +00:00
|
|
|
" quit = function() end, "
|
2017-03-12 03:01:01 +00:00
|
|
|
" focus = function(f) "
|
|
|
|
" if lovr.focus then lovr.focus(f) end "
|
|
|
|
" end, "
|
2016-12-01 22:55:47 +00:00
|
|
|
" controlleradded = function(c) "
|
|
|
|
" if lovr.controlleradded then lovr.controlleradded(c) end "
|
|
|
|
" end, "
|
|
|
|
" controllerremoved = function(c) "
|
|
|
|
" if lovr.controllerremoved then lovr.controllerremoved(c) end "
|
2017-03-12 02:46:07 +00:00
|
|
|
" end, "
|
|
|
|
" controllerpressed = function(c, b) "
|
|
|
|
" if lovr.controllerpressed then lovr.controllerpressed(c, b) end "
|
|
|
|
" end, "
|
|
|
|
" controllerreleased = function(c, b) "
|
|
|
|
" if lovr.controllerreleased then lovr.controllerreleased(c, b) end "
|
2016-12-01 22:55:47 +00:00
|
|
|
" end "
|
2016-11-29 06:59:27 +00:00
|
|
|
"}, { "
|
|
|
|
" __index = function(self, event) "
|
2017-02-26 22:28:41 +00:00
|
|
|
" error('Unknown event: ' .. tostring(event)) "
|
2016-11-29 06:59:27 +00:00
|
|
|
" end "
|
|
|
|
"}) "
|
|
|
|
|
2016-07-16 06:43:57 +00:00
|
|
|
"function lovr.run() "
|
|
|
|
" if lovr.load then lovr.load() end "
|
|
|
|
" while true do "
|
2016-11-29 06:59:27 +00:00
|
|
|
" lovr.event.pump() "
|
|
|
|
" for name, a, b, c, d in lovr.event.poll() do "
|
|
|
|
" if name == 'quit' and (not lovr.quit or not lovr.quit()) then "
|
|
|
|
" return a "
|
|
|
|
" end "
|
|
|
|
" lovr.handlers[name](a, b, c, d) "
|
|
|
|
" end "
|
2016-07-23 22:41:15 +00:00
|
|
|
" local dt = lovr.timer.step() "
|
2017-01-07 01:45:15 +00:00
|
|
|
" if lovr.audio then "
|
|
|
|
" lovr.audio.update() "
|
|
|
|
" if lovr.headset and lovr.headset.isPresent() then "
|
|
|
|
" lovr.audio.setOrientation(lovr.headset.getOrientation()) "
|
2017-02-26 20:57:56 +00:00
|
|
|
" lovr.audio.setPosition(lovr.headset.getPosition()) "
|
|
|
|
" lovr.audio.setVelocity(lovr.headset.getVelocity()) "
|
2017-01-07 01:45:15 +00:00
|
|
|
" end "
|
|
|
|
" end "
|
2016-07-23 22:41:15 +00:00
|
|
|
" if lovr.update then lovr.update(dt) end "
|
2016-07-16 06:43:57 +00:00
|
|
|
" lovr.graphics.clear() "
|
2016-11-08 06:38:45 +00:00
|
|
|
" lovr.graphics.origin() "
|
2016-09-15 04:42:38 +00:00
|
|
|
" if lovr.draw then "
|
2016-10-24 20:43:07 +00:00
|
|
|
" if lovr.headset and lovr.headset.isPresent() then "
|
|
|
|
" lovr.headset.renderTo(lovr.draw) "
|
|
|
|
" else "
|
|
|
|
" lovr.draw() "
|
|
|
|
" end "
|
2016-09-15 04:42:38 +00:00
|
|
|
" end "
|
2016-07-16 06:43:57 +00:00
|
|
|
" lovr.graphics.present() "
|
2016-10-01 22:11:33 +00:00
|
|
|
" lovr.timer.sleep(.001) "
|
2016-07-16 06:43:57 +00:00
|
|
|
" end "
|
2016-11-02 03:27:15 +00:00
|
|
|
"end "
|
|
|
|
|
2017-02-26 22:28:41 +00:00
|
|
|
"function lovr.errhand(message) "
|
2017-03-31 00:22:06 +00:00
|
|
|
" message = 'Error:\\n' .. message:gsub('\\n[^\\n]+$', ''):gsub('\\t', ''):gsub('stack traceback', '\\nStack') "
|
2017-02-19 00:07:45 +00:00
|
|
|
" print(message) "
|
2017-03-13 02:23:26 +00:00
|
|
|
" lovr.graphics.reset() "
|
2017-03-31 00:22:06 +00:00
|
|
|
" lovr.graphics.setBackgroundColor(27, 25, 35) "
|
2017-02-19 00:07:45 +00:00
|
|
|
" lovr.graphics.setColor(220, 220, 220) "
|
2017-03-31 00:22:06 +00:00
|
|
|
" local font = lovr.graphics.getFont() "
|
|
|
|
" local pixelDensity = font:getPixelDensity() "
|
|
|
|
" local width = font:getWidth(message, .55 * pixelDensity) "
|
2017-02-19 00:07:45 +00:00
|
|
|
" local function render() "
|
2017-03-31 00:22:06 +00:00
|
|
|
" lovr.graphics.origin() "
|
|
|
|
" lovr.graphics.print(message, -width / 2, 0, -20, 1, 0, 0, 0, 0, .55 * pixelDensity, 'left') "
|
2017-02-19 00:07:45 +00:00
|
|
|
" end "
|
|
|
|
" while true do "
|
|
|
|
" lovr.event.pump() "
|
|
|
|
" for name in lovr.event.poll() do "
|
|
|
|
" if name == 'quit' then return end "
|
|
|
|
" end "
|
|
|
|
" lovr.graphics.clear() "
|
|
|
|
" if lovr.headset and lovr.headset.isPresent() then "
|
|
|
|
" lovr.headset.renderTo(render) "
|
|
|
|
" else "
|
|
|
|
" render() "
|
|
|
|
" end "
|
|
|
|
" lovr.graphics.present() "
|
2017-03-31 00:22:06 +00:00
|
|
|
" lovr.timer.sleep((lovr.headset and lovr.headset.isPresent()) and .001 or .1) "
|
2017-02-19 00:07:45 +00:00
|
|
|
" end "
|
2016-11-15 04:14:36 +00:00
|
|
|
"end "
|
|
|
|
|
2016-11-18 08:33:26 +00:00
|
|
|
"if lovr.filesystem.isFile('main.lua') then "
|
|
|
|
" require('main') "
|
|
|
|
"end"
|
2016-07-16 06:43:57 +00:00
|
|
|
);
|
|
|
|
|
2016-08-01 00:21:04 +00:00
|
|
|
if (luaL_dostring(L, buffer)) {
|
|
|
|
const char* message = luaL_checkstring(L, 1);
|
|
|
|
error("Unable to bootstrap LOVR: %s", message);
|
2016-07-07 07:04:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 06:50:57 +00:00
|
|
|
void lovrDestroy(int exitCode) {
|
2016-07-09 05:27:34 +00:00
|
|
|
glfwTerminate();
|
2016-10-14 06:50:57 +00:00
|
|
|
exit(exitCode);
|
2016-07-09 05:27:34 +00:00
|
|
|
}
|
|
|
|
|
2016-11-01 00:14:31 +00:00
|
|
|
void lovrRun(lua_State* L) {
|
2017-03-31 00:22:06 +00:00
|
|
|
lua_pushcfunction(L, getStackTrace);
|
2016-07-07 07:04:24 +00:00
|
|
|
|
|
|
|
// lovr.run()
|
|
|
|
lua_getglobal(L, "lovr");
|
|
|
|
lua_getfield(L, -1, "run");
|
2017-03-31 00:22:06 +00:00
|
|
|
if (lua_pcall(L, 0, 1, -3)) {
|
|
|
|
lua_getfield(L, -2, "errhand");
|
|
|
|
if (lua_isfunction(L, -1)) {
|
|
|
|
lua_pushvalue(L, -2);
|
|
|
|
if (!lua_pcall(L, 1, 0, 0)) {
|
|
|
|
lovrDestroy(1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
error(lua_tostring(L, -2));
|
|
|
|
}
|
2016-07-09 05:27:34 +00:00
|
|
|
|
2016-11-29 06:59:27 +00:00
|
|
|
// Exit with return value from lovr.run
|
|
|
|
int exitCode = luaL_optint(L, -1, 0);
|
2017-03-31 00:22:06 +00:00
|
|
|
lua_pop(L, 2);
|
|
|
|
|
2016-11-29 06:59:27 +00:00
|
|
|
lovrDestroy(exitCode);
|
2016-07-09 05:27:34 +00:00
|
|
|
}
|