From f562b23197450e87e2abcb19486d11b01bf59e0d Mon Sep 17 00:00:00 2001 From: Er2 Date: Mon, 30 May 2022 10:33:56 +0300 Subject: [PATCH 1/2] Love Loader v2.0 --- .gitignore | 3 + lib/chroot.lua | 26 +++++ lib/game.lua | 100 +++++++++++++++++++ lib/load.lua | 9 ++ lib/love/chroot.lua | 33 ++++++ lib/love/load.lua | 28 ++++++ lib/main.lua | 27 +++++ luapack.lua | 16 +++ main.lua | 238 +++++++++----------------------------------- readme.md | 75 +++++++++++--- scr/base.png | Bin 0 -> 11483 bytes scr/gui.png | Bin 0 -> 63002 bytes scr/psp.png | Bin 0 -> 25290 bytes skins/base.lua | 190 +++++++++++++++++++++++++++++++++++ skins/gui.lua | 220 ++++++++++++++++++++++++++++++++++++++++ skins/psp.lua | 175 ++++++++++++++++++++++++++++++++ 16 files changed, 933 insertions(+), 207 deletions(-) create mode 100644 .gitignore create mode 100644 lib/chroot.lua create mode 100644 lib/game.lua create mode 100644 lib/load.lua create mode 100644 lib/love/chroot.lua create mode 100644 lib/love/load.lua create mode 100644 lib/main.lua create mode 100644 luapack.lua create mode 100644 scr/base.png create mode 100644 scr/gui.png create mode 100644 scr/psp.png create mode 100644 skins/base.lua create mode 100644 skins/gui.lua create mode 100644 skins/psp.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..05ba253 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +dev +build/ +games/* diff --git a/lib/chroot.lua b/lib/chroot.lua new file mode 100644 index 0000000..4d09f14 --- /dev/null +++ b/lib/chroot.lua @@ -0,0 +1,26 @@ +return function(ll) + +ll.mdir = nil +ll.mgme = nil + +function ll.mount(gme) + --[[ + ll.mdir = gme.base .. gme.dir + ll.mgme = gme + --[=[ + if gme.main then + print('Load', ll.mdir ..'/'.. gme.main) + end + --]=] + --]] + error 'unimplemented' +end + +function ll.umount() + if ll.mdir ~= nil then + ll.mdir = nil + error 'unimplemented' + end +end + +end diff --git a/lib/game.lua b/lib/game.lua new file mode 100644 index 0000000..b9d88f7 --- /dev/null +++ b/lib/game.lua @@ -0,0 +1,100 @@ +return function(ll) + +ll.games = {} + +local function parse(conf) + local r = {} + local k, v + + local buf = '' + local t = 'str' + local esc = false + local prg = true + + local i = 1 + repeat + local ch = conf:sub(i, i) + + if ch == '\\' + then esc = true + + elseif ch == '#' then + repeat i = i + 1 + ch = conf:sub(i, i) + until ch == '' or ch == '\n' or ch == '\r' + + elseif ch == '[' then + buf = buf:match '%s*(.*)%s*' + assert(#buf == 0, 'Unexpected array usage') + t = 'arr' + prg = true + v = {} + + elseif ch == '' + or (ch == '=' and not k) + or (ch == ']' and t == 'arr') + or (ch == ';' and t == 'arr') + or ch == '\n' or ch == '\r' then + buf = buf:match '^%s*(.-)%s*$' + + if ch == '=' then + assert(t == 'str', 'Cannot use other types than string for key') + end + + if t == 'str' + or (t == 'arr' and ch == ']') + then prg = false end + + if not prg or ch == ';' then + if #buf ~= 0 then + if k then + if t == 'str' + then v = buf + elseif t == 'arr' + then table.insert(v, buf) + else error 'wut?' end + else k = buf + end + buf = '' + elseif ch ~= '' + and ch ~= '\r' + and ch ~= '\n' + then error 'empty buffer' + end + end + if k and v and not prg then + r[k] = v + k = nil + v = nil + buf = '' + t = 'str' + end + + elseif esc then + buf = buf .. ch + esc = false + + else buf = buf .. ch + end + i = i + 1 + until i >= #conf + 1 + return r +end + +function ll.gameNew(conf, file, base, dir) + local cfg = parse(conf or '') + local gme = { + name = cfg.name or dir or 'No name', + desc = cfg.desc or 'No description provided.', + base = base, + dir = dir, + main = cfg.main or 'main.lua', + screens = cfg.screens or cfg.pics or nil, + scrcur = 1, + scrprv = 1, + dat = nil, + } + return gme +end + +end diff --git a/lib/load.lua b/lib/load.lua new file mode 100644 index 0000000..acc60dd --- /dev/null +++ b/lib/load.lua @@ -0,0 +1,9 @@ +return function(ll) + +function ll.gameAdd(conf, file, base, dir) + local gme = ll.gameNew(conf, file, base, dir) + table.insert(ll.games, gme) + return gme +end + +end diff --git a/lib/love/chroot.lua b/lib/love/chroot.lua new file mode 100644 index 0000000..24d9cb5 --- /dev/null +++ b/lib/love/chroot.lua @@ -0,0 +1,33 @@ +return function(ll) + +local ffi = require 'ffi' +ffi.cdef [[ + int PHYSFS_mount(const char *, const char *, int); + int PHYSFS_unmount(const char *); +]] + +function ll.mount(gme) + local mdir = gme.base .. gme.dir + + love.filesystem.setRequirePath('' + .. mdir .. '/?.lua;' + .. mdir .. '/?/init.lua;' + .. '?.lua;?/init.lua;' + ) + -- FIXME: Bug may appear in Linux. Recompile Love2D or use official PPA. + if ffi.C.PHYSFS_mount(mdir, '/', 0) == 0 + then error 'Cannot mount' + else + ll.mdir = mdir + ll.mgme = gme + end +end + +function ll.umount() + if ll.mdir ~= nil then + ffi.C.PHYSFS_unmount(ll.mdir) + ll.mdir = nil + end +end + +end diff --git a/lib/love/load.lua b/lib/love/load.lua new file mode 100644 index 0000000..787d1d7 --- /dev/null +++ b/lib/love/load.lua @@ -0,0 +1,28 @@ +return function(ll) + + function ll.gameAdd(conf, file, base, dir) + local gme = ll.gameNew(conf, file, base, dir) + gme.dat = {} + + if gme.screens and gme.screens[1] then + gme.dat.scr = {} + for i = 1, #gme.screens do + table.insert(gme.dat.scr, love.graphics.newImage(ll.cfg.root .. gme.dir ..'/'.. gme.screens[i])) + end + end + + table.insert(ll.games, gme) + return gme + end + +for _, dir in pairs(love.filesystem.getDirectoryItems(ll.cfg.root)) do + local file = ll.cfg.root .. dir..'/'.. 'info.ll' + ll.gameAdd( + love.filesystem.read(file), + file, + love.filesystem.getSource():match '(.*)[\\/]*' ..'/'.. ll.cfg.root, -- TODO: AppData folders support + dir + ) +end + +end diff --git a/lib/main.lua b/lib/main.lua new file mode 100644 index 0000000..86d4169 --- /dev/null +++ b/lib/main.lua @@ -0,0 +1,27 @@ +local ll = {} + +ll.cfg = { + root = 'games/', +} + +require 'lib.game' (ll) +require 'lib.chroot' (ll) +require 'lib.load' (ll) + +function ll.home() + ll.umount() + error 'go to home' +end + +if love then + require 'lib.love.chroot' (ll) + require 'lib.love.load' (ll) + + function ll.home() + ll.umount() + love.event.push('quit', 'restart') + end + llHome = ll.home +end + +return ll diff --git a/luapack.lua b/luapack.lua new file mode 100644 index 0000000..f4ab5ff --- /dev/null +++ b/luapack.lua @@ -0,0 +1,16 @@ +return { + entry = 'main.lua', + output = 'build/main.lua', + plug = { + require 'plug.minify' { + extGlob = { + 'love', + 'llUsed', + 'llHome', + 'resize', + 'COLDIV', + 'W', 'H', + } + }, + } +} diff --git a/main.lua b/main.lua index c45271c..5dd9deb 100644 --- a/main.lua +++ b/main.lua @@ -1,219 +1,71 @@ +local ll = require 'lib.main' +error = love.errhand or love.errorhandler -local root = 'games/' - --- games library and selection -local gms = {} -local sel = 1 -local sgme - --- some internals -local cx, cy, cw, ch -local f, bf - -local ffi = require 'ffi' -local fd -ffi.cdef [[ - int PHYSFS_mount(const char *, const char *, int); - int PHYSFS_unmount(const char *); -]] - -local function llResz() - cw, ch = W / 1.25, H / 1.25 - cx, cy = (W - cw) / 2, (H - ch) / 2 - - local th = math.min(W, H) / 8 - - f = love.graphics.newFont(th / 3) - bf = love.graphics.newFont(th / 2) +function splash() + 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]) + love.graphics.draw(img, 0, 0, 0, W / img:getWidth(), H / img:getHeight()) + end + love.graphics.setColor(255, 255, 255, 255) + love.graphics.print('Loading '..ll.mgme.name, W / 2, H / 2) end -resize = llResz + +ll.skin = require 'skins.psp' (ll) 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 = { - name = 'No name', - desc = 'No description provided.', - dir = dir, - main = 'main.lua', - pics = nil, - psel = 2, - ppsl = 1, - } - local fi = false - cont = cont or '' - cont = cont:gsub('[^\\]#[^\n]*', '') - for v in cont:gmatch '([^\n]+)' do - local k, v = v:match '^%s*([%w_]+)%s*=%s*(.*)%s*$' - if k == 'name' - or k == 'desc' - 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 - table.insert(gms, gme) -end - -for _, v in pairs(love.filesystem.getDirectoryItems(root)) do - local file = v..'/'.. 'info.ll' - gmeNew(love.filesystem.read(root .. file), v, file) -end - -local pf, mx, mb, mpb - -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 - if love.mouse.isDown(1) then mb = 1 - end - - if mpb == 1 and mb == 0 then - if mx <= cx then - sel = sel - 1 - if sel < 1 then sel = #gms end - elseif mx >= cx + cw then - sel = sel + 1 - if sel > #gms then sel = 1 end - 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 llDraw() - love.graphics.polygon('fill', - 8, H / 2, - 32, H / 2 - 32, - 32, H / 2 + 32) - - love.graphics.polygon('fill', - W - 8, H / 2, - W - 32, H / 2 - 32, - W - 32, H / 2 + 32) - - local oy, t = 0, '' - 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) - - oy = cy + ph - love.graphics.setFont(bf) - love.graphics.print(gme.name, cx, oy) - oy = oy + bf:getHeight(gme.name) - love.graphics.setFont(f) - love.graphics.print(gme.desc, cx, oy) - - else oy = H / 2 - t = 'No games' - love.graphics.setFont(bf) - love.graphics.print(t, (W - bf:getWidth(t)) / 2, oy) - oy = oy + bf:getHeight(t) - love.graphics.setFont(f) - t = 'There is no projects/games to run' - love.graphics.print(t, (W - f:getWidth(t)) / 2, oy) - end -end - -function llHome() - escChroot() - love.event.push('quit', 'restart') +if love.errorhandler +then love.errorhandler = error +else love.errhand = error end local brk = false -while not brk and not sgme do +while not brk and not ll.mdir do -- event handling love.event.pump() - for n, a,b,c,d,e,f in love.event.poll() do - if n == 'quit' then - escChroot() + for n, a,b,c in love.event.poll() do + if n == 'quit' + or (n == 'keypressed' and a == 'escape') + then ll.umount() love.event.push('quit') brk = true; break end - love.handlers[n](a,b,c,d,e,f) + love.handlers[n](a,b,c) end -- update and drawing - llUpdate() + ll.skin.update() love.graphics.origin() love.graphics.clear(0, 0, 0) - llDraw() + ll.skin.draw() love.graphics.present() love.timer.sleep(0.001) end -if sgme then +if ll.mdir then love.graphics.setNewFont() resize = nil - chroot(root .. sgme.dir, sgme.main) + + love.graphics.clear(0, 0, 0) + splash() + love.graphics.present() + + if ll.skin.lovecb then + for _, v in pairs(ll.skin.lovecb) + do love[v] = nil + end + end + + love.filesystem.setIdentity(ll.mgme.dir) + local f, err = load(love.filesystem.read(ll.mgme.main), ll.mgme.name) + if not f then error(err) + else xpcall(f, function(e) + error(e) + llHome() + end) + end + + love.resize(love.graphics.getDimensions()) end diff --git a/readme.md b/readme.md index 46bbbf1..b14a9b3 100644 --- a/readme.md +++ b/readme.md @@ -2,31 +2,78 @@ Custom menu for selecting game from multiple for Love2D. +![PSP Style](./scr/psp.png) + +[Other screenshots](./scr) + # How it works? -If simple: just place games in `games` folder with structure like `games/yourgame/main.lua` +Just place games into `games` folder! (like `this_folder/games/game/main.lua`) -If technically: creates local variables functions and variables. -Creates the loop until game wasn't selected with manual event handling and redrawing. +Technically, this creates the loop until game wasn't selected or user wants to exit +with custom event handling and redrawing. -# Things left or API +# LibLL -We are not keep environment super clear (except local variables ;)) -so there are some variables can be used in game: +Love Loader from v2.0 includes library to simplify creating custom interfaces. +It is like a backend for Love Loader. -`W` and `H` variables: width and height of the screen, controlled by love.resize function. +It have not so many functions and fields: -`love.resize` and optional `resize` payload: functions called when screen size when changed and at boot. +- `ll.games` - field for games, which have this structure: + ```lua + { + name = 'string', -- Friendly name for game or placeholder + desc = 'string', -- Description for game or placeholder + base = 'string', -- base directory used in game mounting, must end with `/` + dir = 'string', -- directory name, used if no name was defined + main = 'string', -- main file to execute or `main.lua` + screens = {'array of', 'path to screenshots'}, + scrcur = 1, --[[number]] -- current index from screenshots + scrprv = 1, --[[number]] -- previous index from screenshots + dat = nil, --[[any]] -- maybe platform-dependent data to reduce operations + } + ``` -`love.event.quit`: function to quit to menu screen +- `ll.mdir` - string or nil, contains full mounted directory. -`COLDIV`: color divider (1 or 255) to setColor function +- `ll.mgme` - game or nil, contains mounted game. -`llUsed`: is Love Loader used +- `ll.gameNew(configuration --[[string]], fileName --[[string, not used]], base --[[string]], directory --[[string]])` -`llHome`: function to quit to menu screen + Creates game object (defined above) and returns it. -They also can be used without Love Loader if load `ll-min.lua` +- `ll.gameAdd(conf, file, base, dir)` - same as `ll.gameNew`, but inserts game into `ll.games`. + +- `ll.mount(game)` - mounts game. + + Can throw an error. + + Sets `ll.mdir` and `ll.mgme`. + +- `ll.umount()` - unmounts game if can. + + Unsets `ll.mdir` and `ll.mgme`. + +- `ll.home()` - calls `llHome` + +# API + +To simplify task to the game developers, this loader creates some global variables to use. + +You can also use it without Love Loader by including `ll-min.lua` file. + +`W` and `H`: width and height of the screen which controls by custom love.resize function. + +`love.resize` and optional `resize` payload: functions called when screen size was changed and on booting. + +`love.event.quit`: function to exit to main screen. + +`llHome`: function called by `love.event.quit` (broken for now). + +`llUsed`: is Love Loader (not minimal API) used. + +`COLDIV`: color divider (1 or 255) to `love.graphics.setColor` function. # Fill game information @@ -40,5 +87,5 @@ 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 +pics = [ screen.png; screen2.png ] # wow arrays ``` diff --git a/scr/base.png b/scr/base.png new file mode 100644 index 0000000000000000000000000000000000000000..4761cbb6d958529b36638eace6d9ff72dcf408f9 GIT binary patch literal 11483 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 Sz>)_6f3KvKqzWbU{r(4h>Deg& literal 0 HcmV?d00001 diff --git a/scr/psp.png b/scr/psp.png new file mode 100644 index 0000000000000000000000000000000000000000..be2d5177cf9112ce553866b57852c72e4506ccd0 GIT binary patch literal 25290 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\tInformation about game' + .. '\ninfo\t\tSame as cat' + .. '\nrun\t\tStart game' + .. '\nmount\t\tSame as run' + .. '\nchroot\t\tSame as run' + .. '\nclear\t\tClear screen' + .. '\neval\t\tExecute code' + elseif cmd == 'clear' then + ct = '' + return '' + elseif cmd == 'eval' then + local code = buf:match '^%S+%s+(.*)' + local f, err = load(code, 'test.lua') + if not f then return err + else return tostring(f() or 'nil') + end + elseif cmd == 'ls' + or cmd == 'dir' then + local r = '' + if #ll.games == 0 then + return ('%s: No games found. Add some to the library.'):format(argv[1]) + end + for i = 1, #ll.games do + local v = ll.games[i] + r = r .. ('%s\t(%s)\t - %s\n'):format(v.dir, v.name, v.desc) + end + return r .. ('\nTotal: %3d games\n'):format(#ll.games) + elseif cmd == 'cat' + or cmd == 'info' then + if not argv[2] + then return ('%s: Game directory missing'):format(argv[1]) + end + local r = '' + for _, v in pairs(ll.games) do + if argv[2] == v.dir + or argv[2] == v.base .. v.dir + then r = r.. + ( '\nFriendly name:\t%s' + ..'\nDescription:\t%s' + ..'\nLocation:\t%s%s' + ..'\nMain file:\t%s' + ..'\n\n\t\tScreenshots are not supported yet.' + ..'\n'):format(v.name, v.desc, v.base, v.dir, v.main) + end + end + if r == '' then r = 'Not found' end + return r + elseif cmd == 'run' + or cmd == 'mount' + or cmd == 'chroot' then + local gme + for _, v in pairs(ll.games) do + if argv[2] == v.dir + or argv[2] == v.base .. v.dir + then if gme then + return 'Error: multiple paths found, use full location' + end + gme = v end + end + if gme + then ll.mount(gme) + love.keyboard.setTextInput(false) + return '' + else return 'Not found' + end + else return 'Unknown command "'.. cmd .. '"' + end +end + +local function update() + mpb = mb + if love.mouse.isDown(1) then mb = 1 + if mpb ~= 1 + then mt = os.time() + end + else mb = 0 + end + + if mb == 0 and mpb == 1 + and os.time() - mt <= 1 then + if love.system.getOS() == 'Android' then + love.keyboard.setTextInput( + not love.keyboard.hasTextInput(), + 0, H, W, ch) + end + end + + if not cce then + cce = true + local r = ccp() + if #r ~= 0 then ct = ct.. '\n'.. r end + ct = ct.. '\n> ' + buf = '' + end +end + +local utf8 = require 'utf8' +local function draw() + love.graphics.setColor(255, 255, 255) + + local x, y = 0, 0 + for p, cde in utf8.codes(ct) do + local chr = utf8.char(cde) + if chr == '\n' + then x, y = 0, y + 1 + elseif chr == '\r' + then x = 0 + elseif chr == '\t' + then x = x + 8 - (x % 8) + elseif chr == '\v' + then y = y + 1 + else love.graphics.print(chr, x * cw, y * ch) + if x >= ctw + then x, y = x - ctw, y + 1 + else x = x + 1 + end + end + end + if os.time() % 2 == 0 + then love.graphics.rectangle('fill', x * cw, y * ch, cw, ch) + end +end + +function resize() + local f = love.graphics.newFont(math.min(W, H) / 32) + love.graphics.setFont(f) + cw, ch = f:getWidth 'm', f:getHeight 'A' + ctw, cth = + math.floor(W / cw) - 1, + math.floor(H / ch) - 1 + + love.keyboard.setTextInput(true, 0, H, W, ch) +end + +function love.textinput(txt) + ct = ct.. txt + buf = buf.. txt +end + +function love.keypressed(k) + if k == 'backspace' then + local off = utf8.offset(buf, -1) + if off then + buf = buf:sub(1, off - 1) + off = utf8.offset(ct, -1) + if off + then ct = ct:sub(1, off - 1) + end + end + elseif k == 'return' + then cce = false + end +end + +love.keyboard.setKeyRepeat(true) +love.window.setMode(800, 600, {resizable = true}) + +return { + update = update, + draw = draw, + lovecb = { + 'textinput', + 'keypressed', + }, +} + +end diff --git a/skins/gui.lua b/skins/gui.lua new file mode 100644 index 0000000..10f6c67 --- /dev/null +++ b/skins/gui.lua @@ -0,0 +1,220 @@ +return function(ll) + +-- Classic UI from Love Loader v1 + +ll.cfg.pcht = ll.cfg.pcht or 60 * 5 + +local pikchv, pikcha = 0, 0 +local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5) + +local cx, cy, cw, ch +local f, bf + +local mx, mb, mpb = 0, 0, 0 +local cdir, sel = 0, 1 + +function resize() + cw = W / 1.25 + ch = H / 1.25 + cx = (W - cw) / 2 + cy = (H - ch) / 2 + + local th = math.min(W, H) / 8 + + f = love.graphics.newFont(th / 3) + bf = love.graphics.newFont(th / 2) +end + +local function update() + mx = love.mouse.getX() + mpb = mb + if love.mouse.isDown(1) then mb = 1 + else mb = 0 end + + local sdi = 0 + if mpb == 1 and mb == 0 then + if mx <= cx + then sdi = 1 + elseif mx >= cx + cw + then sdi = 2 + else sdi = 3 + end + end + + if love.keyboard.isScancodeDown('left', 'a') + then sdi = 1 + elseif love.keyboard.isScancodeDown('right', 'd') + then sdi = 2 + elseif love.keyboard.isScancodeDown('return', 'space') + then sdi = 3 + end + + if cdir ~= sdi then + cdir = sdi + if sdi == 1 + then sel = sel - 1 + elseif sdi == 2 + then sel = sel + 1 + elseif sdi == 3 and ll.games[sel] + then ll.mount(ll.games[sel]) + end + + if sel < 1 then sel = #ll.games end + if sel > #ll.games then sel = 1 end + end + + pikchv = pikchv + 1 + if pikchv >= ll.cfg.pcht then + pikchv = 0 + pikcha = 0 + for _, v in pairs(ll.games) do + if v.dat.scr then + v.scrprv = v.scrcur + v.scrcur = v.scrcur + 1 + if v.scrcur > #v.dat.scr + then v.scrcur = 1 + end + end + end + else pikcha = math.min(255, pikcha + pikchao) + end + + if love.keyboard.isDown 'menu' + and mx >= W - 8 + then pcall(select(2, pcall(require, 'dev.devtools')), ll) + end +end + +local tm = 0 +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, 100 / COLDIV) + love.graphics.setLineWidth(8) + love.graphics.setFont(bf) + local t = 'Love Loader' + 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 oy = H / 2 + for x = 0, W + 8, 8 do + c = c + 0.1 + local c, s = math.cos(c), math.sin(c) + local cy, ncy, sy, nsy = + pc * H / 12, + c * H / 12, + ps * H / 12, + s * H / 12 + + love.graphics.line(x - 8, sy + oy, x-1, nsy + oy) + love.graphics.line(x - 8, sy/2 + oy, x-1, nsy/2 + oy) + love.graphics.line(x - 8, cy/1.5 + oy, x-1, ncy/1.5 + oy) + love.graphics.line(x - 8, cy*1.5 + oy, x-1, ncy*1.5 + oy) + pc, ps = c, s + end + love.graphics.setColor(255, 255, 255, 255) + love.graphics.setLineWidth(1) + + local oy, t = 0, '' + local gme = ll.games[sel] + if gme then + love.graphics.polygon('fill', + 8, H / 2, + 32, H / 2 - 32, + 32, H / 2 + 32) + + love.graphics.polygon('fill', + W - 8, H / 2, + W - 32, H / 2 - 32, + W - 32, H / 2 + 32) + + love.graphics.stencil(function() + love.graphics.rectangle('fill', cx, cy, cw, ch, 16) + end) + love.graphics.setStencilTest('greater', 0) + love.graphics.setColor(50 / COLDIV, 50 / COLDIV, 50 / COLDIV, 100 / COLDIV) + love.graphics.rectangle('fill', cx, cy, cw, ch) + love.graphics.setColor(255, 255, 255, 255) + + if gme.dat.scr then + local p, n = gme.dat.scr[gme.scrprv], gme.dat.scr[gme.scrcur] + love.graphics.draw(p, cx, cy, 0, cw / p:getWidth(), ch / p:getHeight()) + love.graphics.setColor(255, 255, 255, pikcha / COLDIV) + love.graphics.draw(n, cx, cy, 0, cw / n:getWidth(), ch / n:getHeight()) + love.graphics.setColor(0, 0, 0, 150 / COLDIV) + love.graphics.rectangle('fill', cx, cy, cw, ch) + love.graphics.setColor(255, 255, 255, 255) + end + + oy = cy + ch / 1.25 + love.graphics.setFont(bf) + love.graphics.print(gme.name, cx + 16, oy) + oy = oy + bf:getHeight(gme.name) + love.graphics.setFont(f) + love.graphics.print(gme.desc, cx + 16, oy) + love.graphics.setStencilTest() + love.graphics.rectangle('line', cx, cy, cw, ch, 16) + + elseif ll.games[1] then + sel = 1 + love.graphics.setColor(255, 255, 255, 255) + love.graphics.print('Sorry :)', W / 2, H / 2) + else love.graphics.setColor(255, 255, 255, 255) + oy = H / 2.5 + t = 'No games' + love.graphics.setFont(bf) + love.graphics.print(t, (W - bf:getWidth(t)) / 2, oy) + oy = oy + bf:getHeight(t) + love.graphics.setFont(f) + t = 'There are no projects/games to run' + love.graphics.print(t, (W - f:getWidth(t)) / 2, oy) + end +end + +function error(msg) + msg = tostring(msg) + + love.graphics.reset() + love.graphics.origin() + local bf = love.graphics.newFont(64) + local f = love.graphics.setNewFont(16) + local perc = 0 + + local q + repeat + perc = math.min(100, perc + 0.1 * math.random(50)) + + love.graphics.clear(17/COLDIV, 113/COLDIV, 172/COLDIV) + love.graphics.setColor(255, 255, 255) + love.graphics.setFont(bf) + love.graphics.print(':(', 64, 16) + love.graphics.setFont(f) + love.graphics.print(('%d%% complete'):format(perc), 64, 100) + love.graphics.printf(msg, 64, 132, W - 64) + love.graphics.print('(c) Love Loader and Er2', 8, H - 16 - 8) + love.graphics.present() + + love.event.pump() + for n, a,b,c in love.event.poll() do + if n == 'quit' + or n == 'mousereleased' + or (n == 'keypressed' and a == 'escape') + then q = true end + end + + love.timer.sleep(0.5) + until q or perc == 100 + + -- Unfortunately, we can't restart Love in error handler + llHome() -- but can outside of love.errorhandler + return function() return 1 end +end + +return { + update = update, + draw = draw, +} + +end diff --git a/skins/psp.lua b/skins/psp.lua new file mode 100644 index 0000000..fc4a34e --- /dev/null +++ b/skins/psp.lua @@ -0,0 +1,175 @@ +return function(ll) + +-- New UI from Sony PSP + +local sel = 1 +local psel + +local cx, cy, cw, ch, cg +local css, rcss = 2, 0 + +local f, bf + +ll.cfg.pcht = ll.cfg.pcht or 60 * 5 + +local pikchv, pikcha = 0, 0 +local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5) + +function resize() + r = math.min(W, H) / 30 + + cg = H / 64 + cw = W / 5 + ch = (H - cg) / 6 + cx = W / 10 + cy = -H / 2 + + f = love.graphics.setNewFont(math.min(W, H) / 30) + bf = love.graphics.newFont(math.min(W, H) / 20) +end + +love.window.setMode(800, 600, {resizable = true}) + +local my, mb, mpb + +local sdir = 0 +local function update() + local ty = H / 2 - (ch + cg) * sel + cy = cy + (ty - cy) * 0.1 + css = css + (2 - css) * 0.2 + rcss = 2 - css + 1 + + local sdi + + my = love.mouse.getY() + mpb = mb + if love.mouse.isDown(1) then mb = 1 + else mb = 0 + end + if mb == 0 and mpb == 1 then + if my <= H / 2 - ch + then sdi = 1 + elseif my >= H / 2 + ch + cg + then sdi = 2 + else sdi = 3 + end + elseif love.keyboard.isScancodeDown('up', 'w') + then sdi = 1 + elseif love.keyboard.isScancodeDown('down', 's') + then sdi = 2 + elseif love.keyboard.isScancodeDown('return', 'space') + then sdi = 3 + else sdi = 0 + end + + if sdi ~= sdir then + if sdi ~= 0 + then rcss = css + css = 1 + if sdi == 3 + then css = 1.5 + end + psel = sel + end + sdir = sdi + if sdi == 1 + then sel = sel - 1 + elseif sdi == 2 + then sel = sel + 1 + elseif sdi == 3 and ll.games[sel] + then ll.mount(ll.games[sel]) + end + + if sel < 1 then sel = #ll.games end + if sel > #ll.games then sel = 1 end + end + + pikchv = pikchv + 1 + if pikchv >= ll.cfg.pcht then + pikchv = 0 + pikcha = 0 + for _, v in pairs(ll.games) do + if v.dat.scr then + v.scrprv = v.scrcur + v.scrcur = v.scrcur + 1 + if v.scrcur > #v.dat.scr + then v.scrcur = 1 + end + end + end + else pikcha = math.min(255, pikcha + pikchao) + end +end + +local function scrCard(gme, x, y, w, h, a) + if not gme.dat.scr then return end + love.graphics.setColor(255, 255, 255, a / COLDIV) + local p, n = gme.dat.scr[gme.scrprv], gme.dat.scr[gme.scrcur] + love.graphics.draw(p, x, y, 0, w / p:getWidth(), h / p:getHeight()) + love.graphics.setColor(255, 255, 255, math.min(a, pikcha) / COLDIV) + love.graphics.draw(n, x, y, 0, w / n:getWidth(), h / n:getHeight()) + love.graphics.setColor(0, 0, 0, 150 / COLDIV) + love.graphics.rectangle('fill', x, y, w, h) +end + +local function draw() + love.graphics.setColor(0 / COLDIV, 50 / COLDIV, 75 / COLDIV) + love.graphics.rectangle('fill', 0, 0, W, H) + if ll.games[sel] then + local cur = ll.games[sel] + scrCard(cur, 0, 0, W, H, (css - 1) * 255) + love.graphics.setColor(255, 255, 255, 255) + love.graphics.setFont(bf) + love.graphics.printf(cur.desc, cx + cw * 2, cx, W - (cx + cw * 2)) + else love.graphics.setColor(255, 255, 255, 255) + sel = #ll.games + end + love.graphics.setFont(f) + local oy = 0 + for k, v in pairs(ll.games) do + local x, w, h, g = cx, cw, ch, cg + if k == sel then + x = cx / css + w = cw * css + h = ch * css + g = cg * 3 + oy = oy + cg * css + elseif k == psel then + x = cx / rcss + w = cw * rcss + h = ch * rcss + oy = oy + cg * rcss + end + + love.graphics.stencil(function() + love.graphics.rectangle('fill', x, cy + oy, w, h, r) + end) + love.graphics.setStencilTest('greater', 0) + + love.graphics.setColor(50 / COLDIV, 50 / COLDIV, 50 / COLDIV, 100 / COLDIV) + love.graphics.rectangle('fill', x, cy + oy, w, h) + love.graphics.setColor(255, 255, 255, 255) + + scrCard(v, x, cy + oy, w, h, 255) + love.graphics.setColor(255, 255, 255, 255) + + local th = f:getHeight(v.name) + love.graphics.print(v.name, x + cg, cy + oy + h - th - cg) + + love.graphics.setStencilTest() + love.graphics.rectangle('line', x, cy + oy, w, h, r) + oy = oy + h + g + end + if #ll.games == 0 then + love.graphics.print('No games', cx, cy - ch) + love.graphics.setFont(bf) + love.graphics.print('Add some to the library', cx, cy) + end +end + +return { + update = update, + draw = draw, +} + +end From e46bc230a6ecef40329d64bcb32ac1c73557f8f9 Mon Sep 17 00:00:00 2001 From: Er2 Date: Thu, 7 Jul 2022 19:37:27 +0300 Subject: [PATCH 2/2] Love Loader v2.1 Bugfixes. Removed cross-engine support, only Love2D. Added filesystem and keyboard modules in LibLL. Remade input handling in skins. Files and broken folders are not shows in game list. Add MOBILE variable and auto-fullscreen on mobile phones. --- .gitignore | 2 ++ lib/chroot.lua | 33 ++++++++++++------ lib/fs.lua | 20 +++++++++++ lib/keyb.lua | 81 +++++++++++++++++++++++++++++++++++++++++++++ lib/load.lua | 42 +++++++++++++++++++++++ lib/love/chroot.lua | 33 ------------------ lib/love/load.lua | 28 ---------------- lib/main.lua | 18 +++++----- ll-min.lua | 11 +++++- luapack.lua | 1 + readme.md | 32 +++++++++++++++--- skins/gui.lua | 46 +++++++------------------ skins/psp.lua | 48 +++++++++------------------ 13 files changed, 242 insertions(+), 153 deletions(-) create mode 100644 lib/fs.lua create mode 100644 lib/keyb.lua delete mode 100644 lib/love/chroot.lua delete mode 100644 lib/love/load.lua diff --git a/.gitignore b/.gitignore index 05ba253..81b0c56 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ dev build/ games/* +!games/.gitkeep + diff --git a/lib/chroot.lua b/lib/chroot.lua index 4d09f14..f0abb42 100644 --- a/lib/chroot.lua +++ b/lib/chroot.lua @@ -3,23 +3,34 @@ return function(ll) ll.mdir = nil ll.mgme = nil +local ffi = require 'ffi' +ffi.cdef [[ + int PHYSFS_mount(const char *, const char *, int); + int PHYSFS_unmount(const char *); +]] + +local baseReq = '?.lua;?/init.lua;' function ll.mount(gme) - --[[ - ll.mdir = gme.base .. gme.dir - ll.mgme = gme - --[=[ - if gme.main then - print('Load', ll.mdir ..'/'.. gme.main) - end - --]=] - --]] - error 'unimplemented' + local mdir = gme.base .. gme.dir + ll.mgme = gme + + 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) + 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.mdir = nil - error 'unimplemented' end end diff --git a/lib/fs.lua b/lib/fs.lua new file mode 100644 index 0000000..e6088c3 --- /dev/null +++ b/lib/fs.lua @@ -0,0 +1,20 @@ +return function(ll) + +function ll.fsIsAbs(f) + f = f:sub(1, 1) + return f == '/' or f == '\\' +end + +function ll.fsIsRel(f) + return not ll.fsIsAbs(f) +end + +function ll.fsFile(f) + return f:match '([^/\\]*)[/\\]*$' +end + +function ll.fsDir(f) + return f:match '^(.*)[/\\]+[^/\\]*[/\\]*$' +end + +end diff --git a/lib/keyb.lua b/lib/keyb.lua new file mode 100644 index 0000000..e3c0719 --- /dev/null +++ b/lib/keyb.lua @@ -0,0 +1,81 @@ +return function(ll) + +local mx, my, mb, mpb +local dir, sc1, sc2, sclm + +-- 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) + if d == 'h' or d == 'v' or d == '*' + then dir = d + elseif d == 'y' + then dir = 'v' + elseif d == 'x' + then dir = 'h' + else error 'Direction must be *, h (x) or v (y)' + end + + c1, c2 = + tonumber(c1) or 0, + tonumber(c2) or 0 + sc1, sc2, sclm = + math.min(c1, c2), + math.max(c1, c2), + tonumber(clim) 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') + mx, my = love.mouse.getPosition() + mpb = mb + if love.mouse.isDown(1) then mb = 1 + else mb = 0 + end + + if love.keyboard.isScancodeDown('up', 'w') + then return dir == '*' and '^' or '<' + + elseif love.keyboard.isScancodeDown('left', 'a') + then return '<' + + elseif love.keyboard.isScancodeDown('down', 's') + then return dir == '*' and 'v' or '>' + + elseif love.keyboard.isScancodeDown('right', 'd') + then return '>' + + elseif love.keyboard.isScancodeDown('return', 'space') + then return 'o' + + elseif love.keyboard.isDown 'menu' + then return 'm' + + elseif mb == 0 and mpb == 1 then -- unpressed + if dir == 'h' then + if sclm < 0 or my <= sclm then + if mx <= sc1 + then return '<' + elseif mx >= sc2 + then return '>' + else return 'o' + end + end + else + if sclm < 0 or mx <= sclm then + if my <= sc1 + then return '<' + elseif my >= sc2 + then return '>' + else return 'o' + end + end + end + + end +end + +end diff --git a/lib/load.lua b/lib/load.lua index acc60dd..04a40e1 100644 --- a/lib/load.lua +++ b/lib/load.lua @@ -1,9 +1,51 @@ return function(ll) +function ll.addGame(file, cont) + local dir = ll.fsDir(file) + file = ll.fsFile(file) + local ext = file:match '%.(%w+)$' + print(file, ext, dir) + return 'NO!', nil +end + function ll.gameAdd(conf, file, base, dir) local gme = ll.gameNew(conf, file, base, dir) + gme.dat = {} + + if gme.screens and gme.screens[1] then + gme.dat.scr = {} + for i = 1, #gme.screens do + table.insert(gme.dat.scr, love.graphics.newImage(ll.cfg.root .. gme.dir ..'/'.. gme.screens[i])) + end + end + table.insert(ll.games, gme) return gme end +local lfs = love.filesystem +local info = lfs.getInfo + +for _, dir in pairs(love.filesystem.getDirectoryItems(ll.cfg.root)) do + local isDir + if info + then isDir = info(ll.cfg.root .. dir).type == 'directory' + else isDir = lfs.isDirectory(ll.cfg.root .. dir) + end + + if isDir then + local file = ll.cfg.root .. dir..'/'.. 'info.ll' + local realDir = love.filesystem.getRealDirectory(file) + or love.filesystem.getRealDirectory(ll.cfg.root .. dir..'/main.lua') + if realDir + then ll.gameAdd( + love.filesystem.read(file), + file, + realDir ..'/'.. ll.cfg.root, + dir + ) + end + end +end + end diff --git a/lib/love/chroot.lua b/lib/love/chroot.lua deleted file mode 100644 index 24d9cb5..0000000 --- a/lib/love/chroot.lua +++ /dev/null @@ -1,33 +0,0 @@ -return function(ll) - -local ffi = require 'ffi' -ffi.cdef [[ - int PHYSFS_mount(const char *, const char *, int); - int PHYSFS_unmount(const char *); -]] - -function ll.mount(gme) - local mdir = gme.base .. gme.dir - - love.filesystem.setRequirePath('' - .. mdir .. '/?.lua;' - .. mdir .. '/?/init.lua;' - .. '?.lua;?/init.lua;' - ) - -- FIXME: Bug may appear in Linux. Recompile Love2D or use official PPA. - if ffi.C.PHYSFS_mount(mdir, '/', 0) == 0 - then error 'Cannot mount' - else - ll.mdir = mdir - ll.mgme = gme - end -end - -function ll.umount() - if ll.mdir ~= nil then - ffi.C.PHYSFS_unmount(ll.mdir) - ll.mdir = nil - end -end - -end diff --git a/lib/love/load.lua b/lib/love/load.lua deleted file mode 100644 index 787d1d7..0000000 --- a/lib/love/load.lua +++ /dev/null @@ -1,28 +0,0 @@ -return function(ll) - - function ll.gameAdd(conf, file, base, dir) - local gme = ll.gameNew(conf, file, base, dir) - gme.dat = {} - - if gme.screens and gme.screens[1] then - gme.dat.scr = {} - for i = 1, #gme.screens do - table.insert(gme.dat.scr, love.graphics.newImage(ll.cfg.root .. gme.dir ..'/'.. gme.screens[i])) - end - end - - table.insert(ll.games, gme) - return gme - end - -for _, dir in pairs(love.filesystem.getDirectoryItems(ll.cfg.root)) do - local file = ll.cfg.root .. dir..'/'.. 'info.ll' - ll.gameAdd( - love.filesystem.read(file), - file, - love.filesystem.getSource():match '(.*)[\\/]*' ..'/'.. ll.cfg.root, -- TODO: AppData folders support - dir - ) -end - -end diff --git a/lib/main.lua b/lib/main.lua index 86d4169..dee7506 100644 --- a/lib/main.lua +++ b/lib/main.lua @@ -4,24 +4,24 @@ ll.cfg = { root = 'games/', } +require 'lib.fs' (ll) require 'lib.game' (ll) require 'lib.chroot' (ll) require 'lib.load' (ll) +require 'lib.keyb' (ll) function ll.home() ll.umount() - error 'go to home' + love.event.push('quit', 'restart') end -if love then - require 'lib.love.chroot' (ll) - require 'lib.love.load' (ll) - - function ll.home() - ll.umount() - love.event.push('quit', 'restart') +ll.dt = false +function ll.devtools() + if not ll.dt then + ll.dt = true + __LL = ll + pcall(function() require 'dev.tools' end) end - llHome = ll.home end return ll diff --git a/ll-min.lua b/ll-min.lua index 37edda9..eafd105 100644 --- a/ll-min.lua +++ b/ll-min.lua @@ -1,8 +1,17 @@ --- minimal Love Loader API +-- Minimal Love Loader API +-- Version 2.1 +-- (c) Er2 2022 +-- Zlib License if not llUsed then COLDIV = love.getVersion() == 0 and 1 or 255 +MOBILE = love.system.getOS() == 'Android' + or love.system.getOS() == 'iOS' + +if MOBILE +then love.window.setFullscreen(true) +end function love.resize(x, y) W, H = x, y diff --git a/luapack.lua b/luapack.lua index f4ab5ff..ab4dec7 100644 --- a/luapack.lua +++ b/luapack.lua @@ -9,6 +9,7 @@ return { 'llHome', 'resize', 'COLDIV', + 'MOBILE', 'W', 'H', } }, diff --git a/readme.md b/readme.md index b14a9b3..f0871b3 100644 --- a/readme.md +++ b/readme.md @@ -15,8 +15,7 @@ with custom event handling and redrawing. # LibLL -Love Loader from v2.0 includes library to simplify creating custom interfaces. -It is like a backend for Love Loader. +Love Loader from 2.0 includes backend API to simplify creating custom skins. It have not so many functions and fields: @@ -43,7 +42,9 @@ It have not so many functions and fields: Creates game object (defined above) and returns it. -- `ll.gameAdd(conf, file, base, dir)` - same as `ll.gameNew`, but inserts game into `ll.games`. +- `ll.gameAdd(conf, file, base, dir)` - same as `ll.gameNew` with insertion into `ll.games`. + +- `ll.addGame(fileName, fileContent)` - function for file dropping, reserved for v3.0. - `ll.mount(game)` - mounts game. @@ -57,11 +58,29 @@ It have not so many functions and fields: - `ll.home()` - calls `llHome` +- `ll.dt` - is developer tools enabled? + +- `__LL` - global variable of Love Loader instance when developer tools enabled. + +- `ll.devtools()` - enable developer tools. + +- `ll.fsIsAbs(file)` - is file absolute (/file)? + +- `ll.fsIsRel(file)` - is file relative, inverted result of ll.fsIsAbs (./file). + +- `ll.fsDir(path)` - get directory name (2 from /1/2/3.file). + +- `ll.fsFile(path)` - get file (including dividers after) (2 from /1/2/). + +- `ll.kbInit(direction --[[string: *, h, v, x, y]], c1 --[[number, coordinate before card for mouse (left/top)]], c2 --[[number, coordinate after card for mouse (right/bottom)]], clim --[[other coordinate limit for mouse or -1 to disable]])` - initialize keyboard module for skins. + +- `ll.kbGet() --[[nil, string: <, >, o, m, ^ anv v if direction is *]]` - get key pressed. + # API -To simplify task to the game developers, this loader creates some global variables to use. +To reduce things to do for game developers, this loader creates some global variables to use. -You can also use it without Love Loader by including `ll-min.lua` file. +You can also use it without Love Loader (or if your game can distribute without loader) by including `ll-min.lua` file. `W` and `H`: width and height of the screen which controls by custom love.resize function. @@ -75,6 +94,8 @@ You can also use it without Love Loader by including `ll-min.lua` file. `COLDIV`: color divider (1 or 255) to `love.graphics.setColor` function. +`MOBILE`: is this device runs Android or iOS? + # Fill game information To fill game information in game folder need to create `info.ll` file. @@ -89,3 +110,4 @@ desc = Some descripion about the game. pic = screen.png pics = [ screen.png; screen2.png ] # wow arrays ``` + diff --git a/skins/gui.lua b/skins/gui.lua index 10f6c67..fdb2708 100644 --- a/skins/gui.lua +++ b/skins/gui.lua @@ -1,7 +1,5 @@ return function(ll) --- Classic UI from Love Loader v1 - ll.cfg.pcht = ll.cfg.pcht or 60 * 5 local pikchv, pikcha = 0, 0 @@ -10,8 +8,8 @@ local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5) local cx, cy, cw, ch local f, bf -local mx, mb, mpb = 0, 0, 0 -local cdir, sel = 0, 1 +local sel = 1 +local cdir function resize() cw = W / 1.25 @@ -23,40 +21,25 @@ function resize() f = love.graphics.newFont(th / 3) bf = love.graphics.newFont(th / 2) + + ll.kbInit('h', cx, cx + cw) end local function update() - mx = love.mouse.getX() - mpb = mb - if love.mouse.isDown(1) then mb = 1 - else mb = 0 end - - local sdi = 0 - if mpb == 1 and mb == 0 then - if mx <= cx - then sdi = 1 - elseif mx >= cx + cw - then sdi = 2 - else sdi = 3 - end - end - - if love.keyboard.isScancodeDown('left', 'a') - then sdi = 1 - elseif love.keyboard.isScancodeDown('right', 'd') - then sdi = 2 - elseif love.keyboard.isScancodeDown('return', 'space') - then sdi = 3 - end + local sdi = ll.kbGet() if cdir ~= sdi then cdir = sdi - if sdi == 1 + if sdi == '<' then sel = sel - 1 - elseif sdi == 2 + elseif sdi == '>' then sel = sel + 1 - elseif sdi == 3 and ll.games[sel] + elseif sdi == 'o' and ll.games[sel] then ll.mount(ll.games[sel]) + + elseif sdi == 'm' + and love.mouse.getX() >= W - 8 + then ll.devtools() end if sel < 1 then sel = #ll.games end @@ -78,11 +61,6 @@ local function update() end else pikcha = math.min(255, pikcha + pikchao) end - - if love.keyboard.isDown 'menu' - and mx >= W - 8 - then pcall(select(2, pcall(require, 'dev.devtools')), ll) - end end local tm = 0 diff --git a/skins/psp.lua b/skins/psp.lua index fc4a34e..2427148 100644 --- a/skins/psp.lua +++ b/skins/psp.lua @@ -15,6 +15,9 @@ ll.cfg.pcht = ll.cfg.pcht or 60 * 5 local pikchv, pikcha = 0, 0 local pikchao = math.floor(1 / ll.cfg.pcht * 2 * 255 + 0.5) +local logger = '' +local chc = '<>><' + function resize() r = math.min(W, H) / 30 @@ -26,57 +29,38 @@ 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) end love.window.setMode(800, 600, {resizable = true}) -local my, mb, mpb - -local sdir = 0 +local sdir local function update() local ty = H / 2 - (ch + cg) * sel cy = cy + (ty - cy) * 0.1 css = css + (2 - css) * 0.2 rcss = 2 - css + 1 - local sdi - - my = love.mouse.getY() - mpb = mb - if love.mouse.isDown(1) then mb = 1 - else mb = 0 - end - if mb == 0 and mpb == 1 then - if my <= H / 2 - ch - then sdi = 1 - elseif my >= H / 2 + ch + cg - then sdi = 2 - else sdi = 3 - end - elseif love.keyboard.isScancodeDown('up', 'w') - then sdi = 1 - elseif love.keyboard.isScancodeDown('down', 's') - then sdi = 2 - elseif love.keyboard.isScancodeDown('return', 'space') - then sdi = 3 - else sdi = 0 - end + local sdi = ll.kbGet() if sdi ~= sdir then - if sdi ~= 0 + if sdi then rcss = css css = 1 - if sdi == 3 - then css = 1.5 - end psel = sel + logger = logger .. sdi + if logger == chc then + resize() + ll.devtools() + end end sdir = sdi - if sdi == 1 + if sdi == '<' then sel = sel - 1 - elseif sdi == 2 + elseif sdi == '>' then sel = sel + 1 - elseif sdi == 3 and ll.games[sel] + elseif sdi == 'o' and ll.games[sel] then ll.mount(ll.games[sel]) end