private void HOExtract() { HaloOnlineLib.HaloTag scnr = null; listHOScenarios.Invoke(new MethodInvoker(delegate { scnr = HaloOnlineTags.Where(t => t.Class.ToString() == "scnr").ElementAt(listHOScenarios.SelectedIndex); })); using (var tagsStream = new FileStream(Path.Combine(Properties.Settings.Default.HOMapFolder, "tags.dat"), FileMode.Open, FileAccess.Read, FileShare.Read)) { var tagContext = new HaloOnlineLib.Serialization.TagSerializationContext(tagsStream, HaloOnlineTagCache, scnr); var scenario = HaloOnlineLib.Serialization.TagDeserializer.Deserialize<HaloOnlineLib.TagStructures.Scenario>(new HaloOnlineLib.Serialization.TagSerializationContext(tagsStream, HaloOnlineTagCache, scnr)); if (scenario.StructureBSPs.Count() == 0) { ConsoleLogit("The scenario has no sbsps"); return; } ConsoleLogit("Found {0} SBSPs", scenario.StructureBSPs.Count()); //TODO: Figure out why we can't have the full SBSP structure... var sbsp = HaloOnlineLib.Serialization.TagDeserializer.Deserialize<HaloOnlineLib.TagStructures.ScenarioStructureBsp>(new HaloOnlineLib.Serialization.TagSerializationContext(tagsStream, HaloOnlineTagCache, scenario.StructureBSPs[0].Bsp)); if (sbsp.CollisionMaterials.Count() == 0) { ConsoleLogit("The sbsp has no matterials"); return; } ConsoleLogit("Found {0} Collision Materials", sbsp.CollisionMaterials.Count()); List<HaloOnlineLib.TagStructures.Shader> ShaderList = new List<HaloOnlineLib.TagStructures.Shader>(); foreach (var mat in sbsp.CollisionMaterials) { var CollMatShader = new HaloOnlineLib.Serialization.TagSerializationContext(tagsStream, HaloOnlineTagCache, mat.Shader); ShaderList.Add(HaloOnlineLib.Serialization.TagDeserializer.Deserialize<HaloOnlineLib.TagStructures.Shader>(CollMatShader)); } if (ShaderList.Count() == 0) { ConsoleLogit("Failed to find SBSPs Collision Material shaders."); return; } ConsoleLogit("Found {0} Shaders", ShaderList.Count()); ExtractHOShaders(ShaderList, tagsStream); } }
private void ExtractHOShaders(List<HaloOnlineLib.TagStructures.Shader> ShaderList, FileStream tagsStream) { var resourceManager = new HaloOnlineLib.Resources.ResourceDataManager(); try { resourceManager.LoadCachesFromDirectory(Properties.Settings.Default.HOMapFolder); } catch { ConsoleLogit("Unable to load the resource .dat files."); ConsoleLogit("Make sure that they all exist and are valid."); return; } foreach (var shader in ShaderList) { for (var i = 0; i < shader.PredictedBitmap.Count; i++) { var BitmapType = HaloOnlineStringIdCache.GetString(shader.PredictedBitmap[i].Type); if (shader.PredictedBitmap[i].Bitmap == null) { continue; } var outPath = Path.Combine("HaloOnlineOutput", "bitmaps"); try { var offset = string.Format("0x{0:X8}", shader.PredictedBitmap[i].Bitmap.Index); var index = HaloOnlinelistA.IndexOf(offset); if (HaloOnlinelistB[index] != "") { outPath = Path.Combine(outPath, HaloOnlinelistB[index] + "-" + BitmapType + ".dds"); ConsoleLogit(HaloOnlinelistB[index]); } else { outPath = Path.Combine(outPath, shader.PredictedBitmap[i].Bitmap.Index.ToString("X8") + "-" + BitmapType + ".dds"); ConsoleLogit(shader.PredictedBitmap[i].Bitmap.Index.ToString("X8") + "-" + BitmapType + ".dds"); } } catch (Exception) { outPath = Path.Combine(outPath, shader.PredictedBitmap[i].Bitmap.Index.ToString("X8") + "-" + BitmapType + ".dds"); ConsoleLogit(shader.PredictedBitmap[i].Bitmap.Index.ToString("X8") + "-" + BitmapType + ".dds"); } Directory.CreateDirectory(Path.GetDirectoryName(outPath)); try { var extractor = new HaloOnlineLib.Resources.Bitmaps.BitmapDdsExtractor(resourceManager); var materialBitmapContext = new HaloOnlineLib.Serialization.TagSerializationContext(tagsStream, HaloOnlineTagCache, shader.PredictedBitmap[i].Bitmap); var bitmap = HaloOnlineLib.Serialization.TagDeserializer.Deserialize<HaloOnlineLib.TagStructures.Bitmap>(materialBitmapContext); var ddsOutDir = outPath; for (var b = 0; b < bitmap.Images.Count; b++) { using (var outStream = File.Open(outPath, FileMode.Create, FileAccess.Write)) { extractor.ExtractDds(bitmap, b, outStream); } } } catch (Exception e) { ConsoleLogit("Error extracting texture for sbsp: " + e.Message); } } } }