port: verify root pack ledger and repair runtime adapters
This commit is contained in:
+42
-19
@@ -20,8 +20,9 @@ var _ui_next := 0
|
||||
var master_sound := 1.0
|
||||
var master_music := 1.0
|
||||
|
||||
# 3D 循环音效实例:id -> AudioStreamPlayer3D
|
||||
# 3D 循环音效实例:id -> AudioStreamPlayer3D;所有 3D 播放器用于 StopAll。
|
||||
var _active_3d := {}
|
||||
var _all_3d: Array[AudioStreamPlayer3D] = []
|
||||
|
||||
func _ready() -> void:
|
||||
_init_roots()
|
||||
@@ -111,16 +112,23 @@ func _find_sound(rel: String) -> String:
|
||||
elif rel.begins_with("d:/") or rel.begins_with("D:/"):
|
||||
rel = rel.substr(3)
|
||||
|
||||
# 1. 尝试直接路径
|
||||
if FileAccess.file_exists(rel):
|
||||
return rel
|
||||
|
||||
# 2. 补全扩展名候选
|
||||
# 补全扩展名候选
|
||||
var cands := PackedStringArray([rel])
|
||||
if rel.get_extension().is_empty():
|
||||
cands = PackedStringArray([rel + ".wav", rel + ".mp3", rel + ".ogg"])
|
||||
|
||||
# 3. 在所有已知根目录中遍历查找
|
||||
# 40250's CEterPackManager is the authority for sounds, as it is for models and UI images.
|
||||
if ClassDB.class_exists("Metin2Pack") and Metin2Pack.is_ready():
|
||||
for c in cands:
|
||||
if Metin2Pack.exists(c):
|
||||
return "pack://" + c
|
||||
if not c.begins_with("sound/") and Metin2Pack.exists("sound/" + c):
|
||||
return "pack://sound/" + c
|
||||
|
||||
if FileAccess.file_exists(rel):
|
||||
return rel
|
||||
|
||||
# 开发期散文件兜底。
|
||||
for root in _sound_roots:
|
||||
for c in cands:
|
||||
var p := root.path_join(c)
|
||||
@@ -139,14 +147,21 @@ func _load_stream(path: String) -> AudioStream:
|
||||
return _cache[path]
|
||||
var s: AudioStream = null
|
||||
var ext := path.get_extension().to_lower()
|
||||
var bytes: PackedByteArray
|
||||
if path.begins_with("pack://"):
|
||||
bytes = Metin2Pack.get_bytes(path.substr(7))
|
||||
else:
|
||||
bytes = FileAccess.get_file_as_bytes(path)
|
||||
if bytes.is_empty():
|
||||
return null
|
||||
if ext == "mp3":
|
||||
var m := AudioStreamMP3.new()
|
||||
m.data = FileAccess.get_file_as_bytes(path)
|
||||
m.data = bytes
|
||||
s = m if m.data.size() > 0 else null
|
||||
elif ext == "ogg":
|
||||
s = AudioStreamOggVorbis.load_from_file(path)
|
||||
s = AudioStreamOggVorbis.load_from_buffer(bytes)
|
||||
elif ext == "wav":
|
||||
s = AudioStreamWAV.load_from_file(path)
|
||||
s = AudioStreamWAV.load_from_buffer(bytes)
|
||||
_cache[path] = s
|
||||
return s
|
||||
|
||||
@@ -164,7 +179,8 @@ func play_sound_2d(rel: String, volume_scale := 1.0) -> void:
|
||||
var pl := _ui_pool[_ui_next]
|
||||
_ui_next = (_ui_next + 1) % _ui_pool.size()
|
||||
pl.stream = stream
|
||||
var vol: float = clampf(master_sound * volume_scale, 0.0, 1.0)
|
||||
# SoundManager already applied the current master volume to this command.
|
||||
var vol: float = clampf(volume_scale, 0.0, 1.0)
|
||||
pl.volume_db = linear_to_db(vol) if vol > 0.001 else -80.0
|
||||
pl.play()
|
||||
|
||||
@@ -181,28 +197,35 @@ func play_sound_3d(rel: String, pos: Vector3, volume_scale := 1.0, sound_id := 0
|
||||
pl.stream = stream
|
||||
pl.unit_size = 8.0
|
||||
pl.max_distance = 80.0
|
||||
var vol: float = clampf(master_sound * volume_scale, 0.0, 1.0)
|
||||
var vol: float = clampf(volume_scale, 0.0, 1.0)
|
||||
pl.volume_db = linear_to_db(vol) if vol > 0.001 else -80.0
|
||||
add_child(pl)
|
||||
_all_3d.append(pl)
|
||||
pl.global_position = pos
|
||||
pl.play()
|
||||
if sound_id > 0:
|
||||
_active_3d[sound_id] = pl
|
||||
pl.finished.connect(func(): _active_3d.erase(sound_id); pl.queue_free())
|
||||
else:
|
||||
pl.finished.connect(pl.queue_free)
|
||||
pl.finished.connect(func():
|
||||
_all_3d.erase(pl)
|
||||
if sound_id > 0 and _active_3d.get(sound_id) == pl:
|
||||
_active_3d.erase(sound_id)
|
||||
pl.queue_free())
|
||||
|
||||
func stop_sound_3d(sound_id: int) -> void:
|
||||
if _active_3d.has(sound_id):
|
||||
var pl: AudioStreamPlayer3D = _active_3d[sound_id]
|
||||
if is_instance_valid(pl):
|
||||
pl.stop()
|
||||
_all_3d.erase(pl)
|
||||
pl.queue_free()
|
||||
_active_3d.erase(sound_id)
|
||||
|
||||
func stop_all_sound_3d() -> void:
|
||||
for id in _active_3d.keys():
|
||||
stop_sound_3d(id)
|
||||
for pl in _all_3d:
|
||||
if is_instance_valid(pl):
|
||||
pl.stop()
|
||||
pl.queue_free()
|
||||
_all_3d.clear()
|
||||
_active_3d.clear()
|
||||
|
||||
# --- BGM 背景音乐播放 -----------------------------------------------------
|
||||
@@ -210,7 +233,6 @@ func stop_all_sound_3d() -> void:
|
||||
func play_music(name: String, volume_scale := 1.0) -> void:
|
||||
if name.is_empty() or name == _bgm_name:
|
||||
return
|
||||
_bgm_name = name
|
||||
|
||||
var path := name.replace("\\", "/")
|
||||
if not path.is_absolute_path():
|
||||
@@ -225,6 +247,7 @@ func play_music(name: String, volume_scale := 1.0) -> void:
|
||||
var stream := _load_stream(path)
|
||||
if stream == null:
|
||||
return
|
||||
_bgm_name = name
|
||||
if stream is AudioStreamMP3:
|
||||
stream.loop = true
|
||||
|
||||
@@ -233,7 +256,7 @@ func play_music(name: String, volume_scale := 1.0) -> void:
|
||||
_bgm[nxt].volume_db = -40.0
|
||||
_bgm[nxt].play()
|
||||
|
||||
var target_vol: float = clampf(master_music * volume_scale, 0.0, 1.0)
|
||||
var target_vol: float = clampf(volume_scale, 0.0, 1.0)
|
||||
var target_db: float = linear_to_db(target_vol) if target_vol > 0.001 else -80.0
|
||||
|
||||
if _bgm_fade_tween and _bgm_fade_tween.is_valid():
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
extends SceneTree
|
||||
|
||||
var failures := 0
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("_run")
|
||||
|
||||
func _check(ok: bool, detail: String) -> void:
|
||||
if not ok:
|
||||
failures += 1
|
||||
printerr("FAIL: " + detail)
|
||||
|
||||
func _run() -> void:
|
||||
_check(AssetRoot.pack_ready(), "40250 pack unavailable")
|
||||
var driver: Node = preload("res://audio_driver.gd").new()
|
||||
root.add_child(driver)
|
||||
var sound := "sound/ambience/waterfall.wav"
|
||||
var path: String = driver._find_sound(sound)
|
||||
_check(path == "pack://" + sound, "sound must resolve through 40250 pack")
|
||||
var stream: AudioStream = driver._load_stream(path)
|
||||
_check(stream != null, "packed WAV must decode")
|
||||
if stream != null:
|
||||
driver.set_sound_volume(0.5)
|
||||
driver.play_sound_2d(sound, 0.5)
|
||||
var player: AudioStreamPlayer = driver._ui_pool[0]
|
||||
_check(absf(player.volume_db - linear_to_db(0.5)) < 0.01,
|
||||
"sound volume was applied more than once")
|
||||
driver.play_sound_3d(sound, Vector3.ZERO, 0.5)
|
||||
_check(driver._all_3d.size() == 1, "3D sound not tracked")
|
||||
driver.stop_all_sound_3d()
|
||||
_check(driver._all_3d.is_empty(), "StopAllSound3D left a player running")
|
||||
driver.free()
|
||||
print("PASS: audio_driver_test" if failures == 0 else "FAIL: audio_driver_test")
|
||||
quit(0 if failures == 0 else 1)
|
||||
Reference in New Issue
Block a user