Page 3 of 44

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Fri Mar 12, 2021 3:38 pm
by Hydreigon233
Getting LeMans 24 networking to work is impressive (due to the flexible and intricate nature of these comm boards). So far the only other games that do not link properly are Sega Rally 2 and Virtual On 2. Emergency Call Ambulance would be interesting to at least figure out because it's unknown why the cab goes through a network check despite it being only a single player game.

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Fri Mar 12, 2021 4:45 pm
by Bart
Ian wrote:With the current code tcp sending will start to block when the socket buffer is full. It needs the receiver to receive the data to unblock. We also used a blocking receive.

How can we improve things? How does it work on the real hw? It sends 64 requests? Does it just check once a frame to see if the data has actually been received?


It's been a while since I've done low-level socket programming but an asynchronous approach should be possible here. For our needs, boost::asio is probably easy enough unless SDL has something comparable. You should be able to send and receive asynchronously unless the underlying Model 3 netboard protocol requires that sort of lock-step synchronicity.

How big are the packets being being sent? They could be enqueued as well if an underlying socket buffer is full.

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Fri Mar 12, 2021 5:29 pm
by Ian
Sdl doesn't support asynchronous sockets. Generally such implementations are os specific. But you can easily just do the receiving in it's own thread so it doesn't block. It does the same. Using this approach we could easily just fill a vector array with the received data. Then the data can be read whenever the consumer needs it.

Maybe we could send the data like this
Struct DataChunk
{
Int addressOffset; // where we want to copy to
Int dataLength:
Uint8 data[0]; // c variable length array
}

I could just asynchronously fill a vector array with an array of DataChunk. Then this can be read whenever the consumer needs it.

Would this be sufficient? Or does anyone have any other suggestions.

I should add we can do something similar to stop tcp sends blocking. Just continously fill a buffer and have the sending work independently in it's own thread.

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Fri Mar 12, 2021 7:14 pm
by Bart
Ian wrote:Sdl doesn't support asynchronous sockets. Generally such implementations are os specific. But you can easily just do the receiving in it's own thread so it doesn't block. It does the same. Using this approach we could easily just fill a vector array with the received data. Then the data can be read whenever the consumer needs it.

Maybe we could send the data like this
Struct DataChunk
{
Int addressOffset; // where we want to copy to
Int dataLength:
Uint8 data[0]; // c variable length array
}

I could just asynchronously fill a vector array with an array of DataChunk. Then this can be read whenever the consumer needs it.

Would this be sufficient? Or does anyone have any other suggestions.

I should add we can do something similar to stop tcp sends blocking. Just continously fill a buffer and have the sending work independently in it's own thread.


Wow, I'm amazed SDL_net doesn't have an async implementation. boost::asio introduces a nasty boost dependency (and asio is not header-only, unfortunately) so I think having send and receive threads would be the most straightforward way. Definitely a fan of not bringing in any more dependencies. :)

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Sat Mar 13, 2021 12:53 am
by sonic32
Network Works great (Daytona 2 and Le Mans 24) :shock:

I'm looking forward to the Scud Race,

Thank you, gm_matthew :)

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Sat Mar 13, 2021 2:01 am
by Spindizzi
Super things :)
If you need some specific values offset for all other games (offset, size), I have logged them. These values are normally retrieved when ring network is builded , in your case, inside "netboard_state_init" and set in "netboard_state_testing". Number of cab present on the ring are also determined inside state init

and many thanks for your awesome huge work on asm dissassembler.

In case, and for more generic code:
nets->Send((const char*)CommRAM + 0x100, 0x3214);
offset 0x100 is the inverted bytes of CommRAM[0xc] (16b endian thing)
and
memcpy(CommRAM + 0x450, recv_data.data(), recv_data.size());
offset 0x450 is the inverted bytes of CommRAM[0x8] (16b endian thing)

can't wait to study your work

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Sat Mar 13, 2021 3:22 am
by nuexzz..
@gm_matthew my respect so you don't keep your research just for you and share it .

Thank you

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Sat Mar 13, 2021 8:37 am
by gm_matthew
Spindizzi wrote:Super things :)
If you need some specific values offset for all other games (offset, size), I have logged them. These values are normally retrieved when ring network is builded , in your case, inside "netboard_state_init" and set in "netboard_state_testing". Number of cab present on the ring are also determined inside state init

and many thanks for your awesome huge work on asm dissassembler.

In case, and for more generic code:
nets->Send((const char*)CommRAM + 0x100, 0x3214);
offset 0x100 is the inverted bytes of CommRAM[0xc] (16b endian thing)
and
memcpy(CommRAM + 0x450, recv_data.data(), recv_data.size());
offset 0x450 is the inverted bytes of CommRAM[0x8] (16b endian thing)

can't wait to study your work

I've traced that the send/receive offsets and sizes actually come from the mainboard before the netboard 68K is executed; the mainboard writes 0x3ef0 to netRAM[0x402] and 0x350 to netRAM[0x404], and the netboard performs calculations on those to produce the send/receive offsets and sizes and stores them in four 16-bit words starting at netRAM[0x500]. When self-testing is complete the netboard also writes them within the first few bytes of CommRAM/netBuffer (where they are read by the mainboard), which is why my simulated netboard does the same thing only in my case the offsets and sizes are hard-coded as they always end up the same regardless of the number of linked machines.

For N linked machines, the send/receive size has to be at least 848(N - 1) + 100. 16 linked machines require 848*15 + 100 = 12820, or 0x3214 which is why I hard-coded that value when calling the nets->Send() function. For my proper implementation I'm planning to adjust the send/receive size depending on the number of linked machines which would cut down on network bandwidth if there are fewer than 16.

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Sat Mar 13, 2021 4:13 pm
by Ian
That works out about 5-6 mbit. Fairly fast. I bet you could drastically reduce it with compression.

I'd love to see scud working properly. The cars end upside down it's crazy.

Will try and finish async tcp functions this weekend if I have time

Re: Simulated netboard - future of linked play in Supermodel

PostPosted: Sat Mar 13, 2021 5:02 pm
by Jiterdomer
Good luck, my friend! Does it also affect Harley and Dirt Devils networking?