diff --git a/OpenRA.TilesetBuilder/Form1.Designer.cs b/OpenRA.TilesetBuilder/Form1.Designer.cs
new file mode 100644
index 0000000000..0b199f7703
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Form1.Designer.cs
@@ -0,0 +1,61 @@
+namespace OpenRA.TilesetBuilder
+{
+ partial class Form1
+ {
+ ///
+ /// 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()
+ {
+ this.surface1 = new OpenRA.TilesetBuilder.Surface();
+ this.SuspendLayout();
+ //
+ // surface1
+ //
+ this.surface1.BackColor = System.Drawing.Color.Black;
+ this.surface1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.surface1.Location = new System.Drawing.Point(0, 0);
+ this.surface1.Name = "surface1";
+ this.surface1.Size = new System.Drawing.Size(745, 596);
+ this.surface1.TabIndex = 0;
+ this.surface1.Text = "surface1";
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(745, 596);
+ this.Controls.Add(this.surface1);
+ this.Name = "Form1";
+ this.Text = "Tileset Builder";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private Surface surface1;
+ }
+}
+
diff --git a/OpenRA.TilesetBuilder/Form1.cs b/OpenRA.TilesetBuilder/Form1.cs
new file mode 100644
index 0000000000..bd9e5d0f2b
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Form1.cs
@@ -0,0 +1,110 @@
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Linq;
+
+namespace OpenRA.TilesetBuilder
+{
+ public partial class Form1 : Form
+ {
+ public Form1( string src )
+ {
+ InitializeComponent();
+
+ surface1.Image = (Bitmap)Image.FromFile(src);
+ surface1.TerrainTypes = new int[surface1.Image.Width / 24, surface1.Image.Height / 24]; /* all passable by default */
+ surface1.Templates = new List();
+
+ /* todo: load stuff from previous session */
+ }
+ }
+
+ class Template
+ {
+ public Dictionary Cells = new Dictionary();
+ }
+
+ class Surface : Control
+ {
+ public Bitmap Image;
+ public int[,] TerrainTypes;
+ public List Templates = new List();
+
+ Template CurrentTemplate;
+
+ public Surface()
+ {
+ SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+ SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
+ SetStyle(ControlStyles.ResizeRedraw, true);
+ UpdateStyles();
+ }
+
+ Brush currentBrush = new SolidBrush(Color.FromArgb(60, Color.White));
+
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ if (Image == null || TerrainTypes == null || Templates == null)
+ return;
+
+ /* draw the background */
+ e.Graphics.DrawImageUnscaled(Image, 0, 0);
+
+ /* draw terrain type overlays */
+
+ /* draw template outlines */
+ foreach (var t in Templates)
+ {
+ foreach (var c in t.Cells.Keys)
+ {
+ if (CurrentTemplate == t)
+ e.Graphics.FillRectangle(currentBrush, 24 * c.X, 24 * c.Y, 24, 24);
+
+ if (!t.Cells.ContainsKey(c + new int2(-1, 0)))
+ e.Graphics.DrawLine(Pens.Red, (24 * c).ToPoint(), (24 * (c + new int2(0, 1))).ToPoint());
+ if (!t.Cells.ContainsKey(c + new int2(+1, 0)))
+ e.Graphics.DrawLine(Pens.Red, (24 * (c + new int2(1, 0))).ToPoint(), (24 * (c + new int2(1, 1))).ToPoint());
+ if (!t.Cells.ContainsKey(c + new int2(0, +1)))
+ e.Graphics.DrawLine(Pens.Red, (24 * (c + new int2(0, 1))).ToPoint(), (24 * (c + new int2(1, 1))).ToPoint());
+ if (!t.Cells.ContainsKey(c + new int2(0, -1)))
+ e.Graphics.DrawLine(Pens.Red, (24 * c).ToPoint(), (24 * (c + new int2(1, 0))).ToPoint());
+ }
+ }
+ }
+
+ protected override void OnMouseDown(MouseEventArgs e)
+ {
+ var pos = new int2( e.X / 24, e.Y / 24 );
+
+ if (e.Button == MouseButtons.Left)
+ {
+ CurrentTemplate = Templates.FirstOrDefault(t => t.Cells.ContainsKey(pos));
+ if (CurrentTemplate == null)
+ Templates.Add(CurrentTemplate = new Template { Cells = new Dictionary { { pos, true } } });
+
+ Invalidate();
+ }
+
+ if (e.Button == MouseButtons.Right)
+ {
+ Templates.RemoveAll(t => t.Cells.ContainsKey(pos));
+ CurrentTemplate = null;
+ Invalidate();
+ }
+ }
+
+ protected override void OnMouseMove(MouseEventArgs e)
+ {
+ var pos = new int2(e.X / 24, e.Y / 24);
+
+ if (e.Button == MouseButtons.Left && CurrentTemplate != null)
+ {
+ if (!CurrentTemplate.Cells.ContainsKey(pos))
+ {
+ CurrentTemplate.Cells[pos] = true;
+ Invalidate();
+ }
+ }
+ }
+ }
+}
diff --git a/OpenRA.TilesetBuilder/Form1.resx b/OpenRA.TilesetBuilder/Form1.resx
new file mode 100644
index 0000000000..ff31a6db56
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Form1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/OpenRA.TilesetBuilder/OpenRA.TilesetBuilder.csproj b/OpenRA.TilesetBuilder/OpenRA.TilesetBuilder.csproj
new file mode 100644
index 0000000000..e134120538
--- /dev/null
+++ b/OpenRA.TilesetBuilder/OpenRA.TilesetBuilder.csproj
@@ -0,0 +1,100 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}
+ WinExe
+ Properties
+ OpenRA.TilesetBuilder
+ OpenRA.TilesetBuilder
+ v3.5
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ x86
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+ {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}
+ OpenRA.FileFormats
+
+
+ {0DFB103F-2962-400F-8C6D-E2C28CCBA633}
+ OpenRA.Game
+
+
+
+
+
\ No newline at end of file
diff --git a/OpenRA.TilesetBuilder/Program.cs b/OpenRA.TilesetBuilder/Program.cs
new file mode 100644
index 0000000000..c32db2d8fa
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Program.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace OpenRA.TilesetBuilder
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main(string[] args)
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1(args.First()));
+ }
+ }
+}
diff --git a/OpenRA.TilesetBuilder/Properties/AssemblyInfo.cs b/OpenRA.TilesetBuilder/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..98243827bb
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OpenRA.TilesetBuilder")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OpenRA.TilesetBuilder")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9efec6a6-74f7-4a7d-a509-aba2aae75bcc")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenRA.TilesetBuilder/Properties/Resources.Designer.cs b/OpenRA.TilesetBuilder/Properties/Resources.Designer.cs
new file mode 100644
index 0000000000..d3640899ac
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4200
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace OpenRA.TilesetBuilder.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenRA.TilesetBuilder.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/OpenRA.TilesetBuilder/Properties/Resources.resx b/OpenRA.TilesetBuilder/Properties/Resources.resx
new file mode 100644
index 0000000000..ffecec851a
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/OpenRA.TilesetBuilder/Properties/Settings.Designer.cs b/OpenRA.TilesetBuilder/Properties/Settings.Designer.cs
new file mode 100644
index 0000000000..58a775578e
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4200
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace OpenRA.TilesetBuilder.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/OpenRA.TilesetBuilder/Properties/Settings.settings b/OpenRA.TilesetBuilder/Properties/Settings.settings
new file mode 100644
index 0000000000..abf36c5d3d
--- /dev/null
+++ b/OpenRA.TilesetBuilder/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/OpenRA.sln b/OpenRA.sln
index 4955cd8d22..5bb2026243 100644
--- a/OpenRA.sln
+++ b/OpenRA.sln
@@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapConverter", "MapConverte
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRA.Editor", "OpenRA.Editor\OpenRA.Editor.csproj", "{00038B75-405B-44F5-8691-BD2546DBE224}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRA.TilesetBuilder", "OpenRA.TilesetBuilder\OpenRA.TilesetBuilder.csproj", "{56B1073B-AE14-499A-BB98-43A8DE9A39CA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -98,6 +100,14 @@ Global
{00038B75-405B-44F5-8691-BD2546DBE224}.Release|Any CPU.Build.0 = Release|Any CPU
{00038B75-405B-44F5-8691-BD2546DBE224}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{00038B75-405B-44F5-8691-BD2546DBE224}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {56B1073B-AE14-499A-BB98-43A8DE9A39CA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE