Jump to content




Monitor screensaver


  • You cannot reply to this topic
14 replies to this topic

#1 W00dyR

  • Members
  • 135 posts

Posted 09 May 2013 - 09:40 AM

Hey guys,

I am writing a simple screensaver which displays a picture in the center of a 3x5 monitor screen untill someone touches it. Now the problem I am having is that I have no idea how to pretty much get started with this.

So far I have my picture, printing that on the monitor, but that is pretty much it. I have read on the touch functions that come with the advanced monitor, but I am not sure how to use them.

My script so far:

mon = peripheral.wrap("back")
term.redirect(mon)
image = paintutils.loadImage("saver")
paintutils.drawImage(image, 15, 2)
term.restore()

Its not much, but its something that only prints out the picture. I am not sure how to do it, but I figured I will need a while true loop in there, with a certain timer.

To list it:
-Starts with screensaver
-Waits for monitor_touch event
-Displays other stuff
-After certain time, it will go back to screensaver
-Back to the start of this list

If anyone can help me out with this,

Thanks ahead :)

#2 W00dyR

  • Members
  • 135 posts

Posted 09 May 2013 - 10:16 AM

New updated code:

mon = peripheral.wrap("back")
term.redirect(mon)
image = paintutils.loadImage("saver")


while true do
  paintutils.drawImage(image, 15, 2)
  waiting = os.pullEvent(monitor_touch)
  term.clear()
  term.setBackgroundColor(7)
  term.setCursorPos(1,1)
  print("pls work")
  sleep(10)
  term.clear()
end

Current problem: It will not set the entire background color but only the background of the written text (The rest stays a random colour which originates from the last pixel in the picture), any idea how to do this? (Im not familiar with advanced monitors sorry :P)

Edited by W00dyR, 09 May 2013 - 10:19 AM.


#3 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 09 May 2013 - 10:21 AM

Swap term.clear and term.setBackgroundColor. term.clear sets the entire screen to a bunch of spaces with the set background.

#4 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 09 May 2013 - 10:27 AM

AND in term.setBackgroundColor(7) 7 should be colors.black or 32768 - 7 will set it to... magenta, I think.

#5 W00dyR

  • Members
  • 135 posts

Posted 09 May 2013 - 10:32 AM

View PostLBPHacker, on 09 May 2013 - 10:21 AM, said:

Swap term.clear and term.setBackgroundColor. term.clear sets the entire screen to a bunch of spaces with the set background.

That seemed to work, thanks.

Now what if I have this entire code, and instead of the -- print("pls work") -- I have a bunch of other code, that also waits for monitor events (touch screen menu pretty much), but I still want it to wait if nothing happens and return to the screensaver.

I read about the parallel.waitForAny() and waitForAll() , but where could I learn how to use this? I dont even know which I would have to use :P


View PostLBPHacker, on 09 May 2013 - 10:27 AM, said:

AND in term.setBackgroundColor(7) 7 should be colors.black or 32768 - 7 will set it to... magenta, I think.

I know, I just put a random number for testing :P Its set to 32768 now :)

#6 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 09 May 2013 - 10:40 AM

Yeah, this is one of the rare cases when you really have to use coroutines (unless the screensaver and the other menu thingie it the same program). I have to ask it though before giving an answer - is that menu thingie the only thing you want to run with the screensaver?

#7 W00dyR

  • Members
  • 135 posts

Posted 09 May 2013 - 10:48 AM

View PostLBPHacker, on 09 May 2013 - 10:40 AM, said:

Yeah, this is one of the rare cases when you really have to use coroutines (unless the screensaver and the other menu thingie it the same program). I have to ask it though before giving an answer - is that menu thingie the only thing you want to run with the screensaver?

Im not quite sure yet what kind of things I want to use for it. But the idea is pretty much, some kind of "main computer" which allows for controls of various kinds of things (accessible through the menu), those things being turning on and off certain redstone signals (bundled cables), sending out rednet messages and all those kind of things.

Whenever the computer is untouched for ~2-3 minutes, it will go back into screensaver mode and when touched, open the main menu again.

#8 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 09 May 2013 - 11:26 AM

Follow the comments, report the bugs.
Spoiler


#9 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 09 May 2013 - 11:58 AM

View PostLBPHacker, on 09 May 2013 - 10:40 AM, said:

Yeah, this is one of the rare cases when you really have to use coroutines
Not so. A screensaver normally pulls control, and then when a particular event occurs gives control back to the parent. Using coroutines means the OS or whatever would be running at the same time as the screensaver.

#10 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 09 May 2013 - 12:00 PM

View Posttheoriginalbit, on 09 May 2013 - 11:58 AM, said:

View PostLBPHacker, on 09 May 2013 - 10:40 AM, said:

Yeah, this is one of the rare cases when you really have to use coroutines
Not so. A screensaver normally pulls control, and then when a particular event occurs gives control back to the parent. Using coroutines means the OS or whatever would be running at the same time as the screensaver.
And that's why I didn't use them in the end.

#11 W00dyR

  • Members
  • 135 posts

Posted 09 May 2013 - 12:06 PM

View PostLBPHacker, on 09 May 2013 - 11:26 AM, said:

Follow the comments, report the bugs.
Spoiler

I'll be real honest here, I barely understand what exactly is going on so I can only thank you for this, but I don't quite understand it, as much comments as you wrote, is there any way to explain it in an easier way? :P (Sorry I'm not a LUA pro :P)

What my idea is of whats going on (As far as I understand it):

-Declare some variables for the timer & image
-Start the counter for the screensaver
-Wait for an event > Put the event in a table for easy usage
-If the event that happens is the timer finishing, it puts up the screensaver & goes back to the start
-If the event is not the timer finishing, it checks if the screensaver is up, if yes, then it prints the menu with all the things that happen in there & take down the screensaver
-Restarts the timer

And from this part I dont get what you mean with "process eventData here".

I might be completely wrong, sorry if that is the case :P

I still don't get how in this thing, it waits for a monitor_touch event WHILE the screensaver counter is going (as in, the menu is up, screensaver is off, it waits for a touch event, and aborts this if the timer hits 0), or is the fact that when the timer triggers, it reads it as an event, and replies to that by putting up the screensaver and restarting the while loop?

#12 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 09 May 2013 - 12:12 PM

View PostW00dyR, on 09 May 2013 - 12:06 PM, said:

when the timer triggers, it reads it as an event, and replies to that by putting up the screensaver and restarting the while loop
Exactly. Everything you've assumed is right. By "process eventData here" I meant to put your code there, so eg.
if eventData[1] == "monitor_touch" then
    print("yay")
end


#13 W00dyR

  • Members
  • 135 posts

Posted 09 May 2013 - 12:19 PM

View PostLBPHacker, on 09 May 2013 - 12:12 PM, said:

View PostW00dyR, on 09 May 2013 - 12:06 PM, said:

when the timer triggers, it reads it as an event, and replies to that by putting up the screensaver and restarting the while loop
Exactly. Everything you've assumed is right. By "process eventData here" I meant to put your code there, so eg.
if eventData[1] == "monitor_touch" then
	print("yay")
end

Alright so where you said print("yay") goes the other code for whatever screen it opens through touching the menu?

So in this part

if screenSaver then
       -- redraw the whole control panel
       -- (I prefer calling a function here that does that)
       screenSaver = false
       -- set the trigger up again
       screenSaverTrigger = os.startTimer(screenSaverTriggerTime)
 end

I put the code for JUST the menu (above "screenSaver = false" ?)

And where it sais "process eventData here" I put something like this

if eventData[1] == "monitor_touch" then
    print("Some kind of screen accessed through the menu")
elseif eventData[1] == "timer" then
    screenSaver = true
end

Also: On top of the code, first line after the "while true do", to print the screensaver, do I add in something like

if screenSaver then
    paintutils.drawImage(image, x, y)
end

To make it print the screensaver?

Thanks btw :)

#14 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 09 May 2013 - 12:29 PM

View PostW00dyR, on 09 May 2013 - 12:19 PM, said:

I put the code for JUST the menu (above "screenSaver = false" ?)
Yup.


View PostW00dyR, on 09 May 2013 - 12:19 PM, said:

if eventData[1] == "monitor_touch" then
	print("Some kind of screen accessed through the menu")
elseif eventData[1] == "timer" then
	screenSaver = true
end
The branch with "monitor_touch"? Yup. The one with "screenSaver = true"? Nope, because the screensaver is handled by the code I've written - you don't even have to touch screenSaver again.


View PostW00dyR, on 09 May 2013 - 12:19 PM, said:

if screenSaver then
	paintutils.drawImage(image, x, y)
end

To make it print the screensaver?
Don't think so. Since the screen gets redrawn if something happens, the screensaver has to be drawn only once anyways.

By the way, keep in mind, that ANY event will break the screensaver, even if a redstone signal turns on behind the computer, or it gets a message on rednet, or a disk drive gets removed next to it. You can put the part that breaks the screensaver into an IF-THEN that checks for specific events like "monitor_touch". I mean, if the only event that the computer is going to get is monitor_touch, we don't have to be so strict:
if eventData[1] == "timer" and eventData[2] == screenSaverTrigger then
    paintutils.drawImage(image, 15, 2) -- whatever that prints the screensaver
    screenSaver = true
end
-- we don't care if the event was eg. a redstone event - since
-- it wasn't a monitor_touch, the screensaver doesn't have to break
-- that's why we don't use a strict ELSE here
if eventData[1] == "monitor_touch" then
    -- this else branch will turn off the screensaver when any
    -- other event fires apart from the one that turns it on
    if screenSaver then
        -- redraw the whole control panel
        -- (I prefer calling a function here that does that)
        screenSaver = false
        -- set the trigger up again
        screenSaverTrigger = os.startTimer(screenSaverTriggerTime)
    end
end


#15 W00dyR

  • Members
  • 135 posts

Posted 09 May 2013 - 12:44 PM

View PostLBPHacker, on 09 May 2013 - 12:29 PM, said:

View PostW00dyR, on 09 May 2013 - 12:19 PM, said:

I put the code for JUST the menu (above "screenSaver = false" ?)
Yup.


View PostW00dyR, on 09 May 2013 - 12:19 PM, said:

if eventData[1] == "monitor_touch" then
	print("Some kind of screen accessed through the menu")
elseif eventData[1] == "timer" then
	screenSaver = true
end
The branch with "monitor_touch"? Yup. The one with "screenSaver = true"? Nope, because the screensaver is handled by the code I've written - you don't even have to touch screenSaver again.


View PostW00dyR, on 09 May 2013 - 12:19 PM, said:

if screenSaver then
	paintutils.drawImage(image, x, y)
end

To make it print the screensaver?
Don't think so. Since the screen gets redrawn if something happens, the screensaver has to be drawn only once anyways.

By the way, keep in mind, that ANY event will break the screensaver, even if a redstone signal turns on behind the computer, or it gets a message on rednet, or a disk drive gets removed next to it. You can put the part that breaks the screensaver into an IF-THEN that checks for specific events like "monitor_touch". I mean, if the only event that the computer is going to get is monitor_touch, we don't have to be so strict:
if eventData[1] == "timer" and eventData[2] == screenSaverTrigger then
	paintutils.drawImage(image, 15, 2) -- whatever that prints the screensaver
	screenSaver = true
end
-- we don't care if the event was eg. a redstone event - since
-- it wasn't a monitor_touch, the screensaver doesn't have to break
-- that's why we don't use a strict ELSE here
if eventData[1] == "monitor_touch" then
	-- this else branch will turn off the screensaver when any
	-- other event fires apart from the one that turns it on
	if screenSaver then
		-- redraw the whole control panel
		-- (I prefer calling a function here that does that)
		screenSaver = false
		-- set the trigger up again
		screenSaverTrigger = os.startTimer(screenSaverTriggerTime)
	end
end

Alright I think I get the idea :)

Thanks very much, Im leaving for a bit now, I'll be back later & I'll post if I come along any more problems :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users