diff --git a/.cargo/config.toml b/.cargo/config.toml index a627181..fa9631c 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,3 +1,3 @@ [env] # use pipewire for audio -SDL_AUDIODRIVER = "pipewire" +#SDL_AUDIODRIVER = "pipewire" diff --git a/Cargo.lock b/Cargo.lock index d5c904b..1e5da53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,54 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anstream" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "bindgen" version = "0.65.1" @@ -21,7 +69,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", + "syn 2.0.36", "which", ] @@ -44,7 +92,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", + "syn 2.0.36", "which", ] @@ -60,6 +108,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "cc" version = "1.0.79" @@ -92,6 +149,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824956d0dca8334758a5b7f7e50518d66ea319330cbceedcf76905c2f6ab30e3" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122ec64120a49b4563ccaedcbea7818d069ed8e9aa6d829b82d8a4128936b2ab" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.36", +] + +[[package]] +name = "clap_lex" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" + [[package]] name = "cmake" version = "0.1.50" @@ -101,12 +198,88 @@ dependencies = [ "cc", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "confique" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944dc1c6dec3f9b3adc127a921affd93baeea3d04c9b2d0a84380a243c9258b" +dependencies = [ + "confique-macro", + "json5", + "serde", + "serde_yaml", + "toml", +] + +[[package]] +name = "confique-macro" +version = "0.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7305b4979ffd6d8b02006da5520b21c66bfab961cd688b9b6db00780f61448ce" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.8" @@ -124,6 +297,27 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "include_dir" version = "0.7.3" @@ -143,6 +337,33 @@ dependencies = [ "quote", ] +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -214,6 +435,51 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pest" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.36", +] + +[[package]] +name = "pest_meta" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -227,7 +493,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.36", ] [[package]] @@ -261,18 +527,21 @@ dependencies = [ name = "projectm_sdl" version = "0.1.1" dependencies = [ + "clap", + "confique", "include_dir", "libc", "projectm", "rand", "sdl3", + "serde", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -328,6 +597,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + [[package]] name = "sdl3" version = "0.6.0" @@ -350,12 +625,73 @@ dependencies = [ "version-compare", ] +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.36", +] + +[[package]] +name = "serde_yaml" +version = "0.9.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.36" @@ -367,18 +703,83 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.36", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "unicode-ident" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "version-compare" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -417,3 +818,69 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index 56cc605..2096eed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,13 +9,16 @@ rust-version = "1.68.2" [dependencies] libc = "*" # projectm = "1.0.5" - projectm = { path = "../projectm-rs", version = "2.0.1-alpha", features = [] } + projectm = { path = "../projectm-rs", version = "4.1.0-alpha.1", features = [] } #projectm = { git = "https://github.com/projectM-visualizer/projectm" nd} # sdl3 = { git = "https://github.com/revmischa/sdl3-rs.git", features = ["use-bindgen"] } # sdl3 = "0.5.0" sdl3 = { path = "../../sdl3-rs", version = "0.6.0", features = ["use-bindgen"] } rand = "0.8.5" include_dir = "0.7.3" +clap = {version="4.4.5", features=["derive"]} +confique = "0.2.4" +serde = "1.0.188" # gl = "0.14.0" [features] diff --git a/src/app.rs b/src/app.rs index c0a1375..ad10b3d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,6 @@ +use crate::app::config::Config; use projectm::core::ProjectM; -use sdl3::video::{GLProfile, WindowPos}; +use sdl3::video::GLProfile; use std::convert::TryInto; use std::rc::Rc; @@ -22,12 +23,8 @@ pub struct App { _gl_context: sdl3::video::GLContext, } -pub fn default_config() -> config::Config { - config::Config::default() -} - impl App { - pub fn new(config: Option) -> Self { + pub fn new(config: Option) -> Self { // setup sdl let sdl_context = sdl3::init().unwrap(); // print SDL version @@ -79,7 +76,7 @@ impl App { playlist, sdl_context, window, - config: config.unwrap_or_else(default_config), + config: config.unwrap_or_else(Config::default), audio, _gl_context: gl_context, // keep this around to keep the context alive } diff --git a/src/app/audio.rs b/src/app/audio.rs index 24b3fbd..7f189af 100644 --- a/src/app/audio.rs +++ b/src/app/audio.rs @@ -63,8 +63,10 @@ impl Audio { /// Start capturing audio from device_index. pub fn capture_device(&mut self, device_index: AudioDeviceIndex) { self.stop_audio_capture(); + println!("Capturing audio from device {}", device_index); self.device_index = device_index; self.begin_audio_capture(device_index); + println!("Capturing audio from device {}", device_index); } pub fn get_device_name(&self, device_index: AudioDeviceIndex) -> String { @@ -123,6 +125,7 @@ impl Audio { // open audio device for capture let device_name = self.get_device_name(device_index); + println!("Opening audio device: {}", device_name); let audio_device = match self .audio_subsystem // sdl .open_capture(device_name.as_str(), &desired_spec, |_spec| { @@ -166,8 +169,13 @@ impl Audio { let device = self.capturing_device.take().unwrap(); device.pause(); + println!("Device paused"); + self.is_capturing = false; + + println!("Stopped audio capture"); drop(device); + println!("Dropped audio device"); } } diff --git a/src/app/config.rs b/src/app/config.rs index df2be8b..a2421f6 100644 --- a/src/app/config.rs +++ b/src/app/config.rs @@ -1,20 +1,25 @@ use crate::app::App; -use std::path::Path; +use confique::Config as ConfiqueConfig; +use serde::{Deserialize, Serialize}; +use std::path::{Path, PathBuf}; pub type FrameRate = u32; +const RESOURCE_DIR_DEFAULT: &str = "/usr/local/share/projectM"; + /// Configuration for the application -/// TODO: use config crate to support loading from env/CLI/file. /// Parameters are defined here: https://github.com/projectM-visualizer/projectm/blob/master/src/api/include/projectM-4/parameters.h +// #[derive(Debug, Serialize, Deserialize)] +#[derive(ConfiqueConfig, Debug, Serialize, Deserialize)] pub struct Config { /// Frame rate to render at. Defaults to 60. pub frame_rate: Option, /// Path to the preset directory. Defaults to /usr/local/share/projectM/presets - pub preset_path: Option, + pub preset_path: Option, /// Path to the texture directory. Defaults to /usr/local/share/projectM/textures - pub texture_path: Option, + pub texture_path: Option, /// How sensitive the beat detection is. 1.0 is default. pub beat_sensitivity: Option, @@ -25,28 +30,22 @@ pub struct Config { impl Default for Config { fn default() -> Self { - // get paths to presets and textures - // TODO: get from config file or env - // - // use /usr/local/share/projectM if it exists, otherwise use local paths - let resource_dir = "/usr/local/share/projectM"; - let dir_exists = Path::new(&resource_dir).exists(); - let preset_path = if dir_exists && false { - String::from(resource_dir) + "/presets" - } else { - // just test presets - "./presets".to_owned() - }; - let texture_path = if dir_exists { - String::from(resource_dir) + "/textures" - } else { - // doesn't exist - "./textures".to_owned() - }; + let dir_exists = Path::new(&RESOURCE_DIR_DEFAULT).exists(); + + let preset_path = format!("{}/presets", RESOURCE_DIR_DEFAULT); + let texture_path = format!("{}/textures", RESOURCE_DIR_DEFAULT); Self { - preset_path: Path::new(&preset_path).exists().then(|| preset_path), - texture_path: Path::new(&texture_path).exists().then(|| texture_path), + preset_path: if dir_exists { + Some(preset_path.into()) + } else { + None + }, + texture_path: if dir_exists { + Some(texture_path.into()) + } else { + None + }, frame_rate: Some(60), beat_sensitivity: Some(1.0), preset_duration: Some(10.0), @@ -54,6 +53,20 @@ impl Default for Config { } } +impl Config { + // Merges another Config into this one + pub fn merge(&mut self, mut other: Self) { + self.frame_rate = other.frame_rate.take().or(self.frame_rate.take()); + self.preset_path = other.preset_path.take().or(self.preset_path.take()); + self.texture_path = other.texture_path.take().or(self.texture_path.take()); + self.beat_sensitivity = other + .beat_sensitivity + .take() + .or(self.beat_sensitivity.take()); + self.preset_duration = other.preset_duration.take().or(self.preset_duration.take()); + } +} + impl App { pub fn load_config(&self, config: &Config) { let pm = &self.pm; @@ -70,8 +83,7 @@ impl App { // load textures if provided if let Some(texture_path) = &config.texture_path { - let mut paths: Vec = Vec::new(); - paths.push(texture_path.into()); + let paths = [texture_path.clone().into_os_string().into_string().unwrap()]; pm.set_texture_search_paths(&paths, 1); } diff --git a/src/app/playlist.rs b/src/app/playlist.rs index 47da25f..3b51d6e 100644 --- a/src/app/playlist.rs +++ b/src/app/playlist.rs @@ -1,10 +1,12 @@ +use std::path::PathBuf; + use crate::app::App; impl App { /// Add presets to the playlist recursively skipping duplicates. - pub fn add_preset_path(&self, preset_path: &str) { - self.playlist.add_path(preset_path, true); - println!("added preset path: {}", preset_path); + pub fn add_preset_path(&self, preset_path: &PathBuf) { + self.playlist.add_path(preset_path.to_str().unwrap(), true); + println!("added preset path: {}", preset_path.to_str().unwrap()); println!("playlist size: {}", self.playlist.len()); } diff --git a/src/main.rs b/src/main.rs index 99b16be..d26247f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,84 @@ mod app; mod dummy_audio; +use std::{net::IpAddr, path::PathBuf}; + +use crate::app::config::Config; +use clap::Parser; +use confique::Config as ConfiqueConfig; + +// command line arguments +#[derive(Parser)] +/// ProjectM: the milkdrop-compatible music visualizer. +/// +/// Need help? Join discord: https://discord.gg/uSSggaMBrv +struct Cli { + // /// Get help + // #[clap(short, long)] + // help: bool, + /// Path to preset directory + #[clap(short, long)] + preset_path: Option, + + /// Path to texture directory + #[clap(short, long)] + texture_path: Option, + + /// Path to config file + #[clap(short, long)] + config_path: Option, + + /// Audio input device (name or index) + #[clap(short, long)] + audio_input: Option, +} fn main() -> Result<(), String> { - let config = app::default_config(); - // TODO: parse args here for config - // config.preset_path = Some("./presets/test".to_string()); + // parse command line arguments + let cli = Cli::parse(); - let mut app = app::App::new(Some(config)); - app.init(); + // show help + // cli.help.then(|| usage()); + // Initialize AppConfig with default values + let mut app_config = Config::default(); + + // Load from environment and config files using confique + let file_config = match Config::builder() + .env() + .file( + cli.config_path + .as_ref() + .unwrap_or(&PathBuf::from("conf.toml")), + ) + .file("conf.yaml") + .file("conf.json") + // .file("/usr/local/share/projectM/config.inp") TODO: custom parser + .load() + { + Ok(config) => config, + Err(e) => { + panic!("Error loading config: {}", e); + } + }; + + // Merge the loaded configuration into the default one + app_config.merge(file_config); + + // Override with CLI arguments + if let Some(preset_path) = cli.preset_path { + app_config.preset_path = Some(preset_path); + } + if let Some(texture_path) = cli.texture_path { + app_config.texture_path = Some(texture_path); + } + // Add other CLI overrides as needed + + // Initialize the application + let mut app = app::App::new(Some(app_config)); + app.init(); app.main_loop(); + + Ok(()) }