mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
Return to Castle Wolfenstein: Tides of War (xbox) maps decompilation
010editor templates to explore the format: Quake3Arena_BSP_Xbox_clip.bt Quake3Arena_BSP_Xbox_world.bt process: get file.cachemap unpack with cachemap_unpack.exe place clip, world files next to file.cachemap q3map2 -convert -format map -readxbox file.cachemap
This commit is contained in:
@@ -0,0 +1,367 @@
|
||||
LittleEndian();
|
||||
|
||||
// char signature[4];
|
||||
// uint32 version;
|
||||
|
||||
// typedef struct {
|
||||
// uint32 offset;
|
||||
// uint32 length;
|
||||
// } lump <read=ReadLumps>;
|
||||
|
||||
// struct {
|
||||
// lump entities;
|
||||
// lump shaders;
|
||||
// lump planes;
|
||||
// lump nodes;
|
||||
// lump leafs;
|
||||
// lump leafSurfaces;
|
||||
// lump leafBrushes;
|
||||
// lump models;
|
||||
// lump brushes;
|
||||
// lump brushSides;
|
||||
// lump drawVerts;
|
||||
// lump drawIndexes;
|
||||
// lump fogs;
|
||||
// lump surfaces;
|
||||
// lump lightmaps;
|
||||
// lump lightGrid;
|
||||
// lump visibility;
|
||||
// } lumps;
|
||||
|
||||
struct {
|
||||
char name[64];
|
||||
int datasize; // -8917903 4286049393
|
||||
int nShaders; // 67
|
||||
int offShaders; // 183238916 1
|
||||
int nBSides; // 22064
|
||||
|
||||
int offBSides; // 183243740 2
|
||||
int nPlanes; // 11400
|
||||
int offPlanes; // 183508580 3
|
||||
int nC; // 998 sz12
|
||||
|
||||
int offC; // 183736820 4
|
||||
int nLeafs; // 1042 sz32
|
||||
int offLeafs; // 183748796 5
|
||||
int nLeafBrushes;// 7094 sz4
|
||||
|
||||
int offLeafbrushes;// 183782204 6
|
||||
int nF; // 46 sz4
|
||||
int offF; // 183810584 7
|
||||
int nLeafSurfaces;// 7647 sz4
|
||||
|
||||
int offLeafSurfaces;// 183810768 8
|
||||
int nH; // 91 sz4
|
||||
int offH; // 183841356 9
|
||||
int nModels; // 43 sz56
|
||||
|
||||
int offModels; // 184050596 16
|
||||
int nBrushes; // 2437 sz44
|
||||
int offBrushes; // 183841720 10
|
||||
int nK; // 29184
|
||||
|
||||
int nL; // 456
|
||||
int nM; // 64
|
||||
int offM; // 183948992 ?vis 11
|
||||
int nN; // 1
|
||||
|
||||
int nEnts; // 42492
|
||||
int offEnts; // 183978176 12
|
||||
int nO; // 5 sz8
|
||||
int offO; // 184020668 13
|
||||
|
||||
int offP; // 184020708 14
|
||||
int nSurfaces; // 2664
|
||||
int offSurfaces;// 184020808 15 // pointer to array of pointers to cPatch_t // non-patches will be NULL
|
||||
int nR; // 1
|
||||
|
||||
int nS; // 0
|
||||
} lumps;
|
||||
|
||||
local int OFF = lumps.offShaders - 212;
|
||||
|
||||
Printf( "OFF: %d\n", OFF );
|
||||
|
||||
|
||||
FSeek( lumps.offEnts - OFF );
|
||||
|
||||
char ents[lumps.nEnts];
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
int surfaceFlags;
|
||||
int contents;
|
||||
} Shader <read=ReadShader>;
|
||||
|
||||
FSeek( lumps.offShaders - OFF );
|
||||
Shader shader[lumps.nShaders];
|
||||
|
||||
typedef struct {
|
||||
float normal[3];
|
||||
float dist;
|
||||
int idk;
|
||||
} Plane <read=ReadPlanes>;
|
||||
|
||||
FSeek( lumps.offPlanes - OFF );
|
||||
Plane planes[lumps.nPlanes];
|
||||
|
||||
// typedef struct {
|
||||
// int plane;
|
||||
// int children[2]; // Children indices. Negative numbers are leaf indices: -(leaf+1).
|
||||
// int mins[3];// Integer bounding box min coord.
|
||||
// int maxs[3];
|
||||
// } Node <read=ReadNodes>;
|
||||
|
||||
// FSeek( lumps.nodes.offset);
|
||||
// Node nodes[lumps.nodes.length / sizeof(Node)];
|
||||
|
||||
// typedef struct {
|
||||
// int cluster; // Visdata cluster index.
|
||||
// int area; // Areaportal area.
|
||||
// // int mins[3]; // Integer bounding box min coord.
|
||||
// // int maxs[3]; // Integer bounding box max coord.
|
||||
// int leafbrush; // First leafbrush for leaf.
|
||||
// int n_leafbrushes; // Number of leafbrushes for leaf.
|
||||
// int leafface; // First leafface for leaf.
|
||||
// int n_leaffaces; // Number of leaffaces for leaf.
|
||||
// int mins[1]; // Integer bounding box min coord. // unused?
|
||||
// int maxs[1]; // Integer bounding box max coord. // unused?
|
||||
// } Leaf <read=ReadLeafs>;
|
||||
|
||||
typedef struct {
|
||||
int cluster;
|
||||
int area;
|
||||
|
||||
int firstLeafBrush;
|
||||
int numLeafBrushes;
|
||||
|
||||
int firstLeafSurface;
|
||||
int numLeafSurfaces;
|
||||
|
||||
uint leafBrush;
|
||||
uint leafSurf;
|
||||
} cLeaf_t;
|
||||
|
||||
|
||||
FSeek( lumps.offLeafs - OFF );
|
||||
cLeaf_t leafs[lumps.nLeafs];
|
||||
|
||||
FSeek( lumps.offLeafbrushes - OFF );
|
||||
int leafBrushes[lumps.nLeafBrushes];
|
||||
|
||||
FSeek( lumps.offLeafSurfaces - OFF );
|
||||
int leafSurfaces[lumps.nLeafSurfaces];
|
||||
|
||||
// typedef struct {
|
||||
// float mins[3];
|
||||
// float maxs[3];
|
||||
// int face1;
|
||||
// int face_n;
|
||||
// int brush1;
|
||||
// int brush_n;
|
||||
// } Model;
|
||||
|
||||
typedef struct cmodel_s {
|
||||
float mins[3], maxs[3];
|
||||
cLeaf_t leaf; // submodels don't reference the main tree
|
||||
} cmodel_t <read=ReadModels>;
|
||||
|
||||
FSeek( lumps.offModels - OFF );
|
||||
cmodel_t models[lumps.nModels];
|
||||
|
||||
// typedef struct {
|
||||
// int brushside; // First brushside for brush.
|
||||
// int n_brushsides; // Number of brushsides for brush.
|
||||
// int texture; // Texture index.
|
||||
// } Brush <read=ReadBrushes>;
|
||||
|
||||
typedef struct {
|
||||
int shaderNum; // the shader that determined the contents
|
||||
int contents;
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
int numsides;
|
||||
uint sidesPTR;
|
||||
int checkcount; // to avoid repeated testings
|
||||
} cbrush_t;
|
||||
|
||||
FSeek( lumps.offBrushes - OFF );
|
||||
cbrush_t brushes[lumps.nBrushes];
|
||||
|
||||
{
|
||||
local uint umin = 4294967295, umax = 0;
|
||||
local int i;
|
||||
for( i = 0; i < lumps.nBrushes; ++i ){
|
||||
if( (brushes[i].sidesPTR) < umin )
|
||||
umin = (brushes[i].sidesPTR);
|
||||
if( (brushes[i].sidesPTR) > umax )
|
||||
umax = (brushes[i].sidesPTR);
|
||||
}
|
||||
Printf( "sidesPTR: min:%u max:%u diff:%u\n", umin, umax, umax - umin );
|
||||
|
||||
local int imin = 2147483647, imax = 0;
|
||||
for( i = 0; i < lumps.nLeafSurfaces; ++i ){
|
||||
if( (leafSurfaces[i]) < imin )
|
||||
imin = (leafSurfaces[i]);
|
||||
if( (leafSurfaces[i]) > imax )
|
||||
imax = (leafSurfaces[i]);
|
||||
}
|
||||
Printf( "leafSurfaces: min:%u max:%u diff:%u\n", imin, imax, imax - imin );
|
||||
|
||||
imin = 2147483647, imax = 0;
|
||||
for( i = 0; i < lumps.nLeafBrushes; ++i ){
|
||||
if( (leafBrushes[i]) < imin )
|
||||
imin = (leafBrushes[i]);
|
||||
if( (leafBrushes[i]) > imax )
|
||||
imax = (leafBrushes[i]);
|
||||
}
|
||||
Printf( "leafBrushes: min:%u max:%u diff:%u\n", imin, imax, imax - imin );
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint planePTR; // Plane index.
|
||||
int surfaceFlags;
|
||||
int shaderNum; // Texture index.
|
||||
} BrushSide <read=ReadBrushSides>;
|
||||
|
||||
FSeek( lumps.offBSides - OFF );
|
||||
BrushSide brushSides[lumps.nBSides];
|
||||
|
||||
{
|
||||
umin = 4294967295, umax = 0;
|
||||
for( i = 0; i < lumps.nBSides; ++i ){
|
||||
if( (brushSides[i].planePTR) < umin )
|
||||
umin = (brushSides[i].planePTR);
|
||||
if( (brushSides[i].planePTR) > umax )
|
||||
umax = (brushSides[i].planePTR);
|
||||
}
|
||||
Printf( "planePTR: min:%u max:%u diff:%u\n", umin, umax, umax - umin );
|
||||
}
|
||||
|
||||
|
||||
FSeek( lumps.offSurfaces - OFF );
|
||||
|
||||
int surfaces[lumps.nSurfaces];
|
||||
|
||||
for( i = 0; i < lumps.nSurfaces; ++i ) {
|
||||
if( surfaces[i] != 0 ) {
|
||||
FSeek( surfaces[i] - OFF );
|
||||
struct cPatch_s {
|
||||
int checkcount; // to avoid repeated testings
|
||||
int surfaceFlags;
|
||||
int contents;
|
||||
int offPatchCollide_s;
|
||||
} cPatch_t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// typedef struct {
|
||||
// uint32 surfaceType;
|
||||
// uint32 firstVert;
|
||||
// uint32 numVerts;
|
||||
// uint32 firstIndex;
|
||||
// uint32 numIndexes;
|
||||
// uint32 lightmapNum;
|
||||
// uint32 fogNum;
|
||||
// uint32 shaderNum;
|
||||
// // uint32 lm_start[2];
|
||||
// // uint32 lm_size[2];
|
||||
// // uint32 lightmapOrigin[3];
|
||||
// uint32 lightmapVecs[6]; // [9]
|
||||
// uint32 patchWidth;
|
||||
// uint32 patchHeight;
|
||||
// } Surface <read=ReadSurfaces>;
|
||||
|
||||
// FSeek( lumps.surfaces.offset);
|
||||
// local int surfCount = lumps.surfaces.length / sizeof(Surface);
|
||||
// Surface surfaces[surfCount];
|
||||
|
||||
// FSeek( lumps.drawVerts.offset);
|
||||
|
||||
// typedef struct {
|
||||
// float xyz[3]; // Vertex position.
|
||||
// float st[2]; // Vertex texture coordinates.
|
||||
// float lightmap[2]; // Vertex lightmap coordinates.
|
||||
// //float normal[3]; // Vertex normal.
|
||||
// byte color[4]; // Vertex color. RGBA. -- 1.0 is max value
|
||||
// } Vertex;
|
||||
|
||||
// Vertex drawVerts[lumps.drawVerts.length / sizeof(Vertex) ];
|
||||
|
||||
|
||||
// local int i, j;
|
||||
// for(i=0;i<surfCount;i++) {
|
||||
// if( surfaces[i].surfaceType == 2) {
|
||||
// for(j=0;j<surfaces[i].numVerts;j++) {
|
||||
// FSeek(lumps.drawVerts.offset+(surfaces[i].firstVert+j)*sizeof(Vertex));
|
||||
// struct PATCH {
|
||||
// float xyz[3];
|
||||
// } patch;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// string ReadLumps( lump &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "%d %d", entry.offset, entry.length );
|
||||
// return s;
|
||||
// }
|
||||
|
||||
string ReadShader( Shader &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "%s", entry.name );
|
||||
return s;
|
||||
}
|
||||
|
||||
string ReadPlanes( Plane &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "%.1f: %.1f, %.1f, %.1f", entry.dist, entry.normal[0], entry.normal[1], entry.normal[2] );
|
||||
return s;
|
||||
}
|
||||
|
||||
// string ReadNodes( Node &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "pln %d: %d, %d", entry.plane, entry.children[0], entry.children[1] );
|
||||
// return s;
|
||||
// }
|
||||
|
||||
// string ReadLeafs( Leaf &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "leaf1 %d, leafn %d, brush1 %d, brushn : %d", entry.leafface, entry.n_leaffaces, entry.leafbrush, entry.n_leafbrushes );
|
||||
// return s;
|
||||
// }
|
||||
|
||||
// string ReadBrushes( Brush &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "tex %d, brushside1 %d, brushside_n %d", entry.texture, entry.brushside, entry.n_brushsides );
|
||||
// return s;
|
||||
// }
|
||||
|
||||
string ReadBrushSides( BrushSide &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "tex %d, plane %u", entry.shaderNum, entry.planePTR );
|
||||
return s;
|
||||
}
|
||||
|
||||
string ReadModels( cmodel_t &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "brush %d, surf %d", entry.leaf.firstLeafBrush & 0x00FFFFFF, entry.leaf.firstLeafSurface & 0x00FFFFFF );
|
||||
return s;
|
||||
}
|
||||
|
||||
// string ReadSurfaces( Surface &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "tex: %d, type: %d", entry.shaderNum, (int)entry.surfaceType );
|
||||
// return s;
|
||||
// }
|
||||
@@ -0,0 +1,416 @@
|
||||
LittleEndian();
|
||||
|
||||
// char signature[4];
|
||||
// uint32 version;
|
||||
|
||||
// typedef struct {
|
||||
// uint32 offset;
|
||||
// uint32 length;
|
||||
// } lump <read=ReadLumps>;
|
||||
|
||||
// struct {
|
||||
// lump entities;
|
||||
// lump shaders;
|
||||
// lump planes;
|
||||
// lump nodes;
|
||||
// lump leafs;
|
||||
// lump leafSurfaces;
|
||||
// lump leafBrushes;
|
||||
// lump models;
|
||||
// lump brushes;
|
||||
// lump brushSides;
|
||||
// lump drawVerts;
|
||||
// lump drawIndexes;
|
||||
// lump fogs;
|
||||
// lump surfaces;
|
||||
// lump lightmaps;
|
||||
// lump lightGrid;
|
||||
// lump visibility;
|
||||
// } lumps;
|
||||
|
||||
struct {
|
||||
char name[64]; // ie: maps/tim_dm2.bsp
|
||||
char baseName[64]; // ie: tim_dm2
|
||||
//---
|
||||
int dataSize;
|
||||
|
||||
int numShaders;
|
||||
uint offShaders;
|
||||
|
||||
int nModels; // 43 sz32
|
||||
//---
|
||||
uint offBmodels; // 166134168 2
|
||||
|
||||
int numplanes;
|
||||
uint offPlanes;
|
||||
|
||||
int numnodes; // includes leafs
|
||||
//---
|
||||
int numDecisionNodes;
|
||||
uint offNodes; // 167112188 4
|
||||
|
||||
int numsurfaces; // 2664
|
||||
uint offSurfaces; // 166135544 3
|
||||
//---
|
||||
int nummarksurfaces;
|
||||
uint offMarksurfaces; // 167242748 5
|
||||
|
||||
int numfogs; // 1 sz72
|
||||
uint offFogs; // 166134096 1
|
||||
//---
|
||||
float lightGridOrigin[3];
|
||||
float lightGridSize[3];
|
||||
float lightGridInverseSize[3];
|
||||
int lightGridBounds[3];
|
||||
//---
|
||||
uint offLightGridData; // 167273336 6
|
||||
|
||||
|
||||
int numClusters;
|
||||
int clusterBytes;
|
||||
int idk;
|
||||
//---
|
||||
uint offVis; // may be passed in by CM_LoadMap to save space
|
||||
int idk0[3];
|
||||
//---
|
||||
uint offNovis; // clusterBytes of 0xff
|
||||
|
||||
uint offEntityString;
|
||||
int idk_0;
|
||||
uint offEntityParsePoint; // 167582840 7
|
||||
} lumps;
|
||||
|
||||
|
||||
// 0166134096
|
||||
// 0166134168
|
||||
// 0166135544
|
||||
// 0167112188
|
||||
// 0167242748
|
||||
// 0167273336
|
||||
// 0167582840
|
||||
// 2264924372
|
||||
// 2265194036
|
||||
// 2265634448
|
||||
// 2265663632
|
||||
// 2265663632
|
||||
|
||||
// 0026047712
|
||||
// 0223740240
|
||||
// 0223740312
|
||||
// 0223744504
|
||||
// 0227575316
|
||||
// 0227906708
|
||||
// 0227998340
|
||||
// 0228621716
|
||||
// 2264924372
|
||||
// 2265808016
|
||||
// 2267132688
|
||||
// 2267243688
|
||||
// 2267243688
|
||||
|
||||
local int OFF = lumps.offFogs - 288;
|
||||
|
||||
Printf( "OFF: %d\n", OFF );
|
||||
|
||||
/*
|
||||
FSeek( lumps.offEnts - OFF );
|
||||
|
||||
char ents[lumps.nEnts];
|
||||
|
||||
typedef struct {
|
||||
char name[64];
|
||||
int surfaceFlags;
|
||||
int contents;
|
||||
} Shader <read=ReadShader>;
|
||||
|
||||
FSeek( lumps.offShaders - OFF );
|
||||
Shader shader[lumps.nShaders];
|
||||
|
||||
typedef struct {
|
||||
float normal[3];
|
||||
float dist;
|
||||
int idk;
|
||||
} Plane <read=ReadPlanes>;
|
||||
|
||||
FSeek( lumps.offPlanes - OFF );
|
||||
Plane planes[lumps.nPlanes];
|
||||
*/
|
||||
// typedef struct {
|
||||
// int plane;
|
||||
// int children[2]; // Children indices. Negative numbers are leaf indices: -(leaf+1).
|
||||
// int mins[3];// Integer bounding box min coord.
|
||||
// int maxs[3];
|
||||
// } Node <read=ReadNodes>;
|
||||
|
||||
// FSeek( lumps.nodes.offset);
|
||||
// Node nodes[lumps.nodes.length / sizeof(Node)];
|
||||
|
||||
// typedef struct {
|
||||
// int cluster; // Visdata cluster index.
|
||||
// int area; // Areaportal area.
|
||||
// // int mins[3]; // Integer bounding box min coord.
|
||||
// // int maxs[3]; // Integer bounding box max coord.
|
||||
// int leafbrush; // First leafbrush for leaf.
|
||||
// int n_leafbrushes; // Number of leafbrushes for leaf.
|
||||
// int leafface; // First leafface for leaf.
|
||||
// int n_leaffaces; // Number of leaffaces for leaf.
|
||||
// int mins[1]; // Integer bounding box min coord. // unused?
|
||||
// int maxs[1]; // Integer bounding box max coord. // unused?
|
||||
// } Leaf <read=ReadLeafs>;
|
||||
|
||||
// FSeek( lumps.leafs.offset);
|
||||
// Leaf leafs[lumps.leafs.length / sizeof(Leaf)];
|
||||
|
||||
// FSeek( lumps.leafSurfaces.offset);
|
||||
// int leafSurfaces[lumps.leafSurfaces.length / sizeof(int)];
|
||||
|
||||
// FSeek( lumps.leafBrushes.offset);
|
||||
// int leafBrushes[lumps.leafBrushes.length / sizeof(int)];
|
||||
|
||||
// typedef struct {
|
||||
// float mins[3];
|
||||
// float maxs[3];
|
||||
// int face1;
|
||||
// int face_n;
|
||||
// int brush1;
|
||||
// int brush_n;
|
||||
// } Model;
|
||||
|
||||
typedef struct {
|
||||
float mins[3]; // for culling
|
||||
float maxs[3]; // for culling
|
||||
uint offFirstSurface;
|
||||
int numSurfaces;
|
||||
} bmodel_t;
|
||||
|
||||
FSeek( lumps.offBmodels - OFF );
|
||||
bmodel_t models[lumps.nModels];
|
||||
|
||||
// typedef struct {
|
||||
// int brushside; // First brushside for brush.
|
||||
// int n_brushsides; // Number of brushsides for brush.
|
||||
// int texture; // Texture index.
|
||||
// } Brush <read=ReadBrushes>;
|
||||
/*
|
||||
typedef struct {
|
||||
int shaderNum; // the shader that determined the contents
|
||||
int contents;
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
int numsides;
|
||||
uint sidesPTR;
|
||||
int checkcount; // to avoid repeated testings
|
||||
} cbrush_t;
|
||||
|
||||
FSeek( lumps.offBrushes - OFF );
|
||||
cbrush_t brushes[lumps.nBrushes];
|
||||
|
||||
{
|
||||
local uint bsmin = 4294967295, bsmax = 0;
|
||||
local int i;
|
||||
for( i = 0; i < lumps.nBrushes; ++i ){
|
||||
if( (brushes[i].sidesPTR) < bsmin )
|
||||
bsmin = (brushes[i].sidesPTR);
|
||||
if( (brushes[i].sidesPTR) > bsmax )
|
||||
bsmax = (brushes[i].sidesPTR);
|
||||
}
|
||||
Printf( "sidesPTR: min:%u max:%u diff:%u\n", bsmin, bsmax, bsmax - bsmin );
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint planePTR; // Plane index.
|
||||
int surfaceFlags;
|
||||
int shaderNum; // Texture index.
|
||||
} BrushSide <read=ReadBrushSides>;
|
||||
|
||||
FSeek( lumps.offBSides - OFF );
|
||||
BrushSide brushSides[lumps.nBSides];
|
||||
|
||||
{
|
||||
bsmin = 4294967295, bsmax = 0;
|
||||
for( i = 0; i < lumps.nBSides; ++i ){
|
||||
if( (brushSides[i].planePTR) < bsmin )
|
||||
bsmin = (brushSides[i].planePTR);
|
||||
if( (brushSides[i].planePTR) > bsmax )
|
||||
bsmax = (brushSides[i].planePTR);
|
||||
}
|
||||
Printf( "planePTR: min:%u max:%u diff:%u\n", bsmin, bsmax, bsmax - bsmin );
|
||||
}
|
||||
*/
|
||||
// typedef struct {
|
||||
// uint32 surfaceType;
|
||||
// uint32 firstVert;
|
||||
// uint32 numVerts;
|
||||
// uint32 firstIndex;
|
||||
// uint32 numIndexes;
|
||||
// uint32 lightmapNum;
|
||||
// uint32 fogNum;
|
||||
// uint32 shaderNum;
|
||||
// // uint32 lm_start[2];
|
||||
// // uint32 lm_size[2];
|
||||
// // uint32 lightmapOrigin[3];
|
||||
// uint32 lightmapVecs[6]; // [9]
|
||||
// uint32 patchWidth;
|
||||
// uint32 patchHeight;
|
||||
// } Surface <read=ReadSurfaces>;
|
||||
|
||||
// FSeek( lumps.surfaces.offset);
|
||||
// local int surfCount = lumps.surfaces.length / sizeof(Surface);
|
||||
// Surface surfaces[surfCount];
|
||||
|
||||
typedef struct {
|
||||
int viewCount; // if == tr.viewCount, already added
|
||||
uint offShader;
|
||||
int fogIndex;
|
||||
int surfType;
|
||||
int offSurf; // any of srf*_t
|
||||
} Surface;
|
||||
|
||||
FSeek( lumps.offSurfaces - OFF );
|
||||
|
||||
Surface surfaces[lumps.numsurfaces];
|
||||
|
||||
{
|
||||
local uint umin = 4294967295, umax = 0;
|
||||
local int i;
|
||||
for( i = 0; i < lumps.numsurfaces; ++i ){
|
||||
if( (surfaces[i].offShader) < umin )
|
||||
umin = (surfaces[i].offShader);
|
||||
if( (surfaces[i].offShader) > umax )
|
||||
umax = (surfaces[i].offShader);
|
||||
}
|
||||
Printf( "offShader: min:%u max:%u diff:%u\n", umin, umax, umax - umin );
|
||||
}
|
||||
|
||||
// FSeek( lumps.drawVerts.offset);
|
||||
|
||||
typedef struct {
|
||||
float xyz[3]; // Vertex position.
|
||||
float st[2]; // Vertex texture coordinates.
|
||||
float lightmap[2]; // Vertex lightmap coordinates.
|
||||
float normal[3]; // Vertex normal.
|
||||
byte color[4]; // Vertex color. RGBA. -- 1.0 is max value
|
||||
} Vertex;
|
||||
|
||||
typedef struct {
|
||||
float xyz[3]; // Vertex position.
|
||||
float st[2]; // Vertex texture coordinates.
|
||||
float lightmap[2]; // Vertex lightmap coordinates.
|
||||
// float normal[3]; // Vertex normal.
|
||||
byte color[4]; // Vertex color. RGBA. -- 1.0 is max value
|
||||
} VertexPlanar;
|
||||
|
||||
// Vertex drawVerts[lumps.drawVerts.length / sizeof(Vertex) ];
|
||||
|
||||
|
||||
// local int i, j;
|
||||
// for(i=0;i<surfCount;i++) {
|
||||
// if( surfaces[i].surfaceType == 2) {
|
||||
// for(j=0;j<surfaces[i].numVerts;j++) {
|
||||
// FSeek(lumps.drawVerts.offset+(surfaces[i].firstVert+j)*sizeof(Vertex));
|
||||
// struct PATCH {
|
||||
// float xyz[3];
|
||||
// } patch;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
local int j;
|
||||
for( i = 0; i < lumps.numsurfaces; ++i ) {
|
||||
FSeek( surfaces[i].offSurf - OFF );
|
||||
if( surfaces[i].surfType == 2 ) { // planar SF_FACE
|
||||
struct PLANAR {
|
||||
int surfType;
|
||||
int idk[7];
|
||||
int numVerts;
|
||||
int numIndices;
|
||||
int idk2;
|
||||
VertexPlanar verts[numVerts];
|
||||
int indices[numIndices];
|
||||
} planar;
|
||||
}
|
||||
else if( surfaces[i].surfType == 3 ) { // patches SF_GRID
|
||||
struct PATCH {
|
||||
int surfType;
|
||||
int idk[18];
|
||||
int width, height;
|
||||
int idk2[2];
|
||||
Vertex verts[width * height]; // !! NOTE width, height may be optimized and be even
|
||||
} patch;
|
||||
}
|
||||
else if( surfaces[i].surfType == 4 ) { // trisoup SF_TRIANGLES
|
||||
struct TRISOUP {
|
||||
int surfType;
|
||||
int idk[11];
|
||||
int numIndices;
|
||||
int offIndices; // -OFF -> short
|
||||
int numVerts;
|
||||
int offVerts; // -OFF -> Vertex
|
||||
} trisoup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// string ReadLumps( lump &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "%d %d", entry.offset, entry.length );
|
||||
// return s;
|
||||
// }
|
||||
/*
|
||||
string ReadShader( Shader &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "%s", entry.name );
|
||||
return s;
|
||||
}
|
||||
|
||||
string ReadPlanes( Plane &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "%.1f: %.1f, %.1f, %.1f", entry.dist, entry.normal[0], entry.normal[1], entry.normal[2] );
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
// string ReadNodes( Node &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "pln %d: %d, %d", entry.plane, entry.children[0], entry.children[1] );
|
||||
// return s;
|
||||
// }
|
||||
|
||||
// string ReadLeafs( Leaf &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "leaf1 %d, leafn %d, brush1 %d, brushn : %d", entry.leafface, entry.n_leaffaces, entry.leafbrush, entry.n_leafbrushes );
|
||||
// return s;
|
||||
// }
|
||||
|
||||
// string ReadBrushes( Brush &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "tex %d, brushside1 %d, brushside_n %d", entry.texture, entry.brushside, entry.n_brushsides );
|
||||
// return s;
|
||||
// }
|
||||
/*
|
||||
string ReadBrushSides( BrushSide &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "tex %d, plane %u", entry.shaderNum, entry.planePTR );
|
||||
return s;
|
||||
}
|
||||
|
||||
string ReadModels( cmodel_t &entry )
|
||||
{
|
||||
string s;
|
||||
SPrintf( s, "brush %d, surf %d", entry.leaf.firstLeafBrush & 0x00FFFFFF, entry.leaf.firstLeafSurface & 0x00FFFFFF );
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
// string ReadSurfaces( Surface &entry )
|
||||
// {
|
||||
// string s;
|
||||
// SPrintf( s, "tex: %d, type: %d", entry.shaderNum, (int)entry.surfaceType );
|
||||
// return s;
|
||||
// }
|
||||
@@ -350,3 +350,429 @@ void WriteIBSPFile( const char *filename ){
|
||||
/* close the file */
|
||||
fclose( file );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
using uint = std::uint32_t;
|
||||
|
||||
struct XbspPlane_t
|
||||
{
|
||||
bspPlane_t plane;
|
||||
int idk;
|
||||
operator bspPlane_t() const {
|
||||
return plane;
|
||||
}
|
||||
};
|
||||
|
||||
struct cLeaf_t
|
||||
{
|
||||
int cluster;
|
||||
int area;
|
||||
|
||||
int firstLeafBrush;
|
||||
int numLeafBrushes;
|
||||
|
||||
int firstLeafSurface;
|
||||
int numLeafSurfaces;
|
||||
|
||||
uint leafBrush;
|
||||
uint leafSurf;
|
||||
|
||||
operator bspLeaf_t() const {
|
||||
return bspLeaf_t{
|
||||
.cluster = cluster,
|
||||
.area = area,
|
||||
.firstBSPLeafSurface = firstLeafSurface,
|
||||
.numBSPLeafSurfaces = numLeafSurfaces,
|
||||
.firstBSPLeafBrush = firstLeafBrush,
|
||||
.numBSPLeafBrushes = numLeafBrushes
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct cmodel_t
|
||||
{
|
||||
MinMax minmax;
|
||||
cLeaf_t leaf; // submodels don't reference the main tree
|
||||
};
|
||||
|
||||
struct cbrush_t
|
||||
{
|
||||
int shaderNum; // the shader that determined the contents
|
||||
int contents;
|
||||
MinMax minmax;
|
||||
int numsides;
|
||||
uint sidesPTR;
|
||||
int checkcount; // to avoid repeated testings
|
||||
};
|
||||
|
||||
struct XBrushSide
|
||||
{
|
||||
uint planePTR; // Plane index.
|
||||
int surfaceFlags;
|
||||
int shaderNum; // Texture index.
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct Clip
|
||||
{
|
||||
char name[64];
|
||||
int datasize; // -8917903 4286049393
|
||||
int nShaders; // 67
|
||||
int offShaders; // 183238916 1
|
||||
int nBSides; // 22064
|
||||
|
||||
int offBSides; // 183243740 2
|
||||
int nPlanes; // 11400
|
||||
int offPlanes; // 183508580 3
|
||||
int nC; // 998 sz12
|
||||
|
||||
int offC; // 183736820 4
|
||||
int nLeafs; // 1042 sz32
|
||||
int offLeafs; // 183748796 5
|
||||
int nLeafBrushes;// 7094 sz4
|
||||
|
||||
int offLeafbrushes;// 183782204 6
|
||||
int nF; // 46 sz4
|
||||
int offF; // 183810584 7
|
||||
int nLeafSurfaces;// 7647 sz4
|
||||
|
||||
int offLeafSurfaces;// 183810768 8
|
||||
int nH; // 91 sz4
|
||||
int offH; // 183841356 9
|
||||
int nModels; // 43 sz56
|
||||
|
||||
int offModels; // 184050596 16
|
||||
int nBrushes; // 2437 sz44
|
||||
int offBrushes; // 183841720 10
|
||||
int nK; // 29184
|
||||
|
||||
int nL; // 456
|
||||
int nM; // 64
|
||||
int offM; // 183948992 ?vis 11
|
||||
int nN; // 1
|
||||
|
||||
int nEnts; // 42492
|
||||
int offEnts; // 183978176 12
|
||||
int nO; // 5 sz8
|
||||
int offO; // 184020668 13
|
||||
|
||||
int offP; // 184020708 14
|
||||
int nSurfaces; // 2664
|
||||
int offSurfaces;// 184020808 15 // pointer to array of pointers to cPatch_t // non-patches will be NULL
|
||||
int nR; // 1
|
||||
|
||||
int nS; // 0
|
||||
};
|
||||
|
||||
|
||||
struct XSurface
|
||||
{
|
||||
int viewCount; // if == tr.viewCount, already added
|
||||
uint offShader;
|
||||
int fogIndex;
|
||||
int surfType;
|
||||
int offSurf; // any of srf*_t
|
||||
};
|
||||
|
||||
using XVertex = ibspDrawVert_t;
|
||||
struct XVertexPlanar
|
||||
{
|
||||
Vector3 xyz;
|
||||
Vector2 st;
|
||||
Vector2 lightmap;
|
||||
// Vector3 normal;
|
||||
Color4b color;
|
||||
operator bspDrawVert_t() const {
|
||||
return bspDrawVert_t{
|
||||
.xyz = xyz,
|
||||
.st = st,
|
||||
.lightmap{ lightmap, Vector2( 0 ), Vector2( 0 ), Vector2( 0 ) },
|
||||
.normal = Vector3( 0 ),
|
||||
.color { color, Color4b( 0 ), Color4b( 0 ), Color4b( 0 ) }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct World
|
||||
{
|
||||
char name[64]; // ie: maps/tim_dm2.bsp
|
||||
char baseName[64]; // ie: tim_dm2
|
||||
//---
|
||||
int dataSize;
|
||||
|
||||
int numShaders;
|
||||
uint offShaders;
|
||||
|
||||
int nModels; // 43 sz32
|
||||
//---
|
||||
uint offBmodels; // 166134168 2
|
||||
|
||||
int numplanes;
|
||||
uint offPlanes;
|
||||
|
||||
int numnodes; // includes leafs
|
||||
//---
|
||||
int numDecisionNodes;
|
||||
uint offNodes; // 167112188 4
|
||||
|
||||
int numsurfaces; // 2664
|
||||
uint offSurfaces; // 166135544 3
|
||||
//---
|
||||
int nummarksurfaces;
|
||||
uint offMarksurfaces; // 167242748 5
|
||||
|
||||
int numfogs; // 1 sz72
|
||||
uint offFogs; // 166134096 1
|
||||
//---
|
||||
float lightGridOrigin[3];
|
||||
float lightGridSize[3];
|
||||
float lightGridInverseSize[3];
|
||||
int lightGridBounds[3];
|
||||
//---
|
||||
uint offLightGridData; // 167273336 6
|
||||
|
||||
|
||||
int numClusters;
|
||||
int clusterBytes;
|
||||
int idk;
|
||||
//---
|
||||
uint offVis; // may be passed in by CM_LoadMap to save space
|
||||
int idk0[3];
|
||||
//---
|
||||
uint offNovis; // clusterBytes of 0xff
|
||||
|
||||
uint offEntityString;
|
||||
int idk_0;
|
||||
uint offEntityParsePoint; // 167582840 7
|
||||
};
|
||||
|
||||
|
||||
|
||||
void LoadXboxFile( const char *filename ){
|
||||
MemBuffer fcachemap = LoadFile( filename );
|
||||
MemBuffer fclip = LoadFile( StringStream( PathFilenameless( filename ), "clip" ) );
|
||||
MemBuffer fworld = LoadFile( StringStream( PathFilenameless( filename ), "world" ) );
|
||||
|
||||
{
|
||||
Clip *clip = fclip.data();
|
||||
const int OFF = clip->offShaders - 212;
|
||||
|
||||
bspEntData = {
|
||||
( char* )( (byte*)fclip.data() + clip->offEnts - OFF ),
|
||||
( char* )( (byte*)fclip.data() + clip->offEnts - OFF ) + clip->nEnts
|
||||
};
|
||||
bspShaders = {
|
||||
( bspShader_t* )( (byte*)fclip.data() + clip->offShaders - OFF ),
|
||||
( bspShader_t* )( (byte*)fclip.data() + clip->offShaders - OFF ) + clip->nShaders
|
||||
};
|
||||
bspPlanes = {
|
||||
( XbspPlane_t* )( (byte*)fclip.data() + clip->offPlanes - OFF ),
|
||||
( XbspPlane_t* )( (byte*)fclip.data() + clip->offPlanes - OFF ) + clip->nPlanes
|
||||
};
|
||||
bspLeafSurfaces = {
|
||||
( int* )( (byte*)fclip.data() + clip->offLeafSurfaces - OFF ),
|
||||
( int* )( (byte*)fclip.data() + clip->offLeafSurfaces - OFF ) + clip->nLeafSurfaces
|
||||
};
|
||||
bspLeafBrushes = {
|
||||
( int* )( (byte*)fclip.data() + clip->offLeafbrushes - OFF ),
|
||||
( int* )( (byte*)fclip.data() + clip->offLeafbrushes - OFF ) + clip->nLeafBrushes
|
||||
};
|
||||
bspLeafs = {
|
||||
( cLeaf_t* )( (byte*)fclip.data() + clip->offLeafs - OFF ),
|
||||
( cLeaf_t* )( (byte*)fclip.data() + clip->offLeafs - OFF ) + clip->nLeafs
|
||||
};
|
||||
|
||||
Span cmodels( ( cmodel_t* )( (byte*)fclip.data() + clip->offModels - OFF ), clip->nModels );
|
||||
for( auto& cmodel : cmodels ){
|
||||
bspModels.push_back( bspModel_t{ .minmax = cmodel.minmax,
|
||||
.firstBSPSurface = 0, .numBSPSurfaces = cmodel.leaf.numLeafSurfaces,
|
||||
.firstBSPBrush = 0, .numBSPBrushes = cmodel.leaf.numLeafBrushes } );
|
||||
if( cmodel.leaf.numLeafSurfaces != 0 ){
|
||||
bspModels.back().firstBSPSurface = *( int* )( (byte*)fclip.data() + ( cmodel.leaf.leafSurf & 0x00FFFFFF ) );
|
||||
if( bspModels.front().numBSPSurfaces > bspModels.back().firstBSPSurface || bspModels.front().numBSPSurfaces == 0 ){
|
||||
bspModels.front().numBSPSurfaces = bspModels.back().firstBSPSurface;
|
||||
}
|
||||
}
|
||||
if( cmodel.leaf.numLeafBrushes != 0 ){
|
||||
bspModels.back().firstBSPBrush = *( int* )( (byte*)fclip.data() + ( cmodel.leaf.leafBrush & 0x00FFFFFF ) );
|
||||
if( bspModels.front().numBSPBrushes > bspModels.back().firstBSPBrush || bspModels.front().numBSPBrushes == 0 ){
|
||||
bspModels.front().numBSPBrushes = bspModels.back().firstBSPBrush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Span cbrushes( ( cbrush_t* )( (byte*)fclip.data() + clip->offBrushes - OFF ), clip->nBrushes );
|
||||
for( auto& cbrush : cbrushes ){
|
||||
bspBrushes.push_back( bspBrush_t{ .firstSide = 0, .numSides = cbrush.numsides, .shaderNum = cbrush.shaderNum } );
|
||||
bspBrushes.back().firstSide = ( ( cbrush.sidesPTR & 0x00FFFFFF ) - ( clip->offBSides - OFF ) ) / sizeof( XBrushSide );
|
||||
}
|
||||
|
||||
Span xbrushsides( ( XBrushSide* )( (byte*)fclip.data() + clip->offBSides - OFF ), clip->nBSides );
|
||||
for( auto& xbs : xbrushsides ){
|
||||
bspBrushSides.push_back( bspBrushSide_t{ .planeNum = 0, .shaderNum = xbs.shaderNum, .surfaceNum = 0 } );
|
||||
bspBrushSides.back().planeNum = ( ( xbs.planePTR & 0x00FFFFFF ) - ( clip->offPlanes - OFF ) ) / sizeof( XbspPlane_t );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
World *world = fworld.data();
|
||||
const int OFF = world->offFogs - 288;
|
||||
|
||||
// note this is start of 0008.block.04
|
||||
const char *shadersSatrt = std::ranges::find_if( Span( (const char*)fcachemap.data(), fcachemap.size() ), []( const char& s ){
|
||||
return strEqual( &s, "<default>" );
|
||||
} ).operator->() - 572;
|
||||
|
||||
Span xsurfs( ( XSurface* )( (byte*)fworld.data() + world->offSurfaces - OFF ), world->numsurfaces );
|
||||
for( auto& xsurf : xsurfs ){
|
||||
bspDrawSurface_t& surf = bspDrawSurfaces.emplace_back( bspDrawSurface_t{ .surfaceType = xsurf.surfType - 1 } );
|
||||
String64 shader( shadersSatrt + ( xsurf.offShader & 0x00FFFFFF ) );
|
||||
// String64 shader( (char*)fcachemap.data() + xsurf.offShader - 2193354400u );
|
||||
for( size_t i = 0; i != bspShaders.size(); ++i ){
|
||||
if( strEqual( shader, bspShaders[i].shader ) ){
|
||||
surf.shaderNum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( surf.surfaceType == MST_PLANAR ) { // planar SF_FACE
|
||||
struct PLANAR {
|
||||
int surfType;
|
||||
int idk[7];
|
||||
int numVerts;
|
||||
int numIndices;
|
||||
int idk2;
|
||||
XVertexPlanar verts; //[numVerts];
|
||||
int indices; //[numIndices];
|
||||
} *planar = ( PLANAR* )( (byte*)fworld.data() + xsurf.offSurf - OFF );
|
||||
surf.numVerts = planar->numVerts;
|
||||
surf.numIndexes = planar->numIndices;
|
||||
surf.firstVert = bspDrawVerts.size();
|
||||
surf.firstIndex = bspDrawIndexes.size();
|
||||
for( auto& v : Span( &planar->verts, planar->numVerts ) )
|
||||
bspDrawVerts.push_back( v );
|
||||
for( auto& i : Span( (int*)( &planar->verts + planar->numVerts ), planar->numIndices ) )
|
||||
bspDrawIndexes.push_back( i );
|
||||
}
|
||||
else if( surf.surfaceType == MST_PATCH ) { // patches SF_GRID
|
||||
struct PATCH {
|
||||
int surfType;
|
||||
int idk[18];
|
||||
int width, height;
|
||||
int idk2[2];
|
||||
XVertex verts; //[width * height]; // !! NOTE width, height may be optimized and be even
|
||||
} *patch = ( PATCH* )( (byte*)fworld.data() + xsurf.offSurf - OFF );
|
||||
|
||||
/* not a case in the maps */
|
||||
if( ( patch->height | 1 ) >= MAX_PATCH_SIZE ){
|
||||
Sys_Warning( "big patch %dx%d: ignoring\n", patch->width, patch->height );
|
||||
surf.surfaceType = MST_BAD;
|
||||
continue;
|
||||
}
|
||||
if( ( patch->width | 1 ) >= MAX_PATCH_SIZE ){
|
||||
Sys_Warning( "big patch %dx%d: splitting\n", patch->width, patch->height );
|
||||
|
||||
mesh_t mesh( patch->width | 1, patch->height | 1 );
|
||||
|
||||
XVertex *v = &patch->verts;
|
||||
for( int h = 0; h < patch->height; ++h ){
|
||||
for( int w = 0; w < mesh.width; ++w ){
|
||||
mesh[h][w] = *v;
|
||||
if( !( !( patch->width & 1 ) && w == ( patch->width - 1 ) ) ){
|
||||
++v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !( patch->height & 1 ) ){
|
||||
for( int w = 0; w < mesh.width; ++w )
|
||||
mesh[patch->height][w] = mesh[patch->height - 1][w];
|
||||
}
|
||||
|
||||
const int wsplit = ( mesh.width >> 1 ) | 1;
|
||||
surf.patchWidth = wsplit;
|
||||
surf.patchHeight = mesh.height;
|
||||
surf.firstVert = bspDrawVerts.size();
|
||||
for( int h = 0; h < surf.patchHeight; ++h ){
|
||||
for( int w = 0; w < surf.patchWidth; ++w ){
|
||||
bspDrawVerts.push_back( mesh[h][w] );
|
||||
}
|
||||
}
|
||||
|
||||
bspDrawSurface_t& surf2 = bspDrawSurfaces.emplace_back( bspDrawSurface_t( surf ) ); // avoid dead reference on realloc
|
||||
surf2.patchWidth = mesh.width - ( wsplit - 1 );
|
||||
surf2.patchHeight = mesh.height;
|
||||
surf2.firstVert = bspDrawVerts.size();
|
||||
for( int h = 0; h < surf2.patchHeight; ++h ){
|
||||
for( int w = ( wsplit - 1 ); w < mesh.width; ++w ){
|
||||
bspDrawVerts.push_back( mesh[h][w] );
|
||||
}
|
||||
}
|
||||
|
||||
/* fix surfaces indexing... */
|
||||
const int surfidx = bspDrawSurfaces.size() - 2; // 1st patch index
|
||||
// bspLeafSurfaces - skip - are not needed to decompile
|
||||
for( auto& model : bspModels ){
|
||||
if( model.firstBSPSurface > surfidx )
|
||||
++model.firstBSPSurface;
|
||||
if( model.firstBSPSurface <= surfidx
|
||||
&& model.firstBSPSurface + model.numBSPSurfaces > surfidx )
|
||||
++model.numBSPSurfaces;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
surf.patchWidth = patch->width;
|
||||
surf.patchHeight = patch->height;
|
||||
surf.firstVert = bspDrawVerts.size();
|
||||
if( patch->width & 1 && patch->height & 1 ){
|
||||
for( auto& v : Span( &patch->verts, patch->width * patch->height ) )
|
||||
bspDrawVerts.push_back( v );
|
||||
}
|
||||
else{
|
||||
surf.patchWidth |= 1;
|
||||
surf.patchHeight |= 1;
|
||||
XVertex *v = &patch->verts;
|
||||
for( int h = 0; h < patch->height; ++h ){
|
||||
for( int w = 0; w < surf.patchWidth; ++w ){
|
||||
bspDrawVerts.push_back( *v );
|
||||
if( !( !( patch->width & 1 ) && w == ( patch->width - 1 ) ) ){
|
||||
++v;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !( patch->height & 1 ) ){
|
||||
for( int i = bspDrawVerts.size() - surf.patchWidth, end = bspDrawVerts.size(); i < end; ++i )
|
||||
bspDrawVerts.push_back( bspDrawVert_t( bspDrawVerts[i] ) ); // avoid dead reference on realloc
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( surf.surfaceType == MST_TRIANGLE_SOUP ) { // trisoup SF_TRIANGLES
|
||||
struct TRISOUP {
|
||||
int surfType;
|
||||
int idk[11];
|
||||
int numIndices;
|
||||
int offIndices; // -OFF -> short
|
||||
int numVerts;
|
||||
int offVerts; // -OFF -> XVertex
|
||||
} *trisoup = ( TRISOUP* )( (byte*)fworld.data() + xsurf.offSurf - OFF );
|
||||
surf.numVerts = trisoup->numVerts;
|
||||
surf.numIndexes = trisoup->numIndices;
|
||||
surf.firstVert = bspDrawVerts.size();
|
||||
surf.firstIndex = bspDrawIndexes.size();
|
||||
for( auto& v : Span( ( XVertex* )( (byte*)fworld.data() + trisoup->offVerts - OFF ), trisoup->numVerts ) )
|
||||
bspDrawVerts.push_back( v );
|
||||
for( auto& i : Span( ( std::int16_t* )( (byte*)fworld.data() + trisoup->offIndices - OFF ), trisoup->numIndices ) )
|
||||
bspDrawIndexes.push_back( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,3 +4,5 @@
|
||||
void LoadIBSPFile( const char *filename );
|
||||
void WriteIBSPFile( const char *filename );
|
||||
void LoadIBSPorRBSPFilePartially( const char *filename );
|
||||
|
||||
void LoadXboxFile( const char *filename );
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
/* dependencies */
|
||||
#include "q3map2.h"
|
||||
#include "bspfile_ibsp.h"
|
||||
|
||||
|
||||
|
||||
@@ -1026,6 +1027,7 @@ int ConvertBSPMain( Args& args ){
|
||||
map_allowed = false;
|
||||
force_bsp = false;
|
||||
force_map = false;
|
||||
bool force_xbox = false;
|
||||
|
||||
/* arg checking */
|
||||
if ( args.empty() ) {
|
||||
@@ -1092,6 +1094,9 @@ int ConvertBSPMain( Args& args ){
|
||||
while ( args.takeArg( "-readmap" ) ) {
|
||||
force_map = true;
|
||||
}
|
||||
while ( args.takeArg( "-readxbox" ) ) {
|
||||
force_xbox = true;
|
||||
}
|
||||
while ( args.takeArg( "-meta" ) ) {
|
||||
meta = true;
|
||||
}
|
||||
@@ -1119,7 +1124,12 @@ int ConvertBSPMain( Args& args ){
|
||||
force_bsp = true;
|
||||
}
|
||||
|
||||
if ( force_map || ( !force_bsp && path_extension_is( source, "map" ) && map_allowed ) ) {
|
||||
if( force_xbox ){
|
||||
Sys_Printf( "Loading %s\n", source );
|
||||
LoadXboxFile( source );
|
||||
ParseEntities();
|
||||
}
|
||||
else if ( force_map || ( !force_bsp && path_extension_is( source, "map" ) && map_allowed ) ) {
|
||||
if ( !map_allowed ) {
|
||||
Sys_Warning( "the requested conversion should not be done from .map files. Compile a .bsp first.\n" );
|
||||
}
|
||||
|
||||
@@ -123,16 +123,16 @@ public:
|
||||
continue;
|
||||
}
|
||||
const TriRef& vert = tri->tri;
|
||||
if ( tri->surfaceType == MST_PLANAR
|
||||
&& VectorCompare( vert[0]->normal, vert[1]->normal )
|
||||
&& VectorCompare( vert[1]->normal, vert[2]->normal ) ) {
|
||||
if ( !vector3_equal_epsilon( vert[0]->normal, buildPlane.normal(), float( nepsilon ) )
|
||||
|| !vector3_equal_epsilon( vert[1]->normal, buildPlane.normal(), float( nepsilon ) )
|
||||
|| !vector3_equal_epsilon( vert[2]->normal, buildPlane.normal(), float( nepsilon ) ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
// if ( tri->surfaceType == MST_PLANAR
|
||||
// && VectorCompare( vert[0]->normal, vert[1]->normal )
|
||||
// && VectorCompare( vert[1]->normal, vert[2]->normal ) ) {
|
||||
// if ( !vector3_equal_epsilon( vert[0]->normal, buildPlane.normal(), float( nepsilon ) )
|
||||
// || !vector3_equal_epsilon( vert[1]->normal, buildPlane.normal(), float( nepsilon ) )
|
||||
// || !vector3_equal_epsilon( vert[2]->normal, buildPlane.normal(), float( nepsilon ) ) ) {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
{
|
||||
// this is more prone to roundoff errors, but with embedded
|
||||
// models, there is no better way
|
||||
|
||||
Reference in New Issue
Block a user