static int Main(string[] args) { Console.WriteLine("{0} {1} -- (c) 2018 Kafuka Productions", Application.ProductName, Application.ProductVersion); if (args.Length == 0) { var myExe = Path.GetFileNameWithoutExtension(Application.ExecutablePath).ToLowerInvariant(); Console.WriteLine(); Console.WriteLine("To create: {0} inFile [-o outFile]", myExe); Console.WriteLine(); Console.WriteLine("inFile is a 320x200-pixel 256-color bitmap from a numbered sequence."); Console.WriteLine("If outFile is missing, inFile with the extension changed to '.seq'"); Console.WriteLine("and the sequence removed is assumed."); Console.WriteLine(); Console.WriteLine("Example: {0} scene1-1.png ==> scene1.seq", myExe); Console.WriteLine(" {0} scene1-1.png -o scene01.seq ==> scene01.seq", myExe); Console.WriteLine(); Console.WriteLine("To play: {0} inFile [-a] [-d] [-e outFile]", myExe); Console.WriteLine(); Console.WriteLine("inFile is a Sierra On-Line SEQ video file."); Console.WriteLine("Specify -a to play with aspect correction, -d to double the window size."); Console.WriteLine("Specify -e to extract frames to individual bitmaps. If no outFile is"); Console.WriteLine("given, 'inFile-0001.png' is assumed."); Console.WriteLine(); Console.WriteLine("Example: {0} scene1.seq", myExe); Console.WriteLine(); return(4); } var wantToCount = true; #if ALLOWGIFS var wasAnimatedGif = false; #endif var filename = string.Empty; var outFile = string.Empty; for (var i = 0; i < args.Length; i++) { if (i == 0) { filename = args[i]; } if (args[i].Equals("-o") && i < args.Length - 1) { outFile = args[i + 1]; } } if (!File.Exists(filename)) { Console.WriteLine("Input file {0} does not exist.", filename); return(1); } var frameList = new List <string>(); if (Path.GetExtension(filename).Equals(".seq", StringComparison.InvariantCultureIgnoreCase)) { try { Application.Run(new SeqPlay.Player(args)); } catch (ObjectDisposedException) { //Only here because Winforms is silly. } return(0); } if (Path.GetExtension(filename).Equals(".txt", StringComparison.InvariantCultureIgnoreCase)) { wantToCount = false; if (string.IsNullOrEmpty(outFile)) { outFile = Path.ChangeExtension(filename.RemoveSequence(), ".seq"); } frameList = File.ReadAllLines(filename).ToList(); foreach (var file in frameList) { if (!File.Exists(file)) { Console.WriteLine("Listed file {0} does not exist.", file); return(1); } } Console.WriteLine("Found {0} frames, from {1} up to {2}.", frameList.Count, Path.GetFileName(frameList[0]), Path.GetFileName(frameList.Last())); } #if ALLOWGIFS else if (Path.GetExtension(filename).Equals(".gif", StringComparison.InvariantCultureIgnoreCase)) { using (var maybeAnim = new System.Drawing.Bitmap(filename)) { if (maybeAnim.Width != 320 || maybeAnim.Height != 200) { Console.WriteLine("Input images can only be 320 by 200 pixels in size."); return(3); } var dimension = new System.Drawing.Imaging.FrameDimension(maybeAnim.FrameDimensionsList[0]); var frameCount = maybeAnim.GetFrameCount(dimension); if (string.IsNullOrEmpty(outFile)) { outFile = Path.ChangeExtension(filename.RemoveSequence(), ".seq"); } if (frameCount == 1) { wantToCount = true; } else { Console.WriteLine("Exploding animated gif..."); wantToCount = false; wasAnimatedGif = true; var tempFile = Path.Combine(Path.GetTempPath(), "seqmaker-0001.gif"); for (var i = 0; i < frameCount; i++) { maybeAnim.SelectActiveFrame(dimension, i); var newFrame = ((System.Drawing.Bitmap)maybeAnim.Clone()); newFrame.SaveEx(tempFile); frameList.Add(tempFile); tempFile = tempFile.IncreaseSequence(); } } } } #endif if (wantToCount && filename.RemoveSequence().Equals(filename)) { Console.WriteLine("Input filename has no sequence."); return(2); } if (wantToCount) { if (string.IsNullOrEmpty(outFile)) { outFile = Path.ChangeExtension(filename.RemoveSequence(), ".seq"); } //Count frames var firstFile = filename; var lastFile = filename; while (File.Exists(filename)) { frameList.Add(filename); lastFile = filename; filename = filename.IncreaseSequence(); } Console.WriteLine("Found {0} frames, from {1} up to {2}.", frameList.Count, Path.GetFileName(firstFile), Path.GetFileName(lastFile)); } var previous = new byte[64000]; var fileStream = new BinaryWriter(File.Open(outFile, FileMode.Create)); fileStream.Write((UInt16)frameList.Count); var palChunk = new byte[1024]; palChunk[10] = 1; palChunk[31] = 1; palChunk[32] = 1; palChunk[29] = 255; fileStream.Write(palChunk.Length); var bitmapData = new BitmapData(); try { filename = frameList[0]; bitmapData.GetPixels(filename); Array.Copy(bitmapData.Palette, 0, palChunk, 37, 768); fileStream.Write(palChunk); foreach (var frame in frameList) { filename = frame; var frameLeft = 0; var frameTop = 0; var frameRight = 319; var frameBottom = 199; bitmapData.GetPixels(filename); var bitmap = bitmapData.Data; var found = false; for (frameTop = 0; frameTop < 200; frameTop++) { for (var c = 0; c < 320; c++) { if (bitmap[(frameTop * 320) + c] != previous[(frameTop * 320) + c]) { found = true; break; } } if (found) { break; } } found = false; for (frameBottom = 199; frameBottom > frameTop; frameBottom--) { for (var c = 0; c < 320; c++) { if (bitmap[(frameBottom * 320) + c] != previous[(frameBottom * 320) + c]) { found = true; break; } } if (found) { break; } } frameBottom++; found = false; for (frameLeft = 0; frameLeft < 320; frameLeft++) { for (var c = 0; c < 200; c++) { if (bitmap[(c * 320) + frameLeft] != previous[(c * 320) + frameLeft]) { found = true; break; } } if (found) { break; } } found = false; for (frameRight = 319; frameRight > frameLeft; frameRight--) { for (var c = 0; c < 200; c++) { if (bitmap[(c * 320) + frameRight] != previous[(c * 320) + frameRight]) { found = true; break; } } if (found) { break; } } frameRight++; var frameWidth = frameRight - frameLeft; var frameHeight = frameBottom - frameTop; if (frameHeight + frameWidth == 0) { frameWidth = 1; frameHeight = 1; frameRight = 1; frameBottom = 1; frameTop = 0; frameLeft = 0; } var actualF = new byte[frameHeight * frameWidth]; for (var l = 0; l < frameHeight; l++) { Array.Copy(bitmap, ((frameTop + l) * 320) + frameLeft, actualF, (l * frameWidth), frameWidth); } //TODO: COMPRESS THAT SHIT var colorKey = 255; var frameType = 0; //full frame var frameSize = frameWidth * frameHeight; var rleSize = 0; fileStream.Write((UInt16)frameWidth); fileStream.Write((UInt16)frameHeight); fileStream.Write((UInt16)frameLeft); fileStream.Write((UInt16)frameTop); fileStream.Write((byte)colorKey); fileStream.Write((byte)frameType); fileStream.Write((UInt16)0); fileStream.Write((UInt16)frameSize); fileStream.Write((UInt16)0); fileStream.Write((UInt16)rleSize); fileStream.Write((UInt32)0); fileStream.Write((UInt16)0); var offset = fileStream.BaseStream.Position + 4; fileStream.Write((UInt32)offset); fileStream.Write(actualF); Array.Copy(bitmap, 0, previous, 0, 64000); } } catch (FormatException fex) { Console.WriteLine("Error working on frame {0}:", filename); Console.WriteLine(fex.Message); return(3); } #if ALLOWGIFS if (wasAnimatedGif) { Console.WriteLine("Cleaning up animated gif frames..."); foreach (var file in frameList) { File.Delete(file); } } #endif Console.WriteLine("Done!"); fileStream.Flush(); fileStream.Close(); return(0); }