Files
perfect-dark/src/game/mainmenu.c
T

4910 lines
109 KiB
C

#include <ultra64.h>
#include "constants.h"
#include "game/bondgun.h"
#include "game/bossfile.h"
#include "game/challenge.h"
#include "game/cheats.h"
#include "game/debug.h"
#include "game/filemgr.h"
#include "game/game_0b0fd0.h"
#include "game/game_1531a0.h"
#include "game/gamefile.h"
#include "game/inv.h"
#include "game/lang.h"
#include "game/lv.h"
#include "game/mainmenu.h"
#include "game/menu.h"
#include "game/mplayer/ingame.h"
#include "game/mplayer/mplayer.h"
#include "game/objectives.h"
#include "game/options.h"
#include "game/pdmode.h"
#include "game/player.h"
#include "game/setup.h"
#include "game/tex.h"
#include "game/title.h"
#include "game/training.h"
#include "bss.h"
#include "lib/vi.h"
#include "lib/joy.h"
#include "lib/main.h"
#include "lib/snd.h"
#include "lib/str.h"
#include "data.h"
#include "types.h"
u8 g_InventoryWeapon;
struct menudialogdef g_2PMissionControlStyleMenuDialog;
struct menudialogdef g_CiControlPlayer2MenuDialog;
struct menudialogdef g_CinemaMenuDialog;
char *menuTextCurrentStageName(struct menuitem *item)
{
sprintf(g_StringPointer, "%s\n", langGet(g_StageNames[g_MissionConfig.stageindex].name3));
return g_StringPointer;
}
char *soloMenuTextDifficulty(struct menuitem *item)
{
#if VERSION >= VERSION_NTSC_1_0
if (g_MissionConfig.pdmode) {
return langGet(L_MPWEAPONS_221);
}
#endif
switch (g_MissionConfig.difficulty) {
case DIFF_SA:
return langGet(L_OPTIONS_252);
case DIFF_PA:
return langGet(L_OPTIONS_253);
case DIFF_A:
default:
return langGet(L_OPTIONS_251);
}
}
u16 g_ControlStyleOptions[] = {
L_OPTIONS_239, // "1.1"
L_OPTIONS_240, // "1.2"
L_OPTIONS_241, // "1.3"
L_OPTIONS_242, // "1.4"
L_OPTIONS_243, // "2.1"
L_OPTIONS_244, // "2.2"
L_OPTIONS_245, // "2.3"
L_OPTIONS_246, // "2.4"
};
s32 menuhandlerControlStyleImpl(s32 operation, struct menuitem *item, union handlerdata *data, s32 mpindex)
{
u16 categories[] = {
L_OPTIONS_237, // "Single"
L_OPTIONS_238, // "Double"
};
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpindex = g_Vars.currentplayerstats->mpindex;
}
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = 8;
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = 2;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(g_ControlStyleOptions[data->list.value]);
case MENUOP_GETOPTGROUPTEXT:
return (s32) langGet(categories[data->list.value]);
case MENUOP_GETGROUPSTARTINDEX:
data->list.groupstartindex = data->list.value == 0 ? 0 : 4;
break;
case MENUOP_SET:
optionsSetControlMode(mpindex, data->list.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
break;
case MENUOP_GETSELECTEDINDEX:
data->list.value = optionsGetControlMode(mpindex);
g_Menus[g_MpPlayerNum].main.mpindex = mpindex;
break;
case MENUOP_LISTITEMFOCUS:
if (g_MenuData.root == MENUROOT_MAINMENU) {
g_Menus[g_MpPlayerNum].main.controlmode = data->list.value;
}
break;
}
return 0;
}
s32 menuhandler001024dc(s32 operation, struct menuitem *item, union handlerdata *data)
{
return menuhandlerControlStyleImpl(operation, item, data, 4);
}
s32 menuhandler001024fc(s32 operation, struct menuitem *item, union handlerdata *data)
{
return menuhandlerControlStyleImpl(operation, item, data, 5);
}
s32 menuhandlerReversePitch(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return !optionsGetForwardPitch(mpchrnum);
case MENUOP_SET:
optionsSetForwardPitch(mpchrnum, data->checkbox.value == 0);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerAimControl(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 playernum = (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0)
? g_Vars.currentplayerstats->mpindex : item->param3;
#if VERSION >= VERSION_PAL_FINAL
s32 index = 0;
u16 options[2][2] = {
{ L_OPTIONS_201, L_OPTIONS_202 }, // "Hold", "Toggle"
{ L_MPWEAPONS_276, L_MPWEAPONS_277 }, // "Hold", "Toggle"
};
if (optionsGetScreenSplit() == SCREENSPLIT_VERTICAL && PLAYERCOUNT() >= 2) {
index = 1;
}
#else
u16 options[] = {
L_OPTIONS_201, // "Hold"
L_OPTIONS_202, // "Toggle"
};
#endif
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 2;
break;
case MENUOP_GETOPTIONTEXT:
#if VERSION >= VERSION_PAL_FINAL
return (s32) langGet(options[index][data->dropdown.value]);
#else
return (s32) langGet(options[data->dropdown.value]);
#endif
case MENUOP_SET:
optionsSetAimControl(playernum, data->dropdown.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = optionsGetAimControl(playernum);
}
return 0;
}
s32 menuhandlerSoundMode(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 options[] = {
L_OPTIONS_232, // "Mono"
L_OPTIONS_233, // "Stereo"
L_OPTIONS_234, // "Headphone"
L_OPTIONS_235, // "Surround"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 4;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(options[data->dropdown.value]);
case MENUOP_SET:
sndSetSoundMode(data->dropdown.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = g_SoundMode;
}
return 0;
}
s32 menuhandlerScreenSize(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 options[] = {
L_OPTIONS_220, // "Full"
L_OPTIONS_221, // "Wide"
L_OPTIONS_222, // "Cinema"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 3;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(options[data->dropdown.value]);
case MENUOP_SET:
optionsSetScreenSize(data->dropdown.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = optionsGetEffectiveScreenSize();
}
return 0;
}
s32 menuhandlerScreenRatio(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 options[] = {
L_OPTIONS_223, // "Normal"
L_OPTIONS_224, // "16:9"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 2;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(options[data->dropdown.value]);
case MENUOP_SET:
optionsSetScreenRatio(data->dropdown.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = optionsGetScreenRatio();
}
return 0;
}
#if PAL
s32 menuhandlerLanguage(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 labels[] = {
L_MPWEAPONS_262, // English
L_MPWEAPONS_263, // French
L_MPWEAPONS_264, // German
L_MPWEAPONS_265, // Italian
L_MPWEAPONS_266, // Spanish
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 5;
break;
case MENUOP_GETOPTIONTEXT:
return (s32)langGet(labels[data->dropdown.value]);
case MENUOP_SET:
g_Vars.language = data->dropdown.value;
langSetEuropean(g_Vars.language);
g_Vars.modifiedfiles |= MODFILE_GAME | MODFILE_BOSS;
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = g_Vars.language;
if (data->dropdown.value > LANGUAGE_PAL_ES) {
data->dropdown.value = LANGUAGE_PAL_EN;
}
break;
}
return 0;
}
#endif
s32 menuhandlerScreenSplit(s32 operation, struct menuitem *item, union handlerdata *data)
{
u16 options[] = {
L_OPTIONS_225, // "Horizontal"
L_OPTIONS_226, // "Vertical"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 2;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(options[data->dropdown.value]);
case MENUOP_SET:
if (data->dropdown.value != (u32)optionsGetScreenSplit()) {
optionsSetScreenSplit(data->dropdown.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
if (PLAYERCOUNT() > 1) {
u32 prevplayernum = g_MpPlayerNum;
g_MpPlayerNum = 0;
func0f0f8120();
g_MpPlayerNum = 1;
func0f0f8120();
g_MpPlayerNum = prevplayernum;
}
}
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = optionsGetScreenSplit();
break;
}
return 0;
}
s32 menuhandlerLookAhead(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return optionsGetLookAhead(mpchrnum);
case MENUOP_SET:
optionsSetLookAhead(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerHeadRoll(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return optionsGetHeadRoll(mpchrnum);
case MENUOP_SET:
optionsSetHeadRoll(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerInGameSubtitles(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return optionsGetInGameSubtitles();
case MENUOP_SET:
optionsSetInGameSubtitles(data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerCutsceneSubtitles(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return optionsGetCutsceneSubtitles();
case MENUOP_SET:
optionsSetCutsceneSubtitles(data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerAlternativeTitle(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_CHECKHIDDEN:
if (g_Vars.stagenum != STAGE_CITRAINING || (u8)g_AltTitleUnlocked == false) {
return true;
}
break;
case MENUOP_GET:
return g_AltTitleEnabled;
case MENUOP_SET:
g_AltTitleEnabled = data->checkbox.value;
g_Vars.modifiedfiles |= MODFILE_BOSS;
}
return 0;
}
s32 menuhandlerHiRes(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_CHECKHIDDEN:
if (IS4MB()) {
return true;
}
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
if (PLAYERCOUNT() >= 2) {
return true;
}
}
break;
case MENUOP_GET:
return g_HiResEnabled == true;
case MENUOP_SET:
playerSetHiResEnabled(data->checkbox.value ? 1 : 0);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerAmmoOnScreen(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return optionsGetAmmoOnScreen(mpchrnum);
case MENUOP_SET:
optionsSetAmmoOnScreen(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerShowGunFunction(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_CHECKDISABLED:
if (optionsGetAmmoOnScreen(mpchrnum) == 0) {
return true;
}
break;
case MENUOP_GET:
return optionsGetShowGunFunction(mpchrnum);
case MENUOP_SET:
optionsSetShowGunFunction(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerShowMissionTime(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return optionsGetShowMissionTime(mpchrnum);
case MENUOP_SET:
optionsSetShowMissionTime(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerAlwaysShowTarget(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_CHECKDISABLED:
if (optionsGetSightOnScreen(mpchrnum) == 0) {
return true;
}
break;
case MENUOP_GET:
return optionsGetAlwaysShowTarget(mpchrnum);
case MENUOP_SET:
optionsSetAlwaysShowTarget(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerShowZoomRange(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_CHECKDISABLED:
if (optionsGetSightOnScreen(mpchrnum) == 0) {
return true;
}
break;
case MENUOP_GET:
return optionsGetShowZoomRange(mpchrnum);
case MENUOP_SET:
optionsSetShowZoomRange(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerPaintball(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return optionsGetPaintball(mpchrnum);
case MENUOP_SET:
optionsSetPaintball(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerSightOnScreen(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return optionsGetSightOnScreen(mpchrnum);
case MENUOP_SET:
optionsSetSightOnScreen(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerAutoAim(s32 operation, struct menuitem *item, union handlerdata *data)
{
u32 mpchrnum;
if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) {
mpchrnum = g_Vars.currentplayerstats->mpindex;
} else {
mpchrnum = item->param3;
}
switch (operation) {
case MENUOP_GET:
return optionsGetAutoAim(mpchrnum);
case MENUOP_SET:
optionsSetAutoAim(mpchrnum, data->checkbox.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerMusicVolume(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = optionsGetMusicVolume();
break;
case MENUOP_SET:
optionsSetMusicVolume(data->slider.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerSfxVolume(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = VOLUME(g_SfxVolume);
break;
case MENUOP_SET:
sndSetSfxVolume(data->slider.value);
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menudialogBriefing(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_TICK) {
if (g_Menus[g_MpPlayerNum].curdialog
&& g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef) {
struct menuinputs *inputs = data->dialog2.inputs;
if (inputs->start) {
menuhandlerAcceptMission(MENUOP_SET, NULL, data);
}
inputs->start = false;
}
}
return 0;
}
struct menuitem g_PreAndPostMissionBriefingMenuItems[] = {
{
MENUITEMTYPE_SCROLLABLE,
DESCRIPTION_BRIEFING,
0,
0,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_PreAndPostMissionBriefingMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_247, // "Briefing"
g_PreAndPostMissionBriefingMenuItems,
menudialogBriefing,
MENUDIALOGFLAG_DISABLEITEMSCROLL,
NULL,
};
s32 menuhandlerAcceptMission(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
menuStop();
if (g_Vars.stagenum == g_MissionConfig.stagenum) {
g_Vars.restartlevel = true;
}
titleSetNextStage(g_MissionConfig.stagenum);
if (g_MissionConfig.iscoop) {
if (g_Vars.numaibuddies == 0) {
// Coop with human buddy
g_Vars.bondplayernum = 0;
g_Vars.coopplayernum = 1;
g_Vars.antiplayernum = -1;
setNumPlayers(2);
} else {
// Coop with AI buddies
g_Vars.bondplayernum = 0;
g_Vars.coopplayernum = -1;
g_Vars.antiplayernum = -1;
setNumPlayers(1);
}
} else if (g_MissionConfig.isanti) {
if (g_Vars.pendingantiplayernum == 1) {
g_Vars.bondplayernum = 0;
g_Vars.antiplayernum = 1;
} else {
g_Vars.bondplayernum = 1;
g_Vars.antiplayernum = 0;
}
g_Vars.coopplayernum = -1;
setNumPlayers(2);
} else {
// Solo
g_Vars.bondplayernum = 0;
g_Vars.coopplayernum = -1;
g_Vars.antiplayernum = -1;
setNumPlayers(1);
}
lvSetDifficulty(g_MissionConfig.difficulty);
titleSetNextMode(TITLEMODE_SKIP);
mainChangeToStage(g_MissionConfig.stagenum);
#if VERSION >= VERSION_NTSC_1_0
viBlack(true);
#endif
}
return 0;
}
char *soloMenuTitleStageOverview(struct menudialogdef *dialogdef)
{
if (dialogdef != g_Menus[g_MpPlayerNum].curdialog->definition) {
return langGet(L_OPTIONS_273); // "Overview"
}
sprintf(g_StringPointer, "%s: %s\n",
langGet(g_StageNames[g_MissionConfig.stageindex].name3),
langGet(L_OPTIONS_273));
return g_StringPointer;
}
s32 menudialog00103608(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
switch (operation) {
case MENUOP_OPEN:
g_Menus[g_MpPlayerNum].unk840.unk010 = 0;
setupLoadBriefing(g_MissionConfig.stagenum,
g_Menus[g_MpPlayerNum].unk840.unk004,
g_Menus[g_MpPlayerNum].unk840.unk008, &g_Briefing);
break;
case MENUOP_CLOSE:
langClearBank(g_Briefing.langbank);
break;
}
return 0;
}
struct menuitem g_AcceptMissionMenuItems[] = {
{
MENUITEMTYPE_OBJECTIVES,
1,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_274, // "Accept"
0,
menuhandlerAcceptMission,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_275, // "Decline"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_AcceptMissionMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&soloMenuTitleStageOverview,
g_AcceptMissionMenuItems,
menudialog00103608,
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_DISABLEITEMSCROLL,
&g_PreAndPostMissionBriefingMenuDialog,
};
f32 func0f1036ac(u8 value, s32 prop)
{
if (prop == PDMODEPROP_REACTION) {
return value / 255.0f;
}
return mpHandicapToDamageScale(value);
}
s32 menuhandlerPdModeSetting(s32 operation, struct menuitem *item, union handlerdata *data)
{
u8 *property;
f32 fvalue;
switch (item->param) {
case PDMODEPROP_REACTION: property = &g_MissionConfig.pdmodereaction; break;
case PDMODEPROP_HEALTH: property = &g_MissionConfig.pdmodehealth; break;
case PDMODEPROP_DAMAGE: property = &g_MissionConfig.pdmodedamage; break;
case PDMODEPROP_ACCURACY: property = &g_MissionConfig.pdmodeaccuracy; break;
default: return 0;
}
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = *property;
break;
case MENUOP_SET:
*property = (u16)data->slider.value;
break;
case MENUOP_GETSLIDERLABEL:
fvalue = func0f1036ac(*property, item->param);
if (item->param == 0) {
fvalue = fvalue * 4 + 1.0f;
}
sprintf(data->slider.label, "%s%s%.00f%%\n", "", "", fvalue * 100.0f);
break;
}
return 0;
}
s32 menuhandlerAcceptPdModeSettings(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_MissionConfig.pdmode = true;
g_MissionConfig.pdmodehealthf = func0f1036ac(g_MissionConfig.pdmodehealth, PDMODEPROP_HEALTH);
g_MissionConfig.pdmodedamagef = func0f1036ac(g_MissionConfig.pdmodedamage, PDMODEPROP_DAMAGE);
g_MissionConfig.pdmodeaccuracyf = func0f1036ac(g_MissionConfig.pdmodeaccuracy, PDMODEPROP_ACCURACY);
g_MissionConfig.difficulty = DIFF_PA;
lvSetDifficulty(g_MissionConfig.difficulty);
menuPopDialog();
menuPopDialog();
menuPushDialog(&g_AcceptMissionMenuDialog);
}
return 0;
}
struct menuitem g_PdModeSettingsMenuItems[] = {
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING,
L_MPWEAPONS_222, // "Choose Settings:"
0,
NULL,
},
{
MENUITEMTYPE_SLIDER,
1,
MENUITEMFLAG_SLIDER_ALTSIZE,
L_MPWEAPONS_224, // "Enemy Health:"
0x000000ff,
menuhandlerPdModeSetting,
},
{
MENUITEMTYPE_SLIDER,
2,
MENUITEMFLAG_SLIDER_ALTSIZE,
L_MPWEAPONS_225, // "Enemy Damage:"
0x000000ff,
menuhandlerPdModeSetting,
},
{
MENUITEMTYPE_SLIDER,
3,
MENUITEMFLAG_SLIDER_ALTSIZE,
L_MPWEAPONS_226, // "Enemy Accuracy:"
0x000000ff,
menuhandlerPdModeSetting,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0x000000b4,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_MPWEAPONS_227, // "OK"
0,
menuhandlerAcceptPdModeSettings,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_MPWEAPONS_228, // "Cancel"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_PdModeSettingsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPWEAPONS_221, // "Perfect Dark"
g_PdModeSettingsMenuItems,
NULL,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
/**
* This function assumes that the stage that's given to it is already unlocked.
* It is checking the difficulty for that stage only.
*
* This function does not test for PD mode being unlocked.
*/
bool isStageDifficultyUnlocked(s32 stageindex, s32 difficulty)
{
s32 s;
s32 d;
// Handle special missions
if (stageindex > SOLOSTAGEINDEX_SKEDARRUINS) {
#if VERSION >= VERSION_NTSC_1_0
// If the player has completed Skedar Ruins on the same difficulty as
// the one that's being queried, then they have access to this
// difficulty for all special missions. Agent is gifted here, so if the
// bonus mission is available at all then Agent is also available.
s32 maxcompleteddiff = DIFF_A;
for (d = DIFF_A; d <= DIFF_PA; d++) {
if (g_GameFile.besttimes[SOLOSTAGEINDEX_SKEDARRUINS][d] != 0) {
maxcompleteddiff = d;
}
}
if (difficulty <= maxcompleteddiff) {
return true;
}
#endif
// Otherwise, grant them the difficulty if they've completed all prior
// difficulties on this stage.
for (d = DIFF_A; d < difficulty; d++) {
if (g_GameFile.besttimes[stageindex][d] == 0) {
return false;
}
}
return true;
}
// Handle normal missions
if (stageindex <= SOLOSTAGEINDEX_SKEDARRUINS && difficulty <= DIFF_PA) {
// Defection is always unlocked on all difficulties
if (g_StageNames[stageindex].stagenum == STAGE_DEFECTION) {
return true;
}
// If the stage has already been completed on the queried difficulty
// or higher then the queried difficulty is made available.
// For coop and anti, coop completions are also checked.
for (d = difficulty; d <= DIFF_PA; d++) {
if (g_GameFile.besttimes[stageindex][d] != 0) {
return true;
}
if ((g_MissionConfig.iscoop || g_MissionConfig.isanti)
&& (g_GameFile.coopcompletions[d] & (1 << stageindex))) {
return true;
}
}
if (stageindex > 0) {
if (g_StageNames[stageindex].stagenum != STAGE_SKEDARRUINS) {
// For normal stages prior to Skedar Ruins, test if the
// prior stage is complete on the same difficulty or higher.
for (d = difficulty; d <= DIFF_PA; d++) {
if (g_GameFile.besttimes[stageindex - 1][d] != 0) {
return true;
}
if ((g_MissionConfig.iscoop || g_MissionConfig.isanti)
&& (g_GameFile.coopcompletions[d] & (1 << (stageindex - 1)))) {
return true;
}
}
} else {
// For Skedar Ruins, check that all prior stages are complete
// on the queried difficulty or higher.
for (s = 0; s < stageindex; s++) {
for (d = difficulty; d <= DIFF_PA; d++) {
if (g_GameFile.besttimes[s][d] != 0) {
break;
}
if ((g_MissionConfig.iscoop || g_MissionConfig.isanti)
&& (g_GameFile.coopcompletions[d] & (1 << s)) != 0) {
break;
}
}
if (d > DIFF_PA) {
// A stage was not complete
break;
}
}
if (s >= stageindex) {
return true;
}
}
}
// If all normal stages are complete on any difficulty, and we're
// querying SA or higher, grant the difficulty if the stage is complete
// on the prior difficulty or higher.
if (difficulty >= DIFF_SA) {
if (g_StageNames[stageindex].stagenum != STAGE_SKEDARRUINS) {
// Check if all normal stages are complete on any difficulty
for (s = 0; s <= SOLOSTAGEINDEX_SKEDARRUINS; s++) {
for (d = DIFF_A; d <= DIFF_PA; d++) {
if (g_GameFile.besttimes[s][d] != 0) {
break;
}
if ((g_MissionConfig.iscoop || g_MissionConfig.isanti)
&& (g_GameFile.coopcompletions[d] & (1 << s)) != 0) {
break;
}
}
if (d > DIFF_PA) {
// A stage was not complete
break;
}
}
if (s >= SOLOSTAGEINDEX_MBR) {
for (d = difficulty - 1; d <= DIFF_PA; d++) {
if (g_GameFile.besttimes[stageindex][d] != 0) {
return true;
}
if ((g_MissionConfig.iscoop || g_MissionConfig.isanti)
&& (g_GameFile.coopcompletions[d] & (1 << stageindex)) != 0) {
return true;
}
}
}
}
}
}
return false;
}
s32 menuhandlerSoloDifficulty(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_CHECKPREFOCUSED:
#if VERSION >= VERSION_NTSC_1_0
if (isStageDifficultyUnlocked(g_MissionConfig.stageindex, item->param)) {
if (item->param3 == 0) {
return true;
}
if (item->param <= (u32)g_GameFile.autodifficulty) {
return true;
}
}
#else
if (item->param3 == 0) {
return true;
}
if (item->param <= (u32)g_GameFile.autodifficulty) {
return true;
}
#endif
break;
case MENUOP_SET:
g_MissionConfig.pdmode = false;
g_MissionConfig.difficulty = item->param;
lvSetDifficulty(g_MissionConfig.difficulty);
menuPopDialog();
menuPushDialog(&g_AcceptMissionMenuDialog);
break;
case MENUOP_CHECKDISABLED:
if (!isStageDifficultyUnlocked(g_MissionConfig.stageindex, item->param)) {
return true;
}
}
return 0;
}
s32 menuhandlerPdMode(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_SET:
menuPushDialog(&g_PdModeSettingsMenuDialog);
break;
case MENUOP_CHECKHIDDEN:
if (g_GameFile.besttimes[SOLOSTAGEINDEX_SKEDARRUINS][DIFF_PA] == 0) {
return true;
}
}
return 0;
}
char *soloMenuTextBestTime(struct menuitem *item)
{
u16 time = g_GameFile.besttimes[g_MissionConfig.stageindex][item->param];
s32 hours = time / 3600;
if (time == 0) {
return "--:--\n";
}
if (time >= 0xfff) { // 1 hour, 8 minutes, 15 seconds
return "==:==\n";
}
if (hours == 0) {
s32 mins = time / 60;
sprintf(g_StringPointer, "%dm:%02ds", mins % 60, time % 60);
} else {
s32 mins = time / 60;
sprintf(g_StringPointer, "%dh:%02dm:%02ds", hours, mins % 60, time % 60);
}
return g_StringPointer;
}
struct menuitem g_SoloMissionDifficultyMenuItems[] = {
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING,
L_OPTIONS_249, // "Difficulty"
L_OPTIONS_250, // "Best Time"
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_251, // "Agent"
(u32)&soloMenuTextBestTime,
menuhandlerSoloDifficulty,
},
{
MENUITEMTYPE_SELECTABLE,
1,
0,
L_OPTIONS_252, // "Special Agent"
(u32)&soloMenuTextBestTime,
menuhandlerSoloDifficulty,
},
{
MENUITEMTYPE_SELECTABLE,
2,
0,
L_OPTIONS_253, // "Perfect Agent"
(u32)&soloMenuTextBestTime,
menuhandlerSoloDifficulty,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_MPWEAPONS_221, // "Perfect Dark"
0,
menuhandlerPdMode,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_254, // "Cancel"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_SoloMissionDifficultyMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_248, // "Select Difficulty"
g_SoloMissionDifficultyMenuItems,
NULL,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
s32 menuhandlerBuddyOptionsContinue(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
menuPopDialog();
menuPushDialog(&g_AcceptMissionMenuDialog);
}
if (operation == MENUOP_CHECKPREFOCUSED) {
return true;
}
return 0;
}
#if VERSION >= VERSION_NTSC_1_0
s32 getMaxAiBuddies(void)
{
u32 stack;
s32 extra = 0;
s32 max = 1 - g_MissionConfig.difficulty;
s32 d;
for (d = 0; d != 3; d++) {
if ((g_GameFile.coopcompletions[d] | 0xfffe0000) == 0xffffffff) {
extra = d + 1;
}
}
max += extra;
if (max > 4) {
max = 4;
}
if (max < 1) {
max = 1;
}
#if VERSION == VERSION_PAL_BETA
if (debugIsAllBuddiesEnabled()) {
max = 4;
}
#endif
return max;
}
#endif
s32 menudialogCoopAntiOptions(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
#if VERSION >= VERSION_NTSC_1_0
if (operation == MENUOP_OPEN) {
s32 max = getMaxAiBuddies();
if (g_Vars.numaibuddies > max) {
g_Vars.numaibuddies = max;
}
}
#endif
if (operation == MENUOP_TICK) {
if (g_Menus[g_MpPlayerNum].curdialog && g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef) {
struct menuinputs *inputs = data->dialog2.inputs;
if (inputs->start) {
menuhandlerBuddyOptionsContinue(MENUOP_SET, NULL, NULL);
}
inputs->start = false;
}
}
return 0;
}
s32 menuhandlerCoopRadar(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return g_Vars.coopradaron;
case MENUOP_SET:
g_Vars.coopradaron = data->checkbox.value ? 1 : 0;
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerCoopFriendlyFire(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return g_Vars.coopfriendlyfire;
case MENUOP_SET:
g_Vars.coopfriendlyfire = data->checkbox.value ? 1 : 0;
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerCoopBuddy(s32 operation, struct menuitem *item, union handlerdata *data)
{
const u16 labels[] = {
L_OPTIONS_261, // "Human"
L_OPTIONS_262, // "1 Simulant"
L_OPTIONS_263, // "2 Simulants"
L_OPTIONS_264, // "3 Simulants"
L_OPTIONS_265, // "4 Simulants"
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
#if VERSION >= VERSION_NTSC_1_0
{
s32 maxaibuddies = getMaxAiBuddies();
s32 human = 0;
if (joyGetConnectedControllers() & 2) {
human = 1;
}
data->dropdown.value = human + maxaibuddies;
}
#else
{
s32 extrabuddies = 0;
s32 i;
s32 maxbuddies = 1 - g_MissionConfig.difficulty;
s32 human = 0;
if (joyGetConnectedControllers() & 2) {
human = 1;
}
for (i = 0; i < 3; i++) {
if ((g_GameFile.coopcompletions[i] | 0xfffe0000) == 0xffffffff) {
extrabuddies = i + 1;
}
}
maxbuddies += extrabuddies;
if (maxbuddies > 4) {
maxbuddies = 4;
}
if (maxbuddies < 1) {
maxbuddies = 1;
}
if (debugIsAllBuddiesEnabled()) {
maxbuddies = 4;
}
data->dropdown.value = human + maxbuddies;
}
#endif
break;
case MENUOP_GETOPTIONTEXT:
{
s32 extra = 1;
if (joyGetConnectedControllers() & 2) {
extra = 0;
}
return (s32)langGet(labels[data->dropdown.value + extra]);
}
case MENUOP_SET:
{
s32 extra = 1;
if (joyGetConnectedControllers() & 2) {
extra = 0;
}
g_Vars.numaibuddies = data->dropdown.value + extra;
g_Vars.modifiedfiles |= MODFILE_GAME;
}
break;
case MENUOP_GETSELECTEDINDEX:
{
s32 extra = 1;
if (joyGetConnectedControllers() & 2) {
extra = 0;
}
if (extra == 1 && g_Vars.numaibuddies == 0) {
g_Vars.numaibuddies = 1;
}
data->dropdown.value = g_Vars.numaibuddies - extra;
}
break;
}
return 0;
}
struct menuitem g_CoopOptionsMenuItems[] = {
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_256, // "Radar On"
0,
menuhandlerCoopRadar,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_257, // "Friendly Fire"
0,
menuhandlerCoopFriendlyFire,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_258, // "Perfect Buddy"
0,
menuhandlerCoopBuddy,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
}, // ""
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_259, // "Continue"
0,
menuhandlerBuddyOptionsContinue,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_260, // "Cancel"
0,
NULL,
},
{ MENUITEMTYPE_END }, // ""
};
struct menudialogdef g_CoopOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_255, // "Co-Operative Options"
g_CoopOptionsMenuItems,
menudialogCoopAntiOptions,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
s32 menuhandlerAntiRadar(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return g_Vars.antiradaron;
case MENUOP_SET:
g_Vars.antiradaron = data->checkbox.value ? 1 : 0;
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerAntiPlayer(s32 operation, struct menuitem *item, union handlerdata *data)
{
const u16 labels[] = {L_OPTIONS_271, L_OPTIONS_272};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->dropdown.value = 2;
break;
case MENUOP_GETOPTIONTEXT:
return (s32) langGet(labels[data->dropdown.value]);
case MENUOP_SET:
g_Vars.pendingantiplayernum = data->dropdown.value;
g_Vars.modifiedfiles |= MODFILE_GAME;
break;
case MENUOP_GETSELECTEDINDEX:
data->dropdown.value = g_Vars.pendingantiplayernum;
break;
}
return 0;
}
struct menuitem g_AntiOptionsMenuItems[] = {
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_267, // "Radar On"
0,
menuhandlerAntiRadar,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_268, // "Counter-Operative"
0,
menuhandlerAntiPlayer,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_269, // "Continue"
0,
menuhandlerBuddyOptionsContinue,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_270, // "Cancel"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_AntiOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_266, // "Counter-Operative Options"
g_AntiOptionsMenuItems,
menudialogCoopAntiOptions,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
s32 menuhandlerCoopDifficulty(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_SET:
g_MissionConfig.pdmode = false;
g_MissionConfig.difficulty = item->param;
lvSetDifficulty(g_MissionConfig.difficulty);
menuPopDialog();
menuPushDialog(&g_CoopOptionsMenuDialog);
break;
case MENUOP_CHECKDISABLED:
if (!isStageDifficultyUnlocked(g_MissionConfig.stageindex, item->param)) {
return true;
}
}
return 0;
}
struct menuitem g_CoopMissionDifficultyMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_251, // "Agent"
0,
menuhandlerCoopDifficulty,
},
{
MENUITEMTYPE_SELECTABLE,
1,
0,
L_OPTIONS_252, // "Special Agent"
0,
menuhandlerCoopDifficulty,
},
{
MENUITEMTYPE_SELECTABLE,
2,
0,
L_OPTIONS_253, // "Perfect Agent"
0,
menuhandlerCoopDifficulty,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_254, // "Cancel"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CoopMissionDifficultyMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_248, // "Select Difficulty"
g_CoopMissionDifficultyMenuItems,
NULL,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
s32 menuhandlerAntiDifficulty(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_SET:
g_MissionConfig.pdmode = false;
g_MissionConfig.difficulty = item->param;
lvSetDifficulty(g_MissionConfig.difficulty);
menuPopDialog();
menuPushDialog(&g_AntiOptionsMenuDialog);
}
return 0;
}
struct menuitem g_AntiMissionDifficultyMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_251, // "Agent"
0,
menuhandlerAntiDifficulty,
},
{
MENUITEMTYPE_SELECTABLE,
1,
0,
L_OPTIONS_252, // "Special Agent"
0,
menuhandlerAntiDifficulty,
},
{
MENUITEMTYPE_SELECTABLE,
2,
0,
L_OPTIONS_253, // "Perfect Agent"
0,
menuhandlerAntiDifficulty,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_254, // "Cancel"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_AntiMissionDifficultyMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_248, // "Select Difficulty"
g_AntiMissionDifficultyMenuItems,
NULL,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
struct stageoverviewentry g_StageNames[NUM_SOLOSTAGES] = {
// stage, unk04,
{ STAGE_DEFECTION, 0x0c, L_OPTIONS_133, L_OPTIONS_134, L_MPWEAPONS_124 },
{ STAGE_INVESTIGATION, 0x0d, L_OPTIONS_135, L_OPTIONS_136, L_MPWEAPONS_172 },
{ STAGE_EXTRACTION, 0x0e, L_OPTIONS_137, L_OPTIONS_138, L_MPWEAPONS_125 },
{ STAGE_VILLA, 0x0f, L_OPTIONS_139, L_OPTIONS_140, L_OPTIONS_139 },
{ STAGE_CHICAGO, 0x10, L_OPTIONS_141, L_OPTIONS_142, L_OPTIONS_141 },
{ STAGE_G5BUILDING, 0x11, L_OPTIONS_143, L_OPTIONS_144, L_OPTIONS_143 },
{ STAGE_INFILTRATION, 0x12, L_OPTIONS_145, L_OPTIONS_146, L_MPWEAPONS_126 },
{ STAGE_RESCUE, 0x13, L_OPTIONS_147, L_OPTIONS_148, L_MPWEAPONS_127 },
{ STAGE_ESCAPE, 0x14, L_OPTIONS_149, L_OPTIONS_150, L_MPWEAPONS_128 },
{ STAGE_AIRBASE, 0x15, L_OPTIONS_151, L_OPTIONS_152, L_OPTIONS_151 },
{ STAGE_AIRFORCEONE, 0x16, L_OPTIONS_153, L_OPTIONS_154, L_OPTIONS_153 },
{ STAGE_CRASHSITE, 0x17, L_OPTIONS_155, L_OPTIONS_156, L_OPTIONS_155 },
{ STAGE_PELAGIC, 0x18, L_OPTIONS_157, L_OPTIONS_158, L_OPTIONS_157 },
{ STAGE_DEEPSEA, 0x19, L_OPTIONS_159, L_OPTIONS_160, L_OPTIONS_159 },
{ STAGE_DEFENSE, 0x1a, L_OPTIONS_161, L_OPTIONS_162, L_OPTIONS_161 },
{ STAGE_ATTACKSHIP, 0x1b, L_OPTIONS_163, L_OPTIONS_164, L_OPTIONS_163 },
{ STAGE_SKEDARRUINS, 0x1c, L_OPTIONS_165, L_OPTIONS_166, L_OPTIONS_165 },
{ STAGE_MBR, 0x1c, L_OPTIONS_167, L_OPTIONS_003, L_OPTIONS_167 },
{ STAGE_MAIANSOS, 0x1c, L_OPTIONS_168, L_OPTIONS_003, L_OPTIONS_168 },
{ STAGE_WAR, 0x1c, L_OPTIONS_170, L_OPTIONS_003, L_OPTIONS_170 },
{ STAGE_DUEL, 0x1c, L_OPTIONS_171, L_OPTIONS_003, L_OPTIONS_171 },
};
s32 getNumUnlockedSpecialStages(void)
{
s32 next = 0;
s32 offsetforduel = 1;
s32 i;
for (i = 0; i < 3; i++) {
if (g_GameFile.besttimes[SOLOSTAGEINDEX_SKEDARRUINS][i]) {
next = i + 1;
}
}
if (g_MissionConfig.iscoop || g_MissionConfig.isanti) {
offsetforduel = 0;
} else {
for (i = 0; i < (VERSION >= VERSION_NTSC_1_0 ? 32 : 33); i++) {
if (ciGetFiringRangeScore(i) <= 0) {
offsetforduel = 0;
}
}
}
return next + offsetforduel;
}
s32 func0f104720(s32 value)
{
s32 next = 0;
s32 d;
for (d = 0; d != 3; d++) {
if (g_GameFile.besttimes[SOLOSTAGEINDEX_SKEDARRUINS][d]) {
next = d + 1;
}
}
if (next > value) {
return 17 + value;
}
return 20;
}
s32 menuhandlerMissionList(s32 operation, struct menuitem *item, union handlerdata *data)
{
struct optiongroup groups[] = {
{ 0, L_OPTIONS_123 }, // "Mission 1"
{ 3, L_OPTIONS_124 }, // "Mission 2"
{ 4, L_OPTIONS_125 }, // "Mission 3"
{ 6, L_OPTIONS_126 }, // "Mission 4"
{ 9, L_OPTIONS_127 }, // "Mission 5"
{ 12, L_OPTIONS_128 }, // "Mission 6"
{ 14, L_OPTIONS_129 }, // "Mission 7"
{ 15, L_OPTIONS_130 }, // "Mission 8"
{ 16, L_OPTIONS_131 }, // "Mission 9"
{ 99, L_OPTIONS_132 }, // "Special Assignments"
};
s32 i;
s32 j;
bool stageiscomplete;
union handlerdata sp18c;
u32 sp188;
union handlerdata sp178;
union handlerdata sp168;
s32 sp164;
s32 sp160;
union handlerdata sp150;
s32 k;
union handlerdata sp13c;
Gfx *gdl;
struct menuitemrenderdata *renderdata;
s32 x;
s32 y;
s32 stack;
s32 incompleteindex;
char text[50];
s32 stageindex;
union handlerdata spdc;
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = 0;
for (i = 0; i < 17; i++) {
stageiscomplete = false;
for (j = 0; j < 3; j++) {
if (g_GameFile.besttimes[i][j] != 0) {
stageiscomplete = true;
}
if ((g_MissionConfig.iscoop || g_MissionConfig.isanti)
&& (g_GameFile.coopcompletions[j] & (1 << i))) {
stageiscomplete = true;
}
}
data->list.value++;
if (!stageiscomplete) {
break;
}
}
data->list.value += getNumUnlockedSpecialStages();
break;
case MENUOP_GETOPTIONTEXT:
if (data->list.unk04u32 == 0) {
menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &sp18c);
data->list.unk04u32 = sp18c.list.value - getNumUnlockedSpecialStages();
}
if (data->list.value < data->list.unk04u32) {
// Regular stage such as "dataDyne Central - Defection"
// Return the name before the dash, such as "dataDyne Central"
return (s32) langGet(g_StageNames[data->list.value].name1);
}
// Special stages have no dash and suffix, so just return the name
return (s32) langGet(g_StageNames[func0f104720(data->list.value - data->list.unk04u32)].name1);
case MENUOP_SET:
sp188 = data->list.value;
menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &sp178);
sp178.list.value -= getNumUnlockedSpecialStages();
if (data->list.value >= sp178.list.value) {
sp188 = func0f104720(data->list.value - sp178.list.value);
}
g_Vars.mplayerisrunning = false;
g_Vars.normmplayerisrunning = false;
g_MissionConfig.stagenum = g_StageNames[sp188].stagenum;
g_MissionConfig.stageindex = sp188;
if (g_MissionConfig.iscoop) {
menuPushDialog(&g_CoopMissionDifficultyMenuDialog);
} else if (g_MissionConfig.isanti) {
menuPushDialog(&g_AntiMissionDifficultyMenuDialog);
} else {
menuPushDialog(&g_SoloMissionDifficultyMenuDialog);
}
break;
case MENUOP_GETSELECTEDINDEX:
data->list.value = 0xfffff;
break;
case MENUOP_25:
if (data->list.unk04 == 0 && !g_MissionConfig.iscoop && !g_MissionConfig.isanti) {
data->list.value = g_GameFile.autostageindex;
menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &sp168);
sp168.list.value -= getNumUnlockedSpecialStages();
if (data->list.value >= sp168.list.value) {
sp164 = getNumUnlockedSpecialStages();
data->list.value = sp168.list.value - 1;
for (sp160 = 0; sp160 < sp164; sp160++) {
if (func0f104720(sp160) == g_GameFile.autostageindex) {
data->list.value = sp168.list.values32 + sp160;
}
}
}
}
break;
case MENUOP_GETOPTGROUPCOUNT:
menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &sp150);
sp150.list.value -= getNumUnlockedSpecialStages();
data->list.unk0c = 0;
for (i = 0; i < ARRAYCOUNT(groups); i++) {
if (groups[i].offset < sp150.list.value) {
data->list.unk0c++;
}
}
data->list.value = data->list.unk0c + 1;
break;
case MENUOP_GETOPTGROUPTEXT:
if (data->list.unk0c == data->list.value) {
return (s32) langGet(groups[9].name); // "Special Assignments"
}
return (s32) langGet(groups[data->list.value].name);
case MENUOP_GETGROUPSTARTINDEX:
if (data->list.unk0c == data->list.value) {
menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &sp13c);
data->list.groupstartindex = sp13c.list.value - getNumUnlockedSpecialStages();
} else {
data->list.groupstartindex = groups[data->list.value].offset;
}
break;
case MENUOP_RENDER:
gdl = data->type19.gdl;
renderdata = data->type19.renderdata2;
incompleteindex = 0;
stageindex = data->type19.unk04u32;
if (data->type19.unk0c == 0) {
menuhandlerMissionList(MENUOP_GETOPTIONCOUNT, item, &spdc);
data->type19.unk0c = spdc.list.value - getNumUnlockedSpecialStages();
}
if (data->type19.unk04u32 >= data->type19.unk0c) {
stageindex = func0f104720(data->type19.unk04u32 - data->type19.unk0c);
}
// Draw the thumbnail
gDPPipeSync(gdl++);
gDPSetTexturePersp(gdl++, G_TP_NONE);
gDPSetAlphaCompare(gdl++, G_AC_NONE);
gDPSetTextureLOD(gdl++, G_TL_TILE);
gDPSetTextureConvert(gdl++, G_TC_FILT);
#if VERSION >= VERSION_NTSC_1_0
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 2, 0, 2, true, NULL);
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
gDPSetCombineLERP(gdl++, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0);
gDPSetTextureFilter(gdl++, G_TF_POINT);
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 255 / 256));
#else
texSelect(&gdl, g_TexGeneralConfigs + 13 + stageindex, 1, 0, 2, true, NULL);
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
gDPSetCombineMode(gdl++, G_CC_DECALRGBA, G_CC_DECALRGBA);
gDPSetTextureFilter(gdl++, G_TF_POINT);
#endif
gSPTextureRectangle(gdl++,
((renderdata->x + 4) << 2) * g_ScaleX, (renderdata->y + 3) << 2,
((renderdata->x + 60) << 2) * g_ScaleX, (renderdata->y + 39) << 2,
G_TX_RENDERTILE, 0, 0x0480, 1024 / g_ScaleX, -1024);
if (g_MissionConfig.isanti) {
// No stars
} else if (g_MissionConfig.iscoop) {
texSelect(&gdl, &g_TexGeneralConfigs[36], 2, 0, 2, true, NULL);
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
gDPSetTextureFilter(gdl++, G_TF_POINT);
for (k = 0; k < 3; k++) {
s32 relx = 63 + k * 17;
if ((g_GameFile.coopcompletions[k] & (1 << stageindex)) == 0) {
#if VERSION >= VERSION_NTSC_1_0
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 63 / 256));
#else
gDPSetEnvColorViaWord(gdl++, 0xffffff3f);
#endif
gDPSetCombineLERP(gdl++,
TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0);
} else {
#if VERSION >= VERSION_NTSC_1_0
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 207 / 256));
#else
gDPSetEnvColorViaWord(gdl++, 0xffffffcf);
#endif
gDPSetCombineMode(gdl++, G_CC_DECALRGBA, G_CC_DECALRGBA);
}
gSPTextureRectangle(gdl++,
((renderdata->x + relx) << 2) * g_ScaleX, (renderdata->y + 25) << 2,
((renderdata->x + relx + 14) << 2) * g_ScaleX, (renderdata->y + 39) << 2,
G_TX_RENDERTILE, 0x0010, 0x01c0, 1024 / g_ScaleX, -1024);
}
} else {
texSelect(&gdl, &g_TexGeneralConfigs[34], 2, 0, 2, true, NULL);
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
gDPSetTextureFilter(gdl++, G_TF_POINT);
gDPSetCombineMode(gdl++, G_CC_DECALRGBA, G_CC_DECALRGBA);
#if VERSION >= VERSION_NTSC_1_0
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 175 / 256));
#else
gDPSetEnvColorViaWord(gdl++, 0xffffffaf);
#endif
for (k = 0; k < 3; k++) {
if (g_GameFile.besttimes[stageindex][k] != 0) {
incompleteindex = k + 1;
}
}
for (k = 0; k < 3; k++) {
s32 relx = 63 + k * 17;
if (k == incompleteindex) {
// Set transparency
#if VERSION >= VERSION_NTSC_1_0
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 63 / 256));
#else
gDPSetEnvColorViaWord(gdl++, 0xffffff3f);
#endif
gDPSetCombineLERP(gdl++,
TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0,
TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0);
}
gSPTextureRectangle(gdl++,
((renderdata->x + relx) << 2) * g_ScaleX, (renderdata->y + 25) << 2,
((renderdata->x + relx + 14) << 2) * g_ScaleX, (renderdata->y + 39) << 2,
G_TX_RENDERTILE, 0x0010, 0x01c0, 1024 / g_ScaleX, -1024);
}
}
x = renderdata->x + 62;
y = renderdata->y + 3;
gdl = text0f153628(gdl);
// Draw first part of name
strcpy(text, langGet(g_StageNames[stageindex].name1));
strcat(text, "\n");
gdl = textRenderProjected(gdl, &x, &y, text, g_CharsHandelGothicMd, g_FontHandelGothicMd,
renderdata->colour, viGetWidth(), viGetHeight(), 0, 0);
// Draw last part of name
strcpy(text, langGet(g_StageNames[stageindex].name2));
gdl = textRenderProjected(gdl, &x, &y, text, g_CharsHandelGothicSm, g_FontHandelGothicSm,
renderdata->colour, viGetWidth(), viGetHeight(), 0, 0);
gdl = text0f153780(gdl);
return (s32) gdl;
case MENUOP_GETOPTIONHEIGHT:
data->list.value = 42;
break;
}
return 0;
}
s32 menudialog0010559c(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
switch (operation) {
case MENUOP_OPEN:
break;
case MENUOP_CLOSE:
if ((g_Vars.modifiedfiles & MODFILE_GAME) && g_Vars.coopplayernum < 0 && g_Vars.antiplayernum < 0) {
if (filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_001, 0) == 0) {
data->dialog1.preventclose = true;
}
g_Vars.modifiedfiles &= ~MODFILE_GAME;
}
if (g_Vars.modifiedfiles & MODFILE_BOSS) {
bossfileSave();
g_Vars.modifiedfiles &= ~MODFILE_BOSS;
}
break;
}
return 0;
}
struct menuitem g_MissionBriefingMenuItems[] = {
{
MENUITEMTYPE_SCROLLABLE,
DESCRIPTION_BRIEFING,
0,
0,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menuitem g_2PMissionBreifingVMenuItems[] = {
{
MENUITEMTYPE_SCROLLABLE,
DESCRIPTION_BRIEFING,
0,
0x00000078,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_SoloMissionBriefingMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_247, // "Briefing"
g_MissionBriefingMenuItems,
NULL,
MENUDIALOGFLAG_DISABLEITEMSCROLL,
NULL,
};
struct menudialogdef g_2PMissionBriefingHMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_247, // "Briefing"
g_MissionBriefingMenuItems,
NULL,
MENUDIALOGFLAG_DISABLEITEMSCROLL,
NULL,
};
struct menudialogdef g_2PMissionBriefingVMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_247, // "Briefing"
g_2PMissionBreifingVMenuItems,
NULL,
MENUDIALOGFLAG_DISABLEITEMSCROLL,
NULL,
};
char *func0f105664(struct menuitem *item)
{
union handlerdata data;
menuhandler001024dc(MENUOP_GETSELECTEDINDEX, item, &data);
return (char *)menuhandler001024dc(MENUOP_GETOPTIONTEXT, item, &data);
}
char *func0f1056a0(struct menuitem *item)
{
union handlerdata data;
menuhandler001024fc(MENUOP_GETSELECTEDINDEX, item, &data);
return (char *)menuhandler001024fc(MENUOP_GETOPTIONTEXT, item, &data);
}
s32 menuhandlerLangFilter(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return g_Vars.langfilteron;
case MENUOP_SET:
g_Vars.langfilteron = data->checkbox.value;
g_Vars.modifiedfiles |= MODFILE_GAME;
}
return 0;
}
s32 menuhandlerControlStyle(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
if (PLAYERCOUNT() >= 2) {
menuPushDialog(&g_2PMissionControlStyleMenuDialog);
} else {
menuPushDialog(&g_SoloMissionControlStyleMenuDialog);
}
}
return 0;
}
s32 menuhandler001057ec(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
filemgrSaveOrLoad(&g_GameFileGuid, FILEOP_SAVE_GAME_002, 0);
}
return 0;
}
s32 menuhandlerChangeAgent(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
func0f0f820c(NULL, -7);
}
return 0;
}
struct menuitem g_2PMissionControlStyleMenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
MENUITEMFLAG_LIST_AUTOWIDTH,
0x00000050,
0,
menuhandler001024dc,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_2PMissionControlStyleMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_236, // "Control"
g_2PMissionControlStyleMenuItems,
NULL,
MENUDIALOGFLAG_0400,
NULL,
};
struct menuitem g_SoloMissionControlStyleMenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
MENUITEMFLAG_LIST_AUTOWIDTH,
0x00000028,
#if VERSION == VERSION_JPN_FINAL
0xbe,
#elif PAL
0x9c,
#else
0x96,
#endif
menuhandler001024dc,
},
{
MENUITEMTYPE_CONTROLLER,
0,
MENUITEMFLAG_NEWCOLUMN,
0,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_SoloMissionControlStyleMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_236, // "Control"
g_SoloMissionControlStyleMenuItems,
NULL,
MENUDIALOGFLAG_0400,
NULL,
};
struct menuitem g_CiControlStyleMenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
MENUITEMFLAG_LIST_AUTOWIDTH,
0x00000028,
#if VERSION == VERSION_JPN_FINAL
0xbe,
#elif PAL
0x9c,
#else
0x96,
#endif
menuhandler001024dc,
},
{
MENUITEMTYPE_CONTROLLER,
0,
MENUITEMFLAG_NEWCOLUMN,
0,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiControlStyleMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_236, // "Control"
g_CiControlStyleMenuItems,
NULL,
MENUDIALOGFLAG_0400,
NULL,
};
struct menuitem g_CiControlStylePlayer2MenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
MENUITEMFLAG_LIST_AUTOWIDTH,
0x00000028,
#if VERSION == VERSION_JPN_FINAL
0xbe,
#elif PAL
0x9c,
#else
0x96,
#endif
menuhandler001024fc,
},
{
MENUITEMTYPE_CONTROLLER,
0,
MENUITEMFLAG_NEWCOLUMN,
0,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiControlStylePlayer2MenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_236, // "Control"
g_CiControlStylePlayer2MenuItems,
NULL,
MENUDIALOGFLAG_0400,
NULL,
};
struct menuitem g_AudioOptionsMenuItems[] = {
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_SLIDER_FAST | MENUITEMFLAG_SLIDER_HIDEVALUE,
L_OPTIONS_228, // "Sound"
#if VERSION >= VERSION_NTSC_1_0
L_MPMENU_000, // ""
#else
0x7fff,
#endif
menuhandlerSfxVolume,
},
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_SLIDER_FAST | MENUITEMFLAG_SLIDER_HIDEVALUE,
L_OPTIONS_229, // "Music"
#if VERSION >= VERSION_NTSC_1_0
L_MPMENU_000, // ""
#else
0x7fff,
#endif
menuhandlerMusicVolume,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_230, // "Sound Mode"
0,
menuhandlerSoundMode,
},
#if VERSION != VERSION_JPN_FINAL
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_218, // "Language Filter"
0,
menuhandlerLangFilter,
},
#endif
{
MENUITEMTYPE_SEPARATOR,
0,
0,
(VERSION >= VERSION_PAL_FINAL ? 200 : 0),
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_231, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_AudioOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_227, // "Audio Options"
g_AudioOptionsMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_2PMissionAudioOptionsVMenuItems[] = {
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_SLIDER_FAST | MENUITEMFLAG_SLIDER_HIDEVALUE | MENUITEMFLAG_SLIDER_ALTSIZE,
L_OPTIONS_228, // "Sound"
#if VERSION >= VERSION_NTSC_1_0
L_MPMENU_000, // ""
#else
0x7fff,
#endif
menuhandlerSfxVolume,
},
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_SLIDER_FAST | MENUITEMFLAG_SLIDER_HIDEVALUE | MENUITEMFLAG_SLIDER_ALTSIZE,
L_OPTIONS_229, // "Music"
#if VERSION >= VERSION_NTSC_1_0
L_MPMENU_000, // ""
#else
0x7fff,
#endif
menuhandlerMusicVolume,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_MPWEAPONS_153, // "Mode"
0,
menuhandlerSoundMode,
},
#if VERSION != VERSION_JPN_FINAL
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_218, // "Language Filter"
0,
menuhandlerLangFilter,
},
#endif
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_231, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_2PMissionAudioOptionsVMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_227, // "Audio Options"
g_2PMissionAudioOptionsVMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_VideoOptionsMenuItems[] = {
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_215, // "Screen Size"
0,
menuhandlerScreenSize,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_216, // "Ratio"
0,
menuhandlerScreenRatio,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_217, // "Hi-Res"
0,
menuhandlerHiRes,
},
#if PAL
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_MPWEAPONS_269, // ""
0,
menuhandlerLanguage,
},
#endif
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_218, // "2-Player Screen Split"
0,
menuhandlerScreenSplit,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_170, // "Alternative Title Screen"
0,
menuhandlerAlternativeTitle,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0x000000c8,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_219, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menuitem g_2PMissionVideoOptionsMenuItems[] = {
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_216, // "Ratio"
0,
menuhandlerScreenRatio,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_217, // "Hi-Res"
0,
menuhandlerHiRes,
},
#if PAL
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_MPWEAPONS_269, // ""
0,
menuhandlerLanguage,
},
#endif
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_MPWEAPONS_154, // "Split"
0,
menuhandlerScreenSplit,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_219, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_VideoOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_214, // "Video Options"
g_VideoOptionsMenuItems,
NULL,
0,
NULL,
};
struct menudialogdef g_2PMissionVideoOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_214, // "Video Options"
g_2PMissionVideoOptionsMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MissionDisplayOptionsMenuItems[] = {
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_205, // "Sight on Screen"
0x00000004,
menuhandlerSightOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_206, // "Always Show Target"
0x00000004,
menuhandlerAlwaysShowTarget,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_207, // "Show Zoom Range"
0x00000004,
menuhandlerShowZoomRange,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_208, // "Ammo on Screen"
0x00000004,
menuhandlerAmmoOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_209, // "Show Gun Function"
0x00000004,
menuhandlerShowGunFunction,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_210, // "Paintball"
0x00000004,
menuhandlerPaintball,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_169, // "In-Game Subtitles"
0x00000004,
menuhandlerInGameSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_168, // "Cutscene Subtitles"
0x00000004,
menuhandlerCutsceneSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_212, // "Show Mission Time"
0x00000004,
menuhandlerShowMissionTime,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_213, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_MissionDisplayOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_203, // "Display Options"
g_MissionDisplayOptionsMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_2PMissionDisplayOptionsVMenuItems[] = {
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_145, // "Sight on Screen"
0x00000004,
menuhandlerSightOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_146, // "Target"
0x00000004,
menuhandlerAlwaysShowTarget,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_147, // "Zoom Range"
0x00000004,
menuhandlerShowZoomRange,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_148, // "Show Ammo"
0x00000004,
menuhandlerAmmoOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_149, // "Gun Function"
0x00000004,
menuhandlerShowGunFunction,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_150, // "Paintball"
0x00000004,
menuhandlerPaintball,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
#if VERSION >= VERSION_PAL_FINAL
L_MPWEAPONS_279, // "In-Game Subtitles"
#else
L_MPWEAPONS_169, // "In-Game Subtitles"
#endif
0x00000004,
menuhandlerInGameSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
#if VERSION >= VERSION_PAL_FINAL
L_MPWEAPONS_278, // "Cutscene Subtitles"
#else
L_MPWEAPONS_168, // "Cutscene Subtitles"
#endif
0x00000004,
menuhandlerCutsceneSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_152, // "Mission Time"
0x00000004,
menuhandlerShowMissionTime,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_213, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_2PMissionDisplayOptionsVMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_203, // "Display Options"
g_2PMissionDisplayOptionsVMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_CiDisplayMenuItems[] = {
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_205, // "Sight on Screen"
0x00000004,
menuhandlerSightOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_206, // "Always Show Target"
0x00000004,
menuhandlerAlwaysShowTarget,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_207, // "Show Zoom Range"
0x00000004,
menuhandlerShowZoomRange,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_208, // "Ammo on Screen"
0x00000004,
menuhandlerAmmoOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_209, // "Show Gun Function"
0x00000004,
menuhandlerShowGunFunction,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_210, // "Paintball"
0x00000004,
menuhandlerPaintball,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_169, // "In-Game Subtitles"
0x00000004,
menuhandlerInGameSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_168, // "Cutscene Subtitles"
0x00000004,
menuhandlerCutsceneSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_212, // "Show Mission Time"
0x00000004,
menuhandlerShowMissionTime,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_213, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiDisplayPlayer2MenuDialog;
struct menudialogdef g_CiDisplayMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_203, // "Display Options"
g_CiDisplayMenuItems,
NULL,
0,
&g_CiDisplayPlayer2MenuDialog,
};
struct menuitem g_CiDisplayPlayer2MenuItems[] = {
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_205, // "Sight on Screen"
0x00000005,
menuhandlerSightOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_206, // "Always Show Target"
0x00000005,
menuhandlerAlwaysShowTarget,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_207, // "Show Zoom Range"
0x00000005,
menuhandlerShowZoomRange,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_208, // "Ammo on Screen"
0x00000005,
menuhandlerAmmoOnScreen,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_209, // "Show Gun Function"
0x00000005,
menuhandlerShowGunFunction,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_210, // "Paintball"
0x00000005,
menuhandlerPaintball,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_169, // "In-Game Subtitles"
0x00000005,
menuhandlerInGameSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_168, // "Cutscene Subtitles"
0x00000005,
menuhandlerCutsceneSubtitles,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_212, // "Show Mission Time"
0x00000005,
menuhandlerShowMissionTime,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_213, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiDisplayPlayer2MenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_204, // "Display Player 2"
g_CiDisplayPlayer2MenuItems,
NULL,
0,
NULL,
};
struct menuitem g_MissionControlOptionsMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_194, // "Control Style"
(u32)&func0f105664,
menuhandlerControlStyle,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_195, // "Reverse Pitch"
0x00000004,
menuhandlerReversePitch,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_196, // "Look Ahead"
0x00000004,
menuhandlerLookAhead,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_197, // "Head Roll"
0x00000004,
menuhandlerHeadRoll,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_198, // "Auto-Aim"
0x00000004,
menuhandlerAutoAim,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_199, // "Aim Control"
0x00000004,
menuhandlerAimControl,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_200, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_MissionControlOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_192, // "Control Options"
g_MissionControlOptionsMenuItems,
NULL,
0,
NULL,
};
#if VERSION >= VERSION_PAL_FINAL
struct menuitem g_CiControlOptionsMenuItems2[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_MPWEAPONS_270, // ""
(u32)&func0f105664,
menuhandlerControlStyle,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_271, // ""
0x00000004,
menuhandlerReversePitch,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_272, // ""
0x00000004,
menuhandlerLookAhead,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_273, // ""
0x00000004,
menuhandlerHeadRoll,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_MPWEAPONS_274, // ""
0x00000004,
menuhandlerAutoAim,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_MPWEAPONS_275, // ""
0x00000004,
menuhandlerAimControl,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_200, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiControlOptionsMenuDialog2 = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_192, // "Control Options"
g_CiControlOptionsMenuItems2,
NULL,
0,
NULL,
};
#endif
struct menuitem g_CiControlOptionsMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_194, // "Control Style"
(u32)&func0f105664,
(void *)&g_CiControlStyleMenuDialog,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_195, // "Reverse Pitch"
0x00000004,
menuhandlerReversePitch,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_196, // "Look Ahead"
0x00000004,
menuhandlerLookAhead,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_197, // "Head Roll"
0x00000004,
menuhandlerHeadRoll,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_198, // "Auto-Aim"
0x00000004,
menuhandlerAutoAim,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_199, // "Aim Control"
0x00000004,
menuhandlerAimControl,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_200, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiControlOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_192, // "Control Options"
g_CiControlOptionsMenuItems,
NULL,
0,
&g_CiControlPlayer2MenuDialog,
};
struct menuitem g_CiControlPlayer2MenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_194, // "Control Style"
(u32)&func0f1056a0,
(void *)&g_CiControlStylePlayer2MenuDialog,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_195, // "Reverse Pitch"
0x00000005,
menuhandlerReversePitch,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_196, // "Look Ahead"
0x00000005,
menuhandlerLookAhead,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_197, // "Head Roll"
0x00000005,
menuhandlerHeadRoll,
},
{
MENUITEMTYPE_CHECKBOX,
0,
0,
L_OPTIONS_198, // "Auto-Aim"
0x00000005,
menuhandlerAutoAim,
},
{
MENUITEMTYPE_DROPDOWN,
0,
0,
L_OPTIONS_199, // "Aim Control"
0x00000005,
menuhandlerAimControl,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_200, // "Back"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiControlPlayer2MenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_193, // "Control Player 2"
g_CiControlPlayer2MenuItems,
NULL,
0,
NULL,
};
struct menuitem g_ChangeAgentMenuItems[] = {
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING,
L_OPTIONS_189, // "Do you want to load another agent?"
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_190, // "Yes"
0,
menuhandlerChangeAgent,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_191, // "No"
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_ChangeAgentMenuDialog = {
MENUDIALOGTYPE_DANGER,
L_OPTIONS_188, // "Warning"
g_ChangeAgentMenuItems,
NULL,
0,
NULL,
};
struct menuitem g_SoloMissionOptionsMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
L_OPTIONS_181, // "Audio"
0,
(void *)&g_AudioOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
L_OPTIONS_182, // "Video"
0,
(void *)&g_VideoOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
L_OPTIONS_183, // "Control"
0,
(void *)&g_MissionControlOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
L_OPTIONS_184, // "Display"
0,
(void *)&g_MissionDisplayOptionsMenuDialog,
},
{ MENUITEMTYPE_END },
};
struct menuitem g_2PMissionOptionsHMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_181, // "Audio"
0,
(void *)&g_AudioOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_182, // "Video"
0,
(void *)&g_2PMissionVideoOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_183, // "Control"
0,
(void *)&g_MissionControlOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_184, // "Display"
0,
(void *)&g_MissionDisplayOptionsMenuDialog,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0x00000064,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
(u32)&menutextPauseOrUnpause,
0,
menuhandlerMpPause,
},
{ MENUITEMTYPE_END },
};
struct menuitem g_2PMissionOptionsVMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_181, // "Audio"
0,
(void *)&g_2PMissionAudioOptionsVMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_182, // "Video"
0,
(void *)&g_2PMissionVideoOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_183, // "Control"
0,
#if VERSION >= VERSION_PAL_FINAL
(void *)&g_CiControlOptionsMenuDialog2,
#else
(void *)&g_MissionControlOptionsMenuDialog,
#endif
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_184, // "Display"
0,
(void *)&g_2PMissionDisplayOptionsVMenuDialog,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0x00000064,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
(u32)&menutextPauseOrUnpause,
0,
menuhandlerMpPause,
},
{ MENUITEMTYPE_END },
};
struct menuitem g_CiOptionsMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
0x000056b5,
0x00000001,
(void *)&g_AudioOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
0x000056b6,
0x00000002,
(void *)&g_VideoOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
0x000056b7,
0x00000003,
(void *)&g_CiControlOptionsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
0x000056b8,
0x00000004,
(void *)&g_CiDisplayMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
0x000056b9,
0x00000005,
(void *)&g_CheatsMenuDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
0x00005679,
0x00000006,
(void *)&g_CinemaMenuDialog,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_SoloMissionOptionsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_180, // "Options"
g_SoloMissionOptionsMenuItems,
menudialog0010559c,
0,
&g_SoloMissionBriefingMenuDialog,
};
struct menudialogdef g_CiOptionsViaPcMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_180, // "Options"
g_CiOptionsMenuItems,
menudialog0010559c,
0,
NULL,
};
struct menudialogdef g_CiOptionsViaPauseMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_180, // "Options"
g_CiOptionsMenuItems,
menudialog0010559c,
0,
NULL,
};
struct menudialogdef g_2PMissionOptionsHMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_180, // "Options"
g_2PMissionOptionsHMenuItems,
menudialog0010559c,
0,
&g_2PMissionBriefingHMenuDialog,
};
struct menudialogdef g_2PMissionOptionsVMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_180, // "Options"
g_2PMissionOptionsVMenuItems,
menudialog0010559c,
0,
&g_2PMissionBriefingVMenuDialog,
};
u8 var80072d88 = 255;
char *invMenuTextPrimaryFunction(struct menuitem *item)
{
struct weaponfunc *primaryfunc = weaponGetFunctionById(g_InventoryWeapon, 0);
struct weaponfunc *secondaryfunc = weaponGetFunctionById(g_InventoryWeapon, 1);
if (primaryfunc && secondaryfunc) {
return langGet(primaryfunc->name);
}
return langGet(L_OPTIONS_003); // "\n"
}
char *invMenuTextSecondaryFunction(struct menuitem *item)
{
struct weaponfunc *primaryfunc = weaponGetFunctionById(g_InventoryWeapon, 0);
struct weaponfunc *secondaryfunc = weaponGetFunctionById(g_InventoryWeapon, 1);
if (secondaryfunc) {
return langGet(secondaryfunc->name);
}
if (primaryfunc) {
return langGet(primaryfunc->name);
}
return langGet(L_OPTIONS_003); // "\n"
}
void func0f105948(s32 weaponnum)
{
f32 gunconfig[][5] = {
{ 23.299999237061f, -16.799999237061f, -153.39999389648f, 6.4140100479126f, 0.48769000172615f },
{ 22.299999237061f, -13.5f, -216.60000610352f, 6.443009853363f, 0.34057000279427f },
{ 19.5f, -31.89999961853f, -154.89999389648f, 6.3730101585388f, 0.41813001036644f },
{ -2.5f, 14.300000190735f, 16.200000762939f, 6.4340100288391f, 0.34057000279427f },
{ -2.4000000953674f, 21.0f, -98.900001525879f, 5.7630100250244f, 0.32354000210762f },
{ -4.0999999046326f, -30.5f, -29.39999961853f, 6.3770098686218f, 0.37735998630524f },
{ 0.69999998807907f, 13.89999961853f, 23.10000038147f, 6.4730100631714f, 0.37735998630524f },
{ 0.69999998807907f, 13.89999961853f, 23.10000038147f, 6.4730100631714f, 0.37735998630524f },
{ -5.1999998092651f, 36.5f, -370.39999389648f, 6.5040102005005f, 0.37735998630524f },
{ -5.5f, -79.5f, -661.0f, 6.3190097808838f, 0.214640006423f },
{ -2.9000000953674f, -57.200000762939f, -110.09999847412f, 6.3170099258423f, 0.27739998698235f },
{ -6.1999998092651f, -33.900001525879f, 101.40000152588f, 6.3320097923279f, 0.27739998698235f },
{ -23.5f, -4.0999999046326f, -209.60000610352f, 6.1110100746155f, 0.214640006423f },
{ -3.9000000953674f, -63.099998474121f, -872.0f, 6.3720102310181f, 0.214640006423f },
{ 218.19999694824f, -56.299999237061f, -210.89999389648f, 6.3500099182129f, 0.22594000399113f },
{ 0.5f, -84.599998474121f, -377.20001220703f, 6.1880102157593f, 0.18402999639511f },
{ -1.6000000238419f, -68.400001525879f, -874.5f, 6.3720102310181f, 0.214640006423f },
{ -3.7999999523163f, -145.5f, 52.5f, 6.3170099258423f, 0.32354000210762f },
{ 117.19999694824f, -13.800000190735f, -177.60000610352f, 6.1730098724365f, 0.23782999813557f },
{ -69.699996948242f, -135.10000610352f, -146.10000610352f, 6.18901014328f, 0.16608999669552f },
{ 0.20000000298023f, -176.60000610352f, -276.29998779297f, 6.2660098075867f, 0.16608999669552f },
{ -0.80000001192093f, -21.200000762939f, 3.5999999046326f, 6.3030200004578f, 0.26352998614311f },
{ -94.800003051758f, -13.300000190735f, -307.70001220703f, 6.2500200271606f, 0.25034999847412f },
{ -2.2000000476837f, -45.599998474121f, -131.89999389648f, 6.3580098152161f, 0.19371999800205f },
{ -148.69999694824f, 26.10000038147f, -251.69999694824f, 42.328819274902f, 0.32354000210762f },
{ -4.0f, -3.0f, -157.60000610352f, 43.489791870117f, 0.48769000172615f },
{ -4.8000001907349f, 14.0f, -89.0f, 43.927791595459f, 0.5688099861145f },
{ -0.40000000596046f, -29.89999961853f, -8.8000001907349f, 43.981800079346f, 0.73510998487473f },
{ -23.700000762939f, -35.799999237061f, -237.89999389648f, 43.153789520264f, 0.6983500123024f },
{ -23.700000762939f, -35.799999237061f, -237.89999389648f, 43.153789520264f, 0.6983500123024f },
{ 63.700000762939f, 53.0f, -171.60000610352f, 43.153789520264f, 0.9025200009346f },
{ 63.700000762939f, 53.0f, -171.60000610352f, 43.153789520264f, 0.9025200009346f },
{ 63.700000762939f, 53.0f, -171.60000610352f, 43.153789520264f, 0.9025200009346f },
{ 0.20000000298023f, -1.5f, 1.0f, 43.288791656494f, 6.6717000007629f },
{ -68.400001525879f, 14.699999809265f, -92.5f, 44.255790710449f, 0.59876000881195f },
{ -2.9000000953674f, 33.5f, 61.400001525879f, 44.254791259766f, 0.48769000172615f },
{ -1.5f, 41.599998474121f, -49.900001525879f, 44.198810577393f, 0.41813001036644f },
{ -2.5999999046326f, -0.20000000298023f, -237.10000610352f, 44.029800415039f, 0.21465000510216f },
{ -1.2999999523163f, 13.39999961853f, -43.700000762939f, 44.2587890625f, 0.34057000279427f },
{ 0.10000000149012f, 32.099998474121f, -161.69999694824f, 44.111789703369f, 0.39722999930382f },
{ -1.0f, -31.89999961853f, -300.0f, 44.034790039062f, 0.18402999639511f },
{ 0.30000001192093f, -44.900001525879f, 45.099998474121f, 44.078788757324f, 0.27739998698235f },
{ -4.8000001907349f, 14.0f, -89.0f, 43.927791595459f, 0.5688099861145f },
{ -0.69999998807907f, -1.7000000476837f, -9.3000001907349f, 44.255809783936f, 3.6051800251007f },
{ 16.0f, -56.099998474121f, 7.5f, 44.468811035156f, 0.77380001544952f },
{ -0.69999998807907f, -1.7000000476837f, -9.3000001907349f, 44.255809783936f, 3.6051800251007f },
{ -1.3999999761581f, -41.5f, -120.30000305176f, 44.265800476074f, 0.3585000038147f },
{ 1.6000000238419f, 3.5f, -0.20000000298023f, 44.75479888916f, 0.48769000172615f },
{ -5.0999999046326f, -9.5f, 2.0f, 43.715789794922f, 0.44014000892639f },
{ -1.3999999761581f, -41.5f, -120.30000305176f, 44.265800476074f, 0.3585000038147f },
{ -1.3999999761581f, -41.5f, -120.30000305176f, 44.265800476074f, 0.3585000038147f },
{ -50.099998474121f, 20.0f, -139.5f, 43.179790496826f, 0.69836002588272f },
{ 60.700000762939f, 27.60000038147f, -146.30000305176f, 43.265789031982f, 0.81453001499176f },
{ 0.60000002384186f, -1.6000000238419f, -0.5f, 38.538738250732f, 0.90254002809525f },
{ 0.60000002384186f, -1.6000000238419f, -0.5f, 38.538738250732f, 0.90254002809525f },
{ 0.40000000596046f, 0.5f, -0.60000002384186f, 38.68675994873f, 0.66345000267029f },
{ -22.700000762939f, -1.7999999523163f, -12.300000190735f, 5.8997898101807f, 0.25036001205444f },
{ 4.1999998092651f, -13.199999809265f, 4.0999999046326f, 43.32479095459f, 0.21465000510216f },
{ -8.5f, -8.1000003814697f, 10.199999809265f, 42.137790679932f, 0.16608999669552f },
{ -8.5f, -8.1000003814697f, 10.199999809265f, 43.388809204102f, 0.54038000106812f },
{ -8.5f, -8.1000003814697f, 10.199999809265f, 43.388809204102f, 0.54038000106812f },
{ -8.5f, -8.1000003814697f, 10.199999809265f, 43.388809204102f, 0.54038000106812f },
{ -0.89999997615814f, -14.10000038147f, 1.7000000476837f, 0.0f, 1.0f },
{ -0.89999997615814f, -14.10000038147f, 1.7000000476837f, 0.0f, 1.0f },
{ -2.7000000476837f, 9.1000003814697f, -2.9000000953674f, 43.391819000244f, 0.54038000106812f },
{ -6.0999999046326f, -0.69999998807907f, -2.0f, 43.391819000244f, 0.69836002588272f },
{ 0.40000000596046f, -7.0f, 1.7999999523163f, 43.211811065674f, 1.6702300310135f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
{ 281.89999389648f, 0.89999997615814f, 8.3999996185303f, 5.0027899742126f, 0.18402999639511f },
{ -1.8999999761581f, 0.89999997615814f, -55.0f, 43.142780303955f, 0.14989000558853f },
#if VERSION >= VERSION_NTSC_1_0
{ -3.7999999523163f, 6.1999998092651f, 1.0f, 5.6747899055481f, 0.29199999570847f },
#endif
{ -3.7999999523163f, 6.1999998092651f, 1.0f, 5.8997898101807f, 2.0506100654602f },
};
s32 useindex;
struct weapon *weapon;
u32 stack;
s32 wantindex;
useindex = weaponnum - 2;
wantindex = useindex;
if ((u32)wantindex < 0 || wantindex >= ARRAYCOUNT(gunconfig)) {
useindex = 0;
}
if (weaponHasFlag(weaponnum, WEAPONFLAG_HIDEMENUMODEL) == false && (u32)wantindex >= 0 && useindex >= 0) {
weapon = weaponFindById(weaponnum);
g_Menus[g_MpPlayerNum].unk840.unk000 = 8;
g_Menus[g_MpPlayerNum].unk840.unk010 = 0;
g_Menus[g_MpPlayerNum].unk840.unk00c = weaponGetModelNum(weaponnum);
g_Menus[g_MpPlayerNum].unk840.unk538 = 0;
g_Menus[g_MpPlayerNum].unk840.unk510 = 0;
g_Menus[g_MpPlayerNum].unk840.unk53c = 0;
g_Menus[g_MpPlayerNum].unk840.unk514 = 0;
g_Menus[g_MpPlayerNum].unk840.unk540 = 0;
g_Menus[g_MpPlayerNum].unk840.unk518 = 0;
g_Menus[g_MpPlayerNum].unk840.unk550 = 0;
g_Menus[g_MpPlayerNum].unk840.unk528 = 0;
g_Menus[g_MpPlayerNum].unk840.unk52c = gunconfig[useindex][0];
g_Menus[g_MpPlayerNum].unk840.unk530 = gunconfig[useindex][1];
g_Menus[g_MpPlayerNum].unk840.unk534 = gunconfig[useindex][2];
g_Menus[g_MpPlayerNum].unk840.unk548 = gunconfig[useindex][3];
g_Menus[g_MpPlayerNum].unk840.unk520 = gunconfig[useindex][3]; // @bug? Wrong index?
func0f0f372c(&g_Menus[g_MpPlayerNum].unk840, 0, 0, 0, 0, 0, 0, gunconfig[useindex][4], 1);
g_Menus[g_MpPlayerNum].unk840.unk51c = 0;
g_Menus[g_MpPlayerNum].unk840.partvisibility = weapon->partvisibility;
g_Menus[g_MpPlayerNum].unk840.unk554 = -1;
// These indexes correspond to WEAPON_DISGUISE40 and WEAPON_DISGUISE41
if (wantindex == 0x3e || wantindex == 0x3f) {
if ((u32)wantindex == 0x3e) {
g_Menus[g_MpPlayerNum].unk840.unk00c = 0x0a01ffff;
} else {
g_Menus[g_MpPlayerNum].unk840.unk00c = 0x0400ffff;
}
g_Menus[g_MpPlayerNum].unk840.partvisibility = NULL;
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.unk578 = TICKS(60);
g_Menus[g_MpPlayerNum].unk840.unk574 = TICKS(120);
g_Menus[g_MpPlayerNum].unk840.unk54c = -0.2f;
g_Menus[g_MpPlayerNum].unk840.unk524 = -0.2f;
}
} else {
g_Menus[g_MpPlayerNum].unk840.bodymodeldef = NULL;
g_Menus[g_MpPlayerNum].unk840.unk010 = 0;
g_Menus[g_MpPlayerNum].unk840.unk00c = 0;
}
}
s32 inventoryMenuDialog(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_TICK) {
if (g_Menus[g_MpPlayerNum].curdialog && g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef) {
g_Menus[g_MpPlayerNum].unk840.unk574 -= g_Vars.diffframe60;
g_Menus[g_MpPlayerNum].unk840.unk54c = 18.849555969238f * g_20SecIntervalFrac;
g_Menus[g_MpPlayerNum].unk840.unk524 = 18.849555969238f * g_20SecIntervalFrac;
g_Menus[g_MpPlayerNum].unk840.unk528 = 0;
g_Menus[g_MpPlayerNum].unk840.unk550 = 0;
if (var80072d88 != g_InventoryWeapon) {
func0f105948(g_InventoryWeapon);
var80072d88 = g_InventoryWeapon;
}
if (g_InventoryWeapon == WEAPON_DISGUISE40 || g_InventoryWeapon == WEAPON_DISGUISE41) {
g_Menus[g_MpPlayerNum].unk840.unk05c = ANIM_006A;
g_Menus[g_MpPlayerNum].unk840.unk578 = TICKS(60);
g_Menus[g_MpPlayerNum].unk840.unk574 = TICKS(120);
}
} else {
var80072d88 = 255;
}
}
return 0;
}
/**
* Return name, but if there is no manufacturer then return a blank value
* because the name is being shown in the manufacturer slot.
*/
char *invMenuTextWeaponName(struct menuitem *item)
{
struct weapon *weapon = weaponFindById(g_InventoryWeapon);
if (weapon) {
if (weapon->manufacturer == L_GUN_000) { // "\n"
return langGet(L_OPTIONS_003); // "\n"
}
return langGet(weapon->name);
}
return langGet(L_OPTIONS_003); // "\n"
}
/**
* Return manufacturer, with fallback to weapon name if manufacturer is blank.
*/
char *invMenuTextWeaponManufacturer(struct menuitem *item)
{
struct weapon *weapon = weaponFindById(g_InventoryWeapon);
u32 textid = L_GUN_000; // "\n"
if (weapon) {
textid = weapon->manufacturer;
}
if (textid != L_GUN_000) {
return langGet(textid);
}
weapon = weaponFindById(g_InventoryWeapon);
if (weapon) {
return langGet(weapon->name);
}
return langGet(L_OPTIONS_003); // "\n"
}
char *invMenuTextWeaponDescription(struct menuitem *item)
{
struct weapon *weapon = weaponFindById(g_InventoryWeapon);
if (weapon) {
if (g_InventoryWeapon == WEAPON_EYESPY && g_Vars.currentplayer->eyespy) {
if (g_Vars.currentplayer->eyespy->mode == EYESPYMODE_DRUGSPY) {
return langGet(L_GUN_237); // Drugspy description
}
if (g_Vars.currentplayer->eyespy->mode == EYESPYMODE_BOMBSPY) {
return langGet(L_GUN_236); // Bombspy description
}
}
if (g_InventoryWeapon == WEAPON_NECKLACE
&& g_Vars.stagenum == (VERSION >= VERSION_NTSC_1_0 ? STAGE_ATTACKSHIP : STAGE_SKEDARRUINS)
&& lvGetDifficulty() >= DIFF_PA) {
#if VERSION >= VERSION_NTSC_1_0
// Phrases included here to assist people searching the code for them:
// CDV780322
// I8MOZYM8NDI85
u8 username[] = {
'C' + 9 * 1,
'D' + 9 * 2,
'V' + 9 * 3,
'7' + 9 * 4,
'8' + 9 * 5,
'0' + 9 * 6,
'3' + 9 * 7,
'2' + 9 * 8,
'2' + 9 * 9,
'\0' + 9 * 10,
};
u8 password[] = {
'I' + 4 * 1,
'8' + 4 * 2,
'M' + 4 * 3,
'O' + 4 * 4,
'Z' + 4 * 5,
'Y' + 4 * 6,
'M' + 4 * 7,
'8' + 4 * 8,
'N' + 4 * 9,
'D' + 4 * 10,
'I' + 4 * 11,
'8' + 4 * 12,
'5' + 4 * 13,
'\0' + 4 * 14,
};
s32 i;
for (i = 0; i < ARRAYCOUNT(username); i++) {
username[i] -= i * 9 + 9;
}
for (i = 0; i < ARRAYCOUNT(password); i++) {
password[i] -= i * 4 + 4;
}
// "Cassandra De Vries' replacement necklace. Username: %s Password: %s"
sprintf(g_StringPointer, langGet(L_GUN_239), &username, &password);
return g_StringPointer;
#else
// ntsc-beta stores the whole thing as a single plain text string
return langGet(L_GUN_239);
#endif
}
return langGet(weapon->description);
}
return langGet(L_OPTIONS_003); // "\n"
}
struct menuitem g_SoloMissionInventoryMenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
0,
0x0000006e,
(VERSION >= VERSION_JPN_FINAL ? 0x54 : 0x63),
menuhandlerInventoryList,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_NEWCOLUMN | MENUITEMFLAG_00000002 | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextWeaponManufacturer,
NULL,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LABEL_ALTCOLOUR | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextWeaponName,
NULL,
},
{
MENUITEMTYPE_MODEL,
0,
0,
0x0000008c,
(VERSION >= VERSION_JPN_FINAL ? 0x14 : 0x37),
NULL,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextPrimaryFunction,
NULL,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextSecondaryFunction,
NULL,
},
{
MENUITEMTYPE_MARQUEE,
0,
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
(u32)&invMenuTextWeaponDescription,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menuitem g_FrWeaponsAvailableMenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
0,
0x0000006e,
0x00000063,
menuhandlerFrInventoryList,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_NEWCOLUMN | MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextWeaponManufacturer,
NULL,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LABEL_ALTCOLOUR | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextWeaponName,
NULL,
},
{
MENUITEMTYPE_MODEL,
0,
0,
0x0000008c,
0x00000037,
NULL,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextPrimaryFunction,
NULL,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
L_OPTIONS_003, // ""
(u32)&invMenuTextSecondaryFunction,
NULL,
},
{
MENUITEMTYPE_MARQUEE,
0,
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
(u32)&invMenuTextWeaponDescription,
0,
NULL,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_SoloMissionInventoryMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_178, // "Inventory"
g_SoloMissionInventoryMenuItems,
inventoryMenuDialog,
#if VERSION >= VERSION_JPN_FINAL
MENUDIALOGFLAG_0002 | MENUDIALOGFLAG_DISABLERESIZE | MENUDIALOGFLAG_0400 | MENUDIALOGFLAG_1000,
#else
MENUDIALOGFLAG_0002 | MENUDIALOGFLAG_DISABLERESIZE | MENUDIALOGFLAG_0400,
#endif
&g_SoloMissionOptionsMenuDialog,
};
struct menudialogdef g_FrWeaponsAvailableMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_179, // "Weapons Available"
g_FrWeaponsAvailableMenuItems,
inventoryMenuDialog,
MENUDIALOGFLAG_0002 | MENUDIALOGFLAG_DISABLERESIZE | MENUDIALOGFLAG_0400,
NULL,
};
s32 menuhandlerFrInventoryList(s32 operation, struct menuitem *item, union handlerdata *data)
{
static u8 g_FrFocusedSlotIndex = 0;
switch (operation) {
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = 0;
break;
case MENUOP_GETOPTGROUPTEXT:
return 0;
case MENUOP_GETGROUPSTARTINDEX:
data->list.groupstartindex = 0;
break;
case MENUOP_GETOPTIONCOUNT:
data->list.value = frGetNumWeaponsAvailable();
break;
case MENUOP_GETOPTIONTEXT:
g_FrFocusedSlotIndex = data->list.value;
return (s32)bgunGetName(frGetWeaponBySlot(data->list.value));
case MENUOP_SET:
g_FrFocusedSlotIndex = data->list.value;
return 0;
case MENUOP_GETSELECTEDINDEX:
data->list.value = g_FrFocusedSlotIndex;
break;
case MENUOP_LISTITEMFOCUS:
g_InventoryWeapon = frGetWeaponBySlot(data->list.value);
g_Menus[g_MpPlayerNum].training.weaponnum = g_InventoryWeapon;
g_FrFocusedSlotIndex = data->list.value;
// These items are labels
func0f0f139c(&g_SoloMissionInventoryMenuItems[1], -1.0f); // manufacturer
func0f0f139c(&g_SoloMissionInventoryMenuItems[2], -1.0f); // weapon name
func0f0f139c(&g_SoloMissionInventoryMenuItems[4], -1.0f); // primary function
func0f0f139c(&g_SoloMissionInventoryMenuItems[5], -1.0f); // secondary function
break;
}
return 0;
}
s32 menuhandlerInventoryList(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = invGetCount();
break;
case MENUOP_GETOPTIONTEXT:
return (s32)invGetNameByIndex(data->list.value);
case MENUOP_SET:
{
s32 weaponnum = invGetWeaponNumByIndex(data->list.value);
bool equippable = true;
if (weaponnum != WEAPON_NONE) {
s32 state = currentPlayerGetDeviceState(weaponnum);
if (state != DEVICESTATE_UNEQUIPPED) {
equippable = false;
if (data->list.unk04 == 0) {
if (state == DEVICESTATE_INACTIVE) {
currentPlayerSetDeviceActive(weaponnum, true);
} else {
currentPlayerSetDeviceActive(weaponnum, false);
}
}
}
}
if (equippable) {
invSetCurrentIndex(data->list.value);
if (invHasDoubleWeaponIncAllGuns(weaponnum, weaponnum)) {
bgunEquipWeapon2(HAND_RIGHT, weaponnum);
bgunEquipWeapon2(HAND_LEFT, weaponnum);
} else {
bgunEquipWeapon2(HAND_RIGHT, weaponnum);
bgunEquipWeapon2(HAND_LEFT, WEAPON_NONE);
}
}
var800711f0 = data->list.value;
}
break;
case MENUOP_GETSELECTEDINDEX:
data->list.value = invGetCurrentIndex();
break;
case MENUOP_GETLISTITEMCHECKBOX:
{
s32 weaponnum = invGetWeaponNumByIndex(data->list.value);
if (weaponnum != WEAPON_NONE) {
s32 state = currentPlayerGetDeviceState(weaponnum);
if (state != DEVICESTATE_UNEQUIPPED) {
data->list.unk04 = state;
}
}
}
break;
case MENUOP_LISTITEMFOCUS:
g_InventoryWeapon = invGetWeaponNumByIndex(data->list.value);
g_Menus[g_MpPlayerNum].training.weaponnum = g_InventoryWeapon;
func0f0f139c(&g_SoloMissionInventoryMenuItems[1], -1);
func0f0f139c(&g_SoloMissionInventoryMenuItems[2], -1);
func0f0f139c(&g_SoloMissionInventoryMenuItems[4], -1);
func0f0f139c(&g_SoloMissionInventoryMenuItems[5], -1);
break;
}
return 0;
}
s32 menuhandlerAbortMission(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_Vars.currentplayer->aborted = true;
mainEndStage();
}
return 0;
}
s32 menudialogAbortMission(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_TICK) {
// empty
}
return 0;
}
struct menuitem g_MissionAbortMenuItems[] = {
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING,
L_OPTIONS_175, // "Do you want to abort the mission?"
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_176, // "Cancel"
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_177, // "Abort"
0,
menuhandlerAbortMission,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_MissionAbortMenuDialog = {
MENUDIALOGTYPE_DANGER,
L_OPTIONS_174, // "Warning"
g_MissionAbortMenuItems,
menudialogAbortMission,
0,
NULL,
};
struct menuitem g_2PMissionAbortVMenuItems[] = {
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING,
L_MPWEAPONS_155, // "Do you want to abort the mission?"
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
L_OPTIONS_176, // "Cancel"
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
0,
L_OPTIONS_177, // "Abort"
0,
menuhandlerAbortMission,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_2PMissionAbortVMenuDialog = {
MENUDIALOGTYPE_DANGER,
L_OPTIONS_174, // "Warning"
g_2PMissionAbortVMenuItems,
menudialogAbortMission,
0,
NULL,
};
s32 soloMenuDialogPauseStatus(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_OPEN) {
struct briefingobj *briefing = g_BriefingObjs;
struct objective *objective;
s32 wanttype = BRIEFINGTYPE_TEXT_PA;
s32 i;
if (lvGetDifficulty() == DIFF_A) {
wanttype = BRIEFINGTYPE_TEXT_A;
}
if (lvGetDifficulty() == DIFF_SA) {
wanttype = BRIEFINGTYPE_TEXT_SA;
}
g_Briefing.briefingtextnum = L_MISC_042; // "No briefing for this mission"
while (briefing) {
if (briefing->type == BRIEFINGTYPE_TEXT_PA) {
g_Briefing.briefingtextnum = briefing->text;
}
if (briefing->type == wanttype) {
g_Briefing.briefingtextnum = briefing->text;
break;
}
briefing = briefing->next;
}
for (i = 0; i < objectiveGetCount(); i++) {
if (g_Objectives[i]) {
g_Briefing.objectivenames[i] = g_Objectives[i]->text;
g_Briefing.objectivedifficulties[i] = objectiveGetDifficultyBits(i);
}
}
}
return 0;
}
char *soloMenuTitlePauseStatus(struct menudialogdef *dialogdef)
{
if (dialogdef != g_Menus[g_MpPlayerNum].curdialog->definition) {
return langGet(L_OPTIONS_172); // "Status"
}
sprintf(g_StringPointer, "%s: %s\n",
langGet(g_StageNames[g_MissionConfig.stageindex].name3),
langGet(L_OPTIONS_172));
return g_StringPointer;
}
struct menuitem g_2PMissionPauseVMenuItems[] = {
{
MENUITEMTYPE_OBJECTIVES,
2,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_173, // "Abort!"
0,
(void *)&g_2PMissionAbortVMenuDialog,
},
{ MENUITEMTYPE_END },
};
struct menuitem g_MissionPauseMenuItems[] = {
{
MENUITEMTYPE_OBJECTIVES,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG,
L_OPTIONS_173, // "Abort!"
0,
(void *)&g_MissionAbortMenuDialog,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_SoloMissionPauseMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&soloMenuTitlePauseStatus,
g_MissionPauseMenuItems,
soloMenuDialogPauseStatus,
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
&g_SoloMissionInventoryMenuDialog,
};
struct menudialogdef g_2PMissionPauseHMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
(u32)&soloMenuTitlePauseStatus,
g_MissionPauseMenuItems,
soloMenuDialogPauseStatus,
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
&g_2PMissionInventoryHMenuDialog,
};
struct menudialogdef g_2PMissionPauseVMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_172, // "Status"
g_2PMissionPauseVMenuItems,
soloMenuDialogPauseStatus,
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
&g_2PMissionInventoryVMenuDialog,
};
struct cutscene g_Cutscenes[] = {
// stage ID, mission, scene, name
{ /* 0*/ STAGE_DEFECTION, 0, 0, L_OPTIONS_450 },
{ /* 1*/ STAGE_DEFECTION, 0, 1, L_OPTIONS_451 },
{ /* 2*/ STAGE_INVESTIGATION, 1, 0, L_OPTIONS_452 },
{ /* 3*/ STAGE_INVESTIGATION, 1, 1, L_OPTIONS_453 },
{ /* 4*/ STAGE_EXTRACTION, 2, 0, L_OPTIONS_454 },
{ /* 5*/ STAGE_EXTRACTION, 2, 1, L_OPTIONS_455 },
{ /* 6*/ STAGE_VILLA, 3, 0, L_OPTIONS_456 },
#if VERSION < VERSION_NTSC_1_0
{ /* 7*/ STAGE_VILLA, 3, 1, L_OPTIONS_457 },
#endif
{ /* 7*/ STAGE_VILLA, 3, 2, L_OPTIONS_458 },
{ /* 8*/ STAGE_CHICAGO, 4, 0, L_OPTIONS_459 },
{ /* 9*/ STAGE_CHICAGO, 4, 1, L_OPTIONS_460 },
{ /*10*/ STAGE_G5BUILDING, 5, 0, L_OPTIONS_461 },
{ /*11*/ STAGE_G5BUILDING, 5, 1, L_OPTIONS_462 },
{ /*12*/ STAGE_G5BUILDING, 5, 2, L_OPTIONS_463 },
{ /*13*/ STAGE_INFILTRATION, 6, 0, L_OPTIONS_464 },
{ /*14*/ STAGE_INFILTRATION, 6, 1, L_OPTIONS_465 },
{ /*15*/ STAGE_RESCUE, 7, 0, L_OPTIONS_466 },
{ /*16*/ STAGE_RESCUE, 7, 1, L_OPTIONS_467 },
{ /*17*/ STAGE_ESCAPE, 8, 0, L_OPTIONS_468 },
{ /*18*/ STAGE_ESCAPE, 8, 1, L_OPTIONS_469 },
{ /*19*/ STAGE_ESCAPE, 8, 2, L_OPTIONS_470 },
{ /*20*/ STAGE_AIRBASE, 9, 0, L_OPTIONS_471 },
{ /*21*/ STAGE_AIRBASE, 9, 1, L_OPTIONS_472 },
{ /*22*/ STAGE_AIRFORCEONE, 10, 0, L_OPTIONS_473 },
{ /*23*/ STAGE_AIRFORCEONE, 10, 1, L_OPTIONS_474 },
{ /*24*/ STAGE_AIRFORCEONE, 10, 2, L_OPTIONS_475 },
{ /*25*/ STAGE_CRASHSITE, 11, 0, L_OPTIONS_476 },
{ /*26*/ STAGE_CRASHSITE, 11, 1, L_OPTIONS_477 },
{ /*27*/ STAGE_PELAGIC, 12, 0, L_OPTIONS_478 },
{ /*28*/ STAGE_PELAGIC, 12, 1, L_OPTIONS_479 },
{ /*29*/ STAGE_DEEPSEA, 13, 0, L_OPTIONS_480 },
{ /*30*/ STAGE_DEEPSEA, 13, 1, L_OPTIONS_481 },
{ /*31*/ STAGE_DEEPSEA, 13, 2, L_OPTIONS_482 },
{ /*32*/ STAGE_DEFENSE, 14, 0, L_OPTIONS_483 },
{ /*33*/ STAGE_DEFENSE, 14, 1, L_OPTIONS_484 },
{ /*34*/ STAGE_ATTACKSHIP, 15, 0, L_OPTIONS_485 },
{ /*35*/ STAGE_ATTACKSHIP, 15, 1, L_OPTIONS_486 },
{ /*36*/ STAGE_SKEDARRUINS, 16, 0, L_OPTIONS_487 },
{ /*37*/ STAGE_SKEDARRUINS, 16, 1, L_OPTIONS_488 },
};
u32 g_CutsceneCountsByMission[] = {
/* 0*/ 1, // 0 missions completed => 1 cutscene available (Def intro)
/* 1*/ 3, // 1 mission completed => 3 cutscenes available (Def intro, outro, Invest intro)
/* 2*/ 5,
/* 3*/ 7,
#if VERSION >= VERSION_NTSC_1_0
// NTSC beta has an extra Villa cutscene
// so the numbers are bumped forward in that version
/* 4*/ 9,
/* 5*/ 11,
/* 6*/ 14,
/* 7*/ 16,
/* 8*/ 18,
/* 9*/ 21,
/*10*/ 23,
/*11*/ 26,
/*12*/ 28,
/*13*/ 30,
/*14*/ 33,
/*15*/ 35,
/*16*/ 37,
/*17*/ 38,
#else
/* 4*/ 10,
/* 5*/ 12,
/* 6*/ 15,
/* 7*/ 17,
/* 8*/ 19,
/* 9*/ 22,
/*10*/ 24,
/*11*/ 27,
/*12*/ 29,
/*13*/ 31,
/*14*/ 34,
/*15*/ 36,
/*16*/ 38,
/*17*/ 39,
#endif
};
s32 getNumCompletedMissions(void)
{
s32 s;
s32 d;
s32 count = 0;
for (s = 0; s != 17; s++) {
bool done = false;
for (d = 0; d != 3; d++) {
if (g_GameFile.besttimes[s][d] || (g_GameFile.coopcompletions[d] & (1 << s))) {
count++;
done = true;
break;
}
}
if (!done) {
break;
}
}
return count;
}
struct cutscenegroup {
u32 first_cutscene_index;
u16 name;
};
s32 menuhandlerCinema(s32 operation, struct menuitem *item, union handlerdata *data)
{
struct cutscenegroup groups[] = {
{ /* 0*/ 0, L_OPTIONS_436 }, // "Special"
{ /* 1*/ 1, L_OPTIONS_438 }, // "Mission 1 - dataDyne Central"
{ /* 2*/ 7, L_OPTIONS_439 },
#if VERSION >= VERSION_NTSC_1_0
{ /* 3*/ 9, L_OPTIONS_440 },
{ /* 4*/ 14, L_OPTIONS_441 },
{ /* 5*/ 21, L_OPTIONS_442 },
{ /* 6*/ 28, L_OPTIONS_443 },
{ /* 7*/ 33, L_OPTIONS_444 },
{ /* 8*/ 35, L_OPTIONS_445 },
{ /* 9*/ 37, L_OPTIONS_446 }, // "Mission 9 - Skedar Ruins"
{ /*10*/ 39, L_OPTIONS_447 }, // "Finale"
#else
{ /* 3*/ 10, L_OPTIONS_440 },
{ /* 4*/ 15, L_OPTIONS_441 },
{ /* 5*/ 22, L_OPTIONS_442 },
{ /* 6*/ 29, L_OPTIONS_443 },
{ /* 7*/ 34, L_OPTIONS_444 },
{ /* 8*/ 36, L_OPTIONS_445 },
{ /* 9*/ 38, L_OPTIONS_446 }, // "Mission 9 - Skedar Ruins"
{ /*10*/ 40, L_OPTIONS_447 }, // "Finale"
#endif
};
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
// Add one for Play All option
data->list.value = g_CutsceneCountsByMission[getNumCompletedMissions()] + 1;
break;
case MENUOP_GETOPTIONTEXT:
if (data->list.value == 0) {
sprintf(g_StringPointer, langGet(L_OPTIONS_448)); // "Play All"
return (s32) g_StringPointer;
}
return (s32) langGet(g_Cutscenes[data->list.value - 1].name);
case MENUOP_SET:
if (data->list.value == 0) {
// Play all
s32 index = getNumCompletedMissions();
g_Vars.autocutgroupcur = 0;
g_Vars.autocutgroupleft = g_CutsceneCountsByMission[index];
menuPopDialog();
menuStop();
} else {
// Play specific cutscene
g_Vars.autocutgroupcur = data->list.value - 1;
g_Vars.autocutgroupleft = 1;
menuPopDialog();
menuStop();
}
break;
case MENUOP_GETSELECTEDINDEX:
data->list.value = 0xfffff;
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = ARRAYCOUNT(groups);
break;
case MENUOP_GETOPTGROUPTEXT:
return (s32) langGet(groups[data->list.value].name);
case MENUOP_GETGROUPSTARTINDEX:
data->list.groupstartindex = groups[data->list.value].first_cutscene_index;
break;
}
return 0;
}
struct menuitem g_CinemaMenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
0,
0x000000eb,
0,
menuhandlerCinema,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CinemaMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_490, // "Cinema"
g_CinemaMenuItems,
NULL,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
struct menuitem g_SelectMissionMenuItems[] = {
{
MENUITEMTYPE_LIST,
0,
MENUITEMFLAG_LIST_CUSTOMRENDER,
0x000000eb,
0,
menuhandlerMissionList,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_SelectMissionMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_122, // "Mission Select"
g_SelectMissionMenuItems,
NULL,
MENUDIALOGFLAG_STARTSELECTS,
NULL,
};
s32 menuhandlerMainMenuSoloMissions(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_MissionConfig.iscoop = false;
g_MissionConfig.isanti = false;
menuPushDialog(&g_SelectMissionMenuDialog);
}
if (operation == MENUOP_CHECKPREFOCUSED) {
if (isStageDifficultyUnlocked(SOLOSTAGEINDEX_INVESTIGATION, DIFF_A)) {
return true;
}
}
return 0;
}
s32 menuhandlerMainMenuCombatSimulator(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_Vars.bondplayernum = 0;
g_Vars.coopplayernum = -1;
g_Vars.antiplayernum = -1;
challengeDetermineUnlockedFeatures();
g_Vars.mpsetupmenu = MPSETUPMENU_GENERAL;
func0f0f820c(&g_CombatSimulatorMenuDialog, MENUROOT_MPSETUP);
func0f0f8300();
}
return 0;
}
s32 menuhandlerMainMenuCooperative(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
g_MissionConfig.iscoop = true;
g_MissionConfig.isanti = false;
menuPushDialog(&g_SelectMissionMenuDialog);
}
return 0;
}
s32 menuhandlerMainMenuCounterOperative(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_CHECKDISABLED) {
if ((joyGetConnectedControllers() & 2) == 0) {
return true;
}
}
if (operation == MENUOP_SET) {
g_MissionConfig.iscoop = false;
g_MissionConfig.isanti = true;
menuPushDialog(&g_SelectMissionMenuDialog);
}
return 0;
}
s32 menudialogMainMenu(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
switch (operation) {
case MENUOP_OPEN:
g_Menus[g_MpPlayerNum].main.unke2c = 0;
break;
case MENUOP_TICK:
if (g_Menus[g_MpPlayerNum].curdialog &&
g_Menus[g_MpPlayerNum].curdialog->definition == dialogdef) {
g_MissionConfig.iscoop = false;
g_MissionConfig.isanti = false;
}
break;
}
return false;
}
char *mainMenuTextLabel(struct menuitem *item)
{
u16 nocheats[] = {
L_OPTIONS_117, // "Solo Missions"
L_OPTIONS_118, // "Combat Simulator"
L_OPTIONS_119, // "Co-Operative"
L_OPTIONS_120, // "Counter-Operative"
};
u16 withcheats[] = {
L_MPWEAPONS_130, // "Cheat Solo Missions"
L_MPWEAPONS_131, // "Cheat Combat Simulator"
L_MPWEAPONS_132, // "Cheat Co-Operative"
L_MPWEAPONS_133, // "Cheat Counter-Operative"
};
if (g_CheatsEnabledBank0 || g_CheatsEnabledBank1) {
return langGet(withcheats[item->param]);
}
return langGet(nocheats[item->param]);
}
struct menuitem g_MainMenuMenuItems[] = {
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG | MENUITEMFLAG_BIGFONT,
L_MISC_446, // "Carrington Institute"
0x00000001,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_BIGFONT,
(u32)&mainMenuTextLabel,
0x00000002,
menuhandlerMainMenuSoloMissions,
},
{
MENUITEMTYPE_SELECTABLE,
1,
MENUITEMFLAG_BIGFONT,
(u32)&mainMenuTextLabel,
0x00000003,
menuhandlerMainMenuCombatSimulator,
},
{
MENUITEMTYPE_SELECTABLE,
2,
MENUITEMFLAG_BIGFONT,
(u32)&mainMenuTextLabel,
0x00000004,
menuhandlerMainMenuCooperative,
},
{
MENUITEMTYPE_SELECTABLE,
3,
MENUITEMFLAG_BIGFONT,
(u32)&mainMenuTextLabel,
0x00000005,
menuhandlerMainMenuCounterOperative,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
L_OPTIONS_187, // "Change Agent..."
0x00000006,
(void *)&g_ChangeAgentMenuDialog,
},
{ MENUITEMTYPE_END },
};
struct menudialogdef g_CiMenuViaPcMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_116, // "Perfect Menu"
g_MainMenuMenuItems,
menudialogMainMenu,
MENUDIALOGFLAG_STARTSELECTS,
&g_CiOptionsViaPcMenuDialog,
};
struct menudialogdef g_CiMenuViaPauseMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_OPTIONS_116, // "Perfect Menu"
g_MainMenuMenuItems,
menudialogMainMenu,
MENUDIALOGFLAG_STARTSELECTS,
&g_CiOptionsViaPauseMenuDialog,
};
bool soloChoosePauseDialog(void)
{
if (g_Menus[g_MpPlayerNum].openinhibit == 0) {
g_Menus[g_MpPlayerNum].playernum = 0;
if (g_Vars.stagenum == STAGE_CITRAINING) {
bool handled = false;
if (ciIsTourDone()) {
struct trainingdata *dtdata = dtGetData();
s32 room = g_Vars.currentplayer->prop->rooms[0];
if (room >= ROOM_DISH_HOLO1 && room <= ROOM_DISH_HOLO4) {
struct trainingdata *htdata = getHoloTrainingData();
if (htdata->intraining) {
menuPushRootDialog(&g_HtDetailsMenuDialog, MENUROOT_TRAINING);
} else if (htdata->finished) {
htPushEndscreen();
} else {
menuPushRootDialog(&g_HtListMenuDialog, MENUROOT_TRAINING);
}
handled = true;
} else if (room == ROOM_DISH_DEVICELAB) {
if (dtdata->intraining) {
menuPushRootDialog(&g_DtDetailsMenuDialog, MENUROOT_TRAINING);
} else if (dtdata->finished) {
dtPushEndscreen();
} else {
menuPushRootDialog(&g_DtListMenuDialog, MENUROOT_TRAINING);
}
handled = true;
} else if (dtdata->intraining) {
menuPushRootDialog(&g_DtDetailsMenuDialog, MENUROOT_TRAINING);
handled = true;
} else if (dtdata->finished) {
dtPushEndscreen();
handled = true;
} else if (room == ROOM_DISH_FIRINGRANGE) {
if (frIsInTraining()) {
menuPushRootDialog(&g_FrTrainingInfoInGameMenuDialog, MENUROOT_TRAINING);
} else {
menuPushRootDialog(&g_FrWeaponListMenuDialog, MENUROOT_TRAINING);
}
handled = true;
}
}
if (!handled) {
menuPushRootDialog(&g_CiMenuViaPauseMenuDialog, MENUROOT_MAINMENU);
return true;
}
} else {
menuPushRootDialog(&g_SoloMissionPauseMenuDialog, MENUROOT_MAINMENU);
}
return true;
}
return false;
}