#include #include "constants.h" #include "game/filelist.h" #include "game/game_0b3350.h" #include "game/savebuffer.h" #include "game/menu.h" #include "game/filemgr.h" #include "game/bossfile.h" #include "game/game_1531a0.h" #include "game/gamefile.h" #include "game/lang.h" #include "game/mplayer/mplayer.h" #include "game/pak/pak.h" #include "game/utils.h" #include "bss.h" #include "lib/vi.h" #include "lib/mema.h" #include "lib/str.h" #include "data.h" #include "types.h" // bss struct fileguid g_FilemgrFileToCopy; struct fileguid var800a21e8; struct fileguid g_FilemgrFileToDelete; #if VERSION == VERSION_JPN_FINAL u8 jpnfill3[0x18]; #endif s32 g_FilemgrLastPakError; #if VERSION == VERSION_JPN_FINAL u8 jpnfill4[8]; #endif struct gamefile g_GameFile; u32 var800a22bc; struct fileguid g_GameFileGuid; // These might be able to be removed by relocating their symbols struct menudialogdef g_FilemgrCopyMenuDialog; struct menudialogdef g_FilemgrConfirmDeleteMenuDialog; struct menudialogdef g_FilemgrDeleteMenuDialog; struct menudialogdef g_FilemgrEnterNameMenuDialog; struct menudialogdef g_FilemgrErrorMenuDialog; struct menudialogdef g_FilemgrFileInUseMenuDialog; struct menudialogdef g_FilemgrFileLostMenuDialog; struct menudialogdef g_FilemgrFileSavedMenuDialog; struct menudialogdef g_FilemgrFileSelectMenuDialog; struct menudialogdef g_FilemgrSaveElsewhereMenuDialog; struct menudialogdef g_FilemgrSaveErrorMenuDialog; struct menudialogdef g_FilemgrSelectLocationMenuDialog; struct menudialogdef g_PakDeleteNoteMenuDialog; struct menudialogdef g_PakGameNotesMenuDialog; struct menudialogdef g_PakNotOriginalMenuDialog; struct pakdata *g_EditingPak; #if VERSION >= VERSION_NTSC_1_0 struct menudialogdef g_FilemgrDuplicateNameMenuDialog; struct menudialogdef g_FilemgrRenameMenuDialog; #endif #if PAL s32 func0f1088d0pf(s32 operation, struct menuitem *item, union handlerdata *data); #if VERSION >= VERSION_PAL_FINAL GLOBAL_ASM( glabel func0f1088d0pf /* f1088d0: 27bdffe8 */ addiu $sp,$sp,-24 /* f1088d4: 24010006 */ li $at,0x6 /* f1088d8: afbf0014 */ sw $ra,0x14($sp) /* f1088dc: 14810009 */ bne $a0,$at,.PF0f108904 /* f1088e0: afa60020 */ sw $a2,0x20($sp) /* f1088e4: 90ae0001 */ lbu $t6,0x1($a1) /* f1088e8: 3c02800a */ lui $v0,0x800a /* f1088ec: 2442a510 */ addiu $v0,$v0,-23280 /* f1088f0: a44e0482 */ sh $t6,0x482($v0) /* f1088f4: 0fc5bdd7 */ jal langSetEuropean /* f1088f8: 31c4ffff */ andi $a0,$t6,0xffff /* f1088fc: 0fc3cf8c */ jal menuPopDialog /* f108900: 00000000 */ nop .PF0f108904: /* f108904: 8fbf0014 */ lw $ra,0x14($sp) /* f108908: 27bd0018 */ addiu $sp,$sp,0x18 /* f10890c: 00001025 */ move $v0,$zero /* f108910: 03e00008 */ jr $ra /* f108914: 00000000 */ nop ); #else GLOBAL_ASM( glabel func0f1088d0pf /* f108630: 27bdffe8 */ addiu $sp,$sp,-24 /* f108634: 24010006 */ li $at,0x6 /* f108638: afbf0014 */ sw $ra,0x14($sp) /* f10863c: 14810009 */ bne $a0,$at,.PB0f108664 /* f108640: afa60020 */ sw $a2,0x20($sp) /* f108644: 90ae0001 */ lbu $t6,0x1($a1) /* f108648: 3c02800a */ lui $v0,0x800a /* f10864c: 2442e4d0 */ addiu $v0,$v0,-6960 /* f108650: a44e0482 */ sh $t6,0x482($v0) /* f108654: 0fc5c097 */ jal langSetEuropean /* f108658: 31c4ffff */ andi $a0,$t6,0xffff /* f10865c: 0fc3cf12 */ jal menuPopDialog /* f108660: 00000000 */ nop .PB0f108664: /* f108664: 8fbf0014 */ lw $ra,0x14($sp) /* f108668: 27bd0018 */ addiu $sp,$sp,0x18 /* f10866c: 00001025 */ move $v0,$zero /* f108670: 03e00008 */ jr $ra /* f108674: 00000000 */ nop ); #endif struct menuitem g_ChooseLanguageMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00004010, L_MPWEAPONS_261, 0x00000000, 0x00000000 }, // "Choose your language:" { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { MENUITEMTYPE_SELECTABLE, LANGUAGE_PAL_EN, 0x00000020, L_MPWEAPONS_262, 0x00000000, func0f1088d0pf }, // "English" { MENUITEMTYPE_SELECTABLE, LANGUAGE_PAL_FR, 0x00000020, L_MPWEAPONS_263, 0x00000000, func0f1088d0pf }, // "French" { MENUITEMTYPE_SELECTABLE, LANGUAGE_PAL_DE, 0x00000020, L_MPWEAPONS_264, 0x00000000, func0f1088d0pf }, // "German" { MENUITEMTYPE_SELECTABLE, LANGUAGE_PAL_IT, 0x00000020, L_MPWEAPONS_265, 0x00000000, func0f1088d0pf }, // "Italian" { MENUITEMTYPE_SELECTABLE, LANGUAGE_PAL_ES, 0x00000020, L_MPWEAPONS_266, 0x00000000, func0f1088d0pf }, // "Spanish" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, }; struct menudialogdef g_ChooseLanguageMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_095, g_ChooseLanguageMenuItems, NULL, MENUDIALOGFLAG_IGNOREBACK, NULL, }; #endif char *filemgrGetDeviceName(s32 index) { u16 names[] = { L_OPTIONS_112, // "Controller Pak 1" L_OPTIONS_113, // "Controller Pak 2" L_OPTIONS_114, // "Controller Pak 3" L_OPTIONS_115, // "Controller Pak 4" L_OPTIONS_111, // "Game Pak" #if VERSION >= VERSION_NTSC_1_0 L_MPWEAPONS_229, // "Controller Pak Not Found" #endif }; if (index < ARRAYCOUNT(names)) { return langGet(names[index]); } return NULL; } s32 filemgrDeviceNameMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_CHECKHIDDEN) { if ((g_Menus[g_MpPlayerNum].fm.device1 & 0x7f) >= SAVEDEVICE_INVALID) { return true; } } return 0; } char *filemgrMenuTextDeviceName(struct menuitem *item) { return filemgrGetDeviceName(g_Menus[g_MpPlayerNum].fm.device1 & 0x7f); } void filemgrGetSelectName(char *buffer, struct filelistfile *file, u32 filetype) { s32 days; char tmpbuffer1[28]; char namebuffer[20]; u32 totalinseconds; s32 pos; s32 hours; s32 minutes; s32 seconds; s32 totalinhours; switch (filetype) { case FILETYPE_GAME: case FILETYPE_MPSETUP: func0f0d564c(file->name, tmpbuffer1, false); break; case FILETYPE_MPPLAYER: // MP Player filenames have the play duration appended to the name mpplayerfileGetOverview(file->name, namebuffer, &totalinseconds); pos = sprintf(tmpbuffer1, "%s-", namebuffer); if (totalinseconds >= 0x7ffffff) { // about 4.25 years sprintf(tmpbuffer1 + pos, "==:=="); } else { seconds = totalinseconds % 60; totalinseconds = totalinseconds / 60; totalinhours = totalinseconds / 60; minutes = totalinseconds % 60; days = totalinhours / 24; hours = totalinhours % 24; if (days == 0) { // seconds is passed but has no placeholder sprintf(tmpbuffer1 + pos, "%d:%02d", hours, minutes, seconds); } else { sprintf(tmpbuffer1 + pos, "%d:%02d:%02d", days, hours, minutes); } } break; } sprintf(buffer, "%s\n", tmpbuffer1); } #if VERSION >= VERSION_NTSC_1_0 const char var7f1b2f28[] = "Setup: item = %x\n"; #endif // game, mpsetup, mpplayer, perfect head const u32 g_FileTypeSizes[] = {0xa0, 0x31, 0x4e, 0x4a0}; s32 filemgrFileNameMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_CHECKHIDDEN) { if (g_Menus[g_MpPlayerNum].fm.filetodelete == 0) { return true; } } return 0; } char *filemgrMenuTextDeleteFileName(struct menuitem *item) { if (g_Menus[g_MpPlayerNum].fm.filetodelete) { filemgrGetSelectName(g_StringPointer, g_Menus[g_MpPlayerNum].fm.filetodelete, g_Menus[g_MpPlayerNum].fm.filetypetodelete); return g_StringPointer; } return NULL; } void filemgrSetDevice1BySerial(s32 deviceserial) { s32 device = pakFindBySerial(deviceserial); if (device >= 0) { g_Menus[g_MpPlayerNum].fm.device1 = device; } else { #if VERSION >= VERSION_NTSC_1_0 g_Menus[g_MpPlayerNum].fm.device1 = SAVEDEVICE_INVALID; #else g_Menus[g_MpPlayerNum].fm.device1 = 0x7f; #endif } } void filemgrSetDevice1ByFile(struct filelistfile *file) { filemgrSetDevice1BySerial(file->deviceserial); } void filemgrSetFileToDelete(struct filelistfile *file, s32 filetype) { g_Menus[g_MpPlayerNum].fm.filetypetodelete = filetype; g_Menus[g_MpPlayerNum].fm.filetodelete = file; filemgrSetDevice1ByFile(file); } char *filemgrMenuTextFailReason(struct menuitem *item) { static u16 reasons[] = { L_OPTIONS_322, // "The Controller Pak was not found in any controller." L_OPTIONS_323, // "File was not saved." L_OPTIONS_324, // "File would not load." L_OPTIONS_325, // "Could not delete the file." L_OPTIONS_326, // "Out of memory." L_OPTIONS_327, // "This player is already loaded for this game." L_OPTIONS_328, // "has been removed." L_OPTIONS_329, // "Controller Pak is damaged or incorrectly inserted." L_OPTIONS_330, // "Game note delete failed." }; return langGet(reasons[g_Menus[g_MpPlayerNum].fm.errno]); } /** * Unused. */ char *filemgr0f108484(struct menuitem *item) { sprintf(g_StringPointer, "location: controller pak 1\n"); return g_StringPointer; } s32 filemgrDeviceNameForErrorMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_CHECKHIDDEN) { if ((g_Menus[g_MpPlayerNum].fm.device1 & 0x7f) >= SAVEDEVICE_INVALID) { return true; } switch (g_Menus[g_MpPlayerNum].fm.errno) { case FILEERROR_OUTOFMEMORY: case FILEERROR_ALREADYLOADED: case FILEERROR_PAKDAMAGED: default: return true; case FILEERROR_SAVEFAILED: case FILEERROR_LOADFAILED: case FILEERROR_DELETEFAILED: case FILEERROR_PAKREMOVED: case FILEERROR_DELETENOTEFAILED: break; } } return false; } char *filemgrMenuTextDeviceNameForError(struct menuitem *item) { sprintf(g_StringPointer, "%s", filemgrGetDeviceName(g_Menus[g_MpPlayerNum].fm.device1 & 0x7f)); if (g_Menus[g_MpPlayerNum].fm.errno != FILEERROR_PAKREMOVED) { s32 i = 0; while (g_StringPointer[i] != '\0') { i++; } g_StringPointer[i - 1] = ':'; g_StringPointer[i] = '\n'; g_StringPointer[i + 1] = '\0'; } return g_StringPointer; } #if VERSION >= VERSION_NTSC_1_0 const char var7f1b2f6c[] = "FileMan: Failure Handler\n"; const char var7f1b2f88[] = "Copy Memory Freed\n"; const char var7f1b2f9c[] = "FileMan: Success Handler\n"; const char var7f1b2fb8[] = "Copy Memory Freed\n"; const char var7f1b2fcc[] = ">> block read going write, target file is %x-%x\n"; const char var7f1b3000[] = "SaveElsewhere\n"; const char var7f1b3010[] = "DELETING: %x-%x\n"; const char var7f1b3024[] = "MyResult: %d\n"; const char var7f1b3034[] = "PakOperationSearch>> Search for pak: %x = %d\n"; #endif void filemgrPushErrorDialog(u16 errno) { g_Menus[g_MpPlayerNum].fm.errno = errno; menuPushDialog(&g_FilemgrErrorMenuDialog); } struct menuitem g_FilemgrErrorMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextDeviceNameForError, 0x00000000, filemgrDeviceNameForErrorMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextFailReason, 0x00000000, NULL }, { MENUITEMTYPE_SELECTABLE, 0, 0x00000028, L_OPTIONS_321, 0x00000000, NULL }, // "Cancel" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrErrorMenuDialog = { MENUDIALOGTYPE_DANGER, L_OPTIONS_320, // "Error" g_FilemgrErrorMenuItems, NULL, MENUDIALOGFLAG_DISABLEBANNER, NULL, }; /** * For a file listing, iterate the devices until the one at optionindex is found. * Depending on operation, return the device name or index of the first file. */ s32 filemgrGetDeviceNameOrStartIndex(s32 listnum, s32 operation, s32 optionindex) { u16 names[] = { L_OPTIONS_111, // "Game Pak" L_OPTIONS_112, // "Controller Pak 1" L_OPTIONS_113, // "Controller Pak 2" L_OPTIONS_114, // "Controller Pak 3" L_OPTIONS_115, // "Controller Pak 4" }; s32 i; s32 remaining = optionindex; for (i = 0; i < ARRAYCOUNT(names); i++) { if (g_FileLists[listnum]->devicestartindexes[i] != -1) { if (remaining == 0) { if (operation == MENUOP_GETOPTGROUPTEXT) { return (s32)langGet(names[i]); } return g_FileLists[listnum]->devicestartindexes[i]; } remaining--; } } return 0; } char *filemgrMenuTextErrorTitle(struct menuitem *item) { u16 messages[] = { L_OPTIONS_331, // "Error Loading Game" L_OPTIONS_332, // "Error Saving Game" L_OPTIONS_333, // "Error Loading Player" L_OPTIONS_334, // "Error Saving Player" L_OPTIONS_335, // "Error Loading PerfectHead" L_OPTIONS_336, // "Error Saving PerfectHead" L_OPTIONS_337, // "Error Reading File" L_OPTIONS_338, // "Error Writing File" L_OPTIONS_339, // "Error" }; switch (g_Menus[g_MpPlayerNum].fm.fileop) { case FILEOP_LOAD_GAME: case FILEOP_LOAD_MPSETUP: return langGet(messages[0]); case FILEOP_SAVE_GAME_000: case FILEOP_SAVE_GAME_001: case FILEOP_SAVE_GAME_002: case FILEOP_SAVE_MPSETUP: return langGet(messages[1]); case FILEOP_LOAD_MPPLAYER: return langGet(messages[2]); case FILEOP_SAVE_MPPLAYER: return langGet(messages[3]); case FILEOP_READ_GAME: case FILEOP_READ_MPSETUP: case FILEOP_READ_MPPLAYER: return langGet(messages[6]); case FILEOP_WRITE_GAME: case FILEOP_WRITE_MPSETUP: case FILEOP_WRITE_MPPLAYER: return langGet(messages[7]); } return langGet(messages[8]); } #if VERSION >= VERSION_NTSC_1_0 char *filemgrMenuTextFileType(struct menuitem *item) { u16 names[] = { L_OPTIONS_103, // "Single Player Agent File" L_OPTIONS_104, // "Combat Simulator Settings File" L_OPTIONS_105, // "Combat Simulator Player File" L_OPTIONS_106, // "PerfectHead Files" }; switch (g_Menus[g_MpPlayerNum].fm.fileop) { case FILEOP_SAVE_GAME_000: case FILEOP_SAVE_GAME_001: case FILEOP_SAVE_GAME_002: case FILEOP_WRITE_GAME: case FILEOP_LOAD_GAME: case FILEOP_READ_GAME: return langGet(names[0]); case FILEOP_SAVE_MPSETUP: case FILEOP_WRITE_MPSETUP: case FILEOP_LOAD_MPSETUP: case FILEOP_READ_MPSETUP: return langGet(names[1]); case FILEOP_SAVE_MPPLAYER: case FILEOP_WRITE_MPPLAYER: case FILEOP_LOAD_MPPLAYER: case FILEOP_READ_MPPLAYER: return langGet(names[2]); } return langGet(names[0]); } #endif void func0f10898c(void) { menuSetBanner(-1, false); switch (g_Menus[g_MpPlayerNum].fm.fileop) { case FILEOP_WRITE_GAME: case FILEOP_WRITE_MPSETUP: case FILEOP_WRITE_MPPLAYER: case FILEOP_READ_GAME: case FILEOP_READ_MPSETUP: case FILEOP_READ_MPPLAYER: memaFree(g_Menus[g_MpPlayerNum].fm.unke44, align16(g_FileTypeSizes[g_Menus[g_MpPlayerNum].fm.filetypeplusone - 1])); break; case FILEOP_LOAD_GAME: case FILEOP_LOAD_MPPLAYER: case FILEOP_LOAD_MPSETUP: case FILEOP_103: case FILEOP_SAVE_GAME_000: case FILEOP_SAVE_GAME_001: case FILEOP_SAVE_GAME_002: case FILEOP_SAVE_MPPLAYER: case FILEOP_SAVE_MPSETUP: case FILEOP_005: break; } } void filemgrHandleSuccess(void) { menuSetBanner(-1, false); switch (g_Menus[g_MpPlayerNum].fm.fileop) { case FILEOP_WRITE_GAME: case FILEOP_WRITE_MPSETUP: case FILEOP_WRITE_MPPLAYER: memaFree(g_Menus[g_MpPlayerNum].fm.unke44, align16(g_FileTypeSizes[g_Menus[g_MpPlayerNum].fm.filetypeplusone - 1])); break; case FILEOP_LOAD_GAME: g_Vars.bossfileid = g_Menus[g_MpPlayerNum].fm.fileid; g_Vars.bossdeviceserial = g_Menus[g_MpPlayerNum].fm.deviceserial; bossfileSave(); if (IS4MB()) { func0f0f820c(&g_MainMenu4MbMenuDialog, MENUROOT_4MBMAINMENU); } else { func0f0f820c(&g_CiMenuViaPcMenuDialog, MENUROOT_MAINMENU); } break; case FILEOP_READ_GAME: case FILEOP_READ_MPSETUP: case FILEOP_READ_MPPLAYER: filemgrSaveOrLoad(&var800a21e8, g_Menus[g_MpPlayerNum].fm.fileop - 98, g_Menus[g_MpPlayerNum].fm.mpplayernum); break; case FILEOP_SAVE_GAME_000: case FILEOP_SAVE_GAME_001: case FILEOP_SAVE_GAME_002: case FILEOP_SAVE_MPPLAYER: case FILEOP_SAVE_MPSETUP: case FILEOP_005: case FILEOP_LOAD_MPPLAYER: case FILEOP_LOAD_MPSETUP: case FILEOP_103: break; } } s32 filemgrRetrySaveMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { filemgrRetrySave(2); } return 0; } s32 filemgrSaveElsewhereYesMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { s32 filetype; menuCloseDialog(); switch (g_Menus[g_MpPlayerNum].fm.fileop) { case FILEOP_SAVE_GAME_000: case FILEOP_SAVE_GAME_001: case FILEOP_SAVE_GAME_002: case FILEOP_WRITE_GAME: filetype = FILETYPE_GAME; break; case FILEOP_SAVE_MPPLAYER: case FILEOP_WRITE_MPPLAYER: filetype = FILETYPE_MPPLAYER; break; case FILEOP_SAVE_MPSETUP: case FILEOP_WRITE_MPSETUP: filetype = FILETYPE_MPSETUP; break; } filemgrPushSelectLocationDialog(g_Menus[g_MpPlayerNum].fm.fileop + 9, filetype); } return 0; } s32 filemgrCancelSave2MenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { menuCloseDialog(); func0f10898c(); menuUpdateCurFrame(); } return 0; } /** * Unused. */ s32 filemgr0f108d14(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { filemgrRetrySave(2); } return 0; } s32 filemgrAcknowledgeFileLostMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { menuCloseDialog(); func0f10898c(); menuUpdateCurFrame(); } return 0; } #if VERSION >= VERSION_NTSC_1_0 void filemgrEraseCorruptFile(void) { s32 device; s32 i; device = pakFindBySerial(g_Menus[g_MpPlayerNum].fm.deviceserial); if (device >= 0) { pakDeleteFile(device, g_Menus[g_MpPlayerNum].fm.fileid); } for (i = 0; i < 4; i++) { if (g_FileLists[i]) { g_FileLists[i]->timeuntilupdate = 1; } } menuPushDialog(&g_FilemgrFileLostMenuDialog); } #endif s32 filemgrInsertOriginalPakMenuDialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data) { if (operation == MENUOP_TICK) { if (g_Menus[g_MpPlayerNum].curdialog && g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef) { filemgrRetrySave(0); } } return false; } s32 filemgrReinsertedOkMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { pakExecuteDebugOperations(); filemgrRetrySave(1); } return 0; } s32 filemgrReinsertedCancelMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { if (FILEOP_IS_SAVE(g_Menus[g_MpPlayerNum].fm.fileop) && g_Menus[g_MpPlayerNum].fm.fileop != FILEOP_SAVE_GAME_001) { func0f0f3704(&g_FilemgrSaveElsewhereMenuDialog); } else { menuPopDialog(); } } return 0; } #if VERSION >= VERSION_NTSC_1_0 char *filemgrMenuTextInsertOriginalPak(struct menuitem *item) { char fullbuffer[100]; char namebuffer[100]; s32 i; sprintf(namebuffer, filemgrMenuTextFileType(item)); // Replace first line break in namebuffer with a terminator i = 0; while (namebuffer[i] != '\0') { if (namebuffer[i] == '\n') { namebuffer[i] = '\0'; } else { i++; } } // "Please insert the Controller Pak containing your %s into any controller." sprintf(fullbuffer, langGet(L_OPTIONS_363), namebuffer); textWrap(120, fullbuffer, g_StringPointer, g_CharsHandelGothicSm, g_FontHandelGothicSm); return g_StringPointer; } #endif /** * Context is: * 0 on tick while reinsert dialog is open * 1 when user selects OK on reinsert dialog * 2 when user selects Retry Save on error dialog */ void filemgrRetrySave(s32 context) { s32 device = pakFindBySerial(g_Menus[g_MpPlayerNum].fm.deviceserial); if (device == -1) { if (context == 1) { filemgrPushErrorDialog(FILEERROR_NOPAK); } if (context == 2) { func0f0f3704(&g_PakNotOriginalMenuDialog); } } else if (filemgrAttemptOperation(device, true)) { if (context == 2) { g_Menus[g_MpPlayerNum].fm.device1 = device; if (FILEOP_IS_SAVE(g_Menus[g_MpPlayerNum].fm.fileop)) { filemgrPushErrorDialog(FILEERROR_SAVEFAILED); } else { filemgrPushErrorDialog(FILEERROR_LOADFAILED); } } else { filemgrSetDevice1BySerial(g_Menus[g_MpPlayerNum].fm.deviceserial); if (FILEOP_IS_SAVE(g_Menus[g_MpPlayerNum].fm.fileop)) { func0f0f3704(&g_FilemgrSaveErrorMenuDialog); } else { #if VERSION >= VERSION_NTSC_1_0 filemgrEraseCorruptFile(); #else func0f0f3704(&g_FilemgrFileLostMenuDialog); #endif } } } } #if VERSION >= VERSION_NTSC_1_0 bool filemgrAttemptOperation(s32 device, bool closeonsuccess) { s32 errno = 0; bool showfilesaved = (g_Menus[g_MpPlayerNum].fm.isretryingsave & 1) != 0; const s32 filetypes[] = { PAKFILETYPE_GAME, PAKFILETYPE_MPSETUP, PAKFILETYPE_MPPLAYER, PAKFILETYPE_CAMERA, }; s32 newfileid; switch (g_Menus[g_MpPlayerNum].fm.fileop) { case FILEOP_SAVE_GAME_002: showfilesaved = true; // fall through case FILEOP_SAVE_GAME_000: case FILEOP_SAVE_GAME_001: errno = gamefileSave(device, g_Menus[g_MpPlayerNum].fm.fileid, g_Menus[g_MpPlayerNum].fm.deviceserial); break; case FILEOP_SAVE_MPPLAYER: errno = mpplayerfileSave( (s32) g_Menus[g_MpPlayerNum].fm.unke44, device, g_Menus[g_MpPlayerNum].fm.fileid, g_Menus[g_MpPlayerNum].fm.deviceserial); break; case FILEOP_SAVE_MPSETUP: errno = mpsetupfileSave(device, g_Menus[g_MpPlayerNum].fm.fileid, g_Menus[g_MpPlayerNum].fm.deviceserial); showfilesaved = true; break; case FILEOP_WRITE_GAME: case FILEOP_WRITE_MPSETUP: case FILEOP_WRITE_MPPLAYER: newfileid = 0; func0f0d5690(g_Menus[g_MpPlayerNum].fm.unke44, g_Menus[g_MpPlayerNum].fm.filename); errno = pakSaveAtGuid(device, g_Menus[g_MpPlayerNum].fm.fileid, filetypes[g_Menus[g_MpPlayerNum].fm.fileop - 6], g_Menus[g_MpPlayerNum].fm.unke44, &newfileid, NULL); var80075bd0[g_Menus[g_MpPlayerNum].fm.fileop - 6] = 1; break; case FILEOP_LOAD_GAME: errno = gamefileLoad(device); break; case FILEOP_LOAD_MPPLAYER: errno = mpplayerfileLoad( (s32) g_Menus[g_MpPlayerNum].fm.unke44, device, g_Menus[g_MpPlayerNum].fm.fileid, g_Menus[g_MpPlayerNum].fm.deviceserial); break; case FILEOP_LOAD_MPSETUP: errno = mpsetupfileLoad(device, g_Menus[g_MpPlayerNum].fm.fileid, g_Menus[g_MpPlayerNum].fm.deviceserial); break; case FILEOP_READ_GAME: case FILEOP_READ_MPSETUP: case FILEOP_READ_MPPLAYER: errno = pakReadBodyAtGuid(device, g_Menus[g_MpPlayerNum].fm.fileid, g_Menus[g_MpPlayerNum].fm.unke44, 0); break; } if (errno == 0 && closeonsuccess) { menuCloseDialog(); } if (FILEOP_IS_SAVE(g_Menus[g_MpPlayerNum].fm.fileop)) { if (errno == 0) { filemgrHandleSuccess(); } if (showfilesaved && errno == 0) { menuPushDialog(&g_FilemgrFileSavedMenuDialog); } } else { if (errno == 0) { filemgrHandleSuccess(); } } menuUpdateCurFrame(); return errno; } #else const s32 var7f1ad258nb[] = {0x80, 0x40, 0x20, 0x08}; GLOBAL_ASM( glabel filemgrAttemptOperation .late_rodata glabel var7f1ad3e8nb .word filemgrAttemptOperation+0x1a8 glabel var7f1ad3ecnb .word filemgrAttemptOperation+0x1b8 glabel var7f1ad3f0nb .word filemgrAttemptOperation+0x1d4 glabel var7f1ad3f4nb .word filemgrAttemptOperation+0x210 glabel var7f1ad3f8nb .word filemgrAttemptOperation+0x1ec glabel var7f1ad3fcnb .word filemgrAttemptOperation+0x1ec glabel var7f1ad400nb .word filemgrAttemptOperation+0x1ec glabel var7f1ad404nb .word filemgrAttemptOperation+0x0dc glabel var7f1ad408nb .word filemgrAttemptOperation+0x0dc glabel var7f1ad40cnb .word filemgrAttemptOperation+0x0d4 glabel var7f1ad410nb .word filemgrAttemptOperation+0x0f4 glabel var7f1ad414nb .word filemgrAttemptOperation+0x110 glabel var7f1ad418nb .word filemgrAttemptOperation+0x210 glabel var7f1ad41cnb .word filemgrAttemptOperation+0x130 glabel var7f1ad420nb .word filemgrAttemptOperation+0x130 glabel var7f1ad424nb .word filemgrAttemptOperation+0x130 .text /* f104a8c: 3c0e8007 */ lui $t6,0x8007 /* f104a90: 8dce3af0 */ lw $t6,0x3af0($t6) /* f104a94: 3c18800a */ lui $t8,0x800a /* f104a98: 271827c0 */ addiu $t8,$t8,0x27c0 /* f104a9c: 000e78c0 */ sll $t7,$t6,0x3 /* f104aa0: 01ee7823 */ subu $t7,$t7,$t6 /* f104aa4: 000f78c0 */ sll $t7,$t7,0x3 /* f104aa8: 01ee7823 */ subu $t7,$t7,$t6 /* f104aac: 000f7900 */ sll $t7,$t7,0x4 /* f104ab0: 01ee7823 */ subu $t7,$t7,$t6 /* f104ab4: 000f7880 */ sll $t7,$t7,0x2 /* f104ab8: 01f81021 */ addu $v0,$t7,$t8 /* f104abc: 94590dac */ lhu $t9,0xdac($v0) /* f104ac0: 27bdffb8 */ addiu $sp,$sp,-72 /* f104ac4: 3c0c7f1b */ lui $t4,0x7f1b /* f104ac8: 332a0001 */ andi $t2,$t9,0x1 /* f104acc: 000a582b */ sltu $t3,$zero,$t2 /* f104ad0: afbf001c */ sw $ra,0x1c($sp) /* f104ad4: afa40048 */ sw $a0,0x48($sp) /* f104ad8: afa5004c */ sw $a1,0x4c($sp) /* f104adc: afab0040 */ sw $t3,0x40($sp) /* f104ae0: 258cd258 */ addiu $t4,$t4,-11688 /* f104ae4: 8d810000 */ lw $at,0x0($t4) /* f104ae8: 27a90030 */ addiu $t1,$sp,0x30 /* f104aec: 90480d9e */ lbu $t0,0xd9e($v0) /* f104af0: ad210000 */ sw $at,0x0($t1) /* f104af4: 8d8f0004 */ lw $t7,0x4($t4) /* f104af8: 01001825 */ or $v1,$t0,$zero /* f104afc: 00003025 */ or $a2,$zero,$zero /* f104b00: ad2f0004 */ sw $t7,0x4($t1) /* f104b04: 8d810008 */ lw $at,0x8($t4) /* f104b08: 2478ff9c */ addiu $t8,$v1,-100 /* f104b0c: ad210008 */ sw $at,0x8($t1) /* f104b10: 8d8f000c */ lw $t7,0xc($t4) /* f104b14: 29010009 */ slti $at,$t0,0x9 /* f104b18: 14200009 */ bnez $at,.NB0f104b40 /* f104b1c: ad2f000c */ sw $t7,0xc($t1) /* f104b20: 2f010007 */ sltiu $at,$t8,0x7 /* f104b24: 1020005d */ beqz $at,.NB0f104c9c /* f104b28: 0018c080 */ sll $t8,$t8,0x2 /* f104b2c: 3c017f1b */ lui $at,0x7f1b /* f104b30: 00380821 */ addu $at,$at,$t8 /* f104b34: 8c38d3e8 */ lw $t8,-0x2c18($at) /* f104b38: 03000008 */ jr $t8 /* f104b3c: 00000000 */ sll $zero,$zero,0x0 .NB0f104b40: /* f104b40: 2c610009 */ sltiu $at,$v1,0x9 /* f104b44: 10200055 */ beqz $at,.NB0f104c9c /* f104b48: 0003c880 */ sll $t9,$v1,0x2 /* f104b4c: 3c017f1b */ lui $at,0x7f1b /* f104b50: 00390821 */ addu $at,$at,$t9 /* f104b54: 8c39d404 */ lw $t9,-0x2bfc($at) /* f104b58: 03200008 */ jr $t9 /* f104b5c: 00000000 */ sll $zero,$zero,0x0 /* f104b60: 240a0001 */ addiu $t2,$zero,0x1 /* f104b64: afaa0040 */ sw $t2,0x40($sp) /* f104b68: 8fa40048 */ lw $a0,0x48($sp) /* f104b6c: 8c450da4 */ lw $a1,0xda4($v0) /* f104b70: 0fc428e0 */ jal gamefileSave /* f104b74: 94460daa */ lhu $a2,0xdaa($v0) /* f104b78: 10000048 */ beqz $zero,.NB0f104c9c /* f104b7c: 00403025 */ or $a2,$v0,$zero /* f104b80: 8c440da0 */ lw $a0,0xda0($v0) /* f104b84: 8fa50048 */ lw $a1,0x48($sp) /* f104b88: 8c460da4 */ lw $a2,0xda4($v0) /* f104b8c: 0fc61f00 */ jal mpplayerfileSave /* f104b90: 94470daa */ lhu $a3,0xdaa($v0) /* f104b94: 10000041 */ beqz $zero,.NB0f104c9c /* f104b98: 00403025 */ or $a2,$v0,$zero /* f104b9c: 8fa40048 */ lw $a0,0x48($sp) /* f104ba0: 8c450da4 */ lw $a1,0xda4($v0) /* f104ba4: 0fc62178 */ jal mpsetupfileSave /* f104ba8: 94460daa */ lhu $a2,0xdaa($v0) /* f104bac: 240b0001 */ addiu $t3,$zero,0x1 /* f104bb0: 00403025 */ or $a2,$v0,$zero /* f104bb4: 10000039 */ beqz $zero,.NB0f104c9c /* f104bb8: afab0040 */ sw $t3,0x40($sp) /* f104bbc: 00087080 */ sll $t6,$t0,0x2 /* f104bc0: afa0002c */ sw $zero,0x2c($sp) /* f104bc4: 012e6821 */ addu $t5,$t1,$t6 /* f104bc8: 8da6ffe8 */ lw $a2,-0x18($t5) /* f104bcc: 27ac002c */ addiu $t4,$sp,0x2c /* f104bd0: afac0010 */ sw $t4,0x10($sp) /* f104bd4: afa00014 */ sw $zero,0x14($sp) /* f104bd8: 83a4004b */ lb $a0,0x4b($sp) /* f104bdc: 8c450da4 */ lw $a1,0xda4($v0) /* f104be0: 0fc442fb */ jal pakSaveAtGuid /* f104be4: 8c470da0 */ lw $a3,0xda0($v0) /* f104be8: 3c188007 */ lui $t8,0x8007 /* f104bec: 8f183af0 */ lw $t8,0x3af0($t8) /* f104bf0: 3c0a800a */ lui $t2,0x800a /* f104bf4: 3c018007 */ lui $at,0x8007 /* f104bf8: 0018c8c0 */ sll $t9,$t8,0x3 /* f104bfc: 0338c823 */ subu $t9,$t9,$t8 /* f104c00: 0019c8c0 */ sll $t9,$t9,0x3 /* f104c04: 0338c823 */ subu $t9,$t9,$t8 /* f104c08: 0019c900 */ sll $t9,$t9,0x4 /* f104c0c: 0338c823 */ subu $t9,$t9,$t8 /* f104c10: 0019c880 */ sll $t9,$t9,0x2 /* f104c14: 01595021 */ addu $t2,$t2,$t9 /* f104c18: 914a355e */ lbu $t2,0x355e($t2) /* f104c1c: 240f0001 */ addiu $t7,$zero,0x1 /* f104c20: 00403025 */ or $a2,$v0,$zero /* f104c24: 000a5880 */ sll $t3,$t2,0x2 /* f104c28: 002b0821 */ addu $at,$at,$t3 /* f104c2c: 1000001b */ beqz $zero,.NB0f104c9c /* f104c30: ac2f7f58 */ sw $t7,0x7f58($at) /* f104c34: 0fc427fe */ jal gamefileLoad /* f104c38: 8fa40048 */ lw $a0,0x48($sp) /* f104c3c: 10000017 */ beqz $zero,.NB0f104c9c /* f104c40: 00403025 */ or $a2,$v0,$zero /* f104c44: 8c440da0 */ lw $a0,0xda0($v0) /* f104c48: 8fa50048 */ lw $a1,0x48($sp) /* f104c4c: 8c460da4 */ lw $a2,0xda4($v0) /* f104c50: 0fc61f31 */ jal mpplayerfileLoad /* f104c54: 94470daa */ lhu $a3,0xdaa($v0) /* f104c58: 10000010 */ beqz $zero,.NB0f104c9c /* f104c5c: 00403025 */ or $a2,$v0,$zero /* f104c60: 8fa40048 */ lw $a0,0x48($sp) /* f104c64: 8c450da4 */ lw $a1,0xda4($v0) /* f104c68: 0fc621a2 */ jal mpsetupfileLoad /* f104c6c: 94460daa */ lhu $a2,0xdaa($v0) /* f104c70: 1000000a */ beqz $zero,.NB0f104c9c /* f104c74: 00403025 */ or $a2,$v0,$zero /* f104c78: 00087080 */ sll $t6,$t0,0x2 /* f104c7c: 3c077f1b */ lui $a3,0x7f1b /* f104c80: 00ee3821 */ addu $a3,$a3,$t6 /* f104c84: 8ce7d088 */ lw $a3,-0x2f78($a3) /* f104c88: 83a4004b */ lb $a0,0x4b($sp) /* f104c8c: 8c450da4 */ lw $a1,0xda4($v0) /* f104c90: 0fc442f1 */ jal pakReadBodyAtGuid /* f104c94: 8c460da0 */ lw $a2,0xda0($v0) /* f104c98: 00403025 */ or $a2,$v0,$zero .NB0f104c9c: /* f104c9c: 14c00006 */ bnez $a2,.NB0f104cb8 /* f104ca0: 8fad004c */ lw $t5,0x4c($sp) /* f104ca4: 11a00004 */ beqz $t5,.NB0f104cb8 /* f104ca8: 00000000 */ sll $zero,$zero,0x0 /* f104cac: 0fc3bfcf */ jal menuCloseDialog /* f104cb0: afa60044 */ sw $a2,0x44($sp) /* f104cb4: 8fa60044 */ lw $a2,0x44($sp) .NB0f104cb8: /* f104cb8: 3c0c8007 */ lui $t4,0x8007 /* f104cbc: 8d8c3af0 */ lw $t4,0x3af0($t4) /* f104cc0: 3c19800a */ lui $t9,0x800a /* f104cc4: 000cc0c0 */ sll $t8,$t4,0x3 /* f104cc8: 030cc023 */ subu $t8,$t8,$t4 /* f104ccc: 0018c0c0 */ sll $t8,$t8,0x3 /* f104cd0: 030cc023 */ subu $t8,$t8,$t4 /* f104cd4: 0018c100 */ sll $t8,$t8,0x4 /* f104cd8: 030cc023 */ subu $t8,$t8,$t4 /* f104cdc: 0018c080 */ sll $t8,$t8,0x2 /* f104ce0: 0338c821 */ addu $t9,$t9,$t8 /* f104ce4: 9339355e */ lbu $t9,0x355e($t9) /* f104ce8: 2b210064 */ slti $at,$t9,0x64 /* f104cec: 10200010 */ beqz $at,.NB0f104d30 /* f104cf0: 00000000 */ sll $zero,$zero,0x0 /* f104cf4: 54c00005 */ bnezl $a2,.NB0f104d0c /* f104cf8: 8faa0040 */ lw $t2,0x40($sp) /* f104cfc: 0fc41127 */ jal filemgrHandleSuccess /* f104d00: afa60044 */ sw $a2,0x44($sp) /* f104d04: 8fa60044 */ lw $a2,0x44($sp) /* f104d08: 8faa0040 */ lw $t2,0x40($sp) .NB0f104d0c: /* f104d0c: 1140000d */ beqz $t2,.NB0f104d44 /* f104d10: 00000000 */ sll $zero,$zero,0x0 /* f104d14: 14c0000b */ bnez $a2,.NB0f104d44 /* f104d18: 3c048007 */ lui $a0,0x8007 /* f104d1c: 248469d4 */ addiu $a0,$a0,0x69d4 /* f104d20: 0fc3beda */ jal menuPushDialog /* f104d24: afa60044 */ sw $a2,0x44($sp) /* f104d28: 10000006 */ beqz $zero,.NB0f104d44 /* f104d2c: 8fa60044 */ lw $a2,0x44($sp) .NB0f104d30: /* f104d30: 14c00004 */ bnez $a2,.NB0f104d44 /* f104d34: 00000000 */ sll $zero,$zero,0x0 /* f104d38: 0fc41127 */ jal filemgrHandleSuccess /* f104d3c: afa60044 */ sw $a2,0x44($sp) /* f104d40: 8fa60044 */ lw $a2,0x44($sp) .NB0f104d44: /* f104d44: 0fc3c058 */ jal menuUpdateCurFrame /* f104d48: afa60044 */ sw $a2,0x44($sp) /* f104d4c: 8fbf001c */ lw $ra,0x1c($sp) /* f104d50: 8fa20044 */ lw $v0,0x44($sp) /* f104d54: 27bd0048 */ addiu $sp,$sp,0x48 /* f104d58: 03e00008 */ jr $ra /* f104d5c: 00000000 */ sll $zero,$zero,0x0 ); #endif #if VERSION >= VERSION_NTSC_1_0 const char var7f1b3074[] = "FileAttemptOperation - pak %d op %d\n"; const char var7f1b309c[] = ">> blockWrite: file:%x pak:%x\n"; const char var7f1b30bc[] = ">> blockRead: file:%x pak:%x\n"; const char var7f1b30dc[] = "SUCCESS**->%d\n"; const char var7f1b30ec[] = "SUCCESS**->%d\n"; const char var7f1b30fc[] = ">>>>>>>>>>>>> FileWrite: type %d <<<<<<<<<<<<<<<\n"; const char var7f1b3130[] = "!!!!!!!!!!!! Wanted: %d\n"; const char var7f1b314c[] = "&&&&&&&&&&&&&&&&&&&&&&&&&&&PASSED**************\n"; const char var7f1b3180[] = "guid: %x gives pakno: %d\n"; const char var7f1b319c[] = "Invalidating pak %d\n"; const char var7f1b31b4[] = "YOUR TARGET: %x-%x\n"; const char var7f1b31c8[] = "MyResult: %d\n"; const char var7f1b31d8[] = "COULD NOT DELETE\n"; const char var7f1b31ec[] = "Multiplayer %d was using that file...\n"; #endif /** * Save or load the file with the specified GUID. * If saving, it's assumed that the file has been saved previously. * * fileop determines the type of file, as well as whether it's a save or load * operation. If set to -1, the previous fileop is reused (eg. for retry). * * playernum is used when working with MP player files, otherwise ignored. * * Return true if it worked, otherwise false. */ bool filemgrSaveOrLoad(struct fileguid *guid, s32 fileop, u32 playernum) { s32 device; if (fileop != -1) { // Common case - set new fileop g_Menus[g_MpPlayerNum].fm.fileop = fileop; g_Menus[g_MpPlayerNum].fm.mpplayernum = playernum; g_Menus[g_MpPlayerNum].fm.isretryingsave = 0; g_FilemgrLastPakError = 0; } g_Menus[g_MpPlayerNum].fm.fileid = guid->fileid; g_Menus[g_MpPlayerNum].fm.deviceserial = guid->deviceserial; if (fileop != -1) { // empty } device = pakFindBySerial(g_Menus[g_MpPlayerNum].fm.deviceserial); if (device == -1) { // Original pak is no longer connected g_Menus[g_MpPlayerNum].fm.isretryingsave |= 1; menuPushDialog(&g_PakNotOriginalMenuDialog); return false; } if (filemgrAttemptOperation(device, false) != 0) { // Operation failed g_Menus[g_MpPlayerNum].fm.isretryingsave |= 1; filemgrSetDevice1BySerial(g_Menus[g_MpPlayerNum].fm.deviceserial); if (FILEOP_IS_SAVE(g_Menus[g_MpPlayerNum].fm.fileop)) { menuPushDialog(&g_FilemgrSaveErrorMenuDialog); } else { // File couldn't be loaded #if VERSION >= VERSION_NTSC_1_0 filemgrEraseCorruptFile(); #else menuPushDialog(&g_FilemgrFileLostMenuDialog); #endif } return false; } return true; } #if VERSION >= VERSION_JPN_FINAL GLOBAL_ASM( glabel filemgrDeleteCurrentFile /* f109820: 27bdffd0 */ addiu $sp,$sp,-48 /* f109824: afb30024 */ sw $s3,0x24($sp) /* f109828: 3c138007 */ lui $s3,0x8007 /* f10982c: 26731998 */ addiu $s3,$s3,0x1998 /* f109830: 8e6e0000 */ lw $t6,0x0($s3) /* f109834: afb40028 */ sw $s4,0x28($sp) /* f109838: 3c14800a */ lui $s4,0x800a /* f10983c: 269428f0 */ addiu $s4,$s4,0x28f0 /* f109840: 000e78c0 */ sll $t7,$t6,0x3 /* f109844: afbf002c */ sw $ra,0x2c($sp) /* f109848: afb00018 */ sw $s0,0x18($sp) /* f10984c: 028fc021 */ addu $t8,$s4,$t7 /* f109850: afb20020 */ sw $s2,0x20($sp) /* f109854: afb1001c */ sw $s1,0x1c($sp) /* f109858: 00008025 */ move $s0,$zero /* f10985c: 0fc47aac */ jal pakFindBySerial /* f109860: 97040004 */ lhu $a0,0x4($t8) /* f109864: 00028e00 */ sll $s1,$v0,0x18 /* f109868: 0011ce03 */ sra $t9,$s1,0x18 /* f10986c: 0440000d */ bltz $v0,.JF0f1098a4 /* f109870: 03208825 */ move $s1,$t9 /* f109874: 8e690000 */ lw $t1,0x0($s3) /* f109878: 00192600 */ sll $a0,$t9,0x18 /* f10987c: 00044603 */ sra $t0,$a0,0x18 /* f109880: 000950c0 */ sll $t2,$t1,0x3 /* f109884: 028a5821 */ addu $t3,$s4,$t2 /* f109888: 8d650000 */ lw $a1,0x0($t3) /* f10988c: 0fc45b04 */ jal pakDeleteFile /* f109890: 01002025 */ move $a0,$t0 /* f109894: 50400005 */ beqzl $v0,.JF0f1098ac /* f109898: 8e6d0000 */ lw $t5,0x0($s3) /* f10989c: 10000002 */ b .JF0f1098a8 /* f1098a0: 24100001 */ li $s0,0x1 .JF0f1098a4: /* f1098a4: 24100001 */ li $s0,0x1 .JF0f1098a8: /* f1098a8: 8e6d0000 */ lw $t5,0x0($s3) .JF0f1098ac: /* f1098ac: 24030e70 */ li $v1,0xe70 /* f1098b0: 3c02800a */ lui $v0,0x800a /* f1098b4: 01a30019 */ multu $t5,$v1 /* f1098b8: 2442e700 */ addiu $v0,$v0,-6400 /* f1098bc: 3c088007 */ lui $t0,0x8007 /* f1098c0: 240c0001 */ li $t4,0x1 /* f1098c4: 24120004 */ li $s2,0x4 /* f1098c8: 00007012 */ mflo $t6 /* f1098cc: 004e7821 */ addu $t7,$v0,$t6 /* f1098d0: 91f80e3f */ lbu $t8,0xe3f($t7) /* f1098d4: 0018c880 */ sll $t9,$t8,0x2 /* f1098d8: 01194021 */ addu $t0,$t0,$t9 /* f1098dc: 8d0861b0 */ lw $t0,0x61b0($t0) /* f1098e0: 1200000a */ beqz $s0,.JF0f10990c /* f1098e4: a10c030c */ sb $t4,0x30c($t0) /* f1098e8: 8e690000 */ lw $t1,0x0($s3) /* f1098ec: 24040003 */ li $a0,0x3 /* f1098f0: 01230019 */ multu $t1,$v1 /* f1098f4: 00005012 */ mflo $t2 /* f1098f8: 004a5821 */ addu $t3,$v0,$t2 /* f1098fc: 0fc421f7 */ jal filemgrPushErrorDialog /* f109900: a1710e3c */ sb $s1,0xe3c($t3) /* f109904: 10000016 */ b .JF0f109960 /* f109908: 8fbf002c */ lw $ra,0x2c($sp) .JF0f10990c: /* f10990c: 3c11800b */ lui $s1,0x800b /* f109910: 2631d1e8 */ addiu $s1,$s1,-11800 /* f109914: 00008025 */ move $s0,$zero .JF0f109918: /* f109918: 8e6d0000 */ lw $t5,0x0($s3) /* f10991c: 8e38004c */ lw $t8,0x4c($s1) /* f109920: 000d70c0 */ sll $t6,$t5,0x3 /* f109924: 028e1021 */ addu $v0,$s4,$t6 /* f109928: 8c4f0000 */ lw $t7,0x0($v0) /* f10992c: 55f80009 */ bnel $t7,$t8,.JF0f109954 /* f109930: 26100001 */ addiu $s0,$s0,0x1 /* f109934: 94590004 */ lhu $t9,0x4($v0) /* f109938: 962c0050 */ lhu $t4,0x50($s1) /* f10993c: 02002025 */ move $a0,$s0 /* f109940: 572c0004 */ bnel $t9,$t4,.JF0f109954 /* f109944: 26100001 */ addiu $s0,$s0,0x1 /* f109948: 0fc621cb */ jal mpPlayerSetDefaults /* f10994c: 24050001 */ li $a1,0x1 /* f109950: 26100001 */ addiu $s0,$s0,0x1 .JF0f109954: /* f109954: 1612fff0 */ bne $s0,$s2,.JF0f109918 /* f109958: 263100a0 */ addiu $s1,$s1,0xa0 /* f10995c: 8fbf002c */ lw $ra,0x2c($sp) .JF0f109960: /* f109960: 8fb00018 */ lw $s0,0x18($sp) /* f109964: 8fb1001c */ lw $s1,0x1c($sp) /* f109968: 8fb20020 */ lw $s2,0x20($sp) /* f10996c: 8fb30024 */ lw $s3,0x24($sp) /* f109970: 8fb40028 */ lw $s4,0x28($sp) /* f109974: 03e00008 */ jr $ra /* f109978: 27bd0030 */ addiu $sp,$sp,0x30 ); #else void filemgrDeleteCurrentFile(void) { bool error = false; s8 device = pakFindBySerial(g_FilemgrFileToDelete.deviceserial); s32 i; if (device >= 0) { if (pakDeleteFile(device, g_FilemgrFileToDelete.fileid) != 0) { error = true; } } else { error = true; } g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->timeuntilupdate = 1; if (error) { g_Menus[g_MpPlayerNum].fm.device1 = device; filemgrPushErrorDialog(FILEERROR_DELETEFAILED); } else { // If deleting a loaded MP player, reset them to default for (i = 0; i < 4; i++) { if (g_FilemgrFileToDelete.fileid == g_PlayerConfigsArray[i].fileguid.fileid && g_FilemgrFileToDelete.deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) { mpPlayerSetDefaults(i, true); } } } } #endif struct menuitem g_FilemgrFileSavedMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_346, 0x00000000, NULL }, // "File Saved." { MENUITEMTYPE_SELECTABLE, 0, 0x00000028, L_OPTIONS_347, 0x00000000, NULL }, // "OK" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrFileSavedMenuDialog = { MENUDIALOGTYPE_SUCCESS, L_OPTIONS_345, // "Cool!" g_FilemgrFileSavedMenuItems, NULL, MENUDIALOGFLAG_DISABLEBANNER, NULL, }; struct menuitem g_FilemgrSaveErrorMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextDeviceName, 0x00000000, filemgrDeviceNameMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_348, 0x00000000, NULL }, // "An error occurred while trying to save" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_349, 0x00000000, filemgrRetrySaveMenuHandler }, // "Try Again" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_350, 0x00000000, filemgrSaveElsewhereYesMenuHandler }, // "Save Elsewhere" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_351, 0x00000000, filemgrCancelSave2MenuHandler }, // "Cancel" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrSaveErrorMenuDialog = { MENUDIALOGTYPE_DANGER, (u32)&filemgrMenuTextErrorTitle, g_FilemgrSaveErrorMenuItems, NULL, MENUDIALOGFLAG_IGNOREBACK | MENUDIALOGFLAG_DISABLEBANNER, NULL, }; struct menuitem g_FilemgrFileLostMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextDeviceName, 0x00000000, filemgrDeviceNameMenuHandler }, #if VERSION >= VERSION_NTSC_1_0 { MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPWEAPONS_251, 0x00000000, NULL }, // "The saved file has been erased due to corruption or damage." #else { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_352, 0x00000000, NULL }, // "An error occurred while trying to load." { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_353, 0x00000000, filemgr0f108d14 }, // "Try Again" #endif { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_354, 0x00000000, filemgrAcknowledgeFileLostMenuHandler }, // "Cancel" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrFileLostMenuDialog = { MENUDIALOGTYPE_DANGER, (u32)&filemgrMenuTextErrorTitle, g_FilemgrFileLostMenuItems, NULL, MENUDIALOGFLAG_IGNOREBACK | MENUDIALOGFLAG_DISABLEBANNER, NULL, }; struct menuitem g_FilemgrSaveElsewhereMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_360, 0x00000000, NULL }, // "Would you like to save your file elsewhere?" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_361, 0x00000000, filemgrSaveElsewhereYesMenuHandler }, // "Yes" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_362, 0x00000000, filemgrCancelSave2MenuHandler }, // "No" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrSaveElsewhereMenuDialog = { MENUDIALOGTYPE_DANGER, L_OPTIONS_359, // "Save" g_FilemgrSaveElsewhereMenuItems, NULL, MENUDIALOGFLAG_IGNOREBACK | MENUDIALOGFLAG_DISABLEBANNER, NULL, }; struct menuitem g_PakNotOriginalMenuItems[] = { #if VERSION >= VERSION_NTSC_1_0 { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextInsertOriginalPak, 0x00000000, NULL }, #else { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_363, 0x00000000, NULL }, #endif { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_365, 0x00000000, filemgrReinsertedOkMenuHandler }, // "OK" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_366, 0x00000000, filemgrReinsertedCancelMenuHandler }, // "Cancel" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_PakNotOriginalMenuDialog = { MENUDIALOGTYPE_DANGER, (u32)&filemgrMenuTextErrorTitle, g_PakNotOriginalMenuItems, filemgrInsertOriginalPakMenuDialog, MENUDIALOGFLAG_IGNOREBACK | MENUDIALOGFLAG_DISABLEBANNER, NULL, }; void func0f1097d0(s32 device) { char *typenames[] = {"GAM", "MPG", "MPP", "CAM"}; const u32 typecodes[] = {0x80, 0x40, 0x20, 0x08}; void *thing; if (g_FileLists[0]) { var800a21e8.fileid = g_FileLists[0]->deviceguids[device].fileid; var800a21e8.deviceserial = g_FileLists[0]->deviceguids[device].deviceserial; thing = memaAlloc(align16(g_FileTypeSizes[g_Menus[g_MpPlayerNum].fm.filetypeplusone - 1])); if (thing) { filemgrSaveOrLoad(&g_FilemgrFileToCopy, g_Menus[g_MpPlayerNum].fm.filetypeplusone + 103, (s32) thing); } else { filemgrPushErrorDialog(FILEERROR_OUTOFMEMORY); } var80075bd0[g_Menus[g_MpPlayerNum].fm.filetypeplusone - 1] = 1; } } #if VERSION >= VERSION_NTSC_1_0 const char var7f1b3234[] = "DestPakNo: %d (guid F:%x-%x:P)\n"; const char var7f1b3254[] = "Copy Memory Alloced\n"; const char var7f1b326c[] = "COULDNT GET THE RAM!\n"; const char var7f1b3284[] = "Saving...\n"; #endif void filemgrSaveGameToDevice(s32 device) { if (g_FileLists[0]) { g_GameFileGuid.fileid = g_FileLists[0]->deviceguids[device].fileid; g_GameFileGuid.deviceserial = g_FileLists[0]->deviceguids[device].deviceserial; filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_000, 0); } } #if VERSION >= VERSION_NTSC_1_0 void filemgrGetFileName(char *dst, struct filelistfile *file) { char localbuffer[20]; u32 playtime; localbuffer[0] = '\0'; switch (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->filetype) { case FILETYPE_GAME: case FILETYPE_MPSETUP: func0f0d564c(file->name, localbuffer, false); break; case FILETYPE_MPPLAYER: mpplayerfileGetOverview(file->name, localbuffer, &playtime); break; } sprintf(dst, "%s", localbuffer); } #endif #if VERSION >= VERSION_NTSC_1_0 const char var7f1b3294[] = "GETFileNameForThePurposesOfTheFileRenamingChecker: Unknown type %d\n"; void filemgrGetRenameName(char *buffer) { s32 i; s32 j; switch (g_Menus[g_MpPlayerNum].fm.unke3e) { case 0: case 9: case 10: case 11: strcpy(buffer, g_GameFile.name); break; case 1: case 2: case 3: case 4: case 15: case 16: case 17: strcpy(buffer, g_Menus[g_MpPlayerNum].fm.filename); break; case 6: case 12: i = 0; j = 0; while (g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] != '\0') { if (g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] != '\n') { buffer[j] = g_PlayerConfigsArray[g_MpPlayerNum].base.name[i]; j++; } i++; } buffer[j] = '\0'; break; case 7: case 13: strcpy(buffer, g_MpSetup.name); break; } } #endif #if VERSION >= VERSION_NTSC_1_0 void filemgrSetRenameName(char *name) { switch (g_Menus[g_MpPlayerNum].fm.unke3e) { case 0: case 9: case 10: case 11: strcpy(g_GameFile.name, name); break; case 1: case 2: case 3: case 4: case 15: case 16: case 17: strcpy(g_Menus[g_MpPlayerNum].fm.filename, name); break; case 6: case 12: sprintf(g_PlayerConfigsArray[g_MpPlayerNum].base.name, "%s\n", name); break; case 7: case 13: strcpy(g_MpSetup.name, name); break; } } const char var7f1b32dc[] = "SetFileNameForThePurposesOfTheFileRenamingChecker: Unknown type %d\n"; #endif #if VERSION >= VERSION_NTSC_1_0 bool filemgrIsNameAvailable(s32 device) { static u8 lookup[] = {1, 2, 3, 4, 0}; struct filelist *filelist; char findname[16]; s32 deviceindex; s32 startindex; s32 endindex; s32 i; s32 j; char loopname[16]; deviceindex = lookup[device]; filelist = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]; if (filelist == NULL) { return true; } // Determine which index to start searching at startindex = filelist->devicestartindexes[deviceindex]; if (startindex == -1) { return true; } // Determine which index to stop searching at // (ie. start of a new device or end of the list) endindex = filelist->numfiles; for (i = 4; i > deviceindex; i--) { if (filelist->devicestartindexes[i] != -1) { endindex = filelist->devicestartindexes[i]; } } // Get the filename to search for, make it uppercase and remove trailing line break. // @dangerous: findname can overflow if filemgrGetRenameName returns a long name. findname[0] = '\0'; filemgrGetRenameName(findname); for (j = 0; findname[j] != '\0';) { if (findname[j] >= 'a' && findname[j] <= 'z') { findname[j] -= 32; } if (findname[j] == '\n') { findname[j] = '\0'; } else { j++; } } osSyncPrintf("CheckFileName: Comparing range %d-%d\n", startindex, endindex); // Iterate files for (i = startindex; i < endindex; i++) { filemgrGetFileName(loopname, &g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->files[i]); // Convert loop filename to uppercase and remove trailing line break // @dangerous: loopname can overflow if filemgrGetFileName returns a long name. for (j = 0; loopname[j] != '\0';) { if (loopname[j] >= 'a' && loopname[j] <= 'z') { loopname[j] -= 32; } if (loopname[j] == '\n') { loopname[j] = '\0'; } else { j++; } } // Compare names osSyncPrintf("Compare '%s' to '%s' = %d\n", findname, loopname, strcmp(findname, loopname)); if (strcmp(findname, loopname) == 0) { osSyncPrintf("OI! DUPLICATE FILE NAME! NO!\n"); return false; } } return true; } #endif #if VERSION >= VERSION_NTSC_1_0 const char var7f1b3384[] = "()()()()()() Writing MPLAYER\n"; const char var7f1b33a4[] = "()()()()()() Writing MGAME\n"; const char var7f1b33c0[] = "Write Attempt Made...\n"; const char var7f1b33d8[] = "decided location: %d\n"; /** * Used for both saving new files and copying files. */ void filemgrSaveToDevice(void) { if (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->spacesfree[g_Menus[g_MpPlayerNum].fm.device2] > 0) { if (!filemgrIsNameAvailable(g_Menus[g_MpPlayerNum].fm.device2)) { menuPushDialog(&g_FilemgrDuplicateNameMenuDialog); } else { menuPopDialog(); if (g_Menus[g_MpPlayerNum].fm.unke3e == 0) { filemgrSaveGameToDevice(g_Menus[g_MpPlayerNum].fm.device2); } else if (g_Menus[g_MpPlayerNum].fm.unke3e == 5) { // empty } else if (g_Menus[g_MpPlayerNum].fm.unke3e == 6) { struct fileguid guid; guid.fileid = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->deviceguids[g_Menus[g_MpPlayerNum].fm.device2].fileid; guid.deviceserial = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->deviceguids[g_Menus[g_MpPlayerNum].fm.device2].deviceserial; filemgrSaveOrLoad(&guid, FILEOP_SAVE_MPPLAYER, (u32)g_MpPlayerNum); } else if (g_Menus[g_MpPlayerNum].fm.unke3e == 7) { struct fileguid guid; guid.fileid = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->deviceguids[g_Menus[g_MpPlayerNum].fm.device2].fileid; guid.deviceserial = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->deviceguids[g_Menus[g_MpPlayerNum].fm.device2].deviceserial; filemgrSaveOrLoad(&guid, FILEOP_SAVE_MPSETUP, 0); } else if (g_Menus[g_MpPlayerNum].fm.unke3e >= 9) { struct fileguid guid; guid.fileid = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->deviceguids[g_Menus[g_MpPlayerNum].fm.device2].fileid; guid.deviceserial = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->deviceguids[g_Menus[g_MpPlayerNum].fm.device2].deviceserial; filemgrSaveOrLoad(&guid, -1, 0); } else { func0f1097d0(g_Menus[g_MpPlayerNum].fm.device2); } } } } #endif #if VERSION >= VERSION_NTSC_1_0 s32 filemgrConfirmRenameMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { char *name = data->keyboard.string; switch (operation) { case MENUOP_GETTEXT: filemgrGetRenameName(name); break; case MENUOP_SETTEXT: filemgrSetRenameName(name); break; case MENUOP_SET: filemgrSaveToDevice(); break; } return 0; } #endif #if VERSION >= VERSION_NTSC_1_0 s32 filemgrDuplicateRenameMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { menuPopDialog(); menuPushDialog(&g_FilemgrRenameMenuDialog); } return 0; } #endif #if VERSION >= VERSION_NTSC_1_0 s32 filemgrDuplicateCancelMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { menuPopDialog(); menuPopDialog(); } return 0; } #endif #if VERSION >= VERSION_NTSC_1_0 char *filemgrMenuTextDeviceNameContainingDuplicateFile(struct menuitem *item) { return filemgrGetDeviceName(g_Menus[g_MpPlayerNum].fm.device2); } #endif #if VERSION >= VERSION_NTSC_1_0 char *filemgrMenuTextDuplicateFileName(struct menuitem *item) { char buffer[32]; filemgrGetRenameName(buffer); sprintf(g_StringPointer, "%s\n", buffer); return g_StringPointer; } #endif #if VERSION >= VERSION_NTSC_1_0 struct menuitem g_FilemgrRenameMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPWEAPONS_239, 0x00000000, NULL }, // "Enter new file name:" { MENUITEMTYPE_KEYBOARD, 0, 0x00000000, 0x00000000, 0x00000000, filemgrConfirmRenameMenuHandler }, { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrRenameMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_MPWEAPONS_238, // "Change File Name" g_FilemgrRenameMenuItems, NULL, MENUDIALOGFLAG_DISABLEBANNER, NULL, }; #endif #if VERSION >= VERSION_NTSC_1_0 struct menuitem g_FilemgrDuplicateMenuMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000030, (u32)&filemgrMenuTextDeviceNameContainingDuplicateFile, 0x00000000, NULL }, { MENUITEMTYPE_LABEL, 0, 0x02000030, L_MPWEAPONS_233, 0x00000000, NULL }, // "already contains" { MENUITEMTYPE_LABEL, 0, 0x02000030, L_MPWEAPONS_234, 0x00000000, NULL }, // "a file named" { MENUITEMTYPE_LABEL, 0, 0x02000030, (u32)&filemgrMenuTextDuplicateFileName, 0x00000000, NULL }, { MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPWEAPONS_235, 0x00000000, filemgrDuplicateRenameMenuHandler }, // "Rename File" { MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPWEAPONS_236, 0x00000000, NULL }, // "Change Location" { MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPWEAPONS_237, 0x00000000, filemgrDuplicateCancelMenuHandler }, // "Cancel" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrDuplicateNameMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_MPWEAPONS_232, // "Duplicate File Name" g_FilemgrDuplicateMenuMenuItems, NULL, MENUDIALOGFLAG_DISABLEBANNER, NULL, }; #endif #if VERSION >= VERSION_NTSC_1_0 char *filemgrMenuTextLocationName2(struct menuitem *item) { u16 names[] = { L_OPTIONS_112, // "Controller Pak 1" L_OPTIONS_113, // "Controller Pak 2" L_OPTIONS_114, // "Controller Pak 3" L_OPTIONS_115, // "Controller Pak 4" L_OPTIONS_111, // "Game Pak" L_OPTIONS_004, // "" }; if (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum] == NULL) { return NULL; } if (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->spacesfree[item->param] < 0) { return langGet(names[5]); } return langGet(names[item->param]); } #else u16 names[] = { L_OPTIONS_112, // "Controller Pak 1" L_OPTIONS_113, // "Controller Pak 2" L_OPTIONS_114, // "Controller Pak 3" L_OPTIONS_115, // "Controller Pak 4" L_OPTIONS_111, // "Game Pak" L_OPTIONS_004, // "" }; GLOBAL_ASM( glabel filemgrMenuTextLocationName2 /* f105228: 27bdffd0 */ addiu $sp,$sp,-48 /* f10522c: 3c0e8007 */ lui $t6,0x8007 /* f105230: afbf0014 */ sw $ra,0x14($sp) /* f105234: 25ce6bd8 */ addiu $t6,$t6,0x6bd8 /* f105238: 8dc10000 */ lw $at,0x0($t6) /* f10523c: 27a50024 */ addiu $a1,$sp,0x24 /* f105240: 3c088007 */ lui $t0,0x8007 /* f105244: aca10000 */ sw $at,0x0($a1) /* f105248: 8dd90004 */ lw $t9,0x4($t6) /* f10524c: 3c0a800a */ lui $t2,0x800a /* f105250: 3c028007 */ lui $v0,0x8007 /* f105254: acb90004 */ sw $t9,0x4($a1) /* f105258: 8dc10008 */ lw $at,0x8($t6) /* f10525c: aca10008 */ sw $at,0x8($a1) /* f105260: 8d083af0 */ lw $t0,0x3af0($t0) /* f105264: 000848c0 */ sll $t1,$t0,0x3 /* f105268: 01284823 */ subu $t1,$t1,$t0 /* f10526c: 000948c0 */ sll $t1,$t1,0x3 /* f105270: 01284823 */ subu $t1,$t1,$t0 /* f105274: 00094900 */ sll $t1,$t1,0x4 /* f105278: 01284823 */ subu $t1,$t1,$t0 /* f10527c: 00094880 */ sll $t1,$t1,0x2 /* f105280: 01495021 */ addu $t2,$t2,$t1 /* f105284: 914a355b */ lbu $t2,0x355b($t2) /* f105288: 000a5880 */ sll $t3,$t2,0x2 /* f10528c: 004b1021 */ addu $v0,$v0,$t3 /* f105290: 8c427f60 */ lw $v0,0x7f60($v0) /* f105294: 54400004 */ bnezl $v0,.NB0f1052a8 /* f105298: 90830001 */ lbu $v1,0x1($a0) /* f10529c: 1000000e */ beqz $zero,.NB0f1052d8 /* f1052a0: 00001025 */ or $v0,$zero,$zero /* f1052a4: 90830001 */ lbu $v1,0x1($a0) .NB0f1052a8: /* f1052a8: 00436021 */ addu $t4,$v0,$v1 /* f1052ac: 818d02d2 */ lb $t5,0x2d2($t4) /* f1052b0: 0003c040 */ sll $t8,$v1,0x1 /* f1052b4: 00b87821 */ addu $t7,$a1,$t8 /* f1052b8: 1da00005 */ bgtz $t5,.NB0f1052d0 /* f1052bc: 00000000 */ sll $zero,$zero,0x0 /* f1052c0: 0fc5a4dd */ jal langGet /* f1052c4: 97a4002e */ lhu $a0,0x2e($sp) /* f1052c8: 10000004 */ beqz $zero,.NB0f1052dc /* f1052cc: 8fbf0014 */ lw $ra,0x14($sp) .NB0f1052d0: /* f1052d0: 0fc5a4dd */ jal langGet /* f1052d4: 95e40000 */ lhu $a0,0x0($t7) .NB0f1052d8: /* f1052d8: 8fbf0014 */ lw $ra,0x14($sp) .NB0f1052dc: /* f1052dc: 27bd0030 */ addiu $sp,$sp,0x30 /* f1052e0: 03e00008 */ jr $ra /* f1052e4: 00000000 */ sll $zero,$zero,0x0 ); #endif char *filemgrMenuTextSaveLocationSpaces(struct menuitem *item) { s32 spacesfree; if (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum] == NULL) { return NULL; } spacesfree = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->spacesfree[item->param]; if (spacesfree < 0) { return "\n"; } if (spacesfree == 0) { return langGet(L_OPTIONS_372); // "Full" } sprintf(g_StringPointer, "%d", spacesfree); return g_StringPointer; } #if VERSION >= VERSION_NTSC_1_0 const char var7f1b33fc[] = "GOT OKed!, item->data = %d\n"; const char var7f1b3418[] = "GOT CANCELLED!\n"; const char var7f1b3428[] = "Picking Location, type %d wadtype %d wad %d\n"; const char var7f1b3458[] = "Torching file %d\n"; const char var7f1b346c[] = "Copying file %d\n"; const char var7f1b3480[] = "item: %x\n"; const char var7f1b348c[] = "Switched Wads Back\n"; const char var7f1b34a0[] = "MenuClosed\n"; const char var7f1b34ac[] = "Deleting files, wad %d\n"; #endif #if VERSION >= VERSION_NTSC_1_0 /** * item->param is a SAVEDEVICE constant. */ s32 filemgrSelectLocationMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum] == NULL) { return 0; } if (operation == MENUOP_CHECKDISABLED) { if (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->spacesfree[item->param] < 1) { return true; } } if (operation == MENUOP_SET) { g_Menus[g_MpPlayerNum].fm.device2 = item->param; filemgrSaveToDevice(); } return 0; } #else GLOBAL_ASM( glabel filemgrSelectLocationMenuHandler /* f1053a0: 3c0e8007 */ lui $t6,0x8007 /* f1053a4: 8dce3af0 */ lw $t6,0x3af0($t6) /* f1053a8: 3c18800a */ lui $t8,0x800a /* f1053ac: 3c098007 */ lui $t1,0x8007 /* f1053b0: 000e78c0 */ sll $t7,$t6,0x3 /* f1053b4: 01ee7823 */ subu $t7,$t7,$t6 /* f1053b8: 000f78c0 */ sll $t7,$t7,0x3 /* f1053bc: 01ee7823 */ subu $t7,$t7,$t6 /* f1053c0: 000f7900 */ sll $t7,$t7,0x4 /* f1053c4: 01ee7823 */ subu $t7,$t7,$t6 /* f1053c8: 000f7880 */ sll $t7,$t7,0x2 /* f1053cc: 030fc021 */ addu $t8,$t8,$t7 /* f1053d0: 9318355b */ lbu $t8,0x355b($t8) /* f1053d4: 25297f60 */ addiu $t1,$t1,0x7f60 /* f1053d8: 27bdffc0 */ addiu $sp,$sp,-64 /* f1053dc: 0018c880 */ sll $t9,$t8,0x2 /* f1053e0: 01395021 */ addu $t2,$t1,$t9 /* f1053e4: 8d420000 */ lw $v0,0x0($t2) /* f1053e8: afbf0014 */ sw $ra,0x14($sp) /* f1053ec: afa60048 */ sw $a2,0x48($sp) /* f1053f0: 14400003 */ bnez $v0,.NB0f105400 /* f1053f4: 00a03825 */ or $a3,$a1,$zero /* f1053f8: 1000006f */ beqz $zero,.NB0f1055b8 /* f1053fc: 00001025 */ or $v0,$zero,$zero .NB0f105400: /* f105400: 2401000c */ addiu $at,$zero,0xc /* f105404: 54810009 */ bnel $a0,$at,.NB0f10542c /* f105408: 24010006 */ addiu $at,$zero,0x6 /* f10540c: 90eb0001 */ lbu $t3,0x1($a3) /* f105410: 004b6021 */ addu $t4,$v0,$t3 /* f105414: 818d02d2 */ lb $t5,0x2d2($t4) /* f105418: 5da00004 */ bgtzl $t5,.NB0f10542c /* f10541c: 24010006 */ addiu $at,$zero,0x6 /* f105420: 10000065 */ beqz $zero,.NB0f1055b8 /* f105424: 24020001 */ addiu $v0,$zero,0x1 /* f105428: 24010006 */ addiu $at,$zero,0x6 .NB0f10542c: /* f10542c: 54810062 */ bnel $a0,$at,.NB0f1055b8 /* f105430: 00001025 */ or $v0,$zero,$zero /* f105434: 0fc3c088 */ jal menuPopDialog /* f105438: afa70044 */ sw $a3,0x44($sp) /* f10543c: 3c088007 */ lui $t0,0x8007 /* f105440: 8d083af0 */ lw $t0,0x3af0($t0) /* f105444: 3c0f800a */ lui $t7,0x800a /* f105448: 25ef27c0 */ addiu $t7,$t7,0x27c0 /* f10544c: 000870c0 */ sll $t6,$t0,0x3 /* f105450: 01c87023 */ subu $t6,$t6,$t0 /* f105454: 000e70c0 */ sll $t6,$t6,0x3 /* f105458: 01c87023 */ subu $t6,$t6,$t0 /* f10545c: 000e7100 */ sll $t6,$t6,0x4 /* f105460: 01c87023 */ subu $t6,$t6,$t0 /* f105464: 000e7080 */ sll $t6,$t6,0x2 /* f105468: 01cf1821 */ addu $v1,$t6,$t7 /* f10546c: 90620d9a */ lbu $v0,0xd9a($v1) /* f105470: 3c098007 */ lui $t1,0x8007 /* f105474: 25297f60 */ addiu $t1,$t1,0x7f60 /* f105478: 14400005 */ bnez $v0,.NB0f105490 /* f10547c: 8fa70044 */ lw $a3,0x44($sp) /* f105480: 0fc41475 */ jal filemgrSaveGameToDevice /* f105484: 90e40001 */ lbu $a0,0x1($a3) /* f105488: 1000004b */ beqz $zero,.NB0f1055b8 /* f10548c: 00001025 */ or $v0,$zero,$zero .NB0f105490: /* f105490: 24010005 */ addiu $at,$zero,0x5 /* f105494: 10410047 */ beq $v0,$at,.NB0f1055b4 /* f105498: 24010006 */ addiu $at,$zero,0x6 /* f10549c: 54410016 */ bnel $v0,$at,.NB0f1054f8 /* f1054a0: 24010007 */ addiu $at,$zero,0x7 /* f1054a4: 90780d9b */ lbu $t8,0xd9b($v1) /* f1054a8: 90eb0001 */ lbu $t3,0x1($a3) /* f1054ac: 27a40038 */ addiu $a0,$sp,0x38 /* f1054b0: 0018c880 */ sll $t9,$t8,0x2 /* f1054b4: 01395021 */ addu $t2,$t1,$t9 /* f1054b8: 8d420000 */ lw $v0,0x0($t2) /* f1054bc: 000b60c0 */ sll $t4,$t3,0x3 /* f1054c0: 24050003 */ addiu $a1,$zero,0x3 /* f1054c4: 004c6821 */ addu $t5,$v0,$t4 /* f1054c8: 8dae02d8 */ lw $t6,0x2d8($t5) /* f1054cc: 01003025 */ or $a2,$t0,$zero /* f1054d0: afae0038 */ sw $t6,0x38($sp) /* f1054d4: 90ef0001 */ lbu $t7,0x1($a3) /* f1054d8: 000fc0c0 */ sll $t8,$t7,0x3 /* f1054dc: 0058c821 */ addu $t9,$v0,$t8 /* f1054e0: 972a02dc */ lhu $t2,0x2dc($t9) /* f1054e4: 0fc41358 */ jal filemgrSaveOrLoad /* f1054e8: a7aa003c */ sh $t2,0x3c($sp) /* f1054ec: 10000032 */ beqz $zero,.NB0f1055b8 /* f1054f0: 00001025 */ or $v0,$zero,$zero /* f1054f4: 24010007 */ addiu $at,$zero,0x7 .NB0f1054f8: /* f1054f8: 54410016 */ bnel $v0,$at,.NB0f105554 /* f1054fc: 28410009 */ slti $at,$v0,0x9 /* f105500: 906b0d9b */ lbu $t3,0xd9b($v1) /* f105504: 90ee0001 */ lbu $t6,0x1($a3) /* f105508: 27a40030 */ addiu $a0,$sp,0x30 /* f10550c: 000b6080 */ sll $t4,$t3,0x2 /* f105510: 012c6821 */ addu $t5,$t1,$t4 /* f105514: 8da20000 */ lw $v0,0x0($t5) /* f105518: 000e78c0 */ sll $t7,$t6,0x3 /* f10551c: 24050004 */ addiu $a1,$zero,0x4 /* f105520: 004fc021 */ addu $t8,$v0,$t7 /* f105524: 8f1902d8 */ lw $t9,0x2d8($t8) /* f105528: 00003025 */ or $a2,$zero,$zero /* f10552c: afb90030 */ sw $t9,0x30($sp) /* f105530: 90ea0001 */ lbu $t2,0x1($a3) /* f105534: 000a58c0 */ sll $t3,$t2,0x3 /* f105538: 004b6021 */ addu $t4,$v0,$t3 /* f10553c: 958d02dc */ lhu $t5,0x2dc($t4) /* f105540: 0fc41358 */ jal filemgrSaveOrLoad /* f105544: a7ad0034 */ sh $t5,0x34($sp) /* f105548: 1000001b */ beqz $zero,.NB0f1055b8 /* f10554c: 00001025 */ or $v0,$zero,$zero /* f105550: 28410009 */ slti $at,$v0,0x9 .NB0f105554: /* f105554: 14200015 */ bnez $at,.NB0f1055ac /* f105558: 00000000 */ sll $zero,$zero,0x0 /* f10555c: 906e0d9b */ lbu $t6,0xd9b($v1) /* f105560: 90f90001 */ lbu $t9,0x1($a3) /* f105564: 27a40028 */ addiu $a0,$sp,0x28 /* f105568: 000e7880 */ sll $t7,$t6,0x2 /* f10556c: 012fc021 */ addu $t8,$t1,$t7 /* f105570: 8f020000 */ lw $v0,0x0($t8) /* f105574: 001950c0 */ sll $t2,$t9,0x3 /* f105578: 2405ffff */ addiu $a1,$zero,-1 /* f10557c: 004a5821 */ addu $t3,$v0,$t2 /* f105580: 8d6c02d8 */ lw $t4,0x2d8($t3) /* f105584: 00003025 */ or $a2,$zero,$zero /* f105588: afac0028 */ sw $t4,0x28($sp) /* f10558c: 90ed0001 */ lbu $t5,0x1($a3) /* f105590: 000d70c0 */ sll $t6,$t5,0x3 /* f105594: 004e7821 */ addu $t7,$v0,$t6 /* f105598: 95f802dc */ lhu $t8,0x2dc($t7) /* f10559c: 0fc41358 */ jal filemgrSaveOrLoad /* f1055a0: a7b8002c */ sh $t8,0x2c($sp) /* f1055a4: 10000004 */ beqz $zero,.NB0f1055b8 /* f1055a8: 00001025 */ or $v0,$zero,$zero .NB0f1055ac: /* f1055ac: 0fc41414 */ jal func0f1097d0 /* f1055b0: 90e40001 */ lbu $a0,0x1($a3) .NB0f1055b4: /* f1055b4: 00001025 */ or $v0,$zero,$zero .NB0f1055b8: /* f1055b8: 8fbf0014 */ lw $ra,0x14($sp) /* f1055bc: 27bd0040 */ addiu $sp,$sp,0x40 /* f1055c0: 03e00008 */ jr $ra /* f1055c4: 00000000 */ sll $zero,$zero,0x0 ); #endif s32 filemgrCancelSaveMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { menuPopDialog(); } return 0; } s32 filemgrDeleteFilesForSaveMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { filemgrPushDeleteFileDialog(g_Menus[g_MpPlayerNum].fm.listnum); g_Menus[g_MpPlayerNum].fm.isdeletingforsave = true; } return 0; } void filemgrPushSelectLocationDialog(s32 arg0, u32 filetype) { g_Menus[g_MpPlayerNum].fm.unke3e = arg0; g_Menus[g_MpPlayerNum].fm.listnum = filelistFindOrCreate(filetype); #if VERSION >= VERSION_NTSC_1_0 filelistsTick(); #endif menuPushDialog(&g_FilemgrSelectLocationMenuDialog); } #if VERSION >= VERSION_JPN_FINAL GLOBAL_ASM( glabel filemgrIsFileInUse /* f10a758: 27bdffe0 */ addiu $sp,$sp,-32 /* f10a75c: afb00018 */ sw $s0,0x18($sp) /* f10a760: 00808025 */ move $s0,$a0 /* f10a764: afbf001c */ sw $ra,0x1c($sp) /* f10a768: 3c048007 */ lui $a0,0x8007 /* f10a76c: 0fc3f89a */ jal menuIsDialogOpen /* f10a770: 24845024 */ addiu $a0,$a0,0x5024 /* f10a774: 1040000d */ beqz $v0,.JF0f10a7ac /* f10a778: 3c048007 */ lui $a0,0x8007 /* f10a77c: 3c02800a */ lui $v0,0x800a /* f10a780: 244228e0 */ addiu $v0,$v0,0x28e0 /* f10a784: 8c4e0000 */ lw $t6,0x0($v0) /* f10a788: 8e0f0000 */ lw $t7,0x0($s0) /* f10a78c: 15cf0007 */ bne $t6,$t7,.JF0f10a7ac /* f10a790: 00000000 */ nop /* f10a794: 94580004 */ lhu $t8,0x4($v0) /* f10a798: 96190004 */ lhu $t9,0x4($s0) /* f10a79c: 17190003 */ bne $t8,$t9,.JF0f10a7ac /* f10a7a0: 00000000 */ nop /* f10a7a4: 10000062 */ b .JF0f10a930 /* f10a7a8: 24020001 */ li $v0,0x1 .JF0f10a7ac: /* f10a7ac: 0fc3f89a */ jal menuIsDialogOpen /* f10a7b0: 24845524 */ addiu $a0,$a0,0x5524 /* f10a7b4: 10400003 */ beqz $v0,.JF0f10a7c4 /* f10a7b8: 3c0a800a */ lui $t2,0x800a /* f10a7bc: 1000005c */ b .JF0f10a930 /* f10a7c0: 00001025 */ move $v0,$zero .JF0f10a7c4: /* f10a7c4: 8d4a20c4 */ lw $t2,0x20c4($t2) /* f10a7c8: 24010006 */ li $at,0x6 /* f10a7cc: 3c02800a */ lui $v0,0x800a /* f10a7d0: 15410003 */ bne $t2,$at,.JF0f10a7e0 /* f10a7d4: 244229e0 */ addiu $v0,$v0,0x29e0 /* f10a7d8: 10000055 */ b .JF0f10a930 /* f10a7dc: 00001025 */ move $v0,$zero .JF0f10a7e0: /* f10a7e0: 8e080000 */ lw $t0,0x0($s0) /* f10a7e4: 8c4b0000 */ lw $t3,0x0($v0) /* f10a7e8: 15680007 */ bne $t3,$t0,.JF0f10a808 /* f10a7ec: 00000000 */ nop /* f10a7f0: 944c0004 */ lhu $t4,0x4($v0) /* f10a7f4: 960d0004 */ lhu $t5,0x4($s0) /* f10a7f8: 158d0003 */ bne $t4,$t5,.JF0f10a808 /* f10a7fc: 00000000 */ nop /* f10a800: 1000004b */ b .JF0f10a930 /* f10a804: 24020001 */ li $v0,0x1 .JF0f10a808: /* f10a808: 3c02800b */ lui $v0,0x800b /* f10a80c: 2442d5b8 */ addiu $v0,$v0,-10824 /* f10a810: 8c4e0020 */ lw $t6,0x20($v0) /* f10a814: 3c09800a */ lui $t1,0x800a /* f10a818: 252928f0 */ addiu $t1,$t1,0x28f0 /* f10a81c: 15c80007 */ bne $t6,$t0,.JF0f10a83c /* f10a820: 3c048007 */ lui $a0,0x8007 /* f10a824: 944f0024 */ lhu $t7,0x24($v0) /* f10a828: 96180004 */ lhu $t8,0x4($s0) /* f10a82c: 15f80003 */ bne $t7,$t8,.JF0f10a83c /* f10a830: 00000000 */ nop /* f10a834: 1000003e */ b .JF0f10a930 /* f10a838: 24020001 */ li $v0,0x1 .JF0f10a83c: /* f10a83c: 3c078007 */ lui $a3,0x8007 /* f10a840: 3c05800a */ lui $a1,0x800a /* f10a844: 24a5e700 */ addiu $a1,$a1,-6400 /* f10a848: 24e74ed8 */ addiu $a3,$a3,0x4ed8 /* f10a84c: 00001025 */ move $v0,$zero /* f10a850: 8c841998 */ lw $a0,0x1998($a0) /* f10a854: 24060e70 */ li $a2,0xe70 .JF0f10a858: /* f10a858: 50440016 */ beql $v0,$a0,.JF0f10a8b4 /* f10a85c: 24420001 */ addiu $v0,$v0,0x1 /* f10a860: 00460019 */ multu $v0,$a2 /* f10a864: 0000c812 */ mflo $t9 /* f10a868: 00b95021 */ addu $t2,$a1,$t9 /* f10a86c: 8d4304f8 */ lw $v1,0x4f8($t2) /* f10a870: 50600010 */ beqzl $v1,.JF0f10a8b4 /* f10a874: 24420001 */ addiu $v0,$v0,0x1 /* f10a878: 8c6b0000 */ lw $t3,0x0($v1) /* f10a87c: 000260c0 */ sll $t4,$v0,0x3 /* f10a880: 012c1821 */ addu $v1,$t1,$t4 /* f10a884: 54eb000b */ bnel $a3,$t3,.JF0f10a8b4 /* f10a888: 24420001 */ addiu $v0,$v0,0x1 /* f10a88c: 8c6d0000 */ lw $t5,0x0($v1) /* f10a890: 550d0008 */ bnel $t0,$t5,.JF0f10a8b4 /* f10a894: 24420001 */ addiu $v0,$v0,0x1 /* f10a898: 960e0004 */ lhu $t6,0x4($s0) /* f10a89c: 946f0004 */ lhu $t7,0x4($v1) /* f10a8a0: 55cf0004 */ bnel $t6,$t7,.JF0f10a8b4 /* f10a8a4: 24420001 */ addiu $v0,$v0,0x1 /* f10a8a8: 10000021 */ b .JF0f10a930 /* f10a8ac: 24020001 */ li $v0,0x1 /* f10a8b0: 24420001 */ addiu $v0,$v0,0x1 .JF0f10a8b4: /* f10a8b4: 28410004 */ slti $at,$v0,0x4 /* f10a8b8: 1420ffe7 */ bnez $at,.JF0f10a858 /* f10a8bc: 00000000 */ nop /* f10a8c0: 3c04800b */ lui $a0,0x800b /* f10a8c4: 3c05800b */ lui $a1,0x800b /* f10a8c8: 24a5d1e8 */ addiu $a1,$a1,-11800 /* f10a8cc: 9484d5ce */ lhu $a0,-0x2a32($a0) /* f10a8d0: 00001025 */ move $v0,$zero /* f10a8d4: 24070004 */ li $a3,0x4 /* f10a8d8: 240600a0 */ li $a2,0xa0 /* f10a8dc: 24180001 */ li $t8,0x1 .JF0f10a8e0: /* f10a8e0: 0058c804 */ sllv $t9,$t8,$v0 /* f10a8e4: 00995024 */ and $t2,$a0,$t9 /* f10a8e8: 5140000e */ beqzl $t2,.JF0f10a924 /* f10a8ec: 24420001 */ addiu $v0,$v0,0x1 /* f10a8f0: 00460019 */ multu $v0,$a2 /* f10a8f4: 00005812 */ mflo $t3 /* f10a8f8: 00ab1821 */ addu $v1,$a1,$t3 /* f10a8fc: 8c6c004c */ lw $t4,0x4c($v1) /* f10a900: 550c0008 */ bnel $t0,$t4,.JF0f10a924 /* f10a904: 24420001 */ addiu $v0,$v0,0x1 /* f10a908: 960d0004 */ lhu $t5,0x4($s0) /* f10a90c: 946e0050 */ lhu $t6,0x50($v1) /* f10a910: 55ae0004 */ bnel $t5,$t6,.JF0f10a924 /* f10a914: 24420001 */ addiu $v0,$v0,0x1 /* f10a918: 10000005 */ b .JF0f10a930 /* f10a91c: 24020001 */ li $v0,0x1 /* f10a920: 24420001 */ addiu $v0,$v0,0x1 .JF0f10a924: /* f10a924: 5447ffee */ bnel $v0,$a3,.JF0f10a8e0 /* f10a928: 24180001 */ li $t8,0x1 /* f10a92c: 00001025 */ move $v0,$zero .JF0f10a930: /* f10a930: 8fbf001c */ lw $ra,0x1c($sp) /* f10a934: 8fb00018 */ lw $s0,0x18($sp) /* f10a938: 27bd0020 */ addiu $sp,$sp,0x20 /* f10a93c: 03e00008 */ jr $ra /* f10a940: 00000000 */ nop ); #endif #if VERSION >= VERSION_JPN_FINAL GLOBAL_ASM( glabel filemgrConfirmDeleteMenuHandler /* f10a944: 27bdffc8 */ addiu $sp,$sp,-56 /* f10a948: 24010006 */ li $at,0x6 /* f10a94c: afbf0014 */ sw $ra,0x14($sp) /* f10a950: afa5003c */ sw $a1,0x3c($sp) /* f10a954: 14810016 */ bne $a0,$at,.JF0f10a9b0 /* f10a958: afa60040 */ sw $a2,0x40($sp) /* f10a95c: 3c0e8007 */ lui $t6,0x8007 /* f10a960: 8dce1998 */ lw $t6,0x1998($t6) /* f10a964: 3c18800a */ lui $t8,0x800a /* f10a968: 271828f0 */ addiu $t8,$t8,0x28f0 /* f10a96c: 000e78c0 */ sll $t7,$t6,0x3 /* f10a970: 01f81021 */ addu $v0,$t7,$t8 /* f10a974: 8c590000 */ lw $t9,0x0($v0) /* f10a978: 94480004 */ lhu $t0,0x4($v0) /* f10a97c: afb90020 */ sw $t9,0x20($sp) /* f10a980: 0fc3d0dc */ jal menuPopDialog /* f10a984: a7a80024 */ sh $t0,0x24($sp) /* f10a988: 0fc429d6 */ jal filemgrIsFileInUse /* f10a98c: 27a40020 */ addiu $a0,$sp,0x20 /* f10a990: 10400005 */ beqz $v0,.JF0f10a9a8 /* f10a994: 00000000 */ nop /* f10a998: 0fc421f7 */ jal filemgrPushErrorDialog /* f10a99c: 24040003 */ li $a0,0x3 /* f10a9a0: 10000004 */ b .JF0f10a9b4 /* f10a9a4: 8fbf0014 */ lw $ra,0x14($sp) .JF0f10a9a8: /* f10a9a8: 0fc42608 */ jal filemgrDeleteCurrentFile /* f10a9ac: 00000000 */ nop .JF0f10a9b0: /* f10a9b0: 8fbf0014 */ lw $ra,0x14($sp) .JF0f10a9b4: /* f10a9b4: 27bd0038 */ addiu $sp,$sp,0x38 /* f10a9b8: 00001025 */ move $v0,$zero /* f10a9bc: 03e00008 */ jr $ra /* f10a9c0: 00000000 */ nop ); #else s32 filemgrConfirmDeleteMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { menuPopDialog(); filemgrDeleteCurrentFile(); } return 0; } #endif #if VERSION >= VERSION_NTSC_1_0 char *filemgrMenuTextFileInUseDescription(struct menuitem *item) { if (menuIsDialogOpen(&g_FilemgrCopyMenuDialog)) { return langGet(L_MPWEAPONS_240); // "The file you are copying cannot be deleted." } return langGet(L_MPWEAPONS_160); // "Cannot delete file as it is being used." } #endif /** * This is a dirty decomp hack where we intentionally declare * an incorrect function signature in order to get a match. * pheadGetTexture uses u16 as its last argument * but filemgrRenderPerfectHeadThumbnail will only match if * it's an s32 with a 0xffff mask. */ struct textureconfig *pheadGetTexture(s32 playernum, s32 fileid, s32 deviceserial); Gfx *filemgrRenderPerfectHeadThumbnail(Gfx *gdl, struct menuitemrenderdata *renderdata, s32 fileid, s32 deviceserial) { struct textureconfig *texture = pheadGetTexture(g_MpPlayerNum, fileid, deviceserial & 0xffff); if (texture) { gSPDisplayList(gdl++, &var800613a0); gSPDisplayList(gdl++, &var80061360); gDPPipeSync(gdl++); gDPSetTexturePersp(gdl++, G_TP_NONE); gDPSetAlphaCompare(gdl++, G_AC_NONE); gDPSetTextureLOD(gdl++, G_TL_TILE); gDPSetTextureConvert(gdl++, G_TC_FILT); func0f0b39c0(&gdl, texture, 1, 0, 2, 1, NULL); gDPSetCycleType(gdl++, G_CYC_1CYCLE); gDPSetTextureFilter(gdl++, G_TF_POINT); gDPSetEnvColor(gdl++, 0xff, 0xff, 0xff, renderdata->colour); gDPSetCombineLERP(gdl++, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0); gDPLoadSync(gdl++); gDPTileSync(gdl++); gSPTextureRectangle(gdl++, ((renderdata->x + 4) << 2) * g_ScaleX, (renderdata->y + 2) << 2, ((renderdata->x + 20) << 2) * g_ScaleX, (renderdata->y + 18) << 2, G_TX_RENDERTILE, 0, 512, 1024 / g_ScaleX, -1024); gDPLoadSync(gdl++); gDPTileSync(gdl++); gDPPipeSync(gdl++); if (deviceserial) { // empty } } return gdl; } #if VERSION < VERSION_JPN_FINAL bool filemgrIsFileInUse(struct filelistfile *file) { s32 i; #if VERSION >= VERSION_NTSC_1_0 if (menuIsDialogOpen(&g_FilemgrCopyMenuDialog) && file->fileid == g_FilemgrFileToCopy.fileid && file->deviceserial == g_FilemgrFileToCopy.deviceserial) { return true; } if (menuIsDialogOpen(&g_FilemgrFileSelect4MbMenuDialog)) { return false; } #else if (g_MenuData.root == MENUROOT_FILEMGR && menuIsDialogOpen(&g_FilemgrCopyMenuDialog) && file->fileid == g_FilemgrFileToCopy.fileid && file->deviceserial == g_FilemgrFileToCopy.deviceserial) { return true; } #endif if (g_MenuData.root == MENUROOT_FILEMGR) { return false; } if (file->fileid == g_GameFileGuid.fileid && file->deviceserial == g_GameFileGuid.deviceserial) { return true; } if (file->fileid == g_MpSetup.fileguid.fileid && file->deviceserial == g_MpSetup.fileguid.deviceserial) { return true; } for (i = 0; i < 4; i++) { if ((g_MpSetup.chrslots & (1 << i)) && g_PlayerConfigsArray[i].fileguid.fileid == file->fileid && g_PlayerConfigsArray[i].fileguid.deviceserial == file->deviceserial) { return true; } } return false; } #endif /** * item->param is 0 if copying, 1 if deleting. */ s32 filemgrFileToCopyOrDeleteListMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data, bool isdelete) { s32 x; s32 y; struct filelist *list = g_FileLists[0]; s32 listnum = 0; if (item->param == 1) { listnum = g_Menus[g_MpPlayerNum].fm.listnum; list = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]; } if (list == NULL) { return 0; } switch (operation) { case MENUOP_GETOPTIONVALUE: data->list.value = 0x0fffff; break; case MENUOP_GETOPTIONCOUNT: data->list.value = list->numfiles; break; case MENUOP_RENDER: { Gfx *gdl = data->type19.gdl; struct menuitemrenderdata *renderdata = data->type19.renderdata2; struct filelistfile *file = &list->files[data->list.unk04]; if (g_Menus[g_MpPlayerNum].fm.filetypeplusone == 4) { gdl = filemgrRenderPerfectHeadThumbnail(gdl, renderdata, file->fileid, file->deviceserial); } else { u32 colour = renderdata->colour; char text[32]; if (isdelete && filemgrIsFileInUse(file)) { colour = 0xff333300 | (colour & 0xff); } x = renderdata->x + 2; y = renderdata->y + 2; gdl = func0f153628(gdl); if (file) { filemgrGetSelectName(text, file, g_Menus[g_MpPlayerNum].fm.filetypeplusone - 1); gdl = textRenderProjected(gdl, &x, &y, text, g_CharsHandelGothicSm, g_FontHandelGothicSm, colour, viGetWidth(), viGetHeight(), 0, 1); y = renderdata->y + 12; x = renderdata->x + 2; } gdl = func0f153780(gdl); } return (u32)gdl; } case MENUOP_GETOPTIONHEIGHT: data->list.value = 11; break; case MENUOP_GETOPTGROUPCOUNT: data->list.value = list->numdevices; break; case MENUOP_GETOPTGROUPTEXT: return filemgrGetDeviceNameOrStartIndex(listnum, operation, data->list.value); case MENUOP_GETGROUPSTARTINDEX: data->list.groupstartindex = filemgrGetDeviceNameOrStartIndex(listnum, operation, data->list.value); return 0; } return 0; } #if VERSION >= VERSION_JPN_FINAL GLOBAL_ASM( glabel filemgrFileToDeleteListMenuHandler /* f10b018: 3c0e8007 */ lui $t6,0x8007 /* f10b01c: 8dce1998 */ lw $t6,0x1998($t6) /* f10b020: 24080e70 */ li $t0,0xe70 /* f10b024: 3c07800a */ lui $a3,0x800a /* f10b028: 01c80019 */ multu $t6,$t0 /* f10b02c: 24e7e700 */ addiu $a3,$a3,-6400 /* f10b030: 3c038007 */ lui $v1,0x8007 /* f10b034: 246361b0 */ addiu $v1,$v1,0x61b0 /* f10b038: 27bdffe0 */ addiu $sp,$sp,-32 /* f10b03c: afa40020 */ sw $a0,0x20($sp) /* f10b040: afbf0014 */ sw $ra,0x14($sp) /* f10b044: afa50024 */ sw $a1,0x24($sp) /* f10b048: afa60028 */ sw $a2,0x28($sp) /* f10b04c: 8fab0020 */ lw $t3,0x20($sp) /* f10b050: 00007812 */ mflo $t7 /* f10b054: 00efc021 */ addu $t8,$a3,$t7 /* f10b058: 93190e3f */ lbu $t9,0xe3f($t8) /* f10b05c: 24010006 */ li $at,0x6 /* f10b060: 00194880 */ sll $t1,$t9,0x2 /* f10b064: 00695021 */ addu $t2,$v1,$t1 /* f10b068: 8d420000 */ lw $v0,0x0($t2) /* f10b06c: 14400003 */ bnez $v0,.JF0f10b07c /* f10b070: 00000000 */ nop /* f10b074: 10000044 */ b .JF0f10b188 /* f10b078: 00001025 */ move $v0,$zero .JF0f10b07c: /* f10b07c: 1561003d */ bne $t3,$at,.JF0f10b174 /* f10b080: 8fac0028 */ lw $t4,0x28($sp) /* f10b084: 8d8d0000 */ lw $t5,0x0($t4) /* f10b088: 000d7080 */ sll $t6,$t5,0x2 /* f10b08c: 01cd7023 */ subu $t6,$t6,$t5 /* f10b090: 000e70c0 */ sll $t6,$t6,0x3 /* f10b094: 004e3021 */ addu $a2,$v0,$t6 /* f10b098: 10c00036 */ beqz $a2,.JF0f10b174 /* f10b09c: 00c02025 */ move $a0,$a2 /* f10b0a0: 0fc429d6 */ jal filemgrIsFileInUse /* f10b0a4: afa6001c */ sw $a2,0x1c($sp) /* f10b0a8: 3c038007 */ lui $v1,0x8007 /* f10b0ac: 3c07800a */ lui $a3,0x800a /* f10b0b0: 24e7e700 */ addiu $a3,$a3,-6400 /* f10b0b4: 246361b0 */ addiu $v1,$v1,0x61b0 /* f10b0b8: 8fa6001c */ lw $a2,0x1c($sp) /* f10b0bc: 10400012 */ beqz $v0,.JF0f10b108 /* f10b0c0: 24080e70 */ li $t0,0xe70 /* f10b0c4: 3c0f8007 */ lui $t7,0x8007 /* f10b0c8: 8def1998 */ lw $t7,0x1998($t7) /* f10b0cc: 00c02025 */ move $a0,$a2 /* f10b0d0: 01e80019 */ multu $t7,$t0 /* f10b0d4: 0000c012 */ mflo $t8 /* f10b0d8: 00f8c821 */ addu $t9,$a3,$t8 /* f10b0dc: 93290e3f */ lbu $t1,0xe3f($t9) /* f10b0e0: 00095080 */ sll $t2,$t1,0x2 /* f10b0e4: 006a5821 */ addu $t3,$v1,$t2 /* f10b0e8: 8d6c0000 */ lw $t4,0x0($t3) /* f10b0ec: 0fc42154 */ jal filemgrSetFileToDelete /* f10b0f0: 9185030b */ lbu $a1,0x30b($t4) /* f10b0f4: 3c048007 */ lui $a0,0x8007 /* f10b0f8: 0fc3cef8 */ jal menuPushDialog /* f10b0fc: 24844f54 */ addiu $a0,$a0,0x4f54 /* f10b100: 1000001d */ b .JF0f10b178 /* f10b104: 8fa40020 */ lw $a0,0x20($sp) .JF0f10b108: /* f10b108: 3c0d8007 */ lui $t5,0x8007 /* f10b10c: 8dad1998 */ lw $t5,0x1998($t5) /* f10b110: 00c02025 */ move $a0,$a2 /* f10b114: 01a80019 */ multu $t5,$t0 /* f10b118: 00007012 */ mflo $t6 /* f10b11c: 00ee7821 */ addu $t7,$a3,$t6 /* f10b120: 91f80e3f */ lbu $t8,0xe3f($t7) /* f10b124: 0018c880 */ sll $t9,$t8,0x2 /* f10b128: 00794821 */ addu $t1,$v1,$t9 /* f10b12c: 8d2a0000 */ lw $t2,0x0($t1) /* f10b130: 9145030b */ lbu $a1,0x30b($t2) /* f10b134: 0fc42154 */ jal filemgrSetFileToDelete /* f10b138: afa6001c */ sw $a2,0x1c($sp) /* f10b13c: 8fa6001c */ lw $a2,0x1c($sp) /* f10b140: 3c0b8007 */ lui $t3,0x8007 /* f10b144: 8d6b1998 */ lw $t3,0x1998($t3) /* f10b148: 8cce0000 */ lw $t6,0x0($a2) /* f10b14c: 3c0d800a */ lui $t5,0x800a /* f10b150: 25ad28f0 */ addiu $t5,$t5,0x28f0 /* f10b154: 000b60c0 */ sll $t4,$t3,0x3 /* f10b158: 018d1021 */ addu $v0,$t4,$t5 /* f10b15c: ac4e0000 */ sw $t6,0x0($v0) /* f10b160: 94cf0004 */ lhu $t7,0x4($a2) /* f10b164: 3c048007 */ lui $a0,0x8007 /* f10b168: 24844ed8 */ addiu $a0,$a0,0x4ed8 /* f10b16c: 0fc3cef8 */ jal menuPushDialog /* f10b170: a44f0004 */ sh $t7,0x4($v0) .JF0f10b174: /* f10b174: 8fa40020 */ lw $a0,0x20($sp) .JF0f10b178: /* f10b178: 8fa50024 */ lw $a1,0x24($sp) /* f10b17c: 8fa60028 */ lw $a2,0x28($sp) /* f10b180: 0fc42b56 */ jal filemgrFileToCopyOrDeleteListMenuHandler /* f10b184: 24070001 */ li $a3,0x1 .JF0f10b188: /* f10b188: 8fbf0014 */ lw $ra,0x14($sp) /* f10b18c: 27bd0020 */ addiu $sp,$sp,0x20 /* f10b190: 03e00008 */ jr $ra /* f10b194: 00000000 */ nop ); #else s32 filemgrFileToDeleteListMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum] == NULL) { return 0; } if (operation == MENUOP_SET) { struct filelistfile *file = &g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->files[data->list.value]; if (file) { if (filemgrIsFileInUse(file)) { filemgrSetFileToDelete(file, g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->filetype); menuPushDialog(&g_FilemgrFileInUseMenuDialog); } else { filemgrSetFileToDelete(file, g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]->filetype); g_FilemgrFileToDelete.fileid = file->fileid; g_FilemgrFileToDelete.deviceserial = file->deviceserial; menuPushDialog(&g_FilemgrConfirmDeleteMenuDialog); } } } return filemgrFileToCopyOrDeleteListMenuHandler(operation, item, data, true); } #endif s32 filemgrFileToCopyListMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { struct filelist *list = g_FileLists[0]; if (list == NULL) { return 0; } if (operation == MENUOP_SET) { struct filelistfile *file = &list->files[data->list.value]; if (file) { g_FilemgrFileToCopy.fileid = file->fileid; g_FilemgrFileToCopy.deviceserial = file->deviceserial; #if VERSION >= VERSION_NTSC_1_0 filemgrGetFileName(g_Menus[g_MpPlayerNum].fm.filename, file); #endif filemgrPushSelectLocationDialog(g_Menus[g_MpPlayerNum].fm.filetypeplusone, g_Menus[g_MpPlayerNum].fm.filetypeplusone - 1); } } return filemgrFileToCopyOrDeleteListMenuHandler(operation, item, data, false); } s32 filemgrCopyOrDeleteListMenuDialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data) { if (operation == MENUOP_CLOSE) { if (g_Menus[g_MpPlayerNum].fm.isdeletingforsave == true) { g_Menus[g_MpPlayerNum].fm.isdeletingforsave = false; } else { filelistCreate(0, FILETYPE_GAME); g_Menus[g_MpPlayerNum].fm.filetypeplusone = 0; } } return 0; } void filemgrPushDeleteFileDialog(s32 listnum) { struct filelist *list; g_Menus[g_MpPlayerNum].fm.listnum = listnum; g_Menus[g_MpPlayerNum].fm.isdeletingforsave = false; g_Menus[g_MpPlayerNum].fm.filetypeplusone = 1; list = g_FileLists[g_Menus[g_MpPlayerNum].fm.listnum]; if (list) { g_Menus[g_MpPlayerNum].fm.filetypeplusone = list->filetype + 1; } menuPushDialog(&g_FilemgrDeleteMenuDialog); } s32 pakDeleteGameNoteMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { OSPfsState *note = &g_EditingPak->notes[g_Menus[g_MpPlayerNum].fm.noteindex]; s32 result; g_Menus[g_MpPlayerNum].fm.unke24 = g_Menus[g_MpPlayerNum].fm.unke24 | (1 << g_Menus[g_MpPlayerNum].fm.device); menuPopDialog(); result = pakDeleteGameNote(g_Menus[g_MpPlayerNum].fm.device, note->company_code, note->game_code, note->game_name, note->ext_name); g_Menus[g_MpPlayerNum].fm.device1 = g_Menus[g_MpPlayerNum].fm.device; if (result) { filemgrPushErrorDialog(FILEERROR_DELETENOTEFAILED); } } return 0; } /** * Handler for the note listing in the controller pak menu. */ s32 pakGameNoteListMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { s32 x; s32 y; Gfx *gdl; struct menuitemrenderdata *renderdata; OSPfsState *note; #if VERSION >= VERSION_JPN_FINAL char tmpname[52]; char tmpext[20]; char generalbuffer[80]; char extbuffer[80]; char pagesbuffer[80]; #elif VERSION >= VERSION_NTSC_1_0 char tmpname[40]; char tmpext[12]; char generalbuffer[60]; char extbuffer[60]; char pagesbuffer[60]; #else char tmpname[20]; char tmpext[8]; char generalbuffer[28]; char extbuffer[28]; char pagesbuffer[28]; #endif s32 textwidth; s32 textheight; if (g_EditingPak == NULL) { return 0; } switch (operation) { case MENUOP_GETOPTIONVALUE: data->list.value = 0x0fffff; break; case MENUOP_GETOPTIONCOUNT: data->list.value = 16; break; case MENUOP_RENDER: gdl = data->type19.gdl; renderdata = data->type19.renderdata2; note = &g_EditingPak->notes[data->list.unk04]; // Render note number (1-16) sprintf(generalbuffer, "%d:\n", data->list.unk04 + 1); x = renderdata->x + 4; y = renderdata->y + 1; gdl = textRenderProjected(gdl, &x, &y, generalbuffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 1); // Prepare buffers for remaining text if (g_EditingPak->notesinuse[data->list.unk04] == 1) { pakN64FontCodeToAscii(note->game_name, tmpname, 16); pakN64FontCodeToAscii(note->ext_name, tmpext, 4); tmpext[1] = '\0'; sprintf(generalbuffer, "%s\n", tmpname); sprintf(extbuffer, "%s\n", tmpext); sprintf(pagesbuffer, "%d\n", note->file_size / 256); } else { sprintf(generalbuffer, langGet(L_OPTIONS_392)); // "Empty" sprintf(pagesbuffer, langGet(L_OPTIONS_393)); // "--" sprintf(extbuffer, "", tmpname, tmpext); } // Render note name x = renderdata->x + 20; y = renderdata->y + 1; gdl = textRenderProjected(gdl, &x, &y, generalbuffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 1); // Render ext character (for when a game has multiple notes) x = renderdata->x + (VERSION == VERSION_JPN_FINAL ? 220 : 190); y = renderdata->y + 1; gdl = textRenderProjected(gdl, &x, &y, extbuffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 1); // Render number of pages textMeasure(&textheight, &textwidth, pagesbuffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, 0); x = renderdata->x + renderdata->width - textwidth - 6; y = renderdata->y + 1; gdl = textRenderProjected(gdl, &x, &y, pagesbuffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 1); return (u32)gdl; case MENUOP_GETOPTIONHEIGHT: data->list.value = VERSION == VERSION_JPN_FINAL ? LINEHEIGHT - 1 : LINEHEIGHT; break; case MENUOP_SET: if (g_EditingPak->notesinuse[data->list.value] == true) { g_Menus[g_MpPlayerNum].fm.noteindex = data->list.value; menuPushDialog(&g_PakDeleteNoteMenuDialog); } break; } return 0; } #if VERSION >= VERSION_NTSC_1_0 const char var7f1b34dc[] = "GOT OKed!\n"; const char var7f1b34e8[] = "Try to find last opened file...\n"; #endif /** * Controller pak note listing dialog. */ s32 pakGameNotesMenuDialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data) { if (operation == MENUOP_TICK) { if (g_Menus[g_MpPlayerNum].curdialog && g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef) { s32 value = pak0f1168c4(g_Menus[g_MpPlayerNum].fm.device, &g_EditingPak); if (value) { menuCloseDialog(); g_EditingPak = NULL; g_Menus[g_MpPlayerNum].fm.device1 = g_Menus[g_MpPlayerNum].fm.device; if (value == 1) { filemgrPushErrorDialog(FILEERROR_PAKREMOVED); } menuUpdateCurFrame(); } } } return 0; } char *pakMenuTextPagesFree(struct menuitem *item) { if (g_EditingPak == NULL) { sprintf(g_StringPointer, langGet(L_OPTIONS_394)); // "Pages Free: " } else { sprintf(g_StringPointer, langGet(L_OPTIONS_395), g_EditingPak->pagesfree); // "Pages Free: %d" } return g_StringPointer; } char *pakMenuTextPagesUsed(struct menuitem *item) { if (g_EditingPak == NULL) { sprintf(g_StringPointer2, langGet(L_OPTIONS_396)); // "Pages Used: " } else { sprintf(g_StringPointer2, langGet(L_OPTIONS_397), g_EditingPak->pagesused); // "Pages Used: %d" } return g_StringPointer2; } char *pakMenuTextStatusMessage(struct menuitem *item) { ubool haspdnote = false; ubool hasemptynote = false; s32 i; if (g_EditingPak == NULL) { return langGet(L_OPTIONS_398); // "Perfect Dark note already exists on this Controller Pak." } for (i = 0; i < ARRAYCOUNT(g_EditingPak->notes); i++) { if (g_EditingPak->notesinuse[i] == true) { if (g_EditingPak->notes[i].company_code == ROM_COMPANYCODE && g_EditingPak->notes[i].game_code == ROM_GAMECODE) { haspdnote = true; } } else { hasemptynote = true; } } if (haspdnote) { return langGet(L_OPTIONS_398); // "Perfect Dark note already exists on this Controller Pak." } if (g_EditingPak->pagesfree < 28 || !hasemptynote) { return langGet(L_OPTIONS_400); // "Controller Pak is too full to save note- 1 note and 28 pages required to save to Controller Pak." } return langGet(L_OPTIONS_399); // "There is enough space for Perfect Dark note." } /** * Title for the note listing dialog. */ char *pakMenuTextEditingPakName(struct menuitem *item) { return filemgrGetDeviceName(g_Menus[g_MpPlayerNum].fm.device); } /** * A pak selection on the controller pak menu. * * Selecting one takes you to the note listing dialog. */ s32 pakSelectionMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_CHECKDISABLED) { if (!pakIsMemoryPak((s8)item->param)) { return true; } } if (operation == MENUOP_SET) { g_Menus[g_MpPlayerNum].fm.device = item->param; menuPushDialog(&g_PakGameNotesMenuDialog); } return 0; } #if VERSION >= VERSION_NTSC_1_0 /** * Controller pak menu. * * Lists the connected controller paks. */ s32 pakChoosePakMenuDialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data) { switch (operation) { case MENUOP_OPEN: joy0001398c(3); g_Menus[g_MpPlayerNum].fm.unke24 = 0; break; case MENUOP_TICK: var80062944 = 1; break; case MENUOP_CLOSE: if (g_Vars.stagenum != STAGE_BOOTPAKMENU) { s32 i; for (i = 0; i < 4; i++) { if (g_Menus[g_MpPlayerNum].fm.unke24 & (1 << i)) { g_Vars.unk0004e4 &= 0xfff0; g_Vars.unk0004e4 |= 0x0008; g_Vars.unk0004e4 |= 1 << (i + 8); } } } joy000139c8(); break; } return 0; } #else GLOBAL_ASM( glabel pakChoosePakMenuDialog /* f106af8: 27bdffc8 */ addiu $sp,$sp,-56 /* f106afc: 24010064 */ addiu $at,$zero,0x64 /* f106b00: afbf0034 */ sw $ra,0x34($sp) /* f106b04: afb60030 */ sw $s6,0x30($sp) /* f106b08: afb5002c */ sw $s5,0x2c($sp) /* f106b0c: afb40028 */ sw $s4,0x28($sp) /* f106b10: afb30024 */ sw $s3,0x24($sp) /* f106b14: afb20020 */ sw $s2,0x20($sp) /* f106b18: afb1001c */ sw $s1,0x1c($sp) /* f106b1c: afb00018 */ sw $s0,0x18($sp) /* f106b20: afa5003c */ sw $a1,0x3c($sp) /* f106b24: 10810009 */ beq $a0,$at,.NB0f106b4c /* f106b28: afa60040 */ sw $a2,0x40($sp) /* f106b2c: 24010065 */ addiu $at,$zero,0x65 /* f106b30: 10810019 */ beq $a0,$at,.NB0f106b98 /* f106b34: 00008025 */ or $s0,$zero,$zero /* f106b38: 24010066 */ addiu $at,$zero,0x66 /* f106b3c: 50810013 */ beql $a0,$at,.NB0f106b8c /* f106b40: 24190001 */ addiu $t9,$zero,0x1 /* f106b44: 10000036 */ beqz $zero,.NB0f106c20 /* f106b48: 8fbf0034 */ lw $ra,0x34($sp) .NB0f106b4c: /* f106b4c: 0c00529c */ jal joy0001398c /* f106b50: 24040003 */ addiu $a0,$zero,0x3 /* f106b54: 0c00529c */ jal joy0001398c /* f106b58: 2404ffff */ addiu $a0,$zero,-1 /* f106b5c: 3c128007 */ lui $s2,0x8007 /* f106b60: 26523af0 */ addiu $s2,$s2,0x3af0 /* f106b64: 8e4e0000 */ lw $t6,0x0($s2) /* f106b68: 24130dbc */ addiu $s3,$zero,0xdbc /* f106b6c: 3c11800a */ lui $s1,0x800a /* f106b70: 01d30019 */ multu $t6,$s3 /* f106b74: 263127c0 */ addiu $s1,$s1,0x27c0 /* f106b78: 00007812 */ mflo $t7 /* f106b7c: 022fc021 */ addu $t8,$s1,$t7 /* f106b80: 10000026 */ beqz $zero,.NB0f106c1c /* f106b84: af000d80 */ sw $zero,0xd80($t8) /* f106b88: 24190001 */ addiu $t9,$zero,0x1 .NB0f106b8c: /* f106b8c: 3c018006 */ lui $at,0x8006 /* f106b90: 10000022 */ beqz $zero,.NB0f106c1c /* f106b94: a0394e54 */ sb $t9,0x4e54($at) .NB0f106b98: /* f106b98: 3c14800a */ lui $s4,0x800a /* f106b9c: 3c128007 */ lui $s2,0x8007 /* f106ba0: 3c11800a */ lui $s1,0x800a /* f106ba4: 263127c0 */ addiu $s1,$s1,0x27c0 /* f106ba8: 26523af0 */ addiu $s2,$s2,0x3af0 /* f106bac: 2694e6c0 */ addiu $s4,$s4,-6464 /* f106bb0: 24160004 */ addiu $s6,$zero,0x4 /* f106bb4: 2415005b */ addiu $s5,$zero,0x5b /* f106bb8: 24130dbc */ addiu $s3,$zero,0xdbc /* f106bbc: 8e480000 */ lw $t0,0x0($s2) .NB0f106bc0: /* f106bc0: 240c0001 */ addiu $t4,$zero,0x1 /* f106bc4: 00102600 */ sll $a0,$s0,0x18 /* f106bc8: 01130019 */ multu $t0,$s3 /* f106bcc: 00004812 */ mflo $t1 /* f106bd0: 02295021 */ addu $t2,$s1,$t1 /* f106bd4: 8d4b0d80 */ lw $t3,0xd80($t2) /* f106bd8: 020c6804 */ sllv $t5,$t4,$s0 /* f106bdc: 016d7024 */ and $t6,$t3,$t5 /* f106be0: 51c00008 */ beqzl $t6,.NB0f106c04 /* f106be4: 26100001 */ addiu $s0,$s0,0x1 /* f106be8: 8e9804b4 */ lw $t8,0x4b4($s4) /* f106bec: 00047e03 */ sra $t7,$a0,0x18 /* f106bf0: 01e02025 */ or $a0,$t7,$zero /* f106bf4: 03152826 */ xor $a1,$t8,$s5 /* f106bf8: 0fc44356 */ jal pak0f1169c8 /* f106bfc: 2ca50001 */ sltiu $a1,$a1,0x1 /* f106c00: 26100001 */ addiu $s0,$s0,0x1 .NB0f106c04: /* f106c04: 5616ffee */ bnel $s0,$s6,.NB0f106bc0 /* f106c08: 8e480000 */ lw $t0,0x0($s2) /* f106c0c: 0c00529f */ jal joy000139c8 /* f106c10: 00000000 */ sll $zero,$zero,0x0 /* f106c14: 0fc44b4a */ jal pak0f1189d0 /* f106c18: 00000000 */ sll $zero,$zero,0x0 .NB0f106c1c: /* f106c1c: 8fbf0034 */ lw $ra,0x34($sp) .NB0f106c20: /* f106c20: 8fb00018 */ lw $s0,0x18($sp) /* f106c24: 8fb1001c */ lw $s1,0x1c($sp) /* f106c28: 8fb20020 */ lw $s2,0x20($sp) /* f106c2c: 8fb30024 */ lw $s3,0x24($sp) /* f106c30: 8fb40028 */ lw $s4,0x28($sp) /* f106c34: 8fb5002c */ lw $s5,0x2c($sp) /* f106c38: 8fb60030 */ lw $s6,0x30($sp) /* f106c3c: 27bd0038 */ addiu $sp,$sp,0x38 /* f106c40: 03e00008 */ jr $ra /* f106c44: 00001025 */ or $v0,$zero,$zero ); #endif s32 filemgrOpenCopyFileMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { g_Menus[g_MpPlayerNum].fm.filetypeplusone = item->param + 1; filelistCreate(0, item->param); #if VERSION >= VERSION_NTSC_1_0 g_Menus[g_MpPlayerNum].fm.listnum = 0; #endif g_Menus[g_MpPlayerNum].fm.isdeletingforsave = false; menuPushDialog(&g_FilemgrCopyMenuDialog); } return 0; } s32 filemgrOpenDeleteFileMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { g_Menus[g_MpPlayerNum].fm.filetypeplusone = item->param + 1; filelistCreate(0, item->param); g_Menus[g_MpPlayerNum].fm.unke3e = -1; filemgrPushDeleteFileDialog(0); } return 0; } s32 filemgrAgentNameKeyboardMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { char *name = data->keyboard.string; if (!g_FileLists[0]) { return 0; } switch (operation) { case MENUOP_GETTEXT: strcpy(name, g_GameFile.name); break; case MENUOP_SETTEXT: strcpy(g_GameFile.name, name); break; case MENUOP_SET: filemgrPushSelectLocationDialog(0, FILETYPE_GAME); g_Menus[g_MpPlayerNum].fm.unke2c = 1; break; } return 0; } s32 filemgrChooseAgentListMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data) { s32 x; s32 y; s32 pass; s32 i; s32 j; Gfx *gdl; struct menuitemrenderdata *renderdata; s32 texturenum; struct filelistfile *file; char name[12]; u8 stage; u8 difficulty; u32 time; s32 days; s32 hours; s32 minutes; s32 seconds; char buffer[100]; s32 textwidth; s32 textheight; if (g_FileLists[0] == NULL) { return 0; } switch (operation) { case MENUOP_GETOPTIONVALUE: data->list.value = 0x0fffff; break; case MENUOP_25: pass = false; if (data->list.unk04 == 1) { if (data->list.groupstartindex == 1 && g_Menus[g_MpPlayerNum].fm.unke2c == 1) { for (i = 0; i < g_FileLists[0]->numfiles; i++) { if (g_GameFileGuid.fileid == g_FileLists[0]->files[i].fileid && g_GameFileGuid.deviceserial == g_FileLists[0]->files[i].deviceserial) { data->list.value = i; } } g_Menus[g_MpPlayerNum].fm.unke2c = 0; } if (g_FileLists[0]->updatedthisframe) { pass = true; } } else { pass = true; g_Menus[g_MpPlayerNum].fm.unke2c = 0; } if (pass && g_Vars.bossfileid) { for (j = 0; j < g_FileLists[0]->numfiles; j++) { if (g_Vars.bossfileid == g_FileLists[0]->files[j].fileid && g_Vars.bossdeviceserial == g_FileLists[0]->files[j].deviceserial) { data->list.value = j; g_Vars.bossfileid = 0; } } } break; case MENUOP_GETOPTIONCOUNT: data->list.value = g_FileLists[0]->numfiles + 1; break; case MENUOP_RENDER: gdl = data->type19.gdl; texturenum = 12; file = NULL; renderdata = data->type19.renderdata2; seconds = 0; minutes = 0; hours = 0; days = 0; if (data->list.unk04 != g_FileLists[0]->numfiles) { file = &g_FileLists[0]->files[data->list.unk04]; if (file) { gamefileGetOverview(file->name, name, &stage, &difficulty, &time); seconds = time % 60; time = time / 60; // The stage returned by the above function is offset by 1. // 0 = New recruit // 1 = Defection // ... // This is correctly capping it to Skedar Ruins if (stage > SOLOSTAGEINDEX_SKEDARRUINS + 1) { stage = SOLOSTAGEINDEX_SKEDARRUINS + 1; } if (difficulty > DIFF_PA) { difficulty = DIFF_PA; } texturenum = stage + 12; days = time / 1440; hours = (time - days * 1440) / 60; minutes = (time - days * 1440) - hours * 60; } } gDPPipeSync(gdl++); gDPSetTexturePersp(gdl++, G_TP_NONE); gDPSetAlphaCompare(gdl++, G_AC_NONE); gDPSetTextureLOD(gdl++, G_TL_TILE); gDPSetTextureConvert(gdl++, G_TC_FILT); func0f0b39c0(&gdl, &g_TexGeneralConfigs[texturenum], 2, 0, 2, 1, NULL); gDPSetCycleType(gdl++, G_CYC_1CYCLE); gDPSetTextureFilter(gdl++, G_TF_POINT); gDPSetEnvColor(gdl++, 0xff, 0xff, 0xff, renderdata->colour); gDPSetCombineLERP(gdl++, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0); gSPTextureRectangle(gdl++, ((renderdata->x + 4) << 2) * g_ScaleX, (renderdata->y + 2) << 2, ((renderdata->x + 60) << 2) * g_ScaleX, (renderdata->y + 38) << 2, G_TX_RENDERTILE, 0, 1152, 1024 / g_ScaleX, -1024); x = renderdata->x + 62; y = renderdata->y + (VERSION == VERSION_JPN_FINAL ? 3 : 4); gdl = func0f153628(gdl); if (data->list.unk04 == g_FileLists[0]->numfiles) { // "New Agent..." gdl = textRenderProjected(gdl, &x, &y, langGet(L_OPTIONS_403), g_CharsHandelGothicMd, g_FontHandelGothicMd, renderdata->colour, viGetWidth(), viGetHeight(), 0, 0); } else if (file) { // Render file name gdl = textRenderProjected(gdl, &x, &y, name, g_CharsHandelGothicMd, g_FontHandelGothicMd, renderdata->colour, viGetWidth(), viGetHeight(), 0, 1); // Prepare and render stage name y = renderdata->y + (VERSION == VERSION_JPN_FINAL ? 16 : 18); x = renderdata->x + 62; if (stage > 0) { sprintf(buffer, "%s %s", langGet(g_StageNames[stage - 1].name1), langGet(g_StageNames[stage - 1].name2)); } else { // "New Recruit" strcpy(buffer, langGet(L_OPTIONS_404)); } strcat(buffer, "\n"); gdl = textRenderProjected(gdl, &x, &y, buffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 0); // Prepare and render mission time x = renderdata->x + 62; y++; #if VERSION == VERSION_JPN_FINAL x -= 3; #endif if (days > 0) { // "Mission Time:" sprintf(buffer, "%s %d:%02d:%02d", langGet(L_OPTIONS_405), days, hours, minutes); } else { // "Mission Time:" sprintf(buffer, "%s %02d:%02d", langGet(L_OPTIONS_405), hours, minutes); } // Useless - textwidth and textheight are not used #if VERSION >= VERSION_JPN_FINAL textMeasure(&textheight, &textwidth, buffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, -1); #else textMeasure(&textheight, &textwidth, buffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, 0); #endif gdl = textRenderProjected(gdl, &x, &y, buffer, g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 0); // Render seconds part of mission time (uses a smaller font) y += (VERSION == VERSION_JPN_FINAL) ? 3 : 1; x++; sprintf(buffer, ".%02d", seconds); gdl = textRenderProjected(gdl, &x, &y, buffer, g_CharsHandelGothicXs, g_FontHandelGothicXs, renderdata->colour, viGetWidth(), viGetHeight(), 0, 0); } gdl = func0f153780(gdl); return (u32) gdl; case MENUOP_GETOPTIONHEIGHT: data->list.value = 40; break; case MENUOP_SET: if (data->list.value == g_FileLists[0]->numfiles) { // New agent gamefileLoadDefaults(&g_GameFile); menuPushDialog(&g_FilemgrEnterNameMenuDialog); } else { struct filelistfile *file = &g_FileLists[0]->files[data->list.value]; if (file) { g_GameFileGuid.fileid = file->fileid; g_GameFileGuid.deviceserial = file->deviceserial; filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_LOAD_GAME, 0); } } break; case MENUOP_GETOPTGROUPCOUNT: data->list.value = g_FileLists[0]->numdevices + 1; break; case MENUOP_GETOPTGROUPTEXT: if (data->list.value >= g_FileLists[0]->numdevices) { return (u32) langGet(L_OPTIONS_402); // "New..." } return filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value); case MENUOP_GETGROUPSTARTINDEX: if (data->list.value >= g_FileLists[0]->numdevices) { data->list.groupstartindex = g_FileLists[0]->numfiles; } else { data->list.groupstartindex = filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value); } return 0; } return 0; } s32 filemgrMainMenuDialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data) { s32 i; switch (operation) { case MENUOP_OPEN: g_Menus[g_MpPlayerNum].fm.filetypeplusone = 0; filelistCreate(0, FILETYPE_GAME); mpSetDefaultSetup(); // Set MP player names to "Player 1" through 4 if blank for (i = 0; i < 4; i++) { if (g_PlayerConfigsArray[i].base.name[0] == '\0') { sprintf(g_PlayerConfigsArray[i].base.name, "%s %d\n", langGet(L_MISC_437), i + 1); } } break; case MENUOP_CLOSE: func0f110bf8(); break; #if VERSION < VERSION_NTSC_1_0 case MENUOP_TICK: filelistsTick(); break; #endif } return 0; } #if VERSION == VERSION_PAL_FINAL GLOBAL_ASM( glabel filemgrConsiderPushingFileSelectDialog /* f10d268: 3c0e8007 */ lui $t6,0x8007 /* f10d26c: 8dce1728 */ lw $t6,0x1728($t6) /* f10d270: 3c18800a */ lui $t8,0x800a /* f10d274: 2718e5a0 */ addiu $t8,$t8,-6752 /* f10d278: 000e78c0 */ sll $t7,$t6,0x3 /* f10d27c: 01ee7823 */ subu $t7,$t7,$t6 /* f10d280: 000f7880 */ sll $t7,$t7,0x2 /* f10d284: 01ee7821 */ addu $t7,$t7,$t6 /* f10d288: 000f78c0 */ sll $t7,$t7,0x3 /* f10d28c: 01ee7823 */ subu $t7,$t7,$t6 /* f10d290: 000f7900 */ sll $t7,$t7,0x4 /* f10d294: 01f81021 */ addu $v0,$t7,$t8 /* f10d298: 9059083c */ lbu $t9,0x83c($v0) /* f10d29c: 27bdffe8 */ addiu $sp,$sp,-24 /* f10d2a0: afbf0014 */ sw $ra,0x14($sp) /* f10d2a4: 1720000f */ bnez $t9,.PF0f10d2e4 /* f10d2a8: 3c048007 */ lui $a0,0x8007 /* f10d2ac: a040083b */ sb $zero,0x83b($v0) /* f10d2b0: 2484527c */ addiu $a0,$a0,0x527c /* f10d2b4: 0fc3e29d */ jal menuPushRootDialog /* f10d2b8: 24050006 */ li $a1,0x6 /* f10d2bc: 3c08800a */ lui $t0,0x800a /* f10d2c0: 9508a992 */ lhu $t0,-0x566e($t0) /* f10d2c4: 3c048007 */ lui $a0,0x8007 /* f10d2c8: 29010006 */ slti $at,$t0,0x6 /* f10d2cc: 14200003 */ bnez $at,.PF0f10d2dc /* f10d2d0: 00000000 */ nop /* f10d2d4: 0fc3cda8 */ jal menuPushDialog /* f10d2d8: 24844810 */ addiu $a0,$a0,0x4810 .PF0f10d2dc: /* f10d2dc: 10000002 */ b .PF0f10d2e8 /* f10d2e0: 24020001 */ li $v0,0x1 .PF0f10d2e4: /* f10d2e4: 00001025 */ move $v0,$zero .PF0f10d2e8: /* f10d2e8: 8fbf0014 */ lw $ra,0x14($sp) /* f10d2ec: 27bd0018 */ addiu $sp,$sp,0x18 /* f10d2f0: 03e00008 */ jr $ra /* f10d2f4: 00000000 */ nop ); #elif VERSION == VERSION_PAL_BETA GLOBAL_ASM( glabel filemgrConsiderPushingFileSelectDialog /* f10cfc8: 3c0e8007 */ lui $t6,0x8007 /* f10cfcc: 8dce3118 */ lw $t6,0x3118($t6) /* f10cfd0: 3c18800a */ lui $t8,0x800a /* f10cfd4: 27182530 */ addiu $t8,$t8,0x2530 /* f10cfd8: 000e78c0 */ sll $t7,$t6,0x3 /* f10cfdc: 01ee7823 */ subu $t7,$t7,$t6 /* f10cfe0: 000f7880 */ sll $t7,$t7,0x2 /* f10cfe4: 01ee7821 */ addu $t7,$t7,$t6 /* f10cfe8: 000f78c0 */ sll $t7,$t7,0x3 /* f10cfec: 01ee7823 */ subu $t7,$t7,$t6 /* f10cff0: 000f7900 */ sll $t7,$t7,0x4 /* f10cff4: 01f81021 */ addu $v0,$t7,$t8 /* f10cff8: 9059083c */ lbu $t9,0x83c($v0) /* f10cffc: 27bdffe8 */ addiu $sp,$sp,-24 /* f10d000: afbf0014 */ sw $ra,0x14($sp) /* f10d004: 1720000f */ bnez $t9,.PB0f10d044 /* f10d008: 3c048007 */ lui $a0,0x8007 /* f10d00c: a040083b */ sb $zero,0x83b($v0) /* f10d010: 24846b8c */ addiu $a0,$a0,0x6b8c /* f10d014: 0fc3e223 */ jal menuPushRootDialog /* f10d018: 24050006 */ li $a1,0x6 /* f10d01c: 3c08800a */ lui $t0,0x800a /* f10d020: 9508e952 */ lhu $t0,-0x16ae($t0) /* f10d024: 3c048007 */ lui $a0,0x8007 /* f10d028: 29010006 */ slti $at,$t0,0x6 /* f10d02c: 14200003 */ bnez $at,.PB0f10d03c /* f10d030: 00000000 */ nop /* f10d034: 0fc3cd2e */ jal menuPushDialog /* f10d038: 24846120 */ addiu $a0,$a0,0x6120 .PB0f10d03c: /* f10d03c: 10000002 */ b .PB0f10d048 /* f10d040: 24020001 */ li $v0,0x1 .PB0f10d044: /* f10d044: 00001025 */ move $v0,$zero .PB0f10d048: /* f10d048: 8fbf0014 */ lw $ra,0x14($sp) /* f10d04c: 27bd0018 */ addiu $sp,$sp,0x18 /* f10d050: 03e00008 */ jr $ra /* f10d054: 00000000 */ nop ); #else bool filemgrConsiderPushingFileSelectDialog(void) { if (g_Menus[g_MpPlayerNum].openinhibit == 0) { g_Menus[g_MpPlayerNum].playernum = 0; menuPushRootDialog(&g_FilemgrFileSelectMenuDialog, MENUROOT_FILEMGR); return true; } return false; } #endif void pakPushPakMenuDialog(void) { s32 prevplayernum = g_MpPlayerNum; g_MpPlayerNum = 0; menuPushRootDialog(&g_PakChoosePakMenuDialog, MENUROOT_BOOTPAKMGR); g_MpPlayerNum = prevplayernum; } struct menuitem g_FilemgrSelectLocationMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_368, L_OPTIONS_369, NULL }, // "Where", "Spaces" { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, { MENUITEMTYPE_SELECTABLE, SAVEDEVICE_GAMEPAK, 0x00000000, (u32)&filemgrMenuTextLocationName2, (u32)&filemgrMenuTextSaveLocationSpaces, filemgrSelectLocationMenuHandler }, { MENUITEMTYPE_SELECTABLE, SAVEDEVICE_CONTROLLERPAK1, 0x00000000, (u32)&filemgrMenuTextLocationName2, (u32)&filemgrMenuTextSaveLocationSpaces, filemgrSelectLocationMenuHandler }, { MENUITEMTYPE_SELECTABLE, SAVEDEVICE_CONTROLLERPAK2, 0x00000000, (u32)&filemgrMenuTextLocationName2, (u32)&filemgrMenuTextSaveLocationSpaces, filemgrSelectLocationMenuHandler }, { MENUITEMTYPE_SELECTABLE, SAVEDEVICE_CONTROLLERPAK3, 0x00000000, (u32)&filemgrMenuTextLocationName2, (u32)&filemgrMenuTextSaveLocationSpaces, filemgrSelectLocationMenuHandler }, { MENUITEMTYPE_SELECTABLE, SAVEDEVICE_CONTROLLERPAK4, 0x00000000, (u32)&filemgrMenuTextLocationName2, (u32)&filemgrMenuTextSaveLocationSpaces, filemgrSelectLocationMenuHandler }, { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, { MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_OPTIONS_370, 0x00000000, filemgrDeleteFilesForSaveMenuHandler }, // "Delete Files..." { MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_OPTIONS_371, 0x00000000, filemgrCancelSaveMenuHandler }, // "Cancel" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrSelectLocationMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_367, // "Select Location" g_FilemgrSelectLocationMenuItems, NULL, MENUDIALOGFLAG_DISABLEBANNER, NULL, }; struct menuitem g_FilemgrConfirmDeleteMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000030, (u32)&filemgrMenuTextDeleteFileName, 0x00000000, filemgrFileNameMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00000230, (u32)&filemgrMenuTextDeviceName, 0x00000000, filemgrDeviceNameMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_380, 0x00000000, NULL }, // "Are you sure you want to delete this file?" { MENUITEMTYPE_SELECTABLE, 0, 0x00000028, L_OPTIONS_381, 0x00000000, NULL }, // "Cancel" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_382, 0x00000000, filemgrConfirmDeleteMenuHandler }, // "OK" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrConfirmDeleteMenuDialog = { MENUDIALOGTYPE_DANGER, L_OPTIONS_379, // "Warning" g_FilemgrConfirmDeleteMenuItems, NULL, MENUDIALOGFLAG_DISABLEBANNER, NULL, }; struct menuitem g_FilemgrFileInUseMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000030, (u32)&filemgrMenuTextDeleteFileName, 0x00000000, filemgrFileNameMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00000230, (u32)&filemgrMenuTextDeviceName, 0x00000000, filemgrDeviceNameMenuHandler }, #if VERSION >= VERSION_NTSC_1_0 { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextFileInUseDescription, 0x00000000, NULL }, #else { MENUITEMTYPE_LABEL, 0, 0x00000010, 0x54a0, 0x00000000, NULL }, #endif { MENUITEMTYPE_SELECTABLE, 0, 0x00000028, L_MPWEAPONS_161, 0x00000000, NULL }, // "Cancel" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrFileInUseMenuDialog = { MENUDIALOGTYPE_DANGER, L_MPWEAPONS_159, // "Error" g_FilemgrFileInUseMenuItems, NULL, MENUDIALOGFLAG_DISABLEBANNER, NULL, }; struct menuitem g_FilemgrDeleteMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00004010, L_OPTIONS_377, 0x00000000, NULL }, // "Select a file to delete:" { MENUITEMTYPE_LIST, 1, 0x00200000, 0x00000000, 0x00000000, filemgrFileToDeleteListMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00004030, L_OPTIONS_378, 0x00000000, NULL }, // "Press B Button to exit." { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrDeleteMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_376, // "Delete File" g_FilemgrDeleteMenuItems, filemgrCopyOrDeleteListMenuDialog, 0, NULL, }; struct menuitem g_FilemgrCopyMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00004010, L_OPTIONS_374, 0x00000000, NULL }, // "Select a file to copy:" { MENUITEMTYPE_LIST, 0, 0x00200000, 0x00000000, 0x00000000, filemgrFileToCopyListMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00004030, L_OPTIONS_375, 0x00000000, NULL }, // "Press B Button to exit." { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrCopyMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_373, // "Copy File" g_FilemgrCopyMenuItems, filemgrCopyOrDeleteListMenuDialog, 0, NULL, }; struct pakdata *g_EditingPak = NULL; struct menuitem g_PakDeleteNoteMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_384, 0x00000000, NULL }, // "Are you sure you want to delete this game note?" { MENUITEMTYPE_SELECTABLE, 0, 0x00000028, L_OPTIONS_385, 0x00000000, NULL }, // "No" { MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS_386, 0x00000000, pakDeleteGameNoteMenuHandler }, // "Yes" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_PakDeleteNoteMenuDialog = { MENUDIALOGTYPE_DANGER, L_OPTIONS_383, // "Delete Game Note" g_PakDeleteNoteMenuItems, NULL, 0, NULL, }; struct menuitem g_PakGameNotesMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_388, (u32)&pakMenuTextEditingPakName, NULL }, // "Delete Game Notes:" { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x0000010e, 0x00000000, NULL }, { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_389, L_OPTIONS_390, NULL }, // "Note", "Pages" { MENUITEMTYPE_LIST, 0, 0x00200000, 0x000000c8, 0x0000006e, pakGameNoteListMenuHandler }, { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&pakMenuTextPagesFree, (u32)&pakMenuTextPagesUsed, NULL }, { MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&pakMenuTextStatusMessage, 0x00000000, NULL }, { MENUITEMTYPE_LABEL, 0, 0x00000030, L_OPTIONS_391, 0x00000000, NULL }, // "Press the B Button to exit." { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_PakGameNotesMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_387, // "Game Notes" g_PakGameNotesMenuItems, pakGameNotesMenuDialog, 0, NULL, }; struct menuitem g_PakChoosePakMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_108, 0x00000000, NULL }, // "Use this menu to delete game notes from your Controller Pak" { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, { MENUITEMTYPE_LABEL, 0, 0x00000010, L_OPTIONS_109, 0x00000000, NULL }, // "Choose Controller Pak to Edit:" { MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_OPTIONS_112, 0x00000000, pakSelectionMenuHandler }, // "Controller Pak 1" { MENUITEMTYPE_SELECTABLE, 1, 0x00000000, L_OPTIONS_113, 0x00000000, pakSelectionMenuHandler }, // "Controller Pak 2" { MENUITEMTYPE_SELECTABLE, 2, 0x00000000, L_OPTIONS_114, 0x00000000, pakSelectionMenuHandler }, // "Controller Pak 3" { MENUITEMTYPE_SELECTABLE, 3, 0x00000000, L_OPTIONS_115, 0x00000000, pakSelectionMenuHandler }, // "Controller Pak 4" { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, { MENUITEMTYPE_SELECTABLE, 0, 0x00000028, L_OPTIONS_110, 0x00000000, NULL }, // "Exit" { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_PakChoosePakMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_107, // "Controller Pak Menu" g_PakChoosePakMenuItems, pakChoosePakMenuDialog, 0, NULL, }; struct menuitem g_FilemgrOperationsMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00004010, L_OPTIONS_100, 0x00000000, NULL }, // "Copy:" { MENUITEMTYPE_SELECTABLE, FILETYPE_GAME, 0x00000000, L_OPTIONS_103, 0x00000000, filemgrOpenCopyFileMenuHandler }, // "Single Player Agent File" { MENUITEMTYPE_SELECTABLE, FILETYPE_MPSETUP , 0x00000000, L_OPTIONS_104, 0x00000000, filemgrOpenCopyFileMenuHandler }, // "Combat Simulator Settings File" { MENUITEMTYPE_SELECTABLE, FILETYPE_MPPLAYER, 0x00000000, L_OPTIONS_105, 0x00000000, filemgrOpenCopyFileMenuHandler }, // "Combat Simulator Player File" { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, { MENUITEMTYPE_LABEL, 0, 0x00004010, L_OPTIONS_101, 0x00000000, NULL }, // "Delete:" { MENUITEMTYPE_SELECTABLE, FILETYPE_GAME, 0x00000000, L_OPTIONS_103, 0x00000000, filemgrOpenDeleteFileMenuHandler }, // "Single Player Agent File" { MENUITEMTYPE_SELECTABLE, FILETYPE_MPSETUP, 0x00000000, L_OPTIONS_104, 0x00000000, filemgrOpenDeleteFileMenuHandler }, // "Combat Simulator Settings File" { MENUITEMTYPE_SELECTABLE, FILETYPE_MPPLAYER, 0x00000000, L_OPTIONS_105, 0x00000000, filemgrOpenDeleteFileMenuHandler }, // "Combat Simulator Player File" { MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, { MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_OPTIONS_102, 0x00000000, (void *)&g_PakChoosePakMenuDialog }, // "Delete Game Notes..." { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrOperationsMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_099, // "Game Files" g_FilemgrOperationsMenuItems, NULL, MENUDIALOGFLAG_IGNOREBACK, NULL, }; struct menuitem g_FilemgrEnterNameMenuItems[] = { { MENUITEMTYPE_KEYBOARD, 0, 0x00000000, 0x00000000, 0x00000001, filemgrAgentNameKeyboardMenuHandler }, { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrEnterNameMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_401, // "Enter Agent Name" g_FilemgrEnterNameMenuItems, NULL, 0, NULL, }; struct menuitem g_FilemgrFileSelectMenuItems[] = { { MENUITEMTYPE_LABEL, 0, 0x00004010, L_OPTIONS_096, 0x00000000, NULL }, // "Choose Your Reality" { MENUITEMTYPE_LIST, 0, 0x00200000, 0x000000f5, 0x00000000, filemgrChooseAgentListMenuHandler }, { MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL }, }; struct menudialogdef g_FilemgrFileSelectMenuDialog = { MENUDIALOGTYPE_DEFAULT, L_OPTIONS_095, // "Perfect Dark" g_FilemgrFileSelectMenuItems, filemgrMainMenuDialog, MENUDIALOGFLAG_IGNOREBACK, &g_FilemgrOperationsMenuDialog, };