Migrate audio payloads onto asset VFS
This commit is contained in:
@@ -4,7 +4,7 @@ namespace Age.Engine.Sys4;
|
||||
/// Compatibility facade over the runtime SYS4 catalog. SYS4INI's file list is sectioned (one per scene: SCxxxx.BIN + its
|
||||
/// cross-archive asset manifest); file_number is the index within a section. So a bytecode
|
||||
/// resId resolves as files[section_base(scene) + resId] -- unified for graphics and audio.
|
||||
/// See docs/asset-resolution-re.md. Extracted paths remain temporary graphics/audio backends only.
|
||||
/// See docs/asset-resolution-re.md.
|
||||
/// </summary>
|
||||
public sealed class ResourceMap
|
||||
{
|
||||
@@ -40,27 +40,29 @@ public sealed class ResourceMap
|
||||
public AssetEntry? ResolveName(string name) => _catalog.ResolveName(name);
|
||||
|
||||
/// <summary>
|
||||
/// Resolve a BGM id to its OGG path. BGM is addressed by DIRECT LITERAL NAME (BGM{id:D3}.OGG), NOT the
|
||||
/// Resolve a BGM id to its catalog entry. BGM is addressed by DIRECT LITERAL NAME (BGM{id:D3}.OGG), NOT the
|
||||
/// per-scene section manifest that voices/textures use. Confirmed by ear (play-bgm 5->BGM005, 8->BGM008)
|
||||
/// and by the play-bgm 0x23->BGM035 case: BGM035 is a real standalone track (the BGM set skips 030-034),
|
||||
/// which the manifest mis-resolved to a graphics entry. See docs/asset-resolution-re.md.
|
||||
/// </summary>
|
||||
public string? BgmPathById(long id)
|
||||
public AssetEntry? ResolveBgm(long id)
|
||||
{
|
||||
var name = $"BGM{id:D3}.OGG";
|
||||
var f = _catalog.ResolveName(name);
|
||||
return f == null ? null : AudioPath(f);
|
||||
var entry = _catalog.ResolveName(name);
|
||||
return entry is { IsPlaceholder: false } && IsAudio(entry) ? entry : null;
|
||||
}
|
||||
|
||||
/// <summary>Loose extracted OGG/WAV path for an audio asset (extracted/DATA{n}/{name}), or null.
|
||||
/// Used by the current bootstrap audio backend; voices and SFX use the scene manifest via Resolve.</summary>
|
||||
public static string? AudioPath(AssetEntry a)
|
||||
/// <summary>Read a catalog-resolved OGG/WAV payload through the loose-first ALF/AAI byte store.</summary>
|
||||
public AudioPayload ReadAudio(AssetEntry entry)
|
||||
{
|
||||
if (!a.Name.EndsWith(".OGG", StringComparison.OrdinalIgnoreCase) &&
|
||||
!a.Name.EndsWith(".WAV", StringComparison.OrdinalIgnoreCase)) return null;
|
||||
var dir = a.Archive.EndsWith(".ALF", StringComparison.OrdinalIgnoreCase)
|
||||
? a.Archive[..^4] : a.Archive; // "DATA3.ALF" -> "DATA3"
|
||||
var audio = Path.Combine(Paths.Extracted, dir, a.Name);
|
||||
return File.Exists(audio) ? audio : null;
|
||||
if (entry.IsPlaceholder || !IsAudio(entry))
|
||||
throw new InvalidDataException($"not an OGG/WAV asset: {entry.Name}");
|
||||
return new AudioPayload(entry.Name, _store.ReadAll(entry));
|
||||
}
|
||||
|
||||
private static bool IsAudio(AssetEntry entry)
|
||||
=> entry.Name.EndsWith(".OGG", StringComparison.OrdinalIgnoreCase)
|
||||
|| entry.Name.EndsWith(".WAV", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public sealed record AudioPayload(string Name, byte[] Bytes);
|
||||
|
||||
Reference in New Issue
Block a user