diff options
Diffstat (limited to 'src/load_save.c')
-rw-r--r-- | src/load_save.c | 234 |
1 files changed, 210 insertions, 24 deletions
diff --git a/src/load_save.c b/src/load_save.c index 68d978e3d..005af7c42 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -3,19 +3,31 @@ #include "load_save.h" #include "main.h" #include "pokemon.h" -#include "rng.h" +#include "random.h" #include "malloc.h" +#include "item.h" extern void* gUnknown_0203CF5C; extern bool16 IdentifyFlash(void); -extern void SetBagItemsPointers(void); extern void SetDecorationInventoriesPointers(void); - -void ApplyNewEncyprtionKeyToAllEncryptedData(u32 encryptionKey); +extern void ApplyNewEncryptionKeyToGameStats(u32 key); +extern void ApplyNewEncryptionKeyToBerryPowder(u32 key); +extern void sub_8084FAC(int unused); #define SAVEBLOCK_MOVE_RANGE 128 +struct LoadedSaveData +{ + /*0x0000*/ struct ItemSlot items[BAG_ITEMS_COUNT]; + /*0x0078*/ struct ItemSlot keyItems[BAG_KEYITEMS_COUNT]; + /*0x00F0*/ struct ItemSlot pokeBalls[BAG_POKEBALLS_COUNT]; + /*0x0130*/ struct ItemSlot TMsHMs[BAG_TMHM_COUNT]; + /*0x0230*/ struct ItemSlot berries[BAG_BERRIES_COUNT]; + /*0x02E8*/ struct MailStruct mail[MAIL_COUNT]; +}; + +// EWRAM DATA EWRAM_DATA struct SaveBlock2 gSaveblock2 = {0}; EWRAM_DATA u8 gSaveblock2_DMA[SAVEBLOCK_MOVE_RANGE] = {0}; @@ -25,6 +37,16 @@ EWRAM_DATA u8 gSaveblock1_DMA[SAVEBLOCK_MOVE_RANGE] = {0}; EWRAM_DATA struct PokemonStorage gPokemonStorage = {0}; EWRAM_DATA u8 gSaveblock3_DMA[SAVEBLOCK_MOVE_RANGE] = {0}; +EWRAM_DATA struct LoadedSaveData gLoadedSaveData = {0}; +EWRAM_DATA u32 gLastEncryptionKey = 0; + +// IWRAM common +IWRAM_DATA bool32 gFlashMemoryPresent; +IWRAM_DATA struct SaveBlock1 *gSaveBlock1Ptr; +IWRAM_DATA struct SaveBlock2 *gSaveBlock2Ptr; +IWRAM_DATA struct PokemonStorage *gPokemonStoragePtr; + +// code void CheckForFlashMemory(void) { if (!IdentifyFlash()) @@ -33,7 +55,9 @@ void CheckForFlashMemory(void) InitFlashTimer(); } else + { gFlashMemoryPresent = FALSE; + } } void ClearSav2(void) @@ -60,18 +84,13 @@ void SetSaveBlocksPointers(u16 offset) SetDecorationInventoriesPointers(); } -struct SaveBlocksInOne -{ - struct SaveBlock2 sav2; - struct SaveBlock1 sav1; - struct PokemonStorage sav3; -}; -/* void MoveSaveBlocks_ResetHeap(void) { void *vblankCB, *hblankCB; u32 encryptionKey; - struct SaveBlocksInOne* copiedSavs; + struct SaveBlock2 *saveBlock2Copy; + struct SaveBlock1 *saveBlock1Copy; + struct PokemonStorage *pokemonStorageCopy; // save interrupt functions and turn them off vblankCB = gMain.vblankCallback; @@ -80,24 +99,30 @@ void MoveSaveBlocks_ResetHeap(void) gMain.hblankCallback = NULL; gUnknown_0203CF5C = NULL; - copiedSavs = (void*)(gHeap); + saveBlock2Copy = (struct SaveBlock2 *)(gHeap); + saveBlock1Copy = (struct SaveBlock1 *)(gHeap + sizeof(struct SaveBlock2)); + pokemonStorageCopy = (struct PokemonStorage *)(gHeap + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1)); - // copy saveblocks' content - copiedSavs->sav2 = *gSaveBlock2Ptr; - copiedSavs->sav1 = *gSaveBlock1Ptr; - copiedSavs->sav3 = *gPokemonStoragePtr; + // backup the saves. + *saveBlock2Copy = *gSaveBlock2Ptr; + *saveBlock1Copy = *gSaveBlock1Ptr; + *pokemonStorageCopy = *gPokemonStoragePtr; // change saveblocks' pointers // argument is a sum of the individual trainerId bytes - SetSaveBlocksPointers(copiedSavs->sav2.playerTrainerId[0] + copiedSavs->sav2.playerTrainerId[1] + copiedSavs->sav2.playerTrainerId[2] + copiedSavs->sav2.playerTrainerId[3]); + SetSaveBlocksPointers( + saveBlock2Copy->playerTrainerId[0] + + saveBlock2Copy->playerTrainerId[1] + + saveBlock2Copy->playerTrainerId[2] + + saveBlock2Copy->playerTrainerId[3]); // restore saveblock data since the pointers changed - *gSaveBlock2Ptr = copiedSavs->sav2; - *gSaveBlock1Ptr = copiedSavs->sav1; - *gPokemonStoragePtr = copiedSavs->sav3; + *gSaveBlock2Ptr = *saveBlock2Copy; + *gSaveBlock1Ptr = *saveBlock1Copy; + *gPokemonStoragePtr = *pokemonStorageCopy; // heap was destroyed in the copying process, so reset it - InitHeap(gHeap, sizeof(gHeap)); + InitHeap(gHeap, HEAP_SIZE); // restore interrupt functions gMain.hblankCallback = hblankCB; @@ -105,6 +130,167 @@ void MoveSaveBlocks_ResetHeap(void) // create a new encryption key encryptionKey = (Random() << 0x10) + (Random()); - ApplyNewEncyprtionKeyToAllEncryptedData(encryptionKey); + ApplyNewEncryptionKeyToAllEncryptedData(encryptionKey); gSaveBlock2Ptr->encryptionKey = encryptionKey; -}*/ +} + +u32 GetSecretBase2Field_9(void) +{ + return gSaveBlock2Ptr->specialSaveWarp & 1; +} + +void ClearSecretBase2Field_9(void) +{ + gSaveBlock2Ptr->specialSaveWarp &= ~1; +} + +void sub_8076D48(void) +{ + gSaveBlock2Ptr->specialSaveWarp |= 1; +} + +void sub_8076D5C(void) +{ + sub_8084FAC(0); + gSaveBlock2Ptr->specialSaveWarp |= 1; +} + +void sav2_gender2_inplace_and_xFE(void) +{ + gSaveBlock2Ptr->specialSaveWarp &= ~1; +} + +void SavePlayerParty(void) +{ + int i; + + gSaveBlock1Ptr->playerPartyCount = gPlayerPartyCount; + + for (i = 0; i < PARTY_SIZE; i++) + gSaveBlock1Ptr->playerParty[i] = gPlayerParty[i]; +} + +void LoadPlayerParty(void) +{ + int i; + + gPlayerPartyCount = gSaveBlock1Ptr->playerPartyCount; + + for (i = 0; i < PARTY_SIZE; i++) + gPlayerParty[i] = gSaveBlock1Ptr->playerParty[i]; +} + +void SaveEventObjects(void) +{ + int i; + + for (i = 0; i < EVENT_OBJECTS_COUNT; i++) + gSaveBlock1Ptr->eventObjects[i] = gEventObjects[i]; +} + +void LoadEventObjects(void) +{ + int i; + + for (i = 0; i < EVENT_OBJECTS_COUNT; i++) + gEventObjects[i] = gSaveBlock1Ptr->eventObjects[i]; +} + +void SaveSerializedGame(void) +{ + SavePlayerParty(); + SaveEventObjects(); +} + +void LoadSerializedGame(void) +{ + LoadPlayerParty(); + LoadEventObjects(); +} + +void LoadPlayerBag(void) +{ + int i; + + // load player items. + for (i = 0; i < BAG_ITEMS_COUNT; i++) + gLoadedSaveData.items[i] = gSaveBlock1Ptr->bagPocket_Items[i]; + + // load player key items. + for (i = 0; i < BAG_KEYITEMS_COUNT; i++) + gLoadedSaveData.keyItems[i] = gSaveBlock1Ptr->bagPocket_KeyItems[i]; + + // load player pokeballs. + for (i = 0; i < BAG_POKEBALLS_COUNT; i++) + gLoadedSaveData.pokeBalls[i] = gSaveBlock1Ptr->bagPocket_PokeBalls[i]; + + // load player TMs and HMs. + for (i = 0; i < BAG_TMHM_COUNT; i++) + gLoadedSaveData.TMsHMs[i] = gSaveBlock1Ptr->bagPocket_TMHM[i]; + + // load player berries. + for (i = 0; i < BAG_BERRIES_COUNT; i++) + gLoadedSaveData.berries[i] = gSaveBlock1Ptr->bagPocket_Berries[i]; + + // load mail. + for (i = 0; i < MAIL_COUNT; i++) + gLoadedSaveData.mail[i] = gSaveBlock1Ptr->mail[i]; + + gLastEncryptionKey = gSaveBlock2Ptr->encryptionKey; +} + +void SavePlayerBag(void) +{ + int i; + u32 encryptionKeyBackup; + + // save player items. + for (i = 0; i < BAG_ITEMS_COUNT; i++) + gSaveBlock1Ptr->bagPocket_Items[i] = gLoadedSaveData.items[i]; + + // save player key items. + for (i = 0; i < BAG_KEYITEMS_COUNT; i++) + gSaveBlock1Ptr->bagPocket_KeyItems[i] = gLoadedSaveData.keyItems[i]; + + // save player pokeballs. + for (i = 0; i < BAG_POKEBALLS_COUNT; i++) + gSaveBlock1Ptr->bagPocket_PokeBalls[i] = gLoadedSaveData.pokeBalls[i]; + + // save player TMs and HMs. + for (i = 0; i < BAG_TMHM_COUNT; i++) + gSaveBlock1Ptr->bagPocket_TMHM[i] = gLoadedSaveData.TMsHMs[i]; + + // save player berries. + for (i = 0; i < BAG_BERRIES_COUNT; i++) + gSaveBlock1Ptr->bagPocket_Berries[i] = gLoadedSaveData.berries[i]; + + // save mail. + for (i = 0; i < MAIL_COUNT; i++) + gSaveBlock1Ptr->mail[i] = gLoadedSaveData.mail[i]; + + encryptionKeyBackup = gSaveBlock2Ptr->encryptionKey; + gSaveBlock2Ptr->encryptionKey = gLastEncryptionKey; + ApplyNewEncryptionKeyToBagItems(encryptionKeyBackup); + gSaveBlock2Ptr->encryptionKey = encryptionKeyBackup; // updated twice? +} + +void ApplyNewEncryptionKeyToHword(u16 *hWord, u32 newKey) +{ + *hWord ^= gSaveBlock2Ptr->encryptionKey; + *hWord ^= newKey; +} + +void ApplyNewEncryptionKeyToWord(u32 *word, u32 newKey) +{ + *word ^= gSaveBlock2Ptr->encryptionKey; + *word ^= newKey; +} + +void ApplyNewEncryptionKeyToAllEncryptedData(u32 encryptionKey) +{ + ApplyNewEncryptionKeyToGameStats(encryptionKey); + ApplyNewEncryptionKeyToBagItems_(encryptionKey); + ApplyNewEncryptionKeyToBerryPowder(encryptionKey); + ApplyNewEncryptionKeyToWord(&gSaveBlock1Ptr->money, encryptionKey); + ApplyNewEncryptionKeyToHword(&gSaveBlock1Ptr->coins, encryptionKey); +} |