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/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/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/Dialogs/AreaImageExportDialog.cs b/mage/Dialogs/AreaImageExportDialog.cs index 638f1a4..36fec20 100644 --- a/mage/Dialogs/AreaImageExportDialog.cs +++ b/mage/Dialogs/AreaImageExportDialog.cs @@ -21,8 +21,10 @@ 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; + PixelImageColors pixelColors; - public AreaImageExportDialog(FormMain main, byte[] roomsPerArea, int area) + public AreaImageExportDialog(FormMain main, byte[] roomsPerArea, int area, bool pixelMode = false) { InitializeComponent(); @@ -39,6 +41,20 @@ 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; + + 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) @@ -49,7 +65,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 +89,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 +126,33 @@ 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, pixelColors, 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/Dialogs/RoomPixelImageExportDialog.Designer.cs b/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs new file mode 100644 index 0000000..6485572 --- /dev/null +++ b/mage/Dialogs/RoomPixelImageExportDialog.Designer.cs @@ -0,0 +1,507 @@ +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() + { + 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(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 = "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 new file mode 100644 index 0000000..5e41ddd --- /dev/null +++ b/mage/Dialogs/RoomPixelImageExportDialog.cs @@ -0,0 +1,124 @@ +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 PixelImageColors +{ + public PixelImageColors() { } + + 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 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/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/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..76f8537 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.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 3700a6a..9dcdbe4 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() @@ -198,6 +197,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. @@ -242,7 +247,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; @@ -366,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 @@ -1021,6 +1026,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) { @@ -1097,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(); } @@ -1259,6 +1264,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; } @@ -1376,10 +1382,22 @@ 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); + } + + 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 diff --git a/mage/FormMain.Designer.cs b/mage/FormMain.Designer.cs index 961a904..059a806 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(); @@ -130,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(); @@ -147,6 +151,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(); @@ -274,11 +279,11 @@ 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); splitContainer1 = new System.Windows.Forms.SplitContainer(); - btn_saveCompiled = new System.Windows.Forms.ToolStripMenuItem(); menuStrip.SuspendLayout(); groupBox_location.SuspendLayout(); groupBox_tileset.SuspendLayout(); @@ -305,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 @@ -344,6 +349,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 +389,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 // @@ -850,7 +865,7 @@ private void InitializeComponent() // // 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); @@ -860,7 +875,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; // @@ -868,7 +883,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; // @@ -876,34 +891,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 @@ -964,7 +979,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 @@ -1016,7 +1031,7 @@ private void InitializeComponent() // // 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.Text = "Room Image"; @@ -1035,37 +1050,58 @@ private void InitializeComponent() 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 }); bulkToolStripMenuItem.Name = "bulkToolStripMenuItem"; - bulkToolStripMenuItem.Size = new System.Drawing.Size(171, 22); + bulkToolStripMenuItem.Size = new System.Drawing.Size(180, 22); bulkToolStripMenuItem.Text = "Bulk"; // // 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; // // 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.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(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(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; // @@ -1073,7 +1109,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 @@ -1093,13 +1129,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; // @@ -1108,7 +1144,7 @@ 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 @@ -1153,24 +1189,32 @@ private void InitializeComponent() menuItem_addAnim.Text = "Animation"; menuItem_addAnim.Click += menuItem_addItem_Click; // + // tweaksToolStripMenuItem + // + tweaksToolStripMenuItem.Image = Properties.Resources.toolbox; + 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; 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; @@ -1178,7 +1222,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; @@ -1399,7 +1443,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 +1455,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 @@ -1576,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"; @@ -1589,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 @@ -1861,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 @@ -1899,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 @@ -1976,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 @@ -2327,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; // @@ -2369,27 +2424,17 @@ 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 = 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; 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); @@ -2399,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; @@ -2688,6 +2733,11 @@ 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; + 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/FormMain.cs b/mage/FormMain.cs index b91b0a3..acd0ddf 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; @@ -256,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 @@ -310,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; @@ -548,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); } @@ -1153,16 +1166,37 @@ 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) + { + 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, colors, true); + image.Save(saveRoom.FileName); + } + } + 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); @@ -1323,6 +1357,11 @@ private void CompressFile(bool compress) } } + private void tweaksToolStripMenuItem_Click(object sender, EventArgs e) + { + new FormTweaks().Show(); + } + #endregion @@ -1415,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) { @@ -1502,6 +1541,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/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/Properties/Resources.Designer.cs b/mage/Properties/Resources.Designer.cs index 63f2df8..5073814 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,26 @@ 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. + /// + 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..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,7 +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\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/accept.png b/mage/Resources/accept.png new file mode 100644 index 0000000..89c8129 Binary files /dev/null and b/mage/Resources/accept.png differ diff --git a/mage/Resources/toolbox.png b/mage/Resources/toolbox.png new file mode 100644 index 0000000..de2ed4f Binary files /dev/null and b/mage/Resources/toolbox.png differ diff --git a/mage/Resources/transparent.png b/mage/Resources/transparent.png new file mode 100644 index 0000000..dde5384 Binary files /dev/null and b/mage/Resources/transparent.png differ diff --git a/mage/Room/ClipTypes.cs b/mage/Room/ClipTypes.cs index 9316910..22c0a5c 100644 --- a/mage/Room/ClipTypes.cs +++ b/mage/Room/ClipTypes.cs @@ -1,427 +1,605 @@ -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, PixelImageColors 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; - 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 = startY; y < endY; y++) + for (int x = startX; x < endX; 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; + + int posX = cropped ? x - 2 : x; + int posY = cropped ? y - 2 : y; + b.SetPixel(posX, posY, drawColor); + } + } + + public Color? GetColorForClipdataPixel(ushort clipVal, PixelImageColors 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]; } } + } - } } 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/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(); + } } } diff --git a/mage/Theming/ThemeSwitcher.cs b/mage/Theming/ThemeSwitcher.cs index e49b082..a8711d4 100644 --- a/mage/Theming/ThemeSwitcher.cs +++ b/mage/Theming/ThemeSwitcher.cs @@ -294,6 +294,93 @@ public static void ChangeTheme(Control control) } }; } + + if (control is ListView lv) + { + lv.OwnerDraw = true; + lv.BorderStyle = BorderStyle.None; + lv.ColumnWidthChanged += (_, _) => 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); + 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) + { + 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..7695cbe 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 = 83; // // columnHeader_applied // - this.columnHeader_applied.Text = "Applied"; - this.columnHeader_applied.Width = 52; + columnHeader_applied.Text = "Applied"; + columnHeader_applied.Width = 53; // // 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 new file mode 100644 index 0000000..8464069 --- /dev/null +++ b/mage/Tweaks/FormTweaks.Designer.cs @@ -0,0 +1,357 @@ +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() + { + 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(); + 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(); + tlt_parameterTip = new System.Windows.Forms.ToolTip(components); + statusStrip1.SuspendLayout(); + 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.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); + 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(427, 420); + 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(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 + // + 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(734, 429); + pnl_main.SplitterDistance = 436; + pnl_main.TabIndex = 2; + // + // 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); + 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, 420); + grp_properties.TabIndex = 0; + 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; + 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.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); + 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:"; + // + // 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; + 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"; + statusStrip1.ResumeLayout(false); + statusStrip1.PerformLayout(); + grp_tweaks.ResumeLayout(false); + pnl_main.Panel1.ResumeLayout(false); + 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(); + } + + #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; + 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; + 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 new file mode 100644 index 0000000..923cd66 --- /dev/null +++ b/mage/Tweaks/FormTweaks.cs @@ -0,0 +1,212 @@ +using mage.Theming; +using mage.Tweaks.ParameterControls; +using System; +using System.Collections.Generic; +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; + +public partial class FormTweaks : Form +{ + Tweak selectedTweak; + ListViewItem selectedItem; + + public FormTweaks() + { + InitializeComponent(); + + 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); + statusIcons.ImageSize = new Size(16, 16); + + 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 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"; + + 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(); + if (c is null) continue; + + tlt_parameterTip.SetToolTip(c, p.Description); + } + pnl_parameters.ResumeLayout(); + } + + private void lst_tweaks_Resize(object sender, EventArgs e) + { + 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 && lst_tweaks.Items.Contains(e.Item); + + 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; + } + + 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 new file mode 100644 index 0000000..5e7cfa5 --- /dev/null +++ b/mage/Tweaks/FormTweaks.resx @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 132, 17 + + + + + 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/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/Tweak.cs b/mage/Tweaks/Tweak.cs new file mode 100644 index 0000000..3a53514 --- /dev/null +++ b/mage/Tweaks/Tweak.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Windows.Forms; + +namespace mage.Tweaks; + +public class Tweak +{ + public string Name { get; set; } + public string Author { get; set; } + public string? Description { get; set; } + + 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 + .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.ResolveOldData(); + 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" + ); + } + + public void Apply(ByteStream rom) + { + StopIfMissingParameters(); + + var paramDict = Parameters.ToDictionary(p => p.Name, p => p.Value!.Value); + + Dictionary Backup = new(); + + 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.SetOldData(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); + + foreach (var kvp in Backup) + rom.CopyFromArray(kvp.Value, 0, kvp.Key, kvp.Value.Length); + Applied = false; + return; + } + + 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}'. No old data available." + ); + + foreach (var patch in Patches) + { + int offset = patch.OldOffset ?? 0; + byte[] old = patch.ResolveOldData(); + 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..9c1f93f --- /dev/null +++ b/mage/Tweaks/TweakManager.cs @@ -0,0 +1,37 @@ +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 OnlineTweaks { get; set; } = new(); + public static List ProjectTweaks { get; 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 new file mode 100644 index 0000000..b1a97d2 --- /dev/null +++ b/mage/Tweaks/TweakParameter.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace mage.Tweaks; + +public class TweakParameter +{ + public string Name { get; set; } = "new_parameter"; + public string? DisplayName { get; set; } + public string? Description { get; set; } + public long? Value { 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/TweakPatch.cs b/mage/Tweaks/TweakPatch.cs new file mode 100644 index 0000000..b43347b --- /dev/null +++ b/mage/Tweaks/TweakPatch.cs @@ -0,0 +1,54 @@ +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 List? OldData { get; set; } + + public long ResolveOffset(IReadOnlyDictionary parameters) => EvaluateExpression(Offset, 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) + { + 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/Tweaks/TweakValidation.cs b/mage/Tweaks/TweakValidation.cs new file mode 100644 index 0000000..9977f9f --- /dev/null +++ b/mage/Tweaks/TweakValidation.cs @@ -0,0 +1,112 @@ +using NCalc; +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.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 { evaluate(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 = evaluate(options[0]); } + catch { throw new Exception("Min Value is not a number"); } + if (options.Length == 2) + try { max = evaluate(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 (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/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, 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')}"; diff --git a/mage/Version.cs b/mage/Version.cs index 90bd6da..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,8 +144,17 @@ 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 { get; set; } = null; + public static BackupService? BackupService + { + get => field; + set + { + if (field != null) field.Stop(); + field = value; + } + } public static string[] Clipdata { @@ -545,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); @@ -585,9 +602,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 +615,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) diff --git a/mage/mage.csproj b/mage/mage.csproj index 4987278..c279ed0 100644 --- a/mage/mage.csproj +++ b/mage/mage.csproj @@ -90,6 +90,12 @@ Component + + UserControl + + + UserControl + @@ -173,6 +179,7 @@ +