mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 19:47:35 +01:00
Merge pull request #1725 from GriffinRichards/security-signature
Sector security -> signature
This commit is contained in:
commit
574cf1ddb9
@ -9,8 +9,8 @@
|
||||
|
||||
#define NUM_SAVE_SLOTS 2
|
||||
|
||||
// If the sector's security field is not this value then the sector is either invalid or empty.
|
||||
#define SECTOR_SECURITY_NUM 0x8012025
|
||||
// If the sector's signature field is not this value then the sector is either invalid or empty.
|
||||
#define SECTOR_SIGNATURE 0x8012025
|
||||
|
||||
#define SPECIAL_SECTOR_SENTINEL 0xB39D
|
||||
|
||||
@ -72,12 +72,12 @@ struct SaveSector
|
||||
u8 unused[SECTOR_FOOTER_SIZE - 12]; // Unused portion of the footer
|
||||
u16 id;
|
||||
u16 checksum;
|
||||
u32 security;
|
||||
u32 signature;
|
||||
u32 counter;
|
||||
}; // size is SECTOR_SIZE (0x1000)
|
||||
|
||||
#define SECTOR_SECURITY_OFFSET offsetof(struct SaveSector, security)
|
||||
#define SECTOR_COUNTER_OFFSET offsetof(struct SaveSector, counter)
|
||||
#define SECTOR_SIGNATURE_OFFSET offsetof(struct SaveSector, signature)
|
||||
#define SECTOR_COUNTER_OFFSET offsetof(struct SaveSector, counter)
|
||||
|
||||
extern u16 gLastWrittenSector;
|
||||
extern u32 gLastSaveCounter;
|
||||
@ -99,7 +99,7 @@ u8 TrySavingData(u8 saveType);
|
||||
bool8 LinkFullSave_Init(void);
|
||||
bool8 LinkFullSave_WriteSector(void);
|
||||
bool8 LinkFullSave_ReplaceLastSector(void);
|
||||
bool8 LinkFullSave_SetLastSectorSecurity(void);
|
||||
bool8 LinkFullSave_SetLastSectorSignature(void);
|
||||
bool8 WriteSaveBlock2(void);
|
||||
bool8 WriteSaveBlock1Sector(void);
|
||||
u8 LoadGameSave(u8 saveType);
|
||||
|
@ -15,7 +15,8 @@
|
||||
#include "constants/items.h"
|
||||
#include "constants/trainer_hill.h"
|
||||
|
||||
STATIC_ASSERT(sizeof(struct TrainerHillChallenge) <= SECTOR_DATA_SIZE, TrainerHillChallengeFreeSpace);
|
||||
// Save data using TryWriteSpecialSaveSector is allowed to exceed SECTOR_DATA_SIZE (up to the counter field)
|
||||
STATIC_ASSERT(sizeof(struct TrainerHillChallenge) <= SECTOR_COUNTER_OFFSET, TrainerHillChallengeFreeSpace);
|
||||
|
||||
struct SendRecvMgr
|
||||
{
|
||||
|
@ -67,7 +67,8 @@ struct RecordedBattleSave
|
||||
u32 checksum;
|
||||
};
|
||||
|
||||
STATIC_ASSERT(sizeof(struct RecordedBattleSave) <= SECTOR_DATA_SIZE, RecordedBattleSaveFreeSpace);
|
||||
// Save data using TryWriteSpecialSaveSector is allowed to exceed SECTOR_DATA_SIZE (up to the counter field)
|
||||
STATIC_ASSERT(sizeof(struct RecordedBattleSave) <= SECTOR_COUNTER_OFFSET, RecordedBattleSaveFreeSpace);
|
||||
|
||||
EWRAM_DATA u32 gRecordedBattleRngSeed = 0;
|
||||
EWRAM_DATA u32 gBattlePalaceMoveSelectionRngValue = 0;
|
||||
|
88
src/save.c
88
src/save.c
@ -196,7 +196,7 @@ static u8 HandleWriteSector(u16 sectorId, const struct SaveSectorLocation *locat
|
||||
|
||||
// Set footer data
|
||||
gReadWriteSector->id = sectorId;
|
||||
gReadWriteSector->security = SECTOR_SECURITY_NUM;
|
||||
gReadWriteSector->signature = SECTOR_SIGNATURE;
|
||||
gReadWriteSector->counter = gSaveCounter;
|
||||
|
||||
// Copy current data to temp buffer for writing
|
||||
@ -217,7 +217,7 @@ static u8 HandleWriteSectorNBytes(u8 sectorId, u8 *data, u16 size)
|
||||
for (i = 0; i < SECTOR_SIZE; i++)
|
||||
((u8 *)sector)[i] = 0;
|
||||
|
||||
sector->security = SECTOR_SECURITY_NUM;
|
||||
sector->signature = SECTOR_SIGNATURE;
|
||||
|
||||
// Copy data to temp buffer for writing
|
||||
for (i = 0; i < size; i++)
|
||||
@ -306,7 +306,7 @@ static u8 HandleReplaceSectorAndVerify(u16 sectorId, const struct SaveSectorLoca
|
||||
return status;
|
||||
}
|
||||
|
||||
// Similar to HandleWriteSector, but fully erases the sector first, and skips writing the first security byte
|
||||
// Similar to HandleWriteSector, but fully erases the sector first, and skips writing the first signature byte
|
||||
static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
{
|
||||
u16 i;
|
||||
@ -330,7 +330,7 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
||||
|
||||
// Set footer data
|
||||
gReadWriteSector->id = sectorId;
|
||||
gReadWriteSector->security = SECTOR_SECURITY_NUM;
|
||||
gReadWriteSector->signature = SECTOR_SIGNATURE;
|
||||
gReadWriteSector->counter = gSaveCounter;
|
||||
|
||||
// Copy current data to temp buffer for writing
|
||||
@ -344,8 +344,8 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
||||
|
||||
status = SAVE_STATUS_OK;
|
||||
|
||||
// Write new save data up to security field
|
||||
for (i = 0; i < SECTOR_SECURITY_OFFSET; i++)
|
||||
// Write new save data up to signature field
|
||||
for (i = 0; i < SECTOR_SIGNATURE_OFFSET; i++)
|
||||
{
|
||||
if (ProgramFlashByte(sector, i, ((u8 *)gReadWriteSector)[i]))
|
||||
{
|
||||
@ -362,14 +362,14 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
||||
}
|
||||
else
|
||||
{
|
||||
// Writing save data succeeded, write security and counter
|
||||
// Writing save data succeeded, write signature and counter
|
||||
status = SAVE_STATUS_OK;
|
||||
|
||||
// Write security (skipping the first byte) and counter fields.
|
||||
// The byte of security that is skipped is instead written by WriteSectorSecurityByte or WriteSectorSecurityByte_NoOffset
|
||||
for (i = 0; i < SECTOR_SIZE - (SECTOR_SECURITY_OFFSET + 1); i++)
|
||||
// Write signature (skipping the first byte) and counter fields.
|
||||
// The byte of signature that is skipped is instead written by WriteSectorSignatureByte or WriteSectorSignatureByte_NoOffset
|
||||
for (i = 0; i < SECTOR_SIZE - (SECTOR_SIGNATURE_OFFSET + 1); i++)
|
||||
{
|
||||
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET + 1 + i, ((u8 *)gReadWriteSector)[SECTOR_SECURITY_OFFSET + 1 + i]))
|
||||
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET + 1 + i, ((u8 *)gReadWriteSector)[SECTOR_SIGNATURE_OFFSET + 1 + i]))
|
||||
{
|
||||
status = SAVE_STATUS_ERROR;
|
||||
break;
|
||||
@ -378,7 +378,7 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
||||
|
||||
if (status == SAVE_STATUS_ERROR)
|
||||
{
|
||||
// Writing security/counter failed
|
||||
// Writing signature/counter failed
|
||||
SetDamagedSectorBits(ENABLE, sector);
|
||||
return SAVE_STATUS_ERROR;
|
||||
}
|
||||
@ -391,16 +391,16 @@ static u8 HandleReplaceSector(u16 sectorId, const struct SaveSectorLocation *loc
|
||||
}
|
||||
}
|
||||
|
||||
static u8 WriteSectorSecurityByte_NoOffset(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
static u8 WriteSectorSignatureByte_NoOffset(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
{
|
||||
// Adjust sector id for current save slot
|
||||
// This first line lacking -1 is the only difference from WriteSectorSecurityByte
|
||||
// This first line lacking -1 is the only difference from WriteSectorSignatureByte
|
||||
u16 sector = sectorId + gLastWrittenSector;
|
||||
sector %= NUM_SECTORS_PER_SLOT;
|
||||
sector += NUM_SECTORS_PER_SLOT * (gSaveCounter % NUM_SAVE_SLOTS);
|
||||
|
||||
// Write just the first byte of the security field, which was skipped by HandleReplaceSector
|
||||
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET, SECTOR_SECURITY_NUM & 0xFF))
|
||||
// Write just the first byte of the signature field, which was skipped by HandleReplaceSector
|
||||
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET, SECTOR_SIGNATURE & 0xFF))
|
||||
{
|
||||
// Sector is damaged, so enable the bit in gDamagedSaveSectors and restore the last written sector and save counter.
|
||||
SetDamagedSectorBits(ENABLE, sector);
|
||||
@ -416,15 +416,15 @@ static u8 WriteSectorSecurityByte_NoOffset(u16 sectorId, const struct SaveSector
|
||||
}
|
||||
}
|
||||
|
||||
static u8 CopySectorSecurityByte(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
static u8 CopySectorSignatureByte(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
{
|
||||
// Adjust sector id for current save slot
|
||||
u16 sector = sectorId + gLastWrittenSector - 1;
|
||||
sector %= NUM_SECTORS_PER_SLOT;
|
||||
sector += NUM_SECTORS_PER_SLOT * (gSaveCounter % NUM_SAVE_SLOTS);
|
||||
|
||||
// Copy just the first byte of the security field from the read/write buffer
|
||||
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET, ((u8 *)gReadWriteSector)[SECTOR_SECURITY_OFFSET]))
|
||||
// Copy just the first byte of the signature field from the read/write buffer
|
||||
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET, ((u8 *)gReadWriteSector)[SECTOR_SIGNATURE_OFFSET]))
|
||||
{
|
||||
// Sector is damaged, so enable the bit in gDamagedSaveSectors and restore the last written sector and save counter.
|
||||
SetDamagedSectorBits(ENABLE, sector);
|
||||
@ -440,15 +440,15 @@ static u8 CopySectorSecurityByte(u16 sectorId, const struct SaveSectorLocation *
|
||||
}
|
||||
}
|
||||
|
||||
static u8 WriteSectorSecurityByte(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
static u8 WriteSectorSignatureByte(u16 sectorId, const struct SaveSectorLocation *locations)
|
||||
{
|
||||
// Adjust sector id for current save slot
|
||||
u16 sector = sectorId + gLastWrittenSector - 1;
|
||||
sector %= NUM_SECTORS_PER_SLOT;
|
||||
sector += NUM_SECTORS_PER_SLOT * (gSaveCounter % NUM_SAVE_SLOTS);
|
||||
|
||||
// Write just the first byte of the security field, which was skipped by HandleReplaceSector
|
||||
if (ProgramFlashByte(sector, SECTOR_SECURITY_OFFSET, SECTOR_SECURITY_NUM & 0xFF))
|
||||
// Write just the first byte of the signature field, which was skipped by HandleReplaceSector
|
||||
if (ProgramFlashByte(sector, SECTOR_SIGNATURE_OFFSET, SECTOR_SIGNATURE & 0xFF))
|
||||
{
|
||||
// Sector is damaged, so enable the bit in gDamagedSaveSectors and restore the last written sector and save counter.
|
||||
SetDamagedSectorBits(ENABLE, sector);
|
||||
@ -500,8 +500,8 @@ static u8 CopySaveSlotData(u16 sectorId, struct SaveSectorLocation *locations)
|
||||
|
||||
checksum = CalculateChecksum(gReadWriteSector->data, locations[id].size);
|
||||
|
||||
// Only copy data for sectors whose security and checksum fields are correct
|
||||
if (gReadWriteSector->security == SECTOR_SECURITY_NUM && gReadWriteSector->checksum == checksum)
|
||||
// Only copy data for sectors whose signature and checksum fields are correct
|
||||
if (gReadWriteSector->signature == SECTOR_SIGNATURE && gReadWriteSector->checksum == checksum)
|
||||
{
|
||||
u16 j;
|
||||
for (j = 0; j < locations[id].size; j++)
|
||||
@ -519,7 +519,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
|
||||
u32 saveSlot1Counter = 0;
|
||||
u32 saveSlot2Counter = 0;
|
||||
u32 validSectorFlags = 0;
|
||||
bool8 securityPassed = FALSE;
|
||||
bool8 signatureValid = FALSE;
|
||||
u8 saveSlot1Status;
|
||||
u8 saveSlot2Status;
|
||||
|
||||
@ -527,9 +527,9 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
|
||||
for (i = 0; i < NUM_SECTORS_PER_SLOT; i++)
|
||||
{
|
||||
ReadFlashSector(i, gReadWriteSector);
|
||||
if (gReadWriteSector->security == SECTOR_SECURITY_NUM)
|
||||
if (gReadWriteSector->signature == SECTOR_SIGNATURE)
|
||||
{
|
||||
securityPassed = TRUE;
|
||||
signatureValid = TRUE;
|
||||
checksum = CalculateChecksum(gReadWriteSector->data, locations[gReadWriteSector->id].size);
|
||||
if (gReadWriteSector->checksum == checksum)
|
||||
{
|
||||
@ -539,7 +539,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
|
||||
}
|
||||
}
|
||||
|
||||
if (securityPassed)
|
||||
if (signatureValid)
|
||||
{
|
||||
if (validSectorFlags == (1 << NUM_SECTORS_PER_SLOT) - 1)
|
||||
saveSlot1Status = SAVE_STATUS_OK;
|
||||
@ -548,20 +548,20 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
|
||||
}
|
||||
else
|
||||
{
|
||||
// No sectors in slot 1 have the security number, treat it as empty
|
||||
// No sectors in slot 1 have the correct signature, treat it as empty
|
||||
saveSlot1Status = SAVE_STATUS_EMPTY;
|
||||
}
|
||||
|
||||
validSectorFlags = 0;
|
||||
securityPassed = FALSE;
|
||||
signatureValid = FALSE;
|
||||
|
||||
// Check save slot 2
|
||||
for (i = 0; i < NUM_SECTORS_PER_SLOT; i++)
|
||||
{
|
||||
ReadFlashSector(i + NUM_SECTORS_PER_SLOT, gReadWriteSector);
|
||||
if (gReadWriteSector->security == SECTOR_SECURITY_NUM)
|
||||
if (gReadWriteSector->signature == SECTOR_SIGNATURE)
|
||||
{
|
||||
securityPassed = TRUE;
|
||||
signatureValid = TRUE;
|
||||
checksum = CalculateChecksum(gReadWriteSector->data, locations[gReadWriteSector->id].size);
|
||||
if (gReadWriteSector->checksum == checksum)
|
||||
{
|
||||
@ -571,7 +571,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
|
||||
}
|
||||
}
|
||||
|
||||
if (securityPassed)
|
||||
if (signatureValid)
|
||||
{
|
||||
if (validSectorFlags == (1 << NUM_SECTORS_PER_SLOT) - 1)
|
||||
saveSlot2Status = SAVE_STATUS_OK;
|
||||
@ -580,7 +580,7 @@ static u8 GetSaveValidStatus(const struct SaveSectorLocation *locations)
|
||||
}
|
||||
else
|
||||
{
|
||||
// No sectors in slot 2 have the security number, treat it as empty.
|
||||
// No sectors in slot 2 have the correct signature, treat it as empty.
|
||||
saveSlot2Status = SAVE_STATUS_EMPTY;
|
||||
}
|
||||
|
||||
@ -642,12 +642,12 @@ static u8 TryLoadSaveSector(u8 sectorId, u8 *data, u16 size)
|
||||
u16 i;
|
||||
struct SaveSector *sector = &gSaveDataBuffer;
|
||||
ReadFlashSector(sectorId, sector);
|
||||
if (sector->security == SECTOR_SECURITY_NUM)
|
||||
if (sector->signature == SECTOR_SIGNATURE)
|
||||
{
|
||||
u16 checksum = CalculateChecksum(sector->data, size);
|
||||
if (sector->id == checksum)
|
||||
{
|
||||
// Security and checksum are correct, copy data
|
||||
// Signature and checksum are correct, copy data
|
||||
for (i = 0; i < size; i++)
|
||||
data[i] = sector->data[i];
|
||||
return SAVE_STATUS_OK;
|
||||
@ -660,7 +660,7 @@ static u8 TryLoadSaveSector(u8 sectorId, u8 *data, u16 size)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Incorrect security value
|
||||
// Incorrect signature value
|
||||
return SAVE_STATUS_EMPTY;
|
||||
}
|
||||
}
|
||||
@ -747,7 +747,7 @@ u8 HandleSavingData(u8 saveType)
|
||||
for(i = SECTOR_ID_SAVEBLOCK2; i <= SECTOR_ID_SAVEBLOCK1_END; i++)
|
||||
HandleReplaceSector(i, gRamSaveSectorLocations);
|
||||
for(i = SECTOR_ID_SAVEBLOCK2; i <= SECTOR_ID_SAVEBLOCK1_END; i++)
|
||||
WriteSectorSecurityByte_NoOffset(i, gRamSaveSectorLocations);
|
||||
WriteSectorSignatureByte_NoOffset(i, gRamSaveSectorLocations);
|
||||
break;
|
||||
case SAVE_OVERWRITE_DIFFERENT_FILE:
|
||||
// Erase Hall of Fame
|
||||
@ -818,9 +818,9 @@ bool8 LinkFullSave_ReplaceLastSector(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 LinkFullSave_SetLastSectorSecurity(void)
|
||||
bool8 LinkFullSave_SetLastSectorSignature(void)
|
||||
{
|
||||
CopySectorSecurityByte(NUM_SECTORS_PER_SLOT, gRamSaveSectorLocations);
|
||||
CopySectorSignatureByte(NUM_SECTORS_PER_SLOT, gRamSaveSectorLocations);
|
||||
if (gDamagedSaveSectors)
|
||||
DoSaveFailedScreen(SAVE_NORMAL);
|
||||
return FALSE;
|
||||
@ -852,14 +852,14 @@ bool8 WriteSaveBlock1Sector(void)
|
||||
{
|
||||
// Write a single sector of SaveBlock1
|
||||
HandleReplaceSectorAndVerify(gIncrementalSectorId + 1, gRamSaveSectorLocations);
|
||||
WriteSectorSecurityByte(sectorId, gRamSaveSectorLocations);
|
||||
WriteSectorSignatureByte(sectorId, gRamSaveSectorLocations);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Beyond SaveBlock1, don't write the sector.
|
||||
// Does write 1 byte of the next sector's security field, but as these
|
||||
// Does write 1 byte of the next sector's signature field, but as these
|
||||
// are the same for all valid sectors it doesn't matter.
|
||||
WriteSectorSecurityByte(sectorId, gRamSaveSectorLocations);
|
||||
WriteSectorSignatureByte(sectorId, gRamSaveSectorLocations);
|
||||
finished = TRUE;
|
||||
}
|
||||
|
||||
@ -1030,7 +1030,7 @@ void Task_LinkFullSave(u8 taskId)
|
||||
case 8:
|
||||
if (IsLinkTaskFinished())
|
||||
{
|
||||
LinkFullSave_SetLastSectorSecurity();
|
||||
LinkFullSave_SetLastSectorSignature();
|
||||
tState = 9;
|
||||
}
|
||||
break;
|
||||
|
@ -4708,7 +4708,7 @@ static void CB2_SaveAndEndTrade(void)
|
||||
case 42:
|
||||
if (_IsLinkTaskFinished())
|
||||
{
|
||||
LinkFullSave_SetLastSectorSecurity();
|
||||
LinkFullSave_SetLastSectorSignature();
|
||||
gMain.state = 5;
|
||||
}
|
||||
break;
|
||||
@ -5012,7 +5012,7 @@ static void CB2_SaveAndEndWirelessTrade(void)
|
||||
case 8:
|
||||
if (_IsLinkTaskFinished())
|
||||
{
|
||||
LinkFullSave_SetLastSectorSecurity();
|
||||
LinkFullSave_SetLastSectorSignature();
|
||||
gMain.state = 9;
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user