Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading BSP2 maps in a single binary #1950

Merged
merged 8 commits into from
Jan 9, 2025
15 changes: 0 additions & 15 deletions common/bspfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ GNU General Public License for more details.
#ifndef BSPFILE_H
#define BSPFILE_H

//#define SUPPORT_BSP2_FORMAT // allow to loading Darkplaces BSP2 maps (with broke binary compatibility)

/*
==============================================================================

Expand Down Expand Up @@ -65,7 +63,6 @@ BRUSH MODELS
#define MAX_MAP_CLIPNODES_BSP2 524288

// these limis not using by modelloader but only for displaying 'mapstats' correctly
#ifdef SUPPORT_BSP2_FORMAT
#define MAX_MAP_MODELS 2048 // embedded models
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
#define MAX_MAP_PLANES 131072 // can be increased without problems
Expand All @@ -75,18 +72,6 @@ BRUSH MODELS
#define MAX_MAP_VERTS 524288 // can be increased without problems
#define MAX_MAP_FACES 262144 // can be increased without problems
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
#else
// increased to match PrimeXT compilers
#define MAX_MAP_MODELS 1024 // embedded models
#define MAX_MAP_ENTSTRING 0x100000 // 1 Mb should be enough
#define MAX_MAP_PLANES 65536 // can be increased without problems
#define MAX_MAP_NODES 32767 // because negative shorts are leafs
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_HLBSP // because negative shorts are contents
#define MAX_MAP_LEAFS 32767 // signed short limit
#define MAX_MAP_VERTS 65535 // unsigned short limit
#define MAX_MAP_FACES 65535 // unsigned short limit
#define MAX_MAP_MARKSURFACES 65535 // unsigned short limit
#endif

#define MAX_MAP_ENTITIES 8192 // network limit
#define MAX_MAP_TEXINFO MAX_MAP_FACES // in theory each face may have personal texinfo
Expand Down
135 changes: 110 additions & 25 deletions common/com_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,29 @@ typedef struct
vec3_t position;
} mvertex_t;

typedef struct
typedef struct mclipnode32_s
{
int planenum;
#ifdef SUPPORT_BSP2_FORMAT
int children[2]; // negative numbers are contents
#else
short children[2]; // negative numbers are contents
#endif
} mclipnode_t;
int planenum;
int children[2]; // negative numbers are contents
} mclipnode32_t;

typedef struct mclipnode16_s
{
int planenum;
short children[2]; // negative numbers are contents
} mclipnode16_t;

// size is matched but representation is not
typedef struct
typedef struct medge32_s
{
#ifdef SUPPORT_BSP2_FORMAT
unsigned int v[2];
#else
} medge32_t;

typedef struct medge16_s
{
unsigned short v[2];
unsigned int cachededgeoffset;
#endif
} medge_t;
} medge16_t;

typedef struct texture_s
{
Expand Down Expand Up @@ -156,13 +159,31 @@ typedef struct mnode_s

// node specific
mplane_t *plane;
struct mnode_s *children[2];
#ifdef SUPPORT_BSP2_FORMAT
int firstsurface;
int numsurfaces;

#if !XASH_64BIT
union
{
struct mnode_s *children_[2];
struct
{
// the ordering is important
int child_0_leaf : 1;
int child_0_off : 23;
int firstsurface_1 : 8;
int child_1_leaf : 1;
int child_1_off : 23;
int numsurfaces_1 : 8;
};
};
unsigned short firstsurface_0;
unsigned short numsurfaces_0;
#else
unsigned short firstsurface;
unsigned short numsurfaces;
// in 64-bit ABI this struct has 4 more bytes of padding, let's use it!
struct mnode_s *children_[2];
unsigned short firstsurface_0;
unsigned short numsurfaces_0;
unsigned short firstsurface_1;
unsigned short numsurfaces_1;
#endif
} mnode_t;

Expand Down Expand Up @@ -203,7 +224,6 @@ typedef struct mleaf_s
int nummarksurfaces;
int cluster; // helper to acess to uncompressed visdata
byte ambient_sound_level[NUM_AMBIENTS];

} mleaf_t;

// surface extradata
Expand Down Expand Up @@ -291,7 +311,11 @@ struct msurface_s

typedef struct hull_s
{
mclipnode_t *clipnodes;
union
{
mclipnode16_t *clipnodes16;
mclipnode32_t *clipnodes32;
};
mplane_t *planes;
int firstclipnode;
int lastclipnode;
Expand Down Expand Up @@ -341,7 +365,12 @@ typedef struct model_s
mvertex_t *vertexes;

int numedges;
medge_t *edges;
union
{
medge16_t *edges16;
medge32_t *edges32;
};


int numnodes;
mnode_t *nodes;
Expand All @@ -356,7 +385,11 @@ typedef struct model_s
int *surfedges;

int numclipnodes;
mclipnode_t *clipnodes;
union
{
mclipnode16_t *clipnodes16;
mclipnode32_t *clipnodes32;
};

int nummarksurfaces;
msurface_t **marksurfaces;
Expand Down Expand Up @@ -550,16 +583,68 @@ typedef struct
#define ANIM_CYCLE 2
#define MOD_FRAMES 20



#define MAX_DEMOS 32
#define MAX_MOVIES 8
#define MAX_CDTRACKS 32
#define MAX_CLIENT_SPRITES 512 // SpriteTextures (0-256 hud, 256-512 client)
#define MAX_REQUESTS 64

STATIC_CHECK_SIZEOF( mnode_t, 52, 72 );
STATIC_CHECK_SIZEOF( mextrasurf_t, 324, 496 );
STATIC_CHECK_SIZEOF( decal_t, 60, 88 );
STATIC_CHECK_SIZEOF( mfaceinfo_t, 176, 304 );

// model flags (stored in model_t->flags)
#define MODEL_QBSP2 BIT( 28 ) // uses 32-bit types

// access functions
static inline mnode_t *node_child( const mnode_t *n, int side, const model_t *mod )
{
#if !XASH_64BIT
if( unlikely( mod->flags & MODEL_QBSP2 )) // MODEL_QBSP2
{
if( side == 0 )
{
if( n->child_0_leaf )
return (mnode_t *)(mod->leafs + n->child_0_off);
else
return (mnode_t *)(mod->nodes + n->child_0_off);
}
else
{
if( n->child_1_leaf )
return (mnode_t *)(mod->leafs + n->child_1_off);
else
return (mnode_t *)(mod->nodes + n->child_1_off);
}
}

return n->children_[side];
#else
return n->children_[side];
#endif
}

static inline void node_children( mnode_t *children[2], const mnode_t *n, const model_t *mod )
{
children[0] = node_child( n, 0, mod );
children[1] = node_child( n, 1, mod );
}

static inline int node_firstsurface( const mnode_t *n, const model_t *mod )
{
if( mod->flags & MODEL_QBSP2 )
return n->firstsurface_0 + ( n->firstsurface_1 << 16 );
else
return n->firstsurface_0;
}

static inline int node_numsurfaces( const mnode_t *n, const model_t *mod )
{
if( mod->flags & MODEL_QBSP2 )
return n->numsurfaces_0 + ( n->numsurfaces_1 << 16 );
else
return n->numsurfaces_0;
}

#endif//COM_MODEL_H
6 changes: 4 additions & 2 deletions engine/client/cl_efrag.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ static void R_SplitEntityOnNode( mnode_t *node )
}

// recurse down the contacted sides
if( sides & 1 ) R_SplitEntityOnNode( node->children[0] );
if( sides & 2 ) R_SplitEntityOnNode( node->children[1] );
if( sides & 1 )
R_SplitEntityOnNode( node_child( node, 0, cl.worldmodel ));
if( sides & 2 )
R_SplitEntityOnNode( node_child( node, 1, cl.worldmodel ));
}

/*
Expand Down
3 changes: 0 additions & 3 deletions engine/client/cl_render.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
switch( parm )
{
case PARM_BSP2_SUPPORTED:
#ifdef SUPPORT_BSP2_FORMAT
return 1;
#endif
return 0;
case PARAM_GAMEPAUSED:
return cl.paused;
case PARM_CLIENT_INGAME:
Expand Down
6 changes: 3 additions & 3 deletions engine/client/cl_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,8 @@ static void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int show
R_DrawNodeConnection( x, y, x + scale, y + scale );
}

R_ShowTree_r( node->children[1], x - scale, y + scale, downScale, shownodes, viewleaf );
R_ShowTree_r( node->children[0], x + scale, y + scale, downScale, shownodes, viewleaf );
R_ShowTree_r( node_child( node, 1, cl.worldmodel ), x - scale, y + scale, downScale, shownodes, viewleaf );
R_ShowTree_r( node_child( node, 0, cl.worldmodel ), x + scale, y + scale, downScale, shownodes, viewleaf );

world.recursion_level--;
}
Expand All @@ -482,7 +482,7 @@ static void R_ShowTree( void )
return;

world.recursion_level = 0;
viewleaf = Mod_PointInLeaf( refState.vieworg, cl.worldmodel->nodes );
viewleaf = Mod_PointInLeaf( refState.vieworg, cl.worldmodel->nodes, cl.worldmodel );

ref.dllFuncs.TriRenderMode( kRenderTransTexture );

Expand Down
50 changes: 33 additions & 17 deletions engine/client/mod_dbghulls.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,16 +470,16 @@ static void winding_split( winding_t *in, const mplane_t *split, winding_t **pfr
* This is a stack of the clipnodes we have traversed
* "sides" indicates which side we went down each time
*/
static mclipnode_t *node_stack[MAX_CLIPNODE_DEPTH];
static int node_stack[MAX_CLIPNODE_DEPTH];
static int side_stack[MAX_CLIPNODE_DEPTH];
static uint node_stack_depth;

static void push_node( mclipnode_t *node, int side )
static void push_node( int nodenum, int side )
{
if( node_stack_depth == MAX_CLIPNODE_DEPTH )
Host_Error( "node stack overflow\n" );

node_stack[node_stack_depth] = node;
node_stack[node_stack_depth] = nodenum;
side_stack[node_stack_depth] = side;
node_stack_depth++;
}
Expand All @@ -502,22 +502,27 @@ static void free_hull_polys( hullnode_t *hull_polys )
}
}

static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model );
static void hull_windings_r( hull_t *hull, int nodenum, hullnode_t *polys, hull_model_t *model );

static void do_hull_recursion( hull_t *hull, mclipnode_t *node, int side, hullnode_t *polys, hull_model_t *model )
static void do_hull_recursion( hull_t *hull, int nodenum, int side, hullnode_t *polys, hull_model_t *model )
{
winding_t *w, *next;
int childnum;

if( node->children[side] >= 0 )
if( world.version == QBSP2_VERSION )
childnum = hull->clipnodes32[nodenum].children[side];
else
childnum = hull->clipnodes16[nodenum].children[side];

if( childnum >= 0 )
{
mclipnode_t *child = hull->clipnodes + node->children[side];
push_node( node, side );
hull_windings_r( hull, child, polys, model );
push_node( nodenum, side );
hull_windings_r( hull, childnum, polys, model );
pop_node();
}
else
{
switch( node->children[side] )
switch( childnum )
{
case CONTENTS_EMPTY:
case CONTENTS_WATER:
Expand All @@ -542,20 +547,25 @@ static void do_hull_recursion( hull_t *hull, mclipnode_t *node, int side, hullno
}
break;
default:
Host_Error( "bad contents: %i\n", node->children[side] );
Host_Error( "bad contents: %i\n", childnum );
break;
}
}
}

static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model )
static void hull_windings_r( hull_t *hull, int nodenum, hullnode_t *polys, hull_model_t *model )
{
mplane_t *plane = hull->planes + node->planenum;
mplane_t *plane;
hullnode_t frontlist = LIST_HEAD_INIT( frontlist );
hullnode_t backlist = LIST_HEAD_INIT( backlist );
winding_t *w, *next, *front, *back;
int i;

if( world.version == QBSP2_VERSION )
plane = hull->planes + hull->clipnodes32[nodenum].planenum;
else
plane = hull->planes + hull->clipnodes16[nodenum].planenum;

list_for_each_entry_safe( w, next, polys, chain )
{
// PARANIOA - PAIR CHECK
Expand Down Expand Up @@ -601,7 +611,13 @@ static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys,

for( i = 0; w && i < node_stack_depth; i++ )
{
mplane_t *p = hull->planes + node_stack[i]->planenum;
mplane_t *p;

if( world.version == QBSP2_VERSION )
p = hull->planes + hull->clipnodes32[node_stack[i]].planenum;
else
p = hull->planes + hull->clipnodes16[node_stack[i]].planenum;

w = winding_clip( w, p, false, side_stack[i], 0.00001 );
}

Expand All @@ -625,8 +641,8 @@ static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys,
Con_Printf( S_WARN "new winding was clipped away!\n" );
}

do_hull_recursion( hull, node, 0, &frontlist, model );
do_hull_recursion( hull, node, 1, &backlist, model );
do_hull_recursion( hull, nodenum, 0, &frontlist, model );
do_hull_recursion( hull, nodenum, 1, &backlist, model );
}

static void remove_paired_polys( hull_model_t *model )
Expand Down Expand Up @@ -655,7 +671,7 @@ static void make_hull_windings( hull_t *hull, hull_model_t *model )

if( hull->planes != NULL )
{
hull_windings_r( hull, hull->clipnodes + hull->firstclipnode, &head, model );
hull_windings_r( hull, hull->firstclipnode, &head, model );
remove_paired_polys( model );
}
Con_Reportf( "%i hull polys\n", model->num_polys );
Expand Down
Loading
Loading