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

terminal glasses as computer/turtle interface

Started by Crucidal, 09 January 2014 - 02:57 PM
Crucidal #1
Posted 09 January 2014 - 03:57 PM
Hey,

I've recently started experimenting with terminal glasses and I've got a question about terminal redirecting.

I've managed to make a computer listen to my chat_commands and make it run my commands via shell.run() (using parallel programming)
I'd like to see the terminal via my glasses, completely as you would when you normally access a computer or turtle.

Now when I wrap the terminal glasses bridge: p = peripheral.wrap("bottom")
and then redirect the terminal: term.redirect(p)
it'll give me an error:

Redirect object is missing method isColour. Restoring.

Now i'm not surprised that this isn't working because of course the bridge merely sends information back and forth and it's the glasses that should actually draw/write the output… but is there a way to get the terminal output?

Greetings,

Crucidal | Chris
CometWolf #2
Posted 09 January 2014 - 04:02 PM
Redefine write and print so they render on your glasses aswell.

Or use this
http://www.computerc...243#entry155243
Edited on 09 January 2014 - 03:24 PM
Crucidal #3
Posted 09 January 2014 - 04:41 PM
thanks for such a quik reply!

I'd rather write my own code and use snippets of examples rather than using somebody else's. I've downloaded it and taken a good look at it though.
Creating a fake monitor object is really clever and probably works well… but it's a little too complicated for me at the moment.

Redefining write and print seems like a viable option only I'm not really succeeding yet…

At the moment I'm working from an example:

local oldprint = print
print = function(…)
oldprint("In ur print!");
oldprint(…);
end

when I use this code It'll tell me that there's no such program… even when I put – in front of the oldprint lines.


Any clue why?

edit: I randomly guessed that the function print might not be publicly accesible to my program so I loaded the api like this "os.loadAPI(Term)" it made no difference :(/>
Edited on 09 January 2014 - 03:48 PM
CometWolf #4
Posted 09 January 2014 - 04:49 PM
Is that the actual code? cause this works just fine for me

local oldPrint = print
print = funciton(...)
  oldPrint"we takin ovah"
  oldPrint(...)
end
print"test"
prints
"we takin ovah
test"
Crucidal #5
Posted 09 January 2014 - 04:59 PM
This is my actual code. I've quickly added some comments.

Spoiler


p = peripheral.wrap("bottom") --wraps the terminal glasses bridge
line = 0 --starting position of cursor in a chatbox
myWidth = 480 --practical # equals the whole width of my screen
myHeight = 270 -- see above

local function init() -- I use this function to initialize and refresh the TG-interface
p.clear()
line = 0
--from here
bwidth = 190
bheight = 56
twidth = 100
theight = 75
box = p.addBox(180,0, bwidth, bheight, 0x000000, 0.2)
box.setColor(0xCC0000)
test = p.addBox(myWidth-twidth,myHeight-theight, 201,201, 0x000000, 0.2)
test.setColor(0x000000)
--to here I define 2 boxes. test will be the actual terminal once it fully works.
end

local function say(something, name) -- this function adds a line to the box until it is full and then resets the box.
if(line*8 > bheight-1) then
init()

line = 0
end

--Here I break lines that are longer than my box.
if p.getStringWidth(something) > bwidth then
some = string.sub(something, string.len(something)/2, string.len(something))
thing = string.sub(something, string.len(something)/2+1, string.len(something))
p.addText(180,8*line, name .. ": " .. some, 0xFFFFFF)
line = line+1
os.loadAPI(Term)
p.addText(180, 8*line, name .. ": " .. thing, 0xFFFFFF)
line = line+1
else
p.addText(180, 8*line, name .. ": " .. something, 0xFFFFFF)
line = line+1
end
end

--returns the command I wrote and tries to execute it in the shell
local function echo()
event, command, name = os.pullEvent("chat_command")
say(command, name)
shell.run(command)
end

--making sure that it keeps listening after every command
local function listen()
  while true do 
    echo()
  end
end

local tprint = print
local twrite = write
print = function(...)
tprint(...)
say(...)
end

write = function(...)
twrite(...)
say(...)
end

--starting.
init()
listen()
CometWolf #6
Posted 09 January 2014 - 05:03 PM
What's the full error message, most importantly the line number?
Crucidal #7
Posted 09 January 2014 - 05:06 PM
No such Program

There's no error :P/>

I was thinking: Currently my method say() is not getting the right arguments as it needs a username as well… but even if I put – in front of both say() lines it will give me this message…
Lyqyd #8
Posted 09 January 2014 - 05:07 PM
What did you do to generate that error?
Crucidal #9
Posted 09 January 2014 - 05:09 PM
Oh, I might have to clarify something:

What I did: start the program and then type $$something in the chat. something isn't a program… so that's why it is saying "no such program"…. :rolleyes:/>/>

When I type: $$help I see the usual response in the terminal but I see nothing via the interface

Running a non-existant program after redefining print returns the same thing, i can only assume it uses error() and not print() in this case. Idk, never really looked at the error function.

Edit: Indeed, shell uses a function called printError in the case of a non-existant program.

I'm starting to think that redefining print and write isn't all that easy… looking at the original write for example:

Spoiler

function write( sText )
local w,h = term.getSize()
local x,y = term.getCursorPos()

local nLinesPrinted = 0
local function newLine()
if y + 1 <= h then
term.setCursorPos(1, y + 1)
else
term.setCursorPos(1, h)
term.scroll(1)
end
x, y = term.getCursorPos()
nLinesPrinted = nLinesPrinted + 1
end

-- Print the line with proper word wrapping
while string.len(sText) > 0 do
local whitespace = string.match( sText, "^[ \t]+" )
if whitespace then
-- Print whitespace
term.write( whitespace )
x,y = term.getCursorPos()
sText = string.sub( sText, string.len(whitespace) + 1 )
end

local newline = string.match( sText, "^\n" )
if newline then
-- Print newlines
newLine()
sText = string.sub( sText, 2 )
end

local text = string.match( sText, "^[^ \t\n]+" )
if text then
sText = string.sub( sText, string.len(text) + 1 )
if string.len(text) > w then
-- Print a multiline word
while string.len( text ) > 0 do
if x > w then
newLine()
end
term.write( text )
text = string.sub( text, (w-x) + 2 )
x,y = term.getCursorPos()
end
else
-- Print a word normally
if x + string.len(text) - 1 > w then
newLine()
end
term.write( text )
x,y = term.getCursorPos()
end
end
end

return nLinesPrinted
end

shows a way more complicated method in comparison to my say() method… 0=)

Now I could try to edit this code but then I'll have to find workarounds for x,y and term.getCursorPos() (and basically all the term functions) … which seems like a lot of work :o/>/>
Edited on 09 January 2014 - 04:55 PM
CometWolf #10
Posted 09 January 2014 - 05:19 PM
Oh yeah, that stuff is a pain.
Here's my old terminal glasses print funciton

-- Queues prints to display
tPrintQueue = {}
tRemoveTimer = {}
tRemoveText = {}
function gPrint(msg,time,color)
  if not msg then
	return
  elseif type(msg) == "table" then
	for i=1,#msg do
	  gPrint(msg[i],time,color)
	end
	return
  end
  local msg = string.format(msg) or ""
  local tPrintOrder = {}
  local stringWidth = G.getStringWidth(msg)
  local lines = math.ceil(stringWidth/displaySizeX)
  local time = time or displayMessageTime*lines
  local color = color or displayTextColor
  local stringLength = #msg
  if lines < 2 then
	table.insert(tPrintOrder,msg)
  else
	while true do
	  for s=math.floor(displaySizeX/8),stringLength+math.floor(displaySizeX/8) do
		if not msg then
		  break
		end
		local stringWidth = G.getStringWidth(string.sub(msg,1,s))
		if stringWidth > displaySizeX-2 then
		  local endSpace = string.find(string.sub(msg,1,s),"%s.?$")
		  local lastSpace = string.find(string.sub(msg,1,s),"%s%S-$")
		  if endSpace then
		  --line ending in space
			table.insert(tPrintOrder,string.sub(msg,1,endSpace-1))
			msg = string.sub(msg,endSpace+1,#msg)
		  elseif lastSpace then
		  --line not ending in space
			table.insert(tPrintOrder,string.sub(msg,1,lastSpace-1))
			msg = string.sub(msg,lastSpace+1,#msg)
		  else
		  --word longer than line
			table.insert(tPrintOrder,string.sub(msg,1,s))
			msg = string.sub(msg,s-1,#msg)
		  end
		  break
	  --end of message
		elseif s >= #msg then
		  table.insert(tPrintOrder,msg)
		  msg = nil
		  break
		end
	  end
	  if not msg then
		break
	  end
	end
  end
  if displayDirection == "up" and #tPrintOrder > 1 then
	local size = #tPrintOrder+1
	local tRet = {}
	for i,v in ipairs(tPrintOrder) do
	  tRet[size-i] = v
	end
	for i=1,#tRet do
	  tPrintOrder[i] = tRet[i]
	end
  end
  for i=1,#tPrintOrder do
	table.insert(tPrintQueue,tPrintOrder[i])
	if time > 0 then
	  table.insert(tRemoveTimer,os.startTimer(time))
	  table.insert(tRemoveText,tPrintOrder[i])
	end
  end
  table.insert(tRunning,cDisplay)
end
Note that this is just for seperating the lines properly, not actual rendering. Anyways, what you're currently doing should get you going in the right direction, i mean it should atleast render something on your screen. If you redefine printError aswell that is, in the case of shell errors.
Edited on 09 January 2014 - 09:31 PM