Jump to content

Mystery Gift: Reverse Engineering of IR Protocol


bayleef

Recommended Posts

The Mystery Gift IR Protocol

HIGH means: IR LED is turned on
LOW means: IR LED is turned off

There are two message types:

1. Hello Message

  • HIGH for 126 µs
  • LOW for 537 µs
  • HIGH for 126 µs

2. Data Message

This message is used to send a stream of bytes. For every byte, the bits are sent in MSB-first order.

  • HIGH for 126 µs
  • LOW for 725 µs
  • for every bit B that should be sent:
    • HIGH for 52 µs
    • if B is 0: LOW for 120 µs
      elseif B is 1: LOW for 299 µs
  • HIGH for 109 µs
  • LOW for 620 µs

 

How Data Is Sent

One party is the master (M), the other one is the slave (S). Only the master can send data. The slave can only send acknowledgements. However, the master can initiate a change of roles.

Data is always sent by M in a block of three data messages (called data block in the following):

  1. data message: 0x5A, [length of data]
  2. data message: [data] ...
  3. data message: low(checksum), high(checksum)

The checksum is just the sum over all bytes that have been sent in the first two messages (0x5A, the length of data, and every data byte).

After such a block, S sends an acknowledgement:

  1. data message: 0x6C

 

The procedure to send data is as follows:

  1. M: hello message
  2. S: hello message
     
  3. M: data block with three data messages (see above)
  4. S: acknowledgement
     
  5. M: data block with empty data, i.e. [length of data]==0 and the second message contains zero bits.
  6. S: acknowledgement

There must be a delay of about 1–2ms between reception of a message and sending the next message. After these steps, S and M change roles, resulting in new hello messages.

 

When sending empty data, the first data block is left out (last step of protocol, see protocol section below):

  1. M: hello message
  2. S: hello message
     
  3. M: data block with empty data, i.e. [length of data]==0 and the second message contains zero bits.
  4. S: acknowledgement

As above, there must be a delay of about 1–2ms between reception of a message and sending the next message.

 

The Whole Protocol

The following happens two times (for first and for second payload). There must be a delay of at least 5ms between the first and the second pass. Roles are preserved, i.e. after A has received the acknowledgement for the last message of the first pass, A continues to send a hello message (first message of the second pass).

  1. A: send 0x96
  2. B: send region code (see table below)
  3. A: send i-th payload
     
  4. B: send 0x96
  5. A: send region code (see table below)
  6. B: send i-th payload
     
  7. A: send empty data

If the region code received does not match the game's one, Mystery Gift fails.

region code country
0x90 USA
0x96 ESP
0x99 ITA
0x9A FRA
0x9F GER
0xF3 PIKACHU (see below)

 

The Payload

First payload: 20 Bytes.
[version] high(ID) low(ID) name[0] name[1] name[2] name[3] name[4] name[5] name[6] name[7] name[8] name[9] name[10] [pokedex] [gift type] [item] [decoration] [status] [counter]

  • version: gold,crystal: 0x01; silver: 0x02; Pokémon Pikachu 2 GS: 0x03
  • name: terminated by 0x50; after termination character, all bytes til name[7] are 0x50; name[8..10] are 0x00 (except for pokémon pikachu 2 GS)
  • pokedex: number of different Pokémon catched so far
  • gift type: 0x00 = item, 0x01 = decoration (or item if receiver owns the decoration already)
  • item, decoration: 0x00 to 0x24 (only a subset is ever sent, depending on the sender's trainer ID. 0x22 to 0x24 will never be sent (very rare items/decos). however, the receiving game accepts every item/deco in the range 0x00 to 0x24 without testing legality)
  • status: 0x00 if everything is ok; 0xAD if the player needs to retrieve gift at Pokémon center before
  • counter: player's today's number of mystery gifts

for Pokémon Pikachu 2 GS: ID is 0x0000, name is "PIKACHU" (name[7..10] are 0x50), pokedex is 0x00, gift type is 0x00, decoration is 0x00, status is 0x00, counter is 0x00. item depends on the number of watts sent. only the first payload is exchanged (version field must be 0x03, otherwise communication without the second payload fails.) The number of Mystery Gifts received from Pokémon Pikachu 2 GS is not bounded (and the trainer ID is ignored).
Pokémon Pikachu 2 GS copies the region code from the receiving game. This always possible, because Pikachu always plays the role A in the protocol (it never responds to initial hello messages, but sends its own hello messages repeatedly until the game answers). Role A receives the region code of B before it needs to send its own.

Second payload: 38 Bytes. (only exchanged if [version] is not 0x03)
Team Pokémon (for Viridian City Battle Hall):
6 Bytes for each Pokémon: [level] [species] [move1] [move2] [move3] [move4]
The last Pokémon is followed by 0xFF. The remaining part of the message is filled with random bytes (uninitialized memory).

 

Pokémon Pikachu 2 GS

When sending watts to Pokémon GSC, Pikachu acts as described in the section above. Depending on the number of watts sent, Pikachu sends a payload with the following item to Pokémon GSC:

Watts Item
0–99 Eon Mail (0x0D)
100–199 Berry (0x00)
200–299 Bitter Berry (0x09)
300–399 Great Ball (0x13)
400–499 Max Repel (0x15)
500–599 Ether (0x17)
600–699 MiracleBerry (0x10)
700–799 Gold Berry (0x11)
800–899 Elixir (0x16)
900–998 Revive (0x12)
999 Rare Candy (0x22)


As receiver, Pikachu plays role B in the protocol above. It identifies itself by the region code 0xF3.
Thus, a communication with Pokémon GSC fails. When another Pikachu plays role A, it detects the communication with Pikachu by the region code.

The watts are sent using a payload of length 67 bytes. Only the first two bytes are used, the remaining bytes are padded with zeros (don't ask me why!).
The amount of watts is sent as packed BCD. E.g., when sending 237 watts, the first two bytes of the payload are 0x02 0x37, followed by 65 bytes with value 0x00. Note that the maximal amount of watts that can be sent is 999. When illegal codings like 0x0A 0xFF 0x00 ... 0x00 are sent, the receiving Pikachu may start to operate glitchy until it is reset (to reset Pikachu, remove its battery and wait a few minutes before reinsertion).

The receiving Pikachu sends a payload, too. Thus, exactly one pass of the protocol is performed. The payload sent by the receiving Pikachu contains 67 random junk bytes (i.e. uninitialized memory; again: don't ask me why!).

 

How are items / decorations encoded?

code item decoration
0x00 Berry Jigglypuff Doll
0x01 PRZCureBerry Poliwag Doll
0x02 Mint Berry Diglett Doll
0x03 Ice Berry Staryu Doll
0x04 Burnt Berry Magikarp Doll
0x05 PSNCureBerry Oddish Doll
0x06 Guard Spec. Gengar Doll
0x07 X Defend Shellder Doll
0x08 X Attack Grimer Doll
0x09 Bitter Berry Voltorb Doll
0x0A Dire Hit Clefairy Poster
0x0B X Special Jigglypuff Poster
0x0C X Accuracy Super NES
0x0D Eon Mail Weedle Doll
0x0E Morph Mail Geodude Doll
0x0F Music Mail Machop Doll
0x10 MiracleBerry Magna Plant
0x11 Gold Berry Tropic Plant
0x12 Revive NES
0x13 Great Ball Nintendo 64
0x14 Super Repel Bulbasaur Doll
0x15 Max Repel Squirtle Doll
0x16 Elixir Pink Bed
0x17 Ether Polkadot Bed
0x18 Water Stone Red Carpet
0x19 Fire Stone Blue Carpet
0x1A Leaf Stone Yellow Carpet
0x1B Thunderstone Green Carpet
0x1C Max Ether Jumbo Plant
0x1D Max Elixir Virtual Boy
0x1E Max Revive Big Onix Doll
0x1F Scope Lens Pikachu Poster
0x20 HP Up Big Lapras Doll
0x21 PP Up Surf Pikachu Doll
0x22 Rare Candy Pikachu Bed
0x23 Bluesky Mail Unown Doll
0x24 Mirage Mail Tentacool Doll
0x25–0xFF Great Ball Red Carpet

 

How are the other data encoded?

Trainer name: Every character is encoded the same way as all text in the game: https://bulbapedia.bulbagarden.net/wiki/Character_encoding_in_Generation_II
Pokémon: By the ID in the national Pokédex (Bulbasaur = 0x01, Celebi = 0xFB)
Moves: By their index number in the game: https://bulbapedia.bulbagarden.net/wiki/List_of_moves

 

Which Items resp. Decorations Are Sent at All?

Items/Decorations 0x22–0xFF are never sent by Pokémon GSC at all. Rare Candy can be sent by Pokémon Pikachu 2 GS. Pikachu Bed, Unown Doll, and Tentacool Doll are only sent by Pokémon Stadium 2 (however, without IR communication). Bluesky Mail and Mirage Mail are never sent by any device.

For the other items and decorations (0x00–0x21), only a subset of them is actually sent by a specific game, depending on the trainer ID. Compile and run gifts.c to find out which gifts can be sent by a game with a specific ID.

 

Building a Mystery Gift Station

I own only one GameBoy Color, but three Gen 2 games. So I used a Raspberry Pi to implement the protocol above.
The first time, the Raspberry sends payload with the status byte (see first payload) not zero, thus it does not send any gift. But the Raspberry Pi stores the received payload. Then I can swap the game cartridge and run mystery gift again, receiving the stored data from the first exchange. The Raspberry Pi stores the received data again, so after swapping the game cartridge back the exchange is completed. If a communication error occurs (this happens often), the Raspberry Pi just keeps the last correct data.

I have attached the circuit layout (without capacity / resistance information*) and the source code (mysterygift.c) for the mystery gift station (needs WiringPi library and Linux kernel with RT_PREEMPT). The input timing of the source code differs from the timing described above. I guess that the high-pass filter may extend the HIGH-time. Depending on the capacitor, one may need to change the appropriate values in the source. You may connect a push button at GPIO 27 for shutdown and a status LED (with resistor) at GPIO 22 (gives light while communication is active). When you add the mysterygift executable to /etc/local.rc, e.g. nohup /home/pi/mysterygift &, mystery gift becomes active at start up. The station can be shut down by the push button at GPIO 27, thus it can run without any keyboard, monitor, or network connection.

circuit layout.png

* I have chosen them by instinct, so they may be somewhat less than perfect. However, you can find details in another posting below.

Demo of Mystery Gift Station

https://www.youtube.com/watch?v=sqk3Zm-s1eI

 

Cheating

It is possible to manipulate the item or decoration in the first payload to obtain rare items like BLUESKY MAIL or MIRAGE MAIL.

You may either solder a Mystery Gift Station and run it with a modified version of mysterygift.c. If you own two GBC and a flashcart, you may use a ROM that does the IR communication as you like: mysterygift_eng.gbc (see posting below for versions with German, French, Spain, or Italian translation).

Edited by bayleef
  • Like 5
  • Amazed 2
  • Proud 1
  • Confused 1
Link to comment
Share on other sites

  • 3 months later...

Amazing work, good job!

Could you tell us the exact parts you bought? :) I would like to test this out some day!

Edited by Guest
Link to comment
Share on other sites

On 6/8/2018 at 8:59 PM, Lt. Lynx said:

I have two GBC and a GB USB Smart Card. Is it possible to create a ROM that gives the prize you want? ?

I have built such ROMs:
English: mysterygift_eng.gbc
French: mysterygift_fra.gbc
German: mysterygift_ger.gbc
Italian: mysterygift_ita.gbc
Spainish: mysterygift_esp.gbc

Each ROM should work with all US and EU versions of Pokémon GSC. The different versions contain translated names of Pokémon, moves, items, and decorations. When using special characters in the trainer name, they may be displayed incorrectly if the ROM version does not match the game version.
There may be mistakes in the translations. If you have trouble with them, use the English version please. Decorations are not translated to Italian by me, thus the Italian ROM uses English decoration names.

Usage: Use up/down keys to select menu entry. Change entries "ID", "name", "item", "deco", "send" (Trainer House data) by left/right keys. Go to submenu for "name", "ID", or Pokémon editing by pressing A. Delete a Pokémon by pressing B in the main menu when the Pokémon is selected. When everything is set up, press START to begin sending. Afterwards, enable Mystery Gift in Pokémon GSC (by entering the Mystery Gift screen and pressing A).

Navigate through the submenus by arrow keys. Leave "name" submenu by selecting "OK" (you can jump to "OK" by pressing START). Leave ID menu and Pokémon menu by A button. You can discard changes of a Pokémon by leaving the submenu with B.

When you set up moves: The first move should never be (none), otherwise the game will crash when fighting the Pokémon. Avoid holes with (none) moves between moves, but place all (none) moves (if any) at the end of the list.

When sending the Trainer House data is disabled, Mystery Gifts are not counted by the game. I.e., you can receive arbitrary many gifts at the same day and from the same ID.

Changing Pokémon data is a pain (I know this!). I recommend to set up Pokémon data only when it is really required. To keep your Pokémon data in GSC, you can disable sending these data for future gifts. Don't forget to turn on sending the data after your painful setup. Sending them is disabled by default (so you won't overwrite your data with the standard team by accident later).

Edited by bayleef
  • Like 1
  • Thanks 2
Link to comment
Share on other sites

On 6/8/2018 at 10:55 PM, Purin said:

Could you tell us the exact parts you bought? :) I would like to test this out some day!

You can find the parts in the attached circuit diagram. I have just bought random parts. The operational amplifier may be absolutely inappropriate for this task (or overqualified). I don't know much about op-amps. The same holds for the transistor and the diodes. However, it works for me (and the timing in the C code for the Raspberry Pi is optimized for this setup). The MCP 607-I/P contains two op-amps, so you just need to buy one.

pokemon mystery gift circuit layout - with values.png

Btw.: At the moment I am working on an ATtiny implementation to get rid of the Raspberry Pi. However, I have some timing issues, so I don't know whether it will finally work.

Edited by bayleef
Link to comment
Share on other sites

13 hours ago, bayleef said:

I have build such a ROM: mysterygift.gbc

Usage: Use arrow keys to set up trainer ID and item. Note that only one gift per day and ID is possible. Press Start to enable communication. Afterwards, start Mystery Gift on Pokémon GSC (press A when Mystery Gift screen is active). If communication fails, you may need to press Start again in my ROM before restarting gifting in GSC. Don't move the GameBoys and adjust their distance if it doesn't work.

The ROM might not work due to timing issues, because I have only tested it with my Raspberry Pi Mystery Gift Station as counterpart. Timing of Pokémon GSC might be slightly different. Please inform me whether it works for you and whether you want to set up Viridian City Battle Hall data.

I have tried several times and it didn't work with european Gold and Crystal ? It keeps giving the error message.
Also, I can only change the ID from unit to unit.
However, thanks for sharing ? I'm sure that it can be fixed.

Link to comment
Share on other sites

On 6/13/2018 at 12:27 PM, Lt. Lynx said:

I have tried several times and it didn't work with european Gold and Crystal ? It keeps giving the error message.
Also, I can only change the ID from unit to unit.
However, thanks for sharing ? I'm sure that it can be fixed.

Together we managed to fix it. The posting has been updated and contains the fixed version now.

Thank you for your help, Lt. Lynx! ?

  • Thanks 1
Link to comment
Share on other sites

10 hours ago, Wanderer1391 said:

Is there a way to edit the Viridian City Trainer House data with the Mystery Gift rom as while I see the data for a team it seems to be read only.

Not yet. If there is interest (seems so), I may work on it. This may take a few days. Be warned: At least in the first release with this feature, changing moves will be a bit annoying.

Edited by bayleef
  • Like 1
Link to comment
Share on other sites

13 hours ago, bayleef said:

Not yet. If there is interest (seems so), I may work on it. This may take a few days. Be warned: At least in the first release with this feature, changing moves will be a bit annoying.

Perfectly fine with me, I can be patient. The only other thing I would want would be an easier way to scroll through the Trainer ID numbers as if you wanted to use a specific one for some reason it can take a while. I completely understand if its too difficult to program though.

Edited by Wanderer1391
Clarifying message
Link to comment
Share on other sites

10 hours ago, Wanderer1391 said:

Perfectly fine with me, I can be patient. The only other thing I would want would be an easier way to scroll through the Trainer ID numbers as if you wanted to use a specific one for some reason it can take a while. I completely understand if its too difficult to program though.

It's not difficult and it's on my list already, hence it should be implemented in the next release. I wanted to release the first version asap, thus it contains only basic features. Normally, the trainer ID doesn't matter, except that it has to be different from other IDs used before during the same day (exception: if you want to fake legal communication the trainer ID and the item/decoration need to match). However, thank you for your feedback.

  • Like 3
Link to comment
Share on other sites

The new version has been released.

On 6/12/2018 at 11:19 PM, bayleef said:

Read instructions in the (edited) posting above. I know that changing Pokémon data is a pain. I have many ideas how one could improve handling. However, I won't improve it, because it would require too much effort. Just keep sending Trainer House data disabled after you have set up your favorite Pokémon team. This way you won't need to set up these data frequently.

Edited by bayleef
  • Like 2
Link to comment
Share on other sites

  • 11 months later...
1 hour ago, minuro63 said:

Thank you for your work! Would it be possible for the ROM file to be usable with 3DS Virtual Console versions of G/S/C via 3DS's own IR commmunication?

I expect that this won't work, because Nintendo has changed the IR communication completely for the 3DS VC release. However, I haven't tried it out yet.

  • Like 1
Link to comment
Share on other sites

  • 2 years later...
On 2/19/2018 at 1:45 AM, bayleef said:

One party is the master (M), the other one is the slave (S). Only the master can send data. The slave can only send acknowledgements. However, the master can initiate a change of roles.

How are master an slave determined?

Link to comment
Share on other sites

  • 8 months later...
On 7/4/2021 at 2:40 PM, Jungbluth said:

How are master an slave determined?

Sorry for my late reply.

If the player presses the A button in the gift screen, a HELLO message is sent immediately, acting as master. If no HELLO message is received as response, the game switches to slave mode, waiting for HELLO messages from other games for a few seconds. If no message is received during this time, IR communication is disabled until the A button to be pressed again.

Thus, the player who presses the A button first will effectively start with in the slave role (since he won't receive a response on his HELLO message sent as master), while the player who presses the A button afterwards will start with the master role.

  • Like 1
Link to comment
Share on other sites

  • 8 months later...
On 6/16/2019 at 5:05 PM, minuro63 said:

Thank you for your work! Would it be possible for the ROM file to be usable with 3DS Virtual Console versions of G/S/C via 3DS's own IR commmunication?

Hello there!

Any news regarding this feature on 3DS?

Thank you in advance for your help and keep up the great work! ;)

  • Like 1
Link to comment
Share on other sites

Over the past year I have spent time on and off working with the IR signals for the Gen II Mystery Gift (specifically in regards to the Pokemon Pikachu 2), and there are two clarifications to bayleef's data that I was able to gleam, for whatever that's worth. I will note that I wouldn't have gotten to where I am if it hadn't been for bayleef's trove of information and trailblazing on this topic.

On 2/18/2018 at 6:45 PM, bayleef said:

The receiving Pikachu sends a payload, too. Thus, exactly one pass of the protocol is performed. The payload sent by the receiving Pikachu contains 67 random junk bytes (i.e. uninitialized memory; again: don't ask me why!).

I discovered that, of the 67 bytes the receiving Pikachu sends, the first two bytes are--for some reason--the number of Watts that was most recently given to Pikachu on that Pokemon Pikachu 2. When a player goes to "Present," then "Give," the Watt amount given will show up as a binary-coded decimal in the Pikachu's payload, followed by 65 0x00 bytes (ie If the receiver was recently given 987 Watts, its payload will be 0x09, 0x87, 0x00, 0x00...; you can even "reset" this to 0 by giving Pikachu 0 Watts). To quote bayleef, don't ask me why! (Note: This was discovered by reading from a Japanese Pocket Pikachu Color, but I'm confident it applies to the international version as well)

On 2/18/2018 at 6:45 PM, bayleef said:

status: 0x00 if everything is ok; 0xAD if the player needs to retrieve gift at Pokémon center before

I was noticing that there was considerable variety among my Pokemon games' status byte here when there was an item waiting at the center. It took an embarrassingly-long amount of testing and troubleshooting for me to discover how it actually works. If there is no item waiting at the Center, the status byte will of course be 0x00. However, if an item is waiting at the Center, the status byte will actually be the ID of the item waiting at the center.

However, it is not the Mystery Gift ID of the item. That is a separate and unique ID list. It goes off of the item's internal GSC ID number. In bayleef's case, it happened to be 0xAD--the Berry item that otherwise has a Mystery Gift ID of 0x00.

I will note that upon this revelation that at least once, the Mystery Gift's payload used GSC ID numbers, I was excited at the possibility of using Mystery Gift to inject items like the GS Ball. However, the rest of the process uses the unique Mystery Gift IDs, so I unfortunately don't believe that is possible. Would love for someone to prove me wrong though!

  • Like 1
Link to comment
Share on other sites

  • 6 months later...
On 2/19/2018 at 1:45 AM, bayleef said:

the remaining bytes are padded with zeros (don't ask me why!).

 

On 1/1/2023 at 8:44 PM, SupremeThunderDragon said:

followed by 65 0x00 bytes

The 65 bytes and used to send the melody you created for the alarm.
The melody is 64 notes long, so the last byte must be used as an end of line character.
You can send the melody by sending 0 watts.

  • Amazed 1
Link to comment
Share on other sites

On 7/8/2023 at 2:59 AM, Heykinox said:

 

The 65 bytes and used to send the melody you created for the alarm.
The melody is 64 notes long, so the last byte must be used as an end of line character.
You can send the melody by sending 0 watts.

The alarm has always been such an afterthought to me that I never explored that possibility! It's one thing for the receiver of Watts to send the last-gifted Watts as a dummy amount, but it's another thing entirely for the Pikachu to send their alarms to each other. Perhaps they share them? Between my three Pikachu devices, my one English one has two "presets," which are "A" and either a "G" or maybe a "6." Of the two Japanese ones, one has only "A" while the other has "A" and "B". Curious.

Also, I did a couple reads of my Japanese Pikachu sending data to the other with an alarm created. Turns out, the first byte of the 65-byte string is actually the length of the melody, with 0x64 being the highest with one test, and another test with 30 being 0x30, so this also appears to be a binary-coded decimal. The next 64 bytes are the actual melody.

The lowest pitch is 0x7D (decimal 125), and decreases in size as pitch increases. It stops after 0x72 (decimal 114), and there's a small gap where 0x71, 0x70, and 0x6F aren't included, so the next pitch increase goes from 0x72 to 0x6D, and continues to increase by one until the max at 0x62 (decimal 98). I don't know why there's that gap, but 0x71 is used as a rest note, as opposed to one with a pitch. 0x70 and 0x6F appear unused however.

Thank you for the new insight!

Edited by SupremeThunderDragon
Hit enter too soon...
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...