diff --git a/.gitignore b/.gitignore index 81b0c56..8500a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -dev -build/ -games/* -!games/.gitkeep +/.cache +/dev/ +/build/ +/games/* +!/games/.gitkeep diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..f06b433 --- /dev/null +++ b/build.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +echo General packaging +rm -r build +mkdir build +cd build + +mv ../dev ../deva +lua ~/proj/luapack/main.lua ../luapack.lua +mv ../deva ../dev + +#cp -r lib skins ll-min.lua build/ + +zip -9 -r ../game.love . +rm * +mv ../game.love . + +echo Windows packaging +VER=11.4 +BITS=64 +ARCH=x86_64 +if [ ! -d ../.cache/love-$VER-win$BITS ]; then + mkdir -p ../.cache/love-$VER-win$BITS + cd ../.cache + wget https://github.com/love2d/love/releases/download/$VER/love-$VER-win$BITS.zip + unzip love-$VER-win$BITS.zip + cd - +fi +mkdir win && cd win +cp -r ../../.cache/love-$VER-win$BITS/* . +cat love.exe ../game.love > game.exe +rm love.exe lovec.exe *.ico *.txt +zip -r ../win.zip * +cd .. +rm -r win + +echo Linux packaging +if [ ! -e ../.cache/love-$VER-$ARCH.AppImage ]; then + cd ../.cache + wget https://github.com/love2d/love/releases/download/$VER/love-$VER-$ARCH.AppImage + chmod a+x love-$VER-$ARCH.AppImage + cd - +fi +if [ ! -e ../.cache/appimagetool-$ARCH.AppImage ]; then + cd ../.cache + wget https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-$ARCH.AppImage + chmod a+x appimagetool-$ARCH.AppImage + cd - +fi +mkdir lin && cd lin +../../.cache/love-$VER-$ARCH.AppImage --appimage-extract > /dev/null +cd squashfs-root +cat ../../game.love >> bin/love +chmod a+x bin/love +cd .. +../../.cache/appimagetool-$ARCH.AppImage squashfs-root ../linux.AppImage > /dev/null +rm -r squashfs-root +chmod a+x ../linux.AppImage +cd .. +rm -r lin + diff --git a/lib/keyb.lua b/lib/keyb.lua index bf7d9b6..84b2e52 100644 --- a/lib/keyb.lua +++ b/lib/keyb.lua @@ -1,13 +1,14 @@ return function(ll) local mx, my, mb, mpb -local dir, sc1, sc2, sclm +local dir, sc1, sc2, sclm1, sclm2 --- d - direction (h, v, x, y, *) --- c1 - coordinate before card (mouse) (be left or top) --- c2 - coordinate after card (mouse) (be right or bottom) --- clm - other coordinate limit (mouse) (set -1 to disable) -function ll.kbInit(d, c1, c2, clim) +-- d - direction (h, v, x, y, *) +-- c1 - coordinate before card (mouse) (be left or top) +-- c2 - coordinate after card (mouse) (be right or bottom) +-- clim1 - other coordinate limit before (mouse) (set -1 to disable) +-- clim2 - other coordinate limit after (mouse) (set -1 to disable) +function ll.kbInit(d, c1, c2, clim1, clim2) if d == 'h' or d == 'v' or d == '*' then dir = d elseif d == 'y' @@ -17,19 +18,37 @@ function ll.kbInit(d, c1, c2, clim) else error 'Direction must be *, h (x) or v (y)' end + ll.kbSetCC(c1, c2) + ll.kbSetOC(clim1, clim2) +end + +-- set card coordinate +-- c1 - coordinate before card (mouse) (be left or top) +-- c2 - coordinate after card (mouse) (be right or bottom) +function ll.kbSetCC(c1, c2) c1, c2 = tonumber(c1) or 0, tonumber(c2) or 0 - sc1, sc2, sclm = + + sc1, sc2 = math.min(c1, c2), - math.max(c1, c2), - tonumber(clim) or -1 + math.max(c1, c2) +end + +-- set other coordinate limit +-- clim1 - other coordinate limit before (mouse) (set -1 to disable) +-- clim2 - other coordinate limit after (mouse) (set -1 to disable) +function ll.kbSetOC(clim1, clim2) + sclm1, sclm2 = + tonumber(clim1) or -1, + tonumber(clim2) or -1 end -- returns: <, >, o, m, nil -- ^ and v if dir is * function ll.kbGet() - assert(dir, 'Call ll.kbInit(dir, coord1, coord2, coordlimit) before') + assert(dir, 'Call ll.kbInit() before') + assert(love, 'Use it with LÖVE engine') mx, my = love.mouse.getPosition() mpb = mb if love.mouse.isDown(1) then mb = 1 @@ -56,7 +75,8 @@ function ll.kbGet() elseif mb == 0 and mpb == 1 then -- mouse unpressed if dir == 'h' then - if sclm < 0 or my <= sclm then + if (sclm1 < 0 or my > sclm1) + and (sclm2 < 0 or my <= sclm2) then if mx <= sc1 then return '<' elseif mx >= sc2 @@ -65,7 +85,8 @@ function ll.kbGet() end end else - if sclm < 0 or mx <= sclm then + if (sclm1 < 0 or mx > sclm1) + and (sclm2 < 0 or mx <= sclm2) then if my <= sc1 then return '<' elseif my >= sc2 diff --git a/lib/main.lua b/lib/main.lua index 9859a1e..f119d65 100644 --- a/lib/main.lua +++ b/lib/main.lua @@ -4,19 +4,25 @@ ll.cfg = { root = 'games/', } -require 'lib.fs' (ll) -require 'lib.game' (ll) -require 'lib.chroot' (ll) -require 'lib.load' (ll) -require 'lib.keyb' (ll) +require 'lib.fs' (ll) +require 'lib.game' (ll) +if love then + require 'lib.chroot' (ll) + -- TODO: CLI interface? + require 'lib.load' (ll) +end +require 'lib.keyb' (ll) -- except ll.kbGet() function ll.home() + if not love then return end ll.umount() love.event.push('quit', 'restart') end ll.dt = false function ll.devtools() + if not love then return end + if not ll.dt then ll.dt = true __LL = ll @@ -27,3 +33,4 @@ function ll.devtools() end return ll + diff --git a/ll-min.lua b/ll-min.lua index 86e6389..a47f01a 100644 --- a/ll-min.lua +++ b/ll-min.lua @@ -6,8 +6,11 @@ if not llUsed then COLDIV = love.getVersion() == 0 and 1 or 255 -MOBILE = love.system.getOS() == 'Android' +if love.system +then MOBILE = love.system.getOS() == 'Android' or love.system.getOS() == 'iOS' +else MOBILE = false +end function llHome() love.event.push('quit', 'restart') diff --git a/luapack.lua b/luapack.lua index ab4dec7..b4787e4 100644 --- a/luapack.lua +++ b/luapack.lua @@ -1,6 +1,9 @@ return { - entry = 'main.lua', - output = 'build/main.lua', + entry = { + 'main.lua', + 'll-min.lua', + }, + output = 'build/$name.lua', plug = { require 'plug.minify' { extGlob = { diff --git a/main.lua b/main.lua index 2c84ede..6364fcd 100644 --- a/main.lua +++ b/main.lua @@ -1,7 +1,7 @@ local ll = require 'lib.main' error = love.errhand or love.errorhandler -ll.skin = require 'skins.psp' (ll) +ll.skin = require 'skins.nx' (ll) function splash() if not ll.mgme then return end diff --git a/skins/nx.lua b/skins/nx.lua new file mode 100644 index 0000000..1bbf750 --- /dev/null +++ b/skins/nx.lua @@ -0,0 +1,71 @@ +return function(ll) + +-- Nintendo NX (AKA Switch) UI + +local r + +os.setlocale('', 'time') + +function resize() + r = math.min(W, H) / 30 + + f = love.graphics.setNewFont(math.min(W, H) / 30) + bf = love.graphics.newFont(math.min(W, H) / 20) + + --ll.kbInit('h', H / 2 - ch, H / 2 + ch + cg, 0, cx + cw * 2) +end + +local function update(dt) +end + +local function roundRect(m, x, y, w, h, r) + if w < 1 or h < 1 then return end + + love.graphics.rectangle(m, x, y, w, h, r) + + if m == 'fill' + then roundRect('line', x, y, w, h, r) + end +end + +local function draw() + love.graphics.setColor(0 / COLDIV, 50 / COLDIV, 75 / COLDIV) + love.graphics.rectangle('fill', 0, 0, W, H) + love.graphics.setColor(255, 255, 255) + -- Indicators + love.graphics.push() + love.graphics.translate(W - W / 16, H / 16) + love.graphics.setLineWidth(r / 8) + local pst, pper = love.system.getPowerInfo() + if pst ~= 'nobattery' then + pper = pper or 0 + if pst == 'charging' + then pper = os.time() % 5 / 4 * 100 + end + roundRect('line', -r * 2.2, 0, r * 2, r * 1.2, r / 4) + roundRect('fill', -r / 6, r * 0.3, r / 4, r / 2, r / 16) + roundRect('fill', -r * 1.95, r * 0.3, r * 1.5 * pper / 100, r * 0.6, r / 16) + love.graphics.translate(-r * 2.8, 0) + end + local time = os.date('%X'):gsub('^(%d+.+%d+).+%d+', '%1') + local w = f:getWidth(time) + love.graphics.print(time, -w, -2) + love.graphics.pop() +end + +local function addGame(file, cont, x, y) + local msg, id = ll.addGame(file, cont) + love.graphics.print(msg, x, y) + if id then + sel = id + end +end + +return { + update = update, + draw = draw, + addGame = addGame, +} + +end + diff --git a/skins/psp.lua b/skins/psp.lua index 7988d83..5a766c1 100644 --- a/skins/psp.lua +++ b/skins/psp.lua @@ -18,6 +18,8 @@ local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5) local logger = '' local chc = '<>><' +os.setlocale('', 'time') + function resize() r = math.min(W, H) / 30 @@ -30,11 +32,9 @@ function resize() f = love.graphics.setNewFont(math.min(W, H) / 30) bf = love.graphics.newFont(math.min(W, H) / 20) - ll.kbInit('v', H / 2 - ch, H / 2 + ch + cg, cx + cw * 2) + ll.kbInit('v', H / 2 - ch, H / 2 + ch + cg, 0, cx + cw * 2) end -love.window.setMode(800, 600, {resizable = true}) - local sdir local function update(dt) local ty = H / 2 - (ch + cg) * sel @@ -68,10 +68,6 @@ local function update(dt) if sel > #ll.games then sel = 1 end end - if logger:sub(-3) == 'mm' - then ll.skin = require 'skins.select' (ll) - end - pikchv = pikchv + dt if pikchv >= ll.cfg.pcht / 100 then pikchv, pikcha = 0, 0 @@ -99,6 +95,16 @@ local function scrCard(gme, x, y, w, h, a) love.graphics.rectangle('fill', x, y, w, h) end +local function roundRect(m, x, y, w, h, r) + if w < 1 or h < 1 then return end + + love.graphics.rectangle(m, x, y, w, h, r) + + if m == 'fill' + then roundRect('line', x, y, w, h, r) + end +end + local function draw() love.graphics.setColor(0 / COLDIV, 50 / COLDIV, 75 / COLDIV) love.graphics.rectangle('fill', 0, 0, W, H) @@ -112,6 +118,28 @@ local function draw() sel = #ll.games end love.graphics.setFont(f) + + -- battery indicators + love.graphics.setColor(255, 255, 255) + love.graphics.push() + love.graphics.translate(W - r * 1.5, r) + love.graphics.setLineWidth(r / 8) + local pst, pper = love.system.getPowerInfo() + if pst ~= 'nobattery' then + pper = pper or 0 + if pst == 'charging' + then pper = os.time() % 5 / 4 * 100 + end + roundRect('line', -r * 2.2, 0, r * 2, r * 1.2, r / 4) + roundRect('fill', -r / 6, r * 0.3, r / 4, r / 2, r / 16) + roundRect('fill', -r * 1.95, r * 0.3, r * 1.5 * pper / 100, r * 0.6, r / 16) + love.graphics.translate(-r * 2.8, 0) + end + local time = os.date('%X'):gsub('^(%d+.+%d+).+%d+', '%1') + local w = f:getWidth(time) + love.graphics.print(time, -w, -2) + love.graphics.pop() + local oy = 0 for k, v in pairs(ll.games) do local x, w, h, g = cx, cw, ch, cg diff --git a/skins/select.lua b/skins/select.lua deleted file mode 100644 index 277e7b1..0000000 --- a/skins/select.lua +++ /dev/null @@ -1,130 +0,0 @@ -return function(ll) - -local skins = { - require 'skins.psp', - require 'skins.gui', - require 'skins.base', - require 'skins.select', -} - -local sel = 1 -local sk, ssel - -local cx, cw, ch - -local scx, scy = 1, 1 -local tscx, tscy -local canv - -local resz, l - -function load(nunl) - l = true - resize = nil - assert(skins[sel], 'Skin does not exists') - sk = skins[sel](ll) - love.resize(love.graphics.getDimensions()) - sk.update() - if not nunl then - if sk.lovecb then - for _, v in pairs(sk.lovecb) - do love[v] = nil - end - end - resize = resz - love.resize(love.graphics.getDimensions()) - - love.graphics.setCanvas(canv) - love.graphics.setColor(0, 0, 0) - love.graphics.rectangle('fill', 0, 0, W, H) - love.graphics.setColor(255, 255, 255) - sk.draw() - love.graphics.setCanvas() - else ll.skin = sk - end - l = false -end - -function resize() - cx = math.min(W, H) / 8 - cw, ch = - W - cx * 2.5, - H - cx * 1.5 - tscx, tscy = - cw / W, - ch / H - - canv = love.graphics.newCanvas(W, H) - if not l then load() end - ll.kbInit('h', cx, W - cx) -end -resz = resize - -local d -local function update() - if not sk then load() end - scx = scx + (tscx - scx) * 0.1 - scy = scy + (tscy - scy) * 0.1 - - if ssel - and scx > 0.99 - and scy > 0.99 - then load(true) end - - local nd = ll.kbGet() - - if nd ~= d then - d = nd - - local ns = sel - - if d == '<' - then ns = sel - 1 - elseif d == '>' - then ns = sel + 1 - elseif d == 'o' - then ssel = true - tscx, tscy = 1, 1 - end - - if ns < 1 then ns = #skins end - if ns > #skins then ns = 1 end - - if sel ~= ns then - sel = ns - load() - end - end -end - -local function draw() - local w, h = W * scx, H * scy - local x, y, r = - (W - w) / 2, - (H - h) / 2, - math.min(W - w, H - h) / 8 - love.graphics.setColor(100 / COLDIV, 100 / COLDIV, 100 / COLDIV) - love.graphics.rectangle('fill', 0, 0, W, H) - love.graphics.setColor(255, 255, 255) - love.graphics.stencil(function() - love.graphics.rectangle('fill', x, y, w, h, r) - end) - love.graphics.setStencilTest('greater', 0) - love.graphics.draw(canv, x, y, 0, scx, scy) - love.graphics.setStencilTest() - love.graphics.rectangle('line', x, y, w, h, r) -end - --- execute if loaded from other skin -if ll.skin then - load() - resize() - update() -end - -return { - draw = draw, - update = update, -} - -end