diff --git a/Build/Configurations/Includes/ZDoom_linedefs.cfg b/Build/Configurations/Includes/ZDoom_linedefs.cfg
index 8176a7bf..56ad3112 100644
--- a/Build/Configurations/Includes/ZDoom_linedefs.cfg
+++ b/Build/Configurations/Includes/ZDoom_linedefs.cfg
@@ -3372,7 +3372,7 @@ zdoom
{
1 = "Disable light effects";
2 = "Restrict light inside";
- 4 = "Fog effect (GZDoom) / Fade effect (ZDoom)";
+ 4 = "Fog effect (GZDoom only)";
8 = "Ignore bottom height";
16 = "Use upper texture";
32 = "Use lower texture";
diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index 019fc99d..55ca8445 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -1021,6 +1021,7 @@
+
diff --git a/Source/Core/Config/ScriptConfiguration.cs b/Source/Core/Config/ScriptConfiguration.cs
index 602317f1..1d73c45a 100644
--- a/Source/Core/Config/ScriptConfiguration.cs
+++ b/Source/Core/Config/ScriptConfiguration.cs
@@ -42,6 +42,7 @@ namespace CodeImp.DoomBuilder.Config
ANIMDEFS = 9,
REVERBS = 10,
TERRAIN = 11,
+ X11R6RGB = 12,
}
internal class ScriptConfiguration : IComparable
diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs
index d55087b4..c7d7358b 100644
--- a/Source/Core/Data/DataManager.cs
+++ b/Source/Core/Data/DataManager.cs
@@ -97,6 +97,7 @@ namespace CodeImp.DoomBuilder.Data
private string[] soundsequences;
private string[] terrainnames;
private string[] damagetypes;
+ private Dictionary knowncolors; // Colors parsed from X11R6RGB lump. Color names are lowercase without spaces
//mxd. Text resources
private Dictionary> textresources;
@@ -156,6 +157,7 @@ namespace CodeImp.DoomBuilder.Data
public string[] SoundSequences { get { return soundsequences; } }
public string[] TerrainNames { get { return terrainnames; } }
public string[] DamageTypes { get { return damagetypes; } }
+ public Dictionary KnownColors { get { return knowncolors; } }
internal Dictionary> TextResources { get { return textresources; } }
//mxd
@@ -326,6 +328,7 @@ namespace CodeImp.DoomBuilder.Data
terrainnames = new string[0];
textresources = new Dictionary>();
damagetypes = new string[0];
+ knowncolors = new Dictionary(StringComparer.OrdinalIgnoreCase);
// Load texture sets
foreach(DefinedTextureSet ts in General.Map.ConfigSettings.TextureSets)
@@ -386,6 +389,7 @@ namespace CodeImp.DoomBuilder.Data
}
// Load stuff
+ LoadX11R6RGB(); //mxd
LoadPalette();
Dictionary cachedparsers = new Dictionary(); //mxd
int texcount = LoadTextures(texturesonly, texturenamesshorttofull, cachedparsers);
@@ -588,6 +592,7 @@ namespace CodeImp.DoomBuilder.Data
terrainnames = null; //mxd
textresources = null; //mxd
damagetypes = null; //mxd
+ knowncolors = null; //mxd
texturenames = null;
flatnames = null;
imageque = null;
@@ -801,10 +806,7 @@ namespace CodeImp.DoomBuilder.Data
}
while(true);
}
- catch(ThreadInterruptedException)
- {
- return;
- }
+ catch(ThreadInterruptedException) { }
}
// This adds an image for background loading or unloading
@@ -2460,6 +2462,34 @@ namespace CodeImp.DoomBuilder.Data
terrainnames = names.ToArray();
}
+ //mxd. This loads X11R6RGB
+ private void LoadX11R6RGB()
+ {
+ X11R6RGBParser parser = new X11R6RGBParser();
+
+ foreach(DataReader dr in containers)
+ {
+ currentreader = dr;
+ IEnumerable streams = dr.GetX11R6RGBData();
+
+ // Parse the data
+ foreach(TextResourceData data in streams)
+ {
+ parser.Parse(data, true);
+
+ // Report errors?
+ if(parser.HasError) parser.LogError();
+ }
+ }
+
+ // Add to text resources collection
+ textresources[parser.ScriptType] = new HashSet(parser.TextResources.Values);
+ currentreader = null;
+
+ // Set as collection
+ knowncolors = parser.KnownColors;
+ }
+
//mxd
internal TextResourceData GetTextResourceData(string name)
{
diff --git a/Source/Core/Data/DataReader.cs b/Source/Core/Data/DataReader.cs
index cfb2a870..fa4c9d20 100644
--- a/Source/Core/Data/DataReader.cs
+++ b/Source/Core/Data/DataReader.cs
@@ -240,6 +240,9 @@ namespace CodeImp.DoomBuilder.Data
//mxd. When implemented, this returns the TERRAIN lump
public abstract IEnumerable GetTerrainData();
+ //mxd. When implemented, this returns the X11R6RGB lump
+ public abstract IEnumerable GetX11R6RGBData();
+
//mxd. When implemented, this returns the list of voxel model names
public abstract IEnumerable GetVoxelNames();
diff --git a/Source/Core/Data/PK3StructuredReader.cs b/Source/Core/Data/PK3StructuredReader.cs
index 913dc57b..f73ff012 100644
--- a/Source/Core/Data/PK3StructuredReader.cs
+++ b/Source/Core/Data/PK3StructuredReader.cs
@@ -701,7 +701,6 @@ namespace CodeImp.DoomBuilder.Data
#region ================== TERRAIN (mxd)
- //mxd
public override IEnumerable GetTerrainData()
{
// Error when suspended
@@ -722,6 +721,28 @@ namespace CodeImp.DoomBuilder.Data
#endregion
+ #region ================== XBRSBSBB11 (mxd)
+
+ public override IEnumerable GetX11R6RGBData()
+ {
+ // Error when suspended
+ if(issuspended) throw new Exception("Data reader is suspended");
+
+ List result = new List();
+ string[] files = GetAllFilesWithTitle("", "X11R6RGB", false);
+
+ // Add to collection
+ foreach(string s in files)
+ result.Add(new TextResourceData(this, LoadFile(s), s, true));
+
+ // Find in any of the wad files
+ foreach(WADReader wr in wads) result.AddRange(wr.GetTerrainData());
+
+ return result;
+ }
+
+ #endregion
+
#region ================== Methods
// This loads the images in this directory
diff --git a/Source/Core/Data/TEXTURESImage.cs b/Source/Core/Data/TEXTURESImage.cs
index c39986bd..857e11f7 100644
--- a/Source/Core/Data/TEXTURESImage.cs
+++ b/Source/Core/Data/TEXTURESImage.cs
@@ -98,7 +98,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Add it
patches.Add(patch);
- if(patch.lumpname == Name) hasPatchWithSameName = true; //mxd
+ if(patch.LumpName == Name) hasPatchWithSameName = true; //mxd
}
// This loads the image
@@ -143,11 +143,11 @@ namespace CodeImp.DoomBuilder.Data
foreach(TexturePatch p in patches)
{
//mxd. Some patches (like "TNT1A0") should be skipped
- if(p.skip) continue;
+ if(p.Skip) continue;
// Get the patch data stream
string patchlocation = string.Empty; //mxd
- Stream patchdata = General.Map.Data.GetPatchData(p.lumpname, p.haslongname, ref patchlocation);
+ Stream patchdata = General.Map.Data.GetPatchData(p.LumpName, p.HasLongName, ref patchlocation);
if(patchdata != null)
{
// Copy patch data to memory
@@ -170,7 +170,7 @@ namespace CodeImp.DoomBuilder.Data
if(reader is UnknownImageReader)
{
// Data is in an unknown format!
- General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.lumpname) + "\" data format could not be read, while loading texture \"" + this.Name + "\"");
+ General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.LumpName) + "\" data format could not be read, while loading texture \"" + this.Name + "\"");
missingpatches++; //mxd
}
}
@@ -184,7 +184,7 @@ namespace CodeImp.DoomBuilder.Data
catch(InvalidDataException)
{
// Data cannot be read!
- General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + p.lumpname + "\" data format could not be read, while loading texture \"" + this.Name + "\"");
+ General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + p.LumpName + "\" data format could not be read, while loading texture \"" + this.Name + "\"");
missingpatches++; //mxd
}
@@ -194,7 +194,7 @@ namespace CodeImp.DoomBuilder.Data
patchbmp = TransformPatch(p, patchbmp);
// Draw the patch on the texture image
- Rectangle tgtrect = new Rectangle(p.x, p.y, patchbmp.Size.Width, patchbmp.Size.Height);
+ Rectangle tgtrect = new Rectangle(p.X, p.Y, patchbmp.Size.Width, patchbmp.Size.Height);
g.DrawImageUnscaledAndClipped(patchbmp, tgtrect);
patchbmp.Dispose();
}
@@ -208,7 +208,7 @@ namespace CodeImp.DoomBuilder.Data
//mxd. ZDoom can use any known graphic as patch
if(General.Map.Config.MixTexturesFlats)
{
- ImageData img = General.Map.Data.GetTextureImage(p.lumpname);
+ ImageData img = General.Map.Data.GetTextureImage(p.LumpName);
if(!(img is UnknownImage) && img != this)
{
if(!img.IsImageLoaded) img.LoadImage();
@@ -217,7 +217,7 @@ namespace CodeImp.DoomBuilder.Data
Bitmap patchbmp = TransformPatch(p, new Bitmap(img.GetBitmap()));
// Draw the patch on the texture image
- Rectangle tgtrect = new Rectangle(p.x, p.y, patchbmp.Size.Width, patchbmp.Size.Height);
+ Rectangle tgtrect = new Rectangle(p.X, p.Y, patchbmp.Size.Width, patchbmp.Size.Height);
g.DrawImageUnscaledAndClipped(patchbmp, tgtrect);
patchbmp.Dispose();
@@ -226,7 +226,7 @@ namespace CodeImp.DoomBuilder.Data
}
// Missing a patch lump!
- General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump \"" + p.lumpname + "\" while loading texture \"" + this.Name + "\"");
+ General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump \"" + p.LumpName + "\" while loading texture \"" + this.Name + "\"");
missingpatches++; //mxd
}
}
@@ -249,20 +249,20 @@ namespace CodeImp.DoomBuilder.Data
private Bitmap TransformPatch(TexturePatch p, Bitmap patchbmp)
{
//mxd. Flip
- if(p.flipx || p.flipy)
+ if(p.FlipX || p.FlipY)
{
RotateFlipType flip;
- if(p.flipx && !p.flipy) flip = RotateFlipType.RotateNoneFlipX;
- else if(!p.flipx && p.flipy) flip = RotateFlipType.RotateNoneFlipY;
+ if(p.FlipX && !p.FlipY) flip = RotateFlipType.RotateNoneFlipX;
+ else if(!p.FlipX && p.FlipY) flip = RotateFlipType.RotateNoneFlipY;
else flip = RotateFlipType.RotateNoneFlipXY;
patchbmp.RotateFlip(flip);
}
//mxd. Then rotate. I do it this way because RotateFlip function rotates THEN flips, and GZDoom does it the other way around.
- if(p.rotate != 0)
+ if(p.Rotate != 0)
{
RotateFlipType rotate;
- switch(p.rotate)
+ switch(p.Rotate)
{
case 90: rotate = RotateFlipType.Rotate90FlipNone; break;
case 180: rotate = RotateFlipType.Rotate180FlipNone; break;
@@ -272,7 +272,7 @@ namespace CodeImp.DoomBuilder.Data
}
// Adjust patch alpha, apply tint or blend
- if(p.blendstyle != TexturePathBlendStyle.None || p.style != TexturePathRenderStyle.Copy)
+ if(p.BlendStyle != TexturePathBlendStyle.NONE || p.RenderStyle != TexturePathRenderStyle.COPY)
{
BitmapData bmpdata = null;
@@ -282,61 +282,61 @@ namespace CodeImp.DoomBuilder.Data
}
catch(Exception e)
{
- General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image \"" + p.lumpname + "\" for alpha adjustment. " + e.GetType().Name + ": " + e.Message);
+ General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image \"" + p.LumpName + "\" for alpha adjustment. " + e.GetType().Name + ": " + e.Message);
}
if(bmpdata != null)
{
PixelColor* pixels = (PixelColor*)(bmpdata.Scan0.ToPointer());
int numpixels = bmpdata.Width * bmpdata.Height;
- int patchalpha = (int)Math.Round(General.Clamp(p.alpha, 0f, 1f) * 255); //convert alpha to [0-255] range
+ int patchalpha = (int)Math.Round(General.Clamp(p.Alpha, 0f, 1f) * 255); //convert alpha to [0-255] range
//mxd. Blend/Tint support
- if(p.blendstyle == TexturePathBlendStyle.Blend)
+ if(p.BlendStyle == TexturePathBlendStyle.BLEND)
{
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
- cp->r = (byte)((cp->r * p.blend.r) * PixelColor.BYTE_TO_FLOAT);
- cp->g = (byte)((cp->g * p.blend.g) * PixelColor.BYTE_TO_FLOAT);
- cp->b = (byte)((cp->b * p.blend.b) * PixelColor.BYTE_TO_FLOAT);
+ cp->r = (byte)((cp->r * p.BlendColor.r) * PixelColor.BYTE_TO_FLOAT);
+ cp->g = (byte)((cp->g * p.BlendColor.g) * PixelColor.BYTE_TO_FLOAT);
+ cp->b = (byte)((cp->b * p.BlendColor.b) * PixelColor.BYTE_TO_FLOAT);
}
}
- else if(p.blendstyle == TexturePathBlendStyle.Tint)
+ else if(p.BlendStyle == TexturePathBlendStyle.TINT)
{
- float tintammount = p.tintammount - 0.1f;
+ float tintammount = p.BlendColor.a * PixelColor.BYTE_TO_FLOAT;// -0.1f;
if(tintammount > 0)
{
- float br = p.blend.r * PixelColor.BYTE_TO_FLOAT * tintammount;
- float bg = p.blend.g * PixelColor.BYTE_TO_FLOAT * tintammount;
- float bb = p.blend.b * PixelColor.BYTE_TO_FLOAT * tintammount;
- float invTint = 1.0f - tintammount;
+ float br = p.BlendColor.r * PixelColor.BYTE_TO_FLOAT * tintammount;
+ float bg = p.BlendColor.g * PixelColor.BYTE_TO_FLOAT * tintammount;
+ float bb = p.BlendColor.b * PixelColor.BYTE_TO_FLOAT * tintammount;
+ float invtintammount = 1.0f - tintammount;
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
- cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * invTint + br) * 255.0f);
- cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * invTint + bg) * 255.0f);
- cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * invTint + bb) * 255.0f);
+ cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * invtintammount + br) * 255.0f);
+ cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * invtintammount + bg) * 255.0f);
+ cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * invtintammount + bb) * 255.0f);
}
}
}
//mxd. Apply RenderStyle
- if(p.style == TexturePathRenderStyle.Blend)
+ if(p.RenderStyle == TexturePathRenderStyle.BLEND)
{
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
}
//mxd. We need a copy of underlying part of texture for these styles
- else if(p.style != TexturePathRenderStyle.Copy)
+ else if(p.RenderStyle != TexturePathRenderStyle.COPY)
{
// Copy portion of texture
- int lockWidth = (p.x + patchbmp.Size.Width > bitmap.Width) ? bitmap.Width - p.x : patchbmp.Size.Width;
- int lockHeight = (p.y + patchbmp.Size.Height > bitmap.Height) ? bitmap.Height - p.y : patchbmp.Size.Height;
+ int lockWidth = (p.X + patchbmp.Size.Width > bitmap.Width) ? bitmap.Width - p.X : patchbmp.Size.Width;
+ int lockHeight = (p.Y + patchbmp.Size.Height > bitmap.Height) ? bitmap.Height - p.Y : patchbmp.Size.Height;
Bitmap source = new Bitmap(patchbmp.Size.Width, patchbmp.Size.Height);
using(Graphics sg = Graphics.FromImage(source))
- sg.DrawImageUnscaled(bitmap, new Rectangle(-p.x, -p.y, lockWidth, lockHeight));
+ sg.DrawImageUnscaled(bitmap, new Rectangle(-p.X, -p.Y, lockWidth, lockHeight));
// Lock texture
BitmapData texturebmpdata = null;
@@ -355,9 +355,9 @@ namespace CodeImp.DoomBuilder.Data
PixelColor* texturepixels = (PixelColor*)(texturebmpdata.Scan0.ToPointer());
PixelColor* tcp = texturepixels + numpixels - 1;
- switch(p.style)
+ switch(p.RenderStyle)
{
- case TexturePathRenderStyle.Add:
+ case TexturePathRenderStyle.ADD:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
cp->r = (byte)Math.Min(255, cp->r + tcp->r);
@@ -368,7 +368,7 @@ namespace CodeImp.DoomBuilder.Data
}
break;
- case TexturePathRenderStyle.Subtract:
+ case TexturePathRenderStyle.SUBTRACT:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
cp->r = (byte)Math.Max(0, tcp->r - cp->r);
@@ -379,7 +379,7 @@ namespace CodeImp.DoomBuilder.Data
}
break;
- case TexturePathRenderStyle.ReverseSubtract:
+ case TexturePathRenderStyle.REVERSE_SUBTRACT:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
cp->r = (byte)Math.Max(0, cp->r - tcp->r);
@@ -390,7 +390,7 @@ namespace CodeImp.DoomBuilder.Data
}
break;
- case TexturePathRenderStyle.Modulate:
+ case TexturePathRenderStyle.MODULATE:
for(PixelColor* cp = pixels + numpixels - 1; cp >= pixels; cp--)
{
cp->r = (byte)((cp->r * tcp->r) * PixelColor.BYTE_TO_FLOAT);
diff --git a/Source/Core/Data/TextureImage.cs b/Source/Core/Data/TextureImage.cs
index 3866974d..cd110dc3 100644
--- a/Source/Core/Data/TextureImage.cs
+++ b/Source/Core/Data/TextureImage.cs
@@ -64,7 +64,7 @@ namespace CodeImp.DoomBuilder.Data
// Add it
patches.Add(patch);
- if(patch.lumpname == Name) hasPatchWithSameName = true; //mxd
+ if(patch.LumpName == Name) hasPatchWithSameName = true; //mxd
}
// This loads the image
@@ -103,7 +103,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Get the patch data stream
string patchlocation = string.Empty; //mxd
- Stream patchdata = General.Map.Data.GetPatchData(p.lumpname, p.haslongname, ref patchlocation);
+ Stream patchdata = General.Map.Data.GetPatchData(p.LumpName, p.HasLongName, ref patchlocation);
if(patchdata != null)
{
// Copy patch data to memory
@@ -125,7 +125,7 @@ namespace CodeImp.DoomBuilder.Data
if(reader is UnknownImageReader)
{
// Data is in an unknown format!
- General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.lumpname) + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?");
+ General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.LumpName) + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?");
loadfailed = true;
missingpatches++; //mxd
}
@@ -135,11 +135,11 @@ namespace CodeImp.DoomBuilder.Data
{
// Draw the patch
mem.Seek(0, SeekOrigin.Begin);
- try { reader.DrawToPixelData(mem, pixels, width, height, p.x, p.y); }
+ try { reader.DrawToPixelData(mem, pixels, width, height, p.X, p.Y); }
catch(InvalidDataException)
{
// Data cannot be read!
- General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + p.lumpname + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?");
+ General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + p.LumpName + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?");
loadfailed = true;
missingpatches++; //mxd
}
@@ -151,7 +151,7 @@ namespace CodeImp.DoomBuilder.Data
else
{
// Missing a patch lump!
- General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump \"" + p.lumpname + "\" while loading texture \"" + this.Name + "\". Did you forget to include required resources?");
+ General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump \"" + p.LumpName + "\" while loading texture \"" + this.Name + "\". Did you forget to include required resources?");
loadfailed = true;
missingpatches++; //mxd
}
diff --git a/Source/Core/Data/TexturePatch.cs b/Source/Core/Data/TexturePatch.cs
index 1d71d24a..7820cc28 100644
--- a/Source/Core/Data/TexturePatch.cs
+++ b/Source/Core/Data/TexturePatch.cs
@@ -26,93 +26,90 @@ namespace CodeImp.DoomBuilder.Data
{
public enum TexturePathRenderStyle
{
- Copy,
- Blend,
- Add,
- Subtract,
- ReverseSubtract,
- Modulate,
- CopyAlpha,
- CopyNewAlpha, //mxd
- Overlay, //mxd
+ COPY,
+ BLEND,
+ ADD,
+ SUBTRACT,
+ REVERSE_SUBTRACT,
+ MODULATE,
+ COPY_ALPHA,
+ COPY_NEW_ALPHA, //mxd
+ OVERLAY, //mxd
}
public enum TexturePathBlendStyle //mxd
{
- None,
- Blend,
- Tint
+ NONE,
+ BLEND,
+ TINT
}
internal struct TexturePatch
{
- public readonly string lumpname;
- public readonly int x;
- public readonly int y;
- public readonly bool flipx;
- public readonly bool flipy;
- public readonly bool haslongname; //mxd
- public readonly int rotate;
- public PixelColor blend;
- public readonly float alpha;
- public readonly TexturePathRenderStyle style;
- public readonly TexturePathBlendStyle blendstyle; //mxd
- public readonly float tintammount;//mxd
- public readonly bool skip; //mxd
+ public readonly string LumpName;
+ public readonly int X;
+ public readonly int Y;
+ public readonly bool FlipX;
+ public readonly bool FlipY;
+ public readonly bool HasLongName; //mxd
+ public readonly int Rotate;
+ public PixelColor BlendColor;
+ public readonly float Alpha;
+ public readonly TexturePathRenderStyle RenderStyle;
+ public readonly TexturePathBlendStyle BlendStyle; //mxd
+ public readonly bool Skip; //mxd
// Constructor for simple patches
public TexturePatch(string lumpname, int x, int y)
{
// Initialize
- this.lumpname = lumpname;
- this.x = x;
- this.y = y;
- this.flipx = false;
- this.flipy = false;
- this.rotate = 0;
- this.blend = new PixelColor(0, 0, 0, 0);
- this.alpha = 1.0f;
- this.style = TexturePathRenderStyle.Copy;
- this.blendstyle = TexturePathBlendStyle.None;//mxd
- this.tintammount = 0; //mxd
- this.haslongname = false; //mxd
- this.skip = false; //mxd
+ this.LumpName = lumpname;
+ this.X = x;
+ this.Y = y;
+ this.FlipX = false;
+ this.FlipY = false;
+ this.Rotate = 0;
+ this.BlendColor = new PixelColor(0, 0, 0, 0);
+ this.Alpha = 1.0f;
+ this.RenderStyle = TexturePathRenderStyle.COPY;
+ this.BlendStyle = TexturePathBlendStyle.NONE;//mxd
+ this.HasLongName = false; //mxd
+ this.Skip = false; //mxd
}
//mxd. Constructor for hires patches
public TexturePatch(PatchStructure patch)
{
// Initialize
- this.lumpname = patch.Name.ToUpperInvariant();
- this.x = patch.OffsetX;
- this.y = patch.OffsetY;
- this.flipx = patch.FlipX;
- this.flipy = patch.FlipY;
- this.rotate = patch.Rotation;
- this.blend = patch.BlendColor;
- this.alpha = patch.Alpha;
- this.style = patch.RenderStyle;
- this.blendstyle = patch.BlendStyle;
- this.tintammount = patch.TintAmmount;
- this.haslongname = (Path.GetFileNameWithoutExtension(this.lumpname) != this.lumpname);
- this.skip = patch.Skip;
+ this.LumpName = patch.Name.ToUpperInvariant();
+ this.X = patch.OffsetX;
+ this.Y = patch.OffsetY;
+ this.FlipX = patch.FlipX;
+ this.FlipY = patch.FlipY;
+ this.Rotate = patch.Rotation;
+ this.BlendColor = patch.BlendColor;
+ this.Alpha = patch.Alpha;
+ this.RenderStyle = patch.RenderStyle;
+ this.BlendStyle = patch.BlendStyle;
+ this.HasLongName = (Path.GetFileNameWithoutExtension(this.LumpName) != this.LumpName);
+ this.Skip = patch.Skip;
//mxd. Check data so we don't perform unneeded operations later on
- if(this.alpha == 1.0f)
+ if(this.Alpha == 1.0f)
{
- switch(this.style)
+ switch(this.RenderStyle)
{
- case TexturePathRenderStyle.Blend:
- case TexturePathRenderStyle.CopyAlpha:
- case TexturePathRenderStyle.CopyNewAlpha:
- case TexturePathRenderStyle.Overlay:
- this.style = TexturePathRenderStyle.Copy;
+ case TexturePathRenderStyle.BLEND:
+ case TexturePathRenderStyle.COPY_ALPHA:
+ case TexturePathRenderStyle.COPY_NEW_ALPHA:
+ case TexturePathRenderStyle.OVERLAY:
+ this.RenderStyle = TexturePathRenderStyle.COPY;
break;
}
}
//mxd. and get rid of render styles we don't support
- if(this.style == TexturePathRenderStyle.Overlay) this.style = TexturePathRenderStyle.Copy;
+ if(this.RenderStyle == TexturePathRenderStyle.OVERLAY) this.RenderStyle = TexturePathRenderStyle.COPY;
}
}
}
diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs
index 51591f63..a79b52ee 100644
--- a/Source/Core/Data/WADReader.cs
+++ b/Source/Core/Data/WADReader.cs
@@ -1015,6 +1015,13 @@ namespace CodeImp.DoomBuilder.Data
return GetAllLumps("TERRAIN");
}
+ //mxd
+ public override IEnumerable GetX11R6RGBData()
+ {
+ if(issuspended) throw new Exception("Data reader is suspended");
+ return GetAllLumps("X11R6RGB");
+ }
+
//mxd
private IEnumerable GetFirstLump(string name)
{
diff --git a/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs b/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs
index 1d3b76a4..9ab80845 100644
--- a/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs
+++ b/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs
@@ -2,12 +2,11 @@
using System;
using System.Collections.Generic;
-using System.Drawing;
using System.Globalization;
using System.IO;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Data;
-using SlimDX;
+using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.ZDoom;
using CodeImp.DoomBuilder.GZBuilder.Data;
@@ -607,16 +606,15 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
ReportError("Expected " + fadetype + " color value");
return false;
}
-
- Color4 color = new Color4();
// Try to get the color...
- if(GetColor(colorval, ref color))
+ PixelColor color = new PixelColor();
+ if(GetColorFromString(colorval, ref color))
{
if(fadetype == "fade")
- mapinfo.FadeColor = color;
+ mapinfo.FadeColor = color.ToColorValue();
else
- mapinfo.OutsideFogColor = color;
+ mapinfo.OutsideFogColor = color.ToColorValue();
}
else //...or not
{
@@ -687,30 +685,5 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
#endregion
- #region ================== Methods
-
- private static bool GetColor(string name, ref Color4 color)
- {
- if(name == "black") return true;
-
- //probably it's a hex color (like FFCC11)?
- int ci;
- if(int.TryParse(name, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ci))
- {
- color = new Color4(ci) {Alpha = 1.0f};
- return true;
- }
-
- //probably it's a color name?
- Color c = Color.FromName(name); //should be similar to C++ color name detection, I suppose
- if(c.IsKnownColor)
- {
- color = new Color4(c);
- return true;
- }
- return false;
- }
-
- #endregion
}
}
diff --git a/Source/Core/GZBuilder/Windows/ExceptionDialog.cs b/Source/Core/GZBuilder/Windows/ExceptionDialog.cs
index bb71e7e7..283e8e67 100644
--- a/Source/Core/GZBuilder/Windows/ExceptionDialog.cs
+++ b/Source/Core/GZBuilder/Windows/ExceptionDialog.cs
@@ -12,34 +12,34 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
{
public partial class ExceptionDialog : Form
{
- private readonly bool cannotContinue;
- private readonly string logPath;
+ private readonly bool isterminating;
+ private readonly string logpath;
public ExceptionDialog(UnhandledExceptionEventArgs e)
{
InitializeComponent();
- logPath = Path.Combine(General.SettingsPath, @"GZCrash.txt");
+ logpath = Path.Combine(General.SettingsPath, @"GZCrash.txt");
Exception ex = (Exception)e.ExceptionObject;
errorDescription.Text = "Error in " + ex.Source + ":";
string sysinfo = GetSystemInfo();
- using(StreamWriter sw = File.CreateText(logPath))
+ using(StreamWriter sw = File.CreateText(logpath))
{
sw.Write(sysinfo + GetExceptionDescription(ex));
}
errorMessage.Text = ex.Message + Environment.NewLine + ex.StackTrace;
- cannotContinue = true; //cannot recover from this...
+ isterminating = e.IsTerminating; // Recoverable?
}
public ExceptionDialog(ThreadExceptionEventArgs e)
{
InitializeComponent();
- logPath = Path.Combine(General.SettingsPath, @"GZCrash.txt");
+ logpath = Path.Combine(General.SettingsPath, @"GZCrash.txt");
errorDescription.Text = "Error in " + e.Exception.Source + ":";
string sysinfo = GetSystemInfo();
- using(StreamWriter sw = File.CreateText(logPath))
+ using(StreamWriter sw = File.CreateText(logpath))
{
sw.Write(sysinfo + GetExceptionDescription(e.Exception));
}
@@ -50,78 +50,92 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
public void Setup()
{
- bContinue.Enabled = !cannotContinue;
+ string[] titles =
+ {
+ "0x000000 at 0xFFFFFF. That's probaby bad",
+ "Here we go again...",
+ "Uh oh, you're screwed",
+ "All is lost!",
+ "Achievement unlocked: CRASH TIME!",
+ "OH NOES! TEH ERROR!",
+ "0001000001111011000000000011001101011120110111",
+ "Nuclear launch detected!",
+ "Don't send this to Microsoft",
+ "You. Shall. Not. Pass!!!",
+ "Yep, we have bugs",
+ "It's dangerous to go alone. Take this!",
+ "The operation completed successfully",
+ "Security Alert – Moving cursor is not as safe as you thought",
+ "Random error appears from north",
+ "ERROR: NO_ERROR",
+ "Epic fail",
+ "At least it's not BSoD...",
+ "User Error. Please Replace User",
+ "Brought to you by MaxED!",
+ "GZDoom Builder proudly presents:",
+ "You aren't expected to understand this",
+ "Back to the drawing board...",
+ "I'm sorry... :(",
+ "This is a horrbble day for you, and of course, the world",
+ "Abort, Retry, Fail?",
+ "You are making progress. I'm afraid that's something I can't allow to happen",
+ "You are making progress. That's not OK",
+ "No errors found, restarting computer",
+ "Does Not Compute!",
+ "I’m sorry, Dave, I’m afraid I can’t do that",
+ "What's that? Chicken?",
+ "It can only be attributable to human error",
+ "It's now safe to turn off your computer",
+ "I've got a bad feeling about this",
+ "YOU CAN’T DO THAT!",
+ "Man the Lifeboats! Women and children first!",
+ "IMPOSSIBURU!!!",
+ "Now deleting all files. Goodbye",
+ "General Failure",
+ "Invalid Error",
+ "Beam me up Scotty, there’s no life out here",
+ "Well, you ran into something and the game is over",
+ "I'm good at writing bad code",
+ "$FUNNY_ERROR_CAPTION",
+ "In Soviet Russia, exception throws YOU!",
+ "...and then GZDB was the demons!",
+ "B U S T E D",
+ "Freeze mode enabled",
+ "You feel strange...",
+ "That doesn't seem to work",
+ "This function is only available in the retail version of GZDoom Builder",
+ "You picked up the Random Exception.",
+ "Pinky says that you're the new hope. Bear that in mind.",
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+ "Deal with it",
+ "Error 47",
+ "YOU DIED",
+ "Thanks, Obama",
+ "The God Of Exceptions Demands MORE Exceptions!",
+ "Good. It's boring here anyway.",
+ "Shameful display!",
+ "It's CRASHENING!",
+ "W-W-W-WIPEOUT!",
+ "EVERYTHING IS LOST!",
+ "Your empty is full!",
+ "Let's see how far this infinite loop goes...",
+ "Windows 10 is here! RUN!",
+ "You really screwed up this time!",
+ "[WFDS]",
+ "[No]",
+ "An error has occurred while creating an error",
+ "Catastrophic failure",
+ "This time, it’s the human’s fault",
+ "No error occurred",
+ "Hey! It looks like you're having an error!",
+ "What, what, what, what, what, what, what, what, what, what?",
+ "WARNING: PROGRAMMING BUG IN GZDB!",
+ "Something happened",
+ "The Device is Error",
+ };
- string[] titles = {
- "0x000000 at 0xFFFFFF. That's probaby bad",
- "Here we go again...",
- "Uh oh, you're screwed",
- "All is lost!",
- "Achievement unlocked: CRASH TIME!",
- "OH NOES! TEH ERROR!",
- "0001000001111011000000000011001101011110110111",
- "Nuclear launch detected!",
- "Don't send this to Microsoft",
- "You. Shall. Not. Pass!!!",
- "Yep, we have bugs",
- "It's dangerous to go alone. Take this!",
- "The operation completed successfully",
- "Security Alert – Moving cursor is not as safe as you thought",
- "Random error appears from north",
- "ERROR: NO_ERROR",
- "Epic fail",
- "At least it's not BSoD...",
- "User Error. Please Replace User",
- "Brought to you by MaxED!",
- "GZDoom Builder proudly presents:",
- "You aren't expected to understand this",
- "Back to the drawing board...",
- "I'm sorry... :(",
- "This is a horrbble day for you, and of course, the world",
- "Abort, Retry, Fail?",
- "You are making progress. I'm afraid that's something I can't allow to happen",
- "You are making progress. That's not OK",
- "No errors found, restarting computer",
- "Does Not Compute!",
- "I’m sorry, Dave, I’m afraid I can’t do that",
- "What's that? Chicken?",
- "It can only be attributable to human error",
- "It's now safe to turn off your computer",
- "I've got a bad feeling about this",
- "YOU CAN’T DO THAT!",
- "Man the Lifeboats! Women and children first!",
- "IMPOSSIBURU!!!",
- "Now deleting all files. Goodbye",
- "General Failure",
- "Invalid Error",
- "Beam me up Scotty, there’s no life out here",
- "Well, you ran into something and the game is over",
- "I'm good at writing bad code",
- "$FUNNY_ERROR_CAPTION",
- "In Soviet Russia, exception throws YOU!",
- "...and then GZDB was the demons!",
- "B U S T E D",
- "Freeze mode enabled",
- "You feel strange...",
- "That doesn't seem to work",
- "This function is only available in the retail version of GZDoom Builder",
- "You picked up the Random Exception.",
- "Pinky says that you're the new hope. Bear that in mind.",
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
- "Deal with it",
- "Error 47",
- "YOU DIED",
- "Thanks, Obama",
- "The God Of Exceptions Demands MORE Exceptions!",
- "Good. It's boring here anyway.",
- "Shameful display!",
- "It's CRASHENING!",
- "W-W-W-WIPEOUT!",
- "EVERYTHING IS LOST!",
- "Your empty is full!",
- "Let's see how far this infinite loop goes...",
- };
this.Text = titles[new Random().Next(0, titles.Length - 1)];
+ bContinue.Enabled = !isterminating;
}
private static string GetSystemInfo()
@@ -181,8 +195,8 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
private void reportLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
- if(!File.Exists(logPath)) return;
- System.Diagnostics.Process.Start("explorer.exe", @"/select, " + logPath);
+ if(!File.Exists(logpath)) return;
+ System.Diagnostics.Process.Start("explorer.exe", @"/select, " + logpath);
reportLink.LinkVisited = true;
}
diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs
index e9e9d308..f1258c2d 100644
--- a/Source/Core/General/General.cs
+++ b/Source/Core/General/General.cs
@@ -2080,70 +2080,64 @@ namespace CodeImp.DoomBuilder
#region ================== mxd. Uncaught exceptions handling
+ // In some cases the program can remain operational after these
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
try
{
+ // Try handling it in user-friendy way...
GZBuilder.Windows.ExceptionDialog dlg = new GZBuilder.Windows.ExceptionDialog(e);
dlg.Setup();
- if(dlg.ShowDialog() == DialogResult.Cancel) Application.Exit();
+ if(dlg.ShowDialog() == DialogResult.Cancel) Terminate(false);
}
- catch
+ catch
{
- try
- {
- MessageBox.Show("Fatal Windows Forms Error", "Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
- }
- finally
- {
- Application.Exit();
- }
+ string exceptionmsg;
+
+ // Try getting exception details...
+ try { exceptionmsg = "Fatal Windows Forms error occurred: " + e.Exception.Message + "\n\nStack Trace:\n" + e.Exception.StackTrace; }
+ catch(Exception exc) { exceptionmsg = "Failed to get initial excepton details: " + exc.Message + "\n\nStack Trace:\n" + exc.StackTrace; }
+
+ // Try logging it...
+ try { WriteLogLine(exceptionmsg); } catch { }
+
+ // Try displaying it to the user...
+ try { MessageBox.Show("Fatal Windows Forms Error", exceptionmsg, MessageBoxButtons.OK, MessageBoxIcon.Stop); }
+ finally { Process.GetCurrentProcess().Kill(); }
}
}
+ // These are usually unrecoverable
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
- string exceptionmsg = string.Empty;
-
- try
+ try
{
- Exception ex = (Exception)e.ExceptionObject;
- exceptionmsg = "An application error occurred: " + ex.Message + "\n\nStack Trace:\n" + ex.StackTrace;
-
- // Since we can't prevent the app from terminating, log this to the event log.
- try
- {
- if(!EventLog.SourceExists("ThreadException"))
- EventLog.CreateEventSource("ThreadException", "Application");
-
- // Create an EventLog instance and assign its source.
- using(EventLog myLog = new EventLog())
- {
- myLog.Source = "ThreadException";
- myLog.WriteEntry(exceptionmsg);
- }
- }
- catch(Exception exc)
- {
- MessageBox.Show("Could not write the error to the event log.\nReason: "
- + exc.Message + "\n\nInitial exception:\n" + exceptionmsg, "Fatal Non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
- }
-
+ // Try handling it in user-friendy way...
GZBuilder.Windows.ExceptionDialog dlg = new GZBuilder.Windows.ExceptionDialog(e);
dlg.Setup();
- dlg.ShowDialog();
- }
- catch(Exception exc)
+ if(dlg.ShowDialog() == DialogResult.Cancel) Terminate(false);
+ }
+ catch
{
- try
+ string exceptionmsg;
+
+ // Try getting exception details...
+ try
{
- MessageBox.Show("Failed to write the error to the event log or to show the Exception Dialog.\n\nReason: "
- + exc.Message + "\n\nInitial exception:\n" + exceptionmsg, "Fatal Non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
- }
- finally
- {
- Application.Exit();
+ Exception ex = (Exception) e.ExceptionObject;
+ exceptionmsg = "Fatal Non-UI error occurred: " + ex.Message + "\n\nStack Trace:\n" + ex.StackTrace;
}
+ catch(Exception exc)
+ {
+ exceptionmsg = "Failed to get initial excepton details: " + exc.Message + "\n\nStack Trace:\n" + exc.StackTrace;
+ }
+
+ // Try logging it...
+ try { WriteLogLine(exceptionmsg); } catch {}
+
+ // Try displaying it to the user...
+ try { MessageBox.Show("Fatal Windows Forms Error", exceptionmsg, MessageBoxButtons.OK, MessageBoxIcon.Stop); }
+ finally { Process.GetCurrentProcess().Kill(); }
}
}
diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs
index 7d21db5d..9e4ab2a9 100644
--- a/Source/Core/General/MapManager.cs
+++ b/Source/Core/General/MapManager.cs
@@ -724,21 +724,22 @@ namespace CodeImp.DoomBuilder
string settingsfile;
WAD targetwad = null;
bool includenodes;
+ bool fileexists = File.Exists(newfilepathname); //mxd
General.WriteLogLine("Saving map to file: " + newfilepathname);
//mxd. Official IWAD check...
- WAD hashtest = new WAD(newfilepathname, true);
- if(hashtest.IsOfficialIWAD)
- {
- General.WriteLogLine("Map saving aborted: attempt to modify official IWAD");
- General.ShowErrorMessage("Official IWADs should not be modified.\nConsider making a PWAD instead", MessageBoxButtons.OK);
- return false;
- }
- else
+ if(fileexists)
{
+ WAD hashtest = new WAD(newfilepathname, true);
+ if(hashtest.IsOfficialIWAD)
+ {
+ General.WriteLogLine("Map saving aborted: attempt to modify an official IWAD");
+ General.ShowErrorMessage("Official IWADs should not be modified.\nConsider making a PWAD instead", MessageBoxButtons.OK);
+ return false;
+ }
+
hashtest.Dispose();
- hashtest = null;
}
// Scripts changed?
@@ -786,79 +787,85 @@ namespace CodeImp.DoomBuilder
}
//mxd. Target file is read-only?
- FileInfo info = new FileInfo(newfilepathname);
- if(info.Exists && info.IsReadOnly)
+ if(fileexists)
{
- if(General.ShowWarningMessage("Unable to save the map: target file is read-only.\nRemove read-only flag and save the map anyway?", MessageBoxButtons.YesNo) == DialogResult.Yes)
+ FileInfo info = new FileInfo(newfilepathname);
+ if(info.IsReadOnly)
{
- General.WriteLogLine("Removing read-only flag from the map file...");
- try
+ if(General.ShowWarningMessage("Unable to save the map: target file is read-only.\nRemove read-only flag and save the map anyway?", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
- info.IsReadOnly = false;
+ General.WriteLogLine("Removing read-only flag from the map file...");
+ try
+ {
+ info.IsReadOnly = false;
+ }
+ catch(Exception e)
+ {
+ General.ShowErrorMessage("Failed to remove read-only flag from \"" + filepathname + "\":" + Environment.NewLine + Environment.NewLine + e.Message, MessageBoxButtons.OK);
+ General.WriteLogLine("Failed to remove read-only flag from \"" + filepathname + "\":" + e.Message);
+ return false;
+ }
}
- catch(Exception e)
+ else
{
- General.ShowErrorMessage("Failed to remove read-only flag from \"" + filepathname + "\":" + Environment.NewLine + Environment.NewLine + e.Message, MessageBoxButtons.OK);
- General.WriteLogLine("Failed to remove read-only flag from \"" + filepathname + "\":" + e.Message);
+ General.WriteLogLine("Map saving cancelled...");
return false;
}
}
- else
- {
- General.WriteLogLine("Map saving cancelled...");
- return false;
- }
}
// Suspend data resources
data.Suspend();
//mxd. Check if the target file is locked
- FileLockChecker.FileLockCheckResult checkresult = FileLockChecker.CheckFile(newfilepathname);
- if(!string.IsNullOrEmpty(checkresult.Error))
+ if(fileexists)
{
- if(checkresult.Processes.Count > 0)
+ FileLockChecker.FileLockCheckResult checkresult = FileLockChecker.CheckFile(newfilepathname);
+ if(!string.IsNullOrEmpty(checkresult.Error))
{
- string rest = "Press 'Retry' to close " + (checkresult.Processes.Count > 1 ? "all processes" : "the process")
- + " and retry." + Environment.NewLine + "Press 'Cancel' to cancel saving.";
-
- if(General.ShowErrorMessage(checkresult.Error + rest, MessageBoxButtons.RetryCancel) == DialogResult.Retry)
+ if(checkresult.Processes.Count > 0)
{
- // Close all processes
- foreach(Process process in checkresult.Processes)
- {
- try
- {
- if(!process.HasExited) process.Kill();
- }
- catch(Exception e)
- {
- General.ShowErrorMessage("Failed to close " + Path.GetFileName(process.MainModule.FileName) + ":" + Environment.NewLine + Environment.NewLine + e.Message, MessageBoxButtons.OK);
- data.Resume();
- General.WriteLogLine("Map saving failed: failed to close " + Path.GetFileName(process.MainModule.FileName));
- return false;
- }
- }
+ string rest = "Press 'Retry' to close " + (checkresult.Processes.Count > 1 ? "all processes" : "the process")
+ + " and retry." + Environment.NewLine + "Press 'Cancel' to cancel saving.";
- // Retry
- data.Resume();
- General.WriteLogLine("Map saving restarted...");
- return SaveMap(newfilepathname, purpose);
+ if(General.ShowErrorMessage(checkresult.Error + rest, MessageBoxButtons.RetryCancel) == DialogResult.Retry)
+ {
+ // Close all processes
+ foreach(Process process in checkresult.Processes)
+ {
+ try
+ {
+ if(!process.HasExited) process.Kill();
+ }
+ catch(Exception e)
+ {
+ General.ShowErrorMessage("Failed to close " + Path.GetFileName(process.MainModule.FileName) + ":" + Environment.NewLine + Environment.NewLine + e.Message, MessageBoxButtons.OK);
+ data.Resume();
+ General.WriteLogLine("Map saving failed: failed to close " + Path.GetFileName(process.MainModule.FileName));
+ return false;
+ }
+ }
+
+ // Retry
+ data.Resume();
+ General.WriteLogLine("Map saving restarted...");
+ return SaveMap(newfilepathname, purpose);
+ }
+ else
+ {
+ data.Resume();
+ General.WriteLogLine("Map saving cancelled...");
+ return false;
+ }
}
else
{
+ General.ShowErrorMessage(checkresult.Error, MessageBoxButtons.OK);
data.Resume();
- General.WriteLogLine("Map saving cancelled...");
+ General.WriteLogLine("Map saving failed: " + checkresult.Error);
return false;
}
}
- else
- {
- General.ShowErrorMessage(checkresult.Error, MessageBoxButtons.OK);
- data.Resume();
- General.WriteLogLine("Map saving failed: " + checkresult.Error);
- return false;
- }
}
// Determine original map name
@@ -867,7 +874,7 @@ namespace CodeImp.DoomBuilder
try
{
- if(File.Exists(newfilepathname))
+ if(fileexists)
{
// mxd. Check if target wad already has a map with the same name
if(purpose == SavePurpose.IntoFile)
diff --git a/Source/Core/Windows/MainForm.Designer.cs b/Source/Core/Windows/MainForm.Designer.cs
index 5a440216..366ec483 100644
--- a/Source/Core/Windows/MainForm.Designer.cs
+++ b/Source/Core/Windows/MainForm.Designer.cs
@@ -1,3 +1,4 @@
+using System;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Controls;
@@ -407,6 +408,7 @@ namespace CodeImp.DoomBuilder.Windows
this.menufile.Name = "menufile";
this.menufile.Size = new System.Drawing.Size(37, 20);
this.menufile.Text = "&File";
+ this.menufile.DropDownOpening += menufile_DropDownOpening;
//
// itemnewmap
//
diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs
index 8af1485b..80242ac5 100644
--- a/Source/Core/Windows/MainForm.cs
+++ b/Source/Core/Windows/MainForm.cs
@@ -2603,13 +2603,9 @@ namespace CodeImp.DoomBuilder.Windows
internal void AddRecentFile(string filename)
{
//mxd. Recreate recent files list
- if(recentitems.Length != General.Settings.MaxRecentFiles)
+ if(recentitems.Length != General.Settings.MaxRecentFiles)
{
- foreach(ToolStripMenuItem item in recentitems)
- menufile.DropDownItems.Remove(item);
-
- SaveRecentFiles();
- CreateRecentFiles();
+ UpdateRecentItems();
}
int movedownto = General.Settings.MaxRecentFiles - 1;
@@ -2645,6 +2641,16 @@ namespace CodeImp.DoomBuilder.Windows
itemnorecent.Visible = false;
}
+ //mxd
+ private void UpdateRecentItems()
+ {
+ foreach(ToolStripMenuItem item in recentitems)
+ menufile.DropDownItems.Remove(item);
+
+ SaveRecentFiles();
+ CreateRecentFiles();
+ }
+
// This returns the trimmed file/path string
private string GetDisplayFilename(string filename)
{
@@ -2689,6 +2695,12 @@ namespace CodeImp.DoomBuilder.Windows
// Open this file
General.OpenMapFile(item.Tag.ToString(), null);
}
+
+ //mxd
+ private void menufile_DropDownOpening(object sender, EventArgs e)
+ {
+ UpdateRecentItems();
+ }
#endregion
diff --git a/Source/Core/ZDoom/AnimdefsParser.cs b/Source/Core/ZDoom/AnimdefsParser.cs
index 2e834d72..1c3ef0d9 100644
--- a/Source/Core/ZDoom/AnimdefsParser.cs
+++ b/Source/Core/ZDoom/AnimdefsParser.cs
@@ -1,7 +1,6 @@
#region ================== Namespaces
using System.Collections.Generic;
-using System.IO;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Data;
diff --git a/Source/Core/ZDoom/PatchStructure.cs b/Source/Core/ZDoom/PatchStructure.cs
index d9e19d45..fb997a18 100644
--- a/Source/Core/ZDoom/PatchStructure.cs
+++ b/Source/Core/ZDoom/PatchStructure.cs
@@ -18,8 +18,8 @@
using System;
using System.Globalization;
-using CodeImp.DoomBuilder.Data;
using System.IO;
+using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Rendering;
#endregion
@@ -45,10 +45,9 @@ namespace CodeImp.DoomBuilder.ZDoom
private readonly bool flipy;
private readonly float alpha;
private readonly int rotation; //mxd
- private readonly TexturePathRenderStyle renderStyle; //mxd
- private readonly PixelColor blendColor; //mxd
- private readonly TexturePathBlendStyle blendStyle; //mxd
- private readonly float tintAmmount; //mxd
+ private readonly TexturePathRenderStyle renderstyle; //mxd
+ private readonly PixelColor blendcolor; //mxd
+ private readonly TexturePathBlendStyle blendstyle; //mxd
private static readonly string[] renderStyles = { "copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay" }; //mxd
private readonly bool skip; //mxd
@@ -63,10 +62,9 @@ namespace CodeImp.DoomBuilder.ZDoom
public bool FlipY { get { return flipy; } }
public float Alpha { get { return alpha; } }
public int Rotation { get { return rotation; } } //mxd
- public TexturePathRenderStyle RenderStyle { get { return renderStyle; } } //mxd
- public TexturePathBlendStyle BlendStyle { get { return blendStyle; } }
- public float TintAmmount { get { return tintAmmount; } }
- public PixelColor BlendColor { get { return blendColor; } }//mxd
+ public TexturePathRenderStyle RenderStyle { get { return renderstyle; } } //mxd
+ public TexturePathBlendStyle BlendStyle { get { return blendstyle; } }
+ public PixelColor BlendColor { get { return blendcolor; } }//mxd
public bool Skip { get { return skip; } } //mxd
#endregion
@@ -78,8 +76,8 @@ namespace CodeImp.DoomBuilder.ZDoom
{
// Initialize
alpha = 1.0f;
- renderStyle = TexturePathRenderStyle.Copy;//mxd
- blendStyle = TexturePathBlendStyle.None; //mxd
+ renderstyle = TexturePathRenderStyle.COPY;//mxd
+ blendstyle = TexturePathBlendStyle.NONE; //mxd
// There should be 3 tokens separated by 2 commas now:
// Name, Width, Height
@@ -164,30 +162,69 @@ namespace CodeImp.DoomBuilder.ZDoom
string s;
if(!ReadTokenString(parser, token, out s)) return;
int index = Array.IndexOf(renderStyles, s.ToLowerInvariant());
- renderStyle = index == -1 ? TexturePathRenderStyle.Copy : (TexturePathRenderStyle) index;
+ renderstyle = index == -1 ? TexturePathRenderStyle.COPY : (TexturePathRenderStyle) index;
break;
case "blend": //mxd
- int val;
- if(!ReadTokenColor(parser, token, out val)) return;
- blendColor = PixelColor.FromInt(val);
-
parser.SkipWhitespace(false);
- token = parser.ReadToken();
+ PixelColor color = new PixelColor();
- if(token == ",") //read tint ammount
- {
- parser.SkipWhitespace(false);
- if(!ReadTokenFloat(parser, token, out tintAmmount)) return;
- tintAmmount = General.Clamp(tintAmmount, 0.0f, 1.0f);
- blendStyle = TexturePathBlendStyle.Tint;
- }
- else
+ // Blend [,] block?
+ token = parser.ReadToken(false);
+ if(!parser.ReadByte(token, ref color.r))
{
- blendStyle = TexturePathBlendStyle.Blend;
- // Rewind so this structure can be read again
- parser.DataStream.Seek(-token.Length, SeekOrigin.Current);
+ if(!ZDTextParser.GetColorFromString(token, ref color))
+ {
+ parser.ReportError("Unsupported patch blend definition");
+ return;
+ }
}
+ // That's Blend ,,[,] block
+ else
+ {
+ if(!parser.SkipWhitespace(false) ||
+ !parser.NextTokenIs(",", false) || !parser.SkipWhitespace(false) || !parser.ReadByte(ref color.g) ||
+ !parser.NextTokenIs(",", false) || !parser.SkipWhitespace(false) || !parser.ReadByte(ref color.b))
+ {
+ parser.ReportError("Unsupported patch blend definition");
+ return;
+ }
+ }
+
+ // Alpha block?
+ float blendalpha = -1f;
+ parser.SkipWhitespace(false);
+ if(parser.NextTokenIs(",", false))
+ {
+ parser.SkipWhitespace(false);
+ if(!ReadTokenFloat(parser, token, out blendalpha))
+ {
+ parser.ReportError("Unsupported patch blend alpha value");
+ return;
+ }
+ }
+
+ // Blend may never be 0 when using the Tint effect
+ if(blendalpha > 0.0f)
+ {
+ color.a = (byte)General.Clamp((int)(blendalpha * 255), 1, 254);
+ blendstyle = TexturePathBlendStyle.TINT;
+
+ }
+ else if(blendalpha < 0.0f)
+ {
+ color.a = 255;
+ blendstyle = TexturePathBlendStyle.BLEND;
+ }
+ else
+ {
+ // Ignore Blend when alpha == 0
+ parser.LogWarning("Blend with zero alpha will be ignored by ZDoom");
+ break;
+ }
+
+ // Store the color
+ blendcolor = color;
break;
case "}":
@@ -268,36 +305,6 @@ namespace CodeImp.DoomBuilder.ZDoom
return true;
}
- //mxd. This reads the next token and sets a PixelColor value, returns false when failed
- private static bool ReadTokenColor(TexturesParser parser, string propertyname, out int value)
- {
- parser.SkipWhitespace(true);
- string strvalue = parser.StripTokenQuotes(parser.ReadToken());
- value = 0;
-
- if(string.IsNullOrEmpty(strvalue))
- {
- // Can't find the property value!
- parser.ReportError("Expected a value for property \"" + propertyname + "\"");
- return false;
- }
-
- if(strvalue[0] != '#')
- {
- parser.ReportError("Expected color value for property \"" + propertyname + "\"");
- return false;
- }
-
- // Try parsing as value
- if(!int.TryParse(strvalue.Remove(0, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value))
- {
- parser.ReportError("Expected color value for property \"" + propertyname + "\"");
- return false;
- }
-
- return true;
- }
-
#endregion
}
}
diff --git a/Source/Core/ZDoom/X11R6RGBParser.cs b/Source/Core/ZDoom/X11R6RGBParser.cs
new file mode 100644
index 00000000..18bec45d
--- /dev/null
+++ b/Source/Core/ZDoom/X11R6RGBParser.cs
@@ -0,0 +1,87 @@
+#region ================== Namespaces
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using CodeImp.DoomBuilder.Config;
+using CodeImp.DoomBuilder.Data;
+using CodeImp.DoomBuilder.Rendering;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.ZDoom
+{
+ internal sealed class X11R6RGBParser : ZDTextParser
+ {
+ #region ================== Variables
+
+ private readonly Dictionary knowncolors;
+
+ #endregion
+
+ #region ================== Properties
+
+ internal override ScriptType ScriptType { get { return ScriptType.X11R6RGB; } }
+
+ public Dictionary KnownColors { get { return knowncolors; } }
+
+ #endregion
+
+ #region ================== Constructor
+
+ internal X11R6RGBParser()
+ {
+ knowncolors = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ }
+
+ #endregion
+
+ #region ================== Parsing
+
+ public override bool Parse(TextResourceData data, bool clearerrors)
+ {
+ // Already parsed?
+ if(!base.AddTextResource(data))
+ {
+ if(clearerrors) ClearError();
+ return true;
+ }
+
+ // Cannot process?
+ if(!base.Parse(data, clearerrors)) return false;
+
+ // Continue until at the end of the stream
+ char[] space = {' ', '\t'};
+ while(SkipWhitespace(true))
+ {
+ string line = ReadLine();
+ if(string.IsNullOrEmpty(line) || line.StartsWith("!")) continue; // Skip comments
+
+ // "R G B Name with spaces"
+ string[] parts = line.Split(space, StringSplitOptions.RemoveEmptyEntries);
+
+ if(parts.Length < 4)
+ {
+ ReportError("Incorrect X11R6RGB color assignment");
+ return false;
+ }
+
+ // Parse colors
+ byte r = 0, g = 0, b = 0;
+ if(!ReadByte(parts[0], ref r)) { ReportError("Expected red color value in [0 .. 255] range"); return false; }
+ if(!ReadByte(parts[1], ref g)) { ReportError("Expected green color value in [0 .. 255] range"); return false; }
+ if(!ReadByte(parts[2], ref b)) { ReportError("Expected blue color value in [0 .. 255] range"); return false; }
+
+ // Assemble name
+ string colorname = string.Join("", parts, 3, parts.Length - 3);
+
+ // Add to collection
+ knowncolors[colorname] = new PixelColor(255, r, g, b);
+ }
+
+ return true;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/Core/ZDoom/ZDTextParser.cs b/Source/Core/ZDoom/ZDTextParser.cs
index 851e23b4..7c11110f 100644
--- a/Source/Core/ZDoom/ZDTextParser.cs
+++ b/Source/Core/ZDoom/ZDTextParser.cs
@@ -24,6 +24,7 @@ using System.IO;
using CodeImp.DoomBuilder.Compilers;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Data;
+using CodeImp.DoomBuilder.Rendering;
#endregion
@@ -557,6 +558,65 @@ namespace CodeImp.DoomBuilder.ZDoom
return success;
}
+ //mxd
+ protected internal bool ReadByte(ref byte value) { return ReadByte(StripTokenQuotes(ReadToken(false)), ref value); }
+ protected internal bool ReadByte(string token, ref byte value)
+ {
+ if(token == "-") return false;
+
+ int result;
+ if(!int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out result) || result < 0 || result > 255)
+ {
+ return false;
+ }
+
+ value = (byte)result;
+ return true;
+ }
+
+ //mxd. This replicates ZDoom's V_GetColorFromString method
+ public static bool GetColorFromString(string name, ref PixelColor color)
+ {
+ name = StripQuotes(name.Replace(" ", ""));
+
+ // Check for HTML-style #RRGGBB or #RGB color string
+ bool ishtmlcolor = false;
+ if(name.StartsWith("#"))
+ {
+ ishtmlcolor = true;
+ name = name.Remove(0, 1);
+
+ // Expand RGB to RRGGBB
+ if(name.Length == 3)
+ {
+ name = name[0].ToString() + name[0] + name[1] + name[1] + name[2] + name[2];
+ }
+ else if(name.Length != 6)
+ {
+ // Bad HTML-style; pretend it's black.
+ color = new PixelColor();
+ return true;
+ }
+ }
+
+ // Probably it's a hex color (like FFCC11)?
+ int ci;
+ if(int.TryParse(name, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ci))
+ {
+ color = PixelColor.FromInt(ci).WithAlpha(255);
+ return true;
+ }
+
+ // Probably it's a color name?
+ if(!ishtmlcolor && General.Map.Data.KnownColors.ContainsKey(name))
+ {
+ color = General.Map.Data.KnownColors[name];
+ return true;
+ }
+
+ return false;
+ }
+
//mxd
protected void SkipStructure() { SkipStructure(new HashSet()); }
protected void SkipStructure(HashSet breakat)