about summary refs log tree commit diff stats
path: root/gba/source/gamedata.c
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-08-18 13:49:00 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-08-18 13:49:00 -0400
commit08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6 (patch)
treeb46baa9353c0919efaed4349d2207958fa0bfaf5 /gba/source/gamedata.c
parenta19507262602fa31f9f14a9e4f4e03e375bca111 (diff)
downloadgen3uploader-08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6.tar.gz
gen3uploader-08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6.tar.bz2
gen3uploader-08dfb0aa80668b80c4a31bd064f5f2d729e5b7f6.zip
Started working on serializing pokemon data
The GBA program now sends serialized data about the first pokemon in the
player's party over to the Wii. This data doesn't yet include all of the
information that we will eventually want. It does, however, not transfer
any private data, specifically IVs, EVs, and the personality value. It
does this by deriving the public information (stats, nature, gender,
shiny) before sending the pokemon over. Because of this, lookup tables
for things such as base stats were needed, and given that these are
large tables, it was easier to use the tables already existent in the
game's ROM. Thus, the addresses of the three lookup tables that are now
used are necessary for each ROM that this tool supports.

I derived the addresses for version 1 of English Pokemon LeafGreen by dumping
my own copy and searching through it with a text editor. Thus, at the current
time, that cartridge is the only one that is supported. I will supplement this
soon with addresses for the other four gen 3 carts that I have, but that will
still not provide a very large amount of coverage. I have not yet decided how
to address this issue.

There is one current bug with the serialized data: the Wii doesn't seem
to see the original trainer ID. Will fix.
Diffstat (limited to 'gba/source/gamedata.c')
-rw-r--r--gba/source/gamedata.c167
1 files changed, 159 insertions, 8 deletions
diff --git a/gba/source/gamedata.c b/gba/source/gamedata.c index bbcf4dd..ae593b1 100644 --- a/gba/source/gamedata.c +++ b/gba/source/gamedata.c
@@ -7,7 +7,7 @@
7 */ 7 */
8#include "gamedata.h" 8#include "gamedata.h"
9 9
10void decryptSaveStructures( 10static void decryptSaveStructures(
11 pSaveBlock1 SaveBlock1, 11 pSaveBlock1 SaveBlock1,
12 pSaveBlock2 SaveBlock2, 12 pSaveBlock2 SaveBlock2,
13 pSaveBlock3 SaveBlock3) 13 pSaveBlock3 SaveBlock3)
@@ -119,10 +119,15 @@ void decryptSaveStructures(
119 *xor_key_ptr = 0; 119 *xor_key_ptr = 0;
120} 120}
121 121
122bool initSaveData( 122static void CryptBoxPokemon(struct BoxPokemon* pkm)
123 pSaveBlock1* SaveBlock1, 123{
124 pSaveBlock2* SaveBlock2, 124 for (u32 i = 0; i < 12; i++)
125 pSaveBlock3* SaveBlock3) 125 {
126 pkm->secure.raw[i] ^= (pkm->otId ^ pkm->personality);
127 }
128}
129
130bool initSaveData(struct GameData* gameData)
126{ 131{
127 // check the ROM code, make sure this game is supported. 132 // check the ROM code, make sure this game is supported.
128 u8* ROM = (u8*) 0x8000000; 133 u8* ROM = (u8*) 0x8000000;
@@ -135,6 +140,9 @@ bool initSaveData(
135 pSaveBlock1 gSaveBlock1; 140 pSaveBlock1 gSaveBlock1;
136 pSaveBlock2 gSaveBlock2; 141 pSaveBlock2 gSaveBlock2;
137 pSaveBlock3 gSaveBlock3; 142 pSaveBlock3 gSaveBlock3;
143 struct BaseStats* gBaseStats;
144 const u32 (*gExpTables)[101];
145 const u16* gNatOrder;
138 //u32 titlemid = 0; 146 //u32 titlemid = 0;
139 147
140 // get the address of the save loading function. 148 // get the address of the save loading function.
@@ -337,6 +345,9 @@ bool initSaveData(
337 //mainloop = (void(*)()) 0x8000429; 345 //mainloop = (void(*)()) 0x8000429;
338 //titlemid = 0x807928f; 346 //titlemid = 0x807928f;
339 //load_pokemon = (void(*)()) 0x804c245; 347 //load_pokemon = (void(*)()) 0x804c245;
348 gBaseStats = (struct BaseStats*) ( GAME_FR ? 0 : 0x82547d0 );
349 gExpTables = (ExperienceTables) ( GAME_FR ? 0 : 0x8253b30 );
350 gNatOrder = (const u16*) ( GAME_FR ? 0 : 0x825203a );
340 351
341 break; 352 break;
342 } 353 }
@@ -504,9 +515,149 @@ bool initSaveData(
504 // applicable. 515 // applicable.
505 decryptSaveStructures(gSaveBlock1,gSaveBlock2,gSaveBlock3); 516 decryptSaveStructures(gSaveBlock1,gSaveBlock2,gSaveBlock3);
506 517
507 *SaveBlock1 = gSaveBlock1; 518 gameData->SaveBlock1 = gSaveBlock1;
508 *SaveBlock2 = gSaveBlock2; 519 gameData->SaveBlock2 = gSaveBlock2;
509 *SaveBlock3 = gSaveBlock3; 520 gameData->SaveBlock3 = gSaveBlock3;
521 gameData->baseStats = gBaseStats;
522 gameData->expTables = gExpTables;
523 gameData->natOrder = gNatOrder;
510 524
511 return true; 525 return true;
512} 526}
527
528void DecryptPokemon(struct Pokemon* pkm)
529{
530 struct BoxPokemon* boxMon = &(pkm->box);
531
532 CryptBoxPokemon(boxMon);
533}
534
535void DecryptBoxPokemon(struct BoxPokemon* pkm)
536{
537 CryptBoxPokemon(pkm);
538}
539
540void EncryptPokemon(struct Pokemon* pkm)
541{
542 struct BoxPokemon* boxMon = &(pkm->box);
543
544 EncryptBoxPokemon(boxMon);
545}
546
547void EncryptBoxPokemon(struct BoxPokemon* pkm)
548{
549 FixBoxPokemonChecksum(pkm);
550 CryptBoxPokemon(pkm);
551}
552
553union PokemonSubstruct* GetPokemonSubstruct(struct Pokemon* pkm,u8 substructId)
554{
555 struct BoxPokemon* boxMon = &(pkm->box);
556
557 return GetBoxPokemonSubstruct(boxMon,substructId);
558}
559
560union PokemonSubstruct* GetBoxPokemonSubstruct(
561 struct BoxPokemon* pkm,
562 u8 substructId)
563{
564 if (substructId > 3)
565 {
566 return NULL;
567 }
568
569 u32 personality = pkm->personality;
570 u32 modulo = (personality % 24);
571
572 // Staring at the substruct indexes, I noticed the last two columns are the
573 // reverse of the first two! that is, substructId==2 column is the reverse of
574 // substructId==1, substructId==3 is the reverse of substructId==0.
575 // At least that means there's no need to hardcode all four.
576 u8 substruct_idxes[2][24] = {
577 { 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 2, 3, 1, 1, 2, 3, 2, 3, 1, 1, 2, 3, 2, 3 },
578 { 1, 1, 2, 3, 2, 3, 0, 0, 0, 0, 0, 0, 2, 3, 1, 1, 3, 2, 2, 3, 1, 1, 3, 2 }
579 };
580
581 if (substructId < 2)
582 {
583 return &(pkm->secure.substructs[substruct_idxes[substructId][modulo]]);
584 }
585
586 return &(pkm->secure.substructs[
587 substruct_idxes[3 - substructId][23 - modulo]]);
588}
589
590u16 CalculateBoxPokemonChecksum(struct BoxPokemon* pkm)
591{
592 u16 checksum = 0;
593
594 union PokemonSubstruct* substructs[4] = {
595 GetBoxPokemonSubstruct(pkm,0),
596 GetBoxPokemonSubstruct(pkm,1),
597 GetBoxPokemonSubstruct(pkm,2),
598 GetBoxPokemonSubstruct(pkm,3)
599 };
600
601 for (int substruct = 0; substruct < 4; substruct++)
602 {
603 for (int i = 0; i < 6; i++)
604 {
605 checksum += substructs[substruct]->raw[i];
606 }
607 }
608
609 return checksum;
610}
611
612void FixBoxPokemonChecksum(struct BoxPokemon* pkm)
613{
614 pkm->checksum = CalculateBoxPokemonChecksum(pkm);
615}
616
617struct PokemonSubstruct0* GetPokemonSubstruct0(struct Pokemon* pkm)
618{
619 struct BoxPokemon* boxMon = &(pkm->box);
620
621 return GetBoxPokemonSubstruct0(boxMon);
622}
623
624struct PokemonSubstruct0* GetBoxPokemonSubstruct0(struct BoxPokemon* pkm)
625{
626 return &(GetBoxPokemonSubstruct(pkm,0)->type0);
627}
628
629struct PokemonSubstruct1* GetPokemonSubstruct1(struct Pokemon* pkm)
630{
631 struct BoxPokemon* boxMon = &(pkm->box);
632
633 return GetBoxPokemonSubstruct1(boxMon);
634}
635
636struct PokemonSubstruct1* GetBoxPokemonSubstruct1(struct BoxPokemon* pkm)
637{
638 return &(GetBoxPokemonSubstruct(pkm,1)->type1);
639}
640
641struct PokemonSubstruct2* GetPokemonSubstruct2(struct Pokemon* pkm)
642{
643 struct BoxPokemon* boxMon = &(pkm->box);
644
645 return GetBoxPokemonSubstruct2(boxMon);
646}
647
648struct PokemonSubstruct2* GetBoxPokemonSubstruct2(struct BoxPokemon* pkm)
649{
650 return &(GetBoxPokemonSubstruct(pkm,2)->type2);
651}
652
653struct PokemonSubstruct3* GetPokemonSubstruct3(struct Pokemon* pkm)
654{
655 struct BoxPokemon* boxMon = &(pkm->box);
656
657 return GetBoxPokemonSubstruct3(boxMon);
658}
659
660struct PokemonSubstruct3* GetBoxPokemonSubstruct3(struct BoxPokemon* pkm)
661{
662 return &(GetBoxPokemonSubstruct(pkm,3)->type3);
663}