support "extended nodes"

This converts some variables to their unsidged types, which enables
the port to load all maps which use the regular Doom BSP nodes format.

This enables the port to load some maps that it would normally choke
upon, e.g. Nova Maps 30 and 31; Eviternity Map 15 and Sunlust Maps 16,
18, 20, 24, 28 and 31.

It does still not support DeePBSP and ZDBSP nodes, and will probably
never do.

Fixes #23.
This commit is contained in:
Fabian Greffrath 2020-01-09 21:05:04 +01:00
parent b7b15098b0
commit 5a314ae831
7 changed files with 53 additions and 36 deletions

View File

@ -75,12 +75,12 @@ typedef struct {
// A LineDef, as used for editing, and as input to the BSP builder. // A LineDef, as used for editing, and as input to the BSP builder.
typedef struct { typedef struct {
short v1; unsigned short v1;
short v2; unsigned short v2;
short flags; unsigned short flags;
short special; short special;
short tag; short tag;
short sidenum[2]; // sidenum[1] will be -1 if one sided unsigned short sidenum[2]; // sidenum[1] will be -1 (NO_INDEX) if one sided
} maplinedef_t; } maplinedef_t;
// //
@ -140,17 +140,17 @@ typedef struct {
// SubSector, as generated by BSP. // SubSector, as generated by BSP.
typedef struct { typedef struct {
short numsegs; unsigned short numsegs;
short firstseg; // Index of first one; segs are stored sequentially. unsigned short firstseg; // Index of first one; segs are stored sequentially.
} mapsubsector_t; } mapsubsector_t;
// LineSeg, generated by splitting LineDefs // LineSeg, generated by splitting LineDefs
// using partition lines selected by BSP builder. // using partition lines selected by BSP builder.
typedef struct { typedef struct {
short v1; unsigned short v1;
short v2; unsigned short v2;
short angle; short angle;
short linedef; unsigned short linedef;
short side; short side;
short offset; short offset;
} mapseg_t; } mapseg_t;
@ -158,7 +158,9 @@ typedef struct {
// BSP node structure. // BSP node structure.
// Indicate a leaf. // Indicate a leaf.
#define NF_SUBSECTOR 0x8000 #define NF_SUBSECTOR 0x80000000
// [FG] extended nodes
#define NO_INDEX ((unsigned short)-1)
typedef struct { typedef struct {
short x; // Partition line from (x,y) to x+dx,y+dy) short x; // Partition line from (x,y) to x+dx,y+dy)

View File

@ -439,7 +439,7 @@ int EV_VerticalDoor(line_t *line, mobj_t *thing)
} }
// if the wrong side of door is pushed, give oof sound // if the wrong side of door is pushed, give oof sound
if (line->sidenum[1]==-1) // killough if (line->sidenum[1]==NO_INDEX) // killough
{ {
S_StartSound(player->mo,sfx_oof); // killough 3/20/98 S_StartSound(player->mo,sfx_oof); // killough 3/20/98
return 0; return 0;

View File

@ -160,7 +160,7 @@ sector_t *openbacksector; // made global
void P_LineOpening(line_t *linedef) void P_LineOpening(line_t *linedef)
{ {
if (linedef->sidenum[1] == -1) // single sided line if (linedef->sidenum[1] == NO_INDEX) // single sided line
{ {
openrange = 0; openrange = 0;
return; return;

View File

@ -115,10 +115,10 @@ void P_ArchiveWorld (void)
for (i=0; i<numlines; i++) for (i=0; i<numlines; i++)
{ {
if (lines[i].sidenum[0] != -1) if (lines[i].sidenum[0] != NO_INDEX)
size += size +=
sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset;
if (lines[i].sidenum[1] != -1) if (lines[i].sidenum[1] != NO_INDEX)
size += size +=
sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset;
} }
@ -155,7 +155,7 @@ void P_ArchiveWorld (void)
*put++ = li->tag; *put++ = li->tag;
for (j=0; j<2; j++) for (j=0; j<2; j++)
if (li->sidenum[j] != -1) if (li->sidenum[j] != NO_INDEX)
{ {
si = &sides[li->sidenum[j]]; si = &sides[li->sidenum[j]];
@ -221,7 +221,7 @@ void P_UnArchiveWorld (void)
li->special = *get++; li->special = *get++;
li->tag = *get++; li->tag = *get++;
for (j=0 ; j<2 ; j++) for (j=0 ; j<2 ; j++)
if (li->sidenum[j] != -1) if (li->sidenum[j] != NO_INDEX)
{ {
side_t *si = &sides[li->sidenum[j]]; side_t *si = &sides[li->sidenum[j]];

View File

@ -164,12 +164,12 @@ void P_LoadSegs (int lump)
int side, linedef; int side, linedef;
line_t *ldef; line_t *ldef;
li->v1 = &vertexes[SHORT(ml->v1)]; li->v1 = &vertexes[(unsigned short)SHORT(ml->v1)];
li->v2 = &vertexes[SHORT(ml->v2)]; li->v2 = &vertexes[(unsigned short)SHORT(ml->v2)];
li->angle = (SHORT(ml->angle))<<16; li->angle = (SHORT(ml->angle))<<16;
li->offset = (SHORT(ml->offset))<<16; li->offset = (SHORT(ml->offset))<<16;
linedef = SHORT(ml->linedef); linedef = (unsigned short)SHORT(ml->linedef);
ldef = &lines[linedef]; ldef = &lines[linedef];
li->linedef = ldef; li->linedef = ldef;
side = SHORT(ml->side); side = SHORT(ml->side);
@ -177,7 +177,7 @@ void P_LoadSegs (int lump)
li->frontsector = sides[ldef->sidenum[side]].sector; li->frontsector = sides[ldef->sidenum[side]].sector;
// killough 5/3/98: ignore 2s flag if second sidedef missing: // killough 5/3/98: ignore 2s flag if second sidedef missing:
if (ldef->flags & ML_TWOSIDED && ldef->sidenum[side^1]!=-1) if (ldef->flags & ML_TWOSIDED && ldef->sidenum[side^1]!=NO_INDEX)
li->backsector = sides[ldef->sidenum[side^1]].sector; li->backsector = sides[ldef->sidenum[side^1]].sector;
else else
li->backsector = 0; li->backsector = 0;
@ -204,8 +204,8 @@ void P_LoadSubsectors (int lump)
for (i=0; i<numsubsectors; i++) for (i=0; i<numsubsectors; i++)
{ {
subsectors[i].numlines = SHORT(((mapsubsector_t *) data)[i].numsegs ); subsectors[i].numlines = (unsigned short)SHORT(((mapsubsector_t *) data)[i].numsegs );
subsectors[i].firstline = SHORT(((mapsubsector_t *) data)[i].firstseg); subsectors[i].firstline = (unsigned short)SHORT(((mapsubsector_t *) data)[i].firstseg);
} }
Z_Free (data); Z_Free (data);
@ -296,7 +296,22 @@ void P_LoadNodes (int lump)
for (j=0 ; j<2 ; j++) for (j=0 ; j<2 ; j++)
{ {
int k; int k;
no->children[j] = SHORT(mn->children[j]); no->children[j] = (unsigned short)SHORT(mn->children[j]);
// [FG] extended nodes
if (no->children[j] == 0xFFFF)
no->children[j] = -1;
else
if (no->children[j] & 0x8000)
{
no->children[j] &= ~0x8000;
if (no->children[j] >= numsubsectors)
no->children[j] = 0;
no->children[j] |= NF_SUBSECTOR;
}
for (k=0 ; k<4 ; k++) for (k=0 ; k<4 ; k++)
no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS; no->bbox[j][k] = SHORT(mn->bbox[j][k])<<FRACBITS;
} }
@ -377,11 +392,11 @@ void P_LoadLineDefs (int lump)
line_t *ld = lines+i; line_t *ld = lines+i;
vertex_t *v1, *v2; vertex_t *v1, *v2;
ld->flags = SHORT(mld->flags); ld->flags = (unsigned short)SHORT(mld->flags);
ld->special = SHORT(mld->special); ld->special = SHORT(mld->special);
ld->tag = SHORT(mld->tag); ld->tag = SHORT(mld->tag);
v1 = ld->v1 = &vertexes[SHORT(mld->v1)]; v1 = ld->v1 = &vertexes[(unsigned short)SHORT(mld->v1)];
v2 = ld->v2 = &vertexes[SHORT(mld->v2)]; v2 = ld->v2 = &vertexes[(unsigned short)SHORT(mld->v2)];
ld->dx = v2->x - v1->x; ld->dx = v2->x - v1->x;
ld->dy = v2->y - v1->y; ld->dy = v2->y - v1->y;
@ -416,7 +431,7 @@ void P_LoadLineDefs (int lump)
ld->sidenum[1] = SHORT(mld->sidenum[1]); ld->sidenum[1] = SHORT(mld->sidenum[1]);
// killough 4/4/98: support special sidedef interpretation below // killough 4/4/98: support special sidedef interpretation below
if (ld->sidenum[0] != -1 && ld->special) if (ld->sidenum[0] != NO_INDEX && ld->special)
sides[*ld->sidenum].special = ld->special; sides[*ld->sidenum].special = ld->special;
} }
Z_Free (data); Z_Free (data);
@ -433,14 +448,14 @@ void P_LoadLineDefs2(int lump)
{ {
// killough 11/98: fix common wad errors (missing sidedefs): // killough 11/98: fix common wad errors (missing sidedefs):
if (ld->sidenum[0] == -1) if (ld->sidenum[0] == NO_INDEX)
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
if (ld->sidenum[1] == -1) if (ld->sidenum[1] == NO_INDEX)
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
ld->frontsector = ld->sidenum[0]!=-1 ? sides[ld->sidenum[0]].sector : 0; ld->frontsector = ld->sidenum[0]!=NO_INDEX ? sides[ld->sidenum[0]].sector : 0;
ld->backsector = ld->sidenum[1]!=-1 ? sides[ld->sidenum[1]].sector : 0; ld->backsector = ld->sidenum[1]!=NO_INDEX ? sides[ld->sidenum[1]].sector : 0;
switch (ld->special) switch (ld->special)
{ // killough 4/11/98: handle special types { // killough 4/11/98: handle special types
int lump, j; int lump, j;

View File

@ -214,7 +214,7 @@ int twoSided(int sector, int line)
//has two sidedefs, rather than whether the 2S flag is set //has two sidedefs, rather than whether the 2S flag is set
return comp[comp_model] ? sectors[sector].lines[line]->flags & ML_TWOSIDED : return comp[comp_model] ? sectors[sector].lines[line]->flags & ML_TWOSIDED :
sectors[sector].lines[line]->sidenum[1] != -1; sectors[sector].lines[line]->sidenum[1] != NO_INDEX;
} }
// //

View File

@ -181,10 +181,10 @@ typedef struct line_s
{ {
vertex_t *v1, *v2; // Vertices, from v1 to v2. vertex_t *v1, *v2; // Vertices, from v1 to v2.
fixed_t dx, dy; // Precalculated v2 - v1 for side checking. fixed_t dx, dy; // Precalculated v2 - v1 for side checking.
short flags; // Animation related. unsigned short flags; // Animation related.
short special; short special;
short tag; short tag;
short sidenum[2]; // Visual appearance: SideDefs. unsigned short sidenum[2]; // Visual appearance: SideDefs.
fixed_t bbox[4]; // A bounding box, for the linedef's extent fixed_t bbox[4]; // A bounding box, for the linedef's extent
slopetype_t slopetype; // To aid move clipping. slopetype_t slopetype; // To aid move clipping.
sector_t *frontsector; // Front and back sector. sector_t *frontsector; // Front and back sector.
@ -206,7 +206,7 @@ typedef struct line_s
typedef struct subsector_s typedef struct subsector_s
{ {
sector_t *sector; sector_t *sector;
short numlines, firstline; int numlines, firstline;
} subsector_t; } subsector_t;
// phares 3/14/98 // phares 3/14/98
@ -262,7 +262,7 @@ typedef struct
{ {
fixed_t x, y, dx, dy; // Partition line. fixed_t x, y, dx, dy; // Partition line.
fixed_t bbox[2][4]; // Bounding box for each child. fixed_t bbox[2][4]; // Bounding box for each child.
unsigned short children[2]; // If NF_SUBSECTOR its a subsector. int children[2]; // If NF_SUBSECTOR its a subsector.
} node_t; } node_t;
// posts are runs of non masked source pixels // posts are runs of non masked source pixels