Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions savedata/user.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
[auto]
delay = 2.5382617
delay = 3.5
is_wait = true

[text]
speed = 14.647284
opacity = 0.2754137
speed = 50.0
opacity = 0.8

[volume]
main = 0.0
bgm = 100.0
voice = 100.0

[character_volume]
rir = 100.0
rar = 100.0
65 changes: 65 additions & 0 deletions src/config/character_volume.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::collections::HashMap;
use std::rc::Rc;
use serde::{Deserialize, Serialize};
use slint::{Model, Weak};
use crate::config::ENGINE_CONFIG;
use crate::config::user::USER_CONFIG;
use crate::executor::executor::Executor;
use crate::ui::ui::{CharacterVolume, MainWindow};

#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct CharacterVolumeConfig {
#[serde(flatten)]
pub(crate) volumes: HashMap<String, f32>,
}

impl CharacterVolumeConfig {
pub(crate) fn default_from_engine() -> Self {
CharacterVolumeConfig {
volumes: ENGINE_CONFIG
.characters()
.iter()
.map(|name| (name.clone(), 100.0_f32))
.collect(),
}
}

pub(crate) fn fill_missing(&mut self) {
for name in ENGINE_CONFIG.characters() {
self.volumes.entry(name.clone()).or_insert(100.0);
}
}

pub fn from_weak(weak: Weak<MainWindow>) -> Self {
if let Some(window) = weak.upgrade() {
let model = window.get_character_volumes();
let volumes = (0..model.row_count())
.filter_map(|i| model.row_data(i))
.map(|item| (item.name.to_string(), item.volume))
.collect();
CharacterVolumeConfig { volumes }
} else {
unreachable!()
}
}
}

impl Executor {
pub fn load_character_volumes(&self) {
let weak = self.get_weak();
if let Some(window) = weak.upgrade() {
let volumes: Vec<CharacterVolume> = ENGINE_CONFIG
.characters()
.iter()
.map(|name| CharacterVolume {
name: name.as_str().into(),
volume: USER_CONFIG.character_volume(name),
})
.collect();

window.set_character_volumes(
Rc::new(slint::VecModel::from(volumes)).into()
);
}
}
}
6 changes: 6 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashSet;
use crate::config::initialize::{Character, InitializeConfig};
use serde::{Deserialize, Serialize};
use std::fs;
Expand All @@ -13,6 +14,7 @@ pub mod voice;
pub mod volume;
pub mod extra;
pub mod cg;
pub mod character_volume;

lazy_static::lazy_static! {
pub static ref ENGINE_CONFIG: EngineConfig = load_engine_config();
Expand Down Expand Up @@ -52,6 +54,10 @@ impl EngineConfig {
pub fn save_path(&self) -> &str {
&self.initialize.save_path
}

pub fn characters(&self) -> &HashSet<String> {
&self.character.list
}
}

fn load_engine_config() -> EngineConfig {
Expand Down
6 changes: 6 additions & 0 deletions src/config/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ pub struct AutoConfig {
is_wait: bool,
}

impl Default for AutoConfig {
fn default() -> Self {
AutoConfig { delay: 3.5, is_wait: true }
}
}

impl AutoConfig {
pub fn delay(&self) -> f32 {
self.delay
Expand Down
5 changes: 5 additions & 0 deletions src/config/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ pub struct TextConfig {
opacity: f32,
}

impl Default for TextConfig {
fn default() -> Self {
TextConfig { speed: 50.0, opacity: 0.8 }
}
}
impl TextConfig {
pub fn speed(&self) -> f32 {
self.speed
Expand Down
49 changes: 42 additions & 7 deletions src/config/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::ui::ui::MainWindow;
use serde::{Deserialize, Serialize};
use slint::Weak;
use std::fs;
use crate::config::character_volume::CharacterVolumeConfig;

lazy_static::lazy_static! {
pub static ref USER_CONFIG: UserConfig = load_user_config();
Expand All @@ -17,9 +18,19 @@ pub struct UserConfig {
auto: AutoConfig,
text: TextConfig,
volume: VolumeConfig,
character_volume: CharacterVolumeConfig,
}

impl UserConfig {
fn default() -> Self {
UserConfig {
auto: AutoConfig::default(),
text: TextConfig::default(),
volume: VolumeConfig::default(),
character_volume: CharacterVolumeConfig::default_from_engine(),
}
}

pub fn delay(&self) -> f32 {
self.auto.delay()
}
Expand Down Expand Up @@ -48,25 +59,49 @@ impl UserConfig {
self.text.opacity()
}

pub fn character_volume(&self, name: &str) -> f32 {
self.character_volume.volumes.get(name).unwrap().clone()
}

pub fn from_weak(weak: Weak<MainWindow>) -> Self {
UserConfig {
auto: AutoConfig::from_weak(weak.clone()),
text: TextConfig::from_weak(weak.clone()),
volume: VolumeConfig::from_weak(weak),
volume: VolumeConfig::from_weak(weak.clone()),
character_volume: CharacterVolumeConfig::from_weak(weak),
}
}
}

fn load_user_config() -> UserConfig {
let content = fs::read_to_string(format!("{}/user.toml", ENGINE_CONFIG.save_path())).unwrap();
toml::from_str(&content).unwrap()
let path = format!("{}/user.toml", ENGINE_CONFIG.save_path());

match fs::read_to_string(&path) {
Ok(content) => match toml::from_str::<UserConfig>(&content) {
Ok(mut config) => {
config.character_volume.fill_missing();
config
}
Err(_) => {
let config = UserConfig::default();
let _ = write_config(&path, &config);
config
}
},
Err(_) => {
let config = UserConfig::default();
let _ = write_config(&path, &config);
config
}
}
}

pub fn save_user_config(weak: Weak<MainWindow>) -> Result<(), EngineError> {
fs::write(
format!("{}/user.toml", ENGINE_CONFIG.save_path()),
toml::to_string(&UserConfig::from_weak(weak))?,
)?;
let path = format!("{}/user.toml", ENGINE_CONFIG.save_path());
write_config(&path, &UserConfig::from_weak(weak))
}

fn write_config(path: &str, config: &UserConfig) -> Result<(), EngineError> {
fs::write(path, toml::to_string(config)?)?;
Ok(())
}
6 changes: 6 additions & 0 deletions src/config/volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ pub(crate) struct VolumeConfig {
voice: f32,
}

impl Default for VolumeConfig {
fn default() -> Self {
VolumeConfig { main: 100.0, bgm: 100.0, voice: 100.0 }
}
}

impl VolumeConfig {
pub fn main(&self) -> f32 {
self.main
Expand Down
10 changes: 9 additions & 1 deletion src/executor/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,9 +573,17 @@ impl Executor {
let voice_player = self.voice_player.borrow_mut();
let volume = window.get_main_volume() / 100.0;
let voice_volume = window.get_voice_volume() / 100.0;
let character_volumes = window.get_character_volumes();
let mut character_volume = 100.0;
for character_volume_struct in character_volumes.iter() {
if character_volume_struct.name == name {
character_volume = character_volume_struct.volume / 100.0;
break;
}
}
voice_player.play_voice(
&format!("{}/{}/{}.ogg", ENGINE_CONFIG.voice_path(), name, voice),
volume * voice_volume,
volume * voice_volume * character_volume,
);
duration += length.get(voice).unwrap().clone();
}
Expand Down
1 change: 1 addition & 0 deletions src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub fn load_data(executor: &mut Executor) -> Result<ExecutorTX, EngineError> {

executor.load_save_data()?;
executor.load_volume();
executor.load_character_volumes();
executor.load_auto();
executor.load_text();
executor.load_extra();
Expand Down
6 changes: 6 additions & 0 deletions ui/main_window.slint
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import { ExtraView } from "components/extra.slint";
import { SettingsView } from "components/main_config.slint";
import { StoryView } from "components/story.slint";

struct CharacterVolume {
name: string,
volume: float,
}

export component MainWindow inherits Window {
min-width: 1280px;
min-height: 720px;
Expand Down Expand Up @@ -66,6 +71,7 @@ export component MainWindow inherits Window {
in-out property <float> main-volume;
in-out property <float> bgm-volume;
in-out property <float> voice-volume;
in-out property <[CharacterVolume]> character_volumes: [];

// 计算容器尺寸
property <length> container-size: min(self.width, self.height * 16 / 9);
Expand Down