0
|
1 // This file is a part of the Relic Tools and is copyright 2006-2018 IBBoard.
|
|
2 //
|
|
3 // 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.
|
|
4 using System;
|
|
5 using System.IO;
|
|
6 using IBBoard.Relic.RelicTools.Exceptions;
|
|
7 using IBBoard.Relic.RelicTools.Collections;
|
|
8
|
|
9
|
|
10 namespace IBBoard.Relic.RelicTools
|
|
11 {
|
|
12 /// <summary>
|
|
13 /// Summary description for WTPFile.
|
|
14 /// </summary>
|
|
15 public class RTXFile:RelicChunkyFile
|
|
16 {
|
|
17 int width = 0;
|
|
18 int height = 0;
|
|
19 int id = 0;
|
|
20
|
|
21 public RTXFile(string filename, ChunkyFolder folder)
|
|
22 :this(filename, new ChunkyStructureCollection(new RelicChunkyStructure(folder))){}
|
|
23
|
|
24 public RTXFile(string filename, ChunkyCollection col)
|
|
25 :this(filename, new ChunkyStructureCollection(new RelicChunkyStructure(col))){}
|
|
26
|
|
27 public RTXFile(string filename, ChunkyStructureCollection col): base(filename, col)
|
|
28 {
|
|
29 int lastIndex = filename.LastIndexOf('_');
|
|
30
|
|
31 if (lastIndex == -1 || filename.IndexOf('_')==lastIndex)
|
|
32 {
|
|
33 throw new InvalidFileException("RTX file name specified must end with a skin name and number e.g. _default_0.rtx");
|
|
34 }
|
|
35
|
|
36 try
|
|
37 {
|
|
38 int dot = filename.LastIndexOf('.');
|
|
39 lastIndex++;
|
|
40 id = int.Parse(filename.Substring(lastIndex, dot - lastIndex));
|
|
41 }
|
|
42 catch(FormatException)
|
|
43 {
|
|
44 throw new InvalidFileException("RTX file name specified must end with a skin name and number e.g. _default_0.rtx");
|
|
45 }
|
|
46
|
|
47 FindAttributes((ChunkyFolder)this.ChunkyStructures[0].RootChunks[0]);
|
|
48 }
|
|
49
|
|
50 private void FindAttributes(ChunkyFolder folder)
|
|
51 {
|
|
52 int children = folder.Children.Count;
|
|
53 ChunkyChunk chunk = null;
|
|
54 ChunkyDataATTR attr = null;
|
|
55
|
|
56 for (int i = 0; i<children; i++)
|
|
57 {
|
|
58 chunk = folder.Children[i];
|
|
59
|
|
60 if (chunk is ChunkyDataATTR)
|
|
61 {
|
|
62 attr = (ChunkyDataATTR)chunk;
|
|
63 width = attr.Width;
|
|
64 height = attr.Height;
|
|
65 break;
|
|
66 }
|
|
67 else if (chunk is ChunkyFolder)
|
|
68 {
|
|
69 FindAttributes((ChunkyFolder)chunk);
|
|
70 }
|
|
71 }
|
|
72 }
|
|
73
|
|
74 public void SaveParts(DirectoryInfo destination)
|
|
75 {
|
|
76 string filenamebase = filename.Substring(0, filename.LastIndexOf('.'));
|
|
77
|
|
78 saveFolder((ChunkyFolder)this.ChunkyStructures[0].RootChunks[0], destination, filenamebase);
|
|
79 }
|
|
80
|
|
81 private void saveFolder(ChunkyFolder folder, DirectoryInfo destination, string filenamebase)
|
|
82 {
|
|
83 int children = folder.Children.Count;
|
|
84 ChunkyChunk chunk = null;
|
|
85
|
|
86 for (int i = 0; i<children; i++)
|
|
87 {
|
|
88 chunk = folder.Children[i];
|
|
89
|
|
90 if (chunk is ChunkyFolder)
|
|
91 {
|
|
92 this.saveFolder((ChunkyFolder)chunk, destination, filenamebase);
|
|
93 }
|
|
94 /*else if (chunk is ChunkyDataATTR)
|
|
95 {
|
|
96 attr = (ChunkyDataATTR)chunk;
|
|
97 imagetype = attr.ImageType;
|
|
98 mipmaps = attr.MipMaps;
|
|
99 }*/
|
|
100 else if (chunk is ChunkyDataDATAIMAG)
|
|
101 {
|
|
102 ((ChunkyDataDATAIMAG)chunk).Save(destination, filenamebase);
|
|
103 }
|
|
104 }
|
|
105 }
|
|
106
|
|
107 public static RTXFile Create(string filepath)
|
|
108 {
|
|
109 string baseFileName = filepath.Substring(filepath.LastIndexOf(Path.DirectorySeparatorChar)+1);
|
|
110 string baseFileNameLower = baseFileName.ToLower();
|
|
111
|
|
112 string directory = "";
|
|
113
|
|
114 if (filepath.IndexOf(Path.DirectorySeparatorChar)!=-1)
|
|
115 {
|
|
116 directory = filepath.Substring(0, filepath.LastIndexOf(Path.DirectorySeparatorChar))+Path.DirectorySeparatorChar;
|
|
117 }
|
|
118
|
|
119 if(baseFileNameLower.EndsWith(".dds"))
|
|
120 {
|
|
121 baseFileName = baseFileName.Substring(0, baseFileName.Length-4);
|
|
122 }
|
|
123 else
|
|
124 {
|
|
125 throw new InvalidFileException("File path specified is not valid for a RTX file");
|
|
126 }
|
|
127
|
|
128 string unit_name = "";
|
|
129 int lastUnderscore = baseFileName.LastIndexOf('_');
|
|
130
|
|
131 if (lastUnderscore!=-1)
|
|
132 {
|
|
133 unit_name = baseFileName.Substring(0, lastUnderscore);//trim the number
|
|
134
|
|
135 try
|
|
136 {
|
|
137 int id = int.Parse(baseFileName.Substring(lastUnderscore+1));
|
|
138 }
|
|
139 catch
|
|
140 {
|
|
141 throw new InvalidFileException("DDS file name specified must end with a number to identify RTX e.g. _default_0.dds");
|
|
142 }
|
|
143
|
|
144 lastUnderscore = unit_name.LastIndexOf('_');
|
|
145 if (lastUnderscore!=-1)
|
|
146 {
|
|
147 unit_name = unit_name.Substring(0, lastUnderscore);
|
|
148 }
|
|
149 else
|
|
150 {
|
|
151 throw new InvalidFileException("DDS file name specified must end with a skin name followed by a number e.g. _default_0.dds");
|
|
152 }
|
|
153 }
|
|
154 else
|
|
155 {
|
|
156 throw new InvalidFileException("DDS file name specified must end with a skin name and number e.g. _default_0.dds");
|
|
157 }
|
|
158
|
|
159 ChunkyDataDATA defaultData = null;
|
|
160 ChunkyData attr = null;
|
|
161 byte [] data;
|
|
162
|
|
163 int width = 0;
|
|
164 int height = 0;
|
|
165 int mipmaps = 0;
|
|
166
|
|
167 if (File.Exists(directory+baseFileName+".dds"))
|
|
168 {
|
|
169 CompilationEvent("Reading "+baseFileName+".dds");
|
|
170 FileInfo file = new FileInfo(directory+baseFileName+".dds");
|
|
171 BinaryReader br = new BinaryReader(file.OpenRead());
|
|
172 br.BaseStream.Seek(0, SeekOrigin.Begin);
|
|
173 data = br.ReadBytes((int)file.Length);
|
|
174
|
|
175 defaultData = ChunkyDataDATAIMAG.CreateFromDDS(2, "", data);
|
|
176
|
|
177 br.BaseStream.Seek(12,SeekOrigin.Begin);
|
|
178 height = br.ReadInt32();
|
|
179 width = br.ReadInt32();
|
|
180 int size = br.ReadInt32();
|
|
181 br.BaseStream.Seek(4, SeekOrigin.Current);
|
|
182 mipmaps = br.ReadInt32();
|
|
183 br.Close();
|
|
184
|
|
185 byte type = 0x8;
|
|
186
|
|
187 if (size==width*height)
|
|
188 {
|
|
189 type = 0xb;
|
|
190 }
|
|
191
|
|
192 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)};
|
|
193 attr = new ChunkyDataUnknown("ATTR", 2, "", data);
|
|
194 }
|
|
195 else
|
|
196 {
|
|
197 throw new RelicTools.Exceptions.FileNotFoundException("RTX files must be made from a DDS file");
|
|
198 }
|
|
199
|
|
200 ChunkyFolder defaultFolder = new ChunkyFolder("IMAG", 1, "");
|
|
201
|
|
202 defaultFolder.Children.Add(attr);
|
|
203 defaultFolder.Children.Add(defaultData);
|
|
204
|
|
205 ChunkyData head = new ChunkyDataUnknown("HEAD", 1, "", new byte[]{0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00});
|
|
206
|
|
207
|
|
208 CompilationEvent("Compiling RTX File");
|
|
209 ChunkyFolder txtr = new ChunkyFolder("TXTR", 1, unit_name);
|
|
210 txtr.Children.Add(head);
|
|
211 txtr.Children.Add(defaultFolder);
|
|
212 return new RTXFile(baseFileName+".rtx", txtr);
|
|
213 //RelicChunkyFile.SaveChunky(directory+baseFileName+".rtx", txtr.GetBytes());
|
|
214 }
|
|
215 }
|
|
216 }
|