Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
253
Ultima/Light.cs
Normal file
253
Ultima/Light.cs
Normal file
@@ -0,0 +1,253 @@
|
||||
#region References
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
#endregion
|
||||
|
||||
namespace Ultima
|
||||
{
|
||||
public sealed class Light
|
||||
{
|
||||
private static FileIndex m_FileIndex = new FileIndex("lightidx.mul", "light.mul", 100, -1);
|
||||
private static Bitmap[] m_Cache = new Bitmap[100];
|
||||
private static bool[] m_Removed = new bool[100];
|
||||
private static byte[] m_StreamBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// ReReads light.mul
|
||||
/// </summary>
|
||||
public static void Reload()
|
||||
{
|
||||
m_FileIndex = new FileIndex("lightidx.mul", "light.mul", 100, -1);
|
||||
m_Cache = new Bitmap[100];
|
||||
m_Removed = new bool[100];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets count of definied lights
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int GetCount()
|
||||
{
|
||||
string idxPath = Files.GetFilePath("lightidx.mul");
|
||||
if (idxPath == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
using (var index = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
return (int)(index.Length / 12);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if given index is valid
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TestLight(int index)
|
||||
{
|
||||
if (m_Removed[index])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (m_Cache[index] != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int length, extra;
|
||||
bool patched;
|
||||
|
||||
Stream stream = m_FileIndex.Seek(index, out length, out extra, out patched);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
stream.Close();
|
||||
int width = (extra & 0xFFFF);
|
||||
int height = ((extra >> 16) & 0xFFFF);
|
||||
if ((width > 0) && (height > 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes Light <see cref="m_Removed" />
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
public static void Remove(int index)
|
||||
{
|
||||
m_Removed[index] = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces Light
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="bmp"></param>
|
||||
public static void Replace(int index, Bitmap bmp)
|
||||
{
|
||||
m_Cache[index] = bmp;
|
||||
m_Removed[index] = false;
|
||||
}
|
||||
|
||||
public static byte[] GetRawLight(int index, out int width, out int height)
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
if (m_Removed[index])
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int length, extra;
|
||||
bool patched;
|
||||
|
||||
Stream stream = m_FileIndex.Seek(index, out length, out extra, out patched);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
width = (extra & 0xFFFF);
|
||||
height = ((extra >> 16) & 0xFFFF);
|
||||
var buffer = new byte[length];
|
||||
stream.Read(buffer, 0, length);
|
||||
stream.Close();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Bitmap of given index
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public static unsafe Bitmap GetLight(int index)
|
||||
{
|
||||
if (m_Removed[index])
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (m_Cache[index] != null)
|
||||
{
|
||||
return m_Cache[index];
|
||||
}
|
||||
|
||||
int length, extra;
|
||||
bool patched;
|
||||
|
||||
Stream stream = m_FileIndex.Seek(index, out length, out extra, out patched);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int width = (extra & 0xFFFF);
|
||||
int height = ((extra >> 16) & 0xFFFF);
|
||||
|
||||
if (m_StreamBuffer == null || m_StreamBuffer.Length < length)
|
||||
{
|
||||
m_StreamBuffer = new byte[length];
|
||||
}
|
||||
stream.Read(m_StreamBuffer, 0, length);
|
||||
|
||||
var bmp = new Bitmap(width, height, Settings.PixelFormat);
|
||||
BitmapData bd = bmp.LockBits(
|
||||
new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, Settings.PixelFormat);
|
||||
|
||||
var line = (ushort*)bd.Scan0;
|
||||
int delta = bd.Stride >> 1;
|
||||
|
||||
fixed (byte* data = m_StreamBuffer)
|
||||
{
|
||||
var bindat = (sbyte*)data;
|
||||
for (int y = 0; y < height; ++y, line += delta)
|
||||
{
|
||||
ushort* cur = line;
|
||||
ushort* end = cur + width;
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
sbyte value = *bindat++;
|
||||
*cur++ = (ushort)(((0x1f + value) << 10) + ((0x1F + value) << 5) + (0x1F + value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bmp.UnlockBits(bd);
|
||||
stream.Close();
|
||||
if (!Files.CacheData)
|
||||
{
|
||||
return m_Cache[index] = bmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void Save(string path)
|
||||
{
|
||||
string idx = Path.Combine(path, "lightidx.mul");
|
||||
string mul = Path.Combine(path, "light.mul");
|
||||
using (
|
||||
FileStream fsidx = new FileStream(idx, FileMode.Create, FileAccess.Write, FileShare.Write),
|
||||
fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write))
|
||||
{
|
||||
using (BinaryWriter binidx = new BinaryWriter(fsidx), binmul = new BinaryWriter(fsmul))
|
||||
{
|
||||
for (int index = 0; index < m_Cache.Length; index++)
|
||||
{
|
||||
if (m_Cache[index] == null)
|
||||
{
|
||||
m_Cache[index] = GetLight(index);
|
||||
}
|
||||
Bitmap bmp = m_Cache[index];
|
||||
|
||||
if ((bmp == null) || (m_Removed[index]))
|
||||
{
|
||||
binidx.Write(-1); // lookup
|
||||
binidx.Write(-1); // length
|
||||
binidx.Write(-1); // extra
|
||||
}
|
||||
else
|
||||
{
|
||||
BitmapData bd = bmp.LockBits(
|
||||
new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, Settings.PixelFormat);
|
||||
var line = (ushort*)bd.Scan0;
|
||||
int delta = bd.Stride >> 1;
|
||||
|
||||
binidx.Write((int)fsmul.Position); //lookup
|
||||
var length = (int)fsmul.Position;
|
||||
|
||||
for (int Y = 0; Y < bmp.Height; ++Y, line += delta)
|
||||
{
|
||||
ushort* cur = line;
|
||||
ushort* end = cur + bmp.Width;
|
||||
while (cur < end)
|
||||
{
|
||||
var value = (sbyte)(((*cur++ >> 10) & 0xffff) - 0x1f);
|
||||
if (value > 0) // wtf? but it works...
|
||||
{
|
||||
--value;
|
||||
}
|
||||
binmul.Write(value);
|
||||
}
|
||||
}
|
||||
length = (int)fsmul.Position - length;
|
||||
binidx.Write(length);
|
||||
binidx.Write((bmp.Width << 16) + bmp.Height);
|
||||
bmp.UnlockBits(bd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user