Tools for preprocessing data files from Quake to make them suitable for use on PS1 hardware
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.

129 lines
4.1 KiB

#ifndef __PS1BSP_H__
#define __PS1BSP_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
Probable rendering process:
- Determine visible leaves based on PVS and frustum culling, the usual.
- Chain together faces/polygons to be drawn. Possibly grouped by texture ID?
Texture chaining might improve performance by making better use of texture cache, but we'll still be separating polygons based on depth anyway, so the advantage is questionable.
Texture chaining should probably be the last optimization we try.
- Tessellate polygons close to the camera by recursively cutting edges in two, up to X times based on camera distance/screen size. Possibly GTE can aid with averaging coordinates? => look at GPF/GPL (general purpose interpolation)
- Collect all vertices that need to be transformed, put them through GTE, update lighting values if needed, and cache the results.
(It may not be worth it to collect and precalculate vertices, as keeping track of all the administration also comes at a considerable cost.)
- Draw all the (tessellated) polygons using the precalculated vertex positions. Use GTE to calculate average depth and order polygons.
Note: we may not have to calculate average depth for BSP polygons, as the leafs already provide an ordering, and leafs are convex so there is no need to sort the polygons within.
We do however need some kind of depth value per leaf to insert alias models at the correct positions in the ordering table.
*/
typedef struct
{
unsigned int offset;
unsigned int size;
} ps1bsp_dentry_t;
typedef struct
{
u_short version;
ps1bsp_dentry_t vertices;
ps1bsp_dentry_t faces;
ps1bsp_dentry_t faceVertices;
ps1bsp_dentry_t planes;
ps1bsp_dentry_t nodes;
ps1bsp_dentry_t leaves;
ps1bsp_dentry_t leafFaces;
ps1bsp_dentry_t visData;
} ps1bsp_header_t;
typedef struct
{
unsigned char w, h; // These may be necessary for scaling UVs, especially since we use a mix of mip0 and mip1 textures
int tpage; // Texture page in PS1 VRAM (precalculated when generating the texture atlas)
short uoffs, voffs; // Texture coordinate offset within the texture page
unsigned short nextframe; // If non-zero, the texture is animated and this points to the next texture in the sequence
} ps1bsp_texture_t;
// This matches the SVECTOR data type, using the extra padding to store vertex color data.
// The full range and precision required cannot be stored in just shorts, so we make use of a floating origin stored in the BSP leafs.
// With this the higher-order bits of each vertex position are calculated into the model-view matrix, giving good precision for polygons near the camera.
typedef struct
{
short x;
short y;
short z;
unsigned char baseLight, finalLight; // Used for gouraud shading based on static lightmap data
// Sampled color value from the face texture, for untextured gouraud shaded drawing
unsigned char a : 1; // 0 = opaque, 1 = semi-transparent
unsigned char r : 5;
unsigned char g : 5;
unsigned char b : 5;
} ps1bsp_vertex_t;
typedef struct
{
unsigned short index;
unsigned short light;
} ps1bsp_facevertex_t;
typedef struct
{
unsigned short firstFaceVertex;
unsigned short numFaceVertices;
u_long drawFrame; // Which frame was this face last drawn on? Used to check if this face should be drawn.
} ps1bsp_face_t;
typedef struct
{
SVECTOR normal;
int dist;
} ps1bsp_plane_t;
typedef struct
{
int planeId;
short front;
short back;
// TODO: add bounding box for frustum culling
u_short firstFace;
u_short numFaces;
} ps1bsp_node_t;
typedef struct
{
int type;
int vislist;
// TODO: add bounding box for frustum culing
u_short firstLeafFace;
u_short numLeafFaces;
} ps1bsp_leaf_t;
// Pre-parsed and encoded entity data (this runs the risk of becoming too bloated)
typedef struct
{
unsigned short classtype; // Hash of the original classname
short angle[3]; // Can store both mangle (all axes) and just angle (Z-axis rotation only)
int origin[3]; // In 12-bit fixed point coordinates
unsigned int spawnflags;
unsigned short messageId; // Index into a pool of pre-defined messages
} ps1bsp_entity_t;
typedef struct
{
unsigned short length;
char message[];
} ps1bsp_message_t;
#ifdef __cplusplus
}
#endif
#endif // __PS1BSP_H__