mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
loading resources from PK3 files implemented (tested with KDIZD, CAH and SP_USIMP)
This commit is contained in:
parent
4ce26ad8fa
commit
320a002677
16 changed files with 844 additions and 376 deletions
|
@ -650,6 +650,8 @@
|
|||
<None Include="Resources\Cut.png" />
|
||||
<None Include="Resources\Close.png" />
|
||||
<Compile Include="Config\FlagTranslation.cs" />
|
||||
<Compile Include="Data\PK3FileImage.cs" />
|
||||
<Compile Include="Data\PK3StructuredReader.cs" />
|
||||
<Compile Include="Editing\EditingManager.cs" />
|
||||
<EmbeddedResource Include="Resources\Crosshair.png" />
|
||||
<EmbeddedResource Include="Resources\CrosshairBusy.png" />
|
||||
|
|
|
@ -243,9 +243,11 @@ namespace CodeImp.DoomBuilder.Data
|
|||
break;
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
catch(Exception e)
|
||||
{
|
||||
// Unable to load resource
|
||||
General.WriteLogLine("ERROR while creating data reader. " + e.GetType().Name + ": " + e.Message);
|
||||
General.WriteLogLine(e.StackTrace);
|
||||
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;
|
||||
}
|
||||
|
@ -361,9 +363,11 @@ namespace CodeImp.DoomBuilder.Data
|
|||
General.WriteLogLine("Resumed data resource '" + d.Location.location + "'");
|
||||
d.Resume();
|
||||
}
|
||||
catch(Exception)
|
||||
catch(Exception e)
|
||||
{
|
||||
// Unable to load resource
|
||||
General.WriteLogLine("ERROR while resuming data reader. " + e.GetType().Name + ": " + e.Message);
|
||||
General.WriteLogLine(e.StackTrace);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -891,7 +895,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
string[] files = Directory.GetFiles(General.SpritesPath, "*.png", SearchOption.TopDirectoryOnly);
|
||||
foreach(string spritefile in files)
|
||||
{
|
||||
ImageData img = new FileImage(Path.GetFileNameWithoutExtension(spritefile).ToLowerInvariant(), spritefile);
|
||||
ImageData img = new FileImage(Path.GetFileNameWithoutExtension(spritefile).ToLowerInvariant(), spritefile, false);
|
||||
img.LoadImage();
|
||||
internalsprites.Add(img.Name, img);
|
||||
}
|
||||
|
|
|
@ -30,66 +30,17 @@ using CodeImp.DoomBuilder.IO;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal sealed class DirectoryReader : DataReader
|
||||
internal sealed class DirectoryReader : PK3StructuredReader
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const string PATCHES_DIR = "patches";
|
||||
private const string TEXTURES_DIR = "textures";
|
||||
private const string FLATS_DIR = "flats";
|
||||
private const string HIRES_DIR = "hires";
|
||||
private const string SPRITES_DIR = "sprites";
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
// Source
|
||||
private bool roottextures;
|
||||
private bool rootflats;
|
||||
|
||||
// Paths
|
||||
private string rootpath;
|
||||
private string patchespath;
|
||||
private string texturespath;
|
||||
private string flatspath;
|
||||
private string hirespath;
|
||||
private string spritespath;
|
||||
|
||||
// WAD files that must be loaded as well
|
||||
private List<WADReader> wads;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public DirectoryReader(DataLocation dl) : base(dl)
|
||||
{
|
||||
// Initialize
|
||||
this.roottextures = dl.textures;
|
||||
this.rootflats = dl.flats;
|
||||
this.rootpath = dl.location;
|
||||
this.patchespath = Path.Combine(rootpath, PATCHES_DIR);
|
||||
this.texturespath = Path.Combine(rootpath, TEXTURES_DIR);
|
||||
this.flatspath = Path.Combine(rootpath, FLATS_DIR);
|
||||
this.hirespath = Path.Combine(rootpath, HIRES_DIR);
|
||||
this.spritespath = Path.Combine(rootpath, SPRITES_DIR);
|
||||
|
||||
General.WriteLogLine("Opening directory resource '" + location.location + "'");
|
||||
|
||||
// Load all WAD files in the root as WAD resources
|
||||
string[] wadfiles = Directory.GetFiles(rootpath, "*.wad", SearchOption.TopDirectoryOnly);
|
||||
wads = new List<WADReader>(wadfiles.Length);
|
||||
foreach(string w in wadfiles)
|
||||
{
|
||||
DataLocation wdl = new DataLocation(DataLocation.RESOURCE_WAD, w, false, false);
|
||||
wads.Add(new WADReader(wdl));
|
||||
}
|
||||
// Initialize
|
||||
Initialize(dl.location);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -101,9 +52,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Not already disposed?
|
||||
if(!isdisposed)
|
||||
{
|
||||
// Clean up
|
||||
foreach(WADReader wr in wads) wr.Dispose();
|
||||
|
||||
General.WriteLogLine("Closing directory resource '" + location.location + "'");
|
||||
|
||||
// Done
|
||||
|
@ -113,275 +61,62 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#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) palette = wadpalette;
|
||||
}
|
||||
|
||||
// Done
|
||||
return palette;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Textures
|
||||
|
||||
// This loads the textures
|
||||
public override ICollection<ImageData> LoadTextures(PatchNames pnames)
|
||||
{
|
||||
List<ImageData> images = new List<ImageData>();
|
||||
ICollection<ImageData> collection;
|
||||
|
||||
// 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--)
|
||||
{
|
||||
collection = wads[i].LoadTextures(pnames);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Should we load the images in this directory as textures?
|
||||
if(roottextures)
|
||||
{
|
||||
collection = LoadDirectoryImages(rootpath);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// TODO: Add support for hires texture here
|
||||
|
||||
// Add images from texture directory
|
||||
collection = LoadDirectoryImages(texturespath);
|
||||
AddImagesToList(images, collection);
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
// 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--)
|
||||
{
|
||||
PatchNames pnames = wads[i].LoadPatchNames();
|
||||
if(pnames != null) return pnames;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// This finds and returns a patch stream
|
||||
public override Stream GetPatchData(string pname)
|
||||
{
|
||||
string filename;
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Find in any of the wad files
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Stream data = wads[i].GetPatchData(pname);
|
||||
if(data != null) return data;
|
||||
}
|
||||
|
||||
// Find in patches directory
|
||||
string datafile = null;
|
||||
filename = Path.Combine(patchespath, pname + ".bmp");
|
||||
if(File.Exists(filename)) datafile = filename;
|
||||
filename = Path.Combine(patchespath, pname + ".gif");
|
||||
if(File.Exists(filename)) datafile = filename;
|
||||
filename = Path.Combine(patchespath, pname + ".png");
|
||||
if(File.Exists(filename)) datafile = filename;
|
||||
filename = Path.Combine(patchespath, pname);
|
||||
if(File.Exists(filename)) datafile = filename;
|
||||
|
||||
// Found anything?
|
||||
if(datafile != null)
|
||||
{
|
||||
byte[] filedata = File.ReadAllBytes(datafile);
|
||||
MemoryStream mem = new MemoryStream(filedata);
|
||||
return mem;
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Flats
|
||||
|
||||
// This loads the textures
|
||||
public override ICollection<ImageData> LoadFlats()
|
||||
{
|
||||
List<ImageData> images = new List<ImageData>();
|
||||
ICollection<ImageData> collection;
|
||||
|
||||
// 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--)
|
||||
{
|
||||
collection = wads[i].LoadFlats();
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Should we load the images in this directory as flats?
|
||||
if(rootflats)
|
||||
{
|
||||
collection = LoadDirectoryImages(rootpath);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Add images from flats directory
|
||||
collection = LoadDirectoryImages(flatspath);
|
||||
AddImagesToList(images, collection);
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Sprites
|
||||
|
||||
// This finds and returns a sprite stream
|
||||
public override Stream GetSpriteData(string pname)
|
||||
{
|
||||
string pfilename = pname.Replace('\\', '^');
|
||||
string filename;
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Find in any of the wad files
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Stream sprite = wads[i].GetSpriteData(pname);
|
||||
if(sprite != null) return sprite;
|
||||
}
|
||||
|
||||
// Find in sprites directory
|
||||
string spritefoundfile = null;
|
||||
filename = Path.Combine(spritespath, pfilename + ".bmp");
|
||||
if(File.Exists(filename)) spritefoundfile = filename;
|
||||
filename = Path.Combine(spritespath, pfilename + ".gif");
|
||||
if(File.Exists(filename)) spritefoundfile = filename;
|
||||
filename = Path.Combine(spritespath, pfilename + ".png");
|
||||
if(File.Exists(filename)) spritefoundfile = filename;
|
||||
|
||||
// Found anything?
|
||||
if(spritefoundfile != null)
|
||||
{
|
||||
byte[] filedata = File.ReadAllBytes(spritefoundfile);
|
||||
MemoryStream mem = new MemoryStream(filedata);
|
||||
return mem;
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This loads the images in this directory
|
||||
private ICollection<ImageData> LoadDirectoryImages(string path)
|
||||
// This creates an image
|
||||
protected override ImageData CreateImage(string name, string filename, bool flat)
|
||||
{
|
||||
List<ImageData> images = new List<ImageData>();
|
||||
string[] files;
|
||||
string name;
|
||||
return new FileImage(name, filename, flat);
|
||||
}
|
||||
|
||||
// Find all BMP files
|
||||
files = Directory.GetFiles(path, "*.bmp", SearchOption.TopDirectoryOnly);
|
||||
// This returns true if the specified file exists
|
||||
protected override bool FileExists(string filename)
|
||||
{
|
||||
return File.Exists(filename);
|
||||
}
|
||||
|
||||
// This returns all files in a given directory
|
||||
protected override string[] GetAllFiles(string path)
|
||||
{
|
||||
return Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||
}
|
||||
|
||||
// Find all GIF files and append to files array
|
||||
AddToArray(ref files, Directory.GetFiles(path, "*.gif", SearchOption.TopDirectoryOnly));
|
||||
// This returns all files in a given directory that match the given extension
|
||||
protected override string[] GetFilesWithExt(string path, string extension)
|
||||
{
|
||||
return Directory.GetFiles(path, "*." + extension, SearchOption.TopDirectoryOnly);
|
||||
}
|
||||
|
||||
// Find all PNG files and append to files array
|
||||
AddToArray(ref files, Directory.GetFiles(path, "*.png", SearchOption.TopDirectoryOnly));
|
||||
|
||||
// Go for all files
|
||||
// This finds the first file that has the specific name, regardless of file extension
|
||||
protected override string FindFirstFile(string path, string beginswith)
|
||||
{
|
||||
string[] files = GetAllFiles(path);
|
||||
foreach(string f in files)
|
||||
{
|
||||
// Make the texture name from filename without extension
|
||||
name = Path.GetFileNameWithoutExtension(f).ToUpperInvariant();
|
||||
if(name.Length > 8) name = name.Substring(0, 8);
|
||||
|
||||
// Add image to list
|
||||
images.Add(new FileImage(name, f));
|
||||
if(string.Compare(Path.GetFileNameWithoutExtension(f), beginswith, true) == 0)
|
||||
return f;
|
||||
}
|
||||
|
||||
// Return result
|
||||
return images;
|
||||
return null;
|
||||
}
|
||||
|
||||
// This resizes a string array and adds to it
|
||||
private void AddToArray(ref string[] array, string[] add)
|
||||
// This loads an entire file in memory and returns the stream
|
||||
// NOTE: Callers are responsible for disposing the stream!
|
||||
protected override MemoryStream LoadFile(string filename)
|
||||
{
|
||||
int insertindex = array.Length;
|
||||
Array.Resize<string>(ref array, array.Length + add.Length);
|
||||
add.CopyTo(array, insertindex);
|
||||
return new MemoryStream(File.ReadAllBytes(filename));
|
||||
}
|
||||
|
||||
// This copies images from a collection unless they already exist in the list
|
||||
private void AddImagesToList(List<ImageData> targetlist, ICollection<ImageData> sourcelist)
|
||||
|
||||
// This creates 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 override string CreateTempFile(string filename)
|
||||
{
|
||||
// Go for all source images
|
||||
foreach(ImageData src in sourcelist)
|
||||
{
|
||||
// Check if exists in target list
|
||||
bool alreadyexists = false;
|
||||
foreach(ImageData tgt in targetlist)
|
||||
{
|
||||
if(tgt.LongName == src.LongName)
|
||||
{
|
||||
alreadyexists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add source image to target list
|
||||
if(!alreadyexists) targetlist.Add(src);
|
||||
}
|
||||
// Just copy the file
|
||||
string tempfile = General.MakeTempFilename(General.Map.TempPath, "wad");
|
||||
File.Copy(filename, tempfile);
|
||||
return tempfile;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ using System.Text;
|
|||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -34,34 +35,56 @@ namespace CodeImp.DoomBuilder.Data
|
|||
#region ================== Variables
|
||||
|
||||
private string filepathname;
|
||||
private int probableformat;
|
||||
private float scalex;
|
||||
private float scaley;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public FileImage(string name, string filepathname)
|
||||
public FileImage(string name, string filepathname, bool asflat)
|
||||
{
|
||||
// Initialize
|
||||
this.filepathname = filepathname;
|
||||
SetName(name);
|
||||
|
||||
// Temporarily load file
|
||||
Bitmap bmp = (Bitmap)Bitmap.FromFile(filepathname);
|
||||
|
||||
// Get width and height from image
|
||||
width = bmp.Size.Width;
|
||||
height = bmp.Size.Height;
|
||||
scaledwidth = (float)bmp.Size.Width * General.Map.Config.DefaultTextureScale;
|
||||
scaledheight = (float)bmp.Size.Height * General.Map.Config.DefaultTextureScale;
|
||||
|
||||
// Unload file
|
||||
bmp.Dispose();
|
||||
if(asflat)
|
||||
{
|
||||
probableformat = ImageDataFormat.DOOMFLAT;
|
||||
scalex = General.Map.Config.DefaultFlatScale;
|
||||
scaley = General.Map.Config.DefaultFlatScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
probableformat = ImageDataFormat.DOOMPICTURE;
|
||||
scalex = General.Map.Config.DefaultTextureScale;
|
||||
scaley = General.Map.Config.DefaultTextureScale;
|
||||
}
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public FileImage(string name, string filepathname, bool asflat, float scalex, float scaley)
|
||||
{
|
||||
// Initialize
|
||||
this.filepathname = filepathname;
|
||||
this.scalex = scalex;
|
||||
this.scaley = scaley;
|
||||
SetName(name);
|
||||
|
||||
if(asflat)
|
||||
probableformat = ImageDataFormat.DOOMFLAT;
|
||||
else
|
||||
probableformat = ImageDataFormat.DOOMPICTURE;
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
@ -74,17 +97,41 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
lock(this)
|
||||
{
|
||||
// Load file
|
||||
if(bitmap != null) bitmap.Dispose();
|
||||
bitmap = (Bitmap)Bitmap.FromFile(filepathname);
|
||||
// Load file data
|
||||
if(bitmap != null) bitmap.Dispose(); bitmap = null;
|
||||
MemoryStream filedata = new MemoryStream(File.ReadAllBytes(filepathname));
|
||||
|
||||
// Get a reader for the data
|
||||
IImageReader reader = ImageDataFormat.GetImageReader(filedata, probableformat, General.Map.Data.Palette);
|
||||
if(!(reader is UnknownImageReader))
|
||||
{
|
||||
// Load the image
|
||||
filedata.Seek(0, SeekOrigin.Begin);
|
||||
try { bitmap = reader.ReadAsBitmap(filedata); }
|
||||
catch(InvalidDataException)
|
||||
{
|
||||
// Data cannot be read!
|
||||
bitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Not loaded?
|
||||
if(bitmap == null)
|
||||
{
|
||||
General.WriteLogLine("WARNING: Image file '" + filepathname + "' data format could not be read, while loading texture '" + this.Name + "'!");
|
||||
loadfailed = true;
|
||||
filedata.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get width and height from image
|
||||
width = bitmap.Size.Width;
|
||||
height = bitmap.Size.Height;
|
||||
scaledwidth = (float)bitmap.Size.Width * General.Map.Config.DefaultTextureScale;
|
||||
scaledheight = (float)bitmap.Size.Height * General.Map.Config.DefaultTextureScale;
|
||||
scaledwidth = (float)bitmap.Size.Width * scalex;
|
||||
scaledheight = (float)bitmap.Size.Height * scaley;
|
||||
|
||||
// Pass on to base
|
||||
filedata.Dispose();
|
||||
base.LocalLoadImage();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
int oldheight = height;
|
||||
float oldscaledwidth = scaledwidth;
|
||||
float oldscaledheight = scaledheight;
|
||||
|
||||
|
||||
// Do the loading
|
||||
LocalLoadImage();
|
||||
|
||||
|
|
125
Source/Data/PK3FileImage.cs
Normal file
125
Source/Data/PK3FileImage.cs
Normal file
|
@ -0,0 +1,125 @@
|
|||
|
||||
#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;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
public sealed class PK3FileImage : ImageData
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private PK3Reader datareader;
|
||||
private string filepathname;
|
||||
private int probableformat;
|
||||
private float scalex;
|
||||
private float scaley;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
internal PK3FileImage(PK3Reader datareader, string name, string filepathname, bool asflat)
|
||||
{
|
||||
// Initialize
|
||||
this.datareader = datareader;
|
||||
this.filepathname = filepathname;
|
||||
SetName(name);
|
||||
|
||||
if(asflat)
|
||||
{
|
||||
probableformat = ImageDataFormat.DOOMFLAT;
|
||||
scalex = General.Map.Config.DefaultFlatScale;
|
||||
scaley = General.Map.Config.DefaultFlatScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
probableformat = ImageDataFormat.DOOMPICTURE;
|
||||
scalex = General.Map.Config.DefaultTextureScale;
|
||||
scaley = General.Map.Config.DefaultTextureScale;
|
||||
}
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This loads the image
|
||||
protected override void LocalLoadImage()
|
||||
{
|
||||
// Leave when already loaded
|
||||
if(this.IsImageLoaded) return;
|
||||
|
||||
lock(this)
|
||||
{
|
||||
// Load file data
|
||||
if(bitmap != null) bitmap.Dispose(); bitmap = null;
|
||||
MemoryStream filedata = datareader.ExtractFile(filepathname);
|
||||
|
||||
// Get a reader for the data
|
||||
IImageReader reader = ImageDataFormat.GetImageReader(filedata, probableformat, General.Map.Data.Palette);
|
||||
if(!(reader is UnknownImageReader))
|
||||
{
|
||||
// Load the image
|
||||
filedata.Seek(0, SeekOrigin.Begin);
|
||||
try { bitmap = reader.ReadAsBitmap(filedata); }
|
||||
catch(InvalidDataException)
|
||||
{
|
||||
// Data cannot be read!
|
||||
bitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Not loaded?
|
||||
if(bitmap == null)
|
||||
{
|
||||
General.WriteLogLine("WARNING: Image file '" + filepathname + "' data format could not be read, while loading texture '" + this.Name + "'!");
|
||||
loadfailed = true;
|
||||
filedata.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get width and height from image
|
||||
width = bitmap.Size.Width;
|
||||
height = bitmap.Size.Height;
|
||||
scaledwidth = (float)bitmap.Size.Width * scalex;
|
||||
scaledheight = (float)bitmap.Size.Height * scaley;
|
||||
|
||||
// Pass on to base
|
||||
filedata.Dispose();
|
||||
base.LocalLoadImage();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -31,17 +31,11 @@ using ICSharpCode.SharpZipLib.Zip;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal sealed class PK3Reader : DataReader
|
||||
internal sealed class PK3Reader : PK3StructuredReader
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
private List<string> fileslist;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -50,21 +44,29 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Constructor
|
||||
public PK3Reader(DataLocation dl) : base(dl)
|
||||
{
|
||||
// Initialize
|
||||
General.WriteLogLine("Opening PK3 resource '" + location.location + "'");
|
||||
|
||||
//TEST
|
||||
/*
|
||||
ZipInputStream z = new ZipInputStream(File.Open(dl.location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||
ZipEntry ze;
|
||||
while((ze = z.GetNextEntry()) != null)
|
||||
{
|
||||
General.WriteLogLine(ze.Name);
|
||||
|
||||
}
|
||||
z.Dispose();
|
||||
*/
|
||||
|
||||
// Open the zip file
|
||||
ZipInputStream zipstream = OpenPK3File();
|
||||
|
||||
// Make list of all files
|
||||
fileslist = new List<string>();
|
||||
ZipEntry entry = zipstream.GetNextEntry();
|
||||
while(entry != null)
|
||||
{
|
||||
if(entry.IsFile) fileslist.Add(entry.Name.ToLowerInvariant());
|
||||
|
||||
// Next
|
||||
entry = zipstream.GetNextEntry();
|
||||
}
|
||||
|
||||
// Done with the zip file
|
||||
zipstream.Close();
|
||||
zipstream.Dispose();
|
||||
|
||||
// Initialize without path (because we use paths relative to the PK3 file)
|
||||
Initialize("");
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
@ -76,9 +78,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(!isdisposed)
|
||||
{
|
||||
General.WriteLogLine("Closing PK3 resource '" + location.location + "'");
|
||||
|
||||
// Clean up
|
||||
|
||||
|
||||
// Done
|
||||
base.Dispose();
|
||||
}
|
||||
|
@ -86,22 +86,148 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== Palette
|
||||
#region ================== Management
|
||||
|
||||
// This loads the PLAYPAL palette
|
||||
public override Playpal LoadPalette()
|
||||
// This opens the zip file for reading
|
||||
private ZipInputStream OpenPK3File()
|
||||
{
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Not yet implemented
|
||||
return null;
|
||||
FileStream filestream = File.Open(location.location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
filestream.Seek(0, SeekOrigin.Begin);
|
||||
return new ZipInputStream(filestream);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This creates an image
|
||||
protected override ImageData CreateImage(string name, string filename, bool flat)
|
||||
{
|
||||
return new PK3FileImage(this, name, filename, flat);
|
||||
}
|
||||
|
||||
#region ================== Textures
|
||||
// This returns true if the specified file exists
|
||||
protected override bool FileExists(string filename)
|
||||
{
|
||||
string lowfile = filename.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(f, lowfile) == 0)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This returns all files in a given directory
|
||||
protected override string[] GetAllFiles(string path)
|
||||
{
|
||||
List<string> matches = new List<string>();
|
||||
string lowpath = path.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(Path.GetFileName(f).Length > 0))
|
||||
matches.Add(f);
|
||||
}
|
||||
|
||||
return matches.ToArray();
|
||||
}
|
||||
|
||||
// This returns all files in a given directory that match the given extension
|
||||
protected override string[] GetFilesWithExt(string path, string extension)
|
||||
{
|
||||
List<string> matches = new List<string>();
|
||||
string lowpath = path.ToLowerInvariant();
|
||||
string lowext = "." + extension.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) && f.EndsWith(lowext))
|
||||
matches.Add(f);
|
||||
}
|
||||
|
||||
return matches.ToArray();
|
||||
}
|
||||
|
||||
// This finds the first file that has the specific name, regardless of file extension
|
||||
protected override string FindFirstFile(string path, string beginswith)
|
||||
{
|
||||
string lowpath = path.ToLowerInvariant();
|
||||
string lowbegin = beginswith.ToLowerInvariant();
|
||||
foreach(string f in fileslist)
|
||||
{
|
||||
if((string.Compare(Path.GetDirectoryName(f), lowpath) == 0) &&
|
||||
(string.Compare(Path.GetFileNameWithoutExtension(f), lowbegin) == 0))
|
||||
return f;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// This loads an entire file in memory and returns the stream
|
||||
// NOTE: Callers are responsible for disposing the stream!
|
||||
protected override MemoryStream LoadFile(string filename)
|
||||
{
|
||||
MemoryStream filedata = null;
|
||||
byte[] copybuffer = new byte[4096];
|
||||
|
||||
// Open the zip file
|
||||
ZipInputStream zipstream = OpenPK3File();
|
||||
|
||||
ZipEntry entry = zipstream.GetNextEntry();
|
||||
while(entry != null)
|
||||
{
|
||||
// Is this the entry we are looking for?
|
||||
if(string.Compare(entry.Name, filename, true) == 0)
|
||||
{
|
||||
int expectedsize = (int)entry.Size;
|
||||
if(expectedsize < 1) expectedsize = 1024;
|
||||
filedata = new MemoryStream(expectedsize);
|
||||
int readsize = zipstream.Read(copybuffer, 0, copybuffer.Length);
|
||||
while(readsize > 0)
|
||||
{
|
||||
filedata.Write(copybuffer, 0, readsize);
|
||||
readsize = zipstream.Read(copybuffer, 0, copybuffer.Length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Next
|
||||
entry = zipstream.GetNextEntry();
|
||||
}
|
||||
|
||||
// Done with the zip file
|
||||
zipstream.Close();
|
||||
zipstream.Dispose();
|
||||
|
||||
// Nothing found?
|
||||
if(filedata == null)
|
||||
{
|
||||
throw new FileNotFoundException("Cannot find the file " + filename + " in PK3 file " + location.location + ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
return filedata;
|
||||
}
|
||||
}
|
||||
|
||||
// This creates 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 override string CreateTempFile(string filename)
|
||||
{
|
||||
// Just copy the file
|
||||
string tempfile = General.MakeTempFilename(General.Map.TempPath, "wad");
|
||||
MemoryStream filedata = LoadFile(filename);
|
||||
File.WriteAllBytes(tempfile, filedata.ToArray());
|
||||
filedata.Dispose();
|
||||
return tempfile;
|
||||
}
|
||||
|
||||
// Public version to load a file
|
||||
internal MemoryStream ExtractFile(string filename)
|
||||
{
|
||||
return LoadFile(filename);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
413
Source/Data/PK3StructuredReader.cs
Normal file
413
Source/Data/PK3StructuredReader.cs
Normal file
|
@ -0,0 +1,413 @@
|
|||
|
||||
#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;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal abstract class PK3StructuredReader : DataReader
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const string PATCHES_DIR = "patches";
|
||||
private const string TEXTURES_DIR = "textures";
|
||||
private const string FLATS_DIR = "flats";
|
||||
private const string HIRES_DIR = "hires";
|
||||
private const string SPRITES_DIR = "sprites";
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
// Source
|
||||
private bool roottextures;
|
||||
private bool rootflats;
|
||||
|
||||
// Paths
|
||||
protected string rootpath;
|
||||
protected string patchespath;
|
||||
protected string texturespath;
|
||||
protected string flatspath;
|
||||
protected string hirespath;
|
||||
protected string spritespath;
|
||||
|
||||
// WAD files that must be loaded as well
|
||||
private List<WADReader> wads;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public PK3StructuredReader(DataLocation dl) : base(dl)
|
||||
{
|
||||
// Initialize
|
||||
this.roottextures = dl.textures;
|
||||
this.rootflats = dl.flats;
|
||||
}
|
||||
|
||||
// Call this to initialize this class
|
||||
protected virtual void Initialize(string rootpath)
|
||||
{
|
||||
// Initialize
|
||||
this.rootpath = rootpath;
|
||||
this.patchespath = Path.Combine(rootpath, PATCHES_DIR);
|
||||
this.texturespath = Path.Combine(rootpath, TEXTURES_DIR);
|
||||
this.flatspath = Path.Combine(rootpath, FLATS_DIR);
|
||||
this.hirespath = Path.Combine(rootpath, HIRES_DIR);
|
||||
this.spritespath = Path.Combine(rootpath, SPRITES_DIR);
|
||||
|
||||
// Load all WAD files in the root as WAD resources
|
||||
string[] wadfiles = GetFilesWithExt(rootpath, "wad");
|
||||
wads = new List<WADReader>(wadfiles.Length);
|
||||
foreach(string w in wadfiles)
|
||||
{
|
||||
string tempfile = CreateTempFile(w);
|
||||
DataLocation wdl = new DataLocation(DataLocation.RESOURCE_WAD, tempfile, false, false);
|
||||
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) palette = wadpalette;
|
||||
}
|
||||
|
||||
// Done
|
||||
return palette;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Textures
|
||||
|
||||
// This loads the textures
|
||||
public override ICollection<ImageData> LoadTextures(PatchNames pnames)
|
||||
{
|
||||
List<ImageData> images = new List<ImageData>();
|
||||
ICollection<ImageData> collection;
|
||||
|
||||
// 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--)
|
||||
{
|
||||
collection = wads[i].LoadTextures(pnames);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Should we load the images in this directory as textures?
|
||||
if(roottextures)
|
||||
{
|
||||
collection = LoadDirectoryImages(rootpath, false);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// TODO: Add support for hires texture here
|
||||
|
||||
// Add images from texture directory
|
||||
collection = LoadDirectoryImages(texturespath, false);
|
||||
AddImagesToList(images, collection);
|
||||
|
||||
// Load TEXTURE1 lump file
|
||||
List<ImageData> imgset = new List<ImageData>();
|
||||
string texture1file = FindFirstFile(rootpath, "TEXTURE1");
|
||||
if((texture1file != null) && FileExists(texture1file))
|
||||
{
|
||||
MemoryStream filedata = LoadFile(texture1file);
|
||||
WADReader.LoadTextureSet(filedata, ref imgset, pnames);
|
||||
filedata.Dispose();
|
||||
}
|
||||
|
||||
// Load TEXTURE2 lump file
|
||||
string texture2file = FindFirstFile(rootpath, "TEXTURE2");
|
||||
if((texture2file != null) && FileExists(texture2file))
|
||||
{
|
||||
MemoryStream filedata = LoadFile(texture2file);
|
||||
WADReader.LoadTextureSet(filedata, ref imgset, pnames);
|
||||
filedata.Dispose();
|
||||
}
|
||||
|
||||
// Add images from TEXTURE1 and TEXTURE2 lump files
|
||||
AddImagesToList(images, imgset);
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
// 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(rootpath, "PNAMES");
|
||||
if((pnamesfile != null) && FileExists(pnamesfile))
|
||||
{
|
||||
MemoryStream pnamesdata = LoadFile(pnamesfile);
|
||||
pnames = new PatchNames(pnamesdata);
|
||||
pnamesdata.Dispose();
|
||||
return pnames;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// This finds and returns a patch stream
|
||||
public override Stream GetPatchData(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 >= 0; i--)
|
||||
{
|
||||
Stream data = wads[i].GetPatchData(pname);
|
||||
if(data != null) return data;
|
||||
}
|
||||
|
||||
// Find in patches directory
|
||||
string filename = FindFirstFile(patchespath, pname);
|
||||
if((filename != null) && FileExists(filename))
|
||||
{
|
||||
return LoadFile(filename);
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Flats
|
||||
|
||||
// This loads the textures
|
||||
public override ICollection<ImageData> LoadFlats()
|
||||
{
|
||||
List<ImageData> images = new List<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].LoadFlats();
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Should we load the images in this directory as flats?
|
||||
if(rootflats)
|
||||
{
|
||||
collection = LoadDirectoryImages(rootpath, true);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Add images from flats directory
|
||||
collection = LoadDirectoryImages(flatspath, true);
|
||||
AddImagesToList(images, collection);
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Sprites
|
||||
|
||||
// This finds and returns a sprite stream
|
||||
public override Stream GetSpriteData(string pname)
|
||||
{
|
||||
string pfilename = pname.Replace('\\', '^');
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Find in any of the wad files
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Stream sprite = wads[i].GetSpriteData(pname);
|
||||
if(sprite != null) return sprite;
|
||||
}
|
||||
|
||||
// Find in sprites directory
|
||||
string filename = FindFirstFile(spritespath, pfilename);
|
||||
if((filename != null) && FileExists(filename))
|
||||
{
|
||||
return LoadFile(filename);
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This loads the images in this directory
|
||||
private ICollection<ImageData> LoadDirectoryImages(string path, bool flats)
|
||||
{
|
||||
List<ImageData> images = new List<ImageData>();
|
||||
string[] files;
|
||||
string name;
|
||||
|
||||
// Go for all files
|
||||
files = GetAllFiles(path);
|
||||
foreach(string f in files)
|
||||
{
|
||||
// Make the texture name from filename without extension
|
||||
name = Path.GetFileNameWithoutExtension(f).ToUpperInvariant();
|
||||
if(name.Length > 8) name = name.Substring(0, 8);
|
||||
|
||||
// Add image to list
|
||||
images.Add(CreateImage(name, f, flats));
|
||||
}
|
||||
|
||||
// Return result
|
||||
return images;
|
||||
}
|
||||
|
||||
// This copies images from a collection unless they already exist in the list
|
||||
private void AddImagesToList(List<ImageData> targetlist, ICollection<ImageData> sourcelist)
|
||||
{
|
||||
// Go for all source images
|
||||
foreach(ImageData src in sourcelist)
|
||||
{
|
||||
// Check if exists in target list
|
||||
bool alreadyexists = false;
|
||||
foreach(ImageData tgt in targetlist)
|
||||
{
|
||||
if(tgt.LongName == src.LongName)
|
||||
{
|
||||
alreadyexists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add source image to target list
|
||||
if(!alreadyexists) targetlist.Add(src);
|
||||
}
|
||||
}
|
||||
|
||||
// This must create an image
|
||||
protected abstract ImageData CreateImage(string name, string filename, bool flat);
|
||||
|
||||
// This must return true if the specified file exists
|
||||
protected abstract bool FileExists(string filename);
|
||||
|
||||
// This must return all files in a given directory
|
||||
protected abstract string[] GetAllFiles(string path);
|
||||
|
||||
// This must return all files in a given directory that match the given extension
|
||||
protected abstract string[] GetFilesWithExt(string path, string extension);
|
||||
|
||||
// This must find the first file that has the specific name, regardless of file extension
|
||||
protected abstract string FindFirstFile(string path, string beginswith);
|
||||
|
||||
// This must load an entire file in memory and returns the stream
|
||||
// NOTE: Callers are responsible for disposing the stream!
|
||||
protected abstract MemoryStream LoadFile(string filename);
|
||||
|
||||
// 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);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
lock(this)
|
||||
{
|
||||
// Get the patch data stream
|
||||
if(bitmap != null) bitmap.Dispose(); bitmap = null;
|
||||
patchdata = General.Map.Data.GetPatchData(lumpname);
|
||||
if(patchdata != null)
|
||||
{
|
||||
|
@ -92,16 +93,31 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// Get a reader for the data
|
||||
reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
|
||||
if(reader is UnknownImageReader)
|
||||
if(!(reader is UnknownImageReader))
|
||||
{
|
||||
// Data is in an unknown format!
|
||||
General.WriteLogLine("WARNING: Image lump '" + lumpname + "' data format could not be read, while loading texture '" + this.Name + "'!");
|
||||
// Load the image
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
try { bitmap = reader.ReadAsBitmap(mem); }
|
||||
catch(InvalidDataException)
|
||||
{
|
||||
// Data cannot be read!
|
||||
bitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the image
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
bitmap = reader.ReadAsBitmap(mem);
|
||||
if(bitmap == null) return;
|
||||
// Not loaded?
|
||||
if(bitmap == null)
|
||||
{
|
||||
General.WriteLogLine("WARNING: Image lump '" + lumpname + "' data format could not be read, while loading texture '" + this.Name + "'!");
|
||||
loadfailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get width and height from image
|
||||
width = bitmap.Size.Width;
|
||||
height = bitmap.Size.Height;
|
||||
scaledwidth = (float)width * scalex;
|
||||
scaledheight = (float)height * scaley;
|
||||
|
||||
// Done
|
||||
mem.Dispose();
|
||||
|
|
|
@ -201,7 +201,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This loads a set of textures
|
||||
private void LoadTextureSet(Stream texturedata, ref List<ImageData> images, PatchNames pnames)
|
||||
public static void LoadTextureSet(Stream texturedata, ref List<ImageData> images, PatchNames pnames)
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(texturedata);
|
||||
int flags, width, height, patches, px, py, pi;
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
break;
|
||||
|
||||
case SOURCE_FILE:
|
||||
backimage = new FileImage(background, background);
|
||||
backimage = new FileImage(background, background, false, 1.0f, 1.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace CodeImp.DoomBuilder
|
|||
internal static extern void ZeroMemory(IntPtr dest, int size);
|
||||
|
||||
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||||
internal static extern unsafe void CopyMemory(void* dst, void* src, UIntPtr length);
|
||||
internal static extern unsafe void CopyMemory(void* dst, void* src, uint length);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
|
||||
internal static extern int SendMessage(IntPtr hwnd, uint Msg, int wParam, int lParam);
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
|
||||
// Copy the pixels
|
||||
General.CopyMemory((void*)targetdata, (void*)pixeldata.Pointer, new UIntPtr((uint)(width * height * sizeof(PixelColor))));
|
||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bitmapdata);
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
|
||||
// Copy the pixels
|
||||
General.CopyMemory((void*)targetdata, (void*)pixeldata.Pointer, new UIntPtr((uint)(width * height * sizeof(PixelColor))));
|
||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bitmapdata);
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
|
||||
fixed(void* bp = namebytes)
|
||||
{
|
||||
General.CopyMemory(&value, bp, new UIntPtr(bytes));
|
||||
General.CopyMemory(&value, bp, bytes);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
|
|
@ -132,7 +132,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
// Set this file as background
|
||||
backgroundname = browsefile.FileName;
|
||||
backgroundsource = GridSetup.SOURCE_FILE;
|
||||
ImageData img = new FileImage(backgroundname, backgroundname);
|
||||
ImageData img = new FileImage(backgroundname, backgroundname, false, 1.0f, 1.0f);
|
||||
img.LoadImage();
|
||||
General.DisplayZoomedImage(backgroundimage, new Bitmap(img.Bitmap));
|
||||
img.Dispose();
|
||||
|
|
Loading…
Reference in a new issue