97
OpenRA.FileFormats/Graphics/TileSetRenderer.cs
Normal file
97
OpenRA.FileFormats/Graphics/TileSetRenderer.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OpenRA.FileFormats
|
||||
{
|
||||
public class TileSetRenderer
|
||||
{
|
||||
public TileSet TileSet;
|
||||
Dictionary<ushort, List<byte[]>> templates;
|
||||
public Size TileSize;
|
||||
|
||||
List<byte[]> LoadTemplate(string filename, string[] exts, Cache<string, R8Reader> r8Cache, int[] frames)
|
||||
{
|
||||
if (exts.Contains(".R8") && FileSystem.Exists(filename+".R8"))
|
||||
{
|
||||
var data = new List<byte[]>();
|
||||
|
||||
foreach (var f in frames)
|
||||
data.Add(f >= 0 ? r8Cache[filename][f].Image : null);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
using (var s = FileSystem.OpenWithExts(filename, exts))
|
||||
return new Terrain(s).TileBitmapBytes;
|
||||
}
|
||||
|
||||
public TileSetRenderer(TileSet tileset, Size tileSize)
|
||||
{
|
||||
this.TileSet = tileset;
|
||||
this.TileSize = tileSize;
|
||||
|
||||
templates = new Dictionary<ushort, List<byte[]>>();
|
||||
var r8Cache = new Cache<string, R8Reader>(s => new R8Reader(FileSystem.OpenWithExts(s, ".R8")));
|
||||
foreach (var t in TileSet.Templates)
|
||||
templates.Add(t.Key, LoadTemplate(t.Value.Image, tileset.Extensions, r8Cache, t.Value.Frames));
|
||||
}
|
||||
|
||||
public Bitmap RenderTemplate(ushort id, Palette p)
|
||||
{
|
||||
var template = TileSet.Templates[id];
|
||||
var templateData = templates[id];
|
||||
|
||||
var bitmap = new Bitmap(TileSize.Width * template.Size.X, TileSize.Height * template.Size.Y,
|
||||
PixelFormat.Format8bppIndexed);
|
||||
|
||||
bitmap.Palette = p.AsSystemPalette();
|
||||
|
||||
var data = bitmap.LockBits(bitmap.Bounds(),
|
||||
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
|
||||
|
||||
unsafe
|
||||
{
|
||||
var q = (byte*)data.Scan0.ToPointer();
|
||||
var stride = data.Stride;
|
||||
|
||||
for (var u = 0; u < template.Size.X; u++)
|
||||
for (var v = 0; v < template.Size.Y; v++)
|
||||
if (templateData[u + v * template.Size.X] != null)
|
||||
{
|
||||
var rawImage = templateData[u + v * template.Size.X];
|
||||
for (var i = 0; i < TileSize.Width; i++)
|
||||
for (var j = 0; j < TileSize.Height; j++)
|
||||
q[(v * TileSize.Width + j) * stride + u * TileSize.Width + i] = rawImage[i + TileSize.Width * j];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < TileSize.Width; i++)
|
||||
for (var j = 0; j < TileSize.Height; j++)
|
||||
q[(v * TileSize.Width + j) * stride + u * TileSize.Width + i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bitmap.UnlockBits(data);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public List<byte[]> Data(ushort id)
|
||||
{
|
||||
return templates[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,16 +16,15 @@ namespace OpenRA.FileFormats
|
||||
public class Terrain
|
||||
{
|
||||
public readonly List<byte[]> TileBitmapBytes = new List<byte[]>();
|
||||
public readonly int Width;
|
||||
public readonly int Height;
|
||||
|
||||
public Terrain( Stream stream, int size )
|
||||
public Terrain(Stream stream)
|
||||
{
|
||||
// Try loading as a cnc .tem
|
||||
BinaryReader reader = new BinaryReader( stream );
|
||||
int Width = reader.ReadUInt16();
|
||||
int Height = reader.ReadUInt16();
|
||||
|
||||
if( Width != size || Height != size )
|
||||
throw new InvalidDataException( "{0}x{1} != {2}x{2}".F(Width, Height, size ) );
|
||||
Width = reader.ReadUInt16();
|
||||
Height = reader.ReadUInt16();
|
||||
|
||||
/*NumTiles = */reader.ReadUInt16();
|
||||
/*Zero1 = */reader.ReadUInt16();
|
||||
@@ -65,8 +64,8 @@ namespace OpenRA.FileFormats
|
||||
{
|
||||
if (b != 255)
|
||||
{
|
||||
stream.Position = ImgStart + b * size * size;
|
||||
TileBitmapBytes.Add(new BinaryReader(stream).ReadBytes(size * size));
|
||||
stream.Position = ImgStart + b * Width * Height;
|
||||
TileBitmapBytes.Add(new BinaryReader(stream).ReadBytes(Width * Height));
|
||||
}
|
||||
else
|
||||
TileBitmapBytes.Add(null);
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace OpenRA.FileFormats
|
||||
{
|
||||
public ushort Id;
|
||||
public string Image;
|
||||
public int[] Frames;
|
||||
public int2 Size;
|
||||
public bool PickAny;
|
||||
public string Category;
|
||||
@@ -52,7 +53,7 @@ namespace OpenRA.FileFormats
|
||||
t => t.Value.Value);
|
||||
}
|
||||
|
||||
static readonly string[] Fields = { "Id", "Image", "Size", "PickAny" };
|
||||
static readonly string[] Fields = { "Id", "Image", "Frames", "Size", "PickAny" };
|
||||
|
||||
public MiniYaml Save()
|
||||
{
|
||||
@@ -71,24 +72,22 @@ namespace OpenRA.FileFormats
|
||||
|
||||
return new MiniYaml(null, root);
|
||||
}
|
||||
|
||||
public Terrain Data;
|
||||
}
|
||||
|
||||
public class TileSet
|
||||
{
|
||||
public string Name;
|
||||
public string Id;
|
||||
public int SheetSize = 512;
|
||||
public string Palette;
|
||||
public string PlayerPalette;
|
||||
public int TileSize = 24;
|
||||
public string[] Extensions;
|
||||
public int WaterPaletteRotationBase = 0x60;
|
||||
public Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
|
||||
public Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||
public string[] EditorTemplateOrder;
|
||||
|
||||
static readonly string[] fields = {"Name", "TileSize", "Id", "Palette", "Extensions"};
|
||||
static readonly string[] fields = {"Name", "TileSize", "Id", "SheetSize", "Palette", "Extensions"};
|
||||
|
||||
public TileSet() {}
|
||||
|
||||
@@ -108,14 +107,6 @@ namespace OpenRA.FileFormats
|
||||
.Select(y => new TileTemplate(y)).ToDictionary(t => t.Id);
|
||||
}
|
||||
|
||||
public void LoadTiles()
|
||||
{
|
||||
foreach (var t in Templates)
|
||||
if (t.Value.Data == null)
|
||||
using (var s = FileSystem.OpenWithExts(t.Value.Image, Extensions))
|
||||
t.Value.Data = new Terrain(s, TileSize);
|
||||
}
|
||||
|
||||
public void Save(string filepath)
|
||||
{
|
||||
var root = new List<MiniYamlNode>();
|
||||
@@ -144,23 +135,6 @@ namespace OpenRA.FileFormats
|
||||
root.WriteToFile(filepath);
|
||||
}
|
||||
|
||||
public byte[] GetBytes(TileReference<ushort,byte> r)
|
||||
{
|
||||
TileTemplate tile;
|
||||
if (Templates.TryGetValue(r.type, out tile))
|
||||
{
|
||||
var data = tile.Data.TileBitmapBytes[r.index];
|
||||
if (data != null)
|
||||
return data;
|
||||
}
|
||||
|
||||
byte[] missingTile = new byte[TileSize*TileSize];
|
||||
for (var i = 0; i < missingTile.Length; i++)
|
||||
missingTile[i] = 0x00;
|
||||
|
||||
return missingTile;
|
||||
}
|
||||
|
||||
public string GetTerrainType(TileReference<ushort, byte> r)
|
||||
{
|
||||
var tt = Templates[r.type].Tiles;
|
||||
@@ -170,43 +144,5 @@ namespace OpenRA.FileFormats
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Bitmap RenderTemplate(ushort n, Palette p)
|
||||
{
|
||||
var template = Templates[n];
|
||||
|
||||
var bitmap = new Bitmap(TileSize * template.Size.X, TileSize * template.Size.Y,
|
||||
PixelFormat.Format8bppIndexed);
|
||||
|
||||
bitmap.Palette = p.AsSystemPalette();
|
||||
|
||||
var data = bitmap.LockBits(bitmap.Bounds(),
|
||||
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
|
||||
|
||||
unsafe
|
||||
{
|
||||
byte* q = (byte*)data.Scan0.ToPointer();
|
||||
var stride = data.Stride;
|
||||
|
||||
for (var u = 0; u < template.Size.X; u++)
|
||||
for (var v = 0; v < template.Size.Y; v++)
|
||||
if (template.Data.TileBitmapBytes[u + v * template.Size.X] != null)
|
||||
{
|
||||
var rawImage = template.Data.TileBitmapBytes[u + v * template.Size.X];
|
||||
for (var i = 0; i < TileSize; i++)
|
||||
for (var j = 0; j < TileSize; j++)
|
||||
q[(v * TileSize + j) * stride + u * TileSize + i] = rawImage[i + TileSize * j];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < TileSize; i++)
|
||||
for (var j = 0; j < TileSize; j++)
|
||||
q[(v * TileSize + j) * stride + u * TileSize + i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bitmap.UnlockBits(data);
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
<Compile Include="FileFormats\WavLoader.cs" />
|
||||
<Compile Include="Filesystem\D2kSoundResources.cs" />
|
||||
<Compile Include="Graphics\R8Reader.cs" />
|
||||
<Compile Include="Graphics\TileSetRenderer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
|
||||
Reference in New Issue
Block a user