"Open Map in current WAD" action now works much faster.

This commit is contained in:
MaxED 2013-07-25 12:39:40 +00:00
parent 3a4876704a
commit b8900b36dd
7 changed files with 546 additions and 16 deletions

View file

@ -796,6 +796,12 @@
<Compile Include="Types\ThingClassHandler.cs" />
<Compile Include="Types\ThingTypeHandler.cs" />
<Compile Include="VisualModes\VisualVertex.cs" />
<Compile Include="Windows\ChangeMapForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\ChangeMapForm.Designer.cs">
<DependentUpon>ChangeMapForm.cs</DependentUpon>
</Compile>
<Compile Include="Windows\ErrorsForm.cs">
<SubType>Form</SubType>
</Compile>
@ -1033,6 +1039,9 @@
<SubType>Designer</SubType>
<DependentUpon>BitFlagsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Windows\ChangeMapForm.resx">
<DependentUpon>ChangeMapForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Windows\CustomFieldsForm.resx">
<SubType>Designer</SubType>
<DependentUpon>CustomFieldsForm.cs</DependentUpon>

View file

@ -1126,23 +1126,67 @@ namespace CodeImp.DoomBuilder
}
//mxd
// This loads a map from file
// This loads a different map from same wad file
[BeginAction("openmapincurrentwad")]
internal static void OpenMapInCurrentWad() {
if (map == null || string.IsNullOrEmpty(map.FilePathName) || !File.Exists(map.FilePathName)){
General.Interface.DisplayStatus(StatusType.Warning, "Unable to open map form current WAD!");
Interface.DisplayStatus(StatusType.Warning, "Unable to open map form current WAD!");
return;
}
// Update main window
mainwindow.Update();
// Cancel volatile mode, if any
Editing.DisengageVolatileMode();
// Open map file
OpenMapFile(map.FilePathName, null);
// Ask the user to save changes (if any)
if(!AskSaveMap()) return;
// Open map options dialog
ChangeMapForm changemapwindow = new ChangeMapForm(map.FilePathName, map.Options);
if(changemapwindow.ShowDialog(mainwindow) != DialogResult.OK) return;
// Display status
mainwindow.DisplayStatus(StatusType.Busy, "Switching to map '" + changemapwindow.Options.CurrentName + "'...");
WriteLogLine("Switching to map '" + changemapwindow.Options.CurrentName + "'...");
Cursor.Current = Cursors.WaitCursor;
// Clear the display
mainwindow.ClearDisplay();
// Let the plugins know
plugins.OnMapOpenBegin();
// Clear old errors
ErrorLogger.Clear();
if(!map.InitializeSwitchMap(changemapwindow.Options)) return;
// Let the plugins know
plugins.OnMapOpenEnd();
// All done
settings.FindDefaultDrawSettings();
mainwindow.SetupInterface();
mainwindow.RedrawDisplay();
mainwindow.UpdateThingsFilters();
mainwindow.UpdateInterface();
mainwindow.HideInfo();
//mxd
mainwindow.UpdateGZDoomPanel();
General.Settings.GZForceDefaultTextures = false;
Settings.GZForceDefaultTextures = false;
if (errorlogger.IsErrorAdded)
{
// Show any errors if preferred
mainwindow.DisplayStatus(StatusType.Warning, "There were errors during loading!");
if (!delaymainwindow && Settings.ShowErrorsWindow)
mainwindow.ShowErrors();
} else {
mainwindow.DisplayReady();
}
Cursor.Current = Cursors.Default;
}
// This opens the specified file
@ -1183,9 +1227,8 @@ namespace CodeImp.DoomBuilder
// Let the plugins know
plugins.OnMapOpenBegin();
// Set this to false so we can see if errors are added
//General.ErrorLogger.IsErrorAdded = false;
General.ErrorLogger.Clear();//mxd
// mxd. Clear old errors
General.ErrorLogger.Clear();
// Create map manager with given options
map = new MapManager();

View file

@ -221,10 +221,9 @@ namespace CodeImp.DoomBuilder {
isdisposed = true;
return true;
}
else {
// Already closed
return true;
}
// Already closed
return true;
}
#endregion
@ -447,6 +446,84 @@ namespace CodeImp.DoomBuilder {
return true;
}
//mxd. This switches to another map in the same wad
internal bool InitializeSwitchMap(MapOptions options) {
this.changed = false;
this.options = options;
// Create map data
MapSet newmap = new MapSet();
// Create temp wadfile
string tempfile = General.MakeTempFilename(temppath);
General.WriteLogLine("Creating temporary file: " + tempfile);
if(tempwad != null) tempwad.Dispose();
#if DEBUG
tempwad = new WAD(tempfile);
#else
try { tempwad = new WAD(tempfile); }
catch(Exception e)
{
General.ShowErrorMessage("Error while creating a temporary wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
return false;
}
#endif
// Now open the map file
General.WriteLogLine("Opening source file: " + filepathname);
#if DEBUG
WAD mapwad = new WAD(filepathname, true);
#else
try { mapwad = new WAD(filepathname, true); }
catch(Exception e)
{
General.ShowErrorMessage("Error while opening source wad file:\n" + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
return false;
}
#endif
// Copy the map lumps to the temp file
General.WriteLogLine("Copying map lumps to temporary file...");
CopyLumpsByType(mapwad, options.CurrentName, tempwad, TEMP_MAP_HEADER, true, true, true, true);
// Close the map file
mapwad.Dispose();
// Read the map from temp file
newmap.BeginAddRemove();
General.WriteLogLine("Initializing map format interface " + config.FormatInterface + "...");
io = MapSetIO.Create(config.FormatInterface, tempwad, this);
General.WriteLogLine("Reading map data structures from file...");
#if DEBUG
newmap = io.Read(newmap, TEMP_MAP_HEADER);
#else
try { newmap = io.Read(newmap, TEMP_MAP_HEADER); }
catch(Exception e)
{
General.ErrorLogger.Add(ErrorType.Error, "Unable to read the map data structures with the specified configuration. " + e.GetType().Name + ": " + e.Message);
General.ShowErrorMessage("Unable to read the map data structures with the specified configuration.", MessageBoxButtons.OK);
return false;
}
#endif
newmap.EndAddRemove();
ChangeMapSet(newmap);
data.UpdateUsedTextures();
//mxd. check script names
UpdateScriptNames();
// Center map in screen
if(General.Editing.Mode is ClassicMode) (General.Editing.Mode as ClassicMode).CenterInScreen();
// Success
this.changed = false;
General.WriteLogLine("Map switching done");
return true;
}
#endregion
#region ================== Save

View file

@ -0,0 +1,125 @@
namespace CodeImp.DoomBuilder.Windows
{
partial class ChangeMapForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
System.Windows.Forms.Label label2;
System.Windows.Forms.ColumnHeader columnHeader1;
this.mapslist = new System.Windows.Forms.ListView();
this.cancel = new System.Windows.Forms.Button();
this.apply = new System.Windows.Forms.Button();
label2 = new System.Windows.Forms.Label();
columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.SuspendLayout();
//
// label2
//
label2.Location = new System.Drawing.Point(12, 9);
label2.Name = "label2";
label2.Size = new System.Drawing.Size(396, 17);
label2.TabIndex = 17;
label2.Text = "Please select the map to load for editing.";
//
// columnHeader1
//
columnHeader1.Text = "Map name";
//
// mapslist
//
this.mapslist.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.mapslist.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
columnHeader1});
this.mapslist.FullRowSelect = true;
this.mapslist.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
this.mapslist.HideSelection = false;
this.mapslist.LabelWrap = false;
this.mapslist.Location = new System.Drawing.Point(12, 29);
this.mapslist.MultiSelect = false;
this.mapslist.Name = "mapslist";
this.mapslist.ShowGroups = false;
this.mapslist.Size = new System.Drawing.Size(396, 116);
this.mapslist.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.mapslist.TabIndex = 18;
this.mapslist.UseCompatibleStateImageBehavior = false;
this.mapslist.View = System.Windows.Forms.View.List;
this.mapslist.DoubleClick += new System.EventHandler(this.mapslist_DoubleClick);
//
// cancel
//
this.cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancel.Location = new System.Drawing.Point(296, 152);
this.cancel.Name = "cancel";
this.cancel.Size = new System.Drawing.Size(112, 25);
this.cancel.TabIndex = 20;
this.cancel.Text = "Cancel";
this.cancel.UseVisualStyleBackColor = true;
this.cancel.Click += new System.EventHandler(this.cancel_Click);
//
// apply
//
this.apply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.apply.Location = new System.Drawing.Point(178, 152);
this.apply.Name = "apply";
this.apply.Size = new System.Drawing.Size(112, 25);
this.apply.TabIndex = 19;
this.apply.Text = "OK";
this.apply.UseVisualStyleBackColor = true;
this.apply.Click += new System.EventHandler(this.apply_Click);
//
// ChangeMapForm
//
this.AcceptButton = this.apply;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.CancelButton = this.cancel;
this.ClientSize = new System.Drawing.Size(420, 183);
this.Controls.Add(this.cancel);
this.Controls.Add(this.apply);
this.Controls.Add(this.mapslist);
this.Controls.Add(label2);
this.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ChangeMapForm";
this.Opacity = 0;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Change Map";
this.Shown += new System.EventHandler(this.ChangeMapForm_Shown);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListView mapslist;
private System.Windows.Forms.Button cancel;
private System.Windows.Forms.Button apply;
}
}

View file

@ -0,0 +1,150 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Map;
namespace CodeImp.DoomBuilder.Windows
{
public partial class ChangeMapForm : DelayedForm
{
private readonly MapOptions options;
private readonly string filepathname;
public MapOptions Options { get { return options; } }
public ChangeMapForm(string filepathname, MapOptions options) {
InitializeComponent();
this.options = options;
this.filepathname = filepathname;
}
private void LoadSettings() {
int scanindex, checkoffset;
int lumpsfound, lumpsrequired = 0;
string lumpname;
WAD wadfile;
// Busy
Cursor.Current = Cursors.WaitCursor;
// Check if the file exists
if(!File.Exists(filepathname))
{
// WAD file does not exist
MessageBox.Show(this, "Could not open the WAD file: The file does not exist.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
this.DialogResult = DialogResult.Cancel;
this.Close();
return;
}
try
{
// Open the WAD file
wadfile = new WAD(filepathname, true);
}
catch(Exception)
{
// Unable to open WAD file (or its config)
MessageBox.Show(this, "Could not open the WAD file for reading. Please make sure the file you selected is valid and is not in use by any other application.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
this.DialogResult = DialogResult.Cancel;
this.Close();
return;
}
// Make an array for the map names
List<ListViewItem> mapnames = new List<ListViewItem>();
// Load this configuration
Configuration cfg = General.LoadGameConfiguration(options.ConfigFile);
// Get the map lump names
IDictionary maplumpnames = cfg.ReadSetting("maplumpnames", new Hashtable());
// Count how many required lumps we have to find
foreach(DictionaryEntry ml in maplumpnames) {
// Ignore the map header (it will not be found because the name is different)
if(ml.Key.ToString() != MapManager.CONFIG_MAP_HEADER) {
// Read lump setting and count it
if(cfg.ReadSetting("maplumpnames." + ml.Key + ".required", false))
lumpsrequired++;
}
}
// Go for all the lumps in the wad
for(scanindex = 0; scanindex < (wadfile.Lumps.Count - 1); scanindex++) {
// Make sure this lump is not part of the map
if(!maplumpnames.Contains(wadfile.Lumps[scanindex].Name)) {
// Reset check
lumpsfound = 0;
checkoffset = 1;
// Continue while still within bounds and lumps are still recognized
while(((scanindex + checkoffset) < wadfile.Lumps.Count) &&
maplumpnames.Contains(wadfile.Lumps[scanindex + checkoffset].Name)) {
// Count the lump when it is marked as required
lumpname = wadfile.Lumps[scanindex + checkoffset].Name;
if(cfg.ReadSetting("maplumpnames." + lumpname + ".required", false))
lumpsfound++;
// Check the next lump
checkoffset++;
}
// Map found? Then add it to the list
if(lumpsfound >= lumpsrequired)
mapnames.Add(new ListViewItem(wadfile.Lumps[scanindex].Name));
}
}
wadfile.Dispose();
// Clear the list and add the new map names
mapslist.BeginUpdate();
mapslist.Items.Clear();
mapslist.Items.AddRange(mapnames.ToArray());
mapslist.Sort();
//select current map
foreach(ListViewItem item in mapslist.Items) {
// Was this item previously selected?
if(item.Text == options.LevelName) {
// Select it again
item.Selected = true;
break;
}
}
mapslist.EndUpdate();
// Done
Cursor.Current = Cursors.Default;
}
private void ChangeMapForm_Shown(object sender, EventArgs e){
LoadSettings();
}
private void mapslist_DoubleClick(object sender, EventArgs e) {
// Click OK
if(mapslist.SelectedItems.Count > 0) apply.PerformClick();
}
private void apply_Click(object sender, EventArgs e) {
options.CurrentName = mapslist.SelectedItems[0].Text;
options.PreviousName = string.Empty;
// Hide window
this.DialogResult = DialogResult.OK;
this.Close();
}
private void cancel_Click(object sender, EventArgs e) {
// Just hide window
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="columnHeader1.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View file

@ -97,7 +97,7 @@ namespace CodeImp.DoomBuilder.Windows
this.strictpatches.AutoSize = true;
this.strictpatches.Location = new System.Drawing.Point(14, 27);
this.strictpatches.Name = "strictpatches";
this.strictpatches.Size = new System.Drawing.Size(352, 18);
this.strictpatches.Size = new System.Drawing.Size(351, 18);
this.strictpatches.TabIndex = 19;
this.strictpatches.Text = "Strictly load patches between P_START and P_END only for this file";
this.strictpatches.UseVisualStyleBackColor = true;
@ -160,7 +160,7 @@ namespace CodeImp.DoomBuilder.Windows
this.mapslist.MultiSelect = false;
this.mapslist.Name = "mapslist";
this.mapslist.ShowGroups = false;
this.mapslist.Size = new System.Drawing.Size(396, 110);
this.mapslist.Size = new System.Drawing.Size(396, 118);
this.mapslist.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.mapslist.TabIndex = 1;
this.mapslist.UseCompatibleStateImageBehavior = false;