You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
10 KiB
378 lines
10 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of model_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0, CharSet = CharSet.Ansi)]
|
|
public class QModel
|
|
{
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = QConstants.MaxQPath)] public string name;
|
|
public uint pathId;
|
|
public bool needLoad;
|
|
|
|
public QModelType type;
|
|
public int numFrames;
|
|
public QSyncType syncType;
|
|
|
|
public int flags;
|
|
|
|
// Volume occupied by the model graphics
|
|
public QVec3 mins, maxs;
|
|
public QVec3 ymins, ymaxs;
|
|
public QVec3 rmins, rmaxs;
|
|
|
|
// Solid volume for clipping
|
|
public bool clipBox;
|
|
public QVec3 clipMins, clipMaxs;
|
|
|
|
// Brush model
|
|
public int firstModelSurface, numModelSurfaces;
|
|
|
|
public int numSubModels;
|
|
public IntPtr subModels; // Array of dmodel_t
|
|
public QSubModel[] SubModels => subModels.ToStructArray<QSubModel>(numSubModels);
|
|
|
|
public int numPlanes;
|
|
public IntPtr planes; // Array of mplane_t
|
|
|
|
public int numLeafs;
|
|
public IntPtr leafs; // Array of mleaf_t
|
|
|
|
public int numVertices;
|
|
public IntPtr vertices; // Array of mvertex_t (which is just a single vec3_t)
|
|
|
|
public int numEdges;
|
|
public IntPtr edges; // Array of medge_t
|
|
|
|
public int numNodes;
|
|
public IntPtr nodes; // Array of mnode_t
|
|
|
|
public int numTexInfo;
|
|
public IntPtr texInfo; // Array of mtexinfo_t
|
|
|
|
public int numSurfaces;
|
|
public IntPtr surfaces; // Array of msurface_t
|
|
public QSurface[] Surfaces => surfaces.ToStructArray<QSurface>(numSurfaces);
|
|
|
|
public int numSurfEdges;
|
|
public IntPtr surfEdges; // Array of int
|
|
|
|
public int numClipNodes;
|
|
public IntPtr clipNodes; // Array of dclipnode_t
|
|
|
|
public int numMarkSurfaces;
|
|
public IntPtr markSurfaces; // Array of msurface_t pointers
|
|
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxMapHulls)] public QHull[] hulls;
|
|
|
|
public int numTextures;
|
|
public IntPtr textures; // Array of texture_t pointers
|
|
|
|
// Rest of the fields are unused
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of aliashdr_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public class QAliasHeader
|
|
{
|
|
public int ident;
|
|
public int version;
|
|
public QVec3 scale;
|
|
public QVec3 scaleOrigin;
|
|
public float boundingRadius;
|
|
public QVec3 eyePosition;
|
|
public int numSkins;
|
|
public int skinWidth;
|
|
public int skinHeight;
|
|
public int numVerts;
|
|
public int numTriangles;
|
|
public int numFrames;
|
|
public QSyncType syncType;
|
|
public int flags;
|
|
public float size;
|
|
|
|
// VBO data from QuakeSpasm; unused by UniQuake
|
|
public int numVertsVbo;
|
|
public IntPtr meshDesc;
|
|
public int numIndexes;
|
|
public IntPtr indexes;
|
|
public IntPtr vertexes;
|
|
|
|
public int numPoses;
|
|
public int poseVerts;
|
|
public int poseData;
|
|
public int commands;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxSkins * 4)] public IntPtr[] glTextures;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxSkins * 4)] public IntPtr[] fbTextures;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxSkins)] public int[] texels;
|
|
|
|
// Actually variable sized, but we receive an additional pointer to the first element so we can manually marshal the entire array
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public QAliasFrameDesc[] frames;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of modtype_t
|
|
/// </summary>
|
|
public enum QModelType
|
|
{
|
|
Brush,
|
|
Sprite,
|
|
Alias,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of synctype_t
|
|
/// </summary>
|
|
public enum QSyncType
|
|
{
|
|
Sync = 0,
|
|
Rand
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of aliasframetype_t
|
|
/// </summary>
|
|
public enum QAliasFrameType
|
|
{
|
|
Single = 0,
|
|
Group,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of aliasskintype_t
|
|
/// </summary>
|
|
public enum QAliasSkinType
|
|
{
|
|
Single = 0,
|
|
Group,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of hull_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QHull
|
|
{
|
|
public IntPtr clipNodes; // Array of dclipnode_t
|
|
public IntPtr planes; // Array of mplane_t
|
|
public int firstClipNode;
|
|
public int lastClipNode;
|
|
public QVec3 clipMins;
|
|
public QVec3 clipMaxs;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of maliasframedesc_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0, CharSet = CharSet.Ansi)]
|
|
public struct QAliasFrameDesc
|
|
{
|
|
public int firstPose;
|
|
public int numPoses;
|
|
public float interval;
|
|
public QTriVertex bboxMin;
|
|
public QTriVertex bboxMax;
|
|
public int frame;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string name;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of trivertx_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QTriVertex
|
|
{
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] v;
|
|
public byte lightNormalIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of mtriangle_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QTriangle
|
|
{
|
|
public int facesFront;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public int[] vertIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of stvert_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QSTVert
|
|
{
|
|
public int onSeam;
|
|
public int s, t;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of dmodel_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QSubModel
|
|
{
|
|
public QVec3 mins, maxs;
|
|
public QVec3 origin;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxMapHulls)] public int[] headNode;
|
|
public int visLeafs;
|
|
public int firstFace, numFaces;
|
|
|
|
public QNode GetHeadNode(QModel model)
|
|
{
|
|
IntPtr nodePtr = IntPtr.Add(model.nodes, headNode[0] * Marshal.SizeOf<QNode>());
|
|
return Marshal.PtrToStructure<QNode>(nodePtr);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of mnode_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QNode
|
|
{
|
|
// Common with leaf
|
|
public int contents; // 0 for nodes, negative for leafs
|
|
public int visFrame;
|
|
public QVec3 mins, maxs;
|
|
public IntPtr parent; // Pointer to mnode_t
|
|
|
|
// Node specific
|
|
public IntPtr plane; // Pointer to mplane_t
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public IntPtr[] children; // Array of pointers to mnode_t
|
|
|
|
public uint firstSurface;
|
|
public uint numSurfaces;
|
|
|
|
public QNode[] Children => new[]
|
|
{
|
|
Marshal.PtrToStructure<QNode>(children[0]),
|
|
Marshal.PtrToStructure<QNode>(children[1]),
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of mleaf_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QLeaf
|
|
{
|
|
// Common with node
|
|
public int contents; // 0 for nodes, negative for leafs
|
|
public int visFrame;
|
|
public QVec3 mins, maxs;
|
|
public IntPtr parent; // Pointer to mnode_t
|
|
|
|
// Leaf-specific data is unused
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of msurface_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QSurface
|
|
{
|
|
public int visFrame;
|
|
public bool culled;
|
|
public QVec3 mins, maxs;
|
|
|
|
public IntPtr plane; // Pointer to mplane_t
|
|
public QSurfaceFlags flags;
|
|
|
|
public int firstEdge;
|
|
public int numEdges;
|
|
|
|
public QVec2s textureMins;
|
|
public QVec2s extents;
|
|
|
|
public QVec2i lightST;
|
|
|
|
public IntPtr polys; // Pointer to glpoly_t
|
|
public IntPtr textureChain; // Pointer to msurface_t
|
|
|
|
public IntPtr texInfo; // Pointer to mtexinfo_t
|
|
|
|
public int vboFirstVert; // QuakeSpasm VBO stuff
|
|
|
|
public int dLightFrame;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (QConstants.MaxDLights + 31) >> 5)] public uint[] dLightBits;
|
|
|
|
public int lightmapTextureNum;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxLightmaps)] public byte[] styles;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = QConstants.MaxLightmaps)] public int[] cachedLight;
|
|
public bool cachedDLight;
|
|
public IntPtr samples; // Pointer to byte
|
|
|
|
// This is safe as the Quake engine guarantees this pointer is never null (see: Mod_LoadFaces)
|
|
public QTexInfo TextureInfo => Marshal.PtrToStructure<QTexInfo>(texInfo);
|
|
|
|
public QGLPolyVert[] GetPolygon()
|
|
{
|
|
// We have to calculate the position inside the struct where the variable-sized array of vertices starts
|
|
int offset = Marshal.SizeOf<IntPtr>() * 2 + Marshal.SizeOf<int>();
|
|
QGLPoly polygon = Marshal.PtrToStructure<QGLPoly>(polys);
|
|
return IntPtr.Add(polys, offset).ToStructArray<QGLPolyVert>(polygon.numVerts);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of glpoly_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QGLPoly
|
|
{
|
|
public IntPtr next; // Pointer to glpoly_t (next in linked list)
|
|
public IntPtr chain; // Pointer to glpoly_t (start of linked list)
|
|
public int numVerts;
|
|
|
|
// No need to include this field in the struct, as we calculate its offset and marshal the data manually
|
|
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public QGLPolyVert[] verts; // Variable sized
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QGLPolyVert
|
|
{
|
|
public QVec3 position;
|
|
public QVec2 textureUV;
|
|
public QVec2 lightmapUV;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of mtexinfo_t
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential, Pack = 0)]
|
|
public struct QTexInfo
|
|
{
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 4)] public float[] vecs;
|
|
public float mipAdjust;
|
|
public IntPtr texture; // Pointer to texture_t
|
|
public int flags;
|
|
|
|
// This is safe as the Quake engine guarantees this pointer is never null (see: Mod_LoadTexinfo)
|
|
public QTexture Texture => Marshal.PtrToStructure<QTexture>(texture);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Managed equivalent of SURF_ defines
|
|
/// </summary>
|
|
[Flags]
|
|
public enum QSurfaceFlags : int
|
|
{
|
|
PlaneBack = 0x2,
|
|
DrawSky = 0x4,
|
|
DrawSprite = 0x8,
|
|
DrawTurbulence = 0x10,
|
|
DrawTiled = 0x20,
|
|
DrawBackground = 0x40,
|
|
Underwater = 0x80,
|
|
NoTexture = 0x100,
|
|
DrawFence = 0x200,
|
|
DrawLava = 0x400,
|
|
DrawSlime = 0x800,
|
|
DrawTeleporter = 0x1000,
|
|
DrawWater = 0x2000,
|
|
}
|