| -- called from /init.lua | | -- called from /init.lua |
| local raw_loadfile = ... | | local raw_loadfile = ... |
| | | |
| _G._OSVERSION = "OpenOS 1.7.5" | | _G._OSVERSION = "OpenOS 1.7.5" |
| | | |
| | | local title = "OpenOS Loading" |
| | | |
| -- luacheck: globals component computer unicode _OSVERSION | | -- luacheck: globals component computer unicode _OSVERSION |
| local component = component | | local component = component |
| local computer = computer | | local computer = computer |
| local unicode = unicode | | local unicode = unicode |
| | | |
| -- Runlevel information. | | local function centrize(wi, screenWidth) |
| _G.runlevel = "S" | | return math.floor(screenWidth / 2 - wi / 2) |
| local shutdown = computer.shutdown | | end |
| computer.runlevel = function() return _G.runlevel end | | local runlevel, shutdown = "S", computer.shutdown |
| | | computer.runlevel = function() return runlevel end |
| computer.shutdown = function(reboot) | | computer.shutdown = function(reboot) |
| _G.runlevel = reboot and 6 or 0 | | runlevel = reboot and 6 or 0 |
| if os.sleep then | | if os.sleep then |
| computer.pushSignal("shutdown") | | computer.pushSignal("shutdown") |
| os.sleep(0.1) -- Allow shutdown processing. | | os.sleep(0.1) -- Allow shutdown processing. |
| end | | end |
| shutdown(reboot) | | shutdown(reboot) |
| end | | end |
| | | |
| local w, h | | local screen = component.list('screen', true)() |
| local screen = component.list("screen", true)() | | for address in component.list('screen', true) do |
| local gpu = screen and component.list("gpu", true)() | | if #component.invoke(address, 'getKeyboards') > 0 then |
| if gpu then | | screen = address |
| gpu = component.proxy(gpu) | | break |
| if not gpu.getScreen() then | | |
| gpu.bind(screen) | | |
| end | | end |
| _G.boot_screen = gpu.getScreen() | | end |
| w, h = gpu.maxResolution() | | |
| gpu.setResolution(w, h) | | _G.boot_screen = screen |
| gpu.setBackground(0x000000) | | local gpu = component.list("gpu", true)() |
| gpu.setForeground(0xFFFFFF) | | local w, h = 160, 50 |
| gpu.fill(1, 1, w, h, " ") | | if gpu and screen then |
| | | component.invoke(gpu, "bind", screen) |
| | | w, h = component.invoke(gpu, "maxResolution") |
| | | component.invoke(gpu, "setResolution", w, h) |
| | | component.invoke(gpu, "setBackground", 0xd4d4d4) |
| | | component.invoke(gpu, "setForeground", 0x2D2D2D) |
| | | component.invoke(gpu, "fill", 1, 1, w, h, " ") |
| | | component.invoke(gpu, "set", centrize(#title, w), h/2, title) |
| | | component.invoke(gpu, "setForeground", 0xC3C3C3) |
| | | component.invoke(gpu, "set", w/2-25,h/2+2,string.rep("─", 50)) |
| end | | end |
| | | |
| -- Report boot progress if possible. | | -- Report boot progress if possible. |
| local y = 1 | | local y = 1 |
| local uptime = computer.uptime | | |
| -- we actually want to ref the original pullSignal here because /lib/event intercepts it later | | |
| -- because of that, we must re-pushSignal when we use this, else things break badly | | |
| local pull = computer.pullSignal | | |
| local last_sleep = uptime() | | |
| local function status(msg) | | local function status(msg) |
| if gpu then | | if gpu and screen then |
| gpu.set(1, y, msg) | | component.invoke(gpu, "setForeground", 0x878787) |
| if y == h then | | if y < 20 then |
| gpu.copy(1, 2, w, h - 1, 0, -1) | | loa = string.rep("─", y*2.5) |
| gpu.fill(1, h, w, 1, " ") | | else |
| else | | loa = string.rep("─", 50) |
| y = y + 1 | | end |
| end | | component.invoke(gpu, "set", w/2-25,h/2+2,loa) |
| end | | component.invoke(gpu, "fill",1,h,w,h," ") |
| -- boot can be slow in some environments, protect from timeouts | | component.invoke(gpu, "set",1,h,"Status: "..msg) |
| if uptime() - last_sleep > 1 then | | y = y + 1 |
| local signal = table.pack(pull(0)) | | |
| -- there might not be any signal | | |
| if signal.n > 0 then | | |
| -- push the signal back in queue for the system to use it | | |
| computer.pushSignal(table.unpack(signal, 1, signal.n)) | | |
| end | | |
| last_sleep = uptime() | | |
| end | | end |
| end | | end |
| | | |
| status("Booting " .. _OSVERSION .. "...") | | status("Booting " .. _OSVERSION .. "...") |
| | | |
| -- Custom low-level dofile implementation reading from our ROM. | | local loadfile = function(file) |
| | | status("> " .. file) |
| | | return raw_loadfile(file) |
| | | end |
| | | |
| local function dofile(file) | | local function dofile(file) |
| status("> " .. file) | | local program, reason = loadfile(file) |
| local program, reason = raw_loadfile(file) | | |
| if program then | | if program then |
| local result = table.pack(pcall(program)) | | local result = table.pack(pcall(program)) |
| if result[1] then | | if result[1] then |
| return table.unpack(result, 2, result.n) | | return table.unpack(result, 2, result.n) |
| else | | else |
| error(result[2]) | | error(result[2]) |
| end | | end |
| else | | else |
| error(reason) | | error(reason) |
| end | | end |
| end | | end |
| | | |
| status("Initializing package management...") | | status("Initializing package management...") |
| | | |
| -- Load file system related libraries we need to load other stuff moree | | -- Load file system related libraries we need to load other stuff moree |
| -- comfortably. This is basically wrapper stuff for the file streams | | -- comfortably. This is basically wrapper stuff for the file streams |
| -- provided by the filesystem components. | | -- provided by the filesystem components. |
| local package = dofile("/lib/package.lua") | | local package = dofile("/lib/package.lua") |
| | | |
| do | | do |
| -- Unclutter global namespace now that we have the package module and a filesystem | | -- Unclutter global namespace now that we have the package module and a filesystem |
| _G.component = nil | | _G.component = nil |
| _G.computer = nil | | _G.computer = nil |
| _G.process = nil | | _G.process = nil |
| _G.unicode = nil | | _G.unicode = nil |
| -- Inject the package modules into the global namespace, as in Lua. | | -- Inject the package modules into the global namespace, as in Lua. |
| _G.package = package | | _G.package = package |
| | | |
| -- Initialize the package module with some of our own APIs. | | -- Initialize the package module with some of our own APIs. |
| package.loaded.component = component | | package.loaded.component = component |
| package.loaded.computer = computer | | package.loaded.computer = computer |
| package.loaded.unicode = unicode | | package.loaded.unicode = unicode |
| package.loaded.buffer = dofile("/lib/buffer.lua") | | package.loaded.buffer = dofile("/lib/buffer.lua") |
| package.loaded.filesystem = dofile("/lib/filesystem.lua") | | package.loaded.filesystem = dofile("/lib/filesystem.lua") |
| | | |
| -- Inject the io modules | | -- Inject the io modules |
| _G.io = dofile("/lib/io.lua") | | _G.io = loadfile("/lib/io.lua") |
| | | |
| | | package.delayed["text"] = true |
| | | package.delayed["sh"] = true |
| | | package.delayed["transforms"] = true |
| | | package.delayed["term"] = true |
| end | | end |
| | | |
| status("Initializing file system...") | | status("Initializing file system...") |
| | | |
| -- Mount the ROM and temporary file systems to allow working on the file | | -- Mount the ROM and temporary file systems to allow working on the file |
| -- system module from this point on. | | -- system module from this point on. |
| require("filesystem").mount(computer.getBootAddress(), "/") | | require("filesystem").mount(computer.getBootAddress(), "/") |
| | | package.preload={} |
| | | |
| status("Running boot scripts...") | | status("Running boot scripts...") |
| | | |
| -- Run library startup scripts. These mostly initialize event handlers. | | -- Run library startup scripts. These mostly initialize event handlers. |
| local function rom_invoke(method, ...) | | local function rom_invoke(method, ...) |
| return component.invoke(computer.getBootAddress(), method, ...) | | return component.invoke(computer.getBootAddress(), method, ...) |
| end | | end |
| | | |
| local scripts = {} | | local scripts = {} |
| for _, file in ipairs(rom_invoke("list", "boot")) do | | for _, file in ipairs(rom_invoke("list", "boot")) do |
| local path = "boot/" .. file | | local path = "boot/" .. file |
| if not rom_invoke("isDirectory", path) then | | if not rom_invoke("isDirectory", path) then |
| table.insert(scripts, path) | | table.insert(scripts, path) |
| end | | end |
| end | | end |
| table.sort(scripts) | | table.sort(scripts) |
| for i = 1, #scripts do | | for i = 1, #scripts do |
| dofile(scripts[i]) | | dofile(scripts[i]) |
| end | | end |
| | | |
| status("Initializing components...") | | status("Initializing components...") |
| | | |
| for c, t in component.list() do | | for c, t in component.list() do |
| computer.pushSignal("component_added", c, t) | | computer.pushSignal("component_added", c, t) |
| end | | end |
| | | |
| status("Initializing system...") | | status("Initializing system...") |
| | | |
| computer.pushSignal("init") -- so libs know components are initialized. | | computer.pushSignal("init") -- so libs know components are initialized. |
| require("event").pull(1, "init") -- Allow init processing. | | require("event").pull(1, "init") -- Allow init processing. |
| _G.runlevel = 1 | | _G.runlevel = 1 |