2022-02-10 06:15:28 +00:00
|
|
|
use itertools::Itertools;
|
|
|
|
|
2021-08-16 07:47:11 +00:00
|
|
|
use crate::framework::context::Context;
|
|
|
|
use crate::framework::error::GameResult;
|
2022-11-19 17:20:03 +00:00
|
|
|
use crate::framework::graphics::VSyncMode;
|
2022-11-20 19:38:36 +00:00
|
|
|
use crate::framework::{filesystem, graphics};
|
2022-11-19 17:20:03 +00:00
|
|
|
use crate::game::shared_game_state::{CutsceneSkipMode, ScreenShakeIntensity, SharedGameState, TimingMode, WindowMode};
|
2022-11-20 19:38:36 +00:00
|
|
|
use crate::graphics::font::Font;
|
2021-08-16 07:47:11 +00:00
|
|
|
use crate::input::combined_menu_controller::CombinedMenuController;
|
2022-11-19 17:20:03 +00:00
|
|
|
use crate::menu::MenuEntry;
|
2022-11-20 19:38:36 +00:00
|
|
|
use crate::menu::{Menu, MenuSelectionResult};
|
2022-03-15 01:54:03 +00:00
|
|
|
use crate::scene::title_scene::TitleScene;
|
2021-08-16 07:47:11 +00:00
|
|
|
use crate::sound::InterpolationMode;
|
2022-11-21 14:15:51 +00:00
|
|
|
use crate::util::browser;
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-07-30 20:20:53 +00:00
|
|
|
use super::controls_menu::ControlsMenu;
|
|
|
|
|
2021-08-16 07:47:11 +00:00
|
|
|
#[derive(PartialEq, Eq, Copy, Clone)]
|
|
|
|
#[repr(u8)]
|
|
|
|
#[allow(unused)]
|
|
|
|
enum CurrentMenu {
|
|
|
|
MainMenu,
|
|
|
|
GraphicsMenu,
|
|
|
|
SoundMenu,
|
2022-07-30 20:20:53 +00:00
|
|
|
ControlsMenu,
|
2022-02-10 06:15:28 +00:00
|
|
|
SoundtrackMenu,
|
2022-03-15 01:54:03 +00:00
|
|
|
LanguageMenu,
|
2022-07-25 08:41:20 +00:00
|
|
|
BehaviorMenu,
|
2022-08-28 21:06:58 +00:00
|
|
|
LinksMenu,
|
2023-02-17 14:05:38 +00:00
|
|
|
AdvancedMenu,
|
2023-02-23 12:27:53 +00:00
|
|
|
PortableMenu,
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum MainMenuEntry {
|
|
|
|
Graphics,
|
|
|
|
Sound,
|
2022-07-30 20:20:53 +00:00
|
|
|
Controls,
|
2022-07-24 14:52:51 +00:00
|
|
|
Language,
|
2022-07-25 08:41:20 +00:00
|
|
|
Behavior,
|
2022-08-28 21:06:58 +00:00
|
|
|
Links,
|
2023-02-17 14:05:38 +00:00
|
|
|
Advanced,
|
2022-07-24 14:52:51 +00:00
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for MainMenuEntry {
|
|
|
|
fn default() -> Self {
|
|
|
|
MainMenuEntry::Graphics
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum GraphicsMenuEntry {
|
|
|
|
VSyncMode,
|
2023-01-25 14:25:42 +00:00
|
|
|
WindowMode,
|
2022-07-24 14:52:51 +00:00
|
|
|
LightingEffects,
|
|
|
|
WeaponLightCone,
|
|
|
|
ScreenShake,
|
|
|
|
MotionInterpolation,
|
|
|
|
SubpixelScrolling,
|
|
|
|
OriginalTextures,
|
|
|
|
SeasonalTextures,
|
|
|
|
Renderer,
|
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for GraphicsMenuEntry {
|
|
|
|
fn default() -> Self {
|
2023-01-25 14:25:42 +00:00
|
|
|
GraphicsMenuEntry::VSyncMode
|
2022-07-24 14:52:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum SoundMenuEntry {
|
|
|
|
MusicVolume,
|
|
|
|
EffectsVolume,
|
|
|
|
BGMInterpolation,
|
|
|
|
Soundtrack,
|
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for SoundMenuEntry {
|
|
|
|
fn default() -> Self {
|
|
|
|
SoundMenuEntry::MusicVolume
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum SoundtrackMenuEntry {
|
|
|
|
Soundtrack(usize),
|
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for SoundtrackMenuEntry {
|
|
|
|
fn default() -> Self {
|
|
|
|
SoundtrackMenuEntry::Soundtrack(0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-26 00:17:45 +00:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
2022-07-24 14:52:51 +00:00
|
|
|
enum LanguageMenuEntry {
|
|
|
|
Title,
|
2022-08-26 00:17:45 +00:00
|
|
|
Language(String),
|
2022-07-24 14:52:51 +00:00
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for LanguageMenuEntry {
|
|
|
|
fn default() -> Self {
|
2022-08-26 00:17:45 +00:00
|
|
|
LanguageMenuEntry::Back
|
2022-07-24 14:52:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-25 08:41:20 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum BehaviorMenuEntry {
|
|
|
|
GameTiming,
|
|
|
|
PauseOnFocusLoss,
|
2022-08-23 22:27:39 +00:00
|
|
|
CutsceneSkipMode,
|
2023-02-18 18:42:00 +00:00
|
|
|
#[cfg(feature = "discord-rpc")]
|
|
|
|
DiscordRPC,
|
2022-07-25 08:41:20 +00:00
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for BehaviorMenuEntry {
|
|
|
|
fn default() -> Self {
|
|
|
|
BehaviorMenuEntry::GameTiming
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:06:58 +00:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
|
|
enum LinksMenuEntry {
|
|
|
|
Title,
|
|
|
|
Link(&'static str),
|
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for LinksMenuEntry {
|
|
|
|
fn default() -> Self {
|
|
|
|
LinksMenuEntry::Link(DISCORD_LINK)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-17 14:05:38 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum AdvancedMenuEntry {
|
|
|
|
Title,
|
|
|
|
OpenUserData,
|
|
|
|
OpenGameData,
|
2023-02-23 12:27:53 +00:00
|
|
|
#[cfg(not(any(target_os = "android", target_os = "horizon")))]
|
|
|
|
MakePortable,
|
2023-02-17 14:05:38 +00:00
|
|
|
Back,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for AdvancedMenuEntry {
|
|
|
|
fn default() -> Self {
|
|
|
|
AdvancedMenuEntry::OpenUserData
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-23 12:27:53 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
|
|
|
enum PortableMenuEntry {
|
|
|
|
Title,
|
|
|
|
Explanation,
|
|
|
|
RestartQuestion,
|
|
|
|
Yes,
|
|
|
|
No,
|
|
|
|
Spacer,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for PortableMenuEntry {
|
|
|
|
fn default() -> Self {
|
|
|
|
PortableMenuEntry::No
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-16 07:47:11 +00:00
|
|
|
pub struct SettingsMenu {
|
|
|
|
current: CurrentMenu,
|
2022-07-24 14:52:51 +00:00
|
|
|
main: Menu<MainMenuEntry>,
|
|
|
|
graphics: Menu<GraphicsMenuEntry>,
|
|
|
|
sound: Menu<SoundMenuEntry>,
|
|
|
|
soundtrack: Menu<SoundtrackMenuEntry>,
|
|
|
|
language: Menu<LanguageMenuEntry>,
|
2022-07-25 08:41:20 +00:00
|
|
|
behavior: Menu<BehaviorMenuEntry>,
|
2022-08-28 21:06:58 +00:00
|
|
|
links: Menu<LinksMenuEntry>,
|
2023-02-17 14:05:38 +00:00
|
|
|
advanced: Menu<AdvancedMenuEntry>,
|
2023-02-23 12:27:53 +00:00
|
|
|
portable: Menu<PortableMenuEntry>,
|
2022-07-30 20:20:53 +00:00
|
|
|
controls_menu: ControlsMenu,
|
2022-02-10 06:15:28 +00:00
|
|
|
pub on_title: bool,
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static DISCORD_LINK: &str = "https://discord.gg/fbRsNNB";
|
2022-08-28 21:06:58 +00:00
|
|
|
static GITHUB_LINK: &str = "https://github.com/doukutsu-rs/doukutsu-rs";
|
|
|
|
static DOCS_LINK: &str = "https://doukutsu-rs.gitbook.io/docs/";
|
|
|
|
static TRIBUTE_LINK: &str = "https://www.cavestory.org/";
|
|
|
|
static GENERAL_LINK: &str = "https://discord.gg/cavestory";
|
|
|
|
static MODDING_LINK: &str = "https://discord.gg/xRsWpz6";
|
|
|
|
static GETPLUS_LINK: &str = "https://www.nicalis.com/games/cavestory+";
|
2021-08-16 07:47:11 +00:00
|
|
|
|
|
|
|
impl SettingsMenu {
|
|
|
|
pub fn new() -> SettingsMenu {
|
2022-01-21 20:00:36 +00:00
|
|
|
let main = Menu::new(0, 0, 220, 0);
|
2021-08-16 07:47:11 +00:00
|
|
|
let graphics = Menu::new(0, 0, 180, 0);
|
|
|
|
let sound = Menu::new(0, 0, 260, 0);
|
2022-02-10 06:15:28 +00:00
|
|
|
let soundtrack = Menu::new(0, 0, 260, 0);
|
2022-03-15 01:54:03 +00:00
|
|
|
let language = Menu::new(0, 0, 120, 0);
|
2022-07-25 08:41:20 +00:00
|
|
|
let behavior = Menu::new(0, 0, 220, 0);
|
2022-08-28 21:06:58 +00:00
|
|
|
let links = Menu::new(0, 0, 220, 0);
|
2023-02-17 14:05:38 +00:00
|
|
|
let advanced = Menu::new(0, 0, 220, 0);
|
2023-02-23 12:27:53 +00:00
|
|
|
let portable = Menu::new(0, 0, 220, 0);
|
2022-07-25 08:41:20 +00:00
|
|
|
|
2022-07-30 20:20:53 +00:00
|
|
|
let controls_menu = ControlsMenu::new();
|
|
|
|
|
2022-07-25 08:41:20 +00:00
|
|
|
SettingsMenu {
|
|
|
|
current: CurrentMenu::MainMenu,
|
|
|
|
main,
|
|
|
|
graphics,
|
|
|
|
sound,
|
|
|
|
soundtrack,
|
|
|
|
language,
|
|
|
|
behavior,
|
2022-08-28 21:06:58 +00:00
|
|
|
links,
|
2023-02-17 14:05:38 +00:00
|
|
|
advanced,
|
2022-07-30 20:20:53 +00:00
|
|
|
controls_menu,
|
2023-02-23 12:27:53 +00:00
|
|
|
portable,
|
2022-07-25 08:41:20 +00:00
|
|
|
on_title: false,
|
|
|
|
}
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
2022-07-24 14:52:51 +00:00
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::VSyncMode,
|
|
|
|
MenuEntry::DescriptiveOptions(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.entry").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.vsync_mode as usize,
|
|
|
|
vec![
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.uncapped").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vsync").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_1x").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_2x").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_3x").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
],
|
|
|
|
vec![
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.uncapped_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vsync_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_1x_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_2x_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_3x_desc").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
2023-01-25 17:23:15 +00:00
|
|
|
#[cfg(not(any(target_os = "android", target_os = "horizon")))]
|
2023-01-25 14:25:42 +00:00
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::WindowMode,
|
|
|
|
MenuEntry::Options(
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.window_mode.entry").to_owned(),
|
|
|
|
state.settings.window_mode as usize,
|
|
|
|
vec![
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.window_mode.windowed").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.window_mode.fullscreen").to_owned(),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
2022-07-24 14:52:51 +00:00
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::LightingEffects,
|
|
|
|
MenuEntry::Toggle(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.lighting_effects").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.shader_effects,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::WeaponLightCone,
|
2022-11-20 19:38:36 +00:00
|
|
|
MenuEntry::Toggle(
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.weapon_light_cone").to_owned(),
|
|
|
|
state.settings.light_cone,
|
|
|
|
),
|
2022-07-24 14:52:51 +00:00
|
|
|
);
|
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::ScreenShake,
|
|
|
|
MenuEntry::Options(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.screen_shake.entry").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.screen_shake_intensity as usize,
|
|
|
|
vec![
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.screen_shake.full").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.screen_shake.half").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.graphics_menu.screen_shake.off").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::MotionInterpolation,
|
|
|
|
MenuEntry::Toggle(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.motion_interpolation").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.motion_interpolation,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::SubpixelScrolling,
|
|
|
|
MenuEntry::Toggle(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.subpixel_scrolling").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.subpixel_coords,
|
|
|
|
),
|
|
|
|
);
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-02-10 07:54:20 +00:00
|
|
|
// NS version uses two different maps, therefore we can't dynamically switch between graphics presets.
|
2022-11-19 11:21:10 +00:00
|
|
|
if state.constants.supports_og_textures {
|
2022-02-10 07:54:20 +00:00
|
|
|
if !state.constants.is_switch || self.on_title {
|
2022-07-24 14:52:51 +00:00
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::OriginalTextures,
|
|
|
|
MenuEntry::Toggle(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.original_textures").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.original_textures,
|
|
|
|
),
|
|
|
|
);
|
2022-02-10 07:54:20 +00:00
|
|
|
} else {
|
2022-07-24 14:52:51 +00:00
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::OriginalTextures,
|
2022-11-20 19:38:36 +00:00
|
|
|
MenuEntry::Disabled(state.loc.t("menus.options_menu.graphics_menu.original_textures").to_owned()),
|
2022-07-24 14:52:51 +00:00
|
|
|
);
|
2022-02-10 07:54:20 +00:00
|
|
|
}
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if state.constants.is_cs_plus {
|
2022-07-24 14:52:51 +00:00
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::SeasonalTextures,
|
|
|
|
MenuEntry::Toggle(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.seasonal_textures").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.seasonal_textures,
|
|
|
|
),
|
|
|
|
);
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
self.graphics.push_entry(
|
|
|
|
GraphicsMenuEntry::Renderer,
|
|
|
|
MenuEntry::Disabled(format!(
|
|
|
|
"{} {}",
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.graphics_menu.renderer").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
ctx.renderer.as_ref().unwrap().renderer_name()
|
|
|
|
)),
|
|
|
|
);
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.graphics.push_entry(GraphicsMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-11-21 14:15:51 +00:00
|
|
|
self.main.push_entry(
|
|
|
|
MainMenuEntry::Graphics,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.graphics").to_owned()),
|
|
|
|
);
|
2022-11-20 19:38:36 +00:00
|
|
|
self.main
|
2022-11-21 14:15:51 +00:00
|
|
|
.push_entry(MainMenuEntry::Sound, MenuEntry::Active(state.loc.t("menus.options_menu.sound").to_owned()));
|
2022-07-24 14:52:51 +00:00
|
|
|
|
2022-07-30 20:20:53 +00:00
|
|
|
#[cfg(not(target_os = "android"))]
|
2022-11-21 14:15:51 +00:00
|
|
|
self.main.push_entry(
|
|
|
|
MainMenuEntry::Controls,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.controls").to_owned()),
|
|
|
|
);
|
2022-07-30 20:20:53 +00:00
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.language.push_entry(
|
|
|
|
LanguageMenuEntry::Title,
|
|
|
|
MenuEntry::Disabled(state.loc.t("menus.options_menu.language").to_owned()),
|
|
|
|
);
|
2022-03-15 01:54:03 +00:00
|
|
|
|
2022-08-26 00:17:45 +00:00
|
|
|
for locale in &state.constants.locales {
|
|
|
|
self.language
|
|
|
|
.push_entry(LanguageMenuEntry::Language(locale.code.clone()), MenuEntry::Active(locale.name.clone()));
|
2022-03-15 01:54:03 +00:00
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.language.push_entry(LanguageMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
2022-03-15 01:54:03 +00:00
|
|
|
|
|
|
|
if self.on_title {
|
2022-11-20 19:38:36 +00:00
|
|
|
self.main.push_entry(
|
|
|
|
MainMenuEntry::Language,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.language").to_owned()),
|
|
|
|
);
|
2022-03-15 01:54:03 +00:00
|
|
|
}
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-11-21 14:15:51 +00:00
|
|
|
self.main.push_entry(
|
|
|
|
MainMenuEntry::Behavior,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.behavior").to_owned()),
|
|
|
|
);
|
2022-07-24 14:52:51 +00:00
|
|
|
|
2022-11-21 14:15:51 +00:00
|
|
|
self.main
|
|
|
|
.push_entry(MainMenuEntry::Links, MenuEntry::Active(state.loc.t("menus.options_menu.links").to_owned()));
|
2022-08-28 21:06:58 +00:00
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.links
|
|
|
|
.push_entry(LinksMenuEntry::Title, MenuEntry::Disabled(state.loc.t("menus.options_menu.links").to_owned()));
|
2022-08-28 21:06:58 +00:00
|
|
|
self.links.push_entry(LinksMenuEntry::Link(DISCORD_LINK), MenuEntry::Active("doukutsu-rs Discord".to_owned()));
|
|
|
|
self.links.push_entry(LinksMenuEntry::Link(GITHUB_LINK), MenuEntry::Active("doukutsu-rs GitHub".to_owned()));
|
|
|
|
self.links.push_entry(LinksMenuEntry::Link(DOCS_LINK), MenuEntry::Active("doukutsu-rs Docs".to_owned()));
|
2022-09-17 10:57:37 +00:00
|
|
|
self.links
|
|
|
|
.push_entry(LinksMenuEntry::Link(TRIBUTE_LINK), MenuEntry::Active("Cave Story Tribute Website".to_owned()));
|
2022-08-28 21:06:58 +00:00
|
|
|
self.links.push_entry(LinksMenuEntry::Link(GENERAL_LINK), MenuEntry::Active("Cave Story Discord".to_owned()));
|
2022-09-17 10:57:37 +00:00
|
|
|
self.links.push_entry(
|
|
|
|
LinksMenuEntry::Link(MODDING_LINK),
|
|
|
|
MenuEntry::Active("Cave Story Modding Community".to_owned()),
|
|
|
|
);
|
2022-08-28 21:06:58 +00:00
|
|
|
self.links.push_entry(LinksMenuEntry::Link(GETPLUS_LINK), MenuEntry::Active("Get Cave Story+".to_owned()));
|
2022-07-24 14:52:51 +00:00
|
|
|
|
2023-02-17 14:05:38 +00:00
|
|
|
#[cfg(not(any(target_os = "android", target_os = "horizon")))]
|
|
|
|
self.main.push_entry(
|
|
|
|
MainMenuEntry::Advanced,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.advanced").to_owned()),
|
|
|
|
);
|
|
|
|
|
|
|
|
self.advanced.push_entry(
|
|
|
|
AdvancedMenuEntry::Title,
|
|
|
|
MenuEntry::Disabled(state.loc.t("menus.options_menu.advanced").to_owned()),
|
|
|
|
);
|
|
|
|
self.advanced.push_entry(
|
|
|
|
AdvancedMenuEntry::OpenUserData,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.advanced_menu.open_user_data").to_owned()),
|
|
|
|
);
|
|
|
|
self.advanced.push_entry(
|
|
|
|
AdvancedMenuEntry::OpenGameData,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.advanced_menu.open_game_data").to_owned()),
|
|
|
|
);
|
2023-02-23 12:27:53 +00:00
|
|
|
|
|
|
|
#[cfg(not(any(target_os = "android", target_os = "horizon")))]
|
|
|
|
if let Some(fs_container) = &state.fs_container {
|
|
|
|
if !fs_container.is_portable && self.on_title {
|
|
|
|
self.advanced.push_entry(
|
|
|
|
AdvancedMenuEntry::MakePortable,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.advanced_menu.make_portable").to_owned()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-17 14:05:38 +00:00
|
|
|
self.advanced.push_entry(AdvancedMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
|
|
|
|
2023-02-23 12:27:53 +00:00
|
|
|
self.portable.center_options = true;
|
|
|
|
|
|
|
|
self.portable.push_entry(
|
|
|
|
PortableMenuEntry::Title,
|
|
|
|
MenuEntry::Title(state.loc.t("menus.options_menu.advanced_menu.make_portable").to_owned(), true, false),
|
|
|
|
);
|
|
|
|
|
|
|
|
self.portable.push_entry(PortableMenuEntry::Spacer, MenuEntry::Spacer(8.0));
|
|
|
|
|
|
|
|
self.portable.push_entry(
|
|
|
|
PortableMenuEntry::Explanation,
|
|
|
|
MenuEntry::LongText(state.loc.t("menus.options_menu.portable_menu.explanation").to_owned(), true, true),
|
|
|
|
);
|
|
|
|
|
|
|
|
self.portable.push_entry(PortableMenuEntry::Spacer, MenuEntry::Spacer(8.0));
|
|
|
|
|
|
|
|
self.portable.push_entry(
|
|
|
|
PortableMenuEntry::RestartQuestion,
|
|
|
|
MenuEntry::LongText(
|
|
|
|
state.loc.t("menus.options_menu.portable_menu.restart_question").to_owned(),
|
|
|
|
true,
|
|
|
|
true,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
self.portable.push_entry(PortableMenuEntry::Spacer, MenuEntry::Spacer(8.0));
|
|
|
|
|
|
|
|
self.portable.push_entry(
|
|
|
|
PortableMenuEntry::Yes,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.portable_menu.restart").to_owned()),
|
|
|
|
);
|
|
|
|
|
|
|
|
self.portable.push_entry(
|
|
|
|
PortableMenuEntry::No,
|
|
|
|
MenuEntry::Active(state.loc.t("menus.options_menu.portable_menu.cancel").to_owned()),
|
|
|
|
);
|
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.main.push_entry(MainMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
2022-07-24 14:52:51 +00:00
|
|
|
|
|
|
|
self.sound.push_entry(
|
|
|
|
SoundMenuEntry::MusicVolume,
|
2022-11-21 14:15:51 +00:00
|
|
|
MenuEntry::OptionsBar(
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.music_volume").to_owned(),
|
|
|
|
state.settings.bgm_volume,
|
|
|
|
),
|
2022-07-24 14:52:51 +00:00
|
|
|
);
|
|
|
|
self.sound.push_entry(
|
|
|
|
SoundMenuEntry::EffectsVolume,
|
2022-11-21 14:15:51 +00:00
|
|
|
MenuEntry::OptionsBar(
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.effects_volume").to_owned(),
|
|
|
|
state.settings.sfx_volume,
|
|
|
|
),
|
2022-07-24 14:52:51 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
self.sound.push_entry(
|
|
|
|
SoundMenuEntry::BGMInterpolation,
|
|
|
|
MenuEntry::DescriptiveOptions(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.entry").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
state.settings.organya_interpolation as usize,
|
|
|
|
vec![
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.nearest").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.linear").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.cosine").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.cubic").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.linear_lp").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
],
|
|
|
|
vec![
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.nearest_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.linear_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.cosine_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.cubic_desc").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.sound_menu.bgm_interpolation.linear_lp_desc").to_owned(),
|
2022-07-24 14:52:51 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
self.sound.push_entry(
|
|
|
|
SoundMenuEntry::Soundtrack,
|
2022-09-17 10:57:37 +00:00
|
|
|
MenuEntry::Active(
|
|
|
|
state.tt(
|
|
|
|
"menus.options_menu.sound_menu.soundtrack",
|
|
|
|
&[("soundtrack", state.settings.soundtrack.as_str())],
|
|
|
|
),
|
|
|
|
),
|
2022-07-24 14:52:51 +00:00
|
|
|
);
|
2022-11-20 19:38:36 +00:00
|
|
|
self.sound.push_entry(SoundMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-03-07 13:47:37 +00:00
|
|
|
let mut soundtrack_entries =
|
|
|
|
state.constants.soundtracks.iter().filter(|s| s.available).map(|s| s.name.to_owned()).collect_vec();
|
2022-02-10 06:15:28 +00:00
|
|
|
soundtrack_entries.push("Organya".to_owned());
|
|
|
|
|
|
|
|
if let Ok(dir) = filesystem::read_dir(ctx, "/Soundtracks/") {
|
|
|
|
for entry in dir {
|
|
|
|
if filesystem::is_dir(ctx, &entry) {
|
|
|
|
let filename = entry.file_name().unwrap().to_string_lossy().to_string();
|
|
|
|
|
|
|
|
if !soundtrack_entries.contains(&filename) {
|
|
|
|
soundtrack_entries.push(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
soundtrack_entries.sort();
|
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
for (idx, soundtrack) in soundtrack_entries.iter().enumerate() {
|
|
|
|
self.soundtrack.push_entry(SoundtrackMenuEntry::Soundtrack(idx), MenuEntry::Active(soundtrack.to_string()));
|
2022-02-10 06:15:28 +00:00
|
|
|
}
|
|
|
|
|
2022-02-10 23:37:08 +00:00
|
|
|
self.soundtrack.width = soundtrack_entries
|
|
|
|
.into_iter()
|
2022-11-20 19:38:36 +00:00
|
|
|
.map(|str| state.font.builder().compute_width(&str))
|
2022-02-10 23:37:08 +00:00
|
|
|
.max_by(|a, b| a.abs().partial_cmp(&b.abs()).unwrap())
|
|
|
|
.unwrap_or(self.soundtrack.width as f32) as u16
|
|
|
|
+ 32;
|
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.soundtrack.push_entry(SoundtrackMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
2022-02-10 06:15:28 +00:00
|
|
|
|
2022-07-25 08:41:20 +00:00
|
|
|
self.behavior.push_entry(
|
|
|
|
BehaviorMenuEntry::GameTiming,
|
|
|
|
MenuEntry::Options(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.behavior_menu.game_timing.entry").to_owned(),
|
2022-07-25 08:41:20 +00:00
|
|
|
if state.settings.timing_mode == TimingMode::_50Hz { 0 } else { 1 },
|
|
|
|
vec![
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.behavior_menu.game_timing.50tps").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.behavior_menu.game_timing.60tps").to_owned(),
|
2022-07-25 08:41:20 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
self.behavior.push_entry(
|
|
|
|
BehaviorMenuEntry::PauseOnFocusLoss,
|
|
|
|
MenuEntry::Toggle(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.behavior_menu.pause_on_focus_loss").to_owned(),
|
2022-07-25 08:41:20 +00:00
|
|
|
state.settings.pause_on_focus_loss,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2022-08-23 22:27:39 +00:00
|
|
|
self.behavior.push_entry(
|
|
|
|
BehaviorMenuEntry::CutsceneSkipMode,
|
|
|
|
MenuEntry::Options(
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.behavior_menu.cutscene_skip_method.entry").to_owned(),
|
2022-08-23 22:27:39 +00:00
|
|
|
if state.settings.cutscene_skip_mode == CutsceneSkipMode::Hold { 0 } else { 1 },
|
|
|
|
vec![
|
2022-11-20 19:38:36 +00:00
|
|
|
state.loc.t("menus.options_menu.behavior_menu.cutscene_skip_method.hold").to_owned(),
|
|
|
|
state.loc.t("menus.options_menu.behavior_menu.cutscene_skip_method.fastforward").to_owned(),
|
2022-08-23 22:27:39 +00:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2023-02-18 18:42:00 +00:00
|
|
|
#[cfg(feature = "discord-rpc")]
|
|
|
|
self.behavior.push_entry(
|
|
|
|
BehaviorMenuEntry::DiscordRPC,
|
|
|
|
MenuEntry::Toggle(
|
|
|
|
state.loc.t("menus.options_menu.behavior_menu.discord_rpc").to_owned(),
|
|
|
|
state.settings.discord_rpc,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.behavior.push_entry(BehaviorMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
2022-07-25 08:41:20 +00:00
|
|
|
|
2022-11-20 19:38:36 +00:00
|
|
|
self.links.push_entry(LinksMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
2022-08-28 21:06:58 +00:00
|
|
|
|
2022-07-30 20:20:53 +00:00
|
|
|
self.controls_menu.init(state, ctx)?;
|
|
|
|
|
2021-08-16 07:47:11 +00:00
|
|
|
self.update_sizes(state);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn update_sizes(&mut self, state: &SharedGameState) {
|
2022-03-15 01:54:03 +00:00
|
|
|
self.main.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.main.update_height(state);
|
2021-08-16 07:47:11 +00:00
|
|
|
self.main.x = ((state.canvas_size.0 - self.main.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.main.y = 30 + ((state.canvas_size.1 - self.main.height as f32) / 2.0).floor() as isize;
|
|
|
|
|
2022-03-15 01:54:03 +00:00
|
|
|
self.graphics.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.graphics.update_height(state);
|
2021-08-16 07:47:11 +00:00
|
|
|
self.graphics.x = ((state.canvas_size.0 - self.graphics.width as f32) / 2.0).floor() as isize;
|
2022-07-09 15:06:22 +00:00
|
|
|
self.graphics.y = 20 + ((state.canvas_size.1 - self.graphics.height as f32) / 2.0).floor() as isize;
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-03-15 01:54:03 +00:00
|
|
|
self.sound.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.sound.update_height(state);
|
2021-08-16 07:47:11 +00:00
|
|
|
self.sound.x = ((state.canvas_size.0 - self.sound.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.sound.y = 30 + ((state.canvas_size.1 - self.sound.height as f32) / 2.0).floor() as isize;
|
2022-02-10 06:15:28 +00:00
|
|
|
|
2022-03-15 01:54:03 +00:00
|
|
|
self.soundtrack.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.soundtrack.update_height(state);
|
2022-02-10 06:15:28 +00:00
|
|
|
self.soundtrack.x = ((state.canvas_size.0 - self.soundtrack.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.soundtrack.y = ((state.canvas_size.1 - self.soundtrack.height as f32) / 2.0).floor() as isize;
|
2022-03-15 01:54:03 +00:00
|
|
|
|
|
|
|
self.language.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.language.update_height(state);
|
2022-03-15 01:54:03 +00:00
|
|
|
self.language.x = ((state.canvas_size.0 - self.language.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.language.y = ((state.canvas_size.1 - self.language.height as f32) / 2.0).floor() as isize;
|
2022-07-25 08:41:20 +00:00
|
|
|
|
|
|
|
self.behavior.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.behavior.update_height(state);
|
2022-07-25 08:41:20 +00:00
|
|
|
self.behavior.x = ((state.canvas_size.0 - self.behavior.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.behavior.y = 30 + ((state.canvas_size.1 - self.behavior.height as f32) / 2.0).floor() as isize;
|
2022-08-28 21:06:58 +00:00
|
|
|
|
|
|
|
self.links.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.links.update_height(state);
|
2022-08-28 21:06:58 +00:00
|
|
|
self.links.x = ((state.canvas_size.0 - self.links.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.links.y = 30 + ((state.canvas_size.1 - self.links.height as f32) / 2.0).floor() as isize;
|
2023-02-17 14:05:38 +00:00
|
|
|
|
|
|
|
self.advanced.update_width(state);
|
2023-02-23 12:27:53 +00:00
|
|
|
self.advanced.update_height(state);
|
2023-02-17 14:05:38 +00:00
|
|
|
self.advanced.x = ((state.canvas_size.0 - self.advanced.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.advanced.y = 30 + ((state.canvas_size.1 - self.advanced.height as f32) / 2.0).floor() as isize;
|
2023-02-23 12:27:53 +00:00
|
|
|
|
|
|
|
self.portable.update_width(state);
|
|
|
|
self.portable.update_height(state);
|
|
|
|
self.portable.x = ((state.canvas_size.0 - self.portable.width as f32) / 2.0).floor() as isize;
|
|
|
|
self.portable.y = 30 + ((state.canvas_size.1 - self.portable.height as f32) / 2.0).floor() as isize;
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn tick(
|
|
|
|
&mut self,
|
|
|
|
exit_action: &mut dyn FnMut(),
|
|
|
|
controller: &mut CombinedMenuController,
|
|
|
|
state: &mut SharedGameState,
|
|
|
|
ctx: &mut Context,
|
|
|
|
) -> GameResult {
|
|
|
|
self.update_sizes(state);
|
|
|
|
|
|
|
|
match self.current {
|
|
|
|
CurrentMenu::MainMenu => match self.main.tick(controller, state) {
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Graphics, _) => {
|
2021-08-16 07:47:11 +00:00
|
|
|
self.current = CurrentMenu::GraphicsMenu;
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Sound, _) => {
|
2021-08-16 07:47:11 +00:00
|
|
|
self.current = CurrentMenu::SoundMenu;
|
|
|
|
}
|
2022-07-30 20:20:53 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Controls, _) => {
|
|
|
|
self.current = CurrentMenu::ControlsMenu;
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Language, _) => {
|
2022-03-15 01:54:03 +00:00
|
|
|
self.current = CurrentMenu::LanguageMenu;
|
|
|
|
}
|
2022-07-25 08:41:20 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Behavior, _) => {
|
|
|
|
self.current = CurrentMenu::BehaviorMenu;
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
2022-08-28 21:06:58 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Links, _) => {
|
|
|
|
self.current = CurrentMenu::LinksMenu;
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
2023-02-17 14:05:38 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Advanced, _) => {
|
|
|
|
self.current = CurrentMenu::AdvancedMenu;
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(MainMenuEntry::Back, _) | MenuSelectionResult::Canceled => exit_action(),
|
2021-08-16 07:47:11 +00:00
|
|
|
_ => (),
|
|
|
|
},
|
|
|
|
CurrentMenu::GraphicsMenu => match self.graphics.tick(controller, state) {
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::WindowMode, toggle)
|
|
|
|
| MenuSelectionResult::Right(GraphicsMenuEntry::WindowMode, toggle, _)
|
|
|
|
| MenuSelectionResult::Left(GraphicsMenuEntry::WindowMode, toggle, _) => {
|
2022-07-13 14:03:17 +00:00
|
|
|
if let MenuEntry::Options(_, value, _) = toggle {
|
|
|
|
let (new_mode, new_value) = match *value {
|
|
|
|
0 => (WindowMode::Fullscreen, 1),
|
|
|
|
1 => (WindowMode::Windowed, 0),
|
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
|
|
|
|
|
|
|
*value = new_value;
|
|
|
|
state.settings.window_mode = new_mode;
|
|
|
|
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::VSyncMode, toggle)
|
|
|
|
| MenuSelectionResult::Right(GraphicsMenuEntry::VSyncMode, toggle, _) => {
|
2022-04-15 00:51:48 +00:00
|
|
|
if let MenuEntry::DescriptiveOptions(_, value, _, _) = toggle {
|
|
|
|
let (new_mode, new_value) = match *value {
|
|
|
|
0 => (VSyncMode::VSync, 1),
|
|
|
|
1 => (VSyncMode::VRRTickSync1x, 2),
|
|
|
|
2 => (VSyncMode::VRRTickSync2x, 3),
|
|
|
|
3 => (VSyncMode::VRRTickSync3x, 4),
|
|
|
|
_ => (VSyncMode::Uncapped, 0),
|
|
|
|
};
|
|
|
|
|
|
|
|
*value = new_value;
|
|
|
|
state.settings.vsync_mode = new_mode;
|
2022-04-15 02:15:25 +00:00
|
|
|
graphics::set_vsync_mode(ctx, new_mode)?;
|
|
|
|
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Left(GraphicsMenuEntry::VSyncMode, toggle, _) => {
|
2022-04-15 02:15:25 +00:00
|
|
|
if let MenuEntry::DescriptiveOptions(_, value, _, _) = toggle {
|
|
|
|
let (new_mode, new_value) = match *value {
|
|
|
|
0 => (VSyncMode::VRRTickSync3x, 4),
|
|
|
|
1 => (VSyncMode::Uncapped, 0),
|
|
|
|
2 => (VSyncMode::VSync, 1),
|
|
|
|
3 => (VSyncMode::VRRTickSync1x, 2),
|
|
|
|
_ => (VSyncMode::VRRTickSync2x, 3),
|
|
|
|
};
|
|
|
|
|
|
|
|
*value = new_value;
|
|
|
|
state.settings.vsync_mode = new_mode;
|
|
|
|
graphics::set_vsync_mode(ctx, new_mode)?;
|
2022-04-15 00:51:48 +00:00
|
|
|
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::LightingEffects, toggle) => {
|
2021-08-16 07:47:11 +00:00
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.shader_effects = !state.settings.shader_effects;
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.shader_effects;
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::WeaponLightCone, toggle) => {
|
2021-10-10 00:31:07 +00:00
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.light_cone = !state.settings.light_cone;
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.light_cone;
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::ScreenShake, toggle)
|
|
|
|
| MenuSelectionResult::Right(GraphicsMenuEntry::ScreenShake, toggle, _) => {
|
2022-07-09 15:06:22 +00:00
|
|
|
if let MenuEntry::Options(_, value, _) = toggle {
|
|
|
|
let (new_intensity, new_value) = match *value {
|
|
|
|
0 => (ScreenShakeIntensity::Half, 1),
|
|
|
|
1 => (ScreenShakeIntensity::Off, 2),
|
|
|
|
_ => (ScreenShakeIntensity::Full, 0),
|
|
|
|
};
|
|
|
|
|
|
|
|
*value = new_value;
|
|
|
|
state.settings.screen_shake_intensity = new_intensity;
|
|
|
|
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Left(GraphicsMenuEntry::ScreenShake, toggle, _) => {
|
2022-07-09 15:06:22 +00:00
|
|
|
if let MenuEntry::Options(_, value, _) = toggle {
|
|
|
|
let (new_intensity, new_value) = match *value {
|
|
|
|
0 => (ScreenShakeIntensity::Off, 2),
|
|
|
|
1 => (ScreenShakeIntensity::Full, 0),
|
|
|
|
_ => (ScreenShakeIntensity::Half, 1),
|
|
|
|
};
|
|
|
|
|
|
|
|
*value = new_value;
|
|
|
|
state.settings.screen_shake_intensity = new_intensity;
|
|
|
|
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::MotionInterpolation, toggle) => {
|
2021-08-16 07:47:11 +00:00
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.motion_interpolation = !state.settings.motion_interpolation;
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.motion_interpolation;
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::SubpixelScrolling, toggle) => {
|
2021-08-16 07:47:11 +00:00
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.subpixel_coords = !state.settings.subpixel_coords;
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.subpixel_coords;
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::OriginalTextures, toggle) => {
|
2021-08-16 07:47:11 +00:00
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.original_textures = !state.settings.original_textures;
|
2022-03-09 02:37:44 +00:00
|
|
|
if self.on_title {
|
|
|
|
state.reload_resources(ctx)?;
|
|
|
|
} else {
|
|
|
|
state.reload_graphics();
|
|
|
|
}
|
2021-08-16 07:47:11 +00:00
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.original_textures;
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::SeasonalTextures, toggle) => {
|
2021-08-16 07:47:11 +00:00
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.seasonal_textures = !state.settings.seasonal_textures;
|
2022-02-10 07:54:20 +00:00
|
|
|
state.reload_graphics();
|
2021-08-16 07:47:11 +00:00
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.seasonal_textures;
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(GraphicsMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
2021-08-16 07:47:11 +00:00
|
|
|
self.current = CurrentMenu::MainMenu
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
},
|
|
|
|
CurrentMenu::SoundMenu => match self.sound.tick(controller, state) {
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Left(SoundMenuEntry::MusicVolume, bgm, direction)
|
|
|
|
| MenuSelectionResult::Right(SoundMenuEntry::MusicVolume, bgm, direction) => {
|
2022-02-03 03:09:29 +00:00
|
|
|
if let MenuEntry::OptionsBar(_, value) = bgm {
|
2022-05-14 13:18:50 +00:00
|
|
|
*value = (*value * 10.0 + (direction as f32)).clamp(0.0, 10.0) / 10.0;
|
2022-02-03 03:09:29 +00:00
|
|
|
state.settings.bgm_volume = *value;
|
|
|
|
state.sound_manager.set_song_volume(*value);
|
|
|
|
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Left(SoundMenuEntry::EffectsVolume, sfx, direction)
|
|
|
|
| MenuSelectionResult::Right(SoundMenuEntry::EffectsVolume, sfx, direction) => {
|
2022-02-03 03:09:29 +00:00
|
|
|
if let MenuEntry::OptionsBar(_, value) = sfx {
|
2022-05-14 13:18:50 +00:00
|
|
|
*value = (*value * 10.0 + (direction as f32)).clamp(0.0, 10.0) / 10.0;
|
2022-02-03 03:09:29 +00:00
|
|
|
state.settings.sfx_volume = *value;
|
|
|
|
state.sound_manager.set_sfx_volume(*value);
|
|
|
|
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-09-17 10:57:37 +00:00
|
|
|
MenuSelectionResult::Selected(SoundMenuEntry::BGMInterpolation, toggle)
|
2022-09-16 19:08:19 +00:00
|
|
|
| MenuSelectionResult::Right(SoundMenuEntry::BGMInterpolation, toggle, _) => {
|
2022-01-17 19:34:37 +00:00
|
|
|
if let MenuEntry::DescriptiveOptions(_, value, _, _) = toggle {
|
2021-08-16 07:47:11 +00:00
|
|
|
let (new_mode, new_value) = match *value {
|
|
|
|
0 => (InterpolationMode::Linear, 1),
|
|
|
|
1 => (InterpolationMode::Cosine, 2),
|
|
|
|
2 => (InterpolationMode::Cubic, 3),
|
|
|
|
3 => (InterpolationMode::Polyphase, 4),
|
|
|
|
_ => (InterpolationMode::Nearest, 0),
|
|
|
|
};
|
2022-09-17 10:57:37 +00:00
|
|
|
|
2021-08-16 07:47:11 +00:00
|
|
|
*value = new_value;
|
|
|
|
state.settings.organya_interpolation = new_mode;
|
|
|
|
state.sound_manager.set_org_interpolation(new_mode);
|
2022-09-16 19:08:19 +00:00
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MenuSelectionResult::Left(SoundMenuEntry::BGMInterpolation, toggle, _) => {
|
|
|
|
if let MenuEntry::DescriptiveOptions(_, value, _, _) = toggle {
|
|
|
|
let (new_mode, new_value) = match *value {
|
|
|
|
0 => (InterpolationMode::Polyphase, 4),
|
|
|
|
1 => (InterpolationMode::Nearest, 0),
|
|
|
|
2 => (InterpolationMode::Linear, 1),
|
|
|
|
3 => (InterpolationMode::Cosine, 2),
|
|
|
|
_ => (InterpolationMode::Cubic, 3),
|
|
|
|
};
|
2021-08-16 07:47:11 +00:00
|
|
|
|
2022-09-16 19:08:19 +00:00
|
|
|
*value = new_value;
|
|
|
|
state.settings.organya_interpolation = new_mode;
|
|
|
|
state.sound_manager.set_org_interpolation(new_mode);
|
2021-08-16 07:47:11 +00:00
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(SoundMenuEntry::Soundtrack, _) => {
|
|
|
|
let mut active_soundtrack = SoundtrackMenuEntry::Soundtrack(0);
|
2022-02-23 21:37:02 +00:00
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
for (id, entry) in &self.soundtrack.entries {
|
2022-02-23 21:37:02 +00:00
|
|
|
if let MenuEntry::Active(soundtrack) = entry {
|
|
|
|
if soundtrack == &state.settings.soundtrack {
|
2022-07-24 14:52:51 +00:00
|
|
|
active_soundtrack = *id;
|
2022-04-15 00:51:48 +00:00
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
break;
|
2022-02-23 21:37:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
self.soundtrack.selected = active_soundtrack;
|
2022-02-23 21:37:02 +00:00
|
|
|
|
|
|
|
self.current = CurrentMenu::SoundtrackMenu
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(SoundMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
2021-08-16 07:47:11 +00:00
|
|
|
self.current = CurrentMenu::MainMenu
|
|
|
|
}
|
|
|
|
_ => (),
|
2022-02-03 03:09:29 +00:00
|
|
|
},
|
2022-07-30 20:20:53 +00:00
|
|
|
CurrentMenu::ControlsMenu => {
|
|
|
|
let cm = &mut self.current;
|
|
|
|
self.controls_menu.tick(
|
|
|
|
&mut || {
|
|
|
|
*cm = CurrentMenu::MainMenu;
|
|
|
|
},
|
|
|
|
controller,
|
|
|
|
state,
|
|
|
|
ctx,
|
|
|
|
)?;
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
CurrentMenu::LanguageMenu => match self.language.tick(controller, state) {
|
|
|
|
MenuSelectionResult::Selected(LanguageMenuEntry::Language(new_locale), entry) => {
|
|
|
|
if let MenuEntry::Active(_) = entry {
|
|
|
|
if new_locale == state.settings.locale {
|
|
|
|
self.current = CurrentMenu::MainMenu;
|
|
|
|
} else {
|
|
|
|
state.settings.locale = new_locale;
|
2022-11-20 19:38:36 +00:00
|
|
|
state.update_locale(ctx);
|
2022-03-15 01:54:03 +00:00
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
let _ = state.settings.save(ctx);
|
2022-03-15 01:54:03 +00:00
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
let mut new_menu = TitleScene::new();
|
|
|
|
new_menu.open_settings_menu()?;
|
|
|
|
state.next_scene = Some(Box::new(new_menu));
|
2022-03-15 01:54:03 +00:00
|
|
|
}
|
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
|
|
|
|
self.current = CurrentMenu::MainMenu;
|
2022-03-15 01:54:03 +00:00
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(LanguageMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
|
|
|
self.current = CurrentMenu::MainMenu;
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
|
|
|
CurrentMenu::SoundtrackMenu => match self.soundtrack.tick(controller, state) {
|
|
|
|
MenuSelectionResult::Selected(SoundtrackMenuEntry::Soundtrack(_), entry) => {
|
|
|
|
if let MenuEntry::Active(name) = entry {
|
|
|
|
state.settings.soundtrack = name.to_owned();
|
|
|
|
let _ = state.settings.save(ctx);
|
2022-02-10 06:15:28 +00:00
|
|
|
|
2022-07-24 14:52:51 +00:00
|
|
|
self.sound.set_entry(
|
|
|
|
SoundMenuEntry::Soundtrack,
|
|
|
|
MenuEntry::Active(format!("Soundtrack: {}", state.settings.soundtrack)),
|
|
|
|
);
|
|
|
|
state.sound_manager.reload_songs(&state.constants, &state.settings, ctx)?;
|
2022-02-10 06:15:28 +00:00
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
|
|
|
|
self.current = CurrentMenu::SoundMenu;
|
2022-02-10 06:15:28 +00:00
|
|
|
}
|
2022-07-24 14:52:51 +00:00
|
|
|
MenuSelectionResult::Selected(SoundtrackMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
|
|
|
self.current = CurrentMenu::SoundMenu;
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
},
|
2022-07-25 08:41:20 +00:00
|
|
|
CurrentMenu::BehaviorMenu => match self.behavior.tick(controller, state) {
|
|
|
|
MenuSelectionResult::Selected(BehaviorMenuEntry::GameTiming, toggle) => {
|
|
|
|
if let MenuEntry::Options(_, value, _) = toggle {
|
|
|
|
match state.settings.timing_mode {
|
|
|
|
TimingMode::_50Hz => {
|
|
|
|
state.settings.timing_mode = TimingMode::_60Hz;
|
|
|
|
*value = 1;
|
|
|
|
}
|
|
|
|
TimingMode::_60Hz => {
|
|
|
|
state.settings.timing_mode = TimingMode::_50Hz;
|
|
|
|
*value = 0;
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MenuSelectionResult::Selected(BehaviorMenuEntry::PauseOnFocusLoss, toggle) => {
|
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.pause_on_focus_loss = !state.settings.pause_on_focus_loss;
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.pause_on_focus_loss;
|
|
|
|
}
|
|
|
|
}
|
2022-08-23 22:27:39 +00:00
|
|
|
MenuSelectionResult::Selected(BehaviorMenuEntry::CutsceneSkipMode, toggle) => {
|
|
|
|
if let MenuEntry::Options(_, value, _) = toggle {
|
|
|
|
match state.settings.cutscene_skip_mode {
|
|
|
|
CutsceneSkipMode::Hold => {
|
|
|
|
state.settings.cutscene_skip_mode = CutsceneSkipMode::FastForward;
|
|
|
|
*value = 1;
|
|
|
|
}
|
|
|
|
CutsceneSkipMode::FastForward => {
|
|
|
|
state.settings.cutscene_skip_mode = CutsceneSkipMode::Hold;
|
|
|
|
*value = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
}
|
|
|
|
}
|
2023-02-18 18:42:00 +00:00
|
|
|
#[cfg(feature = "discord-rpc")]
|
|
|
|
MenuSelectionResult::Selected(BehaviorMenuEntry::DiscordRPC, toggle) => {
|
|
|
|
if let MenuEntry::Toggle(_, value) = toggle {
|
|
|
|
state.settings.discord_rpc = !state.settings.discord_rpc;
|
|
|
|
let _ = state.settings.save(ctx);
|
|
|
|
|
|
|
|
*value = state.settings.discord_rpc;
|
|
|
|
state.discord_rpc.enabled = state.settings.discord_rpc;
|
|
|
|
|
|
|
|
if state.discord_rpc.enabled {
|
|
|
|
if !state.discord_rpc.ready {
|
|
|
|
state.discord_rpc.start()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
state.discord_rpc.set_idling()?;
|
|
|
|
} else {
|
|
|
|
state.discord_rpc.clear()?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-07-25 08:41:20 +00:00
|
|
|
MenuSelectionResult::Selected(BehaviorMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
|
|
|
self.current = CurrentMenu::MainMenu;
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
},
|
2022-08-28 21:06:58 +00:00
|
|
|
CurrentMenu::LinksMenu => match self.links.tick(controller, state) {
|
|
|
|
MenuSelectionResult::Selected(LinksMenuEntry::Link(url), _) => {
|
2022-11-21 14:15:51 +00:00
|
|
|
if let Err(e) = browser::open(&url) {
|
2022-08-28 21:06:58 +00:00
|
|
|
log::warn!("Error opening web browser: {}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MenuSelectionResult::Selected(LinksMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
|
|
|
self.current = CurrentMenu::MainMenu;
|
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
},
|
2023-02-17 14:05:38 +00:00
|
|
|
CurrentMenu::AdvancedMenu => match self.advanced.tick(controller, state) {
|
|
|
|
MenuSelectionResult::Selected(AdvancedMenuEntry::OpenUserData, _) => {
|
|
|
|
if let Some(fs_container) = &state.fs_container {
|
|
|
|
fs_container.open_user_directory()?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MenuSelectionResult::Selected(AdvancedMenuEntry::OpenGameData, _) => {
|
|
|
|
if let Some(fs_container) = &state.fs_container {
|
|
|
|
fs_container.open_game_directory()?;
|
|
|
|
}
|
|
|
|
}
|
2023-03-03 18:28:43 +00:00
|
|
|
|
|
|
|
#[cfg(not(any(target_os = "android", target_os = "horizon")))]
|
2023-02-23 12:27:53 +00:00
|
|
|
MenuSelectionResult::Selected(AdvancedMenuEntry::MakePortable, _) => {
|
|
|
|
self.current = CurrentMenu::PortableMenu;
|
|
|
|
}
|
2023-02-17 14:05:38 +00:00
|
|
|
MenuSelectionResult::Selected(AdvancedMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
|
|
|
self.current = CurrentMenu::MainMenu;
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
2023-02-23 12:27:53 +00:00
|
|
|
CurrentMenu::PortableMenu => match self.portable.tick(controller, state) {
|
|
|
|
MenuSelectionResult::Selected(PortableMenuEntry::Yes, _) => {
|
|
|
|
if let Some(fs_container) = &mut state.fs_container {
|
|
|
|
fs_container.make_portable_user_directory(ctx)?;
|
|
|
|
state.next_scene = Some(Box::new(TitleScene::new()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MenuSelectionResult::Selected(PortableMenuEntry::No, _) | MenuSelectionResult::Canceled => {
|
|
|
|
self.current = CurrentMenu::AdvancedMenu;
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
},
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
|
|
|
match self.current {
|
|
|
|
CurrentMenu::MainMenu => self.main.draw(state, ctx)?,
|
|
|
|
CurrentMenu::GraphicsMenu => self.graphics.draw(state, ctx)?,
|
|
|
|
CurrentMenu::SoundMenu => self.sound.draw(state, ctx)?,
|
2022-02-10 06:15:28 +00:00
|
|
|
CurrentMenu::SoundtrackMenu => self.soundtrack.draw(state, ctx)?,
|
2022-07-30 20:20:53 +00:00
|
|
|
CurrentMenu::ControlsMenu => self.controls_menu.draw(state, ctx)?,
|
2022-03-15 01:54:03 +00:00
|
|
|
CurrentMenu::LanguageMenu => self.language.draw(state, ctx)?,
|
2022-07-25 08:41:20 +00:00
|
|
|
CurrentMenu::BehaviorMenu => self.behavior.draw(state, ctx)?,
|
2022-08-28 21:06:58 +00:00
|
|
|
CurrentMenu::LinksMenu => self.links.draw(state, ctx)?,
|
2023-02-17 14:05:38 +00:00
|
|
|
CurrentMenu::AdvancedMenu => self.advanced.draw(state, ctx)?,
|
2023-02-23 12:27:53 +00:00
|
|
|
CurrentMenu::PortableMenu => self.portable.draw(state, ctx)?,
|
2021-08-16 07:47:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|