Пример #1
0
        unsafe void ReadStaticTexture(int index, out Texture2DInfo texture)
        {
            texture = null;
            // get a reader inside Art.Mul
            var r = _fileIndex.Seek(index, out int length, out int extra, out bool patched);

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

            if (width <= 0 || height <= 0)
            {
                return;
            }
            // read the texture data!
            var lookups  = r.ReadUShorts(height);
            var fileData = r.ReadUShorts(length - lookups.Length * 2 - 8);

            Metrics.ReportDataRead(sizeof(ushort) * (fileData.Length + lookups.Length + 2));
            var pixels = new byte[width * height * 4];

            fixed(byte *pData = pixels)
            {
                uint *dataRef = (uint *)pData;
                int   i;

                for (int y = 0; y < height; y++, dataRef += width)
                {
                    i = lookups[y];
                    uint *start = dataRef;
                    int   count, offset;
                    while (((offset = fileData[i++]) + (count = fileData[i++])) != 0)
                    {
                        start += offset;
                        uint *end = start + count;
                        while (start < end)
                        {
                            uint color   = ConvertUtils.FromBGR555(fileData[i++]);
                            *    start++ = color;
                        }
                    }
                }
            }

            texture = new Texture2DInfo(width, height, TextureFormat.BGRA32, false, pixels);
            _staticPicking.Set(index, width, height, pixels);
            return;
        }
Пример #2
0
        public unsafe Texture2DInfo GetGumpTexture(int textureID, bool replaceMask080808 = false)
        {
            if (textureID < 0)
            {
                return(null);
            }
            if (_textureCache[textureID] == null)
            {
                var reader = _fileIndex.Seek(textureID, out int length, out int extra, out bool patched);
                if (reader == null)
                {
                    return(null);
                }
                var width  = (extra >> 16) & 0xFFFF;
                var height = extra & 0xFFFF;
                if (width == 0 || height == 0)
                {
                    return(null);
                }
                var shortsToRead = length - (height * 2);
                if (reader.Stream.Length - reader.Position < (shortsToRead * 2))
                {
                    Utils.Error($"Could not read gump {textureID:X4}: not enough data. Gump texture file truncated?");
                    return(null);
                }
                var lookups = reader.ReadInts(height);
                var metrics_dataread_start = (int)reader.Position;
                var fileData = reader.ReadUShorts(shortsToRead);
                var pixels   = new byte[width * height * 4];
                fixed(byte *line = &pixels[0])
                fixed(ushort *data = &fileData[0])
                for (int y = 0; y < height; ++y)
                {
                    ushort *dataRef = data + (lookups[y] - height) * 2;
                    uint *  cur     = (uint *)line + (y * width);
                    uint *  end     = cur + width;

                    while (cur < end)
                    {
                        uint  color = ConvertUtils.FromBGR555(*dataRef++, false);
                        uint *next  = cur + *dataRef++;
                        if (color == 0)
                        {
                            cur = next;
                        }
                        else
                        {
                            color |= 0xFF000000;
                            while (cur < next)
                            {
                                *cur++ = color;
                            }
                        }
                    }
                }

                Metrics.ReportDataRead(length);
                //if (replaceMask080808)
                //    for (var i = 0; i < pixels.Length; i++)
                //        if (pixels[i] == 0x8421)
                //            pixels[i] = 0xFC1F;
                var texture = new Texture2DInfo(width, height, TextureFormat.BGRA32, false, pixels); //: SurfaceFormat.Bgra5551
                _textureCache[textureID] = texture;
                _picking.Set(textureID, width, height, pixels);
            }
            return(_textureCache[textureID]);
        }
Пример #3
0
        public unsafe AnimationFrame(int uniqueAnimationIndex, object graphics, ushort[] palette, BinaryFileReader reader, SittingTransformation sitting)
        {
            _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;
            }
            var data = new byte[width * height * 4];

            // 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(byte *pData = data)
            {
                ushort *dataRef  = (ushort *)pData;
                var     dataRead = 0;
                int     header;

                while ((header = reader.ReadInt()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;
                    var x = ((header >> 22) & 0x3FF) + xCenter - 0x200;
                    var y = ((header >> 12) & 0x3FF) + yCenter + height - 0x200;
                    if (sitting == SittingTransformation.StandSouth)
                    {
                        const int skew_start = -17;
                        const int skew_end   = skew_start - 16;
                        var       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);
                    var     filecounter = 0;
                    var     filedata    = reader.ReadBytes(header & 0xFFF);
                    while (cur < end)
                    {
                        *cur++ = palette[filedata[filecounter++]];
                    }
                    dataRead += header & 0xFFF;
                }
                Metrics.ReportDataRead(dataRead);
            }

            Center  = new Vector2Int(xCenter, yCenter);
            Texture = new Texture2DInfo(width, height, TextureFormat.BGRA32, false, data);
            _picking.Set(_animationIndex, width, height, data);
        }