diff --git a/Cargo.toml b/Cargo.toml index 225e4b6..9250260 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ cpal = { git = "https://github.com/doukutsu-rs/cpal", rev = "9d269d8724102404e73 directories = "3" discord-rich-presence = "0.2" downcast = "0.11" +fern = "0.6.2" glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "2dd95f042e6e090d36f577cbea125560dd99bd27", optional = true, default_features = false, features = ["x11"] } imgui = "0.8" image = { version = "0.24", default-features = false, features = ["png", "bmp"] } @@ -85,7 +86,6 @@ serde = { version = "1", features = ["derive"] } serde_derive = "1" serde_cbor = { version = "0.11", optional = true } serde_json = "1.0" -simple_logger = { version = "1.16", features = ["colors", "threads"] } strum = "0.24" strum_macros = "0.24" # remove and replace when drain_filter is in stable diff --git a/src/framework/error.rs b/src/framework/error.rs index 3b3769c..1a41e89 100644 --- a/src/framework/error.rs +++ b/src/framework/error.rs @@ -44,6 +44,8 @@ pub enum GameError { InvalidValue(String), /// Something went wrong while executing a debug command line command. CommandLineError(String), + /// Something went wrong while initializing logger + LoggerError(String), } impl fmt::Display for GameError { @@ -147,3 +149,10 @@ impl From> for GameError { GameError::EventLoopError(errstr) } } + +impl From for GameError { + fn from(s: log::SetLoggerError) -> GameError { + let errstr = format!("Set logger error: {}", s); + GameError::LoggerError(errstr) + } +} diff --git a/src/game/mod.rs b/src/game/mod.rs index cf52f48..1ce43a0 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,4 +1,5 @@ use std::cell::UnsafeCell; +use std::path::PathBuf; use std::sync::Mutex; use std::time::{Duration, Instant}; @@ -212,18 +213,85 @@ impl Game { } } -pub fn init(options: LaunchOptions) -> GameResult { - let _ = simple_logger::SimpleLogger::new() - .without_timestamps() - .with_colors(true) - .with_level(log::Level::Info.to_level_filter()) - .init(); +// For the most part this is just a copy-paste of the code from FilesystemContainer because it logs +// some messages during init, but the default logger cannot be replaced with another +// one or deinited(so we can't create the console-only logger and replace it by the +// console&file logger after FilesystemContainer has been initialized) +fn get_logs_dir() -> GameResult { + let mut logs_dir = PathBuf::new(); + + + #[cfg(target_os = "android")] + { + logs_dir = PathBuf::from(ndk_glue::native_activity().internal_data_path().to_string_lossy().to_string()); + } + + #[cfg(not(any(target_os = "android", target_os = "horizon")))] + { + let project_dirs = match directories::ProjectDirs::from("", "", "doukutsu-rs") { + Some(dirs) => dirs, + None => { + use crate::framework::error::GameError; + return Err(GameError::FilesystemError(String::from( + "No valid home directory path could be retrieved.", + ))); + } + }; + + logs_dir = project_dirs.data_local_dir().to_path_buf(); + } + + #[cfg(target_os = "horizon")] + { + logs_dir = PathBuf::from("sdmc:/switch/doukutsu-rs"); + } + + + + logs_dir.push("logs"); + + Ok(logs_dir) +} +fn init_logger() -> GameResult { + let logs_dir = get_logs_dir()?; + let _ = std::fs::create_dir_all(&logs_dir); + + + let mut dispatcher = fern::Dispatch::new() + .format(|out, message, record| { + out.finish(format_args!( + "{} [{}] {}", + record.level(), + record.module_path().unwrap().to_owned(), + message + )) + }) + .level(log::LevelFilter::Info) + .chain(std::io::stderr()); + + + let date = chrono::Utc::now(); + let mut file = logs_dir.clone(); + file.push(format!("log_{}", date.format("%Y-%m-%d"))); + file.set_extension("txt"); + + dispatcher = dispatcher.chain(fern::log_file(file).unwrap()); + dispatcher.apply()?; + + //log::info!("===GAME LAUNCH==="); + + Ok(()) +} + +pub fn init(options: LaunchOptions) -> GameResult { + let _ = init_logger(); + let mut context = Box::pin(Context::new()); let mut fs_container = FilesystemContainer::new(); fs_container.mount_fs(&mut context)?; - + if options.server_mode { log::info!("Running in server mode..."); context.headless = true; diff --git a/src/sound/mod.rs b/src/sound/mod.rs index 73a4aab..0f707df 100644 --- a/src/sound/mod.rs +++ b/src/sound/mod.rs @@ -600,17 +600,17 @@ fn run( let mut speed = 1.0; let mut org_engine = Box::new(OrgPlaybackEngine::new()); #[cfg(feature = "ogg-playback")] - let mut ogg_engine = Box::new(OggPlaybackEngine::new()); + let mut ogg_engine = Box::new(OggPlaybackEngine::new()); let mut pixtone = Box::new(PixTonePlayback::new()); pixtone.create_samples(); log::info!("Audio format: {} {}", sample_rate, channels); org_engine.set_sample_rate(sample_rate as usize); #[cfg(feature = "ogg-playback")] - { - org_engine.loops = usize::MAX; - ogg_engine.set_sample_rate(sample_rate as usize); - } + { + org_engine.loops = usize::MAX; + ogg_engine.set_sample_rate(sample_rate as usize); + } let buf_size = sample_rate as usize * 10 / 1000; let mut bgm_buf = vec![0x8080; buf_size * 2];