Use universal packed resource resolution
This commit is contained in:
@@ -75,7 +75,7 @@ public class AgfDecoderTests
|
||||
var catalog = Sys4AssetCatalog.Load(Paths.Sys4Ini);
|
||||
var store = new Sys4AssetStore(catalog, Paths.GameDir, Paths.GameDir);
|
||||
var resources = new ResourceMap(catalog, store);
|
||||
Assert.Equal("SO001.AGF", resources.ResolveTexture("SC0000", 0x337e)?.Name);
|
||||
Assert.Equal("SO001.AGF", resources.ResolveTexture(0x337e)?.Name);
|
||||
var image = AgfDecoder.Decode(store, catalog.ResolveRaw(0x337e)!);
|
||||
Assert.Equal((800, 300), (image.Width, image.Height));
|
||||
Assert.Contains(image.Pixels.Where((_, i) => (i & 3) == 3), a => a is > 0 and < 255);
|
||||
@@ -89,7 +89,7 @@ public class AgfDecoderTests
|
||||
public void InstalledFieldMapSheetsResolveAndDecodeByRawCatalogIndex(int rawId, string name)
|
||||
{
|
||||
var resources = ResourceMap.Load();
|
||||
var asset = resources.ResolveRawTexture(rawId);
|
||||
var asset = resources.ResolveTexture(rawId);
|
||||
Assert.NotNull(asset);
|
||||
Assert.Equal(name, asset.Name);
|
||||
var image = resources.DecodeTexture(asset);
|
||||
|
||||
@@ -15,7 +15,6 @@ public class CallScriptTests
|
||||
{
|
||||
public virtual void EnterScriptContext(string scriptName) { }
|
||||
public virtual void ExitScriptContext() { }
|
||||
public virtual long ResolveTextureResourceId(long resourceId) => resourceId;
|
||||
public void ShowText(int o, string t) { }
|
||||
public void WaitForInput() { }
|
||||
public void Sleep(long duration) { }
|
||||
@@ -52,9 +51,6 @@ public class CallScriptTests
|
||||
Events.Add($"exit:{_contexts.Pop()}");
|
||||
}
|
||||
|
||||
public override long ResolveTextureResourceId(long resourceId)
|
||||
=> resourceId + (_contexts.Peek() == "CALLEE" ? 700 : 70);
|
||||
|
||||
public override void SetTexture(long resourceId, int slot) => Textures.Add((resourceId, slot));
|
||||
}
|
||||
|
||||
@@ -133,7 +129,7 @@ public class CallScriptTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScriptLocalTextureIdsFollowTheActiveNestedFrame()
|
||||
public void PackedTextureIdsRemainUnchangedAcrossNestedFrames()
|
||||
{
|
||||
var t = Table();
|
||||
var callee = Asm(t, "CALLEE",
|
||||
@@ -149,7 +145,7 @@ public class CallScriptTests
|
||||
|
||||
vm.Run();
|
||||
|
||||
Assert.Equal(new[] { (77L, 1), (707L, 2), (77L, 3) }, host.Textures);
|
||||
Assert.Equal(new[] { (7L, 1), (7L, 2), (7L, 3) }, host.Textures);
|
||||
Assert.Equal(new[] { "enter:CALLER", "enter:CALLEE", "exit:CALLEE", "exit:CALLER" }, host.Events);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class GfxCommandBufferTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RawTextureLoadBypassesSceneResourceNormalizationAndFeedsRetainedDraws()
|
||||
public void ModeOneTextureLoadPreservesPackedIdAndFeedsRetainedDraws()
|
||||
{
|
||||
var t = T();
|
||||
var scene = ScriptAssembler.Assemble(t, "RAW-GFX", new List<(int, Operand[])>
|
||||
@@ -135,7 +135,7 @@ public class GfxCommandBufferTests
|
||||
(0x1fb, new[] { I(0x100), I(0x3e), I(0), I(0), I(100), I(100), I(20), I(30) }),
|
||||
Exit(),
|
||||
}, System.Array.Empty<string>());
|
||||
var host = new RecordingHost { TextureResourceIdOffset = 0x1000 };
|
||||
var host = new RecordingHost();
|
||||
var vm = new VirtualMachine(scene, t, host);
|
||||
|
||||
vm.Run();
|
||||
|
||||
@@ -342,7 +342,7 @@ public class HistoryInteractionOpsTests
|
||||
Assert.Equal(new[] { (expectedVoice, checked((int)expectedVariant)) }, host.VoiceRequests);
|
||||
|
||||
var resources = ResourceMap.Load();
|
||||
var voice = Assert.IsType<AssetEntry>(resources.Resolve("SC0000", expectedVoice));
|
||||
var voice = Assert.IsType<AssetEntry>(resources.ResolveVoice(expectedVoice));
|
||||
Assert.Equal("MAN999.OGG", voice.Name);
|
||||
Assert.NotEmpty(resources.ReadAudio(voice).Bytes);
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ public class MovieOpcodeTests
|
||||
{
|
||||
var catalog = Sys4AssetCatalog.Load(Paths.Sys4Ini);
|
||||
var resources = new ResourceMap(catalog, new Sys4AssetStore(catalog, Paths.GameDir));
|
||||
var entry = resources.Resolve("SC0000", 0x33);
|
||||
var entry = resources.ResolveMovie(0x33);
|
||||
|
||||
Assert.Equal("CHAPTER.AGF", entry?.Name);
|
||||
var movie = resources.ReadMovie(entry!);
|
||||
@@ -207,11 +207,11 @@ public class MovieOpcodeTests
|
||||
[Theory]
|
||||
[InlineData(0x335f, "LOGO.AGF")]
|
||||
[InlineData(0x3364, "OP.AGF")]
|
||||
public void ModalMoviePayloadResolvesFromUniversalRawCatalog(int rawId, string expectedName)
|
||||
public void ModalMoviePayloadResolvesFromUniversalPackedCatalog(int resourceId, string expectedName)
|
||||
{
|
||||
var catalog = Sys4AssetCatalog.Load(Paths.Sys4Ini);
|
||||
var resources = new ResourceMap(catalog, new Sys4AssetStore(catalog, Paths.GameDir));
|
||||
var entry = resources.ResolveRawMovie(rawId);
|
||||
var entry = resources.ResolveMovie(resourceId);
|
||||
|
||||
Assert.Equal(expectedName, entry?.Name);
|
||||
var movie = resources.ReadMovie(entry!);
|
||||
@@ -224,7 +224,7 @@ public class MovieOpcodeTests
|
||||
if (!OperatingSystem.IsWindows()) return;
|
||||
var catalog = Sys4AssetCatalog.Load(Paths.Sys4Ini);
|
||||
var resources = new ResourceMap(catalog, new Sys4AssetStore(catalog, Paths.GameDir));
|
||||
var entry = resources.Resolve("SC0000", 0x33)!;
|
||||
var entry = resources.ResolveMovie(0x33)!;
|
||||
using var decoder = new DirectShowMovieDecoder(resources.ReadMovie(entry));
|
||||
|
||||
Assert.True(decoder.StopTimeMs > 0, "DirectShow should expose a positive IMediaPosition stop time");
|
||||
|
||||
@@ -22,6 +22,7 @@ public class Sys4AssetStoreTests
|
||||
Assert.All(append.Files, entry =>
|
||||
{
|
||||
Assert.Equal(1, entry.PackId);
|
||||
Assert.Equal(0x01000000 | entry.RawIndex, entry.PackedId);
|
||||
Assert.StartsWith("$1$", entry.Name);
|
||||
Assert.Equal("APPEND01.ALF", entry.Archive);
|
||||
});
|
||||
@@ -178,14 +179,14 @@ public class Sys4AssetStoreTests
|
||||
Assert.Equal("BGM005.OGG", bgm?.Name);
|
||||
AssertOgg(resources.ReadAudio(bgm!));
|
||||
|
||||
var voice = resources.ResolveVoice("SC0000", 0x24);
|
||||
var voice = resources.ResolveVoice(0x24);
|
||||
Assert.Equal("MAN999.OGG", voice?.Name);
|
||||
AssertOgg(resources.ReadAudio(voice!));
|
||||
|
||||
var roomVoice = resources.ResolveVoice("ROOM", 0x3365);
|
||||
var roomVoice = resources.ResolveVoice(0x3365);
|
||||
Assert.Equal("EUA0016.OGG", roomVoice?.Name);
|
||||
AssertOgg(resources.ReadAudio(roomVoice!));
|
||||
Assert.Null(resources.ResolveVoice("ROOM", 0x337e)); // SO001.AGF is not voice audio.
|
||||
Assert.Null(resources.ResolveVoice(0x337e)); // SO001.AGF is not voice audio.
|
||||
|
||||
var sfx = resources.ResolveSoundEffect(0x28);
|
||||
Assert.Equal("E0808.WAV", sfx?.Name);
|
||||
@@ -194,7 +195,6 @@ public class Sys4AssetStoreTests
|
||||
Assert.Equal("RIFF", Encoding.ASCII.GetString(wav.Bytes, 0, 4));
|
||||
Assert.Equal("WAVE", Encoding.ASCII.GetString(wav.Bytes, 8, 4));
|
||||
|
||||
Assert.Null(resources.Resolve("TITLE", 0x2aea));
|
||||
Assert.Equal("SE020.WAV", resources.ResolveSoundEffect(0x2aea)?.Name);
|
||||
Assert.Equal("SE013.WAV", resources.ResolveSoundEffect(0x2aeb)?.Name);
|
||||
Assert.Equal("SE015.WAV", resources.ResolveSoundEffect(0x3321)?.Name);
|
||||
@@ -204,6 +204,33 @@ public class Sys4AssetStoreTests
|
||||
Assert.Throws<InvalidDataException>(() => resources.ReadAudio(catalog.ResolveName("SO001.AGF")!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Sc0010LowOperandsAreAlreadyUniversalPackedIds()
|
||||
{
|
||||
var resources = ResourceMap.Load();
|
||||
|
||||
Assert.Equal("SO013A.AGF", resources.ResolveTexture(0x21)?.Name);
|
||||
Assert.Equal("LILA1414.OGG", resources.ResolveVoice(0x120)?.Name);
|
||||
Assert.Equal("LILB0053.OGG", resources.ResolveVoice(0x121)?.Name);
|
||||
Assert.Equal("LILC0054.OGG", resources.ResolveVoice(0x122)?.Name);
|
||||
|
||||
var catalog = Sys4AssetCatalog.Load(Paths.Sys4Ini);
|
||||
Assert.Equal("COL0023.OGG", catalog.ResolveRaw(0x11e + 0x21)?.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TypedResourceResolutionPreservesAppendPackSelector()
|
||||
{
|
||||
var catalog = Sys4AssetCatalog.Load(Paths.Sys4Ini);
|
||||
var resources = new ResourceMap(catalog);
|
||||
var append = Assert.Single(catalog.AppendPacks).Value;
|
||||
var texture = Assert.Single(append.Files.Where(entry =>
|
||||
entry.Name.EndsWith(".AGF", StringComparison.OrdinalIgnoreCase)).Take(1));
|
||||
|
||||
Assert.Same(texture, resources.ResolveTexture(texture.PackedId));
|
||||
Assert.NotEqual(texture, resources.ResolveTexture(texture.RawIndex));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllInstalledLooseScriptOverridesShadowArchiveCopies()
|
||||
{
|
||||
|
||||
@@ -55,9 +55,7 @@ internal class RecordingHost : IHost
|
||||
public readonly List<bool> AdvPagePresentationSuspended = new();
|
||||
public int CursorClearCount;
|
||||
public int SceneContextResets;
|
||||
public long TextureResourceIdOffset;
|
||||
public void ReportWarning(string message) => Warnings.Add(message);
|
||||
public long ResolveTextureResourceId(long resourceId) => resourceId + TextureResourceIdOffset;
|
||||
public void ShowText(int offset, string text) => Lines.Add((offset, text));
|
||||
public void SetAdvTextCursor(int layoutSlot, int x, int y) => TextCursors.Add((layoutSlot, x, y));
|
||||
public void DrawStringToSurface(int surfaceSlot, int x, int y, string text)
|
||||
@@ -162,8 +160,8 @@ internal class RecordingHost : IHost
|
||||
return MovieStopTimeMs;
|
||||
}
|
||||
public bool IsMovieSurfaceActive(int surfaceSlot) => ActiveMovieSurfaces.Contains(surfaceSlot);
|
||||
public void PlayModalMovieToSurface(long rawResourceId, int surfaceSlot, long movieFlags)
|
||||
=> ModalMovies.Add((rawResourceId, surfaceSlot, movieFlags));
|
||||
public void PlayModalMovieToSurface(long resourceId, int surfaceSlot, long movieFlags)
|
||||
=> ModalMovies.Add((resourceId, surfaceSlot, movieFlags));
|
||||
}
|
||||
|
||||
internal sealed class MapProvider : IScriptProvider
|
||||
|
||||
Reference in New Issue
Block a user