Files
perfect-dark/src/game/mplayer/setup.c
T

4258 lines
129 KiB
C

#include <ultra64.h>
#include "constants.h"
#include "game/camdraw.h"
#include "game/game_0b3350.h"
#include "game/savebuffer.h"
#include "game/menu.h"
#include "game/mainmenu.h"
#include "game/filemgr.h"
#include "game/game_1531a0.h"
#include "game/music.h"
#include "game/mplayer/ingame.h"
#include "game/mplayer/setup.h"
#include "game/mplayer/scenarios.h"
#include "game/game_19aa80.h"
#include "game/lang.h"
#include "game/mplayer/mplayer.h"
#include "game/options.h"
#include "bss.h"
#include "lib/snd.h"
#include "lib/vi.h"
#include "lib/rng.h"
#include "data.h"
#include "types.h"
struct menuitem g_MpCharacterMenuItems[];
struct menudialogdef g_MpAddSimulantMenuDialog;
struct menudialogdef g_MpChangeSimulantMenuDialog;
struct menudialogdef g_MpChangeTeamNameMenuDialog;
struct menudialogdef g_MpEditSimulantMenuDialog;
struct menudialogdef g_MpSaveSetupNameMenuDialog;
s32 menuhandlerMpDropOut(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
menuPopDialog();
menuPopDialog();
}
return 0;
}
char *mpGetCurrentPlayerName(struct menuitem *item)
{
return g_PlayerConfigsArray[g_MpPlayerNum].base.name;
}
s32 menuhandlerMpTeamsLabel(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKDISABLED) {
if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) == 0) {
return true;
}
}
return 0;
}
struct menuitem g_MpDropOutMenuItems[] = {
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_196, 0x00000000, NULL }, // "Are you sure you want to drop out?"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_197, 0x00000000, menuhandlerMpDropOut }, // "Drop Out"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_198, 0x00000000, NULL }, // "Cancel"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpDropOutMenuDialog = {
MENUDIALOGTYPE_DANGER,
L_MPMENU_195, // "Drop Out"
g_MpDropOutMenuItems,
NULL,
0,
NULL,
};
struct mparena g_MpArenas[] = {
// Stage, unlock, name
{ STAGE_MP_SKEDAR, 0, L_MPMENU_119 },
{ STAGE_MP_PIPES, 0, L_MPMENU_120 },
{ STAGE_MP_RAVINE, MPFEATURE_STAGE_RAVINE, L_MPMENU_121 },
{ STAGE_MP_G5BUILDING, MPFEATURE_STAGE_G5BUILDING, L_MPMENU_122 },
{ STAGE_MP_SEWERS, MPFEATURE_STAGE_SEWERS, L_MPMENU_123 },
{ STAGE_MP_WAREHOUSE, MPFEATURE_STAGE_WAREHOUSE, L_MPMENU_124 },
{ STAGE_MP_GRID, MPFEATURE_STAGE_GRID, L_MPMENU_125 },
{ STAGE_MP_RUINS, MPFEATURE_STAGE_RUINS, L_MPMENU_126 },
{ STAGE_MP_AREA52, 0, L_MPMENU_127 },
{ STAGE_MP_BASE, MPFEATURE_STAGE_BASE, L_MPMENU_128 },
{ STAGE_MP_FORTRESS, MPFEATURE_STAGE_FORTRESS, L_MPMENU_130 },
{ STAGE_MP_VILLA, MPFEATURE_STAGE_VILLA, L_MPMENU_131 },
{ STAGE_MP_CARPARK, MPFEATURE_STAGE_CARPARK, L_MPMENU_132 },
{ STAGE_MP_TEMPLE, MPFEATURE_STAGE_TEMPLE, L_MPMENU_133 },
{ STAGE_MP_COMPLEX, MPFEATURE_STAGE_COMPLEX, L_MPMENU_134 },
{ STAGE_MP_FELICITY, MPFEATURE_STAGE_FELICITY, L_MPMENU_135 },
{ 1, 0, L_MPMENU_136 }, // "Random"
};
s32 mpGetNumStages(void)
{
return 17;
}
s16 mpChooseRandomStage(void)
{
s32 i;
s32 numchallengescomplete = 0;
s32 index;
for (i = 0; i < 16; i++) {
if (mpIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
numchallengescomplete++;
}
}
index = random() % numchallengescomplete;
for (i = 0; i < 16; i++) {
if (mpIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
if (index == 0) {
return g_MpArenas[i].stagenum;
}
index--;
}
}
return STAGE_MP_SKEDAR;
}
s32 mpArenaMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
struct optiongroup groups[] = {
{ 0, L_MPMENU_116 }, // "Dark"
{ 13, L_MPMENU_117 }, // "Classic"
{ 16, L_MPMENU_118 }, // "Random"
};
s32 i;
s32 count = 0;
s32 groupindex;
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
if (mpIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
count++;
}
}
data->list.value = count;
break;
case MENUOP_GETOPTIONTEXT:
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
if (mpIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
if (count == data->list.value) {
return (s32)langGet(g_MpArenas[i].name);
}
count++;
}
}
break;
case MENUOP_SET:
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
if (mpIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
if (count == data->list.value) {
break;
}
count++;
}
}
g_MpSetup.stagenum = g_MpArenas[i].stagenum;
break;
case MENUOP_GETOPTIONVALUE:
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
if (g_MpSetup.stagenum == g_MpArenas[i].stagenum) {
data->list.value = count;
}
if (mpIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
count++;
}
}
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = 3;
if (!mpIsFeatureUnlocked(MPFEATURE_STAGE_COMPLEX)
&& !mpIsFeatureUnlocked(MPFEATURE_STAGE_TEMPLE)
&& !mpIsFeatureUnlocked(MPFEATURE_STAGE_FELICITY)) {
data->list.value--;
}
break;
case MENUOP_GETOPTGROUPTEXT:
count = data->list.value;
if (!mpIsFeatureUnlocked(MPFEATURE_STAGE_COMPLEX)
&& !mpIsFeatureUnlocked(MPFEATURE_STAGE_TEMPLE)
&& !mpIsFeatureUnlocked(MPFEATURE_STAGE_FELICITY)
&& count > 0) {
count++;
}
return (s32)langGet(groups[count].name);
case MENUOP_GETGROUPSTARTINDEX:
groupindex = data->list.value;
if (!mpIsFeatureUnlocked(MPFEATURE_STAGE_COMPLEX)
&& !mpIsFeatureUnlocked(MPFEATURE_STAGE_TEMPLE)
&& !mpIsFeatureUnlocked(MPFEATURE_STAGE_FELICITY)
&& groupindex == 1) {
groupindex++;
}
for (i = 0; i < groups[groupindex].offset; i++) {
if (mpIsFeatureUnlocked(g_MpArenas[i].requirefeature)) {
count++;
}
}
data->list.groupstartindex = count;
break;
}
return 0;
}
s32 menuhandlerMpControlStyle(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 labels[] = {
L_OPTIONS_239, // "1.1"
L_OPTIONS_240, // "1.2"
L_OPTIONS_241, // "1.3"
L_OPTIONS_242, // "1.4"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 4;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(labels[data->dropdown.value]);
case MENUOP_SET:
optionsSetControlMode(g_MpPlayerNum, data->dropdown.value);
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = optionsGetControlMode(g_MpPlayerNum);
break;
}
return 0;
}
s32 menuhandlerMpWeaponSlot(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = mpGetNumWeaponOptions();
break;
case MENUOP_GETOPTIONTEXT:
return (s32) mpGetWeaponLabel(data->dropdown.value);
case MENUOP_SET:
mpSetWeaponSlot(item->param3, data->dropdown.value);
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = mpGetWeaponSlot(item->param3);
}
return 0;
}
char *mpMenuTextWeaponNameForSlot(struct menuitem *item)
{
return mpGetWeaponLabel(mpGetWeaponSlot(item->param));
}
s32 menuhandlerMpWeaponSetDropdown(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = func0f189058(item->param);
break;
case MENUOP_GETOPTIONTEXT:
return (s32) mpGetWeaponSetName(data->dropdown.value);
case MENUOP_SET:
mpSetWeaponSet(data->dropdown.value);
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = mpGetWeaponSet();
break;
}
return 0;
}
s32 menuhandlerMpControlCheckbox(s32 operation, struct menuitem *item, union handlerdata *data)
{
s32 val;
switch (operation) {
case MENUOP_GET:
if (item->param3 == OPTION_FORWARDPITCH) {
if ((g_PlayerConfigsArray[g_MpPlayerNum].options & item->param3) == 0) {
return true;
}
return false;
}
if ((g_PlayerConfigsArray[g_MpPlayerNum].options & item->param3) == 0) {
return false;
}
return true;
case MENUOP_SET:
val = OPTION_FORWARDPITCH;
if (item->param3 == val) {
if (data->checkbox.value == 0) {
data->checkbox.value = val;
} else {
data->checkbox.value = 0;
}
}
g_PlayerConfigsArray[g_MpPlayerNum].options &= ~item->param3;
if (data->checkbox.value) {
g_PlayerConfigsArray[g_MpPlayerNum].options |= item->param3;
}
}
return 0;
}
s32 menuhandlerMpAimControl(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 labels[] = {
#if VERSION >= VERSION_PAL_FINAL
L_MPWEAPONS_276, // "Hold"
L_MPWEAPONS_277, // "Toggle"
#else
L_MPMENU_213, // "Hold"
L_MPMENU_214, // "Toggle"
#endif
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 2;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(labels[data->dropdown.value]);
case MENUOP_SET:
optionsSetAimControl(g_MpPlayerNum, data->dropdown.value);
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = optionsGetAimControl(g_MpPlayerNum);
break;
}
return 0;
}
s32 menuhandlerMpCheckboxOption(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
if ((g_MpSetup.options & item->param3) == 0) {
return false;
}
return true;
case MENUOP_SET:
g_MpSetup.options = g_MpSetup.options & ~item->param3;
if (data->checkbox.value) {
g_MpSetup.options = g_MpSetup.options | item->param3;
}
}
return 0;
}
s32 menuhandlerMpTeamsEnabled(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKDISABLED) {
if (g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE ||
g_MpSetup.scenario == MPSCENARIO_KINGOFTHEHILL) {
return true;
}
return false;
}
return menuhandlerMpCheckboxOption(operation, item, data);
}
s32 menuhandlerMpDisplayOptionCheckbox(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
if ((g_PlayerConfigsArray[g_MpPlayerNum].base.displayoptions & item->param3) == 0) {
return false;
}
return true;
case MENUOP_SET:
g_PlayerConfigsArray[g_MpPlayerNum].base.displayoptions &= ~(u8)item->param3;
if (data->checkbox.value) {
g_PlayerConfigsArray[g_MpPlayerNum].base.displayoptions |= (u8)item->param3;
}
break;
}
return 0;
}
s32 menuhandlerMpConfirmSaveChr(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
menuPopDialog();
filemgrPushSelectLocationDialog(6, FILETYPE_MPPLAYER);
}
return 0;
}
s32 menuhandlerMpSetupName(s32 operation, struct menuitem *item, union handlerdata *data)
{
char *name = data->keyboard.string;
switch (operation) {
case MENUOP_GETTEXT:
strcpy(name, g_MpSetup.name);
break;
case MENUOP_SETTEXT:
strcpy(g_MpSetup.name, name);
break;
case MENUOP_SET:
filemgrPushSelectLocationDialog(7, FILETYPE_MPSETUP);
break;
}
return 0;
}
s32 menuhandlerMpSaveSetupOverwrite(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
menuPopDialog();
filemgrSaveOrLoad(&g_MpSetup.fileguid, FILEOP_SAVE_MPSETUP, 0);
}
return 0;
}
s32 menuhandlerMpSaveSetupCopy(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
menuPopDialog();
menuPushDialog(&g_MpSaveSetupNameMenuDialog);
}
return 0;
}
#if VERSION >= VERSION_NTSC_1_0
char *mpMenuTextSetupName(struct menuitem *item)
{
return g_MpSetup.name;
}
#endif
s32 func0f179b68(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = g_PlayerConfigsArray[g_MpPlayerNum].base.unk18;
break;
case MENUOP_SET:
g_PlayerConfigsArray[g_MpPlayerNum].base.unk18 = (u8) data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
sprintf(data->slider.label, "%d%%\n", data->slider.value + 20);
break;
}
return 0;
}
s32 func0f179c14(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = g_PlayerConfigsArray[g_MpPlayerNum].base.unk1a;
break;
case MENUOP_SET:
g_PlayerConfigsArray[g_MpPlayerNum].base.unk1a = (u8) data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
sprintf(data->slider.label, "%d%%\n", data->slider.value + 20);
break;
}
return 0;
}
s32 func0f179cc0(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = g_PlayerConfigsArray[g_MpPlayerNum].base.unk1c;
break;
case MENUOP_SET:
g_PlayerConfigsArray[g_MpPlayerNum].base.unk1c = data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
sprintf(data->slider.label, "%d%%\n", data->slider.value + 25);
break;
}
return 0;
}
s32 func0f179d6c(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
func0f187fbc(g_MpPlayerNum);
}
return 0;
}
/**
* This function is used by both player body selection and bot body selection.
*/
s32 mpCharacterBodyMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data, s32 mpheadnum, s32 mpbodynum, bool isplayer)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->carousel.value = mpGetNumBodies();
break;
case MENUOP_11:
g_Menus[g_MpPlayerNum].unk840.unk05c = 0x1fc;
g_Menus[g_MpPlayerNum].unk840.unk00c = mpbodynum << 16 | 0xffff | mpheadnum << 24;
g_Menus[g_MpPlayerNum].unk840.unk574 += g_Vars.diffframe60;
if (g_Menus[g_MpPlayerNum].unk840.unk574 > TICKS(480)) {
g_Menus[g_MpPlayerNum].unk840.unk574 -= TICKS(480);
}
if (g_Menus[g_MpPlayerNum].unk840.unk578 > 0) {
g_Menus[g_MpPlayerNum].unk840.unk578 -= g_Vars.diffframe60;
} else {
#if VERSION >= VERSION_PAL_BETA
f32 value = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60freal;
#else
f32 value = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60f;
#endif
g_Menus[g_MpPlayerNum].unk840.unk54c = value;
g_Menus[g_MpPlayerNum].unk840.unk524 = value;
}
g_Menus[g_MpPlayerNum].unk840.partvisibility = NULL;
g_Menus[g_MpPlayerNum].unk840.unk554 = 30;
break;
case MENUOP_21:
if (!mpIsFeatureUnlocked(mpGetBodyRequiredFeature(data->carousel.value))) {
return 1;
}
break;
#if VERSION >= VERSION_NTSC_1_0
case MENUOP_FOCUS:
g_Menus[g_MpPlayerNum].unk840.unk000 = 3;
break;
#endif
case MENUOP_GETOPTIONVALUE:
data->carousel.value = mpheadnum;
break;
case MENUOP_SET:
case MENUOP_CHECKPREFOCUSED:
g_Menus[g_MpPlayerNum].unk840.unk580 = 0;
func0f0f372c(&g_Menus[g_MpPlayerNum].unk840, 0, 0, 0, 0, 0, 0, 1, 1);
g_Menus[g_MpPlayerNum].unk840.unk510 = 8.2f;
g_Menus[g_MpPlayerNum].unk840.unk514 = -4.1f;
g_Menus[g_MpPlayerNum].unk840.unk53c = -4.1f;
g_Menus[g_MpPlayerNum].unk840.unk538 = 8.2f;
g_Menus[g_MpPlayerNum].unk840.unk51c = 0.002f;
g_Menus[g_MpPlayerNum].unk840.unk524 = -0.2f;
g_Menus[g_MpPlayerNum].unk840.unk54c = -0.2f;
g_Menus[g_MpPlayerNum].unk840.unk578 = TICKS(60);
g_Menus[g_MpPlayerNum].unk840.unk574 = TICKS(120);
g_Menus[g_MpPlayerNum].unk840.unk000 = 8;
#if VERSION >= VERSION_NTSC_1_0
if (operation == MENUOP_CHECKPREFOCUSED) {
g_Menus[g_MpPlayerNum].unk840.unk000 = 16;
}
#endif
break;
}
return 0;
}
s32 menuhandlerMpCharacterBody(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_SET:
if (g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum < mpGetNumHeads()) {
#if VERSION >= VERSION_NTSC_1_0
if (!data->carousel.unk04)
#endif
{
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum = mpGetMpheadnumByMpbodynum(data->carousel.value);
}
}
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum = data->carousel.value;
func0f17b8f0();
break;
case MENUOP_CHECKPREFOCUSED:
#if VERSION >= VERSION_NTSC_1_0
mpCharacterBodyMenuHandler(operation, item, data,
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum,
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, true);
#endif
return true;
}
return mpCharacterBodyMenuHandler(operation, item, data,
g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum,
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, true);
}
s32 menudialog0017a174(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
switch (operation) {
case MENUOP_OPEN:
break;
case MENUOP_CLOSE:
break;
case MENUOP_TICK:
if (g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[1]
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[2]) {
union handlerdata data;
menuhandlerMpCharacterBody(MENUOP_11, &dialogdef->items[2], &data);
}
}
return 0;
}
s32 mpChallengesListHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
Gfx *gdl;
struct menuitemrenderdata *renderdata;
s32 challengeindex;
s32 x;
s32 y;
s32 loopx;
s32 maxplayers;
s32 i;
char *name;
s32 size = 11;
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = mpGetAutoFocusedChallengeIndex(g_MpPlayerNum);
break;
case MENUOP_RENDER:
maxplayers = 4;
gdl = data->type19.gdl;
renderdata = data->type19.renderdata2;
challengeindex = data->list.unk04;
if (IS4MB()) {
maxplayers = 2;
}
x = renderdata->x + 10;
y = renderdata->y + 1;
gdl = func0f153628(gdl);
name = mpChallengeGetNameWithArg(g_MpPlayerNum, challengeindex);
gdl = textRenderProjected(gdl, &x, &y, name,
g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour,
viGetWidth(), viGetHeight(), 0, 0);
gdl = func0f153780(gdl);
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[35], 2, 0, 2, 1, NULL);
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
gDPSetTextureFilter(gdl++, G_TF_POINT);
for (i = 0, loopx = 10; i < maxplayers; i++) {
#if VERSION >= VERSION_NTSC_1_0
if (mpIsChallengeCompletedByPlayerWithNumPlayers2(g_MpPlayerNum, challengeindex, i + 1)) {
gDPSetEnvColorViaWord(gdl++, 0xb2efff00 | (renderdata->colour & 0xff) * 255 / 256);
} else {
gDPSetEnvColorViaWord(gdl++, 0x30407000 | (renderdata->colour & 0xff) * 255 / 256);
}
#else
if (mpIsChallengeCompletedByPlayerWithNumPlayers2(g_MpPlayerNum, challengeindex, i + 1)) {
gDPSetEnvColorViaWord(gdl++, 0xb2efffff);
} else {
gDPSetEnvColorViaWord(gdl++, 0x304070ff);
}
#endif
gDPSetCombineLERP(gdl++,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0);
gSPTextureRectangle(gdl++,
((renderdata->x + loopx) << 2) * g_ScaleX,
(renderdata->y + size) << 2,
((renderdata->x + size + loopx) << 2) * g_ScaleX,
(renderdata->y + size * 2) << 2,
G_TX_RENDERTILE,
0, 0x0160, 0x0400 / g_ScaleX, 0xfc00);
loopx += 13;
}
return (s32) gdl;
case MENUOP_GETOPTIONHEIGHT:
data->list.value = 26;
break;
}
return 0;
}
const char var7f1b7ea8[] = "Menu99 -> Calling Camera Module Start\n";
const char var7f1b7ed0[] = "Menu99 -> Calling Camera Module Finish\n";
char *mpMenuTextKills(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].kills);
return g_StringPointer;
}
char *mpMenuTextDeaths(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].deaths);
return g_StringPointer;
}
char *mpMenuTextGamesPlayed(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gamesplayed);
return g_StringPointer;
}
char *mpMenuTextGamesWon(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gameswon);
return g_StringPointer;
}
char *mpMenuTextGamesLost(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].gameslost);
return g_StringPointer;
}
char *mpMenuTextHeadShots(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].headshots);
return g_StringPointer;
}
char *mpMenuTextMedalAccuracy(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].accuracymedals);
return g_StringPointer;
}
char *mpMenuTextMedalHeadShot(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].headshotmedals);
return g_StringPointer;
}
char *mpMenuTextMedalKillMaster(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].killmastermedals);
return g_StringPointer;
}
char *mpMenuTextMedalSurvivor(struct menuitem *item)
{ \
sprintf(g_StringPointer, "%d\n", g_PlayerConfigsArray[g_MpPlayerNum].survivormedals);
return g_StringPointer;
}
char *mpMenuTextAmmoUsed(struct menuitem *item)
{
s32 value = g_PlayerConfigsArray[g_MpPlayerNum].ammoused;
if (value > 100000) {
value = value / 1000;
if (value > 100000) {
value = value / 1000;
sprintf(g_StringPointer, "%dM\n", value);
} else {
sprintf(g_StringPointer, "%dK\n", value);
}
} else {
sprintf(g_StringPointer, "%d\n", value);
}
return g_StringPointer;
}
char *mpMenuTextDistance(struct menuitem *item)
{
sprintf(g_StringPointer, "%s%s%.1fkm\n", "", "", g_PlayerConfigsArray[g_MpPlayerNum].distance / 10.0f);
return g_StringPointer;
}
char *mpMenuTextTime(struct menuitem *item)
{
u32 raw = g_PlayerConfigsArray[g_MpPlayerNum].time;
s32 secs = raw % 60;
s32 hours;
s32 days;
if (raw == 0) {
return "--:--\n";
}
if (raw >= 0x7fffffff) {
return "==:==\n";
}
raw = raw / 60;
hours = raw / 60;
days = hours / 24;
if (days == 0) {
sprintf(g_StringPointer, "%d:%02d.%02d", hours % 24, raw % 60, secs);
} else {
sprintf(g_StringPointer, "%d:%02d:%02d", days, hours % 24, raw % 60);
}
return g_StringPointer;
}
char *mpMenuTextAccuracy(struct menuitem *item)
{
#if VERSION < VERSION_NTSC_1_0
if (g_PlayerConfigsArray[g_MpPlayerNum].gamesplayed < 8) {
return "-\n";
}
#endif
sprintf(g_StringPointer, "%s%s%.1f%%", "", "", g_PlayerConfigsArray[g_MpPlayerNum].accuracy / 10.0f);
return g_StringPointer;
}
void mpFormatDamageValue(char *dst, f32 damage)
{
#if VERSION >= VERSION_NTSC_1_0
if (damage < 1000) {
sprintf(dst, "%s%s%.1f", "", "", damage);
} else if (damage < 10000) {
sprintf(dst, "%s%s%.0f", "", "", damage);
} else if (damage < 100000) {
damage = damage / 1000;
sprintf(dst, "%s%s%.1fK", "", "", damage);
} else if (damage < 1000000) {
damage = damage / 1000;
sprintf(dst, "%s%s%.0fK", "", "", damage);
} else if (damage < 10000000) {
damage = damage / 1000;
damage = damage / 1000;
sprintf(dst, "%s%s%.1fM", "", "", damage);
} else {
damage = damage / 1000;
damage = damage / 1000;
sprintf(dst, "%s%s%.0fM", "", "", damage);
}
#else
if (damage > 100000) {
damage = damage / 1000;
sprintf(dst, "%s%s%.1fKL", "", "", damage);
} else {
sprintf(dst, "%s%s%.1fL", "", "", damage);
}
#endif
}
char *mpMenuTextPainReceived(struct menuitem *item)
{
mpFormatDamageValue(g_StringPointer, g_PlayerConfigsArray[g_MpPlayerNum].painreceived / 10.0f);
return g_StringPointer;
}
char *mpMenuTextDamageDealt(struct menuitem *item)
{
mpFormatDamageValue(g_StringPointer, g_PlayerConfigsArray[g_MpPlayerNum].damagedealt / 10.0f);
return g_StringPointer;
}
s32 mpMedalMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_RENDER) {
Gfx *gdl = data->type19.gdl;
struct menuitemrenderdata *renderdata = data->type19.renderdata2;
u32 colour;
gDPPipeSync(gdl++);
gDPSetTexturePersp(gdl++, G_TP_NONE);
gDPSetAlphaCompare(gdl++, G_AC_NONE);
gDPSetTextureLOD(gdl++, G_TL_TILE);
gDPSetTextureConvert(gdl++, G_TC_FILT);
gDPSetTextureFilter(gdl++, G_TF_POINT);
func0f0b39c0(&gdl, &g_TexGeneralConfigs[35], 2, 0, 2, 1, NULL);
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
gDPSetCombineMode(gdl++, G_CC_DECALRGBA, G_CC_DECALRGBA);
gDPSetTextureFilter(gdl++, G_TF_POINT);
switch (item->param) {
case 0: // KillMaster - red
colour = 0xff7f7fff;
break;
case 1: // Headshot - yellow
colour = 0xbfbf00ff;
break;
case 2: // Accuracy - green
colour = 0x00ff00ff;
break;
case 3: // Survivor - blue
colour = 0x00bfbfff;
break;
}
#if VERSION >= VERSION_NTSC_1_0
colour = colour & 0xffffff00 | (colour & 0xff) * (renderdata->colour & 0xff) >> 8;
#endif
gDPSetEnvColorViaWord(gdl++, colour);
gDPSetCombineLERP(gdl++,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0);
gSPTextureRectangle(gdl++,
((renderdata->x + 9) << 2) * g_ScaleX, renderdata->y << 2,
((renderdata->x + 20) << 2) * g_ScaleX, (renderdata->y + 11) << 2,
G_TX_RENDERTILE, 0, 0x0160, 1024 / g_ScaleX, -1024);
return (s32) gdl;
}
return 0;
}
char *mpMenuTitleStatsForPlayerName(struct menudialogdef *dialogdef)
{
// "Stats for %s"
sprintf(g_StringPointer, langGet(L_MPMENU_145), g_PlayerConfigsArray[g_MpPlayerNum].base.name);
return g_StringPointer;
}
s32 menuhandlerMpUsernamePassword(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKHIDDEN) {
if (g_PlayerConfigsArray[g_MpPlayerNum].title != MPPLAYERTITLE_PERFECT) {
return true;
}
}
return 0;
}
struct menuitem g_MpSavePlayerMenuItems[] = {
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_191, 0x00000000, NULL }, // "Your player file is always saved automatically."
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_192, 0x00000000, NULL }, // "Save a copy now?"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_193, 0x00000000, NULL }, // "No"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_194, 0x00000000, menuhandlerMpConfirmSaveChr }, // "Yes"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpSavePlayerMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_190, // "Confirm"
g_MpSavePlayerMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpSaveSetupNameMenuItems[] = {
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_189, 0x00000000, NULL }, // "Enter a name for your game setup file:"
{ MENUITEMTYPE_KEYBOARD, 0, 0x00000000, 0x00000000, 0x00000000, menuhandlerMpSetupName },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpSaveSetupNameMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_188, // "Game File Name"
g_MpSaveSetupNameMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpSaveSetupExistsMenuItems[] = {
#if VERSION >= VERSION_NTSC_1_0
{ MENUITEMTYPE_LABEL, 0, 0x00000210, L_MPWEAPONS_230, (u32)&mpMenuTextSetupName, NULL }, // "Name:"
{ MENUITEMTYPE_LABEL, 0, 0x00000230, (u32)&filemgrMenuTextDeviceName, 0x00000000, NULL },
#endif
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_184, 0x00000000, NULL }, // "Do you want to save over your original game file?"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_185, 0x00000000, menuhandlerMpSaveSetupOverwrite }, // "Save Over Original"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_186, 0x00000000, menuhandlerMpSaveSetupCopy }, // "Save Copy"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_187, 0x00000000, NULL }, // "Do Not Save"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpSaveSetupExistsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_183, // "Save Game Setup"
g_MpSaveSetupExistsMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpWeaponsMenuItems[] = {
{ MENUITEMTYPE_DROPDOWN, 1, 0x00020090, L_MPMENU_174, 0x00000000, menuhandlerMpWeaponSetDropdown }, // "Set:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000212, L_MPMENU_175, 0x00000000, NULL }, // "Current Weapon Setup:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x000a0080, L_MPMENU_176, 0x00000000, menuhandlerMpWeaponSlot }, // "1:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x000a0080, L_MPMENU_177, 0x00000001, menuhandlerMpWeaponSlot }, // "2:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x000a0080, L_MPMENU_178, 0x00000002, menuhandlerMpWeaponSlot }, // "3:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x000a0080, L_MPMENU_179, 0x00000003, menuhandlerMpWeaponSlot }, // "4:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x000a0080, L_MPMENU_180, 0x00000004, menuhandlerMpWeaponSlot }, // "5:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x000a0080, L_MPMENU_181, 0x00000005, menuhandlerMpWeaponSlot }, // "6:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_182, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpWeaponsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_173, // "Weapons"
g_MpWeaponsMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpQuickTeamWeaponsMenuItems[] = {
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020090, L_MPMENU_174, 0x00000000, menuhandlerMpWeaponSetDropdown }, // "Set:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000002, L_MPMENU_176, (u32)&mpMenuTextWeaponNameForSlot, NULL }, // "1:"
{ MENUITEMTYPE_LABEL, 1, 0x00000002, L_MPMENU_177, (u32)&mpMenuTextWeaponNameForSlot, NULL }, // "2:"
{ MENUITEMTYPE_LABEL, 2, 0x00000002, L_MPMENU_178, (u32)&mpMenuTextWeaponNameForSlot, NULL }, // "3:"
{ MENUITEMTYPE_LABEL, 3, 0x00000002, L_MPMENU_179, (u32)&mpMenuTextWeaponNameForSlot, NULL }, // "4:"
{ MENUITEMTYPE_LABEL, 4, 0x00000002, L_MPMENU_180, (u32)&mpMenuTextWeaponNameForSlot, NULL }, // "5:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_182, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpQuickTeamWeaponsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_173, // "Weapons"
g_MpQuickTeamWeaponsMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpPlayerOptionsMenuItems[] = {
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_168, MPDISPLAYOPTION_HIGHLIGHTPICKUPS, menuhandlerMpDisplayOptionCheckbox }, // "Highlight Pickups"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_169, MPDISPLAYOPTION_HIGHLIGHTPLAYERS, menuhandlerMpDisplayOptionCheckbox }, // "Highlight Players"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_170, MPDISPLAYOPTION_HIGHLIGHTTEAMS, menuhandlerMpDisplayOptionCheckbox }, // "Highlight Teams"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_171, MPDISPLAYOPTION_RADAR, menuhandlerMpDisplayOptionCheckbox }, // "Radar"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_172, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpPlayerOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_167, // "Options"
g_MpPlayerOptionsMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpControlMenuItems[] = {
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_MPMENU_200, 0x00000000, menuhandlerMpControlStyle }, // "Control Style"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_201, OPTION_FORWARDPITCH, menuhandlerMpControlCheckbox }, // "Reverse Pitch"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_202, OPTION_LOOKAHEAD, menuhandlerMpControlCheckbox }, // "Look Ahead"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_203, OPTION_HEADROLL, menuhandlerMpControlCheckbox }, // "Head Roll"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_204, OPTION_AUTOAIM, menuhandlerMpControlCheckbox }, // "Auto-Aim"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_MPMENU_205, 0x00000000, menuhandlerMpAimControl }, // "Aim Control"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_206, OPTION_SIGHTONSCREEN, menuhandlerMpControlCheckbox }, // "Sight on Screen"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_207, OPTION_ALWAYSSHOWTARGET, menuhandlerMpControlCheckbox }, // "Show Target"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_208, OPTION_SHOWZOOMRANGE, menuhandlerMpControlCheckbox }, // "Show Zoom Range"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_209, OPTION_AMMOONSCREEN, menuhandlerMpControlCheckbox }, // "Ammo on Screen"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_210, OPTION_SHOWGUNFUNCTION, menuhandlerMpControlCheckbox }, // "Gun Function"
{ MENUITEMTYPE_CHECKBOX, 0, 0x00000000, L_MPMENU_211, OPTION_PAINTBALL, menuhandlerMpControlCheckbox }, // "Paintball"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_212, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpControlMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_199, // "Control"
g_MpControlMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpCompletedChallengesMenuItems[] = {
{ MENUITEMTYPE_LIST, 0, 0x00200000, 0x00000078, 0x0000004d, mpChallengesListHandler },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpCompletedChallengesMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_165, // "Completed Challenges"
g_MpCompletedChallengesMenuItems,
NULL,
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
NULL,
};
#if VERSION >= VERSION_NTSC_1_0
char *mpMenuTextUsernamePassword(struct menuitem *item)
{
// Phrases included here to assist people searching the code for them:
// EnTROpIcDeCAy
// ZeRo-Tau
u8 username[15] = {
'E' + 9 * 1,
'n' + 9 * 2,
'T' + 9 * 3,
'R' + 9 * 4,
'O' + 9 * 5,
'p' + 9 * 6,
'I' + 9 * 7,
'c' + 9 * 8,
'D' + 9 * 9,
'e' + 9 * 10,
'C' + 9 * 11,
'A' + 9 * 12,
'y' + 9 * 13,
'\n' + 9 * 14,
'\0' + 9 * 15,
};
u8 password[10] = {
'Z' + 4 * 1,
'e' + 4 * 2,
'R' + 4 * 3,
'o' + 4 * 4,
'-' + 4 * 5,
'T' + 4 * 6,
'a' + 4 * 7,
'u' + 4 * 8,
'\n' + 4 * 9,
'\0' + 4 * 10,
};
u32 stack;
s32 i;
if (item->param == 0) {
for (i = 0; i < 15; i++) {
g_StringPointer[i] = username[i] - i * 9 - 9;
}
} else {
for (i = 0; i < 10; i++) {
g_StringPointer[i] = password[i] - i * 4 - 4;
}
}
return g_StringPointer;
}
#endif
struct menuitem g_MpPlayerStatsMenuItems[] = {
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_146, (u32)&mpMenuTextKills, NULL }, // "Kills:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_147, (u32)&mpMenuTextDeaths, NULL }, // "Deaths:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_148, (u32)&mpMenuTextAccuracy, NULL }, // "Accuracy:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_149, (u32)&mpMenuTextHeadShots, NULL }, // "Head Shots:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_150, (u32)&mpMenuTextAmmoUsed, NULL }, // "Ammo Used:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_151, (u32)&mpMenuTextDamageDealt, NULL }, // "Damage Dealt:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_152, (u32)&mpMenuTextPainReceived, NULL }, // "Pain Received:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_153, (u32)&mpMenuTextGamesPlayed, NULL }, // "Games Played:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_154, (u32)&mpMenuTextGamesWon, NULL }, // "Games Won:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_155, (u32)&mpMenuTextGamesLost, NULL }, // "Games Lost:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_156, (u32)&mpMenuTextTime, NULL }, // "Time:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_157, (u32)&mpMenuTextDistance, NULL }, // "Distance:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000210, L_MPMENU_158, 0x00000000, NULL }, // "Medals Won:"
{ MENUITEMTYPE_LABEL, 2, 0x00200000, L_MPMENU_159, (u32)&mpMenuTextMedalAccuracy, mpMedalMenuHandler }, // "Accuracy:"
{ MENUITEMTYPE_LABEL, 1, 0x00200000, L_MPMENU_160, (u32)&mpMenuTextMedalHeadShot, mpMedalMenuHandler }, // "Head Shot:"
{ MENUITEMTYPE_LABEL, 0, 0x00200000, L_MPMENU_161, (u32)&mpMenuTextMedalKillMaster, mpMedalMenuHandler }, // "KillMaster:"
{ MENUITEMTYPE_LABEL, 3, 0x00200000, L_MPMENU_162, (u32)&mpMenuTextMedalSurvivor, mpMedalMenuHandler }, // "Survivor:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_163, 0x00000000, NULL }, // "Your Title:"
{ MENUITEMTYPE_LABEL, 0, 0x00000020, (u32)&mpMenuTextPlayerTitle, 0x00000000, NULL },
#if VERSION >= VERSION_NTSC_1_0
{ MENUITEMTYPE_LABEL, 0, 0x00000200, L_MPWEAPONS_219, 0x00000000, menuhandlerMpUsernamePassword }, // "USERNAME:"
{ MENUITEMTYPE_LABEL, 0, 0x00000220, (u32)&mpMenuTextUsernamePassword, 0x00000000, menuhandlerMpUsernamePassword },
{ MENUITEMTYPE_LABEL, 0, 0x00000200, L_MPWEAPONS_220, 0x00000000, menuhandlerMpUsernamePassword }, // "PASSWORD:"
{ MENUITEMTYPE_LABEL, 1, 0x00000220, (u32)&mpMenuTextUsernamePassword, 0x00000000, menuhandlerMpUsernamePassword },
#else
{ MENUITEMTYPE_LABEL, 0, 0x00000200, L_MPWEAPONS_219, 0x00000000, menuhandlerMpUsernamePassword }, // "USERNAME:"
{ MENUITEMTYPE_LABEL, 0, 0x00000220, 0x51f0, 0x00000000, menuhandlerMpUsernamePassword },
{ MENUITEMTYPE_LABEL, 0, 0x00000200, L_MPWEAPONS_220, 0x00000000, menuhandlerMpUsernamePassword }, // "PASSWORD:"
{ MENUITEMTYPE_LABEL, 0, 0x00000220, 0x51f1, 0x00000000, menuhandlerMpUsernamePassword },
#endif
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_164, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpPlayerStatsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&mpMenuTitleStatsForPlayerName,
g_MpPlayerStatsMenuItems,
NULL,
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
&g_MpCompletedChallengesMenuDialog,
};
s32 mpCharacterHeadMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data, s32 mpheadnum, bool arg4)
{
f32 diffframe;
s32 headnum;
static struct modelpartvisibility visibility[] = {
{ MODELPART_HEAD_SUNGLASSES, false },
{ MODELPART_HEAD_EYESCLOSED, false },
{ MODELPART_HEAD_HUDPIECE, false },
{ 255, false },
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->carousel.value = mpGetNumHeads2();
break;
case MENUOP_11:
#if VERSION >= VERSION_PAL_BETA
diffframe = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60freal;
#else
diffframe = g_Menus[g_MpPlayerNum].unk840.unk524 + 0.01f * g_Vars.diffframe60f;
#endif
g_Menus[g_MpPlayerNum].unk840.unk54c = diffframe;
g_Menus[g_MpPlayerNum].unk840.unk524 = diffframe;
if (mpheadnum < mpGetNumHeads2()) {
headnum = mpGetHeadId(mpheadnum);
g_Menus[g_MpPlayerNum].unk840.unk00c = g_HeadsAndBodies[headnum].filenum;
g_Menus[g_MpPlayerNum].unk840.unk5b1_01 = false;
} else {
headnum = mpGetBeauHeadId(func0f14a9f8(mpheadnum - mpGetNumHeads2()));
g_Menus[g_MpPlayerNum].unk840.unk00c = g_HeadsAndBodies[headnum].filenum;
g_Menus[g_MpPlayerNum].unk840.unk5b1_01 = true;
g_Menus[g_MpPlayerNum].unk840.unk5b0 = mpheadnum - mpGetNumHeads2();
}
g_Menus[g_MpPlayerNum].unk840.unk574 = 0;
g_Menus[g_MpPlayerNum].unk840.partvisibility = visibility;
g_Menus[g_MpPlayerNum].unk840.unk554 = 30;
break;
case MENUOP_21:
if (!mpIsFeatureUnlocked(mpGetHeadRequiredFeature(data->carousel.value))) {
return 1;
}
break;
case MENUOP_GETOPTIONVALUE:
data->carousel.value = mpheadnum;
break;
case MENUOP_SET:
case MENUOP_FOCUS:
#if VERSION >= VERSION_NTSC_1_0
g_Menus[g_MpPlayerNum].unk840.unk000 = 3;
#endif
mpGetNumHeads2();
func0f0f372c(&g_Menus[g_MpPlayerNum].unk840, 0, 0, 0, 0, 0, 0, 1, 1);
g_Menus[g_MpPlayerNum].unk840.unk510 = 0;
g_Menus[g_MpPlayerNum].unk840.unk514 = 0;
g_Menus[g_MpPlayerNum].unk840.unk53c = -3;
g_Menus[g_MpPlayerNum].unk840.unk538 = 0;
g_Menus[g_MpPlayerNum].unk840.unk51c = 0.01f;
g_Menus[g_MpPlayerNum].unk840.unk524 = -0.3f;
g_Menus[g_MpPlayerNum].unk840.unk54c = -0.3f;
g_Menus[g_MpPlayerNum].unk840.unk544 = 1;
g_Menus[g_MpPlayerNum].unk840.unk554 = 30;
break;
}
return 0;
}
s32 menuhandlerMpCharacterHead(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum = data->carousel.value;
}
return mpCharacterHeadMenuHandler(operation, item, data, g_PlayerConfigsArray[g_MpPlayerNum].base.mpheadnum, 1);
}
char *mpMenuTextBodyName(struct menuitem *item)
{
return mpGetBodyName(g_PlayerConfigsArray[g_MpPlayerNum].base.mpbodynum);
}
void func0f17b8f0(void)
{
func0f0f139c(g_MpCharacterMenuItems, -0.4f);
}
s32 mpPlayerNameMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
char *name = data->keyboard.string;
s32 i;
switch (operation) {
case MENUOP_GETTEXT:
i = 0;
while (g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] != '\n'
&& g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] != '\0'
&& i < 11) {
name[i] = g_PlayerConfigsArray[g_MpPlayerNum].base.name[i];
i++;
}
while (i < 11) {
name[i] = '\0';
i++;
}
break;
case MENUOP_SETTEXT:
i = 0;
while (i < 11 && name[i] != '\0') {
g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] = name[i];
i++;
}
g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] = '\n';
i++;
while (i < 11) {
g_PlayerConfigsArray[g_MpPlayerNum].base.name[i] = '\0';
i++;
}
break;
}
return 0;
}
s32 mpLoadSettingsMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = mpGetNumUnlockedPresets();
if (g_FileLists[1] != NULL) {
data->list.value += g_FileLists[1]->numfiles;
}
break;
case MENUOP_GETOPTIONTEXT:
if (data->list.value < mpGetNumUnlockedPresets()) {
return (s32)mpGetPresetNameBySlot(data->list.value);
}
if (g_FileLists[1] != NULL) {
func0f0d564c(g_FileLists[1]->files[data->list.value - mpGetNumUnlockedPresets()].name, g_StringPointer, false);
return (s32)g_StringPointer;
}
break;
case MENUOP_SET:
mpCloseDialogsForNewSetup();
if (data->list.value < mpGetNumUnlockedPresets()) {
func0f18dec4(data->list.value);
} else if (g_FileLists[1] != NULL) {
struct filelistfile *file = &g_FileLists[1]->files[data->list.value - mpGetNumUnlockedPresets()];
struct fileguid guid;
guid.fileid = file->fileid;
guid.deviceserial = file->deviceserial;
filemgrSaveOrLoad(&guid, FILEOP_LOAD_MPSETUP, 0);
}
if (item->param == 1) {
if (IS4MB()) {
func0f0f820c(&g_MpQuickGo4MbMenuDialog, MENUROOT_4MBMAINMENU);
} else {
func0f0f820c(&g_MpQuickGoMenuDialog, MENUROOT_MPSETUP);
}
}
break;
case MENUOP_GETOPTIONVALUE:
data->list.value = 0xfffff;
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = 1;
if (g_FileLists[1] != NULL) {
data->list.value += g_FileLists[1]->numdevices;
}
break;
case MENUOP_GETOPTGROUPTEXT:
if (data->list.value == 0) {
return (s32)langGet(L_MPMENU_141); // "Presets"
}
if (g_FileLists[1] != NULL) {
return (s32)filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1);
}
break;
case MENUOP_GETGROUPSTARTINDEX:
if (data->list.value == 0) {
data->list.groupstartindex = 0;
} else {
data->list.groupstartindex = mpGetNumUnlockedPresets();
if (g_FileLists[1] != NULL) {
data->list.groupstartindex += filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1);
}
}
break;
case MENUOP_LISTITEMFOCUS:
if (data->list.value < mpGetNumUnlockedPresets()) {
g_Menus[g_MpPlayerNum].mpsetup.slotindex = 0xffff;
} else {
g_Menus[g_MpPlayerNum].mpsetup.slotindex = data->list.value - mpGetNumUnlockedPresets();
}
break;
}
return 0;
}
char *mpMenuTextMpconfigMarquee(struct menuitem *item)
{
char filename[20];
u16 numsims;
u16 stagenum;
u16 scenarionum;
s32 arenanum;
s32 i;
if (g_Menus[g_MpPlayerNum].mpsetup.slotindex < 0xffff && g_FileLists[1]) {
#if VERSION >= VERSION_NTSC_1_0
arenanum = -1;
#else
arenanum = 0;
#endif
mpsetupfileGetOverview(g_FileLists[1]->files[g_Menus[g_MpPlayerNum].mpsetup.slotindex].name,
filename, &numsims, &stagenum, &scenarionum);
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
if (g_MpArenas[i].stagenum == stagenum) {
arenanum = i;
}
}
#if VERSION >= VERSION_NTSC_1_0
if (scenarionum <= 5 && arenanum != -1 && numsims >= 0 && filename[0] != '\0' && numsims <= MAX_BOTS) {
// "%s: Scenario: %s Arena: %s Simulants: %d"
sprintf(g_StringPointer, langGet(L_MPMENU_140),
filename,
langGet(g_MpScenarioOverviews[scenarionum].name),
langGet(g_MpArenas[arenanum].name),
numsims);
} else {
return "";
}
#else
// "%s: Scenario: %s Arena: %s Simulants: %d"
sprintf(g_StringPointer, langGet(L_MPMENU_140),
filename,
langGet(g_MpScenarioOverviews[scenarionum].name),
langGet(g_MpArenas[arenanum].name),
numsims);
#endif
return g_StringPointer;
}
return "";
}
s32 mpLoadPlayerMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
s32 i;
struct fileguid guid;
struct filelistfile *file;
bool available;
if (g_FileLists[0] == NULL) {
return 0;
}
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = g_FileLists[0]->numfiles;
break;
case MENUOP_GETOPTIONTEXT:
filemgrGetSelectName(g_StringPointer, &g_FileLists[0]->files[data->list.value], FILETYPE_MPPLAYER);
return (s32)g_StringPointer;
case MENUOP_SET:
file = &g_FileLists[0]->files[data->list.value];
available = true;
for (i = 0; i < 4; i++) {
if (file->fileid == g_PlayerConfigsArray[i].fileguid.fileid
&& file->deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) {
if ((g_MpSetup.chrslots & (1 << i)) == 0) {
mpPlayerSetDefaults(i, true);
} else {
available = false;
}
}
}
if (available) {
guid.fileid = file->fileid;
guid.deviceserial = file->deviceserial;
menuPopDialog();
filemgrSaveOrLoad(&guid, FILEOP_LOAD_MPPLAYER, g_MpPlayerNum);
} else {
filemgrPushErrorDialog(FILEERROR_ALREADYLOADED);
}
break;
case MENUOP_GETOPTIONVALUE:
data->list.value = 0xfffff;
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = g_FileLists[0]->numdevices;
break;
case MENUOP_GETOPTGROUPTEXT:
return filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value);
case MENUOP_GETGROUPSTARTINDEX:
data->list.groupstartindex = filemgrGetDeviceNameOrStartIndex(0, operation, data->list.value);
return 0;
}
return 0;
}
s32 menuhandlerMpTimeLimitSlider(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = g_MpSetup.timelimit;
break;
case MENUOP_SET:
g_MpSetup.timelimit = data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
if (data->slider.value == 60) {
sprintf(data->slider.label, langGet(L_MPMENU_112)); // "No Limit"
} else {
sprintf(data->slider.label, langGet(L_MPMENU_114), data->slider.value + 1); // "%d Min"
}
}
return 0;
}
s32 menuhandlerMpScoreLimitSlider(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = g_MpSetup.scorelimit;
break;
case MENUOP_SET:
g_MpSetup.scorelimit = data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
if (data->slider.value == 100) {
sprintf(data->slider.label, langGet(L_MPMENU_112)); // "No Limit"
} else {
sprintf(data->slider.label, langGet(L_MPMENU_113), data->slider.value + 1); // "%d"
}
}
return 0;
}
s32 menuhandlerMpTeamScoreLimitSlider(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = mpCalculateTeamScoreLimit();
break;
case MENUOP_SET:
g_MpSetup.teamscorelimit = data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
if (data->slider.value == 400) {
sprintf(data->slider.label, langGet(L_MPMENU_112)); // "No Limit"
} else {
sprintf(data->slider.label, langGet(L_MPMENU_113), data->slider.value + 1); // "%d"
}
}
return 0;
}
s32 menuhandlerMpRestoreScoreDefaults(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
func0f187fec();
}
return 0;
}
s32 menuhandlerMpHandicapPlayer(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_CHECKHIDDEN:
if ((g_MpSetup.chrslots & (1 << item->param)) == 0) {
return 1;
}
break;
case MENUOP_GETSLIDER:
data->slider.value = g_PlayerConfigsArray[item->param].handicap;
break;
case MENUOP_SET:
g_PlayerConfigsArray[item->param].handicap = (u16)data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
sprintf(data->slider.label, "%s%s%.00f%%\n", "", "", mpHandicapToDamageScale(g_PlayerConfigsArray[item->param].handicap) * 100);
break;
}
return 0;
}
char *mpMenuTextHandicapPlayerName(struct menuitem *item)
{
if (g_MpSetup.chrslots & (1 << item->param)) {
return g_PlayerConfigsArray[item->param].base.name;
}
return "";
}
s32 menuhandlerMpRestoreHandicapDefaults(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
s32 i;
for (i = 0; i < 4; i++) {
g_PlayerConfigsArray[i].handicap = 0x80;
}
}
return 0;
}
s32 menudialogMpReady(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_OPEN) {
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid && g_PlayerConfigsArray[g_MpPlayerNum].fileguid.deviceserial) {
filemgrSaveOrLoad(&g_PlayerConfigsArray[g_MpPlayerNum].fileguid, FILEOP_SAVE_MPPLAYER, g_MpPlayerNum);
}
}
return false;
}
s32 menudialogMpSimulant(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_TICK) {
if ((u8)g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.name[0] == '\0') {
menuPopDialog();
}
}
return false;
}
struct menuitem g_MpCharacterMenuItems[] = {
{ MENUITEMTYPE_LABEL, 0, 0x00004230, (u32)&mpMenuTextBodyName, 0x00000000, NULL },
{ MENUITEMTYPE_CAROUSEL, 0, 0x00000000, 0x00000000, 0x00000022, menuhandlerMpCharacterHead },
{ MENUITEMTYPE_CAROUSEL, 0, 0x00000000, 0x00000000, 0x0000001b, menuhandlerMpCharacterBody },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpCharacterMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_143, // "Character"
g_MpCharacterMenuItems,
menudialog0017a174,
MENUDIALOGFLAG_0002,
NULL,
};
struct menuitem g_MpPlayerNameMenuItems[] = {
{ MENUITEMTYPE_KEYBOARD, 0, 0x00000000, 0x00000000, 0x00000000, mpPlayerNameMenuHandler },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpPlayerNameMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_142, // "Player Name"
g_MpPlayerNameMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpLoadSettingsMenuItems[] = {
{ MENUITEMTYPE_LIST, 0, 0x00000000, 0x00000078, 0x00000042, mpLoadSettingsMenuHandler },
{ MENUITEMTYPE_MARQUEE, 0, 0x00000a00, (u32)&mpMenuTextMpconfigMarquee, 0x00000000, NULL },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpLoadSettingsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_139, // "Load Game Settings"
g_MpLoadSettingsMenuItems,
NULL,
MENUDIALOGFLAG_CLOSEONSELECT,
NULL,
};
struct menuitem g_MpLoadPresetMenuItems[] = {
{ MENUITEMTYPE_LIST, 1, 0x00000000, 0x00000078, 0x00000042, mpLoadSettingsMenuHandler },
{ MENUITEMTYPE_MARQUEE, 0, 0x00000a00, (u32)&mpMenuTextMpconfigMarquee, 0x00000000, NULL },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpLoadPresetMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_139, // "Load Game Settings"
g_MpLoadPresetMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpLoadPlayerMenuItems[] = {
{ MENUITEMTYPE_LIST, 0, 0x00000000, 0x0000007e, 0x00000042, mpLoadPlayerMenuHandler },
{ MENUITEMTYPE_LABEL, 0, 0x00000200, L_MPMENU_138, 0x00000000, NULL }, // "B Button to cancel"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpLoadPlayerMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_137, // "Load Player"
g_MpLoadPlayerMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpArenaMenuItems[] = {
{ MENUITEMTYPE_LIST, 0, 0x00020000, 0x00000078, 0x0000004d, mpArenaMenuHandler },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpArenaMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_115, // "Arena"
g_MpArenaMenuItems,
NULL,
MENUDIALOGFLAG_CLOSEONSELECT | MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpLimitsMenuItems[] = {
{ MENUITEMTYPE_SLIDER, 0, 0x00020010, L_MPMENU_108, 0x0000003c, menuhandlerMpTimeLimitSlider }, // "Time"
{ MENUITEMTYPE_SLIDER, 0, 0x00020010, L_MPMENU_109, 0x00000064, menuhandlerMpScoreLimitSlider }, // "Score"
{ MENUITEMTYPE_SLIDER, 0, 0x00020010, L_MISC_447, 0x00000190, menuhandlerMpTeamScoreLimitSlider }, // "Team Score"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00060000, L_MPMENU_110, 0x00000000, menuhandlerMpRestoreScoreDefaults }, // "Restore Defaults"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_111, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpLimitsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_107, // "Limits"
g_MpLimitsMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpHandicapsMenuItems[] = {
{ MENUITEMTYPE_SLIDER, 0, 0x00020010, (u32)&mpMenuTextHandicapPlayerName, 0x000000ff, menuhandlerMpHandicapPlayer },
{ MENUITEMTYPE_SLIDER, 1, 0x00020010, (u32)&mpMenuTextHandicapPlayerName, 0x000000ff, menuhandlerMpHandicapPlayer },
{ MENUITEMTYPE_SLIDER, 2, 0x00020010, (u32)&mpMenuTextHandicapPlayerName, 0x000000ff, menuhandlerMpHandicapPlayer },
{ MENUITEMTYPE_SLIDER, 3, 0x00020010, (u32)&mpMenuTextHandicapPlayerName, 0x000000ff, menuhandlerMpHandicapPlayer },
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00060000, L_MPMENU_110, 0x00000000, menuhandlerMpRestoreHandicapDefaults }, // "Restore Defaults"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_111, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpHandicapsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPWEAPONS_184, // "Player Handicaps"
g_MpHandicapsMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpReadyMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_106, 0x00000000, NULL }, // "...and waiting"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpReadyMenuDialog = {
MENUDIALOGTYPE_SUCCESS,
L_MPMENU_105, // "Ready!"
g_MpReadyMenuItems,
menudialogMpReady,
MENUDIALOGFLAG_CLOSEONSELECT,
NULL,
};
s32 mpAddChangeSimulantMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
s32 i;
s32 count = 0;
struct optiongroup groups[] = {
{ 0, L_MPMENU_103 }, // "Normal Simulants"
{ 6, L_MPMENU_104 }, // "Special Simulants"
};
s32 botnum;
bool creating;
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
count++;
}
}
data->list.value = count;
break;
case MENUOP_GETOPTIONTEXT:
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
if (count == data->list.value) {
return (s32)langGet(g_BotProfiles[i].name);
}
count++;
}
}
break;
case MENUOP_SET:
botnum = g_Menus[g_MpPlayerNum].mpsetup.slotindex;
creating = false;
if (botnum < 0) {
botnum = mpGetSlotForNewBot();
creating = 1;
} else if ((g_MpSetup.chrslots & (1 << (botnum + 4))) == 0) {
creating = 1;
}
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
if (count == data->list.value) {
break;
}
count++;
}
}
if (creating) {
mpCreateBotFromProfile(botnum, i);
} else {
g_BotConfigsArray[botnum].type = g_BotProfiles[i].type;
if (g_BotConfigsArray[botnum].type == BOTTYPE_GENERAL) {
mpSetBotDifficulty(botnum, g_BotProfiles[i].difficulty);
}
}
mpGenerateBotNames();
g_Menus[g_MpPlayerNum].mpsetup.slotcount = data->list.value;
break;
case MENUOP_LISTITEMFOCUS:
for (i = 0; i < ARRAYCOUNT(g_BotProfiles); i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
if (count == data->list.value) {
break;
}
count++;
}
}
g_Menus[g_MpPlayerNum].mpsetup.unke24 = i;
// fall-through
case MENUOP_GETOPTIONVALUE:
data->list.value = g_Menus[g_MpPlayerNum].mpsetup.slotcount;
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = 2;
break;
case MENUOP_GETOPTGROUPTEXT:
return (s32)langGet(groups[data->list.value].name);
case MENUOP_GETGROUPSTARTINDEX:
for (i = 0; i < groups[data->list.value].offset; i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
count++;
}
}
data->list.groupstartindex = count;
break;
}
return 0;
}
char *mpMenuTextSimulantDescription(struct menuitem *item)
{
return langGet(L_MISC_106 + g_Menus[g_MpPlayerNum].mpsetup.unke24);
}
s32 menuhandlerMpSimulantHead(s32 operation, struct menuitem *item, union handlerdata *data)
{
s32 start = 0;
if (item->param2 == 1) {
start = mpGetNumHeads();
}
/**
* Rare developers forgot to add a break statement to the first case,
* and when they noticed a problem their fix was to add an additional
* MENUOP_FOCUS check in the next case.
*/
switch (operation) {
case MENUOP_SET:
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum = start + data->carousel.value;
case MENUOP_FOCUS:
if (operation == MENUOP_FOCUS
&& item->param2 == 1
&& g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum < start) {
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum = start;
}
break;
}
return mpCharacterHeadMenuHandler(operation, item, data, g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum, 0);
}
s32 menuhandlerMpSimulantBody(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpbodynum = data->carousel.value;
}
return mpCharacterBodyMenuHandler(operation, item, data,
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpbodynum,
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.mpheadnum,
false);
}
s32 menudialog0017ccfc(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
switch (operation) {
case MENUOP_TICK:
if (g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[0]
&& g_Menus[g_MpPlayerNum].curdialog->focuseditem != &dialogdef->items[1]) {
union handlerdata data;
menuhandlerMpCharacterBody(MENUOP_11, &dialogdef->items[1], &data);
}
}
return menudialogMpSimulant(operation, dialogdef, data);
}
s32 mpBotDifficultyMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
s32 count = 0;
s32 i;
switch (operation) {
case MENUOP_SET:
mpSetBotDifficulty(g_Menus[g_MpPlayerNum].mpsetup.slotindex, data->dropdown.value);
mpGenerateBotNames();
break;
case MENUOP_GETOPTIONVALUE:
if (g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty >= 0
&& g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty < BOTDIFF_DISABLED) {
data->dropdown.value = g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty;
} else {
data->dropdown.value = 0;
}
break;
case MENUOP_GETOPTIONCOUNT:
for (i = 0; i < BOTDIFF_DISABLED; i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
count++;
}
}
data->dropdown.value = count;
break;
case MENUOP_GETOPTIONTEXT:
for (i = 0; i < BOTDIFF_DISABLED; i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
if (count == data->dropdown.value) {
// "Meat", "Easy", "Normal" etc
return (s32) langGet(L_MISC_082 + i);
}
count++;
}
}
return (s32)"\n";
}
return 0;
}
s32 menuhandlerMpDeleteSimulant(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
mpRemoveSimulant(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
menuPopDialog();
}
return 0;
}
char *mpMenuTitleEditSimulant(struct menudialogdef *dialogdef)
{
sprintf(g_StringPointer, "%s", &g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].base.name);
return g_StringPointer;
}
s32 menuhandlerMpChangeSimulantType(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
s32 i;
s32 count = 0;
s32 profilenum = mpFindBotProfile(
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].type,
g_BotConfigsArray[g_Menus[g_MpPlayerNum].mpsetup.slotindex].difficulty);
for (i = 0; i < profilenum; i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
count++;
}
}
g_Menus[g_MpPlayerNum].mpsetup.slotcount = count;
menuPushDialog(&g_MpChangeSimulantMenuDialog);
}
return 0;
}
s32 menuhandlerMpClearAllSimulants(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
s32 i;
for (i = 0; i < MAX_BOTS; i++) {
mpRemoveSimulant(i);
}
}
return 0;
}
s32 menuhandlerMpAddSimulant(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_SET:
g_Menus[g_MpPlayerNum].mpsetup.slotindex = -1;
menuPushDialog(&g_MpAddSimulantMenuDialog);
break;
case MENUOP_CHECKDISABLED:
if (mpHasUnusedBotSlots() == 0) {
return true;
}
}
return 0;
}
s32 menuhandlerMpSimulantSlot(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_SET:
g_Menus[g_MpPlayerNum].mpsetup.slotindex = item->param;
if ((g_MpSetup.chrslots & (1 << (item->param + 4))) == 0) {
menuPushDialog(&g_MpAddSimulantMenuDialog);
} else if (IS4MB()) {
menuPushDialog(&g_MpEditSimulant4MbMenuDialog);
} else {
menuPushDialog(&g_MpEditSimulantMenuDialog);
}
break;
case MENUOP_CHECKHIDDEN:
if (item->param >= 4 && !mpIsFeatureUnlocked(MPFEATURE_8BOTS)) {
return true;
}
break;
case MENUOP_CHECKDISABLED:
if (!mpIsSimSlotEnabled(item->param)) {
return true;
}
}
return 0;
}
char *mpMenuTextSimulantName(struct menuitem *item)
{
s32 index = item->param;
if (g_BotConfigsArray[index].base.name[0] == '\0' || (g_MpSetup.chrslots & 1 << (index + 4)) == 0) {
return "";
}
return g_BotConfigsArray[index].base.name;
}
char *func0f17d3dc(struct menuitem *item)
{
s32 index = item->param;
if (g_BotConfigsArray[index].base.name[0] == '\0'
|| ((g_MpSetup.chrslots & 1 << (index + 4)) == 0)) {
return "";
}
sprintf(g_StringPointer, "%d:\n", index + 1);
return g_StringPointer;
}
s32 menudialogMpSimulants(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_OPEN) {
g_Menus[g_MpPlayerNum].mpsetup.slotcount = 0;
}
return false;
}
struct menuitem g_MpAddChangeSimulantMenuItems[] = {
{ MENUITEMTYPE_LIST, 0, 0x00020000, 0x00000078, 0x00000042, mpAddChangeSimulantMenuHandler },
{ MENUITEMTYPE_MARQUEE, 0, 0x00000a00, (u32)&mpMenuTextSimulantDescription, 0x00000000, NULL },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpAddSimulantMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_101, // "Add Simulant"
g_MpAddChangeSimulantMenuItems,
NULL,
MENUDIALOGFLAG_CLOSEONSELECT | MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menudialogdef g_MpChangeSimulantMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_102, // "Change Simulant"
g_MpAddChangeSimulantMenuItems,
menudialogMpSimulant,
MENUDIALOGFLAG_CLOSEONSELECT | MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpSimulantCharacterMenuItems[] = {
{ MENUITEMTYPE_CAROUSEL, 0, 0x00020000, 0x00000000, 0x00000025, menuhandlerMpSimulantHead },
{ MENUITEMTYPE_CAROUSEL, 0, 0x00020000, 0x00000000, 0x0000001b, menuhandlerMpSimulantBody },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpSimulantCharacterMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_100, // "Simulant Character"
g_MpSimulantCharacterMenuItems,
menudialog0017ccfc,
MENUDIALOGFLAG_0002 | MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpEditSimulantMenuItems[] = {
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_095, 0x00000000, mpBotDifficultyMenuHandler }, // "Difficulty:"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_096, 0x00000000, menuhandlerMpChangeSimulantType }, // "Change Type..."
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_097, 0x00000000, (void *)&g_MpSimulantCharacterMenuDialog }, // "Character..."
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_098, 0x00000000, menuhandlerMpDeleteSimulant }, // "Delete Simulant"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_099, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpEditSimulantMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&mpMenuTitleEditSimulant,
g_MpEditSimulantMenuItems,
menudialogMpSimulant,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpSimulantsMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_084, 0x00000000, menuhandlerMpAddSimulant }, // "Add Simulant..."
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_085, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "1:"
{ MENUITEMTYPE_SELECTABLE, 1, 0x00000000, L_MPMENU_086, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "2:"
{ MENUITEMTYPE_SELECTABLE, 2, 0x00000000, L_MPMENU_087, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "3:"
{ MENUITEMTYPE_SELECTABLE, 3, 0x00000000, L_MPMENU_088, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "4:"
{ MENUITEMTYPE_SELECTABLE, 4, 0x00000000, L_MPMENU_089, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "5:"
{ MENUITEMTYPE_SELECTABLE, 5, 0x00000000, L_MPMENU_090, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "6:"
{ MENUITEMTYPE_SELECTABLE, 6, 0x00000000, L_MPMENU_091, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "7:"
{ MENUITEMTYPE_SELECTABLE, 7, 0x00000000, L_MPMENU_092, (u32)&mpMenuTextSimulantName, menuhandlerMpSimulantSlot }, // "8:"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_093, 0x00000000, menuhandlerMpClearAllSimulants }, // "Clear All"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_094, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpSimulantsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_083, // "Simulants"
g_MpSimulantsMenuItems,
menudialogMpSimulants,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
#if VERSION >= VERSION_NTSC_1_0
s32 menuhandlerMpNTeams(s32 operation, struct menuitem *item, union handlerdata *data, s32 numteams)
{
if (operation == MENUOP_SET) {
s32 numchrs = mpGetNumChrs();
s32 array[] = {0, 0, 0, 0};
s32 somevalue = (numchrs + numteams - 1) / numteams;
s32 teamsremaining = numteams;
s32 chrsremaining = numchrs;
s32 start = random() % numchrs;
s32 i;
s32 teamnum;
if (!numchrs) {
return 0;
}
i = (start + 1) % numchrs;
do {
struct mpchrconfig *mpchr = mpGetChrConfigBySlotNum(i);
if (teamsremaining);
if (teamsremaining >= chrsremaining) {
teamnum = random() % numteams;
while (true) {
if (array[teamnum] == 0) {
mpchr->team = teamnum;
array[teamnum]++;
teamsremaining--;
chrsremaining--;
break;
} else {
teamnum = (teamnum + 1) % numteams;
}
}
} else {
teamnum = random() % numteams;
while (true) {
if (array[teamnum] < somevalue) {
mpchr->team = teamnum;
if (array[teamnum] == 0) {
teamsremaining--;
}
array[teamnum]++;
chrsremaining--;
break;
} else {
teamnum = (teamnum + 1) % numteams;
}
}
}
if (i == start) {
break;
}
i = (i + 1) % numchrs;
} while (true);
menuPopDialog();
}
return 0;
}
#else
u32 var800881f0nb[4] = {0};
GLOBAL_ASM(
glabel menuhandlerMpNTeams
/* f177bd0: 27bdff88 */ addiu $sp,$sp,-120
/* f177bd4: afb00018 */ sw $s0,0x18($sp)
/* f177bd8: 24010006 */ addiu $at,$zero,0x6
/* f177bdc: 00e08025 */ or $s0,$a3,$zero
/* f177be0: afbf003c */ sw $ra,0x3c($sp)
/* f177be4: afbe0038 */ sw $s8,0x38($sp)
/* f177be8: afb70034 */ sw $s7,0x34($sp)
/* f177bec: afb60030 */ sw $s6,0x30($sp)
/* f177bf0: afb5002c */ sw $s5,0x2c($sp)
/* f177bf4: afb40028 */ sw $s4,0x28($sp)
/* f177bf8: afb30024 */ sw $s3,0x24($sp)
/* f177bfc: afb20020 */ sw $s2,0x20($sp)
/* f177c00: afb1001c */ sw $s1,0x1c($sp)
/* f177c04: afa5007c */ sw $a1,0x7c($sp)
/* f177c08: 1481008c */ bne $a0,$at,.NB0f177e3c
/* f177c0c: afa60080 */ sw $a2,0x80($sp)
/* f177c10: 0fc61aa0 */ jal mpGetNumChrs
/* f177c14: 00000000 */ sll $zero,$zero,0x0
/* f177c18: 0050c821 */ addu $t9,$v0,$s0
/* f177c1c: 2728ffff */ addiu $t0,$t9,-1
/* f177c20: 0110001a */ div $zero,$t0,$s0
/* f177c24: 3c0e8009 */ lui $t6,0x8009
/* f177c28: 25ce81f0 */ addiu $t6,$t6,-32272
/* f177c2c: 8dc10000 */ lw $at,0x0($t6)
/* f177c30: 27b10064 */ addiu $s1,$sp,0x64
/* f177c34: 00009012 */ mflo $s2
/* f177c38: ae210000 */ sw $at,0x0($s1)
/* f177c3c: 8dd80004 */ lw $t8,0x4($t6)
/* f177c40: 0040f025 */ or $s8,$v0,$zero
/* f177c44: 02009825 */ or $s3,$s0,$zero
/* f177c48: ae380004 */ sw $t8,0x4($s1)
/* f177c4c: 8dc10008 */ lw $at,0x8($t6)
/* f177c50: 0040a025 */ or $s4,$v0,$zero
/* f177c54: ae210008 */ sw $at,0x8($s1)
/* f177c58: 8dd8000c */ lw $t8,0xc($t6)
/* f177c5c: ae38000c */ sw $t8,0xc($s1)
/* f177c60: 16000002 */ bnez $s0,.NB0f177c6c
/* f177c64: 00000000 */ sll $zero,$zero,0x0
/* f177c68: 0007000d */ break 0x7
.NB0f177c6c:
/* f177c6c: 2401ffff */ addiu $at,$zero,-1
/* f177c70: 16010004 */ bne $s0,$at,.NB0f177c84
/* f177c74: 3c018000 */ lui $at,0x8000
/* f177c78: 15010002 */ bne $t0,$at,.NB0f177c84
/* f177c7c: 00000000 */ sll $zero,$zero,0x0
/* f177c80: 0006000d */ break 0x6
.NB0f177c84:
/* f177c84: 0c004d84 */ jal random
/* f177c88: 00000000 */ sll $zero,$zero,0x0
/* f177c8c: 005e001b */ divu $zero,$v0,$s8
/* f177c90: 00001810 */ mfhi $v1
/* f177c94: 24690001 */ addiu $t1,$v1,0x1
/* f177c98: 0060b825 */ or $s7,$v1,$zero
/* f177c9c: 013e001a */ div $zero,$t1,$s8
/* f177ca0: 0000a810 */ mfhi $s5
/* f177ca4: 17c00002 */ bnez $s8,.NB0f177cb0
/* f177ca8: 00000000 */ sll $zero,$zero,0x0
/* f177cac: 0007000d */ break 0x7
.NB0f177cb0:
/* f177cb0: 17c00002 */ bnez $s8,.NB0f177cbc
/* f177cb4: 00000000 */ sll $zero,$zero,0x0
/* f177cb8: 0007000d */ break 0x7
.NB0f177cbc:
/* f177cbc: 2401ffff */ addiu $at,$zero,-1
/* f177cc0: 17c10004 */ bne $s8,$at,.NB0f177cd4
/* f177cc4: 3c018000 */ lui $at,0x8000
/* f177cc8: 15210002 */ bne $t1,$at,.NB0f177cd4
/* f177ccc: 00000000 */ sll $zero,$zero,0x0
/* f177cd0: 0006000d */ break 0x6
.NB0f177cd4:
/* f177cd4: 0fc61a7b */ jal mpGetChrConfigBySlotNum
/* f177cd8: 02a02025 */ or $a0,$s5,$zero
/* f177cdc: 0274082a */ slt $at,$s3,$s4
/* f177ce0: 14200022 */ bnez $at,.NB0f177d6c
/* f177ce4: 0040b025 */ or $s6,$v0,$zero
/* f177ce8: 0c004d84 */ jal random
/* f177cec: 00000000 */ sll $zero,$zero,0x0
/* f177cf0: 0050001b */ divu $zero,$v0,$s0
/* f177cf4: 00001810 */ mfhi $v1
/* f177cf8: 16000002 */ bnez $s0,.NB0f177d04
/* f177cfc: 00000000 */ sll $zero,$zero,0x0
/* f177d00: 0007000d */ break 0x7
.NB0f177d04:
/* f177d04: 00035080 */ sll $t2,$v1,0x2
.NB0f177d08:
/* f177d08: 022a1021 */ addu $v0,$s1,$t2
/* f177d0c: 8c4b0000 */ lw $t3,0x0($v0)
/* f177d10: 55600009 */ bnezl $t3,.NB0f177d38
/* f177d14: 246f0001 */ addiu $t7,$v1,0x1
/* f177d18: a2c30011 */ sb $v1,0x11($s6)
/* f177d1c: 8c4c0000 */ lw $t4,0x0($v0)
/* f177d20: 2673ffff */ addiu $s3,$s3,-1
/* f177d24: 2694ffff */ addiu $s4,$s4,-1
/* f177d28: 258d0001 */ addiu $t5,$t4,0x1
/* f177d2c: 10000032 */ beqz $zero,.NB0f177df8
/* f177d30: ac4d0000 */ sw $t5,0x0($v0)
/* f177d34: 246f0001 */ addiu $t7,$v1,0x1
.NB0f177d38:
/* f177d38: 01f0001a */ div $zero,$t7,$s0
/* f177d3c: 00001810 */ mfhi $v1
/* f177d40: 16000002 */ bnez $s0,.NB0f177d4c
/* f177d44: 00000000 */ sll $zero,$zero,0x0
/* f177d48: 0007000d */ break 0x7
.NB0f177d4c:
/* f177d4c: 2401ffff */ addiu $at,$zero,-1
/* f177d50: 16010004 */ bne $s0,$at,.NB0f177d64
/* f177d54: 3c018000 */ lui $at,0x8000
/* f177d58: 15e10002 */ bne $t7,$at,.NB0f177d64
/* f177d5c: 00000000 */ sll $zero,$zero,0x0
/* f177d60: 0006000d */ break 0x6
.NB0f177d64:
/* f177d64: 1000ffe8 */ beqz $zero,.NB0f177d08
/* f177d68: 00035080 */ sll $t2,$v1,0x2
.NB0f177d6c:
/* f177d6c: 0c004d84 */ jal random
/* f177d70: 00000000 */ sll $zero,$zero,0x0
/* f177d74: 0050001b */ divu $zero,$v0,$s0
/* f177d78: 00001810 */ mfhi $v1
/* f177d7c: 16000002 */ bnez $s0,.NB0f177d88
/* f177d80: 00000000 */ sll $zero,$zero,0x0
/* f177d84: 0007000d */ break 0x7
.NB0f177d88:
/* f177d88: 00037080 */ sll $t6,$v1,0x2
.NB0f177d8c:
/* f177d8c: 022e1021 */ addu $v0,$s1,$t6
/* f177d90: 8c580000 */ lw $t8,0x0($v0)
/* f177d94: 0312082a */ slt $at,$t8,$s2
/* f177d98: 5020000a */ beqzl $at,.NB0f177dc4
/* f177d9c: 24680001 */ addiu $t0,$v1,0x1
/* f177da0: a2c30011 */ sb $v1,0x11($s6)
/* f177da4: 8c440000 */ lw $a0,0x0($v0)
/* f177da8: 2694ffff */ addiu $s4,$s4,-1
/* f177dac: 14800002 */ bnez $a0,.NB0f177db8
/* f177db0: 24990001 */ addiu $t9,$a0,0x1
/* f177db4: 2673ffff */ addiu $s3,$s3,-1
.NB0f177db8:
/* f177db8: 1000000f */ beqz $zero,.NB0f177df8
/* f177dbc: ac590000 */ sw $t9,0x0($v0)
/* f177dc0: 24680001 */ addiu $t0,$v1,0x1
.NB0f177dc4:
/* f177dc4: 0110001a */ div $zero,$t0,$s0
/* f177dc8: 00001810 */ mfhi $v1
/* f177dcc: 16000002 */ bnez $s0,.NB0f177dd8
/* f177dd0: 00000000 */ sll $zero,$zero,0x0
/* f177dd4: 0007000d */ break 0x7
.NB0f177dd8:
/* f177dd8: 2401ffff */ addiu $at,$zero,-1
/* f177ddc: 16010004 */ bne $s0,$at,.NB0f177df0
/* f177de0: 3c018000 */ lui $at,0x8000
/* f177de4: 15010002 */ bne $t0,$at,.NB0f177df0
/* f177de8: 00000000 */ sll $zero,$zero,0x0
/* f177dec: 0006000d */ break 0x6
.NB0f177df0:
/* f177df0: 1000ffe6 */ beqz $zero,.NB0f177d8c
/* f177df4: 00037080 */ sll $t6,$v1,0x2
.NB0f177df8:
/* f177df8: 12b7000e */ beq $s5,$s7,.NB0f177e34
/* f177dfc: 26a90001 */ addiu $t1,$s5,0x1
/* f177e00: 013e001a */ div $zero,$t1,$s8
/* f177e04: 0000a810 */ mfhi $s5
/* f177e08: 17c00002 */ bnez $s8,.NB0f177e14
/* f177e0c: 00000000 */ sll $zero,$zero,0x0
/* f177e10: 0007000d */ break 0x7
.NB0f177e14:
/* f177e14: 2401ffff */ addiu $at,$zero,-1
/* f177e18: 17c10004 */ bne $s8,$at,.NB0f177e2c
/* f177e1c: 3c018000 */ lui $at,0x8000
/* f177e20: 15210002 */ bne $t1,$at,.NB0f177e2c
/* f177e24: 00000000 */ sll $zero,$zero,0x0
/* f177e28: 0006000d */ break 0x6
.NB0f177e2c:
/* f177e2c: 1000ffa9 */ beqz $zero,.NB0f177cd4
/* f177e30: 00000000 */ sll $zero,$zero,0x0
.NB0f177e34:
/* f177e34: 0fc3c088 */ jal menuPopDialog
/* f177e38: 00000000 */ sll $zero,$zero,0x0
.NB0f177e3c:
/* f177e3c: 8fbf003c */ lw $ra,0x3c($sp)
/* f177e40: 8fb00018 */ lw $s0,0x18($sp)
/* f177e44: 8fb1001c */ lw $s1,0x1c($sp)
/* f177e48: 8fb20020 */ lw $s2,0x20($sp)
/* f177e4c: 8fb30024 */ lw $s3,0x24($sp)
/* f177e50: 8fb40028 */ lw $s4,0x28($sp)
/* f177e54: 8fb5002c */ lw $s5,0x2c($sp)
/* f177e58: 8fb60030 */ lw $s6,0x30($sp)
/* f177e5c: 8fb70034 */ lw $s7,0x34($sp)
/* f177e60: 8fbe0038 */ lw $s8,0x38($sp)
/* f177e64: 27bd0078 */ addiu $sp,$sp,0x78
/* f177e68: 03e00008 */ jr $ra
/* f177e6c: 00001025 */ or $v0,$zero,$zero
);
#endif
s32 menuhandlerMpTwoTeams(s32 operation, struct menuitem *item, union handlerdata *data)
{
return menuhandlerMpNTeams(operation, item, data, 2);
}
s32 menuhandlerMpThreeTeams(s32 operation, struct menuitem *item, union handlerdata *data)
{
return menuhandlerMpNTeams(operation, item, data, 3);
}
s32 menuhandlerMpFourTeams(s32 operation, struct menuitem *item, union handlerdata *data)
{
return menuhandlerMpNTeams(operation, item, data, 4);
}
s32 menuhandlerMpMaximumTeams(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
s32 i;
u8 team = 0;
for (i = 0; i != MAX_MPCHRS; i++) {
if (g_MpSetup.chrslots & (1 << i)) {
struct mpchrconfig *mpchr = MPCHR(i);
mpchr->team = team++;
if (team >= scenarioGetMaxTeams()) {
team = 0;
}
}
}
menuPopDialog();
}
return 0;
}
s32 menuhandlerMpHumansVsSimulants(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
s32 i;
for (i = 0; i != MAX_MPCHRS; i++) {
if (g_MpSetup.chrslots & (1 << i)) {
struct mpchrconfig *mpchr = MPCHR(i);
mpchr->team = i < 4 ? 0 : 1;
}
}
menuPopDialog();
}
return 0;
}
s32 menuhandlerMpHumanSimulantPairs(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
u8 team_ids[4] = {0, 1, 2, 3};
s32 i;
s32 playerindex = 0;
s32 simindex = 0;
for (i = 0; i != MAX_MPCHRS; i++) {
if (g_MpSetup.chrslots & (1 << i)) {
struct mpchrconfig *mpchr = MPCHR(i);
if (i < 4) {
mpchr->team = team_ids[playerindex++];
} else {
mpchr->team = team_ids[simindex++];
if (simindex >= playerindex) {
simindex = 0;
}
}
}
}
menuPopDialog();
}
return 0;
}
char *mpMenuTextChrNameForTeamSetup(struct menuitem *item)
{
struct mpchrconfig *mpchr = mpGetChrConfigBySlotNum(item->param);
if (mpchr) {
return mpchr->name;
}
return "";
}
s32 func0f17dac4(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = scenarioGetMaxTeams();
break;
case MENUOP_GETOPTIONTEXT:
if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) == 0) {
return (s32) "\n";
}
return (s32) g_BossFile.teamnames[data->list.value];
}
return menuhandlerMpTeamsLabel(operation, item, data);
}
s32 menuhandlerMpTeamSlot(s32 operation, struct menuitem *item, union handlerdata *data)
{
struct mpchrconfig *mpchr;
switch (operation) {
case MENUOP_SET:
mpchr = mpGetChrConfigBySlotNum(item->param);
mpchr->team = data->dropdown.value;
break;
case MENUOP_GETOPTIONVALUE:
mpchr = mpGetChrConfigBySlotNum(item->param);
if (!mpchr) {
data->dropdown.value = 0xff;
} else {
data->dropdown.value = mpchr->team;
}
break;
case MENUOP_CHECKDISABLED:
mpchr = mpGetChrConfigBySlotNum(item->param);
if (!mpchr) {
return 1;
}
return menuhandlerMpTeamsLabel(operation, item, data);
}
return func0f17dac4(operation, item, data);
}
char *mpMenuTextSelectTuneOrTunes(struct menuitem *item)
{
if (mpGetUsingMultipleTunes()) {
return langGet(L_MPMENU_069); // "Select Tune"
}
return langGet(L_MPMENU_068); // "Select Tunes"
}
struct menuitem g_MpAutoTeamMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_076, 0x00000000, menuhandlerMpTwoTeams }, // "Two Teams"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_077, 0x00000000, menuhandlerMpThreeTeams }, // "Three Teams"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_078, 0x00000000, menuhandlerMpFourTeams }, // "Four Teams"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_079, 0x00000000, menuhandlerMpMaximumTeams }, // "Maximum Teams"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_080, 0x00000000, menuhandlerMpHumansVsSimulants }, // "Humans vs. Simulants"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_MPMENU_081, 0x00000000, menuhandlerMpHumanSimulantPairs }, // "Human-Simulant Pairs"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_082, 0x00000000, NULL }, // "Cancel"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpAutoTeamMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_075, // "Auto Team"
g_MpAutoTeamMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpTeamsMenuItems[] = {
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_071, 0x00000002, menuhandlerMpTeamsEnabled }, // "Teams Enabled"
#if VERSION >= VERSION_PAL_FINAL
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x85, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_072, 0x00000000, menuhandlerMpTeamsLabel }, // "Teams:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 1, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 2, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 3, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 4, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 5, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 6, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 7, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 8, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 9, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 10, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 11, 0x00021000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
#else
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0, 0x00000000, NULL },
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_072, 0x00000000, menuhandlerMpTeamsLabel }, // "Teams:"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 1, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 2, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 3, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 4, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 5, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 6, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 7, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 8, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 9, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 10, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
{ MENUITEMTYPE_DROPDOWN, 11, 0x00020000, (u32)&mpMenuTextChrNameForTeamSetup, 0x00000000, menuhandlerMpTeamSlot },
#endif
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_073, 0x00000000, (void *)&g_MpAutoTeamMenuDialog }, // "Auto Team..."
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_074, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpTeamsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_070, // "Team Control"
g_MpTeamsMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
u32 var80085ce8[] = {
L_MISC_166, // "Random"
L_MISC_167, // "Select All"
L_MISC_168, // "Select None"
L_MISC_169, // "Randomize"
};
/**
* List handler for the select tune dialog.
*
* If multiple tracks are disabled, the listing contains the track listing plus
* one item for Randomize.
*
* If multiple tracks are disabled, the listing contains the track listing plus
* 3 items for Select All, Select None and Randomize.
*/
s32 mpSelectTuneListHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = mpGetNumUnlockedTracks();
if (mpGetUsingMultipleTunes()) {
data->list.value += 3;
} else {
data->list.value++;
}
break;
case MENUOP_GETOPTIONTEXT:
{
s32 numtracks = mpGetNumUnlockedTracks();
if (data->list.value < numtracks) {
return (s32) mpGetTrackName(data->list.value);
}
if (mpGetUsingMultipleTunes()) {
return (s32) langGet(var80085ce8[1 + data->list.value - numtracks]);
}
return (s32) langGet(var80085ce8[data->list.value - numtracks]);
}
case MENUOP_SET:
{
s32 numtracks = mpGetNumUnlockedTracks();
if (data->list.value < numtracks) {
if (data->list.unk04 == 0) {
mpSetTrackSlotEnabled(data->list.value);
}
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
} else if (mpGetUsingMultipleTunes()) {
s32 index = data->list.value - numtracks;
switch (index) {
case 0:
mpEnableAllMultiTracks();
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
break;
case 1:
mpDisableAllMultiTracks();
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
break;
case 2:
mpRandomiseMultiTracks();
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
break;
}
} else {
mpSetTrackToRandom();
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
}
}
break;
case MENUOP_GETOPTIONVALUE:
if (mpGetUsingMultipleTunes()) {
data->list.value = 0x000fffff;
} else {
s32 slotnum = mpGetCurrentTrackSlotNum();
if (slotnum < 0) {
data->list.value = mpGetNumUnlockedTracks();
} else {
data->list.value = slotnum;
}
}
break;
case MENUOP_LISTITEMFOCUS:
if (data->list.value < mpGetNumUnlockedTracks()) {
musicStartTrackAsMenu(mpGetTrackMusicNum(data->list.value));
}
break;
case MENUOP_GETLISTITEMCHECKBOX:
{
s32 numtracks = mpGetNumUnlockedTracks();
if (mpGetUsingMultipleTunes() && data->list.value < numtracks) {
data->list.unk04 = mpIsMultiTrackSlotEnabled(data->list.value);
}
}
break;
}
return 0;
}
s32 menudialogMpSelectTune(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_OPEN) {
var800840e0 = 80;
}
if (operation == MENUOP_CLOSE) {
var800840e0 = 15;
}
return false;
}
char *mpMenuTextCurrentTrack(struct menuitem *item)
{
s32 slotnum;
if (mpGetUsingMultipleTunes()) {
return langGet(L_MPMENU_066); // "Multiple Tunes"
}
slotnum = mpGetCurrentTrackSlotNum();
if (slotnum >= 0) {
return mpGetTrackName(slotnum);
}
return langGet(L_MPMENU_067); // "Random"
}
s32 menuhandlerMpMultipleTunes(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return mpGetUsingMultipleTunes();
case MENUOP_SET:
mpSetUsingMultipleTunes(data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
}
return 0;
}
s32 mpTeamNameMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
char *name = data->keyboard.string;
s32 i;
switch (operation) {
case MENUOP_GETTEXT:
i = 0;
while (g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] != '\n'
&& g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] != '\0'
&& i < 11) {
name[i] = g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i];
i++;
}
while (i < 11) {
name[i] = '\0';
i++;
}
break;
case MENUOP_SETTEXT:
i = 0;
while (i < 11 && name[i] != '\0') {
g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] = name[i];
i++;
}
g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] = '\n';
i++;
while (i < 11) {
g_BossFile.teamnames[g_Menus[g_MpPlayerNum].mpsetup.slotindex][i] = '\0';
i++;
}
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
break;
}
return 0;
}
/**
* item->param2 is a text ID for that team's colour. The text IDs for team
* colours are consecutive, so the index of the team is determined by
* subtracting the first team's colour text ID.
*/
char *mpMenuTextTeamName(struct menuitem *item)
{
s32 index = item->param2;
index -= L_OPTIONS_008;
return g_BossFile.teamnames[index];
}
s32 menuhandlerMpTeamNameSlot(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_Menus[g_MpPlayerNum].mpsetup.slotindex = item->param2 - 0x5608;
menuPushDialog(&g_MpChangeTeamNameMenuDialog);
}
return 0;
}
char *func0f17e318(struct menudialogdef *dialogdef)
{
sprintf(g_StringPointer, langGet(L_MPMENU_056), mpGetChallengeNameBySlot(g_Menus[g_MpPlayerNum].mpsetup.slotindex));
return g_StringPointer;
}
/**
* An "Accept" item somewhere. Probably accepting a challenge.
*/
s32 menuhandler0017e38c(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
#if VERSION >= VERSION_NTSC_1_0
mpClearCurrentChallenge();
#endif
menuPopDialog();
mpSetCurrentChallenge(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
}
return 0;
}
s32 menudialog0017e3fc(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
switch (operation) {
case MENUOP_OPEN:
g_Menus[g_MpPlayerNum].unk840.unk010 = 0;
g_Menus[g_MpPlayerNum].training.mpconfig = mpGetNthAvailableChallengeSomething(
g_Menus[g_MpPlayerNum].training.unke1c,
g_Menus[g_MpPlayerNum].unk840.unk004,
g_Menus[g_MpPlayerNum].unk840.unk008);
break;
case MENUOP_CLOSE:
break;
case MENUOP_TICK:
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
menuPopDialog();
}
break;
}
return 0;
}
struct menuitem g_MpSelectTunesMenuItems[] = {
{ MENUITEMTYPE_LIST, 0, 0x00020000, 0x00000078, 0x0000004d, mpSelectTuneListHandler },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpSelectTunesMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&mpMenuTextSelectTuneOrTunes,
g_MpSelectTunesMenuItems,
menudialogMpSelectTune,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpSoundtrackMenuItems[] = {
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_MPMENU_063, 0x00000000, NULL }, // "Current:"
{ MENUITEMTYPE_LABEL, 0, 0x00000000, L_OPTIONS_003, (u32)&mpMenuTextCurrentTrack, NULL }, // ""
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, (u32)&mpMenuTextSelectTuneOrTunes, 0x00000000, (void *)&g_MpSelectTunesMenuDialog },
{ MENUITEMTYPE_CHECKBOX, 0, 0x00020000, L_MPMENU_064, 0x00000000, menuhandlerMpMultipleTunes }, // "Multiple Tunes"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_065, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpSoundtrackMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_062, // "Soundtrack"
g_MpSoundtrackMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpChangeTeamNameMenuItems[] = {
{ MENUITEMTYPE_KEYBOARD, 0, 0x00000000, 0x00000000, 0x00000000, mpTeamNameMenuHandler },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpChangeTeamNameMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_061, // "Change Team Name"
g_MpChangeTeamNameMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpTeamNamesMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_008, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Red"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_009, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Yellow"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_010, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Blue"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_011, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Magenta"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_012, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Cyan"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_013, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Orange"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_014, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Pink"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020000, L_OPTIONS_015, (u32)&mpMenuTextTeamName, menuhandlerMpTeamNameSlot }, // "Brown"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_060, 0x00000000, NULL }, // "Back"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpTeamNamesMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_059, // "Team Names"
g_MpTeamNamesMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpConfirmChallengeViaListOrDetailsMenuItems[] = {
{ MENUITEMTYPE_SCROLLABLE, DESCRIPTION_MPCONFIG, 0x00000000, 0x0000007c, PAL ? 0x41 : 0x37, NULL },
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00060000, L_MPMENU_057, 0x00000000, menuhandler0017e38c }, // "Accept"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_058, 0x00000000, NULL }, // "Cancel"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpConfirmChallengeViaListOrDetailsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&func0f17e318,
g_MpConfirmChallengeViaListOrDetailsMenuItems,
menudialog0017e3fc,
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_MPLOCKABLE,
NULL,
};
struct menuitem g_MpChallengesListOrDetailsMenuItems[] = {
{ MENUITEMTYPE_LIST, 0, 0x00200000, 0x00000078, 0x0000004d, mpChallengesListMenuHandler },
#if VERSION < VERSION_NTSC_1_0
{ MENUITEMTYPE_LABEL, 2, 0x110, 0x7f179198, 0, (void *)0x7f1790a8 },
#endif
{ MENUITEMTYPE_SCROLLABLE, DESCRIPTION_MPCHALLENGE, 0x00000000, 0x0000007c, PAL ? 0x41 : 0x37, menuhandler0017e9d8 },
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, menuhandler0017e9d8 },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPWEAPONS_171, 0x00000000, menuhandlerMpStartChallenge }, // "Start Challenge"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_051, 0x00000000, menuhandlerMpAbortChallenge }, // "Abort Challenge"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpChallengeListOrDetailsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
#if VERSION >= VERSION_NTSC_1_0
(u32)&mpMenuTextChallengeName,
#else
0x5032,
#endif
g_MpChallengesListOrDetailsMenuItems,
mpCombatChallengesMenuDialog,
#if VERSION >= VERSION_NTSC_1_0
0x00000808,
#else
MENUDIALOGFLAG_DROPOUTONCLOSE,
#endif
NULL,
};
struct menudialogdef g_MpAdvancedSetupViaAdvChallengeMenuDialog;
struct menudialogdef g_MpChallengeListOrDetailsViaAdvChallengeMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
#if VERSION >= VERSION_NTSC_1_0
(u32)&mpMenuTextChallengeName,
#else
0x5032,
#endif
g_MpChallengesListOrDetailsMenuItems,
mpCombatChallengesMenuDialog,
#if VERSION >= VERSION_NTSC_1_0
0x00000808,
&g_MpAdvancedSetupViaAdvChallengeMenuDialog,
#else
MENUDIALOGFLAG_DROPOUTONCLOSE,
&g_MpAdvancedSetupMenuDialog,
#endif
};
struct menuitem g_MpConfirmChallengeMenuItems[] = {
{ MENUITEMTYPE_SCROLLABLE, DESCRIPTION_MPCONFIG, 0x00000000, 0x0000007c, PAL ? 0x41 : 0x37, NULL },
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_057, 0x00000000, menuhandler0017ec64 }, // "Accept"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_058, 0x00000000, NULL }, // "Cancel"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpConfirmChallengeMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&func0f17e318,
g_MpConfirmChallengeMenuItems,
menudialog0017e3fc,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
s32 mpChallengesListMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
Gfx *gdl;
struct menuitemrenderdata *renderdata;
s32 x;
s32 y;
s32 maxchrs;
s32 marginleft;
s32 i;
switch (operation) {
case MENUOP_CHECKHIDDEN:
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
return 1;
}
break;
case MENUOP_GETOPTIONCOUNT:
data->list.value = mpGetNumAvailableChallenges();
break;
case MENUOP_SET:
if (data->list.unk04 != 0) {
data->list.unk04 = 2;
}
g_Menus[g_MpPlayerNum].mpsetup.slotindex = data->list.value;
if (item->param == 0) {
menuPushDialog(&g_MpConfirmChallengeViaListOrDetailsMenuDialog);
} else if (IS4MB()) {
menuPushDialog(&g_MpConfirmChallenge4MbMenuDialog);
} else {
menuPushDialog(&g_MpConfirmChallengeMenuDialog);
}
break;
case MENUOP_GETOPTIONVALUE:
data->list.value = 0xfffff;
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = 0;
break;
case MENUOP_GETOPTGROUPTEXT:
return 0;
case MENUOP_GETGROUPSTARTINDEX:
data->list.groupstartindex = 0;
break;
case MENUOP_RENDER:
gdl = data->type19.gdl;
renderdata = data->type19.renderdata2;
marginleft = 10;
maxchrs = 4;
if (IS4MB()) {
maxchrs = 2;
}
x = renderdata->x + 10;
y = renderdata->y + 1;
gdl = func0f153628(gdl);
gdl = textRenderProjected(gdl, &x, &y, mpGetChallengeNameBySlot(data->type19.unk04), g_CharsHandelGothicSm, g_FontHandelGothicSm, renderdata->colour, viGetWidth(), viGetHeight(), 0, 0);
gdl = func0f153780(gdl);
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[35], 2, 0, 2, 1, NULL);
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
gDPSetTextureFilter(gdl++, G_TF_POINT);
for (i = 0; i < maxchrs; i++) {
#if VERSION >= VERSION_NTSC_1_0
if (mpIsChallengeCompletedByAnyChrWithNumPlayersBySlot(data->type19.unk04, i + 1)) {
gDPSetEnvColorViaWord(gdl++, (renderdata->colour & 0xff) * 0xff >> 8 | 0xffe56500);
} else {
gDPSetEnvColorViaWord(gdl++, (renderdata->colour & 0xff) * 0xff >> 8 | 0x43430000);
}
#else
if (mpIsChallengeCompletedByAnyChrWithNumPlayersBySlot(data->type19.unk04, i + 1)) {
gDPSetEnvColorViaWord(gdl++, 0xffe565ff);
} else {
gDPSetEnvColorViaWord(gdl++, 0x434300ff);
}
#endif
gDPSetCombineLERP(gdl++,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0);
gSPTextureRectangle(gdl++,
((renderdata->x + marginleft) << 2) * g_ScaleX, (renderdata->y + 11) << 2,
((renderdata->x + marginleft + 11) << 2) * g_ScaleX, (renderdata->y + 22) << 2,
G_TX_RENDERTILE, 0, 0x0160, 1024 / g_ScaleX, -1024);
marginleft += 13;
}
return (s32)gdl;
case MENUOP_GETOPTIONHEIGHT:
data->list.value = 26;
break;
}
return 0;
}
/**
* This is for a separator and fixed height thing in the dialog at:
* Combat Simulator > Advanced Setup > Challenges > pick one > Accept
*/
s32 menuhandler0017e9d8(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKHIDDEN) {
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
return true;
}
}
return 0;
}
s32 menuhandlerMpAbortChallenge(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKHIDDEN) {
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
return true;
}
}
if (operation == MENUOP_SET) {
mpRemoveLock();
}
return 0;
}
s32 menuhandlerMpStartChallenge(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKHIDDEN) {
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
return true;
}
}
if (operation == MENUOP_SET) {
menuPushDialog(&g_MpReadyMenuDialog);
}
return 0;
}
char *mpMenuTextChallengeName(struct menuitem *item)
{
#if VERSION >= VERSION_NTSC_1_0
if (g_BossFile.locktype != MPLOCKTYPE_CHALLENGE) {
return langGet(L_MPMENU_050); // "Combat Challenges"
}
#endif
sprintf(g_StringPointer, "%s:\n", mpChallengeGetName(mpGetCurrentChallengeIndex()));
return g_StringPointer;
}
s32 mpCombatChallengesMenuDialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_TICK) {
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE
&& g_Menus[g_MpPlayerNum].curdialog
&& g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef
&& !mpIsChallengeLoaded()) {
g_Menus[g_MpPlayerNum].unk840.unk010 = 0x4fac5ace;
mpLoadAndStoreCurrentChallenge(
g_Menus[g_MpPlayerNum].unk840.unk004,
g_Menus[g_MpPlayerNum].unk840.unk008);
}
}
if (operation == MENUOP_CLOSE) {
if (g_Menus[g_MpPlayerNum].unk840.unk010 == 0x4fac5ace) {
mpClearCurrentChallenge();
}
}
return 0;
}
s32 menuhandler0017ec64(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
mpSetCurrentChallenge(g_Menus[g_MpPlayerNum].mpsetup.slotindex);
func0f0f820c(&g_MpQuickGoMenuDialog, 3);
}
return 0;
}
struct menuitem g_MpChallengesMenuItems[] = {
{ MENUITEMTYPE_LIST, 1, 0x00200000, 0x00000078, 0x0000004d, mpChallengesListMenuHandler },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpChallengesMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_050, // "Combat Challenges"
g_MpChallengesMenuItems,
mpCombatChallengesMenuDialog,
0,
NULL,
};
s32 menuhandlerMpLock(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 labels[] = {
L_MPMENU_045, // "None"
L_MPMENU_046, // "Last Winner"
L_MPMENU_047, // "Last Loser"
L_MPMENU_048, // "Random"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = mpGetLockType() == MPLOCKTYPE_CHALLENGE ? 1 : 5;
break;
case MENUOP_GETOPTIONTEXT:
if (mpGetLockType() == MPLOCKTYPE_CHALLENGE) {
return (s32) langGet(L_MPMENU_049); // "Challenge"
}
if (data->dropdown.value <= 3) {
return (s32) langGet(labels[data->dropdown.value]);
}
if (mpGetLockType() == MPLOCKTYPE_PLAYER) {
return (s32) g_PlayerConfigsArray[mpGetLockPlayerNum()].base.name;
}
return (s32) mpGetCurrentPlayerName(item);
case MENUOP_SET:
if (mpGetLockType() != MPLOCKTYPE_CHALLENGE) {
mpSetLock(data->dropdown.value, g_MpPlayerNum);
}
g_Vars.modifiedfiles |= MODFILE_MPSETUP;
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = mpGetLockType() == MPLOCKTYPE_CHALLENGE ? 0 : mpGetLockType();
break;
}
return 0;
}
s32 menuhandlerMpSavePlayer(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid == 0) {
filemgrPushSelectLocationDialog(6, FILETYPE_MPPLAYER);
} else {
menuPushDialog(&g_MpSavePlayerMenuDialog);
}
}
return 0;
}
char *mpMenuTextSavePlayerOrCopy(struct menuitem *item)
{
if (g_PlayerConfigsArray[g_MpPlayerNum].fileguid.fileid == 0) {
return langGet(L_MPMENU_038); // "Save Player"
}
return langGet(L_MPMENU_039); // "Save Copy of Player"
}
s32 menuhandler0017ef30(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
if (g_Vars.stagenum == STAGE_CITRAINING) {
if (IS4MB()) {
func0f0f820c(&g_CiMenuViaPauseMenuDialog, 2);
} else {
func0f0f820c(&g_CiMenuViaPcMenuDialog, 2);
}
} else {
func0f0f820c(&g_SoloMissionPauseMenuDialog, 2);
}
}
return 0;
}
s32 menuhandlerMpSaveSettings(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
if (g_MpSetup.fileguid.fileid == 0) {
menuPushDialog(&g_MpSaveSetupNameMenuDialog);
} else {
#if VERSION >= VERSION_NTSC_1_0
filemgrSetDevice1BySerial(g_MpSetup.fileguid.deviceserial);
#endif
menuPushDialog(&g_MpSaveSetupExistsMenuDialog);
}
}
return 0;
}
char *mpMenuTextArenaName(struct menuitem *item)
{
s32 i;
for (i = 0; i != ARRAYCOUNT(g_MpArenas); i++) {
if (g_MpArenas[i].stagenum == g_MpSetup.stagenum) {
return langGet(g_MpArenas[i].name);
}
}
return "\n";
}
char *mpMenuTextWeaponSetName(struct menuitem *item)
{
return mpGetWeaponSetName(mpGetWeaponSet());
}
s32 menudialogMpGameSetup(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_OPEN) {
g_Vars.mpsetupmenu = MPSETUPMENU_ADVSETUP;
g_Vars.usingadvsetup = true;
}
return false;
}
s32 menudialogMpQuickGo(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_OPEN) {
g_Vars.mpsetupmenu = MPSETUPMENU_QUICKGO;
}
return false;
}
void mpConfigureQuickTeamPlayers(void)
{
s32 i;
if (g_Vars.mpquickteam != MPQUICKTEAM_NONE) {
for (i = 0; i < MAX_BOTS; i++) {
mpRemoveSimulant(i);
}
switch (g_Vars.mpquickteam) {
case MPQUICKTEAM_PLAYERSONLY:
g_MpSetup.options &= ~MPOPTION_TEAMSENABLED;
break;
case MPQUICKTEAM_PLAYERSANDSIMS:
g_MpSetup.options &= ~MPOPTION_TEAMSENABLED;
break;
case MPQUICKTEAM_PLAYERSTEAMS:
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
for (i = 0; i < 4; i++) {
g_PlayerConfigsArray[i].base.team = g_Vars.mpplayerteams[i];
}
break;
case MPQUICKTEAM_PLAYERSVSSIMS:
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
for (i = 0; i < 4; i++) {
g_PlayerConfigsArray[i].base.team = 0;
}
break;
case MPQUICKTEAM_PLAYERSIMTEAMS:
g_MpSetup.options |= MPOPTION_TEAMSENABLED;
for (i = 0; i < 4; i++) {
g_PlayerConfigsArray[i].base.team = i;
}
break;
}
}
}
void mpConfigureQuickTeamSimulants(void)
{
struct mpchrconfig *mpchr;
s32 numchrs;
s32 botnum;
s32 i;
s32 j;
if (g_Vars.mpquickteam != MPQUICKTEAM_NONE) {
switch (g_Vars.mpquickteam) {
case MPQUICKTEAM_PLAYERSANDSIMS:
for (i = 0; i < g_Vars.mpquickteamnumsims; i++) {
botnum = mpGetSlotForNewBot();
if (botnum >= 0) {
mpCreateBotFromProfile(botnum, g_Vars.mpsimdifficulty);
}
}
mpGenerateBotNames();
break;
case MPQUICKTEAM_PLAYERSVSSIMS:
for (i = 0; i < g_Vars.mpquickteamnumsims; i++) {
botnum = mpGetSlotForNewBot();
if (botnum >= 0) {
mpCreateBotFromProfile(botnum, g_Vars.mpsimdifficulty);
}
}
mpGenerateBotNames();
for (i = 0; i < ARRAYCOUNT(g_BotConfigsArray); i++) {
g_BotConfigsArray[i].base.team = 1;
}
break;
case MPQUICKTEAM_PLAYERSIMTEAMS:
for (i = mpGetNumChrs() - 1; i >= 0; i--) {
mpchr = mpGetChrConfigBySlotNum(i);
for (j = 0; j < g_Vars.unk0004a0; j++) {
botnum = mpGetSlotForNewBot();
if (botnum >= 0) {
mpCreateBotFromProfile(botnum, g_Vars.mpsimdifficulty);
g_BotConfigsArray[botnum].base.team = mpchr->team;
}
}
}
mpGenerateBotNames();
break;
case MPQUICKTEAM_PLAYERSONLY:
case MPQUICKTEAM_PLAYERSTEAMS:
break;
}
}
}
void func0f17f428(void)
{
mpConfigureQuickTeamPlayers();
if (IS4MB()) {
func0f0f820c(&g_MpQuickGo4MbMenuDialog, MENUROOT_4MBMAINMENU);
} else {
func0f0f820c(&g_MpQuickGoMenuDialog, MENUROOT_MPSETUP);
}
}
s32 menuhandlerMpFinishedSetup(s32 operation, struct menuitem *item, union handlerdata *data)
{
#if VERSION >= VERSION_NTSC_1_0
if (operation == MENUOP_CHECKPREFOCUSED) {
return true;
}
#endif
if (operation == MENUOP_SET) {
func0f17f428();
}
return 0;
}
s32 menuhandlerQuickTeamSeparator(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKHIDDEN) {
if (g_Vars.mpquickteam == MPQUICKTEAM_PLAYERSONLY) {
return true;
}
}
return 0;
}
#if VERSION >= VERSION_JPN_FINAL
GLOBAL_ASM(
glabel menuhandlerPlayerTeam
.late_rodata
glabel var7f1b9204
.word 0x7f17fb18
.word 0x7f17fc20
.word 0x7f17fb2c
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fb4c
.word 0x7f17fb64
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc20
.word 0x7f17fc04
.text
/* f17faec: 248effff */ addiu $t6,$a0,-1
/* f17faf0: 27bdffe8 */ addiu $sp,$sp,-24
/* f17faf4: 2dc10018 */ sltiu $at,$t6,0x18
/* f17faf8: 10200049 */ beqz $at,.JF0f17fc20
/* f17fafc: afbf0014 */ sw $ra,0x14($sp)
/* f17fb00: 000e7080 */ sll $t6,$t6,0x2
/* f17fb04: 3c017f1c */ lui $at,0x7f1c
/* f17fb08: 002e0821 */ addu $at,$at,$t6
/* f17fb0c: 8c2e9204 */ lw $t6,-0x6dfc($at)
/* f17fb10: 01c00008 */ jr $t6
/* f17fb14: 00000000 */ nop
/* f17fb18: 0fc61aba */ jal 0xf186ae8
/* f17fb1c: afa60020 */ sw $a2,0x20($sp)
/* f17fb20: 8fa60020 */ lw $a2,0x20($sp)
/* f17fb24: 1000003e */ b .JF0f17fc20
/* f17fb28: acc20000 */ sw $v0,0x0($a2)
/* f17fb2c: 8ccf0000 */ lw $t7,0x0($a2)
/* f17fb30: 3c19800b */ lui $t9,0x800b
/* f17fb34: 2739d5e0 */ addiu $t9,$t9,-10784
/* f17fb38: 000fc080 */ sll $t8,$t7,0x2
/* f17fb3c: 030fc023 */ subu $t8,$t8,$t7
/* f17fb40: 0018c080 */ sll $t8,$t8,0x2
/* f17fb44: 10000037 */ b .JF0f17fc24
/* f17fb48: 03191021 */ addu $v0,$t8,$t9
/* f17fb4c: 90a90001 */ lbu $t1,0x1($a1)
/* f17fb50: 8cc80000 */ lw $t0,0x0($a2)
/* f17fb54: 3c01800a */ lui $at,0x800a
/* f17fb58: 00290821 */ addu $at,$at,$t1
/* f17fb5c: 10000030 */ b .JF0f17fc20
/* f17fb60: a028aadc */ sb $t0,-0x5524($at)
/* f17fb64: afa5001c */ sw $a1,0x1c($sp)
/* f17fb68: 0fc61aba */ jal 0xf186ae8
/* f17fb6c: afa60020 */ sw $a2,0x20($sp)
/* f17fb70: 8fa5001c */ lw $a1,0x1c($sp)
/* f17fb74: 3c04800a */ lui $a0,0x800a
/* f17fb78: 8fa60020 */ lw $a2,0x20($sp)
/* f17fb7c: 90aa0001 */ lbu $t2,0x1($a1)
/* f17fb80: 008a2021 */ addu $a0,$a0,$t2
/* f17fb84: 8084aadc */ lb $a0,-0x5524($a0)
/* f17fb88: 0082082a */ slt $at,$a0,$v0
/* f17fb8c: 1420001b */ bnez $at,.JF0f17fbfc
/* f17fb90: 00000000 */ nop
/* f17fb94: afa5001c */ sw $a1,0x1c($sp)
/* f17fb98: 0fc61aba */ jal 0xf186ae8
/* f17fb9c: afa60020 */ sw $a2,0x20($sp)
/* f17fba0: 8fa5001c */ lw $a1,0x1c($sp)
/* f17fba4: 3c0c800a */ lui $t4,0x800a
/* f17fba8: 258ca630 */ addiu $t4,$t4,-22992
/* f17fbac: 90ab0001 */ lbu $t3,0x1($a1)
/* f17fbb0: 3c04800a */ lui $a0,0x800a
/* f17fbb4: 8fa60020 */ lw $a2,0x20($sp)
/* f17fbb8: 016c1821 */ addu $v1,$t3,$t4
/* f17fbbc: 806d04ac */ lb $t5,0x4ac($v1)
/* f17fbc0: 01a2001a */ div $zero,$t5,$v0
/* f17fbc4: 00007010 */ mfhi $t6
/* f17fbc8: a06e04ac */ sb $t6,0x4ac($v1)
/* f17fbcc: 90af0001 */ lbu $t7,0x1($a1)
/* f17fbd0: 14400002 */ bnez $v0,.JF0f17fbdc
/* f17fbd4: 00000000 */ nop
/* f17fbd8: 0007000d */ break 0x7
.JF0f17fbdc:
/* f17fbdc: 2401ffff */ li $at,-1
/* f17fbe0: 14410004 */ bne $v0,$at,.JF0f17fbf4
/* f17fbe4: 3c018000 */ lui $at,0x8000
/* f17fbe8: 15a10002 */ bne $t5,$at,.JF0f17fbf4
/* f17fbec: 00000000 */ nop
/* f17fbf0: 0006000d */ break 0x6
.JF0f17fbf4:
/* f17fbf4: 008f2021 */ addu $a0,$a0,$t7
/* f17fbf8: 8084aadc */ lb $a0,-0x5524($a0)
.JF0f17fbfc:
/* f17fbfc: 10000008 */ b .JF0f17fc20
/* f17fc00: acc40000 */ sw $a0,0x0($a2)
/* f17fc04: 3c18800a */ lui $t8,0x800a
/* f17fc08: 8f18aae0 */ lw $t8,-0x5520($t8)
/* f17fc0c: 24010002 */ li $at,0x2
/* f17fc10: 53010004 */ beql $t8,$at,.JF0f17fc24
/* f17fc14: 00001025 */ move $v0,$zero
/* f17fc18: 10000002 */ b .JF0f17fc24
/* f17fc1c: 24020001 */ li $v0,0x1
.JF0f17fc20:
/* f17fc20: 00001025 */ move $v0,$zero
.JF0f17fc24:
/* f17fc24: 8fbf0014 */ lw $ra,0x14($sp)
/* f17fc28: 27bd0018 */ addiu $sp,$sp,0x18
/* f17fc2c: 03e00008 */ jr $ra
/* f17fc30: 00000000 */ nop
);
#else
s32 menuhandlerPlayerTeam(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 8;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) &g_BossFile.teamnames[data->dropdown.value];
case MENUOP_SET:
g_Vars.mpplayerteams[item->param] = data->dropdown.value;
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = g_Vars.mpplayerteams[item->param];
break;
case MENUOP_CHECKHIDDEN:
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSTEAMS) {
return true;
}
break;
}
return 0;
}
#endif
s32 menuhandlerMpNumberOfSimulants(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = !mpIsFeatureUnlocked(MPFEATURE_8BOTS) ? 4 : MAX_BOTS;
break;
case MENUOP_GETOPTIONTEXT:
sprintf(g_StringPointer, "%d\n", data->dropdown.value + 1);
return (s32) g_StringPointer;
case MENUOP_SET:
g_Vars.mpquickteamnumsims = data->dropdown.value + 1;
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = g_Vars.mpquickteamnumsims - 1;
break;
case MENUOP_CHECKHIDDEN:
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSANDSIMS
&& g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSVSSIMS) {
return true;
}
break;
}
return 0;
}
s32 menuhandlerMpSimulantsPerTeam(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 2;
break;
case MENUOP_GETOPTIONTEXT:
sprintf(g_StringPointer, "%d\n", data->dropdown.value + 1);
return (s32) g_StringPointer;
case MENUOP_SET:
g_Vars.unk0004a0 = data->dropdown.value + 1;
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = g_Vars.unk0004a0 - 1;
break;
case MENUOP_CHECKHIDDEN:
if (g_Vars.mpquickteam != MPQUICKTEAM_PLAYERSIMTEAMS) {
return true;
}
break;
}
return 0;
}
s32 mpQuickTeamSimulantDifficultyHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
s32 count = 0;
s32 i;
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
for (i = 0; i < 6; i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
count++;
}
}
data->dropdown.value = count;
break;
case MENUOP_GETOPTIONTEXT:
for (i = 0; i < 6; i++) {
if (mpIsFeatureUnlocked(g_BotProfiles[i].requirefeature)) {
if (count == data->dropdown.value) {
return (s32) langGet(i + L_MISC_082);
}
count++;
}
}
break;
case MENUOP_SET:
g_Vars.mpsimdifficulty = data->dropdown.value;
break;
case MENUOP_GETOPTIONVALUE:
data->dropdown.value = g_Vars.mpsimdifficulty;
break;
case MENUOP_CHECKHIDDEN:
if (g_Vars.mpquickteam != 1 && g_Vars.mpquickteam != 3 && g_Vars.mpquickteam != 4) {
return true;
}
}
return 0;
}
s32 menuhandlerMpQuickTeamOption(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_Vars.mpquickteam = item->param;
if (mpGetWeaponSet() >= func0f189058(0)) {
mpSetWeaponSet(0);
}
if (g_Vars.mpquickteam == MPQUICKTEAM_PLAYERSONLY ||
g_Vars.mpquickteam == MPQUICKTEAM_PLAYERSANDSIMS) {
if (g_MpSetup.scenario == MPSCENARIO_KINGOFTHEHILL ||
g_MpSetup.scenario == MPSCENARIO_CAPTURETHECASE) {
g_MpSetup.scenario = MPSCENARIO_COMBAT;
}
}
menuPushDialog(&g_MpQuickTeamGameSetupMenuDialog);
}
return 0;
}
s32 menudialogCombatSimulator(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_OPEN) {
g_Vars.waitingtojoin[0] = false;
g_Vars.waitingtojoin[1] = false;
g_Vars.waitingtojoin[2] = false;
g_Vars.waitingtojoin[3] = false;
}
if (g_Menus[g_MpPlayerNum].curdialog
&& g_Menus[g_MpPlayerNum].curdialog->definition == &g_CombatSimulatorMenuDialog
&& operation == MENUOP_TICK) {
g_Vars.mpsetupmenu = MPSETUPMENU_GENERAL;
g_Vars.mpquickteam = MPQUICKTEAM_NONE;
g_Vars.usingadvsetup = false;
mpClearCurrentChallenge();
mpRemoveLock();
}
return false;
}
s32 menuhandlerMpAdvancedSetup(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
func0f0f820c(&g_MpAdvancedSetupMenuDialog, 3);
}
return 0;
}
/**
* When a player is loading a saved setup, check which dialogs the other players
* have open and close them if they no longer apply or need to be updated.
*/
void mpCloseDialogsForNewSetup(void)
{
s32 i;
s32 prevplayernum = g_MpPlayerNum;
s32 j;
s32 k;
// Loop through each player
for (i = 0; i < 4; i++) {
g_MpPlayerNum = i;
// If they have a menu open
if (g_Menus[g_MpPlayerNum].curdialog) {
bool ok = false;
// Repeat the following steps until we've stopped finding dialogs
// that should be closed
while (!ok) {
ok = true;
// Loop through each layer of menus
for (j = 0; j < g_Menus[g_MpPlayerNum].depth; j++) {
// Loop through the siblings (left/right) in this layer
for (k = 0; k < g_Menus[g_MpPlayerNum].layers[j].numsiblings; k++) {
if (g_Menus[g_MpPlayerNum].layers[j].siblings[k]) {
struct menudialogdef *dialogdef = g_Menus[g_MpPlayerNum].layers[j].siblings[k]->definition;
if (dialogdef == &g_MpSaveSetupNameMenuDialog) ok = false;
if (dialogdef == &g_MpSaveSetupExistsMenuDialog) ok = false;
if (dialogdef == &g_MpAddSimulantMenuDialog) ok = false;
if (dialogdef == &g_MpChangeSimulantMenuDialog) ok = false;
if (dialogdef == &g_MpEditSimulantMenuDialog) ok = false;
if (dialogdef == &g_MpCombatOptionsMenuDialog) ok = false;
if (dialogdef == &g_HtbOptionsMenuDialog) ok = false;
if (dialogdef == &g_CtcOptionsMenuDialog) ok = false;
if (dialogdef == &g_KohOptionsMenuDialog) ok = false;
if (dialogdef == &g_HtmOptionsMenuDialog) ok = false;
if (dialogdef == &g_PacOptionsMenuDialog) ok = false;
}
}
}
// Close the leaf layer
if (!ok) {
menuPopDialog();
}
}
}
}
g_MpPlayerNum = prevplayernum;
}
struct menudialogdef g_MpAbortMenuDialog;
struct menuitem g_MpStuffMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_041, 0x00000000, (void *)&g_MpSoundtrackMenuDialog }, // "Soundtrack"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_042, 0x00000000, (void *)&g_MpTeamNamesMenuDialog }, // "Team Names"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00020000, L_MPMENU_044, 0x00000000, menuhandlerMpLock }, // "Lock"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_OPTIONS_216, 0x00000000, menuhandlerScreenRatio }, // "Ratio"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_MPWEAPONS_154, 0x00000000, menuhandlerScreenSplit }, // "Split"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_036, 0x00000000, (void *)&g_MpReadyMenuDialog }, // "Start Game"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_037, 0x00000000, (void *)&g_MpDropOutMenuDialog }, // "Drop Out"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_027, 0x00000000, (void *)&g_MpAbortMenuDialog }, // "Abort Game"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpStuffMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_040, // "Stuff"
g_MpStuffMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
&g_MpChallengeListOrDetailsMenuDialog,
};
struct menudialogdef g_MpStuffViaAdvChallengeMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_040, // "Stuff"
g_MpStuffMenuItems,
NULL,
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
NULL,
};
struct menuitem g_MpPlayerSetup234MenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_030, (u32)&mpGetCurrentPlayerName, (void *)&g_MpPlayerNameMenuDialog }, // "Name"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_031, 0x00000000, (void *)&g_MpCharacterMenuDialog }, // "Character"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_033, 0x00000000, (void *)&g_MpControlMenuDialog }, // "Control"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_034, 0x00000000, (void *)&g_MpPlayerOptionsMenuDialog }, // "Player Options"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_035, 0x00000000, (void *)&g_MpPlayerStatsMenuDialog }, // "Statistics"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_029, 0x00000000, (void *)&g_MpLoadPlayerMenuDialog }, // "Load Player"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, (u32)&mpMenuTextSavePlayerOrCopy, 0x00000000, menuhandlerMpSavePlayer },
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpPlayerSetupViaAdvMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_028, // "Player Setup"
g_MpPlayerSetup234MenuItems,
NULL,
MENUDIALOGFLAG_DROPOUTONCLOSE,
&g_MpStuffMenuDialog,
};
struct menudialogdef g_MpPlayerSetupViaAdvChallengeMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_028, // "Player Setup"
g_MpPlayerSetup234MenuItems,
NULL,
MENUDIALOGFLAG_DROPOUTONCLOSE,
&g_MpStuffViaAdvChallengeMenuDialog,
};
struct menudialogdef g_MpPlayerSetupViaQuickGoMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_028, // "Player Setup"
g_MpPlayerSetup234MenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpAbortMenuItems[] = {
{ MENUITEMTYPE_LABEL, 0, 0x00000010, L_MPMENU_053, 0x00000000, NULL }, // "Are you sure you want to abort the game?"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_054, 0x00000000, menuhandler0017ef30 }, // "Abort"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000008, L_MPMENU_055, 0x00000000, NULL }, // "Cancel"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpAbortMenuDialog = {
MENUDIALOGTYPE_DANGER,
L_MPMENU_052, // "Abort"
g_MpAbortMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpAdvancedSetupMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020004, L_MPMENU_019, (u32)&mpMenuTextScenarioShortName, (void *)&g_MpScenarioMenuDialog }, // "Scenario"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_021, 0x00000000, menuhandlerMpOpenOptions }, // "Options"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_020, (u32)&mpMenuTextArenaName, (void *)&g_MpArenaMenuDialog }, // "Arena"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_023, 0x00000000, (void *)&g_MpWeaponsMenuDialog }, // "Weapons"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_024, 0x00000000, (void *)&g_MpLimitsMenuDialog }, // "Limits"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPWEAPONS_184, 0x00000000, (void *)&g_MpHandicapsMenuDialog }, // "Player Handicaps"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_025, 0x00000000, (void *)&g_MpSimulantsMenuDialog }, // "Simulants"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_022, 0x00000000, (void *)&g_MpTeamsMenuDialog }, // "Teams"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000082, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00060004, L_MPMENU_018, 0x00000000, (void *)&g_MpLoadSettingsMenuDialog }, // "Load Settings"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00060000, L_MPMENU_026, 0x00000000, menuhandlerMpSaveSettings }, // "Save Settings"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpAdvancedSetupMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_017, // "Game Setup"
g_MpAdvancedSetupMenuItems,
menudialogMpGameSetup,
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
&g_MpPlayerSetupViaAdvMenuDialog,
};
struct menudialogdef g_MpAdvancedSetupViaAdvChallengeMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_017, // "Game Setup"
g_MpAdvancedSetupMenuItems,
menudialogMpGameSetup,
MENUDIALOGFLAG_MPLOCKABLE | MENUDIALOGFLAG_DROPOUTONCLOSE,
&g_MpPlayerSetupViaAdvChallengeMenuDialog,
};
struct menuitem g_MpQuickGoMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MISC_456, 0x00000000, (void *)&g_MpReadyMenuDialog }, // "Start Game"
#if VERSION >= VERSION_NTSC_1_0
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_029, 0x00000000, (void *)&g_MpLoadPlayerMenuDialog }, // "Load Player"
#endif
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MISC_458, 0x00000000, (void *)&g_MpPlayerSetupViaQuickGoMenuDialog }, // "Player Settings"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MISC_457, 0x00000000, (void *)&g_MpDropOutMenuDialog }, // "Drop Out"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpQuickGoMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MISC_460, // "Quick Go"
g_MpQuickGoMenuItems,
menudialogMpQuickGo,
0,
NULL,
};
struct menuitem g_MpQuickTeamGameSetupMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00020004, L_MPMENU_019, (u32)&mpMenuTextScenarioShortName, (void *)&g_MpQuickTeamScenarioMenuDialog }, // "Scenario"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MPMENU_021, 0x00000000, menuhandlerMpOpenOptions }, // "Options"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_020, (u32)&mpMenuTextArenaName, (void *)&g_MpArenaMenuDialog }, // "Arena"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_023, (u32)&mpMenuTextWeaponSetName, (void *)&g_MpQuickTeamWeaponsMenuDialog }, // "Weapons"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000004, L_MPMENU_024, 0x00000000, (void *)&g_MpLimitsMenuDialog }, // "Limits"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000082, 0x00000000, menuhandlerQuickTeamSeparator },
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_MISC_449, 0x00000000, menuhandlerPlayerTeam }, // "Player 1 Team"
{ MENUITEMTYPE_DROPDOWN, 1, 0x00000000, L_MISC_450, 0x00000000, menuhandlerPlayerTeam }, // "Player 2 Team"
{ MENUITEMTYPE_DROPDOWN, 2, 0x00000000, L_MISC_451, 0x00000000, menuhandlerPlayerTeam }, // "Player 3 Team"
{ MENUITEMTYPE_DROPDOWN, 3, 0x00000000, L_MISC_452, 0x00000000, menuhandlerPlayerTeam }, // "Player 4 Team"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_MISC_453, 0x00000000, menuhandlerMpNumberOfSimulants }, // "Number Of Simulants"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_MISC_454, 0x00000000, menuhandlerMpSimulantsPerTeam }, // "Simulants Per Team"
{ MENUITEMTYPE_DROPDOWN, 0, 0x00000000, L_MISC_455, 0x00000000, mpQuickTeamSimulantDifficultyHandler }, // "Simulant Difficulty"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000082, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00000000, L_MISC_448, 0x00000000, menuhandlerMpFinishedSetup }, // "Finished Setup"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000082, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 0, 0x00060000, L_MPMENU_026, 0x00000000, menuhandlerMpSaveSettings }, // "Save Settings"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpQuickTeamGameSetupMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_017, // "Game Setup"
g_MpQuickTeamGameSetupMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MpQuickTeamMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00400000, L_MISC_463, 0x00000000, menuhandlerMpQuickTeamOption }, // "Players Only"
{ MENUITEMTYPE_SELECTABLE, 1, 0x00400000, L_MISC_464, 0x00000000, menuhandlerMpQuickTeamOption }, // "Players and Simulants"
{ MENUITEMTYPE_SEPARATOR, 0, 0x00000000, 0x00000082, 0x00000000, NULL },
{ MENUITEMTYPE_SELECTABLE, 2, 0x00400000, L_MISC_465, 0x00000000, menuhandlerMpQuickTeamOption }, // "Player Teams"
{ MENUITEMTYPE_SELECTABLE, 3, 0x00400000, L_MISC_466, 0x00000000, menuhandlerMpQuickTeamOption }, // "Players vs. Simulants"
{ MENUITEMTYPE_SELECTABLE, 4, 0x00400000, L_MISC_467, 0x00000000, menuhandlerMpQuickTeamOption }, // "Player-Simulant Teams"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_MpQuickTeamMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MISC_462, // "Quick Team"
g_MpQuickTeamMenuItems,
NULL,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
struct menuitem g_CombatSimulatorMenuItems[] = {
{ MENUITEMTYPE_SELECTABLE, 0, 0x00400004, L_MISC_441, 0x00000000, (void *)&g_MpChallengesMenuDialog }, // "Challenges"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00400004, L_MISC_442, 0x00000001, (void *)&g_MpLoadPresetMenuDialog }, // "Load/Preset Games"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00400004, L_MISC_443, 0x00000002, (void *)&g_MpQuickTeamMenuDialog }, // "Quick Start"
{ MENUITEMTYPE_SELECTABLE, 0, 0x00400000, L_MISC_444, 0x00000003, menuhandlerMpAdvancedSetup }, // "Advanced Setup"
{ MENUITEMTYPE_END, 0, 0x00000000, 0x00000000, 0x00000000, NULL },
};
struct menudialogdef g_CombatSimulatorMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MISC_445, // "Combat Simulator"
g_CombatSimulatorMenuItems,
menudialogCombatSimulator,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
void func0f17fcb0(s32 silent)
{
g_Menus[g_MpPlayerNum].playernum = g_MpPlayerNum;
if (IS4MB()) {
menuPushRootDialog(&g_AdvancedSetup4MbMenuDialog, MENUROOT_4MBMAINMENU);
func0f0f8300();
} else {
if (g_BossFile.locktype == MPLOCKTYPE_CHALLENGE) {
menuPushRootDialog(&g_MpChallengeListOrDetailsViaAdvChallengeMenuDialog, MENUROOT_MPSETUP);
} else {
menuPushRootDialog(&g_MpAdvancedSetupMenuDialog, MENUROOT_MPSETUP);
}
func0f0f8300();
}
if (!silent) {
// Explosion sound
sndStart(var80095200, SFX_EXPLOSION_809A, NULL, -1, -1, -1, -1, -1);
}
}