From 57c56d90fd497e17715e93623e302f9535b5f84f Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sun, 21 Jun 2026 06:24:41 +0900 Subject: [PATCH] Clarify audio preview controls --- scripts/scenes/battle_scene.gd | 80 +++++++++++++++++++++++++---- tools/capture_readability_frames.gd | 6 +++ tools/smoke_title_menu.gd | 78 +++++++++++++++++----------- 3 files changed, 125 insertions(+), 39 deletions(-) diff --git a/scripts/scenes/battle_scene.gd b/scripts/scenes/battle_scene.gd index de55e20..d68ff9f 100644 --- a/scripts/scenes/battle_scene.gd +++ b/scripts/scenes/battle_scene.gd @@ -664,6 +664,7 @@ var settings_sfx_volume_slider: HSlider var settings_bgm_volume_value_label: Label var settings_sfx_volume_value_label: Label var settings_audio_status_label: Label +var settings_audio_preview_button: Button var settings_audio_reset_button: Button var restart_button: Button var new_campaign_button: Button @@ -703,6 +704,7 @@ var title_sfx_volume_slider: HSlider var title_bgm_volume_value_label: Label var title_sfx_volume_value_label: Label var title_audio_status_label: Label +var title_audio_preview_button: Button var title_audio_reset_button: Button var title_settings_back_button: Button var title_screen_visible := false @@ -3669,12 +3671,28 @@ func _create_hud() -> void: _apply_label_style(settings_audio_status_label, UI_PARCHMENT_TEXT, 12) settings_column.add_child(settings_audio_status_label) + var settings_audio_button_row := HBoxContainer.new() + settings_audio_button_row.custom_minimum_size = Vector2(374, 32) + settings_audio_button_row.add_theme_constant_override("separation", 8) + settings_column.add_child(settings_audio_button_row) + + settings_audio_preview_button = Button.new() + settings_audio_preview_button.text = "소리 확인" + settings_audio_preview_button.custom_minimum_size = Vector2(183, 32) + settings_audio_preview_button.tooltip_text = "현재 음악을 켜고 확인음, 발소리, 타격음, 퇴각음, 보급음을 차례로 재생합니다." + settings_audio_preview_button.set_meta("flat_readable_button", true) + _apply_button_style(settings_audio_preview_button) + settings_audio_preview_button.pressed.connect(_on_settings_audio_preview_pressed) + settings_audio_button_row.add_child(settings_audio_preview_button) + settings_audio_reset_button = Button.new() - settings_audio_reset_button.text = "기본값 듣기" - settings_audio_reset_button.custom_minimum_size = Vector2(374, 32) - settings_audio_reset_button.tooltip_text = "음악과 효과음을 켜고 75%로 되돌린 뒤 현재 음악, 확인음, 발소리, 타격음, 퇴각음, 보급음을 재생합니다." + settings_audio_reset_button.text = "기본값" + settings_audio_reset_button.custom_minimum_size = Vector2(183, 32) + settings_audio_reset_button.tooltip_text = "음악과 효과음을 켜고 크기를 75%로 되돌린 뒤 바로 소리를 확인합니다." + settings_audio_reset_button.set_meta("flat_readable_button", true) + _apply_button_style(settings_audio_reset_button) settings_audio_reset_button.pressed.connect(_on_settings_audio_reset_pressed) - settings_column.add_child(settings_audio_reset_button) + settings_audio_button_row.add_child(settings_audio_reset_button) settings_edge_scroll_toggle = CheckButton.new() settings_edge_scroll_toggle.text = "가장자리 스크롤" @@ -5471,17 +5489,34 @@ func _create_hud() -> void: _apply_label_style(title_audio_status_label, UI_PARCHMENT_TEXT, 12) title_settings_column.add_child(title_audio_status_label) + var title_audio_button_row := HBoxContainer.new() + title_audio_button_row.custom_minimum_size = Vector2(350, 32) + title_audio_button_row.add_theme_constant_override("separation", 8) + title_settings_column.add_child(title_audio_button_row) + + title_audio_preview_button = Button.new() + _configure_title_menu_button( + title_audio_preview_button, + "TitleAudioPreviewButton", + "status", + "소리 확인", + "현재 음악을 켜고 확인음, 발소리, 타격음, 퇴각음, 보급음을 차례로 재생합니다.", + Vector2(171, 32) + ) + title_audio_preview_button.pressed.connect(_on_title_audio_preview_pressed) + title_audio_button_row.add_child(title_audio_preview_button) + title_audio_reset_button = Button.new() _configure_title_menu_button( title_audio_reset_button, "TitleAudioResetButton", "status", - "기본값 듣기", - "음악과 효과음을 켜고 75%로 되돌린 뒤 현재 음악, 확인음, 발소리, 타격음, 퇴각음, 보급음을 재생합니다.", - Vector2(350, 32) + "기본값", + "음악과 효과음을 켜고 크기를 75%로 되돌린 뒤 바로 소리를 확인합니다.", + Vector2(171, 32) ) title_audio_reset_button.pressed.connect(_on_title_audio_reset_pressed) - title_settings_column.add_child(title_audio_reset_button) + title_audio_button_row.add_child(title_audio_reset_button) title_edge_scroll_toggle = CheckButton.new() title_edge_scroll_toggle.text = "가장자리 스크롤" @@ -5563,7 +5598,9 @@ func _create_hud() -> void: title_load_manual_button, title_load_back_button, title_settings_back_button, + title_audio_preview_button, title_audio_reset_button, + settings_audio_preview_button, settings_audio_reset_button ]: _apply_button_style(hud_button) @@ -5717,11 +5754,11 @@ func _format_audio_status_text() -> String: var sfx_text := "효과음 꺼짐" if title_sfx_enabled: sfx_text = "효과음 %d%%" % title_sfx_volume_percent - return "%s\n%s · 미리듣기: %s" % [bgm_text, sfx_text, AUDIO_PREVIEW_LABEL] + return "%s\n%s · 소리 확인: %s" % [bgm_text, sfx_text, AUDIO_PREVIEW_LABEL] func _format_audio_status_tooltip() -> String: - return "현재 재생되는 음악과 기본값 듣기에서 확인할 효과음입니다.\n%s" % _format_audio_status_text() + return "현재 재생되는 음악과 소리 확인에서 들을 효과음입니다.\n%s" % _format_audio_status_text() func _format_audio_chip_hint_detail() -> String: @@ -15653,6 +15690,10 @@ func _on_settings_sfx_volume_changed(value: float) -> void: _on_title_sfx_volume_changed(value) +func _on_settings_audio_preview_pressed() -> void: + _preview_audio_mix() + + func _on_settings_audio_reset_pressed() -> void: _restore_audio_defaults(true) @@ -16498,6 +16539,25 @@ func _on_title_audio_reset_pressed() -> void: _restore_audio_defaults(true) +func _on_title_audio_preview_pressed() -> void: + _preview_audio_mix() + + +func _preview_audio_mix() -> void: + title_bgm_enabled = true + title_sfx_enabled = true + if title_bgm_volume_percent <= 0: + title_bgm_volume_percent = DEFAULT_AUDIO_VOLUME_PERCENT + if title_sfx_volume_percent <= 0: + title_sfx_volume_percent = DEFAULT_AUDIO_VOLUME_PERCENT + _apply_audio_settings() + _save_title_settings() + _refresh_title_volume_controls() + _update_title_menu_state() + _play_bgm(current_bgm_key if not current_bgm_key.is_empty() else "menu") + _play_audio_preview_sfx() + + func _restore_audio_defaults(play_preview: bool) -> void: title_bgm_enabled = true title_sfx_enabled = true diff --git a/tools/capture_readability_frames.gd b/tools/capture_readability_frames.gd index fe7b437..af2c246 100644 --- a/tools/capture_readability_frames.gd +++ b/tools/capture_readability_frames.gd @@ -69,6 +69,12 @@ func _capture_viewport_set(spec: Dictionary, output_dir: String, captures: Array await _capture_frame(scene, output_dir, label, "01_title", captures, failures) + scene._on_title_settings_pressed() + await _settle() + await _capture_frame(scene, output_dir, label, "01b_title_settings", captures, failures) + scene._on_title_settings_back_pressed() + await _settle() + scene._show_opening_prologue() await _settle() await _capture_frame(scene, output_dir, label, "02_opening_rebellion", captures, failures) diff --git a/tools/smoke_title_menu.gd b/tools/smoke_title_menu.gd index bd2de18..941a248 100644 --- a/tools/smoke_title_menu.gd +++ b/tools/smoke_title_menu.gd @@ -196,7 +196,7 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: failures.append("title settings should expose BGM and SFX volume sliders") if scene.title_audio_status_label == null: failures.append("title settings should describe the current audio mix") - elif not scene.title_audio_status_label.text.contains("현재 음악: 군막의 새벽") or not scene.title_audio_status_label.text.contains("미리듣기: 확인음"): + elif not scene.title_audio_status_label.text.contains("현재 음악: 군막의 새벽") or not scene.title_audio_status_label.text.contains("소리 확인: 확인음"): failures.append("title audio status should name the current BGM and preview SFX: %s" % scene.title_audio_status_label.text) scene._on_title_bgm_toggled(false) if scene.title_bgm_enabled: @@ -233,12 +233,29 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: if persisted_scene.title_bgm_volume_percent != 45 or persisted_scene.title_sfx_volume_percent != 35: failures.append("title settings volume values should persist into a new scene instance") persisted_scene.free() - if scene.title_audio_reset_button == null or scene.title_audio_reset_button.text != "기본값 듣기": - failures.append("title settings should expose a clear audio defaults preview button") + if scene.title_audio_preview_button == null or scene.title_audio_preview_button.text != "소리 확인": + failures.append("title settings should expose a clear sound preview button") + else: + _check_title_menu_button_art(failures, scene.title_audio_preview_button, "status", "title audio preview") + if not scene.title_audio_preview_button.tooltip_text.contains("확인음") or not scene.title_audio_preview_button.tooltip_text.contains("발소리") or not scene.title_audio_preview_button.tooltip_text.contains("타격음") or not scene.title_audio_preview_button.tooltip_text.contains("퇴각음") or not scene.title_audio_preview_button.tooltip_text.contains("보급음"): + failures.append("title audio preview should explain the confirmation, movement, strike, defeat, and supply samples") + if scene.title_audio_reset_button == null or scene.title_audio_reset_button.text != "기본값": + failures.append("title settings should expose a separate audio defaults button") else: _check_title_menu_button_art(failures, scene.title_audio_reset_button, "status", "title audio reset") - if not scene.title_audio_reset_button.tooltip_text.contains("확인음") or not scene.title_audio_reset_button.tooltip_text.contains("발소리") or not scene.title_audio_reset_button.tooltip_text.contains("타격음") or not scene.title_audio_reset_button.tooltip_text.contains("퇴각음") or not scene.title_audio_reset_button.tooltip_text.contains("보급음"): - failures.append("title audio preview should explain the confirmation, movement, strike, defeat, and supply samples") + if not scene.title_audio_reset_button.tooltip_text.contains("75%") or not scene.title_audio_reset_button.tooltip_text.contains("소리"): + failures.append("title audio defaults should explain that it restores audible defaults") + scene.recent_sfx_keys.clear() + scene._on_title_audio_preview_pressed() + if not scene.title_bgm_enabled or not scene.title_sfx_enabled: + failures.append("title audio preview should re-enable BGM and SFX") + if scene.title_bgm_volume_percent != 45 or scene.title_sfx_volume_percent != 35: + failures.append("title audio preview should preserve non-zero custom volumes") + if scene.bgm_player == null or scene.bgm_player.stream == null or scene.current_bgm_key.is_empty(): + failures.append("title audio preview should leave a playable BGM stream selected") + for preview_key in ["menu_confirm", "footstep", "slash", "defeat_sting", "item_pickup"]: + if not scene.recent_sfx_keys.has(preview_key): + failures.append("title audio preview should play %s" % preview_key) scene.recent_sfx_keys.clear() scene._on_title_audio_reset_pressed() if not scene.title_bgm_enabled or not scene.title_sfx_enabled: @@ -249,16 +266,9 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: failures.append("title audio recovery should leave a playable BGM stream selected") if scene.title_audio_status_label != null and (not scene.title_audio_status_label.text.contains("군막의 새벽") or not scene.title_audio_status_label.text.contains("%d%%" % BattleSceneScript.DEFAULT_AUDIO_VOLUME_PERCENT)): failures.append("title audio status should refresh after defaults preview: %s" % scene.title_audio_status_label.text) - if not scene.recent_sfx_keys.has("menu_confirm"): - failures.append("title audio preview should play an audible confirmation SFX") - if not scene.recent_sfx_keys.has("footstep"): - failures.append("title audio preview should play a movement footstep SFX") - if not scene.recent_sfx_keys.has("slash"): - failures.append("title audio preview should play a strike SFX") - if not scene.recent_sfx_keys.has("defeat_sting"): - failures.append("title audio preview should play a defeat SFX") - if not scene.recent_sfx_keys.has("item_pickup"): - failures.append("title audio preview should play a supply SFX") + for reset_preview_key in ["menu_confirm", "footstep", "slash", "defeat_sting", "item_pickup"]: + if not scene.recent_sfx_keys.has(reset_preview_key): + failures.append("title audio defaults should play %s" % reset_preview_key) scene._on_title_settings_back_pressed() if scene.title_settings_panel != null and scene.title_settings_panel.visible: failures.append("settings back should hide the title settings panel") @@ -494,10 +504,14 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: failures.append("in-game settings toggles should update the shared settings state") if scene.title_bgm_volume_percent != 70 or scene.title_sfx_volume_percent != 60: failures.append("in-game settings sliders should update the shared volume state") - if scene.settings_audio_reset_button == null or scene.settings_audio_reset_button.text != "기본값 듣기": - failures.append("in-game settings should expose a clear audio defaults preview button") - elif not scene.settings_audio_reset_button.tooltip_text.contains("현재 음악"): - failures.append("in-game audio preview should explain that it plays the current music") + if scene.settings_audio_preview_button == null or scene.settings_audio_preview_button.text != "소리 확인": + failures.append("in-game settings should expose a clear sound preview button") + elif not scene.settings_audio_preview_button.tooltip_text.contains("확인음") or not scene.settings_audio_preview_button.tooltip_text.contains("타격음"): + failures.append("in-game audio preview should explain audible SFX samples") + if scene.settings_audio_reset_button == null or scene.settings_audio_reset_button.text != "기본값": + failures.append("in-game settings should expose a separate audio defaults button") + elif not scene.settings_audio_reset_button.tooltip_text.contains("75%") or not scene.settings_audio_reset_button.tooltip_text.contains("소리"): + failures.append("in-game audio defaults should explain audible recovery") if scene.settings_audio_status_label != null and (not scene.settings_audio_status_label.text.contains("군막의 새벽") or not scene.settings_audio_status_label.text.contains("효과음 60%")): failures.append("in-game audio status should reflect battle BGM and SFX volume: %s" % scene.settings_audio_status_label.text) scene._on_settings_bgm_toggled(false) @@ -505,6 +519,19 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: scene._on_settings_bgm_volume_changed(20.0) scene._on_settings_sfx_volume_changed(15.0) scene.recent_sfx_keys.clear() + scene._on_settings_audio_preview_pressed() + if not scene.title_bgm_enabled or not scene.title_sfx_enabled: + failures.append("in-game audio preview should re-enable BGM and SFX") + if scene.title_bgm_volume_percent != 20 or scene.title_sfx_volume_percent != 15: + failures.append("in-game audio preview should preserve non-zero custom volumes") + for settings_preview_key in ["menu_confirm", "footstep", "slash", "defeat_sting", "item_pickup"]: + if not scene.recent_sfx_keys.has(settings_preview_key): + failures.append("in-game audio preview should play %s" % settings_preview_key) + scene._on_settings_bgm_toggled(false) + scene._on_settings_sfx_toggled(false) + scene._on_settings_bgm_volume_changed(20.0) + scene._on_settings_sfx_volume_changed(15.0) + scene.recent_sfx_keys.clear() scene._on_settings_audio_reset_pressed() if not scene.title_bgm_enabled or not scene.title_sfx_enabled: failures.append("in-game audio recovery should re-enable BGM and SFX") @@ -512,16 +539,9 @@ func _check_title_menu_start_load_and_settings(failures: Array[String]) -> void: failures.append("in-game audio recovery should restore audible volume defaults") if scene.settings_audio_status_label != null and (not scene.settings_audio_status_label.text.contains("군막의 새벽") or not scene.settings_audio_status_label.text.contains("%d%%" % BattleSceneScript.DEFAULT_AUDIO_VOLUME_PERCENT)): failures.append("in-game audio status should refresh after defaults preview: %s" % scene.settings_audio_status_label.text) - if not scene.recent_sfx_keys.has("menu_confirm"): - failures.append("in-game audio preview should play an audible confirmation SFX") - if not scene.recent_sfx_keys.has("footstep"): - failures.append("in-game audio preview should play a movement footstep SFX") - if not scene.recent_sfx_keys.has("slash"): - failures.append("in-game audio preview should play a strike SFX") - if not scene.recent_sfx_keys.has("defeat_sting"): - failures.append("in-game audio preview should play a defeat SFX") - if not scene.recent_sfx_keys.has("item_pickup"): - failures.append("in-game audio preview should play a supply SFX") + for settings_reset_preview_key in ["menu_confirm", "footstep", "slash", "defeat_sting", "item_pickup"]: + if not scene.recent_sfx_keys.has(settings_reset_preview_key): + failures.append("in-game audio defaults should play %s" % settings_reset_preview_key) scene._hide_settings_panel() scene._on_new_campaign_pressed() if not scene._is_opening_prologue_visible():