Fast and accurate GameBoy Color emulator by sinamas. Based on 0.5-wip1.

How to compile library (for libretro)

git clone
cd libgambatte
make -f Makefile.libretro

1 Like

The colorization for non-Game Boy Color games has now been made a runtime option. It can be disabled or enabled using RGUI and/or RMenu and it will necessitate a retro_reset() call just to be safe.

is there any chance that the graphical glitch with F-1 Race will get fixed? (a flickering line between the ground and horizon) yeah, it actually doesn’t happen on the real hardware and it seems it was a regression introduced with version 0.5.0 . according to sinamas he had a fix which he wanted to implement, but I don’t know what happend since then. see this thread right here:

If they fix it upstream, we should get it automatically.

Gambatte dev is now hosted on github. To have the latest fixes, you could fork the repo and re-add the libretro stuff. (i dunno if this will fix F-1 Race btw)

I’ll look into this.

It’s an absolute priority though that all ports across all platforms libretro supports still works though.

So hopefully he will merge our changes when we do a pull request, otherwise the shallow fork will have no point.

Ugh, API got changed around. Will look at it when I have a less busy workschedule.

Perhaps maister will feel more like rebasing the port again.

New Gambatte version fixes the problem: waiting for RetroArch implementation.

In the meanwhile you can use these standalone builds

Could we also get a core option for “GBA mode”? In mainline Gambatte, this is enabled through “Settings – GBA CGB Mode”. This simply gives the game a way to tell that it’s running “on a GBA”; several games offer crappy, washed-out palettes when run on GBA, in order to counteract that console’s terrible screen, but more importantly, some games offer the player bonuses for playing on the newer platform (Shantae, Zelda Oracles). Behind the scenes, all it means is setting rB to 01 on boot–for this reason, it should force a reset just like colorization does now.

EDIT: Actually, if this is added, the “Force DMG Mode” setting could be added alongside it and combined into the same core setting. Force DMG will run even GBC games in original Game Boy mode, and there’s essentially no reason to do this and enable GBA mode at the same time, so a toggle which allowed the default, DMG or GBA modes should do the job of both settings. The only potential issue I see is how “GB Colorization” being set to “enabled” might conflict with “GB Mode” set to “DMG”.

EDIT 2: The result of that conflict is actually somewhat interesting: you can run backwards-compatible GBC games in DMG mode, with colorization as provided by the GBC bootrom, resulting in unexpected use cases like “colorized” Link’s Awakening DX or Wario Land II Color. I think leaving it as-is would work fine, even if it confused some.

You can add in the Gambatte emulator to press all buttons (a, b, start and select)? Games like Zelda Link’s awakening need this to save the game.

I know this is a bit of a necro, and is a somewhat niche case on my part, but I figured this might not be a bad place to start.

To preface, I have been trying to get two nintendo switches running retroarch on modded firmware to run a Netlink-enabled build of Gambatte to enable trading/battling using the original gamelink protocol of the first and second gen pokemon games.

I have recently compiled a Gambatte core build for Nintendo Switch with “HAVE_NETWORK = 1” set instead of the default “HAVE_NETWORK = 0”. I added the appropriate dependencies to the build files and managed to make a successful netlink enabled build for the switch.

The only hitch that I have hit so far is with the switch being in Network Server mode instead of Network Client mode. When in Client mode, the switch can connect to Linux and Android retroarch Gambatte Server setups. I have completed successful trades between two running instances, so long as either the Android device or the Linux (I’m pretty sure Windows builds will work as well, I just haven’t tested) build are set as the server, the Switch build in Client mode has no issues connecting.

When the Switch is in Server mode, and one attempts to connect to it with a client, of any kind, the client freezes in-game (in Pokemon, a text box is opened when engaging with the “link associate” standing in a pokemon center. When no link is made, a canned message is displayed, stating that the space is reserved for two linked players. When a link is established, a separate dialog is initiated to indicate that a save needs to be made before the link can be established with the attached console. The freeze occurs just before either of these texts can be displayed, and indicates that it was in the middle of trying to establish a connection with a device, rather than immediately failing and displaying the former script about needing two players.) until the server instance is closed on the server device (if you close retroarch on the server device, the client unfreezes and displays the canned message about needing two players to enter).

In my logs from Retroarch, I am also confirming a successful server instance being intitiated in the server devices logs, and a successful server detection by the client in the client’s logs. The freeze only occurs once the Pokemon game attempts to initiate the link for actual data transmission and linking.

Does anyone here have any in-depth experience with the netlink code involved in Gambatte and could help me with this? My next step was to do some really weird stuff like attempt to sniff the connections being made via Wireshark, but I fear this might be overkill and may yield nothing of real interest to me.

Hopeful that someone out there wants to help me get OG pokemon trading working on the Nintendo Switch before Ninty decides to release the OG roms via virtual console on the Switch in Nintendo Switch Online. (Currently that works for trading, but only between the same game files, like Red to Red or Blue to Blue trading. When attempting to cross-link games like Red to Blue, the emulator fails to load the game entirely on the client side).

I had always heard that the link cable protocol was too sensitive to latency to work over a network, but if I’m understanding you correctly, you’ve already gotten it working everywhere but when a Switch is the server, right?

If that’s the case, Wireshark may be useful just to see if the Switch just isn’t sending the right handshake signal, etc.

It has a bit of a delay to initiate the link, but my understanding of the pokemon link protocol specifically is that it sends the data in serial packets that are fairly one-sided and have a significant wait time to allow for a response to the packet.

I have video proof of a pokemon trade being made from a Linux Server host with a Nintendo Switch Client, all running within retroarch builds using Gambatte-netlink builds.

Thank you for the encouragement, I will try to see what I can find with Wireshark. :slight_smile:


After doing some wireshark learning, and then sniffing packets on the default gambatte netlink port (tcp 56400), I captured packets for a successful link and trade with linux as the server and nintendo switch as the client, and then attempted to capture packets of the switch as server and linux as client when it failed. When observing the successful link, there is clearly data transfer happening and the necessary bytes for a successful trade (and also battles, unsurprisingly) are visible as variations in TCP packets.

The discouraging portion thus far is that wireshark shows a push and acknowledge set of packets for the switch and linux setup with switch as server, but then when the link is attempted to be initiated in-game at the pokecenter with the link associate, the client game freezes (linux) and the server (nintendo switch) proceeds with talking to the link associate as if there is no connected second party. There are no packets shared between the server and client on port 56400 during this frozen state, but when the switch server closes retroarch completely, a reset tcp packet is sent out which unfreezes the linux client.

At this juncture, I’m unaware of what to poke at. I have attempted to set retroarch in full debug logging mode, and even built the gambatte core with DEBUG = 1 (didn’t seem to make any difference in the retroarch logs) and the logs only seem to indicate a successful connection between the client and server in both cases. The issue comes with the switch being the server, just as the in-game link is actually being initiated. There must be some core handshake that is either being blocked/redirected by another service on the switch, or there is still something wrong in my build of the gambatte core, but only with the server portion of the code…

I’ll keep trying to dig on this, but I wouldn’t mind any guidance from anyone more knowledgeable on the subject as well.

1 Like

Guys… I did it…

I guess I should say, WE did it. In a surprising (or unsurprising if you’ve been keeping up with recent tech news) turn of events, I decided to see if ChatGPT could help me with my dilemma of server mode not working on the Switch.

After a series of pointed questions from me, and several iterations of attempted compiling, with ChatGPT’s help (I basically just worded requests and let ChatGPT do all the code modification) I compiled a GameLink-enabled build that works on the Switch in both client AND server mode.

I tested it with current Gambatte builds on linux and android, in both server and client mode, and was able to trade and battle pokemon in the Gen 1 and Gen 2 pokemon games.

The best part about this code is that it is not pigeon-holed to only work with pokemon. It’s a general Gameboy Serial Link that is being emulated over TCP, and so games like Tetris and other multiplayer games should at least be moderately functional on a local network. I have not tested this for internet play, but with reasonable ping, I don’t see why it couldn’t be made to work.

To be clear, this functionality has been in the Gambatte core since August 2016, when Github user “UnimatrixX01” made a single large push to the gambatte-libretro repository. Their code has worked on Android, Linux, Windows, and probably many other platforms.

As the Nintendo Switch was not released until March of 2017, this particular git push did not have the Nintendo Switch in mind, so it was no wonder when I tried to build a GameLink enabled core for the Switch using the libnx libraries from DevKitPro and it failed to compile properly. I just got lucky that the largest majority of the groundwork was lain. I needed to update some deprecated calls from “gethostbyname” to “getaddrinfo” and then make sure that the socket initialization was robust enough that it would not fail with the switch as the server.

I took a couple weeks trying to figure out exactly what I was still missing, but then thought, “How about I ask ChatGPT if it can help me out?” I described my issues to ChatGPT, copy pasted my modified net_serial.cpp file into the chat prompt, and then requested that it modify the code to allow for better debugging errors. It suggested several points in the code to allow for extra error-handling, and also made the swap from “gethostbyname” to “getaddrinfo”.

After a few failed builds, I finally asked the right questions and provided the right information to the prompt, and ChatGPT spit out the code that built the fully-functioning Gambatte core for nintendo Switch. For kicks, I also compiled a Unix core, but have not attempted compiling a Windows core or Android core, because the Gamelink function from the Github build seems to work fine in both server and client modes for all existing other GameLink enabled builds.

Without further ado, I present a video of my and ChatGPT’s hard work in action:

If people are interested, I’ll upload my compiled NRO, or possibly even push my updated net_serial.cpp to the github, but I can’t imagine THAT many people are still emulating networked Gameboy games specifically on the Switch.

I did this as a project to give these two nintendo switchs to my nephews, because I wanted them to have the same original pokemon experience I had, but better. Who needs a stinkin LINK CABLE, amirite?

1 Like

man, congratulations, that’s great! I didn’t actually realize link-cable-over-TCP was already there at all until you mentioned it, so if you’d be interested in writing/recording a tutorial for doing it, I think a lot of people would be interested.

1 Like

I’ll see what I can whip together. I recently put together a guide for PicoFly installation over on GBAtemp, so it shouldn’t be too difficult to make a quick tutorial for setting up the GameLink :slight_smile:

1 Like

Since this is probably the most relevant place to post such a thing, I’ll first reiterate what is already gone over concerning GameLink emulation, in a cursory fashion on the libretro wiki in the docs regarding the Gambatte core.

First things first, make sure you are loading a “netlink”-enabled build of Gambatte on whatever platforms you are trying to link. In my case, I’ve loaded Unix, Windows, Android, and Nintendo Switch Gambatte cores that are netlink-enabled, and they all seem to be connectable with one-another with the proper settings.

To get to these particular settings, we must launch a Gameboy game in the Gambatte core to access the “Core Options” menu. To make sure that this menu shows up in the Quick Menu once the game is launched, we need to go to the Main Menu settings (Start on the Main Menu, and hit right once to get to the General Settings Tab), then scroll down to “Core” and enable “Core Option Categories” inside it if not already enabled.

Launch a Gameboy game in the Gambatte core, and then open the Quick Menu. From here, scroll down to “Core Options”, which may just be labeled as “Options” (for instance in older Android builds). Inside this Gambatte Core Options menu are all kinds of options to tweak the Core settings, but at the very bottom of the list is an option called Game Link; this is what we’re concerned with.

Inside the Game Link setting, there are three modes, “Not Connected”, “Network Server”, and “Network Client”. The important thing here is that one of your devices needs to be the Server, and the other needs to be the Client. We can leave the port at the default 56400, and then the remaining 12 options are to enter the individual digits of the Server device’s IP address. Technically you shouldn’t need to enter an IP address on the Server device, but for simplicity’s sake, I always enter the Server’s IP address on both the Client and Server devices.

Once you have both devices configured (Their Game Link options pages should be identical, but one should be Client while the other is Server), restart retroarch to ensure you reload the core and its options cleanly. When you launch the emulators, make sure you launch them within about 5-10 seconds of eachother, because they need to link up the way two original gameboys would when being linked by a physical cable. Any and all quirks of the original cable system should still be present with this system. More importantly, launch the Server device a little sooner than the Client device, so the Client device can connect to the Server once it launches.

At this point, the two emulators should be linked up, and whatever link process the game you loaded should be able to take care of the rest. I have even successfully played head-to-head Tetris between two Nintendo Switches on the same local network over wireless.

This should be enough to get you a working setup with GameLink in Gambatte. If you have any questions, I’ll do my best to help sort them out. :smiley:

1 Like