QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: madscijr on November 23, 2021, 11:02:30 am

Title: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: madscijr on November 23, 2021, 11:02:30 am
Hi all,

I saw the "Multi Monitor" thread from July
which discussed the _SCREENMOVE command.

What if you want to simultaneously display different output on 2 or 3 different displays from one program?

For example if you wanted to make a flight or driving simulator where the middle monitor shows the front view, and the side view is displayed on the right/left monitors, or perhaps a simple game of Battleship where each player's view is in a different display. Or a game where screen 1 is the map and screen 2 is statistics. Etc.

With _SCREENMOVE it sounds like there is still just one screen per program. I suppose you could have a main program which drives display #1, and separate child programs running concurrently which control the other displays based on data sent from the main program (is there an efficient way to get 2 QB64 programs running concurrently on the same computer to talk to each other, besides reading & writing to a file?)

Anyway, has anyone done a simultaneous multi-display program in QB64?

Any information or advice appreciated...
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: Petr on November 23, 2021, 02:23:17 pm
Hi. I don't have two monitors to try. I think it could work something like this, in this case the default monitor is on the left, it will make a blue screen and the one on the right will make a red screen with the same resolution.

It's just a suggestion that may work, but only if you have your desktop set up as an extended, not as a copy of desktop. It is also a question of whether _DESKTOPWIDTH and _DESKTOPHEIGHT are then counted only for a specific monitor, or whether it contains the overall resolution. And this implies the need for a new function that could switch between individual monitors (to get their resolution), I do not know if you can use the _DEVICES function to this (I do not even have how to try it).

Code: QB64: [Select]
  1. 'let say, you have two monitors, both with resolution 1920 x 1080. Windows desktop is set as one screen with resolution 2x 1920 x 1080:
  2.  
  3. ScreenA = _NewImage(1920, 1080, 32)
  4. ScreenB = _NewImage(1920, 1080, 32)
  5.  
  6. Screen _NewImage(1920, 1080, 32)
  7.  
  8. _Dest ScreenA
  9. Cls , Blue
  10.  
  11. _Dest ScreenB
  12. Cls , Red
  13.  
  14. _PutImage (0, 0), ScreenA, 0
  15. _PutImage (1921, 0), ScreenB, 0
  16.  
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: Petr on November 23, 2021, 02:59:13 pm
So I found a way to try it but I have bad news. 1) after connecting two monitors (specifically, I found a VGA cable and connected a laptop to the second input of the monitor), the resolution of both monitors in windows 7 is set the same, accordingly with a lower resolution (extended desktop mode). QB64 coordinates can only be seen on the first monitor, the example above does not work (of course when using the correct resolution). So I tried the mouse. The mouse that moves to monitor number two in the system gets out of focus (probably that's the problem) and _MOUSEX stops responding and stays at the maximum level _DESKTOPWIDTH even if it moves on the right monitor, QB64 can't see it.

I tried it in QB 1.4 because on a laptop, I don't have a newer version of the IDE. So - it probably won't work.
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: bplus on November 23, 2021, 03:03:38 pm
Got 2 AI programs playing each other, they shared a data file that tracked the moves of each player. When the other player finished, the next player up had it's turn to play and add to data file it's move. Worked OK. The first player's duty at startup was to start a new data file. Probably had to start the 2nd AI after 1st player made it's move.

If you need several screens I would say developing them on the side and _putimage to screen when and where needed. Although QB64 is one screen PL you can program as if a Windows OS is controlling what and where things go. I've seen Keybone and _vince (maybe Petr or TempodiBasic too) start these and Rho Sigma has multiple-screens in his projects resume.
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: Petr on November 23, 2021, 03:50:13 pm

I made another attempt. So yes, two monitors can be used. If you have two monitors with the same resolution, you will do so in _DESKTOPWIDTH * 2, _DESKTOPHEIGHT. The program window is then drawn over both monitors, so if you want to solve it separately, you have to take this into account in the program. The program window simply splits between the two monitors. I took a picture of the result (the red area is the area of the program window), this time my monitors uses different resolution.


This code:

Code: QB64: [Select]

do this output:

  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: SMcNeill on November 23, 2021, 04:27:10 pm
I don't think the OP is talking about writing one program that spans two screens; what he's wanting is to produce two screens which can be positioned independently on each monitor.  Unfortunately, QB64 doesn't have "child windows", so I think the closest he can get to his desired results is with the main window and a separate console window.  That's all the "multi-screen" support we offer intrinsically.
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: Petr on November 23, 2021, 04:49:31 pm
Well, maybe I misunderstood. But if not, then now is verified, that if @madscijr has two monitors with a resolution of 1980x1050 and makes the main program SCREEN in 3960x1050 resolution, then it will be able to use _PUTIMAGE on this screen and place the graphic outputs anywhere in this area of the two monitors. So in my first case it would work, I only initiated one monitor with the SCREEN command, but for it to work on both, the called SCREEN must be large across both monitors.
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: Petr on November 23, 2021, 04:55:30 pm
And if @madscijr really wants more windows with graphic outputs on one monitor, then it can be done as well. Although they will not be classic windows as we perceive them, you can use _DEST, _SOURCE, _PUTIMAGE to make windows with graphic outputs, you can redirect any graphic or text output to them. Just use virtual screens...
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: Petr on November 23, 2021, 05:10:50 pm
@bplus i think, you talk about COMMON SHARED between two programs. Then is really possible runing more EXE files (windows), and run it with shared variables between this two or more programs. It is somewhere in forum...
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: OldMoses on November 23, 2021, 06:58:09 pm
My space flight project is one that I've thought about modifying to do something similar. Mind you, I've only thought about it, and have not tried any implementation. I really haven't used multiple monitor setups enough to fool with it.

It being a RPG utility, I could run a setup where the gamemaster would have one screen showing all the action and another monitor which would have only what the players would have access to.

I assumed that since only one screen could be drawn, one would just make a double width screen, draw the desired details on each half and _SCREENMOVE _DESKTOPWIDTH - _WIDTH(0)/2, 0 {or whatever ratio desired} to split between the two as a work around for not having two separate screens.

Alternatively, upon a certain condition being true one could move the screen at will with a _SCREENMOVE that alternates between 0 and _DESKTOPWIDTH +1

...well anyway, nothing would beat a try, but a failure...
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: bplus on November 23, 2021, 07:15:34 pm
@bplus i think, you talk about COMMON SHARED between two programs. Then is really possible runing more EXE files (windows), and run it with shared variables between this two or more programs. It is somewhere in forum...

No, the 2 programs access the same Data file. The programs can both be running on my computer or one on your computer and one on mine, as long as we can get the data file updates from both programs. We could just pass the data file back and forth between us at this forum. Would not be practical for real time action though. The program, Connect 4 AI, was tried at Steves old forum before he closed it to new members.
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: madscijr on November 23, 2021, 10:53:51 pm
@bplus i think, you talk about COMMON SHARED between two programs. Then is really possible runing more EXE files (windows), and run it with shared variables between this two or more programs. It is somewhere in forum...

Thanks everyone for your replies.

I would really prefer each screen be discretely seperate, and not treated as one big window where you plot each "screen" to a portion of the window, or dependent on both displays having the same resolution.

It sounds as though having seperately running programs that communicate to each other is the way.

Using a file to share data is probably fine for something like Battleship, or a D&D type game where the dungeonmaster sees their view on one screen and the players get a different view on screen #2, where screen updating doesn't have to be done in realtime.

But for realtime action games like a flight or driving sim (where you want to continuously update 3 displays with the front / left / right views), I think some more direct and faster method of communication between processes would be necessary.

So the shared variables you mention might be the answer. Do you recall what subject line to search the forums for?

Thanks again!
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: SMcNeill on November 23, 2021, 11:10:05 pm
In that case, I'd use OPENHOST and OPENCLIENT to form a TCP/IP connection between the two programs, ofwhich there are several examples already here on the forums via chat hosts and clients.
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: Petr on November 24, 2021, 10:41:25 am
I'm glad we finally came to a solution. I have to laugh at my English. This is not the first time I have answered something other than what the author of the topic asks. I apologize for that, but on the other hand, at least it's fun here, isn't it?

:)
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: FellippeHeitor on November 24, 2021, 10:44:24 am
(...) but on the other hand, at least it's fun here, isn't it?


:)

🤗
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: madscijr on November 24, 2021, 02:45:45 pm
In that case, I'd use OPENHOST and OPENCLIENT to form a TCP/IP connection between the two programs, ofwhich there are several examples already here on the forums via chat hosts and clients.

TCP/IP between two programs on the same machine?
Interesting...
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: SMcNeill on November 24, 2021, 02:56:50 pm
TCP/IP between two programs on the same machine?
Interesting...

An example for you for testing purposes:

A lot of folks are curious about how we can get our programs to talk to each other, and curious about how we'd use QB64 to communicate via TCP/IP over a network.  The wiki has a few examples, but they tend to be outdated and simply don't work for me.  (Such as the mini-messenger  example here: http://www.qb64.org/wiki/OPENHOST.) I figured people might like a working example of how to get all the proper parts working together, so I tried various wiki samples and eventually decided to rework one until I got it to working for me...

The finished code here is working as intended on Windows. (I dunno if it'll work for Linux or Mac users, but I'd love to hear if it does or doesn't.)  Instead of a single set of code which tries to toggle between client and host, I worked this up as two separate sets of code -- one for each.   Copy one set of code into QB64, and then run it.  Then, while that program is still running in the background, copy the second set of code and run it..  Type in either program and watch as they happily communicate with each other without any issues.

THE HOST:
Code: QB64: [Select]
  1. DIM SHARED Users(1 TO 1000) ' array to hold other client info
  2. DIM SHARED NumClients
  3.  
  4.  
  5. PRINT "[Steve's Mini Messenger]"
  6. host = _OPENHOST("TCP/IP:7319") ' no host found, so begin new host
  7. IF host THEN
  8.     PRINT "[Beginning new host chat session!]"
  9.     NumClients = 0
  10.     client = _OPENCLIENT("TCP/IP:7319:localhost")
  11.     IF client = 0 THEN PRINT "ERROR: could not attach host's personal client to host!"
  12.     INPUT "Enter your name:", myname$
  13.     'PRINT #client, myname$ + " connected!"
  14.     PRINT "[Chat session active!]"
  15.     PRINT "ERROR: Could not begin new host!"
  16. END IF ' host
  17.  
  18.  
  19. DO ' host main loop
  20.     newclient = _OPENCONNECTION(host) ' receive any new connection
  21.     IF newclient THEN
  22.         NumClients = NumClients + 1
  23.         Users(NumClients) = newclient
  24.         PRINT "Welcome to Steve's Mini Messenger!"
  25.     END IF
  26.     FOR i = 1 TO NumClients
  27.         GetMessage Users(i) 'check all clients for a message
  28.         IF out$ <> "" THEN
  29.             l = LEN(out$)
  30.             FOR j = 1 TO NumClients ' distribute incoming messages to all clients
  31.                 PUT #Users(j), , l
  32.                 PUT #Users(j), , out$
  33.             NEXT
  34.         END IF
  35.     NEXT i
  36.  
  37.     SendMessage myname$, mymessage$, client
  38.     _LIMIT 30
  39.  
  40.  
  41. SUB GetMessage (client) ' get & display any new message
  42.     GET #client, , l
  43.     IF l > 0 THEN
  44.         out$ = SPACE$(l)
  45.         GET #client, , out$
  46.         VIEW PRINT 1 TO 20
  47.         LOCATE 20, 1
  48.         PRINT out$
  49.         VIEW PRINT 1 TO 24
  50.     ELSE
  51.         out$ = ""
  52.     END IF
  53.  
  54. SUB SendMessage (myname$, mymessage$, client) ' simple input handler
  55.     k$ = INKEY$
  56.     IF LEN(k$) THEN
  57.         IF k$ = CHR$(8) AND LEN(mymessage$) <> 0 THEN
  58.             mymessage$ = LEFT$(mymessage$, LEN(mymessage$) - 1)
  59.         ELSE
  60.             IF LEN(k$) = 1 AND ASC(k$) >= 32 THEN mymessage$ = mymessage$ + k$
  61.         END IF
  62.     END IF
  63.     VIEW PRINT 1 TO 24
  64.     LOCATE 22, 1: PRINT SPACE$(80); ' erase previous message displayed
  65.     LOCATE 22, 1: PRINT myname$ + ": "; mymessage$;
  66.     IF k$ = CHR$(13) THEN ' [Enter] sends the message
  67.         IF mymessage$ = "" THEN SYSTEM ' [Enter] with no message ends program
  68.         mymessage$ = myname$ + ":" + mymessage$
  69.         l = LEN(mymessage$)
  70.         PUT #client, , l
  71.         PUT #client, , mymessage$
  72.         mymessage$ = ""
  73.     END IF
  74.     IF k$ = CHR$(27) THEN SYSTEM ' [Esc] key ends program

THE CLIENT:
Code: QB64: [Select]
  1.  
  2.  
  3. PRINT "[Steve's Mini Messenger]"
  4. client = _OPENCLIENT("TCP/IP:7319:localhost") ' Attempt to connect to local host as a client
  5. PRINT "[connected to " + _CONNECTIONADDRESS(client) + "]"
  6.  
  7. INPUT "Enter your name: ", myname$
  8. out$ = myname$ + " connected!"
  9. l = LEN(out$)
  10. PUT #client, , l
  11. PUT #client, , out$
  12.     GetMessage client
  13.     SendMessage myname$, mymessage$, client ' display current input on screen
  14.     _LIMIT 30
  15.  
  16. '.................... END OF MAIN PROGRAM ................
  17.  
  18.  
  19. SUB GetMessage (client) ' get & display any new message
  20.     GET #client, , l
  21.     IF l > 0 THEN
  22.         out$ = SPACE$(l)
  23.         GET #client, , out$
  24.         VIEW PRINT 1 TO 20
  25.         LOCATE 20, 1
  26.         PRINT out$
  27.         VIEW PRINT 1 TO 24
  28.     ELSE
  29.         out$ = ""
  30.     END IF
  31.  
  32. SUB SendMessage (myname$, mymessage$, client) ' simple input handler
  33.     k$ = INKEY$
  34.     IF LEN(k$) THEN
  35.         IF k$ = CHR$(8) AND LEN(mymessage$) <> 0 THEN
  36.             mymessage$ = LEFT$(mymessage$, LEN(mymessage$) - 1)
  37.         ELSE
  38.             IF LEN(k$) = 1 AND ASC(k$) >= 32 THEN mymessage$ = mymessage$ + k$
  39.         END IF
  40.     END IF
  41.     VIEW PRINT 1 TO 24
  42.     LOCATE 22, 1: PRINT SPACE$(80); ' erase previous message displayed
  43.     LOCATE 22, 1: PRINT myname$ + ": "; mymessage$;
  44.     IF k$ = CHR$(13) THEN ' [Enter] sends the message
  45.         IF mymessage$ = "" THEN SYSTEM ' [Enter] with no message ends program
  46.         mymessage$ = myname$ + ":" + mymessage$
  47.         l = LEN(mymessage$)
  48.         PUT #client, , l
  49.         PUT #client, , mymessage$
  50.         mymessage$ = ""
  51.     END IF
  52.     IF k$ = CHR$(27) THEN SYSTEM ' [Esc] key ends program
  53.  

Have fun playing around with this as a local system messenger program.  Try it out, kick it around, and let me know if there's anything you don't understand about what it's doing.  This isn’t exactly how I'd normally write one of these; but that's because I started with what the wiki had and then gutted it and rebuilt it up until it was actually working  for me as it should.  Honestly, I think I would've been better off to have just wrote the whole program from scratch!  :P
Title: Re: Drawing different screens on different monitors from 1 program? (Multi Monitor)
Post by: OldMoses on November 24, 2021, 03:26:33 pm
Now that was a refreshing experience. I got in a chat war with myself. You should have seen the insults... ;)