mirror of
https://github.com/celisej567/LibBSP.git
synced 2026-09-23 20:08:40 +03:00
Refactors to reuse some commonly used code. This changes a lot.
Refactor everything to use a base ILump interface, and a Lump class implementing it to use in place of regular List. Refactor lump structures to use an ILumpObject interface. Eventually Lump<T> will enforce T is ILumpObject, there are some other things to do first. Use Path class to simplify some code in BSP.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LibBSP {
|
||||
#if UNITY
|
||||
@@ -15,17 +16,47 @@ namespace LibBSP {
|
||||
/// <summary>
|
||||
/// Holds the data for a patch in a CoD BSP.
|
||||
/// </summary>
|
||||
public struct Patch {
|
||||
public struct Patch : ILumpObject {
|
||||
|
||||
public byte[] data;
|
||||
public MapType type;
|
||||
public int version;
|
||||
/// <summary>
|
||||
/// The <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public ILump Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Array of <c>byte</c>s used as the data source for this <see cref="ILumpObject"/>.
|
||||
/// </summary>
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibBSP.MapType"/> to use to interpret <see cref="Data"/>.
|
||||
/// </summary>
|
||||
public MapType MapType {
|
||||
get {
|
||||
if (Parent == null || Parent.Bsp == null) {
|
||||
return MapType.Undefined;
|
||||
}
|
||||
return Parent.Bsp.version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The version number of the <see cref="ILump"/> this <see cref="ILumpObject"/> came from.
|
||||
/// </summary>
|
||||
public int LumpVersion {
|
||||
get {
|
||||
if (Parent == null) {
|
||||
return 0;
|
||||
}
|
||||
return Parent.LumpInfo.version;
|
||||
}
|
||||
}
|
||||
|
||||
public short shader {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
return BitConverter.ToInt16(data, 0);
|
||||
return BitConverter.ToInt16(Data, 0);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -34,9 +65,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
bytes.CopyTo(data, 0);
|
||||
bytes.CopyTo(Data, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -45,9 +76,9 @@ namespace LibBSP {
|
||||
|
||||
public short patchType {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
return BitConverter.ToInt16(data, 2);
|
||||
return BitConverter.ToInt16(Data, 2);
|
||||
}
|
||||
default: {
|
||||
return -1;
|
||||
@@ -56,9 +87,9 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
bytes.CopyTo(data, 2);
|
||||
bytes.CopyTo(Data, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -67,10 +98,10 @@ namespace LibBSP {
|
||||
|
||||
public Vector2d dimensions {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return new Vector2d(BitConverter.ToInt16(data, 4), BitConverter.ToInt16(data, 6));
|
||||
return new Vector2d(BitConverter.ToInt16(Data, 4), BitConverter.ToInt16(Data, 6));
|
||||
} else {
|
||||
return new Vector2d(float.NaN, float.NaN);
|
||||
}
|
||||
@@ -81,11 +112,11 @@ namespace LibBSP {
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
BitConverter.GetBytes((short)value.x).CopyTo(data, 4);
|
||||
BitConverter.GetBytes((short)value.y).CopyTo(data, 6);
|
||||
BitConverter.GetBytes((short)value.x).CopyTo(Data, 4);
|
||||
BitConverter.GetBytes((short)value.y).CopyTo(Data, 6);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -95,10 +126,10 @@ namespace LibBSP {
|
||||
|
||||
public int flags {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -110,10 +141,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -123,12 +154,12 @@ namespace LibBSP {
|
||||
|
||||
[Index("patchVerts")] public int firstVertex {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
} else if (patchType == 1) {
|
||||
return BitConverter.ToInt32(data, 8);
|
||||
return BitConverter.ToInt32(Data, 8);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -140,12 +171,12 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
} else if (patchType == 1) {
|
||||
bytes.CopyTo(data, 8);
|
||||
bytes.CopyTo(Data, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -155,12 +186,12 @@ namespace LibBSP {
|
||||
|
||||
[Count("patchVerts")] public int numVertices {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 0) {
|
||||
return BitConverter.ToInt16(data, 4) * BitConverter.ToInt16(data, 6);
|
||||
return BitConverter.ToInt16(Data, 4) * BitConverter.ToInt16(Data, 6);
|
||||
} else if (patchType == 1) {
|
||||
return BitConverter.ToInt16(data, 4);
|
||||
return BitConverter.ToInt16(Data, 4);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -172,11 +203,11 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
data[4] = bytes[0];
|
||||
data[5] = bytes[1];
|
||||
Data[4] = bytes[0];
|
||||
Data[5] = bytes[1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -186,10 +217,10 @@ namespace LibBSP {
|
||||
|
||||
[Count("patchIndices")] public int numIndices {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
return BitConverter.ToInt16(data, 6);
|
||||
return BitConverter.ToInt16(Data, 6);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -201,11 +232,11 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
data[6] = bytes[0];
|
||||
data[7] = bytes[1];
|
||||
Data[6] = bytes[0];
|
||||
Data[7] = bytes[1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -215,10 +246,10 @@ namespace LibBSP {
|
||||
|
||||
[Index("patchIndices")] public int firstIndex {
|
||||
get {
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
return BitConverter.ToInt32(data, 12);
|
||||
return BitConverter.ToInt32(Data, 12);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -230,10 +261,10 @@ namespace LibBSP {
|
||||
}
|
||||
set {
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
switch (type) {
|
||||
switch (MapType) {
|
||||
case MapType.CoD: {
|
||||
if (patchType == 1) {
|
||||
bytes.CopyTo(data, 12);
|
||||
bytes.CopyTo(Data, 12);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -245,49 +276,49 @@ namespace LibBSP {
|
||||
/// Creates a new <see cref="Patch"/> object from a <c>byte</c> array.
|
||||
/// </summary>
|
||||
/// <param name="data"><c>byte</c> array to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <param name="parent">The <see cref="ILump"/> this <see cref="Patch"/> came from.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
|
||||
public Patch(byte[] data, MapType type, int version = 0) : this() {
|
||||
public Patch(byte[] data, ILump parent = null) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
|
||||
Data = data;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory method to parse a <c>byte</c> array into a <c>List</c> of <see cref="Patch"/> objects.
|
||||
/// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Patch}"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">The data to parse.</param>
|
||||
/// <param name="type">The map type.</param>
|
||||
/// <param name="version">The version of this lump.</param>
|
||||
/// <returns>A <c>List</c> of <see cref="Patch"/> objects.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">This structure is not implemented for the given maptype.</exception>
|
||||
public static List<Patch> LumpFactory(byte[] data, MapType type, int version = 0) {
|
||||
/// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
|
||||
/// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
|
||||
/// <returns>A <see cref="Lump{Patch}"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
|
||||
public static Lump<Patch> LumpFactory(byte[] data, BSP bsp, LumpInfo lumpInfo) {
|
||||
if (data == null) {
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
int structLength = 0;
|
||||
switch (type) {
|
||||
|
||||
return new Lump<Patch>(data, GetStructLength(bsp.version, lumpInfo.version), bsp, lumpInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of this struct's data for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.
|
||||
/// </summary>
|
||||
/// <param name="mapType">The <see cref="LibBSP.MapType"/> of the BSP.</param>
|
||||
/// <param name="lumpVersion">The version number for the lump.</param>
|
||||
/// <returns>The length, in <c>byte</c>s, of this struct.</returns>
|
||||
/// <exception cref="ArgumentException">This struct is not valid or is not implemented for the given <paramref name="mapType"/> and <paramref name="lumpVersion"/>.</exception>
|
||||
public static int GetStructLength(MapType mapType, int lumpVersion = 0) {
|
||||
switch (mapType) {
|
||||
case MapType.CoD: {
|
||||
structLength = 16;
|
||||
break;
|
||||
return 16;
|
||||
}
|
||||
default: {
|
||||
throw new ArgumentException("Map type " + type + " isn't supported by the Patch lump factory.");
|
||||
throw new ArgumentException("Lump object " + MethodBase.GetCurrentMethod().DeclaringType.Name + " does not exist in map type " + mapType + " or has not been implemented.");
|
||||
}
|
||||
}
|
||||
int numObjects = data.Length / structLength;
|
||||
List<Patch> lump = new List<Patch>(numObjects);
|
||||
for (int i = 0; i < numObjects; ++i) {
|
||||
byte[] bytes = new byte[structLength];
|
||||
Array.Copy(data, (i * structLength), bytes, 0, structLength);
|
||||
lump.Add(new Patch(bytes, type, version));
|
||||
}
|
||||
return lump;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user