GBC serial link

Discussion in 'Other Handhelds' started by pepposole, Nov 8, 2016.

  1. pepposole
    OP

    pepposole Newbie

    Newcomer
    4
    0
    Nov 8, 2016
    Italy
    Hi guys!
    I'm studying console emulation and i tried to build my own Classic Gameboy emulator.

    Most of the functionality are done and working but i'm stucked with serial link emulation.

    The goal is emulate the cable link through the wifi/LAN but i really can't cope with very strict timings of the games.

    Most of the time the game go in timeout state because the Wifi network (or the LAN) is not fast enough to deliver data packets from one PC to another.

    I know this is possible because it exists an emulator called My Old Boy that work flawlessly in Serial Link emulation mode through my net.

    How do you think it works? It create a sort of empty packets in order to avoid timeouts? Or maybe it got a very fast way to send data through the network?

    Thank you
    Davide
     
  2. mammastuffing

    mammastuffing GBAtemp Regular

    Member
    107
    24
    Aug 7, 2015
    How have you currently implemented the link protocol?

    I've never written an emulator but I'm thinking you would have to adjust the clock speed in the link communication to match the speed of the network.

    Also, I would send the data over UDP for faster communication.
     
    Last edited by mammastuffing, Nov 8, 2016
  3. migles

    migles i'm a dude, i just enjoy pretty girls and money...

    Member
    GBAtemp Patron
    migles is a Patron of GBAtemp and is helping us stay independent!

    Our Patreon
    6,017
    3,976
    Sep 19, 2013
    Saint Kitts and Nevis
    my dad works for nintendo.
    i guess one other way is making the emulation pause while waiting for the packet to receive\sent... and resuming when the computer has the packet...
    this can work very well on pokemon games since they only send and receive info when the "please wait" message appears, but for real time games i don't have idea...
     
    Wolfvak likes this.
  4. FAST6191

    FAST6191 Techromancer

    pip Reporter
    22,914
    8,591
    Nov 21, 2005
    Option 2. Modern computers are powerful enough that you can emulate two GB/GBCs at the same time. Emulate them on a host PC and stream the footage (maybe also do something fun with savestates and make it a bit more transparent to the person joining) back to the client. If you are having latency and reliability issues inside the memory bus of a modern computer then you have gone very wrong somewhere. Still might not be ideal for twitchy/speed/reaction games but streaming low resolution video/VNC is a considerably more solved problem.

    After this you might explore the dark and murky world of UDP but don't as it will still not get you much further. Generally you are not going to get the latency down, you are going to suffer the odd dropped packet. It is old but damned if it is not still relevant http://www.gamasutra.com/view/feature/131781/the_internet_sucks_or_what_i_.php

    The trouble tends to come in the serial cable protocols being rather latency sensitive (as you read this if a packet takes 1000ms to make it to your computer then nobody would care really, for a game that is an age) and rather dropped packet sensitive (there not being many dropped packets in direct 1:1 cables less than 1m long and running on machines that are clocked barely into the MHz). As it is just games then nobody also makes robust code either -- oh dear tetris link failed is not as bad as oh dear bank link failed. For normal consoles that you would have been on the same couch for then you just stream the screen and take in button inputs when you are doing net play.
     
  5. mammastuffing

    mammastuffing GBAtemp Regular

    Member
    107
    24
    Aug 7, 2015
    I like this approach, although streaming the footage seems a bit too much. I'd probably go for a GGPO like solution in that case, where the input is sent instead for each frame and also use prediction for it. Meaning that you send your input for every frame and for every frame you haven't received input, you assume it was the same as the previous frame. When you receive the real input you might realise that your prediction was wrong. If that is the case, you roll back the game, put the correct input in, and then fast forward the game with all the inputs received up to the current time. I'd recommend that you look at the GGPO implementation if you find it interesting - it's a good solution for twitch games.

    The problem with TCP is that if you actually do suffer packet loss you will have to wait at least one round trip before being able to resend the data. So with a delay of 1000 ms one way, it would take at least 3 seconds before the receiver gets the data if a packet is dropped. With UDP you can write your own protocol. A simple approach would be to buffer every byte and send them all with every packet. With every packet you send you also acknowledge the last one you received. That way you can clear the buffer of every byte that has been acknowledged to been received.
     
  6. dpad_5678

    dpad_5678 GBAtemp Maniac

    Member
    1,128
    795
    Nov 19, 2015
    United States
    I can't really help but great job making a fully functional emulator! :) Cheers.
     
  7. pepposole
    OP

    pepposole Newbie

    Newcomer
    4
    0
    Nov 8, 2016
    Italy
    Great ideas!
    In the meantime i did some progress but i'm still far from the finish line.

    Now i can emulate it, with no problem, two instances of the emulator (connected by serial link) on the same machine.

    That's what i do.

    Every 8192 CPU cycles, emulator one send serial link state (data, clock and transfer flag) to the other emulator.
    Emulator-two do the same and wait for the emulator-one packet (if it's not already received).

    If transfer flags are set on both sides and clocks are different, then a serial data interrupt is raised in the same moment (at the same cycles) on both emulators.

    It works perfectly but this solution needs to exchange circa 1000 packets per second (since the clock of GB Color could reach 8Mhz).
    When the packets are sent through wifi, everything is getting really slow since the avg ping of my network is 3ms.

    If i try to exchange serial state every 16384 cycles, latency-sensitive games like Mario Tennis just drop connection.


    I also tried to dump traffic generated by two instances of My Old Boy connected through wifi.

    This is the PCAP.... and apparently it can keep connection perfectly running just exchanging TCP data even with 40ms+++ latency.


    http://www.dbtecno.it/upload/emu.pcap


    I'm running out of ideas =(
     
    Last edited by pepposole, Nov 15, 2016
  8. pepposole
    OP

    pepposole Newbie

    Newcomer
    4
    0
    Nov 8, 2016
    Italy
    OMG i got a vision thanks to Fast6191 suggestion...

    2 instances of the emulator running on machine A and 2 instances running on machine B.

    serial link is kept up between the instances on the same machine (getting rid of latency problems)

    * machine A *

    instance 1 takes input from keyboard
    instance 2 takes input through the network from machine B

    instance 1 video output is shown
    instance 2 got no video output nor sound output

    * machine B *

    same as machine A

    if two machines are CPU-cycles-synced, and input are exchanged in the same moment (and not necessarily VERY fast), machine A and machine B should show the exacly identical video output on screen....

    what do you think?
     
  9. FAST6191

    FAST6191 Techromancer

    pip Reporter
    22,914
    8,591
    Nov 21, 2005
    If you are playing a two humans game of chess, or an otherwise unrelated to each other game (two players playing their own levels that can not trouble each other but will compare high scores at the end or something) then sure.

    Trouble would likely arise though if you have random events (say pokemon, and believe me if you are writing an emulator doing link emulation for the general public you will sick of pokemon before all is said and done, has a move with 50% accuracy, virtual coin flip says machine A wins coin flip, B fails coin flip)) and computer AI maybe seeing different results happen, and I am not sure you can rely on any randomness generation being that broken/an expanded version of https://xkcd.com/221/ . At that point the emulators become desynced and you have traded a latency issue for a predictive input issue, something which is a nightmare for a full modern PC game you have coded yourself, let alone a 20 something year old closed source game that would never have dreamed of anything like this running in an emulator.
    Worse still what if someone makes a cheat?

    You could have some redundancy and sync savestates between them but leave one as a dummy machine until it drops or something, you might also get somewhere if you wanted to sync them with a dominant savestate (I am sure we have all had an online game make us move somewhere else when the lag drops down to a manageable level, same idea) or pause the emulation until one player comes back in.
     
  10. pepposole
    OP

    pepposole Newbie

    Newcomer
    4
    0
    Nov 8, 2016
    Italy