Advertisement
DOGGYWOOF

GUI bootloader

Apr 7th, 2024
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.73 KB | None | 0 0
  1. local function main()
  2. local component_invoke = component.invoke
  3. local function boot_invoke(address, method, ...)
  4. local result = table.pack(pcall(component_invoke, address, method, ...))
  5. if not result[1] then
  6. return nil, result[2]
  7. else
  8. return table.unpack(result, 2, result.n)
  9. end
  10. end
  11.  
  12. local eeprom = component.list("eeprom")()
  13. computer.getBootAddress = function()
  14. return boot_invoke(eeprom, "getData")
  15. end
  16. computer.setBootAddress = function(address)
  17. return boot_invoke(eeprom, "setData", address)
  18. end
  19.  
  20. do
  21. local screen = component.list("screen")()
  22. local gpu = component.list("gpu")()
  23. if gpu and screen then
  24. boot_invoke(gpu, "bind", screen)
  25. end
  26. end
  27.  
  28. local function tryLoadFrom(address)
  29. local handle, reason = boot_invoke(address, "open", "/init.lua")
  30. if not handle then
  31. return nil, reason
  32. end
  33. local buffer = ""
  34. repeat
  35. local data, reason = boot_invoke(address, "read", handle, math.maxinteger or math.huge)
  36. if not data and reason then
  37. return nil, reason
  38. end
  39. buffer = buffer .. (data or "")
  40. until not data
  41. boot_invoke(address, "close", handle)
  42. return load(buffer, "=init")
  43. end
  44.  
  45. -- Get a list of bootable drives and their names
  46. local osList = {}
  47. for address in component.list("filesystem") do
  48. local label = boot_invoke(address, "getLabel") or "Unnamed Drive"
  49. table.insert(osList, {address = address, label = label})
  50. end
  51.  
  52. -- Function to display boot menu with a larger grey box around it, centered on the screen
  53. local function displayBootMenu(selectedIndex)
  54. local gpu = component.list("gpu")()
  55. local w, h = boot_invoke(gpu, "getResolution")
  56. local boxWidth = 60
  57. local boxHeight = #osList + 4
  58. local boxX = math.floor((w - boxWidth) / 2)
  59. local boxY = math.floor((h - boxHeight) / 2)
  60.  
  61. -- Draw grey box
  62. boot_invoke(gpu, "setBackground", 0x888888)
  63. boot_invoke(gpu, "fill", boxX, boxY, boxWidth, boxHeight, " ")
  64.  
  65. -- Draw boot menu options
  66. boot_invoke(gpu, "setForeground", 0xFFFFFF)
  67. boot_invoke(gpu, "setBackground", 0x888888) -- Set background color to grey for text
  68. boot_invoke(gpu, "set", boxX + 2, boxY + 1, "Select OS to boot:")
  69. for i, os in ipairs(osList) do
  70. local line = boxY + i + 2
  71. local textColor = i == selectedIndex and 0xFF0000 or 0xFFFFFF
  72. boot_invoke(gpu, "setForeground", textColor)
  73. boot_invoke(gpu, "set", boxX + 2, line, os.label .. " (" .. os.address .. ")")
  74. end
  75. computer.beep(1000, 0.10) -- Beep when boot menu appears
  76. end
  77.  
  78. -- Main boot menu logic
  79. local selectedIndex = math.ceil(#osList / 2) -- Select middle OS initially
  80. displayBootMenu(selectedIndex)
  81. while true do
  82. local event = {computer.pullSignal()}
  83. if event[1] == "key_down" then
  84. if event[4] == 200 and selectedIndex > 1 then -- Arrow up
  85. selectedIndex = selectedIndex - 1
  86. displayBootMenu(selectedIndex)
  87. elseif event[4] == 208 and selectedIndex < #osList then -- Arrow down
  88. selectedIndex = selectedIndex + 1
  89. displayBootMenu(selectedIndex)
  90. elseif event[4] == 28 then -- Enter key
  91. local selectedOS = osList[selectedIndex]
  92. local init, reason = tryLoadFrom(selectedOS.address)
  93. if init then
  94. computer.setBootAddress(selectedOS.address)
  95. computer.beep(1500, 0.10) -- Beep when booting into the operating system
  96. return init() -- Return the result of running loaded code
  97. else
  98. print("Failed to boot from " .. selectedOS.label .. ": " .. tostring(reason))
  99. end
  100. end
  101. end
  102. end
  103. end
  104.  
  105. main() -- Call the main function to execute the boot process
  106.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement