mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2026-01-10 05:02:40 +01:00
299 lines
8.1 KiB
Lua
299 lines
8.1 KiB
Lua
|
|
local stringsMain, stringsInit, stringsChangeLabel, stringKeyDown, stringsFilesystem, colorsTitle, colorsBackground, colorsText, colorsSelectionBackground, colorsSelectionText, componentProxy, componentList, pullSignal, uptime, tableInsert, mathMax, mathMin, mathHuge, mathFloor = "MineOS EFI", "/OS.lua", "Change label", "key_down", "filesystem", 0x2D2D2D, 0xE1E1E1, 0x878787, 0x878787, 0xE1E1E1, component.proxy, component.list, computer.pullSignal, computer.uptime, table.insert, math.max, math.min, math.huge, math.floor
|
|
|
|
local eeprom, gpu, internetAddress = componentProxy(componentList("eeprom")()), componentProxy(componentList("gpu")()), componentList("internet")()
|
|
|
|
local shutdown, gpuSet, gpuFill, eepromSetData, eepromGetData, screenWidth, screenHeight, curentBackground, currentForeground = computer.shutdown, gpu.set, gpu.fill, eeprom.setData, eeprom.getData, gpu.getResolution()
|
|
|
|
local resetColors, setBackground, setForeground, restrict =
|
|
function()
|
|
curentBackground, currentForeground = nil, nil
|
|
end,
|
|
function(color)
|
|
if color ~= curentBackground then
|
|
gpu.setBackground(color)
|
|
curentBackground = color
|
|
end
|
|
end,
|
|
function(color)
|
|
if color ~= currentForeground then
|
|
gpu.setForeground(color)
|
|
currentForeground = color
|
|
end
|
|
end,
|
|
function(text, limit, skip)
|
|
if #text < limit then
|
|
text = text .. string.rep(" ", limit - #text)
|
|
else
|
|
text = text:sub(1, limit)
|
|
end
|
|
|
|
return text .. (skip and "" or " ")
|
|
end
|
|
|
|
local rectangle, centrizedText, menuElement =
|
|
function(x, y, width, height, color)
|
|
setBackground(color)
|
|
gpuFill(x, y, width, height, " ")
|
|
end,
|
|
function(y, foreground, text)
|
|
local x = mathFloor(screenWidth / 2 - #text / 2)
|
|
setForeground(foreground)
|
|
gpuSet(x, y, text)
|
|
end,
|
|
function(text, callback, breakLoop)
|
|
return {
|
|
s = text,
|
|
c = callback,
|
|
b = breakLoop
|
|
}
|
|
end
|
|
|
|
local function title(y, titleText)
|
|
y = mathFloor(screenHeight / 2 - y / 2)
|
|
rectangle(1, 1, screenWidth, screenHeight, colorsBackground)
|
|
centrizedText(y, colorsTitle, titleText)
|
|
|
|
return y + 2
|
|
end
|
|
|
|
local function status(titleText, statusText, needWait)
|
|
local lines = {}
|
|
for line in statusText:gmatch("[^\r\n]+") do
|
|
lines[#lines + 1] = line:gsub("\t", " ")
|
|
end
|
|
|
|
local y = title(#lines, titleText)
|
|
|
|
for i = 1, #lines do
|
|
centrizedText(y, colorsText, lines[i])
|
|
y = y + 1
|
|
end
|
|
|
|
if needWait then
|
|
repeat
|
|
needWait = pullSignal()
|
|
until needWait == stringKeyDown or needWait == "touch"
|
|
end
|
|
end
|
|
|
|
local function executeString(...)
|
|
local result, reason = load(...)
|
|
if result then
|
|
result, reason = xpcall(result, debug.traceback)
|
|
if result then
|
|
return
|
|
end
|
|
end
|
|
|
|
resetColors()
|
|
status(stringsMain, reason, 1)
|
|
end
|
|
|
|
local loadInit, menuBack, menu, input =
|
|
function(proxy)
|
|
status(stringsMain, "Booting from " .. proxy.address)
|
|
|
|
local handle, data, chunk, success, reason = proxy.open(stringsInit, "rb"), "", ""
|
|
repeat
|
|
chunk = proxy.read(handle, mathHuge)
|
|
data = data .. (chunk or "")
|
|
until not chunk
|
|
|
|
proxy.close(handle)
|
|
|
|
executeString(data, "=" .. stringsInit)
|
|
end,
|
|
function()
|
|
return menuElement("Back", nil, 1)
|
|
end,
|
|
function(titleText, elements)
|
|
local spacing, selectedElement, maxLength = 2, 1, 0
|
|
for i = 1, #elements do
|
|
maxLength = math.max(maxLength, #elements[i].s)
|
|
end
|
|
|
|
while 1 do
|
|
local y, x, eventData = title(#elements + 2, titleText)
|
|
|
|
for i = 1, #elements do
|
|
x = mathFloor(screenWidth / 2 - #elements[i].s / 2)
|
|
|
|
if i == selectedElement then
|
|
rectangle(mathFloor(screenWidth / 2 - maxLength / 2) - 2, y, maxLength + 4, 1, colorsSelectionBackground)
|
|
setForeground(colorsSelectionText)
|
|
gpuSet(x, y, elements[i].s)
|
|
else
|
|
setBackground(colorsBackground)
|
|
setForeground(colorsText)
|
|
gpuSet(x, y, elements[i].s)
|
|
end
|
|
|
|
y = y + 1
|
|
end
|
|
|
|
eventData = {pullSignal()}
|
|
if eventData[1] == stringKeyDown then
|
|
if eventData[4] == 200 and selectedElement > 1 then
|
|
selectedElement = selectedElement - 1
|
|
elseif eventData[4] == 208 and selectedElement < #elements then
|
|
selectedElement = selectedElement + 1
|
|
elseif eventData[4] == 28 then
|
|
if elements[selectedElement].c then
|
|
elements[selectedElement].c()
|
|
end
|
|
|
|
if elements[selectedElement].b then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
function(y, prefix)
|
|
local text, state, eblo, eventData, char = "", true
|
|
while 1 do
|
|
eblo = prefix .. text
|
|
gpuFill(1, y, screenWidth, 1, " ")
|
|
setForeground(colorsText)
|
|
gpuSet(mathFloor(screenWidth / 2 - #eblo / 2), y, eblo .. (state and "█" or ""))
|
|
|
|
eventData = {pullSignal(0.5)}
|
|
if eventData[1] == stringKeyDown then
|
|
if eventData[4] == 28 then
|
|
return text
|
|
elseif eventData[4] == 14 then
|
|
text = text:sub(1, -2)
|
|
else
|
|
char = unicode.char(eventData[3])
|
|
if char:match("^[%w%d%p%s]+") then
|
|
text = text .. char
|
|
end
|
|
end
|
|
|
|
state = true
|
|
elseif eventData[1] == "clipboard" then
|
|
text = text .. eventData[3]
|
|
elseif not eventData[1] then
|
|
state = not state
|
|
end
|
|
end
|
|
end
|
|
|
|
gpu.bind(componentList("screen")(), true)
|
|
status(stringsMain, "Hold Alt to show boot options menu")
|
|
|
|
local deadline, eventData = uptime() + 1
|
|
while uptime() < deadline do
|
|
eventData = {pullSignal(deadline - uptime())}
|
|
if eventData[1] == stringKeyDown and eventData[4] == 56 then
|
|
local utilities = {
|
|
menuElement("Disk management", function()
|
|
local filesystems, bootAddress = {menuBack()}, eepromGetData()
|
|
|
|
for address in componentList(stringsFilesystem) do
|
|
local proxy = componentProxy(address)
|
|
local label, isReadOnly = proxy.getLabel() or "Unnamed", proxy.isReadOnly()
|
|
|
|
tableInsert(filesystems, 1,
|
|
menuElement(
|
|
(address == bootAddress and "> " or " ") ..
|
|
restrict(label, 10) ..
|
|
restrict(proxy.spaceTotal() > 1048576 and "HDD" or proxy.spaceTotal() > 65536 and "FDD" or "SYS", 3) ..
|
|
restrict(isReadOnly and "R" or "R/W", 3) ..
|
|
address:sub(1, 8) .. " " ..
|
|
restrict(string.format("%.2f", proxy.spaceUsed() / proxy.spaceTotal() * 100) .. "%", 6, 1),
|
|
|
|
function()
|
|
local filesystemOptions = {menuBack()}
|
|
|
|
if not isReadOnly then
|
|
tableInsert(filesystemOptions, 1, menuElement(stringsChangeLabel, function()
|
|
proxy.setLabel(input(title(2, stringsChangeLabel), "Enter new name: "))
|
|
end, 1))
|
|
|
|
tableInsert(filesystemOptions, 2, menuElement("Format", function()
|
|
status(stringsMain, "Formatting filesystem " .. address)
|
|
for _, file in ipairs(proxy.list("/")) do
|
|
proxy.remove(file)
|
|
end
|
|
status(stringsMain, "Formatting finished", 1)
|
|
end, 1))
|
|
end
|
|
|
|
tableInsert(filesystemOptions, 1, menuElement("Set as startup", function()
|
|
eepromSetData(address)
|
|
end, 1))
|
|
|
|
menu(label .. " (" .. address .. ")", filesystemOptions)
|
|
end
|
|
, 1)
|
|
)
|
|
end
|
|
|
|
menu("Select filesystem", filesystems)
|
|
end),
|
|
|
|
menuElement("Shutdown", function()
|
|
shutdown()
|
|
end),
|
|
|
|
menuBack()
|
|
}
|
|
|
|
if internetAddress then
|
|
tableInsert(utilities, 2, menuElement("Internet recovery", function()
|
|
local handle, data, result, reason = componentProxy(internetAddress).request("https://raw.githubusercontent.com/IgorTimofeev/MineOSStandalone/master/Installer/Main.lua"), ""
|
|
|
|
if handle then
|
|
status(stringsMain, "Downloading recovery script")
|
|
|
|
while 1 do
|
|
result, reason = handle.read(mathHuge)
|
|
|
|
if result then
|
|
data = data .. result
|
|
else
|
|
handle:close()
|
|
|
|
if reason then
|
|
status(stringsMain, reason, 1)
|
|
else
|
|
executeString(data, "=string")
|
|
end
|
|
|
|
break
|
|
end
|
|
end
|
|
else
|
|
status(stringsMain, "invalid URL-address", 1)
|
|
end
|
|
end))
|
|
end
|
|
|
|
menu(stringsMain, utilities)
|
|
end
|
|
end
|
|
|
|
local proxy = componentProxy(eepromGetData())
|
|
if proxy and proxy.exists(stringsInit) then
|
|
loadInit(proxy)
|
|
else
|
|
for address in componentList(stringsFilesystem) do
|
|
proxy = componentProxy(address)
|
|
if proxy.exists(stringsInit) then
|
|
eepromSetData(address)
|
|
loadInit(proxy)
|
|
break
|
|
else
|
|
proxy = nil
|
|
end
|
|
end
|
|
|
|
if not proxy then
|
|
status(stringsMain, "No bootable mediums found", 1)
|
|
end
|
|
end
|
|
|
|
shutdown()
|