From fa96af12436c6f2d31527758e64fb5d1bb799567 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:26:03 +0100 Subject: [PATCH 01/16] fix: tiles cannot be placed in TTE when shift is applied fix #69 --- mage/Controls/TileTableTooltip.cs | 9 +++++---- mage/Editors/NewEditors/FormTileTableNew.cs | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mage/Controls/TileTableTooltip.cs b/mage/Controls/TileTableTooltip.cs index 0939626..fb6e378 100644 --- a/mage/Controls/TileTableTooltip.cs +++ b/mage/Controls/TileTableTooltip.cs @@ -17,10 +17,11 @@ public class TileTableTooltip : ToolTip public Image TileGFX { get; set; } = null; public Point PositionOnImage = new Point(-1, -1); public ushort TileVal = 0; - public int TileID => TileVal & 0x3FF; + public int TileID => TileVal - Shift & 0x3FF; public int TilePal => TileVal >> 12; public bool FlipH => (TileVal & 0x400) != 0; public bool FlipV => (TileVal & 0x800) != 0; + public int Shift = 0; public TileTableTooltip() { @@ -67,7 +68,7 @@ private void TileTableTooltip_Draw(object? sender, DrawToolTipEventArgs e) // Title text g.DrawString(caption, captionFont, textBrush, drawLocation); drawLocation.Y += (int)captionSize.Height + margin; - + // Tile ID g.DrawString($"ID:\t {Hex.ToString(TileID)}", regularFont, textBrush, drawLocation); drawLocation.Y += regularHeight + margin; @@ -90,8 +91,8 @@ private void TileTableTooltip_Draw(object? sender, DrawToolTipEventArgs e) // Draw actual Tile g.InterpolationMode = InterpolationMode.NearestNeighbor; g.DrawImage( - TileGFX, - new Rectangle(drawLocation.X + vArrow.Width + 1, drawLocation.Y + hArrow.Height + 1, previewSize, previewSize), + TileGFX, + new Rectangle(drawLocation.X + vArrow.Width + 1, drawLocation.Y + hArrow.Height + 1, previewSize, previewSize), new Rectangle(PositionOnImage.X, PositionOnImage.Y, 7, 7), GraphicsUnit.Pixel ); } diff --git a/mage/Editors/NewEditors/FormTileTableNew.cs b/mage/Editors/NewEditors/FormTileTableNew.cs index 3700a6a..4e048ce 100644 --- a/mage/Editors/NewEditors/FormTileTableNew.cs +++ b/mage/Editors/NewEditors/FormTileTableNew.cs @@ -242,7 +242,7 @@ private void SelectTilesFromGFX() for (int y = 0; y < height; y++) { // Get number for current tile - int gfxNum = (GfxSelection.X / 8 + x) + ((GfxSelection.Y / 8 + y) * 32); + int gfxNum = (GfxSelection.X / 8 + x) + ((GfxSelection.Y / 8 + y) * 32) + (int)numericUpDown_shift.Value & 0x3FF; //Apply current palette if (CopyPalette) gfxNum |= (comboBox_palette.SelectedIndex << 12); selectedTiles[x, y] = (ushort)gfxNum; @@ -1021,6 +1021,7 @@ private void tab_select_SelectedIndexChanged(object sender, EventArgs e) oldSelectedTab = tab_select.SelectedIndex; Reset(); + numericUpDown_shift.Value = 0; if (openedInRoom == null) return; if (selectedTab == Tab.Tileset) { @@ -1259,6 +1260,7 @@ private void tableView_TileMouseMove(object sender, TileDisplay.TileDisplayArgs { TileTip.TileGFX = tableView.TileImage; TileTip.TileVal = tileTable[GetIndexFromLocation(e.TileIndexPosition.X, e.TileIndexPosition.Y)]; + TileTip.Shift = (int)numericUpDown_shift.Value; TileTip.PositionOnImage = e.TilePixelPosition; } From 8217711a1c498adfd43e4bab31f39a702850d842 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:09:47 +0100 Subject: [PATCH 02/16] fix: testing a room sometimes selects tourian in the area selector fix #47 --- mage/Controls/ExtendedPanel.cs | 6 ++++++ mage/FormMain.Designer.cs | 32 ++++++++++++++++---------------- mage/RoomView.cs | 7 +++++++ 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/mage/Controls/ExtendedPanel.cs b/mage/Controls/ExtendedPanel.cs index bc551bb..23b24c1 100644 --- a/mage/Controls/ExtendedPanel.cs +++ b/mage/Controls/ExtendedPanel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -26,4 +27,9 @@ protected override void OnMouseWheel(MouseEventArgs e) } base.OnMouseWheel(e); } + + protected override Point ScrollToControl(Control activeControl) + { + return this.AutoScrollPosition; + } } diff --git a/mage/FormMain.Designer.cs b/mage/FormMain.Designer.cs index 961a904..d60dc74 100644 --- a/mage/FormMain.Designer.cs +++ b/mage/FormMain.Designer.cs @@ -35,6 +35,7 @@ private void InitializeComponent() menuItem_openROM = new System.Windows.Forms.ToolStripMenuItem(); menuItem_saveROM = new System.Windows.Forms.ToolStripMenuItem(); menuItem_saveROMas = new System.Windows.Forms.ToolStripMenuItem(); + btn_saveCompiled = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); menuItem_createBackup = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); @@ -278,7 +279,6 @@ private void InitializeComponent() comboBox_spriteset = new mage.Theming.CustomControls.FlatComboBox(); ToolTip = new System.Windows.Forms.ToolTip(components); splitContainer1 = new System.Windows.Forms.SplitContainer(); - btn_saveCompiled = new System.Windows.Forms.ToolStripMenuItem(); menuStrip.SuspendLayout(); groupBox_location.SuspendLayout(); groupBox_tileset.SuspendLayout(); @@ -344,6 +344,16 @@ private void InitializeComponent() menuItem_saveROMas.Text = "Save ROM as..."; menuItem_saveROMas.Click += menuItem_saveROMAs_Click; // + // btn_saveCompiled + // + btn_saveCompiled.Image = Properties.Resources.script_code_red; + btn_saveCompiled.Name = "btn_saveCompiled"; + btn_saveCompiled.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.C; + btn_saveCompiled.Size = new System.Drawing.Size(232, 22); + btn_saveCompiled.Text = "Compile ROM..."; + btn_saveCompiled.Visible = false; + btn_saveCompiled.Click += btn_saveCompiled_Click; + // // toolStripSeparator5 // toolStripSeparator5.Name = "toolStripSeparator5"; @@ -374,14 +384,14 @@ private void InitializeComponent() // menuItem_clearRecentFiles // menuItem_clearRecentFiles.Name = "menuItem_clearRecentFiles"; - menuItem_clearRecentFiles.Size = new System.Drawing.Size(180, 22); + menuItem_clearRecentFiles.Size = new System.Drawing.Size(101, 22); menuItem_clearRecentFiles.Text = "Clear"; menuItem_clearRecentFiles.Click += menuItem_clearRecentFiles_Click; // // toolStripSeparator22 // toolStripSeparator22.Name = "toolStripSeparator22"; - toolStripSeparator22.Size = new System.Drawing.Size(177, 6); + toolStripSeparator22.Size = new System.Drawing.Size(98, 6); // // menuStrip_edit // @@ -1399,7 +1409,7 @@ private void InitializeComponent() comboBox_room.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); comboBox_room.Name = "comboBox_room"; comboBox_room.Size = new System.Drawing.Size(73, 23); - comboBox_room.TabIndex = 10; + comboBox_room.TabIndex = 1; comboBox_room.SelectedIndexChanged += comboBox_room_SelectedIndexChanged; comboBox_room.KeyPress += comboBox_KeyPress; // @@ -1411,7 +1421,7 @@ private void InitializeComponent() comboBox_area.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); comboBox_area.Name = "comboBox_area"; comboBox_area.Size = new System.Drawing.Size(73, 23); - comboBox_area.TabIndex = 9; + comboBox_area.TabIndex = 0; comboBox_area.SelectedIndexChanged += comboBox_area_SelectedIndexChanged; // // label_room @@ -2372,19 +2382,9 @@ private void InitializeComponent() splitContainer1.Size = new System.Drawing.Size(799, 424); splitContainer1.SplitterDistance = 299; splitContainer1.SplitterWidth = 3; - splitContainer1.TabIndex = 12; + splitContainer1.TabIndex = 0; splitContainer1.SplitterMoved += splitContainer1_SplitterMoved; // - // btn_saveCompiled - // - btn_saveCompiled.Image = Properties.Resources.script_code_red; - btn_saveCompiled.Name = "btn_saveCompiled"; - btn_saveCompiled.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.C; - btn_saveCompiled.Size = new System.Drawing.Size(232, 22); - btn_saveCompiled.Text = "Compile ROM..."; - btn_saveCompiled.Visible = false; - btn_saveCompiled.Click += btn_saveCompiled_Click; - // // FormMain // AllowDrop = true; diff --git a/mage/RoomView.cs b/mage/RoomView.cs index a0619cf..1fedb3d 100644 --- a/mage/RoomView.cs +++ b/mage/RoomView.cs @@ -1,4 +1,5 @@ using System; +using System.Configuration; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; @@ -273,5 +274,11 @@ protected override void OnMouseWheel(MouseEventArgs e) Scrolled.Invoke(this, e); base.OnMouseWheel(e); } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + if (!this.Focused) this.Focus(); + } } } From ac506d251120f2e9dfa8fe557bec94f7d46bca3c Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Tue, 17 Feb 2026 22:16:49 +0100 Subject: [PATCH 03/16] tweak applying works --- mage/FormMain.cs | 6 + mage/Tweaks/FormTweaks.Designer.cs | 47 +++++++ mage/Tweaks/FormTweaks.cs | 21 ++++ mage/Tweaks/FormTweaks.resx | 195 +++++++++++++++++++++++++++++ mage/Tweaks/Tweak.cs | 99 +++++++++++++++ mage/Tweaks/TweakManager.cs | 11 ++ mage/Tweaks/TweakParameter.cs | 14 +++ mage/Tweaks/TweakPatch.cs | 45 +++++++ mage/mage.csproj | 1 + 9 files changed, 439 insertions(+) create mode 100644 mage/Tweaks/FormTweaks.Designer.cs create mode 100644 mage/Tweaks/FormTweaks.cs create mode 100644 mage/Tweaks/FormTweaks.resx create mode 100644 mage/Tweaks/Tweak.cs create mode 100644 mage/Tweaks/TweakManager.cs create mode 100644 mage/Tweaks/TweakParameter.cs create mode 100644 mage/Tweaks/TweakPatch.cs diff --git a/mage/FormMain.cs b/mage/FormMain.cs index b91b0a3..512e38e 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -11,6 +11,7 @@ using mage.Properties; using mage.Theming; using mage.Tools; +using mage.Tweaks; using mage.Updates; using mage.Utility; using Microsoft.Win32; @@ -1563,6 +1564,11 @@ private void InitializePart2() NewRomLoaded?.Invoke(this, null); Sound.PlaySound("load.wav"); + + // TEST REMOVE PLEASE + string json = "{\"Name\": \"Chozo Statue Flip\",\"Author\": \"Biospark\",\"Description\": \"Flips Chozo Statue\",\"Parameters\": [ {\"Name\": \"spriteID\",\"Description\": \"Sprite ID of the Chozo Statue that gets flipped\",\"Value\": 35},{\"Name\": \"flip\",\"Description\": \"0xDC for left, 0xD4 for right\",\"Value\": 220}],\"Patches\": [{\"Offset\": \"0x13C08 + (spriteID - 0x22) * 0x4\",\"Data\": [\"flip\"]}]}"; + Tweak t = JsonSerializer.Deserialize(json); + t.Apply(ROM.Stream); } private void EnableControls(bool val) diff --git a/mage/Tweaks/FormTweaks.Designer.cs b/mage/Tweaks/FormTweaks.Designer.cs new file mode 100644 index 0000000..a07f796 --- /dev/null +++ b/mage/Tweaks/FormTweaks.Designer.cs @@ -0,0 +1,47 @@ +namespace mage.Tweaks +{ + partial class FormTweaks + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormTweaks)); + SuspendLayout(); + // + // FormTweaks + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(800, 450); + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + Name = "FormTweaks"; + Text = "Tweaks"; + ResumeLayout(false); + } + + #endregion + } +} \ No newline at end of file diff --git a/mage/Tweaks/FormTweaks.cs b/mage/Tweaks/FormTweaks.cs new file mode 100644 index 0000000..029f3ca --- /dev/null +++ b/mage/Tweaks/FormTweaks.cs @@ -0,0 +1,21 @@ +using mage.Theming; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace mage.Tweaks; + +public partial class FormTweaks : Form +{ + public FormTweaks() + { + InitializeComponent(); + + ThemeSwitcher.ChangeTheme(Controls, this); + ThemeSwitcher.InjectPaintOverrides(Controls); + } +} diff --git a/mage/Tweaks/FormTweaks.resx b/mage/Tweaks/FormTweaks.resx new file mode 100644 index 0000000..c3147e2 --- /dev/null +++ b/mage/Tweaks/FormTweaks.resx @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAIAEBAAAAAAGABoAwAAJgAAACAgAAAAABgAqAwAAI4DAAAoAAAAEAAAACAAAAABABgAAAAAAAAD + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUCgwUCgwUCgwUCgwAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAUCgwUCgwACjoACCwABhwUCgwUCgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUCgw + YHhAACjoUCgwACjosMiQsMiQYHhAUCgwUCgwAAAAAAAAAAAAAAAAAAAAAAAAUCgwsMiQABhwsMiQACjo + ACjosMiQ+Pj4sMiQsMiQACCwUCgwUCgwAAAAAAAAAAAAYHhAABhwcPgAcPgAcPgAYHhAACjoACCwsMiQ + sMiQACCwACCwICBAICBAAAAAAAAAABhwYHhAcPgA+Pj4cPgAcPgAUCgwACjoABhwACjoICBAICBAAMD4 + ICBAAAAAAAAAABhwcPgA+Pj4+Pj4cPgAcPgAUCgwACjoICBAICBAAMD4AMD4AJDoICBAAAAAAAAAUCgw + cPgA+Pj4+Pj4cPgAcPgAYHhAICBAAMD4AMD4AJDoAJDoICBAAAAAAAAAAAAAUCgwYHhAcPgAYHhAcPgA + ICBAICBAMPj4AJDoAJDoAJDoICBAAAAAAAAAAAAAAAAAUCgwABhwYHhAICBAICBAAMD4MPj4AJDoAJDo + ACAwACAwICBAAAAAAAAAAAAAAAAAAAAAICBAICBAAMD4AMD4MPj4MPj4ACAwACAwACAwGGC4ICBAAAAA + AAAAAAAAAAAAICBAAMD4MPj4MPj4MPj4MPj4GGC4ACAwGGC4AJDoGGC4GGC4ICBAAAAAAAAAICBAAMD4 + MPj4MPj4MPj4AJDoGGC4GGC4AMD4MPj4AMD4GGC4GGC4GGC4ICBAAAAAAAAAICBAICBAICBAICBAICBA + GGC4AMD4MPj4MPj4AJDoAJDoAMD4AMD4AJDoICBAAAAAAAAAAAAAAAAAAAAAAAAAICBAICBAMPj4MPj4 + MPj4AMD4AJDoGGC4ICBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICBAICBAICBAICBAICBAICBA + AAAAAAAA8P8AAMB/AACAHwAAgAMAAIABAACAAQAAgAEAAIADAACABwAAgAcAAMAHAACAAwAAAAEAAIAA + AAD8AQAA/wMAACgAAAAgAAAAQAAAAAEAGAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABQKDBQKDBQKDBQKDBQKDBQKDBQKDBQKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQKDBQKDBQKDBQ + KDBQKDBQKDBQKDBQKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAABQKDBQKDBQKDBQKDAaMsAaMsAAILAAILAAGHAAGHBQKDBQKDBQKDBQKDAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQKDBQKDBQKDBQ + KDAaMsAaMsAAILAAILAAGHAAGHBQKDBQKDBQKDBQKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAABQKDBQKDBgeEBgeEAaNdIaNdJQKDBQKDAAKOgAKOiwyJCwyJCwyJCw + yJBgeEBgeEBQKDBQKDBQKDBQKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQKDBQ + KDBgeEBgeEAaNdIaNdJQKDBQKDAAKOgAKOiwyJCwyJCwyJCwyJBgeEBgeEBQKDBQKDBQKDBQKDAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQKDBQKDCwyJCwyJAAGHAAGHCwyJCwyJAAKOgA + KOgAKOgAKOiwyJCwyJD4+Pj4+PiwyJCwyJCwyJCwyJAAILAAILBQKDBQKDBQKDBQKDAAAAAAAAAAAAAA + AAAAAAAAAABQKDBQKDCwyJCwyJAAGHAAGHCwyJCwyJAAKOgAKOgAKOgAKOiwyJCwyJD4+Pj4+PiwyJCw + yJCwyJCwyJAAILAAILBQKDBQKDBQKDBQKDAAAAAAAAAAAAAAAAAAAAAAAABPbkVPbkUAGHAAGHBw+ABw + +ABw+ABw+ABw+ABw+ABgeEBgeEAAKOgAKOgAILAAILCwyJCwyJCwyJCwyJAAILAAILAAILAAILAgIEAg + IEAgIEAgIEAAAAAAAAAAAAAAAABPbkVPbkUAGHAAGHBw+ABw+ABw+ABw+ABw+ABw+ABgeEBgeEAAKOgA + KOgAILAAILCwyJCwyJCwyJCwyJAAILAAILAAILAAILAgIEAgIEAgIEAgIEAAAAAAAAAAAAAAAAAAGHAA + GHBjeVdjeVdw+ABw+AD4+Pj4+Phw+ABw+ABw+ABw+ABQKDBQKDAAKOgAKOgAGHAAGHAAKOgAKOggIEAg + IEAgIEAgIEAAwPgAwPggIEAgIEAAAAAAAAAAAAAAAAAAGHAAGHBjeVdjeVdw+ABw+AD4+Pj4+Phw+ABw + +ABw+ABw+ABQKDBQKDAAKOgAKOgAGHAAGHAAKOgAKOggIEAgIEAgIEAgIEAAwPgAwPggIEAgIEAAAAAA + AAAAAAAAAAAAGHAAGHBw+ABw+AD4+Pj4+Pj4+Pj4+Phw+ABw+ABw+ABw+ABQKDBQKDAAKOgAKOggIEAg + IEAgIEAgIEAAwPgAwPgAwPgAwPgAkOgAkOggIEAgIEAAAAAAAAAAAAAAAAAAGHAAGHBw+ABw+AD4+Pj4 + +Pj4+Pj4+Phw+ABw+ABw+ABw+ABQKDBQKDAAKOgAKOggIEAgIEAgIEAgIEAAwPgAwPgAwPgAwPgAkOgA + kOggIEAgIEAAAAAAAAAAAAAAAABQKDBQKDBw+ABw+AD4+Pj4+Pj4+Pj4+Phw+ABw+ABw+ABw+ABgeEBg + eEAgIEAgIEAAwPgAwPgAwPgAwPgAkOgAkOgAkOgAkOggIEAgIEAAAAAAAAAAAAAAAAAAAAAAAABQKDBQ + KDBw+ABw+AD4+Pj4+Pj4+Pj4+Phw+ABw+ABw+ABw+ABgeEBgeEAgIEAgIEAAwPgAwPgAwPgAwPgAkOgA + kOgAkOgAkOggIEAgIEAAAAAAAAAAAAAAAAAAAAAAAABQKDBQKDBgeEBgeEBw+ABw+ABgeEBgeEBw+ABw + +AAgIEAgIEAgIEAgIEAw+Pgw+PgAkOgAkOgAkOgAkOgAkOgAkOggIEAgIEAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAABQKDBQKDBgeEBgeEBw+ABw+ABgeEBgeEBw+ABw+AAgIEAgIEAgIEAgIEAw+Pgw+PgAkOgA + kOgAkOgAkOgAkOgAkOggIEAgIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQKDBQKDAAGHAAGHBgeEBg + eEAgIEAgIEAgIEAgIEAAwPgAwPgw+Pgw+PgAkOgAkOgAkOgAkOgAIDAAIDAAIDAAIDAgIEAgIEAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAABQKDBQKDAAGHAAGHBgeEBgeEAgIEAgIEAgIEAgIEAAwPgAwPgw+Pgw + +PgAkOgAkOgAkOgAkOgAIDAAIDAAIDAAIDAgIEAgIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAgIEAgIEAgIEAgIEAAwPgAwPgAwPgAwPgw+Pgw+Pgw+Pgw+PgAIDAAIDAAIDAAIDAAIDAAIDAYYLgY + YLggIEAgIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIEAgIEAgIEAgIEAAwPgAwPgAwPgA + wPgw+Pgw+Pgw+Pgw+PgAIDAAIDAAIDAAIDAAIDAAIDAYYLgYYLggIEAgIEAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAgIEAgIEAAwPgAwPgw+Pgw+Pgw+Pgw+Pgw+Pgw+Pgw+Pgw+PgYYLgYYLgAIDAAIDAYYLgY + YLgAkOgAkOgYYLgYYLgYYLgYYLggIEAgIEAAAAAAAAAAAAAAAAAAAAAAAAAgIEAgIEAAwPgAwPgw+Pgw + +Pgw+Pgw+Pgw+Pgw+Pgw+Pgw+PgYYLgYYLgAIDAAIDAYYLgYYLgAkOgAkOgYYLgYYLgYYLgYYLggIEAg + IEAAAAAAAAAAAAAAAAAgIEAgIEAAwPgAwPgw+Pgw+Pgw+Pgw+Pgw+Pgw+PgAkOgAkOgYYLgYYLgYYLgY + YLgAwPgAwPgw+Pgw+PgAwPgAwPgYYLgYYLgYYLgYYLgYYLgYYLggIEAgIEAAAAAAAAAgIEAgIEAAwPgA + wPgw+Pgw+Pgw+Pgw+Pgw+Pgw+PgAkOgAkOgYYLgYYLgYYLgYYLgAwPgAwPgw+Pgw+PgAwPgAwPgYYLgY + YLgYYLgYYLgYYLgYYLggIEAgIEAAAAAAAAAAAAAAAAAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAg + IEAYYLgYYLgAwPgAwPgw+Pgw+Pgw+Pgw+PgAkOgAkOgAkOgAkOgCreoCreoAwPgAwPgAkOgAkOggIEAg + IEAAAAAAAAAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAYYLgYYLgAwPgAwPgw+Pgw+Pgw+Pgw + +PgAkOgAkOgAkOgAkOgCreoCreoAwPgAwPgAkOgAkOggIEAgIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAgIEAgIEAgIEAgIEAw+Pgw+Pgw+Pgw+Pgw+Pgw+PgDru4Dru4AkOgAkOgYYLgY + YLggIEAgIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIEAgIEAgIEAg + IEAw+Pgw+Pgw+Pgw+Pgw+Pgw+PgDru4Dru4AkOgAkOgYYLgYYLggIEAgIEAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIEAgIEAgIEAgIEAgIEAgIEAgIEAg + IEAgIEAgIEAgIEAgIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAgIEAAAAAAAAAAAAAA + AAD/AP///wD///AAP//wAD//wAAD/8AAA//AAAAPwAAAD8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AA/AAAAPwAAAP8AAAD/AAAA/wAAAP/AAAD/wAAA/wAAAD8AAAA8AAAADAAAAA8AAAADAAAAA//AAA//w + AAP//wAP//8ADw== + + + \ No newline at end of file diff --git a/mage/Tweaks/Tweak.cs b/mage/Tweaks/Tweak.cs new file mode 100644 index 0000000..65ad03e --- /dev/null +++ b/mage/Tweaks/Tweak.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; + +namespace mage.Tweaks; + +public class Tweak +{ + public string Name { get; set; } + public string Author { get; set; } + public string Description { get; set; } + + [JsonIgnore] + public bool Applied { get; private set; } = false; + + public List Parameters { get; set; } = []; + public List Patches { get; set; } = []; + + private void StopIfMissingParameters() + { + var missingParams = Parameters + .Where(p => p.Value == null) + .Select(p => p.Name) + .ToList(); + + if (missingParams.Any()) + { + throw new InvalidOperationException( + $"Cannot apply tweak '{Name}'. Missing values for: {string.Join(", ", missingParams)}" + ); + } + } + + private void CheckIfOverwritingCorrectVals(ByteStream rom, TweakPatch patch, int offset) + { + if (patch.OldData == null) return; + + byte[] expected = patch.OldData; + int len = expected.Length; + + byte[] current = new byte[len]; + rom.CopyToArray(offset, current, 0, len); + + if (!expected.AsSpan().SequenceEqual(current)) + throw new InvalidOperationException( + $"Cannot apply tweak '{Name}'. Tweak would overwrite unexpected data" + ); + } + + private void PopulateOldValues(ByteStream rom, TweakPatch patch, int offset, int len) + { + byte[] old = new byte[len]; + rom.CopyToArray(offset, old, 0, len); + patch.OldData = old; + } + + public void Apply(ByteStream rom) + { + StopIfMissingParameters(); + + var paramDict = Parameters.ToDictionary(p => p.Name, p => p.Value!.Value); + + foreach (var patch in Patches) + { + var offset = (int)patch.ResolveOffset(paramDict); + var data = patch.ResolveData(paramDict); + + // Checking if overwriting should be done or saving old values + if (patch.OldData == null || Parameters.Count != 0) PopulateOldValues(rom, patch, offset, data.Length); + else CheckIfOverwritingCorrectVals(rom, patch, offset); + + patch.OldOffset = offset; + + // Write patch data + rom.CopyFromArray(data, 0, offset, data.Length); + } + + Applied = true; + } + + public void Revert(ByteStream rom) + { + foreach (var patch in Patches) + if (patch.OldData == null || patch.OldOffset == null) throw new InvalidOperationException( + $"Cannot revert tweak '{Name}'. There is missing information on the old data" + ); + + foreach (var patch in Patches) + { + int offset = patch.OldOffset ?? 0; + byte[] old = patch.OldData; + rom.CopyFromArray(old, 0, offset, old.Length); + } + + Applied = false; + } +} diff --git a/mage/Tweaks/TweakManager.cs b/mage/Tweaks/TweakManager.cs new file mode 100644 index 0000000..eefa3e9 --- /dev/null +++ b/mage/Tweaks/TweakManager.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace mage.Tweaks; + +public static class TweakManager +{ + public static List IncludedTweaks { get; set; } = new(); + public static List ProjectTweaks { get; set; } = new(); +} diff --git a/mage/Tweaks/TweakParameter.cs b/mage/Tweaks/TweakParameter.cs new file mode 100644 index 0000000..0f01b21 --- /dev/null +++ b/mage/Tweaks/TweakParameter.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace mage.Tweaks; + +public class TweakParameter +{ + public string Name { get; set; } = "New Tweak"; + public string? Description { get; set; } + public long? Value { get; set; } + public long? MinValue { get; set; } + public long? MaxValue { get; set; } +} diff --git a/mage/Tweaks/TweakPatch.cs b/mage/Tweaks/TweakPatch.cs new file mode 100644 index 0000000..b632492 --- /dev/null +++ b/mage/Tweaks/TweakPatch.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace mage.Tweaks; + +public class TweakPatch +{ + public string? Offset { get; set; } + public List Data { get; set; } = []; + + public int? OldOffset { get; set; } + public byte[]? OldData { get; set; } + + public long ResolveOffset(IReadOnlyDictionary parameters) => EvaluateExpression(Offset, parameters); + public byte[] ResolveData(IReadOnlyDictionary parameters) + { + var resultBytes = new List(); + + foreach (var expression in Data) + { + long value = EvaluateExpression(expression, parameters); + resultBytes.Add((byte)(value & 0xFF)); + } + + return resultBytes.ToArray(); + } + + private static long EvaluateExpression(string? expression, IReadOnlyDictionary parameters) + { + if (string.IsNullOrEmpty(expression)) + throw new InvalidOperationException("No expression defined"); + + var expr = new NCalc.Expression(expression); + expr.EvaluateParameter += (name, args) => + { + if (parameters.TryGetValue(name, out var value)) + args.Result = value; + else + throw new ArgumentException($"Unknown parameter: {name}"); + }; + + return Convert.ToInt64(expr.Evaluate()); + } +} diff --git a/mage/mage.csproj b/mage/mage.csproj index 4987278..0ee310e 100644 --- a/mage/mage.csproj +++ b/mage/mage.csproj @@ -173,6 +173,7 @@ + From 79a710c86619fbaaccc28c6b55383620e999e33c Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 19 Feb 2026 11:38:49 +0100 Subject: [PATCH 04/16] fix: door-id-overlays do not respect number base preference fix #58 --- mage/FormMain.cs | 5 ----- mage/Room/DoorList.cs | 14 +++++++------- mage/Utility/Draw.cs | 26 +++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/mage/FormMain.cs b/mage/FormMain.cs index 512e38e..06bd651 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -1564,11 +1564,6 @@ private void InitializePart2() NewRomLoaded?.Invoke(this, null); Sound.PlaySound("load.wav"); - - // TEST REMOVE PLEASE - string json = "{\"Name\": \"Chozo Statue Flip\",\"Author\": \"Biospark\",\"Description\": \"Flips Chozo Statue\",\"Parameters\": [ {\"Name\": \"spriteID\",\"Description\": \"Sprite ID of the Chozo Statue that gets flipped\",\"Value\": 35},{\"Name\": \"flip\",\"Description\": \"0xDC for left, 0xD4 for right\",\"Value\": 220}],\"Patches\": [{\"Offset\": \"0x13C08 + (spriteID - 0x22) * 0x4\",\"Data\": [\"flip\"]}]}"; - Tweak t = JsonSerializer.Deserialize(json); - t.Apply(ROM.Stream); } private void EnableControls(bool val) diff --git a/mage/Room/DoorList.cs b/mage/Room/DoorList.cs index 0541ce7..9054ea9 100644 --- a/mage/Room/DoorList.cs +++ b/mage/Room/DoorList.cs @@ -68,14 +68,14 @@ public void Draw(Graphics g, Rectangle rect, bool includeMoreInfo = false) if (!includeMoreInfo) continue; // Draw Door Numbers - Point pnt = new Point(d.xStart * 16, d.yStart * 16); - mage.Draw.DrawNumber(g, pnt, d.doorNum); + Point pnt = new Point(d.xStart * 16 + 8, d.yStart * 16 + 8); + mage.Draw.DrawNumberCenteredRespectBase(g, pnt, d.doorNum); // Draw connected door ID if (ySize >= 3) { - Point dstPnt = new Point(d.xStart * 16, d.yEnd * 16); - mage.Draw.DrawNumber(g, dstPnt, d.dstDoor); + Point dstPnt = new Point(d.xStart * 16 + 8, d.yEnd * 16 + 8); + mage.Draw.DrawNumberCenteredRespectBase(g, dstPnt, d.dstDoor); //Draw Arrow Point arrowPoint = new Point(d.xStart * 16, (d.yStart * 16 + d.yEnd * 16) / 2); @@ -83,8 +83,8 @@ public void Draw(Graphics g, Rectangle rect, bool includeMoreInfo = false) } else if (xSize >= 3) { - Point dstPnt = new Point(d.xEnd * 16, d.yStart * 16); - mage.Draw.DrawNumber(g, dstPnt, d.dstDoor); + Point dstPnt = new Point(d.xEnd * 16 + 8, d.yStart * 16 + 8); + mage.Draw.DrawNumberCenteredRespectBase(g, dstPnt, d.dstDoor); //Draw Arrow Point arrowPoint = new Point((d.xStart * 16 + d.xEnd * 16) / 2, d.yStart * 16); @@ -184,7 +184,7 @@ public void RemoveDoor(int num) public void Clear() { Edited = true; - foreach(Door d in doors) + foreach (Door d in doors) { d.Edited = true; d.srcRoom = 0xFF; diff --git a/mage/Utility/Draw.cs b/mage/Utility/Draw.cs index d806ffc..899fcb7 100644 --- a/mage/Utility/Draw.cs +++ b/mage/Utility/Draw.cs @@ -113,7 +113,7 @@ public unsafe static void Combine15bpp(Bitmap src, BitmapData dstData, int x, in { Rectangle srcRect = new Rectangle(0, 0, src.Width, src.Height); BitmapData srcData = src.LockBits(srcRect, ImageLockMode.ReadOnly, src.PixelFormat); - + int xStart = Math.Max(0, x); int yStart = Math.Max(0, y); int width = Math.Min(x + src.Width, dstData.Width) - xStart; @@ -316,6 +316,25 @@ public static void DrawNumber(Graphics g, Point point, byte num) new Rectangle((tens + 1) * 8, 0, 8, 8), GraphicsUnit.Pixel); } + public static void DrawNumberCenteredRespectBase(Graphics g, Point point, byte num) + { + string numAsString = Hex.ToString(num); + int len = numAsString.Length; + int textWidth = len * 8; + + int xLeft = point.X - textWidth / 2; + + Bitmap nums = Properties.Resources.scrollNums; + for (int i = 0; i < len; i++) + { + byte val = Hex.ToByte(numAsString[i].ToString()); + var numGfx = new Rectangle((val + 1) * 8, 0, 8, 8); + var goalRegion = new Rectangle(xLeft + (i * 8), point.Y - 4, 8, 8); + + g.DrawImage(nums, goalRegion, numGfx, GraphicsUnit.Pixel); + } + } + public static void DrawArrow(Graphics g, Point point, ArrowDirection dir) { Bitmap arrows = Properties.Resources.arrows; @@ -328,13 +347,14 @@ public static void DrawArrow(Graphics g, Point point, ArrowDirection dir) public static Bitmap BitmapFromFile(string filename) { FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read); - Bitmap b = (Bitmap) Bitmap.FromStream(fs); + Bitmap b = (Bitmap)Bitmap.FromStream(fs); fs.Dispose(); return b; } - public enum ArrowDirection : int { + public enum ArrowDirection : int + { Right = 0, Down = 1, Left = 2, From d15c9891f839c3cd089ddccdcc6e7530a9b3da1e Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:18:33 +0100 Subject: [PATCH 05/16] fix: some editor shortcuts do not respect the editor choice preference --- mage/Editors/FormAnimation.cs | 14 +++++------ mage/Editors/FormMinimap.cs | 6 ++--- mage/Editors/FormSprite.cs | 13 +++------- mage/Editors/FormText.cs | 6 ++--- mage/Editors/FormTileset.cs | 27 +++++++++++++++------ mage/Editors/FormWeapon.cs | 12 ++++----- mage/Editors/NewEditors/FormGraphicsNew.cs | 6 +++++ mage/Editors/NewEditors/FormMinimapNew.cs | 5 +--- mage/Editors/NewEditors/FormTileTableNew.cs | 11 ++++++--- 9 files changed, 57 insertions(+), 43 deletions(-) diff --git a/mage/Editors/FormAnimation.cs b/mage/Editors/FormAnimation.cs index cf639fd..fd17963 100644 --- a/mage/Editors/FormAnimation.cs +++ b/mage/Editors/FormAnimation.cs @@ -1,4 +1,5 @@ -using mage.Theming; +using mage.Editors.NewEditors; +using mage.Theming; using System; using System.Diagnostics; using System.Drawing; @@ -89,7 +90,7 @@ private void Initialize(int window, int number) for (int i = 0; i < 16; i++) { comboBox_tilesetSlot.Items.Add(Hex.ToString(i)); - } + } // graphics count = Version.NumOfAnimGfx; @@ -167,7 +168,7 @@ private void animTimer_Tick(object sender, EventArgs e) double frames = sw.ElapsedMilliseconds * 0.06; sw.Reset(); sw.Start(); - + if (animGfx.type != 0 && animGfx.numStates > 0) { UpdateGraphics(frames); @@ -409,8 +410,7 @@ private void button_gfxEdit_Click(object sender, EventArgs e) { palOffset = Version.GenericBgPaletteOffset; } - FormGraphics form = new FormGraphics(main, animGfx.gfx.Offset, 4, height, palOffset); - form.Show(); + FormGraphicsNew.OpenGraphicsEditor(animGfx.gfx.Offset, 4, height, palOffset); } private void button_gfxApply_Click(object sender, EventArgs e) @@ -517,7 +517,7 @@ private void button_palApply_Click(object sender, EventArgs e) romStream.Write8(offset + 1, delay); romStream.Write8(offset + 2, rows); - animPalette = new AnimPalette(romStream, number); + animPalette = new AnimPalette(romStream, number); DrawPalette(0); ResetAnimation(); @@ -537,6 +537,6 @@ private void button_palClose_Click(object sender, EventArgs e) Close(); } - + } } diff --git a/mage/Editors/FormMinimap.cs b/mage/Editors/FormMinimap.cs index cf05694..d8df34b 100644 --- a/mage/Editors/FormMinimap.cs +++ b/mage/Editors/FormMinimap.cs @@ -1,4 +1,5 @@ -using mage.Theming; +using mage.Editors.NewEditors; +using mage.Theming; using System; using System.Collections.Generic; using System.Drawing; @@ -379,8 +380,7 @@ private void gfxView_squares_MouseDown(object sender, MouseEventArgs e) private void button_editGFX_Click(object sender, EventArgs e) { int height = numTiles / 32; - FormGraphics form = new FormGraphics(main, Version.MinimapGfxOffset, 32, height, Version.MinimapPaletteOffset); - form.Show(); + FormGraphicsNew.OpenGraphicsEditor(Version.MinimapGfxOffset, 32, height, Version.MinimapPaletteOffset); } private void button_bgColor_Click(object sender, EventArgs e) diff --git a/mage/Editors/FormSprite.cs b/mage/Editors/FormSprite.cs index 9d1f6c7..e6c77b5 100644 --- a/mage/Editors/FormSprite.cs +++ b/mage/Editors/FormSprite.cs @@ -1,4 +1,5 @@ -using mage.Theming; +using mage.Editors.NewEditors; +using mage.Theming; using mage.Theming.CustomControls; using System; using System.Diagnostics; @@ -443,16 +444,10 @@ private void SpriteValueChanged(object sender, EventArgs e) private void button_editGFX_Click(object sender, EventArgs e) { - FormGraphics formGfx; if (Version.IsMF) - { - formGfx = new FormGraphics(main, currGfx.GfxOffset, 32, currGfx.NumGfxRows * 2, currGfx.PalOffset); - } + FormGraphicsNew.OpenGraphicsEditor(currGfx.GfxOffset, 32, currGfx.NumGfxRows * 2, currGfx.PalOffset); else - { - formGfx = new FormGraphics(main, currGfx.GfxOffset, 0, 0, currGfx.PalOffset); - } - formGfx.Show(); + FormGraphicsNew.OpenGraphicsEditor(currGfx.GfxOffset, 0, 0, currGfx.PalOffset); } private void button_editPalette_Click(object sender, EventArgs e) diff --git a/mage/Editors/FormText.cs b/mage/Editors/FormText.cs index 2ed680d..f2b4ff8 100644 --- a/mage/Editors/FormText.cs +++ b/mage/Editors/FormText.cs @@ -1,4 +1,5 @@ -using mage.Theming; +using mage.Editors.NewEditors; +using mage.Theming; using System; using System.Collections.Generic; using System.Drawing; @@ -405,8 +406,7 @@ private void button_editPalette_Click(object sender, EventArgs e) private void button_editGfx_Click(object sender, EventArgs e) { - FormGraphics form = new FormGraphics(main, Version.TextGfxOffset, 32, 32, Version.TextPaletteOffset); - form.Show(); + FormGraphicsNew.OpenGraphicsEditor(Version.TextGfxOffset, 32, 32, Version.TextPaletteOffset): } private void button_update_Click(object sender, EventArgs e) diff --git a/mage/Editors/FormTileset.cs b/mage/Editors/FormTileset.cs index 2656481..434044e 100644 --- a/mage/Editors/FormTileset.cs +++ b/mage/Editors/FormTileset.cs @@ -1,4 +1,6 @@ -using mage.Theming; +using mage.Editors; +using mage.Editors.NewEditors; +using mage.Theming; using System; using System.Windows.Forms; @@ -63,14 +65,18 @@ private void textBox_TextChanged(object sender, EventArgs e) status.ChangeMade(); } + private void openGraphicsEditor(int gfxOffset, int palOffset) + { + FormGraphicsNew.OpenGraphicsEditor(gfxOffset, 32, 0, palOffset); + } + private void button_editRLE_Click(object sender, EventArgs e) { try { int gfxOffset = Hex.ToInt(textBox_rleGfx.Text); int palOffset = Hex.ToInt(textBox_palette.Text) + 0x20; - FormGraphics form = new FormGraphics(main, gfxOffset, 32, 0, palOffset); - form.Show(); + openGraphicsEditor(gfxOffset, palOffset); } catch (Exception ex) { @@ -91,8 +97,7 @@ private void button_editLZ77_Click(object sender, EventArgs e) { int gfxOffset = Hex.ToInt(textBox_lz77gfx.Text); int palOffset = Hex.ToInt(textBox_palette.Text) + 0x20; - FormGraphics form = new FormGraphics(main, gfxOffset, 32, 0, palOffset); - form.Show(); + openGraphicsEditor(gfxOffset, palOffset); } catch (Exception ex) { @@ -103,8 +108,16 @@ private void button_editLZ77_Click(object sender, EventArgs e) private void button_editTileTable_Click(object sender, EventArgs e) { - FormTileTable form = new FormTileTable(main, comboBox_tileset.SelectedIndex); - form.Show(); + if (Program.LegacyEditors) + { + FormTileTable form = new FormTileTable(main, comboBox_tileset.SelectedIndex); + form.Show(); + } + else + { + FormTileTableNew form = new FormTileTableNew(comboBox_tileset.SelectedIndex); + form.Show(); + } } private void button_editAnimTileset_Click(object sender, EventArgs e) diff --git a/mage/Editors/FormWeapon.cs b/mage/Editors/FormWeapon.cs index e5b3822..d52b670 100644 --- a/mage/Editors/FormWeapon.cs +++ b/mage/Editors/FormWeapon.cs @@ -1,4 +1,5 @@ -using mage.Theming; +using mage.Editors.NewEditors; +using mage.Theming; using System; using System.Text.RegularExpressions; using System.Windows.Forms; @@ -16,7 +17,7 @@ private class WeaponInfo public int height; public int value; } - + private int gfxOffset; private int palOffset; private int width; @@ -41,7 +42,7 @@ public FormWeapon(FormMain main) statusLabel_changes.Text = ""; status = new Status(statusLabel_changes, button_apply); - + InitializeTree(); } @@ -171,8 +172,7 @@ private void treeView_AfterSelect(object sender, TreeViewEventArgs e) private void button_gfx_Click(object sender, EventArgs e) { - FormGraphics form = new FormGraphics(main, gfxOffset, width, height, palOffset); - form.Show(); + FormGraphicsNew.OpenGraphicsEditor(gfxOffset, width, height, palOffset); } private void button_palette_Click(object sender, EventArgs e) @@ -197,7 +197,7 @@ private void button_apply_Click(object sender, EventArgs e) } catch (Exception ex) { - MessageBox.Show("The value entered was not valid.\n\n" + ex.Message, + MessageBox.Show("The value entered was not valid.\n\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } diff --git a/mage/Editors/NewEditors/FormGraphicsNew.cs b/mage/Editors/NewEditors/FormGraphicsNew.cs index 8c4f4a8..8537943 100644 --- a/mage/Editors/NewEditors/FormGraphicsNew.cs +++ b/mage/Editors/NewEditors/FormGraphicsNew.cs @@ -23,6 +23,12 @@ namespace mage.Editors.NewEditors; public partial class FormGraphicsNew : Form { + public static void OpenGraphicsEditor(int gfxOffset, int width, int height, int palOffset) + { + if (Program.ExperimentalFeaturesEnabled) new FormGraphicsNew(FormMain.Instance, gfxOffset, width, height, palOffset).Show(); + else new FormGraphics(FormMain.Instance, gfxOffset, width, height, palOffset).Show(); + } + private enum Tool { Select, diff --git a/mage/Editors/NewEditors/FormMinimapNew.cs b/mage/Editors/NewEditors/FormMinimapNew.cs index 8be5620..4f4a81e 100644 --- a/mage/Editors/NewEditors/FormMinimapNew.cs +++ b/mage/Editors/NewEditors/FormMinimapNew.cs @@ -976,10 +976,7 @@ private void FormMinimapNew_KeyDown(object sender, KeyEventArgs e) private void button_editGfx_Click(object sender, EventArgs e) { int height = numTiles / 32; - Form f; - if (!Program.ExperimentalFeaturesEnabled) f = new FormGraphics(main, Version.MinimapGfxOffset, 32, height, Version.MinimapPaletteOffset); - else f = new FormGraphicsNew(main, Version.MinimapGfxOffset, 32, height, Version.MinimapPaletteOffset); - f.Show(); + FormGraphicsNew.OpenGraphicsEditor(Version.MinimapGfxOffset, 32, height, Version.MinimapPaletteOffset); } #endregion } diff --git a/mage/Editors/NewEditors/FormTileTableNew.cs b/mage/Editors/NewEditors/FormTileTableNew.cs index 4e048ce..76317ed 100644 --- a/mage/Editors/NewEditors/FormTileTableNew.cs +++ b/mage/Editors/NewEditors/FormTileTableNew.cs @@ -198,6 +198,12 @@ public FormTileTableNew(Room room) : this() comboBox_tileset.SelectedIndex = room.tileset.number; } + public FormTileTableNew(int tileset) : this() + { + openedInRoom = null; + comboBox_tileset.SelectedIndex = tileset; + } + #region Helpers /// /// Gets the index for a single tile from the tile x and y position on a metatile canvas. @@ -1378,10 +1384,7 @@ private void statusButton_export_Click(object sender, EventArgs e) private void button_editGfx_Click(object sender, EventArgs e) { - Form f; - if (Program.ExperimentalFeaturesEnabled) f = new FormGraphicsNew(FormMain.Instance, gfxSourceOffset, 32, 0, palSourceOffset); - else f = new FormGraphics(FormMain.Instance, gfxSourceOffset, 32, 0, palSourceOffset); - f.Show(); + FormGraphicsNew.OpenGraphicsEditor(gfxSourceOffset, 32, 0, palSourceOffset); } } } From 5594c6d93a181594458852509bda2b9a13fccba0 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:33:27 +0100 Subject: [PATCH 06/16] fix: tile table editor might resize lz77 bg to 256x256 fix #37 --- mage/Editors/FormText.cs | 2 +- mage/Editors/NewEditors/FormTileTableNew.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mage/Editors/FormText.cs b/mage/Editors/FormText.cs index f2b4ff8..76f8537 100644 --- a/mage/Editors/FormText.cs +++ b/mage/Editors/FormText.cs @@ -406,7 +406,7 @@ private void button_editPalette_Click(object sender, EventArgs e) private void button_editGfx_Click(object sender, EventArgs e) { - FormGraphicsNew.OpenGraphicsEditor(Version.TextGfxOffset, 32, 32, Version.TextPaletteOffset): + FormGraphicsNew.OpenGraphicsEditor(Version.TextGfxOffset, 32, 32, Version.TextPaletteOffset); } private void button_update_Click(object sender, EventArgs e) diff --git a/mage/Editors/NewEditors/FormTileTableNew.cs b/mage/Editors/NewEditors/FormTileTableNew.cs index 76317ed..a95ea3d 100644 --- a/mage/Editors/NewEditors/FormTileTableNew.cs +++ b/mage/Editors/NewEditors/FormTileTableNew.cs @@ -142,7 +142,6 @@ private Size selectedTilesSize private int oldSelectedArea; private int oldSelectedRoom; private int oldSelectedBG; - private int oldSelectedSize; #endregion public FormTileTableNew() @@ -372,7 +371,7 @@ private void Save() // compress by LZ77 ByteStream compData = new ByteStream(); - compData.Write32(oldSelectedSize); + compData.Write32(comboBox_size.SelectedIndex); int newCompLen = Compress.CompLZ77(uncompData, length, compData); // get pointer @@ -1104,7 +1103,6 @@ private void RoomOrBackgroundChanged(object sender, EventArgs e) private void comboBox_size_SelectedIndexChanged(object sender, EventArgs e) { if (init) return; - oldSelectedSize = comboBox_size.SelectedIndex; SetBackgroundImage(); Status.ChangeMade(); } From 9d5553c5db1862921b063c18b390258df63c571b Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:55:05 +0100 Subject: [PATCH 07/16] fix: switching roms leads to multiple backups being created during auto-backup fix #33 --- mage/FormMain.cs | 1 + mage/Version.cs | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/mage/FormMain.cs b/mage/FormMain.cs index 06bd651..3bdd235 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -1503,6 +1503,7 @@ private void InitializePart1() Version.BackupService = BackupService.FromMinutes(Version.ProjectConfig.BackupsAutoCreationInterval); Version.BackupService.Start(); } + else Version.BackupService = null; } // Look for Input Mono to use in clipdata list; default to Consolas if absent - alexman25 diff --git a/mage/Version.cs b/mage/Version.cs index 90bd6da..54b4de2 100644 --- a/mage/Version.cs +++ b/mage/Version.cs @@ -142,7 +142,15 @@ public static bool SaveProject(string filename) public static int MetroidOffset { get; private set; } public static List ProjectBookmarks { get; private set; } public static ProjectConfig ProjectConfig { get; private set; } = ProjectConfig.DefaultConfig; - public static BackupService? BackupService { get; set; } = null; + public static BackupService? BackupService + { + get => field; + set + { + if (field != null) field.Stop(); + field = value; + } + } public static string[] Clipdata { @@ -585,9 +593,9 @@ public static void RepointedOAM(int oldOffset, int newOffset) } } if (!repointedInProject) foreach (var kvp in PSpriteOAM) - { - if (kvp.Value == oldOffset) ProjectConfig.PrimarySpriteOAMRepoints[kvp.Key] = newOffset; - } + { + if (kvp.Value == oldOffset) ProjectConfig.PrimarySpriteOAMRepoints[kvp.Key] = newOffset; + } foreach (var kvp in ProjectConfig.SecondarySpriteOAMRepoints) { @@ -598,9 +606,9 @@ public static void RepointedOAM(int oldOffset, int newOffset) } } if (!repointedInProject) foreach (var kvp in SSpriteOAM) - { - if (kvp.Value == oldOffset) ProjectConfig.SecondarySpriteOAMRepoints[kvp.Key] = newOffset; - } + { + if (kvp.Value == oldOffset) ProjectConfig.SecondarySpriteOAMRepoints[kvp.Key] = newOffset; + } } public static void MarkOAMInvalid(byte spriteID, bool isSecondary) From f021ebeade2f6e1c9ec233cb440f5351aec55ff2 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:28:55 +0100 Subject: [PATCH 08/16] fix: list view control is not themed correctly --- mage/Compiling/ScriptExecutor.cs | 4 +- mage/FormMain.Designer.cs | 107 +++++++++++++------------ mage/FormMain.cs | 5 ++ mage/Properties/Resources.Designer.cs | 20 +++++ mage/Properties/Resources.resx | 6 ++ mage/Resources/accept.png | Bin 0 -> 781 bytes mage/Resources/transparent.png | Bin 0 -> 126 bytes mage/Theming/ThemeSwitcher.cs | 86 ++++++++++++++++++++ mage/Tools/FormPatches.Designer.cs | 102 ++++++++++++------------ mage/Tools/FormPatches.resx | 56 ++++++------- mage/Tweaks/FormTweaks.Designer.cs | 110 +++++++++++++++++++++++++- mage/Tweaks/FormTweaks.cs | 31 ++++++++ mage/Tweaks/FormTweaks.resx | 6 ++ mage/Tweaks/Tweak.cs | 68 ++++++++++------ mage/Tweaks/TweakManager.cs | 40 +++++++++- mage/Tweaks/TweakParameter.cs | 14 +++- mage/Tweaks/TweakValidation.cs | 110 ++++++++++++++++++++++++++ 17 files changed, 601 insertions(+), 164 deletions(-) create mode 100644 mage/Resources/accept.png create mode 100644 mage/Resources/transparent.png create mode 100644 mage/Tweaks/TweakValidation.cs diff --git a/mage/Compiling/ScriptExecutor.cs b/mage/Compiling/ScriptExecutor.cs index 59fdfbf..a15c588 100644 --- a/mage/Compiling/ScriptExecutor.cs +++ b/mage/Compiling/ScriptExecutor.cs @@ -142,14 +142,12 @@ public async Task ExecuteAsync(string tempRomPath, CancellationTok private static string? ParseOutputRomPath(List lines) { - for (int i = lines.Count - 1; i >= 0; i--) + for (int i = lines.Count - 1; i >= lines.Count - 40; i--) { var trimmed = lines[i].Trim(); if (trimmed.Length == 0) continue; if (AbsolutePathPattern.IsMatch(trimmed)) return trimmed; - // Stop searching after the first non-empty, non-path line from the bottom. - break; } return null; } diff --git a/mage/FormMain.Designer.cs b/mage/FormMain.Designer.cs index d60dc74..0e64774 100644 --- a/mage/FormMain.Designer.cs +++ b/mage/FormMain.Designer.cs @@ -279,6 +279,7 @@ private void InitializeComponent() comboBox_spriteset = new mage.Theming.CustomControls.FlatComboBox(); ToolTip = new System.Windows.Forms.ToolTip(components); splitContainer1 = new System.Windows.Forms.SplitContainer(); + tweaksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); menuStrip.SuspendLayout(); groupBox_location.SuspendLayout(); groupBox_tileset.SuspendLayout(); @@ -719,7 +720,7 @@ private void InitializeComponent() // menuItem_headerEditor.Image = Properties.Resources.toolbar_header; menuItem_headerEditor.Name = "menuItem_headerEditor"; - menuItem_headerEditor.Size = new System.Drawing.Size(170, 22); + menuItem_headerEditor.Size = new System.Drawing.Size(180, 22); menuItem_headerEditor.Text = "Header Editor"; menuItem_headerEditor.Click += menuItem_headerEditor_Click; // @@ -727,20 +728,20 @@ private void InitializeComponent() // menuItem_tilesetEditor.Image = Properties.Resources.shortcut_screw; menuItem_tilesetEditor.Name = "menuItem_tilesetEditor"; - menuItem_tilesetEditor.Size = new System.Drawing.Size(170, 22); + menuItem_tilesetEditor.Size = new System.Drawing.Size(180, 22); menuItem_tilesetEditor.Text = "Tileset Editor"; menuItem_tilesetEditor.Click += menuItem_tilesetEditor_Click; // // toolStripSeparator24 // toolStripSeparator24.Name = "toolStripSeparator24"; - toolStripSeparator24.Size = new System.Drawing.Size(167, 6); + toolStripSeparator24.Size = new System.Drawing.Size(177, 6); // // menuItem_graphicsEditor // menuItem_graphicsEditor.Image = Properties.Resources.toolbar_graphics; menuItem_graphicsEditor.Name = "menuItem_graphicsEditor"; - menuItem_graphicsEditor.Size = new System.Drawing.Size(170, 22); + menuItem_graphicsEditor.Size = new System.Drawing.Size(180, 22); menuItem_graphicsEditor.Text = "Graphics Editor"; menuItem_graphicsEditor.Click += menuItem_graphicsEditor_Click; // @@ -748,7 +749,7 @@ private void InitializeComponent() // menuItem_paletteEditor.Image = Properties.Resources.toolbar_palette; menuItem_paletteEditor.Name = "menuItem_paletteEditor"; - menuItem_paletteEditor.Size = new System.Drawing.Size(170, 22); + menuItem_paletteEditor.Size = new System.Drawing.Size(180, 22); menuItem_paletteEditor.Text = "Palette Editor"; menuItem_paletteEditor.Click += menuItem_paletteEditor_Click; // @@ -756,7 +757,7 @@ private void InitializeComponent() // menuItem_tileTableEditor.Image = Properties.Resources.toolbar_tile_table; menuItem_tileTableEditor.Name = "menuItem_tileTableEditor"; - menuItem_tileTableEditor.Size = new System.Drawing.Size(170, 22); + menuItem_tileTableEditor.Size = new System.Drawing.Size(180, 22); menuItem_tileTableEditor.Text = "Tile Table Editor"; menuItem_tileTableEditor.Click += menuItem_tileTableEditor_Click; // @@ -764,7 +765,7 @@ private void InitializeComponent() // menuItem_animationEditor.Image = Properties.Resources.toolbar_animation; menuItem_animationEditor.Name = "menuItem_animationEditor"; - menuItem_animationEditor.Size = new System.Drawing.Size(170, 22); + menuItem_animationEditor.Size = new System.Drawing.Size(180, 22); menuItem_animationEditor.Text = "Animation Editor"; menuItem_animationEditor.Click += menuItem_animationEditor_Click; // @@ -772,20 +773,20 @@ private void InitializeComponent() // menuItem_oamViewer.Image = Properties.Resources.toolbar_oam; menuItem_oamViewer.Name = "menuItem_oamViewer"; - menuItem_oamViewer.Size = new System.Drawing.Size(170, 22); + menuItem_oamViewer.Size = new System.Drawing.Size(180, 22); menuItem_oamViewer.Text = "OAM Editor"; menuItem_oamViewer.Click += menuItem_oamViewer_Click; // // toolStripSeparator25 // toolStripSeparator25.Name = "toolStripSeparator25"; - toolStripSeparator25.Size = new System.Drawing.Size(167, 6); + toolStripSeparator25.Size = new System.Drawing.Size(177, 6); // // menuItem_spriteEditor // menuItem_spriteEditor.Image = Properties.Resources.toolbar_sprite; menuItem_spriteEditor.Name = "menuItem_spriteEditor"; - menuItem_spriteEditor.Size = new System.Drawing.Size(170, 22); + menuItem_spriteEditor.Size = new System.Drawing.Size(180, 22); menuItem_spriteEditor.Text = "Sprite Editor"; menuItem_spriteEditor.Click += menuItem_spriteEditor_Click; // @@ -793,7 +794,7 @@ private void InitializeComponent() // menuItem_spritesetEditor.Image = Properties.Resources.toolbar_spriteset; menuItem_spritesetEditor.Name = "menuItem_spritesetEditor"; - menuItem_spritesetEditor.Size = new System.Drawing.Size(170, 22); + menuItem_spritesetEditor.Size = new System.Drawing.Size(180, 22); menuItem_spritesetEditor.Text = "Spriteset Editor"; menuItem_spritesetEditor.Click += menuItem_spritesetEditor_Click; // @@ -801,7 +802,7 @@ private void InitializeComponent() // menuItem_minimapEditor.Image = Properties.Resources.toolbar_minimap; menuItem_minimapEditor.Name = "menuItem_minimapEditor"; - menuItem_minimapEditor.Size = new System.Drawing.Size(170, 22); + menuItem_minimapEditor.Size = new System.Drawing.Size(180, 22); menuItem_minimapEditor.Text = "Map Editor"; menuItem_minimapEditor.Click += menuItem_minimapEditor_Click; // @@ -809,20 +810,20 @@ private void InitializeComponent() // menuItem_connectionEditor.Image = Properties.Resources.toolbar_connection; menuItem_connectionEditor.Name = "menuItem_connectionEditor"; - menuItem_connectionEditor.Size = new System.Drawing.Size(170, 22); + menuItem_connectionEditor.Size = new System.Drawing.Size(180, 22); menuItem_connectionEditor.Text = "Connection Editor"; menuItem_connectionEditor.Click += menuItem_connectionEditor_Click; // // toolStripSeparator26 // toolStripSeparator26.Name = "toolStripSeparator26"; - toolStripSeparator26.Size = new System.Drawing.Size(167, 6); + toolStripSeparator26.Size = new System.Drawing.Size(177, 6); // // menuItem_textEditor // menuItem_textEditor.Image = Properties.Resources.toolbar_text; menuItem_textEditor.Name = "menuItem_textEditor"; - menuItem_textEditor.Size = new System.Drawing.Size(170, 22); + menuItem_textEditor.Size = new System.Drawing.Size(180, 22); menuItem_textEditor.Text = "Text Editor"; menuItem_textEditor.Click += menuItem_textEditor_Click; // @@ -830,7 +831,7 @@ private void InitializeComponent() // menuItem_demoEditor.Image = Properties.Resources.toolbar_demo; menuItem_demoEditor.Name = "menuItem_demoEditor"; - menuItem_demoEditor.Size = new System.Drawing.Size(170, 22); + menuItem_demoEditor.Size = new System.Drawing.Size(180, 22); menuItem_demoEditor.Text = "Demo Editor"; menuItem_demoEditor.Click += menuItem_demoEditor_Click; // @@ -838,7 +839,7 @@ private void InitializeComponent() // menuItem_physicsEditor.Image = Properties.Resources.toolbar_physics; menuItem_physicsEditor.Name = "menuItem_physicsEditor"; - menuItem_physicsEditor.Size = new System.Drawing.Size(170, 22); + menuItem_physicsEditor.Size = new System.Drawing.Size(180, 22); menuItem_physicsEditor.Text = "Physics Editor"; menuItem_physicsEditor.Click += menuItem_physicsEditor_Click; // @@ -846,7 +847,7 @@ private void InitializeComponent() // menuItem_weaponEditor.Image = Properties.Resources.toolbar_weapon; menuItem_weaponEditor.Name = "menuItem_weaponEditor"; - menuItem_weaponEditor.Size = new System.Drawing.Size(170, 22); + menuItem_weaponEditor.Size = new System.Drawing.Size(180, 22); menuItem_weaponEditor.Text = "Weapon Editor"; menuItem_weaponEditor.Click += menuItem_weaponEditor_Click; // @@ -854,13 +855,13 @@ private void InitializeComponent() // menuItem_creditsEditor.Image = Properties.Resources.toolbar_credits; menuItem_creditsEditor.Name = "menuItem_creditsEditor"; - menuItem_creditsEditor.Size = new System.Drawing.Size(170, 22); + menuItem_creditsEditor.Size = new System.Drawing.Size(180, 22); menuItem_creditsEditor.Text = "Credits Editor"; menuItem_creditsEditor.Click += menuItem_creditsEditor_Click; // // menuStrip_tools // - menuStrip_tools.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_roomOptions, menuItem_testRoom, menuItem_clipShortcuts, toolStripSeparator28, menuItem_bookmarks, toolStripSeparator2, menuItem_import, menuItem_export, bulkToolStripMenuItem, menuItem_compression, toolStripSeparator23, menuItem_tileBuilder, menuItem_add, menuItem_patches, seperator_flip, menuItem_flip_h, menuItem_flip_v }); + menuStrip_tools.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_roomOptions, menuItem_testRoom, menuItem_clipShortcuts, toolStripSeparator28, menuItem_bookmarks, toolStripSeparator2, menuItem_import, menuItem_export, bulkToolStripMenuItem, menuItem_compression, toolStripSeparator23, menuItem_tileBuilder, menuItem_add, tweaksToolStripMenuItem, menuItem_patches, seperator_flip, menuItem_flip_h, menuItem_flip_v }); menuStrip_tools.Enabled = false; menuStrip_tools.Name = "menuStrip_tools"; menuStrip_tools.Size = new System.Drawing.Size(46, 20); @@ -870,7 +871,7 @@ private void InitializeComponent() // menuItem_roomOptions.Image = Properties.Resources.toolbar_options; menuItem_roomOptions.Name = "menuItem_roomOptions"; - menuItem_roomOptions.Size = new System.Drawing.Size(171, 22); + menuItem_roomOptions.Size = new System.Drawing.Size(180, 22); menuItem_roomOptions.Text = "Room Options..."; menuItem_roomOptions.Click += menuItem_roomOptions_Click; // @@ -878,7 +879,7 @@ private void InitializeComponent() // menuItem_testRoom.Image = Properties.Resources.toolbar_test; menuItem_testRoom.Name = "menuItem_testRoom"; - menuItem_testRoom.Size = new System.Drawing.Size(171, 22); + menuItem_testRoom.Size = new System.Drawing.Size(180, 22); menuItem_testRoom.Text = "Test Room..."; menuItem_testRoom.Click += menuItem_testRoom_Click; // @@ -886,34 +887,34 @@ private void InitializeComponent() // menuItem_clipShortcuts.Image = Properties.Resources.shortcut_shot; menuItem_clipShortcuts.Name = "menuItem_clipShortcuts"; - menuItem_clipShortcuts.Size = new System.Drawing.Size(171, 22); + menuItem_clipShortcuts.Size = new System.Drawing.Size(180, 22); menuItem_clipShortcuts.Text = "Clipdata Shortcuts"; menuItem_clipShortcuts.Click += menuItem_clipShortcuts_Click; // // toolStripSeparator28 // toolStripSeparator28.Name = "toolStripSeparator28"; - toolStripSeparator28.Size = new System.Drawing.Size(168, 6); + toolStripSeparator28.Size = new System.Drawing.Size(177, 6); // // menuItem_bookmarks // menuItem_bookmarks.Enabled = false; menuItem_bookmarks.Image = Properties.Resources.book_open; menuItem_bookmarks.Name = "menuItem_bookmarks"; - menuItem_bookmarks.Size = new System.Drawing.Size(171, 22); + menuItem_bookmarks.Size = new System.Drawing.Size(180, 22); menuItem_bookmarks.Text = "Bookmarks"; menuItem_bookmarks.Click += menuItem_bookmarks_Click; // // toolStripSeparator2 // toolStripSeparator2.Name = "toolStripSeparator2"; - toolStripSeparator2.Size = new System.Drawing.Size(168, 6); + toolStripSeparator2.Size = new System.Drawing.Size(177, 6); // // menuItem_import // menuItem_import.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_importTileset, menuItem_importRLE, menuItem_importLZ77, menuItem_importRoom, toolStripSeparator8, menuItem_importTilesetImage, menuItem_importLZ77BGimage, menuItem_importEnding }); menuItem_import.Name = "menuItem_import"; - menuItem_import.Size = new System.Drawing.Size(171, 22); + menuItem_import.Size = new System.Drawing.Size(180, 22); menuItem_import.Text = "Import"; // // menuItem_importTileset @@ -974,7 +975,7 @@ private void InitializeComponent() // menuItem_export.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_exportTileset, menuItem_exportBG, menuItem_exportRoom, toolStripSeparator7, menuItem_exportTilesetImage, menuItem_exportBG0image, menuItem_exportBG3image, menuItem_exportRoomImage }); menuItem_export.Name = "menuItem_export"; - menuItem_export.Size = new System.Drawing.Size(171, 22); + menuItem_export.Size = new System.Drawing.Size(180, 22); menuItem_export.Text = "Export"; // // menuItem_exportTileset @@ -1049,7 +1050,7 @@ private void InitializeComponent() // bulkToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { button_exportAllRooms, button_areaImage, toolStripSeparator29, button_importAllRooms }); bulkToolStripMenuItem.Name = "bulkToolStripMenuItem"; - bulkToolStripMenuItem.Size = new System.Drawing.Size(171, 22); + bulkToolStripMenuItem.Size = new System.Drawing.Size(180, 22); bulkToolStripMenuItem.Text = "Bulk"; // // button_exportAllRooms @@ -1083,7 +1084,7 @@ private void InitializeComponent() // menuItem_compression.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_LZ77comp, menuItem_LZ77decomp }); menuItem_compression.Name = "menuItem_compression"; - menuItem_compression.Size = new System.Drawing.Size(171, 22); + menuItem_compression.Size = new System.Drawing.Size(180, 22); menuItem_compression.Text = "Compression"; // // menuItem_LZ77comp @@ -1103,13 +1104,13 @@ private void InitializeComponent() // toolStripSeparator23 // toolStripSeparator23.Name = "toolStripSeparator23"; - toolStripSeparator23.Size = new System.Drawing.Size(168, 6); + toolStripSeparator23.Size = new System.Drawing.Size(177, 6); // // menuItem_tileBuilder // menuItem_tileBuilder.Image = Properties.Resources.toolbar_tile_builder; menuItem_tileBuilder.Name = "menuItem_tileBuilder"; - menuItem_tileBuilder.Size = new System.Drawing.Size(171, 22); + menuItem_tileBuilder.Size = new System.Drawing.Size(180, 22); menuItem_tileBuilder.Text = "Map Tile Builder"; menuItem_tileBuilder.Click += menuItem_tileBuilder_Click; // @@ -1118,48 +1119,48 @@ private void InitializeComponent() menuItem_add.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_addBG, menuItem_addEnemyset, menuItem_addRoom, menuItem_addTileset, menuItem_addSpriteset, menuItem_addAnim }); menuItem_add.Image = Properties.Resources.toolbar_add; menuItem_add.Name = "menuItem_add"; - menuItem_add.Size = new System.Drawing.Size(171, 22); + menuItem_add.Size = new System.Drawing.Size(180, 22); menuItem_add.Text = "Add"; // // menuItem_addBG // menuItem_addBG.Name = "menuItem_addBG"; - menuItem_addBG.Size = new System.Drawing.Size(144, 22); + menuItem_addBG.Size = new System.Drawing.Size(180, 22); menuItem_addBG.Text = "Background"; menuItem_addBG.Click += menuItem_addItem_Click; // // menuItem_addEnemyset // menuItem_addEnemyset.Name = "menuItem_addEnemyset"; - menuItem_addEnemyset.Size = new System.Drawing.Size(144, 22); + menuItem_addEnemyset.Size = new System.Drawing.Size(180, 22); menuItem_addEnemyset.Text = "Room Sprites"; menuItem_addEnemyset.Click += menuItem_addItem_Click; // // menuItem_addRoom // menuItem_addRoom.Name = "menuItem_addRoom"; - menuItem_addRoom.Size = new System.Drawing.Size(144, 22); + menuItem_addRoom.Size = new System.Drawing.Size(180, 22); menuItem_addRoom.Text = "Room"; menuItem_addRoom.Click += menuItem_addItem_Click; // // menuItem_addTileset // menuItem_addTileset.Name = "menuItem_addTileset"; - menuItem_addTileset.Size = new System.Drawing.Size(144, 22); + menuItem_addTileset.Size = new System.Drawing.Size(180, 22); menuItem_addTileset.Text = "Tileset"; menuItem_addTileset.Click += menuItem_addItem_Click; // // menuItem_addSpriteset // menuItem_addSpriteset.Name = "menuItem_addSpriteset"; - menuItem_addSpriteset.Size = new System.Drawing.Size(144, 22); + menuItem_addSpriteset.Size = new System.Drawing.Size(180, 22); menuItem_addSpriteset.Text = "Spriteset"; menuItem_addSpriteset.Click += menuItem_addItem_Click; // // menuItem_addAnim // menuItem_addAnim.Name = "menuItem_addAnim"; - menuItem_addAnim.Size = new System.Drawing.Size(144, 22); + menuItem_addAnim.Size = new System.Drawing.Size(180, 22); menuItem_addAnim.Text = "Animation"; menuItem_addAnim.Click += menuItem_addItem_Click; // @@ -1167,20 +1168,20 @@ private void InitializeComponent() // menuItem_patches.Image = Properties.Resources.toolbar_patches; menuItem_patches.Name = "menuItem_patches"; - menuItem_patches.Size = new System.Drawing.Size(171, 22); + menuItem_patches.Size = new System.Drawing.Size(180, 22); menuItem_patches.Text = "Patches"; menuItem_patches.Click += menuItem_patches_Click; // // seperator_flip // seperator_flip.Name = "seperator_flip"; - seperator_flip.Size = new System.Drawing.Size(168, 6); + seperator_flip.Size = new System.Drawing.Size(177, 6); seperator_flip.Visible = false; // // menuItem_flip_h // menuItem_flip_h.Name = "menuItem_flip_h"; - menuItem_flip_h.Size = new System.Drawing.Size(171, 22); + menuItem_flip_h.Size = new System.Drawing.Size(180, 22); menuItem_flip_h.Text = "Flip Room H"; menuItem_flip_h.Visible = false; menuItem_flip_h.Click += flipRoomToolStripMenuItem_Click; @@ -1188,7 +1189,7 @@ private void InitializeComponent() // menuItem_flip_v // menuItem_flip_v.Name = "menuItem_flip_v"; - menuItem_flip_v.Size = new System.Drawing.Size(171, 22); + menuItem_flip_v.Size = new System.Drawing.Size(180, 22); menuItem_flip_v.Text = "Flip Room V"; menuItem_flip_v.Visible = false; menuItem_flip_v.Click += flipRoomVToolStripMenuItem_Click; @@ -1204,7 +1205,7 @@ private void InitializeComponent() // menuItem_options.Image = Properties.Resources.cog; menuItem_options.Name = "menuItem_options"; - menuItem_options.Size = new System.Drawing.Size(165, 22); + menuItem_options.Size = new System.Drawing.Size(180, 22); menuItem_options.Text = "Preferences..."; menuItem_options.Click += programSettingsToolStripMenuItem_Click; // @@ -1213,21 +1214,21 @@ private void InitializeComponent() menuItem_projectSettings.Enabled = false; menuItem_projectSettings.Image = Properties.Resources.script_gear; menuItem_projectSettings.Name = "menuItem_projectSettings"; - menuItem_projectSettings.Size = new System.Drawing.Size(165, 22); + menuItem_projectSettings.Size = new System.Drawing.Size(180, 22); menuItem_projectSettings.Text = "Project Settings..."; menuItem_projectSettings.Click += menuItem_projectSettings_Click; // // toolStripSeparator31 // toolStripSeparator31.Name = "toolStripSeparator31"; - toolStripSeparator31.Size = new System.Drawing.Size(162, 6); + toolStripSeparator31.Size = new System.Drawing.Size(177, 6); // // menuItem_defaultView // menuItem_defaultView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_defaultBG0, menuItem_defaultBG1, menuItem_defaultBG2, menuItem_defaultBG3, menuItem_defaultClipdata, toolStripSeparator13, menuItem_defaultSprites, menuItem_defaultSpriteOutlines, menuItem_defaultDoors, menuItem_defaultScrolls, menuItem_defaultScreens }); menuItem_defaultView.Enabled = false; menuItem_defaultView.Name = "menuItem_defaultView"; - menuItem_defaultView.Size = new System.Drawing.Size(165, 22); + menuItem_defaultView.Size = new System.Drawing.Size(180, 22); menuItem_defaultView.Text = "Default View"; // // menuItem_defaultBG0 @@ -1344,14 +1345,14 @@ private void InitializeComponent() // menuItem_tooltips.Enabled = false; menuItem_tooltips.Name = "menuItem_tooltips"; - menuItem_tooltips.Size = new System.Drawing.Size(165, 22); + menuItem_tooltips.Size = new System.Drawing.Size(180, 22); menuItem_tooltips.Text = "Disable Tooltips"; menuItem_tooltips.Click += menuItem_tooltips_Click; // // toolStripSeparator21 // toolStripSeparator21.Name = "toolStripSeparator21"; - toolStripSeparator21.Size = new System.Drawing.Size(162, 6); + toolStripSeparator21.Size = new System.Drawing.Size(177, 6); // // menuStrip_help // @@ -2385,6 +2386,13 @@ private void InitializeComponent() splitContainer1.TabIndex = 0; splitContainer1.SplitterMoved += splitContainer1_SplitterMoved; // + // tweaksToolStripMenuItem + // + tweaksToolStripMenuItem.Name = "tweaksToolStripMenuItem"; + tweaksToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + tweaksToolStripMenuItem.Text = "Tweaks"; + tweaksToolStripMenuItem.Click += tweaksToolStripMenuItem_Click; + // // FormMain // AllowDrop = true; @@ -2688,6 +2696,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem menuItem_creditsEditor; private System.Windows.Forms.ToolStripButton toolStrip_credits; private System.Windows.Forms.ToolStripMenuItem btn_saveCompiled; + private System.Windows.Forms.ToolStripMenuItem tweaksToolStripMenuItem; } } diff --git a/mage/FormMain.cs b/mage/FormMain.cs index 3bdd235..f807932 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -1324,6 +1324,11 @@ private void CompressFile(bool compress) } } + private void tweaksToolStripMenuItem_Click(object sender, EventArgs e) + { + new FormTweaks().Show(); + } + #endregion diff --git a/mage/Properties/Resources.Designer.cs b/mage/Properties/Resources.Designer.cs index 63f2df8..956041f 100644 --- a/mage/Properties/Resources.Designer.cs +++ b/mage/Properties/Resources.Designer.cs @@ -60,6 +60,16 @@ internal Resources() { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap accept { + get { + object obj = ResourceManager.GetObject("accept", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -2076,6 +2086,16 @@ public static System.Drawing.Bitmap toolbar_zoom { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap transparent { + get { + object obj = ResourceManager.GetObject("transparent", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized string similar to 0040 ///0041 ! diff --git a/mage/Properties/Resources.resx b/mage/Properties/Resources.resx index 7b9fe15..bb35bad 100644 --- a/mage/Properties/Resources.resx +++ b/mage/Properties/Resources.resx @@ -667,4 +667,10 @@ ..\Resources\script_code_red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\accept.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\transparent.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/mage/Resources/accept.png b/mage/Resources/accept.png new file mode 100644 index 0000000000000000000000000000000000000000..89c8129a490b329f3165f32fa0781701aab417ea GIT binary patch literal 781 zcmV+o1M>WdP)4-QibtN)VXQDpczE`xXAkUjh%RI>;okxb7K@0kpyQ1k_Y(|Oe7$m(^ zNYX>mI||sUbmn+c3<&FnE=4u#()KBS^SH8e)Qs5i!#lY=$-1gbH6VluzU=m=EP78&5vQ z-?+fFP-G2l&l_QzYealK$;1Rl?FkzXR&Jv@fBPNjCr#AYRyJ7UJQ0v#?)7Ott=>3`#-pV!7>9}>Q1jL)H6h&gkP@3nI=+F3nA~M>u#(n* z8T!#8oEw&-mED4!h4s!N@Jo3S7N&Q6%6l3}nlcd~X@>;uelvPsSkXIgg~e+^T1zSf z3SNj(5%jK~i8@b;C lv.Invalidate(true); + + var sf = new StringFormat + { + Alignment = StringAlignment.Near, + LineAlignment = StringAlignment.Center, + Trimming = StringTrimming.EllipsisCharacter + }; + + lv.DrawColumnHeader += (_, e) => + { + using var backBrush = new SolidBrush(theme.BackgroundColor); + using var textBrush = new SolidBrush(theme.TextColor); + using var borderPen = new Pen(theme.SecondaryOutline); + + e.Graphics.FillRectangle(backBrush, e.Bounds); + e.Graphics.DrawLine(borderPen, e.Bounds.Left, e.Bounds.Bottom - 1, + e.Bounds.Right - 1, e.Bounds.Bottom - 1); + e.Graphics.DrawLine(borderPen, e.Bounds.Right - 1, e.Bounds.Top, + e.Bounds.Right - 1, e.Bounds.Bottom - 1); + + var textRect = new Rectangle(e.Bounds.X + 4, e.Bounds.Y, + e.Bounds.Width - 8, e.Bounds.Height); + e.Graphics.DrawString(e.Header.Text, lv.Font, textBrush, textRect, sf); + + if (e.ColumnIndex == lv.Columns.Count - 1) + { + int gapWidth = lv.ClientRectangle.Width - e.Bounds.Right; + if (gapWidth > 0) + { + var gapRect = new Rectangle(e.Bounds.Right, e.Bounds.Y, + gapWidth, e.Bounds.Height); + var oldClip = e.Graphics.Clip; + e.Graphics.SetClip(gapRect); + e.Graphics.FillRectangle(backBrush, gapRect); + e.Graphics.DrawLine(borderPen, gapRect.Left, gapRect.Bottom - 1, + gapRect.Right, gapRect.Bottom - 1); + e.Graphics.Clip = oldClip; + } + } + }; + + lv.DrawItem += (_, e) => e.DrawDefault = lv.View != View.Details; + + lv.DrawSubItem += (_, e) => + { + bool isSelected = e.Item.Selected; + var backColor = isSelected ? theme.AccentColor : theme.BackgroundColor; + var textColor = isSelected ? theme.TextColorHighlight : theme.TextColor; + + using var backBrush = new SolidBrush(backColor); + using var textBrush = new SolidBrush(textColor); + using var gridPen = new Pen(theme.SecondaryOutline); + + e.Graphics.FillRectangle(backBrush, e.Bounds); + + int textX = e.Bounds.X + 4; + int availableWidth = e.Bounds.Width - 8; + + if (e.ColumnIndex == 0 && lv.SmallImageList != null && + e.Item.ImageIndex >= 0 && + e.Item.ImageIndex < lv.SmallImageList.Images.Count) + { + var img = lv.SmallImageList.Images[e.Item.ImageIndex]; + int imgY = e.Bounds.Y + (e.Bounds.Height - img.Height) / 2; + e.Graphics.DrawImage(img, e.Bounds.X + 4, imgY); + textX += img.Width + 4; + availableWidth -= img.Width + 4; + } + + var textRect = new Rectangle(textX, e.Bounds.Y, + availableWidth, e.Bounds.Height); + e.Graphics.DrawString(e.SubItem?.Text ?? "", lv.Font, + textBrush, textRect, sf); + + e.Graphics.DrawLine(gridPen, e.Bounds.Right - 1, e.Bounds.Top, + e.Bounds.Right - 1, e.Bounds.Bottom - 1); + e.Graphics.DrawLine(gridPen, e.Bounds.Left, e.Bounds.Bottom - 1, + e.Bounds.Right - 1, e.Bounds.Bottom - 1); + }; + } } /// diff --git a/mage/Tools/FormPatches.Designer.cs b/mage/Tools/FormPatches.Designer.cs index 57e5151..f763aa2 100644 --- a/mage/Tools/FormPatches.Designer.cs +++ b/mage/Tools/FormPatches.Designer.cs @@ -29,80 +29,76 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormPatches)); - this.button_apply = new System.Windows.Forms.Button(); - this.button_close = new System.Windows.Forms.Button(); - this.listView_patches = new System.Windows.Forms.ListView(); - this.columnHeader_patches = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeader_author = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnHeader_applied = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.SuspendLayout(); + button_apply = new System.Windows.Forms.Button(); + button_close = new System.Windows.Forms.Button(); + listView_patches = new System.Windows.Forms.ListView(); + columnHeader_patches = new System.Windows.Forms.ColumnHeader(); + columnHeader_author = new System.Windows.Forms.ColumnHeader(); + columnHeader_applied = new System.Windows.Forms.ColumnHeader(); + SuspendLayout(); // // button_apply // - this.button_apply.Enabled = false; - this.button_apply.Location = new System.Drawing.Point(12, 182); - this.button_apply.Name = "button_apply"; - this.button_apply.Size = new System.Drawing.Size(75, 23); - this.button_apply.TabIndex = 1; - this.button_apply.Text = "Apply"; - this.button_apply.UseVisualStyleBackColor = true; - this.button_apply.Click += new System.EventHandler(this.button_apply_Click); + button_apply.Enabled = false; + button_apply.Location = new System.Drawing.Point(12, 182); + button_apply.Name = "button_apply"; + button_apply.Size = new System.Drawing.Size(75, 23); + button_apply.TabIndex = 1; + button_apply.Text = "Apply"; + button_apply.UseVisualStyleBackColor = true; + button_apply.Click += button_apply_Click; // // button_close // - this.button_close.Location = new System.Drawing.Point(276, 182); - this.button_close.Name = "button_close"; - this.button_close.Size = new System.Drawing.Size(75, 23); - this.button_close.TabIndex = 2; - this.button_close.Text = "Close"; - this.button_close.UseVisualStyleBackColor = true; - this.button_close.Click += new System.EventHandler(this.button_close_Click); + button_close.Location = new System.Drawing.Point(276, 182); + button_close.Name = "button_close"; + button_close.Size = new System.Drawing.Size(75, 23); + button_close.TabIndex = 2; + button_close.Text = "Close"; + button_close.UseVisualStyleBackColor = true; + button_close.Click += button_close_Click; // // listView_patches // - this.listView_patches.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnHeader_patches, - this.columnHeader_author, - this.columnHeader_applied}); - this.listView_patches.FullRowSelect = true; - this.listView_patches.GridLines = true; - this.listView_patches.Location = new System.Drawing.Point(12, 12); - this.listView_patches.MultiSelect = false; - this.listView_patches.Name = "listView_patches"; - this.listView_patches.Size = new System.Drawing.Size(339, 164); - this.listView_patches.TabIndex = 0; - this.listView_patches.UseCompatibleStateImageBehavior = false; - this.listView_patches.View = System.Windows.Forms.View.Details; - this.listView_patches.SelectedIndexChanged += new System.EventHandler(this.listView_patches_SelectedIndexChanged); + listView_patches.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { columnHeader_patches, columnHeader_author, columnHeader_applied }); + listView_patches.FullRowSelect = true; + listView_patches.Location = new System.Drawing.Point(12, 12); + listView_patches.MultiSelect = false; + listView_patches.Name = "listView_patches"; + listView_patches.Size = new System.Drawing.Size(339, 164); + listView_patches.TabIndex = 0; + listView_patches.UseCompatibleStateImageBehavior = false; + listView_patches.View = System.Windows.Forms.View.Details; + listView_patches.SelectedIndexChanged += listView_patches_SelectedIndexChanged; // // columnHeader_patches // - this.columnHeader_patches.Text = "Patches"; - this.columnHeader_patches.Width = 203; + columnHeader_patches.Text = "Patches"; + columnHeader_patches.Width = 203; // // columnHeader_author // - this.columnHeader_author.Text = "Author"; - this.columnHeader_author.Width = 80; + columnHeader_author.Text = "Author"; + columnHeader_author.Width = 85; // // columnHeader_applied // - this.columnHeader_applied.Text = "Applied"; - this.columnHeader_applied.Width = 52; + columnHeader_applied.Text = "Applied"; + columnHeader_applied.Width = 51; // // FormPatches // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(363, 217); - this.Controls.Add(this.listView_patches); - this.Controls.Add(this.button_close); - this.Controls.Add(this.button_apply); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "FormPatches"; - this.Text = "Patches"; - this.ResumeLayout(false); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + ClientSize = new System.Drawing.Size(363, 217); + Controls.Add(listView_patches); + Controls.Add(button_close); + Controls.Add(button_apply); + Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + Name = "FormPatches"; + Text = "Patches"; + ResumeLayout(false); } diff --git a/mage/Tools/FormPatches.resx b/mage/Tools/FormPatches.resx index 9920357..d2957a1 100644 --- a/mage/Tools/FormPatches.resx +++ b/mage/Tools/FormPatches.resx @@ -1,17 +1,17 @@  - @@ -117,7 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + AAABAAIAEBAAAAAAGABoAwAAJgAAACAgAAAAABgAqAwAAI4DAAAoAAAAEAAAACAAAAABABgAAAAAAAAD diff --git a/mage/Tweaks/FormTweaks.Designer.cs b/mage/Tweaks/FormTweaks.Designer.cs index a07f796..89d8109 100644 --- a/mage/Tweaks/FormTweaks.Designer.cs +++ b/mage/Tweaks/FormTweaks.Designer.cs @@ -29,19 +29,121 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormTweaks)); + statusStrip1 = new System.Windows.Forms.StatusStrip(); + grp_tweaks = new System.Windows.Forms.GroupBox(); + lst_tweaks = new System.Windows.Forms.ListView(); + clm_name = new System.Windows.Forms.ColumnHeader(); + clm_author = new System.Windows.Forms.ColumnHeader(); + pnl_main = new System.Windows.Forms.SplitContainer(); + grp_properties = new System.Windows.Forms.GroupBox(); + grp_tweaks.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pnl_main).BeginInit(); + pnl_main.Panel1.SuspendLayout(); + pnl_main.Panel2.SuspendLayout(); + pnl_main.SuspendLayout(); SuspendLayout(); // + // statusStrip1 + // + statusStrip1.Location = new System.Drawing.Point(0, 428); + statusStrip1.Name = "statusStrip1"; + statusStrip1.Size = new System.Drawing.Size(797, 22); + statusStrip1.TabIndex = 0; + statusStrip1.Text = "statusStrip1"; + // + // grp_tweaks + // + grp_tweaks.Controls.Add(lst_tweaks); + grp_tweaks.Dock = System.Windows.Forms.DockStyle.Fill; + grp_tweaks.Location = new System.Drawing.Point(6, 6); + grp_tweaks.Name = "grp_tweaks"; + grp_tweaks.Size = new System.Drawing.Size(490, 419); + grp_tweaks.TabIndex = 1; + grp_tweaks.TabStop = false; + grp_tweaks.Text = "Tweaks"; + // + // lst_tweaks + // + lst_tweaks.BorderStyle = System.Windows.Forms.BorderStyle.None; + lst_tweaks.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { clm_name, clm_author }); + lst_tweaks.Dock = System.Windows.Forms.DockStyle.Fill; + lst_tweaks.FullRowSelect = true; + lst_tweaks.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + lst_tweaks.Location = new System.Drawing.Point(3, 19); + lst_tweaks.MultiSelect = false; + lst_tweaks.Name = "lst_tweaks"; + lst_tweaks.Size = new System.Drawing.Size(484, 397); + lst_tweaks.TabIndex = 0; + lst_tweaks.UseCompatibleStateImageBehavior = false; + lst_tweaks.View = System.Windows.Forms.View.Details; + lst_tweaks.Resize += lst_tweaks_Resize; + // + // clm_name + // + clm_name.Text = "Name"; + clm_name.Width = 300; + // + // clm_author + // + clm_author.Text = "Author"; + clm_author.Width = 150; + // + // pnl_main + // + pnl_main.Dock = System.Windows.Forms.DockStyle.Fill; + pnl_main.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + pnl_main.Location = new System.Drawing.Point(0, 0); + pnl_main.Name = "pnl_main"; + // + // pnl_main.Panel1 + // + pnl_main.Panel1.Controls.Add(grp_tweaks); + pnl_main.Panel1.Padding = new System.Windows.Forms.Padding(6, 6, 3, 3); + // + // pnl_main.Panel2 + // + pnl_main.Panel2.Controls.Add(grp_properties); + pnl_main.Panel2.Padding = new System.Windows.Forms.Padding(3, 6, 6, 3); + pnl_main.Size = new System.Drawing.Size(797, 428); + pnl_main.SplitterDistance = 499; + pnl_main.TabIndex = 2; + // + // grp_properties + // + grp_properties.Dock = System.Windows.Forms.DockStyle.Fill; + grp_properties.Location = new System.Drawing.Point(3, 6); + grp_properties.Name = "grp_properties"; + grp_properties.Size = new System.Drawing.Size(285, 419); + grp_properties.TabIndex = 0; + grp_properties.TabStop = false; + grp_properties.Text = "Properties"; + // // FormTweaks // - AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - ClientSize = new System.Drawing.Size(800, 450); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + ClientSize = new System.Drawing.Size(797, 450); + Controls.Add(pnl_main); + Controls.Add(statusStrip1); Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); Name = "FormTweaks"; - Text = "Tweaks"; + Text = "Tweak Manager"; + grp_tweaks.ResumeLayout(false); + pnl_main.Panel1.ResumeLayout(false); + pnl_main.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)pnl_main).EndInit(); + pnl_main.ResumeLayout(false); ResumeLayout(false); + PerformLayout(); } #endregion + + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.GroupBox grp_tweaks; + private System.Windows.Forms.SplitContainer pnl_main; + private System.Windows.Forms.ListView lst_tweaks; + private System.Windows.Forms.ColumnHeader clm_name; + private System.Windows.Forms.ColumnHeader clm_author; + private System.Windows.Forms.GroupBox grp_properties; } } \ No newline at end of file diff --git a/mage/Tweaks/FormTweaks.cs b/mage/Tweaks/FormTweaks.cs index 029f3ca..3bdf9a5 100644 --- a/mage/Tweaks/FormTweaks.cs +++ b/mage/Tweaks/FormTweaks.cs @@ -17,5 +17,36 @@ public FormTweaks() ThemeSwitcher.ChangeTheme(Controls, this); ThemeSwitcher.InjectPaintOverrides(Controls); + + pnl_main.Panel2Collapsed = true; + + ImageList statusIcons = new ImageList(); + statusIcons.Images.Add("checked", Properties.Resources.accept); + statusIcons.Images.Add("unchecked", Properties.Resources.transparent); + + lst_tweaks.SmallImageList = statusIcons; + lst_tweaks.View = View.Details; + + PopulateTweaksList(); + } + + private void PopulateTweaksList() + { + lst_tweaks.Items.Clear(); + foreach (Tweak t in TweakManager.ProjectTweaks) + { + ListViewItem item = new ListViewItem(t.Name); + item.ImageIndex = t.Applied ? 0 : 1; + item.SubItems.Add(t.Author); + + lst_tweaks.Items.Add(item); + } + } + + private void lst_tweaks_Resize(object sender, EventArgs e) + { + ListView lv = sender as ListView; + int authorFixedWidth = lv.Columns[1].Width; + lv.Columns[0].Width = lv.ClientSize.Width - authorFixedWidth; } } diff --git a/mage/Tweaks/FormTweaks.resx b/mage/Tweaks/FormTweaks.resx index c3147e2..09b770d 100644 --- a/mage/Tweaks/FormTweaks.resx +++ b/mage/Tweaks/FormTweaks.resx @@ -117,6 +117,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + True + diff --git a/mage/Tweaks/Tweak.cs b/mage/Tweaks/Tweak.cs index 65ad03e..d4b01b2 100644 --- a/mage/Tweaks/Tweak.cs +++ b/mage/Tweaks/Tweak.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Text.Json.Serialization; +using System.Windows.Forms; namespace mage.Tweaks; @@ -10,14 +11,27 @@ public class Tweak { public string Name { get; set; } public string Author { get; set; } - public string Description { get; set; } + public string? Description { get; set; } - [JsonIgnore] - public bool Applied { get; private set; } = false; + public string[]? Tags { get; set; } + + public bool Applied { get; set; } = false; public List Parameters { get; set; } = []; public List Patches { get; set; } = []; + [JsonIgnore] + public bool HasDynamicPatchLocation + { + get + { + foreach (var patch in Patches) + try { Hex.ToInt(patch.Offset); } + catch { return true; } + return false; + } + } + private void StopIfMissingParameters() { var missingParams = Parameters @@ -49,32 +63,42 @@ private void CheckIfOverwritingCorrectVals(ByteStream rom, TweakPatch patch, int ); } - private void PopulateOldValues(ByteStream rom, TweakPatch patch, int offset, int len) - { - byte[] old = new byte[len]; - rom.CopyToArray(offset, old, 0, len); - patch.OldData = old; - } - public void Apply(ByteStream rom) { StopIfMissingParameters(); var paramDict = Parameters.ToDictionary(p => p.Name, p => p.Value!.Value); - foreach (var patch in Patches) - { - var offset = (int)patch.ResolveOffset(paramDict); - var data = patch.ResolveData(paramDict); - - // Checking if overwriting should be done or saving old values - if (patch.OldData == null || Parameters.Count != 0) PopulateOldValues(rom, patch, offset, data.Length); - else CheckIfOverwritingCorrectVals(rom, patch, offset); + Dictionary Backup = new(); - patch.OldOffset = offset; + try + { + foreach (var patch in Patches) + { + var offset = (int)patch.ResolveOffset(paramDict); + var data = patch.ResolveData(paramDict); + + // Add to backup, in case something fails + byte[] old = new byte[data.Length]; + rom.CopyToArray(offset, old, 0, old.Length); + patch.OldOffset = offset; + + // Checking if overwriting should be done or saving old values + if (patch.OldData == null || HasDynamicPatchLocation) patch.OldData = old; + else CheckIfOverwritingCorrectVals(rom, patch, offset); + + // Write patch data + rom.CopyFromArray(data, 0, offset, data.Length); + } + } + catch (Exception e) + { + MessageBox.Show($"Tweak could not be appplied.\n\n{e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - // Write patch data - rom.CopyFromArray(data, 0, offset, data.Length); + foreach (var kvp in Backup) + rom.CopyFromArray(kvp.Value, 0, kvp.Key, kvp.Value.Length); + Applied = false; + return; } Applied = true; @@ -84,7 +108,7 @@ public void Revert(ByteStream rom) { foreach (var patch in Patches) if (patch.OldData == null || patch.OldOffset == null) throw new InvalidOperationException( - $"Cannot revert tweak '{Name}'. There is missing information on the old data" + $"Cannot revert tweak '{Name}'. No old data available." ); foreach (var patch in Patches) diff --git a/mage/Tweaks/TweakManager.cs b/mage/Tweaks/TweakManager.cs index eefa3e9..9783283 100644 --- a/mage/Tweaks/TweakManager.cs +++ b/mage/Tweaks/TweakManager.cs @@ -1,11 +1,45 @@ -using System; +using mage.Bookmarks; +using System; using System.Collections.Generic; +using System.IO; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; namespace mage.Tweaks; public static class TweakManager { - public static List IncludedTweaks { get; set; } = new(); - public static List ProjectTweaks { get; set; } = new(); + public static List OnlineTweaks { get; set; } = new(); + public static List ProjectTweaks + { + get + { + string json = File.ReadAllText("C:\\Users\\Conner\\Desktop\\testtweak.json"); + return Deserialize(json); + } + set; + } = new(); + + + // Serializing + private static JsonSerializerOptions JsonOptions = new JsonSerializerOptions() + { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + AllowTrailingCommas = true, + }; + private static JsonSerializerOptions JsonOptionsIndented = new JsonSerializerOptions() + { + WriteIndented = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + AllowTrailingCommas = true, + }; + + public static string Serialize(List tweaks, bool writeIndented = true) + { + JsonSerializerOptions options = writeIndented ? JsonOptionsIndented : JsonOptions; + return JsonSerializer.Serialize(tweaks, options); + } + + public static List Deserialize(string json) => JsonSerializer.Deserialize>(json, JsonOptions); } diff --git a/mage/Tweaks/TweakParameter.cs b/mage/Tweaks/TweakParameter.cs index 0f01b21..af723fa 100644 --- a/mage/Tweaks/TweakParameter.cs +++ b/mage/Tweaks/TweakParameter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Text.Json.Serialization; namespace mage.Tweaks; @@ -9,6 +10,15 @@ public class TweakParameter public string Name { get; set; } = "New Tweak"; public string? Description { get; set; } public long? Value { get; set; } - public long? MinValue { get; set; } - public long? MaxValue { get; set; } + + [JsonConverter(typeof(JsonStringEnumConverter))] + public ParameterType Type { get; set; } = ParameterType.Value; + public string[]? Options { get; set; } +} + +public enum ParameterType +{ + Value, + Toggle, + Selection, } diff --git a/mage/Tweaks/TweakValidation.cs b/mage/Tweaks/TweakValidation.cs new file mode 100644 index 0000000..e873d63 --- /dev/null +++ b/mage/Tweaks/TweakValidation.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace mage.Tweaks; + +public static class TweakValidation +{ + private static void ShowValidationError(string message) + { + MessageBox.Show(message, "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + public static bool Validate(Tweak tweak) + { + foreach (var param in tweak.Parameters) + if (!ValidateParameter(param)) return false; + + return true; + } + + private static bool ValidateParameter(TweakParameter param) + { + if (param.Type != ParameterType.Value && !InOptions(param.Value, param.Options)) + { + ShowValidationError($"Current Value {param.Value} is not allowed as defined by the options."); + return false; + } + + if (param.Type == ParameterType.Value) + { + if (param.Options is not null || param.Options!.Length > 2) + { + ShowValidationError($"Parameter of type Value only takes two options: Min Value, Max Value. Supplied: {param.Options.Length}"); + return false; + } + + try + { + var optVals = parseValueOptions(param.Options); + if (param.Value is not null) + { + if (optVals.min is not null && param.Value < optVals.min) throw new Exception("Value cannot be smaller than Min Value"); + if (optVals.max is not null && param.Value > optVals.max) throw new Exception("Value cannot be larger than Max Value"); + } + } + catch (Exception e) + { + ShowValidationError(e.Message); + return false; + } + } + + if (param.Type == ParameterType.Toggle) + { + if (param.Options is null || param.Options.Length != 2) + { + ShowValidationError($"Parameter of type Toggle requires exactly two options: Toggle Off, Toggle On. Supplied: {param.Options.Length}"); + return false; + } + } + + if (param.Type == ParameterType.Selection) + { + if (param.Options is null || param.Options.Length % 2 != 0) + { + ShowValidationError($"Parameter of type Selection requires options in the following format: Select1, Value1, Select2, Value2..."); + return false; + } + for (int i = 1; i < param.Options.Length; i += 2) + { + try { Hex.ToInt(param.Options[i]); } + catch + { + ShowValidationError($"Option Value[{i}] is not a number"); + return false; + } + } + } + + return true; + } + + private static (int? min, int? max) parseValueOptions(string[]? options) + { + if (options is null) return (null, null); + + int? min = null; + int? max = null; + if (options.Length >= 1) + try { min = Hex.ToInt(options[0]); } + catch { throw new Exception("Min Value is not a number"); } + if (options.Length == 2) + try { max = Hex.ToInt(options[1]); } + catch { throw new Exception("Max Value is not a number"); } + return (min, max); + } + + private static bool InOptions(long? val, string[]? options) + { + if (val is null || options is null) return true; + + foreach (var opt in options) + try { if (Hex.ToInt(opt) == val) return true; } + catch { continue; } + + return false; + } +} From b8bc61be41794de3d1dd9e4d6477293a2d6d7f98 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Mon, 23 Feb 2026 21:09:05 +0100 Subject: [PATCH 09/16] displaying and applying reverting of tweaks works --- mage/Theming/ThemeSwitcher.cs | 3 +- mage/Tools/FormPatches.Designer.cs | 4 +- mage/Tweaks/FormTweaks.Designer.cs | 164 +++++++++++++++++++++++++++-- mage/Tweaks/FormTweaks.cs | 85 ++++++++++++++- mage/Tweaks/FormTweaks.resx | 3 - mage/Tweaks/Tweak.cs | 6 +- mage/Tweaks/TweakManager.cs | 10 +- mage/Tweaks/TweakPatch.cs | 15 ++- mage/Tweaks/TweakValidation.cs | 19 ++-- mage/Utility/Hex.cs | 5 + 10 files changed, 282 insertions(+), 32 deletions(-) diff --git a/mage/Theming/ThemeSwitcher.cs b/mage/Theming/ThemeSwitcher.cs index 0b4e9b4..a8711d4 100644 --- a/mage/Theming/ThemeSwitcher.cs +++ b/mage/Theming/ThemeSwitcher.cs @@ -322,7 +322,8 @@ public static void ChangeTheme(Control control) var textRect = new Rectangle(e.Bounds.X + 4, e.Bounds.Y, e.Bounds.Width - 8, e.Bounds.Height); - e.Graphics.DrawString(e.Header.Text, lv.Font, textBrush, textRect, sf); + using var font = new Font(lv.Font, FontStyle.Bold); + e.Graphics.DrawString(e.Header.Text, font, textBrush, textRect, sf); if (e.ColumnIndex == lv.Columns.Count - 1) { diff --git a/mage/Tools/FormPatches.Designer.cs b/mage/Tools/FormPatches.Designer.cs index f763aa2..7695cbe 100644 --- a/mage/Tools/FormPatches.Designer.cs +++ b/mage/Tools/FormPatches.Designer.cs @@ -79,12 +79,12 @@ private void InitializeComponent() // columnHeader_author // columnHeader_author.Text = "Author"; - columnHeader_author.Width = 85; + columnHeader_author.Width = 83; // // columnHeader_applied // columnHeader_applied.Text = "Applied"; - columnHeader_applied.Width = 51; + columnHeader_applied.Width = 53; // // FormPatches // diff --git a/mage/Tweaks/FormTweaks.Designer.cs b/mage/Tweaks/FormTweaks.Designer.cs index 89d8109..05794f5 100644 --- a/mage/Tweaks/FormTweaks.Designer.cs +++ b/mage/Tweaks/FormTweaks.Designer.cs @@ -36,18 +36,29 @@ private void InitializeComponent() clm_author = new System.Windows.Forms.ColumnHeader(); pnl_main = new System.Windows.Forms.SplitContainer(); grp_properties = new System.Windows.Forms.GroupBox(); + sep_parameters = new mage.Controls.Seperator(); + btn_applyRevert = new System.Windows.Forms.Button(); + pnl_parameters = new System.Windows.Forms.Panel(); + lbl_parameters = new System.Windows.Forms.Label(); + txb_description = new mage.Theming.CustomControls.FlatTextBox(); + lbl_author = new System.Windows.Forms.Label(); + lbl_authorLabel = new System.Windows.Forms.Label(); + lbl_descriptionLabel = new System.Windows.Forms.Label(); + lbl_name = new System.Windows.Forms.Label(); + lbl_labelName = new System.Windows.Forms.Label(); grp_tweaks.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pnl_main).BeginInit(); pnl_main.Panel1.SuspendLayout(); pnl_main.Panel2.SuspendLayout(); pnl_main.SuspendLayout(); + grp_properties.SuspendLayout(); SuspendLayout(); // // statusStrip1 // - statusStrip1.Location = new System.Drawing.Point(0, 428); + statusStrip1.Location = new System.Drawing.Point(0, 429); statusStrip1.Name = "statusStrip1"; - statusStrip1.Size = new System.Drawing.Size(797, 22); + statusStrip1.Size = new System.Drawing.Size(734, 22); statusStrip1.TabIndex = 0; statusStrip1.Text = "statusStrip1"; // @@ -57,7 +68,7 @@ private void InitializeComponent() grp_tweaks.Dock = System.Windows.Forms.DockStyle.Fill; grp_tweaks.Location = new System.Drawing.Point(6, 6); grp_tweaks.Name = "grp_tweaks"; - grp_tweaks.Size = new System.Drawing.Size(490, 419); + grp_tweaks.Size = new System.Drawing.Size(427, 420); grp_tweaks.TabIndex = 1; grp_tweaks.TabStop = false; grp_tweaks.Text = "Tweaks"; @@ -72,10 +83,11 @@ private void InitializeComponent() lst_tweaks.Location = new System.Drawing.Point(3, 19); lst_tweaks.MultiSelect = false; lst_tweaks.Name = "lst_tweaks"; - lst_tweaks.Size = new System.Drawing.Size(484, 397); + lst_tweaks.Size = new System.Drawing.Size(421, 398); lst_tweaks.TabIndex = 0; lst_tweaks.UseCompatibleStateImageBehavior = false; lst_tweaks.View = System.Windows.Forms.View.Details; + lst_tweaks.ItemSelectionChanged += lst_tweaks_ItemSelectionChanged; lst_tweaks.Resize += lst_tweaks_Resize; // // clm_name @@ -104,27 +116,151 @@ private void InitializeComponent() // pnl_main.Panel2.Controls.Add(grp_properties); pnl_main.Panel2.Padding = new System.Windows.Forms.Padding(3, 6, 6, 3); - pnl_main.Size = new System.Drawing.Size(797, 428); - pnl_main.SplitterDistance = 499; + pnl_main.Size = new System.Drawing.Size(734, 429); + pnl_main.SplitterDistance = 436; pnl_main.TabIndex = 2; // // grp_properties // + grp_properties.Controls.Add(sep_parameters); + grp_properties.Controls.Add(btn_applyRevert); + grp_properties.Controls.Add(pnl_parameters); + grp_properties.Controls.Add(lbl_parameters); + grp_properties.Controls.Add(txb_description); + grp_properties.Controls.Add(lbl_author); + grp_properties.Controls.Add(lbl_authorLabel); + grp_properties.Controls.Add(lbl_descriptionLabel); + grp_properties.Controls.Add(lbl_name); + grp_properties.Controls.Add(lbl_labelName); grp_properties.Dock = System.Windows.Forms.DockStyle.Fill; grp_properties.Location = new System.Drawing.Point(3, 6); grp_properties.Name = "grp_properties"; - grp_properties.Size = new System.Drawing.Size(285, 419); + grp_properties.Size = new System.Drawing.Size(285, 420); grp_properties.TabIndex = 0; grp_properties.TabStop = false; grp_properties.Text = "Properties"; // + // sep_parameters + // + sep_parameters.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + sep_parameters.Location = new System.Drawing.Point(6, 154); + sep_parameters.Name = "sep_parameters"; + sep_parameters.Orientation = System.Windows.Forms.Orientation.Horizontal; + sep_parameters.Size = new System.Drawing.Size(273, 1); + sep_parameters.TabIndex = 9; + sep_parameters.Text = "seperator1"; + // + // btn_applyRevert + // + btn_applyRevert.Location = new System.Drawing.Point(204, 391); + btn_applyRevert.Name = "btn_applyRevert"; + btn_applyRevert.Size = new System.Drawing.Size(75, 23); + btn_applyRevert.TabIndex = 8; + btn_applyRevert.Text = "Apply"; + btn_applyRevert.UseVisualStyleBackColor = true; + btn_applyRevert.Click += btn_applyRevert_Click; + // + // pnl_parameters + // + pnl_parameters.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + pnl_parameters.AutoScroll = true; + pnl_parameters.Location = new System.Drawing.Point(6, 182); + pnl_parameters.Name = "pnl_parameters"; + pnl_parameters.Size = new System.Drawing.Size(273, 203); + pnl_parameters.TabIndex = 7; + // + // lbl_parameters + // + lbl_parameters.AutoSize = true; + lbl_parameters.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); + lbl_parameters.Location = new System.Drawing.Point(6, 161); + lbl_parameters.Margin = new System.Windows.Forms.Padding(3); + lbl_parameters.Name = "lbl_parameters"; + lbl_parameters.Size = new System.Drawing.Size(74, 15); + lbl_parameters.TabIndex = 6; + lbl_parameters.Text = "Parameters:"; + // + // txb_description + // + txb_description.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + txb_description.AutoScroll = true; + txb_description.BorderColor = System.Drawing.Color.Black; + txb_description.DisplayBorder = false; + txb_description.Location = new System.Drawing.Point(86, 61); + txb_description.MaxLength = 32767; + txb_description.Multiline = true; + txb_description.Name = "txb_description"; + txb_description.OnTextChanged = null; + txb_description.Padding = new System.Windows.Forms.Padding(3, 3, 1, 2); + txb_description.PlaceholderText = ""; + txb_description.ReadOnly = true; + txb_description.ScrollBars = System.Windows.Forms.ScrollBars.None; + txb_description.SelectionStart = 0; + txb_description.Size = new System.Drawing.Size(193, 87); + txb_description.TabIndex = 5; + txb_description.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + txb_description.ValueBox = false; + txb_description.WordWrap = true; + // + // lbl_author + // + lbl_author.AutoSize = true; + lbl_author.Location = new System.Drawing.Point(83, 42); + lbl_author.Name = "lbl_author"; + lbl_author.Size = new System.Drawing.Size(102, 15); + lbl_author.TabIndex = 4; + lbl_author.Text = "Insert Author here"; + // + // lbl_authorLabel + // + lbl_authorLabel.AutoSize = true; + lbl_authorLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); + lbl_authorLabel.Location = new System.Drawing.Point(6, 42); + lbl_authorLabel.Margin = new System.Windows.Forms.Padding(3); + lbl_authorLabel.Name = "lbl_authorLabel"; + lbl_authorLabel.Size = new System.Drawing.Size(49, 15); + lbl_authorLabel.TabIndex = 3; + lbl_authorLabel.Text = "Author:"; + // + // lbl_descriptionLabel + // + lbl_descriptionLabel.AutoSize = true; + lbl_descriptionLabel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); + lbl_descriptionLabel.Location = new System.Drawing.Point(6, 64); + lbl_descriptionLabel.Margin = new System.Windows.Forms.Padding(3); + lbl_descriptionLabel.Name = "lbl_descriptionLabel"; + lbl_descriptionLabel.Size = new System.Drawing.Size(74, 15); + lbl_descriptionLabel.TabIndex = 2; + lbl_descriptionLabel.Text = "Description:"; + // + // lbl_name + // + lbl_name.AutoSize = true; + lbl_name.Location = new System.Drawing.Point(83, 21); + lbl_name.Name = "lbl_name"; + lbl_name.Size = new System.Drawing.Size(97, 15); + lbl_name.TabIndex = 1; + lbl_name.Text = "Insert Name here"; + // + // lbl_labelName + // + lbl_labelName.AutoSize = true; + lbl_labelName.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); + lbl_labelName.Location = new System.Drawing.Point(6, 21); + lbl_labelName.Margin = new System.Windows.Forms.Padding(3); + lbl_labelName.Name = "lbl_labelName"; + lbl_labelName.Size = new System.Drawing.Size(43, 15); + lbl_labelName.TabIndex = 0; + lbl_labelName.Text = "Name:"; + // // FormTweaks // AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - ClientSize = new System.Drawing.Size(797, 450); + ClientSize = new System.Drawing.Size(734, 451); Controls.Add(pnl_main); Controls.Add(statusStrip1); Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + MinimumSize = new System.Drawing.Size(750, 490); Name = "FormTweaks"; Text = "Tweak Manager"; grp_tweaks.ResumeLayout(false); @@ -132,6 +268,8 @@ private void InitializeComponent() pnl_main.Panel2.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)pnl_main).EndInit(); pnl_main.ResumeLayout(false); + grp_properties.ResumeLayout(false); + grp_properties.PerformLayout(); ResumeLayout(false); PerformLayout(); } @@ -145,5 +283,15 @@ private void InitializeComponent() private System.Windows.Forms.ColumnHeader clm_name; private System.Windows.Forms.ColumnHeader clm_author; private System.Windows.Forms.GroupBox grp_properties; + private System.Windows.Forms.Label lbl_labelName; + private Theming.CustomControls.FlatTextBox txb_description; + private System.Windows.Forms.Label lbl_author; + private System.Windows.Forms.Label lbl_authorLabel; + private System.Windows.Forms.Label lbl_descriptionLabel; + private System.Windows.Forms.Label lbl_name; + private System.Windows.Forms.Label lbl_parameters; + private System.Windows.Forms.Button btn_applyRevert; + private System.Windows.Forms.Panel pnl_parameters; + private Controls.Seperator sep_parameters; } } \ No newline at end of file diff --git a/mage/Tweaks/FormTweaks.cs b/mage/Tweaks/FormTweaks.cs index 3bdf9a5..d9f66ec 100644 --- a/mage/Tweaks/FormTweaks.cs +++ b/mage/Tweaks/FormTweaks.cs @@ -11,6 +11,9 @@ namespace mage.Tweaks; public partial class FormTweaks : Form { + Tweak selectedTweak; + ListViewItem selectedItem; + public FormTweaks() { InitializeComponent(); @@ -23,6 +26,7 @@ public FormTweaks() ImageList statusIcons = new ImageList(); statusIcons.Images.Add("checked", Properties.Resources.accept); statusIcons.Images.Add("unchecked", Properties.Resources.transparent); + statusIcons.ImageSize = new Size(16, 16); lst_tweaks.SmallImageList = statusIcons; lst_tweaks.View = View.Details; @@ -43,10 +47,85 @@ private void PopulateTweaksList() } } + private void DisplayTweakProperties(Tweak t) + { + lbl_author.Text = t.Author; + lbl_name.Text = t.Name; + txb_description.Text = t.Description ?? ""; + + bool hasParam = t.Parameters.Count > 0; + lbl_parameters.Visible = hasParam; + pnl_parameters.Visible = hasParam; + sep_parameters.Visible = hasParam; + pnl_parameters.Enabled = !t.Applied; + + btn_applyRevert.Text = t.Applied ? "Revert" : "Apply"; + } + private void lst_tweaks_Resize(object sender, EventArgs e) { - ListView lv = sender as ListView; - int authorFixedWidth = lv.Columns[1].Width; - lv.Columns[0].Width = lv.ClientSize.Width - authorFixedWidth; + var lv = sender as ListView; + if (lv?.Columns.Count < 2) return; + + lv.SuspendLayout(); + try + { + int fixedWidth = lv.Columns[1].Width; + + // Account for vertical scrollbar width (if items overflow) + 2px safety margin + int availableWidth = lv.ClientSize.Width + - fixedWidth; + + lv.Columns[0].Width = Math.Max(50, availableWidth); + } + finally + { + lv.ResumeLayout(); + } + } + + private void lst_tweaks_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) + { + bool itemSelected = e.Item != null; + + pnl_main.Panel2Collapsed = !itemSelected; + grp_properties.Enabled = itemSelected; + + if (!itemSelected) return; + Tweak t = TweakManager.ProjectTweaks[e.ItemIndex]; + DisplayTweakProperties(t); + selectedTweak = t; + selectedItem = e.Item; + } + + private void btn_applyRevert_Click(object sender, EventArgs e) + { + if (selectedTweak.Applied) Revert(selectedTweak); + else Apply(selectedTweak); + UpdateListItem(selectedItem, selectedTweak); + DisplayTweakProperties(selectedTweak); + } + + private void Apply(Tweak t) + { + try + { + if (!TweakValidation.Validate(t)) return; + t.Apply(ROM.Stream); + } + catch (Exception e) + { + MessageBox.Show($"Could not apply Tweak.\n\n{e.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + } + private void Revert(Tweak t) + { + t.Revert(ROM.Stream); + } + + private void UpdateListItem(ListViewItem item, Tweak tweak) + { + item.ImageIndex = tweak.Applied ? 0 : 1; } } diff --git a/mage/Tweaks/FormTweaks.resx b/mage/Tweaks/FormTweaks.resx index 09b770d..6cd43ed 100644 --- a/mage/Tweaks/FormTweaks.resx +++ b/mage/Tweaks/FormTweaks.resx @@ -120,9 +120,6 @@ 17, 17 - - True - diff --git a/mage/Tweaks/Tweak.cs b/mage/Tweaks/Tweak.cs index d4b01b2..3a53514 100644 --- a/mage/Tweaks/Tweak.cs +++ b/mage/Tweaks/Tweak.cs @@ -51,7 +51,7 @@ private void CheckIfOverwritingCorrectVals(ByteStream rom, TweakPatch patch, int { if (patch.OldData == null) return; - byte[] expected = patch.OldData; + byte[] expected = patch.ResolveOldData(); int len = expected.Length; byte[] current = new byte[len]; @@ -84,7 +84,7 @@ public void Apply(ByteStream rom) patch.OldOffset = offset; // Checking if overwriting should be done or saving old values - if (patch.OldData == null || HasDynamicPatchLocation) patch.OldData = old; + if (patch.OldData == null || HasDynamicPatchLocation) patch.SetOldData(old); else CheckIfOverwritingCorrectVals(rom, patch, offset); // Write patch data @@ -114,7 +114,7 @@ public void Revert(ByteStream rom) foreach (var patch in Patches) { int offset = patch.OldOffset ?? 0; - byte[] old = patch.OldData; + byte[] old = patch.ResolveOldData(); rom.CopyFromArray(old, 0, offset, old.Length); } diff --git a/mage/Tweaks/TweakManager.cs b/mage/Tweaks/TweakManager.cs index 9783283..947caac 100644 --- a/mage/Tweaks/TweakManager.cs +++ b/mage/Tweaks/TweakManager.cs @@ -15,11 +15,15 @@ public static List ProjectTweaks { get { - string json = File.ReadAllText("C:\\Users\\Conner\\Desktop\\testtweak.json"); - return Deserialize(json); + if (field == null) + { + string json = File.ReadAllText("C:\\Users\\Conner\\Desktop\\testtweak.json"); + field = Deserialize(json); + } + return field; } set; - } = new(); + } = null; // Serializing diff --git a/mage/Tweaks/TweakPatch.cs b/mage/Tweaks/TweakPatch.cs index b632492..b43347b 100644 --- a/mage/Tweaks/TweakPatch.cs +++ b/mage/Tweaks/TweakPatch.cs @@ -10,14 +10,23 @@ public class TweakPatch public List Data { get; set; } = []; public int? OldOffset { get; set; } - public byte[]? OldData { get; set; } + public List? OldData { get; set; } public long ResolveOffset(IReadOnlyDictionary parameters) => EvaluateExpression(Offset, parameters); - public byte[] ResolveData(IReadOnlyDictionary parameters) + public byte[] ResolveData(IReadOnlyDictionary parameters) => ResolveByteList(Data, parameters); + public byte[] ResolveOldData() => ResolveByteList(OldData, null); + + public void SetOldData(byte[] data) + { + OldData = new(); + foreach (var b in data) OldData.Add(Hex.ToString(b, 10)); + } + + private byte[] ResolveByteList(List data, IReadOnlyDictionary parameters) { var resultBytes = new List(); - foreach (var expression in Data) + foreach (var expression in data) { long value = EvaluateExpression(expression, parameters); resultBytes.Add((byte)(value & 0xFF)); diff --git a/mage/Tweaks/TweakValidation.cs b/mage/Tweaks/TweakValidation.cs index e873d63..81a1d67 100644 --- a/mage/Tweaks/TweakValidation.cs +++ b/mage/Tweaks/TweakValidation.cs @@ -1,4 +1,5 @@ -using System; +using NCalc; +using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; @@ -30,7 +31,7 @@ private static bool ValidateParameter(TweakParameter param) if (param.Type == ParameterType.Value) { - if (param.Options is not null || param.Options!.Length > 2) + if (param.Options is not null && param.Options!.Length > 2) { ShowValidationError($"Parameter of type Value only takes two options: Min Value, Max Value. Supplied: {param.Options.Length}"); return false; @@ -70,7 +71,7 @@ private static bool ValidateParameter(TweakParameter param) } for (int i = 1; i < param.Options.Length; i += 2) { - try { Hex.ToInt(param.Options[i]); } + try { evaluate(param.Options[i]); } catch { ShowValidationError($"Option Value[{i}] is not a number"); @@ -89,10 +90,10 @@ private static (int? min, int? max) parseValueOptions(string[]? options) int? min = null; int? max = null; if (options.Length >= 1) - try { min = Hex.ToInt(options[0]); } + try { min = evaluate(options[0]); } catch { throw new Exception("Min Value is not a number"); } if (options.Length == 2) - try { max = Hex.ToInt(options[1]); } + try { max = evaluate(options[1]); } catch { throw new Exception("Max Value is not a number"); } return (min, max); } @@ -102,9 +103,15 @@ private static bool InOptions(long? val, string[]? options) if (val is null || options is null) return true; foreach (var opt in options) - try { if (Hex.ToInt(opt) == val) return true; } + try { if (evaluate(opt) == val) return true; } catch { continue; } return false; } + + private static int evaluate(string expression) + { + Expression ex = new Expression(expression); + return Convert.ToInt32(ex.Evaluate()); + } } diff --git a/mage/Utility/Hex.cs b/mage/Utility/Hex.cs index 5d5b730..0d75246 100644 --- a/mage/Utility/Hex.cs +++ b/mage/Utility/Hex.cs @@ -23,6 +23,11 @@ public static string ToString(int value) return Convert.ToString(value, radix).ToUpper(); } + public static string ToString(int value, int radix) + { + return Convert.ToString(value, radix).ToUpper(); + } + public static string ToPrefixedPaddedString(int value) { return $"0x{Convert.ToString(value, 16).ToUpper().PadLeft(4, '0')}"; From a35f9707c9b3cff8c0bdc7d4d50ec861949e4050 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 26 Feb 2026 14:09:04 +0100 Subject: [PATCH 10/16] feat: export tile table as image --- .../NewEditors/FormTileTableNew.Designer.cs | 64 +++++++++++++------ mage/Editors/NewEditors/FormTileTableNew.cs | 15 +++++ mage/Editors/NewEditors/FormTileTableNew.resx | 3 + 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/mage/Editors/NewEditors/FormTileTableNew.Designer.cs b/mage/Editors/NewEditors/FormTileTableNew.Designer.cs index 59be384..4780390 100644 --- a/mage/Editors/NewEditors/FormTileTableNew.Designer.cs +++ b/mage/Editors/NewEditors/FormTileTableNew.Designer.cs @@ -44,6 +44,8 @@ private void InitializeComponent() button_gfxZoomIn = new System.Windows.Forms.ToolStripButton(); button_gfxZoomOut = new System.Windows.Forms.ToolStripButton(); label_gfxZoom = new System.Windows.Forms.ToolStripLabel(); + toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + button_editGfx = new System.Windows.Forms.ToolStripButton(); panel_select = new mage.Controls.ExtendedPanel(); tab_select = new mage.Theming.CustomControls.FlatTabControl(); tabPage_tileset = new System.Windows.Forms.TabPage(); @@ -93,8 +95,9 @@ private void InitializeComponent() statusButton_import = new System.Windows.Forms.ToolStripDropDownButton(); statusButton_export = new System.Windows.Forms.ToolStripDropDownButton(); button_apply = new System.Windows.Forms.ToolStripDropDownButton(); - toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - button_editGfx = new System.Windows.Forms.ToolStripButton(); + btn_exportTT = new System.Windows.Forms.ToolStripMenuItem(); + btn_exportImg = new System.Windows.Forms.ToolStripMenuItem(); + bnt_importTT = new System.Windows.Forms.ToolStripMenuItem(); panel_gfxView.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)panel_Main).BeginInit(); panel_Main.Panel1.SuspendLayout(); @@ -336,6 +339,21 @@ private void InitializeComponent() label_gfxZoom.Size = new System.Drawing.Size(35, 22); label_gfxZoom.Text = "100%"; // + // toolStripSeparator4 + // + toolStripSeparator4.Name = "toolStripSeparator4"; + toolStripSeparator4.Size = new System.Drawing.Size(6, 25); + // + // button_editGfx + // + button_editGfx.Image = Properties.Resources.toolbar_graphics; + button_editGfx.ImageTransparentColor = System.Drawing.Color.Magenta; + button_editGfx.Name = "button_editGfx"; + button_editGfx.Size = new System.Drawing.Size(71, 22); + button_editGfx.Text = "Edit GFX"; + button_editGfx.TextImageRelation = System.Windows.Forms.TextImageRelation.TextBeforeImage; + button_editGfx.Click += button_editGfx_Click; + // // panel_select // panel_select.Controls.Add(tab_select); @@ -859,30 +877,29 @@ private void InitializeComponent() // spring // spring.Name = "spring"; - spring.Size = new System.Drawing.Size(580, 17); + spring.Size = new System.Drawing.Size(531, 17); spring.Spring = true; // // statusButton_import // statusButton_import.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + statusButton_import.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { bnt_importTT }); statusButton_import.Image = (System.Drawing.Image)resources.GetObject("statusButton_import.Image"); statusButton_import.ImageTransparentColor = System.Drawing.Color.Magenta; statusButton_import.Name = "statusButton_import"; - statusButton_import.ShowDropDownArrow = false; - statusButton_import.Size = new System.Drawing.Size(47, 20); + statusButton_import.Size = new System.Drawing.Size(56, 20); statusButton_import.Text = "Import"; statusButton_import.Click += statusButton_import_Click; // // statusButton_export // statusButton_export.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + statusButton_export.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { btn_exportImg, btn_exportTT }); statusButton_export.Image = (System.Drawing.Image)resources.GetObject("statusButton_export.Image"); statusButton_export.ImageTransparentColor = System.Drawing.Color.Magenta; statusButton_export.Name = "statusButton_export"; - statusButton_export.ShowDropDownArrow = false; - statusButton_export.Size = new System.Drawing.Size(45, 20); + statusButton_export.Size = new System.Drawing.Size(54, 20); statusButton_export.Text = "Export"; - statusButton_export.Click += statusButton_export_Click; // // button_apply // @@ -895,20 +912,26 @@ private void InitializeComponent() button_apply.Text = "Apply"; button_apply.Click += button_apply_Click; // - // toolStripSeparator4 + // btn_exportTT // - toolStripSeparator4.Name = "toolStripSeparator4"; - toolStripSeparator4.Size = new System.Drawing.Size(6, 25); + btn_exportTT.Name = "btn_exportTT"; + btn_exportTT.Size = new System.Drawing.Size(180, 22); + btn_exportTT.Text = "Tile Table..."; + btn_exportTT.Click += statusButton_export_Click; // - // button_editGfx + // btn_exportImg // - button_editGfx.Image = Properties.Resources.toolbar_graphics; - button_editGfx.ImageTransparentColor = System.Drawing.Color.Magenta; - button_editGfx.Name = "button_editGfx"; - button_editGfx.Size = new System.Drawing.Size(71, 22); - button_editGfx.Text = "Edit GFX"; - button_editGfx.TextImageRelation = System.Windows.Forms.TextImageRelation.TextBeforeImage; - button_editGfx.Click += button_editGfx_Click; + btn_exportImg.Name = "btn_exportImg"; + btn_exportImg.Size = new System.Drawing.Size(180, 22); + btn_exportImg.Text = "Image..."; + btn_exportImg.Click += btn_exportImg_Click; + // + // bnt_importTT + // + bnt_importTT.Name = "bnt_importTT"; + bnt_importTT.Size = new System.Drawing.Size(180, 22); + bnt_importTT.Text = "Tile Table..."; + bnt_importTT.Click += statusButton_import_Click; // // FormTileTableNew // @@ -1026,5 +1049,8 @@ private void InitializeComponent() private Controls.ExtendedPanel panel_tableView; private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; private System.Windows.Forms.ToolStripButton button_editGfx; + private System.Windows.Forms.ToolStripMenuItem btn_exportImg; + private System.Windows.Forms.ToolStripMenuItem btn_exportTT; + private System.Windows.Forms.ToolStripMenuItem bnt_importTT; } } \ No newline at end of file diff --git a/mage/Editors/NewEditors/FormTileTableNew.cs b/mage/Editors/NewEditors/FormTileTableNew.cs index a95ea3d..9dcdbe4 100644 --- a/mage/Editors/NewEditors/FormTileTableNew.cs +++ b/mage/Editors/NewEditors/FormTileTableNew.cs @@ -1384,5 +1384,20 @@ private void button_editGfx_Click(object sender, EventArgs e) { FormGraphicsNew.OpenGraphicsEditor(gfxSourceOffset, 32, 0, palSourceOffset); } + + private void btn_exportImg_Click(object sender, EventArgs e) + { + if (tableView.TileImage is null) + { + MessageBox.Show("Please load a Tile Table first.", "No Tile Table loaded", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + SaveFileDialog saveTileset = new SaveFileDialog(); + saveTileset.Filter = "PNG files (*.png)|*.png"; + if (saveTileset.ShowDialog() != DialogResult.OK) return; + + tableView.TileImage.Save(saveTileset.FileName); + } } } diff --git a/mage/Editors/NewEditors/FormTileTableNew.resx b/mage/Editors/NewEditors/FormTileTableNew.resx index 6ac1688..5523c93 100644 --- a/mage/Editors/NewEditors/FormTileTableNew.resx +++ b/mage/Editors/NewEditors/FormTileTableNew.resx @@ -123,6 +123,9 @@ 279, 17 + + 158, 17 + 279, 17 From 48d9da0000e55059df03f65d52d22dce70bf145c Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:42:13 +0100 Subject: [PATCH 11/16] feat: export room as pixel image --- .../RoomPixelImageExportDialog.Designer.cs | 47 + mage/Dialogs/RoomPixelImageExportDialog.cs | 44 + mage/Dialogs/RoomPixelImageExportDialog.resx | 120 +++ mage/FormMain.Designer.cs | 105 ++- mage/FormMain.cs | 22 +- mage/Room/ClipTypes.cs | 884 +++++++++++------- 6 files changed, 816 insertions(+), 406 deletions(-) create mode 100644 mage/Dialogs/RoomPixelImageExportDialog.Designer.cs create mode 100644 mage/Dialogs/RoomPixelImageExportDialog.cs create mode 100644 mage/Dialogs/RoomPixelImageExportDialog.resx diff --git a/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs b/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs new file mode 100644 index 0000000..a2363ad --- /dev/null +++ b/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs @@ -0,0 +1,47 @@ +namespace mage.Dialogs +{ + partial class RoomPixelImageExportDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + SuspendLayout(); + // + // RoomPixelImageExportDialog + // + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + ClientSize = new System.Drawing.Size(800, 450); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + MaximizeBox = false; + MinimizeBox = false; + Name = "RoomPixelImageExportDialog"; + Text = "Save Pixel Room Image"; + ResumeLayout(false); + } + + #endregion + } +} \ No newline at end of file diff --git a/mage/Dialogs/RoomPixelImageExportDialog.cs b/mage/Dialogs/RoomPixelImageExportDialog.cs new file mode 100644 index 0000000..518a9a7 --- /dev/null +++ b/mage/Dialogs/RoomPixelImageExportDialog.cs @@ -0,0 +1,44 @@ +using mage.Theming; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace mage.Dialogs; + +public struct RoomPixelImageExportDialogResult +{ + public RoomPixelImageExportDialogResult() { } + + public Color ColorBackground { get; set; } = Color.Black; + public Color ColorSolid { get; set; } = Color.Gray; + + public Color ColorBlueHatch { get; set; } = Color.Blue; + public Color ColorRedHatch { get; set; } = Color.Red; + public Color ColorYellowHatch { get; set; } = Color.Yellow; + public Color ColorGreenHatch { get; set; } = Color.Green; + public Color ColorGrayHatch { get; set; } = Color.LightGray; + + public Color ColorShotBlock { get; set; } = Color.White; + public Color ColorCrumbleBlock { get; set; } = Color.LightGray; + public Color ColorBombBlock { get; set; } = Color.MediumPurple; + public Color ColorMissileBlock { get; set; } = Color.IndianRed; + public Color ColorSuperBlock { get; set; } = Color.LawnGreen; + public Color ColorSpeedBlock { get; set; } = Color.GreenYellow; + public Color ColorScrewBlock { get; set; } = Color.Gold; + public Color ColorPowerBlock { get; set; } = Color.Purple; +} + +public partial class RoomPixelImageExportDialog : Form +{ + public RoomPixelImageExportDialog() + { + InitializeComponent(); + + ThemeSwitcher.ChangeTheme(Controls, this); + ThemeSwitcher.InjectPaintOverrides(Controls); + } +} diff --git a/mage/Dialogs/RoomPixelImageExportDialog.resx b/mage/Dialogs/RoomPixelImageExportDialog.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/mage/Dialogs/RoomPixelImageExportDialog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mage/FormMain.Designer.cs b/mage/FormMain.Designer.cs index 0e64774..ab0ef2b 100644 --- a/mage/FormMain.Designer.cs +++ b/mage/FormMain.Designer.cs @@ -148,6 +148,7 @@ private void InitializeComponent() menuItem_addTileset = new System.Windows.Forms.ToolStripMenuItem(); menuItem_addSpriteset = new System.Windows.Forms.ToolStripMenuItem(); menuItem_addAnim = new System.Windows.Forms.ToolStripMenuItem(); + tweaksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); menuItem_patches = new System.Windows.Forms.ToolStripMenuItem(); seperator_flip = new System.Windows.Forms.ToolStripSeparator(); menuItem_flip_h = new System.Windows.Forms.ToolStripMenuItem(); @@ -279,7 +280,7 @@ private void InitializeComponent() comboBox_spriteset = new mage.Theming.CustomControls.FlatComboBox(); ToolTip = new System.Windows.Forms.ToolTip(components); splitContainer1 = new System.Windows.Forms.SplitContainer(); - tweaksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + pixelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); menuStrip.SuspendLayout(); groupBox_location.SuspendLayout(); groupBox_tileset.SuspendLayout(); @@ -720,7 +721,7 @@ private void InitializeComponent() // menuItem_headerEditor.Image = Properties.Resources.toolbar_header; menuItem_headerEditor.Name = "menuItem_headerEditor"; - menuItem_headerEditor.Size = new System.Drawing.Size(180, 22); + menuItem_headerEditor.Size = new System.Drawing.Size(170, 22); menuItem_headerEditor.Text = "Header Editor"; menuItem_headerEditor.Click += menuItem_headerEditor_Click; // @@ -728,20 +729,20 @@ private void InitializeComponent() // menuItem_tilesetEditor.Image = Properties.Resources.shortcut_screw; menuItem_tilesetEditor.Name = "menuItem_tilesetEditor"; - menuItem_tilesetEditor.Size = new System.Drawing.Size(180, 22); + menuItem_tilesetEditor.Size = new System.Drawing.Size(170, 22); menuItem_tilesetEditor.Text = "Tileset Editor"; menuItem_tilesetEditor.Click += menuItem_tilesetEditor_Click; // // toolStripSeparator24 // toolStripSeparator24.Name = "toolStripSeparator24"; - toolStripSeparator24.Size = new System.Drawing.Size(177, 6); + toolStripSeparator24.Size = new System.Drawing.Size(167, 6); // // menuItem_graphicsEditor // menuItem_graphicsEditor.Image = Properties.Resources.toolbar_graphics; menuItem_graphicsEditor.Name = "menuItem_graphicsEditor"; - menuItem_graphicsEditor.Size = new System.Drawing.Size(180, 22); + menuItem_graphicsEditor.Size = new System.Drawing.Size(170, 22); menuItem_graphicsEditor.Text = "Graphics Editor"; menuItem_graphicsEditor.Click += menuItem_graphicsEditor_Click; // @@ -749,7 +750,7 @@ private void InitializeComponent() // menuItem_paletteEditor.Image = Properties.Resources.toolbar_palette; menuItem_paletteEditor.Name = "menuItem_paletteEditor"; - menuItem_paletteEditor.Size = new System.Drawing.Size(180, 22); + menuItem_paletteEditor.Size = new System.Drawing.Size(170, 22); menuItem_paletteEditor.Text = "Palette Editor"; menuItem_paletteEditor.Click += menuItem_paletteEditor_Click; // @@ -757,7 +758,7 @@ private void InitializeComponent() // menuItem_tileTableEditor.Image = Properties.Resources.toolbar_tile_table; menuItem_tileTableEditor.Name = "menuItem_tileTableEditor"; - menuItem_tileTableEditor.Size = new System.Drawing.Size(180, 22); + menuItem_tileTableEditor.Size = new System.Drawing.Size(170, 22); menuItem_tileTableEditor.Text = "Tile Table Editor"; menuItem_tileTableEditor.Click += menuItem_tileTableEditor_Click; // @@ -765,7 +766,7 @@ private void InitializeComponent() // menuItem_animationEditor.Image = Properties.Resources.toolbar_animation; menuItem_animationEditor.Name = "menuItem_animationEditor"; - menuItem_animationEditor.Size = new System.Drawing.Size(180, 22); + menuItem_animationEditor.Size = new System.Drawing.Size(170, 22); menuItem_animationEditor.Text = "Animation Editor"; menuItem_animationEditor.Click += menuItem_animationEditor_Click; // @@ -773,20 +774,20 @@ private void InitializeComponent() // menuItem_oamViewer.Image = Properties.Resources.toolbar_oam; menuItem_oamViewer.Name = "menuItem_oamViewer"; - menuItem_oamViewer.Size = new System.Drawing.Size(180, 22); + menuItem_oamViewer.Size = new System.Drawing.Size(170, 22); menuItem_oamViewer.Text = "OAM Editor"; menuItem_oamViewer.Click += menuItem_oamViewer_Click; // // toolStripSeparator25 // toolStripSeparator25.Name = "toolStripSeparator25"; - toolStripSeparator25.Size = new System.Drawing.Size(177, 6); + toolStripSeparator25.Size = new System.Drawing.Size(167, 6); // // menuItem_spriteEditor // menuItem_spriteEditor.Image = Properties.Resources.toolbar_sprite; menuItem_spriteEditor.Name = "menuItem_spriteEditor"; - menuItem_spriteEditor.Size = new System.Drawing.Size(180, 22); + menuItem_spriteEditor.Size = new System.Drawing.Size(170, 22); menuItem_spriteEditor.Text = "Sprite Editor"; menuItem_spriteEditor.Click += menuItem_spriteEditor_Click; // @@ -794,7 +795,7 @@ private void InitializeComponent() // menuItem_spritesetEditor.Image = Properties.Resources.toolbar_spriteset; menuItem_spritesetEditor.Name = "menuItem_spritesetEditor"; - menuItem_spritesetEditor.Size = new System.Drawing.Size(180, 22); + menuItem_spritesetEditor.Size = new System.Drawing.Size(170, 22); menuItem_spritesetEditor.Text = "Spriteset Editor"; menuItem_spritesetEditor.Click += menuItem_spritesetEditor_Click; // @@ -802,7 +803,7 @@ private void InitializeComponent() // menuItem_minimapEditor.Image = Properties.Resources.toolbar_minimap; menuItem_minimapEditor.Name = "menuItem_minimapEditor"; - menuItem_minimapEditor.Size = new System.Drawing.Size(180, 22); + menuItem_minimapEditor.Size = new System.Drawing.Size(170, 22); menuItem_minimapEditor.Text = "Map Editor"; menuItem_minimapEditor.Click += menuItem_minimapEditor_Click; // @@ -810,20 +811,20 @@ private void InitializeComponent() // menuItem_connectionEditor.Image = Properties.Resources.toolbar_connection; menuItem_connectionEditor.Name = "menuItem_connectionEditor"; - menuItem_connectionEditor.Size = new System.Drawing.Size(180, 22); + menuItem_connectionEditor.Size = new System.Drawing.Size(170, 22); menuItem_connectionEditor.Text = "Connection Editor"; menuItem_connectionEditor.Click += menuItem_connectionEditor_Click; // // toolStripSeparator26 // toolStripSeparator26.Name = "toolStripSeparator26"; - toolStripSeparator26.Size = new System.Drawing.Size(177, 6); + toolStripSeparator26.Size = new System.Drawing.Size(167, 6); // // menuItem_textEditor // menuItem_textEditor.Image = Properties.Resources.toolbar_text; menuItem_textEditor.Name = "menuItem_textEditor"; - menuItem_textEditor.Size = new System.Drawing.Size(180, 22); + menuItem_textEditor.Size = new System.Drawing.Size(170, 22); menuItem_textEditor.Text = "Text Editor"; menuItem_textEditor.Click += menuItem_textEditor_Click; // @@ -831,7 +832,7 @@ private void InitializeComponent() // menuItem_demoEditor.Image = Properties.Resources.toolbar_demo; menuItem_demoEditor.Name = "menuItem_demoEditor"; - menuItem_demoEditor.Size = new System.Drawing.Size(180, 22); + menuItem_demoEditor.Size = new System.Drawing.Size(170, 22); menuItem_demoEditor.Text = "Demo Editor"; menuItem_demoEditor.Click += menuItem_demoEditor_Click; // @@ -839,7 +840,7 @@ private void InitializeComponent() // menuItem_physicsEditor.Image = Properties.Resources.toolbar_physics; menuItem_physicsEditor.Name = "menuItem_physicsEditor"; - menuItem_physicsEditor.Size = new System.Drawing.Size(180, 22); + menuItem_physicsEditor.Size = new System.Drawing.Size(170, 22); menuItem_physicsEditor.Text = "Physics Editor"; menuItem_physicsEditor.Click += menuItem_physicsEditor_Click; // @@ -847,7 +848,7 @@ private void InitializeComponent() // menuItem_weaponEditor.Image = Properties.Resources.toolbar_weapon; menuItem_weaponEditor.Name = "menuItem_weaponEditor"; - menuItem_weaponEditor.Size = new System.Drawing.Size(180, 22); + menuItem_weaponEditor.Size = new System.Drawing.Size(170, 22); menuItem_weaponEditor.Text = "Weapon Editor"; menuItem_weaponEditor.Click += menuItem_weaponEditor_Click; // @@ -855,7 +856,7 @@ private void InitializeComponent() // menuItem_creditsEditor.Image = Properties.Resources.toolbar_credits; menuItem_creditsEditor.Name = "menuItem_creditsEditor"; - menuItem_creditsEditor.Size = new System.Drawing.Size(180, 22); + menuItem_creditsEditor.Size = new System.Drawing.Size(170, 22); menuItem_creditsEditor.Text = "Credits Editor"; menuItem_creditsEditor.Click += menuItem_creditsEditor_Click; // @@ -981,68 +982,68 @@ private void InitializeComponent() // menuItem_exportTileset // menuItem_exportTileset.Name = "menuItem_exportTileset"; - menuItem_exportTileset.Size = new System.Drawing.Size(152, 22); + menuItem_exportTileset.Size = new System.Drawing.Size(180, 22); menuItem_exportTileset.Text = "Tileset..."; menuItem_exportTileset.Click += menuItem_exportTileset_Click; // // menuItem_exportBG // menuItem_exportBG.Name = "menuItem_exportBG"; - menuItem_exportBG.Size = new System.Drawing.Size(152, 22); + menuItem_exportBG.Size = new System.Drawing.Size(180, 22); menuItem_exportBG.Text = "Background..."; menuItem_exportBG.Click += menuItem_exportBG_Click; // // menuItem_exportRoom // menuItem_exportRoom.Name = "menuItem_exportRoom"; - menuItem_exportRoom.Size = new System.Drawing.Size(152, 22); + menuItem_exportRoom.Size = new System.Drawing.Size(180, 22); menuItem_exportRoom.Text = "Room..."; menuItem_exportRoom.Click += menuItem_exportRoom_Click; // // toolStripSeparator7 // toolStripSeparator7.Name = "toolStripSeparator7"; - toolStripSeparator7.Size = new System.Drawing.Size(149, 6); + toolStripSeparator7.Size = new System.Drawing.Size(177, 6); // // menuItem_exportTilesetImage // menuItem_exportTilesetImage.Name = "menuItem_exportTilesetImage"; - menuItem_exportTilesetImage.Size = new System.Drawing.Size(152, 22); + menuItem_exportTilesetImage.Size = new System.Drawing.Size(180, 22); menuItem_exportTilesetImage.Text = "Tileset Image..."; menuItem_exportTilesetImage.Click += menuItem_exportTilesetImage_Click; // // menuItem_exportBG0image // menuItem_exportBG0image.Name = "menuItem_exportBG0image"; - menuItem_exportBG0image.Size = new System.Drawing.Size(152, 22); + menuItem_exportBG0image.Size = new System.Drawing.Size(180, 22); menuItem_exportBG0image.Text = "BG0 Image..."; menuItem_exportBG0image.Click += menuItem_exportBG0image_Click; // // menuItem_exportBG3image // menuItem_exportBG3image.Name = "menuItem_exportBG3image"; - menuItem_exportBG3image.Size = new System.Drawing.Size(152, 22); + menuItem_exportBG3image.Size = new System.Drawing.Size(180, 22); menuItem_exportBG3image.Text = "BG3 Image..."; menuItem_exportBG3image.Click += menuItem_exportBG3image_Click; // // menuItem_exportRoomImage // - menuItem_exportRoomImage.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { regularToolStripMenuItem, croppedToolStripMenuItem }); + menuItem_exportRoomImage.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { regularToolStripMenuItem, croppedToolStripMenuItem, pixelToolStripMenuItem }); menuItem_exportRoomImage.Name = "menuItem_exportRoomImage"; - menuItem_exportRoomImage.Size = new System.Drawing.Size(152, 22); + menuItem_exportRoomImage.Size = new System.Drawing.Size(180, 22); menuItem_exportRoomImage.Text = "Room Image"; // // regularToolStripMenuItem // regularToolStripMenuItem.Name = "regularToolStripMenuItem"; - regularToolStripMenuItem.Size = new System.Drawing.Size(129, 22); + regularToolStripMenuItem.Size = new System.Drawing.Size(180, 22); regularToolStripMenuItem.Text = "Regular..."; regularToolStripMenuItem.Click += menuItem_exportRoomImage_Click; // // croppedToolStripMenuItem // croppedToolStripMenuItem.Name = "croppedToolStripMenuItem"; - croppedToolStripMenuItem.Size = new System.Drawing.Size(129, 22); + croppedToolStripMenuItem.Size = new System.Drawing.Size(180, 22); croppedToolStripMenuItem.Text = "Cropped..."; croppedToolStripMenuItem.Click += menuItem_exportCroppedRoomImage_Click; // @@ -1125,45 +1126,52 @@ private void InitializeComponent() // menuItem_addBG // menuItem_addBG.Name = "menuItem_addBG"; - menuItem_addBG.Size = new System.Drawing.Size(180, 22); + menuItem_addBG.Size = new System.Drawing.Size(144, 22); menuItem_addBG.Text = "Background"; menuItem_addBG.Click += menuItem_addItem_Click; // // menuItem_addEnemyset // menuItem_addEnemyset.Name = "menuItem_addEnemyset"; - menuItem_addEnemyset.Size = new System.Drawing.Size(180, 22); + menuItem_addEnemyset.Size = new System.Drawing.Size(144, 22); menuItem_addEnemyset.Text = "Room Sprites"; menuItem_addEnemyset.Click += menuItem_addItem_Click; // // menuItem_addRoom // menuItem_addRoom.Name = "menuItem_addRoom"; - menuItem_addRoom.Size = new System.Drawing.Size(180, 22); + menuItem_addRoom.Size = new System.Drawing.Size(144, 22); menuItem_addRoom.Text = "Room"; menuItem_addRoom.Click += menuItem_addItem_Click; // // menuItem_addTileset // menuItem_addTileset.Name = "menuItem_addTileset"; - menuItem_addTileset.Size = new System.Drawing.Size(180, 22); + menuItem_addTileset.Size = new System.Drawing.Size(144, 22); menuItem_addTileset.Text = "Tileset"; menuItem_addTileset.Click += menuItem_addItem_Click; // // menuItem_addSpriteset // menuItem_addSpriteset.Name = "menuItem_addSpriteset"; - menuItem_addSpriteset.Size = new System.Drawing.Size(180, 22); + menuItem_addSpriteset.Size = new System.Drawing.Size(144, 22); menuItem_addSpriteset.Text = "Spriteset"; menuItem_addSpriteset.Click += menuItem_addItem_Click; // // menuItem_addAnim // menuItem_addAnim.Name = "menuItem_addAnim"; - menuItem_addAnim.Size = new System.Drawing.Size(180, 22); + menuItem_addAnim.Size = new System.Drawing.Size(144, 22); menuItem_addAnim.Text = "Animation"; menuItem_addAnim.Click += menuItem_addItem_Click; // + // tweaksToolStripMenuItem + // + tweaksToolStripMenuItem.Name = "tweaksToolStripMenuItem"; + tweaksToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + tweaksToolStripMenuItem.Text = "Tweaks"; + tweaksToolStripMenuItem.Click += tweaksToolStripMenuItem_Click; + // // menuItem_patches // menuItem_patches.Image = Properties.Resources.toolbar_patches; @@ -1205,7 +1213,7 @@ private void InitializeComponent() // menuItem_options.Image = Properties.Resources.cog; menuItem_options.Name = "menuItem_options"; - menuItem_options.Size = new System.Drawing.Size(180, 22); + menuItem_options.Size = new System.Drawing.Size(165, 22); menuItem_options.Text = "Preferences..."; menuItem_options.Click += programSettingsToolStripMenuItem_Click; // @@ -1214,21 +1222,21 @@ private void InitializeComponent() menuItem_projectSettings.Enabled = false; menuItem_projectSettings.Image = Properties.Resources.script_gear; menuItem_projectSettings.Name = "menuItem_projectSettings"; - menuItem_projectSettings.Size = new System.Drawing.Size(180, 22); + menuItem_projectSettings.Size = new System.Drawing.Size(165, 22); menuItem_projectSettings.Text = "Project Settings..."; menuItem_projectSettings.Click += menuItem_projectSettings_Click; // // toolStripSeparator31 // toolStripSeparator31.Name = "toolStripSeparator31"; - toolStripSeparator31.Size = new System.Drawing.Size(177, 6); + toolStripSeparator31.Size = new System.Drawing.Size(162, 6); // // menuItem_defaultView // menuItem_defaultView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { menuItem_defaultBG0, menuItem_defaultBG1, menuItem_defaultBG2, menuItem_defaultBG3, menuItem_defaultClipdata, toolStripSeparator13, menuItem_defaultSprites, menuItem_defaultSpriteOutlines, menuItem_defaultDoors, menuItem_defaultScrolls, menuItem_defaultScreens }); menuItem_defaultView.Enabled = false; menuItem_defaultView.Name = "menuItem_defaultView"; - menuItem_defaultView.Size = new System.Drawing.Size(180, 22); + menuItem_defaultView.Size = new System.Drawing.Size(165, 22); menuItem_defaultView.Text = "Default View"; // // menuItem_defaultBG0 @@ -1345,14 +1353,14 @@ private void InitializeComponent() // menuItem_tooltips.Enabled = false; menuItem_tooltips.Name = "menuItem_tooltips"; - menuItem_tooltips.Size = new System.Drawing.Size(180, 22); + menuItem_tooltips.Size = new System.Drawing.Size(165, 22); menuItem_tooltips.Text = "Disable Tooltips"; menuItem_tooltips.Click += menuItem_tooltips_Click; // // toolStripSeparator21 // toolStripSeparator21.Name = "toolStripSeparator21"; - toolStripSeparator21.Size = new System.Drawing.Size(177, 6); + toolStripSeparator21.Size = new System.Drawing.Size(162, 6); // // menuStrip_help // @@ -2386,12 +2394,12 @@ private void InitializeComponent() splitContainer1.TabIndex = 0; splitContainer1.SplitterMoved += splitContainer1_SplitterMoved; // - // tweaksToolStripMenuItem + // pixelToolStripMenuItem // - tweaksToolStripMenuItem.Name = "tweaksToolStripMenuItem"; - tweaksToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - tweaksToolStripMenuItem.Text = "Tweaks"; - tweaksToolStripMenuItem.Click += tweaksToolStripMenuItem_Click; + pixelToolStripMenuItem.Name = "pixelToolStripMenuItem"; + pixelToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + pixelToolStripMenuItem.Text = "Pixel..."; + pixelToolStripMenuItem.Click += menuItem_exportPixelRoomImage_Click; // // FormMain // @@ -2697,6 +2705,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripButton toolStrip_credits; private System.Windows.Forms.ToolStripMenuItem btn_saveCompiled; private System.Windows.Forms.ToolStripMenuItem tweaksToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem pixelToolStripMenuItem; } } diff --git a/mage/FormMain.cs b/mage/FormMain.cs index f807932..f1d43a8 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -257,7 +257,13 @@ private void InitializeSettings() statusStrip_zoom.Text = $"{1 << zoom}00%"; // Config object - try { Program.Config = JsonSerializer.Deserialize(Settings.Default.config); } + var configOptions = new JsonSerializerOptions() + { + Converters = { + new ColorJsonConverter() + } + }; + try { Program.Config = JsonSerializer.Deserialize(Settings.Default.config, configOptions); } catch { Program.Config = new(); } //Room Viewer Settings @@ -1154,11 +1160,23 @@ private void menuItem_exportCroppedRoomImage_Click(object sender, EventArgs e) if (saveRoom.ShowDialog() == DialogResult.OK) { Rectangle cropArea = new Rectangle(16 * 2, 16 * 2, (room.Width - 4) * 16, (room.Height - 4) * 16); - Bitmap roomBitmap = new Bitmap(roomView.BackgroundImage); + using Bitmap roomBitmap = new Bitmap(roomView.BackgroundImage); roomBitmap.Clone(cropArea, roomView.BackgroundImage.PixelFormat).Save(saveRoom.FileName); } } + private void menuItem_exportPixelRoomImage_Click(object sender, EventArgs e) + { + SaveFileDialog saveRoom = new SaveFileDialog(); + saveRoom.Filter = "PNG files (*.png)|*.png"; + if (saveRoom.ShowDialog() == DialogResult.OK) + { + using Bitmap image = new Bitmap(room.Width, room.Height); + room.backgrounds.clipTypes.DrawCollisionPixel(image, new()); + image.Save(saveRoom.FileName); + } + } + private void menuItem_areaImage_Click(object sender, EventArgs e) { new AreaImageExportDialog(this, roomsPerArea, room.AreaID).ShowDialog(); diff --git a/mage/Room/ClipTypes.cs b/mage/Room/ClipTypes.cs index 9316910..dbb1c47 100644 --- a/mage/Room/ClipTypes.cs +++ b/mage/Room/ClipTypes.cs @@ -1,427 +1,599 @@ -using System; +using mage.Dialogs; +using System; using System.Drawing; -namespace mage +namespace mage; + + + +public class ClipTypes { - public class ClipTypes - { - // fields - private static Pen p_solid = Pens.Red; - private static Pen p_door = Pens.Aqua; - private static Pen p_item = Pens.Magenta; - private static Pen p_samus = Pens.PaleGreen; - private static Pen p_enemy = Pens.DarkOrange; - private static Pen[] pens = new Pen[] - { p_enemy, p_solid, p_solid, p_solid, p_solid, p_solid, p_solid, - p_solid, p_enemy, p_samus, p_item, p_door, p_enemy }; + // fields + private static Pen p_solid = Pens.Red; + private static Pen p_door = Pens.Aqua; + private static Pen p_item = Pens.Magenta; + private static Pen p_samus = Pens.PaleGreen; + private static Pen p_enemy = Pens.DarkOrange; + private static Pen[] pens = new Pen[] + { p_enemy, p_solid, p_solid, p_solid, p_solid, p_solid, p_solid, + p_solid, p_enemy, p_samus, p_item, p_door, p_enemy }; - private byte[,] clipType; + private byte[,] clipType; - private Bitmap genBG; + private Bitmap genBG; - private ByteStream romStream; - private BG clip; + private ByteStream romStream; + private BG clip; - // constructor - public ClipTypes(BG clip) - { - this.romStream = ROM.Stream; - this.clip = clip; + // constructor + public ClipTypes(BG clip) + { + this.romStream = ROM.Stream; + this.clip = clip; - clipType = new byte[clip.width, clip.height]; + clipType = new byte[clip.width, clip.height]; - GFX gfx = ROM.GenericBGgfx; - genBG = gfx.Draw15bpp(ROM.GenericBGpalette, 0, true); - } + GFX gfx = ROM.GenericBGgfx; + genBG = gfx.Draw15bpp(ROM.GenericBGpalette, 0, true); + } + + public void DrawCollision(Graphics g, Rectangle region) + { + int w = clip.width; + int h = clip.height; + int xStart = Math.Max(region.X / 16, 0); + int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); + int yStart = Math.Max(region.Y / 16, 0); + int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); - public void DrawCollision(Graphics g, Rectangle region) + // get clip type values + int offset = Version.ClipdataTypeOffset; + for (int y = yStart; y < yEnd; y++) { - int w = clip.width; - int h = clip.height; - int xStart = Math.Max(region.X / 16, 0); - int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); - int yStart = Math.Max(region.Y / 16, 0); - int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); - - // get clip type values - int offset = Version.ClipdataTypeOffset; - for (int y = yStart; y < yEnd; y++) + for (int x = xStart; x < xEnd; x++) { - for (int x = xStart; x < xEnd; x++) - { - ushort clipVal = clip.blocks[x, y]; - clipType[x, y] = romStream.Read8(offset + clipVal); - } + ushort clipVal = clip.blocks[x, y]; + clipType[x, y] = romStream.Read8(offset + clipVal); } + } - // draw clipdata image - for (int y = yStart; y < yEnd; y++) + // draw clipdata image + for (int y = yStart; y < yEnd; y++) + { + for (int x = xStart; x < xEnd; x++) { - for (int x = xStart; x < xEnd; x++) - { - byte val = clipType[x, y]; - if (val > 0xC) val = 0; - if (val == 0) { continue; } // air - - int x1 = x * 16; - int y1 = y * 16; + byte val = clipType[x, y]; + if (val > 0xC) val = 0; + if (val == 0) { continue; } // air - if (val >= 2 && val <= 7) // slopes - { - Point[] pts = new Point[4]; - if (val == 3) // steep / - { - pts[0] = new Point(x1, y1 + 15); - pts[1] = new Point(x1 + 15, y1); - pts[2] = new Point(x1, y1 + 16); - pts[3] = new Point(x1 + 15, y1 + 1); - } - else if (val == 2) // steep \ - { - pts[0] = new Point(x1, y1); - pts[1] = new Point(x1 + 15, y1 + 15); - pts[2] = new Point(x1, y1 + 1); - pts[3] = new Point(x1 + 15, y1 + 16); - } - else if (val == 6) // lower slight / - { - pts[0] = new Point(x1, y1 + 15); - pts[1] = new Point(x1 + 15, y1 + 8); - pts[2] = new Point(x1, y1 + 16); - pts[3] = new Point(x1 + 15, y1 + 9); - } - else if (val == 7) // upper slight / - { - pts[0] = new Point(x1, y1 + 7); - pts[1] = new Point(x1 + 15, y1); - pts[2] = new Point(x1, y1 + 8); - pts[3] = new Point(x1 + 15, y1 + 1); - } - else if (val == 4) // upper slight \ - { - pts[0] = new Point(x1, y1); - pts[1] = new Point(x1 + 15, y1 + 7); - pts[2] = new Point(x1, y1 + 1); - pts[3] = new Point(x1 + 15, y1 + 8); - } - else // lower slight \ - { - pts[0] = new Point(x1, y1 + 8); - pts[1] = new Point(x1 + 15, y1 + 15); - pts[2] = new Point(x1, y1 + 9); - pts[3] = new Point(x1 + 15, y1 + 16); - } - - g.DrawLine(pens[val], pts[0], pts[1]); - g.DrawLine(pens[val], pts[2], pts[3]); - continue; - } + int x1 = x * 16; + int y1 = y * 16; - bool drawL, drawR, drawT, drawB; - bool drawTL, drawTR, drawBL, drawBR; - if (val == 1) - { - drawL = (x - 1 < 0 || (byte)(clipType[x - 1, y] - 1) > 6); - drawR = (x + 1 >= w || (byte)(clipType[x + 1, y] - 1) > 6); - drawT = (y - 1 < 0 || (byte)(clipType[x, y - 1] - 1) > 6); - drawB = (y + 1 >= h || (byte)(clipType[x, y + 1] - 1) > 6); - drawTL = !(drawT || drawL) && (byte)(clipType[x - 1, y - 1] - 1) > 6 && (byte)(clipType[x, y - 1] - 2) > 5; - drawTR = !(drawT || drawR) && (byte)(clipType[x + 1, y - 1] - 1) > 6 && (byte)(clipType[x, y - 1] - 2) > 5; - } - else - { - drawL = (x - 1 < 0 || clipType[x - 1, y] != val); - drawR = (x + 1 >= w || clipType[x + 1, y] != val); - drawT = (y - 1 < 0 || clipType[x, y - 1] != val); - drawB = (y + 1 >= h || clipType[x, y + 1] != val); - drawTL = !(drawT || drawL) && clipType[x - 1, y - 1] != val; - drawTR = !(drawT || drawR) && clipType[x + 1, y - 1] != val; - } - drawBL = !(drawB || drawL) && clipType[x - 1, y + 1] != val; - drawBR = !(drawB || drawR) && clipType[x + 1, y + 1] != val; - - if (drawL) - { - g.DrawRectangle(pens[val], x1, y1, 1, 15); - } - if (drawR) - { - g.DrawRectangle(pens[val], x1 + 14, y1, 1, 15); - } - if (drawT) + if (val >= 2 && val <= 7) // slopes + { + Point[] pts = new Point[4]; + if (val == 3) // steep / { - g.DrawRectangle(pens[val], x1, y1, 15, 1); + pts[0] = new Point(x1, y1 + 15); + pts[1] = new Point(x1 + 15, y1); + pts[2] = new Point(x1, y1 + 16); + pts[3] = new Point(x1 + 15, y1 + 1); } - if (drawB) + else if (val == 2) // steep \ { - g.DrawRectangle(pens[val], x1, y1 + 14, 15, 1); + pts[0] = new Point(x1, y1); + pts[1] = new Point(x1 + 15, y1 + 15); + pts[2] = new Point(x1, y1 + 1); + pts[3] = new Point(x1 + 15, y1 + 16); } - if (drawTL) + else if (val == 6) // lower slight / { - g.DrawRectangle(pens[val], x1, y1, 1, 1); + pts[0] = new Point(x1, y1 + 15); + pts[1] = new Point(x1 + 15, y1 + 8); + pts[2] = new Point(x1, y1 + 16); + pts[3] = new Point(x1 + 15, y1 + 9); } - if (drawTR) + else if (val == 7) // upper slight / { - g.DrawRectangle(pens[val], x1 + 14, y1, 1, 1); + pts[0] = new Point(x1, y1 + 7); + pts[1] = new Point(x1 + 15, y1); + pts[2] = new Point(x1, y1 + 8); + pts[3] = new Point(x1 + 15, y1 + 1); } - if (drawBL) + else if (val == 4) // upper slight \ { - g.DrawRectangle(pens[val], x1, y1 + 14, 1, 1); + pts[0] = new Point(x1, y1); + pts[1] = new Point(x1 + 15, y1 + 7); + pts[2] = new Point(x1, y1 + 1); + pts[3] = new Point(x1 + 15, y1 + 8); } - if (drawBR) + else // lower slight \ { - g.DrawRectangle(pens[val], x1 + 14, y1 + 14, 1, 1); + pts[0] = new Point(x1, y1 + 8); + pts[1] = new Point(x1 + 15, y1 + 15); + pts[2] = new Point(x1, y1 + 9); + pts[3] = new Point(x1 + 15, y1 + 16); } + + g.DrawLine(pens[val], pts[0], pts[1]); + g.DrawLine(pens[val], pts[2], pts[3]); + continue; + } + + bool drawL, drawR, drawT, drawB; + bool drawTL, drawTR, drawBL, drawBR; + if (val == 1) + { + drawL = (x - 1 < 0 || (byte)(clipType[x - 1, y] - 1) > 6); + drawR = (x + 1 >= w || (byte)(clipType[x + 1, y] - 1) > 6); + drawT = (y - 1 < 0 || (byte)(clipType[x, y - 1] - 1) > 6); + drawB = (y + 1 >= h || (byte)(clipType[x, y + 1] - 1) > 6); + drawTL = !(drawT || drawL) && (byte)(clipType[x - 1, y - 1] - 1) > 6 && (byte)(clipType[x, y - 1] - 2) > 5; + drawTR = !(drawT || drawR) && (byte)(clipType[x + 1, y - 1] - 1) > 6 && (byte)(clipType[x, y - 1] - 2) > 5; + } + else + { + drawL = (x - 1 < 0 || clipType[x - 1, y] != val); + drawR = (x + 1 >= w || clipType[x + 1, y] != val); + drawT = (y - 1 < 0 || clipType[x, y - 1] != val); + drawB = (y + 1 >= h || clipType[x, y + 1] != val); + drawTL = !(drawT || drawL) && clipType[x - 1, y - 1] != val; + drawTR = !(drawT || drawR) && clipType[x + 1, y - 1] != val; + } + drawBL = !(drawB || drawL) && clipType[x - 1, y + 1] != val; + drawBR = !(drawB || drawR) && clipType[x + 1, y + 1] != val; + + if (drawL) + { + g.DrawRectangle(pens[val], x1, y1, 1, 15); + } + if (drawR) + { + g.DrawRectangle(pens[val], x1 + 14, y1, 1, 15); + } + if (drawT) + { + g.DrawRectangle(pens[val], x1, y1, 15, 1); + } + if (drawB) + { + g.DrawRectangle(pens[val], x1, y1 + 14, 15, 1); + } + if (drawTL) + { + g.DrawRectangle(pens[val], x1, y1, 1, 1); + } + if (drawTR) + { + g.DrawRectangle(pens[val], x1 + 14, y1, 1, 1); + } + if (drawBL) + { + g.DrawRectangle(pens[val], x1, y1 + 14, 1, 1); + } + if (drawBR) + { + g.DrawRectangle(pens[val], x1 + 14, y1 + 14, 1, 1); } } } + } + + public void DrawCollisionPixel(Bitmap b, RoomPixelImageExportDialogResult options) + { + int w = clip.width; + int h = clip.height; - public void DrawBreakable(Graphics g, Rectangle region) + // get clip type values + int offset = Version.ClipdataTypeOffset; + for (int y = 0; y < h; y++) { - if (Version.IsMF) { DrawBreakableMF(g, region); } - else { DrawBreakableZM(g, region); } + for (int x = 0; x < w; x++) + { + ushort clipVal = clip.blocks[x, y]; + clipType[x, y] = romStream.Read8(offset + clipVal); + } } - private void DrawBreakableMF(Graphics g, Rectangle region) + // Draw new values + for (int y = 0; y < h; y++) + for (int x = 0; x < w; x++) + { + byte type = clipType[x, y]; + if (type > 0xC) type = 0; + ushort val = clip.blocks[x, y]; + + Color drawColor = options.ColorBackground; + if (type == 1) drawColor = options.ColorSolid; + + drawColor = GetColorForClipdataPixel(val, options) ?? drawColor; + + b.SetPixel(x, y, drawColor); + } + } + + public Color? GetColorForClipdataPixel(ushort clipVal, RoomPixelImageExportDialogResult options) + { + if (Version.IsMF) { - int w = clip.width; - int h = clip.height; - int xStart = Math.Max(region.X / 16, 0); - int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); - int yStart = Math.Max(region.Y / 16, 0); - int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); - - for (int y = yStart; y < yEnd; y++) + switch (clipVal) { - for (int x = xStart; x < xEnd; x++) - { - ushort clipVal = clip.blocks[x, y]; - switch (clipVal) - { - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x60: - case 0x61: - case 0x6C: - case 0x6D: // shot - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(160, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x54: - case 0x5E: // missile - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(112, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x55: - case 0x56: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: // bomb - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(80, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x57: // power - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(128, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x58: - case 0x6B: // speed - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(96, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x59: // screw - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(144, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x5A: // crumble - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(64, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x64: // missile tank - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(128, 0, 16, 8), GraphicsUnit.Pixel); - g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(144, 0, 16, 8), GraphicsUnit.Pixel); - break; - case 0x65: // energy tank - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(160, 0, 16, 8), GraphicsUnit.Pixel); - g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(176, 0, 16, 8), GraphicsUnit.Pixel); - break; - case 0x69: // power tank - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(192, 0, 16, 8), GraphicsUnit.Pixel); - g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(208, 0, 16, 8), GraphicsUnit.Pixel); - break; - } - } + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x3F: + return options.ColorGrayHatch; + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + return options.ColorBlueHatch; + case 0x3C: + case 0x3D: + case 0x3E: + case 0x4C: + case 0x4D: + case 0x4E: + return options.ColorRedHatch; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + return options.ColorGreenHatch; + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + return options.ColorYellowHatch; + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x60: + case 0x61: + case 0x6C: + case 0x6D: + return options.ColorShotBlock; + case 0x54: + case 0x5E: + return options.ColorMissileBlock; + case 0x55: + case 0x56: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + return options.ColorBombBlock; + case 0x57: + return options.ColorPowerBlock; + case 0x58: + case 0x6B: + return options.ColorSpeedBlock; + case 0x59: + return options.ColorScrewBlock; + case 0x5A: + return options.ColorCrumbleBlock; } } + else + { + switch (clipVal) + { + case 0x30: + return options.ColorGrayHatch; + case 0x36: + return options.ColorBlueHatch; + case 0x40: + return options.ColorRedHatch; + case 0x46: + return options.ColorGreenHatch; + case 0x4C: + return options.ColorYellowHatch; + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + return options.ColorShotBlock; + case 0x56: + case 0x66: + return options.ColorCrumbleBlock; + case 0x57: + case 0x67: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + return options.ColorBombBlock; + case 0x58: + case 0x68: + return options.ColorMissileBlock; + case 0x59: + case 0x69: + return options.ColorSuperBlock; + case 0x5A: + case 0x6A: + return options.ColorSpeedBlock; + case 0x5B: + return options.ColorPowerBlock; + case 0x6B: + return options.ColorScrewBlock; + } + } + return null; + } - private void DrawBreakableZM(Graphics g, Rectangle region) + public void DrawBreakable(Graphics g, Rectangle region) + { + if (Version.IsMF) { DrawBreakableMF(g, region); } + else { DrawBreakableZM(g, region); } + } + + private void DrawBreakableMF(Graphics g, Rectangle region) + { + int w = clip.width; + int h = clip.height; + int xStart = Math.Max(region.X / 16, 0); + int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); + int yStart = Math.Max(region.Y / 16, 0); + int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); + + for (int y = yStart; y < yEnd; y++) { - int w = clip.width; - int h = clip.height; - int xStart = Math.Max(region.X / 16, 0); - int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); - int yStart = Math.Max(region.Y / 16, 0); - int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); - - for (int y = yStart; y < yEnd; y++) + for (int x = xStart; x < xEnd; x++) { - for (int x = xStart; x < xEnd; x++) + ushort clipVal = clip.blocks[x, y]; + switch (clipVal) { - ushort clipVal = clip.blocks[x, y]; - switch (clipVal) - { - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: // shot - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(160, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x56: // crumble - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(64, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x57: - case 0x67: - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: // bomb - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(80, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x58: - case 0x68: // missile - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(112, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x59: - case 0x69: // super - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(176, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x5A: - case 0x6A: // speed - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(96, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x5B: // power - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(128, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x66: // slow crumble - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(0, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x6B: // screw - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(144, 16, 16, 16), GraphicsUnit.Pixel); - break; - case 0x6C: // energy tank - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(40, 0, 16, 8), GraphicsUnit.Pixel); - g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(56, 0, 16, 8), GraphicsUnit.Pixel); - break; - case 0x6D: // missile tank - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(8, 0, 16, 8), GraphicsUnit.Pixel); - g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(24, 0, 16, 8), GraphicsUnit.Pixel); - break; - case 0x6E: // super tank - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(104, 0, 16, 8), GraphicsUnit.Pixel); - g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(120, 0, 16, 8), GraphicsUnit.Pixel); - break; - case 0x6F: // power tank - g.DrawImage(genBG, x * 16, y * 16, new Rectangle(72, 0, 16, 8), GraphicsUnit.Pixel); - g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(88, 0, 16, 8), GraphicsUnit.Pixel); - break; - } + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x60: + case 0x61: + case 0x6C: + case 0x6D: // shot + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(160, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x54: + case 0x5E: // missile + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(112, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x55: + case 0x56: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: // bomb + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(80, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x57: // power + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(128, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x58: + case 0x6B: // speed + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(96, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x59: // screw + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(144, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x5A: // crumble + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(64, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x64: // missile tank + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(128, 0, 16, 8), GraphicsUnit.Pixel); + g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(144, 0, 16, 8), GraphicsUnit.Pixel); + break; + case 0x65: // energy tank + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(160, 0, 16, 8), GraphicsUnit.Pixel); + g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(176, 0, 16, 8), GraphicsUnit.Pixel); + break; + case 0x69: // power tank + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(192, 0, 16, 8), GraphicsUnit.Pixel); + g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(208, 0, 16, 8), GraphicsUnit.Pixel); + break; } } } + } - public void DrawValues(Graphics g, Rectangle region) - { - int w = clip.width; - int h = clip.height; - int xStart = Math.Max(region.X / 16, 0); - int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); - int yStart = Math.Max(region.Y / 16, 0); - int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); - - Bitmap nums = Properties.Resources.clipNums; + private void DrawBreakableZM(Graphics g, Rectangle region) + { + int w = clip.width; + int h = clip.height; + int xStart = Math.Max(region.X / 16, 0); + int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); + int yStart = Math.Max(region.Y / 16, 0); + int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); - for (int y = yStart; y < yEnd; y++) + for (int y = yStart; y < yEnd; y++) + { + for (int x = xStart; x < xEnd; x++) { - for (int x = xStart; x < xEnd; x++) + ushort clipVal = clip.blocks[x, y]; + switch (clipVal) { - int u = x * 16; - int v = y * 16; - ushort clipVal = clip.blocks[x, y]; - // fill with color - SolidBrush sb = new SolidBrush(GetColorFromHue(clipVal)); - g.FillRectangle(sb, u, v, 16, 16); - // draw value - int a = (clipVal >> 4) * 7; - int b = (clipVal & 0xF) * 7; - g.DrawImage(nums, new Rectangle(u + 2, v + 4, 7, 9), new Rectangle(a, 0, 7, 9), GraphicsUnit.Pixel); - g.DrawImage(nums, new Rectangle(u + 8, v + 4, 7, 9), new Rectangle(b, 0, 7, 9), GraphicsUnit.Pixel); + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: // shot + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(160, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x56: // crumble + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(64, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x57: + case 0x67: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: // bomb + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(80, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x58: + case 0x68: // missile + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(112, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x59: + case 0x69: // super + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(176, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x5A: + case 0x6A: // speed + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(96, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x5B: // power + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(128, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x66: // slow crumble + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(0, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x6B: // screw + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(144, 16, 16, 16), GraphicsUnit.Pixel); + break; + case 0x6C: // energy tank + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(40, 0, 16, 8), GraphicsUnit.Pixel); + g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(56, 0, 16, 8), GraphicsUnit.Pixel); + break; + case 0x6D: // missile tank + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(8, 0, 16, 8), GraphicsUnit.Pixel); + g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(24, 0, 16, 8), GraphicsUnit.Pixel); + break; + case 0x6E: // super tank + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(104, 0, 16, 8), GraphicsUnit.Pixel); + g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(120, 0, 16, 8), GraphicsUnit.Pixel); + break; + case 0x6F: // power tank + g.DrawImage(genBG, x * 16, y * 16, new Rectangle(72, 0, 16, 8), GraphicsUnit.Pixel); + g.DrawImage(genBG, x * 16, y * 16 + 8, new Rectangle(88, 0, 16, 8), GraphicsUnit.Pixel); + break; } } } + } - private Color GetColorFromHue(int val) + public void DrawValues(Graphics g, Rectangle region) + { + int w = clip.width; + int h = clip.height; + int xStart = Math.Max(region.X / 16, 0); + int xEnd = Math.Min(xStart + region.Width / 16 + 2, w); + int yStart = Math.Max(region.Y / 16, 0); + int yEnd = Math.Min(yStart + region.Height / 16 + 2, h); + + Bitmap nums = Properties.Resources.clipNums; + + for (int y = yStart; y < yEnd; y++) { - int x = (val % 43) * 6; - switch (val % 6) + for (int x = xStart; x < xEnd; x++) { - case 0: - return Color.FromArgb(64, 255, x, 0); - case 1: - return Color.FromArgb(64, 255 - x, 255, 0); - case 2: - return Color.FromArgb(64, 0, 255, x); - case 3: - return Color.FromArgb(64, 0, 255 - x, 255); - case 4: - return Color.FromArgb(64, x, 0, 255); - case 5: - return Color.FromArgb(64, 255, 0, 255 - x); - default: - throw new ArgumentException(); + int u = x * 16; + int v = y * 16; + ushort clipVal = clip.blocks[x, y]; + // fill with color + SolidBrush sb = new SolidBrush(GetColorFromHue(clipVal)); + g.FillRectangle(sb, u, v, 16, 16); + // draw value + int a = (clipVal >> 4) * 7; + int b = (clipVal & 0xF) * 7; + g.DrawImage(nums, new Rectangle(u + 2, v + 4, 7, 9), new Rectangle(a, 0, 7, 9), GraphicsUnit.Pixel); + g.DrawImage(nums, new Rectangle(u + 8, v + 4, 7, 9), new Rectangle(b, 0, 7, 9), GraphicsUnit.Pixel); } } + } - public void ResizeClip(byte w, byte h) + private Color GetColorFromHue(int val) + { + int x = (val % 43) * 6; + switch (val % 6) { - clipType = new byte[w, h]; + case 0: + return Color.FromArgb(64, 255, x, 0); + case 1: + return Color.FromArgb(64, 255 - x, 255, 0); + case 2: + return Color.FromArgb(64, 0, 255, x); + case 3: + return Color.FromArgb(64, 0, 255 - x, 255); + case 4: + return Color.FromArgb(64, x, 0, 255); + case 5: + return Color.FromArgb(64, 255, 0, 255 - x); + default: + throw new ArgumentException(); } + } - public void ConvertClip() - { - // get list of clipdata values - string[] lines = Version.ConvertClipdata; + public void ResizeClip(byte w, byte h) + { + clipType = new byte[w, h]; + } - ushort[] clipVals = new ushort[0x100]; - for (int i = 0; i < 0x100; i++) - { - clipVals[i] = Convert.ToUInt16(lines[i].Substring(3, 2), 16); - } + public void ConvertClip() + { + // get list of clipdata values + string[] lines = Version.ConvertClipdata; - // convert all blocks in the room - for (int y = 0; y < clip.height; y++) + ushort[] clipVals = new ushort[0x100]; + for (int i = 0; i < 0x100; i++) + { + clipVals[i] = Convert.ToUInt16(lines[i].Substring(3, 2), 16); + } + + // convert all blocks in the room + for (int y = 0; y < clip.height; y++) + { + for (int x = 0; x < clip.width; x++) { - for (int x = 0; x < clip.width; x++) - { - ushort val = clip.blocks[x, y]; - clip.blocks[x, y] = clipVals[val]; - } + ushort val = clip.blocks[x, y]; + clip.blocks[x, y] = clipVals[val]; } } + } - } } From 6fcb5188d35a87eb2814c760c1937a730482d575 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 26 Feb 2026 18:17:22 +0100 Subject: [PATCH 12/16] feat: export area as pixel image fix #80 --- mage/Dialogs/AreaImageExportDialog.cs | 43 +++++++++++++++++++++++++-- mage/FormMain.Designer.cs | 42 ++++++++++++++++++-------- mage/FormMain.cs | 9 ++++-- mage/Room/ClipTypes.cs | 14 ++++++--- 4 files changed, 88 insertions(+), 20 deletions(-) diff --git a/mage/Dialogs/AreaImageExportDialog.cs b/mage/Dialogs/AreaImageExportDialog.cs index 638f1a4..5e73784 100644 --- a/mage/Dialogs/AreaImageExportDialog.cs +++ b/mage/Dialogs/AreaImageExportDialog.cs @@ -21,8 +21,9 @@ public partial class AreaImageExportDialog : Form private string areaName => Version.AreaNames[area]; private bool requireDoors => checkBox_roomRequireDoors.Checked; private List excludedRooms => listbox_excludedRooms.SelectedIndices.Cast().ToList(); + private bool pixelMode; - public AreaImageExportDialog(FormMain main, byte[] roomsPerArea, int area) + public AreaImageExportDialog(FormMain main, byte[] roomsPerArea, int area, bool pixelMode = false) { InitializeComponent(); @@ -39,6 +40,9 @@ public AreaImageExportDialog(FormMain main, byte[] roomsPerArea, int area) string item = $"{areaName} - {Hex.ToString(i)}"; listbox_excludedRooms.Items.Add(item); } + + Text = pixelMode ? "Export Area Pixel Image" : "Export Area Image"; + this.pixelMode = pixelMode; } private void button_save_Click(object sender, EventArgs e) @@ -49,7 +53,7 @@ private void button_save_Click(object sender, EventArgs e) filePath = dialog.FileName; - // Export image + // List of all relevant rooms List rooms = new List(); (Point, Point) bounds = new(new Point(16, 16), new Point(0, 0)); @@ -73,6 +77,13 @@ private void button_save_Click(object sender, EventArgs e) if (r.header.mapX + r.WidthInScreens > bounds.Item2.X) bounds.Item2.X = r.header.mapX + r.WidthInScreens; if (r.header.mapY + r.HeightInScreens > bounds.Item2.Y) bounds.Item2.Y = r.header.mapY + r.HeightInScreens; } + + if (!pixelMode) exportAreaImage(rooms, bounds); + else exportPixelImage(rooms, bounds); + } + + private void exportAreaImage(List rooms, (Point, Point) bounds) + { //Rectangle with maximum area size Rectangle areaSize = new Rectangle( bounds.Item1.X * 15 * 16, @@ -103,4 +114,32 @@ private void button_save_Click(object sender, EventArgs e) areaImage.Dispose(); Close(); } + + private void exportPixelImage(List rooms, (Point, Point) bounds) + { + //Rectangle with maximum area size + Rectangle areaSize = new( + bounds.Item1.X * 15, + bounds.Item1.Y * 10, + (bounds.Item2.X - bounds.Item1.X) * 15, + (bounds.Item2.Y - bounds.Item1.Y) * 10 + ); + + //Creating bitmap + using Bitmap areaImage = new Bitmap(areaSize.Width, areaSize.Height); + using Graphics g = Graphics.FromImage(areaImage); + + foreach (Room r in rooms) + { + using Bitmap roomImage = new(r.Width - 4, r.Height - 4); + r.backgrounds.clipTypes.DrawCollisionPixel(roomImage, new(), true); + + int areaCoordinateX = r.header.mapX * 15 - areaSize.X; + int areaCoordinateY = r.header.mapY * 10 - areaSize.Y; + g.DrawImage(roomImage, areaCoordinateX, areaCoordinateY, roomImage.Width, roomImage.Height); + } + + areaImage.Save(filePath); + Close(); + } } diff --git a/mage/FormMain.Designer.cs b/mage/FormMain.Designer.cs index ab0ef2b..4f63c30 100644 --- a/mage/FormMain.Designer.cs +++ b/mage/FormMain.Designer.cs @@ -131,9 +131,12 @@ private void InitializeComponent() menuItem_exportRoomImage = new System.Windows.Forms.ToolStripMenuItem(); regularToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); croppedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + pixelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); bulkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); button_exportAllRooms = new System.Windows.Forms.ToolStripMenuItem(); button_areaImage = new System.Windows.Forms.ToolStripMenuItem(); + button_exportAreaRegular = new System.Windows.Forms.ToolStripMenuItem(); + button_exportAreaPixel = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator29 = new System.Windows.Forms.ToolStripSeparator(); button_importAllRooms = new System.Windows.Forms.ToolStripMenuItem(); menuItem_compression = new System.Windows.Forms.ToolStripMenuItem(); @@ -280,7 +283,6 @@ private void InitializeComponent() comboBox_spriteset = new mage.Theming.CustomControls.FlatComboBox(); ToolTip = new System.Windows.Forms.ToolTip(components); splitContainer1 = new System.Windows.Forms.SplitContainer(); - pixelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); menuStrip.SuspendLayout(); groupBox_location.SuspendLayout(); groupBox_tileset.SuspendLayout(); @@ -1036,17 +1038,24 @@ private void InitializeComponent() // regularToolStripMenuItem // regularToolStripMenuItem.Name = "regularToolStripMenuItem"; - regularToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + regularToolStripMenuItem.Size = new System.Drawing.Size(129, 22); regularToolStripMenuItem.Text = "Regular..."; regularToolStripMenuItem.Click += menuItem_exportRoomImage_Click; // // croppedToolStripMenuItem // croppedToolStripMenuItem.Name = "croppedToolStripMenuItem"; - croppedToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + croppedToolStripMenuItem.Size = new System.Drawing.Size(129, 22); croppedToolStripMenuItem.Text = "Cropped..."; croppedToolStripMenuItem.Click += menuItem_exportCroppedRoomImage_Click; // + // pixelToolStripMenuItem + // + pixelToolStripMenuItem.Name = "pixelToolStripMenuItem"; + pixelToolStripMenuItem.Size = new System.Drawing.Size(129, 22); + pixelToolStripMenuItem.Text = "Pixel..."; + pixelToolStripMenuItem.Click += menuItem_exportPixelRoomImage_Click; + // // bulkToolStripMenuItem // bulkToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { button_exportAllRooms, button_areaImage, toolStripSeparator29, button_importAllRooms }); @@ -1063,10 +1072,24 @@ private void InitializeComponent() // // button_areaImage // + button_areaImage.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { button_exportAreaRegular, button_exportAreaPixel }); button_areaImage.Name = "button_areaImage"; button_areaImage.Size = new System.Drawing.Size(180, 22); - button_areaImage.Text = "Export Area Image..."; - button_areaImage.Click += menuItem_areaImage_Click; + button_areaImage.Text = "Export Area Image"; + // + // button_exportAreaRegular + // + button_exportAreaRegular.Name = "button_exportAreaRegular"; + button_exportAreaRegular.Size = new System.Drawing.Size(180, 22); + button_exportAreaRegular.Text = "Regular..."; + button_exportAreaRegular.Click += menuItem_areaImage_Click; + // + // button_exportAreaPixel + // + button_exportAreaPixel.Name = "button_exportAreaPixel"; + button_exportAreaPixel.Size = new System.Drawing.Size(180, 22); + button_exportAreaPixel.Text = "Pixel..."; + button_exportAreaPixel.Click += button_exportAreaPixel_Click; // // toolStripSeparator29 // @@ -2394,13 +2417,6 @@ private void InitializeComponent() splitContainer1.TabIndex = 0; splitContainer1.SplitterMoved += splitContainer1_SplitterMoved; // - // pixelToolStripMenuItem - // - pixelToolStripMenuItem.Name = "pixelToolStripMenuItem"; - pixelToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - pixelToolStripMenuItem.Text = "Pixel..."; - pixelToolStripMenuItem.Click += menuItem_exportPixelRoomImage_Click; - // // FormMain // AllowDrop = true; @@ -2706,6 +2722,8 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem btn_saveCompiled; private System.Windows.Forms.ToolStripMenuItem tweaksToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem pixelToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem button_exportAreaRegular; + private System.Windows.Forms.ToolStripMenuItem button_exportAreaPixel; } } diff --git a/mage/FormMain.cs b/mage/FormMain.cs index f1d43a8..1f9e173 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -1171,8 +1171,8 @@ private void menuItem_exportPixelRoomImage_Click(object sender, EventArgs e) saveRoom.Filter = "PNG files (*.png)|*.png"; if (saveRoom.ShowDialog() == DialogResult.OK) { - using Bitmap image = new Bitmap(room.Width, room.Height); - room.backgrounds.clipTypes.DrawCollisionPixel(image, new()); + using Bitmap image = new Bitmap(room.Width - 4, room.Height - 4); + room.backgrounds.clipTypes.DrawCollisionPixel(image, new(), true); image.Save(saveRoom.FileName); } } @@ -1182,6 +1182,11 @@ private void menuItem_areaImage_Click(object sender, EventArgs e) new AreaImageExportDialog(this, roomsPerArea, room.AreaID).ShowDialog(); } + private void button_exportAreaPixel_Click(object sender, EventArgs e) + { + new AreaImageExportDialog(this, roomsPerArea, room.AreaID, true).ShowDialog(); + } + private void menuItem_LZ77comp_Click(object sender, EventArgs e) { CompressFile(true); diff --git a/mage/Room/ClipTypes.cs b/mage/Room/ClipTypes.cs index dbb1c47..e0f65a0 100644 --- a/mage/Room/ClipTypes.cs +++ b/mage/Room/ClipTypes.cs @@ -179,10 +179,14 @@ public void DrawCollision(Graphics g, Rectangle region) } } - public void DrawCollisionPixel(Bitmap b, RoomPixelImageExportDialogResult options) + public void DrawCollisionPixel(Bitmap b, RoomPixelImageExportDialogResult options, bool cropped = false) { int w = clip.width; int h = clip.height; + int endX = cropped ? w - 2 : w; + int endY = cropped ? h - 2 : h; + int startX = cropped ? 2 : 0; + int startY = cropped ? 2 : 0; // get clip type values int offset = Version.ClipdataTypeOffset; @@ -196,8 +200,8 @@ public void DrawCollisionPixel(Bitmap b, RoomPixelImageExportDialogResult option } // Draw new values - for (int y = 0; y < h; y++) - for (int x = 0; x < w; x++) + for (int y = startY; y < endY; y++) + for (int x = startX; x < endX; x++) { byte type = clipType[x, y]; if (type > 0xC) type = 0; @@ -208,7 +212,9 @@ public void DrawCollisionPixel(Bitmap b, RoomPixelImageExportDialogResult option drawColor = GetColorForClipdataPixel(val, options) ?? drawColor; - b.SetPixel(x, y, drawColor); + int posX = cropped ? x - 2 : x; + int posY = cropped ? y - 2 : y; + b.SetPixel(posX, posY, drawColor); } } From e35da3a96be309373c28b77e2ba0bcc30325ab8e Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:47:10 +0100 Subject: [PATCH 13/16] color dialog for pixel export --- mage/Dialogs/AreaImageExportDialog.cs | 15 +- .../RoomPixelImageExportDialog.Designer.cs | 464 +++++++++++++++++- mage/Dialogs/RoomPixelImageExportDialog.cs | 84 +++- mage/FormMain.cs | 14 +- mage/Options/Config.cs | 7 +- mage/Room/ClipTypes.cs | 4 +- 6 files changed, 578 insertions(+), 10 deletions(-) diff --git a/mage/Dialogs/AreaImageExportDialog.cs b/mage/Dialogs/AreaImageExportDialog.cs index 5e73784..36fec20 100644 --- a/mage/Dialogs/AreaImageExportDialog.cs +++ b/mage/Dialogs/AreaImageExportDialog.cs @@ -22,6 +22,7 @@ public partial class AreaImageExportDialog : Form private bool requireDoors => checkBox_roomRequireDoors.Checked; private List excludedRooms => listbox_excludedRooms.SelectedIndices.Cast().ToList(); private bool pixelMode; + PixelImageColors pixelColors; public AreaImageExportDialog(FormMain main, byte[] roomsPerArea, int area, bool pixelMode = false) { @@ -43,6 +44,17 @@ public AreaImageExportDialog(FormMain main, byte[] roomsPerArea, int area, bool Text = pixelMode ? "Export Area Pixel Image" : "Export Area Image"; this.pixelMode = pixelMode; + + if (pixelMode) + { + RoomPixelImageExportDialog dialog = new RoomPixelImageExportDialog(); + if (dialog.ShowDialog() != DialogResult.OK) + { + DialogResult = DialogResult.Cancel; + Close(); + } + pixelColors = dialog.Colors; + } } private void button_save_Click(object sender, EventArgs e) @@ -117,6 +129,7 @@ private void exportAreaImage(List rooms, (Point, Point) bounds) private void exportPixelImage(List rooms, (Point, Point) bounds) { + //Rectangle with maximum area size Rectangle areaSize = new( bounds.Item1.X * 15, @@ -132,7 +145,7 @@ private void exportPixelImage(List rooms, (Point, Point) bounds) foreach (Room r in rooms) { using Bitmap roomImage = new(r.Width - 4, r.Height - 4); - r.backgrounds.clipTypes.DrawCollisionPixel(roomImage, new(), true); + r.backgrounds.clipTypes.DrawCollisionPixel(roomImage, pixelColors, true); int areaCoordinateX = r.header.mapX * 15 - areaSize.X; int areaCoordinateY = r.header.mapY * 10 - areaSize.Y; diff --git a/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs b/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs index a2363ad..6485572 100644 --- a/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs +++ b/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs @@ -28,20 +28,480 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + grp_colors = new System.Windows.Forms.GroupBox(); + pnl_colYellowHatch = new System.Windows.Forms.Panel(); + lbl_colYellowHatch = new System.Windows.Forms.Label(); + pnl_colGreenHatch = new System.Windows.Forms.Panel(); + lbl_colGreenHatch = new System.Windows.Forms.Label(); + pnl_colRedHatch = new System.Windows.Forms.Panel(); + lbl_colRedHatch = new System.Windows.Forms.Label(); + pnl_colBlueHatch = new System.Windows.Forms.Panel(); + lbl_colBlueHatch = new System.Windows.Forms.Label(); + pnl_colGrayHatch = new System.Windows.Forms.Panel(); + lbl_colGrayHatch = new System.Windows.Forms.Label(); + lbl_colBackground = new System.Windows.Forms.Label(); + grp_general = new System.Windows.Forms.GroupBox(); + pnl_colSolid = new System.Windows.Forms.Panel(); + lbl_colSolid = new System.Windows.Forms.Label(); + pnl_colBackground = new System.Windows.Forms.Panel(); + grp_blocks = new System.Windows.Forms.GroupBox(); + pnl_colCrumble = new System.Windows.Forms.Panel(); + lbl_colCrumble = new System.Windows.Forms.Label(); + pnl_colScrew = new System.Windows.Forms.Panel(); + lbl_colScrew = new System.Windows.Forms.Label(); + pnl_colSpeed = new System.Windows.Forms.Panel(); + lbl_colSpeed = new System.Windows.Forms.Label(); + pnl_colSuper = new System.Windows.Forms.Panel(); + lbl_colSuper = new System.Windows.Forms.Label(); + pnl_colMissile = new System.Windows.Forms.Panel(); + lbl_colMissiles = new System.Windows.Forms.Label(); + pnl_colPowerBombs = new System.Windows.Forms.Panel(); + lbl_colPowerBombs = new System.Windows.Forms.Label(); + pnl_colBombs = new System.Windows.Forms.Panel(); + lbl_colBomb = new System.Windows.Forms.Label(); + pnl_colShot = new System.Windows.Forms.Panel(); + lbl_colShot = new System.Windows.Forms.Label(); + btn_ok = new System.Windows.Forms.Button(); + btn_cancel = new System.Windows.Forms.Button(); + btn_reset = new System.Windows.Forms.Button(); + grp_colors.SuspendLayout(); + grp_general.SuspendLayout(); + grp_blocks.SuspendLayout(); SuspendLayout(); // + // grp_colors + // + grp_colors.Controls.Add(pnl_colYellowHatch); + grp_colors.Controls.Add(lbl_colYellowHatch); + grp_colors.Controls.Add(pnl_colGreenHatch); + grp_colors.Controls.Add(lbl_colGreenHatch); + grp_colors.Controls.Add(pnl_colRedHatch); + grp_colors.Controls.Add(lbl_colRedHatch); + grp_colors.Controls.Add(pnl_colBlueHatch); + grp_colors.Controls.Add(lbl_colBlueHatch); + grp_colors.Controls.Add(pnl_colGrayHatch); + grp_colors.Controls.Add(lbl_colGrayHatch); + grp_colors.Location = new System.Drawing.Point(12, 104); + grp_colors.Name = "grp_colors"; + grp_colors.Size = new System.Drawing.Size(114, 177); + grp_colors.TabIndex = 0; + grp_colors.TabStop = false; + grp_colors.Text = "Hatches"; + // + // pnl_colYellowHatch + // + pnl_colYellowHatch.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colYellowHatch.Location = new System.Drawing.Point(83, 138); + pnl_colYellowHatch.Name = "pnl_colYellowHatch"; + pnl_colYellowHatch.Size = new System.Drawing.Size(23, 23); + pnl_colYellowHatch.TabIndex = 5; + pnl_colYellowHatch.Tag = ""; + pnl_colYellowHatch.Click += pnl_color_Click; + // + // lbl_colYellowHatch + // + lbl_colYellowHatch.AutoSize = true; + lbl_colYellowHatch.Location = new System.Drawing.Point(6, 142); + lbl_colYellowHatch.Name = "lbl_colYellowHatch"; + lbl_colYellowHatch.Size = new System.Drawing.Size(41, 15); + lbl_colYellowHatch.TabIndex = 4; + lbl_colYellowHatch.Text = "Yellow"; + // + // pnl_colGreenHatch + // + pnl_colGreenHatch.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colGreenHatch.Location = new System.Drawing.Point(83, 109); + pnl_colGreenHatch.Name = "pnl_colGreenHatch"; + pnl_colGreenHatch.Size = new System.Drawing.Size(23, 23); + pnl_colGreenHatch.TabIndex = 5; + pnl_colGreenHatch.Tag = ""; + pnl_colGreenHatch.Click += pnl_color_Click; + // + // lbl_colGreenHatch + // + lbl_colGreenHatch.AutoSize = true; + lbl_colGreenHatch.Location = new System.Drawing.Point(6, 113); + lbl_colGreenHatch.Name = "lbl_colGreenHatch"; + lbl_colGreenHatch.Size = new System.Drawing.Size(38, 15); + lbl_colGreenHatch.TabIndex = 4; + lbl_colGreenHatch.Text = "Green"; + // + // pnl_colRedHatch + // + pnl_colRedHatch.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colRedHatch.Location = new System.Drawing.Point(83, 80); + pnl_colRedHatch.Name = "pnl_colRedHatch"; + pnl_colRedHatch.Size = new System.Drawing.Size(23, 23); + pnl_colRedHatch.TabIndex = 5; + pnl_colRedHatch.Tag = ""; + pnl_colRedHatch.Click += pnl_color_Click; + // + // lbl_colRedHatch + // + lbl_colRedHatch.AutoSize = true; + lbl_colRedHatch.Location = new System.Drawing.Point(6, 84); + lbl_colRedHatch.Name = "lbl_colRedHatch"; + lbl_colRedHatch.Size = new System.Drawing.Size(27, 15); + lbl_colRedHatch.TabIndex = 4; + lbl_colRedHatch.Text = "Red"; + // + // pnl_colBlueHatch + // + pnl_colBlueHatch.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colBlueHatch.Location = new System.Drawing.Point(83, 51); + pnl_colBlueHatch.Name = "pnl_colBlueHatch"; + pnl_colBlueHatch.Size = new System.Drawing.Size(23, 23); + pnl_colBlueHatch.TabIndex = 5; + pnl_colBlueHatch.Tag = ""; + pnl_colBlueHatch.Click += pnl_color_Click; + // + // lbl_colBlueHatch + // + lbl_colBlueHatch.AutoSize = true; + lbl_colBlueHatch.Location = new System.Drawing.Point(6, 55); + lbl_colBlueHatch.Name = "lbl_colBlueHatch"; + lbl_colBlueHatch.Size = new System.Drawing.Size(30, 15); + lbl_colBlueHatch.TabIndex = 4; + lbl_colBlueHatch.Text = "Blue"; + // + // pnl_colGrayHatch + // + pnl_colGrayHatch.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colGrayHatch.Location = new System.Drawing.Point(83, 22); + pnl_colGrayHatch.Name = "pnl_colGrayHatch"; + pnl_colGrayHatch.Size = new System.Drawing.Size(23, 23); + pnl_colGrayHatch.TabIndex = 5; + pnl_colGrayHatch.Tag = ""; + pnl_colGrayHatch.Click += pnl_color_Click; + // + // lbl_colGrayHatch + // + lbl_colGrayHatch.AutoSize = true; + lbl_colGrayHatch.Location = new System.Drawing.Point(6, 26); + lbl_colGrayHatch.Name = "lbl_colGrayHatch"; + lbl_colGrayHatch.Size = new System.Drawing.Size(31, 15); + lbl_colGrayHatch.TabIndex = 4; + lbl_colGrayHatch.Text = "Gray"; + // + // lbl_colBackground + // + lbl_colBackground.AutoSize = true; + lbl_colBackground.Location = new System.Drawing.Point(6, 26); + lbl_colBackground.Name = "lbl_colBackground"; + lbl_colBackground.Size = new System.Drawing.Size(71, 15); + lbl_colBackground.TabIndex = 0; + lbl_colBackground.Text = "Background"; + // + // grp_general + // + grp_general.Controls.Add(pnl_colSolid); + grp_general.Controls.Add(lbl_colSolid); + grp_general.Controls.Add(pnl_colBackground); + grp_general.Controls.Add(lbl_colBackground); + grp_general.Location = new System.Drawing.Point(12, 12); + grp_general.Name = "grp_general"; + grp_general.Size = new System.Drawing.Size(114, 86); + grp_general.TabIndex = 1; + grp_general.TabStop = false; + grp_general.Text = "General"; + // + // pnl_colSolid + // + pnl_colSolid.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colSolid.Location = new System.Drawing.Point(83, 51); + pnl_colSolid.Name = "pnl_colSolid"; + pnl_colSolid.Size = new System.Drawing.Size(23, 23); + pnl_colSolid.TabIndex = 3; + pnl_colSolid.Tag = ""; + pnl_colSolid.Click += pnl_color_Click; + // + // lbl_colSolid + // + lbl_colSolid.AutoSize = true; + lbl_colSolid.Location = new System.Drawing.Point(6, 55); + lbl_colSolid.Name = "lbl_colSolid"; + lbl_colSolid.Size = new System.Drawing.Size(33, 15); + lbl_colSolid.TabIndex = 2; + lbl_colSolid.Text = "Solid"; + // + // pnl_colBackground + // + pnl_colBackground.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colBackground.Location = new System.Drawing.Point(83, 22); + pnl_colBackground.Name = "pnl_colBackground"; + pnl_colBackground.Size = new System.Drawing.Size(23, 23); + pnl_colBackground.TabIndex = 1; + pnl_colBackground.Tag = ""; + pnl_colBackground.Click += pnl_color_Click; + // + // grp_blocks + // + grp_blocks.Controls.Add(pnl_colCrumble); + grp_blocks.Controls.Add(lbl_colCrumble); + grp_blocks.Controls.Add(pnl_colScrew); + grp_blocks.Controls.Add(lbl_colScrew); + grp_blocks.Controls.Add(pnl_colSpeed); + grp_blocks.Controls.Add(lbl_colSpeed); + grp_blocks.Controls.Add(pnl_colSuper); + grp_blocks.Controls.Add(lbl_colSuper); + grp_blocks.Controls.Add(pnl_colMissile); + grp_blocks.Controls.Add(lbl_colMissiles); + grp_blocks.Controls.Add(pnl_colPowerBombs); + grp_blocks.Controls.Add(lbl_colPowerBombs); + grp_blocks.Controls.Add(pnl_colBombs); + grp_blocks.Controls.Add(lbl_colBomb); + grp_blocks.Controls.Add(pnl_colShot); + grp_blocks.Controls.Add(lbl_colShot); + grp_blocks.Location = new System.Drawing.Point(132, 12); + grp_blocks.Name = "grp_blocks"; + grp_blocks.Size = new System.Drawing.Size(125, 269); + grp_blocks.TabIndex = 2; + grp_blocks.TabStop = false; + grp_blocks.Text = "Blocks"; + // + // pnl_colCrumble + // + pnl_colCrumble.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colCrumble.Location = new System.Drawing.Point(94, 225); + pnl_colCrumble.Name = "pnl_colCrumble"; + pnl_colCrumble.Size = new System.Drawing.Size(23, 23); + pnl_colCrumble.TabIndex = 19; + pnl_colCrumble.Tag = ""; + pnl_colCrumble.Click += pnl_color_Click; + // + // lbl_colCrumble + // + lbl_colCrumble.AutoSize = true; + lbl_colCrumble.Location = new System.Drawing.Point(6, 229); + lbl_colCrumble.Name = "lbl_colCrumble"; + lbl_colCrumble.Size = new System.Drawing.Size(53, 15); + lbl_colCrumble.TabIndex = 16; + lbl_colCrumble.Text = "Crumble"; + // + // pnl_colScrew + // + pnl_colScrew.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colScrew.Location = new System.Drawing.Point(94, 196); + pnl_colScrew.Name = "pnl_colScrew"; + pnl_colScrew.Size = new System.Drawing.Size(23, 23); + pnl_colScrew.TabIndex = 20; + pnl_colScrew.Tag = ""; + pnl_colScrew.Click += pnl_color_Click; + // + // lbl_colScrew + // + lbl_colScrew.AutoSize = true; + lbl_colScrew.Location = new System.Drawing.Point(6, 200); + lbl_colScrew.Name = "lbl_colScrew"; + lbl_colScrew.Size = new System.Drawing.Size(75, 15); + lbl_colScrew.TabIndex = 17; + lbl_colScrew.Text = "Screw Attack"; + // + // pnl_colSpeed + // + pnl_colSpeed.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colSpeed.Location = new System.Drawing.Point(94, 167); + pnl_colSpeed.Name = "pnl_colSpeed"; + pnl_colSpeed.Size = new System.Drawing.Size(23, 23); + pnl_colSpeed.TabIndex = 21; + pnl_colSpeed.Tag = ""; + pnl_colSpeed.Click += pnl_color_Click; + // + // lbl_colSpeed + // + lbl_colSpeed.AutoSize = true; + lbl_colSpeed.Location = new System.Drawing.Point(6, 171); + lbl_colSpeed.Name = "lbl_colSpeed"; + lbl_colSpeed.Size = new System.Drawing.Size(82, 15); + lbl_colSpeed.TabIndex = 18; + lbl_colSpeed.Text = "Speed Booster"; + // + // pnl_colSuper + // + pnl_colSuper.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colSuper.Location = new System.Drawing.Point(94, 138); + pnl_colSuper.Name = "pnl_colSuper"; + pnl_colSuper.Size = new System.Drawing.Size(23, 23); + pnl_colSuper.TabIndex = 11; + pnl_colSuper.Tag = ""; + pnl_colSuper.Click += pnl_color_Click; + // + // lbl_colSuper + // + lbl_colSuper.AutoSize = true; + lbl_colSuper.Location = new System.Drawing.Point(6, 142); + lbl_colSuper.Name = "lbl_colSuper"; + lbl_colSuper.Size = new System.Drawing.Size(76, 15); + lbl_colSuper.TabIndex = 6; + lbl_colSuper.Text = "Super Missile"; + // + // pnl_colMissile + // + pnl_colMissile.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colMissile.Location = new System.Drawing.Point(94, 109); + pnl_colMissile.Name = "pnl_colMissile"; + pnl_colMissile.Size = new System.Drawing.Size(23, 23); + pnl_colMissile.TabIndex = 12; + pnl_colMissile.Tag = ""; + pnl_colMissile.Click += pnl_color_Click; + // + // lbl_colMissiles + // + lbl_colMissiles.AutoSize = true; + lbl_colMissiles.Location = new System.Drawing.Point(6, 113); + lbl_colMissiles.Name = "lbl_colMissiles"; + lbl_colMissiles.Size = new System.Drawing.Size(43, 15); + lbl_colMissiles.TabIndex = 7; + lbl_colMissiles.Text = "Missile"; + // + // pnl_colPowerBombs + // + pnl_colPowerBombs.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colPowerBombs.Location = new System.Drawing.Point(94, 80); + pnl_colPowerBombs.Name = "pnl_colPowerBombs"; + pnl_colPowerBombs.Size = new System.Drawing.Size(23, 23); + pnl_colPowerBombs.TabIndex = 13; + pnl_colPowerBombs.Tag = ""; + pnl_colPowerBombs.Click += pnl_color_Click; + // + // lbl_colPowerBombs + // + lbl_colPowerBombs.AutoSize = true; + lbl_colPowerBombs.Location = new System.Drawing.Point(6, 84); + lbl_colPowerBombs.Name = "lbl_colPowerBombs"; + lbl_colPowerBombs.Size = new System.Drawing.Size(75, 15); + lbl_colPowerBombs.TabIndex = 8; + lbl_colPowerBombs.Text = "Power Bomb"; + // + // pnl_colBombs + // + pnl_colBombs.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colBombs.Location = new System.Drawing.Point(94, 51); + pnl_colBombs.Name = "pnl_colBombs"; + pnl_colBombs.Size = new System.Drawing.Size(23, 23); + pnl_colBombs.TabIndex = 14; + pnl_colBombs.Tag = ""; + pnl_colBombs.Click += pnl_color_Click; + // + // lbl_colBomb + // + lbl_colBomb.AutoSize = true; + lbl_colBomb.Location = new System.Drawing.Point(6, 55); + lbl_colBomb.Name = "lbl_colBomb"; + lbl_colBomb.Size = new System.Drawing.Size(39, 15); + lbl_colBomb.TabIndex = 9; + lbl_colBomb.Text = "Bomb"; + // + // pnl_colShot + // + pnl_colShot.Cursor = System.Windows.Forms.Cursors.Hand; + pnl_colShot.Location = new System.Drawing.Point(94, 22); + pnl_colShot.Name = "pnl_colShot"; + pnl_colShot.Size = new System.Drawing.Size(23, 23); + pnl_colShot.TabIndex = 15; + pnl_colShot.Tag = ""; + pnl_colShot.Click += pnl_color_Click; + // + // lbl_colShot + // + lbl_colShot.AutoSize = true; + lbl_colShot.Location = new System.Drawing.Point(6, 26); + lbl_colShot.Name = "lbl_colShot"; + lbl_colShot.Size = new System.Drawing.Size(31, 15); + lbl_colShot.TabIndex = 10; + lbl_colShot.Text = "Shot"; + // + // btn_ok + // + btn_ok.Location = new System.Drawing.Point(182, 287); + btn_ok.Name = "btn_ok"; + btn_ok.Size = new System.Drawing.Size(75, 23); + btn_ok.TabIndex = 3; + btn_ok.Text = "OK"; + btn_ok.UseVisualStyleBackColor = true; + btn_ok.Click += btn_ok_Click; + // + // btn_cancel + // + btn_cancel.Location = new System.Drawing.Point(102, 287); + btn_cancel.Name = "btn_cancel"; + btn_cancel.Size = new System.Drawing.Size(75, 23); + btn_cancel.TabIndex = 4; + btn_cancel.Text = "Cancel"; + btn_cancel.UseVisualStyleBackColor = true; + btn_cancel.Click += btn_cancel_Click; + // + // btn_reset + // + btn_reset.Location = new System.Drawing.Point(12, 287); + btn_reset.Name = "btn_reset"; + btn_reset.Size = new System.Drawing.Size(47, 23); + btn_reset.TabIndex = 5; + btn_reset.Text = "Reset"; + btn_reset.UseVisualStyleBackColor = true; + btn_reset.Click += btn_reset_Click; + // // RoomPixelImageExportDialog // AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - ClientSize = new System.Drawing.Size(800, 450); + ClientSize = new System.Drawing.Size(267, 321); + Controls.Add(btn_reset); + Controls.Add(btn_cancel); + Controls.Add(btn_ok); + Controls.Add(grp_blocks); + Controls.Add(grp_general); + Controls.Add(grp_colors); FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; Name = "RoomPixelImageExportDialog"; - Text = "Save Pixel Room Image"; + Text = "Pixel Image Colors"; + grp_colors.ResumeLayout(false); + grp_colors.PerformLayout(); + grp_general.ResumeLayout(false); + grp_general.PerformLayout(); + grp_blocks.ResumeLayout(false); + grp_blocks.PerformLayout(); ResumeLayout(false); } #endregion + + private System.Windows.Forms.GroupBox grp_colors; + private System.Windows.Forms.Label lbl_colBackground; + private System.Windows.Forms.GroupBox grp_general; + private System.Windows.Forms.Panel pnl_colBackground; + private System.Windows.Forms.Panel pnl_colYellowHatch; + private System.Windows.Forms.Label lbl_colYellowHatch; + private System.Windows.Forms.Panel pnl_colGreenHatch; + private System.Windows.Forms.Label lbl_colGreenHatch; + private System.Windows.Forms.Panel pnl_colRedHatch; + private System.Windows.Forms.Label lbl_colRedHatch; + private System.Windows.Forms.Panel pnl_colBlueHatch; + private System.Windows.Forms.Label lbl_colBlueHatch; + private System.Windows.Forms.Panel pnl_colGrayHatch; + private System.Windows.Forms.Label lbl_colGrayHatch; + private System.Windows.Forms.Panel pnl_colSolid; + private System.Windows.Forms.Label lbl_colSolid; + private System.Windows.Forms.GroupBox grp_blocks; + private System.Windows.Forms.Panel pnl_colSuper; + private System.Windows.Forms.Label lbl_colSuper; + private System.Windows.Forms.Panel pnl_colMissile; + private System.Windows.Forms.Label lbl_colMissiles; + private System.Windows.Forms.Panel pnl_colPowerBombs; + private System.Windows.Forms.Label lbl_colPowerBombs; + private System.Windows.Forms.Panel pnl_colBombs; + private System.Windows.Forms.Label lbl_colBomb; + private System.Windows.Forms.Panel pnl_colShot; + private System.Windows.Forms.Label lbl_colShot; + private System.Windows.Forms.Panel pnl_colCrumble; + private System.Windows.Forms.Label lbl_colCrumble; + private System.Windows.Forms.Panel pnl_colScrew; + private System.Windows.Forms.Label lbl_colScrew; + private System.Windows.Forms.Panel pnl_colSpeed; + private System.Windows.Forms.Label lbl_colSpeed; + private System.Windows.Forms.Button btn_ok; + private System.Windows.Forms.Button btn_cancel; + private System.Windows.Forms.Button btn_reset; } } \ No newline at end of file diff --git a/mage/Dialogs/RoomPixelImageExportDialog.cs b/mage/Dialogs/RoomPixelImageExportDialog.cs index 518a9a7..5e41ddd 100644 --- a/mage/Dialogs/RoomPixelImageExportDialog.cs +++ b/mage/Dialogs/RoomPixelImageExportDialog.cs @@ -9,9 +9,9 @@ namespace mage.Dialogs; -public struct RoomPixelImageExportDialogResult +public struct PixelImageColors { - public RoomPixelImageExportDialogResult() { } + public PixelImageColors() { } public Color ColorBackground { get; set; } = Color.Black; public Color ColorSolid { get; set; } = Color.Gray; @@ -34,11 +34,91 @@ public RoomPixelImageExportDialogResult() { } public partial class RoomPixelImageExportDialog : Form { + public PixelImageColors Colors { get; set; } + public RoomPixelImageExportDialog() { InitializeComponent(); ThemeSwitcher.ChangeTheme(Controls, this); ThemeSwitcher.InjectPaintOverrides(Controls); + + Colors = Program.Config.PixelImageColors; + UpdatePanels(); + } + + private void btn_ok_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + Colors = UpdateColors(); + Program.Config.PixelImageColors = Colors; + Close(); + } + + private void btn_cancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void UpdatePanels() + { + pnl_colBackground.BackColor = Colors.ColorBackground; + pnl_colSolid.BackColor = Colors.ColorSolid; + pnl_colGrayHatch.BackColor = Colors.ColorGrayHatch; + pnl_colBlueHatch.BackColor = Colors.ColorBlueHatch; + pnl_colRedHatch.BackColor = Colors.ColorRedHatch; + pnl_colGreenHatch.BackColor = Colors.ColorGreenHatch; + pnl_colYellowHatch.BackColor = Colors.ColorYellowHatch; + pnl_colShot.BackColor = Colors.ColorShotBlock; + pnl_colBombs.BackColor = Colors.ColorBombBlock; + pnl_colPowerBombs.BackColor = Colors.ColorPowerBlock; + pnl_colMissile.BackColor = Colors.ColorMissileBlock; + pnl_colSuper.BackColor = Colors.ColorSuperBlock; + pnl_colSpeed.BackColor = Colors.ColorSpeedBlock; + pnl_colScrew.BackColor = Colors.ColorScrewBlock; + pnl_colCrumble.BackColor = Colors.ColorCrumbleBlock; + } + + private PixelImageColors UpdateColors() + { + return new() + { + ColorBackground = pnl_colBackground.BackColor, + ColorSolid = pnl_colSolid.BackColor, + ColorGrayHatch = pnl_colGrayHatch.BackColor, + ColorBlueHatch = pnl_colBlueHatch.BackColor, + ColorRedHatch = pnl_colRedHatch.BackColor, + ColorGreenHatch = pnl_colGreenHatch.BackColor, + ColorYellowHatch = pnl_colYellowHatch.BackColor, + ColorShotBlock = pnl_colShot.BackColor, + ColorBombBlock = pnl_colBombs.BackColor, + ColorPowerBlock = pnl_colPowerBombs.BackColor, + ColorMissileBlock = pnl_colMissile.BackColor, + ColorSuperBlock = pnl_colSuper.BackColor, + ColorSpeedBlock = pnl_colSpeed.BackColor, + ColorScrewBlock = pnl_colScrew.BackColor, + ColorCrumbleBlock = pnl_colCrumble.BackColor, + }; + } + + private void pnl_color_Click(object sender, EventArgs e) + { + if (sender is not Panel p) return; + + ColorDialog dialog = new ColorDialog(); + dialog.Color = p.BackColor; + dialog.FullOpen = true; + dialog.SolidColorOnly = true; + + if (dialog.ShowDialog() != DialogResult.OK) return; + + p.BackColor = dialog.Color; + } + + private void btn_reset_Click(object sender, EventArgs e) + { + Colors = new(); + UpdatePanels(); } } diff --git a/mage/FormMain.cs b/mage/FormMain.cs index 1f9e173..92c8082 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -317,7 +317,13 @@ private void SaveSettings() Settings.Default.legacyEditors = Program.LegacyEditors; //Config - Settings.Default.config = JsonSerializer.Serialize(Program.Config); + var configOptions = new JsonSerializerOptions() + { + Converters = { + new ColorJsonConverter() + } + }; + Settings.Default.config = JsonSerializer.Serialize(Program.Config, configOptions); //Room Viewer Settings Settings.Default.bg3color = Bg3Color; @@ -1167,12 +1173,16 @@ private void menuItem_exportCroppedRoomImage_Click(object sender, EventArgs e) private void menuItem_exportPixelRoomImage_Click(object sender, EventArgs e) { + RoomPixelImageExportDialog dialog = new RoomPixelImageExportDialog(); + if (dialog.ShowDialog() != DialogResult.OK) return; + PixelImageColors colors = dialog.Colors; + SaveFileDialog saveRoom = new SaveFileDialog(); saveRoom.Filter = "PNG files (*.png)|*.png"; if (saveRoom.ShowDialog() == DialogResult.OK) { using Bitmap image = new Bitmap(room.Width - 4, room.Height - 4); - room.backgrounds.clipTypes.DrawCollisionPixel(image, new(), true); + room.backgrounds.clipTypes.DrawCollisionPixel(image, colors, true); image.Save(saveRoom.FileName); } } diff --git a/mage/Options/Config.cs b/mage/Options/Config.cs index cd34284..ae29331 100644 --- a/mage/Options/Config.cs +++ b/mage/Options/Config.cs @@ -1,4 +1,5 @@ -using System; +using mage.Dialogs; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -23,6 +24,10 @@ public class Config public bool OnlyNotifyOnMajor { get; set; } = false; #endregion + #region Pixel Image exporting + public PixelImageColors PixelImageColors { get; set; } = new(); + #endregion + #region Bookmarking public enum BookmarkCollection { diff --git a/mage/Room/ClipTypes.cs b/mage/Room/ClipTypes.cs index e0f65a0..22c0a5c 100644 --- a/mage/Room/ClipTypes.cs +++ b/mage/Room/ClipTypes.cs @@ -179,7 +179,7 @@ public void DrawCollision(Graphics g, Rectangle region) } } - public void DrawCollisionPixel(Bitmap b, RoomPixelImageExportDialogResult options, bool cropped = false) + public void DrawCollisionPixel(Bitmap b, PixelImageColors options, bool cropped = false) { int w = clip.width; int h = clip.height; @@ -218,7 +218,7 @@ public void DrawCollisionPixel(Bitmap b, RoomPixelImageExportDialogResult option } } - public Color? GetColorForClipdataPixel(ushort clipVal, RoomPixelImageExportDialogResult options) + public Color? GetColorForClipdataPixel(ushort clipVal, PixelImageColors options) { if (Version.IsMF) { From 4efa88e80c0ed4adead46692cf53917163cdb123 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Fri, 27 Feb 2026 00:09:53 +0100 Subject: [PATCH 14/16] feat: added tweak manager --- mage/Tweaks/FormTweaks.Designer.cs | 1 + mage/Tweaks/FormTweaks.cs | 31 +++++ .../ITweakParameterControl.cs | 10 ++ .../TweakParameterSelection.Designer.cs | 72 +++++++++++ .../TweakParameterSelection.cs | 72 +++++++++++ .../TweakParameterSelection.resx | 120 ++++++++++++++++++ .../TweakParameterToggle.Designer.cs | 59 +++++++++ .../ParameterControls/TweakParameterToggle.cs | 35 +++++ .../TweakParameterToggle.resx | 120 ++++++++++++++++++ .../TweakParameterValue.Designer.cs | 83 ++++++++++++ .../ParameterControls/TweakParameterValue.cs | 50 ++++++++ .../TweakParameterValue.resx | 120 ++++++++++++++++++ mage/Tweaks/TweakParameter.cs | 3 +- mage/Tweaks/TweakValidation.cs | 5 - mage/mage.csproj | 6 + 15 files changed, 781 insertions(+), 6 deletions(-) create mode 100644 mage/Tweaks/ParameterControls/ITweakParameterControl.cs create mode 100644 mage/Tweaks/ParameterControls/TweakParameterSelection.Designer.cs create mode 100644 mage/Tweaks/ParameterControls/TweakParameterSelection.cs create mode 100644 mage/Tweaks/ParameterControls/TweakParameterSelection.resx create mode 100644 mage/Tweaks/ParameterControls/TweakParameterToggle.Designer.cs create mode 100644 mage/Tweaks/ParameterControls/TweakParameterToggle.cs create mode 100644 mage/Tweaks/ParameterControls/TweakParameterToggle.resx create mode 100644 mage/Tweaks/ParameterControls/TweakParameterValue.Designer.cs create mode 100644 mage/Tweaks/ParameterControls/TweakParameterValue.cs create mode 100644 mage/Tweaks/ParameterControls/TweakParameterValue.resx diff --git a/mage/Tweaks/FormTweaks.Designer.cs b/mage/Tweaks/FormTweaks.Designer.cs index 05794f5..4540f1f 100644 --- a/mage/Tweaks/FormTweaks.Designer.cs +++ b/mage/Tweaks/FormTweaks.Designer.cs @@ -152,6 +152,7 @@ private void InitializeComponent() // // btn_applyRevert // + btn_applyRevert.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right; btn_applyRevert.Location = new System.Drawing.Point(204, 391); btn_applyRevert.Name = "btn_applyRevert"; btn_applyRevert.Size = new System.Drawing.Size(75, 23); diff --git a/mage/Tweaks/FormTweaks.cs b/mage/Tweaks/FormTweaks.cs index d9f66ec..31818e3 100644 --- a/mage/Tweaks/FormTweaks.cs +++ b/mage/Tweaks/FormTweaks.cs @@ -1,4 +1,5 @@ using mage.Theming; +using mage.Tweaks.ParameterControls; using System; using System.Collections.Generic; using System.ComponentModel; @@ -60,6 +61,36 @@ private void DisplayTweakProperties(Tweak t) pnl_parameters.Enabled = !t.Applied; btn_applyRevert.Text = t.Applied ? "Revert" : "Apply"; + + DisplayTweakParameters(t); + } + + private void DisplayTweakParameters(Tweak t) + { + pnl_parameters.SuspendLayout(); + + pnl_parameters.Controls.Clear(); + foreach (TweakParameter p in t.Parameters) + { + Control? c = null; + switch (p.Type) + { + case ParameterType.Value: + c = new TweakParameterValue(p); + break; + case ParameterType.Selection: + c = new TweakParameterSelection(p); + break; + case ParameterType.Toggle: + c = new TweakParameterToggle(p); + break; + } + + c?.Dock = DockStyle.Top; + pnl_parameters.Controls.Add(c); + c?.BringToFront(); + } + pnl_parameters.ResumeLayout(); } private void lst_tweaks_Resize(object sender, EventArgs e) diff --git a/mage/Tweaks/ParameterControls/ITweakParameterControl.cs b/mage/Tweaks/ParameterControls/ITweakParameterControl.cs new file mode 100644 index 0000000..2184b42 --- /dev/null +++ b/mage/Tweaks/ParameterControls/ITweakParameterControl.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace mage.Tweaks.ParameterControls; + +public interface ITweakParameterControl +{ + public long? Value { get; set; } +} diff --git a/mage/Tweaks/ParameterControls/TweakParameterSelection.Designer.cs b/mage/Tweaks/ParameterControls/TweakParameterSelection.Designer.cs new file mode 100644 index 0000000..1086785 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterSelection.Designer.cs @@ -0,0 +1,72 @@ +namespace mage.Tweaks.ParameterControls +{ + partial class TweakParameterSelection + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + lbl_name = new System.Windows.Forms.Label(); + cbb_value = new mage.Theming.CustomControls.FlatComboBox(); + SuspendLayout(); + // + // lbl_name + // + lbl_name.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + lbl_name.AutoEllipsis = true; + lbl_name.Location = new System.Drawing.Point(3, 3); + lbl_name.Name = "lbl_name"; + lbl_name.Size = new System.Drawing.Size(97, 23); + lbl_name.TabIndex = 0; + lbl_name.Text = "Display Name"; + lbl_name.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // cbb_value + // + cbb_value.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + cbb_value.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + cbb_value.FormattingEnabled = true; + cbb_value.Location = new System.Drawing.Point(106, 3); + cbb_value.Name = "cbb_value"; + cbb_value.Size = new System.Drawing.Size(100, 23); + cbb_value.TabIndex = 2; + cbb_value.SelectedIndexChanged += cbb_value_SelectedIndexChanged; + // + // TweakParameterSelection + // + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + Controls.Add(cbb_value); + Controls.Add(lbl_name); + Name = "TweakParameterSelection"; + Size = new System.Drawing.Size(209, 30); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.Label lbl_name; + private Theming.CustomControls.FlatComboBox cbb_value; + } +} diff --git a/mage/Tweaks/ParameterControls/TweakParameterSelection.cs b/mage/Tweaks/ParameterControls/TweakParameterSelection.cs new file mode 100644 index 0000000..7f6b5b6 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterSelection.cs @@ -0,0 +1,72 @@ +using mage.Theming; +using NCalc; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace mage.Tweaks.ParameterControls +{ + public partial class TweakParameterSelection : UserControl + { + private TweakParameter Parameter; + private List Values; + + public TweakParameterSelection(TweakParameter param) + { + InitializeComponent(); + + ThemeSwitcher.ChangeTheme(Controls); + ThemeSwitcher.InjectPaintOverrides(Controls); + + Parameter = param; + + if (param.Options is null || param.Options.Length % 2 != 0 || param.Options.Length < 2) Invalid(); + + LoadCombobox(); + + cbb_value.SelectedIndex = Values.IndexOf((int)(param.Value ?? -1)); + lbl_name.Text = param.DisplayName ?? param.Name; + } + + private void LoadCombobox() + { + Values = new(); + + cbb_value.Items.Clear(); + for (int i = 0; i < Parameter.Options.Length; i += 2) + { + string key = Parameter.Options[i]; + int val = evaluate(Parameter.Options[i + 1]); + cbb_value.Items.Add(key); + Values.Add(val); + } + } + + + private void Invalid() + { + MessageBox.Show($"Could not load Parameter {lbl_name.Text}. Options are malformed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + Dispose(); + } + + private static int evaluate(string expression) + { + Expression ex = new Expression(expression); + return Convert.ToInt32(ex.Evaluate()); + } + + private void cbb_value_SelectedIndexChanged(object sender, EventArgs e) + { + if (cbb_value.SelectedIndex == -1) + { + Parameter.Value = null; + return; + } + Parameter.Value = Values[cbb_value.SelectedIndex]; + } + } +} diff --git a/mage/Tweaks/ParameterControls/TweakParameterSelection.resx b/mage/Tweaks/ParameterControls/TweakParameterSelection.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterSelection.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mage/Tweaks/ParameterControls/TweakParameterToggle.Designer.cs b/mage/Tweaks/ParameterControls/TweakParameterToggle.Designer.cs new file mode 100644 index 0000000..0c4cbb2 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterToggle.Designer.cs @@ -0,0 +1,59 @@ +namespace mage.Tweaks.ParameterControls +{ + partial class TweakParameterToggle + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + chb_value = new System.Windows.Forms.CheckBox(); + SuspendLayout(); + // + // chb_value + // + chb_value.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + chb_value.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; + chb_value.Location = new System.Drawing.Point(3, 3); + chb_value.Name = "chb_value"; + chb_value.Size = new System.Drawing.Size(217, 24); + chb_value.TabIndex = 0; + chb_value.Text = "Display Name"; + chb_value.UseVisualStyleBackColor = true; + chb_value.CheckedChanged += chb_value_CheckedChanged; + // + // TweakParameterToggle + // + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + Controls.Add(chb_value); + Name = "TweakParameterToggle"; + Size = new System.Drawing.Size(223, 30); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.CheckBox chb_value; + } +} diff --git a/mage/Tweaks/ParameterControls/TweakParameterToggle.cs b/mage/Tweaks/ParameterControls/TweakParameterToggle.cs new file mode 100644 index 0000000..65a6e3e --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterToggle.cs @@ -0,0 +1,35 @@ +using mage.Theming; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace mage.Tweaks.ParameterControls +{ + public partial class TweakParameterToggle : UserControl + { + private TweakParameter Parameter; + + public TweakParameterToggle(TweakParameter param) + { + InitializeComponent(); + + ThemeSwitcher.ChangeTheme(Controls); + ThemeSwitcher.InjectPaintOverrides(Controls); + + Parameter = param; + bool check = (Parameter.Value ?? 0) > 0; + + chb_value.Checked = check; + chb_value.Text = param.DisplayName ?? param.Name; + } + + private void chb_value_CheckedChanged(object sender, EventArgs e) + { + Parameter.Value = chb_value.Checked ? 1 : 0; + } + } +} diff --git a/mage/Tweaks/ParameterControls/TweakParameterToggle.resx b/mage/Tweaks/ParameterControls/TweakParameterToggle.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterToggle.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mage/Tweaks/ParameterControls/TweakParameterValue.Designer.cs b/mage/Tweaks/ParameterControls/TweakParameterValue.Designer.cs new file mode 100644 index 0000000..76a0473 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterValue.Designer.cs @@ -0,0 +1,83 @@ +namespace mage.Tweaks.ParameterControls +{ + partial class TweakParameterValue + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + lbl_name = new System.Windows.Forms.Label(); + txb_value = new mage.Theming.CustomControls.FlatTextBox(); + SuspendLayout(); + // + // lbl_name + // + lbl_name.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + lbl_name.AutoEllipsis = true; + lbl_name.Location = new System.Drawing.Point(3, 3); + lbl_name.Name = "lbl_name"; + lbl_name.Size = new System.Drawing.Size(111, 23); + lbl_name.TabIndex = 0; + lbl_name.Text = "Display Name"; + lbl_name.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // txb_value + // + txb_value.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + txb_value.BorderColor = System.Drawing.Color.Black; + txb_value.DisplayBorder = true; + txb_value.Location = new System.Drawing.Point(120, 3); + txb_value.MaxLength = 32767; + txb_value.Multiline = false; + txb_value.Name = "txb_value"; + txb_value.OnTextChanged = null; + txb_value.Padding = new System.Windows.Forms.Padding(3, 3, 1, 2); + txb_value.PlaceholderText = ""; + txb_value.ReadOnly = false; + txb_value.ScrollBars = System.Windows.Forms.ScrollBars.None; + txb_value.SelectionStart = 0; + txb_value.Size = new System.Drawing.Size(100, 23); + txb_value.TabIndex = 1; + txb_value.TextAlign = System.Windows.Forms.HorizontalAlignment.Left; + txb_value.ValueBox = false; + txb_value.WordWrap = true; + txb_value.TextChanged += txb_value_TextChanged; + // + // TweakParameterValue + // + AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + Controls.Add(txb_value); + Controls.Add(lbl_name); + Name = "TweakParameterValue"; + Size = new System.Drawing.Size(223, 30); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.Label lbl_name; + private Theming.CustomControls.FlatTextBox txb_value; + } +} diff --git a/mage/Tweaks/ParameterControls/TweakParameterValue.cs b/mage/Tweaks/ParameterControls/TweakParameterValue.cs new file mode 100644 index 0000000..c008565 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterValue.cs @@ -0,0 +1,50 @@ +using mage.Theming; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace mage.Tweaks.ParameterControls +{ + public partial class TweakParameterValue : UserControl + { + private TweakParameter Parameter; + + public TweakParameterValue(TweakParameter param) + { + InitializeComponent(); + + ThemeSwitcher.ChangeTheme(Controls); + ThemeSwitcher.InjectPaintOverrides(Controls); + + Parameter = param; + if (param.Value == null) txb_value.Text = ""; + else txb_value.Text = Hex.ToString((int)param.Value); + + lbl_name.Text = param.DisplayName ?? param.Name; + } + + private void txb_value_TextChanged(object sender, EventArgs e) + { + txb_value.ForeColor = ThemeSwitcher.ProjectTheme.TextColor; + if (txb_value.Text == String.Empty) + { + Parameter.Value = null; + return; + } + + try + { + Parameter.Value = Hex.ToInt(txb_value.Text); + } + catch + { + txb_value.ForeColor = Color.Red; + Parameter.Value = null; + } + } + } +} diff --git a/mage/Tweaks/ParameterControls/TweakParameterValue.resx b/mage/Tweaks/ParameterControls/TweakParameterValue.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/mage/Tweaks/ParameterControls/TweakParameterValue.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mage/Tweaks/TweakParameter.cs b/mage/Tweaks/TweakParameter.cs index af723fa..b1a97d2 100644 --- a/mage/Tweaks/TweakParameter.cs +++ b/mage/Tweaks/TweakParameter.cs @@ -7,7 +7,8 @@ namespace mage.Tweaks; public class TweakParameter { - public string Name { get; set; } = "New Tweak"; + public string Name { get; set; } = "new_parameter"; + public string? DisplayName { get; set; } public string? Description { get; set; } public long? Value { get; set; } diff --git a/mage/Tweaks/TweakValidation.cs b/mage/Tweaks/TweakValidation.cs index 81a1d67..9977f9f 100644 --- a/mage/Tweaks/TweakValidation.cs +++ b/mage/Tweaks/TweakValidation.cs @@ -55,11 +55,6 @@ private static bool ValidateParameter(TweakParameter param) if (param.Type == ParameterType.Toggle) { - if (param.Options is null || param.Options.Length != 2) - { - ShowValidationError($"Parameter of type Toggle requires exactly two options: Toggle Off, Toggle On. Supplied: {param.Options.Length}"); - return false; - } } if (param.Type == ParameterType.Selection) diff --git a/mage/mage.csproj b/mage/mage.csproj index 0ee310e..c279ed0 100644 --- a/mage/mage.csproj +++ b/mage/mage.csproj @@ -90,6 +90,12 @@ Component + + UserControl + + + UserControl + From b17ce2f618ec84b209397654c895bd7a6182a5c5 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Fri, 27 Feb 2026 13:31:00 +0100 Subject: [PATCH 15/16] tweak importing and deletion --- mage/FormMain.cs | 4 +- mage/Tweaks/FormTweaks.Designer.cs | 59 ++++++++++++++++++++++++++++++ mage/Tweaks/FormTweaks.cs | 52 +++++++++++++++++++++++++- mage/Tweaks/FormTweaks.resx | 3 ++ mage/Tweaks/TweakManager.cs | 14 +------ mage/Version.cs | 9 +++++ 6 files changed, 125 insertions(+), 16 deletions(-) diff --git a/mage/FormMain.cs b/mage/FormMain.cs index 92c8082..acd0ddf 100644 --- a/mage/FormMain.cs +++ b/mage/FormMain.cs @@ -561,7 +561,7 @@ public void CreateBackup() // save backup byte[] copy = ROM.BackupData(); ROM.SaveROM(backup, false); - if (!ProjectConfig.IsDefault(Version.ProjectConfig) || BookmarkManager.ProjectCollections.Count > 0) Version.UpdateProject(); + if (!ProjectConfig.IsDefault(Version.ProjectConfig) || BookmarkManager.ProjectCollections.Count > 0 || TweakManager.ProjectTweaks.Count > 0) Version.UpdateProject(); Version.SaveProject(backup); ROM.RestoreData(copy); } @@ -1454,7 +1454,7 @@ private void SaveROM() // save all edited lists and compress backgrounds ROM.SaveROM(filename, true); - if (!ProjectConfig.IsDefault(Version.ProjectConfig) || BookmarkManager.ProjectCollections.Count > 0) Version.UpdateProject(); + if (!ProjectConfig.IsDefault(Version.ProjectConfig) || BookmarkManager.ProjectCollections.Count > 0 || BookmarkManager.ProjectCollections.Count > 0) Version.UpdateProject(); bool newProject = Version.SaveProject(filename); if (newProject) { diff --git a/mage/Tweaks/FormTweaks.Designer.cs b/mage/Tweaks/FormTweaks.Designer.cs index 4540f1f..8464069 100644 --- a/mage/Tweaks/FormTweaks.Designer.cs +++ b/mage/Tweaks/FormTweaks.Designer.cs @@ -28,14 +28,19 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormTweaks)); statusStrip1 = new System.Windows.Forms.StatusStrip(); + lbl_spring = new System.Windows.Forms.ToolStripStatusLabel(); + btn_add = new System.Windows.Forms.ToolStripDropDownButton(); + btn_import = new System.Windows.Forms.ToolStripMenuItem(); grp_tweaks = new System.Windows.Forms.GroupBox(); lst_tweaks = new System.Windows.Forms.ListView(); clm_name = new System.Windows.Forms.ColumnHeader(); clm_author = new System.Windows.Forms.ColumnHeader(); pnl_main = new System.Windows.Forms.SplitContainer(); grp_properties = new System.Windows.Forms.GroupBox(); + btn_delete = new System.Windows.Forms.Button(); sep_parameters = new mage.Controls.Seperator(); btn_applyRevert = new System.Windows.Forms.Button(); pnl_parameters = new System.Windows.Forms.Panel(); @@ -46,6 +51,8 @@ private void InitializeComponent() lbl_descriptionLabel = new System.Windows.Forms.Label(); lbl_name = new System.Windows.Forms.Label(); lbl_labelName = new System.Windows.Forms.Label(); + tlt_parameterTip = new System.Windows.Forms.ToolTip(components); + statusStrip1.SuspendLayout(); grp_tweaks.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pnl_main).BeginInit(); pnl_main.Panel1.SuspendLayout(); @@ -56,12 +63,35 @@ private void InitializeComponent() // // statusStrip1 // + statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { lbl_spring, btn_add }); statusStrip1.Location = new System.Drawing.Point(0, 429); statusStrip1.Name = "statusStrip1"; statusStrip1.Size = new System.Drawing.Size(734, 22); statusStrip1.TabIndex = 0; statusStrip1.Text = "statusStrip1"; // + // lbl_spring + // + lbl_spring.Name = "lbl_spring"; + lbl_spring.Size = new System.Drawing.Size(595, 17); + lbl_spring.Spring = true; + // + // btn_add + // + btn_add.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { btn_import }); + btn_add.Image = Properties.Resources.toolbar_add; + btn_add.ImageTransparentColor = System.Drawing.Color.Magenta; + btn_add.Name = "btn_add"; + btn_add.Size = new System.Drawing.Size(93, 20); + btn_add.Text = "Add Tweak"; + // + // btn_import + // + btn_import.Name = "btn_import"; + btn_import.Size = new System.Drawing.Size(180, 22); + btn_import.Text = "Import..."; + btn_import.Click += btn_import_Click; + // // grp_tweaks // grp_tweaks.Controls.Add(lst_tweaks); @@ -122,6 +152,7 @@ private void InitializeComponent() // // grp_properties // + grp_properties.Controls.Add(btn_delete); grp_properties.Controls.Add(sep_parameters); grp_properties.Controls.Add(btn_applyRevert); grp_properties.Controls.Add(pnl_parameters); @@ -140,6 +171,20 @@ private void InitializeComponent() grp_properties.TabStop = false; grp_properties.Text = "Properties"; // + // btn_delete + // + btn_delete.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left; + btn_delete.Image = Properties.Resources.delete; + btn_delete.Location = new System.Drawing.Point(6, 391); + btn_delete.Name = "btn_delete"; + btn_delete.Size = new System.Drawing.Size(74, 23); + btn_delete.TabIndex = 10; + btn_delete.Text = "Delete"; + btn_delete.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + btn_delete.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + btn_delete.UseVisualStyleBackColor = true; + btn_delete.Click += btn_delete_Click; + // // sep_parameters // sep_parameters.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; @@ -254,6 +299,13 @@ private void InitializeComponent() lbl_labelName.TabIndex = 0; lbl_labelName.Text = "Name:"; // + // tlt_parameterTip + // + tlt_parameterTip.AutoPopDelay = 10000; + tlt_parameterTip.InitialDelay = 500; + tlt_parameterTip.ReshowDelay = 100; + tlt_parameterTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info; + // // FormTweaks // AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; @@ -264,6 +316,8 @@ private void InitializeComponent() MinimumSize = new System.Drawing.Size(750, 490); Name = "FormTweaks"; Text = "Tweak Manager"; + statusStrip1.ResumeLayout(false); + statusStrip1.PerformLayout(); grp_tweaks.ResumeLayout(false); pnl_main.Panel1.ResumeLayout(false); pnl_main.Panel2.ResumeLayout(false); @@ -294,5 +348,10 @@ private void InitializeComponent() private System.Windows.Forms.Button btn_applyRevert; private System.Windows.Forms.Panel pnl_parameters; private Controls.Seperator sep_parameters; + private System.Windows.Forms.ToolTip tlt_parameterTip; + private System.Windows.Forms.ToolStripStatusLabel lbl_spring; + private System.Windows.Forms.ToolStripDropDownButton btn_add; + private System.Windows.Forms.ToolStripMenuItem btn_import; + private System.Windows.Forms.Button btn_delete; } } \ No newline at end of file diff --git a/mage/Tweaks/FormTweaks.cs b/mage/Tweaks/FormTweaks.cs index 31818e3..923cd66 100644 --- a/mage/Tweaks/FormTweaks.cs +++ b/mage/Tweaks/FormTweaks.cs @@ -5,7 +5,9 @@ using System.ComponentModel; using System.Data; using System.Drawing; +using System.IO; using System.Text; +using System.Text.Json; using System.Windows.Forms; namespace mage.Tweaks; @@ -89,6 +91,9 @@ private void DisplayTweakParameters(Tweak t) c?.Dock = DockStyle.Top; pnl_parameters.Controls.Add(c); c?.BringToFront(); + if (c is null) continue; + + tlt_parameterTip.SetToolTip(c, p.Description); } pnl_parameters.ResumeLayout(); } @@ -117,7 +122,7 @@ private void lst_tweaks_Resize(object sender, EventArgs e) private void lst_tweaks_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) { - bool itemSelected = e.Item != null; + bool itemSelected = e.Item != null && lst_tweaks.Items.Contains(e.Item); pnl_main.Panel2Collapsed = !itemSelected; grp_properties.Enabled = itemSelected; @@ -159,4 +164,49 @@ private void UpdateListItem(ListViewItem item, Tweak tweak) { item.ImageIndex = tweak.Applied ? 0 : 1; } + + private void btn_delete_Click(object sender, EventArgs e) + { + if (selectedTweak is null) return; + + if (MessageBox.Show("Deleting a Tweak cannot be undone. If this Tweak is currently applied, it will be reverted first.", "Delete Tweak", + MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) + != DialogResult.OK) return; + + if (selectedTweak.Applied) Revert(selectedTweak); + TweakManager.ProjectTweaks.Remove(selectedTweak); + lst_tweaks.Items.Remove(selectedItem); + + selectedItem = null; + selectedTweak = null; + } + + private void btn_import_Click(object sender, EventArgs e) + { + using var dialog = new OpenFileDialog + { + Multiselect = true, + Filter = "Tweak files (*.mtw)|*.mtw", + Title = "Select Tweaks" + }; + if (dialog.ShowDialog() != DialogResult.OK) return; + + foreach (string file in dialog.FileNames) + { + try { TweakManager.ProjectTweaks.Add(ImportTweak(file)); } + catch (Exception ex) + { + MessageBox.Show($"Could not import tweak from:\n{file}\n\n{ex.Message}"); + continue; + } + } + PopulateTweaksList(); + } + + private Tweak ImportTweak(string filename) + { + string json = File.ReadAllText(filename); + Tweak t = JsonSerializer.Deserialize(json); + return t; + } } diff --git a/mage/Tweaks/FormTweaks.resx b/mage/Tweaks/FormTweaks.resx index 6cd43ed..5e7cfa5 100644 --- a/mage/Tweaks/FormTweaks.resx +++ b/mage/Tweaks/FormTweaks.resx @@ -120,6 +120,9 @@ 17, 17 + + 132, 17 + diff --git a/mage/Tweaks/TweakManager.cs b/mage/Tweaks/TweakManager.cs index 947caac..9c1f93f 100644 --- a/mage/Tweaks/TweakManager.cs +++ b/mage/Tweaks/TweakManager.cs @@ -11,19 +11,7 @@ namespace mage.Tweaks; public static class TweakManager { public static List OnlineTweaks { get; set; } = new(); - public static List ProjectTweaks - { - get - { - if (field == null) - { - string json = File.ReadAllText("C:\\Users\\Conner\\Desktop\\testtweak.json"); - field = Deserialize(json); - } - return field; - } - set; - } = null; + public static List ProjectTweaks { get; set; } = new(); // Serializing diff --git a/mage/Version.cs b/mage/Version.cs index 54b4de2..cc30e2d 100644 --- a/mage/Version.cs +++ b/mage/Version.cs @@ -1,6 +1,7 @@ using mage.Bookmarks; using mage.Options; using mage.Properties; +using mage.Tweaks; using mage.Utility; using System; using System.Collections.Generic; @@ -62,6 +63,7 @@ public static void LoadProject(string filename) catch { return; } if (ProjectBookmarks != null) BookmarkManager.ProjectCollections = ProjectBookmarks; + if (ProjectTweaks != null) TweakManager.ProjectTweaks = ProjectTweaks; project = ProjectState.Exists; } @@ -119,6 +121,7 @@ public static bool SaveProject(string filename) // extended project data sw.WriteLine("[Project]"); sw.WriteLine("ProjectBookmarks=" + BookmarkManager.SerializeCollections(BookmarkManager.ProjectCollections, false)); + sw.WriteLine("ProjectTweaks=" + TweakManager.Serialize(TweakManager.ProjectTweaks, false)); sw.WriteLine("ProjectConfig=" + ProjectConfig.Serialize(Version.ProjectConfig)); sw.Close(); @@ -141,6 +144,7 @@ public static bool SaveProject(string filename) public static byte NumOfDemos { get; private set; } public static int MetroidOffset { get; private set; } public static List ProjectBookmarks { get; private set; } + public static List ProjectTweaks { get; private set; } public static ProjectConfig ProjectConfig { get; private set; } = ProjectConfig.DefaultConfig; public static BackupService? BackupService { @@ -553,6 +557,11 @@ public static void Parse(string name, string value) List bf = BookmarkManager.DeserializeCollections(value); info.SetValue(null, bf, null); } + else if (info.PropertyType == typeof(List)) + { + List tw = TweakManager.Deserialize(value); + info.SetValue(null, tw, null); + } else if (info.PropertyType == typeof(ProjectConfig)) { ProjectConfig cf = ProjectConfig.Deserialize(value); From 51c6e8f73181ce39e98084a4a2631153d2d0a857 Mon Sep 17 00:00:00 2001 From: Conner <69326416+ConConner@users.noreply.github.com> Date: Fri, 27 Feb 2026 15:17:58 +0100 Subject: [PATCH 16/16] tweaks icon --- mage/FormMain.Designer.cs | 64 +++++++---- mage/Properties/Resources.Designer.cs | 10 ++ mage/Properties/Resources.resx | 159 +++++++++++++------------- mage/Resources/toolbox.png | Bin 0 -> 634 bytes 4 files changed, 130 insertions(+), 103 deletions(-) create mode 100644 mage/Resources/toolbox.png diff --git a/mage/FormMain.Designer.cs b/mage/FormMain.Designer.cs index 4f63c30..059a806 100644 --- a/mage/FormMain.Designer.cs +++ b/mage/FormMain.Designer.cs @@ -279,6 +279,7 @@ private void InitializeComponent() toolStrip_test = new System.Windows.Forms.ToolStripButton(); toolStrip_tileBuilder = new System.Windows.Forms.ToolStripButton(); toolStrip_add = new System.Windows.Forms.ToolStripButton(); + toolStripButton_tweaks = new System.Windows.Forms.ToolStripButton(); toolStrip_patches = new System.Windows.Forms.ToolStripButton(); comboBox_spriteset = new mage.Theming.CustomControls.FlatComboBox(); ToolTip = new System.Windows.Forms.ToolTip(components); @@ -309,7 +310,7 @@ private void InitializeComponent() menuStrip.Name = "menuStrip"; menuStrip.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2); menuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System; - menuStrip.Size = new System.Drawing.Size(799, 24); + menuStrip.Size = new System.Drawing.Size(824, 24); menuStrip.TabIndex = 0; // // menuStrip_file @@ -984,47 +985,47 @@ private void InitializeComponent() // menuItem_exportTileset // menuItem_exportTileset.Name = "menuItem_exportTileset"; - menuItem_exportTileset.Size = new System.Drawing.Size(180, 22); + menuItem_exportTileset.Size = new System.Drawing.Size(152, 22); menuItem_exportTileset.Text = "Tileset..."; menuItem_exportTileset.Click += menuItem_exportTileset_Click; // // menuItem_exportBG // menuItem_exportBG.Name = "menuItem_exportBG"; - menuItem_exportBG.Size = new System.Drawing.Size(180, 22); + menuItem_exportBG.Size = new System.Drawing.Size(152, 22); menuItem_exportBG.Text = "Background..."; menuItem_exportBG.Click += menuItem_exportBG_Click; // // menuItem_exportRoom // menuItem_exportRoom.Name = "menuItem_exportRoom"; - menuItem_exportRoom.Size = new System.Drawing.Size(180, 22); + menuItem_exportRoom.Size = new System.Drawing.Size(152, 22); menuItem_exportRoom.Text = "Room..."; menuItem_exportRoom.Click += menuItem_exportRoom_Click; // // toolStripSeparator7 // toolStripSeparator7.Name = "toolStripSeparator7"; - toolStripSeparator7.Size = new System.Drawing.Size(177, 6); + toolStripSeparator7.Size = new System.Drawing.Size(149, 6); // // menuItem_exportTilesetImage // menuItem_exportTilesetImage.Name = "menuItem_exportTilesetImage"; - menuItem_exportTilesetImage.Size = new System.Drawing.Size(180, 22); + menuItem_exportTilesetImage.Size = new System.Drawing.Size(152, 22); menuItem_exportTilesetImage.Text = "Tileset Image..."; menuItem_exportTilesetImage.Click += menuItem_exportTilesetImage_Click; // // menuItem_exportBG0image // menuItem_exportBG0image.Name = "menuItem_exportBG0image"; - menuItem_exportBG0image.Size = new System.Drawing.Size(180, 22); + menuItem_exportBG0image.Size = new System.Drawing.Size(152, 22); menuItem_exportBG0image.Text = "BG0 Image..."; menuItem_exportBG0image.Click += menuItem_exportBG0image_Click; // // menuItem_exportBG3image // menuItem_exportBG3image.Name = "menuItem_exportBG3image"; - menuItem_exportBG3image.Size = new System.Drawing.Size(180, 22); + menuItem_exportBG3image.Size = new System.Drawing.Size(152, 22); menuItem_exportBG3image.Text = "BG3 Image..."; menuItem_exportBG3image.Click += menuItem_exportBG3image_Click; // @@ -1032,7 +1033,7 @@ private void InitializeComponent() // menuItem_exportRoomImage.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { regularToolStripMenuItem, croppedToolStripMenuItem, pixelToolStripMenuItem }); menuItem_exportRoomImage.Name = "menuItem_exportRoomImage"; - menuItem_exportRoomImage.Size = new System.Drawing.Size(180, 22); + menuItem_exportRoomImage.Size = new System.Drawing.Size(152, 22); menuItem_exportRoomImage.Text = "Room Image"; // // regularToolStripMenuItem @@ -1066,7 +1067,7 @@ private void InitializeComponent() // button_exportAllRooms // button_exportAllRooms.Name = "button_exportAllRooms"; - button_exportAllRooms.Size = new System.Drawing.Size(180, 22); + button_exportAllRooms.Size = new System.Drawing.Size(171, 22); button_exportAllRooms.Text = "Export Rooms..."; button_exportAllRooms.Click += menuItem_bulkExportScreens_Click; // @@ -1074,33 +1075,33 @@ private void InitializeComponent() // button_areaImage.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { button_exportAreaRegular, button_exportAreaPixel }); button_areaImage.Name = "button_areaImage"; - button_areaImage.Size = new System.Drawing.Size(180, 22); + button_areaImage.Size = new System.Drawing.Size(171, 22); button_areaImage.Text = "Export Area Image"; // // button_exportAreaRegular // button_exportAreaRegular.Name = "button_exportAreaRegular"; - button_exportAreaRegular.Size = new System.Drawing.Size(180, 22); + button_exportAreaRegular.Size = new System.Drawing.Size(123, 22); button_exportAreaRegular.Text = "Regular..."; button_exportAreaRegular.Click += menuItem_areaImage_Click; // // button_exportAreaPixel // button_exportAreaPixel.Name = "button_exportAreaPixel"; - button_exportAreaPixel.Size = new System.Drawing.Size(180, 22); + button_exportAreaPixel.Size = new System.Drawing.Size(123, 22); button_exportAreaPixel.Text = "Pixel..."; button_exportAreaPixel.Click += button_exportAreaPixel_Click; // // toolStripSeparator29 // toolStripSeparator29.Name = "toolStripSeparator29"; - toolStripSeparator29.Size = new System.Drawing.Size(177, 6); + toolStripSeparator29.Size = new System.Drawing.Size(168, 6); toolStripSeparator29.Visible = false; // // button_importAllRooms // button_importAllRooms.Name = "button_importAllRooms"; - button_importAllRooms.Size = new System.Drawing.Size(180, 22); + button_importAllRooms.Size = new System.Drawing.Size(171, 22); button_importAllRooms.Text = "Import Rooms..."; button_importAllRooms.Visible = false; // @@ -1190,6 +1191,7 @@ private void InitializeComponent() // // tweaksToolStripMenuItem // + tweaksToolStripMenuItem.Image = Properties.Resources.toolbox; tweaksToolStripMenuItem.Name = "tweaksToolStripMenuItem"; tweaksToolStripMenuItem.Size = new System.Drawing.Size(180, 22); tweaksToolStripMenuItem.Text = "Tweaks"; @@ -1618,7 +1620,7 @@ private void InitializeComponent() groupBox_room.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox_room.Name = "groupBox_room"; groupBox_room.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - groupBox_room.Size = new System.Drawing.Size(480, 412); + groupBox_room.Size = new System.Drawing.Size(505, 412); groupBox_room.TabIndex = 0; groupBox_room.TabStop = false; groupBox_room.Text = "Room"; @@ -1631,7 +1633,7 @@ private void InitializeComponent() panel_room.Location = new System.Drawing.Point(4, 19); panel_room.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); panel_room.Name = "panel_room"; - panel_room.Size = new System.Drawing.Size(472, 390); + panel_room.Size = new System.Drawing.Size(497, 390); panel_room.TabIndex = 0; // // roomView @@ -1903,7 +1905,7 @@ private void InitializeComponent() statusStrip.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0); statusStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; statusStrip.ShowItemToolTips = true; - statusStrip.Size = new System.Drawing.Size(799, 24); + statusStrip.Size = new System.Drawing.Size(824, 24); statusStrip.TabIndex = 0; // // statusLabel_coor @@ -1941,7 +1943,7 @@ private void InitializeComponent() // lbl_spring // lbl_spring.Name = "lbl_spring"; - lbl_spring.Size = new System.Drawing.Size(321, 19); + lbl_spring.Size = new System.Drawing.Size(346, 19); lbl_spring.Spring = true; // // statusStrip_emulator @@ -2018,12 +2020,12 @@ private void InitializeComponent() // toolStrip // toolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; - toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStrip_open, toolStrip_save, toolStripSeparator9, toolStrip_undo, toolStrip_redo, toolStripSeparator10, toolStrip_editBGs, toolStrip_editObjects, toolStripSeparator15, toolStrip_viewSprites, toolStrip_outlineSprites, toolStrip_outlineDoors, toolStrip_outlineScrolls, toolStrip_outlineEffect, toolStripSeparator16, toolStrip_header, toolStrip_tileset, toolStrip_graphics, toolStrip_palette, toolStrip_tileTable, toolStrip_animation, toolStrip_sprite, toolStrip_spriteset, toolStrip_oamEditor, toolStrip_connection, toolStrip_minimap, toolStrip_text, toolStrip_demoEditor, toolStrip_physics, toolStrip_weapon, toolStrip_credits, toolStripSeparator11, toolStrip_options, toolStrip_test, toolStrip_tileBuilder, toolStrip_add, toolStrip_patches }); + toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStrip_open, toolStrip_save, toolStripSeparator9, toolStrip_undo, toolStrip_redo, toolStripSeparator10, toolStrip_editBGs, toolStrip_editObjects, toolStripSeparator15, toolStrip_viewSprites, toolStrip_outlineSprites, toolStrip_outlineDoors, toolStrip_outlineScrolls, toolStrip_outlineEffect, toolStripSeparator16, toolStrip_header, toolStrip_tileset, toolStrip_graphics, toolStrip_palette, toolStrip_tileTable, toolStrip_animation, toolStrip_sprite, toolStrip_spriteset, toolStrip_oamEditor, toolStrip_connection, toolStrip_minimap, toolStrip_text, toolStrip_demoEditor, toolStrip_physics, toolStrip_weapon, toolStrip_credits, toolStripSeparator11, toolStrip_options, toolStrip_test, toolStrip_tileBuilder, toolStrip_add, toolStripButton_tweaks, toolStrip_patches }); toolStrip.Location = new System.Drawing.Point(0, 24); toolStrip.Name = "toolStrip"; toolStrip.Padding = new System.Windows.Forms.Padding(4, 0, 1, 0); toolStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System; - toolStrip.Size = new System.Drawing.Size(799, 25); + toolStrip.Size = new System.Drawing.Size(824, 25); toolStrip.TabIndex = 0; // // toolStrip_open @@ -2369,13 +2371,24 @@ private void InitializeComponent() toolStrip_add.Text = "Add"; toolStrip_add.Click += toolStrip_add_Click; // + // toolStripButton_tweaks + // + toolStripButton_tweaks.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + toolStripButton_tweaks.Enabled = false; + toolStripButton_tweaks.Image = Properties.Resources.toolbox; + toolStripButton_tweaks.ImageTransparentColor = System.Drawing.Color.Magenta; + toolStripButton_tweaks.Name = "toolStripButton_tweaks"; + toolStripButton_tweaks.Size = new System.Drawing.Size(23, 22); + toolStripButton_tweaks.Text = "Tweaks"; + toolStripButton_tweaks.Click += tweaksToolStripMenuItem_Click; + // // toolStrip_patches // toolStrip_patches.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; toolStrip_patches.Enabled = false; toolStrip_patches.Image = Properties.Resources.toolbar_patches; toolStrip_patches.Name = "toolStrip_patches"; - toolStrip_patches.Size = new System.Drawing.Size(23, 22); + toolStrip_patches.Size = new System.Drawing.Size(23, 20); toolStrip_patches.Text = "Patches"; toolStrip_patches.Click += menuItem_patches_Click; // @@ -2411,7 +2424,7 @@ private void InitializeComponent() splitContainer1.Panel2.Controls.Add(groupBox_room); splitContainer1.Panel2.Padding = new System.Windows.Forms.Padding(3, 6, 14, 6); splitContainer1.Panel2MinSize = 300; - splitContainer1.Size = new System.Drawing.Size(799, 424); + splitContainer1.Size = new System.Drawing.Size(824, 424); splitContainer1.SplitterDistance = 299; splitContainer1.SplitterWidth = 3; splitContainer1.TabIndex = 0; @@ -2421,7 +2434,7 @@ private void InitializeComponent() // AllowDrop = true; AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - ClientSize = new System.Drawing.Size(799, 497); + ClientSize = new System.Drawing.Size(824, 497); Controls.Add(splitContainer1); Controls.Add(toolStrip); Controls.Add(statusStrip); @@ -2431,7 +2444,7 @@ private void InitializeComponent() KeyPreview = true; MainMenuStrip = menuStrip; Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - MinimumSize = new System.Drawing.Size(815, 536); + MinimumSize = new System.Drawing.Size(840, 536); Name = "FormMain"; Text = "MAGE Themes"; FormClosing += FormMain_FormClosing; @@ -2724,6 +2737,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem pixelToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem button_exportAreaRegular; private System.Windows.Forms.ToolStripMenuItem button_exportAreaPixel; + private System.Windows.Forms.ToolStripButton toolStripButton_tweaks; } } diff --git a/mage/Properties/Resources.Designer.cs b/mage/Properties/Resources.Designer.cs index 956041f..5073814 100644 --- a/mage/Properties/Resources.Designer.cs +++ b/mage/Properties/Resources.Designer.cs @@ -2086,6 +2086,16 @@ public static System.Drawing.Bitmap toolbar_zoom { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap toolbox { + get { + object obj = ResourceManager.GetObject("toolbox", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/mage/Properties/Resources.resx b/mage/Properties/Resources.resx index bb35bad..1075514 100644 --- a/mage/Properties/Resources.resx +++ b/mage/Properties/Resources.resx @@ -127,8 +127,8 @@ ..\Resources\Icons\shortcut_power.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\toolbar_connection.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Misc\ZM_U_locationNames.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\zoom_out.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -148,9 +148,6 @@ ..\Resources\Misc\ZM_U_testRoom.ips;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Resources\Icons\toolbar_outline_scrolls.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Patches\ZM_U_disableChozoHints.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -169,15 +166,15 @@ ..\Resources\toolbar_oam.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\toolbar_save.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\shortcut_hatch_red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Lists\MF\MF_U_physics.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 + + ..\Resources\Icons\shortcut_slope45_pos.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Patches\MF_U_skipIntro.ips;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -193,8 +190,8 @@ ..\Resources\Lists\MF\MF_U_demoRAM.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\Misc\ZM_U_locationNames.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\disk_multiple.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Icons\shortcut_power_water.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -223,6 +220,9 @@ ..\Resources\Icons\toolbar_open.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\shortcut_bomb.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Icons\shortcut_power_hidden.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -235,8 +235,8 @@ ..\Resources\Lists\ZM\ZM_U_sSpriteOAM.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\Icons\button_bg_color.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Patches\ZM_U_addElevators1.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\cog.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -259,12 +259,18 @@ ..\Resources\Icons\shortcut_dusty.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\TestRoom\item_zero.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\toolbar_outline_effect.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Patches\ZM_U_removeCloseup.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Icons\shortcut_shot_TL.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Icons\toolbar_weapon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\TestRoom\test_play.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -343,6 +349,9 @@ ..\Resources\page_copy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\button_bg_color.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Lists\endings.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 @@ -379,9 +388,6 @@ ..\Resources\Icons\toolbar_outline_sprites.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\pencil.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Patches\ZM_U_addMinimapTiles.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -394,8 +400,11 @@ ..\Resources\Icons\mage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\shortcut_lava_strong.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\shortcut_super_block.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Misc\ZM_U_testDemo.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\Icons\toolbar_zoom.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -421,9 +430,6 @@ ..\Resources\TestRoom\item_full_gravity.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\toolbar_outline_effect.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Icons\shortcut_crumble_slow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -433,6 +439,9 @@ ..\Resources\Icons\toolbar_header.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\accept.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Icons\toolbar_minimap.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -445,8 +454,8 @@ ..\Resources\Lists\MF\MF_U_sSpriteOAM.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\TestRoom\status_screen.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Patches\MF_U_getPowerBombs.ips;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\zm_digits.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -454,6 +463,9 @@ ..\Resources\Misc\arrows.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\TestRoom\item_zero.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\grid.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -472,8 +484,8 @@ ..\Resources\bullet_arrow_down.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Lists\MF\MF_U_pSpriteOAM.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 + + ..\Resources\Icons\toolbar_redo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Icons\shortcut_trans_down.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -481,17 +493,20 @@ ..\Resources\Icons\shortcut_energy_water.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\MZM.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\fill_bucket.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Lists\MF\MF_U_weapons.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\Icons\shortcut_super_block.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\Icons\shortcut_super_hidden.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\toolbar_sprite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\toolbar_connection.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Lists\ZM\ZM_clipdata.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 @@ -499,12 +514,6 @@ ..\Resources\Misc\scrollNums.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Lists\ZM\ZM_U_physics.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - - ..\Resources\Patches\ZM_U_addElevators1.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\Resources\Misc\ZM_genTileTable;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -535,14 +544,14 @@ ..\Resources\TestRoom\item_disabled.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\disk_multiple.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\toolbar_save.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Patches\MF_U_addMinimapTiles.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Lists\ZM\ZM_U_pSpriteOAM.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\Patches\MF_U_getPowerBombs.ips;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Icons\toolbar_outline_scrolls.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\help.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -550,11 +559,11 @@ ..\Resources\Icons\toolbar_demo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\toolbar_weapon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Lists\MF\MF_U_pSpriteOAM.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\Icons\shortcut_bomb.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\toolbar_sprite.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Lists\textLists.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 @@ -562,9 +571,6 @@ ..\Resources\TestRoom\item_gravity.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Lists\MF\MF_J_patches.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - ..\Resources\Icons\shortcut_missile_water.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -577,8 +583,8 @@ ..\Resources\Icons\shortcut_air.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\shortcut_slope45_pos.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Icons\shortcut_lava_strong.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Icons\shortcut_lava_weak.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -586,21 +592,18 @@ ..\Resources\Misc\clipNums.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Patches\MF_U_noMinimap.ips;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\Resources\Misc\MF_U_locationNames.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Resources\fill_bucket.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\control_play_blue.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\TestRoom\status_screen.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\shape_flip_vertical.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\control_play_blue.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\page_white_add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -613,11 +616,11 @@ ..\Resources\Lists\MF\MF_clipdata.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\Misc\ZM_U_testDemo.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Lists\ZM\ZM_U_physics.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\MZM.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Patches\MF_U_noMinimap.ips;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\Icons\shortcut_super_water.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -625,6 +628,9 @@ ..\Resources\shape_group.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\script_code_red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Icons\shortcut_missile.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -634,20 +640,23 @@ ..\Resources\Lists\ZM\ZM_U_weapons.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 + + ..\Resources\transparent.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Icons\shortcut_shot_BR.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\shortcut_shot_TL.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Patches\MF_U_addMinimapTiles.ips;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\Icons\toolbar_view_sprites.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Icons\toolbar_redo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Lists\MF\MF_J_patches.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 - - ..\Resources\Lists\ZM\ZM_U_pSpriteOAM.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 + + ..\Resources\pencil.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Lists\ZM\ZM_constants.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 @@ -664,13 +673,7 @@ ..\Resources\Icons\shortcut_slope27_Lneg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\script_code_red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\accept.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\transparent.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\toolbox.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/mage/Resources/toolbox.png b/mage/Resources/toolbox.png new file mode 100644 index 0000000000000000000000000000000000000000..de2ed4f664bc358899ee6a211b17ac2fae7e3f2a GIT binary patch literal 634 zcmV-=0)_pFP)rlgmq0aS+Ep^EEBjI;+qk5ysdB8XZA z2|=_E45B|E+O?`pZR!um76pO}tz{3e2*E{I*CJE7#x2oG^PYRpIWsNHt9uvCVrF38 z-{%w6%F`>!Z&htS#~xy0 zxlFP69bAAE3JWsx`qhOXNg4tt{921@Za;c@|8!^TL}y3)3~Dm^cH(?j@BZ=2{ilZF zIH4Rx)OYWD)7sPfLB_|P^-bNl{;~xyU{#d|%^eIh<>>q}OKFmnj+4o5`Wl3e7$s3>Qv>U}0dO}3WQHtjA=Db?mE8iDs2+HyH?L3Q^cf~Ja85`2vlYT}p}+h_o1 zM&n|U)xsRvub;_QDya9H3I6fW3Es@mfAeh|wTh6zXd4?Q#8B_qdhi>%8Td*R?Fd4T zQiY&erq0&E+%jFY168H8_9x?Y&))Zw^K)HJTs3&B^VW)+35-Oc=j^$>{P%DC3lv8E U!zUxpGXMYp07*qoM6N<$g2_uG2><{9 literal 0 HcmV?d00001