Bimg
- added some basic bimg support - added basaltdraw.blit (and frame.blit for internal use)
This commit is contained in:
@@ -1055,13 +1055,20 @@ return function(name, parent, pTerm, basalt)
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
blit = function (self, x, y, t, b, f)
|
blit = function (self, x, y, t, f, b)
|
||||||
local obx, oby = self:getAnchorPosition()
|
local obx, oby = self:getAnchorPosition()
|
||||||
if (y >= 1) and (y <= self:getHeight()) then
|
if (y >= 1) and (y <= self:getHeight()) then
|
||||||
|
local w = self:getWidth()
|
||||||
if (self.parent ~= nil) then
|
if (self.parent ~= nil) then
|
||||||
self.parent:blit(max(x + (obx - 1), obx), oby + y - 1, sub(text, max(1 - x + 1, 1), self:getWidth() - x + 1), bgCol, fgCol)
|
t = sub(t, max(1 - x + 1, 1), w - x + 1)
|
||||||
|
f = sub(f, max(1 - x + 1, 1), w - x + 1)
|
||||||
|
b = sub(b, max(1 - x + 1, 1), w - x + 1)
|
||||||
|
self.parent:blit(max(x + (obx - 1), obx), oby + y - 1, t, f, b)
|
||||||
else
|
else
|
||||||
basaltDraw.blit(max(x + (obx - 1), obx), oby + y - 1, sub(text, max(1 - x + 1, 1), max(self:getWidth() - x + 1,1)), bgCol, fgCol)
|
t = sub(t, max(1 - x + 1, 1), max(w - x + 1,1))
|
||||||
|
f = sub(f, max(1 - x + 1, 1), max(w - x + 1,1))
|
||||||
|
b = sub(b, max(1 - x + 1, 1), max(w - x + 1,1))
|
||||||
|
basaltDraw.blit(max(x + (obx - 1), obx), oby + y - 1, t, f, b)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|||||||
@@ -784,16 +784,9 @@ return function(name)
|
|||||||
|
|
||||||
dragHandler = function(self, button, x, y)
|
dragHandler = function(self, button, x, y)
|
||||||
if(isDragging)then
|
if(isDragging)then
|
||||||
local xO, yO, parentX, parentY = 0, 0, 1, 1
|
|
||||||
if (self.parent ~= nil) then
|
|
||||||
xO, yO = self.parent:getOffsetInternal()
|
|
||||||
xO = xO < 0 and math.abs(xO) or -xO
|
|
||||||
yO = yO < 0 and math.abs(yO) or -yO
|
|
||||||
parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition())
|
|
||||||
end
|
|
||||||
local dX, dY = x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO
|
|
||||||
local val = eventSystem:sendEvent("mouse_drag", self, "mouse_drag", button, dX, dY, dragStartX-x, dragStartY-y, x, y)
|
|
||||||
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
|
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
|
||||||
|
local dX, dY = x - objX + 1, y - objY + 1
|
||||||
|
local val = eventSystem:sendEvent("mouse_drag", self, "mouse_drag", button, dX, dY, dragStartX-x, dragStartY-y, x, y)
|
||||||
dragStartX, dragStartY = x, y
|
dragStartX, dragStartY = x, y
|
||||||
if(val~=nil)then return val end
|
if(val~=nil)then return val end
|
||||||
if(self.parent~=nil)then
|
if(self.parent~=nil)then
|
||||||
|
|||||||
@@ -126,6 +126,52 @@ return function(drawTerm)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function blit(x, y, t, fg, bg)
|
||||||
|
if(#t == #fg)or(#t == #bg)then
|
||||||
|
if (y >= 1) and (y <= height) then
|
||||||
|
if (x + t:len() > 0) and (x <= width) then
|
||||||
|
local oldCacheT = cacheT[y]
|
||||||
|
local oldCacheFG = cacheFG[y]
|
||||||
|
local oldCacheBG = cacheBG[y]
|
||||||
|
local newCacheT, newCacheFG, newCacheBG
|
||||||
|
local nEnd = x + #t - 1
|
||||||
|
|
||||||
|
if (x < 1) then
|
||||||
|
local startN = 1 - x + 1
|
||||||
|
local endN = width - x + 1
|
||||||
|
t = sub(t, startN, endN)
|
||||||
|
fg = sub(fg, startN, endN)
|
||||||
|
bg = sub(bg, startN, endN)
|
||||||
|
elseif (nEnd > width) then
|
||||||
|
local endN = width - x + 1
|
||||||
|
t = sub(t, 1, endN)
|
||||||
|
fg = sub(fg, 1, endN)
|
||||||
|
bg = sub(bg, 1, endN)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (x > 1) then
|
||||||
|
local endN = x - 1
|
||||||
|
newCacheT = sub(oldCacheT, 1, endN) .. t
|
||||||
|
newCacheFG = sub(oldCacheFG, 1, endN) .. fg
|
||||||
|
newCacheBG = sub(oldCacheBG, 1, endN) .. bg
|
||||||
|
else
|
||||||
|
newCacheT = t
|
||||||
|
newCacheFG = fg
|
||||||
|
newCacheBG = bg
|
||||||
|
end
|
||||||
|
if nEnd < width then
|
||||||
|
newCacheT = newCacheT .. sub(oldCacheT, nEnd + 1, width)
|
||||||
|
newCacheFG = newCacheFG .. sub(oldCacheFG, nEnd + 1, width)
|
||||||
|
newCacheBG = newCacheBG .. sub(oldCacheBG, nEnd + 1, width)
|
||||||
|
end
|
||||||
|
cacheT[y] = newCacheT
|
||||||
|
cacheFG[y] = newCacheFG
|
||||||
|
cacheBG[y] = newCacheBG
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local drawHelper = {
|
local drawHelper = {
|
||||||
setSize = function(w, h)
|
setSize = function(w, h)
|
||||||
width, height = w, h
|
width, height = w, h
|
||||||
@@ -147,6 +193,10 @@ return function(drawTerm)
|
|||||||
setFG(x, y, colorStr)
|
setFG(x, y, colorStr)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
blit = function(x, y, t, fg, bg)
|
||||||
|
blit(x, y, t, fg, bg)
|
||||||
|
end,
|
||||||
|
|
||||||
drawBackgroundBox = function(x, y, width, height, bgCol)
|
drawBackgroundBox = function(x, y, width, height, bgCol)
|
||||||
for n = 1, height do
|
for n = 1, height do
|
||||||
setBG(x, y + (n - 1), rep(tHex[bgCol], width))
|
setBG(x, y + (n - 1), rep(tHex[bgCol], width))
|
||||||
|
|||||||
32
Basalt/libraries/images.lua
Normal file
32
Basalt/libraries/images.lua
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
local function loadNFP(path)
|
||||||
|
return paintutils.loadImage(path), "nfp"
|
||||||
|
end
|
||||||
|
|
||||||
|
local function loadBIMG(path)
|
||||||
|
local f = fs.open(path, "r")
|
||||||
|
local content = load("return "..f.readAll())()
|
||||||
|
f.close()
|
||||||
|
if(content~=nil)then
|
||||||
|
return content, "bimg"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function loadImage(path, f)
|
||||||
|
if(f==nil)then
|
||||||
|
if(path:find(".bimg"))then
|
||||||
|
return loadBIMG(path)
|
||||||
|
elseif(path:find(".bbf"))then
|
||||||
|
return loadBBF(path)
|
||||||
|
else
|
||||||
|
return loadNFP(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- ...
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
loadNFP = loadNFP,
|
||||||
|
loadBIMG = loadBIMG,
|
||||||
|
loadImage = loadImage,
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,135 +1,15 @@
|
|||||||
local Object = require("Object")
|
local Object = require("Object")
|
||||||
local xmlValue = require("utils").getValueFromXML
|
local xmlValue = require("utils").getValueFromXML
|
||||||
|
local images = require("images")
|
||||||
|
|
||||||
|
local unpack = table.unpack
|
||||||
return function(name)
|
return function(name)
|
||||||
-- Image
|
-- Image
|
||||||
local base = Object(name)
|
local base = Object(name)
|
||||||
local objectType = "Image"
|
local objectType = "Image"
|
||||||
base:setZIndex(2)
|
base:setZIndex(2)
|
||||||
local image
|
local image
|
||||||
local shrinkedImage
|
local format = "nfp"
|
||||||
local imageGotShrinked = false
|
|
||||||
|
|
||||||
local function shrink()
|
|
||||||
-- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
|
|
||||||
local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 },
|
|
||||||
{ 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } }
|
|
||||||
|
|
||||||
local colourNum, exponents, colourChar = {}, {}, {}
|
|
||||||
for i = 0, 15 do
|
|
||||||
exponents[2 ^ i] = i
|
|
||||||
end
|
|
||||||
do
|
|
||||||
local hex = "0123456789abcdef"
|
|
||||||
for i = 1, 16 do
|
|
||||||
colourNum[hex:sub(i, i)] = i - 1
|
|
||||||
colourNum[i - 1] = hex:sub(i, i)
|
|
||||||
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
|
|
||||||
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
|
|
||||||
|
|
||||||
local thisRel = relations[i - 1]
|
|
||||||
for i = 1, #thisRel do
|
|
||||||
thisRel[i] = 2 ^ thisRel[i]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function getBestColourMatch(usage)
|
|
||||||
local lastCol = relations[exponents[usage[#usage][1]]]
|
|
||||||
|
|
||||||
for j = 1, #lastCol do
|
|
||||||
local thisRelation = lastCol[j]
|
|
||||||
for i = 1, #usage - 1 do
|
|
||||||
if usage[i][1] == thisRelation then
|
|
||||||
return i
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local function colsToChar(pattern, totals)
|
|
||||||
if not totals then
|
|
||||||
local newPattern = {}
|
|
||||||
totals = {}
|
|
||||||
for i = 1, 6 do
|
|
||||||
local thisVal = pattern[i]
|
|
||||||
local thisTot = totals[thisVal]
|
|
||||||
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
|
|
||||||
end
|
|
||||||
pattern = newPattern
|
|
||||||
end
|
|
||||||
|
|
||||||
local usage = {}
|
|
||||||
for key, value in pairs(totals) do
|
|
||||||
usage[#usage + 1] = { key, value }
|
|
||||||
end
|
|
||||||
|
|
||||||
if #usage > 1 then
|
|
||||||
-- Reduce the chunk to two colours:
|
|
||||||
while #usage > 2 do
|
|
||||||
table.sort(usage, function(a, b)
|
|
||||||
return a[2] > b[2]
|
|
||||||
end)
|
|
||||||
local matchToInd, usageLen = getBestColourMatch(usage), #usage
|
|
||||||
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
|
|
||||||
for i = 1, 6 do
|
|
||||||
if pattern[i] == matchFrom then
|
|
||||||
pattern[i] = matchTo
|
|
||||||
usage[matchToInd][2] = usage[matchToInd][2] + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
usage[usageLen] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Convert to character. Adapted from oli414's function:
|
|
||||||
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
|
|
||||||
local data = 128
|
|
||||||
for i = 1, #pattern - 1 do
|
|
||||||
if pattern[i] ~= pattern[6] then
|
|
||||||
data = data + 2 ^ (i - 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
|
|
||||||
else
|
|
||||||
-- Solid colour character:
|
|
||||||
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local results, width, height, bgCol = { {}, {}, {} }, 0, #image + #image % 3, base.bgColor or colors.black
|
|
||||||
for i = 1, #image do
|
|
||||||
if #image[i] > width then
|
|
||||||
width = #image[i]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for y = 0, height - 1, 3 do
|
|
||||||
local cRow, tRow, bRow, counter = {}, {}, {}, 1
|
|
||||||
|
|
||||||
for x = 0, width - 1, 2 do
|
|
||||||
-- Grab a 2x3 chunk:
|
|
||||||
local pattern, totals = {}, {}
|
|
||||||
|
|
||||||
for yy = 1, 3 do
|
|
||||||
for xx = 1, 2 do
|
|
||||||
pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol
|
|
||||||
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
|
|
||||||
counter = counter + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
|
|
||||||
end
|
|
||||||
|
|
||||||
results.width, results.height = #results[1][1], #results[1]
|
|
||||||
|
|
||||||
shrinkedImage = results
|
|
||||||
end
|
|
||||||
|
|
||||||
local object = {
|
local object = {
|
||||||
init = function(self)
|
init = function(self)
|
||||||
@@ -139,58 +19,41 @@ return function(name)
|
|||||||
return objectType
|
return objectType
|
||||||
end;
|
end;
|
||||||
|
|
||||||
loadImage = function(self, path)
|
loadImage = function(self, path, f)
|
||||||
image = paintutils.loadImage(path)
|
image, _format = images.loadImage(path, f)
|
||||||
imageGotShrinked = false
|
if(_format~=nil)then
|
||||||
|
format = _format
|
||||||
|
end
|
||||||
self:updateDraw()
|
self:updateDraw()
|
||||||
return self
|
return self
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
setImage = function(self, data, _format)
|
||||||
|
iamge = data
|
||||||
|
format = _format
|
||||||
|
end,
|
||||||
|
|
||||||
shrink = function(self)
|
getImageData = function(self)
|
||||||
shrink()
|
return image
|
||||||
imageGotShrinked = true
|
end,
|
||||||
self:updateDraw()
|
|
||||||
return self
|
|
||||||
end;
|
|
||||||
|
|
||||||
setValuesByXMLData = function(self, data)
|
setValuesByXMLData = function(self, data)
|
||||||
base.setValuesByXMLData(self, data)
|
base.setValuesByXMLData(self, data)
|
||||||
if(xmlValue("shrink", data)~=nil)then if(xmlValue("shrink", data))then self:shrink() end end
|
|
||||||
if(xmlValue("path", data)~=nil)then self:loadImage(xmlValue("path", data)) end
|
if(xmlValue("path", data)~=nil)then self:loadImage(xmlValue("path", data)) end
|
||||||
return self
|
return self
|
||||||
end,
|
end,
|
||||||
|
|
||||||
draw = function(self)
|
draw = function(self)
|
||||||
if (base.draw(self)) then
|
if (base.draw(self)) then
|
||||||
if (self.parent ~= nil) then
|
if (image ~= nil) then
|
||||||
if (image ~= nil) then
|
local obx, oby = self:getAnchorPosition()
|
||||||
local obx, oby = self:getAnchorPosition()
|
local w,h = self:getSize()
|
||||||
local w,h = self:getSize()
|
if(format=="nfp")then
|
||||||
if (imageGotShrinked) then
|
|
||||||
-- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
|
elseif(format=="bimg")then
|
||||||
local t, tC, bC = shrinkedImage[1], shrinkedImage[2], shrinkedImage[3]
|
for y,v in ipairs(image[1])do
|
||||||
for i = 1, math.min(shrinkedImage.height, h) do
|
self.parent:blit(obx, oby+y-1, unpack(v))
|
||||||
local tI = t[i]
|
|
||||||
if type(tI) == "string" then
|
|
||||||
self.parent:setText(obx, oby + i - 1, tI:sub(1,w))
|
|
||||||
self.parent:setFG(obx, oby + i - 1, tC[i]:sub(1,w))
|
|
||||||
self.parent:setBG(obx, oby + i - 1, bC[i]:sub(1,w))
|
|
||||||
elseif type(tI) == "table" then
|
|
||||||
self.parent:setText(obx, oby + i - 1, tI[2]:sub(1,w))
|
|
||||||
self.parent:setFG(obx, oby + i - 1, tC[i]:sub(1,w))
|
|
||||||
self.parent:setBG(obx, oby + i - 1, bC[i]:sub(1,w))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for yPos = 1, math.min(#image, h) do
|
|
||||||
local line = image[yPos]
|
|
||||||
for xPos = 1, math.min(#line, w) do
|
|
||||||
if line[xPos] > 0 then
|
|
||||||
self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user