#pragma once /*! * @file kmemcard.h * Memory card interface. Very messy code. */ #include "common/common_types.h" #include "kmachine.h" void kmemcard_init_globals(); constexpr s32 SAVE_SIZE = 691; // likely different between versions! 692 on PAL/JPN constexpr s32 BANK_SIZE = 0x10000; // each card can be in one of these states: enum class MemoryCardState : u32 { UNKNOWN = 0, // we know nothing about the card. KNOWN = 1, // we know if the card is there or not OPEN_BUT_UNFORMATTED = 2, // we checked the status, and its a valid card, but it's not formatted FORMATTED = 3 // the card is formatted }; // cached in ee memory so we can preview. struct MemoryCardFile { u32 present; // todo: enough memory? u32 most_recent_save_count; u32 last_saved_bank; u8 data[64]; }; // type of the mc field. struct MemoryCard { MemoryCardState state; u32 handle; u32 countdown_to_check; u32 inited; u32 last_file; u32 mem_size; MemoryCardFile files[4]; }; // FORMAT: // args: handle // requirements: handle is for a card that is OPEN_BUT_UNFORMATTED. // formats the memory card. // Callbacks: // sceMcGetInfo -> cb_reprobe_format -> // UNFORMAT: // args: handle // requirements: handle is for a card that is FORMATTED // unformats the memory card (for debug use only) // Callbacks: // sceMcUnformat -> cb_unformat // CREATE_FILE: // args: handle // requirement: handle is for a card that is FORMATTED // creates the Jak and Daxter save directory and files // Callbacks: // sceMcGetInfo -> cb_reprobe_createfile // SAVE_FILE: // args: handle, file_idx (believed) // requirement: handle is for a card that is FORMATTED and has file // saves game data // Callbacks: // sceMcGetInfo -> cb_reprobe_save // LOAD_FILE: // args: handle, file_idx // requirement: handle is for a card that is FORMATTED and has file // loads game data // Callbacks: // sceMcGetInfo -> cb_reprobe_load // probing: // sceMcGetInfo -> cb_probe -> sceMcGetDir -> cb_getdir -> sceMcOpen -> cb_check_open -> // -> sceMcRead -> cb_check_read enum class MemoryCardOperationKind : u32 { NO_OP = 0, FORMAT = 1, // (handle, unused), (slot, type, free, format) UNFORMAT = 2, // (handle, unused), (slot) CREATE_FILE = 3, // (handle, unused) SAVE = 4, LOAD = 5, }; enum class McStatusCode : u32 { BUSY = 0, OK = 1, BAD_HANDLE = 2, FORMAT_FAILED = 3, INTERNAL_ERROR = 4, WRITE_ERROR = 5, READ_ERROR = 6, NEW_GAME = 7, NO_MEMORY = 8, NO_CARD = 9, NO_LAST = 10, NO_FORMAT = 11, NO_FILE = 12, NO_SAVE = 13, NO_SPACE = 14, BAD_VERSION = 15, NO_PROCESS = 16, NO_AUTO_SAVE = 17 }; struct MemoryCardOperation { MemoryCardOperationKind operation; uint32_t param; uint32_t param2; McStatusCode result; uint32_t retry_count; Ptr data_ptr; Ptr data_ptr2; }; struct mc_file_info { u32 present; u8 data[64]; }; struct mc_slot_info { u32 handle; u32 known; u32 formatted; u32 initted; s32 last_file; u32 mem_required; u32 mem_actual; mc_file_info files[4]; }; void MC_set_language(s32 lang); void MC_run(); u64 MC_format(s32 card_idx); u64 MC_unformat(s32 card_idx); u64 MC_createfile(s32 param, Ptr data); u64 MC_save(s32 card_idx, s32 file_idx, Ptr save_data, Ptr save_summary_data); u64 MC_load(s32 card_idx, s32 file_idx, Ptr data); void MC_makefile(s32 port, s32 size); void MC_get_status(s32 slot, Ptr info); u32 MC_check_result();