source: OniSplit/Akira/RoomGrid.cs@ 1171

Last change on this file since 1171 was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 4.0 KB
RevLine 
[1114]1using System;
2using System.Collections.Generic;
3using System.IO;
4using Oni.Imaging;
5
6namespace Oni.Akira
7{
8 internal class RoomGrid
9 {
10 #region Private data
11 private static readonly Color[] gridColors = new[]
12 {
13 new Color(255, 255, 255),
14 new Color(0x90, 0xee, 0x90),
15 new Color(0xad, 0xd8, 0xe6),
16 new Color(0x87, 0xce, 0xfa),
17 new Color(0, 255, 0),
18 new Color(0, 0, 255),
19 new Color(0, 0, 128),
20 new Color(0, 128, 0),
21 new Color(255, 165, 0),
22 new Color(255, 0, 0)
23 };
24
25 private const int origin = -2;
26 private const float tileSize = 4.0f;
27 private readonly int xOrigin = -2;
28 private readonly int xTiles;
29 private readonly int zOrigin = -2;
30 private readonly int zTiles;
31 private readonly byte[] data;
32 private readonly byte[] debugData;
33 #endregion
34
35 public RoomGrid(int xTiles, int zTiles, byte[] data, byte[] debugData)
36 {
37 this.xTiles = xTiles;
38 this.zTiles = zTiles;
39 this.data = data;
40 this.debugData = debugData;
41 }
42
43 public static RoomGrid FromImage(Surface image)
44 {
45 var data = new byte[image.Width * image.Height];
46
47 for (int z = 0; z < image.Height; z++)
48 {
49 for (int x = 0; x < image.Width; x++)
50 {
51 int type = Array.IndexOf(gridColors, image[x, z]);
52
53 if (type == -1)
54 throw new InvalidDataException(string.Format("Color '{0}' does not match a valid tile type", image[x, z]));
55
56 data[z * image.Width + x] = (byte)type;
57 }
58 }
59
60 return new RoomGrid(image.Width, image.Height, data, null);
61 }
62
63 public static RoomGrid FromCompressedData(int xTiles, int zTiles, byte[] compressedData)
64 {
65 var data = new byte[xTiles * zTiles];
66
67 if (compressedData != null)
68 {
69 int k = 0;
70
71 for (int i = 0; i < compressedData.Length;)
72 {
73 byte run = compressedData[i++];
74 byte type = (byte)(run & 0x0f);
75 byte count = (byte)(run >> 4);
76
77 if (count == 0)
78 count = compressedData[i++];
79
80 for (int j = 0; j < count; j++)
81 data[k++] = type;
82 }
83 }
84
85 return new RoomGrid(xTiles, zTiles, data, null);
86 }
87
88 public int XTiles => xTiles;
89 public int ZTiles => zTiles;
90 public float TileSize => tileSize;
91 public int XOrigin => xOrigin;
92 public int ZOrigin => zOrigin;
93 public byte[] DebugData => debugData;
94
95 public byte[] Compress()
96 {
97 var compressed = new List<byte>(data.Length);
98
99 for (int i = 0; i < data.Length;)
100 {
101 byte type = data[i];
102 int count = 1;
103
104 while (count < 255 && i + count < data.Length && data[i + count] == type)
105 count++;
106
107 if (count < 16)
108 {
109 compressed.Add((byte)((count << 4) | type));
110 }
111 else
112 {
113 compressed.Add(type);
114 compressed.Add((byte)count);
115 }
116
117 i += count;
118 }
119
120 return compressed.ToArray();
121 }
122
123 public Surface ToImage()
124 {
125 var image = new Surface(xTiles, zTiles, SurfaceFormat.BGRX);
126
127 for (int z = 0; z < zTiles; z++)
128 {
129 for (int x = 0; x < xTiles; x++)
130 image[x, z] = gridColors[data[z * xTiles + x]];
131 }
132
133 return image;
134 }
135 }
136}
Note: See TracBrowser for help on using the repository browser.