diff RTXFile.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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RTXFile.cs	Sat Oct 06 19:49:25 2018 +0100
@@ -0,0 +1,216 @@
+// 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.Relic.RelicTools.Exceptions;
+using IBBoard.Relic.RelicTools.Collections;
+
+
+namespace IBBoard.Relic.RelicTools
+{
+	/// <summary>
+	/// Summary description for WTPFile.
+	/// </summary>
+	public class RTXFile:RelicChunkyFile
+	{
+		int width = 0;
+		int height = 0;
+		int id = 0;
+
+		public RTXFile(string filename, ChunkyFolder folder)
+			:this(filename, new ChunkyStructureCollection(new RelicChunkyStructure(folder))){}
+		
+		public RTXFile(string filename, ChunkyCollection col)
+			:this(filename, new ChunkyStructureCollection(new RelicChunkyStructure(col))){}
+
+		public RTXFile(string filename, ChunkyStructureCollection col): base(filename, col)
+		{	
+			int lastIndex = filename.LastIndexOf('_');
+			
+			if (lastIndex == -1 ||  filename.IndexOf('_')==lastIndex)
+			{
+				throw new InvalidFileException("RTX file name specified must end with a skin name and number e.g. _default_0.rtx");
+			}
+
+			try
+			{
+				int dot = filename.LastIndexOf('.');
+				lastIndex++;
+				id = int.Parse(filename.Substring(lastIndex, dot - lastIndex));
+			}
+			catch(FormatException)
+			{
+				throw new InvalidFileException("RTX file name specified must end with a skin name and number e.g. _default_0.rtx");
+			}
+
+			FindAttributes((ChunkyFolder)this.ChunkyStructures[0].RootChunks[0]);			
+		}
+
+		private void FindAttributes(ChunkyFolder folder)
+		{
+			int children = folder.Children.Count;
+			ChunkyChunk chunk = null;
+			ChunkyDataATTR attr = null;
+
+			for (int i = 0; i<children; i++)
+			{
+				chunk = folder.Children[i];
+
+				if (chunk is ChunkyDataATTR)
+				{
+					attr = (ChunkyDataATTR)chunk;
+					width = attr.Width;
+					height = attr.Height;
+					break;
+				}
+				else if (chunk is ChunkyFolder)
+				{
+					FindAttributes((ChunkyFolder)chunk);
+				}
+			}
+		}
+
+		public void SaveParts(DirectoryInfo destination)
+		{
+			string filenamebase = filename.Substring(0, filename.LastIndexOf('.'));
+
+			saveFolder((ChunkyFolder)this.ChunkyStructures[0].RootChunks[0], destination, filenamebase);
+		}
+
+		private void saveFolder(ChunkyFolder folder, DirectoryInfo destination, string filenamebase)
+		{
+			int children = folder.Children.Count;
+			ChunkyChunk chunk = null;
+
+			for (int i = 0; i<children; i++)
+			{
+				chunk = folder.Children[i];
+
+				if (chunk is ChunkyFolder)
+				{
+					this.saveFolder((ChunkyFolder)chunk, destination, filenamebase);
+				}
+				/*else if (chunk is ChunkyDataATTR)
+				{
+					attr = (ChunkyDataATTR)chunk;
+					imagetype = attr.ImageType;
+					mipmaps = attr.MipMaps;
+				}*/
+				else if (chunk is ChunkyDataDATAIMAG)
+				{
+					((ChunkyDataDATAIMAG)chunk).Save(destination, filenamebase);
+				}
+			}
+		}
+
+		public static RTXFile Create(string filepath)
+		{
+			string baseFileName = filepath.Substring(filepath.LastIndexOf(Path.DirectorySeparatorChar)+1);
+			string baseFileNameLower = baseFileName.ToLower();
+
+			string directory = "";
+
+			if (filepath.IndexOf(Path.DirectorySeparatorChar)!=-1)
+			{
+				directory = filepath.Substring(0, filepath.LastIndexOf(Path.DirectorySeparatorChar))+Path.DirectorySeparatorChar;
+			}
+			
+			if(baseFileNameLower.EndsWith(".dds"))
+			{
+				baseFileName = baseFileName.Substring(0, baseFileName.Length-4);
+			}
+			else
+			{
+				throw new InvalidFileException("File path specified is not valid for a RTX file");
+			}
+
+			string unit_name = "";
+			int lastUnderscore = baseFileName.LastIndexOf('_');
+
+			if (lastUnderscore!=-1)
+			{
+				unit_name = baseFileName.Substring(0, lastUnderscore);//trim the number
+
+				try
+				{
+					int id = int.Parse(baseFileName.Substring(lastUnderscore+1));
+				}
+				catch
+				{
+					throw new InvalidFileException("DDS file name specified must end with a number to identify RTX e.g. _default_0.dds");
+				}
+
+				lastUnderscore = unit_name.LastIndexOf('_');
+				if (lastUnderscore!=-1)
+				{
+					unit_name = unit_name.Substring(0, lastUnderscore);
+				}
+				else
+				{
+					throw new InvalidFileException("DDS file name specified must end with a skin name followed by a number e.g. _default_0.dds");
+				}
+			}
+			else
+			{
+				throw new InvalidFileException("DDS file name specified must end with a skin name and number e.g. _default_0.dds");
+			}
+
+			ChunkyDataDATA defaultData = null;
+			ChunkyData attr = null;
+			byte [] data;
+
+			int width = 0;
+			int height = 0;
+			int mipmaps = 0;
+
+			if (File.Exists(directory+baseFileName+".dds"))
+			{
+				CompilationEvent("Reading "+baseFileName+".dds");
+				FileInfo file = new FileInfo(directory+baseFileName+".dds");
+				BinaryReader br = new BinaryReader(file.OpenRead());
+				br.BaseStream.Seek(0, SeekOrigin.Begin);
+				data = br.ReadBytes((int)file.Length);
+
+				defaultData = ChunkyDataDATAIMAG.CreateFromDDS(2, "", data);
+				
+				br.BaseStream.Seek(12,SeekOrigin.Begin);
+				height = br.ReadInt32();
+				width = br.ReadInt32();
+				int size = br.ReadInt32();
+				br.BaseStream.Seek(4, SeekOrigin.Current);
+				mipmaps = br.ReadInt32();
+				br.Close();
+
+				byte type = 0x8;
+
+				if (size==width*height)
+				{
+					type = 0xb;
+				}
+
+				data = new byte[]{type, 0x0, 0x0, 0x0, (byte)width, (byte)(width>>8), (byte)(width>>16), (byte)(width>>24), (byte)(height), (byte)(height>>8), (byte)(height>>16), (byte)(height>>24), (byte)mipmaps, (byte)(mipmaps>>8), (byte)(mipmaps>>16), (byte)(mipmaps>>24)};
+				attr = new ChunkyDataUnknown("ATTR", 2, "", data);
+			}
+			else
+			{
+				throw new RelicTools.Exceptions.FileNotFoundException("RTX files must be made from a DDS file");
+			}
+
+			ChunkyFolder defaultFolder = new ChunkyFolder("IMAG", 1, "");
+
+			defaultFolder.Children.Add(attr);
+			defaultFolder.Children.Add(defaultData);
+
+			ChunkyData head = new ChunkyDataUnknown("HEAD", 1, "", new byte[]{0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00});
+
+
+			CompilationEvent("Compiling RTX File");
+			ChunkyFolder txtr = new ChunkyFolder("TXTR", 1, unit_name);
+			txtr.Children.Add(head);
+			txtr.Children.Add(defaultFolder);
+			return new RTXFile(baseFileName+".rtx", txtr);
+			//RelicChunkyFile.SaveChunky(directory+baseFileName+".rtx", txtr.GetBytes());
+		}
+	}
+}