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

Dynamic buttons through file [Help]

Started by onix331, 17 January 2015 - 08:11 AM
onix331 #1
Posted 17 January 2015 - 09:11 AM
Hello!

Currently i am making a program where the client logs in on the host, and the host sends a map to the client (A few checks between it).

Now i am stuck at the part to integrate the touchscreen. I want to read the map through the file, also the touchscreen-positions.

Spoiler

--This code is developed by me (onix331) and is available under the GNU General Public License (Version 3)
--For all CC-Versions Universal
--See http://opensource.org/licenses/GPL-3.0
--Have fun
ver = "0.1 Alpha"--For updates
status = "---"--You can modify the init-status that will be transferred to the host at the beginning
--It is usually not necessary to modify the next variables
ishost = "0"
requiredvers = "0.1"
isvers = "0.1"
function clear()--To clear the screen
term.clear()
term.setCursorPos(1,1)
end
function startclient()
clear()
clientid = tostring(os.getComputerID())
rednet.open("back")
hostid = rednet.lookup("TCiP")

if hostid then
  print("Server found! continuining!")
else
  print("Server not found! Might be down right now, please try again later!")
  error()
end

function pair()
  clear()
  print ("Trying to pair with host")
  hostid = rednet.lookup("TCiP")
  rednet.send(hostid, "pair", "TCiP")
  hostid, message, protocol = rednet.receive(0.5)
  if message=="succesfull" then
   print("Succesfully paired, continuing...")
  else
   print("Pairing not successfull, trying again...")
   pair()
  end
end
function getinfo()
  rednet.send(hostid, isvers, "version")
  hostid, message, version = rednet.receive(1)
  if message==nil then
   print("Error, host did not respond in time!")
   error()
  elseif message=="ok" then
   print ("Versioncheck ok")
   getmap()
  else
   print ("Versioncheck not ok, please get the latest version!")
   error()
  end
end

function getmap()
  file = fs.open("map1", "w")
  hostid, map1, TCiP = rednet.receive()
  file.write(map1)
  file.close()
  map1 = paintutils.loadImage("map1")
  clear()
  paintutils.drawImage(map1, 0, 0)
end
function sendinitial()--Send the initial data
  rednet.send(hostid, clientid)
  hostid, message, TCiP = rednet.receive()
  if message=="ok" then
   clear()
   print("Please enter your password!")
   passwd = read()
   rednet.send(hostid, passwd, "pass")
   hostid, response, TCiP = rednet.receive(2)
   if response=="ok" then
	getinfo()
   else
	print ("An error occured. Please reconnect!")
	error()
   end
  else
   print ("Error! Your Computer is not registered!")
   error()
  end
end
--Print header
clear()
print ("Irgendwas by onix331")
print ("Version ", ver)
os.sleep(2)

--Fire up the main program
pair()
sendinitial()
end
function starthost()
print("Initialising...")
rednet.open("top")
rednet.host("TCiP", "authost")

idok = "0"
pwok = "0"

ids = {}
pws = {}

file = fs.open("listedids", "r")
if file then
  local line = file.readLine()
  while line do
   table.insert(ids, line)
   line = file.readLine()
  end
  file.close()
end

file1 = fs.open("passwds", "r")
if file1 then
  local line = file1.readLine()
  while line do
   table.insert(pws, line)
   line = file1.readLine()
  end
  file1.close()
end

function getclientver()
  clientid, clientvers, protocol = rednet.receive(2)
  if clientvers==nil then
   print ("Version check failed")
   receive()
  elseif clientvers==requiredvers then
   print ("Version check ok")
   rednet.send(tonumber(clientid), "ok")
   sendmap()
  end
end

function sendmap()
  file2 = fs.open("map1", "r")
  if file2 then
   rednet.send(tonumber(clientid), file2.readAll())
   file2.close()
  end
  receive()
end

function idcheck()
  senderid, clientid, protocol = rednet.receive(20)
  for i=1,#ids do
   if clientid==ids[i] then
	rednet.send(tonumber(clientid), "ok")
	print("Idcheck ok (", clientid, ")")
	idok = "1"
   end
  end
  if idok=="1" then
   idok = "0"
   passwordcheck()
  else
   rednet.send(tonumber(clientid), "notexist")
   print("Idcheck not ok (", clientid, ")")
   receive()
  end
end
  
function passwordcheck()
  print ("Waiting for pw")
  clientid, passwd, protocol = rednet.receive(10)
  if passwd==nil then
   print ("Client waited too long, continuining...")
   receive()
  end
  for i=1,#pws do
   if passwd==pws[i] then
	rednet.send(tonumber(clientid), "ok")
	pwok = "1"
	print("Passwordcheck ok (", passwd, ")")
	passwd = ""
   end
  end
  if pwok=="1" then
   pwok = "0"
   getclientver()
  else
   rednet.send(tonumber(clientid), "wrong")
   print("Passwordcheck not ok (", passwd, ")")
   receive()
  end
end

function receive()
  while true do
   clientid, message, protocol = rednet.receive(2)
   if message=="pair" then--To pair to the client
	rednet.send(clientid, "succesfull")
	print ("Succesfull paired, continuing...")
	idcheck()
   end
  end
end
clear()
print ("Irgendwas by onix331")
print ("Version ", ver)
print ("Waiting for pair request")
receive()
end
if ishost=="0" then--To find out if program is run as host or client
startclient()
else
starthost()
end

I want to read the file "map1" and place the positions for the touchscreen where 1 stands. (1 is orange i think). But i found no way to do it.
(Map is created by using "paint" on an advanced wireless pocket computer)
The orange button should be used to switch between map1, map2, map3 etc.
Also i want to add buttons inside the map to open/close doors.


											   1
							  0
							  0
							  0
							  0
							  0
							  0
							  0
							  0
							  0
							  0
							  20000000000000000000000000
							  0
1							0
							  0
							  0
							  0
							  0
							  0
							  0
							  0
							  0
(The outstanding 0 seems to be an bug)
Like this. where 1 is, there should be a button (Orange) that should be clickable, and at 2 (Midscreen) there should be a button too. (Don't know which color).
All this should be dynamic, that means if i change the layout, it should detect automatically where the buttons should be
Edited on 17 January 2015 - 08:12 AM
Bomb Bloke #2
Posted 17 January 2015 - 01:37 PM
The "really simple" way is to just draw the image to your display, keep the table representing that image loading in RAM, and then compare mouse-clicks to it.

For example, at one point in your code you do this:

map1 = paintutils.loadImage("map1")

map1 now points to a table holding the data representing the image. map1[y][x] can be used to get the colour set at any given x/y co-ord.

This allows you to build something along the lines of this simple mouse-listener loop:

while true to
	local myEvent = {os.pullEvent("mouse_click")}
	
	if map1[myEvent[4]][myEvent[3]] == colours.orange then
		-- change maps
	end
end
Edited on 17 January 2015 - 12:37 PM
InDieTasten #3
Posted 17 January 2015 - 01:50 PM
I want to read the file "map1" and place the positions for the touchscreen where 1 stands. (1 is orange i think). But i found no way to do it.

Well, you need to open the file and parse the contents to a 2-dimensional table.
This way, whenever someone clicks at a certain position you lookup the coordinates in your table
and find either, the colorcode [0-F] a space or nil. The latter two are not buttons and from the first one you can identify the button of the code.


The parsing is pretty difficult though. I would do something like this:

function parseMap(path)
    local fh = fs.open(path, "r")
    if(not fh) then
	    error("Couldn't open file", 2)
    end
    local dump = fh.readAll()
    fh.close()

    local resultMap = {{}}
    local currentRow = 1
    local currentChar = 1

    for i = 1, #dump, 1 do
	    if(string.sub(dump, i, i) == "\n") then
		    currentChar = 1
		    currentRow = currentRow + 1
		    resultMap[currentRow] = {}
	    else
		    resultMap[currentRow][currentChar] = string.sub(dump, i, i)
		    currentChar = currentChar + 1
	    end
    end
    return resultMap
end

This is basically paintutils.loadImage() as I have noticed afterwards (facepalm) xD
Edited on 17 January 2015 - 12:53 PM
onix331 #4
Posted 17 January 2015 - 03:35 PM
Thanks! I will try to do this, i would have thought to get the x and y coordinates in the first way and then compare the mouseclicks. But this way it's simpler.

–onix331