diff --git a/.luarc.json b/.luarc.json index f472490..488c6fe 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,100 +1,10 @@ { - "$schema": "https://raw.githubusercontent.com/LuaLS/lua-language-server/master/locale/en-us/setting.lua", - "runtime": { - "version": "Lua 5.3", - "special": {}, - "unicodeName": false, - "nonstandardSymbol": [] - }, - "workspace": { - "checkThirdParty": false, - "maxPreload": 5000, - "preloadFileSize": 500 - }, - "diagnostics": { - "disable": [ - "undefined-global", - "lowercase-global" + "diagnostics.globals": [ + "checkArg", + "computer", + "component" ], - "globals": [ - "_G", - "_VERSION", - "assert", - "error", - "getmetatable", - "ipairs", - "load", - "next", - "pairs", - "pcall", - "rawequal", - "rawget", - "rawlen", - "rawset", - "select", - "setmetatable", - "tonumber", - "tostring", - "type", - "xpcall", - "checkArg", - "bit32", - "coroutine", - "debug", - "math", - "os", - "string", - "table", - "component", - "computer", - "unicode", - "utf8" + "diagnostics.disable": [ + "lowercase-global" ] - }, - "completion": { - "enable": true, - "callSnippet": "Both", - "keywordSnippet": "Both", - "displayContext": 6 - }, - "hover": { - "enable": true, - "viewString": true, - "viewStringMax": 1000, - "viewNumber": true, - "fieldInfer": 3000, - "previewFields": 50, - "enumsLimit": 5 - }, - "semantic": { - "enable": true, - "variable": true, - "annotation": true, - "keyword": false - }, - "format": { - "enable": true, - "defaultConfig": { - "indent_style": "space", - "indent_size": "2", - "tab_width": "2" - } - }, - "spell": { - "dict": [] - }, - "telemetry": { - "enable": false - }, - "IntelliSense": { - "traceLocalSet": false, - "traceReturn": false, - "traceBeSetted": false, - "traceFieldInject": false - }, - "type": { - "castNumberToInteger": false, - "weakUnionCheck": false, - "weakNilCheck": false - } -} +} \ No newline at end of file diff --git a/halyde/apps/argentum.lua b/halyde/apps/argentum.lua index a7367a7..4edff50 100644 --- a/halyde/apps/argentum.lua +++ b/halyde/apps/argentum.lua @@ -1,9 +1,9 @@ local packages = {...} local command = packages[1] table.remove(packages, 1) -local fs = require("filesystem") -local component = require("component") -local agReg = require("/argentum/registry.cfg") +local fs = import("filesystem") +local component = import("component") +local agReg = import("/argentum/registry.cfg") if not command then shell.run("help argentum") return @@ -346,7 +346,7 @@ if command == "install" then else print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil")) end - agReg = require("/argentum/registry.cfg") + agReg = import("/argentum/registry.cfg") while true do if not doChecks(packages[i]) then table.insert(fails, packages[i]) @@ -497,7 +497,7 @@ elseif command == "update" then else print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil")) end - agReg = require("/argentum/registry.cfg") + agReg = import("/argentum/registry.cfg") if not packages[1] then local packagesInstalled = fs.list("/argentum/store/") for _, currentPackage in pairs(packagesInstalled) do @@ -632,7 +632,7 @@ elseif command == "info" then else print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil")) end - agReg = require("/argentum/registry.cfg") + agReg = import("/argentum/registry.cfg") if not agReg[packages[1]] and not source then print("\27[91mPackage " .. packages[1] .. " does not exist.") return @@ -656,7 +656,7 @@ elseif command == "search" then else print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil")) end - agReg = require("/argentum/registry.cfg") + agReg = import("/argentum/registry.cfg") local searchResults = {} for packageName, _ in pairs(agReg) do if packageName:find(packages[1], 1, true) then @@ -679,7 +679,7 @@ elseif command == "list" then else print("\27[91mFailed to fetch Ag registry: " .. (errorMessage or "returned nil")) end - agReg = require("/argentum/registry.cfg") + agReg = import("/argentum/registry.cfg") local sortedPackages = {} for packageName, _ in pairs(agReg) do table.insert(sortedPackages, packageName) diff --git a/halyde/apps/boot.lua b/halyde/apps/boot.lua index 80de81e..d08ef3d 100644 --- a/halyde/apps/boot.lua +++ b/halyde/apps/boot.lua @@ -1,5 +1,5 @@ -local component = require("component") -local computer = require("computer") +local component = import("component") +local computer = import("computer") local args = {...} local force = false diff --git a/halyde/apps/cat.lua b/halyde/apps/cat.lua index 2151914..1c5dc93 100644 --- a/halyde/apps/cat.lua +++ b/halyde/apps/cat.lua @@ -1,5 +1,5 @@ local files = {...} -local fs = require("filesystem") +local fs = import("filesystem") if not files or not files[1] then shell.run("help cat") return diff --git a/halyde/apps/cd.lua b/halyde/apps/cd.lua index 5df313f..72aee9e 100644 --- a/halyde/apps/cd.lua +++ b/halyde/apps/cd.lua @@ -1,5 +1,5 @@ local directory = ... -local fs = require("filesystem") +local fs = import("filesystem") if not directory then return diff --git a/halyde/apps/cp.lua b/halyde/apps/cp.lua index 9962779..ecd1316 100644 --- a/halyde/apps/cp.lua +++ b/halyde/apps/cp.lua @@ -1,5 +1,5 @@ local fromFile, toFile = ... -local fs = require("filesystem") +local fs = import("filesystem") if not fromFile or not toFile then shell.run("help cp") diff --git a/halyde/apps/download.lua b/halyde/apps/download.lua index 5885055..96fdd5b 100644 --- a/halyde/apps/download.lua +++ b/halyde/apps/download.lua @@ -1,7 +1,7 @@ local url = ... -local component = require("component") -local fs = require("filesystem") +local component = import("component") +local fs = import("filesystem") if not component.list("internet")() then print("\27[91mThis program requires an internet card to run.") diff --git a/halyde/apps/edit.lua b/halyde/apps/edit.lua index 1281f03..467a5cf 100644 --- a/halyde/apps/edit.lua +++ b/halyde/apps/edit.lua @@ -1,8 +1,8 @@ local file = ... -local fs = require("filesystem") -local event = require("event") -local component = require("component") -local unicode = require("unicode") +local fs = import("filesystem") +local event = import("event") +local component = import("component") +local unicode = import("unicode") local gpu = component.gpu local width, height = gpu.getResolution() local scrollPosX, scrollPosY = 1, 1 diff --git a/halyde/apps/fetch.lua b/halyde/apps/fetch.lua index eb71ae2..add0a0d 100644 --- a/halyde/apps/fetch.lua +++ b/halyde/apps/fetch.lua @@ -1,13 +1,13 @@ -local component = require("component") -local computer = require("computer") +local component = import("component") +local computer = import("computer") local function printstat(text) - terminal.cursorPosX = 35 - terminal.write(text .. "\n", false) + termlib.cursorPosX = 35 + termlib.write(text .. "\n", false) end -terminal.write(_OSLOGO, false) -terminal.cursorPosY = terminal.cursorPosY - 17 +termlib.write(_OSLOGO, false) +termlib.cursorPosY = termlib.cursorPosY - 17 printstat("\27[92mOS\27[0m: ".._OSVERSION) printstat("\27[92mArchitecture\27[0m: ".._VERSION) local componentCounter = 0 @@ -15,7 +15,7 @@ for _, _ in component.list() do componentCounter = componentCounter + 1 end printstat("\27[92mComponents\27[0m: "..tostring(componentCounter)) -printstat("\27[92mCoroutines\27[0m: "..tostring(#tsched.getTasks())) +printstat("\27[92mCoroutines\27[0m: "..tostring(#cormgr.corList)) printstat("\27[92mBattery\27[0m: "..tostring(math.floor(computer.energy() / computer.maxEnergy() * 1000 + 0.5) / 10).."%") local totalMemory = computer.totalMemory() local usedMemory = computer.totalMemory() - computer.freeMemory() @@ -67,4 +67,4 @@ local width, height = component.invoke(component.list("gpu")(), "getResolution") printstat("\27[92mResolution\27[0m: "..tostring(width).."x"..tostring(height).."\n") printstat("\27[40m \27[41m \27[42m \27[43m \27[44m \27[45m \27[46m \27[47m ") printstat("\27[100m \27[101m \27[102m \27[103m \27[104m \27[105m \27[106m \27[107m ") -terminal.cursorPosY = terminal.cursorPosY + 5 +termlib.cursorPosY = termlib.cursorPosY + 5 diff --git a/halyde/apps/help.lua b/halyde/apps/help.lua index 0b27476..47cd216 100644 --- a/halyde/apps/help.lua +++ b/halyde/apps/help.lua @@ -1,4 +1,4 @@ -local fs = require("filesystem") +local fs = import("filesystem") local args = {...} local command = args[1] args = nil diff --git a/halyde/apps/label.lua b/halyde/apps/label.lua index 2ed358e..0c12ee4 100644 --- a/halyde/apps/label.lua +++ b/halyde/apps/label.lua @@ -1,5 +1,5 @@ -local component = require("component") -local computer = require("computer") +local component = import("component") +local computer = import("computer") local args = {...} if not args then return print("\x1b[91mCannot get arguments.") end if not args[1] then diff --git a/halyde/apps/ls.lua b/halyde/apps/ls.lua index e7e7fe0..f7149b8 100644 --- a/halyde/apps/ls.lua +++ b/halyde/apps/ls.lua @@ -1,8 +1,8 @@ local args = {...} local target = args[1] args = nil -local fs = require("filesystem") -local unicode = require("unicode") +local fs = import("filesystem") +local unicode = import("unicode") local maxLength = 0 local margin = 2 -- minimum space between filename and size local dirTable = {} diff --git a/halyde/apps/lsdrv.lua b/halyde/apps/lsdrv.lua index a392c7f..55133fb 100644 --- a/halyde/apps/lsdrv.lua +++ b/halyde/apps/lsdrv.lua @@ -1,7 +1,7 @@ -local serialize = require("serialize") -local component = require("component") -local computer = require("computer") -local unicode = require("unicode") +local serialize = import("serialize") +local component = import("component") +local computer = import("computer") +local unicode = import("unicode") local width,height = component.gpu.getResolution() diff --git a/halyde/apps/lua.lua b/halyde/apps/lua.lua index 251f1ee..03629f6 100644 --- a/halyde/apps/lua.lua +++ b/halyde/apps/lua.lua @@ -1,13 +1,13 @@ print("\27[44m".._VERSION.."\27[0m shell") print('Type "exit" to exit.') termlib.readHistory["lua"] = {""} -local fs = require("filesystem") +local fs = import("filesystem") local loadedLibraries = "" local libList = fs.list("halyde/lib") for _, lib in pairs(libList) do if lib:match("(.+)%.lua") then - loadedLibraries = loadedLibraries .. "local " .. lib:match("(.+)%.lua") .. ' = require("' .. lib:match("(.+)%.lua") .. '")\n' + loadedLibraries = loadedLibraries .. "local " .. lib:match("(.+)%.lua") .. ' = import("' .. lib:match("(.+)%.lua") .. '")\n' end end diff --git a/halyde/apps/maindrv.lua b/halyde/apps/maindrv.lua index 561f213..74aaf2a 100644 --- a/halyde/apps/maindrv.lua +++ b/halyde/apps/maindrv.lua @@ -1,4 +1,4 @@ -local computer = require("computer") +local computer = import("computer") if type(computer)~="table" then return print("\x1b[91mComputer library returned '"..type(computer).."' type\x1b[39m") diff --git a/halyde/apps/mkdir.lua b/halyde/apps/mkdir.lua index 39eb0be..b1a8c1a 100644 --- a/halyde/apps/mkdir.lua +++ b/halyde/apps/mkdir.lua @@ -1,5 +1,5 @@ local directory = ... -local fs = require("filesystem") +local fs = import("filesystem") if not directory then shell.run("help mkdir") diff --git a/halyde/apps/mv.lua b/halyde/apps/mv.lua index d974660..6ffd880 100644 --- a/halyde/apps/mv.lua +++ b/halyde/apps/mv.lua @@ -1,5 +1,5 @@ local fromFile, toFile = ... -local fs = require("filesystem") +local fs = import("filesystem") if not fromFile or not toFile then shell.run("help mv") diff --git a/halyde/apps/reboot.lua b/halyde/apps/reboot.lua index af9b0cd..a11869a 100644 --- a/halyde/apps/reboot.lua +++ b/halyde/apps/reboot.lua @@ -1 +1 @@ -require("computer").shutdown(true) +import("computer").shutdown(true) diff --git a/halyde/apps/resolution.lua b/halyde/apps/resolution.lua deleted file mode 100644 index e69de29..0000000 diff --git a/halyde/apps/rm.lua b/halyde/apps/rm.lua index d8fa1a9..f83b695 100644 --- a/halyde/apps/rm.lua +++ b/halyde/apps/rm.lua @@ -1,5 +1,5 @@ local file = ... -local fs = require("filesystem") +local fs = import("filesystem") if not file then shell.run("help rm") diff --git a/halyde/apps/rtest.lua b/halyde/apps/rtest.lua index d5b202c..825e54f 100644 --- a/halyde/apps/rtest.lua +++ b/halyde/apps/rtest.lua @@ -1,4 +1,4 @@ -local raster = require("raster") +local raster = import("raster") raster.init() @@ -15,7 +15,7 @@ end]] end end ]] -local event = require("event") +local event = import("event") local x=0 local y=0 local vx=1 @@ -88,4 +88,4 @@ end end ]] raster.free() -termlib.cursorPosY=1 +termlib.cursorPosY=1 \ No newline at end of file diff --git a/halyde/apps/rtest3d.lua b/halyde/apps/rtest3d.lua index b8a8702..62c0c2c 100644 --- a/halyde/apps/rtest3d.lua +++ b/halyde/apps/rtest3d.lua @@ -1,7 +1,7 @@ -local component = require("component") -local computer = require("computer") -local raster = require("raster") -local event = require("event") +local component = import("component") +local computer = import("computer") +local raster = import("raster") +local event = import("event") -- Initialize the 3D renderer for a spinning cube -- Using the raster library for drawing diff --git a/halyde/apps/shutdown.lua b/halyde/apps/shutdown.lua index 6c79ab6..d2544dc 100644 --- a/halyde/apps/shutdown.lua +++ b/halyde/apps/shutdown.lua @@ -1 +1 @@ -require("computer").shutdown() +import("computer").shutdown() diff --git a/halyde/config/shell.json b/halyde/config/shell.json index f1f250d..4bed850 100644 --- a/halyde/config/shell.json +++ b/halyde/config/shell.json @@ -1 +1 @@ -{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!","Now i% more secure!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"} +{"prompt":"\u001b[92m%s > \u001b[0m","aliases":{"move":"mv","copy":"cp","ag":"argentum","rename":"mv","..":"cd ..","man":"help","del":"rm","delete":"rm","ren":"mv","remove":"rm","list":"ls","wget":"download","dir":"ls","ps":"lscor","poweroff":"shutdown","restart":"reboot","lsblk":"lsdrv"},"splashMessages":["Made by John Haly- I mean Cerulean Blue.","Welcome! Type \"help\" to get started.","Also try KOCOS!","Welcome back, Commander. We have no idea what we're doing.","99.9% bug-free. The remaining 0.1% are features.","0 days since last error.","Everything is fine. The fire is decorative.","Please don't feed the background processes.","Also has fetch!","Anything red is no man's land. Trust me.","Machine...","Abort, Retry, Fail?","What's the deal with /argentum/store?","So cutting-edge you can't hold it in your hand.","Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.","Shoutout to Ponali!"],"path":["/halyde/apps/"],"startupMessage":"\n │\n │ %s\n │ %s\n │\n ","defaultWorkingDirectory":"/home/"} diff --git a/halyde/config/startupapps.json b/halyde/config/startupapps.json index 3597354..5609ad6 100644 --- a/halyde/config/startupapps.json +++ b/halyde/config/startupapps.json @@ -1 +1 @@ -["/halyde/shell/shell.lua"] +["/halyde/core/fullkb.lua","/halyde/core/evmgr.lua","/halyde/core/drvload.lua","/halyde/core/shell.lua"] diff --git a/halyde/core/boot.lua b/halyde/core/boot.lua new file mode 100644 index 0000000..0405c25 --- /dev/null +++ b/halyde/core/boot.lua @@ -0,0 +1,98 @@ +local loadfile = ... +local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile) + +_G._OSVERSION = "Halyde 2.8.1" +_G._OSLOGO = "" +local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil +repeat + tmpdata = handle:read(math.huge) + _OSLOGO = _OSLOGO .. (tmpdata or "") +until not tmpdata + +_G.package = {["preloaded"] = {}} + +loadfile("/halyde/core/datatools.lua")() + +function _G.import(module, ...) + local args = table.pack(...) + if package.preloaded[module] then + return package.preloaded[module] + end + local modulepath + if filesystem.exists(module) then + modulepath = module + elseif filesystem.exists("/halyde/lib/"..module..".lua") then + modulepath = "/halyde/lib/"..module..".lua" + elseif shell and shell.workingDirectory and filesystem.exists(shell.workingDirectory..module) then + modulepath = shell.workingDirectory..module + end + assert(modulepath, "module not found\npossible locations:\n/halyde/lib/"..module..".lua") + local handle, data, tmpdata = filesystem.open(modulepath), "", nil + repeat + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") + until not tmpdata + handle:close() + return(assert(load(data, "="..modulepath))(table.unpack(args))) +end + +local function preload(module) + local handle, data, tmpdata = assert(filesystem.open("/halyde/lib/" .. module .. ".lua", "r")), "", nil + repeat + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") + until not tmpdata + package.preloaded[module] = assert(load(data, "="..module))() + _G[module] = nil +end + +preload("component") +preload("computer") +preload("filesystem") + +local component = import("component") +local gpu = component.gpu +local screenAddress = component.list("screen")() +--local screen = component.screen + +gpu.bind(screenAddress) +--local maxWidth, maxHeight = gpu.maxResolution() +--local aspectX, aspectY = screen.getAspectRatio() +--local screenRatio = aspectX * 2 / aspectY + +-- Calculate potential dimensions +--local widthLimited = math.floor(maxHeight * screenRatio) +--local heightLimited = math.floor(maxWidth / screenRatio) + +--local targetWidth, targetHeight + +--if widthLimited <= maxWidth then + -- height is the limiting factor +-- targetWidth = widthLimited +-- targetHeight = maxHeight +--else + -- width is the limiting factor +-- targetWidth = maxWidth +-- targetHeight = heightLimited +--end + +--targetWidth = math.min(targetWidth, maxWidth) +--targetHeight = math.min(targetHeight, maxHeight) + +--gpu.setResolution(targetWidth, targetHeight) +gpu.setResolution(gpu.maxResolution()) + +--local handle = assert(filesystem.open("/bazinga.txt", "w")) +--assert(handle:write("Bazinga!")) +--handle:close() + +local fs = import("filesystem") +if not fs.exists("/halyde/config/shell.json") then -- Auto-generate configs + fs.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json") +end +if not fs.exists("/halyde/config/startupapps.json") then + fs.copy("/halyde/config/generate/startupapps.json", "/halyde/config/startupapps.json") +end +fs = nil + +import("/halyde/core/cormgr.lua") diff --git a/halyde/core/cormgr.lua b/halyde/core/cormgr.lua new file mode 100644 index 0000000..7049fa3 --- /dev/null +++ b/halyde/core/cormgr.lua @@ -0,0 +1,97 @@ +_G.cormgr = {} +_G.cormgr.corList = {} +_G.cormgr.labelList = {} + +local component = import("component") +local filesystem = import("filesystem") +local json = import("json") +local gpu = component.gpu +--local ocelot = component.ocelot + +function _G.cormgr.loadCoroutine(path,...) + local args = {...} + local function corFunction() + local result, errorMessage = xpcall(function(...) + import(...) + end, function(errorMessage) + return errorMessage .. "\n \n" .. debug.traceback() + end, path, table.unpack(args)) + if not result then + if print then + gpu.freeAllBuffers() + print("\n\27[91m" .. errorMessage) + else + error(errorMessage) + end + end + --import(path, table.unpack(args)) + end + cormgr.addCoroutine(corFunction, string.match(tostring(path), "([^/]+)%.lua$")) +end + +function _G.cormgr.addCoroutine(func, name) + local cor = coroutine.create(func) + table.insert(cormgr.corList, cor) + table.insert(cormgr.labelList, name) + return cor +end + +function _G.cormgr.removeCoroutine(name) + local index = table.find(cormgr.labelList, cor) + table.remove(cormgr.corList, index) + table.remove(cormgr.labelList, index) + --coroutine.close(cor) +end + +function handleError(errormsg) + if errormsg == nil then + error("unknown error") + else + error(tostring(errormsg).."\n \n"..debug.traceback()) + end +end + +local function runCoroutines() + for i = 1, #_G.cormgr.corList do + if cormgr.corList[i] then + local result, errorMessage = coroutine.resume(cormgr.corList[i]) + if cormgr.corList[i] then + if not result then + handleError(errorMessage) + end + if coroutine.status(cormgr.corList[i]) == "dead" then + table.remove(cormgr.corList, i) + table.remove(cormgr.labelList, i) + --ocelot.log("Removed coroutine") + i = i - 1 + end + --computer.pullSignal(0) + --coroutine.yield() + end + end + end +end + +local handle, data, tmpdata = filesystem.open("/halyde/config/startupapps.json", "r"), "", nil +repeat + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") +until not tmpdata +handle:close() +for _, line in ipairs(json.decode(data)) do + if line ~= "" then + --[[ if _G.print then + print(line) + end ]] + _G.cormgr.loadCoroutine(line) + runCoroutines() + end +end +-- _G.cormgr.loadCoroutine("/halyde/core/shell.lua") + +while true do + runCoroutines() + if #_G.cormgr.corList == 0 then + computer.shutdown() + end +end diff --git a/halyde/kernel/datatools.lua b/halyde/core/datatools.lua similarity index 100% rename from halyde/kernel/datatools.lua rename to halyde/core/datatools.lua diff --git a/halyde/core/drvload.lua b/halyde/core/drvload.lua new file mode 100644 index 0000000..441b091 --- /dev/null +++ b/halyde/core/drvload.lua @@ -0,0 +1,46 @@ +local fs = import("filesystem") + +local driverPath = "/halyde/drivers" + +local drivers = fs.list(driverPath) +local driverTypes = {} + +local function loadDriver(drvName) + local driverData = import(fs.concat(driverPath, drvName)) + table.remove(drivers, table.find(drivers, drvName)) + if driverData.dependencies then + for _, dependency in pairs(driverData.dependencies) do + if table.find(drivers, dependency) then + loadDriver(dependency) + elseif table.find(drivers, dependency .. ".lua") then + loadDriver(dependency .. ".lua") + else + for typeLookupDrvName, typeLookupDrvType in pairs(driverTypes) do + if typeLookupDrvType == dependency then + loadDriver(typeLookupDrvName) + -- Don't break, because there can be multiple drivers of the correct type + end + end + end + end + end + --print(drvName) + if driverData.onStartup then -- I have no idea why would this not exist, but it's a failsafe + driverData.onStartup() + end + -- More functions to be implemented in the future +end + +for _, drvName in pairs(drivers) do -- Get all the driver types + local driverData = import(fs.concat(driverPath, drvName)) + if driverData.type then + --print(driverData.type) + driverTypes[drvName] = driverData.type -- Not the other way around because there can be multiple drivers of the same type, but there can't be multiple entries with the same key + end +end + +for _, drvName in pairs(drivers) do -- Load the drivers + if drvName:sub(-1, -1) ~= "/" then -- Check if it's not a directory. Otherwise it might be driver config + loadDriver(drvName) + end +end diff --git a/halyde/kernel/evmgr.lua b/halyde/core/evmgr.lua similarity index 57% rename from halyde/kernel/evmgr.lua rename to halyde/core/evmgr.lua index 861cfa1..7fb252f 100644 --- a/halyde/kernel/evmgr.lua +++ b/halyde/core/evmgr.lua @@ -2,11 +2,11 @@ _G.evmgr = {} _G.evmgr.eventQueue = {} local maxEventQueueLength = 10 -- increase if events start getting dropped -local computer = require("computer") +local computer = import("computer") -_G._PUBLIC.keyboard.ctrlDown = false -_G._PUBLIC.keyboard.altDown = false -_G._PUBLIC.keyboard.shiftDown = false +keyboard.ctrlDown = false +keyboard.altDown = false +keyboard.shiftDown = false --local ocelot = component.proxy(component.list("ocelot")()) @@ -16,31 +16,31 @@ while true do args = {computer.uptime(), computer.pullSignal(0)} if args and args[2] then table.insert(evmgr.eventQueue, args) - if _PUBLIC.keyboard then + if keyboard then if args[2] == "key_down" then local keycode = args[5] - local key = _PUBLIC.keyboard.keys[keycode] + local key = keyboard.keys[keycode] if key == "lcontrol" then - _PUBLIC.keyboard.ctrlDown = true + keyboard.ctrlDown = true elseif key == "lmenu" then - _PUBLIC.keyboard.altDown = true + keyboard.altDown = true elseif key == "lshift" then - _PUBLIC.keyboard.shiftDown = true - elseif key == "c" and _PUBLIC.keyboard.ctrlDown and _PUBLIC.keyboard.altDown then + keyboard.shiftDown = true + elseif key == "c" and keyboard.ctrlDown and keyboard.altDown then if print then - print("\n\27[91mCoroutine "..tostring(#tsched.tasks).." killed.") + print("\n\27[91mCoroutine "..tostring(#cormgr.corList).." killed.") end - tsched.tasks[#tsched.tasks] = nil + cormgr.corList[#cormgr.corList] = nil end elseif args[2] == "key_up" then local keycode = args[5] - local key = _PUBLIC.keyboard.keys[keycode] + local key = keyboard.keys[keycode] if key == "lcontrol" then - _PUBLIC.keyboard.ctrlDown = false + keyboard.ctrlDown = false elseif key == "lmenu" then - _PUBLIC.keyboard.altDown = false + keyboard.altDown = false elseif key == "lshift" then - _PUBLIC.keyboard.shiftDown = true + keyboard.shiftDown = true end end end diff --git a/halyde/core/fullkb.lua b/halyde/core/fullkb.lua new file mode 100644 index 0000000..e9c64de --- /dev/null +++ b/halyde/core/fullkb.lua @@ -0,0 +1,143 @@ +_G.keyboard = {["keys"] = {}} + +keyboard.keys["1"] = 0x02 +keyboard.keys["2"] = 0x03 +keyboard.keys["3"] = 0x04 +keyboard.keys["4"] = 0x05 +keyboard.keys["5"] = 0x06 +keyboard.keys["6"] = 0x07 +keyboard.keys["7"] = 0x08 +keyboard.keys["8"] = 0x09 +keyboard.keys["9"] = 0x0A +keyboard.keys["0"] = 0x0B +keyboard.keys.a = 0x1E +keyboard.keys.b = 0x30 +keyboard.keys.c = 0x2E +keyboard.keys.d = 0x20 +keyboard.keys.e = 0x12 +keyboard.keys.f = 0x21 +keyboard.keys.g = 0x22 +keyboard.keys.h = 0x23 +keyboard.keys.i = 0x17 +keyboard.keys.j = 0x24 +keyboard.keys.k = 0x25 +keyboard.keys.l = 0x26 +keyboard.keys.m = 0x32 +keyboard.keys.n = 0x31 +keyboard.keys.o = 0x18 +keyboard.keys.p = 0x19 +keyboard.keys.q = 0x10 +keyboard.keys.r = 0x13 +keyboard.keys.s = 0x1F +keyboard.keys.t = 0x14 +keyboard.keys.u = 0x16 +keyboard.keys.v = 0x2F +keyboard.keys.w = 0x11 +keyboard.keys.x = 0x2D +keyboard.keys.y = 0x15 +keyboard.keys.z = 0x2C + +keyboard.keys.apostrophe = 0x28 +keyboard.keys.at = 0x91 +keyboard.keys.back = 0x0E -- backspace +keyboard.keys.backslash = 0x2B +keyboard.keys.capital = 0x3A -- capslock +keyboard.keys.colon = 0x92 +keyboard.keys.comma = 0x33 +keyboard.keys.enter = 0x1C +keyboard.keys.equals = 0x0D +keyboard.keys.grave = 0x29 -- accent grave +keyboard.keys.lbracket = 0x1A +keyboard.keys.lcontrol = 0x1D +keyboard.keys.lmenu = 0x38 -- left Alt +keyboard.keys.lshift = 0x2A +keyboard.keys.minus = 0x0C +keyboard.keys.numlock = 0x45 +keyboard.keys.pause = 0xC5 +keyboard.keys.period = 0x34 +keyboard.keys.rbracket = 0x1B +keyboard.keys.rcontrol = 0x9D +keyboard.keys.rmenu = 0xB8 -- right Alt +keyboard.keys.rshift = 0x36 +keyboard.keys.scroll = 0x46 -- Scroll Lock +keyboard.keys.semicolon = 0x27 +keyboard.keys.slash = 0x35 -- / on main keyboard +keyboard.keys.space = 0x39 +keyboard.keys.stop = 0x95 +keyboard.keys.tab = 0x0F +keyboard.keys.underline = 0x93 + +-- Keypad (and numpad with numlock off) +keyboard.keys.up = 0xC8 +keyboard.keys.down = 0xD0 +keyboard.keys.left = 0xCB +keyboard.keys.right = 0xCD +keyboard.keys.home = 0xC7 +keyboard.keys["end"] = 0xCF +keyboard.keys.pageUp = 0xC9 +keyboard.keys.pageDown = 0xD1 +keyboard.keys.insert = 0xD2 +keyboard.keys.delete = 0xD3 + +-- Function keys +keyboard.keys.f1 = 0x3B +keyboard.keys.f2 = 0x3C +keyboard.keys.f3 = 0x3D +keyboard.keys.f4 = 0x3E +keyboard.keys.f5 = 0x3F +keyboard.keys.f6 = 0x40 +keyboard.keys.f7 = 0x41 +keyboard.keys.f8 = 0x42 +keyboard.keys.f9 = 0x43 +keyboard.keys.f10 = 0x44 +keyboard.keys.f11 = 0x57 +keyboard.keys.f12 = 0x58 +keyboard.keys.f13 = 0x64 +keyboard.keys.f14 = 0x65 +keyboard.keys.f15 = 0x66 +keyboard.keys.f16 = 0x67 +keyboard.keys.f17 = 0x68 +keyboard.keys.f18 = 0x69 +keyboard.keys.f19 = 0x71 + +-- Japanese keyboards +keyboard.keys.kana = 0x70 +keyboard.keys.kanji = 0x94 +keyboard.keys.convert = 0x79 +keyboard.keys.noconvert = 0x7B +keyboard.keys.yen = 0x7D +keyboard.keys.circumflex = 0x90 +keyboard.keys.ax = 0x96 + +-- Numpad +keyboard.keys.numpad0 = 0x52 +keyboard.keys.numpad1 = 0x4F +keyboard.keys.numpad2 = 0x50 +keyboard.keys.numpad3 = 0x51 +keyboard.keys.numpad4 = 0x4B +keyboard.keys.numpad5 = 0x4C +keyboard.keys.numpad6 = 0x4D +keyboard.keys.numpad7 = 0x47 +keyboard.keys.numpad8 = 0x48 +keyboard.keys.numpad9 = 0x49 +keyboard.keys.numpadmul = 0x37 +keyboard.keys.numpaddiv = 0xB5 +keyboard.keys.numpadsub = 0x4A +keyboard.keys.numpadadd = 0x4E +keyboard.keys.numpaddecimal = 0x53 +keyboard.keys.numpadcomma = 0xB3 +keyboard.keys.numpadenter = 0x9C +keyboard.keys.numpadequals = 0x8D + +-- Create inverse mapping for name lookup. +setmetatable(keyboard.keys, +{ + __index = function(tbl, k) + if type(k) ~= "number" then return end + for name,value in pairs(tbl) do + if value == k then + return name + end + end + end +}) diff --git a/halyde/shell/shell.lua b/halyde/core/shell.lua similarity index 83% rename from halyde/shell/shell.lua rename to halyde/core/shell.lua index efc5937..f75b189 100644 --- a/halyde/shell/shell.lua +++ b/halyde/core/shell.lua @@ -1,5 +1,5 @@ -local fs = require("filesystem") -local json = require("json") +local fs = import("filesystem") +local json = import("json") local handle, data, tmpdata = fs.open("/halyde/config/shell.json", "r"), "", nil repeat tmpdata = handle:read(math.huge) @@ -7,21 +7,23 @@ repeat until not tmpdata handle:close() local shellcfg = json.decode(data) -local component = require("component") +import("/halyde/core/termlib.lua") +local event = import("event") +local component = import("component") local gpu = component.gpu _G.shell = {} _G.shell.workingDirectory = shellcfg["defaultWorkingDirectory"] _G.shell.aliases = shellcfg["aliases"] -local function runAsTask(path, ...) +local function runAsCoroutine(path, ...) --ocelot.log("running " .. path .. " as coroutine") - tsched.runAsTask(path, ...) - local corIndex = #tsched.getTasks() - local task = tsched.getTasks()[#tsched.getTasks()] + cormgr.loadCoroutine(path, ...) + local corIndex = #cormgr.corList + local cor = cormgr.corList[#cormgr.corList] repeat coroutine.yield() - until tsched.getTasks()[corIndex] ~= task + until cormgr.corList[corIndex] ~= cor end function _G.shell.run(command) @@ -64,14 +66,14 @@ function _G.shell.run(command) if fs.exists(args[1]) and not fs.isDirectory(args[1]) then local path = args[1] table.remove(args, 1) - runAsTask(path, table.unpack(args)) + runAsCoroutine(path, table.unpack(args)) return end for _, item in pairs(PATH) do if fs.exists(item..args[1]) and not fs.isDirectory(item .. args[1]) then local path = fs.concat(item, args[1]) table.remove(args, 1) - runAsTask(path, table.unpack(args)) + runAsCoroutine(path, table.unpack(args)) return else -- try to look for it without the file extension local files = fs.list(item) or {} @@ -79,7 +81,7 @@ function _G.shell.run(command) -- previous pattern: (.+)%.[^%.]+$ if args[1] == file:match("(.+)%.[^%.]+$") and not fs.isDirectory(item .. file) then table.remove(args, 1) - runAsTask(item .. file, table.unpack(args)) + runAsCoroutine(item .. file, table.unpack(args)) return end end @@ -98,7 +100,7 @@ while true do if shell.workingDirectory:sub(-1, -1) ~= "/" then shell.workingDirectory = shell.workingDirectory .. "/" end - local shellCommand = terminal.read("shell", shellcfg.prompt:format(shell.workingDirectory)) + local shellCommand = read("shell", shellcfg.prompt:format(shell.workingDirectory)) shell.run(shellCommand) gpu.freeAllBuffers() end diff --git a/halyde/core/termlib.lua b/halyde/core/termlib.lua new file mode 100644 index 0000000..1d1e74b --- /dev/null +++ b/halyde/core/termlib.lua @@ -0,0 +1,453 @@ +local serialize = import("serialize") +local unicode = import("unicode") +local event = import("event") +--local keyboard = import("keyboard") + +--local ocelot = component.proxy(component.list("ocelot")()) +local component = import("component") +local computer = import("computer") +local gpu = component.gpu +_G.termlib = {} +termlib.cursorPosX = 1 +termlib.cursorPosY = 1 +termlib.readHistory = {} + +local width, height = gpu.getResolution() + +local ANSIColorPalette = { + ["dark"] = { + [0] = 0x000000, + [1] = 0x800000, + [2] = 0x008000, + [3] = 0x808000, + [4] = 0x000080, + [5] = 0x800080, + [6] = 0x008080, + [7] = 0xC0C0C0 + }, + ["bright"] = { + [0] = 0x808080, + [1] = 0xFF0000, + [2] = 0x00FF00, + [3] = 0xFFFF00, + [4] = 0x0000FF, + [5] = 0xFF00FF, + [6] = 0x00FFFF, + [7] = 0xFFFFFF + } +} + +defaultForegroundColor = ANSIColorPalette["bright"][7] +defaultBackgroundColor = ANSIColorPalette["dark"][0] + +gpu.setForeground(defaultForegroundColor) +gpu.setBackground(defaultBackgroundColor) + +local function scrollDown() + local width, height = gpu.getResolution() + if gpu.copy(1,1,width,height,0,-1) then + local prevForeground = gpu.getForeground() + local prevBackground = gpu.getBackground() + gpu.setForeground(defaultForegroundColor) + gpu.setBackground(defaultBackgroundColor) + gpu.fill(1, height, width, 1, " ") + gpu.setForeground(prevForeground) + gpu.setBackground(prevBackground) + termlib.cursorPosY=height + end +end + +local function newLine() + termlib.cursorPosX=1 + termlib.cursorPosY = termlib.cursorPosY + 1 + if termlib.cursorPosY>height then + scrollDown() + end +end + +local function parseCodeNumbers(code) + local o = {} + for num in code:sub(3,-2):gmatch("[^;]+") do + table.insert(o,tonumber(num)) + end + return o +end + +local function from8BitColor(num) + num=math.floor(num)&255 + if num<16 then return 0x444444*((num>>3)&1)+(0xBB0000*((num>>2)&1)|0x00BB00*((num>>1)&1)|0x0000BB*(num&1)) end + if num>=232 then return 0x10101*(8+(num-232)*10) end + num=num-16 + local palette = {0,95,135,175,215,255} + return (palette[(num//36)%6+1]<<16)|(palette[(num//6)%6+1]<<8)|palette[num%6+1] +end + +local function from24BitColor(r,g,b) + r,g,b=math.floor(r)&255,math.floor(g)&255,math.floor(b)&255 + return (r<<16)|(g<<8)|b +end + +local function findCodeEnd(text,i) + local function inRange(v,min,max) + return v>=min and v<=max + end + i=i+2 + while i<=#text and not inRange(text:byte(i),0x40,0x7F) do i=i+1 end + return i +end + +function termlib.write(text, textWrap) + local width, height = gpu.getResolution() + + -- you don't know how tiring this was just for ANSI escape code support + + if textWrap == nil then + textWrap = true + end + + if not text or not tostring(text) then + return + end + if text:find("\a") then + computer.beep() + end + text = tostring(text) + text = "\27[0m" .. text:gsub("\t", " ") + local readBreak = 0 + -- readBreak is for when, inside the for loop, there normally would have been an increase in the "i" variable because it has read more than one character. + -- unfortunately, changing the "i" variable would have unpredictable effects, so to not risk anything, this workaround was done. + local section = "" + + local function printSection() + if #section==0 then + return + end + while true do + gpu.set(termlib.cursorPosX,termlib.cursorPosY,section) + if unicode.wlen(section) > width - termlib.cursorPosX + 1 and textWrap then + section = section:sub(width - termlib.cursorPosX + 2) + newLine() + else + termlib.cursorPosX = termlib.cursorPosX+unicode.wlen(section) + break + end + end + section = "" + end + + for i=1,#text do + if readBreak>0 then + readBreak = readBreak - 1 + goto continue + end + + if string.byte(text,i)==10 then + printSection() + newLine() + elseif string.byte(text,i)==13 then + printSection() + termlib.cursorPosX=1 + elseif string.byte(text,i)==0x1b and i<=#text-2 then + printSection() + --ocelot.log("0x1b char detected") + local codeType = string.sub(text,i+1,i+1) + if codeType=="[" then + -- Control Sequence Introducer + --ocelot.log("Control Sequence Introducer") + local codeEndIdx = findCodeEnd(text,i) + -- codeEndIdx = string.find(text,"m",i) + local code = string.sub(text,i,codeEndIdx) + --ocelot.log("Code: "..code.." ("..i..", "..codeEndIdx..")") + readBreak = readBreak + #code - 1 + local nums = parseCodeNumbers(code) + local codeEnd = code:sub(-1) + --ocelot.log("Code end: "..codeEnd..", "..#codeEnd) + if codeEnd == "m" then + -- Select Graphic Rendition + --ocelot.log("Select Graphic Rendition, ID "..nums[1]) + if nums[1]>=30 and nums[1]<=37 then + gpu.setForeground(ANSIColorPalette["dark"][nums[1]%10]) + end + if nums[1]==38 and nums[2]==5 then + gpu.setForeground(from8BitColor(nums[3])) + end + if nums[1]==38 and nums[2]==2 then + gpu.setForeground(from24BitColor(nums[3],nums[4],nums[5])) + end + if nums[1]==39 or nums[1]==0 then + gpu.setForeground(defaultForegroundColor) + end + if nums[1]>=40 and nums[1]<=47 then + gpu.setBackground(ANSIColorPalette["dark"][nums[1]%10]) + end + if nums[1]==48 and nums[2]==5 then + gpu.setBackground(from8BitColor(nums[3])) + end + if nums[1]==48 and nums[2]==2 then + gpu.setBackground(from24BitColor(nums[3],nums[4],nums[5])) + end + if nums[1]==49 or nums[1]==0 then + gpu.setBackground(defaultBackgroundColor) + end + if nums[1]>=90 and nums[1]<=97 then + gpu.setForeground(ANSIColorPalette["bright"][nums[1]%10]) + end + if nums[1]>=100 and nums[1]<=107 then + gpu.setBackground(ANSIColorPalette["bright"][nums[1]%10]) + end + end + end + else + --gpu.set(termlib.cursorPosX,termlib.cursorPosY,string.sub(text,i,i)) + section = section..string.sub(text,i,i) + end + ::continue:: + end + printSection() +end + +function _G.print(...) + local args = {...} + local stringArgs = {} + for _, arg in pairs(args) do + if type(arg)=="table" then + table.insert(stringArgs, serialize.table(arg,true)) + elseif tostring(arg) then + table.insert(stringArgs, tostring(arg)) + end + end + termlib.write(table.concat(stringArgs, " ") .. "\n") +end + +function _G.clear() + width, height = gpu.getResolution() + gpu.setForeground(defaultForegroundColor) + gpu.setBackground(defaultBackgroundColor) + gpu.fill(1,1,width,height," ") + termlib.cursorPosX, termlib.cursorPosY = 1, 1 +end + +function _G.read(readHistoryType, prefix, defaultText, maxChars) + checkArg(1, readHistoryType, "string", "nil") + checkArg(2, prefix, "string", "nil") + checkArg(3, defaultText, "string", "nil") + checkArg(4, maxChars, "number", "nil") + maxChars = maxChars or math.huge + + local text = defaultText or "" + + local historyIdx + if readHistoryType then + if not termlib.readHistory[readHistoryType] then + termlib.readHistory[readHistoryType] = {text} + elseif termlib.readHistory[readHistoryType][#termlib.readHistory[readHistoryType] ] ~= "" then + table.insert(termlib.readHistory[readHistoryType], text) + end + historyIdx = #termlib.readHistory[readHistoryType] + end + + local function updateHistory() + if not readHistoryType then return end + termlib.readHistory[readHistoryType][historyIdx]=text + end + + local cur = unicode.len(text)+1 + if prefix then termlib.write(prefix) end + local startX, startY = termlib.cursorPosX, termlib.cursorPosY + local fg, bg = gpu.getForeground(), gpu.getBackground() + local cursorBlink = true + local function get(idx) + idx=startX+idx-1 + return gpu.get(idx%width,startY+(idx//width)) + end + local function checkScroll(y) + for i=1,y-height do + scrollDown() + startY=startY-1 + end + return math.min(y,height) + end + local function set(idx,chr,rev) + if chr==nil or chr=="" then return end + if rev then + gpu.setForeground(bg) + gpu.setBackground(fg) + else + gpu.setForeground(fg) + gpu.setBackground(bg) + end + idx=startX+idx-1 + local setX, setY = (idx-1)%width+1, startY+((idx-1)//width+1)-1 + setY = checkScroll(setY) + gpu.set(setX,setY,unicode.sub(chr,1,width-setX+1)) + for i=1,math.ceil((#chr+setX-1)/width)+1 do + gpu.set(1,setY+i,unicode.sub(chr,2-setX+i*width,width+i*width-setX)) + setY = checkScroll(setY) + end + end + local function strDef(a,b) + if #a==0 then return b end + return a + end + local function curPos(cur) + return unicode.wlen(unicode.sub(text,1,cur-1))+1 + end + local function add(chr) + if type(chr)~="string" or #chr==0 then return end + if unicode.len(text)>=maxChars then return end + if maxChars1 then + text=unicode.sub(text,1,cur-2)..unicode.sub(text,cur) + cur=cur-1 + set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true) + cursorBlink = true + set(curPos(cur)+1,unicode.sub(text,cur+1).." ",false) + updateHistory() + elseif key=="delete" then + text = unicode.sub(text,1,cur-1)..unicode.sub(text,cur+1) + set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true) + cursorBlink = true + if cur<=unicode.len(text) then + set(curPos(cur+1),unicode.sub(text,cur+1).." ",false) + end + updateHistory() + elseif key=="enter" then + set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false) + break + elseif not (args[3]<32 or (args[3]>0x7F and args[3]<=0x9F)) then + add(unicode.char(args[3]) or " ") + updateHistory() + end + elseif args and args[1]=="clipboard" then + local clip = args[3] + if not args[3] then goto continue end + while isLine(unicode.sub(clip,1,1)) do clip=unicode.sub(clip,2) end + while isLine(unicode.sub(clip,-1)) do clip=unicode.sub(clip,1,-2) end + add(clip) + updateHistory() + else + cursorBlink=not cursorBlink + set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),cursorBlink) + end + ::continue:: + end + + if readHistoryType then + if termlib.readHistory[readHistoryType][#termlib.readHistory[readHistoryType]]=="" then + table.remove(termlib.readHistory[readHistoryType],#termlib.readHistory[readHistoryType]) + end + if historyIdx<#termlib.readHistory[readHistoryType] then + table.remove(termlib.readHistory[readHistoryType],historyIdx) + table.insert(termlib.readHistory[readHistoryType],text) + end + while #termlib.readHistory[readHistoryType] > 50 do + table.remove(termlib.readHistory[readHistoryType], 1) + end + end + + termlib.cursorPosX=1 + termlib.cursorPosY=termlib.cursorPosY+math.ceil((unicode.wlen(text)+startX-1)/width) + if termlib.cursorPosY>height then scrollDown() end + + return text +end diff --git a/halyde/kernel/boot.lua b/halyde/kernel/boot.lua deleted file mode 100644 index 27c5c41..0000000 --- a/halyde/kernel/boot.lua +++ /dev/null @@ -1,73 +0,0 @@ -local loadfile = ... -local filesystem = assert(loadfile("/lib/filesystem.lua")(loadfile)) -_G._OSVERSION = "HALYDE VERSION" -- TODO: Put this in a separate config file -_G._OSLOGO = "" -_G._PUBLIC = {} -local ocelot = component.proxy(component.list("ocelot")()) - -local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil -repeat - tmpdata = handle:read(math.huge) - _OSLOGO = _OSLOGO .. (tmpdata or "") -until not tmpdata - -_G.package = {["preloaded"] = {}} - -loadfile("/halyde/kernel/modules/datatools.lua")() - -function _G.require(module, ...) - ocelot.log("Requiring " .. module) - local args = table.pack(...) - if package.preloaded[module] then - return package.preloaded[module] - end - local modulepath - if filesystem.exists(module) then - modulepath = module - elseif filesystem.exists("/lib/" .. module .. ".lua") then - modulepath = "/lib/" .. module .. ".lua" - elseif shell and shell.workingDirectory and filesystem.exists(filesystem.concat(shell.workingDirectory, module .. ".lua")) then - modulepath = shell.workingDirectory .. module .. ".lua" - end - assert(modulepath, "Module not found\nPossible locations:\n/lib/" .. module .. ".lua") - local handle, data, tmpdata = filesystem.open(modulepath), "", nil - repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") - until not tmpdata - handle:close() - return(assert(load(data, "="..modulepath))(table.unpack(args))) -end - -function _G.package.preload(module) - local handle, data, tmpdata = assert(filesystem.open("/lib/" .. module .. ".lua", "r")), "", nil - repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") - until not tmpdata - handle:close() - package.preloaded[module] = assert(load(data, "="..module))() - _G[module] = nil -end - -require("/halyde/kernel/datatools.lua") -- If this is not imported BEFORE modload gets run, modload requires filesystem which requires computer which requires datatools. -require("/halyde/kernel/modload.lua") - -package.preload("component") -package.preload("computer") - -local component = require("component") -local gpu = component.gpu -local screenAddress = component.list("screen")() - -gpu.bind(screenAddress) -gpu.setResolution(gpu.maxResolution()) - -if not filesystem.exists("/halyde/config/shell.json") then -- Auto-generate configs - filesystem.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json") -end -if not filesystem.exists("/halyde/config/startupapps.json") then - filesystem.copy("/halyde/config/generate/startupapps.json", "/halyde/config/startupapps.json") -end - -require("/halyde/kernel/tsched.lua") diff --git a/halyde/kernel/modload.lua b/halyde/kernel/modload.lua deleted file mode 100644 index 6aa7dfa..0000000 --- a/halyde/kernel/modload.lua +++ /dev/null @@ -1,53 +0,0 @@ -local fs = require("filesystem") -local ocelot = require("component").ocelot - -local modulePath = "/halyde/kernel/modules" - -local modules = fs.list(modulePath) -local moduleTypes = {} - -local function loadModule(modName) - ocelot.log("Checking module " .. modName) - local moduleData = require(fs.concat(modulePath, modName)) - table.remove(modules, table.find(modules, modName)) - if not moduleData.check() then - return - end - ocelot.log("Loading module " .. modName) - if moduleData.dependencies then - for _, dependency in pairs(moduleData.dependencies) do - if table.find(modules, dependency) then - loadModule(dependency) - elseif table.find(modules, dependency .. ".lua") then - loadModule(dependency .. ".lua") - else - for typeLookupDrvName, typeLookupDrvType in pairs(moduleTypes) do - if typeLookupDrvType == dependency then - loadModule(typeLookupDrvName) - -- Don't break, because there can be multiple modules of the correct type - end - end - end - end - end - --print(modName) - if moduleData.init then -- I have no idea why this would not exist, but it's a failsafe - moduleData.init() - end -end - -for _, modName in pairs(modules) do -- Get all the module types - local moduleData = require(fs.concat(modulePath, modName)) - if moduleData.type then - --print(moduleData.type) - moduleTypes[modName] = moduleData.type -- Not the other way around because there can be multiple modules of the same type, but there can't be multiple entries with the same key - end -end - -while modules[1] do - if modules[1]:sub(-1, -1) ~= "/" then -- Check if it's not a directory. If it is, it might be module config - loadModule(modules[1]) - end -end - -ocelot.log("Finished loading modules!") diff --git a/halyde/kernel/modules/defenv.lua b/halyde/kernel/modules/defenv.lua deleted file mode 100644 index a3ab3a5..0000000 --- a/halyde/kernel/modules/defenv.lua +++ /dev/null @@ -1,53 +0,0 @@ -local module = {} - -module.dependencies = {"terminal"} - -function module.check() - return true -- This module should always be loaded -end - -function module.init() - local publicTable = { - "print", - "require", - "_VERSION", - "_OSVERSION", - "assert", - "error", - "getmetatable", - "ipairs", - "load", - "next", - "pairs", - "pcall", - "rawequal", - "rawget", - "rawlen", - "rawset", - "select", - "setmetatable", - "tonumber", - "tostring", - "type", - "xpcall", - "bit32", - "coroutine", - "debug", - "math", - "os", - "string", - "table", - "checkArg", - "utf8", - "convert" - } - for _, value in ipairs(publicTable) do - _G._PUBLIC[value] = table.copy(_G[value]) - end -end - -function module.exit() - _G._PUBLIC = nil -end - -return module diff --git a/halyde/kernel/modules/ipc.lua b/halyde/kernel/modules/ipc.lua deleted file mode 100644 index fbdbec7..0000000 --- a/halyde/kernel/modules/ipc.lua +++ /dev/null @@ -1,15 +0,0 @@ -local module = {} - -function module.check() - return true -- This module should always be loaded -end - -function module.init() - -end - -function module.exit() - -end - -return module diff --git a/halyde/kernel/modules/keyboard.lua b/halyde/kernel/modules/keyboard.lua deleted file mode 100644 index d20850d..0000000 --- a/halyde/kernel/modules/keyboard.lua +++ /dev/null @@ -1,157 +0,0 @@ -local module = {} - -function module.check() - return true -- This module should always be loaded -end - -function module.init() - _G._PUBLIC.keyboard = {["keys"] = {}} - - _PUBLIC.keyboard.keys["1"] = 0x02 - _PUBLIC.keyboard.keys["2"] = 0x03 - _PUBLIC.keyboard.keys["3"] = 0x04 - _PUBLIC.keyboard.keys["4"] = 0x05 - _PUBLIC.keyboard.keys["5"] = 0x06 - _PUBLIC.keyboard.keys["6"] = 0x07 - _PUBLIC.keyboard.keys["7"] = 0x08 - _PUBLIC.keyboard.keys["8"] = 0x09 - _PUBLIC.keyboard.keys["9"] = 0x0A - _PUBLIC.keyboard.keys["0"] = 0x0B - _PUBLIC.keyboard.keys.a = 0x1E - _PUBLIC.keyboard.keys.b = 0x30 - _PUBLIC.keyboard.keys.c = 0x2E - _PUBLIC.keyboard.keys.d = 0x20 - _PUBLIC.keyboard.keys.e = 0x12 - _PUBLIC.keyboard.keys.f = 0x21 - _PUBLIC.keyboard.keys.g = 0x22 - _PUBLIC.keyboard.keys.h = 0x23 - _PUBLIC.keyboard.keys.i = 0x17 - _PUBLIC.keyboard.keys.j = 0x24 - _PUBLIC.keyboard.keys.k = 0x25 - _PUBLIC.keyboard.keys.l = 0x26 - _PUBLIC.keyboard.keys.m = 0x32 - _PUBLIC.keyboard.keys.n = 0x31 - _PUBLIC.keyboard.keys.o = 0x18 - _PUBLIC.keyboard.keys.p = 0x19 - _PUBLIC.keyboard.keys.q = 0x10 - _PUBLIC.keyboard.keys.r = 0x13 - _PUBLIC.keyboard.keys.s = 0x1F - _PUBLIC.keyboard.keys.t = 0x14 - _PUBLIC.keyboard.keys.u = 0x16 - _PUBLIC.keyboard.keys.v = 0x2F - _PUBLIC.keyboard.keys.w = 0x11 - _PUBLIC.keyboard.keys.x = 0x2D - _PUBLIC.keyboard.keys.y = 0x15 - _PUBLIC.keyboard.keys.z = 0x2C - - _PUBLIC.keyboard.keys.apostrophe = 0x28 - _PUBLIC.keyboard.keys.at = 0x91 - _PUBLIC.keyboard.keys.back = 0x0E -- backspace - _PUBLIC.keyboard.keys.backslash = 0x2B - _PUBLIC.keyboard.keys.capital = 0x3A -- capslock - _PUBLIC.keyboard.keys.colon = 0x92 - _PUBLIC.keyboard.keys.comma = 0x33 - _PUBLIC.keyboard.keys.enter = 0x1C - _PUBLIC.keyboard.keys.equals = 0x0D - _PUBLIC.keyboard.keys.grave = 0x29 -- accent grave - _PUBLIC.keyboard.keys.lbracket = 0x1A - _PUBLIC.keyboard.keys.lcontrol = 0x1D - _PUBLIC.keyboard.keys.lmenu = 0x38 -- left Alt - _PUBLIC.keyboard.keys.lshift = 0x2A - _PUBLIC.keyboard.keys.minus = 0x0C - _PUBLIC.keyboard.keys.numlock = 0x45 - _PUBLIC.keyboard.keys.pause = 0xC5 - _PUBLIC.keyboard.keys.period = 0x34 - _PUBLIC.keyboard.keys.rbracket = 0x1B - _PUBLIC.keyboard.keys.rcontrol = 0x9D - _PUBLIC.keyboard.keys.rmenu = 0xB8 -- right Alt - _PUBLIC.keyboard.keys.rshift = 0x36 - _PUBLIC.keyboard.keys.scroll = 0x46 -- Scroll Lock - _PUBLIC.keyboard.keys.semicolon = 0x27 - _PUBLIC.keyboard.keys.slash = 0x35 -- / on main _PUBLIC.keyboard - _PUBLIC.keyboard.keys.space = 0x39 - _PUBLIC.keyboard.keys.stop = 0x95 - _PUBLIC.keyboard.keys.tab = 0x0F - _PUBLIC.keyboard.keys.underline = 0x93 - - -- Keypad (and numpad with numlock off) - _PUBLIC.keyboard.keys.up = 0xC8 - _PUBLIC.keyboard.keys.down = 0xD0 - _PUBLIC.keyboard.keys.left = 0xCB - _PUBLIC.keyboard.keys.right = 0xCD - _PUBLIC.keyboard.keys.home = 0xC7 - _PUBLIC.keyboard.keys["end"] = 0xCF - _PUBLIC.keyboard.keys.pageUp = 0xC9 - _PUBLIC.keyboard.keys.pageDown = 0xD1 - _PUBLIC.keyboard.keys.insert = 0xD2 - _PUBLIC.keyboard.keys.delete = 0xD3 - - -- Function keys - _PUBLIC.keyboard.keys.f1 = 0x3B - _PUBLIC.keyboard.keys.f2 = 0x3C - _PUBLIC.keyboard.keys.f3 = 0x3D - _PUBLIC.keyboard.keys.f4 = 0x3E - _PUBLIC.keyboard.keys.f5 = 0x3F - _PUBLIC.keyboard.keys.f6 = 0x40 - _PUBLIC.keyboard.keys.f7 = 0x41 - _PUBLIC.keyboard.keys.f8 = 0x42 - _PUBLIC.keyboard.keys.f9 = 0x43 - _PUBLIC.keyboard.keys.f10 = 0x44 - _PUBLIC.keyboard.keys.f11 = 0x57 - _PUBLIC.keyboard.keys.f12 = 0x58 - _PUBLIC.keyboard.keys.f13 = 0x64 - _PUBLIC.keyboard.keys.f14 = 0x65 - _PUBLIC.keyboard.keys.f15 = 0x66 - _PUBLIC.keyboard.keys.f16 = 0x67 - _PUBLIC.keyboard.keys.f17 = 0x68 - _PUBLIC.keyboard.keys.f18 = 0x69 - _PUBLIC.keyboard.keys.f19 = 0x71 - - -- Japanese keyboards - _PUBLIC.keyboard.keys.kana = 0x70 - _PUBLIC.keyboard.keys.kanji = 0x94 - _PUBLIC.keyboard.keys.convert = 0x79 - _PUBLIC.keyboard.keys.noconvert = 0x7B - _PUBLIC.keyboard.keys.yen = 0x7D - _PUBLIC.keyboard.keys.circumflex = 0x90 - _PUBLIC.keyboard.keys.ax = 0x96 - - -- Numpad - _PUBLIC.keyboard.keys.numpad0 = 0x52 - _PUBLIC.keyboard.keys.numpad1 = 0x4F - _PUBLIC.keyboard.keys.numpad2 = 0x50 - _PUBLIC.keyboard.keys.numpad3 = 0x51 - _PUBLIC.keyboard.keys.numpad4 = 0x4B - _PUBLIC.keyboard.keys.numpad5 = 0x4C - _PUBLIC.keyboard.keys.numpad6 = 0x4D - _PUBLIC.keyboard.keys.numpad7 = 0x47 - _PUBLIC.keyboard.keys.numpad8 = 0x48 - _PUBLIC.keyboard.keys.numpad9 = 0x49 - _PUBLIC.keyboard.keys.numpadmul = 0x37 - _PUBLIC.keyboard.keys.numpaddiv = 0xB5 - _PUBLIC.keyboard.keys.numpadsub = 0x4A - _PUBLIC.keyboard.keys.numpadadd = 0x4E - _PUBLIC.keyboard.keys.numpaddecimal = 0x53 - _PUBLIC.keyboard.keys.numpadcomma = 0xB3 - _PUBLIC.keyboard.keys.numpadenter = 0x9C - _PUBLIC.keyboard.keys.numpadequals = 0x8D - - -- Create inverse mapping for name lookup. - setmetatable(_PUBLIC.keyboard.keys, - { - __index = function(tbl, k) - if type(k) ~= "number" then return end - for name,value in pairs(tbl) do - if value == k then - return name - end - end - end - }) -end - -function module.exit() - _G._PUBLIC.keyboard = nil -end - -return module diff --git a/halyde/kernel/modules/terminal.lua b/halyde/kernel/modules/terminal.lua deleted file mode 100644 index 2d8fc94..0000000 --- a/halyde/kernel/modules/terminal.lua +++ /dev/null @@ -1,466 +0,0 @@ -local module = {} - -function module.check() - return true -- Usually always loaded, but maybe it would be worth it to check if the computer has a GPU or not? I'm not sure. -end - -function module.init() - local serialize = require("serialize") - local unicode = require("unicode") - local event = require("event") - - --local ocelot = component.proxy(component.list("ocelot")()) - local component = require("component") - local computer = require("computer") - local gpu = component.gpu - _G._PUBLIC.terminal = {} - _PUBLIC.terminal.cursorPosX = 1 - _PUBLIC.terminal.cursorPosY = 1 - _PUBLIC.terminal.readHistory = {} - - local width, height = gpu.getResolution() - - local ANSIColorPalette = { - ["dark"] = { - [0] = 0x000000, - [1] = 0x800000, - [2] = 0x008000, - [3] = 0x808000, - [4] = 0x000080, - [5] = 0x800080, - [6] = 0x008080, - [7] = 0xC0C0C0 - }, - ["bright"] = { - [0] = 0x808080, - [1] = 0xFF0000, - [2] = 0x00FF00, - [3] = 0xFFFF00, - [4] = 0x0000FF, - [5] = 0xFF00FF, - [6] = 0x00FFFF, - [7] = 0xFFFFFF - } - } - - defaultForegroundColor = ANSIColorPalette["bright"][7] - defaultBackgroundColor = ANSIColorPalette["dark"][0] - - gpu.setForeground(defaultForegroundColor) - gpu.setBackground(defaultBackgroundColor) - - local function scrollDown() - local width, height = gpu.getResolution() - if gpu.copy(1,1,width,height,0,-1) then - local prevForeground = gpu.getForeground() - local prevBackground = gpu.getBackground() - gpu.setForeground(defaultForegroundColor) - gpu.setBackground(defaultBackgroundColor) - gpu.fill(1, height, width, 1, " ") - gpu.setForeground(prevForeground) - gpu.setBackground(prevBackground) - _PUBLIC.terminal.cursorPosY=height - end - end - - local function newLine() - _PUBLIC.terminal.cursorPosX=1 - _PUBLIC.terminal.cursorPosY = _PUBLIC.terminal.cursorPosY + 1 - if _PUBLIC.terminal.cursorPosY>height then - scrollDown() - end - end - - local function parseCodeNumbers(code) - local o = {} - for num in code:sub(3,-2):gmatch("[^;]+") do - table.insert(o,tonumber(num)) - end - return o - end - - local function from8BitColor(num) - num=math.floor(num)&255 - if num<16 then return 0x444444*((num>>3)&1)+(0xBB0000*((num>>2)&1)|0x00BB00*((num>>1)&1)|0x0000BB*(num&1)) end - if num>=232 then return 0x10101*(8+(num-232)*10) end - num=num-16 - local palette = {0,95,135,175,215,255} - return (palette[(num//36)%6+1]<<16)|(palette[(num//6)%6+1]<<8)|palette[num%6+1] - end - - local function from24BitColor(r,g,b) - r,g,b=math.floor(r)&255,math.floor(g)&255,math.floor(b)&255 - return (r<<16)|(g<<8)|b - end - - local function findCodeEnd(text,i) - local function inRange(v,min,max) - return v>=min and v<=max - end - i=i+2 - while i<=#text and not inRange(text:byte(i),0x40,0x7F) do i=i+1 end - return i - end - - function _PUBLIC.terminal.write(text, textWrap) - local width, height = gpu.getResolution() - - -- you don't know how tiring this was just for ANSI escape code support - - if textWrap == nil then - textWrap = true - end - - if not text or not tostring(text) then - return - end - if text:find("\a") then - computer.beep() - end - text = tostring(text) - text = "\27[0m" .. text:gsub("\t", " ") - local readBreak = 0 - -- readBreak is for when, inside the for loop, there normally would have been an increase in the "i" variable because it has read more than one character. - -- unfortunately, changing the "i" variable would have unpredictable effects, so to not risk anything, this workaround was done. - local section = "" - - local function printSection() - if #section==0 then - return - end - while true do - gpu.set(_PUBLIC.terminal.cursorPosX,_PUBLIC.terminal.cursorPosY,section) - if unicode.wlen(section) > width - _PUBLIC.terminal.cursorPosX + 1 and textWrap then - section = section:sub(width - _PUBLIC.terminal.cursorPosX + 2) - newLine() - else - _PUBLIC.terminal.cursorPosX = _PUBLIC.terminal.cursorPosX+unicode.wlen(section) - break - end - end - section = "" - end - - for i=1,#text do - if readBreak>0 then - readBreak = readBreak - 1 - goto continue - end - - if string.byte(text,i)==10 then - printSection() - newLine() - elseif string.byte(text,i)==13 then - printSection() - _PUBLIC.terminal.cursorPosX=1 - elseif string.byte(text,i)==0x1b and i<=#text-2 then - printSection() - --ocelot.log("0x1b char detected") - local codeType = string.sub(text,i+1,i+1) - if codeType=="[" then - -- Control Sequence Introducer - --ocelot.log("Control Sequence Introducer") - local codeEndIdx = findCodeEnd(text,i) - -- codeEndIdx = string.find(text,"m",i) - local code = string.sub(text,i,codeEndIdx) - --ocelot.log("Code: "..code.." ("..i..", "..codeEndIdx..")") - readBreak = readBreak + #code - 1 - local nums = parseCodeNumbers(code) - local codeEnd = code:sub(-1) - --ocelot.log("Code end: "..codeEnd..", "..#codeEnd) - if codeEnd == "m" then - -- Select Graphic Rendition - --ocelot.log("Select Graphic Rendition, ID "..nums[1]) - if nums[1]>=30 and nums[1]<=37 then - gpu.setForeground(ANSIColorPalette["dark"][nums[1]%10]) - end - if nums[1]==38 and nums[2]==5 then - gpu.setForeground(from8BitColor(nums[3])) - end - if nums[1]==38 and nums[2]==2 then - gpu.setForeground(from24BitColor(nums[3],nums[4],nums[5])) - end - if nums[1]==39 or nums[1]==0 then - gpu.setForeground(defaultForegroundColor) - end - if nums[1]>=40 and nums[1]<=47 then - gpu.setBackground(ANSIColorPalette["dark"][nums[1]%10]) - end - if nums[1]==48 and nums[2]==5 then - gpu.setBackground(from8BitColor(nums[3])) - end - if nums[1]==48 and nums[2]==2 then - gpu.setBackground(from24BitColor(nums[3],nums[4],nums[5])) - end - if nums[1]==49 or nums[1]==0 then - gpu.setBackground(defaultBackgroundColor) - end - if nums[1]>=90 and nums[1]<=97 then - gpu.setForeground(ANSIColorPalette["bright"][nums[1]%10]) - end - if nums[1]>=100 and nums[1]<=107 then - gpu.setBackground(ANSIColorPalette["bright"][nums[1]%10]) - end - end - end - else - --gpu.set(_PUBLIC.terminal.cursorPosX,_PUBLIC.terminal.cursorPosY,string.sub(text,i,i)) - section = section..string.sub(text,i,i) - end - ::continue:: - end - printSection() - end - - function _G.print(...) - local args = {...} - local stringArgs = {} - for _, arg in pairs(args) do - if type(arg)=="table" then - table.insert(stringArgs, serialize.table(arg,true)) - elseif tostring(arg) then - table.insert(stringArgs, tostring(arg)) - end - end - _PUBLIC.terminal.write(table.concat(stringArgs, " ") .. "\n") - end - - function _G._PUBLIC.terminal.clear() - width, height = gpu.getResolution() - gpu.setForeground(defaultForegroundColor) - gpu.setBackground(defaultBackgroundColor) - gpu.fill(1,1,width,height," ") - _PUBLIC.terminal.cursorPosX, _PUBLIC.terminal.cursorPosY = 1, 1 - end - - function _G._PUBLIC.terminal.read(readHistoryType, prefix, defaultText, maxChars) - checkArg(1, readHistoryType, "string", "nil") - checkArg(2, prefix, "string", "nil") - checkArg(3, defaultText, "string", "nil") - checkArg(4, maxChars, "number", "nil") - maxChars = maxChars or math.huge - - local text = defaultText or "" - - local historyIdx - if readHistoryType then - if not _PUBLIC.terminal.readHistory[readHistoryType] then - _PUBLIC.terminal.readHistory[readHistoryType] = {text} - elseif _PUBLIC.terminal.readHistory[readHistoryType][#_PUBLIC.terminal.readHistory[readHistoryType] ] ~= "" then - table.insert(_PUBLIC.terminal.readHistory[readHistoryType], text) - end - historyIdx = #_PUBLIC.terminal.readHistory[readHistoryType] - end - - local function updateHistory() - if not readHistoryType then return end - _PUBLIC.terminal.readHistory[readHistoryType][historyIdx]=text - end - - local cur = unicode.len(text)+1 - if prefix then _PUBLIC.terminal.write(prefix) end - local startX, startY = _PUBLIC.terminal.cursorPosX, _PUBLIC.terminal.cursorPosY - local fg, bg = gpu.getForeground(), gpu.getBackground() - local cursorBlink = true - local function get(idx) - idx=startX+idx-1 - return gpu.get(idx%width,startY+(idx//width)) - end - local function checkScroll(y) - for i=1,y-height do - scrollDown() - startY=startY-1 - end - return math.min(y,height) - end - local function set(idx,chr,rev) - if chr==nil or chr=="" then return end - if rev then - gpu.setForeground(bg) - gpu.setBackground(fg) - else - gpu.setForeground(fg) - gpu.setBackground(bg) - end - idx=startX+idx-1 - local setX, setY = (idx-1)%width+1, startY+((idx-1)//width+1)-1 - setY = checkScroll(setY) - gpu.set(setX,setY,unicode.sub(chr,1,width-setX+1)) - for i=1,math.ceil((#chr+setX-1)/width)+1 do - gpu.set(1,setY+i,unicode.sub(chr,2-setX+i*width,width+i*width-setX)) - setY = checkScroll(setY) - end - end - local function strDef(a,b) - if #a==0 then return b end - return a - end - local function curPos(cur) - return unicode.wlen(unicode.sub(text,1,cur-1))+1 - end - local function add(chr) - if type(chr)~="string" or #chr==0 then return end - if unicode.len(text)>=maxChars then return end - if maxChars1 then - text=unicode.sub(text,1,cur-2)..unicode.sub(text,cur) - cur=cur-1 - set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true) - cursorBlink = true - set(curPos(cur)+1,unicode.sub(text,cur+1).." ",false) - updateHistory() - elseif key=="delete" then - text = unicode.sub(text,1,cur-1)..unicode.sub(text,cur+1) - set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),true) - cursorBlink = true - if cur<=unicode.len(text) then - set(curPos(cur+1),unicode.sub(text,cur+1).." ",false) - end - updateHistory() - elseif key=="enter" then - set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),false) - break - elseif not (args[3]<32 or (args[3]>0x7F and args[3]<=0x9F)) then - add(unicode.char(args[3]) or " ") - updateHistory() - end - elseif args and args[1]=="clipboard" then - local clip = args[3] - if not args[3] then goto continue end - while isLine(unicode.sub(clip,1,1)) do clip=unicode.sub(clip,2) end - while isLine(unicode.sub(clip,-1)) do clip=unicode.sub(clip,1,-2) end - add(clip) - updateHistory() - else - cursorBlink=not cursorBlink - set(curPos(cur),strDef(unicode.sub(text,cur,cur)," "),cursorBlink) - end - ::continue:: - end - - if readHistoryType then - if _PUBLIC.terminal.readHistory[readHistoryType][#_PUBLIC.terminal.readHistory[readHistoryType]]=="" then - table.remove(_PUBLIC.terminal.readHistory[readHistoryType],#_PUBLIC.terminal.readHistory[readHistoryType]) - end - if historyIdx<#_PUBLIC.terminal.readHistory[readHistoryType] then - table.remove(_PUBLIC.terminal.readHistory[readHistoryType],historyIdx) - table.insert(_PUBLIC.terminal.readHistory[readHistoryType],text) - end - while #_PUBLIC.terminal.readHistory[readHistoryType] > 50 do - table.remove(_PUBLIC.terminal.readHistory[readHistoryType], 1) - end - end - - _PUBLIC.terminal.cursorPosX=1 - _PUBLIC.terminal.cursorPosY=_PUBLIC.terminal.cursorPosY+math.ceil((unicode.wlen(text)+startX-1)/width) - if _PUBLIC.terminal.cursorPosY>height then scrollDown() end - - return text - end -end - -function module.exit() - _G._PUBLIC.terminal = nil -end - -return module diff --git a/halyde/kernel/tsched.lua b/halyde/kernel/tsched.lua deleted file mode 100644 index 865a1eb..0000000 --- a/halyde/kernel/tsched.lua +++ /dev/null @@ -1,149 +0,0 @@ -_G._PUBLIC.tsched = {} -_G.tsched = {} -_G.tsched.tasks = {} - -local currentTask - -local component = require("component") -local computer = require("computer") -local filesystem = require("filesystem") -local json = require("json") -local gpu = component.gpu -local ocelot = component.ocelot - -function _G._PUBLIC.tsched.runAsTask(path,...) - local args = {...} - local function taskFunction() - local result, errorMessage = xpcall(function(...) - local args = table.pack(...) - if not filesystem.exists(path) then - error("No such file: " .. path) - end - local handle, data, tmpdata = filesystem.open(path), "", nil - repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") - until not tmpdata - handle:close() - - -- Userland environment definition - local userland = table.copy(_PUBLIC) - userland._G = userland - - assert(load(data, "="..path, "t", userland))(table.unpack(args)) - end, function(errorMessage) - return errorMessage .. "\n \n" .. debug.traceback() - end, path, table.unpack(args)) - if not result then - if print then - gpu.freeAllBuffers() - print("\n\27[91m" .. errorMessage) - else - error(errorMessage) - end - end - --require(path, table.unpack(args)) - end - _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) -end - -function _G._PUBLIC.tsched.addTask(func, name) - ocelot.log("Added task " .. name) - local task = coroutine.create(func) - table.insert(tsched.tasks, {["task"] = task, ["name"] = name}) - return task -end - -function _G._PUBLIC.tsched.removeTask(id) - -- TODO: Check for user permissions before running - table.remove(_G.tsched.tasks, id) -end - -function handleError(errormsg) - if errormsg == nil then -- TODO: Replace with proper error handling (if this isn't considered proper..?) - print("\27[91munknown error" .. "\n \n" .. debug.traceback()) - else - print("\27[91m" .. tostring(errormsg) .. "\n \n" .. debug.traceback()) - end -end - -local function runTasks() - for i = 1, #_G.tsched.tasks do - if tsched.tasks[i] then - currentTask = tsched.tasks[i] - local result, errorMessage = coroutine.resume(tsched.tasks[i].task) - if not result then - handleError(errorMessage) - end - if coroutine.status(tsched.tasks[i].task) == "dead" then - _PUBLIC.tsched.removeTask(i) - --ocelot.log("Removed coroutine") - i = i - 1 - end - --computer.pullSignal(0) - --coroutine.yield() - end - end -end - -function _G._PUBLIC.tsched.getCurrentTask() - return table.copy(currentTask) -end - -function _G._PUBLIC.tsched.getTasks() - return table.copy(tsched.tasks) -end - -local function taskFunction() - local result, errorMessage = xpcall(function() - if not filesystem.exists("/halyde/kernel/evmgr.lua") then - error("No such file: /halyde/kernel/evmgr.lua") - end - local handle, data, tmpdata = filesystem.open("/halyde/kernel/evmgr.lua"), "", nil - repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") - until not tmpdata - handle:close() - assert(load(data, "=/halyde/kernel/evmgr.lua"))() - end, function(errorMessage) - return errorMessage .. "\n \n" .. debug.traceback() - end, "/halyde/kernel/evmgr.lua") - if not result then - if print then - gpu.freeAllBuffers() - print("\n\27[91m" .. errorMessage) - else - error(errorMessage) - end - end -end -_PUBLIC.tsched.addTask(taskFunction, "evmgr") -package.preload("event") - -local handle, data, tmpdata = filesystem.open("/halyde/config/startupapps.json", "r"), "", nil -repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") -until not tmpdata -handle:close() -for _, line in ipairs(json.decode(data)) do - if line ~= "" then - --[[ if _G.print then - print(line) - end ]] - _G._PUBLIC.tsched.runAsTask(line) - runTasks() - end -end --- _G.cormgr.loadCoroutine("/halyde/core/shell.lua") - -while true do - runTasks() - if #_G.tsched.tasks == 0 then - computer.beep(1000, 0.5) - while true do - computer.pullSignal() - end - end -end diff --git a/lib/component.lua b/halyde/lib/component.lua similarity index 100% rename from lib/component.lua rename to halyde/lib/component.lua diff --git a/lib/computer.lua b/halyde/lib/computer.lua similarity index 100% rename from lib/computer.lua rename to halyde/lib/computer.lua diff --git a/lib/event.lua b/halyde/lib/event.lua similarity index 97% rename from lib/event.lua rename to halyde/lib/event.lua index eada457..64547fa 100644 --- a/lib/event.lua +++ b/halyde/lib/event.lua @@ -1,4 +1,4 @@ -local computer = require("computer") +local computer = import("computer") local event = {} local bufferTime = 0.1 -- A little bit of buffer time so events won't be skipped by accident. diff --git a/lib/filesystem.lua b/halyde/lib/filesystem.lua similarity index 98% rename from lib/filesystem.lua rename to halyde/lib/filesystem.lua index 570e3c5..cbdd325 100644 --- a/lib/filesystem.lua +++ b/halyde/lib/filesystem.lua @@ -1,14 +1,14 @@ local loadfile = ... -- raw loadfile from boot.lua -local unicode, component, computer +local component, computer if loadfile then - unicode = loadfile("/lib/unicode.lua")(loadfile) - component = loadfile("/lib/component.lua")(loadfile) + unicode = loadfile("/halyde/lib/unicode.lua")(loadfile) + component = loadfile("/halyde/lib/component.lua")(loadfile) computer = _G.computer -elseif require then - unicode = require("unicode") - component = require("component") - computer = require("computer") +elseif import then + unicode = import("unicode") + component = import("component") + computer = import("computer") end local filesystem = {} diff --git a/lib/json.lua b/halyde/lib/json.lua similarity index 100% rename from lib/json.lua rename to halyde/lib/json.lua diff --git a/lib/raster.lua b/halyde/lib/raster.lua similarity index 99% rename from lib/raster.lua rename to halyde/lib/raster.lua index cff96a8..2709b75 100644 --- a/lib/raster.lua +++ b/halyde/lib/raster.lua @@ -9,7 +9,7 @@ local raster = { ["backgroundColor"]=0xFFFFFF } -local component = require("component") +local component = import("component") -- local ocelot = component.proxy(component.list("ocelot")()) local gpu = component.gpu diff --git a/lib/serialize.lua b/halyde/lib/serialize.lua similarity index 100% rename from lib/serialize.lua rename to halyde/lib/serialize.lua diff --git a/lib/unicode.lua b/halyde/lib/unicode.lua similarity index 100% rename from lib/unicode.lua rename to halyde/lib/unicode.lua diff --git a/halyde/system.log b/halyde/system.log deleted file mode 100644 index 5e48223..0000000 --- a/halyde/system.log +++ /dev/null @@ -1,4 +0,0 @@ -[00:00:04:12] Debug! -[00:00:04:19] Info! -[00:00:04:25] Warning! -[00:00:04:32] Error! diff --git a/home/test.lua b/home/test.lua deleted file mode 100644 index c6f637f..0000000 --- a/home/test.lua +++ /dev/null @@ -1,7 +0,0 @@ -local cor = coroutine.create(function() - print("Hello World!") -end) - -print(coroutine.status(cor)) -coroutine.resume(cor) -print(coroutine.status(cor)) diff --git a/init.lua b/init.lua index 463f850..56c7dcd 100644 --- a/init.lua +++ b/init.lua @@ -1,24 +1,5 @@ local gpu = component.proxy(component.list("gpu")()) -local resX, resY = gpu.getResolution() - --- Architecture check -local foundArchitecture = false -for _, arch in pairs(computer.getArchitectures()) do - if arch == "Lua 5.3" then - foundArchitecture = true - break - end -end - -if foundArchitecture then - computer.setArchitecture("Lua 5.3") -else - gpu.set(1, 1, "Required architecture (Lua 5.3) is not supported.") - gpu.set(1, 2, "Halting.") - while true do - computer.pullSignal() - end -end +local resx, resy = gpu.getResolution() local function loadfile(file) checkArg(1, file, "string") @@ -36,36 +17,36 @@ local function handleError(errorMessage) return(errorMessage.."\n \n"..debug.traceback()) end -function loadBoot() - loadfile("/halyde/kernel/boot.lua")(loadfile) +function loadthething() + loadfile("/halyde/core/boot.lua")(loadfile) end gpu.setBackground(0x000000) -gpu.fill(1, 1, resX, resY, " ") - --- Copying low-level functions in case of post-preload failure -local pullSignal = computer.pullSignal -local shutdown = computer.shutdown - -local result, reason = xpcall(loadBoot, handleError) +gpu.fill(1, 1, resx, resy, " ") +local result, reason = xpcall(loadthething, handleError) if not result then + if import then + local computer = import("computer") + end gpu.setBackground(0x000000) - gpu.fill(1, 1, resX, resY, " ") + gpu.fill(1, 1, resx, resy, " ") gpu.setBackground(0x800000) gpu.setForeground(0xFFFFFF) gpu.set(2,2,"A critical error has occurred.") local i = 4 - reason = tostring(reason):gsub("\t", " ") - for line in string.gmatch(reason or "unknown error", "([^\n]*)\n?") do + reason = reason:gsub("\t", " ") + for line in string.gmatch((reason ~= nil and tostring(reason)) or "unknown error", "([^\n]*)\n?") do gpu.set(2,i,line) i = i + 1 end - gpu.set(2,i+1, "Press any key to restart.") - local evname - repeat - evname = pullSignal() - until evname == "key_down" - shutdown(true) + if computer~=nil then + gpu.set(2,i+1, "Press any key to restart.") + local evname + repeat + evname = computer.pullSignal() + until evname == "key_down" + computer.shutdown(true) + end while true do coroutine.yield() end diff --git a/lib/log.lua b/lib/log.lua deleted file mode 100644 index fe8fb35..0000000 --- a/lib/log.lua +++ /dev/null @@ -1,30 +0,0 @@ -local fs = require("filesystem") -local computer = require("computer") - -local log = {} - -function log.add(text, logType) - checkArg(1, text, "string") - checkArg(2, logType, "string", "nil") - if logType ~= "debug" and logType ~= "info" and logType ~= "warning" and logType ~= "error" and logType then - error("Log type must either be debug, info, warning or error.") - end - if not logType then - logType = "debug" - end - local handle = fs.open("/halyde/system.log", "a") - local time = computer.uptime() - local logText = string.format("[%02d:%02d:%02d:%02d] " .. text, math.floor(time / 86400), math.floor(time / 3600 % 24), math.floor(time / 60 % 60), math.floor(time % 60)) .. "\n" - if logType == "debug" then - handle:write("\27[37m" .. logText) - elseif logType == "info" then - handle:write("\27[97m" .. logText) - elseif logType == "warning" then - handle:write("\27[93m" .. logText) - else - handle:write("\27[91m" .. logText) - end - handle:close() -end - -return log