//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;
                }
            }
        }
Exemple #2
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;
        }
Exemple #5
0
        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++;
            }
        }