Merge pull request #6698 from RoosterDragon/memory-savings

Small memory savings
This commit is contained in:
Paul Chote
2014-10-12 11:43:08 +13:00
15 changed files with 79 additions and 82 deletions

View File

@@ -77,12 +77,12 @@ namespace OpenRA.Graphics
Flush(); Flush();
vertices[nv++] = new Vertex(start + offset, vertices[nv++] = new Vertex(start + offset,
new float2(startColor.R / 255.0f, startColor.G / 255.0f), startColor.R / 255.0f, startColor.G / 255.0f,
new float2(startColor.B / 255.0f, startColor.A / 255.0f)); startColor.B / 255.0f, startColor.A / 255.0f);
vertices[nv++] = new Vertex(end + offset, vertices[nv++] = new Vertex(end + offset,
new float2(endColor.R / 255.0f, endColor.G / 255.0f), endColor.R / 255.0f, endColor.G / 255.0f,
new float2(endColor.B / 255.0f, endColor.A / 255.0f)); endColor.B / 255.0f, endColor.A / 255.0f);
} }
public void FillRect(RectangleF r, Color color) public void FillRect(RectangleF r, Color color)

View File

@@ -115,7 +115,7 @@ namespace OpenRA.Graphics
var mapX = x + b.Left; var mapX = x + b.Left;
var mapY = y + b.Top; var mapY = y + b.Top;
var custom = map.CustomTerrain[mapX, mapY]; var custom = map.CustomTerrain[mapX, mapY];
if (custom == -1) if (custom == byte.MaxValue)
continue; continue;
colors[y * stride + x] = world.TileSet[custom].Color.ToArgb(); colors[y * stride + x] = world.TileSet[custom].Color.ToArgb();
} }

View File

@@ -43,17 +43,21 @@ namespace OpenRA.Graphics
} }
} }
public void FillRect(RectangleF r, Color color) public void FillRect(RectangleF rect, Color color)
{ {
Renderer.CurrentBatchRenderer = this; Renderer.CurrentBatchRenderer = this;
if (nv + 4 > Renderer.TempBufferSize) if (nv + 4 > Renderer.TempBufferSize)
Flush(); Flush();
vertices[nv] = new Vertex(new float2(r.Left, r.Top), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f)); var r = color.R / 255.0f;
vertices[nv + 1] = new Vertex(new float2(r.Right, r.Top), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f)); var g = color.G / 255.0f;
vertices[nv + 2] = new Vertex(new float2(r.Right, r.Bottom), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f)); var b = color.B / 255.0f;
vertices[nv + 3] = new Vertex(new float2(r.Left, r.Bottom), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f)); var a = color.A / 255.0f;
vertices[nv] = new Vertex(new float2(rect.Left, rect.Top), r, g, b, a);
vertices[nv + 1] = new Vertex(new float2(rect.Right, rect.Top), r, g, b, a);
vertices[nv + 2] = new Vertex(new float2(rect.Right, rect.Bottom), r, g, b, a);
vertices[nv + 3] = new Vertex(new float2(rect.Left, rect.Bottom), r, g, b, a);
nv += 4; nv += 4;
} }

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Graphics
public readonly float2 size; public readonly float2 size;
public readonly float2 offset; public readonly float2 offset;
public readonly float2 fractionalOffset; public readonly float2 fractionalOffset;
readonly float2[] textureCoords; public readonly float top, left, bottom, right;
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel) public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel)
: this(sheet, bounds, float2.Zero, channel, BlendMode.Alpha) {} : this(sheet, bounds, float2.Zero, channel, BlendMode.Alpha) {}
@@ -40,22 +40,10 @@ namespace OpenRA.Graphics
this.fractionalOffset = offset / this.size; this.fractionalOffset = offset / this.size;
var left = (float)(bounds.Left) / sheet.Size.Width; left = (float)(bounds.Left) / sheet.Size.Width;
var top = (float)(bounds.Top) / sheet.Size.Height; top = (float)(bounds.Top) / sheet.Size.Height;
var right = (float)(bounds.Right) / sheet.Size.Width; right = (float)(bounds.Right) / sheet.Size.Width;
var bottom = (float)(bounds.Bottom) / sheet.Size.Height; bottom = (float)(bounds.Bottom) / sheet.Size.Height;
textureCoords = new float2[]
{
new float2(left, top),
new float2(right, top),
new float2(left, bottom),
new float2(right, bottom),
};
}
public float2 FastMapTextureCoords(int k)
{
return textureCoords[k];
} }
} }

View File

@@ -29,12 +29,13 @@ namespace OpenRA.Graphics
public static void FastCreateQuad(Vertex[] vertices, float2 a, float2 b, float2 c, float2 d, Sprite r, int palette, int nv) public static void FastCreateQuad(Vertex[] vertices, float2 a, float2 b, float2 c, float2 d, Sprite r, int palette, int nv)
{ {
var attrib = new float2(palette / (float)HardwarePalette.MaxPalettes, channelSelect[(int)r.channel]); var attribP = palette / (float)HardwarePalette.MaxPalettes;
var attribC = channelSelect[(int)r.channel];
vertices[nv] = new Vertex(a, r.FastMapTextureCoords(0), attrib); vertices[nv] = new Vertex(a, r.left, r.top, attribP, attribC);
vertices[nv + 1] = new Vertex(b, r.FastMapTextureCoords(1), attrib); vertices[nv + 1] = new Vertex(b, r.right, r.top, attribP, attribC);
vertices[nv + 2] = new Vertex(c, r.FastMapTextureCoords(3), attrib); vertices[nv + 2] = new Vertex(c, r.right, r.bottom, attribP, attribC);
vertices[nv + 3] = new Vertex(d, r.FastMapTextureCoords(2), attrib); vertices[nv + 3] = new Vertex(d, r.left, r.bottom, attribP, attribC);
} }
static readonly int[] channelMasks = { 2, 1, 0, 3 }; // yes, our channel order is nuts. static readonly int[] channelMasks = { 2, 1, 0, 3 }; // yes, our channel order is nuts.

View File

@@ -18,18 +18,18 @@ namespace OpenRA.Graphics
public float x, y, z, u, v; public float x, y, z, u, v;
public float p, c; public float p, c;
public Vertex(float2 xy, float2 uv, float2 pc) public Vertex(float2 xy, float u, float v, float p, float c)
{ {
this.x = xy.X; this.y = xy.Y; this.z = 0; this.x = xy.X; this.y = xy.Y; this.z = 0;
this.u = uv.X; this.v = uv.Y; this.u = u; this.v = v;
this.p = pc.X; this.c = pc.Y; this.p = p; this.c = c;
} }
public Vertex(float[] xyz, float2 uv, float2 pc) public Vertex(float[] xyz, float u, float v, float p, float c)
{ {
this.x = xyz[0]; this.y = xyz[1]; this.z = xyz[2]; this.x = xyz[0]; this.y = xyz[1]; this.z = xyz[2];
this.u = uv.X; this.v = uv.Y; this.u = u; this.v = v;
this.p = pc.X; this.c = pc.Y; this.p = p; this.c = c;
} }
} }
} }

View File

@@ -87,13 +87,14 @@ namespace OpenRA.Graphics
Util.FastCopyIntoChannel(s, 1, normals); Util.FastCopyIntoChannel(s, 1, normals);
s.sheet.CommitData(); s.sheet.CommitData();
var channels = new float2(channelSelect[(int)s.channel], channelSelect[(int)s.channel + 1]); var channelP =channelSelect[(int)s.channel];
var channelC = channelSelect[(int)s.channel + 1];
return new Vertex[4] return new Vertex[4]
{ {
new Vertex(coord(0, 0), s.FastMapTextureCoords(0), channels), new Vertex(coord(0, 0), s.left, s.top, channelP, channelC),
new Vertex(coord(su, 0), s.FastMapTextureCoords(1), channels), new Vertex(coord(su, 0),s.right, s.top, channelP, channelC),
new Vertex(coord(su, sv), s.FastMapTextureCoords(3), channels), new Vertex(coord(su, sv), s.right, s.bottom, channelP, channelC),
new Vertex(coord(0, sv), s.FastMapTextureCoords(2), channels) new Vertex(coord(0, sv), s.left, s.bottom, channelP, channelC)
}; };
} }

View File

@@ -122,7 +122,7 @@ namespace OpenRA
[FieldLoader.Ignore] public Lazy<CellLayer<TerrainTile>> MapTiles; [FieldLoader.Ignore] public Lazy<CellLayer<TerrainTile>> MapTiles;
[FieldLoader.Ignore] public Lazy<CellLayer<ResourceTile>> MapResources; [FieldLoader.Ignore] public Lazy<CellLayer<ResourceTile>> MapResources;
[FieldLoader.Ignore] public CellLayer<int> CustomTerrain; [FieldLoader.Ignore] public CellLayer<byte> CustomTerrain;
[FieldLoader.Ignore] Lazy<TileSet> cachedTileSet; [FieldLoader.Ignore] Lazy<TileSet> cachedTileSet;
[FieldLoader.Ignore] Lazy<Ruleset> rules; [FieldLoader.Ignore] Lazy<Ruleset> rules;
@@ -281,9 +281,9 @@ namespace OpenRA
var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1)); var br = Map.MapToCell(TileShape, new CPos(Bounds.Right - 1, Bounds.Bottom - 1));
Cells = new CellRegion(TileShape, tl, br); Cells = new CellRegion(TileShape, tl, br);
CustomTerrain = new CellLayer<int>(this); CustomTerrain = new CellLayer<byte>(this);
foreach (var cell in Cells) foreach (var cell in Cells)
CustomTerrain[cell] = -1; CustomTerrain[cell] = byte.MaxValue;
} }
public Ruleset PreloadRules() public Ruleset PreloadRules()
@@ -673,10 +673,10 @@ namespace OpenRA
} }
} }
public int GetTerrainIndex(CPos cell) public byte GetTerrainIndex(CPos cell)
{ {
var custom = CustomTerrain[cell]; var custom = CustomTerrain[cell];
return custom != -1 ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[cell]); return custom != byte.MaxValue ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[cell]);
} }
public TerrainTypeInfo GetTerrainInfo(CPos cell) public TerrainTypeInfo GetTerrainInfo(CPos cell)

View File

@@ -39,9 +39,9 @@ namespace OpenRA
public readonly bool PickAny; public readonly bool PickAny;
public readonly string Category; public readonly string Category;
int[] tiles; byte[] tiles;
public TileTemplate(ushort id, string image, int2 size, int[] tiles) public TileTemplate(ushort id, string image, int2 size, byte[] tiles)
{ {
this.Id = id; this.Id = id;
this.Image = image; this.Image = image;
@@ -56,16 +56,16 @@ namespace OpenRA
tiles = LoadTiles(tileSet, my); tiles = LoadTiles(tileSet, my);
} }
int[] LoadTiles(TileSet tileSet, MiniYaml y) byte[] LoadTiles(TileSet tileSet, MiniYaml y)
{ {
var nodes = y.ToDictionary()["Tiles"].Nodes; var nodes = y.ToDictionary()["Tiles"].Nodes;
if (!PickAny) if (!PickAny)
{ {
var tiles = new int[Size.X * Size.Y]; var tiles = new byte[Size.X * Size.Y];
for (var i = 0; i < tiles.Length; i++) for (var i = 0; i < tiles.Length; i++)
tiles[i] = -1; tiles[i] = byte.MaxValue;
foreach (var node in nodes) foreach (var node in nodes)
{ {
@@ -80,7 +80,7 @@ namespace OpenRA
} }
else else
{ {
var tiles = new int[nodes.Count]; var tiles = new byte[nodes.Count];
var i = 0; var i = 0;
foreach (var node in nodes) foreach (var node in nodes)
@@ -98,7 +98,7 @@ namespace OpenRA
static readonly string[] Fields = { "Id", "Image", "Frames", "Size", "PickAny" }; static readonly string[] Fields = { "Id", "Image", "Frames", "Size", "PickAny" };
public int this[int index] public byte this[int index]
{ {
get { return tiles[index]; } get { return tiles[index]; }
} }
@@ -145,8 +145,8 @@ namespace OpenRA
public readonly string[] EditorTemplateOrder; public readonly string[] EditorTemplateOrder;
public readonly TerrainTypeInfo[] TerrainInfo; public readonly TerrainTypeInfo[] TerrainInfo;
readonly Dictionary<string, int> terrainIndexByType = new Dictionary<string, int>(); readonly Dictionary<string, byte> terrainIndexByType = new Dictionary<string, byte>();
readonly int defaultWalkableTerrainIndex; readonly byte defaultWalkableTerrainIndex;
static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "Extensions" }; static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "Extensions" };
@@ -162,7 +162,9 @@ namespace OpenRA
.Select(y => new TerrainTypeInfo(y)) .Select(y => new TerrainTypeInfo(y))
.OrderBy(tt => tt.Type) .OrderBy(tt => tt.Type)
.ToArray(); .ToArray();
for (var i = 0; i < TerrainInfo.Length; i++) if (TerrainInfo.Length >= byte.MaxValue)
throw new InvalidDataException("Too many terrain types.");
for (byte i = 0; i < TerrainInfo.Length; i++)
{ {
var tt = TerrainInfo[i].Type; var tt = TerrainInfo[i].Type;
@@ -186,8 +188,9 @@ namespace OpenRA
this.Palette = palette; this.Palette = palette;
this.Extensions = extensions; this.Extensions = extensions;
this.TerrainInfo = terrainInfo; this.TerrainInfo = terrainInfo;
if (TerrainInfo.Length >= byte.MaxValue)
for (var i = 0; i < terrainInfo.Length; i++) throw new InvalidDataException("Too many terrain types.");
for (byte i = 0; i < terrainInfo.Length; i++)
{ {
var tt = terrainInfo[i].Type; var tt = terrainInfo[i].Type;
@@ -199,7 +202,7 @@ namespace OpenRA
defaultWalkableTerrainIndex = GetTerrainIndex("Clear"); defaultWalkableTerrainIndex = GetTerrainIndex("Clear");
} }
public TerrainTypeInfo this[int index] public TerrainTypeInfo this[byte index]
{ {
get { return TerrainInfo[index]; } get { return TerrainInfo[index]; }
} }
@@ -209,28 +212,28 @@ namespace OpenRA
get { return TerrainInfo.Length; } get { return TerrainInfo.Length; }
} }
public bool TryGetTerrainIndex(string type, out int index) public bool TryGetTerrainIndex(string type, out byte index)
{ {
return terrainIndexByType.TryGetValue(type, out index); return terrainIndexByType.TryGetValue(type, out index);
} }
public int GetTerrainIndex(string type) public byte GetTerrainIndex(string type)
{ {
int index; byte index;
if (terrainIndexByType.TryGetValue(type, out index)) if (terrainIndexByType.TryGetValue(type, out index))
return index; return index;
throw new InvalidDataException("Tileset '{0}' lacks terrain type '{1}'".F(Id, type)); throw new InvalidDataException("Tileset '{0}' lacks terrain type '{1}'".F(Id, type));
} }
public int GetTerrainIndex(TerrainTile r) public byte GetTerrainIndex(TerrainTile r)
{ {
var tpl = Templates[r.Type]; var tpl = Templates[r.Type];
if (tpl.Contains(r.Index)) if (tpl.Contains(r.Index))
{ {
var ti = tpl[r.Index]; var ti = tpl[r.Index];
if (ti != -1) if (ti != byte.MaxValue)
return ti; return ti;
} }
@@ -263,7 +266,7 @@ namespace OpenRA
public TerrainTypeInfo GetTerrainInfo(TerrainTile r) public TerrainTypeInfo GetTerrainInfo(TerrainTile r)
{ {
return TerrainInfo[GetTerrainIndex(r)]; return this[GetTerrainIndex(r)];
} }
} }
} }

View File

@@ -9,6 +9,7 @@
#endregion #endregion
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common; using OpenRA.Mods.Common;
@@ -158,7 +159,7 @@ namespace OpenRA.Mods.RA.AI
bool enabled; bool enabled;
int ticks; int ticks;
HashSet<int> resourceTypeIndices; BitArray resourceTypeIndices;
RushFuzzy rushFuzzy = new RushFuzzy(); RushFuzzy rushFuzzy = new RushFuzzy();
@@ -208,10 +209,9 @@ namespace OpenRA.Mods.RA.AI
random = new MersenneTwister((int)p.PlayerActor.ActorID); random = new MersenneTwister((int)p.PlayerActor.ActorID);
resourceTypeIndices = new HashSet<int>( resourceTypeIndices = new BitArray(world.TileSet.TerrainInfo.Length); // Big enough
Map.Rules.Actors["world"].Traits foreach (var t in Map.Rules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>())
.WithInterface<ResourceTypeInfo>() resourceTypeIndices.Set(world.TileSet.GetTerrainIndex(t.TerrainType), true);
.Select(t => world.TileSet.GetTerrainIndex(t.TerrainType)));
} }
ActorInfo ChooseRandomUnitToBuild(ProductionQueue queue) ActorInfo ChooseRandomUnitToBuild(ProductionQueue queue)
@@ -371,7 +371,7 @@ namespace OpenRA.Mods.RA.AI
// Try and place the refinery near a resource field // Try and place the refinery near a resource field
var nearbyResources = Map.FindTilesInCircle(baseCenter, Info.MaxBaseRadius) var nearbyResources = Map.FindTilesInCircle(baseCenter, Info.MaxBaseRadius)
.Where(a => resourceTypeIndices.Contains(Map.GetTerrainIndex(a))) .Where(a => resourceTypeIndices.Get(Map.GetTerrainIndex(a)))
.Shuffle(random); .Shuffle(random);
foreach (var c in nearbyResources) foreach (var c in nearbyResources)

View File

@@ -117,7 +117,7 @@ namespace OpenRA.Mods.RA
self.World.Map.CustomTerrain[c] = GetTerrainType(c); self.World.Map.CustomTerrain[c] = GetTerrainType(c);
} }
int GetTerrainType(CPos cell) byte GetTerrainType(CPos cell)
{ {
var dx = cell - self.Location; var dx = cell - self.Location;
var index = dx.X + self.World.TileSet.Templates[template].Size.X * dx.Y; var index = dx.X + self.World.TileSet.Templates[template].Size.X * dx.Y;

View File

@@ -57,7 +57,7 @@ namespace OpenRA.Mods.RA.Buildings
continue; continue;
// Don't place under other buildings or custom terrain // Don't place under other buildings or custom terrain
if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != -1) if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != byte.MaxValue)
continue; continue;
var index = Game.CosmeticRandom.Next(template.TilesCount); var index = Game.CosmeticRandom.Next(template.TilesCount);
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.RA.Buildings
continue; continue;
// Don't place under other buildings or custom terrain // Don't place under other buildings or custom terrain
if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != -1) if (bi.GetBuildingAt(c) != self || map.CustomTerrain[c] != byte.MaxValue)
continue; continue;
layer.AddTile(c, new TerrainTile(template.Id, (byte)i)); layer.AddTile(c, new TerrainTile(template.Id, (byte)i));

View File

@@ -82,7 +82,7 @@ namespace OpenRA.Mods.RA.Move
foreach (var kvp in TerrainSpeeds) foreach (var kvp in TerrainSpeeds)
{ {
int index; byte index;
if (tileSet.TryGetTerrainIndex(kvp.Key, out index)) if (tileSet.TryGetTerrainIndex(kvp.Key, out index))
info[index] = kvp.Value; info[index] = kvp.Value;
} }
@@ -125,7 +125,7 @@ namespace OpenRA.Mods.RA.Move
return int.MaxValue; return int.MaxValue;
var index = world.Map.GetTerrainIndex(cell); var index = world.Map.GetTerrainIndex(cell);
if (index == -1) if (index == byte.MaxValue)
return int.MaxValue; return int.MaxValue;
return TilesetTerrainInfo[world.TileSet][index].Cost; return TilesetTerrainInfo[world.TileSet][index].Cost;
@@ -526,7 +526,7 @@ namespace OpenRA.Mods.RA.Move
public int MovementSpeedForCell(Actor self, CPos cell) public int MovementSpeedForCell(Actor self, CPos cell)
{ {
var index = self.World.Map.GetTerrainIndex(cell); var index = self.World.Map.GetTerrainIndex(cell);
if (index == -1) if (index == byte.MaxValue)
return 0; return 0;
// TODO: Convert to integers // TODO: Convert to integers

View File

@@ -203,7 +203,7 @@ namespace OpenRA.Mods.RA
if (--c.Density < 0) if (--c.Density < 0)
{ {
content[cell] = EmptyCell; content[cell] = EmptyCell;
world.Map.CustomTerrain[cell] = -1; world.Map.CustomTerrain[cell] = byte.MaxValue;
} }
else else
content[cell] = c; content[cell] = c;
@@ -222,7 +222,7 @@ namespace OpenRA.Mods.RA
// Clear cell // Clear cell
content[cell] = EmptyCell; content[cell] = EmptyCell;
world.Map.CustomTerrain[cell] = -1; world.Map.CustomTerrain[cell] = byte.MaxValue;
if (!dirty.Contains(cell)) if (!dirty.Contains(cell))
dirty.Add(cell); dirty.Add(cell);

View File

@@ -385,7 +385,7 @@ namespace OpenRA.TilesetBuilder
ushort cur = 0; ushort cur = 0;
foreach (var tp in surface1.Templates) foreach (var tp in surface1.Templates)
{ {
var tiles = new int[tp.Width * tp.Height]; var tiles = new byte[tp.Width * tp.Height];
foreach (var t in tp.Cells) foreach (var t in tp.Cells)
{ {
var ttype = TerrainType[surface1.TerrainTypes[t.Key.X, t.Key.Y]].Type; var ttype = TerrainType[surface1.TerrainTypes[t.Key.X, t.Key.Y]].Type;