Browse Source

Made an attempt to add some structure to the BSP file processing

master
Nico de Poel 3 years ago
parent
commit
fac8e40425
  1. 128
      main.cpp
  2. 2
      ps1bsp.h

128
main.cpp

@ -4,46 +4,32 @@
#include "bsp.h" #include "bsp.h"
#include "rectpack/finders_interface.h" #include "rectpack/finders_interface.h"
int main(int argc, char** argv)
{
FILE* f;
dheader_t header;
char path[_MAX_PATH];
fopen_s(&f, argv[1], "rb");
if (f == NULL)
return 1;
fread(&header, sizeof(dheader_t), 1, f);
static char path[_MAX_PATH];
printf("Header model version: %d\n", header.version);
// Test reading the entity string data
fseek(f, header.entities.offset, SEEK_SET);
int process_entities(dheader_t* header, FILE* f)
{
fseek(f, header->entities.offset, SEEK_SET);
char* entities = (char*)malloc((header.entities.size + 1) * sizeof(char));
char* entities = (char*)malloc((header->entities.size + 1) * sizeof(char));
if (entities == NULL) if (entities == NULL)
{
fclose(f);
return 1;
}
return 0;
memset(entities, 0, (header.entities.size + 1) * sizeof(char));
fread(entities, sizeof(char), header.entities.size, f);
memset(entities, 0, (header->entities.size + 1) * sizeof(char));
fread(entities, sizeof(char), header->entities.size, f);
printf("Entities list:\n%s\n", entities); printf("Entities list:\n%s\n", entities);
free(entities); free(entities);
return 1;
}
// Test exporting texture data
fseek(f, header.miptex.offset, SEEK_SET);
int process_textures(const char* bspname, dheader_t* header, FILE* f)
{
fseek(f, header->miptex.offset, SEEK_SET);
mipheader_t mipheader; mipheader_t mipheader;
fread(&mipheader.numtex, sizeof(long), 1, f); fread(&mipheader.numtex, sizeof(long), 1, f);
mipheader.offset = (long*)malloc(mipheader.numtex * sizeof(long)); mipheader.offset = (long*)malloc(mipheader.numtex * sizeof(long));
if (mipheader.offset == NULL) if (mipheader.offset == NULL)
{
fclose(f);
return 1;
}
return 0;
fread(mipheader.offset, sizeof(long), mipheader.numtex, f); fread(mipheader.offset, sizeof(long), mipheader.numtex, f);
@ -58,7 +44,7 @@ int main(int argc, char** argv)
return rectpack2D::callback_result::ABORT_PACKING; return rectpack2D::callback_result::ABORT_PACKING;
}; };
const auto max_side = 512; // Max height of PS1 VRAM. 8-bit textures take up half the horizontal space so this is 256x512 in practice, or a quarter of the PS1's VRAM allocation.
const auto max_side = 512; // Max height of PS1 VRAM. 8-bit textures take up half the horizontal space so this is 512x256 in practice, or a quarter of the PS1's VRAM allocation.
const auto discard_step = -4; const auto discard_step = -4;
std::vector<rect_type> rectangles; std::vector<rect_type> rectangles;
@ -68,7 +54,7 @@ int main(int argc, char** argv)
// Try some texture packing and see if we fit inside the PS1's VRAM // Try some texture packing and see if we fit inside the PS1's VRAM
for (int texNum = 0; texNum < mipheader.numtex; ++texNum) for (int texNum = 0; texNum < mipheader.numtex; ++texNum)
{ {
unsigned long miptexOffset = header.miptex.offset + mipheader.offset[texNum];
unsigned long miptexOffset = header->miptex.offset + mipheader.offset[texNum];
fseek(f, miptexOffset, SEEK_SET); fseek(f, miptexOffset, SEEK_SET);
fread(&miptex, sizeof(miptex_t), 1, f); fread(&miptex, sizeof(miptex_t), 1, f);
@ -97,12 +83,15 @@ int main(int argc, char** argv)
printf("%d textures. Packed texture atlas size: %d x %d\n", mipheader.numtex, result_size.w, result_size.h); printf("%d textures. Packed texture atlas size: %d x %d\n", mipheader.numtex, result_size.w, result_size.h);
unsigned char* atlas = (unsigned char*)malloc(result_size.w * result_size.h * sizeof(unsigned char)); unsigned char* atlas = (unsigned char*)malloc(result_size.w * result_size.h * sizeof(unsigned char));
if (atlas == NULL)
return 0;
memset(atlas, 0, result_size.w * result_size.h * sizeof(unsigned char)); memset(atlas, 0, result_size.w * result_size.h * sizeof(unsigned char));
// Try to construct the texture atlas, see what we get // Try to construct the texture atlas, see what we get
for (int texNum = 0; texNum < mipheader.numtex; ++texNum) for (int texNum = 0; texNum < mipheader.numtex; ++texNum)
{ {
unsigned long miptexOffset = header.miptex.offset + mipheader.offset[texNum];
unsigned long miptexOffset = header->miptex.offset + mipheader.offset[texNum];
fseek(f, miptexOffset, SEEK_SET); fseek(f, miptexOffset, SEEK_SET);
fread(&miptex, sizeof(miptex_t), 1, f); fread(&miptex, sizeof(miptex_t), 1, f);
@ -120,10 +109,13 @@ int main(int argc, char** argv)
fread(texBytes, sizeof(unsigned char), numBytes, f); fread(texBytes, sizeof(unsigned char), numBytes, f);
FILE* fout; FILE* fout;
sprintf_s(path, _MAX_PATH, "textures/%s-mip%d-%dx%d.raw", outName, mipLevel, miptex.width >> mipLevel, miptex.height >> mipLevel);
sprintf_s(path, _MAX_PATH, "textures/%s-%s-mip%d-%dx%d.raw", bspname, outName, mipLevel, miptex.width >> mipLevel, miptex.height >> mipLevel);
fopen_s(&fout, path, "wb"); fopen_s(&fout, path, "wb");
fwrite(texBytes, sizeof(unsigned char), numBytes, fout);
fclose(fout);
if (fout != NULL)
{
fwrite(texBytes, sizeof(unsigned char), numBytes, fout);
fclose(fout);
}
const auto& rectangle = rectangles[texNum]; const auto& rectangle = rectangles[texNum];
if (miptex.width >> mipLevel == rectangle.w) // This is the mip level we've previously decided we want for our PS1 atlas if (miptex.width >> mipLevel == rectangle.w) // This is the mip level we've previously decided we want for our PS1 atlas
@ -140,19 +132,29 @@ int main(int argc, char** argv)
} }
FILE* fatlas; FILE* fatlas;
sprintf_s(path, _MAX_PATH, "atlas-%dx%d.raw", result_size.w, result_size.h);
sprintf_s(path, _MAX_PATH, "%s-atlas-%dx%d.raw", bspname, result_size.w, result_size.h);
fopen_s(&fatlas, path, "wb"); fopen_s(&fatlas, path, "wb");
fwrite(atlas, sizeof(unsigned char), result_size.w * result_size.h, fatlas);
fclose(fatlas);
if (fatlas != NULL)
{
fwrite(atlas, sizeof(unsigned char), result_size.w * result_size.h, fatlas);
fclose(fatlas);
}
free(atlas); free(atlas);
free(mipheader.offset); free(mipheader.offset);
return 1;
}
// Inspect vertex data
int numVertices = header.vertices.size / sizeof(vertex_t);
int numFaces = header.faces.size / sizeof(face_t);
fseek(f, header.vertices.offset, SEEK_SET);
vertex_t* vertices = (vertex_t*)malloc(header.vertices.size);
int process_vertices(dheader_t* header, FILE* f)
{
int numVertices = header->vertices.size / sizeof(vertex_t);
int numFaces = header->faces.size / sizeof(face_t);
vertex_t* vertices = (vertex_t*)malloc(header->vertices.size);
if (vertices == NULL)
return 0;
fseek(f, header->vertices.offset, SEEK_SET);
fread(vertices, sizeof(vertex_t), numVertices, f); fread(vertices, sizeof(vertex_t), numVertices, f);
vec3_t min = { FLT_MAX, FLT_MAX, FLT_MAX }, max = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; vec3_t min = { FLT_MAX, FLT_MAX, FLT_MAX }, max = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
@ -173,8 +175,48 @@ int main(int argc, char** argv)
int fixedMin[3] = { (int)(min.x * fixedScale), (int)(min.y * fixedScale), (int)(min.z * fixedScale) }; int fixedMin[3] = { (int)(min.x * fixedScale), (int)(min.y * fixedScale), (int)(min.z * fixedScale) };
int fixedMax[3] = { (int)(max.x * fixedScale), (int)(max.y * fixedScale), (int)(max.z * fixedScale) }; int fixedMax[3] = { (int)(max.x * fixedScale), (int)(max.y * fixedScale), (int)(max.z * fixedScale) };
printf("Fixed point min = (%d, %d, %d), max = (%d, %d, %d)\n", fixedMin[0], fixedMin[1], fixedMin[2], fixedMax[0], fixedMax[1], fixedMax[2]); printf("Fixed point min = (%d, %d, %d), max = (%d, %d, %d)\n", fixedMin[0], fixedMin[1], fixedMin[2], fixedMax[0], fixedMax[1], fixedMax[2]);
return 1;
}
int process_bsp(const char* bspname)
{
FILE* f;
dheader_t header;
sprintf_s(path, _MAX_PATH, "%s.bsp", bspname);
fopen_s(&f, path, "rb");
if (f == NULL)
return 0;
fread(&header, sizeof(dheader_t), 1, f);
printf("Header model version: %d\n", header.version);
// Test reading the entity string data
if (!process_entities(&header, f))
{
fclose(f);
return 0;
}
// Test exporting texture data
if (!process_textures(bspname, &header, f))
{
fclose(f);
return 0;
}
// Inspect vertex data
if (!process_vertices(&header, f))
{
fclose(f);
return 0;
}
fclose(f); fclose(f);
return 1;
}
return 0;
int main(int argc, char** argv)
{
return !process_bsp(argv[1]);
} }

2
ps1bsp.h

@ -44,7 +44,7 @@ typedef struct
typedef struct typedef struct
{ {
unsigned char length;
unsigned short length;
char message[]; char message[];
} ps1bsp_message_t; } ps1bsp_message_t;

Loading…
Cancel
Save