This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
je06's profile picture

Drawing From Tables

Started by je06, 06 August 2015 - 02:57 PM
je06 #1
Posted 06 August 2015 - 04:57 PM
I'm trying to make a format for images that takes up less space and is easier to use for computercraft.
My draw function is not working correctly.

A example of my file formate
Spoiler

layers={
l1={
bgColors={
{-1,-1,-1,-1,5},
{-1,-1,-1,4,-1},
{-1,-1,3,-1,-1},
{-1,2,-1,-1,-1},
{1,-1,-1,-1,-1},
},
textColors={
{0,0,0,0,4},
{0,0,0,3,0},
{0,0,2,0,0},
{0,1,0,0,0},
{5,0,0,0,0},
},
text={
{0,0,0,0,"a"},
{0,0,0,"b",0},
{0,0,"c",0,0},
{0,"d",0,0,0},
{"e",0,0,0,0},
}
},
l2={
bgColors={
{-1,2},
{1,-1},
},
textColors={
{0,0},
{0,0},
},
text={
{0,0},
{0,0},
},
}
}

My load function
Spoiler

function readFile(path)
  fs.move(path, "a")
  os.loadAPI("a")
  fs.move("a", path)
  local l = a.layers
  os.unloadAPI("a")
  return l
end

My draw function
Spoiler

function draw(layers,sX,sY)
  for a,b in pairs(layers) do
	for y=1,#layers[a].bgColors do
	  sY = sY + y - 1
	  for x=1,#layers[a].bgColors[1] do
		sX = sX + x - 1
		term.setCursorPos(sX,sY)
		if not layers[a].bgColors[sY][sX] == -1 then
		  term.setBackgroundColor(color[layers[a].bgColors[sY][sX]])
		end
		term.setTextColor(color[layers[a].textColors[sY][sX]])
		if tonumber(layers[a].text[sY][sX]) == nil or layers[a].text[sY] == nil or layers[a].text == nil then
		  term.write(layers[a].text[sY][sX])
		else
		  term.write(" ")
		end
	  end
	end
  end
end

And then at the very top I have
Spoiler

color={colors.white,colors.orange,colors.magenta,colors.lightBlue,
colors.yellow,colors.lime,colors.pink,colors.gray,colors.lightGray,
colors.cyan,colors.purple,colors.blue,colors.green,colors.red,colors.black}
KingofGamesYami #2
Posted 06 August 2015 - 05:37 PM
FYI you can store two colors in a single character/byte, because there are 256 possible characters and 16 * 16 = 256. So, to store text and colors for said text, you'd need only two characters.

Maybe you want to try again using that?
je06 #3
Posted 06 August 2015 - 09:15 PM
That probably won't work for what I'm doing
SquidDev #4
Posted 06 August 2015 - 09:22 PM
Just a couple of points on your code.

Your loading function uses os.loadAPI. You might want to look into textutils.unserialize and fs.open.

function readFile(path)
  local handle = fs.open(path, "r")
  local data = textutils.unserialize("{" .. handle.readAll() .. "}")
  handle.close
  return l.layers
end

Your drawing function:

for a,b in pairs(layers) do
	-- layers[a] == b. So you don't need to do layers[a]
end

Also:

sX = sX + x -  1 -- Replace this with
local offsetX = sX + x  - 1
Otherwise you are just overwriting sX every time. If that isn't breaking your code then the fact that lua tables start at 1, whilst your numbers start at 0 will - so color lookup ends wrong.

You can also simplify your colors table:

colors[x] -- can be replaced with
2^x -- (Or 2 ^ (x-1) if you start at 1).

Edited with some more fixes
Edited on 06 August 2015 - 07:24 PM
je06 #5
Posted 06 August 2015 - 09:46 PM
That didn't fix it
ErwinOlie #6
Posted 06 August 2015 - 10:58 PM
First of all, i asume that sX and sY are the starting positions of the drawing?

Then, there are 3 problems,

Firstly, the color-array doesn't recognize index '0' from bgColors and textColors,
Secondly, the use of sX and sY is invalid and not working.
Thirdly, (i'm flabbergasted by this one), the order of the layers gets reordered.

Fix for problem 1 and 2:
function draw(layers, sX, sY)
  for a, b in pairs(layers) do
	for y=1, #layers[a].bgColors do
	  for x=1, #layers[a].bgColors[1] do
		term.setCursorPos(sX + x, sY + y)
		if not layers[a].bgColors[y][x] == -1 then
		  term.setBackgroundColor(2 ^ layers[a].bgColors[y][x])
		end
		term.setTextColor(2 ^ layers[a].textColors[y][x])
		if tonumber(layers[a].text[y][x]) == nil or layers[a].text[y] == nil or layers[a].text == nil then
		  term.write(layers[a].text[y][x])
		else
		  term.write(" ")
		end
	  end
	end
  end
end

Oh, and i removed the use of that color-table, see how it's done now… :)/>
Bomb Bloke #7
Posted 06 August 2015 - 11:37 PM
Fix what? How about you describe your symptoms, so people know what to look for, and post the updated version of your code, so they can confirm you've applied the suggested fixes correctly?
je06 #8
Posted 07 August 2015 - 01:32 AM
Erwin almost fixed it. The font color works and it does display text, but it the background colors don't display.
ErwinOlie #9
Posted 07 August 2015 - 07:49 AM
Erwin almost fixed it. The font color works and it does display text, but it the background colors don't display.

This should fix it;

--if not layers[a].bgColors[y][x] == -1 then
if layers[a].bgColors[y][x] ~= -1 then

Remember that term.setBackgroundColor sets the color, not only for the selected point, but also for the points you select afterwards, so you should 'reset' the bgColors to default ;)/>

It should look a bit like this:
if layers[a].bgColors[y][x] ~= -1 then
term.setBackgroundColor(2 ^ layers[a].bgColors[y][x])
else
term.setBackgroundColor(2 ^ 15) -- the black color
end

But.. there is also a nerd-way of solving this, try to learn from it:

--if layers[a].bgColors[y][x] ~= -1 then
--  term.setBackgroundColor(2 ^ layers[a].bgColors[y][x])
--else
--  term.setBackgroundColor(2 ^ 15) -- the black color
--end
term.setBackgroundColor(2 ^ (b.bgColors[y][x] == -1 and 15 or b.bgColors[y][x]))

Have some fun with it :)/>
Bomb Bloke #10
Posted 07 August 2015 - 10:29 AM
So are you saying the background is always black? Looks to me like you should be getting colours, but probably not where you want them - what are you expecting to see used when you've got a -1 set for the location? Currently it'll just use whatever it used for the last spot.

You might consider looking into term.blit().
je06 #11
Posted 07 August 2015 - 05:53 PM
Thanks Eriwn for the fix :)/> ! To answer Bomb's question, the background is not always suppose to be black and -1 means it's transparent so nothing is drawn there.

I'm also trying to write a saving function that would write to the format properly from three individual tables(bgColor, textColor, text).

At the top of my file I have this
Spoiler

local bgColors = {}
local textColors = {}
local text = {}

And my save function
Spoiler

function saveFile()
  local path = saveLoadFile()
  local layers = {}
  for a=1,#bgColors do
	layers[a] = {bgColors={},textColors={},text={}}
	layers[a].bgColors = bgColors[a]
	layers[a].textColors = textColors[a]
	layers[a].text = text[a]
  end
  local fLayers = {}
  for a=1,#layers do
	fLayers["l"..tostring(a)] = layers[a]
  end
  layers = fLayers
  local file = fs.open(path, "w")
  file.write("layers=")
  file.write(layers)
  file.close()
end

Also, how would you draw on screen from the three tables at top?
Edited on 07 August 2015 - 06:54 PM