mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-07-11 06:04:37 -04:00
4927 lines
113 KiB
C
4927 lines
113 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/gset.h"
|
|
#include "game/text.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;
|
|
|
|
MenuItemHandlerResult menuhandler_fr_inventory_list(s32 operation, struct menuitem *item, union handlerdata *data);
|
|
|
|
char *menu_text_current_stage_name(struct menuitem *item)
|
|
{
|
|
sprintf(g_StringPointer, "%s\n", lang_get(g_SoloStages[g_MissionConfig.stageindex].name3));
|
|
return g_StringPointer;
|
|
}
|
|
|
|
char *solo_menu_text_difficulty(struct menuitem *item)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_MissionConfig.pdmode) {
|
|
return lang_get(L_MPWEAPONS_221);
|
|
}
|
|
#endif
|
|
|
|
switch (g_MissionConfig.difficulty) {
|
|
case DIFF_SA:
|
|
return lang_get(L_OPTIONS_252);
|
|
case DIFF_PA:
|
|
return lang_get(L_OPTIONS_253);
|
|
case DIFF_A:
|
|
default:
|
|
return lang_get(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"
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_control_style_impl(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) lang_get(g_ControlStyleOptions[data->list.value]);
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
return (s32) lang_get(categories[data->list.value]);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
data->list.groupstartindex = data->list.value == 0 ? 0 : 4;
|
|
break;
|
|
case MENUOP_SET:
|
|
options_set_control_mode(mpindex, data->list.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->list.value = options_get_control_mode(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;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_control_style_p1(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandler_control_style_impl(operation, item, data, 4);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_control_style_p2(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
return menuhandler_control_style_impl(operation, item, data, 5);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_reverse_pitch(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 !options_get_forward_pitch(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_forward_pitch(mpchrnum, data->checkbox.value == 0);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_aim_control(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 (options_get_screen_split() == 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) lang_get(options[index][data->dropdown.value]);
|
|
#else
|
|
return (s32) lang_get(options[data->dropdown.value]);
|
|
#endif
|
|
case MENUOP_SET:
|
|
options_set_aim_control(playernum, data->dropdown.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = options_get_aim_control(playernum);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_sound_mode(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) lang_get(options[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
snd_set_sound_mode(data->dropdown.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = g_SoundMode;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_screen_size(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) lang_get(options[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
options_set_screen_size(data->dropdown.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = options_get_effective_screen_size();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_screen_ratio(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) lang_get(options[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
options_set_screen_ratio(data->dropdown.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = options_get_screen_ratio();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if PAL
|
|
MenuItemHandlerResult menuhandler_language(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)lang_get(labels[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
g_Vars.language = data->dropdown.value;
|
|
lang_set_european(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
|
|
|
|
MenuItemHandlerResult menuhandler_screen_split(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) lang_get(options[data->dropdown.value]);
|
|
case MENUOP_SET:
|
|
if (data->dropdown.value != (u32)options_get_screen_split()) {
|
|
options_set_screen_split(data->dropdown.value);
|
|
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
|
|
if (PLAYERCOUNT() > 1) {
|
|
u32 prevplayernum = g_MpPlayerNum;
|
|
g_MpPlayerNum = 0;
|
|
menu_save_and_close_all();
|
|
g_MpPlayerNum = 1;
|
|
menu_save_and_close_all();
|
|
g_MpPlayerNum = prevplayernum;
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->dropdown.value = options_get_screen_split();
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_look_ahead(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 options_get_look_ahead(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_look_ahead(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_head_roll(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 options_get_head_roll(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_head_roll(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_in_game_subtitles(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GET:
|
|
return options_get_in_game_subtitles();
|
|
case MENUOP_SET:
|
|
options_set_in_game_subtitles(data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_cutscene_subtitles(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GET:
|
|
return options_get_cutscene_subtitles();
|
|
case MENUOP_SET:
|
|
options_set_cutscene_subtitles(data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_alternative_title(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;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_hi_res(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:
|
|
player_set_hi_res_enabled(data->checkbox.value ? 1 : 0);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_ammo_on_screen(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 options_get_ammo_on_screen(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_ammo_on_screen(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_show_gun_function(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 (options_get_ammo_on_screen(mpchrnum) == 0) {
|
|
return true;
|
|
}
|
|
break;
|
|
case MENUOP_GET:
|
|
return options_get_show_gun_function(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_show_gun_function(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_show_mission_time(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 options_get_show_mission_time(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_show_mission_time(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_always_show_target(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 (options_get_sight_on_screen(mpchrnum) == 0) {
|
|
return true;
|
|
}
|
|
break;
|
|
case MENUOP_GET:
|
|
return options_get_always_show_target(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_always_show_target(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_show_zoom_range(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 (options_get_sight_on_screen(mpchrnum) == 0) {
|
|
return true;
|
|
}
|
|
break;
|
|
case MENUOP_GET:
|
|
return options_get_show_zoom_range(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_show_zoom_range(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_paintball(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 options_get_paintball(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_paintball(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_sight_on_screen(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 options_get_sight_on_screen(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_sight_on_screen(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_autoaim(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 options_get_autoaim(mpchrnum);
|
|
case MENUOP_SET:
|
|
options_set_autoaim(mpchrnum, data->checkbox.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_music_volume(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = options_get_music_volume();
|
|
break;
|
|
case MENUOP_SET:
|
|
options_set_music_volume(data->slider.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_sfx_volume(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETSLIDER:
|
|
data->slider.value = VOLUME(g_SfxVolume);
|
|
break;
|
|
case MENUOP_SET:
|
|
snd_set_sfx_volume(data->slider.value);
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_briefing(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) {
|
|
menuhandler_accept_mission(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,
|
|
menudialog_briefing,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_accept_mission(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menu_stop();
|
|
|
|
if (g_Vars.stagenum == g_MissionConfig.stagenum) {
|
|
g_Vars.restartlevel = true;
|
|
}
|
|
|
|
title_set_next_stage(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;
|
|
set_num_players(2);
|
|
} else {
|
|
// Coop with AI buddies
|
|
g_Vars.bondplayernum = 0;
|
|
g_Vars.coopplayernum = -1;
|
|
g_Vars.antiplayernum = -1;
|
|
set_num_players(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;
|
|
set_num_players(2);
|
|
} else {
|
|
// Solo
|
|
g_Vars.bondplayernum = 0;
|
|
g_Vars.coopplayernum = -1;
|
|
g_Vars.antiplayernum = -1;
|
|
set_num_players(1);
|
|
}
|
|
|
|
lv_set_difficulty(g_MissionConfig.difficulty);
|
|
title_set_next_mode(TITLEMODE_SKIP);
|
|
main_change_to_stage(g_MissionConfig.stagenum);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
vi_black(true);
|
|
#endif
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *solo_menu_title_stage_overview(struct menudialogdef *dialogdef)
|
|
{
|
|
if (dialogdef != g_Menus[g_MpPlayerNum].curdialog->definition) {
|
|
return lang_get(L_OPTIONS_273); // "Overview"
|
|
}
|
|
|
|
sprintf(g_StringPointer, "%s: %s\n",
|
|
lang_get(g_SoloStages[g_MissionConfig.stageindex].name3),
|
|
lang_get(L_OPTIONS_273));
|
|
|
|
return g_StringPointer;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_accept_mission(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_OPEN:
|
|
g_Menus[g_MpPlayerNum].menumodel.curparams = 0;
|
|
|
|
setup_load_briefing(g_MissionConfig.stagenum,
|
|
g_Menus[g_MpPlayerNum].menumodel.allocstart,
|
|
g_Menus[g_MpPlayerNum].menumodel.alloclen, &g_Briefing);
|
|
break;
|
|
case MENUOP_CLOSE:
|
|
lang_clear_bank(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,
|
|
menuhandler_accept_mission,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
|
L_OPTIONS_275, // "Decline"
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_AcceptMissionMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(uintptr_t)&solo_menu_title_stage_overview,
|
|
g_AcceptMissionMenuItems,
|
|
menudialog_accept_mission,
|
|
MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_DISABLEITEMSCROLL,
|
|
&g_PreAndPostMissionBriefingMenuDialog,
|
|
};
|
|
|
|
f32 mainmenu_pdmode_handicap_to_value(u8 handicap, s32 prop)
|
|
{
|
|
if (prop == PDMODEPROP_REACTION) {
|
|
return handicap / 255.0f;
|
|
}
|
|
|
|
return mp_handicap_to_value(handicap);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_pd_mode_setting(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 = mainmenu_pdmode_handicap_to_value(*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;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_accept_pd_mode_settings(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_MissionConfig.pdmode = true;
|
|
g_MissionConfig.pdmodehealthf = mainmenu_pdmode_handicap_to_value(g_MissionConfig.pdmodehealth, PDMODEPROP_HEALTH);
|
|
g_MissionConfig.pdmodedamagef = mainmenu_pdmode_handicap_to_value(g_MissionConfig.pdmodedamage, PDMODEPROP_DAMAGE);
|
|
g_MissionConfig.pdmodeaccuracyf = mainmenu_pdmode_handicap_to_value(g_MissionConfig.pdmodeaccuracy, PDMODEPROP_ACCURACY);
|
|
g_MissionConfig.difficulty = DIFF_PA;
|
|
lv_set_difficulty(g_MissionConfig.difficulty);
|
|
menu_pop_dialog();
|
|
menu_pop_dialog();
|
|
menu_push_dialog(&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,
|
|
menuhandler_pd_mode_setting,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
2,
|
|
MENUITEMFLAG_SLIDER_ALTSIZE,
|
|
L_MPWEAPONS_225, // "Enemy Damage:"
|
|
0x000000ff,
|
|
menuhandler_pd_mode_setting,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SLIDER,
|
|
3,
|
|
MENUITEMFLAG_SLIDER_ALTSIZE,
|
|
L_MPWEAPONS_226, // "Enemy Accuracy:"
|
|
0x000000ff,
|
|
menuhandler_pd_mode_setting,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0x000000b4,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_227, // "OK"
|
|
0,
|
|
menuhandler_accept_pd_mode_settings,
|
|
},
|
|
{
|
|
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 is_stage_difficulty_unlocked(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_SoloStages[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_SoloStages[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_SoloStages[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;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_solo_difficulty(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_CHECKPREFOCUSED:
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (is_stage_difficulty_unlocked(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;
|
|
lv_set_difficulty(g_MissionConfig.difficulty);
|
|
menu_pop_dialog();
|
|
menu_push_dialog(&g_AcceptMissionMenuDialog);
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
if (!is_stage_difficulty_unlocked(g_MissionConfig.stageindex, item->param)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_pd_mode(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
menu_push_dialog(&g_PdModeSettingsMenuDialog);
|
|
break;
|
|
case MENUOP_CHECKHIDDEN:
|
|
if (g_GameFile.besttimes[SOLOSTAGEINDEX_SKEDARRUINS][DIFF_PA] == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *solo_menu_text_best_time(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"
|
|
(uintptr_t)&solo_menu_text_best_time,
|
|
menuhandler_solo_difficulty,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
0,
|
|
L_OPTIONS_252, // "Special Agent"
|
|
(uintptr_t)&solo_menu_text_best_time,
|
|
menuhandler_solo_difficulty,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
0,
|
|
L_OPTIONS_253, // "Perfect Agent"
|
|
(uintptr_t)&solo_menu_text_best_time,
|
|
menuhandler_solo_difficulty,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_221, // "Perfect Dark"
|
|
0,
|
|
menuhandler_pd_mode,
|
|
},
|
|
{
|
|
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,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_buddy_options_continue(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menu_pop_dialog();
|
|
menu_push_dialog(&g_AcceptMissionMenuDialog);
|
|
}
|
|
|
|
if (operation == MENUOP_CHECKPREFOCUSED) {
|
|
return true;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
s32 get_max_ai_buddies(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
|
|
#ifdef DEBUG
|
|
if (debug_is_all_buddies_enabled()) {
|
|
max = 4;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
return max;
|
|
}
|
|
#endif
|
|
|
|
MenuDialogHandlerResult menudialog_coop_anti_options(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (operation == MENUOP_OPEN) {
|
|
s32 max = get_max_ai_buddies();
|
|
|
|
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) {
|
|
menuhandler_buddy_options_continue(MENUOP_SET, NULL, NULL);
|
|
}
|
|
|
|
inputs->start = false;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_coop_radar(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 ? true : false;
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_coop_friendly_fire(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 ? true : false;
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_coop_buddy(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 = get_max_ai_buddies();
|
|
s32 human = 0;
|
|
|
|
if (joy_get_connected_controllers() & 2) {
|
|
human = 1;
|
|
}
|
|
|
|
data->dropdown.value = human + maxaibuddies;
|
|
}
|
|
#else
|
|
{
|
|
s32 extrabuddies = 0;
|
|
s32 i;
|
|
s32 maxbuddies = 1 - g_MissionConfig.difficulty;
|
|
s32 human = 0;
|
|
|
|
if (joy_get_connected_controllers() & 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;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (debug_is_all_buddies_enabled()) {
|
|
maxbuddies = 4;
|
|
}
|
|
#endif
|
|
|
|
data->dropdown.value = human + maxbuddies;
|
|
}
|
|
#endif
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
{
|
|
s32 extra = 1;
|
|
|
|
if (joy_get_connected_controllers() & 2) {
|
|
extra = 0;
|
|
}
|
|
|
|
return (s32)lang_get(labels[data->dropdown.value + extra]);
|
|
}
|
|
case MENUOP_SET:
|
|
{
|
|
s32 extra = 1;
|
|
|
|
if (joy_get_connected_controllers() & 2) {
|
|
extra = 0;
|
|
}
|
|
|
|
g_Vars.numaibuddies = data->dropdown.value + extra;
|
|
g_Vars.modifiedfiles |= MODFILE_GAME;
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
{
|
|
s32 extra = 1;
|
|
|
|
if (joy_get_connected_controllers() & 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,
|
|
menuhandler_coop_radar,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_257, // "Friendly Fire"
|
|
0,
|
|
menuhandler_coop_friendly_fire,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_258, // "Perfect Buddy"
|
|
0,
|
|
menuhandler_coop_buddy,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
}, // ""
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_259, // "Continue"
|
|
0,
|
|
menuhandler_buddy_options_continue,
|
|
},
|
|
{
|
|
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,
|
|
menudialog_coop_anti_options,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_anti_radar(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;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_anti_player(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) lang_get(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,
|
|
menuhandler_anti_radar,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_268, // "Counter-Operative"
|
|
0,
|
|
menuhandler_anti_player,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SEPARATOR,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_269, // "Continue"
|
|
0,
|
|
menuhandler_buddy_options_continue,
|
|
},
|
|
{
|
|
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,
|
|
menudialog_coop_anti_options,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_coop_difficulty(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
g_MissionConfig.pdmode = false;
|
|
g_MissionConfig.difficulty = item->param;
|
|
lv_set_difficulty(g_MissionConfig.difficulty);
|
|
menu_pop_dialog();
|
|
menu_push_dialog(&g_CoopOptionsMenuDialog);
|
|
break;
|
|
case MENUOP_CHECKDISABLED:
|
|
if (!is_stage_difficulty_unlocked(g_MissionConfig.stageindex, item->param)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_CoopMissionDifficultyMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_251, // "Agent"
|
|
0,
|
|
menuhandler_coop_difficulty,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
0,
|
|
L_OPTIONS_252, // "Special Agent"
|
|
0,
|
|
menuhandler_coop_difficulty,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
0,
|
|
L_OPTIONS_253, // "Perfect Agent"
|
|
0,
|
|
menuhandler_coop_difficulty,
|
|
},
|
|
{
|
|
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,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_anti_difficulty(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_SET:
|
|
g_MissionConfig.pdmode = false;
|
|
g_MissionConfig.difficulty = item->param;
|
|
lv_set_difficulty(g_MissionConfig.difficulty);
|
|
menu_pop_dialog();
|
|
menu_push_dialog(&g_AntiOptionsMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_AntiMissionDifficultyMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
0,
|
|
L_OPTIONS_251, // "Agent"
|
|
0,
|
|
menuhandler_anti_difficulty,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
0,
|
|
L_OPTIONS_252, // "Special Agent"
|
|
0,
|
|
menuhandler_anti_difficulty,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
0,
|
|
L_OPTIONS_253, // "Perfect Agent"
|
|
0,
|
|
menuhandler_anti_difficulty,
|
|
},
|
|
{
|
|
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 solostage g_SoloStages[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 get_num_unlocked_special_stages(void)
|
|
{
|
|
s32 count = 0;
|
|
s32 offsetforduel = 1;
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_GameFile.besttimes[0]); i++) {
|
|
if (g_GameFile.besttimes[SOLOSTAGEINDEX_SKEDARRUINS][i]) {
|
|
count = 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 (fr_get_score(i) <= FRSCORE_INCOMPLETE) {
|
|
offsetforduel = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count + offsetforduel;
|
|
}
|
|
|
|
/**
|
|
* Convert a special stage index (0 = MBR, 3 = Duel) to a regular stage index (17-20).
|
|
*
|
|
* If the special stage index isn't unlocked then the stage index for Duel will be returned.
|
|
* This never happens though, so this function is needlessly complicated.
|
|
*/
|
|
s32 mainmenu_specialindex_to_stageindex(s32 specialindex)
|
|
{
|
|
s32 completed = 0;
|
|
s32 d;
|
|
|
|
for (d = 0; d < ARRAYCOUNT(g_GameFile.besttimes[0]); d++) {
|
|
if (g_GameFile.besttimes[SOLOSTAGEINDEX_SKEDARRUINS][d]) {
|
|
completed = d + 1;
|
|
}
|
|
}
|
|
|
|
if (completed > specialindex) {
|
|
return 17 + specialindex;
|
|
}
|
|
|
|
return 20;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_mission_list(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 stageindex2;
|
|
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 <= SOLOSTAGEINDEX_SKEDARRUINS; i++) {
|
|
stageiscomplete = false;
|
|
|
|
for (j = 0; j < ARRAYCOUNT(g_GameFile.besttimes[i]); 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 += get_num_unlocked_special_stages();
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if (data->list.unk04u32 == 0) {
|
|
menuhandler_mission_list(MENUOP_GETOPTIONCOUNT, item, &sp18c);
|
|
data->list.unk04u32 = sp18c.list.value - get_num_unlocked_special_stages();
|
|
}
|
|
|
|
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 (intptr_t) lang_get(g_SoloStages[data->list.value].name1);
|
|
}
|
|
|
|
// Special stages have no dash and suffix, so just return the name
|
|
return (intptr_t) lang_get(g_SoloStages[mainmenu_specialindex_to_stageindex(data->list.value - data->list.unk04u32)].name1);
|
|
case MENUOP_SET:
|
|
stageindex2 = data->list.value;
|
|
menuhandler_mission_list(MENUOP_GETOPTIONCOUNT, item, &sp178);
|
|
sp178.list.value -= get_num_unlocked_special_stages();
|
|
|
|
if (data->list.value >= sp178.list.value) {
|
|
stageindex2 = mainmenu_specialindex_to_stageindex(data->list.value - sp178.list.value);
|
|
}
|
|
|
|
g_Vars.mplayerisrunning = false;
|
|
g_Vars.normmplayerisrunning = false;
|
|
g_MissionConfig.stagenum = g_SoloStages[stageindex2].stagenum;
|
|
g_MissionConfig.stageindex = stageindex2;
|
|
|
|
if (g_MissionConfig.iscoop) {
|
|
menu_push_dialog(&g_CoopMissionDifficultyMenuDialog);
|
|
} else if (g_MissionConfig.isanti) {
|
|
menu_push_dialog(&g_AntiMissionDifficultyMenuDialog);
|
|
} else {
|
|
menu_push_dialog(&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;
|
|
|
|
menuhandler_mission_list(MENUOP_GETOPTIONCOUNT, item, &sp168);
|
|
sp168.list.value -= get_num_unlocked_special_stages();
|
|
|
|
if (data->list.value >= sp168.list.value) {
|
|
sp164 = get_num_unlocked_special_stages();
|
|
|
|
data->list.value = sp168.list.value - 1;
|
|
|
|
for (sp160 = 0; sp160 < sp164; sp160++) {
|
|
if (mainmenu_specialindex_to_stageindex(sp160) == g_GameFile.autostageindex) {
|
|
data->list.value = sp168.list.values32 + sp160;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
menuhandler_mission_list(MENUOP_GETOPTIONCOUNT, item, &sp150);
|
|
sp150.list.value -= get_num_unlocked_special_stages();
|
|
|
|
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) lang_get(groups[9].name); // "Special Assignments"
|
|
}
|
|
return (s32) lang_get(groups[data->list.value].name);
|
|
case MENUOP_GETGROUPSTARTINDEX:
|
|
if (data->list.unk0c == data->list.value) {
|
|
menuhandler_mission_list(MENUOP_GETOPTIONCOUNT, item, &sp13c);
|
|
data->list.groupstartindex = sp13c.list.value - get_num_unlocked_special_stages();
|
|
} 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) {
|
|
menuhandler_mission_list(MENUOP_GETOPTIONCOUNT, item, &spdc);
|
|
data->type19.unk0c = spdc.list.value - get_num_unlocked_special_stages();
|
|
}
|
|
|
|
if (data->type19.unk04u32 >= data->type19.unk0c) {
|
|
stageindex = mainmenu_specialindex_to_stageindex(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
|
|
tex_select(&gdl, g_TexGeneralConfigs + TEX_GENERAL_DEFECTION + stageindex, 2, 0, 2, true, NULL);
|
|
gDPSetCycleType(gdl++, G_CYC_1CYCLE);
|
|
gDPSetCombineMode(gdl++, G_CC_CUSTOM_00, G_CC_CUSTOM_00);
|
|
gDPSetTextureFilter(gdl++, G_TF_POINT);
|
|
gDPSetEnvColorViaWord(gdl++, 0xffffff00 | ((renderdata->colour & 0xff) * 255 / 256));
|
|
#else
|
|
tex_select(&gdl, g_TexGeneralConfigs + TEX_GENERAL_DEFECTION + 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_UiScaleX, (renderdata->y + 3) << 2,
|
|
((renderdata->x + 60) << 2) * g_UiScaleX, (renderdata->y + 39) << 2,
|
|
G_TX_RENDERTILE, 0, 0x0480, 1024 / g_UiScaleX, -1024);
|
|
|
|
if (g_MissionConfig.isanti) {
|
|
// No stars
|
|
} else if (g_MissionConfig.iscoop) {
|
|
tex_select(&gdl, &g_TexGeneralConfigs[TEX_GENERAL_SILVERSTAR], 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_UiScaleX, (renderdata->y + 25) << 2,
|
|
((renderdata->x + relx + 14) << 2) * g_UiScaleX, (renderdata->y + 39) << 2,
|
|
G_TX_RENDERTILE, 0x0010, 0x01c0, 1024 / g_UiScaleX, -1024);
|
|
}
|
|
} else {
|
|
tex_select(&gdl, &g_TexGeneralConfigs[TEX_GENERAL_GOLDSTAR], 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_UiScaleX, (renderdata->y + 25) << 2,
|
|
((renderdata->x + relx + 14) << 2) * g_UiScaleX, (renderdata->y + 39) << 2,
|
|
G_TX_RENDERTILE, 0x0010, 0x01c0, 1024 / g_UiScaleX, -1024);
|
|
}
|
|
}
|
|
|
|
x = renderdata->x + 62;
|
|
y = renderdata->y + 3;
|
|
|
|
gdl = text_begin(gdl);
|
|
|
|
// Draw first part of name
|
|
strcpy(text, lang_get(g_SoloStages[stageindex].name1));
|
|
strcat(text, "\n");
|
|
|
|
gdl = text_render_v2(gdl, &x, &y, text, g_CharsHandelGothicMd, g_FontHandelGothicMd,
|
|
renderdata->colour, vi_get_width(), vi_get_height(), 0, 0);
|
|
|
|
// Draw last part of name
|
|
strcpy(text, lang_get(g_SoloStages[stageindex].name2));
|
|
|
|
gdl = text_render_v2(gdl, &x, &y, text, g_CharsHandelGothicSm, g_FontHandelGothicSm,
|
|
renderdata->colour, vi_get_width(), vi_get_height(), 0, 0);
|
|
|
|
gdl = text_end(gdl);
|
|
|
|
return (s32) gdl;
|
|
case MENUOP_GETOPTIONHEIGHT:
|
|
data->list.value = 42;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_mainmenu_options(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 (filemgr_save_or_load(&g_GameFileGuid, FILEOP_SAVE_GAME_001, 0) == 0) {
|
|
data->dialog1.preventclose = true;
|
|
}
|
|
|
|
g_Vars.modifiedfiles &= ~MODFILE_GAME;
|
|
}
|
|
|
|
if (g_Vars.modifiedfiles & MODFILE_BOSS) {
|
|
bossfile_save();
|
|
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 *menutext_control_style_p1(struct menuitem *item)
|
|
{
|
|
union handlerdata data;
|
|
|
|
menuhandler_control_style_p1(MENUOP_GETSELECTEDINDEX, item, &data);
|
|
|
|
return (char *)menuhandler_control_style_p1(MENUOP_GETOPTIONTEXT, item, &data);
|
|
}
|
|
|
|
char *menutext_control_style_p2(struct menuitem *item)
|
|
{
|
|
union handlerdata data;
|
|
|
|
menuhandler_control_style_p2(MENUOP_GETSELECTEDINDEX, item, &data);
|
|
|
|
return (char *)menuhandler_control_style_p2(MENUOP_GETOPTIONTEXT, item, &data);
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_lang_filter(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;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_control_style(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
if (PLAYERCOUNT() >= 2) {
|
|
menu_push_dialog(&g_2PMissionControlStyleMenuDialog);
|
|
} else {
|
|
menu_push_dialog(&g_SoloMissionControlStyleMenuDialog);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* This function is not used.
|
|
*
|
|
* The filemgr will show a "file saved" dialog when using FILEOP_SAVE_GAME_002,
|
|
* so this is likely the handler for a manual Save Game option which was removed.
|
|
*/
|
|
MenuItemHandlerResult menuhandler_save_game(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
filemgr_save_or_load(&g_GameFileGuid, FILEOP_SAVE_GAME_002, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_change_agent(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
menu_save_and_push_root_dialog(NULL, MENUROOT_CHANGE_AGENT);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct menuitem g_2PMissionControlStyleMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
MENUITEMFLAG_LIST_AUTOWIDTH,
|
|
0x00000050,
|
|
0,
|
|
menuhandler_control_style_p1,
|
|
},
|
|
{ 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
|
|
menuhandler_control_style_p1,
|
|
},
|
|
{
|
|
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
|
|
menuhandler_control_style_p1,
|
|
},
|
|
{
|
|
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
|
|
menuhandler_control_style_p2,
|
|
},
|
|
{
|
|
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
|
|
menuhandler_sfx_volume,
|
|
},
|
|
{
|
|
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
|
|
menuhandler_music_volume,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_230, // "Sound Mode"
|
|
0,
|
|
menuhandler_sound_mode,
|
|
},
|
|
#if VERSION != VERSION_JPN_FINAL
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_218, // "Language Filter"
|
|
0,
|
|
menuhandler_lang_filter,
|
|
},
|
|
#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
|
|
menuhandler_sfx_volume,
|
|
},
|
|
{
|
|
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
|
|
menuhandler_music_volume,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_153, // "Mode"
|
|
0,
|
|
menuhandler_sound_mode,
|
|
},
|
|
#if VERSION != VERSION_JPN_FINAL
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_218, // "Language Filter"
|
|
0,
|
|
menuhandler_lang_filter,
|
|
},
|
|
#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,
|
|
menuhandler_screen_size,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_216, // "Ratio"
|
|
0,
|
|
menuhandler_screen_ratio,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_217, // "Hi-Res"
|
|
0,
|
|
menuhandler_hi_res,
|
|
},
|
|
#if PAL
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_269, // ""
|
|
0,
|
|
menuhandler_language,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_218, // "2-Player Screen Split"
|
|
0,
|
|
menuhandler_screen_split,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_170, // "Alternative Title Screen"
|
|
0,
|
|
menuhandler_alternative_title,
|
|
},
|
|
{
|
|
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,
|
|
menuhandler_screen_ratio,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_217, // "Hi-Res"
|
|
0,
|
|
menuhandler_hi_res,
|
|
},
|
|
#if PAL
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_269, // ""
|
|
0,
|
|
menuhandler_language,
|
|
},
|
|
#endif
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_154, // "Split"
|
|
0,
|
|
menuhandler_screen_split,
|
|
},
|
|
{
|
|
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,
|
|
menuhandler_sight_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_206, // "Always Show Target"
|
|
0x00000004,
|
|
menuhandler_always_show_target,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_207, // "Show Zoom Range"
|
|
0x00000004,
|
|
menuhandler_show_zoom_range,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_208, // "Ammo on Screen"
|
|
0x00000004,
|
|
menuhandler_ammo_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_209, // "Show Gun Function"
|
|
0x00000004,
|
|
menuhandler_show_gun_function,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_210, // "Paintball"
|
|
0x00000004,
|
|
menuhandler_paintball,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_169, // "In-Game Subtitles"
|
|
0x00000004,
|
|
menuhandler_in_game_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
|
0x00000004,
|
|
menuhandler_cutscene_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_212, // "Show Mission Time"
|
|
0x00000004,
|
|
menuhandler_show_mission_time,
|
|
},
|
|
{
|
|
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,
|
|
menuhandler_sight_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_146, // "Target"
|
|
0x00000004,
|
|
menuhandler_always_show_target,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_147, // "Zoom Range"
|
|
0x00000004,
|
|
menuhandler_show_zoom_range,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_148, // "Show Ammo"
|
|
0x00000004,
|
|
menuhandler_ammo_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_149, // "Gun Function"
|
|
0x00000004,
|
|
menuhandler_show_gun_function,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_150, // "Paintball"
|
|
0x00000004,
|
|
menuhandler_paintball,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
L_MPWEAPONS_279, // "In-Game Subtitles"
|
|
#else
|
|
L_MPWEAPONS_169, // "In-Game Subtitles"
|
|
#endif
|
|
0x00000004,
|
|
menuhandler_in_game_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
L_MPWEAPONS_278, // "Cutscene Subtitles"
|
|
#else
|
|
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
|
#endif
|
|
0x00000004,
|
|
menuhandler_cutscene_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_152, // "Mission Time"
|
|
0x00000004,
|
|
menuhandler_show_mission_time,
|
|
},
|
|
{
|
|
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,
|
|
menuhandler_sight_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_206, // "Always Show Target"
|
|
0x00000004,
|
|
menuhandler_always_show_target,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_207, // "Show Zoom Range"
|
|
0x00000004,
|
|
menuhandler_show_zoom_range,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_208, // "Ammo on Screen"
|
|
0x00000004,
|
|
menuhandler_ammo_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_209, // "Show Gun Function"
|
|
0x00000004,
|
|
menuhandler_show_gun_function,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_210, // "Paintball"
|
|
0x00000004,
|
|
menuhandler_paintball,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_169, // "In-Game Subtitles"
|
|
0x00000004,
|
|
menuhandler_in_game_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
|
0x00000004,
|
|
menuhandler_cutscene_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_212, // "Show Mission Time"
|
|
0x00000004,
|
|
menuhandler_show_mission_time,
|
|
},
|
|
{
|
|
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,
|
|
menuhandler_sight_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_206, // "Always Show Target"
|
|
0x00000005,
|
|
menuhandler_always_show_target,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_207, // "Show Zoom Range"
|
|
0x00000005,
|
|
menuhandler_show_zoom_range,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_208, // "Ammo on Screen"
|
|
0x00000005,
|
|
menuhandler_ammo_on_screen,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_209, // "Show Gun Function"
|
|
0x00000005,
|
|
menuhandler_show_gun_function,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_210, // "Paintball"
|
|
0x00000005,
|
|
menuhandler_paintball,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_169, // "In-Game Subtitles"
|
|
0x00000005,
|
|
menuhandler_in_game_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_168, // "Cutscene Subtitles"
|
|
0x00000005,
|
|
menuhandler_cutscene_subtitles,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_212, // "Show Mission Time"
|
|
0x00000005,
|
|
menuhandler_show_mission_time,
|
|
},
|
|
{
|
|
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"
|
|
(uintptr_t)&menutext_control_style_p1,
|
|
menuhandler_control_style,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_195, // "Reverse Pitch"
|
|
0x00000004,
|
|
menuhandler_reverse_pitch,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_196, // "Look Ahead"
|
|
0x00000004,
|
|
menuhandler_look_ahead,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_197, // "Head Roll"
|
|
0x00000004,
|
|
menuhandler_head_roll,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_198, // "Auto-Aim"
|
|
0x00000004,
|
|
menuhandler_autoaim,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_199, // "Aim Control"
|
|
0x00000004,
|
|
menuhandler_aim_control,
|
|
},
|
|
{
|
|
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, // ""
|
|
(uintptr_t)&menutext_control_style_p1,
|
|
menuhandler_control_style,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_271, // ""
|
|
0x00000004,
|
|
menuhandler_reverse_pitch,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_272, // ""
|
|
0x00000004,
|
|
menuhandler_look_ahead,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_273, // ""
|
|
0x00000004,
|
|
menuhandler_head_roll,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_274, // ""
|
|
0x00000004,
|
|
menuhandler_autoaim,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_MPWEAPONS_275, // ""
|
|
0x00000004,
|
|
menuhandler_aim_control,
|
|
},
|
|
{
|
|
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"
|
|
(uintptr_t)&menutext_control_style_p1,
|
|
(void *)&g_CiControlStyleMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_195, // "Reverse Pitch"
|
|
0x00000004,
|
|
menuhandler_reverse_pitch,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_196, // "Look Ahead"
|
|
0x00000004,
|
|
menuhandler_look_ahead,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_197, // "Head Roll"
|
|
0x00000004,
|
|
menuhandler_head_roll,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_198, // "Auto-Aim"
|
|
0x00000004,
|
|
menuhandler_autoaim,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_199, // "Aim Control"
|
|
0x00000004,
|
|
menuhandler_aim_control,
|
|
},
|
|
{
|
|
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"
|
|
(uintptr_t)&menutext_control_style_p2,
|
|
(void *)&g_CiControlStylePlayer2MenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_195, // "Reverse Pitch"
|
|
0x00000005,
|
|
menuhandler_reverse_pitch,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_196, // "Look Ahead"
|
|
0x00000005,
|
|
menuhandler_look_ahead,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_197, // "Head Roll"
|
|
0x00000005,
|
|
menuhandler_head_roll,
|
|
},
|
|
{
|
|
MENUITEMTYPE_CHECKBOX,
|
|
0,
|
|
0,
|
|
L_OPTIONS_198, // "Auto-Aim"
|
|
0x00000005,
|
|
menuhandler_autoaim,
|
|
},
|
|
{
|
|
MENUITEMTYPE_DROPDOWN,
|
|
0,
|
|
0,
|
|
L_OPTIONS_199, // "Aim Control"
|
|
0x00000005,
|
|
menuhandler_aim_control,
|
|
},
|
|
{
|
|
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,
|
|
menuhandler_change_agent,
|
|
},
|
|
{
|
|
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,
|
|
(uintptr_t)&menutext_pause_or_unpause,
|
|
0,
|
|
menuhandler_mp_pause,
|
|
},
|
|
{ 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,
|
|
(uintptr_t)&menutext_pause_or_unpause,
|
|
0,
|
|
menuhandler_mp_pause,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menuitem g_CiOptionsMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_OPTIONS_181, // "Audio"
|
|
1,
|
|
(void *)&g_AudioOptionsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_OPTIONS_182, // "Video"
|
|
2,
|
|
(void *)&g_VideoOptionsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_OPTIONS_183, // "Control"
|
|
3,
|
|
(void *)&g_CiControlOptionsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_OPTIONS_184, // "Display"
|
|
4,
|
|
(void *)&g_CiDisplayMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_OPTIONS_185, // "Cheats"
|
|
5,
|
|
(void *)&g_CheatsMenuDialog,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
0,
|
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_BIGFONT,
|
|
L_OPTIONS_121, // "Cinema"
|
|
6,
|
|
(void *)&g_CinemaMenuDialog,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_SoloMissionOptionsMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_180, // "Options"
|
|
g_SoloMissionOptionsMenuItems,
|
|
menudialog_mainmenu_options,
|
|
0,
|
|
&g_SoloMissionBriefingMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_CiOptionsViaPcMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_180, // "Options"
|
|
g_CiOptionsMenuItems,
|
|
menudialog_mainmenu_options,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menudialogdef g_CiOptionsViaPauseMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_180, // "Options"
|
|
g_CiOptionsMenuItems,
|
|
menudialog_mainmenu_options,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionOptionsHMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_180, // "Options"
|
|
g_2PMissionOptionsHMenuItems,
|
|
menudialog_mainmenu_options,
|
|
0,
|
|
&g_2PMissionBriefingHMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionOptionsVMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_180, // "Options"
|
|
g_2PMissionOptionsVMenuItems,
|
|
menudialog_mainmenu_options,
|
|
0,
|
|
&g_2PMissionBriefingVMenuDialog,
|
|
};
|
|
|
|
u8 g_PrevInventoryWeapon = 255;
|
|
|
|
char *inv_menu_text_primary_function(struct menuitem *item)
|
|
{
|
|
struct funcdef *primaryfunc = gset_get_funcdef_by_weaponnum_funcnum(g_InventoryWeapon, FUNC_PRIMARY);
|
|
struct funcdef *secondaryfunc = gset_get_funcdef_by_weaponnum_funcnum(g_InventoryWeapon, FUNC_SECONDARY);
|
|
|
|
if (primaryfunc && secondaryfunc) {
|
|
return lang_get(primaryfunc->name);
|
|
}
|
|
|
|
return lang_get(L_OPTIONS_003); // "\n"
|
|
}
|
|
|
|
char *inv_menu_text_secondary_function(struct menuitem *item)
|
|
{
|
|
struct funcdef *primaryfunc = gset_get_funcdef_by_weaponnum_funcnum(g_InventoryWeapon, FUNC_PRIMARY);
|
|
struct funcdef *secondaryfunc = gset_get_funcdef_by_weaponnum_funcnum(g_InventoryWeapon, FUNC_SECONDARY);
|
|
|
|
if (secondaryfunc) {
|
|
return lang_get(secondaryfunc->name);
|
|
}
|
|
|
|
if (primaryfunc) {
|
|
return lang_get(primaryfunc->name);
|
|
}
|
|
|
|
return lang_get(L_OPTIONS_003); // "\n"
|
|
}
|
|
|
|
void mainmenu_prepare_weapon_menumodel(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 weapondef *weapon;
|
|
u32 stack;
|
|
s32 wantindex;
|
|
|
|
useindex = weaponnum - 2;
|
|
wantindex = useindex;
|
|
|
|
if ((u32)wantindex < 0 || wantindex >= ARRAYCOUNT(gunconfig)) {
|
|
useindex = 0;
|
|
}
|
|
|
|
if (gset_has_weapon_flag(weaponnum, WEAPONFLAG_HIDEMENUMODEL) == false && (u32)wantindex >= 0 && useindex >= 0) {
|
|
weapon = gset_get_weapondef(weaponnum);
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.loaddelay = 8;
|
|
g_Menus[g_MpPlayerNum].menumodel.curparams = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.newparams = MENUMODELPARAMS_SET_FILENUM(gset_get_filenum(weaponnum));
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curposx = g_Menus[g_MpPlayerNum].menumodel.newposx = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.curposy = g_Menus[g_MpPlayerNum].menumodel.newposy = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.curposz = g_Menus[g_MpPlayerNum].menumodel.newposz = 0;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.currotz = g_Menus[g_MpPlayerNum].menumodel.newrotz = 0;
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.displacex = gunconfig[useindex][0];
|
|
g_Menus[g_MpPlayerNum].menumodel.displacey = gunconfig[useindex][1];
|
|
g_Menus[g_MpPlayerNum].menumodel.displacez = gunconfig[useindex][2];
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.newrotx = gunconfig[useindex][3];
|
|
g_Menus[g_MpPlayerNum].menumodel.currotx = gunconfig[useindex][3];
|
|
|
|
menu_configure_model(&g_Menus[g_MpPlayerNum].menumodel, 0, 0, 0, 0, 0, 0, gunconfig[useindex][4], MENUMODELFLAG_HASSCALE);
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.curscale = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.partvisibility = weapon->partvisibility;
|
|
g_Menus[g_MpPlayerNum].menumodel.zoom = -1;
|
|
|
|
// These indexes correspond to WEAPON_DISGUISE40 and WEAPON_DISGUISE41
|
|
if (wantindex == 0x3e || wantindex == 0x3f) {
|
|
if ((u32)wantindex == 0x3e) {
|
|
g_Menus[g_MpPlayerNum].menumodel.newparams = MENUMODELPARAMS_SET_MP_HEADBODY(MPHEAD_DARK_FROCK, MPBODY_DARKLAB);
|
|
} else {
|
|
g_Menus[g_MpPlayerNum].menumodel.newparams = MENUMODELPARAMS_SET_MP_HEADBODY(MPHEAD_DARK_COMBAT, MPBODY_DARK_AF1);
|
|
}
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.partvisibility = NULL;
|
|
g_Menus[g_MpPlayerNum].menumodel.removingpiece = false;
|
|
|
|
menu_configure_model(&g_Menus[g_MpPlayerNum].menumodel, 0, 0, 0, 0, 0, 0, 1, MENUMODELFLAG_HASSCALE);
|
|
|
|
g_Menus[g_MpPlayerNum].menumodel.rottimer60 = TICKS(60);
|
|
g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 = TICKS(120);
|
|
g_Menus[g_MpPlayerNum].menumodel.curroty = g_Menus[g_MpPlayerNum].menumodel.newroty = -0.2f;
|
|
}
|
|
} else {
|
|
g_Menus[g_MpPlayerNum].menumodel.bodymodeldef = NULL;
|
|
g_Menus[g_MpPlayerNum].menumodel.curparams = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.newparams = 0;
|
|
}
|
|
}
|
|
|
|
MenuDialogHandlerResult inventory_menu_dialog(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].menumodel.zoomtimer60 -= g_Vars.diffframe60;
|
|
g_Menus[g_MpPlayerNum].menumodel.newroty = 18.849555969238f * g_20SecIntervalFrac;
|
|
g_Menus[g_MpPlayerNum].menumodel.curroty = 18.849555969238f * g_20SecIntervalFrac;
|
|
g_Menus[g_MpPlayerNum].menumodel.currotz = 0;
|
|
g_Menus[g_MpPlayerNum].menumodel.newrotz = 0;
|
|
|
|
if (g_PrevInventoryWeapon != g_InventoryWeapon) {
|
|
mainmenu_prepare_weapon_menumodel(g_InventoryWeapon);
|
|
g_PrevInventoryWeapon = g_InventoryWeapon;
|
|
}
|
|
|
|
if (g_InventoryWeapon == WEAPON_DISGUISE40 || g_InventoryWeapon == WEAPON_DISGUISE41) {
|
|
g_Menus[g_MpPlayerNum].menumodel.newanimnum = ANIM_006A;
|
|
g_Menus[g_MpPlayerNum].menumodel.rottimer60 = TICKS(60);
|
|
g_Menus[g_MpPlayerNum].menumodel.zoomtimer60 = TICKS(120);
|
|
}
|
|
} else {
|
|
g_PrevInventoryWeapon = 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 *inv_menu_text_weapon_name(struct menuitem *item)
|
|
{
|
|
struct weapondef *weapon = gset_get_weapondef(g_InventoryWeapon);
|
|
|
|
if (weapon) {
|
|
if (weapon->manufacturer == L_GUN_000) { // "\n"
|
|
return lang_get(L_OPTIONS_003); // "\n"
|
|
}
|
|
|
|
return lang_get(weapon->name);
|
|
}
|
|
|
|
return lang_get(L_OPTIONS_003); // "\n"
|
|
}
|
|
|
|
/**
|
|
* Return manufacturer, with fallback to weapon name if manufacturer is blank.
|
|
*/
|
|
char *inv_menu_text_weapon_manufacturer(struct menuitem *item)
|
|
{
|
|
struct weapondef *weapon = gset_get_weapondef(g_InventoryWeapon);
|
|
u32 textid = L_GUN_000; // "\n"
|
|
|
|
if (weapon) {
|
|
textid = weapon->manufacturer;
|
|
}
|
|
|
|
if (textid != L_GUN_000) {
|
|
return lang_get(textid);
|
|
}
|
|
|
|
weapon = gset_get_weapondef(g_InventoryWeapon);
|
|
|
|
if (weapon) {
|
|
return lang_get(weapon->name);
|
|
}
|
|
|
|
return lang_get(L_OPTIONS_003); // "\n"
|
|
}
|
|
|
|
char *inv_menu_text_weapon_description(struct menuitem *item)
|
|
{
|
|
struct weapondef *weapon = gset_get_weapondef(g_InventoryWeapon);
|
|
|
|
if (weapon) {
|
|
if (g_InventoryWeapon == WEAPON_EYESPY && g_Vars.currentplayer->eyespy) {
|
|
if (g_Vars.currentplayer->eyespy->mode == EYESPYMODE_DRUGSPY) {
|
|
return lang_get(L_GUN_237); // Drugspy description
|
|
}
|
|
|
|
if (g_Vars.currentplayer->eyespy->mode == EYESPYMODE_BOMBSPY) {
|
|
return lang_get(L_GUN_236); // Bombspy description
|
|
}
|
|
}
|
|
|
|
if (g_InventoryWeapon == WEAPON_NECKLACE
|
|
&& g_Vars.stagenum == (VERSION >= VERSION_NTSC_1_0 ? STAGE_ATTACKSHIP : STAGE_SKEDARRUINS)
|
|
&& lv_get_difficulty() >= 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, lang_get(L_GUN_239), &username, &password);
|
|
return g_StringPointer;
|
|
#else
|
|
// ntsc-beta stores the whole thing as a single plain text string
|
|
return lang_get(L_GUN_239);
|
|
#endif
|
|
}
|
|
|
|
return lang_get(weapon->description);
|
|
}
|
|
|
|
return lang_get(L_OPTIONS_003); // "\n"
|
|
}
|
|
|
|
struct menuitem g_SoloMissionInventoryMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
0,
|
|
0x0000006e,
|
|
(VERSION >= VERSION_JPN_FINAL ? 0x54 : 0x63),
|
|
menuhandler_inventory_list,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_NEWCOLUMN | MENUITEMFLAG_00000002 | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_weapon_manufacturer,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002 | MENUITEMFLAG_LABEL_ALTCOLOUR | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_weapon_name,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MODEL,
|
|
0,
|
|
0,
|
|
0x0000008c,
|
|
(VERSION >= VERSION_JPN_FINAL ? 0x14 : 0x37),
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002 | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_primary_function,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002 | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_secondary_function,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(uintptr_t)&inv_menu_text_weapon_description,
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menuitem g_FrWeaponsAvailableMenuItems[] = {
|
|
{
|
|
MENUITEMTYPE_LIST,
|
|
0,
|
|
0,
|
|
0x0000006e,
|
|
0x00000063,
|
|
menuhandler_fr_inventory_list,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_NEWCOLUMN | MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_weapon_manufacturer,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LABEL_ALTCOLOUR | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_weapon_name,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MODEL,
|
|
0,
|
|
0,
|
|
0x0000008c,
|
|
0x00000037,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_primary_function,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_LABEL,
|
|
0,
|
|
MENUITEMFLAG_00000002 | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
|
|
L_OPTIONS_003, // ""
|
|
(uintptr_t)&inv_menu_text_secondary_function,
|
|
NULL,
|
|
},
|
|
{
|
|
MENUITEMTYPE_MARQUEE,
|
|
0,
|
|
MENUITEMFLAG_SMALLFONT | MENUITEMFLAG_MARQUEE_FADEBOTHSIDES,
|
|
(uintptr_t)&inv_menu_text_weapon_description,
|
|
0,
|
|
NULL,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_SoloMissionInventoryMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_178, // "Inventory"
|
|
g_SoloMissionInventoryMenuItems,
|
|
inventory_menu_dialog,
|
|
#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,
|
|
inventory_menu_dialog,
|
|
MENUDIALOGFLAG_0002 | MENUDIALOGFLAG_DISABLERESIZE | MENUDIALOGFLAG_0400,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_fr_inventory_list(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 = fr_get_num_weapons_available();
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
g_FrFocusedSlotIndex = data->list.value;
|
|
return (s32)bgun_get_name(fr_get_weapon_by_slot(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 = fr_get_weapon_by_slot(data->list.value);
|
|
g_Menus[g_MpPlayerNum].training.weaponnum = g_InventoryWeapon;
|
|
g_FrFocusedSlotIndex = data->list.value;
|
|
|
|
// These items are labels
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[1], -1.0f); // manufacturer
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[2], -1.0f); // weapon name
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[4], -1.0f); // primary function
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[5], -1.0f); // secondary function
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_inventory_list(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
switch (operation) {
|
|
case MENUOP_GETOPTIONCOUNT:
|
|
data->list.value = inv_get_count();
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
return (s32)inv_get_name_by_index(data->list.value);
|
|
case MENUOP_SET:
|
|
{
|
|
s32 weaponnum = inv_get_weapon_num_by_index(data->list.value);
|
|
bool equippable = true;
|
|
|
|
if (weaponnum != WEAPON_NONE) {
|
|
s32 state = gset_get_device_state(weaponnum);
|
|
|
|
if (state != DEVICESTATE_UNEQUIPPED) {
|
|
equippable = false;
|
|
|
|
if (data->list.unk04 == 0) {
|
|
if (state == DEVICESTATE_INACTIVE) {
|
|
gset_set_device_active(weaponnum, true);
|
|
} else {
|
|
gset_set_device_active(weaponnum, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (equippable) {
|
|
inv_set_current_index(data->list.value);
|
|
|
|
if (inv_has_double_weapon_inc_all_guns(weaponnum, weaponnum)) {
|
|
bgun_equip_weapon2(HAND_RIGHT, weaponnum);
|
|
bgun_equip_weapon2(HAND_LEFT, weaponnum);
|
|
} else {
|
|
bgun_equip_weapon2(HAND_RIGHT, weaponnum);
|
|
bgun_equip_weapon2(HAND_LEFT, WEAPON_NONE);
|
|
}
|
|
}
|
|
|
|
var800711f0 = data->list.value;
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->list.value = inv_get_current_index();
|
|
break;
|
|
case MENUOP_GETLISTITEMCHECKBOX:
|
|
{
|
|
s32 weaponnum = inv_get_weapon_num_by_index(data->list.value);
|
|
|
|
if (weaponnum != WEAPON_NONE) {
|
|
s32 state = gset_get_device_state(weaponnum);
|
|
|
|
if (state != DEVICESTATE_UNEQUIPPED) {
|
|
data->list.unk04 = state;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MENUOP_LISTITEMFOCUS:
|
|
g_InventoryWeapon = inv_get_weapon_num_by_index(data->list.value);
|
|
g_Menus[g_MpPlayerNum].training.weaponnum = g_InventoryWeapon;
|
|
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[1], -1);
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[2], -1);
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[4], -1);
|
|
menu_set_item_redraw_timer(&g_SoloMissionInventoryMenuItems[5], -1);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_abort_mission(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Vars.currentplayer->aborted = true;
|
|
main_end_stage();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_abort_mission(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,
|
|
menuhandler_abort_mission,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_MissionAbortMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS_174, // "Warning"
|
|
g_MissionAbortMenuItems,
|
|
menudialog_abort_mission,
|
|
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,
|
|
menuhandler_abort_mission,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionAbortVMenuDialog = {
|
|
MENUDIALOGTYPE_DANGER,
|
|
L_OPTIONS_174, // "Warning"
|
|
g_2PMissionAbortVMenuItems,
|
|
menudialog_abort_mission,
|
|
0,
|
|
NULL,
|
|
};
|
|
|
|
MenuDialogHandlerResult solo_menu_dialog_pause_status(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 (lv_get_difficulty() == DIFF_A) {
|
|
wanttype = BRIEFINGTYPE_TEXT_A;
|
|
}
|
|
|
|
if (lv_get_difficulty() == 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 < objective_get_count(); i++) {
|
|
if (g_Objectives[i]) {
|
|
g_Briefing.objectivenames[i] = g_Objectives[i]->text;
|
|
g_Briefing.objectivedifficulties[i] = objective_get_difficulty_bits(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *solo_menu_title_pause_status(struct menudialogdef *dialogdef)
|
|
{
|
|
if (dialogdef != g_Menus[g_MpPlayerNum].curdialog->definition) {
|
|
return lang_get(L_OPTIONS_172); // "Status"
|
|
}
|
|
|
|
sprintf(g_StringPointer, "%s: %s\n",
|
|
lang_get(g_SoloStages[g_MissionConfig.stageindex].name3),
|
|
lang_get(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,
|
|
(uintptr_t)&solo_menu_title_pause_status,
|
|
g_MissionPauseMenuItems,
|
|
solo_menu_dialog_pause_status,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_SoloMissionInventoryMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionPauseHMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
(uintptr_t)&solo_menu_title_pause_status,
|
|
g_MissionPauseMenuItems,
|
|
solo_menu_dialog_pause_status,
|
|
MENUDIALOGFLAG_DISABLEITEMSCROLL | MENUDIALOGFLAG_SMOOTHSCROLLABLE,
|
|
&g_2PMissionInventoryHMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_2PMissionPauseVMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_172, // "Status"
|
|
g_2PMissionPauseVMenuItems,
|
|
solo_menu_dialog_pause_status,
|
|
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 get_num_completed_missions(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;
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_cinema(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[get_num_completed_missions()] + 1;
|
|
break;
|
|
case MENUOP_GETOPTIONTEXT:
|
|
if (data->list.value == 0) {
|
|
sprintf(g_StringPointer, lang_get(L_OPTIONS_448)); // "Play All"
|
|
return (s32) g_StringPointer;
|
|
}
|
|
return (s32) lang_get(g_Cutscenes[data->list.value - 1].name);
|
|
case MENUOP_SET:
|
|
if (data->list.value == 0) {
|
|
// Play all
|
|
s32 index = get_num_completed_missions();
|
|
g_Vars.autocutgroupcur = 0;
|
|
g_Vars.autocutgroupleft = g_CutsceneCountsByMission[index];
|
|
menu_pop_dialog();
|
|
menu_stop();
|
|
} else {
|
|
// Play specific cutscene
|
|
g_Vars.autocutgroupcur = data->list.value - 1;
|
|
g_Vars.autocutgroupleft = 1;
|
|
menu_pop_dialog();
|
|
menu_stop();
|
|
}
|
|
break;
|
|
case MENUOP_GETSELECTEDINDEX:
|
|
data->list.value = 0xfffff;
|
|
break;
|
|
case MENUOP_GETOPTGROUPCOUNT:
|
|
data->list.value = ARRAYCOUNT(groups);
|
|
break;
|
|
case MENUOP_GETOPTGROUPTEXT:
|
|
return (s32) lang_get(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,
|
|
menuhandler_cinema,
|
|
},
|
|
{ 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,
|
|
menuhandler_mission_list,
|
|
},
|
|
{ MENUITEMTYPE_END },
|
|
};
|
|
|
|
struct menudialogdef g_SelectMissionMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_122, // "Mission Select"
|
|
g_SelectMissionMenuItems,
|
|
NULL,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
NULL,
|
|
};
|
|
|
|
MenuItemHandlerResult menuhandler_main_menu_solo_missions(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_MissionConfig.iscoop = false;
|
|
g_MissionConfig.isanti = false;
|
|
menu_push_dialog(&g_SelectMissionMenuDialog);
|
|
}
|
|
|
|
if (operation == MENUOP_CHECKPREFOCUSED) {
|
|
if (is_stage_difficulty_unlocked(SOLOSTAGEINDEX_INVESTIGATION, DIFF_A)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_main_menu_combat_simulator(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_Vars.bondplayernum = 0;
|
|
g_Vars.coopplayernum = -1;
|
|
g_Vars.antiplayernum = -1;
|
|
challenge_determine_unlocked_features();
|
|
g_Vars.mpsetupmenu = MPSETUPMENU_GENERAL;
|
|
menu_save_and_push_root_dialog(&g_CombatSimulatorMenuDialog, MENUROOT_MPSETUP);
|
|
menu_hide_pressstart_labels();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_main_menu_cooperative(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_SET) {
|
|
g_MissionConfig.iscoop = true;
|
|
g_MissionConfig.isanti = false;
|
|
menu_push_dialog(&g_SelectMissionMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuItemHandlerResult menuhandler_main_menu_counter_operative(s32 operation, struct menuitem *item, union handlerdata *data)
|
|
{
|
|
if (operation == MENUOP_CHECKDISABLED) {
|
|
if ((joy_get_connected_controllers() & 2) == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (operation == MENUOP_SET) {
|
|
g_MissionConfig.iscoop = false;
|
|
g_MissionConfig.isanti = true;
|
|
menu_push_dialog(&g_SelectMissionMenuDialog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MenuDialogHandlerResult menudialog_main_menu(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 *main_menu_text_label(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 lang_get(withcheats[item->param]);
|
|
}
|
|
|
|
return lang_get(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,
|
|
(uintptr_t)&main_menu_text_label,
|
|
0x00000002,
|
|
menuhandler_main_menu_solo_missions,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
1,
|
|
MENUITEMFLAG_BIGFONT,
|
|
(uintptr_t)&main_menu_text_label,
|
|
0x00000003,
|
|
menuhandler_main_menu_combat_simulator,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
2,
|
|
MENUITEMFLAG_BIGFONT,
|
|
(uintptr_t)&main_menu_text_label,
|
|
0x00000004,
|
|
menuhandler_main_menu_cooperative,
|
|
},
|
|
{
|
|
MENUITEMTYPE_SELECTABLE,
|
|
3,
|
|
MENUITEMFLAG_BIGFONT,
|
|
(uintptr_t)&main_menu_text_label,
|
|
0x00000005,
|
|
menuhandler_main_menu_counter_operative,
|
|
},
|
|
{
|
|
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,
|
|
menudialog_main_menu,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
&g_CiOptionsViaPcMenuDialog,
|
|
};
|
|
|
|
struct menudialogdef g_CiMenuViaPauseMenuDialog = {
|
|
MENUDIALOGTYPE_DEFAULT,
|
|
L_OPTIONS_116, // "Perfect Menu"
|
|
g_MainMenuMenuItems,
|
|
menudialog_main_menu,
|
|
MENUDIALOGFLAG_STARTSELECTS,
|
|
&g_CiOptionsViaPauseMenuDialog,
|
|
};
|
|
|
|
bool solo_choose_pause_dialog(void)
|
|
{
|
|
if (g_Menus[g_MpPlayerNum].openinhibit == 0) {
|
|
g_Menus[g_MpPlayerNum].playernum = 0;
|
|
|
|
if (g_Vars.stagenum == STAGE_CITRAINING) {
|
|
bool handled = false;
|
|
|
|
if (ci_is_tour_done()) {
|
|
struct trainingdata *dtdata = dt_get_data();
|
|
s32 room = g_Vars.currentplayer->prop->rooms[0];
|
|
|
|
if (room >= ROOM_DISH_HOLO1 && room <= ROOM_DISH_HOLO4) {
|
|
struct trainingdata *htdata = get_holo_training_data();
|
|
|
|
if (htdata->intraining) {
|
|
menu_push_root_dialog(&g_HtDetailsMenuDialog, MENUROOT_TRAINING);
|
|
} else if (htdata->finished) {
|
|
ht_push_endscreen();
|
|
} else {
|
|
menu_push_root_dialog(&g_HtListMenuDialog, MENUROOT_TRAINING);
|
|
}
|
|
|
|
handled = true;
|
|
} else if (room == ROOM_DISH_DEVICELAB) {
|
|
if (dtdata->intraining) {
|
|
menu_push_root_dialog(&g_DtDetailsMenuDialog, MENUROOT_TRAINING);
|
|
} else if (dtdata->finished) {
|
|
dt_push_endscreen();
|
|
} else {
|
|
menu_push_root_dialog(&g_DtListMenuDialog, MENUROOT_TRAINING);
|
|
}
|
|
|
|
handled = true;
|
|
} else if (dtdata->intraining) {
|
|
menu_push_root_dialog(&g_DtDetailsMenuDialog, MENUROOT_TRAINING);
|
|
handled = true;
|
|
} else if (dtdata->finished) {
|
|
dt_push_endscreen();
|
|
handled = true;
|
|
} else if (room == ROOM_DISH_FIRINGRANGE) {
|
|
if (fr_is_in_training()) {
|
|
menu_push_root_dialog(&g_FrTrainingInfoInGameMenuDialog, MENUROOT_TRAINING);
|
|
} else {
|
|
menu_push_root_dialog(&g_FrWeaponListMenuDialog, MENUROOT_TRAINING);
|
|
}
|
|
|
|
handled = true;
|
|
}
|
|
}
|
|
|
|
if (!handled) {
|
|
menu_push_root_dialog(&g_CiMenuViaPauseMenuDialog, MENUROOT_MAINMENU);
|
|
return true;
|
|
}
|
|
} else {
|
|
menu_push_root_dialog(&g_SoloMissionPauseMenuDialog, MENUROOT_MAINMENU);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|