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.Drawing ;
using System.Drawing.Imaging ;
using CodeImp.DoomBuilder.Rendering ;
using CodeImp.DoomBuilder.IO ;
using System.IO ;
#endregion
namespace CodeImp.DoomBuilder.Data
{
internal sealed unsafe class TextureImage : ImageData
{
#region = = = = = = = = = = = = = = = = = = Variables
private List < TexturePatch > patches ;
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
2016-06-15 14:48:21 +00:00
public TextureImage ( string group , string name , int width , int height , float scalex , float scaley , bool worldpanning )
2009-04-19 18:07:22 +00:00
{
// Initialize
this . width = width ;
this . height = height ;
2010-01-02 20:22:05 +00:00
this . scale . x = scalex ;
this . scale . y = scaley ;
2016-06-15 14:48:21 +00:00
this . worldpanning = worldpanning ; //mxd
2009-04-19 18:07:22 +00:00
this . patches = new List < TexturePatch > ( ) ;
SetName ( name ) ;
2015-03-22 20:43:05 +00:00
virtualname = "[" + group + "]/" + this . name ; //mxd
2009-04-19 18:07:22 +00:00
// We have no destructor
GC . SuppressFinalize ( this ) ;
}
#endregion
#region = = = = = = = = = = = = = = = = = = Methods
// This adds a patch to the texture
public void AddPatch ( TexturePatch patch )
{
// Add it
patches . Add ( patch ) ;
2014-07-15 08:08:57 +00:00
2016-03-16 23:26:53 +00:00
if ( patch . LumpName = = Name ) hasPatchWithSameName = true ; //mxd
2009-04-19 18:07:22 +00:00
}
// This loads the image
protected override void LocalLoadImage ( )
{
2015-12-28 15:01:53 +00:00
// Checks
if ( this . IsImageLoaded | | width = = 0 | | height = = 0 ) return ;
2009-04-19 18:07:22 +00:00
BitmapData bitmapdata = null ;
PixelColor * pixels = ( PixelColor * ) 0 ;
lock ( this )
{
// Create texture bitmap
try
{
if ( bitmap ! = null ) bitmap . Dispose ( ) ;
bitmap = new Bitmap ( width , height , PixelFormat . Format32bppArgb ) ;
bitmapdata = bitmap . LockBits ( new Rectangle ( 0 , 0 , width , height ) , ImageLockMode . WriteOnly , PixelFormat . Format32bppArgb ) ;
pixels = ( PixelColor * ) bitmapdata . Scan0 . ToPointer ( ) ;
General . ZeroMemory ( new IntPtr ( pixels ) , width * height * sizeof ( PixelColor ) ) ;
}
catch ( Exception e )
{
// Unable to make bitmap
2016-02-22 08:04:06 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Unable to load texture image \"" + this . Name + "\". " + e . GetType ( ) . Name + ": " + e . Message ) ;
2009-04-19 18:07:22 +00:00
loadfailed = true ;
}
2015-12-30 13:58:58 +00:00
int missingpatches = 0 ; //mxd
2013-07-29 08:50:50 +00:00
2009-04-19 18:07:22 +00:00
if ( ! loadfailed )
{
// Go for all patches
foreach ( TexturePatch p in patches )
{
// Get the patch data stream
2016-03-14 21:53:53 +00:00
string patchlocation = string . Empty ; //mxd
2016-03-16 23:26:53 +00:00
Stream patchdata = General . Map . Data . GetPatchData ( p . LumpName , p . HasLongName , ref patchlocation ) ;
2009-04-19 18:07:22 +00:00
if ( patchdata ! = null )
{
// Copy patch data to memory
2015-12-28 15:01:53 +00:00
byte [ ] membytes = new byte [ ( int ) patchdata . Length ] ;
2016-08-29 10:06:16 +00:00
lock ( patchdata ) //mxd
{
patchdata . Seek ( 0 , SeekOrigin . Begin ) ;
patchdata . Read ( membytes , 0 , ( int ) patchdata . Length ) ;
}
2015-12-28 15:01:53 +00:00
MemoryStream mem = new MemoryStream ( membytes ) ;
2009-04-19 18:07:22 +00:00
mem . Seek ( 0 , SeekOrigin . Begin ) ;
// Get a reader for the data
2015-12-28 15:01:53 +00:00
IImageReader reader = ImageDataFormat . GetImageReader ( mem , ImageDataFormat . DOOMPICTURE , General . Map . Data . Palette ) ;
2009-04-19 18:07:22 +00:00
if ( reader is UnknownImageReader )
{
2013-12-02 15:02:01 +00:00
//mxd. Probably that's a flat?..
2015-12-28 15:01:53 +00:00
if ( General . Map . Config . MixTexturesFlats )
2014-12-03 23:15:26 +00:00
{
2013-12-02 15:02:01 +00:00
reader = ImageDataFormat . GetImageReader ( mem , ImageDataFormat . DOOMFLAT , General . Map . Data . Palette ) ;
}
2015-12-28 15:01:53 +00:00
if ( reader is UnknownImageReader )
2014-12-03 23:15:26 +00:00
{
2013-12-02 15:02:01 +00:00
// Data is in an unknown format!
2016-03-16 23:26:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Patch lump \"" + Path . Combine ( patchlocation , p . LumpName ) + "\" data format could not be read, while loading texture \"" + this . Name + "\". Does this lump contain valid picture data at all?" ) ;
2013-12-02 15:02:01 +00:00
loadfailed = true ;
2015-12-30 13:58:58 +00:00
missingpatches + + ; //mxd
2013-12-02 15:02:01 +00:00
}
2009-04-19 18:07:22 +00:00
}
2013-12-02 15:02:01 +00:00
2014-12-03 23:15:26 +00:00
if ( ! ( reader is UnknownImageReader ) )
{
2009-04-19 18:07:22 +00:00
// Draw the patch
mem . Seek ( 0 , SeekOrigin . Begin ) ;
2016-03-16 23:26:53 +00:00
try { reader . DrawToPixelData ( mem , pixels , width , height , p . X , p . Y ) ; }
2009-04-19 18:07:22 +00:00
catch ( InvalidDataException )
{
// Data cannot be read!
2016-03-16 23:26:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Patch lump \"" + p . LumpName + "\" data format could not be read, while loading texture \"" + this . Name + "\". Does this lump contain valid picture data at all?" ) ;
2009-04-19 18:07:22 +00:00
loadfailed = true ;
2015-12-30 13:58:58 +00:00
missingpatches + + ; //mxd
2009-04-19 18:07:22 +00:00
}
}
// Done
mem . Dispose ( ) ;
}
else
{
// Missing a patch lump!
2016-03-16 23:26:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Missing patch lump \"" + p . LumpName + "\" while loading texture \"" + this . Name + "\". Did you forget to include required resources?" ) ;
2009-04-19 18:07:22 +00:00
loadfailed = true ;
2015-12-30 13:58:58 +00:00
missingpatches + + ; //mxd
2009-04-19 18:07:22 +00:00
}
}
// Done
bitmap . UnlockBits ( bitmapdata ) ;
}
// Dispose bitmap if load failed
2015-12-30 13:58:58 +00:00
if ( ( bitmap ! = null ) & & ( loadfailed | | missingpatches > = patches . Count ) ) //mxd. We can still display texture if at least one of the patches was loaded
2009-04-19 18:07:22 +00:00
{
bitmap . Dispose ( ) ;
bitmap = null ;
2013-07-29 08:50:50 +00:00
loadfailed = true ;
2009-04-19 18:07:22 +00:00
}
// Pass on to base
base . LocalLoadImage ( ) ;
}
}
#endregion
}
}