public static SpriteSheet GetSpriteSheet(int num, int form, Enums.Coloration shiny, Enums.Gender gender) { string formString = "r"; if (form >= 0) { formString += "-" + form; if (shiny >= 0) { formString += "-" + (int)shiny; if (gender >= 0) { formString += "-" + (int)gender; } } } SpriteSheet sheet = spriteCache.Get(num + formString); if (sheet != null) return sheet; try { // If we are still here, that means the sprite wasn't in the cache if (System.IO.File.Exists(Paths.CachedGFXPath + "Sprite\\Sprite" + num + ".sprite")) { sheet = new SpriteSheet(); string changedFormString = formString; using (FileStream fileStream = File.OpenRead(Paths.CachedGFXPath + "Sprite\\Sprite" + num + ".sprite")) { using (BinaryReader reader = new BinaryReader(fileStream)) { int formCount = reader.ReadInt32(); Dictionary<string, int[]> formData = new Dictionary<string, int[]>(); for (int i = 0; i < formCount; i++) { // Read the form name string formName = reader.ReadString(); int[] formIntData = new int[2]; // Load form position formIntData[0] = reader.ReadInt32(); // Load form size formIntData[1] = reader.ReadInt32(); // Add form data to collection formData.Add(formName, formIntData); } while (true) { if (spriteCache.ContainsKey(num + changedFormString)) {//this point will be hit if the first fallback data to be found is already in the cache //the cache needs to be updated for aliases, but that's it. No need to load any new data. sheet = spriteCache.Get(num + changedFormString); break; } else if (formData.ContainsKey(changedFormString) || changedFormString == "r") {//we've found a spritesheet in the file, so load it. int[] formInt = formData[changedFormString]; // Jump to the correct position fileStream.Seek(formInt[0], SeekOrigin.Current); sheet.LoadFromData(reader, formInt[1]); spriteCache.Add(num + changedFormString, sheet); break; } // If the form specified wasn't found, continually revert to the backup until only "r" is reached changedFormString = changedFormString.Substring(0, changedFormString.LastIndexOf('-')); } } } //continually add aliases string aliasString = formString; while (aliasString != changedFormString) { //add aliases here spriteCache.AddAlias(num + aliasString, num + changedFormString); // If the form specified wasn't found, continually revert to the backup until only "r" is reached aliasString = aliasString.Substring(0, aliasString.LastIndexOf('-')); } //string rootForm = spriteCache.GetOriginalKeyFromAlias(num + formString); //if (rootForm != num + formString) //{ // Logs.Logger.LogDebug("Could not load " + num + formString + ", loaded " + num + rootForm +" instead."); //} return sheet; } } catch (Exception ex) { Logs.Logger.LogError(new Exception("Error retrieving sprite " + num + " " + formString+"\n", ex)); } //add error sheet sheet = new SpriteSheet(); spriteCache.Add(num + formString, sheet); return sheet; }
private static SpriteSheet BuildSpriteSurface(Dictionary<FrameType, Dictionary<Maps.Direction8, List<Bitmap>>> frameCollection, Dictionary<FrameType, List<Bitmap>> miscFrameCollection, string spriteRootDirectory) { int frameHeight = 0; int frameWidth = 0; SpriteSheet sprite = new SpriteSheet(); //set frame count and frame size for (int i = 0; i < frameCollection.Keys.Count; i++) { Dictionary<Maps.Direction8, List<Bitmap>> frameDirectionCollection = frameCollection.Values.ElementAt(i); for (int j = 0; j < 8; j++) { Maps.Direction8 direction = (Maps.Direction8)j; int totalSurfaceWidth = 0; int lastX = 0; List<Bitmap> frameList = frameDirectionCollection[direction]; sprite.FrameData.SetFrameCount(frameCollection.Keys.ElementAt(i), direction, frameList.Count); foreach (Bitmap frame in frameList) { if (frameHeight == 0) { frameHeight = frame.Height; } else if (frameHeight != frame.Height) { throw new Exception("Frameheight mismatch: " + frameCollection.Keys.ElementAt(i).ToString() + " " + direction.ToString() + " (" + frameHeight + " vs. " + frame.Height + ")" ); } if (frameWidth == 0) { frameWidth = frame.Width; } else if (frameWidth != frame.Width) { throw new Exception("Framewidth mismatch: " + frameCollection.Keys.ElementAt(i).ToString() + " " + direction.ToString() + " (" + frameWidth + " vs. " + frame.Width + ")"); } totalSurfaceWidth += frame.Width; } TileSheet animSheet = null; if (totalSurfaceWidth > 0) { animSheet = new TileSheet(); animSheet.CreatePixels32(totalSurfaceWidth, frameHeight); } foreach (Bitmap frame in frameList) { BitmapData frameData = frame.LockBits(new Rectangle(0, 0, frame.Width, frame.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); animSheet.Blit(frameData, 0, 0, frame.Width, frame.Height, lastX, 0); frame.UnlockBits(frameData); lastX += frame.Width; frame.Dispose(); } sprite.AddSheet(frameCollection.Keys.ElementAt(i), direction, animSheet); } } //set frame count and frame size for (int i = 0; i < miscFrameCollection.Count; i++) { int totalSurfaceWidth = 0; int lastX = 0; List<Bitmap> frameList = miscFrameCollection.Values.ElementAt(i); sprite.FrameData.SetFrameCount(miscFrameCollection.Keys.ElementAt(i), Maps.Direction8.Down, frameList.Count); foreach (Bitmap frame in frameList) { if (frameHeight == 0) { frameHeight = frame.Height; } else if (frameHeight != frame.Height) { throw new Exception("Frameheight mismatch: " + frameCollection.Keys.ElementAt(i).ToString() + " (" + frameHeight + " vs. " + frame.Height + ")"); } if (frameWidth == 0) { frameWidth = frame.Width; } else if (frameWidth != frame.Width) { throw new Exception("Framewidth mismatch: " + frameCollection.Keys.ElementAt(i).ToString() + " (" + frameWidth + " vs. " + frame.Width + ")"); } totalSurfaceWidth += frame.Width; } TileSheet animSheet = null; if (totalSurfaceWidth > 0) { animSheet = new TileSheet(); animSheet.CreatePixels32(totalSurfaceWidth, frameHeight); } foreach (Bitmap frame in frameList) { BitmapData frameData = frame.LockBits(new Rectangle(0, 0, frame.Width, frame.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); animSheet.Blit(frameData, 0, 0, frame.Width, frame.Height, lastX, 0); frame.UnlockBits(frameData); lastX += frame.Width; frame.Dispose(); } sprite.AddSheet(miscFrameCollection.Keys.ElementAt(i), Maps.Direction8.Down, animSheet); } return sprite; }