Mysteries of the e-Reader: Part 1
Translating Pokémon e-Reader cards for English versions.
The e-Reader
The GameBoy Advance had a number of weird and wacky add-ons, a lot of them exclusive to Japan. But one that I’ve been quite interested over the last few years (and isn’t exclusive!) is the Nintendo e-Reader. This amazing device is essentially a barcode reader that scans in e-Reader cards that have dot codes printed on them. You could load in full NES games, Game and Watch games, new levels for Super Mario Advance 4: Super Mario Bros. 3 and new items for Animal Crossing to name a few. But today we’re looking at the Pokémon e-Reader Cards. The wonderful e-Reader
Converting Japanese Battle Tower cards to English
When I was a but a wee child I loved Pokémon but I was always disappointed in the lack of events in my country1. I later learnt that one Pokémon event, the Eon Ticket, was distributed as an e-Reader Card. Fortunately Australia was one of the countries that the e-Reader was released in, unfortunately the Eon Ticket e-Reader Card was not released here. But this did get me interested in what other e-Reader Cards there were for Pokémon. After some searching and becoming familiar with the different types of Pokémon e-Reader Cards I found this thread and github repo by háčky. They had already decompiled the majority of the e-Reader Cards, including the Eon Ticket! But all the e-Reader Cards here were ones that released in English, there were no Japanese exclusives. At that point I made it my mission to change that.
An e-Reader card with the dotcode on the bottom
I won’t go too in detail on what all the cards did2 but today we’ll be focusing on the cards made for Pokémon Fire Red and Leaf Green. These games were a remake of the original Red and Blue with a lot more content included, particularly in the post-game. There is a location in the games called the Trainer Tower located on Seven Island, where you could ascend an 8 floor battle gauntlet of trainers. Well unless you had a Japanese copy, then there were only 4 floors, because these versions of the games had an extra feature that made the Trainer Tower a whole lot more interesting. Using the e-Reader you could scan in a card containing a Pokémon trainer with a team of Pokémon for them to use. And, you could scan up to 8 of them, one for each floor!
The first thing I did was inspect the data of one of these e-Reader Cards. Doing so involves unpacking the card into a raw binary file of the original data as it is compressed into a vpk format. CaitSith2 had made a bunch of tools to assist with e-Reader development so decompressing the cards was pretty straightforward. Once I had the data I wiped the dust off my hex editor, loaded up the file and had a look. We’re greeted straight up with a pointer3, some data at 0x100
4, data at 0x700
and then even more data at 0xC56
. At this point I’m not really caring what all of the different data sections are for, I just want to find that juicy trainer data. Since the trainer teams are actually known, it was easy to find for data for them just by searching the trainer name, which points us to the 0x100
section of data. This data was set out similarly to the other Battle-e cards so creating a Python script I was able to extract the data into a more human readable format5.
For those curious the trainer data looks like this
- The first 4 bytes are: the card ID, the floor ID, the challenge type, and the prize.
- The next block of bytes is the trainers name in Pokémon’s text format.
- The first byte is the trainer class followed by the text colour that should be used when the trainer talks. The 2
0x00
bytes are for alignment.- To save space, these e-Reader card trainers make use of the easy chat system. When the trainer talks to the player instead of using a string and having one byte for each character a set list of words has been created in the game with each one being represented by 2 bytes. These trainers talk to the trainer 4 times, once before battle, once if the player loses, once if the player wins and once when the player interacts with them after winning. Each time the trainer can use up to 6 words from the easy chat list.
- The actual Pokémon data which is the species (2 bytes), the held item (2 bytes), the Pokémon’s moves (4 x 2 bytes), the Pokémon’s level (1 byte), any PP bonuses (1 byte), the Pokémon’s EV spread (6 bytes), the original trainer ID (4 bytes), the Pokémon’s IV spread and ability (4 bytes), the Pokémon’s personality value (4 bytes), the Pokémon’s nickname ( bytes) and the Pokémon’s friendship value (1 byte). There’s 5 more blocks like this to make a full team of 6 Pokémon.
So I know how it’s formatted but I still needed to get that data into the game. This is where the pokefirered decompilation project enters the scene. It is a complete recreation of Pokémon Fire Red and Leaf Green’s source code through reverse engineering. Fire Red and Leaf Green has the Mystery Gift option in the main menu but doesn’t have Mystery Event to read e-Reader cards. I would have to port that feature over from Emerald, which was actually fairly straight forward! Pokémon Emerald has both the Mystery Gift and Mystery Event features so I could figure out how to merge them together for Fire Red and Leaf Green. Copying over a couple of function from the pokeemerald project and changing some variable names to their Fire Red and Leaf Green equivalents got things working.
One thing I still don’t have working correctly though is a scrolling main menu. The addition of Mystery Event means that there’s too many options now and it currently still is off screen.
Now that we have a way for the games to handle the data I had to try it out. Scanning the card actually worked first go with no error! Like how there’s the old man’s house in Ruby and Sapphire, Fire Red has a house on Seven Island with an old lady who lets you battle the custom trainers, and quickly running to that house I could indeed battle them! Wait a second, that’s not what I wanted. I wanted them in the Trainer Tower!
A Tale of Two Mysteries
So before we go any further I should fully explain the Mystery Event feature and a Mystery Gift feature in the Gen 3 Pokémon games. Mystery Event is what I had worked with before when converting Ruby and Sapphire Japanese exclusive cards to English. You only scan in cards one at a time, with the thrainer data from the newly scanned card overwiting the old data. Trainers are then fought in Mossdeep for Ruby and Sapphire or Sootopolis for Emerald. On the other hand I had never worked with Mystery Gift cards, as I thought it was only for wireless adapter events. It turns out, however, that Mystery Gift is only in Fire Red and Leaf Green and Emerald and can use the wireless adapter or the e-Reader. Cards that are scanned into the games using this method are only for the Trainer Tower, or in Emerald’s case Trainer Hill (but that’s for another blog post).
Both methods require using a link cable to connect the game to another Game Boy Advance with the e-Reader plugged in. The Scan Card mode is used for Mystery Event and Communication mode is used for Mystery Gift. Using the Communication mode allows Fire Red and Leaf Green to send a small program, called a mulitboot program to the e-Reader for it to execute.
The multiboot feature allows the Game Boy Advance to boot data sent over the link cable rather than from a cartridge.
When it does run you’re greeted with quite a happy looking Pikachu giving you instructions on how to scan the cards. It’s all in Japanese but it’s not hard to figure out.
A Diglett pops up for every card scanned!
You can scan Battle Tower e-Reader cards one at a time, up to the full set of 8 which are stored in RAM before sending it all over. Attempting to scan the cards the other way through Mystery Event gives you a cute error screen. Which kindly tells you can’t use the Scan Card mode and must use the Communication mode.
Once I found out these cards were scanned in with the multiboot program I knew this was not going to be as easy as I thought.
Compiling Cards
Before I went digging into the multiboot program though, I wanted to make sure that I could make simple edits to the Battle-e cards that would work on the Japanese games. I did something simple, just change the Trainer’s first pokemon to something else. So I changed their Raticate to a Charizard. There is a checksum that I forgot about the first time I tried this but I was quickly able to fix that. After that I connected a Japanese version of the game, loaded the multiboot program on the e-Reader and scanned the e-Reader card. I got an error. Even with the correct checksum something was still wrong.
The checksum was simply a byte-sum of all the trainer data and was appended at the end in little endian format. Game Freak didn’t do many complex checksums for these games.
I used the program nedcmake which I had no problem using to compile other e-Reader cards but for some reason it didn’t work for these cards. I first tried remaking the first trainer in the set, Youngster Cole, without any edits but still had no success when trying to scan it, so I definitely knew it was the compilation process. But I had one e-Reader card that worked and one that didn’t for the exact same data so I looked at them side by side in a hex editor with Pan Docs6 open, which is a great resource for Nintendo handhelds. Comparing the two cards there was one byte in the vpk header that were different and consulting Pan Docs revealed that the byte actually had an unknown meaning. Maybe they’re related to cards being scanned in to a multiboot program? But I didn’t want to figure that out right now and instead focused on solving the issue. I ended up forking the source code of nedclib and modifying nedcmake. I only needed to change it slightly by adding a flag that would change the one byte of the e-Reader card header when it’s compiled. Lo and behold compiling now works!
With cards compiling now I could edit them to work for the English games. The Japanese games actually have shorter names for the trainer and Pokémon due to their letters being wider. All the Western language versions increased this since there was more space to use. So to convert the Japanese cards to English a couple of extra bytes were added to all the names and now they will, theoretically, work!
Multiboot of Madness
Whew, now that I knew I could actually create new cards I went digging into the multiboot program. I knew there would be 2 main changes that would need to be made to get the program into a working state, plus 1 nice to have change.
- Region Locking: The multiboot program was made for a specific language, and so probably performs checks on the e-Reader card’s language and possibly also checks the game’s language.
- Card Size: English card data would be bigger because English trainer names are bigger. The multiboot program would have to handle this larger size.
- Text Changes (nice to have): Since the muliboot program is for the Japanese games the text in it is, naturally, Japanese. Since I can’t understand Japanese I left this change for now.
With pokefirered both these things should be fairly easy to sort out. While most of pokefirered is decompiled code I discovered there are 3 multiboot program binaries which of course includes the e-Reader program we need to modify. The other 2 are a Berry fix program that fixes a bug with the RTC for Ruby and Sapphire and a program for Pokémon Colosseum.
Taking a look at the multiboot program with a hex editor I found that it looked just like a vpk archive, which made sense since it ran on the e-Reader. I went ahead and decompressed it and opened it up in a disassembler. It seemed to be correct but there was so much that I didn’t know where to start. So I gave up. Yep I did not touch it for weeks because I just didn’t know how to tackle it. I had worked with asm before but on a tiny scale to modify a single function, but this was a full on program that I’d need to dissect to figure out where the card data was handled.
After a few weeks of completely ignoring this project I went back to the archived glitch city thread to see if there was any little bit of information it could provided. Luckily there was. The first couple of pages dealt with the normal Battle-e cards for Ruby and Sapphire that I was used to, but the multiboot program and Fire Red and Leaf Green’s Battle-e cards were brought up later in the thread. Further discussions led to háčky detailing how the multiboot program works along with the data size it expects, what addresses it keeps the data in and language restriction placed on it. Importantly they mention that the program stores 0x3D4
bytes of data for each card in RAM.
Opening the multiboot program into a disassembler I began having a look around and did find several instances of 0x3D4
being used. Confirming that this was how big the trainer data was in unedited cards I found how big the data was for the English equivalent, 0x3E0
. Doing a bit of hex editing I changed all instances of 0x3DC
with 0x3E0
, hoping ther were no other checks for the size. Changing the language version for the program was similarly easy as the language identifier is seen in the e-Reader cards. A packet is sent by the multiboot that contains the text “GameFreak inc.”, twice. In that packet is a single byte that provide the language. Changing it from 0x1
(Japanese) to 0x2
(English) is all that’s needed. Now while I don’t know Japanese and so couldn’t change the text, I did figured out how the text works for future reference. A character map exists near the end of the program which can be swapped out for the English version. And underneath that are the strings in the program, using the letters from the character map.
Similarly to the Battle-e cards I tried compiling the multiboot program without any edits and once again I did not get the correct output. What was compiled was completely different from the original so I had no idea how to start troubleshooting the problem. I went over and over every step to make sure I was doing everything correctly. Maybe because it was a multiboot program and not a card that I was trying to compile, maybe I’m just an idiot. I still don’t know which explanation is correct. Either way I was stuck. I searched everywhere online to find information on what could be wrong. I eventually did find a solution with a perl script that I found from an online source, Compiling with this worked! Sending the multiboot program to the e-Reader worked! Scanning in English compatible cards worked! Sending the trainer data back to the game… worked?
Data was definitely sent back but I had to make sure game was reading it correctly. Running to the Trainer Tower I had to see the result!
Success! The trainer data was loaded with all the correct Pokémon! Sure their names were kept as Japanese so they looked messed up and the trainer’s easy chat text made no sense but we could battle new trainers on English games, and that’s all I wanted.
Final Words
Thanks for reading! This was my first blog post so I had no idea what I was doing so let me know what you thought - not enough detail, too much detail, needed more dragons? I do have ideas for a couple more blog posts on the e-Reader and then one more for a different peripheral I’m messing around with.
So until then, see ya!
Footnotes
There were like 5 total according to Bulbapedia, I can really only remember 1 from the first 3 generations. ↩︎
Check out Bulbapedia for more information. ↩︎
A pointer is basically an address, literally go to this location in the code. ↩︎
Any number with
0x
at the start is Hex notation. ↩︎Pan Docs is a technical reference document for the Game Boy line of handhelds. There’s also Dan Docs for the more obscure peripherals. ↩︎