diff --git a/LibBSP/Source/Structs/BSP/Lumps/Textures.cs b/LibBSP/Source/Structs/BSP/Lumps/Textures.cs
index 023e76b..abb8308 100644
--- a/LibBSP/Source/Structs/BSP/Lumps/Textures.cs
+++ b/LibBSP/Source/Structs/BSP/Lumps/Textures.cs
@@ -104,10 +104,30 @@ namespace LibBSP {
case MapType.GoldSrc: {
int numElements = BitConverter.ToInt32(data, 0);
structLength = 40;
+ int currentOffset;
+ int width;
+ int height;
+ int power;
+ int mipmapOffset;
for (int i = 0; i < numElements; ++i) {
byte[] myBytes = new byte[structLength];
- Array.Copy(data, BitConverter.ToInt32(data, (i + 1) * 4), myBytes, 0, structLength);
- Add(new Texture(myBytes, this));
+ byte[][] mipmaps = new byte[Texture.NumMipmaps][];
+ currentOffset = BitConverter.ToInt32(data, (i + 1) * 4);
+ if (currentOffset >= 0) {
+ Array.Copy(data, currentOffset, myBytes, 0, structLength);
+ width = BitConverter.ToInt32(myBytes, 16);
+ height = BitConverter.ToInt32(myBytes, 20);
+ power = 1;
+ for (int j = 0; j < mipmaps.Length; ++j) {
+ mipmapOffset = BitConverter.ToInt32(myBytes, 24 + (4 * j));
+ if (mipmapOffset > 0) {
+ mipmaps[j] = new byte[(width / power) * (height / power)];
+ Array.Copy(data, currentOffset + mipmapOffset, mipmaps[j], 0, mipmaps[j].Length);
+ }
+ power *= 2;
+ }
+ }
+ Add(new Texture(myBytes, this, mipmaps));
}
return;
}
diff --git a/LibBSP/Source/Structs/BSP/Texture.cs b/LibBSP/Source/Structs/BSP/Texture.cs
index d997c69..67fdd54 100644
--- a/LibBSP/Source/Structs/BSP/Texture.cs
+++ b/LibBSP/Source/Structs/BSP/Texture.cs
@@ -29,6 +29,27 @@ namespace LibBSP {
///
public struct Texture : ILumpObject {
+ ///
+ /// Number of MipMap levels used by Quake/GoldSrc engines.
+ ///
+ public const int NumMipmaps = 4;
+ ///
+ /// Index of the full mipmap.
+ ///
+ public const int FullMipmap = 0;
+ ///
+ /// Index of the half mipmap.
+ ///
+ public const int HalfMipmap = 1;
+ ///
+ /// Index of the quarter mipmap.
+ ///
+ public const int QuarterMipmap = 2;
+ ///
+ /// Index of the eighth mipmap.
+ ///
+ public const int EighthMipmap = 3;
+
///
/// The this came from.
///
@@ -39,6 +60,19 @@ namespace LibBSP {
///
public byte[] Data { get; private set; }
+ private byte[][] _mipmaps;
+ ///
+ /// Mipmap image data for this .
+ ///
+ public byte[][] Mipmaps {
+ get {
+ if (_mipmaps == null && MipmapFullOffset >= 0) {
+ _mipmaps = new byte[NumMipmaps][];
+ }
+ return _mipmaps;
+ }
+ }
+
///
/// The to use to interpret .
///
@@ -341,26 +375,26 @@ namespace LibBSP {
}
///
- /// Gets or sets the width of this .
+ /// Gets or sets the dimensions of this .
///
- public uint Width {
+ public Vector2 Dimensions {
get {
switch (MapType) {
case MapType.Quake:
case MapType.GoldSrc: {
- return BitConverter.ToUInt32(Data, 16);
+ return new Vector2(BitConverter.ToUInt32(Data, 16), BitConverter.ToUInt32(Data, 20));
}
default: {
- return 0;
+ return new Vector2(0, 0);
}
}
}
set {
- byte[] bytes = BitConverter.GetBytes(value);
switch (MapType) {
case MapType.Quake:
case MapType.GoldSrc: {
- bytes.CopyTo(Data, 16);
+ BitConverter.GetBytes((int)value.X()).CopyTo(Data, 16);
+ BitConverter.GetBytes((int)value.Y()).CopyTo(Data, 20);
break;
}
}
@@ -368,44 +402,17 @@ namespace LibBSP {
}
///
- /// Gets or sets the height of this .
+ /// Gets the offset to the full mipmap of this .
///
- public uint Height {
+ public int MipmapFullOffset {
get {
switch (MapType) {
case MapType.Quake:
case MapType.GoldSrc: {
- return BitConverter.ToUInt32(Data, 20);
+ return BitConverter.ToInt32(Data, 24);
}
default: {
- return 0;
- }
- }
- }
- set {
- byte[] bytes = BitConverter.GetBytes(value);
- switch (MapType) {
- case MapType.Quake:
- case MapType.GoldSrc: {
- bytes.CopyTo(Data, 20);
- break;
- }
- }
- }
- }
-
- ///
- /// Gets the offset to the full version of this .
- ///
- public uint OffsetFull {
- get {
- switch (MapType) {
- case MapType.Quake:
- case MapType.GoldSrc: {
- return BitConverter.ToUInt32(Data, 24);
- }
- default: {
- return 0;
+ return -1;
}
}
}
@@ -422,17 +429,17 @@ namespace LibBSP {
}
///
- /// Gets the offset to the half version of this .
+ /// Gets the offset to the half mipmap of this .
///
- public uint OffsetHalf {
+ public int MipmapHalfOffset {
get {
switch (MapType) {
case MapType.Quake:
case MapType.GoldSrc: {
- return BitConverter.ToUInt32(Data, 28);
+ return BitConverter.ToInt32(Data, 28);
}
default: {
- return 0;
+ return -1;
}
}
}
@@ -449,17 +456,17 @@ namespace LibBSP {
}
///
- /// Gets the offset to the quarter version of this .
+ /// Gets the offset to the quarter mipmap of this .
///
- public uint OffsetQuarter {
+ public int MipmapQuarterOffset {
get {
switch (MapType) {
case MapType.Quake:
case MapType.GoldSrc: {
- return BitConverter.ToUInt32(Data, 32);
+ return BitConverter.ToInt32(Data, 32);
}
default: {
- return 0;
+ return -1;
}
}
}
@@ -476,17 +483,17 @@ namespace LibBSP {
}
///
- /// Gets the offset to the eighth version of this .
+ /// Gets the offset to the eighth mipmap of this .
///
- public uint OffsetEighth {
+ public int MipmapEighthOffset {
get {
switch (MapType) {
case MapType.Quake:
case MapType.GoldSrc: {
- return BitConverter.ToUInt32(Data, 36);
+ return BitConverter.ToInt32(Data, 36);
}
default: {
- return 0;
+ return -1;
}
}
}
@@ -604,13 +611,23 @@ namespace LibBSP {
/// byte array to parse.
/// The this came from.
/// was null.
- public Texture(byte[] data, ILump parent) {
+ public Texture(byte[] data, ILump parent) : this(data, parent, null) { }
+
+ ///
+ /// Creates a new object from a byte array.
+ ///
+ /// byte array to parse.
+ /// The this came from.
+ /// Data for the mipmap levels.
+ /// was null.
+ public Texture(byte[] data, ILump parent, byte[][] mipmaps) {
if (data == null) {
throw new ArgumentNullException();
}
Data = data;
Parent = parent;
+ _mipmaps = mipmaps;
}
///
@@ -632,6 +649,7 @@ namespace LibBSP {
if (source.Parent != null && source.Parent.Bsp != null && source.Parent.Bsp.version == parent.Bsp.version && source.LumpVersion == parent.LumpInfo.version) {
Data = new byte[source.Data.Length];
Array.Copy(source.Data, Data, source.Data.Length);
+ _mipmaps = source.Mipmaps;
return;
} else {
Data = new byte[GetStructLength(parent.Bsp.version, parent.LumpInfo.version)];
@@ -644,17 +662,17 @@ namespace LibBSP {
}
}
+ _mipmaps = source.Mipmaps;
Name = source.Name;
Mask = source.Mask;
Flags = source.Flags;
Contents = source.Contents;
TextureInfo = source.TextureInfo;
- Width = source.Width;
- Height = source.Height;
- OffsetFull = source.OffsetFull;
- OffsetHalf = source.OffsetHalf;
- OffsetQuarter = source.OffsetQuarter;
- OffsetEighth = source.OffsetEighth;
+ Dimensions = source.Dimensions;
+ MipmapFullOffset = source.MipmapFullOffset;
+ MipmapHalfOffset = source.MipmapHalfOffset;
+ MipmapQuarterOffset = source.MipmapQuarterOffset;
+ MipmapEighthOffset = source.MipmapEighthOffset;
Value = source.Value;
Next = source.Next;
Subdivisions = source.Subdivisions;