private bool IsDrSpr(Stream s) { var start = s.Position; var h = new SprHeader() { Magic1 = s.ReadASCII(4), Version = s.ReadInt32(), Nanims = s.ReadInt32(), Nrots = s.ReadInt32(), Szx = s.ReadInt32(), Szy = s.ReadInt32(), Npics = s.ReadInt32(), Nsects = s.ReadInt32() }; if (h.Magic1 != "RSPR" && h.Magic1 != "SSPR") { s.Position = start; return(false); } if (h.Magic1 == "SSPR") { h.IsShadow = true; } if (h.Version != 0x0210) { s.Position = start; return(false); } h.OffSections = HeaderSize + 4 * h.Nanims * h.Nrots; h.OffAnims = h.OffSections + 16 * h.Nsects; h.OffPicoffs = h.OffAnims + 4 * h.Nanims; h.OffBits = h.OffPicoffs + 8 * h.Npics + 4; header = h; return(true); }
/// <summary> /// Load and read Sprite file. /// </summary> /// <param name="inputFile">Input file.</param> /// <param name="transparent">Replace blue color with transparent.</param> /// <exception cref="HLToolsUnsupportedFile"></exception> public Frame[] LoadFile(string inputFile, bool transparent = false) { Filename = inputFile; //Reset previous loaded data Bitmap bmp = null; frames.Clear(); Close(); fs = new FileStream(inputFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); binReader = new BinaryReader(fs); //First try get header ID SprHeader SpriteHeader = new SprHeader(); SpriteHeader.Id = binReader.ReadChars(4); string magic = new string(SpriteHeader.Id); if (magic != SpriteHeaderId) //if invalid SPR file { throw new HLToolsUnsupportedFile("Invalid or unsupported Sprite File!"); } SpriteHeader.Version = binReader.ReadInt32(); SpriteHeader.Type = (SprType)binReader.ReadInt32(); SpriteHeader.TextFormat = (SprTextFormat)binReader.ReadInt32(); SpriteHeader.BoundingRadius = binReader.ReadSingle(); SpriteHeader.MaxWidth = binReader.ReadInt32(); SpriteHeader.MaxHeight = binReader.ReadInt32(); SpriteHeader.NumFrames = binReader.ReadInt32(); SpriteHeader.BeamLen = binReader.ReadSingle(); SpriteHeader.SynchType = (SprSynchType)binReader.ReadInt32(); this.SpriteHeader = SpriteHeader; //Palette length ushort u = binReader.ReadUInt16(); //Prepare new palette for bitmap ColorPalette pal = null; using (Bitmap tmpBitmap = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) { pal = tmpBitmap.Palette; byte[] palBytes = binReader.ReadBytes(u * 3); for (int i = 0, j = 0; i < u; i++) { //Load (R,G,B) from file /*if (transparent && SpriteHeader.TextFormat == SprTextFormat.SPR_ADDITIVE) * { * //pal.Entries[i] = Color.FromArgb((u - 1) - i, palBytes[j], palBytes[j + 1], palBytes[j + 2]); * } * else * { * //pal.Entries[i] = Color.FromArgb(palBytes[j], palBytes[j + 1], palBytes[j + 2]); * }*/ pal.Entries[i] = Color.FromArgb(palBytes[j], palBytes[j + 1], palBytes[j + 2]); //Check for transparent color if (i == (u - 1)) //256th color is alpha { if (transparent && SpriteHeader.TextFormat == SprTextFormat.SPR_ALPHTEST) { pal.Entries[i] = Color.FromArgb(0, pal.Entries[i]); } } j += 3; } } indexesOfPixelPositions = new long[SpriteHeader.NumFrames]; pixelsLengths = new uint[SpriteHeader.NumFrames]; //Load frames for (int i = 0; i < SpriteHeader.NumFrames; i++) { int frameGroup = binReader.ReadInt32(); int frameOriginX = binReader.ReadInt32(); int frameOriginY = binReader.ReadInt32(); int frameWidth = binReader.ReadInt32(); int frameHeight = binReader.ReadInt32(); bmp = new Bitmap(frameWidth, frameHeight, PixelFormat.Format8bppIndexed); bmp.Palette = pal; //Get pixelsize uint pixelSize = (uint)(frameWidth * frameHeight); indexesOfPixelPositions[i] = binReader.BaseStream.Position; pixelsLengths[i] = pixelSize; //Load all pixels from file to array byte[] pixels = binReader.ReadBytes((int)pixelSize); //Lock bitmap for pixel manipulation BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); System.Runtime.InteropServices.Marshal.Copy(pixels, 0, bmd.Scan0, pixels.Length); bmp.UnlockBits(bmd); //Insert new frame to frames list Frame frame = new Frame(); frame.OriginX = frameOriginX; frame.OriginY = frameOriginY; frame.Image = bmp; frames.Add(frame); } return(frames.ToArray()); }
/// <summary> /// Load and read Sprite file. /// </summary> /// <param name="inputFile">Input file.</param> /// <param name="transparent">Replace blue color with transparent.</param> /// <exception cref="HLToolsUnsupportedFile"></exception> public Frame[] LoadFile(string inputFile, bool transparent = false) { Filename = inputFile; //Reset previous loaded data Bitmap bmp = null; frames.Clear(); Close(); fs = new FileStream(inputFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); binReader = new BinaryReader(fs); //First try get header ID SprHeader SpriteHeader = new SprHeader(); SpriteHeader.Id = binReader.ReadChars(4); string magic = new string(SpriteHeader.Id); if (magic != SpriteHeaderId) //if invalid SPR file { throw new HLToolsUnsupportedFile("Invalid or unsupported Sprite File!"); } SpriteHeader.Version = binReader.ReadInt32(); SpriteHeader.Type = (SprType)binReader.ReadInt32(); SpriteHeader.TextFormat = (SprTextFormat)binReader.ReadInt32(); SpriteHeader.BoundingRadius = binReader.ReadSingle(); SpriteHeader.MaxWidth = binReader.ReadInt32(); SpriteHeader.MaxHeight = binReader.ReadInt32(); SpriteHeader.NumFrames = binReader.ReadInt32(); SpriteHeader.BeamLen = binReader.ReadSingle(); SpriteHeader.SynchType = (SprSynchType)binReader.ReadInt32(); this.SpriteHeader = SpriteHeader; //Palette length ushort u = binReader.ReadUInt16(); //Prepare new palette for bitmap ColorPalette pal = null; using (Bitmap tmpBitmap = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) { pal = tmpBitmap.Palette; byte[] palBytes = binReader.ReadBytes(u * 3); for (int i = 0, j = 0; i < u; i++) { //Load (R,G,B) from file /*if (transparent && SpriteHeader.TextFormat == SprTextFormat.SPR_ADDITIVE) { //pal.Entries[i] = Color.FromArgb((u - 1) - i, palBytes[j], palBytes[j + 1], palBytes[j + 2]); } else { //pal.Entries[i] = Color.FromArgb(palBytes[j], palBytes[j + 1], palBytes[j + 2]); }*/ pal.Entries[i] = Color.FromArgb(palBytes[j], palBytes[j + 1], palBytes[j + 2]); //Check for transparent color if (i == (u - 1)) //256th color is alpha { if (transparent && SpriteHeader.TextFormat == SprTextFormat.SPR_ALPHTEST) { pal.Entries[i] = Color.FromArgb(0, pal.Entries[i]); } } j += 3; } } indexesOfPixelPositions = new long[SpriteHeader.NumFrames]; pixelsLengths = new uint[SpriteHeader.NumFrames]; //Load frames for (int i = 0; i < SpriteHeader.NumFrames; i++) { int frameGroup = binReader.ReadInt32(); int frameOriginX = binReader.ReadInt32(); int frameOriginY = binReader.ReadInt32(); int frameWidth = binReader.ReadInt32(); int frameHeight = binReader.ReadInt32(); bmp = new Bitmap(frameWidth, frameHeight, PixelFormat.Format8bppIndexed); bmp.Palette = pal; //Get pixelsize uint pixelSize = (uint)(frameWidth * frameHeight); indexesOfPixelPositions[i] = binReader.BaseStream.Position; pixelsLengths[i] = pixelSize; //Load all pixels from file to array byte[] pixels = binReader.ReadBytes((int)pixelSize); //Lock bitmap for pixel manipulation BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); System.Runtime.InteropServices.Marshal.Copy(pixels, 0, bmd.Scan0, pixels.Length); bmp.UnlockBits(bmd); //Insert new frame to frames list Frame frame = new Frame(); frame.OriginX = frameOriginX; frame.OriginY = frameOriginY; frame.Image = bmp; frames.Add(frame); } return frames.ToArray(); }
public DrSprFrame(Stream s, SprHeader sph, SprFrameInfo info) { Type = SpriteFrameType.Indexed; var picindex = info.A * sph.Nrots + info.R; var readInt = new Func <int, int>((off) => { s.Position = off; return(s.ReadInt32()); }); var picnr = readInt(HeaderSize + picindex * 4); if (picnr >= sph.Npics) { throw new Exception("Pic number was greater or equal to number of pics."); } var picoff = readInt(sph.OffPicoffs + 8 * picnr); var nextpicoff = readInt(sph.OffPicoffs + 8 * (picnr + 1)); var start = s.Position; s.Position = sph.OffBits + picoff; var tempData = s.ReadBytes(nextpicoff - picoff); Data = new byte[(sph.Szx + 2) * sph.Szy]; var pixindex = new Func <int, int, int>((x, y) => { int vr = (y * sph.Szx) + x; return(vr); }); var curr = 0; for (var l = 0; l < sph.Szy; ++l) { int step = 0, currx = 0, cnt, i; while (currx < sph.Szx) { cnt = tempData[curr++]; if ((step & 1) != 0) { cnt &= 0x7f; } if ((step & 1) != 0) { if (!sph.IsShadow) { for (i = 0; i < cnt; ++i, ++curr) { int newIndex = pixindex(currx + i, l); Data[newIndex] = tempData[curr]; } } else { for (i = 0; i < cnt; ++i) { int newIndex = pixindex(currx + i, l); Data[newIndex] = 47; } } } currx += cnt; ++step; } if (currx != sph.Szx) { throw new Exception("Current x was not equal to the line size."); } } Offset = new float2(0, 0); FrameSize = new Size(sph.Szx, sph.Szy); Size = FrameSize; s.Position = start; }