1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2024-10-31 19:44:20 +00:00

settings menu rework

This commit is contained in:
Alula 2021-08-16 09:47:11 +02:00
parent c815c91541
commit a601d6c044
No known key found for this signature in database
GPG key ID: 3E00485503A1D8BA
5 changed files with 326 additions and 103 deletions

View file

@ -1,16 +1,19 @@
use std::cell::Cell;
use crate::common::Rect; use crate::common::Rect;
use crate::framework::context::Context; use crate::framework::context::Context;
use crate::framework::error::GameResult; use crate::framework::error::GameResult;
use crate::input::combined_menu_controller::CombinedMenuController; use crate::input::combined_menu_controller::CombinedMenuController;
use crate::player::skin::basic::BasicPlayerSkin;
use crate::shared_game_state::SharedGameState; use crate::shared_game_state::SharedGameState;
use std::cell::Cell;
pub mod settings_menu;
pub struct MenuSaveInfo {} pub struct MenuSaveInfo {}
pub enum MenuEntry { pub enum MenuEntry {
Hidden, Hidden,
Active(String), Active(String),
DisabledWhite(String),
Disabled(String), Disabled(String),
Toggle(String, bool), Toggle(String, bool),
Options(String, usize, Vec<String>), Options(String, usize, Vec<String>),
@ -23,6 +26,7 @@ impl MenuEntry {
match self { match self {
MenuEntry::Hidden => 0.0, MenuEntry::Hidden => 0.0,
MenuEntry::Active(_) => 14.0, MenuEntry::Active(_) => 14.0,
MenuEntry::DisabledWhite(_) => 14.0,
MenuEntry::Disabled(_) => 14.0, MenuEntry::Disabled(_) => 14.0,
MenuEntry::Toggle(_, _) => 14.0, MenuEntry::Toggle(_, _) => 14.0,
MenuEntry::Options(_, _, _) => 14.0, MenuEntry::Options(_, _, _) => 14.0,
@ -30,6 +34,19 @@ impl MenuEntry {
MenuEntry::NewSave => 30.0, MenuEntry::NewSave => 30.0,
} }
} }
pub fn selectable(&self) -> bool {
match self {
MenuEntry::Hidden => false,
MenuEntry::Active(_) => true,
MenuEntry::DisabledWhite(_) => false,
MenuEntry::Disabled(_) => false,
MenuEntry::Toggle(_, _) => true,
MenuEntry::Options(_, _, _) => true,
MenuEntry::SaveData(_) => true,
MenuEntry::NewSave => true,
}
}
} }
pub enum MenuSelectionResult<'a> { pub enum MenuSelectionResult<'a> {
@ -210,7 +227,7 @@ impl Menu {
y = self.y as f32 + 6.0; y = self.y as f32 + 6.0;
for entry in self.entries.iter() { for entry in self.entries.iter() {
match entry { match entry {
MenuEntry::Active(name) => { MenuEntry::Active(name) | MenuEntry::DisabledWhite(name) => {
state.font.draw_text( state.font.draw_text(
name.chars(), name.chars(),
self.x as f32 + 20.0, self.x as f32 + 20.0,
@ -253,7 +270,28 @@ impl Menu {
ctx, ctx,
)?; )?;
} }
MenuEntry::Hidden => {} MenuEntry::Options(name, index, value) => {
let value_text = if let Some(text) = value.get(*index) { text.as_str() } else { "???" };
let val_text_len = state.font.text_width(value_text.chars(), &state.constants);
state.font.draw_text(
name.chars(),
self.x as f32 + 20.0,
y,
&state.constants,
&mut state.texture_set,
ctx,
)?;
state.font.draw_text(
value_text.chars(),
self.x as f32 + self.width as f32 - val_text_len,
y,
&state.constants,
&mut state.texture_set,
ctx,
)?;
}
_ => {} _ => {}
} }
@ -289,14 +327,8 @@ impl Menu {
} }
if let Some(entry) = self.entries.get(self.selected) { if let Some(entry) = self.entries.get(self.selected) {
match entry { if entry.selectable() {
MenuEntry::Active(_) => { break;
break;
}
MenuEntry::Toggle(_, _) => {
break;
}
_ => {}
} }
} else { } else {
break; break;
@ -314,7 +346,7 @@ impl Menu {
y += entry.height() as f32; y += entry.height() as f32;
match entry { match entry {
MenuEntry::Active(_) | MenuEntry::Toggle(_, _) MenuEntry::Active(_) | MenuEntry::Toggle(_, _) | MenuEntry::Options(_, _, _)
if (self.selected == idx && controller.trigger_ok()) if (self.selected == idx && controller.trigger_ok())
|| state.touch_controls.consume_click_in(entry_bounds) => || state.touch_controls.consume_click_in(entry_bounds) =>
{ {

233
src/menu/settings_menu.rs Normal file
View file

@ -0,0 +1,233 @@
use crate::framework::context::Context;
use crate::framework::error::GameResult;
use crate::input::combined_menu_controller::CombinedMenuController;
use crate::menu::{Menu, MenuSelectionResult};
use crate::menu::MenuEntry;
use crate::shared_game_state::{SharedGameState, TimingMode};
use crate::sound::InterpolationMode;
#[derive(PartialEq, Eq, Copy, Clone)]
#[repr(u8)]
#[allow(unused)]
enum CurrentMenu {
MainMenu,
GraphicsMenu,
SoundMenu,
}
pub struct SettingsMenu {
current: CurrentMenu,
main: Menu,
graphics: Menu,
sound: Menu,
}
static DISCORD_LINK: &str = "https://discord.gg/fbRsNNB";
impl SettingsMenu {
pub fn new() -> SettingsMenu {
let main = Menu::new(0, 0, 200, 0);
let graphics = Menu::new(0, 0, 180, 0);
let sound = Menu::new(0, 0, 260, 0);
SettingsMenu { current: CurrentMenu::MainMenu, main, graphics, sound }
}
pub fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
self.graphics.push_entry(MenuEntry::Toggle("Lighting effects:".to_string(), state.settings.shader_effects));
self.graphics
.push_entry(MenuEntry::Toggle("Motion interpolation:".to_string(), state.settings.motion_interpolation));
self.graphics.push_entry(MenuEntry::Toggle("Subpixel scrolling:".to_string(), state.settings.subpixel_coords));
if state.constants.supports_og_textures {
self.graphics
.push_entry(MenuEntry::Toggle("Original textures".to_string(), state.settings.original_textures));
} else {
self.graphics.push_entry(MenuEntry::Hidden);
}
if state.constants.is_cs_plus {
self.graphics
.push_entry(MenuEntry::Toggle("Seasonal textures".to_string(), state.settings.seasonal_textures));
} else {
self.graphics.push_entry(MenuEntry::Hidden);
}
self.graphics
.push_entry(MenuEntry::Disabled(format!("Renderer: {}", ctx.renderer.as_ref().unwrap().renderer_name())));
self.graphics.push_entry(MenuEntry::Active("< Back".to_owned()));
self.main.push_entry(MenuEntry::Active("Graphics...".to_owned()));
self.main.push_entry(MenuEntry::Active("Sound...".to_owned()));
self.main.push_entry(MenuEntry::Options(
"Game timing:".to_owned(),
if state.timing_mode == TimingMode::_50Hz { 0 } else { 1 },
vec!["50tps (freeware)".to_owned(), "60tps (CS+)".to_owned()],
));
self.main.push_entry(MenuEntry::Active(DISCORD_LINK.to_owned()));
self.main.push_entry(MenuEntry::Active("< Back".to_owned()));
self.sound.push_entry(MenuEntry::DisabledWhite("BGM Interpolation:".to_owned()));
self.sound.push_entry(MenuEntry::Options(
"".to_owned(),
state.settings.organya_interpolation as usize,
vec![
"Nearest (fastest, lowest quality)".to_owned(),
"Linear (fast, similar to freeware on Vista+)".to_owned(),
"Cosine".to_owned(),
"Cubic".to_owned(),
"Polyphase (slowest, similar to freeware on XP)".to_owned()
],
));
self.sound.push_entry(MenuEntry::Disabled(format!("Soundtrack: {}", state.settings.soundtrack)));
self.sound.push_entry(MenuEntry::Active("< Back".to_owned()));
self.update_sizes(state);
Ok(())
}
fn update_sizes(&mut self, state: &SharedGameState) {
self.main.update_height();
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;
self.graphics.update_height();
self.graphics.x = ((state.canvas_size.0 - self.graphics.width as f32) / 2.0).floor() as isize;
self.graphics.y = 30 + ((state.canvas_size.1 - self.graphics.height as f32) / 2.0).floor() as isize;
self.sound.update_height();
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;
}
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) {
MenuSelectionResult::Selected(0, _) => {
self.current = CurrentMenu::GraphicsMenu;
}
MenuSelectionResult::Selected(1, _) => {
self.current = CurrentMenu::SoundMenu;
}
MenuSelectionResult::Selected(2, toggle) => {
if let MenuEntry::Options(_, value, _) = toggle {
match state.timing_mode {
TimingMode::_50Hz => {
state.timing_mode = TimingMode::_60Hz;
*value = 1;
}
TimingMode::_60Hz => {
state.timing_mode = TimingMode::_50Hz;
*value = 0;
}
_ => {}
}
let _ = state.settings.save(ctx);
}
}
MenuSelectionResult::Selected(3, _) => {
if let Err(e) = webbrowser::open(DISCORD_LINK) {
log::warn!("Error opening web browser: {}", e);
}
}
MenuSelectionResult::Selected(4, _) | MenuSelectionResult::Canceled => exit_action(),
_ => (),
},
CurrentMenu::GraphicsMenu => match self.graphics.tick(controller, state) {
MenuSelectionResult::Selected(0, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.shader_effects = !state.settings.shader_effects;
let _ = state.settings.save(ctx);
*value = state.settings.shader_effects;
}
}
MenuSelectionResult::Selected(1, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.motion_interpolation = !state.settings.motion_interpolation;
let _ = state.settings.save(ctx);
*value = state.settings.motion_interpolation;
}
}
MenuSelectionResult::Selected(2, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.subpixel_coords = !state.settings.subpixel_coords;
let _ = state.settings.save(ctx);
*value = state.settings.subpixel_coords;
}
}
MenuSelectionResult::Selected(3, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.original_textures = !state.settings.original_textures;
state.reload_textures();
let _ = state.settings.save(ctx);
*value = state.settings.original_textures;
}
}
MenuSelectionResult::Selected(4, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.seasonal_textures = !state.settings.seasonal_textures;
state.reload_textures();
let _ = state.settings.save(ctx);
*value = state.settings.seasonal_textures;
}
}
MenuSelectionResult::Selected(6, _) | MenuSelectionResult::Canceled => {
self.current = CurrentMenu::MainMenu
}
_ => (),
},
CurrentMenu::SoundMenu => match self.sound.tick(controller, state) {
MenuSelectionResult::Selected(1, toggle) => {
if let MenuEntry::Options(_, value, _) = toggle {
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),
};
*value = new_value;
state.settings.organya_interpolation = new_mode;
state.sound_manager.set_org_interpolation(new_mode);
let _ = state.settings.save(ctx);
}
}
MenuSelectionResult::Selected(3, _) | MenuSelectionResult::Canceled => {
self.current = CurrentMenu::MainMenu
}
_ => (),
}
}
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)?,
}
Ok(())
}
}

View file

@ -4,9 +4,10 @@ use crate::framework::error::GameResult;
use crate::framework::graphics; use crate::framework::graphics;
use crate::input::combined_menu_controller::CombinedMenuController; use crate::input::combined_menu_controller::CombinedMenuController;
use crate::input::touch_controls::TouchControlType; use crate::input::touch_controls::TouchControlType;
use crate::menu::settings_menu::SettingsMenu;
use crate::menu::{Menu, MenuEntry, MenuSelectionResult}; use crate::menu::{Menu, MenuEntry, MenuSelectionResult};
use crate::scene::Scene; use crate::scene::Scene;
use crate::shared_game_state::{SharedGameState, TimingMode}; use crate::shared_game_state::SharedGameState;
#[derive(PartialEq, Eq, Copy, Clone)] #[derive(PartialEq, Eq, Copy, Clone)]
#[repr(u8)] #[repr(u8)]
@ -25,7 +26,7 @@ pub struct TitleScene {
controller: CombinedMenuController, controller: CombinedMenuController,
current_menu: CurrentMenu, current_menu: CurrentMenu,
main_menu: Menu, main_menu: Menu,
option_menu: Menu, option_menu: SettingsMenu,
save_select_menu: Menu, save_select_menu: Menu,
} }
@ -36,7 +37,7 @@ impl TitleScene {
controller: CombinedMenuController::new(), controller: CombinedMenuController::new(),
current_menu: CurrentMenu::MainMenu, current_menu: CurrentMenu::MainMenu,
main_menu: Menu::new(0, 0, 100, 0), main_menu: Menu::new(0, 0, 100, 0),
option_menu: Menu::new(0, 0, 180, 0), option_menu: SettingsMenu::new(),
save_select_menu: Menu::new(0, 0, 200, 0), save_select_menu: Menu::new(0, 0, 200, 0),
} }
} }
@ -85,7 +86,6 @@ impl TitleScene {
// asset copyright for freeware version // asset copyright for freeware version
static COPYRIGHT_PIXEL: &str = "2004.12 Studio Pixel"; static COPYRIGHT_PIXEL: &str = "2004.12 Studio Pixel";
static DISCORD_LINK: &str = "https://discord.gg/fbRsNNB";
impl Scene for TitleScene { impl Scene for TitleScene {
fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
@ -103,27 +103,7 @@ impl Scene for TitleScene {
} }
self.main_menu.push_entry(MenuEntry::Active("Quit".to_string())); self.main_menu.push_entry(MenuEntry::Active("Quit".to_string()));
self.option_menu.push_entry(MenuEntry::Toggle( self.option_menu.init(state, ctx)?;
"Original timing (50TPS)".to_string(),
state.timing_mode == TimingMode::_50Hz,
));
self.option_menu.push_entry(MenuEntry::Toggle("Lighting effects".to_string(), state.settings.shader_effects));
if state.constants.supports_og_textures {
self.option_menu
.push_entry(MenuEntry::Toggle("Original textures".to_string(), state.settings.original_textures));
} else {
self.option_menu.push_entry(MenuEntry::Disabled("Original textures".to_string()));
}
if state.constants.is_cs_plus {
self.option_menu
.push_entry(MenuEntry::Toggle("Seasonal textures".to_string(), state.settings.seasonal_textures));
} else {
self.option_menu.push_entry(MenuEntry::Disabled("Seasonal textures".to_string()));
}
self.option_menu.push_entry(MenuEntry::Active(DISCORD_LINK.to_owned()));
self.option_menu.push_entry(MenuEntry::Disabled(["Renderer: ", &ctx.renderer.as_ref().unwrap().renderer_name()].join("")));
self.option_menu.push_entry(MenuEntry::Active("Back".to_string()));
self.save_select_menu.push_entry(MenuEntry::NewSave); self.save_select_menu.push_entry(MenuEntry::NewSave);
self.save_select_menu.push_entry(MenuEntry::NewSave); self.save_select_menu.push_entry(MenuEntry::NewSave);
@ -146,10 +126,6 @@ impl Scene for TitleScene {
self.main_menu.x = ((state.canvas_size.0 - self.main_menu.width as f32) / 2.0).floor() as isize; self.main_menu.x = ((state.canvas_size.0 - self.main_menu.width as f32) / 2.0).floor() as isize;
self.main_menu.y = ((state.canvas_size.1 + 70.0 - self.main_menu.height as f32) / 2.0).floor() as isize; self.main_menu.y = ((state.canvas_size.1 + 70.0 - self.main_menu.height as f32) / 2.0).floor() as isize;
self.option_menu.update_height();
self.option_menu.x = ((state.canvas_size.0 - self.option_menu.width as f32) / 2.0).floor() as isize;
self.option_menu.y = ((state.canvas_size.1 + 70.0 - self.option_menu.height as f32) / 2.0).floor() as isize;
match self.current_menu { match self.current_menu {
CurrentMenu::MainMenu => match self.main_menu.tick(&mut self.controller, state) { CurrentMenu::MainMenu => match self.main_menu.tick(&mut self.controller, state) {
MenuSelectionResult::Selected(0, _) => { MenuSelectionResult::Selected(0, _) => {
@ -171,55 +147,17 @@ impl Scene for TitleScene {
} }
_ => {} _ => {}
}, },
CurrentMenu::OptionMenu => match self.option_menu.tick(&mut self.controller, state) { CurrentMenu::OptionMenu => {
MenuSelectionResult::Selected(0, toggle) => { let cm = &mut self.current_menu;
if let MenuEntry::Toggle(_, value) = toggle { self.option_menu.tick(
match state.timing_mode { &mut || {
TimingMode::_50Hz => state.timing_mode = TimingMode::_60Hz, *cm = CurrentMenu::MainMenu;
TimingMode::_60Hz => state.timing_mode = TimingMode::_50Hz, },
_ => {} &mut self.controller,
} state,
let _ = state.settings.save(ctx); ctx,
)?;
*value = state.timing_mode == TimingMode::_50Hz; }
}
}
MenuSelectionResult::Selected(1, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.shader_effects = !state.settings.shader_effects;
let _ = state.settings.save(ctx);
*value = state.settings.shader_effects;
}
}
MenuSelectionResult::Selected(2, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.original_textures = !state.settings.original_textures;
state.reload_textures();
let _ = state.settings.save(ctx);
*value = state.settings.original_textures;
}
}
MenuSelectionResult::Selected(3, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.settings.seasonal_textures = !state.settings.seasonal_textures;
state.reload_textures();
let _ = state.settings.save(ctx);
*value = state.settings.seasonal_textures;
}
}
MenuSelectionResult::Selected(4, _) => {
if let Err(e) = webbrowser::open(DISCORD_LINK) {
log::warn!("Error opening web browser: {}", e);
}
}
MenuSelectionResult::Selected(6, _) | MenuSelectionResult::Canceled => {
self.current_menu = CurrentMenu::MainMenu;
}
_ => {}
},
CurrentMenu::StartGame => { CurrentMenu::StartGame => {
if self.tick == 10 { if self.tick == 10 {
state.reset_skip_flags(); state.reset_skip_flags();
@ -262,12 +200,8 @@ impl Scene for TitleScene {
self.draw_text_centered(COPYRIGHT_PIXEL, state.canvas_size.1 - 30.0, state, ctx)?; self.draw_text_centered(COPYRIGHT_PIXEL, state.canvas_size.1 - 30.0, state, ctx)?;
match self.current_menu { match self.current_menu {
CurrentMenu::MainMenu => { CurrentMenu::MainMenu => self.main_menu.draw(state, ctx)?,
self.main_menu.draw(state, ctx)?; CurrentMenu::OptionMenu => self.option_menu.draw(state, ctx)?,
}
CurrentMenu::OptionMenu => {
self.option_menu.draw(state, ctx)?;
}
_ => {} _ => {}
} }

View file

@ -1,5 +1,3 @@
use serde::{Deserialize, Serialize};
use crate::framework::context::Context; use crate::framework::context::Context;
use crate::framework::error::GameResult; use crate::framework::error::GameResult;
use crate::framework::filesystem::{user_create, user_open}; use crate::framework::filesystem::{user_create, user_open};
@ -8,9 +6,12 @@ use crate::input::keyboard_player_controller::KeyboardController;
use crate::input::player_controller::PlayerController; use crate::input::player_controller::PlayerController;
use crate::input::touch_player_controller::TouchPlayerController; use crate::input::touch_player_controller::TouchPlayerController;
use crate::player::TargetPlayer; use crate::player::TargetPlayer;
use crate::sound::InterpolationMode;
#[derive(Serialize, Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
pub struct Settings { pub struct Settings {
#[serde(default = "current_version")]
pub version: u32,
pub seasonal_textures: bool, pub seasonal_textures: bool,
pub original_textures: bool, pub original_textures: bool,
pub shader_effects: bool, pub shader_effects: bool,
@ -18,6 +19,8 @@ pub struct Settings {
pub motion_interpolation: bool, pub motion_interpolation: bool,
pub touch_controls: bool, pub touch_controls: bool,
pub soundtrack: String, pub soundtrack: String,
#[serde(default = "default_interpolation")]
pub organya_interpolation: InterpolationMode,
#[serde(default = "p1_default_keymap")] #[serde(default = "p1_default_keymap")]
pub player1_key_map: PlayerKeyMap, pub player1_key_map: PlayerKeyMap,
#[serde(default = "p2_default_keymap")] #[serde(default = "p2_default_keymap")]
@ -32,6 +35,13 @@ pub struct Settings {
pub debug_outlines: bool, pub debug_outlines: bool,
} }
#[inline(always)]
fn current_version() -> u32 { 2 }
#[inline(always)]
fn default_interpolation() -> InterpolationMode { InterpolationMode::Linear }
#[inline(always)]
fn default_speed() -> f64 { fn default_speed() -> f64 {
1.0 1.0
} }
@ -70,6 +80,7 @@ impl Settings {
impl Default for Settings { impl Default for Settings {
fn default() -> Self { fn default() -> Self {
Settings { Settings {
version: 2,
seasonal_textures: true, seasonal_textures: true,
original_textures: false, original_textures: false,
shader_effects: true, shader_effects: true,
@ -77,6 +88,7 @@ impl Default for Settings {
motion_interpolation: true, motion_interpolation: true,
touch_controls: cfg!(target_os = "android"), touch_controls: cfg!(target_os = "android"),
soundtrack: "".to_string(), soundtrack: "".to_string(),
organya_interpolation: InterpolationMode::Linear,
player1_key_map: p1_default_keymap(), player1_key_map: p1_default_keymap(),
player2_key_map: p2_default_keymap(), player2_key_map: p2_default_keymap(),
speed: 1.0, speed: 1.0,
@ -87,7 +99,7 @@ impl Default for Settings {
} }
} }
#[derive(Serialize, Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
pub struct PlayerKeyMap { pub struct PlayerKeyMap {
pub left: ScanCode, pub left: ScanCode,
pub up: ScanCode, pub up: ScanCode,
@ -102,6 +114,7 @@ pub struct PlayerKeyMap {
pub map: ScanCode, pub map: ScanCode,
} }
#[inline(always)]
fn p1_default_keymap() -> PlayerKeyMap { fn p1_default_keymap() -> PlayerKeyMap {
PlayerKeyMap { PlayerKeyMap {
left: ScanCode::Left, left: ScanCode::Left,
@ -118,6 +131,7 @@ fn p1_default_keymap() -> PlayerKeyMap {
} }
} }
#[inline(always)]
fn p2_default_keymap() -> PlayerKeyMap { fn p2_default_keymap() -> PlayerKeyMap {
PlayerKeyMap { PlayerKeyMap {
left: ScanCode::Comma, left: ScanCode::Comma,

View file

@ -96,6 +96,10 @@ impl SoundManager {
let _ = self.tx.send(PlaybackMessage::StopSample(id)); let _ = self.tx.send(PlaybackMessage::StopSample(id));
} }
pub fn set_org_interpolation(&self, interpolation: InterpolationMode) {
let _ = self.tx.send(PlaybackMessage::SetOrgInterpolation(interpolation));
}
pub fn play_song( pub fn play_song(
&mut self, &mut self,
song_id: usize, song_id: usize,
@ -113,6 +117,7 @@ impl SoundManager {
self.prev_song_id = self.current_song_id; self.prev_song_id = self.current_song_id;
self.current_song_id = 0; self.current_song_id = 0;
self.tx.send(PlaybackMessage::SetOrgInterpolation(settings.organya_interpolation))?;
self.tx.send(PlaybackMessage::SaveState)?; self.tx.send(PlaybackMessage::SaveState)?;
self.tx.send(PlaybackMessage::Stop)?; self.tx.send(PlaybackMessage::Stop)?;
} else if let Some(song_name) = constants.music_table.get(song_id) { } else if let Some(song_name) = constants.music_table.get(song_id) {
@ -152,6 +157,7 @@ impl SoundManager {
self.prev_song_id = self.current_song_id; self.prev_song_id = self.current_song_id;
self.current_song_id = song_id; self.current_song_id = song_id;
self.tx.send(PlaybackMessage::SetOrgInterpolation(settings.organya_interpolation))?;
self.tx.send(PlaybackMessage::SaveState)?; self.tx.send(PlaybackMessage::SaveState)?;
self.tx.send(PlaybackMessage::PlayOrganyaSong(Box::new(org)))?; self.tx.send(PlaybackMessage::PlayOrganyaSong(Box::new(org)))?;
@ -339,6 +345,7 @@ enum PlaybackMessage {
SaveState, SaveState,
RestoreState, RestoreState,
SetSampleParams(u8, PixToneParameters), SetSampleParams(u8, PixToneParameters),
SetOrgInterpolation(InterpolationMode),
} }
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq)]
@ -520,6 +527,9 @@ where
Ok(PlaybackMessage::SetSampleParams(id, params)) => { Ok(PlaybackMessage::SetSampleParams(id, params)) => {
pixtone.set_sample_parameters(id, params); pixtone.set_sample_parameters(id, params);
} }
Ok(PlaybackMessage::SetOrgInterpolation(interpolation)) => {
org_engine.interpolation = interpolation;
}
Err(_) => { Err(_) => {
break; break;
} }
@ -626,11 +636,11 @@ where
if state { if state {
if let Err(e) = stream.pause() { if let Err(e) = stream.pause() {
log::error!("Failed to pause the stream: {}", e); log::error!("Failed to pause the stream: {:?}", e);
} }
} else { } else {
if let Err(e) = stream.play() { if let Err(e) = stream.play() {
log::error!("Failed to unpause the stream: {}", e); log::error!("Failed to unpause the stream: {:?}", e);
} }
} }
} }