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

multiglass - Now 101% less useless! (Now with multiple window support) (OpenPeripheral Glasses)

Started by blunty666, 04 September 2015 - 07:11 PM
blunty666 #1
Posted 04 September 2015 - 09:11 PM
Do you want to be able to use your computer from anywhere in the world, but are too cool for pocket computers? Then look no more…
multiglass


Download from pastebin:

For OpenPeripheral-Addons Version 0.4.x: BnCDV0b4

For OpenPeripheral-Addons Version 0.5.x: nTQN6hQA

Introducing multiglass, the program that is about 5 ComputerCraft versions too late! This program lets you run any program on your terminal glasses, and control them through your wireless keyboard, exactly like using a pocket computer. Just place a terminal glasses bridge next to your computer, connect your terminal glasses to it, and away you go.
Features:
- Works exactly the same as any regular advanced computer (apart from mouse_drag implementation, which is only available on 0.5.x version)
- Includes a toolbar that allows you to customise the size and transparency of the screen, as well as lock the screen so you can still see it when not using the wireless keyboard
- Has termination support through an extra button on the the toolbar
- It even works across dimensions!
- Each user has their own instance that only they can use (it isn't sandboxed though so be careful who you give access to!)
0.5.x New Features:
- Now has mouse_drag implementation
- Multiple windows!!!
- Uses new 'tiles' API which allows for easy rotation and re-scaling of windows
- Easier to use toolbar for window manipulation

Usage:
The program is available for download from pastebin:
- For OpenPeripheral-Addons Version 0.4.x: BnCDV0b4 (Does not require 'tiles' API)
- For OpenPeripheral-Addons Version 0.5.x: nTQN6hQA (Will also download the required APIs)
Once you've downloaded, all you need to do is provide the side the terminal glasses bridge is attached to as the first argument:
 multiglass
(Please note: You will probably need to change the GUI scale in your Minecraft settings to support larger window sizes.)
All code is also available on Github.
User guide:
Spoiler0.5.x version:

SpoilerWhen using the wireless keyboard, double left click anywhere in empty space to stop using the keyboard. Similarly, double right click in empty space to open a new window running CraftOS's multishell. You can then left click and drag the yellow surround of the window to move it around.

The windows can be resized by left clicking and dragging the black cross on the bottom right of the window.


The windows can be rotated and rescaled by right clicking and dragging the black cross on the bottom right of the window.


The window can be locked to remain open when you stop using the wireless keyboard by clicking the "L" in the top left of the window. Clicking the "S" in the top left opens a slider that lets you adjust the windows opacity. Finally, clicking the "T" in the top left will fire a terminate event to the currently running program (the button must be held down for around half a second).


0.4.x version:
Spoiler

The settings menu can be opened by clicking the 'S' in the toolbar below the window

(If you can't see the toolbar, type '$$settings' into chat and it should be open next time you use the wireless keyboard)


The settings menu can be repositioned in all four corners of the screen


It allows you to adjust the screen size and transparency

More screenshots!!!
Spoiler

By default the screen closes when you stop using the wireless keyboard, but it can be locked so that it remains visible at all times


As long as the attached computer is chunk loaded it will even work across dimensions


Some very strange orientations can be achieved in the new version!


Edited on 29 July 2017 - 03:48 PM
Cloud Ninja #2
Posted 04 September 2015 - 11:54 PM
This is actually really cool man! Ive always wanted to be able to use the shell pretty portable (although you could use a pocket computer) but now i can also have shell with my terminal glasses programs!
Konlab #3
Posted 06 September 2015 - 05:54 PM
offtopic
whats the ubertopsecretproject and minecraft tabs in the screenshots?
ontopic
i can imagine myself using this if i used openperipherals
its not the most useless program in the world,
its not useless at all!
Cloud Ninja #4
Posted 06 September 2015 - 07:15 PM
offtopic
whats the ubertopsecretproject and minecraft tabs in the screenshots?
ontopic
i can imagine myself using this if i used openperipherals
its not the most useless program in the world,
its not useless at all!
Its only downside is the lag, but you really cant fix that unfortunately.
blunty666 #5
Posted 07 September 2015 - 09:03 AM
Its only downside is the lag, but you really cant fix that unfortunately.
Yeah it's a bit of a pain, it doesn't seem to hit my framerate to hard though, which is an improvement on previous versions of openP. I think the lag is mainly caused by the delay and overhead involved in receiving player input through the wireless keyboard.

On a side note, you'll be interested to know that you're not technically limited to the screen size of regular computers. Try doubling the width and height variables on line 466! You may need to adjust the GUI scale in your Minecraft settings though. (EDIT: I've updated the OP to add this, including another screenshot to show it off!)
Edited on 07 September 2015 - 02:53 PM
Wojbie #6
Posted 11 September 2015 - 11:16 AM
Nice looking. This got me thinking. Would version with no color support became faster? That way instead of drawing each letter in a box you could do one big background for whole terminal. Height times addTexts one for each line. Only thing left is ClickCatcher that could also be thrown away. So technically downgrading a lot could lead to kinda faster end effect. I think i may try to make something like that just to compare how faster would it get.

On side note This thing is more useful than pocket for remote controlling turtles! Cause you can't see turtle trough the screen without some texture overwrites!.

EDIT1: Way you are stopping resuming program when terminal is disconnected can cause program to loose its timer event. Per exaple play worm and then disconnect for few seconds. After reconnection worm will be frozen. Also i can't seem to figure out way to cause terminate event to be called. That sounds like something that can be achieved by adding a control button.

EDIT2: Also why create more than one clickCatcher ? Can't you just make one covering whole screen and get coords someone clicked based on size of one letter box and 6,7 event returns. That would cut down 1/3 of elements drawn at one time? …. I am spending why too much time thinking about your program.
Edited on 11 September 2015 - 01:48 PM
blunty666 #7
Posted 11 September 2015 - 09:42 PM
…. I am spending why too much time thinking about your program.
Tell me about it, I've already sunk more time than is reasonable into this! It's addictive I'm sure of it…

As far as I'm aware it will continue to resume the timer events after you stop using the keyboard, it's just that the amount of time it takes to clear/draw the objects from the glasses means that it misses the timers when they get fired. Setting the 'resume' variable to false just means it doesn't resume the program with that event.

I thought about doing the text all in one line, the problem arose when using characters such as 'i' and 't', that aren't as wide as others like 'w'. It messed up the spacing of the lines which made it impossible to draw individual pixels. Using a single large 'clickCatcher' is a good idea though, using the current individual ones is a product of my laziness and wanting to implement it quickly without having to go through the maths of working out coords…

You're right about not being able to terminate, I was going to add a second redirect window with various controls to customise position, size, opacity of the main window, but then got sidetracked thinking of all the possibilities that it could lead to (multiple windows etc), which resulted in me getting nothing productive done!
Wojbie #8
Posted 11 September 2015 - 09:52 PM
maths of working out coords…

That would be for where x and y are click place and h,w are one letter size.

local function coords(x,y)
return math.floor(x/w),math.floor(y/h)
end
Yea… as i said. I am spending why too much time thinking. But implemeting that would cut down amount of element/redrawing by 1/3

As far as I'm aware it will continue to resume the timer events after you stop using the keyboard, it's just that the amount of time it takes to clear/draw the objects from the glasses means that it misses the timers when they get fired. Setting the 'resume' variable to false just means it doesn't resume the program with that event.
You could solve that by splitting program into two function run via parallel or some other coroutine manager, if redraws are on separate function from program it should not miss events right? They would just get lagged i believe? Ad-least that's what i used when i had problems with turles loosing modem-messages.

You're right about not being able to terminate, I was going to add a second redirect window with various controls to customise position, size, opacity of the main window, but then got sidetracked thinking of all the possibilities that it could lead to (multiple windows etc), which resulted in me getting nothing productive done!
Well thats one button to add below the screen and a special case for it ;D No need to overthink it.


EDIT: Also i think i will make my own version of this thing now… It sounds like fun project to try. If i am not back before fallout 4 send paramedics to my man-cave.
Edited on 11 September 2015 - 08:04 PM
blunty666 #9
Posted 11 September 2015 - 10:49 PM
maths of working out coords…

That would be for where x and y are click place and h,w are one letter size.

local function coords(x,y)
return math.floor(x/w),math.floor(y/h)
end

I've just uploaded a modified version that now only uses one clickCatcher box (same pastebin), seems to have improved the speed of drawing a bit, but still not enough to avoid the timer events getting missed in worm. A quick debug shows that the timers keep being received and sent to the program after exiting the capture, but when the screen is drawn again on re-capture, it is taking too long and missing the next timer which stops the worm program dead in its tracks!

EDIT: Also i think i will make my own version of this thing now… It sounds like fun project to try. If i am not back before fallout 4 send paramedics to my man-cave.
Haha, no problem, although I may be too busy playing it to remember!!! Let me know how you get on, I'm keen to see if there's a solution to the lag…
H4X0RZ #10
Posted 12 September 2015 - 01:26 AM
Are you redrawing everything (like completely clear and then draw everything again) or do you buffer (only redraw changes) it? If it's plain redrawing you should switch over to buffering. I guess it will help a lot!
blunty666 #11
Posted 12 September 2015 - 10:08 AM
Made another slight change that means the screen is set to be invisible when you stop using the keyboard, instead of clearing and redrawing it each time you start the capture again. Seemed to help with the problem of lost timers.


Are you redrawing everything (like completely clear and then draw everything again) or do you buffer (only redraw changes) it? If it's plain redrawing you should switch over to buffering. I guess it will help a lot!
By design, it needs to have a buffer so that it can redraw itself when you remove/re-equip the glasses, as they forget what is drawn on them if you are drawing to a private surface. And any changes you make to the onscreen objects are server side only until you call sync() on the glasses bridge, which then syncs the changes to the clients, although I'm not sure how they handle this behind the scenes (if they check for changes or just send all updates)? I tried including a check in the redirect buffer for actual changes when updating what is on screen, but here didn't seem to be any increase in speed. I'm not sure if the extra overhead needed for calculating if something has changed counteracted the reduction in screen updates?
Wojbie #12
Posted 14 September 2015 - 03:35 PM
Its me again! I got my version about 80% working. Lucky 78% code could have been taken from my WebTerminal project so it was a fast to code.

All you need to do to test it is to run


pastebin get e5NF1BCe Wojbie
pastebin get rBVzcYQN test
test [side] [Username]

where [side] is side where GlassTerminal sits and Username is username of only player allowed to interact with the terminal contents.


Right now its always drawn and visible. Will get it to only appear when keyboard is up later. Its set to mirror contents of terminal for test reasons (so i can see what was supposed to be on screen).
I also copied colors codes form my WebTerminal and i think they look more like original screen colors (with exception of dark green - need to work on that one). Also mouse_drag events don't work yet. Hope you like it!

Got a question to you anyways. How did you remove that green tint that appears when keyboard is used?
Edited on 15 September 2015 - 10:13 PM
blunty666 #13
Posted 14 September 2015 - 06:47 PM
I also copied colors codes form my WebTerminal and i think they look more like original screen colors (with exception of dark green - need to work on that one). Also mouse_drag events don't work yet. Hope you like it!
I do like it, especially the way you can mix multiple terminals together at the same time. I did notice that the cursor remains visible though even when cursor blink is off. I thought the colours looked better, gonna have to poach those off you!

I've seen that they've implemented mouse drag events in the latest version, but I'm yet to get round to trying it out. Not sure it's even been released yet?

Got a question to you anyways. How did you remove that green tint that appears when keyboard is used?
That's part of the capture control that you have to fetch each time a player starts using the keyboard. You get it by calling bridge.getCaptureControl(playerUUID) and then doing capture.setBackground(hexColour). I don't think there's a way to remove it completely so I resorted to setting it to white instead.

I looked into splitting the drawing functions into a separate parallel coroutine to see if that solved the delay of drawing the glasses objects, but it didn't seem to help. Might have a look at adding terminate buttons etc to mine this evening though…
Wojbie #14
Posted 14 September 2015 - 10:05 PM
That's part of the capture control that you have to fetch each time a player starts using the keyboard. You get it by calling bridge.getCaptureControl(playerUUID) and then doing capture.setBackground(hexColour). I don't think there's a way to remove it completely so I resorted to setting it to white instead.

I just figure it out!


local control = glasses.getCaptureControl(UUID)
control.setBackground(0xFFFFFF,0)
control.toggleGuiElements({["CROSSHAIRS"]=false})

This will remove all colors from overlay. setBackground has a visibility as secon argument. And it will remove Crosshairs from center of screen for capture!.
blunty666 #15
Posted 15 September 2015 - 08:44 PM
setBackground has a visibility as secon argument.
Ah nice one! Didn't realise that, well spotted.

And it will remove Crosshairs from center of screen for capture!.
Found this out yesterday when I was playing around with the latest version, fancy!!! Couldn't figure out how to enable the drag event though, or if it was even in the latest available version (0.4)? Might try the dev builds as I'm keen to see how it works…
Wojbie #16
Posted 16 September 2015 - 12:18 AM
Ok finished my program.
As before to test it all you need to do is to run

pastebin get e5NF1BCe Wojbie
pastebin get rBVzcYQN test
test [side] [Username]

Termination is handled by doubleclicking outside of terminal window. Also changed 2 colors hex values to fit ones on the wiki. Amazingly i got rest of them correct from my prinscreen+paint pick a color adventure. Autoactivates on all glasses when anyone opens the keyboard. Only owner can Write and generate events. And to my amazement its not as laggy as i expected.
blunty666 #17
Posted 21 September 2015 - 10:01 PM
And to my amazement its not as laggy as i expected.
I was impressed by how much less lag you have, so I've done the same as you and put the sync() function in its own coroutine and it's reduced the lag almost to zero! I've now ended up doing almost a complete re-write, the new version is available at BnCDV0b4. It only takes one argument which is the side the terminal bridge is connected on.

Each player has their own instance that they have full control over, and there is a toolbar that handles termination, window settings and lets you lock the screen so it remains visible when you stop using the keyboard. Will update the OP tomorrow when I have more time.
Wojbie #18
Posted 21 September 2015 - 10:32 PM
I love it! That menu stuff and settings and everything! Its great! :D/> This is 100% Useful stuff! I love it!
Edited on 21 September 2015 - 08:33 PM
blunty666 #19
Posted 22 September 2015 - 09:20 PM
I love it! That menu stuff and settings and everything! Its great! :D/> This is 100% Useful stuff! I love it!
Thanks!!! I've really enjoyed messing around with this, ended up sinking a fair few hours into it…

A couple of things I've learnt that may be useful to you: Firstly, the coordinates supplied by the 'glasses_component_mouse_up/down/etc' events start at (0,0) not (1,1) so I had to adjust them when working out the click position from the clickCatcher. Also, when glasses objects are drawn but set to not be visible, they will still trigger mouse events when clicked even though you can't see them. Not sure if this is a bug or not, but it had me confused for a while!
blunty666 #20
Posted 26 September 2015 - 05:50 PM
Minor update:
- Added mouse drag support, requires dev builds of openPeripheral Addons for now
- Added a way to open the settings menu if you can't see/click the toolbar button, just type '$$settings' into chat.
- Fixed not clearing the global bridge surface on startup (just in case!)

Still at the same pastebin location.
Creator #21
Posted 13 October 2015 - 07:11 PM
This is amazing. I think you deserve a +1.
blunty666 #22
Posted 14 October 2015 - 07:31 PM
This is amazing. I think you deserve a +1.

Thanks!!! \o/
FUNCTION MAN! #23
Posted 16 October 2015 - 02:43 AM
Now add multiple panel support!
blunty666 #24
Posted 25 October 2015 - 07:13 PM
Now add multiple panel support!

Don't worry I'm working on it! To help improve performance to make this possible I have a new version to share. The windows now have an active buffer and an update buffer which allows the 'term' functions of the window to perform at the same speed as the vanilla CC windows. The new function, 'pushUpdates()', pushes any changes in the update buffer to the active buffer and updates the screen in the process. Hopefully this will keep the lag to a minimum when I get round to having multiple windows on the screen, just need to work out how I want to implement this now…

The Dev version is available at pastebin: nTQN6hQA
(Requires OpenPeripheralAddons dev build 218 or greater)
blunty666 #25
Posted 01 January 2016 - 03:02 PM
Now add multiple panel support!

You asked and I have provided!!! It will need the newest version of OpenPeripheral-Addons to work, but let me know what you think!

Same pastebin as above.
FUNCTION MAN! #26
Posted 01 January 2016 - 03:25 PM
Awesome!
Pyuu #27
Posted 02 January 2016 - 02:03 AM
Now, we need more programs like this one in CC. It's creative, and well designed.
Saadar #28
Posted 03 October 2016 - 11:05 PM
Hi there, i wanted to try out your code and i couldn't run the code, so i saw that theres a problem with the code
I'm no specialist, but i changed this(line 1201):
    local surfaceHandler = tiles.new(playerSurface)

    local player = {
	    capture = bridge.getCaptureControl(playerUUID),
	    surfaceHandler = surfaceHandler,
    }
to this:

    local capture = bridge.getCaptureControl(playerUUID)
    local surfaceHandler = tiles.newSurfaceHandler(playerSurface, capture)

    local player = {
	    capture = capture,
	    surfaceHandler = surfaceHandler,
    }
and it seemed to fix the issue.
Amazing job btw! Respect ;)/>
blunty666 #29
Posted 05 October 2016 - 10:29 PM

Thanks for letting me know! I've been working on this on and off for a while now and the latest code is only Github at the moment. I'll get the pastebins updated over the weekend and maybe do a quick installer for Github to try and avoid this issue going forward.
blunty666 #30
Posted 08 October 2016 - 09:21 AM

Ok so I've updated the pastebin to the latest version which will automatically download the required APIs when it runs. Give it a go and let me know if there are any problems.

The main change is that it now uses the 'guiTiles' API, and the windows are in their own API (the glassWindow API), so you can more easily create your own programs that use them if you want to.