private static Block readNextBlock(Stream file) { Block bl = new Block(); byte[] countbytes = new byte[4]; ReadWholeArray(file, countbytes); int count = BitConverter.ToInt32(countbytes, 0); if (count < 3) { throw new Exception("Invalid block data length: must be > 2"); } byte[] typebytes = new byte[2], data = new byte[count - 2]; ReadWholeArray(file, typebytes); ReadWholeArray(file, data); bl.type = BitConverter.ToUInt16(typebytes, 0); bl.data = data; return bl; }
public static void loadProjectFile(string path) { //1. discard first 12 bytes //2. get layer info //3. read in keyframes //Clear everything in the timeline (prompts to come later) Timeline.resetEverything(true); Canvas zeCanvas = Program.CanvasForm; FileStream file; try { file = File.Open(path, FileMode.Open); } catch { throw new Exception("Failed to load project file. Reason: Unable to open file."); } file.Position += 12; long length = file.Length; List<Layer> layers = new List<Layer>(); Block layer = new Block(); layer.type = ushort.MaxValue; try { while (layer.type != 6 && layer.type != 0) layer = readNextBlock(file); if (layer.type == 6) { try { ushort width = BitConverter.ToUInt16(layer.data, 0); ushort height = BitConverter.ToUInt16(layer.data, 2); Color canColor = Color.FromArgb(layer.data[4], layer.data[5], layer.data[6]); zeCanvas.Size = new Size(width, height); zeCanvas.setBackgroundColor(canColor); } catch { //Do nothing. The parser should attempt to load the rest of the file even if the preferences aren't valid. } } } catch { throw new Exception("Failed to load project file. Reason: No Layer or Preferences block found."); } while (file.Position + 1 < length) { try { layer = readNextBlock(file); } catch { throw new Exception("Failed to load project file. Reason: Unable to read from file."); } if (layer.type != 0) //If it isn't the actual layer type, then skip. continue; byte layerType = layer.data[0]; int nameLength = layer.data[1] + 1; string name = Encoding.UTF8.GetString(layer.data, 2, nameLength); Layer newLayer; Block otherTmpBlock = new Block(); if (layerType == 1) newLayer = new StickLayer(name, new StickFigure(false), zeCanvas); else if (layerType == 2) newLayer = new LineLayer(name, new StickLine(false), zeCanvas); else if (layerType == 3) newLayer = new RectLayer(name, new StickRect(false), zeCanvas); else if (layerType == 4) { newLayer = new CustomLayer(name, new StickCustom(false), zeCanvas); otherTmpBlock = readNextBlock(file); } else if (layerType == 5) newLayer = new LightLayer(name, new LightObject(false), zeCanvas); else if (layerType == 7) { otherTmpBlock = readNextBlock(file); Stream s = new MemoryStream(otherTmpBlock.data); Bitmap b = (Bitmap)Bitmap.FromStream(s); newLayer = new ImageLayer(name, new StickImage(b, false), zeCanvas, b); } else if (layerType == 10) { newLayer = new PolyLayer(name, new StickPoly(false), zeCanvas, 0); } else continue; //Only 1, 2, 3, 4, and 5 have been coded so far, so only load those types. List<KeyFrame> thingy = new List<KeyFrame>(); for (Block tmpBlk = readNextBlock(file);tmpBlk.type != 1;tmpBlk = readNextBlock(file)) { if (tmpBlk.type != 2) continue; KeyFrame f; if (layerType == 1) f = new StickFrame(0); else if (layerType == 2) f = new LineFrame(0); else if (layerType == 3) f = new RectFrame(0); else if (layerType == 4) { f = new custObjectFrame(0); StickCustom figure = CustomFigLoader.loadStickFile(otherTmpBlock.data); //figure.reSortJoints(); //For the love of GOD do not uncomment this!!! for (int i = 0;i < figure.Joints.Count();i++) { if (figure.Joints[i].parent != null) { figure.Joints[i].CalcLength(null); figure.Joints[i].recalcAngleToParent(); } } for (int i = 0;i < figure.Joints.Count();i++) { if (figure.Joints[i].parent != null) { if (!(figure.Joints[i].parent.children.IndexOf(figure.Joints[i]) >= 0)) figure.Joints[i].parent.children.Add(figure.Joints[i]); } figure.Joints[i].ParentFigure = figure; } for (int i = 0;i < figure.Joints.Count;i++) { foreach (StickJoint sj in figure.Joints[i].children) { sj.parent = figure.Joints[i]; } } f.Joints = figure.Joints; newLayer.tweenFig = new StickCustom(true); newLayer.tweenFig.Joints = custObjectFrame.createClone(f.Joints); } else if (layerType == 5) f = new LightFrame(0); else if (layerType == 7) { Stream s = new MemoryStream(otherTmpBlock.data); Bitmap b = (Bitmap)Bitmap.FromStream(s); f = new ImageFrame(0, b); } //TODO: Implement poly saving //else if (layerType == 10) //{ //} else continue; //Nothing past layer type 5 has even begun implementation, so if we encounter any just skip. int kPos = BitConverter.ToInt32(tmpBlk.data, 0); f.pos = kPos; //Read the next block, which contains the other properties of the keyframe, like the colour of the joints. Block propBlock = readNextBlock(file); try { //We can also just skip the keyframe properties totally in case we're loading an older file format. while (propBlock.type != 4 && propBlock.type != 5) propBlock = readNextBlock(file); } catch { throw new Exception("Loading failed. Reason: Unable to load keyframe properties."); } Block posblk = propBlock; Color figColor = Color.Black; int thickness = 0; if (propBlock.type == 4) { //Obtain the colour that's stored in the properties block if (layerType != 4) figColor = Color.FromArgb(propBlock.data[1], propBlock.data[2], propBlock.data[3], propBlock.data[4]); if (layerType == 3) { ((RectFrame)f).figColor = figColor; ((RectFrame)f).filled = BitConverter.ToBoolean(propBlock.data, 4); Color outlineColor = Color.FromArgb(propBlock.data[5], propBlock.data[6], propBlock.data[7], propBlock.data[8]); foreach (StickJoint j in f.Joints) j.color = outlineColor; } //Obtain the joints positions block posblk = readNextBlock(file); //Oh readNextBlock method, how you make my life simpler so } int jointcount = BitConverter.ToUInt16(posblk.data, 0); try { for (int a = 0;a < jointcount;a++) { int x = 8 * a + 2; if (layerType != 4 && layerType != 3) f.Joints[a].color = figColor; f.Joints[a].location = new Point(BitConverter.ToInt16(posblk.data, x), BitConverter.ToInt16(posblk.data, x + 2)); f.Joints[a].thickness = BitConverter.ToInt16(posblk.data, x + 4); f.Joints[a].length = BitConverter.ToInt16(posblk.data, x + 6); } f.figColor = figColor; } catch { //Do nothing. The loader should try to continue loading if it encounters any sort of error here. } foreach (StickJoint x in f.Joints) x.ParentFigure = newLayer.fig; if (layerType == 3) ((StickRect)newLayer.fig).filled = ((RectFrame)f).filled; thingy.Add(f); } newLayer.keyFrames = thingy; newLayer.firstKF = newLayer.keyFrames[0].pos; newLayer.lastKF = newLayer.keyFrames[newLayer.keyFrames.Count - 1].pos; layers.Add(newLayer); } Timeline.layers = layers; Timeline.layer_cnt = layers.Count; Program.MainformForm.doneLoading(); file.Close(); }