- 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)
This commit is contained in:
Randy Heit 2012-12-07 06:19:25 +00:00
parent 36224bad4b
commit 732d9bc710
10 changed files with 208 additions and 562 deletions

View file

@ -167,13 +167,20 @@ struct MapNode
WORD children[2]; WORD children[2];
}; };
struct MapNodeEx struct MapNodeExO
{ {
short x,y,dx,dy; short x,y,dx,dy;
short bbox[2][4]; short bbox[2][4];
DWORD children[2]; DWORD children[2];
}; };
struct MapNodeEx
{
int x,y,dx,dy;
short bbox[2][4];
DWORD children[2];
};
struct MapThing struct MapThing
{ {
short x; short x;

View file

@ -206,14 +206,16 @@ void FNodeBuilder::CreateSubsectorsForReal ()
} }
for (unsigned int i = sub.firstline; i < SegList.Size(); ++i) 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->linedef == -1 ? '+' : ' ',
SegList[i].SegPtr->v1, SegList[i].SegPtr->v1,
Vertices[SegList[i].SegPtr->v1].x>>16, Vertices[SegList[i].SegPtr->v1].x>>16,
Vertices[SegList[i].SegPtr->v1].y>>16, Vertices[SegList[i].SegPtr->v1].y>>16,
SegList[i].SegPtr->v2, SegList[i].SegPtr->v2,
Vertices[SegList[i].SegPtr->v2].x>>16, 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]); SegList[i].SegNum = DWORD(SegList[i].SegPtr - &Segs[0]);
} }
Subsectors.Push (sub); Subsectors.Push (sub);

View file

@ -254,6 +254,7 @@ private:
double InterceptVector (const node_t &splitter, const FPrivSeg &seg); double InterceptVector (const node_t &splitter, const FPrivSeg &seg);
void PrintSet (int l, DWORD set); 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. // Points within this distance of a line will be considered on the line.

View file

@ -47,10 +47,10 @@ void FNodeBuilder::GetGLNodes (MapNodeEx *&outNodes, int &nodeCount,
const node_t *orgnode = &Nodes[i]; const node_t *orgnode = &Nodes[i];
MapNodeEx *newnode = &outNodes[i]; MapNodeEx *newnode = &outNodes[i];
newnode->x = short(orgnode->x >> FRACBITS); newnode->x = orgnode->x;
newnode->y = short(orgnode->y >> FRACBITS); newnode->y = orgnode->y;
newnode->dx = short(orgnode->dx >> FRACBITS); newnode->dx = orgnode->dx;
newnode->dy = short(orgnode->dy >> FRACBITS); newnode->dy = orgnode->dy;
for (j = 0; j < 2; ++j) 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; outSegs[i].partner = Segs[outSegs[i].partner].storedseg;
} }
} }
D(DumpNodes(outNodes, nodeCount));
} }
int FNodeBuilder::CloseSubsector (TArray<MapSegGLEx> &segs, int subsector) int FNodeBuilder::CloseSubsector (TArray<MapSegGLEx> &segs, int subsector)
@ -134,12 +136,14 @@ int FNodeBuilder::CloseSubsector (TArray<MapSegGLEx> &segs, int subsector)
{ {
seg = &Segs[SegList[j].SegNum]; seg = &Segs[SegList[j].SegNum];
angle_t ang = PointToAngle (Vertices[seg->v1].x - midx, Vertices[seg->v1].y - midy); 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->linedef == -1 ? '+' : ':',
seg->v1, Vertices[seg->v1].x>>16, Vertices[seg->v1].y>>16, seg->v1, Vertices[seg->v1].x>>16, Vertices[seg->v1].y>>16,
seg->v2, Vertices[seg->v2].x>>16, Vertices[seg->v2].y>>16, seg->v2, Vertices[seg->v2].x>>16, Vertices[seg->v2].y>>16,
double(ang/2)*180/(1<<30), 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 #endif
@ -230,12 +234,16 @@ int FNodeBuilder::CloseSubsector (TArray<MapSegGLEx> &segs, int subsector)
printf ("Output GL subsector %d:\n", subsector); printf ("Output GL subsector %d:\n", subsector);
for (i = segs.Size() - count; i < (int)segs.Size(); ++i) 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 ? '+' : ' ', segs[i].linedef == NO_INDEX ? '+' : ' ',
Vertices[segs[i].v1].x>>16, Vertices[segs[i].v1].x>>16,
Vertices[segs[i].v1].y>>16, Vertices[segs[i].v1].y>>16,
Vertices[segs[i].v2].x>>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 #endif
@ -406,25 +414,9 @@ void FNodeBuilder::GetNodes (MapNodeEx *&outNodes, int &nodeCount,
outSegs = new MapSegEx[segCount]; outSegs = new MapSegEx[segCount];
memcpy (outSegs, &segs[0], segCount*sizeof(MapSegEx)); memcpy (outSegs, &segs[0], segCount*sizeof(MapSegEx));
D(DumpNodes(outNodes, nodeCount));
#ifdef DD #ifdef DD
int i, j; for (int i = 0; i < segCount; ++i)
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)
{ {
printf("Seg %d: v1(%d) -> v2(%d)\n", i, outSegs[i].v1, outSegs[i].v2); 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]); int child1 = RemoveMinisegs (nodes, segs, subs, orgnode->intchildren[1], newnode->bbox[1]);
newnode->x = orgnode->x >> FRACBITS; newnode->x = orgnode->x;
newnode->y = orgnode->y >> FRACBITS; newnode->y = orgnode->y;
newnode->dx = orgnode->dx >> FRACBITS; newnode->dx = orgnode->dx;
newnode->dy = orgnode->dy >> FRACBITS; newnode->dy = orgnode->dy;
newnode->children[0] = child0; newnode->children[0] = child0;
newnode->children[1] = child1; 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[BOXBOTTOM]) bbox[BOXBOTTOM] = v2y;
if (v2y > bbox[BOXTOP]) bbox[BOXTOP] = 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]);
}
}
}
}

View file

@ -143,8 +143,9 @@ int FNodeBuilder::CreateSeg (int linenum, int sidenum)
segnum = (int)Segs.Push (seg); segnum = (int)Segs.Push (seg);
Vertices[seg.v1].segs = segnum; Vertices[seg.v1].segs = segnum;
Vertices[seg.v2].segs2 = 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", 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>>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; return segnum;
} }

View file

@ -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 void FProcessor::WriteNodes5 (FWadWriter &out, const char *name, const MapNodeEx *zaNodes, int count) const
{ {
int i, j; 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) for (i = 0; i < count; ++i)
{ {
const short *inodes = &zaNodes[i].x; const short *inodes = &zaNodes[i].bbox[0][0];
short *coord = &nodes[i].x; short *coord = &nodes[i].bbox[0][0];
for (j = 0; j < 4+2*4; ++j) for (j = 0; j < 2*4; ++j)
{ {
coord[j] = LittleShort(inodes[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) for (j = 0; j < 2; ++j)
{ {
nodes[i].children[j] = LittleLong(zaNodes[i].children[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); WriteVerticesZ (zout, &Level.Vertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumVertices - Level.NumOrgVerts);
WriteSubsectorsZ (zout, Level.Subsectors, Level.NumSubsectors); WriteSubsectorsZ (zout, Level.Subsectors, Level.NumSubsectors);
WriteSegsZ (zout, Level.Segs, Level.NumSegs); 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) void FProcessor::WriteGLBSPZ (FWadWriter &out, const char *label)
{ {
ZLibOut zout (out); ZLibOut zout (out);
bool fracsplitters = CheckForFracSplitters(Level.GLNodes, Level.NumGLNodes);
int nodever;
if (!CompressGLNodes) if (!CompressGLNodes)
{ {
@ -1383,18 +1389,25 @@ void FProcessor::WriteGLBSPZ (FWadWriter &out, const char *label)
} }
out.StartWritingLump (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); out.AddToLump ("ZGLN", 4);
nodever = 1;
} }
else else
{ {
out.AddToLump ("ZGL2", 4); out.AddToLump ("ZGL2", 4);
nodever = 2;
} }
WriteVerticesZ (zout, &Level.GLVertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumGLVertices - Level.NumOrgVerts); WriteVerticesZ (zout, &Level.GLVertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumGLVertices - Level.NumOrgVerts);
WriteSubsectorsZ (zout, Level.GLSubsectors, Level.NumGLSubsectors); WriteSubsectorsZ (zout, Level.GLSubsectors, Level.NumGLSubsectors);
WriteGLSegsZ (zout, Level.GLSegs, Level.NumGLSegs); WriteGLSegsZ (zout, Level.GLSegs, Level.NumGLSegs, nodever);
WriteNodesZ (zout, Level.GLNodes, Level.NumGLNodes); WriteNodesZ (zout, Level.GLNodes, Level.NumGLNodes, nodever);
} }
void FProcessor::WriteVerticesZ (ZLibOut &out, const WideVertex *verts, int orgverts, int newverts) 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; out << (DWORD)numsegs;
if (Level.NumLines() < 65535) if (nodever < 2)
{ {
for (int i = 0; i < numsegs; ++i) 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; out << (DWORD)numnodes;
for (int i = 0; i < numnodes; ++i) for (int i = 0; i < numnodes; ++i)
{ {
out << (SWORD)nodes[i].x if (nodever < 3)
<< (SWORD)nodes[i].y {
<< (SWORD)nodes[i].dx out << (SWORD)(nodes[i].x >> 16)
<< (SWORD)nodes[i].dy; << (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 j = 0; j < 2; ++j)
{ {
for (int k = 0; k < 4; ++k) 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); WriteVerticesX (out, &Level.Vertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumVertices - Level.NumOrgVerts);
WriteSubsectorsX (out, Level.Subsectors, Level.NumSubsectors); WriteSubsectorsX (out, Level.Subsectors, Level.NumSubsectors);
WriteSegsX (out, Level.Segs, Level.NumSegs); 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) void FProcessor::WriteGLBSPX (FWadWriter &out, const char *label)
{ {
bool fracsplitters = CheckForFracSplitters(Level.GLNodes, Level.NumGLNodes);
int nodever;
if (!CompressGLNodes) if (!CompressGLNodes)
{ {
printf (" GL Nodes are so big that extended format has been forced.\n"); printf (" GL Nodes are so big that extended format has been forced.\n");
} }
out.StartWritingLump (label); out.StartWritingLump (label);
if (Level.NumLines() < 65535) if (fracsplitters)
{
out.AddToLump ("XGL3", 4);
nodever = 3;
}
else if (Level.NumLines() < 65535)
{ {
out.AddToLump ("XGLN", 4); out.AddToLump ("XGLN", 4);
nodever = 1;
} }
else else
{ {
out.AddToLump ("XGL2", 4); out.AddToLump ("XGL2", 4);
nodever = 2;
} }
WriteVerticesX (out, &Level.GLVertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumGLVertices - Level.NumOrgVerts); WriteVerticesX (out, &Level.GLVertices[Level.NumOrgVerts], Level.NumOrgVerts, Level.NumGLVertices - Level.NumOrgVerts);
WriteSubsectorsX (out, Level.GLSubsectors, Level.NumGLSubsectors); WriteSubsectorsX (out, Level.GLSubsectors, Level.NumGLSubsectors);
WriteGLSegsX (out, Level.GLSegs, Level.NumGLSegs); WriteGLSegsX (out, Level.GLSegs, Level.NumGLSegs, nodever);
WriteNodesX (out, Level.GLNodes, Level.NumGLNodes); WriteNodesX (out, Level.GLNodes, Level.NumGLNodes, nodever);
} }
void FProcessor::WriteVerticesX (FWadWriter &out, const WideVertex *verts, int orgverts, int newverts) 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; out << (DWORD)numsegs;
if (Level.NumLines() < 65535) if (nodever < 2)
{ {
for (int i = 0; i < numsegs; ++i) 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; out << (DWORD)numnodes;
for (int i = 0; i < numnodes; ++i) for (int i = 0; i < numnodes; ++i)
{ {
out << (SWORD)nodes[i].x if (nodever < 3)
<< (SWORD)nodes[i].y {
<< (SWORD)nodes[i].dx out << (SWORD)(nodes[i].x >> 16)
<< (SWORD)nodes[i].dy; << (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 j = 0; j < 2; ++j)
{ {
for (int k = 0; k < 4; ++k) 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 --------------------------------------------------------- // zlib lump writer ---------------------------------------------------------
ZLibOut::ZLibOut (FWadWriter &out) ZLibOut::ZLibOut (FWadWriter &out)

View file

@ -56,6 +56,7 @@ private:
MapSegGLEx *SegGLsToEx (const MapSegGL *segs, int count); MapSegGLEx *SegGLsToEx (const MapSegGL *segs, int count);
BYTE *FixReject (const BYTE *oldreject); BYTE *FixReject (const BYTE *oldreject);
bool CheckForFracSplitters(const MapNodeEx *nodes, int count);
void WriteLines (FWadWriter &out); void WriteLines (FWadWriter &out);
void WriteVertices (FWadWriter &out, int count); void WriteVertices (FWadWriter &out, int count);
@ -79,8 +80,8 @@ private:
void WriteVerticesZ (ZLibOut &out, const WideVertex *verts, int orgverts, int newverts); void WriteVerticesZ (ZLibOut &out, const WideVertex *verts, int orgverts, int newverts);
void WriteSubsectorsZ (ZLibOut &out, const MapSubsectorEx *subs, int numsubs); void WriteSubsectorsZ (ZLibOut &out, const MapSubsectorEx *subs, int numsubs);
void WriteSegsZ (ZLibOut &out, const MapSegEx *segs, int numsegs); void WriteSegsZ (ZLibOut &out, const MapSegEx *segs, int numsegs);
void WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs); void WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs, int nodever);
void WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes); void WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes, int nodever);
void WriteBSPX (FWadWriter &out, const char *label); void WriteBSPX (FWadWriter &out, const char *label);
void WriteGLBSPX (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 WriteVerticesX (FWadWriter &out, const WideVertex *verts, int orgverts, int newverts);
void WriteSubsectorsX (FWadWriter &out, const MapSubsectorEx *subs, int numsubs); void WriteSubsectorsX (FWadWriter &out, const MapSubsectorEx *subs, int numsubs);
void WriteSegsX (FWadWriter &out, const MapSegEx *segs, int numsegs); void WriteSegsX (FWadWriter &out, const MapSegEx *segs, int numsegs);
void WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs); void WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs, int nodever);
void WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numnodes); 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 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; void WriteSSectors2 (FWadWriter &out, const char *name, const MapSubsectorEx *zaSubs, int count) const;

View file

@ -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) static void DrawLevelNodes (HDC dc)
{ {
HPEN oldPen; HPEN oldPen;
@ -412,17 +426,13 @@ static void DrawLevelNodes (HDC dc)
{ {
DrawOutsideNode (dc, Level->NumNodes - 1); DrawOutsideNode (dc, Level->NumNodes - 1);
DrawNode (dc, Level->NumNodes - 1); DrawNode (dc, Level->NumNodes - 1);
SelectObject (dc, Splitter); DrawSplitter (dc, &Level->Nodes[DesiredNode]);
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);
} }
else else
{ {
DrawOutsideNode (dc, Level->NumGLNodes - 1); DrawOutsideNode (dc, Level->NumGLNodes - 1);
DrawNode (dc, Level->NumGLNodes - 1); DrawNode (dc, Level->NumGLNodes - 1);
SelectObject (dc, Splitter); DrawSplitter (dc, &Level->GLNodes[DesiredNode]);
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);
} }
@ -496,7 +506,7 @@ static void DrawLevelSubsectors (HDC dc)
static inline int PointOnSide (int x, int y, const MapNodeEx &nd) 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; return foo >= 0;
} }

View file

@ -265,7 +265,9 @@
signature. This can be either 'ZNOD' for regular nodes or 'ZGLN' for GL nodes. 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 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 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 Following the signature is the zlib data stream. For a description of its
format, see the zlib documentation. When you decompress it, the following format, see the zlib documentation. When you decompress it, the following
information is obtained in this order:</p> information is obtained in this order:</p>
@ -420,7 +422,7 @@
<td>The linedef's side this seg came from (0=front, 1=back) (ignored if no line)</td> <td>The linedef's side this seg came from (0=front, 1=back) (ignored if no line)</td>
</tr> </tr>
</table> </table>
<h3>GL nodes ('ZGL2' signature)</h3> <h3>GL nodes ('ZGL2' and 'ZGL3' signature)</h3>
<table> <table>
<tr> <tr>
<td>DWORD</td> <td>DWORD</td>
@ -482,7 +484,8 @@
the next seg's first vertex. The last seg's second vertex will be the same as the next seg's first vertex. The last seg's second vertex will be the same as
the first seg's first vertex.</p> the first seg's first vertex.</p>
<h2>Node information</h2> <h2>Node information</h2>
<p>This is really no different from standard nodes.</p> <p>Only 'ZGL3' nodes structure this differently from standard nodes.</p>
<h3>All nodes formats except 'ZGL3'</h3>
<table> <table>
<tr> <tr>
<td>DWORD</td> <td>DWORD</td>
@ -513,6 +516,37 @@
<td>References to child nodes or subsectors</td> <td>References to child nodes or subsectors</td>
</tr> </tr>
</table> </table>
<h3>Nodes with 'ZGL3' signature</h3>
<table>
<tr>
<td>DWORD</td>
<td><i>NumNodes</i></td>
<td>Number of nodes</td>
</tr>
<tr>
<td colspan="3" bgcolor="#dddddd">Repeat <i>NumNodes</i> times:</td>
</tr>
<tr>
<td>4 FIXEDs</td>
<td><i>X</i>, <i>Y</i>, <i>dX</i>, <i>dY</i></td>
<td>Splitter for this node</td>
</tr>
<tr>
<td>4 SWORDs</td>
<td><i>Top</i>, <i>Bottom</i>, <i>Left</i>, <i>Right</i></td>
<td>Bounding box for <i>Child0</i></td>
</tr>
<tr>
<td>4 SWORDs</td>
<td><i>Top</i>, <i>Bottom</i>, <i>Left</i>, <i>Right</i></td>
<td>Bounding box for <i>Child1</i></td>
</tr>
<tr>
<td>2 DWORDs</td>
<td><i>Child0</i>, <i>Child1</i></td>
<td>References to child nodes or subsectors</td>
</tr>
</table>
<p>As with standard nodes, a child's high bit is set to indicate that it is a <p>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 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.</p> the child references are stored using four bytes each instead of two.</p>
@ -528,5 +562,15 @@
compressed nodes are not used.</p> compressed nodes are not used.</p>
<p>For UDMF maps, nodes a stored in the map's ZNODES lump. These will only be <p>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.</p> 'ZGLN' or 'ZGL2' format nodes. Non-GL nodes are not supported for UDMF.</p>
<h2>Extended nodes</h2>
<p>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:</p>
<ul><li>ZNOD -> XNOD</li>
<li>ZGLN -> XGLN</li>
<li>ZGL2 -> XGL2</li>
<li>ZGL3 -> XGL3</li></ul>
</BODY> </BODY>
</HTML> </HTML>

View file

@ -1,487 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="zdbsp"
RootNamespace="zdbsp"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2"
WholeProgramOptimization="TRUE">
<Tool
Name="VCCLCompilerTool"
Optimization="4"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
OptimizeForProcessor="0"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories="zlib"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="0"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/zdbsp.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
OutputFile=".\Release/zdbsp.exe"
LinkIncremental="0"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="&quot;$(VSInstallDir)vc7\lib&quot;"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Release/zdbsp.pdb"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="0"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/zdbsp.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="zlib"
PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/zdbsp.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
OutputFile=".\Debug/zdbsp.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="&quot;$(VSInstallDir)vc7\lib&quot;"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/zdbsp.pdb"
SubSystem="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/zdbsp.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release (SSE2)|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2"
WholeProgramOptimization="TRUE">
<Tool
Name="VCCLCompilerTool"
Optimization="4"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
OptimizeForProcessor="0"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories="zlib"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE,__SSE2__"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
EnableEnhancedInstructionSet="2"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/zdbsp.pch"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
OutputFile=".\Release/zdbsp.exe"
LinkIncremental="0"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="&quot;$(VSInstallDir)vc7\lib&quot;"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Release/zdbsp.pdb"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="0"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/zdbsp.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath=".\blockmapbuilder.cpp">
</File>
<File
RelativePath=".\getopt.c">
</File>
<File
RelativePath="getopt1.c">
</File>
<File
RelativePath=".\main.cpp">
</File>
<File
RelativePath=".\nodebuild.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"/>
</FileConfiguration>
<FileConfiguration
Name="Release (SSE2)|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath=".\nodebuild_classify_nosse2.cpp">
</File>
<File
RelativePath=".\nodebuild_classify_sse1.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
EnableEnhancedInstructionSet="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
EnableEnhancedInstructionSet="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release (SSE2)|Win32">
<Tool
Name="VCCLCompilerTool"
EnableEnhancedInstructionSet="1"/>
</FileConfiguration>
</File>
<File
RelativePath=".\nodebuild_classify_sse2.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
EnableEnhancedInstructionSet="2"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
EnableEnhancedInstructionSet="2"/>
</FileConfiguration>
</File>
<File
RelativePath="nodebuild_events.cpp">
</File>
<File
RelativePath="nodebuild_extract.cpp">
</File>
<File
RelativePath="nodebuild_gl.cpp">
</File>
<File
RelativePath="nodebuild_utility.cpp">
</File>
<File
RelativePath=".\processor.cpp">
</File>
<File
RelativePath=".\view.cpp">
</File>
<File
RelativePath=".\wad.cpp">
</File>
<Filter
Name="Reject(ed)"
Filter="">
<File
RelativePath=".\Unused\rejectbuilder.cpp">
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release (SSE2)|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath=".\Unused\rejectbuilder.h">
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release (SSE2)|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
</File>
<File
RelativePath=".\Unused\vis.cpp">
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release (SSE2)|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath=".\Unused\visflow.cpp">
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release (SSE2)|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath=".\blockmapbuilder.h">
</File>
<File
RelativePath=".\doomdata.h">
</File>
<File
RelativePath="getopt.h">
</File>
<File
RelativePath=".\nodebuild.h">
</File>
<File
RelativePath=".\processor.h">
</File>
<File
RelativePath=".\resource.h">
</File>
<File
RelativePath=".\tarray.h">
</File>
<File
RelativePath=".\templates.h">
</File>
<File
RelativePath=".\wad.h">
</File>
<File
RelativePath=".\workdata.h">
</File>
<File
RelativePath=".\zdbsp.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
<File
RelativePath=".\resource.rc">
</File>
</Filter>
<Filter
Name="zlib"
Filter="">
<File
RelativePath=".\zlib\adler32.c">
</File>
<File
RelativePath=".\zlib\compress.c">
</File>
<File
RelativePath=".\zlib\crc32.c">
</File>
<File
RelativePath=".\zlib\crc32.h">
</File>
<File
RelativePath=".\zlib\deflate.c">
</File>
<File
RelativePath=".\zlib\deflate.h">
</File>
<File
RelativePath=".\zlib\trees.c">
</File>
<File
RelativePath=".\zlib\trees.h">
</File>
<File
RelativePath=".\zlib\zconf.h">
</File>
<File
RelativePath=".\zlib\zlib.h">
</File>
<File
RelativePath=".\zlib\zutil.c">
</File>
</Filter>
<File
RelativePath=".\Makefile">
</File>
<File
RelativePath=".\zdbsp.html">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>