diff options
Diffstat (limited to 'gba/source/gamedata.c')
-rw-r--r-- | gba/source/gamedata.c | 167 |
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 | ||
10 | void decryptSaveStructures( | 10 | static 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 | ||
122 | bool initSaveData( | 122 | static 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 | |||
130 | bool 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 | |||
528 | void DecryptPokemon(struct Pokemon* pkm) | ||
529 | { | ||
530 | struct BoxPokemon* boxMon = &(pkm->box); | ||
531 | |||
532 | CryptBoxPokemon(boxMon); | ||
533 | } | ||
534 | |||
535 | void DecryptBoxPokemon(struct BoxPokemon* pkm) | ||
536 | { | ||
537 | CryptBoxPokemon(pkm); | ||
538 | } | ||
539 | |||
540 | void EncryptPokemon(struct Pokemon* pkm) | ||
541 | { | ||
542 | struct BoxPokemon* boxMon = &(pkm->box); | ||
543 | |||
544 | EncryptBoxPokemon(boxMon); | ||
545 | } | ||
546 | |||
547 | void EncryptBoxPokemon(struct BoxPokemon* pkm) | ||
548 | { | ||
549 | FixBoxPokemonChecksum(pkm); | ||
550 | CryptBoxPokemon(pkm); | ||
551 | } | ||
552 | |||
553 | union PokemonSubstruct* GetPokemonSubstruct(struct Pokemon* pkm,u8 substructId) | ||
554 | { | ||
555 | struct BoxPokemon* boxMon = &(pkm->box); | ||
556 | |||
557 | return GetBoxPokemonSubstruct(boxMon,substructId); | ||
558 | } | ||
559 | |||
560 | union 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 | |||
590 | u16 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 | |||
612 | void FixBoxPokemonChecksum(struct BoxPokemon* pkm) | ||
613 | { | ||
614 | pkm->checksum = CalculateBoxPokemonChecksum(pkm); | ||
615 | } | ||
616 | |||
617 | struct PokemonSubstruct0* GetPokemonSubstruct0(struct Pokemon* pkm) | ||
618 | { | ||
619 | struct BoxPokemon* boxMon = &(pkm->box); | ||
620 | |||
621 | return GetBoxPokemonSubstruct0(boxMon); | ||
622 | } | ||
623 | |||
624 | struct PokemonSubstruct0* GetBoxPokemonSubstruct0(struct BoxPokemon* pkm) | ||
625 | { | ||
626 | return &(GetBoxPokemonSubstruct(pkm,0)->type0); | ||
627 | } | ||
628 | |||
629 | struct PokemonSubstruct1* GetPokemonSubstruct1(struct Pokemon* pkm) | ||
630 | { | ||
631 | struct BoxPokemon* boxMon = &(pkm->box); | ||
632 | |||
633 | return GetBoxPokemonSubstruct1(boxMon); | ||
634 | } | ||
635 | |||
636 | struct PokemonSubstruct1* GetBoxPokemonSubstruct1(struct BoxPokemon* pkm) | ||
637 | { | ||
638 | return &(GetBoxPokemonSubstruct(pkm,1)->type1); | ||
639 | } | ||
640 | |||
641 | struct PokemonSubstruct2* GetPokemonSubstruct2(struct Pokemon* pkm) | ||
642 | { | ||
643 | struct BoxPokemon* boxMon = &(pkm->box); | ||
644 | |||
645 | return GetBoxPokemonSubstruct2(boxMon); | ||
646 | } | ||
647 | |||
648 | struct PokemonSubstruct2* GetBoxPokemonSubstruct2(struct BoxPokemon* pkm) | ||
649 | { | ||
650 | return &(GetBoxPokemonSubstruct(pkm,2)->type2); | ||
651 | } | ||
652 | |||
653 | struct PokemonSubstruct3* GetPokemonSubstruct3(struct Pokemon* pkm) | ||
654 | { | ||
655 | struct BoxPokemon* boxMon = &(pkm->box); | ||
656 | |||
657 | return GetBoxPokemonSubstruct3(boxMon); | ||
658 | } | ||
659 | |||
660 | struct PokemonSubstruct3* GetBoxPokemonSubstruct3(struct BoxPokemon* pkm) | ||
661 | { | ||
662 | return &(GetBoxPokemonSubstruct(pkm,3)->type3); | ||
663 | } | ||