MineOS/Applications/MultiScreen/MultiScreen.lua

314 lines
12 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require("advancedLua")
local ecs = require("ECSAPI")
local components = require("component")
local serialization = require("serialization")
local fs = require("filesystem")
local event = require("event")
local unicode = require("unicode")
local bit32 = require("bit32")
local color = require("color")
local gpu = components.gpu
--------------------------------------------------------------------------------------------------------------------------------------------
local mainScreenAddress = gpu.getScreen()
local pathToConfigFile = "/MultiScreen.cfg"
local colors = {
background = 0x262626,
foreground = 0xDDDDDD,
currentScreen = ecs.colors.green,
screen = 0xDDDDDD,
}
local baseResolution = {
width = 146,
height = 54,
}
local monitors = {}
--------------------------------------------------------------------------------------------------------------------------------------------
local currentBackground, currentForeground, currentAddress = 0x000000, 0xffffff, ""
local function multiScreenSet(x, y, background, foreground, text)
local xMonitor = math.ceil(x / monitors.screenResolutionByWidth)
local yMonitor = math.ceil(y / monitors.screenResolutionByHeight)
if monitors[xMonitor] and monitors[xMonitor][yMonitor] then
if currentAddress ~= monitors[xMonitor][yMonitor].address then
gpu.bind(monitors[xMonitor][yMonitor].address, false)
gpu.setBackground(background)
gpu.setForeground(foreground)
currentBackground, currentForeground = background, foreground
currentAddress = monitors[xMonitor][yMonitor].address
end
if currentBackground ~= background then
gpu.setBackground(background)
currentBackground = background
end
if currentForeground ~= foreground then
gpu.setForeground(foreground)
currentForeground = foreground
end
gpu.set(x - (xMonitor - 1) * monitors.screenResolutionByWidth, y - (yMonitor - 1) * monitors.screenResolutionByHeight, text)
end
end
local function multiScreenClear(color)
for address in components.list("screen") do
if address ~= mainScreenAddress then
gpu.bind(address, false)
gpu.setResolution(baseResolution.width, baseResolution.height)
gpu.setDepth(8)
gpu.setBackground(0x0)
gpu.setForeground(0xffffff)
gpu.fill(1, 1, baseResolution.width, baseResolution.height, " ")
end
end
gpu.bind(mainScreenAddress, false)
end
--------------------------------------------------------------------------------------------------------------------------------------------
local function getAllConnectedScreens()
local massiv = {}
for address in pairs(components.list("screen")) do
table.insert(massiv, address)
end
return massiv
end
local function configurator()
fs.makeDirectory(fs.path(pathToConfigFile))
local data = ecs.universalWindow("auto", "auto", 40, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x880000, "Здорово, ебана!"}, {"EmptyLine"}, {"WrappedText", 0x262626, "Добро пожаловать в программу конфигурации мультимонитора. Вам необходимо указать количество мониторов по ширине и высоте, которые вы желаете объединить, а также выбрать желаемый масштаб."}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, "Ширина"}, {"Input", 0x262626, 0x880000, "Высота"}, {"Slider", 0x262626, 0x880000, 1, 100, 100, "Масштаб: ", "%"}, {"EmptyLine"}, {"Button", {ecs.colors.orange, 0xffffff, "Подтвердить"}, {0x777777, 0xffffff, "Отмена"}})
local width, height, scale = tonumber(data[1]), tonumber(data[2]), tonumber(data[3]) / 100
if data[4] == "Отмена" then
ecs.prepareToExit()
print("Калибровка отменена!")
os.exit()
end
baseResolution.width, baseResolution.height = math.floor(baseResolution.width * scale), math.floor(baseResolution.height * scale)
-- ecs.error(baseResolution.width .. "x" ..baseResolution.height .. " ccale = " ..scale)
local countOfConnectedScreens = #getAllConnectedScreens()
while ((countOfConnectedScreens - 1) < width * height) do
data = ecs.universalWindow("auto", "auto", 44, 0xeeeeee, true, {"EmptyLine"}, {"WrappedText", 0x262626, "Теперь вам необходимо подключить внешние мониторы. Вы указали, что собираетесь сделать мультимонитор из " .. width*height .. " мониторов, но на данный момент вы подключили " .. countOfConnectedScreens - 1 .. " мониторов. Так что подключайте все так, как указали, и жмите \"Далее\"."}, {"EmptyLine"}, {"Button", {ecs.colors.orange, 0xffffff, "Далее"}, {0x777777, 0xffffff, "Отмена"}})
if data[1] == "Отмена" then
ecs.prepareToExit()
print("Калибровка отменена!")
os.exit()
end
countOfConnectedScreens = #getAllConnectedScreens()
end
----
local w, h = 8, 3
local xC, yC = 1, 1
local xSize, ySize = gpu.getResolution()
local function drawMonitors()
ecs.clearScreen(colors.background)
local x, y = 3, 2
local xPos, yPos = x, y
for j = 1, height do
for i = 1, width do
if j == yC and i == xC then
ecs.square(xPos, yPos, w, h, colors.currentScreen)
else
ecs.square(xPos, yPos, w, h, colors.screen)
end
xPos = xPos + w + 2
end
yPos = yPos + h + 1
xPos = x
end
gpu.setBackground(colors.background)
gpu.setForeground(colors.foreground)
ecs.centerText("x", ySize - 5, "Начинаем процесс калибровки. Коснитесь монитора, подсвеченного зеленым цветом.")
ecs.centerText("x", ySize - 4, "Не нарушайте порядок прокосновений!")
end
ecs.prepareToExit()
print("Идет подготовка мониторов...")
multiScreenClear(0x0)
monitors = {}
local monitorCount = width * height
local counter = 1
while counter <= monitorCount do
drawMonitors()
local e = {event.pull("touch")}
if e[2] ~= mainScreenAddress then
local exists = false
for x = 1, #monitors do
for y = 1, #monitors[x] do
if monitors[x][y].address == e[2] then
ecs.error("Ты уже кликал на этот монитор. Совсем уебок штоле?")
exists = true
end
end
end
if not exists then
gpu.bind(e[2], false)
gpu.setResolution(baseResolution.width, baseResolution.height)
gpu.setDepth(8)
local color = color.HSBToInteger(counter / monitorCount * 360, 1, 1)
gpu.setBackground(color)
gpu.setForeground(0xffffff - color)
gpu.fill(1, 1, baseResolution.width, baseResolution.height, " ")
ecs.centerText("xy", 0, "Монитор " .. xC .. "x" .. yC .. " откалиброван!")
gpu.bind(mainScreenAddress, false)
monitors[xC] = monitors[xC] or {}
monitors[xC][yC] = {address = e[2]}
xC = xC + 1
if xC > width and yC < height then
xC, yC = 1, yC + 1
end
end
else
ecs.error("Ну что ты за мудак криворукий! Сказано же, каких мониторов касаться. Не трогай этот монитор.")
end
counter = counter + 1
end
monitors.countOfScreensByWidth = width
monitors.countOfScreensByHeight = height
monitors.screenResolutionByWidth = baseResolution.width
monitors.screenResolutionByHeight = baseResolution.height
monitors.totalResolutionByWidth = baseResolution.width * width
monitors.totalResolutionByHeight = baseResolution.height * height
ecs.prepareToExit()
ecs.universalWindow("auto", "auto", 40, 0xeeeeee, true, {"EmptyLine"}, {"CenterText", 0x262626, "Калибровка успешно завершена!"}, {"EmptyLine"}, {"Button", {ecs.colors.orange, 0xffffff, "Отлично"}})
ecs.prepareToExit()
end
local function saveConfig()
local file = io.open(pathToConfigFile, "w")
file:write(serialization.serialize(monitors))
file:close()
end
local function loadConfig()
if fs.exists(pathToConfigFile) then
local file = io.open(pathToConfigFile, "r")
monitors = serialization.unserialize(file:read("*a"))
file:close()
print(" ")
print("Файл конфигурации мультимонитора загружен")
print(" ")
print("Количество экранов: " .. monitors.countOfScreensByWidth .. "x" .. monitors.countOfScreensByHeight .. " шт")
print("Разрешение каждого экрана: " .. monitors.screenResolutionByWidth .. "x" .. monitors.screenResolutionByHeight .. " px")
print("Суммарное разрешение кластера: " .. monitors.totalResolutionByWidth .. "x" .. monitors.totalResolutionByHeight .. " px")
-- print("Суммарное разрешение кластера через шрифт Брайля: ".. monitors.totalResolutionByWidth * 2 .. "x" .. monitors.totalResolutionByHeight * 4 .. " px")
print(" ")
else
configurator()
saveConfig()
loadConfig()
end
end
--------------------------------------------------------------------------------------------------------------------------------------------
--Прочитать n байтов из файла, возвращает прочитанные байты как число, если не удалось прочитать, то возвращает 0
local function readNumber(file, count)
return bit32.byteArrayToNumber({string.byte(file:read(count), 1, count)})
end
local function drawBigImageFromOCIFRawFile(x, y, path)
local file = io.open(path, "rb")
print("Открываем файл " .. path)
local signature = file:read(4)
print("Читаем сигнатуру файла: " .. signature)
local encodingMethod = string.byte(file:read(1))
print("Читаем метод кодирования: " .. tostring(encodingMethod))
if encodingMethod ~= 5 then
print("Неподдерживаемый метод кодирования. Откройте конвертер, измените формат на OCIF5 (Multiscreen) и повторите попытку")
file:close()
end
local width = readNumber(file, 2)
local height = readNumber(file, 2)
print("Ширина пикчи: " .. tostring(width))
print("Высота пикчи: " .. tostring(height))
print("Начинаю отросовку пикчи...")
for j = 1, height do
for i = 1, width do
local background = color.to24Bit(string.byte(file:read(1)))
local foreground = color.to24Bit(string.byte(file:read(1)))
file:read(1)
local symbol = fs.readUnicodeChar(file)
multiScreenSet(x + i - 1, y + j - 1, background, foreground, symbol)
end
end
file:close()
gpu.bind(mainScreenAddress, false)
print("Отрисовка пикчи завершена")
end
--------------------------------------------------------------------------------------------------------------------------------------------
local args = {...}
if args[1] == "draw" and args[2] then
loadConfig()
print("Идет очистка мониторов...")
multiScreenClear(0x000000)
if fs.exists(args[2]) then
drawBigImageFromOCIFRawFile(1, 1, args[2])
else
print("Файл " .. tostring(args[2]) .. " не найден. Используйте абсолютный путь к файлу, добавив / в начало")
end
elseif args[1] == "calibrate" then
fs.remove(pathToConfigFile)
loadConfig()
elseif args[1] == "clear" then
loadConfig()
multiScreenClear(tonumber(args[2] or 0x000000))
else
loadConfig()
print("Использование программы:")
print(" MultiScreen calibrate - перекалибровать мониторы")
print(" MultiScreen draw <путь к изображению> - отобразить изображение из файла на мониторах")
print(" MultiScreen clear <цвет> - очистить мониторы с указанным цветом (черным по умолчанию)")
end
--------------------------------------------------------------------------------------------------------------------------------------------
return multiScreen