mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-11-22 05:33:02 +00:00
make pausing on focus loss toggleable
This commit is contained in:
parent
2a792db797
commit
fee63f2600
|
@ -116,10 +116,14 @@
|
|||
|
||||
"language": "Language...",
|
||||
|
||||
"game_timing": {
|
||||
"entry": "Game timing:",
|
||||
"50tps": "50tps (freeware)",
|
||||
"60tps": "60tps (CS+)"
|
||||
"behavior": "Behavior...",
|
||||
"behavior_menu": {
|
||||
"game_timing": {
|
||||
"entry": "Game timing:",
|
||||
"50tps": "50tps (freeware)",
|
||||
"60tps": "60tps (CS+)"
|
||||
},
|
||||
"pause_on_focus_loss": "Pause on focus loss:"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -105,11 +105,17 @@
|
|||
},
|
||||
"soundtrack": "サウンドトラック: {soundtrack}"
|
||||
},
|
||||
|
||||
"language": "言語",
|
||||
"game_timing": {
|
||||
"entry": "ゲームのタイミング:",
|
||||
"50tps": "50tps (freeware)",
|
||||
"60tps": "60tps (CS+)"
|
||||
|
||||
"behavior": "動作",
|
||||
"behavior_menu": {
|
||||
"game_timing": {
|
||||
"entry": "ゲームのタイミング:",
|
||||
"50tps": "50tps (freeware)",
|
||||
"60tps": "60tps (CS+)"
|
||||
},
|
||||
"pause_on_focus_loss": "フォーカスが外れた時のポーズ:"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -237,8 +237,25 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
state.shutdown();
|
||||
}
|
||||
Event::Window { win_event, .. } => match win_event {
|
||||
WindowEvent::FocusGained | WindowEvent::Shown => {}
|
||||
WindowEvent::FocusLost | WindowEvent::Hidden => {}
|
||||
WindowEvent::FocusGained | WindowEvent::Shown => {
|
||||
if state.settings.pause_on_focus_loss {
|
||||
{
|
||||
let mut mutex = GAME_SUSPENDED.lock().unwrap();
|
||||
*mutex = false;
|
||||
}
|
||||
|
||||
state.sound_manager.resume();
|
||||
game.loops = 0;
|
||||
}
|
||||
}
|
||||
WindowEvent::FocusLost | WindowEvent::Hidden => {
|
||||
if state.settings.pause_on_focus_loss {
|
||||
let mut mutex = GAME_SUSPENDED.lock().unwrap();
|
||||
*mutex = true;
|
||||
|
||||
state.sound_manager.pause();
|
||||
}
|
||||
}
|
||||
WindowEvent::SizeChanged(width, height) => {
|
||||
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ enum CurrentMenu {
|
|||
SoundMenu,
|
||||
SoundtrackMenu,
|
||||
LanguageMenu,
|
||||
BehaviorMenu,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
|
@ -29,7 +30,7 @@ enum MainMenuEntry {
|
|||
Graphics,
|
||||
Sound,
|
||||
Language,
|
||||
GameTiming,
|
||||
Behavior,
|
||||
DiscordLink,
|
||||
Back,
|
||||
}
|
||||
|
@ -101,6 +102,19 @@ impl Default for LanguageMenuEntry {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
enum BehaviorMenuEntry {
|
||||
GameTiming,
|
||||
PauseOnFocusLoss,
|
||||
Back,
|
||||
}
|
||||
|
||||
impl Default for BehaviorMenuEntry {
|
||||
fn default() -> Self {
|
||||
BehaviorMenuEntry::GameTiming
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SettingsMenu {
|
||||
current: CurrentMenu,
|
||||
main: Menu<MainMenuEntry>,
|
||||
|
@ -108,6 +122,7 @@ pub struct SettingsMenu {
|
|||
sound: Menu<SoundMenuEntry>,
|
||||
soundtrack: Menu<SoundtrackMenuEntry>,
|
||||
language: Menu<LanguageMenuEntry>,
|
||||
behavior: Menu<BehaviorMenuEntry>,
|
||||
pub on_title: bool,
|
||||
}
|
||||
|
||||
|
@ -120,8 +135,18 @@ impl SettingsMenu {
|
|||
let sound = Menu::new(0, 0, 260, 0);
|
||||
let soundtrack = Menu::new(0, 0, 260, 0);
|
||||
let language = Menu::new(0, 0, 120, 0);
|
||||
let behavior = Menu::new(0, 0, 220, 0);
|
||||
|
||||
SettingsMenu { current: CurrentMenu::MainMenu, main, graphics, sound, soundtrack, language, on_title: false }
|
||||
SettingsMenu {
|
||||
current: CurrentMenu::MainMenu,
|
||||
main,
|
||||
graphics,
|
||||
sound,
|
||||
soundtrack,
|
||||
language,
|
||||
behavior,
|
||||
on_title: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
||||
|
@ -251,14 +276,7 @@ impl SettingsMenu {
|
|||
self.main.push_entry(MainMenuEntry::Language, MenuEntry::Active(state.t("menus.options_menu.language")));
|
||||
}
|
||||
|
||||
self.main.push_entry(
|
||||
MainMenuEntry::GameTiming,
|
||||
MenuEntry::Options(
|
||||
state.t("menus.options_menu.game_timing.entry"),
|
||||
if state.settings.timing_mode == TimingMode::_50Hz { 0 } else { 1 },
|
||||
vec![state.t("menus.options_menu.game_timing.50tps"), state.t("menus.options_menu.game_timing.60tps")],
|
||||
),
|
||||
);
|
||||
self.main.push_entry(MainMenuEntry::Behavior, MenuEntry::Active(state.t("menus.options_menu.behavior")));
|
||||
|
||||
self.main.push_entry(MainMenuEntry::DiscordLink, MenuEntry::Active(DISCORD_LINK.to_owned()));
|
||||
|
||||
|
@ -334,6 +352,28 @@ impl SettingsMenu {
|
|||
|
||||
self.soundtrack.push_entry(SoundtrackMenuEntry::Back, MenuEntry::Active(state.t("common.back")));
|
||||
|
||||
self.behavior.push_entry(
|
||||
BehaviorMenuEntry::GameTiming,
|
||||
MenuEntry::Options(
|
||||
state.t("menus.options_menu.behavior_menu.game_timing.entry"),
|
||||
if state.settings.timing_mode == TimingMode::_50Hz { 0 } else { 1 },
|
||||
vec![
|
||||
state.t("menus.options_menu.behavior_menu.game_timing.50tps"),
|
||||
state.t("menus.options_menu.behavior_menu.game_timing.60tps"),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
self.behavior.push_entry(
|
||||
BehaviorMenuEntry::PauseOnFocusLoss,
|
||||
MenuEntry::Toggle(
|
||||
state.t("menus.options_menu.behavior_menu.pause_on_focus_loss"),
|
||||
state.settings.pause_on_focus_loss,
|
||||
),
|
||||
);
|
||||
|
||||
self.behavior.push_entry(BehaviorMenuEntry::Back, MenuEntry::Active(state.t("common.back")));
|
||||
|
||||
self.update_sizes(state);
|
||||
|
||||
Ok(())
|
||||
|
@ -364,6 +404,11 @@ impl SettingsMenu {
|
|||
self.language.update_height();
|
||||
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;
|
||||
|
||||
self.behavior.update_width(state);
|
||||
self.behavior.update_height();
|
||||
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;
|
||||
}
|
||||
|
||||
pub fn tick(
|
||||
|
@ -387,21 +432,8 @@ impl SettingsMenu {
|
|||
self.language.selected = LanguageMenuEntry::Language(state.settings.locale);
|
||||
self.current = CurrentMenu::LanguageMenu;
|
||||
}
|
||||
MenuSelectionResult::Selected(MainMenuEntry::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(MainMenuEntry::Behavior, _) => {
|
||||
self.current = CurrentMenu::BehaviorMenu;
|
||||
}
|
||||
MenuSelectionResult::Selected(MainMenuEntry::DiscordLink, _) => {
|
||||
if let Err(e) = webbrowser::open(DISCORD_LINK) {
|
||||
|
@ -655,6 +687,36 @@ impl SettingsMenu {
|
|||
}
|
||||
_ => (),
|
||||
},
|
||||
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;
|
||||
}
|
||||
}
|
||||
MenuSelectionResult::Selected(BehaviorMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
|
||||
self.current = CurrentMenu::MainMenu;
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -666,6 +728,7 @@ impl SettingsMenu {
|
|||
CurrentMenu::SoundMenu => self.sound.draw(state, ctx)?,
|
||||
CurrentMenu::SoundtrackMenu => self.soundtrack.draw(state, ctx)?,
|
||||
CurrentMenu::LanguageMenu => self.language.draw(state, ctx)?,
|
||||
CurrentMenu::BehaviorMenu => self.behavior.draw(state, ctx)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -24,6 +24,7 @@ pub struct JukeboxScene {
|
|||
frame: Frame,
|
||||
stage: Stage,
|
||||
textures: StageTexturePaths,
|
||||
previous_pause_on_focus_loss_setting: bool,
|
||||
}
|
||||
|
||||
impl JukeboxScene {
|
||||
|
@ -58,6 +59,7 @@ impl JukeboxScene {
|
|||
frame: Frame::new(),
|
||||
stage: fake_stage,
|
||||
textures,
|
||||
previous_pause_on_focus_loss_setting: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +99,9 @@ impl Scene for JukeboxScene {
|
|||
self.soundtracks.iter().position(|s| s == &state.settings.soundtrack).unwrap_or(0);
|
||||
self.selected_soundtrack = selected_soundtrack_index;
|
||||
|
||||
self.previous_pause_on_focus_loss_setting = state.settings.pause_on_focus_loss;
|
||||
state.settings.pause_on_focus_loss = false;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -151,6 +156,7 @@ impl Scene for JukeboxScene {
|
|||
}
|
||||
|
||||
if self.controller.trigger_back() {
|
||||
state.settings.pause_on_focus_loss = self.previous_pause_on_focus_loss_setting;
|
||||
state.next_scene = Some(Box::new(TitleScene::new()));
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ pub struct Settings {
|
|||
pub sfx_volume: f32,
|
||||
#[serde(default = "default_timing")]
|
||||
pub timing_mode: TimingMode,
|
||||
#[serde(default = "default_pause_on_focus_loss")]
|
||||
pub pause_on_focus_loss: bool,
|
||||
#[serde(default = "default_interpolation")]
|
||||
pub organya_interpolation: InterpolationMode,
|
||||
#[serde(default = "default_controller_type")]
|
||||
|
@ -79,7 +81,7 @@ fn default_true() -> bool {
|
|||
|
||||
#[inline(always)]
|
||||
fn current_version() -> u32 {
|
||||
14
|
||||
15
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -127,6 +129,11 @@ fn default_controller_type() -> ControllerType {
|
|||
ControllerType::Keyboard
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn default_pause_on_focus_loss() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
pub fn load(ctx: &Context) -> GameResult<Settings> {
|
||||
if let Ok(file) = user_open(ctx, "/settings.json") {
|
||||
|
@ -223,6 +230,11 @@ impl Settings {
|
|||
self.player2_controller_button_map = player_default_controller_button_map();
|
||||
}
|
||||
|
||||
if self.version == 14 {
|
||||
self.version = 15;
|
||||
self.pause_on_focus_loss = default_pause_on_focus_loss();
|
||||
}
|
||||
|
||||
if self.version != initial_version {
|
||||
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
||||
}
|
||||
|
@ -281,6 +293,7 @@ impl Default for Settings {
|
|||
bgm_volume: 1.0,
|
||||
sfx_volume: 1.0,
|
||||
timing_mode: default_timing(),
|
||||
pause_on_focus_loss: default_pause_on_focus_loss(),
|
||||
organya_interpolation: InterpolationMode::Linear,
|
||||
player1_controller_type: default_controller_type(),
|
||||
player2_controller_type: default_controller_type(),
|
||||
|
|
Loading…
Reference in a new issue