private static void LoadTableInfo(FileTableContainer tableContainer, CFStorage rootStorage, CFStorage gameStorage) { // first, although we can loop through entries, get them from the game storage, so we // know their order, which is important when writing back (because you know, hashing). gameStorage.TryGetStream("CustomInfoTags", out var citStream); if (citStream != null) { using (var stream = new MemoryStream(citStream.GetData())) using (var reader = new BinaryReader(stream)) { tableContainer.CustomInfoTags.Load(reader); } } // now actually read them in rootStorage.TryGetStorage("TableInfo", out var tableInfoStorage); if (tableInfoStorage == null) { Logger.Info("TableInfo storage not found, skipping."); return; } tableInfoStorage.VisitEntries(item => { if (item.IsStream) { var itemStream = item as CFStream; if (itemStream != null) { tableContainer.TableInfo[item.Name] = BiffUtil.ParseWideString(itemStream.GetData()); } } }, false); }
private static void LoadTableMeta(FileTableContainer tableContainer, CFStorage gameStorage) { // version gameStorage.TryGetStream("Version", out var versionBytes); if (versionBytes != null) { tableContainer.FileVersion = BitConverter.ToInt32(versionBytes.GetData(), 0); } else { Logger.Info("No Version under GameStg found, skipping."); } // hash gameStorage.TryGetStream("Version", out var hashBytes); if (hashBytes != null) { tableContainer.FileHash = hashBytes.GetData(); } else { Logger.Info("No MAC under GameStg found, skipping."); } }
public static FileTableContainer Load(string filename, bool loadGameItems = true) { var cf = new CompoundFile(filename); try { var gameStorage = cf.RootStorage.GetStorage("GameStg"); var gameData = gameStorage.GetStream("GameData"); var fileVersion = BitConverter.ToInt32(gameStorage.GetStream("Version").GetData(), 0); using (var stream = new MemoryStream(gameData.GetData())) using (var reader = new BinaryReader(stream)) { var tableContainer = new FileTableContainer(reader); LoadTableInfo(tableContainer, cf.RootStorage, gameStorage); if (loadGameItems) { LoadGameItems(tableContainer, gameStorage, tableContainer.NumGameItems, "GameItem"); LoadGameItems(tableContainer, gameStorage, tableContainer.NumVpeGameItems, "VpeGameItem"); } LoadTextures(tableContainer, gameStorage); LoadSounds(tableContainer, gameStorage, fileVersion); LoadCollections(tableContainer, gameStorage); LoadTableMeta(tableContainer, gameStorage); return(tableContainer); } } finally { cf.Close(); } }
private static void LoadTextures(FileTableContainer tableContainer, CFStorage storage) { for (var i = 0; i < tableContainer.NumTextures; i++) { var textureName = $"Image{i}"; storage.TryGetStream(textureName, out var textureStream); if (textureStream == null) { Logger.Warn("Could not find stream {0}, skipping.", textureName); continue; } var textureData = textureStream.GetData(); if (textureData.Length < 4) { Logger.Warn("Skipping {itemName} because it has size of {itemDataLength}.", textureName, textureData.Length); continue; } using (var stream = new MemoryStream(textureData)) using (var reader = new BinaryReader(stream)) { var texture = new Texture(reader, textureName); tableContainer.AddTexture(texture); } } }
private static void LoadCollections(FileTableContainer tableContainer, CFStorage storage) { for (var i = 0; i < tableContainer.NumCollections; i++) { var collectionName = $"Collection{i}"; storage.TryGetStream(collectionName, out var collectionStream); if (collectionStream == null) { Logger.Warn("Could not find stream {0}, skipping.", collectionName); continue; } using (var stream = new MemoryStream(collectionStream.GetData())) using (var reader = new BinaryReader(stream)) { tableContainer.Collections.Add(new CollectionData(reader, collectionName)); } } }
private static void LoadSounds(FileTableContainer tableContainer, CFStorage storage, int fileVersion) { for (var i = 0; i < tableContainer.NumSounds; i++) { var soundName = $"Sound{i}"; storage.TryGetStream(soundName, out var soundStream); if (soundStream == null) { Logger.Warn("Could not find stream {0}, skipping.", soundName); continue; } var soundData = soundStream.GetData(); using (var stream = new MemoryStream(soundData)) using (var reader = new BinaryReader(stream)) { var sound = new Sound.Sound(reader, soundName, fileVersion); tableContainer.AddSound(sound); } } }
private static void LoadGameItems(FileTableContainer tableContainer, CFStorage storage, int count, string storagePrefix) { for (var i = 0; i < count; i++) { var itemName = $"{storagePrefix}{i}"; storage.TryGetStream(itemName, out var itemStream); if (itemStream == null) { Logger.Warn("Could not find stream {0}, skipping.", itemName); continue; } var itemData = itemStream.GetData(); if (itemData.Length < 4) { Logger.Warn("Skipping {itemName} because it has size of {itemDataLength}.", itemName, itemData.Length); continue; } var reader = new BinaryReader(new MemoryStream(itemData)); // parse to enum var iItemType = reader.ReadInt32(); if (!Enum.IsDefined(typeof(ItemType), iItemType)) { Logger.Info("Invalid item type " + iItemType); return; } var itemType = (ItemType)iItemType; switch (itemType) { case ItemType.Bumper: { var item = new VisualPinball.Engine.VPT.Bumper.Bumper(reader, itemName); tableContainer.Add(item); break; } case ItemType.Decal: { tableContainer.Add(new VisualPinball.Engine.VPT.Decal.Decal(reader, itemName)); break; } case ItemType.DispReel: { var item = new VisualPinball.Engine.VPT.DispReel.DispReel(reader, itemName); tableContainer.Add(item); break; } case ItemType.Flasher: { var item = new VisualPinball.Engine.VPT.Flasher.Flasher(reader, itemName); tableContainer.Add(item); break; } case ItemType.Flipper: { var item = new VisualPinball.Engine.VPT.Flipper.Flipper(reader, itemName); tableContainer.Add(item); break; } case ItemType.Gate: { var item = new VisualPinball.Engine.VPT.Gate.Gate(reader, itemName); tableContainer.Add(item); break; } case ItemType.HitTarget: { var item = new VisualPinball.Engine.VPT.HitTarget.HitTarget(reader, itemName); tableContainer.Add(item); break; } case ItemType.Kicker: { var item = new VisualPinball.Engine.VPT.Kicker.Kicker(reader, itemName); tableContainer.Add(item); break; } case ItemType.Light: { var item = new VisualPinball.Engine.VPT.Light.Light(reader, itemName); tableContainer.Add(item); break; } case ItemType.LightSeq: { var item = new VisualPinball.Engine.VPT.LightSeq.LightSeq(reader, itemName); tableContainer.Add(item); break; } case ItemType.Plunger: { var item = new VisualPinball.Engine.VPT.Plunger.Plunger(reader, itemName); tableContainer.Add(item); break; } case ItemType.Primitive: { var item = new Primitive.Primitive(reader, itemName); tableContainer.Add(item); break; } case ItemType.Ramp: { var item = new Ramp.Ramp(reader, itemName); tableContainer.Add(item); break; } case ItemType.Rubber: { var item = new Rubber.Rubber(reader, itemName); tableContainer.Add(item); break; } case ItemType.Spinner: { var item = new Spinner.Spinner(reader, itemName); tableContainer.Add(item); break; } case ItemType.Surface: { var item = new Surface.Surface(reader, itemName); tableContainer.Add(item); break; } case ItemType.TextBox: { var item = new TextBox.TextBox(reader, itemName); tableContainer.Add(item); break; } case ItemType.Timer: { var item = new Timer.Timer(reader, itemName); tableContainer.Add(item); break; } case ItemType.Trigger: { var item = new Trigger.Trigger(reader, itemName); tableContainer.Add(item); break; } case ItemType.Trough: { var item = new Trough.Trough(reader, itemName); tableContainer.Add(item); break; } case ItemType.MetalWireGuide: { var item = new MetalWireGuide.MetalWireGuide(reader, itemName); tableContainer.Add(item); break; } } } }