2007-10-01 20:57:41 +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 ;
using System.Collections.Generic ;
using System.Globalization ;
using System.Text ;
using System.Drawing ;
using System.Drawing.Imaging ;
using System.IO ;
2007-10-07 22:21:47 +00:00
using CodeImp.DoomBuilder.IO ;
2007-10-14 21:31:45 +00:00
using System.Windows.Forms ;
2007-10-26 13:17:20 +00:00
using SlimDX.Direct3D9 ;
2007-10-26 15:28:32 +00:00
using CodeImp.DoomBuilder.Config ;
using System.Threading ;
2008-09-28 21:20:56 +00:00
using CodeImp.DoomBuilder.Map ;
2008-11-18 13:05:04 +00:00
using CodeImp.DoomBuilder.Windows ;
2009-02-12 17:58:09 +00:00
using CodeImp.DoomBuilder.ZDoom ;
2007-10-01 20:57:41 +00:00
#endregion
namespace CodeImp.DoomBuilder.Data
{
2008-01-02 21:49:43 +00:00
public sealed class DataManager
2007-10-01 20:57:41 +00:00
{
#region = = = = = = = = = = = = = = = = = = Constants
2008-12-11 10:59:35 +00:00
public const string INTERNAL_PREFIX = "internal:" ;
2007-10-01 20:57:41 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
2008-10-01 14:17:52 +00:00
2007-10-04 18:16:05 +00:00
// Data containers
2007-10-07 22:21:47 +00:00
private List < DataReader > containers ;
2009-01-21 23:09:25 +00:00
private DataReader currentreader ;
2008-10-01 14:17:52 +00:00
2007-10-07 22:21:47 +00:00
// Palette
private Playpal palette ;
2008-10-01 14:17:52 +00:00
// Textures, Flats and Sprites
2007-10-07 22:21:47 +00:00
private Dictionary < long , ImageData > textures ;
2007-12-27 01:24:11 +00:00
private List < string > texturenames ;
2007-10-07 22:21:47 +00:00
private Dictionary < long , ImageData > flats ;
2007-12-27 01:24:11 +00:00
private List < string > flatnames ;
2007-10-07 22:21:47 +00:00
private Dictionary < long , ImageData > sprites ;
2008-10-01 14:17:52 +00:00
private List < MatchingTextureSet > texturesets ;
2009-03-01 18:34:37 +00:00
private List < ResourceTextureSet > resourcetextures ;
2009-01-09 23:05:41 +00:00
private AllTextureSet alltextures ;
2008-09-26 15:15:56 +00:00
2007-10-26 15:28:32 +00:00
// Background loading
2008-09-26 15:15:56 +00:00
private Queue < ImageData > imageque ;
2007-10-26 15:28:32 +00:00
private Thread backgroundloader ;
2008-09-28 21:20:56 +00:00
private volatile bool updatedusedtextures ;
2009-01-24 19:05:58 +00:00
private bool notifiedbusy ;
2007-10-26 15:28:32 +00:00
2008-09-25 18:42:45 +00:00
// Image previews
private PreviewManager previews ;
2008-01-13 21:23:59 +00:00
// Special images
private ImageData missingtexture3d ;
2009-01-24 14:48:43 +00:00
private ImageData unknowntexture3d ;
2008-09-28 21:20:56 +00:00
private ImageData hourglass3d ;
2008-12-03 07:04:57 +00:00
private ImageData crosshair ;
2008-12-06 13:20:47 +00:00
private ImageData crosshairbusy ;
2008-12-11 10:59:35 +00:00
private Dictionary < string , ImageData > internalsprites ;
2008-12-14 23:24:40 +00:00
private ImageData thingbox ;
2008-01-13 21:23:59 +00:00
2008-10-15 17:26:59 +00:00
// Used images
private Dictionary < long , long > usedimages ;
2009-01-21 16:18:30 +00:00
// Things combined with things created from Decorate
private List < ThingCategory > thingcategories ;
private Dictionary < int , ThingTypeInfo > thingtypes ;
2009-04-18 12:01:08 +00:00
// Timing
private double loadstarttime ;
private double loadfinishtime ;
2007-10-01 20:57:41 +00:00
// Disposing
private bool isdisposed = false ;
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
2007-10-08 14:29:31 +00:00
public Playpal Palette { get { return palette ; } }
2008-09-28 21:20:56 +00:00
public PreviewManager Previews { get { return previews ; } }
2007-10-31 20:34:09 +00:00
public ICollection < ImageData > Textures { get { return textures . Values ; } }
public ICollection < ImageData > Flats { get { return flats . Values ; } }
2007-12-27 01:24:11 +00:00
public List < string > TextureNames { get { return texturenames ; } }
public List < string > FlatNames { get { return flatnames ; } }
2007-10-01 20:57:41 +00:00
public bool IsDisposed { get { return isdisposed ; } }
2008-01-13 21:23:59 +00:00
public ImageData MissingTexture3D { get { return missingtexture3d ; } }
2009-01-24 14:48:43 +00:00
public ImageData UnknownTexture3D { get { return unknowntexture3d ; } }
2008-09-28 21:20:56 +00:00
public ImageData Hourglass3D { get { return hourglass3d ; } }
2008-12-03 07:04:57 +00:00
public ImageData Crosshair3D { get { return crosshair ; } }
2008-12-06 13:20:47 +00:00
public ImageData CrosshairBusy3D { get { return crosshairbusy ; } }
2008-12-14 23:24:40 +00:00
public ImageData ThingBox { get { return thingbox ; } }
2009-01-21 16:18:30 +00:00
public List < ThingCategory > ThingCategories { get { return thingcategories ; } }
public ICollection < ThingTypeInfo > ThingTypes { get { return thingtypes . Values ; } }
2008-10-01 14:17:52 +00:00
internal ICollection < MatchingTextureSet > TextureSets { get { return texturesets ; } }
2009-03-01 18:34:37 +00:00
internal ICollection < ResourceTextureSet > ResourceTextureSets { get { return resourcetextures ; } }
2009-01-09 23:05:41 +00:00
internal AllTextureSet AllTextureSet { get { return alltextures ; } }
2007-10-26 19:06:59 +00:00
2008-05-05 14:22:36 +00:00
public bool IsLoading
{
get
{
2008-09-28 21:20:56 +00:00
if ( imageque ! = null )
2008-05-05 14:22:36 +00:00
{
2008-09-28 21:20:56 +00:00
return ( backgroundloader ! = null ) & & backgroundloader . IsAlive & & ( ( imageque . Count > 0 ) | | previews . IsLoading ) ;
2008-05-05 14:22:36 +00:00
}
else
{
return false ;
}
}
}
2007-10-01 20:57:41 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
2008-01-02 21:49:43 +00:00
internal DataManager ( )
2007-10-01 20:57:41 +00:00
{
// We have no destructor
GC . SuppressFinalize ( this ) ;
2008-01-13 21:23:59 +00:00
// Load special images
missingtexture3d = new ResourceImage ( "MissingTexture3D.png" ) ;
missingtexture3d . LoadImage ( ) ;
2009-01-24 14:48:43 +00:00
unknowntexture3d = new ResourceImage ( "UnknownTexture3D.png" ) ;
unknowntexture3d . LoadImage ( ) ;
2008-09-28 21:20:56 +00:00
hourglass3d = new ResourceImage ( "Hourglass3D.png" ) ;
hourglass3d . LoadImage ( ) ;
2008-12-03 07:04:57 +00:00
crosshair = new ResourceImage ( "Crosshair.png" ) ;
crosshair . LoadImage ( ) ;
2008-12-06 13:20:47 +00:00
crosshairbusy = new ResourceImage ( "CrosshairBusy.png" ) ;
crosshairbusy . LoadImage ( ) ;
2008-12-14 23:24:40 +00:00
thingbox = new ResourceImage ( "ThingBox.png" ) ;
thingbox . LoadImage ( ) ;
2007-10-01 20:57:41 +00:00
}
2007-10-04 18:16:05 +00:00
// Disposer
2008-01-02 21:49:43 +00:00
internal void Dispose ( )
2007-10-01 20:57:41 +00:00
{
// Not already disposed?
if ( ! isdisposed )
{
// Clean up
2007-10-05 11:17:58 +00:00
Unload ( ) ;
2008-01-13 21:23:59 +00:00
missingtexture3d . Dispose ( ) ;
missingtexture3d = null ;
2009-01-24 14:48:43 +00:00
unknowntexture3d . Dispose ( ) ;
unknowntexture3d = null ;
2008-12-03 07:04:57 +00:00
hourglass3d . Dispose ( ) ;
hourglass3d = null ;
crosshair . Dispose ( ) ;
crosshair = null ;
2008-12-06 13:20:47 +00:00
crosshairbusy . Dispose ( ) ;
crosshairbusy = null ;
2008-12-14 23:24:40 +00:00
thingbox . Dispose ( ) ;
thingbox = null ;
2007-10-05 11:17:58 +00:00
2007-10-01 20:57:41 +00:00
// Done
isdisposed = true ;
}
}
#endregion
2007-10-04 18:16:05 +00:00
#region = = = = = = = = = = = = = = = = = = Loading / Unloading
2007-10-05 11:17:58 +00:00
// This loads all data resources
2008-01-02 21:49:43 +00:00
internal void Load ( DataLocationList configlist , DataLocationList maplist , DataLocation maplocation )
2007-10-05 11:17:58 +00:00
{
2007-10-07 22:21:47 +00:00
DataLocationList all = DataLocationList . Combined ( configlist , maplist ) ;
2007-10-05 11:17:58 +00:00
all . Add ( maplocation ) ;
Load ( all ) ;
}
// This loads all data resources
2008-01-02 21:49:43 +00:00
internal void Load ( DataLocationList configlist , DataLocationList maplist )
2007-10-05 11:17:58 +00:00
{
2007-10-07 22:21:47 +00:00
DataLocationList all = DataLocationList . Combined ( configlist , maplist ) ;
2007-10-05 11:17:58 +00:00
Load ( all ) ;
}
2007-10-04 18:16:05 +00:00
// This loads all data resources
2008-01-02 21:49:43 +00:00
internal void Load ( DataLocationList locations )
2007-10-04 18:16:05 +00:00
{
2009-01-21 16:18:30 +00:00
int texcount , flatcount , spritecount , thingcount ;
2009-04-18 09:38:13 +00:00
Dictionary < long , ImageData > texturesonly = new Dictionary < long , ImageData > ( ) ;
Dictionary < long , ImageData > flatsonly = new Dictionary < long , ImageData > ( ) ;
2007-10-07 22:21:47 +00:00
DataReader c ;
// Create collections
containers = new List < DataReader > ( ) ;
textures = new Dictionary < long , ImageData > ( ) ;
flats = new Dictionary < long , ImageData > ( ) ;
sprites = new Dictionary < long , ImageData > ( ) ;
2007-12-27 01:24:11 +00:00
texturenames = new List < string > ( ) ;
flatnames = new List < string > ( ) ;
2008-09-28 21:20:56 +00:00
imageque = new Queue < ImageData > ( ) ;
2008-09-25 18:42:45 +00:00
previews = new PreviewManager ( ) ;
2008-10-01 14:17:52 +00:00
texturesets = new List < MatchingTextureSet > ( ) ;
2008-10-15 17:26:59 +00:00
usedimages = new Dictionary < long , long > ( ) ;
2008-12-11 10:59:35 +00:00
internalsprites = new Dictionary < string , ImageData > ( ) ;
2009-01-21 16:18:30 +00:00
thingcategories = General . Map . Config . GetThingCategories ( ) ;
thingtypes = General . Map . Config . GetThingTypes ( ) ;
2008-10-01 14:17:52 +00:00
// Load texture sets
foreach ( DefinedTextureSet ts in General . Map . ConfigSettings . TextureSets )
texturesets . Add ( new MatchingTextureSet ( ts ) ) ;
2008-10-02 18:53:07 +00:00
// Sort the texture sets
texturesets . Sort ( ) ;
2009-01-09 23:05:41 +00:00
// Special textures sets
alltextures = new AllTextureSet ( ) ;
2009-03-01 18:34:37 +00:00
resourcetextures = new List < ResourceTextureSet > ( ) ;
2007-10-04 18:16:05 +00:00
// Go for all locations
foreach ( DataLocation dl in locations )
{
// Nothing chosen yet
c = null ;
2007-10-05 11:17:58 +00:00
2007-10-07 22:21:47 +00:00
// TODO: Make this work more elegant using reflection.
// Make DataLocation.type of type Type and assign the
// types of the desired reader classes.
2007-10-14 21:31:45 +00:00
2009-03-25 12:42:32 +00:00
try
2007-10-04 18:16:05 +00:00
{
2007-10-14 21:31:45 +00:00
// Choose container type
switch ( dl . type )
{
// WAD file container
case DataLocation . RESOURCE_WAD :
c = new WADReader ( dl ) ;
break ;
// Directory container
case DataLocation . RESOURCE_DIRECTORY :
c = new DirectoryReader ( dl ) ;
break ;
2007-10-26 14:16:23 +00:00
// PK3 file container
case DataLocation . RESOURCE_PK3 :
c = new PK3Reader ( dl ) ;
break ;
2007-10-14 21:31:45 +00:00
}
2007-10-04 18:16:05 +00:00
}
2009-01-03 19:45:59 +00:00
catch ( Exception e )
2007-10-14 21:31:45 +00:00
{
// Unable to load resource
2009-02-26 23:27:46 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error while creating data reader. " + e . GetType ( ) . Name + ": " + e . Message ) ;
2009-01-03 19:45:59 +00:00
General . WriteLogLine ( e . StackTrace ) ;
2007-10-14 21:31:45 +00:00
General . ShowErrorMessage ( "Unable to load resources from location \"" + dl . location + "\". Please make sure the location is accessible and not in use by another program." , MessageBoxButtons . OK ) ;
continue ;
}
2009-02-26 23:27:46 +00:00
2007-10-07 22:21:47 +00:00
// Add container
2009-03-01 18:34:37 +00:00
if ( c ! = null )
{
containers . Add ( c ) ;
resourcetextures . Add ( c . TextureSet ) ;
}
2007-10-04 18:16:05 +00:00
}
2008-10-01 14:17:52 +00:00
2007-10-07 22:21:47 +00:00
// Load stuff
LoadPalette ( ) ;
2009-04-18 09:38:13 +00:00
texcount = LoadTextures ( texturesonly ) ;
flatcount = LoadFlats ( flatsonly ) ;
2009-01-21 16:18:30 +00:00
thingcount = LoadDecorateThings ( ) ;
2008-05-05 14:22:36 +00:00
spritecount = LoadSprites ( ) ;
2008-12-11 10:59:35 +00:00
LoadInternalSprites ( ) ;
2009-04-18 09:38:13 +00:00
// Process textures
foreach ( KeyValuePair < long , ImageData > t in texturesonly )
{
textures . Add ( t . Key , t . Value ) ;
texturenames . Add ( t . Value . Name ) ;
}
// Process flats
foreach ( KeyValuePair < long , ImageData > f in flatsonly )
{
flats . Add ( f . Key , f . Value ) ;
flatnames . Add ( f . Value . Name ) ;
}
// Mixed textures and flats?
if ( General . Map . Config . MixTexturesFlats )
{
// Add textures to flats
foreach ( KeyValuePair < long , ImageData > t in texturesonly )
{
if ( ! flats . ContainsKey ( t . Key ) )
{
flats . Add ( t . Key , t . Value ) ;
flatnames . Add ( t . Value . Name ) ;
}
}
// Add flats to textures
foreach ( KeyValuePair < long , ImageData > f in flatsonly )
{
if ( ! textures . ContainsKey ( f . Key ) )
{
textures . Add ( f . Key , f . Value ) ;
texturenames . Add ( f . Value . Name ) ;
}
}
}
2008-10-01 14:17:52 +00:00
2008-05-05 14:22:36 +00:00
// Sort names
texturenames . Sort ( ) ;
flatnames . Sort ( ) ;
2008-10-01 20:30:29 +00:00
2009-01-22 22:22:02 +00:00
// Sort things
foreach ( ThingCategory tc in thingcategories ) tc . SortIfNeeded ( ) ;
2008-10-01 20:30:29 +00:00
// Update the used textures
General . Map . Data . UpdateUsedTextures ( ) ;
2008-05-05 14:22:36 +00:00
2008-10-01 14:17:52 +00:00
// Add texture names to texture sets
foreach ( KeyValuePair < long , ImageData > img in textures )
{
// Add to all sets where it matches
bool matchfound = false ;
foreach ( MatchingTextureSet ms in texturesets )
matchfound | = ms . AddTexture ( img . Value ) ;
2009-01-09 23:05:41 +00:00
// Add to all
alltextures . AddTexture ( img . Value ) ;
2008-10-01 14:17:52 +00:00
}
// Add flat names to texture sets
foreach ( KeyValuePair < long , ImageData > img in flats )
{
// Add to all sets where it matches
bool matchfound = false ;
foreach ( MatchingTextureSet ms in texturesets )
matchfound | = ms . AddFlat ( img . Value ) ;
2009-01-09 23:05:41 +00:00
// Add to all
alltextures . AddFlat ( img . Value ) ;
2008-10-01 14:17:52 +00:00
}
2007-10-26 15:28:32 +00:00
// Start background loading
StartBackgroundLoader ( ) ;
2008-10-01 14:17:52 +00:00
2008-05-05 14:22:36 +00:00
// Output info
2009-01-21 16:18:30 +00:00
General . WriteLogLine ( "Loaded " + texcount + " textures, " + flatcount + " flats, " + spritecount + " sprites, " + thingcount + " decorate things" ) ;
2007-10-04 18:16:05 +00:00
}
2008-12-11 10:59:35 +00:00
2007-10-04 18:16:05 +00:00
// This unloads all data
2008-01-02 21:49:43 +00:00
internal void Unload ( )
2007-10-04 18:16:05 +00:00
{
2007-10-26 15:28:32 +00:00
// Stop background loader
StopBackgroundLoader ( ) ;
2008-09-25 18:42:45 +00:00
// Dispose preview manager
previews . Dispose ( ) ;
previews = null ;
2007-10-07 22:21:47 +00:00
// Dispose resources
foreach ( KeyValuePair < long , ImageData > i in textures ) i . Value . Dispose ( ) ;
foreach ( KeyValuePair < long , ImageData > i in flats ) i . Value . Dispose ( ) ;
foreach ( KeyValuePair < long , ImageData > i in sprites ) i . Value . Dispose ( ) ;
palette = null ;
2008-10-01 14:17:52 +00:00
2007-10-04 18:16:05 +00:00
// Dispose containers
2007-10-07 22:21:47 +00:00
foreach ( DataReader c in containers ) c . Dispose ( ) ;
2007-10-04 18:16:05 +00:00
containers . Clear ( ) ;
2008-10-01 14:17:52 +00:00
2008-05-05 14:22:36 +00:00
// Trash collections
containers = null ;
textures = null ;
flats = null ;
sprites = null ;
texturenames = null ;
flatnames = null ;
2008-09-28 21:20:56 +00:00
imageque = null ;
2008-12-11 10:59:35 +00:00
internalsprites = null ;
2007-10-04 18:16:05 +00:00
}
2008-10-01 14:17:52 +00:00
2007-10-07 22:21:47 +00:00
#endregion
2007-10-04 18:16:05 +00:00
2007-10-07 22:21:47 +00:00
#region = = = = = = = = = = = = = = = = = = Suspend / Resume
2007-10-13 14:05:45 +00:00
// This suspends data resources
2008-01-02 21:49:43 +00:00
internal void Suspend ( )
2007-10-05 11:17:58 +00:00
{
2007-10-26 15:28:32 +00:00
// Stop background loader
StopBackgroundLoader ( ) ;
2007-10-05 11:17:58 +00:00
// Go for all containers
2007-10-07 22:21:47 +00:00
foreach ( DataReader d in containers )
2007-10-05 11:17:58 +00:00
{
2007-10-13 14:05:45 +00:00
// Suspend
General . WriteLogLine ( "Suspended data resource '" + d . Location . location + "'" ) ;
d . Suspend ( ) ;
2007-10-05 11:17:58 +00:00
}
}
2007-10-13 14:05:45 +00:00
// This resumes data resources
2008-01-02 21:49:43 +00:00
internal void Resume ( )
2007-10-05 11:17:58 +00:00
{
// Go for all containers
2007-10-07 22:21:47 +00:00
foreach ( DataReader d in containers )
2007-10-05 11:17:58 +00:00
{
2007-10-14 21:31:45 +00:00
try
{
// Resume
General . WriteLogLine ( "Resumed data resource '" + d . Location . location + "'" ) ;
d . Resume ( ) ;
}
2009-01-03 19:45:59 +00:00
catch ( Exception e )
2007-10-14 21:31:45 +00:00
{
// Unable to load resource
2009-02-26 23:27:46 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error while resuming data reader. " + e . GetType ( ) . Name + ": " + e . Message ) ;
2009-01-03 19:45:59 +00:00
General . WriteLogLine ( e . StackTrace ) ;
2007-10-14 21:31:45 +00:00
General . ShowErrorMessage ( "Unable to load resources from location \"" + d . Location . location + "\". Please make sure the location is accessible and not in use by another program." , MessageBoxButtons . OK ) ;
}
2007-10-05 11:17:58 +00:00
}
2007-10-26 15:28:32 +00:00
// Start background loading
StartBackgroundLoader ( ) ;
2007-10-05 11:17:58 +00:00
}
2007-10-01 20:57:41 +00:00
#endregion
2007-10-07 22:21:47 +00:00
2007-10-26 15:28:32 +00:00
#region = = = = = = = = = = = = = = = = = = Background Loading
2008-10-23 11:23:11 +00:00
2007-10-26 15:28:32 +00:00
// This starts background loading
private void StartBackgroundLoader ( )
{
2009-04-18 12:01:08 +00:00
// Timing
loadstarttime = General . Clock . GetCurrentTime ( ) ;
loadfinishtime = 0 ;
2007-10-26 15:28:32 +00:00
// If a loader is already running, stop it first
if ( backgroundloader ! = null ) StopBackgroundLoader ( ) ;
2008-02-23 13:12:59 +00:00
2008-05-05 14:22:36 +00:00
// Start a low priority thread to load images in background
General . WriteLogLine ( "Starting background resource loading..." ) ;
backgroundloader = new Thread ( new ThreadStart ( BackgroundLoad ) ) ;
2008-09-28 21:20:56 +00:00
backgroundloader . Name = "Background Loader" ;
2008-05-05 14:22:36 +00:00
backgroundloader . Priority = ThreadPriority . Lowest ;
2008-10-23 11:23:11 +00:00
backgroundloader . IsBackground = true ;
2008-05-05 14:22:36 +00:00
backgroundloader . Start ( ) ;
2007-10-26 15:28:32 +00:00
}
2008-10-23 11:23:11 +00:00
2007-10-26 15:28:32 +00:00
// This stops background loading
private void StopBackgroundLoader ( )
{
2008-09-28 21:20:56 +00:00
ImageData img ;
2008-05-05 14:22:36 +00:00
2007-10-26 15:28:32 +00:00
General . WriteLogLine ( "Stopping background resource loading..." ) ;
2007-10-26 18:04:54 +00:00
if ( backgroundloader ! = null )
{
// Stop the thread and wait for it to end
backgroundloader . Interrupt ( ) ;
backgroundloader . Join ( ) ;
2007-10-26 15:28:32 +00:00
2008-05-05 14:22:36 +00:00
// Reset load states on all images in the list
2008-09-28 21:20:56 +00:00
while ( imageque . Count > 0 )
2008-05-05 14:22:36 +00:00
{
2008-09-28 21:20:56 +00:00
img = imageque . Dequeue ( ) ;
switch ( img . ImageState )
{
case ImageLoadState . Loading :
img . ImageState = ImageLoadState . None ;
break ;
case ImageLoadState . Unloading :
img . ImageState = ImageLoadState . Ready ;
break ;
}
switch ( img . PreviewState )
{
case ImageLoadState . Loading :
img . PreviewState = ImageLoadState . None ;
break ;
case ImageLoadState . Unloading :
img . PreviewState = ImageLoadState . Ready ;
break ;
}
2008-05-05 14:22:36 +00:00
}
2007-10-26 18:04:54 +00:00
// Done
2009-01-24 19:05:58 +00:00
notifiedbusy = false ;
2007-10-26 18:04:54 +00:00
backgroundloader = null ;
2009-02-26 14:16:18 +00:00
General . SendMessage ( General . MainWindow . Handle , ( int ) MainForm . ThreadMessages . UpdateStatus , 0 , 0 ) ;
2007-10-26 18:04:54 +00:00
}
2007-10-26 15:28:32 +00:00
}
2008-09-26 15:15:56 +00:00
2007-10-26 15:28:32 +00:00
// The background loader
private void BackgroundLoad ( )
{
try
{
2008-05-05 14:22:36 +00:00
do
{
2008-09-28 21:20:56 +00:00
// Do we have to update the used-in-map status?
2008-10-15 17:26:59 +00:00
if ( updatedusedtextures ) BackgroundUpdateUsedTextures ( ) ;
2008-09-28 21:20:56 +00:00
2008-05-05 14:22:36 +00:00
// Get next item
ImageData image = null ;
2008-09-26 15:15:56 +00:00
lock ( imageque )
{
2008-09-28 21:20:56 +00:00
// Fetch next image to process
2008-09-26 15:15:56 +00:00
if ( imageque . Count > 0 ) image = imageque . Dequeue ( ) ;
}
// Any image to process?
if ( image ! = null )
2008-05-05 14:22:36 +00:00
{
2008-09-26 15:15:56 +00:00
// Load this image?
2008-09-28 21:20:56 +00:00
if ( image . IsReferenced & & ( image . ImageState ! = ImageLoadState . Ready ) )
2008-05-05 14:22:36 +00:00
{
2008-09-28 21:20:56 +00:00
image . LoadImage ( ) ;
2008-09-26 15:15:56 +00:00
}
// Unload this image?
2008-09-28 21:20:56 +00:00
if ( ! image . IsReferenced & & ( image . ImageState ! = ImageLoadState . None ) )
2008-09-26 15:15:56 +00:00
{
// Still unreferenced?
2008-09-28 21:20:56 +00:00
image . UnloadImage ( ) ;
2008-05-05 14:22:36 +00:00
}
}
2008-09-26 15:15:56 +00:00
// Doing something?
2008-05-05 14:22:36 +00:00
if ( image ! = null )
{
// Wait a bit and update icon
2009-01-24 19:05:58 +00:00
if ( ! notifiedbusy )
{
notifiedbusy = true ;
2009-02-26 14:16:18 +00:00
General . SendMessage ( General . MainWindow . Handle , ( int ) MainForm . ThreadMessages . UpdateStatus , 0 , 0 ) ;
2009-01-24 19:05:58 +00:00
}
2008-10-08 19:02:35 +00:00
Thread . Sleep ( 0 ) ;
2008-05-05 14:22:36 +00:00
}
else
{
2008-09-26 15:15:56 +00:00
// Process previews only when we don't have images to process
// because these are lower priority than the actual images
if ( previews . BackgroundLoad ( ) )
{
// Wait a bit and update icon
2009-01-24 19:05:58 +00:00
if ( ! notifiedbusy )
{
notifiedbusy = true ;
2009-02-26 14:16:18 +00:00
General . SendMessage ( General . MainWindow . Handle , ( int ) MainForm . ThreadMessages . UpdateStatus , 0 , 0 ) ;
2009-01-24 19:05:58 +00:00
}
2008-10-08 19:02:35 +00:00
Thread . Sleep ( 0 ) ;
2008-09-26 15:15:56 +00:00
}
else
{
2009-01-24 19:05:58 +00:00
if ( notifiedbusy )
{
notifiedbusy = false ;
2009-02-26 14:16:18 +00:00
General . SendMessage ( General . MainWindow . Handle , ( int ) MainForm . ThreadMessages . UpdateStatus , 0 , 0 ) ;
2009-01-24 19:05:58 +00:00
}
2009-04-18 12:01:08 +00:00
// Timing
if ( loadfinishtime = = 0 )
{
loadfinishtime = General . Clock . GetCurrentTime ( ) ;
double deltatimesec = ( loadfinishtime - loadstarttime ) / 1000.0d ;
General . WriteLogLine ( "Resources loading took " + deltatimesec . ToString ( "########0.00" ) + " seconds" ) ;
}
2008-09-26 15:15:56 +00:00
// Wait longer to release CPU resources
Thread . Sleep ( 50 ) ;
}
2008-05-05 14:22:36 +00:00
}
}
while ( true ) ;
2007-10-26 15:28:32 +00:00
}
catch ( ThreadInterruptedException )
{
return ;
}
}
2008-09-26 15:15:56 +00:00
2008-05-05 14:22:36 +00:00
// This adds an image for background loading or unloading
2008-09-26 15:15:56 +00:00
internal void ProcessImage ( ImageData img )
2007-10-26 15:28:32 +00:00
{
2008-09-26 15:15:56 +00:00
// Load this image?
if ( ( img . ImageState = = ImageLoadState . None ) & & img . IsReferenced )
{
// Add for loading
img . ImageState = ImageLoadState . Loading ;
lock ( imageque ) { imageque . Enqueue ( img ) ; }
}
2007-10-26 15:28:32 +00:00
2008-09-26 15:15:56 +00:00
// Unload this image?
if ( ( img . ImageState = = ImageLoadState . Ready ) & & ! img . IsReferenced )
2007-10-26 15:28:32 +00:00
{
2008-09-26 15:15:56 +00:00
// Add for unloading
img . ImageState = ImageLoadState . Unloading ;
lock ( imageque ) { imageque . Enqueue ( img ) ; }
2008-05-05 14:22:36 +00:00
}
// Update icon
2009-02-26 14:16:18 +00:00
General . SendMessage ( General . MainWindow . Handle , ( int ) MainForm . ThreadMessages . UpdateStatus , 0 , 0 ) ;
2008-05-05 14:22:36 +00:00
}
2008-09-28 21:20:56 +00:00
// This updates the used-in-map status on all textures and flats
private void BackgroundUpdateUsedTextures ( )
{
2008-10-15 17:26:59 +00:00
lock ( usedimages )
2008-09-28 21:20:56 +00:00
{
2008-10-15 17:26:59 +00:00
// Set used on all textures
foreach ( KeyValuePair < long , ImageData > i in textures )
{
i . Value . SetUsedInMap ( usedimages . ContainsKey ( i . Key ) ) ;
if ( i . Value . IsImageLoaded ! = i . Value . IsReferenced ) ProcessImage ( i . Value ) ;
}
2008-09-28 21:20:56 +00:00
2009-04-18 09:38:13 +00:00
// Set used on all flats
foreach ( KeyValuePair < long , ImageData > i in flats )
2008-10-15 17:26:59 +00:00
{
2009-04-18 09:38:13 +00:00
i . Value . SetUsedInMap ( usedimages . ContainsKey ( i . Key ) ) ;
if ( i . Value . IsImageLoaded ! = i . Value . IsReferenced ) ProcessImage ( i . Value ) ;
2008-10-15 17:26:59 +00:00
}
2009-04-18 09:38:13 +00:00
2008-10-15 17:26:59 +00:00
// Done
updatedusedtextures = false ;
2008-09-28 21:20:56 +00:00
}
}
2007-10-26 15:28:32 +00:00
#endregion
2007-10-07 22:21:47 +00:00
#region = = = = = = = = = = = = = = = = = = Palette
// This loads the PLAYPAL palette
private void LoadPalette ( )
{
// Go for all opened containers
for ( int i = containers . Count - 1 ; i > = 0 ; i - - )
{
// Load palette
palette = containers [ i ] . LoadPalette ( ) ;
if ( palette ! = null ) break ;
}
2007-12-26 01:14:31 +00:00
// Make empty palette when still no palette found
if ( palette = = null )
{
2009-03-01 09:15:58 +00:00
General . ErrorLogger . Add ( ErrorType . Warning , "None of the loaded resources define a color palette. Did you forget to configure an IWAD for this configuration?" ) ;
2007-12-26 01:14:31 +00:00
palette = new Playpal ( ) ;
}
2007-10-07 22:21:47 +00:00
}
#endregion
#region = = = = = = = = = = = = = = = = = = Textures
// This loads the textures
2009-04-18 09:38:13 +00:00
private int LoadTextures ( Dictionary < long , ImageData > list )
2007-10-07 22:21:47 +00:00
{
ICollection < ImageData > images ;
2007-10-27 13:59:24 +00:00
PatchNames pnames = new PatchNames ( ) ;
PatchNames newpnames ;
2008-05-05 14:22:36 +00:00
int counter = 0 ;
2008-10-02 18:53:07 +00:00
long firsttexture = 0 ;
2009-01-21 16:18:30 +00:00
2007-10-07 22:21:47 +00:00
// Go for all opened containers
foreach ( DataReader dr in containers )
{
// Load PNAMES info
// Note that pnames is NOT set to null in the loop
// because if a container has no pnames, the pnames
// of the previous (higher) container should be used.
2007-10-27 13:59:24 +00:00
newpnames = dr . LoadPatchNames ( ) ;
if ( newpnames ! = null ) pnames = newpnames ;
// Load textures
images = dr . LoadTextures ( pnames ) ;
if ( images ! = null )
2007-10-07 22:21:47 +00:00
{
2007-10-27 13:59:24 +00:00
// Go for all textures
foreach ( ImageData img in images )
2007-10-07 22:21:47 +00:00
{
2007-10-27 13:59:24 +00:00
// Add or replace in textures list
2009-04-18 09:38:13 +00:00
list . Remove ( img . LongName ) ;
list . Add ( img . LongName , img ) ;
2008-10-02 18:53:07 +00:00
if ( firsttexture = = 0 ) firsttexture = img . LongName ;
2008-05-05 14:22:36 +00:00
counter + + ;
2007-12-27 01:24:11 +00:00
2008-09-28 21:20:56 +00:00
// Add to preview manager
previews . AddImage ( img ) ;
2007-10-07 22:21:47 +00:00
}
}
}
2008-05-05 14:22:36 +00:00
2008-10-02 18:53:07 +00:00
// The first texture cannot be used, because in the game engine it
// has index 0 which means "no texture", so remove it from the list.
2009-04-18 09:38:13 +00:00
list . Remove ( firsttexture ) ;
2008-10-02 18:53:07 +00:00
2008-05-05 14:22:36 +00:00
// Output info
return counter ;
2007-10-07 22:21:47 +00:00
}
// This returns a specific patch stream
2008-01-02 21:49:43 +00:00
internal Stream GetPatchData ( string pname )
2007-10-07 22:21:47 +00:00
{
Stream patch ;
2009-01-22 22:39:10 +00:00
2007-10-07 22:21:47 +00:00
// Go for all opened containers
for ( int i = containers . Count - 1 ; i > = 0 ; i - - )
{
// This contain provides this patch?
patch = containers [ i ] . GetPatchData ( pname ) ;
if ( patch ! = null ) return patch ;
}
// No such patch found
return null ;
}
2009-01-22 23:32:44 +00:00
// This returns a specific texture stream
internal Stream GetTextureData ( string pname )
{
Stream patch ;
// Go for all opened containers
for ( int i = containers . Count - 1 ; i > = 0 ; i - - )
{
// This contain provides this patch?
patch = containers [ i ] . GetTextureData ( pname ) ;
if ( patch ! = null ) return patch ;
}
// No such patch found
return null ;
}
2007-10-07 22:21:47 +00:00
2007-10-26 13:17:20 +00:00
// This returns an image by string
public ImageData GetTextureImage ( string name )
2007-10-24 17:25:03 +00:00
{
// Get the long name
long longname = Lump . MakeLongName ( name ) ;
2007-10-26 13:17:20 +00:00
return GetTextureImage ( longname ) ;
2007-10-24 17:25:03 +00:00
}
2007-10-26 13:17:20 +00:00
// This returns an image by long
public ImageData GetTextureImage ( long longname )
2007-10-24 17:25:03 +00:00
{
2008-05-05 14:22:36 +00:00
// Does this texture exist?
if ( textures . ContainsKey ( longname ) )
2007-10-24 17:25:03 +00:00
{
2008-05-05 14:22:36 +00:00
// Return texture
return textures [ longname ] ;
}
else
{
// Return null image
2009-01-24 14:48:43 +00:00
return new UnknownImage ( Properties . Resources . UnknownImage ) ;
2007-10-24 17:25:03 +00:00
}
}
2007-10-26 15:28:32 +00:00
2008-09-28 21:20:56 +00:00
// BAD! These block while loading the image. That is not
// what our background loading system is for!
/ *
2007-10-26 13:17:20 +00:00
// This returns a bitmap by string
public Bitmap GetTextureBitmap ( string name )
{
ImageData img = GetTextureImage ( name ) ;
img . LoadImage ( ) ;
return img . Bitmap ;
}
// This returns a bitmap by string
public Bitmap GetTextureBitmap ( long longname )
{
ImageData img = GetTextureImage ( longname ) ;
img . LoadImage ( ) ;
return img . Bitmap ;
}
// This returns a texture by string
public Texture GetTextureTexture ( string name )
{
ImageData img = GetTextureImage ( name ) ;
img . LoadImage ( ) ;
img . CreateTexture ( ) ;
return img . Texture ;
}
// This returns a texture by string
public Texture GetTextureTexture ( long longname )
{
ImageData img = GetTextureImage ( longname ) ;
img . LoadImage ( ) ;
img . CreateTexture ( ) ;
return img . Texture ;
}
2008-09-28 21:20:56 +00:00
* /
2007-10-24 17:25:03 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Flats
2007-10-26 13:17:20 +00:00
// This loads the flats
2009-04-18 09:38:13 +00:00
private int LoadFlats ( Dictionary < long , ImageData > list )
2007-10-26 13:17:20 +00:00
{
ICollection < ImageData > images ;
2008-05-05 14:22:36 +00:00
int counter = 0 ;
2007-10-26 13:17:20 +00:00
// Go for all opened containers
foreach ( DataReader dr in containers )
{
// Load flats
images = dr . LoadFlats ( ) ;
if ( images ! = null )
{
// Go for all flats
foreach ( ImageData img in images )
{
// Add or replace in flats list
2009-04-18 09:38:13 +00:00
list . Remove ( img . LongName ) ;
list . Add ( img . LongName , img ) ;
2008-05-05 14:22:36 +00:00
counter + + ;
2007-11-04 23:09:21 +00:00
2008-09-28 21:20:56 +00:00
// Add to preview manager
previews . AddImage ( img ) ;
2007-10-26 13:17:20 +00:00
}
}
}
2008-05-05 14:22:36 +00:00
// Output info
return counter ;
2007-10-26 13:17:20 +00:00
}
// This returns a specific flat stream
2008-01-02 21:49:43 +00:00
internal Stream GetFlatData ( string pname )
2007-10-26 13:17:20 +00:00
{
Stream flat ;
// Go for all opened containers
for ( int i = containers . Count - 1 ; i > = 0 ; i - - )
{
// This contain provides this flat?
flat = containers [ i ] . GetFlatData ( pname ) ;
if ( flat ! = null ) return flat ;
}
// No such patch found
return null ;
}
// This returns an image by string
public ImageData GetFlatImage ( string name )
2007-10-24 17:25:03 +00:00
{
// Get the long name
long longname = Lump . MakeLongName ( name ) ;
2007-10-26 13:17:20 +00:00
return GetFlatImage ( longname ) ;
2007-10-24 17:25:03 +00:00
}
2007-10-26 13:17:20 +00:00
// This returns an image by long
public ImageData GetFlatImage ( long longname )
2007-10-24 17:25:03 +00:00
{
2008-05-05 14:22:36 +00:00
// Does this flat exist?
if ( flats . ContainsKey ( longname ) )
2007-10-24 17:25:03 +00:00
{
2008-05-05 14:22:36 +00:00
// Return flat
return flats [ longname ] ;
}
else
{
// Return null image
2009-01-24 14:48:43 +00:00
return new UnknownImage ( Properties . Resources . UnknownImage ) ;
2007-10-24 17:25:03 +00:00
}
}
2008-09-28 21:20:56 +00:00
// BAD! These block while loading the image. That is not
// what our background loading system is for!
/ *
2007-10-26 13:17:20 +00:00
// This returns a bitmap by string
public Bitmap GetFlatBitmap ( string name )
{
ImageData img = GetFlatImage ( name ) ;
img . LoadImage ( ) ;
return img . Bitmap ;
}
// This returns a bitmap by string
public Bitmap GetFlatBitmap ( long longname )
{
ImageData img = GetFlatImage ( longname ) ;
img . LoadImage ( ) ;
return img . Bitmap ;
}
// This returns a texture by string
public Texture GetFlatTexture ( string name )
{
ImageData img = GetFlatImage ( name ) ;
img . LoadImage ( ) ;
img . CreateTexture ( ) ;
return img . Texture ;
}
// This returns a texture by string
public Texture GetFlatTexture ( long longname )
{
ImageData img = GetFlatImage ( longname ) ;
img . LoadImage ( ) ;
img . CreateTexture ( ) ;
return img . Texture ;
}
2008-09-28 21:20:56 +00:00
* /
2007-10-26 13:17:20 +00:00
2007-10-24 17:25:03 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Sprites
2007-10-26 15:28:32 +00:00
// This loads the sprites
2008-05-05 14:22:36 +00:00
private int LoadSprites ( )
2007-10-26 15:28:32 +00:00
{
// Go for all things
2009-01-21 16:18:30 +00:00
foreach ( ThingTypeInfo ti in General . Map . Data . ThingTypes )
2007-10-26 15:28:32 +00:00
{
// Sprite not added to collection yet?
2008-12-11 10:59:35 +00:00
if ( ! sprites . ContainsKey ( ti . SpriteLongName ) & & ( ti . Sprite . Length < = 8 ) )
2007-10-26 15:28:32 +00:00
{
2009-01-15 23:13:43 +00:00
// Find sprite data
Stream spritedata = GetSpriteData ( ti . Sprite ) ;
2007-10-26 15:28:32 +00:00
if ( spritedata ! = null )
{
// Make new sprite image
2009-01-15 23:13:43 +00:00
SpriteImage image = new SpriteImage ( ti . Sprite ) ;
2007-10-26 15:28:32 +00:00
// Add to collection
sprites . Add ( ti . SpriteLongName , image ) ;
2008-09-28 21:20:56 +00:00
// Add to preview manager
previews . AddImage ( image ) ;
2007-10-26 15:28:32 +00:00
}
}
}
2008-05-05 14:22:36 +00:00
// Output info
return sprites . Count ;
2007-10-26 15:28:32 +00:00
}
2009-01-15 23:13:43 +00:00
// This returns a specific patch stream
internal Stream GetSpriteData ( string pname )
{
if ( ! string . IsNullOrEmpty ( pname ) )
{
// Go for all opened containers
for ( int i = containers . Count - 1 ; i > = 0 ; i - - )
{
// This contain provides this patch?
Stream spritedata = containers [ i ] . GetSpriteData ( pname ) ;
if ( spritedata ! = null ) return spritedata ;
}
}
// No such patch found
return null ;
}
2009-01-22 15:10:41 +00:00
// This tests if a given sprite can be found
internal bool GetSpriteExists ( string pname )
{
if ( ! string . IsNullOrEmpty ( pname ) )
{
// Go for all opened containers
for ( int i = containers . Count - 1 ; i > = 0 ; i - - )
{
// This contain provides this patch?
if ( containers [ i ] . GetSpriteExists ( pname ) ) return true ;
}
}
// No such patch found
return false ;
}
2008-12-11 10:59:35 +00:00
// This loads the internal sprites
private void LoadInternalSprites ( )
{
// Add sprite icon files from directory
string [ ] files = Directory . GetFiles ( General . SpritesPath , "*.png" , SearchOption . TopDirectoryOnly ) ;
foreach ( string spritefile in files )
{
2009-01-03 19:45:59 +00:00
ImageData img = new FileImage ( Path . GetFileNameWithoutExtension ( spritefile ) . ToLowerInvariant ( ) , spritefile , false ) ;
2008-12-11 10:59:35 +00:00
img . LoadImage ( ) ;
internalsprites . Add ( img . Name , img ) ;
}
// Add some internal resources
if ( ! internalsprites . ContainsKey ( "nothing" ) )
{
ImageData img = new ResourceImage ( "Nothing.png" ) ;
img . LoadImage ( ) ;
internalsprites . Add ( "nothing" , img ) ;
}
if ( ! internalsprites . ContainsKey ( "unknownthing" ) )
{
ImageData img = new ResourceImage ( "UnknownThing.png" ) ;
img . LoadImage ( ) ;
internalsprites . Add ( "unknownthing" , img ) ;
}
}
2007-10-26 13:31:02 +00:00
// This returns an image by long
2007-10-26 13:17:20 +00:00
public ImageData GetSpriteImage ( string name )
2007-10-24 17:25:03 +00:00
{
2008-12-11 10:59:35 +00:00
// Is this referring to an internal sprite image?
if ( ( name . Length > INTERNAL_PREFIX . Length ) & & name . ToLowerInvariant ( ) . StartsWith ( INTERNAL_PREFIX ) )
2007-10-24 17:25:03 +00:00
{
2008-12-11 10:59:35 +00:00
// Get the internal sprite
string internalname = name . Substring ( INTERNAL_PREFIX . Length ) . ToLowerInvariant ( ) ;
if ( internalsprites . ContainsKey ( internalname ) )
{
return internalsprites [ internalname ] ;
}
else
{
2009-01-24 14:48:43 +00:00
return new UnknownImage ( Properties . Resources . UnknownImage ) ;
2008-12-11 10:59:35 +00:00
}
2008-05-05 14:22:36 +00:00
}
else
{
2008-12-11 10:59:35 +00:00
// Get the long name
long longname = Lump . MakeLongName ( name ) ;
2007-10-26 13:31:02 +00:00
2008-12-11 10:59:35 +00:00
// Sprite already loaded?
if ( sprites . ContainsKey ( longname ) )
2008-05-05 14:22:36 +00:00
{
2008-12-11 10:59:35 +00:00
// Return exiting sprite
return sprites [ longname ] ;
2008-05-05 14:22:36 +00:00
}
else
{
2008-12-11 10:59:35 +00:00
Stream spritedata = null ;
// Go for all opened containers
for ( int i = containers . Count - 1 ; i > = 0 ; i - - )
{
// This contain provides this sprite?
spritedata = containers [ i ] . GetSpriteData ( name ) ;
if ( spritedata ! = null ) break ;
}
// Found anything?
if ( spritedata ! = null )
{
// Make new sprite image
SpriteImage image = new SpriteImage ( name ) ;
// Add to collection
sprites . Add ( longname , image ) ;
// Return result
return image ;
}
else
{
// Return null image
2009-01-24 14:48:43 +00:00
return new UnknownImage ( Properties . Resources . UnknownImage ) ;
2008-12-11 10:59:35 +00:00
}
2007-10-26 13:31:02 +00:00
}
2007-10-24 17:25:03 +00:00
}
}
2008-09-28 21:20:56 +00:00
// BAD! These block while loading the image. That is not
// what our background loading system is for!
/ *
2007-10-26 13:17:20 +00:00
// This returns a bitmap by string
public Bitmap GetSpriteBitmap ( string name )
{
ImageData img = GetSpriteImage ( name ) ;
img . LoadImage ( ) ;
return img . Bitmap ;
}
// This returns a texture by string
public Texture GetSpriteTexture ( string name )
{
ImageData img = GetSpriteImage ( name ) ;
img . LoadImage ( ) ;
img . CreateTexture ( ) ;
return img . Texture ;
}
2008-09-28 21:20:56 +00:00
* /
2007-10-26 13:17:20 +00:00
2009-01-21 16:18:30 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Things
// This loads the things from Decorate
private int LoadDecorateThings ( )
{
DecorateParser parser ;
int counter = 0 ;
2009-01-22 15:10:41 +00:00
// Only load these when the game configuration supports the use of decorate
if ( ! string . IsNullOrEmpty ( General . Map . Config . DecorateGames ) )
2009-01-21 16:18:30 +00:00
{
2009-01-22 15:10:41 +00:00
// Create the parser
parser = new DecorateParser ( ) ;
parser . OnInclude = LoadDecorateFromLocation ;
// Go for all opened containers
foreach ( DataReader dr in containers )
2009-01-21 16:18:30 +00:00
{
2009-01-22 15:10:41 +00:00
// Load Decorate info cumulatively (the last Decorate is added to the previous)
// I'm not sure if this is the right thing to do though.
currentreader = dr ;
Stream decodata = dr . GetDecorateData ( "DECORATE" ) ;
if ( decodata ! = null )
{
// Parse the data
decodata . Seek ( 0 , SeekOrigin . Begin ) ;
parser . Parse ( decodata , "DECORATE" ) ;
// Check for errors
if ( parser . HasError )
{
2009-02-26 23:27:46 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Unable to parse DECORATE data from location " +
2009-03-01 09:15:58 +00:00
dr . Location . location + ". " + parser . ErrorDescription + " on line " + parser . ErrorLine +
2009-02-26 23:27:46 +00:00
" in '" + parser . ErrorSource + "'" ) ;
2009-01-22 15:10:41 +00:00
break ;
}
}
}
currentreader = null ;
if ( ! parser . HasError )
{
// Go for all actors in the decorate to make things or update things
foreach ( ActorStructure actor in parser . Actors )
2009-01-21 16:18:30 +00:00
{
2009-01-22 15:10:41 +00:00
// Check if we want to add this actor
if ( actor . DoomEdNum > 0 )
{
2009-02-09 22:59:43 +00:00
string catname = actor . Category . ToLowerInvariant ( ) ;
2009-01-22 15:10:41 +00:00
// Check if we can find this thing in our existing collection
if ( thingtypes . ContainsKey ( actor . DoomEdNum ) )
{
// Update the thing
thingtypes [ actor . DoomEdNum ] . ModifyByDecorateActor ( actor ) ;
}
else
{
2009-02-09 22:59:43 +00:00
// Find the category to put the actor in
2009-02-12 06:24:22 +00:00
// First search by Title, then search by Name
2009-02-09 22:59:43 +00:00
ThingCategory cat = null ;
foreach ( ThingCategory c in thingcategories )
{
2009-02-12 06:24:22 +00:00
if ( c . Title . ToLowerInvariant ( ) = = catname ) cat = c ;
}
if ( cat = = null )
{
foreach ( ThingCategory c in thingcategories )
{
if ( c . Name . ToLowerInvariant ( ) = = catname ) cat = c ;
}
2009-02-09 22:59:43 +00:00
}
// Make the category if needed
2009-01-22 15:10:41 +00:00
if ( cat = = null )
{
2009-02-09 22:59:43 +00:00
cat = new ThingCategory ( catname , actor . Category ) ;
2009-01-22 15:10:41 +00:00
thingcategories . Add ( cat ) ;
}
// Add new thing
ThingTypeInfo t = new ThingTypeInfo ( cat , actor ) ;
cat . AddThing ( t ) ;
thingtypes . Add ( t . Index , t ) ;
}
// Count
counter + + ;
}
2009-01-21 16:18:30 +00:00
}
}
}
// Output info
return counter ;
}
// This loads Decorate data from a specific file or lump name
2009-01-21 23:09:25 +00:00
private void LoadDecorateFromLocation ( DecorateParser parser , string location )
2009-01-21 16:18:30 +00:00
{
2009-01-22 15:10:41 +00:00
//General.WriteLogLine("Including DECORATE resource '" + location + "'...");
2009-01-21 23:09:25 +00:00
Stream decodata = currentreader . GetDecorateData ( location ) ;
if ( decodata ! = null )
{
// Parse this data
parser . Parse ( decodata , location ) ;
}
2009-01-21 16:18:30 +00:00
}
// This gets thing information by index
public ThingTypeInfo GetThingInfo ( int thingtype )
{
// Index in config?
if ( thingtypes . ContainsKey ( thingtype ) )
{
// Return from config
return thingtypes [ thingtype ] ;
}
else
{
// Create unknown thing info
return new ThingTypeInfo ( thingtype ) ;
}
}
// This gets thing information by index
// Returns null when thing type info could not be found
public ThingTypeInfo GetThingInfoEx ( int thingtype )
{
// Index in config?
if ( thingtypes . ContainsKey ( thingtype ) )
{
// Return from config
return thingtypes [ thingtype ] ;
}
else
{
// No such thing type known
return null ;
}
}
2007-10-07 22:21:47 +00:00
#endregion
2008-05-22 12:03:33 +00:00
#region = = = = = = = = = = = = = = = = = = Tools
// This finds the first IWAD resource
// Returns false when not found
internal bool FindFirstIWAD ( out DataLocation result )
{
// Go for all data containers
foreach ( DataReader dr in containers )
{
// Container is a WAD file?
if ( dr is WADReader )
{
// Check if it is an IWAD
WADReader wr = dr as WADReader ;
if ( wr . IsIWAD )
{
// Return location!
result = wr . Location ;
return true ;
}
}
}
// No IWAD found
result = new DataLocation ( ) ;
return false ;
}
2008-09-28 21:20:56 +00:00
// This signals the background thread to update the
// used-in-map status on all textures and flats
public void UpdateUsedTextures ( )
{
2008-10-15 17:26:59 +00:00
lock ( usedimages )
{
usedimages . Clear ( ) ;
// Go through the map to find the used textures
foreach ( Sidedef sd in General . Map . Map . Sidedefs )
{
// Add used textures to dictionary
if ( sd . HighTexture . Length > 0 ) usedimages [ sd . LongHighTexture ] = 0 ;
if ( sd . LowTexture . Length > 0 ) usedimages [ sd . LongMiddleTexture ] = 0 ;
if ( sd . MiddleTexture . Length > 0 ) usedimages [ sd . LongLowTexture ] = 0 ;
}
// Go through the map to find the used flats
foreach ( Sector s in General . Map . Map . Sectors )
{
// Add used flats to dictionary
usedimages [ s . LongFloorTexture ] = 0 ;
usedimages [ s . LongCeilTexture ] = 0 ;
}
// Notify the background thread that it needs to update the images
updatedusedtextures = true ;
}
2008-09-28 21:20:56 +00:00
}
2008-12-31 00:44:04 +00:00
// This returns the long name for a string
public long GetLongImageName ( string name )
{
return Lump . MakeLongName ( name ) ;
}
2008-09-28 21:20:56 +00:00
2008-05-22 12:03:33 +00:00
#endregion
2007-10-01 20:57:41 +00:00
}
}