diff options
author | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2018-10-15 22:21:18 -0400 |
---|---|---|
committer | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2018-10-15 22:21:18 -0400 |
commit | 77d98a23c6553e1264c8488286f4a7b11287322e (patch) | |
tree | 9f3dc7ac5580c2523b775d934cf617b7aaa407c0 /src/load_save.c | |
parent | a2e49c4d5c275b28b6485d404e305a98c935d022 (diff) |
decompile load_save.c
Diffstat (limited to 'src/load_save.c')
-rw-r--r-- | src/load_save.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/load_save.c b/src/load_save.c new file mode 100644 index 000000000..eba01642c --- /dev/null +++ b/src/load_save.c @@ -0,0 +1,297 @@ +#include "global.h" +#include "gba/flash_internal.h" +#include "load_save.h" +#include "main.h" +#include "pokemon.h" +#include "random.h" +#include "malloc.h" +#include "item.h" + +extern void sub_8099E44(void); +extern void sub_8110840(void *oldSave); +extern void sub_8055778(int); +extern void sub_8054F38(u32 newKey); +extern void ApplyNewEncryptionKeyToBagItems_(u32 newKey); +extern void sub_815EE6C(u32 newKey); + +#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}; + +EWRAM_DATA struct SaveBlock1 gSaveBlock1 = {0}; +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; + +void CheckForFlashMemory(void) +{ + if (!IdentifyFlash()) + { + gFlashMemoryPresent = TRUE; + InitFlashTimer(); + } + else + { + gFlashMemoryPresent = FALSE; + } +} + +void ClearSav2(void) +{ + CpuFill16(0, &gSaveBlock2, sizeof(struct SaveBlock2) + sizeof(gSaveBlock2_DMA)); +} + +void ClearSav1(void) +{ + CpuFill16(0, &gSaveBlock1, sizeof(struct SaveBlock1) + sizeof(gSaveBlock1_DMA)); +} + +void SetSaveBlocksPointers(void) +{ + u32 offset; + struct SaveBlock1** sav1_LocalVar = &gSaveBlock1Ptr; + void *oldSave = (void *)gSaveBlock1Ptr; + + offset = (Random()) & (SAVEBLOCK_MOVE_RANGE - 4); + + gSaveBlock2Ptr = (void*)(&gSaveBlock2) + offset; + *sav1_LocalVar = (void*)(&gSaveBlock1) + offset; + gPokemonStoragePtr = (void*)(&gPokemonStorage) + offset; + + sub_8099E44(); + sub_8110840(oldSave); +} + +void MoveSaveBlocks_ResetHeap(void) +{ + void *vblankCB, *hblankCB; + u32 encryptionKey; + struct SaveBlock2 *saveBlock2Copy; + struct SaveBlock1 *saveBlock1Copy; + struct PokemonStorage *pokemonStorageCopy; + + // save interrupt functions and turn them off + vblankCB = gMain.vblankCallback; + hblankCB = gMain.hblankCallback; + gMain.vblankCallback = NULL; + gMain.hblankCallback = NULL; + gMain.vblankCounter1 = NULL; + + saveBlock2Copy = (struct SaveBlock2 *)(gHeap); + saveBlock1Copy = (struct SaveBlock1 *)(gHeap + sizeof(struct SaveBlock2)); + pokemonStorageCopy = (struct PokemonStorage *)(gHeap + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1)); + + // backup the saves. + *saveBlock2Copy = *gSaveBlock2Ptr; + *saveBlock1Copy = *gSaveBlock1Ptr; + *pokemonStorageCopy = *gPokemonStoragePtr; + + // change saveblocks' pointers + SetSaveBlocksPointers(); // unlike Emerald, this does not use + // the trainer ID sum for an offset. + + // restore saveblock data since the pointers changed + *gSaveBlock2Ptr = *saveBlock2Copy; + *gSaveBlock1Ptr = *saveBlock1Copy; + *gPokemonStoragePtr = *pokemonStorageCopy; + + // heap was destroyed in the copying process, so reset it + InitHeap(gHeap, HEAP_SIZE); + + // restore interrupt functions + gMain.hblankCallback = hblankCB; + gMain.vblankCallback = vblankCB; + + // create a new encryption key + encryptionKey = (Random() << 0x10) + (Random()); + ApplyNewEncryptionKeyToAllEncryptedData(encryptionKey); + gSaveBlock2Ptr->encryptionKey = encryptionKey; +} + +u32 sav2_x1_query_bit1(void) +{ + return gSaveBlock2Ptr->specialSaveWarp & 1; +} + +void sav2_x9_clear_bit1(void) +{ + gSaveBlock2Ptr->specialSaveWarp &= ~1; +} + +void sub_804C1AC(void) +{ + gSaveBlock2Ptr->specialSaveWarp |= 1; +} + +void sub_804C1C0(void) +{ + sub_8055778(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 SaveMapObjects(void) +{ + int i; + + for (i = 0; i < NUM_FIELD_OBJECTS; i++) + gSaveBlock1Ptr->mapObjects[i] = gMapObjects[i]; +} + +void LoadMapObjects(void) +{ + int i; + + for (i = 0; i < NUM_FIELD_OBJECTS; i++) + gMapObjects[i] = gSaveBlock1Ptr->mapObjects[i]; +} + +void SaveSerializedGame(void) +{ + SavePlayerParty(); + SaveMapObjects(); +} + +void LoadSerializedGame(void) +{ + LoadPlayerParty(); + LoadMapObjects(); +} + +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; +} + +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) +{ + int i; + + for(i = 0; i < 4; i++) + ApplyNewEncryptionKeyToWord(&gSaveBlock1Ptr->unkArray[i][1], encryptionKey); + + sub_8054F38(encryptionKey); + ApplyNewEncryptionKeyToBagItems_(encryptionKey); + sub_815EE6C(encryptionKey); + ApplyNewEncryptionKeyToWord(&gSaveBlock1Ptr->money, encryptionKey); + ApplyNewEncryptionKeyToHword(&gSaveBlock1Ptr->coins, encryptionKey); +} |