pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

doomlegacy-devel: Patch to support DeeP and ZDoom extended nodes



Module Name:	pkgsrc-wip
Committed By:	Michael Baeuerle <michael.baeuerle%stz-e.de@localhost>
Pushed By:	micha
Date:		Wed Apr 22 17:56:40 2020 +0200
Changeset:	cb74ce082c9bb1cd401e33dc3fda0c78b7a0193e

Modified Files:
	doomlegacy-devel/Makefile
	doomlegacy-devel/TODO
	doomlegacy-devel/distinfo
Added Files:
	doomlegacy-devel/files/p_extnodes.c
	doomlegacy-devel/files/p_extnodes.h
	doomlegacy-devel/patches/patch-src_Makefile
	doomlegacy-devel/patches/patch-src_doomdata.h
	doomlegacy-devel/patches/patch-src_p__setup.c
	doomlegacy-devel/patches/patch-src_r__defs.h

Log Message:
doomlegacy-devel: Patch to support DeeP and ZDoom extended nodes

Based on woof 1.2.0

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=cb74ce082c9bb1cd401e33dc3fda0c78b7a0193e

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 doomlegacy-devel/Makefile                     |   2 +
 doomlegacy-devel/TODO                         |   6 +
 doomlegacy-devel/distinfo                     |   4 +
 doomlegacy-devel/files/p_extnodes.c           | 574 ++++++++++++++++++++++++++
 doomlegacy-devel/files/p_extnodes.h           |  92 +++++
 doomlegacy-devel/patches/patch-src_Makefile   |  15 +
 doomlegacy-devel/patches/patch-src_doomdata.h |  26 ++
 doomlegacy-devel/patches/patch-src_p__setup.c | 114 +++++
 doomlegacy-devel/patches/patch-src_r__defs.h  |  40 ++
 9 files changed, 873 insertions(+)

diffs:
diff --git a/doomlegacy-devel/Makefile b/doomlegacy-devel/Makefile
index 4822a38291..a46f183bfe 100644
--- a/doomlegacy-devel/Makefile
+++ b/doomlegacy-devel/Makefile
@@ -80,6 +80,8 @@ pre-configure:
 	${CP} ${FILESDIR}/INSTALL.pkgsrc ${WRKDIR}
 	${CP} ${FILESDIR}/doomlegacy.sh ${WRKDIR}
 	${CP} ${FILESDIR}/doomlegacy.6.in ${WRKDIR}
+	${CP} ${FILESDIR}/p_extnodes.c ${WRKSRC}/src
+	${CP} ${FILESDIR}/p_extnodes.h ${WRKSRC}/src
 	cd ${WRKSRC} && ${CP} make_options_nix make_options
 
 # Move configure options and process manpage template
diff --git a/doomlegacy-devel/TODO b/doomlegacy-devel/TODO
index a3b953edf8..e21dc7d2f6 100644
--- a/doomlegacy-devel/TODO
+++ b/doomlegacy-devel/TODO
@@ -105,4 +105,10 @@ Part 6: Import final release
     Not released yet
 
 
+Part 7: Support for extended nodes
+==================================
+[X] Add patch to support DeeP and ZDoom extended nodes
+    This code is based on woof 1.2.0
+
+
 EOF
diff --git a/doomlegacy-devel/distinfo b/doomlegacy-devel/distinfo
index 1a9cfbc2e3..b8b3ee8f79 100644
--- a/doomlegacy-devel/distinfo
+++ b/doomlegacy-devel/distinfo
@@ -4,4 +4,8 @@ SHA1 (doomlegacy_1.47.2_common.zip) = 9e6faaea797b988565a078a47e80bbe2119d78b9
 RMD160 (doomlegacy_1.47.2_common.zip) = 1ac1f47563ad2c0d7c5c1bea93a2aaeb1c001c10
 SHA512 (doomlegacy_1.47.2_common.zip) = 7c7c2a0cbab5b9b4645a3fe166addd597de533db7ab41f8011c6c526a868bb04c8dd6b0d27b48765406fbab328bf64fc7827770b395e6c0e5d861d99c4d3865a
 Size (doomlegacy_1.47.2_common.zip) = 981654 bytes
+SHA1 (patch-src_Makefile) = efe91a6966412a9c1a92c4d239e2e8ae4eaa6bf6
 SHA1 (patch-src_am__map.c) = 8d7d17d29c0934c92ca933e8976a5ecc692e465d
+SHA1 (patch-src_doomdata.h) = 662d580457440fff338c683a76581b6d8973f8e5
+SHA1 (patch-src_p__setup.c) = 9bdd3c882871cf3d49e2f8ef99d92715d1afe64b
+SHA1 (patch-src_r__defs.h) = bd3846096127cfd7f99f541e0e94b79b5ca8229a
diff --git a/doomlegacy-devel/files/p_extnodes.c b/doomlegacy-devel/files/p_extnodes.c
new file mode 100644
index 0000000000..fa41b95d52
--- /dev/null
+++ b/doomlegacy-devel/files/p_extnodes.c
@@ -0,0 +1,574 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: r_defs.h,v 1.18 1998/04/27 02:12:59 killough Exp $
+//
+//  Copyright (C) 1999 by
+//  id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
+//  Copyright(C) 2015-2020 Fabian Greffrath
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
+//  02111-1307, USA.
+//
+//  DESCRIPTION:
+//  Support maps with NODES in compressed or uncompressed ZDBSP format or
+//  DeePBSP format.
+//
+//-----------------------------------------------------------------------------
+
+// [MB] 2020-04-21: Support for ZDoom extended nodes based on woof 1.2.0
+//      Modified to use C99 fixed width data types
+//      Added some checks taken from DooM Legacy code for regular nodes
+//      Fixed endianess and use LE_SWAP* macros
+//      Added #ifdef switches for all code that requires zlib
+
+// [FG] support maps with NODES in compressed ZDBSP format
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif  // HAVE_ZLIB
+
+#include "doomincl.h"
+
+#include "m_swap.h"
+#include "r_main.h"
+#include "r_splats.h"  // [MB] 2020-04-21: Added for hardware renderer
+#include "w_wad.h"
+#include "z_zone.h"
+
+#include "p_extnodes.h"
+
+// [crispy] support maps with NODES in DeePBSP format
+
+typedef PACKED_STRUCT (
+{
+    int32_t v1;
+    int32_t v2;
+    uint16_t angle;
+    uint16_t linedef;
+    int16_t side;
+    uint16_t offset;
+}) mapseg_deepbsp_t;
+
+typedef PACKED_STRUCT (
+{
+    int16_t x;
+    int16_t y;
+    int16_t dx;
+    int16_t dy;
+    int16_t bbox[2][4];
+    int32_t children[2];
+}) mapnode_deepbsp_t;
+
+typedef PACKED_STRUCT (
+{
+    uint16_t numsegs;
+    int32_t firstseg;
+}) mapsubsector_deepbsp_t;
+
+// [crispy] support maps with NODES in ZDBSP format
+
+typedef PACKED_STRUCT (
+{
+    int32_t v1, v2;
+    uint16_t linedef;
+    unsigned char side;
+}) mapseg_zdbsp_t;
+
+typedef PACKED_STRUCT (
+{
+    int16_t x;
+    int16_t y;
+    int16_t dx;
+    int16_t dy;
+    int16_t bbox[2][4];
+    int32_t children[2];
+}) mapnode_zdbsp_t;
+
+typedef PACKED_STRUCT (
+{
+    unsigned int numsegs;
+}) mapsubsector_zdbsp_t;
+
+// [FG] support maps with NODES in compressed or uncompressed ZDBSP format
+//      or DeePBSP format
+
+mapformat_t P_CheckMapFormat (int lumpnum)
+{
+    mapformat_t format = MFMT_DOOMBSP;
+    byte *nodes = NULL;
+    int b;
+
+#if 0  // [MB] 2020-04-21: Hexen format was already checked in p_setup.c
+    if ((b = lumpnum+ML_BLOCKMAP+1) < numlumps &&
+        !strcasecmp(lumpinfo[b].name, "BEHAVIOR"))
+        I_Error("P_CheckMapFormat: Hexen map format not supported in %s.\n",
+                lumpinfo[lumpnum-ML_NODES].name);
+#endif
+
+    // [MB] 2020-04-21: Check for <numlumps removed (numlumps not available)
+    b = lumpnum+ML_NODES;
+    if ((nodes = W_CacheLumpNum(b, PU_STATIC)) && W_LumpLength(b) > 8)
+    {
+        if (!memcmp(nodes, "xNd4\0\0\0\0", 8))
+            format = MFMT_DEEPBSP;
+        else if (!memcmp(nodes, "XNOD", 4))
+            format = MFMT_ZDBSPX;
+        else if (!memcmp(nodes, "ZNOD", 4))
+            format = MFMT_ZDBSPZ;
+    }
+
+    if (nodes)
+        Z_Free(nodes);
+
+    return format;
+}
+
+// [FG] recalculate seg offsets
+
+static fixed_t GetOffset(vertex_t *v1, vertex_t *v2)
+{
+    fixed_t dx, dy;
+    fixed_t r;
+
+    dx = (v1->x - v2->x)>>FRACBITS;
+    dy = (v1->y - v2->y)>>FRACBITS;
+    r = (fixed_t)(sqrt(dx*dx + dy*dy))<<FRACBITS;
+
+    return r;
+}
+
+// [FG] support maps with DeePBSP nodes
+
+void P_LoadSegs_DeePBSP (int lump)
+{
+    int  i;
+    byte *data;
+    int32_t vn1, vn2;
+
+    numsegs = W_LumpLength(lump) / sizeof(mapseg_deepbsp_t);
+    segs = Z_Malloc(numsegs*sizeof(seg_t),PU_LEVEL,0);
+    memset(segs, 0, numsegs*sizeof(seg_t));
+    data = W_CacheLumpNum(lump,PU_STATIC);
+
+    for (i=0; i<numsegs; i++)
+    {
+        seg_t *li = segs+i;
+        mapseg_deepbsp_t *ml = (mapseg_deepbsp_t *) data + i;
+
+        int side, linedef;
+        line_t *ldef;
+
+        vn1 = LE_SWAP32(ml->v1);
+        vn2 = LE_SWAP32(ml->v2);
+        // [MB] 2020-04-21: Detect buggy wad (same as for normal nodes)
+        if( vn1 > numvertexes || vn2 > numvertexes )
+        {
+            I_SoftError("P_LoadSegs_DeePBSP: Seg vertex bad %i,%i\n",
+                        (int) vn1, (int) vn2 );
+            // zero both out together, make seg safer
+            // (otherwise will cross another line)
+            vn1 = vn2 = 0;
+        }
+        li->v1 = &vertexes[vn1];
+        li->v2 = &vertexes[vn2];
+
+#ifdef HWRENDER
+        // [MB] 2020-04-21: Added (same as for normal nodes)
+        li->pv1 = li->pv2 = NULL;
+        li->length = P_SegLength (li);
+        li->lightmaps = NULL; // list of static lightmap for this seg
+#endif
+
+        li->angle = ((uint16_t)( LE_SWAP16(ml->angle) ))<<16;
+        li->offset = (LE_SWAP16(ml->offset))<<16;
+        linedef = (uint16_t)( LE_SWAP16(ml->linedef) );
+
+        // [MB] 2020-04-21: Detect buggy wad (same as for normal nodes)
+        if( linedef > numlines )
+        {
+            I_SoftError( "P_LoadSegs_DeePBSP: linedef #%i > numlines %i\n",
+                         linedef, numlines );
+            linedef = 0; // default
+        }
+
+        ldef = &lines[linedef];
+        li->linedef = ldef;
+        side = LE_SWAP16(ml->side);
+
+        // [MB] 2020-04-21: Detect buggy wad (same as for normal nodes)
+        if( side != 0 && side != 1 )
+        {
+            I_SoftError( "P_LoadSegs_DeePBSP: bad side index\n");
+            side = 0;  // assume was using wrong side
+        }
+        // side1 required to have sidenum != NULL_INDEX
+        if( ldef->sidenum[side] == NULL_INDEX )
+        {
+            I_SoftError( "P_LoadSegs_DeePBSP: using missing sidedef\n");
+            side = 0;  // assume was using wrong side
+        }
+
+        li->side = side;
+        li->sidedef = &sides[ldef->sidenum[side]];
+        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]!=NULL_INDEX)
+            li->backsector = sides[ldef->sidenum[side^1]].sector;
+        else
+            li->backsector = 0;
+
+        // [MB] 2020-04-21: Added (same as for normal nodes)
+        li->numlights = 0;
+        li->rlights = NULL;
+    }
+
+    Z_Free (data);
+}
+
+void P_LoadSubsectors_DeePBSP (int lump)
+{
+    mapsubsector_deepbsp_t *data;
+    int  i;
+
+    numsubsectors = W_LumpLength (lump) / sizeof(mapsubsector_deepbsp_t);
+    subsectors = Z_Malloc(numsubsectors*sizeof(subsector_t),PU_LEVEL,0);
+    data = (mapsubsector_deepbsp_t *)W_CacheLumpNum(lump, PU_STATIC);
+
+    memset(subsectors, 0, numsubsectors*sizeof(subsector_t));
+
+    for (i=0; i<numsubsectors; i++)
+    {
+        subsectors[i].numlines = (uint16_t)( LE_SWAP16(data[i].numsegs) );
+        subsectors[i].firstline = (uint32_t)( LE_SWAP32(data[i].firstseg) );
+    }
+
+    Z_Free (data);
+}
+
+void P_LoadNodes_DeePBSP (int lump)
+{
+    byte *data;
+    int  i;
+
+    numnodes = W_LumpLength (lump) / sizeof(mapnode_deepbsp_t);
+    nodes = Z_Malloc (numnodes*sizeof(node_t),PU_LEVEL,0);
+    data = W_CacheLumpNum (lump, PU_STATIC);
+
+    // [FG] skip header
+    data += 8;
+
+    // [MB] 2020-04-21: Added similar check as for normal nodes
+    // No nodes and one subsector is a trivial but legal map.
+    if( (numnodes < 1) && (numsubsectors > 1) )
+    {
+        I_SoftError("P_LoadNodes_DeePBSP: Bad node data\n");
+        return;
+    }
+
+    for (i=0; i<numnodes; i++)
+    {
+        node_t *no = nodes + i;
+        mapnode_deepbsp_t *mn = (mapnode_deepbsp_t *) data + i;
+        int j;
+
+        no->x = LE_SWAP16(mn->x)<<FRACBITS;
+        no->y = LE_SWAP16(mn->y)<<FRACBITS;
+        no->dx = LE_SWAP16(mn->dx)<<FRACBITS;
+        no->dy = LE_SWAP16(mn->dy)<<FRACBITS;
+
+        for (j=0 ; j<2 ; j++)
+        {
+            int k;
+            no->children[j] = LE_SWAP32(mn->children[j]);
+
+            for (k=0 ; k<4 ; k++)
+                no->bbox[j][k] = LE_SWAP16(mn->bbox[j][k])<<FRACBITS;
+        }
+    }
+
+    W_CacheLumpNum(lump, PU_CACHE);
+}
+
+// [FG] support maps with compressed or uncompressed ZDBSP nodes
+// adapted from prboom-plus/src/p_setup.c:1040-1331
+// heavily modified, condensed and simplyfied
+// - removed most paranoid checks, brought in line with Vanilla P_LoadNodes()
+// - removed const type punning pointers
+// - inlined P_LoadZSegs()
+// - added support for compressed ZDBSP nodes
+// - added support for flipped levels
+
+void P_LoadNodes_ZDBSP (int lump, boolean compressed)
+{
+    byte *data;
+    uint32_t i;
+#ifdef HAVE_ZLIB
+    byte *output;
+#endif  // HAVE_ZLIB
+
+    uint32_t orgVerts, newVerts;
+    uint32_t numSubs, currSeg;
+    uint32_t numSegs;
+    uint32_t numNodes;
+    vertex_t *newvertarray = NULL;
+
+    data = W_CacheLumpNum(lump, PU_LEVEL);
+
+    // 0. Uncompress nodes lump (or simply skip header)
+
+    if (compressed)
+    {
+#ifdef HAVE_ZLIB
+        const int len =  W_LumpLength(lump);
+        int outlen, err;
+        z_stream *zstream;
+
+        // first estimate for compression rate:
+        // output buffer size == 2.5 * input size
+        outlen = 2.5 * len;
+        output = Z_Malloc(outlen, PU_STATIC, 0);
+
+        // initialize stream state for decompression
+        zstream = malloc(sizeof(*zstream));
+        if (NULL == zstream)
+            I_Error("P_LoadNodes: "
+                    "Out of memory during ZDBSP nodes decrompression!");
+        memset(zstream, 0, sizeof(*zstream));
+        zstream->next_in = data + 4;
+        zstream->avail_in = len - 4;
+        zstream->next_out = output;
+        zstream->avail_out = outlen;
+
+        if (inflateInit(zstream) != Z_OK)
+            I_Error("P_LoadNodes: "
+                    "Error during ZDBSP nodes decompression initialization!");
+
+        // resize if output buffer runs full
+        while ((err = inflate(zstream, Z_SYNC_FLUSH)) == Z_OK)
+        {
+            int outlen_old = outlen;
+            outlen = 2 * outlen_old;
+            output = Z_Realloc(output, outlen, PU_STATIC, 0);
+            zstream->next_out = output + outlen_old;
+            zstream->avail_out = outlen - outlen_old;
+        }
+
+        if (err != Z_STREAM_END)
+            I_Error("P_LoadNodes: Error during ZDBSP nodes decompression!");
+
+        GenPrintf(EMSG_info,
+                  "P_LoadNodes: ZDBSP nodes compression ratio %.3f\n",
+                  (float)zstream->total_out/zstream->total_in);
+
+        data = output;
+
+        if (inflateEnd(zstream) != Z_OK)
+            I_Error("P_LoadNodes: "
+                    "Error during ZDBSP nodes decompression shut-down!");
+
+        // release the original data lump
+        W_CacheLumpNum(lump, PU_CACHE);
+        free(zstream);
+#else  // HAVE_ZLIB
+        I_Error("P_LoadNodes: ZDBSP nodes decompression requires zlib!");
+#endif  // HAVE_ZLIB
+    }
+    else
+    {
+        // skip header
+        data += 4;
+    }
+
+    // 1. Load new vertices added during node building
+
+    orgVerts = (uint32_t)LE_SWAP32(*((uint32_t*)data));
+    data += sizeof(orgVerts);
+
+    newVerts = (uint32_t)LE_SWAP32(*((uint32_t*)data));
+    data += sizeof(newVerts);
+
+    if (orgVerts + newVerts == (unsigned int)numvertexes)
+    {
+        newvertarray = vertexes;
+    }
+    else
+    {
+        newvertarray = Z_Malloc((orgVerts + newVerts) * sizeof(vertex_t),
+                                 PU_LEVEL, 0);
+        memcpy(newvertarray, vertexes, orgVerts * sizeof(vertex_t));
+        memset(newvertarray + orgVerts, 0, newVerts * sizeof(vertex_t));
+    }
+
+    for (i = 0; i < newVerts; i++)
+    {
+#if 0  // [MB] 2020-04-21: DooM Legacy has no separate renderer coordinates
+        newvertarray[i + orgVerts].r_x =
+#endif
+            newvertarray[i + orgVerts].x = LE_SWAP32(*((uint32_t*)data));
+        data += sizeof(newvertarray[0].x);
+
+#if 0  // [MB] 2020-04-21: DooM Legacy has no separate renderer coordinates
+        newvertarray[i + orgVerts].r_y =
+#endif
+            newvertarray[i + orgVerts].y = LE_SWAP32(*((uint32_t*)data));
+        data += sizeof(newvertarray[0].y);
+    }
+
+    if (vertexes != newvertarray)
+    {
+        for (i = 0; i < (uint32_t)numlines; i++)
+        {
+            lines[i].v1 = lines[i].v1 - vertexes + newvertarray;
+            lines[i].v2 = lines[i].v2 - vertexes + newvertarray;
+        }
+
+        Z_Free(vertexes);
+        vertexes = newvertarray;
+        numvertexes = (int)(orgVerts + newVerts);
+    }
+
+    // 2. Load subsectors
+
+    numSubs = (uint32_t)LE_SWAP32(*((uint32_t*)data));
+    data += sizeof(numSubs);
+
+    if (0 == numSubs)
+        I_Error("P_LoadNodes_ZDBSP: No subsectors in map!");
+
+    numsubsectors = (int)numSubs;
+    subsectors = Z_Malloc(numsubsectors * sizeof(subsector_t), PU_LEVEL, 0);
+
+    for (i = currSeg = 0; i < numsubsectors; i++)
+    {
+        mapsubsector_zdbsp_t *mseg = (mapsubsector_zdbsp_t*) data + i;
+
+        subsectors[i].firstline = currSeg;
+        subsectors[i].numlines = (uint32_t)LE_SWAP32(mseg->numsegs);
+        currSeg += (uint32_t)LE_SWAP32(mseg->numsegs);
+    }
+
+    data += numsubsectors * sizeof(mapsubsector_zdbsp_t);
+
+    // 3. Load segs
+
+    numSegs = (uint32_t)LE_SWAP32(*((uint32_t*)data));
+    data += sizeof(numSegs);
+
+    // The number of stored segs should match the number of segs used by
+    // subsectors
+    if (numSegs != currSeg)
+    {
+        I_Error("P_LoadNodes_ZDBSP: Incorrect number of segs in ZDBSP nodes!");
+    }
+
+    numsegs = (int)numSegs;
+    segs = Z_Malloc(numsegs * sizeof(seg_t), PU_LEVEL, 0);
+
+    for (i = 0; i < (uint32_t)numsegs; i++)
+    {
+        line_t *ldef;
+        unsigned int linedef;
+        unsigned char side;
+        seg_t *li = segs + i;
+        mapseg_zdbsp_t *ml = (mapseg_zdbsp_t *) data + i;
+        int32_t vn1, vn2;
+
+        vn1 = LE_SWAP32(ml->v1);
+        vn2 = LE_SWAP32(ml->v2);
+        // [MB] 2020-04-21: Detect buggy wad (same as for normal nodes)
+        if( vn1 > numvertexes || vn2 > numvertexes )
+        {
+            I_SoftError("P_LoadSegs_ZDBSP: Seg vertex bad %i,%i\n",
+                        (int) vn1, (int) vn2 );
+            // zero both out together, make seg safer
+            // (otherwise will cross another line)
+            vn1 = vn2 = 0;
+        }
+        li->v1 = &vertexes[vn1];
+        li->v2 = &vertexes[vn2];
+
+#ifdef HWRENDER
+        // [MB] 2020-04-22: Added (same as for normal nodes)
+        li->pv1 = li->pv2 = NULL;
+        li->length = P_SegLength (li);
+        li->lightmaps = NULL; // list of static lightmap for this seg
+#endif
+
+        linedef = (uint16_t)( LE_SWAP16(ml->linedef) );
+        ldef = &lines[linedef];
+        li->linedef = ldef;
+        side = ml->side;
+
+        // e6y: check for wrong indexes
+        if ((unsigned)ldef->sidenum[side] >= (unsigned)numsides)
+        {
+            I_Error("P_LoadSegs_ZDBSP: linedef %u for seg %u "
+                    "references a non-existent sidedef %u",
+                    linedef, (unsigned) i, (unsigned)ldef->sidenum[side]);
+        }
+
+        li->sidedef = &sides[ldef->sidenum[side]];
+        li->frontsector = sides[ldef->sidenum[side]].sector;
+
+        // seg angle and offset are not included
+        li->angle = R_PointToAngle2(segs[i].v1->x, segs[i].v1->y,
+                                    segs[i].v2->x, segs[i].v2->y);
+        li->offset = GetOffset(li->v1, (ml->side ? ldef->v2 : ldef->v1));
+
+        // killough 5/3/98: ignore 2s flag if second sidedef missing:
+        if (ldef->flags & ML_TWOSIDED && ldef->sidenum[side^1]!=NULL_INDEX)
+            li->backsector = sides[ldef->sidenum[side^1]].sector;
+        else
+            li->backsector = 0;
+    }
+
+    data += numsegs * sizeof(mapseg_zdbsp_t);
+
+    // 4. Load nodes
+
+    numNodes = (uint32_t)LE_SWAP32(*((uint32_t*)data));
+    data += sizeof(numNodes);
+
+    numnodes = (int)numNodes;
+    nodes = Z_Malloc(numnodes * sizeof(node_t), PU_LEVEL, 0);
+
+    for (i = 0; i < numnodes; i++)
+    {
+        int j, k;
+        node_t *no = nodes + i;
+        mapnode_zdbsp_t *mn = (mapnode_zdbsp_t *) data + i;
+
+        no->x = LE_SWAP16(mn->x)<<FRACBITS;
+        no->y = LE_SWAP16(mn->y)<<FRACBITS;
+        no->dx = LE_SWAP16(mn->dx)<<FRACBITS;
+        no->dy = LE_SWAP16(mn->dy)<<FRACBITS;
+
+        for (j = 0; j < 2; j++)
+        {
+            no->children[j] = (uint32_t)LE_SWAP32(mn->children[j]);
+
+            for (k = 0; k < 4; k++)
+                no->bbox[j][k] = LE_SWAP16(mn->bbox[j][k])<<FRACBITS;
+        }
+    }
+
+#ifdef HAVE_ZLIB
+    if (compressed)
+        Z_Free(output);
+    else
+#endif  // HAVE_ZLIB
+        W_CacheLumpNum(lump, PU_CACHE);
+}
diff --git a/doomlegacy-devel/files/p_extnodes.h b/doomlegacy-devel/files/p_extnodes.h
new file mode 100644
index 0000000000..b5cb1ea452
--- /dev/null
+++ b/doomlegacy-devel/files/p_extnodes.h
@@ -0,0 +1,92 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: r_defs.h,v 1.18 1998/04/27 02:12:59 killough Exp $
+//
+//  Copyright (C) 1999 by
+//  id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
+//  Copyright(C) 2015-2020 Fabian Greffrath
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
+//  02111-1307, USA.
+//
+//  DESCRIPTION:
+//  Support maps with NODES in compressed or uncompressed ZDBSP format or
+//  DeePBSP format.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __P_EXTNODES__
+#define __P_EXTNODES__
+
+// [MB] 2020-04-21: Support for ZDoom extended nodes based on woof 1.2.0
+
+// [MB] 2020-04-21: Moved from woof doomtype.h to this header
+// The packed attribute forces structures to be packed into the minimum
+// space necessary.  If this is not done, the compiler may align structure
+// fields differently to optimize memory access, inflating the overall
+// structure size.  It is important to use the packed attribute on certain
+// structures where alignment is important, particularly data read/written
+// to disk.
+
+#ifdef __GNUC__
+ #if defined(_WIN32) && !defined(__clang__)
+  #define PACKEDATTR __attribute__((packed,gcc_struct))
+ #else
+  #define PACKEDATTR __attribute__((packed))
+ #endif
+
+ #define PRINTF_ATTR(fmt, first) __attribute__((format(printf, fmt, first)))
+ #define PRINTF_ARG_ATTR(x) __attribute__((format_arg(x)))
+ #define NORETURN __attribute__((noreturn))
+#else
+ #if defined(_MSC_VER)
+  #define PACKEDATTR __pragma(pack(pop))
+ #else
+  #define PACKEDATTR
+ #endif
+
+ #define PRINTF_ATTR(fmt, first)
+ #define PRINTF_ARG_ATTR(x)
+ #define NORETURN
+#endif
+
+#ifdef __WATCOMC__
+ #define PACKEDPREFIX _Packed
+#elif defined(_MSC_VER)
+ #define PACKEDPREFIX __pragma(pack(push,1))
+#else
+ #define PACKEDPREFIX
+#endif
+
+#define PACKED_STRUCT(...) PACKEDPREFIX struct __VA_ARGS__ PACKEDATTR
+
+typedef enum
+{
+    MFMT_DOOMBSP = 0x000,
+    MFMT_DEEPBSP = 0x001,
+    MFMT_ZDBSPX  = 0x002,
+    MFMT_ZDBSPZ  = 0x004,
+} mapformat_t;
+
+extern mapformat_t P_CheckMapFormat (int lumpnum);
+
+extern void P_LoadSegs_DeePBSP (int lump);
+extern void P_LoadSubsectors_DeePBSP (int lump);
+extern void P_LoadNodes_DeePBSP (int lump);
+extern void P_LoadNodes_ZDBSP (int lump, boolean compressed);
+
+#endif
diff --git a/doomlegacy-devel/patches/patch-src_Makefile b/doomlegacy-devel/patches/patch-src_Makefile
new file mode 100644
index 0000000000..20c9e2ae0a
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_Makefile
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Add object file for import of extended nodes.
+
+--- src/Makefile.orig	2020-04-20 10:32:33.000000000 +0000
++++ src/Makefile
+@@ -1070,7 +1070,7 @@ screen.o v_video.o \
+ r_draw.o r_plane.o r_segs.o r_sky.o r_things.o r_splats.o \
+ r_bsp.o r_data.o r_main.o \
+ z_zone.o \
+-p_sight.o p_mobj.o p_enemy.o p_user.o p_inter.o p_pspr.o \
++p_sight.o p_mobj.o p_enemy.o p_extnodes.o p_user.o p_inter.o p_pspr.o \
+ p_lights.o p_ceilng.o p_doors.o p_plats.o p_floor.o p_spec.o \
+ p_switch.o p_genlin.o p_telept.o p_tick.o p_fab.o p_info.o p_setup.o \
+ p_map.o p_maputl.o \
diff --git a/doomlegacy-devel/patches/patch-src_doomdata.h b/doomlegacy-devel/patches/patch-src_doomdata.h
new file mode 100644
index 0000000000..a1f4f7478f
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_doomdata.h
@@ -0,0 +1,26 @@
+$NetBSD$
+
+Refer to subsectors with 32-Bit values (required for extended nodes).
+
+--- src/doomdata.h.orig	2020-04-20 10:32:30.000000000 +0000
++++ src/doomdata.h
+@@ -203,7 +203,8 @@ typedef struct
+ // BSP node structure.
+ 
+ // Indicate a leaf.
+-#define NF_SUBSECTOR    0x8000
++// [MB] 2020-04-22: Changed to 32-Bit for extended nodes
++#define NF_SUBSECTOR    0x80000000
+ 
+ // WAD lump structure
+ typedef struct
+@@ -218,7 +219,8 @@ typedef struct
+   // clip against view frustum.
+   int16_t       bbox[2][4];
+ 
+-  // If NF_SUBSECTOR its a subsector,
++  // [MB] 2020-04-22: NF_SUBSECTOR no longer matches here!
++  // If MSB is set it's a subsector,
+   // else it's a node of another subtree.
+   uint16_t      children[2];
+ 
diff --git a/doomlegacy-devel/patches/patch-src_p__setup.c b/doomlegacy-devel/patches/patch-src_p__setup.c
new file mode 100644
index 0000000000..c0adea5baf
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_p__setup.c
@@ -0,0 +1,114 @@
+$NetBSD$
+
+Add support for DeeP and ZDoom extended nodes.
+
+--- src/p_setup.c.orig	2020-04-20 10:32:30.000000000 +0000
++++ src/p_setup.c
+@@ -150,6 +150,7 @@
+ //-----------------------------------------------------------------------------
+ 
+ #include "doomincl.h"
++#include "p_extnodes.h"  // [MB] 2020-04-21: For import of extended nodes
+ #include "p_local.h"
+ #include "p_tick.h"
+   // think
+@@ -282,6 +283,7 @@ mapthing_t  *   playerstarts[MAXPLAYERS]
+ 
+ #if 0
+ // [WDJ] Checks from PrBoom.
++// [MB] 2020-04-21: Used the woof code from p_extnodes.c instead
+ 
+ // figgi 08/21/00 -- constants and globals for glBsp support
+ #define gNd2  0x32644E67
+@@ -793,7 +795,22 @@ void P_LoadNodes (int lump)
+         no->dy = LE_SWAP16(mn->dy)<<FRACBITS;
+         for (j=0 ; j<2 ; j++)
+         {
+-            no->children[j] = (uint16_t)( LE_SWAP16(mn->children[j]) );
++            no->children[j] = (uint16_t) ( LE_SWAP16(mn->children[j]) );
++
++            // [MB] 2020-04-21: Changed for 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] = LE_SWAP16(mn->bbox[j][k])<<FRACBITS;
+         }
+@@ -1840,6 +1857,7 @@ boolean P_SetupLevel (int      to_episod
+     const char  *errstr;
+     char  *sl_mapname = NULL;
+     int   i;
++    mapformat_t mapformat;
+ 
+     GenPrintf( (verbose? (EMSG_ver|EMSG_now) : (EMSG_console|EMSG_now)),
+                "Setup Level\n" );
+@@ -1985,6 +2003,29 @@ boolean P_SetupLevel (int      to_episod
+         goto load_reject;
+     }
+ 
++    // [MB] 2020-04-21: Node format check from woof (p_extnodes.c)
++    mapformat = P_CheckMapFormat(level_lumpnum);
++    switch (mapformat)
++    {
++    case MFMT_DOOMBSP:
++        GenPrintf(EMSG_info, "Node format: Regular\n" );
++        break;
++    case MFMT_DEEPBSP:
++        GenPrintf(EMSG_info, "Node format: DeeP V4 extended\n" );
++        break;
++    case MFMT_ZDBSPX:
++        GenPrintf(EMSG_info, "Node format: ZDoom extended\n" );
++        break;
++#if HAVE_ZLIB
++    case MFMT_ZDBSPZ:
++        GenPrintf(EMSG_info, "Node format: ZDoom extended (compressed)\n" );
++        break;
++#endif  // HAVE_ZLIB
++    default:
++        I_Error( "P_SetupLevel: Node format not supported\n" );
++        break;
++    }
++
+     // note: most of this ordering is important
+     P_LoadBlockMap (level_lumpnum+ML_BLOCKMAP);
+     P_LoadVertexes (level_lumpnum+ML_VERTEXES);
+@@ -1994,9 +2035,26 @@ boolean P_SetupLevel (int      to_episod
+     P_LoadLineDefs (level_lumpnum+ML_LINEDEFS);
+     P_LoadSideDefs2(level_lumpnum+ML_SIDEDEFS);
+     P_LoadLineDefs2();
+-    P_LoadSubsectors (level_lumpnum+ML_SSECTORS);
+-    P_LoadNodes (level_lumpnum+ML_NODES);
+-    P_LoadSegs (level_lumpnum+ML_SEGS);
++
++    // [MB] 2020-04-21: Hook in code imported from woof 1.2.0 (p_extnodes.c)
++    if (mapformat == MFMT_ZDBSPX || mapformat == MFMT_ZDBSPZ)
++    {
++        P_LoadNodes_ZDBSP (level_lumpnum+ML_NODES, mapformat == MFMT_ZDBSPZ);
++    }
++    else if (mapformat == MFMT_DEEPBSP)
++    {
++        P_LoadSubsectors_DeePBSP (level_lumpnum+ML_SSECTORS);
++        P_LoadNodes_DeePBSP (level_lumpnum+ML_NODES);
++        P_LoadSegs_DeePBSP (level_lumpnum+ML_SEGS);
++    }
++    // [MB] 2020-04-21: This is the former DooM Legacy code
++    else
++    {
++        P_LoadSubsectors (level_lumpnum+ML_SSECTORS);
++        P_LoadNodes (level_lumpnum+ML_NODES);
++        P_LoadSegs (level_lumpnum+ML_SEGS);
++    }
++
+     rejectmatrix = W_CacheLumpNum (level_lumpnum+ML_REJECT,PU_LEVEL);
+     P_GroupLines ();
+ 
diff --git a/doomlegacy-devel/patches/patch-src_r__defs.h b/doomlegacy-devel/patches/patch-src_r__defs.h
new file mode 100644
index 0000000000..242ff96480
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_r__defs.h
@@ -0,0 +1,40 @@
+$NetBSD$
+
+Refer to segments and subsectors with 32-Bit values.
+
+--- src/r_defs.h.orig	2020-04-20 10:32:32.000000000 +0000
++++ src/r_defs.h
+@@ -130,8 +130,7 @@
+ 
+ 
+ // Max index (or -1). Used in line_t::sidenum and maplinedef_t::sidenum.
+-#define NULL_INDEX   0xFFFF
+-
++#define NULL_INDEX   UINT16_C(0xFFFF)
+ 
+ // Silhouette, needed for clipping Segs (mainly)
+ // and sprites representing things.
+@@ -566,9 +565,9 @@ typedef struct subsector_s
+ {
+     sector_t*   sector;   // (ref) part of this sector, from segs->sector of firstline
+     // numlines and firstline are from the subsectors lump (nodebuilder)
+-    // [WDJ] some wad may be large enough to overflow signed short.
+-    unsigned short  numlines;   // number of segs in this subsector
+-    unsigned short  firstline;  // index into segs lump (loaded from wad)
++    // [MB] 2020-04-22: Changed to 32-Bit for extended nodes
++    uint32_t  numlines;   // number of segs in this subsector
++    uint32_t  firstline;  // index into segs lump (loaded from wad)
+     // floorsplat_t list
+     void*       splats;
+     //Hurdler: added for optimized mlook in hw mode
+@@ -790,7 +789,9 @@ typedef struct
+ 
+     // If NF_SUBSECTOR is set then rest of it is a subsector index,
+     // otherwise it is another node index.
+-    uint16_t    children[2];
++    // [MB] 2020-04-22: Changed to 32-Bit for extended nodes
++    //      Use int to match rest of the code (should be uint32_t)
++    int         children[2];
+         // children[0]= right
+         // children[1]= left
+ } node_t;


Home | Main Index | Thread Index | Old Index