From c1b4ef26447b43e19d10d98b7a25e7c66c3c8ae7 Mon Sep 17 00:00:00 2001 From: Astronand Date: Sun, 4 Oct 2026 19:45:35 -0400 Subject: [PATCH] GFX update :D --- .vscode/settings.json | 4 +- .../authors.txt | 0 .../data/lib/modules/ccpc/26_gfx.kmod | 318 +++ .../description.txt | 0 .../version.txt | 0 .../data/boot/ac/boot.lua | 124 +- Src/Hyperion-firmware-ac/data/boot/ac/eeprom | 206 +- .../data/boot/ccpc/boot.lua | 387 ---- .../data/boot/ccpc/eeprom | 119 - .../data/boot/ccpc/initdisks | 272 --- .../data/lib/modules/ccpc/25_gfx.kmod | 6 - .../data/boot/cct/boot.lua | 12 +- .../data/boot/cct/initdisks | 2 +- .../data/lib/modules/cc-tweaked/25_mouse.kmod | 25 + .../data/lib/modules/cc-tweaked/25_tty.kmod | 45 +- .../lib/modules/cc-tweaked/30_daemon.kmod | 12 + .../lib/modules/cc-tweaked/46_scheduler.kmod | 12 +- .../data/boot/oc/boot.lua | 1 + .../modules/opencomputers/36_scheduler.kmod | 5 +- Src/Hyperion-kernel/data/boot/kernel.lua | 13 +- .../data/lib/modules/hyperion/01_stdlib.kmod | 27 +- .../data/lib/modules/hyperion/10_vfs.kmod | 23 + .../data/lib/modules/hyperion/11_ld.kmod | 10 +- .../data/lib/modules/hyperion/12_runfs.kmod | 3 + .../data/lib/modules/hyperion/12_sysfs.kmod | 82 + .../data/lib/modules/hyperion/20_signals.kmod | 2 +- .../lib/modules/hyperion/21_unixsockets.kmod | 2 + .../lib/modules/hyperion/30_userspace.kmod | 4 +- .../data/lib/modules/hyperion/30_vterm.kmod | 26 +- .../lib/modules/hyperion/45_hypervisor.kmod | 19 +- .../data/lib/modules/hyperion/48_dbg.kmod | 6 +- .../data/lib/modules/hyperion/90_init.kmod | 4 +- .../data/lib/modules/hyperion/90_kgc.kmod | 10 +- .../data/lib/modules/hyperion/92_setup.kmod | 18 +- Src/coreutils/data/bin/su | 2 +- Src/{gfx => fonts}/authors.txt | 0 Src/{gfx => fonts}/data/lib/psf | 0 .../data/usr/local/share/fonts/default8x9.psf | Bin Src/fonts/dependencies.txt | 1 + Src/{gfx => fonts}/description.txt | 0 Src/fonts/docs/gfx.sig | 19 + Src/fonts/docs/gfxccimpl.lua | 0 Src/{gfx => fonts}/palette | 0 Src/fonts/test/bin/testgfx | 0 Src/{gfx => fonts}/version.txt | 0 Src/gfx/data/lib/gfx | 40 - Src/gfx/test/usr/local/gfxterm/tests/uv.lsl | 350 --- Src/hysh/data/bin/hysh | 13 +- Src/lua/data/bin/lua | 10 +- Src/math/authors.txt | 2 + Src/math/data/lib/matrix | 217 ++ Src/math/data/lib/vector | 217 ++ Src/math/description.txt | 3 + Src/math/version.txt | 1 + Src/render3d/data/bin/render3d | 124 ++ Src/render3d/data/usr/local/models/box.obj | 40 + Src/scomposite/data/lib/gfx | 4 + Test/HyperionOS-units/bin/hunit | 23 - Test/HyperionOS-units/bin/looptest | 427 ---- Test/HyperionOS-units/bin/socktest | 151 -- Test/HyperionOS-units/usr/lib/hunit/dir.unit | 3 - Test/HyperionOS-units/usr/lib/hunit/file.unit | 10 - build.py | 7 +- docs/README.md | 4 + docs/kernel/Syscalls/README.md | 1 + docs/kernel/boot.cfg.md | 9 + manifest.lua | 679 +----- misc/json | 388 ---- misc/spm.lua | 55 - misc/xz | 1973 ----------------- 70 files changed, 1398 insertions(+), 5174 deletions(-) rename Src/{Hyperion-firmware-ccpc => Hyperion-addon-ccpc-gfx}/authors.txt (100%) create mode 100644 Src/Hyperion-addon-ccpc-gfx/data/lib/modules/ccpc/26_gfx.kmod rename Src/{Hyperion-firmware-ccpc => Hyperion-addon-ccpc-gfx}/description.txt (100%) rename Src/{Hyperion-firmware-ccpc => Hyperion-addon-ccpc-gfx}/version.txt (100%) delete mode 100644 Src/Hyperion-firmware-ccpc/data/boot/ccpc/boot.lua delete mode 100644 Src/Hyperion-firmware-ccpc/data/boot/ccpc/eeprom delete mode 100644 Src/Hyperion-firmware-ccpc/data/boot/ccpc/initdisks delete mode 100644 Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod create mode 100644 Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_mouse.kmod create mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/12_runfs.kmod create mode 100644 Src/Hyperion-kernel/data/lib/modules/hyperion/12_sysfs.kmod rename Src/{gfx => fonts}/authors.txt (100%) rename Src/{gfx => fonts}/data/lib/psf (100%) rename Src/{gfx => fonts}/data/usr/local/share/fonts/default8x9.psf (100%) create mode 100644 Src/fonts/dependencies.txt rename Src/{gfx => fonts}/description.txt (100%) create mode 100644 Src/fonts/docs/gfx.sig create mode 100644 Src/fonts/docs/gfxccimpl.lua rename Src/{gfx => fonts}/palette (100%) create mode 100644 Src/fonts/test/bin/testgfx rename Src/{gfx => fonts}/version.txt (100%) delete mode 100644 Src/gfx/data/lib/gfx delete mode 100644 Src/gfx/test/usr/local/gfxterm/tests/uv.lsl create mode 100644 Src/math/authors.txt create mode 100644 Src/math/data/lib/matrix create mode 100644 Src/math/data/lib/vector create mode 100644 Src/math/description.txt create mode 100644 Src/math/version.txt create mode 100644 Src/render3d/data/bin/render3d create mode 100644 Src/render3d/data/usr/local/models/box.obj create mode 100644 Src/scomposite/data/lib/gfx delete mode 100644 Test/HyperionOS-units/bin/hunit delete mode 100644 Test/HyperionOS-units/bin/looptest delete mode 100644 Test/HyperionOS-units/bin/socktest delete mode 100644 Test/HyperionOS-units/usr/lib/hunit/dir.unit delete mode 100644 Test/HyperionOS-units/usr/lib/hunit/file.unit create mode 100644 docs/README.md delete mode 100644 misc/json delete mode 100644 misc/spm.lua delete mode 100644 misc/xz diff --git a/.vscode/settings.json b/.vscode/settings.json index 710e125..d0c891f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,10 +6,10 @@ "printf", "printInline", "toHex", - "loadcstr", "userinput" ], "Lua.diagnostics.disable": [ - "need-check-nil" + "need-check-nil", + "param-type-mismatch" ] } \ No newline at end of file diff --git a/Src/Hyperion-firmware-ccpc/authors.txt b/Src/Hyperion-addon-ccpc-gfx/authors.txt similarity index 100% rename from Src/Hyperion-firmware-ccpc/authors.txt rename to Src/Hyperion-addon-ccpc-gfx/authors.txt diff --git a/Src/Hyperion-addon-ccpc-gfx/data/lib/modules/ccpc/26_gfx.kmod b/Src/Hyperion-addon-ccpc-gfx/data/lib/modules/ccpc/26_gfx.kmod new file mode 100644 index 0000000..7969b9f --- /dev/null +++ b/Src/Hyperion-addon-ccpc-gfx/data/lib/modules/ccpc/26_gfx.kmod @@ -0,0 +1,318 @@ +--:Minify:-- +local kernel=... +if not kernel.cct then return end + +local plt={ + [0]=0x000000,0x0b0b0b,0x222222,0x444444,0x555555,0x777777,0x888888,0xaaaaaa, + 0xbbbbbb,0xdddddd,0xeeeeee,0x00000b,0x000022,0x000044,0x000055,0x000077, + 0x000088,0x0000aa,0x0000bb,0x0000dd,0x0000ee,0x000b00,0x002200,0x004400, + 0x005500,0x007700,0x008800,0x00aa00,0x00bb00,0x00dd00,0x00ee00,0x0b0000, + 0x220000,0x440000,0x550000,0x770000,0x880000,0xaa0000,0xbb0000,0xdd0000, + 0xee0000,0x000033,0x000066,0x000099,0x0000cc,0x0000ff,0x003300,0x003333, + 0x003366,0x003399,0x0033cc,0x0033ff,0x006600,0x006633,0x006666,0x006699, + 0x0066cc,0x0066ff,0x009900,0x009933,0x009966,0x009999,0x0099cc,0x0099ff, + 0x00cc00,0x00cc33,0x00cc66,0x00cc99,0x00cccc,0x00ccff,0x00ff00,0x00ff33, + 0x00ff66,0x00ff99,0x00ffcc,0x00ffff,0x330000,0x330033,0x330066,0x330099, + 0x3300cc,0x3300ff,0x333300,0x333333,0x333366,0x333399,0x3333cc,0x3333ff, + 0x336600,0x336633,0x336666,0x336699,0x3366cc,0x3366ff,0x339900,0x339933, + 0x339966,0x339999,0x3399cc,0x3399ff,0x33cc00,0x33cc33,0x33cc66,0x33cc99, + 0x33cccc,0x33ccff,0x33ff00,0x33ff33,0x33ff66,0x33ff99,0x33ffcc,0x33ffff, + 0x660000,0x660033,0x660066,0x660099,0x6600cc,0x6600ff,0x663300,0x663333, + 0x663366,0x663399,0x6633cc,0x6633ff,0x666600,0x666633,0x666666,0x666699, + 0x6666cc,0x6666ff,0x669900,0x669933,0x669966,0x669999,0x6699cc,0x6699ff, + 0x66cc00,0x66cc33,0x66cc66,0x66cc99,0x66cccc,0x66ccff,0x66ff00,0x66ff33, + 0x66ff66,0x66ff99,0x66ffcc,0x66ffff,0x990000,0x990033,0x990066,0x990099, + 0x9900cc,0x9900ff,0x993300,0x993333,0x993366,0x993399,0x9933cc,0x9933ff, + 0x996600,0x996633,0x996666,0x996699,0x9966cc,0x9966ff,0x999900,0x999933, + 0x999966,0x999999,0x9999cc,0x9999ff,0x99cc00,0x99cc33,0x99cc66,0x99cc99, + 0x99cccc,0x99ccff,0x99ff00,0x99ff33,0x99ff66,0x99ff99,0x99ffcc,0x99ffff, + 0xcc0000,0xcc0033,0xcc0066,0xcc0099,0xcc00cc,0xcc00ff,0xcc3300,0xcc3333, + 0xcc3366,0xcc3399,0xcc33cc,0xcc33ff,0xcc6600,0xcc6633,0xcc6666,0xcc6699, + 0xcc66cc,0xcc66ff,0xcc9900,0xcc9933,0xcc9966,0xcc9999,0xcc99cc,0xcc99ff, + 0xcccc00,0xcccc33,0xcccc66,0xcccc99,0xcccccc,0xccccff,0xccff00,0xccff33, + 0xccff66,0xccff99,0xccffcc,0xccffff,0xff0000,0xff0033,0xff0066,0xff0099, + 0xff00cc,0xff00ff,0xff3300,0xff3333,0xff3366,0xff3399,0xff33cc,0xff33ff, + 0xff6600,0xff6633,0xff6666,0xff6699,0xff66cc,0xff66ff,0xff9900,0xff9933, + 0xff9966,0xff9999,0xff99cc,0xff99ff,0xffcc00,0xffcc33,0xffcc66,0xffcc99, + 0xffcccc,0xffccff,0xffff00,0xffff33,0xffff66,0xffff99,0xffffcc,0xffffff, +} + +local iplt={} +for i=0, #plt do + iplt[plt[i]]=i +end +local l1f,l1d,l2,ops={},{},{},0 + +local function findClosest(tbl, target) + local closest = nil + local smallestDiff = math.huge + + for k, _ in pairs(tbl) do + if k==target then return k end + local diff = math.abs(k - target) + if diff < smallestDiff then + smallestDiff = diff + closest = k + end + end + + return closest +end + +local function aprox(c24) + ops = ops + 1 + + if ops % 1024 == 0 then + l1d = {} + l1f = {} + end + + if ops % 8192 == 0 then + l2 = {} + end + + if l2[c24] ~= nil then + return l2[c24] + end + + if l1d[c24] ~= nil then + l1f[c24] = l1f[c24] + 1 + + if l1f[c24] >= 16 then + l2[c24] = l1d[c24] + l1d[c24] = nil + l1f[c24] = nil + return l2[c24] + end + + return l1d[c24] + end + + local closestKey = findClosest(iplt, c24) + if not closestKey then return nil end + + local value = iplt[closestKey] + + l1d[c24] = value + l1f[c24] = 1 + + return value +end + +local function splitFramebufferToStrings(fb, w) + local rows = {} + + for i = 1, #fb, w do + local row_chars = {} + for j = 0, w - 1 do + local val = fb[i + j] + if val ~= nil then + table.insert(row_chars, string.char(aprox(val))) + else + break + end + end + table.insert(rows, table.concat(row_chars)) + end + + return rows +end + +local function creategfx(term, id) + local active=false + term.setGraphicsMode(2) + for i=0, #plt do + term.setPaletteColor(i,plt[i]) + end + term.setGraphicsMode(false) + term.setPaletteColor(0x1, 0xFFFFFF) + term.setPaletteColor(0x2, 0xFF0000) + term.setPaletteColor(0x4, 0x00FF00) + term.setPaletteColor(0x8, 0x0000FF) + term.setPaletteColor(0x10, 0x00FFFF) + term.setPaletteColor(0x20, 0xFF00FF) + term.setPaletteColor(0x40, 0xFFFF00) + term.setPaletteColor(0x80, 0xFF6D00) + term.setPaletteColor(0x100, 0x6DFF55) + term.setPaletteColor(0x200, 0x24FFFF) + term.setPaletteColor(0x400, 0x924900) + term.setPaletteColor(0x800, 0x6D6D55) + term.setPaletteColor(0x1000, 0xDBDBAA) + term.setPaletteColor(0x2000, 0x6D00FF) + term.setPaletteColor(0x4000, 0xB6FF00) + term.setPaletteColor(0x8000, 0x000000) + local handle={ + gplt=function() + return setmetatable({},{__index=plt,__usermeta=false,__pairs=function() return pairs(plt) end}) + end, + spixel=function(x,y,c) + term.setPixel(x,y,aprox(c)) + end, + gpixel=function(x,y) + return term.getPixel() + end, + drawFB=function(x,y,fb,w) + local f=splitFramebufferToStrings(fb,w) + term.drawPixels(x,y,f) + end, + box=function(x,y,w,h,c,fill) + c=aprox(c) + if not fill then + term.drawPixels(x,y,c,w,1) + term.drawPixels(x,y,c,1,h) + term.drawPixels(x+w-1,y,c,1,h) + term.drawPixels(x,y+h-1,c,w,1) + else + term.drawPixels(x,y,c,w,h) + end + end, + circle=function(xc,yc,r,c,fill) + c=aprox(c) + if not fill then + local x = 0 + local y = r + local d = 3 - 2 * r + + -- Helper function to plot all 8 symmetric points + local function plot8Points(x, y) + term.setPixel(xc + x, yc + y, c) + term.setPixel(xc - x, yc + y, c) + term.setPixel(xc + x, yc - y, c) + term.setPixel(xc - x, yc - y, c) + term.setPixel(xc + y, yc + x, c) + term.setPixel(xc - y, yc + x, c) + term.setPixel(xc + y, yc - x, c) + term.setPixel(xc - y, yc - x, c) + end + + plot8Points(x, y) + + while y >= x do + x = x + 1 + if d > 0 then + y = y - 1 + d = d + 4 * (x - y) + 10 + else + d = d + 4 * x + 6 + end + plot8Points(x, y) + end + else + local x = 0 + local y = r + local d = 3 - 2 * r + + -- Helper to fill rows using symmetry + local function fillRows(x, y) + -- Width is (2 * coordinate) + 1 to include the center column + local strX = string.rep(string.char(c), 2 * x + 1) + local strY = string.rep(string.char(c), 2 * y + 1) + -- Draw the horizontal spans + term.drawPixels(xc - x, yc + y, {strX}) + term.drawPixels(xc - x, yc - y, {strX}) + term.drawPixels(xc - y, yc + x, {strY}) + term.drawPixels(xc - y, yc - x, {strY}) + end + + fillRows(x, y) + + while y >= x do + x = x + 1 + if d > 0 then + y = y - 1 + d = d + 4 * (x - y) + 10 + else + d = d + 4 * x + 6 + end + fillRows(x, y) + end + end + end, + line=function(x1,y1,x2,y2,c) + x1=math.floor(x1+0.5) + y1=math.floor(y1+0.5) + x2=math.floor(x2+0.5) + y2=math.floor(y2+0.5) + + c=aprox(c) + + local w,h=term.getSize(2) + + local dx=math.abs(x2-x1) + local dy=math.abs(y2-y1) + + local sx=x1-dy then + err=err-dy + x1=x1+sx + end + + if e21 then scr.cx=scr.cx-1;gpu.set(scr.cx,scr.cy," ") end - else gpu.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end - if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end - if scr.cy>scr.h then scroll(scr);scr.cy=scr.cy-1 end - end - end -end -local function throw(err) - if gpu then - gpu.setBackground(0x0000AA); - gpu.setForeground(0xFFFFFF); - for i=1, #screens do - gpu.fill(1,1,screens[i].w,screens[i].h," "); - screens[i].cx,screens[i].cy=1,1; - end - write("CRITICAL KERNEL ERROR:\n"..tostring(err)) - end - while true do c.pullSignal() end -end -local ok,err=xpcall(function() - local apis={} - local _l={coroutine=1,debug=1,_VERSION=1,assert=1,collectgarbage=1,error=1,getmetatable=1,ipairs=1,load=1,math=1,next=1,pairs=1,pcall=1,rawequal=1,rawget=1,rawlen=1,rawset=1,select=1,setmetatable=1,string=1,table=1,tonumber=1,tostring=1,type=1,xpcall=1,_G=1} - for k,v in pairs(_G) do if not _l[k] then apis[k]=v;_G[k]=nil end end - function sleep(t) local s=c.uptime()+t;while c.uptime() 0 then - return table.unpack(table.remove(eQ, 1)) - else - return nil - end - end, - getEEPROM=function() return e_rom and e_rom.get() or "" end, - setEEPROM=function(_,t) if e_rom then e_rom.set(t) end end, - getNvram=function() return e_rom and e_rom.getData() or "" end, - setNvram=function(_,t) if e_rom then e_rom.setData(t) end end, - beep=function(freq, timeMs) c.beep(freq, timeMs / 1000) end, - initfs=fs, - disks=initFs, - architecture="oc", - firmware=apis, - reboot=false, - yield=function() coroutine.yield() end, - screenCtl={ - print=function(_,t) write(tostring(t).."\n") end, - printInline=function(_,t) write(tostring(t)) end, - clear=function() if gpu then for i=1, #screens do local scr=screens[i];gpu.bind(scr.addr);gpu.fill(1,1,scr.w,scr.h," ");scr.cx,scr.cy=1,1 end end end, - resetCursor=function() for i=1, #screens do local scr=screens[i];scr.cx,scr.cy=1,1 end end, - setBackgroundColor=function(_,cl) if gpu then gpu.setBackground(cl) end end, - setTextColor=function(_,cl) if gpu then gpu.setForeground(cl) end end, - enable=function() end, - disable=function() end - } - } - local kCo=coroutine.create(function() - local s,e=xpcall(Kernel,debug.traceback,efi) - if not s and not efi.reboot then throw(e) end - if efi.reboot then c.shutdown(true) else c.shutdown() end - end) - efi.screenCtl:print("Loaded in "..tostring(c.uptime()).."s") - while true do - local st,e=coroutine.resume(kCo) - c.pushSignal("NoSleep") - local ex=false - while not ex do - local ev={c.pullSignal(0)} - if ev[1]=="key_down" then qEv("keyPressed",1,ev[3]);qEv("keyTyped",1,string.char(ev[3])) - elseif ev[1]=="key_up" then qEv("keyReleased",1,ev[3]) - end - if ev[1]=="NoSleep" then ex=true else qEv(table.unpack(ev)) end - end - if st=="error" or coroutine.status(kCo)=="dead" then - if efi.reboot then c.shutdown(true) end - throw("Kernel fault: "..tostring(e)) - end - end -end,debug.traceback) -if not ok then throw("Boot fault: "..err) end \ No newline at end of file +---@diagnostic disable-next-line: undefined-global +local bootdrive=__UEFI.bootDrive + diff --git a/Src/Hyperion-firmware-ac/data/boot/ac/eeprom b/Src/Hyperion-firmware-ac/data/boot/ac/eeprom index 3ff38a9..6763594 100644 --- a/Src/Hyperion-firmware-ac/data/boot/ac/eeprom +++ b/Src/Hyperion-firmware-ac/data/boot/ac/eeprom @@ -1,68 +1,146 @@ -local init -do - local component_invoke = component.invoke - local function boot_invoke(address, method, ...) - local result = table.pack(pcall(component_invoke, address, method, ...)) - if not result[1] then - return nil, result[2] - else - return table.unpack(result, 2, result.n) +local comp,disks,autocomplete,ev,ent,data,path,exit,dirty,ls,eb,sb,bp=components,{},false,nil,true,"","",false,true,{},false +local c,gpu=comp:getFirst("computer"),comp:getFirst("gpu") +if gpu then sb=gpu:newBuffer(48,32) end +--c.nvram.data="1/ac/boot.lua" +local function resetScreens() + sb=gpu:newBuffer(64,48) + for typ, obj in comp:list() do + if typ=="screen" then gpu:assignBuffer(sb,obj) end end - end - - -- backwards compatibility, may remove later - local eeprom = component.list("eeprom")() - computer.getBootAddress = function() - return boot_invoke(eeprom, "getData") - end - computer.setBootAddress = function(address) - return boot_invoke(eeprom, "setData", address) - end - - do - local screen = component.list("screen")() - local gpu = component.list("gpu")() - if gpu and screen then - boot_invoke(gpu, "bind", screen) - end - end - local function tryLoadFrom(address) - local handle, reason = boot_invoke(address, "open", "/oc/boot.lua") - if not handle then - return nil, reason - end - local buffer = "" - repeat - local data, reason = boot_invoke(address, "read", handle, math.maxinteger or math.huge) - if not data and reason then - return nil, reason - end - buffer = buffer .. (data or "") - until not data - boot_invoke(address, "close", handle) - return load(buffer, "=init") - end - local reason - if computer.getBootAddress() then - init, reason = tryLoadFrom(computer.getBootAddress()) - end - if not init then - computer.setBootAddress() - for address in component.list("filesystem") do - init, reason = tryLoadFrom(address) - if init then - computer.setBootAddress(address) - break - end - end - end - if not init then - error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0) - end end -local ok, err = xpcall(init,debug.traceback) -if not ok then - error(err) +resetScreens() + +local function displayError(err) + if not gpu then return end + gpu:freeAllBuffers() + resetScreens() + sb:pasteText(0,0,"FILL_SPILL",err) +end + +local function bootloader() +for typ, obj in comp:list() do + if typ~="massStorage" then goto skip end + disks[tostring(obj.diskId)]=obj + ::skip:: +end + +local function display(text) + print(text) + if not sb then print("NO_SB") return end + sb:pasteText(0,0,"FILL_SPILL",text) +end + +local function boot() + local pos = path:find("/", 1, true) + if not pos then displayError("EINVAL") sleep(5) return end + local id,p = path:sub(1,pos-1),path:sub(pos) + if not disks[id] then displayError("ENODEV") sleep(5) return end + local init,err=load(disks[id]:open(p):read(-1),"@init","t",_G) + if err then displayError(err) sleep(5) return end + local ret = {xpcall(init, debug.traceback)} + if not ret[1] then + displayError("EFI PROGRAM ERROR: "..err) + sleep(5) + return false + else + if ret[2]=="ENTER_BIOS" then + c.nvram.ENTER_BIOS=true + return true + end + return table.unpack(ret, 2) + end +end + +if c.nvram then + path=c.nvram.data or "" + eb=c.nvram.ENTER_BIOS + c.nvram.ENTER_BIOS=false +end + +local function drainev() + repeat + ev={c:getMachineEvent()} + if ev[1]=="charTyped" then ent=false end + until not ev[1] +end + +if path=="" or eb then drainev() ent=false else + display("Press key to enter boot menu...") + sleep(3) + drainev() + if ent then return boot() end +end + +local function proc(key) + if key=="\n" then exit=true + elseif key=="\b" then path=path:sub(1,#path-1) dirty=true + elseif key=="\t" then print("autocomplete") + else path=path..key dirty=true end +end + +local function get() + data="" + local pos = path:find("/", 1, true) + local trailingslash=false + if path:sub(#path)=="/" then trailingslash=true end + if not pos then + for id in pairs(disks) do + if id:sub(1,#path)==path then + data=data..id.."\n" + end + end + else + if not trailingslash then + local n="" + for i=#path, 0, -1 do + if path:sub(i,i)~="/" then + n=path:sub(i,i)..n + else break end + end + local ok,ret=pcall(function() + return disks[path:sub(1,pos-1)]:list(path:sub(pos,#path-#n)) + end) + if ok then + ls = ret + end + for _,p in ipairs(ls) do + if p:sub(1,#n) == n then + data=data..p.."\n" + end + end + else + local ok,ret=pcall(function() + return disks[path:sub(1,pos-1)]:list(path:sub(pos)) + end) + + if ok then + ls=ret + for _,p in ipairs(ls) do + data=data..p.."\n" + end + end + end + end +end + +if not ent then + while true do + get() + if dirty then + for i=0,31 do sb:clearRow(i) end + display("Select boot file...\n"..path.."\n\n"..data) + dirty=false + end + ev={c:getMachineEvent()} + if ev[1]=="charTyped" then proc(ev[2]) end + if exit then return boot() end + end +end +end +local ret={xpcall(bootloader,debug.traceback)} +if not ret[1] then + displayError(ret[2]) + error(ret[2]) else - return err + return table.unpack(ret, 2) end \ No newline at end of file diff --git a/Src/Hyperion-firmware-ccpc/data/boot/ccpc/boot.lua b/Src/Hyperion-firmware-ccpc/data/boot/ccpc/boot.lua deleted file mode 100644 index 1385e44..0000000 --- a/Src/Hyperion-firmware-ccpc/data/boot/ccpc/boot.lua +++ /dev/null @@ -1,387 +0,0 @@ ---:Minify:-- -local BOOT_DRIVE_PATH = ({...})[1] or "/$" ----@diagnostic disable-next-line: undefined-global -local term = term -local os = os -local function write(text) - local x, y = term.getCursorPos() - local w, h = term.getSize() - - for i = 1, #text do - local c = text:sub(i, i) - - if c == "\n" then - y = y + 1 - x = 1 - elseif c == "\t" then - local tabSize = 4 - local spaces = tabSize - ((x - 1) % tabSize) - term.write(string.rep(" ", spaces)) - x = x + spaces - elseif c == "\b" then - if x > 1 then - x = x - 1 - term.setCursorPos(x, y) - term.write(" ") - term.setCursorPos(x, y) - end - else - if x <= w and y <= h then - term.setCursorPos(x, y) - term.write(c) - x = x + 1 - end - end - - if x > w then - x = 1 - y = y + 1 - end - - if y - 1 >= h then - term.scroll(1) - y = h - term.setCursorPos(x, y) - end - end - - term.setCursorPos(x, y) -end - -local function displaySuperBadError(err) - term.setBackgroundColor(0x1) - term.setTextColor(0x4) - term.clear() - term.setCursorPos(1, 1) - term.write("A critical error occurred while loading the system:") - term.setCursorPos(1, 3) - write(err) - while true do end -end - -term.setCursorBlink(false) -local ok, err = xpcall(function() - local apis = {BOOT_DRIVE_PATH = BOOT_DRIVE_PATH} - - local lua = { - coroutine = true, - debug = true, - _VERSION = true, - assert = true, - collectgarbage = true, - error = true, - gcinfo = true, - getmetatable = true, - ipairs = true, - __inext = true, - load = true, - math = true, - next = true, - pairs = true, - pcall = true, - rawequal = true, - rawget = true, - rawlen = true, - rawset = true, - select = true, - setmetatable = true, - string = true, - table = true, - tonumber = true, - tostring = true, - type = true, - xpcall = true, - _G = true - } - - local debug = debug - for i, v in pairs(_G) do - if not lua[i] or lua[i] == nil then - apis[i] = v - _G[i] = nil - end - end - - local acekeys={ - [apis.keys.enter]="\n", - [apis.keys.tab]="\t", - [apis.keys.backspace]="\b", - [apis.keys.up]="\17", - [apis.keys.down]="\18", - [apis.keys.left]="\19", - [apis.keys.right]="\20", - } - - function sleep(time) - local stoptime = apis.os.clock() + (time) - while stoptime > apis.os.clock() do end - end - - apis.term.setPaletteColor(0x1, 0xFFFFFF) -- #000000 - apis.term.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF - apis.term.setPaletteColor(0x4, 0x00FF00) -- #FF0000 - apis.term.setPaletteColor(0x8, 0x0000FF) -- #00FF00 - apis.term.setPaletteColor(0x10, 0x00FFFF) -- #0000FF - apis.term.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF - apis.term.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF - apis.term.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00 - apis.term.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00 - apis.term.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55 - apis.term.setPaletteColor(0x400, 0x924900) -- #24FFFF - apis.term.setPaletteColor(0x800, 0x6D6D55) -- #924900 - apis.term.setPaletteColor(0x1000, 0xDBDBAA) -- #6D6D55 - apis.term.setPaletteColor(0x2000, 0x6D00FF) -- #DBDBAA - apis.term.setPaletteColor(0x4000, 0xB6FF00) -- #6D00FF - apis.term.setPaletteColor(0x8000, 0x000000) -- #B6FF00 - - local function getFile(path) - local file = apis.fs.open(path, "r") - if not file then - displaySuperBadError("Could not open file: " .. path) - end - local content = file.readAll() - file.close() - return content - end - - local Kernel = load(getFile(BOOT_DRIVE_PATH .. "/boot/kernel.lua"),"@Kernel") - local initFs = load(getFile(BOOT_DRIVE_PATH .. "/boot/cct/initdisks"),"@Init_disks")(apis) - local fs = load(getFile(BOOT_DRIVE_PATH .. "/boot/initfs"), "@InitFs")() - - if not Kernel then displaySuperBadError("Could not load kernel.") end - if not initFs then displaySuperBadError("Could not load initdisks.") end - if not fs then displaySuperBadError("Could not load initfs.") end - - if not apis.fs.exists("/nvram.dat") then - local file = apis.fs.open("/nvram.dat", "w") - file.write("Hello, World!") - file.close() - end - - local eeprom - if apis.fs.exists("/startup.lua") then - eeprom="/startup.lua" - elseif apis.fs.exists("/eeprom") then - eeprom="/eeprom" - end - - local eventQueue = {} - - local function queueEvent(event, ...) - table.insert(eventQueue, {event, ...}) - end - - local colors = { - [0x000000]=0x0001, - [0xFFFFFF]=0x0002, - [0xFF0000]=0x0004, - [0x00FF00]=0x0008, - [0x0000FF]=0x0010, - [0x00FFFF]=0x0020, - [0xFF00FF]=0x0040, - [0xFFFF00]=0x0080, - [0xFF6D00]=0x0100, - [0x6DFF55]=0x0200, - [0x24FFFF]=0x0400, - [0x924900]=0x0800, - [0x6D6D55]=0x1000, - [0xDBDBAA]=0x2000, - [0x6D00FF]=0x4000, - [0xB6FF00]=0x8000 - } - - local fg,bg=0x6D6D55,0x000000 - local l1f,l1d,l2,ops={},{},{},0 - - local function findClosest(tbl, target) - local closest = nil - local smallestDiff = math.huge - - for k, _ in pairs(tbl) do - local diff = math.abs(k - target) - if diff < smallestDiff then - smallestDiff = diff - closest = k - end - end - - return closest - end - - local function aprox(c24) - ops = ops + 1 - - if ops % 1024 == 0 then - l1d = {} - l1f = {} - end - - if ops % 8192 == 0 then - l2 = {} - end - - if l2[c24] ~= nil then - return l2[c24] - end - - if l1d[c24] ~= nil then - l1f[c24] = l1f[c24] + 1 - - if l1f[c24] >= 16 then - l2[c24] = l1d[c24] - l1d[c24] = nil - l1f[c24] = nil - return l2[c24] - end - - return l1d[c24] - end - - local closestKey = findClosest(colors, c24) - if not closestKey then return nil end - - local value = colors[closestKey] - - l1d[c24] = value - l1f[c24] = 1 - - return value - end - - local EFI = { - getEpochMs = function() return apis.os.epoch("utc") end, - getUptime = function() return apis.os.clock() * 1000 end, - date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end, - getMachineEvent = function() - if #eventQueue > 0 then - return table.unpack(table.remove(eventQueue, 1)) - else - return nil - end - end, - getEEPROM = function() return getFile(eeprom) end, - setEEPROM = function(_, text) - local h = apis.fs.open(eeprom, "w") - h.write(text) - h.close() - end, - initfs=fs, - disks=initFs, - screenCtl={ - print = function(_, text) write(text .. "\n") end, - printInline = function(_, text) write(text) end, - clear = function() - apis.term.clear() - apis.term.setCursorPos(1, 1) - end, - setCursorPos = function(_, x, y) - apis.term.setCursorPos(x, y) - end, - getCursorPos = function() return apis.term.getCursorPos() end, - getSize = function() return apis.term.getSize() end, - setBackgroundColor = function(_, color) - apis.term.setBackgroundColor(aprox(color)) - end, - setTextColor = function(_, color) - apis.term.setTextColor(aprox(color)) - end, - getBackgroundColor = function() - return bg - end, - getTextColor = function() - return fg - end, - enable=function() end, - disable=function() end - }, - architecture="cct", - getNvram = function() return getFile("/nvram.dat") end, - setNvram = function(_, text) - local h = apis.fs.open("/nvram.dat", "w") - h.write(text) - h.close() - end, - firmware=apis, - reboot=false - } - - apis.term.setBackgroundColor(0x8000) - apis.term.setTextColor(0x1000) - apis.term.clear() - apis.term.setCursorPos(1, 1) - - local kernelCoro = coroutine.create(function() - ---@diagnostic disable-next-line: param-type-mismatch - local ok, err = xpcall(Kernel, debug.traceback, EFI) - if not ok and not EFI.reboot then displaySuperBadError(err) end - if err then - apis.os.reboot() - else - apis.os.shutdown() - end - end) - - function EFI.resumeWithTimeout(co, timeout, ...) - local startTime = EFI.getEpochMs() - debug.sethook(co, function() - if EFI.getEpochMs() > startTime + timeout then - return coroutine.yield("timeout") - end - end, "", 1000) - local ret = {coroutine.resume(co, ...)} - if ret[1] and ret[2] == "timeout" then - return "timeout" - elseif ret[1] == false then - return "error", ret[2] - else - debug.sethook(co) - return "success", table.unpack(ret, 2) - end - end - - write("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n") - - while true do - local status, err = EFI.resumeWithTimeout(kernelCoro, 50) - apis.os.queueEvent("NoSleep") - local exit = false - while not exit do - local event = {coroutine.yield()} - if event[1] == "key" then - queueEvent("keyPressed", 1, event[2]) - if acekeys[event[2]] then - queueEvent("keyTyped", 1, acekeys[event[2]]) - end - elseif event[1] == "char" then - queueEvent("keyTyped", 1, event[2]) - elseif event[1] == "key_up" then - queueEvent("keyReleased", 1, event[2]) - elseif event[1] == "disk" then - queueEvent("componentAdded", "disk") - elseif event[1] == "disk_eject" then - queueEvent("componentRemoved", "disk") - elseif event[1] == "modem_message" then - queueEvent("modem_message", table.unpack(event, 2)) - elseif event[1] == "rednet_message" then - queueEvent("rednet_message", table.unpack(event, 2)) - elseif event[1] == "http_success" then - queueEvent("http_success", table.unpack(event, 2)) - elseif event[1] == "http_failure" then - queueEvent("http_failure", table.unpack(event, 2)) - elseif event[1] == "NoSleep" then - exit = true - end - end - if status == "error" or coroutine.status(kernelCoro) == "dead" then - if EFI.reboot then - apis.os.reboot() - end - displaySuperBadError("Kernel error: " .. tostring(err)) - coroutine.yield("key") - end - initFs:refresh() - end -end, debug.traceback) - -if not ok then displaySuperBadError("Fatal error during boot: " .. err) end -while true do coroutine.yield("key") end diff --git a/Src/Hyperion-firmware-ccpc/data/boot/ccpc/eeprom b/Src/Hyperion-firmware-ccpc/data/boot/ccpc/eeprom deleted file mode 100644 index e3bb2a4..0000000 --- a/Src/Hyperion-firmware-ccpc/data/boot/ccpc/eeprom +++ /dev/null @@ -1,119 +0,0 @@ ---:Minify:-- -local BOOT_DRIVE_PATH=({...})[1] or "/$" --- UnBIOS by JackMacWindows --- This will undo most of the changes/additions made in the BIOS, but some things may remain wrapped if `debug` is unavailable --- To use, just place a `bios.lua` in the root of the drive, and run this program --- Here's a list of things that are irreversibly changed: --- * both `bit` and `bit32` are kept for compatibility --- * string metatable blocking (on old versions of CC) --- In addition, if `debug` is not available these things are also irreversibly changed: --- * old Lua 5.1 `load` function (for loading from a function) --- * `loadstring` prefixing (before CC:T 1.96.0) --- * `http.request` --- * `os.shutdown` and `os.reboot` --- * `peripheral` --- * `turtle.equip[Left|Right]` --- Licensed under the MIT license -local args = {...} -local keptAPIs = {keys=true, bit32 = true, bit = true, ccemux = true, config = true, coroutine = true, debug = true, fs = true, http = true, mounter = true, os = true, periphemu = true, peripheral = true, redstone = true, rs = true, term = true, utf8 = true, _HOST = true, _CC_DEFAULT_SETTINGS = true, _CC_DISABLE_LUA51_FEATURES = true, _VERSION = true, assert = true, collectgarbage = true, error = true, gcinfo = true, getfenv = true, getmetatable = true, ipairs = true, __inext = true,load = true, loadstring = true, math = true, newproxy = true, next = true, pairs = true, pcall = true, rawequal = true, rawget = true, rawlen = true, rawset = true, select = true, setfenv = true, setmetatable = true, string = true, table = true, tonumber = true, tostring = true, type = true, unpack = true, xpcall = true, turtle = true, pocket = true, commands = true, _G = true} -local t = {} -for k in pairs(_G) do if not keptAPIs[k] then table.insert(t, k) end end -for _,k in ipairs(t) do _G[k] = nil end -local native = _G.term.native() -for _, method in ipairs {"nativePaletteColor", "nativePaletteColour", "screenshot"} do native[method] = _G.term[method] end -_G.term = native -if _G.http then - _G.http.checkURL = _G.http.checkURLAsync - _G.http.websocket = _G.http.websocketAsync -end -if _G.commands then _G.commands = _G.commands.native end -if _G.turtle then _G.turtle.native, _G.turtle.craft = nil end -local delete = {os = {"version", "pullEventRaw", "pullEvent", "run", "loadAPI", "unloadAPI", "sleep"}, http = _G.http and {"get", "post", "put", "delete", "patch", "options", "head", "trace", "listen", "checkURLAsync", "websocketAsync"}, fs = {"complete", "isDriveRoot"}} -for k,v in pairs(delete) do for _,a in ipairs(v) do _G[k][a] = nil end end --- Set up TLCO --- This functions by crashing `rednet.run` by removing `os.pullEventRaw`. Normally --- this would cause `parallel` to throw an error, but we replace `error` with an --- empty placeholder to let it continue and return without throwing. This results --- in the `pcall` returning successfully, preventing the error-displaying code --- from running - essentially making it so that `os.shutdown` is called immediately --- after the new BIOS exits. --- --- From there, the setup code is placed in `term.native` since it's the first --- thing called after `parallel` exits. This loads the new BIOS and prepares it --- for execution. Finally, it overwrites `os.shutdown` with the new function to --- allow it to be the last function called in the original BIOS, and returns. --- From there execution continues, calling the `term.redirect` dummy, skipping --- over the error-handling code (since `pcall` returned ok), and calling --- `os.shutdown()`. The real `os.shutdown` is re-added, and the new BIOS is tail --- called, which effectively makes it run as the main chunk. -local olderror = error -_G.error = function() end -_G.term.redirect = function() end -function _G.term.native() - _G.term.native = nil - _G.term.redirect = nil - _G.error = olderror - term.setBackgroundColor(32768) - term.setTextColor(1) - term.setCursorPos(1, 1) - term.setCursorBlink(true) - term.clear() - local file = fs.open(BOOT_DRIVE_PATH.."/boot/cct/boot.lua", "r") - if file == nil then - term.setCursorBlink(false) - term.setTextColor(16384) - term.write("Could not find /boot/cct/boot.lua. UnBIOS cannot continue.") - term.setCursorPos(1, 2) - term.write("Press any key to continue") - coroutine.yield("key") - os.shutdown() - end - local fn, err = loadstring(file.readAll(), "@bootloader") - file.close() - if fn == nil then - term.setCursorBlink(false) - term.setTextColor(16384) - term.write("Could not load /boot/cc/boot.lua. UnBIOS cannot continue.") - term.setCursorPos(1, 2) - term.write(err) - term.setCursorPos(1, 3) - term.write("Press any key to continue") - coroutine.yield("key") - os.shutdown() - end - setfenv(fn, _G) - local oldshutdown = os.shutdown - os.shutdown = function() - os.shutdown = oldshutdown - return fn(BOOT_DRIVE_PATH) - end -end -if debug then - -- Restore functions that were overwritten in the BIOS - -- Apparently this has to be done *after* redefining term.native - local function restoreValue(tab, idx, name, hint) - local i, key, value = 1, debug.getupvalue(tab[idx], hint) - while key ~= name and key ~= nil do - key, value = debug.getupvalue(tab[idx], i) - i=i+1 - end - tab[idx] = value or tab[idx] - end - restoreValue(_G, "loadstring", "nativeloadstring", 1) - restoreValue(_G, "load", "nativeload", 5) - if http then restoreValue(http, "request", "nativeHTTPRequest", 3) end - restoreValue(os, "shutdown", "nativeShutdown", 1) - restoreValue(os, "reboot", "nativeReboot", 1) - if turtle then - restoreValue(turtle, "equipLeft", "v", 1) - restoreValue(turtle, "equipRight", "v", 1) - end - do - local i, key, value = 1, debug.getupvalue(peripheral.isPresent, 2) - while key ~= "native" and key ~= nil do - key, value = debug.getupvalue(peripheral.isPresent, i) - i=i+1 - end - _G.peripheral = value or peripheral - end -end \ No newline at end of file diff --git a/Src/Hyperion-firmware-ccpc/data/boot/ccpc/initdisks b/Src/Hyperion-firmware-ccpc/data/boot/ccpc/initdisks deleted file mode 100644 index 1480a0b..0000000 --- a/Src/Hyperion-firmware-ccpc/data/boot/ccpc/initdisks +++ /dev/null @@ -1,272 +0,0 @@ ---:Minify:-- -local apis = ({...})[1] -local BOOT_DRIVE_PATH = apis.BOOT_DRIVE_PATH -local fs = apis.fs -local native = apis.peripheral -local peripheral = {} -local sides = {"top", "bottom", "left", "right", "front", "back"} - -function peripheral.getNames() - local results = {} - for n = 1, #sides do - local side = sides[n] - if native.isPresent(side) then - table.insert(results, side) - if native.hasType(side, "peripheral_hub") then - local remote = native.call(side, "getNamesRemote") - for _, name in ipairs(remote) do - table.insert(results, name) - end - end - end - end - return results -end - -function peripheral.isPresent(name) - if native.isPresent(name) then - return true - end - - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then - return true - end - end - return false -end - -function peripheral.getType(peripheral) - if type(peripheral) == "string" then - if native.isPresent(peripheral) then - return native.getType(peripheral) - end - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then - return native.call(side, "getTypeRemote", peripheral) - end - end - return nil - else - local mt = getmetatable(peripheral) - if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then - error("bad argument #1 (table is not a peripheral)", 2) - end - return table.unpack(mt.types) - end -end - -function peripheral.hasType(peripheral, peripheral_type) - if type(peripheral) == "string" then - if native.isPresent(peripheral) then - return native.hasType(peripheral, peripheral_type) - end - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then - return native.call(side, "hasTypeRemote", peripheral, peripheral_type) - end - end - return nil - else - local mt = getmetatable(peripheral) - if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then - error("bad argument #1 (table is not a peripheral)", 2) - end - return mt.types[peripheral_type] ~= nil - end -end - -function peripheral.getMethods(name) - if native.isPresent(name) then - return native.getMethods(name) - end - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then - return native.call(side, "getMethodsRemote", name) - end - end - return nil -end - -function peripheral.getName(peripheral) - local mt = getmetatable(peripheral) - if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then - error("bad argument #1 (table is not a peripheral)", 2) - end - return mt.name -end - -function peripheral.call(name, method, ...) - if native.isPresent(name) then - return native.call(name, method, ...) - end - - for n = 1, #sides do - local side = sides[n] - if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then - return native.call(side, "callRemote", name, method, ...) - end - end - return nil -end - -function peripheral.wrap(name) - local methods = peripheral.getMethods(name) - if not methods then - return nil - end - - local types = { peripheral.getType(name) } - for i = 1, #types do types[types[i]] = true end - local result = setmetatable({}, { - __name = "peripheral", - name = name, - type = types[1], - types = types, - }) - for _, method in ipairs(methods) do - result[method] = function(...) - return peripheral.call(name, method, ...) - end - end - return result -end - -function peripheral.find(ty, filter) - local results = {} - for _, name in ipairs(peripheral.getNames()) do - if peripheral.hasType(name, ty) then - local wrapped = peripheral.wrap(name) - if filter == nil or filter(name, wrapped) then - table.insert(results, wrapped) - end - end - end - return table.unpack(results) -end - -local disks = {} -local internal = {} - -local function norm(path) - if not path or path == "" then return "/" end - return fs.combine("/", path) -end - -local function createDisk(id, basePath, readonly, periph) - basePath = norm(basePath) - - local disk = {address = id, isReadOnly = function() return readonly end} - - function disk:spaceUsed() - return fs.getCapacity(basePath) - fs.getFreeSpace(basePath) - end - - function disk:spaceTotal() return fs.getCapacity(basePath) end - - function disk:list(path) - local p = fs.combine(basePath, path) - if not fs.exists(p) or not fs.isDir(p) then - return nil, "not directory" - end - return fs.list(p) - end - - function disk:fileExists(path) - local p = fs.combine(basePath, path) - return fs.exists(p) and not fs.isDir(p) - end - - function disk:directoryExists(path) - local p = fs.combine(basePath, path) - return fs.exists(p) and fs.isDir(p) - end - - function disk:type(path) - local p = fs.combine(basePath, path) - if not fs.exists(p) then - return nil - elseif fs.isDir(p) then - return "directory" - else - return "file" - end - end - - function disk:makeDirectory(path) - local p = fs.combine(basePath, path) - fs.makeDir(p) - return true - end - - function disk:remove(path) - local p = fs.combine(basePath, path) - if fs.exists(p) then fs.delete(p) end - return true - end - - function disk:setLabel(label) periph.setLabel(label) end - - function disk:getLabel(label) return periph.getLabel() end - - function disk:attributes(path) - local p = fs.combine(basePath, path) - return fs.attributes(p) - end - - function disk:open(path, mode) - local p = fs.combine(basePath, path) - return fs.open(p, mode) - end - - return disk -end - -internal["$"] = createDisk("$", BOOT_DRIVE_PATH, false, { - setLabel = function(label) - local h = fs.open("/.label", "w") - h.write(label) - h.close() - end, - getLabel = function() - local h = fs.open("/.label", "r") - if not h then return "$" end - local label = h.readAll() - h.close() - return label - end -}) - -internal["rom"] = createDisk("rom", "/rom", true, { - setLabel = function(label) - error("Device is read-only") - end, - getLabel = function() - return "cctrom" - end -}) - -local function refresh() - disks={} - for _, disk in ipairs({peripheral.find("drive")}) do - if disk.isDiskPresent() then - disks[tostring(disk.getDiskID())]=createDisk("cctdisk"..tostring(disk.getDiskID()), disk.getMountPath(), false, fs) - end - end -end - -local function iter() - refresh() - local combined = {} - - for id, obj in pairs(internal) do combined[id] = obj end - for id, obj in pairs(disks) do combined[id] = obj end - - return pairs(combined) -end - -return {refresh = refresh, list = iter} diff --git a/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod b/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod deleted file mode 100644 index 9a6481b..0000000 --- a/Src/Hyperion-firmware-ccpc/data/lib/modules/ccpc/25_gfx.kmod +++ /dev/null @@ -1,6 +0,0 @@ ---:Minify:-- -local kernel=... - -if kernel.gfx then - -end \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua index e3f607f..9b5bc6b 100644 --- a/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua +++ b/Src/Hyperion-firmware-cct/data/boot/cct/boot.lua @@ -494,7 +494,7 @@ local ok, err = xpcall(function() h.close() end, firmware=apis, - reboot=false, + status="running", beep=function() end } @@ -505,7 +505,7 @@ local ok, err = xpcall(function() local kernelCoro = coroutine.create(function() --pf - ---@diagnostic disable-next-line: param-type-mismatch- + ---@diagnostic disable-next-line: param-type-mismatch local ok, err = xpcall(Kernel, debug.traceback, EFI) if not ok then error(err) @@ -569,14 +569,18 @@ local ok, err = xpcall(function() end end if status == "error" or coroutine.status(kernelCoro) == "dead" then - if EFI.reboot then + if EFI.status=="reboot" then apis.os.reboot() + elseif EFI.status=="shutdown" then + apis.os.shutdown() end displaySuperBadError("Kernel error: " .. tostring(err)) coroutine.yield("key") elseif status == "success" then - if EFI.reboot then + if EFI.status=="reboot" then apis.os.reboot() + elseif EFI.status=="shutdown" then + apis.os.shutdown() end displaySuperBadError("Kernel error: Attempted to yield main thread\n"..debug.traceback(kernelCoro, "Attempted to yield main thread")) coroutine.yield("key") diff --git a/Src/Hyperion-firmware-cct/data/boot/cct/initdisks b/Src/Hyperion-firmware-cct/data/boot/cct/initdisks index 28af9cf..a795a71 100644 --- a/Src/Hyperion-firmware-cct/data/boot/cct/initdisks +++ b/Src/Hyperion-firmware-cct/data/boot/cct/initdisks @@ -163,7 +163,7 @@ local function createDisk(id, basePath, readonly, periph) local disk = {address = id, isReadOnly = function() return readonly end} function disk:spaceUsed() - return fs.getCapacity(basePath) - fs.getFreeSpace(basePath) + return (fs.getCapacity(basePath) or 0) - (fs.getFreeSpace(basePath) or 0) end function disk:spaceTotal() return fs.getCapacity(basePath) end diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_mouse.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_mouse.kmod new file mode 100644 index 0000000..394b285 --- /dev/null +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_mouse.kmod @@ -0,0 +1,25 @@ +--:Minify:-- +local kernel=... +local fifo=kernel.newFifo() +kernel.devfs.data["input"]["mouse1"] = function(op, mode) + if op=="type" then + return "Mouse" + elseif op=="open" then + local h = { + read=function(amount) + local rv="" + for i=1, amount or 1 do + local event = {fifo.pop()} + if event[1] then + rv=rv..event[1] + end + end + ---@diagnostic disable-next-line: cast-local-type + if rv=="" then rv=nil end + return rv + end + } + return h + end +end +kernel.cct.mouse={fifo=fifo} diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod index c70d41a..4f41145 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/25_tty.kmod @@ -1,6 +1,8 @@ --:Minify:-- local kernel = ... local peripheral=kernel.cct.peripheral +kernel.cct.gfx={} +kernel.cct.term={} local colors = { [0xFFFFFF]=0x0001, @@ -155,6 +157,7 @@ local function serializeBool(bool) end local function newtty(obj, id, ev) + kernel.cct.term[id]=obj obj.setPaletteColor(0x1, 0xFFFFFF) -- #000000 obj.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF obj.setPaletteColor(0x4, 0x00FF00) -- #FF0000 @@ -176,17 +179,6 @@ local function newtty(obj, id, ev) return "Terminal" elseif op=="open" then local h = { - read=function(amount) - local rv="" - for i=1, amount or 1 do - local event = {ev()} - if event[1] then - rv=rv..event[1] - end - end - if rv=="" then rv=nil end - return rv - end, write=function(content) write(content, obj) end, @@ -221,18 +213,16 @@ local function newtty(obj, id, ev) return false end, gplt=function() - return plt + return table.deepcopy(plt) + end, + gfx=function(...) + if kernel.cct.gfx[id] then return kernel.cct.gfx[id] else return false end + end, + id=function() + return id end } - if mode=="rw" then - return h - elseif mode=="r" then - h["write"]=nil - return h - elseif mode=="w" then - h["read"]=nil - return h - end + return h end end end @@ -259,23 +249,14 @@ kernel.devfs.data["input"]["keyboard1"] = function(op, mode) rv=rv..event[1] end end + ---@diagnostic disable-next-line: cast-local-type if rv=="" then rv=nil end return rv end, - write=function(content) - end, gctrl=function() return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt) end } - if mode=="rw" then - return h - elseif mode=="r" then - h["write"]=nil - return h - elseif mode=="w" then - h["read"]=nil - return h - end + return h end end \ No newline at end of file diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_daemon.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_daemon.kmod index c5ef91c..dc5c865 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_daemon.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/30_daemon.kmod @@ -71,8 +71,10 @@ kernel.processes.cctdaemon = function() elseif eventType == "mouse_scroll" then if event[2] == 1 then kernel.cct.fifo.push("S") + kernel.cct.mouse.fifo.push("S") else kernel.cct.fifo.push("T") + kernel.cct.mouse.fifo.push("T") end elseif eventType == "http_success" then if kernel.cct.httpqueue[event[2]] then @@ -85,6 +87,16 @@ kernel.processes.cctdaemon = function() kernel.cct.httperror[event[2]]=event[3] kernel.cct.httpresponse[event[2]]=event[4] end + elseif eventType == "mouse_click" then + --";X;Y;C" + -- 1 = left + -- 2 = right + -- 3 = middle + kernel.cct.mouse.fifo.push(";"..tostring(event[3])..";"..tostring(event[4])..";"..tostring(event[2])) + elseif eventType == "mouse_drag" then + kernel.cct.mouse.fifo.push(";"..tostring(event[3])..";"..tostring(event[4])..";"..tostring(event[2])) + elseif eventType == "mouse_up" then + kernel.cct.mouse.fifo.push(";"..tostring(event[3])..";"..tostring(event[4])..";"..tostring(event[2])) else if kernel.cct.eventhooks[eventType] then local ok,err = xpcall(kernel.cct.eventhooks[eventType], debug.traceback, table.unpack(event)) diff --git a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/46_scheduler.kmod b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/46_scheduler.kmod index ce40f8f..089ec64 100644 --- a/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/46_scheduler.kmod +++ b/Src/Hyperion-firmware-cct/data/lib/modules/cc-tweaked/46_scheduler.kmod @@ -35,6 +35,14 @@ function kernel.main() local totalTaskTime = 0 local taskTimes = {} + for id,hook in ipairs(kernel.mainHooks) do + local ok,err = xpcall(hook, debug.traceback) + if not ok then + kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000) + kernel.mainHooks[id]=nil + end + end + for pid, task in pairs(kernel.tasks) do if kernel.exitMain then break end @@ -42,7 +50,7 @@ function kernel.main() for id,hook in ipairs(list) do local ok,err = xpcall(hook, debug.traceback, task, pid) if not ok then - kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000) + kernel.log("[TASK HOOK ERR]: "..err, "ERROR", 0xFF0000) list[id]=nil end end @@ -148,4 +156,6 @@ function kernel.main() kernel.saveLog() end end + kernel.log("Exited main") + kernel.saveLog() end \ No newline at end of file diff --git a/Src/Hyperion-firmware-oc/data/boot/oc/boot.lua b/Src/Hyperion-firmware-oc/data/boot/oc/boot.lua index 79a5744..83d8086 100644 --- a/Src/Hyperion-firmware-oc/data/boot/oc/boot.lua +++ b/Src/Hyperion-firmware-oc/data/boot/oc/boot.lua @@ -1,3 +1,4 @@ +---@diagnostic disable-next-line: undefined-global local cp,c=component,computer;local b_addr=c.getBootAddress();local b_fs=cp.proxy(b_addr) local gpu=cp.list("gpu")() and cp.proxy(cp.list("gpu")()) local e_rom=cp.list("eeprom")() and cp.proxy(cp.list("eeprom")()) diff --git a/Src/Hyperion-firmware-oc/data/lib/modules/opencomputers/36_scheduler.kmod b/Src/Hyperion-firmware-oc/data/lib/modules/opencomputers/36_scheduler.kmod index 18dddea..80a4212 100644 --- a/Src/Hyperion-firmware-oc/data/lib/modules/opencomputers/36_scheduler.kmod +++ b/Src/Hyperion-firmware-oc/data/lib/modules/opencomputers/36_scheduler.kmod @@ -121,10 +121,7 @@ function kernel.main() end end end - if kernel.EFI:getEpochMs()>=nextyield then - kernel.EFI:yield() - nextyield=kernel.EFI:getEpochMs()+5000 - end + kernel.EFI:yield() end local T_prev_avg = (N > 0) and (totalTaskTime / N) or 0 diff --git a/Src/Hyperion-kernel/data/boot/kernel.lua b/Src/Hyperion-kernel/data/boot/kernel.lua index e9efb23..1af0fcb 100644 --- a/Src/Hyperion-kernel/data/boot/kernel.lua +++ b/Src/Hyperion-kernel/data/boot/kernel.lua @@ -74,7 +74,7 @@ function kernel.PANIC(msg) break end end - EFI.reboot=true + EFI.status="reboot" error("KERNEL PANIC") end kernel.panic=kernel.PANIC @@ -179,7 +179,6 @@ if not root then if event[1]=="keyTyped" then if tonumber(event[3]) then if canadates[tonumber(event[3])] then - ifs.writeAllText("/boot/fstab", "U "..canadates[tonumber(event[3])]..";/\n"..fstab) fstab="U "..canadates[tonumber(event[3])]..";/\n"..fstab ifs.mount(canadates[tonumber(event[3])], "/") break @@ -359,7 +358,7 @@ kernel.perTaskHooks={} kernel.mainHooks={} kernel.runhooks={} --- args {taskobj} +-- args {taskobj, pid} function kernel.execPerTask(func, prior) if not kernel.perTaskHooks[prior] then kernel.perTaskHooks[prior]={} end kernel.perTaskHooks[prior][#kernel.perTaskHooks[prior]+1] = func @@ -460,6 +459,7 @@ kernel.syscalls["saveLog"]=function() end end +ifs.writeAllText("/boot/fstab", fstab) kernel.saveLog() kernel.log("Running modules") for _,p in ipairs(modules) do @@ -471,7 +471,7 @@ for _,p in ipairs(modules) do if not code then kernel.panic("Failed to read module "..v) end - local func,err=load(code,"@"..v) + local func,err=load(code,"@"..v,"t",_G) if not func then kernel.panic("ModuLoadErr: "..tostring(err)) end local status, err = xpcall(func,debug.traceback, kernel) if not status then kernel.panic("ModuRunErr: "..tostring(err)) end @@ -502,10 +502,13 @@ if kernel.status=="panic" then kernel.panic(kernel.reason) end if kernel.status=="reboot" then - EFI.reboot=true + EFI.status="reboot" return true elseif kernel.status=="halt" then kernel.log("System halted.") kernel.saveLog() while true do end +else + EFI.status="shutdown" + return true end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod index d6c50d5..e266f65 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/01_stdlib.kmod @@ -2,6 +2,16 @@ --- @diagnostic disable: duplicate-set-field local kernel = ... kernel.allowGlobalOverwrites = true +local oldtype = type +local oldgetmetatable = getmetatable + +function math.round(x) + if x>=0 then + return math.floor(x+0.5) + else + return math.ceil(x-0.5) + end +end function string.hasSuffix(str, suffix) return string.sub(str, #suffix + 1) == suffix @@ -70,6 +80,10 @@ function table.hasVal(tabl, query) return false end +function table.readOnly(tabl, typ) + return setmetatable({},{__index=tabl,__newindex=function()error("Table is read-only")end,__usermeta=false,__type=typ}) +end + local function serialize(tbl, seen) seen = seen or {} @@ -100,6 +114,8 @@ local function serialize(tbl, seen) output = output .. "\"" .. tostring(v) .. "\"" elseif type(v) == "thread" then output = output .. "\"" .. tostring(v) .. "\"" + elseif oldgetmetatable(v) and oldgetmetatable(v).__tostring then + output = output .. tostring(v) else error("serialization of type \"" .. type(v) .. "\" is not supported") end @@ -111,8 +127,6 @@ local function serialize(tbl, seen) return output end -local oldtype = type -local oldgetmetatable = getmetatable function type(object, trueType) if trueType then return oldtype(object) end if oldtype(object) ~= "table" then @@ -131,7 +145,7 @@ end function getmetatable(object) if oldtype(object) ~= "table" then return end if oldtype(oldgetmetatable(object)) == "table" then - if oldgetmetatable(object).__isuserdata then + if oldgetmetatable(object).__usermeta then if oldtype(oldgetmetatable(object).__usermeta) == "function" then return oldgetmetatable(object).__usermeta() else @@ -251,8 +265,6 @@ local function makeSyscallProxy() local backing = {} return setmetatable(backing, { __index = function(self, name) - local raw = rawget(self, name) - if raw ~= nil then return raw end return function(...) local res = table.pack(coroutine.yield("syscall", name, ...)) if res[1] then @@ -263,7 +275,7 @@ local function makeSyscallProxy() end end, __newindex = function(self, k, v) - rawset(self, k, v) + error("Table is read-only") end, __metatable=false }) @@ -271,6 +283,5 @@ end syscall = makeSyscallProxy() -_makeSyscallProxy = makeSyscallProxy - table.serialize = serialize + diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod index c34f1c6..834a65e 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/10_vfs.kmod @@ -299,6 +299,7 @@ local function namei(path, noFollow, symDepth) if not target or target == "" then error("ENOENT: empty symlink target") end + if kernel.config.logSymlinkTraverse then kernel.log(curPath .. " > " .. target) end local symIsAbs, symTokens = tokenizePath(target) @@ -1158,7 +1159,27 @@ function vfs.devlst(fd) return table.keys(kernel.currentTask.fd[fd].handle) end +function vfs.getOpenFds() + local out={} + for i,v in ipairs(kernel.currentTask.fd) do + out[i]=v.path + end + return out +end + +function vfs.fsinfo() + local out={mounts={},disks={}} + for i,v in pairs(vfs.mounts) do + out.mounts[i]=v + end + for i,v in pairs(vfs.disks) do + out.disks[i]={size=vfs.disks[i].spaceTotal(),used=vfs.disks[i].spaceUsed(),label=vfs.disks[i].getLabel(),readOnly=vfs.disks[i].isReadOnly(),isVirt=vfs.disks[i].isvirt,address=vfs.disks[i].addressz} + end + return out +end + vfs.resolveMount = resolveMount +vfs.updateMeta = updateMeta local sys = kernel.syscalls sys["open"] = vfs.open @@ -1198,5 +1219,7 @@ sys["fget_suid"] = function(fd) local fobj = kernel.currentTask and kernel.currentTask.fd[fd] return fobj and fobj.suid_owner or nil end +sys["getOpenFds"]= vfs.getOpenFds +sys["fsinfo"] = vfs.fsinfo kernel.log("VFS module loaded") diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod index 3909e2a..6dafbae 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/11_ld.kmod @@ -7,8 +7,12 @@ kernel.searchpaths = { } kernel.reqcache = cache +local function wrap(lib) + return setmetatable({},{__index=lib,__newindex=function()error("Table is read-only")end,__usermeta=false,__call=function(s,...) return lib.new(...) end}) +end + local function require(module, ...) - if cache[module] then return cache[module].ret end + if cache[module] then return wrap(cache[module].ret) end local args = {...} for _, path in ipairs(kernel.searchpaths) do local filepath = path:gsub("?", module) @@ -36,8 +40,8 @@ local function require(module, ...) if not ok then error("Error running module "..module..": "..tostring(ret)) end - cache[module] = {ret = ret, expires = kernel.EFI:getEpochMs() + 120000} - return ret + cache[module] = {ret = ret} + return wrap(ret) end coroutine.yield() end diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_runfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_runfs.kmod new file mode 100644 index 0000000..7ceec01 --- /dev/null +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_runfs.kmod @@ -0,0 +1,3 @@ +--:Minify:-- +local kernel = ... + diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/12_sysfs.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_sysfs.kmod new file mode 100644 index 0000000..7d7a8eb --- /dev/null +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/12_sysfs.kmod @@ -0,0 +1,82 @@ +--:Minify:-- +local kernel = ... + +local proxy = {} +local data = {} + +proxy.address = "devfs0000" +proxy.isvirt = true +proxy.isReadOnly = function() return false end +proxy.spaceUsed = function() return 0 end +proxy.spaceTotal = function() return 0 end +proxy.makeDirectory = function() error("EACCES") end +proxy.remove = function() error("EACCES") end +proxy.setLabel = function() error("EACCES") end +proxy.getLabel = function() return "devfs" end +proxy.attributes = function(path) return { + size = 0, + modified = 0, + created = 0 +} end + +function proxy:open(path, mode) + local steps = kernel.vfs.splitPath(path) + local step = data + for i=1, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENFILE") end + step=dat + end + if type(step[steps[#steps]]) == "function" then + return step[steps[#steps]]("open", mode) + end + error("ENFILE") +end + +function proxy:type(path, mode) + local steps = kernel.vfs.splitPath(path) + local step = data + if #steps == 0 then + return "directory" + end + for i=1, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENFILE") end + step=dat + end + if type(step[steps[#steps]]) == "function" then + return step[steps[#steps]]("type", mode) + end + if type(step[steps[#steps]]) == "table" then + return "directory" + end + error("ENOENT") +end + +function proxy:list(path) + local steps = kernel.vfs.splitPath(path) + local step = data + if #steps == 0 then + return table.keys(data) + end + for i=1, #steps-1 do + local dat = step[steps[i]] + if type(dat) ~= "table" then error("ENOENT") end + step=dat + end + if type(step[steps[#steps]]) == "table" then + return table.keys(step[steps[#steps]]) + end + error("ENOENT") +end + +function proxy:fileExists(path) + local ok = pcall(function() + return self:type(path) + end) + return ok +end + +kernel.sysfs={} +kernel.sysfs.proxy=proxy +kernel.disks["sysfs0000"]=proxy \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_signals.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_signals.kmod index 13fb08b..5d17c2b 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/20_signals.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/20_signals.kmod @@ -37,7 +37,7 @@ kernel.execPerTask(function(task) if task.sigq and #task.sigq ~= 0 and task.sigh then local coro = coroutine.create(task.sigh) local status,err=coroutine.resume(coro, table.remove(task.sigq, 1)) - EFI:yeild() + kernel.EFI:yield() if status=="error" or status==false then task.sigd.error=err or "Unknown" task.sigd.active=false diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod index a145249..97da65f 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/21_unixsockets.kmod @@ -2,3 +2,5 @@ local kernel=... kernel.unixSockets={} local socket=kernel.socket + +--socket.registerProtocal() diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/30_userspace.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/30_userspace.kmod index a7a2e90..941e1cf 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/30_userspace.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/30_userspace.kmod @@ -58,10 +58,12 @@ kernel._U.load = function(a,b,c,d) return origLoad(a,b,c,d or kernel._U) end function kernel.freshUserEnv() local locals = {} - locals.syscall = _makeSyscallProxy() local env = setmetatable(locals, { __index = kernel._U, + __pairs = function(self) + return pairs(kernel._U) + end, __newindex = function(_, k, v) rawset(locals, k, v) end, __metatable=false }) diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod index 1ec91b7..edf2e58 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/30_vterm.kmod @@ -33,7 +33,7 @@ local function createVt(id, width, height) end end - function vt.obj:write(content) + function vt.obj.write(content) local x, y = vt.cursorX, vt.cursorY if x>vt.width then return end if y>vt.height then return end @@ -79,36 +79,36 @@ local function createVt(id, width, height) vt.cursorX, vt.cursorY = x, y end - function vt.obj:spos(x, y) + function vt.obj.spos(x, y) vt.cursorX = tonumber(x) vt.cursorY = tonumber(y) end - function vt.obj:gpos() - return tostring(vt.cursorX)..";"..tostring(vt.cursorY) + function vt.obj.gpos() + return vt.cursorX, vt.cursorY end - function vt.obj:sfgc(color) + function vt.obj.sfgc(color) vt.fgColor = tonumber(color) end - function vt.obj:sbgc(color) + function vt.obj.sbgc(color) vt.bgColor = tonumber(color) end - function vt.obj:gfgc() + function vt.obj.gfgc() return vt.fgColor end - function vt.obj:gbgc() + function vt.obj.gbgc() return vt.bgColor end - function vt.obj:gplt() + function vt.obj.gplt() return 24 end - function vt.obj:clear() + function vt.obj.clear() for y = 1, vt.height do for x = 1, vt.width do vt.buffer[y][x] = {char = " ", fgColor = vt.fgColor, bgColor = vt.bgColor} @@ -117,12 +117,12 @@ local function createVt(id, width, height) vt.cursorX, vt.cursorY = 1, 1 end - function vt.obj:isvirt() + function vt.obj.isvirt() return true end - function vt.obj:gctrl() - return serializeBool(vt.ctrl)..";"..serializeBool(vt.alt) + function vt.obj.gfx() + end return vt diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod index 720f78d..5b8dbbe 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/45_hypervisor.kmod @@ -108,7 +108,7 @@ function sys.spawn(func, name, envars, args, tgid, clearFds) end function sys.execspawn(path, name, envars, args, tgid, keepFds) - local func, euid, suid_active = loadExecutable(path, kernel._U) + local func, euid, suid_active = loadExecutable(path) local caller = kernel.currentTask local real_uid = caller and caller.uid or kernel.uid @@ -124,16 +124,19 @@ function sys.execspawn(path, name, envars, args, tgid, keepFds) return createTask(func, name or path, envars, args, tgid, real_uid, euid, not keepFds) end -function sys.exec(path, args, envars) +function sys.exec(path, args, envars, clearFds) local task = kernel.currentTask - local func, euid, _ = loadExecutable(path, kernel._U) + local func, euid, _ = loadExecutable(path) -- no idea why this is here? - --if task.fd then - -- for fd, _ in pairs(task.fd) do - -- if fd > 2 then pcall(kernel.vfs.close, fd) end - -- end - --end + -- Figured it out it is to close fds on su + if clearFds then + if task.fd then + for fd, _ in pairs(task.fd) do + if fd > 2 then pcall(kernel.vfs.close, fd) end + end + end + end task.euid = euid task.args = args or {} diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/48_dbg.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/48_dbg.kmod index bb18018..3989827 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/48_dbg.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/48_dbg.kmod @@ -1,7 +1,7 @@ --:Minify:-- local kernel=... -local debug=debug +kernel.debug=debug kernel._G.debug={ - getinfo=debug.getinfo, - traceback=debug.traceback + getinfo=kernel.debug.getinfo, + traceback=kernel.debug.traceback } \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod index 4f623c6..eb7d3b7 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_init.kmod @@ -14,7 +14,7 @@ local data = kernel.vfs.read(handle, 1024 * 1024 * 4) if not handle then kernel.panic("Failed to read "..kernel.config.initPath) end kernel.vfs.close(handle) -local initFunc, err = load(data, "@sysinit", "t", kernel._U) +local initFunc, err = load(data, "@init", "t", kernel._U) if not initFunc then kernel.PANIC("Failed to load init system: " .. err) end kernel.tasks["1"] = { @@ -28,7 +28,7 @@ kernel.tasks["1"] = { kernel.saveLog() end), - name = "sysinit", + name = "init", status = "R", pid = 1, tgid = 1, diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod index 9ad2300..9d36446 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/90_kgc.kmod @@ -2,11 +2,11 @@ local kernel = ... kernel.processes.kgc = function() while true do - for i,v in pairs(kernel.reqcache) do - if v.expires and kernel.EFI:getEpochMs() > v.expires then - kernel.reqcache[i] = nil - end - end + --for i,v in pairs(kernel.reqcache) do + -- if v.expires and kernel.EFI:getEpochMs() > v.expires then + -- kernel.reqcache[i] = nil + -- end + --end sleep(5) end end \ No newline at end of file diff --git a/Src/Hyperion-kernel/data/lib/modules/hyperion/92_setup.kmod b/Src/Hyperion-kernel/data/lib/modules/hyperion/92_setup.kmod index 790fc72..1cabb2c 100644 --- a/Src/Hyperion-kernel/data/lib/modules/hyperion/92_setup.kmod +++ b/Src/Hyperion-kernel/data/lib/modules/hyperion/92_setup.kmod @@ -1,7 +1,10 @@ --:Minify:-- local kernel = ... -if kernel.firstBoot then +if kernel.firstBoot or kernel.config.resetPerms then + if kernel.config.resetPerms then + kernel.log("resetPerms is active, disable it in /boot/boot.cfg", "WARN", 0xFFFF00) + end kernel.log("Seeding filesystem permissions...") local P = kernel.vfs.P @@ -18,20 +21,23 @@ if kernel.firstBoot then local function seed(root, data) for i=1,#data do - local entry=data[1] - kernel.vfs.chmod(root..entry[1],entry[2],entry[3]) - kernel.vfs.chown(root..entry[1],entry[4]) + local entry=data[i] + if kernel.vfs.exists(root..entry[1]) then + kernel.vfs.updateMeta(root..entry[1],function(e) + e.perms=entry[4] + e.group=entry[3] + e.owner=entry[2] + end) + end end end seed("/", { {"bin", 0, 0, RWX_RX_RX}, {"boot", 0, 0, RWX_RX_RX}, - {"dev", 0, 0, RWXRWXRWX}, {"etc", 0, 0, RWX_RX_RX}, {"home", 0, 0, RWX_RX_RX}, {"lib", 0, 0, RWX_RX_RX}, - {"proc", 0, 0, RWXRWXRWX}, {"root", 0, 0, RW____ }, {"sbin", 0, 0, RWX_RX_RX}, {"tmp", 0, 0, RWXRWXRWX}, diff --git a/Src/coreutils/data/bin/su b/Src/coreutils/data/bin/su index 64d75af..1ef271e 100644 --- a/Src/coreutils/data/bin/su +++ b/Src/coreutils/data/bin/su @@ -58,7 +58,7 @@ syscall.setEnviron("HOME", homedir) syscall.setEnviron("USER", username) syscall.setEnviron("SHELL", shell) -local ok, err = pcall(syscall.exec, shell) +local ok, err = pcall(syscall.exec, shell, nil, true) if not ok then print("su: cannot exec shell '" .. shell .. "': " .. tostring(err)) syscall.exit(1) diff --git a/Src/gfx/authors.txt b/Src/fonts/authors.txt similarity index 100% rename from Src/gfx/authors.txt rename to Src/fonts/authors.txt diff --git a/Src/gfx/data/lib/psf b/Src/fonts/data/lib/psf similarity index 100% rename from Src/gfx/data/lib/psf rename to Src/fonts/data/lib/psf diff --git a/Src/gfx/data/usr/local/share/fonts/default8x9.psf b/Src/fonts/data/usr/local/share/fonts/default8x9.psf similarity index 100% rename from Src/gfx/data/usr/local/share/fonts/default8x9.psf rename to Src/fonts/data/usr/local/share/fonts/default8x9.psf diff --git a/Src/fonts/dependencies.txt b/Src/fonts/dependencies.txt new file mode 100644 index 0000000..e2e962e --- /dev/null +++ b/Src/fonts/dependencies.txt @@ -0,0 +1 @@ +vector \ No newline at end of file diff --git a/Src/gfx/description.txt b/Src/fonts/description.txt similarity index 100% rename from Src/gfx/description.txt rename to Src/fonts/description.txt diff --git a/Src/fonts/docs/gfx.sig b/Src/fonts/docs/gfx.sig new file mode 100644 index 0000000..cee561d --- /dev/null +++ b/Src/fonts/docs/gfx.sig @@ -0,0 +1,19 @@ +function lib.load(fd) + function handle.setPixel(x,y,color24) + function handle.getPixel(x,y) + function handle.setPixels(x,y,w,framebuffer) + function handle.getPixels(x,y,w,h) + function handle.frame(x,y,w,h,writeonly) + integer id + recurse lib.load + function handle.framectl(id) + function frame.move(x,y) + function frame.resize(w,h) + function frame.free() + function handle.sync() + function handle.line(x1,y1,x2,y2) + function handle.box(x,y,w,h,c,fill) + function handle.filledBox(x,y,w,h,c) + function handle.text(x,y,font,text) + function handle.free() + function handle.size() \ No newline at end of file diff --git a/Src/fonts/docs/gfxccimpl.lua b/Src/fonts/docs/gfxccimpl.lua new file mode 100644 index 0000000..e69de29 diff --git a/Src/gfx/palette b/Src/fonts/palette similarity index 100% rename from Src/gfx/palette rename to Src/fonts/palette diff --git a/Src/fonts/test/bin/testgfx b/Src/fonts/test/bin/testgfx new file mode 100644 index 0000000..e69de29 diff --git a/Src/gfx/version.txt b/Src/fonts/version.txt similarity index 100% rename from Src/gfx/version.txt rename to Src/fonts/version.txt diff --git a/Src/gfx/data/lib/gfx b/Src/gfx/data/lib/gfx deleted file mode 100644 index a1b2f1f..0000000 --- a/Src/gfx/data/lib/gfx +++ /dev/null @@ -1,40 +0,0 @@ ---:Minify:-- -local lib = {} - -function lib.frame(frame) - local handle = {} - - function handle.setPixel(x,y,color24) - - end - - function handle.getPixel(x,y) - - end - - function handle.setPixels(x,y,framebuffer) - - end - - function handle.getPixels(x,y,w,h) - - end - - function handle.frame(x,y,w,h,writeonly) - - end - - function handle.framectl(id,x,y,w,h,writeonly) - - end - - function handle.drawframe() - - end - - function handle.line() - - end - - return handle -end \ No newline at end of file diff --git a/Src/gfx/test/usr/local/gfxterm/tests/uv.lsl b/Src/gfx/test/usr/local/gfxterm/tests/uv.lsl deleted file mode 100644 index d8076e8..0000000 --- a/Src/gfx/test/usr/local/gfxterm/tests/uv.lsl +++ /dev/null @@ -1,350 +0,0 @@ -term.setGraphicsMode(2) -local w,h = term.getSize(2) -local fb={} -for i=1, h do - fb[i]={} - for x=1, w do - fb[i][x]=0 - end -end - -local function setPixel(x,y,c) - --local old=fb[y] - --fb[y]=string.sub(old,1,x-1)..string.char(c)..string.sub(old,x+1) - fb[y][x]=c -end - -local function setPixels(x,y,frame) - local w,h = #fb[1], #fb - for i=1, #frame do - for j=1, #frame[i] do - fb[y+i-1][x+j-1]=frame[i][j] - end - end -end - -local function getPixel(x,y) - return fb[y][x] -end - -local function getPixels(x,y,w,h) - local ret={} - for i=y, y+h do - ret[#ret+1] = {table.unpack(fb[i], x, x+w)} - end - return ret -end - -local colors = { - [0]=0x000000, - 0x0b0b0b, - 0x222222, - 0x444444, - 0x555555, - 0x777777, - 0x888888, - 0xaaaaaa, - 0xbbbbbb, - 0xdddddd, - 0xeeeeee, - 0x00000b, - 0x000022, - 0x000044, - 0x000055, - 0x000077, - 0x000088, - 0x0000aa, - 0x0000bb, - 0x0000dd, - 0x0000ee, - 0x000b00, - 0x002200, - 0x004400, - 0x005500, - 0x007700, - 0x008800, - 0x00aa00, - 0x00bb00, - 0x00dd00, - 0x00ee00, - 0x0b0000, - 0x220000, - 0x440000, - 0x550000, - 0x770000, - 0x880000, - 0xaa0000, - 0xbb0000, - 0xdd0000, - 0xee0000, - 0x000033, - 0x000066, - 0x000099, - 0x0000cc, - 0x0000ff, - 0x003300, - 0x003333, - 0x003366, - 0x003399, - 0x0033cc, - 0x0033ff, - 0x006600, - 0x006633, - 0x006666, - 0x006699, - 0x0066cc, - 0x0066ff, - 0x009900, - 0x009933, - 0x009966, - 0x009999, - 0x0099cc, - 0x0099ff, - 0x00cc00, - 0x00cc33, - 0x00cc66, - 0x00cc99, - 0x00cccc, - 0x00ccff, - 0x00ff00, - 0x00ff33, - 0x00ff66, - 0x00ff99, - 0x00ffcc, - 0x00ffff, - 0x330000, - 0x330033, - 0x330066, - 0x330099, - 0x3300cc, - 0x3300ff, - 0x333300, - 0x333333, - 0x333366, - 0x333399, - 0x3333cc, - 0x3333ff, - 0x336600, - 0x336633, - 0x336666, - 0x336699, - 0x3366cc, - 0x3366ff, - 0x339900, - 0x339933, - 0x339966, - 0x339999, - 0x3399cc, - 0x3399ff, - 0x33cc00, - 0x33cc33, - 0x33cc66, - 0x33cc99, - 0x33cccc, - 0x33ccff, - 0x33ff00, - 0x33ff33, - 0x33ff66, - 0x33ff99, - 0x33ffcc, - 0x33ffff, - 0x660000, - 0x660033, - 0x660066, - 0x660099, - 0x6600cc, - 0x6600ff, - 0x663300, - 0x663333, - 0x663366, - 0x663399, - 0x6633cc, - 0x6633ff, - 0x666600, - 0x666633, - 0x666666, - 0x666699, - 0x6666cc, - 0x6666ff, - 0x669900, - 0x669933, - 0x669966, - 0x669999, - 0x6699cc, - 0x6699ff, - 0x66cc00, - 0x66cc33, - 0x66cc66, - 0x66cc99, - 0x66cccc, - 0x66ccff, - 0x66ff00, - 0x66ff33, - 0x66ff66, - 0x66ff99, - 0x66ffcc, - 0x66ffff, - 0x990000, - 0x990033, - 0x990066, - 0x990099, - 0x9900cc, - 0x9900ff, - 0x993300, - 0x993333, - 0x993366, - 0x993399, - 0x9933cc, - 0x9933ff, - 0x996600, - 0x996633, - 0x996666, - 0x996699, - 0x9966cc, - 0x9966ff, - 0x999900, - 0x999933, - 0x999966, - 0x999999, - 0x9999cc, - 0x9999ff, - 0x99cc00, - 0x99cc33, - 0x99cc66, - 0x99cc99, - 0x99cccc, - 0x99ccff, - 0x99ff00, - 0x99ff33, - 0x99ff66, - 0x99ff99, - 0x99ffcc, - 0x99ffff, - 0xcc0000, - 0xcc0033, - 0xcc0066, - 0xcc0099, - 0xcc00cc, - 0xcc00ff, - 0xcc3300, - 0xcc3333, - 0xcc3366, - 0xcc3399, - 0xcc33cc, - 0xcc33ff, - 0xcc6600, - 0xcc6633, - 0xcc6666, - 0xcc6699, - 0xcc66cc, - 0xcc66ff, - 0xcc9900, - 0xcc9933, - 0xcc9966, - 0xcc9999, - 0xcc99cc, - 0xcc99ff, - 0xcccc00, - 0xcccc33, - 0xcccc66, - 0xcccc99, - 0xcccccc, - 0xccccff, - 0xccff00, - 0xccff33, - 0xccff66, - 0xccff99, - 0xccffcc, - 0xccffff, - 0xff0000, - 0xff0033, - 0xff0066, - 0xff0099, - 0xff00cc, - 0xff00ff, - 0xff3300, - 0xff3333, - 0xff3366, - 0xff3399, - 0xff33cc, - 0xff33ff, - 0xff6600, - 0xff6633, - 0xff6666, - 0xff6699, - 0xff66cc, - 0xff66ff, - 0xff9900, - 0xff9933, - 0xff9966, - 0xff9999, - 0xff99cc, - 0xff99ff, - 0xffcc00, - 0xffcc33, - 0xffcc66, - 0xffcc99, - 0xffcccc, - 0xffccff, - 0xffff00, - 0xffff33, - 0xffff66, - 0xffff99, - 0xffffcc, - 0xffffff, -} - -for i=0,255 do - term.setPaletteColor(i,colors[i]) -end -term.drawPixels(0,0,fb) - -for i=0,255 do - for y=1+i, h-i do - for x=1+i, w-i do - setPixel(x,y,i) - end - end - term.drawPixels(1,1,fb) - os.queueEvent("nosleep") - os.pullEvent() -end - -for i=1, 1000 do - pcall(function() - setPixels(math.random(1,w),math.random(1,h),getPixels(math.random(1,w),math.random(1,h),math.random(1,w),math.random(1,h))) - end) - term.drawPixels(1,1,fb) - os.queueEvent("nosleep") - os.pullEvent() -end -setPixels(1,1,getPixels(w-50,h-50,50,50)) -term.drawPixels(0,0,fb) - -local i=0 -for x=1, 16*4, 4 do - for y=1, 16*4, 4 do - setPixel(x,y,i) - setPixel(x+1,y,i) - setPixel(x+2,y,i) - setPixel(x+3,y,i) - setPixel(x,y+1,i) - setPixel(x+1,y+1,i) - setPixel(x+2,y+1,i) - setPixel(x+3,y+1,i) - setPixel(x,y+2,i) - setPixel(x+1,y+2,i) - setPixel(x+2,y+2,i) - setPixel(x+3,y+2,i) - setPixel(x,y+3,i) - setPixel(x+1,y+3,i) - setPixel(x+2,y+3,i) - setPixel(x+3,y+3,i) - i=i+1 - end -end -term.drawPixels(0,0,fb) - -sleep(5) -term.setGraphicsMode(false) - diff --git a/Src/hysh/data/bin/hysh b/Src/hysh/data/bin/hysh index 74ff793..8015834 100644 --- a/Src/hysh/data/bin/hysh +++ b/Src/hysh/data/bin/hysh @@ -6,6 +6,7 @@ syscall.open("/dev/tty/1","w") --stdout (Device 1) syscall.open("/dev/null","w") --stderr (device 2) local fs = require("fs") +local gfx = syscall.devctl(1,"gfx") syscall.devctl(1,"clear") syscall.devctl(1,"sfgc",0xFFFFFF) @@ -242,6 +243,7 @@ builtinCmds.clear = function() syscall.devctl(1,"clear") syscall.devctl(1,"sfgc",0xFFFFFF) syscall.devctl(1,"spos",1,1) + if gfx then local w,h=gfx.size() gfx.box(0,0,w+5,h+5,0,true) end end builtinCmds.whoami = function() @@ -820,10 +822,11 @@ builtinCmds.df = function(...) end local function fmt(n) return opts.h and hfmt(n) or tostring(n) end print(string.format("%-20s %10s %10s %10s %6s %-s","Filesystem","Size","Used","Avail","Use%","Mounted on")) - local mounts = {{"$","/"}, {"devfs0000","/dev/"}, {"tmpfs0000","/tmp/"}} - for _, m in ipairs(mounts) do - local id, mp = m[1], m[2] - print(string.format("%-20s %10s %10s %10s %6s %-s", id, "?", "?", "?", "?%", mp)) + local fsinfo = syscall.fsinfo() + for id, obj in pairs(fsinfo.disks) do + local use = ((obj.size/obj.used)-1)*100 + local avail = obj.size-obj.used + print(string.format("%-20s %10s %10s %10s %6s %-s", id, tostring(obj.size), tostring(obj.used), avail, tostring(use).."%", fsinfo.mounts[id] or "")) end end @@ -1218,12 +1221,14 @@ local function runCommand(command) while true do local exited, code = syscall.collect(proc) if exited then + if gfx then gfx.setMode(false) end if code then print("\nTask exited with code:\n"..tostring(code)) end return end if terminate then local ok2 = syscall.kill(proc, true) if ok2 then + if gfx then gfx.setMode(false) end syscall.devctl(1,"sbgc",16); syscall.devctl(1,"sfgc",0xFF0000) print("\nProgram Terminated."); syscall.devctl(1,"sfgc",0xFFFFFF) end diff --git a/Src/lua/data/bin/lua b/Src/lua/data/bin/lua index fe450a1..30afff3 100644 --- a/Src/lua/data/bin/lua +++ b/Src/lua/data/bin/lua @@ -173,6 +173,8 @@ end local luaEnv = setmetatable({}, {__index = _ENV}) luaEnv._G = luaEnv +luaEnv._ENV = _ENV +luaEnv._G = _G luaEnv.print = function(...) local n = select("#", ...) @@ -259,9 +261,9 @@ local function getUserInput(prompt, history) local key = syscall.read(0) if key and key ~= "" then if key == "" then - if cursor > 1 then cursor = cursor - 1; dirty = true end + if cursor > 1 then cursor = cursor + 1; dirty = true end elseif key == "" then - if cursor <= #input then cursor = cursor + 1; dirty = true end + if cursor <= #input then cursor = cursor - 1; dirty = true end elseif key == "" then if history and histIdx < #history then histIdx = histIdx + 1 @@ -298,9 +300,9 @@ local function getUserInput(prompt, history) end c(C_PROMPT); w("HyperionOS " .. _VERSION .. "\n") -w("Type \"exit()\" to exit.") +w("Interactive Lua REPL. Type \"exit()\" to exit.\n") c(C_NIL) -w("Interactive Lua REPL. exit() to quit.\n\n") +w("\n\n") c(1) local history = {} diff --git a/Src/math/authors.txt b/Src/math/authors.txt new file mode 100644 index 0000000..73c23ff --- /dev/null +++ b/Src/math/authors.txt @@ -0,0 +1,2 @@ +Hyperion +Astronand \ No newline at end of file diff --git a/Src/math/data/lib/matrix b/Src/math/data/lib/matrix new file mode 100644 index 0000000..3837d9e --- /dev/null +++ b/Src/math/data/lib/matrix @@ -0,0 +1,217 @@ +--:Minify:-- +local lib={} + +local function check(a,b,ignoreb) + if type(a)~="vector" then error("vector metatable is on non vector object") end + if not ignoreb and b~=nil then + if type(b)~="vector" then error("b must be vector") end + if #a~=#b then error("vectors must be same size") end + end +end + +local vector={ + add = function(a,b) + check(a,b) + local ret={} + for i=1, #a do + ret[i]=a[i]+b[i] + end + return lib.convert(ret) + end, + + sub = function(a,b) + check(a,b) + if type(b)~="vector" then error("b must be vector") end + local ret={} + for i=1, #a do + ret[i]=a[i]-b[i] + end + return lib.convert(ret) + end, + + unm = function(a) + local ret={} + for i=1, #a do + ret[i]=-a[i] + end + return lib.convert(ret) + end, + + mul = function(a,b) + if type(a)=="number" and type(b)=="vector" then a,b=b,a end + check(a,b,true) + local ret={} + if type(b)=="vector" then + for i=1, #a do + ret[i]=a[i]*b[i] + end + elseif type(b)=="number" then + for i=1, #a do + ret[i]=a[i]*b + end + else + error("b must be vector or number") + end + return lib.convert(ret) + end, + + div = function(a,b) + if type(a)=="number" and type(b)=="vector" then a,b=b,a end + check(a,b,true) + local ret={} + if type(b)=="vector" then + for i=1, #a do + ret[i]=a[i]/b[i] + end + elseif type(b)=="number" then + for i=1, #a do + ret[i]=a[i]/b + end + else + error("b must be vector or number") + end + return lib.convert(ret) + end, + + dot = function(a,b) + check(a,b) + local out=a[1]*b[1] + for i=2, #a do + out=out+a[i]*b[i] + end + return out + end, + + tostring = function(a) + check(a) + local out = "{" + for i=1, #a do + out=out..tostring(a[i])..", " + end + return out:sub(1,#out-2).."}" + end, + + equals = function(a,b) + check(a,b) + for i=1, #a do + if a[i]~=b[i] then + return false + end + end + return true + end, + + cross = function(a,b) + check(a,b) + if #a~=3 then error("Vectors must be of type 'vec3'") end + if #b~=3 then error("Vectors must be of type 'vec3'") end + return lib.convert({ + a.y*b.z-a.z*b.y, + a.z*b.x-a.x*b.z, + a.x*b.y-a.y*b.x + }) + end, + + length = function(a) + check(a) + local out=a[1]*a[1] + for i=2, #a do + out=out+a[i]*a[i] + end + if type(out)=="vector" then + return out:sqrt() + else + return math.sqrt(out) + end + end, + + len = function(a) + return a:length() + end, + + normalize = function(a) + return a*(1/a:len()) + end, + + round = function(a, t) + check(a) + local ret={} + for i=1, #a do + ret[i]=math.floor((a[i]+t*0.5)/t)*t + end + return lib.convert(ret) + end, + + exp = function(a, e) + check(a) + local ret={} + for i=1, #a do + ret[i]=a^e + end + return lib.convert(ret) + end, + + sqrt = function(a) + check(a) + local ret={} + for i=1, #a do + if type(a[i])=="vector" then + ret[i]=a[i]:sqrt() + else + ret[i]=math.sqrt(a[i]) + end + end + return lib.convert(ret) + end +} + +local idxtable={ + w=4, + x=1, + y=2, + z=3, +} + +local function index(self, k) + if idxtable[k] then + return rawget(self,idxtable[k]) + elseif vector[k] then + return vector[k] + else + return rawget(self,k) + end +end + +local function newindex(self, k, v) + if idxtable[k] then + rawset(self, idxtable[k], v) + else + rawset(self, k, v) + end +end + +local meta={ + __name="vector", + __type="vector", + __usermeta=function() error("EACCES") end, + __index=index, + __newindex=newindex, + __unm=vector.unm, + __add=vector.add, + __sub=vector.sub, + __mul=vector.mul, + __div=vector.div, + __tostring=vector.tostring, + __eq=vector.equals +} + +function lib.new(...) + local vars={...} + return setmetatable(vars,meta) +end + +function lib.convert(vars) + return setmetatable(vars,meta) +end + +return lib \ No newline at end of file diff --git a/Src/math/data/lib/vector b/Src/math/data/lib/vector new file mode 100644 index 0000000..918db98 --- /dev/null +++ b/Src/math/data/lib/vector @@ -0,0 +1,217 @@ +--:Minify:-- +local lib={} + +local function check(a,b,ignoreb) + if type(a)~="vector" then error("a must be vector") end + if not ignoreb and b~=nil then + if type(b)~="vector" then error("b must be vector") end + if #a~=#b then error("vectors must be same size") end + end +end + +local vector={ + add = function(a,b) + check(a,b) + local ret={} + for i=1, #a do + ret[i]=a[i]+b[i] + end + return lib.convert(ret) + end, + + sub = function(a,b) + check(a,b) + if type(b)~="vector" then error("b must be vector") end + local ret={} + for i=1, #a do + ret[i]=a[i]-b[i] + end + return lib.convert(ret) + end, + + unm = function(a) + local ret={} + for i=1, #a do + ret[i]=-a[i] + end + return lib.convert(ret) + end, + + mul = function(a,b) + if type(a)=="number" and type(b)=="vector" then a,b=b,a end + check(a,b,true) + local ret={} + if type(b)=="vector" then + for i=1, #a do + ret[i]=a[i]*b[i] + end + elseif type(b)=="number" then + for i=1, #a do + ret[i]=a[i]*b + end + else + error("b must be vector or number") + end + return lib.convert(ret) + end, + + div = function(a,b) + if type(a)=="number" and type(b)=="vector" then a,b=b,a end + check(a,b,true) + local ret={} + if type(b)=="vector" then + for i=1, #a do + ret[i]=a[i]/b[i] + end + elseif type(b)=="number" then + for i=1, #a do + ret[i]=a[i]/b + end + else + error("b must be vector or number") + end + return lib.convert(ret) + end, + + dot = function(a,b) + check(a,b) + local out=a[1]*b[1] + for i=2, #a do + out=out+a[i]*b[i] + end + return out + end, + + tostring = function(a) + check(a) + local out = "{" + for i=1, #a do + out=out..tostring(a[i])..", " + end + return out:sub(1,#out-2).."}" + end, + + equals = function(a,b) + check(a,b) + for i=1, #a do + if a[i]~=b[i] then + return false + end + end + return true + end, + + cross = function(a,b) + check(a,b) + if #a~=3 then error("Vectors must be of type 'vec3'") end + if #b~=3 then error("Vectors must be of type 'vec3'") end + return lib.convert({ + a.y*b.z-a.z*b.y, + a.z*b.x-a.x*b.z, + a.x*b.y-a.y*b.x + }) + end, + + length = function(a) + check(a) + local out=a[1]*a[1] + for i=2, #a do + out=out+a[i]*a[i] + end + if type(out)=="vector" then + return out:sqrt() + else + return math.sqrt(out) + end + end, + + len = function(a) + return a:length() + end, + + normalize = function(a) + return a*(1/a:len()) + end, + + round = function(a, t) + check(a) + local ret={} + for i=1, #a do + ret[i]=math.floor((a[i]+t*0.5)/t)*t + end + return lib.convert(ret) + end, + + exp = function(a, e) + check(a) + local ret={} + for i=1, #a do + ret[i]=a^e + end + return lib.convert(ret) + end, + + sqrt = function(a) + check(a) + local ret={} + for i=1, #a do + if type(a[i])=="vector" then + ret[i]=a[i]:sqrt() + else + ret[i]=math.sqrt(a[i]) + end + end + return lib.convert(ret) + end +} + +local idxtable={ + w=4, + x=1, + y=2, + z=3, +} + +local function index(self, k) + if idxtable[k] then + return rawget(self,idxtable[k]) + elseif vector[k] then + return vector[k] + else + return rawget(self,k) + end +end + +local function newindex(self, k, v) + if idxtable[k] then + rawset(self, idxtable[k], v) + else + rawset(self, k, v) + end +end + +local meta={ + __name="vector", + __type="vector", + __usermeta=function() error("EACCES") end, + __index=index, + __newindex=newindex, + __unm=vector.unm, + __add=vector.add, + __sub=vector.sub, + __mul=vector.mul, + __div=vector.div, + __tostring=vector.tostring, + __eq=vector.equals +} + +function lib.new(...) + local vars={...} + return setmetatable(vars,meta) +end + +function lib.convert(vars) + return setmetatable(vars,meta) +end + +return lib \ No newline at end of file diff --git a/Src/math/description.txt b/Src/math/description.txt new file mode 100644 index 0000000..97cc442 --- /dev/null +++ b/Src/math/description.txt @@ -0,0 +1,3 @@ +General advanced math libs +VectorX +Matrix diff --git a/Src/math/version.txt b/Src/math/version.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/Src/math/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/Src/render3d/data/bin/render3d b/Src/render3d/data/bin/render3d new file mode 100644 index 0000000..e9910e4 --- /dev/null +++ b/Src/render3d/data/bin/render3d @@ -0,0 +1,124 @@ +local args={...} +if #args<1 then print("Usage: render3d [file.obj]") end +local fs=require("fs") +local vec=require("vector") +local gfx=syscall.devctl(1,"gfx") + +local file = fs.readAllText(args[1]) + +local obj={v={},f={}} +local lines=string.split(file, "\n") + +for i=1, #lines do + local line=lines[i] + if line:sub(1,2)=="v " then + line=line:sub(3) + local s=string.split(line, " ") + obj.v[#obj.v+1]=vec(tonumber(s[1]),tonumber(s[2]),tonumber(s[3])) + elseif line:sub(1,2)=="f " then + line=line:sub(3) + local s=string.split(line, " ") + local vs={} + for c=1, #s do + local v=string.split(s[c], "/") + vs[#vs+1]=tonumber(v[1]) + end + obj.f[#obj.f+1]=vec(table.unpack(vs)) + end +end + +print("Vertices") +for i=1, #obj.v do + print(obj.v[i]) +end + +print("Faces") +for i=1, #obj.f do + print(obj.f[i]) +end + +local function projectPoint(point, cameraPos, cameraRot, fov, width, height) + + local p=point-cameraPos + + local pitch=cameraRot.x + local yaw=cameraRot.y + + local cp=math.cos(pitch) + local sp=math.sin(pitch) + + local cy=math.cos(yaw) + local sy=math.sin(yaw) + + local right=vec( + cy, + 0, + -sy + ) + + local up=vec( + sy*sp, + cp, + cy*sp + ) + + local forward=vec( + -sy*cp, + sp, + -cy*cp + ) + + local x=p:dot(right) + local y=p:dot(up) + local z=p:dot(forward) + + if z<=0 then + return nil + end + + local aspect=width/height + local f=1/math.tan(fov*0.5) + + local sx=(x*f/aspect)/z + local sy=(y*f)/z + + return vec( + (sx+1)*0.5*width, + (1-sy)*0.5*height + ),z + +end + +local proj={} +local camera=vec(0,0,3) +local rot=vec(0,0,0) +local w,h=gfx.size() +local fov=math.rad(90) +for i=1, #obj.v do + proj[i]={} + proj[i].p,proj[i].z=projectPoint(obj.v[i],camera,rot,fov,w,h) +end + +print("Projected") +for i=1, #proj do + print(proj[i].p) +end + +gfx.setMode(true) +for i=#obj.f, 1, -1 do + local f=obj.f[i] + local c=math.random(0,0xffffff) + for p=1, #f do + if p~=#f then + print(tostring(proj[f[p]].p.x)..","..tostring(proj[f[p]].p.y).." > "..tostring(proj[f[p+1]].p.x)..","..tostring(proj[f[p+1]].p.y)) + gfx.line(proj[f[p]].p.x,proj[f[p]].p.y,proj[f[p+1]].p.x,proj[f[p+1]].p.y,c) + else + print(tostring(proj[f[p]].p.x)..","..tostring(proj[f[p]].p.y).." > "..tostring(proj[f[1]].p.x)..","..tostring(proj[f[1]].p.y)) + gfx.line(proj[f[p]].p.x,proj[f[p]].p.y,proj[f[1]].p.x,proj[f[1]].p.y,c) + end + end +end + +while true do + sleep(5) +end \ No newline at end of file diff --git a/Src/render3d/data/usr/local/models/box.obj b/Src/render3d/data/usr/local/models/box.obj new file mode 100644 index 0000000..5f9946d --- /dev/null +++ b/Src/render3d/data/usr/local/models/box.obj @@ -0,0 +1,40 @@ +# Blender 5.2.2 LTS +# www.blender.org +mtllib box.mtl +o Cube +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vt 0.625000 0.500000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.625000 1.000000 +vt 0.375000 1.000000 +vt 0.375000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.250000 +vt 0.375000 0.250000 +vt 0.125000 0.500000 +vt 0.375000 0.500000 +vt 0.125000 0.750000 +s 0 +usemtl Material +f 1/1/1 5/2/1 7/3/1 3/4/1 +f 4/5/2 3/4/2 7/6/2 8/7/2 +f 8/8/3 7/9/3 5/10/3 6/11/3 +f 6/12/4 2/13/4 4/5/4 8/14/4 +f 2/13/5 1/1/5 3/4/5 4/5/5 +f 6/11/6 5/10/6 1/1/6 2/13/6 diff --git a/Src/scomposite/data/lib/gfx b/Src/scomposite/data/lib/gfx new file mode 100644 index 0000000..13bcafc --- /dev/null +++ b/Src/scomposite/data/lib/gfx @@ -0,0 +1,4 @@ +--:Minify:-- +local lib = {} + +return lib \ No newline at end of file diff --git a/Test/HyperionOS-units/bin/hunit b/Test/HyperionOS-units/bin/hunit deleted file mode 100644 index cf6e040..0000000 --- a/Test/HyperionOS-units/bin/hunit +++ /dev/null @@ -1,23 +0,0 @@ -local fs=require("fs") -local units=fs.list("/usr/lib/hunit/") -fs.mkdir("/tmp/hunit/") -local errors={} -for i,v in ipairs(units) do - print("running unit "..v) - local code=fs.readAllText("/usr/lib/hunit/"..v) - local func, err=load(code, "@"..v) - if not func then - print(" [ERROR]:"..err) - end - ---@diagnostic disable-next-line: param-type-mismatch - local ok, err=pcall(func) - if not ok then - print(" [ERROR]:"..err) - table.insert(errors, v) - else - print(" [SUCCESS]") - end -end - -print(tostring(#errors).." units failed") -return 0 \ No newline at end of file diff --git a/Test/HyperionOS-units/bin/looptest b/Test/HyperionOS-units/bin/looptest deleted file mode 100644 index 58e9aa4..0000000 --- a/Test/HyperionOS-units/bin/looptest +++ /dev/null @@ -1,427 +0,0 @@ ---:Minify:-- - -local passed, failed = 0, 0 - -local function pass(msg) syscall.devctl(1,"sfgc",10); print(" PASS "..msg); syscall.devctl(1,"sfgc",1) end -local function fail(msg) syscall.devctl(1,"sfgc",2); print(" FAIL "..msg); syscall.devctl(1,"sfgc",1) end -local function info(msg) syscall.devctl(1,"sfgc",14); print(" .... "..msg); syscall.devctl(1,"sfgc",1) end -local function head(msg) syscall.devctl(1,"sfgc",4); print("\n"..msg); syscall.devctl(1,"sfgc",1) end - -local function check(label, ok, err) - if ok then passed = passed + 1; pass(label) - else failed = failed + 1; fail(label.." - "..tostring(err)) end -end - -local function writeFile(path, data) - local ok, fd = pcall(syscall.open, path, "w") - if not ok then return false, fd end - local ok2, err = pcall(syscall.write, fd, data) - pcall(syscall.close, fd) - return ok2, err -end - -local function readFile(path) - local ok, fd = pcall(syscall.open, path, "r") - if not ok then return false, fd end - local ok2, data = pcall(syscall.read, fd, 65536) - pcall(syscall.close, fd) - return ok2, data -end - -local function rmrf(path) - local t = syscall.type(path) - if t == "directory" then - local ok, entries = pcall(syscall.listdir, path) - if ok then - for _, name in ipairs(entries) do - rmrf(path:gsub("/$","").."/"..name) - end - end - pcall(syscall.remove, path) - elseif t == "file" then - pcall(syscall.remove, path) - end -end - -local SCRATCH = "/tmp/looptest_scratch" -local SRC_DIR = SCRATCH.."/src" -local BIND_MNT = SCRATCH.."/bind_mnt" -local IMG_PATH = SCRATCH.."/test.hfs" -local IMG_MNT = SCRATCH.."/img_mnt" -local BIND_LOOP = nil -local IMG_LOOP = nil - -rmrf(SCRATCH) -pcall(syscall.mkdir, SCRATCH) -pcall(syscall.mkdir, SRC_DIR) -pcall(syscall.mkdir, BIND_MNT) -pcall(syscall.mkdir, IMG_MNT) -pcall(syscall.mkdir, SRC_DIR.."/subdir") - -writeFile(SRC_DIR.."/hello.txt", "hello from hyperion\n") -writeFile(SRC_DIR.."/data.txt", "line1\nline2\nline3\n") -writeFile(SRC_DIR.."/subdir/deep.txt", "deep file\n") - -head("[ 1 ] bind mode - losetup on a directory") -do - local ok, id = pcall(syscall.losetup, SRC_DIR) - check("losetup(dir) returns a loop id", ok and type(id) == "string" and id:sub(1,4) == "loop", id) - if ok then - BIND_LOOP = id - info("attached as "..id) - end -end - -head("[ 2 ] bind mode - mount and read files") -do - if BIND_LOOP then - local mok = pcall(syscall.mount, BIND_MNT, BIND_LOOP) - check("mount(bind_mnt, "..BIND_LOOP..")", mok, "mount failed") - - if mok then - local lok, entries = pcall(syscall.listdir, BIND_MNT) - check("listdir through bind mount", lok and type(entries) == "table", entries) - - local rok, data = readFile(BIND_MNT.."/hello.txt") - check("read hello.txt through bind", rok and data == "hello from hyperion\n", - rok and ("got: "..tostring(data):sub(1,40)) or tostring(data)) - - local rok2, data2 = readFile(BIND_MNT.."/subdir/deep.txt") - check("read subdir/deep.txt through bind", rok2 and data2 == "deep file\n", - rok2 and ("got: "..tostring(data2)) or tostring(data2)) - end - else - check("mount (skipped - no loop id)", false, "losetup failed in [1]") - end -end - -head("[ 3 ] bind mode - write through loop mount, verify on host") -do - if BIND_LOOP then - local wok, werr = writeFile(BIND_MNT.."/written.txt", "written via loop\n") - check("write new file through bind mount", wok, werr) - - local rok, data = readFile(BIND_MNT.."/written.txt") - check("read back through bind mount", rok and data == "written via loop\n", - rok and ("got: "..tostring(data)) or tostring(data)) - - local rok2, data2 = readFile(SRC_DIR.."/written.txt") - check("file visible on host path (bind is transparent)", rok2 and data2 == "written via loop\n", - rok2 and ("got: "..tostring(data2)) or tostring(data2)) - else - check("write (skipped)", false, "bind mount not set up") - end -end - -head("[ 4 ] bind mode - lodetach while mounted returns EBUSY") -do - if BIND_LOOP then - local ok = pcall(syscall.lodetach, BIND_LOOP) - check("lodetach while mounted is refused (EBUSY)", not ok, "should have errored") - else - check("lodetach busy check (skipped)", false, "no bind loop") - end -end - -head("[ 5 ] bind mode - umount then lodetach") -do - if BIND_LOOP then - local uok = pcall(syscall.umount, BIND_MNT) - check("umount(bind_mnt)", uok, "umount failed") - - local dok = pcall(syscall.lodetach, BIND_LOOP) - check("lodetach after umount", dok, "lodetach failed") - - if dok then BIND_LOOP = nil end - else - check("umount+lodetach (skipped)", false, "no bind loop") - end -end - -head("[ 6 ] loimgcreate - serialise directory to HFS image") -do - local ok, imgStr = pcall(syscall.loimgcreate, SRC_DIR) - check("loimgcreate(srcdir) returns a string", ok and type(imgStr) == "string" and #imgStr > 0, imgStr) - - if ok then - info("image size: "..#imgStr.." bytes") - - local isBHFS = imgStr:sub(1, 4) == "BHFS" - check("image has BHFS magic header", isBHFS, - "got: "..imgStr:sub(1,4):gsub(".", function(c) return string.format("%02X ", c:byte()) end)) - check("image has correct version byte (0x01)", imgStr:byte(5) == 1, - "version byte: "..tostring(imgStr:byte(5))) - check("image contains FILE record (type=0x01)", imgStr:find("\001", 9, true) ~= nil, "no FILE type byte found") - check("image contains DIR record (type=0x02)", imgStr:find("\002", 9, true) ~= nil, "no DIR type byte found") - check("image ends with END record (type=0xFF)", imgStr:byte(#imgStr) == 0xFF, - "last byte: 0x"..string.format("%02X", imgStr:byte(#imgStr))) - - local wok, werr = pcall(syscall.loimgwrite, imgStr, IMG_PATH) - check("loimgwrite writes image file", wok, werr) - check("image file exists on disk", syscall.type(IMG_PATH) == "file", "file not found") - end -end - -head("[ 7 ] HFS image - losetup attaches image file") -do - if syscall.type(IMG_PATH) == "file" then - local ok, id = pcall(syscall.losetup, IMG_PATH) - check("losetup(image.hfs) returns loop id", ok and type(id) == "string", id) - if ok then - IMG_LOOP = id - info("image attached as "..id) - - local lok, devs = pcall(syscall.lolist) - local found = false - if lok then - for lid, info_entry in pairs(devs) do - if lid == id then found = true end - end - end - check("lolist() contains new image device", found, "not found in lolist") - end - else - check("losetup image (skipped - no image file)", false, "image not created in [6]") - end -end - -head("[ 8 ] HFS image - mount and read files") -do - if IMG_LOOP then - local mok = pcall(syscall.mount, IMG_MNT, IMG_LOOP) - check("mount(img_mnt, "..IMG_LOOP..")", mok, "mount failed") - - if mok then - local lok, entries = pcall(syscall.listdir, IMG_MNT) - check("listdir through image mount returns table", lok and type(entries) == "table", entries) - if lok then - local hasHello = false - local hasSubdir = false - for _, e in ipairs(entries) do - if e == "hello.txt" then hasHello = true end - if e == "subdir" then hasSubdir = true end - end - check("hello.txt visible in image root", hasHello, "not listed") - check("subdir/ visible in image root", hasSubdir, "not listed") - end - - local rok, data = readFile(IMG_MNT.."/hello.txt") - check("read hello.txt from image", rok and data == "hello from hyperion\n", - rok and ("got: "..tostring(data):sub(1,40)) or tostring(data)) - - local rok2, data2 = readFile(IMG_MNT.."/data.txt") - check("read data.txt from image", rok2 and data2 == "line1\nline2\nline3\n", - rok2 and ("got: "..tostring(data2)) or tostring(data2)) - end - else - check("image mount read (skipped)", false, "no image loop") - end -end - -head("[ 9 ] HFS image - write new files into image mount") -do - if IMG_LOOP then - local wok, werr = writeFile(IMG_MNT.."/newfile.txt", "created inside image\n") - check("write new file into image mount", wok, werr) - - local rok, data = readFile(IMG_MNT.."/newfile.txt") - check("read back newly written file", rok and data == "created inside image\n", - rok and ("got: "..tostring(data)) or tostring(data)) - - local wok2, werr2 = writeFile(IMG_MNT.."/hello.txt", "overwritten\n") - check("overwrite existing file in image", wok2, werr2) - - local rok2, data2 = readFile(IMG_MNT.."/hello.txt") - check("overwritten content reads back correctly", rok2 and data2 == "overwritten\n", - rok2 and ("got: "..tostring(data2)) or tostring(data2)) - - local rok3, orig = readFile(IMG_PATH) - check("disk image file is unchanged after in-memory write", - rok3 and orig and orig:find("/hello%.txt") ~= nil, - rok3 and "filename record missing from image" or tostring(orig)) - else - check("image write test (skipped)", false, "image not mounted") - end -end - -head("[ 10 ] HFS image - sub-directory traversal") -do - if IMG_LOOP then - local t = syscall.type(IMG_MNT.."/subdir") - check("type(subdir) == 'directory'", t == "directory", "got: "..tostring(t)) - - local lok, entries = pcall(syscall.listdir, IMG_MNT.."/subdir") - check("listdir(subdir) works", lok and type(entries) == "table", entries) - - local rok, data = readFile(IMG_MNT.."/subdir/deep.txt") - check("read subdir/deep.txt from image", rok and data == "deep file\n", - rok and ("got: "..tostring(data)) or tostring(data)) - - local mok = pcall(syscall.mkdir, IMG_MNT.."/subdir/newdir") - check("mkdir inside image mount", mok, "mkdir failed") - check("new dir has type 'directory'", - syscall.type(IMG_MNT.."/subdir/newdir") == "directory", - "wrong type") - - local wok, werr = writeFile(IMG_MNT.."/subdir/newdir/x.txt", "x\n") - check("write file in newly created subdir", wok, werr) - else - check("subdir traversal (skipped)", false, "image not mounted") - end -end - -head("[ 11 ] HFS image - lodetach while mounted returns EBUSY") -do - if IMG_LOOP then - local ok = pcall(syscall.lodetach, IMG_LOOP) - check("lodetach image while mounted is refused", not ok, "should have errored EBUSY") - else - check("lodetach busy (skipped)", false, "no image loop") - end -end - -head("[ 12 ] HFS image - umount then lodetach") -do - if IMG_LOOP then - local uok = pcall(syscall.umount, IMG_MNT) - check("umount(img_mnt)", uok, "umount failed") - - local dok = pcall(syscall.lodetach, IMG_LOOP) - check("lodetach after umount", dok, "lodetach failed") - - if dok then - local lok, devs = pcall(syscall.lolist) - local found = false - if lok then - for lid in pairs(devs) do - if lid == IMG_LOOP then found = true end - end - end - check("lolist no longer shows detached device", not found, "still present in lolist") - IMG_LOOP = nil - end - else - check("image umount+lodetach (skipped)", false, "no image loop") - end -end - -head("[ 13 ] lolist - reflects attached device count") -do - local ok1, id1 = pcall(syscall.losetup, SRC_DIR) - local ok2, id2 = pcall(syscall.losetup, SRC_DIR) - check("attach first device for lolist test", ok1, id1) - check("attach second device for lolist test", ok2, id2) - - if ok1 and ok2 then - local lok, devs = pcall(syscall.lolist) - check("lolist() succeeds", lok, devs) - if lok then - local found1, found2 = false, false - for lid in pairs(devs) do - if lid == id1 then found1 = true end - if lid == id2 then found2 = true end - end - check("lolist contains first device", found1, "missing "..id1) - check("lolist contains second device", found2, "missing "..id2) - local count = 0 - for _ in pairs(devs) do count = count + 1 end - info("lolist shows "..count.." device(s)") - end - end - - if ok1 then pcall(syscall.lodetach, id1) end - if ok2 then pcall(syscall.lodetach, id2) end -end - -head("[ 14 ] losetup - non-existent path returns error") -do - local ok = pcall(syscall.losetup, "/tmp/does_not_exist_xyz_looptest") - check("losetup on missing path errors", not ok, "should have errored") -end - -head("[ 15 ] mount - same loop device cannot be mounted twice") -do - local ok, id = pcall(syscall.losetup, SRC_DIR) - check("losetup for double-mount test", ok, id) - if ok then - local m1ok = pcall(syscall.mount, BIND_MNT, id) - check("first mount succeeds", m1ok, "mount failed") - - if m1ok then - local m2ok = pcall(syscall.mount, IMG_MNT, id) - check("second mount of same device is refused", not m2ok, "should have errored EBUSY") - pcall(syscall.umount, BIND_MNT) - end - pcall(syscall.lodetach, id) - end -end - -head("[ 16 ] loimgcreate - on a regular file returns ENOTDIR") -do - local ok = pcall(syscall.loimgcreate, IMG_PATH) - check("loimgcreate on a file errors (ENOTDIR)", not ok, "should have errored") -end - -head("[ 17 ] HFS image - binary round-trip (all byte values)") -do - local bytes = {} - for i = 0, 255 do bytes[i+1] = string.char(i) end - local binData = table.concat(bytes) - - local binSrc = SCRATCH.."/binsrc" - pcall(syscall.mkdir, binSrc) - writeFile(binSrc.."/binary.bin", binData) - - local ok1, imgStr = pcall(syscall.loimgcreate, binSrc) - check("loimgcreate handles binary content", ok1, imgStr) - - if ok1 then - local binImg = SCRATCH.."/binary.hfs" - pcall(syscall.loimgwrite, imgStr, binImg) - - local ok2, lid = pcall(syscall.losetup, binImg) - check("losetup on binary image", ok2, lid) - - if ok2 then - local mnt = SCRATCH.."/binmnt" - pcall(syscall.mkdir, mnt) - local mok = pcall(syscall.mount, mnt, lid) - check("mount binary image", mok, "mount failed") - - if mok then - local rok, readBack = readFile(mnt.."/binary.bin") - check("binary file readable from image", rok, readBack) - check("binary data round-trips without corruption", - rok and readBack == binData, - rok and string.format("length in=%d out=%d", #binData, #(readBack or "")) or tostring(readBack)) - pcall(syscall.umount, mnt) - end - pcall(syscall.lodetach, lid) - end - end -end - -head("[ 18 ] second-run safety - lolist is empty after full cleanup") -do - local lok, devs = pcall(syscall.lolist) - check("lolist() call succeeds", lok, devs) - if lok then - local count = 0 - for _ in pairs(devs) do count = count + 1 end - check("no leftover loop devices after all tests", count == 0, - count.." device(s) still attached: ".. - (function() - local ids = {} - for id in pairs(devs) do ids[#ids+1] = id end - return table.concat(ids, ", ") - end)()) - end -end - -rmrf(SCRATCH) - -print("") -syscall.devctl(1, "sfgc", failed == 0 and 10 or 2) -print(string.format("Results: %d passed, %d failed", passed, failed)) -syscall.devctl(1, "sfgc", 1) -if failed > 0 then syscall.exit(1) end diff --git a/Test/HyperionOS-units/bin/socktest b/Test/HyperionOS-units/bin/socktest deleted file mode 100644 index 026f457..0000000 --- a/Test/HyperionOS-units/bin/socktest +++ /dev/null @@ -1,151 +0,0 @@ ---:Minify:-- -local args = { ... } -local target = args[1] or "http://example.com" - -local function pass(msg) syscall.devctl(1,"sfgc",10); print(" PASS " .. msg); syscall.devctl(1,"sfgc",1) end -local function fail(msg) syscall.devctl(1,"sfgc",2); print(" FAIL " .. msg); syscall.devctl(1,"sfgc",1) end -local function info(msg) syscall.devctl(1,"sfgc",14); print(" .... " .. msg); syscall.devctl(1,"sfgc",1) end -local function head(msg) syscall.devctl(1,"sfgc",4); print("\n" .. msg); syscall.devctl(1,"sfgc",1) end - -local passed, failed = 0, 0 -local function check(name, ok, err) - if ok then passed = passed + 1; pass(name) - else failed = failed + 1; fail(name .. " - " .. tostring(err)) end -end - -head("[ 1 ] socket() creation") -do - local ok, fd = pcall(syscall.socket, "inet", "stream") - check("socket(inet, stream) returns fd", ok and type(fd) == "number", fd) - - if ok then - local cok = pcall(syscall.close, fd) - check("close() on socket fd", cok, "close failed") - end - - local ok2, fd2 = pcall(syscall.socket, "unix", "stream") - check("socket(unix, stream) returns fd", ok2 and type(fd2) == "number", fd2) - if ok2 then pcall(syscall.close, fd2) end - - local ok3 = pcall(syscall.socket, "ax25", "stream") - check("socket(ax25) returns EAFNOSUPPORT", not ok3, "should have errored") -end - -head("[ 2 ] connect() to " .. target) -local sockfd -do - local ok, fd = pcall(syscall.socket, "inet", "stream") - check("socket() before connect", ok, fd) - - if ok then - sockfd = fd - local cok, cerr = pcall(syscall.connect, fd, target) - check("connect(" .. target .. ")", cok, cerr) - end -end - -head("[ 3 ] send() HTTP GET via socket") -do - if sockfd then - local sok, serr = pcall(syscall.send, sockfd, "") - check("send() does not error", sok, serr) - else - check("send() skipped (no socket)", false, "socket creation failed") - end -end - -head("[ 4 ] recv() reads HTTP response") -do - if sockfd then - info("waiting for response (recv blocks up to 10s)...") - local ok, body = pcall(syscall.recv, sockfd, 65536) - check("recv() returns non-empty body", ok and body and #body > 0, - ok and "empty response" or tostring(body)) - if ok and body and #body > 0 then - info("received " .. #body .. " bytes") - local preview = body:sub(1, 120):gsub("\r", ""):gsub("\n", " ") - info("preview: " .. preview) - end - pcall(syscall.close, sockfd) - sockfd = nil - else - check("recv() skipped (no socket)", false, "socket creation failed") - end -end - -head("[ 5 ] httpget() convenience wrapper") -do - info("GET " .. target .. " ...") - local ok, body = pcall(syscall.httpget, target) - check("httpget() succeeds", ok, body) - if ok then - check("httpget() returns non-empty string", type(body) == "string" and #body > 0, "empty") - if type(body) == "string" and #body > 0 then - info("received " .. #body .. " bytes") - local preview = body:sub(1, 120):gsub("\r", ""):gsub("\n", " ") - info("preview: " .. preview) - local hasHtml = body:lower():find(" 0 then syscall.exit(1) end diff --git a/Test/HyperionOS-units/usr/lib/hunit/dir.unit b/Test/HyperionOS-units/usr/lib/hunit/dir.unit deleted file mode 100644 index 1d3c79e..0000000 --- a/Test/HyperionOS-units/usr/lib/hunit/dir.unit +++ /dev/null @@ -1,3 +0,0 @@ -local fs = require("fs") -assert(fs.mkdir("/tmp/hunit/testdir"), "failed to make directory") -assert(fs.isDir("/tmp/hunit/testdir"), "directory does not exist") \ No newline at end of file diff --git a/Test/HyperionOS-units/usr/lib/hunit/file.unit b/Test/HyperionOS-units/usr/lib/hunit/file.unit deleted file mode 100644 index 9467dae..0000000 --- a/Test/HyperionOS-units/usr/lib/hunit/file.unit +++ /dev/null @@ -1,10 +0,0 @@ -local fd = syscall.VFS_open("/tmp/hunit/testfile.txt", "w") -syscall.VFS_write(fd, "This is a test file") -syscall.VFS_close(fd) -local fd = syscall.VFS_open("/tmp/hunit/testfile.txt", "r") -local text = syscall.VFS_read(fd, 64) -syscall.VFS_close(fd) - -if text~="This is a test file" then - error("File failed to write/read") -end \ No newline at end of file diff --git a/build.py b/build.py index f78a39b..d6c55ed 100644 --- a/build.py +++ b/build.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ Usage: - python build.py [--arch cct|oc] [--release|--dev] + python build.py [--arch cct|oc|ac] [--release|--dev] Targets: build @@ -17,6 +17,7 @@ Targets: Arch flags: --arch cct --arch oc + --arch ac Release flags: --release @@ -41,6 +42,7 @@ PROD_ROOT = PROJECT_ROOT / "prod" ARCH_BOOT_DIR = { "cct": Path("boot") / "cct", "oc": Path("boot") / "oc", + "ac": Path("boot") / "ac" } @@ -146,6 +148,7 @@ def install_bootloader(arch: str, release: bool): eeprom = boot_dir / "eeprom" eeprom_dst_name = "startup.lua" if release else "eeprom" + eeprom_dst_name = "uefi.lua" if arch=="ac" else eeprom_dst_name print(f" Installing: eeprom -> Build/{eeprom_dst_name}") shutil.copy2(eeprom, BUILD_ROOT / eeprom_dst_name) @@ -236,7 +239,7 @@ def inject_makeusers(users, arch): def main(): parser = argparse.ArgumentParser(description="HyperionOS build script") parser.add_argument("target", choices=["build", "build-mini", "build-micro", "build-test", "build-mini-test", "build-micro-test", "clean", "prod", "prod-mini"]) - parser.add_argument("--arch", choices=["cct", "oc"], default=None, + parser.add_argument("--arch", choices=["cct", "oc", "ac"], default=None, help="Target architecture") parser.add_argument("--release", dest="release", action="store_true", default=True, help="Release build: eeprom placed as startup.lua (default)") diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..c55cea5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,4 @@ +# Hyperion-OS Docs + +>These docs are a WIP take them as you will + diff --git a/docs/kernel/Syscalls/README.md b/docs/kernel/Syscalls/README.md index 99e3777..cc8cdfb 100644 --- a/docs/kernel/Syscalls/README.md +++ b/docs/kernel/Syscalls/README.md @@ -11,4 +11,5 @@ sleep(ms) print(...) printInline(...) printf(fmt, ...) +userinput(fdin, helpstr, replacestr, fdout) ``` diff --git a/docs/kernel/boot.cfg.md b/docs/kernel/boot.cfg.md index c2ec588..73b5b62 100644 --- a/docs/kernel/boot.cfg.md +++ b/docs/kernel/boot.cfg.md @@ -32,4 +32,13 @@ showModLoad tmpToDisk writes tmp to disk instead of ram + +logSymlinkTraverse + logs symlink traversal (can harm preformance) + +moreLogsaves + enables log debug save points (can harm preformance) + +logPathResolution + logs how a vfs path resolves to a disk path (can harm preformance) ``` \ No newline at end of file diff --git a/manifest.lua b/manifest.lua index b920163..19c2a9a 100644 --- a/manifest.lua +++ b/manifest.lua @@ -1,680 +1,9 @@ ---- @version 1.2.3 ---- @diagnostic disable: missing-return ---- @diagnostic disable: duplicate-set-field +--#region userspace syscall={} ---- @alias userinfo {username:string,homedir:string,shell:string,uid:number,gid:number} ---- Sets home directory of User with corresponding uid to homedir ---- @param uid integer ---- @param homedir string ---- @return true|nil, nil|string -syscall.sethomedir=function(uid, homedir) end +--#endregion userspace ---- Reads amount from fd and returns content or nil ---- @param fd integer ---- @param amount? integer ---- @return string|nil -syscall.read=function(fd, amount) end +--#region kernel ---- Gets information of task with id of pid ----@param pid integer ----@return table|nil -syscall.getTask=function(pid) end - ---- Connects a client socket to a server address ----@param fd integer ----@param address string ----@return boolean, string|nil -syscall.connect=function(fd, address) end - ---- Get current working directory ---- @return string -syscall.getcwd=function() end - ---- Detach loop device (must be unmounted first) ---- @param id string ---- @return boolean, string|nil -syscall.lodetach=function(id) end - ---- Stops task with id of pid ---- @param pid integer ---- @return boolean, string|nil -syscall.stop=function(pid) return true end - ---- Receive bytes from socket (blocking poll, returns "" if no data) ---- @param fd integer ---- @param amount integer ---- @return string -syscall.recv=function(fd, amount) end - ---- Write data to file descriptor ---- @param fd integer ---- @param data string ---- @return boolean, string|nil -syscall.write=function(fd, data) end - ---- Get parent process ID ---- @return integer -syscall.getppid=function() end - ---- Get file information (metadata) ---- @param path string ---- @return table|nil -syscall.lstat=function(path) end - ---- Open a file with mode ("r", "w", etc.) ---- @param path string ---- @param mode string ---- @return integer|nil, string|nil -syscall.open=function(path, mode) end - ---- Seek in a file descriptor ---- @param fd integer ---- @param offset integer ---- @param whence integer ---- @return integer|nil -syscall.lseek=function(fd, offset, whence) end - ---- Set system hostname ---- @param hostname string ---- @return boolean -syscall.setHostname=function(hostname) end - ---- Change root directory ---- @param path string ---- @return boolean, string|nil -syscall.chroot=function(path) end - ---- Duplicate file descriptor ---- @param src integer ---- @param dst integer ---- @return integer|nil, string|nil -syscall.dup2=function(src, dst) end - ---- Get current process ID ---- @return integer -syscall.getpid=function() end - ---- Change ownership of a file descriptor ---- @param fd integer ---- @param uid integer ---- @param gid integer ---- @return boolean, string|nil -syscall.fchown=function(fd, uid, gid) end - ---- Close a file descriptor ---- @param fd integer ---- @return boolean, string|nil -syscall.close=function(fd) end - ---- Unmount a target ---- @param target string ---- @return boolean, string|nil -syscall.umount=function(target) end - ---- Get all task IDs ---- @return integer[] -syscall.getTasks=function() end - ---- Dump all syscalls for debugging ---- @return table -syscall.sysdump=function() end - ---- Change permissions of a file descriptor ---- @param fd integer ---- @param perms integer ---- @return boolean, string|nil -syscall.fchmod=function(fd, perms) end - ---- Get system hostname ---- @return string -syscall.getHostname=function() end - ---- Listen for incoming connections ---- @param fd integer ---- @param backlog integer ---- @return boolean, string|nil -syscall.listen=function(fd, backlog) end - ---- Duplicate a file descriptor ---- @param fd integer ---- @return integer|nil -syscall.dup=function(fd) end - ---- Read GPIO pin ---- @param pin integer ---- @return boolean|nil -syscall.gpio_read=function(pin) end - ---- Read GPIO pin analog ---- @param pin integer ---- @return number|nil -syscall.gpio_readAnalog=function(pin) end - ---- Get SUID bit from fd ---- @param fd integer ---- @return boolean -syscall.fget_suid=function(fd) end - ---- Write GPIO pin ---- @param pin integer ---- @param data boolean -syscall.gpio_write=function(pin, data) end - ---- Write GPIO pin analog ---- @param pin integer ---- @param data number -syscall.gpio_writeAnalog=function(pin, data) end - ---- Set password for user ---- @param uid integer ---- @param newPassword string ---- @return boolean, string|nil -syscall.setpassword=function(uid, newPassword) end - ---- Set environment variable ---- @param key string ---- @param value any ---- @return boolean -syscall.setEnviron=function(key, value) end - ---- Setup a loop device with filePath ---- @param filePath string ---- @param forceImage boolean ---- @return string|nil, string|nil -syscall.losetup=function(filePath, forceImage) end - ---- Reboot the system -syscall.reboot=function() end - ---- Get current user ID ---- @return integer -syscall.getuid=function() end - ---- Send signal to task ---- @param pid integer ---- @param sigid integer|string ---- @return boolean, string|nil -syscall.sigsend=function(pid, sigid) end - ---- Sleep current task for time seconds ---- @param time number -syscall.sleep=function(time) end - ---- Exit current task ---- @param code integer|nil -syscall.exit=function(code) end - ---- Get environment variable ---- @param key string ---- @return any -syscall.getEnviron=function(key) end - ---- Continue a stopped task ---- @param pid integer ---- @return boolean, string|nil -syscall.continue=function(pid) end - ---- Create a socket ---- @param domain integer ---- @param socktype integer ---- @return integer|nil -syscall.socket=function(domain, socktype) end - ---- Log a message ---- @param text string ---- @param tag string ---- @param color integer -syscall.log=function(text, tag, color) end - ---- Write an image to disk ---- @param imgStr string ---- @param destPath string ---- @return boolean, string|nil -syscall.loimgwrite=function(imgStr, destPath) end - ---- Check if file exists ---- @param path string ---- @return boolean -syscall.exists=function(path) end - ---- Set user ID of current task ---- @param uid integer ---- @return boolean, string|nil -syscall.setuid=function(uid) end - ---- Replace current task with executable ---- @param path string ---- @param args? table ---- @param envars? table -syscall.exec=function(path, args, envars) end - ---- Spawn a new task from executable ---- @param path string ---- @param name? string ---- @param envars? table ---- @param args? table ---- @param tgid? integer ---- @return integer -syscall.execspawn=function(path, name, envars, args, tgid) end - ---- Create image from file ---- @param srcPath string ---- @return string|nil -syscall.loimgcreate=function(srcPath) end - ---- Get system time in ms ---- @return number -syscall.time=function() end - ---- Create a new user ---- @param username string ---- @param password string ---- @param gid integer ---- @param homedir string ---- @param shell string ---- @return integer|nil -syscall.newuser=function(username, password, gid, homedir, shell) end - ---- Spawn a new task from function ---- @param func function ---- @param name? string ---- @param envars? table ---- @param args? table ---- @param tgid? integer ---- @return integer -syscall.spawn=function(func, name, envars, args, tgid) end - ---- Collect exit code of a dead child task ---- @param pid integer ---- @return boolean, integer|string -syscall.collect=function(pid) end - ---- Set shell of user ---- @param uid integer ---- @param shell string ---- @return boolean -syscall.setshell=function(uid, shell) end - ---- Device control ---- @param fd integer ---- @param funcname string ---- @param ... any ---- @return any -syscall.devctl=function(fd, funcname, ...) end - ---- List all users ---- @return table -syscall.listusers=function() end - ---- Unlock a user account ---- @param uid integer ---- @return boolean -syscall.unlockuser=function(uid) end - ---- Mount a disk or loop device ---- @param target string ---- @param diskOrId string ---- @return boolean, string|nil -syscall.mount=function(target, diskOrId) end - ---- Accept a client connection on a socket ---- @param fd integer ---- @return integer|nil -syscall.accept=function(fd) end - ---- List loop devices ---- @return table -syscall.lolist=function() end - ---- Read a symbolic link ---- @param path string ---- @return string|nil -syscall.readlink=function(path) end - ---- Delete a user ---- @param uid integer ---- @return boolean -syscall.deleteuser=function(uid) end - ---- Remove a file ---- @param path string ---- @return boolean, string|nil -syscall.remove=function(path) end - ---- Get type of a path (file, dir, link) ---- @param path string ---- @return string|nil -syscall.type=function(path) end - ---- Elevate to root with password (Disabled due to VULN) ---- @param targetUsername string ---- @param password string ---- @return boolean -syscall.elevate=function(targetUsername, password) end - ---- Make a directory ---- @param path string ---- @return boolean, string|nil -syscall.mkdir=function(path) end - ---- Get UID by username ---- @param username string ---- @return integer|nil -syscall.getuidbyname=function(username) end - ---- Get current user name ---- @return string -syscall.whoami=function() end - ---- Send file content ---- @param src string ---- @param dest string ---- @param amount integer ---- @return boolean, string|nil -syscall.sendfile=function(src, dest, amount) end - ---- Change username of user ---- @param uid integer ---- @param newUsername string ---- @return boolean -syscall.setusername=function(uid, newUsername) end - ---- Get effective UID ---- @return integer -syscall.geteuid=function() end - ---- Login as user ---- @param uid integer ---- @param password string ---- @return boolean -syscall.login=function(uid, password) end - ---- Get system hostname ---- @return string -syscall.getHost=function() end - ---- Get system uptime in ms ---- @return number -syscall.getUptime=function() end - ---- HTTP GET request ---- @param url string ---- @param headers table|nil ---- @return string|nil -syscall.httpget=function(url, headers) end - ---- Get file metadata ---- @param path string ---- @return table|nil -syscall.stat=function(path) end - ---- Create symbolic link ---- @param target string ---- @param linkPath string ---- @return boolean, string|nil -syscall.symlink=function(target, linkPath) end - ---- Read from fd at offset ---- @param fd integer ---- @param count integer ---- @param offset integer ---- @return string|nil -syscall.pread=function(fd, count, offset) end - ---- Change current working directory ---- @param path string ---- @return boolean, string|nil -syscall.chdir=function(path) end - ---- Get system architecture ---- @return string -syscall.arch=function() end - ---- Write to fd at offset ---- @param fd integer ---- @param data string ---- @param offset integer ---- @return boolean, string|nil -syscall.pwrite=function(fd, data, offset) end - ---- Shutdown socket ---- @param fd integer ---- @return boolean, string|nil -syscall.sockshutdown=function(fd) end - ---- Resolve hostname to IP ---- @param hostname string ---- @return string|nil -syscall.resolve=function(hostname) end - ---- Send data over socket ---- @param fd integer ---- @param data string ---- @return boolean, string|nil -syscall.send=function(fd, data) end - ---- Get file descriptor info ---- @param fd integer ---- @return table|nil -syscall.fstat=function(fd) end - ---- Change ownership of path ---- @param path string ---- @param uid integer ---- @param gid integer ---- @return boolean, string|nil -syscall.chown=function(path, uid, gid) end - ---- Flush file descriptor ---- @param fd integer ---- @return boolean, string|nil -syscall.fsync=function(fd) end - ---- Lock user account ---- @param uid integer ---- @return boolean -syscall.lockuser=function(uid) end - ---- Get username by UID ---- @param uid integer ---- @return string|nil -syscall.getUsername=function(uid) end - ---- Get socket name ---- @param fd integer ---- @return string|nil -syscall.getsockname=function(fd) end - ---- Bind socket to address ---- @param fd integer ---- @param address string ---- @return boolean, string|nil -syscall.bind=function(fd, address) end - ---- Kill a task ---- @param pid integer ---- @return boolean, string|nil -syscall.kill=function(pid) end - ---- Set GID for user ---- @param uid integer ---- @param gid integer ---- @return boolean -syscall.setgid=function(uid, gid) end - ---- Get peer name of socket ---- @param fd integer ---- @return string|nil -syscall.getpeername=function(fd) end - ---- Set signal handler ---- @param handler function -syscall.sigcatch=function(handler) end - ---- Shutdown the system -syscall.shutdown=function() end - ---- Check file access mode ---- @param path string ---- @param mode string ---- @return boolean -syscall.access=function(path, mode) end - ---- Ignore current signal -syscall.sigignore=function() end - ---- Get user information ---- @param uid integer ---- @return userinfo|nil -syscall.getpasswd=function(uid) end - ---- Get OS version ---- @return string -syscall.version=function() end - ---- Change file permissions ---- @param path string ---- @param perms integer ---- @return boolean -syscall.chmod=function(path, perms) end - ---- List directory contents ---- @param path string ---- @return table -syscall.listdir=function(path) end - - ----------------------------------------------- ---- STDLib manifest ----------------------------------------------- - ---- Gets the index of value or -1 ---- @param tabl table ---- @param value string|integer ---- @return integer -table.indexOf=function(tabl, value) end - --- Returns true if tabl has key else false ---- @param tabl table ---- @param query string ---- @return boolean -table.hasKey=function(tabl, query) end - ---- Returns true if tabl has value else false ---- @param tabl table ---- @param query any ---- @return boolean -table.hasVal=function(tabl, query) end - ---- Creates a deepcopy of tabl ---- @param tabl table ---- @return table -table.deepcopy=function(tabl) end - ---- Returns the keys of tabl ---- @param tabl table ---- @return table -table.keys=function(tabl) end - ---- Returns the values of tabl ---- @param tabl table ---- @return table -table.values=function(tabl) end - ---- Returns a serialized version of tabl ---- @param tabl table ---- @return string -table.serialize=function(tabl) end - ---- Returns a merged table with a and b ---- @param ... table ---- @return table -table.merge=function(...) end - ---- Gets prefix of string with suffix ---- @param str string ---- @param suffix string ---- @return string -string.getPrefix=function(str, suffix) end - ---- Gets suffix of string with prefix ---- @param str string ---- @param prefix string ---- @return string -string.getSuffix=function(str, prefix) end - ---- Returns if sting has prefix ---- @param str string ---- @param prefix string ---- @return boolean -string.hasPrefix=function(str, prefix) end - ---- Returns if sting has suffix ---- @param str string ---- @param suffix string ---- @return boolean -string.hasSuffix=function(str, suffix) end - ---- Joins all args ---- @param str string ---- @param ... string ---- @return string -string.join=function(str, ...) end - ---- Joins all strings with delim ---- @param delim string ---- @param ... string ---- @return string -string.delim=function(delim, ...) end - ---- Splits a string by delim ---- @param str string ---- @param delim string ---- @return table -string.split=function(str, delim) end - ---- Replaces all instances of target with repl ---- @param str string ---- @param target string ---- @param repl string ---- @return string -string.replace=function(str, target, repl) end - ---- Converts a number to hex ---- @param num integer ---- @return string -toHex=function(num) end - ---- Returns if obj is equal to all in ... ---- @param obj any ---- @param ... any ---- @return boolean -isEqualToAll=function(obj, ...) end - ---- Returns if obj is equal to any in ... ---- @param obj any ---- @param ... any ---- @return boolean -isEqualToAny=function(obj, ...) end - ---- Prints text to stdout ---- @param ... any -print=function(...) end - ---- Prints text to stdout but with no trailing newline ---- @param ... any -printInline=function(...) end - ---- Prints text to stdout with format ---- @param fmt string ---- @param ... any -printf=function(fmt, ...) end - ---- Gets input from fd ---- @param fd integer ---- @param helpstr string ---- @param replacechar string ---- @param fdo integer -userinput=function(fd, helpstr, replacechar, fdo) end \ No newline at end of file +--#endregion kernel \ No newline at end of file diff --git a/misc/json b/misc/json deleted file mode 100644 index 484c997..0000000 --- a/misc/json +++ /dev/null @@ -1,388 +0,0 @@ ---:Minify:-- --- json.lua --- --- Copyright (c) 2020 rxi --- --- Permission is hereby granted, free of charge, to any person obtaining a copy of --- this software and associated documentation files (the "Software"), to deal in --- the Software without restriction, including without limitation the rights to --- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies --- of the Software, and to permit persons to whom the Software is furnished to do --- so, subject to the following conditions: --- --- The above copyright notice and this permission notice shall be included in all --- copies or substantial portions of the Software. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --- SOFTWARE. --- - -local json = { _version = "0.1.2" } - -------------------------------------------------------------------------------- --- Encode -------------------------------------------------------------------------------- - -local encode - -local escape_char_map = { - [ "\\" ] = "\\", - [ "\"" ] = "\"", - [ "\b" ] = "b", - [ "\f" ] = "f", - [ "\n" ] = "n", - [ "\r" ] = "r", - [ "\t" ] = "t", -} - -local escape_char_map_inv = { [ "/" ] = "/" } -for k, v in pairs(escape_char_map) do - escape_char_map_inv[v] = k -end - - -local function escape_char(c) - return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) -end - - -local function encode_nil(val) - return "null" -end - - -local function encode_table(val, stack) - local res = {} - stack = stack or {} - - -- Circular reference? - if stack[val] then error("circular reference") end - - stack[val] = true - - if rawget(val, 1) ~= nil or next(val) == nil then - -- Treat as array -- check keys are valid and it is not sparse - local n = 0 - for k in pairs(val) do - if type(k) ~= "number" then - error("invalid table: mixed or invalid key types") - end - n = n + 1 - end - if n ~= #val then - error("invalid table: sparse array") - end - -- Encode - for i, v in ipairs(val) do - table.insert(res, encode(v, stack)) - end - stack[val] = nil - return "[" .. table.concat(res, ",") .. "]" - - else - -- Treat as an object - for k, v in pairs(val) do - if type(k) ~= "string" then - error("invalid table: mixed or invalid key types") - end - table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) - end - stack[val] = nil - return "{" .. table.concat(res, ",") .. "}" - end -end - - -local function encode_string(val) - return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' -end - - -local function encode_number(val) - -- Check for NaN, -inf and inf - if val ~= val or val <= -math.huge or val >= math.huge then - error("unexpected number value '" .. tostring(val) .. "'") - end - return string.format("%.14g", val) -end - - -local type_func_map = { - [ "nil" ] = encode_nil, - [ "table" ] = encode_table, - [ "string" ] = encode_string, - [ "number" ] = encode_number, - [ "boolean" ] = tostring, -} - - -encode = function(val, stack) - local t = type(val) - local f = type_func_map[t] - if f then - return f(val, stack) - end - error("unexpected type '" .. t .. "'") -end - - -function json.encode(val) - return ( encode(val) ) -end - - -------------------------------------------------------------------------------- --- Decode -------------------------------------------------------------------------------- - -local parse - -local function create_set(...) - local res = {} - for i = 1, select("#", ...) do - res[ select(i, ...) ] = true - end - return res -end - -local space_chars = create_set(" ", "\t", "\r", "\n") -local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") -local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") -local literals = create_set("true", "false", "null") - -local literal_map = { - [ "true" ] = true, - [ "false" ] = false, - [ "null" ] = nil, -} - - -local function next_char(str, idx, set, negate) - for i = idx, #str do - if set[str:sub(i, i)] ~= negate then - return i - end - end - return #str + 1 -end - - -local function decode_error(str, idx, msg) - local line_count = 1 - local col_count = 1 - for i = 1, idx - 1 do - col_count = col_count + 1 - if str:sub(i, i) == "\n" then - line_count = line_count + 1 - col_count = 1 - end - end - error( string.format("%s at line %d col %d", msg, line_count, col_count) ) -end - - -local function codepoint_to_utf8(n) - -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa - local f = math.floor - if n <= 0x7f then - return string.char(n) - elseif n <= 0x7ff then - return string.char(f(n / 64) + 192, n % 64 + 128) - elseif n <= 0xffff then - return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) - elseif n <= 0x10ffff then - return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, - f(n % 4096 / 64) + 128, n % 64 + 128) - end - error( string.format("invalid unicode codepoint '%x'", n) ) -end - - -local function parse_unicode_escape(s) - local n1 = tonumber( s:sub(1, 4), 16 ) - local n2 = tonumber( s:sub(7, 10), 16 ) - -- Surrogate pair? - if n2 then - return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) - else - return codepoint_to_utf8(n1) - end -end - - -local function parse_string(str, i) - local res = "" - local j = i + 1 - local k = j - - while j <= #str do - local x = str:byte(j) - - if x < 32 then - decode_error(str, j, "control character in string") - - elseif x == 92 then -- `\`: Escape - res = res .. str:sub(k, j - 1) - j = j + 1 - local c = str:sub(j, j) - if c == "u" then - local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) - or str:match("^%x%x%x%x", j + 1) - or decode_error(str, j - 1, "invalid unicode escape in string") - res = res .. parse_unicode_escape(hex) - j = j + #hex - else - if not escape_chars[c] then - decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") - end - res = res .. escape_char_map_inv[c] - end - k = j + 1 - - elseif x == 34 then -- `"`: End of string - res = res .. str:sub(k, j - 1) - return res, j + 1 - end - - j = j + 1 - end - - decode_error(str, i, "expected closing quote for string") -end - - -local function parse_number(str, i) - local x = next_char(str, i, delim_chars) - local s = str:sub(i, x - 1) - local n = tonumber(s) - if not n then - decode_error(str, i, "invalid number '" .. s .. "'") - end - return n, x -end - - -local function parse_literal(str, i) - local x = next_char(str, i, delim_chars) - local word = str:sub(i, x - 1) - if not literals[word] then - decode_error(str, i, "invalid literal '" .. word .. "'") - end - return literal_map[word], x -end - - -local function parse_array(str, i) - local res = {} - local n = 1 - i = i + 1 - while 1 do - local x - i = next_char(str, i, space_chars, true) - -- Empty / end of array? - if str:sub(i, i) == "]" then - i = i + 1 - break - end - -- Read token - x, i = parse(str, i) - res[n] = x - n = n + 1 - -- Next token - i = next_char(str, i, space_chars, true) - local chr = str:sub(i, i) - i = i + 1 - if chr == "]" then break end - if chr ~= "," then decode_error(str, i, "expected ']' or ','") end - end - return res, i -end - - -local function parse_object(str, i) - local res = {} - i = i + 1 - while 1 do - local key, val - i = next_char(str, i, space_chars, true) - -- Empty / end of object? - if str:sub(i, i) == "}" then - i = i + 1 - break - end - -- Read key - if str:sub(i, i) ~= '"' then - decode_error(str, i, "expected string for key") - end - key, i = parse(str, i) - -- Read ':' delimiter - i = next_char(str, i, space_chars, true) - if str:sub(i, i) ~= ":" then - decode_error(str, i, "expected ':' after key") - end - i = next_char(str, i + 1, space_chars, true) - -- Read value - val, i = parse(str, i) - -- Set - res[key] = val - -- Next token - i = next_char(str, i, space_chars, true) - local chr = str:sub(i, i) - i = i + 1 - if chr == "}" then break end - if chr ~= "," then decode_error(str, i, "expected '}' or ','") end - end - return res, i -end - - -local char_func_map = { - [ '"' ] = parse_string, - [ "0" ] = parse_number, - [ "1" ] = parse_number, - [ "2" ] = parse_number, - [ "3" ] = parse_number, - [ "4" ] = parse_number, - [ "5" ] = parse_number, - [ "6" ] = parse_number, - [ "7" ] = parse_number, - [ "8" ] = parse_number, - [ "9" ] = parse_number, - [ "-" ] = parse_number, - [ "t" ] = parse_literal, - [ "f" ] = parse_literal, - [ "n" ] = parse_literal, - [ "[" ] = parse_array, - [ "{" ] = parse_object, -} - - -parse = function(str, idx) - local chr = str:sub(idx, idx) - local f = char_func_map[chr] - if f then - return f(str, idx) - end - decode_error(str, idx, "unexpected character '" .. chr .. "'") -end - - -function json.decode(str) - if type(str) ~= "string" then - error("expected argument of type string, got " .. type(str)) - end - local res, idx = parse(str, next_char(str, 1, space_chars, true)) - idx = next_char(str, idx, space_chars, true) - if idx <= #str then - decode_error(str, idx, "trailing garbage") - end - return res -end - - -return json \ No newline at end of file diff --git a/misc/spm.lua b/misc/spm.lua deleted file mode 100644 index bca07a8..0000000 --- a/misc/spm.lua +++ /dev/null @@ -1,55 +0,0 @@ -local cloptions = { - a = false, - h = false, - l = false, - help = false, -} -local inpArgs = { ... } -local args = {} - -for _, v in pairs(inpArgs) do - if v:sub(1, 2) == "--" then - local opt = v:sub(3) - if cloptions[opt] == nil then - print("spm: unrecognized option '" .. v .. "'.") - print("try 'spm --help' for more information.") - return - end - cloptions[opt] = true - elseif v:sub(1, 1) == "-" then - for i = 2, #v do - local opt = v:sub(i, i) - if cloptions[opt] == nil then - print("spm: invalid option '-" .. opt .. "'.") - print("try 'spm --help' for more information.") - return - end - cloptions[opt] = true - end - else - table.insert(args, v) - end -end - -local http=http or require("http") -local json=json or require("json") -local xz =xz or require("xz") - -if cloptions.help then - print("Usage: spm [COMMAND] [OPTION] [packages]") - print("The Simple package Mannager.") - print("") - print("Commands:") - print(" remove Remove package(s)") - print(" update Updates package(s)") - print(" install Install package(s)") - print(" sync Syncs local registry with servers") - print("") - print("Options:") - print(" --help display this help and exit") - return -end - -local function getustar() - -end \ No newline at end of file diff --git a/misc/xz b/misc/xz deleted file mode 100644 index 6254bfc..0000000 --- a/misc/xz +++ /dev/null @@ -1,1973 +0,0 @@ ---[[ - XZ/LZMA decompressor ported from https://github.com/pts/muxzcat - Licensed under GNU GPL 2.0 or later - This should work under all Lua 5.1+ - To use: - muxzcat.DecompressXzOrLzmaFile(input, output) will read an XZ/LZMA file from input (FILE* or path) and write the result to output (FILE* or path) - muxzcat.DecompressXzOrLzmaString(input) will decompress a loaded XZ/LZMA file and returns the result - muxzcat.GetError(num) will return a string representation for an error code - muxzcat.ErrorCodes is a table that reverses GetError() - Written by pts@fazekas.hu at Sat Feb 2 13:28:42 CET 2019 - Ported to Lua by JackMacWindows -]] - -local bitlib -if bit32 ~= nil then bitlib = bit32 -elseif pcall(require, "bit32") then bitlib = require "bit32" -elseif pcall(require, "bit") then bitlib = require "bit" -elseif bit ~= nil then bitlib = bit -else - --[[--------------- - LuaBit v0.4 - ------------------- - a bitwise operation lib for lua. - - http: - - How to use: - ------------------- - bit.bnot(n) -- bitwise not (~n) - bit.band(m, n) -- bitwise and (m & n) - bit.bor(m, n) -- bitwise or (m | n) - bit.bxor(m, n) -- bitwise xor (m ^ n) - bit.brshift(n, bits) -- right shift (n >> bits) - bit.blshift(n, bits) -- left shift (n << bits) - bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>) - - Please note that bit.brshift and bit.blshift only support number within - 32 bits. - - 2 utility functions are provided too: - bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence) - -- high bits first - bit.tonumb(bit_tbl) -- convert a bit table into a number - ------------------- - - Under the MIT license. - - copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com) - --]]--------------- - ------------------------ - -- bit lib implementions - - local function check_int(n) - -- checking not float - if(n - math.floor(n) > 0) then - error("trying to use bitwise operation on non-integer!") - end - end - - local function to_bits(n) - check_int(n) - if(n < 0) then - -- negative - return to_bits(bitlib.bnot(math.abs(n)) + 1) - end - -- to bits table - local tbl = {} - local cnt = 1 - while (n > 0) do - local last = math.mod(n,2) - if(last == 1) then - tbl[cnt] = 1 - else - tbl[cnt] = 0 - end - n = (n-last)/2 - cnt = cnt + 1 - end - - return tbl - end - - local function tbl_to_number(tbl) - local n = table.getn(tbl) - - local rslt = 0 - local power = 1 - for i = 1, n do - rslt = rslt + tbl[i]*power - power = power*2 - end - - return rslt - end - - local function expand(tbl_m, tbl_n) - local big = {} - local small = {} - if(table.getn(tbl_m) > table.getn(tbl_n)) then - big = tbl_m - small = tbl_n - else - big = tbl_n - small = tbl_m - end - -- expand small - for i = table.getn(small) + 1, table.getn(big) do - small[i] = 0 - end - - end - - local function bit_or(m, n) - local tbl_m = to_bits(m) - local tbl_n = to_bits(n) - expand(tbl_m, tbl_n) - - local tbl = {} - local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) - for i = 1, rslt do - if(tbl_m[i]== 0 and tbl_n[i] == 0) then - tbl[i] = 0 - else - tbl[i] = 1 - end - end - - return tbl_to_number(tbl) - end - - local function bit_and(m, n) - local tbl_m = to_bits(m) - local tbl_n = to_bits(n) - expand(tbl_m, tbl_n) - - local tbl = {} - local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) - for i = 1, rslt do - if(tbl_m[i]== 0 or tbl_n[i] == 0) then - tbl[i] = 0 - else - tbl[i] = 1 - end - end - - return tbl_to_number(tbl) - end - - local function bit_not(n) - - local tbl = to_bits(n) - local size = math.max(table.getn(tbl), 32) - for i = 1, size do - if(tbl[i] == 1) then - tbl[i] = 0 - else - tbl[i] = 1 - end - end - return tbl_to_number(tbl) - end - - local function bit_xor(m, n) - local tbl_m = to_bits(m) - local tbl_n = to_bits(n) - expand(tbl_m, tbl_n) - - local tbl = {} - local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n)) - for i = 1, rslt do - if(tbl_m[i] ~= tbl_n[i]) then - tbl[i] = 1 - else - tbl[i] = 0 - end - end - - --table.foreach(tbl, --print) - - return tbl_to_number(tbl) - end - - local function bit_rshift(n, bits) - check_int(n) - - local high_bit = 0 - if(n < 0) then - -- negative - n = bit_not(math.abs(n)) + 1 - high_bit = 2147483648 -- 0x80000000 - end - - for i=1, bits do - n = n/2 - n = bit_or(math.floor(n), high_bit) - end - return math.floor(n) - end - - -- logic rightshift assures zero filling shift - local function bit_logic_rshift(n, bits) - check_int(n) - if(n < 0) then - -- negative - n = bit_not(math.abs(n)) + 1 - end - for i=1, bits do - n = n/2 - end - return math.floor(n) - end - - local function bit_lshift(n, bits) - check_int(n) - - if(n < 0) then - -- negative - n = bit_not(math.abs(n)) + 1 - end - - for i=1, bits do - n = n*2 - end - return bit_and(n, 4294967295) -- 0xFFFFFFFF - end - - -------------------- - -- bit lib interface - - bitlib = { - -- bit operations - bnot = bit_not, - band = bit_and, - bor = bit_or, - bxor = bit_xor, - brshift = bit_rshift, - blshift = bit_lshift, - blogic_rshift = bit_logic_rshift, - } -end -if bitlib.blogic_rshift then - bitlib = { - arshift = bitlib.brshift, - band = bitlib.band, - bnot = bitlib.bnot, - bor = bitlib.bor, - btest = function(a, b) return bitlib.band(a, b) ~= 0 end, - bxor = bitlib.bxor, - lshift = bitlib.blshift, - rshift = bitlib.blogic_rshift - } -end - -local band = {} -local bor = {} -local bxor = {} -local bnot = {} -local blshift = {} -local brshift = {} - -setmetatable(band, {__sub = function(lhs) - local mt = {lhs, __sub = function(self, b) return bitlib.band(self[1], b) end} - return setmetatable(mt, mt) -end}) - -setmetatable(bor, {__sub = function(lhs) - local mt = {lhs, __sub = function(self, b) return bitlib.bor(self[1], b) end} - return setmetatable(mt, mt) -end}) - -setmetatable(bxor, {__sub = function(lhs) - local mt = {lhs, __sub = function(self, b) return bitlib.bxor(self[1], b) end} - return setmetatable(mt, mt) -end}) - -setmetatable(blshift, {__sub = function(lhs) - local mt = {lhs, __sub = function(self, b) return bitlib.lshift(self[1], b) end} - return setmetatable(mt, mt) -end}) - -setmetatable(brshift, {__sub = function(lhs) - local mt = {lhs, __sub = function(self, b) return bitlib.rshift(self[1], b) end} - return setmetatable(mt, mt) -end}) - -setmetatable(bnot, {__sub = function(_, rhs) return bitlib.bnot(rhs) end}) - -local str_input, str_output - -local function writeTableSeq(tab, i, n, ...) if n ~= nil then tab[i] = n return writeTableSeq(tab, i+1, ...) end end - -local stdin=0 -local stdout=1 - -local function READ_FROM_STDIN_TO_ARY8(a, fromIdx, size) - local str - if str_input then - str, str_input = str_input:sub(1, size), str_input:sub(size+1) - for i = 1, #str, 256 do writeTableSeq(a, fromIdx + i - 1, str:byte(i, i + 256)) end - return #str - else - str = syscall.read(stdin,size) - for i = 1, #str, 256 do writeTableSeq(a, fromIdx + i - 1, str:byte(i, i + 256)) end - --assert(#a - fromIdx == #str - 1, (#a - fromIdx) .. ", " .. #str .. ", " .. size) - return #str - end -end - -local function readTableSeq(tab, i, j) if i == j then return tab[i] elseif i > j then return nil else return tab[i], readTableSeq(tab, i+1, j) end end - -local function WRITE_TO_STDOUT_FROM_ARY8(a, fromIdx, size) - if str_output then - for i = fromIdx, fromIdx + size - 1, 256 do str_output = str_output .. string.char(readTableSeq(a, i, math.min(fromIdx + size - 1, i + 255))) end - return size - else - for i = 1, size, 256 do syscall.write(stdout,string.char(readTableSeq(a, i+fromIdx-1, math.min(fromIdx + size - 1, i + fromIdx + 254)))) end - return size - end -end - -local bufCur = 0; -local dicSize = 0; -local range = 0; -local code = 0; -local dicPos = 0; -local dicBufSize = 0; -local processedPos = 0; -local checkDicSize = 0; -local state = 0; -local rep0 = 1; -local rep1 = 1; -local rep2 = 1; -local rep3 = 1; -local remainLen = 0; -local tempBufSize = 0; -local readCur = 0; -local readEnd = 0; -local needFlush = 0; -local needInitLzma = 0; -local needInitDic = 0; -local needInitState = 0; -local needInitProp = 0; -local lc = 0; -local lp = 0; -local pb = 0; -local lcm8 = 0; -local _probs16 = {} -local probs16 = setmetatable({}, {__index = function(_, idx) return _probs16[idx] --[[-band- 0xFFFF]] end, __newindex = function(_, idx, val) _probs16[idx] = val -band- 0xFFFF end}); -local _readBuf8 = {} -local readBuf8 = setmetatable({}, {__index = function(_, idx) return _readBuf8[idx] --[[-band- 0xFF]] end, __newindex = function(_, idx, val) _readBuf8[idx] = val -band- 0xFF end}); -local _dic8 = {} -local dic8 = setmetatable({}, {__index = function(_, idx) return _dic8[idx] --[[-band- 0xFF]] end, __newindex = function(_, idx, val) _dic8[idx] = val -band- 0xFF end}); - -local function ResetGlobals() - bufCur = 0; - dicSize = 0; - range = 0; - code = 0; - dicPos = 0; - dicBufSize = 0; - processedPos = 0; - checkDicSize = 0; - state = 0; - rep0 = 1; - rep1 = 1; - rep2 = 1; - rep3 = 1; - remainLen = 0; - tempBufSize = 0; - readCur = 0; - readEnd = 0; - needFlush = 0; - needInitLzma = 0; - needInitDic = 0; - needInitState = 0; - needInitProp = 0; - lc = 0; - lp = 0; - pb = 0; - lcm8 = 0; - _probs16 = {} - _readBuf8 = {} - _dic8 = {} - stdin=0 - stdout=1 -end - -local function LzmaDec_WriteRem(wrDicLimit) - - if (((remainLen) ~= (0)) and ((remainLen) < (274))) then - local wrLen = remainLen; - if (((wrDicLimit - dicPos) < (wrLen))) then - wrLen = wrDicLimit - dicPos ; - end - if (((checkDicSize) == (0)) and ((dicSize - processedPos) <= (wrLen))) then - checkDicSize = dicSize; - end - processedPos = processedPos + wrLen; - remainLen = remainLen - wrLen; - while (((wrLen) ~= (0))) do - wrLen=wrLen-1; - dic8[dicPos] = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)] -band- 0xFF; - dicPos=dicPos+1; - end - end -end - - -local function LzmaDec_DecodeReal2(drDicLimit, drBufLimit) - local pbMask = ((1) -blshift- (pb)) - 1; - local lpMask = ((1) -blshift- (lp)) - 1; - local drI = 0; - local lastTime - if textutils then - os.queueEvent("nosleep") - lastTime = os.epoch("utc") - end - - repeat - local drDicLimit2 = (((checkDicSize) == (0)) and ((dicSize - processedPos) < (drDicLimit - dicPos))) and (dicPos + (dicSize - processedPos)) or drDicLimit; - --print("drDicLimit2", drDicLimit2, "checkDicSize", checkDicSize, "dicSize", dicSize, "processedPos", processedPos, "drDicLimit", drDicLimit, "dicPos", dicPos) - remainLen = 0; - repeat - local drProbIdx = 0; - local drBound = 0; - local drTtt = 0; - local distance = 0; - local drPosState = processedPos -band- pbMask; - if textutils and os.epoch("utc") - lastTime > 3000 then - --write(".") - lastTime = os.epoch("utc") - os.queueEvent(os.pullEvent()) - end - --print(rep0, rep1, rep2, rep3) - drProbIdx = 0 + (state -blshift- (4)) + drPosState ; - drTtt = probs16[drProbIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur = bufCur + 1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - local drSymbol = 0; - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - range = (drBound) ; - probs16[drProbIdx] = drTtt + ((bitlib.rshift((2048 - drTtt), (5)))); - drProbIdx = 1846 ; - if (((checkDicSize) ~= (0)) or ((processedPos) ~= (0))) then - drProbIdx = drProbIdx + (768 * (((processedPos -band- lpMask) -blshift- lc) + (bitlib.rshift((dic8[(((dicPos) == (0)) and dicBufSize or dicPos) - 1]), (lcm8))))) ; - end - if (((state) < (7))) then - state = state - ((((state) < (4))) and state or 3); - drSymbol = 1 ; - repeat - drTtt = probs16[drProbIdx + drSymbol] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = ((bitlib.rshift((range), 11))) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx + drSymbol] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drSymbol = (drSymbol + drSymbol); - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx + drSymbol] = drTtt - (bitlib.rshift((drTtt), (5))); - drSymbol = (drSymbol + drSymbol) + 1; - end - until not (((drSymbol) < (0x100))) - else - local drMatchByte = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)]; - local drMatchMask = 0x100; - state = state - (((state) < (10)) and 3 or 6); - drSymbol = 1 ; - repeat - local drBit; - local drProbLitIdx; - assert(drMatchMask == 0 or drMatchMask == 0x100); - drMatchByte = drMatchByte -blshift- 1 ; - drBit = (drMatchByte -band- drMatchMask) ; - drProbLitIdx = drProbIdx + drMatchMask + drBit + drSymbol ; - drTtt = probs16[drProbLitIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbLitIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drSymbol = (drSymbol + drSymbol) ; - drMatchMask = drMatchMask -band- (bnot-drBit) ; - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbLitIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - drSymbol = (drSymbol + drSymbol) + 1 ; - drMatchMask = drMatchMask -band- drBit ; - end - until not (((drSymbol) < (0x100))); - end - dic8[dicPos] = drSymbol -band- 0xFF; - dicPos=dicPos+1; - processedPos=processedPos+1; - --print("continue2") - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - drProbIdx = 192 + state ; - drTtt = probs16[drProbIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - local shouldContinue = true - if (((code) < (drBound))) then - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - range = (drBound) ; - probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - state = state + 12; - drProbIdx = 818 ; - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - if (((checkDicSize) == (0)) and ((processedPos) == (0))) then - --print("A") - return 1; - end - drProbIdx = 204 + state ; - drTtt = probs16[drProbIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - range = (drBound) ; - probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drProbIdx = 240 + (state -blshift- (4)) + drPosState ; - drTtt = probs16[drProbIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - dic8[dicPos] = dic8[(dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0)] -band- 0xFF; - dicPos=dicPos+1; - processedPos=processedPos+1; - state = ((state) < (7)) and 9 or 11; - --print("continue") - shouldContinue = false - end - if shouldContinue then - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - end - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - drProbIdx = 216 + state ; - drTtt = probs16[drProbIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - distance = rep1 ; - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - drProbIdx = 228 + state ; - drTtt = probs16[drProbIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - distance = rep2 ; - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - distance = rep3 ; - rep3 = rep2; - end - rep2 = rep1; - end - rep1 = rep0; - rep0 = distance; - end - if shouldContinue then - state = ((state) < (7)) and 8 or 11; - drProbIdx = 1332 ; - end - end - if shouldContinue then - --print(distance) - do - local drLimitSub; - local drOffset; - local drProbLenIdx = drProbIdx + 0; - drTtt = probs16[drProbLenIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - range = (drBound) ; - probs16[drProbLenIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drProbLenIdx = drProbIdx + 2 + (drPosState -blshift- (3)) ; - drOffset = 0 ; - drLimitSub = (8) ; - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbLenIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - drProbLenIdx = drProbIdx + 1 ; - drTtt = probs16[drProbLenIdx] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - range = (drBound) ; - probs16[drProbLenIdx] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drProbLenIdx = drProbIdx + 130 + (drPosState -blshift- (3)) ; - drOffset = 8 ; - drLimitSub = 8 ; - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbLenIdx] = drTtt - (bitlib.rshift((drTtt), (5))); - drProbLenIdx = drProbIdx + 258 ; - drOffset = 8 + 8 ; - drLimitSub = 256 ; - end - end - do - remainLen = (1) ; - repeat - drTtt = probs16[(drProbLenIdx + remainLen)] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[(drProbLenIdx + remainLen)] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - remainLen = ((remainLen + remainLen)); - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[(drProbLenIdx + remainLen)] = drTtt - (bitlib.rshift((drTtt), (5))); - remainLen = ((remainLen + remainLen) + 1); - end - until not (((remainLen) < (drLimitSub))); - remainLen = remainLen - (drLimitSub) ; - end - remainLen = remainLen + (drOffset) ; - end - - if (((state) >= (12))) then - drProbIdx = 432 + ((((remainLen) < (4)) and remainLen or 4 - 1) -blshift- (6)) ; - do - distance = 1 ; - repeat - drTtt = probs16[(drProbIdx + distance)] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[(drProbIdx + distance)] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - distance = (distance + distance); - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[(drProbIdx + distance)] = drTtt - (bitlib.rshift((drTtt), (5))); - distance = (distance + distance) + 1; - end - until not (((distance) < ((64)))); - distance = distance - (64) ; - end - assert((distance <= 0x7fffffff) and ((distance) < (64))); - if (((distance) >= (4))) then - local drPosSlot = distance; - local drDirectBitCount = (bitlib.rshift((distance), (1))) - 1; - distance = (2 -bor- (distance -band- 1)) ; - if (((drPosSlot) < (14))) then - distance = distance -blshift- drDirectBitCount ; - drProbIdx = 688 + distance - drPosSlot - 1 ; - do - local mask = 1; - drI = 1; - repeat - drTtt = probs16[drProbIdx + drI] ; - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drI = (drI + drI); - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); - drI = (drI + drI) + 1 ; - distance = distance -bor- mask ; - end - mask = mask -blshift- 1 ; - drDirectBitCount = drDirectBitCount - 1 - until not (((drDirectBitCount) ~= (0))); - end - else - drDirectBitCount = drDirectBitCount - 4 ; - repeat - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - - range = ((bitlib.rshift((range), 1))); - if (((code - range) -band- 0x80000000 ~= 0)) then - distance = distance -blshift- 1; - else - code = code - (range); - - distance = (distance -blshift- 1) + 1; - end - drDirectBitCount = drDirectBitCount-1; - until not (((drDirectBitCount) ~= (0))); - drProbIdx = 802 ; - distance = distance -blshift- 4 ; - do - drI = 1; - drTtt = probs16[drProbIdx + drI]; - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drI = (drI + drI); - else - range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); - drI = (drI + drI) + 1 ; - distance = distance -bor- 1 ; - end - drTtt = probs16[drProbIdx + drI]; - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drI = (drI + drI); - else range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); - drI = (drI + drI) + 1 ; - distance = distance -bor- 2 ; - end - drTtt = probs16[drProbIdx + drI]; - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drI = (drI + drI); - else range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); - drI = (drI + drI) + 1 ; - distance = distance -bor- 4 ; - end - drTtt = probs16[drProbIdx + drI]; - assert((drTtt <= 0x7fffffff) and ((drTtt) <= (2048))); - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - drBound = (bitlib.rshift((range), 11)) * drTtt ; - if (((code) < (drBound))) then - range = (drBound) ; - probs16[drProbIdx + drI] = drTtt + (bitlib.rshift((2048 - drTtt), (5))); - drI = (drI + drI); - else range = range - (drBound) ; - code = code - (drBound) ; - probs16[drProbIdx + drI] = drTtt - (bitlib.rshift((drTtt), (5))); - drI = (drI + drI) + 1 ; - distance = distance -bor- 8 ; - end - end - if (((bnot-distance) == 0)) then - remainLen = remainLen + (274) ; - state = state - 12; - --print("break") - break; - end - end - end - - assert((distance <= 0x7fffffff) and ((distance) <= (1610612736))); - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance + 1; - if (((checkDicSize) == (0))) then - if (((distance) >= (processedPos))) then - --print("B") - return 1; - end - else - if (((distance) >= (checkDicSize))) then - --print("C") - return 1; - end - end - state = ((state) < (12 + 7)) and 7 or 7 + 3; - end - - remainLen = remainLen + (2) ; - - if (((drDicLimit2) == (dicPos))) then - --print("D") - return 1; - end - do - local drRem = drDicLimit2 - dicPos; - local curLen = (((drRem) < (remainLen)) and drRem or remainLen); - local pos = (dicPos - rep0) + (((dicPos) < (rep0)) and dicBufSize or 0); - - processedPos = processedPos + curLen; - - remainLen = remainLen - (curLen) ; - if (((pos + curLen) <= (dicBufSize))) then - assert(((dicPos) > (pos))); - assert(((curLen) > (0))); - repeat - - dic8[dicPos] = dic8[pos] -band- 0xFF; - dicPos=dicPos+1 - pos=pos+1 - curLen=curLen-1 - until not (((curLen) ~= (0))); - else - repeat - dic8[dicPos] = dic8[pos] -band- 0xFF; - dicPos=dicPos+1 - pos=pos+1 - if (((pos) == (dicBufSize))) then - pos = 0 ; - end - until not (((curLen) ~= (0))); - end - end - end - end - --print("drDicLimit2", drDicLimit2, "drBufLimit", drBufLimit, "dicPos", dicPos, "bufCur", bufCur) - until not (((dicPos) < (drDicLimit2)) and ((bufCur) < (drBufLimit))); - - if (((range) < (16777216))) then - range = range -blshift- (8) ; - code = ((code -blshift- 8) -bor- (readBuf8[bufCur])) ; - bufCur=bufCur+1; - end - if (((processedPos) >= (dicSize))) then - checkDicSize = dicSize; - end - LzmaDec_WriteRem(drDicLimit); - until not (((dicPos) < (drDicLimit)) and ((bufCur) < (drBufLimit)) and ((remainLen) < (274))); - - if (((remainLen) > (274))) then - remainLen = 274; - end - return 0; -end - -local function LzmaDec_TryDummy(tdCur, tdBufLimit) - local tdRange = range; - local tdCode = code; - local tdState = state; - local tdRes; - local tdProbIdx; - local tdBound; - local tdTtt; - local tdPosState = (processedPos) -band- ((1 -blshift- pb) - 1); - - - tdProbIdx = 0 + (tdState -blshift- (4)) + tdPosState ; - tdTtt = probs16[tdProbIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - local tdSymbol = 1; - tdRange = tdBound ; - tdProbIdx = 1846 ; - if (((checkDicSize) ~= (0)) or ((processedPos) ~= (0))) then - tdProbIdx = tdProbIdx + (768 * ((((processedPos) -band- ((1 -blshift- (lp)) - 1)) -blshift- lc) + (bitlib.rshift((dic8[(((dicPos) == (0)) and dicBufSize or dicPos) - 1]), (lcm8))))) ; - end - - if (((tdState) < (7))) then - repeat - tdTtt = probs16[tdProbIdx + tdSymbol] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdSymbol = (tdSymbol + tdSymbol); - else tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdSymbol = (tdSymbol + tdSymbol) + 1; - end - until not (((tdSymbol) < (0x100))); - else - local tdMatchByte = dic8[dicPos - rep0 + (((dicPos) < (rep0)) and dicBufSize or 0)]; - local tdMatchMask = 0x100; - repeat - local tdBit; - local tdProbLitIdx; - assert(tdMatchMask == 0 or tdMatchMask == 0x100); - tdMatchByte = tdMatchByte -blshift- 1 ; - tdBit = (tdMatchByte -band- tdMatchMask) ; - tdProbLitIdx = tdProbIdx + tdMatchMask + tdBit + tdSymbol ; - tdTtt = probs16[tdProbLitIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdSymbol = (tdSymbol + tdSymbol) ; - tdMatchMask = tdMatchMask -band- (bnot-tdBit) ; - else tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdSymbol = (tdSymbol + tdSymbol) + 1 ; - tdMatchMask = tdMatchMask -band- tdBit ; - end - until not (((tdSymbol) < (0x100))); - end - tdRes = 1 ; - else - local tdLen; - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdProbIdx = 192 + tdState ; - tdTtt = probs16[tdProbIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdState = 0 ; - tdProbIdx = 818 ; - tdRes = 2 ; - else - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdRes = 3 ; - tdProbIdx = 204 + tdState ; - tdTtt = probs16[tdProbIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdProbIdx = 240 + (tdState -blshift- (4)) + tdPosState ; - tdTtt = probs16[tdProbIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - return 3; - else - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - end - else - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdProbIdx = 216 + tdState ; - tdTtt = probs16[tdProbIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - else - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdProbIdx = 228 + tdState ; - tdTtt = probs16[tdProbIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - else - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - end - end - end - tdState = 12 ; - tdProbIdx = 1332 ; - end - do - local tdLimitSub; - local tdOffset; - local tdProbLenIdx = tdProbIdx + 0; - tdTtt = probs16[tdProbLenIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdProbLenIdx = tdProbIdx + 2 + (tdPosState -blshift- (3)) ; - tdOffset = 0 ; - tdLimitSub = 8 ; - else - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdProbLenIdx = tdProbIdx + 1 ; - tdTtt = probs16[tdProbLenIdx] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdProbLenIdx = tdProbIdx + 130 + (tdPosState -blshift- (3)) ; - tdOffset = 8 ; - tdLimitSub = 8 ; - else - tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdProbLenIdx = tdProbIdx + 258 ; - tdOffset = 8 + 8 ; - tdLimitSub = 256 ; - end - end - do - tdLen = 1 ; - repeat - tdTtt = probs16[tdProbLenIdx + tdLen] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdLen = (tdLen + tdLen); - else tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdLen = (tdLen + tdLen) + 1; - end - until not (((tdLen) < (tdLimitSub))); - tdLen = tdLen - tdLimitSub ; - end - tdLen = tdLen + tdOffset ; - end - - if (((tdState) < (4))) then - local tdPosSlot; - tdProbIdx = 432 + ((((tdLen) < (4)) and tdLen or 4 - 1) -blshift- (6)) ; - do - tdPosSlot = 1 ; - repeat - tdTtt = probs16[tdProbIdx + tdPosSlot] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdPosSlot = (tdPosSlot + tdPosSlot); - else tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdPosSlot = (tdPosSlot + tdPosSlot) + 1; - end - until not (((tdPosSlot) < (64))); - tdPosSlot = tdPosSlot - (64) ; - end - - assert((tdPosSlot <= 0x7fffffff) and ((tdPosSlot) < (64))); - if (((tdPosSlot) >= (4))) then - local tdDirectBitCount = (bitlib.rshift((tdPosSlot), (1))) - 1; - if (((tdPosSlot) < (14))) then - tdProbIdx = 688 + ((2 -bor- (tdPosSlot -band- 1)) -blshift- tdDirectBitCount) - tdPosSlot - 1 ; - else - tdDirectBitCount = tdDirectBitCount - 4 ; - repeat - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdRange = (bitlib.rshift((tdRange), 1)); - if (((tdCode - tdRange) -band- 0x80000000) == 0) then - tdCode = tdCode - tdRange; - end - tdDirectBitCount=tdDirectBitCount-1; - until not (((tdDirectBitCount) ~= (0))); - tdProbIdx = 802 ; - tdDirectBitCount = 4 ; - end - do - local tdI = 1; - repeat - tdTtt = probs16[tdProbIdx + tdI] ; - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - tdBound = (bitlib.rshift((tdRange), 11)) * tdTtt ; - if (((tdCode) < (tdBound))) then - tdRange = tdBound ; - tdI = (tdI + tdI); - else tdRange = tdRange - tdBound ; - tdCode = tdCode - tdBound ; - tdI = (tdI + tdI) + 1; - end - tdDirectBitCount=tdDirectBitCount-1; - until not (((tdDirectBitCount) ~= (0))); - end - end - end - end - if (((tdRange) < (16777216))) then - if (((tdCur) >= (tdBufLimit))) then - return 0; - end - tdRange = tdRange -blshift- 8 ; - tdCode = (tdCode -blshift- 8) -bor- (readBuf8[tdCur]) ; - tdCur=tdCur+1; - end - return tdRes; -end - -local function LzmaDec_InitDicAndState(idInitDic, idInitState) - - - needFlush = 1; - remainLen = 0; - tempBufSize = 0; - - if ((idInitDic ~= 0)) then - processedPos = 0; - checkDicSize = 0; - needInitLzma = 1; - end - if ((idInitState ~= 0)) then - needInitLzma = 1; - end -end - - - - - -local function LzmaDec_DecodeToDic(ddSrcLen) - - local decodeLimit = readCur + ddSrcLen; - local checkEndMarkNow; - local dummyRes; - - LzmaDec_WriteRem(dicBufSize); - - while (((remainLen) ~= (274))) do - if ((needFlush ~= 0)) then - - - - while (((decodeLimit) > (readCur)) and ((tempBufSize) < (5))) do - readBuf8[(6 + 65536 + 6) + tempBufSize] = readBuf8[readCur]; - tempBufSize=tempBufSize+1 - readCur=readCur+1 - end - if (((tempBufSize) < (5))) then - - - - - - end - if (((readBuf8[(6 + 65536 + 6)]) ~= (0))) then - --print("E") - return 1; - end - code = ((((readBuf8[(6 + 65536 + 6) + 1]) -blshift- 24) -bor- ((readBuf8[(6 + 65536 + 6) + 2]) -blshift- 16)) -bor- ((readBuf8[(6 + 65536 + 6) + 3]) -blshift- 8)) -bor- ((readBuf8[(6 + 65536 + 6) + 4])); - range = 0xffffffff; - needFlush = 0; - tempBufSize = 0; - end - - checkEndMarkNow = 0 ; - if (((dicPos) >= (dicBufSize))) then - if (((remainLen) == (0)) and ((code) == 0)) then - if (((readCur) ~= (decodeLimit))) then - return 18; - end - return 0 ; - end - if (((remainLen) ~= (0))) then - return 16; - end - checkEndMarkNow = 1 ; - end - - if ((needInitLzma ~= 0)) then - local numProbs = 1846 + ((768) -blshift- (lc + lp)); - for ddProbIdx = 0, numProbs-1, 1 do - probs16[ddProbIdx] = (bitlib.rshift((2048), (1))); - end - rep3 = 1; - rep2 = rep3; - rep1 = rep2; - rep0 = rep1; - state = 0; - needInitLzma = 0; - end - - if (((tempBufSize) == (0))) then - local bufLimit; - if (((decodeLimit - readCur) < (20)) or (checkEndMarkNow ~= 0)) then - dummyRes = LzmaDec_TryDummy(readCur, decodeLimit) ; - if (((dummyRes) == (0))) then - - tempBufSize = 0; - while (((readCur) ~= (decodeLimit))) do - readBuf8[(6 + 65536 + 6) + tempBufSize] = readBuf8[readCur]; - tempBufSize=tempBufSize+1; - readCur=readCur+1; - end - - - - if (((readCur) ~= (decodeLimit))) then - return 17; - end - return 17; - - end - if ((checkEndMarkNow ~= 0) and ((dummyRes) ~= (2))) then - return 16; - end - bufLimit = readCur ; - else - bufLimit = decodeLimit - 20 ; - end - bufCur = readCur; - if (((LzmaDec_DecodeReal2(dicBufSize, bufLimit)) ~= (0))) then - --print("F") - return 1; - end - readCur = bufCur; - else - local ddRem = tempBufSize; - local lookAhead = 0; - while (((ddRem) < (20)) and ((lookAhead) < (decodeLimit - readCur))) do - readBuf8[(6 + 65536 + 6) + ddRem] = readBuf8[readCur + lookAhead]; - ddRem=ddRem+1; - lookAhead=lookAhead+1; - end - tempBufSize = ddRem; - if (((ddRem) < (20)) or (checkEndMarkNow ~= 0)) then - dummyRes = LzmaDec_TryDummy((6 + 65536 + 6), (6 + 65536 + 6) + ddRem) ; - if (((dummyRes) == (0))) then - readCur = readCur + lookAhead; - - - - if (((readCur) ~= (decodeLimit))) then - return 17; - end - return 17; - - end - if ((checkEndMarkNow ~= 0) and ((dummyRes) ~= (2))) then - return 16; - end - end - - bufCur = (6 + 65536 + 6); - if (((LzmaDec_DecodeReal2(0, (6 + 65536 + 6))) ~= (0))) then - --print("G") - return 1; - end - lookAhead = lookAhead - ddRem - (bufCur - (6 + 65536 + 6)) ; - readCur = readCur + lookAhead; - tempBufSize = 0; - end - end - if (((code) ~= 0)) then - --print("H"); - return 1; - end - return 15; -end -local function Preread(prSize) - - - - local prPos = readEnd - readCur; - local prGot; - - assert(((prSize) <= ((6 + 65536 + 6)))); - if (((prPos) < (prSize))) then - if ((((6 + 65536 + 6) - readCur) < (prSize))) then - - - readEnd = 0 - while readEnd < prPos do - readBuf8[readEnd] = readBuf8[readCur + readEnd]; - readEnd=readEnd+1 - end - readCur = 0; - end - while (((prPos) < (prSize))) do - - - - - prGot = READ_FROM_STDIN_TO_ARY8(readBuf8, readEnd, prSize - prPos); - if (((prGot + 1) <= (1))) then - break; - end - readEnd = readEnd + prGot; - prPos = prPos + prGot ; - end - end - - return prPos; - - - - - -end - -local function IgnoreVarint() - while (((readBuf8[readCur]) >= (0x80))) do readCur = readCur + 1 end - readCur = readCur + 1 -end - -local function IgnoreZeroBytes(izCount) - - while ((izCount) ~= (0)) do - readCur=readCur+1 - if (((readBuf8[readCur-1]) ~= (0))) then - return 57; - end - izCount=izCount-1; - end - return 0; -end - -local function GetLE4(glPos) - --return ((readBuf8[glPos] -bor- (readBuf8[glPos + 1] -blshift- 8)) -bor- (readBuf8[glPos + 2] -blshift- 16)) -bor- (readBuf8[glPos + 3] -blshift- 24); - --print("glPos", glPos) - return bitlib.band(readBuf8[glPos], 0xff) + bitlib.blshift(bitlib.band(readBuf8[glPos+1], 0xff), 8) + bitlib.blshift(bitlib.band(readBuf8[glPos+2], 0xff), 16) + bit.blshift(bitlib.band(readBuf8[glPos+3], 0xff), 24) -end - - -local function InitDecode() - - - dicBufSize = 0; - needInitDic = 1; - needInitState = 1; - needInitProp = 1; - dicPos = 0; - LzmaDec_InitDicAndState(1, 1); -end - -local function InitProp(ipByte) - - if (((ipByte) >= (9 * 5 * 5))) then - return 68; - end - lc = ipByte % 9; - lcm8 = 8 - lc; - ipByte = math.floor(ipByte / 9) ; - pb = math.floor(ipByte / 5); - lp = ipByte % 5; - if (((lc + lp) > (4))) then - return 68; - end - needInitProp = 0; - return 0; -end - - -local function WriteFrom(wfDicPos) - - - local lastTime = os.epoch("utc") - - - while (((wfDicPos) ~= (dicPos))) do - local wfGot = WRITE_TO_STDOUT_FROM_ARY8(dic8, wfDicPos, dicPos - wfDicPos); - if (wfGot -band- 0x80000000) ~= 0 then - return 9; - end - wfDicPos = wfDicPos + wfGot ; - if textutils and os.epoch("utc") - lastTime > 3000 then - --write(",") - lastTime = os.epoch("utc") - os.queueEvent(os.pullEvent()) - end - end - - return 0; -end - - - - - - -local function DecompressXzOrLzma() - local checksumSize; - local bhf; - local dxRes; - - - - - if (((Preread(12 + 12 + 6)) < (12 + 12 + 6))) then - return 6; - end - - if (((readBuf8[0]) == (0xfd)) and ((readBuf8[1]) == (0x37)) and - ((readBuf8[2]) == (0x7a)) and ((readBuf8[3]) == (0x58)) and - ((readBuf8[4]) == (0x5a)) and ((readBuf8[5]) == (0)) and - ((readBuf8[6]) == (0))) then --print("xz") - elseif ( - ( - (readBuf8[readCur]) <= (225) - ) and ( - (readBuf8[readCur + 13]) == (0) - ) and ( - ( - ( - (function() bhf = GetLE4(readCur + 9); return bhf end)() - ) == 0 - ) or ( - (bnot-bhf) == 0 - ) - ) and ( - ( - (function() dicSize = GetLE4(readCur + 1); return dicSize end)() - ) >= ((4096)) - ) and ( - (dicSize) < bitlib.band((1610612736 + 1), 0x7fffffff) - ) - ) then - - local readBufUS; - local srcLen; - local fromDicPos; - InitDecode(); - - - - - - if ((((function() dxRes = InitProp(readBuf8[readCur]); return dxRes end)()) ~= (0))) then - return dxRes; - end - if (((bhf) == 0)) then - readBufUS = GetLE4(readCur + 5); - dicBufSize = readBufUS; - if (not ((readBufUS) < bitlib.band((1610612736 + 1), 0x7fffffff))) then - return 2; - end - else - readBufUS = bhf ; - - dicBufSize = 1610612736; - end - - readCur = readCur + 13; - - - - - - - - while ((((function() srcLen = Preread((6 + 65536 + 6)); return srcLen end)()) ~= (0))) do - fromDicPos = dicPos ; - dxRes = LzmaDec_DecodeToDic(srcLen) ; - - if (((readBufUS) < (dicPos))) then - dicPos = readBufUS; - end - if ((((function() dxRes = WriteFrom(fromDicPos); return dxRes end)()) ~= (0))) then - return dxRes; - end - if (((dxRes) == (15))) then - break; - end - if (((dxRes) ~= (17)) and ((dxRes) ~= (0))) then - return dxRes; - end - if (((dicPos - readBufUS) == 0)) then - break; - end - end - return 0; - else - return 51; - end - - checksumSize = readBuf8[readCur + 7]; - if (((checksumSize) == (0))) then - checksumSize = 1; - elseif (((checksumSize) == (1))) then - checksumSize = 4; - elseif (((checksumSize) == (4))) then - checksumSize = 8; - elseif (((checksumSize) == (10))) then - checksumSize = 32; - else return 60; - end - - readCur = readCur + 12; - while true do - - local blockSizePad = 3; - local bhs; - local bhs2; - local dicSizeProp; - local readAtBlock; - assert(((readEnd - readCur) >= (12))); - readAtBlock = readCur ; - readCur=readCur+1; - if ((((function() bhs = readBuf8[readCur-1]; return bhs end)()) == (0))) then - break; - end - - bhs = (bhs + 1) -blshift- 2; - - - if (((Preread(bhs)) < (bhs))) then - return 6; - end - readAtBlock = readCur ; - bhf = readBuf8[readCur] ; - --print("bhf", string.format("%x\n", bhf)) - readCur=readCur+1; - if (((bhf -band- 2) ~= (0))) then - return 53; - end - - if (((bhf -band- 20) ~= (0))) then - return 54; - end - if (((bhf -band- 64) ~= (0))) then - - IgnoreVarint(); - end - if (((bhf -band- 128) ~= (0))) then - - IgnoreVarint(); - end - if (((readBuf8[readCur]) ~= (0x21))) then - return 55; - end - readCur=readCur+1; - if (((readBuf8[readCur]) ~= (1))) then - return 56; - end - readCur=readCur+1; - dicSizeProp = readBuf8[readCur] ; - readCur=readCur+1; - if (((dicSizeProp) > (40))) then - return 61; - end - - - - if (((dicSizeProp) > (37))) then - return 62; - end - dicSize = (((2) -bor- ((dicSizeProp) -band- 1)) -blshift- (math.floor((dicSizeProp) / 2) + 11)); - assert(((dicSize) >= ((4096)))); - - - - - - bhs2 = readCur - readAtBlock + 5 ; - - if (((bhs2) > (bhs))) then - return 58; - end - if ((((function() dxRes = IgnoreZeroBytes(bhs - bhs2); return dxRes end)()) ~= (0))) then - return dxRes; - end - readCur = readCur + 4; - - - do - - local chunkUS; - local chunkCS; - local initDic; - InitDecode(); - - while true do - local control; - assert(((dicPos) == (dicBufSize))); - - - - if (((Preread(6)) < (6))) then - return 6; - end - control = readBuf8[readCur] ; - - if (((control) == (0))) then - - readCur=readCur+1; - break; - elseif ((((bitlib.band((control - 3), 0xff))) < (0x80 - 3))) then - return 59; - end - chunkUS = (readBuf8[readCur + 1] -blshift- 8) + readBuf8[readCur + 2] + 1 ; - --print("chunkUS", chunkUS, "readCur", readCur, "@1", readBuf8[readCur + 1], "@2", readBuf8[readCur + 2]) - if (((control) < (3))) then - initDic = (((control) == (1)) and 1 or 0); - chunkCS = chunkUS ; - readCur = readCur + 3; - - blockSizePad = blockSizePad - 3; - if ((initDic ~= 0)) then - needInitState = 1; - needInitProp = needInitState; - needInitDic = 0; - elseif ((needInitDic ~= 0)) then - --print("I") - return 1; - end - LzmaDec_InitDicAndState(initDic, 0); - else - local mode = ((bitlib.rshift(((control)), (5))) -band- 3); - local initState = (((mode) ~= (0)) and 1 or 0); - local isProp = ((((control -band- 64)) ~= (0)) and 1 or 0); - initDic = (((mode) == (3)) and 1 or 0); - chunkUS = chunkUS + ((control -band- 31) -blshift- 16) ; - chunkCS = (readBuf8[readCur + 3] -blshift- 8) + readBuf8[readCur + 4] + 1 ; - if ((isProp ~= 0)) then - if ((((function() dxRes = InitProp(readBuf8[readCur + 5]); return dxRes end)()) ~= (0))) then - return dxRes; - end - readCur=readCur+1; - blockSizePad=blockSizePad-1; - else - if ((needInitProp ~= 0)) then - return 67; - end - end - readCur = readCur + 5; - blockSizePad = blockSizePad - 5 ; - if (((initDic == 0) and (needInitDic ~= 0)) or ((initState == 0) and (needInitState ~= 0))) then - --print("J") - return 1; - end - LzmaDec_InitDicAndState(initDic, initState); - needInitDic = 0; - needInitState = 0; - end - assert(((dicPos) == (dicBufSize))); - dicBufSize = dicBufSize + chunkUS; - - if (((dicBufSize) > (1610612736))) then - return 2; - end - - - - - if (((Preread(chunkCS + 6)) < (chunkCS))) then - return 6; - end - - if (((control) < (0x80))) then - - while (((dicPos) ~= (dicBufSize))) do - dic8[dicPos] = readBuf8[readCur] -band- 0xFF; - dicPos=dicPos+1; - readCur=readCur+1; - end - if (((checkDicSize) == (0)) and ((dicSize - processedPos) <= (chunkUS))) then - checkDicSize = dicSize; - end - processedPos = processedPos + chunkUS; - else - - - if ((((function() dxRes = LzmaDec_DecodeToDic(chunkCS); return dxRes end)()) ~= (0))) then - return dxRes; - end - end - if (((dicPos) ~= (dicBufSize))) then - return 65; - end - if ((((function() dxRes = WriteFrom(dicPos - chunkUS); return dxRes end)()) ~= (0))) then - return dxRes; - end - blockSizePad = blockSizePad - chunkCS ; - - - - - end - end - - - - - if (((Preread(7 + 12 + 6)) < (7 + 12 + 6))) then - return 6; - end - - - if ((((function() dxRes = IgnoreZeroBytes(blockSizePad -band- 3); return dxRes end)()) ~= (0))) then - return dxRes; - end - readCur = readCur + checksumSize; - end - - return 0; -end - -local error_table = { - UNKNOWN_ERROR = -1, - OK = 0, - ERROR_DATA = 1, - ERROR_MEM = 2, - ERROR_CRC = 3, - ERROR_UNSUPPORTED = 4, - ERROR_PARAM = 5, - ERROR_INPUT_EOF = 6, - ERROR_OUTPUT_EOF = 7, - ERROR_READ = 8, - ERROR_WRITE = 9, - ERROR_FINISHED_WITH_MARK = 15, - ERROR_NOT_FINISHED = 16, - ERROR_NEEDS_MORE_INPUT = 17, - ERROR_CHUNK_NOT_CONSUMED = 18, - ERROR_NEEDS_MORE_INPUT_PARTIAL = 17, - ERROR_BAD_MAGIC = 51, - ERROR_BAD_STREAM_FLAGS = 52, - ERROR_UNSUPPORTED_FILTER_COUNT = 53, - ERROR_BAD_BLOCK_FLAGS = 54, - ERROR_UNSUPPORTED_FILTER_ID = 55, - ERROR_UNSUPPORTED_FILTER_PROPERTIES_SIZE = 56, - ERROR_BAD_PADDING = 57, - ERROR_BLOCK_HEADER_TOO_LONG = 58, - ERROR_BAD_CHUNK_CONTROL_BYTE = 59, - ERROR_BAD_CHECKSUM_TYPE = 60, - ERROR_BAD_DICTIONARY_SIZE = 61, - ERROR_UNSUPPORTED_DICTIONARY_SIZE = 62, - ERROR_FEED_CHUNK = 63, - ERROR_NOT_FINISHED_WITH_MARK = 64, - ERROR_BAD_DICPOS = 65, - ERROR_MISSING_INITPROP = 67, - ERROR_BAD_LCLPPB_PROP = 68, -} - -return { - --- Decompresses an XZ or LZMA file using file I/O. Both files will be closed after decompression finishes. - -- @param input The input file (path) to read from - -- @param output The output file (path) to write to - -- @return Whether the decompression succeeded - -- @return If failure, an error code describing the issue - DecompressXzOrLzmaFile = function(input, output) - if type(input) ~= "number" and type(input) ~= "string" and type(input)~="table" then error("bad argument #1 (expected string or file, got " .. type(input) .. ")", 2) end - if type(output) ~= "number" and type(output) ~= "string" and type(input)~="table" then error("bad argument #2 (expected string or file, got " .. type(output) .. ")", 2) end - str_input = nil - str_output = nil - if type(input) == "string" then - input = syscall.open(input, "r") - if input == nil then return false, -1 end - end - if type(output) == "string" then - output = syscall.open(output, "w") - if output == nil then return false, -1 end - end - ResetGlobals() - stdin=input - stdout=output - local ok, res = pcall(DecompressXzOrLzma) - syscall.close(input) - syscall.close(output) - if not ok then - if res then error(res .. "\n") end - return false, -1 - else return res == 0, res end - end, - - --- Decompresses XZ or LZMA data. - -- @param input The input data to decompress - -- @return The decompressed data, or nil if failure - -- @return If failure, an error code describing the issue - DecompressXzOrLzmaString = function(input) - if type(input) ~= "string" then error("bad argument #1 (expected string, got " .. type(input) .. ")", 2) end - str_input = input - str_output = "" - ResetGlobals() - local ok, res = pcall(DecompressXzOrLzma) - if not ok then - if res then error(res .. "\n") end - return -1 - elseif res == 0 then return str_output - elseif res == 53 and #str_output > 0 then return str_output, res - else return nil, res end - end, - - --- Translates error codes to a semi-understandable meaning. - -- @param code The error code - -- @return A string describing the error - GetError = function(code) for k,v in pairs(error_table) do if v == code then return k end end return nil end, - --- Error code table for your convenience - Errors = error_table, -} \ No newline at end of file