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"); | ||||
| 
 | ||||
|                 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 | ||||
|                 fileLocation = openFileDialog.FileName; | ||||
|  | @ -365,7 +365,7 @@ namespace BOTWToolset.Control | |||
| 
 | ||||
|             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> | ||||
|         /// <param name="file">The .tscb file.</param> | ||||
|         /// <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 | ||||
|                 using (var r = new BinaryReaderBig(File.Open(file, FileMode.Open))) | ||||
|                 // Skip the 3 extra version bytes | ||||
|                 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 | ||||
|                     t.Signature = new string(r.ReadChars(4)); | ||||
|                     t.Version = r.ReadByte(); | ||||
|                     uint index = r.ReadUInt32(); | ||||
|                     float tex_u = r.ReadSingle(); | ||||
|                     float tex_v = r.ReadSingle(); | ||||
|                     float unk_1 = r.ReadSingle(); | ||||
|                     float unk_2 = r.ReadSingle(); | ||||
| 
 | ||||
|                     // Skip the 3 extra version bytes | ||||
|                     r.BaseStream.Seek(3, SeekOrigin.Current); | ||||
|                     MaterialInfo matInfo = new MaterialInfo(index, tex_u, tex_v, unk_1, unk_2); | ||||
| 
 | ||||
|                     // Skip 4 bytes of "00 00 00 01" | ||||
|                     r.BaseStream.Seek(4, SeekOrigin.Current); | ||||
|                     t.MaterialInfo[i] = matInfo; | ||||
|                 } | ||||
| 
 | ||||
|                     t.FileBaseOffset = r.ReadUInt32(); | ||||
|                     t.WorldScale = r.ReadSingle(); | ||||
|                     t.TerrainMaxHeight = r.ReadSingle(); | ||||
|                     t.MaterialInfoLength = r.ReadUInt32(); | ||||
|                     t.AreaArrayLength = r.ReadUInt32(); | ||||
|                 BOTWConsole.Log($"Offset before area offset iteration: {r.BaseStream.Position}"); | ||||
| 
 | ||||
|                     // Skip 8 bytes of padding | ||||
|                     r.Advance(8); | ||||
|                 // Read area offsets | ||||
|                 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" | ||||
|                     r.Advance(4); | ||||
|                 t.AreaInfo = new AreaInfo[t.AreaArrayLength]; | ||||
| 
 | ||||
|                     // Read mat info offsets | ||||
|                     t.MaterialInfoOffsets = r.ReadBytes((int)((t.MaterialInfoLength * 4) + 4)); | ||||
|                 // Read every area info entry | ||||
|                 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 | ||||
|                     t.MaterialInfo = new MaterialInfo[t.MaterialInfoLength]; | ||||
|                     if (unk_1 == 0) | ||||
|                     { // 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 | ||||
|                     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 | ||||
|                         if (next_val != 1) // If the next value isn't extra unneeded info | ||||
|                         { | ||||
|                             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 | ||||
|                     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++) | ||||
|                     AreaInfo areaInfo = new AreaInfo | ||||
|                     { | ||||
|                         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; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 throw new FileNotFoundException("Cannot find .tscb file to read."); | ||||
|                 BOTWConsole.Log($"Offset after area iteration: {r.BaseStream.Position} (should be {t.FileBaseOffset + 16})"); | ||||
| 
 | ||||
|                 //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; | ||||
| 
 | ||||
|                 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> | ||||
|  | @ -221,7 +214,7 @@ namespace BOTWToolset.IO.TSCB | |||
|         /// </summary> | ||||
|         /// <param name="tscb"><see cref="TSCB"/> that contains data to write.</param> | ||||
|         /// <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>(); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Chev
						Chev