Compare commits

...

4 Commits

Author SHA1 Message Date
Er2 b8cecffec2 Update.
Add 2nd limit for other coordinate in lib/keyb.

Add build script.

Fix luapack.

Removed select skin (very buggy).

Added battery and time indicator in psp skin.
2022-09-08 21:45:22 +03:00
Er2 f56eabf59c DT and some internal updates, base skin scrolling. 2022-07-15 14:17:59 +03:00
Er2 c0a8f03063 fix stencil after some discussion in #1818 in love2d/love 2022-07-09 15:39:12 +03:00
Er2 ab8638bfe5 3.0 begin 2022-07-08 21:09:39 +03:00
12 changed files with 350 additions and 67 deletions

9
.gitignore vendored
View File

@ -1,5 +1,6 @@
dev
build/
games/*
!games/.gitkeep
/.cache
/dev/
/build/
/games/*
!/games/.gitkeep

61
build.sh Executable file
View File

@ -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

View File

@ -3,33 +3,51 @@ return function(ll)
ll.mdir = nil
ll.mgme = nil
local ffi = require 'ffi'
ffi.cdef [[
if love.getVersion() >= 12 then
function ll._mntdir(dir)
return love.filesystem.mountFullPath(dir, '/')
end
function ll._umntdir(dir)
love.filesystem.unmountFullPath(dir)
end
else
local ffi = require 'ffi'
local liblove = ffi.os == 'Windows'
and ffi.load 'love'
or ffi.C -- thanks to slime73, Love2D developer :)
ffi.cdef [[
int PHYSFS_mount(const char *, const char *, int);
int PHYSFS_unmount(const char *);
]]
int PHYSFS_unmount(const char *);]]
-- FIXME: Bug may appear in Linux. Recompile Love2D or use official PPA.
function ll._mntdir(dir)
return liblove.PHYSFS_mount(dir, '/', 0) ~= 0
end
function ll._umntdir(dir)
liblove.PHYSFS_unmount(dir)
end
end
local baseReq = '?.lua;?/init.lua;'
function ll.mount(gme)
local mdir = gme.base .. gme.dir
ll.mgme = gme
love.filesystem.setRequirePath(''
.. mdir .. '/?.lua;'
love.filesystem.setRequirePath(
mdir .. '/?.lua;'
.. mdir .. '/?/init.lua;'
.. baseReq
)
-- FIXME: Bug may appear in Linux. Recompile Love2D or use official PPA.
if ffi.C.PHYSFS_mount(mdir, '/', 0) == 0
then error('Cannot mount '..mdir)
if ll._mntdir(mdir)
then ll.mdir, ll.mgme = mdir, gme
else error('Cannot mount '..mdir)
love.filesystem.setRequirePath(baseReq)
else ll.mdir = mdir
end
end
function ll.umount()
if ll.mdir ~= nil then
ffi.C.PHYSFS_unmount(ll.mdir)
ll._umntdir(ll.mdir)
ll.mdir = nil
end
end

View File

@ -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
@ -54,9 +73,10 @@ function ll.kbGet()
elseif love.keyboard.isDown 'menu'
then return 'm'
elseif mb == 0 and mpb == 1 then -- unpressed
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

View File

@ -4,24 +4,33 @@ 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
pcall(function() require 'dev.tools' end)
return true
end
return false
end
return ll

View File

@ -1,13 +1,35 @@
-- Minimal Love Loader API
-- Version 2.1
-- Version 3.0
-- (c) Er2 2022 <er2@dismail.de>
-- Zlib License
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')
end
if love.getVersion() >= 12 then
function love.graphics.stencil(fn)
love.graphics.setColorMask(false)
love.graphics.setStencilMode('replace', 'always', 1)
fn()
love.graphics.setColorMask(true)
end
function love.graphics.setStencilTest(cmp, val)
if cmp
then love.graphics.setStencilMode('keep', cmp, val)
else love.graphics.setStencilMode()
end
end
end
if MOBILE
then love.window.setFullscreen(true)
@ -22,9 +44,6 @@ function love.resize(x, y)
end
love.resize(love.graphics.getDimensions())
function llHome()
love.event.push('quit')
end
function love.event.quit()
llHome()
end

View File

@ -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 = {

View File

@ -1,7 +1,10 @@
local ll = require 'lib.main'
error = love.errhand or love.errorhandler
ll.skin = require 'skins.nx' (ll)
function splash()
if not ll.mgme then return end
love.graphics.setColor(255, 255, 255, 100 / COLDIV)
if ll.mgme.screens and ll.mgme.screens[1] then
local img = love.graphics.newImage(ll.mgme.screens[1])
@ -11,16 +14,26 @@ function splash()
love.graphics.print('Loading '..ll.mgme.name, W / 2, H / 2)
end
ll.skin = require 'skins.psp' (ll)
require 'll-min'
llUsed = true
if love.errorhandler
if love.getVersion() >= 12 then
function llHome()
ll.umount()
love.event.restart()
end
else
function llHome()
ll.umount()
love.event.push('quit', 'restart')
end
end
if love.getVersion() >= 11
then love.errorhandler = error
else love.errhand = error
end
local dt = love.timer and love.timer.step() or 0
local brk = false
while not brk and not ll.mdir do
-- event handling
@ -31,12 +44,29 @@ while not brk and not ll.mdir do
then ll.umount()
love.event.push('quit')
brk = true; break
elseif n == 'filedropped' then
love.graphics.clear()
local x, y, g = 32, 32, 16
local w, h = 84, 96
love.graphics.rectangle('line', x, y, w, h, w / 8)
love.graphics.line(x + w / 1.5, y, x + w, y + h / 3)
if ll.skin.addGame then
a:open 'r'
ll.skin.addGame(a:getFilename(), a:read(), x + w + g, y)
else love.graphics.print('This skin does not support file dropping', x + w + g, y)
end
love.graphics.present()
love.timer.sleep(2)
end
love.handlers[n](a,b,c)
end
-- update and drawing
ll.skin.update()
if love.timer then
love.timer.step()
dt = love.timer.getDelta()
end
ll.skin.update(dt)
love.graphics.origin()
love.graphics.clear(0, 0, 0)
ll.skin.draw()

View File

@ -86,6 +86,11 @@ local function ccp()
return ''
else return 'Not found'
end
elseif cmd == 'devtools' then
if ll.devtools()
then return 'Enabled'
else return 'Already enabled'
end
else return 'Unknown command "'.. cmd .. '"'
end
end
@ -117,6 +122,7 @@ local function update()
end
end
local oy = 0
local utf8 = require 'utf8'
local function draw()
love.graphics.setColor(255, 255, 255)
@ -132,15 +138,18 @@ local function draw()
then x = x + 8 - (x % 8)
elseif chr == '\v'
then y = y + 1
else love.graphics.print(chr, x * cw, y * ch)
else love.graphics.print(chr, x * cw, y * ch - oy)
if x >= ctw
then x, y = x - ctw, y + 1
else x = x + 1
end
end
end
if y * ch - oy >= H
then oy = oy + H / 4
end
if os.time() % 2 == 0
then love.graphics.rectangle('fill', x * cw, y * ch, cw, ch)
then love.graphics.rectangle('fill', x * cw, y * ch - oy, cw, ch)
end
end

View File

@ -1,9 +1,10 @@
return function(ll)
ll.cfg.pcht = ll.cfg.pcht or 60 * 5
ll.cfg.pcht = ll.cfg.pcht or 60 * 10
local pikchv, pikcha = 0, 0
local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5)
local bg = 0
local cx, cy, cw, ch
local f, bf
@ -25,7 +26,7 @@ function resize()
ll.kbInit('h', cx, cx + cw)
end
local function update()
local function update(dt)
local sdi = ll.kbGet()
if cdir ~= sdi then
@ -46,8 +47,8 @@ local function update()
if sel > #ll.games then sel = 1 end
end
pikchv = pikchv + 1
if pikchv >= ll.cfg.pcht then
pikchv = pikchv + dt
if pikchv >= ll.cfg.pcht / 100 then
pikchv = 0
pikcha = 0
for _, v in pairs(ll.games) do
@ -59,11 +60,12 @@ local function update()
end
end
end
else pikcha = math.min(255, pikcha + pikchao)
else pikcha = math.min(255, pikcha + pikchao * 100 * dt)
end
bg = (bg + dt) % 6.28
end
local tm = 0
local function draw()
love.graphics.setColor(0 / COLDIV, 50 / COLDIV, 75 / COLDIV)
love.graphics.rectangle('fill', 0, 0, W, H)
@ -74,8 +76,7 @@ local function draw()
local tw, th = bf:getWidth(t), bf:getHeight(t)
love.graphics.print(t, W - tw - 8, H - th)
tm = (tm + 0.02) % 6.28
local c, pc, ps = tm, math.cos(tm), math.sin(tm)
local c, pc, ps = bg, math.cos(bg), math.sin(bg)
local oy = H / 2
for x = 0, W + 8, 8 do
c = c + 0.1

71
skins/nx.lua Normal file
View File

@ -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

View File

@ -10,7 +10,7 @@ local css, rcss = 2, 0
local f, bf
ll.cfg.pcht = ll.cfg.pcht or 60 * 5
ll.cfg.pcht = ll.cfg.pcht or 60 * 10
local pikchv, pikcha = 0, 0
local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5)
@ -18,6 +18,8 @@ local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5)
local logger = ''
local chc = '<>><m><'
os.setlocale('', 'time')
function resize()
r = math.min(W, H) / 30
@ -30,16 +32,14 @@ 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()
local function update(dt)
local ty = H / 2 - (ch + cg) * sel
cy = cy + (ty - cy) * 0.1
css = css + (2 - css) * 0.2
cy = cy + (ty - cy) * 5 * dt
css = css + (2 - css) * 15 * dt
rcss = 2 - css + 1
local sdi = ll.kbGet()
@ -68,10 +68,9 @@ local function update()
if sel > #ll.games then sel = 1 end
end
pikchv = pikchv + 1
if pikchv >= ll.cfg.pcht then
pikchv = 0
pikcha = 0
pikchv = pikchv + dt
if pikchv >= ll.cfg.pcht / 100 then
pikchv, pikcha = 0, 0
for _, v in pairs(ll.games) do
if v.dat.scr then
v.scrprv = v.scrcur
@ -81,7 +80,7 @@ local function update()
end
end
end
else pikcha = math.min(255, pikcha + pikchao)
else pikcha = math.min(255, pikcha + pikchao * 100 * dt)
end
end
@ -96,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)
@ -109,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
@ -151,9 +182,18 @@ local function draw()
end
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