Split multiplayer screen
FrancoJ

Hello, Im new in allegro

I'm making a multiplayer tetris and I want to do a split screen. It's a college proyect and I need to use sockets for the multiplayer with processes (fork()). My question, is it possible to do it? I understood I cant 'share' a display with two different processes simultaneusly using allegro, but is there any other way to do it? I saw the al_set_target_bitmap() function for this kind of things but I dont know how to apply this function and if i can do what i want with it.

Thank and sorry if my english is'nt good at all. ;D

SiegeLord

Only one thread can draw to an ALLEGRO_DISPLAY. Typically you'd just send data to that thread using whatever method you want (sockets, messages, ALLEGRO_EVENTs) and have it draw whatever you need.

In your case, it's a little weird as split screen usually implies a single game process with multiple controllers without any networking. If you want multiple game processes on separate computers communicating via sockets then you typically don't need to use a split screen, although you still could. Either way in that case you'd still have a single thread doing all the drawing (and the game logic), and the only place where multi-processing would come up is exchanging the game state between the game clients and the server.

There's an example in Allegro (ex_enet_client and ex_enet_server) that illustrate how to write a networked game that you could use as an inspiration.

Chris Katko

Yeah, split-screen games aren't multi-threaded (that is, it's not required).

Here's how I do it:

window_t  //each window can have multiple viewports
viewport_t  //each viewport has a screen position (x,y,width,height), and draws the game from its location (or in your case each player has their own separate game field)

So are you specifically TRYING to make a game where multiple threads run SEPARATE game simulations on the SAME computer? If not, just do the above.

IF SO, then you need a third thread. Each game simulation is in a thread, and then COMMUNICATES with the display thread to tell it what to draw.

The third alternative, is to play your "multiplayer game" not split-screen at all, but hosting the same game twice, each with their own window. So you still have two screens, but they're attached to their own, independent process with display.

gillius

Maybe what's meant is split-screen where the other half is the "remote" site -- i.e. Tetris clone where you control one side but you still see what the other player is doing. In that case you would not be sharing displays at all.

How complicated it gets depends only on the requirements for the project. I can imagine a way to do it that needs no server and trivial network code. If both clients don't interact, then latency and conflicts are not a concern, basically you are playing a local Tetris on one side and the other side is a remote view updated by the sockets. In this case you are just simply observing the other character and the "server" in "server/client" is not needed. I can imagine that would be quite sufficient for learning about sockets.

If you have a low-latency, high-bandwidth connection (actually it would be infinite bandwidth, zero latency if you were truly fork()ing), then you could just send the whole game state on each tick over the socket, and the remote side would be nothing but a renderer of that game state. The renderer would be the same for local and remote sides, the only difference is you wouldn't call update from a timer on the remote state. You'd need to add a way to transmit deltas of state if bandwidth is low, and a way to predict future user input if latency jitty is high (if jitter is low, no worries -- just the games won't be in sync, which is OK if you are not interacting with each other).

In this scenario, you'd fork before you set up Allegro. Then each game would set up Allegro with one display, with the renderer drawing just half of the screen.

Gideon Weems
SiegeLord said:

There's an example in Allegro (ex_enet_client and ex_enet_server) that illustrate how to write a networked game that you could use as an inspiration.

Holy heck, I was unaware of this example.

FrancoJ

Thanks to all for the help!

Like gillius said, my idea was to make that the display show my tetris in the left-half of the screen and in the right-half appear the opponent's tetris. Something like a battle tetris for two players. What I made at the beginning was to fork, one process do all the game logic and print the graphics and the other process sends my tetris state and receive the opponent's tetris state, all with sockets. Both processes communicate with simple pipes (i need to use it too). But I dont know how can I print the opponent state in the "game logic" process every time it changes. The ony way I thought was to call the function that prints in every part of the code to refresh the oponent's state in the screen, but probably it isn't the best way.

Thanks again and be patients with me, I'm newbie. ;D

gillius

Given this is just an academic exercise, assuming that there is infinite bandwidth, zero latency (pipes), and logic should all run on one of the two instances:

Given a standard game loop of "wait for game tick, update logic, render state to screen", the loop would differ between client and server side:

client side:

update logic = Capture local input (i.e rotate left, drop piece, etc.) and send to server. Receive state (location of pieces, scores, etc.) from remote server. If state is not received yet, use state from last execution. If receive more than 1 state, drop all but the last.
render state = draw current state to screen.

server side:

update logic = Capture local input, and remote input. If remote input is empty/not arrived, assume no action from remote. Update game state for both players. Send entire game state to the remote.
render state = draw current state to screen -- same as in client side

Thread #616688. Printed from Allegro.cc