ZoneBuilder/Source/Core/Data/SpriteImage.cs
MaxED 7435d4bd5b Added: action argument inputs now support incremental increase/decrease prefixes (+++ and ---).
Probably fixed probable I/O race condition when loading images.
Fixed Visual mode stuttering due to floating point precision degradation when running the editor for several days without restarting (internal timer is now reset when saving the map or creating a new one).
Fixed, Nodes Viewer, cosmetic: Nodes Viewer window position was reset after pressing the "Rebuild Nodes" button.
Added Eternity Game configurations by printz.
Updated ZDoom_ACS.cfg (CheckClass).
Updated ZDoom ACC (CheckClass).
2023-01-06 12:11:22 +01:00

151 lines
3.7 KiB
C#

#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 CodeImp.DoomBuilder.IO;
using System.IO;
using System.Runtime.InteropServices;
using CodeImp.DoomBuilder.Windows;
#endregion
namespace CodeImp.DoomBuilder.Data
{
public sealed class SpriteImage : ImageData
{
#region ================== Variables
private int offsetx;
private int offsety;
private bool flipped;
#endregion
#region ================== Properties
public int OffsetX { get { return offsetx; } }
public int OffsetY { get { return offsety; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
internal SpriteImage(string name, bool flip = false)
{
flipped = flip;
// Initialize
SetName(name);
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
//mxd
override public void LoadImage()
{
// Do the loading
LocalLoadImage();
// Notify the main thread about the change to redraw display
IntPtr strptr = Marshal.StringToCoTaskMemAuto(this.Name);
General.SendMessage(General.MainWindow.Handle, (int)MainForm.ThreadMessages.SpriteDataLoaded, strptr.ToInt32(), 0);
}
// This loads the image
protected override void LocalLoadImage()
{
// Leave when already loaded
if(this.IsImageLoaded) return;
lock(this)
{
// Get the lump data stream
Stream lumpdata = General.Map.Data.GetSpriteData(Name);
if(lumpdata != null)
{
// Copy lump data to memory
byte[] membytes = new byte[(int)lumpdata.Length];
lock(lumpdata) //mxd
{
lumpdata.Seek(0, SeekOrigin.Begin);
lumpdata.Read(membytes, 0, (int)lumpdata.Length);
}
MemoryStream mem = new MemoryStream(membytes);
mem.Seek(0, SeekOrigin.Begin);
// Get a reader for the data
IImageReader reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
if(reader is UnknownImageReader)
{
// Data is in an unknown format!
General.ErrorLogger.Add(ErrorType.Error, "Sprite lump \"" + Name + "\" data format could not be read. Does this lump contain valid picture data at all?");
bitmap = null;
}
else
{
// Read data as bitmap
mem.Seek(0, SeekOrigin.Begin);
if(bitmap != null) bitmap.Dispose();
bitmap = reader.ReadAsBitmap(mem, out offsetx, out offsety);
}
// Done
mem.Dispose();
if(bitmap != null)
{
// Get width and height from image
width = bitmap.Size.Width;
height = bitmap.Size.Height;
scale.x = 1.0f;
scale.y = 1.0f;
// Make offset corrections if the offset was not given
if((offsetx == int.MinValue) || (offsety == int.MinValue))
{
offsetx = (int)((width * scale.x) * 0.5f);
offsety = (int)(height * scale.y);
}
if (flipped) bitmap.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
}
else
{
loadfailed = true;
}
}
else
{
// Missing a patch lump!
General.ErrorLogger.Add(ErrorType.Error, "Missing sprite lump \"" + Name + "\". Forgot to include required resources?");
}
// Pass on to base
base.LocalLoadImage();
}
}
#endregion
}
}