global refactoring
This commit is contained in:
		
							parent
							
								
									1b55bb0ba6
								
							
						
					
					
						commit
						0812075336
					
				
					 36 changed files with 209 additions and 742 deletions
				
			
		
							
								
								
									
										91
									
								
								A/ccp.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								A/ccp.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,91 @@ | |||
| return function(argv, con) | ||||
| 
 | ||||
| local runs = true | ||||
| 
 | ||||
| local function parseArgs(ln) | ||||
|   local iq, buf, args = false, '', {} | ||||
|   local qt, esc = nil, false | ||||
| 
 | ||||
|   -- helper function | ||||
|   local function psh() | ||||
|     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 | ||||
| 
 | ||||
| local cd = 'A:' | ||||
| 
 | ||||
| await(function() | ||||
|   con.print(cd.. '>') | ||||
|   con.down() | ||||
|   local ln = con.getln() | ||||
|   local argv = parseArgs(ln) | ||||
| 
 | ||||
|   if not argv[1] then -- nothing | ||||
| 
 | ||||
|   elseif argv[1]:lower() == 'dir' then | ||||
|     local cp, f = 0, fsLs(cd) | ||||
|     for _, v in pairs(f) do | ||||
|       if cp + 14 + #cd >= con.w | ||||
|       then con.print '\n'; cp = 0 end | ||||
|       if cp == 0 then cp = #cd | ||||
|         con.print(cd) | ||||
|       else con.print ' : ' end | ||||
|       local i = fsInfo(cd..v) | ||||
|       local n, ext = v:match('(.+)%.(.+)$') | ||||
|       n = n or v | ||||
|       if #n > 8 | ||||
|       then con.print(n:sub(1, 6) .. '~1') | ||||
|       elseif #n < 8 | ||||
|       then con.print(n ..(' '):rep(8 - #n)) | ||||
|       end | ||||
|       con.print ' ' | ||||
|       if i.type == 'directory'   then con.print '<D>' | ||||
|       elseif i.type == 'symlink' then con.print '<S>' | ||||
|       elseif i.type == 'other'   then con.print '<O>' | ||||
|       elseif ext then | ||||
|         con.print(ext:upper():sub(1, 3)) | ||||
|         con.print((' '):rep(3 - #ext)) | ||||
|       else con.print '   ' | ||||
|       end | ||||
|       cp = cp + 14 | ||||
|     end | ||||
|     con.print '\n' | ||||
| 
 | ||||
|   elseif argv[1]:match '%u:' then | ||||
|     cd = argv[1] | ||||
| 
 | ||||
|   elseif argv[1]:lower() == 'type' then | ||||
|     con.print(fsRead(argv[2])) | ||||
|     con.print '\n' | ||||
| 
 | ||||
|   else con.println(argv[1].. ': command not found') | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
|   return not runs | ||||
| end) | ||||
| 
 | ||||
| return sh | ||||
| 
 | ||||
| end | ||||
							
								
								
									
										8
									
								
								A/ver.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								A/ver.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| return function(argv, con) | ||||
|   con.print('Er2/L '.. VER) | ||||
|   con.print(' On the Love2D '.. table.concat({love.getVersion()}, '.', 1, 3)) | ||||
|   con.println('    20 FEB 22') | ||||
|   local txt = ('Terminal size is %dx%d characters'):format(con.w, con.h) | ||||
|   local sp = (' '):rep((con.w - #txt) / 2) | ||||
|   con.println(sp.. txt ..'\n\n\n') | ||||
| end | ||||
|  | @ -5,4 +5,4 @@ | |||
| -- Load default shell | ||||
| 
 | ||||
| loadapp 'ver' | ||||
| loadapp 'ersh' | ||||
| loadapp 'ccp' | ||||
|  |  | |||
							
								
								
									
										1
									
								
								main.lua
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								main.lua
									
										
									
									
									
								
							|  | @ -5,4 +5,5 @@ require 'src.os' (con) | |||
| 
 | ||||
| require 'autoexec' | ||||
| 
 | ||||
| con.getch() | ||||
| love.event.push 'quit' | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| 
 | ||||
| ACTIVE = true | ||||
| function __run() | ||||
| function __run(debug) | ||||
|   if love.event then | ||||
|     love.event.pump() | ||||
|     for n, a,b,c,d,e,f in love.event.poll() do | ||||
|  | @ -23,10 +23,11 @@ function __run() | |||
|   if love.graphics and love.graphics.isActive() then | ||||
|     love.graphics.origin() | ||||
|     love.graphics.clear(0, 0, 0) | ||||
|     --if debug then love.graphics.rectangle('fill', 0,0, 10, 10) end | ||||
|     if love.draw then love.draw() end | ||||
|     love.graphics.present() | ||||
|   end | ||||
|   if love.timer then love.timer.sleep(0.001) end | ||||
|   --if love.timer then love.timer.sleep(0.001) end | ||||
| end | ||||
| 
 | ||||
| function await(fn) | ||||
|  |  | |||
|  | @ -1,83 +0,0 @@ | |||
| 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 | ||||
							
								
								
									
										31
									
								
								src/draw.lua
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/draw.lua
									
										
									
									
									
								
							|  | @ -1,31 +0,0 @@ | |||
| -- 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) | ||||
|  | @ -1,32 +0,0 @@ | |||
| 
 | ||||
| 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 | ||||
|  | @ -1,44 +0,0 @@ | |||
| 
 | ||||
| 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 | ||||
|  | @ -1,16 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,13 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,13 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,33 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,33 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,36 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,18 +0,0 @@ | |||
| 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 | ||||
							
								
								
									
										16
									
								
								src/fs.lua
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								src/fs.lua
									
										
									
									
									
								
							|  | @ -2,17 +2,23 @@ return function() | |||
| 
 | ||||
| local lfs = love.filesystem | ||||
| 
 | ||||
| function fsPath(path) | ||||
|   local v = path:gsub(':', '/') | ||||
|   return v | ||||
| end | ||||
| 
 | ||||
| function fsLs(path) | ||||
|   return lfs.getDirectoryItems(path) | ||||
|   return lfs.getDirectoryItems(fsPath(path)) | ||||
| end | ||||
| 
 | ||||
| function fsHas(file) | ||||
|   if lfs.getInfo | ||||
|   then return not not lfs.getInfo(file) end | ||||
|   return lfs.exists(file) | ||||
|   then return not not lfs.getInfo(fsPath(file)) end | ||||
|   return lfs.exists(fsPath(file)) | ||||
| end | ||||
| 
 | ||||
| function fsInfo(file) | ||||
|   file = fsPath(file) | ||||
|   if lfs.getInfo | ||||
|   then return lfs.getInfo(file) | ||||
|   end | ||||
|  | @ -28,4 +34,8 @@ function fsInfo(file) | |||
|   return info | ||||
| end | ||||
| 
 | ||||
| function fsRead(file) | ||||
|   return lfs.read(fsPath(file)), nil | ||||
| end | ||||
| 
 | ||||
| end | ||||
|  |  | |||
							
								
								
									
										28
									
								
								src/gui.lua
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								src/gui.lua
									
										
									
									
									
								
							|  | @ -1,28 +0,0 @@ | |||
| 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 | ||||
							
								
								
									
										
											BIN
										
									
								
								src/hack.ttf
									
										
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/hack.ttf
									
										
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/hack.ttf.old
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/hack.ttf.old
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										19
									
								
								src/os.lua
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								src/os.lua
									
										
									
									
									
								
							|  | @ -7,15 +7,14 @@ love.keyboard.setKeyRepeat(true) | |||
| require 'src.mouse' (con) | ||||
| require 'src.fs' () | ||||
| require 'src.async' | ||||
| draw = require 'src.draw' | ||||
| 
 | ||||
| local w, h | ||||
| local w, h, f | ||||
| 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' | ||||
|   f = love.graphics.setNewFont('src/hack.ttf', math.min(w, h) / 32) | ||||
|   local cw, ch = f:getWidth 'A', f:getHeight 'A' | ||||
|   collectgarbage 'collect' | ||||
|   con:emit('res', w, h, cw, ch) | ||||
|   con.resz(w, h, cw, ch) | ||||
| end | ||||
| love.resize(love.graphics.getDimensions()) | ||||
| love.window.setMode(w, h, { | ||||
|  | @ -27,23 +26,25 @@ love.window.setMode(w, h, { | |||
| love.textinput  = con.type | ||||
| love.keypressed = con.keydown | ||||
| 
 | ||||
| local sf = (love.getVersion() or love._version_major) | ||||
|   == 0 and 1 or 255 | ||||
| 
 | ||||
| function love.draw() | ||||
|   draw:color(100, 255, 0) | ||||
|   love.graphics.setColor(100 / sf, 255 / sf, 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) | ||||
|     then love.graphics.print(l, x * con.cw, y * con.ch + con.oy) | ||||
|     end | ||||
|   end) | ||||
| end | ||||
| 
 | ||||
| function loadapp(name, ...) | ||||
|   local succ, msg = pcall(require, 'sysapps.'.. name) | ||||
|   local succ, msg = pcall(require, 'A.'.. name) | ||||
|   if not succ then | ||||
|     con.println('ERROR: '.. msg) | ||||
|     print(msg) | ||||
|  |  | |||
|  | @ -1,51 +0,0 @@ | |||
| --[[ Events library | ||||
|   -- (c) Er2 2021 <er2@dismail.de> | ||||
|   -- 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 | ||||
|  | @ -1,43 +1,31 @@ | |||
| return function(con) | ||||
| 
 | ||||
| -- KostylLand | ||||
| --- Special for (almost) terminal | ||||
| --- (c) Er2 2022 <er2@dismail.de> | ||||
| 
 | ||||
| local function updK() | ||||
|   __run(true) | ||||
| end | ||||
| 
 | ||||
| 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 | ||||
|   while ch == nil and ACTIVE do | ||||
|     updK() | ||||
|     ch = con.popbuf(false) | ||||
|     if tout and os.time() - t >= tout | ||||
|     then break end | ||||
|   end | ||||
|   return ch or '' | ||||
| end | ||||
| 
 | ||||
| function con.getln() | ||||
|   local ln, du = '', true | ||||
|   local function _ln(text) | ||||
|     ln = ln .. text | ||||
|   local ln | ||||
|   while ln == nil and ACTIVE do | ||||
|     updK() | ||||
|     ln = con.popbuf(true) | ||||
|   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 | ||||
|   return ln or '' | ||||
| end | ||||
| 
 | ||||
| end | ||||
|  |  | |||
|  | @ -2,15 +2,13 @@ utf8 = require 'utf8' | |||
| 
 | ||||
| -- Model | ||||
| local con = { | ||||
|   text = {''}, | ||||
|   out = {''}, | ||||
|   w = 0, h = 0, | ||||
|   cw = 0, ch = 0, | ||||
|   oy = 0, th = 0, | ||||
|   usebs = true, | ||||
| } | ||||
| 
 | ||||
| local m = { | ||||
|   'events', -- REQUIRED! | ||||
|   'loop', | ||||
|   'resize', 'type', 'get', | ||||
| } | ||||
|  | @ -19,6 +17,4 @@ for _, v in pairs(m) do | |||
|   require('src.term.'.. v)(con) | ||||
| end | ||||
| 
 | ||||
| con:emit('init') | ||||
| 
 | ||||
| return con | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ return function(con) | |||
| 
 | ||||
| function con.forLine(l, fn, oy) | ||||
|   local x, y = 0, 0 | ||||
|   for j, l in utf8.codes(con.text[l]) do | ||||
|   for j, l in utf8.codes(con.out[l]) do | ||||
|     l = utf8.char(l) | ||||
|     if fn then fn(l, x, y + oy) end | ||||
|     if l == '\t' then x = x + 8 - (x % 8) | ||||
|  | @ -10,15 +10,13 @@ function con.forLine(l, fn, oy) | |||
|     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 | ||||
|   for i = 1, #con.out do | ||||
|     y = y + 1 + con.forLine(i, fn, y) | ||||
|   end | ||||
|   return y | ||||
|  |  | |||
|  | @ -1,17 +1,19 @@ | |||
| return function(con) | ||||
| 
 | ||||
| con:on('res', function(w, h, cw, ch) | ||||
|   con.cw, con.ch = cw or con.cw, ch or con.ch | ||||
| function con.resz(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.reszT() | ||||
| end | ||||
| 
 | ||||
| con:on('resT', function() | ||||
| function con.reszT() | ||||
|   local y = con.forText() | ||||
|   con.th = y * con.ch | ||||
| end) | ||||
| end | ||||
| 
 | ||||
| function con.down() | ||||
|   con.oy = 0 | ||||
|  |  | |||
|  | @ -1,28 +1,59 @@ | |||
| return function(con) | ||||
| 
 | ||||
| function con.curln(of) | ||||
|   return con.text[#con.text - (of or 0)] | ||||
| end | ||||
| local buf = {''} | ||||
| 
 | ||||
| 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) | ||||
| function con.keydown(k) | ||||
|   if k == 'backspace' then | ||||
|     if #buf[#buf] > 0 then con.bs() end | ||||
|   elseif k == 'return' then | ||||
|     con.type '\n' | ||||
|     table.insert(buf, '') | ||||
|   end | ||||
|   if not oth then con.setln(s) end | ||||
|   return s | ||||
| end | ||||
| 
 | ||||
| function con.popbuf(line) | ||||
|   local v = buf[#buf-1] or '' | ||||
|   if line then | ||||
|     if v:sub(-1) == '\n' then | ||||
|       buf[#buf-1] = '' | ||||
|       return v:sub(1, -2) | ||||
|     end | ||||
|   else | ||||
|     buf[#buf] = bs(buf[#buf]) | ||||
|     v = v:sub(1,1) | ||||
|   end | ||||
|   return nil | ||||
| end | ||||
| 
 | ||||
| function con.type(text) | ||||
|   buf[#buf] = buf[#buf].. text | ||||
|   con.print(text) | ||||
| end | ||||
| 
 | ||||
| local function bs(v) | ||||
|   local off = utf8.offset(v, -1) | ||||
|   if off then v = v:sub(1, off - 1) end | ||||
|   return v, off ~= nil | ||||
| end | ||||
| 
 | ||||
| function con.bs() | ||||
|   buf[#buf] = bs(buf[#buf]) | ||||
|   con.out[#con.out] = bs(con.out[#con.out]) | ||||
| end | ||||
| 
 | ||||
| function con.cls() | ||||
|   buf = {''} | ||||
|   con.text = {''} | ||||
|   con.oy = 0 | ||||
|   con.reszT() | ||||
| end | ||||
| 
 | ||||
| function con.ret() | ||||
|   table.insert(con.out, '') | ||||
| end | ||||
| 
 | ||||
| local function conc(a, b) | ||||
|   return tostring(a)..tostring(b) | ||||
| end | ||||
| 
 | ||||
| function con.print(text) | ||||
|  | @ -30,38 +61,15 @@ function con.print(text) | |||
|     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) | ||||
|     -- \r\t\v is in loop.lua | ||||
|     else con.out[#con.out] = conc(con.out[#con.out],v) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| function con.puts(text) | ||||
|   con.setln(con.curln().. text) | ||||
|   con:emit('resT') | ||||
|   con.reszT() | ||||
| 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 | ||||
|   con.print(conc(text,'\n')) | ||||
| end | ||||
| 
 | ||||
| end | ||||
|  |  | |||
							
								
								
									
										54
									
								
								src/win.lua
									
										
									
									
									
								
							
							
						
						
									
										54
									
								
								src/win.lua
									
										
									
									
									
								
							|  | @ -1,54 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,35 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,3 +0,0 @@ | |||
| return function(argv, con) | ||||
|   con.cls() | ||||
| end | ||||
|  | @ -1,31 +0,0 @@ | |||
| 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 '<DIR>' | ||||
|     elseif i.type == 'symlink' then con.print '<SYM>' | ||||
|     elseif i.type == 'other'   then con.print '<OTH>' | ||||
|     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 | ||||
|  | @ -1,3 +0,0 @@ | |||
| return function(argv, con) | ||||
|   con.println(table.concat(argv, ' ', 2)) | ||||
| end | ||||
|  | @ -1,65 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,7 +0,0 @@ | |||
| return function(argv, con) | ||||
|   local pr = print | ||||
|   print = con.println | ||||
|   local suc, ret = pcall(load(table.concat(argv, ' ', 2))) | ||||
|   print(ret) | ||||
|   print = pr | ||||
| end | ||||
|  | @ -1,5 +0,0 @@ | |||
| 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 | ||||
|  | @ -1,3 +0,0 @@ | |||
| return function(argv, con) | ||||
|   require 'src.win' (con.w * con.cw, con.h * con.ch) | ||||
| end | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue