mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Document remainder of save.c
This commit is contained in:
parent
ab1074e629
commit
adf773f1ed
@ -3,11 +3,11 @@ gLastSaveCounter
|
|||||||
gLastKnownGoodSector
|
gLastKnownGoodSector
|
||||||
gDamagedSaveSectors
|
gDamagedSaveSectors
|
||||||
gSaveCounter
|
gSaveCounter
|
||||||
gFastSaveSection
|
gReadWriteSector
|
||||||
gUnknown_03006208
|
gIncrementalSectorId
|
||||||
gSaveUnusedVar
|
gSaveUnusedVar
|
||||||
gSaveFileStatus
|
gSaveFileStatus
|
||||||
gGameContinueCallback
|
gGameContinueCallback
|
||||||
gRamSaveSectionLocations
|
gRamSaveSectorLocations
|
||||||
gSaveUnusedVar2
|
gSaveUnusedVar2
|
||||||
gSaveAttemptStatus
|
gSaveAttemptStatus
|
||||||
|
@ -24,8 +24,8 @@ void SavePlayerParty(void);
|
|||||||
void LoadPlayerParty(void);
|
void LoadPlayerParty(void);
|
||||||
void SaveObjectEvents(void);
|
void SaveObjectEvents(void);
|
||||||
void LoadObjectEvents(void);
|
void LoadObjectEvents(void);
|
||||||
void SaveSerializedGame(void);
|
void CopyPartyAndObjectsToSave(void);
|
||||||
void LoadSerializedGame(void);
|
void CopyPartyAndObjectsFromSave(void);
|
||||||
void LoadPlayerBag(void);
|
void LoadPlayerBag(void);
|
||||||
void SavePlayerBag(void);
|
void SavePlayerBag(void);
|
||||||
void ApplyNewEncryptionKeyToHword(u16 *hWord, u32 newKey);
|
void ApplyNewEncryptionKeyToHword(u16 *hWord, u32 newKey);
|
||||||
|
129
include/save.h
129
include/save.h
@ -1,43 +1,43 @@
|
|||||||
#ifndef GUARD_SAVE_H
|
#ifndef GUARD_SAVE_H
|
||||||
#define GUARD_SAVE_H
|
#define GUARD_SAVE_H
|
||||||
|
|
||||||
struct SaveSectionLocation
|
// Each 4 KiB flash sector contains 3968 bytes of actual data followed by a 128 byte footer.
|
||||||
{
|
// Only 12 bytes of the footer are used.
|
||||||
void *data;
|
|
||||||
u16 size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SaveSection
|
|
||||||
{
|
|
||||||
u8 data[0xFF4];
|
|
||||||
u16 id;
|
|
||||||
u16 checksum;
|
|
||||||
u32 security;
|
|
||||||
u32 counter;
|
|
||||||
}; // size is 0x1000
|
|
||||||
|
|
||||||
// headless save section?
|
|
||||||
struct UnkSaveSection
|
|
||||||
{
|
|
||||||
u8 data[0xFF4];
|
|
||||||
u32 security;
|
|
||||||
}; // size is 0xFF8
|
|
||||||
|
|
||||||
struct SaveSectionOffsets
|
|
||||||
{
|
|
||||||
u16 toAdd;
|
|
||||||
u16 size;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Each 4 KiB flash sector contains 3968 bytes of actual data followed by a 128 byte footer
|
|
||||||
#define SECTOR_DATA_SIZE 3968
|
#define SECTOR_DATA_SIZE 3968
|
||||||
#define SECTOR_FOOTER_SIZE 128
|
#define SECTOR_FOOTER_SIZE 128
|
||||||
#define SECTOR_SIZE (SECTOR_DATA_SIZE + SECTOR_FOOTER_SIZE)
|
#define SECTOR_SIZE (SECTOR_DATA_SIZE + SECTOR_FOOTER_SIZE)
|
||||||
|
|
||||||
#define NUM_SAVE_SLOTS 2
|
#define NUM_SAVE_SLOTS 2
|
||||||
|
|
||||||
#define UNKNOWN_CHECK_VALUE 0x8012025
|
// If the sector's security field is not this value then the sector is either invalid or empty.
|
||||||
#define SPECIAL_SECTION_SENTINEL 0xB39D
|
#define SECTOR_SECURITY_NUM 0x8012025
|
||||||
|
|
||||||
|
#define SPECIAL_SECTOR_SENTINEL 0xB39D
|
||||||
|
|
||||||
|
#define SECTOR_ID_SAVEBLOCK2 0
|
||||||
|
#define SECTOR_ID_SAVEBLOCK1_START 1
|
||||||
|
#define SECTOR_ID_SAVEBLOCK1_END 4
|
||||||
|
#define SECTOR_ID_PKMN_STORAGE_START 5
|
||||||
|
#define SECTOR_ID_PKMN_STORAGE_END 13
|
||||||
|
#define NUM_SECTORS_PER_SLOT 14
|
||||||
|
// Save Slot 1: 0-13; Save Slot 2: 14-27
|
||||||
|
#define SECTOR_ID_HOF_1 28
|
||||||
|
#define SECTOR_ID_HOF_2 29
|
||||||
|
#define SECTOR_ID_TRAINER_HILL 30
|
||||||
|
#define SECTOR_ID_RECORDED_BATTLE 31
|
||||||
|
#define SECTORS_COUNT 32
|
||||||
|
|
||||||
|
#define NUM_HOF_SECTORS 2
|
||||||
|
|
||||||
|
#define SAVE_STATUS_EMPTY 0
|
||||||
|
#define SAVE_STATUS_OK 1
|
||||||
|
#define SAVE_STATUS_CORRUPT 2
|
||||||
|
#define SAVE_STATUS_NO_FLASH 4
|
||||||
|
#define SAVE_STATUS_ERROR 0xFF
|
||||||
|
|
||||||
|
// Special sector id value for certain save functions to
|
||||||
|
// indicate that no specific sector should be used.
|
||||||
|
#define FULL_SAVE_SLOT 0xFFFF
|
||||||
|
|
||||||
// SetDamagedSectorBits states
|
// SetDamagedSectorBits states
|
||||||
enum
|
enum
|
||||||
@ -51,7 +51,7 @@ enum
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SAVE_NORMAL,
|
SAVE_NORMAL,
|
||||||
SAVE_LINK,
|
SAVE_LINK, // Link / Battle Frontier
|
||||||
//EREADER_SAVE, // deprecated in Emerald
|
//EREADER_SAVE, // deprecated in Emerald
|
||||||
SAVE_LINK2, // unknown 2nd link save
|
SAVE_LINK2, // unknown 2nd link save
|
||||||
SAVE_HALL_OF_FAME,
|
SAVE_HALL_OF_FAME,
|
||||||
@ -59,54 +59,55 @@ enum
|
|||||||
SAVE_HALL_OF_FAME_ERASE_BEFORE // unused
|
SAVE_HALL_OF_FAME_ERASE_BEFORE // unused
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SECTOR_ID_SAVEBLOCK2 0
|
// A save sector location holds a pointer to the data for a particular sector
|
||||||
#define SECTOR_ID_SAVEBLOCK1_START 1
|
// and the size of that data. Size cannot be greater than SECTOR_DATA_SIZE.
|
||||||
#define SECTOR_ID_SAVEBLOCK1_END 4
|
struct SaveSectorLocation
|
||||||
#define SECTOR_ID_PKMN_STORAGE_START 5
|
{
|
||||||
#define SECTOR_ID_PKMN_STORAGE_END 13
|
void *data;
|
||||||
#define NUM_SECTORS_PER_SLOT 14
|
u16 size;
|
||||||
// Save Slot 1: 0-13; Save Slot 2: 14-27
|
};
|
||||||
#define SECTOR_ID_HOF_1 28
|
|
||||||
#define SECTOR_ID_HOF_2 29
|
|
||||||
#define SECTOR_ID_TRAINER_HILL 30
|
|
||||||
#define SECTOR_ID_RECORDED_BATTLE 31
|
|
||||||
#define SECTORS_COUNT 32
|
|
||||||
|
|
||||||
#define SAVE_STATUS_EMPTY 0
|
struct SaveSector
|
||||||
#define SAVE_STATUS_OK 1
|
{
|
||||||
#define SAVE_STATUS_CORRUPT 2
|
u8 data[SECTOR_DATA_SIZE];
|
||||||
#define SAVE_STATUS_NO_FLASH 4
|
u8 unused[SECTOR_FOOTER_SIZE - 12]; // Unused portion of the footer
|
||||||
#define SAVE_STATUS_ERROR 0xFF
|
u16 id;
|
||||||
|
u16 checksum;
|
||||||
|
u32 security;
|
||||||
|
u32 counter;
|
||||||
|
}; // size is SECTOR_SIZE (0x1000)
|
||||||
|
|
||||||
|
#define SECTOR_SECURITY_OFFSET offsetof(struct SaveSector, security)
|
||||||
|
#define SECTOR_COUNTER_OFFSET offsetof(struct SaveSector, counter)
|
||||||
|
|
||||||
extern u16 gLastWrittenSector;
|
extern u16 gLastWrittenSector;
|
||||||
extern u32 gLastSaveCounter;
|
extern u32 gLastSaveCounter;
|
||||||
extern u16 gLastKnownGoodSector;
|
extern u16 gLastKnownGoodSector;
|
||||||
extern u32 gDamagedSaveSectors;
|
extern u32 gDamagedSaveSectors;
|
||||||
extern u32 gSaveCounter;
|
extern u32 gSaveCounter;
|
||||||
extern struct SaveSection *gFastSaveSection;
|
extern struct SaveSector *gFastSaveSector;
|
||||||
extern u16 gUnknown_03006208;
|
extern u16 gIncrementalSectorId;
|
||||||
extern u16 gSaveFileStatus;
|
extern u16 gSaveFileStatus;
|
||||||
extern void (*gGameContinueCallback)(void);
|
extern void (*gGameContinueCallback)(void);
|
||||||
extern struct SaveSectionLocation gRamSaveSectionLocations[];
|
extern struct SaveSectorLocation gRamSaveSectorLocations[];
|
||||||
extern u16 gUnknown_03006294;
|
|
||||||
|
|
||||||
extern struct SaveSection gSaveDataBuffer;
|
extern struct SaveSector gSaveDataBuffer;
|
||||||
|
|
||||||
void ClearSaveData(void);
|
void ClearSaveData(void);
|
||||||
void Save_ResetSaveCounters(void);
|
void Save_ResetSaveCounters(void);
|
||||||
u8 HandleSavingData(u8 saveType);
|
u8 HandleSavingData(u8 saveType);
|
||||||
u8 TrySavingData(u8 saveType);
|
u8 TrySavingData(u8 saveType);
|
||||||
bool8 sub_8153380(void);
|
bool8 LinkFullSave_Init(void);
|
||||||
bool8 sub_81533AC(void);
|
bool8 LinkFullSave_WriteSector(void);
|
||||||
bool8 sub_81533E0(void);
|
bool8 LinkFullSave_ReplaceLastSector(void);
|
||||||
bool8 sub_8153408(void);
|
bool8 LinkFullSave_SetLastSectorSecurity(void);
|
||||||
bool8 FullSaveGame(void);
|
bool8 WriteSaveBlock2(void);
|
||||||
bool8 CheckSaveFile(void);
|
bool8 WriteSaveBlock1Sector(void);
|
||||||
u8 Save_LoadGameData(u8 saveType);
|
u8 LoadGameSave(u8 saveType);
|
||||||
u16 GetSaveBlocksPointersBaseOffset(void);
|
u16 GetSaveBlocksPointersBaseOffset(void);
|
||||||
u32 TryReadSpecialSaveSection(u8 sector, u8* dst);
|
u32 TryReadSpecialSaveSector(u8 sector, u8* dst);
|
||||||
u32 TryWriteSpecialSaveSection(u8 sector, u8* src);
|
u32 TryWriteSpecialSaveSector(u8 sector, u8* src);
|
||||||
void Task_LinkSave(u8 taskId);
|
void Task_LinkFullSave(u8 taskId);
|
||||||
|
|
||||||
// save_failed_screen.c
|
// save_failed_screen.c
|
||||||
void DoSaveFailedScreen(u8 saveType);
|
void DoSaveFailedScreen(u8 saveType);
|
||||||
|
@ -2785,7 +2785,7 @@ static bool8 LinkPlayAgainHandleSaving(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
FullSaveGame();
|
WriteSaveBlock2();
|
||||||
sBerryBlender->linkPlayAgainState++;
|
sBerryBlender->linkPlayAgainState++;
|
||||||
sBerryBlender->framesToWait = 0;
|
sBerryBlender->framesToWait = 0;
|
||||||
break;
|
break;
|
||||||
@ -2799,7 +2799,7 @@ static bool8 LinkPlayAgainHandleSaving(void)
|
|||||||
case 4:
|
case 4:
|
||||||
if (IsLinkTaskFinished())
|
if (IsLinkTaskFinished())
|
||||||
{
|
{
|
||||||
if (CheckSaveFile())
|
if (WriteSaveBlock1Sector())
|
||||||
{
|
{
|
||||||
sBerryBlender->linkPlayAgainState = 5;
|
sBerryBlender->linkPlayAgainState = 5;
|
||||||
}
|
}
|
||||||
|
@ -3244,10 +3244,10 @@ static u32 Cmd_SaveGame(struct BerryCrushGame *game, u8 *args)
|
|||||||
DrawDialogueFrame(0, 0);
|
DrawDialogueFrame(0, 0);
|
||||||
AddTextPrinterParameterized2(0, FONT_NORMAL, gText_SavingDontTurnOffPower, 0, 0, 2, 1, 3);
|
AddTextPrinterParameterized2(0, FONT_NORMAL, gText_SavingDontTurnOffPower, 0, 0, 2, 1, 3);
|
||||||
CopyWindowToVram(0, 3);
|
CopyWindowToVram(0, 3);
|
||||||
CreateTask(Task_LinkSave, 0);
|
CreateTask(Task_LinkFullSave, 0);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (FuncIsActiveTask(Task_LinkSave))
|
if (FuncIsActiveTask(Task_LinkFullSave))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -5035,12 +5035,12 @@ static void Msg_SavingDontTurnOff(void)
|
|||||||
case 2:
|
case 2:
|
||||||
if (!IsDma3ManagerBusyWithBgCopy())
|
if (!IsDma3ManagerBusyWithBgCopy())
|
||||||
{
|
{
|
||||||
CreateTask(Task_LinkSave, 0);
|
CreateTask(Task_LinkFullSave, 0);
|
||||||
sGfx->state++;
|
sGfx->state++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (!FuncIsActiveTask(Task_LinkSave))
|
if (!FuncIsActiveTask(Task_LinkFullSave))
|
||||||
sGfx->state++;
|
sGfx->state++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -481,7 +481,7 @@ static bool32 TryWriteTrainerHill_Internal(struct EReaderTrainerHillSet * hillSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
hillTag->checksum = CalcByteArraySum((u8 *)hillTag->floors, NUM_TRAINER_HILL_FLOORS * sizeof(struct TrHillFloor));
|
hillTag->checksum = CalcByteArraySum((u8 *)hillTag->floors, NUM_TRAINER_HILL_FLOORS * sizeof(struct TrHillFloor));
|
||||||
if (TryWriteSpecialSaveSection(SECTOR_ID_TRAINER_HILL, (u8 *)hillTag) != SAVE_STATUS_OK)
|
if (TryWriteSpecialSaveSector(SECTOR_ID_TRAINER_HILL, (u8 *)hillTag) != SAVE_STATUS_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -497,7 +497,7 @@ bool32 TryWriteTrainerHill(struct EReaderTrainerHillSet * hillSet)
|
|||||||
|
|
||||||
static bool32 TryReadTrainerHill_Internal(struct EReaderTrainerHillSet * dest, u8 * buffer)
|
static bool32 TryReadTrainerHill_Internal(struct EReaderTrainerHillSet * dest, u8 * buffer)
|
||||||
{
|
{
|
||||||
if (TryReadSpecialSaveSection(SECTOR_ID_TRAINER_HILL, buffer) != SAVE_STATUS_OK)
|
if (TryReadSpecialSaveSector(SECTOR_ID_TRAINER_HILL, buffer) != SAVE_STATUS_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
memcpy(dest, buffer, sizeof(struct EReaderTrainerHillSet));
|
memcpy(dest, buffer, sizeof(struct EReaderTrainerHillSet));
|
||||||
|
@ -487,12 +487,12 @@ static void Task_Hof_InitTeamSaveData(u8 taskId)
|
|||||||
|
|
||||||
if (!gHasHallOfFameRecords)
|
if (!gHasHallOfFameRecords)
|
||||||
{
|
{
|
||||||
memset(gDecompressionBuffer, 0, 0x2000);
|
memset(gDecompressionBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Save_LoadGameData(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK)
|
if (LoadGameSave(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK)
|
||||||
memset(gDecompressionBuffer, 0, 0x2000);
|
memset(gDecompressionBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++)
|
for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++)
|
||||||
@ -853,7 +853,7 @@ void CB2_DoHallOfFamePC(void)
|
|||||||
gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE;
|
gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sHofMonPtr = AllocZeroed(0x2000);
|
sHofMonPtr = AllocZeroed(SECTOR_SIZE * NUM_HOF_SECTORS);
|
||||||
SetMainCallback2(CB2_HallOfFame);
|
SetMainCallback2(CB2_HallOfFame);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -863,7 +863,7 @@ void CB2_DoHallOfFamePC(void)
|
|||||||
static void Task_HofPC_CopySaveData(u8 taskId)
|
static void Task_HofPC_CopySaveData(u8 taskId)
|
||||||
{
|
{
|
||||||
sub_81980F0(0, 0x1E, 0, 0xC, 0x226);
|
sub_81980F0(0, 0x1E, 0, 0xC, 0x226);
|
||||||
if (Save_LoadGameData(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK)
|
if (LoadGameSave(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK)
|
||||||
{
|
{
|
||||||
gTasks[taskId].func = Task_HofPC_PrintDataIsCorrupted;
|
gTasks[taskId].func = Task_HofPC_PrintDataIsCorrupted;
|
||||||
}
|
}
|
||||||
@ -872,7 +872,7 @@ static void Task_HofPC_CopySaveData(u8 taskId)
|
|||||||
u16 i;
|
u16 i;
|
||||||
struct HallofFameTeam* savedTeams;
|
struct HallofFameTeam* savedTeams;
|
||||||
|
|
||||||
CpuCopy16(gDecompressionBuffer, sHofMonPtr, 0x2000);
|
CpuCopy16(gDecompressionBuffer, sHofMonPtr, SECTOR_SIZE * NUM_HOF_SECTORS);
|
||||||
savedTeams = sHofMonPtr;
|
savedTeams = sHofMonPtr;
|
||||||
for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++)
|
for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++)
|
||||||
{
|
{
|
||||||
|
@ -1145,7 +1145,7 @@ void CB2_InitCopyrightScreenAfterBootup(void)
|
|||||||
SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset());
|
SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset());
|
||||||
ResetMenuAndMonGlobals();
|
ResetMenuAndMonGlobals();
|
||||||
Save_ResetSaveCounters();
|
Save_ResetSaveCounters();
|
||||||
Save_LoadGameData(SAVE_NORMAL);
|
LoadGameSave(SAVE_NORMAL);
|
||||||
if (gSaveFileStatus == SAVE_STATUS_EMPTY || gSaveFileStatus == SAVE_STATUS_CORRUPT)
|
if (gSaveFileStatus == SAVE_STATUS_EMPTY || gSaveFileStatus == SAVE_STATUS_CORRUPT)
|
||||||
Sav2_ClearSetDefault();
|
Sav2_ClearSetDefault();
|
||||||
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
|
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
|
||||||
|
@ -198,13 +198,13 @@ void LoadObjectEvents(void)
|
|||||||
gObjectEvents[i] = gSaveBlock1Ptr->objectEvents[i];
|
gObjectEvents[i] = gSaveBlock1Ptr->objectEvents[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveSerializedGame(void)
|
void CopyPartyAndObjectsToSave(void)
|
||||||
{
|
{
|
||||||
SavePlayerParty();
|
SavePlayerParty();
|
||||||
SaveObjectEvents();
|
SaveObjectEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadSerializedGame(void)
|
void CopyPartyAndObjectsFromSave(void)
|
||||||
{
|
{
|
||||||
LoadPlayerParty();
|
LoadPlayerParty();
|
||||||
LoadObjectEvents();
|
LoadObjectEvents();
|
||||||
|
@ -1282,12 +1282,12 @@ static bool32 SavePokeJump(void)
|
|||||||
case 2:
|
case 2:
|
||||||
if (AreLinkQueuesEmpty())
|
if (AreLinkQueuesEmpty())
|
||||||
{
|
{
|
||||||
CreateTask(Task_LinkSave, 6);
|
CreateTask(Task_LinkFullSave, 6);
|
||||||
sPokemonJump->mainState++;
|
sPokemonJump->mainState++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (!FuncIsActiveTask(Task_LinkSave))
|
if (!FuncIsActiveTask(Task_LinkFullSave))
|
||||||
{
|
{
|
||||||
ClearMessageWindow();
|
ClearMessageWindow();
|
||||||
sPokemonJump->mainState++;
|
sPokemonJump->mainState++;
|
||||||
|
@ -1002,11 +1002,11 @@ static void Task_DoRecordMixing(u8 taskId)
|
|||||||
case 2:
|
case 2:
|
||||||
// Mixing Ruby/Sapphire records.
|
// Mixing Ruby/Sapphire records.
|
||||||
SetContinueGameWarpStatusToDynamicWarp();
|
SetContinueGameWarpStatusToDynamicWarp();
|
||||||
FullSaveGame();
|
WriteSaveBlock2();
|
||||||
task->tState++;
|
task->tState++;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (CheckSaveFile())
|
if (WriteSaveBlock1Sector())
|
||||||
{
|
{
|
||||||
ClearContinueGameWarpStatus2();
|
ClearContinueGameWarpStatus2();
|
||||||
task->tState = 4;
|
task->tState = 4;
|
||||||
@ -1030,12 +1030,12 @@ static void Task_DoRecordMixing(u8 taskId)
|
|||||||
case 6:
|
case 6:
|
||||||
if (!Rfu_SetLinkRecovery(FALSE))
|
if (!Rfu_SetLinkRecovery(FALSE))
|
||||||
{
|
{
|
||||||
CreateTask(Task_LinkSave, 5);
|
CreateTask(Task_LinkFullSave, 5);
|
||||||
task->tState++;
|
task->tState++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: // wait for Task_LinkSave to finish.
|
case 7: // wait for Task_LinkFullSave to finish.
|
||||||
if (!FuncIsActiveTask(Task_LinkSave))
|
if (!FuncIsActiveTask(Task_LinkFullSave))
|
||||||
{
|
{
|
||||||
if (gWirelessCommType)
|
if (gWirelessCommType)
|
||||||
{
|
{
|
||||||
|
@ -306,14 +306,14 @@ static bool32 IsRecordedBattleSaveValid(struct RecordedBattleSave *save)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 RecordedBattleToSave(struct RecordedBattleSave *battleSave, struct RecordedBattleSave *saveSection)
|
static bool32 RecordedBattleToSave(struct RecordedBattleSave *battleSave, struct RecordedBattleSave *saveSector)
|
||||||
{
|
{
|
||||||
memset(saveSection, 0, SECTOR_SIZE);
|
memset(saveSector, 0, SECTOR_SIZE);
|
||||||
memcpy(saveSection, battleSave, sizeof(*battleSave));
|
memcpy(saveSector, battleSave, sizeof(*battleSave));
|
||||||
|
|
||||||
saveSection->checksum = CalcByteArraySum((void*)(saveSection), sizeof(*saveSection) - 4);
|
saveSector->checksum = CalcByteArraySum((void*)(saveSector), sizeof(*saveSector) - 4);
|
||||||
|
|
||||||
if (TryWriteSpecialSaveSection(SECTOR_ID_RECORDED_BATTLE, (void*)(saveSection)) != SAVE_STATUS_OK)
|
if (TryWriteSpecialSaveSector(SECTOR_ID_RECORDED_BATTLE, (void*)(saveSector)) != SAVE_STATUS_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else
|
else
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -477,9 +477,9 @@ bool32 MoveRecordedBattleToSaveData(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 TryCopyRecordedBattleSaveData(struct RecordedBattleSave *dst, struct SaveSection *saveBuffer)
|
static bool32 TryCopyRecordedBattleSaveData(struct RecordedBattleSave *dst, struct SaveSector *saveBuffer)
|
||||||
{
|
{
|
||||||
if (TryReadSpecialSaveSection(SECTOR_ID_RECORDED_BATTLE, (void*)(saveBuffer)) != SAVE_STATUS_OK)
|
if (TryReadSpecialSaveSector(SECTOR_ID_RECORDED_BATTLE, (void*)(saveBuffer)) != SAVE_STATUS_OK)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
memcpy(dst, saveBuffer, sizeof(struct RecordedBattleSave));
|
memcpy(dst, saveBuffer, sizeof(struct RecordedBattleSave));
|
||||||
@ -492,7 +492,7 @@ static bool32 TryCopyRecordedBattleSaveData(struct RecordedBattleSave *dst, stru
|
|||||||
|
|
||||||
static bool32 CopyRecordedBattleFromSave(struct RecordedBattleSave *dst)
|
static bool32 CopyRecordedBattleFromSave(struct RecordedBattleSave *dst)
|
||||||
{
|
{
|
||||||
struct SaveSection *savBuffer = AllocZeroed(sizeof(struct SaveSection));
|
struct SaveSector *savBuffer = AllocZeroed(SECTOR_SIZE);
|
||||||
bool32 ret = TryCopyRecordedBattleSaveData(dst, savBuffer);
|
bool32 ret = TryCopyRecordedBattleSaveData(dst, savBuffer);
|
||||||
Free(savBuffer);
|
Free(savBuffer);
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ void ReloadSave(void)
|
|||||||
SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset());
|
SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset());
|
||||||
ResetMenuAndMonGlobals();
|
ResetMenuAndMonGlobals();
|
||||||
Save_ResetSaveCounters();
|
Save_ResetSaveCounters();
|
||||||
Save_LoadGameData(SAVE_NORMAL);
|
LoadGameSave(SAVE_NORMAL);
|
||||||
if (gSaveFileStatus == SAVE_STATUS_EMPTY || gSaveFileStatus == SAVE_STATUS_CORRUPT)
|
if (gSaveFileStatus == SAVE_STATUS_EMPTY || gSaveFileStatus == SAVE_STATUS_CORRUPT)
|
||||||
Sav2_ClearSetDefault();
|
Sav2_ClearSetDefault();
|
||||||
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
|
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
|
||||||
|
544
src/save.c
544
src/save.c
File diff suppressed because it is too large
Load Diff
@ -363,9 +363,10 @@ static bool8 VerifySectorWipe(u16 sector)
|
|||||||
|
|
||||||
ReadFlash(sector, 0, (u8 *)ptr, SECTOR_SIZE);
|
ReadFlash(sector, 0, (u8 *)ptr, SECTOR_SIZE);
|
||||||
|
|
||||||
for (i = 0; i < 0x400; i++, ptr++)
|
// 1/4 because ptr is u32
|
||||||
|
for (i = 0; i < SECTOR_SIZE / 4; i++, ptr++)
|
||||||
if (*ptr)
|
if (*ptr)
|
||||||
return TRUE;
|
return TRUE; // Sector has nonzero data, failed
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -375,6 +376,7 @@ static bool8 WipeSector(u16 sector)
|
|||||||
u16 i, j;
|
u16 i, j;
|
||||||
bool8 failed = TRUE;
|
bool8 failed = TRUE;
|
||||||
|
|
||||||
|
// Attempt to wipe sector with an arbitrary attempt limit of 130
|
||||||
for (i = 0; failed && i < 130; i++)
|
for (i = 0; failed && i < 130; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < SECTOR_SIZE; j++)
|
for (j = 0; j < SECTOR_SIZE; j++)
|
||||||
|
@ -1269,11 +1269,11 @@ static void Task_SaveAfterLinkBattle(u8 taskId)
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
SetContinueGameWarpStatusToDynamicWarp();
|
SetContinueGameWarpStatusToDynamicWarp();
|
||||||
FullSaveGame();
|
WriteSaveBlock2();
|
||||||
*state = 2;
|
*state = 2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (CheckSaveFile())
|
if (WriteSaveBlock1Sector())
|
||||||
{
|
{
|
||||||
ClearContinueGameWarpStatus2();
|
ClearContinueGameWarpStatus2();
|
||||||
*state = 3;
|
*state = 3;
|
||||||
@ -1290,11 +1290,11 @@ static void Task_SaveAfterLinkBattle(u8 taskId)
|
|||||||
DestroyTask(taskId);
|
DestroyTask(taskId);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
CreateTask(Task_LinkSave, 5);
|
CreateTask(Task_LinkFullSave, 5);
|
||||||
*state = 6;
|
*state = 6;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if (!FuncIsActiveTask(Task_LinkSave))
|
if (!FuncIsActiveTask(Task_LinkFullSave))
|
||||||
{
|
{
|
||||||
*state = 3;
|
*state = 3;
|
||||||
}
|
}
|
||||||
@ -1374,23 +1374,23 @@ static void RemoveSaveInfoWindow(void)
|
|||||||
|
|
||||||
static void Task_WaitForBattleTowerLinkSave(u8 taskId)
|
static void Task_WaitForBattleTowerLinkSave(u8 taskId)
|
||||||
{
|
{
|
||||||
if (!FuncIsActiveTask(Task_LinkSave))
|
if (!FuncIsActiveTask(Task_LinkFullSave))
|
||||||
{
|
{
|
||||||
DestroyTask(taskId);
|
DestroyTask(taskId);
|
||||||
EnableBothScriptContexts();
|
EnableBothScriptContexts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define tPartialSave data[2]
|
#define tInBattleTower data[2]
|
||||||
|
|
||||||
void SaveForBattleTowerLink(void)
|
void SaveForBattleTowerLink(void)
|
||||||
{
|
{
|
||||||
u8 taskId = CreateTask(Task_LinkSave, 5);
|
u8 taskId = CreateTask(Task_LinkFullSave, 5);
|
||||||
gTasks[taskId].tPartialSave = TRUE;
|
gTasks[taskId].tInBattleTower = TRUE;
|
||||||
gTasks[CreateTask(Task_WaitForBattleTowerLinkSave, 6)].data[1] = taskId;
|
gTasks[CreateTask(Task_WaitForBattleTowerLinkSave, 6)].data[1] = taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef tPartialSave
|
#undef tInBattleTower
|
||||||
|
|
||||||
static void HideStartMenuWindow(void)
|
static void HideStartMenuWindow(void)
|
||||||
{
|
{
|
||||||
|
19
src/trade.c
19
src/trade.c
@ -4654,30 +4654,29 @@ static void CB2_SaveAndEndTrade(void)
|
|||||||
MysteryGift_TryIncrementStat(CARD_STAT_NUM_TRADES, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
|
MysteryGift_TryIncrementStat(CARD_STAT_NUM_TRADES, gLinkPlayers[GetMultiplayerId() ^ 1].trainerId);
|
||||||
|
|
||||||
SetContinueGameWarpStatusToDynamicWarp();
|
SetContinueGameWarpStatusToDynamicWarp();
|
||||||
sub_8153380();
|
LinkFullSave_Init();
|
||||||
gMain.state++;
|
gMain.state++;
|
||||||
sTradeData->timer = 0;
|
sTradeData->timer = 0;
|
||||||
break;
|
break;
|
||||||
case 51:
|
case 51:
|
||||||
if (++sTradeData->timer == 5)
|
if (++sTradeData->timer == 5)
|
||||||
{
|
|
||||||
gMain.state++;
|
gMain.state++;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 52:
|
case 52:
|
||||||
if (sub_81533AC())
|
if (LinkFullSave_WriteSector())
|
||||||
{
|
{
|
||||||
ClearContinueGameWarpStatus2();
|
ClearContinueGameWarpStatus2();
|
||||||
gMain.state = 4;
|
gMain.state = 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Save isn't finished, delay again
|
||||||
sTradeData->timer = 0;
|
sTradeData->timer = 0;
|
||||||
gMain.state = 51;
|
gMain.state = 51;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
sub_81533E0();
|
LinkFullSave_ReplaceLastSector();
|
||||||
gMain.state = 40;
|
gMain.state = 40;
|
||||||
sTradeData->timer = 0;
|
sTradeData->timer = 0;
|
||||||
break;
|
break;
|
||||||
@ -4709,7 +4708,7 @@ static void CB2_SaveAndEndTrade(void)
|
|||||||
case 42:
|
case 42:
|
||||||
if (_IsLinkTaskFinished())
|
if (_IsLinkTaskFinished())
|
||||||
{
|
{
|
||||||
sub_8153408();
|
LinkFullSave_SetLastSectorSecurity();
|
||||||
gMain.state = 5;
|
gMain.state = 5;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4965,7 +4964,7 @@ static void CB2_SaveAndEndWirelessTrade(void)
|
|||||||
StringExpandPlaceholders(gStringVar4, gText_SavingDontTurnOffPower);
|
StringExpandPlaceholders(gStringVar4, gText_SavingDontTurnOffPower);
|
||||||
DrawTextOnTradeWindow(0, gStringVar4, 0);
|
DrawTextOnTradeWindow(0, gStringVar4, 0);
|
||||||
IncrementGameStat(GAME_STAT_POKEMON_TRADES);
|
IncrementGameStat(GAME_STAT_POKEMON_TRADES);
|
||||||
sub_8153380();
|
LinkFullSave_Init();
|
||||||
sTradeData->timer = 0;
|
sTradeData->timer = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -4974,7 +4973,7 @@ static void CB2_SaveAndEndWirelessTrade(void)
|
|||||||
gMain.state = 4;
|
gMain.state = 4;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (sub_81533AC())
|
if (LinkFullSave_WriteSector())
|
||||||
{
|
{
|
||||||
gMain.state = 5;
|
gMain.state = 5;
|
||||||
}
|
}
|
||||||
@ -4985,7 +4984,7 @@ static void CB2_SaveAndEndWirelessTrade(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
sub_81533E0();
|
LinkFullSave_ReplaceLastSector();
|
||||||
gMain.state = 6;
|
gMain.state = 6;
|
||||||
sTradeData->timer = 0;
|
sTradeData->timer = 0;
|
||||||
break;
|
break;
|
||||||
@ -5013,7 +5012,7 @@ static void CB2_SaveAndEndWirelessTrade(void)
|
|||||||
case 8:
|
case 8:
|
||||||
if (_IsLinkTaskFinished())
|
if (_IsLinkTaskFinished())
|
||||||
{
|
{
|
||||||
sub_8153408();
|
LinkFullSave_SetLastSectorSecurity();
|
||||||
gMain.state = 9;
|
gMain.state = 9;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user