From 732d9bc7109f18a1838fadf02b98acceb09af429 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 7 Dec 2012 06:19:25 +0000 Subject: [PATCH] - Added a new node format (ZGL3/XGL3) which allows node splitters to have fractional precision. This can only happen with UDMF, and since UDMF is restricted to GL nodes, there's no need for a non-GL version of these nodes. - Added additional debug output. - Remove the outdated zdbsp.vcproj project file. SVN r3981 (trunk) --- doomdata.h | 9 +- nodebuild.cpp | 6 +- nodebuild.h | 1 + nodebuild_extract.cpp | 72 ++++--- nodebuild_utility.cpp | 5 +- processor.cpp | 107 +++++++--- processor.h | 9 +- view.cpp | 24 ++- zdbsp.html | 50 ++++- zdbsp.vcproj | 487 ------------------------------------------ 10 files changed, 208 insertions(+), 562 deletions(-) delete mode 100644 zdbsp.vcproj diff --git a/doomdata.h b/doomdata.h index b9ca4ce..3c5aabb 100644 --- a/doomdata.h +++ b/doomdata.h @@ -167,13 +167,20 @@ struct MapNode WORD children[2]; }; -struct MapNodeEx +struct MapNodeExO { short x,y,dx,dy; short bbox[2][4]; DWORD children[2]; }; +struct MapNodeEx +{ + int x,y,dx,dy; + short bbox[2][4]; + DWORD children[2]; +}; + struct MapThing { short x; diff --git a/nodebuild.cpp b/nodebuild.cpp index 194397e..8d2bce2 100644 --- a/nodebuild.cpp +++ b/nodebuild.cpp @@ -206,14 +206,16 @@ void FNodeBuilder::CreateSubsectorsForReal () } for (unsigned int i = sub.firstline; i < SegList.Size(); ++i) { - D(printf (" Seg %5d%c%d(%5d,%5d)-%d(%5d,%5d)\n", SegList[i].SegPtr - &Segs[0], + D(printf (" Seg %5d%c%d(%5d,%5d)-%d(%5d,%5d) [%08x,%08x]-[%08x,%08x]\n", SegList[i].SegPtr - &Segs[0], SegList[i].SegPtr->linedef == -1 ? '+' : ' ', SegList[i].SegPtr->v1, Vertices[SegList[i].SegPtr->v1].x>>16, Vertices[SegList[i].SegPtr->v1].y>>16, SegList[i].SegPtr->v2, Vertices[SegList[i].SegPtr->v2].x>>16, - Vertices[SegList[i].SegPtr->v2].y>>16)); + Vertices[SegList[i].SegPtr->v2].y>>16, + Vertices[SegList[i].SegPtr->v1].x, Vertices[SegList[i].SegPtr->v1].y, + Vertices[SegList[i].SegPtr->v2].x, Vertices[SegList[i].SegPtr->v2].y)); SegList[i].SegNum = DWORD(SegList[i].SegPtr - &Segs[0]); } Subsectors.Push (sub); diff --git a/nodebuild.h b/nodebuild.h index c02e726..23ed8d7 100644 --- a/nodebuild.h +++ b/nodebuild.h @@ -254,6 +254,7 @@ private: double InterceptVector (const node_t &splitter, const FPrivSeg &seg); void PrintSet (int l, DWORD set); + void DumpNodes(MapNodeEx *outNodes, int nodeCount); }; // Points within this distance of a line will be considered on the line. diff --git a/nodebuild_extract.cpp b/nodebuild_extract.cpp index 7a541d8..4b6b92e 100644 --- a/nodebuild_extract.cpp +++ b/nodebuild_extract.cpp @@ -47,10 +47,10 @@ void FNodeBuilder::GetGLNodes (MapNodeEx *&outNodes, int &nodeCount, const node_t *orgnode = &Nodes[i]; MapNodeEx *newnode = &outNodes[i]; - newnode->x = short(orgnode->x >> FRACBITS); - newnode->y = short(orgnode->y >> FRACBITS); - newnode->dx = short(orgnode->dx >> FRACBITS); - newnode->dy = short(orgnode->dy >> FRACBITS); + newnode->x = orgnode->x; + newnode->y = orgnode->y; + newnode->dx = orgnode->dx; + newnode->dy = orgnode->dy; for (j = 0; j < 2; ++j) { @@ -82,6 +82,8 @@ void FNodeBuilder::GetGLNodes (MapNodeEx *&outNodes, int &nodeCount, outSegs[i].partner = Segs[outSegs[i].partner].storedseg; } } + + D(DumpNodes(outNodes, nodeCount)); } int FNodeBuilder::CloseSubsector (TArray &segs, int subsector) @@ -134,12 +136,14 @@ int FNodeBuilder::CloseSubsector (TArray &segs, int subsector) { seg = &Segs[SegList[j].SegNum]; angle_t ang = PointToAngle (Vertices[seg->v1].x - midx, Vertices[seg->v1].y - midy); - printf ("%d%c %5d(%5d,%5d)->%5d(%5d,%5d) - %3.3f %d,%d\n", j, + printf ("%d%c %5d(%5d,%5d)->%5d(%5d,%5d) - %3.5f %d,%d [%08x,%08x]-[%08x,%08x]\n", j, seg->linedef == -1 ? '+' : ':', seg->v1, Vertices[seg->v1].x>>16, Vertices[seg->v1].y>>16, seg->v2, Vertices[seg->v2].x>>16, Vertices[seg->v2].y>>16, double(ang/2)*180/(1<<30), - seg->planenum, seg->planefront); + seg->planenum, seg->planefront, + Vertices[seg->v1].x, Vertices[seg->v1].y, + Vertices[seg->v2].x, Vertices[seg->v2].y); } #endif @@ -230,12 +234,16 @@ int FNodeBuilder::CloseSubsector (TArray &segs, int subsector) printf ("Output GL subsector %d:\n", subsector); for (i = segs.Size() - count; i < (int)segs.Size(); ++i) { - printf (" Seg %5d%c(%5d,%5d)-(%5d,%5d)\n", i, + printf (" Seg %5d%c(%5d,%5d)-(%5d,%5d) [%08x,%08x]-[%08x,%08x]\n", i, segs[i].linedef == NO_INDEX ? '+' : ' ', Vertices[segs[i].v1].x>>16, Vertices[segs[i].v1].y>>16, Vertices[segs[i].v2].x>>16, - Vertices[segs[i].v2].y>>16); + Vertices[segs[i].v2].y>>16, + Vertices[segs[i].v1].x, + Vertices[segs[i].v1].y, + Vertices[segs[i].v2].x, + Vertices[segs[i].v2].y); } #endif @@ -406,25 +414,9 @@ void FNodeBuilder::GetNodes (MapNodeEx *&outNodes, int &nodeCount, outSegs = new MapSegEx[segCount]; memcpy (outSegs, &segs[0], segCount*sizeof(MapSegEx)); + D(DumpNodes(outNodes, nodeCount)); #ifdef DD - int i, j; - - for (i = 0; i < nodeCount; ++i) - { - printf("Node %d:\n", i); - for (j = 1; j >= 0; --j) - { - if (outNodes[i].children[j] & NFX_SUBSECTOR) - { - printf(" subsector %d\n", outNodes[i].children[j] & ~NFX_SUBSECTOR); - } - else - { - printf(" node %d\n", outNodes[i].children[j]); - } - } - } - for (i = 0; i < segCount; ++i) + for (int i = 0; i < segCount; ++i) { printf("Seg %d: v1(%d) -> v2(%d)\n", i, outSegs[i].v1, outSegs[i].v2); } @@ -451,10 +443,10 @@ int FNodeBuilder::RemoveMinisegs (MapNodeEx *nodes, int child1 = RemoveMinisegs (nodes, segs, subs, orgnode->intchildren[1], newnode->bbox[1]); - newnode->x = orgnode->x >> FRACBITS; - newnode->y = orgnode->y >> FRACBITS; - newnode->dx = orgnode->dx >> FRACBITS; - newnode->dy = orgnode->dy >> FRACBITS; + newnode->x = orgnode->x; + newnode->y = orgnode->y; + newnode->dx = orgnode->dx; + newnode->dy = orgnode->dy; newnode->children[0] = child0; newnode->children[1] = child1; @@ -558,3 +550,23 @@ void FNodeBuilder::AddSegToShortBBox (short bbox[4], const FPrivSeg *seg) if (v2y < bbox[BOXBOTTOM]) bbox[BOXBOTTOM] = v2y; if (v2y > bbox[BOXTOP]) bbox[BOXTOP] = v2y; } + +void FNodeBuilder::DumpNodes(MapNodeEx *outNodes, int nodeCount) +{ + for (unsigned int i = 0; i < Nodes.Size(); ++i) + { + printf("Node %d: Splitter[%08x,%08x] [%08x,%08x]\n", i, + outNodes[i].x, outNodes[i].y, outNodes[i].dx, outNodes[i].dy); + for (int j = 1; j >= 0; --j) + { + if (outNodes[i].children[j] & NFX_SUBSECTOR) + { + printf(" subsector %d\n", outNodes[i].children[j] & ~NFX_SUBSECTOR); + } + else + { + printf(" node %d\n", outNodes[i].children[j]); + } + } + } +} diff --git a/nodebuild_utility.cpp b/nodebuild_utility.cpp index 9da4abf..df49873 100644 --- a/nodebuild_utility.cpp +++ b/nodebuild_utility.cpp @@ -143,8 +143,9 @@ int FNodeBuilder::CreateSeg (int linenum, int sidenum) segnum = (int)Segs.Push (seg); Vertices[seg.v1].segs = segnum; Vertices[seg.v2].segs2 = segnum; - D(printf("Seg %4d: From line %d, side %s (%5d,%5d)-(%5d,%5d)\n", segnum, linenum, sidenum ? "back " : "front", - Vertices[seg.v1].x>>16, Vertices[seg.v1].y>>16, Vertices[seg.v2].x>>16, Vertices[seg.v2].y>>16)); + D(printf("Seg %4d: From line %d, side %s (%5d,%5d)-(%5d,%5d) [%08x,%08x]-[%08x,%08x]\n", segnum, linenum, sidenum ? "back " : "front", + Vertices[seg.v1].x>>16, Vertices[seg.v1].y>>16, Vertices[seg.v2].x>>16, Vertices[seg.v2].y>>16, + Vertices[seg.v1].x, Vertices[seg.v1].y, Vertices[seg.v2].x, Vertices[seg.v2].y)); return segnum; } diff --git a/processor.cpp b/processor.cpp index 2def63c..5c75359 100644 --- a/processor.cpp +++ b/processor.cpp @@ -1147,16 +1147,20 @@ void FProcessor::WriteNodes2 (FWadWriter &out, const char *name, const MapNodeEx void FProcessor::WriteNodes5 (FWadWriter &out, const char *name, const MapNodeEx *zaNodes, int count) const { int i, j; - MapNodeEx *const nodes = new MapNodeEx[count * sizeof(MapNodeEx)]; + MapNodeExO *const nodes = new MapNodeExO[count * sizeof(MapNodeEx)]; for (i = 0; i < count; ++i) { - const short *inodes = &zaNodes[i].x; - short *coord = &nodes[i].x; - for (j = 0; j < 4+2*4; ++j) + const short *inodes = &zaNodes[i].bbox[0][0]; + short *coord = &nodes[i].bbox[0][0]; + for (j = 0; j < 2*4; ++j) { coord[j] = LittleShort(inodes[j]); } + nodes[i].x = LittleShort(zaNodes[i].x >> 16); + nodes[i].y = LittleShort(zaNodes[i].y >> 16); + nodes[i].dx = LittleShort(zaNodes[i].dx >> 16); + nodes[i].dy = LittleShort(zaNodes[i].dy >> 16); for (j = 0; j < 2; ++j) { nodes[i].children[j] = LittleLong(zaNodes[i].children[j]); @@ -1370,12 +1374,14 @@ void FProcessor::WriteBSPZ (FWadWriter &out, const char *label) WriteVerticesZ (zout, &Level.Vertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumVertices - Level.NumOrgVerts); WriteSubsectorsZ (zout, Level.Subsectors, Level.NumSubsectors); WriteSegsZ (zout, Level.Segs, Level.NumSegs); - WriteNodesZ (zout, Level.Nodes, Level.NumNodes); + WriteNodesZ (zout, Level.Nodes, Level.NumNodes, 1); } void FProcessor::WriteGLBSPZ (FWadWriter &out, const char *label) { ZLibOut zout (out); + bool fracsplitters = CheckForFracSplitters(Level.GLNodes, Level.NumGLNodes); + int nodever; if (!CompressGLNodes) { @@ -1383,18 +1389,25 @@ void FProcessor::WriteGLBSPZ (FWadWriter &out, const char *label) } out.StartWritingLump (label); - if (Level.NumLines() < 65535) + if (fracsplitters) + { + out.AddToLump ("ZGL3", 4); + nodever = 3; + } + else if (Level.NumLines() < 65535) { out.AddToLump ("ZGLN", 4); + nodever = 1; } else { out.AddToLump ("ZGL2", 4); + nodever = 2; } WriteVerticesZ (zout, &Level.GLVertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumGLVertices - Level.NumOrgVerts); WriteSubsectorsZ (zout, Level.GLSubsectors, Level.NumGLSubsectors); - WriteGLSegsZ (zout, Level.GLSegs, Level.NumGLSegs); - WriteNodesZ (zout, Level.GLNodes, Level.NumGLNodes); + WriteGLSegsZ (zout, Level.GLSegs, Level.NumGLSegs, nodever); + WriteNodesZ (zout, Level.GLNodes, Level.NumGLNodes, nodever); } void FProcessor::WriteVerticesZ (ZLibOut &out, const WideVertex *verts, int orgverts, int newverts) @@ -1430,11 +1443,11 @@ void FProcessor::WriteSegsZ (ZLibOut &out, const MapSegEx *segs, int numsegs) } } -void FProcessor::WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs) +void FProcessor::WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs, int nodever) { out << (DWORD)numsegs; - if (Level.NumLines() < 65535) + if (nodever < 2) { for (int i = 0; i < numsegs; ++i) { @@ -1456,16 +1469,26 @@ void FProcessor::WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs } } -void FProcessor::WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes) +void FProcessor::WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes, int nodever) { out << (DWORD)numnodes; for (int i = 0; i < numnodes; ++i) { - out << (SWORD)nodes[i].x - << (SWORD)nodes[i].y - << (SWORD)nodes[i].dx - << (SWORD)nodes[i].dy; + if (nodever < 3) + { + out << (SWORD)(nodes[i].x >> 16) + << (SWORD)(nodes[i].y >> 16) + << (SWORD)(nodes[i].dx >> 16) + << (SWORD)(nodes[i].dy >> 16); + } + else + { + out << (DWORD)nodes[i].x + << (DWORD)nodes[i].y + << (DWORD)nodes[i].dx + << (DWORD)nodes[i].dy; + } for (int j = 0; j < 2; ++j) { for (int k = 0; k < 4; ++k) @@ -1490,29 +1513,39 @@ void FProcessor::WriteBSPX (FWadWriter &out, const char *label) WriteVerticesX (out, &Level.Vertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumVertices - Level.NumOrgVerts); WriteSubsectorsX (out, Level.Subsectors, Level.NumSubsectors); WriteSegsX (out, Level.Segs, Level.NumSegs); - WriteNodesX (out, Level.Nodes, Level.NumNodes); + WriteNodesX (out, Level.Nodes, Level.NumNodes, 1); } void FProcessor::WriteGLBSPX (FWadWriter &out, const char *label) { + bool fracsplitters = CheckForFracSplitters(Level.GLNodes, Level.NumGLNodes); + int nodever; + if (!CompressGLNodes) { printf (" GL Nodes are so big that extended format has been forced.\n"); } out.StartWritingLump (label); - if (Level.NumLines() < 65535) + if (fracsplitters) + { + out.AddToLump ("XGL3", 4); + nodever = 3; + } + else if (Level.NumLines() < 65535) { out.AddToLump ("XGLN", 4); + nodever = 1; } else { out.AddToLump ("XGL2", 4); + nodever = 2; } WriteVerticesX (out, &Level.GLVertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumGLVertices - Level.NumOrgVerts); WriteSubsectorsX (out, Level.GLSubsectors, Level.NumGLSubsectors); - WriteGLSegsX (out, Level.GLSegs, Level.NumGLSegs); - WriteNodesX (out, Level.GLNodes, Level.NumGLNodes); + WriteGLSegsX (out, Level.GLSegs, Level.NumGLSegs, nodever); + WriteNodesX (out, Level.GLNodes, Level.NumGLNodes, nodever); } void FProcessor::WriteVerticesX (FWadWriter &out, const WideVertex *verts, int orgverts, int newverts) @@ -1548,11 +1581,11 @@ void FProcessor::WriteSegsX (FWadWriter &out, const MapSegEx *segs, int numsegs) } } -void FProcessor::WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs) +void FProcessor::WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs, int nodever) { out << (DWORD)numsegs; - if (Level.NumLines() < 65535) + if (nodever < 2) { for (int i = 0; i < numsegs; ++i) { @@ -1574,16 +1607,26 @@ void FProcessor::WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int nums } } -void FProcessor::WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numnodes) +void FProcessor::WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numnodes, int nodever) { out << (DWORD)numnodes; for (int i = 0; i < numnodes; ++i) { - out << (SWORD)nodes[i].x - << (SWORD)nodes[i].y - << (SWORD)nodes[i].dx - << (SWORD)nodes[i].dy; + if (nodever < 3) + { + out << (SWORD)(nodes[i].x >> 16) + << (SWORD)(nodes[i].y >> 16) + << (SWORD)(nodes[i].dx >> 16) + << (SWORD)(nodes[i].dy >> 16); + } + else + { + out << (DWORD)nodes[i].x + << (DWORD)nodes[i].y + << (DWORD)nodes[i].dx + << (DWORD)nodes[i].dy; + } for (int j = 0; j < 2; ++j) { for (int k = 0; k < 4; ++k) @@ -1596,6 +1639,18 @@ void FProcessor::WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numno } } +bool FProcessor::CheckForFracSplitters(const MapNodeEx *nodes, int numnodes) +{ + for (int i = 0; i < numnodes; ++i) + { + if (0 != ((nodes[i].x | nodes[i].y | nodes[i].dx | nodes[i].dy) & 0x0000FFFF)) + { + return true; + } + } + return false; +} + // zlib lump writer --------------------------------------------------------- ZLibOut::ZLibOut (FWadWriter &out) diff --git a/processor.h b/processor.h index c9c2550..ce4b767 100644 --- a/processor.h +++ b/processor.h @@ -56,6 +56,7 @@ private: MapSegGLEx *SegGLsToEx (const MapSegGL *segs, int count); BYTE *FixReject (const BYTE *oldreject); + bool CheckForFracSplitters(const MapNodeEx *nodes, int count); void WriteLines (FWadWriter &out); void WriteVertices (FWadWriter &out, int count); @@ -79,8 +80,8 @@ private: void WriteVerticesZ (ZLibOut &out, const WideVertex *verts, int orgverts, int newverts); void WriteSubsectorsZ (ZLibOut &out, const MapSubsectorEx *subs, int numsubs); void WriteSegsZ (ZLibOut &out, const MapSegEx *segs, int numsegs); - void WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs); - void WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes); + void WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs, int nodever); + void WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes, int nodever); void WriteBSPX (FWadWriter &out, const char *label); void WriteGLBSPX (FWadWriter &out, const char *label); @@ -88,8 +89,8 @@ private: void WriteVerticesX (FWadWriter &out, const WideVertex *verts, int orgverts, int newverts); void WriteSubsectorsX (FWadWriter &out, const MapSubsectorEx *subs, int numsubs); void WriteSegsX (FWadWriter &out, const MapSegEx *segs, int numsegs); - void WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs); - void WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numnodes); + void WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs, int nodever); + void WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numnodes, int nodever); void WriteNodes2 (FWadWriter &out, const char *name, const MapNodeEx *zaNodes, int count) const; void WriteSSectors2 (FWadWriter &out, const char *name, const MapSubsectorEx *zaSubs, int count) const; diff --git a/view.cpp b/view.cpp index bb301e9..8d7c2ff 100644 --- a/view.cpp +++ b/view.cpp @@ -392,6 +392,20 @@ static void DrawOutsideNode (HDC dc, int node) } } +static void DrawSplitter (HDC dc, MapNodeEx *node) +{ + int dx = node->dx, dy = node->dy; + // If the splitter is particularly short, make it longer to stand out + while (abs(dx) < (20 << 16) && abs(dy) < (20 << 16)) + { + dx <<= 1; + dy <<= 1; + } + SelectObject (dc, Splitter); + MoveToEx (dc, (node->x - dx) >> 16, (node->y - dy) >> 16, NULL); + LineTo (dc, (node->x + 2*dx) >> 16, (node->y + 2*dy) >> 16); +} + static void DrawLevelNodes (HDC dc) { HPEN oldPen; @@ -412,17 +426,13 @@ static void DrawLevelNodes (HDC dc) { DrawOutsideNode (dc, Level->NumNodes - 1); DrawNode (dc, Level->NumNodes - 1); - SelectObject (dc, Splitter); - MoveToEx (dc, Level->Nodes[DesiredNode].x - Level->Nodes[DesiredNode].dx, Level->Nodes[DesiredNode].y - Level->Nodes[DesiredNode].dy, NULL); - LineTo (dc, Level->Nodes[DesiredNode].x + 2*Level->Nodes[DesiredNode].dx, Level->Nodes[DesiredNode].y + 2*Level->Nodes[DesiredNode].dy); + DrawSplitter (dc, &Level->Nodes[DesiredNode]); } else { DrawOutsideNode (dc, Level->NumGLNodes - 1); DrawNode (dc, Level->NumGLNodes - 1); - SelectObject (dc, Splitter); - MoveToEx (dc, Level->GLNodes[DesiredNode].x - Level->GLNodes[DesiredNode].dx, Level->GLNodes[DesiredNode].y - Level->GLNodes[DesiredNode].dy, NULL); - LineTo (dc, Level->GLNodes[DesiredNode].x + 2*Level->GLNodes[DesiredNode].dx, Level->GLNodes[DesiredNode].y + 2*Level->GLNodes[DesiredNode].dy); + DrawSplitter (dc, &Level->GLNodes[DesiredNode]); } @@ -496,7 +506,7 @@ static void DrawLevelSubsectors (HDC dc) static inline int PointOnSide (int x, int y, const MapNodeEx &nd) { - int foo = DMulScale32 (y-nd.y, nd.dx, nd.x-x, nd.dy); + int foo = DMulScale32 ((y<<16)-nd.y, nd.dx, nd.x-(x<<16), nd.dy); return foo >= 0; } diff --git a/zdbsp.html b/zdbsp.html index c20d4c8..e3c8837 100644 --- a/zdbsp.html +++ b/zdbsp.html @@ -265,7 +265,9 @@ signature. This can be either 'ZNOD' for regular nodes or 'ZGLN' for GL nodes. If there are more than 65534 lines in the map, the signature 'ZGL2' is used for GL nodes instead. (Note that this can only happen with UDMF maps, because - the binary map format does not allow more lines than that.) + the binary map format does not allow more lines than that.) There is also a third + variant of 'ZGLN': 'ZGL3' is identical to 'ZGL2' but expands the node's splitter + field to fixed point coordinates. Following the signature is the zlib data stream. For a description of its format, see the zlib documentation. When you decompress it, the following information is obtained in this order:

@@ -420,7 +422,7 @@ The linedef's side this seg came from (0=front, 1=back) (ignored if no line) -

GL nodes ('ZGL2' signature)

+

GL nodes ('ZGL2' and 'ZGL3' signature)

@@ -482,7 +484,8 @@ the next seg's first vertex. The last seg's second vertex will be the same as the first seg's first vertex.

Node information

-

This is really no different from standard nodes.

+

Only 'ZGL3' nodes structure this differently from standard nodes.

+

All nodes formats except 'ZGL3'

DWORD
@@ -513,6 +516,37 @@
DWORDReferences to child nodes or subsectors
+

Nodes with 'ZGL3' signature

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DWORDNumNodesNumber of nodes
Repeat NumNodes times:
4 FIXEDsX, Y, dX, dYSplitter for this node
4 SWORDsTop, Bottom, Left, RightBounding box for Child0
4 SWORDsTop, Bottom, Left, RightBounding box for Child1
2 DWORDsChild0, Child1References to child nodes or subsectors

As with standard nodes, a child's high bit is set to indicate that it is a subsector and cleared to indicate that it is another node. Just remember that the child references are stored using four bytes each instead of two.

@@ -528,5 +562,15 @@ compressed nodes are not used.

For UDMF maps, nodes a stored in the map's ZNODES lump. These will only be 'ZGLN' or 'ZGL2' format nodes. Non-GL nodes are not supported for UDMF.

+

Extended nodes

+

For the benefit of ports not wishing to support zlib decompression of nodes, + there are variants of the compressed node formats without compression. These + are referred to extended nodes, and differ only from their compressed counterparts + in that their contents are not compressed. They use a different signature to + distinguish them from compressed nodes:

+
  • ZNOD -> XNOD
  • +
  • ZGLN -> XGLN
  • +
  • ZGL2 -> XGL2
  • +
  • ZGL3 -> XGL3
diff --git a/zdbsp.vcproj b/zdbsp.vcproj deleted file mode 100644 index 9167a6a..0000000 --- a/zdbsp.vcproj +++ /dev/null @@ -1,487 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -