diff --git a/PS1BSP.vcxproj b/PS1BSP.vcxproj
index daae418..0e820f8 100644
--- a/PS1BSP.vcxproj
+++ b/PS1BSP.vcxproj
@@ -146,6 +146,7 @@
+
diff --git a/PS1BSP.vcxproj.filters b/PS1BSP.vcxproj.filters
index 613a5ff..534b521 100644
--- a/PS1BSP.vcxproj.filters
+++ b/PS1BSP.vcxproj.filters
@@ -47,5 +47,8 @@
Header Files\rectpack2D
+
+ Header Files
+
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
index d48f8cf..c1168d3 100644
--- a/main.cpp
+++ b/main.cpp
@@ -5,6 +5,7 @@
#include
#include "bsp.h"
#include "rectpack/finders_interface.h"
+#include "ps1types.h"
#include "ps1bsp.h"
static char path[_MAX_PATH];
@@ -262,6 +263,13 @@ static void export_lightmap(const world_t* world, const face_t* face, const Boun
fclose(flm);
}
+template size_t writeMapData(const std::vector& data, ps1bsp_dentry_t& dentry, FILE* f)
+{
+ dentry.offset = (unsigned int)ftell(f);
+ dentry.size = sizeof(TData) * data.size();
+ return fwrite(data.data(), sizeof(TData), data.size(), f);
+}
+
int process_faces(const world_t* world)
{
// Write some data to a file
@@ -271,22 +279,13 @@ int process_faces(const world_t* world)
return 0;
ps1bsp_header_t outHeader = { 0 }; // Write an empty placeholder header first
+ outHeader.version = 1;
fwrite(&outHeader, sizeof(ps1bsp_header_t), 1, fbsp);
- // TODO: convert vertices and group them by material properties (texture, lightmap) and floating origin zone (based on leaf data), duplicate where necessary
- short zone[3];
- for (int leafIdx = 0; leafIdx < world->numLeaves; ++leafIdx)
- {
- dleaf_t* leaf = &world->leaves[leafIdx];
- leaf_zone(leaf, zone);
- //printf("Leaf %d zone (%d, %d, %d) %d face(s)\n", leafIdx, zone[0], zone[1], zone[2], leaf->lface_num);
- }
-
// Write vertex data to a file (no vertex splitting yet)
std::vector outVertices;
for (unsigned short i = 0; i < world->numVertices; ++i)
{
- // TODO: we should respect the ordering from vertexRef->index here but meh, problem for later
vertex_t* inVertex = &world->vertices[i];
ps1bsp_vertex_t outVertex = { 0 };
@@ -297,6 +296,12 @@ int process_faces(const world_t* world)
outVertex.y = (short)(inVertex->Y * 4);
outVertex.z = (short)(inVertex->Z * 4);
}
+ else
+ {
+ printf("Error: vertices found outside of acceptable range: (%f, %f, %f)\n", inVertex->X, inVertex->Y, inVertex->Z);
+ fclose(fbsp);
+ return 0;
+ }
outVertices.push_back(outVertex);
}
@@ -368,22 +373,17 @@ int process_faces(const world_t* world)
(*iter).r = 0;
}
- // Write triangle and face data to file
- fwrite(outVertices.data(), sizeof(ps1bsp_vertex_t), outVertices.size(), fbsp);
- fwrite(outFaceVertices.data(), sizeof(ps1bsp_facevertex_t), outFaceVertices.size(), fbsp);
- fwrite(outFaces.data(), sizeof(ps1bsp_face_t), outFaces.size(), fbsp);
-
- // Update header information
- outHeader.numVertices = (unsigned short)outVertices.size();
- outHeader.numFaceVertices = (unsigned short)outFaceVertices.size();
- outHeader.numFaces = (unsigned short)outFaces.size();
+ // Write collected data to file and update header info
+ writeMapData(outVertices, outHeader.vertices, fbsp);
+ writeMapData(outFaces, outHeader.faces, fbsp);
+ writeMapData(outFaceVertices, outHeader.faceVertices, fbsp);
// Write final header
fseek(fbsp, 0, SEEK_SET);
fwrite(&outHeader, sizeof(ps1bsp_header_t), 1, fbsp);
fclose(fbsp);
- printf("PS1BSP: wrote %d vertices, %d indices, %d faces\n", outHeader.numVertices, outHeader.numFaceVertices, outHeader.numFaces);
+ printf("PS1BSP: wrote %d vertices, %d indices, %d faces\n", outVertices.size(), outFaceVertices.size(), outFaces.size());
return 1;
}
diff --git a/ps1bsp.h b/ps1bsp.h
index 7154fc8..796e297 100644
--- a/ps1bsp.h
+++ b/ps1bsp.h
@@ -18,12 +18,23 @@ Probable rendering process:
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
{
- unsigned short numVertices;
- unsigned short numFaceVertices;
- unsigned short numFaces;
+ 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 leafs;
+ ps1bsp_dentry_t leafFaces;
} ps1bsp_header_t;
typedef struct
@@ -63,6 +74,32 @@ typedef struct
unsigned char numFaceVertices;
} ps1bsp_face_t;
+typedef struct
+{
+ SVECTOR normal;
+ u_short dist;
+} ps1bsp_plane_t;
+
+typedef struct
+{
+ u_int planeId;
+ u_short front;
+ u_short back;
+ // TODO: add bounding box for frustum culling
+ // TODO: not sure if face list is needed here
+} 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
{
@@ -79,11 +116,6 @@ typedef struct
char message[];
} ps1bsp_message_t;
-typedef struct
-{
- // TODO: add floating origin position, so face vertices can be moved relative to the camera position
-} ps1bsp_leaf_t;
-
#ifdef __cplusplus
}
#endif
diff --git a/ps1types.h b/ps1types.h
new file mode 100644
index 0000000..570ebdf
--- /dev/null
+++ b/ps1types.h
@@ -0,0 +1,28 @@
+#pragma once
+#include
+
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+typedef struct _MATRIX {
+ int16_t m[3][3];
+ int32_t t[3];
+} MATRIX;
+
+typedef struct _VECTOR {
+ int32_t vx, vy, vz;
+} VECTOR;
+
+typedef struct _SVECTOR {
+ int16_t vx, vy, vz, pad;
+} SVECTOR;
+
+typedef struct _CVECTOR {
+ uint8_t r, g, b, cd;
+} CVECTOR;
+
+typedef struct _DVECTOR {
+ int16_t vx, vy;
+} DVECTOR;