From 3291f86f382fa47c0109eb7754090f3b1e0fd552 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Sun, 2 Aug 2026 21:08:05 -0400 Subject: [PATCH] Split GfxState public contracts --- docs/PROJECT-STRUCTURE.md | 2 + docs/remake-architecture-and-roadmap.md | 9 +- engine/Age.Engine/Model/GfxState.Contracts.cs | 101 ++++++++++++++++++ engine/Age.Engine/Model/GfxState.cs | 97 ----------------- 4 files changed, 110 insertions(+), 99 deletions(-) create mode 100644 engine/Age.Engine/Model/GfxState.Contracts.cs diff --git a/docs/PROJECT-STRUCTURE.md b/docs/PROJECT-STRUCTURE.md index a36e21d..477cf84 100644 --- a/docs/PROJECT-STRUCTURE.md +++ b/docs/PROJECT-STRUCTURE.md @@ -107,6 +107,8 @@ S:\Game Hacking\Eushully\Himegari\ ← workspace root (three siblings) │ └── manifest.json, opcode-coverage.md (opcode-coverage.md GENERATED from opcodes.toml) │ ├── engine/ DELIVERABLE — the .NET VM core (AgeEngine.sln: Age.Engine / Age.Cli / tests) + │ ├── Age.Engine/Model/ retained graphics state plus separately navigable public + │ render, transition, diagnostic, and persistence contracts │ ├── Age.Engine/Sys4/ runtime game-root selection, catalog parser, loose-first bounded │ ALF asset store, script provider, AGF/LZSS and Windows CUR decoders, │ and resource facade diff --git a/docs/remake-architecture-and-roadmap.md b/docs/remake-architecture-and-roadmap.md index d09ab85..c81a826 100644 --- a/docs/remake-architecture-and-roadmap.md +++ b/docs/remake-architecture-and-roadmap.md @@ -596,6 +596,11 @@ do not mix mechanical moves with semantic changes. scene reset, and frame-pulse consumers retain direct access through the sealed partial class. The planned host decomposition is complete; runtime validation remains green. + The first bounded `GfxState` split moved its public render, transition, diagnostic, persistence, animation, + numeric-glyph, and handle-range value contracts into `engine/Age.Engine/Model/GfxState.Contracts.cs`. + `GfxState` remains the same sealed runtime type, and every moved declaration is textually unchanged; runtime + validation remains green. + **Gate:** no externally visible behavior or command changes; generated artifacts are byte-identical where deterministic, and the corresponding engine, Python, Godot, and corpus validations remain green after each domain move. @@ -967,7 +972,7 @@ layer's rendering diverges from ADV; save layout. ## 8. Immediate next step Continue step 2 of the **codebase consolidation** maintenance slice: behavior-neutral physical splits backed by the tracked launcher and layered validation driver. With the planned `Main` and `GodotAdvHost` domains -isolated, begin the `GfxState` decomposition with one existing ownership domain at a time, preserving public -types, commands, and generated output. +isolated and the `GfxState` public contract layer separated, move `GfxState` surface ownership next, preserving +public types, commands, and generated output. 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/Model/GfxState.Contracts.cs b/engine/Age.Engine/Model/GfxState.Contracts.cs new file mode 100644 index 0000000..7145f08 --- /dev/null +++ b/engine/Age.Engine/Model/GfxState.Contracts.cs @@ -0,0 +1,101 @@ +using Age.Engine.Hosting; + +namespace Age.Engine.Model; + +/// The sampled native one-shot channels carried to the compositor: op 0x21e scale, op 0x21f +/// axis-angle rotation, and op 0x220 translation. Z is retained through full 4x4 composition. +public readonly record struct TransformState(double ScaleX, double ScaleY, double ScaleZ, + double TranslateX, double TranslateY, double TranslateZ, + double AnchorX, double AnchorY, double AnchorZ, + double RotationAxisX = 0, double RotationAxisY = 0, + double RotationAxisZ = 0, double RotationAngleDegrees = 0); + +public readonly record struct RotationCycleState(bool Enabled, long PeriodMs, + double AxisX, double AxisY, double AxisZ, + double AngleDegrees = 0); + +public readonly record struct ScaleCycleState(bool Enabled, long PeriodMs, + double ScaleX, double ScaleY, double ScaleZ); + +[System.Flags] +public enum GfxPresentationReason +{ + None = 0, + RetainedMutation = 1, + ContinuousChannel = 2, + DiscreteSourceCell = 4, +} + +/// Sampled op-0x223 type-0 surface transition. Range A is already present in normal z-order; +/// the compositor draws range B over it with to form the native crossfade. +public readonly record struct SurfaceTransitionState(long CommandKey, int TargetSlot, + long RangeAStart, int RangeACount, long RangeBStart, int RangeBCount, + long DelayMs, long DurationMs, long StartMs, double Progress, bool Forced); + +public readonly record struct MovieMaskTransitionState( + MovieMaskTransitionRequest Request, bool Completed); + +/// One synchronized sample of op 0x202's native one-shot packed-color channel. +public readonly record struct ColorTransitionState(long Current, long Target, + long DelayMs, long DurationMs, long StartMs, double Progress, bool Active); + +/// One EngineCtx numeric-glyph style registered by opcode 0x13a. +public readonly record struct NumericGlyphStyle(int SurfaceSlot, int AtlasX, int AtlasY, + int DigitWidth, int DigitHeight) +{ + public bool Registered => SurfaceSlot != 0; +} + +public sealed record BlockingGfxObjectDiagnostic( + long Handle, int SourceSlot, long StartMs, long ControlFlags, + bool ColorEnabled, long ColorDelayMs, long ColorDurationMs, + bool ScaleEnabled, long ScaleDelayMs, long ScaleDurationMs, + bool RotationEnabled, long RotationDelayMs, long RotationDurationMs, + bool TranslationEnabled, long TranslationDelayMs, long TranslationDurationMs); + +public sealed record GfxDiagnosticSnapshot( + long NowMs, bool HasActiveTimedPresentation, int ObjectCount, int VisibleObjectCount, + int ActiveSurfaceTransitionCount, long AnimationServiceFlags, + long AnimClockDurationTicks, long AnimClockGeneration, + uint PreviousFrameTimeMilliseconds, uint CurrentFrameTimeMilliseconds, + long RangeTransformFirst, long RangeTransformCount, + BlockingGfxObjectDiagnostic? BlockingRangeTransform, + IReadOnlyList BlockingObjects); + +public readonly record struct GfxSurfacePersistenceState( + int Slot, long ResourceId, long ColorKey, bool Created, bool ReloadOnRestore); + +public sealed record GfxPersistenceSnapshot( + IReadOnlyList Surfaces, + IReadOnlyList<(long Handle, GfxState.GfxObject Object)> Objects, + long RangeFirst, + long RangeCount, + GfxState.GfxObject RangeTransform); + +/// A renderable view of one visible gfx object — the host composites these in ascending-handle order +/// (= the engine's z-order) each frame. Built by ; the surface +/// resId/colorkey are resolved from the object's live source slot at snapshot time (see docs/engine-re.md, +/// "The full gfx render model"). +/// The packed-color channel is mode-dependent. Textured mode 0 ignores packed alpha and +/// multiplicatively modulates by ; surfaceless mode 0 uses . +/// A mode-0 color which has passed through op 0x202, and mode 1, use as opacity. +/// selects the latter compositor path. +public readonly record struct RenderObject(long Handle, long SurfaceResId, long ColorKey, + int SrcX, int SrcY, int W, int H, int DstX, int DstY, + TransformState Transform, RotationCycleState Rotation, + int Alpha, long Tint, int TintStrength, BlendKind Blend, + bool MultiplyTint, + SurfaceTransitionState? SurfaceTransition = null, + ColorTransitionState? ColorTransition = null, + Affine2D? RangeTransform = null, + bool TimeVarying = false, + ScaleCycleState ScaleCycle = default); + +/// The retained handle interval selected by an op-0x222 backbuffer publication. +public readonly record struct GfxHandleRange(long First, long Count) +{ + public static GfxHandleRange All => new(0, long.MaxValue); + + public bool Contains(long handle) + => Count > 0 && handle >= First && (ulong)(handle - First) < (ulong)Count; +} diff --git a/engine/Age.Engine/Model/GfxState.cs b/engine/Age.Engine/Model/GfxState.cs index 45774b9..c7a132d 100644 --- a/engine/Age.Engine/Model/GfxState.cs +++ b/engine/Age.Engine/Model/GfxState.cs @@ -3,103 +3,6 @@ using Age.Engine.Hosting; namespace Age.Engine.Model; -/// The sampled native one-shot channels carried to the compositor: op 0x21e scale, op 0x21f -/// axis-angle rotation, and op 0x220 translation. Z is retained through full 4x4 composition. -public readonly record struct TransformState(double ScaleX, double ScaleY, double ScaleZ, - double TranslateX, double TranslateY, double TranslateZ, - double AnchorX, double AnchorY, double AnchorZ, - double RotationAxisX = 0, double RotationAxisY = 0, - double RotationAxisZ = 0, double RotationAngleDegrees = 0); - -public readonly record struct RotationCycleState(bool Enabled, long PeriodMs, - double AxisX, double AxisY, double AxisZ, - double AngleDegrees = 0); - -public readonly record struct ScaleCycleState(bool Enabled, long PeriodMs, - double ScaleX, double ScaleY, double ScaleZ); - -[System.Flags] -public enum GfxPresentationReason -{ - None = 0, - RetainedMutation = 1, - ContinuousChannel = 2, - DiscreteSourceCell = 4, -} - -/// Sampled op-0x223 type-0 surface transition. Range A is already present in normal z-order; -/// the compositor draws range B over it with to form the native crossfade. -public readonly record struct SurfaceTransitionState(long CommandKey, int TargetSlot, - long RangeAStart, int RangeACount, long RangeBStart, int RangeBCount, - long DelayMs, long DurationMs, long StartMs, double Progress, bool Forced); - -public readonly record struct MovieMaskTransitionState( - MovieMaskTransitionRequest Request, bool Completed); - -/// One synchronized sample of op 0x202's native one-shot packed-color channel. -public readonly record struct ColorTransitionState(long Current, long Target, - long DelayMs, long DurationMs, long StartMs, double Progress, bool Active); - -/// One EngineCtx numeric-glyph style registered by opcode 0x13a. -public readonly record struct NumericGlyphStyle(int SurfaceSlot, int AtlasX, int AtlasY, - int DigitWidth, int DigitHeight) -{ - public bool Registered => SurfaceSlot != 0; -} - -public sealed record BlockingGfxObjectDiagnostic( - long Handle, int SourceSlot, long StartMs, long ControlFlags, - bool ColorEnabled, long ColorDelayMs, long ColorDurationMs, - bool ScaleEnabled, long ScaleDelayMs, long ScaleDurationMs, - bool RotationEnabled, long RotationDelayMs, long RotationDurationMs, - bool TranslationEnabled, long TranslationDelayMs, long TranslationDurationMs); - -public sealed record GfxDiagnosticSnapshot( - long NowMs, bool HasActiveTimedPresentation, int ObjectCount, int VisibleObjectCount, - int ActiveSurfaceTransitionCount, long AnimationServiceFlags, - long AnimClockDurationTicks, long AnimClockGeneration, - uint PreviousFrameTimeMilliseconds, uint CurrentFrameTimeMilliseconds, - long RangeTransformFirst, long RangeTransformCount, - BlockingGfxObjectDiagnostic? BlockingRangeTransform, - IReadOnlyList BlockingObjects); - -public readonly record struct GfxSurfacePersistenceState( - int Slot, long ResourceId, long ColorKey, bool Created, bool ReloadOnRestore); - -public sealed record GfxPersistenceSnapshot( - IReadOnlyList Surfaces, - IReadOnlyList<(long Handle, GfxState.GfxObject Object)> Objects, - long RangeFirst, - long RangeCount, - GfxState.GfxObject RangeTransform); - -/// A renderable view of one visible gfx object — the host composites these in ascending-handle order -/// (= the engine's z-order) each frame. Built by ; the surface -/// resId/colorkey are resolved from the object's live source slot at snapshot time (see docs/engine-re.md, -/// "The full gfx render model"). -/// The packed-color channel is mode-dependent. Textured mode 0 ignores packed alpha and -/// multiplicatively modulates by ; surfaceless mode 0 uses . -/// A mode-0 color which has passed through op 0x202, and mode 1, use as opacity. -/// selects the latter compositor path. -public readonly record struct RenderObject(long Handle, long SurfaceResId, long ColorKey, - int SrcX, int SrcY, int W, int H, int DstX, int DstY, - TransformState Transform, RotationCycleState Rotation, - int Alpha, long Tint, int TintStrength, BlendKind Blend, - bool MultiplyTint, - SurfaceTransitionState? SurfaceTransition = null, - ColorTransitionState? ColorTransition = null, - Affine2D? RangeTransform = null, - bool TimeVarying = false, - ScaleCycleState ScaleCycle = default); - -/// The retained handle interval selected by an op-0x222 backbuffer publication. -public readonly record struct GfxHandleRange(long First, long Count) -{ - public static GfxHandleRange All => new(0, long.MaxValue); - - public bool Contains(long handle) - => Count > 0 && handle >= First && (ulong)(handle - First) < (ulong)Count; -} /// Host-agnostic model of the AGE native gfx command-buffer (reversed in /// docs/engine-re.md, gfx op-contract table). One registry maps an object handle to a GfxObject — the