summaryrefslogtreecommitdiff
path: root/src/load_save.c
diff options
context:
space:
mode:
authorProjectRevoTPP <projectrevotpp@hotmail.com>2018-10-15 22:21:18 -0400
committerProjectRevoTPP <projectrevotpp@hotmail.com>2018-10-15 22:21:18 -0400
commit77d98a23c6553e1264c8488286f4a7b11287322e (patch)
tree9f3dc7ac5580c2523b775d934cf617b7aaa407c0 /src/load_save.c
parenta2e49c4d5c275b28b6485d404e305a98c935d022 (diff)
decompile load_save.c
Diffstat (limited to 'src/load_save.c')
-rw-r--r--src/load_save.c297
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);
+}