mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-08-03 16:42:16 -04:00
2436 lines
69 KiB
C
2436 lines
69 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/data/data_000000.h"
|
|
#include "game/data/data_0083d0.h"
|
|
#include "game/data/data_00e460.h"
|
|
#include "game/data/data_0160b0.h"
|
|
#include "game/data/data_01a3a0.h"
|
|
#include "game/data/data_020df0.h"
|
|
#include "game/data/data_02da90.h"
|
|
#include "game/game_0b3350.h"
|
|
#include "game/game_0d4690.h"
|
|
#include "game/game_0f09f0.h"
|
|
#include "game/game_107fb0.h"
|
|
#include "game/game_1531a0.h"
|
|
#include "game/gamefile.h"
|
|
#include "game/lang.h"
|
|
#include "game/mplayer.h"
|
|
#include "game/pak/pak.h"
|
|
#include "game/utils.h"
|
|
#include "gvars/gvars.h"
|
|
#include "lib/lib_09660.h"
|
|
#include "lib/lib_126b0.h"
|
|
#include "lib/lib_13130.h"
|
|
#include "lib/lib_13900.h"
|
|
#include "types.h"
|
|
|
|
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"
|
|
L_MPWEAPONS(229), // "Controller Pak Not Found"
|
|
};
|
|
|
|
if (index < ARRAYCOUNT(names)) {
|
|
return langGet(names[index]);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
s32 filemgrDeviceNameMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if ((g_Menus[g_MpPlayerNum].unke3c & 0x7f) >= SAVEDEVICE_INVALID) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *filemgrMenuTextDeviceName(struct menuitem *item)
|
|
{
|
|
return filemgrGetDeviceName(g_Menus[g_MpPlayerNum].unke3c & 0x7f);
|
|
}
|
|
|
|
void filemgrGetFileName(char *buffer, struct savelocation000 *arg1, 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_SOLO:
|
|
case FILETYPE_MPSETUP:
|
|
func0f0d564c(arg1->unk06, tmpbuffer1, 0);
|
|
break;
|
|
case FILETYPE_MPPLAYER:
|
|
// MP Player filenames have the play duration appended to the name
|
|
func0f18d9a4(arg1->unk06, 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);
|
|
}
|
|
|
|
const char var7f1b2f28[] = "Setup: item = %x\n";
|
|
|
|
const u32 var7f1b2f3c[] = {0xa0, 0x31, 0x4e, 0x4a0};
|
|
|
|
s32 filemgrFileNameMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if (g_Menus[g_MpPlayerNum].unke38 == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *filemgrMenuTextDeleteFileName(struct menuitem *item)
|
|
{
|
|
if (g_Menus[g_MpPlayerNum].unke38) {
|
|
filemgrGetFileName(g_StringPointer,
|
|
g_Menus[g_MpPlayerNum].unke38,
|
|
g_Menus[g_MpPlayerNum].unke3d);
|
|
return g_StringPointer;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void func0f108324(s32 arg0)
|
|
{
|
|
s32 index = pakSearch(arg0);
|
|
|
|
if (index >= 0) {
|
|
g_Menus[g_MpPlayerNum].unke3c = index;
|
|
} else {
|
|
g_Menus[g_MpPlayerNum].unke3c = SAVEDEVICE_INVALID;
|
|
}
|
|
}
|
|
|
|
void func0f1083b0(struct savelocation000 *arg0)
|
|
{
|
|
func0f108324(arg0->unk04);
|
|
}
|
|
|
|
void func0f1083d0(struct savelocation000 *arg0, s32 filetype)
|
|
{
|
|
g_Menus[g_MpPlayerNum].unke3d = filetype;
|
|
g_Menus[g_MpPlayerNum].unke38 = arg0;
|
|
func0f1083b0(arg0);
|
|
}
|
|
|
|
u16 g_PakFailReasons[] = {
|
|
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."
|
|
};
|
|
|
|
char *filemgrMenuTextFailReason(struct menuitem *item)
|
|
{
|
|
return langGet(g_PakFailReasons[g_Menus[g_MpPlayerNum].errno]);
|
|
}
|
|
|
|
/**
|
|
* Unused.
|
|
*/
|
|
char *func0f108484(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "location: controller pak 1\n");
|
|
return g_StringPointer;
|
|
}
|
|
|
|
s32 filemgrDeviceNameForErrorMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKHIDDEN) {
|
|
if ((g_Menus[g_MpPlayerNum].unke3c & 0x7f) >= SAVEDEVICE_INVALID) {
|
|
return true;
|
|
}
|
|
|
|
switch (g_Menus[g_MpPlayerNum].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].unke3c & 0x7f));
|
|
|
|
if (g_Menus[g_MpPlayerNum].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;
|
|
}
|
|
|
|
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";
|
|
|
|
void filemgrPushErrorDialog(u16 errno)
|
|
{
|
|
g_Menus[g_MpPlayerNum].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 menudialog g_FilemgrErrorMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS(320), // "Error"
|
|
g_FilemgrErrorMenuItems,
|
|
NULL,
|
|
0x00000080,
|
|
NULL,
|
|
};
|
|
|
|
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].unke42) {
|
|
case 100:
|
|
case 102:
|
|
return langGet(messages[0]);
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 4:
|
|
return langGet(messages[1]);
|
|
case 101:
|
|
return langGet(messages[2]);
|
|
case 3:
|
|
return langGet(messages[3]);
|
|
case 104:
|
|
case 105:
|
|
case 106:
|
|
return langGet(messages[6]);
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
return langGet(messages[7]);
|
|
}
|
|
|
|
return langGet(messages[8]);
|
|
}
|
|
|
|
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].unke42) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
case 100:
|
|
case 104:
|
|
return langGet(names[0]);
|
|
case 4:
|
|
case 7:
|
|
case 102:
|
|
case 105:
|
|
return langGet(names[1]);
|
|
case 3:
|
|
case 8:
|
|
case 101:
|
|
case 106:
|
|
return langGet(names[2]);
|
|
}
|
|
|
|
return langGet(names[0]);
|
|
}
|
|
|
|
void func0f10898c(void)
|
|
{
|
|
func0f0f0ca0(-1, false);
|
|
|
|
switch (g_Menus[g_MpPlayerNum].unke42) {
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 104:
|
|
case 105:
|
|
case 106:
|
|
func00012cb4(g_Menus[g_MpPlayerNum].unke44, align16(var7f1b2f3c[g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone - 1]));
|
|
break;
|
|
case 100:
|
|
case 101:
|
|
case 102:
|
|
case 103:
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void func0f108a80(void)
|
|
{
|
|
func0f0f0ca0(-1, false);
|
|
|
|
switch (g_Menus[g_MpPlayerNum].unke42) {
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
func00012cb4(g_Menus[g_MpPlayerNum].unke44,
|
|
align16(var7f1b2f3c[g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone - 1]));
|
|
break;
|
|
case 100:
|
|
g_Vars.unk00047c = g_Menus[g_MpPlayerNum].unke48;
|
|
g_Vars.unk000480 = g_Menus[g_MpPlayerNum].unke4c;
|
|
func0f1109c0();
|
|
|
|
if (IS4MB()) {
|
|
func0f0f820c(&g_4MbMainMenu, MENUROOT_4MBMAINMENU);
|
|
} else {
|
|
func0f0f820c(&g_MainMenuMenuDialog, MENUROOT_MAINMENU);
|
|
}
|
|
break;
|
|
case 104:
|
|
case 105:
|
|
case 106:
|
|
func0f1094e4(&var800a21e8,
|
|
g_Menus[g_MpPlayerNum].unke42 - 98,
|
|
g_Menus[g_MpPlayerNum].unke44);
|
|
break;
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 101:
|
|
case 102:
|
|
case 103:
|
|
break;
|
|
}
|
|
}
|
|
|
|
s32 filemgrRetrySaveMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
filemgrRetrySave(2);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrSaveElsewhereYesMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
s32 sp1c;
|
|
|
|
menuCloseDialog();
|
|
|
|
switch (g_Menus[g_MpPlayerNum].unke42) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 6:
|
|
sp1c = 0;
|
|
break;
|
|
case 3:
|
|
case 8:
|
|
sp1c = 2;
|
|
break;
|
|
case 4:
|
|
case 7:
|
|
sp1c = 1;
|
|
break;
|
|
}
|
|
|
|
filemgrPushSelectLocationDialog(g_Menus[g_MpPlayerNum].unke42 + 9, sp1c);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrCancelSave2MenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuCloseDialog();
|
|
func0f10898c();
|
|
menuUpdateCurFrame();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Unused.
|
|
*/
|
|
s32 func0f108d14(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
filemgrRetrySave(2);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrAcknowledgeFileLostMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuCloseDialog();
|
|
func0f10898c();
|
|
menuUpdateCurFrame();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void filemgrEraseCorruptFile(void)
|
|
{
|
|
s32 value;
|
|
s32 i;
|
|
|
|
value = pakSearch(g_Menus[g_MpPlayerNum].unke4c);
|
|
|
|
if (value >= 0) {
|
|
filemgrDeleteFile(value, g_Menus[g_MpPlayerNum].unke48);
|
|
}
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (g_FileLists[i]) {
|
|
g_FileLists[i]->outdated = true;
|
|
}
|
|
}
|
|
|
|
menuPushDialog(&g_FilemgrFileLostMenuDialog);
|
|
}
|
|
|
|
s32 filemgrInsertOriginalPakMenuDialog(u32 operation, struct menudialog *dialog, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_TICK) {
|
|
if (g_Menus[g_MpPlayerNum].curframe &&
|
|
g_Menus[g_MpPlayerNum].curframe->dialog == dialog) {
|
|
filemgrRetrySave(0);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 filemgrReinsertedOkMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
pakExecuteDebugOperations();
|
|
filemgrRetrySave(1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrReinsertedCancelMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
if (g_Menus[g_MpPlayerNum].unke42 < 100 && g_Menus[g_MpPlayerNum].unke42 != 1) {
|
|
func0f0f3704(&g_FilemgrSaveElsewhereMenuDialog);
|
|
} else {
|
|
menuPopDialog();
|
|
}
|
|
}
|
|
|
|
return 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, var8007fb10, var8007fb0c);
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
/**
|
|
* 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 index = pakSearch(g_Menus[g_MpPlayerNum].unke4c);
|
|
|
|
if (index == -1) {
|
|
if (context == 1) {
|
|
filemgrPushErrorDialog(FILEERROR_NOPAK);
|
|
}
|
|
|
|
if (context == 2) {
|
|
func0f0f3704(&g_FilemgrInsertOriginalPakMenuDialog);
|
|
}
|
|
} else if (fileSave(index, true)) {
|
|
if (context == 2) {
|
|
g_Menus[g_MpPlayerNum].unke3c = index;
|
|
|
|
if (g_Menus[g_MpPlayerNum].unke42 < 100) {
|
|
filemgrPushErrorDialog(FILEERROR_SAVEFAILED);
|
|
} else {
|
|
filemgrPushErrorDialog(FILEERROR_LOADFAILED);
|
|
}
|
|
} else {
|
|
func0f108324(g_Menus[g_MpPlayerNum].unke4c);
|
|
|
|
if (g_Menus[g_MpPlayerNum].unke42 < 100) {
|
|
func0f0f3704(&g_FilemgrSaveErrorMenuDialog);
|
|
} else {
|
|
filemgrEraseCorruptFile();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool fileSave(s32 arg0, bool arg1)
|
|
{
|
|
s32 errno = 0;
|
|
u32 sp40 = (g_Menus[g_MpPlayerNum].isretryingsave & 1) != 0;
|
|
|
|
const s32 sp30[] = {0x80, 0x40, 0x20, 0x08};
|
|
s32 sp2c;
|
|
|
|
switch (g_Menus[g_MpPlayerNum].unke42) {
|
|
case 2:
|
|
sp40 = 1;
|
|
// fall through
|
|
case 0:
|
|
case 1:
|
|
errno = func0f10feac(arg0,
|
|
g_Menus[g_MpPlayerNum].unke48,
|
|
g_Menus[g_MpPlayerNum].unke4c);
|
|
break;
|
|
case 3:
|
|
errno = func0f18d9fc(
|
|
g_Menus[g_MpPlayerNum].unke44, arg0,
|
|
g_Menus[g_MpPlayerNum].unke48,
|
|
g_Menus[g_MpPlayerNum].unke4c);
|
|
break;
|
|
case 4:
|
|
errno = func0f18e420(arg0,
|
|
g_Menus[g_MpPlayerNum].unke48,
|
|
g_Menus[g_MpPlayerNum].unke4c);
|
|
sp40 = 1;
|
|
break;
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
sp2c = 0;
|
|
func0f0d5690(g_Menus[g_MpPlayerNum].unke44, g_Menus[g_MpPlayerNum].unke53);
|
|
errno = func0f116828(arg0,
|
|
g_Menus[g_MpPlayerNum].unke48,
|
|
sp30[g_Menus[g_MpPlayerNum].unke42 - 6],
|
|
g_Menus[g_MpPlayerNum].unke44, &sp2c, 0);
|
|
var80075bd0[g_Menus[g_MpPlayerNum].unke42 - 6] = 1;
|
|
break;
|
|
case 100:
|
|
errno = func0f10fac8(arg0);
|
|
break;
|
|
case 101:
|
|
errno = func0f18dac0(
|
|
g_Menus[g_MpPlayerNum].unke44,
|
|
arg0,
|
|
g_Menus[g_MpPlayerNum].unke48,
|
|
g_Menus[g_MpPlayerNum].unke4c);
|
|
break;
|
|
case 102:
|
|
errno = func0f18e4c8(arg0,
|
|
g_Menus[g_MpPlayerNum].unke48,
|
|
g_Menus[g_MpPlayerNum].unke4c);
|
|
break;
|
|
case 104:
|
|
case 105:
|
|
case 106:
|
|
errno = func0f116800(arg0,
|
|
g_Menus[g_MpPlayerNum].unke48,
|
|
g_Menus[g_MpPlayerNum].unke44, 0);
|
|
break;
|
|
}
|
|
|
|
if (errno == 0 && arg1) {
|
|
menuCloseDialog();
|
|
}
|
|
|
|
if (g_Menus[g_MpPlayerNum].unke42 < 100) {
|
|
if (errno == 0) {
|
|
func0f108a80();
|
|
}
|
|
|
|
if (sp40 && errno == 0) {
|
|
menuPushDialog(&g_FilemgrFileSavedMenuDialog);
|
|
}
|
|
} else {
|
|
if (errno == 0) {
|
|
func0f108a80();
|
|
}
|
|
}
|
|
|
|
menuUpdateCurFrame();
|
|
|
|
return errno;
|
|
}
|
|
|
|
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";
|
|
|
|
bool func0f1094e4(struct savelocation_2d8 *arg0, s32 arg1, void *arg2)
|
|
{
|
|
s32 value;
|
|
|
|
if (arg1 != -1) {
|
|
g_Menus[g_MpPlayerNum].unke42 = arg1;
|
|
g_Menus[g_MpPlayerNum].unke44 = arg2;
|
|
g_Menus[g_MpPlayerNum].isretryingsave = 0;
|
|
var800a21f8.unk00 = 0;
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].unke48 = arg0->unk00;
|
|
g_Menus[g_MpPlayerNum].unke4c = arg0->unk04;
|
|
|
|
if (arg1 != -1) {
|
|
// empty
|
|
}
|
|
|
|
value = pakSearch(g_Menus[g_MpPlayerNum].unke4c);
|
|
|
|
if (value == -1) {
|
|
g_Menus[g_MpPlayerNum].isretryingsave |= 1;
|
|
menuPushDialog(&g_FilemgrInsertOriginalPakMenuDialog);
|
|
return false;
|
|
}
|
|
|
|
if (fileSave(value, false) != 0) {
|
|
g_Menus[g_MpPlayerNum].isretryingsave |= 1;
|
|
func0f108324(g_Menus[g_MpPlayerNum].unke4c);
|
|
|
|
if (g_Menus[g_MpPlayerNum].unke42 < 100) {
|
|
menuPushDialog(&g_FilemgrSaveErrorMenuDialog);
|
|
} else {
|
|
filemgrEraseCorruptFile();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void filemgrDeleteCurrentFile(void)
|
|
{
|
|
bool error = false;
|
|
s8 index = pakSearch(g_FilemgrFileToDelete.unk04);
|
|
s32 i;
|
|
|
|
if (index >= 0) {
|
|
if (filemgrDeleteFile(index, g_FilemgrFileToDelete.unk00)) {
|
|
error = true;
|
|
}
|
|
} else {
|
|
error = true;
|
|
}
|
|
|
|
g_FileLists[g_Menus[g_MpPlayerNum].listnum]->outdated = true;
|
|
|
|
if (error) {
|
|
g_Menus[g_MpPlayerNum].unke3c = index;
|
|
filemgrPushErrorDialog(FILEERROR_DELETEFAILED);
|
|
} else {
|
|
for (i = 0; i < 4; i++) {
|
|
if (g_FilemgrFileToDelete.unk00 == g_MpPlayers[i].unk4c.unk00
|
|
&& g_FilemgrFileToDelete.unk04 == g_MpPlayers[i].unk4c.unk04) {
|
|
func0f18800c(i, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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 menudialog g_FilemgrFileSavedMenuDialog = {
|
|
MENUDIALOGTYPE_SUCCESS,
|
|
L_OPTIONS(345), // "Cool!"
|
|
g_FilemgrFileSavedMenuItems,
|
|
NULL,
|
|
0x00000080,
|
|
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 menudialog g_FilemgrSaveErrorMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
(u32)&filemgrMenuTextErrorTitle,
|
|
g_FilemgrSaveErrorMenuItems,
|
|
NULL,
|
|
0x000000a0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrFileLostMenuItems[] = {
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextDeviceName, 0x00000000, filemgrDeviceNameMenuHandler },
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPWEAPONS(251), 0x00000000, NULL }, // "The saved file has been erased due to corruption or damage."
|
|
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000020, L_OPTIONS(354), 0x00000000, filemgrAcknowledgeFileLostMenuHandler }, // "Cancel"
|
|
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
|
};
|
|
|
|
struct menudialog g_FilemgrFileLostMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
(u32)&filemgrMenuTextErrorTitle,
|
|
g_FilemgrFileLostMenuItems,
|
|
NULL,
|
|
0x000000a0,
|
|
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 menudialog g_FilemgrSaveElsewhereMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS(359), // "Save"
|
|
g_FilemgrSaveElsewhereMenuItems,
|
|
NULL,
|
|
0x000000a0,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrInsertOriginalPakMenuItems[] = {
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextInsertOriginalPak, 0x00000000, NULL },
|
|
{ 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 menudialog g_FilemgrInsertOriginalPakMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
(u32)&filemgrMenuTextErrorTitle,
|
|
g_FilemgrInsertOriginalPakMenuItems,
|
|
filemgrInsertOriginalPakMenuDialog,
|
|
0x000000a0,
|
|
NULL,
|
|
};
|
|
|
|
void func0f1097d0(s32 device)
|
|
{
|
|
char *types[] = {"GAM", "MPG", "MPP", "CAM"};
|
|
const u32 sizes[] = {0x80, 0x40, 0x20, 0x08};
|
|
void *thing;
|
|
|
|
if (g_FileLists[0]) {
|
|
var800a21e8.unk00 = g_FileLists[0]->unk2d8[device].unk00;
|
|
var800a21e8.unk04 = g_FileLists[0]->unk2d8[device].unk04;
|
|
|
|
thing = func00012ab0(align16(var7f1b2f3c[g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone - 1]));
|
|
|
|
if (thing) {
|
|
func0f1094e4(&g_FilemgrFileToCopy, g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone + 103, thing);
|
|
} else {
|
|
filemgrPushErrorDialog(FILEERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
var80075bd0[g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone - 1] = 1;
|
|
}
|
|
}
|
|
|
|
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";
|
|
|
|
u32 var8007465c = 0x01020304;
|
|
u32 var80074660 = 0x00000000;
|
|
|
|
void func0f109954(s32 arg0)
|
|
{
|
|
if (g_FileLists[0]) {
|
|
g_FilemgrLoadedMainFile.unk00 = g_FileLists[0]->unk2d8[arg0].unk00;
|
|
g_FilemgrLoadedMainFile.unk04 = g_FileLists[0]->unk2d8[arg0].unk04;
|
|
|
|
func0f1094e4(&g_FilemgrLoadedMainFile, 0, NULL);
|
|
}
|
|
}
|
|
|
|
void func0f1099a8(char *buffer, struct savelocation000 *arg1)
|
|
{
|
|
char localbuffer[20];
|
|
u32 sp20;
|
|
|
|
localbuffer[0] = '\0';
|
|
|
|
switch (g_FileLists[g_Menus[g_MpPlayerNum].listnum]->filetype) {
|
|
case FILETYPE_SOLO:
|
|
case FILETYPE_MPSETUP:
|
|
func0f0d564c(arg1->unk06, localbuffer, 0);
|
|
break;
|
|
case FILETYPE_MPPLAYER:
|
|
func0f18d9a4(arg1->unk06, localbuffer, &sp20);
|
|
break;
|
|
}
|
|
|
|
sprintf(buffer, "%s", localbuffer);
|
|
}
|
|
|
|
const char var7f1b3294[] = "GETFileNameForThePurposesOfTheFileRenamingChecker: Unknown type %d\n";
|
|
|
|
void filemgrGetRenameName(char *buffer)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
|
|
switch (g_Menus[g_MpPlayerNum].unke3e) {
|
|
case 0:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
strcpy(buffer, g_SoloSaveFile.name);
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 15:
|
|
case 16:
|
|
case 17:
|
|
strcpy(buffer, g_Menus[g_MpPlayerNum].unke53);
|
|
break;
|
|
case 6:
|
|
case 12:
|
|
i = 0;
|
|
j = 0;
|
|
|
|
while (g_MpPlayers[g_MpPlayerNum].base.name[i] != '\0') {
|
|
if (g_MpPlayers[g_MpPlayerNum].base.name[i] != '\n') {
|
|
buffer[j] = g_MpPlayers[g_MpPlayerNum].base.name[i];
|
|
j++;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
buffer[j] = '\0';
|
|
break;
|
|
case 7:
|
|
case 13:
|
|
strcpy(buffer, g_MpSetup.name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void filemgrSetRenameName(char *name)
|
|
{
|
|
switch (g_Menus[g_MpPlayerNum].unke3e) {
|
|
case 0:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
strcpy(g_SoloSaveFile.name, name);
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 15:
|
|
case 16:
|
|
case 17:
|
|
strcpy(g_Menus[g_MpPlayerNum].unke53, name);
|
|
break;
|
|
case 6:
|
|
case 12:
|
|
sprintf(g_MpPlayers[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";
|
|
const char var7f1b3320[] = "CheckFileName: Comparing range %d-%d\n";
|
|
const char var7f1b3348[] = "Compare '%s' to '%s' = %d\n";
|
|
const char var7f1b3364[] = "OI! DUPLICATE FILE NAME! NO!\n";
|
|
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";
|
|
|
|
GLOBAL_ASM(
|
|
glabel filemgrIsNameAvailable
|
|
/* f109c8c: 3c0e8007 */ lui $t6,%hi(g_MpPlayerNum)
|
|
/* f109c90: 8dce1448 */ lw $t6,%lo(g_MpPlayerNum)($t6)
|
|
/* f109c94: 3c18800a */ lui $t8,%hi(g_Menus+0xe3f)
|
|
/* f109c98: 27bdff88 */ addiu $sp,$sp,-120
|
|
/* f109c9c: 000e78c0 */ sll $t7,$t6,0x3
|
|
/* f109ca0: 01ee7823 */ subu $t7,$t7,$t6
|
|
/* f109ca4: 000f7880 */ sll $t7,$t7,0x2
|
|
/* f109ca8: 01ee7821 */ addu $t7,$t7,$t6
|
|
/* f109cac: 000f78c0 */ sll $t7,$t7,0x3
|
|
/* f109cb0: 01ee7823 */ subu $t7,$t7,$t6
|
|
/* f109cb4: 000f7900 */ sll $t7,$t7,0x4
|
|
/* f109cb8: 030fc021 */ addu $t8,$t8,$t7
|
|
/* f109cbc: 9318ee3f */ lbu $t8,%lo(g_Menus+0xe3f)($t8)
|
|
/* f109cc0: 3c038007 */ lui $v1,%hi(g_FileLists)
|
|
/* f109cc4: 3c058007 */ lui $a1,%hi(var8007465c)
|
|
/* f109cc8: 0018c880 */ sll $t9,$t8,0x2
|
|
/* f109ccc: 00791821 */ addu $v1,$v1,$t9
|
|
/* f109cd0: 8c635bc0 */ lw $v1,%lo(g_FileLists)($v1)
|
|
/* f109cd4: 00a42821 */ addu $a1,$a1,$a0
|
|
/* f109cd8: afbf002c */ sw $ra,0x2c($sp)
|
|
/* f109cdc: afb50028 */ sw $s5,0x28($sp)
|
|
/* f109ce0: afb40024 */ sw $s4,0x24($sp)
|
|
/* f109ce4: afb30020 */ sw $s3,0x20($sp)
|
|
/* f109ce8: afb2001c */ sw $s2,0x1c($sp)
|
|
/* f109cec: afb10018 */ sw $s1,0x18($sp)
|
|
/* f109cf0: afb00014 */ sw $s0,0x14($sp)
|
|
/* f109cf4: 14600003 */ bnez $v1,.L0f109d04
|
|
/* f109cf8: 90a5465c */ lbu $a1,%lo(var8007465c)($a1)
|
|
/* f109cfc: 10000068 */ b .L0f109ea0
|
|
/* f109d00: 24020001 */ addiu $v0,$zero,0x1
|
|
.L0f109d04:
|
|
/* f109d04: 00654021 */ addu $t0,$v1,$a1
|
|
/* f109d08: 81120300 */ lb $s2,0x300($t0)
|
|
/* f109d0c: 2404ffff */ addiu $a0,$zero,-1
|
|
/* f109d10: 24110004 */ addiu $s1,$zero,0x4
|
|
/* f109d14: 16440003 */ bne $s2,$a0,.L0f109d24
|
|
/* f109d18: 28a10004 */ slti $at,$a1,0x4
|
|
/* f109d1c: 10000060 */ b .L0f109ea0
|
|
/* f109d20: 24020001 */ addiu $v0,$zero,0x1
|
|
.L0f109d24:
|
|
/* f109d24: 10200009 */ beqz $at,.L0f109d4c
|
|
/* f109d28: 847502d0 */ lh $s5,0x2d0($v1)
|
|
/* f109d2c: 24620004 */ addiu $v0,$v1,0x4
|
|
.L0f109d30:
|
|
/* f109d30: 80430300 */ lb $v1,0x300($v0)
|
|
/* f109d34: 2631ffff */ addiu $s1,$s1,-1
|
|
/* f109d38: 10830002 */ beq $a0,$v1,.L0f109d44
|
|
/* f109d3c: 00000000 */ nop
|
|
/* f109d40: 0060a825 */ or $s5,$v1,$zero
|
|
.L0f109d44:
|
|
/* f109d44: 14b1fffa */ bne $a1,$s1,.L0f109d30
|
|
/* f109d48: 2442ffff */ addiu $v0,$v0,-1
|
|
.L0f109d4c:
|
|
/* f109d4c: 27b40064 */ addiu $s4,$sp,0x64
|
|
/* f109d50: a3a00064 */ sb $zero,0x64($sp)
|
|
/* f109d54: 0fc4269a */ jal filemgrGetRenameName
|
|
/* f109d58: 02802025 */ or $a0,$s4,$zero
|
|
/* f109d5c: 93a90064 */ lbu $t1,0x64($sp)
|
|
/* f109d60: 27a30064 */ addiu $v1,$sp,0x64
|
|
/* f109d64: 2410000a */ addiu $s0,$zero,0xa
|
|
/* f109d68: 11200011 */ beqz $t1,.L0f109db0
|
|
/* f109d6c: 02408825 */ or $s1,$s2,$zero
|
|
/* f109d70: 90620000 */ lbu $v0,0x0($v1)
|
|
/* f109d74: 28410061 */ slti $at,$v0,0x61
|
|
.L0f109d78:
|
|
/* f109d78: 14200005 */ bnez $at,.L0f109d90
|
|
/* f109d7c: 2841007b */ slti $at,$v0,0x7b
|
|
/* f109d80: 10200003 */ beqz $at,.L0f109d90
|
|
/* f109d84: 244bffe0 */ addiu $t3,$v0,-32
|
|
/* f109d88: a06b0000 */ sb $t3,0x0($v1)
|
|
/* f109d8c: 316200ff */ andi $v0,$t3,0xff
|
|
.L0f109d90:
|
|
/* f109d90: 56020004 */ bnel $s0,$v0,.L0f109da4
|
|
/* f109d94: 24630001 */ addiu $v1,$v1,0x1
|
|
/* f109d98: 10000002 */ b .L0f109da4
|
|
/* f109d9c: a0600000 */ sb $zero,0x0($v1)
|
|
/* f109da0: 24630001 */ addiu $v1,$v1,0x1
|
|
.L0f109da4:
|
|
/* f109da4: 90620000 */ lbu $v0,0x0($v1)
|
|
/* f109da8: 5440fff3 */ bnezl $v0,.L0f109d78
|
|
/* f109dac: 28410061 */ slti $at,$v0,0x61
|
|
.L0f109db0:
|
|
/* f109db0: 0255082a */ slt $at,$s2,$s5
|
|
/* f109db4: 10200039 */ beqz $at,.L0f109e9c
|
|
/* f109db8: 2410000a */ addiu $s0,$zero,0xa
|
|
/* f109dbc: 00129080 */ sll $s2,$s2,0x2
|
|
/* f109dc0: 02519023 */ subu $s2,$s2,$s1
|
|
/* f109dc4: 001290c0 */ sll $s2,$s2,0x3
|
|
/* f109dc8: 27b30040 */ addiu $s3,$sp,0x40
|
|
.L0f109dcc:
|
|
/* f109dcc: 3c0c8007 */ lui $t4,%hi(g_MpPlayerNum)
|
|
/* f109dd0: 8d8c1448 */ lw $t4,%lo(g_MpPlayerNum)($t4)
|
|
/* f109dd4: 3c0e800a */ lui $t6,%hi(g_Menus+0xe3f)
|
|
/* f109dd8: 3c188007 */ lui $t8,%hi(g_FileLists)
|
|
/* f109ddc: 000c68c0 */ sll $t5,$t4,0x3
|
|
/* f109de0: 01ac6823 */ subu $t5,$t5,$t4
|
|
/* f109de4: 000d6880 */ sll $t5,$t5,0x2
|
|
/* f109de8: 01ac6821 */ addu $t5,$t5,$t4
|
|
/* f109dec: 000d68c0 */ sll $t5,$t5,0x3
|
|
/* f109df0: 01ac6823 */ subu $t5,$t5,$t4
|
|
/* f109df4: 000d6900 */ sll $t5,$t5,0x4
|
|
/* f109df8: 01cd7021 */ addu $t6,$t6,$t5
|
|
/* f109dfc: 91ceee3f */ lbu $t6,%lo(g_Menus+0xe3f)($t6)
|
|
/* f109e00: 02602025 */ or $a0,$s3,$zero
|
|
/* f109e04: 00001025 */ or $v0,$zero,$zero
|
|
/* f109e08: 000e7880 */ sll $t7,$t6,0x2
|
|
/* f109e0c: 030fc021 */ addu $t8,$t8,$t7
|
|
/* f109e10: 8f185bc0 */ lw $t8,%lo(g_FileLists)($t8)
|
|
/* f109e14: 0fc4266a */ jal func0f1099a8
|
|
/* f109e18: 03122821 */ addu $a1,$t8,$s2
|
|
/* f109e1c: 93b90040 */ lbu $t9,0x40($sp)
|
|
/* f109e20: 27a30040 */ addiu $v1,$sp,0x40
|
|
/* f109e24: 02802025 */ or $a0,$s4,$zero
|
|
/* f109e28: 13200011 */ beqz $t9,.L0f109e70
|
|
/* f109e2c: 00000000 */ nop
|
|
/* f109e30: 90620000 */ lbu $v0,0x0($v1)
|
|
/* f109e34: 28410061 */ slti $at,$v0,0x61
|
|
.L0f109e38:
|
|
/* f109e38: 14200005 */ bnez $at,.L0f109e50
|
|
/* f109e3c: 2841007b */ slti $at,$v0,0x7b
|
|
/* f109e40: 10200003 */ beqz $at,.L0f109e50
|
|
/* f109e44: 2449ffe0 */ addiu $t1,$v0,-32
|
|
/* f109e48: a0690000 */ sb $t1,0x0($v1)
|
|
/* f109e4c: 312200ff */ andi $v0,$t1,0xff
|
|
.L0f109e50:
|
|
/* f109e50: 56020004 */ bnel $s0,$v0,.L0f109e64
|
|
/* f109e54: 24630001 */ addiu $v1,$v1,0x1
|
|
/* f109e58: 10000002 */ b .L0f109e64
|
|
/* f109e5c: a0600000 */ sb $zero,0x0($v1)
|
|
/* f109e60: 24630001 */ addiu $v1,$v1,0x1
|
|
.L0f109e64:
|
|
/* f109e64: 90620000 */ lbu $v0,0x0($v1)
|
|
/* f109e68: 5440fff3 */ bnezl $v0,.L0f109e38
|
|
/* f109e6c: 28410061 */ slti $at,$v0,0x61
|
|
.L0f109e70:
|
|
/* f109e70: 0c004c9d */ jal func00013274
|
|
/* f109e74: 02602825 */ or $a1,$s3,$zero
|
|
/* f109e78: 02802025 */ or $a0,$s4,$zero
|
|
/* f109e7c: 0c004c9d */ jal func00013274
|
|
/* f109e80: 02602825 */ or $a1,$s3,$zero
|
|
/* f109e84: 14400003 */ bnez $v0,.L0f109e94
|
|
/* f109e88: 26310001 */ addiu $s1,$s1,0x1
|
|
/* f109e8c: 10000004 */ b .L0f109ea0
|
|
/* f109e90: 00001025 */ or $v0,$zero,$zero
|
|
.L0f109e94:
|
|
/* f109e94: 1635ffcd */ bne $s1,$s5,.L0f109dcc
|
|
/* f109e98: 26520018 */ addiu $s2,$s2,0x18
|
|
.L0f109e9c:
|
|
/* f109e9c: 24020001 */ addiu $v0,$zero,0x1
|
|
.L0f109ea0:
|
|
/* f109ea0: 8fbf002c */ lw $ra,0x2c($sp)
|
|
/* f109ea4: 8fb00014 */ lw $s0,0x14($sp)
|
|
/* f109ea8: 8fb10018 */ lw $s1,0x18($sp)
|
|
/* f109eac: 8fb2001c */ lw $s2,0x1c($sp)
|
|
/* f109eb0: 8fb30020 */ lw $s3,0x20($sp)
|
|
/* f109eb4: 8fb40024 */ lw $s4,0x24($sp)
|
|
/* f109eb8: 8fb50028 */ lw $s5,0x28($sp)
|
|
/* f109ebc: 03e00008 */ jr $ra
|
|
/* f109ec0: 27bd0078 */ addiu $sp,$sp,0x78
|
|
);
|
|
|
|
void func0f109ec4(void)
|
|
{
|
|
if (g_FileLists[g_Menus[g_MpPlayerNum].listnum]->spacesfree[g_Menus[g_MpPlayerNum].device] > 0) {
|
|
if (!filemgrIsNameAvailable(g_Menus[g_MpPlayerNum].device)) {
|
|
menuPushDialog(&g_FilemgrDuplicateFileNameMenuDialog);
|
|
} else {
|
|
menuPopDialog();
|
|
|
|
if (g_Menus[g_MpPlayerNum].unke3e == 0) {
|
|
func0f109954(g_Menus[g_MpPlayerNum].device);
|
|
} else if (g_Menus[g_MpPlayerNum].unke3e == 5) {
|
|
// empty
|
|
} else if (g_Menus[g_MpPlayerNum].unke3e == 6) {
|
|
struct savelocation_2d8 thing;
|
|
thing.unk00 = g_FileLists[g_Menus[g_MpPlayerNum].listnum]->unk2d8[g_Menus[g_MpPlayerNum].device].unk00;
|
|
thing.unk04 = g_FileLists[g_Menus[g_MpPlayerNum].listnum]->unk2d8[g_Menus[g_MpPlayerNum].device].unk04;
|
|
func0f1094e4(&thing, 3, (void *)g_MpPlayerNum);
|
|
} else if (g_Menus[g_MpPlayerNum].unke3e == 7) {
|
|
struct savelocation_2d8 thing;
|
|
thing.unk00 = g_FileLists[g_Menus[g_MpPlayerNum].listnum]->unk2d8[g_Menus[g_MpPlayerNum].device].unk00;
|
|
thing.unk04 = g_FileLists[g_Menus[g_MpPlayerNum].listnum]->unk2d8[g_Menus[g_MpPlayerNum].device].unk04;
|
|
func0f1094e4(&thing, 4, NULL);
|
|
} else if (g_Menus[g_MpPlayerNum].unke3e >= 9) {
|
|
struct savelocation_2d8 thing;
|
|
thing.unk00 = g_FileLists[g_Menus[g_MpPlayerNum].listnum]->unk2d8[g_Menus[g_MpPlayerNum].device].unk00;
|
|
thing.unk04 = g_FileLists[g_Menus[g_MpPlayerNum].listnum]->unk2d8[g_Menus[g_MpPlayerNum].device].unk04;
|
|
func0f1094e4(&thing, -1, NULL);
|
|
} else {
|
|
func0f1097d0(g_Menus[g_MpPlayerNum].device);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 filemgrConfirmRenameMenuHandler(u32 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:
|
|
func0f109ec4();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrDuplicateRenameMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
menuPushDialog(&g_FilemgrChangeFileNameMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrDuplicateCancelMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *filemgrMenuTextDeviceNameContainingDuplicateFile(struct menuitem *item)
|
|
{
|
|
return filemgrGetDeviceName(g_Menus[g_MpPlayerNum].device);
|
|
}
|
|
|
|
char *filemgrMenuTextDuplicateFileName(struct menuitem *item)
|
|
{
|
|
char buffer[32];
|
|
|
|
filemgrGetRenameName(buffer);
|
|
sprintf(g_StringPointer, "%s\n", buffer);
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
struct menuitem g_FilemgrChangeFileNameMenuItems[] = {
|
|
{ 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 menudialog g_FilemgrChangeFileNameMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPWEAPONS(238), // "Change File Name"
|
|
g_FilemgrChangeFileNameMenuItems,
|
|
NULL,
|
|
0x00000080,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrDuplicateFileNameMenuItems[] = {
|
|
{ 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 menudialog g_FilemgrDuplicateFileNameMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_MPWEAPONS(232), // "Duplicate File Name"
|
|
g_FilemgrDuplicateFileNameMenuItems,
|
|
NULL,
|
|
0x00000080,
|
|
NULL,
|
|
};
|
|
|
|
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(4), // ""
|
|
};
|
|
|
|
if (g_FileLists[g_Menus[g_MpPlayerNum].listnum] == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (g_FileLists[g_Menus[g_MpPlayerNum].listnum]->spacesfree[item->param] < 0) {
|
|
return langGet(names[5]);
|
|
}
|
|
|
|
return langGet(names[item->param]);
|
|
}
|
|
|
|
char *filemgrMenuTextSaveLocationSpaces(struct menuitem *item)
|
|
{
|
|
s32 spacesfree;
|
|
|
|
if (g_FileLists[g_Menus[g_MpPlayerNum].listnum] == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
spacesfree = g_FileLists[g_Menus[g_MpPlayerNum].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;
|
|
}
|
|
|
|
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";
|
|
|
|
/**
|
|
* item->param is a SAVEDEVICE constant.
|
|
*/
|
|
s32 filemgrSelectLocationMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (g_FileLists[g_Menus[g_MpPlayerNum].listnum] == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
if (operation == MENUOP_CHECKDISABLED) {
|
|
if (g_FileLists[g_Menus[g_MpPlayerNum].listnum]->spacesfree[item->param] < 1) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_SET) {
|
|
g_Menus[g_MpPlayerNum].device = item->param;
|
|
func0f109ec4();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrCancelSaveMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrDeleteFilesForSaveMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
filemgrPushDeleteFileDialog(g_Menus[g_MpPlayerNum].listnum);
|
|
g_Menus[g_MpPlayerNum].data.filemgr.isdeletingforsave = true;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void filemgrPushSelectLocationDialog(s32 arg0, u32 arg1)
|
|
{
|
|
g_Menus[g_MpPlayerNum].unke3e = arg0;
|
|
g_Menus[g_MpPlayerNum].listnum = func0f110cf8(arg1);
|
|
|
|
func0f110da8();
|
|
|
|
menuPushDialog(&g_FilemgrSelectLocationMenuDialog);
|
|
}
|
|
|
|
s32 filemgrConfirmDeleteMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menuPopDialog();
|
|
filemgrDeleteCurrentFile();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *filemgrMenuTextFileInUseDescription(struct menuitem *item)
|
|
{
|
|
if (menuIsDialogOpen(&g_FilemgrCopyListMenuDialog)) {
|
|
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."
|
|
}
|
|
|
|
Gfx *filemgrRenderPerfectHeadThumbnail(Gfx *gdl, struct menuitemrenderdata *renderdata, u32 arg2, u32 arg3)
|
|
{
|
|
struct var800ab5a8 *texture = func0f111460(g_MpPlayerNum, arg2, arg3 & 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, 0);
|
|
|
|
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_ScreenWidthMultiplier,
|
|
(renderdata->y + 2) << 2,
|
|
((renderdata->x + 20) << 2) * g_ScreenWidthMultiplier,
|
|
(renderdata->y + 18) << 2,
|
|
G_TX_RENDERTILE, 0, 512, 1024 / g_ScreenWidthMultiplier, -1024);
|
|
|
|
gDPLoadSync(gdl++);
|
|
gDPTileSync(gdl++);
|
|
gDPPipeSync(gdl++);
|
|
|
|
if (arg3) {
|
|
// empty
|
|
}
|
|
}
|
|
|
|
return gdl;
|
|
}
|
|
|
|
bool filemgrIsFileInUse(struct savelocation000 *arg0)
|
|
{
|
|
s32 i;
|
|
|
|
if (menuIsDialogOpen(&g_FilemgrCopyListMenuDialog)
|
|
&& arg0->unk00 == g_FilemgrFileToCopy.unk00
|
|
&& arg0->unk04 == g_FilemgrFileToCopy.unk04) {
|
|
return true;
|
|
}
|
|
|
|
if (menuIsDialogOpen(&menudialog_fileselect2)) {
|
|
return false;
|
|
}
|
|
|
|
if (g_MenuData.root == MENUROOT_FILEMGR) {
|
|
return false;
|
|
}
|
|
|
|
if (arg0->unk00 == g_FilemgrLoadedMainFile.unk00 && arg0->unk04 == g_FilemgrLoadedMainFile.unk04) {
|
|
return true;
|
|
}
|
|
|
|
if (arg0->unk00 == g_MpSetup.unk20.unk00 && arg0->unk04 == g_MpSetup.unk20.unk04) {
|
|
return true;
|
|
}
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if ((g_MpSetup.chrslots & (1 << i))
|
|
&& g_MpPlayers[i].unk4c.unk00 == arg0->unk00
|
|
&& g_MpPlayers[i].unk4c.unk04 == arg0->unk04) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* item->param is 0 if copying, 1 if deleting.
|
|
*/
|
|
s32 filemgrFileToCopyOrDeleteListMenuHandler(u32 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].listnum;
|
|
list = g_FileLists[g_Menus[g_MpPlayerNum].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 savelocation000 *location000 = &list->unk000[data->list.unk04];
|
|
|
|
if (g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone == 4) {
|
|
gdl = filemgrRenderPerfectHeadThumbnail(gdl, renderdata, location000->unk00, location000->unk04);
|
|
} else {
|
|
u32 colour = renderdata->colour;
|
|
char text[32];
|
|
|
|
if (isdelete && filemgrIsFileInUse(location000)) {
|
|
colour = 0xff333300 | (colour & 0xff);
|
|
}
|
|
|
|
x = renderdata->x + 2;
|
|
y = renderdata->y + 2;
|
|
|
|
gdl = func0f153628(gdl);
|
|
|
|
if (location000) {
|
|
filemgrGetFileName(text, location000, g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone - 1);
|
|
gdl = textRenderProjected(gdl, &x, &y, text, var8007fb10, var8007fb0c,
|
|
colour, viGetX(), viGetY(), 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->unk30a;
|
|
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;
|
|
}
|
|
|
|
s32 filemgrFileToDeleteListMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (g_FileLists[g_Menus[g_MpPlayerNum].listnum] == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
if (operation == MENUOP_SET) {
|
|
struct savelocation000 *thing = &g_FileLists[g_Menus[g_MpPlayerNum].listnum]->unk000[data->list.value];
|
|
|
|
if (thing) {
|
|
if (filemgrIsFileInUse(thing)) {
|
|
func0f1083d0(thing, g_FileLists[g_Menus[g_MpPlayerNum].listnum]->filetype);
|
|
menuPushDialog(&g_FilemgrFileInUseMenuDialog);
|
|
} else {
|
|
func0f1083d0(thing, g_FileLists[g_Menus[g_MpPlayerNum].listnum]->filetype);
|
|
g_FilemgrFileToDelete.unk00 = thing->unk00;
|
|
g_FilemgrFileToDelete.unk04 = thing->unk04;
|
|
menuPushDialog(&g_FilemgrConfirmDeleteMenuDialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
return filemgrFileToCopyOrDeleteListMenuHandler(operation, item, data, true);
|
|
}
|
|
|
|
s32 filemgrFileToCopyListMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
struct filelist *list = g_FileLists[0];
|
|
|
|
if (list == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
if (operation == MENUOP_SET) {
|
|
struct savelocation000 *thing = &list->unk000[data->list.value];
|
|
|
|
if (thing) {
|
|
g_FilemgrFileToCopy.unk00 = thing->unk00;
|
|
g_FilemgrFileToCopy.unk04 = thing->unk04;
|
|
|
|
func0f1099a8(g_Menus[g_MpPlayerNum].unke53, thing);
|
|
filemgrPushSelectLocationDialog(g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone, g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone - 1);
|
|
}
|
|
}
|
|
|
|
return filemgrFileToCopyOrDeleteListMenuHandler(operation, item, data, false);
|
|
}
|
|
|
|
s32 filemgrCopyOrDeleteListMenuDialog(u32 operation, struct menudialog *dialog, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CLOSE) {
|
|
if (g_Menus[g_MpPlayerNum].data.filemgr.isdeletingforsave == true) {
|
|
g_Menus[g_MpPlayerNum].data.filemgr.isdeletingforsave = false;
|
|
} else {
|
|
func0f110c5c(0, FILETYPE_SOLO);
|
|
g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone = 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void filemgrPushDeleteFileDialog(s32 listnum)
|
|
{
|
|
struct filelist *list;
|
|
|
|
g_Menus[g_MpPlayerNum].listnum = listnum;
|
|
g_Menus[g_MpPlayerNum].data.filemgr.isdeletingforsave = false;
|
|
g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone = 1;
|
|
|
|
list = g_FileLists[g_Menus[g_MpPlayerNum].listnum];
|
|
|
|
if (list) {
|
|
g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone = list->filetype + 1;
|
|
}
|
|
|
|
menuPushDialog(&g_FilemgrDeleteFileMenuDialog);
|
|
}
|
|
|
|
s32 pakDeleteGameNoteMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
OSPfsState *note = &g_EditingPak->notes[g_Menus[g_MpPlayerNum].data.pak.noteindex];
|
|
s32 result;
|
|
|
|
g_Menus[g_MpPlayerNum].data.pak.unke24 = g_Menus[g_MpPlayerNum].data.pak.unke24 | (1 << g_Menus[g_MpPlayerNum].data.pak.device);
|
|
|
|
menuPopDialog();
|
|
|
|
result = pakDeleteGameNote(g_Menus[g_MpPlayerNum].data.pak.device,
|
|
note->company_code, note->game_code, note->game_name, note->ext_name);
|
|
|
|
g_Menus[g_MpPlayerNum].unke3c = g_Menus[g_MpPlayerNum].data.pak.device;
|
|
|
|
if (result) {
|
|
filemgrPushErrorDialog(FILEERROR_DELETENOTEFAILED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 pakGameNoteListMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
s32 x;
|
|
s32 y;
|
|
Gfx *gdl;
|
|
struct menuitemrenderdata *renderdata;
|
|
OSPfsState *note;
|
|
char tmpname[40];
|
|
char tmpext[12];
|
|
char generalbuffer[60];
|
|
char extbuffer[60];
|
|
char pagesbuffer[60];
|
|
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, var8007fb10, var8007fb0c,
|
|
renderdata->colour, viGetX(), viGetY(), 0, 1);
|
|
|
|
// Prepare buffers for remaining text
|
|
if (g_EditingPak->notesinuse[data->list.unk04] == 1) {
|
|
func0f11e618(note->game_name, tmpname, 16);
|
|
func0f11e618(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, var8007fb10, var8007fb0c,
|
|
renderdata->colour, viGetX(), viGetY(), 0, 1);
|
|
|
|
// Render ext character (for when a game has multiple notes)
|
|
x = renderdata->x + 190;
|
|
y = renderdata->y + 1;
|
|
gdl = textRenderProjected(gdl, &x, &y, extbuffer, var8007fb10, var8007fb0c,
|
|
renderdata->colour, viGetX(), viGetY(), 0, 1);
|
|
|
|
// Render number of pages
|
|
textMeasure(&textheight, &textwidth, pagesbuffer, var8007fb10, var8007fb0c, 0);
|
|
|
|
x = renderdata->x + renderdata->width - textwidth - 6;
|
|
y = renderdata->y + 1;
|
|
gdl = textRenderProjected(gdl, &x, &y, pagesbuffer, var8007fb10, var8007fb0c,
|
|
renderdata->colour, viGetX(), viGetY(), 0, 1);
|
|
|
|
return (u32)gdl;
|
|
case MENUOP_GETOPTIONHEIGHT:
|
|
data->list.value = 11;
|
|
break;
|
|
case MENUOP_SET:
|
|
if (g_EditingPak->notesinuse[data->list.value] == true) {
|
|
g_Menus[g_MpPlayerNum].data.pak.noteindex = data->list.value;
|
|
menuPushDialog(&g_PakDeleteGameNoteMenuDialog);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char var7f1b34dc[] = "GOT OKed!\n";
|
|
const char var7f1b34e8[] = "Try to find last opened file...\n";
|
|
|
|
s32 pakGameNotesMenuDialog(u32 operation, struct menudialog *dialog, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_TICK) {
|
|
if (g_Menus[g_MpPlayerNum].curframe
|
|
&& g_Menus[g_MpPlayerNum].curframe->dialog == dialog) {
|
|
s32 value = func0f1168c4(g_Menus[g_MpPlayerNum].data.pak.device, &g_EditingPak);
|
|
|
|
if (value) {
|
|
menuCloseDialog();
|
|
g_EditingPak = NULL;
|
|
g_Menus[g_MpPlayerNum].unke3c = g_Menus[g_MpPlayerNum].data.pak.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)
|
|
{
|
|
s32 haspdnote = false;
|
|
s32 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."
|
|
}
|
|
|
|
char *pakMenuTextEditingPakName(struct menuitem *item)
|
|
{
|
|
return filemgrGetDeviceName(g_Menus[g_MpPlayerNum].data.pak.device);
|
|
}
|
|
|
|
s32 pakSelectionMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKDISABLED) {
|
|
if (!pakIsConnected((s8)item->param)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_SET) {
|
|
g_Menus[g_MpPlayerNum].data.pak.device = item->param;
|
|
menuPushDialog(&g_PakGameNotesMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 pakChoosePakMenuDialog(u32 operation, struct menudialog *dialog, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_OPEN:
|
|
func0001398c(3);
|
|
g_Menus[g_MpPlayerNum].data.pak.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].data.pak.unke24 & (1 << i)) {
|
|
g_Vars.unk0004e4 &= 0xfff0;
|
|
g_Vars.unk0004e4 |= 0x0008;
|
|
g_Vars.unk0004e4 |= 1 << (i + 8);
|
|
}
|
|
}
|
|
}
|
|
func000139c8();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrOpenCopyFileMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone = item->param + 1;
|
|
func0f110c5c(0, item->param);
|
|
g_Menus[g_MpPlayerNum].listnum = 0;
|
|
g_Menus[g_MpPlayerNum].data.filemgr.isdeletingforsave = false;
|
|
menuPushDialog(&g_FilemgrCopyListMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrOpenDeleteFileMenuHandler(u32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone = item->param + 1;
|
|
func0f110c5c(0, item->param);
|
|
g_Menus[g_MpPlayerNum].unke3e = -1;
|
|
filemgrPushDeleteFileDialog(0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrAgentNameKeyboardMenuHandler(u32 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_SoloSaveFile.name);
|
|
break;
|
|
case MENUOP_SETTEXT:
|
|
strcpy(g_SoloSaveFile.name, name);
|
|
break;
|
|
case MENUOP_SET:
|
|
filemgrPushSelectLocationDialog(0, 0);
|
|
g_Menus[g_MpPlayerNum].data.filemgr.unke2c = 1;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrChooseAgentListMenuHandler(u32 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 savelocation000 *location000;
|
|
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].data.filemgr.unke2c == 1) {
|
|
for (i = 0; i < g_FileLists[0]->numfiles; i++) {
|
|
if (g_FilemgrLoadedMainFile.unk00 == g_FileLists[0]->unk000[i].unk00
|
|
&& g_FilemgrLoadedMainFile.unk04 == g_FileLists[0]->unk000[i].unk04) {
|
|
data->list.value = i;
|
|
}
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].data.filemgr.unke2c = 0;
|
|
}
|
|
|
|
if (g_FileLists[0]->unk30e) {
|
|
pass = true;
|
|
}
|
|
} else {
|
|
pass = true;
|
|
g_Menus[g_MpPlayerNum].data.filemgr.unke2c = 0;
|
|
}
|
|
|
|
if (pass && g_Vars.unk00047c) {
|
|
for (j = 0; j < g_FileLists[0]->numfiles; j++) {
|
|
if (g_Vars.unk00047c == g_FileLists[0]->unk000[j].unk00
|
|
&& g_Vars.unk000480 == g_FileLists[0]->unk000[j].unk04) {
|
|
data->list.value = j;
|
|
g_Vars.unk00047c = 0;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = g_FileLists[0]->numfiles + 1;
|
|
break;
|
|
case MENUOP_RENDER:
|
|
gdl = data->type19.gdl;
|
|
texturenum = 12;
|
|
location000 = NULL;
|
|
renderdata = data->type19.renderdata2;
|
|
seconds = 0;
|
|
minutes = 0;
|
|
hours = 0;
|
|
days = 0;
|
|
|
|
if (data->list.unk04 != g_FileLists[0]->numfiles) {
|
|
location000 = &g_FileLists[0]->unk000[data->list.unk04];
|
|
|
|
if (location000) {
|
|
savefileGetOverview(location000->unk06, 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, &var800ab5a8[texturenum], 2, 0, 2, 1, 0);
|
|
|
|
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_ScreenWidthMultiplier,
|
|
(renderdata->y + 2) << 2,
|
|
((renderdata->x + 60) << 2) * g_ScreenWidthMultiplier,
|
|
(renderdata->y + 38) << 2,
|
|
G_TX_RENDERTILE, 0, 1152, 1024 / g_ScreenWidthMultiplier, -1024);
|
|
|
|
x = renderdata->x + 62;
|
|
y = renderdata->y + 4;
|
|
gdl = func0f153628(gdl);
|
|
|
|
if (data->list.unk04 == g_FileLists[0]->numfiles) {
|
|
// "New Agent..."
|
|
gdl = textRenderProjected(gdl, &x, &y, langGet(L_OPTIONS(403)),
|
|
var8007fb18, var8007fb14, renderdata->colour, viGetX(), viGetY(), 0, 0);
|
|
} else {
|
|
if (location000) {
|
|
// Render file name
|
|
gdl = textRenderProjected(gdl, &x, &y, name,
|
|
var8007fb18, var8007fb14, renderdata->colour, viGetX(), viGetY(), 0, 1);
|
|
|
|
// Prepare and render stage name
|
|
y = renderdata->y + 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,
|
|
var8007fb10, var8007fb0c, renderdata->colour, viGetX(), viGetY(), 0, 0);
|
|
|
|
// Prepare and render mission time
|
|
x = renderdata->x + 62;
|
|
y++;
|
|
|
|
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
|
|
textMeasure(&textheight, &textwidth, buffer, var8007fb10, var8007fb0c, 0);
|
|
|
|
gdl = textRenderProjected(gdl, &x, &y, buffer,
|
|
var8007fb10, var8007fb0c, renderdata->colour, viGetX(), viGetY(), 0, 0);
|
|
|
|
// Render seconds part of mission time (uses a smaller font)
|
|
y++;
|
|
x++;
|
|
sprintf(buffer, ".%02d", seconds);
|
|
gdl = textRenderProjected(gdl, &x, &y, buffer,
|
|
var8007fb08, var8007fb04, renderdata->colour, viGetX(), viGetY(), 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) {
|
|
savefileLoadDefaults(&g_SoloSaveFile);
|
|
menuPushDialog(&g_FilemgrEnterAgentNameMenuDialog);
|
|
} else {
|
|
struct savelocation000 *file = &g_FileLists[0]->unk000[data->list.value];
|
|
|
|
if (file) {
|
|
g_FilemgrLoadedMainFile.unk00 = file->unk00;
|
|
g_FilemgrLoadedMainFile.unk04 = file->unk04;
|
|
func0f1094e4(&g_FilemgrLoadedMainFile, 100, 0);
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = g_FileLists[0]->unk30a + 1;
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
if (data->list.value >= g_FileLists[0]->unk30a) {
|
|
return (u32) langGet(L_OPTIONS(402)); // "New..."
|
|
}
|
|
return filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
if (data->list.value >= g_FileLists[0]->unk30a) {
|
|
data->list.groupstartindex = g_FileLists[0]->numfiles;
|
|
} else {
|
|
data->list.groupstartindex = filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 filemgrMainMenuDialog(u32 operation, struct menudialog *dialog, union handlerdata *data)
|
|
{
|
|
s32 i;
|
|
|
|
switch (operation) {
|
|
case MENUOP_OPEN:
|
|
g_Menus[g_MpPlayerNum].data.filemgr.filetypeplusone = 0;
|
|
|
|
func0f110c5c(0, FILETYPE_SOLO);
|
|
func0f188210();
|
|
|
|
// Set MP player names to "Player 1" through 4 if blank
|
|
for (i = 0; i < 4; i++) {
|
|
if (g_MpPlayers[i].base.name[0] == '\0') {
|
|
sprintf(g_MpPlayers[i].base.name, "%s %d\n", langGet(L_MISC(437)), i + 1);
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_CLOSE:
|
|
func0f110bf8();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool filemgrConsiderPushingFileSelectDialog(void)
|
|
{
|
|
if (g_Menus[g_MpPlayerNum].unk83c == 0) {
|
|
g_Menus[g_MpPlayerNum].playernum = 0;
|
|
menuPushRootDialog(&g_FilemgrMainMenuDialog, MENUROOT_FILEMGR);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
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 menudialog g_FilemgrSelectLocationMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(367), // "Select Location"
|
|
g_FilemgrSelectLocationMenuItems,
|
|
NULL,
|
|
0x00000080,
|
|
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 menudialog g_FilemgrConfirmDeleteMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS(379), // "Warning"
|
|
g_FilemgrConfirmDeleteMenuItems,
|
|
NULL,
|
|
0x00000080,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrFileInUseMenuItems[] = {
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00000030, (u32)&filemgrMenuTextDeleteFileName, 0x00000000, filemgrFileNameMenuHandler },
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00000230, (u32)&filemgrMenuTextDeviceName, 0x00000000, filemgrDeviceNameMenuHandler },
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00000010, (u32)&filemgrMenuTextFileInUseDescription, 0x00000000, NULL },
|
|
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000028, L_MPWEAPONS(161), 0x00000000, NULL }, // "Cancel"
|
|
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
|
};
|
|
|
|
struct menudialog g_FilemgrFileInUseMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_MPWEAPONS(159), // "Error"
|
|
g_FilemgrFileInUseMenuItems,
|
|
NULL,
|
|
0x00000080,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrDeleteFileMenuItems[] = {
|
|
{ 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 menudialog g_FilemgrDeleteFileMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(376), // "Delete File"
|
|
g_FilemgrDeleteFileMenuItems,
|
|
filemgrCopyOrDeleteListMenuDialog,
|
|
0x00000000,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrCopyListMenuItems[] = {
|
|
{ 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 menudialog g_FilemgrCopyListMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(373), // "Copy File"
|
|
g_FilemgrCopyListMenuItems,
|
|
filemgrCopyOrDeleteListMenuDialog,
|
|
0x00000000,
|
|
NULL,
|
|
};
|
|
|
|
struct pakdata *g_EditingPak = NULL;
|
|
|
|
struct menuitem g_PakDeleteGameNoteMenuItems[] = {
|
|
{ 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 menudialog g_PakDeleteGameNoteMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS(383), // "Delete Game Note"
|
|
g_PakDeleteGameNoteMenuItems,
|
|
NULL,
|
|
0x00000000,
|
|
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 menudialog g_PakGameNotesMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(387), // "Game Notes"
|
|
g_PakGameNotesMenuItems,
|
|
pakGameNotesMenuDialog,
|
|
0x00000000,
|
|
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 menudialog g_PakChoosePakMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(107), // "Controller Pak Menu"
|
|
g_PakChoosePakMenuItems,
|
|
pakChoosePakMenuDialog,
|
|
0x00000000,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrOperationsMenuItems[] = {
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00004010, L_OPTIONS(100), 0x00000000, NULL }, // "Copy:"
|
|
{ MENUITEMTYPE_SELECTABLE, FILETYPE_SOLO, 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_SOLO, 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 menudialog g_FilemgrOperationsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(99), // "Game Files"
|
|
g_FilemgrOperationsMenuItems,
|
|
NULL,
|
|
0x00000020,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrEnterAgentNameMenuItems[] = {
|
|
{ MENUITEMTYPE_KEYBOARD, 0, 0x00000000, 0x00000000, 0x00000001, filemgrAgentNameKeyboardMenuHandler },
|
|
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
|
};
|
|
|
|
struct menudialog g_FilemgrEnterAgentNameMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(401), // "Enter Agent Name"
|
|
g_FilemgrEnterAgentNameMenuItems,
|
|
NULL,
|
|
0x00000000,
|
|
NULL,
|
|
};
|
|
|
|
struct menuitem g_FilemgrMainMenuItems[] = {
|
|
{ MENUITEMTYPE_LABEL, 0, 0x00004010, L_OPTIONS(96), 0x00000000, NULL }, // "Choose Your Reality"
|
|
{ MENUITEMTYPE_LIST, 0, 0x00200000, 0x000000f5, 0x00000000, filemgrChooseAgentListMenuHandler },
|
|
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
|
|
};
|
|
|
|
struct menudialog g_FilemgrMainMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS(95), // "Perfect Dark"
|
|
g_FilemgrMainMenuItems,
|
|
filemgrMainMenuDialog,
|
|
0x00000020,
|
|
&g_FilemgrOperationsMenuDialog,
|
|
};
|