about summary refs log tree commit diff stats
path: root/gba/source/gamedata.c
diff options
context:
space:
mode:
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}