infatuated/main.lua

255 lines
6.5 KiB
Lua

local oldprint = print
local function print(...)
oldprint("[Infatuated] "..string.format(...))
end
infatuated = {}
infatuated.version = "11.3"
infatuated.conf = {
identity = nil,
appendidentity = false,
version = infatuated.version,
console = false,
accelerometerjoystick = true,
externalstorage = false,
gammacorrect = false,
audio = {
mic = false,
mixwithsystem = true,
},
window = {
title = "Untitled",
icon = nil,
width = 800,
height = 600,
borderless = false,
resizable = false,
minwidth = 1,
minheight = 1,
fullscreen = false,
fullscreentype = "desktop",
vsync = 1,
msaa = 0,
depth = nil,
stencil = nil,
display = 1,
highdpi = false,
usedpiscale = true,
x = nil,
y = nil
},
modules = {
audio = true,
data = true,
event = true,
font = true,
graphics = true,
image = true,
joystick = true,
keyboard = true,
math = true,
mouse = true,
physics = true,
sound = true,
system = true,
thread = true,
timer = true,
touch = true,
video = true,
window = true
}
}
local js = require "js"
infatuated.js = js
local window = js.global
infatuated.path = window.infatuated.game;
local document = window.document
local canvas = document:getElementById("infatuated-canvas")
infatuated.canvas = canvas
local ctx = canvas:getContext("2d")
infatuated.ctx = ctx
infatuated.overlay = document:getElementById("infatuated-overlay")
infatuated.msgbox = {
root = document:getElementById("infatuated-msgbox"),
title = document:getElementById("infatuated-msgbox-title"),
text = document:getElementById("infatuated-msgbox-text"),
buttons = document:getElementById("infatuated-msgbox-buttons")
}
function infatuated.msgbox:show(title, text, buttons, callback)
self.title.textContent = title
self.text.textContent = text
for k, v in pairs(self.buttons.children) do
v:remove()
end
for i=1, #buttons do
local btn = document:createElement("button")
btn.textContent = buttons[i]
--btn.dataset.id = i
self.buttons:append(btn)
btn:addEventListener("click", function()
self:hide()
callback(i)
end)
end
infatuated.overlay.dataset.hidden = false
self.root.dataset.hidden = false
end
function infatuated.msgbox:hide()
infatuated.canvas:focus()
infatuated.overlay.dataset.hidden = true
self.root.dataset.hidden = true
end
--infatuated.msgbox:show("sample title", "the quick brown fox", {"a", "b", "c"}, oldprint)
print("Running game from path %q", path)
local function errorprint(...)
window.console:error("[Infatuated] "..string.format(...))
end
function infatuated.stop(status)
print("Stopping with code %s", status or "null")
infatuated.stopDue = status
end
function infatuated.crash(errmsg)
errorprint("%s\n%s", errmsg, debug.traceback())
if infatuated.crashed then
print("Error handler crashed; stopping execution entirely")
infatuated.loopGuest = function() end
else
infatuated.crashed = true
infatuated.loopGuest = love.errorhandler(errmsg)
end
end
function infatuated.parseColor(r, g, b, a)
if type(r) == "table" then
return infatuated.parseColor(r[1], r[2], r[3], r[4])
elseif type(r) == "number" then
a = a or 1
assert(type(g) == "number", "bad argument #2 to parseColor")
assert(type(b) == "number", "bad argument #3 to parseColor")
assert(type(a) == "number", "bad argument #4 to parseColor")
--return {r, g, b, a}, string.format("rgba(%f, %f, %f, %f)", r, g, b, a)
return {r, g, b, a}, string.format("rgba(%f, %f, %f, %f)", r*255, g*255, b*255, a)
else
error("bad argument #1 to parseColor")
end
end
love = {}
function love.conf() end
function love.errorhandler(msg)
msg = tostring(msg)
oldprint((debug.traceback("Error: "..msg, 1+(layer or 1)):gsub("\n[^\n]+$", "")))
--if not love.window or not love.graphics or not love.event then return end -- SOMEHOW THIS IS AN "ATTEMPT TO INDEX A NIL VALUE". WTF????
if love.mouse then
love.mouse.setVisible(true)
love.mouse.setGrabbed(false)
love.mouse.setRelativeMode(false)
love.mouse.setCursor()
end
if love.audio then love.audio.stop() end
love.graphics.reset()
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setBackgroundColor(89/255, 157/255, 220/255)
return function()
love.graphics.clear()
love.graphics.print("An error was detected. Check console for details.", 70, 70)
love.graphics.present()
end
end
love.errhand = love.errorhandler
function love.run()
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setBackgroundColor(0, 0, 0, 1)
love.graphics.setLineWidth(2)
if love.load then love.load() end
infatuated.startTime = window.performance:now()
infatuated.dt1 = infatuated.startTime
return function()
if infatuated.stopDue then return infatuated.stopDue end
if love.update then love.update(infatuated.dt) end
if love.graphics and love.graphics.isActive() then
love.graphics.origin()
love.graphics.clear()
if love.draw then love.draw() end
love.graphics.present()
end
end
end
print("Coroutining now")
infatuated.thread = coroutine.create(function()
require "modules.data"
require "modules.event"
require "modules.filesystem"
require "modules.graphics"
require "modules.handlers"
require "modules.image"
require "modules.math"
require "modules.timer"
require "modules.window"
love.run()
local oldrequire = require
infatuated.require = oldrequire
function require(path)
assert(type(path) == "string", "bad argument #1 to require")
if path == "love" then return love end
return oldrequire(infatuated.path.."."..path)
end
print("Importing conf")
local status, errmsg = pcall(oldrequire, infatuated.path..".conf")
if not status and not errmsg:find("^module '.-%.conf' not found:") then
infatuated.crash(errmsg)
end
local status, errmsg = pcall(love.conf, infatuated.conf)
if not status then infatuated.crash(errmsg) end
print("Importing main")
local status, errmsg = pcall(oldrequire, infatuated.path..".main")
if not status then infatuated.crash(errmsg) end
local status, errmsg = pcall(love.run)
if not status then
infatuated.crash(errmsg)
else
infatuated.loopGuest = errmsg
end
print("Starting event loop")
infatuated.dt1 = window.performance:now()
local function resume()
coroutine.resume(infatuated.thread)
end
while true do
local dt2 = window.performance:now()
infatuated.dt = (dt2-infatuated.dt1)/1000
infatuated.dt1 = dt2
local status, errmsg = pcall(infatuated.loopGuest)
if not status then
infatuated.crash(errmsg)
elseif errmsg then
print("Exited with code %d", errmsg or -1)
return
end
window:requestAnimationFrame(resume)
coroutine.yield()
end
end)
coroutine.resume(infatuated.thread)