/* * This file is part of NSMB Editor 5. * * NSMB Editor 5 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NSMB Editor 5 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NSMB Editor 5. If not, see . */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; namespace NSMBe4 { public partial class SpriteEditor : UserControl { List SelectedObjects = new List(); private LevelEditorControl EdControl; private byte[] SSTable; private bool updating = false; public string[] spritelist = new string[ROM.SpriteCount]; public List allSprites = new List(); private List curSprites = new List(); public SpriteEditor(LevelEditorControl EdControl) { InitializeComponent(); this.EdControl = EdControl; SSTable = ROM.GetInlineFile(ROM.Data.File_Modifiers); for (int i = 0; i < SpriteData.spriteNames.Count; i++) { int ActorID = (int)ROM.GetClassIDFromTable(i); string sprite = SpriteData.spriteNames[ActorID]; spritelist[i] = i + ": " + sprite; } if (SpriteData.spriteNames.Count == 0) { string spriteText = LanguageManager.Get("SpriteEditor", "sprite"); for (int s = 0; s < ROM.SpriteCount; s++) spritelist[s] = String.Format(spriteText, s); } for (int l = 0; l < ROM.SpriteCount; l++) curSprites.Add(l); categoryList.Items.Add(LanguageManager.Get("SpriteEditor", "All")); categoryList.Items.Add(LanguageManager.Get("SpriteEditor", "InLevel")); categoryList.Items.Add(LanguageManager.Get("SpriteEditor", "InSpriteSets")); foreach (string cat in SpriteData.categories) categoryList.Items.Add(cat); categoryList.SelectedIndex = 0; UpdateDataEditor(); UpdateInfo(); LanguageManager.ApplyToContainer(this, "SpriteEditor"); spriteTypeUpDown.Maximum = ROM.SpriteCount - 1; } private SpriteData.SpriteDataEditor sed; public void SelectObjects(List objs) { SelectedObjects = objs; UpdateInfo(); UpdateDataEditor(); } public void UpdateDataEditor() { if (sed != null) { sed.saveData(null, null); sed.Parent = null; } sed = null; if (SelectedObjects == null) return; int type = getSpriteType(); if (type != -1 && SpriteData.datas.ContainsKey(type)) { sed = new SpriteData.SpriteDataEditor(SelectedObjects, SpriteData.datas[type], EdControl); spriteDataPanel.Controls.Add(sed); sed.Dock = DockStyle.Fill; //sed.Parent = spriteDataPanel; spriteDataPanel.Visible = true; } else { spriteDataPanel.Visible = false; } } public void RefreshDataEditor() { if (sed != null) sed.UpdateData(); } public void UpdateInfo() { if (SelectedObjects == null || SelectedObjects.Count == 0) { tableLayoutPanel1.Visible = false; spriteDataPanel.Visible = false; return; } tableLayoutPanel1.Visible = true; spriteDataPanel.Visible = true; updating = true; int type = getSpriteType(); spriteTypeUpDown.Value = type > -1 ? type : 0; byte[] SpriteData = (SelectedObjects[0] as NSMBSprite).Data; spriteDataTextBox.Text = String.Format( "{0:X2} {1:X2} {2:X2} {3:X2} {4:X2} {5:X2}", SpriteData[0], SpriteData[1], SpriteData[2], SpriteData[3], SpriteData[4], SpriteData[5]); spriteDataTextBox.BackColor = SystemColors.Window; spriteListBox.SelectedIndex = curSprites.IndexOf(type); updating = false; } private void spriteTypeUpDown_ValueChanged(object sender, EventArgs e) { if (updating) return; EdControl.UndoManager.Do(new ChangeSpriteTypeAction(SelectedObjects, (int)spriteTypeUpDown.Value), true); } private void spriteListBox_SelectedIndexChanged(object sender, EventArgs e) { if (updating) return; if (spriteListBox.SelectedIndex > -1) spriteTypeUpDown.Value = curSprites[spriteListBox.SelectedIndex]; } private void spriteListBox_DrawItem(object sender, DrawItemEventArgs e) { e.DrawBackground(); Color TextColor, BackColor = e.BackColor; if (spriteListBox.Items.Count > 0 && e.Index > -1) { if (EdControl.Level.ValidSprites[curSprites[e.Index]]) { TextColor = e.ForeColor; } else { TextColor = Color.DarkRed; if ((e.State & DrawItemState.Selected) != DrawItemState.None) { TextColor = Color.White; BackColor = Color.DarkRed; SolidBrush b = new SolidBrush(BackColor); e.Graphics.FillRectangle(b, e.Bounds); b.Dispose(); } } TextRenderer.DrawText(e.Graphics, (string)spriteListBox.Items[e.Index], spriteListBox.Font, e.Bounds, TextColor, BackColor, TextFormatFlags.Left); int SSNumber = SSTable[curSprites[e.Index] << 1]; int SSValue = SSTable[(curSprites[e.Index] << 1) + 1]; string txt = (SSNumber + 1) + "-" + SSValue; if (SSValue == 0) txt = "-"; TextRenderer.DrawText(e.Graphics, txt, spriteListBox.Font, new Rectangle(e.Bounds.X +e.Bounds.Width - 30, e.Bounds.Y, 30, e.Bounds.Height), TextColor, BackColor, TextFormatFlags.Right); } } private void spriteDataTextBox_TextChanged(object sender, EventArgs e) { if (updating || !spriteDataTextBox.Visible) return; // validate if (System.Text.RegularExpressions.Regex.IsMatch( spriteDataTextBox.Text, "^[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *[0-9a-f] *$", System.Text.RegularExpressions.RegexOptions.IgnoreCase)) { string parseit = spriteDataTextBox.Text.Replace(" ", ""); byte[] data = new byte[6]; for (int hexidx = 0; hexidx < 6; hexidx++) data[hexidx] = byte.Parse(parseit.Substring(hexidx*2, 2), System.Globalization.NumberStyles.AllowHexSpecifier); if (!updating) EdControl.UndoManager.Do(new ChangeSpriteDataAction(SelectedObjects, data)); spriteDataTextBox.BackColor = SystemColors.Window; } else spriteDataTextBox.BackColor = Color.Coral; } private void textBox1_TextChanged(object sender, EventArgs e) { curSprites.Clear(); for (int l = 0; l < allSprites.Count; l++) { if (spritelist[allSprites[l]].ToLowerInvariant().Contains(searchBox.Text.ToLowerInvariant())) curSprites.Add(allSprites[l]); } spriteListBox.Items.Clear(); List items = new List(); for (int l = 0; l < curSprites.Count; l++) items.Add(spritelist[curSprites[l]]); spriteListBox.Items.AddRange(items.ToArray()); spriteListBox.SelectedIndex = curSprites.IndexOf(getSpriteType()); if (curSprites.Count > 0) searchBox.BackColor = SystemColors.Window; else searchBox.BackColor = Color.Coral; } private int getSpriteType() { int type = -1; foreach (LevelItem obj in SelectedObjects) if (obj is NSMBSprite) { NSMBSprite s = obj as NSMBSprite; if (type == -1) type = s.Type; if (type != s.Type) return -1; } return type; } private void clearSearch_Click(object sender, EventArgs e) { searchBox.Text = ""; } private void clearSpriteData_Click(object sender, EventArgs e) { byte[] emptyData = new byte[6]; EdControl.UndoManager.Do(new ChangeSpriteDataAction(SelectedObjects, emptyData)); } public int getSelectedType() { if (spriteListBox.SelectedIndex == -1) { // Fix for this http://nsmbhd.net/post/39505/ if (SelectedObjects.Count > 0 && SelectedObjects[0] is NSMBSprite) { return (SelectedObjects[0] as NSMBSprite).Type; } return -1; } return curSprites[spriteListBox.SelectedIndex]; } private void categoryList_SelectedIndexChanged(object sender, EventArgs e) { allSprites.Clear(); switch (categoryList.SelectedIndex) { case 0: for (int i = 0; i < ROM.SpriteCount; i++) allSprites.Add(i); break; case 1: foreach (NSMBSprite s in EdControl.Level.Sprites) if (!allSprites.Contains(s.Type)) allSprites.Add(s.Type); break; case 2: for (int i = 0; i < ROM.SpriteCount; i++) if (EdControl.Level.ValidSprites[i]) allSprites.Add(i); break; default: foreach (int spriteId in SpriteData.spritesInCategory[SpriteData.categoryIds[categoryList.SelectedIndex - 3]]) allSprites.Add(spriteId); break; } textBox1_TextChanged(sender, e); } } }