Ejemplo n.º 1
0
 internal PaletteArchive(AssetLoader loader)
     : base(loader)
 {
     for (int index = 0; index < 8; index++)
     {
         PaletteAsset asset = PaletteAsset.ReadRgb(Manager, "Palette " + index, loader.Reader, 256, 63);
         AddChild(asset);
     }
 }
Ejemplo n.º 2
0
        void ReadIconAndTitle(int iconAndTitleOffset)
        {
            if (iconAndTitleOffset == 0)
            {
                return;
            }

            // Read the palette.
            Reader.BaseStream.Position = iconAndTitleOffset + 0x220;
            Color[] colors = new Color[16];
            for (int index = 0; index < 16; index++)
            {
                Reader.ReadNDSColor(forceTransparent: index == 0);
            }
            PaletteAsset palette = new PaletteAsset(Manager, "Icon palette", colors);

            // Read the icon.
            Reader.BaseStream.Position = iconAndTitleOffset + 0x20;
            Vector2i iconSize = new Vector2i(32, 32);
            Vector2i tileSize = iconSize / 8;

            int[] indices = new int[iconSize.X * iconSize.Y];

            for (Vector2i tile = Vector2i.Zero; tile.Y < tileSize.Y; tile.Y++)
            {
                for (tile.X = 0; tile.X < tileSize.X; tile.X++)
                {
                    for (Vector2i pixel = Vector2i.Zero; pixel.Y < 8; pixel.Y++)
                    {
                        for (pixel.X = 0; pixel.X < 4; pixel.X++)
                        {
                            int  x      = pixel.X + tile.X * 4;
                            int  y      = pixel.Y + tile.Y * 8;
                            int  offset = x + y * iconSize.X;
                            byte pair   = Reader.ReadByte();

                            indices[offset + 0] = pair & 0x0F;
                            indices[offset + 1] = pair >> 4;
                        }
                    }
                }
            }

            Icon = new IndexedTextureAsset(Manager, "Icon", palette, iconSize.X, iconSize.Y, indices);

            // Read the title.
            Name         = Reader.ReadStringzAt(iconAndTitleOffset + 0x240, Encoding.Unicode);
            TitleEnglish = Reader.ReadStringzAt(iconAndTitleOffset + 0x340, Encoding.Unicode);
            TitleFrench  = Reader.ReadStringzAt(iconAndTitleOffset + 0x440, Encoding.Unicode);
            TitleGerman  = Reader.ReadStringzAt(iconAndTitleOffset + 0x540, Encoding.Unicode);
            TitleItalian = Reader.ReadStringzAt(iconAndTitleOffset + 0x640, Encoding.Unicode);
            TitleSpanish = Reader.ReadStringzAt(iconAndTitleOffset + 0x740, Encoding.Unicode);
        }
Ejemplo n.º 3
0
        internal Palette(AssetLoader loader)
            : base(loader)
        {
            BinaryReader reader = loader.Reader;

            Unknowns.ReadBytes(reader, 25);            // Offset 0-24
            int firstIndex = reader.ReadByte();        // Offset 25-25

            Unknowns.ReadBytes(reader, 3);             // Offset 26-28
            int count = reader.ReadUInt16();           // Offset 29-30

            Unknowns.ReadBytes(reader, 1);             // Offset 31-31
            byte format = reader.ReadByte();           // Offset 32-32

            Unknowns.ReadBytes(reader, 4);             // Offset 33-36
            // Offset 37

            PaletteColor[] colors = new PaletteColor[count];
            Colors     = new ReadOnlyCollection <PaletteColor>(colors);
            FlatColors = new Codex <Color>(256);
            for (int index = 0; index < firstIndex; index++)
            {
                FlatColors.Add(Color.Purple);
            }
            for (int index = 0; index < count; index++)
            {
                PaletteColor color;

                switch (format)
                {
                case 0:                         // Variable (byte used, byte red, byte green, byte blue)
                    color = new PaletteColor(reader.ReadByte() != 0, reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                    break;

                case 1:                         // Constant (byte red, byte green, byte blue)
                    color = new PaletteColor(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                    break;

                default:
                    throw new NotImplementedException();
                }

                colors[index] = color;
                FlatColors.Add(color);
            }

            PaletteAsset = new PaletteAsset(Manager, Name ?? "Palette", FlatColors);
        }
Ejemplo n.º 4
0
        internal GraphicArchive(int paletteIndex, AssetLoader loader, int[] sizes = null)
            : base(loader)
        {
            State        state   = State.Get(this);
            PaletteAsset palette = state.GetPalette(paletteIndex);

            using (BinaryReader reader = loader.Reader) {
                byte forceSizeCode = reader.ReadByte();
                int  forceSize     = 0;

                if (forceSizeCode == 2)
                {
                    forceSize = reader.ReadByte();
                }
                else if (forceSizeCode != 1)
                {
                    throw new InvalidDataException();
                }

                int   count   = reader.ReadUInt16();
                int[] offsets = reader.ReadArrayInt32(count + 1);

                for (int index = 0; index < count; index++)
                {
                    int length = offsets[index + 1] - offsets[index];

                    reader.BaseStream.Position = offsets[index];

                    int width = -1, height = -1;

                    if (sizes != null && index * 2 < sizes.Length)
                    {
                        width  = sizes[index * 2 + 0];
                        height = sizes[index * 2 + 1];
                    }
                    else if (forceSize != 0)
                    {
                        width = height = forceSize;
                    }

                    new Graphic(this, loader, index, length, width, height, palette);
                }
            }
        }
Ejemplo n.º 5
0
        void Load(BinaryReader reader, int width, int height, PaletteAsset palette, byte format, int[] aux = null, int auxOffset = 0)
        {
            int[]  indices = new int[width * height];
            ushort dataSize;

            switch (format)
            {
            case 4:                     // Uncompressed
                dataSize = reader.ReadUInt16();
                if (width * height != dataSize)
                {
                    throw new InvalidDataException();
                }
                reader.ReadBytesAsInt32(indices, 0, width * height);
                break;

            case 6:                     // 5-bit RLE
                dataSize = reader.ReadUInt16();
                LoadRLE(indices, reader, width, height, 5, aux, auxOffset);
                break;

            case 8:                     // 4-bit RLE
                if (aux == null)
                {
                    throw new NotImplementedException("Need to load auxiliary palette.");
                }
                dataSize = reader.ReadUInt16();
                LoadRLE(indices, reader, width, height, 4, aux, auxOffset);
                break;

            case 10:                     // 4-bit aux palette indices.
                throw new NotImplementedException("Need to load auxiliary palette.");

            default:
                throw new NotImplementedException("Unknown graphic format " + format + ".");
            }

            Setup(palette, width, height, indices);
        }
Ejemplo n.º 6
0
        internal Image(AssetManager manager, BinaryReader reader, string name, Asset context)
            : base(manager, name)
        {
            using (reader) {
                int height = reader.ReadByte();
                int width  = reader.ReadByte() * 8;
                reader.RequireZeroes(4);
                int frameCount = reader.ReadUInt16();
                if (frameCount == 0)
                {
                    throw new InvalidDataException();
                }

                byte baseColorIndex = reader.ReadByte();
                int  colorCount     = reader.ReadByte() + 1;

                // Need to initialize palette.
                Color[] colors = new Color[256];

                for (int index = 0; index < 16; index++)
                {
                    colors[index] = Raster.DefaultEgaColors[index];
                }

                for (int index = 0; index < colorCount; index++)
                {
                    colors[index + baseColorIndex] = Color.FromArgb(reader.ReadByte() * 255 / 63, reader.ReadByte() * 255 / 63, reader.ReadByte() * 255 / 63);
                }

                PaletteAsset palette = new PaletteAsset(Manager, Name + " palette", colors);

                Unknowns.ReadBytes(reader, (colorCount + 1) / 2);                 // EGA color map, two colours per byte.
                Unknowns.ReadBytes(reader, 4);

                int remaining = checked ((int)(reader.BaseStream.Length - reader.BaseStream.Position));

                if (remaining == width * height * frameCount + 28)
                {
                    Unknowns.ReadBytes(reader, 28);
                    remaining -= 28;
                }

                if (remaining != width * height * frameCount || (height != 0 && remaining % height != 0))
                {
                    throw new InvalidDataException("Expected file length is not correct.");
                }

                int[] indices = new int[width * height];

                if (width == 0 || height == 0)
                {
                    AddChild(palette);
                }
                else
                {
                    for (int index = 0; index < frameCount; index++)
                    {
                        reader.ReadBytesAsInt32(indices, 0, indices.Length);
                        var resource = new IndexedTextureAsset(Manager, "Frame " + index, palette, width, height, indices);
                        AddChild(resource);
                    }
                }

                // Hack for "over.dax" files to use their multiple palettes.
                if (context is ArchiveRecord && ((ArchiveRecord)context).Id >= 51 && string.Equals(Path.GetFileName(context.Parent.Name), "over.dax", StringComparison.InvariantCultureIgnoreCase))
                {
                    Archive archive = (Archive)context.Parent;

                    for (int id = 1; id <= 4; id++)
                    {
                        palette = (PaletteAsset)archive.RecordsById[id].Contents.Children[0];
                        var frame = new IndexedTextureAsset(Manager, "Palette " + id, palette, width, height, indices);
                        AddChild(frame);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        internal Graphic(GraphicArchive archive, AssetLoader loader, int index, int length, int width, int height, PaletteAsset palette, int[] aux = null, int auxOffset = 0)
            : base(archive, loader)
        {
            BinaryReader reader = loader.Reader;

            Name = index.ToString();
            if (length == 0)
            {
                return;
            }

            if (width >= 0 && height >= 0)
            {
                int[] indices = reader.ReadBytesAsInt32(width * height);
                Setup(palette, width, height, indices);
            }
            else
            {
                byte format = reader.ReadByte();
                width  = reader.ReadByte();
                height = reader.ReadByte();
                Load(reader, width, height, palette, format, aux, auxOffset);
            }

            Center = new Vector2i(width / 2 - 4, height - 4);
        }
Ejemplo n.º 8
0
        /// <summary>Load the PCX image file.</summary>
        /// <param name="loader"></param>
        /// <returns></returns>
        public override Asset Load(AssetLoader loader)
        {
            BinaryReader reader = loader.Reader;
            PcxHeader    header = new PcxHeader(reader);

            int pitch = (header.BitsPerPixel * header.ColorPlaneCount + 7) / 8 * header.SizeX;

            int[] data = new int[pitch * header.SizeY + 1];

            for (int row = 0; row < header.SizeY; row++)
            {
                switch (header.Compression)
                {
                case PcxCompression.None:
                    for (int index = 0; index < pitch; index++)
                    {
                        data[pitch * row + index] = reader.ReadByte();
                    }
                    break;

                case PcxCompression.RLE:
                    for (int offset = pitch * row, end = offset + header.BytesPerScanLine; offset < end;)
                    {
                        byte value = reader.ReadByte();

                        if (value < 0xC0)
                        {
                            data[offset++] = value;
                        }
                        else
                        {
                            int  runEnd = offset + value - 0xC0;
                            byte code   = reader.ReadByte();

                            while (offset < runEnd)
                            {
                                data[offset++] = code;
                            }
                        }
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            PaletteAsset palette = null;

            if (header.ColorPlaneCount == 1)
            {
                if (reader.BaseStream.ReadByte() == PaletteMagic)
                {
                    palette = PaletteAsset.ReadRgb(Manager, loader.Name + " Palette", reader, 1 << header.BitsPerPixel, 255);
                }
            }

            if (palette != null)
            {
                return(new IndexedTextureAsset(loader, palette, header.SizeX, header.SizeY, data, pitch));
            }
            else
            {
                throw new NotImplementedException();
            }
        }