diff --git a/src/data/builtin/builtin_data/locale/en.json b/src/data/builtin/builtin_data/locale/en.json index d7554c7..79a10f7 100644 --- a/src/data/builtin/builtin_data/locale/en.json +++ b/src/data/builtin/builtin_data/locale/en.json @@ -68,7 +68,13 @@ "windowed": "Windowed", "fullscreen": "Fullscreen" }, - "lighting_effects": "Lighting effects:", + "lighting_engine": { + "entry": "Lighting engine:", + "default": "Default for game edition", + "disabled": "Disabled", + "basic": "Basic (CS+ Remastered)", + "raytraced_drs": "Raytraced (d-rs, GPU heavy)" + }, "weapon_light_cone": "Weapon light cone:", "screen_shake": { "entry": "Screen shake intensity:", @@ -84,15 +90,13 @@ "vsync_mode": { "entry": "V-Sync:", "uncapped": "Uncapped", - "uncapped_desc": "V-Sync Off.", + "uncapped_desc": "V-Sync is disabled (may cause tearing).", "vsync": "Enabled", - "vsync_desc": "V-Sync On.", + "vsync_desc": "Synchronized to monitor refresh rate.", "vrr_1x": "Variable Refresh Rate (1x)", - "vrr_1x_desc": "Uses (G-/Free)Sync if available.", "vrr_2x": "Variable Refresh Rate (2x)", - "vrr_2x_desc": "Uses (G-/Free)Sync if available.", "vrr_3x": "Variable Refresh Rate (3x)", - "vrr_3x_desc": "Uses (G-/Free)Sync if available." + "vrr_desc": "Uses (G-/Free)Sync if available." } }, "sound": "Sound...", diff --git a/src/data/builtin/builtin_data/locale/jp.json b/src/data/builtin/builtin_data/locale/jp.json index 811d478..0d85c7e 100644 --- a/src/data/builtin/builtin_data/locale/jp.json +++ b/src/data/builtin/builtin_data/locale/jp.json @@ -68,7 +68,13 @@ "windowed": "ウィンドウ", "fullscreen": "フルスクリーン" }, - "lighting_effects": "ライティング効果:", + "lighting_engine": { + "entry": "ライティング エンジン:", + "default": "ゲーム エディションのデフォルト", + "disabled": "無効", + "basic": "基本 (CS+ リマスター)", + "raytraced_drs": "レイトレース (d-rs、GPU 重視)" + }, "weapon_light_cone": "兵器のライトコーン:", "screen_shake": { "entry": "画面の揺れ:", @@ -82,17 +88,15 @@ "seasonal_textures": "季節ものテクスチャ:", "renderer": "レンダラ:", "vsync_mode": { - "entry": "V-Sync:", - "uncapped": "Uncapped", - "uncapped_desc": "V-Sync Off.", - "vsync": "Enabled", - "vsync_desc": "V-Sync On.", - "vrr_1x": "Variable Refresh Rate (1x)", - "vrr_1x_desc": "Uses (G-/Free)Sync if available.", - "vrr_2x": "Variable Refresh Rate (2x)", - "vrr_2x_desc": "Uses (G-/Free)Sync if available.", - "vrr_3x": "Variable Refresh Rate (3x)", - "vrr_3x_desc": "Uses (G-/Free)Sync if available." + "entry": "V-Sync:", + "uncapped": "上限なし", + "uncapped_desc": "V-Syncは無効(ティアリングが発生する可能性があります)。", + "vsync": "有効", + "vsync_desc": "モニターのリフレッシュ レートに同期します。", + "vrr_1x": "可変リフレッシュレート (1x)", + "vrr_2x": "可変リフレッシュレート (2x)", + "vrr_3x": "可変リフレッシュレート (3x)", + "vrr_desc": "利用可能であれば、(G-/Free)Syncを使用。" } }, "sound": "サウンド", @@ -130,7 +134,8 @@ "cutscene_skip_method": { "entry": "カットシーンをスキップ", "hold": "を押し続け", - "fastforward": "はやおくり" + "fastforward": "はやおくり", + "auto": "自動" }, "discord_rpc": "Discord Rich Presence:", "allow_strafe": "ストレイフを許可する:" diff --git a/src/game/settings.rs b/src/game/settings.rs index baa6864..9a6de88 100644 --- a/src/game/settings.rs +++ b/src/game/settings.rs @@ -20,7 +20,7 @@ pub struct Settings { #[serde(default = "default_true")] pub seasonal_textures: bool, pub original_textures: bool, - pub shader_effects: bool, + pub lighting_engine: LightingEngine, #[serde(default = "default_true")] pub light_cone: bool, #[serde(default = "default_true")] @@ -350,11 +350,7 @@ impl Settings { if self.version == 24 { self.version = 25; self.soundtrack = match self.soundtrack.as_str() { - "Organya" => "organya".to_owned(), - "Remastered" => "remastered".to_owned(), - "New" => "new".to_owned(), - "Famitracks" => "famitracks".to_owned(), - "Ridiculon" => "ridiculon".to_owned(), + "Organya" | "Remastered" | "New" | "Famitracks" | "Ridiculon" => self.soundtrack.to_ascii_lowercase(), _ => self.soundtrack.clone(), } } @@ -430,7 +426,7 @@ impl Default for Settings { version: current_version(), seasonal_textures: true, original_textures: false, - shader_effects: false, + lighting_engine: LightingEngine::default(), light_cone: true, subpixel_coords: true, motion_interpolation: true, @@ -577,3 +573,17 @@ pub fn player_default_controller_button_map() -> PlayerControllerButtonMap { pub fn default_controller_axis_sensitivity() -> f64 { 0.3 } + +#[derive(serde::Serialize, serde::Deserialize, Copy, Clone, PartialEq, Eq)] +pub enum LightingEngine { + Default, + Disabled, + Basic, + Raytraced, +} + +impl Default for LightingEngine { + fn default() -> Self { + LightingEngine::Default + } +} diff --git a/src/game/shared_game_state.rs b/src/game/shared_game_state.rs index 3973397..16eee2d 100644 --- a/src/game/shared_game_state.rs +++ b/src/game/shared_game_state.rs @@ -38,6 +38,7 @@ use crate::util::bitvec::BitVec; use crate::util::rng::XorShift; use super::filesystem_container::FilesystemContainer; +use super::settings::LightingEngine; #[derive(PartialEq, Eq, Copy, Clone, serde::Serialize, serde::Deserialize)] pub enum TimingMode { @@ -900,6 +901,18 @@ impl SharedGameState { .map_or_else(|| id.to_owned(), |s| self.loc.t(format!("soundtrack.{}", s.id).as_str()).to_owned()) } + pub fn get_lighting_type(&self) -> LightingEngine { + if self.settings.lighting_engine == LightingEngine::Default { + if self.constants.is_switch { + return LightingEngine::Basic; + } + + return LightingEngine::Disabled; + } + + self.settings.lighting_engine + } + pub fn tt(&self, key: &str, args: &[(&str, &str)]) -> String { return self.loc.tt(key, args); } diff --git a/src/menu/settings_menu.rs b/src/menu/settings_menu.rs index aefd3b2..fb83749 100644 --- a/src/menu/settings_menu.rs +++ b/src/menu/settings_menu.rs @@ -4,6 +4,7 @@ use crate::framework::context::Context; use crate::framework::error::GameResult; use crate::framework::graphics::VSyncMode; use crate::framework::{filesystem, graphics}; +use crate::game::settings::LightingEngine; use crate::game::shared_game_state::{CutsceneSkipMode, ScreenShakeIntensity, SharedGameState, TimingMode, WindowMode}; use crate::graphics::font::Font; use crate::input::combined_menu_controller::CombinedMenuController; @@ -53,7 +54,7 @@ impl Default for MainMenuEntry { enum GraphicsMenuEntry { VSyncMode, WindowMode, - LightingEffects, + LightingEngine, WeaponLightCone, ScreenShake, MotionInterpolation, @@ -241,9 +242,9 @@ impl SettingsMenu { vec![ 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(), + state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_desc").to_owned(), + state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_desc").to_owned(), + state.loc.t("menus.options_menu.graphics_menu.vsync_mode.vrr_desc").to_owned(), ], ), ); @@ -260,10 +261,16 @@ impl SettingsMenu { ), ); self.graphics.push_entry( - GraphicsMenuEntry::LightingEffects, - MenuEntry::Toggle( - state.loc.t("menus.options_menu.graphics_menu.lighting_effects").to_owned(), - state.settings.shader_effects, + GraphicsMenuEntry::LightingEngine, + MenuEntry::Options( + state.loc.t("menus.options_menu.graphics_menu.lighting_engine.entry").to_owned(), + state.settings.lighting_engine as usize, + vec![ + state.loc.t("menus.options_menu.graphics_menu.lighting_engine.default").to_owned(), + state.loc.t("menus.options_menu.graphics_menu.lighting_engine.disabled").to_owned(), + state.loc.t("menus.options_menu.graphics_menu.lighting_engine.basic").to_owned(), + state.loc.t("menus.options_menu.graphics_menu.lighting_engine.raytraced_drs").to_owned(), + ], ), ); self.graphics.push_entry( @@ -660,6 +667,8 @@ impl SettingsMenu { ) -> GameResult { self.update_sizes(state); + // holy shit this is utter garbage + // we desperately need a new menu system match self.current { CurrentMenu::MainMenu => match self.main.tick(controller, state) { MenuSelectionResult::Selected(MainMenuEntry::Graphics, _) => { @@ -738,12 +747,35 @@ impl SettingsMenu { let _ = state.settings.save(ctx); } } - MenuSelectionResult::Selected(GraphicsMenuEntry::LightingEffects, toggle) => { - if let MenuEntry::Toggle(_, value) = toggle { - state.settings.shader_effects = !state.settings.shader_effects; - let _ = state.settings.save(ctx); + MenuSelectionResult::Selected(GraphicsMenuEntry::LightingEngine, toggle) + | MenuSelectionResult::Right(GraphicsMenuEntry::LightingEngine, toggle, _) => { + if let MenuEntry::Options(_, value, _) = toggle { + let (new_mode, new_value) = match *value { + 0 => (LightingEngine::Disabled, 1), + 1 => (LightingEngine::Basic, 2), + 2 => (LightingEngine::Raytraced, 3), + _ => (LightingEngine::Default, 0), + }; - *value = state.settings.shader_effects; + *value = new_value; + state.settings.lighting_engine = new_mode; + + let _ = state.settings.save(ctx); + } + } + MenuSelectionResult::Left(GraphicsMenuEntry::LightingEngine, toggle, _) => { + if let MenuEntry::Options(_, value, _) = toggle { + let (new_mode, new_value) = match *value { + 0 => (LightingEngine::Raytraced, 3), + 1 => (LightingEngine::Default, 0), + 2 => (LightingEngine::Disabled, 1), + _ => (LightingEngine::Basic, 2), + }; + + *value = new_value; + state.settings.lighting_engine = new_mode; + + let _ = state.settings.save(ctx); } } MenuSelectionResult::Selected(GraphicsMenuEntry::WeaponLightCone, toggle) => { diff --git a/src/scene/game_scene.rs b/src/scene/game_scene.rs index b46c951..da19ce8 100644 --- a/src/scene/game_scene.rs +++ b/src/scene/game_scene.rs @@ -41,7 +41,7 @@ use crate::game::physics::{PhysicalEntity, OFFSETS}; use crate::game::player::{ControlMode, Player, TargetPlayer}; use crate::game::scripting::tsc::credit_script::CreditScriptVM; use crate::game::scripting::tsc::text_script::{ScriptMode, TextScriptExecutionState, TextScriptVM}; -use crate::game::settings::ControllerType; +use crate::game::settings::{ControllerType, LightingEngine}; use crate::game::shared_game_state::{CutsceneSkipMode, PlayerCount, ReplayState, SharedGameState, TileSize}; use crate::game::stage::{BackgroundType, Stage, StageTexturePaths}; use crate::game::weapon::bullet::BulletManager; @@ -1991,7 +1991,7 @@ impl Scene for GameScene { self.draw_npc_layer(state, ctx, NPCLayer::Background)?; self.tilemap.draw(state, ctx, &self.frame, TileLayer::Middleground, stage_textures_ref, &self.stage)?; - if state.settings.shader_effects && self.lighting_mode == LightingMode::BackgroundOnly { + if state.get_lighting_type() == LightingEngine::Basic && self.lighting_mode == LightingMode::BackgroundOnly { self.draw_light_map(state, ctx)?; } @@ -2019,7 +2019,7 @@ impl Scene for GameScene { self.draw_boss_popup(state, ctx)?; if !state.control_flags.credits_running() - && state.settings.shader_effects + && state.get_lighting_type() == LightingEngine::Basic && self.lighting_mode == LightingMode::Ambient { self.draw_light_map(state, ctx)?;