@ -17,6 +17,30 @@
# define SLOT_OFFSET(index) (SRAM_HEADER_SIZE + 0x10 + (index * SLOT_SIZE))
# if !PLATFORM_IQUE
# define SRAM_READ(addr, dramAddr, size) SsSram_ReadWrite(addr, dramAddr, size, OS_READ)
# define SRAM_WRITE(addr, dramAddr, size) SsSram_ReadWrite(addr, dramAddr, size, OS_WRITE)
# else
void Sram_ReadWriteIQue ( s32 addr , void * dramAddr , size_t size , s32 direction ) {
void * sramAddr ;
addr - = OS_K1_TO_PHYSICAL ( 0xA8000000 ) ;
sramAddr = ( void * ) ( __osBbSramAddress + addr ) ;
if ( direction = = OS_READ ) {
bcopy ( sramAddr , dramAddr , size ) ;
} else if ( direction = = OS_WRITE ) {
bcopy ( dramAddr , sramAddr , size ) ;
}
}
# define SRAM_READ(addr, dramAddr, size) Sram_ReadWriteIQue(addr, dramAddr, size, OS_READ)
# define SRAM_WRITE(addr, dramAddr, size) Sram_ReadWriteIQue(addr, dramAddr, size, OS_WRITE)
# endif
u16 gSramSlotOffsets [ ] = {
SLOT_OFFSET ( 0 ) ,
SLOT_OFFSET ( 1 ) ,
@ -27,7 +51,23 @@ u16 gSramSlotOffsets[] = {
SLOT_OFFSET ( 5 ) ,
} ;
static char sZeldaMagic [ ] = { ' \0 ' , ' \0 ' , ' \0 ' , ' \x98 ' , ' \x09 ' , ' \x10 ' , ' \x21 ' , ' Z ' , ' E ' , ' L ' , ' D ' , ' A ' } ;
static u8 sSramDefaultHeader [ ] = {
// TODO: use enums for these
0 , // SRAM_HEADER_SOUND
0 , // SRAM_HEADER_ZTARGET
0 , // SRAM_HEADER_LANGUAGE
// SRAM_HEADER_MAGIC
0x98 ,
0x09 ,
0x10 ,
0x21 ,
' Z ' ,
' E ' ,
' L ' ,
' D ' ,
' A ' ,
} ;
static SavePlayerData sNewSavePlayerData = {
{ ' \0 ' , ' \0 ' , ' \0 ' , ' \0 ' , ' \0 ' , ' \0 ' } , // newf
@ -138,15 +178,13 @@ static Inventory sNewSaveInventory = {
0 , // gsTokens
} ;
static u16 sNewSaveChecksum = 0 ;
static Checksum sNewSaveChecksum = { 0 } ;
/**
* Initialize new save .
* This save has an empty inventory with 3 hearts and single magic .
*/
void Sram_InitNewSave ( void ) {
SaveContext * temp = & gSaveContext ;
bzero ( & gSaveContext . save . info , sizeof ( SaveInfo ) ) ;
gSaveContext . save . totalDays = 0 ;
gSaveContext . save . bgsDayCount = 0 ;
@ -154,8 +192,8 @@ void Sram_InitNewSave(void) {
gSaveContext . save . info . playerData = sNewSavePlayerData ;
gSaveContext . save . info . equips = sNewSaveEquips ;
gSaveContext . save . info . inventory = sNewSaveInventory ;
gSaveContext . save . info . checksum = sNewSaveChecksum ;
temp - > save . info . checksum = sNewSaveChecksum ;
gSaveContext . save . info . horseData . sceneId = SCENE_HYRULE_FIELD ;
gSaveContext . save . info . horseData . pos . x = - 1840 ;
gSaveContext . save . info . horseData . pos . y = 72 ;
@ -297,7 +335,7 @@ static Inventory sDebugSaveInventory = {
0 , // gsTokens
} ;
static u16 sDebugSaveChecksum = 0 ;
static Checksum sDebugSaveChecksum = { 0 } ;
/**
* Initialize debug save . This is also used on the Title Screen
@ -309,8 +347,6 @@ static u16 sDebugSaveChecksum = 0;
* and set water level in Water Temple to lowest level .
*/
void Sram_InitDebugSave ( void ) {
SaveContext * temp = & gSaveContext ;
bzero ( & gSaveContext . save . info , sizeof ( SaveInfo ) ) ;
gSaveContext . save . totalDays = 0 ;
gSaveContext . save . bgsDayCount = 0 ;
@ -318,8 +354,8 @@ void Sram_InitDebugSave(void) {
gSaveContext . save . info . playerData = sDebugSavePlayerData ;
gSaveContext . save . info . equips = sDebugSaveEquips ;
gSaveContext . save . info . inventory = sDebugSaveInventory ;
gSaveContext . save . info . checksum = sDebugSaveChecksum ;
temp - > save . info . checksum = sDebugSaveChecksum ;
gSaveContext . save . info . horseData . sceneId = SCENE_HYRULE_FIELD ;
gSaveContext . save . info . horseData . pos . x = - 1840 ;
gSaveContext . save . info . horseData . pos . y = 72 ;
@ -456,8 +492,11 @@ void Sram_OpenSave(SramContext* sramCtx) {
default :
if ( gSaveContext . save . info . playerData . savedSceneId ! = SCENE_LINKS_HOUSE ) {
gSaveContext . save . entranceIndex =
( LINK_AGE_IN_YEARS = = YEARS_CHILD ) ? ENTR_LINKS_HOUSE_0 : ENTR_TEMPLE_OF_TIME_7 ;
if ( LINK_AGE_IN_YEARS = = YEARS_CHILD ) {
gSaveContext . save . entranceIndex = ENTR_LINKS_HOUSE_0 ;
} else {
gSaveContext . save . entranceIndex = ENTR_TEMPLE_OF_TIME_7 ;
}
} else {
gSaveContext . save . entranceIndex = ENTR_LINKS_HOUSE_0 ;
}
@ -505,7 +544,8 @@ void Sram_OpenSave(SramContext* sramCtx) {
// if zelda cutscene has been watched but lullaby was not obtained, restore cutscene and take away letter
if ( GET_EVENTCHKINF ( EVENTCHKINF_40 ) & & ! CHECK_QUEST_ITEM ( QUEST_SONG_LULLABY ) ) {
i = gSaveContext . save . info . eventChkInf [ EVENTCHKINF_INDEX_40 ] & ~ EVENTCHKINF_MASK ( EVENTCHKINF_40 ) ;
i = gSaveContext . save . info . eventChkInf [ EVENTCHKINF_INDEX_40 ] ;
i & = ~ EVENTCHKINF_MASK ( EVENTCHKINF_40 ) ;
gSaveContext . save . info . eventChkInf [ EVENTCHKINF_INDEX_40 ] = i ;
INV_CONTENT ( ITEM_ZELDAS_LETTER ) = ITEM_CHICKEN ;
@ -551,7 +591,7 @@ void Sram_WriteSave(SramContext* sramCtx) {
u16 j ;
u16 * ptr ;
gSaveContext . save . info . checksum = 0 ;
gSaveContext . save . info . checksum . value = 0 ;
ptr = ( u16 * ) & gSaveContext ;
checksum = j = 0 ;
@ -563,7 +603,7 @@ void Sram_WriteSave(SramContext* sramCtx) {
checksum + = * ptr + + ;
}
gSaveContext . save . info . checksum = checksum ;
gSaveContext . save . info . checksum . value = checksum ;
ptr = ( u16 * ) & gSaveContext ;
checksum = 0 ;
@ -576,7 +616,7 @@ void Sram_WriteSave(SramContext* sramCtx) {
}
offset = gSramSlotOffsets [ gSaveContext . fileNum ] ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE );
ptr = ( u16 * ) & gSaveContext ;
checksum = 0 ;
@ -589,7 +629,7 @@ void Sram_WriteSave(SramContext* sramCtx) {
}
offset = gSramSlotOffsets [ gSaveContext . fileNum + 3 ] ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE );
}
/**
@ -610,7 +650,7 @@ void Sram_VerifyAndLoadAllSaves(FileSelectState* fileSelect, SramContext* sramCt
PRINTF ( " S R A M START─LOAD\n " ) ;
bzero ( sramCtx - > readBuff , SRAM_SIZE ) ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE , OS_READ );
S RAM_READ ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE );
dayTime = ( ( void ) 0 , gSaveContext . save . dayTime ) ;
@ -620,8 +660,8 @@ void Sram_VerifyAndLoadAllSaves(FileSelectState* fileSelect, SramContext* sramCt
sizeof ( Save ) ) ;
MemCpy ( & gSaveContext , sramCtx - > readBuff + offset , sizeof ( Save ) ) ;
oldChecksum = gSaveContext . save . info . checksum ;
gSaveContext . save . info . checksum = 0 ;
oldChecksum = gSaveContext . save . info . checksum .value ;
gSaveContext . save . info . checksum . value = 0 ;
ptr = ( u16 * ) & gSaveContext ;
PRINTF ( " \n = = = = = = = = = = = = = S ( %d) = = = = = = = = = = = = = \n " , slotNum ) ;
@ -645,8 +685,8 @@ void Sram_VerifyAndLoadAllSaves(FileSelectState* fileSelect, SramContext* sramCt
offset = gSramSlotOffsets [ slotNum + 3 ] ;
MemCpy ( & gSaveContext , sramCtx - > readBuff + offset , sizeof ( Save ) ) ;
oldChecksum = gSaveContext . save . info . checksum ;
gSaveContext . save . info . checksum = 0 ;
oldChecksum = gSaveContext . save . info . checksum .value ;
gSaveContext . save . info . checksum . value = 0 ;
ptr = ( u16 * ) & gSaveContext ;
PRINTF ( " ================= BACK─UP ======================== \n " ) ;
@ -710,32 +750,33 @@ void Sram_VerifyAndLoadAllSaves(FileSelectState* fileSelect, SramContext* sramCt
newChecksum + = * ptr + + ;
}
gSaveContext . save . info . checksum = newChecksum ;
PRINTF ( " \n Check_Sum=%x(%x) \n " , gSaveContext . save . info . checksum , newChecksum ) ;
gSaveContext . save . info . checksum . value = newChecksum ;
PRINTF ( " \n Check_Sum=%x(%x) \n " , gSaveContext . save . info . checksum .value , newChecksum ) ;
i = gSramSlotOffsets [ slotNum + 3 ] ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + i , & gSaveContext , SLOT_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + i , & gSaveContext , SLOT_SIZE );
PRINTF ( " ????#%x,%x,%x,%x,%x,%x \n " , gSaveContext . save . info . playerData . newf [ 0 ] ,
//! @bug The ??= below is interpreted as a trigraph for # by IDO
PRINTF ( " ??????=%x,%x,%x,%x,%x,%x \n " , gSaveContext . save . info . playerData . newf [ 0 ] ,
gSaveContext . save . info . playerData . newf [ 1 ] , gSaveContext . save . info . playerData . newf [ 2 ] ,
gSaveContext . save . info . playerData . newf [ 3 ] , gSaveContext . save . info . playerData . newf [ 4 ] ,
gSaveContext . save . info . playerData . newf [ 5 ] ) ;
PRINTF ( T ( " \n ぽいんと=%x(%d+3) check_sum=%x(%x) \n " , " \n points=%x(%d+3) check_sum=%x(%x) \n " ) , i ,
slotNum , gSaveContext . save . info . checksum , newChecksum ) ;
slotNum , gSaveContext . save . info . checksum .value , newChecksum ) ;
}
i = gSramSlotOffsets [ slotNum ] ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + i , & gSaveContext , SLOT_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + i , & gSaveContext , SLOT_SIZE );
PRINTF ( T ( " ぽいんと=%x(%d) check_sum=%x(%x) \n " , " point=%x(%d) check_sum=%x(%x) \n " ) , i , slotNum ,
gSaveContext . save . info . checksum , newChecksum ) ;
gSaveContext . save . info . checksum .value , newChecksum ) ;
} else {
PRINTF ( T ( " \n SAVEデータ O K ! ! ! ! \n " , " \n SAVE data OK!!!! \n " ) ) ;
}
}
bzero ( sramCtx - > readBuff , SRAM_SIZE ) ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE , OS_READ );
S RAM_READ ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE );
gSaveContext . save . dayTime = dayTime ;
PRINTF ( " SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, 64DD=%x, HEART=%x \n " , DEATHS , NAME , HEALTH_CAP , QUEST , N64DD ,
@ -809,7 +850,14 @@ void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx) {
# endif
for ( offset = 0 ; offset < 8 ; offset + + ) {
# if !PLATFORM_IQUE
gSaveContext . save . info . playerData . playerName [ offset ] = fileSelect - > fileNames [ fileSelect - > buttonIndex ] [ offset ] ;
# else
// Workaround for EGCS bug
u8 * fileName = fileSelect - > fileNames [ fileSelect - > buttonIndex ] ;
gSaveContext . save . info . playerData . playerName [ offset ] = fileName [ offset ] ;
# endif
}
gSaveContext . save . info . playerData . newf [ 0 ] = ' Z ' ;
@ -838,8 +886,8 @@ void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx) {
}
}
gSaveContext . save . info . checksum = checksum ;
PRINTF ( T ( " \n チェックサム=%x \n " , " \n Checksum = %x \n " ) , gSaveContext . save . info . checksum );
gSaveContext . save . info . checksum . value = checksum ;
PRINTF ( T ( " \n チェックサム=%x \n " , " \n Checksum = %x \n " ) , gSaveContext . save . info . checksum .value );
offset = gSramSlotOffsets [ gSaveContext . fileNum ] ;
PRINTF ( " I=%x no=%d \n " , offset , gSaveContext . fileNum ) ;
@ -849,7 +897,7 @@ void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx) {
PRINTF ( " I=%x no=%d \n " , offset , gSaveContext . fileNum + 3 ) ;
MemCpy ( sramCtx - > readBuff + offset , & gSaveContext , sizeof ( Save ) ) ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE );
PRINTF ( T ( " SAVE終了 \n " , " SAVE end \n " ) ) ;
PRINTF ( " z_common_data.file_no = %d \n " , gSaveContext . fileNum ) ;
@ -879,26 +927,26 @@ void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx) {
}
void Sram_EraseSave ( FileSelectState * fileSelect , SramContext * sramCtx ) {
s32 offset ;
u16 offset ;
Sram_InitNewSave ( ) ;
offset = gSramSlotOffsets [ fileSelect - > selectedFileIndex ] ;
MemCpy ( sramCtx - > readBuff + offset , & gSaveContext , sizeof ( Save ) ) ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE );
MemCpy ( & fileSelect - > n64ddFlags [ fileSelect - > selectedFileIndex ] , sramCtx - > readBuff + offset + N64DD ,
sizeof ( fileSelect - > n64ddFlags [ 0 ] ) ) ;
offset = gSramSlotOffsets [ fileSelect - > selectedFileIndex + 3 ] ;
MemCpy ( sramCtx - > readBuff + offset , & gSaveContext , sizeof ( Save ) ) ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) + offset , & gSaveContext , SLOT_SIZE );
PRINTF ( T ( " CLEAR終了 \n " , " CLEAR END \n " ) ) ;
}
void Sram_CopySave ( FileSelectState * fileSelect , SramContext * sramCtx ) {
s32 offset ;
u16 offset ;
PRINTF ( " R E A D =%d(%x) C O P Y =%d(%x)\n " , fileSelect - > selectedFileIndex ,
gSramSlotOffsets [ fileSelect - > selectedFileIndex ] , fileSelect - > copyDestFileIndex ,
@ -913,7 +961,7 @@ void Sram_CopySave(FileSelectState* fileSelect, SramContext* sramCtx) {
offset = gSramSlotOffsets [ fileSelect - > copyDestFileIndex + 3 ] ;
MemCpy ( sramCtx - > readBuff + offset , & gSaveContext , sizeof ( Save ) ) ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE );
offset = gSramSlotOffsets [ fileSelect - > copyDestFileIndex ] ;
@ -943,23 +991,23 @@ void Sram_CopySave(FileSelectState* fileSelect, SramContext* sramCtx) {
* Write the first 16 bytes of the read buffer to the SRAM header
*/
void Sram_WriteSramHeader ( SramContext * sramCtx ) {
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_HEADER_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_HEADER_SIZE );
}
void Sram_InitSram ( GameState * gameState , SramContext * sramCtx ) {
u16 i ;
PRINTF ( " sram_initialize( Game *game, Sram *sram ) \n " ) ;
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE , OS_READ );
S RAM_READ ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE );
for ( i = 0 ; i < ARRAY_COUNTU ( s ZeldaMagic) - 3 ; i + + ) {
if ( s ZeldaMagic [ i + SRAM_HEADER_MAGIC ] ! = sramCtx - > readBuff [ i + SRAM_HEADER_MAGIC ] ) {
for ( i = 0 ; i < ARRAY_COUNTU ( s SramDefaultHeader) - SRAM_HEADER_MAGIC ; i + + ) {
if ( s SramDefaultHeader [ i + SRAM_HEADER_MAGIC ] ! = sramCtx - > readBuff [ i + SRAM_HEADER_MAGIC ] ) {
PRINTF ( T ( " SRAM破壊!!!!!! \n " , " SRAM destruction!!!!!! \n " ) ) ;
# if PLATFORM_GC && OOT_PAL
gSaveContext . language = sramCtx - > readBuff [ SRAM_HEADER_LANGUAGE ] ;
# endif
MemCpy ( sramCtx - > readBuff , s ZeldaMagic, sizeof ( sZeldaMagic ) ) ;
MemCpy ( sramCtx - > readBuff , s SramDefaultHeader, sizeof ( sSramDefaultHeader ) ) ;
# if PLATFORM_GC && OOT_PAL
sramCtx - > readBuff [ SRAM_HEADER_LANGUAGE ] = gSaveContext . language ;
@ -986,7 +1034,7 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
for ( i = 0 ; i < CHECKSUM_SIZE ; i + + ) {
sramCtx - > readBuff [ i ] = i ;
}
S sSram_ReadWrite ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE , OS_WRITE );
S RAM_WRITE ( OS_K1_TO_PHYSICAL ( 0xA8000000 ) , sramCtx - > readBuff , SRAM_SIZE );
PRINTF ( T ( " SRAM破壊!!!!!! \n " , " SRAM destruction!!!!!! \n " ) ) ;
}
# endif