diff --git a/OpenRa.BlockCacheVisualizer/Form1.Designer.cs b/OpenRa.BlockCacheVisualizer/Form1.Designer.cs
new file mode 100644
index 0000000000..a525d53002
--- /dev/null
+++ b/OpenRa.BlockCacheVisualizer/Form1.Designer.cs
@@ -0,0 +1,60 @@
+namespace OpenRa.BlockCacheVisualizer
+{
+ 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.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
+ this.SuspendLayout();
+ //
+ // flowLayoutPanel1
+ //
+ this.flowLayoutPanel1.AutoScroll = true;
+ this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
+ this.flowLayoutPanel1.Name = "flowLayoutPanel1";
+ this.flowLayoutPanel1.Size = new System.Drawing.Size(748, 528);
+ this.flowLayoutPanel1.TabIndex = 0;
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(748, 528);
+ this.Controls.Add(this.flowLayoutPanel1);
+ this.Name = "Form1";
+ this.Text = "Form1";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
+ }
+}
+
diff --git a/OpenRa.BlockCacheVisualizer/Form1.cs b/OpenRa.BlockCacheVisualizer/Form1.cs
new file mode 100644
index 0000000000..bd8204a830
--- /dev/null
+++ b/OpenRa.BlockCacheVisualizer/Form1.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+
+namespace OpenRa.BlockCacheVisualizer
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ Visible = true;
+
+ OpenFileDialog d = new OpenFileDialog();
+ d.RestoreDirectory = true;
+ d.Filter = "OpenRA PNG Block Cache (*.png)|*.png";
+
+ if (DialogResult.OK != d.ShowDialog())
+ return;
+
+ string filename = d.FileName;
+ string palname = Path.GetDirectoryName(filename) + "\\palette-cache.png";
+
+ Bitmap palette = new Bitmap(palname);
+ Bitmap block = new Bitmap(filename);
+
+ unchecked
+ {
+ Color[] masks = {
+ Color.FromArgb( (int)0xff000000 ),
+ Color.FromArgb( (int)0x00ff0000 ),
+ Color.FromArgb( (int)0x0000ff00 ),
+ Color.FromArgb( (int)0x000000ff )
+ };
+
+ foreach (Color c in masks)
+ {
+ Bitmap b = ExtractChannelToBitmap(block, palette, c);
+ PictureBox pb = new PictureBox();
+
+ pb.SizeMode = PictureBoxSizeMode.AutoSize;
+ pb.Image = b;
+
+ flowLayoutPanel1.Controls.Add(pb);
+ }
+
+ }
+ }
+
+ int MaskColor(Color c, Color mask)
+ {
+ int result = 0;
+ if (mask.R > 0) result += c.R;
+ if (mask.G > 0) result += c.G;
+ if (mask.B > 0) result += c.B;
+ if (mask.A > 0) result += c.A;
+
+ return result;
+ }
+
+ Bitmap ExtractChannelToBitmap(Bitmap src, Bitmap pal, Color mask)
+ {
+ Bitmap dest = new Bitmap(src.Width, src.Height);
+
+ for( int i = 0; i < src.Width; i++ )
+ for (int j = 0; j < src.Height; j++)
+ {
+ int index = MaskColor(src.GetPixel(i, j), mask);
+ dest.SetPixel(i, j, pal.GetPixel(index, 0));
+ }
+
+ return dest;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenRa.BlockCacheVisualizer/Form1.resx b/OpenRa.BlockCacheVisualizer/Form1.resx
new file mode 100644
index 0000000000..ff31a6db56
--- /dev/null
+++ b/OpenRa.BlockCacheVisualizer/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.BlockCacheVisualizer/OpenRa.BlockCacheVisualizer.csproj b/OpenRa.BlockCacheVisualizer/OpenRa.BlockCacheVisualizer.csproj
new file mode 100644
index 0000000000..b058495057
--- /dev/null
+++ b/OpenRa.BlockCacheVisualizer/OpenRa.BlockCacheVisualizer.csproj
@@ -0,0 +1,60 @@
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {127D13D1-3589-4240-A33B-70C3A25536A4}
+ WinExe
+ Properties
+ OpenRa.BlockCacheVisualizer
+ OpenRa.BlockCacheVisualizer
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ Designer
+ Form1.cs
+
+
+
+
+
\ No newline at end of file
diff --git a/OpenRa.BlockCacheVisualizer/Program.cs b/OpenRa.BlockCacheVisualizer/Program.cs
new file mode 100644
index 0000000000..1fd48c145d
--- /dev/null
+++ b/OpenRa.BlockCacheVisualizer/Program.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+
+namespace OpenRa.BlockCacheVisualizer
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenRa.BlockCacheVisualizer/Properties/AssemblyInfo.cs b/OpenRa.BlockCacheVisualizer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..0948e9b23f
--- /dev/null
+++ b/OpenRa.BlockCacheVisualizer/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+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.BlockCacheVisualizer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OpenRa.BlockCacheVisualizer")]
+[assembly: AssemblyCopyright("Copyright © 2007")]
+[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("db73d0ce-dd5f-4143-92ed-3c8e8b98f380")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenRa.sln b/OpenRa.sln
index bbfa823aba..54a110afd6 100644
--- a/OpenRa.sln
+++ b/OpenRa.sln
@@ -19,6 +19,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BluntDx", "BluntDx\BluntDx.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.TechTree", "OpenRa.TechTree\OpenRa.TechTree.csproj", "{2BFC3861-E90E-4F77-B254-8FB8285E43AC}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.BlockCacheVisualizer", "OpenRa.BlockCacheVisualizer\OpenRa.BlockCacheVisualizer.csproj", "{127D13D1-3589-4240-A33B-70C3A25536A4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -89,6 +91,16 @@ Global
{2BFC3861-E90E-4F77-B254-8FB8285E43AC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{2BFC3861-E90E-4F77-B254-8FB8285E43AC}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{2BFC3861-E90E-4F77-B254-8FB8285E43AC}.Release|Win32.ActiveCfg = Release|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {127D13D1-3589-4240-A33B-70C3A25536A4}.Release|Win32.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE