private static FrameXNA[] checkCache(int body, int action, int direction) { // Make sure the cache is complete. // max number of bodies is about 0x1000 if (_Cache == null) _Cache = new FrameXNA[0x1000][][][]; if (_Cache[body] == null) _Cache[body] = new FrameXNA[35][][]; if (_Cache[body][action] == null) _Cache[body][action] = new FrameXNA[8][]; if (_Cache[body][action][direction] == null) _Cache[body][action][direction] = new FrameXNA[1]; if (_Cache[body][action][direction][0] != null) return _Cache[body][action][direction]; else return null; }
public static FrameXNA[] GetAnimation(BinaryReader bin) { uint[] palette = getPalette(bin); // 0x100 * 2 = 0x0200 bytes int lookupStart = (int)bin.BaseStream.Position; int frameCount = bin.ReadInt32(); // 0x04 bytes int[] lookups = new int[frameCount]; // frameCount * 0x04 bytes for (int i = 0; i < frameCount; ++i) { lookups[i] = bin.ReadInt32(); } FrameXNA[] frames = new FrameXNA[frameCount]; for (int i = 0; i < frameCount; ++i) { if (lookups[i] < lookups[0]) { frames[i] = FrameXNA.Empty; // Fix for broken animations, per issue13 } else { bin.BaseStream.Seek(lookupStart + lookups[i], SeekOrigin.Begin); frames[i] = new FrameXNA(_graphics, palette, bin); } } return frames; }
private static void getWidthHeight(FrameXNA[] frames, out int width, out int height, out int maxXoffset, out int maxYoffset) { // get the offsets maxXoffset = 0; maxYoffset = 0; for (int i = 0; i < frames.Length; i++) { if (frames[i].Center.X > maxXoffset) maxXoffset = frames[i].Center.X; if (frames[i].Center.Y < maxYoffset) maxYoffset = frames[i].Center.Y; } // get height/width using these offsets width = 0; height = 0; for (int i = 0; i < frames.Length; i++) { int thiswidth = frames[i].Texture.Width + (maxXoffset - frames[i].Center.X); if (thiswidth > width) { width = thiswidth; } int thisheight = frames[i].Texture.Height - (maxYoffset - frames[i].Center.Y); if (thisheight > height) { height = thisheight; } } }
private static void transform(BinaryReader bin) { FrameXNA[] frames = AnimationsXNA.GetAnimation(bin); BitStream CellMatrixStream = new BitStream(); BitStream CellDeltaEncodingStream = new BitStream(); BitStream CellDataStream = new BitStream(); int width, height, xoffset, yoffset; getWidthHeight(frames, out width, out height, out xoffset, out yoffset); uint[][] pixeldata = new uint[frames.Length][]; for (int i = 0; i < frames.Length; i++) pixeldata[i] = getPixelData(frames[i], width, height, xoffset - frames[i].Center.X, (height + (yoffset - frames[i].Center.Y)) - frames[i].Texture.Height); uint[] palette = new uint[0x100]; uint[] palettesortvalues = new uint[0x100]; uint[] paletteSimilars = new uint[0x100]; for (int i = 0; i < frames.Length; i++) getPalette(pixeldata[i], palette, palettesortvalues); palettesortvalues[0] = int.MaxValue; sortPalette(palette, palettesortvalues); // findSimilarShadesInPalette(palette, ref paletteSimilars); // combinePalette(palette, paletteSimilars, palettesortvalues); // sortPalette(palette, palettesortvalues, paletteSimilars); // debug = count num of pixels using top 16 colors. int topsixteen = 0; int others = 0; for (int i = 1; i < 17; i++) topsixteen += (int)palettesortvalues[i]; for (int i = 17; i < 256; i++) others += (int)palettesortvalues[i]; byte[][] framedata = new byte[frames.Length][]; for (int i = 0; i < frames.Length; i++) framedata[i] = palettedFrame(pixeldata[i], palette, paletteSimilars); for (int i = 0; i < frames.Length; i++) { byte[][] framecells = getCells(framedata[i], width); byte[][] lastFrameCells; if (i > 0) lastFrameCells = getCells(buildFrame(width, height, CellMatrixStream, CellDeltaEncodingStream, CellDataStream), width); else lastFrameCells = new byte[0][]; getStreams(framecells, lastFrameCells, i, width, palette, CellMatrixStream, CellDeltaEncodingStream, CellDataStream); byte[] newframedata = buildFrame(width, height, CellMatrixStream, CellDeltaEncodingStream, CellDataStream); FrameXNA frame = new FrameXNA(AnimationsXNA.DEBUG_GFX, palette, newframedata, width, height, 0, 0); frame.Texture.Save("test.bmp", Microsoft.Xna.Framework.Graphics.ImageFileFormat.Bmp); } int size = (int)(CellMatrixStream.Length >> 3) + (int)(CellDeltaEncodingStream.Length >> 3) + (int)(CellDataStream.Length >> 3); }
private static uint[] getPixelData(FrameXNA f, int width, int height, int xoffset, int yoffset) { uint[] outdata = new uint[width * height]; uint[] pixeldata = new uint[f.Texture.Height * f.Texture.Width]; f.Texture.GetData<uint>(pixeldata); for (int y = 0; y < f.Texture.Height; y++) { Array.Copy(pixeldata, y * f.Texture.Width, outdata, xoffset + (y + yoffset) * width, f.Texture.Width); } return outdata; }