//ask for save before quitting private void BetterTextureAnimationEditor_FormClosing(object sender, FormClosingEventArgs e) { int unsavedAnims = 0; foreach (Dictionary <string, LevelTexAnim.Def> areaEntries in m_unsavedEntries) { unsavedAnims += areaEntries.Count; } if (unsavedAnims == 0) { return; } DialogResult result = MessageBox.Show(this, unsavedAnims + " files are unsaved, would you like to save them?", "Save before quitting", MessageBoxButtons.YesNoCancel); if (result == DialogResult.Yes) { SaveAll(); } else if (result == DialogResult.Cancel) { e.Cancel = true; } for (int area = 0; area < m_parent.m_Level.m_TexAnims.Count; area++) { LevelTexAnim animation = m_parent.m_Level.m_TexAnims[area]; if (animation.m_NumDefs == 0) { animation.m_NumFrames = 0; } } }
public void SaveChanges() { //using a MemoryStream instead of an INitroROMBlock for dynamic size MemoryStream stream = new MemoryStream(); BinaryWriter binWriter = new BinaryWriter(stream); byte overlayInitialiserVersion = 0; switch (Program.m_ROM.m_Version) { case NitroROM.Version.EUR: binWriter.Write(Properties.Resources.level_ovl_init_EUR_001); overlayInitialiserVersion = 1; break; case NitroROM.Version.USA_v1: binWriter.Write(Properties.Resources.level_ovl_init_USAv1); break; case NitroROM.Version.USA_v2: binWriter.Write(Properties.Resources.level_ovl_init_USAv2); break; case NitroROM.Version.JAP: binWriter.Write(Properties.Resources.level_ovl_init_JAP); break; default: throw new InvalidDataException("This ROM is an unknown version."); } m_LevelSettings.LevelFormatVersion = k_LevelFormatVersion; m_LevelSettings.OverlayInitialiserVersion = overlayInitialiserVersion; uint areaTableOffset; m_LevelSettings.SaveChanges(binWriter); SaveCLPS(binWriter); SaveMiscObjs(binWriter); SaveRegularObjs(binWriter, out areaTableOffset); LevelTexAnim.SaveAll(binWriter, m_TexAnims, areaTableOffset, (uint)m_NumAreas); if (DoesLevelSupportDynamicLibs()) { while (stream.Position % 2 != 0) { binWriter.Write((byte)0); } Helper.WritePosAndRestore(binWriter, 0x30, 0); binWriter.Write((ushort)m_DynLibIDs.Count); m_DynLibIDs.ForEach(x => binWriter.Write((ushort)x)); Helper.AlignWriter(binWriter, 4); } Array.Clear(m_Overlay.m_Data, 0, m_Overlay.m_Data.Length); Array.Resize(ref m_Overlay.m_Data, (int)stream.Length); stream.Position = 0; new BinaryReader(stream).Read(m_Overlay.m_Data, 0, (int)stream.Length); m_Overlay.SaveChanges(); }
private void UpdateAnimation() { if (m_animEntry != null) { m_translationX = LevelTexAnim.AnimationValue(m_animEntry.m_TranslationXValues, m_texAnimFrame, (int)m_animations[m_animId].m_NumFrames); m_translationY = LevelTexAnim.AnimationValue(m_animEntry.m_TranslationYValues, m_texAnimFrame, (int)m_animations[m_animId].m_NumFrames); m_rotation = LevelTexAnim.AnimationValue(m_animEntry.m_RotationValues, m_texAnimFrame, (int)m_animations[m_animId].m_NumFrames); m_scale = LevelTexAnim.AnimationValue(m_animEntry.m_ScaleValues, m_texAnimFrame, (int)m_animations[m_animId].m_NumFrames); } if (valueSettingPanel2.Visible) { if ((AnimationProperty)cbSelectProperty.SelectedIndex == AnimationProperty.TRANSLATION_X) { m_translationX = InterpolatedValue(m_keyFrames, m_texAnimFrame) * (float)numScaling.Value; } else if ((AnimationProperty)cbSelectProperty.SelectedIndex == AnimationProperty.TRANSLATION_Y) { m_translationY = InterpolatedValue(m_keyFrames, m_texAnimFrame) * (float)numScaling.Value; } else if ((AnimationProperty)cbSelectProperty.SelectedIndex == AnimationProperty.ROTATION) { m_rotation = InterpolatedValue(m_keyFrames, m_texAnimFrame) * (float)numScaling.Value; } else if ((AnimationProperty)cbSelectProperty.SelectedIndex == AnimationProperty.SCALE) { m_scale = InterpolatedValue(m_keyFrames, m_texAnimFrame) * (float)numScaling.Value; } } m_texAnimFrame %= (int)m_animations[m_animId].m_NumFrames; m_timelineFrame = m_texAnimFrame % 120; m_timelinePart = (m_texAnimFrame / 120) % m_timelineParts; if (!m_texAnimTimer.Enabled) { //decide which buttons should be disabled btnStepLeft.Enabled = (m_texAnimFrame > 0); btnStepRight.Enabled = true; btnPrevPart.Enabled = (m_timelinePart > 0); btnNextPart.Enabled = (m_timelinePart < m_timelineParts); if (m_animEntry != null) { m_settingValue = true; numValue.Value = (decimal)m_animationValues[Math.Min(m_animationValues.Count - 1, m_texAnimFrame)]; m_settingValue = false; } if (valueSettingPanel2.Visible) { m_settingKeyframeValue = true; numKeyframeValue.Value = (decimal)InterpolatedValue(m_keyFrames, m_texAnimFrame); m_settingKeyframeValue = false; btnDeleteKeyframe.Enabled = m_keyFrames.ContainsKey(m_texAnimFrame); } } textureView.Refresh(); timelinePanel.Refresh(); }
private void btnDeleteAnimData_Click(object sender, EventArgs e) { TreeNode selected = tvMaterials.SelectedNode; int area = (int)selected.Tag; LevelTexAnim texAnim = m_parent.m_Level.m_TexAnims[area]; texAnim.m_Defs = new List <LevelTexAnim.Def>(); texAnim.m_NumFrames = 0; selected.Nodes.Clear(); selected.Text = "Area " + area + " (0 frames)"; btnDeleteAnimData.Enabled = false; }
protected virtual void ReadTextureAnimationArea(XmlReader reader, Level level) { int area = int.Parse(reader.GetAttribute("area")); List <LevelTexAnim> texAnimsForArea = level.m_TexAnims.Where(t => t.m_Area == area).ToList(); LevelTexAnim texAnimArea; if (texAnimsForArea.Count < 1) { texAnimArea = new LevelTexAnim(area); level.m_TexAnims.Add(texAnimArea); } else { texAnimArea = texAnimsForArea[0]; } List <float> scales = new List <float>(); List <float> rotations = new List <float>(); List <float> translations = new List <float>(); while (reader.Read()) { reader.MoveToContent(); if (reader.NodeType.Equals(XmlNodeType.Element) && reader.LocalName.Equals("NumberOfFrames")) { texAnimArea.m_NumFrames = (uint)reader.ReadElementContentAsInt(); } else if (reader.NodeType.Equals(XmlNodeType.Element) && reader.LocalName.Equals("ScaleTable")) { scales = ReadTextureAnimationScaleTable(reader); } else if (reader.NodeType.Equals(XmlNodeType.Element) && reader.LocalName.Equals("RotationTable")) { rotations = ReadTextureAnimationRotationTable(reader); } else if (reader.NodeType.Equals(XmlNodeType.Element) && reader.LocalName.Equals("TranslationTable")) { translations = ReadTextureAnimationTranslationTable(reader); } else if (reader.NodeType.Equals(XmlNodeType.Element) && reader.LocalName.Equals("TextureAnimation")) { texAnimArea.m_Defs.Add(ReadTextureAnimation(reader, scales, rotations, translations)); } else if (reader.NodeType.Equals(XmlNodeType.EndElement) && reader.LocalName.Equals("TextureAnimationArea")) { break; } } }
private void RefreshLbx() { if (lbxArea.SelectedIndex < 0) { return; } LevelTexAnim texAnim = m_Level.m_TexAnims[lbxArea.SelectedIndex]; if (lbxTexAnim.SelectedIndex < 0) { ClearFormFields(); return; } LevelTexAnim.Def texAnimDef = texAnim.m_Defs[lbxTexAnim.SelectedIndex]; txtMaterialName.Text = texAnimDef.m_MaterialName; txtNumFrames.Text = texAnim.m_NumFrames.ToString(); lbxScaleValues.Items.Clear(); for (int i = 0; i < texAnimDef.m_ScaleValues.Count; i++) { lbxScaleValues.Items.Add("Scale value " + i.ToString("D4")); } lbxRotationValues.Items.Clear(); for (int i = 0; i < texAnimDef.m_RotationValues.Count; i++) { lbxRotationValues.Items.Add("Rotation value " + i.ToString("D4")); } lbxTranslationXValues.Items.Clear(); for (int i = 0; i < texAnimDef.m_TranslationXValues.Count; i++) { lbxTranslationXValues.Items.Add("Translation X value " + i.ToString("D4")); } lbxTranslationYValues.Items.Clear(); for (int i = 0; i < texAnimDef.m_TranslationYValues.Count; i++) { lbxTranslationYValues.Items.Add("Translation Y value " + i.ToString("D4")); } txtScaleLength.Text = texAnimDef.m_NumScaleValues.ToString(); txtRotationLength.Text = texAnimDef.m_NumRotationValues.ToString(); txtTranslationXLength.Text = texAnimDef.m_NumTranslationXValues.ToString(); txtTranslationYLength.Text = texAnimDef.m_NumTranslationYValues.ToString(); }
private void StopAnimation() { m_texAnimTimer.Stop(); m_texAnimTimer.Enabled = false; m_texAnimFrame = 0; if (m_animEntry != null) { m_translationX = LevelTexAnim.AnimationValue(m_animEntry.m_TranslationXValues, 0, 0); m_translationY = LevelTexAnim.AnimationValue(m_animEntry.m_TranslationYValues, 0, 0); m_rotation = LevelTexAnim.AnimationValue(m_animEntry.m_RotationValues, 0, 0); m_scale = LevelTexAnim.AnimationValue(m_animEntry.m_ScaleValues, 0, 0); } else { m_translationX = 0; m_translationY = 0; m_rotation = 0; m_scale = 1; } SetupGUIForPauseMode(); UpdateAnimation(); }
//---CONSTRUCTOR--- public BetterTextureAnimationEditor(LevelEditorForm parent) { //setup GUI InitializeComponent(); typeof(Panel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, textureView, new object[] { true }); typeof(Panel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, timelinePanel, new object[] { true }); InitTimer(); textureView.MouseWheel += textureView_MouseWheel; numScaling.Tag = 1; valueSettingPanel2.Location = valueSettingPanel1.Location; valueSettingPanel1.BringToFront(); //set private values m_parent = parent; m_BMD = m_parent.m_LevelModel; m_previewTexture = new Bitmap(64, 64); m_animId = 0; m_animations = new List <LevelTexAnim>(); //load Animations m_unsavedEntries = new Dictionary <string, LevelTexAnim.Def> [m_BMD.m_ModelChunks.Length]; m_entries = new Dictionary <string, LevelTexAnim.Def>(); int i = 0; foreach (BMD.ModelChunk chunk in m_BMD.m_ModelChunks) { LevelTexAnim animForArea = m_parent.m_Level.m_TexAnims[i]; TreeNode chunkNode = tvMaterials.Nodes.Add(chunk.m_Name, "Area " + i + " (" + m_parent.m_Level.m_TexAnims[i].m_NumFrames + " frames)"); chunkNode.Tag = i; m_unsavedEntries[i] = new Dictionary <string, LevelTexAnim.Def>(); m_animations.Add(animForArea); List <LevelTexAnim.Def> newEntries = new List <LevelTexAnim.Def>(); foreach (LevelTexAnim.Def entry in animForArea.m_Defs) { LevelTexAnim.Def newEntry = new LevelTexAnim.Def() { m_DefaultScale = entry.m_DefaultScale, m_MaterialName = entry.m_MaterialName, m_TranslationXValues = new List <float>(entry.m_TranslationXValues), m_TranslationYValues = new List <float>(entry.m_TranslationYValues), m_RotationValues = new List <float>(entry.m_RotationValues), m_ScaleValues = new List <float>(entry.m_ScaleValues), }; m_entries.Add(entry.m_MaterialName, newEntry); } if (animForArea.m_NumFrames > 0) { //populate AnimationNode int i2 = 0; foreach (BMD.MaterialGroup matGroup in chunk.m_MatGroups) { if (matGroup.m_Texture != null) { bool hasAnimation = false; foreach (LevelTexAnim.Def entry in m_animations[i].m_Defs) { if (entry.m_MaterialName == matGroup.m_Name) { hasAnimation = true; } } TreeNode matGroupNode = chunkNode.Nodes.Add(matGroup.m_Name, matGroup.m_Name + (hasAnimation ? "[ANIMATED]" : "")); matGroupNode.Tag = i2; } i2++; } } i++; } }