Ejemplo n.º 1
0
        unsafe void ReadStaticTexture(int index, out Texture2D texture)
        {
            texture = null;
            int  length, extra;
            bool is_patched;
            // get a reader inside Art.Mul
            BinaryFileReader reader = m_FileIndex.Seek(index, out length, out extra, out is_patched);

            if (reader == null)
            {
                return;
            }
            reader.ReadInt(); // don't need this, see Art.mul file format.
            // get the dimensions of the texture
            int width  = reader.ReadShort();
            int height = reader.ReadShort();

            if (width <= 0 || height <= 0)
            {
                return;
            }
            // read the texture data!
            ushort[] lookups = reader.ReadUShorts(height);
            ushort[] data    = reader.ReadUShorts(length - lookups.Length * 2 - 8);
            Metrics.ReportDataRead(sizeof(ushort) * (data.Length + lookups.Length + 2));
            ushort[] pixels = new ushort[width * height];
            fixed(ushort *pData = pixels)
            {
                ushort *dataRef = pData;
                int     i;

                for (int y = 0; y < height; y++, dataRef += width)
                {
                    i = lookups[y];

                    ushort *start = dataRef;

                    int count, offset;

                    while (((offset = data[i++]) + (count = data[i++])) != 0)
                    {
                        start += offset;
                        ushort *end = start + count;

                        while (start < end)
                        {
                            ushort color   = data[i++];
                            *      start++ = (ushort)(color | 0x8000);
                        }
                    }
                }
            }

            texture = new Texture2D(m_Graphics, width, height, false, SurfaceFormat.Bgra5551);
            texture.SetData(pixels);
            m_StaticPicking.Set(index, width, height, pixels);
            return;
        }
Ejemplo n.º 2
0
        public unsafe AnimationFrame(int uniqueAnimationIndex, GraphicsDevice graphics, ushort[] palette, BinaryFileReader reader, SittingTransformation sitting)
        {
            m_AnimationIndex = uniqueAnimationIndex;
            int xCenter = reader.ReadShort();
            int yCenter = reader.ReadShort();
            int width   = reader.ReadUShort();
            int height  = reader.ReadUShort();

            // Fix for animations with no pixels.
            if ((width == 0) || (height == 0))
            {
                Texture = null;
                return;
            }
            if (sitting == SittingTransformation.StandSouth)
            {
                xCenter += 8;
                width   += 8;
                height  += 4;
            }
            ushort[] data = new ushort[width * height];
            // for sitting:
            // somewhere around the waist of a typical mobile animation, we take twelve rows of pixels,
            // discard every third, and shift every remaining row (total of eight) one pixel to the left
            // or right (depending on orientation), for a total skew of eight pixels.
            fixed(ushort *pData = data)
            {
                ushort *dataRef = pData;

                int dataRead = 0;

                int header;

                while ((header = reader.ReadInt()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;
                    int x = ((header >> 22) & 0x3FF) + xCenter - 0x200;
                    int y = ((header >> 12) & 0x3FF) + yCenter + height - 0x200;
                    if (sitting == SittingTransformation.StandSouth)
                    {
                        const int skew_start = -17;
                        const int skew_end   = skew_start - 16;
                        int       iy         = y - height - yCenter;
                        if (iy > skew_start)
                        {
                            // pixels below the skew
                            x -= 8;
                            y -= 4;
                        }
                        else if (iy > skew_end)
                        {
                            // pixels within the skew
                            if ((iy - skew_end) % 4 == 0)
                            {
                                reader.Position += (header & 0xFFF);
                                continue;
                            }
                            x -= (iy - skew_end) / 2;
                            y -= (iy - skew_end) / 4;
                        }
                    }
                    ushort *cur         = dataRef + y * width + x;
                    ushort *end         = cur + (header & 0xFFF);
                    int     filecounter = 0;
                    byte[]  filedata    = reader.ReadBytes(header & 0xFFF);
                    while (cur < end)
                    {
                        *cur++ = palette[filedata[filecounter++]];
                    }
                    dataRead += header & 0xFFF;
                }
                Metrics.ReportDataRead(dataRead);
            }

            Center  = new Point(xCenter, yCenter);
            Texture = new Texture2D(graphics, width, height, false, SurfaceFormat.Bgra5551);
            Texture.SetData(data);
            m_Picking.Set(m_AnimationIndex, width, height, data);
        }
Ejemplo n.º 3
0
        public unsafe Texture2D GetGumpTexture(int textureID, bool replaceMask080808 = false)
        {
            if (textureID < 0)
            {
                return(null);
            }

            if (m_TextureCache[textureID] == null)
            {
                int              length, extra;
                bool             patched;
                BinaryFileReader reader = m_FileIndex.Seek(textureID, out length, out extra, out patched);
                if (reader == null)
                {
                    return(null);
                }
                int width  = (extra >> 16) & 0xFFFF;
                int height = extra & 0xFFFF;
                if (width == 0 || height == 0)
                {
                    return(null);
                }
                int shortsToRead = length - (height * 2);
                if (reader.Stream.Length - reader.Position < (shortsToRead * 2))
                {
                    Tracer.Error($"Could not read gump {textureID:X4}: not enough data. Gump texture file truncated?");
                    return(null);
                }
                int[]    lookups = reader.ReadInts(height);
                int      metrics_dataread_start = (int)reader.Position;
                ushort[] fileData = reader.ReadUShorts(shortsToRead);
                ushort[] pixels   = new ushort[width * height];
                fixed(ushort *line = &pixels[0])
                {
                    fixed(ushort *data = &fileData[0])
                    {
                        for (int y = 0; y < height; ++y)
                        {
                            ushort *dataRef = data + (lookups[y] - height) * 2;
                            ushort *cur     = line + (y * width);
                            ushort *end     = cur + width;
                            while (cur < end)
                            {
                                ushort  color = *dataRef++;
                                ushort *next  = cur + *dataRef++;
                                if (color == 0)
                                {
                                    cur = next;
                                }
                                else
                                {
                                    color |= 0x8000;
                                    while (cur < next)
                                    {
                                        *cur++ = color;
                                    }
                                }
                            }
                        }
                    }
                }

                Metrics.ReportDataRead(length);
                if (replaceMask080808)
                {
                    for (int i = 0; i < pixels.Length; i++)
                    {
                        if (pixels[i] == 0x8421)
                        {
                            pixels[i] = 0xFC1F;
                        }
                    }
                }
                Texture2D texture = new Texture2D(m_graphicsDevice, width, height, false, SurfaceFormat.Bgra5551);
                texture.SetData(pixels);
                m_TextureCache[textureID] = texture;
                m_Picking.Set(textureID, width, height, pixels);
            }
            return(m_TextureCache[textureID]);
        }