public void parseSubChunks() { using (BinaryReader reader = new(new MemoryStream(data))) { while (reader.BaseStream.Position + 4 < reader.BaseStream.Length) { string header = reader.ReadStringFromChars(4); if (ChunkedFile.IsInterestingChunk(header)) { int subsize = reader.ReadInt32(); if (subsize < data.Length) { header = ChunkedFile.InterestingChunks[header]; FileChunk chunk = new FileChunk(reader.ReadBytes(subsize)); chunk.parseSubChunks(); if (!subchunks.ContainsKey(header)) { subchunks[header] = new List <FileChunk>(); } subchunks[header].Add(chunk); } } } } }
/// <summary> /// Загрузка картинки из файла /// </summary> /// <param name="filename">Имя файла</param> /// <returns>Изображение</returns> public override Image Generate(string filename) { Image img = null; ChunkedFile cf = new ChunkedFile(filename); if (cf.Root.Name == "Skybox") { // Ищем чанк с текстурами ChunkedFile.KeyValueChunk k = (ChunkedFile.KeyValueChunk)cf.Root.GetChunk("Texture"); if (k != null) { foreach (string sn in sideNames) { if (k.Values.ContainsKey(sn)) { string fn = k.Values[sn]; if (FileSystem.FileExist(fn)) { img = Image.FromStream(new MemoryStream(FileSystem.Read(fn))); break; } } } } } // TODO: Добавить затемнение картинки цветом скайбокса return(img); }
/// <summary> /// Сохранение файла /// </summary> public override void Save() { ChunkedFile cf = new ChunkedFile(); cf.Root.Name = "Skybox"; // Запись текстур ChunkedFile.KeyValueChunk textureChunk = new ChunkedFile.KeyValueChunk("Texture"); textureChunk.Values.Add("Front", sky[Skybox.Side.Front] != null ? sky[Skybox.Side.Front].Link : ""); textureChunk.Values.Add("Right", sky[Skybox.Side.Right] != null ? sky[Skybox.Side.Right].Link : ""); textureChunk.Values.Add("Back", sky[Skybox.Side.Back] != null ? sky[Skybox.Side.Back].Link : ""); textureChunk.Values.Add("Left", sky[Skybox.Side.Left] != null ? sky[Skybox.Side.Left].Link : ""); textureChunk.Values.Add("Top", sky[Skybox.Side.Top] != null ? sky[Skybox.Side.Top].Link : ""); textureChunk.Values.Add("Bottom", sky[Skybox.Side.Bottom] != null ? sky[Skybox.Side.Bottom].Link : ""); cf.Root.Children.Add(textureChunk); // Запись данных редактора ChunkedFile.DataChunk editorChunk = new ChunkedFile.DataChunk("Editor"); MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write((float)cam.Angles.X); bw.Write((float)cam.Angles.Y); bw.Write((bool)(Form as SkyboxForm).skyGizmoButton.Checked); bw.Close(); editorChunk.Data = ms.ToArray(); cf.Root.Children.Add(editorChunk); // Сохранение saving = true; cf.Save(File.FullPath); Project.Notify(File); saving = false; Saved = true; }
public static ChunkedFile GetMapFromWDT(CASCLib.CASCHandler cascHandler, ChunkedFile wdt, uint x, uint y, string mapName) { if (!(x >= 0 && y >= 0 && x < 64 && y < 64)) { return(null); } if (adtCache[x][y] != null) { return(adtCache[x][y]); } MPHD header = wdt.GetChunk("MPHD").As <MPHD>(); if (header == null) { return(null); } MAIN main = wdt.GetChunk("MAIN").As <MAIN>(); if (main == null || (main.MapAreaInfo[y][x].Flag & 0x1) == 0) { return(null); } MAID mapFileIDs = wdt.GetChunk("MAID").As <MAID>(); if (mapFileIDs == null) { return(null); } if (mapFileIDs.MapFileDataIDs[y][x].Obj0ADT == 0) { return(null); } ADTFile adt = new(adtCache[x][y] != null); if ((header.Flags & 0x200) != 0) { adt.LoadFile(cascHandler, mapFileIDs.MapFileDataIDs[y][x].Obj0ADT, $"Obj0ADT {x}_{y} for {mapName}"); } else { adt.LoadFile(cascHandler, $"world/maps/{mapName}/{mapName}_{x}_{y}_obj0.adt"); } adtCache[x][y] = adt; return(adt); }
/// <summary> /// Загрузка и инициализация /// </summary> protected override void Load() { // Инициализация графики if (scene == null) { // Создание сцены scene = new Scene(); // Камера cam = new Camera(); scene.Camera = cam; // Создание скайбокса sky = new Skybox(); scene.Sky = sky; // Направляющие WireCubeComponent c = new WireCubeComponent(); c.WireColor = Color.Lime; c.WireWidth = 3f; wireGuides = new Entity(); wireGuides.AddComponent(c); wireGuides.Position = Vec3.Zero; scene.Entities.Add(wireGuides); } // Загрузка данных UpdateTitle(); ChunkedFile cf = new ChunkedFile(File.FullPath); if (cf.Root.Name == "Skybox") { // Конвертация формы SkyboxForm frm = Form as SkyboxForm; // Поиск чанка с текстурами ChunkedFile.KeyValueChunk textureChunk = (ChunkedFile.KeyValueChunk)cf.Root.GetChunk("Texture"); if (textureChunk != null) { frm.topSkyTexture.File = Project.GetEntry(textureChunk.Values["Top"]); frm.bottomSkyTexture.File = Project.GetEntry(textureChunk.Values["Bottom"]); frm.leftSkyTexture.File = Project.GetEntry(textureChunk.Values["Left"]); frm.rightSkyTexture.File = Project.GetEntry(textureChunk.Values["Right"]); frm.frontSkyTexture.File = Project.GetEntry(textureChunk.Values["Front"]); frm.backSkyTexture.File = Project.GetEntry(textureChunk.Values["Back"]); } // Получение чанка для редактора ChunkedFile.DataChunk editorChunk = (ChunkedFile.DataChunk)cf.Root.GetChunk("Editor"); if (editorChunk != null) { MemoryStream ms = new MemoryStream(editorChunk.Data); BinaryReader br = new BinaryReader(ms); float cx = br.ReadSingle(); float cy = br.ReadSingle(); cam.Angles = new Vec3(cx, cy, 0f); (Form as SkyboxForm).skyGizmoButton.Checked = br.ReadBoolean(); br.Close(); } } Saved = true; }
public static void ParsMapFiles(CASCLib.CASCHandler cascHandler) { for (var i = 0; i < 64; ++i) { adtCache[i] = new ChunkedFile[64]; } var mapStorage = DBReader.Read <MapRecord>(1349477); if (mapStorage == null) { Console.WriteLine("Fatal error: Invalid Map.db2 file format!\n"); return; } Dictionary <uint, WDTFile> wdts = new(); WDTFile getWDT(uint mapId) { WDTFile wdtFile = wdts.LookupByKey(mapId); if (wdtFile == null) { MapRecord record = mapStorage.LookupByKey(mapId); if (record == null) { return(null); } wdtFile = new WDTFile(); if (!wdtFile.LoadFile(cascHandler, $"world/maps/{record.Directory}/{record.Directory}.wdt") || !wdtFile.Init(mapId)) { return(null); } wdts.Add(mapId, wdtFile); } return(wdtFile); } foreach (var(id, record) in mapStorage) { WDTFile wdtFile = getWDT(id); if (wdtFile != null) { Console.Write($"Processing Map {id}\n"); for (uint x = 0; x < 64; ++x) { for (uint y = 0; y < 64; ++y) { bool success = true; if (GetMapFromWDT(cascHandler, wdtFile, x, y, record.Directory) is not ADTFile adt || !adt.Init(id, id)) { success = false; } if (!success) { WDTFile parentWDT = record.ParentMapID >= 0 ? getWDT((uint)record.ParentMapID) : null; MapRecord parentMap = mapStorage.LookupByKey((uint)record.ParentMapID); if (parentMap != null && parentWDT != null) { if (GetMapFromWDT(cascHandler, parentWDT, x, y, parentMap.Directory) is not ADTFile parentAdt || !parentAdt.Init(id, id)) { Console.WriteLine($"Failed to process map {id} and {record.ParentMapID}"); continue; } } } } // draw progress bar Console.Write($"Processing........................{(100 * (x + 1)) / 64}%\r"); } Console.Write("\n"); } } }