Beispiel #1
0
    private static bool ForwardDraw(
        XSpriteBatch @this,
        XTexture2D?texture,
        XRectangle destinationRectangle,
        XColor color,
        XRectangle?sourceRectangle = null,
        float rotation             = 0f,
        XVector2?origin            = null,
        SpriteEffects effects      = SpriteEffects.None,
        float layerDepth           = 0f
        )
    {
        if (!Config.IsEnabled)
        {
            return(true);
        }

        @this.Draw(
            texture: texture,
            destinationRectangle: destinationRectangle,
            sourceRectangle: sourceRectangle,
            color: color,
            rotation: rotation,
            origin: origin ?? XVector2.Zero,
            effects: effects,
            layerDepth: layerDepth
            );

        return(false);
    }
Beispiel #2
0
 public static bool OnDrawString(
     XSpriteBatch __instance,
     SpriteFont spriteFont,
     StringBuilder text,
     XVector2 position,
     XColor color,
     float rotation,
     XVector2 origin,
     XVector2 scale,
     SpriteEffects effects,
     float layerDepth
     )
 {
     return(Core.OnDrawStringImpl.DrawString(
                __instance,
                spriteFont,
                text,
                position,
                color,
                rotation,
                origin,
                scale,
                effects,
                layerDepth
                ));
 }
Beispiel #3
0
    public static bool OnDrawLast(
        XSpriteBatch __instance,
        ref XTexture2D?texture,
        ref XRectangle destinationRectangle,
        ref XRectangle?sourceRectangle,
        ref XColor color,
        float rotation,
        ref XVector2 origin,
        ref SpriteEffects effects,
        ref float layerDepth,
        ref ManagedTexture2D?__state
        )
    {
        if (!Config.IsEnabled)
        {
            return(true);
        }

        return(__instance.OnDraw(
                   texture: ref texture,
                   destination: ref destinationRectangle,
                   source: ref sourceRectangle,
                   color: ref color,
                   rotation: rotation,
                   origin: ref origin,
                   effects: ref effects,
                   layerDepth: ref layerDepth,
                   __state: ref __state
                   ));
    }
Beispiel #4
0
 public static bool OnDraw(XSpriteBatch __instance, XTexture2D?texture, XVector2 position, XColor color)
 {
     return(ForwardDraw(
                @this: __instance,
                texture: texture,
                position: position,
                color: color
                ));
 }
Beispiel #5
0
 public static bool OnDraw(XSpriteBatch __instance, XTexture2D?texture, XRectangle destinationRectangle, XColor color)
 {
     return(ForwardDraw(
                @this: __instance,
                texture: texture,
                destinationRectangle: destinationRectangle,
                color: color
                ));
 }
Beispiel #6
0
 public static bool OnDraw(XSpriteBatch __instance, XTexture2D?texture, XVector2 position, XRectangle?sourceRectangle, XColor color, float rotation, XVector2 origin, float scale, SpriteEffects effects, float layerDepth)
 {
     return(ForwardDraw(
                @this: __instance,
                texture: texture,
                position: position,
                sourceRectangle: sourceRectangle,
                color: color,
                rotation: rotation,
                origin: origin,
                scale: new XVector2(scale),
                effects: effects,
                layerDepth: layerDepth
                ));
 }
Beispiel #7
0
 public static bool OnDrawString(XSpriteBatch __instance, SpriteFont spriteFont, StringBuilder text, XVector2 position, XColor color)
 {
     __instance.DrawString(
         spriteFont: spriteFont,
         text: text,
         position: position,
         color: color,
         rotation: 0.0f,
         origin: XVector2.Zero,
         scale: XVector2.One,
         effects: SpriteEffects.None,
         layerDepth: 0.0f
         );
     return(false);
 }
Beispiel #8
0
    public static bool OnDraw(XSpriteBatch __instance, ref XTexture2D?texture, ref XVector2 position, ref XRectangle?sourceRectangle, ref XColor color, float rotation, ref XVector2 origin, ref XVector2 scale, SpriteEffects effects, float layerDepth)
    {
        if (!Config.IsEnabled)
        {
            return(true);
        }

        return(__instance.OnDraw(
                   texture: ref texture,
                   position: ref position,
                   source: ref sourceRectangle,
                   color: ref color,
                   rotation: rotation,
                   origin: ref origin,
                   scale: ref scale,
                   effects: effects,
                   layerDepth: ref layerDepth
                   ));
    }
Beispiel #9
0
    public static void OnBegin(XSpriteBatch __instance, ref SpriteSortMode sortMode, BlendState?blendState, SamplerState?samplerState, DepthStencilState?depthStencilState, RasterizerState?rasterizerState, Effect?effect, Matrix?transformMatrix)
    {
        if (!Config.IsEnabled)
        {
            return;
        }

        /*
         * if (sortMode is (SpriteSortMode.Deferred or SpriteSortMode.Immediate)) {
         *      sortMode = SpriteSortMode.Texture;
         * }
         */

        DrawState.OnBegin(
            __instance,
            sortMode,
            blendState ?? BlendState.AlphaBlend,
            samplerState ?? SamplerState.PointClamp,
            depthStencilState ?? DepthStencilState.None,
            rasterizerState ?? RasterizerState.CullCounterClockwise,
            effect,
            transformMatrix ?? Matrix.Identity
            );
    }
Beispiel #10
0
    internal static bool OnDraw(
        this XSpriteBatch @this,
        ref XTexture2D?texture,
        ref XVector2 position,
        ref XRectangle?source,
        ref XColor color,
        float rotation,
        ref XVector2 origin,
        ref XVector2 scale,
        SpriteEffects effects,
        ref float layerDepth
        )
    {
        if (texture is null)
        {
            return(false);
        }

        GetDrawParameters(
            texture: texture,
            source: source,
            bounds: out var sourceRectangle,
            scaleFactor: out var scaleFactor
            );

        var originalSourceRect = sourceRectangle;

        ManagedSpriteInstance?spriteInstance;
        ManagedTexture2D?     resampledTexture;

        if (texture is ManagedTexture2D texture2D)
        {
            resampledTexture = texture2D;
            spriteInstance   = resampledTexture.SpriteInstance;
            sourceRectangle  = resampledTexture.Dimensions;
        }
        else if (texture.FetchScaledTexture(
                     expectedScale: EstimateScale(scale, scaleFactor),
                     source: ref sourceRectangle,
                     spriteInstance: out spriteInstance,
                     create: true
                     ))
        {
            spriteInstance.UpdateReferenceFrame();
            resampledTexture = spriteInstance.Texture !;
        }
        else
        {
            resampledTexture = null;
        }

        if (spriteInstance is null || resampledTexture is null)
        {
            return(Continue);
        }

        if (originalSourceRect.X < 0)
        {
            position.X -= originalSourceRect.X * scale.X;
        }
        if (originalSourceRect.Y < 0)
        {
            position.Y -= originalSourceRect.Y * scale.Y;
        }

        var adjustedScale    = (Vector2F)scale / spriteInstance.Scale;
        var adjustedPosition = position;
        var adjustedOrigin   = (Vector2F)origin;

        if (spriteInstance.TexType == TextureType.SlicedImage)
        {
            sourceRectangle = source ?? resampledTexture.Bounds;
            if (source is not null)
            {
                sourceRectangle = new Bounds(
                    (Vector2I)source.Value.Location - spriteInstance.OriginalSourceRectangle.Offset,
                    source.Value.Size
                    );
                sourceRectangle.Offset = (sourceRectangle.OffsetF * spriteInstance.Scale).NearestInt();
                sourceRectangle.Extent = (sourceRectangle.ExtentF * spriteInstance.Scale).NearestInt();
            }
        }

        if (!spriteInstance.Padding.IsZero)
        {
            var paddingX = spriteInstance.Padding.X;
            var paddingY = spriteInstance.Padding.Y;

            if (effects.HasFlag(SpriteEffects.FlipHorizontally))
            {
                paddingX = (paddingX.Y, paddingX.X);
            }

            if (effects.HasFlag(SpriteEffects.FlipVertically))
            {
                paddingY = (paddingY.Y, paddingY.X);
            }

            var padding = new PaddingQuad(paddingX, paddingY);

            var textureSize = new Vector2F(sourceRectangle.Extent);
            var innerSize   = (Vector2F)spriteInstance.UnpaddedSize;

            // This is the scale factor to bring the inner size to the draw size.
            var innerRatio = textureSize / innerSize;             // spriteInstance.InnerRatio;

            // Scale the... scale by the scale factor.
            adjustedScale *= innerRatio;

            adjustedOrigin *= spriteInstance.Scale;
            adjustedOrigin /= innerRatio;
            adjustedOrigin += (Vector2F)padding.Offset;
        }
        else
        {
            adjustedOrigin *= spriteInstance.Scale;
        }

        if (source.HasValue)
        {
            sourceRectangle.Invert.X = source.Value.Width < 0;
            sourceRectangle.Invert.Y = source.Value.Height < 0;
        }

        if (Debug.Mode.RegisterDrawForSelect(
                instance: spriteInstance,
                texture: texture,
                originalPosition: position,
                originalSource: source,
                position: adjustedPosition,
                source: sourceRectangle,
                color: color,
                rotation: rotation,
                originalOrigin: origin,
                origin: adjustedOrigin,
                scale: adjustedScale,
                effects: effects,
                layerDepth: layerDepth
                ))
        {
            color = XColor.Red;
        }

        texture  = resampledTexture;
        source   = sourceRectangle;
        origin   = adjustedOrigin;
        scale    = adjustedScale;
        position = adjustedPosition;
        return(Continue);
    }
Beispiel #11
0
    // Takes the arguments, and checks to see if the texture is padded. If it is, it is forwarded to the correct draw call, avoiding
    // intervening mods altering the arguments first.
    internal static bool OnDrawFirst(
        this XSpriteBatch @this,
        ref XTexture2D?texture,
        ref XRectangle destination,
        ref XRectangle?source,
        XColor color,
        float rotation,
        ref XVector2 origin,
        ref SpriteEffects effects,
        float layerDepth,
        ref ManagedTexture2D?__state
        )
    {
        if (texture is null)
        {
            return(false);
        }

        using var watchdogScoped = WatchDog.WatchDog.ScopedWorkingState;

        /*
         * if (destination.Width < 0 || destination.Height < 0) {
         *      Debug.Trace("destination invert");
         * }
         * if (source is XRectangle sourceRect && (sourceRect.Width < 0 || sourceRect.Height < 0)) {
         *      Debug.Trace("source invert");
         * }
         */

        GetDrawParameters(
            texture: texture,
            source: source,
            bounds: out var sourceRectangle,
            scaleFactor: out var scaleFactor
            );

        var referenceRectangle = sourceRectangle;

        Bounds destinationBounds = destination;

        var expectedScale2D = destinationBounds.ExtentF / sourceRectangle.ExtentF;
        var expectedScale   = EstimateScale(expectedScale2D, scaleFactor);

        if (!texture.FetchScaledTexture(
                expectedScale: expectedScale,
                source: ref sourceRectangle,
                spriteInstance: out var spriteInstance,
                create: true
                ))
        {
            return(Continue);
        }
        spriteInstance.UpdateReferenceFrame();

        if (referenceRectangle.X < 0)
        {
            destinationBounds.Left -= referenceRectangle.X;
        }
        if (referenceRectangle.Y < 0)
        {
            destinationBounds.Top -= referenceRectangle.Y;
        }

        var resampledTexture = spriteInstance.Texture !;

        if (!spriteInstance.Padding.IsZero)
        {
            // Convert the draw into the other draw style. This has to be done because the padding potentially has
            // subpixel accuracy when scaled to the destination rectangle.

            var originalSize    = referenceRectangle.ExtentF;
            var destinationSize = destinationBounds.ExtentF;
            var newScale        = destinationSize / originalSize;
            var newPosition     = destinationBounds.OffsetF;

            if ((destinationBounds.Invert.X || destinationBounds.Invert.Y) && DrawState.CurrentRasterizerState.CullMode == CullMode.CullCounterClockwiseFace)
            {
                // Winding order is invalid
                return(Stop);
            }
            if (destinationBounds.Invert.X)
            {
                effects ^= SpriteEffects.FlipHorizontally;
            }
            if (destinationBounds.Invert.Y)
            {
                effects ^= SpriteEffects.FlipVertically;
            }

            // TODO handle culling here for inverted sprites?

            @this.Draw(
                texture: resampledTexture,
                position: newPosition,
                sourceRectangle: sourceRectangle,
                color: color,
                rotation: rotation,
                origin: origin,
                scale: newScale,
                effects: effects,
                layerDepth: layerDepth
                );
            return(Stop);
        }
        __state = resampledTexture;
        return(Continue);
    }
Beispiel #12
0
    internal static bool OnDraw(
        this XSpriteBatch @this,
        ref XTexture2D?texture,
        ref XRectangle destination,
        ref XRectangle?source,
        ref XColor color,
        float rotation,
        ref XVector2 origin,
        ref SpriteEffects effects,
        ref float layerDepth,
        ref ManagedTexture2D?__state
        )
    {
        if (texture is null)
        {
            return(false);
        }

        Bounds sourceRectangle;
        ManagedSpriteInstance?spriteInstance;
        ManagedTexture2D      resampledTexture;

        Bounds destinationBounds = destination;

        var referenceSource = source.GetValueOrDefault();

        if (__state is null)
        {
            GetDrawParameters(
                texture: texture,
                source: source,
                bounds: out sourceRectangle,
                scaleFactor: out var scaleFactor
                );

            var expectedScale2D = new Vector2F(destinationBounds.Extent) / new Vector2F(sourceRectangle.Extent);
            var expectedScale   = EstimateScale(expectedScale2D, scaleFactor);

            if (!texture.FetchScaledTexture(
                    expectedScale: expectedScale,
                    source: ref sourceRectangle,
                    spriteInstance: out spriteInstance
                    ))
            {
                return(Continue);
            }

            if (spriteInstance.TexType == TextureType.SlicedImage)
            {
                sourceRectangle = source ?? spriteInstance.Texture !.Bounds;
            }

            spriteInstance.UpdateReferenceFrame();

            resampledTexture = spriteInstance.Texture !;
        }
        else
        {
            resampledTexture = __state;
            spriteInstance   = resampledTexture.SpriteInstance;
            sourceRectangle  = resampledTexture.Dimensions;
            if (spriteInstance.TexType == TextureType.SlicedImage)
            {
                sourceRectangle = source ?? resampledTexture.Bounds;
                if (source.HasValue)
                {
                    sourceRectangle = new Bounds(
                        (Vector2I)source.Value.Location - spriteInstance.OriginalSourceRectangle.Offset,
                        source.Value.Size
                        );
                    sourceRectangle.Offset = (sourceRectangle.OffsetF * spriteInstance.Scale).NearestInt();
                    sourceRectangle.Extent = (sourceRectangle.ExtentF * spriteInstance.Scale).NearestInt();
                }
            }
        }

        if (referenceSource.X < 0)
        {
            destination.X -= referenceSource.X;
        }
        if (referenceSource.Y < 0)
        {
            destination.Y -= referenceSource.Y;
        }

        var scaledOrigin = (Vector2F)origin * spriteInstance.Scale;

        if (source.HasValue)
        {
            sourceRectangle.Invert.X = source.Value.Width < 0;
            sourceRectangle.Invert.Y = source.Value.Height < 0;
        }

        if (Debug.Mode.RegisterDrawForSelect(
                instance: spriteInstance,
                texture: texture,
                originalDestination: destinationBounds,
                destination: destination,
                source: sourceRectangle,
                color: color,
                rotation: rotation,
                originalOrigin: origin,
                origin: scaledOrigin,
                effects: effects,
                layerDepth: layerDepth
                ))
        {
            color = XColor.Red;
        }

        source  = sourceRectangle;
        origin  = scaledOrigin;
        texture = resampledTexture;

        return(Continue);
    }