382 lines
12 KiB
C#
382 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace GMAssetCompiler
|
|
{
|
|
internal class Texture
|
|
{
|
|
public yyRect TextureRects;
|
|
|
|
public Bitmap Bitmap
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public int GridSizeX
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public int GridSizeY
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public int AreaFree
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public int TP
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public int Group
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public List<TexturePageEntry> Entries
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public Texture(int _width, int _height, int _gridX, int _gridY, int _marginX, int _marginY)
|
|
{
|
|
GridSizeX = _gridX;
|
|
GridSizeY = _gridY;
|
|
AreaFree = _width * _height;
|
|
Entries = new List<TexturePageEntry>();
|
|
Resize(_width, _height);
|
|
}
|
|
|
|
public void Resize(int width, int height)
|
|
{
|
|
AreaFree = width * height;
|
|
Bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
|
using (Graphics graphics = Graphics.FromImage(Bitmap))
|
|
{
|
|
graphics.Clear(Color.FromArgb(0));
|
|
}
|
|
TextureRects = yyRect.Create(width, height);
|
|
}
|
|
|
|
public static Bitmap ResizeImage(Bitmap _source, int _destWidth, int _destHeight)
|
|
{
|
|
Bitmap bitmap = new Bitmap(_destWidth, _destHeight);
|
|
Graphics graphics = Graphics.FromImage(bitmap);
|
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
graphics.DrawImage(_source, 0, 0, _destWidth, _destHeight);
|
|
graphics.Dispose();
|
|
return bitmap;
|
|
}
|
|
|
|
public bool Alloc(TexturePageEntry _entry, out int _X, out int _Y)
|
|
{
|
|
bool flag = false;
|
|
bool flag2 = false;
|
|
_X = -1;
|
|
_Y = -1;
|
|
int num = GridSizeX;
|
|
int num2 = GridSizeY;
|
|
int num3 = _entry.W;
|
|
int num4 = _entry.H;
|
|
if (_entry.OriginalRepeatBorder)
|
|
{
|
|
num += _entry.RepeatX;
|
|
num2 += _entry.RepeatY;
|
|
}
|
|
if (num3 < Bitmap.Width)
|
|
{
|
|
num3 += num;
|
|
num3 += num;
|
|
num3 = ((num3 + 3) & -4);
|
|
flag = true;
|
|
}
|
|
if (num4 < Bitmap.Height)
|
|
{
|
|
num4 += num2;
|
|
num4 += num2;
|
|
num4 = ((num4 + 3) & -4);
|
|
flag2 = true;
|
|
}
|
|
_entry.RepeatBorder = _entry.OriginalRepeatBorder;
|
|
if (!flag || !flag2)
|
|
{
|
|
_entry.RepeatBorder = false;
|
|
}
|
|
yyRect yyRect = TextureRects.Test(num3, num4);
|
|
if (yyRect != null)
|
|
{
|
|
Point point = TextureRects.AddImage(yyRect, num3, num4);
|
|
_X = point.X;
|
|
_Y = point.Y;
|
|
if (flag)
|
|
{
|
|
_X += num;
|
|
}
|
|
if (flag2)
|
|
{
|
|
_Y += num2;
|
|
}
|
|
AreaFree -= num3 * num4;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void CopyEntries()
|
|
{
|
|
Rectangle rect = new Rectangle(0, 0, Bitmap.Width, Bitmap.Height);
|
|
BitmapData bitmapData = Bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
|
foreach (TexturePageEntry entry in Entries)
|
|
{
|
|
Rectangle rect2 = new Rectangle(0, 0, entry.W, entry.H);
|
|
BitmapData bitmapData2 = entry.Bitmap.LockBits(rect2, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
|
IntPtr intPtr = new IntPtr(bitmapData2.Scan0.ToInt64());
|
|
IntPtr intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + entry.Y * bitmapData.Stride + entry.X * 4);
|
|
int num = 0;
|
|
while (num < entry.Bitmap.Height)
|
|
{
|
|
IntPtr ptr = intPtr;
|
|
IntPtr ptr2 = intPtr2;
|
|
int num2 = 0;
|
|
while (num2 < entry.Bitmap.Width)
|
|
{
|
|
int val = Marshal.ReadInt32(ptr);
|
|
Marshal.WriteInt32(ptr2, val);
|
|
num2++;
|
|
ptr2 = new IntPtr(ptr2.ToInt64() + 4);
|
|
ptr = new IntPtr(ptr.ToInt64() + 4);
|
|
}
|
|
num++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() + bitmapData.Stride);
|
|
intPtr = new IntPtr(intPtr.ToInt64() + bitmapData2.Stride);
|
|
}
|
|
if (entry.RepeatBorder && !entry.IgnoreRepeatBorder)
|
|
{
|
|
intPtr = new IntPtr(bitmapData2.Scan0.ToInt64());
|
|
intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y + entry.H) * bitmapData.Stride + entry.X * 4);
|
|
int num3 = 0;
|
|
while (num3 < entry.RepeatY)
|
|
{
|
|
IntPtr ptr3 = intPtr;
|
|
IntPtr ptr4 = intPtr2;
|
|
int num4 = 0;
|
|
while (num4 < entry.Bitmap.Width)
|
|
{
|
|
Marshal.WriteInt32(ptr4, Marshal.ReadInt32(ptr3));
|
|
num4++;
|
|
ptr4 = new IntPtr(ptr4.ToInt64() + 4);
|
|
ptr3 = new IntPtr(ptr3.ToInt64() + 4);
|
|
}
|
|
num3++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() + bitmapData.Stride);
|
|
intPtr = new IntPtr(intPtr.ToInt64() + bitmapData2.Stride);
|
|
}
|
|
intPtr = new IntPtr(bitmapData2.Scan0.ToInt64() + (entry.H - entry.RepeatY) * bitmapData2.Stride);
|
|
intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y - entry.RepeatY) * bitmapData.Stride + entry.X * 4);
|
|
int num5 = 0;
|
|
while (num5 < entry.RepeatY)
|
|
{
|
|
IntPtr ptr5 = intPtr;
|
|
IntPtr ptr6 = intPtr2;
|
|
int num6 = 0;
|
|
while (num6 < entry.Bitmap.Width)
|
|
{
|
|
Marshal.WriteInt32(ptr6, Marshal.ReadInt32(ptr5));
|
|
num6++;
|
|
ptr6 = new IntPtr(ptr6.ToInt64() + 4);
|
|
ptr5 = new IntPtr(ptr5.ToInt64() + 4);
|
|
}
|
|
num5++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() + bitmapData.Stride);
|
|
intPtr = new IntPtr(intPtr.ToInt64() + bitmapData2.Stride);
|
|
}
|
|
intPtr = new IntPtr(bitmapData2.Scan0.ToInt64());
|
|
intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + entry.Y * bitmapData.Stride + (entry.X - entry.RepeatX) * 4);
|
|
int num7 = 0;
|
|
while (num7 < entry.Bitmap.Height)
|
|
{
|
|
IntPtr ptr7 = intPtr;
|
|
IntPtr ptr8 = intPtr2;
|
|
int num8 = 0;
|
|
while (num8 < entry.RepeatX)
|
|
{
|
|
IntPtr ptr9 = new IntPtr(ptr7.ToInt64() + (entry.W - entry.RepeatX) * 4);
|
|
IntPtr ptr10 = new IntPtr(ptr8.ToInt64() + (entry.W + entry.RepeatX) * 4);
|
|
Marshal.WriteInt32(ptr8, Marshal.ReadInt32(ptr9));
|
|
Marshal.WriteInt32(ptr10, Marshal.ReadInt32(ptr7));
|
|
num8++;
|
|
ptr8 = new IntPtr(ptr8.ToInt64() + 4);
|
|
ptr7 = new IntPtr(ptr7.ToInt64() + 4);
|
|
}
|
|
num7++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() + bitmapData.Stride);
|
|
intPtr = new IntPtr(intPtr.ToInt64() + bitmapData2.Stride);
|
|
}
|
|
for (int i = 0; i < entry.RepeatY; i++)
|
|
{
|
|
for (int j = 0; j < entry.RepeatX; j++)
|
|
{
|
|
IntPtr ptr11 = new IntPtr(bitmapData2.Scan0.ToInt64() + i * bitmapData2.Stride + j * 4);
|
|
IntPtr ptr12 = new IntPtr(bitmapData2.Scan0.ToInt64() + (entry.H - (i + 1)) * bitmapData2.Stride + j * 4);
|
|
IntPtr ptr13 = new IntPtr(ptr11.ToInt64() + (entry.W - (j + 1)) * 4);
|
|
IntPtr ptr14 = new IntPtr(ptr12.ToInt64() + (entry.W - (j + 1)) * 4);
|
|
IntPtr ptr15 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y - (i + 1)) * bitmapData.Stride + (entry.X - (j + 1)) * 4);
|
|
IntPtr ptr16 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y + entry.H + i) * bitmapData.Stride + (entry.X - (j + 1)) * 4);
|
|
IntPtr ptr17 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y - (i + 1)) * bitmapData.Stride + (entry.X + entry.W + j) * 4);
|
|
IntPtr ptr18 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y + entry.H + i) * bitmapData.Stride + (entry.X + entry.W + j) * 4);
|
|
Marshal.WriteInt32(ptr15, Marshal.ReadInt32(ptr14));
|
|
Marshal.WriteInt32(ptr18, Marshal.ReadInt32(ptr11));
|
|
Marshal.WriteInt32(ptr17, Marshal.ReadInt32(ptr12));
|
|
Marshal.WriteInt32(ptr16, Marshal.ReadInt32(ptr13));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (entry.Y != 0)
|
|
{
|
|
intPtr = new IntPtr(bitmapData2.Scan0.ToInt64());
|
|
intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y - 1) * bitmapData.Stride + entry.X * 4);
|
|
int num9 = 0;
|
|
while (num9 < GridSizeY)
|
|
{
|
|
IntPtr ptr19 = intPtr;
|
|
IntPtr ptr20 = intPtr2;
|
|
int num10 = 0;
|
|
while (num10 < entry.Bitmap.Width)
|
|
{
|
|
Marshal.WriteInt32(ptr20, Marshal.ReadInt32(ptr19));
|
|
num10++;
|
|
ptr20 = new IntPtr(ptr20.ToInt64() + 4);
|
|
ptr19 = new IntPtr(ptr19.ToInt64() + 4);
|
|
}
|
|
num9++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() - bitmapData.Stride);
|
|
}
|
|
}
|
|
if (entry.Y + entry.H != Bitmap.Height)
|
|
{
|
|
intPtr = new IntPtr(bitmapData2.Scan0.ToInt64() + (entry.H - 1) * bitmapData2.Stride);
|
|
intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y + entry.H) * bitmapData.Stride + entry.X * 4);
|
|
int num11 = 0;
|
|
while (num11 < GridSizeY)
|
|
{
|
|
IntPtr ptr21 = intPtr;
|
|
IntPtr ptr22 = intPtr2;
|
|
int num12 = 0;
|
|
while (num12 < entry.Bitmap.Width)
|
|
{
|
|
Marshal.WriteInt32(ptr22, Marshal.ReadInt32(ptr21));
|
|
num12++;
|
|
ptr22 = new IntPtr(ptr22.ToInt64() + 4);
|
|
ptr21 = new IntPtr(ptr21.ToInt64() + 4);
|
|
}
|
|
num11++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() + bitmapData.Stride);
|
|
}
|
|
}
|
|
if (entry.X != 0)
|
|
{
|
|
intPtr = new IntPtr(bitmapData2.Scan0.ToInt64());
|
|
intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + entry.Y * bitmapData.Stride + (entry.X - 1) * 4);
|
|
int num13 = 0;
|
|
while (num13 < entry.Bitmap.Height)
|
|
{
|
|
IntPtr ptr23 = intPtr;
|
|
IntPtr ptr24 = intPtr2;
|
|
int num14 = 0;
|
|
while (num14 < GridSizeX)
|
|
{
|
|
Marshal.WriteInt32(ptr24, Marshal.ReadInt32(ptr23));
|
|
num14++;
|
|
ptr24 = new IntPtr(ptr24.ToInt64() - 4);
|
|
}
|
|
num13++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() + bitmapData.Stride);
|
|
intPtr = new IntPtr(intPtr.ToInt64() + bitmapData2.Stride);
|
|
}
|
|
}
|
|
if (entry.X + entry.W != Bitmap.Width)
|
|
{
|
|
intPtr = new IntPtr(bitmapData2.Scan0.ToInt64() + (entry.W - 1) * 4);
|
|
intPtr2 = new IntPtr(bitmapData.Scan0.ToInt64() + entry.Y * bitmapData.Stride + (entry.X + entry.W) * 4);
|
|
int num15 = 0;
|
|
while (num15 < entry.Bitmap.Height)
|
|
{
|
|
IntPtr ptr25 = intPtr;
|
|
IntPtr ptr26 = intPtr2;
|
|
int num16 = 0;
|
|
while (num16 < GridSizeX)
|
|
{
|
|
Marshal.WriteInt32(ptr26, Marshal.ReadInt32(ptr25));
|
|
num16++;
|
|
ptr26 = new IntPtr(ptr26.ToInt64() + 4);
|
|
}
|
|
num15++;
|
|
intPtr2 = new IntPtr(intPtr2.ToInt64() + bitmapData.Stride);
|
|
intPtr = new IntPtr(intPtr.ToInt64() + bitmapData2.Stride);
|
|
}
|
|
}
|
|
IntPtr ptr27 = new IntPtr(bitmapData2.Scan0.ToInt64());
|
|
IntPtr ptr28 = new IntPtr(bitmapData2.Scan0.ToInt64() + (entry.H - 1) * bitmapData2.Stride);
|
|
IntPtr ptr29 = new IntPtr(ptr27.ToInt64() + (entry.W - 1) * 4);
|
|
IntPtr ptr30 = new IntPtr(ptr28.ToInt64() + (entry.W - 1) * 4);
|
|
int val2 = Marshal.ReadInt32(ptr30);
|
|
int val3 = Marshal.ReadInt32(ptr29);
|
|
int val4 = Marshal.ReadInt32(ptr28);
|
|
int val5 = Marshal.ReadInt32(ptr27);
|
|
for (int k = 0; k < GridSizeY; k++)
|
|
{
|
|
for (int l = 0; l < GridSizeX; l++)
|
|
{
|
|
if (entry.Y != 0)
|
|
{
|
|
if (entry.X != 0)
|
|
{
|
|
IntPtr ptr31 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y - (k + 1)) * bitmapData.Stride + (entry.X - (l + 1)) * 4);
|
|
Marshal.WriteInt32(ptr31, val5);
|
|
}
|
|
if (entry.X + entry.W != Bitmap.Width)
|
|
{
|
|
IntPtr ptr32 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y - (k + 1)) * bitmapData.Stride + (entry.X + entry.W + l) * 4);
|
|
Marshal.WriteInt32(ptr32, val3);
|
|
}
|
|
}
|
|
if (entry.Y + entry.H != Bitmap.Height)
|
|
{
|
|
if (entry.X != 0)
|
|
{
|
|
IntPtr ptr33 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y + entry.H + k) * bitmapData.Stride + (entry.X - (l + 1)) * 4);
|
|
Marshal.WriteInt32(ptr33, val4);
|
|
}
|
|
if (entry.X + entry.W != Bitmap.Width)
|
|
{
|
|
IntPtr ptr34 = new IntPtr(bitmapData.Scan0.ToInt64() + (entry.Y + entry.H + k) * bitmapData.Stride + (entry.X + entry.W + l) * 4);
|
|
Marshal.WriteInt32(ptr34, val2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
entry.Bitmap.UnlockBits(bitmapData2);
|
|
}
|
|
Bitmap.UnlockBits(bitmapData);
|
|
}
|
|
}
|
|
}
|