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 | } | ||
