diff --git a/README.md b/README.md index b8d40f303e..7aa2913ffb 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ So far, we've decompiled around 400,000 lines of GOAL code, out of an estimated Here are some screenshots of the renderer: ![](./docs/img/screenshot_hut_new_small.png) -![](./docs/img/screenshot_jungle1_small.png) +![](./docs/img/screenshot_junglenew_custommood_small.png) YouTube playlist: https://www.youtube.com/playlist?list=PLWx9T30aAT50cLnCTY1SAbt2TtWQzKfXX diff --git a/docs/img/screenshot_hut.png b/docs/img/screenshot_hut.png deleted file mode 100644 index f59f07a014..0000000000 Binary files a/docs/img/screenshot_hut.png and /dev/null differ diff --git a/docs/img/screenshot_jungle1_small.png b/docs/img/screenshot_jungle1_small.png deleted file mode 100644 index ccfa520cf0..0000000000 Binary files a/docs/img/screenshot_jungle1_small.png and /dev/null differ diff --git a/docs/img/screenshot_junglenew_custommood_small.png b/docs/img/screenshot_junglenew_custommood_small.png new file mode 100644 index 0000000000..3b3f83c0e3 Binary files /dev/null and b/docs/img/screenshot_junglenew_custommood_small.png differ diff --git a/docs/img/screenshot_vi1.png b/docs/img/screenshot_vi1.png deleted file mode 100644 index 5afdb6e14f..0000000000 Binary files a/docs/img/screenshot_vi1.png and /dev/null differ diff --git a/game/kernel/kmemcard.cpp b/game/kernel/kmemcard.cpp index 8c9ea62698..06e9c63738 100644 --- a/game/kernel/kmemcard.cpp +++ b/game/kernel/kmemcard.cpp @@ -1,10 +1,12 @@ /*! * @file kmemcard.cpp - * Memory card interface. Very messy code. + * Memory card interface. Very messy code. Most of it is commented out now, as we've switched away + * from memory cards to just raw saves. */ #include #include +#include #include "third-party/fmt/core.h" @@ -14,20 +16,29 @@ #include "game/kernel/kdgo.h" #include "game/common/ramdisk_rpc_types.h" #include "game/kernel/fileio.h" +#include "common/util/FileUtil.h" +#include "common/util/Timer.h" #include "common/util/Assert.h" -constexpr static bool memcard_debug = false; +static constexpr bool memcard_debug = false; using McCallbackFunc = void (*)(s32); McCallbackFunc callback; -static s32 next; +// static s32 next; static s32 language; static MemoryCardOperation op; -static MemoryCard mc[2]; -static RPC_Ramdisk_LoadCmd ramdisk_cmd; -static ee::sceMcTblGetDir dirent; +// static MemoryCard mc[2]; +// instead of two memory cards we just simulate the 4 save files (8 banks). +static MemoryCardFile mc_files[4]; +// keep track of latest file selected. this is only used in an auto-save mode thats not used +static int mc_last_file = -1; +// static RPC_Ramdisk_LoadCmd ramdisk_cmd; +// static ee::sceMcTblGetDir dirent; + +// a random value we will use as the memory card "handle" for the pc port, which has no memcards. +constexpr u32 PC_MEM_CARD_HANDLE = 0x6C616F67; constexpr u32 MEM_CARD_MAGIC = 0x12345678; @@ -39,8 +50,8 @@ struct McHeader { u8 data[944]; u32 unk1_repeated; }; - static_assert(sizeof(McHeader) == 0x400, "McHeader size"); +constexpr s32 BANK_TOTAL_SIZE = BANK_SIZE + sizeof(McHeader) * 2; static McHeader header; @@ -48,33 +59,33 @@ static McHeader header; static s32 p1, p2, p3, p4; using namespace ee; -void cb_reprobe_format(s32); -void cb_format_complete(s32); -void cb_unformat(s32); -void cb_reprobe_createfile(s32); -void cb_wait_for_ramdisk(s32); -void cb_wait_for_ramdisk_load(s32); -void cb_createfile_erasing(s32); -void cb_createdir(s32); -void cb_createdfile(s32); -void cb_writtenfile(s32); -void cb_closedfile(s32); -void cb_reprobe_save(s32); -void cb_reprobe_load(s32); -void cb_probe(s32); -void cb_reprobe(s32); -void cb_getdir(s32); -void cb_check_open(s32); -void cb_check_read(s32); -void cb_check_close(s32); -void cb_openedsave(s32); -void cb_savedheader(s32); -void cb_saveddata(s32); -void cb_savedfooter(s32); -void cb_closedsave(s32); -void cb_openedload(s32); -void cb_readload(s32); -void cb_closedload(s32); +// void cb_reprobe_format(s32); +// void cb_format_complete(s32); +// void cb_unformat(s32); +// void cb_reprobe_createfile(s32); +// void cb_wait_for_ramdisk(s32); +// void cb_wait_for_ramdisk_load(s32); +// void cb_createfile_erasing(s32); +// void cb_createdir(s32); +// void cb_createdfile(s32); +// void cb_writtenfile(s32); +// void cb_closedfile(s32); +// void cb_reprobe_save(s32); +// void cb_reprobe_load(s32); +// void cb_probe(s32); +// void cb_reprobe(s32); +// void cb_getdir(s32); +// void cb_check_open(s32); +// void cb_check_read(s32); +// void cb_check_close(s32); +// void cb_openedsave(s32); +// void cb_savedheader(s32); +// void cb_saveddata(s32); +// void cb_savedfooter(s32); +// void cb_closedsave(s32); +// void cb_openedload(s32); +// void cb_readload(s32); +// void cb_closedload(s32); template void mc_print(const std::string& str, Args&&... args) { @@ -97,17 +108,21 @@ const char* filename[12] = { "/BASCUS-97124AYBABTU!/bank6.bin", "/BASCUS-97124AYBABTU!/bank7.bin"}; void kmemcard_init_globals() { - next = 0; + // next = 0; language = 0; op = {}; - mc[0] = {}; - mc[1] = {}; + // mc[0] = {}; + // mc[1] = {}; + mc_files[0] = {}; + mc_files[1] = {}; + mc_files[2] = {}; + mc_files[3] = {}; callback = nullptr; p1 = 0; p2 = 0; p3 = 0; p4 = 0; - memset(&dirent, 0, sizeof(sceMcTblGetDir)); + // memset(&dirent, 0, sizeof(sceMcTblGetDir)); memset(&header, 0, sizeof(McHeader)); } @@ -117,16 +132,16 @@ void kmemcard_init_globals() { * A handle is a unique integer that can be passed up to the GOAL game code and represents a * specific memory card. If the card is removed, the handle will become invalid. */ -s32 new_mc_handle() { - s32 handle = next++; - - // if you wrap around, it avoid the zero handle. - // it doesn't seem like you will need billions of memory card handles - if (handle == 0) { - handle = next++; - } - return handle; -} +// s32 new_mc_handle() { +// s32 handle = next++; +// +// // if you wrap around, it avoids the zero handle. +// // it doesn't seem like you will need billions of memory card handles +// if (handle == 0) { +// handle = next++; +// } +// return handle; +//} /*! * A questionable checksum used on memory card data. @@ -148,16 +163,311 @@ u32 mc_checksum(Ptr data, s32 size) { /*! * Get the slot for a handle. The card must be in the given state. * Return -1 if it fails. + * There are no slots in the port. This function should not be used. */ -s32 handle_to_slot(u32 handle, MemoryCardState state) { - if (mc[0].state == state && mc[0].handle == handle) { - return 0; +// s32 handle_to_slot(u32 handle, MemoryCardState state) { +// if (mc[0].state == state && mc[0].handle == handle) { +// return 0; +// } +// if (mc[1].state == state && mc[0].handle == handle) { +// return 1; +// } else { +// return -1; +// } +//} + +/*! + * PC port function that returns whether a given bank ID's file exists or not. + */ +bool file_is_present(int id, int bank = 0) { + auto bankname = file_util::get_file_path({"user", "memcard", filename[4 + id * 2 + bank]}); + if (!std::filesystem::exists(bankname)) { + // file doesn't exist... + return false; } - if (mc[1].state == state && mc[0].handle == handle) { - return 1; + // avoid file check tbh. there shouldn't be any saves with a save count of zero anyway. + // the file check is quite slow and ultimately not very useful. + return true; + + /* + // file exists. but let's see if it's an empty one. + // this prevents the game from reading a bank but classifying it as corrupt data. + // which a file full of zeros logically is. + auto fp = fopen(bankname.c_str(), "rb"); + + // we can actually just check if the save count is over zero... + u32 savecount = 0; + fread(&savecount, sizeof(u32), 1, fp); + fclose(fp); + return savecount > 0; + */ +} + +/*! + * PC port function to set memcard info. We don't use a memory card, instead just the raw savefiles. + */ +void pc_update_card() { + // int highest_save_count = 0; + mc_last_file = -1; + for (s32 file = 0; file < 4; file++) { + auto bankname = file_util::get_file_path({"user", "memcard", filename[4 + file * 2]}); + mc_files[file].present = file_is_present(file); + if (mc_files[file].present) { + auto bankdata = file_util::read_binary_file(bankname); + auto header1 = reinterpret_cast(bankdata.data()); + if (file_is_present(file, 1)) { + auto bankname2 = file_util::get_file_path({"user", "memcard", filename[1 + 4 + file * 2]}); + auto bankdata2 = file_util::read_binary_file(bankname2); + auto header2 = reinterpret_cast(bankdata.data()); + + if (header2->save_count > header1->save_count) { + // use most recent bank here. + header1 = header2; + } + + // banks chosen and checked. copy data and set info. + mc_files[file].last_saved_bank = header1 == header2; + mc_files[file].most_recent_save_count = header1->save_count; + + memcpy(mc_files[file].data, header1->preview_data, 64); + } else { + // banks chosen and checked. copy data and set info. + mc_files[file].last_saved_bank = 0; + mc_files[file].most_recent_save_count = header1->save_count; + + memcpy(mc_files[file].data, header1->preview_data, 64); + } + + // if (mc_files[file].most_recent_save_count > highest_save_count) { + // mc_last_file = file; + // highest_save_count = mc_files[file].most_recent_save_count; + // } + } + } +} + +/*! + * PC port function to save a file. This does the whole saving at once, synchronously. + */ +void pc_game_save_synch() { + Timer mc_timer; + mc_timer.start(); + pc_update_card(); + + // cd_reprobe_save // + if (!file_is_present(op.param2)) { + mc_print("reprobe save: first time!"); + // first time saving! + p2 = 0; // save count 0 + p4 = 0; // first bank for file } else { - return -1; + p2 = mc_files[op.param2].most_recent_save_count + 1; // increment save count + p4 = mc_files[op.param2].last_saved_bank ^ 1; // use the other bank } + + // reserve 0 as "I never saved" and use 1 instead. + if (p2 == 0) { + p2 = 1; + } + + // file*2 + p4 is the bank (2 banks per file, p4 is 0 or 1 to select the bank) + // 4 is the first bank file + mc_print("open {} for saving", filename[op.param2 * 2 + 4 + p4]); + auto fd = + fopen(file_util::get_file_path({"user", "memcard", filename[op.param2 * 2 + 4 + p4]}).c_str(), + "wb"); + fmt::print("[MC] synchronous save file open took {:.2f}ms\n", mc_timer.getMs()); + if (fd) { + // cb_openedsave // + mc_print("save file opened, writing header..."); + memset(&header, 0, sizeof(McHeader)); + header.save_count = p2; + header.checksum = mc_checksum(op.data_ptr, BANK_SIZE); + header.magic = MEM_CARD_MAGIC; + header.unk1_repeated = p2; + memcpy(header.preview_data, op.data_ptr2.c(), 64); + if (fwrite(&header, sizeof(McHeader), 1, fd) == 1) { + // cb_savedheader // + mc_print("save file writing main data"); + if (fwrite(op.data_ptr.c(), BANK_SIZE, 1, fd) == 1) { + // cb_saveddata // + mc_print("save file writing footer"); + if (fwrite(&header, sizeof(McHeader), 1, fd) == 1) { + // cb_savedfooter // + if (fclose(fd) == 0) { + // cb_closedsave // + mc_print("All done with saving!!"); + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::OK; + mc_files[op.param2].present = 1; + mc_files[op.param2].most_recent_save_count = p2; + mc_files[op.param2].last_saved_bank = p4; + memcpy(mc_files[op.param2].data, op.data_ptr2.c(), 64); + mc_last_file = op.param2; + } else { + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } + } else { + fclose(fd); + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } + } else { + fclose(fd); + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } + } else { + fclose(fd); + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } + } else { + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } + + fmt::print("[MC] synchronous save took {:.2f}ms\n", mc_timer.getMs()); +} + +void pc_game_load_open_file(FILE* fd) { + if (fd) { + // cb_openedload // + size_t read_size = BANK_TOTAL_SIZE; + mc_print("reading save file..."); + if (fread(op.data_ptr.c() + p2 * read_size, read_size, 1, fd) == 1) { + // cb_readload // + mc_print("closing save file.."); + if (fclose(fd) == 0) { + // cb_closedload // + p2++; + // added : check if aux bank exists + auto new_bankname = + file_util::get_file_path({"user", "memcard", filename[op.param2 * 2 + 4 + p2]}); + bool aux_exists = std::filesystem::exists(new_bankname); + if (p2 < 2 && aux_exists) { + mc_print("reading next save bank {}", filename[op.param2 * 2 + 4 + p2]); + auto new_fd = fopen(new_bankname.c_str(), "rb"); + pc_game_load_open_file(new_fd); + } else { + // let's verify the data. + McHeader* headers[2]; + McHeader* footers[2]; + bool ok[2]; + + headers[0] = (McHeader*)(op.data_ptr.c()); + footers[0] = (McHeader*)(op.data_ptr.c() + sizeof(McHeader) + BANK_SIZE); + headers[1] = (McHeader*)(op.data_ptr.c() + BANK_TOTAL_SIZE); + footers[1] = + (McHeader*)(op.data_ptr.c() + BANK_TOTAL_SIZE + sizeof(McHeader) + BANK_SIZE); + static_assert(BANK_TOTAL_SIZE * 2 == 0x21000, "save layout"); + ok[0] = true; + ok[1] = aux_exists; + + for (int idx = 0; idx < 2; idx++) { + u32 expected_save_count = headers[idx]->save_count; + if (headers[idx]->unk1_repeated == expected_save_count && + footers[idx]->save_count == expected_save_count && + footers[idx]->unk1_repeated == expected_save_count) { + // save count is okay! + if (headers[idx]->magic == MEM_CARD_MAGIC && footers[idx]->magic == MEM_CARD_MAGIC) { + // magic numbers okay! + if (headers[idx]->checksum == footers[idx]->checksum) { + // checksum + auto expected_checksum = headers[idx]->checksum; + if (mc_checksum(make_u8_ptr(headers[idx] + 1), BANK_SIZE) != expected_checksum) { + mc_print("failed checksum"); + ok[idx] = false; + } + } else { + mc_print("corrupted checksum"); + ok[idx] = false; + } + } else { + mc_print("bad magic"); + ok[idx] = false; + } + } else { + mc_print("bad save count"); + ok[idx] = false; + } + } + + mc_print("checking loaded banks"); + + // + if (!ok[0] && !ok[1]) { + // no good data. + if (headers[0]->save_count == 0 && headers[0]->checksum == 0 && + headers[0]->magic == 0 && headers[0]->unk1_repeated == 0 && + headers[1]->save_count == 0 && headers[1]->checksum == 0 && + headers[1]->magic == 0 && headers[1]->unk1_repeated == 0) { + // this is a fresh file that you tried to load from... + mc_print("new game result"); + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::NEW_GAME; + mc_last_file = op.param2; + } else { + mc_print("corrupted data"); + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::READ_ERROR; + } + } else { + // pick the bank + int bank = 0; + + if (!ok[0] || !ok[1]) { + if (ok[1]) { + bank = 1; + } + } else { + bank = headers[0]->save_count <= headers[1]->save_count; + } + + mc_print(fmt::format("loading bank {}", bank)); + u32 current_save_count = headers[bank]->save_count; + memcpy(op.data_ptr.c(), op.data_ptr.c() + bank * BANK_TOTAL_SIZE + sizeof(McHeader), + BANK_SIZE); + mc_last_file = op.param2; + mc_files[op.param2].most_recent_save_count = current_save_count; + mc_files[op.param2].last_saved_bank = bank; + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::OK; + mc_print("load succeeded"); + } + } + } else { + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } + } else { + fclose(fd); + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } + } else { + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::INTERNAL_ERROR; + } +} + +/*! + * PC port function to load a file. This does the whole loading at once, synchronously. + */ +void pc_game_load_synch() { + Timer mc_timer; + mc_timer.start(); + pc_update_card(); + + // cb_reprobe_load // + p2 = 0; + mc_print("opening save file {}", filename[op.param2 * 2 + 4]); + auto fd = fopen( + file_util::get_file_path({"user", "memcard", filename[op.param2 * 2 + 4]}).c_str(), "rb"); + pc_game_load_open_file(fd); + + fmt::print("[MC] synchronous load took {:.2f}ms\n", mc_timer.getMs()); } /*! @@ -200,6 +510,9 @@ void MC_run() { // if we got here, there is no in-progress sony function. So start the next one, if we should if (op.operation == MemoryCardOperationKind::FORMAT) { + // format memory card. Not used in PC port, so lets move on. + return; + /* mc_print("begin format operation"); // grab the slot. should be open, but not formatted p1 = handle_to_slot(op.param, MemoryCardState::OPEN_BUT_UNFORMATTED); @@ -219,8 +532,11 @@ void MC_run() { op.operation = MemoryCardOperationKind::NO_OP; op.result = McStatusCode::INTERNAL_ERROR; } - } + } */ } else if (op.operation == MemoryCardOperationKind::UNFORMAT) { + // unformat memory card. + return; + /* mc_print("begin unformat operation"); p1 = handle_to_slot(op.param, MemoryCardState::FORMATTED); if (p1 == -1) { @@ -237,7 +553,12 @@ void MC_run() { op.result = McStatusCode::INTERNAL_ERROR; } } + */ } else if (op.operation == MemoryCardOperationKind::CREATE_FILE) { + // create the game file. + // there's no cards, keep in mind. + return; + /* mc_print("begin create file operation"); p1 = handle_to_slot(op.param, MemoryCardState::FORMATTED); if (p1 == -1) { @@ -254,50 +575,73 @@ void MC_run() { op.operation = MemoryCardOperationKind::NO_OP; op.result = McStatusCode::INTERNAL_ERROR; } - } + } */ } else if (op.operation == MemoryCardOperationKind::SAVE) { - mc_print("begin save operation"); - p1 = handle_to_slot(op.param, MemoryCardState::FORMATTED); - if (p1 == -1) { + // write game save. + // there's no cards, keep in mind. + pc_game_save_synch(); + // allow some number of errors. + op.retry_count--; + if (op.retry_count == 0) { op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; + op.result = McStatusCode::INTERNAL_ERROR; + } + // p1 = handle_to_slot(op.param, MemoryCardState::FORMATTED); + // if (p1 == -1) { + // op.operation = MemoryCardOperationKind::NO_OP; + // op.result = McStatusCode::BAD_HANDLE; + //} else { + // s32 info_result = sceMcGetInfo(p1, 0, &p2, &p3, &p4); + // if (info_result == sceMcResSucceed) { + // callback = cb_reprobe_save; + // } + // // allow some number of errors. + // op.retry_count--; + // if (op.retry_count == 0) { + // op.operation = MemoryCardOperationKind::NO_OP; + // op.result = McStatusCode::INTERNAL_ERROR; + // } + //} + } else if (op.operation == MemoryCardOperationKind::LOAD) { + // load game save. + // potato. + if (!file_is_present(op.param2)) { + // tried to load, but there's no save data in the file. + op.operation = MemoryCardOperationKind::NO_OP; + op.result = McStatusCode::NO_MEMORY; } else { - s32 info_result = sceMcGetInfo(p1, 0, &p2, &p3, &p4); - if (info_result == sceMcResSucceed) { - callback = cb_reprobe_save; - } - // allow some number of errors. + pc_game_load_synch(); op.retry_count--; if (op.retry_count == 0) { op.operation = MemoryCardOperationKind::NO_OP; op.result = McStatusCode::INTERNAL_ERROR; } } - } else if (op.operation == MemoryCardOperationKind::LOAD) { - mc_print("begin load operation"); - p1 = handle_to_slot(op.param, MemoryCardState::FORMATTED); - if (p1 == -1) { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; - } else { - if (!mc[p1].files[op.param2].present) { - // tried to load, but there's no save data in the file. - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::NO_MEMORY; - } else { - s32 info_result = sceMcGetInfo(p1, 0, &p2, &p3, &p4); - if (info_result == sceMcResSucceed) { - callback = cb_reprobe_load; - } - op.retry_count--; - if (op.retry_count == 0) { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } - } + // mc_print("begin load operation"); + // p1 = handle_to_slot(op.param, MemoryCardState::FORMATTED); + // if (p1 == -1) { + // op.operation = MemoryCardOperationKind::NO_OP; + // op.result = McStatusCode::BAD_HANDLE; + //} else { + // if (!mc[p1].files[op.param2].present) { + // // tried to load, but there's no save data in the file. + // op.operation = MemoryCardOperationKind::NO_OP; + // op.result = McStatusCode::NO_MEMORY; + // } else { + // s32 info_result = sceMcGetInfo(p1, 0, &p2, &p3, &p4); + // if (info_result == sceMcResSucceed) { + // callback = cb_reprobe_load; + // } + // op.retry_count--; + // if (op.retry_count == 0) { + // op.operation = MemoryCardOperationKind::NO_OP; + // op.result = McStatusCode::INTERNAL_ERROR; + // } + // } + //} // below here is just doing maintenance to look for new/removed memory cards. - } else if (mc[0].state == MemoryCardState::UNKNOWN) { + // it's cut from the port. we do not use memory cards. just raw saves. + } /* else if (mc[0].state == MemoryCardState::UNKNOWN) { mc_print("begin probe operation for slot 0"); // don't know anything about port 0, try and see p1 = 0; @@ -347,7 +691,7 @@ void MC_run() { } } } - } + }*/ } ///////////////////////// @@ -358,6 +702,7 @@ void MC_run() { /*! * Set the language or something. + * Why is this a memory card func? */ void MC_set_language(s32 l) { printf("Language set to %d\n", l); @@ -366,34 +711,38 @@ void MC_set_language(s32 l) { /*! * Set the current memory card operation to FORMAT the given card. + * Doesn't do anything in the port because we don't use memory cards. */ u64 MC_format(s32 card_idx) { - u64 can_add = op.operation == MemoryCardOperationKind::NO_OP; - mc_print("requested format"); - if (can_add) { - mc_print("setting op to format"); - op.operation = MemoryCardOperationKind::FORMAT; - op.result = McStatusCode::BUSY; - op.retry_count = 100; - op.param = card_idx; - } - return can_add; + return u64(McStatusCode::OK); + // u64 can_add = op.operation == MemoryCardOperationKind::NO_OP; + // mc_print("requested format"); + // if (can_add) { + // mc_print("setting op to format"); + // op.operation = MemoryCardOperationKind::FORMAT; + // op.result = McStatusCode::BUSY; + // op.retry_count = 100; + // op.param = card_idx; + //} + // return can_add; } /*! * Set the current memory card operation to UNFORMAT the given card. + * You get the idea. */ u64 MC_unformat(s32 card_idx) { - u64 can_add = op.operation == MemoryCardOperationKind::NO_OP; - mc_print("requested unformat"); - if (can_add) { - mc_print("setting op to unformat"); - op.operation = MemoryCardOperationKind::UNFORMAT; - op.result = McStatusCode::BUSY; - op.retry_count = 100; - op.param = card_idx; - } - return can_add; + return u64(McStatusCode::OK); + // u64 can_add = op.operation == MemoryCardOperationKind::NO_OP; + // mc_print("requested unformat"); + // if (can_add) { + // mc_print("setting op to unformat"); + // op.operation = MemoryCardOperationKind::UNFORMAT; + // op.result = McStatusCode::BUSY; + // op.retry_count = 100; + // op.param = card_idx; + //} + // return can_add; } /*! @@ -401,22 +750,24 @@ u64 MC_unformat(s32 card_idx) { * The data I believe is just an empty buffer used as temporary storage. */ u64 MC_createfile(s32 param, Ptr data) { - u64 can_add = op.operation == MemoryCardOperationKind::NO_OP; - mc_print("requested createfile"); - if (can_add) { - mc_print("setting op to create file"); - op.operation = MemoryCardOperationKind::CREATE_FILE; - op.result = McStatusCode::BUSY; - op.retry_count = 100; - op.param = param; - op.data_ptr = data; - } - return can_add; + return u64(McStatusCode::OK); + // u64 can_add = op.operation == MemoryCardOperationKind::NO_OP; + // mc_print("requested createfile"); + // if (can_add) { + // mc_print("setting op to create file"); + // op.operation = MemoryCardOperationKind::CREATE_FILE; + // op.result = McStatusCode::BUSY; + // op.retry_count = 100; + // op.param = param; + // op.data_ptr = data; + //} + // return can_add; } /*! * Set the current operation to SAVE. * The "summary data" is data that will be used when previewing save files (number of orbs etc) + * TODO put synchronous call here */ u64 MC_save(s32 card_idx, s32 file_idx, Ptr save_data, Ptr save_summary_data) { mc_print("requested save"); @@ -436,6 +787,7 @@ u64 MC_save(s32 card_idx, s32 file_idx, Ptr save_data, Ptr save_summary_ /*! * Set the current operation to LOAD. + * TODO put synchronous call here */ u64 MC_load(s32 card_idx, s32 file_idx, Ptr data) { mc_print("requested load"); @@ -470,7 +822,7 @@ void MC_makefile(s32 port, s32 size) { sceMcSync(0, &cmd, &fd); if (result < 0) { - printf("Can\'t open file on memcard [%d]\n", result); + printf("Can't open file on memcard [%d]\n", result); } else { // write some random crap into the memory card. sceMcWrite(fd, Ptr(0x1000000).c(), size); @@ -496,8 +848,11 @@ u32 MC_check_result() { /*! * Update the info for the given slot. * You can call this at any time. + * The slot includes the four save slots (8 banks), and a few other files. */ void MC_get_status(s32 slot, Ptr info) { + ASSERT(slot == 0); // no memory cards so only allow "slot 0"!!! + info->handle = 0; info->known = 0; info->formatted = 0; @@ -509,6 +864,22 @@ void MC_get_status(s32 slot, Ptr info) { info->mem_required = SAVE_SIZE; info->mem_actual = 0; + pc_update_card(); + info->known = 1; + info->handle = PC_MEM_CARD_HANDLE; + info->formatted = 1; + info->mem_actual = SAVE_SIZE; // idk TODO does this matter? + info->initted = 1; + // copy over the preview data. + for (s32 file = 0; file < 4; file++) { + info->files[file].present = mc_files[file].present; + for (s32 i = 0; i < 64; i++) { // actually a loop over u32's + info->files[file].data[i] = mc_files[file].data[i]; + } + } + info->last_file = mc_last_file; + + /* switch (mc[slot].state) { case MemoryCardState::KNOWN: info->known = 1; @@ -537,741 +908,740 @@ void MC_get_status(s32 slot, Ptr info) { break; case MemoryCardState::UNKNOWN: break; - } + }*/ } /*! * Check for an error. Returns true if there is an error and sets op.result as needed */ -u64 cb_check(s32 sony_error, McStatusCode goal_error) { - if (sony_error < 0) { - // sony thing failed. - if (sony_error < -9) { - // memory card gone. reset state - mc[p1].state = MemoryCardState::UNKNOWN; - // kill in progress op - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; - return 1; - } else { - // return the given GOAL error. - op.operation = MemoryCardOperationKind::NO_OP; - op.result = goal_error; - return 1; - } - } - return 0; -} +// u64 cb_check(s32 sony_error, McStatusCode goal_error) { +// if (sony_error < 0) { +// // sony thing failed. +// if (sony_error < -9) { +// // memory card gone. reset state +// mc[p1].state = MemoryCardState::UNKNOWN; +// // kill in progress op +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::BAD_HANDLE; +// return 1; +// } else { +// // return the given GOAL error. +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = goal_error; +// return 1; +// } +// } +// return 0; +//} /*! * Is this sync-result an error? If so, set status to unknown. */ -bool cb_pcheck(s32 sync_result) { - if (sync_result < 0) { - mc[p1].state = MemoryCardState::UNKNOWN; - } - return sync_result < 0; -} +// bool cb_pcheck(s32 sync_result) { +// if (sync_result < 0) { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +// return sync_result < 0; +//} /*! * Callback for sceMcGetInfo for the first time (assumes nothing about the card) + * Cut. We don't use memory cards. */ -void cb_probe(s32 sync_result) { - if (sync_result < -9) { - // changed card. We have the card, but we don't know anything about it. - mc[p1].state = MemoryCardState::KNOWN; - mc[p1].countdown_to_check = 100; - mc_print("probe: bad sync, trying again in a bit"); - } else { - // there is a memory card. - if (p2 == sceMcTypePS2) { - // it is the right type. - // create a new handle - mc[p1].handle = new_mc_handle(); - if (p4 == 0) { - mc_print("probe: got a card, but it's not formatted"); - // it's not formatted. But open (we have a handle) - mc[p1].state = MemoryCardState::OPEN_BUT_UNFORMATTED; - mc[p1].countdown_to_check = 100; - } else { - mc_print("probe: got a formatted card, trying getdir"); - // it's formatted. Get the size - mc[p1].mem_size = p3; - p2 = 0; - - // and get our jak and daxter directory - if (sceMcGetDir(p1, 0, filename[0], 0, 1, &dirent) == sceMcResSucceed) { - callback = cb_getdir; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - } - } - - } else { - mc_print("probe: bad card type, trying again in a bit"); - mc[p1].state = MemoryCardState::KNOWN; - mc[p1].countdown_to_check = 100; - } - } -} +// void cb_probe(s32 sync_result) { +// if (sync_result < -9) { +// // changed card. We have the card, but we don't know anything about it. +// mc[p1].state = MemoryCardState::KNOWN; +// mc[p1].countdown_to_check = 100; +// mc_print("probe: bad sync, trying again in a bit"); +// } else { +// // there is a memory card. +// if (p2 == sceMcTypePS2) { +// // it is the right type. +// // create a new handle +// mc[p1].handle = new_mc_handle(); +// if (p4 == 0) { +// mc_print("probe: got a card, but it's not formatted"); +// // it's not formatted. But open (we have a handle) +// mc[p1].state = MemoryCardState::OPEN_BUT_UNFORMATTED; +// mc[p1].countdown_to_check = 100; +// } else { +// mc_print("probe: got a formatted card, trying getdir"); +// // it's formatted. Get the size +// mc[p1].mem_size = p3; +// p2 = 0; +// +// // and get our jak and daxter directory +// if (sceMcGetDir(p1, 0, filename[0], 0, 1, &dirent) == sceMcResSucceed) { +// callback = cb_getdir; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +// } +// +// } else { +// mc_print("probe: bad card type, trying again in a bit"); +// mc[p1].state = MemoryCardState::KNOWN; +// mc[p1].countdown_to_check = 100; +// } +// } +//} /*! * Callback for sceMcGetDir. This runs again and again to check all files */ -void cb_getdir(s32 sync_result) { - // called after sceMcGetDir - if (sync_result == 0) { - // didn't find the jak and daxter dir, or some stuff is missing. - // call this uninitialized. - mc[p1].inited = false; - mc[p1].state = MemoryCardState::FORMATTED; - mc[p1].countdown_to_check = 100; - mc[p1].last_file = -1; - } else if (sync_result == 1) { - // found whatever we were looking for - p2++; - if (p2 == 12) { - // all done checking for files. - mc[p1].inited = true; - mc[p1].countdown_to_check = 100; - mc[p1].last_file = -1; - for (int i = 0; i < 4; i++) { - mc[p1].files[i].present = 0; - } - - // now open file 4, which is the first bank. - p2 = 4; - mc_print("opening first bank..."); - if (sceMcOpen(p1, 0, filename[4], 1) == sceMcResSucceed) { - callback = cb_check_open; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - } - } else { - // still checking files, check the next one. - mc_print("checking {}", filename[p2]); - if (sceMcGetDir(p1, 0, filename[p2], 0, 1, &dirent) == sceMcResSucceed) { - callback = cb_getdir; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - } - } - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - } -} +// void cb_getdir(s32 sync_result) { +// // called after sceMcGetDir +// if (sync_result == 0) { +// // didn't find the jak and daxter dir, or some stuff is missing. +// // call this uninitialized. +// mc[p1].inited = false; +// mc[p1].state = MemoryCardState::FORMATTED; +// mc[p1].countdown_to_check = 100; +// mc[p1].last_file = -1; +// } else if (sync_result == 1) { +// // found whatever we were looking for +// p2++; +// if (p2 == 12) { +// // all done checking for files. +// mc[p1].inited = true; +// mc[p1].countdown_to_check = 100; +// mc[p1].last_file = -1; +// for (int i = 0; i < 4; i++) { +// mc[p1].files[i].present = 0; +// } +// +// // now open file 4, which is the first bank. +// p2 = 4; +// mc_print("opening first bank..."); +// if (sceMcOpen(p1, 0, filename[4], 1) == sceMcResSucceed) { +// callback = cb_check_open; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +// } else { +// // still checking files, check the next one. +// mc_print("checking {}", filename[p2]); +// if (sceMcGetDir(p1, 0, filename[p2], 0, 1, &dirent) == sceMcResSucceed) { +// callback = cb_getdir; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +// } +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +//} /*! * Callback for sceMcOpen for opening bank files. */ -void cb_check_open(s32 sync_result) { - if (!cb_pcheck(sync_result)) { - p3 = sync_result; - // read the header. - mc_print("read header"); - if (sceMcRead(sync_result, &header, sizeof(McHeader)) == sceMcResSucceed) { - callback = cb_check_read; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - } - } -} +// void cb_check_open(s32 sync_result) { +// if (!cb_pcheck(sync_result)) { +// p3 = sync_result; +// // read the header. +// mc_print("read header"); +// if (sceMcRead(sync_result, &header, sizeof(McHeader)) == sceMcResSucceed) { +// callback = cb_check_read; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +// } +//} /*! * Callback for sceMcRead for reading the header of a bank file. */ -void cb_check_read(s32 sync_result) { - if (!cb_pcheck(sync_result)) { - if (header.save_count != 0 && // we've saved into this bank - header.magic == MEM_CARD_MAGIC // looks valid - ) { - // each file has two banks. so if you corrupt a save, you hopefully have the other bank. - // get the file that goes with this bank - s32 file_idx = (p2 - 4) / 2; - if (mc[p1].files[file_idx].present == 0 || // haven't found any banks for this file - header.save_count > mc[p1].files[file_idx].most_recent_save_count // newer than prev. - ) { - // this is so far our best guess at the right bank to use. - mc[p1].files[file_idx].present = 1; - mc[p1].files[file_idx].most_recent_save_count = header.save_count; - mc[p1].files[file_idx].last_saved_bank = p2 & 1; - // copy header data (for GOAL to read) - for (int i = 0; i < 64; i++) { - mc[p1].files[file_idx].data[i] = header.preview_data[i]; - } - } - } - - if (sceMcClose(p3) == sceMcResSucceed) { - // close the file - callback = cb_check_close; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - } - } -} +// void cb_check_read(s32 sync_result) { +// if (!cb_pcheck(sync_result)) { +// if (header.save_count != 0 && // we've saved into this bank +// header.magic == MEM_CARD_MAGIC // looks valid +// ) { +// // each file has two banks. so if you corrupt a save, you hopefully have the other bank. +// // get the file that goes with this bank +// s32 file_idx = (p2 - 4) / 2; +// if (mc_files[file_idx].present == 0 || // haven't found any banks for this file +// header.save_count > mc_files[file_idx].most_recent_save_count // newer than prev. +// ) { +// // this is so far our best guess at the right bank to use. +// mc_files[file_idx].present = 1; +// mc_files[file_idx].most_recent_save_count = header.save_count; +// mc_files[file_idx].last_saved_bank = p2 & 1; +// // copy header data (for GOAL to read) +// for (int i = 0; i < 64; i++) { +// mc_files[file_idx].data[i] = header.preview_data[i]; +// } +// } +// } +// +// if (sceMcClose(p3) == sceMcResSucceed) { +// // close the file +// callback = cb_check_close; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +// } +//} /*! * Callback for closing a file after reading the header */ -void cb_check_close(s32 sync_result) { - if (!cb_pcheck(sync_result)) { - // next bank. - p2++; - if (p2 == 12) { - // done with banks - mc[p1].state = MemoryCardState::FORMATTED; - // and we're done! - } else { - // on to the next bank... - if (sceMcOpen(p1, 0, filename[p2], 1) == sceMcResSucceed) { - callback = cb_check_open; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - } - } - } -} +// void cb_check_close(s32 sync_result) { +// if (!cb_pcheck(sync_result)) { +// // next bank. +// p2++; +// if (p2 == 12) { +// // done with banks +// mc[p1].state = MemoryCardState::FORMATTED; +// // and we're done! +// } else { +// // on to the next bank... +// if (sceMcOpen(p1, 0, filename[p2], 1) == sceMcResSucceed) { +// callback = cb_check_open; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +// } +// } +//} /*! * Callback for checking on a known memory card. If it is swapped, will reset. */ -void cb_reprobe(s32 sync_result) { - if (sync_result == sceMcResSucceed) { - // nobody took out the memory card. try again in 100 frames - mc[p1].countdown_to_check = 100; - } else { - // somebody took it out. reset everything! - mc[p1].state = MemoryCardState::UNKNOWN; - } -} +// void cb_reprobe(s32 sync_result) { +// if (sync_result == sceMcResSucceed) { +// // nobody took out the memory card. try again in 100 frames +// mc[p1].countdown_to_check = 100; +// } else { +// // somebody took it out. reset everything! +// mc[p1].state = MemoryCardState::UNKNOWN; +// } +//} /*! * Callback for probe before formatting. */ -void cb_reprobe_format(s32 sync_result) { - if (sync_result == sceMcResSucceed) { - // get info succeeded. we can format. - s32 format_result = sceMcFormat(p1, 0); - if (format_result == sceMcResSucceed) { - callback = cb_format_complete; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - // get info failed. Revert the state to unknown, this will restart everything. - mc[p1].state = MemoryCardState::UNKNOWN; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; - } -} +// void cb_reprobe_format(s32 sync_result) { +// if (sync_result == sceMcResSucceed) { +// // get info succeeded. we can format. +// s32 format_result = sceMcFormat(p1, 0); +// if (format_result == sceMcResSucceed) { +// callback = cb_format_complete; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// // get info failed. Revert the state to unknown, this will restart everything. +// mc[p1].state = MemoryCardState::UNKNOWN; +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::BAD_HANDLE; +// } +//} /*! * Callback for actual formatting operation */ -void cb_format_complete(s32 sync_result) { - if (sync_result == sceMcResSucceed) { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::OK; - mc[p1].state = MemoryCardState::FORMATTED; - mc[p1].countdown_to_check = 100; - mc[p1].inited = 0; - for (int i = 0; i < 4; i++) { - mc[p1].files[i].present = 0; - } - mc[p1].last_file = -1; - mc[p1].mem_size = 8000; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::FORMAT_FAILED; - } -} +// void cb_format_complete(s32 sync_result) { +// if (sync_result == sceMcResSucceed) { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::OK; +// mc[p1].state = MemoryCardState::FORMATTED; +// mc[p1].countdown_to_check = 100; +// mc[p1].inited = 0; +// for (int i = 0; i < 4; i++) { +// mc[p1].files[i].present = 0; +// } +// mc[p1].last_file = -1; +// mc[p1].mem_size = 8000; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::FORMAT_FAILED; +// } +//} /*! * Callback for actual unformatting operation */ -void cb_unformat(s32 sync_result) { - if (sync_result == sceMcResSucceed) { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::OK; - mc[p1].state = MemoryCardState::UNKNOWN; - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::FORMAT_FAILED; - } -} +// void cb_unformat(s32 sync_result) { +// if (sync_result == sceMcResSucceed) { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::OK; +// mc[p1].state = MemoryCardState::UNKNOWN; +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::FORMAT_FAILED; +// } +//} /*! * Callback for probe before creating save files. */ -void cb_reprobe_createfile(s32 sync_result) { - if (sync_result == sceMcResSucceed) { - // if the ramdisk is ready, just jump directly to its callback - if (!RpcBusy(RAMDISK_RPC_CHANNEL)) { - cb_wait_for_ramdisk(0); - } else { - // I think this is a typo and should be cb_reprobe_createfile again. - callback = cb_wait_for_ramdisk; - } - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; - } -} +// void cb_reprobe_createfile(s32 sync_result) { +// if (sync_result == sceMcResSucceed) { +// // if the ramdisk is ready, just jump directly to its callback +// if (!RpcBusy(RAMDISK_RPC_CHANNEL)) { +// cb_wait_for_ramdisk(0); +// } else { +// // I think this is a typo and should be cb_reprobe_createfile again. +// callback = cb_wait_for_ramdisk; +// } +// } else { +// mc[p1].state = MemoryCardState::UNKNOWN; +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::BAD_HANDLE; +// } +//} /*! * Actually start the ramdisk load of the icon file to temp buffer */ -void cb_wait_for_ramdisk(s32) { - ramdisk_cmd.pad = 0; - // caller should have given us a temporary buffer. - ramdisk_cmd.file_id_or_ee_addr = op.data_ptr.offset; - ramdisk_cmd.offset_into_file = 0; - ramdisk_cmd.size = 0x1e800; - memcpy(ramdisk_cmd.name, "SAVEGAME.ICO", 13); // was 16. - RpcCall(RAMDISK_RPC_CHANNEL, RAMDISK_BYPASS_LOAD_FILE, 1, &ramdisk_cmd, 0x20, nullptr, 0); - callback = cb_wait_for_ramdisk_load; -} +// void cb_wait_for_ramdisk(s32) { +// ramdisk_cmd.pad = 0; +// // caller should have given us a temporary buffer. +// ramdisk_cmd.file_id_or_ee_addr = op.data_ptr.offset; +// ramdisk_cmd.offset_into_file = 0; +// ramdisk_cmd.size = 0x1e800; +// memcpy(ramdisk_cmd.name, "SAVEGAME.ICO", 13); // was 16. +// RpcCall(RAMDISK_RPC_CHANNEL, RAMDISK_BYPASS_LOAD_FILE, 1, &ramdisk_cmd, 0x20, nullptr, 0); +// callback = cb_wait_for_ramdisk_load; +//} /*! * Callback for checking if the ramdisk load is done */ -void cb_wait_for_ramdisk_load(s32) { - if (RpcBusy(RAMDISK_RPC_CHANNEL) == 0) { - // ramdisk is done. start deleting 12 files - p2 = 11; // filenames left to delete - mc_print("start delete {}", filename[11]); - if (sceMcDelete(p1, 0, filename[11]) == sceMcResSucceed) { - callback = cb_createfile_erasing; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - // still waiting... - callback = cb_wait_for_ramdisk_load; - } -} +// void cb_wait_for_ramdisk_load(s32) { +// if (RpcBusy(RAMDISK_RPC_CHANNEL) == 0) { +// // ramdisk is done. start deleting 12 files +// p2 = 11; // filenames left to delete +// mc_print("start delete {}", filename[11]); +// if (sceMcDelete(p1, 0, filename[11]) == sceMcResSucceed) { +// callback = cb_createfile_erasing; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// // still waiting... +// callback = cb_wait_for_ramdisk_load; +// } +//} /*! * Callback to start erasing previous save files. */ -void cb_createfile_erasing(s32 sync_result) { - if (sync_result == sceMcResSucceed || sync_result == sceMcResNoEntry || - sync_result == sceMcResNotEmpty) { - mc[p1].inited = 0; - // delete didn't fail. - if (p2 < 1) { - // on the last one. move on on to creating the directory again. - mc_print("create dir {}", filename[0]); - if (sceMcMkdir(p1, 0, filename[0]) == sceMcResSucceed) { - callback = cb_createdir; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - p2--; - mc_print("delete next {}", filename[p2]); - if (sceMcDelete(p1, 0, filename[p2]) == sceMcResSucceed) { - callback = cb_createfile_erasing; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } - } else { - if (sync_result == sceMcResDeniedPermit) { - mc_print("erasing: denied"); - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } else { - mc_print("erasing: other bad"); - mc[p1].state = MemoryCardState::UNKNOWN; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; - } - } -} +// void cb_createfile_erasing(s32 sync_result) { +// if (sync_result == sceMcResSucceed || sync_result == sceMcResNoEntry || +// sync_result == sceMcResNotEmpty) { +// mc[p1].inited = 0; +// // delete didn't fail. +// if (p2 < 1) { +// // on the last one. move on on to creating the directory again. +// mc_print("create dir {}", filename[0]); +// if (sceMcMkdir(p1, 0, filename[0]) == sceMcResSucceed) { +// callback = cb_createdir; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// p2--; +// mc_print("delete next {}", filename[p2]); +// if (sceMcDelete(p1, 0, filename[p2]) == sceMcResSucceed) { +// callback = cb_createfile_erasing; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +// } else { +// if (sync_result == sceMcResDeniedPermit) { +// mc_print("erasing: denied"); +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } else { +// mc_print("erasing: other bad"); +// mc[p1].state = MemoryCardState::UNKNOWN; +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::BAD_HANDLE; +// } +// } +//} /*! * Callback after creating directory for jak save data */ -void cb_createdir(s32 sync_result) { - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - // this sets up some stuff for the icon file that we will ignore. - // memset(&iconsys,0,0x3c4); - // kstrcpy(&iconsys,&DAT_00137000); - // if (language == Language::Japanese) { - // kstrcpy(&DAT_00137560,titles[5]); - // } else { - // // non japanese need to convert to shift-JIS format. - // ASCII2SJIS(&DAT_00137560,titles[language]); - // } - // DAT_001374a6 = 0x20; - // DAT_001374ac = 0; - // memcpy(&DAT_001374b0,bgcolor.610,0x40); - // memcpy(&DAT_001374f0,lightdir.611,0x30); - // memcpy(&DAT_00137520,lightcol.612,0x30); - // memcpy(&DAT_00137550,ambient.613,0x10); - // kstrcpy(&DAT_001375a4,"icon.ico"); - // kstrcpy(&DAT_001375e4,"icon.ico"); - // kstrcpy(&DAT_00137624,"icon.ico"); - - p2 = 1; - // move on to creating files - mc_print("starting create file at {}", filename[p2]); - if (sceMcOpen(p1, 0, filename[1], 0x203) == 0) { - callback = cb_createdfile; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} +// void cb_createdir(s32 sync_result) { +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// // this sets up some stuff for the icon file that we will ignore. +// // memset(&iconsys,0,0x3c4); +// // kstrcpy(&iconsys,&DAT_00137000); +// // if (language == Language::Japanese) { +// // kstrcpy(&DAT_00137560,titles[5]); +// // } else { +// // // non japanese need to convert to shift-JIS format. +// // ASCII2SJIS(&DAT_00137560,titles[language]); +// // } +// // DAT_001374a6 = 0x20; +// // DAT_001374ac = 0; +// // memcpy(&DAT_001374b0,bgcolor.610,0x40); +// // memcpy(&DAT_001374f0,lightdir.611,0x30); +// // memcpy(&DAT_00137520,lightcol.612,0x30); +// // memcpy(&DAT_00137550,ambient.613,0x10); +// // kstrcpy(&DAT_001375a4,"icon.ico"); +// // kstrcpy(&DAT_001375e4,"icon.ico"); +// // kstrcpy(&DAT_00137624,"icon.ico"); +// +// p2 = 1; +// // move on to creating files +// mc_print("starting create file at {}", filename[p2]); +// if (sceMcOpen(p1, 0, filename[1], 0x203) == 0) { +// callback = cb_createdfile; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} /*! * Callback after creating the file. */ -void cb_createdfile(s32 sync_result) { - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - mc_print("create file cb {}", filename[p2]); - if (p2 == 1) { - p3 = sync_result; // the fd of the icon file. - // actually would write the icon sys file. - if (sceMcWrite(sync_result, nullptr, 0) == sceMcResSucceed) { - callback = cb_writtenfile; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else if (p2 == 2) { - p3 = sync_result; - // would write the icon data (ramdisk loaded into the temp buffer) - if (sceMcWrite(sync_result, nullptr, 0) == sceMcResSucceed) { - callback = cb_writtenfile; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else if (p2 == 3) { - // writes the aybabtu meme file - p3 = sync_result; - kstrcpy(op.data_ptr.cast().c(), "Nope, the save game data isn\'t in this file!\n"); - if (sceMcWrite(p3, op.data_ptr.c(), strlen((const char*)op.data_ptr.c())) == - sceMcResSucceed) { - callback = cb_writtenfile; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - // writes the actual bank files. - p3 = sync_result; - memset(op.data_ptr.c(), 0, 0x11800); - if (sceMcWrite(p3, op.data_ptr.c(), 0x11800) == sceMcResSucceed) { - callback = cb_writtenfile; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } - } -} +// void cb_createdfile(s32 sync_result) { +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// mc_print("create file cb {}", filename[p2]); +// if (p2 == 1) { +// p3 = sync_result; // the fd of the icon file. +// // actually would write the icon sys file. +// if (sceMcWrite(sync_result, nullptr, 0) == sceMcResSucceed) { +// callback = cb_writtenfile; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else if (p2 == 2) { +// p3 = sync_result; +// // would write the icon data (ramdisk loaded into the temp buffer) +// if (sceMcWrite(sync_result, nullptr, 0) == sceMcResSucceed) { +// callback = cb_writtenfile; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else if (p2 == 3) { +// // writes the aybabtu meme file +// p3 = sync_result; +// kstrcpy(op.data_ptr.cast().c(), "Nope, the save game data isn\'t in this file!\n"); +// if (sceMcWrite(p3, op.data_ptr.c(), strlen((const char*)op.data_ptr.c())) == +// sceMcResSucceed) { +// callback = cb_writtenfile; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// // writes the actual bank files. +// p3 = sync_result; +// memset(op.data_ptr.c(), 0, 0x11800); +// if (sceMcWrite(p3, op.data_ptr.c(), 0x11800) == sceMcResSucceed) { +// callback = cb_writtenfile; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +// } +//} /*! * Callback after writing data to files. */ -void cb_writtenfile(s32 sync_result) { - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - if (sceMcClose(p3) == sceMcResSucceed) { - callback = cb_closedfile; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} +// void cb_writtenfile(s32 sync_result) { +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// if (sceMcClose(p3) == sceMcResSucceed) { +// callback = cb_closedfile; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} /*! * Callback after closing the file. */ -void cb_closedfile(s32 sync_result) { - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - p2++; - if (p2 < 0xc) { - // open the next one - if (sceMcOpen(p1, 0, filename[p2], 0x203) == sceMcResSucceed) { - callback = cb_createdfile; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - // done! - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::OK; - - // save data is inited - mc[p1].inited = 1; - // but no files have anything in it. - for (int i = 0; i < 4; i++) { - mc[p1].files[i].present = 0; - } - mc[p1].last_file = -1; - } - } -} +// void cb_closedfile(s32 sync_result) { +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// p2++; +// if (p2 < 12) { +// // open the next one +// if (sceMcOpen(p1, 0, filename[p2], 0x203) == sceMcResSucceed) { +// callback = cb_createdfile; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// // done! +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::OK; +// +// // save data is inited +// mc[p1].inited = 1; +// // but no files have anything in it. +// for (int i = 0; i < 4; i++) { +// mc[p1].files[i].present = 0; +// } +// mc[p1].last_file = -1; +// } +// } +//} /*! * Callback after check before saving. */ -void cb_reprobe_save(s32 sync_result) { - if (sync_result == sceMcResSucceed) { - if (!mc[p1].files[op.param2].present) { - mc_print("reprobe save: first time!"); - // first time saving! - p2 = 0; // save count 0 - p4 = 0; // first bank for file - } else { - p2 = mc[p1].files[op.param2].most_recent_save_count + 1; // increment save count - p4 = mc[p1].files[op.param2].last_saved_bank ^ 1; // use the other bank - } - - // reserve 0 as "I never saved" and use 1 instead. - if (p2 == 0) { - p2 = 1; - } - - // file*2 + p4 is the bank (2 banks per file, p4 is 0 or 1 to select the bank) - // 4 is the first bank file - mc_print("open {} for saving", filename[op.param2 * 2 + 4 + p4]); - if (sceMcOpen(p1, 0, filename[op.param2 * 2 + 4 + p4], 2) == sceMcResSucceed) { - callback = cb_openedsave; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; - } -} - -void cb_openedsave(s32 sync_result) { - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - mc_print("save file opened, writing header..."); - p3 = sync_result; - memset(&header, 0, sizeof(McHeader)); - header.save_count = p2; - header.checksum = mc_checksum(op.data_ptr, BANK_SIZE); - header.magic = MEM_CARD_MAGIC; - header.unk1_repeated = p2; - for (int i = 0; i < 64; i++) { - header.preview_data[i] = op.data_ptr2.c()[i]; - } - if (sceMcWrite(p3, &header, sizeof(McHeader)) == sceMcResSucceed) { - callback = cb_savedheader; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} - -void cb_savedheader(s32 sync_result) { - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - mc_print("save file writing main data"); - if (sceMcWrite(p3, op.data_ptr.c(), BANK_SIZE) == sceMcResSucceed) { - callback = cb_saveddata; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} - -void cb_saveddata(s32 sync_result) { - mc_print("save file writing footer"); - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - if (sceMcWrite(p3, &header, sizeof(McHeader)) == sceMcResSucceed) { - callback = cb_savedfooter; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} - -void cb_savedfooter(s32 sync_result) { - mc_print("closing after save"); - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - if (sceMcClose(p3) == sceMcResSucceed) { - callback = cb_closedsave; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} - -void cb_closedsave(s32 sync_result) { - if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { - mc_print("All done with saving!!"); - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::OK; - mc[p1].files[op.param2].present = 1; - mc[p1].files[op.param2].most_recent_save_count = p2; - mc[p1].files[op.param2].last_saved_bank = p4; - for (int i = 0; i < 64; i++) { - mc[p1].files[op.param2].data[i] = op.data_ptr2.c()[i]; - } - mc[p1].last_file = op.param2; - flush_memory_card_to_file(); - } -} - -void cb_reprobe_load(s32 sync_result) { - if (sync_result == 0) { - p2 = 0; - mc_print("opening save file {}", filename[op.param2 * 2 + 4]); - if (sceMcOpen(p1, 0, filename[op.param2 * 2 + 4], 1) == sceMcResSucceed) { - callback = cb_openedload; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - mc[p1].state = MemoryCardState::UNKNOWN; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::BAD_HANDLE; - } -} - -void cb_openedload(s32 sync_result) { - if (cb_check(sync_result, McStatusCode::READ_ERROR) == 0) { - p3 = sync_result; - size_t read_size = (BANK_SIZE + 2 * sizeof(McHeader)); - mc_print("reading save file..."); - if (sceMcRead(sync_result, op.data_ptr.c() + p2 * read_size, read_size) == sceMcResSucceed) { - callback = cb_readload; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} - -void cb_readload(s32 sync_result) { - if (cb_check(sync_result, McStatusCode::READ_ERROR) == 0) { - mc_print("closing save file.."); - if (sceMcClose(p3) == sceMcResSucceed) { - callback = cb_closedload; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } -} - -void cb_closedload(s32 sync_result) { - if (cb_check(sync_result, McStatusCode::READ_ERROR) == 0) { - p2++; - if (p2 < 2) { - mc_print("reading next save bank {}", filename[op.param2 * 2 + 4 + p2]); - if (sceMcOpen(p1, 0, filename[op.param2 * 2 + 4 + p2], 1) == sceMcResSucceed) { - callback = cb_openedload; - } else { - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::INTERNAL_ERROR; - } - } else { - // let's verify the data. - McHeader* headers[2]; - McHeader* footers[2]; - bool ok[2]; - - headers[0] = (McHeader*)(op.data_ptr.c()); - footers[0] = (McHeader*)(op.data_ptr.c() + sizeof(McHeader) + BANK_SIZE); - headers[1] = (McHeader*)(op.data_ptr.c() + sizeof(McHeader) * 2 + BANK_SIZE); - footers[1] = (McHeader*)(op.data_ptr.c() + sizeof(McHeader) * 3 + BANK_SIZE * 2); - static_assert(sizeof(McHeader) * 3 + BANK_SIZE * 2 == 0x20c00, "save layout"); - ok[0] = true; - ok[1] = true; - - for (int idx = 0; idx < 2; idx++) { - u32 expected_save_count = headers[idx]->save_count; - if (headers[idx]->unk1_repeated == expected_save_count && - footers[idx]->save_count == expected_save_count && - footers[idx]->unk1_repeated == expected_save_count) { - // save count is okay! - if (headers[idx]->magic == MEM_CARD_MAGIC && footers[idx]->magic == MEM_CARD_MAGIC) { - // magic numbers okay! - if (headers[idx]->checksum == footers[idx]->checksum) { - // checksum - auto expected_checksum = headers[idx]->checksum; - if (mc_checksum(make_u8_ptr(headers[idx] + 1), BANK_SIZE) != expected_checksum) { - mc_print("failed checksum"); - ok[idx] = false; - } - } else { - mc_print("corrupted checksum"); - ok[idx] = false; - } - } else { - mc_print("bad magic"); - ok[idx] = false; - } - } else { - mc_print("bad save count"); - ok[idx] = false; - } - } - - mc_print("checking loaded banks"); - - // - if (!ok[0] && !ok[1]) { - // no good data. - if (headers[0]->save_count == 0 && headers[0]->checksum == 0 && headers[0]->magic == 0 && - headers[0]->unk1_repeated == 0 && headers[1]->save_count == 0 && - headers[1]->checksum == 0 && headers[1]->magic == 0 && headers[1]->unk1_repeated == 0) { - // this is a fresh file that you tried to load from... - mc_print("new game result"); - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::NEW_GAME; - mc[p1].last_file = op.param2; - } else { - mc_print("corrupted data"); - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::READ_ERROR; - } - } else { - // pick the bank - int bank = 0; - - if (!ok[0] || !ok[1]) { - if (ok[1]) { - bank = 1; - } - } else { - bank = (headers[0]->save_count - headers[1]->save_count) < 1; - } - - u32 current_save_count = headers[bank]->save_count; - memcpy(op.data_ptr.c(), op.data_ptr.c() + sizeof(McHeader), BANK_SIZE); - mc[p1].last_file = op.param2; - mc[p1].files[op.param2].most_recent_save_count = current_save_count; - mc[p1].files[op.param2].last_saved_bank = bank; - op.operation = MemoryCardOperationKind::NO_OP; - op.result = McStatusCode::OK; - mc_print("load succeeded"); - } - } - } -} \ No newline at end of file +// void cb_reprobe_save(s32 sync_result) { +// if (sync_result == sceMcResSucceed) { +// if (!mc[p1].files[op.param2].present) { +// mc_print("reprobe save: first time!"); +// // first time saving! +// p2 = 0; // save count 0 +// p4 = 0; // first bank for file +// } else { +// p2 = mc_files[op.param2].most_recent_save_count + 1; // increment save count +// p4 = mc_files[op.param2].last_saved_bank ^ 1; // use the other bank +// } +// +// // reserve 0 as "I never saved" and use 1 instead. +// if (p2 == 0) { +// p2 = 1; +// } +// +// // file*2 + p4 is the bank (2 banks per file, p4 is 0 or 1 to select the bank) +// // 4 is the first bank file +// mc_print("open {} for saving", filename[op.param2 * 2 + 4 + p4]); +// if (sceMcOpen(p1, 0, filename[op.param2 * 2 + 4 + p4], 2) == sceMcResSucceed) { +// callback = cb_openedsave; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// // mc[p1].state = MemoryCardState::UNKNOWN; +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::BAD_HANDLE; +// } +//} +// +// void cb_openedsave(s32 sync_result) { +// mc_print("save file opened, writing header..."); +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// p3 = sync_result; +// memset(&header, 0, sizeof(McHeader)); +// header.save_count = p2; +// header.checksum = mc_checksum(op.data_ptr, BANK_SIZE); +// header.magic = MEM_CARD_MAGIC; +// header.unk1_repeated = p2; +// for (int i = 0; i < 64; i++) { +// header.preview_data[i] = op.data_ptr2.c()[i]; +// } +// if (sceMcWrite(p3, &header, sizeof(McHeader)) == sceMcResSucceed) { +// callback = cb_savedheader; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} +// +// void cb_savedheader(s32 sync_result) { +// mc_print("save file writing main data"); +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// if (sceMcWrite(p3, op.data_ptr.c(), BANK_SIZE) == sceMcResSucceed) { +// callback = cb_saveddata; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} +// +// void cb_saveddata(s32 sync_result) { +// mc_print("save file writing footer"); +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// if (sceMcWrite(p3, &header, sizeof(McHeader)) == sceMcResSucceed) { +// callback = cb_savedfooter; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} +// +// void cb_savedfooter(s32 sync_result) { +// mc_print("closing after save"); +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// if (sceMcClose(p3) == sceMcResSucceed) { +// callback = cb_closedsave; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} +// +// void cb_closedsave(s32 sync_result) { +// if (!cb_check(sync_result, McStatusCode::WRITE_ERROR)) { +// mc_print("All done with saving!!"); +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::OK; +// // mc_files[op.param2].present = 1; +// mc_files[op.param2].most_recent_save_count = p2; +// mc_files[op.param2].last_saved_bank = p4; +// for (int i = 0; i < 64; i++) { +// mc_files[op.param2].data[i] = op.data_ptr2.c()[i]; +// } +// mc_last_file = op.param2; +// flush_memory_card_to_file(); +// } +//} +// +// void cb_reprobe_load(s32 sync_result) { +// if (sync_result == 0) { +// p2 = 0; +// mc_print("opening save file {}", filename[op.param2 * 2 + 4]); +// if (sceMcOpen(p1, 0, filename[op.param2 * 2 + 4], 1) == sceMcResSucceed) { +// callback = cb_openedload; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// // mc[p1].state = MemoryCardState::UNKNOWN; +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::BAD_HANDLE; +// } +//} +// +// void cb_openedload(s32 sync_result) { +// if (cb_check(sync_result, McStatusCode::READ_ERROR) == 0) { +// p3 = sync_result; +// size_t read_size = BANK_TOTAL_SIZE; +// mc_print("reading save file..."); +// if (sceMcRead(sync_result, op.data_ptr.c() + p2 * read_size, read_size) == sceMcResSucceed) { +// callback = cb_readload; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} +// +// void cb_readload(s32 sync_result) { +// if (cb_check(sync_result, McStatusCode::READ_ERROR) == 0) { +// mc_print("closing save file.."); +// if (sceMcClose(p3) == sceMcResSucceed) { +// callback = cb_closedload; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } +//} +// +// void cb_closedload(s32 sync_result) { +// if (cb_check(sync_result, McStatusCode::READ_ERROR) == 0) { +// p2++; +// if (p2 < 2) { +// mc_print("reading next save bank {}", filename[op.param2 * 2 + 4 + p2]); +// if (sceMcOpen(p1, 0, filename[op.param2 * 2 + 4 + p2], 1) == sceMcResSucceed) { +// callback = cb_openedload; +// } else { +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::INTERNAL_ERROR; +// } +// } else { +// // let's verify the data. +// McHeader* headers[2]; +// McHeader* footers[2]; +// bool ok[2]; +// +// headers[0] = (McHeader*)(op.data_ptr.c()); +// footers[0] = (McHeader*)(op.data_ptr.c() + sizeof(McHeader) + BANK_SIZE); +// headers[1] = (McHeader*)(op.data_ptr.c() + BANK_TOTAL_SIZE); +// footers[1] = (McHeader*)(op.data_ptr.c() + BANK_TOTAL_SIZE + sizeof(McHeader) + BANK_SIZE); +// static_assert(BANK_TOTAL_SIZE * 2 == 0x21000, "save layout"); +// ok[0] = true; +// ok[1] = true; +// +// for (int idx = 0; idx < 2; idx++) { +// u32 expected_save_count = headers[idx]->save_count; +// if (headers[idx]->unk1_repeated == expected_save_count && +// footers[idx]->save_count == expected_save_count && +// footers[idx]->unk1_repeated == expected_save_count) { +// // save count is okay! +// if (headers[idx]->magic == MEM_CARD_MAGIC && footers[idx]->magic == MEM_CARD_MAGIC) { +// // magic numbers okay! +// if (headers[idx]->checksum == footers[idx]->checksum) { +// // checksum +// auto expected_checksum = headers[idx]->checksum; +// if (mc_checksum(make_u8_ptr(headers[idx] + 1), BANK_SIZE) != expected_checksum) { +// mc_print("failed checksum"); +// ok[idx] = false; +// } +// } else { +// mc_print("corrupted checksum"); +// ok[idx] = false; +// } +// } else { +// mc_print("bad magic"); +// ok[idx] = false; +// } +// } else { +// mc_print("bad save count"); +// ok[idx] = false; +// } +// } +// +// mc_print("checking loaded banks"); +// +// // +// if (!ok[0] && !ok[1]) { +// // no good data. +// if (headers[0]->save_count == 0 && headers[0]->checksum == 0 && headers[0]->magic == 0 && +// headers[0]->unk1_repeated == 0 && headers[1]->save_count == 0 && +// headers[1]->checksum == 0 && headers[1]->magic == 0 && headers[1]->unk1_repeated == 0) +// { +// // this is a fresh file that you tried to load from... +// mc_print("new game result"); +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::NEW_GAME; +// mc_last_file = op.param2; +// } else { +// mc_print("corrupted data"); +// op.operation = MemoryCardOperationKind::NO_OP; +// op.result = McStatusCode::READ_ERROR; +// } +// } else { +// // pick the bank +// int bank = 0; +// +// if (!ok[0] || !ok[1]) { +// if (ok[1]) { +// bank = 1; +// } +// } else { +// bank = headers[0]->save_count <= headers[1]->save_count; +// } +// +// u32 current_save_count = headers[bank]->save_count; +// memcpy(op.data_ptr.c(), op.data_ptr.c() + bank * BANK_TOTAL_SIZE + sizeof(McHeader), +// BANK_SIZE); mc_last_file = op.param2; mc_files[op.param2].most_recent_save_count = +// current_save_count; mc_files[op.param2].last_saved_bank = bank; op.operation = +// MemoryCardOperationKind::NO_OP; op.result = McStatusCode::OK; mc_print("load succeeded"); +// } +// } +// } +//} diff --git a/game/kernel/kmemcard.h b/game/kernel/kmemcard.h index 70349b2256..78bd54b10f 100644 --- a/game/kernel/kmemcard.h +++ b/game/kernel/kmemcard.h @@ -10,7 +10,7 @@ void kmemcard_init_globals(); -constexpr s32 SAVE_SIZE = 0x2b3; // likely different by versions! +constexpr s32 SAVE_SIZE = 691; // likely different by versions! 692 on PAL/JPN constexpr s32 BANK_SIZE = 0x10000; // each card can be in one of these states: @@ -144,4 +144,4 @@ u64 MC_save(s32 card_idx, s32 file_idx, Ptr save_data, Ptr save_summary_ 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(); \ No newline at end of file +u32 MC_check_result(); diff --git a/game/sce/sif_ee_memcard.cpp b/game/sce/sif_ee_memcard.cpp index 1c6a822c8b..8f4fdee63b 100644 --- a/game/sce/sif_ee_memcard.cpp +++ b/game/sce/sif_ee_memcard.cpp @@ -133,7 +133,7 @@ s32 sceMcOpen(s32 port, s32 slot, const char* name, s32 mode) { g_mc_state.handles[fd] = handle; g_mc_state.current_function_result = fd; - return 0; + return sceMcResSucceed; } s32 sceMcWrite(s32 fd, const void* buff, s32 size) { @@ -303,4 +303,4 @@ void read_memory_card_from_file() { } } -} // namespace ee \ No newline at end of file +} // namespace ee diff --git a/goal_src/engine/game/collectables-part.gc b/goal_src/engine/game/collectables-part.gc index 9c4d91e93a..d58a812a54 100644 --- a/goal_src/engine/game/collectables-part.gc +++ b/goal_src/engine/game/collectables-part.gc @@ -2179,7 +2179,7 @@ :init-specs ((sp-tex spt-texture (new 'static 'texture-id :index #x2c :page #x2)) (sp-flt spt-num 1.0) - (sp-flt spt-scale-x (meters 1.2)) + (sp-flt spt-scale-x (meters 1.22)) (sp-copy-from-other spt-scale-y -4) (sp-flt spt-r 128.0) (sp-flt spt-g 128.0) @@ -2191,7 +2191,6 @@ ) ) -;; customized (defpartgroup group-money-starburst :id 64 :bounds (static-bspherem 0 0.5 0 1.5) :parts ((sp-item 238))) (defpartgroup group-buzzer-effect diff --git a/goal_src/engine/game/game-save.gc b/goal_src/engine/game/game-save.gc index 90ab41e3e6..11998b6dd5 100644 --- a/goal_src/engine/game/game-save.gc +++ b/goal_src/engine/game/game-save.gc @@ -804,243 +804,209 @@ ;; loop over all tags (let ((data (the-as game-save-tag (-> save tag)))) - (while (< (the-as int data) (the-as int (+ (+ (-> save length) 76) (the-as int save)))) - (let ((v1-7 (-> data elt-type))) - (cond - ((= v1-7 (game-save-elt base-time)) - ;; updating this requires some care to not break things - (let ((old-base-frame (-> *display* base-frame-counter))) - (set! (-> *display* base-frame-counter) (the int (-> data user-uint64))) - ;; remember the old value - (set! (-> *display* old-base-frame-counter) (+ (-> *display* base-frame-counter) -1)) - (let ((frame-counter-diff (- (-> *display* base-frame-counter) old-base-frame))) - - ;; update in-progress counters - (if (nonzero? (-> obj blackout-time)) - (set! (-> obj blackout-time) (+ (-> obj blackout-time) frame-counter-diff)) - ) - (if (nonzero? (-> obj letterbox-time)) - (set! (-> obj letterbox-time) (+ (-> obj letterbox-time) frame-counter-diff)) - ) - (if (nonzero? (-> obj hint-play-time)) - (set! (-> obj hint-play-time) (+ (-> obj hint-play-time) frame-counter-diff)) - ) - (if (nonzero? (-> obj display-text-time)) - (set! (-> obj display-text-time) (+ (-> obj display-text-time) frame-counter-diff)) - ) + (while (< (the-as int data) (the-as int (&-> save tag 0 user-int8 (-> save length)))) + (case (-> data elt-type) + (((game-save-elt base-time)) + (let ((old-base-frame (-> *display* base-frame-counter))) + (set! (-> *display* base-frame-counter) (the-as time-frame (-> data user-uint64))) + (set! (-> *display* old-base-frame-counter) (+ (-> *display* base-frame-counter) -1)) + (let ((frame-counter-diff (- (-> *display* base-frame-counter) old-base-frame))) + (if (nonzero? (-> obj blackout-time)) + (+! (-> obj blackout-time) frame-counter-diff) + ) + (if (nonzero? (-> obj letterbox-time)) + (+! (-> obj letterbox-time) frame-counter-diff) + ) + (if (nonzero? (-> obj hint-play-time)) + (+! (-> obj hint-play-time) frame-counter-diff) + ) + (if (nonzero? (-> obj display-text-time)) + (+! (-> obj display-text-time) frame-counter-diff) + ) + ) + ) + (buzz-stop! 0) + ) + (((game-save-elt game-time)) + (set! (-> *display* game-frame-counter) (the-as time-frame (-> data user-uint64))) + (set! (-> *display* old-game-frame-counter) (+ (-> *display* game-frame-counter) -1)) + ) + (((game-save-elt real-time)) + (set! (-> *display* real-frame-counter) (the-as time-frame (-> data user-uint64))) + (set! (-> *display* old-real-frame-counter) (+ (-> *display* real-frame-counter) -1)) + ) + (((game-save-elt integral-time)) + (set! (-> *display* integral-frame-counter) (the-as time-frame (-> data user-uint64))) + (set! (-> *display* old-integral-frame-counter) (+ (-> *display* integral-frame-counter) -1)) + ) + (((game-save-elt continue)) + (format (clear *temp-string*) "~G" (&+ (the-as pointer data) 16)) + (set-continue! obj *temp-string*) + ) + (((game-save-elt life)) + (set! (-> obj life) (-> data user-float0)) + ) + (((game-save-elt buzzer-total)) + (set! (-> obj buzzer-total) (-> data user-float0)) + ) + (((game-save-elt fuel-cell)) + (set! (-> obj fuel) (-> data user-float0)) + ) + (((game-save-elt death-movie-tick)) + (set! (-> obj death-movie-tick) (the-as int (-> data user-uint64))) + ) + (((game-save-elt money)) + (set! (-> obj money) (-> data user-float0)) + ) + (((game-save-elt money-total)) + (set! (-> obj money-total) (-> data user-float0)) + ) + (((game-save-elt moeny-per-level)) + (let ((v1-34 (min 32 (-> data elt-count)))) + (dotimes (a0-76 v1-34) + (set! (-> obj money-per-level a0-76) (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-76)) + ) + ) + ) + (((game-save-elt level-open-list)) + (let ((v1-38 (min 32 (-> data elt-count)))) + (dotimes (a0-80 v1-38) + (set! (-> obj level-opened a0-80) (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-80)) + ) + ) + ) + (((game-save-elt perm-list)) + (let ((s3-2 (min (-> data elt-count) (-> obj perm-list allocated-length)))) + (set! (-> obj perm-list length) s3-2) + (dotimes (s2-0 s3-2) + (mem-copy! (the-as pointer (-> obj perm-list data s2-0)) (&+ (&+ (the-as pointer data) 16) (* s2-0 16)) 16) + ) + ) + ) + (((game-save-elt task-list)) + (let ((s3-4 (min (-> data elt-count) (-> obj task-perm-list allocated-length)))) + (set! (-> obj task-perm-list length) s3-4) + (dotimes (s2-1 s3-4) + (mem-copy! + (the-as pointer (-> obj task-perm-list data s2-1)) + (&+ (&+ (the-as pointer data) 16) (* s2-1 16)) + 16 ) ) - ;; vibration may get stuck on if we warp back in time, just kill it - (buzz-stop! 0) ) - - ((= v1-7 (game-save-elt game-time)) - (set! (-> *display* game-frame-counter) (the int (-> data user-uint64))) - (set! (-> *display* old-game-frame-counter) (+ (-> *display* game-frame-counter) -1)) - ) - ((= v1-7 (game-save-elt real-time)) - (set! (-> *display* real-frame-counter) (the int (-> data user-uint64))) - (set! (-> *display* old-real-frame-counter) (+ (-> *display* real-frame-counter) -1)) - ) - ((= v1-7 (game-save-elt integral-time)) - (set! (-> *display* integral-frame-counter) (the int (-> data user-uint64))) - (set! (-> *display* old-integral-frame-counter) (+ (-> *display* integral-frame-counter) -1)) - ) - ((= v1-7 (game-save-elt continue)) - (format (clear *temp-string*) "~G" (&+ (the-as pointer data) 16)) - (set-continue! obj *temp-string*) - ) - ((= v1-7 (game-save-elt life)) - (set! (-> obj life) (-> data user-float0)) - ) - ((= v1-7 (game-save-elt buzzer-total)) - (set! (-> obj buzzer-total) (-> data user-float0)) - ) - ((= v1-7 (game-save-elt fuel-cell)) - (set! (-> obj fuel) (-> data user-float0)) - ) - ((= v1-7 (game-save-elt death-movie-tick)) - (set! (-> obj death-movie-tick) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt money)) - (set! (-> obj money) (-> data user-float0)) - ) - ((= v1-7 (game-save-elt money-total)) - (set! (-> obj money-total) (-> data user-float0)) - ) - ((= v1-7 (game-save-elt moeny-per-level)) - (let ((v1-34 (min 32 (-> data elt-count)))) - (dotimes (a0-76 v1-34) - (set! - (-> obj money-per-level a0-76) - (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-76) + ) + (((game-save-elt text-list)) + (let ((v1-61 (/ (logand -8 (+ (-> obj text-ids-seen allocated-length) 7)) 8)) + (a0-94 (-> data elt-count)) + ) + (dotimes (a1-35 v1-61) + (cond + ((>= a1-35 a0-94) + (set! (-> obj text-ids-seen bytes a1-35) (the-as uint 0)) + 0 ) - ) - ) - ) - ((= v1-7 (game-save-elt level-open-list)) - (let ((v1-38 (min 32 (-> data elt-count)))) - (dotimes (a0-80 v1-38) - (set! - (-> obj level-opened a0-80) - (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-80) - ) - ) - ) - ) - ((= v1-7 (game-save-elt perm-list)) - (let ((s3-2 (min (-> data elt-count) (-> obj perm-list allocated-length)))) - (set! (-> obj perm-list length) s3-2) - (dotimes (s2-0 s3-2) - (mem-copy! - (the-as pointer (-> obj perm-list data s2-0)) - (&+ (&+ (the-as pointer data) 16) (* s2-0 16)) - 16 - ) - ) - ) - ) - ((= v1-7 (game-save-elt task-list)) - (let ((s3-4 (min (-> data elt-count) (-> obj task-perm-list allocated-length)))) - (set! (-> obj task-perm-list length) s3-4) - (dotimes (s2-1 s3-4) - (mem-copy! - (the-as pointer (-> obj task-perm-list data s2-1)) - (&+ (&+ (the-as pointer data) 16) (* s2-1 16)) - 16 - ) - ) - ) - ) - ((= v1-7 (game-save-elt text-list)) - (let ((v1-61 (/ (logand -8 (+ (-> obj text-ids-seen allocated-length) 7)) 8)) - (a0-94 (-> data elt-count))) - (dotimes (a1-35 v1-61) - (cond - ((>= a1-35 a0-94) - (set! (-> obj text-ids-seen bytes a1-35) (the-as uint 0)) - 0 - ) - (else - (set! (-> obj text-ids-seen bytes a1-35) - (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a1-35) - ) - ) + (else + (set! (-> obj text-ids-seen bytes a1-35) (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a1-35)) ) ) ) ) - ((= v1-7 (game-save-elt hint-list)) - (cond - ((= (-> obj hint-control length) (-> data elt-count)) - (let ((v1-65 (&+ (the-as pointer data) 16))) - (dotimes (a0-99 (-> data elt-count)) - (set! (-> obj hint-control a0-99 start-time) - (-> (the-as (pointer int64) (&+ v1-65 (* (* a0-99 4) 8)))) - ) - (set! (-> obj hint-control a0-99 last-time-called) - (-> (the-as (pointer int64) (&+ v1-65 (* (+ (* a0-99 4) 1) 8)))) - ) - (set! (-> obj hint-control a0-99 num-attempts) - (-> (the-as (pointer int8) - (&+ (the-as (pointer uint8) v1-65) (+ (* a0-99 32) 16)) - ) - ) - ) - (set! - (-> obj hint-control a0-99 num-success) - (-> (the-as (pointer int8) - (&+ (the-as (pointer uint8) v1-65) (+ (* a0-99 32) 17)) - ) - ) + ) + (((game-save-elt hint-list)) + (cond + ((= (-> obj hint-control length) (-> data elt-count)) + (let ((v1-65 (&+ (the-as pointer data) 16))) + (dotimes (a0-99 (-> data elt-count)) + (set! (-> obj hint-control a0-99 start-time) + (the-as time-frame (-> (the-as (pointer uint64) (&+ v1-65 (* (* a0-99 4) 8))))) + ) + (set! (-> obj hint-control a0-99 last-time-called) + (the-as time-frame (-> (the-as (pointer uint64) (&+ v1-65 (* (+ (* a0-99 4) 1) 8))))) + ) + (set! (-> obj hint-control a0-99 num-attempts) + (-> (the-as (pointer int8) (&+ (the-as (pointer uint8) v1-65) (+ (* a0-99 32) 16)))) + ) + (set! (-> obj hint-control a0-99 num-success) + (-> (the-as (pointer int8) (&+ (the-as (pointer uint8) v1-65) (+ (* a0-99 32) 17)))) + ) + ) + ) + ) + (else + (format 0 "WARNING: SAVEGAME: hint control list did not match current, ignoring~%") + ) + ) + ) + (((game-save-elt auto-save-count)) + (set! (-> obj auto-save-count) (the-as int (-> data user-uint64))) + ) + (((game-save-elt total-deaths)) + (set! (-> obj total-deaths) (the-as int (-> data user-uint64))) + ) + (((game-save-elt continue-deaths)) + (set! (-> obj continue-deaths) (the-as int (-> data user-uint64))) + ) + (((game-save-elt fuel-cell-deaths)) + (set! (-> obj fuel-cell-deaths) (the-as int (-> data user-uint64))) + ) + (((game-save-elt game-start-time)) + (set! (-> obj game-start-time) (the-as time-frame (-> data user-uint64))) + ) + (((game-save-elt continue-time)) + (set! (-> obj continue-time) (the-as time-frame (-> data user-uint64))) + ) + (((game-save-elt death-time)) + (set! (-> obj death-time) (the-as time-frame (-> data user-uint64))) + ) + (((game-save-elt hit-time)) + (set! (-> obj hit-time) (the-as time-frame (-> data user-uint64))) + ) + (((game-save-elt fuel-cell-pickup-time)) + (set! (-> obj fuel-cell-pickup-time) (the-as time-frame (-> data user-uint64))) + ) + (((game-save-elt deaths-per-level)) + (let ((v1-79 (min 32 (-> data elt-count)))) + (dotimes (a0-122 v1-79) + (set! (-> obj deaths-per-level a0-122) (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-122)) + ) + ) + ) + (((game-save-elt enter-level-time)) + (let ((v1-83 (min 32 (-> data elt-count)))) + (dotimes (a0-126 v1-83) + (set! (-> obj enter-level-time a0-126) + (the-as time-frame (-> (the-as (pointer uint64) (&+ (&+ (the-as pointer data) 16) (* a0-126 8))))) ) - ) - ) - ) - (else - (format - 0 - "WARNING: SAVEGAME: hint control list did not match current, ignoring~%" - ) - ) ) ) - ((= v1-7 (game-save-elt auto-save-count)) - (set! (-> obj auto-save-count) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt total-deaths)) - (set! (-> obj total-deaths) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt continue-deaths)) - (set! (-> obj continue-deaths) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt fuel-cell-deaths)) - (set! (-> obj fuel-cell-deaths) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt game-start-time)) - (set! (-> obj game-start-time) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt continue-time)) - (set! (-> obj continue-time) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt death-time)) - (set! (-> obj death-time) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt hit-time)) - (set! (-> obj hit-time) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt fuel-cell-pickup-time)) - (set! (-> obj fuel-cell-pickup-time) (the-as int (-> data user-uint64))) - ) - ((= v1-7 (game-save-elt deaths-per-level)) - (let ((v1-79 (min 32 (-> data elt-count)))) - (dotimes (a0-122 v1-79) - (set! - (-> obj deaths-per-level a0-122) - (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-122) - ) - ) + ) + (((game-save-elt in-level-time)) + (let ((v1-87 (min 32 (-> data elt-count)))) + (dotimes (a0-130 v1-87) + (set! (-> obj in-level-time a0-130) + (the-as time-frame (-> (the-as (pointer uint64) (&+ (&+ (the-as pointer data) 16) (* a0-130 8))))) + ) ) ) - ((= v1-7 (game-save-elt enter-level-time)) - (let ((v1-83 (min 32 (-> data elt-count)))) - (dotimes (a0-126 v1-83) - (set! (-> obj enter-level-time a0-126) - (-> (the-as (pointer int64) (&+ (&+ (the-as pointer data) 16) (* a0-126 8)))) - ) - ) + ) + (((game-save-elt fuel-cell-time)) + (let ((v1-92 (min 32 (-> data elt-count)))) + (dotimes (a0-133 v1-92) + (set! (-> obj fuel-cell-time a0-133) + (the-as time-frame (-> (the-as (pointer uint64) (&+ (&+ (the-as pointer data) 16) (* a0-133 8))))) + ) ) ) - ((= v1-7 (game-save-elt in-level-time)) - (let ((v1-87 (min 32 (-> data elt-count)))) - (dotimes (a0-130 v1-87) - (set! (-> obj in-level-time a0-130) - (-> (the-as (pointer int64) (&+ (&+ (the-as pointer data) 16) (* a0-130 8)))) - ) - ) - ) - ) - ((= v1-7 (game-save-elt fuel-cell-time)) - (let ((v1-92 (min 32 (-> data elt-count)))) - (dotimes (a0-133 v1-92) - (set! (-> obj fuel-cell-time a0-133) - (-> (the-as (pointer int64) (&+ (&+ (the-as pointer data) 16) (* a0-133 8)))) - ) - ) - ) - ) - ) + ) ) - (set! data (the-as game-save-tag (&+ (the-as pointer data) - (logand -16 - (+ (* (the-as int (-> data elt-size)) (-> data elt-count)) 31) - ) - ) - ) + (set! data + (the-as + game-save-tag + (&+ (the-as pointer data) (logand -16 (+ (* (the-as int (-> data elt-size)) (-> data elt-count)) 31))) + ) ) ) ) - ;; update entity stuff in levels that are active (dotimes (s4-1 (-> *level* length)) (let ((a1-68 (-> *level* level s4-1))) @@ -1107,13 +1073,8 @@ ) (when (!= (-> obj version) SAVE_VERSION) ;; uh-oh, the version is wrong - (format 0 "ERROR: SAVEGAME: save file ~A was version ~d, but only ~d is supported.~%" - stream - (-> obj version) - SAVE_VERSION - ) + (format 0 "ERROR: SAVEGAME: save file ~A was version ~d, but only ~d is supported.~%" stream (-> obj version) SAVE_VERSION) (set! (-> obj length) 0) - 0 ) (file-stream-close stream) ) @@ -1124,39 +1085,29 @@ ;; particles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; used for the flashing auto-save icon, I think. +;; used for the flashing auto-save icon. -(set! (-> *part-group-id-table* 656) - (new 'static 'sparticle-launch-group - :length 1 - :duration #xbb8 - :linger-duration #x5dc - :flags (sp-group-flag screen-space) - :name "group-part-save-icon" - :launcher - (new 'static 'inline-array sparticle-group-item 1 (sp-item 2662)) - :bounds (new 'static 'sphere :w 409600.0) - ) - ) +(defpartgroup group-part-save-icon + :id 656 + :flags (screen-space) + :bounds (static-bspherem 0 0 0 100) + :parts ((sp-item 2662)) + ) -(set! (-> *part-id-table* 2662) - (new 'static 'sparticle-launcher - :init-specs - (new 'static 'inline-array sp-field-init-spec 11 - (sp-tex spt-texture (new 'static 'texture-id :index #x6b :page #x1cf)) - (sp-flt spt-num 1.0) - (sp-flt spt-scale-x (meters 1.5)) - (sp-copy-from-other spt-scale-y -4) - (sp-flt spt-r 128.0) - (sp-flt spt-g 128.0) - (sp-flt spt-b 128.0) - (sp-flt spt-a 128.0) - (sp-int spt-timer 5) - (sp-cpuinfo-flags bit2 bit9 bit13) - (sp-end) - ) - ) - ) +(defpart 2662 + :init-specs + ((sp-tex spt-texture (new 'static 'texture-id :index #x6b :page #x1cf)) + (sp-flt spt-num 1.0) + (sp-flt spt-scale-x (meters 1.5)) + (sp-copy-from-other spt-scale-y -4) + (sp-flt spt-r 128.0) + (sp-flt spt-g 128.0) + (sp-flt spt-b 128.0) + (sp-flt spt-a 128.0) + (sp-int spt-timer 5) + (sp-cpuinfo-flags bit2 bit9 bit13) + ) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; auto-save process @@ -1242,66 +1193,69 @@ ;; auto-save drawing (when (and (= (-> self mode) 'auto-save) (!= (-> self next-state name) 'done)) - (let ((gp-1 (new 'stack 'font-context *font-default-matrix* 20 40 0.0 (font-color default) (font-flags shadow kerning)))) - (let ((v1-15 gp-1)) - (set! (-> v1-15 scale) 0.8) - ) - (let ((v1-16 gp-1)) - (set! (-> v1-16 width) (the float 472)) - ) - (let ((v1-17 gp-1)) - (set! (-> v1-17 height) (the float 20)) - ) - (set! (-> gp-1 flags) (font-flags shadow kerning middle left large)) + (let ((gp-1 + (new 'stack 'font-context *font-default-matrix* 20 40 0.0 (font-color default) (font-flags shadow kerning)) + ) + ) + (let ((v1-15 gp-1)) + (set! (-> v1-15 scale) 0.8) + ) + (let ((v1-16 gp-1)) + (set! (-> v1-16 width) (the float 472)) + ) + (let ((v1-17 gp-1)) + (set! (-> v1-17 height) (the float 20)) + ) + (set! (-> gp-1 flags) (font-flags shadow kerning middle left large)) - ;; if this is the first time saving, display a warning. - (when (zero? (-> *game-info* auto-save-count)) - (print-game-text (lookup-text! *common-text* (game-text-id saving-data) #f) gp-1 #f 128 22) - (set! (-> gp-1 origin x) 20.0) - (set! (-> gp-1 origin y) 130.0) - (let ((v1-23 gp-1)) - (set! (-> v1-23 scale) 0.7) + ;; if this is the first time saving, display a warning. + (when (zero? (-> *game-info* auto-save-count)) + (print-game-text (lookup-text! *common-text* (game-text-id saving-data) #f) gp-1 #f 128 22) + (set! (-> gp-1 origin x) 20.0) + (set! (-> gp-1 origin y) 130.0) + (let ((v1-23 gp-1)) + (set! (-> v1-23 scale) 0.7) + ) + (let ((v1-24 gp-1)) + (set! (-> v1-24 height) (the float 40)) + ) + (let ((s5-2 print-game-text)) + ((the-as (function object string object none) format) + (clear *temp-string*) + (lookup-text! *common-text* (game-text-id do-not-remove-mem-card) #f) + 1 + ) + (s5-2 *temp-string* gp-1 #f 128 22) + ) + ) ) - (let ((v1-24 gp-1)) - (set! (-> v1-24 height) (the float 40)) - ) - (let ((s5-2 print-game-text)) - ((the-as (function object string object none) format) - (clear *temp-string*) - (lookup-text! *common-text* (game-text-id do-not-remove-mem-card) #f) - 1 - ) - (s5-2 *temp-string* gp-1 #f 128 22) - ) - ) - ) - ;; flash the icon. - (when (< (mod (-> *display* real-frame-counter) 300) 270) - (if (> (-> self part matrix) 0) - (set-vector! - (sprite-get-user-hvdf (-> self part matrix)) - 1842.0 - (the float (+ (the int (* 0.5 (- (* (if (= (get-aspect-ratio) 'aspect16x9) - 370.0 - 360.0 - ) - (-> *video-parms* relative-y-scale) - ) - (the float (-> *video-parms* screen-sy)) - ) - ) - ) - 2048 - ) - ) - (+ -1024.0 (-> *math-camera* hvdf-off z)) - (-> *math-camera* hvdf-off w) + ;; flash the icon. + (when (< (mod (-> *display* real-frame-counter) 300) 270) + (if (> (-> self part matrix) 0) + (set-vector! + (sprite-get-user-hvdf (-> self part matrix)) + 1842.0 + (the float (+ (the int (* 0.5 (- (* (if (= (get-aspect-ratio) 'aspect16x9) + 370.0 + 360.0 + ) + (-> *video-parms* relative-y-scale) + ) + (the float (-> *video-parms* screen-sy)) + ) + ) + ) + 2048 + ) + ) + (+ -1024.0 (-> *math-camera* hvdf-off z)) + (-> *math-camera* hvdf-off w) + ) + ) + (spawn (-> self part) *zero-vector*) ) - ) - (spawn (-> self part) *zero-vector*) ) - ) (none) ) @@ -1310,12 +1264,11 @@ (defbehavior auto-save-init-by-other auto-save ((desired-mode symbol) (notify-proc process-tree) (card-idx int) (file-idx int)) - (format 0 "auto-save-init!~%") ;; trying to create multiple auto save procs, bad idea. (when (handle->process (-> *game-info* auto-save-proc)) - (send-event notify-proc 'notify 'error 16) - (return #f) - ) + (send-event notify-proc 'notify 'error 16) + (return #f) + ) ;; set us as the auto save proc (set! (-> *game-info* auto-save-proc) (process->handle self)) @@ -1334,22 +1287,21 @@ (set! (-> self part) (create-launch-control (-> *part-group-id-table* 656) self)) (set! (-> self part matrix) (sprite-allocate-user-hvdf)) (cond - ((= desired-mode 'auto-save) - (if (not (-> *setting-control* current auto-save)) - (go-virtual error (mc-status-code no-auto-save)) + ((= desired-mode 'auto-save) + (if (not (-> *setting-control* current auto-save)) + (go-virtual error (mc-status-code no-auto-save)) + ) + (when (and (zero? (-> self card)) (-> *setting-control* current auto-save)) + (set! (-> self card) (-> *game-info* auto-save-card)) + (set! (-> self which) (-> *game-info* auto-save-which)) + ) ) - (when (and (zero? (-> self card)) (-> *setting-control* current auto-save)) - (set! (-> self card) (-> *game-info* auto-save-card)) - (set! (-> self which) (-> *game-info* auto-save-which)) + ((= desired-mode 'error) + (set! (-> *setting-control* default auto-save) #f) + (go-virtual error (mc-status-code no-card)) ) ) - ((= desired-mode 'error) - (set! (-> *setting-control* default auto-save) #f) - (go-virtual error (mc-status-code no-card)) - ) - ) (set! (-> *setting-control* default auto-save) #f) - (format 0 "going to get-heap!~%") (go-virtual get-heap) (none) ) @@ -1359,532 +1311,430 @@ :virtual #t :code (behavior () - (set! (-> self state-time) (-> *display* real-frame-counter)) - (let ((a0-1 (reserve-alloc *art-control*))) - (while (not a0-1) - (if (>= (- (-> *display* real-frame-counter) (-> self state-time)) (seconds 60)) - (go-virtual error (mc-status-code no-memory)) + (set! (-> self state-time) (-> *display* real-frame-counter)) + (let ((a0-1 (reserve-alloc *art-control*))) + (while (not a0-1) + (if (>= (- (-> *display* real-frame-counter) (-> self state-time)) (seconds 60)) + (go-virtual error (mc-status-code no-memory)) + ) + (suspend) + (set! a0-1 (reserve-alloc *art-control*)) + ) + (set! (-> self buffer) a0-1) ) - (suspend) - (set! a0-1 (reserve-alloc *art-control*)) - ) - (set! (-> self buffer) a0-1) + (go-virtual get-card) + (none) ) - (go-virtual get-card) - (none) - ) - :post - auto-save-post ) (defstate get-card (auto-save) :virtual #t :code (behavior () - (label cfg-0) - (mc-get-slot-info (-> self slot) (-> self info)) - (when (zero? (-> self info known)) - (suspend) - (goto cfg-0) - ) - (cond - ((zero? (-> self info handle)) - (go-virtual error (mc-status-code no-card)) - ) - ((zero? (-> self card)) - (set! (-> self card) (-> self info handle)) - ) - ((!= (-> self info handle) (-> self card)) - (go-virtual error (mc-status-code bad-handle)) - ) - ) - (case (-> self mode) - (('save 'auto-save) - (go-virtual save) + (label cfg-0) + (mc-get-slot-info (-> self slot) (-> self info)) + (when (zero? (-> self info known)) + (suspend) + (goto cfg-0) ) - (('save-last) - (set! (-> self which) (-> self info last-file)) - (if (= (-> self which) -1) - (go-virtual error (mc-status-code no-last)) - (go-virtual save) + (cond + ((zero? (-> self info handle)) + (go-virtual error (mc-status-code no-card)) + ) + ((zero? (-> self card)) + (set! (-> self card) (-> self info handle)) + ) + ((!= (-> self info handle) (-> self card)) + (go-virtual error (mc-status-code bad-handle)) + ) ) - ) - (('restore) - (go-virtual restore) - ) - (('format-card) - (go-virtual format-card) - ) - (('unformat-card) - (go-virtual unformat-card) - ) - (('create-file) - (go-virtual create-file) - ) - (else - (go-virtual done) - ) + (case (-> self mode) + (('save 'auto-save) + (go-virtual save) + ) + (('save-last) + (set! (-> self which) (-> self info last-file)) + (if (= (-> self which) -1) + (go-virtual error (mc-status-code no-last)) + (go-virtual save) + ) + ) + (('restore) + (go-virtual restore) + ) + (('format-card) + (go-virtual format-card) + ) + (('unformat-card) + (go-virtual unformat-card) + ) + (('create-file) + (go-virtual create-file) + ) + (else + (go-virtual done) + ) + ) + (none) ) - (none) - ) - :post - auto-save-post ) (defstate format-card (auto-save) :virtual #t :code (behavior () - (when (zero? (-> self info formatted)) - (label cfg-1) - (set! (-> self result) (mc-format (-> self card))) - (when (!= (-> self result) (mc-status-code ok)) - (suspend) - (goto cfg-1) - ) - (label cfg-3) - (set! (-> self result) (the-as mc-status-code (mc-check-result))) - (let ((v1-4 (-> self result))) - (b! (nonzero? v1-4) cfg-5 :delay (nop!)) - (b! #t cfg-10 :delay (nop!)) - (label cfg-5) - (b! (= v1-4 (mc-status-code format-failed)) cfg-1 :delay (nop!)) - (nop!) - (b! (!= v1-4 (mc-status-code ok)) cfg-9 :delay (nop!)) - ) - (b! #t cfg-12 :delay (nop!)) - (the-as none 0) - (b! #t cfg-10 :delay (nop!)) - (label cfg-9) - (go-virtual error (-> self result)) - (label cfg-10) - (suspend) - (goto cfg-3) - ;;(break ((empty)) ((empty-form))) - - ) - (label cfg-12) - (case (-> self mode) - (('create-file 'save 'save-last 'auto-save 'restore) - (go-virtual create-file) + (when (zero? (-> self info formatted)) + (label cfg-1) + (set! (-> self result) (mc-format (-> self card))) + (when (!= (-> self result) (mc-status-code ok)) + (suspend) + (goto cfg-1) + ) + (label cfg-3) + (set! (-> self result) (the-as mc-status-code (mc-check-result))) + (let ((v1-4 (-> self result))) + (b! (nonzero? v1-4) cfg-5 :delay (nop!)) + (b! #t cfg-10 :delay (nop!)) + (label cfg-5) + (b! (= v1-4 (mc-status-code format-failed)) cfg-1 :delay (nop!)) + (nop!) + (b! (!= v1-4 (mc-status-code ok)) cfg-9 :delay (nop!)) + ) + (b! #t cfg-12 :delay (nop!)) + (the-as none 0) + (b! #t cfg-10 :delay (nop!)) + (label cfg-9) + (go-virtual error (-> self result)) + (label cfg-10) + (suspend) + (b! #t cfg-3 :delay (nop!)) ) + (label cfg-12) + (case (-> self mode) + (('create-file 'save 'save-last 'auto-save 'restore) + (go-virtual create-file) + ) + ) + (go-virtual done) + (none) ) - (go-virtual done) - (none) - ) - :post - auto-save-post ) (defstate unformat-card (auto-save) :virtual #t :code (behavior () - (when (nonzero? (-> self info formatted)) - (label cfg-1) - (set! (-> self result) (mc-unformat (-> self card))) - (when (!= (-> self result) (mc-status-code ok)) - (suspend) - (goto cfg-1) - ) - (while #t - (set! (-> self result) (the-as mc-status-code (mc-check-result))) - (case (-> self result) - (((mc-status-code busy)) + (when (nonzero? (-> self info formatted)) + (label cfg-1) + (set! (-> self result) (mc-unformat (-> self card))) + (when (!= (-> self result) (mc-status-code ok)) + (suspend) + (goto cfg-1) + ) + (while #t + (set! (-> self result) (the-as mc-status-code (mc-check-result))) + (case (-> self result) + (((mc-status-code busy)) + ) + (((mc-status-code ok)) + (goto cfg-11) + ) + (else + (go-virtual error (-> self result)) + ) + ) + (suspend) ) - (((mc-status-code ok)) - (goto cfg-11) - ) - (else - (go-virtual error (-> self result)) - ) ) - (suspend) - ) + (label cfg-11) + (go-virtual done) + (none) ) - (label cfg-11) - (go-virtual done) - (none) - ) - :post - auto-save-post ) (defstate create-file (auto-save) :virtual #t :code (behavior () - (cond - ((zero? (-> self info formatted)) - (go-virtual error (mc-status-code no-format)) - ) - ((zero? (-> self info inited)) - (if (< (-> self info mem-actual) (-> self info mem-required)) - (go-virtual error (mc-status-code no-space)) - ) - (let ((v1-12 (-> self buffer))) - (set! (-> v1-12 current) (-> v1-12 base)) - ) - (label cfg-6) - (set! - (-> self result) - (mc-create-file (-> self card) (the-as uint (-> self buffer base))) - ) - (when (!= (-> self result) (mc-status-code ok)) - (suspend) - (goto cfg-6) - ) - (while #t - (set! (-> self result) (the-as mc-status-code (mc-check-result))) - (case (-> self result) - (((mc-status-code busy)) - ) - (((mc-status-code ok)) - (goto cfg-16) - ) - (else - (go-virtual error (-> self result)) - ) + (cond + ((zero? (-> self info formatted)) + (go-virtual error (mc-status-code no-format)) + ) + ((zero? (-> self info inited)) + (if (< (-> self info mem-actual) (-> self info mem-required)) + (go-virtual error (mc-status-code no-space)) + ) + (let ((v1-12 (-> self buffer))) + (set! (-> v1-12 current) (-> v1-12 base)) + ) + (label cfg-6) + (set! (-> self result) (mc-create-file (-> self card) (the-as uint (-> self buffer base)))) + (when (!= (-> self result) (mc-status-code ok)) + (suspend) + (goto cfg-6) + ) + (while #t + (set! (-> self result) (the-as mc-status-code (mc-check-result))) + (case (-> self result) + (((mc-status-code busy)) + ) + (((mc-status-code ok)) + (goto cfg-16) + ) + (else + (go-virtual error (-> self result)) + ) + ) + (suspend) + ) ) - (suspend) ) - ) - ) - (label cfg-16) - (case (-> self mode) - (('restore) - (go-virtual restore) + (label cfg-16) + (case (-> self mode) + (('restore) + (go-virtual restore) + ) + (('save 'save-last 'auto-save) + (go-virtual save) + ) ) - (('save 'save-last 'auto-save) - (go-virtual save) - ) + (go-virtual done) + (none) ) - (go-virtual done) - (none) - ) - :post - auto-save-post ) (defstate save (auto-save) :virtual #t :code (behavior () - (cond - ((zero? (-> self info formatted)) - (go-virtual error (mc-status-code no-format)) - ) - ((zero? (-> self info inited)) - (go-virtual error (mc-status-code no-file)) - ) - ) - (case (-> self mode) - (('auto-save) - (+! (-> *game-info* auto-save-count) 1) + (cond + ((zero? (-> self info formatted)) + (go-virtual error (mc-status-code no-format)) + ) + ((zero? (-> self info inited)) + (go-virtual error (mc-status-code no-file)) + ) ) - ) - (let ((v1-14 (-> self buffer))) - (set! (-> v1-14 current) (-> v1-14 base)) - ) - (let ((gp-0 loading-level)) - (set! loading-level (-> self buffer)) - (set! (-> self save) (new 'loading-level 'game-save #x10000)) - (save-game! *game-info* (-> self save) "save") - (set! loading-level (the-as kheap gp-0)) - 0 - (label cfg-7) - (set! - (-> self result) - (mc-save - (-> self card) - (-> self which) - (&-> (-> self save) type) - (the-as int (-> self save info-int32)) + (case (-> self mode) + (('auto-save) + (+! (-> *game-info* auto-save-count) 1) + ) ) - ) - (when (!= (-> self result) (mc-status-code ok)) - (suspend) - (goto cfg-7) - ) - (while #t - (set! (-> self result) (the-as mc-status-code (mc-check-result))) - (let ((v1-24 (-> self result))) - (cond - ((= v1-24 (mc-status-code busy)) - #f - ) - ((= v1-24 (mc-status-code ok)) - (goto cfg-21) - gp-0 - ) - ((= v1-24 (mc-status-code write-error)) - (suspend) - gp-0 - ) - (else - (case (-> self mode) - (('auto-save) - (set! - (-> *game-info* auto-save-count) - (seekl (-> *game-info* auto-save-count) 0 1) - ) - ) - ) - (go-virtual error (-> self result)) - ) - - ) + (let ((v1-14 (-> self buffer))) + (set! (-> v1-14 current) (-> v1-14 base)) ) - (suspend) - ) + (let ((gp-0 (the-as object loading-level))) + (set! loading-level (-> self buffer)) + (set! (-> self save) (new 'loading-level 'game-save #x10000)) + (save-game! *game-info* (-> self save) "save") + (set! loading-level (the-as kheap gp-0)) + 0 + (label cfg-7) + (set! (-> self result) + (mc-save (-> self card) (-> self which) (&-> (-> self save) type) (the-as int (-> self save info-int32))) + ) + (when (!= (-> self result) (mc-status-code ok)) + (suspend) + (goto cfg-7) + ) + (while #t + (set! (-> self result) (the-as mc-status-code (mc-check-result))) + (let ((v1-24 (-> self result))) + (set! gp-0 (cond + ((= v1-24 (mc-status-code busy)) + #f + ) + ((= v1-24 (mc-status-code ok)) + (goto cfg-21) + gp-0 + ) + ((= v1-24 (mc-status-code write-error)) + (suspend) + gp-0 + ) + (else + (case (-> self mode) + (('auto-save) + (set! (-> *game-info* auto-save-count) (seekl (-> *game-info* auto-save-count) 0 1)) + ) + ) + (go-virtual error (-> self result)) + ) + ) + ) + ) + (suspend) + ) + ) + (label cfg-21) + (go-virtual done) + (none) ) - (label cfg-21) - (go-virtual done) - (none) - ) - :post - auto-save-post ) (defstate restore (auto-save) :virtual #t :code (behavior () - (local-vars (gp-0 none)) - (cond - ((zero? (-> self info formatted)) - (go-virtual error (mc-status-code no-format)) - ) - ((zero? (-> self info inited)) - (go-virtual error (mc-status-code no-file)) - ) - ) - (let ((v1-10 (-> self buffer))) - (set! (-> v1-10 current) (-> v1-10 base)) - ) - (if (zero? (-> self info file (-> self which) present)) - (go-virtual error (mc-status-code no-save)) - ) - (label cfg-6) - (set! - (-> self result) - (mc-load (-> self card) (-> self which) (-> self buffer base)) - ) - (when (!= (-> self result) (mc-status-code ok)) - (suspend) - (goto cfg-6) - ) - (while #t - (set! (-> self result) (the-as mc-status-code (mc-check-result))) - (let ((v1-22 (-> self result))) - (cond - ((= v1-22 (mc-status-code busy)) - #f - ) - ((= v1-22 (mc-status-code ok)) - (goto cfg-20) - gp-0 - ) - ((= v1-22 (mc-status-code read-error)) - (suspend) - gp-0 - ) - ((= v1-22 (mc-status-code new-game)) - (go-virtual error (mc-status-code no-save)) - ) - (else - (go-virtual error (-> self result)) - ) + (local-vars (gp-0 object)) + (cond + ((zero? (-> self info formatted)) + (go-virtual error (mc-status-code no-format)) + ) + ((zero? (-> self info inited)) + (go-virtual error (mc-status-code no-file)) + ) + ) + (let ((v1-10 (-> self buffer))) + (set! (-> v1-10 current) (-> v1-10 base)) + ) + (if (zero? (-> self info file (-> self which) present)) + (go-virtual error (mc-status-code no-save)) ) - - ) - (suspend) + (label cfg-6) + (set! (-> self result) (mc-load (-> self card) (-> self which) (-> self buffer base))) + (when (!= (-> self result) (mc-status-code ok)) + (suspend) + (goto cfg-6) + ) + (while #t + (set! (-> self result) (the-as mc-status-code (mc-check-result))) + (let ((v1-22 (-> self result))) + (set! gp-0 (cond + ((= v1-22 (mc-status-code busy)) + #f + ) + ((= v1-22 (mc-status-code ok)) + (goto cfg-20) + gp-0 + ) + ((= v1-22 (mc-status-code read-error)) + (suspend) + gp-0 + ) + ((= v1-22 (mc-status-code new-game)) + (go-virtual error (mc-status-code no-save)) + ) + (else + (go-virtual error (-> self result)) + ) + ) + ) + ) + (suspend) + ) + (label cfg-20) + (set! (-> self save) (the-as game-save (&+ (-> self buffer base) 4))) + (let ((v1-34 (-> self save))) + (set! (-> v1-34 type) game-save) + (if (!= (-> v1-34 version) 1) + (go-virtual error (mc-status-code bad-version)) + ) + ) + (set-setting! *setting-control* self 'music-volume 'abs 0.0 0) + (set-setting! *setting-control* self 'sfx-volume 'abs 0.0 0) + (set! (-> *game-info* mode) 'play) + (initialize! *game-info* 'game (-> self save) (the-as string #f)) + (set-master-mode 'game) + (push-setting! *setting-control* self 'process-mask 'set 0.0 16) + (copy-settings-from-target! *setting-control*) + (dotimes (gp-1 15) + (suspend) + ) + (go-virtual done) + (none) ) - (label cfg-20) - (set! (-> self save) (the-as game-save (&+ (-> self buffer base) 4))) - (let ((v1-34 (-> self save))) - (set! (-> v1-34 type) game-save) - (if (!= (-> v1-34 version) 1) - (go-virtual error (mc-status-code bad-version)) - ) - ) - (set-setting! *setting-control* self 'music-volume 'abs 0.0 0) - (set-setting! *setting-control* self 'sfx-volume 'abs 0.0 0) - (set! (-> *game-info* mode) 'play) - (initialize! *game-info* 'game (-> self save) (the-as string #f)) - (set-master-mode 'game) - (push-setting! *setting-control* self 'process-mask 'set 0.0 16) - (copy-settings-from-target! *setting-control*) - (dotimes (gp-1 15) - (suspend) - ) - (go-virtual done) - (none) - ) - :post - auto-save-post ) (defstate error (auto-save) :virtual #t :event (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) - (let ((v1-0 arg2)) - (the-as object (cond - ((= v1-0 'progress-allowed?) - #t - ) - ((= v1-0 'die) - (deactivate self) - ) - ) - ) - ) - ) - :code - (behavior ((arg0 mc-status-code)) - (if (-> self buffer) - (reserve-free *art-control* (-> self buffer)) - ) - (set! (-> self result) arg0) - (let ((s5-0 *auto-save-info*)) - (mem-copy! (the-as pointer s5-0) (the-as pointer (-> self info)) 300) - (send-event (handle->process (-> self notify)) 'notify 'error (-> self result) s5-0) - ) - (let ((t9-3 format) - (a0-7 #t) - (a1-3 "SAVE ERROR: ~A~%") - (v1-12 (-> self result)) - ) - (t9-3 a0-7 a1-3 (cond - ((= v1-12 (mc-status-code no-auto-save)) - "no-auto-save" - ) - ((= v1-12 (mc-status-code no-process)) - "no-process" - ) - ((= v1-12 (mc-status-code bad-version)) - "bad-version" - ) - ((= v1-12 (mc-status-code no-space)) - "no-space" - ) - ((= v1-12 (mc-status-code no-save)) - "no-save" - ) - ((= v1-12 (mc-status-code no-file)) - "no-file" - ) - ((= v1-12 (mc-status-code no-format)) - "no-format" - ) - ((= v1-12 (mc-status-code no-last)) - "no-last" - ) - ((= v1-12 (mc-status-code no-card)) - "no-card" - ) - ((= v1-12 (mc-status-code no-memory)) - "no-memory" - ) - ((= v1-12 (mc-status-code new-game)) - "new-game" - ) - ((= v1-12 (mc-status-code read-error)) - "read-error" - ) - ((= v1-12 (mc-status-code write-error)) - "write-error" - ) - ((= v1-12 (mc-status-code internal-error)) - "internal-error" - ) - ((= v1-12 (mc-status-code format-failed)) - "format-failed" - ) - ((= v1-12 (mc-status-code bad-handle)) - "bad-handle" - ) - ((= v1-12 (mc-status-code ok)) - "ok" - ) - ((= v1-12 (mc-status-code busy)) - "busy" - ) - (else - "*unknown*" - ) - ) - ) - ) - (if (= (-> self result) (mc-status-code no-auto-save)) - (return #f) - ) - (case (-> self mode) - (('auto-save 'error) - (set! (-> self state-time) (-> *display* real-frame-counter)) - (set! (-> *game-info* auto-save-status) arg0) - (while (< (- (-> *display* real-frame-counter) (-> self state-time)) (seconds 0.2)) - (if (not (progress-allowed?)) - (set! (-> self state-time) (-> *display* real-frame-counter)) - ) - (suspend) - ) - (if (= arg0 (mc-status-code no-card)) - (activate-progress *dproc* (progress-screen memcard-removed)) - (activate-progress *dproc* (progress-screen memcard-auto-save-error)) - ) + (let ((v1-0 arg2)) + (the-as object (cond + ((= v1-0 'progress-allowed?) + #t + ) + ((= v1-0 'die) + (deactivate self) + ) + ) + ) ) ) - (none) - ) - :post - auto-save-post + :code + (behavior ((arg0 mc-status-code)) + (if (-> self buffer) + (reserve-free *art-control* (-> self buffer)) + ) + (set! (-> self result) arg0) + (let ((s5-0 *auto-save-info*)) + (mem-copy! (the-as pointer s5-0) (the-as pointer (-> self info)) 300) + (send-event (handle->process (-> self notify)) 'notify 'error (-> self result) s5-0) + ) + (format #t "SAVE ERROR: ~A~%" (enum->string mc-status-code (-> self result))) + (if (= (-> self result) (mc-status-code no-auto-save)) + (return #f) + ) + (case (-> self mode) + (('auto-save 'error) + (set! (-> self state-time) (-> *display* real-frame-counter)) + (set! (-> *game-info* auto-save-status) arg0) + (while (< (- (-> *display* real-frame-counter) (-> self state-time)) (seconds 0.2)) + (if (not (progress-allowed?)) + (set! (-> self state-time) (-> *display* real-frame-counter)) + ) + (suspend) + ) + (if (= arg0 (mc-status-code no-card)) + (activate-progress *dproc* (progress-screen memcard-removed)) + (activate-progress *dproc* (progress-screen memcard-auto-save-error)) + ) + ) + ) + (none) + ) ) -;; failed to figure out what this is: (defstate done (auto-save) :virtual #t :code (behavior () - (if (and (-> self buffer) (-> *art-control* reserve-buffer)) - (reserve-free *art-control* (-> self buffer)) - ) - (set! (-> *game-info* auto-save-status) (mc-status-code ok)) - (case (-> self mode) - (('save 'save-last 'auto-save 'restore) - (set! (-> *setting-control* default auto-save) #t) - (set! (-> *game-info* auto-save-card) (-> self card)) - (set! (-> *game-info* auto-save-which) (-> self which)) - ) - ) - (let ((gp-0 *auto-save-info*)) - (mem-copy! (the-as pointer gp-0) (the-as pointer (-> self info)) 300) - (send-event (handle->process (-> self notify)) 'notify 'done 1 gp-0) - ) - (case (-> self mode) - (('auto-save) - (when (= (-> *game-info* auto-save-count) 1) - (set! (-> self event-hook) (-> (method-of-object self error) event)) - (set! (-> self state-time) (-> *display* real-frame-counter)) - (while (< (- (-> *display* real-frame-counter) (-> self state-time)) (seconds 0.2)) - (if (not (progress-allowed?)) - (set! (-> self state-time) (-> *display* real-frame-counter)) - ) - (suspend) + (if (and (-> self buffer) (-> *art-control* reserve-buffer)) + (reserve-free *art-control* (-> self buffer)) ) - (activate-progress *dproc* (progress-screen auto-save)) + (set! (-> *game-info* auto-save-status) (mc-status-code ok)) + (case (-> self mode) + (('save 'save-last 'auto-save 'restore) + (set! (-> *setting-control* default auto-save) #t) + (set! (-> *game-info* auto-save-card) (-> self card)) + (set! (-> *game-info* auto-save-which) (-> self which)) ) ) + (let ((gp-0 *auto-save-info*)) + (mem-copy! (the-as pointer gp-0) (the-as pointer (-> self info)) 300) + (send-event (handle->process (-> self notify)) 'notify 'done 1 gp-0) + ) + (case (-> self mode) + (('auto-save) + (when (= (-> *game-info* auto-save-count) 1) + (set! (-> self event-hook) (-> (method-of-object self error) event)) + (set! (-> self state-time) (-> *display* real-frame-counter)) + (while (< (- (-> *display* real-frame-counter) (-> self state-time)) (seconds 0.2)) + (if (not (progress-allowed?)) + (set! (-> self state-time) (-> *display* real-frame-counter)) + ) + (suspend) + ) + (activate-progress *dproc* (progress-screen auto-save)) + ) + ) + ) + (none) ) - (none) - ) - :post - auto-save-post ) (defun auto-save-command ((arg0 symbol) (arg1 int) (arg2 int) (arg3 process-tree)) - (format #t "auto-save cmd: ~A from ~A~%" arg0 arg3) (make-init-process auto-save auto-save-init-by-other arg0 arg3 arg1 arg2) (none) ) @@ -1899,7 +1749,7 @@ (!= (-> *auto-save-info* handle) (-> *game-info* auto-save-card)) ) ) - (auto-save-command 'error 0 0 (the-as process *default-pool*)) + (auto-save-command 'error 0 0 *default-pool*) ) ) 0