#ifndef COMPILE_H
#include "COMPILE.H"
#endif
#ifdef MEDIA678_F31E_F31J_X31J_P31J_SU1E_AU1E_AU2E_AU3E
#ifdef MEDIA773_SU1E_AU1E
BOOLEAN F1999_FILE_Read(unsigned char* P5919_puc_Buffer, unsigned int16_t P5920_ui_ByteCount)
{
        register long L5778_;


        if ((L5778_ = P5920_ui_ByteCount) == 0) {
                return 1;
        } else {
#ifdef MEDIA772_SU1E
                return (Fread(G3805_FileHandle, L5778_, P5919_puc_Buffer) == L5778_);
#endif
#ifdef MEDIA762_AU1E
                return F0772_FILE_Read(G3805_FileHandle, L5778_, P5919_puc_Buffer);
#endif
        }
}

BOOLEAN F2000_FILE_Write(unsigned char* P5921_puc_Buffer, unsigned int16_t P5922_ui_ByteCount)
{
        register long L5779_;


        if ((L5779_ = P5922_ui_ByteCount) == 0) {
                return 1;
        } else {
#ifdef MEDIA772_SU1E
                return (Fwrite(G3805_FileHandle, L5779_, P5921_puc_Buffer) == L5779_);
#endif
#ifdef MEDIA762_AU1E
                return F0773_FILE_Write(G3805_FileHandle, L5779_, P5921_puc_Buffer);
#endif
        }
}
#endif

/* Obfuscation and deobfuscation are the same reversible operation */
unsigned int16_t F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(
REGISTER unsigned int16_t* P0804_pui_Buffer  SEPARATOR
REGISTER unsigned int16_t P0805_ui_Key       SEPARATOR
REGISTER unsigned int16_t P0806_ui_WordCount FINAL_SEPARATOR
{
        REGISTER unsigned int16_t L1282_ui_Checksum;


        L1282_ui_Checksum = P0805_ui_Key;
        do {
                L1282_ui_Checksum += *P0804_pui_Buffer;
                *P0804_pui_Buffer ^= P0805_ui_Key;
                L1282_ui_Checksum += *P0804_pui_Buffer++;
                P0805_ui_Key += P0806_ui_WordCount;
        } while (--P0806_ui_WordCount);
        return L1282_ui_Checksum;
}

unsigned int16_t F7056_F0418_SAVEUTIL_GetChecksum(
REGISTER unsigned int16_t* P0807_pui_Buffer   SEPARATOR
REGISTER unsigned int16_t  P0808_ui_Key       SEPARATOR
REGISTER unsigned int16_t  P0809_ui_WordCount FINAL_SEPARATOR
{
        REGISTER unsigned int16_t L1283_ui_Checksum;


        L1283_ui_Checksum = P0808_ui_Key;
        do {
                L1283_ui_Checksum += *P0807_pui_Buffer;
                L1283_ui_Checksum += *P0807_pui_Buffer++ ^ P0808_ui_Key;
                P0808_ui_Key += P0809_ui_WordCount;
        } while (--P0809_ui_WordCount);
        return L1283_ui_Checksum;
}

#ifdef MEDIA773_SU1E_AU1E
BOOLEAN F7057_ReadSaveGamePartWithChecksum(unsigned char* P3578_puc_Buffer, unsigned int16_t P3579_ui_Size, unsigned int16_t P3580_ui_Key, unsigned int16_t P3581_ui_Checksum)
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
void F7057_ReadSaveGamePartWithChecksum(unsigned char* P3578_puc_Buffer, unsigned int16_t P3579_ui_Size, unsigned int16_t P3580_ui_Key, unsigned int16_t P3581_ui_Checksum)
#endif
{
#ifdef MEDIA773_SU1E_AU1E
        return (F1999_FILE_Read(P3578_puc_Buffer, P3579_ui_Size)) && (F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(P3578_puc_Buffer, P3580_ui_Key, P3579_ui_Size >> 1) == P3581_ui_Checksum);
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
        if (P3579_ui_Size != 0) {
                F7137_FileOperation(G7004_SavedGameFileHandle, C0xF00A_OPERATION_READ, C16_FILEOP_BYTE_COUNT, (long)P3579_ui_Size, C15_FILEOP_SET_BUFFER, P3578_puc_Buffer, 0);
                if (F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(M776_CAST_PUI(P3578_puc_Buffer), P3580_ui_Key, P3579_ui_Size >> 1) != P3581_ui_Checksum) {
                        F7112_FallbackToLastProgramState(C0_FALSE, 23001, 0L);
                }
        }
#endif
}

#ifdef MEDIA773_SU1E_AU1E
int16_t F7058_WriteSavePartWithChecksum(register char* P3715_pc_Buffer, unsigned int16_t P3716_ui_ByteCount, int16_t P3717_i_Key, unsigned int16_t* P3718_pui_Checksum)
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
void F7058_WriteSavePartWithChecksum(REGISTER char* P3715_pc_Buffer, unsigned int16_t P3716_ui_ByteCount, int16_t P3717_i_Key, unsigned int16_t* P3718_pui_Checksum)
#endif
{
#ifdef MEDIA773_SU1E_AU1E
        register int16_t L5780_i_;
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
        REGISTER long L6036_l_Unreferenced;
#endif
        REGISTER int16_t L3961_i_;


#ifdef MEDIA773_SU1E_AU1E
        *P3718_pui_Checksum = F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(P3715_pc_Buffer, P3717_i_Key, L3961_i_ = P3716_ui_ByteCount >> 1);
        L5780_i_ = F2000_FILE_Write(P3715_pc_Buffer, P3716_ui_ByteCount);
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
        L3961_i_ = P3716_ui_ByteCount >> 1;
        *P3718_pui_Checksum = F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(M776_CAST_PUI(P3715_pc_Buffer), P3717_i_Key, L3961_i_);
        F7137_FileOperation(G7004_SavedGameFileHandle, C0xF00B_OPERATION_WRITE, C16_FILEOP_BYTE_COUNT, (long)P3716_ui_ByteCount, C15_FILEOP_SET_BUFFER, P3715_pc_Buffer, 0);
#endif
        F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(M776_CAST_PUI(P3715_pc_Buffer), P3717_i_Key, L3961_i_);
#ifdef MEDIA773_SU1E_AU1E
        return L5780_i_;
#endif
}

#ifdef MEDIA773_SU1E_AU1E
int16_t F7059_ReadDungeonPartWithChecksum(register unsigned char* P3719_pc_, register int16_t* P3720_pi_Checksum, register unsigned int16_t P3721_ui_ByteCount)
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
void F7059_ReadDungeonPartWithChecksum(REGISTER unsigned char* P3719_pc_, REGISTER int16_t* P3720_pi_Checksum, REGISTER unsigned int16_t P3721_ui_ByteCount)
#endif
{
        REGISTER unsigned int16_t L3962_ui_ = 0;


#ifdef MEDIA773_SU1E_AU1E
        if (F1999_FILE_Read(P3719_pc_, P3721_ui_ByteCount) == 0) {
                return 0;
        }
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
        if (P3721_ui_ByteCount != 0) {
                F7137_FileOperation(G7004_SavedGameFileHandle, C0xF00A_OPERATION_READ, C16_FILEOP_BYTE_COUNT, (long)P3721_ui_ByteCount, C15_FILEOP_SET_BUFFER, P3719_pc_, 0);
#endif
                while (P3721_ui_ByteCount--) {
                        L3962_ui_ += *P3719_pc_++;
                }
                *P3720_pi_Checksum += L3962_ui_;
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
        }
#endif
#ifdef MEDIA773_SU1E_AU1E
        return 1;
#endif
}

#ifdef MEDIA773_SU1E_AU1E
int16_t F7060_WriteDungeonPartWithChecksum(register unsigned char* P3722_puc_, register int16_t* P3723_pi_Checksum, register unsigned int16_t P3724_ui_ByteCount)
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
void F7060_WriteDungeonPartWithChecksum(REGISTER unsigned char* P3722_puc_, REGISTER int16_t* P3723_pi_Checksum, REGISTER unsigned int16_t P3724_ui_ByteCount)
#endif
{
        REGISTER int16_t L3963_i_ = 0;


#ifdef MEDIA773_SU1E_AU1E
        if (F2000_FILE_Write(P3722_puc_, P3724_ui_ByteCount) == 0) {
                return 0;
        }
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
        F7137_FileOperation(G7004_SavedGameFileHandle, C0xF00B_OPERATION_WRITE, C16_FILEOP_BYTE_COUNT, (long)P3724_ui_ByteCount, C15_FILEOP_SET_BUFFER, P3722_puc_, 0);
#endif
        while (P3724_ui_ByteCount--) {
                L3963_i_ += *P3722_puc_++;
        }
        *P3723_pi_Checksum += L3963_i_;
#ifdef MEDIA773_SU1E_AU1E
        return 1;
#endif
}

#ifdef MEDIA773_SU1E_AU1E
BOOLEAN F1993_(register CSB_SAVE_HEADER* P5905_) {
        register int16_t L5762_;
        register int16_t L5763_;
        register int16_t L5764_;


        if (F1999_FILE_Read(P5905_, 512) == 0) {
                return 0;
        } else {
                return 1;
        }
}
#endif

BOOLEAN F7061_F0429_STARTEND_IsReadSaveHeaderSuccessful(int16_t* P0846_pi_Buffer, unsigned int16_t P3582_ui_KeyWordIndex)
{
        REGISTER int16_t* L1323_pi_HeaderData;
        REGISTER unsigned int16_t L1320_ui_Counter;
        REGISTER int16_t L1321_i_ExpectedChecksum;
        REGISTER int16_t L1322_i_Checksum;


        L1323_pi_HeaderData = P0846_pi_Buffer;
        L1320_ui_Counter = 32;
        L1321_i_ExpectedChecksum = 0;
        /* Compute expected checksum over the first 256 bytes of the header */
        do {
                L1321_i_ExpectedChecksum += *L1323_pi_HeaderData++;
                L1321_i_ExpectedChecksum ^= *L1323_pi_HeaderData++;
                L1321_i_ExpectedChecksum -= *L1323_pi_HeaderData++;
                L1321_i_ExpectedChecksum ^= *L1323_pi_HeaderData++;
        } while (--L1320_ui_Counter);
        /* Deobfuscate the last 256 bytes of the header */
        F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(M776_CAST_PUI(L1323_pi_HeaderData), P0846_pi_Buffer[P3582_ui_KeyWordIndex], 128);
        L1322_i_Checksum = 0;
        L1320_ui_Counter = 128;
        do {
                L1322_i_Checksum += *L1323_pi_HeaderData++;
        } while (--L1320_ui_Counter);
        return (L1321_i_ExpectedChecksum == L1322_i_Checksum);
}

#ifdef MEDIA773_SU1E_AU1E
int16_t F7062_F0430_STARTEND_IsWriteObfuscatedSaveHeaderSuccessful(
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
void F7062_F0430_STARTEND_IsWriteObfuscatedSaveHeaderSuccessful(
#endif
int16_t* P0847_pi_Buffer              SEPARATOR
unsigned int16_t P3583_i_KeyWordIndex FINAL_SEPARATOR
{
        REGISTER int16_t* L1327_pi_HeaderData;
#ifdef MEDIA696_X31J_P31J_SU1E_AU1E_AU2E_AU3E
        register unsigned int16_t L1324_ui_Multiple;
#endif
#ifdef MEDIA670_F31E_F31J
        unsigned int16_t L1324_ui_Multiple;
#endif
#define AL1324_ui_Counter                    L1324_ui_Multiple
        register int16_t L1325_i_LastWord;
        register int16_t L1326_i_Checksum = 0;


        AL1324_ui_Counter = 128;
        L1327_pi_HeaderData = P0847_pi_Buffer + 128;
        do {
                L1326_i_Checksum += *L1327_pi_HeaderData++;
        } while (--AL1324_ui_Counter);
        AL1324_ui_Counter = 32;
        L1325_i_LastWord = 0;
        L1327_pi_HeaderData = P0847_pi_Buffer;
        for (;;) { /*_Infinite loop_*/
                L1325_i_LastWord += *L1327_pi_HeaderData++ = M006_RANDOM(65536);
                L1325_i_LastWord ^= *L1327_pi_HeaderData++ = M006_RANDOM(65536);
                L1325_i_LastWord -= *L1327_pi_HeaderData++ = M006_RANDOM(65536);
                if (--AL1324_ui_Counter == 0) {
                        break;
                }
                L1325_i_LastWord ^= *L1327_pi_HeaderData++ = M006_RANDOM(65536);
        }
        *L1327_pi_HeaderData++ = L1325_i_LastWord ^ L1326_i_Checksum;
        F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(M776_CAST_PUI(L1327_pi_HeaderData), P0847_pi_Buffer[P3583_i_KeyWordIndex], 128); /* Obfuscate before writing */
#ifdef MEDIA773_SU1E_AU1E
        L1324_ui_Multiple = F2000_FILE_Write(P0847_pi_Buffer, 512);
#endif
#ifdef MEDIA677_F31E_F31J_X31J_P31J_AU2E_AU3E
        F7137_FileOperation(G7004_SavedGameFileHandle, C0xF00B_OPERATION_WRITE, C16_FILEOP_BYTE_COUNT, (long)512, C15_FILEOP_SET_BUFFER, P0847_pi_Buffer, 0);
#endif
        F7055_F0417_SAVEUTIL_GetChecksumAndObfuscate(M776_CAST_PUI(L1327_pi_HeaderData), P0847_pi_Buffer[P3583_i_KeyWordIndex], 128); /* Deobfuscate after writing */
#ifdef MEDIA773_SU1E_AU1E
        return L1324_ui_Multiple;
#endif
}
#endif
