commit 1b55bb0ba653c4df442c94c380f74beaed1291ec Author: Er2 Date: Wed Feb 16 21:53:37 2022 +0300 init diff --git a/autoexec.lua b/autoexec.lua new file mode 100644 index 0000000..40043e3 --- /dev/null +++ b/autoexec.lua @@ -0,0 +1,8 @@ +-- Autoexec for ErDOS +--- (c) Er2 2022 +--- Zlib License + +-- Load default shell + +loadapp 'ver' +loadapp 'ersh' diff --git a/license b/license new file mode 100644 index 0000000..888e15d --- /dev/null +++ b/license @@ -0,0 +1,19 @@ +Zlib License + +Copyright (c) 2022 Er2 + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgement in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..1e03e17 --- /dev/null +++ b/main.lua @@ -0,0 +1,8 @@ +-- Startup + +local con = require 'src.term.init' +require 'src.os' (con) + +require 'autoexec' + +love.event.push 'quit' diff --git a/src/async.lua b/src/async.lua new file mode 100644 index 0000000..92702b2 --- /dev/null +++ b/src/async.lua @@ -0,0 +1,48 @@ + +ACTIVE = true +function __run() + if love.event then + love.event.pump() + for n, a,b,c,d,e,f in love.event.poll() do + if n == 'quit' or not ACTIVE then + if not love.quit or not love.quit() then + ACTIVE = false + return a or 0 + end + end + love.handlers[n](a,b,c,d,e,f) + end + end + + local dt = 0 + if love.timer + then dt = love.timer.step() or love.timer.getDelta() + end + + if love.update then love.update(dt) end + if love.graphics and love.graphics.isActive() then + love.graphics.origin() + love.graphics.clear(0, 0, 0) + if love.draw then love.draw() end + love.graphics.present() + end + if love.timer then love.timer.sleep(0.001) end +end + +function await(fn) + while fn() ~= true do + if not ACTIVE then break end + __run() + end +end + +function love.run() + if love.timer then love.timer.step() end + if love.getVersion() == 0 + then + while ACTIVE do + __run() + end + else return __run + end +end diff --git a/src/baseshell.lua b/src/baseshell.lua new file mode 100644 index 0000000..a9c7ccc --- /dev/null +++ b/src/baseshell.lua @@ -0,0 +1,83 @@ +return function(con) + +local sh = { + prompt = function() return '>' end, + runs = true, + env = { + code = 0, + path = 'sysapps:apps', + } +} + +function sh:which(cmd) + local file = cmd or '' + if file:sub(-4) ~= '.lua' + then file = file.. '.lua' + end + if fsHas(file) + then return '', file end + for path in self.env.path:gmatch '[^:]+' do + if fsHas(path..'/'..file) + then return path, '/'..file + end + end +end + +function sh:parseArgs(ln) + local iq, buf, args = false, '', {} + local qt, esc = nil, false + + ln = ln:gsub('%$(%S+)%s*=%s*(.*)$', function(k, v) + env[k] = self:parseArgs(v)[1] + return '' + end) + + -- helper function + local function psh() + if buf:sub(1,1) == '$' + then buf = tostring(self.env[buf:sub(2)] or '') end + if #buf > 0 then table.insert(args, buf) end + buf, qt = '', nil + end + + for i = 1, #ln + 1 do + local v = ln:sub(i, i) + if ((v == ' ' or v == '\n' or v == '\t') and not iq) + or v == '' + then psh() + + elseif esc then esc, buf = false, buf.. v + elseif v == '\\' then esc = true + + elseif (not qt or qt == v) + and (v == '"' or v == "'") + then psh() + qt, iq = v, not iq + + else buf = buf.. v + end + end + + return args +end + +function sh:run() + return 'TODO' +end + +function sh:loop() + await(function() + con.print(self:prompt()) + local ln = con.getln() + con.down() + + local res = self:run(ln) + if res then con.println(res) end + + return not self.runs + end) +end + +return sh + +end diff --git a/src/draw.lua b/src/draw.lua new file mode 100644 index 0000000..6e8f525 --- /dev/null +++ b/src/draw.lua @@ -0,0 +1,31 @@ +-- Drawing API +--- (c) Er2 2021-2022 +--- Zlib License + +local comp = { + 'system', 'transform', + 'color', 'figures', 'font', + 'line', 'picture', 'rcorn', + 'rrect', +} + +FILL, LINE = 1, 0 + +local draw = {} +draw.__index = draw + +function draw.new(w, h) + assert(w > 0 and h > 0, 'cr must be greater than 0') + local cr = setmetatable({}, draw) + cr._cr = love.graphics.newCanvas(w, h) + cr.w, cr.h = w, h + cr:newFont() + return cr +end + +for _, v in pairs(comp) do + require('src.draw.'.. v)(draw) +end + +draw:newFont() +return setmetatable({}, draw) diff --git a/src/draw/color.lua b/src/draw/color.lua new file mode 100644 index 0000000..3e5c269 --- /dev/null +++ b/src/draw/color.lua @@ -0,0 +1,32 @@ + +local f = (love.getVersion or + function() return love._version_major +end)() == 0 and 1 or 255 + +return function(draw) + +function draw:color(r, g, b, a) + a = a or 255 + love.graphics.setColor(r / f, g / f, b / f, a / f) + return self +end + +function draw:colorT(t) + return self:color(t[1], t[2], t[3], t[4]) +end + +function draw:colorH(hex) + hex = (tostring(hex) or ''):lower() + local r, g, b, a = hex:match '#?(%x%x?)(%x%x?)(%x%x?)' + r = #r == 1 and r..r or r + g = #g == 1 and g..g or g + b = #b == 1 and b..b or b + if a then a = #a == 1 and a..a or a end + return self:color( + tonumber(r, 16), tonumber(g, 16), + tonumber(b, 16), + not a and 255 or tonumber(a, 16) + ) +end + +end diff --git a/src/draw/figures.lua b/src/draw/figures.lua new file mode 100644 index 0000000..50adaac --- /dev/null +++ b/src/draw/figures.lua @@ -0,0 +1,44 @@ + +local function gm(m) + return m == FILL and 'fill' or 'line' +end + +return function(draw) + +function draw:rect(m, x, y, w, h) + love.graphics.rectangle(gm(m), x, y, w, h) + return self +end + +function draw:ellipse(m, x, y, rx, ry) + love.graphics.ellipse(gm(m), x, y, rx, ry) + if m == FILL then + self:ellipse(LINE, x, y, rx, ry) + end + return self +end + +function draw:circle(m, x, y, r) + return self:ellipse(m, x, y, r, r) +end + +function draw:triang(m, x, y, ox1, oy1, ox2, oy2) + if m == FILL then self:triang(LINE, x, y, ox1, oy1, ox2, oy2) end + love.graphics.polygon(gm(m), x, y, x + ox1, y + oy1, x + ox2, y + oy2) + return self +end + +function draw:arc(m, cx, cy, r, sa, ea) + love.graphics.arc(gm(m), m == FILL and 'pie' or 'open', + cx, cy, r, sa, ea) + if m == FILL then self:arc(LINE, cx, cy, r, sa, ea) end + return self +end + +function draw:text(t, x, y) + love.graphics.setFont(self.f) + love.graphics.print(t, x, y) + return self +end + +end diff --git a/src/draw/font.lua b/src/draw/font.lua new file mode 100644 index 0000000..7d6f78b --- /dev/null +++ b/src/draw/font.lua @@ -0,0 +1,16 @@ +return function(draw) + +function draw:font(f) + if f then self.f = f end + return self +end + +function draw:newFont(...) + return self:font(love.graphics.newFont(...)) +end + +function draw:getFText(t) + return self.f:getWidth(t), self.f:getHeight(t) +end + +end diff --git a/src/draw/line.lua b/src/draw/line.lua new file mode 100644 index 0000000..7ead00d --- /dev/null +++ b/src/draw/line.lua @@ -0,0 +1,13 @@ +return function(draw) + +function draw:lineWidth(w) + love.graphics.setLineWidth(w) + return self +end + +function draw:line(x1, y1, x2, y2) + love.graphics.line(x1, y1, x2, y2) + return self +end + +end diff --git a/src/draw/picture.lua b/src/draw/picture.lua new file mode 100644 index 0000000..5830287 --- /dev/null +++ b/src/draw/picture.lua @@ -0,0 +1,13 @@ +return function(draw) + +function draw:img(im, x, y, r, sx, sy) + love.graphics.draw(im, x, y, r, sx, sy) + return self +end + +function draw:cr(cr, x, y, r, sx, sy) + if cr.fr then return end + return self:img(cr._cr, x, y, r, sx, sy) +end + +end diff --git a/src/draw/rcorn.lua b/src/draw/rcorn.lua new file mode 100644 index 0000000..e4935ec --- /dev/null +++ b/src/draw/rcorn.lua @@ -0,0 +1,33 @@ +return function(draw) + +function draw:rcorn(x, y, d, p) + p = p or 1 + if p == 1 then self -- bot-right + + :arc(LINE, x - d, y - d, d, 0, math.pi / 2) + :triang(FILL, x, y - d, 0, d, -d/2, d) + :triang(FILL, x - d, y, d / 1.5, -d / 4, d, 0) + + elseif p == 2 then self -- bot-left + + :arc(LINE, x + d, y - d, d, math.pi / 2, math.pi) + :triang(FILL, x, y - d, 0, d, d/2, d) + :triang(FILL, x, y, d / 1.5, -d / 4, d, 0) + + elseif p == 3 then self -- top-right + + :arc(LINE, x - d, y + d, d, math.pi * 1.5, math.pi * 2) + :triang(FILL, x, y, 0, d, -d/2, 0) + :triang(FILL, x - d, y, d / 1.5, d / 4, d, 0) + + elseif p == 4 then self -- top-left + + :arc(LINE, x + d, y + d, d, math.pi, math.pi * 1.5) + :triang(FILL, x, y, 0, d, d/2, 0) + :triang(FILL, x, y, d / 1.5, d / 4, d, 0) + + end + return self +end + +end diff --git a/src/draw/rrect.lua b/src/draw/rrect.lua new file mode 100644 index 0000000..4358a08 --- /dev/null +++ b/src/draw/rrect.lua @@ -0,0 +1,33 @@ +return function(draw) + +function draw:rrect(m, x, y, w, h, r) + local rtl, rtr, rbl, rbr = r[1] or 8, r[2], r[3], r[4] + rtr = rtr or rtl + rbl = rbl or rtl + rbr = rbr or rbl + + local ml, mr, Ml, Mr, Mt, Mb = + math.min(rtl, rbl), math.min(rtr, rbr), + math.max(rtl, rbl), math.max(rtr, rbr), + math.max(rtl, rtr), math.max(rbl, rbr) + if m == FILL then self + :rect(m, x + Ml, y + Mt, w - Ml - Mr, h - Mt - Mb) + :rect(m, x + rtl, y, w - rtl - rtr, Mt) -- top + :rect(m, x + rbl, y + h - Mb, w - rbl - rbr, Mb) -- bottom + :rect(m, x, y + rtl, Ml, h - rtl - rbl) -- left + :rect(m, x + w - Mr, y + rtr, Mr, h - rtr - rbr) -- right + end + self + :line(x + rtl, y, x + w - rtr, y) + :line(x, y + rtl, x, y + h - rbl) + :line(x + rbl, y + h, x + w - rbr, y + h) + :line(x + w, y + rtr, x + w, y + h - rbr) + + :arc(m, x + rtl, y + rtl, rtl, math.pi, math.pi * 1.5) + :arc(m, x + w - rtr, y + rtr, rtr, math.pi * 1.5, math.pi * 2) + :arc(m, x + w - rbr, y + h - rbr, rbr, 0, math.pi / 2) + :arc(m, x + rbl, y + h - rbl, rbl, math.pi / 2, math.pi) + return self +end + +end diff --git a/src/draw/system.lua b/src/draw/system.lua new file mode 100644 index 0000000..231e1ed --- /dev/null +++ b/src/draw/system.lua @@ -0,0 +1,36 @@ +return function(draw) + +function draw:free(f) + if self.fr then return end + self.fr = true + --if self._cr then self._cr:release() end + if f then draw:freeFont() end + collectgarbage 'collect' +end +function draw:freeFont() + if self.f then self.f:release() end +end + +function draw:give() + if self.fr then return end + self.pc = love.graphics.getCanvas() + if self.pc ~= self.cr then + love.graphics.push() + love.graphics.origin() + love.graphics.setCanvas(self._cr) + end + return self +end + +function draw:back() + love.graphics.setCanvas(self.pc) + love.graphics.pop() + return self +end + +function draw:full(full) + love.window.setFullscreen(full or false) + return self +end + +end \ No newline at end of file diff --git a/src/draw/transform.lua b/src/draw/transform.lua new file mode 100644 index 0000000..72be04c --- /dev/null +++ b/src/draw/transform.lua @@ -0,0 +1,18 @@ +return function(draw) + +function draw:orig() + love.graphics.origin() + return self +end + +function draw:move(x, y) + love.graphics.translate(x, y) + return self +end + +function draw:scale(sx, sy) + love.graphics.scale(sx, sy) + return self +end + +end \ No newline at end of file diff --git a/src/fs.lua b/src/fs.lua new file mode 100644 index 0000000..5ad852a --- /dev/null +++ b/src/fs.lua @@ -0,0 +1,31 @@ +return function() + +local lfs = love.filesystem + +function fsLs(path) + return lfs.getDirectoryItems(path) +end + +function fsHas(file) + if lfs.getInfo + then return not not lfs.getInfo(file) end + return lfs.exists(file) +end + +function fsInfo(file) + if lfs.getInfo + then return lfs.getInfo(file) + end + if not fsHas(file) + then return end + local info = {} + if lfs.isFile(file) then info.type = 'file' + elseif lfs.isDirectory(file) then info.type = 'directory' + elseif lfs.isSymlink(file) then info.type = 'symlink' + else info.type = 'other' end + info.size = lfs.getSize(file) + info.modtime = lfs.getLastModified(file) + return info +end + +end diff --git a/src/gui.lua b/src/gui.lua new file mode 100644 index 0000000..a2ad4e1 --- /dev/null +++ b/src/gui.lua @@ -0,0 +1,28 @@ +local nlv = {} +for k, v in pairs(love) do + nlv[k] = v +end + +local gui = {} + +function gui.init() + love.draw = gui.draw + love.update = gui.update + + love.keypressed = nil + love.keyreleased = nil + love.textedited = nil + love.textinput = nil +end + +function gui.update(dt) + updM() +end + +function gui.stop() + for k, v in pairs(nlv) do + love[k] = v + end +end + +return gui diff --git a/src/hack.ttf b/src/hack.ttf new file mode 100644 index 0000000..92a90cb Binary files /dev/null and b/src/hack.ttf differ diff --git a/src/mouse.lua b/src/mouse.lua new file mode 100644 index 0000000..601df3b --- /dev/null +++ b/src/mouse.lua @@ -0,0 +1,53 @@ +return function(con) + +local mob = love.system.getOS() == 'Android' + +m = { + x = 0, y = 0, + mx = 0, my = 0, + b = 0, pb = 0, + t = os.time(), +} +function updM() + local x, y = love.mouse.getPosition() + m.mx, m.my = x - m.x, y - m.y + m.x, m.y = x, y + + m.pb = m.b + if love.mouse.isDown(1) then m.b = 1 + elseif love.mouse.isDown(2) then m.b = 2 + elseif love.mouse.isDown(3) then m.b = 3 + else m.b = 0 end + + if m.b ~= 0 and m.pb == 0 + then m.t = os.time() end + + if m.pb == 0 and m.b ~= 0 + then m.mx, m.my = 0, 0 + end +end + +function love.update(dt) + updM() + + if m.b == 0 and m.pb ~= 0 then + if os.time() - m.t < 1 then + if mob + then love.keyboard.setTextInput( + not love.keyboard.hasTextInput(), + 0, con.th + con.oy, + con.w * con.cw, con.ch) + end + con.down() + end + end + + if m.b == 1 + then con.move(m.my) end +end + +function love.wheelmoved(x, y) + con.move(y * con.ch) +end + +end diff --git a/src/os.lua b/src/os.lua new file mode 100644 index 0000000..528425e --- /dev/null +++ b/src/os.lua @@ -0,0 +1,55 @@ +VER = '0.1' + +return function(con) + +love.keyboard.setKeyRepeat(true) + +require 'src.mouse' (con) +require 'src.fs' () +require 'src.async' +draw = require 'src.draw' + +local w, h +function love.resize(x, y) + w, h = math.max(32, x), math.max(32, y) + draw:newFont('src/hack.ttf', math.min(w, h) / 32) + local cw, ch = draw:getFText 'A' + collectgarbage 'collect' + con:emit('res', w, h, cw, ch) +end +love.resize(love.graphics.getDimensions()) +love.window.setMode(w, h, { + resizable = true, + minwidth = 32, + minheight = 32 +}) + +love.textinput = con.type +love.keypressed = con.keydown + +function love.draw() + draw:color(100, 255, 0) + con.forText(function(l, x, y) + local cw, ch = draw:getFText(l) + if not ( + l == '\n' + or l == '\r' + or l == '\v' + or l == '\t' + ) + then draw:text(l, x * con.cw + (con.cw - cw) / 2, y * con.ch + con.oy) + end + end) +end + +function loadapp(name, ...) + local succ, msg = pcall(require, 'sysapps.'.. name) + if not succ then + con.println('ERROR: '.. msg) + print(msg) + else + msg({...}, con) + end +end + +end diff --git a/src/term/events.lua b/src/term/events.lua new file mode 100644 index 0000000..28de8d0 --- /dev/null +++ b/src/term/events.lua @@ -0,0 +1,51 @@ +--[[ Events library + -- (c) Er2 2021 + -- Zlib License +--]] + +local events = {} +events.__index = events + +function events:_add(t, n, f) + table.insert(self._ev_, { + type = t, + name = n, + fn = f, + }) +end + +function events:on(n,f) self:_add('on', n,f) end +function events:once(n,f) self:_add('once', n,f) end + +function events:off(f) + for k, v in pairs(self._ev_) do + if v.fn == f then + table.remove(self._ev_, k) + end + end +end + +function events:_ev(t, i, name, ...) + local v = t[i] + if v.name == name then + v.fn(...) + if v.type == 'once' then table.remove(t, i) end + end +end + +function events:emit(name, ...) + local t = self._ev_ + for i = 1, #t do + local v = t[i] or {} + if type(v) == 'table' + and type(v.name) == 'string' + and type(v.type) == 'string' + and type(v.fn) == 'function' + then self:_ev(t, i, name, ...) end + end +end + +return function(t) + t._ev_ = {} + return setmetatable(t, events) +end diff --git a/src/term/get.lua b/src/term/get.lua new file mode 100644 index 0000000..6eccd27 --- /dev/null +++ b/src/term/get.lua @@ -0,0 +1,43 @@ +return function(con) + +function con.getch(tout) + local t, ch = os.time(), nil + con.usebs = false + con:once('type', function(text) + ch = text:sub(1, 1) + end) + await(function() return + ch ~= nil + or (tout and os.time() - t >= tout) + end) + con.usebs = true + return ch +end + +function con.getln() + local ln, du = '', true + local function _ln(text) + ln = ln .. text + end + local function _dwn(k) + if k == 'backspace' then + if #ln == 0 then con.usebs = false + else + con.usebs = true + ln = con.bs(ln) + end + end + end + con:on('type', _ln) + con:on('down', _dwn) + con:once('return', function() + con:off(_ln) + con:off(_dwn) + con.usebs = true + du = false + end) + await(function() return not du end) + return ln +end + +end diff --git a/src/term/init.lua b/src/term/init.lua new file mode 100644 index 0000000..8882903 --- /dev/null +++ b/src/term/init.lua @@ -0,0 +1,24 @@ +utf8 = require 'utf8' + +-- Model +local con = { + text = {''}, + w = 0, h = 0, + cw = 0, ch = 0, + oy = 0, th = 0, + usebs = true, +} + +local m = { + 'events', -- REQUIRED! + 'loop', + 'resize', 'type', 'get', +} + +for _, v in pairs(m) do + require('src.term.'.. v)(con) +end + +con:emit('init') + +return con diff --git a/src/term/loop.lua b/src/term/loop.lua new file mode 100644 index 0000000..097e9cb --- /dev/null +++ b/src/term/loop.lua @@ -0,0 +1,27 @@ +return function(con) + +function con.forLine(l, fn, oy) + local x, y = 0, 0 + for j, l in utf8.codes(con.text[l]) do + l = utf8.char(l) + if fn then fn(l, x, y + oy) end + if l == '\t' then x = x + 8 - (x % 8) + elseif l == '\v' then y = y + 1 + elseif l == '\r' then x = 0 + else x = x + 1 + end + if x + 1 > con.w + then x, y = 0, y + 1 end + end + return y +end + +function con.forText(fn) + local y = 0 + for i = 1, #con.text do + y = y + 1 + con.forLine(i, fn, y) + end + return y +end + +end diff --git a/src/term/resize.lua b/src/term/resize.lua new file mode 100644 index 0000000..0aafafd --- /dev/null +++ b/src/term/resize.lua @@ -0,0 +1,31 @@ +return function(con) + +con:on('res', function(w, h, cw, ch) + con.cw, con.ch = cw or con.cw, ch or con.ch + con.w, con.h = + math.floor(w / cw), + math.floor(h / ch) + con:emit('resT') +end) + +con:on('resT', function() + local y = con.forText() + con.th = y * con.ch +end) + +function con.down() + con.oy = 0 + con.move(-math.huge) +end + +function con.move(oy) + con.oy = con.oy + oy + con.oy = math.max( + -(con.th - con.ch * con.h / 1.2), + math.min(con.oy, 0) + ) + if con.th < (con.ch - 1) * con.h + then con.oy = 0 end +end + +end diff --git a/src/term/type.lua b/src/term/type.lua new file mode 100644 index 0000000..bd6b48a --- /dev/null +++ b/src/term/type.lua @@ -0,0 +1,67 @@ +return function(con) + +function con.curln(of) + return con.text[#con.text - (of or 0)] +end + +function con.setln(v, of) + con.text[#con.text - (of or 0)] = tostring(v) + return v +end + +function con.bs(oth) + if not con.usebs then return end + local s = oth or con.curln() + local off = utf8.offset(s, -1) + if off then + s = s:sub(1, off - 1) + end + if not oth then con.setln(s) end + return s +end + +function con.cls() + con.text = {''} + con.oy = 0 +end + +function con.print(text) + for i, v in utf8.codes(tostring(text)) do + v = utf8.char(v) + if v == '\n' then con.ret() + elseif v == '\b' then con.bs() + -- \r\t\v is in loop + else con.puts(v) + end + end +end + +function con.puts(text) + con.setln(con.curln().. text) + con:emit('resT') +end + +function con.println(text) + con.print(tostring(text).. '\n') +end + +function con.ret() + table.insert(con.text, '') +end + +function con.type(text) + con.puts(text) + con:emit('type', text) +end + +function con.keydown(k) + con:emit('down', k) + if k == 'backspace' then con.bs() + elseif k == 'return' then + con.ret() + con.down() + con:emit('return') + end +end + +end diff --git a/src/win.lua b/src/win.lua new file mode 100644 index 0000000..c7eb88a --- /dev/null +++ b/src/win.lua @@ -0,0 +1,54 @@ +local gui = require 'src.gui' + +local wins = { + {x = 64, y = 64, w = 64, h = 64}, +} + +local bw, th = 8, 16 + +function gui.draw() + draw:color(0, 100, 150) + :rect(FILL, 0, 0, gui.w, gui.h) + :color(255, 255, 255) + :text('This is a demo of GUI in ErDOS', gui.w / 4, gui.h / 2) + for i = #wins, 1, -1 do + local v = wins[i] + draw + :color(100, 100, 100) + :rrect(FILL, + v.x - bw, v.y - bw - th, + v.w + bw * 2, v.h + bw * 2 + th, + {bw} + ) + :color(255, 255, 255) + :rect(FILL, v.x, v.y, v.w, v.h) + end +end + +function AABB(x1, y1, w1, h1, x2, y2, w2, h2) + return + x1 + w1 > x2 + and x2 + w2 > x1 + and y1 + h1 > y2 + and y2 + h2 > y1 +end + +function gui.update(dt) + updM() + for i = 1, #wins do + local v = wins[i] + if AABB(m.x, m.y, 0, 0, + v.x - bw, v.y - bw - th, + v.w + bw * 2, v.h + bw * 2 + th + ) then + gui.stop() + end + end +end + +return function(w, h) + gui.init() + gui.w, gui.h = + w or gui.w or 0, + h or gui.h or 0 +end diff --git a/sysapps/choise.lua b/sysapps/choise.lua new file mode 100644 index 0000000..e266c62 --- /dev/null +++ b/sysapps/choise.lua @@ -0,0 +1,35 @@ +return function(argv, con) + -- /Ckeys /S text + local ch = {'Y', 'N'} + local cs = false + local i = 2 + while argv[i] do + local v = argv[i]:upper() + if v:sub(1,1) == '/' + then table.remove(argv, i) + else i = i + 1 + end + if v:sub(1, 2) == '/C' + and #v > 2 then + ch = {} + for l in v:sub(3):gmatch '.' do table.insert(ch, l) end + elseif v == '/S' then cs = true + end + end + con.print(table.concat(argv, ' ', 2)) + con.print(' ['.. table.concat(ch, ',') ..'] ') + con.print('('.. ch[1] ..') ') + local chr = con.getch(10) + if not chr then chr = ch[1] end + + local ret = 0 + for k, v in pairs(ch) do + if v == chr + or (not cs and v:upper() == chr:upper()) + then ret = k end + end + + con.print '\n' + + return ret +end diff --git a/sysapps/cls.lua b/sysapps/cls.lua new file mode 100644 index 0000000..b4c8d6a --- /dev/null +++ b/sysapps/cls.lua @@ -0,0 +1,3 @@ +return function(argv, con) + con.cls() +end diff --git a/sysapps/dir.lua b/sysapps/dir.lua new file mode 100644 index 0000000..759a5a3 --- /dev/null +++ b/sysapps/dir.lua @@ -0,0 +1,31 @@ +return function(argv, con) + local dir = argv[2] or '' + con.print(' Listing of '..dir ..'\n\n') + local d = fsLs(dir) + local dirs, files, tb = 0, 0, 0 + for _, v in pairs(d) do + local i = fsInfo(dir..'/'..v) + con.print(os.date('%m/%d/%Y %I:%M %p ', i.modtime)) + if i.type == 'directory' then con.print '' + elseif i.type == 'symlink' then con.print '' + elseif i.type == 'other' then con.print '' + else con.print ' ' end + if i.type == 'directory' then + dirs = dirs + 1 + con.print ' ' + else + files = files + 1 + tb = tb + i.size + con.print ' ' + local s = tostring(i.size) + con.print((' '):rep(7 - #s)) + con.print(s) + con.print ' ' + end + + con.println(v) + end + con.println(('%d File(s)\n%d Dir(s)\n%d Bytes total') + :format(files, dirs, tb)) + con.print '\n' +end diff --git a/sysapps/echo.lua b/sysapps/echo.lua new file mode 100644 index 0000000..619b5c7 --- /dev/null +++ b/sysapps/echo.lua @@ -0,0 +1,3 @@ +return function(argv, con) + con.println(table.concat(argv, ' ', 2)) +end diff --git a/sysapps/ersh.lua b/sysapps/ersh.lua new file mode 100644 index 0000000..56d8f83 --- /dev/null +++ b/sysapps/ersh.lua @@ -0,0 +1,65 @@ +return function(argv, con) + +if argv[2] == '-v' +then + con.println 'Er2Shell 0.5' + return +end + +local sh = require 'src.baseshell' (con) + +function sh:prompt() + return ('%d > '):format(self.env.code) +end + +function sh:run(ln) + local argv = self:parseArgs(ln) + + if not argv[1] then -- nothing + + elseif argv[1] == 'exit' then + self.runs = false + + elseif argv[1] == 'which' then + local fnd, snd = self:which(argv[2]) + if not fnd then self.env.code = 1 + else self.env.code = 0 + return fnd..snd + end + + elseif argv[1] == 'env' then + local ls = '' + for k, v in pairs(self.env) do + k, v = tostring(k), tostring(v) + ls=ls.. ('$%s=%s\n') + :format(k, v:match '%s' and '"'..v..'"' or v) + end + self.env.code = 0 + return ls:sub(1, -2) + + else + local fnd, snd = self:which(argv[1]) + if not fnd then + self.env.code = 127 + return argv[1].. ': command not found' + else self.env.code = 0 + local succ, msg = pcall(select(2, pcall(loadfile, fnd..snd))) + if not succ then + print(msg) + self.env.code = 126 + return argv[1].. ': file error' + else + local succ, msg = pcall(msg, argv, con, self.env) + if not succ then + self.env.code = self.env.code ~= 0 and self.env.code or 1 + return argv[1].. ': '.. tostring(msg) + else self.env.code = tonumber(msg) or 0 + end + end + end + end +end + +sh:loop() + +end diff --git a/sysapps/run.lua b/sysapps/run.lua new file mode 100644 index 0000000..393fa93 --- /dev/null +++ b/sysapps/run.lua @@ -0,0 +1,7 @@ +return function(argv, con) + local pr = print + print = con.println + local suc, ret = pcall(load(table.concat(argv, ' ', 2))) + print(ret) + print = pr +end diff --git a/sysapps/ver.lua b/sysapps/ver.lua new file mode 100644 index 0000000..1467c18 --- /dev/null +++ b/sysapps/ver.lua @@ -0,0 +1,5 @@ +return function(argv, con) + con.println('ErDOS version '.. VER) + con.println('Runs on\vLove2D '.. table.concat({love.getVersion()}, '.', 1, 3)) + con.println('(c) Er2 2022\tZlib License\n') +end diff --git a/sysapps/win.lua b/sysapps/win.lua new file mode 100644 index 0000000..2a71dc6 --- /dev/null +++ b/sysapps/win.lua @@ -0,0 +1,3 @@ +return function(argv, con) + require 'src.win' (con.w * con.cw, con.h * con.ch) +end