diff --git a/Applications/3DPrint/Icon.pic b/Applications/3DPrint/Icon.pic index 22799bf3..a95c7813 100644 Binary files a/Applications/3DPrint/Icon.pic and b/Applications/3DPrint/Icon.pic differ diff --git a/Applications/3DTest/Icon.pic b/Applications/3DTest/Icon.pic index f50a0059..358e8b8d 100644 Binary files a/Applications/3DTest/Icon.pic and b/Applications/3DTest/Icon.pic differ diff --git a/Applications/AppMarket/AppMarket.lua b/Applications/AppMarket/AppMarket.lua index d43e85de..cf035d36 100755 --- a/Applications/AppMarket/AppMarket.lua +++ b/Applications/AppMarket/AppMarket.lua @@ -299,9 +299,9 @@ end local function updateImageWindow() clearMainZone() - local x, y = math.floor(sizes.x + sizes.width / 2 - updateImage.width / 2), math.floor(obj.main.y + obj.main.height / 2 - updateImage.height / 2 - 2) + local x, y = math.floor(sizes.x + sizes.width / 2 - updateImage[1] / 2), math.floor(obj.main.y + obj.main.height / 2 - updateImage[2] / 2 - 2) buffer.image(x, y, updateImage) - return y + updateImage.height + return y + updateImage[2] end local function updateImageWindowWithText(text) diff --git a/Applications/AppMarket/Icon.pic b/Applications/AppMarket/Icon.pic index 4573a17d..1e0deecf 100644 Binary files a/Applications/AppMarket/Icon.pic and b/Applications/AppMarket/Icon.pic differ diff --git a/Applications/Battleship/Icon.pic b/Applications/Battleship/Icon.pic index 0ab32b2d..c7304d27 100644 Binary files a/Applications/Battleship/Icon.pic and b/Applications/Battleship/Icon.pic differ diff --git a/Applications/BufferDemo/Icon.pic b/Applications/BufferDemo/Icon.pic index 07ea8497..aa3c658a 100644 Binary files a/Applications/BufferDemo/Icon.pic and b/Applications/BufferDemo/Icon.pic differ diff --git a/Applications/BufferDemo/Wallpaper.pic b/Applications/BufferDemo/Wallpaper.pic index 8ee5a9e3..75a0427e 100644 Binary files a/Applications/BufferDemo/Wallpaper.pic and b/Applications/BufferDemo/Wallpaper.pic differ diff --git a/Applications/Calendar/Icon.pic b/Applications/Calendar/Icon.pic index 3dda989b..cf2b3f92 100644 Binary files a/Applications/Calendar/Icon.pic and b/Applications/Calendar/Icon.pic differ diff --git a/Applications/Camera/Icon.pic b/Applications/Camera/Icon.pic index 1b681dc4..09876074 100644 Binary files a/Applications/Camera/Icon.pic and b/Applications/Camera/Icon.pic differ diff --git a/Applications/Chat/Icon.pic b/Applications/Chat/Icon.pic index 3ddcac13..281a6308 100644 Binary files a/Applications/Chat/Icon.pic and b/Applications/Chat/Icon.pic differ diff --git a/Applications/Chat/MyAvatar.pic b/Applications/Chat/MyAvatar.pic index b2187072..4550254d 100644 Binary files a/Applications/Chat/MyAvatar.pic and b/Applications/Chat/MyAvatar.pic differ diff --git a/Applications/ChristmasTree/Icon.pic b/Applications/ChristmasTree/Icon.pic index 62f17419..ac91b177 100644 Binary files a/Applications/ChristmasTree/Icon.pic and b/Applications/ChristmasTree/Icon.pic differ diff --git a/Applications/CodeDoor/Icon.pic b/Applications/CodeDoor/Icon.pic index 9cb31339..e17de0ae 100644 Binary files a/Applications/CodeDoor/Icon.pic and b/Applications/CodeDoor/Icon.pic differ diff --git a/Applications/Control2/Icon.pic b/Applications/Control2/Icon.pic old mode 100755 new mode 100644 index f9ddfaf0..7072fb24 Binary files a/Applications/Control2/Icon.pic and b/Applications/Control2/Icon.pic differ diff --git a/Applications/Control2/LuaLogo.pic b/Applications/Control2/LuaLogo.pic old mode 100755 new mode 100644 index 1d4bc94e..99d38a57 Binary files a/Applications/Control2/LuaLogo.pic and b/Applications/Control2/LuaLogo.pic differ diff --git a/Applications/DanceFloor/Icon.pic b/Applications/DanceFloor/Icon.pic index 089d190c..01e581ff 100644 Binary files a/Applications/DanceFloor/Icon.pic and b/Applications/DanceFloor/Icon.pic differ diff --git a/Applications/FlappyBird/Flappy.pic b/Applications/FlappyBird/Flappy.pic index c705f6bf..b2af2738 100644 Binary files a/Applications/FlappyBird/Flappy.pic and b/Applications/FlappyBird/Flappy.pic differ diff --git a/Applications/FlappyBird/Icon.pic b/Applications/FlappyBird/Icon.pic index 21470640..3eb71bed 100644 Binary files a/Applications/FlappyBird/Icon.pic and b/Applications/FlappyBird/Icon.pic differ diff --git a/Applications/ForceAdmin/Icon.pic b/Applications/ForceAdmin/Icon.pic index 0a1efaad..4ff99176 100644 Binary files a/Applications/ForceAdmin/Icon.pic and b/Applications/ForceAdmin/Icon.pic differ diff --git a/Applications/FuckTheRain/Icon.pic b/Applications/FuckTheRain/Icon.pic index c2297554..d4453d92 100644 Binary files a/Applications/FuckTheRain/Icon.pic and b/Applications/FuckTheRain/Icon.pic differ diff --git a/Applications/GeoScan2/Earth.pic b/Applications/GeoScan2/Earth.pic index 495b01b5..6d024358 100644 Binary files a/Applications/GeoScan2/Earth.pic and b/Applications/GeoScan2/Earth.pic differ diff --git a/Applications/GeoScan2/GeoScan2.lua b/Applications/GeoScan2/GeoScan2.lua index aba54f18..bd72d698 100644 --- a/Applications/GeoScan2/GeoScan2.lua +++ b/Applications/GeoScan2/GeoScan2.lua @@ -115,7 +115,7 @@ local buttonWidth = panelWidth - 4 window:addPanel(panelX, 1, panelWidth, buffer.screen.height, 0x444444) window.planetImage = window:addImage(buttonX, objectY, earthImage) -objectY = objectY + window.planetImage.image.height + 1 +objectY = objectY + window.planetImage.image[2] + 1 window:addLabel(buttonX, objectY, buttonWidth, 1, 0xFFFFFF, "GeoScan v2.0"):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) objectY = objectY + 2 diff --git a/Applications/GeoScan2/Icon.pic b/Applications/GeoScan2/Icon.pic index a99036a8..30130057 100644 Binary files a/Applications/GeoScan2/Icon.pic and b/Applications/GeoScan2/Icon.pic differ diff --git a/Applications/Graph/Icon.pic b/Applications/Graph/Icon.pic index 9a02e45c..aa40e770 100644 Binary files a/Applications/Graph/Icon.pic and b/Applications/Graph/Icon.pic differ diff --git a/Applications/GuessWord/Icon.pic b/Applications/GuessWord/Icon.pic index 63f7b86d..b59268a0 100644 Binary files a/Applications/GuessWord/Icon.pic and b/Applications/GuessWord/Icon.pic differ diff --git a/Applications/HEX/Icon.pic b/Applications/HEX/Icon.pic index 365307f8..a504ec1e 100644 Binary files a/Applications/HEX/Icon.pic and b/Applications/HEX/Icon.pic differ diff --git a/Applications/HoloClock/Icon.pic b/Applications/HoloClock/Icon.pic old mode 100755 new mode 100644 index 3d1903e1..427da9b1 Binary files a/Applications/HoloClock/Icon.pic and b/Applications/HoloClock/Icon.pic differ diff --git a/Applications/HoloEdit/Icon.pic b/Applications/HoloEdit/Icon.pic index cdfeef8e..1e74fc67 100644 Binary files a/Applications/HoloEdit/Icon.pic and b/Applications/HoloEdit/Icon.pic differ diff --git a/Applications/InfoPanel/Icon.pic b/Applications/InfoPanel/Icon.pic index 258d8684..8f074d12 100644 Binary files a/Applications/InfoPanel/Icon.pic and b/Applications/InfoPanel/Icon.pic differ diff --git a/Applications/Keyboard/Icon.pic b/Applications/Keyboard/Icon.pic index 15c1fff9..6ae147ec 100644 Binary files a/Applications/Keyboard/Icon.pic and b/Applications/Keyboard/Icon.pic differ diff --git a/Applications/MineCodeIDE/Icon.pic b/Applications/MineCodeIDE/Icon.pic old mode 100755 new mode 100644 index 350a3a54..f913804b Binary files a/Applications/MineCodeIDE/Icon.pic and b/Applications/MineCodeIDE/Icon.pic differ diff --git a/Applications/MineSweeper/Icon.pic b/Applications/MineSweeper/Icon.pic index 732c3185..d1f56db3 100644 Binary files a/Applications/MineSweeper/Icon.pic and b/Applications/MineSweeper/Icon.pic differ diff --git a/Applications/Palette/Icon.pic b/Applications/Palette/Icon.pic old mode 100755 new mode 100644 index 5c218fc4..bb47d9e3 Binary files a/Applications/Palette/Icon.pic and b/Applications/Palette/Icon.pic differ diff --git a/Applications/Photoshop/Icon.pic b/Applications/Photoshop/Icon.pic index bf3d6d7b..e7d2f0be 100644 Binary files a/Applications/Photoshop/Icon.pic and b/Applications/Photoshop/Icon.pic differ diff --git a/Applications/Photoshop/Localization/English.lang b/Applications/Photoshop/Localization/English.lang index e7edc1ca..c576084a 100755 --- a/Applications/Photoshop/Localization/English.lang +++ b/Applications/Photoshop/Localization/English.lang @@ -25,7 +25,7 @@ new = "New", open = "Open", - createFromString = "Create from OCIFString", + createFromString = "Create from StringImage", save = "Save", saveAs = "Save as", exit = "Exit", diff --git a/Applications/Photoshop/Localization/Russian.lang b/Applications/Photoshop/Localization/Russian.lang index 64937958..a811b943 100755 --- a/Applications/Photoshop/Localization/Russian.lang +++ b/Applications/Photoshop/Localization/Russian.lang @@ -25,7 +25,7 @@ new = "Новый", open = "Открыть", - createFromString = "Создать из OCIFString", + createFromString = "Создать из StringImage", save = "Сохранить", saveAs = "Сохранить как", exit = "Выход", diff --git a/Applications/Photoshop/Photoshop.lua b/Applications/Photoshop/Photoshop.lua index 62048dfc..dd4de4b6 100755 --- a/Applications/Photoshop/Photoshop.lua +++ b/Applications/Photoshop/Photoshop.lua @@ -1,20 +1,24 @@ ------------------------------------------------ Информешйн, епта -------------------------------------------------------------- -local photoshopVersion = "Photoshop v6.5" +local photoshopVersion = "Photoshop v6.6" local copyright = [[ - Photoshop v6.5 для OpenComputers + Photoshop v6.6 для OpenComputers Автор: ECS Контактый адрес: https://vk.com/id7799889 Соавтор: Pornogion Контактый адрес: https://vk.com/id88323331 + Что нового в версии 6.6: + - Программа адаптирована под работу с нумерически индексированным форматом изображения + - Добавлена поддержка кодирования формата OCIF6 + Что нового в версии 6.5: - Палитра заменена на более быструю и стильную, работающую на тройном буфере - - Добавлена возможность загрузки изображения из строки, созданной методом сохранения OCIFString + - Добавлена возможность загрузки изображения из строки, созданной методом сохранения StringImage Что нового в версии 6.4: - Добавлена возможность выбора цвета сетки прозрачности во вкладке "Вид" @@ -84,8 +88,8 @@ local args = {...} --Массив главного изображения local masterPixels = { - width = 0, - height = 0, + 0, + 0, } --Базовая цветовая схема программы @@ -123,8 +127,8 @@ sizes.sizeOfPixelData = 4 local function reCalculateImageSizes(x, y) sizes.xStartOfImage = x or 9 sizes.yStartOfImage = y or 6 - sizes.xEndOfImage = sizes.xStartOfImage + masterPixels.width - 1 - sizes.yEndOfImage = sizes.yStartOfImage + masterPixels.height - 1 + sizes.xEndOfImage = sizes.xStartOfImage + image.getWidth(masterPixels) - 1 + sizes.yEndOfImage = sizes.yStartOfImage + image.getHeight(masterPixels) - 1 end reCalculateImageSizes() @@ -182,25 +186,25 @@ local function drawTransparentZone(x, y) local stro4ka1 = "" local stro4ka2 = "" - if masterPixels.width % 2 == 0 then - stro4ka1 = string.rep("▒ ", math.floor(masterPixels.width / 2)) + if image.getWidth(masterPixels) % 2 == 0 then + stro4ka1 = string.rep("▒ ", math.floor(image.getWidth(masterPixels) / 2)) stro4ka2 = stro4ka1 else - stro4ka1 = string.rep("▒ ", math.floor(masterPixels.width / 2)) + stro4ka1 = string.rep("▒ ", math.floor(image.getWidth(masterPixels) / 2)) stro4ka2 = stro4ka1 .. "▒" end - for i = 1, masterPixels.height do + for i = 1, image.getHeight(masterPixels) do if i % 2 == 0 then - buffer.square(x, y + i, masterPixels.width, 1, colors.transparencyWhite, colors.transparencyGray, " ") + buffer.square(x, y + i, image.getWidth(masterPixels), 1, colors.transparencyWhite, colors.transparencyGray, " ") buffer.text(x + 1, y + i, colors.transparencyGray, stro4ka1) else - buffer.square(x, y + i, masterPixels.width, 1, colors.transparencyWhite, colors.transparencyGray) + buffer.square(x, y + i, image.getWidth(masterPixels), 1, colors.transparencyWhite, colors.transparencyGray) buffer.text(x, y + i, colors.transparencyGray, stro4ka2) end end else - buffer.square(x, y, masterPixels.width, masterPixels.height, colors.transparencyWhite, 0x000000, " ") + buffer.square(x, y, image.getWidth(masterPixels), image.getHeight(masterPixels), colors.transparencyWhite, 0x000000, " ") end end @@ -251,7 +255,6 @@ local function drawTopMenu() obj.menu:addItem("PS", ecs.colors.blue) obj.menu:addItem(localization.file) obj.menu:addItem(localization.image) - obj.menu:addItem(localization.edit) obj.menu:addItem(localization.view) obj.menu:addItem(localization.hotkeys) obj.menu:addItem(localization.about) @@ -261,7 +264,7 @@ end --Функция, создающая пустой массив изображения на основе указанных ранее длины и ширины local function createEmptyMasterPixels() --Создаем пустой мастерпиксельс - for j = 1, masterPixels.height * masterPixels.width do + for j = 1, image.getHeight(masterPixels) * image.getWidth(masterPixels) do table.insert(masterPixels, 0x010101) table.insert(masterPixels, 0x010101) table.insert(masterPixels, 0xFF) @@ -269,28 +272,6 @@ local function createEmptyMasterPixels() end end ---Формула конвертации итератора массива в абсолютные координаты пикселя изображения -local function convertIteratorToCoords(iterator) - --Приводим итератор к корректному виду (1 = 1, 5 = 2, 9 = 3, 13 = 4, 17 = 5, ...) - iterator = (iterator + sizes.sizeOfPixelData - 1) / sizes.sizeOfPixelData - --Получаем остаток от деления итератора на ширину изображения - local ostatok = iterator % masterPixels.width - --Если остаток равен 0, то х равен ширине изображения, а если нет, то х равен остатку - local x = (ostatok == 0) and masterPixels.width or ostatok - --А теперь как два пальца получаем координату по Y - local y = math.ceil(iterator / masterPixels.width) - --Очищаем остаток из оперативки - ostatok = nil - --Возвращаем координаты - return x, y -end - ---Формула конвертации абсолютных координат пикселя изображения в итератор для массива -local function convertCoordsToIterator(x, y) - --Конвертируем координаты в итератор - return (masterPixels.width * (y - 1) + x) * sizes.sizeOfPixelData - sizes.sizeOfPixelData + 1 -end - --Мини-консолька для отладки, сообщающая снизу, че происходит ваще local function console(text) buffer.square(sizes.xStartOfDrawingArea, buffer.screen.height, sizes.widthOfDrawingArea, 1, colors.console, colors.consoleText, " ") @@ -456,18 +437,18 @@ local function stroke(x, y, width, height, color, applyToMasterPixels) if applyToMasterPixels then local iterator for i = x, x + width - 1 do - iterator = convertCoordsToIterator(i, y) + iterator = image.getImageIndexByCoordinates(i, y, image.getWidth(masterPixels)) masterPixels[iterator] = color; masterPixels[iterator + 1] = 0x0; masterPixels[iterator + 2] = 0x0; masterPixels[iterator + 3] = " " - iterator = convertCoordsToIterator(i, y + height - 1) + iterator = image.getImageIndexByCoordinates(i, y + height - 1, image.getWidth(masterPixels)) masterPixels[iterator] = color; masterPixels[iterator + 1] = 0x0; masterPixels[iterator + 2] = 0x0; masterPixels[iterator + 3] = " " end for i = y, y + height - 1 do - iterator = convertCoordsToIterator(x, i) + iterator = image.getImageIndexByCoordinates(x, i, image.getWidth(masterPixels)) masterPixels[iterator] = color; masterPixels[iterator + 1] = 0x0; masterPixels[iterator + 2] = 0x0; masterPixels[iterator + 3] = " " - iterator = convertCoordsToIterator(x + width - 1, i) + iterator = image.getImageIndexByCoordinates(x + width - 1, i, image.getWidth(masterPixels)) masterPixels[iterator] = color; masterPixels[iterator + 1] = 0x0; masterPixels[iterator + 2] = 0x0; masterPixels[iterator + 3] = " " end else @@ -602,7 +583,7 @@ local function drawImage() drawTransparentZone(xPos, yPos) --Перебираем массив мастерпиксельса - for i = 1, #masterPixels, 4 do + for i = 3, #masterPixels, 4 do --Рисуем пиксель, если у него прозрачность не абсолютная, ЛИБО имеется какой-то символ --Т.е. даже если прозрачность и охуела, но символ есть, то рисуем его if masterPixels[i + 2] ~= 0xFF or masterPixels[i + 3] ~= " " then @@ -611,12 +592,12 @@ local function drawImage() --Всякие расчеты координат xPixel = xPixel + 1 xPos = xPos + 1 - if xPixel > masterPixels.width then xPixel = 1; xPos = sizes.xStartOfImage; yPixel = yPixel + 1; yPos = yPos + 1 end + if xPixel > image.getWidth(masterPixels) then xPixel = 1; xPos = sizes.xStartOfImage; yPixel = yPixel + 1; yPos = yPos + 1 end end - if masterPixels.width > 0 and masterPixels.height > 0 then - local text = localization.size .. ": " .. masterPixels.width .. "x" .. masterPixels.height .. " px" - xPos = math.floor(sizes.xStartOfImage + masterPixels.width / 2 - unicode.len(text) / 2) + if image.getWidth(masterPixels) > 0 and image.getHeight(masterPixels) > 0 then + local text = localization.size .. ": " .. image.getWidth(masterPixels) .. "x" .. image.getHeight(masterPixels) .. " px" + xPos = math.floor(sizes.xStartOfImage + image.getWidth(masterPixels) / 2 - unicode.len(text) / 2) buffer.text(xPos, sizes.yEndOfImage + 1, 0xFFFFFF, text) end @@ -659,13 +640,13 @@ local function move(direction) if selection.y < 1 then selection.y = 1 end elseif direction == "down" then selection.y = selection.y + 1 - if selection.y + selection.height - 1 > masterPixels.height then selection.y = selection.y - 1 end + if selection.y + selection.height - 1 > image.getHeight(masterPixels) then selection.y = selection.y - 1 end elseif direction == "left" then selection.x = selection.x - 1 if selection.x < 1 then selection.x = 1 end elseif direction == "right" then selection.x = selection.x + 1 - if selection.x + selection.width - 1 > masterPixels.width then selection.x = selection.x - 1 end + if selection.x + selection.width - 1 > image.getWidth(masterPixels) then selection.x = selection.x - 1 end end else local howMuchUpDown = 2 @@ -777,8 +758,8 @@ local function saveTextToPixels(x, y, text) local iterator x = x - 1 for i = 1, sText do - if x + i > masterPixels.width then break end - iterator = convertCoordsToIterator(x + i, y) + if x + i > image.getWidth(masterPixels) then break end + iterator = image.getImageIndexByCoordinates(x + i, y, image.getWidth(masterPixels)) setPixel(iterator, masterPixels[iterator], currentBackground, masterPixels[iterator + 2], unicode.sub(text, i, i)) end end @@ -788,12 +769,12 @@ local function tryToFitImageOnCenterOfScreen() reCalculateImageSizes() local x, y = sizes.xStartOfImage, sizes.yStartOfImage - if masterPixels.width < sizes.widthOfDrawingArea then - x = math.floor(sizes.xStartOfDrawingArea + sizes.widthOfDrawingArea / 2 - masterPixels.width / 2) - 1 + if image.getWidth(masterPixels) < sizes.widthOfDrawingArea then + x = math.floor(sizes.xStartOfDrawingArea + sizes.widthOfDrawingArea / 2 - image.getWidth(masterPixels) / 2) - 1 end - if masterPixels.height < sizes.heightOfDrawingArea then - y = math.floor(sizes.yStartOfDrawingArea + sizes.heightOfDrawingArea / 2 - masterPixels.height / 2) + if image.getHeight(masterPixels) < sizes.heightOfDrawingArea then + y = math.floor(sizes.yStartOfDrawingArea + sizes.heightOfDrawingArea / 2 - image.getHeight(masterPixels) / 2) end reCalculateImageSizes(x, y) @@ -808,7 +789,7 @@ local function new() data[2] = tonumber(data[2]) or 19 masterPixels = {} - masterPixels.width, masterPixels.height = data[1], data[2] + masterPixels[1], masterPixels[2] = data[1], data[2] createEmptyMasterPixels() tryToFitImageOnCenterOfScreen() drawAll() @@ -818,7 +799,7 @@ end --Есть инфа, что выжирает стек, но Луа, вроде, не особо ругается, так что заебок все local function fill(x, y, startColor, fillColor) local function doFill(xStart, yStart) - local iterator = convertCoordsToIterator(xStart, yStart) + local iterator = image.getImageIndexByCoordinates(xStart, yStart, image.getWidth(masterPixels)) --Завершаем функцию, если цвет в массиве не такой, какой мы заливаем if masterPixels[iterator] ~= startColor or masterPixels[iterator] == fillColor then return end @@ -850,10 +831,10 @@ local function brush(x, y, background, foreground, alpha, symbol) for cyka = 1, currentBrushSize do for pidor = 1, currentBrushSize do --Если этот кусочек входит в границы рисовабельной зоны, то - if x >= 1 and x <= masterPixels.width and y >= 1 and y <= masterPixels.height then + if x >= 1 and x <= image.getWidth(masterPixels) and y >= 1 and y <= image.getHeight(masterPixels) then --Считаем итератор для кусочка кисти - newIterator = convertCoordsToIterator(x, y) + newIterator = image.getImageIndexByCoordinates(x, y, image.getWidth(masterPixels)) --Если прозрачности кисти ВАЩЕ НЕТ, то просто рисуем как обычненько все if alpha == 0x00 then @@ -893,11 +874,21 @@ local function brush(x, y, background, foreground, alpha, symbol) end end ---Диалоговое окно обрезки и расширения картинки -local function cropOrExpand(text) +--Функция-обрезчик картинки +local function crop() + if selection then + masterPixels = image.crop(masterPixels, selection.x, selection.y, selection.width, selection.height) + selection = nil + tryToFitImageOnCenterOfScreen() + drawAll() + end +end + +--Функция-расширитель картинки +local function expand() local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, - {"CenterText", 0x262626, text}, + {"CenterText", 0x262626, localization.expand}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, localization.countOfPixels}, {"Selector", 0x262626, 0x880000, localization.fromBottom, localization.fromTop, localization.fromLeft, localization.fromRight}, @@ -908,41 +899,16 @@ local function cropOrExpand(text) if data[3] == "OK" then local countOfPixels = tonumber(data[1]) if countOfPixels then - local direction = "" - if data[2] == localization.fromBottom then - direction = "fromBottom" - elseif data[2] == localization.fromTop then - direction = "fromTop" - elseif data[2] == localization.fromLeft then - direction = "fromLeft" - else - direction = "fromRight" - end - - return direction, countOfPixels - else - ecs.error("Введено некорректное количество пикселей") - end - end -end - ---Функция-обрезчик картинки -local function crop() - local direction, countOfPixels = cropOrExpand(localization.crop) - if direction then - masterPixels = image.crop(masterPixels, direction, countOfPixels) - reCalculateImageSizes(sizes.xStartOfImage, sizes.yStartOfImage) - drawAll() - end -end - ---Функция-расширитель картинки -local function expand() - local direction, countOfPixels = cropOrExpand(localization.crop) - if direction then - masterPixels = image.expand(masterPixels, direction, countOfPixels, 0x010101, 0x010101, 0xFF, " ") - reCalculateImageSizes(sizes.xStartOfImage, sizes.yStartOfImage) - drawAll() + masterPixels = image.expand(masterPixels, + data[2] == localization.fromTop and countOfPixels or 0, + data[2] == localization.fromBottom and countOfPixels or 0, + data[2] == localization.fromLeft and countOfPixels or 0, + data[2] == localization.fromRight and countOfPixels or 0, + 0x010101, 0x010101, 0xFF, " " + ) + reCalculateImageSizes(sizes.xStartOfImage, sizes.yStartOfImage) + drawAll() + end end end @@ -962,7 +928,7 @@ end local function fillSelection(background, foreground, alpha, symbol) for j = selection.y, selection.y + selection.height - 1 do for i = selection.x, selection.x + selection.width - 1 do - local iterator = convertCoordsToIterator(i, j) + local iterator = image.getImageIndexByCoordinates(i, j, image.getWidth(masterPixels)) masterPixels[iterator] = background masterPixels[iterator + 1] = foreground masterPixels[iterator + 2] = alpha @@ -1015,7 +981,7 @@ while true do --Получаем координаты в изображении и итератор local x, y = e[3] - sizes.xStartOfImage + 1, e[4] - sizes.yStartOfImage + 1 - local iterator = convertCoordsToIterator(x, y) + local iterator = image.getImageIndexByCoordinates(x, y, image.getWidth(masterPixels)) --Все для инструментов мультиточечного рисования if instruments[currentInstrument] == "M" or instruments[currentInstrument] == "S" then @@ -1072,7 +1038,7 @@ while true do buffer.draw() --Текст elseif instruments[currentInstrument] == "T" then - local limit = masterPixels.width - x + 1 + local limit = image.getWidth(masterPixels) - x + 1 local text = inputText(e[3], e[4], limit) saveTextToPixels(x, y, text) drawImage() @@ -1146,9 +1112,16 @@ while true do if object.text == localization.file then action = GUI.contextMenu(object.x, object.y + 1, {localization.new, false, "^N"}, {localization.open, false, "^O"}, {localization.createFromString}, "-", {localization.save, (savePath == nil), "^S"}, {localization.saveAs}, "-", {localization.exit}):show() elseif object.text == localization.image then - action = GUI.contextMenu(object.x, object.y + 1, {localization.crop}, {localization.expand}, "-", {localization.rotateBy90}, {localization.rotateBy180}, "-", {localization.flipHorizontal}, {localization.flipVertical}):show() - elseif object.text == localization.edit then - action = GUI.contextMenu(object.x, object.y + 1, {localization.hueSaturation}, {localization.colorBalance}, {localization.photoFilter}, "-", {localization.invertColors}, {localization.blackWhite}, "-", {localization.gaussianBlur}):show() + action = GUI.contextMenu(object.x, object.y + 1, + -- {localization.crop}, + {localization.expand}, + -- "-", + -- {localization.rotateBy90}, + -- {localization.rotateBy180}, + "-", + {localization.flipHorizontal}, + {localization.flipVertical} + ):show() elseif object.text == localization.view then action = GUI.contextMenu(object.x, object.y + 1, {localization.transparencyPad}):show() elseif object.text == localization.about then @@ -1225,10 +1198,10 @@ while true do elseif action == localization.expand then expand() elseif action == localization.flipVertical then - masterPixels = image.flipVertical(masterPixels) + masterPixels = image.flipVertically(masterPixels) drawAll() elseif action == localization.flipHorizontal then - masterPixels = image.flipHorizontal(masterPixels) + masterPixels = image.flipHorizontally(masterPixels) drawAll() elseif action == localization.invertColors then masterPixels = image.invert(masterPixels) @@ -1246,28 +1219,28 @@ while true do new() drawAll() elseif action == localization.saveAs then - local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, {"EmptyLine"}, {"CenterText", 0x262626, localization.saveAs}, {"EmptyLine"}, {"Input", 0x262626, 0x880000, localization.path}, {"Selector", 0x262626, 0x880000, "OCIF4", "OCIF1", "OCIFString", "RAW"}, {"CenterText", 0x262626, "Рекомендуется использовать"}, {"CenterText", 0x262626, "метод кодирования OCIF4"}, {"EmptyLine"}, {"Button", {0xaaaaaa, 0xffffff, "OK"}, {0x888888, 0xffffff, localization.cancel}}) + local data = ecs.universalWindow("auto", "auto", 30, ecs.windowColors.background, true, + {"EmptyLine"}, + {"CenterText", 0x262626, localization.saveAs}, + {"EmptyLine"}, + {"Input", 0x262626, 0x880000, localization.path}, + {"Selector", 0x262626, 0x880000, "OCIF6", "OCIF1", "StringImage"}, + {"EmptyLine"}, + {"Button", {0xaaaaaa, 0xffffff, "OK"}, {0x888888, 0xffffff, localization.cancel}} + ) + if data[3] == "OK" then - data[1] = data[1] or "Untitled" - data[2] = data[2] or "OCIF4" + data[1] = data[1] or "Untitled.pic" - if data[2] == "RAW" then - data[2] = 0 - elseif data[2] == "OCIF1" then - data[2] = 1 - elseif data[2] == "OCIF4" then - data[2] = 4 - elseif data[2] == "OCIFString" then - data[2] = 6 + local path = string.gsub(data[1], "%.pic$", "") .. ".pic" + if data[2] == "StringImage" then + local file = io.open(path, "w") + file:write(image.toString(masterPixels)) + file:close() else - data[2] = 4 + savePath = path + image.save(path, masterPixels, data[2] == "OCIF6" and 6 or 1) end - - local filename = string.gsub(data[1], ".pic$", "") .. ".pic" - local encodingMethod = data[2] - - image.save(filename, masterPixels, encodingMethod) - savePath = filename end elseif action == localization.save then image.save(savePath, masterPixels) @@ -1304,7 +1277,7 @@ while true do tryToFitImageOnCenterOfScreen() drawAll() else - error("Невозможно создать изображение из этой строки!") + error("Failed to create image from string") end end elseif action == localization.transparencyPad then @@ -1334,10 +1307,21 @@ while true do if ecs.clickedAtArea(e[3], e[4], sizes.xStartOfImage, sizes.yStartOfImage, sizes.xEndOfImage, sizes.yEndOfImage) then if instruments[currentInstrument] == "M" and selection then - local action = GUI.contextMenu(e[3], e[4], {localization.deselect}, {localization.crop, true}, "-", {localization.fill}, {localization.border}, "-", {localization.clear}):show() + local action = GUI.contextMenu(e[3], e[4], + {localization.deselect}, + {localization.crop}, + "-", + {localization.fill}, + {localization.border}, + "-", + {localization.clear} + ):show() + if action == localization.deselect then selection = nil drawAll() + elseif action == localization.crop then + crop() elseif action == localization.clear then fillSelection(0x0, 0x0, 0xFF, " ") elseif action == localization.fill then diff --git a/Applications/PrintImage/Icon.pic b/Applications/PrintImage/Icon.pic index b321cd4f..f28c8154 100644 Binary files a/Applications/PrintImage/Icon.pic and b/Applications/PrintImage/Icon.pic differ diff --git a/Applications/PrintImage/PrintImage.lua b/Applications/PrintImage/PrintImage.lua index 3884fe4d..c2bde01b 100755 --- a/Applications/PrintImage/PrintImage.lua +++ b/Applications/PrintImage/PrintImage.lua @@ -65,9 +65,9 @@ local function addShapePixel(x, y, color, xPrinterPixel, yPrinterPixel) if config.frame.enabled then local xModifyer1, xModifyer2, yModifyer1, yModifyer2 = 0, 0, 0, 0 if xPrinterPixel == 1 then xModifyer1 = config.frame.width end - if xPrinterPixel == mainImage.width then xModifyer2 = -config.frame.width end + if xPrinterPixel == image.getWidth(mainImage) then xModifyer2 = -config.frame.width end if yPrinterPixel == 1 then yModifyer2 = -config.frame.width end - if yPrinterPixel == mainImage.height * 2 then yModifyer1 = config.frame.width end + if yPrinterPixel == image.getHeight(mainImage) * 2 then yModifyer1 = config.frame.width end printers[currentPrinter].addShape(xPrinter + xModifyer1, yPrinter + yModifyer1, 15, xPrinter + pixelSize + xModifyer2, yPrinter + pixelSize + yModifyer2, 16, config.mainMaterial, false, color) else printers[currentPrinter].addShape(xPrinter, 15, yPrinter, xPrinter + pixelSize, 16, yPrinter + pixelSize, config.mainMaterial, false, color) @@ -79,7 +79,7 @@ local function beginPrint() buffer.clear(0x0000000, 50) local xShape, yShape = 1, 1 - local xShapeCount, yShapeCount = math.ceil(mainImage.width / shapeResolutionLimit), math.ceil(mainImage.height * 2 / shapeResolutionLimit) + local xShapeCount, yShapeCount = math.ceil(image.getWidth(mainImage) / shapeResolutionLimit), math.ceil(image.getHeight(mainImage) * 2 / shapeResolutionLimit) local counter = 0 while true do if printers[currentPrinter].status() == "idle" then @@ -94,7 +94,7 @@ local function beginPrint() local xImage = xShape * shapeResolutionLimit - shapeResolutionLimit + i local yImage = yShape * (shapeResolutionLimit / 2) - (shapeResolutionLimit / 2) + j - if xImage <= mainImage.width and yImage <= mainImage.height then + if xImage <= image.getWidth(mainImage) and yImage <= image.getHeight(mainImage) then local background, foreground, alpha, symbol = image.get(mainImage, xImage, yImage) if alpha < 0xFF then if symbol == " " then foreground = background end @@ -113,7 +113,7 @@ local function beginPrint() end if config.frame.enabled and not config.floorMode then - local xFrame, yFrame = shapeResolutionLimit * (mainImage.width % shapeResolutionLimit), shapeResolutionLimit * ((mainImage.height * 2) % shapeResolutionLimit) + local xFrame, yFrame = shapeResolutionLimit * (image.getWidth(mainImage) % shapeResolutionLimit), shapeResolutionLimit * ((image.getHeight(mainImage) * 2) % shapeResolutionLimit) xFrame = xShape == xShapeCount and (xFrame == 0 and 16 or xFrame) or 16 yFrame = yShape == yShapeCount and (yFrame == 0 and 0 or yFrame) or 0 @@ -145,9 +145,9 @@ end ----------------------------------------- Window-zaluped parasha ----------------------------------------- local function getStatus() - local xBlocks, yBlocks = math.ceil(mainImage.width / shapeResolutionLimit), math.ceil(mainImage.height * 2 / shapeResolutionLimit) + local xBlocks, yBlocks = math.ceil(image.getWidth(mainImage) / shapeResolutionLimit), math.ceil(image.getHeight(mainImage) * 2 / shapeResolutionLimit) window.shadeContainer.statusTextBox.lines = { - "Image size: " .. mainImage.width .. "x" .. mainImage.height .. " px", + "Image size: " .. image.getWidth(mainImage) .. "x" .. image.getHeight(mainImage) .. " px", "Count of printers: " .. #printers, "Print result: " .. xBlocks .. "x" .. yBlocks .. " blocks", "Total count: " .. xBlocks * yBlocks .. " blocks" @@ -170,13 +170,13 @@ end local function drawMainImageObject(object) if mainImage then - local xImage = mainImage.width < buffer.screen.width and math.floor(buffer.screen.width / 2 - mainImage.width / 2) or 1 - local yImage = mainImage.height < buffer.screen.height and math.floor(buffer.screen.height / 2 - mainImage.height / 2) or 1 + local xImage = image.getWidth(mainImage) < buffer.screen.width and math.floor(buffer.screen.width / 2 - image.getWidth(mainImage) / 2) or 1 + local yImage = image.getHeight(mainImage) < buffer.screen.height and math.floor(buffer.screen.height / 2 - image.getHeight(mainImage) / 2) or 1 buffer.image(xImage, yImage, mainImage) - GUI.windowShadow(xImage, yImage, mainImage.width, mainImage.height, 50, true) + GUI.windowShadow(xImage, yImage, image.getWidth(mainImage), image.getHeight(mainImage), 50, true) if config.showGrid then - for x = xImage, xImage + mainImage.width - 1, shapeResolutionLimit do verticalLine(x, yImage, mainImage.height, 0.627) end - for y = yImage, yImage + mainImage.height - 1, shapeResolutionLimit / 2 do horizontalLine(xImage, y, mainImage.width, 0.627) end + for x = xImage, xImage + image.getWidth(mainImage) - 1, shapeResolutionLimit do verticalLine(x, yImage, image.getHeight(mainImage), 0.627) end + for y = yImage, yImage + image.getHeight(mainImage) - 1, shapeResolutionLimit / 2 do horizontalLine(xImage, y, image.getWidth(mainImage), 0.627) end buffer.text(1, 1, 0xBBBBBB, "хуй") end end diff --git a/Applications/QuantumCube/Icon.pic b/Applications/QuantumCube/Icon.pic index d9d4b85f..a6643e54 100644 Binary files a/Applications/QuantumCube/Icon.pic and b/Applications/QuantumCube/Icon.pic differ diff --git a/Applications/Radio/Icon.pic b/Applications/Radio/Icon.pic index ee54526b..c5f17e38 100644 Binary files a/Applications/Radio/Icon.pic and b/Applications/Radio/Icon.pic differ diff --git a/Applications/RayWalk/Icon.pic b/Applications/RayWalk/Icon.pic index 21544b5c..b8e59198 100644 Binary files a/Applications/RayWalk/Icon.pic and b/Applications/RayWalk/Icon.pic differ diff --git a/Applications/RayWalk/Weapons/CrosshairTextures/Angled.pic b/Applications/RayWalk/Weapons/CrosshairTextures/Angled.pic old mode 100755 new mode 100644 index 301892fd..b89fb64c Binary files a/Applications/RayWalk/Weapons/CrosshairTextures/Angled.pic and b/Applications/RayWalk/Weapons/CrosshairTextures/Angled.pic differ diff --git a/Applications/RayWalk/Weapons/CrosshairTextures/Default.pic b/Applications/RayWalk/Weapons/CrosshairTextures/Default.pic old mode 100755 new mode 100644 index e997c9a3..19b50b5d Binary files a/Applications/RayWalk/Weapons/CrosshairTextures/Default.pic and b/Applications/RayWalk/Weapons/CrosshairTextures/Default.pic differ diff --git a/Applications/RayWalk/Weapons/CrosshairTextures/Dotted.pic b/Applications/RayWalk/Weapons/CrosshairTextures/Dotted.pic old mode 100755 new mode 100644 index 6d02180d..5e93a436 Binary files a/Applications/RayWalk/Weapons/CrosshairTextures/Dotted.pic and b/Applications/RayWalk/Weapons/CrosshairTextures/Dotted.pic differ diff --git a/Applications/RayWalk/Weapons/CrosshairTextures/Half.pic b/Applications/RayWalk/Weapons/CrosshairTextures/Half.pic old mode 100755 new mode 100644 index 465c6f47..209f09ea Binary files a/Applications/RayWalk/Weapons/CrosshairTextures/Half.pic and b/Applications/RayWalk/Weapons/CrosshairTextures/Half.pic differ diff --git a/Applications/RayWalk/Weapons/FireTextures/Plasma.pic b/Applications/RayWalk/Weapons/FireTextures/Plasma.pic old mode 100755 new mode 100644 index 6a16564a..f97fdb8f Binary files a/Applications/RayWalk/Weapons/FireTextures/Plasma.pic and b/Applications/RayWalk/Weapons/FireTextures/Plasma.pic differ diff --git a/Applications/RayWalk/Weapons/FireTextures/PowderFire.pic b/Applications/RayWalk/Weapons/FireTextures/PowderFire.pic old mode 100755 new mode 100644 index f91c3c47..89b283c3 Binary files a/Applications/RayWalk/Weapons/FireTextures/PowderFire.pic and b/Applications/RayWalk/Weapons/FireTextures/PowderFire.pic differ diff --git a/Applications/RayWalk/Weapons/WeaponTextures/Pistol.pic b/Applications/RayWalk/Weapons/WeaponTextures/Pistol.pic old mode 100755 new mode 100644 index 806f1d6d..e6ebe7c5 Binary files a/Applications/RayWalk/Weapons/WeaponTextures/Pistol.pic and b/Applications/RayWalk/Weapons/WeaponTextures/Pistol.pic differ diff --git a/Applications/RayWalk/Weapons/WeaponTextures/Plasmer.pic b/Applications/RayWalk/Weapons/WeaponTextures/Plasmer.pic old mode 100755 new mode 100644 index 75e49f99..e1994a21 Binary files a/Applications/RayWalk/Weapons/WeaponTextures/Plasmer.pic and b/Applications/RayWalk/Weapons/WeaponTextures/Plasmer.pic differ diff --git a/Applications/RayWalk/Weapons/WeaponTextures/Rifle.pic b/Applications/RayWalk/Weapons/WeaponTextures/Rifle.pic old mode 100755 new mode 100644 index 50858628..fd034377 Binary files a/Applications/RayWalk/Weapons/WeaponTextures/Rifle.pic and b/Applications/RayWalk/Weapons/WeaponTextures/Rifle.pic differ diff --git a/Applications/RayWalk/Weapons/WeaponTextures/Sniper.pic b/Applications/RayWalk/Weapons/WeaponTextures/Sniper.pic old mode 100755 new mode 100644 index 926953e2..53d74425 Binary files a/Applications/RayWalk/Weapons/WeaponTextures/Sniper.pic and b/Applications/RayWalk/Weapons/WeaponTextures/Sniper.pic differ diff --git a/Applications/RunningString/Icon.pic b/Applications/RunningString/Icon.pic index 5e6c8c71..6eacebcc 100644 Binary files a/Applications/RunningString/Icon.pic and b/Applications/RunningString/Icon.pic differ diff --git a/Applications/Shooting/Icon.pic b/Applications/Shooting/Icon.pic index 9ecfd340..7a2f264a 100644 Binary files a/Applications/Shooting/Icon.pic and b/Applications/Shooting/Icon.pic differ diff --git a/Applications/SmartHouse/Icon.pic b/Applications/SmartHouse/Icon.pic index 68a8d810..6ff36b49 100644 Binary files a/Applications/SmartHouse/Icon.pic and b/Applications/SmartHouse/Icon.pic differ diff --git a/Applications/SmartHouse/Modules/command_block/Icon.pic b/Applications/SmartHouse/Modules/command_block/Icon.pic index ea3be0e8..c8c42687 100644 Binary files a/Applications/SmartHouse/Modules/command_block/Icon.pic and b/Applications/SmartHouse/Modules/command_block/Icon.pic differ diff --git a/Applications/SmartHouse/Modules/homePC/Icon.pic b/Applications/SmartHouse/Modules/homePC/Icon.pic index 3d64612a..66ce7360 100644 Binary files a/Applications/SmartHouse/Modules/homePC/Icon.pic and b/Applications/SmartHouse/Modules/homePC/Icon.pic differ diff --git a/Applications/SmartHouse/Modules/homePC/Server.pic b/Applications/SmartHouse/Modules/homePC/Server.pic index 47635948..4fad2e85 100644 Binary files a/Applications/SmartHouse/Modules/homePC/Server.pic and b/Applications/SmartHouse/Modules/homePC/Server.pic differ diff --git a/Applications/SmartHouse/Modules/mfsu/Icon.pic b/Applications/SmartHouse/Modules/mfsu/Icon.pic index f8db004f..222dc330 100644 Binary files a/Applications/SmartHouse/Modules/mfsu/Icon.pic and b/Applications/SmartHouse/Modules/mfsu/Icon.pic differ diff --git a/Applications/SmartHouse/Modules/motion_sensor/Icon.pic b/Applications/SmartHouse/Modules/motion_sensor/Icon.pic index 51314a2f..b34c8157 100644 Binary files a/Applications/SmartHouse/Modules/motion_sensor/Icon.pic and b/Applications/SmartHouse/Modules/motion_sensor/Icon.pic differ diff --git a/Applications/SmartHouse/Modules/reactor/Icon.pic b/Applications/SmartHouse/Modules/reactor/Icon.pic index c463dc0f..fa84a3ea 100644 Binary files a/Applications/SmartHouse/Modules/reactor/Icon.pic and b/Applications/SmartHouse/Modules/reactor/Icon.pic differ diff --git a/Applications/SmartHouse/Modules/redstone/Icon.pic b/Applications/SmartHouse/Modules/redstone/Icon.pic index 90841a49..73593d92 100644 Binary files a/Applications/SmartHouse/Modules/redstone/Icon.pic and b/Applications/SmartHouse/Modules/redstone/Icon.pic differ diff --git a/Applications/SmartHouse/Modules/screen/Icon.pic b/Applications/SmartHouse/Modules/screen/Icon.pic index fc9b172c..e1b5f8ac 100644 Binary files a/Applications/SmartHouse/Modules/screen/Icon.pic and b/Applications/SmartHouse/Modules/screen/Icon.pic differ diff --git a/Applications/Stargate/Gate.pic b/Applications/Stargate/Gate.pic index cf17b105..1522b174 100644 Binary files a/Applications/Stargate/Gate.pic and b/Applications/Stargate/Gate.pic differ diff --git a/Applications/Stargate/GateCore.pic b/Applications/Stargate/GateCore.pic index dac109ea..44ec4bab 100644 Binary files a/Applications/Stargate/GateCore.pic and b/Applications/Stargate/GateCore.pic differ diff --git a/Applications/Stargate/Icon.pic b/Applications/Stargate/Icon.pic index 5ff4234a..2c3153d7 100644 Binary files a/Applications/Stargate/Icon.pic and b/Applications/Stargate/Icon.pic differ diff --git a/Applications/Stargate/Stargate.lua b/Applications/Stargate/Stargate.lua index 1f075fcb..cebeb537 100755 --- a/Applications/Stargate/Stargate.lua +++ b/Applications/Stargate/Stargate.lua @@ -79,7 +79,7 @@ local function drawSG() buttons = {} local toolbarHeight = 34 - local x, y = math.floor((buffer.screen.width - toolbarWidth) / 2 - sg.width / 2), math.floor(buffer.screen.height / 2 - sg.height / 2) + local x, y = math.floor((buffer.screen.width - toolbarWidth) / 2 - sg[1] / 2), math.floor(buffer.screen.height / 2 - sg[2] / 2) buffer.image(x, y, sg) local stargateState = stargate.stargateState() @@ -92,7 +92,7 @@ local function drawSG() end drawChevrons(x, y) local currentDockWidth, heightOfDock = 50, 4 - drawDock(math.floor(x + sg.width / 2 - currentDockWidth / 2), y + sg.height + 1, currentDockWidth, heightOfDock ) + drawDock(math.floor(x + sg[1] / 2 - currentDockWidth / 2), y + sg[2] + 1, currentDockWidth, heightOfDock ) local function centerText(y, color, text) local x = math.floor(buffer.screen.width - toolbarWidth / 2 - unicode.len(text) / 2 + 1) @@ -104,7 +104,7 @@ local function drawSG() local buttonDisabledColor = 0xAAAAAA local pizdos = math.floor(buffer.screen.height / 2) - x, y = x + sg.width + 5, pizdos + x, y = x + sg[1] + 5, pizdos local width = buffer.screen.width - x - toolbarWidth buffer.text(x, y, lineColor, string.rep("─", width)) x = x + width @@ -272,9 +272,7 @@ while true do if e[3] == "Closing" then stateOfChevrons(false) end drawAll() elseif e[1] == "sgChevronEngaged" then - if chevrons[e[3]] then - chevrons[e[3]].isActivated = true - end + chevrons[e[3]].isActivated = true drawAll() elseif e[1] == "sgMessageReceived" then GUI.error(tostring(e[3]), {title = {color = 0xFFDB40, text = "Соообщение от Врат"}, backgroundColor = 0x262626}) diff --git a/Applications/TurretControl/Icon.pic b/Applications/TurretControl/Icon.pic index 35aaafb2..9effbea4 100644 Binary files a/Applications/TurretControl/Icon.pic and b/Applications/TurretControl/Icon.pic differ diff --git a/Applications/TurretControl/Turret.pic b/Applications/TurretControl/Turret.pic index fe98e0db..46b99f7f 100644 Binary files a/Applications/TurretControl/Turret.pic and b/Applications/TurretControl/Turret.pic differ diff --git a/Applications/TurretControl/TurretControl.lua b/Applications/TurretControl/TurretControl.lua index 0693d472..e9928aac 100644 --- a/Applications/TurretControl/TurretControl.lua +++ b/Applications/TurretControl/TurretControl.lua @@ -27,8 +27,8 @@ local turretConfig = { local yTurrets = 2 local spaceBetweenTurretsHorizontal = 2 local spaceBetweenTurretsVertical = 1 -local turretHeight = turretImage.height + 12 -local turretWidth = turretImage.width + 8 +local turretHeight = turretImage[2] + 12 +local turretWidth = turretImage[1] + 8 local countOfTurretsCanBeShowByWidth = math.floor(buffer.screen.width / (turretWidth + spaceBetweenTurretsHorizontal)) local xTurrets = math.floor(buffer.screen.width / 2 - (countOfTurretsCanBeShowByWidth * (turretWidth + spaceBetweenTurretsHorizontal)) / 2 ) + math.floor(spaceBetweenTurretsHorizontal / 2) @@ -107,7 +107,7 @@ local function drawTurrets(y) buffer.text(x + 2, yPos, yellowColor, ecs.stringLimit("end", "Турель " .. turrets[turret].proxy.address, turretWidth - 4)) yPos = yPos + 2 buffer.image(x + 4, yPos, turretImage) - yPos = yPos + turretImage.height + 1 + yPos = yPos + turretImage[2] + 1 buffer.text(x + 2, yPos, yellowColor, "Энергия:") yPos = yPos + 1 progressBar(x + 1, yPos, turretWidth - 2, 3, 0x000000, yellowColor, turrets[turret].energyPercent) diff --git a/Applications/VK/Icon.pic b/Applications/VK/Icon.pic index 3e1aafd2..c4363302 100644 Binary files a/Applications/VK/Icon.pic and b/Applications/VK/Icon.pic differ diff --git a/Applications/VK/VK.lua b/Applications/VK/VK.lua index d08ee8c1..98ab2d1d 100755 --- a/Applications/VK/VK.lua +++ b/Applications/VK/VK.lua @@ -307,7 +307,7 @@ local function loginGUI(startUsername, startPassword) local background = 0x002440 local buttonColor = 0x666DFF local textColor = 0x262626 - local username, password = startUsername or "E-Mail или номер телефона", startPassword or "Пароль" + local username, password = startUsername, startPassword local textFieldWidth = 50 local textFieldHeight = 3 @@ -316,11 +316,11 @@ local function loginGUI(startUsername, startPassword) local obj = {} obj.username = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1 obj.password = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1 - obj.button = GUI.button(x, y, textFieldWidth, textFieldHeight, buttonColor, 0xFFFFFF, 0xFFFFFF, buttonColor, "Войти") + obj.button = GUI.button(x, y, textFieldWidth, textFieldHeight, buttonColor, 0xEEEEEE, 0xEEEEEE, buttonColor, "Войти") local VKLogoImage = image.load(VKLogoImagePath) - local loginTextBox = GUI.inputTextBox(x, obj.username[2], textFieldWidth, 3, 0xFFFFFF, 0x444444, 0xFFFFFF, 0x262626, username, "E-Mail", false) - local passwordTextBox = GUI.inputTextBox(x, obj.password[2], textFieldWidth, 3, 0xFFFFFF, 0x444444, 0xFFFFFF, 0x262626, password, "Password", false, "*") + local loginTextBox = GUI.inputTextBox(x, obj.username[2], textFieldWidth, 3, 0xEEEEEE, 0x777777, 0xEEEEEE, 0x262626, username, "E-Mail", false) + local passwordTextBox = GUI.inputTextBox(x, obj.password[2], textFieldWidth, 3, 0xEEEEEE, 0x777777, 0xEEEEEE, 0x262626, password, "Password", false, "*") local function draw() buffer.clear(colors.loginGUIBackground) @@ -1087,7 +1087,7 @@ buffer.start() --Хуярим настррррроечки loadSettings() --Активируем форму логина -local loginData = loginGUI(settings.username or "E-Mail", settings.password or "password") +local loginData = loginGUI(settings.username, settings.password) access_token = loginData.access_token --Получаем персональные данные _, personalInfo = usersInformationRequest(loginData.user_id) diff --git a/Applications/VK/VKLogo.pic b/Applications/VK/VKLogo.pic index 7ead9384..a6a2e932 100644 Binary files a/Applications/VK/VKLogo.pic and b/Applications/VK/VKLogo.pic differ diff --git a/Applications/Weather/Cloudy.pic b/Applications/Weather/Cloudy.pic index e2027cbb..08a860a4 100644 Binary files a/Applications/Weather/Cloudy.pic and b/Applications/Weather/Cloudy.pic differ diff --git a/Applications/Weather/Icon.pic b/Applications/Weather/Icon.pic index fa30a947..f29b8737 100644 Binary files a/Applications/Weather/Icon.pic and b/Applications/Weather/Icon.pic differ diff --git a/Applications/Weather/Rainy.pic b/Applications/Weather/Rainy.pic index c2297554..d4453d92 100644 Binary files a/Applications/Weather/Rainy.pic and b/Applications/Weather/Rainy.pic differ diff --git a/Applications/Weather/Snowy.pic b/Applications/Weather/Snowy.pic index a12a9afb..6059231b 100644 Binary files a/Applications/Weather/Snowy.pic and b/Applications/Weather/Snowy.pic differ diff --git a/Applications/Weather/Stormy.pic b/Applications/Weather/Stormy.pic index be9c0528..c8e4709d 100644 Binary files a/Applications/Weather/Stormy.pic and b/Applications/Weather/Stormy.pic differ diff --git a/Applications/Weather/Sunny.pic b/Applications/Weather/Sunny.pic index 508008a0..b1f0a6c2 100644 Binary files a/Applications/Weather/Sunny.pic and b/Applications/Weather/Sunny.pic differ diff --git a/Applications/Weather/SunnyWithClouds.pic b/Applications/Weather/SunnyWithClouds.pic index fa30a947..f29b8737 100644 Binary files a/Applications/Weather/SunnyWithClouds.pic and b/Applications/Weather/SunnyWithClouds.pic differ diff --git a/Documentation/GUI.md b/Documentation/GUI.md index a2ed4942..020715e6 100644 --- a/Documentation/GUI.md +++ b/Documentation/GUI.md @@ -982,7 +982,7 @@ local x, y = math.floor(window.width / 2 - elementWidth / 2), math.floor(window. -- Загружаем и добавляем изображение логотипа "нашей компании" local logotype = image.load("/MineOS/Applications/VK.app/Resources/VKLogo.pic") -window:addImage(math.floor(window.width / 2 - logotype.width / 2) - 2, y - logotype.height - 1, logotype); y = y + 2 +window:addImage(math.floor(window.width / 2 - image.getWidth(logotype) / 2) - 2, y - image.getHeight(logotype) - 1, logotype); y = y + 2 -- Создаем поле для ввода адреса почты local emailTextBox = window:addInputTextBox(x, y, elementWidth, elementHeight, 0xEEEEEE, 0x777777, 0xEEEEEE, 0x2D2D2D, nil, "E-mail", false, nil, nil, nil) diff --git a/MineOS/Icons/3DModel.pic b/MineOS/Icons/3DModel.pic index b8175a10..4a59920a 100644 Binary files a/MineOS/Icons/3DModel.pic and b/MineOS/Icons/3DModel.pic differ diff --git a/MineOS/Icons/Application.pic b/MineOS/Icons/Application.pic old mode 100755 new mode 100644 index 9563c32f..9d7cd339 Binary files a/MineOS/Icons/Application.pic and b/MineOS/Icons/Application.pic differ diff --git a/MineOS/Icons/Archive.pic b/MineOS/Icons/Archive.pic index 6ef24be0..1c5e4d85 100644 Binary files a/MineOS/Icons/Archive.pic and b/MineOS/Icons/Archive.pic differ diff --git a/MineOS/Icons/Computer.pic b/MineOS/Icons/Computer.pic index 4e9fec95..a7c0cd22 100644 Binary files a/MineOS/Icons/Computer.pic and b/MineOS/Icons/Computer.pic differ diff --git a/MineOS/Icons/Config.pic b/MineOS/Icons/Config.pic index 52537f16..6665434a 100644 Binary files a/MineOS/Icons/Config.pic and b/MineOS/Icons/Config.pic differ diff --git a/MineOS/Icons/Downloading.pic b/MineOS/Icons/Downloading.pic index 471cdf77..c4799201 100644 Binary files a/MineOS/Icons/Downloading.pic and b/MineOS/Icons/Downloading.pic differ diff --git a/MineOS/Icons/FileNotExists.pic b/MineOS/Icons/FileNotExists.pic index e021276a..beb2616d 100644 Binary files a/MineOS/Icons/FileNotExists.pic and b/MineOS/Icons/FileNotExists.pic differ diff --git a/MineOS/Icons/Finger.pic b/MineOS/Icons/Finger.pic index c3310793..21d43984 100644 Binary files a/MineOS/Icons/Finger.pic and b/MineOS/Icons/Finger.pic differ diff --git a/MineOS/Icons/Floppy.pic b/MineOS/Icons/Floppy.pic index 2d73cb49..6b45d1c9 100644 Binary files a/MineOS/Icons/Floppy.pic and b/MineOS/Icons/Floppy.pic differ diff --git a/MineOS/Icons/Folder.pic b/MineOS/Icons/Folder.pic index a99c78c1..67da2648 100644 Binary files a/MineOS/Icons/Folder.pic and b/MineOS/Icons/Folder.pic differ diff --git a/MineOS/Icons/HDD.pic b/MineOS/Icons/HDD.pic index a42f0fea..e50cd2a1 100644 Binary files a/MineOS/Icons/HDD.pic and b/MineOS/Icons/HDD.pic differ diff --git a/MineOS/Icons/Image.pic b/MineOS/Icons/Image.pic index b7eca799..f9f60845 100644 Binary files a/MineOS/Icons/Image.pic and b/MineOS/Icons/Image.pic differ diff --git a/MineOS/Icons/Languages.pic b/MineOS/Icons/Languages.pic index 9db56e75..da1494b8 100644 Binary files a/MineOS/Icons/Languages.pic and b/MineOS/Icons/Languages.pic differ diff --git a/MineOS/Icons/Love.pic b/MineOS/Icons/Love.pic index 6429fea8..d3b6a591 100644 Binary files a/MineOS/Icons/Love.pic and b/MineOS/Icons/Love.pic differ diff --git a/MineOS/Icons/Lua.pic b/MineOS/Icons/Lua.pic index d7b3cea8..38efd7be 100644 Binary files a/MineOS/Icons/Lua.pic and b/MineOS/Icons/Lua.pic differ diff --git a/MineOS/Icons/OK.pic b/MineOS/Icons/OK.pic index 669be952..da867b01 100644 Binary files a/MineOS/Icons/OK.pic and b/MineOS/Icons/OK.pic differ diff --git a/MineOS/Icons/OS_Logo.pic b/MineOS/Icons/OS_Logo.pic index dc3ccce8..f6e8fcf7 100644 Binary files a/MineOS/Icons/OS_Logo.pic and b/MineOS/Icons/OS_Logo.pic differ diff --git a/MineOS/Icons/Pastebin.pic b/MineOS/Icons/Pastebin.pic index 709eb08b..038d95ba 100644 Binary files a/MineOS/Icons/Pastebin.pic and b/MineOS/Icons/Pastebin.pic differ diff --git a/MineOS/Icons/RawImage.pic b/MineOS/Icons/RawImage.pic deleted file mode 100644 index e3fbeaa4..00000000 Binary files a/MineOS/Icons/RawImage.pic and /dev/null differ diff --git a/MineOS/Icons/Robot.pic b/MineOS/Icons/Robot.pic index f4175286..107fdce4 100644 Binary files a/MineOS/Icons/Robot.pic and b/MineOS/Icons/Robot.pic differ diff --git a/MineOS/Icons/SampleIcon.pic b/MineOS/Icons/SampleIcon.pic index e1aee29b..06a0bcaa 100644 Binary files a/MineOS/Icons/SampleIcon.pic and b/MineOS/Icons/SampleIcon.pic differ diff --git a/MineOS/Icons/Script.pic b/MineOS/Icons/Script.pic index b7a4156f..8adc3360 100644 Binary files a/MineOS/Icons/Script.pic and b/MineOS/Icons/Script.pic differ diff --git a/MineOS/Icons/Security.pic b/MineOS/Icons/Security.pic index d1b4722c..a46db99b 100644 Binary files a/MineOS/Icons/Security.pic and b/MineOS/Icons/Security.pic differ diff --git a/MineOS/Icons/Steve.pic b/MineOS/Icons/Steve.pic index 72d28dd3..5d8bcc4d 100644 Binary files a/MineOS/Icons/Steve.pic and b/MineOS/Icons/Steve.pic differ diff --git a/MineOS/Icons/Tablet.pic b/MineOS/Icons/Tablet.pic index ef53dee0..55c834b2 100644 Binary files a/MineOS/Icons/Tablet.pic and b/MineOS/Icons/Tablet.pic differ diff --git a/MineOS/Icons/Text.pic b/MineOS/Icons/Text.pic index 493c3052..21fc3490 100644 Binary files a/MineOS/Icons/Text.pic and b/MineOS/Icons/Text.pic differ diff --git a/MineOS/Icons/Trash.pic b/MineOS/Icons/Trash.pic index cac6eac5..c36191ae 100644 Binary files a/MineOS/Icons/Trash.pic and b/MineOS/Icons/Trash.pic differ diff --git a/MineOS/Icons/Update.pic b/MineOS/Icons/Update.pic index 9f797d95..73788bf1 100644 Binary files a/MineOS/Icons/Update.pic and b/MineOS/Icons/Update.pic differ diff --git a/MineOS/OS.lua b/MineOS/OS.lua index d3cf9464..03283e34 100755 --- a/MineOS/OS.lua +++ b/MineOS/OS.lua @@ -431,7 +431,7 @@ end local function createWorkspace() workspace = GUI.fullScreenWindow() workspace.background = workspace:addPanel(1, 1, workspace.width, workspace.height, _G.OSSettings.backgroundColor or colors.background) - workspace.wallpaper = workspace:addImage(1, 1, {width = workspace.width, height = workspace.height}) + workspace.wallpaper = workspace:addImage(1, 1, {workspace.width, workspace.height}) workspace.desktopCounters = workspace:addContainer(1, 1, 1, 1) diff --git a/MineOS/Wallpapers/Afterlife.pic b/MineOS/Wallpapers/Afterlife.pic deleted file mode 100644 index 6cd2541f..00000000 Binary files a/MineOS/Wallpapers/Afterlife.pic and /dev/null differ diff --git a/MineOS/Wallpapers/AhsokaTanoHiRes.pic b/MineOS/Wallpapers/AhsokaTanoHiRes.pic index a8867e17..bc4ba77f 100644 Binary files a/MineOS/Wallpapers/AhsokaTanoHiRes.pic and b/MineOS/Wallpapers/AhsokaTanoHiRes.pic differ diff --git a/MineOS/Wallpapers/Blueberry.pic b/MineOS/Wallpapers/Blueberry.pic deleted file mode 100644 index fa2859ae..00000000 Binary files a/MineOS/Wallpapers/Blueberry.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Catniss.pic b/MineOS/Wallpapers/Catniss.pic index 74a0ff7e..a1e2c423 100644 Binary files a/MineOS/Wallpapers/Catniss.pic and b/MineOS/Wallpapers/Catniss.pic differ diff --git a/MineOS/Wallpapers/ChristmasTree.pic b/MineOS/Wallpapers/ChristmasTree.pic index f0649507..62efb20f 100644 Binary files a/MineOS/Wallpapers/ChristmasTree.pic and b/MineOS/Wallpapers/ChristmasTree.pic differ diff --git a/MineOS/Wallpapers/Ciri.pic b/MineOS/Wallpapers/Ciri.pic index ed6837aa..55b84565 100644 Binary files a/MineOS/Wallpapers/Ciri.pic and b/MineOS/Wallpapers/Ciri.pic differ diff --git a/MineOS/Wallpapers/Dayeneris.pic b/MineOS/Wallpapers/Dayeneris.pic deleted file mode 100644 index cedde461..00000000 Binary files a/MineOS/Wallpapers/Dayeneris.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Girl.pic b/MineOS/Wallpapers/Girl.pic index 91735d2d..334b9a2d 100644 Binary files a/MineOS/Wallpapers/Girl.pic and b/MineOS/Wallpapers/Girl.pic differ diff --git a/MineOS/Wallpapers/Harp.pic b/MineOS/Wallpapers/Harp.pic deleted file mode 100644 index fa904516..00000000 Binary files a/MineOS/Wallpapers/Harp.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Invoker.pic b/MineOS/Wallpapers/Invoker.pic deleted file mode 100644 index 18556fdd..00000000 Binary files a/MineOS/Wallpapers/Invoker.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Jodie.pic b/MineOS/Wallpapers/Jodie.pic deleted file mode 100644 index f3800441..00000000 Binary files a/MineOS/Wallpapers/Jodie.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Liara.pic b/MineOS/Wallpapers/Liara.pic deleted file mode 100644 index afc5bc4b..00000000 Binary files a/MineOS/Wallpapers/Liara.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Luna.pic b/MineOS/Wallpapers/Luna.pic deleted file mode 100644 index 27f2d655..00000000 Binary files a/MineOS/Wallpapers/Luna.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Nettle.pic b/MineOS/Wallpapers/Nettle.pic index 40c06cd1..2e63b65d 100644 Binary files a/MineOS/Wallpapers/Nettle.pic and b/MineOS/Wallpapers/Nettle.pic differ diff --git a/MineOS/Wallpapers/Nocturnal.pic b/MineOS/Wallpapers/Nocturnal.pic index ad71342a..94555c33 100644 Binary files a/MineOS/Wallpapers/Nocturnal.pic and b/MineOS/Wallpapers/Nocturnal.pic differ diff --git a/MineOS/Wallpapers/Raspberry.pic b/MineOS/Wallpapers/Raspberry.pic index 0639737d..1da69c1a 100644 Binary files a/MineOS/Wallpapers/Raspberry.pic and b/MineOS/Wallpapers/Raspberry.pic differ diff --git a/MineOS/Wallpapers/StarWars.pic b/MineOS/Wallpapers/StarWars.pic deleted file mode 100644 index d1f183d8..00000000 Binary files a/MineOS/Wallpapers/StarWars.pic and /dev/null differ diff --git a/MineOS/Wallpapers/Sunbeams.pic b/MineOS/Wallpapers/Sunbeams.pic deleted file mode 100644 index bd96bc56..00000000 Binary files a/MineOS/Wallpapers/Sunbeams.pic and /dev/null differ diff --git a/MineOS/Wallpapers/TemplarAssassin.pic b/MineOS/Wallpapers/TemplarAssassin.pic index fdc0d03c..7daac977 100644 Binary files a/MineOS/Wallpapers/TemplarAssassin.pic and b/MineOS/Wallpapers/TemplarAssassin.pic differ diff --git a/lib/ECSAPI.lua b/lib/ECSAPI.lua index 6332b866..77853a37 100755 --- a/lib/ECSAPI.lua +++ b/lib/ECSAPI.lua @@ -297,7 +297,7 @@ function ecs.getOSApplication(application) fs.makeDirectory(application.name .. ".app/Resources") --Загружаем основной исполняемый файл и иконку - ecs.getFromGitHub(application.url, application.name .. ".app/" .. fs.name(application.name .. ".lua")) + ecs.getFromGitHub(application.url, application.name .. ".app/Main.lua") ecs.getFromGitHub(application.icon, application.name .. ".app/Resources/Icon.pic") --Если есть ресурсы, то загружаем ресурсы diff --git a/lib/GUI.lua b/lib/GUI.lua index 7ac6c782..553eef88 100755 --- a/lib/GUI.lua +++ b/lib/GUI.lua @@ -592,7 +592,7 @@ local function drawImage(object) end function GUI.image(x, y, image) - local object = GUI.object(x, y, image.width, image.height) + local object = GUI.object(x, y, image[1], image[2]) object.image = image object.draw = drawImage return object @@ -626,7 +626,7 @@ local function drawDropDownMenuElement(object, itemIndex, isPressed) end -- Основной текст - buffer.text(object.x + object.sidesOffset, yText, textColor, string.limit(object.items[itemIndex].text, object.width - object.sidesOffset * 2, false)) + buffer.text(object.x + object.sidesOffset, yText, textColor, string.limit(object.items[itemIndex].text, object.width - object.sidesOffset * 2, "right")) -- Шурткатикус if object.items[itemIndex].shortcut then buffer.text(object.x + object.width - unicode.len(object.items[itemIndex].shortcut) - object.sidesOffset, yText, textColor, object.items[itemIndex].shortcut) @@ -665,8 +665,8 @@ local function showDropDownMenu(object) if e[3] >= object.x and e[3] <= object.x + object.width - 1 and - e[4] >= object.y + (itemIndex - 1) * object.elementHeight - 1 and - e[4] <= object.y + (itemIndex - 1) * object.elementHeight - 1 + object.elementHeight + e[4] >= object.y + itemIndex * object.elementHeight - object.elementHeight and + e[4] <= object.y + itemIndex * object.elementHeight - 1 then objectFound = true if not object.items[itemIndex].disabled and object.items[itemIndex].type == GUI.dropDownMenuElementTypes.default then @@ -1131,7 +1131,19 @@ local function drawInputTextBox(inputTextBox) local background = inputTextBox.isFocused and inputTextBox.colors.focused.background or inputTextBox.colors.default.background local foreground = inputTextBox.isFocused and inputTextBox.colors.focused.text or inputTextBox.colors.default.text local y = math.floor(inputTextBox.y + inputTextBox.height / 2) - local text = inputTextBox.isFocused and (inputTextBox.eraseTextOnFocus and "" or inputTextBox.text) or (inputTextBox.text ~= "" and inputTextBox.text or inputTextBox.placeholderText or "") + + local text = inputTextBox.text or "" + if inputTextBox.isFocused then + if inputTextBox.eraseTextOnFocus then + text = "" + else + text = inputTextBox.text or "" + end + else + if inputTextBox.text == "" or not inputTextBox.text then + text = inputTextBox.placeholderText or "" + end + end if background then buffer.square(inputTextBox.x, inputTextBox.y, inputTextBox.width, inputTextBox.height, background, foreground, " ") @@ -1333,7 +1345,7 @@ end local function drawComboBox(object) buffer.square(object.x, object.y, object.width, object.height, object.colors.default.background) local x, y, limit, arrowSize = object.x + 1, math.floor(object.y + object.height / 2), object.width - 5, object.height - buffer.text(x, y, object.colors.default.text, string.limit(object.items[object.currentItem].text, limit, false)) + buffer.text(x, y, object.colors.default.text, string.limit(object.items[object.currentItem].text, limit, "right")) GUI.button(object.x + object.width - arrowSize * 2 + 1, object.y, arrowSize * 2 - 1, arrowSize, object.colors.arrow.background, object.colors.arrow.text, 0x0, 0x0, object.state and "▲" or "▼"):draw() end diff --git a/lib/ImageFormatModules/OCIF.lua b/lib/ImageFormatModules/OCIF.lua new file mode 100755 index 00000000..bdb20344 --- /dev/null +++ b/lib/ImageFormatModules/OCIF.lua @@ -0,0 +1,196 @@ + +local args = {...} +local image = args[1] + +---------------------------------------- Libraries ---------------------------------------- + +local bit32 = require("bit32") +local advancedLua = require("advancedLua") +local unicode = require("unicode") +local fs = require("filesystem") +local colorlib = require("colorlib") + +------------------------------------------------------------------------------------------------------------ + +local module = {} +local OCIFSignature = "OCIF" +local encodingMethods = { + load = {}, + save = {} +} + +------------------------------------------------------------------------------------------------------------ + +local function writeByteArrayToFile(file, byteArray) + for i = 1, #byteArray do + file:write(string.char(byteArray[i])) + end +end + +local function readNumberFromFile(file, countOfBytes) + local byteArray = {} + for i = 1, countOfBytes do + table.insert(byteArray, string.byte(file:read(1))) + end + + return bit32.byteArrayToNumber(byteArray) +end + +---------------------------------------- Uncompressed OCIF1 encoding ---------------------------------------- + +encodingMethods.save[1] = function(file, picture) + for i = 3, #picture, 4 do + writeByteArrayToFile(file, {colorlib.HEXtoRGB(picture[i])}) + writeByteArrayToFile(file, {colorlib.HEXtoRGB(picture[i + 1])}) + file:write(string.char(picture[i + 2])) + writeByteArrayToFile(file, {string.byte(picture[i + 3], 1, 6)}) + end +end + +encodingMethods.load[1] = function(file, picture) + for i = 1, image.getWidth(picture) * image.getHeight(picture) do + table.insert(picture, colorlib.RGBtoHEX(string.byte(file:read(1)), string.byte(file:read(1)), string.byte(file:read(1)))) + table.insert(picture, colorlib.RGBtoHEX(string.byte(file:read(1)), string.byte(file:read(1)), string.byte(file:read(1)))) + table.insert(picture, string.byte(file:read(1))) + table.insert(picture, string.readUnicodeChar(file)) + end +end + +---------------------------------------- Grouped and compressed OCIF6 encoding ---------------------------------------- + +encodingMethods.save[6] = function(file, picture) + -- Grouping picture by it's alphas, symbols and colors + local groupedPicture = image.group(picture, true) + -- Writing 1 byte for alphas array size + file:write(string.char(table.size(groupedPicture))) + + for alpha in pairs(groupedPicture) do + -- Writing 1 byte for current alpha value + file:write(string.char(alpha)) + -- Writing 2 bytes for symbols array size + writeByteArrayToFile(file, bit32.numberToFixedSizeByteArray(table.size(groupedPicture[alpha]), 2)) + + for symbol in pairs(groupedPicture[alpha]) do + -- Writing N bytes for current unicode symbol value + writeByteArrayToFile(file, { string.byte(symbol, 1, 6) }) + -- Writing 1 byte for backgrounds array size + file:write(string.char(table.size(groupedPicture[alpha][symbol]))) + + for background in pairs(groupedPicture[alpha][symbol]) do + -- Writing 1 byte for background color value (compressed by colorlib) + file:write(string.char(background)) + -- Writing 1 byte for foregrounds array size + file:write(string.char(table.size(groupedPicture[alpha][symbol][background]))) + + for foreground in pairs(groupedPicture[alpha][symbol][background]) do + -- Writing 1 byte for foreground color value (compressed by colorlib) + file:write(string.char(foreground)) + -- Writing 1 byte for y array size + file:write(string.char(table.size(groupedPicture[alpha][symbol][background][foreground]))) + + for y in pairs(groupedPicture[alpha][symbol][background][foreground]) do + -- Writing 1 byte for current y value + file:write(string.char(y)) + -- Writing 1 byte for x array size + file:write(string.char(#groupedPicture[alpha][symbol][background][foreground][y])) + + for x = 1, #groupedPicture[alpha][symbol][background][foreground][y] do + file:write(string.char(groupedPicture[alpha][symbol][background][foreground][y][x])) + end + end + end + end + end + end +end + +encodingMethods.load[6] = function(file, picture) + local currentAlpha, currentSymbol, currentBackground, currentForeground, currentY, currentX + local alphaSize, symbolSize, backgroundSize, foregroundSize, ySize, xSize + + alphaSize = string.byte(file:read(1)) + + for alpha = 1, alphaSize do + currentAlpha = string.byte(file:read(1)) + symbolSize = readNumberFromFile(file, 2) + + for symbol = 1, symbolSize do + currentSymbol = string.readUnicodeChar(file) + backgroundSize = string.byte(file:read(1)) + + for background = 1, backgroundSize do + currentBackground = colorlib.convert8BitTo24Bit(string.byte(file:read(1))) + foregroundSize = string.byte(file:read(1)) + + for foreground = 1, foregroundSize do + currentForeground = colorlib.convert8BitTo24Bit(string.byte(file:read(1))) + ySize = string.byte(file:read(1)) + + for y = 1, ySize do + currentY = string.byte(file:read(1)) + xSize = string.byte(file:read(1)) + + for x = 1, xSize do + currentX = string.byte(file:read(1)) + image.set(picture, currentX, currentY, currentBackground, currentForeground, currentAlpha, currentSymbol) + end + end + end + end + end + end +end + +---------------------------------------- Public load&save methods of module ---------------------------------------- + +function module.load(path) + local file, reason = io.open(path, "rb") + if file then + local readedSignature = file:read(#OCIFSignature) + if readedSignature == OCIFSignature then + local encodingMethod = string.byte(file:read(1)) + if encodingMethods.load[encodingMethod] then + -- Reading width and height of a picture + local picture = {string.byte(file:read(1)), string.byte(file:read(1))} + -- Continue parsing + encodingMethods.load[encodingMethod](file, picture) + file:close() + return picture + else + file:close() + error("Failed to load OCIF image: encoding method \"" .. tostring(encodingMethod) .. "\" is not supported") + end + else + file:close() + error("Failed to load OCIF image: wrong signature (\"" .. tostring(readedSignature) .. "\")") + end + else + error("Failed to open file for reading: " .. tostring(reason)) + end +end + +function module.save(path, picture, encodingMethod) + encodingMethod = encodingMethod or 6 + + local file, reason = io.open(path, "wb") + if file then + if encodingMethods.save[encodingMethod] then + -- Writing signature, encoding method, image width and height + file:write(OCIFSignature, string.char(encodingMethod), string.char(picture[1]), string.char(picture[2])) + -- Executing selected encoding method + encodingMethods.save[encodingMethod](file, picture) + file:close() + else + file:close() + error("Failed to save file as OCIF image: encoding method \"" .. tostring(encodingMethod) .. "\" is not supported") + end + else + error("Failed to open file for writing: " .. tostring(reason)) + end +end + +------------------------------------------------------------------------------------------------------------ + +return module + + diff --git a/lib/MineOSCore.lua b/lib/MineOSCore.lua index 71684909..e016e89f 100755 --- a/lib/MineOSCore.lua +++ b/lib/MineOSCore.lua @@ -309,14 +309,22 @@ function MineOSCore.analyzeIconFormat(iconObject) if iconObject.isDirectory then if iconObject.format == ".app" then if MineOSCore.showApplicationIcons then - iconObject.iconImage.image = image.load(iconObject.path .. "/Resources/Icon.pic") + if fs.exists(iconObject.path .. "/Resources/Icon.pic") then + iconObject.iconImage.image = image.load(iconObject.path .. "/Resources/Icon.pic") + else + iconObject.iconImage.image = MineOSCore.icons.fileNotExists + end else iconObject.iconImage.image = MineOSCore.icons.application end iconObject.launch = function() ecs.applicationHelp(iconObject.path) - MineOSCore.safeLaunch(iconObject.path .. "/" .. MineOSCore.hideFileFormat(MineOSCore.getFileName(iconObject.path)) .. ".lua") + if fs.exists(iconObject.path .. "/Main.lua") then + MineOSCore.safeLaunch(iconObject.path .. "/Main.lua") + else + MineOSCore.safeLaunch(iconObject.path .. "/" .. MineOSCore.hideFileFormat(MineOSCore.getFileName(iconObject.path)) .. ".lua") + end end else iconObject.iconImage.image = MineOSCore.icons.folder @@ -411,7 +419,7 @@ function MineOSCore.createIconObject(x, y, path, textColor, showFileFormat) iconObject.isShortcut = false iconObject.isSelected = false - iconObject.iconImage = iconObject:addImage(3, 1, {width = 8, height = 4}) + iconObject.iconImage = iconObject:addImage(3, 1, {8, 4}) iconObject.textLabel = iconObject:addLabel(1, MineOSCore.iconHeight, MineOSCore.iconWidth, 1, textColor, MineOSCore.getFileName(iconObject.path)):setAlignment(GUI.alignment.horizontal.center, GUI.alignment.vertical.top) local oldDraw = iconObject.draw diff --git a/lib/advancedLua.lua b/lib/advancedLua.lua index de847498..6f0b1eb6 100755 --- a/lib/advancedLua.lua +++ b/lib/advancedLua.lua @@ -45,23 +45,56 @@ end -------------------------------------------------- Bit32 extensions -------------------------------------------------- +-- Merge two numbers into one (0xAABB, 0xCCDD -> 0xAABBCCDD) +function bit32.merge(number2, number1) + local cutter = math.ceil(math.log(number1 + 1, 256)) * 8 + while number2 > 0 do + number1, number2, cutter = bit32.bor(bit32.lshift(bit32.band(number2, 0xFF), cutter), number1), bit32.rshift(number2, 8), cutter + 8 + end + + return number1 +end + +-- Split number to it's own bytes (0xAABBCC -> {0xAA, 0xBB, 0xCC}) function bit32.numberToByteArray(number) local byteArray = {} - while number > 0 do + + repeat table.insert(byteArray, 1, bit32.band(number, 0xFF)) number = bit32.rshift(number, 8) - end + until number <= 0 + return byteArray end -function bit32.byteArrayToNumber(byteArray) - local number = byteArray[1] - for i = 2, #byteArray do - number = bit32.bor(byteArray[i], bit32.lshift(number, 8)) +-- Split nubmer to it's own bytes with specified count of bytes (0xAABB, 5 -> {0x00, 0x00, 0x00, 0xAA, 0xBB}) +function bit32.numberToFixedSizeByteArray(number, size) + local byteArray, counter = {}, 0 + + repeat + table.insert(byteArray, 1, bit32.band(number, 0xFF)) + number = bit32.rshift(number, 8) + counter = counter + 1 + until number <= 0 + + for i = 1, size - counter do + table.insert(byteArray, 1, 0x0) end - return number + + return byteArray end +-- Create number from it's own bytes ({0xAA, 0xBB, 0xCC} -> 0xAABBCC) +function bit32.byteArrayToNumber(byteArray) + local result = byteArray[1] + for i = 2, #byteArray do + result = bit32.bor(bit32.lshift(result, 8), byteArray[i]) + end + + return result +end + +-- Create byte from it's bits ({1, 0, 1, 0, 1, 0, 1, 1} -> 0xAB) function bit32.bitArrayToByte(bitArray) local number = 0 for i = 1, #bitArray do @@ -70,9 +103,6 @@ function bit32.bitArrayToByte(bitArray) return number end -bit32.byteArrayFromNumber = bit32.numberToByteArray -bit32.numberFromByteArray = bit32.byteArrayToNumber - -------------------------------------------------- Math extensions -------------------------------------------------- function math.round(num) @@ -85,7 +115,7 @@ end function math.roundToDecimalPlaces(num, decimalPlaces) local mult = 10 ^ (decimalPlaces or 0) - return math.round(num * mult) / mult + return math.floor(num * mult + 0.5) / mult end function math.getDigitCount(num) @@ -259,13 +289,31 @@ function table.binarySearch(t, requestedValue) end function table.size(t) - local size = #t - if size == 0 then for key in pairs(t) do size = size + 1 end end + local size = 0 + for key in pairs(t) do size = size + 1 end return size end -------------------------------------------------- String extensions -------------------------------------------------- +function string.readUnicodeChar(file) + local byteArray = {string.byte(file:read(1))} + + local nullBitPosition = 0 + for i = 1, 7 do + if bit32.band(bit32.rshift(byteArray[1], 8 - i), 0x1) == 0x0 then + nullBitPosition = i + break + end + end + + for i = 1, nullBitPosition - 2 do + table.insert(byteArray, string.byte(file:read(1))) + end + + return string.char(table.unpack(byteArray)) +end + function string.canonicalPath(str) return string.gsub("/" .. str, "%/+", "/") end @@ -307,21 +355,24 @@ function string.unicodeFind(str, pattern, init, plain) end end -function string.limit(text, size, fromLeft, noDots) +function string.limit(text, limit, mode, noDots) local length = unicode.len(text) - if length <= size then return text end + if length <= limit then return text end - if fromLeft then + if mode == "left" then if noDots then - return unicode.sub(text, length - size + 1, -1) + return unicode.sub(text, length - limit + 1, -1) else - return "…" .. unicode.sub(text, length - size + 2, -1) + return "…" .. unicode.sub(text, length - limit + 2, -1) end + elseif mode == "center" then + local partSize = math.ceil(limit / 2) + return unicode.sub(text, 1, partSize) .. "…" .. unicode.sub(text, -partSize + 1, -1) else if noDots then - return unicode.sub(text, 1, size) + return unicode.sub(text, 1, limit) else - return unicode.sub(text, 1, size - 1) .. "…" + return unicode.sub(text, 1, limit - 1) .. "…" end end end diff --git a/lib/colorlib.lua b/lib/colorlib.lua index a28c3b96..9c698d93 100755 --- a/lib/colorlib.lua +++ b/lib/colorlib.lua @@ -1,6 +1,4 @@ - local bit32 = require("bit32") -local serialization = require("serialization") local colorlib = {} local function isNan(x) @@ -103,19 +101,24 @@ end ----------------------------------------------------------------------------------------------------------------------- -local palette = {} - -for r = 0, 5 do - for g = 0, 7 do - for b = 0, 4 do - table.insert(palette, colorlib.RGBtoHEX(r * 0x33, g * 0x24, math.floor(b / 4 * 0xFF + 0.5))) --СИНИЙ, ПРЕКРАТИ - end - end -end -for gr = 1, 0x10 do --Градации серого - table.insert(palette, gr * 0xF0F0F) --Нет смысла использовать colorlib.RGBtoHEX() -end -table.sort(palette) +local palette = { + 0x000000, 0x000040, 0x000080, 0x0000BF, 0x0000FF, 0x002400, 0x002440, 0x002480, 0x0024BF, 0x0024FF, 0x004900, 0x004940, 0x004980, 0x0049BF, 0x0049FF, 0x006D00, + 0x006D40, 0x006D80, 0x006DBF, 0x006DFF, 0x009200, 0x009240, 0x009280, 0x0092BF, 0x0092FF, 0x00B600, 0x00B640, 0x00B680, 0x00B6BF, 0x00B6FF, 0x00DB00, 0x00DB40, + 0x00DB80, 0x00DBBF, 0x00DBFF, 0x00FF00, 0x00FF40, 0x00FF80, 0x00FFBF, 0x00FFFF, 0x0F0F0F, 0x1E1E1E, 0x2D2D2D, 0x330000, 0x330040, 0x330080, 0x3300BF, 0x3300FF, + 0x332400, 0x332440, 0x332480, 0x3324BF, 0x3324FF, 0x334900, 0x334940, 0x334980, 0x3349BF, 0x3349FF, 0x336D00, 0x336D40, 0x336D80, 0x336DBF, 0x336DFF, 0x339200, + 0x339240, 0x339280, 0x3392BF, 0x3392FF, 0x33B600, 0x33B640, 0x33B680, 0x33B6BF, 0x33B6FF, 0x33DB00, 0x33DB40, 0x33DB80, 0x33DBBF, 0x33DBFF, 0x33FF00, 0x33FF40, + 0x33FF80, 0x33FFBF, 0x33FFFF, 0x3C3C3C, 0x4B4B4B, 0x5A5A5A, 0x660000, 0x660040, 0x660080, 0x6600BF, 0x6600FF, 0x662400, 0x662440, 0x662480, 0x6624BF, 0x6624FF, + 0x664900, 0x664940, 0x664980, 0x6649BF, 0x6649FF, 0x666D00, 0x666D40, 0x666D80, 0x666DBF, 0x666DFF, 0x669200, 0x669240, 0x669280, 0x6692BF, 0x6692FF, 0x66B600, + 0x66B640, 0x66B680, 0x66B6BF, 0x66B6FF, 0x66DB00, 0x66DB40, 0x66DB80, 0x66DBBF, 0x66DBFF, 0x66FF00, 0x66FF40, 0x66FF80, 0x66FFBF, 0x66FFFF, 0x696969, 0x787878, + 0x878787, 0x969696, 0x990000, 0x990040, 0x990080, 0x9900BF, 0x9900FF, 0x992400, 0x992440, 0x992480, 0x9924BF, 0x9924FF, 0x994900, 0x994940, 0x994980, 0x9949BF, + 0x9949FF, 0x996D00, 0x996D40, 0x996D80, 0x996DBF, 0x996DFF, 0x999200, 0x999240, 0x999280, 0x9992BF, 0x9992FF, 0x99B600, 0x99B640, 0x99B680, 0x99B6BF, 0x99B6FF, + 0x99DB00, 0x99DB40, 0x99DB80, 0x99DBBF, 0x99DBFF, 0x99FF00, 0x99FF40, 0x99FF80, 0x99FFBF, 0x99FFFF, 0xA5A5A5, 0xB4B4B4, 0xC3C3C3, 0xCC0000, 0xCC0040, 0xCC0080, + 0xCC00BF, 0xCC00FF, 0xCC2400, 0xCC2440, 0xCC2480, 0xCC24BF, 0xCC24FF, 0xCC4900, 0xCC4940, 0xCC4980, 0xCC49BF, 0xCC49FF, 0xCC6D00, 0xCC6D40, 0xCC6D80, 0xCC6DBF, + 0xCC6DFF, 0xCC9200, 0xCC9240, 0xCC9280, 0xCC92BF, 0xCC92FF, 0xCCB600, 0xCCB640, 0xCCB680, 0xCCB6BF, 0xCCB6FF, 0xCCDB00, 0xCCDB40, 0xCCDB80, 0xCCDBBF, 0xCCDBFF, + 0xCCFF00, 0xCCFF40, 0xCCFF80, 0xCCFFBF, 0xCCFFFF, 0xD2D2D2, 0xE1E1E1, 0xF0F0F0, 0xFF0000, 0xFF0040, 0xFF0080, 0xFF00BF, 0xFF00FF, 0xFF2400, 0xFF2440, 0xFF2480, + 0xFF24BF, 0xFF24FF, 0xFF4900, 0xFF4940, 0xFF4980, 0xFF49BF, 0xFF49FF, 0xFF6D00, 0xFF6D40, 0xFF6D80, 0xFF6DBF, 0xFF6DFF, 0xFF9200, 0xFF9240, 0xFF9280, 0xFF92BF, + 0xFF92FF, 0xFFB600, 0xFFB640, 0xFFB680, 0xFFB6BF, 0xFFB6FF, 0xFFDB00, 0xFFDB40, 0xFFDB80, 0xFFDBBF, 0xFFDBFF, 0xFFFF00, 0xFFFF40, 0xFFFF80, 0xFFFFBF, 0xFFFFFF, +} function colorlib.convert24BitTo8Bit(hex24) local encodedIndex = nil @@ -158,6 +161,3 @@ return colorlib - - - diff --git a/lib/doubleBuffering.lua b/lib/doubleBuffering.lua index 8bc166a6..d396e57b 100755 --- a/lib/doubleBuffering.lua +++ b/lib/doubleBuffering.lua @@ -244,14 +244,14 @@ end -- Отрисовка изображения function buffer.image(x, y, picture) - local xPos, xEnd, bufferIndexStepOnReachOfImageWidth = x, x + picture.width - 1, (buffer.screen.width - picture.width) * 3 + local xPos, xEnd, bufferIndexStepOnReachOfImageWidth = x, x + picture[1] - 1, (buffer.screen.width - picture[1]) * 3 local bufferIndex = buffer.getBufferIndexByCoordinates(x, y) local imageIndexPlus2, imageIndexPlus3 - for imageIndex = 1, #picture, 4 do + for imageIndex = 3, #picture, 4 do if xPos >= buffer.drawLimit.x and y >= buffer.drawLimit.y and xPos <= buffer.drawLimit.x2 and y <= buffer.drawLimit.y2 then imageIndexPlus2, imageIndexPlus3 = imageIndex + 2, imageIndex + 3 - -- Ебля с прозрачностью + if picture[imageIndexPlus2] == 0x00 then buffer.screen.new[bufferIndex] = picture[imageIndex] buffer.screen.new[bufferIndex + 1] = picture[imageIndex + 1] @@ -265,11 +265,11 @@ function buffer.image(x, y, picture) buffer.screen.new[bufferIndex + 2] = picture[imageIndexPlus3] end end - - --Корректируем координаты и индексы - xPos = xPos + 1 - bufferIndex = bufferIndex + 3 - if xPos > xEnd then xPos, y, bufferIndex = x, y + 1, bufferIndex + bufferIndexStepOnReachOfImageWidth end + + xPos, bufferIndex = xPos + 1, bufferIndex + 3 + if xPos > xEnd then + xPos, y, bufferIndex = x, y + 1, bufferIndex + bufferIndexStepOnReachOfImageWidth + end end end @@ -468,6 +468,31 @@ function buffer.semiPixelLine(x1, y1, x2, y2, color) end end +function buffer.semiPixelCircle(xCenter, yCenter, radius, color, filled) + local function insertPoints(x, y) + buffer.semiPixelSet(xCenter + x, yCenter + y, color) + buffer.semiPixelSet(xCenter + x, yCenter - y, color) + buffer.semiPixelSet(xCenter - x, yCenter + y, color) + buffer.semiPixelSet(xCenter - x, yCenter - y, color) + end + + local x, y = 0, radius + local delta = 3 - 2 * radius; + while (x < y) do + insertPoints(x, y); + insertPoints(y, x); + if (delta < 0) then + delta = delta + (4 * x + 6) + else + delta = delta + (4 * (x - y) + 10) + y = y - 1 + end + x = x + 1 + end + + if x == y then insertPoints(x, y) end +end + ----------------------------------------- Bezier curve ----------------------------------------- local function getPointTimedPosition(firstPoint, secondPoint, time) @@ -620,6 +645,10 @@ end buffer.start() +-- buffer.clear(0x0) +-- buffer.semiPixelCircle(80, 50, 20, 0xFFDB40, true) +-- buffer.draw() + -- buffer.clear(0xFF8888) -- buffer.bezierCurve({ -- -- { x = 32, y = 2}, diff --git a/lib/event.lua b/lib/event.lua index 97676ab8..6e47db2e 100755 --- a/lib/event.lua +++ b/lib/event.lua @@ -17,7 +17,7 @@ local event = { [56] = true }, onError = function(errorMessage) - + require("ECSAPI").error("CYKA: " .. tostring(errorMessage)) end } diff --git a/lib/image.lua b/lib/image.lua index 6facd282..18805491 100755 --- a/lib/image.lua +++ b/lib/image.lua @@ -1,1284 +1,72 @@ ----------------------------------------- OpenComputers Image Format (OCIF) ----------------------------------------------------------- +-------------------------------------------------- Libraries -------------------------------------------------- ---[[ - - Автор: Pornogion - VK: https://vk.com/id88323331 - Соавтор: IT - VK: https://vk.com/id7799889 - - Основные функции: - - image.load(string путь): table изображение - Загружает существующую картинку в формате .pic и возвращает ее - в качестве массива (таблицы). - - image.draw(int x, int y, table изображение) - Рисует на экране загруженную ранее картинку по указанным координатам. - - image.save(string путь, table изображение [, int метод кодирования]) - Сохраняет указанную картинку по указанному пути в формате .pic, - по умолчанию используя метод кодирования 3. Рекомендуется - использовать именно его. - - Функции для работы с изображением: - - image.transform(table картинка, int масштаб по ширине, int масштаб по высоте): table картинка - Изменяет размер картинки по методу интерполяции по соседним пикселям. - - image.expand(table картинка, string направление, int количество пикселей[, int цвет фона, int цвет текста, int прозрачность, char символ]): table картинка - Расширяет указанную картинку в указанном направлении (fromRight, fromLeft, fromTop, fromBottom), - создавая при этом пустые белые пиксели. Если указаны опциональные аргументы, то вместо пустых - пикселей могут быть вполне конкретные значения. - - image.crop(table картинка, string направление, int количество пикселей): table картинка - Обрезает указанную картинку в указанном направлении (fromRight, fromLeft, fromTop, fromBottom), - удаляя лишние пиксели. - - image.rotate(table картинка, int угол): table картинка - Поворачивает указанную картинку на указанный угол. Угол может иметь - значение 90, 180 и 270 градусов. - - image.flipVertical(table картинка): table картинка - Отражает указанную картинку по вертикали. - - image.flipHorizontal(table картинка): table картинка - Отражает указанную картинку по горизонтали. - - Функции для работы с цветом: - - image.hueSaturationBrightness(table картинка, int тон, int насыщенность, int яркость): table картинка - Корректирует цветовой тон, насыщенность и яркость указанной картинки. - Значения аргументов могут быть отрицательными для уменьшения параметра - и положительными для его увеличения. Если значение, к примеру, насыщенности - менять не требуется, просто указывайте 0. - - Для удобства вы можете использовать следующие сокращения: - image.hue(table картинка, int тон): table картинка - image.saturation(table картинка, int насыщенность): table картинка - image.brightness(table картинка, int яркость): table картинка - image.blackAndWhite(table картинка): table картинка - - image.colorBalance(table картинка, int красный, int зеленый, int синий): table картинка - Корректирует цветовые каналы изображения указанной картинки. Аргументы цветовых - каналов могут принимать как отрицательные значения для уменьшения интенсивности канала, - так и положительные для увеличения. - - image.invert(table картинка): table картинка - Инвертирует цвета в указанной картинке. - - image.photoFilter(table картинка, int цвет, int прозрачность): table картинка - Накладывает на указанное изображение фотофильтр с указанной прозрачностью. - Прозрачность может быть от 0 до 255. - - image.replaceColor(table картинка, int заменяемыйЦвет, int цветДляЗамены): table картинка - Заменяет в указанном изображении один конкретный цвет на другой. -]] - ---------------------------------------- Подгрузка библиотек -------------------------------------------------------------- - -local component = require("component") -local unicode = require("unicode") -local fs = require("filesystem") local colorlib = require("colorlib") -local bit32 = require("bit32") +local unicode = require("unicode") +local gpu = require("component").gpu + +-------------------------------------------------- Constants -------------------------------------------------- local image = {} +image.formatModules = {} --------------------------------------------- Переменные ------------------------------------------------------------------- +-------------------------------------------------- Low-level methods -------------------------------------------------- ---Константы программы -local constants = { - OCIFSignature = "OCIF", - OCIF2Elements = { - alphaStart = "A", - symbolStart = "S", - backgroundStart = "B", - foregroundStart = "F", - }, - elementCount = 4, - byteSize = 8, - nullChar = 0, - rawImageLoadStep = 19, - compressedFileFormat = ".pic", - pngFileFormat = ".png", -} - ----------------------------------------- Локальные функции ------------------------------------------------------------------- - ---Формула конвертации индекса массива изображения в абсолютные координаты пикселя изображения -local function convertIndexToCoords(index, width) - --Приводим индекс к корректному виду (1 = 1, 4 = 2, 7 = 3, 10 = 4, 13 = 5, ...) - index = (index + constants.elementCount - 1) / constants.elementCount - --Получаем остаток от деления индекса на ширину изображения - local ostatok = index % width - --Если остаток равен 0, то х равен ширине изображения, а если нет, то х равен остатку - local x = (ostatok == 0) and width or ostatok - --А теперь как два пальца получаем координату по Y - local y = math.ceil(index / width) - --Очищаем остаток из оперативки - ostatok = nil - --Возвращаем координаты - return x, y +local function compressionYield(iteration) + if iteration % 603 == 0 then os.sleep(0) end end ---Формула конвертации абсолютных координат пикселя изображения в индекс для массива изображения -local function convertCoordsToIndex(x, y, width) - return (width * (y - 1) + x) * constants.elementCount - constants.elementCount + 1 +function image.getImageCoordinatesByIndex(index, width) + local integer, fractional = math.modf((index - 2) / (width * 4)) + return math.ceil(fractional * width), integer + 1 end ---Костыльное получение размера массива, ибо автор луа не позволяет ---подсчитывать ненумерические индексы через #massiv ---мда, мда ---... ---мда -local function getArraySize(array) - local size = 0 - for key in pairs(array) do - size = size + 1 - end - return size +function image.getImageIndexByCoordinates(x, y, width) + return (width * 4) * (y - 1) + x * 4 - 1 end ---Получить количество байт, которое можно извлечь из указанного числа -local function getCountOfBytes(number) - if number == 0 or number == 1 then return 1 end - return math.ceil(math.log(number, 256)) -end +function image.group(picture, compressColors) + local groupedPicture, x, y, iPlus2, iPlus3, background, foreground = {}, 1, 1 ---Распидорасить число на составляющие байты -local function extractBytesFromNumber(number, countOfBytesToExtract) - local bytes = {} - local byteCutter = 0xff - for i = 1, countOfBytesToExtract do - table.insert(bytes, 1, bit32.rshift(bit32.band(number, byteCutter), (i-1)*8)) - byteCutter = bit32.lshift(byteCutter, 8) - end - return table.unpack(bytes) -end + for i = 3, #picture, 4 do + iPlus2, iPlus3 = i + 2, i + 3 ---Склеить байты и создать из них число -local function mergeBytesToNumber(...) - local bytes = {...} - local finalNumber = bytes[1] - for i = 2, #bytes do - finalNumber = bit32.bor(bit32.lshift(finalNumber, 8), bytes[i]) - end - return finalNumber -end - --- Сконвертировать все переданные байты в строку -local function convertBytesToString(...) - local bytes = {...} - for i = 1, #bytes do - bytes[i] = string.char(bytes[i]) - end - return table.concat(bytes) -end - ---Выделить бит-терминатор в первом байте UTF-8 символа: 1100 0010 --> 0010 0000 -local function selectTerminateBit_l() - local prevByte = nil - local prevTerminateBit = nil - - return function( byte ) - local x, terminateBit = nil - if ( prevByte == byte ) then - return prevTerminateBit - end - - x = bit32.band( bit32.bnot(byte), 0x000000FF ) - x = bit32.bor( x, bit32.rshift(x, 1) ) - x = bit32.bor( x, bit32.rshift(x, 2) ) - x = bit32.bor( x, bit32.rshift(x, 4) ) - x = bit32.bor( x, bit32.rshift(x, 8) ) - x = bit32.bor( x, bit32.rshift(x, 16) ) - - terminateBit = x - bit32.rshift(x, 1) - - prevByte = byte - prevTerminateBit = terminateBit - - return terminateBit - end -end -local selectTerminateBit = selectTerminateBit_l() - ---Прочитать n байтов из файла, возвращает прочитанные байты как число, если не удалось прочитать, то возвращает 0 -local function readBytes(file, count) - local readedBytes = file:read(count) - return mergeBytesToNumber(string.byte(readedBytes, 1, count)) -end - ---Подготавливает цвета и символ для записи в файл сжатого формата -local function encodePixel(background, foreground, alpha, char) - --Расхерачиваем жирные цвета в компактные цвета - local ascii_background1, ascii_background2, ascii_background3 = colorlib.HEXtoRGB(background) - local ascii_foreground1, ascii_foreground2, ascii_foreground3 = colorlib.HEXtoRGB(foreground) - --Расхерачиваем жирный код юникод-символа в несколько миленьких ascii-кодов - local ascii_char1, ascii_char2, ascii_char3, ascii_char4, ascii_char5, ascii_char6 = string.byte( char, 1, 6 ) - ascii_char1 = ascii_char1 or constants.nullChar - --Возвращаем все расхераченное - return ascii_background1, ascii_background2, ascii_background3, ascii_foreground1, ascii_foreground2, ascii_foreground3, alpha, ascii_char1, ascii_char2, ascii_char3, ascii_char4, ascii_char5, ascii_char6 -end - ---Декодирование UTF-8 символа -local function decodeChar(file) - local first_byte = readBytes(file, 1) - local charcode_array = {first_byte} - local len = 1 - - local middle = selectTerminateBit(first_byte) - if ( middle == 32 ) then - len = 2 - elseif ( middle == 16 ) then - len = 3 - elseif ( middle == 8 ) then - len = 4 - elseif ( middle == 4 ) then - len = 5 - elseif ( middle == 2 ) then - len = 6 - end - - for i = 1, len-1 do - table.insert( charcode_array, readBytes(file, 1) ) - end - - return string.char( table.unpack( charcode_array ) ) -end - ---Правильное конвертирование HEX-переменной в строковую -local function HEXtoSTRING(color, bitCount, withNull) - local stro4ka = string.format("%X",color) - local sStro4ka = unicode.len(stro4ka) - - if sStro4ka < bitCount then - stro4ka = string.rep("0", bitCount - sStro4ka) .. stro4ka - end - - sStro4ka = nil - - if withNull then return "0x"..stro4ka else return stro4ka end -end - ---Получение формата файла -local function getFileFormat(path) - local name = fs.name(path) - local starting, ending = string.find(name, "(.)%.[%d%w]*$") - if starting == nil then - return nil - else - return unicode.sub(name, starting + 1, -1) - end - name, starting, ending = nil, nil, nil -end - ---Прочесть сигнатуру файла и сравнить ее с константой -local function readSignature(file) - local readedSignature = file:read(4) - if readedSignature ~= constants.OCIFSignature then - file:close() - error("Can't load file: wrong OCIF format signature (\""..readedSignature .. "\" ~= \"" ..constants.OCIFSignature .. "\")") - end -end - ---Записать сигнатуру в файл -local function writeSignature(file) - file:write(constants.OCIFSignature) -end - ---Сжать все цвета в изображении в 8-битную палитру -local function convertImageColorsTo8Bit(picture) - for i = 1, #picture, 4 do - picture[i] = colorlib.convert24BitTo8Bit(picture[i]) - picture[i + 1] = colorlib.convert24BitTo8Bit(picture[i + 1]) - if i % 505 == 0 then os.sleep(0) end - end - return picture -end - ---Расжать все цвета в изображении в 24-битную палитру -local function convertImageColorsTo24Bit(picture) - for i = 1, #picture, 4 do - picture[i] = colorlib.convert8BitTo24Bit(picture[i]) - picture[i + 1] = colorlib.convert8BitTo24Bit(picture[i + 1]) - if i % 505 == 0 then os.sleep(0) end - end - return picture -end - ------------------------------- Все, что касается формата OCIF1 ------------------------------------------------------------ - --- Запись в файл сжатого OCIF-формата изображения -local function saveOCIF1(file, picture) - local encodedPixel - file:write( string.char( picture.width ) ) - file:write( string.char( picture.height ) ) - - for i = 1, picture.width * picture.height * constants.elementCount, constants.elementCount do - encodedPixel = - { - encodePixel(picture[i], picture[i + 1], picture[i + 2], picture[i + 3]) - } - for j = 1, #encodedPixel do - file:write( string.char( encodedPixel[j] ) ) - end - end - - file:close() -end - ---Чтение из файла сжатого OCIF-формата изображения, возвращает массив типа 2 (подробнее о типах см. конец файла) -local function loadOCIF1(file) - local picture = {} - - --Читаем ширину и высоту файла - picture.width = readBytes(file, 1) - picture.height = readBytes(file, 1) - - for i = 1, picture.width * picture.height do - --Читаем бекграунд - table.insert(picture, readBytes(file, 3)) - --Читаем форграунд - table.insert(picture, readBytes(file, 3)) - --Читаем альфу - table.insert(picture, readBytes(file, 1)) - --Читаем символ - table.insert(picture, decodeChar( file )) - end - - file:close() - - return picture -end - ------------------------------------------- Все, что касается формата OCIF2 ------------------------------------------------ - -local function saveOCIF2(file, picture, compressColors) - --Записываем ширину изображения - file:write(string.char(picture.width)) - file:write(string.char(picture.height)) - - --Группируем картинку - local grouppedPucture = image.convertToGroupedImage(picture) - - --Перебираем все альфы - for alpha in pairs(grouppedPucture) do - --Получаем размер массива, содержащего символы - local arraySize = getArraySize(grouppedPucture[alpha]) - local countOfBytesForArraySize = getCountOfBytes(arraySize) - --Записываем в файл символ АльфаСтарта, размер массива альфы и само значение альфы - file:write( - constants.OCIF2Elements.alphaStart, - string.char(countOfBytesForArraySize), - convertBytesToString(extractBytesFromNumber(arraySize, countOfBytesForArraySize)), - string.char(alpha) - ) - - for symbol in pairs(grouppedPucture[alpha]) do - --Записываем заголовок - file:write(constants.OCIF2Elements.symbolStart) - --Записываем количество всех цветов текста и символ - if compressColors then - file:write( - string.char(getArraySize(grouppedPucture[alpha][symbol])), - convertBytesToString(string.byte(symbol, 1, 6)) - ) - else - file:write( - convertBytesToString(extractBytesFromNumber(getArraySize(grouppedPucture[alpha][symbol]), 3)), - convertBytesToString(string.byte(symbol, 1, 6)) - ) - end - - for foreground in pairs(grouppedPucture[alpha][symbol]) do - --Записываем заголовок - file:write(constants.OCIF2Elements.foregroundStart) - --Записываем количество цветов фона и цвет текста - if compressColors then - file:write( - string.char(getArraySize(grouppedPucture[alpha][symbol][foreground])), - string.char(foreground) - ) - else - file:write( - convertBytesToString(extractBytesFromNumber(getArraySize(grouppedPucture[alpha][symbol][foreground]), 3)), - convertBytesToString(extractBytesFromNumber(foreground, 3)) - ) - end - - for background in pairs(grouppedPucture[alpha][symbol][foreground]) do - --Записываем заголовок и размер массива координат - file:write( - constants.OCIF2Elements.backgroundStart, - convertBytesToString(extractBytesFromNumber(getArraySize(grouppedPucture[alpha][symbol][foreground][background]), 2)) - ) - --Записываем цвет фона - if compressColors then - file:write(string.char(background)) - else - file:write(convertBytesToString(extractBytesFromNumber(background, 3))) - end - - --Перебираем координаты - for y in pairs(grouppedPucture[alpha][symbol][foreground][background]) do - --Записываем заголовок координат, размер массива y и само значение y - file:write( - "Y", - string.char(getArraySize(grouppedPucture[alpha][symbol][foreground][background][y])), - string.char(y) - ) - --Записываем ИКСЫЫЫ - --Ы - for i = 1, #grouppedPucture[alpha][symbol][foreground][background][y] do - file:write(string.char(grouppedPucture[alpha][symbol][foreground][background][y][i])) - end - end - end - end - end - end - - file:close() -end - -local function loadOCIF2(file, decompressColors, useOCIF4) - local picture = {} - - --Читаем размер изображения - local readedWidth = string.byte(file:read(1)) - local readedHeight = string.byte(file:read(1)) - picture.width = readedWidth - picture.height = readedHeight - - local header, alpha, symbol, foreground, background, y, alphaSize, symbolSize, foregroundSize, backgroundSize, ySize = "" - while true do - header = file:read(1) - if not header then break end - -- print("----------------------") - -- print("Заголовок: " .. header) - - if header == "A" then - local countOfBytesForArraySize = string.byte(file:read(1)) - alphaSize = string.byte(file:read(countOfBytesForArraySize)) - alpha = string.byte(file:read(1)) - -- print("Количество байт под размер массива символов: " .. countOfBytesForArraySize) - -- print("Размер массива символов: " .. alphaSize) - -- print("Альфа: " .. alpha) - - elseif header == "S" then - if decompressColors then - symbolSize = string.byte(file:read(1)) - else - symbolSize = mergeBytesToNumber(string.byte(file:read(3), 1, 3)) - end - symbol = decodeChar(file) - -- print("Размер массива цвета текста: " .. symbolSize) - -- print("Символ: \"" .. symbol .. "\"") - - elseif header == "F" then - if decompressColors then - foregroundSize = string.byte(file:read(1)) - foreground = colorlib.convert8BitTo24Bit(string.byte(file:read(1))) - else - foregroundSize = mergeBytesToNumber(string.byte(file:read(3), 1, 3)) - foreground = mergeBytesToNumber(string.byte(file:read(3), 1, 3)) - end - -- print("Размер массива цвета фона: " .. foregroundSize) - -- print("Цвет текста: " .. foreground) - - elseif header == "B" then - backgroundSize = mergeBytesToNumber(string.byte(file:read(2), 1, 2)) - if decompressColors then - background = colorlib.convert8BitTo24Bit(string.byte(file:read(1))) - else - background = mergeBytesToNumber(string.byte(file:read(3), 1, 3)) - end - -- print("Размер массива координат: " .. backgroundSize) - -- print("Цвет фона: " .. background) - - --Поддержка загрузки формата OCIF3 - if not useOCIF4 then - --Читаем координаты - for i = 1, backgroundSize, 2 do - local x = string.byte(file:read(1)) - local y = string.byte(file:read(1)) - local index = convertCoordsToIndex(x, y, readedWidth) - -- print("Координата: " .. x .. "x" .. y .. ", индекс: "..index) - - picture[index] = background - picture[index + 1] = foreground - picture[index + 2] = alpha - picture[index + 3] = symbol - end - end - - --Новый формат OCIF4 - elseif header == "Y" and useOCIF4 then - ySize = string.byte(file:read(1)) - y = string.byte(file:read(1)) - -- print("Размер массива Y: " .. ySize) - -- print("Текущий Y: " .. y) - - for i = 1, ySize do - local x = string.byte(file:read(1)) - local index = convertCoordsToIndex(x, y, readedWidth) - -- print("Координата: " .. x .. "x" .. y .. ", индекс: "..index) - - picture[index] = background - picture[index + 1] = foreground - picture[index + 2] = alpha - picture[index + 3] = symbol - end + if compressColors then + background, foreground = colorlib.convert24BitTo8Bit(picture[i]), colorlib.convert24BitTo8Bit(picture[i + 1]) + compressionYield(i) else - error("Error while reading OCIF format: unknown Header type (" .. header .. ")") + background, foreground = picture[i], picture[i + 1] end - end + groupedPicture[picture[iPlus2]] = groupedPicture[picture[iPlus2]] or {} + groupedPicture[picture[iPlus2]][picture[iPlus3]] = groupedPicture[picture[iPlus2]][picture[iPlus3]] or {} + groupedPicture[picture[iPlus2]][picture[iPlus3]][background] = groupedPicture[picture[iPlus2]][picture[iPlus3]][background] or {} + groupedPicture[picture[iPlus2]][picture[iPlus3]][background][foreground] = groupedPicture[picture[iPlus2]][picture[iPlus3]][background][foreground] or {} + groupedPicture[picture[iPlus2]][picture[iPlus3]][background][foreground][y] = groupedPicture[picture[iPlus2]][picture[iPlus3]][background][foreground][y] or {} - file:close() + table.insert(groupedPicture[picture[iPlus2]][picture[iPlus3]][background][foreground][y], x) - return picture -end - ------------------------------- Все, что касается формата RAW ------------------------------------------------------------ - ---Сохранение в файл сырого формата изображения типа 2 (подробнее о типах см. конец файла) -local function saveRaw(file, picture) - - file:write("\n") - - local xPos, yPos = 1, 1 - for i = 1, picture.width * picture.height * constants.elementCount, constants.elementCount do - file:write( HEXtoSTRING(picture[i], 6), " ", HEXtoSTRING(picture[i + 1], 6), " ", HEXtoSTRING(picture[i + 2], 2), " ", picture[i + 3], " ") - - xPos = xPos + 1 - if xPos > picture.width then - xPos = 1 - yPos = yPos + 1 - file:write("\n") + x = x + 1 + if x > picture[1] then + x, y = 1, y + 1 end end - file:close() + return groupedPicture end ---Загрузка из файла сырого формата изображения типа 2 (подробнее о типах см. конец файла) -local function loadRaw(file) - --Читаем один байт "прост так" - file:read(1) - - local picture = {} - local background, foreground, alpha, symbol, sLine - local lineCounter = 0 - - for line in file:lines() do - sLine = unicode.len(line) - for i = 1, sLine, constants.rawImageLoadStep do - background = "0x" .. unicode.sub(line, i, i + 5) - foreground = "0x" .. unicode.sub(line, i + 7, i + 12) - alpha = "0x" .. unicode.sub(line, i + 14, i + 15) - symbol = unicode.sub(line, i + 17, i + 17) - - table.insert(picture, tonumber(background)) - table.insert(picture, tonumber(foreground)) - table.insert(picture, tonumber(alpha)) - table.insert(picture, symbol) - end - lineCounter = lineCounter + 1 - end - - picture.width = sLine / constants.rawImageLoadStep - picture.height = lineCounter - - file:close() - return picture -end - ------------------------------------ Все, что касается реального PNG-формата ------------------------------------------------------------ - -function image.loadPng(path) - if not _G.libPNGImage then _G.libPNGImage = require("libPNGImage") end - - local success, pngImageOrErrorMessage = pcall(libPNGImage.newFromFile, path) - - if not success then - io.stderr:write(" * PNGView: PNG Loading Error *\n") - io.stderr:write("While attempting to load '" .. path .. "' as PNG, libPNGImage erred:\n") - io.stderr:write(pngImageOrErrorMessage) - return - end - - local picture = {} - picture.width, picture.height = pngImageOrErrorMessage:getSize() - - local r, g, b, a, hex - for j = 0, picture.height - 1 do - for i = 0, picture.width - 1 do - r, g, b, a = pngImageOrErrorMessage:getPixel(i, j) - - if r and g and b and a and a > 0 then - hex = colorlib.RGBtoHEX(r, g, b) - table.insert(picture, hex) - table.insert(picture, 0x000000) - table.insert(picture, 0x00) - table.insert(picture, " ") - end - - end - end - - return picture -end - ------------------------------------ Вспомогательные функции программы ------------------------------------------------------------ - ---Оптимизировать и сгруппировать по цветам картинку типа 2 (подробнее о типах см. конец файла) -function image.convertToGroupedImage(picture) - --Создаем массив оптимизированной картинки - local optimizedPicture = {} - --Задаем константы - local xPos, yPos, background, foreground, alpha, symbol = 1, 1, nil, nil, nil, nil - --Перебираем все элементы массива - for i = 1, picture.width * picture.height * constants.elementCount, constants.elementCount do - --Получаем символ из неоптимизированного массива - background, foreground, alpha, symbol = picture[i], picture[i + 1], picture[i + 2], picture[i + 3] - --Группируем картинку по цветам - optimizedPicture[alpha] = optimizedPicture[alpha] or {} - optimizedPicture[alpha][symbol] = optimizedPicture[alpha][symbol] or {} - optimizedPicture[alpha][symbol][foreground] = optimizedPicture[alpha][symbol][foreground] or {} - optimizedPicture[alpha][symbol][foreground][background] = optimizedPicture[alpha][symbol][foreground][background] or {} - optimizedPicture[alpha][symbol][foreground][background][yPos] = optimizedPicture[alpha][symbol][foreground][background][yPos] or {} - - table.insert(optimizedPicture[alpha][symbol][foreground][background][yPos], xPos) - --Если xPos достигает width изображения, то сбросить на 1, иначе xPos++ - xPos = (xPos == picture.width) and 1 or xPos + 1 - --Если xPos равняется 1, то yPos++, а если нет, то похуй - yPos = (xPos == 1) and yPos + 1 or yPos - end - --Возвращаем оптимизированный массив - return optimizedPicture -end - ---Нарисовать по указанным координатам картинку указанной ширины и высоты для теста -function image.create(width, height, background, foreground, alpha, symbol, random) - background, foreground, alpha, symbol = background or 0x0, foreground or 0x0, alpha or 0x0, symbol or " " - local picture, symbolArray = {width = width, height = height}, {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "А", "Б", "В", "Г", "Д", "Е", "Ж", "З", "И", "Й", "К", "Л", "И", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я"} - for i = 1, picture.width * picture.height do - if random then - background = math.random(0x000000, 0xffffff) - foreground = math.random(0x000000, 0xffffff) - symbol = symbolArray[math.random(1, #symbolArray)] - end - table.insert(picture, background) - table.insert(picture, foreground) - table.insert(picture, alpha) - table.insert(picture, symbol) - end - return picture -end - --- Функция оптимизации цвета текста и символов у картинки, уменьшает число GPU-операций при отрисовке из буфера --- Вызывается только при сохранении файла, так что на быстродействии не сказывается, --- а в целом штука очень и очень полезная. Фиксит криворукость художников. -function image.optimize(picture) - local i1, i2, i3 = 0, 0, 0 - for i = 1, #picture, constants.elementCount do - --Уменьшаем нагрузку на ЦОПЕ - i1, i2, i3 = i + 1, i + 2, i + 3 - --Если цвет фона равен цвету текста, и используется псевдографические полупиксели - if picture[i] == picture[i1] and (picture[i3] == "▄" or picture[i3] == "▀") then - picture[i3] = " " - end - --Если символ равен пролбелу, т.е. цвет текста не учитывается - if picture[i3] == " " then - picture[i1] = 0x000000 - end - end - - return picture -end - ---Получить пиксель из изображения по указанным координатам -function image.get(picture, x, y) - if x >= 1 and y >= 1 and x <= picture.width and y <= picture.height then - local index = convertCoordsToIndex(x, y, picture.width) - return picture[index], picture[index + 1], picture[index + 2], picture[index + 3] - else - return nil - end -end - ---Установить пиксель в изображении по указанным координатам -function image.set(picture, x, y, background, foreground, alpha, symbol, debug) - if x >= 1 and y >= 1 and x <= picture.width and y <= picture.height then - local index = convertCoordsToIndex(x, y, picture.width) - picture[index] = background or 0xFF00FF - picture[index + 1] = foreground or 0xFF00FF - picture[index + 2] = alpha or 0x00 - picture[index + 3] = symbol or " " - return picture - else - error("Can't set pixel because it's located out of image coordinates: x = " .. x .. ", y = " .. y) - end -end - ------------------------------------------- Функция снятия скриншота с экрана ------------------------------------------------ - ---Сделать скриншот экрана и сохранить его по указанному пути -function image.screenshot(path) - local picture = {} - local foreground, background, symbol - picture.width, picture.height = component.gpu.getResolution() - - for j = 1, picture.height do - for i = 1, picture.width do - symbol, foreground, background = component.gpu.get(i, j) - table.insert(picture, background) - table.insert(picture, foreground) - table.insert(picture, 0x00) - table.insert(picture, symbol) - end - end - - image.save(path, picture) -end - ------------------------------------------- Методы трансформирования изображения ------------------------------------------------ - ---Вставка ряда пикселей -function image.insertRow(picture, y, rowArray) - local index = convertCoordsToIndex(1, y, picture.width) - for i = 1, #rowArray, 4 do - table.insert(picture, index, rowArray[i + 3]) - table.insert(picture, index, rowArray[i + 2]) - table.insert(picture, index, rowArray[i + 1]) - table.insert(picture, index, rowArray[i]) - index = index + 4 - end - picture.height = picture.height + 1 - return picture -end - -function image.insertColumn(picture, x, columnArray) - local index = convertCoordsToIndex(x, 1, picture.width) - for i = 1, #columnArray, 4 do - table.insert(picture, index, columnArray[i + 3]) - table.insert(picture, index, columnArray[i + 2]) - table.insert(picture, index, columnArray[i + 1]) - table.insert(picture, index, columnArray[i]) - index = index + picture.width * 4 + 4 - end - picture.width = picture.width + 1 - return picture -end - ---Удаление ряда пикселей -function image.removeRow(picture, y) - local index = convertCoordsToIndex(1, y, picture.width) - for i = 1, picture.width * 4 do table.remove(picture, index) end - picture.height = picture.height - 1 - return picture -end - ---Удаление колонки пикселей -function image.removeColumn(picture, x) - local index = convertCoordsToIndex(x, 1, picture.width) - for i = 1, picture.height do - for j = 1, 4 do table.remove(picture, index) end - index = index + (picture.width) * 4 - 4 - end - picture.width = picture.width - 1 - return picture -end - ---Получение ряда пикселей -function image.getRow(picture, y) - local row, background, foreground, alpha, symbol = {width = picture.width, height = 1} - for x = 1, picture.width do - background, foreground, alpha, symbol = image.get(picture, x, y) - table.insert(row, background) - table.insert(row, foreground) - table.insert(row, alpha) - table.insert(row, symbol) - end - return row -end - ---Получение колонки пикселей -function image.getColumn(picture, x) - local column, background, foreground, alpha, symbol = {width = 1, height = picture.height} - for y = 1, picture.height do - background, foreground, alpha, symbol = image.get(picture, x, y) - table.insert(column, background) - table.insert(column, foreground) - table.insert(column, alpha) - table.insert(column, symbol) - end - return column -end - ---Создание копии массива изображения -function image.duplicate(picture) - local newPicture = {width = picture.width, height = picture.height} - for i = 1, #picture do newPicture[i] = picture[i] end - return newPicture -end - ---Аналог свободного трансформирования из фотошопа -function image.transform(picture, newWidth, newHeight) - local newPicture = image.duplicate(picture) - local widthScale, heightScale = newWidth / picture.width, newHeight / picture.height - local deltaWidth, deltaHeight = math.abs(newWidth - picture.width), math.abs(newHeight - picture.height) - local widthIteration, heightIteration = widthScale > 1 and newWidth / deltaWidth or picture.width / deltaWidth, heightScale > 1 and newHeight / deltaHeight or picture.height / deltaHeight - - -- ecs.error(widthIteration, heightIteration, deltaWidth, picture.width, newWidth) - - --Сжимаем шакалов по ширине - if widthScale > 1 then - local x = 1 - while x <= newPicture.width do - if math.floor(x % widthIteration) == 0 then newPicture = image.insertColumn(newPicture, x, image.getColumn(newPicture, x - 1)) end - x = x + 1 - end - elseif widthScale < 1 then - local x = 1 - while x <= newPicture.width do - if math.floor(x % widthIteration) == 0 then newPicture = image.removeColumn(newPicture, x) end - x = x + 1 - end - end - - --И по высоте - if heightScale > 1 then - local y = 1 - while y <= newPicture.height do - if math.floor(y % heightIteration) == 0 then newPicture = image.insertRow(newPicture, y, image.getRow(newPicture, y - 1)) end - y = y + 1 - end - elseif heightScale < 1 then - local y = 1 - while y <= newPicture.height do - if math.floor(y % heightIteration) == 0 then newPicture = image.removeRow(newPicture, y) end - y = y + 1 - end - end - - return newPicture -end - -function image.expand(picture, mode, countOfPixels, background, foreground, alpha, symbol) - local column = {}; for i = 1, picture.height do table.insert(column, background or 0xFFFFFF); table.insert(column, foreground or 0xFFFFFF); table.insert(column, alpha or 0x00); table.insert(column, symbol or " ") end - local row = {}; for i = 1, picture.height do table.insert(row, background or 0xFFFFFF); table.insert(row, foreground or 0xFFFFFF); table.insert(row, alpha or 0x00); table.insert(row, symbol or " ") end - - if mode == "fromRight" then - for i = 1, countOfPixels do picture = image.insertColumn(picture, picture.width + 1, column) end - elseif mode == "fromLeft" then - for i = 1, countOfPixels do picture = image.insertColumn(picture, 1, column) end - elseif mode == "fromTop" then - for i = 1, countOfPixels do picture = image.insertRow(picture, 1, row) end - elseif mode == "fromBottom" then - for i = 1, countOfPixels do picture = image.insertRow(picture, picture.height + 1, row) end - else - error("Wrong image expanding mode: only 'fromRight', 'fromLeft', 'fromTop' and 'fromBottom' are supported.") - end - - return picture -end - -function image.crop(picture, mode, countOfPixels) - if mode == "fromRight" then - for i = 1, countOfPixels do picture = image.removeColumn(picture, picture.width) end - elseif mode == "fromLeft" then - for i = 1, countOfPixels do picture = image.removeColumn(picture, 1) end - elseif mode == "fromTop" then - for i = 1, countOfPixels do picture = image.removeRow(picture, 1) end - elseif mode == "fromBottom" then - for i = 1, countOfPixels do picture = image.removeRow(picture, picture.height) end - else - error("Wrong image cropping mode: only 'fromRight', 'fromLeft', 'fromTop' and 'fromBottom' are supported.") - end - - return picture -end - -function image.flipVertical(picture) - local newPicture = {}; newPicture.width = picture.width; newPicture.height = picture.height - for j = picture.height, 1, -1 do - for i = 1, picture.width do - local index = convertCoordsToIndex(i, j, picture.width) - table.insert(newPicture, picture[index]); table.insert(newPicture, picture[index + 1]); table.insert(newPicture, picture[index + 2]); table.insert(newPicture, picture[index + 3]) - picture[index], picture[index + 1], picture[index + 2], picture[index + 3] = nil, nil, nil, nil - end - end - return newPicture -end - -function image.flipHorizontal(picture) - local newPicture = {}; newPicture.width = picture.width; newPicture.height = picture.height - for j = 1, picture.height do - for i = picture.width, 1, -1 do - local index = convertCoordsToIndex(i, j, picture.width) - table.insert(newPicture, picture[index]); table.insert(newPicture, picture[index + 1]); table.insert(newPicture, picture[index + 2]); table.insert(newPicture, picture[index + 3]) - picture[index], picture[index + 1], picture[index + 2], picture[index + 3] = nil, nil, nil, nil - end - end - return newPicture -end - -function image.rotate(picture, angle) - local function rotateBy90(picture) - local newPicture = {}; newPicture.width = picture.height; newPicture.height = picture.width - for i = 1, picture.width do - for j = picture.height, 1, -1 do - local index = convertCoordsToIndex(i, j, picture.width) - table.insert(newPicture, picture[index]); table.insert(newPicture, picture[index + 1]); table.insert(newPicture, picture[index + 2]); table.insert(newPicture, picture[index + 3]) - picture[index], picture[index + 1], picture[index + 2], picture[index + 3] = nil, nil, nil, nil - end - end - return newPicture - end - - local function rotateBy180(picture) - local newPicture = {}; newPicture.width = picture.width; newPicture.height = picture.height - for j = picture.height, 1, -1 do - for i = picture.width, 1, -1 do - local index = convertCoordsToIndex(i, j, picture.width) - table.insert(newPicture, picture[index]); table.insert(newPicture, picture[index + 1]); table.insert(newPicture, picture[index + 2]); table.insert(newPicture, picture[index + 3]) - picture[index], picture[index + 1], picture[index + 2], picture[index + 3] = nil, nil, nil, nil - end - end - return newPicture - end - - local function rotateBy270(picture) - local newPicture = {}; newPicture.width = picture.height; newPicture.height = picture.width - for i = picture.width, 1, -1 do - for j = 1, picture.height do - local index = convertCoordsToIndex(i, j, picture.width) - table.insert(newPicture, picture[index]); table.insert(newPicture, picture[index + 1]); table.insert(newPicture, picture[index + 2]); table.insert(newPicture, picture[index + 3]) - picture[index], picture[index + 1], picture[index + 2], picture[index + 3] = nil, nil, nil, nil - end - end - return newPicture - end - - if angle == 90 then - return rotateBy90(picture) - elseif angle == 180 then - return rotateBy180(picture) - elseif angle == 270 then - return rotateBy270(picture) - else - error("Can't rotate image: angle must be 90, 180 or 270 degrees.") - end -end - ------------------------------------------- Функции для работы с цветом ----------------------------------------------- - -function image.hueSaturationBrightness(picture, hue, saturation, brightness) - local function calculateBrightnessChanges(color) - local h, s, b = colorlib.HEXtoHSB(color) - b = b + brightness; if b < 0 then b = 0 elseif b > 100 then b = 100 end - s = s + saturation; if s < 0 then s = 0 elseif s > 100 then s = 100 end - h = h + hue; if h < 0 then h = 0 elseif h > 360 then h = 360 end - return colorlib.HSBtoHEX(h, s, b) - end - - for i = 1, #picture, 4 do - picture[i] = calculateBrightnessChanges(picture[i]) - picture[i + 1] = calculateBrightnessChanges(picture[i + 1]) - end - - return picture -end - -function image.hue(picture, hue) - return image.hueSaturationBrightness(picture, hue, 0, 0) -end - -function image.saturation(picture, saturation) - return image.hueSaturationBrightness(picture, 0, saturation, 0) -end - -function image.brightness(picture, brightness) - return image.hueSaturationBrightness(picture, 0, 0, brightness) -end - -function image.blackAndWhite(picture) - return image.hueSaturationBrightness(picture, 0, -100, 0) -end - -function image.colorBalance(picture, r, g, b) - local function calculateRGBChanges(color) - local rr, gg, bb = colorlib.HEXtoRGB(color) - rr = rr + r; gg = gg + g; bb = bb + b - if rr < 0 then rr = 0 elseif rr > 255 then rr = 255 end - if gg < 0 then gg = 0 elseif gg > 255 then gg = 255 end - if bb < 0 then bb = 0 elseif bb > 255 then bb = 255 end - return colorlib.RGBtoHEX(rr, gg, bb) - end - - for i = 1, #picture, 4 do - picture[i] = calculateRGBChanges(picture[i]) - picture[i + 1] = calculateRGBChanges(picture[i + 1]) - end - - return picture -end - -function image.invert(picture) - for i = 1, #picture, 4 do - picture[i] = 0xffffff - picture[i] - picture[i + 1] = 0xffffff - picture[i + 1] - end - return picture -end - -function image.photoFilter(picture, color, transparency) - if transparency < 0 then transparency = 0 elseif transparency > 255 then transparency = 255 end - for i = 1, #picture, 4 do - picture[i] = colorlib.alphaBlend(picture[i], color, transparency / 255) - picture[i + 1] = colorlib.alphaBlend(picture[i + 1], color, transparency / 255) - end - return picture -end - -function image.replaceColor(picture, fromColor, toColor) - for i = 1, #picture, 4 do - if picture[i] == fromColor then picture[i] = toColor end - end - return picture -end - ---Функция размытия по Гауссу -function image.gaussianBlur(picture, radius, force) - --Функция для генерации матрицы размытия - local function createConvolutionMatrix(maximumValue, matrixSize) - local delta = maximumValue / matrixSize - local matrix = {} - for y = 1, matrixSize do - for x = 1, matrixSize do - local value = ((x - 1) * delta + (y - 1) * delta) / 2 - matrix[y] = matrix[y] or {} - matrix[y][x] = value - end - end - return matrix - end - - --Функция для распределения стартового цвета на указанный пиксель на основе указанного значения матрицы - local function spreadPixelToSpecifiedCoordinates(picture, xCoordinate, yCoordinate, matrixValue, startBackground, startForeground, startAlpha, startSymbol) - local matrixBackground, matrixForeground, matrixAlpha, matrixSymbol = image.get(picture, xCoordinate, yCoordinate) - - if matrixBackground and matrixForeground then - local newBackground = colorlib.alphaBlend(startBackground, matrixBackground, matrixValue / 0xFF) - --Пизданись оно все в жопу, ебанина - --Короч, смари. Если символ равен пробелу, то мы полюбэ не учитываем цвет текста, верно? - --Но в будущих итерациях это цвет будет учтен, поэтому возникали ссаные баги графические - --Поэтому даже для ебучего пробела мы присваиваем значение цвета текста, равному НОВОМУ цвету фона - --Т.е. вроде бы как они и равны, но потом охуенно все будет, угу - local newForeground = matrixSymbol == " " and newBackground or colorlib.alphaBlend(startForeground, matrixForeground, matrixValue / 0xFF) - - image.set(picture, xCoordinate, yCoordinate, newBackground, newForeground, 0x00, matrixSymbol) - end - end - - --Функция, распределяющая указанный пиксель по соседним пикселям на основе матрицы - local function spreadColorToOtherPixels(picture, xStart, yStart, matrix) - --Получаем стартовые данные о пикселе - local startBackground, startForeground, startAlpha, startSymbol = image.get(picture, xStart, yStart) - local xCoordinate, yCoordinate - --Перебираем матрицу - for yMatrix = 1, #matrix do - for xMatrix = 1, #matrix[yMatrix] do - --Игнорируем стартовый пиксель, на кой хер его размывать-то? - if not (xMatrix == 1 and yMatrix == 1) then - --Получаем координаты новых пикселей в изображении - --И в обратном направлении матрицы - xCoordinate, yCoordinate = xStart - xMatrix + 1, yStart - yMatrix + 1 - spreadPixelToSpecifiedCoordinates(picture, xCoordinate, yCoordinate, matrix[yMatrix][xMatrix], startBackground, startForeground, startAlpha, startSymbol) - --Для начала в правильную сторону матрицы - xCoordinate, yCoordinate = xStart + xMatrix - 1, yStart + yMatrix - 1 - spreadPixelToSpecifiedCoordinates(picture, xCoordinate, yCoordinate, matrix[yMatrix][xMatrix], startBackground, startForeground, startAlpha, startSymbol) - end - end - end - end - - --Генерируем матрицу - local matrix = createConvolutionMatrix(force or 0x55, radius) - --Распределяем все пиксели по изображению - for y = 1, picture.height do - for x = 1, picture.width do - spreadColorToOtherPixels(picture, x, y, matrix) - end - end - return picture -end - ------------------------------------------ Строковая обработка изображений ------------------------------------------------------------------- - ---Преобразовать изображение в строковую интерпретацию, которая может быть вставлена в код ---Удобно, если не хочется возиться с файловой системой -function image.toString(picture) - local stringedPicture = {} - picture = convertImageColorsTo8Bit(picture) - table.insert(stringedPicture, string.format("%02X", picture.width)) - table.insert(stringedPicture, string.format("%02X", picture.height)) - for i = 1, #picture, 4 do - table.insert(stringedPicture, string.format("%02X", picture[i])) - table.insert(stringedPicture, string.format("%02X", picture[i + 1])) - table.insert(stringedPicture, string.format("%02X", picture[i + 2])) - table.insert(stringedPicture, picture[i + 3]) - end - picture = convertImageColorsTo24Bit(picture) - return table.concat(stringedPicture) -end - ---Получить изображение из строковой интерпретации, созданной ранее -function image.fromString(stringedPicture) - local picture = {} - local subIndex = 1 - picture.width = tonumber("0x" .. unicode.sub(stringedPicture, subIndex, subIndex + 1)); subIndex = subIndex + 2 - picture.height = tonumber("0x" .. unicode.sub(stringedPicture, subIndex, subIndex + 1)); subIndex = subIndex + 2 - - for pixel = 1, picture.width * picture.height do - table.insert(picture, tonumber("0x" .. unicode.sub(stringedPicture, subIndex, subIndex + 1))); subIndex = subIndex + 2 - table.insert(picture, tonumber("0x" .. unicode.sub(stringedPicture, subIndex, subIndex + 1))); subIndex = subIndex + 2 - table.insert(picture, tonumber("0x" .. unicode.sub(stringedPicture, subIndex, subIndex + 1))); subIndex = subIndex + 2 - table.insert(picture, unicode.sub(stringedPicture, subIndex, subIndex)); subIndex = subIndex + 1 - end - picture = convertImageColorsTo24Bit(picture) - return picture -end - ------------------------------------------ Основные функции программы ------------------------------------------------------------------- - ---Сохранить изображение любого поддерживаемого формата -function image.save(path, picture, encodingMethod) - encodingMethod = encodingMethod or 4 - --Создать папку под файл, если ее нет - fs.makeDirectory(fs.path(path)) - --Получаем формат указанного файла - local fileFormat = getFileFormat(path) - - --Проверяем соответствие формата файла - if fileFormat == constants.compressedFileFormat then - --Оптимизируем картинку - picture = image.optimize(picture) - --Открываем файл - local file = io.open(path, "w") - --Записываем сигнатуру - writeSignature(file) - --Разбираемся с кодировкой - if encodingMethod == 0 or string.lower(encodingMethod) == "raw" then - file:write(string.char(encodingMethod)) - saveRaw(file, picture) - elseif encodingMethod == 1 or string.lower(encodingMethod) == "ocif1" then - file:write(string.char(encodingMethod)) - saveOCIF1(file, picture) - elseif encodingMethod == 2 or string.lower(encodingMethod) == "ocif2" then - file:write(string.char(encodingMethod)) - saveOCIF2(file, picture) - elseif encodingMethod == 3 or string.lower(encodingMethod) == "ocif3" then - error("Saving in encoding method 3 is deprecated and no longer supported. Use method 4 instead of it.") - elseif encodingMethod == 4 or string.lower(encodingMethod) == "ocif4" then - file:write(string.char(encodingMethod)) - picture = convertImageColorsTo8Bit(picture) - saveOCIF2(file, picture, true) - picture = convertImageColorsTo24Bit(picture) - elseif encodingMethod == 6 then - file:close() - file = io.open(path, "w") - file:write(image.toString(picture)) - file:close() - else - file:close() - error("Unsupported encoding method.\n") - end - else - file:close() - error("Unsupported file format.\n") - end -end - ---Загрузить изображение любого поддерживаемого формата -function image.load(path) - --Кинуть ошибку, если такого файла не существует - if not fs.exists(path) then error("File \""..path.."\" does not exists.\n") end - --Получаем формат указанного файла - local fileFormat = getFileFormat(path) - --Проверяем соответствие формата файла - if fileFormat == constants.compressedFileFormat then - local file = io.open(path, "rb") - --Читаем сигнатуру файла - readSignature(file) - --Читаем метод обработки изображения - local encodingMethod = string.byte(file:read(1)) - --Читаем файлы в зависимости от метода - --print("Загружаю файл типа " .. encodingMethod) - if encodingMethod == 0 then - return image.optimize(loadRaw(file)) - elseif encodingMethod == 1 then - return image.optimize(loadOCIF1(file)) - elseif encodingMethod == 2 then - return image.optimize(loadOCIF2(file)) - elseif encodingMethod == 3 then - return image.optimize(loadOCIF2(file, true)) - elseif encodingMethod == 4 then - return image.optimize(loadOCIF2(file, true, true)) - else - file:close() - error("Unsupported encoding method: " .. encodingMethod .. "\n") - end - --Поддержка ПНГ-формата - elseif fileFormat == constants.pngFileFormat then - return image.loadPng(path) - else - error("Unsupported file format: " .. fileFormat .. "\n") - end -end - ---Отрисовка изображения типа 3 (подробнее о типах см. конец файла) function image.draw(x, y, picture) - --Конвертируем в групповое изображение - picture = image.convertToGroupedImage(picture) - --Все как обычно - x, y = x - 1, y - 1 + local groupedPicture = image.group(picture) - local xPos, yPos, currentBackground - for alpha in pairs(picture) do - for symbol in pairs(picture[alpha]) do - for foreground in pairs(picture[alpha][symbol]) do - if component.gpu.getForeground ~= foreground then component.gpu.setForeground(foreground) end - for background in pairs(picture[alpha][symbol][foreground]) do - if component.gpu.getBackground ~= background then component.gpu.setBackground(background) end - currentBackground = background - - for yArray in pairs(picture[alpha][symbol][foreground][background]) do - for xArray = 1, #picture[alpha][symbol][foreground][background][yArray] do - xPos, yPos = x + picture[alpha][symbol][foreground][background][yArray][xArray], y + yArray - - --Если альфа имеется, но она не совсем прозрачна - if (alpha > 0x00 and alpha < 0xFF) or (alpha == 0xFF and symbol ~= " ")then - _, _, currentBackground = component.gpu.get(xPos, yPos) - currentBackground = colorlib.alphaBlend(currentBackground, background, alpha / 0xFF) - component.gpu.setBackground(currentBackground) - - component.gpu.set(xPos, yPos, symbol) - - elseif alpha == 0x00 then - if currentBackground ~= background then - currentBackground = background - component.gpu.setBackground(currentBackground) - end - - component.gpu.set(xPos, yPos, symbol) - end - --ecs.wait() + for alpha in pairs(groupedPicture) do + for symbol in pairs(groupedPicture[alpha]) do + for background in pairs(groupedPicture[alpha][symbol]) do + gpu.setBackground(background) + for foreground in pairs(groupedPicture[alpha][symbol][background]) do + gpu.setForeground(foreground) + for yPos in pairs(groupedPicture[alpha][symbol][background][foreground]) do + for xPos = 1, #groupedPicture[alpha][symbol][background][foreground][yPos] do + gpu.set(x + groupedPicture[alpha][symbol][background][foreground][yPos][xPos] - 1, y + yPos - 1, symbol) end end end @@ -1287,48 +75,308 @@ function image.draw(x, y, picture) end end -local function createSaveAndLoadFiles() - ecs.prepareToExit() - ecs.error("Создаю/загружаю изображение") - -- local cyka = image.load("MineOS/System/OS/Icons/Love.pic") - local cyka = image.createImage(4, 4) - ecs.error("Рисую загруженное изображение") - image.draw(2, 2, cyka) - ecs.error("Сохраняю его в 4 форматах") - image.save("0.pic", cyka, 0) - image.save("1.pic", cyka, 1) - image.save("4.pic", cyka, 4) - ecs.prepareToExit() - ecs.error("Загружаю все 4 формата и рисую их") - local cyka0 = image.load("0.pic") - image.draw(2, 2, cyka0) - local cyka1 = image.load("1.pic") - image.draw(10, 2, cyka1) - local cyka4 = image.load("4.pic") - image.draw(34, 2, cyka4) +function image.create(width, height, background, foreground, alpha, symbol, random) + local picture = {width, height} + + for i = 1, width * height do + table.insert(picture, random and math.random(0x0, 0xFFFFFF) or (background or 0x0)) + table.insert(picture, random and math.random(0x0, 0xFFFFFF) or (foreground or 0x0)) + table.insert(picture, alpha or 0x0) + table.insert(picture, random and string.char(math.random(65, 90)) or (symbol or " ")) + end + + return picture +end + +function image.copy(picture) + local newPicture = {} + for i = 1, #picture do + table.insert(newPicture, picture[i]) + end + + return newPicture +end + +function image.optimize(picture) + local iPlus1, iPlus2, iPlus3 + + for i = 3, #picture, 4 do + iPlus1, iPlus2, iPlus3 = i + 1, i + 2, i + 3 + + if picture[i] == picture[iPlus1] and (picture[iPlus3] == "▄" or picture[iPlus3] == "▀") then + picture[iPlus3] = " " + end + + if picture[iPlus3] == " " then + picture[iPlus1] = 0x000000 + end + end + + return picture +end + +-------------------------------------------------- Filesystem related methods -------------------------------------------------- + +function image.loadFormatModule(path, fileExtension) + local loadSuccess, loadReason = loadfile(path) + if loadSuccess then + local xpcallSuccess, xpcallReason = pcall(loadSuccess, image) + if xpcallSuccess then + image.formatModules[fileExtension] = xpcallReason + else + error("Failed to execute image format module: " .. tostring(xpcallReason)) + end + else + error("Failed to load image format module: " .. tostring(loadReason)) + end +end + +local function getFileExtension(path) + return string.match(path, "^.+(%.[^%/]+)%/?$") +end + +local function loadOrSave(methodName, path, picture, encodingMethod) + local fileExtension = getFileExtension(path) + if image.formatModules[fileExtension] then + return image.formatModules[fileExtension][methodName](path, picture, encodingMethod) + else + error("Failed to open file \"" .. tostring(path) .. "\" as image: format module for extension \"" .. tostring(fileExtension) .. "\" is not loaded") + end +end + +function image.save(path, picture, encodingMethod) + return loadOrSave("save", path, image.optimize(picture), encodingMethod) +end + +function image.load(path) + return loadOrSave("load", path) +end + +-------------------------------------------------- Image serialization -------------------------------------------------- + +function image.toString(picture) + local charArray = { + string.format("%02X", picture[1]), + string.format("%02X", picture[2]) + } + + for i = 3, #picture, 4 do + table.insert(charArray, string.format("%02X", colorlib.convert24BitTo8Bit(picture[i]))) + table.insert(charArray, string.format("%02X", colorlib.convert24BitTo8Bit(picture[i]))) + table.insert(charArray, string.format("%02X", picture[i + 2])) + table.insert(charArray, picture[i + 3]) + + compressionYield(i) + end + + return table.concat(charArray) +end + +function image.fromString(pictureString) + local picture = { + tonumber("0x" .. unicode.sub(pictureString, 1, 2)), + tonumber("0x" .. unicode.sub(pictureString, 3, 4)) + } + + for i = 5, unicode.len(pictureString), 7 do + table.insert(picture, colorlib.convert8BitTo24Bit(tonumber("0x" .. unicode.sub(pictureString, i, i + 1)))) + table.insert(picture, colorlib.convert8BitTo24Bit(tonumber("0x" .. unicode.sub(pictureString, i + 2, i + 3)))) + table.insert(picture, tonumber("0x" .. unicode.sub(pictureString, i + 4, i + 5))) + table.insert(picture, unicode.sub(pictureString, i + 6, i + 6)) + end + + return picture +end + +-------------------------------------------------- Image processing -------------------------------------------------- + +function image.set(picture, x, y, background, foreground, alpha, symbol) + local index = image.getImageIndexByCoordinates(x, y, picture[1]) + picture[index], picture[index + 1], picture[index + 2], picture[index + 3] = background, foreground, alpha, symbol + + return picture +end + +function image.get(picture, x, y) + local index = image.getImageIndexByCoordinates(x, y, picture[1]) + return picture[index], picture[index + 1], picture[index + 2], picture[index + 3] +end + +function image.getSize(picture) + return picture[1], picture[2] +end + +function image.getWidth(picture) + return picture[1] +end + +function image.getHeight(picture) + return picture[2] +end + +function image.transform(picture, newWidth, newHeight) + local newPicture, stepWidth, stepHeight, background, foreground, alpha, symbol = {newWidth, newHeight}, picture[1] / newWidth, picture[2] / newHeight + + local x, y = 1, 1 + for j = 1, newHeight do + for i = 1, newWidth do + background, foreground, alpha, symbol = image.get(picture, math.floor(x), math.floor(y)) + table.insert(newPicture, background) + table.insert(newPicture, foreground) + table.insert(newPicture, alpha) + table.insert(newPicture, symbol) + + x = x + stepWidth + end + x, y = 1, y + stepHeight + end + + return newPicture +end + +function image.crop(picture, fromX, fromY, width, height) + if fromX >= 1 and fromY >= 1 and fromX + width - 1 <= picture[1] and fromY + height - 1 <= picture[2] then + local newPicture, background, foreground, alpha, symbol = {width, height} + + for y = fromY, fromY + height - 1 do + for x = fromX, fromX + width - 1 do + background, foreground, alpha, symbol = image.get(picture, x, y) + table.insert(newPicture, background) + table.insert(newPicture, foreground) + table.insert(newPicture, alpha) + table.insert(newPicture, symbol) + end + end + + return newPicture + else + error("Failed to crop image: target coordinates are out of source range") + end +end + +function image.flipHorizontally(picture) + local newPicture, background, foreground, alpha, symbol = {picture[1], picture[2]} + + for y = 1, picture[2] do + for x = picture[1], 1, -1 do + background, foreground, alpha, symbol = image.get(picture, x, y) + table.insert(newPicture, background) + table.insert(newPicture, foreground) + table.insert(newPicture, alpha) + table.insert(newPicture, symbol) + end + end + + return newPicture +end + +function image.flipVertically(picture) + local newPicture, background, foreground, alpha, symbol = {picture[1], picture[2]} + + for y = picture[2], 1, -1 do + for x = 1, picture[1] do + background, foreground, alpha, symbol = image.get(picture, x, y) + table.insert(newPicture, background) + table.insert(newPicture, foreground) + table.insert(newPicture, alpha) + table.insert(newPicture, symbol) + end + end + + return newPicture +end + +function image.expand(picture, fromTop, fromBottom, fromLeft, fromRight, background, foreground, alpha, symbol) + local newPicture = image.create(picture[1] + fromRight + fromLeft, picture[2] + fromTop + fromBottom, background, foreground, alpha, symbol) + + for y = 1, picture[2] do + for x = 1, picture[1] do + image.set(newPicture, x + fromLeft, y + fromTop, image.get(picture, x, y)) + end + end + + return newPicture end ------------------------------------------------------------------------------------------------------------------------ --- local picture = image.load("MineOS/System/OS/Icons/Love.pic") --- buffer.clear(0xFF8888) --- buffer.draw(true) +image.loadFormatModule("/lib/ImageFormatModules/OCIF.lua", ".pic") --- buffer.image(1, 1, picture) --- buffer.draw() +------------------------------------------------------------------------------------------------------------------------ --- local newPicture = transform(picture, 0.5, 2) +-- local function loadImageInOldFormat(path) +-- local picture = require("image").load(path) +-- table.insert(picture, 1, picture.height) +-- table.insert(picture, 1, picture.width) +-- picture.width, picture.height = nil, nil +-- return picture +-- end --- local columnArray = {}; for i = 1, picture.height do table.insert(columnArray, 0xFFFFFF); table.insert(columnArray, 0x000000); table.insert(columnArray, 0x00); table.insert(columnArray, " ") end --- local rowArray = {}; for i = 1, picture.width do table.insert(rowArray, 0xFFFFFF); table.insert(rowArray, 0x000000); table.insert(rowArray, 0x00); table.insert(rowArray, " ") end --- local rowArray = image.getRow(picture, 2) --- picture = image.insertColumn(picture, 1, columnArray) --- picture = image.insertRow(picture, 3, rowArray) --- picture = image.removeColumn(picture, 1) +-- local fs = require("filesystem") +-- local function recursiveConversion(path, targetPath) +-- for file in fs.list(path) do +-- if fs.isDirectory(path .. file) then +-- if not string.find(path .. file, "ConvertedPics") then +-- recursiveConversion(path .. file, targetPath) +-- end +-- else +-- local fileExtension = getFileExtension(path .. file) +-- if fileExtension == ".pic" then +-- print("Загружаю пикчу в старом формате:", path .. file) +-- local oldPicture = loadImageInOldFormat(path .. file) --- buffer.image(1, 19, picture) --- buffer.image(1, 19, newPicture) --- buffer.draw() +-- -- local newPath = string.gsub(path, ".app", "") +-- -- print("Сейвлю пикчу в новом:", targetPath .. newPath .. file) +-- -- fs.makeDirectory(targetPath .. newPath) +-- -- image.save(targetPath .. newPath .. file, oldPicture, 6) +-- -- print("---------------") + +-- print("Пересохраняю ее в новом формате") +-- image.save(path .. file, oldPicture, 6) +-- end +-- end +-- end +-- end + +-- recursiveConversion("/MineOS/", "/ConvertedPics/") + +-- local function clearAndDraw(picture) +-- gpu.setBackground(0x2D2D2D) +-- gpu.setForeground(0xFFFFFF) +-- gpu.fill(1, 1, 160, 50, " ") + +-- image.draw(1, 1, picture) +-- end + +-- local w, h = 2, 2 +-- local picture = image.create(w, h, 0xFF0000, 0xFFFFFF, 0x0, "Q") +-- local picture = loadImageInOldFormat("/MineOS/System/OS/Icons/Love.pic") + +-- print("Saving as old...") +-- require("image").save("/testPicOld.pic", picture, 4) + +-- print("Processing image...") +-- local newPicture = image.transform(picture, 100, 50) +-- local newPicture = image.flipVertically(picture) +-- local newPicture = image.crop(picture, 4, 4, 20, 10) +-- local newPicture = image.expand(picture, 1, 1, 1, 1, 0xFFFFFF, 0x000000, 0x0, "#") +-- clearAndDraw(newPicture) + +-- print("ToStringing...") +-- local pictureString = image.toString(picture) +-- print(pictureString) + +-- print("FromStringing...") +-- local fromStringPicture = image.fromString("0804000000 000000 000000 000000 000000 000000 000000 0000FF 000000 0000FF 0000FF 0000FF 0000FF 0000FF 000000 0000FF 000000 000000 000000 000000 000000 000000 000000 0000FF 000000 0000FF 0000FF 0000FF 0000FF 0000FF 000000 0000FF ") +-- clearAndDraw(fromStringPicture) + +-- print("Creating new...") +-- image.save("/testPic.pic", picture, 6) + +-- print("Loading new...") +-- local loadedPicture = image.load("/testPic.pic") +-- print("Drawing new...") +-- clearAndDraw(loadedPicture) ------------------------------------------------------------------------------------------------------------------------ diff --git a/lib/internetLib.lua b/lib/internetLib.lua new file mode 100755 index 00000000..4826d27a --- /dev/null +++ b/lib/internetLib.lua @@ -0,0 +1,83 @@ + +----------------------------------------- Libraries ----------------------------------------- + +local fs = require("filesystem") +local component = require("component") +local internet = {} + +----------------------------------------- Main methods ----------------------------------------- + +function internet.request(url) + local pcallSuccess, requestHandle, requestReason = pcall(component.internet.request, url) + + -- Если функция компонента была вызвана верно, то идем дальше + if pcallSuccess then + -- Если компонент вернул там хендл соединения, то читаем ответ из него + -- Хендл может не вернуться в случае хуевой урл-ки, которая не нравится компоненту + if requestHandle then + local responseData = "" + -- Читаем данные из хендла по кусочкам + while true do + local data, reason = requestHandle.read(math.huge) + -- Если прочтение удалость, то записываем кусочек в буфер + if data then + responseData = responseData .. data + else + -- Если чтение не удалось, и существует некий прочитанный кусочек, то в нем стопудова содержится ошибка чтения + requestHandle:close() + if reason then + return false, reason + -- А если кусочка нет, то это значит, что соединение можно закрывать с чистой совестью и возвращать всю инфу + else + return true, responseData + end + end + end + else + return false, "Invalid URL-addess" + end + else + return false, "Usage: internet.request(string url)" + end +end + +function internet.downloadFile(url, path) + local success, result = internet.request(url) + if success then + fs.makeDirectory(fs.path(path) or "") + local file = io.open(path, "w") + file:write(result) + file:close() + return true + else + return false, "Could not connect to to URL-address \"" .. tostring(url) .. "\", the reason is \"" .. tostring(result) .. "\"" + end +end + +function internet.runScript(url) + local success, result = internet.request(url) + if success then + local loadSucces, loadReason = load(result) + if loadSucces then + local xpcallSuccess, xpcallSuccessReason = xpcall(loadSucces, debug.traceback) + if xpcallSuccess then + return true + else + return false, "Failed to run script: " .. tostring(xpcallSuccessReason) + end + else + return false, "Failed to run script: " .. tostring(loadReason) + end + else + return false, "Could not connect to to URL-address \"" .. tostring(url) .. "\", the reason is \"" .. tostring(result) .. "\"" + end +end + +----------------------------------------- Cyka ----------------------------------------- + +return internet + + + + + diff --git a/lib/palette.lua b/lib/palette.lua index cf77f8eb..fb3f6e71 100755 --- a/lib/palette.lua +++ b/lib/palette.lua @@ -205,7 +205,6 @@ local function createWindow(x, y) drawAll() end bigRainbow.onDrag = bigRainbow.onTouch - x = x + bigRainbow.width + 2 miniRainbow = window:addImage(x, y, image.create(3, 25)) diff --git a/lib/rayEngine.lua b/lib/rayEngine.lua index 47f654c8..d0cddb54 100755 --- a/lib/rayEngine.lua +++ b/lib/rayEngine.lua @@ -40,12 +40,12 @@ end -- Позиция оружия на экране и всех его вспомогательных текстур function rayEngine.calculateWeaponPosition() - rayEngine.currentWeapon.xWeapon = buffer.screen.width - rayEngine.currentWeapon.weaponTexture.width + 1 - rayEngine.currentWeapon.yWeapon = buffer.screen.height - rayEngine.currentWeapon.weaponTexture.height + 1 + rayEngine.currentWeapon.xWeapon = buffer.screen.width - rayEngine.currentWeapon.weaponTexture[1] + 1 + rayEngine.currentWeapon.yWeapon = buffer.screen.height - rayEngine.currentWeapon.weaponTexture[2] + 1 rayEngine.currentWeapon.xFire = rayEngine.currentWeapon.xWeapon + rayEngine.weapons[rayEngine.currentWeapon.ID].firePosition.x rayEngine.currentWeapon.yFire = rayEngine.currentWeapon.yWeapon + rayEngine.weapons[rayEngine.currentWeapon.ID].firePosition.y - rayEngine.currentWeapon.xCrosshair = math.floor(buffer.screen.width / 2 - rayEngine.currentWeapon.crosshairTexture.width / 2) - rayEngine.currentWeapon.yCrosshair = math.floor(buffer.screen.height / 2 - rayEngine.currentWeapon.crosshairTexture.height / 2) + rayEngine.currentWeapon.xCrosshair = math.floor(buffer.screen.width / 2 - rayEngine.currentWeapon.crosshairTexture[1] / 2) + rayEngine.currentWeapon.yCrosshair = math.floor(buffer.screen.height / 2 - rayEngine.currentWeapon.crosshairTexture[2] / 2) end -- Грубо говоря, это расстояние от камеры до виртуального экрана, на котором рисуется весь наш мир, влияет на размер блоков @@ -286,7 +286,7 @@ end function rayEngine.intro() local logo = image.fromString("17060000FF 0000FF 0000FF 0000FF 007EFF▄007EFF▄007EFF▄007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▄007EFF▄007EFF▄0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 007EFF▄007EFF▀007EFF▀0000FF 0000FF 0000FF 0000FF 0053FF▄0053FF▀0053FF▀0053FF▀0053FF▄0000FF 0000FF 0000FF 0000FF 007EFF▀007EFF▀007EFF▄0000FF 0000FF 0000FF 007EFF▀007EFF▄0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 530000 0000FF 0078FF▀0000FF 537800▀0078FF▀0078FF▀0078FF▀0078FF▀0078FF▀0078FF▀7E7800▀0078FF▀0000FF 0078FF▀0000FF 0000FF 007EFF▀007EFF▀007EFF▄007EFF▄007EFF▄0000FF 0000FF 0053FF▀0053FF▀0053FF▀0000FF 0000FF 007EFF▄007EFF▄007EFF▄007EFF▀007EFF▀0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀007EFF▀0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 0000FF 007EFFP007EFFo007EFFw007EFFe007EFFr007EFFe007EFFd0000FF 007EFFb007EFFy0000FF 007EFFR007EFFa007EFFy007EFFE007EFFn007EFFg007EFFi007EFFn007EFFe007EFF™0000FF 0000FF ") - local x, y = math.floor(buffer.screen.width / 2 - logo.width / 2), math.floor(buffer.screen.height / 2 - logo.height / 2) + local x, y = math.floor(buffer.screen.width / 2 - logo[1] / 2), math.floor(buffer.screen.height / 2 - logo[2] / 2) local function draw(transparency) buffer.clear(0xF0F0F0); buffer.image(x, y, logo) diff --git a/lib/windows.lua b/lib/windows.lua new file mode 100755 index 00000000..4e1427a4 --- /dev/null +++ b/lib/windows.lua @@ -0,0 +1,4 @@ + + +error("Ты че, долбоеб? Виндолиба удалена уже, пиздец") +