Main Menu
Main Page
Forums
Recent changes
Random page
Help

Databases
GlitchDex
AttackDex
ItemDex

Major Glitches
Trainer escape glitch
Old man trick
Celebi trick
Select glitches (Japan)
SRAM glitch
CoolTrainer♀ corruption
LOL glitch
Rival LOL glitch
Super Glitch
ZZAZZ glitch
Pomeg corruption glitch (Glitzer Popping)
Tweaking
Elite Four door glitch (Japan)
Pokémon merge glitch
Pokémon cloning
Time Capsule exploit
Arbitrary code execution
Coin Case glitch
More

Other Glitch Categories
Glitches by generation
Glitches between two generations
Japan-only/language specific glitches
Music glitches
Natural glitches
Non-core series glitches
Non-Pokémon glitches
Officially acknowledged glitches
Recurring glitches
Dead glitches

References
Pokémon GameShark codes
The Big HEX List
GB programming
Curiosities
Debugging features
Easter eggs
Error traps
Glitch areas
Glitch myths
Non-glitch exploits
Placeholder texts
Pokémon glitch terminology
Unused content and prerelease information

Useful Tools
8F Helper
GBz80 to Items
Old man trick name generator
PATH (Prama's Advanced Tweaking Heaven)
Save file editors
Special stat/Pokémon converter
Trainer escape Trainer Pokémon finder

Affiliates
Legendary Star Blob 2 (Hakuda)
Pokémon Speedruns wiki
PRAMA Initiative
Become an affiliate!

Search Wiki

 

Search Forums

 

Author Topic: Anatomy of an e-Reader Mystery Event  (Read 10119 times)

0 Members and 1 Guest are viewing this topic.

Háčky

  • Distinguished Member
  • *
  • Offline Offline
  • Pick which packet as an error?
    • View Profile
Anatomy of an e-Reader Mystery Event
« on: November 21, 2014, 05:24:47 am »
For a long time, I didn’t know anything about the e-Reader other than that it was a short-lived gimmick on Pokémon trading cards. Once I realized that it was basically a Nintendo-approved flash cart that can install patches in games, I’ve really wanted to find out how it works and how to make my own cards for it.

I’ve made a disassembly of most of the English e-Reader cards released for Pokémon Ruby and Sapphire (excluding some promotional cards, but including the Eon Ticket). These programs are Z80 machine code which the e-Reader emulates on the GBA. The program communicates with the linked GBA running Ruby/Sapphire and sends Mystery Events data.

Prologue
The first packet of data sent by a Mystery Events card is 60 bytes. It seems to be exactly the same for every card, except for two useless fields and a region code.

Code: [Select]
Offset Len  Description
$00    14   “GameFreak inc.” [sic] in ASCII
$0E    6    Unknown (00 00 00 00 00 00)
$14    4    Arbitrary number
$18    8    Arbitrary identifier in R/S charset
$24    10   Unknown (00 00 00 00 01 55 00 00 00 00)
$2A    1    01: Japanese; 02: English
$2B    1    Unknown (00)
$2C    14   “GameFreak inc.” [sic] in ASCII
$3A    2    Probably padding (00 00)

Apparently Generation III was a period in which Game Freak didn’t know what their company’s name was; it’s also spelled as one word on the title screens of the Japanese Generation III games, but as two words on the cartridge labels and most everywhere else.

On Battle e cards, the arbitrary number is $12345678 and the arbitrary identifier is “カ。ドE” (an apparent typo for カードe Card e). On the Gentleman Nils and Lady Astrid cards included in the American releases of Ruby and Sapphire, the arbitrary number is 0 and the arbitrary identifiers are “NILS” and “ASTRID”. On the Eon Ticket, the arbitrary number is 0 and the arbitrary identifier is “e reader” with no $FF terminator.

If the region code at offset $2A is wrong, the game will terminate the link with the message “Loading error. Ending session.”, which is the same message used for checksum failures.


Header
The second packet, which contains the actual card data, is either 3072 or 6144 bytes long, starting with a 24- or 32-byte header and ending by lazily copying about 2000–5000 bytes after the end of the data, including the card’s entire Z80 program. It’s almost a quine!

Code: [Select]
Offset Len  Description
$00   1     Unknown (01)
$01   4     Base address ($02000000)
            This is where the data gets loaded in RAM, and all subsequent
            pointers are based on this location.
$05   1     01: Japanese; 02: English
$06   1     Unknown (00)
$07   1     01: Japanese; 02: English
$08   9     Unknown (00 00 00 04 00 80 01 00 00)
$11   1     Data type
              2: Variable-length data (must be used inside type 16)
              5: Custom script, runs immediately (must be used inside type 16)
              6: Custom script, runs in-game (must be used inside type 16)
              7: Enigma Berry
              11: Mixing records gift item
              13: Battle Trainer
              16: Contains multiple types

God knows why they needed two more copies of the region code, but if either is incorrect, the message “This data cannot be used in this version.” will appear. The region code in the prologue must be correct to even reach this point, so this message is never seen when scanning a real card.

For simple cards such as the Enigma Berries or Battle Trainers, which consist of a single fixed-length chunk of data, the header finishes with six more bytes:

Code: [Select]
Offset Len  Description
$12    4    Pointer to data start (always $02000018)
$16    2    Unknown (02 00)

For cards with multiple data chunks (type 16), such as the Eon Ticket, the header instead finishes with twelve more bytes:

Code: [Select]
Offset Len  Description
$12    2    Data checksum
$14    2    Padding (00 00)
$16    4    Pointer to data start (always $0200001E)
$1A    4    Pointer to data end

Unlike Pokémon data, save data, other kinds of e-Reader cards, or anything else in these games, for which a trivial bytewise or wordwise sum is sufficient to preserve integrity, this particular card structure is SERIOUS GODDAMNED BUSINESS which demands the use of a grown-up CRC function found at $08041174 in the original English Ruby. Here’s a C translation:

Code: [Select]
uint16_t compound_card_crc(const char * data, uint16_t len)
{
uint16_t x = 0x1121;
for(uint16_t i = 0; i < len; ++i)
{
x ^= data[i];
for(uint16_t j = 0; j < 8; ++j)
if(x & 1)
x = (x >> 1) ^ 0x8408;
else
x >>= 1;
}
return ~x;
}

This relatively impressive level of verification is used only at the time the data is transferred. Once loaded into the game, the separate chunks are protected only by a bytewise checksum preceding each one. Why did they even bother?

After the header, each chunk is declared with a type byte, followed by its data, the length of which is inferred from the type. If variable-length data (type 2) is included, it must come after all fixed-length chunks.


Variable-length data (type 2)
This chunk is used to contain the actual script code for a chunk of type 5 or 6. It has no particular structure; those other chunks include pointers to the specific addresses of the data they need.


Custom script, runs immediately (type 5)
This chunk is 4 bytes long; it’s just a pointer to a script stored in the type 2 chunk. The script is executed right away while still on the Mystery Events screen. The result of the script is given using the setbyte command ($0E):

  • setbyte 0 is a success state which displays the message “The event was safely loaded.”
  • setbyte 1 is a failure state which displays the message “Loading error. Ending session.”
  • setbyte 2 is a success state which displays the message at the address loaded with the virtualloadpointer command ($BE).
  • setbyte 3 is a failure state which displays the message at the address loaded with the virtualloadpointer command.
Both the Eon Ticket and the Japanese “Decoration Present” card (which gives the Regirock, Regice, and Registeel Dolls) use setbyte 2 or setbyte 3 to display custom messages, so “The event was safely loaded.” is never seen. The Eon Ticket’s script fails if the player already has the Eon Ticket item, if flag $00CE is set, or if the Key Items pocket is full. If the type 5 script fails, other chunks (i.e., the Norman event and the mixing records gift) will not be loaded into the save file.


Custom script, runs in-game (type 6)
This 11-byte chunk gives pointers to the start and end of a script stored in the type 2 chunk, and the “person event” in the game to which this script should be attached. The script is copied into the save file and run whenever the player interacts with that person.

Code: [Select]
Offset Len  Description
$00    1    Map bank
$01    1    Map number
$02    1    Person event number
$03    4    Pointer to script start
$07    4    Pointer to script end

The Eon Ticket gives its script to Norman (map 8.1, person event 1), but it can just as easily be assigned to anyone in Hoenn:




The killscript command ($0D) deletes the script from the save file.


Enigma Berry (type 7)
These cards define the properties of a berry which replaces the Enigma Berry as No. 43, triggering an in-game event where Norman gives you the berry at Petalburg Gym (unlike the Eon Ticket, this is hard-coded). The chunk is 1328 bytes long, most of which is just a pretty picture:

Code: [Select]
Offset Len  Description
$000   7    Berry name
$007   1    Firmness (from 1 “very soft” to 5 “super hard”)
$008   2    Size (in millimeters)
$00A   1    Maximum yield
$00B   1    Minimum yield
$00C   8    Always 00
$014   1    Hours per growth stage
$015   5    Flavor (Spicy, Dry, Sweet, Bitter, Sour)
$01A   1    Smoothness
$01B   1    Always 00
$01C   1152 Sprite (48×48 px)
$49C   32   Palette (16 colors in 15-bit BGR format)
$4BC   45   Tag description line 1
$4E9   45   Tag description line 2
$516   10   Usage by trainer
$520   8    Unknown (always 00)
$528   1    Usage as held item
$529   3    Unknown (always 00)
$52C   4    Bytewise checksum

JPAN on PokéCommunity documented this item-usage-by-trainer data structure. It consists of a six-byte bitfield followed by parameters. Parameters are included only if required.

There could well an equally-sophisticated structure for defining held item usage, but I couldn’t find information on that. The known values for offset $528 are:

Code: [Select]
$00: No effect
$04: Cures poison            (Drash Berry)
$05: Cures burn              (Japanese Yago Berry)
$06: Cures freeze            (Pumkin Berry)
$08: Cures confusion         (Japanese Touga Berry)
$17: Restores a lowered stat (Japanese Ginema Berry)
$1C: Cures infatuation       (Eggant Berry)

Incidentally, Bulbapedia claims the Kuo Berry cures a burn, but it’s actually the Yago Berry that does. Too bad it’s been closed to editing because of some new game that isn’t half as exciting as this stuff. :P


Mixing records gift item (type 11)
This chunk is written to the save file and causes an item to be received in other games when they mix records with this one. It is four bytes long:

Code: [Select]
Offset Len  Description
$00    1    Unknown (01)
$01    1    Distribution limit
$02    2    Item

For the Eon Ticket, the distribution limit is 30. This number is reduced by 1 each time the game mixes records, even if the item is not actually distributed (when mixing records with the same game again, or when the recipient does not have space for the item). Receiving the Eon Ticket in this manner automatically activates the Southern Island event.

This only seems to work with key items. Pokémon Emerald will accept key items offered in this manner from Ruby/Sapphire even if the item did not exist in the earlier games (index > $015C). However, receiving the MysticTicket, AuroraTicket, or Old Sea Map in this manner does not activate the corresponding event.


Battle Trainer (type 13)
This 188-byte chunk is written to the save file and causes a trainer to appear at a house in Mossdeep City. It may also allow this trainer to appear in the Battle Tower. Furlock’s Forest previously documented this data structure, but I’ve learned a couple of new things about it.

Code: [Select]
Offset Len  Description
$00    1    Battle Tower appearance
              0: does not appear at Battle Tower, only in Mossdeep house
              50: appears in Battle Tower Lv50 challenge
              100: appears in Battle Tower Lv100 challenge
$01    1    Trainer class
$02    1    Battle Tower floor (0: does not appear at Battle Tower)
$03    1    Unknown (always 00)
$04    8    Trainer name
$0C    2    Trainer ID (always 00000)
$0E    2    Trainer SID (always 00000)
$10    12   Pre-battle text (six easy chat halfwords)
$1C    12   Victory text (six easy chat halfwords)
$28    12   Defeat text (six easy chat halfwords)
$34    44   Pokémon 1
$60    44   Pokémon 2
$8C    44   Pokémon 3
$B8    4    Wordwise checksum

The indices for trainer classes are different than those used for the in-game trainer data. I don’t know if this list is used for anything other than e-Reader cards.

Code: [Select]
$00: *AQUA LEADER
$01: *TEAM AQUA    (♂)
$02: *TEAM AQUA    (♀)
$03:  AROMA LADY
$04:  RUIN MANIAC
$05: *INTERVIEWER
$06:  TUBER        (♀)
$07:  TUBER        (♂)
$08:  COOLTRAINER♂
$09:  COOLTRAINER♀
$0A:  HEX MANIAC
$0B:  LADY
$0C:  BEAUTY
$0D:  RICH BOY
$0E:  POKéMANIAC
$0F:  SWIMMER♂
$10:  BLACK BELT
$11:  GUITARIST
$12:  KINDLER
$13:  CAMPER
$14:  BUG MANIAC
$15:  PSYCHIC      (♂)
$16:  PSYCHIC      (♀)
$17:  GENTLEMAN
$18: *ELITE FOUR   (Sidney)
$19: *ELITE FOUR   (Phoebe)
$1A: *LEADER       (Roxanne)
$1B: *LEADER       (Brawly)
$1C: *LEADER       (Tate&Liza)
$1D:  SCHOOL KID   (♂)
$1E:  SCHOOL KID   (♀)
$1F: *SR. AND JR.
$20:  POKéFAN      (♂)
$21:  POKéFAN      (♀)
$22:  EXPERT       (♂)
$23:  EXPERT       (♀)
$24:  YOUNGSTER
$25: *CHAMPION
$26:  FISHERMAN
$27:  TRIATHLETE   (♂ cycling)
$28:  TRIATHLETE   (♀ cycling)
$29:  TRIATHLETE   (♂ running)
$2A:  TRIATHLETE   (♀ running)
$2B:  TRIATHLETE   (♂ swimming)
$2C:  TRIATHLETE   (♀ swimming)
$2D:  DRAGON TAMER
$2E:  BIRD KEEPER
$2F:  NINJA BOY
$30:  BATTLE GIRL
$31:  PARASOL LADY
$32:  SWIMMER♀
$33:  PICNICKER
$34: *TWINS
$35:  SAILOR
$36: *BOARDER      (Youngster)
$37: *BOARDER      (Youngster)
$38:  COLLECTOR
$39: *PKMN TRAINER (Wally)
$3A: *PKMN TRAINER (Brendan)
$3B: *PKMN TRAINER (Brendan)
$3C: *PKMN TRAINER (Brendan)
$3D: *PKMN TRAINER (May)
$3E: *PKMN TRAINER (May)
$3F: *PKMN TRAINER (May)
$40:  PKMN BREEDER (♂)
$41:  PKMN BREEDER (♀)
$42:  PKMN RANGER  (♂)
$43:  PKMN RANGER  (♀)
$44: *MAGMA LEADER
$45: *TEAM MAGMA   (♂)
$46: *TEAM MAGMA   (♀)
$47:  LASS
$48:  BUG CATCHER
$49:  HIKER
$4A: *YOUNG COUPLE
$4B: *OLD COUPLE
$4C: *SIS AND BRO

The classes AQUA ADMIN, MAGMA ADMIN, and WINSTRATE are apparently unavailable, as are the other five Leaders and two Elite Four members. Indices greater than $4C result in mismatches between the trainer class and sprite:



This value also determines the overworld sprite shown in the Mossdeep house. Any class marked with an asterisk, and any value greater than $4C, will be shown in the overworld as a generic male NPC.

There are two identical entries for the unused BOARDER class in this list, implying that male and female versions were planned, and three identical entries each for Brendan and May, which might indicate that they were intended to have multiple sprites like the rivals in prior games.

The 44-byte substructure for Pokémon data is:

Code: [Select]
Offset Len  Description
$00    2    Species
$02    2    Held item
$04    8    Moves
$0C    1    Level
$0D    1    It’s not very effective…
$0E    6    Effort values
$14    2    OT ID (always 00000)
$16    2    OT SID (always 00000)
$18    4    Individual values (five bits each); bit 31: Ability
$1C    4    Personality value
$20    11   Nickname
$2B    1    Friendship (always 255, unless it knows Frustration)

Offset $0D represents the number of PP Ups applied, with two bits for each move. This byte is ultimately copied to offset $3B of the battle data structure, which is used to determine the moves’ maximum PP, but it is not taken into account when initializing the moves’ remaining PP at the start of the battle. For example, Collector Stuart’s Wailord has 3 PP Ups applied to Hydro Pump and Blizzard, but these moves have only 5 out of 8 PP available in the battle. If this Pokémon were holding a Leppa Berry (which it isn’t), it would be able to restore one of these moves to 8 PP after expending the original 5 PP, but otherwise PP Ups have no effect. PKMN Ranger Irazu is the other card affected by this glitch; his Pokémon each have three PP Ups for Return.

IVs and EVs seem to have been assigned a bit haphazardly in the Battle e series. Most Pokémon have two perfect IVs and four 15s except for level 100 Pokémon, which have 20s instead of 15s. A few have their IVs adjusted for the sake of Hidden Power, but there are several exceptions that appear to be by mistake, including some Pokémon with one 0 IV. EVs are generally assigned as either 252+252+6 or 255+255, but again there are a few exceptions, including one Pokémon (Psychic Natasha’s Starmie) that has an illegal EV spread of 6/0/6/252/252/0. Perfect IVs and EVs are sometimes given in the same two stats, but often not.


Open questions
  • Based on the numbering, there would appear to be around 7–10 other types of Mystery Event chunks which aren’t used in any e-Reader cards. (Notes: the berry glitch patch doesn’t use Mystery Events, the Japanese “Decoration Present” card uses type 5 scripts to award the Regi dolls, and Altering Cave wasn’t in Ruby and Sapphire.) Surely one of them was used for event Pokémon distributions, but I’m very interested in finding out what the others are.
  • The leaked German Ruby debug version contains some Mystery Event data, including a test Pokémon distribution. I did some searching through the ROM, and found the Eon Ticket script at $45DAE1. First impressions: the event’s text is translated into German, addresses are based on the ROM location rather than $02000000 (implying this can only work if transferred to another debug cartridge?), the header uses region code 4, offset $0E is set to 0 instead of 1, and the oh-so-important checksum is set to $0000. There’s definitely more to explore here.
  • How is Mystery Event data structured in the save file?
  • Even though the data itself is nothing special, it might be useful to disassemble the Regi doll card, because it features a basic menu system (for choosing which doll to send) that may be a helpful template for a custom interactive e-Reader program. I think it’d be neat to make programs that can do things like customizing a Battle Trainer before you send it to your game.
  • The popular conception seems to be that “e-Reader support” was removed from the Western releases of FireRed, LeafGreen, and Emerald, but there really isn’t such a thing. The e-Reader can run any program that fits in a series of dotcodes, and a program can be made to access any of the networking features that exist in the game. Trainer Tower/Trainer Hill customization may have been removed, but there’s no reason an e-Reader program couldn’t be written to distribute Wonder Cards.

Torchickens

  • Administrator
  • *****
  • Offline Offline
  • Gender: Female
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #1 on: November 21, 2014, 11:48:55 am »
Wow. Excellent work. Keep it up.

Incidentally, Bulbapedia claims the Kuo Berry cures a burn, but it’s actually the Yago Berry that does. Too bad it’s been closed to editing because of some new game that isn’t half as exciting as this stuff. :P

What does the Kuo Berry actually do? Might the effects differ if you hacked it in the English version somehow? Does it really have an English bag description? "A hold item that heals a burn in battle."

Sorry for so many questions. I'm inexperienced with the e-Reader.

You might want to send a tweet to SnorlaxMonster. He's a Bulbapedia admin who incidentally has an account here. He could edit the article for you.
« Last Edit: November 21, 2014, 12:20:43 pm by Torchickens »
Hello. I actually identify as gender questioning, but nowadays feel more firmly that I identify as female. My sex is male but I like to express myself as female.  She/her pronouns, please.


Thank you TMTRAINER for my avatar and Aeriixion for the cute sprite! :) Roelof also made different variations of the sprite (which I animated).

Contact:

Email Youtube Twitter
Skype: Torchickens
Bulbapedia Starfy Wiki

Beyond all philosophies are the things that go best for you; what makes you feel content. It's important to always follow your heart, so unless you feel perfectly happy about it don't just follow something because it is popular, fits a style or is conventional. Sometimes you may reach a point you're not sure who you are, but as things settle I'm convinced things do work out in time.

Háčky

  • Distinguished Member
  • *
  • Offline Offline
  • Pick which packet as an error?
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #2 on: November 21, 2014, 01:12:41 pm »
Incidentally, Bulbapedia claims the Kuo Berry cures a burn, but it’s actually the Yago Berry that does. Too bad it’s been closed to editing because of some new game that isn’t half as exciting as this stuff. :P

What does the Kuo Berry actually do? Might the effects differ if you hacked it in the English version somehow? Does it really have an English bag description? "A hold item that heals a burn in battle."
The Kuo Berry is only a Pokéblock ingredient (offsets $516–52B are all 00), same as the other five berries I didn’t list.

All e-Reader berries have the Enigma Berry’s bag description, “POKéBLOCK ingredient. Plant in loamy soil to grow a mystery.” In Japanese, it’s 「オロックの ざいりょう つちのなかに うめると なぞな みが そだつ」.

Torchickens

  • Administrator
  • *****
  • Offline Offline
  • Gender: Female
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #3 on: November 21, 2014, 01:51:18 pm »
I see, thanks. I wonder where that English description (here for bag description) came from?

You made a minor typo. It should be: ロックの ざいりょう つちのなかに うめると なぞな みが そだつ
« Last Edit: November 21, 2014, 01:52:18 pm by Torchickens »
Hello. I actually identify as gender questioning, but nowadays feel more firmly that I identify as female. My sex is male but I like to express myself as female.  She/her pronouns, please.


Thank you TMTRAINER for my avatar and Aeriixion for the cute sprite! :) Roelof also made different variations of the sprite (which I animated).

Contact:

Email Youtube Twitter
Skype: Torchickens
Bulbapedia Starfy Wiki

Beyond all philosophies are the things that go best for you; what makes you feel content. It's important to always follow your heart, so unless you feel perfectly happy about it don't just follow something because it is popular, fits a style or is conventional. Sometimes you may reach a point you're not sure who you are, but as things settle I'm convinced things do work out in time.

Wack0

  • Coder, reverser, beta collector [BetaArchive staff]
  • Staff
  • *****
  • Offline Offline
  • Gender: Male
  • cBRH - Doing nothing since 2k7
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #4 on: November 21, 2014, 06:30:38 pm »
The leaked German Ruby debug version contains some Mystery Event data, including a test Pokémon distribution. I did some searching through the ROM, and found the Eon Ticket script at $45DAE1.

So.. let's find the others.

Any chance we could find the other Mystery Event data by searching the ROM for the byte sequence 04 00 04 00 00 00 04 00 80 00 00 00 ?
C H E C K E D . B U I L D S . A R E . A W E S O M E N E S S

BetaArchiveSoftHistory Forumsirc.rol.im #galaxy,#softhistory

Also known as The Distractor.

Shane, please stop telling children that there's a Mew outside under the delivery trucks. - Management

Pokémon: arbitrary code execution 1996-2016

Háčky

  • Distinguished Member
  • *
  • Offline Offline
  • Pick which packet as an error?
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #5 on: November 21, 2014, 07:05:14 pm »
The leaked German Ruby debug version contains some Mystery Event data, including a test Pokémon distribution. I did some searching through the ROM, and found the Eon Ticket script at $45DAE1.

So.. let's find the others.

Any chance we could find the other Mystery Event data by searching the ROM for the byte sequence 04 00 04 00 00 00 04 00 80 00 00 00 ?
Definitely. Here’s an index:

$45DAE1 (type $10, Eon Ticket)
$45DDB2 (type $0F)
$45E306 (type $05 script)
$45E3E0 (type $10, first embedded chunk is type $08)
$45E402 (type $10, first embedded chunk is type $09)
$45E422 (type $10, first embedded chunk is type $0A)
$45E443 (type $10, first embedded chunk is type $0C)
$45E4EF (type $0D Battle Trainer)
$45E606 (type $0E)
$45E619 (type $0F)
$45E712 (type $10, type $05 script + type $02 data)
$45E797 (type $10, type $0B mixing records item + empty type $02 data)

“TOURNAMENT”, the nickname for the Unown distribution, appears at $42E248. I don’t see any obvious pointers into that neighborhood from the $45xxxx region.

It’s interesting that there’s a naked type $05 script pointer; I guess that’s only possible because the pointer is to a ROM address, so the actual script doesn’t need to be sent with it in a type $02 chunk?

Háčky

  • Distinguished Member
  • *
  • Offline Offline
  • Pick which packet as an error?
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #6 on: November 21, 2014, 11:10:07 pm »
I sloppily merged the German Eon Ticket into my disassembly of the English one so I could try to build it into a working e-Reader program (with $02000000 as the base address, so it would work with any old non-debug Rubin/Saphir cartridge). My first attempt succeeded in making contact with the game, but resulted in “Fehler beim Laden! Vorgang wird abgebrochen.” (Loading error. Ending session.)

When I first looked at the debug version data, I was surprised that the region codes were $04, since the Pokémon data structure uses $04 for Italian and $05 for German. So, I tried changing all three region codes to $05, and…





Setting offset $0E of the header to 0 or 1 doesn’t seem to have any effect.

As far as I know, this is the first e-Reader dotcode created to be compatible with a European localization of the game.

IIMarckus

  • Administrator
  • *****
  • Offline Offline
  • Gender: Male
  • Impersonal Text
    • View Profile
    • iimarck.us
Re: Anatomy of an e-Reader Mystery Event
« Reply #7 on: November 22, 2014, 12:25:45 am »
How is emulation of the e‐Reader these days? Does it work well? Does it still need custom builds?

Háčky

  • Distinguished Member
  • *
  • Offline Offline
  • Pick which packet as an error?
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #8 on: November 22, 2014, 12:43:03 am »
How is emulation of the e‐Reader these days? Does it work well? Does it still need custom builds?
no$gba does a fine job of it.

hpoké_coloradohugge

  • Member+
  • *
  • Offline Offline
  • Gender: Male
  • I like Pokémon...
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #9 on: November 22, 2014, 05:25:58 am »
sometimes if feel like im actually the only one who owns a e-reader...

Wack0

  • Coder, reverser, beta collector [BetaArchive staff]
  • Staff
  • *****
  • Offline Offline
  • Gender: Male
  • cBRH - Doing nothing since 2k7
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #10 on: November 22, 2014, 08:22:29 am »
I'm also interested in the gen 3 distribution ROMs, though I doubt we'll see those until hell freezes over. The only one known to exist outside of Nintendo is in the hands of a collector who paid like £200 for it on ebay. It's also bolted inside the GBASP it came with.
C H E C K E D . B U I L D S . A R E . A W E S O M E N E S S

BetaArchiveSoftHistory Forumsirc.rol.im #galaxy,#softhistory

Also known as The Distractor.

Shane, please stop telling children that there's a Mew outside under the delivery trucks. - Management

Pokémon: arbitrary code execution 1996-2016

Sanqui

  • Distinguished Member
  • Offline Offline
  • Also known as Sanky
    • View Profile
    • Sanky @ Rusted Logic
Re: Anatomy of an e-Reader Mystery Event
« Reply #11 on: November 23, 2014, 05:50:29 pm »
I'm also interested in the gen 3 distribution ROMs, though I doubt we'll see those until hell freezes over. The only one known to exist outside of Nintendo is in the hands of a collector who paid like £200 for it on ebay. It's also bolted inside the GBASP it came with.
One of my friends owns a Gen 3 distribution cartridge or two.  I didn't realize they weren't dumped - I could totally borrow them and dump them with my DS.

Háčky

  • Distinguished Member
  • *
  • Offline Offline
  • Pick which packet as an error?
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #12 on: November 24, 2014, 02:24:29 am »
I spent some quality time with the German debug ROM, and learned quite a bit more.

First, I was slightly wrong about the structure of Mystery Event data: anything after the 17-byte header is read as a series of chunks. The Battle Trainer and Enigma Berry chunks eah consist only of the four-byte pointer to the data, and the following $02 byte terminates the chunk list. The $00 byte after that is unnecessary padding.

The type $10 chunk, consisting of a checksum and the start and end addresses for it (12 bytes), is not required to make a card with multiple chunks. You can bypass the need to calculate that checksum by just deleting that chunk. (It’s still a good idea to include it if you’re making an actual card to be printed, to ensure that transmission errors are detected. It’s less necessary for Battle Trainer/Enigma Berry cards because that data includes its own checksum, albeit a childish one.)

A type $0F is the same as type $10 except that the checksum is merely bytewise addition. Why choose this when you have a good checksum option sitting right next to it?

Several of the Mystery Event packets stored in the debug ROM have empty data sections, which are filled in by the “Mimic e-Card” code before it transmits them. You can see the actual packet that’s transmitted by viewing RAM starting at $02000000. In particular, the checksums for type $0F or $10 chunks are filled in automatically, with one exception noted below.


$45DAE1: Eon Ticket
This is a German translation of the American Eon Ticket event, except that the distribution limit for mixing records is 5 in this version, whereas it was 30 in the American release. The Mimic e-Card mode’s “ticket” function sends this script.


$45DDB2: Template for Enigma Berry
This is blank Enigma Berry data with a type $0F checksum.

The “RAM seed” function uses this template and sends a berry based on the Cheri Berry’s stats (soft, 2.0 cm, yields 2–3, et cetera), but overwrites its name with 「ガイブ」 (part of the German name “AMRENA” remains after the $FF string terminator). The Cheri Berry’s tag sprite is used. The tag description is 「そとから きた きのみ ただいま かいはつちゅう」. The usage-by-trainer structure is set to 40 00 00 00 44 00 FF, which gives this berry the effect of Sacred Ash (revives and fully heals all fainted Pokémon). Offsets $520–527 contain the text 「\v2かい じっこ」 (no terminator; \v2 is a variable). The last four bytes before the checksum are 00, indicating it has no use as a held item.


$45E306: Luvdisc event
This data has a type $05 script which gives the player a level 15 Luvdisc holding Berry Juice, or fails if the player’s party is full. It also has two type $03 chunks, which appear to define the messages that appear when the script succeeds or fails. The Eon Ticket does this by calling virtualloadpointer within the script itself.

None of the functions on the Mimic e-Card menu access this data. I guess nobody actually wants a Luvdisc—not even the developers…

Code: [Select]
db $05 ; instant script
GBAPTR ScriptData

db $03 ; loading message
db $02 ; success
GBAPTR AddedToYourTeam

db $03 ; loading message
db $03 ; failure
GBAPTR YourPartyIsFull

db $02 ; end of chunks

ScriptData:
setvirtualaddress ScriptData
countpokemon
compare LASTRESULT, 6
virtualgotoif 1, .party_full

givepokemon LUVDISC, 15, BERRY_JUICE, $00000000, $00000000, $00
setbyte 2 ; success; will display AddedToYourTeam
end

.party_full
setbyte 3 ; failure; will display YourPartyIsFull
end

AddedToYourTeam:
Text_DE "Ein POKéMON wurde in das Team des\n"
Text_DE "Spielers aufgenommen.@"

YourPartyIsFull:
Text_DE "Das Team des Spielers ist vollständig.\n"
Text_DE "Es kann kein weiteres POKéMON\l"
Text_DE "aufgenommen werden.@"


$45E3E0: Gives ribbon to party Pokémon
A type $08 chunk awards a ribbon to each of the party Pokémon. The “ribbon” function uses this data to award a Marine Ribbon with the text „REGIONAL TURNIER 2003 BAND des CHAMPS“. The first byte represents the type of ribbon, and the second represents the description.

Code: [Select]
db $08 ; award ribbon
db $00 ; Marine Ribbon
db $01 ; 2003 REGIONAL TOURNEY CHAMPION RIBBON

db $02 ; end of chunks

The possible ribbon types are:

Code: [Select]
$00: Marine Ribbon
$01: Land Ribbon
$02: Sky Ribbon
$03: Country Ribbon
$04: National Ribbon
$05: Earth Ribbon
$06: World Ribbon

The descriptions are taken from this list, $01 being the first. $00 results in a blank description.

If a ribbon of type > $06 or description > $40 is specified, no ribbons will be attached to the Pokémon, although the Mystery Events screen will say they were.


$45E402: Upgrades Pokédex to National Mode
The type $09 chunk has zero bytes of data, and upgrades the recipient’s Pokédex to National Mode.


$45E422: Adds a rare word?
The type $0A chunk contains one byte. This data is used by the “message” function, and the receiving game displays „Ein seltenes Wort wurde hinzugefügt.“ (A rare word has been added.) Does this have something to do with the easy chat system?

Code: [Select]
db $0A ; adds a rare word?
db $01

db $02 ; end of chunks


$45E443: Template for gift Pokémon
Gift Pokémon are defined using a type $0C chunk, which consists of a pointer to a 136-byte structure. The first 100 bytes of that are a complete Pokémon data structure. I have no idea what the last 36 bytes are for.

The “PKMN” function sends a level 21 Unown with nickname TOURNAMENT, OT 09999 ENGLISH, caught in a Great Ball in Petalburg City, game of origin 14 (is that normal for event Pokémon?), holding a Full Restore.

The “wrong PKMN” function sends the same Pokémon, but clears the checksum at offset $1C to create a Bad Egg. (IVs are randomized, so there may be a 1/65536 chance that the checksum really would be $0000 and this wouldn’t become a Bad Egg.)

For both “PKMN” and “wrong PKMN”, the 36 unknown bytes are: 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 BF C8 C1 C6 C3 CD C2 FF 0F 27 00 00 4A 75 82 00 00 03. This notably includes the string “ENGLISH”.

The “egg” function tries to send a Pikachu egg. It leaves the checksum in the type $10 chunk blank, so it fails with a loading error. (This could also have a 1/65536 chance of working.) For “egg”, the 36 unknown bytes are: 00 31 00 03 49 6A 00 03 30 06 00 00 00 31 00 03 DF 8F 00 08 F0 17 00 03 A3 07 00 08 17 00 00 00 8C 1D 00 03.


$45E4EF: Template for Battle Trainer
This is just blank Battle Trainer data.

The “trainer” function fills in this template to place a PKMN Ranger named 「カードイー」 (Card e) in the house in Mossdeep City:

Code: [Select]
BT_Level 0 ; Mossdeep only
Class PKMN_RANGER_M
BT_Floor 0 ; Mossdeep only
db $03 ; unknown value, which is $00 on all Battle e cards
OT_Name "カードイー"
OT_ID 09999, 00000

; these easy chat words are invalid; all display as “???”
Introduction $0000, $0000, $0000, $0000, $0000, $0000
After_Win    $0007, $0008, $0009, $000A, $000B, $000C
After_Loss   $000D, $000E, $000F, $0010, $0011, $0012

Pokemon CHARMELEON
Holds QUICK_CLAW
Moves SCARY_FACE, FLAMETHROWER, SLASH, DRAGON_RAGE
Level 50
PP_Ups 0,0,0,0
EVs 0,0,0,0,0,0
OT_ID 09999, 00000
IVs 21,13,11,23,14,22, CHARMELEON_BLAZE
PV $93788551 ; ♂ Lonely
Nickname "TOURNAMENT"
Friendship 70

Pokemon WARTORTLE
Holds FOCUS_BAND
Moves RAPID_SPIN, PROTECT, RAIN_DANCE, SKULL_BASH
; lol, Rain Dance is your only Water move
Level 50
PP_Ups 0,0,0,0
EVs 0,0,0,0,0,0
OT_ID 09999, 00000
dd $67817E1E ; bit 30 identifies this Pokémon as an egg!
             ; but that doesn’t actually make it one
; IVs 30,16,31,2,24,19, WARTORTLE_TORRENT
PV $6BE2D612 ; ♀ Hardy
Nickname "TOURNAMENT"
Friendship 70

Pokemon IVYSAUR
Holds LUM_BERRY
Moves RAZOR_LEAF, SWEET_SCENT, GROWTH, SYNTHESIS
Level 50
PP_Ups 0,0,0,0
EVs 0,0,0,0,0,0
OT_ID 09999, 00000
IVs 24,1,2,3,4,8, IVYSAUR_OVERGROW
PV $6222CB3B ; ♂ Rash
Nickname "TOURNAMENT"
Friendship 70



$45E606: In-game clock adjustment?
The type $0E chunk has zero bytes of data, and results in the message „Das spielinterne Zeiteingabe-System ist jetzt verfügbar.“ (The in-game clock adjustment system is now useable.)

Does anyone know what the in-game clock adjustment system is? It didn’t enable me to change the time on the clock in my bedroom.

The “clock” function sends this. I’m not convinced of TCRF’s claim that this is related to the berry glitch.


$45E619: Ganlon Berry event
This is similar to the Eon Ticket event, with Norman giving you the Ganlon Berry at his Gym. The difference is that instead of the Eon Ticket’s type $05 script which checks whether the Southern Island event has already beenplayed [sic] and whether there’s space in the Key Items pocket, this data appears to have a type $03 chunk which points to the “Go see your father…” text, and a type $04 chunk with the single byte $02. The $FF byte in the type $03 chunk might indicate a message that is always displayed, and the $02 byte in the type $04 chunk might indicate success, allowing the type $06 script to be saved without needing to run a type $05 script.

The “item” function sends this script.

Code: [Select]
db $06 ; in-game script
db 8,1 ; Petalburg Gym
db 1   ; Norman
GBAPTR NormanScriptStart
GBAPTR NormanScriptEnd

db $03 ; loading message
db $FF
GBAPTR GoSeeYourFather

db $04 ; sets script return value?
db $02

db $02 ; end of chunks

GoSeeYourFather:
Text_DE "Besuche deinen Vater in der ARENA\n"
Text_DE "von BLÜTENBURG CITY.@"

NormanScriptStart:
setvirtualaddress NormanScriptStart

; can’t get this berry if you have one in your bag or PC
checkitem GANLON_BERRY, 1
compare LASTRESULT, 1
virtualgotoif 1, .ineligible
checkpcitem GANLON_BERRY, 1
compare LASTRESULT, 1
virtualgotoif 1, .ineligible

lock
faceplayer
virtualmsgbox FoundARareBerry
waitmsg
waitkeypress

copyvarifnotzero $8000, GANLON_BERRY
copyvarifnotzero $8001, 1
callstd 0 ; give item
release
killscript

.ineligible
jumpram ; does this cause Norman’s default script to run?

FoundARareBerry:
Text_DE "VATER: Hi, \v1!\p"
Text_DE "Ich habe gerade diese seltene BEERE\n"
Text_DE "erhalten. Ich schenke sie dir!@"


$45E712: Registeel Doll event
This is a German translation of one of the three events on the Japanese Decoration Present card. The “goods” function sends this script.


$45E797: Mixing records item
This enables you to give a Potion to up to three other games when you mix records.

The “potion” function sends this verbatim. “ball” replaces the Potion with a Poké Ball, and “cheri berry” and “TM01” likewise do what you’d expect.

An item will only be sent by mixing records if the recipient does not already have the item in question. (I think that was my problem when I was trying to send non-Key Items in this manner before.)

Code: [Select]
db $0B ; mixing records gift item
db $01 ; unknown, same value as for Eon Ticket
db 3   ; distribution limit
dw POTION

db $02 ; end of chunks

Torchickens

  • Administrator
  • *****
  • Offline Offline
  • Gender: Female
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #13 on: November 24, 2014, 10:05:11 am »
$45DDB2: Template for Enigma Berry
This is blank Enigma Berry data with a type $0F checksum.

The “RAM seed” function uses this template and sends a berry based on the Cheri Berry’s stats (soft, 2.0 cm, yields 2–3, et cetera), but overwrites its name with 「ガイブ」 (part of the German name “AMRENA” remains after the $FF string terminator). The Cheri Berry’s tag sprite is used. The tag description is 「そとから きた きのみ ただいま かいはつちゅう」. The usage-by-trainer structure is set to 40 00 00 00 44 00 FF, which gives this berry the effect of Sacred Ash (revives and fully heals all fainted Pokémon). Offsets $520–527 contain the text 「\v2かい じっこ」 (no terminator; \v2 is a variable). The last four bytes before the checksum are 00, indicating it has no use as a held item.

Interesting. Is that Berry data in the final game too? I'm going to have a go at interpreting this as I'm studying Japanese. I don't know much though.

「そとから きた きのみ ただいま かいはつちゅう」 probably reads like: "This external Berry is in development right now."

そとから = External?
きた = Ta form of verb くる, which means come/arrive.
きのみ= Fruit/Berry.
ただいま = Right now.
かいはつ = Development.
-ちゅう = in (and apparently other prepositions).

ガイブ probably means "external" here too (as in real data is supposed to be written from the e-Reader).

I don't know what \v2かい じっこ means; however, as well as floor, かい can be "times" (e.g. '2 times'), "world", etc. "じっこう" means effect, but I don't know if it's the same as じっこ.
« Last Edit: November 24, 2014, 10:31:39 am by Torchickens »
Hello. I actually identify as gender questioning, but nowadays feel more firmly that I identify as female. My sex is male but I like to express myself as female.  She/her pronouns, please.


Thank you TMTRAINER for my avatar and Aeriixion for the cute sprite! :) Roelof also made different variations of the sprite (which I animated).

Contact:

Email Youtube Twitter
Skype: Torchickens
Bulbapedia Starfy Wiki

Beyond all philosophies are the things that go best for you; what makes you feel content. It's important to always follow your heart, so unless you feel perfectly happy about it don't just follow something because it is popular, fits a style or is conventional. Sometimes you may reach a point you're not sure who you are, but as things settle I'm convinced things do work out in time.

Háčky

  • Distinguished Member
  • *
  • Offline Offline
  • Pick which packet as an error?
    • View Profile
Re: Anatomy of an e-Reader Mystery Event
« Reply #14 on: November 24, 2014, 11:30:57 am »
Interesting. Is that Berry data in the final game too?
No. It doesn’t even exist coherently in the debug ROM—it’s pieced together at runtime from the actual Cheri Berry data and a few scattered strings—but those strings aren’t in the final Japanese ROM.

I don't know what \v2かい じっこ means; however, as well as floor, かい can be "times" (e.g. '2 times'), "world", etc. "じっこう" means effect, but I don't know if it's the same as じっこ.
The string 「\v2かい じっこう \v3うんいじかん しょうひ」 occurs at $39B6D8 of the debug ROM, directly after the usage-by-trainer data for this berry that makes it work like Sacred Ash. The first eight bytes of it are probably copied into the berry data by accident.