mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
Added support for Boom colormaps
This commit is contained in:
parent
63c22e5d2d
commit
16dfffb068
24 changed files with 828 additions and 35 deletions
|
@ -152,6 +152,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -147,6 +147,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -152,6 +152,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -147,6 +147,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -147,6 +147,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -155,6 +155,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -166,6 +166,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -155,6 +155,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -166,6 +166,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -176,6 +176,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -165,6 +165,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -165,6 +165,16 @@ flats
|
|||
}
|
||||
}
|
||||
|
||||
// Colormap sources
|
||||
colormaps
|
||||
{
|
||||
standard1
|
||||
{
|
||||
start = "C_START";
|
||||
end = "C_END";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
GAME DETECT PATTERN
|
||||
|
|
|
@ -667,12 +667,14 @@
|
|||
<DependentUpon>ThingBrowserControl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Data\ColorImage.cs" />
|
||||
<Compile Include="Data\ColormapImage.cs" />
|
||||
<Compile Include="Data\HighResImage.cs" />
|
||||
<Compile Include="Data\PK3FileImage.cs" />
|
||||
<Compile Include="Data\PK3StructuredReader.cs" />
|
||||
<Compile Include="General\CRC.cs" />
|
||||
<Compile Include="General\ErrorItem.cs" />
|
||||
<Compile Include="General\ErrorLogger.cs" />
|
||||
<Compile Include="IO\DoomColormapReader.cs" />
|
||||
<Compile Include="Map\SelectionType.cs" />
|
||||
<Compile Include="Windows\ErrorsForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
@ -872,4 +874,4 @@
|
|||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
private IDictionary flatranges;
|
||||
private IDictionary patchranges;
|
||||
private IDictionary spriteranges;
|
||||
private IDictionary colormapranges;
|
||||
|
||||
// Things
|
||||
private List<string> defaultthingflags;
|
||||
|
@ -163,6 +164,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
public IDictionary FlatRanges { get { return flatranges; } }
|
||||
public IDictionary PatchRanges { get { return patchranges; } }
|
||||
public IDictionary SpriteRanges { get { return spriteranges; } }
|
||||
public IDictionary ColormapRanges { get { return colormapranges; } }
|
||||
|
||||
// Things
|
||||
public ICollection<string> DefaultThingFlags { get { return defaultthingflags; } }
|
||||
|
@ -276,6 +278,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
flatranges = cfg.ReadSetting("flats", new Hashtable());
|
||||
patchranges = cfg.ReadSetting("patches", new Hashtable());
|
||||
spriteranges = cfg.ReadSetting("sprites", new Hashtable());
|
||||
colormapranges = cfg.ReadSetting("colormaps", new Hashtable());
|
||||
|
||||
// Map lumps
|
||||
LoadMapLumps();
|
||||
|
|
121
Source/Core/Data/ColormapImage.cs
Normal file
121
Source/Core/Data/ColormapImage.cs
Normal file
|
@ -0,0 +1,121 @@
|
|||
|
||||
#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 sealed class ColormapImage : ImageData
|
||||
{
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public ColormapImage(string name)
|
||||
{
|
||||
// Initialize
|
||||
SetName(name);
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This loads the image
|
||||
protected override void LocalLoadImage()
|
||||
{
|
||||
Stream lumpdata;
|
||||
MemoryStream mem;
|
||||
IImageReader reader;
|
||||
byte[] membytes;
|
||||
|
||||
// Leave when already loaded
|
||||
if(this.IsImageLoaded) return;
|
||||
|
||||
lock(this)
|
||||
{
|
||||
// Get the lump data stream
|
||||
lumpdata = General.Map.Data.GetColormapData(Name);
|
||||
if(lumpdata != null)
|
||||
{
|
||||
// Copy lump data to memory
|
||||
lumpdata.Seek(0, SeekOrigin.Begin);
|
||||
membytes = new byte[(int)lumpdata.Length];
|
||||
lumpdata.Read(membytes, 0, (int)lumpdata.Length);
|
||||
mem = new MemoryStream(membytes);
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
// Get a reader for the data
|
||||
reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMCOLORMAP, General.Map.Data.Palette);
|
||||
if(reader is UnknownImageReader)
|
||||
{
|
||||
// Data is in an unknown format!
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Colormap lump '" + Name + "' data format could not be read. Does this lump contain valid colormap data at all?");
|
||||
bitmap = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read data as bitmap
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
if(bitmap != null) bitmap.Dispose();
|
||||
bitmap = reader.ReadAsBitmap(mem);
|
||||
}
|
||||
|
||||
// Done
|
||||
mem.Dispose();
|
||||
|
||||
if(bitmap != null)
|
||||
{
|
||||
// Get width and height from image
|
||||
width = bitmap.Size.Width;
|
||||
height = bitmap.Size.Height;
|
||||
scaledwidth = (float)width * General.Map.Config.DefaultFlatScale;
|
||||
scaledheight = (float)height * General.Map.Config.DefaultFlatScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
loadfailed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing a patch lump!
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Missing colormap lump '" + Name + "'. Did you forget to include required resources?");
|
||||
loadfailed = true;
|
||||
}
|
||||
|
||||
// Pass on to base
|
||||
base.LocalLoadImage();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -207,8 +207,9 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// This loads all data resources
|
||||
internal void Load(DataLocationList locations)
|
||||
{
|
||||
int texcount, flatcount, spritecount, thingcount;
|
||||
int texcount, flatcount, spritecount, thingcount, colormapcount;
|
||||
Dictionary<long, ImageData> texturesonly = new Dictionary<long, ImageData>();
|
||||
Dictionary<long, ImageData> colormapsonly = new Dictionary<long, ImageData>();
|
||||
Dictionary<long, ImageData> flatsonly = new Dictionary<long, ImageData>();
|
||||
DataReader c;
|
||||
|
||||
|
@ -289,10 +290,18 @@ namespace CodeImp.DoomBuilder.Data
|
|||
LoadPalette();
|
||||
texcount = LoadTextures(texturesonly);
|
||||
flatcount = LoadFlats(flatsonly);
|
||||
colormapcount = LoadColormaps(colormapsonly);
|
||||
thingcount = LoadDecorateThings();
|
||||
spritecount = LoadSprites();
|
||||
LoadInternalSprites();
|
||||
|
||||
|
||||
// Process colormaps (we just put them in as textures)
|
||||
foreach(KeyValuePair<long, ImageData> t in colormapsonly)
|
||||
{
|
||||
textures.Add(t.Key, t.Value);
|
||||
texturenames.Add(t.Value.Name);
|
||||
}
|
||||
|
||||
// Process textures
|
||||
foreach(KeyValuePair<long, ImageData> t in texturesonly)
|
||||
{
|
||||
|
@ -369,7 +378,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
StartBackgroundLoader();
|
||||
|
||||
// Output info
|
||||
General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " + spritecount + " sprites, " + thingcount + " decorate things");
|
||||
General.WriteLogLine("Loaded " + texcount + " textures, " + flatcount + " flats, " + colormapcount + " colormaps, " + spritecount + " sprites, " + thingcount + " decorate things");
|
||||
}
|
||||
|
||||
// This unloads all data
|
||||
|
@ -677,8 +686,60 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== Colormaps
|
||||
|
||||
// This loads the colormaps
|
||||
private int LoadColormaps(Dictionary<long, ImageData> list)
|
||||
{
|
||||
ICollection<ImageData> images;
|
||||
int counter = 0;
|
||||
|
||||
// Go for all opened containers
|
||||
foreach(DataReader dr in containers)
|
||||
{
|
||||
// Load colormaps
|
||||
images = dr.LoadColormaps();
|
||||
if(images != null)
|
||||
{
|
||||
// Go for all colormaps
|
||||
foreach(ImageData img in images)
|
||||
{
|
||||
// Add or replace in flats list
|
||||
list.Remove(img.LongName);
|
||||
list.Add(img.LongName, img);
|
||||
counter++;
|
||||
|
||||
// Add to preview manager
|
||||
previews.AddImage(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output info
|
||||
return counter;
|
||||
}
|
||||
|
||||
// This returns a specific colormap stream
|
||||
internal Stream GetColormapData(string pname)
|
||||
{
|
||||
Stream colormap;
|
||||
|
||||
// Go for all opened containers
|
||||
for(int i = containers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// This contain provides this flat?
|
||||
colormap = containers[i].GetColormapData(pname);
|
||||
if(colormap != null) return colormap;
|
||||
}
|
||||
|
||||
// No such patch found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Textures
|
||||
|
||||
|
||||
// This loads the textures
|
||||
private int LoadTextures(Dictionary<long, ImageData> list)
|
||||
{
|
||||
|
@ -758,7 +819,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// No such patch found
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// This returns an image by string
|
||||
public ImageData GetTextureImage(string name)
|
||||
{
|
||||
|
|
|
@ -102,6 +102,16 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== Colormaps
|
||||
|
||||
// When implemented, this loads the colormaps
|
||||
public virtual ICollection<ImageData> LoadColormaps() { return null; }
|
||||
|
||||
// When implemented, this returns the colormap lump
|
||||
public virtual Stream GetColormapData(string pname) { return null; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Textures
|
||||
|
||||
// When implemented, this should read the patch names
|
||||
|
|
|
@ -137,6 +137,39 @@ namespace CodeImp.DoomBuilder.Data
|
|||
return null;
|
||||
}
|
||||
|
||||
// This finds and returns a colormap stream
|
||||
public override Stream GetColormapData(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].GetColormapData(pname);
|
||||
if(data != null) return data;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Find in patches directory
|
||||
string path = Path.Combine(COLORMAPS_DIR, Path.GetDirectoryName(pname));
|
||||
string filename = FindFirstFile(path, Path.GetFileName(pname), true);
|
||||
if((filename != null) && FileExists(filename))
|
||||
{
|
||||
return LoadFile(filename);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, e.GetType().Name + " while loading colormap '" + pname + "' from directory: " + e.Message);
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Sprites
|
||||
|
@ -215,9 +248,23 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This creates an image
|
||||
protected override ImageData CreateImage(string name, string filename, bool flat)
|
||||
protected override ImageData CreateImage(string name, string filename, int imagetype)
|
||||
{
|
||||
return new FileImage(name, Path.Combine(location.location, filename), flat);
|
||||
switch(imagetype)
|
||||
{
|
||||
case ImageDataFormat.DOOMFLAT:
|
||||
return new FileImage(name, Path.Combine(location.location, filename), true);
|
||||
|
||||
case ImageDataFormat.DOOMPICTURE:
|
||||
return new FileImage(name, Path.Combine(location.location, filename), false);
|
||||
|
||||
case ImageDataFormat.DOOMCOLORMAP:
|
||||
return new ColormapImage(name);
|
||||
|
||||
default:
|
||||
throw new ArgumentException("Invalid image format specified!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// This returns true if the specified file exists
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public const int UNKNOWN = 0; // No clue.
|
||||
public const int DOOMPICTURE = 1; // Could be Doom Picture format (column list rendered data)
|
||||
public const int DOOMFLAT = 2; // Could be Doom Flat format (raw 8-bit pixel data)
|
||||
public const int DOOMCOLORMAP = 3; // Could be Doom Colormap format (raw 8-bit pixel palette mapping)
|
||||
|
||||
// File format signatures
|
||||
private static readonly int[] PNG_SIGNATURE = new int[] { 137, 80, 78, 71, 13, 10, 26, 10 };
|
||||
|
@ -47,6 +48,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
BinaryReader bindata = new BinaryReader(data);
|
||||
DoomPictureReader picreader;
|
||||
DoomFlatReader flatreader;
|
||||
DoomColormapReader colormapreader;
|
||||
|
||||
// First check the formats that provide the means to 'ensure' that
|
||||
// it actually is that format. Then guess the Doom image format.
|
||||
|
@ -87,6 +89,14 @@ namespace CodeImp.DoomBuilder.Data
|
|||
flatreader = new DoomFlatReader(palette);
|
||||
if(flatreader.Validate(data)) return flatreader;
|
||||
}
|
||||
// Could it be a doom colormap?
|
||||
else if(guessformat == DOOMCOLORMAP)
|
||||
{
|
||||
// Check if data is valid for a doom colormap
|
||||
data.Seek(0, SeekOrigin.Begin);
|
||||
colormapreader = new DoomColormapReader(palette);
|
||||
if(colormapreader.Validate(data)) return colormapreader;
|
||||
}
|
||||
|
||||
// Format not supported
|
||||
return new UnknownImageReader();
|
||||
|
|
|
@ -153,6 +153,31 @@ namespace CodeImp.DoomBuilder.Data
|
|||
return null;
|
||||
}
|
||||
|
||||
// This finds and returns a colormap stream
|
||||
public override Stream GetColormapData(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].GetColormapData(pname);
|
||||
if(data != null) return data;
|
||||
}
|
||||
|
||||
// Find in patches directory
|
||||
string filename = FindFirstFile(COLORMAPS_DIR, pname, true);
|
||||
if((filename != null) && FileExists(filename))
|
||||
{
|
||||
return LoadFile(filename);
|
||||
}
|
||||
|
||||
// Nothing found
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Sprites
|
||||
|
@ -219,9 +244,23 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This creates an image
|
||||
protected override ImageData CreateImage(string name, string filename, bool flat)
|
||||
protected override ImageData CreateImage(string name, string filename, int imagetype)
|
||||
{
|
||||
return new PK3FileImage(this, name, filename, flat);
|
||||
switch(imagetype)
|
||||
{
|
||||
case ImageDataFormat.DOOMFLAT:
|
||||
return new PK3FileImage(this, name, filename, true);
|
||||
|
||||
case ImageDataFormat.DOOMPICTURE:
|
||||
return new PK3FileImage(this, name, filename, false);
|
||||
|
||||
case ImageDataFormat.DOOMCOLORMAP:
|
||||
return new ColormapImage(name);
|
||||
|
||||
default:
|
||||
throw new ArgumentException("Invalid image format specified!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// This returns true if the specified file exists
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
protected const string FLATS_DIR = "flats";
|
||||
protected const string HIRES_DIR = "hires";
|
||||
protected const string SPRITES_DIR = "sprites";
|
||||
protected const string COLORMAPS_DIR = "colormaps";
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -175,12 +176,12 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Should we load the images in this directory as textures?
|
||||
if(roottextures)
|
||||
{
|
||||
collection = LoadDirectoryImages("", false, false);
|
||||
collection = LoadDirectoryImages("", ImageDataFormat.DOOMPICTURE, false);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Add images from texture directory
|
||||
collection = LoadDirectoryImages(TEXTURES_DIR, false, true);
|
||||
collection = LoadDirectoryImages(TEXTURES_DIR, ImageDataFormat.DOOMPICTURE, true);
|
||||
AddImagesToList(images, collection);
|
||||
|
||||
// Load TEXTURE1 lump file
|
||||
|
@ -279,12 +280,12 @@ namespace CodeImp.DoomBuilder.Data
|
|||
// Should we load the images in this directory as flats?
|
||||
if(rootflats)
|
||||
{
|
||||
collection = LoadDirectoryImages("", true, false);
|
||||
collection = LoadDirectoryImages("", ImageDataFormat.DOOMFLAT, false);
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Add images from flats directory
|
||||
collection = LoadDirectoryImages(FLATS_DIR, true, true);
|
||||
collection = LoadDirectoryImages(FLATS_DIR, ImageDataFormat.DOOMFLAT, true);
|
||||
AddImagesToList(images, collection);
|
||||
|
||||
// Add images to the container-specific texture set
|
||||
|
@ -296,6 +297,38 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== Colormaps
|
||||
|
||||
// This loads the textures
|
||||
public override ICollection<ImageData> LoadColormaps()
|
||||
{
|
||||
Dictionary<long, ImageData> images = new Dictionary<long, ImageData>();
|
||||
ICollection<ImageData> collection;
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Load from wad files
|
||||
// Note the backward order, because the last wad's images have priority
|
||||
for(int i = wads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
collection = wads[i].LoadColormaps();
|
||||
AddImagesToList(images, collection);
|
||||
}
|
||||
|
||||
// Add images from flats directory
|
||||
collection = LoadDirectoryImages(COLORMAPS_DIR, ImageDataFormat.DOOMCOLORMAP, true);
|
||||
AddImagesToList(images, collection);
|
||||
|
||||
// Add images to the container-specific texture set
|
||||
foreach(ImageData img in images.Values)
|
||||
textureset.AddFlat(img);
|
||||
|
||||
return new List<ImageData>(images.Values);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Decorate
|
||||
|
||||
// This finds and returns a sprite stream
|
||||
|
@ -329,7 +362,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
#region ================== Methods
|
||||
|
||||
// This loads the images in this directory
|
||||
private ICollection<ImageData> LoadDirectoryImages(string path, bool flats, bool includesubdirs)
|
||||
private ICollection<ImageData> LoadDirectoryImages(string path, int imagetype, bool includesubdirs)
|
||||
{
|
||||
List<ImageData> images = new List<ImageData>();
|
||||
string[] files;
|
||||
|
@ -345,7 +378,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(name.Length > 0)
|
||||
{
|
||||
// Add image to list
|
||||
images.Add(CreateImage(name, f, flats));
|
||||
images.Add(CreateImage(name, f, imagetype));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -371,7 +404,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This must create an image
|
||||
protected abstract ImageData CreateImage(string name, string filename, bool flat);
|
||||
protected abstract ImageData CreateImage(string name, string filename, int imagetype);
|
||||
|
||||
// This must return true if the specified file exists
|
||||
protected abstract bool FileExists(string filename);
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
private List<LumpRange> patchranges;
|
||||
private List<LumpRange> spriteranges;
|
||||
private List<LumpRange> textureranges;
|
||||
private List<LumpRange> colormapranges;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -84,12 +85,14 @@ namespace CodeImp.DoomBuilder.Data
|
|||
spriteranges = new List<LumpRange>();
|
||||
flatranges = new List<LumpRange>();
|
||||
textureranges = new List<LumpRange>();
|
||||
colormapranges = new List<LumpRange>();
|
||||
|
||||
// Find ranges
|
||||
FindRanges(patchranges, General.Map.Config.PatchRanges, "patches");
|
||||
FindRanges(spriteranges, General.Map.Config.SpriteRanges, "sprites");
|
||||
FindRanges(flatranges, General.Map.Config.FlatRanges, "flats");
|
||||
FindRanges(textureranges, General.Map.Config.TextureRanges, "textures");
|
||||
FindRanges(colormapranges, General.Map.Config.ColormapRanges, "colormaps");
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -195,6 +198,96 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== Colormaps
|
||||
|
||||
// This loads the textures
|
||||
public override ICollection<ImageData> LoadColormaps()
|
||||
{
|
||||
List<ImageData> images = new List<ImageData>();
|
||||
string rangestart, rangeend;
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Read ranges from configuration
|
||||
foreach(DictionaryEntry r in General.Map.Config.ColormapRanges)
|
||||
{
|
||||
// Read start and end
|
||||
rangestart = General.Map.Config.ReadSetting("colormaps." + r.Key + ".start", "");
|
||||
rangeend = General.Map.Config.ReadSetting("colormaps." + r.Key + ".end", "");
|
||||
if((rangestart.Length > 0) && (rangeend.Length > 0))
|
||||
{
|
||||
// Load texture range
|
||||
LoadColormapsRange(rangestart, rangeend, ref images);
|
||||
}
|
||||
}
|
||||
|
||||
// Add images to the container-specific texture set
|
||||
foreach(ImageData img in images)
|
||||
textureset.AddFlat(img);
|
||||
|
||||
// Return result
|
||||
return images;
|
||||
}
|
||||
|
||||
// This loads a range of colormaps
|
||||
private void LoadColormapsRange(string startlump, string endlump, ref List<ImageData> images)
|
||||
{
|
||||
int startindex, endindex;
|
||||
float defaultscale;
|
||||
ColormapImage image;
|
||||
|
||||
// Determine default scale
|
||||
defaultscale = General.Map.Config.DefaultTextureScale;
|
||||
|
||||
// Continue until no more start can be found
|
||||
startindex = file.FindLumpIndex(startlump);
|
||||
while(startindex > -1)
|
||||
{
|
||||
// Find end index
|
||||
endindex = file.FindLumpIndex(endlump, startindex + 1);
|
||||
if(endindex > -1)
|
||||
{
|
||||
// Go for all lumps between start and end exclusive
|
||||
for(int i = startindex + 1; i < endindex; i++)
|
||||
{
|
||||
// Lump not zero-length?
|
||||
if(file.Lumps[i].Length > 0)
|
||||
{
|
||||
// Make the image object
|
||||
image = new ColormapImage(file.Lumps[i].Name);
|
||||
|
||||
// Add image to collection
|
||||
images.Add(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the next start
|
||||
startindex = file.FindLumpIndex(startlump, startindex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// This finds and returns a colormap stream
|
||||
public override Stream GetColormapData(string pname)
|
||||
{
|
||||
Lump lump;
|
||||
|
||||
// Error when suspended
|
||||
if(issuspended) throw new Exception("Data reader is suspended");
|
||||
|
||||
// Find the lump in ranges
|
||||
foreach(LumpRange range in colormapranges)
|
||||
{
|
||||
lump = file.FindLump(pname, range.start, range.end);
|
||||
if(lump != null) return lump.Stream;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Textures
|
||||
|
||||
// This loads the textures
|
||||
|
@ -460,7 +553,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Flats
|
||||
|
|
242
Source/Core/IO/DoomColormapReader.cs
Normal file
242
Source/Core/IO/DoomColormapReader.cs
Normal file
|
@ -0,0 +1,242 @@
|
|||
|
||||
#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.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.IO
|
||||
{
|
||||
internal unsafe class DoomColormapReader : IImageReader
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
// Palette to use
|
||||
private Playpal palette;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public DoomColormapReader(Playpal palette)
|
||||
{
|
||||
// Initialize
|
||||
this.palette = palette;
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This validates the data as doom flat
|
||||
public bool Validate(Stream stream)
|
||||
{
|
||||
int remainder;
|
||||
|
||||
// Check if the data can be divided by 256 (each palette is 256 bytes)
|
||||
remainder = (int)stream.Length % 256;
|
||||
if(remainder == 0)
|
||||
{
|
||||
// Success when not 0
|
||||
return (stream.Length > 0);
|
||||
}
|
||||
|
||||
// Format invalid
|
||||
return false;
|
||||
}
|
||||
|
||||
// This creates a Bitmap from the given data
|
||||
// Returns null on failure
|
||||
public Bitmap ReadAsBitmap(Stream stream, out int offsetx, out int offsety)
|
||||
{
|
||||
offsetx = int.MinValue;
|
||||
offsety = int.MinValue;
|
||||
return ReadAsBitmap(stream);
|
||||
}
|
||||
|
||||
// This creates a Bitmap from the given data
|
||||
// Returns null on failure
|
||||
public Bitmap ReadAsBitmap(Stream stream)
|
||||
{
|
||||
BitmapData bitmapdata;
|
||||
PixelColorBlock pixeldata;
|
||||
PixelColor* targetdata;
|
||||
int width, height;
|
||||
Bitmap bmp;
|
||||
|
||||
// Read pixel data
|
||||
pixeldata = ReadAsPixelData(stream, out width, out height);
|
||||
if(pixeldata != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create bitmap and lock pixels
|
||||
bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
|
||||
// Copy the pixels
|
||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bitmapdata);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Unable to make bitmap
|
||||
General.ErrorLogger.Add(ErrorType.Error, "Unable to make Doom flat data. " + e.GetType().Name + ": " + e.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed loading picture
|
||||
bmp = null;
|
||||
}
|
||||
|
||||
// Return result
|
||||
return bmp;
|
||||
}
|
||||
|
||||
// This draws the picture to the given pixel color data
|
||||
// Throws exception on failure
|
||||
public unsafe void DrawToPixelData(Stream stream, PixelColor* target, int targetwidth, int targetheight, int x, int y)
|
||||
{
|
||||
Bitmap bmp;
|
||||
BitmapData bmpdata;
|
||||
PixelColor* pixels;
|
||||
int ox, oy, tx, ty;
|
||||
int width, height;
|
||||
|
||||
// Get bitmap
|
||||
bmp = ReadAsBitmap(stream);
|
||||
width = bmp.Size.Width;
|
||||
height = bmp.Size.Height;
|
||||
|
||||
// Lock bitmap pixels
|
||||
bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
pixels = (PixelColor*)bmpdata.Scan0.ToPointer();
|
||||
|
||||
// Go for all pixels in the original image
|
||||
for(ox = 0; ox < width; ox++)
|
||||
{
|
||||
for(oy = 0; oy < height; oy++)
|
||||
{
|
||||
// Copy this pixel?
|
||||
if(pixels[oy * width + ox].a > 0.5f)
|
||||
{
|
||||
// Calculate target pixel and copy when within bounds
|
||||
tx = x + ox;
|
||||
ty = y + oy;
|
||||
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
|
||||
target[ty * targetwidth + tx] = pixels[oy * width + ox];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bmpdata);
|
||||
bmp.Dispose();
|
||||
}
|
||||
|
||||
// This creates pixel color data from the given data
|
||||
// Returns null on failure
|
||||
private PixelColorBlock ReadAsPixelData(Stream stream, out int width, out int height)
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
PixelColorBlock pixeldata = null;
|
||||
byte[] bytes;
|
||||
|
||||
// Image will be 128x128
|
||||
width = 128;
|
||||
height = 128;
|
||||
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
|
||||
// Allocate memory
|
||||
pixeldata = new PixelColorBlock(width, height);
|
||||
pixeldata.Clear();
|
||||
|
||||
// Read flat bytes from stream
|
||||
bytes = new byte[width * height];
|
||||
stream.Read(bytes, 0, width * height);
|
||||
|
||||
// Draw blocks using the palette
|
||||
// We want to draw 8x8 blocks for each color
|
||||
// 16 wide and 16 high
|
||||
uint i = 0;
|
||||
for(int by = 0; by < 16; by++)
|
||||
{
|
||||
for(int bx = 0; bx < 16; bx++)
|
||||
{
|
||||
PixelColor bc = palette[bytes[i++]];
|
||||
PixelColor bc1 = General.Colors.CreateBrightVariant(palette[bytes[i++]]);
|
||||
PixelColor bc2 = General.Colors.CreateDarkVariant(palette[bytes[i++]]);
|
||||
for(int py = 0; py < 8; py++)
|
||||
{
|
||||
for(int px = 0; px < 8; px++)
|
||||
{
|
||||
int p = ((by * 8) + py) * width + (bx * 8) + px;
|
||||
|
||||
// We make the borders slightly brighter and darker
|
||||
if((py == 0) || (px == 0))
|
||||
pixeldata.Pointer[p] = bc1;
|
||||
else if((py == 7) || (px == 7))
|
||||
pixeldata.Pointer[p] = bc2;
|
||||
else
|
||||
pixeldata.Pointer[p] = bc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return pointer
|
||||
return pixeldata;
|
||||
|
||||
#if !DEBUG
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
// Return nothing
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
|
@ -228,29 +228,41 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// This creates assist colors
|
||||
internal void CreateAssistColors()
|
||||
{
|
||||
Color4 o;
|
||||
Color4 c = new Color4(1f, 0f, 0f, 0f);
|
||||
|
||||
// Go for all colors
|
||||
for(int i = 0; i < NUM_COLORS; i++)
|
||||
{
|
||||
// Get original color
|
||||
o = colors[i].ToColorValue();
|
||||
|
||||
// Create brighter color
|
||||
c.Red = Saturate(o.Red * BRIGHT_MULTIPLIER + BRIGHT_ADDITION);
|
||||
c.Green = Saturate(o.Green * BRIGHT_MULTIPLIER + BRIGHT_ADDITION);
|
||||
c.Blue = Saturate(o.Blue * BRIGHT_MULTIPLIER + BRIGHT_ADDITION);
|
||||
brightcolors[i] = PixelColor.FromInt(c.ToArgb());
|
||||
|
||||
// Create darker color
|
||||
c.Red = Saturate(o.Red * DARK_MULTIPLIER + DARK_ADDITION);
|
||||
c.Green = Saturate(o.Green * DARK_MULTIPLIER + DARK_ADDITION);
|
||||
c.Blue = Saturate(o.Blue * DARK_MULTIPLIER + DARK_ADDITION);
|
||||
darkcolors[i] = PixelColor.FromInt(c.ToArgb());
|
||||
// Create assist colors
|
||||
brightcolors[i] = CreateBrightVariant(colors[i]);
|
||||
darkcolors[i] = CreateDarkVariant(colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// This creates a brighter color
|
||||
public PixelColor CreateBrightVariant(PixelColor pc)
|
||||
{
|
||||
Color4 o = pc.ToColorValue();
|
||||
Color4 c = new Color4(1f, 0f, 0f, 0f);
|
||||
|
||||
// Create brighter color
|
||||
c.Red = Saturate(o.Red * BRIGHT_MULTIPLIER + BRIGHT_ADDITION);
|
||||
c.Green = Saturate(o.Green * BRIGHT_MULTIPLIER + BRIGHT_ADDITION);
|
||||
c.Blue = Saturate(o.Blue * BRIGHT_MULTIPLIER + BRIGHT_ADDITION);
|
||||
return PixelColor.FromInt(c.ToArgb());
|
||||
}
|
||||
|
||||
// This creates a darker color
|
||||
public PixelColor CreateDarkVariant(PixelColor pc)
|
||||
{
|
||||
Color4 o = pc.ToColorValue();
|
||||
Color4 c = new Color4(1f, 0f, 0f, 0f);
|
||||
|
||||
// Create darker color
|
||||
c.Red = Saturate(o.Red * DARK_MULTIPLIER + DARK_ADDITION);
|
||||
c.Green = Saturate(o.Green * DARK_MULTIPLIER + DARK_ADDITION);
|
||||
c.Blue = Saturate(o.Blue * DARK_MULTIPLIER + DARK_ADDITION);
|
||||
return PixelColor.FromInt(c.ToArgb());
|
||||
}
|
||||
|
||||
// This saves colors to configuration
|
||||
internal void SaveColors(Configuration cfg)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue