From 48266e670d8adcd26d501616f286d40c947ec7b4 Mon Sep 17 00:00:00 2001 From: offspring131313 Date: Sun, 4 Mar 2012 19:02:28 +0000 Subject: [PATCH] Added a function for making Animated Gifs. No UI has been implemented to allow a user to use this functionality, but there is commented out code that I used to test it in MainForm.TakeScreenShot(). Instructions on how to use is in comments. --- BizHawk.MultiClient/MainForm.cs | 122 ++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index b86a6475a7..1a988a3503 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -13,6 +13,7 @@ using BizHawk.Emulation.Consoles.Calculator; using BizHawk.Emulation.Consoles.Gameboy; using BizHawk.Emulation.Consoles.Nintendo; using BizHawk.MultiClient.tools; +using System.Collections.Generic; namespace BizHawk.MultiClient { @@ -1766,6 +1767,13 @@ namespace BizHawk.MultiClient { string path = String.Format(PathManager.ScreenshotPrefix(Global.Game) + ".{0:yyyy-MM-dd HH.mm.ss}.png", DateTime.Now); TakeScreenshot(path); + /*int frames = 120; + int skip = 1; + int speed = 1; + bool reversable = true; + string path = String.Format(PathManager.ScreenshotPrefix(Global.Game) + frames + "Frames-Skip=" + skip + "-Speed=" + speed + "-reversable=" + reversable + ".gif"); + makeAnimatedGif(frames, skip, speed, reversable, path);*/ + //Was using this code to test the animated gif functions } private void TakeScreenshot(string path) @@ -2530,5 +2538,119 @@ namespace BizHawk.MultiClient } } + #region Animaged Gifs + /// + /// Creates Animated Gifs + /// + /// Total number of frames in the gif + /// How many frames to skip per screenshot in the image. + /// A value of 5 means that frame 1002 will be an image and 1007 will be an image in the gif + /// A value of 1 means that frame 1001 will be an image and 1002 will be an image in the gif + /// How quickly the animated gif will run. A value of 1 or -1 = normal emulator speed. + /// A value of 2 will double the speed of the gif. + /// Input a negative value to slow down the speed of the gif. + /// A value of -2 will be half speed + /// Flag for making the gif loop back and forth + /// location to save the file + /// false if the parameters are incorrect, true if it completes + public bool makeAnimatedGif(int num_images, int frameskip, int gifSpeed, bool reversable, String filename) + { + if (num_images < 1 || frameskip < 1 || gifSpeed == 0) return false;//Exits if settings are bad + #region declare/insantiate variables + List images = new List(); //Variable for holding all images for the gif animation + Image tempImage; //Holding the image in case it doesn't end up being added to the animation + // Such a scenario could be a frameskip setting of 2 and a gifSpeed setting of 3 + // This would result in 1 of every 3 images being requested getting skipped. + // My math might be wrong at this hour, but you get the point! + int speedTracker = 0; // To keep track of when to add another image to the list + bool status = PressFrameAdvance; + PressFrameAdvance = true; + #endregion + + #region Get the Images for the File + int totalFrames = (gifSpeed > 0 ? num_images : (num_images * (gifSpeed * -1))); + images.Add(MakeScreenshotImage()); + while(images.Count < totalFrames) + { + tempImage = MakeScreenshotImage(); + if(gifSpeed < 0) + for (speedTracker = 0; speedTracker > gifSpeed; speedTracker--) + images.Add(tempImage); //If the speed of the animation is to be slowed down, then add that many copies + //of the image to the list + + for (int j = 0; j < frameskip; j++) + { + StepRunLoop_Core(); + Global.Emulator.FrameAdvance(true); //Frame advance + Global.RenderPanel.Render(Global.Emulator.VideoProvider); + + if (gifSpeed > 0) + { + speedTracker++;//Advance the frame counter for adding to the List of Images + if (speedTracker == Math.Max(gifSpeed,frameskip)) + { + images.Add(tempImage); + speedTracker = 0; + } + } + } + } + #endregion + PressFrameAdvance = status; + + /* + * The following code was obtained from here: + * http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/0c4252c8-8274-449c-ad9b-e4f07a8f8cdd/ + * Modified to work with the BizHawk Project + */ + #region make gif file + byte[] GifAnimation = {33, 255, 11, 78, 69, 84, 83, 67, 65, 80, 69, 50, 46, 48, 3, 1, 0, 0, 0}; + MemoryStream MS = new MemoryStream(); + BinaryReader BR = new BinaryReader(MS); + BinaryWriter BW = new BinaryWriter(new FileStream(filename, FileMode.Create)); + images[0].Save(MS,ImageFormat.Gif); + byte[] B = MS.ToArray(); + B[10] = (byte)(B[10] & 0X78); //No global color table. + BW.Write(B, 0, 13); + BW.Write(GifAnimation); + WriteGifImg(B, BW); + for (int I = 1; I < images.Count; I++) + { + MS.SetLength(0); + images[I].Save(MS, ImageFormat.Gif); + B = MS.ToArray(); + WriteGifImg(B, BW); + } + if (reversable) + { + for (int I = images.Count - 2; I >= 0; I--)//Start at (count - 2) because last image is already in place + { + MS.SetLength(0); + images[I].Save(MS, ImageFormat.Gif); + B = MS.ToArray(); + WriteGifImg(B, BW); + } + } + BW.Write(B[B.Length - 1]); + BW.Close(); + MS.Dispose(); + #endregion + + return true; + } + + public void WriteGifImg(byte[] B, BinaryWriter BW) + { + byte[] Delay = {0, 0}; + B[785] = Delay[0]; + B[786] = Delay[1]; + B[798] = (byte)(B[798] | 0X87); + BW.Write(B, 781, 18); + BW.Write(B, 13, 768); + BW.Write(B, 799, B.Length - 800); + } + + #endregion + } } \ No newline at end of file