Mercurial > repos > RelicTools > RelicTools
view ChunkyDataPTBD.cs @ 0:82db9430c2e4 default tip
Initial commit under GPLv3
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 06 Oct 2018 19:49:25 +0100 |
parents | |
children |
line wrap: on
line source
// This file is a part of the Relic Tools and is copyright 2006-2018 IBBoard. // // The file and the library/program it is in are licensed under the GNU GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license. using System; using System.IO; using IBBoard.Graphics; using IBBoard.Relic.RelicTools.Exceptions; namespace IBBoard.Relic.RelicTools { /// <summary> /// Summary description for ChunkyDataPTBD. /// </summary> public class ChunkyDataPTBD : ChunkyDataLayer { const float size_x = 64; const float size_y = 64; float x; float y; public ChunkyDataPTBD(int version_in, string name_in, byte[] innerData):base("PTBD", version_in, name_in) { x = BitConverter.ToSingle(innerData,0); y = BitConverter.ToSingle(innerData,4); } public float Pos_x { get{ return x; } } public float Pos_y { get{ return y; } } public float Height { get{ return size_y; } } public float Width { get{ return size_x; } } public override void Save(DirectoryInfo dir, string fileBaseName) { int width = Info.Width; int height = Info.Height; float right = x+size_x; float top = y+size_y; if (((int)right)>width || ((int)top)>height) { throw new InvalidChunkException("Badge layer contains an invalid badge position"); } //create the TGA int fileLength = width*height; byte [] file = new byte[fileLength]; int pos = 0; for (int i = 0; i<height; i++) { for (int j = 0; j<width; j++) { if (x<=j && j<right && y<=i && i<top) { file[pos] = byte.MaxValue; } else { file[pos] = byte.MinValue; } pos++; } } //save the TGA FileStream str = new FileStream(dir.FullName.TrimEnd(Path.DirectorySeparatorChar)+Path.DirectorySeparatorChar+fileBaseName+"_Badge.tga", FileMode.Create); BinaryWriter bw = new BinaryWriter(str); bw.Write(TGA_Greyscale_Header_a); bw.Write((ushort)width); bw.Write((ushort)height); bw.Write(TGA_Greyscale_Header_b); bw.Write(file); bw.Flush(); bw.Close(); } public static ChunkyDataPTBD CreateFromTGA(int version, string name, byte[] tgaData) { //check image type code if (tgaData[2]!=0x03) { bool worked = false; if (tgaData[1] == 0x01 && tgaData[2] == 0x01) { tgaData = ImageConverter.ColourMapToGreyscale(tgaData); worked = true; } if (!worked) { ImageConverter.MapEncStruct format = ImageConverter.getMapEncStruct(tgaData[2]); throw new InvalidFileException("_badge.tga must be an unencoded unmapped monochrome Targa image.\r\n"+ " Image type: "+format.formatType+"\r\n"+ " Image encoded: "+((format.isEncoded)?"yes":"no")+"\r\n"+ " Colour mapped: "+((format.isMapped)?"yes":"no")); } } //check colour depth if (tgaData[16]!=0x08) { throw new InvalidFileException("_badge.tga must be an 8-bit Targa image. Image was "+tgaData[16]+"-bit."); } float pos_x = float.MinValue; float pos_y = float.MinValue; int width = (int)tgaData[12]+(((int)tgaData[13])<<8); int height = (int)tgaData[14]+(((int)tgaData[15])<<8); int currPos = 0; int size_x_int = (int)size_x; for (currPos = 18; currPos<tgaData.Length; currPos+=size_x_int) { //try to find our badge; if (tgaData[currPos]==byte.MaxValue) { pos_y = (float)((currPos-18)/width); pos_x = (float)(currPos-18-(pos_y*width)); break; } } if (pos_y!=float.MinValue) { int maxPossibleEnd = currPos+width; int extra = 0; while (currPos<maxPossibleEnd && tgaData[currPos]==byte.MaxValue) { currPos++; extra++; } //check where the left hand side should start if (pos_x>0 && (tgaData[currPos-size_x_int]!=byte.MaxValue || tgaData[currPos-size_x_int-1]!=byte.MinValue)) { throw new InvalidFileException("Badge is is not the correct width or is not a solid white square"); } else { pos_x = pos_x+extra-size_x; } //and check for the top - not all of the block, just assume a left and bottom side are OK int aboveTop = currPos-size_x_int+(width*(int)size_y); for (int i = currPos-size_x_int; i<=aboveTop && i<tgaData.Length; i+= width) { if (tgaData[i]!=byte.MaxValue && i!=aboveTop) { throw new InvalidFileException("Badge area is too small. Badge must be 64px by 64px"); } } //if we got here, it's all OK byte[] data = new byte[16]; BitConverter.GetBytes(pos_x).CopyTo(data, 0); BitConverter.GetBytes(pos_y).CopyTo(data, 4); BitConverter.GetBytes(size_x).CopyTo(data, 8); BitConverter.GetBytes(size_y).CopyTo(data, 12); return new ChunkyDataPTBD(version, name, data); } else { return null; } } public override bool Savable { get { return true; } } public override int DataLength { get { return 16; } } public override byte[] GetDataBytes() { byte[] data = new byte[16]; BitConverter.GetBytes(x).CopyTo(data, 0); BitConverter.GetBytes(y).CopyTo(data, 4); BitConverter.GetBytes(size_x).CopyTo(data, 8); BitConverter.GetBytes(size_y).CopyTo(data, 12); return data; } public override string GetDisplayDetails() { return base.GetBaseDisplayDetails()+Environment.NewLine+ "------------"+Environment.NewLine+ "X:\t\t"+x+Environment.NewLine+ "Y:\t\t"+y+Environment.NewLine+ "Width:\t\t"+size_x+Environment.NewLine+ "Height:\t\t"+size_y; } } }