├── .gitignore
├── BlastCorpsConsole
├── App.config
├── BlastCorpsConsole.csproj
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── BlastCorpsEditor.sln
├── BlastCorpsEditor
├── AboutBox.Designer.cs
├── AboutBox.cs
├── AboutBox.resx
├── App.config
├── BlastCorps.ico
├── BlastCorps3DForm.Designer.cs
├── BlastCorps3DForm.cs
├── BlastCorps3DForm.resx
├── BlastCorpsEditor.csproj
├── BlastCorpsEditorForm.Designer.cs
├── BlastCorpsEditorForm.cs
├── BlastCorpsEditorForm.resx
├── BlastCorpsLevel.cs
├── BlastCorpsRom.cs
├── BlastCorpsTexture.cs
├── BlastCorpsViewer.Designer.cs
├── BlastCorpsViewer.cs
├── BlastCorpsViewer.resx
├── ExportDialog.Designer.cs
├── ExportDialog.cs
├── ExportDialog.resx
├── Model3D.cs
├── N64Graphics.cs
├── PictureBoxInterpolation.cs
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── TextureForm.Designer.cs
├── TextureForm.cs
├── TextureForm.resx
├── Utils.cs
├── WavefrontObjExporter.cs
└── cursors
│ ├── cursor-move.cur
│ └── cursor-plus.cur
├── LICENSE
├── README.md
└── TODO
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 |
84 | # Visual Studio profiler
85 | *.psess
86 | *.vsp
87 | *.vspx
88 | *.sap
89 |
90 | # TFS 2012 Local Workspace
91 | $tf/
92 |
93 | # Guidance Automation Toolkit
94 | *.gpState
95 |
96 | # ReSharper is a .NET coding add-in
97 | _ReSharper*/
98 | *.[Rr]e[Ss]harper
99 | *.DotSettings.user
100 |
101 | # JustCode is a .NET coding add-in
102 | .JustCode
103 |
104 | # TeamCity is a build add-in
105 | _TeamCity*
106 |
107 | # DotCover is a Code Coverage Tool
108 | *.dotCover
109 |
110 | # NCrunch
111 | _NCrunch_*
112 | .*crunch*.local.xml
113 | nCrunchTemp_*
114 |
115 | # MightyMoose
116 | *.mm.*
117 | AutoTest.Net/
118 |
119 | # Web workbench (sass)
120 | .sass-cache/
121 |
122 | # Installshield output folder
123 | [Ee]xpress/
124 |
125 | # DocProject is a documentation generator add-in
126 | DocProject/buildhelp/
127 | DocProject/Help/*.HxT
128 | DocProject/Help/*.HxC
129 | DocProject/Help/*.hhc
130 | DocProject/Help/*.hhk
131 | DocProject/Help/*.hhp
132 | DocProject/Help/Html2
133 | DocProject/Help/html
134 |
135 | # Click-Once directory
136 | publish/
137 |
138 | # Publish Web Output
139 | *.[Pp]ublish.xml
140 | *.azurePubxml
141 | # TODO: Comment the next line if you want to checkin your web deploy settings
142 | # but database connection strings (with potential passwords) will be unencrypted
143 | *.pubxml
144 | *.publishproj
145 |
146 | # NuGet Packages
147 | *.nupkg
148 | # The packages folder can be ignored because of Package Restore
149 | **/packages/*
150 | # except build/, which is used as an MSBuild target.
151 | !**/packages/build/
152 | # Uncomment if necessary however generally it will be regenerated when needed
153 | #!**/packages/repositories.config
154 | # NuGet v3's project.json files produces more ignoreable files
155 | *.nuget.props
156 | *.nuget.targets
157 |
158 | # Microsoft Azure Build Output
159 | csx/
160 | *.build.csdef
161 |
162 | # Microsoft Azure Emulator
163 | ecf/
164 | rcf/
165 |
166 | # Microsoft Azure ApplicationInsights config file
167 | ApplicationInsights.config
168 |
169 | # Windows Store app package directory
170 | AppPackages/
171 | BundleArtifacts/
172 |
173 | # Visual Studio cache files
174 | # files ending in .cache can be ignored
175 | *.[Cc]ache
176 | # but keep track of directories ending in .cache
177 | !*.[Cc]ache/
178 |
179 | # Others
180 | ClientBin/
181 | ~$*
182 | *~
183 | *.dbmdl
184 | *.dbproj.schemaview
185 | *.pfx
186 | *.publishsettings
187 | node_modules/
188 | orleans.codegen.cs
189 |
190 | # RIA/Silverlight projects
191 | Generated_Code/
192 |
193 | # Backup & report files from converting an old project file
194 | # to a newer Visual Studio version. Backup files are not needed,
195 | # because we have git ;-)
196 | _UpgradeReport_Files/
197 | Backup*/
198 | UpgradeLog*.XML
199 | UpgradeLog*.htm
200 |
201 | # SQL Server files
202 | *.mdf
203 | *.ldf
204 |
205 | # Business Intelligence projects
206 | *.rdl.data
207 | *.bim.layout
208 | *.bim_*.settings
209 |
210 | # Microsoft Fakes
211 | FakesAssemblies/
212 |
213 | # GhostDoc plugin setting file
214 | *.GhostDoc.xml
215 |
216 | # Node.js Tools for Visual Studio
217 | .ntvs_analysis.dat
218 |
219 | # Visual Studio 6 build log
220 | *.plg
221 |
222 | # Visual Studio 6 workspace options file
223 | *.opt
224 |
225 | # Visual Studio LightSwitch build output
226 | **/*.HTMLClient/GeneratedArtifacts
227 | **/*.DesktopClient/GeneratedArtifacts
228 | **/*.DesktopClient/ModelManifest.xml
229 | **/*.Server/GeneratedArtifacts
230 | **/*.Server/ModelManifest.xml
231 | _Pvt_Extensions
232 |
233 | # Paket dependency manager
234 | .paket/paket.exe
235 |
236 | # FAKE - F# Make
237 | .fake/
238 |
--------------------------------------------------------------------------------
/BlastCorpsConsole/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/BlastCorpsConsole/BlastCorpsConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {1E746792-F706-45C0-88A3-C9A74111AAA6}
8 | Exe
9 | Properties
10 | BlastCorpsConsole
11 | BlastCorpsConsole
12 | v4.5
13 | 512
14 | publish\
15 | true
16 | Disk
17 | false
18 | Foreground
19 | 7
20 | Days
21 | false
22 | false
23 | true
24 | 0
25 | 1.0.0.%2a
26 | false
27 | false
28 | true
29 |
30 |
31 | AnyCPU
32 | true
33 | full
34 | false
35 | bin\Debug\
36 | DEBUG;TRACE
37 | prompt
38 | 4
39 |
40 |
41 | AnyCPU
42 | pdbonly
43 | true
44 | bin\Release\
45 | TRACE
46 | prompt
47 | 4
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | {8a6eb49f-95c9-48c9-9796-60f6b7dbac98}
68 | BlastCorpsEditor
69 |
70 |
71 |
72 |
73 | False
74 | Microsoft .NET Framework 4.5 %28x86 and x64%29
75 | true
76 |
77 |
78 | False
79 | .NET Framework 3.5 SP1 Client Profile
80 | false
81 |
82 |
83 | False
84 | .NET Framework 3.5 SP1
85 | false
86 |
87 |
88 |
89 |
96 |
--------------------------------------------------------------------------------
/BlastCorpsConsole/Program.cs:
--------------------------------------------------------------------------------
1 | using BlastCorpsEditor;
2 | using System;
3 | using System.IO;
4 |
5 | namespace BlastCorpsConsole
6 | {
7 | class Program
8 | {
9 | static void StatusPrint(ConsoleColor color, string colorMessage, string plainMessage)
10 | {
11 | ConsoleColor orig = System.Console.ForegroundColor;
12 | System.Console.ForegroundColor = color;
13 | System.Console.Write(colorMessage);
14 | System.Console.ForegroundColor = orig;
15 | System.Console.WriteLine(": " + plainMessage);
16 | }
17 |
18 | static void Main(string[] args)
19 | {
20 | if (args.Length < 1)
21 | {
22 | System.Console.WriteLine("Usage: BlastCorpsConsole
[DIR to output .txt]");
23 | return;
24 | }
25 | string tmpDir = Path.GetTempPath();
26 | string inputDir = args[0];
27 | string outputDir = null;
28 |
29 | if (args.Length > 1)
30 | {
31 | outputDir = args[1];
32 | System.Console.WriteLine("Outputing data to {0}", outputDir);
33 | }
34 |
35 | tmpDir = Path.Combine(tmpDir, "BlastCorps");
36 | System.Console.WriteLine("Saving generated levels to: " + tmpDir);
37 |
38 | Directory.CreateDirectory(tmpDir);
39 |
40 | foreach (BlastCorpsLevelMeta levelMeta in BlastCorpsRom.levelMeta)
41 | {
42 | string inputFile = Path.Combine(inputDir, levelMeta.filename + ".raw");
43 | string outputFile = Path.Combine(tmpDir, levelMeta.filename + ".raw");
44 | byte[] inData = File.ReadAllBytes(inputFile);
45 | BlastCorpsLevel level = BlastCorpsLevel.decodeLevel(inData, inData);
46 |
47 | if (outputDir != null)
48 | {
49 | string txtFile = Path.Combine(outputDir, levelMeta.filename + ".txt");
50 | using (StreamWriter writer = new StreamWriter(txtFile))
51 | {
52 | level.Write(writer, levelMeta);
53 | }
54 | }
55 |
56 | byte[] outData = level.ToBytes();
57 | FileStream outStream = File.OpenWrite(outputFile);
58 | outStream.Write(outData, 0, outData.Length);
59 | outStream.Close();
60 | bool passed = true;
61 | if (levelMeta.id == 14)
62 | {
63 | StatusPrint(ConsoleColor.Yellow, "level14 fails square hole off", "0175A5");
64 | }
65 | if (inData.Length != outData.Length)
66 | {
67 | StatusPrint(ConsoleColor.Red, "Fail", levelMeta.filename + ".raw, lengths differ: " + inData.Length + " -> " + outData.Length);
68 | passed = false;
69 | }
70 | for (int i = 0; i < Math.Min(inData.Length, outData.Length); i++)
71 | {
72 | if (inData[i] != outData[i])
73 | {
74 | StatusPrint(ConsoleColor.Red, "Fail", levelMeta.filename + ".raw, mismatch at " + i.ToString("X6"));
75 | passed = false;
76 | break;
77 | }
78 | }
79 | if (passed)
80 | {
81 | StatusPrint(ConsoleColor.Green, "Pass", levelMeta.filename + ".raw");
82 | }
83 | }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/BlastCorpsConsole/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("BlastCorpsConsole")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("queueRAM")]
12 | [assembly: AssemblyProduct("BlastCorpsConsole")]
13 | [assembly: AssemblyCopyright("Copyright © queueRAM 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("7533aefe-d862-474a-9c01-7f11d1ff384d")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.0.3.2")]
36 | [assembly: AssemblyFileVersion("0.0.3.2")]
37 |
--------------------------------------------------------------------------------
/BlastCorpsEditor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Express 2013 for Windows Desktop
4 | VisualStudioVersion = 12.0.40629.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlastCorpsEditor", "BlastCorpsEditor\BlastCorpsEditor.csproj", "{8A6EB49F-95C9-48C9-9796-60F6B7DBAC98}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlastCorpsConsole", "BlastCorpsConsole\BlastCorpsConsole.csproj", "{1E746792-F706-45C0-88A3-C9A74111AAA6}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {8A6EB49F-95C9-48C9-9796-60F6B7DBAC98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {8A6EB49F-95C9-48C9-9796-60F6B7DBAC98}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {8A6EB49F-95C9-48C9-9796-60F6B7DBAC98}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {8A6EB49F-95C9-48C9-9796-60F6B7DBAC98}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {1E746792-F706-45C0-88A3-C9A74111AAA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {1E746792-F706-45C0-88A3-C9A74111AAA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {1E746792-F706-45C0-88A3-C9A74111AAA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {1E746792-F706-45C0-88A3-C9A74111AAA6}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/AboutBox.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BlastCorpsEditor
2 | {
3 | partial class AboutBox
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | protected override void Dispose(bool disposing)
14 | {
15 | if (disposing && (components != null))
16 | {
17 | components.Dispose();
18 | }
19 | base.Dispose(disposing);
20 | }
21 |
22 | #region Windows Form Designer generated code
23 |
24 | ///
25 | /// Required method for Designer support - do not modify
26 | /// the contents of this method with the code editor.
27 | ///
28 | private void InitializeComponent()
29 | {
30 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox));
31 | this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
32 | this.labelProductName = new System.Windows.Forms.Label();
33 | this.labelVersion = new System.Windows.Forms.Label();
34 | this.labelCopyright = new System.Windows.Forms.Label();
35 | this.okButton = new System.Windows.Forms.Button();
36 | this.logoPictureBox = new System.Windows.Forms.PictureBox();
37 | this.textBoxDescription = new System.Windows.Forms.TextBox();
38 | this.tableLayoutPanel.SuspendLayout();
39 | ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
40 | this.SuspendLayout();
41 | //
42 | // tableLayoutPanel
43 | //
44 | this.tableLayoutPanel.ColumnCount = 2;
45 | this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
46 | this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
47 | this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
48 | this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1);
49 | this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 2);
50 | this.tableLayoutPanel.Controls.Add(this.okButton, 1, 4);
51 | this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
52 | this.tableLayoutPanel.Controls.Add(this.textBoxDescription, 0, 3);
53 | this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
54 | this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9);
55 | this.tableLayoutPanel.Name = "tableLayoutPanel";
56 | this.tableLayoutPanel.RowCount = 5;
57 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
58 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
59 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
60 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
61 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F));
62 | this.tableLayoutPanel.Size = new System.Drawing.Size(417, 206);
63 | this.tableLayoutPanel.TabIndex = 0;
64 | //
65 | // labelProductName
66 | //
67 | this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
68 | this.labelProductName.Location = new System.Drawing.Point(86, 0);
69 | this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
70 | this.labelProductName.MaximumSize = new System.Drawing.Size(0, 17);
71 | this.labelProductName.Name = "labelProductName";
72 | this.labelProductName.Size = new System.Drawing.Size(328, 17);
73 | this.labelProductName.TabIndex = 19;
74 | this.labelProductName.Text = "Product Name";
75 | this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
76 | //
77 | // labelVersion
78 | //
79 | this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill;
80 | this.labelVersion.Location = new System.Drawing.Point(86, 24);
81 | this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
82 | this.labelVersion.MaximumSize = new System.Drawing.Size(0, 17);
83 | this.labelVersion.Name = "labelVersion";
84 | this.labelVersion.Size = new System.Drawing.Size(328, 17);
85 | this.labelVersion.TabIndex = 0;
86 | this.labelVersion.Text = "Version";
87 | this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
88 | //
89 | // labelCopyright
90 | //
91 | this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
92 | this.labelCopyright.Location = new System.Drawing.Point(86, 48);
93 | this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
94 | this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 17);
95 | this.labelCopyright.Name = "labelCopyright";
96 | this.labelCopyright.Size = new System.Drawing.Size(328, 17);
97 | this.labelCopyright.TabIndex = 21;
98 | this.labelCopyright.Text = "Copyright";
99 | this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
100 | //
101 | // okButton
102 | //
103 | this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
104 | this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
105 | this.okButton.Location = new System.Drawing.Point(339, 183);
106 | this.okButton.Name = "okButton";
107 | this.okButton.Size = new System.Drawing.Size(75, 22);
108 | this.okButton.TabIndex = 24;
109 | this.okButton.Text = "&OK";
110 | //
111 | // logoPictureBox
112 | //
113 | this.logoPictureBox.Dock = System.Windows.Forms.DockStyle.Top;
114 | this.logoPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("logoPictureBox.Image")));
115 | this.logoPictureBox.Location = new System.Drawing.Point(3, 3);
116 | this.logoPictureBox.Name = "logoPictureBox";
117 | this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 3);
118 | this.logoPictureBox.Size = new System.Drawing.Size(74, 66);
119 | this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
120 | this.logoPictureBox.TabIndex = 12;
121 | this.logoPictureBox.TabStop = false;
122 | //
123 | // textBoxDescription
124 | //
125 | this.tableLayoutPanel.SetColumnSpan(this.textBoxDescription, 2);
126 | this.textBoxDescription.Dock = System.Windows.Forms.DockStyle.Fill;
127 | this.textBoxDescription.Location = new System.Drawing.Point(6, 75);
128 | this.textBoxDescription.Margin = new System.Windows.Forms.Padding(6, 3, 3, 3);
129 | this.textBoxDescription.Multiline = true;
130 | this.textBoxDescription.Name = "textBoxDescription";
131 | this.textBoxDescription.ReadOnly = true;
132 | this.textBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Both;
133 | this.textBoxDescription.Size = new System.Drawing.Size(408, 100);
134 | this.textBoxDescription.TabIndex = 23;
135 | this.textBoxDescription.TabStop = false;
136 | this.textBoxDescription.Text = "Description";
137 | //
138 | // AboutBox
139 | //
140 | this.AcceptButton = this.okButton;
141 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
142 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
143 | this.ClientSize = new System.Drawing.Size(435, 224);
144 | this.Controls.Add(this.tableLayoutPanel);
145 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
146 | this.MaximizeBox = false;
147 | this.MinimizeBox = false;
148 | this.Name = "AboutBox";
149 | this.Padding = new System.Windows.Forms.Padding(9);
150 | this.ShowIcon = false;
151 | this.ShowInTaskbar = false;
152 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
153 | this.Text = "AboutBox";
154 | this.tableLayoutPanel.ResumeLayout(false);
155 | this.tableLayoutPanel.PerformLayout();
156 | ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
157 | this.ResumeLayout(false);
158 |
159 | }
160 |
161 | #endregion
162 |
163 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
164 | private System.Windows.Forms.PictureBox logoPictureBox;
165 | private System.Windows.Forms.Label labelProductName;
166 | private System.Windows.Forms.Label labelVersion;
167 | private System.Windows.Forms.Label labelCopyright;
168 | private System.Windows.Forms.TextBox textBoxDescription;
169 | private System.Windows.Forms.Button okButton;
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/AboutBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Windows.Forms;
4 |
5 | namespace BlastCorpsEditor
6 | {
7 | partial class AboutBox : Form
8 | {
9 | public AboutBox()
10 | {
11 | var thanks = "Special thanks to :\r\n" +
12 | " \u2022 SunakazeKun / Aurum for Blast Corps documentation and testing\r\n" +
13 | " \u2022 SubDrag for the Universal N64 Compressor and notes\r\n" +
14 | " \u2022 Everyone else who has helped along the way";
15 | InitializeComponent();
16 | this.Text = String.Format("About {0}", AssemblyTitle);
17 | this.labelProductName.Text = AssemblyProduct;
18 | this.labelVersion.Text = String.Format("Version {0}", AssemblyVersion);
19 | this.labelCopyright.Text = AssemblyCopyright;
20 | this.textBoxDescription.Text = thanks;
21 | }
22 |
23 | #region Assembly Attribute Accessors
24 |
25 | public string AssemblyTitle
26 | {
27 | get
28 | {
29 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
30 | if (attributes.Length > 0)
31 | {
32 | AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
33 | if (titleAttribute.Title != "")
34 | {
35 | return titleAttribute.Title;
36 | }
37 | }
38 | return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
39 | }
40 | }
41 |
42 | public string AssemblyVersion
43 | {
44 | get
45 | {
46 | return Assembly.GetExecutingAssembly().GetName().Version.ToString();
47 | }
48 | }
49 |
50 | public string AssemblyDescription
51 | {
52 | get
53 | {
54 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
55 | if (attributes.Length == 0)
56 | {
57 | return "";
58 | }
59 | return ((AssemblyDescriptionAttribute)attributes[0]).Description;
60 | }
61 | }
62 |
63 | public string AssemblyProduct
64 | {
65 | get
66 | {
67 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
68 | if (attributes.Length == 0)
69 | {
70 | return "";
71 | }
72 | return ((AssemblyProductAttribute)attributes[0]).Product;
73 | }
74 | }
75 |
76 | public string AssemblyCopyright
77 | {
78 | get
79 | {
80 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
81 | if (attributes.Length == 0)
82 | {
83 | return "";
84 | }
85 | return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
86 | }
87 | }
88 |
89 | public string AssemblyCompany
90 | {
91 | get
92 | {
93 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
94 | if (attributes.Length == 0)
95 | {
96 | return "";
97 | }
98 | return ((AssemblyCompanyAttribute)attributes[0]).Company;
99 | }
100 | }
101 | #endregion
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/AboutBox.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 |
123 | 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
242 | SUVORK5CYII=
243 |
244 |
245 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | False
15 |
16 |
17 | False
18 |
19 |
20 | True
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/BlastCorps.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queueRAM/BlastCorpsEditor/0ae39a7bf0db381fb0e70805ac7f384eb81d3bd7/BlastCorpsEditor/BlastCorps.ico
--------------------------------------------------------------------------------
/BlastCorpsEditor/BlastCorps3DForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BlastCorpsEditor
2 | {
3 | partial class BlastCorps3DForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BlastCorps3DForm));
32 | this.glControlViewer = new OpenTK.GLControl();
33 | this.labelX = new System.Windows.Forms.Label();
34 | this.labelY = new System.Windows.Forms.Label();
35 | this.labelZ = new System.Windows.Forms.Label();
36 | this.labelHeading = new System.Windows.Forms.Label();
37 | this.labelPitch = new System.Windows.Forms.Label();
38 | this.checkBoxCollision6C = new System.Windows.Forms.CheckBox();
39 | this.checkBoxTerrain = new System.Windows.Forms.CheckBox();
40 | this.checkBoxDisplay = new System.Windows.Forms.CheckBox();
41 | this.checkBoxWireframe = new System.Windows.Forms.CheckBox();
42 | this.checkBoxWalls = new System.Windows.Forms.CheckBox();
43 | this.checkBoxCollision24 = new System.Windows.Forms.CheckBox();
44 | this.checkBox44 = new System.Windows.Forms.CheckBox();
45 | this.checkBox40 = new System.Windows.Forms.CheckBox();
46 | this.labelType = new System.Windows.Forms.Label();
47 | this.labelIndex = new System.Windows.Forms.Label();
48 | this.SuspendLayout();
49 | //
50 | // glControlViewer
51 | //
52 | this.glControlViewer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
53 | | System.Windows.Forms.AnchorStyles.Left)
54 | | System.Windows.Forms.AnchorStyles.Right)));
55 | this.glControlViewer.BackColor = System.Drawing.Color.Black;
56 | this.glControlViewer.Location = new System.Drawing.Point(0, 51);
57 | this.glControlViewer.Name = "glControlViewer";
58 | this.glControlViewer.Size = new System.Drawing.Size(914, 635);
59 | this.glControlViewer.TabIndex = 1;
60 | this.glControlViewer.VSync = false;
61 | this.glControlViewer.Load += new System.EventHandler(this.glControlViewer_Load);
62 | this.glControlViewer.Paint += new System.Windows.Forms.PaintEventHandler(this.glControlViewer_Paint);
63 | this.glControlViewer.KeyDown += new System.Windows.Forms.KeyEventHandler(this.glControlViewer_KeyDown);
64 | this.glControlViewer.MouseDown += new System.Windows.Forms.MouseEventHandler(this.glControlViewer_MouseDown);
65 | this.glControlViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.glControlViewer_MouseMove);
66 | this.glControlViewer.Resize += new System.EventHandler(this.glControlViewer_Resize);
67 | //
68 | // labelX
69 | //
70 | this.labelX.AutoSize = true;
71 | this.labelX.Location = new System.Drawing.Point(12, 9);
72 | this.labelX.Name = "labelX";
73 | this.labelX.Size = new System.Drawing.Size(17, 13);
74 | this.labelX.TabIndex = 2;
75 | this.labelX.Text = "X:";
76 | //
77 | // labelY
78 | //
79 | this.labelY.AutoSize = true;
80 | this.labelY.Location = new System.Drawing.Point(12, 22);
81 | this.labelY.Name = "labelY";
82 | this.labelY.Size = new System.Drawing.Size(17, 13);
83 | this.labelY.TabIndex = 3;
84 | this.labelY.Text = "Y:";
85 | //
86 | // labelZ
87 | //
88 | this.labelZ.AutoSize = true;
89 | this.labelZ.Location = new System.Drawing.Point(12, 35);
90 | this.labelZ.Name = "labelZ";
91 | this.labelZ.Size = new System.Drawing.Size(17, 13);
92 | this.labelZ.TabIndex = 4;
93 | this.labelZ.Text = "Z:";
94 | //
95 | // labelHeading
96 | //
97 | this.labelHeading.AutoSize = true;
98 | this.labelHeading.Location = new System.Drawing.Point(74, 9);
99 | this.labelHeading.Name = "labelHeading";
100 | this.labelHeading.Size = new System.Drawing.Size(18, 13);
101 | this.labelHeading.TabIndex = 5;
102 | this.labelHeading.Text = "H:";
103 | //
104 | // labelPitch
105 | //
106 | this.labelPitch.AutoSize = true;
107 | this.labelPitch.Location = new System.Drawing.Point(74, 22);
108 | this.labelPitch.Name = "labelPitch";
109 | this.labelPitch.Size = new System.Drawing.Size(17, 13);
110 | this.labelPitch.TabIndex = 6;
111 | this.labelPitch.Text = "P:";
112 | //
113 | // checkBoxCollision6C
114 | //
115 | this.checkBoxCollision6C.AutoSize = true;
116 | this.checkBoxCollision6C.Checked = true;
117 | this.checkBoxCollision6C.CheckState = System.Windows.Forms.CheckState.Checked;
118 | this.checkBoxCollision6C.Location = new System.Drawing.Point(425, 5);
119 | this.checkBoxCollision6C.Name = "checkBoxCollision6C";
120 | this.checkBoxCollision6C.Size = new System.Drawing.Size(138, 17);
121 | this.checkBoxCollision6C.TabIndex = 7;
122 | this.checkBoxCollision6C.Text = "Show Collision H (0x6C)";
123 | this.checkBoxCollision6C.UseVisualStyleBackColor = true;
124 | this.checkBoxCollision6C.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
125 | //
126 | // checkBoxTerrain
127 | //
128 | this.checkBoxTerrain.AutoSize = true;
129 | this.checkBoxTerrain.Checked = true;
130 | this.checkBoxTerrain.CheckState = System.Windows.Forms.CheckState.Checked;
131 | this.checkBoxTerrain.Location = new System.Drawing.Point(192, 21);
132 | this.checkBoxTerrain.Name = "checkBoxTerrain";
133 | this.checkBoxTerrain.Size = new System.Drawing.Size(121, 17);
134 | this.checkBoxTerrain.TabIndex = 8;
135 | this.checkBoxTerrain.Text = "Show Terrain (0x30)";
136 | this.checkBoxTerrain.UseVisualStyleBackColor = true;
137 | this.checkBoxTerrain.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
138 | //
139 | // checkBoxDisplay
140 | //
141 | this.checkBoxDisplay.AutoSize = true;
142 | this.checkBoxDisplay.Location = new System.Drawing.Point(569, 23);
143 | this.checkBoxDisplay.Name = "checkBoxDisplay";
144 | this.checkBoxDisplay.Size = new System.Drawing.Size(109, 17);
145 | this.checkBoxDisplay.TabIndex = 9;
146 | this.checkBoxDisplay.Text = "Show Display List";
147 | this.checkBoxDisplay.UseVisualStyleBackColor = true;
148 | this.checkBoxDisplay.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
149 | //
150 | // checkBoxWireframe
151 | //
152 | this.checkBoxWireframe.AutoSize = true;
153 | this.checkBoxWireframe.Checked = true;
154 | this.checkBoxWireframe.CheckState = System.Windows.Forms.CheckState.Checked;
155 | this.checkBoxWireframe.Location = new System.Drawing.Point(569, 5);
156 | this.checkBoxWireframe.Name = "checkBoxWireframe";
157 | this.checkBoxWireframe.Size = new System.Drawing.Size(104, 17);
158 | this.checkBoxWireframe.TabIndex = 10;
159 | this.checkBoxWireframe.Text = "Show Wireframe";
160 | this.checkBoxWireframe.UseVisualStyleBackColor = true;
161 | this.checkBoxWireframe.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
162 | //
163 | // checkBoxWalls
164 | //
165 | this.checkBoxWalls.AutoSize = true;
166 | this.checkBoxWalls.Location = new System.Drawing.Point(425, 23);
167 | this.checkBoxWalls.Name = "checkBoxWalls";
168 | this.checkBoxWalls.Size = new System.Drawing.Size(114, 17);
169 | this.checkBoxWalls.TabIndex = 11;
170 | this.checkBoxWalls.Text = "Show Walls (0x64)";
171 | this.checkBoxWalls.UseVisualStyleBackColor = true;
172 | this.checkBoxWalls.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
173 | //
174 | // checkBoxCollision24
175 | //
176 | this.checkBoxCollision24.AutoSize = true;
177 | this.checkBoxCollision24.Location = new System.Drawing.Point(192, 5);
178 | this.checkBoxCollision24.Name = "checkBoxCollision24";
179 | this.checkBoxCollision24.Size = new System.Drawing.Size(136, 17);
180 | this.checkBoxCollision24.TabIndex = 12;
181 | this.checkBoxCollision24.Text = "Show Collision V (0x24)";
182 | this.checkBoxCollision24.UseVisualStyleBackColor = true;
183 | this.checkBoxCollision24.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
184 | //
185 | // checkBox44
186 | //
187 | this.checkBox44.AutoSize = true;
188 | this.checkBox44.Location = new System.Drawing.Point(334, 23);
189 | this.checkBox44.Name = "checkBox44";
190 | this.checkBox44.Size = new System.Drawing.Size(85, 17);
191 | this.checkBox44.TabIndex = 14;
192 | this.checkBox44.Text = "Show (0x44)";
193 | this.checkBox44.UseVisualStyleBackColor = true;
194 | this.checkBox44.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
195 | //
196 | // checkBox40
197 | //
198 | this.checkBox40.AutoSize = true;
199 | this.checkBox40.Location = new System.Drawing.Point(334, 5);
200 | this.checkBox40.Name = "checkBox40";
201 | this.checkBox40.Size = new System.Drawing.Size(85, 17);
202 | this.checkBox40.TabIndex = 13;
203 | this.checkBox40.Text = "Show (0x40)";
204 | this.checkBox40.UseVisualStyleBackColor = true;
205 | this.checkBox40.CheckedChanged += new System.EventHandler(this.settingCheckedChanged);
206 | //
207 | // labelType
208 | //
209 | this.labelType.AutoSize = true;
210 | this.labelType.Location = new System.Drawing.Point(726, 8);
211 | this.labelType.Name = "labelType";
212 | this.labelType.Size = new System.Drawing.Size(34, 13);
213 | this.labelType.TabIndex = 15;
214 | this.labelType.Text = "Type:";
215 | //
216 | // labelIndex
217 | //
218 | this.labelIndex.AutoSize = true;
219 | this.labelIndex.Location = new System.Drawing.Point(729, 25);
220 | this.labelIndex.Name = "labelIndex";
221 | this.labelIndex.Size = new System.Drawing.Size(36, 13);
222 | this.labelIndex.TabIndex = 16;
223 | this.labelIndex.Text = "Index:";
224 | //
225 | // BlastCorps3DForm
226 | //
227 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
228 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
229 | this.ClientSize = new System.Drawing.Size(914, 686);
230 | this.Controls.Add(this.labelIndex);
231 | this.Controls.Add(this.labelType);
232 | this.Controls.Add(this.checkBox44);
233 | this.Controls.Add(this.checkBox40);
234 | this.Controls.Add(this.checkBoxCollision24);
235 | this.Controls.Add(this.checkBoxWalls);
236 | this.Controls.Add(this.checkBoxWireframe);
237 | this.Controls.Add(this.checkBoxDisplay);
238 | this.Controls.Add(this.checkBoxTerrain);
239 | this.Controls.Add(this.checkBoxCollision6C);
240 | this.Controls.Add(this.labelPitch);
241 | this.Controls.Add(this.labelHeading);
242 | this.Controls.Add(this.labelZ);
243 | this.Controls.Add(this.labelY);
244 | this.Controls.Add(this.labelX);
245 | this.Controls.Add(this.glControlViewer);
246 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
247 | this.Name = "BlastCorps3DForm";
248 | this.Text = "Blast Corps 3D Viewer";
249 | this.ResumeLayout(false);
250 | this.PerformLayout();
251 |
252 | }
253 |
254 | #endregion
255 |
256 | private OpenTK.GLControl glControlViewer;
257 | private System.Windows.Forms.Label labelX;
258 | private System.Windows.Forms.Label labelY;
259 | private System.Windows.Forms.Label labelZ;
260 | private System.Windows.Forms.Label labelHeading;
261 | private System.Windows.Forms.Label labelPitch;
262 | private System.Windows.Forms.CheckBox checkBoxCollision6C;
263 | private System.Windows.Forms.CheckBox checkBoxTerrain;
264 | private System.Windows.Forms.CheckBox checkBoxDisplay;
265 | private System.Windows.Forms.CheckBox checkBoxWireframe;
266 | private System.Windows.Forms.CheckBox checkBoxWalls;
267 | private System.Windows.Forms.CheckBox checkBoxCollision24;
268 | private System.Windows.Forms.CheckBox checkBox44;
269 | private System.Windows.Forms.CheckBox checkBox40;
270 | private System.Windows.Forms.Label labelType;
271 | private System.Windows.Forms.Label labelIndex;
272 |
273 | }
274 | }
--------------------------------------------------------------------------------
/BlastCorpsEditor/BlastCorpsEditor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8A6EB49F-95C9-48C9-9796-60F6B7DBAC98}
8 | WinExe
9 | Properties
10 | BlastCorpsEditor
11 | BlastCorpsEditor
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 | BlastCorps.ico
36 |
37 |
38 |
39 | False
40 | ..\external\OpenTK\1.1\Binaries\OpenTK\Release\OpenTK.dll
41 |
42 |
43 | False
44 | ..\external\OpenTK\1.1\Binaries\OpenTK\Release\OpenTK.GLControl.dll
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | Form
59 |
60 |
61 | AboutBox.cs
62 |
63 |
64 | Form
65 |
66 |
67 | BlastCorps3DForm.cs
68 |
69 |
70 |
71 | Form
72 |
73 |
74 | ExportDialog.cs
75 |
76 |
77 |
78 |
79 | Component
80 |
81 |
82 | Form
83 |
84 |
85 | TextureForm.cs
86 |
87 |
88 |
89 | Form
90 |
91 |
92 | BlastCorpsEditorForm.cs
93 |
94 |
95 |
96 |
97 | UserControl
98 |
99 |
100 | BlastCorpsViewer.cs
101 |
102 |
103 |
104 |
105 |
106 | AboutBox.cs
107 |
108 |
109 | BlastCorps3DForm.cs
110 |
111 |
112 | BlastCorpsEditorForm.cs
113 |
114 |
115 | BlastCorpsViewer.cs
116 |
117 |
118 | ExportDialog.cs
119 |
120 |
121 | ResXFileCodeGenerator
122 | Resources.Designer.cs
123 | Designer
124 |
125 |
126 | True
127 | Resources.resx
128 | True
129 |
130 |
131 | TextureForm.cs
132 |
133 |
134 | SettingsSingleFileGenerator
135 | Settings.Designer.cs
136 |
137 |
138 | True
139 | Settings.settings
140 | True
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
160 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/BlastCorpsTexture.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BlastCorpsEditor
8 | {
9 | class BlastCorpsTexture
10 | {
11 | public const UInt32 ROM_OFFSET = 0x4CE0;
12 | public UInt32 offset;
13 | public UInt16 length;
14 | public UInt16 type;
15 | private byte[] raw;
16 | private byte[] inflated;
17 | private byte[] lut; // lookup table used for types 4 and 5
18 |
19 | public BlastCorpsTexture(UInt32 offset, UInt16 length, UInt16 type)
20 | {
21 | this.offset = offset;
22 | this.length = length;
23 | this.type = type;
24 | }
25 |
26 | public BlastCorpsTexture(byte[] data, uint index, uint lutOffset)
27 | {
28 | offset = BE.U32(data, ROM_OFFSET + 8 * index);
29 | length = BE.U16(data, ROM_OFFSET + 8 * index + 4);
30 | type = BE.U16(data, ROM_OFFSET + 8 * index + 6);
31 | raw = new byte[length];
32 | Array.Copy(data, ROM_OFFSET + offset, raw, 0, length);
33 | if (type == 4 || type == 5)
34 | {
35 | lut = new byte[4096];
36 | Array.Copy(data, lutOffset, lut, 0, lut.Length);
37 | }
38 | }
39 |
40 | public byte[] GetInflated()
41 | {
42 | return inflated;
43 | }
44 |
45 | public void decode()
46 | {
47 | switch (type)
48 | {
49 | case 0: inflated = decode0(raw); break;
50 | case 1: inflated = decode1(raw); break;
51 | case 2: inflated = decode2(raw); break;
52 | // TODO: need to figure out where last param is set for decoders 4 and 5
53 | case 4: inflated = decode4(raw, lut); break;
54 | case 5: inflated = decode5(raw, lut); break;
55 | case 3: inflated = decode3(raw); break;
56 | case 6: inflated = decode6(raw); break;
57 | }
58 | }
59 |
60 | // just a memcpy from source to destination
61 | public static byte[] decode0(byte[] source)
62 | {
63 | byte[] retBuffer = new byte[source.Length];
64 | Array.Copy(source, retBuffer, retBuffer.Length);
65 | return retBuffer;
66 | }
67 |
68 | public static byte[] decode1(byte[] source)
69 | {
70 | byte[] retBuffer = new byte[256 * 256];
71 | int remaining = source.Length;
72 | uint inIdx = 0;
73 | int outIdx = 0;
74 | UInt16 t0, t1, t3;
75 | int t2;
76 | while (remaining != 0)
77 | {
78 | t0 = BE.U16(source, inIdx);
79 | inIdx += 2; // a0
80 | if ((t0 & 0x8000) == 0) {
81 | t1 = (UInt16)((t0 & 0xFFC0) << 1);
82 | t0 &= 0x3F;
83 | t0 = (UInt16)(t0 | t1);
84 | BE.ToBytes(t0, retBuffer, outIdx);
85 | outIdx += 2;
86 | remaining -= 2;
87 | } else {
88 | t1 = (UInt16)(t0 & 0x1F); // lookback length
89 | t0 = (UInt16)((t0 & 0x7FFF) >> 5); // lookback offset
90 | remaining -= 2; // a1
91 | t2 = outIdx - t0; // t2 - lookback pointer from current out
92 | while (t1 != 0) {
93 | t3 = BE.U16(retBuffer, (uint)t2);
94 | t2 += 2;
95 | outIdx += 2;
96 | t1 -= 1;
97 | BE.ToBytes(t3, retBuffer, outIdx - 2);
98 | }
99 | }
100 | }
101 | Array.Resize(ref retBuffer, outIdx);
102 | return retBuffer;
103 | }
104 |
105 | public static byte[] decode2(byte[] source)
106 | {
107 | byte[] retBuffer = new byte[256 * 256];
108 | int remaining = source.Length;
109 | uint inIdx = 0;
110 | uint outIdx = 0;
111 | uint lookIdx;
112 | UInt32 t0, t1, t2, t3;
113 | while (remaining != 0) {
114 | t0 = BE.U16(source, inIdx);
115 | inIdx += 2;
116 | if ((t0 & 0x8000) == 0) { // t0 >= 0
117 | t1 = t0 & 0x7800;
118 | t2 = t0 & 0x0780;
119 | t1 <<= 17; // 0x11
120 | t2 <<= 13; // 0xD;
121 | t1 |= t2;
122 | t2 = t0 & 0x78;
123 | t2 <<= 9;
124 | t1 |= t2;
125 | t2 = t0 & 7;
126 | t2 <<= 5;
127 | t1 |= t2;
128 | BE.ToBytes(t1, retBuffer, (int)outIdx);
129 | outIdx += 4;
130 | remaining -= 2;
131 | } else {
132 | t1 = t0 & 0x1f;
133 | t0 &= 0x7FE0;
134 | t0 >>= 4;
135 | remaining -= 2;
136 | lookIdx = outIdx - t0; // t2
137 | while (t1 != 0) {
138 | t3 = BE.U32(retBuffer, lookIdx);
139 | BE.ToBytes(t3, retBuffer, (int)outIdx);
140 | lookIdx += 4; // t2
141 | t1 -= 1;
142 | outIdx += 4;
143 | }
144 | }
145 | }
146 | Array.Resize(ref retBuffer, (int)outIdx);
147 | return retBuffer;
148 | }
149 |
150 | public static byte[] decode3(byte[] source)
151 | {
152 | byte[] retBuffer = new byte[256 * 256];
153 | int remaining = source.Length;
154 | uint inIdx = 0;
155 | uint outIdx = 0;
156 | UInt16 t0, t1, t3;
157 | uint t2Idx;
158 | while (remaining != 0) {
159 | t0 = BE.U16(source, inIdx);
160 | inIdx += 2;
161 | if ((0x8000 & t0) == 0) {
162 | t1 = (UInt16)(t0 >> 8);
163 | t1 <<= 1;
164 | retBuffer[outIdx] = (byte)t1; // sb
165 | t1 = (UInt16)(t0 & 0xFF);
166 | t1 <<= 1;
167 | retBuffer[outIdx + 1] = (byte)t1; // sb
168 | outIdx += 2;
169 | remaining -= 2;
170 | } else {
171 | t1 = (UInt16)(t0 & 0x1F);
172 | t0 &= 0x7FFF;
173 | t0 >>= 5;
174 | remaining -= 2;
175 | t2Idx = outIdx - t0;
176 | while (t1 != 0) {
177 | t3 = BE.U16(retBuffer, t2Idx);
178 | t2Idx += 2;
179 | t1 -= 1;
180 | BE.ToBytes(t3, retBuffer, (int)outIdx);
181 | outIdx += 2;
182 | }
183 | }
184 | }
185 | Array.Resize(ref retBuffer, (int)outIdx);
186 | return retBuffer;
187 | }
188 |
189 | public static byte[] decode4(byte[] source, byte[] lut)
190 | {
191 | byte[] retBuffer = new byte[256 * 256];
192 | int remaining = source.Length;
193 | uint inIdx = 0;
194 | int outIdx = 0;
195 | uint lutIdx;
196 | UInt32 t3;
197 | UInt16 t0, t1, t2;
198 | while (remaining != 0) {
199 | t0 = BE.U16(source, inIdx);
200 | inIdx += 2;
201 | if ((t0 & 0x8000) == 0) {
202 | t1 = (UInt16)(t0 >> 8);
203 | t2 = (UInt16)(t1 & 0xFE);
204 | t2 = BE.U16(lut, t2); // t2 += t4; // t4 set in proc_802A57DC: lw $t4, 0xc($a0)
205 | t1 &= 1;
206 | t2 <<= 1;
207 | t1 |= t2;
208 | BE.ToBytes(t1, retBuffer, outIdx);
209 | outIdx += 2;
210 | t1 = (UInt16)(t0 & 0xFE);
211 | t1 = BE.U16(lut, t1);
212 | t0 &= 1;
213 | remaining -= 2;
214 | t1 <<= 1;
215 | t1 |= t0;
216 | BE.ToBytes(t1, retBuffer, outIdx);
217 | outIdx += 2;
218 | } else {
219 | t1 = (UInt16)(t0 & 0x1F);
220 | t0 &= 0x7FE0;
221 | t0 >>= 4;
222 | remaining -= 2;
223 | lutIdx = (uint)(outIdx - t0);
224 | while (t1 != 0) {
225 | t3 = BE.U32(lut, lutIdx);
226 | lutIdx += 4;
227 | t1 -= 1;
228 | BE.ToBytes(t3, retBuffer, outIdx);
229 | outIdx += 4;
230 | }
231 | }
232 | }
233 | Array.Resize(ref retBuffer, outIdx);
234 | return retBuffer;
235 | }
236 |
237 | public static byte[] decode5(byte[] source, byte[] lut)
238 | {
239 | byte[] retBuffer = new byte[256 * 256];
240 | int remaining = source.Length;
241 | uint inIdx = 0;
242 | int outIdx = 0;
243 | int lutIdx;
244 | int t0, t1, t2, t3;
245 | while (remaining != 0) {
246 | t0 = BE.U16(source, inIdx);
247 | inIdx += 2;
248 | if ((t0 & 0x8000) == 0) { // bltz
249 | t1 = t0 >> 4;
250 | t1 = t1 << 1;
251 | lutIdx = t1; // t1 += t4
252 | t1 = BE.U16(lut, (uint)lutIdx);
253 | t0 &= 0xF;
254 | t0 <<= 4;
255 | t2 = t1 & 0x7C00;
256 | t3 = t1 & 0x03E0;
257 | t2 <<= 17; // 0x11
258 | t3 <<= 14; // 0xe
259 | t2 |= t3;
260 | t3 = t1 & 0x1F;
261 | t3 <<= 11; // 0xb
262 | t2 |= t3;
263 | t2 |= t0;
264 | BE.ToBytes((UInt32)t2, retBuffer, outIdx);
265 | outIdx += 4;
266 | remaining -= 2;
267 | } else {
268 | t1 = t0 & 0x1F;
269 | t0 &= 0x7FE0;
270 | t0 >>= 4;
271 | remaining -= 2;
272 | int tmpIdx = outIdx - t0; // t2
273 | while (t1 != 0) {
274 | UInt32 t3u32 = BE.U32(retBuffer, (uint)tmpIdx); //t2
275 | tmpIdx += 4; // t2
276 | t1 -= 1;
277 | BE.ToBytes(t3u32, retBuffer, outIdx);
278 | outIdx += 4;
279 | }
280 | }
281 | }
282 | Array.Resize(ref retBuffer, outIdx);
283 | return retBuffer;
284 | }
285 |
286 | public static byte[] decode6(byte[] source)
287 | {
288 | byte[] retBuffer = new byte[256 * 256];
289 | int remaining = source.Length;
290 | uint inIdx = 0;
291 | int outIdx = 0;
292 | UInt16 t0, t1;
293 | while (remaining != 0) {
294 | t0 = BE.U16(source, inIdx);
295 | inIdx += 2;
296 | if ((0x8000 & t0) == 0) {
297 | UInt16 t2;
298 | t1 = (UInt16)(t0 >> 8);
299 | t2 = (UInt16)(t1 & 0x38);
300 | t1 = (UInt16)(t1 & 0x07);
301 | t2 <<= 2;
302 | t1 <<= 1;
303 | t1 |= t2;
304 | retBuffer[outIdx] = (byte)t1; // sb
305 | t1 = (UInt16)(t0 & 0xFF);
306 | t2 = (UInt16)(t1 & 0x38);
307 | t1 = (UInt16)(t1 & 0x07);
308 | t2 <<= 2;
309 | t1 <<= 1;
310 | t1 |= t2;
311 | retBuffer[outIdx + 1] = (byte)t1;
312 | outIdx += 2;
313 | remaining -= 2;
314 | } else {
315 | uint t2;
316 | t1 = (UInt16)(t0 & 0x1F);
317 | t0 = (UInt16)(t0 & 0x7FFF);
318 | t0 >>= 5;
319 | remaining -= 2;
320 | t2 = (uint)(outIdx - t0);
321 | while (t1 != 0) {
322 | UInt16 t3u16 = BE.U16(retBuffer, t2);
323 | t2 += 2;
324 | t1 -= 1;
325 | BE.ToBytes(t3u16, retBuffer, outIdx);
326 | outIdx += 2;
327 | }
328 | }
329 | }
330 | Array.Resize(ref retBuffer, outIdx);
331 | return retBuffer;
332 | }
333 | }
334 | }
335 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/BlastCorpsViewer.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BlastCorpsEditor
2 | {
3 | partial class BlastCorpsViewer
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Component Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.SuspendLayout();
32 | //
33 | // BlastCorpsViewer
34 | //
35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
37 | this.Name = "BlastCorpsViewer";
38 | this.Paint += new System.Windows.Forms.PaintEventHandler(this.BlastCorpsViewer_Paint);
39 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.BlastCorpsViewer_KeyDown);
40 | this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.BlastCorpsViewer_MouseDown);
41 | this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.BlastCorpsViewer_MouseMove);
42 | this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.BlastCorpsViewer_MouseUp);
43 | this.Resize += new System.EventHandler(this.BlastCorpsViewer_Resize);
44 | this.ResumeLayout(false);
45 |
46 | }
47 |
48 | #endregion
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/BlastCorpsViewer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 | using System.Drawing.Drawing2D;
5 | using System.IO;
6 |
7 | namespace BlastCorpsEditor
8 | {
9 | public partial class BlastCorpsViewer : UserControl
10 | {
11 | private BlastCorpsLevel level;
12 | private float zoom = 1;
13 | private int offX, offY;
14 |
15 | // cursors
16 | private Cursor cursorPlus;
17 | private Cursor cursorMove;
18 |
19 | private MouseMode mouseMode;
20 |
21 | // item selected either in list or by clicking
22 | private BlastCorpsItem selectedItem = null;
23 | // click and drag related
24 | private BlastCorpsItem dragItem = null;
25 |
26 | public MouseMode Mode
27 | {
28 | get
29 | {
30 | return mouseMode;
31 | }
32 | set
33 | {
34 | mouseMode = value;
35 | switch (mouseMode)
36 | {
37 | case MouseMode.Move: this.Cursor = cursorMove; break;
38 | case MouseMode.Add: this.Cursor = cursorPlus; break;
39 | default: this.Cursor = Cursors.Default; break;
40 | }
41 | }
42 | }
43 |
44 | public Type AddType { get; set; }
45 |
46 | public BlastCorpsViewer()
47 | {
48 | InitializeComponent();
49 | DoubleBuffered = true;
50 | ResizeRedraw = true;
51 |
52 | // create cursors
53 | cursorPlus = new Cursor(new MemoryStream(BlastCorpsEditor.Properties.Resources.cursor_plus));
54 | cursorMove = new Cursor(new MemoryStream(BlastCorpsEditor.Properties.Resources.cursor_move));
55 | }
56 |
57 | // selected item changed event
58 | public event SelectionChangedEventHandler SelectionChangedEvent;
59 | protected virtual void OnSelectionChangedEvent(SelectionChangedEventArgs e)
60 | {
61 | SelectionChangedEvent(this, e);
62 | }
63 |
64 | // item moved
65 | public event ItemMovedEventHandler ItemMovedEvent;
66 | protected virtual void OnItemMovedEvent(ItemMovedEventArgs e)
67 | {
68 | ItemMovedEvent(this, e);
69 | }
70 |
71 | // mouse position change event
72 | public event PositionEventHandler PositionEvent;
73 | protected virtual void OnPositionEvent(PositionEventArgs e)
74 | {
75 | PositionEvent(this, e);
76 | }
77 |
78 | public BlastCorpsItem SelectedItem
79 | {
80 | get { return selectedItem; }
81 | set { selectedItem = value; Invalidate(); }
82 | }
83 |
84 | public void SetLevel(BlastCorpsLevel level)
85 | {
86 | this.level = level;
87 | computeBounds();
88 | Invalidate();
89 | }
90 |
91 | private void computeBounds()
92 | {
93 | // pick higher level/screen ratio
94 | float ratX = (float)(level.bounds.x2 - level.bounds.x1) / (float)Width;
95 | float ratY = (float)(level.bounds.z2 - level.bounds.z1) / (float)Height;
96 | if (ratX > ratY)
97 | {
98 | zoom = ratX;
99 | offX = 0;
100 | offY = (Height - (int)((level.bounds.z2 - level.bounds.z1) / zoom)) / 2;
101 | }
102 | else
103 | {
104 | zoom = ratY;
105 | offX = (Width - (int)((level.bounds.x2 - level.bounds.x1) / zoom)) / 2;
106 | offY = 0;
107 | }
108 | }
109 |
110 | private int pixelX(int levelX)
111 | {
112 | return (int)(Width - (levelX - level.bounds.x1) / zoom) - offX;
113 | }
114 |
115 | private int pixelY(int levelZ)
116 | {
117 | return (int)(Height - (levelZ - level.bounds.z1) / zoom) - offY;
118 | }
119 |
120 | private int levelX(int pixelX)
121 | {
122 | // pixelX = (Width - (levelX - level.bounds.x1) / zoom) - offX;
123 | return (int)((Width - pixelX - offX) * zoom) + level.bounds.x1;
124 | }
125 |
126 | private int levelZ(int pixelY)
127 | {
128 | // pixelY = (Height - (levelZ - level.bounds.z1) / zoom) - offY;
129 | return (int)((Height - pixelY - offY) * zoom) + level.bounds.z1;
130 | }
131 |
132 | private BlastCorpsItem FindNearbyItem(int pixelX, int pixelY)
133 | {
134 | BlastCorpsItem itemFound = null;
135 | if (level != null)
136 | {
137 | // find something to select
138 | int x = levelX(pixelX);
139 | int z = levelZ(pixelY);
140 | int diff = levelX(0) - levelX(4);
141 |
142 | foreach (AmmoBox ammo in level.ammoBoxes)
143 | {
144 | if (Math.Abs(x - ammo.x) < diff && Math.Abs(z - ammo.z) < diff)
145 | {
146 | itemFound = ammo;
147 | break;
148 | }
149 | }
150 |
151 | foreach (CommPoint comm in level.commPoints)
152 | {
153 | if (Math.Abs(x - comm.x) < diff && Math.Abs(z - comm.z) < diff)
154 | {
155 | itemFound = comm;
156 | break;
157 | }
158 | }
159 |
160 | foreach (RDU rdu in level.rdus)
161 | {
162 | if (Math.Abs(x - rdu.x) < diff && Math.Abs(z - rdu.z) < diff)
163 | {
164 | itemFound = rdu;
165 | break;
166 | }
167 | }
168 |
169 | foreach (TNTCrate tnt in level.tntCrates)
170 | {
171 | if (Math.Abs(x - tnt.x) < diff && Math.Abs(z - tnt.z) < diff)
172 | {
173 | itemFound = tnt;
174 | break;
175 | }
176 | }
177 |
178 | foreach (SquareBlock block in level.squareBlocks)
179 | {
180 | if (Math.Abs(x - block.x) < diff && Math.Abs(z - block.z) < diff)
181 | {
182 | itemFound = block;
183 | break;
184 | }
185 | }
186 |
187 | foreach (Vehicle veh in level.vehicles)
188 | {
189 | if (Math.Abs(x - veh.x) < diff && Math.Abs(z - veh.z) < diff)
190 | {
191 | itemFound = veh;
192 | break;
193 | }
194 | }
195 |
196 | if (Math.Abs(x - level.carrier.x) < diff && Math.Abs(z - level.carrier.z) < diff)
197 | {
198 | itemFound = level.carrier;
199 | }
200 |
201 | foreach (Building b in level.buildings)
202 | {
203 | if (Math.Abs(x - b.x) < diff && Math.Abs(z - b.z) < diff)
204 | {
205 | itemFound = b;
206 | break;
207 | }
208 | }
209 | }
210 | return itemFound;
211 | }
212 |
213 | private void BlastCorpsViewer_Paint(object sender, PaintEventArgs e)
214 | {
215 | Brush ammoBrush = new SolidBrush(Color.LightBlue);
216 | Brush commBrush = new SolidBrush(Color.Orange);
217 | Brush rduBrush = new SolidBrush(Color.Goldenrod);
218 | Brush tntBrush = new SolidBrush(Color.Black);
219 | Brush blockBrush = new SolidBrush(Color.DarkGray);
220 | Brush bounds40Brush = new HatchBrush(HatchStyle.DiagonalCross, Color.Green, Color.Transparent);
221 | Brush bounds44Brush = new HatchBrush(HatchStyle.DiagonalCross, Color.Aqua, Color.Transparent);
222 | Pen blockPen = new Pen(Color.DarkGray);
223 | Pen buildingPen = new Pen(Color.Brown, 2);
224 | Pen vehPen = new Pen(Color.Blue);
225 | vehPen.StartCap = LineCap.SquareAnchor;
226 | vehPen.EndCap = LineCap.ArrowAnchor;
227 | Pen playerPen = new Pen(Color.Green, 3);
228 | playerPen.StartCap = LineCap.SquareAnchor;
229 | playerPen.EndCap = LineCap.ArrowAnchor;
230 | Pen carrierPen = new Pen(Color.Red, 3);
231 | carrierPen.DashStyle = DashStyle.DashDot;
232 | carrierPen.StartCap = LineCap.SquareAnchor;
233 | carrierPen.EndCap = LineCap.ArrowAnchor;
234 | Pen zonePen = new Pen(Color.Plum);
235 | Pen stoppingPen = new Pen(Color.SaddleBrown, 2);
236 | Pen platformPen = new Pen(Color.DarkKhaki, 2);
237 | Pen blackPen = new Pen(Color.Black);
238 | Pen selectedPen = new Pen(Color.Magenta, 2);
239 | selectedPen.EndCap = LineCap.ArrowAnchor;
240 | double angle;
241 | int x, y, dx, dy;
242 | Point[] triPoints = new Point[4];
243 | if (level != null)
244 | {
245 | e.Graphics.FillRectangle(new SolidBrush(Color.White), offX, offY, Width - 2*offX, Height - 2*offY);
246 | if (Properties.Settings.Default.ViewGridLines)
247 | {
248 | // every 500 level units
249 | Pen linePen = new Pen(Color.Black);
250 | linePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
251 | const int every = 500;
252 | int start = ((level.bounds.x1 + every - 1) / every) * every;
253 | int end = ((level.bounds.x2 + every - 1) / every) * every;
254 | for (x = start; x < end; x += every)
255 | {
256 | int px = pixelX(x);
257 | e.Graphics.DrawLine(linePen, px, offY, px, Height-offY);
258 | }
259 | start = ((level.bounds.z1 + every - 1) / every) * every;
260 | end = ((level.bounds.z2 + every - 1) / every) * every;
261 | for (y = start; y < end; y += every)
262 | {
263 | int py = pixelY(y);
264 | e.Graphics.DrawLine(linePen, offX, py, Width-offX, py);
265 | }
266 | }
267 | if (Properties.Settings.Default.ViewBoxes40)
268 | {
269 | foreach (Bounds bounds in level.bounds40)
270 | {
271 | if (bounds.todo > 0x00A9)
272 | {
273 | int x1 = pixelX(bounds.x1);
274 | int y1 = pixelY(bounds.z1);
275 | int x2 = pixelX(bounds.x2);
276 | int y2 = pixelY(bounds.z2);
277 | e.Graphics.FillRectangle(bounds40Brush, x2, y2, x1 - x2, y1 - y2);
278 | e.Graphics.DrawRectangle(blackPen, x2, y2, x1 - x2, y1 - y2);
279 | }
280 | }
281 | }
282 | if (Properties.Settings.Default.ViewBoxes44)
283 | {
284 | foreach (Bounds bounds in level.bounds44)
285 | {
286 | int x1 = pixelX(bounds.x1);
287 | int y1 = pixelY(bounds.z1);
288 | int x2 = pixelX(bounds.x2);
289 | int y2 = pixelY(bounds.z2);
290 | e.Graphics.FillRectangle(bounds44Brush, x2, y2, x1 - x2, y1 - y2);
291 | e.Graphics.DrawRectangle(blackPen, x2, y2, x1 - x2, y1 - y2);
292 | }
293 | }
294 |
295 | foreach (Object60 obj in level.object60s)
296 | {
297 | e.Graphics.FillRectangle(Brushes.SeaGreen, pixelX(obj.x) - 2, pixelY(obj.z) - 2, 3, 3);
298 | }
299 |
300 | foreach (WallGroup group in level.wallGroups)
301 | {
302 | foreach (Wall wall in group.walls)
303 | {
304 | triPoints[0].X = pixelX(wall.x1);
305 | triPoints[0].Y = pixelY(wall.z1);
306 | triPoints[1].X = pixelX(wall.x2);
307 | triPoints[1].Y = pixelY(wall.z2);
308 | triPoints[2].X = pixelX(wall.x3);
309 | triPoints[2].Y = pixelY(wall.z3);
310 | triPoints[3].X = pixelX(wall.x1);
311 | triPoints[3].Y = pixelY(wall.z1);
312 | e.Graphics.DrawLines(Pens.Gray, triPoints);
313 | }
314 | }
315 |
316 | // missile carrier
317 | x = pixelX(level.carrier.x);
318 | y = pixelY(level.carrier.z);
319 | angle = Math.PI * level.carrier.heading / 2048.0;
320 | // sin/cos swapped so N = 0, W = 1024
321 | int length = pixelY(0) - pixelY(level.carrier.distance);
322 | dx = (int)(length * Math.Sin(angle));
323 | dy = (int)(length * Math.Cos(angle));
324 | e.Graphics.DrawLine(carrierPen, x, y, x - dx, y - dy);
325 |
326 | foreach (AmmoBox ammo in level.ammoBoxes)
327 | {
328 | e.Graphics.FillRectangle(ammoBrush, pixelX(ammo.x) - 4, pixelY(ammo.z) - 4, 7, 7);
329 | }
330 |
331 | foreach (Collision24 zone in level.collision24)
332 | {
333 | triPoints[0].X = pixelX(zone.x1);
334 | triPoints[0].Y = pixelY(zone.z1);
335 | triPoints[1].X = pixelX(zone.x2);
336 | triPoints[1].Y = pixelY(zone.z2);
337 | triPoints[2].X = pixelX(zone.x3);
338 | triPoints[2].Y = pixelY(zone.z3);
339 | triPoints[3].X = pixelX(zone.x1);
340 | triPoints[3].Y = pixelY(zone.z1);
341 | e.Graphics.DrawLines(zonePen, triPoints);
342 | }
343 | foreach (TrainPlatform platform in level.trainPlatforms)
344 | {
345 | foreach (TrainPlatform.StoppingTriangle zone in platform.stoppingZone)
346 | {
347 | triPoints[0].X = pixelX(zone.x1);
348 | triPoints[0].Y = pixelY(zone.z1);
349 | triPoints[1].X = pixelX(zone.x2);
350 | triPoints[1].Y = pixelY(zone.z2);
351 | triPoints[2].X = pixelX(zone.x3);
352 | triPoints[2].Y = pixelY(zone.z3);
353 | triPoints[3].X = pixelX(zone.x1);
354 | triPoints[3].Y = pixelY(zone.z1);
355 | e.Graphics.DrawLines(stoppingPen, triPoints);
356 | }
357 | foreach (TrainPlatform.PlatformCollision collision in platform.collision)
358 | {
359 | triPoints[0].X = pixelX(collision.x1);
360 | triPoints[0].Y = pixelY(collision.z1);
361 | triPoints[1].X = pixelX(collision.x2);
362 | triPoints[1].Y = pixelY(collision.z2);
363 | triPoints[2].X = pixelX(collision.x3);
364 | triPoints[2].Y = pixelY(collision.z3);
365 | triPoints[3].X = pixelX(collision.x1);
366 | triPoints[3].Y = pixelY(collision.z1);
367 | e.Graphics.DrawLines(platformPen, triPoints);
368 | }
369 | }
370 | foreach (CommPoint comm in level.commPoints)
371 | {
372 | e.Graphics.FillRectangle(commBrush, pixelX(comm.x) - 5, pixelY(comm.z) - 5, 9, 9);
373 | }
374 | foreach (RDU rdu in level.rdus)
375 | {
376 | e.Graphics.FillEllipse(rduBrush, pixelX(rdu.x)-4, pixelY(rdu.z)-4, 7, 7);
377 | }
378 | foreach (TNTCrate tnt in level.tntCrates)
379 | {
380 | e.Graphics.FillRectangle(tntBrush, pixelX(tnt.x)-4, pixelY(tnt.z)-4, 7, 7);
381 | }
382 | foreach (SquareBlock block in level.squareBlocks)
383 | {
384 | if (block.shape == SquareBlock.Shape.Diamond1 || block.shape == SquareBlock.Shape.Diamond2)
385 | {
386 | e.Graphics.RotateTransform(45);
387 | e.Graphics.TranslateTransform(pixelX(block.x), pixelY(block.z)-6, MatrixOrder.Append);
388 | }
389 | else
390 | {
391 | e.Graphics.TranslateTransform(pixelX(block.x)-4, pixelY(block.z)-4, MatrixOrder.Append);
392 | }
393 | if (block.type == SquareBlock.Type.Hole)
394 | {
395 | e.Graphics.DrawRectangle(blockPen, 0, 0, 9, 9);
396 | }
397 | else
398 | {
399 | e.Graphics.FillRectangle(blockBrush, 0, 0, 7, 7);
400 | }
401 | e.Graphics.ResetTransform();
402 | }
403 | foreach (Vehicle veh in level.vehicles)
404 | {
405 | x = pixelX(veh.x);
406 | y = pixelY(veh.z);
407 | angle = Math.PI * veh.heading / 2048.0;
408 | // sin/cos swapped so N = 0, W = 1024
409 | dx = (int)(12 * Math.Sin(angle));
410 | dy = (int)(12 * Math.Cos(angle));
411 | if (veh.type == 0x00)
412 | {
413 | e.Graphics.DrawLine(playerPen, x, y, x - dx, y - dy);
414 | }
415 | else
416 | {
417 | e.Graphics.DrawLine(vehPen, x, y, x - dx, y - dy);
418 | }
419 | }
420 | foreach (Building b in level.buildings)
421 | {
422 | e.Graphics.DrawRectangle(buildingPen, pixelX(b.x) - 5, pixelY(b.z) - 5, 9, 9);
423 | }
424 |
425 | if (selectedItem != null)
426 | {
427 | x = pixelX(selectedItem.x);
428 | y = pixelY(selectedItem.z);
429 | const int selOuter = 10;
430 | const int selInner = 4;
431 | e.Graphics.DrawLine(selectedPen, x - selOuter, y - selOuter, x - selInner, y - selInner);
432 | e.Graphics.DrawLine(selectedPen, x + selOuter - 1, y - selOuter, x + selInner - 1, y - selInner);
433 | e.Graphics.DrawLine(selectedPen, x + selOuter - 1, y + selOuter - 1, x + selInner - 1, y + selInner - 1);
434 | e.Graphics.DrawLine(selectedPen, x - selOuter, y + selOuter - 1, x - selInner, y + selInner - 1);
435 | }
436 | }
437 | e.Graphics.DrawRectangle(blackPen, 0, 0, Width - 1, Height - 1);
438 | }
439 |
440 | private void BlastCorpsViewer_Resize(object sender, EventArgs e)
441 | {
442 | if (level != null)
443 | {
444 | computeBounds();
445 | }
446 | }
447 |
448 | private void BlastCorpsViewer_MouseMove(object sender, MouseEventArgs e)
449 | {
450 | if (level != null)
451 | {
452 | Int16 x = (Int16)levelX(e.X);
453 | Int16 z = (Int16)levelZ(e.Y);
454 | string text = x + "," + z + " ( " + x.ToString("X4") + "," + z.ToString("X4") + " )";
455 | OnPositionEvent(new PositionEventArgs(text));
456 | switch (Mode)
457 | {
458 | case MouseMode.Move:
459 | if (dragItem != null)
460 | {
461 | dragItem.x = x;
462 | dragItem.z = z;
463 | OnItemMovedEvent(new ItemMovedEventArgs(dragItem));
464 | Invalidate();
465 | }
466 | break;
467 | case MouseMode.Add:
468 | break;
469 | }
470 | }
471 | }
472 |
473 | private void BlastCorpsViewer_MouseDown(object sender, MouseEventArgs e)
474 | {
475 | if (e.Button == System.Windows.Forms.MouseButtons.Left)
476 | {
477 | switch (Mode)
478 | {
479 | case MouseMode.Select:
480 | BlastCorpsItem item = FindNearbyItem(e.X, e.Y);
481 | if (item != selectedItem)
482 | {
483 | selectedItem = item;
484 | OnSelectionChangedEvent(new SelectionChangedEventArgs(selectedItem, false, false));
485 | Invalidate();
486 | }
487 | break;
488 | case MouseMode.Move:
489 | dragItem = FindNearbyItem(e.X, e.Y);
490 | if (dragItem != selectedItem)
491 | {
492 | selectedItem = dragItem;
493 | OnSelectionChangedEvent(new SelectionChangedEventArgs(selectedItem, false, false));
494 | Invalidate();
495 | }
496 | break;
497 | case MouseMode.Add:
498 | break;
499 | }
500 | }
501 | }
502 |
503 | private void BlastCorpsViewer_MouseUp(object sender, MouseEventArgs e)
504 | {
505 | if (level != null && e.Button == System.Windows.Forms.MouseButtons.Left)
506 | {
507 | switch (Mode)
508 | {
509 | case MouseMode.Move:
510 | if (dragItem != null)
511 | {
512 | selectedItem = dragItem;
513 | OnSelectionChangedEvent(new SelectionChangedEventArgs(selectedItem, false, false));
514 | dragItem = null;
515 | Invalidate();
516 | }
517 | break;
518 | case MouseMode.Add:
519 | Int16 x = (Int16)levelX(e.X);
520 | Int16 z = (Int16)levelZ(e.Y);
521 | if (AddType == typeof(AmmoBox))
522 | {
523 | AmmoBox box = new AmmoBox(x, level.carrier.y, z, 0);
524 | selectedItem = box;
525 | level.ammoBoxes.Add(box);
526 | }
527 | else if (AddType == typeof(CommPoint))
528 | {
529 | CommPoint comm = new CommPoint(x, level.carrier.y, z, 0);
530 | selectedItem = comm;
531 | level.commPoints.Add(comm);
532 | }
533 | else if (AddType == typeof(RDU))
534 | {
535 | RDU rdu = new RDU(x, level.carrier.y, z);
536 | selectedItem = rdu;
537 | level.rdus.Add(rdu);
538 | }
539 | else if (AddType == typeof(TNTCrate))
540 | {
541 | TNTCrate tnt = new TNTCrate(x, level.carrier.y, z, 0, 0, 0, 0);
542 | selectedItem = tnt;
543 | level.tntCrates.Add(tnt);
544 | }
545 | else if (AddType == typeof(SquareBlock))
546 | {
547 | SquareBlock block = new SquareBlock(x, level.carrier.y, z, SquareBlock.Type.Block, SquareBlock.Shape.Square);
548 | selectedItem = block;
549 | level.squareBlocks.Add(block);
550 | }
551 | else if (AddType == typeof(Vehicle))
552 | {
553 | Vehicle vehicle = new Vehicle(0, x, level.carrier.y, z, 0);
554 | selectedItem = vehicle;
555 | level.vehicles.Add(vehicle);
556 | }
557 | else if (AddType == typeof(Building))
558 | {
559 | Building building = new Building(x, level.carrier.y, z, 0, 0, 0, 0, 0);
560 | selectedItem = building;
561 | level.buildings.Add(building);
562 | }
563 | OnSelectionChangedEvent(new SelectionChangedEventArgs(selectedItem, true, false));
564 | Invalidate();
565 | break;
566 | }
567 | }
568 | }
569 |
570 | private void BlastCorpsViewer_KeyDown(object sender, KeyEventArgs e)
571 | {
572 | if (selectedItem != null)
573 | {
574 | if (e.KeyCode == Keys.Delete)
575 | {
576 | OnSelectionChangedEvent(new SelectionChangedEventArgs(selectedItem, false, true));
577 | selectedItem = null;
578 | Invalidate();
579 | }
580 | }
581 | }
582 | }
583 |
584 | // Event Handlers
585 | public delegate void SelectionChangedEventHandler(object sender, SelectionChangedEventArgs e);
586 | public class SelectionChangedEventArgs : EventArgs
587 | {
588 | public BlastCorpsItem SelectedItem { get; set; }
589 | public bool IsAdded { get; set; }
590 | public bool IsDeleted { get; set; }
591 | public SelectionChangedEventArgs(BlastCorpsItem item, bool added, bool deleted)
592 | {
593 | this.SelectedItem = item;
594 | this.IsAdded = added;
595 | this.IsDeleted = deleted;
596 | }
597 | }
598 |
599 | public delegate void ItemMovedEventHandler(object sender, ItemMovedEventArgs e);
600 | public class ItemMovedEventArgs : EventArgs
601 | {
602 | public BlastCorpsItem SelectedItem { get; set; }
603 | public ItemMovedEventArgs(BlastCorpsItem item)
604 | {
605 | this.SelectedItem = item;
606 | }
607 | }
608 |
609 | public delegate void PositionEventHandler(object sender, PositionEventArgs e);
610 | public class PositionEventArgs : EventArgs
611 | {
612 | public string Position { get; set; }
613 | public PositionEventArgs(string position)
614 | {
615 | this.Position = position;
616 | }
617 | }
618 |
619 | public enum MouseMode { Select, Move, Add };
620 | }
621 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/BlastCorpsViewer.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/ExportDialog.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BlastCorpsEditor
2 | {
3 | partial class ExportDialog
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.label1 = new System.Windows.Forms.Label();
32 | this.comboBoxExport = new System.Windows.Forms.ComboBox();
33 | this.label2 = new System.Windows.Forms.Label();
34 | this.textBoxFilename = new System.Windows.Forms.TextBox();
35 | this.label3 = new System.Windows.Forms.Label();
36 | this.buttonChoose = new System.Windows.Forms.Button();
37 | this.numericScale = new System.Windows.Forms.NumericUpDown();
38 | this.buttonExport = new System.Windows.Forms.Button();
39 | this.buttonCancel = new System.Windows.Forms.Button();
40 | ((System.ComponentModel.ISupportInitialize)(this.numericScale)).BeginInit();
41 | this.SuspendLayout();
42 | //
43 | // label1
44 | //
45 | this.label1.AutoSize = true;
46 | this.label1.Location = new System.Drawing.Point(12, 70);
47 | this.label1.Name = "label1";
48 | this.label1.Size = new System.Drawing.Size(70, 13);
49 | this.label1.TabIndex = 0;
50 | this.label1.Text = "Data Source:";
51 | //
52 | // comboBoxExport
53 | //
54 | this.comboBoxExport.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
55 | this.comboBoxExport.FormattingEnabled = true;
56 | this.comboBoxExport.Items.AddRange(new object[] {
57 | "All",
58 | "Display List",
59 | "0x30: Terrain",
60 | "0x24: Y Collision",
61 | "0x60: Object 60?",
62 | "0x64: Walls",
63 | "0x6C: X/Z Collision",
64 | "0x70: Player Collision"});
65 | this.comboBoxExport.Location = new System.Drawing.Point(88, 67);
66 | this.comboBoxExport.Name = "comboBoxExport";
67 | this.comboBoxExport.Size = new System.Drawing.Size(135, 21);
68 | this.comboBoxExport.TabIndex = 1;
69 | this.comboBoxExport.SelectedIndexChanged += new System.EventHandler(this.comboBoxExport_SelectedIndexChanged);
70 | //
71 | // label2
72 | //
73 | this.label2.AutoSize = true;
74 | this.label2.Location = new System.Drawing.Point(12, 15);
75 | this.label2.Name = "label2";
76 | this.label2.Size = new System.Drawing.Size(56, 13);
77 | this.label2.TabIndex = 2;
78 | this.label2.Text = "Export To:";
79 | //
80 | // textBoxFilename
81 | //
82 | this.textBoxFilename.Location = new System.Drawing.Point(88, 12);
83 | this.textBoxFilename.Name = "textBoxFilename";
84 | this.textBoxFilename.ReadOnly = true;
85 | this.textBoxFilename.Size = new System.Drawing.Size(384, 20);
86 | this.textBoxFilename.TabIndex = 3;
87 | //
88 | // label3
89 | //
90 | this.label3.AutoSize = true;
91 | this.label3.Location = new System.Drawing.Point(12, 96);
92 | this.label3.Name = "label3";
93 | this.label3.Size = new System.Drawing.Size(52, 13);
94 | this.label3.TabIndex = 4;
95 | this.label3.Text = "Scale By:";
96 | //
97 | // buttonChoose
98 | //
99 | this.buttonChoose.Location = new System.Drawing.Point(88, 38);
100 | this.buttonChoose.Name = "buttonChoose";
101 | this.buttonChoose.Size = new System.Drawing.Size(75, 23);
102 | this.buttonChoose.TabIndex = 6;
103 | this.buttonChoose.Text = "Choose...";
104 | this.buttonChoose.UseVisualStyleBackColor = true;
105 | this.buttonChoose.Click += new System.EventHandler(this.buttonChoose_Click);
106 | //
107 | // numericScale
108 | //
109 | this.numericScale.DecimalPlaces = 1;
110 | this.numericScale.Location = new System.Drawing.Point(88, 94);
111 | this.numericScale.Maximum = new decimal(new int[] {
112 | 4096,
113 | 0,
114 | 0,
115 | 0});
116 | this.numericScale.Minimum = new decimal(new int[] {
117 | 1,
118 | 0,
119 | 0,
120 | 0});
121 | this.numericScale.Name = "numericScale";
122 | this.numericScale.Size = new System.Drawing.Size(135, 20);
123 | this.numericScale.TabIndex = 7;
124 | this.numericScale.Value = new decimal(new int[] {
125 | 1024,
126 | 0,
127 | 0,
128 | 0});
129 | //
130 | // buttonExport
131 | //
132 | this.buttonExport.DialogResult = System.Windows.Forms.DialogResult.OK;
133 | this.buttonExport.Enabled = false;
134 | this.buttonExport.Location = new System.Drawing.Point(397, 67);
135 | this.buttonExport.Name = "buttonExport";
136 | this.buttonExport.Size = new System.Drawing.Size(75, 23);
137 | this.buttonExport.TabIndex = 8;
138 | this.buttonExport.Text = "Export";
139 | this.buttonExport.UseVisualStyleBackColor = true;
140 | //
141 | // buttonCancel
142 | //
143 | this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
144 | this.buttonCancel.Location = new System.Drawing.Point(397, 96);
145 | this.buttonCancel.Name = "buttonCancel";
146 | this.buttonCancel.Size = new System.Drawing.Size(75, 23);
147 | this.buttonCancel.TabIndex = 9;
148 | this.buttonCancel.Text = "Cancel";
149 | this.buttonCancel.UseVisualStyleBackColor = true;
150 | //
151 | // ExportDialog
152 | //
153 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
154 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
155 | this.ClientSize = new System.Drawing.Size(484, 134);
156 | this.Controls.Add(this.buttonCancel);
157 | this.Controls.Add(this.buttonExport);
158 | this.Controls.Add(this.numericScale);
159 | this.Controls.Add(this.buttonChoose);
160 | this.Controls.Add(this.label3);
161 | this.Controls.Add(this.textBoxFilename);
162 | this.Controls.Add(this.label2);
163 | this.Controls.Add(this.comboBoxExport);
164 | this.Controls.Add(this.label1);
165 | this.MaximizeBox = false;
166 | this.MinimizeBox = false;
167 | this.Name = "ExportDialog";
168 | this.ShowIcon = false;
169 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
170 | this.Text = "Export Model...";
171 | this.TopMost = true;
172 | ((System.ComponentModel.ISupportInitialize)(this.numericScale)).EndInit();
173 | this.ResumeLayout(false);
174 | this.PerformLayout();
175 |
176 | }
177 |
178 | #endregion
179 |
180 | private System.Windows.Forms.Label label1;
181 | private System.Windows.Forms.ComboBox comboBoxExport;
182 | private System.Windows.Forms.Label label2;
183 | private System.Windows.Forms.TextBox textBoxFilename;
184 | private System.Windows.Forms.Label label3;
185 | private System.Windows.Forms.Button buttonChoose;
186 | private System.Windows.Forms.NumericUpDown numericScale;
187 | private System.Windows.Forms.Button buttonExport;
188 | private System.Windows.Forms.Button buttonCancel;
189 | }
190 | }
--------------------------------------------------------------------------------
/BlastCorpsEditor/ExportDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace BlastCorpsEditor
12 | {
13 | public enum ExportType { All, Terrain30, Collision24, Object60, Walls64, Collision6C, Collision70, DisplayList };
14 |
15 | public partial class ExportDialog : Form
16 | {
17 | public string FileName { get; internal set; }
18 | public float ScaleFactor { get; set; }
19 | public ExportType DataType { get; internal set; }
20 |
21 | public ExportDialog()
22 | {
23 | InitializeComponent();
24 | comboBoxExport.SelectedIndex = 0;
25 | DataBindings.Add("ScaleFactor", numericScale, "Value");
26 | }
27 |
28 | private void buttonChoose_Click(object sender, EventArgs e)
29 | {
30 | SaveFileDialog saveFileDialog = new SaveFileDialog();
31 | saveFileDialog.Filter = "Wavefront OBJ(*.obj)|*.obj";
32 | saveFileDialog.Title = "Export Blast Corps Level Terrain";
33 | saveFileDialog.ShowDialog();
34 |
35 | if (saveFileDialog.FileName != "")
36 | {
37 | FileName = saveFileDialog.FileName;
38 | textBoxFilename.Text = FileName;
39 | buttonExport.Enabled = true;
40 | }
41 | }
42 |
43 | private void comboBoxExport_SelectedIndexChanged(object sender, EventArgs e)
44 | {
45 | // TODO: avoid dual maintenance
46 | switch (comboBoxExport.SelectedIndex)
47 | {
48 | case 0: DataType = ExportType.All; break;
49 | case 1: DataType = ExportType.DisplayList; break;
50 | case 2: DataType = ExportType.Terrain30; break;
51 | case 3: DataType = ExportType.Collision24; break;
52 | case 4: DataType = ExportType.Object60; break;
53 | case 5: DataType = ExportType.Walls64; break;
54 | case 6: DataType = ExportType.Collision6C; break;
55 | case 7: DataType = ExportType.Collision70; break;
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/ExportDialog.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Model3D.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BlastCorpsEditor
8 | {
9 | public class Vertex
10 | {
11 | public enum Type { RGB, XYZ }
12 | public int x, y, z;
13 | public int u, v;
14 | public byte[] normals = new byte[3];
15 | public Type type;
16 | byte a;
17 | public Vertex(byte[] data, uint offset)
18 | {
19 | x = BE.I16(data, offset);
20 | y = BE.I16(data, offset + 0x2);
21 | z = BE.I16(data, offset + 0x4);
22 | // skip 6-7
23 | u = BE.I16(data, offset + 0x8);
24 | v = BE.I16(data, offset + 0xA);
25 | normals[0] = data[offset + 0xC];
26 | normals[1] = data[offset + 0xD];
27 | normals[2] = data[offset + 0xE];
28 | a = data[offset + 0xF];
29 | }
30 | }
31 |
32 | public class Triangle
33 | {
34 | public Vertex[] vertices = new Vertex[3];
35 | public Texture texture;
36 | public Triangle()
37 | {
38 |
39 | }
40 | public Triangle(Vertex v0, Vertex v1, Vertex v2)
41 | {
42 | vertices[0] = v0;
43 | vertices[1] = v1;
44 | vertices[2] = v2;
45 | }
46 | }
47 |
48 | public class Texture
49 | {
50 | public UInt32 address;
51 | public int width;
52 | public int height;
53 | public Texture()
54 | {
55 | address = 0xFFFFFFFF;
56 | width = -1;
57 | height = -1;
58 | }
59 | public bool IsComplete()
60 | {
61 | return (width != -1 && height != -1 && address != 0xFFFFFFFF);
62 | }
63 | }
64 |
65 | class Model3D
66 | {
67 | const byte F3D_MOVEMEM = 0x03;
68 | const byte F3D_VTX = 0x04;
69 | const byte F3D_DL = 0x06;
70 | const byte F3D_QUAD = 0xB5;
71 | const byte F3D_CLRGEOMODE = 0xB6;
72 | const byte F3D_SETGEOMODE = 0xB7;
73 | const byte F3D_ENDDL = 0xB8;
74 | const byte F3D_TEXTURE = 0xBB;
75 | const byte F3D_TRI1 = 0xBF;
76 | const byte G_SETTILESIZE = 0xF2;
77 | const byte G_LOADBLOCK = 0xF3;
78 | const byte G_SETTILE = 0xF5;
79 | const byte G_SETFOGCOLOR = 0xF8;
80 | const byte G_SETENVCOLOR = 0xFB;
81 | const byte G_SETCOMBINE = 0xFC;
82 | const byte G_SETTIMG = 0xFD;
83 |
84 | public List textures = new List();
85 | public List triangles = new List();
86 |
87 | public Model3D(BlastCorpsLevel level)
88 | {
89 | parseModel(level);
90 | }
91 |
92 | public void parseModel(BlastCorpsLevel level)
93 | {
94 | byte[] displayList = level.displayList;
95 | Vertex[] vertexBuffer = new Vertex[16];
96 | Stack dlStack = new Stack();
97 | uint segAddress;
98 | uint segOffset;
99 | byte bank;
100 | Texture nextTexture = new Texture();
101 | Triangle nextTri = new Triangle();
102 | List displayLists = new List();
103 | displayLists.Add(level.header.offsets[(0x88 - 0x20) / 4]);
104 | displayLists.Add(level.header.offsets[(0x90 - 0x20) / 4]);
105 | displayLists.Add(level.header.offsets[(0x94 - 0x20) / 4]);
106 | displayLists.Add(level.header.offsets[(0x98 - 0x20) / 4]);
107 | displayLists.Add(level.header.offsets[(0x9C - 0x20) / 4]);
108 |
109 | foreach (uint startOffset in displayLists)
110 | {
111 | bool done = false;
112 | for (uint offset = startOffset - level.header.dlOffset; offset < displayList.Length && !done; offset += 8)
113 | {
114 | UInt32 w0 = BE.U32(displayList, offset);
115 | UInt32 w1 = BE.U32(displayList, offset + 4);
116 | byte command = displayList[offset];
117 | switch (command)
118 | {
119 | case F3D_MOVEMEM:
120 | break;
121 | case F3D_VTX:
122 | int count = ((displayList[offset + 1] >> 4) & 0xF) + 1;
123 | int index = (displayList[offset + 1]) & 0xF;
124 | segAddress = w1;
125 | bank = displayList[offset + 4];
126 | segOffset = segAddress & 0x00FFFFFF;
127 | LoadVertices(level.vertData, segOffset, index, count, vertexBuffer);
128 | break;
129 | case F3D_DL:
130 | segAddress = w1;
131 | bank = displayList[offset + 4];
132 | segOffset = segAddress & 0x00FFFFFF;
133 | dlStack.Push(offset);
134 | offset = segOffset - 8; // subtract 8 since for loop will increment by 8
135 | break;
136 | case F3D_QUAD:
137 | break;
138 | case F3D_CLRGEOMODE:
139 | break;
140 | case F3D_SETGEOMODE:
141 | break;
142 | case F3D_ENDDL:
143 | if (dlStack.Count == 0)
144 | {
145 | done = true;
146 | }
147 | else
148 | {
149 | offset = dlStack.Pop();
150 | }
151 | break;
152 | case F3D_TEXTURE:
153 | // reset tile sizes
154 | nextTexture = new Texture();
155 | break;
156 | case F3D_TRI1:
157 | int vertex0 = displayList[offset + 5] / 0x0A;
158 | int vertex1 = displayList[offset + 6] / 0x0A;
159 | int vertex2 = displayList[offset + 7] / 0x0A;
160 | Triangle tri = new Triangle(vertexBuffer[vertex0], vertexBuffer[vertex1], vertexBuffer[vertex2]);
161 | tri.texture = nextTexture;
162 | triangles.Add(tri);
163 | break;
164 | case G_SETTILESIZE:
165 | if (nextTexture.width < 0)
166 | {
167 | nextTexture.width = (((displayList[offset + 5] << 8) | (displayList[offset + 6] & 0xF0)) >> 6) + 1;
168 | nextTexture.height = (((displayList[offset + 6] & 0x0F) << 8 | displayList[offset + 7]) >> 2) + 1;
169 | }
170 | if (nextTexture.IsComplete())
171 | {
172 | textures.Add(nextTexture);
173 | }
174 | break;
175 | case G_LOADBLOCK:
176 | break;
177 | case G_SETTILE:
178 | break;
179 | case G_SETFOGCOLOR:
180 | break;
181 | case G_SETENVCOLOR:
182 | break;
183 | case G_SETCOMBINE:
184 | break;
185 | case G_SETTIMG:
186 | segAddress = w1;
187 | bank = displayList[offset + 4];
188 | segOffset = segAddress & 0x00FFFFFF;
189 | nextTexture.address = segAddress;
190 | if (nextTexture.IsComplete())
191 | {
192 | textures.Add(nextTexture);
193 | }
194 | break;
195 | }
196 | }
197 | }
198 | }
199 |
200 | private static void LoadVertices(byte[] segmentData, uint segOffset, int index, int count, Vertex[] vertexBuffer)
201 | {
202 | for (uint i = 0; i < count; i++)
203 | {
204 | if (i + index < vertexBuffer.Length)
205 | {
206 | vertexBuffer[i + index] = new Vertex(segmentData, segOffset + i * 0x10);
207 | }
208 | }
209 | }
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/N64Graphics.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Drawing.Imaging;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace BlastCorpsEditor
10 | {
11 | enum N64Format { RGBA, IA }
12 |
13 | class N64Graphics
14 | {
15 | public static int SCALE_5_8(int val)
16 | {
17 | return (((val) * 0xFF) / 0x1F);
18 | }
19 |
20 | public static int SCALE_4_8(int val)
21 | {
22 | return ((val) * 0x11);
23 | }
24 |
25 | public static int SCALE_3_8(int val)
26 | {
27 | return ((val) * 0x24);
28 | }
29 |
30 | private static void SetPixel(Graphics g, int x, int y, Brush b)
31 | {
32 | g.FillRectangle(b, x, y, 1, 1);
33 | }
34 |
35 | public static Bitmap RGBA(byte[] raw, int width, int height, int depth)
36 | {
37 | Bitmap bitmap = new Bitmap(width, height);
38 |
39 | Graphics graphics = Graphics.FromImage(bitmap);
40 | SolidBrush brush = new SolidBrush(Color.Magenta);
41 | if (depth == 16)
42 | {
43 | for (int i = 0; i < width * height; i++)
44 | {
45 | int idx = i * 2;
46 | if (idx + 2 > raw.Length)
47 | {
48 | break;
49 | }
50 | int red = SCALE_5_8((raw[idx] & 0xF8) >> 3);
51 | int green = SCALE_5_8(((raw[idx] & 0x07) << 2) | ((raw[idx + 1] & 0xC0) >> 6));
52 | int blue = SCALE_5_8((raw[idx + 1] & 0x3E) >> 1);
53 | int alpha = ((raw[idx + 1] & 0x01) > 0) ? 0xFF : 0x00;
54 | brush.Color = Color.FromArgb(alpha, red, green, blue);
55 | int y = i / width;
56 | int x = i % width;
57 | SetPixel(graphics, x, y, brush);
58 | }
59 | }
60 | else if (depth == 32)
61 | {
62 | for (int i = 0; i < width * height; i++)
63 | {
64 | int idx = i * 4;
65 | if (idx + 4 > raw.Length)
66 | {
67 | break;
68 | }
69 | int red = raw[idx];
70 | int green = raw[idx + 1];
71 | int blue = raw[idx + 2];
72 | int alpha = raw[idx + 3];
73 | brush.Color = Color.FromArgb(alpha, red, green, blue);
74 | int y = i / width;
75 | int x = i % width;
76 | SetPixel(graphics, x, y, brush);
77 | }
78 | }
79 |
80 | return bitmap;
81 | }
82 |
83 | public static Bitmap IA(byte[] raw, int width, int height, int depth)
84 | {
85 | Bitmap bitmap = new Bitmap(width, height);
86 |
87 | Graphics graphics = Graphics.FromImage(bitmap);
88 | SolidBrush brush = new SolidBrush(Color.Magenta);
89 | switch (depth) {
90 | case 16:
91 | for (int i = 0; i < width * height; i++) {
92 | int idx = i * 2;
93 | if (idx + 2 > raw.Length)
94 | {
95 | break;
96 | }
97 | int intensity = raw[idx];
98 | int alpha = raw[idx + 1];
99 | brush.Color = Color.FromArgb(alpha, intensity, intensity, intensity);
100 | int y = i / width;
101 | int x = i % width;
102 | SetPixel(graphics, x, y, brush);
103 | }
104 | break;
105 | case 8:
106 | for (int i = 0; i < width * height; i++) {
107 | if (i + 1 > raw.Length)
108 | {
109 | break;
110 | }
111 | int intensity = SCALE_4_8((raw[i] & 0xF0) >> 4);
112 | int alpha = SCALE_4_8(raw[i] & 0x0F);
113 | brush.Color = Color.FromArgb(alpha, intensity, intensity, intensity);
114 | int y = i / width;
115 | int x = i % width;
116 | SetPixel(graphics, x, y, brush);
117 | }
118 | break;
119 | case 4:
120 | for (int i = 0; i < width * height; i++) {
121 | int idx = i / 2;
122 | if (idx >= raw.Length)
123 | {
124 | break;
125 | }
126 | byte bits;
127 | bits = raw[idx];
128 | if (i % 2 > 0) {
129 | bits &= 0xF;
130 | } else {
131 | bits >>= 4;
132 | }
133 | int intensity = SCALE_3_8((bits >> 1) & 0x07);
134 | int alpha = (bits & 0x01) > 0 ? 0xFF : 0x00;
135 | brush.Color = Color.FromArgb(alpha, intensity, intensity, intensity);
136 | int y = i / width;
137 | int x = i % width;
138 | SetPixel(graphics, x, y, brush);
139 | }
140 | break;
141 | case 1:
142 | for (int i = 0; i < width * height; i++) {
143 | int idx = i / 8;
144 | if (idx >= raw.Length)
145 | {
146 | break;
147 | }
148 | int bits;
149 | int mask;
150 | bits = raw[i/8];
151 | mask = 1 << (7 - (i % 8)); // MSb->LSb
152 | bits = ((bits & mask) > 0) ? 0xFF : 0x00;
153 | int intensity = bits;
154 | int alpha = bits;
155 | brush.Color = Color.FromArgb(alpha, intensity, intensity, intensity);
156 | int y = i / width;
157 | int x = i % width;
158 | SetPixel(graphics, x, y, brush);
159 | }
160 | break;
161 | default:
162 | break;
163 | }
164 |
165 | return bitmap;
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/PictureBoxInterpolation.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing.Drawing2D;
2 | using System.Windows.Forms;
3 |
4 | namespace BlastCorpsEditor
5 | {
6 | ///
7 | /// Inherits from PictureBox; adds Interpolation Mode Setting
8 | ///
9 | public class PictureBoxInterpolation : PictureBox
10 | {
11 | public InterpolationMode InterpolationMode { get; set; }
12 |
13 | protected override void OnPaint(PaintEventArgs paintEventArgs)
14 | {
15 | paintEventArgs.Graphics.InterpolationMode = InterpolationMode;
16 | base.OnPaint(paintEventArgs);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace BlastCorpsEditor
5 | {
6 | static class Program
7 | {
8 | ///
9 | /// The main entry point for the application.
10 | ///
11 | [STAThread]
12 | static void Main()
13 | {
14 | Application.EnableVisualStyles();
15 | Application.SetCompatibleTextRenderingDefault(false);
16 | Application.Run(new BlastCorpsEditorForm());
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Blast Corps Editor")]
9 | [assembly: AssemblyDescription("Blast Corps Editor")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("queueRAM")]
12 | [assembly: AssemblyProduct("Blast Corps Editor")]
13 | [assembly: AssemblyCopyright("Copyright ©queueRAM 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("ce279bd5-c8bb-4e2a-bfbe-8b7afe57cc33")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.0.4.4")]
36 | [assembly: AssemblyFileVersion("0.0.4.4")]
37 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace BlastCorpsEditor.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BlastCorpsEditor.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Byte[].
65 | ///
66 | internal static byte[] cursor_move {
67 | get {
68 | object obj = ResourceManager.GetObject("cursor_move", resourceCulture);
69 | return ((byte[])(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Byte[].
75 | ///
76 | internal static byte[] cursor_plus {
77 | get {
78 | object obj = ResourceManager.GetObject("cursor_plus", resourceCulture);
79 | return ((byte[])(obj));
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\cursors\cursor-move.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
123 |
124 |
125 | ..\cursors\cursor-plus.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
126 |
127 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace BlastCorpsEditor.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
29 | public bool ViewBoxes40 {
30 | get {
31 | return ((bool)(this["ViewBoxes40"]));
32 | }
33 | set {
34 | this["ViewBoxes40"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
41 | public bool ViewBoxes44 {
42 | get {
43 | return ((bool)(this["ViewBoxes44"]));
44 | }
45 | set {
46 | this["ViewBoxes44"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
53 | public bool ViewGridLines {
54 | get {
55 | return ((bool)(this["ViewGridLines"]));
56 | }
57 | set {
58 | this["ViewGridLines"] = value;
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | False
7 |
8 |
9 | False
10 |
11 |
12 | True
13 |
14 |
15 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/TextureForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BlastCorpsEditor
2 | {
3 | partial class TextureForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.numericWidth = new System.Windows.Forms.NumericUpDown();
32 | this.label1 = new System.Windows.Forms.Label();
33 | this.numericHeight = new System.Windows.Forms.NumericUpDown();
34 | this.label2 = new System.Windows.Forms.Label();
35 | this.label3 = new System.Windows.Forms.Label();
36 | this.numericImage = new System.Windows.Forms.NumericUpDown();
37 | this.buttonReload = new System.Windows.Forms.Button();
38 | this.groupBox1 = new System.Windows.Forms.GroupBox();
39 | this.label7 = new System.Windows.Forms.Label();
40 | this.textBoxUncompressed = new System.Windows.Forms.TextBox();
41 | this.label6 = new System.Windows.Forms.Label();
42 | this.textBoxType = new System.Windows.Forms.TextBox();
43 | this.label5 = new System.Windows.Forms.Label();
44 | this.textBoxLength = new System.Windows.Forms.TextBox();
45 | this.textBoxOffset = new System.Windows.Forms.TextBox();
46 | this.label4 = new System.Windows.Forms.Label();
47 | this.label8 = new System.Windows.Forms.Label();
48 | this.comboBoxFormat = new System.Windows.Forms.ComboBox();
49 | this.pictureBoxActual = new System.Windows.Forms.PictureBox();
50 | this.buttonExport = new System.Windows.Forms.Button();
51 | this.numericLut = new System.Windows.Forms.NumericUpDown();
52 | this.label9 = new System.Windows.Forms.Label();
53 | this.pictureBoxTexture = new BlastCorpsEditor.PictureBoxInterpolation();
54 | ((System.ComponentModel.ISupportInitialize)(this.numericWidth)).BeginInit();
55 | ((System.ComponentModel.ISupportInitialize)(this.numericHeight)).BeginInit();
56 | ((System.ComponentModel.ISupportInitialize)(this.numericImage)).BeginInit();
57 | this.groupBox1.SuspendLayout();
58 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxActual)).BeginInit();
59 | ((System.ComponentModel.ISupportInitialize)(this.numericLut)).BeginInit();
60 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxTexture)).BeginInit();
61 | this.SuspendLayout();
62 | //
63 | // numericWidth
64 | //
65 | this.numericWidth.Location = new System.Drawing.Point(67, 172);
66 | this.numericWidth.Maximum = new decimal(new int[] {
67 | 2048,
68 | 0,
69 | 0,
70 | 0});
71 | this.numericWidth.Minimum = new decimal(new int[] {
72 | 1,
73 | 0,
74 | 0,
75 | 0});
76 | this.numericWidth.Name = "numericWidth";
77 | this.numericWidth.Size = new System.Drawing.Size(98, 20);
78 | this.numericWidth.TabIndex = 0;
79 | this.numericWidth.Value = new decimal(new int[] {
80 | 16,
81 | 0,
82 | 0,
83 | 0});
84 | //
85 | // label1
86 | //
87 | this.label1.AutoSize = true;
88 | this.label1.Location = new System.Drawing.Point(12, 174);
89 | this.label1.Name = "label1";
90 | this.label1.Size = new System.Drawing.Size(38, 13);
91 | this.label1.TabIndex = 1;
92 | this.label1.Text = "Width:";
93 | //
94 | // numericHeight
95 | //
96 | this.numericHeight.Location = new System.Drawing.Point(67, 199);
97 | this.numericHeight.Maximum = new decimal(new int[] {
98 | 2048,
99 | 0,
100 | 0,
101 | 0});
102 | this.numericHeight.Minimum = new decimal(new int[] {
103 | 1,
104 | 0,
105 | 0,
106 | 0});
107 | this.numericHeight.Name = "numericHeight";
108 | this.numericHeight.Size = new System.Drawing.Size(98, 20);
109 | this.numericHeight.TabIndex = 2;
110 | this.numericHeight.Value = new decimal(new int[] {
111 | 16,
112 | 0,
113 | 0,
114 | 0});
115 | //
116 | // label2
117 | //
118 | this.label2.AutoSize = true;
119 | this.label2.Location = new System.Drawing.Point(12, 201);
120 | this.label2.Name = "label2";
121 | this.label2.Size = new System.Drawing.Size(41, 13);
122 | this.label2.TabIndex = 3;
123 | this.label2.Text = "Height:";
124 | //
125 | // label3
126 | //
127 | this.label3.AutoSize = true;
128 | this.label3.Location = new System.Drawing.Point(12, 14);
129 | this.label3.Name = "label3";
130 | this.label3.Size = new System.Drawing.Size(39, 13);
131 | this.label3.TabIndex = 5;
132 | this.label3.Text = "Image:";
133 | //
134 | // numericImage
135 | //
136 | this.numericImage.Hexadecimal = true;
137 | this.numericImage.Location = new System.Drawing.Point(67, 12);
138 | this.numericImage.Maximum = new decimal(new int[] {
139 | 4096,
140 | 0,
141 | 0,
142 | 0});
143 | this.numericImage.Name = "numericImage";
144 | this.numericImage.Size = new System.Drawing.Size(98, 20);
145 | this.numericImage.TabIndex = 6;
146 | this.numericImage.ValueChanged += new System.EventHandler(this.numericImage_ValueChanged);
147 | //
148 | // buttonReload
149 | //
150 | this.buttonReload.Location = new System.Drawing.Point(15, 280);
151 | this.buttonReload.Name = "buttonReload";
152 | this.buttonReload.Size = new System.Drawing.Size(150, 23);
153 | this.buttonReload.TabIndex = 7;
154 | this.buttonReload.Text = "Reload";
155 | this.buttonReload.UseVisualStyleBackColor = true;
156 | this.buttonReload.Click += new System.EventHandler(this.buttonReload_Click);
157 | //
158 | // groupBox1
159 | //
160 | this.groupBox1.Controls.Add(this.label7);
161 | this.groupBox1.Controls.Add(this.textBoxUncompressed);
162 | this.groupBox1.Controls.Add(this.label6);
163 | this.groupBox1.Controls.Add(this.textBoxType);
164 | this.groupBox1.Controls.Add(this.label5);
165 | this.groupBox1.Controls.Add(this.textBoxLength);
166 | this.groupBox1.Controls.Add(this.textBoxOffset);
167 | this.groupBox1.Controls.Add(this.label4);
168 | this.groupBox1.Location = new System.Drawing.Point(15, 38);
169 | this.groupBox1.Name = "groupBox1";
170 | this.groupBox1.Size = new System.Drawing.Size(156, 128);
171 | this.groupBox1.TabIndex = 8;
172 | this.groupBox1.TabStop = false;
173 | this.groupBox1.Text = "Properties:";
174 | //
175 | // label7
176 | //
177 | this.label7.AutoSize = true;
178 | this.label7.Location = new System.Drawing.Point(8, 101);
179 | this.label7.Name = "label7";
180 | this.label7.Size = new System.Drawing.Size(45, 13);
181 | this.label7.TabIndex = 7;
182 | this.label7.Text = "Inflated:";
183 | //
184 | // textBoxUncompressed
185 | //
186 | this.textBoxUncompressed.Location = new System.Drawing.Point(52, 98);
187 | this.textBoxUncompressed.Name = "textBoxUncompressed";
188 | this.textBoxUncompressed.ReadOnly = true;
189 | this.textBoxUncompressed.Size = new System.Drawing.Size(98, 20);
190 | this.textBoxUncompressed.TabIndex = 6;
191 | //
192 | // label6
193 | //
194 | this.label6.AutoSize = true;
195 | this.label6.Location = new System.Drawing.Point(8, 75);
196 | this.label6.Name = "label6";
197 | this.label6.Size = new System.Drawing.Size(34, 13);
198 | this.label6.TabIndex = 5;
199 | this.label6.Text = "Type:";
200 | //
201 | // textBoxType
202 | //
203 | this.textBoxType.Location = new System.Drawing.Point(52, 72);
204 | this.textBoxType.Name = "textBoxType";
205 | this.textBoxType.ReadOnly = true;
206 | this.textBoxType.Size = new System.Drawing.Size(98, 20);
207 | this.textBoxType.TabIndex = 4;
208 | //
209 | // label5
210 | //
211 | this.label5.AutoSize = true;
212 | this.label5.Location = new System.Drawing.Point(8, 49);
213 | this.label5.Name = "label5";
214 | this.label5.Size = new System.Drawing.Size(43, 13);
215 | this.label5.TabIndex = 3;
216 | this.label5.Text = "Length:";
217 | //
218 | // textBoxLength
219 | //
220 | this.textBoxLength.Location = new System.Drawing.Point(52, 46);
221 | this.textBoxLength.Name = "textBoxLength";
222 | this.textBoxLength.ReadOnly = true;
223 | this.textBoxLength.Size = new System.Drawing.Size(98, 20);
224 | this.textBoxLength.TabIndex = 2;
225 | //
226 | // textBoxOffset
227 | //
228 | this.textBoxOffset.Location = new System.Drawing.Point(52, 19);
229 | this.textBoxOffset.Name = "textBoxOffset";
230 | this.textBoxOffset.ReadOnly = true;
231 | this.textBoxOffset.Size = new System.Drawing.Size(98, 20);
232 | this.textBoxOffset.TabIndex = 1;
233 | //
234 | // label4
235 | //
236 | this.label4.AutoSize = true;
237 | this.label4.Location = new System.Drawing.Point(8, 22);
238 | this.label4.Name = "label4";
239 | this.label4.Size = new System.Drawing.Size(38, 13);
240 | this.label4.TabIndex = 0;
241 | this.label4.Text = "Offset:";
242 | //
243 | // label8
244 | //
245 | this.label8.AutoSize = true;
246 | this.label8.Location = new System.Drawing.Point(12, 229);
247 | this.label8.Name = "label8";
248 | this.label8.Size = new System.Drawing.Size(42, 13);
249 | this.label8.TabIndex = 9;
250 | this.label8.Text = "Format:";
251 | //
252 | // comboBoxFormat
253 | //
254 | this.comboBoxFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
255 | this.comboBoxFormat.FormattingEnabled = true;
256 | this.comboBoxFormat.Items.AddRange(new object[] {
257 | "RBGA16 (5551)",
258 | "RGBA32 (8888)",
259 | "IA16",
260 | "IA8",
261 | "IA4",
262 | "IA1"});
263 | this.comboBoxFormat.Location = new System.Drawing.Point(67, 226);
264 | this.comboBoxFormat.Name = "comboBoxFormat";
265 | this.comboBoxFormat.Size = new System.Drawing.Size(98, 21);
266 | this.comboBoxFormat.TabIndex = 10;
267 | //
268 | // pictureBoxActual
269 | //
270 | this.pictureBoxActual.BackColor = System.Drawing.SystemColors.Control;
271 | this.pictureBoxActual.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
272 | this.pictureBoxActual.Location = new System.Drawing.Point(177, 12);
273 | this.pictureBoxActual.Name = "pictureBoxActual";
274 | this.pictureBoxActual.Size = new System.Drawing.Size(64, 64);
275 | this.pictureBoxActual.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
276 | this.pictureBoxActual.TabIndex = 11;
277 | this.pictureBoxActual.TabStop = false;
278 | //
279 | // buttonExport
280 | //
281 | this.buttonExport.Enabled = false;
282 | this.buttonExport.Location = new System.Drawing.Point(15, 322);
283 | this.buttonExport.Name = "buttonExport";
284 | this.buttonExport.Size = new System.Drawing.Size(150, 23);
285 | this.buttonExport.TabIndex = 12;
286 | this.buttonExport.Text = "Export PNG";
287 | this.buttonExport.UseVisualStyleBackColor = true;
288 | this.buttonExport.Click += new System.EventHandler(this.buttonExport_Click);
289 | //
290 | // numericLut
291 | //
292 | this.numericLut.Enabled = false;
293 | this.numericLut.Hexadecimal = true;
294 | this.numericLut.Location = new System.Drawing.Point(67, 254);
295 | this.numericLut.Maximum = new decimal(new int[] {
296 | 8388608,
297 | 0,
298 | 0,
299 | 0});
300 | this.numericLut.Name = "numericLut";
301 | this.numericLut.Size = new System.Drawing.Size(98, 20);
302 | this.numericLut.TabIndex = 13;
303 | this.numericLut.Value = new decimal(new int[] {
304 | 1386864,
305 | 0,
306 | 0,
307 | 0});
308 | //
309 | // label9
310 | //
311 | this.label9.AutoSize = true;
312 | this.label9.Location = new System.Drawing.Point(12, 256);
313 | this.label9.Name = "label9";
314 | this.label9.Size = new System.Drawing.Size(31, 13);
315 | this.label9.TabIndex = 14;
316 | this.label9.Text = "LUT:";
317 | //
318 | // pictureBoxTexture
319 | //
320 | this.pictureBoxTexture.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
321 | | System.Windows.Forms.AnchorStyles.Left)
322 | | System.Windows.Forms.AnchorStyles.Right)));
323 | this.pictureBoxTexture.BackColor = System.Drawing.SystemColors.Control;
324 | this.pictureBoxTexture.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
325 | this.pictureBoxTexture.Location = new System.Drawing.Point(177, 82);
326 | this.pictureBoxTexture.Name = "pictureBoxTexture";
327 | this.pictureBoxTexture.Size = new System.Drawing.Size(265, 264);
328 | this.pictureBoxTexture.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
329 | this.pictureBoxTexture.TabIndex = 4;
330 | this.pictureBoxTexture.TabStop = false;
331 | //
332 | // TextureForm
333 | //
334 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
335 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
336 | this.ClientSize = new System.Drawing.Size(454, 357);
337 | this.Controls.Add(this.label9);
338 | this.Controls.Add(this.numericLut);
339 | this.Controls.Add(this.buttonExport);
340 | this.Controls.Add(this.pictureBoxActual);
341 | this.Controls.Add(this.comboBoxFormat);
342 | this.Controls.Add(this.label8);
343 | this.Controls.Add(this.groupBox1);
344 | this.Controls.Add(this.buttonReload);
345 | this.Controls.Add(this.numericImage);
346 | this.Controls.Add(this.label3);
347 | this.Controls.Add(this.pictureBoxTexture);
348 | this.Controls.Add(this.label2);
349 | this.Controls.Add(this.numericHeight);
350 | this.Controls.Add(this.label1);
351 | this.Controls.Add(this.numericWidth);
352 | this.Name = "TextureForm";
353 | this.Text = "Blast Corps Textures";
354 | this.Load += new System.EventHandler(this.TextureForm_Load);
355 | ((System.ComponentModel.ISupportInitialize)(this.numericWidth)).EndInit();
356 | ((System.ComponentModel.ISupportInitialize)(this.numericHeight)).EndInit();
357 | ((System.ComponentModel.ISupportInitialize)(this.numericImage)).EndInit();
358 | this.groupBox1.ResumeLayout(false);
359 | this.groupBox1.PerformLayout();
360 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxActual)).EndInit();
361 | ((System.ComponentModel.ISupportInitialize)(this.numericLut)).EndInit();
362 | ((System.ComponentModel.ISupportInitialize)(this.pictureBoxTexture)).EndInit();
363 | this.ResumeLayout(false);
364 | this.PerformLayout();
365 |
366 | }
367 |
368 | #endregion
369 |
370 | private System.Windows.Forms.NumericUpDown numericWidth;
371 | private System.Windows.Forms.Label label1;
372 | private System.Windows.Forms.NumericUpDown numericHeight;
373 | private System.Windows.Forms.Label label2;
374 | private PictureBoxInterpolation pictureBoxTexture;
375 | private System.Windows.Forms.Label label3;
376 | private System.Windows.Forms.NumericUpDown numericImage;
377 | private System.Windows.Forms.Button buttonReload;
378 | private System.Windows.Forms.GroupBox groupBox1;
379 | private System.Windows.Forms.Label label7;
380 | private System.Windows.Forms.TextBox textBoxUncompressed;
381 | private System.Windows.Forms.Label label6;
382 | private System.Windows.Forms.TextBox textBoxType;
383 | private System.Windows.Forms.Label label5;
384 | private System.Windows.Forms.TextBox textBoxLength;
385 | private System.Windows.Forms.TextBox textBoxOffset;
386 | private System.Windows.Forms.Label label4;
387 | private System.Windows.Forms.Label label8;
388 | private System.Windows.Forms.ComboBox comboBoxFormat;
389 | private System.Windows.Forms.PictureBox pictureBoxActual;
390 | private System.Windows.Forms.Button buttonExport;
391 | private System.Windows.Forms.NumericUpDown numericLut;
392 | private System.Windows.Forms.Label label9;
393 | }
394 | }
--------------------------------------------------------------------------------
/BlastCorpsEditor/TextureForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Drawing.Drawing2D;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows.Forms;
11 |
12 | namespace BlastCorpsEditor
13 | {
14 | public partial class TextureForm : Form
15 | {
16 | private BlastCorpsRom rom;
17 | private Bitmap loadedBitmap;
18 |
19 | public TextureForm(BlastCorpsRom rom)
20 | {
21 | InitializeComponent();
22 | this.rom = rom;
23 | }
24 |
25 | private void GuessDims(int type, int length, ref int width, ref int height, ref N64Format format, ref int depth)
26 | {
27 | const int KB = 1024;
28 | switch (type)
29 | {
30 | case 0: // IA8?
31 | // TODO: memcpy, no info
32 | format = N64Format.IA;
33 | depth = 8;
34 | switch (length)
35 | {
36 | case 256: width = 16; height = 16; break;
37 | case 512: width = 32; height = 16; break;
38 | case 1 * KB: width = 32; height = 32; break;
39 | case 2 * KB: width = 64; height = 32; break;
40 | case 4 * KB: width = 64; height = 64; break;
41 | default: width = 16; height = (length * 8 / depth) / width; break;
42 | }
43 | break;
44 | case 1: // RBGA16?
45 | format = N64Format.RGBA;
46 | depth = 16;
47 | switch (length)
48 | {
49 | case 16: width = 4; height = 2; break;
50 | case 512: width = 16; height = 16; break;
51 | case 1 * KB: width = 16; height = 32; break;
52 | case 2 * KB: width = 32; height = 32; break;
53 | case 4 * KB: width = 64; height = 32; break;
54 | case 8 * KB: width = 64; height = 64; break;
55 | case 0xC80: width = 40; height = 40; break;
56 | default: width = 32; height = length / width / 2; break;
57 | }
58 | break;
59 | case 2: // RGBA32?
60 | format = N64Format.RGBA;
61 | depth = 32;
62 | switch (length)
63 | {
64 | case 1 * KB: width = 16; height = 16; break;
65 | case 2 * KB: width = 16; height = 32; break;
66 | case 4 * KB: width = 32; height = 32; break;
67 | case 8 * KB: width = 64; height = 32; break;
68 | default: width = 32; height = length / width / 4; break;
69 | }
70 | break;
71 | case 3: // IA8?
72 | format = N64Format.IA;
73 | depth = 8;
74 | switch (length)
75 | {
76 | case 1 * KB: width = 32; height = 32; break;
77 | case 2 * KB: width = 32; height = 64; break;
78 | case 4 * KB: width = 64; height = 64; break;
79 | case 8 * KB: width = 64; height = 128; break;
80 | default: width = 32; height = length / width; break;
81 | }
82 | break;
83 | case 4: // IA16?
84 | format = N64Format.IA;
85 | depth = 16;
86 | switch (length)
87 | {
88 | case 1 * KB: width = 32; height = 16; break;
89 | case 2 * KB: width = 32; height = 32; break;
90 | case 4 * KB: width = 32; height = 64; break;
91 | case 8 * KB: width = 64; height = 64; break;
92 | default: width = 32; height = length / width / 2; break;
93 | }
94 | break;
95 | case 5: // RGBA32?
96 | format = N64Format.RGBA;
97 | depth = 32;
98 | switch (length)
99 | {
100 | case 1 * KB: width = 16; height = 16; break;
101 | case 2 * KB: width = 32; height = 16; break;
102 | case 4 * KB: width = 32; height = 32; break;
103 | case 8 * KB: width = 64; height = 32; break;
104 | default: width = 32; height = length / width / 2; break;
105 | }
106 | break;
107 | case 6: // IA8? IA4 always has alpha (lsb) clear
108 | format = N64Format.IA;
109 | depth = 8;
110 | width = 16;
111 | height = (length * 8 / depth) / width;
112 | break;
113 | }
114 | }
115 |
116 | private void LoadImage(uint index, int width, int height, N64Format format, int depth)
117 | {
118 | BlastCorpsTexture texture = new BlastCorpsTexture(rom.GetRawData(), index, (uint)numericLut.Value);
119 | texture.decode();
120 | byte[] n64Texture = texture.GetInflated();
121 | textBoxOffset.Text = texture.offset.ToString("X");
122 | textBoxLength.Text = texture.length.ToString("X");
123 | textBoxType.Text = texture.type.ToString();
124 | loadedBitmap = null;
125 | if (n64Texture == null || n64Texture.Length == 0)
126 | {
127 | textBoxUncompressed.Text = "null";
128 | }
129 | else
130 | {
131 | textBoxUncompressed.Text = n64Texture.Length.ToString("X");
132 | if (width == 0)
133 | {
134 | GuessDims(texture.type, n64Texture.Length, ref width, ref height, ref format, ref depth);
135 | numericHeight.Value = height;
136 | numericWidth.Value = width;
137 | switch (format)
138 | {
139 | case N64Format.RGBA:
140 | comboBoxFormat.SelectedIndex = (depth == 32) ? 1 : 0;
141 | break;
142 | case N64Format.IA:
143 | switch (depth)
144 | {
145 | case 16: comboBoxFormat.SelectedIndex = 2; break;
146 | case 8: comboBoxFormat.SelectedIndex = 3; break;
147 | case 4: comboBoxFormat.SelectedIndex = 4; break;
148 | case 1: comboBoxFormat.SelectedIndex = 5; break;
149 | }
150 | break;
151 | }
152 | }
153 | switch (format)
154 | {
155 | case N64Format.RGBA:
156 | loadedBitmap = N64Graphics.RGBA(n64Texture, width, height, depth);
157 | break;
158 | case N64Format.IA:
159 | loadedBitmap = N64Graphics.IA(n64Texture, width, height, depth);
160 | break;
161 | }
162 |
163 | if (loadedBitmap != null)
164 | {
165 | loadedBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
166 | }
167 | }
168 | pictureBoxTexture.Image = loadedBitmap;
169 | pictureBoxActual.Image = loadedBitmap;
170 | buttonExport.Enabled = (loadedBitmap != null);
171 | numericLut.Enabled = (texture.type == 4 || texture.type == 5);
172 | }
173 |
174 | private void LoadImage()
175 | {
176 | LoadImage((uint)numericImage.Value, 0, 0, N64Format.RGBA, 0);
177 | }
178 |
179 | private void TextureForm_Load(object sender, EventArgs e)
180 | {
181 | LoadImage();
182 | }
183 |
184 | private void numericImage_ValueChanged(object sender, EventArgs e)
185 | {
186 | LoadImage();
187 | }
188 |
189 | private void buttonReload_Click(object sender, EventArgs e)
190 | {
191 | N64Format format = N64Format.RGBA;
192 | int depth = 16;
193 | switch (comboBoxFormat.SelectedIndex)
194 | {
195 | case 0: format = N64Format.RGBA; depth = 16; break;
196 | case 1: format = N64Format.RGBA; depth = 32; break;
197 | case 2: format = N64Format.IA; depth = 16; break;
198 | case 3: format = N64Format.IA; depth = 8; break;
199 | case 4: format = N64Format.IA; depth = 4; break;
200 | case 5: format = N64Format.IA; depth = 1; break;
201 | }
202 | LoadImage((uint)numericImage.Value, (int)numericWidth.Value, (int)numericHeight.Value, format, depth);
203 | }
204 |
205 | private void buttonExport_Click(object sender, EventArgs e)
206 | {
207 | SaveFileDialog saveFileDialog = new SaveFileDialog();
208 | saveFileDialog.Filter = "PNG Image(*.png)|*.png";
209 | saveFileDialog.Title = "Export Texture to PNG";
210 | saveFileDialog.ShowDialog();
211 |
212 | if (saveFileDialog.FileName != "")
213 | {
214 | loadedBitmap.Save(saveFileDialog.FileName);
215 | }
216 | }
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/TextureForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace BlastCorpsEditor
5 | {
6 | // helper class for converting arrays of bytes in big endian to native integer types
7 | class BE
8 | {
9 | public static UInt32 U32(byte[] buf, uint i)
10 | {
11 | byte[] u32bytes = new byte[4];
12 | Array.Copy(buf, i, u32bytes, 0, u32bytes.Length);
13 | if (BitConverter.IsLittleEndian)
14 | {
15 | Array.Reverse(u32bytes);
16 | }
17 | return BitConverter.ToUInt32(u32bytes, 0);
18 | }
19 |
20 | public static Int32 I32(byte[] buf, uint i)
21 | {
22 | byte[] i32bytes = new byte[4];
23 | Array.Copy(buf, i, i32bytes, 0, i32bytes.Length);
24 | if (BitConverter.IsLittleEndian)
25 | {
26 | Array.Reverse(i32bytes);
27 | }
28 | return BitConverter.ToInt32(i32bytes, 0);
29 | }
30 |
31 | public static UInt16 U16(byte[] buf, uint i)
32 | {
33 | byte[] u16bytes = new byte[2];
34 | Array.Copy(buf, i, u16bytes, 0, u16bytes.Length);
35 | if (BitConverter.IsLittleEndian)
36 | {
37 | Array.Reverse(u16bytes);
38 | }
39 | return BitConverter.ToUInt16(u16bytes, 0);
40 | }
41 |
42 | public static Int16 I16(byte[] buf, uint i)
43 | {
44 | byte[] i16bytes = new byte[2];
45 | Array.Copy(buf, i, i16bytes, 0, i16bytes.Length);
46 | if (BitConverter.IsLittleEndian)
47 | {
48 | Array.Reverse(i16bytes);
49 | }
50 | return BitConverter.ToInt16(i16bytes, 0);
51 | }
52 |
53 | public static int ToBytes(Int16 val, byte[] buf, int i)
54 | {
55 | byte[] data = BitConverter.GetBytes(val);
56 | if (BitConverter.IsLittleEndian)
57 | {
58 | Array.Reverse(data);
59 | }
60 | Array.Copy(data, 0, buf, i, data.Length);
61 | return data.Length;
62 | }
63 |
64 | public static int ToBytes(UInt16 val, byte[] buf, int i)
65 | {
66 | byte[] data = BitConverter.GetBytes(val);
67 | if (BitConverter.IsLittleEndian)
68 | {
69 | Array.Reverse(data);
70 | }
71 | Array.Copy(data, 0, buf, i, data.Length);
72 | return data.Length;
73 | }
74 |
75 | public static int ToBytes(Int32 val, byte[] buf, int i)
76 | {
77 | byte[] data = BitConverter.GetBytes(val);
78 | if (BitConverter.IsLittleEndian)
79 | {
80 | Array.Reverse(data);
81 | }
82 | Array.Copy(data, 0, buf, i, data.Length);
83 | return data.Length;
84 | }
85 |
86 | public static int ToBytes(UInt32 val, byte[] buf, int i)
87 | {
88 | byte[] data = BitConverter.GetBytes(val);
89 | if (BitConverter.IsLittleEndian)
90 | {
91 | Array.Reverse(data);
92 | }
93 | Array.Copy(data, 0, buf, i, data.Length);
94 | return data.Length;
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/WavefrontObjExporter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Drawing;
5 | using System.IO;
6 | using System.Reflection;
7 |
8 | namespace BlastCorpsEditor
9 | {
10 | class WavefrontObjExporter
11 | {
12 | public static void ExportTerrain(List terrain, string filename, float scale)
13 | {
14 | using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename))
15 | {
16 | int count = 0;
17 | int vertCount = 1;
18 | file.WriteLine(fileHeader());
19 | file.WriteLine("mtllib blast_corps.mtl");
20 | foreach (TerrainGroup tg in terrain)
21 | {
22 | file.WriteLine(String.Format("g Terrain{0:X2}", count));
23 | foreach (TerrainTri tri in tg.triangles)
24 | {
25 | file.WriteLine(String.Format("usemtl Terrain{0:X02}{1:X02}", tri.b12, tri.b13));
26 | file.WriteLine(toObjVert(tri.x1, tri.y1, tri.z1, scale));
27 | file.WriteLine(toObjVert(tri.x2, tri.y2, tri.z2, scale));
28 | file.WriteLine(toObjVert(tri.x3, tri.y3, tri.z3, scale));
29 | file.WriteLine("f " + vertCount + " " + (vertCount + 1) + " " + (vertCount + 2));
30 | vertCount += 3;
31 | }
32 | count++;
33 | }
34 | }
35 | }
36 |
37 | public static void ExportCollision(List collision, string filename, float scale)
38 | {
39 | using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename))
40 | {
41 | int count = 0;
42 | int vertCount = 1;
43 | file.WriteLine(fileHeader());
44 | file.WriteLine("mtllib blast_corps.mtl");
45 | foreach (CollisionGroup cg in collision)
46 | {
47 | file.WriteLine(String.Format("g Collision{0:X2}", count));
48 | foreach (CollisionTri tri in cg.triangles)
49 | {
50 | file.WriteLine(String.Format("usemtl Collision{0:X02}", tri.b14));
51 | file.WriteLine(toObjVert(tri.x1, tri.y1, tri.z1, scale));
52 | file.WriteLine(toObjVert(tri.x2, tri.y2, tri.z2, scale));
53 | file.WriteLine(toObjVert(tri.x3, tri.y3, tri.z3, scale));
54 | file.WriteLine("f " + vertCount + " " + (vertCount + 1) + " " + (vertCount + 2));
55 | vertCount += 3;
56 | }
57 | count++;
58 | }
59 | }
60 | }
61 |
62 | public static void ExportCollision(List collision, string filename, float scale)
63 | {
64 | using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename))
65 | {
66 | int vertCount = 1;
67 | file.WriteLine(fileHeader());
68 | file.WriteLine("mtllib blast_corps.mtl");
69 | foreach (Collision24 tri in collision)
70 | {
71 | file.WriteLine(String.Format("usemtl Collision24_{0:X4}", tri.type));
72 | file.WriteLine(toObjVert(tri.x1, tri.y1, tri.z1, scale));
73 | file.WriteLine(toObjVert(tri.x2, tri.y2, tri.z2, scale));
74 | file.WriteLine(toObjVert(tri.x3, tri.y3, tri.z3, scale));
75 | file.WriteLine("f " + vertCount + " " + (vertCount + 1) + " " + (vertCount + 2));
76 | vertCount += 3;
77 | }
78 | }
79 | }
80 |
81 | public static void ExportObject60(List object60s, string filename, float scale)
82 | {
83 | using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename))
84 | {
85 | int vertCount = 1;
86 | file.WriteLine(fileHeader());
87 | foreach (Object60 obj in object60s)
88 | {
89 | file.WriteLine(toObjVert(obj.x - 2, obj.y, obj.z - 2, scale));
90 | file.WriteLine(toObjVert(obj.x + 2, obj.y, obj.z - 2, scale));
91 | file.WriteLine(toObjVert(obj.x + 2, obj.y + obj.h6, obj.z - 2, scale));
92 | file.WriteLine("f " + vertCount + " " + (vertCount + 1) + " " + (vertCount + 2));
93 | vertCount += 3;
94 |
95 | file.WriteLine(toObjVert(obj.x - 2, obj.y, obj.z - 2, scale));
96 | file.WriteLine(toObjVert(obj.x + 2, obj.y + obj.h6, obj.z - 2, scale));
97 | file.WriteLine(toObjVert(obj.x - 2, obj.y + obj.h6, obj.z - 2, scale));
98 | file.WriteLine("f " + vertCount + " " + (vertCount + 1) + " " + (vertCount + 2));
99 | vertCount += 3;
100 | }
101 | }
102 | }
103 |
104 | public static void ExportWalls(List wallGroups, string filename, float scale)
105 | {
106 | using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename))
107 | {
108 | int vertCount = 1;
109 | file.WriteLine(fileHeader());
110 | file.WriteLine("mtllib blast_corps.mtl");
111 | foreach (WallGroup group in wallGroups)
112 | {
113 | foreach (Wall wall in group.walls)
114 | {
115 | file.WriteLine(String.Format("usemtl Wall{0:X4}", wall.type));
116 | file.WriteLine(toObjVert(wall.x1, wall.y1, wall.z1, scale));
117 | file.WriteLine(toObjVert(wall.x2, wall.y2, wall.z2, scale));
118 | file.WriteLine(toObjVert(wall.x3, wall.y3, wall.z3, scale));
119 | file.WriteLine("f " + vertCount + " " + (vertCount + 1) + " " + (vertCount + 2));
120 | vertCount += 3;
121 | }
122 | }
123 | }
124 | }
125 |
126 | public static void ExportDisplayList(BlastCorpsRom rom, BlastCorpsLevel level, string filename, float scale)
127 | {
128 | Model3D model = new Model3D(level);
129 |
130 | string mtlFileName = filename + ".mtl";
131 |
132 | using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename))
133 | {
134 | int vertCount = 1;
135 | file.WriteLine(fileHeader());
136 | file.WriteLine("mtllib {0}", Path.GetFileName(mtlFileName));
137 | foreach (Triangle tri in model.triangles)
138 | {
139 | float uScale = 32.0f * tri.texture.width;
140 | float vScale = 32.0f * tri.texture.height;
141 | file.WriteLine();
142 | file.WriteLine("usemtl Texture{0:X4}", tri.texture.address);
143 | file.WriteLine(toObjVert(tri.vertices[0], scale, uScale, vScale));
144 | file.WriteLine(toObjVert(tri.vertices[1], scale, uScale, vScale));
145 | file.WriteLine(toObjVert(tri.vertices[2], scale, uScale, vScale));
146 | file.WriteLine("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", vertCount, (vertCount + 1), (vertCount + 2));
147 | vertCount += 3;
148 | }
149 | }
150 |
151 | // create textures directory
152 | string textureDirName = "textures";
153 | string textureDir = Path.Combine(Path.GetDirectoryName(filename), textureDirName);
154 | Directory.CreateDirectory(textureDir);
155 | using (System.IO.StreamWriter file = new System.IO.StreamWriter(mtlFileName))
156 | {
157 | List processedTextures = new List();
158 | file.WriteLine(fileHeader());
159 | foreach (Texture t in model.textures)
160 | {
161 | if (!processedTextures.Contains(t.address))
162 | {
163 | string textureFilename = String.Format("{0:X4}.png", t.address);
164 | string textureFile = String.Format(textureDirName + "/" + textureFilename);
165 | file.WriteLine("newmtl Texture{0:X4}", t.address);
166 | file.WriteLine("Ka 0.0 0.0 0.0"); // ambiant color
167 | file.WriteLine("Kd 1.0 1.0 1.0"); // diffuse color
168 | file.WriteLine("Ks 0.3 0.3 0.3"); // specular color
169 | file.WriteLine("d 1"); // dissolved
170 | file.WriteLine("map_Kd {0}", textureFile);
171 | file.WriteLine();
172 |
173 | BlastCorpsTexture bct = new BlastCorpsTexture(rom.GetRawData(), t.address, 0);
174 | bct.decode();
175 | byte[] n64Texture = bct.GetInflated();
176 | N64Format format = N64Format.RGBA;
177 | int depth = 16;
178 |
179 | switch (bct.type)
180 | {
181 | case 0: // IA8?
182 | // TODO: memcpy, no info
183 | format = N64Format.IA;
184 | depth = 8;
185 | break;
186 | case 1: // RBGA16?
187 | format = N64Format.RGBA;
188 | depth = 16;
189 | break;
190 | case 2: // RGBA32?
191 | format = N64Format.RGBA;
192 | depth = 32;
193 | break;
194 | case 3: // IA8?
195 | format = N64Format.IA;
196 | depth = 8;
197 | break;
198 | case 4: // IA16?
199 | format = N64Format.IA;
200 | depth = 16;
201 | break;
202 | case 5: // RGBA32?
203 | format = N64Format.RGBA;
204 | depth = 32;
205 | break;
206 | case 6: // IA8?
207 | format = N64Format.IA;
208 | depth = 8;
209 | break;
210 | }
211 |
212 | Bitmap loadedBitmap;
213 | switch (format)
214 | {
215 | case N64Format.RGBA:
216 | loadedBitmap = N64Graphics.RGBA(n64Texture, t.width, t.height, depth);
217 | break;
218 | case N64Format.IA:
219 | default:
220 | loadedBitmap = N64Graphics.IA(n64Texture, t.width, t.height, depth);
221 | break;
222 | }
223 | loadedBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
224 | loadedBitmap.Save(Path.Combine(textureDir, textureFilename));
225 |
226 | processedTextures.Add(t.address);
227 | }
228 | }
229 | }
230 | }
231 |
232 | private static string toObjVert(int x, int y, int z, float scale)
233 | {
234 | float fx, fy, fz;
235 | fx = (float)x / scale;
236 | fy = (float)y / scale;
237 | fz = (float)z / scale;
238 | return "v " + fx + " " + fy + " " + fz;
239 | }
240 |
241 | private static string toObjVert(Vertex vert, float scale, float uScale, float vScale)
242 | {
243 | const float normalScale = 127.0f;
244 | float fx, fy, fz;
245 | fx = (float)vert.x / scale;
246 | fy = (float)vert.y / scale;
247 | fz = (float)vert.z / scale;
248 | string vertData = "v " + fx + " " + fy + " " + fz;
249 | fx = (float)vert.u / uScale;
250 | fy = (float)vert.v / vScale;
251 | string textureData = "vt " + fx + " " + fy;
252 | fx = (float)vert.normals[0] / normalScale;
253 | fy = (float)vert.normals[1] / normalScale;
254 | fz = (float)vert.normals[2] / normalScale;
255 | string normalData = "vn " + fx + " " + fy + " " + fz;
256 | return vertData + Environment.NewLine + textureData + Environment.NewLine + normalData;
257 | }
258 |
259 | private static string fileHeader()
260 | {
261 | var appName = "Blast Corps Editor";
262 | var version = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductVersion;
263 | return "# Generated by " + appName + " v" + version;
264 | }
265 | }
266 | }
267 |
--------------------------------------------------------------------------------
/BlastCorpsEditor/cursors/cursor-move.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queueRAM/BlastCorpsEditor/0ae39a7bf0db381fb0e70805ac7f384eb81d3bd7/BlastCorpsEditor/cursors/cursor-move.cur
--------------------------------------------------------------------------------
/BlastCorpsEditor/cursors/cursor-plus.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queueRAM/BlastCorpsEditor/0ae39a7bf0db381fb0e70805ac7f384eb81d3bd7/BlastCorpsEditor/cursors/cursor-plus.cur
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Q
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Blast Corps Level Editor
2 | Tools for hacking the Blast Corps ROM for N64.
3 |
4 | 
5 |
6 | ## Current Features
7 | * Add, remove, and change properties of the following objects:
8 | * Ammo boxes
9 | * Communication points
10 | * RDUs
11 | * TNT crates
12 | * Square blocks
13 | * Vehicles
14 | * Buildings
15 | * Change carrier position, heading, and speed
16 | * View train/barge platforms, collision modifiers, and bounds
17 | * Edit gravity and other level header data
18 | * Works with (U) (V1.0) and (V1.1) ROMs
19 |
20 | ### Changelog ###
21 | 0.0.4: UI Cleanup, V1.0 Support, Tools
22 | * add support for extending (U) (V1.0) ROM
23 | * use TreeView in UI for object list and common properties area
24 | * create tools to add and remove objects from level
25 | * add select and move tools
26 | * handle filename passed in through command line argument
27 | * update square hole bounds and fields
28 | * add TNT texture drop down
29 | * update square hole geometry and display lists pointers
30 |
31 | 0.0.3: More details on comm points and buildings
32 | * add control for comm point H6 value to control animation
33 | * add more descriptive fields for buildings
34 | * improved item selection UI
35 | * export terrain and collision data to Wavefront OBJ model
36 |
37 | 0.0.2: UI cleanup, improved parsing, bug fixes
38 | * use internal GZipStream instead of external gzip dependency
39 | * add train/barge platforms and stopping zones
40 | * accept all N64 ROM types: n64, v64, z64
41 | * better ROM validation
42 | * move level table to 0x7FC000 to potentially support (E) in future
43 | * add "Save & Run" menu option
44 | * add controls and better listing of header data
45 |
46 | 0.0.1: Initial release
47 | * supports vehicles, carrier, TNT, RDUs, ammo, comm. point, buildings
48 | * renders collision mods and bounds
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | 0.0.5:
2 | Export "All" into one .obj
3 | Add .mtl for all collision, wall, and terrain types
4 | Align level end offsets
5 | 3D Level Display
6 | Fix controls in 3D view
7 | - numpad snap to faces, move
8 | - m0, m1, m2
9 | - quat?
10 | * Support (J) ROM
11 | * DMA table to RAM
12 |
13 | 0.0.6:
14 | PropertyGrid for object properties?
15 | Vehicle / Building 3D preview & export
16 | Texture replacement?
17 |
--------------------------------------------------------------------------------