Added ANIMDEFS CAMERATEXTURE support.

Some internal changes in text parsers logic.
This commit is contained in:
MaxED 2015-12-18 10:16:53 +00:00
parent dbcc57b7a6
commit b9eba267db
23 changed files with 524 additions and 155 deletions

View file

@ -792,6 +792,7 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="Data\BitmapImage.cs" />
<Compile Include="Data\CameraTextureImage.cs" />
<Compile Include="Data\ColorImage.cs" />
<Compile Include="Data\ColormapImage.cs" />
<Compile Include="Data\HighResImage.cs" />
@ -996,6 +997,7 @@
<DependentUpon>VertexEditForm.cs</DependentUpon>
</Compile>
<Compile Include="ZDoom\ActorStructure.cs" />
<Compile Include="ZDoom\AnimdefsParser.cs" />
<Compile Include="ZDoom\PatchStructure.cs" />
<Compile Include="ZDoom\ReverbsParser.cs" />
<Compile Include="ZDoom\SndSeqParser.cs" />

View file

@ -426,7 +426,7 @@ namespace CodeImp.DoomBuilder.Controls
navigator.Items.Clear();
DecorateParserSE parser = new DecorateParserSE();
if(parser.Parse(stream, "DECORATE"))
if(parser.Parse(stream, "DECORATE", false))
{
navigator.Items.AddRange(parser.Actors.ToArray());
}
@ -444,7 +444,7 @@ namespace CodeImp.DoomBuilder.Controls
navigator.Items.Clear();
ModeldefParserSE parser = new ModeldefParserSE();
if(parser.Parse(stream, "MODELDEF"))
if(parser.Parse(stream, "MODELDEF", false))
{
navigator.Items.AddRange(parser.Models.ToArray());
}
@ -462,7 +462,7 @@ namespace CodeImp.DoomBuilder.Controls
navigator.Items.Clear();
AcsParserSE parser = new AcsParserSE { AddArgumentsToScriptNames = true, IsMapScriptsLump = this is ScriptLumpDocumentTab };
if(parser.Parse(stream, "SCRIPTS"))
if(parser.Parse(stream, "SCRIPTS", false))
{
navigator.Items.AddRange(parser.NamedScripts.ToArray());
navigator.Items.AddRange(parser.NumberedScripts.ToArray());
@ -479,7 +479,7 @@ namespace CodeImp.DoomBuilder.Controls
internal ScriptType VerifyScriptType()
{
ScriptTypeParserSE parser = new ScriptTypeParserSE();
if(parser.Parse(new MemoryStream(editor.GetText()), config.Description))
if(parser.Parse(new MemoryStream(editor.GetText()), config.Description, false))
{
if(parser.ScriptType != ScriptType.UNKNOWN && config.ScriptType != parser.ScriptType)
return parser.ScriptType;

View file

@ -172,10 +172,10 @@ namespace CodeImp.DoomBuilder.Controls
}
// Preprocess the file
AcsParserSE parser = new AcsParserSE { OnInclude = (se, path) => se.Parse(General.Map.Data.LoadFile(path), path, true, true) };
AcsParserSE parser = new AcsParserSE { OnInclude = (se, path) => se.Parse(General.Map.Data.LoadFile(path), path, true, true, false) };
using(FileStream stream = File.OpenRead(filepathname))
{
if(!parser.Parse(stream, filepathname, scriptconfig.Compiler.Files, true, false))
if(!parser.Parse(stream, filepathname, scriptconfig.Compiler.Files, true, false, false))
{
// Check for errors
if(parser.HasError)

View file

@ -0,0 +1,120 @@
#region ================== Namespaces
using System;
using System.Drawing;
using System.IO;
using CodeImp.DoomBuilder.ZDoom;
#endregion
namespace CodeImp.DoomBuilder.Data
{
public class CameraTextureImage : ImageData
{
#region ================== Constructor / Disposer
// Constructor
public CameraTextureImage(CameraTextureData data)
{
// Initialize
this.UseColorCorrection = false;
this.worldpanning = data.WorldPanning;
SetName(data.Name);
// Get width and height from image
this.width = data.Width;
this.height = data.Height;
scale.x = data.ScaleX;
scale.y = data.ScaleY;
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
// This loads the image
protected override void LocalLoadImage()
{
// Leave when already loaded
if(this.IsImageLoaded) return;
lock(this)
{
bitmap = new Bitmap(width, height);
int w = Math.Max(2, Math.Min(width, height) / 24); // line width
int o = w / 2; // line center offset
int l = w * 3; // line length
name = name.ToUpperInvariant();
using(Graphics g = Graphics.FromImage(bitmap))
{
// Fill bg
g.FillRectangle(Brushes.Black, 0, 0, width, height);
// Draw corners
Color color = General.Colors.BrightColors[General.Random(0, General.Colors.BrightColors.Length - 1)].ToColor();
using(var pen = new Pen(color, w))
{
g.DrawLines(pen, new[] { new Point(l, o), new Point(o, o), new Point(o, l) }); // TL
g.DrawLines(pen, new[] { new Point(width - l, o), new Point(width - o, o), new Point(width - o, l) }); // TR
g.DrawLines(pen, new[] { new Point(l, height - o), new Point(o, height - o), new Point(o, height - l) }); // BL
g.DrawLines(pen, new[] { new Point(width - l, height - o), new Point(width - o, height - o), new Point(width - o, height - l) }); // BR
}
// Calculate required font size
const string rec = "\u25CFREC";
float targetwidth = Math.Max(l * 2, 22);
SizeF fontsize = g.MeasureString(rec, General.MainWindow.Font);
float scaleratio = Math.Min(targetwidth / fontsize.Height, targetwidth / fontsize.Width);
// Draw "REC" text
using(Font font = new Font(General.MainWindow.Font.FontFamily, General.MainWindow.Font.Size * scaleratio))
{
using(var brush = new SolidBrush(Color.Red))
{
g.DrawString(rec, font, brush, new RectangleF(l / 2, l / 2 - w / 2, fontsize.Width * scaleratio, fontsize.Height * scaleratio));
}
}
// Calculate required font size
targetwidth = Math.Min(width, height);
targetwidth -= targetwidth / 6;
fontsize = g.MeasureString(name, General.MainWindow.Font);
scaleratio = Math.Min(targetwidth / fontsize.Height, targetwidth / fontsize.Width);
// Draw texture name
using(Font font = new Font(General.MainWindow.Font.FontFamily, General.MainWindow.Font.Size * scaleratio))
{
using(var brush = new SolidBrush(color))
{
StringFormat sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
g.DrawString(name, font, brush, new RectangleF(0, 0, width, height), sf);
}
}
}
// Pass on to base
base.LocalLoadImage();
}
}
//mxd
protected override void SetName(string name)
{
if(!General.Map.Config.UseLongTextureNames)
{
if(name.Length > DataManager.CLASIC_IMAGE_NAME_LENGTH) name = name.Substring(0, DataManager.CLASIC_IMAGE_NAME_LENGTH);
name = name.ToUpperInvariant();
}
base.SetName(name);
this.virtualname = "[CAMERA TEXTURES]" + Path.AltDirectorySeparatorChar + name;
}
#endregion
}
}

View file

@ -21,7 +21,6 @@ using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Compilers;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.GZBuilder.Data;
using CodeImp.DoomBuilder.GZBuilder.GZDoom;
@ -369,7 +368,7 @@ namespace CodeImp.DoomBuilder.Data
LoadVoxels();
Dictionary<string, List<int>> actorsbyclass = CreateActorsByClassList();
LoadModeldefs(actorsbyclass);
foreach (Thing t in General.Map.Map.Things) t.UpdateCache();
foreach(Thing t in General.Map.Map.Things) t.UpdateCache();
General.MainWindow.DisplayReady();
// Process colormaps (we just put them in as textures)
@ -451,6 +450,9 @@ namespace CodeImp.DoomBuilder.Data
//mxd. Should be done after loading textures...
LoadGldefs(actorsbyclass);
//mxd. Create camera textures. Should be done after loading textures.
LoadAnimdefs();
// Sort names
texturenames.Sort();
@ -954,7 +956,7 @@ namespace CodeImp.DoomBuilder.Data
nametranslation.Remove(longshortname);
nametranslation.Add(longshortname, img.LongName);
}
else if (img is TextureImage && nametranslation.ContainsKey(img.LongName))
else if(img is TextureImage && nametranslation.ContainsKey(img.LongName))
{
nametranslation.Remove(img.LongName);
}
@ -1672,7 +1674,14 @@ namespace CodeImp.DoomBuilder.Data
foreach(KeyValuePair<string, Stream> group in decostreams)
{
// Parse this data
parser.Parse(group.Value, Path.Combine(currentreader.Location.location, group.Key));
parser.Parse(group.Value, Path.Combine(currentreader.Location.location, group.Key), false);
//mxd. DECORATE lumps are interdepandable. Can't carry on...
if(parser.HasError)
{
decorate.LogError();
return;
}
}
}
@ -1741,7 +1750,7 @@ namespace CodeImp.DoomBuilder.Data
group.Value.Dispose();
}
// Bail out when not supported by currect game configuration
// Bail out when not supported by current game configuration
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
General.MainWindow.DisplayStatus(StatusType.Busy, "Reloading model definitions...");
@ -1764,7 +1773,7 @@ namespace CodeImp.DoomBuilder.Data
//mxd
public void ReloadGldefs()
{
// Bail out when not supported by currect game configuration
// Bail out when not supported by current game configuration
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
General.MainWindow.DisplayStatus(StatusType.Busy, "Reloading GLDEFS...");
@ -1806,7 +1815,7 @@ namespace CodeImp.DoomBuilder.Data
foreach(KeyValuePair<string, Stream> group in streams)
{
// Parse the data
if(parser.Parse(group.Value, currentreader.Location.location + "\\" + group.Key))
if(parser.Parse(group.Value, currentreader.Location.location + "\\" + group.Key, true))
{
foreach(KeyValuePair<string, ModelData> g in parser.Entries)
{
@ -1823,11 +1832,7 @@ namespace CodeImp.DoomBuilder.Data
}
// Modeldefs are independable, so parsing fail in one file should not affect the others
if(parser.HasError)
{
parser.LogError();
parser.ClearError();
}
if(parser.HasError) parser.LogError();
}
}
@ -1849,7 +1854,7 @@ namespace CodeImp.DoomBuilder.Data
//mxd
private void LoadVoxels()
{
// Bail out when not supported by currect game configuration
// Bail out when not supported by current game configuration
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
//Get names of all voxel models, which can be used "as is"
@ -1859,7 +1864,7 @@ namespace CodeImp.DoomBuilder.Data
{
currentreader = dr;
string[] result = dr.GetVoxelNames();
IEnumerable<string> result = dr.GetVoxelNames();
if(result == null) continue;
foreach(string s in result)
@ -1902,7 +1907,7 @@ namespace CodeImp.DoomBuilder.Data
KeyValuePair<string, Stream> group = dr.GetVoxeldefData();
if(group.Value != null)
{
if(parser.Parse(group.Value, group.Key))
if(parser.Parse(group.Value, group.Key, true))
{
foreach(KeyValuePair<string, ModelData> entry in parser.Entries)
{
@ -1918,11 +1923,7 @@ namespace CodeImp.DoomBuilder.Data
}
// Report errors?
if(parser.HasError)
{
parser.LogError();
parser.ClearError();
}
if(parser.HasError) parser.LogError();
}
}
@ -1963,7 +1964,7 @@ namespace CodeImp.DoomBuilder.Data
foreach(KeyValuePair<string, Stream> group in streams)
{
parser.Parse(group.Value, group.Key);
parser.Parse(group.Value, group.Key, false);
// Gldefs can be interdependable. Can't carry on
if(parser.HasError)
@ -2006,7 +2007,7 @@ namespace CodeImp.DoomBuilder.Data
foreach(KeyValuePair<string, Stream> group in streams)
{
// Parse the data
parser.Parse(group.Value, Path.Combine(currentreader.Location.location, group.Key), General.Map.Options.LevelName);
parser.Parse(group.Value, Path.Combine(currentreader.Location.location, group.Key), General.Map.Options.LevelName, false);
//MAPINFO lumps are interdependable. Can't carry on...
if(parser.HasError)
@ -2032,11 +2033,10 @@ namespace CodeImp.DoomBuilder.Data
mapinfo = parser.MapInfo ?? new MapInfo();
}
private void ParseFromLocation(ZDTextParser parser, string location)
private void ParseFromLocation(ZDTextParser parser, string location, bool clearerrors)
{
if(currentreader.IsSuspended) throw new Exception("Data reader is suspended");
Stream s = currentreader.LoadFile(location);
if(s != null) parser.Parse(s, location);
parser.Parse(currentreader.LoadFile(location), location, clearerrors);
}
//mxd. This loads REVERBS
@ -2044,7 +2044,7 @@ namespace CodeImp.DoomBuilder.Data
{
reverbs.Clear();
// Bail out when not supported by currect game configuration
// Bail out when not supported by current game configuration
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
ReverbsParser parser = new ReverbsParser();
@ -2055,14 +2055,10 @@ namespace CodeImp.DoomBuilder.Data
foreach(KeyValuePair<string, Stream> group in streams)
{
// Parse the data
parser.Parse(group.Value, group.Key);
parser.Parse(group.Value, group.Key, true);
// Report errors?
if(parser.HasError)
{
parser.LogError();
parser.ClearError();
}
if(parser.HasError) parser.LogError();
}
}
@ -2075,26 +2071,22 @@ namespace CodeImp.DoomBuilder.Data
{
soundsequences.Clear();
// Bail out when not supported by currect game configuration
// Bail out when not supported by current game configuration
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
SndSeqParser parser = new SndSeqParser();
foreach(DataReader dr in containers)
{
currentreader = dr;
List<Stream> streams = dr.GetSndSeqData();
Dictionary<string, Stream> streams = dr.GetSndSeqData();
// Parse the data
foreach(Stream s in streams)
foreach(KeyValuePair<string, Stream> group in streams)
{
if(s != null) parser.Parse(s, "SNDSEQ");
parser.Parse(group.Value, group.Key, true);
// Report errors?
if(parser.HasError)
{
parser.LogError();
parser.ClearError();
}
if(parser.HasError) parser.LogError();
}
}
@ -2102,6 +2094,73 @@ namespace CodeImp.DoomBuilder.Data
soundsequences = parser.GetSoundSequences();
}
//mxd. This loads cameratextures from ANIMDEFS
private void LoadAnimdefs()
{
// Bail out when not supported by current game configuration
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
AnimdefsParser parser = new AnimdefsParser();
foreach(DataReader dr in containers)
{
currentreader = dr;
Dictionary<string, Stream> streams = dr.GetAnimdefsData();
// Parse the data
foreach(KeyValuePair<string, Stream> group in streams)
{
parser.Parse(group.Value, group.Key, true);
// Report errors?
if(parser.HasError) parser.LogError();
// Create images
foreach(var g in parser.CameraTextures)
{
// Grab a local copy
CameraTextureData data = g.Value;
// Apply texture size override?
if(!data.FitTexture)
{
long longname = Lump.MakeLongName(data.Name);
if(textures.ContainsKey(longname))
{
data.ScaleX = (float)textures[longname].Width / data.Width;
data.ScaleY = (float)textures[longname].Height / data.Height;
}
else if(flats.ContainsKey(longname))
{
data.ScaleX = (float)flats[longname].Width / data.Width;
data.ScaleY = (float)flats[longname].Height / data.Height;
}
}
// Create texture
CameraTextureImage camteximage = new CameraTextureImage(data);
// Add to flats and textures
texturenames.Add(camteximage.Name);
flatnames.Add(camteximage.Name);
//TODO: Do cameratextures override stuff like this?..
textures[camteximage.LongName] = camteximage;
flats[camteximage.LongName] = camteximage;
// Add to preview manager
previews.AddImage(camteximage);
// Add to container's texture set
currentreader.TextureSet.AddFlat(camteximage);
currentreader.TextureSet.AddTexture(camteximage);
}
}
}
currentreader = null;
}
//mxd
internal MemoryStream LoadFile(string name)
{

View file

@ -152,36 +152,39 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Decorate, Modeldef, Mapinfo, Gldefs, etc...
// When implemented, this returns the decorate lump
public virtual Dictionary<string, Stream> GetDecorateData(string pname) { return new Dictionary<string, Stream>(); }
// When implemented, this returns the DECORATE lump
public abstract Dictionary<string, Stream> GetDecorateData(string pname); // { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the Modeldef lump
public virtual Dictionary<string, Stream> GetModeldefData() { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the MODELDEF lump
public abstract Dictionary<string, Stream> GetModeldefData(); // { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the Mapinfo lump
public virtual Dictionary<string, Stream> GetMapinfoData() { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the MAPINFO lump
public abstract Dictionary<string, Stream> GetMapinfoData(); // { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the Gldefs lump
public virtual Dictionary<string, Stream> GetGldefsData(GameType gameType) { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the GLDEFS lump
public abstract Dictionary<string, Stream> GetGldefsData(GameType gametype); // { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the Reverbs lump
public virtual Dictionary<string, Stream> GetReverbsData() { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the REVERBS lump
public abstract Dictionary<string, Stream> GetReverbsData(); // { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the VOXELDEF lump
public abstract KeyValuePair<string, Stream> GetVoxeldefData(); // { return new KeyValuePair<string, Stream>(); }
//mxd. When implemented, this returns the SNDSEQ lump
public abstract Dictionary<string, Stream> GetSndSeqData(); // { return new Dictionary<string, Stream>(); }
//mxd. When implemented, this returns the ANIMDEFS lump
public abstract Dictionary<string, Stream> GetAnimdefsData();
//mxd. When implemented, this returns the list of voxel model names
public virtual string[] GetVoxelNames() { return null; }
public abstract IEnumerable<string> GetVoxelNames(); // { return null; }
//mxd. When implemented, this returns the voxel lump
public virtual Stream GetVoxelData(string name) { return null; }
public abstract Stream GetVoxelData(string name); // { return null; }
//mxd
public virtual KeyValuePair<string, Stream> GetVoxeldefData() { return new KeyValuePair<string,Stream>(); }
//mxd. When implemented, this returns the SndSeq lump
public virtual List<Stream> GetSndSeqData() { return new List<Stream>(); }
//mxd
internal virtual MemoryStream LoadFile(string name) { return null; }
internal virtual bool FileExists(string filename) { return false; }
internal abstract MemoryStream LoadFile(string name);// { return null; }
internal abstract bool FileExists(string filename);// { return false; }
#endregion
}

View file

@ -409,7 +409,7 @@ namespace CodeImp.DoomBuilder.Data
#endregion
#region ================== Decorate
#region ================== DECORATE
// This finds and returns a sprite stream
public override Dictionary<string, Stream> GetDecorateData(string pname)
@ -461,7 +461,7 @@ namespace CodeImp.DoomBuilder.Data
#endregion
#region ================== Modeldef (mxd)
#region ================== MODELDEF (mxd)
//mxd
public override Dictionary<string, Stream> GetModeldefData()
@ -484,10 +484,10 @@ namespace CodeImp.DoomBuilder.Data
#endregion
#region ================== Voxeldef (mxd)
#region ================== VOXELDEF (mxd)
//mxd. This returns the list of voxels, which can be used without VOXELDEF definition
public override string[] GetVoxelNames()
public override IEnumerable<string> GetVoxelNames()
{
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
@ -557,7 +557,7 @@ namespace CodeImp.DoomBuilder.Data
public override Dictionary<string, Stream> GetGldefsData(GameType gametype)
{
// Error when suspended
if (issuspended) throw new Exception("Data reader is suspended");
if(issuspended) throw new Exception("Data reader is suspended");
Dictionary<string, Stream> streams = new Dictionary<string, Stream>(StringComparer.Ordinal);
@ -565,10 +565,10 @@ namespace CodeImp.DoomBuilder.Data
string[] files = GetAllFiles("", false);
//try to load game specific GLDEFS first
if (gametype != GameType.UNKNOWN)
if(gametype != GameType.UNKNOWN)
{
string lumpname = Gldefs.GLDEFS_LUMPS_PER_GAME[(int)gametype];
foreach (string s in files)
foreach(string s in files)
{
if(Path.GetFileNameWithoutExtension(s).ToUpperInvariant() == lumpname)
streams.Add(s, LoadFile(s));
@ -576,7 +576,7 @@ namespace CodeImp.DoomBuilder.Data
}
// Can be several entries
foreach (string s in files)
foreach(string s in files)
{
if(Path.GetFileNameWithoutExtension(s).ToUpperInvariant().StartsWith("GLDEFS"))
streams.Add(s, LoadFile(s));
@ -587,7 +587,7 @@ namespace CodeImp.DoomBuilder.Data
#endregion
#region ================== Reverbs
#region ================== REVERBS (mxd)
public override Dictionary<string, Stream> GetReverbsData()
{
@ -616,27 +616,58 @@ namespace CodeImp.DoomBuilder.Data
#endregion
#region ================== SndSeq
#region ================== SNDSEQ (mxd)
public override List<Stream> GetSndSeqData()
public override Dictionary<string, Stream> GetSndSeqData()
{
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
List<Stream> streams = new List<Stream>();
Dictionary<string, Stream> streams = new Dictionary<string, Stream>();
// Get from wads first
//TODO: is this the correct order?..
foreach(WADReader wr in wads)
{
streams.AddRange(wr.GetSndSeqData());
Dictionary<string, Stream> wadstreams = wr.GetSndSeqData();
foreach(KeyValuePair<string, Stream> pair in wadstreams) streams.Add(pair.Key, pair.Value);
}
// Then from our own files
string foundfile = FindFirstFile("sndseq", false);
if(!string.IsNullOrEmpty(foundfile) && FileExists(foundfile))
{
streams.Add(LoadFile(foundfile));
streams.Add(foundfile, LoadFile(foundfile));
}
return streams;
}
#endregion
#region ================== ANIMDEFS (mxd)
public override Dictionary<string, Stream> GetAnimdefsData()
{
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
Dictionary<string, Stream> streams = new Dictionary<string, Stream>();
// Get from wads first
//TODO: is this the correct order?..
foreach(WADReader wr in wads)
{
Dictionary<string, Stream> wadstreams = wr.GetAnimdefsData();
foreach(KeyValuePair<string, Stream> pair in wadstreams)
streams.Add(pair.Key, pair.Value);
}
// Then from our own files
string foundfile = FindFirstFile("animdefs", false);
if(!string.IsNullOrEmpty(foundfile) && FileExists(foundfile))
{
streams.Add(foundfile, LoadFile(foundfile));
}
return streams;

View file

@ -407,7 +407,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Parse the data
TexturesParser parser = new TexturesParser();
parser.Parse(stream, filename);
parser.Parse(stream, filename, false);
if(parser.HasError) parser.LogError(); //mxd
// Make the textures
@ -647,7 +647,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Parse the data
TexturesParser parser = new TexturesParser();
parser.Parse(stream, filename);
parser.Parse(stream, filename, false);
if(parser.HasError) parser.LogError(); //mxd
// Make the textures
@ -710,7 +710,7 @@ namespace CodeImp.DoomBuilder.Data
{
// Parse the data
TexturesParser parser = new TexturesParser();
parser.Parse(stream, filename);
parser.Parse(stream, filename, false);
if(parser.HasError) parser.LogError(); //mxd
// Make the textures
@ -763,7 +763,7 @@ namespace CodeImp.DoomBuilder.Data
#region ================== Voxels (mxd)
//mxd. This returns the list of voxels, which can be used without VOXELDEF definition
public override string[] GetVoxelNames()
public override IEnumerable<string> GetVoxelNames()
{
// Error when suspended
if(issuspended) throw new Exception("Data reader is suspended");
@ -908,13 +908,24 @@ namespace CodeImp.DoomBuilder.Data
}
//mxd
public override List<Stream> GetSndSeqData()
public override Dictionary<string, Stream> GetSndSeqData()
{
if(issuspended) throw new Exception("Data reader is suspended");
List<Stream> result = new List<Stream>();
Dictionary<string, Stream> result = new Dictionary<string, Stream>();
Lump lump = file.FindLump("SNDSEQ");
if(lump != null) result.Add(lump.Stream);
if(lump != null) result.Add(Path.Combine(location.location, "SNDSEQ"), lump.Stream);
return result;
}
//mxd
public override Dictionary<string, Stream> GetAnimdefsData()
{
if(issuspended) throw new Exception("Data reader is suspended");
Dictionary<string, Stream> result = new Dictionary<string, Stream>();
Lump lump = file.FindLump("ANIMDEFS");
if(lump != null) result.Add(Path.Combine(location.location, "ANIMDEFS"), lump.Stream);
return result;
}

View file

@ -42,18 +42,23 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
specialtokens += "(,)";
}
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
return Parse(stream, sourcefilename, new List<string>(), false, false);
return Parse(stream, sourcefilename, new List<string>(), false, false, clearerrors);
}
public bool Parse(Stream stream, string sourcefilename, bool processincludes, bool isinclude)
public bool Parse(Stream stream, string sourcefilename, bool processincludes, bool isinclude, bool clearerrors)
{
return Parse(stream, sourcefilename, includestoskip, processincludes, isinclude);
return Parse(stream, sourcefilename, includestoskip, processincludes, isinclude, clearerrors);
}
public bool Parse(Stream stream, string sourcefilename, List<string> configincludes, bool processincludes, bool isinclude)
public bool Parse(Stream stream, string sourcefilename, List<string> configincludes, bool processincludes, bool isinclude, bool clearerrors)
{
parsedlumps.Add(sourcefilename);
if(isinclude && !includes.Contains(sourcefilename)) includes.Add(sourcefilename);
includestoskip = configincludes;
int bracelevel = 0;
// Integrity check
if(stream == null || stream.Length == 0)
{
@ -61,12 +66,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
return false;
}
base.Parse(stream, sourcefilename);
parsedlumps.Add(sourcefilename);
if(isinclude && !includes.Contains(sourcefilename)) includes.Add(sourcefilename);
includestoskip = configincludes;
int bracelevel = 0;
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Keep local data
Stream localstream = datastream;

View file

@ -17,9 +17,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
actors = new List<ScriptItem>();
}
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Continue until at the end of the stream
while(SkipWhitespace(true))

View file

@ -39,7 +39,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
#region ================== Delegates
public delegate void IncludeDelegate(GldefsParser parser, string includefile);
public delegate void IncludeDelegate(GldefsParser parser, string includefile, bool clearerrors);
public IncludeDelegate OnInclude;
#endregion
@ -79,10 +79,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
#region ================== Parsing
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
parsedlumps.Add(sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Keep local data
Stream localstream = datastream;
@ -652,7 +652,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
// Callback to parse this file
if(OnInclude != null) OnInclude(this, includelump);
if(OnInclude != null) OnInclude(this, includelump, clearerrors);
// Set our buffers back to continue parsing
datastream = localstream;

View file

@ -17,7 +17,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
{
#region ================== Delegates
public delegate void IncludeDelegate(MapinfoParser parser, string includefile);
public delegate void IncludeDelegate(MapinfoParser parser, string includefile, bool clearerror);
public IncludeDelegate OnInclude;
#endregion
@ -59,17 +59,17 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
#region ================== Parsing
override public bool Parse(Stream stream, string sourcefilename)
override public bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
if(string.IsNullOrEmpty(mapname)) throw new NotSupportedException("MapName is required!");
return Parse(stream, sourcefilename, mapname);
return Parse(stream, sourcefilename, mapname, clearerrors);
}
public bool Parse(Stream stream, string sourcefilename, string mapname)
public bool Parse(Stream stream, string sourcefilename, string mapname, bool clearerrors)
{
base.Parse(stream, sourcefilename);
this.mapname = mapname.ToLowerInvariant();
parsedlumps.Add(sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
while(SkipWhitespace(true))
{
@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
if(!string.IsNullOrEmpty(token))
{
token = token.ToLowerInvariant();
if(ParseBlock(token)) break;
if(ParseBlock(token, clearerrors)) break;
}
}
@ -93,7 +93,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
//returns true if parsing is finished
private bool ParseBlock(string token)
private bool ParseBlock(string token, bool clearerrors)
{
// Keep local data
Stream localstream = datastream;
@ -333,7 +333,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
//block end
else if(token == "}")
{
return ParseBlock(token);
return ParseBlock(token, clearerrors);
}
//child block
else if(token == "{")
@ -362,7 +362,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
{
// Callback to parse this file
if(OnInclude != null)
OnInclude(this, includelump.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar));
OnInclude(this, includelump.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar), clearerrors);
// Set our buffers back to continue parsing
datastream = localstream;

View file

@ -17,10 +17,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
}
//should be called after all decorate actors are parsed
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
entries = new Dictionary<string, ModelData>(StringComparer.Ordinal);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Continue until at the end of the stream
while(SkipWhitespace(true))

View file

@ -21,9 +21,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
models = new List<ScriptItem>();
}
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Continue until at the end of the stream
while(SkipWhitespace(true))

View file

@ -19,12 +19,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
scriptType = ScriptType.UNKNOWN;
}
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Continue until at the end of the stream
while (SkipWhitespace(true))
while(SkipWhitespace(true))
{
string token = ReadToken();

View file

@ -1928,10 +1928,10 @@ namespace CodeImp.DoomBuilder
if(stream != null && stream.Length > 0 && scriptconfig != null && scriptconfig.Compiler != null)
{
// Get script names
AcsParserSE parser = new AcsParserSE { OnInclude = (se, path) => se.Parse(General.Map.Data.LoadFile(path), path, true, true) };
AcsParserSE parser = new AcsParserSE { OnInclude = (se, path) => se.Parse(General.Map.Data.LoadFile(path), path, true, true, false) };
//INFO: CompileLump() prepends lumpname with "?" to distinguish between temporary files and files compiled in place
if(parser.Parse(stream, "?SCRIPTS", scriptconfig.Compiler.Files, true, false))
if(parser.Parse(stream, "?SCRIPTS", scriptconfig.Compiler.Files, true, false, false))
{
// Add them to arrays
namedscriptslist.AddRange(parser.NamedScripts);

View file

@ -0,0 +1,147 @@
#region ================== Namespaces
using System.Collections.Generic;
using System.IO;
#endregion
namespace CodeImp.DoomBuilder.ZDoom
{
public struct CameraTextureData
{
public string Name;
public int Width;
public int Height;
public float ScaleX;
public float ScaleY;
public bool WorldPanning;
public bool FitTexture;
}
//mxd. Currently this only parses cameratextures
internal sealed class AnimdefsParser : ZDTextParser
{
#region ================== Variables
private readonly Dictionary<string, CameraTextureData> cameratextures;
#endregion
#region ================== Properties
public Dictionary<string, CameraTextureData> CameraTextures { get { return cameratextures; } }
#endregion
#region ================== Constructor
internal AnimdefsParser()
{
cameratextures = new Dictionary<string, CameraTextureData>();
}
#endregion
#region ================== Parsing
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Continue until at the end of the stream
while(SkipWhitespace(true))
{
string token = ReadToken();
if(string.IsNullOrEmpty(token) || string.Compare(token, "CAMERATEXTURE", true) != 0) continue;
// Texture name
string texturename = StripTokenQuotes(ReadToken(false));
if(string.IsNullOrEmpty(texturename))
{
ReportError("Expected camera texture name");
break;
}
// Width
int width = -1;
SkipWhitespace(true);
if(!ReadSignedInt(ref width) || width < 1)
{
ReportError("Expected camera texture width");
break;
}
// Height
int height = -1;
SkipWhitespace(true);
if(!ReadSignedInt(ref height) || height < 1)
{
ReportError("Expected camera texture height");
break;
}
// "Fit" keyword?
bool worldpanning = false;
bool fit = false;
float scalex = 1.0f;
float scaley = 1.0f;
if(NextTokenIs("fit", false))
{
fit = true;
int fitwidth = width;
int fitheight = height;
// Fit width
SkipWhitespace(true);
if(!ReadSignedInt(ref fitwidth) || fitwidth < 1)
{
ReportError("Expected camera texture fit width");
break;
}
// Fit height
SkipWhitespace(true);
if(!ReadSignedInt(ref fitheight) || fitheight < 1)
{
ReportError("Expected camera texture fit height");
break;
}
// Update scale
scalex = (float)fitwidth / width;
scaley = (float)fitheight / height;
// WorldPanning
worldpanning = NextTokenIs("worldpanning", false);
}
else if(NextTokenIs("worldpanning", false))
{
worldpanning = true;
}
// Check results
if(cameratextures.ContainsKey(texturename.ToUpperInvariant()))
{
ReportError("Camera texture '" + texturename + "' is defined more than once");
break;
}
// Store results
texturename = texturename.ToUpperInvariant();
cameratextures[texturename] = new CameraTextureData { Name = texturename, Width = width, Height = height,
ScaleX = scalex, ScaleY = scaley,
WorldPanning = worldpanning, FitTexture = fit };
}
return true;
}
protected override string GetLanguageType()
{
return "ANIMDEFS";
}
#endregion
}
}

View file

@ -104,7 +104,7 @@ namespace CodeImp.DoomBuilder.ZDoom
// Returns false on errors
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename, clearerrors);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Keep local data
Stream localstream = datastream;

View file

@ -20,9 +20,9 @@ namespace CodeImp.DoomBuilder.ZDoom
combinedargs = new List<int>();
}
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
// Continue until at the end of the stream
while(SkipWhitespace(true))

View file

@ -31,9 +31,9 @@ namespace CodeImp.DoomBuilder.ZDoom
#region ================== Parsing
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
char[] dots = new[] { ':' };
char[] brace = new[] { '[' };

View file

@ -73,9 +73,9 @@ namespace CodeImp.DoomBuilder.ZDoom
// This parses the given stream
// Returns false on errors
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
//mxd. Make vitrual path from filename
string virtualpath = sourcefilename.Substring(8).TrimStart(pathtrimchars);

View file

@ -16,10 +16,10 @@ namespace CodeImp.DoomBuilder.ZDoom
private Dictionary<string, ModelData> entries; //sprite name, entry
internal Dictionary<string, ModelData> Entries { get { return entries; } }
public override bool Parse(Stream stream, string sourcefilename)
public override bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
base.Parse(stream, sourcefilename);
entries = new Dictionary<string, ModelData>(StringComparer.Ordinal);
if(!base.Parse(stream, sourcefilename, clearerrors)) return false;
string prevToken = string.Empty;
List<string> spriteNames = new List<string>();

View file

@ -75,23 +75,17 @@ namespace CodeImp.DoomBuilder.ZDoom
#region ================== Parsing
// This parses the given decorate stream
// Returns false on errors
public virtual bool Parse(Stream stream, string sourcefilename)
{
return Parse(stream, sourcefilename, false);
}
// This parses the given decorate stream (mxd)
// Returns false on errors
//mxd. This parses the given decorate stream. Returns false on errors
public virtual bool Parse(Stream stream, string sourcefilename, bool clearerrors)
{
// Clear error status (mxd)
if(clearerrors)
//mxd. Clear error status?
if(clearerrors) ClearError();
//mxd. Integrity check
if(stream == null || stream.Length == 0)
{
errordesc = null;
errorsource = null;
errorline = -1;
ReportError("Unable to load '" + sourcefilename + "'!");
return false;
}
datastream = stream;
@ -425,7 +419,7 @@ namespace CodeImp.DoomBuilder.ZDoom
if(!SkipWhitespace(true)) return false;
string token = ReadToken();
if(token != expectedtoken)
if(string.Compare(token, expectedtoken, true) != 0)
{
if(reporterror) ReportError("expected '" + expectedtoken + "', but got '" + token + "'");
@ -438,34 +432,36 @@ namespace CodeImp.DoomBuilder.ZDoom
}
//mxd
protected internal bool ReadSignedFloat(ref float value) { return ReadSignedFloat(StripTokenQuotes(ReadToken(false)), ref value); }
protected internal bool ReadSignedFloat(string token, ref float value)
{
int sign = 1;
if (token == "-")
if(token == "-")
{
sign = -1;
token = StripTokenQuotes(ReadToken());
token = StripTokenQuotes(ReadToken(false));
}
float val;
bool success = float.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out val);
if (success) value = val * sign;
if(success) value = val * sign;
return success;
}
//mxd
protected internal bool ReadSignedInt(ref int value) { return ReadSignedInt(StripTokenQuotes(ReadToken(false)), ref value); }
protected internal bool ReadSignedInt(string token, ref int value)
{
int sign = 1;
if (token == "-")
if(token == "-")
{
sign = -1;
token = StripTokenQuotes(ReadToken());
token = StripTokenQuotes(ReadToken(false));
}
int val;
bool success = int.TryParse(token, NumberStyles.Integer, CultureInfo.InvariantCulture, out val);
if (success) value = val * sign;
if(success) value = val * sign;
return success;
}
@ -497,11 +493,11 @@ namespace CodeImp.DoomBuilder.ZDoom
}
//mxd
internal void ClearError()
protected void ClearError()
{
errorline = 0;
errordesc = null;
errorsource = null;
errorline = CompilerError.NO_LINE_NUMBER;
}
//mxd