diff --git a/docs/PROJECT-STRUCTURE.md b/docs/PROJECT-STRUCTURE.md index fe70fa2..fbd4b23 100644 --- a/docs/PROJECT-STRUCTURE.md +++ b/docs/PROJECT-STRUCTURE.md @@ -169,6 +169,9 @@ simple hosts. `engine/Age.Engine/Hosting/IMovieHost.cs` owns ordinary, positione and modal movie playback contracts. `IHost` inherits all four focused contracts; their required and default behavior is unchanged. The neutral `engine/Age.Engine/Model/MovieMaskTransitionRequest.cs` record carries movie mask work between the VM, host, and retained graphics without making `Model` depend on `Hosting`. +`engine/Age.Engine/Model/RgbaImage.cs` owns the format-independent packed RGBA image transported between SYS4 +decoders, host surfaces, renderers, persistence, and tests; consumers do not depend on `Sys4` merely to exchange +decoded pixels. `engine/Age.Engine/Model/GfxState.cs` retains cross-domain retained-graphics coordination. `engine/Age.Engine/Model/GfxState.Contracts.cs` owns its public render, transition, diagnostic, persistence, diff --git a/docs/remake-architecture-and-roadmap.md b/docs/remake-architecture-and-roadmap.md index e6a6c73..979be4e 100644 --- a/docs/remake-architecture-and-roadmap.md +++ b/docs/remake-architecture-and-roadmap.md @@ -781,6 +781,11 @@ do not mix mechanical moves with semantic changes. removing the two now-unused imports eliminates `GfxState`'s reverse dependency on the host namespace. Runtime validation remains green. + The fifth bounded contract slice moved the unchanged, format-independent `RgbaImage` record from the SYS4 AGF + decoder file into `Model`. Decoders, renderers, persistence, Godot, tests, and the aggregate host now consume + the neutral image contract; image-only format imports were removed while genuine SYS4 consumers retained + theirs. Decoder and image behavior remain unchanged, and runtime validation remains green. + 4. **Make the build graph express source ownership.** Stop linking production `.cs` files from `godot/` and `tools/movie-corpus-gate/` into `Age.Engine.Tests`. Extract the platform-neutral frontend/movie/diagnostic code into a small production project referenced by Godot, tests, and the corpus gate. Retain both existing @@ -1141,8 +1146,8 @@ layer's rendering diverges from ADV; save layout. ## 8. Immediate next step Continue step 3 of the **codebase consolidation** maintenance slice: clarify runtime contracts without changing behavior or the aggregate host accepted by the VM. With diagnostic, lifecycle, audio, and movie contracts -established beneath `IHost` and the movie-mask request now neutral, move the format-independent `RgbaImage` record -from `Sys4` to `Model` next. Update its consumers without changing the record or decoder behavior, removing the -aggregate host's image-only dependency on the format namespace before separating larger host domains. +established beneath `IHost` and shared movie/image transport now neutral, introduce the graphics host contract +next. Preserve its surface, retained-range presentation, transition, texture, capture/replace, and headless-default +behavior while leaving the remaining surface request records in place for a separate transport cleanup. Concrete playthrough blockers may still preempt this bounded maintenance work; the consolidation effort does not replace Phase B gameplay validation or the open cross-platform gates. diff --git a/engine/Age.Engine.Tests/AgfDecoderTests.cs b/engine/Age.Engine.Tests/AgfDecoderTests.cs index af1b6de..8346447 100644 --- a/engine/Age.Engine.Tests/AgfDecoderTests.cs +++ b/engine/Age.Engine.Tests/AgfDecoderTests.cs @@ -1,4 +1,5 @@ using System.Buffers.Binary; +using Age.Engine.Model; using Age.Engine.Sys4; namespace Age.Engine.Tests; diff --git a/engine/Age.Engine.Tests/CurDecoderTests.cs b/engine/Age.Engine.Tests/CurDecoderTests.cs index ef8f37a..ec0a759 100644 --- a/engine/Age.Engine.Tests/CurDecoderTests.cs +++ b/engine/Age.Engine.Tests/CurDecoderTests.cs @@ -1,4 +1,5 @@ using System.Linq; +using Age.Engine.Model; using Age.Engine.Sys4; using Xunit; diff --git a/engine/Age.Engine.Tests/GlyphMaskCompositorTests.cs b/engine/Age.Engine.Tests/GlyphMaskCompositorTests.cs index 0f14b71..23fb9e4 100644 --- a/engine/Age.Engine.Tests/GlyphMaskCompositorTests.cs +++ b/engine/Age.Engine.Tests/GlyphMaskCompositorTests.cs @@ -1,5 +1,4 @@ using Age.Engine.Model; -using Age.Engine.Sys4; using Age.Engine.Text; public class GlyphMaskCompositorTests diff --git a/engine/Age.Engine.Tests/MovieCorpusGateTests.cs b/engine/Age.Engine.Tests/MovieCorpusGateTests.cs index 4dc8745..3e16e72 100644 --- a/engine/Age.Engine.Tests/MovieCorpusGateTests.cs +++ b/engine/Age.Engine.Tests/MovieCorpusGateTests.cs @@ -1,3 +1,4 @@ +using Age.Engine.Model; using Age.Engine.Sys4; public class MovieCorpusGateTests diff --git a/engine/Age.Engine.Tests/MovieSurfaceRegistryTests.cs b/engine/Age.Engine.Tests/MovieSurfaceRegistryTests.cs index f03fac6..72ebc9d 100644 --- a/engine/Age.Engine.Tests/MovieSurfaceRegistryTests.cs +++ b/engine/Age.Engine.Tests/MovieSurfaceRegistryTests.cs @@ -1,4 +1,4 @@ -using Age.Engine.Sys4; +using Age.Engine.Model; public class MovieSurfaceRegistryTests { diff --git a/engine/Age.Engine/Hosting/IHost.cs b/engine/Age.Engine/Hosting/IHost.cs index 7110403..55f2fd1 100644 --- a/engine/Age.Engine/Hosting/IHost.cs +++ b/engine/Age.Engine/Hosting/IHost.cs @@ -1,5 +1,4 @@ using Age.Engine.Model; -using Age.Engine.Sys4; namespace Age.Engine.Hosting; diff --git a/engine/Age.Engine/Model/RgbaImage.cs b/engine/Age.Engine/Model/RgbaImage.cs new file mode 100644 index 0000000..32247dc --- /dev/null +++ b/engine/Age.Engine/Model/RgbaImage.cs @@ -0,0 +1,4 @@ +namespace Age.Engine.Model; + +/// A decoded, tightly packed, top-down RGBA8 image. +public sealed record RgbaImage(int Width, int Height, byte[] Pixels); diff --git a/engine/Age.Engine/Persistence/NumberedThumbnailCodec.cs b/engine/Age.Engine/Persistence/NumberedThumbnailCodec.cs index 5b7b013..ed31ff3 100644 --- a/engine/Age.Engine/Persistence/NumberedThumbnailCodec.cs +++ b/engine/Age.Engine/Persistence/NumberedThumbnailCodec.cs @@ -1,5 +1,5 @@ using System.Buffers.Binary; -using Age.Engine.Sys4; +using Age.Engine.Model; namespace Age.Engine.Persistence; diff --git a/engine/Age.Engine/Sys4/AgfDecoder.cs b/engine/Age.Engine/Sys4/AgfDecoder.cs index 093aab8..5daa0f6 100644 --- a/engine/Age.Engine/Sys4/AgfDecoder.cs +++ b/engine/Age.Engine/Sys4/AgfDecoder.cs @@ -1,10 +1,8 @@ using System.Buffers.Binary; +using Age.Engine.Model; namespace Age.Engine.Sys4; -/// A decoded, tightly packed, top-down RGBA8 image. -public sealed record RgbaImage(int Width, int Height, byte[] Pixels); - /// /// Platform-neutral Eushully AGF decoder. Format algorithm ported from GARbro's MIT-licensed /// ArcFormats/Eushully/ImageAGF.cs (Copyright (C) 2015 morkt). diff --git a/engine/Age.Engine/Sys4/CurDecoder.cs b/engine/Age.Engine/Sys4/CurDecoder.cs index 71b9c71..2d537d7 100644 --- a/engine/Age.Engine/Sys4/CurDecoder.cs +++ b/engine/Age.Engine/Sys4/CurDecoder.cs @@ -1,4 +1,5 @@ using System.Buffers.Binary; +using Age.Engine.Model; namespace Age.Engine.Sys4; diff --git a/engine/Age.Engine/Sys4/ResourceMap.cs b/engine/Age.Engine/Sys4/ResourceMap.cs index ebb622a..13f73a2 100644 --- a/engine/Age.Engine/Sys4/ResourceMap.cs +++ b/engine/Age.Engine/Sys4/ResourceMap.cs @@ -1,3 +1,5 @@ +using Age.Engine.Model; + namespace Age.Engine.Sys4; /// diff --git a/engine/Age.Engine/Sys4/RgbaSurfaceOps.cs b/engine/Age.Engine/Sys4/RgbaSurfaceOps.cs index dd6a0e8..0a453cc 100644 --- a/engine/Age.Engine/Sys4/RgbaSurfaceOps.cs +++ b/engine/Age.Engine/Sys4/RgbaSurfaceOps.cs @@ -1,3 +1,5 @@ +using Age.Engine.Model; + namespace Age.Engine.Sys4; /// Platform-neutral mutation helpers for AGE's software-modeled RGBA surfaces. diff --git a/engine/Age.Engine/Text/AgeGlyphMaskCompositor.cs b/engine/Age.Engine/Text/AgeGlyphMaskCompositor.cs index af5b4e0..cca250f 100644 --- a/engine/Age.Engine/Text/AgeGlyphMaskCompositor.cs +++ b/engine/Age.Engine/Text/AgeGlyphMaskCompositor.cs @@ -1,5 +1,4 @@ using Age.Engine.Model; -using Age.Engine.Sys4; namespace Age.Engine.Text; diff --git a/engine/Age.Engine/Text/ImmediateSurfaceTextRenderer.cs b/engine/Age.Engine/Text/ImmediateSurfaceTextRenderer.cs index 1be823f..e8ae4c3 100644 --- a/engine/Age.Engine/Text/ImmediateSurfaceTextRenderer.cs +++ b/engine/Age.Engine/Text/ImmediateSurfaceTextRenderer.cs @@ -1,6 +1,5 @@ using System.Text; using Age.Engine.Model; -using Age.Engine.Sys4; namespace Age.Engine.Text; diff --git a/engine/Age.Engine/Text/RetainedGlyphLayoutEngine.cs b/engine/Age.Engine/Text/RetainedGlyphLayoutEngine.cs index 4bb824e..80040bf 100644 --- a/engine/Age.Engine/Text/RetainedGlyphLayoutEngine.cs +++ b/engine/Age.Engine/Text/RetainedGlyphLayoutEngine.cs @@ -1,5 +1,4 @@ using Age.Engine.Model; -using Age.Engine.Sys4; namespace Age.Engine.Text; diff --git a/godot/FfmpegMovieDecoder.cs b/godot/FfmpegMovieDecoder.cs index 763c50e..c41b324 100644 --- a/godot/FfmpegMovieDecoder.cs +++ b/godot/FfmpegMovieDecoder.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Collections.Generic; using System.Threading; +using Age.Engine.Model; using Age.Engine.Sys4; internal interface IMoviePacingClock diff --git a/godot/FfmpegMovieNative.cs b/godot/FfmpegMovieNative.cs index bbf3d3e..41ef522 100644 --- a/godot/FfmpegMovieNative.cs +++ b/godot/FfmpegMovieNative.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.InteropServices; +using Age.Engine.Model; using Age.Engine.Sys4; using Microsoft.Win32.SafeHandles; diff --git a/godot/GodotAdvHost.AdvText.cs b/godot/GodotAdvHost.AdvText.cs index 68f177a..dea535a 100644 --- a/godot/GodotAdvHost.AdvText.cs +++ b/godot/GodotAdvHost.AdvText.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Threading; using Age.Engine.Hosting; using Age.Engine.Model; -using Age.Engine.Sys4; using Age.Engine.Text; public sealed partial class GodotAdvHost diff --git a/godot/GpuRetainedRenderer.cs b/godot/GpuRetainedRenderer.cs index 4f78e81..cceaa5c 100644 --- a/godot/GpuRetainedRenderer.cs +++ b/godot/GpuRetainedRenderer.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using Godot; using Age.Engine.Model; -using Age.Engine.Sys4; /// /// Godot-native presentation of AGE's sampled retained objects. Static decoded/color-key variants are diff --git a/godot/IMovieDecoder.cs b/godot/IMovieDecoder.cs index 5a6fa1d..5f8ebbd 100644 --- a/godot/IMovieDecoder.cs +++ b/godot/IMovieDecoder.cs @@ -1,4 +1,5 @@ using System; +using Age.Engine.Model; using Age.Engine.Sys4; internal readonly record struct MovieAudioInfo(int SampleRate, int Channels); diff --git a/godot/Main.Compositor.cs b/godot/Main.Compositor.cs index 7697a85..e67b79c 100644 --- a/godot/Main.Compositor.cs +++ b/godot/Main.Compositor.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Godot; using Age.Engine.Model; -using Age.Engine.Sys4; public partial class Main { diff --git a/godot/MovieSurfaceRegistry.cs b/godot/MovieSurfaceRegistry.cs index c5b9047..c6c8cee 100644 --- a/godot/MovieSurfaceRegistry.cs +++ b/godot/MovieSurfaceRegistry.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Age.Engine.Sys4; +using Age.Engine.Model; internal readonly record struct MovieSurfaceBinding(long PlaybackId, long ResourceId, int SurfaceSlot); internal sealed record MovieSurfaceFrame(RgbaImage Image, string Name, int AssetId);