mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-07-07 06:05:31 -04:00
Better controller pak (#504)
* try add a better save use https://github.com/sonicdcer/N64ModernRuntime/blob/controllerpakimpl/librecomp/src/pak.cpp as a ref Co-Authored-By: Alejandro Asenjo Nitti <96613413+sonicdcer@users.noreply.github.com> * update pak * Update save.c * Better controller pak with File deletion menu Co-authored-by: Dario <dariosamo@gmail.com> Co-authored-by: Mr-Wiseguy <mrwiseguyromhacking@gmail.com> * add gControllerPakScreen button * change assert(false) in pak.cpp --------- Co-authored-by: Alejandro Asenjo Nitti <96613413+sonicdcer@users.noreply.github.com> Co-authored-by: Sonic Dreamcaster <alejandro.asenjo88@gmail.com> Co-authored-by: Dario <dariosamo@gmail.com> Co-authored-by: Mr-Wiseguy <mrwiseguyromhacking@gmail.com>
This commit is contained in:
+10
-8
@@ -1445,14 +1445,16 @@ s32 func_80091D74(void) {
|
||||
UNUSED s32 pad[10];
|
||||
s32 i;
|
||||
|
||||
if (!gControllerBits) {
|
||||
return 0;
|
||||
}
|
||||
if ((!gControllerStatuses[0].status) & CONT_CARD_ON) {
|
||||
return 0;
|
||||
}
|
||||
if (!(gControllerOne->button & START_BUTTON)) {
|
||||
return 0;
|
||||
if (CVarGetInteger("gControllerPakScreen", 0) == 0) {
|
||||
if (!gControllerBits) {
|
||||
return 0;
|
||||
}
|
||||
if ((!gControllerStatuses[0].status) & CONT_CARD_ON) {
|
||||
return 0;
|
||||
}
|
||||
if (!(gControllerOne->button & START_BUTTON)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
osPfsIsPlug(&gSIEventMesgQueue, &sp67);
|
||||
if (sp67 & 1) {
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
#include <libultraship.h>
|
||||
#include <libultraship/libultra.h>
|
||||
#include <save.h>
|
||||
|
||||
#define MAX_FILES 16
|
||||
#define EXT_NAME_SIZE 4
|
||||
#define GAME_NAME_SIZE 16
|
||||
|
||||
typedef struct ControllerPak {
|
||||
std::fstream header;
|
||||
std::fstream file;
|
||||
} ControllerPak;
|
||||
|
||||
bool Pfs_PakHeader_Write(u32* file_size, u32* game_code, u16* company_code, u8* ext_name, u8* game_name, u8 fileIndex) {
|
||||
ControllerPak pak;
|
||||
|
||||
pak.header.open("controllerPak_header.sav", std::ios::binary | std::ios::in | std::ios::out);
|
||||
|
||||
if (!pak.header.good()) {
|
||||
return false;
|
||||
}
|
||||
if (!pak.header.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set file parameters to header */
|
||||
u32 seek = fileIndex * sizeof(OSPfsState);
|
||||
|
||||
// file_size
|
||||
pak.header.seekp(seek + 0x0, std::ios::beg);
|
||||
pak.header.write((char*) file_size, 4);
|
||||
// game_code
|
||||
pak.header.seekp(seek + 0x4, std::ios::beg);
|
||||
pak.header.write((char*) game_code, 4);
|
||||
// company_code
|
||||
pak.header.seekp(seek + 0x08, std::ios::beg);
|
||||
pak.header.write((char*) company_code, 2);
|
||||
// ext_name
|
||||
pak.header.seekp(seek + 0x0C, std::ios::beg);
|
||||
pak.header.write((char*) ext_name, EXT_NAME_SIZE);
|
||||
// game_name
|
||||
pak.header.seekp(seek + 0x10, std::ios::beg);
|
||||
pak.header.write((char*) game_name, GAME_NAME_SIZE);
|
||||
|
||||
pak.header.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pfs_PakHeader_Read(u32* file_size, u32* game_code, u16* company_code, char* ext_name, char* game_name,
|
||||
u8 fileIndex) {
|
||||
ControllerPak pak;
|
||||
|
||||
pak.header.open("controllerPak_header.sav", std::ios::binary | std::ios::in | std::ios::out);
|
||||
|
||||
if (!pak.header.good()) {
|
||||
return false;
|
||||
}
|
||||
if (!pak.header.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set file parameters to header */
|
||||
u32 seek = fileIndex * sizeof(OSPfsState);
|
||||
|
||||
// file_size
|
||||
pak.header.seekg(seek + 0x0, std::ios::beg);
|
||||
pak.header.read((char*) file_size, 4);
|
||||
// game_code
|
||||
pak.header.seekg(seek + 0x4, std::ios::beg);
|
||||
pak.header.read((char*) game_code, 4);
|
||||
// company_code
|
||||
pak.header.seekg(seek + 0x08, std::ios::beg);
|
||||
pak.header.read((char*) company_code, 2);
|
||||
// ext_name
|
||||
pak.header.seekg(seek + 0x0C, std::ios::beg);
|
||||
pak.header.read((char*) ext_name, EXT_NAME_SIZE);
|
||||
// game_name
|
||||
pak.header.seekg(seek + 0x10, std::ios::beg);
|
||||
pak.header.read((char*) game_name, GAME_NAME_SIZE);
|
||||
|
||||
pak.header.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsIsPlug(OSMesgQueue* queue, u8* pattern) {
|
||||
*pattern = 1;
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsInit(OSMesgQueue* queue, OSPfs* pfs, int channel) {
|
||||
pfs->queue = queue;
|
||||
pfs->channel = channel;
|
||||
pfs->status = PFS_INITIALIZED;
|
||||
|
||||
ControllerPak pak;
|
||||
|
||||
// If a header file doesn't exist, create it.
|
||||
if (!std::filesystem::exists("controllerPak_header.sav")) {
|
||||
pak.header.open("controllerPak_header.sav", std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc);
|
||||
pak.header.close();
|
||||
}
|
||||
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsFreeBlocks(OSPfs* pfs, s32* bytes_not_used) {
|
||||
ControllerPak pak;
|
||||
|
||||
pak.header.open("controllerPak_header.sav", std::ios::binary | std::ios::in | std::ios::out);
|
||||
|
||||
if (!pak.header.good()) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
if (!pak.header.is_open()) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
s32 usedSpace = 0;
|
||||
for (size_t i = 0; i < MAX_FILES; i++) {
|
||||
u32 file_size = 0;
|
||||
u32 game_code = 0;
|
||||
u16 company_code = 0;
|
||||
char ext_name[EXT_NAME_SIZE] = { 0 };
|
||||
char game_name[GAME_NAME_SIZE] = { 0 };
|
||||
|
||||
if (!Pfs_PakHeader_Read(&file_size, &game_code, &company_code, ext_name, game_name, i)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
if ((company_code == 0) || (game_code == 0)) {
|
||||
continue;
|
||||
} else {
|
||||
usedSpace += file_size >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
pak.header.close();
|
||||
|
||||
*bytes_not_used = (123 - usedSpace) << 8;
|
||||
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsAllocateFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name, u8* ext_name,
|
||||
int file_size_in_bytes, s32* file_no) {
|
||||
|
||||
if ((company_code == 0) || (game_code == 0)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
ControllerPak pak;
|
||||
|
||||
/* Search for a free slot */
|
||||
u8 freeFileIndex = 0;
|
||||
for (size_t i = 0; i < MAX_FILES; i++) {
|
||||
u32 file_size_ = 0;
|
||||
u32 game_code_ = 0;
|
||||
u16 company_code_ = 0;
|
||||
char ext_name_[EXT_NAME_SIZE] = { 0 };
|
||||
char game_name_[GAME_NAME_SIZE] = { 0 };
|
||||
|
||||
if (!Pfs_PakHeader_Read(&file_size_, &game_code_, &company_code_, ext_name_, game_name_, i)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
if ((company_code_ == 0) || (game_code_ == 0)) {
|
||||
freeFileIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (freeFileIndex == MAX_FILES) {
|
||||
return PFS_DIR_FULL;
|
||||
}
|
||||
|
||||
if (!Pfs_PakHeader_Write((u32*) &file_size_in_bytes, &game_code, &company_code, ext_name, game_name, freeFileIndex)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
/* Create empty file */
|
||||
char filename[100];
|
||||
sprintf(filename, "controllerPak_file_%d.sav", freeFileIndex);
|
||||
pak.file.open(filename, std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc);
|
||||
|
||||
file_size_in_bytes = (file_size_in_bytes + 31) & ~31;
|
||||
|
||||
char* zero_block = (char*) malloc(file_size_in_bytes);
|
||||
for (size_t i = 0; i < file_size_in_bytes; i++) {
|
||||
zero_block[i] = 0;
|
||||
}
|
||||
|
||||
pak.file.seekp(0, std::ios::beg);
|
||||
pak.file.write(zero_block, file_size_in_bytes);
|
||||
|
||||
free(zero_block);
|
||||
|
||||
pak.file.close();
|
||||
|
||||
*file_no = freeFileIndex;
|
||||
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsFileState(OSPfs* pfs, s32 file_no, OSPfsState* state) {
|
||||
u32 file_size = 0;
|
||||
u32 game_code = 0;
|
||||
u16 company_code = 0;
|
||||
char ext_name[EXT_NAME_SIZE] = { 0 };
|
||||
char game_name[GAME_NAME_SIZE] = { 0 };
|
||||
|
||||
// should pass the state of the requested file_no to the incoming state pointer,
|
||||
// games call this function 16 times, once per file
|
||||
// fills the incoming state with the information inside the header of the pak.
|
||||
|
||||
char filename[100];
|
||||
sprintf(filename, "controllerPak_file_%d.sav", file_no);
|
||||
if (!std::filesystem::exists(filename)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
/* Read game info from pak */
|
||||
if (!Pfs_PakHeader_Read(&file_size, &game_code, &company_code, ext_name, game_name, file_no)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
state->file_size = file_size;
|
||||
state->company_code = game_code;
|
||||
state->game_code = game_code;
|
||||
|
||||
for (size_t j = 0; j < GAME_NAME_SIZE; j++) {
|
||||
state->game_name[j] = game_name[j];
|
||||
}
|
||||
for (size_t j = 0; j < EXT_NAME_SIZE; j++) {
|
||||
state->ext_name[j] = ext_name[j];
|
||||
}
|
||||
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsFindFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name, u8* ext_name, s32* file_no) {
|
||||
ControllerPak pak;
|
||||
|
||||
for (size_t i = 0; i < MAX_FILES; i++) {
|
||||
u32 file_size_ = 0;
|
||||
u32 game_code_ = 0;
|
||||
u16 company_code_ = 0;
|
||||
char ext_name_[EXT_NAME_SIZE] = { 0 };
|
||||
char game_name_[GAME_NAME_SIZE] = { 0 };
|
||||
|
||||
if (!Pfs_PakHeader_Read(&file_size_, &game_code_, &company_code_, ext_name_, game_name_, i)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
if ((company_code_ == 0) || (game_code_ == 0)) {
|
||||
continue;
|
||||
} else {
|
||||
if ((game_code == game_code_) && (company_code == company_code_) &&
|
||||
(strcmp((const char*) game_name, (const char*) game_name_) == 0) &&
|
||||
strcmp((const char*) ext_name, (const char*) ext_name_) == 0) {
|
||||
// File found
|
||||
*file_no = i;
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// File not found
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, int offset, int size_in_bytes, u8* data_buffer) {
|
||||
ControllerPak pak;
|
||||
|
||||
char filename[100];
|
||||
sprintf(filename, "controllerPak_file_%d.sav", file_no);
|
||||
pak.file.open(filename, std::ios::binary | std::ios::in | std::ios::out);
|
||||
|
||||
if (!std::filesystem::exists(filename)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
if (!pak.file.good()) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
if (!pak.file.is_open()) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (flag == 0) {
|
||||
pak.file.seekg(offset, std::ios::beg);
|
||||
pak.file.read((char*) data_buffer, size_in_bytes);
|
||||
} else {
|
||||
pak.file.seekp(offset, std::ios::beg);
|
||||
pak.file.write((char*) data_buffer, size_in_bytes);
|
||||
}
|
||||
|
||||
pak.file.close();
|
||||
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsNumFiles(OSPfs* pfs, s32* max_files, s32* files_used) {
|
||||
u8 files = 0;
|
||||
for (size_t i = 0; i < MAX_FILES; i++) {
|
||||
u32 file_size = 0;
|
||||
u32 game_code = 0;
|
||||
u16 company_code = 0;
|
||||
char ext_name[EXT_NAME_SIZE] = { 0 };
|
||||
char game_name[GAME_NAME_SIZE] = { 0 };
|
||||
|
||||
if (!Pfs_PakHeader_Read(&file_size, &game_code, &company_code, ext_name, game_name, i)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
if ((company_code != 0) || (game_code != 0)) {
|
||||
files++;
|
||||
}
|
||||
}
|
||||
|
||||
*files_used = files;
|
||||
*max_files = MAX_FILES;
|
||||
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
extern "C" s32 osPfsDeleteFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name, u8* ext_name) {
|
||||
if (company_code == 0 || game_code == 0) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
ControllerPak pak;
|
||||
|
||||
for (int i = 0; i < MAX_FILES; i++) {
|
||||
u32 file_size_ = 0;
|
||||
u32 game_code_ = 0;
|
||||
u16 company_code_ = 0;
|
||||
char ext_name_[4] = { 0 };
|
||||
char game_name_[16] = { 0 };
|
||||
|
||||
if (!Pfs_PakHeader_Read(&file_size_, &game_code_, &company_code_, ext_name_, game_name_, i)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
if ((company_code_ == 0) || (game_code_ == 0)) {
|
||||
continue;
|
||||
} else {
|
||||
if ((game_code == game_code_) && (strcmp((const char*) game_name, (const char*) game_name_) == 0) &&
|
||||
strcmp((const char*) ext_name, (const char*) ext_name_) == 0) {
|
||||
// File found
|
||||
|
||||
pak.header.open("controllerPak_header.sav", std::ios::binary | std::ios::in | std::ios::out);
|
||||
|
||||
if (!pak.header.good()) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
if (!pak.header.is_open()) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
u32 seek = i * sizeof(OSPfsState);
|
||||
|
||||
// Zero out the header for this file.
|
||||
u8* zero_block = (u8*) malloc(sizeof(OSPfsState));
|
||||
for (size_t i = 0; i < sizeof(OSPfsState); i++) {
|
||||
zero_block[i] = 0;
|
||||
}
|
||||
pak.header.seekp(seek + 0x0, std::ios::beg);
|
||||
pak.header.write((char*) zero_block, sizeof(OSPfsState));
|
||||
|
||||
free(zero_block);
|
||||
|
||||
pak.header.close();
|
||||
|
||||
char filename[100];
|
||||
sprintf(filename, "controllerPak_file_%d.sav", i);
|
||||
remove(filename);
|
||||
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// File not found
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
@@ -115,6 +115,10 @@ void PortMenu::AddSettings() {
|
||||
.Tooltip("Changes the Theme of the Menu Widgets.")
|
||||
.ComboMap(menuThemeOptions)
|
||||
.DefaultIndex(Colors::LightBlue));
|
||||
AddWidget(path, "Controller pak screen", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar("gControllerPakScreen")
|
||||
.Options(CheckboxOptions().Tooltip(
|
||||
"Enables the Controller Pak screen when starting the game."));
|
||||
#if not defined(__SWITCH__) and not defined(__WIIU__)
|
||||
AddWidget(path, "Menu Controller Navigation", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_IMGUI_CONTROLLER_NAV)
|
||||
|
||||
+19
-26
@@ -33,7 +33,9 @@ s8 sControllerPak2State = BAD;
|
||||
// default time trial records in little endian form
|
||||
const u8 D_800F2E60[4] = { 0xc0, 0x27, 0x09, 0x00 };
|
||||
// osPfsFindFile -> gGameName ("MARIOKART64" in nosFont)
|
||||
const u8 gGameName[] = "MARIOKART64";
|
||||
const u8 gGameName[] = {
|
||||
0x26, 0x1a, 0x2b, 0x22, 0x28, 0x24, 0x1a, 0x2b, 0x2d, 0x16, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
// ext_name param to osPfsFindFile (four total bytes, but only one is setable)
|
||||
const u8 gExtCode[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
@@ -747,9 +749,10 @@ u8 func_800B60E8(s32 page, u8* data) {
|
||||
u8* addr;
|
||||
|
||||
for (i = 0, addr = (u8*) &(data)[page * 256]; i < 256; i++) {
|
||||
checksum += (*addr++ * (page + 1) + i);
|
||||
checksum += ((*addr++ * (page + 1)) + i);
|
||||
}
|
||||
return checksum;
|
||||
u8 checksumByte = checksum % 256;
|
||||
return checksumByte;
|
||||
}
|
||||
|
||||
s32 func_800B6178(s32 arg0) {
|
||||
@@ -777,8 +780,8 @@ s32 func_800B6178(s32 arg0) {
|
||||
}
|
||||
} else {
|
||||
var_v0 =
|
||||
osPfsReadWriteFile(&gControllerPak1FileHandle, gControllerPak1FileNote, 1U,
|
||||
(arg0 * (sizeof(u8) * 0x1000)) + 0x100, sizeof(u8) * 0x1000, (u8*) sReplayGhostBuffer);
|
||||
osPfsReadWriteFile(&gControllerPak1FileHandle, gControllerPak1FileNote, PFS_WRITE,
|
||||
(arg0 * (sizeof(u8) * 0x10000)) + 0x100, sizeof(u8) * 0x10000, (u8*) sReplayGhostBuffer);
|
||||
if (var_v0 == 0) {
|
||||
temp_s3->ghostDataSaved = 1;
|
||||
if (gGamestate == 4) {
|
||||
@@ -860,35 +863,25 @@ s32 func_800B63F0(s32 arg0) {
|
||||
s32 func_800B64EC(s32 arg0) {
|
||||
s32 temp_s0;
|
||||
s32 temp_v0;
|
||||
u8* phi_s1;
|
||||
|
||||
if ((arg0 != 0) && (arg0 != 1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sPlayerGhostReplay = (u32*) &D_802BFB80.arraySize8[0][D_80162DC8][3];
|
||||
temp_v0 =
|
||||
osPfsReadWriteFile(&gControllerPak1FileHandle, gControllerPak1FileNote, PFS_READ,
|
||||
(arg0 * (sizeof(u8) * 0x1000)) + 0x100, sizeof(u8) * 0x1000, (u8*) sPlayerGhostReplay);
|
||||
temp_v0 = osPfsReadWriteFile(&gControllerPak1FileHandle, gControllerPak1FileNote, PFS_READ,
|
||||
(arg0 * (sizeof(u8) * 0x10000)) + 0x100, sizeof(u8) * 0x10000, (u8*) sPlayerGhostReplay);
|
||||
if (temp_v0 == 0) {
|
||||
// clang-format off
|
||||
phi_s1 = (u8 *) &D_8018EE10[arg0]; temp_s0 = 0; while (1) {
|
||||
// clang-format on
|
||||
|
||||
if (phi_s1[7] != func_800B60E8(temp_s0, (u8*) sPlayerGhostReplay)) {
|
||||
for (int i = 0; i < 0x3C; i++) {
|
||||
if (D_8018EE10[arg0].unk_07[i] != func_800B60E8(i, (u8*) sPlayerGhostReplay)) {
|
||||
D_8018EE10[arg0].ghostDataSaved = 0;
|
||||
return -2;
|
||||
}
|
||||
|
||||
++phi_s1;
|
||||
if ((++temp_s0) == 0x3C) {
|
||||
func_8000522C();
|
||||
bPlayerGhostDisabled = 0;
|
||||
D_80162DE0 = (s32) D_8018EE10[arg0].characterId;
|
||||
D_80162DFC = D_8018EE10[arg0].unk_00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
func_8000522C();
|
||||
bPlayerGhostDisabled = 0;
|
||||
D_80162DE0 = (s32) D_8018EE10[arg0].characterId;
|
||||
D_80162DFC = D_8018EE10[arg0].unk_00;
|
||||
}
|
||||
|
||||
return temp_v0;
|
||||
@@ -907,8 +900,8 @@ s32 func_800B65F4(s32 arg0, s32 arg1) {
|
||||
return -1;
|
||||
}
|
||||
writeStatus =
|
||||
osPfsReadWriteFile(&gControllerPak2FileHandle, gControllerPak2FileNote, 0U,
|
||||
(arg0 * (sizeof(u8) * 0x1000)) + 0x100, sizeof(u8) * 0x1000, (u8*) sReplayGhostBuffer);
|
||||
osPfsReadWriteFile(&gControllerPak2FileHandle, gControllerPak2FileNote, PFS_READ,
|
||||
(arg0 * (sizeof(u8) * 0x10000)) + 0x100, sizeof(u8) * 0x10000, (u8*) sReplayGhostBuffer);
|
||||
if (writeStatus == 0) {
|
||||
temp_s3 = &((struct_8018EE10_entry*) gSomeDLBuffer)[arg0];
|
||||
for (i = 0; i < 0x3C; i++) {
|
||||
@@ -974,7 +967,7 @@ u8 func_800B68F4(s32 arg0) {
|
||||
checksum = 0;
|
||||
for (i = 0; i < 0x43; i++) {
|
||||
u8* addr = &((u8*) gSomeDLBuffer)[arg0];
|
||||
checksum += addr[i] * multiplier + i;
|
||||
checksum += (addr[i] * multiplier) + i;
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
|
||||
-81
@@ -63,84 +63,3 @@ void osSpTaskYield(void) {
|
||||
|
||||
OSYieldResult osSpTaskYielded(OSTask* task) {
|
||||
}
|
||||
|
||||
s32 osPfsDeleteFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name, u8* ext_name) {
|
||||
char filename[1024];
|
||||
sprintf(filename, "channel_%d_%hu_%hd_%s.sav", pfs->channel, company_code, game_code, game_name);
|
||||
remove(filename);
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, int offset, int size_in_bytes, u8* data_buffer) {
|
||||
if (flag == PFS_READ) {
|
||||
fseek(openFile[file_no].file, offset, SEEK_SET);
|
||||
fread(data_buffer, size_in_bytes, 1, openFile[file_no].file);
|
||||
} else {
|
||||
fseek(openFile[file_no].file, offset, SEEK_SET);
|
||||
fwrite(data_buffer, size_in_bytes, 1, openFile[file_no].file);
|
||||
}
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
s32 osPfsAllocateFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name, u8* ext_name, int file_size_in_bytes,
|
||||
s32* file_no) {
|
||||
char filename[1024];
|
||||
sprintf(filename, "channel_%d_%hu_%hd_%s.sav", pfs->channel, company_code, game_code, game_name);
|
||||
*file_no = fileIndex++;
|
||||
openFile[*file_no].file = fopen(filename, "w+");
|
||||
fwrite("\0", 1, file_size_in_bytes, openFile[*file_no].file);
|
||||
openFile[*file_no].state.company_code = company_code;
|
||||
openFile[*file_no].state.game_code = game_code;
|
||||
strcpy(openFile[*file_no].state.game_name, game_name);
|
||||
strcpy(openFile[*file_no].state.ext_name, ext_name);
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
s32 osPfsIsPlug(OSMesgQueue* queue, u8* pattern) {
|
||||
*pattern = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 osPfsInit(OSMesgQueue* queue, OSPfs* pfs, int channel) {
|
||||
pfs->queue = queue;
|
||||
pfs->channel = channel;
|
||||
pfs->status = 0;
|
||||
pfs->status |= PFS_INITIALIZED;
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
s32 osPfsNumFiles(OSPfs* pfs, s32* max_files, s32* files_used) {
|
||||
*max_files = 16;
|
||||
*files_used = fileIndex;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 osPfsFileState(OSPfs* pfs, s32 file_no, OSPfsState* state) {
|
||||
}
|
||||
|
||||
s32 osPfsFreeBlocks(OSPfs* pfs, s32* bytes_not_used) {
|
||||
*bytes_not_used = 0x1000;
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
s32 osPfsFindFile(OSPfs* pfs, u16 company_code, u32 game_code, u8* game_name, u8* ext_name, s32* file_no) {
|
||||
char filename[1024];
|
||||
sprintf(filename, "channel_%d_%hu_%hd_%s.sav", pfs->channel, company_code, game_code, game_name);
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
if (openFile[i].state.game_code == game_code && openFile[i].state.company_code == company_code &&
|
||||
strcmp(openFile[i].state.game_name, game_name) == 0 && strcmp(openFile[i].state.ext_name, ext_name) == 0) {
|
||||
*file_no = i;
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
}
|
||||
*file_no = fileIndex++;
|
||||
openFile[*file_no].file = fopen(filename, "r+");
|
||||
if (openFile[*file_no].file == NULL) {
|
||||
openFile[*file_no].file = fopen(filename, "w+");
|
||||
}
|
||||
openFile[*file_no].state.company_code = company_code;
|
||||
openFile[*file_no].state.game_code = game_code;
|
||||
strcpy(openFile[*file_no].state.game_name, game_name);
|
||||
strcpy(openFile[*file_no].state.ext_name, ext_name);
|
||||
return PFS_NO_ERROR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user