mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
410 lines
13 KiB
C
410 lines
13 KiB
C
/**
|
|
* @file m_flashrom.c
|
|
* @brief Save game check and error handling functions.
|
|
*
|
|
* This file contains functions related to save game checks, error handling,
|
|
* and related utility functions. The functions are responsible for verifying
|
|
* save data integrity, managing error information, and displaying save data
|
|
* check results and error information.
|
|
*
|
|
* Global Functions:
|
|
* - mFRm_set_msg_idx() : Set the message index.
|
|
* - mFRm_get_msg_idx() : Get the message index.
|
|
* - mFRm_ReturnCheckSum() : Calculate the checksum of the given data.
|
|
* - mFRm_GetFlatCheckSum() : Calculate the flat checksum for save data.
|
|
* - mFRm_CheckSaveData_ID() : Check if the save data ID matches the expected ID.
|
|
* - mFRm_CheckSaveData_common(): Check the save data for various conditions.
|
|
* - mFRm_CheckSaveData() : Perform a save data check.
|
|
* - mFRm_ClearSaveCheckData() : Clear the save check data structure.
|
|
* - mFRm_SetSaveCheckData() : Set the save check data structure.
|
|
* - mFRm_PrintSavedDebug() : Print a debug indicator if saved debug data is found.
|
|
* - mFRm_clear_err_info() : Clear the error information array.
|
|
* - mFRm_save_data_check() : Perform a series of save data checks and store errors.
|
|
* - mFRm_display_errInfo() : Display error information on the screen.
|
|
*
|
|
* File-local Functions:
|
|
* - mFRm_get_free_errInfo() : Find a free slot in the error information array.
|
|
* - mFRm_set_errInfo() : Set error information in the error information array.
|
|
* - mFRm_get_errInfoNum() : Get the number of errors in the error information array.
|
|
*/
|
|
|
|
/* TODO: finish & include sChk_ZZZ files each programmer wrote */
|
|
/* TODO: A few removed functions need to be matched on N64 and included for proper .rodata layout */
|
|
|
|
#include "m_flashrom.h"
|
|
|
|
#include "m_common_data.h"
|
|
#include "m_time.h"
|
|
#include "m_land.h"
|
|
#include "zurumode.h"
|
|
|
|
static int l_mfrm_msg_idx;
|
|
static int l_mfrm_now_color;
|
|
static mFRm_err_info_c l_mfrm_err_info[mFRm_ERROR_INFO_NUM];
|
|
static int l_mfrm_err_debug[] = {0, 0, 0, 0, 0, 0};
|
|
|
|
/* Predeclaration for save check functions */
|
|
static int sChk_check_save_data();
|
|
static int sChk_check_save_gen();
|
|
static int sChk_CheckSaveData_MYK();
|
|
static int sChk_CheckSaveData_NSW();
|
|
static int sChk_check_save_take();
|
|
static int sChk_CheckSaveData_YSD();
|
|
static int sChk_CheckSaveData_komatu();
|
|
|
|
/**
|
|
* @brief Set the current message index value.
|
|
*
|
|
* This function sets the global message index value to the provided input.
|
|
*
|
|
* @param idx The message index value to be set.
|
|
*/
|
|
extern void mFRm_set_msg_idx(int idx) {
|
|
l_mfrm_msg_idx = idx;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the current message index value.
|
|
*
|
|
* This function returns the global message index value.
|
|
*
|
|
* @return int The current message index value.
|
|
*/
|
|
extern int mFRm_get_msg_idx() {
|
|
return l_mfrm_msg_idx;
|
|
}
|
|
|
|
/**
|
|
* @brief Calculate the checksum of the given data.
|
|
*
|
|
* This function calculates the checksum of the provided data by adding
|
|
* all the 16-bit data elements together.
|
|
*
|
|
* @param data A pointer to the data buffer.
|
|
* @param size The size of the data buffer in bytes.
|
|
* @return u16 The calculated checksum.
|
|
*/
|
|
extern u16 mFRm_ReturnCheckSum(u16* data, int size) {
|
|
u16 checksum = 0;
|
|
|
|
// Check if the size is even
|
|
if ((size & 1) == 0) {
|
|
// Calculate the checksum by adding all 16-bit data elements
|
|
while (size != 0) {
|
|
checksum += *data;
|
|
data++;
|
|
size -= sizeof(u16);
|
|
}
|
|
}
|
|
|
|
return checksum;
|
|
}
|
|
|
|
/**
|
|
* @brief Calculate the flat checksum of the given data.
|
|
*
|
|
* This function calculates the flat checksum of the provided data by
|
|
* subtracting the current checksum from the calculated checksum and
|
|
* then performing a bitwise complement and incrementing by 1.
|
|
*
|
|
* @param data A pointer to the data buffer.
|
|
* @param size The size of the data buffer in bytes.
|
|
* @param now_checksum The current checksum of the data buffer.
|
|
* @return u16 The calculated flat checksum.
|
|
*/
|
|
extern u16 mFRm_GetFlatCheckSum(u16* data, int size, u16 now_checksum) {
|
|
// Calculate the checksum
|
|
u16 checksum = mFRm_ReturnCheckSum(data, size) - now_checksum;
|
|
|
|
// Perform bitwise complement and increment by 1
|
|
return (u16)(((~checksum & 0xFFFF) + 1) & 0xFFFF);
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the save data ID is valid.
|
|
*
|
|
* This function checks if the provided save_check structure contains a valid
|
|
* save data ID.
|
|
*
|
|
* @param save_check A pointer to the mFRm_chk_t structure containing the save data ID.
|
|
* @return int Returns TRUE if the save data ID is valid, otherwise FALSE.
|
|
*/
|
|
extern int mFRm_CheckSaveData_ID(mFRm_chk_t* save_check) {
|
|
int ret = FALSE;
|
|
|
|
// Check if the save data ID is valid
|
|
if ((save_check->code == mFRm_SAVE_ID)) {
|
|
ret = TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the save data is valid.
|
|
*
|
|
* This function checks if the provided save_check structure contains valid save data,
|
|
* comparing the land ID with the provided land_id parameter.
|
|
*
|
|
* @param save_check A pointer to the mFRm_chk_t structure containing the save data.
|
|
* @param land_id The land ID to check against the save data.
|
|
* @return int Returns TRUE if the save data is valid, otherwise FALSE.
|
|
*/
|
|
extern int mFRm_CheckSaveData_common(mFRm_chk_t* save_check, u16 land_id) {
|
|
int ret = FALSE;
|
|
|
|
// Check if the save data ID is valid and land IDs match
|
|
if (mFRm_CheckSaveData_ID(save_check) != 0 &&
|
|
mLd_CHECK_LAND_ID(save_check->land_id) &&
|
|
save_check->land_id == land_id) {
|
|
ret = TRUE;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the current save data is valid.
|
|
*
|
|
* This function checks if the current save data is valid using mFRm_CheckSaveData_common.
|
|
*
|
|
* @return int Returns TRUE if the save data is valid, otherwise FALSE.
|
|
*/
|
|
extern int mFRm_CheckSaveData() {
|
|
return mFRm_CheckSaveData_common(Save_GetPointer(save_check), Save_Get(land_info.id));
|
|
}
|
|
|
|
/**
|
|
* @brief Clear the save check data.
|
|
*
|
|
* This function clears the provided save_check structure by setting its fields to their
|
|
* default values.
|
|
*
|
|
* @param save_check A pointer to the mFRm_chk_t structure to be cleared.
|
|
*/
|
|
extern void mFRm_ClearSaveCheckData(mFRm_chk_t* save_check) {
|
|
// Set the save check data fields to their default values
|
|
save_check->code = -1;
|
|
save_check->land_id = 0xFFFF;
|
|
bcopy((lbRTC_time_c*)&mTM_rtcTime_clear_code, &save_check->time, sizeof(lbRTC_time_c));
|
|
save_check->checksum = 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the save check data.
|
|
*
|
|
* This function sets the save check data fields based on the current save data
|
|
* and real-time clock values.
|
|
*
|
|
* @param save_check A pointer to the mFRm_chk_t structure to be set.
|
|
*/
|
|
extern void mFRm_SetSaveCheckData(mFRm_chk_t* save_check) {
|
|
u16 land_id = Save_Get(land_info.id);
|
|
|
|
// Set the save check data fields
|
|
save_check->code = mFRm_SAVE_ID;
|
|
save_check->land_id = land_id;
|
|
lbRTC_TimeCopy(&save_check->time, &common_data.time.rtc_time);
|
|
}
|
|
|
|
/**
|
|
* @brief Print the saved debug information.
|
|
*
|
|
* This function prints an 'X' to the screen if the saved debug information is available.
|
|
*
|
|
* @param gfxprint A pointer to the gfxprint_t structure for screen printing.
|
|
*/
|
|
extern void mFRm_PrintSavedDebug(gfxprint_t* gfxprint) {
|
|
// Check if the saved debug information is available
|
|
if (Save_Get(saved_rom_debug) == TRUE) {
|
|
// Set the print color and location
|
|
gfxprint_color(gfxprint, 50, 250, 100, 255);
|
|
gfxprint_locate8x8(gfxprint, 29, 3);
|
|
// Print an 'X' to the screen
|
|
gfxprint_printf(gfxprint, "X");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Clear the error information.
|
|
*
|
|
* This function clears the error information by setting all error numbers
|
|
* to mFRm_NO_ERROR_NO.
|
|
*/
|
|
extern void mFRm_clear_err_info() {
|
|
int i;
|
|
// Zero out the error information array
|
|
bzero(l_mfrm_err_info, sizeof(mFRm_err_info_c) * mFRm_ERROR_INFO_NUM);
|
|
|
|
// Set all error numbers to mFRm_NO_ERROR_NO
|
|
for (i = 0; i < mFRm_ERROR_INFO_NUM; i++) {
|
|
l_mfrm_err_info[i].err_no = mFRm_NO_ERROR_NO;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Get a free error information slot.
|
|
*
|
|
* This function returns a pointer to the first available error information slot.
|
|
*
|
|
* @param err_info A pointer to the error information array.
|
|
* @param count The number of error information slots.
|
|
* @return mFRm_err_info_c* A pointer to the first available error information slot or NULL if none are available.
|
|
*/
|
|
static mFRm_err_info_c* mFRm_get_free_errInfo(mFRm_err_info_c* err_info, int count) {
|
|
mFRm_err_info_c* ret = NULL;
|
|
|
|
// Iterate through the error information slots
|
|
while (count != 0) {
|
|
// Check if the current slot is available
|
|
if (err_info->err_no == mFRm_NO_ERROR_NO) {
|
|
ret = err_info;
|
|
break;
|
|
}
|
|
err_info++;
|
|
count--;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the error information for a specific process.
|
|
*
|
|
* This function sets the error information for the specified process index and error number.
|
|
*
|
|
* @param err_info A pointer to the error information array.
|
|
* @param proc_idx The process index for which the error occurred.
|
|
* @param err_no The error number to be set.
|
|
*/
|
|
static void mFRm_set_errInfo(mFRm_err_info_c* err_info, int proc_idx, int err_no) {
|
|
// Get a free error information slot
|
|
mFRm_err_info_c* free = mFRm_get_free_errInfo(err_info, mFRm_ERROR_INFO_NUM);
|
|
|
|
// Set the error information if a free slot is available
|
|
if (free != NULL) {
|
|
free->err_no = err_no;
|
|
free->proc_idx = proc_idx;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Get the number of error information slots with errors.
|
|
*
|
|
* This function returns the number of error information slots with error numbers
|
|
* different from mFRm_NO_ERROR_NO.
|
|
*
|
|
* @param err_info A pointer to the error information array.
|
|
* @param count The number of error information slots.
|
|
* @return int The number of error information slots with errors.
|
|
*/
|
|
static int mFRm_get_errInfoNum(mFRm_err_info_c* err_info, int count) {
|
|
int ret = 0;
|
|
|
|
// Loop through the error information slots
|
|
while (count != 0) {
|
|
// Increment the count if the error number is not mFRm_NO_ERROR_NO
|
|
if (err_info->err_no != mFRm_NO_ERROR_NO) {
|
|
ret++;
|
|
}
|
|
err_info++;
|
|
count--;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Perform save data checks.
|
|
*
|
|
* This function performs save data checks for different procedures and
|
|
* increments the color index upon each check.
|
|
*/
|
|
extern void mFRm_save_data_check() {
|
|
// Define save data check procedures
|
|
static save_check_proc* proc[] = {
|
|
&sChk_check_save_data, &sChk_check_save_gen, &sChk_CheckSaveData_MYK,
|
|
&sChk_CheckSaveData_NSW, &sChk_check_save_take, &sChk_CheckSaveData_YSD,
|
|
&sChk_CheckSaveData_komatu
|
|
};
|
|
|
|
int i = 0;
|
|
mFRm_err_info_c* err_info = l_mfrm_err_info;
|
|
l_mfrm_now_color = 0;
|
|
|
|
// If zurumode_flag is greater or equal to 2 and scene_no is 7, perform save data checks
|
|
if ((zurumode_flag >= 2) && (Save_Get(scene_no) == 7)) {
|
|
// If there are no errors, perform the save data checks
|
|
if (mFRm_get_errInfoNum(err_info, mFRm_ERROR_INFO_NUM) == 0) {
|
|
while (i < 7) {
|
|
(*proc[i])();
|
|
l_mfrm_now_color++;
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Color table for displaying error information */
|
|
static u32 l_mfrm_color_table[7][3] = {
|
|
{ 0, 0, 0}, /* Black */
|
|
{255, 0, 0}, /* Red */
|
|
{255, 255, 255}, /* White */
|
|
{ 0, 190, 0}, /* Green */
|
|
{100, 100, 100}, /* Gray */
|
|
{ 0, 0, 255}, /* Blue */
|
|
{255, 0, 255} /* Magenta */
|
|
};
|
|
|
|
/* This needs pool_data on */
|
|
#pragma pool_data on
|
|
/**
|
|
* @brief Display error information on the screen.
|
|
*
|
|
* This function displays the error information on the screen if there are
|
|
* any errors and if the zurumode_flag is greater than or equal to 2.
|
|
*
|
|
* @param gfxprint A pointer to the gfxprint_t structure for screen printing.
|
|
*/
|
|
extern void mFRm_display_errInfo(gfxprint_t* gfxprint) {
|
|
mFRm_err_info_c* err_info = l_mfrm_err_info;
|
|
int i;
|
|
|
|
// If zurumode_flag is greater or equal to 2 and scene_no is 7, display
|
|
// error information
|
|
if ((zurumode_flag >= 2) && (Save_Get(scene_no) == 7)) {
|
|
gfxprint_locate8x8(gfxprint, 37, 17);
|
|
gfxprint_color(gfxprint, 255, 255, 255, 255);
|
|
gfxprint_printf(gfxprint, "-");
|
|
|
|
// If there are errors, display them on the screen
|
|
if (mFRm_get_errInfoNum(err_info, mFRm_ERROR_INFO_NUM) > 0) {
|
|
for (i = 0; i < 10; i++) {
|
|
gfxprint_locate8x8(gfxprint, 30, i + 18);
|
|
|
|
// Break the loop if no error is found
|
|
if (err_info->err_no == mFRm_NO_ERROR_NO) {
|
|
break;
|
|
}
|
|
|
|
// Set the color for displaying the error information
|
|
gfxprint_color(
|
|
gfxprint,
|
|
l_mfrm_color_table[err_info->err_no][0],
|
|
l_mfrm_color_table[err_info->err_no][1],
|
|
l_mfrm_color_table[err_info->err_no][2],
|
|
255
|
|
);
|
|
|
|
// Display the error information
|
|
gfxprint_printf(
|
|
gfxprint,
|
|
"x%dx %d",
|
|
err_info->err_no,
|
|
err_info->proc_idx
|
|
);
|
|
err_info++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#pragma pool_data reset
|