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
using System ;
using System.Collections.Generic ;
using System.IO ;
2014-01-03 10:33:45 +00:00
using System.Text.RegularExpressions ;
2012-06-01 10:17:47 +00:00
using CodeImp.DoomBuilder.GZBuilder.Data ;
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.Data
{
internal abstract class PK3StructuredReader : DataReader
{
#region = = = = = = = = = = = = = = = = = = Constants
protected const string PATCHES_DIR = "patches" ;
protected const string TEXTURES_DIR = "textures" ;
protected const string FLATS_DIR = "flats" ;
protected const string HIRES_DIR = "hires" ;
protected const string SPRITES_DIR = "sprites" ;
2009-05-12 09:50:08 +00:00
protected const string COLORMAPS_DIR = "colormaps" ;
2013-12-20 09:24:43 +00:00
protected const string GRAPHICS_DIR = "graphics" ; //mxd
2014-01-03 10:33:45 +00:00
protected const string VOXELS_DIR = "voxels" ; //mxd
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
// Source
protected bool roottextures ;
protected bool rootflats ;
// WAD files that must be loaded as well
protected List < WADReader > wads ;
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
2014-10-07 09:56:36 +00:00
protected readonly string [ ] PatchLocations = { PATCHES_DIR , TEXTURES_DIR , FLATS_DIR , SPRITES_DIR , GRAPHICS_DIR } ; //mxd. Because ZDoom looks for patches and sprites in this order
2013-07-29 08:50:50 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
2015-05-27 12:38:03 +00:00
protected PK3StructuredReader ( DataLocation dl ) : base ( dl )
2009-04-19 18:07:22 +00:00
{
// Initialize
this . roottextures = dl . option1 ;
this . rootflats = dl . option2 ;
}
// Call this to initialize this class
protected virtual void Initialize ( )
{
// Load all WAD files in the root as WAD resources
string [ ] wadfiles = GetFilesWithExt ( "" , "wad" , false ) ;
wads = new List < WADReader > ( wadfiles . Length ) ;
foreach ( string w in wadfiles )
{
string tempfile = CreateTempFile ( w ) ;
2009-07-02 14:15:47 +00:00
DataLocation wdl = new DataLocation ( DataLocation . RESOURCE_WAD , tempfile , false , false , true ) ;
2009-04-19 18:07:22 +00:00
wads . Add ( new WADReader ( wdl ) ) ;
}
}
// Disposer
public override void Dispose ( )
{
// Not already disposed?
if ( ! isdisposed )
{
// Clean up
foreach ( WADReader wr in wads ) wr . Dispose ( ) ;
// Remove temp files
foreach ( WADReader wr in wads )
{
try { File . Delete ( wr . Location . location ) ; }
catch ( Exception ) { }
}
// Done
base . Dispose ( ) ;
}
}
#endregion
#region = = = = = = = = = = = = = = = = = = Management
// This suspends use of this resource
public override void Suspend ( )
{
foreach ( WADReader wr in wads ) wr . Suspend ( ) ;
base . Suspend ( ) ;
}
// This resumes use of this resource
public override void Resume ( )
{
foreach ( WADReader wr in wads ) wr . Resume ( ) ;
base . Resume ( ) ;
}
#endregion
#region = = = = = = = = = = = = = = = = = = Palette
// This loads the PLAYPAL palette
public override Playpal LoadPalette ( )
{
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
// Palette from wad(s)
Playpal palette = null ;
foreach ( WADReader wr in wads )
{
Playpal wadpalette = wr . LoadPalette ( ) ;
if ( wadpalette ! = null ) return wadpalette ;
}
// Find in root directory
string foundfile = FindFirstFile ( "PLAYPAL" , false ) ;
if ( ( foundfile ! = null ) & & FileExists ( foundfile ) )
{
MemoryStream stream = LoadFile ( foundfile ) ;
2012-08-24 01:18:25 +00:00
2015-01-25 23:22:42 +00:00
if ( stream . Length > 767 ) //mxd
2012-08-24 01:18:25 +00:00
palette = new Playpal ( stream ) ;
2015-01-25 23:22:42 +00:00
else
2012-08-24 01:18:25 +00:00
General . ErrorLogger . Add ( ErrorType . Warning , "Warning: invalid palette '" + foundfile + "'" ) ;
2009-04-19 18:07:22 +00:00
stream . Dispose ( ) ;
}
// Done
return palette ;
}
#endregion
#region = = = = = = = = = = = = = = = = = = Textures
// This loads the textures
public override ICollection < ImageData > LoadTextures ( PatchNames pnames )
{
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
2015-12-29 18:22:08 +00:00
Dictionary < long , ImageData > images = new Dictionary < long , ImageData > ( ) ;
ICollection < ImageData > collection ;
2009-04-19 18:07:22 +00:00
// Load from wad files (NOTE: backward order, because the last wad's images have priority)
for ( int i = wads . Count - 1 ; i > = 0 ; i - - )
{
2013-03-18 13:52:27 +00:00
PatchNames wadpnames = wads [ i ] . LoadPatchNames ( ) ; //mxd
collection = wads [ i ] . LoadTextures ( ( wadpnames ! = null & & wadpnames . Length > 0 ) ? wadpnames : pnames ) ; //mxd
2009-04-19 18:07:22 +00:00
AddImagesToList ( images , collection ) ;
}
// Should we load the images in this directory as textures?
if ( roottextures )
{
2009-05-12 09:50:08 +00:00
collection = LoadDirectoryImages ( "" , ImageDataFormat . DOOMPICTURE , false ) ;
2009-04-19 18:07:22 +00:00
AddImagesToList ( images , collection ) ;
}
// Load TEXTURE1 lump file
2015-12-29 18:22:08 +00:00
List < ImageData > imgset = new List < ImageData > ( ) ;
2009-04-19 18:07:22 +00:00
string texture1file = FindFirstFile ( "TEXTURE1" , false ) ;
if ( ( texture1file ! = null ) & & FileExists ( texture1file ) )
{
MemoryStream filedata = LoadFile ( texture1file ) ;
WADReader . LoadTextureSet ( "TEXTURE1" , filedata , ref imgset , pnames ) ;
filedata . Dispose ( ) ;
}
// Load TEXTURE2 lump file
string texture2file = FindFirstFile ( "TEXTURE2" , false ) ;
if ( ( texture2file ! = null ) & & FileExists ( texture2file ) )
{
MemoryStream filedata = LoadFile ( texture2file ) ;
WADReader . LoadTextureSet ( "TEXTURE2" , filedata , ref imgset , pnames ) ;
filedata . Dispose ( ) ;
}
2010-08-13 15:19:51 +00:00
2009-04-19 18:07:22 +00:00
// Add images from TEXTURE1 and TEXTURE2 lump files
AddImagesToList ( images , imgset ) ;
2010-08-13 15:19:51 +00:00
2012-08-05 19:18:05 +00:00
// Load TEXTURES lump files
2009-04-19 18:07:22 +00:00
imgset . Clear ( ) ;
2013-09-11 09:47:53 +00:00
string [ ] alltexturefiles = GetAllFilesWhichTitleStartsWith ( "" , "TEXTURES" ) ; //mxd
2010-08-13 15:19:51 +00:00
foreach ( string texturesfile in alltexturefiles )
2009-04-19 18:07:22 +00:00
{
MemoryStream filedata = LoadFile ( texturesfile ) ;
WADReader . LoadHighresTextures ( filedata , texturesfile , ref imgset , images , null ) ;
filedata . Dispose ( ) ;
}
2010-08-13 15:19:51 +00:00
2009-04-19 18:07:22 +00:00
// Add images from TEXTURES lump file
AddImagesToList ( images , imgset ) ;
2012-08-05 19:18:05 +00:00
//mxd. Add images from texture directory. Textures defined in TEXTURES override ones in "textures" folder
collection = LoadDirectoryImages ( TEXTURES_DIR , ImageDataFormat . DOOMPICTURE , true ) ;
AddImagesToList ( images , collection ) ;
2009-04-19 18:07:22 +00:00
// Add images to the container-specific texture set
foreach ( ImageData img in images . Values )
textureset . AddTexture ( img ) ;
return new List < ImageData > ( images . Values ) ;
}
// This returns the patch names from the PNAMES lump
// A directory resource does not support this lump, but the wads in the directory may contain this lump
public override PatchNames LoadPatchNames ( )
{
PatchNames pnames ;
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
// Load from wad files
// Note the backward order, because the last wad's images have priority
for ( int i = wads . Count - 1 ; i > = 0 ; i - - )
{
pnames = wads [ i ] . LoadPatchNames ( ) ;
if ( pnames ! = null ) return pnames ;
}
// If none of the wads provides patch names, let's see if we can
string pnamesfile = FindFirstFile ( "PNAMES" , false ) ;
if ( ( pnamesfile ! = null ) & & FileExists ( pnamesfile ) )
{
MemoryStream pnamesdata = LoadFile ( pnamesfile ) ;
pnames = new PatchNames ( pnamesdata ) ;
pnamesdata . Dispose ( ) ;
return pnames ;
}
return null ;
}
#endregion
#region = = = = = = = = = = = = = = = = = = Flats
// This loads the textures
public override ICollection < ImageData > LoadFlats ( )
{
Dictionary < long , ImageData > images = new Dictionary < long , ImageData > ( ) ;
ICollection < ImageData > collection ;
2010-08-18 05:49:15 +00:00
List < ImageData > imgset = new List < ImageData > ( ) ;
2009-04-19 18:07:22 +00:00
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
// Load from wad files
// Note the backward order, because the last wad's images have priority
for ( int i = wads . Count - 1 ; i > = 0 ; i - - )
{
collection = wads [ i ] . LoadFlats ( ) ;
AddImagesToList ( images , collection ) ;
}
// Should we load the images in this directory as flats?
if ( rootflats )
{
2009-05-12 09:50:08 +00:00
collection = LoadDirectoryImages ( "" , ImageDataFormat . DOOMFLAT , false ) ;
2009-04-19 18:07:22 +00:00
AddImagesToList ( images , collection ) ;
}
2014-10-07 09:56:36 +00:00
2014-10-13 09:32:55 +00:00
// Add images from flats directory
collection = LoadDirectoryImages ( FLATS_DIR , ImageDataFormat . DOOMFLAT , true ) ;
AddImagesToList ( images , collection ) ;
2009-04-19 18:07:22 +00:00
2010-08-18 05:49:15 +00:00
// Load TEXTURES lump file
Textures Browser form: empty texture sets are no longer shown when mixed textures & flats is disabled in the current game configuration.
Textures Browser form: PK3/Directory TEXTURES images are now shown in a separate folder in the resources tree.
Fixed, Textures Browser form: fixed a logic error when trying to select initial flat when mix textures & flats was disabled in the current game configuration (this resulted in the blank textures list after opening the form).
Fixed, Textures Browser form: resources tree showed textures count even when browsing flats.
Fixed, Textures Browser form: PK3/Directory textures took precedence even when browsing flats (this means when there were a flat and a texture with the same name, a texture was displayed when browsing flats).
Fixed, Classic modes: actor's scale set in DECORATE was ignored when rendering models.
Fixed, MODELDEF parser: in some cases, several model definitions were skipped when trying to skip the current one.
Fixed, resource management: flat and sprite TEXTURES definitions were loaded only from TEXTURES files named "TEXTURES".
Fixed/added, PK3/folder resource management: patch locations for sprites defined in TEXTURES are now checked the same way as in ZDoom (previously only the "sprites" folder was checked).
Fixed/added, PK3/folder resource management: patch locations for textures defined in TEXTURES are now checked the same way as in ZDoom (previously only the "textures" folder was checked).
Fixed, PK3/folder resource management: flats defined in TEXTURES were not added to the global Flats image list.
Fixed, PK3/folder resource management: in some cases, the image search algorithm could find flats, textures, patches or sprites in incorrect folders (for example, it could find a flat in "flats_backup" folder).
2014-10-07 00:23:02 +00:00
string [ ] alltexturefiles = GetAllFilesWhichTitleStartsWith ( "" , "TEXTURES" ) ; //mxd
2010-08-18 05:49:15 +00:00
foreach ( string texturesfile in alltexturefiles )
{
MemoryStream filedata = LoadFile ( texturesfile ) ;
WADReader . LoadHighresFlats ( filedata , texturesfile , ref imgset , null , images ) ;
filedata . Dispose ( ) ;
}
// Add images from TEXTURES lump file
AddImagesToList ( images , imgset ) ;
Textures Browser form: empty texture sets are no longer shown when mixed textures & flats is disabled in the current game configuration.
Textures Browser form: PK3/Directory TEXTURES images are now shown in a separate folder in the resources tree.
Fixed, Textures Browser form: fixed a logic error when trying to select initial flat when mix textures & flats was disabled in the current game configuration (this resulted in the blank textures list after opening the form).
Fixed, Textures Browser form: resources tree showed textures count even when browsing flats.
Fixed, Textures Browser form: PK3/Directory textures took precedence even when browsing flats (this means when there were a flat and a texture with the same name, a texture was displayed when browsing flats).
Fixed, Classic modes: actor's scale set in DECORATE was ignored when rendering models.
Fixed, MODELDEF parser: in some cases, several model definitions were skipped when trying to skip the current one.
Fixed, resource management: flat and sprite TEXTURES definitions were loaded only from TEXTURES files named "TEXTURES".
Fixed/added, PK3/folder resource management: patch locations for sprites defined in TEXTURES are now checked the same way as in ZDoom (previously only the "sprites" folder was checked).
Fixed/added, PK3/folder resource management: patch locations for textures defined in TEXTURES are now checked the same way as in ZDoom (previously only the "textures" folder was checked).
Fixed, PK3/folder resource management: flats defined in TEXTURES were not added to the global Flats image list.
Fixed, PK3/folder resource management: in some cases, the image search algorithm could find flats, textures, patches or sprites in incorrect folders (for example, it could find a flat in "flats_backup" folder).
2014-10-07 00:23:02 +00:00
// Add images to the container-specific texture set
foreach ( ImageData img in images . Values )
textureset . AddFlat ( img ) ;
// Add images from TEXTURES lump file
AddImagesToList ( images , imgset ) ;
2010-08-18 05:49:15 +00:00
2009-04-19 18:07:22 +00:00
return new List < ImageData > ( images . Values ) ;
}
2013-07-29 08:50:50 +00:00
//mxd.
2014-11-25 11:52:01 +00:00
public override Stream GetFlatData ( string pname , bool longname )
{
2013-07-29 08:50:50 +00:00
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
// Find in any of the wad files
// Note the backward order, because the last wad's images have priority
2014-11-25 11:52:01 +00:00
if ( ! longname ) //mxd. Flats with long names can't be in wads
{
2015-12-28 15:01:53 +00:00
for ( int i = wads . Count - 1 ; i > - 1 ; i - - )
2014-11-25 11:52:01 +00:00
{
Stream data = wads [ i ] . GetFlatData ( pname , false ) ;
2015-12-28 15:01:53 +00:00
if ( data ! = null ) return data ;
2014-11-25 11:52:01 +00:00
}
2013-07-29 08:50:50 +00:00
}
// Nothing found
return null ;
}
2009-04-19 18:07:22 +00:00
#endregion
2010-08-18 09:07:54 +00:00
#region = = = = = = = = = = = = = = = = = = Sprites
// This loads the textures
public override ICollection < ImageData > LoadSprites ( )
{
Dictionary < long , ImageData > images = new Dictionary < long , ImageData > ( ) ;
List < ImageData > imgset = new List < ImageData > ( ) ;
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
// Load from wad files
// Note the backward order, because the last wad's images have priority
for ( int i = wads . Count - 1 ; i > = 0 ; i - - )
{
2015-12-28 15:01:53 +00:00
ICollection < ImageData > collection = wads [ i ] . LoadSprites ( ) ;
2010-08-18 09:07:54 +00:00
AddImagesToList ( images , collection ) ;
}
// Load TEXTURES lump file
imgset . Clear ( ) ;
Textures Browser form: empty texture sets are no longer shown when mixed textures & flats is disabled in the current game configuration.
Textures Browser form: PK3/Directory TEXTURES images are now shown in a separate folder in the resources tree.
Fixed, Textures Browser form: fixed a logic error when trying to select initial flat when mix textures & flats was disabled in the current game configuration (this resulted in the blank textures list after opening the form).
Fixed, Textures Browser form: resources tree showed textures count even when browsing flats.
Fixed, Textures Browser form: PK3/Directory textures took precedence even when browsing flats (this means when there were a flat and a texture with the same name, a texture was displayed when browsing flats).
Fixed, Classic modes: actor's scale set in DECORATE was ignored when rendering models.
Fixed, MODELDEF parser: in some cases, several model definitions were skipped when trying to skip the current one.
Fixed, resource management: flat and sprite TEXTURES definitions were loaded only from TEXTURES files named "TEXTURES".
Fixed/added, PK3/folder resource management: patch locations for sprites defined in TEXTURES are now checked the same way as in ZDoom (previously only the "sprites" folder was checked).
Fixed/added, PK3/folder resource management: patch locations for textures defined in TEXTURES are now checked the same way as in ZDoom (previously only the "textures" folder was checked).
Fixed, PK3/folder resource management: flats defined in TEXTURES were not added to the global Flats image list.
Fixed, PK3/folder resource management: in some cases, the image search algorithm could find flats, textures, patches or sprites in incorrect folders (for example, it could find a flat in "flats_backup" folder).
2014-10-07 00:23:02 +00:00
string [ ] alltexturefiles = GetAllFilesWhichTitleStartsWith ( "" , "TEXTURES" ) ; //mxd
2010-08-18 09:07:54 +00:00
foreach ( string texturesfile in alltexturefiles )
{
MemoryStream filedata = LoadFile ( texturesfile ) ;
WADReader . LoadHighresSprites ( filedata , texturesfile , ref imgset , null , null ) ;
filedata . Dispose ( ) ;
}
// Add images from TEXTURES lump file
AddImagesToList ( images , imgset ) ;
return new List < ImageData > ( images . Values ) ;
}
#endregion
2009-05-12 09:50:08 +00:00
#region = = = = = = = = = = = = = = = = = = Colormaps
// This loads the textures
public override ICollection < ImageData > LoadColormaps ( )
{
Dictionary < long , ImageData > images = new Dictionary < long , ImageData > ( ) ;
ICollection < ImageData > collection ;
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
// Load from wad files
// Note the backward order, because the last wad's images have priority
for ( int i = wads . Count - 1 ; i > = 0 ; i - - )
{
collection = wads [ i ] . LoadColormaps ( ) ;
AddImagesToList ( images , collection ) ;
}
// Add images from flats directory
collection = LoadDirectoryImages ( COLORMAPS_DIR , ImageDataFormat . DOOMCOLORMAP , true ) ;
AddImagesToList ( images , collection ) ;
// Add images to the container-specific texture set
foreach ( ImageData img in images . Values )
textureset . AddFlat ( img ) ;
return new List < ImageData > ( images . Values ) ;
}
#endregion
2015-12-18 10:16:53 +00:00
#region = = = = = = = = = = = = = = = = = = DECORATE
2009-04-19 18:07:22 +00:00
// This finds and returns a sprite stream
2014-10-23 12:48:31 +00:00
public override Dictionary < string , Stream > GetDecorateData ( string pname )
2009-04-19 18:07:22 +00:00
{
2014-10-23 12:48:31 +00:00
Dictionary < string , Stream > result = new Dictionary < string , Stream > ( ) ;
2010-08-15 13:45:43 +00:00
string [ ] allfilenames ;
2010-08-12 10:03:29 +00:00
2009-04-19 18:07:22 +00:00
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
2010-08-12 10:03:29 +00:00
2009-04-19 18:07:22 +00:00
// Find in root directory
string filename = Path . GetFileName ( pname ) ;
string pathname = Path . GetDirectoryName ( pname ) ;
2010-08-15 13:45:43 +00:00
if ( filename . IndexOf ( '.' ) > - 1 )
{
2012-08-10 12:08:08 +00:00
string fullName = Path . Combine ( pathname , filename ) ;
2014-10-23 12:48:31 +00:00
if ( FileExists ( fullName ) )
{
2012-08-10 12:08:08 +00:00
allfilenames = new string [ 1 ] ;
allfilenames [ 0 ] = Path . Combine ( pathname , filename ) ;
2014-10-23 12:48:31 +00:00
}
else
{
2012-08-10 12:08:08 +00:00
allfilenames = new string [ 0 ] ;
General . ErrorLogger . Add ( ErrorType . Warning , "Unable to load DECORATE file '" + fullName + "'" ) ;
}
2010-08-15 13:45:43 +00:00
}
else
allfilenames = GetAllFilesWithTitle ( pathname , filename , false ) ;
2010-08-13 15:19:51 +00:00
foreach ( string foundfile in allfilenames )
2009-04-19 18:07:22 +00:00
{
2014-10-23 12:48:31 +00:00
result . Add ( foundfile , LoadFile ( foundfile ) ) ;
2009-04-19 18:07:22 +00:00
}
2010-08-12 10:03:29 +00:00
// Find in any of the wad files
for ( int i = wads . Count - 1 ; i > = 0 ; i - - )
2014-10-23 12:48:31 +00:00
{
Dictionary < string , Stream > wadresult = wads [ i ] . GetDecorateData ( pname ) ;
foreach ( KeyValuePair < string , Stream > group in wadresult )
{
result . Add ( group . Key , group . Value ) ;
}
}
return result ;
2009-04-19 18:07:22 +00:00
}
#endregion
2012-05-21 23:51:32 +00:00
2015-12-18 10:16:53 +00:00
#region = = = = = = = = = = = = = = = = = = MODELDEF ( mxd )
2014-01-03 10:33:45 +00:00
2013-09-11 09:47:53 +00:00
//mxd
2014-11-25 11:52:01 +00:00
public override Dictionary < string , Stream > GetModeldefData ( )
{
2013-09-11 09:47:53 +00:00
// Error when suspended
2015-12-28 15:01:53 +00:00
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
2013-09-11 09:47:53 +00:00
2014-12-03 23:15:26 +00:00
// Modedef should be in root folder
2014-11-25 11:52:01 +00:00
string [ ] files = GetAllFiles ( "" , false ) ;
2014-02-26 14:11:06 +00:00
Dictionary < string , Stream > streams = new Dictionary < string , Stream > ( StringComparer . Ordinal ) ;
2013-09-11 09:47:53 +00:00
2015-12-28 15:01:53 +00:00
foreach ( string s in files )
2014-12-03 23:15:26 +00:00
{
2015-12-28 15:01:53 +00:00
if ( Path . GetFileNameWithoutExtension ( s ) . ToUpperInvariant ( ) . StartsWith ( "MODELDEF" ) )
2013-09-11 09:47:53 +00:00
streams . Add ( s , LoadFile ( s ) ) ;
}
return streams ;
}
2014-01-03 10:33:45 +00:00
#endregion
2015-12-18 10:16:53 +00:00
#region = = = = = = = = = = = = = = = = = = VOXELDEF ( mxd )
2014-01-03 10:33:45 +00:00
//mxd. This returns the list of voxels, which can be used without VOXELDEF definition
2015-12-18 10:16:53 +00:00
public override IEnumerable < string > GetVoxelNames ( )
2014-11-25 11:52:01 +00:00
{
2014-01-03 10:33:45 +00:00
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
string [ ] files = GetAllFiles ( "voxels" , false ) ;
List < string > voxels = new List < string > ( ) ;
2014-11-25 11:52:01 +00:00
Regex spritename = new Regex ( SPRITE_NAME_PATTERN ) ;
2014-01-03 10:33:45 +00:00
2015-12-28 15:01:53 +00:00
foreach ( string t in files )
2014-11-25 11:52:01 +00:00
{
string s = Path . GetFileNameWithoutExtension ( t ) . ToUpperInvariant ( ) ;
if ( spritename . IsMatch ( s ) ) voxels . Add ( s ) ;
2014-01-03 10:33:45 +00:00
}
return voxels . ToArray ( ) ;
}
//mxd
2014-11-25 11:52:01 +00:00
public override KeyValuePair < string , Stream > GetVoxeldefData ( )
{
2014-01-03 10:33:45 +00:00
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
//voxeldef should be in root folder
string [ ] files = GetAllFiles ( "" , false ) ;
2014-11-25 11:52:01 +00:00
foreach ( string s in files )
{
if ( Path . GetFileNameWithoutExtension ( s ) . ToUpperInvariant ( ) = = "VOXELDEF" )
2014-01-03 10:33:45 +00:00
return new KeyValuePair < string , Stream > ( s , LoadFile ( s ) ) ;
}
return new KeyValuePair < string , Stream > ( ) ;
}
2013-09-11 09:47:53 +00:00
#endregion
2014-01-03 10:33:45 +00:00
#region = = = = = = = = = = = = = = = = = = ( Z ) MAPINFO ( mxd )
2013-09-11 09:47:53 +00:00
//mxd
2014-11-25 11:52:01 +00:00
public override Dictionary < string , Stream > GetMapinfoData ( )
{
2013-09-11 09:47:53 +00:00
// Error when suspended
2015-12-28 15:01:53 +00:00
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
2013-09-11 09:47:53 +00:00
2016-01-11 13:00:52 +00:00
// Mapinfo should be in root folder
2014-11-25 11:52:01 +00:00
Dictionary < string , Stream > streams = new Dictionary < string , Stream > ( StringComparer . Ordinal ) ;
2013-09-11 09:47:53 +00:00
2016-01-11 13:00:52 +00:00
// Try to find (z)mapinfo
string [ ] files = GetAllFiles ( "" , false ) ;
2015-12-28 15:01:53 +00:00
foreach ( string s in files )
2014-11-25 11:52:01 +00:00
{
2015-12-28 15:01:53 +00:00
string filename = Path . GetFileNameWithoutExtension ( s . ToLowerInvariant ( ) ) ;
2014-11-25 11:52:01 +00:00
if ( filename = = "zmapinfo" | | filename = = "mapinfo" )
2016-01-11 13:00:52 +00:00
streams [ s ] = LoadFile ( s ) ;
2013-09-11 09:47:53 +00:00
}
return streams ;
}
#endregion
2014-01-03 10:33:45 +00:00
#region = = = = = = = = = = = = = = = = = = GLDEFS ( mxd )
2013-09-11 09:47:53 +00:00
//mxd
2014-11-25 11:52:01 +00:00
public override Dictionary < string , Stream > GetGldefsData ( GameType gametype )
{
2013-09-11 09:47:53 +00:00
// Error when suspended
2015-12-18 10:16:53 +00:00
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
2013-09-11 09:47:53 +00:00
2014-02-26 14:11:06 +00:00
Dictionary < string , Stream > streams = new Dictionary < string , Stream > ( StringComparer . Ordinal ) ;
2014-01-03 10:33:45 +00:00
2013-09-11 09:47:53 +00:00
//at least one of gldefs should be in root folder
2014-11-25 11:52:01 +00:00
string [ ] files = GetAllFiles ( "" , false ) ;
2013-09-11 09:47:53 +00:00
//try to load game specific GLDEFS first
2015-12-18 10:16:53 +00:00
if ( gametype ! = GameType . UNKNOWN )
2014-11-25 11:52:01 +00:00
{
2015-04-14 11:33:57 +00:00
string lumpname = Gldefs . GLDEFS_LUMPS_PER_GAME [ ( int ) gametype ] ;
2015-12-18 10:16:53 +00:00
foreach ( string s in files )
2014-11-25 11:52:01 +00:00
{
2015-04-14 11:33:57 +00:00
if ( Path . GetFileNameWithoutExtension ( s ) . ToUpperInvariant ( ) = = lumpname )
2013-09-11 09:47:53 +00:00
streams . Add ( s , LoadFile ( s ) ) ;
}
}
2014-11-25 11:52:01 +00:00
// Can be several entries
2015-12-18 10:16:53 +00:00
foreach ( string s in files )
2014-11-25 11:52:01 +00:00
{
2015-04-14 11:33:57 +00:00
if ( Path . GetFileNameWithoutExtension ( s ) . ToUpperInvariant ( ) . StartsWith ( "GLDEFS" ) )
2013-09-11 09:47:53 +00:00
streams . Add ( s , LoadFile ( s ) ) ;
}
return streams ;
}
#endregion
2015-12-18 10:16:53 +00:00
#region = = = = = = = = = = = = = = = = = = REVERBS ( mxd )
2015-01-25 23:22:42 +00:00
public override Dictionary < string , Stream > GetReverbsData ( )
{
// 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 . GetReverbsData ( ) ;
foreach ( KeyValuePair < string , Stream > pair in wadstreams ) streams . Add ( pair . Key , pair . Value ) ;
}
// Then from our own files
string foundfile = FindFirstFile ( "reverbs" , false ) ;
if ( ( foundfile ! = null ) & & FileExists ( foundfile ) )
{
streams . Add ( foundfile , LoadFile ( foundfile ) ) ;
}
return streams ;
}
#endregion
2015-12-18 10:16:53 +00:00
#region = = = = = = = = = = = = = = = = = = SNDSEQ ( mxd )
2015-05-28 13:45:01 +00:00
2015-12-18 10:16:53 +00:00
public override Dictionary < string , Stream > GetSndSeqData ( )
2015-05-28 13:45:01 +00:00
{
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
2015-12-18 10:16:53 +00:00
Dictionary < string , Stream > streams = new Dictionary < string , Stream > ( ) ;
2015-05-28 13:45:01 +00:00
// Get from wads first
//TODO: is this the correct order?..
foreach ( WADReader wr in wads )
{
2015-12-18 10:16:53 +00:00
Dictionary < string , Stream > wadstreams = wr . GetSndSeqData ( ) ;
foreach ( KeyValuePair < string , Stream > pair in wadstreams ) streams . Add ( pair . Key , pair . Value ) ;
2015-05-28 13:45:01 +00:00
}
// Then from our own files
string foundfile = FindFirstFile ( "sndseq" , false ) ;
if ( ! string . IsNullOrEmpty ( foundfile ) & & FileExists ( foundfile ) )
{
2015-12-18 10:16:53 +00:00
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 ) ) ;
2015-05-28 13:45:01 +00:00
}
return streams ;
}
#endregion
2013-09-11 09:47:53 +00:00
#region = = = = = = = = = = = = = = = = = = Methods
// This loads the images in this directory
2009-05-12 09:50:08 +00:00
private ICollection < ImageData > LoadDirectoryImages ( string path , int imagetype , bool includesubdirs )
2009-04-19 18:07:22 +00:00
{
List < ImageData > images = new List < ImageData > ( ) ;
// Go for all files
2014-05-19 13:33:38 +00:00
string [ ] files = GetAllFiles ( path , includesubdirs ) ;
2009-04-19 18:07:22 +00:00
foreach ( string f in files )
{
2014-11-25 11:52:01 +00:00
if ( string . IsNullOrEmpty ( Path . GetFileNameWithoutExtension ( f ) ) )
2009-04-19 18:07:22 +00:00
{
// Can't load image without name
2009-05-10 16:02:08 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Can't load an unnamed texture from \"" + path + "\". Please consider giving names to your resources." ) ;
2014-05-19 13:33:38 +00:00
}
else
{
// Add image to list
2014-11-25 11:52:01 +00:00
images . Add ( CreateImage ( f , imagetype ) ) ;
2009-04-19 18:07:22 +00:00
}
}
// Return result
return images ;
}
// This copies images from a collection unless they already exist in the list
2014-03-05 09:21:28 +00:00
private static void AddImagesToList ( Dictionary < long , ImageData > targetlist , ICollection < ImageData > sourcelist )
2009-04-19 18:07:22 +00:00
{
// Go for all source images
foreach ( ImageData src in sourcelist )
{
// Check if exists in target list
if ( ! targetlist . ContainsKey ( src . LongName ) )
targetlist . Add ( src . LongName , src ) ;
}
}
// This must create an image
2014-11-25 11:52:01 +00:00
protected abstract ImageData CreateImage ( string filename , int imagetype ) ;
2009-04-19 18:07:22 +00:00
// This must return all files in a given directory
protected abstract string [ ] GetAllFiles ( string path , bool subfolders ) ;
2010-08-13 15:19:51 +00:00
// This must return all files in a given directory that have the given file title
protected abstract string [ ] GetAllFilesWithTitle ( string path , string title , bool subfolders ) ;
2013-09-11 09:47:53 +00:00
//mxd. This must return all files in a given directory which title starts with given title
protected abstract string [ ] GetAllFilesWhichTitleStartsWith ( string path , string title ) ;
2012-08-05 19:18:05 +00:00
2009-04-19 18:07:22 +00:00
// This must return all files in a given directory that match the given extension
protected abstract string [ ] GetFilesWithExt ( string path , string extension , bool subfolders ) ;
// This must find the first file that has the specific name, regardless of file extension
2016-01-13 09:34:32 +00:00
internal abstract string FindFirstFile ( string beginswith , bool subfolders ) ;
2009-04-19 18:07:22 +00:00
// This must find the first file that has the specific name, regardless of file extension
protected abstract string FindFirstFile ( string path , string beginswith , bool subfolders ) ;
// This must find the first file that has the specific name
protected abstract string FindFirstFileWithExt ( string path , string beginswith , bool subfolders ) ;
2012-07-23 21:28:23 +00:00
2009-04-19 18:07:22 +00:00
// This must create a temp file for the speciied file and return the absolute path to the temp file
// NOTE: Callers are responsible for removing the temp file when done!
protected abstract string CreateTempFile ( string filename ) ;
// This makes the path relative to the directory, if needed
protected virtual string MakeRelativePath ( string anypath )
{
if ( Path . IsPathRooted ( anypath ) )
{
// Make relative
string lowpath = anypath . ToLowerInvariant ( ) ;
string lowlocation = location . location . ToLowerInvariant ( ) ;
if ( ( lowpath . Length > ( lowlocation . Length + 1 ) ) & & lowpath . StartsWith ( lowlocation ) )
return anypath . Substring ( lowlocation . Length + 1 ) ;
else
return anypath ;
}
else
{
// Path is already relative
return anypath ;
}
}
#endregion
}
}