diff --git a/ll-min.lua b/ll-min.lua new file mode 100644 index 0000000..37edda9 --- /dev/null +++ b/ll-min.lua @@ -0,0 +1,23 @@ +-- minimal Love Loader API + +if not llUsed then + +COLDIV = love.getVersion() == 0 and 1 or 255 + +function love.resize(x, y) + W, H = x, y + + if resize then resize(W, H) end + + collectgarbage 'collect' -- because new font isn't clears +end +love.resize(love.graphics.getDimensions()) + +function llHome() + love.event.push('quit') +end +function love.event.quit() + llHome() +end + +end diff --git a/main.lua b/main.lua index 4af53cb..c45271c 100644 --- a/main.lua +++ b/main.lua @@ -10,15 +10,14 @@ local sgme local cx, cy, cw, ch local f, bf -function love.resize(x, y) - W, H = x, y +local ffi = require 'ffi' +local fd +ffi.cdef [[ + int PHYSFS_mount(const char *, const char *, int); + int PHYSFS_unmount(const char *); +]] - if resize then resize(W, H) end - - collectgarbage 'collect' -- because new font isn't clears -end - -function resize() +local function llResz() cw, ch = W / 1.25, H / 1.25 cx, cy = (W - cw) / 2, (H - ch) / 2 @@ -27,8 +26,31 @@ function resize() f = love.graphics.newFont(th / 3) bf = love.graphics.newFont(th / 2) end +resize = llResz -love.resize(love.graphics.getDimensions()) +require 'll-min' +llUsed = true + +local function chroot(dir, main) + fd = love.filesystem.getSource() .. dir + love.filesystem.setRequirePath( + '?.lua;?/init.lua;' + .. dir .. '/?.lua;' + .. dir .. '/?/init.lua;' + ) + -- FIXME: Bug in Linux (Debian) + ffi.C.PHYSFS_mount(fd, '/', 0); + if main then + load(love.filesystem.read(dir ..'/'.. main), main)() + end +end + +local function escChroot() + if fd then + ffi.C.PHYSFS_unmount(fd); + fd = nil + end +end local function gmeNew(cont, dir, file) local gme = { @@ -36,6 +58,9 @@ local function gmeNew(cont, dir, file) desc = 'No description provided.', dir = dir, main = 'main.lua', + pics = nil, + psel = 2, + ppsl = 1, } local fi = false cont = cont or '' @@ -47,10 +72,27 @@ local function gmeNew(cont, dir, file) or k == 'main' then gme[k] = v fi = true + elseif k == 'pic' then + gme.pics = gme.pics or {} + table.insert(gme.pics, v) + fi = true + elseif k == 'pics' then + local t = {} + v = v:sub(2, -2) + for v in v:gmatch '%s*([^;]+%a+)%s*;?' + do table.insert(t, v) end + gme[k] = t + fi = true elseif k then error('unknown field "'.. k ..'" in "'.. file ..'"') end end + if gme.pics then + for k, v in pairs(gme.pics) do + gme.pics[k] = love.graphics.newImage(root .. dir ..'/'.. v) + end + gme.psel = math.min(2, #gme.pics) + end if not fi then gme.name = dir end @@ -63,7 +105,11 @@ for _, v in pairs(love.filesystem.getDirectoryItems(root)) do end local pf, mx, mb, mpb -local function update() + +local pcht = 60 * 5 +local pchat = math.floor(1 / pcht * 2 * 255 + 0.5) +local pchv, pcha = 0, 0 +local function llUpdate() mx = love.mouse.getX() mpb = mb mb = 0 @@ -80,9 +126,23 @@ local function update() else sgme = gms[sel] end end + + pchv = pchv + 1 + if pchv >= pcht then + pchv, pcha = 0, 0 + for _, v in pairs(gms) do + if v.pics then + v.ppsl = v.psel + v.psel = v.psel + 1 + if v.psel > #v.pics + then v.psel = 1 end + end + end + else pcha = math.min(255, pcha + pchat) + end end -local function draw() +local function llDraw() love.graphics.polygon('fill', 8, H / 2, 32, H / 2 - 32, @@ -97,8 +157,15 @@ local function draw() local gme = gms[sel] if gme then local ph = ch / 1.5 + if gme.pics then + local p, n = gme.pics[gme.ppsl], gme.pics[gme.psel] + love.graphics.draw(p, cx, cy, 0, cw / p:getWidth(), ph / p:getHeight()) + love.graphics.setColor(255, 255, 255, pcha / COLDIV) + love.graphics.draw(n, cx, cy, 0, cw / n:getWidth(), ph / n:getHeight()) + love.graphics.setColor(255, 255, 255, 255) + end + love.graphics.rectangle('line', cx, cy, cw, ph) love.graphics.rectangle('line', cx, cy, cw, ch) - love.graphics.rectangle('fill', cx, cy, cw, ph) oy = cy + ph love.graphics.setFont(bf) @@ -118,32 +185,35 @@ local function draw() end end -function love.handlers.quit(c) - -- for some cases when event handler (like this one below) can't correctly close - os.exit(c or 0) +function llHome() + escChroot() + love.event.push('quit', 'restart') end -while not sgme do +local brk = false +while not brk and not sgme do -- event handling love.event.pump() for n, a,b,c,d,e,f in love.event.poll() do + if n == 'quit' then + escChroot() + love.event.push('quit') + brk = true; break + end love.handlers[n](a,b,c,d,e,f) end -- update and drawing - update() + llUpdate() love.graphics.origin() love.graphics.clear(0, 0, 0) - draw() + llDraw() love.graphics.present() love.timer.sleep(0.001) end -love.graphics.setNewFont() -resize = nil -require(root .. sgme.dir ..'/'.. sgme.main:sub(1, -5)) - --- things left: --- W and H global variables --- love.resize and optional global resize function --- love.handlers.quit - modified but can be required +if sgme then + love.graphics.setNewFont() + resize = nil + chroot(root .. sgme.dir, sgme.main) +end diff --git a/readme.md b/readme.md index 7e5ef31..46bbbf1 100644 --- a/readme.md +++ b/readme.md @@ -18,7 +18,15 @@ so there are some variables can be used in game: `love.resize` and optional `resize` payload: functions called when screen size when changed and at boot. -`love.handlers.quit`: function on exit which can be called until game was selected to keep responsive or for custom love.run function. +`love.event.quit`: function to quit to menu screen + +`COLDIV`: color divider (1 or 255) to setColor function + +`llUsed`: is Love Loader used + +`llHome`: function to quit to menu screen + +They also can be used without Love Loader if load `ll-min.lua` # Fill game information @@ -31,4 +39,6 @@ Syntax is `k = v` with `# comments` name = New awesome game using Love Loader desc = Some descripion about the game. # main = optional main file instead of `main.lua` +pic = screen.png +pics = [ screen.png; screen2.png ] # wow array ```