Tiles.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using Microsoft.Xna.Framework;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Linq;
  8. namespace OpenVIII.Fields
  9. {
  10. public partial class Background
  11. {
  12. #region Classes
  13. public class Tiles : IReadOnlyList<Tile>
  14. {
  15. struct pupu_key
  16. {
  17. private uint m_pupu_common;
  18. public uint pupu_common { get => m_pupu_common; set => m_pupu_common = value & 0xFFFFFFC0; }
  19. private int x { get; set; }
  20. private int y { get; set; }
  21. public pupu_key(Tile tile)
  22. {
  23. m_pupu_common = 0;
  24. x = tile.X / Tile.Size;
  25. y = tile.Y / Tile.Size;
  26. pupu_common = tile.PupuID;
  27. }
  28. }
  29. #region Fields
  30. /// <summary>
  31. /// Use before deswizzling.
  32. /// </summary>
  33. public void UniquePupuIDs()
  34. {
  35. var offsets = new Dictionary<pupu_key, byte>();
  36. foreach(var item in _tiles.Select(t => new { key = new pupu_key(t), tile = t }))
  37. {
  38. if(offsets.ContainsKey(item.key))
  39. {
  40. ++offsets[item.key];
  41. }
  42. else
  43. {
  44. offsets.Add(item.key, default);
  45. }
  46. item.tile.PupuID = item.key.pupu_common + offsets[item.key];
  47. }
  48. //var duplicateIDs = GetOverLapTiles().ToList();
  49. //foreach (var i in duplicateIDs)
  50. //{
  51. // i[1].PupuID = i[0].PupuID + 1;
  52. //}
  53. //Debug.Assert(!GetOverLapTiles().Any());
  54. }
  55. //private IEnumerable<Tile[]> GetOverLapTiles() => (from t1 in _tiles.Take(_tiles.Count - 1)
  56. // from t2 in _tiles.Skip(1)
  57. // where t1.PupuID == t2.PupuID && t1.TileID < t2.TileID && t1.Intersect(t2)
  58. // select new[] { t1, t2 }).OrderBy(x=>x[0].TileID);
  59. private readonly IReadOnlyList<Tile> _tiles;
  60. #endregion Fields
  61. #region Constructors
  62. public Tiles() => _tiles = new List<Tile>();
  63. public Tiles(IReadOnlyList<Tile> tiles) => _tiles = tiles;
  64. #endregion Constructors
  65. #region Properties
  66. public Point BottomRight => new Point(_tiles.Max(tile => tile.X) + Tile.Size, _tiles.Max(tile => tile.Y) + Tile.Size);
  67. public int Height => Math.Abs(TopLeft.Y) + BottomRight.Y;// + (int)Origin.Y;
  68. public Point TopLeft => new Point(_tiles.Min(tile => tile.X), _tiles.Min(tile => tile.Y));
  69. public int Width => Math.Abs(TopLeft.X) + BottomRight.X;//+ (int)Origin.X;
  70. public Point Size => new Point(Width, Height);
  71. public Vector2 Origin => BottomRight.ToVector2() + TopLeft.ToVector2();
  72. #endregion Properties
  73. #region Indexers
  74. #endregion Indexers
  75. #region Methods
  76. public static Tiles Load(byte[] mapB, byte textureType)
  77. {
  78. var tiles = new List<Tile>();
  79. //128x256
  80. using (var br = new BinaryReader(new MemoryStream(mapB)))
  81. while (br.BaseStream.Position + 16 < br.BaseStream.Length)
  82. {
  83. var tile = Tile.Load(br, tiles.Count, textureType);
  84. if (tile != null)
  85. tiles.Add(tile);
  86. }
  87. return new Tiles(tiles.AsReadOnly());
  88. }
  89. #endregion Methods
  90. public IEnumerator<Tile> GetEnumerator()
  91. {
  92. return _tiles.GetEnumerator();
  93. }
  94. IEnumerator IEnumerable.GetEnumerator()
  95. {
  96. return ((IEnumerable) _tiles).GetEnumerator();
  97. }
  98. public int Count => _tiles.Count;
  99. public Tile this[int index] => _tiles[index];
  100. }
  101. #endregion Classes
  102. }
  103. }