Beispiel #1
0
        private static WadDirectoryEntry ReadWadEntry(ByteReader reader)
        {
            int         offset = reader.Int();
            int         size   = reader.Int();
            UpperString name   = reader.StringWithoutNulls(8);

            return(new WadDirectoryEntry(offset, size, name));
        }
Beispiel #2
0
        private static WadHeader ReadHeader(ByteReader reader)
        {
            bool iwad       = reader.String(4).ToUpper() == "IWAD";
            int  entryCount = reader.Int();
            int  dirOffset  = reader.Int();

            return(new WadHeader(iwad, entryCount, dirOffset));
        }
Beispiel #3
0
        public static Optional <TextureXImage> From(ByteReader reader)
        {
            try
            {
                UpperString   name            = reader.StringWithoutNulls(8);
                TextureXFlags flags           = (TextureXFlags)reader.UShort();
                Vector2       scale           = new Vector2(reader.Byte(), reader.Byte());
                Dimension     dimension       = new Dimension(reader.Short(), reader.Short());
                int           columnDirectory = reader.Int();
                int           patchCount      = reader.Short();

                List <TextureXPatch> patches = Range(patchCount).Map(i =>
                {
                    Vec2I offset        = new Vec2I(reader.Short(), reader.Short());
                    short patchIndex    = reader.Short();
                    short stepDirection = reader.Short();
                    short colormap      = reader.Short();
                    return(new TextureXPatch(offset, patchIndex, stepDirection, colormap));
                }).ToList();

                return(new TextureXImage(name, flags, scale, dimension, columnDirectory, patches));
            }
            catch
            {
                return(Empty);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Reads a TEXTURE1/2 entry.
        /// </summary>
        /// <param name="number">The index of the X in the textureX. Should be
        /// either 1 or 2.</param>
        /// <param name="data">The data to read.</param>
        /// <returns>All the processed texture definitions, or null if the
        /// entry is corrupt.</returns>
        public static Optional <TextureX> From(int number, byte[] data)
        {
            Debug.Assert(number == 1 || number == 2, "TEXTUREx should have only 1 or 2 as a number");

            try
            {
                ByteReader reader = ByteReader.From(ByteOrder.Little, data);
                Dictionary <UpperString, TextureXImage> images = new Dictionary <UpperString, TextureXImage>();

                int numTextures = reader.Int();

                List <int> offsets = new List <int>();
                for (int i = 0; i < numTextures; i++)
                {
                    offsets.Add(reader.Int());
                }

                foreach (int offset in offsets)
                {
                    reader.Offset = offset;
                    Optional <TextureXImage> imageOptional = TextureXImage.From(reader);
                    if (!imageOptional)
                    {
                        return(Empty);
                    }

                    // Unfortunately we have to follow the specification as per
                    // the ZDoom wiki:  "...however if a texture is defined
                    // more than once in the same TEXTUREx lump, the later
                    // definitions are skipped".
                    TextureXImage image = imageOptional.Value;
                    if (!images.ContainsKey(image.Name))
                    {
                        images[image.Name] = image;
                    }
                }

                return(new TextureX(number, images.Values));
            }
            catch
            {
                return(Empty);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Reads a pnames data from the entry provided.
        /// </summary>
        /// <param name="data">The data to read from.</param>
        /// <returns>A read pnames object from the entry, or an empty value if
        /// the entry has the wrong data amount or is corrupt.</returns>
        public static Optional <PNames> From(byte[] data)
        {
            try
            {
                ByteReader reader     = ByteReader.From(ByteOrder.Little, data);
                int        numStrings = reader.Int();

                List <UpperString> pnames = new List <UpperString>(numStrings);
                for (int i = 0; i < numStrings; i++)
                {
                    pnames.Add(reader.StringWithoutNulls(8));
                }

                return(new PNames(pnames));
            }
            catch
            {
                return(Empty);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Creates a palette image from a column-based image.
        /// </summary>
        /// <param name="data">The data for the image.</param>
        /// <param name="resourceNamespace">The namespace this image belongs
        /// to.</param>
        /// <returns>The palette image for the data, or null if the image is
        /// corrupt and would not make a valid column image.</returns>
        public static Optional <PaletteImage> FromColumn(byte[] data, ResourceNamespace resourceNamespace)
        {
            // OPTIMIZE: Short circuit if it's likely not a column image.
            // OPTIMIZE: Write posts horizontally, then rotate for speed?
            try
            {
                ByteReader reader = ByteReader.From(ByteOrder.Little, data);
                int        width  = reader.Short();
                int        height = reader.Short();
                Vec2I      offset = (reader.Short(), reader.Short());

                if (offset.X < 0 || offset.Y < 0)
                {
                    return(Empty);
                }

                int[] offsets = new int[width];
                for (int i = 0; i < width; i++)
                {
                    offsets[i] = reader.Int();
                }

                short[] indices = Arrays.Create(width * height, TransparentIndex);

                for (int col = 0; col < width; col++)
                {
                    reader.Offset = offsets[col];

                    while (true)
                    {
                        int rowStart = reader.Byte();
                        if (rowStart == 0xFF)
                        {
                            break;
                        }

                        int indicesCount = reader.Byte();
                        reader.Skip(1);
                        byte[] paletteIndices = reader.Bytes(indicesCount);
                        reader.Skip(1);

                        int indicesOffset = (rowStart * width) + col;
                        for (int i = 0; i < paletteIndices.Length; i++)
                        {
                            indices[indicesOffset] = paletteIndices[i];
                            indicesOffset         += width;
                        }
                    }
                }

                return(new PaletteImage(width, height, indices)
                {
                    Namespace = resourceNamespace,
                    Offset = offset
                });
            }
            catch
            {
                return(Empty);
            }
        }