mirror of
				https://github.com/chev2/botw-toolset.git
				synced 2025-10-30 08:12:17 +00:00 
			
		
		
		
	Update TSCB methods
FromBytes replaces ReadFile & uses a byte array instead of filename. GetBytes is renamed to ToBytes.
This commit is contained in:
		
							parent
							
								
									6d6e9f4749
								
							
						
					
					
						commit
						f19f94f459
					
				
					 2 changed files with 132 additions and 139 deletions
				
			
		|  | @ -306,7 +306,7 @@ namespace BOTWToolset.Control | ||||||
| 
 | 
 | ||||||
|                 BOTWConsole.Log("Opening file"); |                 BOTWConsole.Log("Opening file"); | ||||||
| 
 | 
 | ||||||
|                 TSCB t = TSCB.ReadFile(openFileDialog.FileName); |                 TSCB t = TSCB.FromBytes(File.ReadAllBytes(openFileDialog.FileName)); | ||||||
| 
 | 
 | ||||||
|                 // Set the current file location to the chosen file's location |                 // Set the current file location to the chosen file's location | ||||||
|                 fileLocation = openFileDialog.FileName; |                 fileLocation = openFileDialog.FileName; | ||||||
|  | @ -365,7 +365,7 @@ namespace BOTWToolset.Control | ||||||
| 
 | 
 | ||||||
|             if ((bool)saveFileDialog.ShowDialog()) |             if ((bool)saveFileDialog.ShowDialog()) | ||||||
|             { |             { | ||||||
|                 File.WriteAllBytes(saveFileDialog.FileName, TSCB.GetBytes(currentTSCB)); |                 File.WriteAllBytes(saveFileDialog.FileName, TSCB.ToBytes(currentTSCB)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -52,168 +52,161 @@ namespace BOTWToolset.IO.TSCB | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="file">The .tscb file.</param> |         /// <param name="file">The .tscb file.</param> | ||||||
|         /// <returns></returns> |         /// <returns></returns> | ||||||
|         public static TSCB ReadFile(string file) |         public static TSCB FromBytes(byte[] bytes) | ||||||
|         { |         { | ||||||
|             if (File.Exists(file)) |             TSCB t = new TSCB(); | ||||||
|  | 
 | ||||||
|  |             // Use big-endian | ||||||
|  |             using (var r = new BinaryReaderBig(new MemoryStream(bytes))) | ||||||
|             { |             { | ||||||
|                 TSCB t = new TSCB(); |                 // Set header info from file on the new TSCBInfo | ||||||
|  |                 t.Signature = new string(r.ReadChars(4)); | ||||||
|  |                 t.Version = r.ReadByte(); | ||||||
| 
 | 
 | ||||||
|                 // Use big-endian |                 // Skip the 3 extra version bytes | ||||||
|                 using (var r = new BinaryReaderBig(File.Open(file, FileMode.Open))) |                 r.BaseStream.Seek(3, SeekOrigin.Current); | ||||||
|  | 
 | ||||||
|  |                 // Skip 4 bytes of "00 00 00 01" | ||||||
|  |                 r.BaseStream.Seek(4, SeekOrigin.Current); | ||||||
|  | 
 | ||||||
|  |                 t.FileBaseOffset = r.ReadUInt32(); | ||||||
|  |                 t.WorldScale = r.ReadSingle(); | ||||||
|  |                 t.TerrainMaxHeight = r.ReadSingle(); | ||||||
|  |                 t.MaterialInfoLength = r.ReadUInt32(); | ||||||
|  |                 t.AreaArrayLength = r.ReadUInt32(); | ||||||
|  | 
 | ||||||
|  |                 // Skip 8 bytes of padding | ||||||
|  |                 r.Advance(8); | ||||||
|  | 
 | ||||||
|  |                 t.TileSize = r.ReadSingle(); | ||||||
|  | 
 | ||||||
|  |                 // Skip 4 bytes of "00 00 00 08" | ||||||
|  |                 r.Advance(4); | ||||||
|  | 
 | ||||||
|  |                 // Read mat info offsets | ||||||
|  |                 t.MaterialInfoOffsets = r.ReadBytes((int)((t.MaterialInfoLength * 4) + 4)); | ||||||
|  | 
 | ||||||
|  |                 BOTWConsole.Log($"Offset before material iteration: {r.BaseStream.Position}"); | ||||||
|  | 
 | ||||||
|  |                 // Initialize mat info array with provided length | ||||||
|  |                 t.MaterialInfo = new MaterialInfo[t.MaterialInfoLength]; | ||||||
|  | 
 | ||||||
|  |                 // Initialize every mat info, then add to the array | ||||||
|  |                 for (int i = 0; i < t.MaterialInfoLength; i++) | ||||||
|                 { |                 { | ||||||
|                     // Set header info from file on the new TSCBInfo |                     uint index = r.ReadUInt32(); | ||||||
|                     t.Signature = new string(r.ReadChars(4)); |                     float tex_u = r.ReadSingle(); | ||||||
|                     t.Version = r.ReadByte(); |                     float tex_v = r.ReadSingle(); | ||||||
|  |                     float unk_1 = r.ReadSingle(); | ||||||
|  |                     float unk_2 = r.ReadSingle(); | ||||||
| 
 | 
 | ||||||
|                     // Skip the 3 extra version bytes |                     MaterialInfo matInfo = new MaterialInfo(index, tex_u, tex_v, unk_1, unk_2); | ||||||
|                     r.BaseStream.Seek(3, SeekOrigin.Current); |  | ||||||
| 
 | 
 | ||||||
|                     // Skip 4 bytes of "00 00 00 01" |                     t.MaterialInfo[i] = matInfo; | ||||||
|                     r.BaseStream.Seek(4, SeekOrigin.Current); |                 } | ||||||
| 
 | 
 | ||||||
|                     t.FileBaseOffset = r.ReadUInt32(); |                 BOTWConsole.Log($"Offset before area offset iteration: {r.BaseStream.Position}"); | ||||||
|                     t.WorldScale = r.ReadSingle(); |  | ||||||
|                     t.TerrainMaxHeight = r.ReadSingle(); |  | ||||||
|                     t.MaterialInfoLength = r.ReadUInt32(); |  | ||||||
|                     t.AreaArrayLength = r.ReadUInt32(); |  | ||||||
| 
 | 
 | ||||||
|                     // Skip 8 bytes of padding |                 // Read area offsets | ||||||
|                     r.Advance(8); |                 t.AreaArrayOffsets = r.ReadBytes((int)(t.AreaArrayLength * 4)); | ||||||
| 
 | 
 | ||||||
|                     t.TileSize = r.ReadSingle(); |                 BOTWConsole.Log($"Offset before area iteration: {r.BaseStream.Position}"); | ||||||
| 
 | 
 | ||||||
|                     // Skip 4 bytes of "00 00 00 08" |                 t.AreaInfo = new AreaInfo[t.AreaArrayLength]; | ||||||
|                     r.Advance(4); |  | ||||||
| 
 | 
 | ||||||
|                     // Read mat info offsets |                 // Read every area info entry | ||||||
|                     t.MaterialInfoOffsets = r.ReadBytes((int)((t.MaterialInfoLength * 4) + 4)); |                 for (int i = 0; i < t.AreaArrayLength; i++) | ||||||
|  |                 { | ||||||
|  |                     uint offset = (uint)r.BaseStream.Position; | ||||||
| 
 | 
 | ||||||
|                     BOTWConsole.Log($"Offset before material iteration: {r.BaseStream.Position}"); |                     float xpos = r.ReadSingle(); | ||||||
|  |                     float zpos = r.ReadSingle(); | ||||||
|  |                     float area_size = r.ReadSingle(); | ||||||
|  |                     float min_terrain_height = r.ReadSingle(); | ||||||
|  |                     float max_terrain_height = r.ReadSingle(); | ||||||
|  |                     float min_water_height = r.ReadSingle(); | ||||||
|  |                     float max_water_height = r.ReadSingle(); | ||||||
|  |                     uint unk_1 = r.ReadUInt32(); | ||||||
| 
 | 
 | ||||||
|                     // Initialize mat info array with provided length |                     if (unk_1 == 0) | ||||||
|                     t.MaterialInfo = new MaterialInfo[t.MaterialInfoLength]; |                     { // If this unknown is equal to 0, skip the extra byte coming after it | ||||||
|  |                         uint next_val = r.ReadUInt32(); | ||||||
| 
 | 
 | ||||||
|                     // Initialize every mat info, then add to the array |                         if (next_val != 1) // If the next value isn't extra unneeded info | ||||||
|                     for (int i = 0; i < t.MaterialInfoLength; i++) |  | ||||||
|                     { |  | ||||||
|                         uint index = r.ReadUInt32(); |  | ||||||
|                         float tex_u = r.ReadSingle(); |  | ||||||
|                         float tex_v = r.ReadSingle(); |  | ||||||
|                         float unk_1 = r.ReadSingle(); |  | ||||||
|                         float unk_2 = r.ReadSingle(); |  | ||||||
| 
 |  | ||||||
|                         MaterialInfo matInfo = new MaterialInfo(index, tex_u, tex_v, unk_1, unk_2); |  | ||||||
| 
 |  | ||||||
|                         t.MaterialInfo[i] = matInfo; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     BOTWConsole.Log($"Offset before area offset iteration: {r.BaseStream.Position}"); |  | ||||||
| 
 |  | ||||||
|                     // Read area offsets |  | ||||||
|                     t.AreaArrayOffsets = r.ReadBytes((int)(t.AreaArrayLength * 4)); |  | ||||||
| 
 |  | ||||||
|                     BOTWConsole.Log($"Offset before area iteration: {r.BaseStream.Position}"); |  | ||||||
| 
 |  | ||||||
|                     t.AreaInfo = new AreaInfo[t.AreaArrayLength]; |  | ||||||
| 
 |  | ||||||
|                     // Read every area info entry |  | ||||||
|                     for (int i = 0; i < t.AreaArrayLength; i++) |  | ||||||
|                     { |  | ||||||
|                         uint offset = (uint)r.BaseStream.Position; |  | ||||||
| 
 |  | ||||||
|                         float xpos = r.ReadSingle(); |  | ||||||
|                         float zpos = r.ReadSingle(); |  | ||||||
|                         float area_size = r.ReadSingle(); |  | ||||||
|                         float min_terrain_height = r.ReadSingle(); |  | ||||||
|                         float max_terrain_height = r.ReadSingle(); |  | ||||||
|                         float min_water_height = r.ReadSingle(); |  | ||||||
|                         float max_water_height = r.ReadSingle(); |  | ||||||
|                         uint unk_1 = r.ReadUInt32(); |  | ||||||
| 
 |  | ||||||
|                         if (unk_1 == 0) |  | ||||||
|                         { // If this unknown is equal to 0, skip the extra byte coming after it |  | ||||||
|                             uint next_val = r.ReadUInt32(); |  | ||||||
| 
 |  | ||||||
|                             if (next_val != 1) // If the next value isn't extra unneeded info |  | ||||||
|                             { |  | ||||||
|                                 r.Advance(-4); |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         uint file_base = r.ReadUInt32(); |  | ||||||
|                         uint unk_2 = r.ReadUInt32(); |  | ||||||
|                         uint unk_3 = r.ReadUInt32(); |  | ||||||
|                         uint ref_extra = r.ReadUInt32(); |  | ||||||
| 
 |  | ||||||
|                         AreaInfo areaInfo = new AreaInfo |  | ||||||
|                         { |  | ||||||
|                             PositionX = xpos, |  | ||||||
|                             PositionZ = zpos, |  | ||||||
|                             AreaSize = area_size, |  | ||||||
|                             MinTerrainHeight = min_terrain_height, |  | ||||||
|                             MaxTerrainHeight = max_terrain_height, |  | ||||||
|                             MinWaterHeight = min_water_height, |  | ||||||
|                             MaxWaterHeight = max_water_height, |  | ||||||
|                             Unknown1 = unk_1, |  | ||||||
|                             FileBase = file_base, |  | ||||||
|                             Unknown2 = unk_2, |  | ||||||
|                             Unknown3 = unk_3, |  | ||||||
|                             ReferenceExtra = ref_extra, |  | ||||||
|                             Offset = offset |  | ||||||
|                         }; |  | ||||||
| 
 |  | ||||||
|                         areaInfo.ExtraInfoLength = r.ReadUInt32(); //Usually 0, 4, or 8 |  | ||||||
| 
 |  | ||||||
|                         if (ref_extra == 4) |  | ||||||
|                         { |  | ||||||
|                             if (areaInfo.ExtraInfoLength == 8) |  | ||||||
|                             { //Skip the extra "20" after the 8, as well as the extra info |  | ||||||
|                                 areaInfo.HasGrass = true; |  | ||||||
|                                 areaInfo.HasWater = true; |  | ||||||
|                                 r.Advance(36); |  | ||||||
|                             } |  | ||||||
|                             else //If the length is 4 |  | ||||||
|                             { |  | ||||||
|                                 var bytes = r.ReadBytes(16).ToArray(); |  | ||||||
|                                 if (bytes[7] == 0) //If byte 7 equals 0 |  | ||||||
|                                     areaInfo.HasGrass = true; |  | ||||||
|                                 else //Else if the 2nd byte should be anything else (should always be 1) |  | ||||||
|                                     areaInfo.HasWater = true; |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                         else //If the extra info flags aren't set, go back 4 |  | ||||||
|                         { |                         { | ||||||
|                             r.Advance(-4); |                             r.Advance(-4); | ||||||
|                         } |                         } | ||||||
| 
 |  | ||||||
|                         t.AreaInfo[i] = areaInfo; |  | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     BOTWConsole.Log($"Offset after area iteration: {r.BaseStream.Position} (should be {t.FileBaseOffset + 16})"); |                     uint file_base = r.ReadUInt32(); | ||||||
|  |                     uint unk_2 = r.ReadUInt32(); | ||||||
|  |                     uint unk_3 = r.ReadUInt32(); | ||||||
|  |                     uint ref_extra = r.ReadUInt32(); | ||||||
| 
 | 
 | ||||||
|                     //Get the number of filenames by getting how many bytes they take up out of the entire file size |                     AreaInfo areaInfo = new AreaInfo | ||||||
|                     var filenames_count = (r.BaseStream.Length - (t.FileBaseOffset + 16)) / 12; |  | ||||||
| 
 |  | ||||||
|                     BOTWConsole.Log($"Filename count: {filenames_count} (should be {t.AreaArrayLength})"); |  | ||||||
| 
 |  | ||||||
|                     t.FileNames = new string[filenames_count]; |  | ||||||
| 
 |  | ||||||
|                     r.BaseStream.Seek(t.FileBaseOffset + 16, SeekOrigin.Begin); // TODO: change this to 'current' later, or maybe even remove |  | ||||||
| 
 |  | ||||||
|                     for (int i = 0; i < filenames_count; i++) |  | ||||||
|                     { |                     { | ||||||
|                         string filename = new string(r.ReadChars(12)); |                         PositionX = xpos, | ||||||
|  |                         PositionZ = zpos, | ||||||
|  |                         AreaSize = area_size, | ||||||
|  |                         MinTerrainHeight = min_terrain_height, | ||||||
|  |                         MaxTerrainHeight = max_terrain_height, | ||||||
|  |                         MinWaterHeight = min_water_height, | ||||||
|  |                         MaxWaterHeight = max_water_height, | ||||||
|  |                         Unknown1 = unk_1, | ||||||
|  |                         FileBase = file_base, | ||||||
|  |                         Unknown2 = unk_2, | ||||||
|  |                         Unknown3 = unk_3, | ||||||
|  |                         ReferenceExtra = ref_extra, | ||||||
|  |                         Offset = offset | ||||||
|  |                     }; | ||||||
| 
 | 
 | ||||||
|                         t.FileNames[i] = filename; |                     areaInfo.ExtraInfoLength = r.ReadUInt32(); //Usually 0, 4, or 8 | ||||||
|  | 
 | ||||||
|  |                     if (ref_extra == 4) | ||||||
|  |                     { | ||||||
|  |                         if (areaInfo.ExtraInfoLength == 8) | ||||||
|  |                         { //Skip the extra "20" after the 8, as well as the extra info | ||||||
|  |                             areaInfo.HasGrass = true; | ||||||
|  |                             areaInfo.HasWater = true; | ||||||
|  |                             r.Advance(36); | ||||||
|  |                         } | ||||||
|  |                         else //If the length is 4 | ||||||
|  |                         { | ||||||
|  |                             var areabytes = r.ReadBytes(16).ToArray(); | ||||||
|  |                             if (areabytes[7] == 0) //If byte 7 equals 0 | ||||||
|  |                                 areaInfo.HasGrass = true; | ||||||
|  |                             else //Else if the 2nd byte should be anything else (should always be 1) | ||||||
|  |                                 areaInfo.HasWater = true; | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|  |                     else //If the extra info flags aren't set, go back 4 | ||||||
|  |                     { | ||||||
|  |                         r.Advance(-4); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     t.AreaInfo[i] = areaInfo; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 return t; |                 BOTWConsole.Log($"Offset after area iteration: {r.BaseStream.Position} (should be {t.FileBaseOffset + 16})"); | ||||||
|             } | 
 | ||||||
|             else |                 //Get the number of filenames by getting how many bytes they take up out of the entire file size | ||||||
|             { |                 var filenames_count = (r.BaseStream.Length - (t.FileBaseOffset + 16)) / 12; | ||||||
|                 throw new FileNotFoundException("Cannot find .tscb file to read."); | 
 | ||||||
|  |                 BOTWConsole.Log($"Filename count: {filenames_count} (should be {t.AreaArrayLength})"); | ||||||
|  | 
 | ||||||
|  |                 t.FileNames = new string[filenames_count]; | ||||||
|  | 
 | ||||||
|  |                 r.BaseStream.Seek(t.FileBaseOffset + 16, SeekOrigin.Begin); // TODO: change this to 'current' later, or maybe even remove | ||||||
|  | 
 | ||||||
|  |                 for (int i = 0; i < filenames_count; i++) | ||||||
|  |                 { | ||||||
|  |                     string filename = new string(r.ReadChars(12)); | ||||||
|  | 
 | ||||||
|  |                     t.FileNames[i] = filename; | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             return t; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|  | @ -221,7 +214,7 @@ namespace BOTWToolset.IO.TSCB | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         /// <param name="tscb"><see cref="TSCB"/> that contains data to write.</param> |         /// <param name="tscb"><see cref="TSCB"/> that contains data to write.</param> | ||||||
|         /// <returns>Byte array containing the TSCB data.</returns> |         /// <returns>Byte array containing the TSCB data.</returns> | ||||||
|         public static byte[] GetBytes(TSCB tscb) |         public static byte[] ToBytes(TSCB tscb) | ||||||
|         { |         { | ||||||
|             List<byte> b = new List<byte>(); |             List<byte> b = new List<byte>(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Chev
						Chev