public PigFile(byte [] buffer, Palette palette)
        {
            int offset = BitConverter.ToInt32(buffer, 0);

            TotalTextures = BitConverter.ToInt32(buffer, offset);
            offset       += 4;

            TotalSounds = BitConverter.ToInt32(buffer, offset);
            offset     += 4;

            for (var i = 0; i < TotalTextures; i++)
            {
                var pigTexture = new PigTexture();

                pigTexture.Name = buffer.ByteArrayToString(offset, 8).Trim();
                offset         += 8;

                pigTexture.DFlags   = buffer[offset++];
                pigTexture.Width    = buffer[offset++];
                pigTexture.Height   = buffer[offset++];
                pigTexture.Flags    = buffer[offset++];
                pigTexture.AveColor = buffer[offset++];
                pigTexture.Offset   = BitConverter.ToInt32(buffer, offset);
                offset += 4;

                if ((pigTexture.DFlags & 128) != 0)
                {
                    //pigTexture.Width += 256;
                }

                Textures.Add(pigTexture);
            }

            for (var i = 0; i < TotalSounds; i++)
            {
                var pigSound = new PigSound();

                pigSound.Name       = buffer.ByteArrayToString(offset, 8).Trim();
                offset             += 8;
                pigSound.Length     = BitConverter.ToInt32(buffer, offset);
                offset             += 4;
                pigSound.DataLength = BitConverter.ToInt32(buffer, offset);
                offset             += 4;
                pigSound.Offset     = BitConverter.ToInt32(buffer, offset);
                offset             += 4;

                Sounds.Add(pigSound);
            }

            var pigDataStart = offset;

            // read all the texture data
            foreach (var texture in Textures)
            {
                offset = texture.Offset + pigDataStart;

                if (texture.RunLengthEncoded)
                {
                    var size = BitConverter.ToInt32(buffer, offset);
                    offset += 4;
                    offset += texture.Height;
                    if ((texture.DFlags & 32) != 0)
                    {
                        offset += texture.Height;
                    }

                    texture.Data = new byte[size];
                    for (var i = 0; i < size; i++)
                    {
                        texture.Data[i] = buffer[i + offset];
                    }

                    // uncompress
                    var result = new List <byte>();
                    int j      = 0;
                    while (j < size - 5)
                    {
                        var color = texture.Data[j++];
                        if (color == 0xe0)
                        {
                            continue;
                        }

                        if ((color & 0xe0) == 0xe0)
                        {
                            var count = color & 0x1f;
                            color = texture.Data[j++];
                            for (var k = 0; k < count; k++)
                            {
                                result.Add(color);
                            }
                        }
                        else
                        {
                            result.Add(color);
                        }
                    }

                    // replace with decoded data
                    texture.Data = result.ToArray();
                }
                else
                {
                    var size = texture.Height * texture.Width;
                    texture.Data = new byte[size];
                    for (var i = 0; i < size; i++)
                    {
                        texture.Data[i] = buffer[i + offset];
                    }
                }

                //TODO: need to convert indexed data into 32 bit per pixel true color
                var endResults = new List <byte>();
                for (var i = 0; i < texture.Data.Length; i++)
                {
                    var color = palette.paletteColors[texture.Data[i]];
                    endResults.Add(color.R);
                    endResults.Add(color.G);
                    endResults.Add(color.B);
                }

                texture.Data = endResults.ToArray();
            }
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();

            using (var stream = assembly.GetManifestResourceStream("DescentHogFileReader.DESCENT.HOG"))
            {
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);

                char[] sig = { (char)buffer[0], (char)buffer[1], (char)buffer[2] };

                int index = 3;

                var fileData = new List <HogFile>();

                int totalFiles = 0;
                while (index < buffer.Length)
                {
                    fileData.Add(new HogFile(buffer, index));
                    index += fileData[fileData.Count - 1].FileSize + 13 + 4;

                    // write file to output directory
                    File.WriteAllBytes(_outputDirectory + fileData[fileData.Count - 1].FileName, fileData[fileData.Count - 1].Data);

                    Console.WriteLine(fileData[fileData.Count - 1].FileName + "   (" + fileData[fileData.Count - 1].FileSize.ToString("N0") + ")");
                    totalFiles++;
                }
            }

            // read the palette
            Palette paletteData;

            using (var stream = assembly.GetManifestResourceStream("DescentHogFileReader.palette.256"))
            {
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);

                paletteData = new Palette(buffer);
            }


            // read the textures
            using (var stream = assembly.GetManifestResourceStream("DescentHogFileReader.DESCENT.PIG"))
            {
                byte[] buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);

                // read the textures and sounds
                var pigData = new PigFile(buffer, paletteData);

                // dump all the textures
                if (!Directory.Exists(_textureOutputDirectory))
                {
                    Directory.CreateDirectory(_textureOutputDirectory);
                }
                File.Delete(_textureOutputDirectory + "texture_list.txt");
                foreach (var texture in pigData.Textures)
                {
                    if ((texture.DFlags & 63) == 0)
                    {
                        try
                        {
                            var bitmap  = new Bitmap(texture.Width, texture.Height, PixelFormat.Format24bppRgb);
                            var bmData  = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                            var pNative = bmData.Scan0;
                            Marshal.Copy(texture.Data, 0, pNative, texture.Width * texture.Height * 3);
                            bitmap.UnlockBits(bmData);
                            bitmap.Save(_textureOutputDirectory + texture.Name.Trim() + ".png", ImageFormat.Png);
                        }
                        catch (Exception e)
                        {
                        }
                    }

                    File.AppendAllText(_textureOutputDirectory + "texture_list.txt", texture.Name + " (" + texture.Width + " x " + texture.Height + $", Frame:{texture.DFlags & 63}{(texture.RunLengthEncoded ? " RLE" : "")})" + Environment.NewLine);
                }
            }


            Console.ReadKey();
        }