public unsafe AnimationFrame(GraphicsDevice graphics, uint[] palette, BinaryFileReader reader) { int xCenter = reader.ReadShort(); int yCenter = reader.ReadShort(); int width = reader.ReadUShort(); int height = reader.ReadUShort(); // Fix for animations with no IO. if ((width == 0) || (height == 0)) { m_Texture = null; return; } uint[] data = new uint[width * height]; int header; int xBase = xCenter - 0x200; int yBase = (yCenter + height) - 0x200; fixed(uint *pData = data) { uint *dataRef = pData; int delta = width; int dataRead = 0; dataRef += xBase; dataRef += (yBase * delta); while ((header = reader.ReadInt()) != 0x7FFF7FFF) { header ^= DoubleXor; uint *cur = dataRef + ((((header >> 12) & 0x3FF) * delta) + ((header >> 22) & 0x3FF)); uint *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); } m_Center = new Microsoft.Xna.Framework.Point(xCenter, yCenter); m_Texture = new Texture2D(graphics, width, height); m_Texture.SetData <uint>(data); }
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; }
public MultiComponentList(BinaryFileReader reader, int count) { int metrics_dataread_start = (int)reader.Position; m_Min = m_Max = Point.Empty; Items = new MultiItem[count]; for (int i = 0; i < count; ++i) { Items[i].ItemID = reader.ReadShort(); Items[i].OffsetX = reader.ReadShort(); Items[i].OffsetY = reader.ReadShort(); Items[i].OffsetZ = reader.ReadShort(); Items[i].Flags = reader.ReadInt(); if (Items[i].OffsetX < m_Min.X) { m_Min.X = Items[i].OffsetX; } if (Items[i].OffsetY < m_Min.Y) { m_Min.Y = Items[i].OffsetY; } if (Items[i].OffsetX > m_Max.X) { m_Max.X = Items[i].OffsetX; } if (Items[i].OffsetY > m_Max.Y) { m_Max.Y = Items[i].OffsetY; } } m_Center = new Point(-m_Min.X, -m_Min.Y); m_Width = (m_Max.X - m_Min.X) + 1; m_Height = (m_Max.Y - m_Min.Y) + 1; // SortMultiComponentList(); Metrics.ReportDataRead((int)reader.Position - metrics_dataread_start); }
public MultiComponentList(BinaryFileReader r, int count) { var metrics_dataread_start = (int)r.Position; _min = _max = Vector2Int.zero; Items = new MultiItem[count]; for (var i = 0; i < count; ++i) { Items[i].ItemID = r.ReadShort(); Items[i].OffsetX = r.ReadShort(); Items[i].OffsetY = r.ReadShort(); Items[i].OffsetZ = r.ReadShort(); Items[i].Flags = r.ReadInt(); if (Items[i].OffsetX < _min.x) { _min.x = Items[i].OffsetX; } if (Items[i].OffsetY < _min.y) { _min.y = Items[i].OffsetY; } if (Items[i].OffsetX > _max.x) { _max.x = Items[i].OffsetX; } if (Items[i].OffsetY > _max.y) { _max.y = Items[i].OffsetY; } } _center = new Vector2Int(-_min.x, -_min.y); _width = (_max.x - _min.x) + 1; _height = (_max.y - _min.y) + 1; // SortMultiComponentList(); Metrics.ReportDataRead((int)r.Position - metrics_dataread_start); }
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); }
private static unsafe Texture2D readStaticTexture(int index) { int length, extra; bool is_patched; BinaryFileReader reader = m_Index.Seek(index, out length, out extra, out is_patched); reader.ReadInt(); // this data is discarded. Why? int width = reader.ReadShort(); int height = reader.ReadShort(); if (width <= 0 || height <= 0) { return(null); } if (m_dimensions[index - 0x4000] == null) { m_dimensions[index - 0x4000] = new ushort[] { (ushort)width, (ushort)height }; } ushort[] lookups = reader.ReadUShorts(height); int dataStart = (int)reader.Position + (height * 2); int readLength = (getMaxLookup(lookups) + width * 2); // we don't know the length of the last line, so we read width * 2, anticipating worst case compression. if (dataStart + readLength * 2 > reader.Stream.Length) { readLength = ((int)reader.Stream.Length - dataStart) >> 1; } ushort[] fileData = reader.ReadUShorts(readLength); uint[] pixelData = new uint[width * height]; fixed(uint *pData = pixelData) { uint *dataRef = 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 = fileData[i++]; * start++ = 0xFF000000 + ( ((((color >> 10) & 0x1F) * multiplier)) | ((((color >> 5) & 0x1F) * multiplier) << 8) | (((color & 0x1F) * multiplier) << 16) ); } } } } Metrics.ReportDataRead(sizeof(ushort) * (fileData.Length + lookups.Length + 2)); Texture2D texture = new Texture2D(m_graphics, width, height); texture.SetData <uint>(pixelData); return(texture); }