mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-25 05:11:20 +00:00
Remove level writing code as it isn't needed
This commit is contained in:
parent
e9356ea255
commit
b4f22e7959
7 changed files with 308 additions and 1953 deletions
|
@ -130,7 +130,7 @@ endif( NOT STRNICMP_EXISTS )
|
||||||
|
|
||||||
set( ZDRAY_LIBS "${ZLIB_LIBRARIES}" )
|
set( ZDRAY_LIBS "${ZLIB_LIBRARIES}" )
|
||||||
set( SOURCES
|
set( SOURCES
|
||||||
src/commandline/main.cpp
|
src/main.cpp
|
||||||
src/commandline/getopt.c
|
src/commandline/getopt.c
|
||||||
src/commandline/getopt1.c
|
src/commandline/getopt1.c
|
||||||
src/blockmapbuilder/blockmapbuilder.cpp
|
src/blockmapbuilder/blockmapbuilder.cpp
|
||||||
|
|
|
@ -1,713 +0,0 @@
|
||||||
/*
|
|
||||||
The main glue for ZDRay.
|
|
||||||
Copyright (C) 2002-2006 Randy Heit
|
|
||||||
|
|
||||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// HEADER FILES ------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
// Need windows.h for QueryPerformanceCounter
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#define HAVE_TIMING 1
|
|
||||||
#define START_COUNTER(s,e,f) \
|
|
||||||
LARGE_INTEGER s, e, f; QueryPerformanceCounter (&s);
|
|
||||||
#define END_COUNTER(s,e,f,l) \
|
|
||||||
QueryPerformanceCounter (&e); QueryPerformanceFrequency (&f); \
|
|
||||||
if (!NoTiming) printf (l, double(e.QuadPart - s.QuadPart) / double(f.QuadPart));
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#define HAVE_TIMING 1
|
|
||||||
#define START_COUNTER(s,e,f) \
|
|
||||||
clock_t s, e; s = clock();
|
|
||||||
#define END_COUNTER(s,e,f,l) \
|
|
||||||
e = clock(); \
|
|
||||||
if (!NoTiming) printf (l, double(e - s) / CLOCKS_PER_SEC);
|
|
||||||
|
|
||||||
// Need these to check if input/output are the same file
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "framework/zdray.h"
|
|
||||||
#include "wad/wad.h"
|
|
||||||
#include "level/level.h"
|
|
||||||
#include "commandline/getopt.h"
|
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.14159265358979323846
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TYPES -------------------------------------------------------------------
|
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
|
||||||
|
|
||||||
static void ParseArgs (int argc, char **argv);
|
|
||||||
static void ShowUsage ();
|
|
||||||
static void ShowVersion ();
|
|
||||||
static bool CheckInOutNames ();
|
|
||||||
|
|
||||||
#ifndef DISABLE_SSE
|
|
||||||
static void CheckSSE ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
|
||||||
|
|
||||||
extern "C" int optind;
|
|
||||||
extern "C" char *optarg;
|
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
|
||||||
|
|
||||||
const char *Map = NULL;
|
|
||||||
const char *InName;
|
|
||||||
const char *OutName = "tmp.wad";
|
|
||||||
bool BuildNodes = true;
|
|
||||||
bool BuildGLNodes = false;
|
|
||||||
bool ConformNodes = false;
|
|
||||||
bool NoPrune = false;
|
|
||||||
EBlockmapMode BlockmapMode = EBM_Rebuild;
|
|
||||||
ERejectMode RejectMode = ERM_DontTouch;
|
|
||||||
bool WriteComments = false;
|
|
||||||
int MaxSegs = 64;
|
|
||||||
int SplitCost = 8;
|
|
||||||
int AAPreference = 16;
|
|
||||||
bool CheckPolyobjs = true;
|
|
||||||
bool ShowMap = false;
|
|
||||||
bool ShowWarnings = false;
|
|
||||||
bool NoTiming = false;
|
|
||||||
bool CompressNodes = false;
|
|
||||||
bool CompressGLNodes = false;
|
|
||||||
bool ForceCompression = false;
|
|
||||||
bool GLOnly = false;
|
|
||||||
bool V5GLNodes = false;
|
|
||||||
bool HaveSSE1, HaveSSE2;
|
|
||||||
int SSELevel;
|
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
|
||||||
|
|
||||||
static option long_opts[] =
|
|
||||||
{
|
|
||||||
{"help", no_argument, 0, 1000},
|
|
||||||
{"version", no_argument, 0, 'V'},
|
|
||||||
{"view", no_argument, 0, 'v'},
|
|
||||||
{"warn", no_argument, 0, 'w'},
|
|
||||||
{"map", required_argument, 0, 'm'},
|
|
||||||
{"output", required_argument, 0, 'o'},
|
|
||||||
{"output-file", required_argument, 0, 'o'},
|
|
||||||
{"file", required_argument, 0, 'f'},
|
|
||||||
{"no-nodes", no_argument, 0, 'N'},
|
|
||||||
{"gl", no_argument, 0, 'g'},
|
|
||||||
{"gl-matching", no_argument, 0, 'G'},
|
|
||||||
{"empty-blockmap", no_argument, 0, 'b'},
|
|
||||||
{"empty-reject", no_argument, 0, 'r'},
|
|
||||||
{"zero-reject", no_argument, 0, 'R'},
|
|
||||||
{"full-reject", no_argument, 0, 'e'},
|
|
||||||
{"no-reject", no_argument, 0, 'E'},
|
|
||||||
{"partition", required_argument, 0, 'p'},
|
|
||||||
{"split-cost", required_argument, 0, 's'},
|
|
||||||
{"diagonal-cost", required_argument, 0, 'd'},
|
|
||||||
{"no-polyobjs", no_argument, 0, 'P'},
|
|
||||||
{"no-prune", no_argument, 0, 'q'},
|
|
||||||
{"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},
|
|
||||||
{"no-sse2", no_argument, 0, 1003},
|
|
||||||
{"comments", no_argument, 0, 'c'},
|
|
||||||
{0,0,0,0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5c";
|
|
||||||
|
|
||||||
// CODE --------------------------------------------------------------------
|
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
bool fixSame = false;
|
|
||||||
|
|
||||||
#ifdef DISABLE_SSE
|
|
||||||
HaveSSE1 = HaveSSE2 = false;
|
|
||||||
#else
|
|
||||||
HaveSSE1 = HaveSSE2 = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ParseArgs (argc, argv);
|
|
||||||
|
|
||||||
if (InName == NULL)
|
|
||||||
{
|
|
||||||
if (optind >= argc || optind < argc-1)
|
|
||||||
{ // Source file is unspecified or followed by junk
|
|
||||||
ShowUsage ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
InName = argv[optind];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_SSE
|
|
||||||
CheckSSE ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
START_COUNTER(t1a, t1b, t1c)
|
|
||||||
|
|
||||||
if (CheckInOutNames ())
|
|
||||||
{
|
|
||||||
// When the input and output files are the same, output will go to
|
|
||||||
// a temporary file. After everything is done, the input file is
|
|
||||||
// deleted and the output file is renamed to match the input file.
|
|
||||||
|
|
||||||
char *out = new char[strlen(OutName)+3], *dot;
|
|
||||||
|
|
||||||
if (out == NULL)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Could not create temporary file name.");
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy (out, OutName);
|
|
||||||
dot = strrchr (out, '.');
|
|
||||||
if (dot && (dot[1] == 'w' || dot[1] == 'W')
|
|
||||||
&& (dot[2] == 'a' || dot[2] == 'A')
|
|
||||||
&& (dot[3] == 'd' || dot[3] == 'D')
|
|
||||||
&& dot[4] == 0)
|
|
||||||
{
|
|
||||||
// *.wad becomes *.daw
|
|
||||||
dot[1] = 'd';
|
|
||||||
dot[3] = 'w';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// * becomes *.x
|
|
||||||
strcat (out, ".x");
|
|
||||||
}
|
|
||||||
OutName = out;
|
|
||||||
fixSame = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
FWadReader inwad (InName);
|
|
||||||
FWadWriter outwad (OutName, inwad.IsIWAD());
|
|
||||||
|
|
||||||
int lump = 0;
|
|
||||||
int max = inwad.NumLumps ();
|
|
||||||
|
|
||||||
while (lump < max)
|
|
||||||
{
|
|
||||||
if (inwad.IsMap (lump) &&
|
|
||||||
(!Map || stricmp (inwad.LumpName (lump), Map) == 0))
|
|
||||||
{
|
|
||||||
START_COUNTER(t2a, t2b, t2c)
|
|
||||||
FProcessor builder (inwad, lump);
|
|
||||||
builder.Write (outwad);
|
|
||||||
END_COUNTER(t2a, t2b, t2c, " %.3f seconds.\n")
|
|
||||||
|
|
||||||
lump = inwad.LumpAfterMap (lump);
|
|
||||||
}
|
|
||||||
else if (inwad.IsGLNodes (lump))
|
|
||||||
{
|
|
||||||
// Ignore GL nodes from the input for any maps we process.
|
|
||||||
if (BuildNodes && (Map == NULL || stricmp (inwad.LumpName (lump)+3, Map) == 0))
|
|
||||||
{
|
|
||||||
lump = inwad.SkipGLNodes (lump);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outwad.CopyLump (inwad, lump);
|
|
||||||
++lump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//printf ("copy %s\n", inwad.LumpName (lump));
|
|
||||||
outwad.CopyLump (inwad, lump);
|
|
||||||
++lump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outwad.Close ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fixSame)
|
|
||||||
{
|
|
||||||
remove (InName);
|
|
||||||
if (0 != rename (OutName, InName))
|
|
||||||
{
|
|
||||||
printf ("The output file could not be renamed to %s.\nYou can find it as %s.\n",
|
|
||||||
InName, OutName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
END_COUNTER(t1a, t1b, t1c, "\nTotal time: %.3f seconds.\n")
|
|
||||||
}
|
|
||||||
catch (std::runtime_error msg)
|
|
||||||
{
|
|
||||||
printf ("%s\n", msg.what());
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
catch (std::bad_alloc)
|
|
||||||
{
|
|
||||||
printf ("Out of memory\n");
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
catch (std::exception msg)
|
|
||||||
{
|
|
||||||
printf ("%s\n", msg.what());
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
#ifndef _DEBUG
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
printf ("Unhandled exception. ZDRay cannot continue.\n");
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// ParseArgs
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static void ParseArgs (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int ch;
|
|
||||||
|
|
||||||
while ((ch = getopt_long (argc, argv, short_opts, long_opts, NULL)) != EOF)
|
|
||||||
{
|
|
||||||
switch (ch)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
ShowMap = true;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
ShowWarnings = true;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
Map = optarg;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
OutName = optarg;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
InName = optarg;
|
|
||||||
break;
|
|
||||||
case 'N':
|
|
||||||
BuildNodes = false;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
BlockmapMode = EBM_Create0;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
RejectMode = ERM_Create0;
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
RejectMode = ERM_CreateZeroes;
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
RejectMode = ERM_Rebuild;
|
|
||||||
break;
|
|
||||||
case 'E':
|
|
||||||
RejectMode = ERM_DontTouch;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
MaxSegs = atoi (optarg);
|
|
||||||
if (MaxSegs < 3)
|
|
||||||
{ // Don't be too unreasonable
|
|
||||||
MaxSegs = 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
SplitCost = atoi (optarg);
|
|
||||||
if (SplitCost < 1)
|
|
||||||
{ // 1 means to add no extra weight at all
|
|
||||||
SplitCost = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
AAPreference = atoi (optarg);
|
|
||||||
if (AAPreference < 1)
|
|
||||||
{
|
|
||||||
AAPreference = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
CheckPolyobjs = false;
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
BuildGLNodes = true;
|
|
||||||
ConformNodes = false;
|
|
||||||
break;
|
|
||||||
case 'G':
|
|
||||||
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;
|
|
||||||
BuildGLNodes = true;
|
|
||||||
ConformNodes = false;
|
|
||||||
break;
|
|
||||||
case '5':
|
|
||||||
V5GLNodes = true;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
NoPrune = true;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
NoTiming = true;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
WriteComments = true;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
ShowVersion ();
|
|
||||||
exit (0);
|
|
||||||
break;
|
|
||||||
case 1002: // Disable SSE/SSE2 ClassifyLine routine
|
|
||||||
HaveSSE1 = false;
|
|
||||||
HaveSSE2 = false;
|
|
||||||
break;
|
|
||||||
case 1003: // Disable only SSE2 ClassifyLine routine
|
|
||||||
HaveSSE2 = false;
|
|
||||||
break;
|
|
||||||
case 1000:
|
|
||||||
ShowUsage ();
|
|
||||||
exit (0);
|
|
||||||
default:
|
|
||||||
printf ("Try `zdray --help' for more information.\n");
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// ShowUsage
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static void ShowUsage ()
|
|
||||||
{
|
|
||||||
printf (
|
|
||||||
"Usage: zdray [options] sourcefile.wad\n"
|
|
||||||
" -m, --map=MAP Only affect the specified map\n"
|
|
||||||
" -o, --output=FILE Write output to FILE instead of tmp.wad\n"
|
|
||||||
" -q, --no-prune Keep unused sidedefs and sectors\n"
|
|
||||||
" -N, --no-nodes Do not rebuild nodes\n"
|
|
||||||
" -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-friendly nodes (overriden by -z and -X)\n"
|
|
||||||
" -X, --extended Create extended nodes (including GL nodes, if built)\n"
|
|
||||||
" -z, --compress Compress the nodes (including GL nodes, if built)\n"
|
|
||||||
" -Z, --compress-normal Compress normal nodes but not GL nodes\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"
|
|
||||||
//" -e, --full-reject Rebuild reject table (unsupported)\n"
|
|
||||||
" -E, --no-reject Leave reject table untouched\n"
|
|
||||||
" -p, --partition=NNN Maximum segs to consider at each node (default %d)\n"
|
|
||||||
" -s, --split-cost=NNN Cost for splitting segs (default %d)\n"
|
|
||||||
" -d, --diagonal-cost=NNN Cost for avoiding diagonal splitters (default %d)\n"
|
|
||||||
" -P, --no-polyobjs Do not check for polyobject subsector splits\n"
|
|
||||||
#ifdef _WIN32
|
|
||||||
" -v, --view View the nodes\n"
|
|
||||||
#endif
|
|
||||||
" -w, --warn Show warning messages\n"
|
|
||||||
#if HAVE_TIMING
|
|
||||||
" -t, --no-timing Suppress timing information\n"
|
|
||||||
#endif
|
|
||||||
" -V, --version Display version information\n"
|
|
||||||
" --help Display this usage information"
|
|
||||||
#ifndef _WIN32
|
|
||||||
"\n"
|
|
||||||
#endif
|
|
||||||
, MaxSegs /* Partition size */
|
|
||||||
, SplitCost
|
|
||||||
, AAPreference
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// ShowVersion
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static void ShowVersion ()
|
|
||||||
{
|
|
||||||
printf ("ZDRay " ZDRAY_VERSION " ("
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
|
|
||||||
"GCC"
|
|
||||||
#if defined(__i386__)
|
|
||||||
"-x86"
|
|
||||||
#elif defined(__amd64__)
|
|
||||||
"-amd64"
|
|
||||||
#elif defined(__ppc__)
|
|
||||||
"-ppc"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
|
|
||||||
"VC"
|
|
||||||
#if defined(_M_IX86)
|
|
||||||
"-x86"
|
|
||||||
#if _M_IX86_FP > 1
|
|
||||||
"-SSE2"
|
|
||||||
#endif
|
|
||||||
#elif defined(_M_X64)
|
|
||||||
"-x64"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
" : " __DATE__ ")\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// CheckInOutNames
|
|
||||||
//
|
|
||||||
// Returns true if InName and OutName refer to the same file. This needs
|
|
||||||
// to be implemented different under Windows than Unix because the inode
|
|
||||||
// information returned by stat is always 0, so it cannot be used to
|
|
||||||
// determine duplicate files.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static bool CheckInOutNames ()
|
|
||||||
{
|
|
||||||
#ifndef _WIN32
|
|
||||||
struct stat info;
|
|
||||||
dev_t outdev;
|
|
||||||
ino_t outinode;
|
|
||||||
|
|
||||||
if (0 != stat (OutName, &info))
|
|
||||||
{ // If out doesn't exist, it can't be duplicated
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
outdev = info.st_dev;
|
|
||||||
outinode = info.st_ino;
|
|
||||||
if (0 != stat (InName, &info))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return outinode == info.st_ino && outdev == info.st_dev;
|
|
||||||
#else
|
|
||||||
HANDLE inFile, outFile;
|
|
||||||
|
|
||||||
outFile = CreateFile (OutName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (outFile == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
inFile = CreateFile (InName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (inFile == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
CloseHandle (outFile);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BY_HANDLE_FILE_INFORMATION inInfo, outInfo;
|
|
||||||
bool same = false;
|
|
||||||
|
|
||||||
if (GetFileInformationByHandle (inFile, &inInfo) &&
|
|
||||||
GetFileInformationByHandle (outFile, &outInfo))
|
|
||||||
{
|
|
||||||
same = inInfo.dwVolumeSerialNumber == outInfo.dwVolumeSerialNumber &&
|
|
||||||
inInfo.nFileIndexLow == outInfo.nFileIndexLow &&
|
|
||||||
inInfo.nFileIndexHigh == outInfo.nFileIndexHigh;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle (inFile);
|
|
||||||
CloseHandle (outFile);
|
|
||||||
|
|
||||||
return same;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// CheckSSE
|
|
||||||
//
|
|
||||||
// Checks if the processor supports SSE or SSE2.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
#ifndef DISABLE_SSE
|
|
||||||
static void CheckSSE ()
|
|
||||||
{
|
|
||||||
#ifdef __SSE2__
|
|
||||||
// If we compiled with SSE2 support enabled for everything, then
|
|
||||||
// obviously it's available, or the program won't get very far.
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!HaveSSE2 && !HaveSSE1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool forcenosse1 = !HaveSSE1;
|
|
||||||
bool forcenosse2 = !HaveSSE2;
|
|
||||||
|
|
||||||
HaveSSE1 = false;
|
|
||||||
HaveSSE2 = false;
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
|
|
||||||
#ifdef _M_X64
|
|
||||||
// Processors implementing AMD64 are required to support SSE2.
|
|
||||||
return;
|
|
||||||
#else
|
|
||||||
__asm
|
|
||||||
{
|
|
||||||
pushfd // save EFLAGS
|
|
||||||
pop eax // store EFLAGS in EAX
|
|
||||||
mov edx,eax // save in EDX for later testing
|
|
||||||
xor eax,0x00200000 // toggle bit 21
|
|
||||||
push eax // put to stack
|
|
||||||
popfd // save changed EAX to EFLAGS
|
|
||||||
pushfd // push EFLAGS to TOS
|
|
||||||
pop eax // store EFLAGS in EAX
|
|
||||||
cmp eax,edx // see if bit 21 has changed
|
|
||||||
jz noid // if no change, then no CPUID
|
|
||||||
|
|
||||||
// Check the feature flag for SSE/SSE2
|
|
||||||
mov eax,1
|
|
||||||
cpuid
|
|
||||||
test edx,(1<<25) // Check for SSE
|
|
||||||
setnz HaveSSE1
|
|
||||||
test edx,(1<<26) // Check for SSE2
|
|
||||||
setnz HaveSSE2
|
|
||||||
noid:
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(__GNUC__) || defined(__clang__)
|
|
||||||
|
|
||||||
// Same as above, but for GCC
|
|
||||||
asm volatile
|
|
||||||
("pushfl\n\t"
|
|
||||||
"popl %%eax\n\t"
|
|
||||||
"movl %%eax,%%edx\n\t"
|
|
||||||
"xorl $0x200000,%%eax\n\t"
|
|
||||||
"pushl %%eax\n\t"
|
|
||||||
"popfl\n\t"
|
|
||||||
"pushfl\n\t"
|
|
||||||
"popl %%eax\n\t"
|
|
||||||
"cmp %%edx,%%eax\n\t"
|
|
||||||
"jz noid\n\t"
|
|
||||||
"mov $1,%%eax\n\t"
|
|
||||||
"cpuid\n\t"
|
|
||||||
"test $(1<<25),%%edx\n\t"
|
|
||||||
"setneb %0\n"
|
|
||||||
"test $(1<<26),%%edx\n\t"
|
|
||||||
"setneb %1\n"
|
|
||||||
"noid:"
|
|
||||||
:"=m" (HaveSSE1),"=m" (HaveSSE2)::"eax","ebx","ecx","edx");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (forcenosse1)
|
|
||||||
{
|
|
||||||
HaveSSE1 = false;
|
|
||||||
}
|
|
||||||
if (forcenosse2)
|
|
||||||
{
|
|
||||||
HaveSSE2 = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// PointToAngle
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
angle_t PointToAngle (fixed_t x, fixed_t y)
|
|
||||||
{
|
|
||||||
double ang = atan2 (double(y), double(x));
|
|
||||||
const double rad2bam = double(1<<30) / M_PI;
|
|
||||||
double dbam = ang * rad2bam;
|
|
||||||
// Convert to signed first since negative double to unsigned is undefined.
|
|
||||||
return angle_t(int(dbam)) << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Warn
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void Warn (const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list marker;
|
|
||||||
|
|
||||||
if (!ShowWarnings)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start (marker, format);
|
|
||||||
vprintf (format, marker);
|
|
||||||
va_end (marker);
|
|
||||||
}
|
|
1032
src/level/level.cpp
1032
src/level/level.cpp
File diff suppressed because it is too large
Load diff
|
@ -31,12 +31,12 @@ private:
|
||||||
FWadWriter &Out;
|
FWadWriter &Out;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FProcessor
|
class FLevelLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FProcessor (FWadReader &inwad, int lump);
|
FLevelLoader (FWadReader &inwad, int lump);
|
||||||
|
|
||||||
void Write (FWadWriter &out);
|
void BuildNodes ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadUDMF();
|
void LoadUDMF();
|
||||||
|
@ -54,45 +54,6 @@ private:
|
||||||
BYTE *FixReject (const BYTE *oldreject);
|
BYTE *FixReject (const BYTE *oldreject);
|
||||||
bool CheckForFracSplitters(const MapNodeEx *nodes, int count);
|
bool CheckForFracSplitters(const MapNodeEx *nodes, int count);
|
||||||
|
|
||||||
void WriteLines (FWadWriter &out);
|
|
||||||
void WriteVertices (FWadWriter &out, int count);
|
|
||||||
void WriteSectors (FWadWriter &out);
|
|
||||||
void WriteSides (FWadWriter &out);
|
|
||||||
void WriteSegs (FWadWriter &out);
|
|
||||||
void WriteSSectors (FWadWriter &out) const;
|
|
||||||
void WriteNodes (FWadWriter &out) const;
|
|
||||||
void WriteBlockmap (FWadWriter &out);
|
|
||||||
void WriteReject (FWadWriter &out);
|
|
||||||
|
|
||||||
void WriteGLVertices (FWadWriter &out, bool v5);
|
|
||||||
void WriteGLSegs (FWadWriter &out, bool v5);
|
|
||||||
void WriteGLSegs5 (FWadWriter &out);
|
|
||||||
void WriteGLSSect (FWadWriter &out, bool v5);
|
|
||||||
void WriteGLNodes (FWadWriter &out, bool v5);
|
|
||||||
|
|
||||||
void WriteBSPZ (FWadWriter &out, const char *label);
|
|
||||||
void WriteGLBSPZ (FWadWriter &out, const char *label);
|
|
||||||
|
|
||||||
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, 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);
|
|
||||||
|
|
||||||
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, 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;
|
|
||||||
void WriteNodes5 (FWadWriter &out, const char *name, const MapNodeEx *zaNodes, int count) const;
|
|
||||||
void WriteSSectors5 (FWadWriter &out, const char *name, const MapSubsectorEx *zaSubs, int count) const;
|
|
||||||
|
|
||||||
const char *ParseKey(const char *&value);
|
const char *ParseKey(const char *&value);
|
||||||
bool CheckKey(const char *&key, const char *&value);
|
bool CheckKey(const char *&key, const char *&value);
|
||||||
void ParseThing(IntThing *th);
|
void ParseThing(IntThing *th);
|
||||||
|
@ -103,16 +64,6 @@ private:
|
||||||
void ParseMapProperties();
|
void ParseMapProperties();
|
||||||
void ParseTextMap(int lump);
|
void ParseTextMap(int lump);
|
||||||
|
|
||||||
void WriteProps(FWadWriter &out, TArray<UDMFKey> &props);
|
|
||||||
void WriteIntProp(FWadWriter &out, const char *key, int value);
|
|
||||||
void WriteThingUDMF(FWadWriter &out, IntThing *th, int num);
|
|
||||||
void WriteLinedefUDMF(FWadWriter &out, IntLineDef *ld, int num);
|
|
||||||
void WriteSidedefUDMF(FWadWriter &out, IntSideDef *sd, int num);
|
|
||||||
void WriteSectorUDMF(FWadWriter &out, IntSector *sec, int num);
|
|
||||||
void WriteVertexUDMF(FWadWriter &out, IntVertex *vt, int num);
|
|
||||||
void WriteTextMap(FWadWriter &out);
|
|
||||||
void WriteUDMF(FWadWriter &out);
|
|
||||||
|
|
||||||
FLevel Level;
|
FLevel Level;
|
||||||
|
|
||||||
TArray<FNodeBuilder::FPolyStart> PolyStarts;
|
TArray<FNodeBuilder::FPolyStart> PolyStarts;
|
||||||
|
|
|
@ -73,7 +73,7 @@ StringBuffer stbuf;
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
const char *FProcessor::ParseKey(const char *&value)
|
const char *FLevelLoader::ParseKey(const char *&value)
|
||||||
{
|
{
|
||||||
SC_MustGetString();
|
SC_MustGetString();
|
||||||
const char *key = stbuf.Copy(sc_String);
|
const char *key = stbuf.Copy(sc_String);
|
||||||
|
@ -90,7 +90,7 @@ const char *FProcessor::ParseKey(const char *&value)
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FProcessor::CheckKey(const char *&key, const char *&value)
|
bool FLevelLoader::CheckKey(const char *&key, const char *&value)
|
||||||
{
|
{
|
||||||
SC_SavePos();
|
SC_SavePos();
|
||||||
SC_MustGetString();
|
SC_MustGetString();
|
||||||
|
@ -138,7 +138,7 @@ fixed_t CheckFixed(const char *key)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::ParseThing(IntThing *th)
|
void FLevelLoader::ParseThing(IntThing *th)
|
||||||
{
|
{
|
||||||
SC_MustGetStringName("{");
|
SC_MustGetStringName("{");
|
||||||
while (!SC_CheckString("}"))
|
while (!SC_CheckString("}"))
|
||||||
|
@ -178,7 +178,7 @@ void FProcessor::ParseThing(IntThing *th)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::ParseLinedef(IntLineDef *ld)
|
void FLevelLoader::ParseLinedef(IntLineDef *ld)
|
||||||
{
|
{
|
||||||
SC_MustGetStringName("{");
|
SC_MustGetStringName("{");
|
||||||
ld->v1 = ld->v2 = ld->sidenum[0] = ld->sidenum[1] = NO_INDEX;
|
ld->v1 = ld->v2 = ld->sidenum[0] = ld->sidenum[1] = NO_INDEX;
|
||||||
|
@ -229,7 +229,7 @@ void FProcessor::ParseLinedef(IntLineDef *ld)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::ParseSidedef(IntSideDef *sd)
|
void FLevelLoader::ParseSidedef(IntSideDef *sd)
|
||||||
{
|
{
|
||||||
SC_MustGetStringName("{");
|
SC_MustGetStringName("{");
|
||||||
sd->sector = NO_INDEX;
|
sd->sector = NO_INDEX;
|
||||||
|
@ -256,7 +256,7 @@ void FProcessor::ParseSidedef(IntSideDef *sd)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::ParseSector(IntSector *sec)
|
void FLevelLoader::ParseSector(IntSector *sec)
|
||||||
{
|
{
|
||||||
SC_MustGetStringName("{");
|
SC_MustGetStringName("{");
|
||||||
while (!SC_CheckString("}"))
|
while (!SC_CheckString("}"))
|
||||||
|
@ -279,7 +279,7 @@ void FProcessor::ParseSector(IntSector *sec)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::ParseVertex(WideVertex *vt, IntVertex *vtp)
|
void FLevelLoader::ParseVertex(WideVertex *vt, IntVertex *vtp)
|
||||||
{
|
{
|
||||||
vt->x = vt->y = 0;
|
vt->x = vt->y = 0;
|
||||||
SC_MustGetStringName("{");
|
SC_MustGetStringName("{");
|
||||||
|
@ -310,7 +310,7 @@ void FProcessor::ParseVertex(WideVertex *vt, IntVertex *vtp)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::ParseMapProperties()
|
void FLevelLoader::ParseMapProperties()
|
||||||
{
|
{
|
||||||
const char *key, *value;
|
const char *key, *value;
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ void FProcessor::ParseMapProperties()
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::ParseTextMap(int lump)
|
void FLevelLoader::ParseTextMap(int lump)
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int buffersize;
|
int buffersize;
|
||||||
|
@ -393,214 +393,7 @@ void FProcessor::ParseTextMap(int lump)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FProcessor::LoadUDMF()
|
void FLevelLoader::LoadUDMF()
|
||||||
{
|
{
|
||||||
ParseTextMap(Lump+1);
|
ParseTextMap(Lump+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes a property list
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteProps(FWadWriter &out, TArray<UDMFKey> &props)
|
|
||||||
{
|
|
||||||
for(unsigned i=0; i< props.Size(); i++)
|
|
||||||
{
|
|
||||||
out.AddToLump(props[i].key, (int)strlen(props[i].key));
|
|
||||||
out.AddToLump(" = ", 3);
|
|
||||||
out.AddToLump(props[i].value, (int)strlen(props[i].value));
|
|
||||||
out.AddToLump(";\n", 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes an integer property
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteIntProp(FWadWriter &out, const char *key, int value)
|
|
||||||
{
|
|
||||||
char buffer[20];
|
|
||||||
|
|
||||||
out.AddToLump(key, (int)strlen(key));
|
|
||||||
out.AddToLump(" = ", 3);
|
|
||||||
sprintf(buffer, "%d;\n", value);
|
|
||||||
out.AddToLump(buffer, (int)strlen(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes a UDMF thing
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteThingUDMF(FWadWriter &out, IntThing *th, int num)
|
|
||||||
{
|
|
||||||
out.AddToLump("thing", 5);
|
|
||||||
if (WriteComments)
|
|
||||||
{
|
|
||||||
char buffer[32];
|
|
||||||
int len = sprintf(buffer, " // %d", num);
|
|
||||||
out.AddToLump(buffer, len);
|
|
||||||
}
|
|
||||||
out.AddToLump("\n{\n", 3);
|
|
||||||
WriteProps(out, th->props);
|
|
||||||
out.AddToLump("}\n\n", 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes a UDMF linedef
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteLinedefUDMF(FWadWriter &out, IntLineDef *ld, int num)
|
|
||||||
{
|
|
||||||
out.AddToLump("linedef", 7);
|
|
||||||
if (WriteComments)
|
|
||||||
{
|
|
||||||
char buffer[32];
|
|
||||||
int len = sprintf(buffer, " // %d", num);
|
|
||||||
out.AddToLump(buffer, len);
|
|
||||||
}
|
|
||||||
out.AddToLump("\n{\n", 3);
|
|
||||||
WriteIntProp(out, "v1", ld->v1);
|
|
||||||
WriteIntProp(out, "v2", ld->v2);
|
|
||||||
if (ld->sidenum[0] != NO_INDEX) WriteIntProp(out, "sidefront", ld->sidenum[0]);
|
|
||||||
if (ld->sidenum[1] != NO_INDEX) WriteIntProp(out, "sideback", ld->sidenum[1]);
|
|
||||||
WriteProps(out, ld->props);
|
|
||||||
out.AddToLump("}\n\n", 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes a UDMF sidedef
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteSidedefUDMF(FWadWriter &out, IntSideDef *sd, int num)
|
|
||||||
{
|
|
||||||
out.AddToLump("sidedef", 7);
|
|
||||||
if (WriteComments)
|
|
||||||
{
|
|
||||||
char buffer[32];
|
|
||||||
int len = sprintf(buffer, " // %d", num);
|
|
||||||
out.AddToLump(buffer, len);
|
|
||||||
}
|
|
||||||
out.AddToLump("\n{\n", 3);
|
|
||||||
WriteIntProp(out, "sector", sd->sector);
|
|
||||||
WriteProps(out, sd->props);
|
|
||||||
out.AddToLump("}\n\n", 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes a UDMF sector
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteSectorUDMF(FWadWriter &out, IntSector *sec, int num)
|
|
||||||
{
|
|
||||||
out.AddToLump("sector", 6);
|
|
||||||
if (WriteComments)
|
|
||||||
{
|
|
||||||
char buffer[32];
|
|
||||||
int len = sprintf(buffer, " // %d", num);
|
|
||||||
out.AddToLump(buffer, len);
|
|
||||||
}
|
|
||||||
out.AddToLump("\n{\n", 3);
|
|
||||||
WriteProps(out, sec->props);
|
|
||||||
out.AddToLump("}\n\n", 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes a UDMF vertex
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteVertexUDMF(FWadWriter &out, IntVertex *vt, int num)
|
|
||||||
{
|
|
||||||
out.AddToLump("vertex", 6);
|
|
||||||
if (WriteComments)
|
|
||||||
{
|
|
||||||
char buffer[32];
|
|
||||||
int len = sprintf(buffer, " // %d", num);
|
|
||||||
out.AddToLump(buffer, len);
|
|
||||||
}
|
|
||||||
out.AddToLump("\n{\n", 3);
|
|
||||||
WriteProps(out, vt->props);
|
|
||||||
out.AddToLump("}\n\n", 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes a UDMF text map
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteTextMap(FWadWriter &out)
|
|
||||||
{
|
|
||||||
out.StartWritingLump("TEXTMAP");
|
|
||||||
WriteProps(out, Level.props);
|
|
||||||
for(int i = 0; i < Level.NumThings(); i++)
|
|
||||||
{
|
|
||||||
WriteThingUDMF(out, &Level.Things[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < Level.NumOrgVerts; i++)
|
|
||||||
{
|
|
||||||
WideVertex *vt = &Level.Vertices[i];
|
|
||||||
if (vt->index <= 0)
|
|
||||||
{
|
|
||||||
// not valid!
|
|
||||||
throw std::runtime_error("Invalid vertex data.");
|
|
||||||
}
|
|
||||||
WriteVertexUDMF(out, &Level.VertexProps[vt->index-1], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < Level.NumLines(); i++)
|
|
||||||
{
|
|
||||||
WriteLinedefUDMF(out, &Level.Lines[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < Level.NumSides(); i++)
|
|
||||||
{
|
|
||||||
WriteSidedefUDMF(out, &Level.Sides[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < Level.NumSectors(); i++)
|
|
||||||
{
|
|
||||||
WriteSectorUDMF(out, &Level.Sectors[i], i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// writes an UDMF map
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FProcessor::WriteUDMF(FWadWriter &out)
|
|
||||||
{
|
|
||||||
out.CopyLump (Wad, Lump);
|
|
||||||
WriteTextMap(out);
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
const char *lumpname = Wad.LumpName(i);
|
|
||||||
if (stricmp(lumpname, "ZNODES") &&
|
|
||||||
stricmp(lumpname, "BLOCKMAP") &&
|
|
||||||
stricmp(lumpname, "REJECT"))
|
|
||||||
{
|
|
||||||
out.CopyLump(Wad, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.CreateLabel("ENDMAP");
|
|
||||||
}
|
|
||||||
|
|
223
src/main.cpp
Normal file
223
src/main.cpp
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "commandline/getopt.h"
|
||||||
|
#include "framework/zdray.h"
|
||||||
|
#include "wad/wad.h"
|
||||||
|
#include "level/level.h"
|
||||||
|
|
||||||
|
static void ParseArgs(int argc, char **argv);
|
||||||
|
static void ShowUsage();
|
||||||
|
static void ShowVersion();
|
||||||
|
static bool CheckInOutNames();
|
||||||
|
|
||||||
|
const char *Map = nullptr;
|
||||||
|
const char *InName = nullptr;
|
||||||
|
const char *OutName = "zdray.bin";
|
||||||
|
bool ShowMap = false;
|
||||||
|
bool ShowWarnings = false;
|
||||||
|
|
||||||
|
// Constants that used to be args in zdbsp
|
||||||
|
bool NoPrune = false;
|
||||||
|
EBlockmapMode BlockmapMode = EBM_Rebuild;
|
||||||
|
ERejectMode RejectMode = ERM_DontTouch;
|
||||||
|
int MaxSegs = 64;
|
||||||
|
int SplitCost = 8;
|
||||||
|
int AAPreference = 16;
|
||||||
|
bool CheckPolyobjs = true;
|
||||||
|
|
||||||
|
static option long_opts[] =
|
||||||
|
{
|
||||||
|
{"help", no_argument, 0, 1000},
|
||||||
|
{"version", no_argument, 0, 'V'},
|
||||||
|
{"view", no_argument, 0, 'v'},
|
||||||
|
{"warn", no_argument, 0, 'w'},
|
||||||
|
{"map", required_argument, 0, 'm'},
|
||||||
|
{"output", required_argument, 0, 'o'},
|
||||||
|
{"output-file", required_argument, 0, 'o'},
|
||||||
|
{"file", required_argument, 0, 'f'},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char short_opts[] = "wVvm:o:f:";
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ParseArgs(argc, argv);
|
||||||
|
|
||||||
|
if (InName == nullptr)
|
||||||
|
{
|
||||||
|
if (optind >= argc || optind < argc - 1)
|
||||||
|
{
|
||||||
|
ShowUsage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
InName = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FWadReader inwad(InName);
|
||||||
|
|
||||||
|
int lump = 0;
|
||||||
|
int max = inwad.NumLumps();
|
||||||
|
while (lump < max)
|
||||||
|
{
|
||||||
|
if (inwad.IsMap(lump) && (!Map || stricmp(inwad.LumpName(lump), Map) == 0))
|
||||||
|
{
|
||||||
|
FLevelLoader loader(inwad, lump);
|
||||||
|
loader.BuildNodes();
|
||||||
|
|
||||||
|
lump = inwad.LumpAfterMap(lump);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++lump;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::runtime_error msg)
|
||||||
|
{
|
||||||
|
printf("%s\n", msg.what());
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
catch (std::bad_alloc)
|
||||||
|
{
|
||||||
|
printf("Out of memory\n");
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
catch (std::exception msg)
|
||||||
|
{
|
||||||
|
printf("%s\n", msg.what());
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
#ifndef _DEBUG
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("Unhandled exception. ZDRay cannot continue.\n");
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseArgs(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
while ((ch = getopt_long(argc, argv, short_opts, long_opts, nullptr)) != EOF)
|
||||||
|
{
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
ShowMap = true;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
ShowWarnings = true;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
Map = optarg;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
OutName = optarg;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
InName = optarg;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
ShowVersion();
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
case 1000:
|
||||||
|
ShowUsage();
|
||||||
|
exit(0);
|
||||||
|
default:
|
||||||
|
printf("Try `zdray --help' for more information.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ShowUsage
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void ShowUsage()
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"Usage: zdray [options] sourcefile.wad\n"
|
||||||
|
" -m, --map=MAP Only affect the specified map\n"
|
||||||
|
" -o, --output=FILE Write output to FILE instead of zdray.bin\n"
|
||||||
|
#ifdef _WIN32
|
||||||
|
" -v, --view View progress\n"
|
||||||
|
#endif
|
||||||
|
" -w, --warn Show warning messages\n"
|
||||||
|
" -V, --version Display version information\n"
|
||||||
|
" --help Display this usage information"
|
||||||
|
#ifndef _WIN32
|
||||||
|
"\n"
|
||||||
|
#else
|
||||||
|
"\r\n"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ShowVersion
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void ShowVersion()
|
||||||
|
{
|
||||||
|
printf("ZDRay " ZDRAY_VERSION " ("
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
|
||||||
|
"GCC"
|
||||||
|
#if defined(__i386__)
|
||||||
|
"-x86"
|
||||||
|
#elif defined(__amd64__)
|
||||||
|
"-amd64"
|
||||||
|
#elif defined(__ppc__)
|
||||||
|
"-ppc"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
|
||||||
|
"VC"
|
||||||
|
#if defined(_M_IX86)
|
||||||
|
"-x86"
|
||||||
|
#if _M_IX86_FP > 1
|
||||||
|
"-SSE2"
|
||||||
|
#endif
|
||||||
|
#elif defined(_M_X64)
|
||||||
|
"-x64"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
" : " __DATE__ ")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Warn(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list marker;
|
||||||
|
|
||||||
|
if (!ShowWarnings)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(marker, format);
|
||||||
|
vprintf(format, marker);
|
||||||
|
va_end(marker);
|
||||||
|
}
|
|
@ -320,3 +320,12 @@ inline int FNodeBuilder::ClassifyLine (node_t &node, const FPrivVert *v1, const
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline angle_t PointToAngle(fixed_t x, fixed_t y)
|
||||||
|
{
|
||||||
|
double ang = atan2(double(y), double(x));
|
||||||
|
const double rad2bam = double(1 << 30) / 3.14159265358979323846;
|
||||||
|
double dbam = ang * rad2bam;
|
||||||
|
// Convert to signed first since negative double to unsigned is undefined.
|
||||||
|
return angle_t(int(dbam)) << 1;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue