Beispiel #1
0
        // end Convert

        // Datafile
        private void saveRawDataAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (treeView.SelectedNode == null)
            {
                return;
            }

            EntryTreeNode node  = (EntryTreeNode)treeView.SelectedNode;
            Forge         forge = node.Forge;

            saveFileDialog.FileName = node.Text;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                Forge.FileEntry entry = forge.GetFileEntry(node.Text);
                byte[]          data  = forge.GetRawData(entry);
                try
                {
                    File.WriteAllBytes(saveFileDialog.FileName, data);
                }
                catch (IOException ee)
                {
                    Console.WriteLine(ee);
                }
                finally
                {
                    MessageBox.Show("Done");
                }
            }
        }
Beispiel #2
0
        // Datafile
        private void saveRawDataAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (treeView.SelectedNode == null)
            {
                return;
            }

            EntryTreeNode node  = (EntryTreeNode)treeView.SelectedNode;
            Forge         forge = node.GetForge();

            saveFileDialog.FileName = $"{node.Text}.dat";
            saveFileDialog.Filter   = "Raw Data|*.dat|All Files|*.*";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                Forge.FileEntry entry = forge.GetFileEntry(node.Text);
                byte[]          data  = forge.GetRawData(entry);
                try
                {
                    File.WriteAllBytes(saveFileDialog.FileName, data);
                }
                catch (IOException ee)
                {
                    Console.WriteLine(ee);
                }
                finally
                {
                    MessageBox.Show("Extracted decompressed data.", "Success");
                }
            }
        }
Beispiel #3
0
        private void saveDecompressedDataAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (treeView.SelectedNode == null)
            {
                return;
            }

            EntryTreeNode node  = (EntryTreeNode)treeView.SelectedNode;
            Forge         forge = node.GetForge();
            string        text  = node.Text;

            byte[] decompressedData = null;

            BeginMarquee();

            Helpers.DoBackgroundWork(() =>
            {
                Forge.FileEntry entry = forge.GetFileEntry(text);
                byte[] rawData        = forge.GetRawData(entry);
                decompressedData      = Odyssey.ReadFile(rawData);
            }, () =>
            {
                EndMarquee();

                // failure
                if (decompressedData.Length == 0 || decompressedData == null)
                {
                    MessageBox.Show("Could not decompress data.", "Failure");
                    return;
                }

                saveFileDialog.FileName = string.Concat(node.Text, ".", Helpers.ExtensionForGame(node.Game));
                saveFileDialog.Filter   = $"{Helpers.NameOfGame(node.Game)} Data|*.{Helpers.ExtensionForGame(node.Game)}|All Files|*.*";
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        File.WriteAllBytes(saveFileDialog.FileName, decompressedData);
                    }
                    catch (IOException ee)
                    {
                        Console.WriteLine(ee);
                    }
                    finally
                    {
                        MessageBox.Show("Done");
                    }
                }
            });
        }
Beispiel #4
0
        private void saveDecompressedDataAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (treeView.SelectedNode == null)
            {
                return;
            }

            EntryTreeNode node  = (EntryTreeNode)treeView.SelectedNode;
            Forge         forge = node.Forge;
            string        text  = node.Text;

            byte[] decompressedData = null;

            BeginMarquee();

            Helpers.DoBackgroundWork(() =>
            {
                Forge.FileEntry entry = forge.GetFileEntry(text);
                byte[] rawData        = forge.GetRawData(entry);
                decompressedData      = Odyssey.ReadFile(rawData);
            }, () =>
            {
                EndMarquee();

                saveFileDialog.FileName = $"{node.Text}.dec";
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        File.WriteAllBytes(saveFileDialog.FileName, decompressedData);
                    }
                    catch (IOException ee)
                    {
                        Console.WriteLine(ee);
                    }
                    finally
                    {
                        MessageBox.Show("Done");
                    }
                }
            });
        }
Beispiel #5
0
        public static bool ExtractTextureMap(string fileName, Forge forge)
        {
            using (Stream stream = new FileStream($"{fileName}-combined", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    // this is omnipresent
                    DatafileHeader header = new DatafileHeader
                    {
                        ResourceType = reader.ReadInt32(),
                        FileSize     = reader.ReadInt32(),
                        FileNameSize = reader.ReadInt32()
                    };
                    header.FileName = reader.ReadChars(header.FileNameSize);

                    // ignore the 2 bytes, file ID, and resource type identifier
                    reader.BaseStream.Seek(14, SeekOrigin.Current);

                    // toppmip 0
                    TopMip mip0 = new TopMip
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(8, SeekOrigin.Current);
                    mip0.DXTType = DXTExtensions.GetDXT(reader.ReadInt32());
                    reader.BaseStream.Seek(4, SeekOrigin.Current);
                    mip0.Mipmaps = reader.ReadInt32();

                    reader.BaseStream.Seek(81, SeekOrigin.Current);

                    // topmip 1
                    TopMip mip1 = new TopMip
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(8, SeekOrigin.Current);
                    mip1.DXTType = DXTExtensions.GetDXT(reader.ReadInt32());
                    reader.BaseStream.Seek(4, SeekOrigin.Current);
                    mip1.Mipmaps = reader.ReadInt32();

                    // locate the two topmips, if they exist
                    if (forge.FileEntries.Where(x => x.NameTable.Name.Contains(Path.GetFileName(fileName) + "_TopMip")).Count() == 2)
                    {
                        Forge.FileEntry topMipEntry = forge.FileEntries.Where(x => x.NameTable.Name == Path.GetFileName(fileName) + "_TopMip_0").First();

                        // extract, read, and create DDS images with the first topmips
                        byte[] rawData = forge.GetRawData(topMipEntry);
                        Helpers.WriteToTempFile(topMipEntry.NameTable.Name, rawData);

                        ReadFile(Helpers.GetTempPath(topMipEntry.NameTable.Name));

                        ExtractTopMip(Helpers.GetTempPath(topMipEntry.NameTable.Name), mip0);
                    }
                    else // topmips do not exist. fear not! there is still image data found here. let us use that.
                    {
                        reader.BaseStream.Seek(25, SeekOrigin.Current);
                        TextureMap map = new TextureMap
                        {
                            DataSize = reader.ReadInt32()
                        };

                        byte[] mipmapData = reader.ReadBytes(map.DataSize);
                        Helpers.WriteTempDDS(fileName, mipmapData, mip0.Width, mip0.Height, mip0.Mipmaps, mip0.DXTType);
                    }
                }
            }

            return(true);
        }
Beispiel #6
0
        private void treeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (e.Node == null || e.Node.Tag == null)
            {
                return;
            }

            EntryTreeNode curNode = (EntryTreeNode)e.Node;
            string        text    = curNode.Text;
            string        tag     = (string)curNode.Tag;

            // a forge file
            if (tag.EndsWith(".forge"))
            {
                // dump resources used by currentForge
                if (currentForge != null)
                {
                    currentForge.Dump();
                }

                currentForge = new Forge(tag);

                Helpers.DoBackgroundWork(() =>
                {
                    currentForge.Read();
                }, () =>
                {
                    // show message if there are over 10000 files in the forge
                    if (currentForge.FileEntries.Length > 10000 && MessageBox.Show("This forge file contains more " +
                                                                                   "than 10000 entries (" + currentForge.FileEntries.Length + " exactly). Loading all these " +
                                                                                   "entries will take a while and Blacksmith will freeze.\n\nContinue?", "Large forge file!",
                                                                                   MessageBoxButtons.YesNo) != DialogResult.Yes)
                    {
                        return;
                    }

                    // delete the empty tree node
                    e.Node.Nodes.RemoveAt(0);

                    // show and update the progress bar
                    toolStripProgressBar.Visible = true;
                    toolStripProgressBar.Value   = 0;
                    toolStripProgressBar.Maximum = currentForge.FileEntries.Length;

                    // load entries into this forge's tree node
                    for (int i = 0; i < currentForge.FileEntries.Length; i++)
                    {
                        string name        = currentForge.FileEntries[i].NameTable.Name;
                        EntryTreeNode node = new EntryTreeNode
                        {
                            Text = name,
                            Tag  = string.Format("{0}{1}{2}", curNode.Tag, FORGE_ENTRY_IDENTIFIER, name), // set the tag of this file's tree node
                            Size = currentForge.FileEntries[i].IndexTable.RawDataSize
                        };
                        node.Nodes.Add(new EntryTreeNode()); // add empty node (for entry's contents)
                        curNode.Nodes.Add(node);
                        toolStripProgressBar.Value++;
                    }

                    // reset and hide the progress bar
                    toolStripProgressBar.Value   = toolStripProgressBar.Maximum = 0;
                    toolStripProgressBar.Visible = false;
                });
            }
            // forge entry
            else if (tag.Contains(FORGE_ENTRY_IDENTIFIER) && !tag.Contains(FORGE_SUBENTRY_IDENTIFIER))
            {
                // extract, if the entry has an empty node or if data as a file does not exist
                if (curNode.Nodes.Count == 1 && curNode.Nodes[0].Text == "" &&
                    !File.Exists(Helpers.GetTempPath(text)))
                {
                    BeginMarquee();

                    Helpers.DoBackgroundWork(() =>
                    {
                        Forge.FileEntry entry = currentForge.GetFileEntry(text);
                        byte[] rawData        = currentForge.GetRawData(entry);
                        Helpers.WriteToTempFile(text, rawData);

                        Odyssey.ReadFile(Helpers.GetTempPath(text));
                    }, () =>
                    {
                        EndMarquee();

                        // remove nodes
                        curNode.Nodes.Clear();

                        string combined = $"{Helpers.GetTempPath(text)}-combined";

                        // look for supported resource types
                        using (Stream stream = new FileStream(combined, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            using (BinaryReader reader = new BinaryReader(stream))
                            {
                                // create nodes based on located resource types
                                foreach (Helpers.ResourceLocation loc in Helpers.LocateResourceIdentifiers(reader))
                                {
                                    curNode.Nodes.Add(new EntryTreeNode
                                    {
                                        Text         = loc.Type.ToString(),
                                        Tag          = string.Format("{0}{1}{2}", tag, FORGE_SUBENTRY_IDENTIFIER, loc.Type.ToString()),
                                        ResourceType = loc.Type
                                    });
                                }
                            }
                        }
                    });
                }
            }
        }
Beispiel #7
0
        public static void ExtractTextureMap(string fileName, EntryTreeNode node, Action <string> completionAction)
        {
            string name = Path.GetFileNameWithoutExtension(fileName);

            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (stream.Length == 0)
                {
                    return;
                }

                using (BinaryReader reader = new BinaryReader(stream))
                {
                    DatafileHeader header = new DatafileHeader
                    {
                        ResourceIdentifier = reader.ReadUInt32(),
                        FileSize           = reader.ReadInt32(),
                        FileNameSize       = reader.ReadInt32()
                    };
                    header.FileName = reader.ReadChars(header.FileNameSize);
                    reader.BaseStream.Seek(9, SeekOrigin.Current); // fileID + 1 skipped bytes

                    if (header.ResourceIdentifier != (uint)ResourceIdentifier.TEXTURE_MAP)
                    {
                        Message.Fail("This is not proper Texture Map data.");
                    }

                    /*// mip 0
                     * TextureMap mip0 = new TextureMap
                     * {
                     *  Width = reader.ReadInt32(),
                     *  Height = reader.ReadInt32()
                     * };
                     * reader.BaseStream.Seek(4, SeekOrigin.Current);
                     * mip0.DXT = DXTExtensions.GetDXT(reader.ReadInt32());
                     * reader.BaseStream.Seek(8, SeekOrigin.Current);
                     * mip0.Mipmaps = reader.ReadInt32();
                     *
                     * reader.BaseStream.Seek(39, SeekOrigin.Current); // go to next mip
                     *
                     * // ignore mip 1
                     * reader.BaseStream.Seek(28, SeekOrigin.Current);
                     *
                     * // locate the two mips, if they exist
                     * if (node.GetForge().FileEntries.Where(x => x.NameTable.Name.Contains(Path.GetFileNameWithoutExtension(fileName) + "_Mip")).Count() > 0)
                     * {
                     *  Forge.FileEntry[] mipEntries = node.GetForge().FileEntries.Where(x => x.NameTable.Name == Path.GetFileNameWithoutExtension(fileName) + "_Mip0").ToArray();
                     *  if (mipEntries != null && mipEntries.Length > 0)
                     *  {
                     *      Forge.FileEntry mipEntry = mipEntries[0];
                     *
                     *      // extract, read, and create a DDS image with the first mip
                     *      byte[] rawTopMipData = node.GetForge().GetRawData(mipEntry);
                     *
                     *      // read
                     *      byte[] topMipData = ReadFile(rawTopMipData);
                     *      File.WriteAllBytes(Helpers.GetTempPath(mipEntry.NameTable.Name + "." + Helpers.GameToExtension(node.Game)), topMipData);
                     *
                     *      // extract
                     *      //ExtractTopMip(topMipData, mipEntry.NameTable.Name, mip0, completionAction);
                     *  }
                     * }
                     * else // mips do not exist. fear not! there is still image data found here. let us use that.
                     * {
                     *  reader.BaseStream.Seek(12, SeekOrigin.Current);
                     *
                     *  /*TextureMap map = new TextureMap();
                     *  map.DataSize = reader.ReadInt32();
                     *
                     *  // test if this dataSize is too big
                     *  bool correctSize = true;
                     *  if (map.DataSize > reader.BaseStream.Length || map.DataSize < reader.BaseStream.Length - 300) // if the dataSize lies within a reasonable range
                     *  {
                     *      correctSize = false;
                     *  }
                     *
                     *  // test again, 14 bytes later
                     *  if (!correctSize)
                     *  {
                     *      reader.BaseStream.Seek(14, SeekOrigin.Current);
                     *      map.DataSize = reader.ReadInt32();
                     *  }
                     *
                     *  byte[] mipmapData = reader.ReadBytes(map.DataSize);
                     *
                     *  // write DDS file
                     *  TopMip mip = mip0;
                     *  Helpers.WriteTempDDS(name, mipmapData, mip.Width, mip.Height, mip.Mipmaps, mip.DXTType, () =>
                     *  {
                     *      Helpers.ConvertDDS($"{Helpers.GetTempPath(name)}.dds", fixNormals: name.Contains("NormalMap"), completionAction: (error) => {
                     *          if (error)
                     *              completionAction("FAILED");
                     *          else
                     *              completionAction($"{Helpers.GetTempPath(name)}.png");
                     *      });
                     *  });*
                     * }*/

                    // TextureMap
                    reader.BaseStream.Seek(5, SeekOrigin.Current); // identifier + 1 skipped byte
                    TextureMap textureMap = new TextureMap
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(4, SeekOrigin.Current);  // 4 skipped bytes
                    textureMap.DXT = (DXT)reader.ReadInt32();
                    reader.BaseStream.Seek(8, SeekOrigin.Current);  // 8 skipped bytes
                    textureMap.Mipmaps = reader.ReadInt32();
                    reader.BaseStream.Seek(12, SeekOrigin.Current); // 3 skipped ints

                    reader.BaseStream.Seek(2, SeekOrigin.Current);

                    // CompiledTopMip
                    CompiledTopMip[] compiledTopMips = new CompiledTopMip[reader.ReadInt32()];
                    reader.BaseStream.Seek(1, SeekOrigin.Current);

                    // read CompiledTopMips
                    for (int i = 0; i < compiledTopMips.Length; i++)
                    {
                        compiledTopMips[i].FileID = reader.ReadInt64();
                        reader.BaseStream.Seek(1, SeekOrigin.Current); // 1 skipped byte
                    }

                    reader.BaseStream.Seek(8, SeekOrigin.Current);

                    // CompiledTextureMap
                    reader.BaseStream.Seek(12, SeekOrigin.Current); // identifier + two skipped ints
                    CompiledTextureMap compiledTextureMap = new CompiledTextureMap
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(4, SeekOrigin.Current);  // 1 skipped int
                    compiledTextureMap.Mipmaps = reader.ReadInt32();
                    reader.BaseStream.Seek(4, SeekOrigin.Current);  // 1 skipped int
                    compiledTextureMap.DXT = (DXT)reader.ReadInt32();
                    reader.BaseStream.Seek(16, SeekOrigin.Current); // 4 skipped ints

                    // locate the parent forge tree node
                    EntryTreeNode forgeNode = (EntryTreeNode)node.Parent.Parent;
                    if (forgeNode.Type != EntryTreeNodeType.FORGE)
                    {
                        Message.Fail("Failed to locate the forge node.");
                        return;
                    }

                    // check to see if there is a topmip
                    if (compiledTopMips.Select(x => x.FileID).Count() > 0 && compiledTopMips.Select(x => x.FileID).First() != 0)
                    {
                        // search for file IDs from the CompiledTextureMaps
                        if (forgeNode.Nodes.Cast <EntryTreeNode>().Where(x => x.FileID == compiledTopMips[0].FileID).Count() == 0)
                        {
                            if (Message.Show("Failed to locate the Mip0. Would you like to try extracting the TextureMap's internal image data?", "Failed", MessageBoxButtons.YesNo) == DialogResult.Yes)
                            {
                                ExtractInternalTexture(reader, textureMap, name, completionAction);
                                return;
                            }
                            else
                            {
                                return;
                            }
                        }
                        EntryTreeNode mip0Node = forgeNode.Nodes.Cast <EntryTreeNode>().Where(x => x.FileID == compiledTopMips[0].FileID).First();

                        if (node.GetForge().FileEntries.Where(x => x.IndexTable.FileDataID == compiledTopMips[0].FileID).Count() == 0)
                        {
                            Message.Fail("Failed to locate the Mip0 in the forge.");
                            return;
                        }
                        Forge.FileEntry mip0Entry = node.GetForge().FileEntries.Where(x => x.IndexTable.FileDataID == compiledTopMips[0].FileID).First();

                        // read
                        byte[] rawMip0Data = node.GetForge().GetRawData(mip0Entry);
                        byte[] mip0Data    = ReadFile(rawMip0Data);

                        // save for future use
                        File.WriteAllBytes(Helpers.GetTempPath($"{mip0Entry.NameTable.Name}.{Helpers.GameToExtension(node.Game)}"), mip0Data);

                        // extract
                        Odyssey.ExtractTopMip(mip0Data, mip0Entry.NameTable.Name, compiledTextureMap, completionAction);
                    }
                    else
                    {
                        // use the image data within this file
                        ExtractInternalTexture(reader, textureMap, name, completionAction);
                    }
                }
            }
        }
Beispiel #8
0
        public static void ExtractTextureMap(string fileName, EntryTreeNode node, Action <string> completionAction)
        {
            string name = Path.GetFileNameWithoutExtension(fileName);

            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (stream.Length == 0)
                {
                    return;
                }

                using (BinaryReader reader = new BinaryReader(stream))
                {
                    DatafileHeader header = new DatafileHeader
                    {
                        ResourceType = reader.ReadInt32(),
                        FileSize     = reader.ReadInt32(),
                        FileNameSize = reader.ReadInt32()
                    };
                    header.FileName = reader.ReadChars(header.FileNameSize);

                    // ignore the 1 byte, file ID, resource type, and 1 extra byte
                    reader.BaseStream.Seek(14, SeekOrigin.Current);

                    // mip 0
                    Mip mip0 = new Mip
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(8, SeekOrigin.Current);
                    mip0.DXTType = DXTExtensions.GetDXT(reader.ReadInt32());
                    reader.BaseStream.Seek(4, SeekOrigin.Current);
                    mip0.Mipmaps = reader.ReadInt32();

                    reader.BaseStream.Seek(39, SeekOrigin.Current); // go to next mip

                    // mip 1
                    Mip mip1 = new Mip
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(8, SeekOrigin.Current);
                    mip1.DXTType = DXTExtensions.GetDXT(reader.ReadInt32());
                    reader.BaseStream.Seek(4, SeekOrigin.Current);
                    mip1.Mipmaps = reader.ReadInt32();

                    // locate the two mips, if they exist
                    if (node.GetForge().FileEntries.Where(x => x.NameTable.Name.Contains(Path.GetFileNameWithoutExtension(fileName) + "_Mip")).Count() == 2)
                    {
                        Forge.FileEntry[] mipEntries = node.GetForge().FileEntries.Where(x => x.NameTable.Name == Path.GetFileNameWithoutExtension(fileName) + "_Mip0").ToArray();
                        if (mipEntries.Length > 0)
                        {
                            Forge.FileEntry mipEntry = mipEntries[0];

                            // extract, read, and create a DDS image with the first mip
                            byte[] rawTopMipData = node.GetForge().GetRawData(mipEntry);
                            //Helpers.WriteToFile(mipEntry.NameTable.Name, rawData, true);

                            // read
                            //ReadFile(Helpers.GetTempPath(mipEntry.NameTable.Name));
                            byte[] topMipData = ReadFile(rawTopMipData);

                            // extract
                            //ExtractTopMip(Helpers.GetTempPath(mipEntry.NameTable.Name), mip0, completionAction);
                            ExtractTopMip(topMipData, mipEntry.NameTable.Name, mip0, completionAction);
                        }
                    }
                    else // mips do not exist. fear not! there is still image data found here. let us use that.
                    {
                        reader.BaseStream.Seek(12, SeekOrigin.Current);

                        TextureMap map = new TextureMap
                        {
                            DataSize = reader.ReadInt32()
                        };
                        byte[] mipmapData = reader.ReadBytes(map.DataSize);

                        // write DDS file
                        Helpers.WriteTempDDS(name, mipmapData, mip1.Width, mip1.Height, mip1.Mipmaps, mip1.DXTType, () =>
                        {
                            Helpers.ConvertDDS($"{Helpers.GetTempPath(name)}.dds", (bool error) => {
                                if (error)
                                {
                                    completionAction("FAILED");
                                }
                                else
                                {
                                    completionAction($"{Helpers.GetTempPath(name)}.png");
                                }
                            });
                        });
                    }
                }
            }
        }