TextureBuffer.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. namespace OpenVIII
  9. {
  10. public class TextureBuffer : Texture_Base, ICloneable, ICollection, IStructuralComparable, IStructuralEquatable
  11. {
  12. #region Fields
  13. #endregion Fields
  14. #region Constructors
  15. public TextureBuffer(int width, int height, bool alert = true)
  16. {
  17. Height = height;
  18. Width = width;
  19. Colors = new Color[height * width];
  20. Alert = alert;
  21. }
  22. #endregion Constructors
  23. #region Properties
  24. public bool Alert { get; set; }
  25. public Color[] Colors { get; }
  26. public int Count => ((ICollection)Colors).Count;
  27. public override byte GetBytesPerPixel => 4;
  28. public override int GetClutCount => 0;
  29. public override int GetClutSize => 0;
  30. public override int GetColorsCountPerPalette => 0;
  31. public override int GetHeight => Height;
  32. public override int GetOrigX => 0;
  33. public override int GetOrigY => 0;
  34. public override int GetWidth => Width;
  35. public int Height { get; }
  36. public bool IsSynchronized => Colors.IsSynchronized;
  37. public int Length => Colors?.Length ?? 0;
  38. public object SyncRoot => Colors.SyncRoot;
  39. public int Width { get; }
  40. #endregion Properties
  41. #region Indexers
  42. public Color this[int i]
  43. {
  44. get => Colors[i]; set
  45. {
  46. if (Alert && Colors[i] != Color.TransparentBlack)
  47. throw new Exception("Color is set!");
  48. Colors[i] = value;
  49. }
  50. }
  51. public Color this[int x, int y]
  52. {
  53. get
  54. {
  55. var i = x + (y * Width);
  56. if (i < Count && i >= 0)
  57. return Colors[i];
  58. Memory.Log.WriteLine($"{nameof(TextureBuffer)} :: this[int x, int y] => get :: {nameof(IndexOutOfRangeException)} :: {new Point(x, y)} = {i}");
  59. return Color.TransparentBlack; // fail silent...
  60. }
  61. set
  62. {
  63. var i = x + (y * Width);
  64. if (i < Count && i >= 0)
  65. this[i] = value;
  66. else
  67. Memory.Log.WriteLine($"{nameof(TextureBuffer)} :: this[int x, int y] => set :: {nameof(IndexOutOfRangeException)} :: {new Point(x, y)} = {i} :: {nameof(value)} :: {value}");
  68. }
  69. }
  70. public Color[] this[Rectangle rectangle]
  71. {
  72. get => this[rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height];
  73. set => this[rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height] = value;
  74. }
  75. public Color[] this[int x, int y, int width, int height]
  76. {
  77. get
  78. {
  79. var pos = (x + y * Width);
  80. var r = new List<Color>(width * height);
  81. var row = 0;
  82. while (r.Count < width * height)
  83. {
  84. r.AddRange(Colors.Skip(pos + row * Width).Take(width));
  85. row++;
  86. }
  87. return r.ToArray();
  88. }
  89. set
  90. {
  91. for (var loopY = y; (loopY - y) < height; loopY++)
  92. for (var loopX = x; (loopX - x) < width; loopX++)
  93. {
  94. var pos = (loopX + loopY * Width);
  95. Colors[pos] = value[(loopX - x) + (loopY - y) * width];
  96. }
  97. }
  98. }
  99. #endregion Indexers
  100. #region Methods
  101. public static explicit operator Texture2D(TextureBuffer @in)
  102. {
  103. if (Memory.Graphics?.GraphicsDevice != null && @in.Width > 0 && @in.Height > 0)
  104. {
  105. var tex = new Texture2D(Memory.Graphics.GraphicsDevice, @in.Width, @in.Height);
  106. @in.SetData(tex);
  107. return tex;
  108. }
  109. return null;
  110. }
  111. public static explicit operator Texture2DWrapper(TextureBuffer @in) => new Texture2DWrapper(@in.GetTexture());
  112. public static explicit operator TextureBuffer(Texture2D @in)
  113. {
  114. var texture = new TextureBuffer(@in.Width, @in.Height);
  115. @in.GetData(texture.Colors);
  116. return texture;
  117. }
  118. public static explicit operator TextureBuffer(Texture2DWrapper @in)
  119. {
  120. var texture = new TextureBuffer(@in.GetWidth, @in.GetHeight);
  121. var tex = @in.GetTexture();
  122. tex.GetData(texture.Colors);
  123. return texture;
  124. }
  125. public static implicit operator Color[] (TextureBuffer @in) => @in.Colors;
  126. public object Clone() => Colors.Clone();
  127. public int CompareTo(object other, IComparer comparer) => ((IStructuralComparable)Colors).CompareTo(other, comparer);
  128. public void CopyTo(Array array, int index) => Colors.CopyTo(array, index);
  129. public bool Equals(object other, IEqualityComparer comparer) => ((IStructuralEquatable)Colors).Equals(other, comparer);
  130. public override void ForceSetClutColors(ushort newNumOfColors)
  131. {
  132. }
  133. public override void ForceSetClutCount(ushort newClut)
  134. {
  135. }
  136. public override Color[] GetClutColors(ushort clut) => null;
  137. public void GetData(Texture2D tex) => tex.GetData(Colors);
  138. public IEnumerator GetEnumerator() => Colors.GetEnumerator();
  139. public int GetHashCode(IEqualityComparer comparer) => ((IStructuralEquatable)Colors).GetHashCode(comparer);
  140. public override Texture2D GetTexture() => (Texture2D)this;
  141. public override Texture2D GetTexture(Color[] colors) => (Texture2D)this;
  142. public override Texture2D GetTexture(ushort clut) => (Texture2D)this;
  143. public override void Load(byte[] buffer, uint offset = 0) => throw new NotImplementedException();
  144. public override void Save(string path)
  145. {
  146. using (var tex = GetTexture())
  147. using (var fs = File.Create(path))
  148. tex.SaveAsPng(fs, tex.Width, tex.Height);
  149. }
  150. public override void SaveCLUT(string path)
  151. {
  152. }
  153. public void SetData(Texture2D tex) => tex.SetData(Colors);
  154. #endregion Methods
  155. }
  156. }