mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-07-04 20:15:28 -04:00
4910 lines
109 KiB
C
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;
|
|
}
|