ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/OniSplit/Akira/RoomGrid.cs
Revision: 1114
Committed: Wed Jan 22 14:08:57 2020 UTC (5 years, 8 months ago) by iritscen
File size: 4106 byte(s)
Log Message:
Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File Contents

# Content
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using Oni.Imaging;
5
6 namespace 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 }