<commit_before>﻿using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Drawing;
using Xe.Drawing;

namespace OpenKh.Game
{
    using xnaf = Microsoft.Xna.Framework;

    public class MonoDrawing : IDrawing
    {
        private class CSurface : ISurface
        {
            public CSurface(Texture2D texture)
            {
                Texture = texture;
            }

            public Texture2D Texture { get; }
            public int Width => Texture.Width;
            public int Height => Texture.Height;
            public Size Size => new Size(Width, Height);

            public PixelFormat PixelFormat => throw new System.NotImplementedException();


            public void Dispose() => Texture.Dispose();

            public IMappedResource Map()
            {
                throw new System.NotImplementedException();
            }

            public void Save(string filename)
            {
                throw new System.NotImplementedException();
            }
        }

        public struct MyVertex : IVertexType
        {
            public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration
            (
                new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
                new VertexElement(12, VertexElementFormat.Vector4, VertexElementUsage.Color, 0),
                new VertexElement(28, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
            );

            public xnaf.Vector3 Position;
            public xnaf.Vector4 Color;
            public xnaf.Vector2 TextureCoordinate;

            VertexDeclaration IVertexType.VertexDeclaration => VertexDeclaration;

            public MyVertex(xnaf.Vector3 position, xnaf.Vector4 color, xnaf.Vector2 textureCoordinate)
            {
                Position = position;
                Color = color;
                TextureCoordinate = textureCoordinate;
            }
        }

        private const int MaxSpriteCountPerDraw = 8000; // This size should be enough to pack enough 2D graphics at once
        private readonly EffectParameter _parameterWorldViewProjection;
        private readonly EffectParameter _parameterTexture0;
        private readonly Effect _effect;

        private readonly VertexBuffer _vertexBuffer;
        private readonly IndexBuffer _indexBuffer;
        private readonly MyVertex[] _vertices;
        private Texture2D _texture;
        private int _currentSpriteIndex;

        public xnaf.Matrix WorldViewProjection
        {
            get => _parameterWorldViewProjection.GetValueMatrix();
            set => _parameterWorldViewProjection.SetValue(value);
        }
        public Texture2D Texture0
        {
            get => _parameterTexture0.GetValueTexture2D();
            set => _parameterTexture0.SetValue(value);
        }

        public MonoDrawing(GraphicsDevice graphicsDevice, ContentManager contentManager)
        {
            GraphicsDevice = graphicsDevice;
            GraphicsDevice.BlendState = BlendState.NonPremultiplied;

            _effect = contentManager.Load<Effect>("KingdomShader");
            _parameterTexture0 = _effect.Parameters["Texture0"];
            _parameterWorldViewProjection = _effect.Parameters["WorldViewProjection"];

            _vertexBuffer = new VertexBuffer(graphicsDevice, MyVertex.VertexDeclaration, MaxSpriteCountPerDraw * 4, BufferUsage.WriteOnly);
            _indexBuffer = CreateIndexBufferForSprites(graphicsDevice, MaxSpriteCountPerDraw);
            _vertices = new MyVertex[MaxSpriteCountPerDraw * 4];
            _currentSpriteIndex = 0;
        }

        public GraphicsDevice GraphicsDevice { get; }

        public ISurface Surface { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
        public Filter Filter { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }

        public void Clear(Color color)
        {
            GraphicsDevice.Clear(ToXnaColor(color));
        }

        public ISurface CreateSurface(int width, int height, PixelFormat pixelFormat, SurfaceType type = SurfaceType.Input, DataResource dataResource = null)
        {
            var texture = new Texture2D(GraphicsDevice, width, height);
            var data = new byte[dataResource.Data.Length];
            for (int i = 0; i < data.Length; i+=4)
            {
                data[i + 2] = dataResource.Data[i + 0];
                data[i + 1] = dataResource.Data[i + 1];
                data[i + 0] = dataResource.Data[i + 2];
                data[i + 3] = dataResource.Data[i + 3];
            }

            texture.SetData(data);

            return new CSurface(texture);
        }

        public ISurface CreateSurface(string filename, Color[] filterColors = null)
        {
            throw new System.NotImplementedException();
        }
        
        public void Dispose()
        {
            _indexBuffer?.Dispose();
            _effect?.Dispose();
        }

        public void DrawRectangle(RectangleF rect, Color color, float width = 1)
        {
            throw new System.NotImplementedException();
        }

        public void FillRectangle(RectangleF rect, Color color)
        {
            throw new System.NotImplementedException();
        }

        public void DrawSurface(ISurface surface, Rectangle src, RectangleF dst, Flip flip = Flip.None)
        {
            throw new System.NotImplementedException();
        }

        public void DrawSurface(ISurface surface, Rectangle src, RectangleF dst, float alpha, Flip flip = Flip.None)
        {
            throw new System.NotImplementedException();
        }

        public void DrawSurface(ISurface surface, Rectangle src, RectangleF dst, ColorF color0, ColorF color1, ColorF color2, ColorF color3)
        {
            var texture = (surface as CSurface)?.Texture;
            var tw = 1.0f / texture.Width;
            var th = 1.0f / texture.Height;

            var vertexIndex = PrepareVertices(texture);
            _vertices[vertexIndex + 0] = new MyVertex(new xnaf.Vector3(dst.Left, dst.Top, 0.0f), ToXnaColor(color0), new xnaf.Vector2(src.Left * tw, src.Top * th));
            _vertices[vertexIndex + 1] = new MyVertex(new xnaf.Vector3(dst.Right, dst.Top, 0.0f), ToXnaColor(color1), new xnaf.Vector2(src.Right * tw, src.Top * th));
            _vertices[vertexIndex + 2] = new MyVertex(new xnaf.Vector3(dst.Left, dst.Bottom, 0.0f), ToXnaColor(color2), new xnaf.Vector2(src.Left * tw, src.Bottom * th));
            _vertices[vertexIndex + 3] = new MyVertex(new xnaf.Vector3(dst.Right, dst.Bottom, 0.0f), ToXnaColor(color3), new xnaf.Vector2(src.Right * tw, src.Bottom * th));
            PushVertices();
        }

        public void Flush()
        {
            if (_currentSpriteIndex <= 0)
                return;

            _vertexBuffer.SetData(_vertices);
            foreach (var pass in _effect.CurrentTechnique.Passes)
            {
                Texture0 = _texture;
                WorldViewProjection = xnaf.Matrix.CreateOrthographicOffCenter(0, 512, 416, 0, -1000.0f, +1000.0f);
                pass.Apply();

                GraphicsDevice.RasterizerState = new RasterizerState()
                {
                    CullMode = CullMode.None,
                };

                GraphicsDevice.SetVertexBuffer(_vertexBuffer);
                GraphicsDevice.Indices = _indexBuffer;
                GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _currentSpriteIndex * 2);
            }

            _currentSpriteIndex = 0;
        }
        
        private int PrepareVertices(Texture2D texture)
        {<commit_msg>Fix a bug where the title screen background was drawn twice<commit_after>﻿using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Drawing;
using Xe.Drawing;

namespace OpenKh.Game
{
    using xnaf = Microsoft.Xna.Framework;

    public class MonoDrawing : IDrawing
    {
        private class CSurface : ISurface
        {
            public CSurface(Texture2D texture)
            {
                Texture = texture;
            }

            public Texture2D Texture { get; }
            public int Width => Texture.Width;
            public int Height => Texture.Height;
            public Size Size => new Size(Width, Height);

            public PixelFormat PixelFormat => throw new System.NotImplementedException();


            public void Dispose() => Texture.Dispose();

            public IMappedResource Map()
            {
                throw new System.NotImplementedException();
            }

            public void Save(string filename)
            {
                throw new System.NotImplementedException();
            }
        }

        public struct MyVertex : IVertexType
        {
            public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration
            (
                new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
                new VertexElement(12, VertexElementFormat.Vector4, VertexElementUsage.Color, 0),
                new VertexElement(28, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
            );

            public xnaf.Vector3 Position;
            public xnaf.Vector4 Color;
            public xnaf.Vector2 TextureCoordinate;

            VertexDeclaration IVertexType.VertexDeclaration => VertexDeclaration;

            public MyVertex(xnaf.Vector3 position, xnaf.Vector4 color, xnaf.Vector2 textureCoordinate)
            {
                Position = position;
                Color = color;
                TextureCoordinate = textureCoordinate;
            }
        }

        private const int MaxSpriteCountPerDraw = 8000; // This size should be enough to pack enough 2D graphics at once
        private readonly EffectParameter _parameterWorldViewProjection;
        private readonly EffectParameter _parameterTexture0;
        private readonly Effect _effect;
        private readonly BlendState _blendState;
        private readonly SamplerState _samplerState;
        private readonly RasterizerState _rasterizerState;

        private readonly VertexBuffer _vertexBuffer;
        private readonly IndexBuffer _indexBuffer;
        private readonly MyVertex[] _vertices;
        private Texture2D _texture;
        private int _currentSpriteIndex;

        public xnaf.Matrix WorldViewProjection
        {
            get => _parameterWorldViewProjection.GetValueMatrix();
            set => _parameterWorldViewProjection.SetValue(value);
        }
        public Texture2D Texture0
        {
            get => _parameterTexture0.GetValueTexture2D();
            set => _parameterTexture0.SetValue(value);
        }

        public MonoDrawing(GraphicsDevice graphicsDevice, ContentManager contentManager)
        {
            GraphicsDevice = graphicsDevice;
            _blendState = BlendState.NonPremultiplied;
            _samplerState = new SamplerState
            {
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
                Filter = TextureFilter.Linear
            };
            _rasterizerState = new RasterizerState()
            {
                CullMode = CullMode.None,
                ScissorTestEnable = false,
                DepthClipEnable = false,
            };

            _effect = contentManager.Load<Effect>("KingdomShader");
            _parameterTexture0 = _effect.Parameters["Texture0"];
            _parameterWorldViewProjection = _effect.Parameters["WorldViewProjection"];

            _vertexBuffer = new VertexBuffer(graphicsDevice, MyVertex.VertexDeclaration, MaxSpriteCountPerDraw * 4, BufferUsage.WriteOnly);
            _indexBuffer = CreateIndexBufferForSprites(graphicsDevice, MaxSpriteCountPerDraw);
            _vertices = new MyVertex[MaxSpriteCountPerDraw * 4];
            _currentSpriteIndex = 0;
        }

        public GraphicsDevice GraphicsDevice { get; }

        public ISurface Surface { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
        public Filter Filter { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }

        public void Clear(Color color)
        {
            GraphicsDevice.Clear(ToXnaColor(color));
        }

        public ISurface CreateSurface(int width, int height, PixelFormat pixelFormat, SurfaceType type = SurfaceType.Input, DataResource dataResource = null)
        {
            var texture = new Texture2D(GraphicsDevice, width, height);
            var data = new byte[dataResource.Data.Length];
            for (int i = 0; i < data.Length; i+=4)
            {
                data[i + 2] = dataResource.Data[i + 0];
                data[i + 1] = dataResource.Data[i + 1];
                data[i + 0] = dataResource.Data[i + 2];
                data[i + 3] = dataResource.Data[i + 3];
            }

            texture.SetData(data);

            return new CSurface(texture);
        }

        public ISurface CreateSurface(string filename, Color[] filterColors = null)
        {
            throw new System.NotImplementedException();
        }
        
        public void Dispose()
        {
            _indexBuffer?.Dispose();
            _effect?.Dispose();
        }

        public void DrawRectangle(RectangleF rect, Color color, float width = 1)
        {
            throw new System.NotImplementedException();
        }

        public void FillRectangle(RectangleF rect, Color color)
        {
            throw new System.NotImplementedException();
        }

        public void DrawSurface(ISurface surface, Rectangle src, RectangleF dst, Flip flip = Flip.None)
        {
            throw new System.NotImplementedException();
        }

        public void DrawSurface(ISurface surface, Rectangle src, RectangleF dst, float alpha, Flip flip = Flip.None)
        {
            throw new System.NotImplementedException();
        }

        public void DrawSurface(ISurface surface, Rectangle src, RectangleF dst, ColorF color0, ColorF color1, ColorF color2, ColorF color3)
        {
            var texture = (surface as CSurface)?.Texture;
            var tw = 1.0f / texture.Width;
            var th = 1.0f / texture.Height;

            var vertexIndex = PrepareVertices(texture);
            _vertices[vertexIndex + 0] = new MyVertex(new xnaf.Vector3(dst.Left, dst.Top, 0.0f), ToXnaColor(color0), new xnaf.Vector2(src.Left * tw, src.Top * th));
            _vertices[vertexIndex + 1] = new MyVertex(new xnaf.Vector3(dst.Right, dst.Top, 0.0f), ToXnaColor(color1), new xnaf.Vector2(src.Right * tw, src.Top * th));
            _vertices[vertexIndex + 2] = new MyVertex(new xnaf.Vector3(dst.Left, dst.Bottom, 0.0f), ToXnaColor(color2), new xnaf.Vector2(src.Left * tw, src.Bottom * th));
            _vertices[vertexIndex + 3] = new MyVertex(new xnaf.Vector3(dst.Right, dst.Bottom, 0.0f), ToXnaColor(color3), new xnaf.Vector2(src.Right * tw, src.Bottom * th));
            PushVertices();
        }

        public void Flush()
        {
            if (_currentSpriteIndex <= 0)
                return;
            
            GraphicsDevice.SamplerStates[0] = _samplerState;
            GraphicsDevice.RasterizerState = _rasterizerState;
            GraphicsDevice.BlendState = _blendState;
            GraphicsDevice.SetVertexBuffer(_vertexBuffer);
            GraphicsDevice.Indices = _indexBuffer;

            _vertexBuffer.SetData(_vertices);
            foreach (var pass in _effect.CurrentTechnique.Passes)
            {
                Texture0 = _texture;
                WorldViewProjection = xnaf.Matrix.CreateOrthographicOffCenter(0, 512, 416, 0, -1000.0f, +1000.0f);
                pass.Apply();

                GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _currentSpriteIndex * 2);
            }

            _currentSpriteIndex = 0;
        }
        
        private int PrepareVertices(Texture2D texture)
        {
{'fraction_non_alphanumeric': 0.08012525326947872, 'fraction_numerical': 0.01295511757843679, 'mean_word_length': 2.122100824228484, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2612977', 'n_tokens_mistral': 4429, 'n_tokens_neox': 4166, 'n_words': 1013}