2009-04-19 18:07:22 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
/ *
* Copyright ( c ) 2007 Pascal vd Heiden , www . codeimp . com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* /
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
2014-02-26 14:11:06 +00:00
using System ;
2009-04-19 18:07:22 +00:00
using System.Collections.Generic ;
using System.IO ;
2014-11-25 11:52:01 +00:00
using CodeImp.DoomBuilder.Data ;
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.ZDoom
{
public sealed class TexturesParser : ZDTextParser
{
#region = = = = = = = = = = = = = = = = = = Delegates
#endregion
#region = = = = = = = = = = = = = = = = = = Constants
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
2014-11-25 11:52:01 +00:00
private readonly Dictionary < string , TextureStructure > textures ;
private readonly Dictionary < string , TextureStructure > flats ;
private readonly Dictionary < string , TextureStructure > sprites ;
2015-03-04 09:37:30 +00:00
private readonly char [ ] pathtrimchars = new [ ] { '_' , '.' , ' ' , '-' } ; //mxd
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
2010-08-18 05:49:15 +00:00
public ICollection < TextureStructure > Textures { get { return textures . Values ; } }
public ICollection < TextureStructure > Flats { get { return flats . Values ; } }
public ICollection < TextureStructure > Sprites { get { return sprites . Values ; } }
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
public TexturesParser ( )
{
// Syntax
2013-09-11 09:47:53 +00:00
whitespace = "\n \t\r\u00A0" ; //mxd. non-breaking space is also space :)
2009-04-19 18:07:22 +00:00
specialtokens = ",{}\n" ;
// Initialize
2014-02-26 14:11:06 +00:00
textures = new Dictionary < string , TextureStructure > ( StringComparer . Ordinal ) ;
flats = new Dictionary < string , TextureStructure > ( StringComparer . Ordinal ) ;
sprites = new Dictionary < string , TextureStructure > ( StringComparer . Ordinal ) ;
2009-04-19 18:07:22 +00:00
}
#endregion
#region = = = = = = = = = = = = = = = = = = Parsing
// This parses the given stream
// Returns false on errors
public override bool Parse ( Stream stream , string sourcefilename )
{
base . Parse ( stream , sourcefilename ) ;
2015-03-04 09:37:30 +00:00
//mxd. Make vitrual path from filename
string virtualpath = sourcefilename . Substring ( 8 ) . TrimStart ( pathtrimchars ) ;
if ( virtualpath . ToLowerInvariant ( ) = = "txt" ) virtualpath = string . Empty ;
2009-04-19 18:07:22 +00:00
// Continue until at the end of the stream
while ( SkipWhitespace ( true ) )
{
// Read a token
string objdeclaration = ReadToken ( ) ;
2015-06-18 19:45:39 +00:00
if ( ! string . IsNullOrEmpty ( objdeclaration ) )
2009-04-19 18:07:22 +00:00
{
objdeclaration = objdeclaration . ToLowerInvariant ( ) ;
if ( objdeclaration = = "texture" )
{
// Read texture structure
2015-03-04 09:37:30 +00:00
TextureStructure tx = new TextureStructure ( this , "texture" , virtualpath ) ;
2009-04-19 18:07:22 +00:00
if ( this . HasError ) break ;
2009-06-08 18:52:56 +00:00
// if a limit for the texture name length is set make sure that it's not exceeded
2014-11-25 11:52:01 +00:00
if ( tx . Name . Length > General . Map . Config . MaxTextureNameLength )
2009-06-08 18:52:56 +00:00
{
2014-05-19 13:33:38 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Texture name \"" + tx . Name + "\" too long. Texture names must have a length of " + General . Map . Config . MaxTextureNameLength + " characters or less" ) ;
2009-06-08 18:52:56 +00:00
}
else
{
// Add the texture
2010-08-18 05:49:15 +00:00
textures [ tx . Name ] = tx ;
2013-07-29 08:50:50 +00:00
if ( ! General . Map . Config . MixTexturesFlats ) flats [ tx . Name ] = tx ; //mxd. If MixTexturesFlats is set, textures and flats will be mixed in DataManager anyway
2009-06-08 18:52:56 +00:00
}
2009-04-19 18:07:22 +00:00
}
else if ( objdeclaration = = "sprite" )
{
// Read sprite structure
2015-03-04 09:37:30 +00:00
TextureStructure tx = new TextureStructure ( this , "sprite" , virtualpath ) ;
2009-04-19 18:07:22 +00:00
if ( this . HasError ) break ;
2009-06-08 18:52:56 +00:00
// if a limit for the sprite name length is set make sure that it's not exceeded
2014-11-25 11:52:01 +00:00
if ( tx . Name . Length > DataManager . CLASIC_IMAGE_NAME_LENGTH )
2009-06-08 18:52:56 +00:00
{
2014-11-25 11:52:01 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Sprite name \"" + tx . Name + "\" too long. Sprite names must have a length of " + DataManager . CLASIC_IMAGE_NAME_LENGTH + " characters or less" ) ;
2009-06-08 18:52:56 +00:00
}
else
{
// Add the sprite
2010-08-18 05:49:15 +00:00
sprites [ tx . Name ] = tx ;
}
}
else if ( objdeclaration = = "walltexture" )
{
// Read walltexture structure
2015-03-04 09:37:30 +00:00
TextureStructure tx = new TextureStructure ( this , "walltexture" , virtualpath ) ;
2010-08-18 05:49:15 +00:00
if ( this . HasError ) break ;
// if a limit for the walltexture name length is set make sure that it's not exceeded
2014-11-25 11:52:01 +00:00
if ( tx . Name . Length > General . Map . Config . MaxTextureNameLength )
2010-08-18 05:49:15 +00:00
{
2014-05-19 13:33:38 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "WallTexture name \"" + tx . Name + "\" too long. WallTexture names must have a length of " + General . Map . Config . MaxTextureNameLength + " characters or less" ) ;
2010-08-18 05:49:15 +00:00
}
else
{
// Add the walltexture
if ( ! textures . ContainsKey ( tx . Name ) | | ( textures [ tx . Name ] . TypeName ! = "texture" ) )
textures [ tx . Name ] = tx ;
}
}
else if ( objdeclaration = = "flat" )
{
// Read flat structure
2015-03-04 09:37:30 +00:00
TextureStructure tx = new TextureStructure ( this , "flat" , virtualpath ) ;
2010-08-18 05:49:15 +00:00
if ( this . HasError ) break ;
// if a limit for the flat name length is set make sure that it's not exceeded
2014-11-25 11:52:01 +00:00
if ( tx . Name . Length > General . Map . Config . MaxTextureNameLength )
2010-08-18 05:49:15 +00:00
{
2014-05-19 13:33:38 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Flat name \"" + tx . Name + "\" too long. Flat names must have a length of " + General . Map . Config . MaxTextureNameLength + " characters or less" ) ;
2010-08-18 05:49:15 +00:00
}
else
{
// Add the flat
if ( ! flats . ContainsKey ( tx . Name ) | | ( flats [ tx . Name ] . TypeName ! = "texture" ) )
flats [ tx . Name ] = tx ;
2009-06-08 18:52:56 +00:00
}
2009-04-19 18:07:22 +00:00
}
2015-03-04 09:37:30 +00:00
else if ( objdeclaration = = "$gzdb_skip" ) //mxd
{
break ;
}
2009-04-19 18:07:22 +00:00
else
{
// Unknown structure!
// Best we can do now is just find the first { and then
// follow the scopes until the matching } is found
string token2 ;
do
{
if ( ! SkipWhitespace ( true ) ) break ;
token2 = ReadToken ( ) ;
2015-06-18 19:45:39 +00:00
if ( string . IsNullOrEmpty ( token2 ) ) break ;
2009-04-19 18:07:22 +00:00
}
while ( token2 ! = "{" ) ;
int scopelevel = 1 ;
do
{
if ( ! SkipWhitespace ( true ) ) break ;
token2 = ReadToken ( ) ;
2015-06-18 19:45:39 +00:00
if ( string . IsNullOrEmpty ( token2 ) ) break ;
2009-04-19 18:07:22 +00:00
if ( token2 = = "{" ) scopelevel + + ;
if ( token2 = = "}" ) scopelevel - - ;
}
while ( scopelevel > 0 ) ;
}
}
}
// Return true when no errors occurred
return ( ErrorDescription = = null ) ;
}
#endregion
}
}