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
public PK3StructuredReader ( DataLocation dl ) : base ( dl )
{
// 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
if ( stream . Length > 767 ) { //mxd
palette = new Playpal ( stream ) ;
} else {
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 )
{
Dictionary < long , ImageData > images = new Dictionary < long , ImageData > ( ) ;
ICollection < ImageData > collection ;
List < ImageData > imgset = new List < ImageData > ( ) ;
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
// 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
imgset . Clear ( ) ;
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 ;
}
2012-07-23 21:28:23 +00:00
2013-09-11 09:47:53 +00:00
//mxd
public override string GetPatchLocation ( string pname ) {
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
2012-07-23 21:28:23 +00:00
2014-10-07 08:56:21 +00:00
if ( General . Map . Config . MixTexturesFlats )
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
{
2014-10-07 08:56:21 +00:00
// Find in directories ZDoom expects them to be
foreach ( string loc in PatchLocations )
{
string path = Path . Combine ( loc , Path . GetDirectoryName ( pname ) ) ;
string filename = FindFirstFile ( path , Path . GetFileName ( pname ) , true ) ;
if ( ! string . IsNullOrEmpty ( filename ) & & FileExists ( filename ) )
return filename ;
}
}
else
{
// Find in patches directory
string path = Path . Combine ( PATCHES_DIR , Path . GetDirectoryName ( pname ) ) ;
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 filename = FindFirstFile ( path , Path . GetFileName ( pname ) , true ) ;
if ( ! string . IsNullOrEmpty ( filename ) & & FileExists ( filename ) )
return filename ;
}
2012-07-23 21:28:23 +00:00
2013-09-11 09:47:53 +00:00
return pname ;
}
2009-04-19 18:07:22 +00:00
#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.
public override Stream GetFlatData ( string pname ) {
// 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
for ( int i = wads . Count - 1 ; i > - 1 ; i - - ) {
Stream data = wads [ i ] . GetFlatData ( pname ) ;
if ( data ! = null ) return data ;
}
// 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 > ( ) ;
ICollection < ImageData > collection ;
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 - - )
{
collection = wads [ i ] . LoadSprites ( ) ;
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
2009-04-19 18:07:22 +00:00
#region = = = = = = = = = = = = = = = = = = Decorate
// 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
2014-01-03 10:33:45 +00:00
#region = = = = = = = = = = = = = = = = = = Modeldef ( mxd )
2013-09-11 09:47:53 +00:00
//mxd
public override Dictionary < string , Stream > GetModeldefData ( ) {
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
//modedef should be in root folder
string [ ] allFiles = 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
foreach ( string s in allFiles ) {
if ( s . ToLowerInvariant ( ) . IndexOf ( "modeldef" ) ! = - 1 ) {
streams . Add ( s , LoadFile ( s ) ) ;
}
}
return streams ;
}
2014-01-03 10:33:45 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Voxeldef ( mxd )
//mxd. This returns the list of voxels, which can be used without VOXELDEF definition
public override string [ ] GetVoxelNames ( ) {
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
string [ ] files = GetAllFiles ( "voxels" , false ) ;
List < string > voxels = new List < string > ( ) ;
2014-01-08 09:46:57 +00:00
Regex spriteName = new Regex ( SPRITE_NAME_PATTERN ) ;
2014-01-03 10:33:45 +00:00
for ( int i = 0 ; i < files . Length ; i + + ) {
string s = Path . GetFileNameWithoutExtension ( files [ i ] ) . ToUpperInvariant ( ) ;
if ( spriteName . IsMatch ( s ) ) voxels . Add ( s ) ;
}
return voxels . ToArray ( ) ;
}
//mxd
public override KeyValuePair < string , Stream > GetVoxeldefData ( ) {
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
//voxeldef should be in root folder
string [ ] files = GetAllFiles ( "" , false ) ;
foreach ( string s in files ) {
if ( Path . GetFileNameWithoutExtension ( s ) . ToUpperInvariant ( ) = = "VOXELDEF" ) {
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
public override Dictionary < string , Stream > GetMapinfoData ( ) {
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
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
//mapinfo should be in root folder
string [ ] allFiles = GetAllFiles ( "" , false ) ;
string fileName ;
//try to find (z)mapinfo
foreach ( string s in allFiles ) {
fileName = s . ToLowerInvariant ( ) ;
if ( fileName . IndexOf ( "zmapinfo" ) ! = - 1 | | fileName . IndexOf ( "mapinfo" ) ! = - 1 )
streams . Add ( s , LoadFile ( s ) ) ;
}
return streams ;
}
#endregion
2014-01-03 10:33:45 +00:00
#region = = = = = = = = = = = = = = = = = = GLDEFS ( mxd )
2013-09-11 09:47:53 +00:00
//mxd
public override Dictionary < string , Stream > GetGldefsData ( GameType gameType ) {
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
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
string [ ] allFiles = GetAllFiles ( "" , false ) ;
//try to load game specific GLDEFS first
string lumpName ;
if ( gameType ! = GameType . UNKNOWN ) {
lumpName = Gldefs . GLDEFS_LUMPS_PER_GAME [ ( int ) gameType ] . ToLowerInvariant ( ) ;
foreach ( string s in allFiles ) {
if ( s . ToLowerInvariant ( ) . IndexOf ( lumpName ) ! = - 1 )
streams . Add ( s , LoadFile ( s ) ) ;
}
}
//can be several entries
lumpName = "gldefs" ;
foreach ( string s in allFiles ) {
if ( s . ToLowerInvariant ( ) . IndexOf ( lumpName ) ! = - 1 )
streams . Add ( s , LoadFile ( s ) ) ;
}
return streams ;
}
//mxd
public override Dictionary < string , Stream > GetGldefsData ( string location ) {
// Error when suspended
if ( issuspended ) throw new Exception ( "Data reader is suspended" ) ;
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
Stream s = LoadFile ( location ) ;
2014-01-03 10:33:45 +00:00
if ( s ! = null ) streams . Add ( location , s ) ;
2013-09-11 09:47:53 +00:00
return streams ;
}
#endregion
#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 > ( ) ;
string name ;
// 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-10-12 21:59:16 +00:00
//mxd. Skip IMGZ files
if ( Path . GetExtension ( f ) . ToUpperInvariant ( ) = = ".IMGZ" ) continue ;
2009-04-19 18:07:22 +00:00
// Make the texture name from filename without extension
2014-05-19 13:33:38 +00:00
name = Path . GetFileNameWithoutExtension ( f ) ;
if ( string . IsNullOrEmpty ( name ) )
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
{
if ( name . Length > General . Map . Config . MaxTextureNameLength ) name = name . Substring ( 0 , General . Map . Config . MaxTextureNameLength ) ;
if ( General . Settings . CapitalizeTextureNames ) name = name . ToUpperInvariant ( ) ; //mxd
// Add image to list
images . Add ( CreateImage ( name , 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
2009-05-12 09:50:08 +00:00
protected abstract ImageData CreateImage ( string name , 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
protected abstract string FindFirstFile ( string beginswith , bool subfolders ) ;
// 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
}
}