diff --git a/main.cpp b/main.cpp index ae6f9c2..92a9340 100644 --- a/main.cpp +++ b/main.cpp @@ -109,6 +109,7 @@ bool ShowWarnings = false; bool NoTiming = false; bool CompressNodes = false; bool CompressGLNodes = false; +bool ForceCompression = false; bool GLOnly = false; bool V5GLNodes = false; bool HaveSSE1, HaveSSE2; @@ -141,6 +142,7 @@ static option long_opts[] = {"no-timing", no_argument, 0, 't'}, {"compress", no_argument, 0, 'z'}, {"compress-normal", no_argument, 0, 'Z'}, + {"extended", no_argument, 0, 'X'}, {"gl-only", no_argument, 0, 'x'}, {"gl-v5", no_argument, 0, '5'}, {"no-sse", no_argument, 0, 1002}, @@ -149,7 +151,7 @@ static option long_opts[] = {0,0,0,0} }; -static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZx5c"; +static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5c"; // CODE -------------------------------------------------------------------- @@ -380,13 +382,20 @@ static void ParseArgs (int argc, char **argv) BuildGLNodes = true; ConformNodes = true; break; + case 'X': + CompressNodes = true; + CompressGLNodes = true; + ForceCompression = false; + break; case 'z': CompressNodes = true; CompressGLNodes = true; + ForceCompression = true; break; case 'Z': CompressNodes = true; CompressGLNodes = false; + ForceCompression = true; break; case 'x': GLOnly = true; @@ -443,7 +452,7 @@ static void ShowUsage () " -g, --gl Build GL-friendly nodes\n" " -G, --gl-matching Build GL-friendly nodes that match normal nodes\n" " -x, --gl-only Only build GL-friendly nodes\n" -" -5, --gl-v5 Create v5 GL-friedly nodes (ignored if -z is used)\n" +" -5, --gl-v5 Create v5 GL-friedly nodes (ignored if -z or -X is used)\n" " -b, --empty-blockmap Create an empty blockmap\n" " -r, --empty-reject Create an empty reject table\n" " -R, --zero-reject Create a reject table of all zeroes\n" @@ -453,6 +462,7 @@ static void ShowUsage () " -s, --split-cost=NNN Adjusts the cost for splitting segs\n"// (default 8)\n" " -d, --diagonal-cost=NNN Adjusts the cost for avoiding diagonal splitters\n"// (default 16)\n" " -P, --no-polyobjs Do not check for polyobject subsector splits\n" +" -X, --extended Create extended node format (including GL nodes, if created)\n" " -z, --compress Compress the nodes (including GL nodes, if created)\n" " -Z, --compress-normal Compress normal nodes but not GL nodes\n" #ifdef _WIN32 diff --git a/processor.cpp b/processor.cpp index 2e29253..8300625 100644 --- a/processor.cpp +++ b/processor.cpp @@ -781,7 +781,8 @@ void FProcessor::Write (FWadWriter &out) out.CreateLabel ("SEGS"); if (compressGL) { - WriteGLBSPZ (out, "SSECTORS"); + if (ForceCompression) WriteGLBSPZ (out, "SSECTORS"); + else WriteGLBSPX (out, "SSECTORS"); } else { @@ -789,7 +790,8 @@ void FProcessor::Write (FWadWriter &out) } if (!GLOnly) { - WriteBSPZ (out, "NODES"); + if (ForceCompression) WriteBSPZ (out, "NODES"); + else WriteBSPX (out, "NODES"); } else { @@ -1472,6 +1474,124 @@ void FProcessor::WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes } } +void FProcessor::WriteBSPX (FWadWriter &out, const char *label) +{ + if (!CompressNodes) + { + printf (" Nodes are so big that extended format has been forced.\n"); + } + + out.StartWritingLump (label); + out.AddToLump ("XNOD", 4); + 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); +} + +void FProcessor::WriteGLBSPX (FWadWriter &out, const char *label) +{ + if (!CompressGLNodes) + { + printf (" GL Nodes are so big that extended format has been forced.\n"); + } + + out.StartWritingLump (label); + if (Level.NumLines() < 65535) + { + out.AddToLump ("XGLN", 4); + } + else + { + out.AddToLump ("XGL2", 4); + } + 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); +} + +void FProcessor::WriteVerticesX (FWadWriter &out, const WideVertex *verts, int orgverts, int newverts) +{ + out << (DWORD)orgverts << (DWORD)newverts; + + for (int i = 0; i < newverts; ++i) + { + out << verts[i].x << verts[i].y; + } +} + +void FProcessor::WriteSubsectorsX (FWadWriter &out, const MapSubsectorEx *subs, int numsubs) +{ + out << (DWORD)numsubs; + + for (int i = 0; i < numsubs; ++i) + { + out << (DWORD)subs[i].numlines; + } +} + +void FProcessor::WriteSegsX (FWadWriter &out, const MapSeg *segs, int numsegs) +{ + out << (DWORD)numsegs; + + for (int i = 0; i < numsegs; ++i) + { + out << (DWORD)segs[i].v1 + << (DWORD)segs[i].v2 + << (WORD)segs[i].linedef + << (BYTE)segs[i].side; + } +} + +void FProcessor::WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs) +{ + out << (DWORD)numsegs; + + if (Level.NumLines() < 65535) + { + for (int i = 0; i < numsegs; ++i) + { + out << (DWORD)segs[i].v1 + << (DWORD)segs[i].partner + << (WORD)segs[i].linedef + << (BYTE)segs[i].side; + } + } + else + { + for (int i = 0; i < numsegs; ++i) + { + out << (DWORD)segs[i].v1 + << (DWORD)segs[i].partner + << (DWORD)segs[i].linedef + << (BYTE)segs[i].side; + } + } +} + +void FProcessor::WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numnodes) +{ + 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; + for (int j = 0; j < 2; ++j) + { + for (int k = 0; k < 4; ++k) + { + out << (SWORD)nodes[i].bbox[j][k]; + } + } + out << (DWORD)nodes[i].children[0] + << (DWORD)nodes[i].children[1]; + } +} + // zlib lump writer --------------------------------------------------------- ZLibOut::ZLibOut (FWadWriter &out) diff --git a/processor.h b/processor.h index 60437ec..68e3022 100644 --- a/processor.h +++ b/processor.h @@ -82,6 +82,15 @@ private: void WriteGLSegsZ (ZLibOut &out, const MapSegGLEx *segs, int numsegs); void WriteNodesZ (ZLibOut &out, const MapNodeEx *nodes, int numnodes); + void WriteBSPX (FWadWriter &out, const char *label); + void WriteGLBSPX (FWadWriter &out, const char *label); + + 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 MapSeg *segs, int numsegs); + void WriteGLSegsX (FWadWriter &out, const MapSegGLEx *segs, int numsegs); + void WriteNodesX (FWadWriter &out, const MapNodeEx *nodes, int numnodes); + 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 WriteNodes5 (FWadWriter &out, const char *name, const MapNodeEx *zaNodes, int count) const; diff --git a/processor_udmf.cpp b/processor_udmf.cpp index a724910..b52a5a0 100644 --- a/processor_udmf.cpp +++ b/processor_udmf.cpp @@ -578,7 +578,9 @@ void FProcessor::WriteUDMF(FWadWriter &out) { out.CopyLump (Wad, Lump); WriteTextMap(out); - WriteGLBSPZ (out, "ZNODES"); + if (ForceCompression) WriteGLBSPZ (out, "ZNODES"); + else WriteGLBSPX (out, "ZNODES"); + // copy everything except existing nodes, blockmap and reject for(int i=Lump+2; stricmp(Wad.LumpName(i), "ENDMAP") && i < Wad.NumLumps(); i++) { diff --git a/wad.cpp b/wad.cpp index f7f058b..64fb893 100644 --- a/wad.cpp +++ b/wad.cpp @@ -448,3 +448,38 @@ void FWadWriter::SafeWrite (const void *buffer, size_t size) "that you have enough free disk space."); } } + +FWadWriter &FWadWriter::operator << (BYTE val) +{ + SafeWrite (&val, 1); + return *this; +} + +FWadWriter &FWadWriter::operator << (WORD val) +{ + val = LittleShort(val); + SafeWrite ((BYTE *)&val, 2); + return *this; +} + +FWadWriter &FWadWriter::operator << (SWORD val) +{ + val = LittleShort(val); + SafeWrite ((BYTE *)&val, 2); + return *this; +} + +FWadWriter &FWadWriter::operator << (DWORD val) +{ + val = LittleLong(val); + SafeWrite ((BYTE *)&val, 4); + return *this; +} + +FWadWriter &FWadWriter::operator << (fixed_t val) +{ + val = LittleLong(val); + SafeWrite ((BYTE *)&val, 4); + return *this; +} + diff --git a/wad.h b/wad.h index b7a06ee..4f34e75 100644 --- a/wad.h +++ b/wad.h @@ -98,6 +98,12 @@ public: void StartWritingLump (const char *name); void AddToLump (const void *data, int len); + FWadWriter &operator << (BYTE); + FWadWriter &operator << (WORD); + FWadWriter &operator << (SWORD); + FWadWriter &operator << (DWORD); + FWadWriter &operator << (fixed_t); + private: TArray Lumps; FILE *File; diff --git a/zdbsp.h b/zdbsp.h index 01a763f..b8f74d7 100644 --- a/zdbsp.h +++ b/zdbsp.h @@ -44,7 +44,7 @@ extern int SplitCost; extern int AAPreference; extern bool CheckPolyobjs; extern bool ShowMap; -extern bool CompressNodes, CompressGLNodes, V5GLNodes; +extern bool CompressNodes, CompressGLNodes, ForceCompression, V5GLNodes; extern bool HaveSSE1, HaveSSE2; diff --git a/zdbsp_vs2005.sln b/zdbsp_vs2005.sln index 8607041..21b02a6 100644 --- a/zdbsp_vs2005.sln +++ b/zdbsp_vs2005.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 +# Visual C++ Express 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zdbsp_vs2005", "zdbsp_vs2005.vcproj", "{E628034A-AE64-43B5-8CF4-668D07041C35}" EndProject Global