diff --git a/src/main.rs b/src/main.rs index f83c2d8..702d158 100644 --- a/src/main.rs +++ b/src/main.rs @@ -617,6 +617,7 @@ fn handle_relative_connection( file_paths.pk, mlc_path.as_deref(), file_paths.mld, + relative_path, &mut stream, choice, progress, diff --git a/src/vn.rs b/src/vn.rs index 1a98ffc..b8ee83a 100644 --- a/src/vn.rs +++ b/src/vn.rs @@ -95,7 +95,7 @@ fn render_ending() -> Markup { } } -fn generate_html(sections: Vec) -> Markup { +fn generate_html(sections: Vec, base_path: &str) -> Markup { let total_sections = sections.len(); html! { @@ -112,7 +112,7 @@ fn generate_html(sections: Vec) -> Markup { (navigation_controls(total_sections)) (global_styles()) - (interactive_script(total_sections)) + (interactive_script(total_sections, base_path)) } } } @@ -342,10 +342,10 @@ fn global_styles() -> Markup { } } -fn interactive_script(total_sections: usize) -> Markup { +fn interactive_script(total_sections: usize, base_path: &str) -> Markup { html! { script { - (maud::PreEscaped(format!(r" + (maud::PreEscaped(format!(r#" let currentScene = 0; const totalSections = {total_sections}; let textVisible = true; @@ -357,6 +357,22 @@ fn interactive_script(total_sections: usize) -> Markup { textVisible = visible; }} + let currentAudio = null; + + function playSectionAudio(index) {{ + const section = document.querySelector( + `.selection-section[data-section-index="${{index}}"]` + ); + const audioElement = section?.querySelector('audio'); + + if(audioElement) {{ + if(currentAudio) currentAudio.pause(); + audioElement.currentTime = 0; + audioElement.play(); + currentAudio = audioElement; + }} + }} + function updateSection() {{ document.querySelectorAll('.selection-section').forEach((el, index) => {{ el.style.display = index === currentScene ? 'block' : 'none'; @@ -365,6 +381,8 @@ fn interactive_script(total_sections: usize) -> Markup { toggleText(true); document.getElementById('section-counter').textContent = `${{currentScene + 1}}/${{totalSections}}`; + + if (currentScene + 1 < totalSections) playSectionAudio(currentScene); }} function prev() {{ @@ -389,19 +407,34 @@ fn interactive_script(total_sections: usize) -> Markup { document.addEventListener('keydown', handleKeys); toggleText(true); - "))) + + window.addEventListener('load', () => {{ + Array({total_sections}).fill().forEach((_, i) => {{ + const audio = new Audio(`{base_path}.${{i}}.mp3`); + audio.preload = 'metadata'; + }}); + }}); + "#))) } } } fn process_dialog( - dialog_sequence: &DialogSequence, + dialogs: &[DialogSequence], + choice: usize, player_settings: &mut PlayerSettings, sections: &mut Vec, + base_path: &str, ) { + let mut start_index = 0; + for dialog in &dialogs[0..choice] { + start_index += dialog.blocks.len(); + } + let dialog_sequence = &dialogs[choice]; + let mut states = initialize_change_states(&dialog_sequence.changes); - for block in &dialog_sequence.blocks { + for (i, block) in dialog_sequence.blocks.iter().enumerate() { apply_block_changes( block, &dialog_sequence.changes, @@ -412,6 +445,9 @@ fn process_dialog( sections.push(html! { (render_scene(player_settings, &block.name)) (render_dialog_block(block)) + audio { + source src=(format!("/{base_path}.{}.mp3", start_index + i)) type="audio/mpeg"; + } }); } @@ -482,6 +518,7 @@ pub fn render_novel( pk_path: &Path, mlc_path: Option<&Path>, mld_path: &Path, + base_path: &str, stream: &mut TcpStream, mut choice: usize, progress: &str, @@ -494,7 +531,14 @@ pub fn render_novel( let dialogs = parse_map(pk_path, &mut settings_context)?; let mut sections = Vec::new(); - process_dialog(&dialogs[choice], &mut player_settings, &mut sections); + + process_dialog( + &dialogs, + choice, + &mut player_settings, + &mut sections, + base_path, + ); if let Some(named_multilinear_info) = load_multilinear(mlc_path, mld_path) { let multilinear_info = &named_multilinear_info.info; @@ -533,7 +577,13 @@ pub fn render_novel( let next_choice = choices[0].0; if next_choice != choice { choice = next_choice; - process_dialog(&dialogs[choice], &mut player_settings, &mut sections); + process_dialog( + &dialogs, + choice, + &mut player_settings, + &mut sections, + base_path, + ); continue; } } @@ -555,7 +605,7 @@ pub fn render_novel( } } - let html = generate_html(sections); + let html = generate_html(sections, base_path); let _ = write!(stream, "{}", html.into_string()); Ok(())