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); } } }
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 ChunkyData) { ((ChunkyData)chunk).Save(destination, filenamebase); } else if (chunk is ChunkyFolder) { this.saveFolder((ChunkyFolder)chunk, destination, filenamebase); } //else something is wrong! /*else if (chunk is ChunkyDataDATAIMAG) * { * ((ChunkyDataDATAIMAG)chunk).Save(destination, filenamebase); * } * else if (chunk is ChunkyDataPTBD) * { * ((ChunkyDataPTBD)chunk).Save(destination, filenamebase); * } * else if (chunk is ChunkyDataPTBN) * { * ((ChunkyDataPTBN)chunk).Save(destination, filenamebase); * }*/ } }
public RelicChunkyStructure(ChunkyFolder chunkyRoot, int unknown1, int unknown2, int unknown3) { chunkCol = new ChunkyCollection(); chunkCol.Add(chunkyRoot); unknownInt1 = unknown1; unknownInt2 = unknown2; unknownInt3 = unknown3; }
public WTPFile(string filename, ChunkyStructureCollection col) : base(filename, col) { ChunkyFolder folder = (ChunkyFolder)col[0].RootChunks[0]; int children = folder.Children.Count; ChunkyChunk chunk = null; ChunkyDataINFOTPAT info = null; for (int i = 0; i < children; i++) { chunk = folder.Children[i]; if (chunk is ChunkyDataINFOTPAT) { info = (ChunkyDataINFOTPAT)chunk; width = info.Width; height = info.Height; } } }
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 ChunkyDataDATAIMAG) { ((ChunkyDataDATAIMAG)chunk).Save(destination, folder.Parent.Name.Substring(folder.Parent.Name.LastIndexOf('/') + 1)); } } }
private ChunkyDataATTR findFirstDataAttributes() { if (attr == null) { ChunkyFolder root = (ChunkyFolder)this.ChunkyStructures[0].RootChunks[0]; for (int i = 0; i < root.Children.Count; i++) { if (root.Children[i] is ChunkyFolder) { root = (ChunkyFolder)root.Children[i]; break; } } if (root.Children[0] is ChunkyDataATTR) { attr = (ChunkyDataATTR)root.Children[0]; } } return(attr); }
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 static WTPFile 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(".wtp")) { baseFileName = baseFileName.Substring(0, baseFileName.Length - 4); } else if (baseFileNameLower.EndsWith(".tga")) { if (baseFileNameLower.EndsWith("_primary.tga")) { baseFileName = baseFileName.Substring(0, baseFileName.Length - 12); } else if (baseFileNameLower.EndsWith("_secondary.tga")) { baseFileName = baseFileName.Substring(0, baseFileName.Length - 14); } else if (baseFileNameLower.EndsWith("_weapon.tga") || baseFileNameLower.EndsWith("_banner.tga")) { baseFileName = baseFileName.Substring(0, baseFileName.Length - 11); } else if (baseFileNameLower.EndsWith("_badge.tga")) { baseFileName = baseFileName.Substring(0, baseFileName.Length - 10); } else if (baseFileNameLower.EndsWith("_eyes.tga") || baseFileNameLower.EndsWith("_trim.tga") || baseFileNameLower.EndsWith("_dirt.tga")) { baseFileName = baseFileName.Substring(0, baseFileName.Length - 9); } else { baseFileName = baseFileName.Substring(0, baseFileName.Length - 4); } } else { throw new InvalidFileException("File path specified is not valid for a WTP file or one of its components"); } string skinName = baseFileName.Substring(baseFileName.LastIndexOf('_') + 1); //make it forwards compatible on the off-chance Relic introduce multiple textures ChunkyDataDATA defaultData = null; ChunkyData attr = null; FileStream fs = null; BinaryReader br = null; FileInfo file = null; byte [] data; int width = 0; int height = 0; if (File.Exists(directory + baseFileName + ".tga")) { CompilationEvent("Reading " + baseFileName + ".tga"); file = new FileInfo(directory + baseFileName + ".tga"); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(12, SeekOrigin.Begin); width = br.ReadInt16(); height = br.ReadInt16(); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); defaultData = ChunkyDataDATAIMAG.CreateFromTGA(2, "", data); br.Close(); data = new byte[] { 0x0, 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), 0x1, 0x0, 0x0, 0x0 }; attr = new ChunkyDataUnknown("ATTR", 2, "", data); } else { throw new RelicTools.Exceptions.FileNotFoundException("WTP files must have a 32bit layer e.g. _default.tga layer"); } string dirt_name = directory + baseFileName + "_Dirt.tga"; ChunkyFolder defaultFolder = new ChunkyFolder("IMAG", 1, "TOOL:" + dirt_name); defaultFolder.Children.Add(attr); defaultFolder.Children.Add(defaultData); ChunkyDataPTLD primary = null; ChunkyDataPTLD secondary = null; ChunkyDataPTLD trim = null; ChunkyDataPTLD weapon = null; ChunkyDataPTLD eyes = null; ChunkyDataPTLD dirt = null; ChunkyDataPTBD badge = null; ChunkyDataPTBN banner = null; string primaryname = directory + baseFileName + "_Primary.tga"; string secondaryname = directory + baseFileName + "_Secondary.tga"; string trimname = directory + baseFileName + "_Trim.tga"; string weaponname = directory + baseFileName + "_Weapon.tga"; string eyesname = directory + baseFileName + "_Eyes.tga"; string badgename = directory + baseFileName + "_Badge.tga"; string bannername = directory + baseFileName + "_Banner.tga"; //int byteRead = width*height+18;//length of TGA data plus header if (File.Exists(dirt_name)) { CompilationEvent("Reading " + baseFileName + "_Dirt.tga"); file = new FileInfo(dirt_name); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); dirt = ChunkyDataPTLD.CreateFromTGA(PTLD_Layers.Dirt, 1, "", data); } else { throw new RelicTools.Exceptions.FileNotFoundException("WTP Files must contain a dirt layer"); } data = new byte[8]; data[0] = (byte)(width); data[1] = (byte)(width >> 8); data[2] = (byte)(width >> 16); data[3] = (byte)(width >> 24); data[4] = (byte)(height); data[5] = (byte)(height >> 8); data[6] = (byte)(height >> 16); data[7] = (byte)(height >> 24); ChunkyData info = new ChunkyDataUnknown("INFO", 1, "", data); if (File.Exists(primaryname)) { CompilationEvent("Reading " + baseFileName + "_Primary.tga"); file = new FileInfo(primaryname); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); primary = ChunkyDataPTLD.CreateFromTGA(PTLD_Layers.Primary, 1, "", data); if (primary == null) { CompilationEvent("Skipped " + baseFileName + "_Primary.tga - no team colour data"); } } if (File.Exists(secondaryname)) { CompilationEvent("Reading " + baseFileName + "_Secondary.tga"); file = new FileInfo(secondaryname); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); secondary = ChunkyDataPTLD.CreateFromTGA(PTLD_Layers.Secondary, 1, "", data); if (secondary == null) { CompilationEvent("Skipped " + baseFileName + "_Secondary.tga - no team colour data"); } } if (File.Exists(trimname)) { CompilationEvent("Reading " + baseFileName + "_Trim.tga"); file = new FileInfo(trimname); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); trim = ChunkyDataPTLD.CreateFromTGA(PTLD_Layers.Trim, 1, "", data); if (trim == null) { CompilationEvent("Skipped " + baseFileName + "_Trim.tga - no team colour data"); } } if (File.Exists(weaponname)) { CompilationEvent("Reading " + baseFileName + "_Weapon.tga"); file = new FileInfo(weaponname); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); weapon = ChunkyDataPTLD.CreateFromTGA(PTLD_Layers.Weapon, 1, "", data); if (weapon == null) { CompilationEvent("Skipped " + baseFileName + "_Weapon.tga - no team colour data"); } } if (File.Exists(eyesname)) { CompilationEvent("Reading " + baseFileName + "_Eyes.tga"); file = new FileInfo(eyesname); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); eyes = ChunkyDataPTLD.CreateFromTGA(PTLD_Layers.Eyes, 1, "", data); if (eyes == null) { CompilationEvent("Skipped " + baseFileName + "_Eyes.tga - no team colour data"); } } if (File.Exists(badgename)) { CompilationEvent("Reading " + baseFileName + "_Badge.tga"); file = new FileInfo(badgename); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); badge = ChunkyDataPTBD.CreateFromTGA(1, "", data); } if (File.Exists(bannername)) { CompilationEvent("Reading " + baseFileName + "_Banner.tga"); file = new FileInfo(bannername); fs = file.OpenRead(); br = new BinaryReader(fs); br.BaseStream.Seek(0, SeekOrigin.Begin); data = br.ReadBytes((int)br.BaseStream.Length); br.Close(); banner = ChunkyDataPTBN.CreateFromTGA(1, "", data); } if (badge != null && banner != null) { if (((badge.Pos_x <= banner.Pos_x && (badge.Pos_x + badge.Width) >= banner.Pos_x) || (badge.Pos_x <= (banner.Pos_x + banner.Width) && (badge.Pos_x + badge.Width) >= (banner.Pos_x + banner.Width))) && ((badge.Pos_y <= banner.Pos_y && (badge.Pos_y + badge.Height) >= banner.Pos_y) || (badge.Pos_y <= (banner.Pos_y + banner.Height) && (badge.Pos_y + badge.Height) >= (banner.Pos_y + banner.Height)))) { throw new InvalidFileException("Badge and banner position overlap"); } } CompilationEvent("Compiling WTP File"); ChunkyFolder tpat = new ChunkyFolder("TPAT", 3, skinName); tpat.Children.Add(info); tpat.Children.Add(primary); tpat.Children.Add(secondary); tpat.Children.Add(trim); tpat.Children.Add(weapon); tpat.Children.Add(eyes); tpat.Children.Add(dirt); tpat.Children.Add(defaultFolder); tpat.Children.Add(banner); tpat.Children.Add(badge); return(new WTPFile(baseFileName + ".wtp", tpat)); //RelicChunkyFile.SaveChunky(directory+baseFileName+".wtp", tpat.GetBytes()); }
public byte[] CreateCompositeTGABytes(LayerCollection colours, string badgePath, string bannerPath) { if (colours[PTLD_Layers.Dirt].Length != 3) { throw new InvalidOperationException("LayerCollection 'colours' must contain RGB colour data in a 3-byte array"); } FileInfo file = null; BinaryReader br = null; byte[] badge = new byte[64 * 64 * 4]; byte[] banner = new byte[64 * 96 * 4]; byte[] temp; CompilationEvent("Loading badge"); if (File.Exists(badgePath)) { file = new FileInfo(badgePath); br = new BinaryReader(file.OpenRead()); temp = br.ReadBytes((int)file.Length); br.Close(); if ((temp[12] + (temp[13] << 8)) != 64 || (temp[14] + (temp[15] << 8)) != 64) { CompilationEvent("Invalid badge image - badge must be a 64x64 pixel 24/32-bit TGA image", true); } else if (!((temp[16] == 32 || temp[16] == 24) && temp[2] == 2)) { CompilationEvent("Invalid badge image - badge must be a 64x64 pixel 24/32-bit TGA image", true); } else { Buffer.BlockCopy(ImageConverter.TGAto32bitTGA(temp), 18, badge, 0, badge.Length); } } else { CompilationEvent("Invalid badge path - file must exist. Using blank badge.", true); } CompilationEvent("Loading banner"); if (File.Exists(bannerPath)) { file = new FileInfo(bannerPath); br = new BinaryReader(file.OpenRead()); temp = br.ReadBytes((int)file.Length); br.Close(); if ((temp[12] + (temp[13] << 8)) != 64 || (temp[14] + (temp[15] << 8)) != 96) { CompilationEvent("Invalid banner image - banner must be a 64x96 pixel 24/32-bit TGA image", true); } else if (!((temp[16] == 32 || temp[16] == 24) && temp[2] == 2)) { CompilationEvent("Invalid banner image - banner must be a 64x64 pixel 24/32-bit TGA image", true); } else { Buffer.BlockCopy(ImageConverter.TGAto32bitTGA(temp), 18, banner, 0, banner.Length); } } else { CompilationEvent("Invalid banner path - file must exist. Using blank badge.", true); } ChunkyFolder root = (ChunkyFolder)this.ChunkyStructures[0].RootChunks[0]; ChunkyChunk chunk = null; ChunkyDataPTLD ptld = null; ChunkyDataPTBN bannerLayer = null; ChunkyDataPTBD badgeLayer = null; ChunkyDataINFOTPAT info = (ChunkyDataINFOTPAT)root.Children[0]; LayerCollection layers = new LayerCollection(info.Width * info.Height); byte[] mainImage = new byte[info.Width * info.Height]; int badge_bottom = int.MaxValue; int badge_top = int.MaxValue; int badge_left = int.MaxValue; int badge_right = int.MaxValue; int banner_bottom = int.MaxValue; int banner_top = int.MaxValue; int banner_left = int.MaxValue; int banner_right = int.MaxValue; CompilationEvent("Loading colour layers"); for (int i = 0; i < root.Children.Count; i++) { chunk = root.Children[i]; if (chunk is ChunkyDataPTLD) { ptld = (ChunkyDataPTLD)root.Children[i]; layers[(int)ptld.Layer] = ptld.GetColourBytes(); } else if (chunk is ChunkyDataPTBD) { badgeLayer = (ChunkyDataPTBD)chunk; badge_bottom = (int)badgeLayer.Pos_y; badge_top = badge_bottom + (int)badgeLayer.Height; badge_left = (int)badgeLayer.Pos_x; badge_right = badge_left + (int)badgeLayer.Width; } else if (chunk is ChunkyDataPTBN) { bannerLayer = (ChunkyDataPTBN)chunk; banner_bottom = (int)bannerLayer.Pos_y; banner_top = banner_bottom + (int)bannerLayer.Height; banner_left = (int)bannerLayer.Pos_x; banner_right = banner_left + (int)bannerLayer.Width; } else if (chunk is ChunkyFolder) { mainImage = ((ChunkyData)((ChunkyFolder)chunk).Children[1]).GetDataBytes(); } } int bytePos = 0; int bytePos32bit = 0; int bytePosBadge = 0; int bytePosBanner = 0; byte[] badgeByte; byte[] bannerByte; double ratio; double ratio2; double ratio3; double ratioTC; double tempByte = 0; double extra = 0; int badge_width = 0; if (badgeLayer != null) { badge_width = (int)badgeLayer.Width; } int banner_width = 0; if (bannerLayer != null) { banner_width = (int)bannerLayer.Width; } CompilationEvent("Compiling TGA"); for (int i = 0; i < info.Height; i++) { for (int j = 0; j < info.Width; j++) { bytePos = (i * info.Width) + j; bytePos32bit = bytePos * 4; ratio = layers[PTLD_Layers.Dirt][bytePos] / 255.0; if (badge_left <= j && badge_right > j && badge_bottom <= i && badge_top > i) { bytePosBadge = ((i - badge_bottom) * badge_width + (j - badge_left)) * 4; ratio2 = (badge[bytePosBadge + 3] / 255.0); badgeByte = new byte[] { badge[bytePosBadge], badge[bytePosBadge + 1], badge[bytePosBadge + 2] }; } else { ratio2 = 0; badgeByte = new byte[3]; } if (banner_left <= j && banner_right > j && banner_bottom <= i && banner_top > i) { bytePosBanner = ((i - banner_bottom) * banner_width + (j - banner_left)) * 4; ratio3 = (banner[bytePosBanner + 3] / 255.0); bannerByte = new byte[] { banner[bytePosBanner], banner[bytePosBanner + 1], banner[bytePosBanner + 2] }; } else { ratio3 = 0; bannerByte = new byte[3]; } ratioTC = 1 - ratio; ratio2 = ratioTC * ratio2; ratio3 = ratioTC * ratio3; ratioTC = (ratioTC - ratio2 - ratio3) * 2; extra = 0; //TGA files run in reverse - little-endian ARGB, which ends up as BGRA in the file //red tempByte = (ratio * mainImage[bytePos32bit + 2]) + (ratioTC) * ((colours[PTLD_Layers.Primary][0] * layers[PTLD_Layers.Primary][bytePos] / 255.0) + (colours[PTLD_Layers.Secondary][0] * layers[PTLD_Layers.Secondary][bytePos] / 255.0) + (colours[PTLD_Layers.Weapon][0] * layers[PTLD_Layers.Weapon][bytePos] / 255.0) + (colours[PTLD_Layers.Trim][0] * layers[PTLD_Layers.Trim][bytePos] / 255.0) + (colours[PTLD_Layers.Eyes][0] * layers[PTLD_Layers.Eyes][bytePos] / 255.0)) + ratio2 * badgeByte[2] + ratio3 * bannerByte[2]; if (tempByte > byte.MaxValue) { //CompilationEvent("Colour overflow at X:"+j.ToString()+", Y:"+i.ToString()+". Colour will show as Magenta or other bright colour with some colour schemes.", true); mainImage[bytePos32bit + 2] = byte.MaxValue; extra = (tempByte - byte.MaxValue); } else { mainImage[bytePos32bit + 2] = (byte)tempByte; } //green tempByte = (ratio * mainImage[bytePos32bit + 1]) + (ratioTC) * ((colours[PTLD_Layers.Primary][1] * layers[PTLD_Layers.Primary][bytePos] / 255.0) + (colours[PTLD_Layers.Secondary][1] * layers[PTLD_Layers.Secondary][bytePos] / 255.0) + (colours[PTLD_Layers.Weapon][1] * layers[PTLD_Layers.Weapon][bytePos] / 255.0) + (colours[PTLD_Layers.Trim][1] * layers[PTLD_Layers.Trim][bytePos] / 255.0) + (colours[PTLD_Layers.Eyes][1] * layers[PTLD_Layers.Eyes][bytePos] / 255.0)) + extra + ratio2 * badgeByte[1] + ratio3 * bannerByte[1]; if (tempByte > byte.MaxValue) { //CompilationEvent("Colour overflow at X:"+j.ToString()+", Y:"+i.ToString()+". Colour will show as Magenta or other bright colour with some colour schemes.", true); mainImage[bytePos32bit + 1] = byte.MaxValue; extra = extra + tempByte - byte.MaxValue; tempByte = mainImage[bytePos32bit + 2] + extra; if (tempByte > byte.MaxValue) { tempByte = byte.MaxValue; } mainImage[bytePos32bit + 2] = (byte)tempByte; } else { mainImage[bytePos32bit + 1] = (byte)tempByte; } //blue tempByte = (ratio * mainImage[bytePos32bit]) + (ratioTC) * ((colours[PTLD_Layers.Primary][2] * layers[PTLD_Layers.Primary][bytePos] / 255.0) + (colours[PTLD_Layers.Secondary][2] * layers[PTLD_Layers.Secondary][bytePos] / 255.0) + (colours[PTLD_Layers.Weapon][2] * layers[PTLD_Layers.Weapon][bytePos] / 255.0) + (colours[PTLD_Layers.Trim][2] * layers[PTLD_Layers.Trim][bytePos] / 255.0) + (colours[PTLD_Layers.Eyes][2] * layers[PTLD_Layers.Eyes][bytePos] / 255.0)) + extra + ratio2 * badgeByte[0] + ratio3 * bannerByte[0]; if (tempByte > byte.MaxValue) { //CompilationEvent("Colour overflow at X:"+j.ToString()+", Y:"+i.ToString()+". Colour will show as Magenta or other bright colour with some colour schemes.", true); mainImage[bytePos32bit] = byte.MaxValue; extra = extra + tempByte - byte.MaxValue; tempByte = mainImage[bytePos32bit + 2] + extra; if (tempByte > byte.MaxValue) { tempByte = byte.MaxValue; } mainImage[bytePos32bit + 2] = (byte)tempByte; tempByte = mainImage[bytePos32bit + 1] + extra; if (tempByte > byte.MaxValue) { tempByte = byte.MaxValue; } mainImage[bytePos32bit + 1] = (byte)tempByte; } else { mainImage[bytePos32bit] = (byte)tempByte; } } } return(mainImage); }
public WTPFile(string filename, ChunkyFolder folder) : this(filename, new ChunkyStructureCollection(new RelicChunkyStructure(folder))) { }
public static RSHFile Create(string[] filepaths, string mainfilepath) { if (filepaths.Length != 6) { throw new InvalidOperationException("RSH file must contain six file path entries"); } string baseFileName = mainfilepath.Substring(mainfilepath.LastIndexOf(Path.DirectorySeparatorChar) + 1); string baseFileNameLower = baseFileName.ToLower(); string directory = ""; if (mainfilepath.IndexOf(Path.DirectorySeparatorChar) != -1) { directory = mainfilepath.Substring(0, mainfilepath.LastIndexOf(Path.DirectorySeparatorChar)) + Path.DirectorySeparatorChar; } if (baseFileNameLower.EndsWith(".dds")) { baseFileName = baseFileName.Substring(0, baseFileName.Length - 4); } else { throw new InvalidFileException("File specified cannot be converted to a RSH file"); } string texturePath = ""; DirectoryInfo dir = new DirectoryInfo(directory); while (dir.Parent != null) { texturePath = dir.Name + "/" + texturePath; if (dir.Name.ToLower() != "art") { dir = dir.Parent; } else { break; } } if (dir.Parent == null) { throw new InvalidFileException("RSH Files must be built within the 'data\\art' path to ensure correct WTP loading"); } ChunkyDataDATA defaultData = null; ChunkyData attr = null; byte [] data; int width = 0; int height = 0; int mipmaps = 0; int size = 0; byte type; byte byte1; FileInfo file; BinaryReader br; ChunkyFolder defaultFolder; ChunkyData head; ChunkyFolder txtr; string filename; string mainTexturePath = texturePath + baseFileName; string[] texturePaths = new string[filepaths.Length]; int layers = 0; if (filepaths[1] != "" && filepaths[1] != null && filepaths[2] != "" && filepaths[2] != null) { layers = (int)ShaderLayers.SpecMap; } if (filepaths[3] != "" && filepaths[3] != null) { layers += (int)ShaderLayers.SelfIllum; } if (filepaths[4] != "" && filepaths[4] != null) { layers += (int)ShaderLayers.Opacity; } ChunkyFolder shrf = new ChunkyFolder("SHRF", 1, mainTexturePath); CompilationEvent("Compiling RSH Texture..."); for (int i = 0; i < filepaths.Length; i++) { if (filepaths[i] == "" || filepaths[i] == null) { continue; } filename = filepaths[i].Substring(filepaths[i].LastIndexOf(Path.DirectorySeparatorChar) + 1); filename = filename.Substring(0, filename.Length - 4); if (File.Exists(filepaths[i])) { CompilationEvent("Reading " + filename + ".dds"); file = new FileInfo(directory + filename + ".dds"); 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(); size = br.ReadInt32(); br.BaseStream.Seek(4, SeekOrigin.Current); mipmaps = br.ReadInt32(); br.BaseStream.Seek(87, SeekOrigin.Begin); type = br.ReadByte(); br.Close(); if ((char)type == '1') { type = 0x8; byte1 = 0x5; } else if ((char)type == '3') { type = 0xA; byte1 = 0x6; } else if ((char)type == '5') { type = 0xB; byte1 = 0x7; } else { throw new RelicTools.Exceptions.FileNotFoundException("RSH files must be made from DXT1, DXT3 or DXT5 DDS files"); } 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("RSH files must be made from a DDS file"); } defaultFolder = new ChunkyFolder("IMAG", 1, ""); defaultFolder.Children.Add(attr); defaultFolder.Children.Add(defaultData); head = new ChunkyDataUnknown("HEAD", 1, "", new byte[] { byte1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }); texturePaths[i] = texturePath + filename; txtr = new ChunkyFolder("TXTR", 1, texturePath + filename); txtr.Children.Add(head); txtr.Children.Add(defaultFolder); shrf.Children.Add(txtr); } CompilationEvent("Compiling Texture Shaders"); ChunkyDataINFO info = new ChunkyDataINFOGeneric(1, "", new byte[] { 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, (byte)((layers <= 1)?0xcc:0xcd), 0xcc, 0xcc, 0x3d, 0x01, 0x00, 0x00, 0x00, 0x00 }); data = new byte[156 + mainTexturePath.Length]; data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0x01; data[5] = 0x00; data[6] = 0x00; data[7] = 0x00; if (layers <= 1) { data[8] = 0x96; data[9] = 0x96; data[10] = 0x96; data[11] = 0xff; } else { data[8] = 0x0; data[9] = 0x0; data[10] = 0x0; data[11] = 0xff; } data[12] = (byte)mainTexturePath.Length; data[13] = (byte)(mainTexturePath.Length >> 8); data[14] = (byte)(mainTexturePath.Length >> 16); data[15] = (byte)(mainTexturePath.Length >> 24); System.Text.ASCIIEncoding.ASCII.GetBytes(mainTexturePath).CopyTo(data, 16); byte[] temp = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; temp.CopyTo(data, 16 + mainTexturePath.Length); ChunkyData chan0 = new ChunkyDataUnknown("CHAN", 3, "", data); ChunkyData chan1, chan2, chan3, chan4, chan5; //fill out the defaults if ((layers & (int)ShaderLayers.SpecMap) != (int)ShaderLayers.SpecMap) { //they're not using a spec map data = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)((layers <= 1)?0xe5:0x00), (byte)((layers <= 1)?0xe5:0x00), (byte)((layers <= 1)?0xe5:0x00), 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; chan1 = new ChunkyDataUnknown("CHAN", 3, "", data); data = new byte[] { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; chan2 = new ChunkyDataUnknown("CHAN", 3, "", data); } else { //they are using a spec map data = new byte[156 + texturePaths[1].Length]; data[0] = 0x01; //ID data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0x01; //format - 1 = Texture, 2 = Add, 3 = Blend, 4+ = blank data[5] = 0x00; data[6] = 0x00; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0xff; data[12] = (byte)texturePaths[1].Length; data[13] = (byte)(texturePaths[1].Length >> 8); data[14] = (byte)(texturePaths[1].Length >> 16); data[15] = (byte)(texturePaths[1].Length >> 24); System.Text.ASCIIEncoding.ASCII.GetBytes(texturePaths[1]).CopyTo(data, 16); temp = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; temp.CopyTo(data, 16 + texturePaths[1].Length); chan1 = new ChunkyDataUnknown("CHAN", 3, "", data); data = new byte[156 + texturePaths[2].Length]; data[0] = 0x02; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0x01; data[5] = 0x00; data[6] = 0x00; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0xff; data[12] = (byte)texturePaths[2].Length; data[13] = (byte)(texturePaths[2].Length >> 8); data[14] = (byte)(texturePaths[2].Length >> 16); data[15] = (byte)(texturePaths[2].Length >> 24); System.Text.ASCIIEncoding.ASCII.GetBytes(texturePaths[2]).CopyTo(data, 16); temp = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; temp.CopyTo(data, 16 + texturePaths[2].Length); chan2 = new ChunkyDataUnknown("CHAN", 3, "", data); } if ((layers & (int)ShaderLayers.SelfIllum) != (int)ShaderLayers.SelfIllum) { data = new byte[] { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; } else { data = new byte[156 + texturePaths[3].Length]; data[0] = 0x03; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0x01; data[5] = 0x00; data[6] = 0x00; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0xff; data[12] = (byte)texturePaths[3].Length; data[13] = (byte)(texturePaths[3].Length >> 8); data[14] = (byte)(texturePaths[3].Length >> 16); data[15] = (byte)(texturePaths[3].Length >> 24); System.Text.ASCIIEncoding.ASCII.GetBytes(texturePaths[3]).CopyTo(data, 16); temp = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; temp.CopyTo(data, 16 + texturePaths[3].Length); } chan3 = new ChunkyDataUnknown("CHAN", 3, "", data); if ((layers & (int)ShaderLayers.Opacity) != (int)ShaderLayers.Opacity) { data = new byte[] { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; } else { data = new byte[156 + texturePaths[4].Length]; data[0] = 0x04; data[1] = 0x00; data[2] = 0x00; data[3] = 0x00; data[4] = 0x01; data[5] = 0x00; data[6] = 0x00; data[7] = 0x00; data[8] = 0x00; //0x00; data[9] = 0x00; //0x00; data[10] = 0x00; //0x00; data[11] = 0xff; data[12] = (byte)texturePaths[4].Length; data[13] = (byte)(texturePaths[4].Length >> 8); data[14] = (byte)(texturePaths[4].Length >> 16); data[15] = (byte)(texturePaths[4].Length >> 24); System.Text.ASCIIEncoding.ASCII.GetBytes(texturePaths[4]).CopyTo(data, 16); temp = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; temp.CopyTo(data, 16 + texturePaths[4].Length); } chan4 = new ChunkyDataUnknown("CHAN", 3, "", data); //if (filepaths.Length<6) //{ data = new byte[] { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f }; /*} * else * { * data = new byte[156+texturePaths[1].Length]; * data[0] = 0x05; * data[1] = 0x00; * data[2] = 0x00; * data[3] = 0x00; * data[4] = 0x01; * data[5] = 0x00; * data[6] = 0x00; * data[7] = 0x00; * data[8] = 0x00; * data[9] = 0x00; * data[10] = 0x00; * data[11] = 0xff; * data[12] = (byte)texturePaths[1].Length; * data[13] = (byte)(texturePaths[1].Length>>8); * data[14] = (byte)(texturePaths[1].Length>>16); * data[15] = (byte)(texturePaths[1].Length>>24); * * System.Text.ASCIIEncoding.ASCII.GetBytes(texturePaths[1]).CopyTo(data, 16); * temp = new byte[]{0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f}; * temp.CopyTo(data, 16+texturePaths[1].Length); * }*/ chan5 = new ChunkyDataUnknown("CHAN", 3, "", data); ChunkyFolder shdr = new ChunkyFolder("SHDR", 1, mainTexturePath); shdr.Children.Add(info); shdr.Children.Add(chan0); shdr.Children.Add(chan1); shdr.Children.Add(chan2); shdr.Children.Add(chan3); shdr.Children.Add(chan4); shdr.Children.Add(chan5); CompilationEvent("Compiling RSH File"); shrf.Children.Add(shdr); return(new RSHFile(baseFileName + ".rsh", shrf)); //new ChunkyStructureCollection(new RelicChunkyStructure( //RelicChunkyFile.SaveChunky(directory+baseFileName+".rsh", shrf.GetBytes()); }
public RSHFile(string filename, ChunkyFolder folder) : base(filename, folder) { }
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()); }
public RelicChunkyFile(string name, ChunkyFolder folder) : this(name, new RelicChunkyStructure(folder)) { }
public RelicChunkyStructure(ChunkyFolder chunkyRoot) : this(chunkyRoot, 0, 0, 0) { }