mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
DOES NOT COMPILE - working on resource management
This commit is contained in:
parent
4d67cc7dd4
commit
996a56dafc
7 changed files with 228 additions and 192 deletions
|
@ -77,6 +77,7 @@
|
|||
<Compile Include="Data\DirectoryReader.cs" />
|
||||
<Compile Include="Data\FileImage.cs" />
|
||||
<Compile Include="Data\FlatImage.cs" />
|
||||
<Compile Include="Data\ImageLoadState.cs" />
|
||||
<Compile Include="Data\NullImage.cs" />
|
||||
<Compile Include="Data\PatchNames.cs" />
|
||||
<Compile Include="Data\PK3Reader.cs" />
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
private Dictionary<long, ImageData> sprites;
|
||||
|
||||
// Background loading
|
||||
private LinkedList<ImageData> loadlist;
|
||||
private Queue<ImageData> imageque;
|
||||
private Thread backgroundloader;
|
||||
|
||||
// Image previews
|
||||
|
@ -77,6 +77,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
#region ================== Properties
|
||||
|
||||
public Playpal Palette { get { return palette; } }
|
||||
internal PreviewManager Previews { get { return previews; } }
|
||||
public ICollection<ImageData> Textures { get { return textures.Values; } }
|
||||
public ICollection<ImageData> Flats { get { return flats.Values; } }
|
||||
public List<string> TextureNames { get { return texturenames; } }
|
||||
|
@ -351,35 +352,48 @@ namespace CodeImp.DoomBuilder.Data
|
|||
{
|
||||
// Get next item
|
||||
ImageData image = null;
|
||||
lock(loadlist)
|
||||
lock(imageque)
|
||||
{
|
||||
// Anything to do?
|
||||
if(loadlist.Count > 0)
|
||||
{
|
||||
// Fetch image
|
||||
image = loadlist.First.Value;
|
||||
image.LoadingTicket = null;
|
||||
loadlist.RemoveFirst();
|
||||
|
||||
// Load or unload this image?
|
||||
switch(image.LoadState)
|
||||
{
|
||||
// Load image
|
||||
case ImageData.LOADSTATE_LOAD:
|
||||
image.LoadImage();
|
||||
//image.CreateTexture(); // Impossible from different thread
|
||||
break;
|
||||
|
||||
// Unload image
|
||||
case ImageData.LOADSTATE_TRASH:
|
||||
image.UnloadImage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Fethc next image to process
|
||||
if(imageque.Count > 0) image = imageque.Dequeue();
|
||||
}
|
||||
|
||||
// Did we do something?
|
||||
// Any image to process?
|
||||
if(image != null)
|
||||
{
|
||||
// Load this image?
|
||||
if(image.ImageState == ImageLoadState.Loading)
|
||||
{
|
||||
// Still referenced?
|
||||
if(image.IsReferenced)
|
||||
image.LoadImage();
|
||||
else
|
||||
image.ImageState = ImageLoadState.None;
|
||||
}
|
||||
|
||||
// Unload this image?
|
||||
if(image.ImageState == ImageLoadState.Unloading)
|
||||
{
|
||||
// Still unreferenced?
|
||||
if(!image.IsReferenced)
|
||||
image.UnloadImage();
|
||||
else
|
||||
image.ImageState = ImageLoadState.Ready;
|
||||
}
|
||||
}
|
||||
|
||||
// Doing something?
|
||||
if(image != null)
|
||||
{
|
||||
// Wait a bit and update icon
|
||||
General.MainWindow.UpdateStatusIcon();
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Process previews only when we don't have images to process
|
||||
// because these are lower priority than the actual images
|
||||
if(previews.BackgroundLoad())
|
||||
{
|
||||
// Wait a bit and update icon
|
||||
General.MainWindow.UpdateStatusIcon();
|
||||
|
@ -391,6 +405,10 @@ namespace CodeImp.DoomBuilder.Data
|
|||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
image = null;
|
||||
}
|
||||
while(true);
|
||||
}
|
||||
catch(ThreadInterruptedException)
|
||||
|
@ -400,54 +418,28 @@ namespace CodeImp.DoomBuilder.Data
|
|||
}
|
||||
|
||||
// This adds an image for background loading or unloading
|
||||
public void BackgroundLoadImage(ImageData img, bool load)
|
||||
internal void ProcessImage(ImageData img)
|
||||
{
|
||||
int loadstate = load ? ImageData.LOADSTATE_LOAD : ImageData.LOADSTATE_TRASH;
|
||||
// Load this image?
|
||||
if((img.ImageState == ImageLoadState.None) && img.IsReferenced)
|
||||
{
|
||||
// Add for loading
|
||||
img.ImageState = ImageLoadState.Loading;
|
||||
lock(imageque) { imageque.Enqueue(img); }
|
||||
}
|
||||
|
||||
lock(loadlist)
|
||||
// Unload this image?
|
||||
if((img.ImageState == ImageLoadState.Ready) && !img.IsReferenced)
|
||||
{
|
||||
// Already in the list?
|
||||
if(img.LoadingTicket != null)
|
||||
{
|
||||
// Just change the state
|
||||
img.LoadState = loadstate;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set load state and add to list
|
||||
img.LoadState = loadstate;
|
||||
img.LoadingTicket = loadlist.AddLast(img);
|
||||
}
|
||||
// Add for unloading
|
||||
img.ImageState = ImageLoadState.Unloading;
|
||||
lock(imageque) { imageque.Enqueue(img); }
|
||||
}
|
||||
|
||||
// Update icon
|
||||
General.MainWindow.UpdateStatusIcon();
|
||||
}
|
||||
|
||||
// This removes an image from background loading
|
||||
// This does not work for images that are being unloaded!
|
||||
public void BackgroundCancelImage(ImageData img)
|
||||
{
|
||||
// Queued?
|
||||
if(img.LoadingTicket != null)
|
||||
{
|
||||
// Not being trashed?
|
||||
if(img.LoadState != ImageData.LOADSTATE_TRASH)
|
||||
{
|
||||
lock(loadlist)
|
||||
{
|
||||
// Remove it from queue
|
||||
LinkedListNode<ImageData> ticket = img.LoadingTicket;
|
||||
img.LoadingTicket = null;
|
||||
loadlist.Remove(ticket);
|
||||
}
|
||||
|
||||
// Update icon
|
||||
General.MainWindow.UpdateStatusIcon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Palette
|
||||
|
|
|
@ -37,10 +37,6 @@ namespace CodeImp.DoomBuilder.Data
|
|||
{
|
||||
#region ================== Constants
|
||||
|
||||
internal const int LOADSTATE_NONE = 0;
|
||||
internal const int LOADSTATE_LOAD = 1;
|
||||
internal const int LOADSTATE_TRASH = 2;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
@ -54,19 +50,20 @@ namespace CodeImp.DoomBuilder.Data
|
|||
protected float scaledheight;
|
||||
protected bool usecolorcorrection;
|
||||
|
||||
// Background loading
|
||||
private LinkedListNode<ImageData> loadingticket;
|
||||
private int loadstate;
|
||||
private bool temporary;
|
||||
// Loading
|
||||
private LinkedListNode<ImageData> processticket;
|
||||
private ImageLoadState previewstate;
|
||||
private ImageLoadState imagestate;
|
||||
|
||||
// References
|
||||
private bool usedinmap;
|
||||
private int references;
|
||||
|
||||
// GDI bitmap
|
||||
protected Bitmap bitmap;
|
||||
|
||||
// 2D rendering data
|
||||
private PixelColorBlock pixeldata;
|
||||
|
||||
// Direct3D texture
|
||||
private int mipmaplevels = 0; // 0 creates the full chain
|
||||
private int mipmaplevels = 0; // 0 = all mipmaps
|
||||
private Texture texture;
|
||||
|
||||
// Disposing
|
||||
|
@ -79,14 +76,16 @@ namespace CodeImp.DoomBuilder.Data
|
|||
public string Name { get { return name; } }
|
||||
public long LongName { get { return longname; } }
|
||||
public bool UseColorCorrection { get { return usecolorcorrection; } set { usecolorcorrection = value; } }
|
||||
public PixelColorBlock PixelData { get { lock(this) { return pixeldata; } } }
|
||||
public Bitmap Bitmap { get { lock(this) { if(bitmap != null) return new Bitmap(bitmap); else return CodeImp.DoomBuilder.Properties.Resources.Hourglass; } } }
|
||||
public Texture Texture { get { lock(this) { return texture; } } }
|
||||
public bool IsLoaded { get { return (bitmap != null) && (loadstate != ImageData.LOADSTATE_LOAD); } }
|
||||
public bool IsPreviewLoaded { get { lock(this) { return (previewstate == ImageLoadState.Ready); } } }
|
||||
public bool IsImageLoaded { get { lock(this) { return (imagestate == ImageLoadState.Ready); } } }
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
internal bool Temporary { get { return temporary; } set { temporary = value; } }
|
||||
internal int LoadState { get { return loadstate; } set { loadstate = value; } }
|
||||
internal LinkedListNode<ImageData> LoadingTicket { get { return loadingticket; } set { loadingticket = value; } }
|
||||
internal ImageLoadState ImageState { get { return imagestate; } set { imagestate = value; } }
|
||||
internal ImageLoadState PreviewState { get { return previewstate; } set { previewstate = value; } }
|
||||
internal LinkedListNode<ImageData> ProcessTicket { get { return processticket; } set { processticket = value; } }
|
||||
internal bool IsReferenced { get { return (references > 0) || usedinmap; } }
|
||||
internal bool UsedInMap { get { return usedinmap; } set { usedinmap = value; } }
|
||||
public int MipMapLevels { get { return mipmaplevels; } set { mipmaplevels = value; } }
|
||||
public int Width { get { return width; } }
|
||||
public int Height { get { return height; } }
|
||||
|
@ -120,9 +119,12 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(texture != null) texture.Dispose();
|
||||
bitmap = null;
|
||||
texture = null;
|
||||
pixeldata = null;
|
||||
|
||||
// Done
|
||||
usedinmap = false;
|
||||
references = 0;
|
||||
imagestate = ImageLoadState.None;
|
||||
previewstate = ImageLoadState.None;
|
||||
isdisposed = true;
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +134,19 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#region ================== Management
|
||||
|
||||
// This adds a reference
|
||||
public void AddReference()
|
||||
{
|
||||
references++;
|
||||
}
|
||||
|
||||
// This removes a reference
|
||||
public void RemoveReference()
|
||||
{
|
||||
references--;
|
||||
if(references < 0) General.Fail("FAIL! (references < 0)", "Somewhere this image is dereferenced more than it was referenced.");
|
||||
}
|
||||
|
||||
// This sets the name
|
||||
protected void SetName(string name)
|
||||
{
|
||||
|
@ -146,7 +161,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
{
|
||||
if(bitmap != null) bitmap.Dispose();
|
||||
bitmap = null;
|
||||
loadstate = ImageData.LOADSTATE_NONE;
|
||||
imagestate = ImageLoadState.None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,10 +170,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
{
|
||||
BitmapData bmpdata = null;
|
||||
|
||||
// Determine amounts
|
||||
float gamma = (float)(General.Settings.ImageBrightness + 10) * 0.1f;
|
||||
float bright = (float)General.Settings.ImageBrightness * 5f;
|
||||
|
||||
lock(this)
|
||||
{
|
||||
// This applies brightness correction on the image
|
||||
if((bitmap != null) && usecolorcorrection)
|
||||
{
|
||||
|
@ -176,45 +189,14 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(bmpdata != null)
|
||||
{
|
||||
// Apply color correction
|
||||
byte* pixels = (byte*)(bmpdata.Scan0.ToPointer());
|
||||
for(int p = 0; p < bmpdata.Stride * bmpdata.Height; p += 4)
|
||||
{
|
||||
// Apply color correction for individual colors
|
||||
float r = (float)pixels[p + 0] * gamma + bright;
|
||||
float g = (float)pixels[p + 1] * gamma + bright;
|
||||
float b = (float)pixels[p + 2] * gamma + bright;
|
||||
|
||||
// Clamp to 0..255 range
|
||||
if(r < 0f) pixels[p + 0] = 0; else if(r > 255f) pixels[p + 0] = 255; else pixels[p + 0] = (byte)r;
|
||||
if(g < 0f) pixels[p + 1] = 0; else if(g > 255f) pixels[p + 1] = 255; else pixels[p + 1] = (byte)g;
|
||||
if(b < 0f) pixels[p + 2] = 0; else if(b > 255f) pixels[p + 2] = 255; else pixels[p + 2] = (byte)b;
|
||||
}
|
||||
|
||||
// Done with the lock
|
||||
PixelColor* pixels = (PixelColor*)(bmpdata.Scan0.ToPointer());
|
||||
General.Colors.ApplColorCorrection(pixels, bmpdata.Width * bmpdata.Height);
|
||||
bitmap.UnlockBits(bmpdata);
|
||||
}
|
||||
}
|
||||
|
||||
// Done, reset load state
|
||||
loadstate = ImageData.LOADSTATE_NONE;
|
||||
}
|
||||
|
||||
// This creates the 2D pixel data
|
||||
internal virtual void CreatePixelData()
|
||||
{
|
||||
BitmapData bmpdata;
|
||||
|
||||
lock(this)
|
||||
{
|
||||
// Only do this when data is not created yet
|
||||
if((pixeldata == null) && IsLoaded)
|
||||
{
|
||||
// Make a data copy of the bits for the 2D renderer
|
||||
bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
pixeldata = new PixelColorBlock(bitmap.Size.Width, bitmap.Size.Height);
|
||||
General.CopyMemory((void*)pixeldata.Pointer, bmpdata.Scan0.ToPointer(), new UIntPtr(pixeldata.Length));
|
||||
bitmap.UnlockBits(bmpdata);
|
||||
}
|
||||
// Image is ready
|
||||
imagestate = ImageLoadState.Ready;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,7 +208,7 @@ namespace CodeImp.DoomBuilder.Data
|
|||
lock(this)
|
||||
{
|
||||
// Only do this when texture is not created yet
|
||||
if(((texture == null) || (texture.Disposed)) && IsLoaded)
|
||||
if(((texture == null) || (texture.Disposed)) && this.IsLoaded)
|
||||
{
|
||||
// Write to memory stream and read from memory
|
||||
memstream = new MemoryStream();
|
||||
|
|
43
Source/Data/ImageLoadState.cs
Normal file
43
Source/Data/ImageLoadState.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
#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 SlimDX.Direct3D9;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Data
|
||||
{
|
||||
internal enum ImageLoadState : int
|
||||
{
|
||||
None,
|
||||
Loading,
|
||||
Ready,
|
||||
Unloading
|
||||
}
|
||||
}
|
|
@ -138,6 +138,14 @@ namespace CodeImp.DoomBuilder.Data
|
|||
if(GetAtlasIndex(nextpreviewindex) > (atlases.Count - 1)) MakeNewAtlas();
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Background loading
|
||||
// Return true when we have more work to do, so that the
|
||||
// thread will not wait too long before calling again
|
||||
internal bool BackgroundLoad()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -99,6 +99,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
private PixelColor[] brightcolors;
|
||||
private PixelColor[] darkcolors;
|
||||
|
||||
// Color-correction table
|
||||
private byte[] correctiontable;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -174,24 +177,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
// Create assist colors
|
||||
CreateAssistColors();
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
internal ColorCollection(ColorCollection collection)
|
||||
{
|
||||
// Initialize
|
||||
colors = new PixelColor[NUM_COLORS];
|
||||
brightcolors = new PixelColor[NUM_COLORS];
|
||||
darkcolors = new PixelColor[NUM_COLORS];
|
||||
|
||||
// Copy all colors
|
||||
for(int i = 0; i < NUM_COLORS; i++)
|
||||
colors[i] = collection.colors[i];
|
||||
|
||||
// Create assist colors
|
||||
CreateAssistColors();
|
||||
// Create color correction table
|
||||
General.Colors.CreateCorrectionTable();
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -201,6 +188,37 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// This generates a color-correction table
|
||||
internal void CreateCorrectionTable()
|
||||
{
|
||||
// Determine amounts
|
||||
float gamma = (float)(General.Settings.ImageBrightness + 10) * 0.1f;
|
||||
float bright = (float)General.Settings.ImageBrightness * 5f;
|
||||
|
||||
// Make table
|
||||
correctiontable = new byte[256];
|
||||
|
||||
// Fill table
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
byte b;
|
||||
float a = (float)i * gamma + bright;
|
||||
if(a < 0f) b = 0; else if(a > 255f) b = 255; else b = (byte)a;
|
||||
correctiontable[i] = b;
|
||||
}
|
||||
}
|
||||
|
||||
// This applies color-correction over a block of pixel data
|
||||
internal unsafe void ApplColorCorrection(PixelColor* pixels, int numpixels)
|
||||
{
|
||||
for(int i = 0; i < numpixels; i++)
|
||||
{
|
||||
pixels[i].r = correctiontable[pixels[i].r];
|
||||
pixels[i].g = correctiontable[pixels[i].g];
|
||||
pixels[i].b = correctiontable[pixels[i].b];
|
||||
}
|
||||
}
|
||||
|
||||
// This clamps a value between 0 and 1
|
||||
private float Saturate(float v)
|
||||
{
|
||||
|
@ -233,17 +251,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
}
|
||||
}
|
||||
|
||||
// This applies colors to this collection
|
||||
internal void Apply(ColorCollection collection)
|
||||
{
|
||||
// Copy all colors
|
||||
for(int i = 0; i < NUM_COLORS; i++)
|
||||
colors[i] = collection.colors[i];
|
||||
|
||||
// Rebuild assist colors
|
||||
CreateAssistColors();
|
||||
}
|
||||
|
||||
// This saves colors to configuration
|
||||
internal void SaveColors(Configuration cfg)
|
||||
{
|
||||
|
|
|
@ -1695,6 +1695,9 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
// Update shortcut keys in menus
|
||||
ApplyShortcutKeys();
|
||||
|
||||
// Generate new color correction table
|
||||
General.Colors.CreateCorrectionTable();
|
||||
|
||||
// Let the plugins know
|
||||
General.Plugins.ProgramReconfigure();
|
||||
|
||||
|
|
Loading…
Reference in a new issue