Split GfxState public contracts
This commit is contained in:
@@ -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)
|
│ └── 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)
|
├── 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
|
│ ├── Age.Engine/Sys4/ runtime game-root selection, catalog parser, loose-first bounded
|
||||||
│ ALF asset store, script provider, AGF/LZSS and Windows CUR decoders,
|
│ ALF asset store, script provider, AGF/LZSS and Windows CUR decoders,
|
||||||
│ and resource facade
|
│ and resource facade
|
||||||
|
|||||||
@@ -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
|
scene reset, and frame-pulse consumers retain direct access through the sealed partial class. The planned
|
||||||
host decomposition is complete; runtime validation remains green.
|
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
|
**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
|
deterministic, and the corresponding engine, Python, Godot, and corpus validations remain green after
|
||||||
each domain move.
|
each domain move.
|
||||||
@@ -967,7 +972,7 @@ layer's rendering diverges from ADV; save layout.
|
|||||||
## 8. Immediate next step
|
## 8. Immediate next step
|
||||||
Continue step 2 of the **codebase consolidation** maintenance slice: behavior-neutral physical splits backed
|
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
|
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
|
isolated and the `GfxState` public contract layer separated, move `GfxState` surface ownership next, preserving
|
||||||
types, commands, and generated output.
|
public types, commands, and generated output.
|
||||||
Concrete playthrough blockers may still preempt this bounded maintenance work; the consolidation effort does
|
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.
|
not replace Phase B gameplay validation or the open cross-platform gates.
|
||||||
|
|||||||
101
engine/Age.Engine/Model/GfxState.Contracts.cs
Normal file
101
engine/Age.Engine/Model/GfxState.Contracts.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
using Age.Engine.Hosting;
|
||||||
|
|
||||||
|
namespace Age.Engine.Model;
|
||||||
|
|
||||||
|
/// <summary>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.</summary>
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Sampled op-0x223 type-0 surface transition. Range A is already present in normal z-order;
|
||||||
|
/// the compositor draws range B over it with <paramref name="Progress"/> to form the native crossfade.</summary>
|
||||||
|
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);
|
||||||
|
|
||||||
|
/// <summary>One synchronized sample of op 0x202's native one-shot packed-color channel.</summary>
|
||||||
|
public readonly record struct ColorTransitionState(long Current, long Target,
|
||||||
|
long DelayMs, long DurationMs, long StartMs, double Progress, bool Active);
|
||||||
|
|
||||||
|
/// <summary>One EngineCtx numeric-glyph style registered by opcode 0x13a.</summary>
|
||||||
|
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<BlockingGfxObjectDiagnostic> BlockingObjects);
|
||||||
|
|
||||||
|
public readonly record struct GfxSurfacePersistenceState(
|
||||||
|
int Slot, long ResourceId, long ColorKey, bool Created, bool ReloadOnRestore);
|
||||||
|
|
||||||
|
public sealed record GfxPersistenceSnapshot(
|
||||||
|
IReadOnlyList<GfxSurfacePersistenceState> Surfaces,
|
||||||
|
IReadOnlyList<(long Handle, GfxState.GfxObject Object)> Objects,
|
||||||
|
long RangeFirst,
|
||||||
|
long RangeCount,
|
||||||
|
GfxState.GfxObject RangeTransform);
|
||||||
|
|
||||||
|
/// <summary>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 <see cref="GfxState.SnapshotVisibleObjects"/>; 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").</summary>
|
||||||
|
/// <summary>The packed-color channel is mode-dependent. Textured mode 0 ignores packed alpha and
|
||||||
|
/// multiplicatively modulates by <paramref name="Tint"/>; surfaceless mode 0 uses <paramref name="TintStrength"/>.
|
||||||
|
/// A mode-0 color which has passed through op 0x202, and mode 1, use <paramref name="Alpha"/> as opacity.
|
||||||
|
/// <paramref name="MultiplyTint"/> selects the latter compositor path.</summary>
|
||||||
|
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);
|
||||||
|
|
||||||
|
/// <summary>The retained handle interval selected by an op-0x222 backbuffer publication.</summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -3,103 +3,6 @@ using Age.Engine.Hosting;
|
|||||||
|
|
||||||
namespace Age.Engine.Model;
|
namespace Age.Engine.Model;
|
||||||
|
|
||||||
/// <summary>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.</summary>
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Sampled op-0x223 type-0 surface transition. Range A is already present in normal z-order;
|
|
||||||
/// the compositor draws range B over it with <paramref name="Progress"/> to form the native crossfade.</summary>
|
|
||||||
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);
|
|
||||||
|
|
||||||
/// <summary>One synchronized sample of op 0x202's native one-shot packed-color channel.</summary>
|
|
||||||
public readonly record struct ColorTransitionState(long Current, long Target,
|
|
||||||
long DelayMs, long DurationMs, long StartMs, double Progress, bool Active);
|
|
||||||
|
|
||||||
/// <summary>One EngineCtx numeric-glyph style registered by opcode 0x13a.</summary>
|
|
||||||
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<BlockingGfxObjectDiagnostic> BlockingObjects);
|
|
||||||
|
|
||||||
public readonly record struct GfxSurfacePersistenceState(
|
|
||||||
int Slot, long ResourceId, long ColorKey, bool Created, bool ReloadOnRestore);
|
|
||||||
|
|
||||||
public sealed record GfxPersistenceSnapshot(
|
|
||||||
IReadOnlyList<GfxSurfacePersistenceState> Surfaces,
|
|
||||||
IReadOnlyList<(long Handle, GfxState.GfxObject Object)> Objects,
|
|
||||||
long RangeFirst,
|
|
||||||
long RangeCount,
|
|
||||||
GfxState.GfxObject RangeTransform);
|
|
||||||
|
|
||||||
/// <summary>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 <see cref="GfxState.SnapshotVisibleObjects"/>; 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").</summary>
|
|
||||||
/// <summary>The packed-color channel is mode-dependent. Textured mode 0 ignores packed alpha and
|
|
||||||
/// multiplicatively modulates by <paramref name="Tint"/>; surfaceless mode 0 uses <paramref name="TintStrength"/>.
|
|
||||||
/// A mode-0 color which has passed through op 0x202, and mode 1, use <paramref name="Alpha"/> as opacity.
|
|
||||||
/// <paramref name="MultiplyTint"/> selects the latter compositor path.</summary>
|
|
||||||
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);
|
|
||||||
|
|
||||||
/// <summary>The retained handle interval selected by an op-0x222 backbuffer publication.</summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Host-agnostic model of the AGE native gfx command-buffer (reversed in
|
/// <summary>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
|
/// docs/engine-re.md, gfx op-contract table). One registry maps an object handle to a GfxObject — the
|
||||||
|
|||||||
Reference in New Issue
Block a user