lovr/etc/boot.lua

268 lines
7.1 KiB
Lua
Raw Normal View History

2018-09-27 03:14:16 +00:00
lovr = require 'lovr'
-- Note: Cannot be overloaded
function lovr.boot()
local conf = {
2022-10-16 04:49:25 +00:00
version = '0.16.0',
2019-11-25 01:27:17 +00:00
identity = 'default',
saveprecedence = true,
modules = {
audio = true,
data = true,
event = true,
graphics = true,
headset = true,
math = true,
physics = true,
2021-02-25 16:00:12 +00:00
system = true,
thread = true,
timer = true
},
audio = {
start = true,
2021-03-08 05:42:17 +00:00
spatializer = nil
},
2022-04-27 05:48:51 +00:00
graphics = {
debug = false,
vsync = true,
stencil = false,
antialias = true,
shadercache = true
2022-04-27 05:48:51 +00:00
},
headset = {
drivers = { 'openxr', 'webxr', 'desktop' },
supersample = false,
offset = 1.7,
stencil = false,
antialias = true,
2022-08-07 06:45:37 +00:00
submitdepth = true,
2020-11-18 00:38:27 +00:00
overlay = false
},
2019-06-10 07:11:20 +00:00
math = {
2019-07-01 09:16:13 +00:00
globals = true
2019-06-10 07:11:20 +00:00
},
window = {
2022-08-02 04:46:00 +00:00
width = 720,
height = 800,
fullscreen = false,
resizable = false,
title = 'LÖVR',
2022-05-09 19:43:19 +00:00
icon = nil
}
}
2017-12-19 00:01:12 +00:00
lovr.filesystem = require('lovr.filesystem')
local main = arg[0] and arg[0]:match('[^\\/]-%.lua$') or 'main.lua'
local hasConf, hasMain = lovr.filesystem.isFile('conf.lua'), lovr.filesystem.isFile(main)
2022-07-07 06:50:43 +00:00
if not lovr.filesystem.getSource() or not (hasConf or hasMain) then require('nogame') end
2017-12-19 00:01:12 +00:00
-- Shift args up in fused mode, instead of consuming one for the source path
if lovr.filesystem.isFused() then
for i = 1, #arg + 1 do
arg[i] = arg[i - 1]
end
arg[0] = lovr.filesystem.getSource()
end
local confOk, confError = true
if hasConf then confOk, confError = pcall(require, 'conf') end
if confOk and lovr.conf then confOk, confError = pcall(lovr.conf, conf) end
lovr._setConf(conf)
lovr.filesystem.setIdentity(conf.identity, conf.saveprecedence)
2017-12-19 00:01:12 +00:00
for module in pairs(conf.modules) do
if conf.modules[module] then
2018-09-27 18:45:43 +00:00
local ok, result = pcall(require, 'lovr.' .. module)
if not ok then
print(string.format('Warning: Could not load module %q: %s', module, result))
else
lovr[module] = result
end
end
2017-12-19 00:01:12 +00:00
end
2022-05-09 19:43:19 +00:00
if lovr.system and conf.window then
lovr.system.openWindow(conf.window)
end
2022-04-21 07:27:13 +00:00
if lovr.graphics then
lovr.graphics.initialize()
2022-04-21 07:27:13 +00:00
end
if lovr.headset then
lovr.headset.start()
if lovr.headset.getDriver() == 'desktop' then
lovr.mirror = nil
end
end
lovr.handlers = setmetatable({}, { __index = lovr })
if not confOk then error(confError) end
if hasMain then require(main:gsub('%.lua$', '')) end
return lovr.run()
2017-12-19 00:01:12 +00:00
end
function lovr.run()
if lovr.timer then lovr.timer.step() end
if lovr.load then lovr.load(arg) end
return function()
if lovr.event then
lovr.event.pump()
for name, a, b, c, d in lovr.event.poll() do
if name == 'restart' then
local cookie = lovr.restart and lovr.restart()
return 'restart', cookie
elseif name == 'quit' and (not lovr.quit or not lovr.quit(a)) then
return a or 0
end
if lovr.handlers[name] then lovr.handlers[name](a, b, c, d) end
end
2017-12-19 00:01:12 +00:00
end
local dt = 0
if lovr.timer then dt = lovr.timer.step() end
if lovr.headset then dt = lovr.headset.update() end
if lovr.update then lovr.update(dt) end
if lovr.graphics then
if lovr.headset then
local pass = lovr.headset.getPass()
if pass then
local skip = lovr.draw and lovr.draw(pass)
if not skip then lovr.graphics.submit(pass) end
2022-06-06 03:38:14 +00:00
end
end
if lovr.system.isWindowOpen() then
if lovr.mirror then
local pass = lovr.graphics.getWindowPass()
2022-11-08 06:45:10 +00:00
local skip = not pass or lovr.mirror(pass)
if not skip then lovr.graphics.submit(pass) end
end
lovr.graphics.present()
2022-06-06 03:38:14 +00:00
end
end
2022-06-06 03:38:14 +00:00
if lovr.headset then lovr.headset.submit() end
if lovr.math then lovr.math.drain() end
2017-12-19 00:01:12 +00:00
end
end
2022-06-06 03:38:14 +00:00
function lovr.mirror(pass)
if lovr.headset then
2022-07-18 03:07:31 +00:00
local texture = lovr.headset.getTexture()
if texture then
pass:fill(texture)
else
return true
2022-07-18 03:07:31 +00:00
end
2022-06-06 03:38:14 +00:00
else
2022-07-18 03:07:31 +00:00
return lovr.draw and lovr.draw(pass)
2022-06-06 03:38:14 +00:00
end
end
local function formatTraceback(s)
return s:gsub('\n[^\n]+$', ''):gsub('\t', ''):gsub('stack traceback', '\nStack')
end
2022-08-13 03:32:45 +00:00
function lovr.errhand(message)
message = tostring(message) .. formatTraceback(debug.traceback('', 4))
print('Error:\n' .. message)
2022-06-21 01:26:32 +00:00
if not lovr.graphics or not lovr.graphics.isInitialized() then
return function() return 1 end
end
2022-07-11 04:37:52 +00:00
2022-08-13 03:46:59 +00:00
if lovr.audio then lovr.audio.stop() end
local scale = .35
2022-07-11 04:37:52 +00:00
local font = lovr.graphics.getDefaultFont()
local wrap = .7 * font:getPixelDensity()
local lines = font:getLines(message, wrap)
2022-08-02 04:46:00 +00:00
local width = math.min(font:getWidth(message), wrap) * scale
local height = .8 + #lines * font:getHeight() * scale
2022-07-11 04:37:52 +00:00
local x = -width / 2
local y = math.min(height / 2, 10)
2022-08-02 04:46:00 +00:00
local z = -10
2022-08-13 03:32:45 +00:00
lovr.graphics.setBackgroundColor(.11, .10, .14)
2022-07-11 04:37:52 +00:00
font:setPixelDensity()
2022-06-21 01:26:32 +00:00
local function render(pass)
2022-07-11 04:37:52 +00:00
pass:setColor(.95, .95, .95)
2022-08-02 04:46:00 +00:00
pass:text('Error', x, y, z, scale * 1.6, 0, 0, 0, 0, nil, 'left', 'top')
pass:text(message, x, y - .8, z, scale, 0, 0, 0, 0, wrap, 'left', 'top')
2022-06-21 01:26:32 +00:00
end
return function()
lovr.event.pump()
2022-08-13 03:32:45 +00:00
2022-06-21 01:26:32 +00:00
for name, a in lovr.event.poll() do
if name == 'quit' then return a or 1
2022-07-11 04:37:52 +00:00
elseif name == 'restart' then return 'restart', lovr.restart and lovr.restart()
elseif name == 'keypressed' and a == 'f5' then lovr.event.restart() end
2022-06-21 01:26:32 +00:00
end
2022-08-13 03:32:45 +00:00
2022-08-13 02:28:25 +00:00
if lovr.headset and lovr.headset.getDriver() ~= 'desktop' then
2022-06-21 01:26:32 +00:00
lovr.headset.update()
2022-08-06 07:29:40 +00:00
local pass = lovr.headset.getPass()
if pass then
2022-06-21 01:26:32 +00:00
render(pass)
2022-08-13 02:28:25 +00:00
lovr.graphics.submit(pass)
2022-08-13 03:32:45 +00:00
lovr.headset.submit()
2022-06-21 01:26:32 +00:00
end
end
2022-08-13 03:32:45 +00:00
2022-06-21 01:26:32 +00:00
if lovr.system.isWindowOpen() then
2022-08-06 07:29:40 +00:00
local pass = lovr.graphics.getWindowPass()
2022-11-08 06:45:10 +00:00
if pass then
render(pass)
lovr.graphics.submit(pass)
lovr.graphics.present()
end
2022-06-21 01:26:32 +00:00
end
end
2017-12-19 00:01:12 +00:00
end
2018-03-12 17:37:45 +00:00
function lovr.threaderror(thread, err)
error('Thread error\n\n' .. err, 0)
2018-03-12 17:37:45 +00:00
end
function lovr.log(message, level, tag)
message = message:gsub('\n$', '')
print(message)
end
return function()
local errored = false
local function onerror(...)
if not errored then
errored = true -- Ensure errhand is only called once
return lovr.errhand(...) or function() return 1 end
else
local message = tostring(...) .. formatTraceback(debug.traceback('', 2))
print('Error occurred while trying to display another error:\n' .. message)
return function() return 1 end
end
end
-- thread will be either lovr.run's step function, or the result of errhand
local _, thread = xpcall(lovr.boot, onerror)
while true do
local ok, result, cookie = xpcall(thread, onerror)
-- If step function returned something, exit coroutine and return to C
if result and ok then
return result, cookie
elseif not ok then -- Switch to errhand loop
thread = result
if type(thread) ~= 'function' then
print('Error occurred while trying to display another error:\n' .. tostring(result))
return 1
end
end
coroutine.yield()
end
2017-12-19 00:01:12 +00:00
end