From 5a314ae831eefb2447f7cc877c42a4e5b7bb4007 Mon Sep 17 00:00:00 2001 From: Fabian Greffrath Date: Thu, 9 Jan 2020 21:05:04 +0100 Subject: [PATCH] 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. --- Source/doomdata.h | 22 ++++++++++++---------- Source/p_doors.c | 2 +- Source/p_maputl.c | 2 +- Source/p_saveg.c | 8 ++++---- Source/p_setup.c | 45 ++++++++++++++++++++++++++++++--------------- Source/p_spec.c | 2 +- Source/r_defs.h | 8 ++++---- 7 files changed, 53 insertions(+), 36 deletions(-) diff --git a/Source/doomdata.h b/Source/doomdata.h index 09af4b9b..1f8a97fe 100644 --- a/Source/doomdata.h +++ b/Source/doomdata.h @@ -75,12 +75,12 @@ typedef struct { // A LineDef, as used for editing, and as input to the BSP builder. typedef struct { - short v1; - short v2; - short flags; + unsigned short v1; + unsigned short v2; + unsigned short flags; short special; 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; // @@ -140,17 +140,17 @@ typedef struct { // SubSector, as generated by BSP. typedef struct { - short numsegs; - short firstseg; // Index of first one; segs are stored sequentially. + unsigned short numsegs; + unsigned short firstseg; // Index of first one; segs are stored sequentially. } mapsubsector_t; // LineSeg, generated by splitting LineDefs // using partition lines selected by BSP builder. typedef struct { - short v1; - short v2; + unsigned short v1; + unsigned short v2; short angle; - short linedef; + unsigned short linedef; short side; short offset; } mapseg_t; @@ -158,7 +158,9 @@ typedef struct { // BSP node structure. // Indicate a leaf. -#define NF_SUBSECTOR 0x8000 +#define NF_SUBSECTOR 0x80000000 + // [FG] extended nodes +#define NO_INDEX ((unsigned short)-1) typedef struct { short x; // Partition line from (x,y) to x+dx,y+dy) diff --git a/Source/p_doors.c b/Source/p_doors.c index fe6dc8a2..13748b73 100644 --- a/Source/p_doors.c +++ b/Source/p_doors.c @@ -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 (line->sidenum[1]==-1) // killough + if (line->sidenum[1]==NO_INDEX) // killough { S_StartSound(player->mo,sfx_oof); // killough 3/20/98 return 0; diff --git a/Source/p_maputl.c b/Source/p_maputl.c index 54d7fc33..2385bf8e 100644 --- a/Source/p_maputl.c +++ b/Source/p_maputl.c @@ -160,7 +160,7 @@ sector_t *openbacksector; // made global 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; return; diff --git a/Source/p_saveg.c b/Source/p_saveg.c index b2760d66..271d3e4f 100644 --- a/Source/p_saveg.c +++ b/Source/p_saveg.c @@ -115,10 +115,10 @@ void P_ArchiveWorld (void) for (i=0; itextureoffset + sizeof si->rowoffset; - if (lines[i].sidenum[1] != -1) + if (lines[i].sidenum[1] != NO_INDEX) size += sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; } @@ -155,7 +155,7 @@ void P_ArchiveWorld (void) *put++ = li->tag; for (j=0; j<2; j++) - if (li->sidenum[j] != -1) + if (li->sidenum[j] != NO_INDEX) { si = &sides[li->sidenum[j]]; @@ -221,7 +221,7 @@ void P_UnArchiveWorld (void) li->special = *get++; li->tag = *get++; for (j=0 ; j<2 ; j++) - if (li->sidenum[j] != -1) + if (li->sidenum[j] != NO_INDEX) { side_t *si = &sides[li->sidenum[j]]; diff --git a/Source/p_setup.c b/Source/p_setup.c index 23fb91d0..fdbc3a44 100644 --- a/Source/p_setup.c +++ b/Source/p_setup.c @@ -164,12 +164,12 @@ void P_LoadSegs (int lump) int side, linedef; line_t *ldef; - li->v1 = &vertexes[SHORT(ml->v1)]; - li->v2 = &vertexes[SHORT(ml->v2)]; + li->v1 = &vertexes[(unsigned short)SHORT(ml->v1)]; + li->v2 = &vertexes[(unsigned short)SHORT(ml->v2)]; li->angle = (SHORT(ml->angle))<<16; li->offset = (SHORT(ml->offset))<<16; - linedef = SHORT(ml->linedef); + linedef = (unsigned short)SHORT(ml->linedef); ldef = &lines[linedef]; li->linedef = ldef; side = SHORT(ml->side); @@ -177,7 +177,7 @@ void P_LoadSegs (int lump) li->frontsector = sides[ldef->sidenum[side]].sector; // 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; else li->backsector = 0; @@ -204,8 +204,8 @@ void P_LoadSubsectors (int lump) for (i=0; ichildren[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++) no->bbox[j][k] = SHORT(mn->bbox[j][k])<flags = SHORT(mld->flags); + ld->flags = (unsigned short)SHORT(mld->flags); ld->special = SHORT(mld->special); ld->tag = SHORT(mld->tag); - v1 = ld->v1 = &vertexes[SHORT(mld->v1)]; - v2 = ld->v2 = &vertexes[SHORT(mld->v2)]; + v1 = ld->v1 = &vertexes[(unsigned short)SHORT(mld->v1)]; + v2 = ld->v2 = &vertexes[(unsigned short)SHORT(mld->v2)]; ld->dx = v2->x - v1->x; ld->dy = v2->y - v1->y; @@ -416,7 +431,7 @@ void P_LoadLineDefs (int lump) ld->sidenum[1] = SHORT(mld->sidenum[1]); // 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; } Z_Free (data); @@ -433,14 +448,14 @@ void P_LoadLineDefs2(int lump) { // 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 - if (ld->sidenum[1] == -1) + if (ld->sidenum[1] == NO_INDEX) ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side - ld->frontsector = ld->sidenum[0]!=-1 ? sides[ld->sidenum[0]].sector : 0; - ld->backsector = ld->sidenum[1]!=-1 ? sides[ld->sidenum[1]].sector : 0; + ld->frontsector = ld->sidenum[0]!=NO_INDEX ? sides[ld->sidenum[0]].sector : 0; + ld->backsector = ld->sidenum[1]!=NO_INDEX ? sides[ld->sidenum[1]].sector : 0; switch (ld->special) { // killough 4/11/98: handle special types int lump, j; diff --git a/Source/p_spec.c b/Source/p_spec.c index 35c47e34..1f358281 100644 --- a/Source/p_spec.c +++ b/Source/p_spec.c @@ -214,7 +214,7 @@ int twoSided(int sector, int line) //has two sidedefs, rather than whether the 2S flag is set 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; } // diff --git a/Source/r_defs.h b/Source/r_defs.h index df504b72..23f9fe0a 100644 --- a/Source/r_defs.h +++ b/Source/r_defs.h @@ -181,10 +181,10 @@ typedef struct line_s { vertex_t *v1, *v2; // Vertices, from v1 to v2. fixed_t dx, dy; // Precalculated v2 - v1 for side checking. - short flags; // Animation related. + unsigned short flags; // Animation related. short special; 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 slopetype_t slopetype; // To aid move clipping. sector_t *frontsector; // Front and back sector. @@ -206,7 +206,7 @@ typedef struct line_s typedef struct subsector_s { sector_t *sector; - short numlines, firstline; + int numlines, firstline; } subsector_t; // phares 3/14/98 @@ -262,7 +262,7 @@ typedef struct { fixed_t x, y, dx, dy; // Partition line. 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; // posts are runs of non masked source pixels