mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-05-23 23:31:25 +00:00
use localized soundtrack names
This commit is contained in:
parent
7630a9b60e
commit
9c95b20f5c
|
@ -207,7 +207,7 @@ pub struct AnimatedFace {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ExtraSoundtrack {
|
pub struct ExtraSoundtrack {
|
||||||
pub name: String,
|
pub id: String,
|
||||||
pub path: String,
|
pub path: String,
|
||||||
pub available: bool,
|
pub available: bool,
|
||||||
}
|
}
|
||||||
|
@ -1613,10 +1613,10 @@ impl EngineConstants {
|
||||||
font_path: "csfont.fnt".to_owned(),
|
font_path: "csfont.fnt".to_owned(),
|
||||||
font_space_offset: 0.0,
|
font_space_offset: 0.0,
|
||||||
soundtracks: vec![
|
soundtracks: vec![
|
||||||
ExtraSoundtrack { name: "Remastered".to_owned(), path: "/base/Ogg11/".to_owned(), available: false },
|
ExtraSoundtrack { id: "remastered".to_owned(), path: "/base/Ogg11/".to_owned(), available: false },
|
||||||
ExtraSoundtrack { name: "New".to_owned(), path: "/base/Ogg/".to_owned(), available: false },
|
ExtraSoundtrack { id: "new".to_owned(), path: "/base/Ogg/".to_owned(), available: false },
|
||||||
ExtraSoundtrack { name: "Famitracks".to_owned(), path: "/base/ogg17/".to_owned(), available: false },
|
ExtraSoundtrack { id: "famitracks".to_owned(), path: "/base/ogg17/".to_owned(), available: false },
|
||||||
ExtraSoundtrack { name: "Ridiculon".to_owned(), path: "/base/ogg_ridic/".to_owned(), available: false },
|
ExtraSoundtrack { id: "ridiculon".to_owned(), path: "/base/ogg_ridic/".to_owned(), available: false },
|
||||||
],
|
],
|
||||||
music_table: vec![
|
music_table: vec![
|
||||||
"xxxx".to_owned(),
|
"xxxx".to_owned(),
|
||||||
|
|
|
@ -95,7 +95,7 @@ fn default_true() -> bool {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn current_version() -> u32 {
|
fn current_version() -> u32 {
|
||||||
24
|
25
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -347,6 +347,18 @@ impl Settings {
|
||||||
self.allow_strafe = true;
|
self.allow_strafe = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
_ => self.soundtrack.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.version != initial_version {
|
if self.version != initial_version {
|
||||||
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@ use crate::game::profile::GameProfile;
|
||||||
#[cfg(feature = "scripting-lua")]
|
#[cfg(feature = "scripting-lua")]
|
||||||
use crate::game::scripting::lua::LuaScriptingState;
|
use crate::game::scripting::lua::LuaScriptingState;
|
||||||
use crate::game::scripting::tsc::credit_script::{CreditScript, CreditScriptVM};
|
use crate::game::scripting::tsc::credit_script::{CreditScript, CreditScriptVM};
|
||||||
use crate::game::scripting::tsc::text_script::{ScriptMode, TextScript, TextScriptEncoding, TextScriptExecutionState, TextScriptVM};
|
use crate::game::scripting::tsc::text_script::{
|
||||||
|
ScriptMode, TextScript, TextScriptEncoding, TextScriptExecutionState, TextScriptVM,
|
||||||
|
};
|
||||||
use crate::game::settings::Settings;
|
use crate::game::settings::Settings;
|
||||||
use crate::game::stage::StageData;
|
use crate::game::stage::StageData;
|
||||||
use crate::graphics::bmfont::BMFont;
|
use crate::graphics::bmfont::BMFont;
|
||||||
|
@ -408,7 +410,7 @@ impl SharedGameState {
|
||||||
|
|
||||||
for soundtrack in constants.soundtracks.iter_mut() {
|
for soundtrack in constants.soundtracks.iter_mut() {
|
||||||
if filesystem::exists(ctx, &soundtrack.path) {
|
if filesystem::exists(ctx, &soundtrack.path) {
|
||||||
log::info!("Enabling soundtrack {} from {}.", soundtrack.name, soundtrack.path);
|
log::info!("Enabling soundtrack {} from {}.", soundtrack.id, soundtrack.path);
|
||||||
soundtrack.available = true;
|
soundtrack.available = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -647,7 +649,12 @@ impl SharedGameState {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_game(&mut self, game_scene: &mut GameScene, ctx: &mut Context, target_player: Option<TargetPlayer>) -> GameResult {
|
pub fn save_game(
|
||||||
|
&mut self,
|
||||||
|
game_scene: &mut GameScene,
|
||||||
|
ctx: &mut Context,
|
||||||
|
target_player: Option<TargetPlayer>,
|
||||||
|
) -> GameResult {
|
||||||
if let Some(save_path) = self.get_save_filename(self.save_slot) {
|
if let Some(save_path) = self.get_save_filename(self.save_slot) {
|
||||||
if let Ok(data) = filesystem::open_options(ctx, save_path, OpenOptions::new().write(true).create(true)) {
|
if let Ok(data) = filesystem::open_options(ctx, save_path, OpenOptions::new().write(true).create(true)) {
|
||||||
let profile = GameProfile::dump(self, game_scene, target_player);
|
let profile = GameProfile::dump(self, game_scene, target_player);
|
||||||
|
@ -896,6 +903,18 @@ impl SharedGameState {
|
||||||
out_locale
|
out_locale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_localized_soundtrack_name(&self, id: &str) -> String {
|
||||||
|
if id == "organya" {
|
||||||
|
return self.loc.t("soundtrack.organya").to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.constants
|
||||||
|
.soundtracks
|
||||||
|
.iter()
|
||||||
|
.find(|s| s.id == id)
|
||||||
|
.map_or_else(|| id.to_owned(), |s| self.loc.t(format!("soundtrack.{}", s.id).as_str()).to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tt(&self, key: &str, args: &[(&str, &str)]) -> String {
|
pub fn tt(&self, key: &str, args: &[(&str, &str)]) -> String {
|
||||||
return self.loc.tt(key, args);
|
return self.loc.tt(key, args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,18 +500,21 @@ impl SettingsMenu {
|
||||||
);
|
);
|
||||||
self.sound.push_entry(
|
self.sound.push_entry(
|
||||||
SoundMenuEntry::Soundtrack,
|
SoundMenuEntry::Soundtrack,
|
||||||
MenuEntry::Active(
|
MenuEntry::Active(state.loc.tt(
|
||||||
state.tt(
|
|
||||||
"menus.options_menu.sound_menu.soundtrack",
|
"menus.options_menu.sound_menu.soundtrack",
|
||||||
&[("soundtrack", state.settings.soundtrack.as_str())],
|
&[("soundtrack", state.get_localized_soundtrack_name(&state.settings.soundtrack).as_str())],
|
||||||
),
|
)),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
self.sound.push_entry(SoundMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
self.sound.push_entry(SoundMenuEntry::Back, MenuEntry::Active(state.loc.t("common.back").to_owned()));
|
||||||
|
|
||||||
let mut soundtrack_entries =
|
let mut soundtrack_entries = state
|
||||||
state.constants.soundtracks.iter().filter(|s| s.available).map(|s| s.name.to_owned()).collect_vec();
|
.constants
|
||||||
soundtrack_entries.push("Organya".to_owned());
|
.soundtracks
|
||||||
|
.iter()
|
||||||
|
.filter(|s| s.available)
|
||||||
|
.map(|s| state.loc.t(format!("soundtrack.{}", s.id).as_str()).to_owned())
|
||||||
|
.collect_vec();
|
||||||
|
soundtrack_entries.push(state.loc.t("soundtrack.organya").to_owned());
|
||||||
|
|
||||||
if let Ok(dir) = filesystem::read_dir(ctx, "/Soundtracks/") {
|
if let Ok(dir) = filesystem::read_dir(ctx, "/Soundtracks/") {
|
||||||
for entry in dir {
|
for entry in dir {
|
||||||
|
@ -882,7 +885,7 @@ impl SettingsMenu {
|
||||||
|
|
||||||
for (id, entry) in &self.soundtrack.entries {
|
for (id, entry) in &self.soundtrack.entries {
|
||||||
if let MenuEntry::Active(soundtrack) = entry {
|
if let MenuEntry::Active(soundtrack) = entry {
|
||||||
if soundtrack == &state.settings.soundtrack {
|
if soundtrack == &state.get_localized_soundtrack_name(&state.settings.soundtrack) {
|
||||||
active_soundtrack = *id;
|
active_soundtrack = *id;
|
||||||
let _ = state.settings.save(ctx);
|
let _ = state.settings.save(ctx);
|
||||||
break;
|
break;
|
||||||
|
@ -937,12 +940,28 @@ impl SettingsMenu {
|
||||||
CurrentMenu::SoundtrackMenu => match self.soundtrack.tick(controller, state) {
|
CurrentMenu::SoundtrackMenu => match self.soundtrack.tick(controller, state) {
|
||||||
MenuSelectionResult::Selected(SoundtrackMenuEntry::Soundtrack(_), entry) => {
|
MenuSelectionResult::Selected(SoundtrackMenuEntry::Soundtrack(_), entry) => {
|
||||||
if let MenuEntry::Active(name) = entry {
|
if let MenuEntry::Active(name) = entry {
|
||||||
state.settings.soundtrack = name.to_owned();
|
state.settings.soundtrack = state
|
||||||
|
.constants
|
||||||
|
.soundtracks
|
||||||
|
.iter()
|
||||||
|
.find(|s| state.loc.t(format!("soundtrack.{}", s.id).as_str()) == name)
|
||||||
|
.map_or_else(|| name.to_owned(), |s| s.id.clone());
|
||||||
|
|
||||||
|
if state.settings.soundtrack == "Organya" {
|
||||||
|
state.settings.soundtrack = "organya".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
let _ = state.settings.save(ctx);
|
let _ = state.settings.save(ctx);
|
||||||
|
|
||||||
self.sound.set_entry(
|
self.sound.set_entry(
|
||||||
SoundMenuEntry::Soundtrack,
|
SoundMenuEntry::Soundtrack,
|
||||||
MenuEntry::Active(format!("Soundtrack: {}", state.settings.soundtrack)),
|
MenuEntry::Active(state.loc.tt(
|
||||||
|
"menus.options_menu.sound_menu.soundtrack",
|
||||||
|
&[(
|
||||||
|
"soundtrack",
|
||||||
|
state.get_localized_soundtrack_name(&state.settings.soundtrack).as_str(),
|
||||||
|
)],
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
state.sound_manager.reload_songs(&state.constants, &state.settings, ctx)?;
|
state.sound_manager.reload_songs(&state.constants, &state.settings, ctx)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use itertools::Itertools;
|
||||||
use crate::common::Color;
|
use crate::common::Color;
|
||||||
use crate::common::Rect;
|
use crate::common::Rect;
|
||||||
use crate::components::background::Background;
|
use crate::components::background::Background;
|
||||||
|
use crate::engine_constants::ExtraSoundtrack;
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
use crate::framework::error::GameResult;
|
use crate::framework::error::GameResult;
|
||||||
use crate::framework::filesystem;
|
use crate::framework::filesystem;
|
||||||
|
@ -16,10 +17,43 @@ use crate::input::combined_menu_controller::CombinedMenuController;
|
||||||
use crate::scene::title_scene::TitleScene;
|
use crate::scene::title_scene::TitleScene;
|
||||||
use crate::scene::Scene;
|
use crate::scene::Scene;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum JukeboxSoundtrackKind {
|
||||||
|
Organya,
|
||||||
|
Extra(ExtraSoundtrack),
|
||||||
|
Custom(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JukeboxSoundtrackKind {
|
||||||
|
pub fn eq_str(&self, other: &str) -> bool {
|
||||||
|
match self {
|
||||||
|
JukeboxSoundtrackKind::Organya => other == "organya",
|
||||||
|
JukeboxSoundtrackKind::Extra(s) => other == s.id,
|
||||||
|
JukeboxSoundtrackKind::Custom(s) => other == s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_localized_string(&self, state: &mut SharedGameState) -> String {
|
||||||
|
match self {
|
||||||
|
JukeboxSoundtrackKind::Organya => state.loc.t("soundtrack.organya").to_owned(),
|
||||||
|
JukeboxSoundtrackKind::Extra(s) => state.loc.t(format!("soundtrack.{}", s.id).as_str()).to_owned(),
|
||||||
|
JukeboxSoundtrackKind::Custom(s) => s.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_id(&self) -> String {
|
||||||
|
match self {
|
||||||
|
JukeboxSoundtrackKind::Organya => "organya".to_owned(),
|
||||||
|
JukeboxSoundtrackKind::Extra(s) => s.id.clone(),
|
||||||
|
JukeboxSoundtrackKind::Custom(s) => s.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct JukeboxScene {
|
pub struct JukeboxScene {
|
||||||
selected_song: u16,
|
selected_song: u16,
|
||||||
song_list: Vec<String>,
|
song_list: Vec<String>,
|
||||||
soundtracks: Vec<String>,
|
soundtracks: Vec<JukeboxSoundtrackKind>,
|
||||||
selected_soundtrack: usize,
|
selected_soundtrack: usize,
|
||||||
controller: CombinedMenuController,
|
controller: CombinedMenuController,
|
||||||
background: Background,
|
background: Background,
|
||||||
|
@ -79,17 +113,26 @@ impl Scene for JukeboxScene {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut soundtrack_entries =
|
let mut soundtrack_entries = state
|
||||||
state.constants.soundtracks.iter().filter(|s| s.available).map(|s| s.name.to_owned()).collect_vec();
|
.constants
|
||||||
soundtrack_entries.push("Organya".to_owned());
|
.soundtracks
|
||||||
|
.iter()
|
||||||
|
.filter(|s| s.available)
|
||||||
|
.map(|s| JukeboxSoundtrackKind::Extra(s.clone()))
|
||||||
|
.collect_vec();
|
||||||
|
soundtrack_entries.push(JukeboxSoundtrackKind::Organya);
|
||||||
|
|
||||||
if let Ok(dir) = filesystem::read_dir(ctx, "/Soundtracks/") {
|
if let Ok(dir) = filesystem::read_dir(ctx, "/Soundtracks/") {
|
||||||
for entry in dir {
|
for entry in dir {
|
||||||
if filesystem::is_dir(ctx, &entry) {
|
if filesystem::is_dir(ctx, &entry) {
|
||||||
let filename = entry.file_name().unwrap().to_string_lossy().to_string();
|
let filename = entry.file_name().unwrap().to_string_lossy().to_string();
|
||||||
|
|
||||||
if !soundtrack_entries.contains(&filename) {
|
if soundtrack_entries
|
||||||
soundtrack_entries.push(filename);
|
.iter()
|
||||||
|
.find(|s| matches!(s, JukeboxSoundtrackKind::Custom(s) if s == &filename))
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
soundtrack_entries.push(JukeboxSoundtrackKind::Custom(filename.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +141,7 @@ impl Scene for JukeboxScene {
|
||||||
self.soundtracks = soundtrack_entries.clone();
|
self.soundtracks = soundtrack_entries.clone();
|
||||||
|
|
||||||
let selected_soundtrack_index =
|
let selected_soundtrack_index =
|
||||||
self.soundtracks.iter().position(|s| s == &state.settings.soundtrack).unwrap_or(0);
|
self.soundtracks.iter().position(|s| s.eq_str(&state.settings.soundtrack)).unwrap_or(0);
|
||||||
self.selected_soundtrack = selected_soundtrack_index;
|
self.selected_soundtrack = selected_soundtrack_index;
|
||||||
|
|
||||||
self.previous_pause_on_focus_loss_setting = state.settings.pause_on_focus_loss;
|
self.previous_pause_on_focus_loss_setting = state.settings.pause_on_focus_loss;
|
||||||
|
@ -150,13 +193,13 @@ impl Scene for JukeboxScene {
|
||||||
|
|
||||||
if self.controller.trigger_shift_left() {
|
if self.controller.trigger_shift_left() {
|
||||||
self.selected_soundtrack = self.selected_soundtrack.checked_sub(1).unwrap_or(self.soundtracks.len() - 1);
|
self.selected_soundtrack = self.selected_soundtrack.checked_sub(1).unwrap_or(self.soundtracks.len() - 1);
|
||||||
state.settings.soundtrack = self.soundtracks[self.selected_soundtrack].to_string();
|
state.settings.soundtrack = self.soundtracks[self.selected_soundtrack].to_id();
|
||||||
state.sound_manager.reload_songs(&state.constants, &state.settings, ctx)?;
|
state.sound_manager.reload_songs(&state.constants, &state.settings, ctx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.controller.trigger_shift_right() {
|
if self.controller.trigger_shift_right() {
|
||||||
self.selected_soundtrack = (self.selected_soundtrack + 1) % self.soundtracks.len();
|
self.selected_soundtrack = (self.selected_soundtrack + 1) % self.soundtracks.len();
|
||||||
state.settings.soundtrack = self.soundtracks[self.selected_soundtrack].to_string();
|
state.settings.soundtrack = self.soundtracks[self.selected_soundtrack].to_id();
|
||||||
state.sound_manager.reload_songs(&state.constants, &state.settings, ctx)?;
|
state.sound_manager.reload_songs(&state.constants, &state.settings, ctx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,9 +327,9 @@ impl Scene for JukeboxScene {
|
||||||
|
|
||||||
// Write Soundtrack name
|
// Write Soundtrack name
|
||||||
|
|
||||||
let text = &state.settings.soundtrack;
|
let text = self.soundtracks[self.selected_soundtrack].to_localized_string(state);
|
||||||
state.font.builder().center(state.canvas_size.0).y(20.0).shadow(true).draw(
|
state.font.builder().center(state.canvas_size.0).y(20.0).shadow(true).draw(
|
||||||
text,
|
text.as_str(),
|
||||||
ctx,
|
ctx,
|
||||||
&state.constants,
|
&state.constants,
|
||||||
&mut state.texture_set,
|
&mut state.texture_set,
|
||||||
|
|
|
@ -11,8 +11,8 @@ use num_traits::clamp;
|
||||||
|
|
||||||
use crate::engine_constants::EngineConstants;
|
use crate::engine_constants::EngineConstants;
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
use crate::framework::error::{GameError, GameResult};
|
|
||||||
use crate::framework::error::GameError::{AudioError, InvalidValue};
|
use crate::framework::error::GameError::{AudioError, InvalidValue};
|
||||||
|
use crate::framework::error::{GameError, GameResult};
|
||||||
use crate::framework::filesystem;
|
use crate::framework::filesystem;
|
||||||
use crate::framework::filesystem::File;
|
use crate::framework::filesystem::File;
|
||||||
use crate::game::settings::Settings;
|
use crate::game::settings::Settings;
|
||||||
|
@ -286,8 +286,7 @@ impl SoundManager {
|
||||||
|
|
||||||
paths.insert(0, "/Soundtracks/".to_owned() + &settings.soundtrack + "/");
|
paths.insert(0, "/Soundtracks/".to_owned() + &settings.soundtrack + "/");
|
||||||
|
|
||||||
if let Some(soundtrack) =
|
if let Some(soundtrack) = constants.soundtracks.iter().find(|s| s.available && s.id == settings.soundtrack)
|
||||||
constants.soundtracks.iter().find(|s| s.available && s.name == settings.soundtrack)
|
|
||||||
{
|
{
|
||||||
paths.insert(0, soundtrack.path.clone());
|
paths.insert(0, soundtrack.path.clone());
|
||||||
}
|
}
|
||||||
|
@ -895,7 +894,7 @@ fn run<T>(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
err_fn,
|
err_fn,
|
||||||
None
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
if stream_result.is_err() {
|
if stream_result.is_err() {
|
||||||
|
|
Loading…
Reference in a new issue