mirror of
https://github.com/ZDoom/zdbsp.git
synced 2024-11-24 12:51:24 +00:00
ZDBSP:
- Add headers to generated CMake projects. - Made SSELevel global so that ClassifyLineBackpatch can see it without being part of FNodeBuilder. With backpatching enabled, it's rather pointless to have a different one per nodebuilder instance, anyway. - Change ClassifyLineBackpatch so it doesn't need any inline assembly to do its magic. - Change the ClassifyLine functions to be extern "C" linkage. SVN r2410 (trunk)
This commit is contained in:
parent
983907fd20
commit
2de2b094ec
11 changed files with 358 additions and 377 deletions
392
CMakeLists.txt
392
CMakeLists.txt
|
@ -1,189 +1,203 @@
|
||||||
cmake_minimum_required( VERSION 2.4 )
|
cmake_minimum_required( VERSION 2.4 )
|
||||||
if( COMMAND cmake_policy )
|
if( COMMAND cmake_policy )
|
||||||
cmake_policy( SET CMP0003 NEW )
|
cmake_policy( SET CMP0003 NEW )
|
||||||
endif( COMMAND cmake_policy )
|
endif( COMMAND cmake_policy )
|
||||||
|
|
||||||
|
|
||||||
include( CheckFunctionExists )
|
include( CheckFunctionExists )
|
||||||
include( CheckCXXCompilerFlag )
|
include( CheckCXXCompilerFlag )
|
||||||
|
|
||||||
IF( NOT CMAKE_BUILD_TYPE )
|
IF( NOT CMAKE_BUILD_TYPE )
|
||||||
SET( CMAKE_BUILD_TYPE Debug CACHE STRING
|
SET( CMAKE_BUILD_TYPE Debug CACHE STRING
|
||||||
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
||||||
FORCE )
|
FORCE )
|
||||||
ENDIF( NOT CMAKE_BUILD_TYPE )
|
ENDIF( NOT CMAKE_BUILD_TYPE )
|
||||||
|
|
||||||
set( SSE_MATTERS NO )
|
set( SSE_MATTERS NO )
|
||||||
|
|
||||||
# SSE only matters on 32-bit targets. We check compiler flags to know if we can do it.
|
# SSE only matters on 32-bit targets. We check compiler flags to know if we can do it.
|
||||||
if( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
if( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
||||||
CHECK_CXX_COMPILER_FLAG( "-msse2 -mfpmath=sse" CAN_DO_MFPMATH )
|
CHECK_CXX_COMPILER_FLAG( "-msse2 -mfpmath=sse" CAN_DO_MFPMATH )
|
||||||
CHECK_CXX_COMPILER_FLAG( -arch:SSE2 CAN_DO_ARCHSSE2 )
|
CHECK_CXX_COMPILER_FLAG( -arch:SSE2 CAN_DO_ARCHSSE2 )
|
||||||
if( CAN_DO_MFPMATH )
|
if( CAN_DO_MFPMATH )
|
||||||
set( SSE1_ENABLE "-msse -mfpmath=sse" )
|
set( SSE1_ENABLE "-msse -mfpmath=sse" )
|
||||||
set( SSE2_ENABLE "-msse2 -mfpmath=sse" )
|
set( SSE2_ENABLE "-msse2 -mfpmath=sse" )
|
||||||
set( SSE_MATTERS YES )
|
set( SSE_MATTERS YES )
|
||||||
elseif( CAN_DO_ARCHSSE2 )
|
elseif( CAN_DO_ARCHSSE2 )
|
||||||
set( SSE1_ENABLE -arch:SSE )
|
set( SSE1_ENABLE -arch:SSE )
|
||||||
set( SSE2_ENABLE -arch:SSE2 )
|
set( SSE2_ENABLE -arch:SSE2 )
|
||||||
set( SSE_MATTERS YES )
|
set( SSE_MATTERS YES )
|
||||||
endif( CAN_DO_MFPMATH )
|
endif( CAN_DO_MFPMATH )
|
||||||
endif( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
endif( CMAKE_SIZEOF_VOID_P MATCHES "4" )
|
||||||
|
|
||||||
if( SSE_MATTERS )
|
if( SSE_MATTERS )
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX AND WIN32 )
|
if( CMAKE_COMPILER_IS_GNUCXX AND WIN32 )
|
||||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||||
endif( CMAKE_COMPILER_IS_GNUCXX AND WIN32 )
|
endif( CMAKE_COMPILER_IS_GNUCXX AND WIN32 )
|
||||||
set( FULL_SSE2 0 CACHE BOOL "Use SSE2 math everywhere." )
|
set( FULL_SSE2 0 CACHE BOOL "Use SSE2 math everywhere." )
|
||||||
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
||||||
endif( SSE_MATTERS )
|
endif( SSE_MATTERS )
|
||||||
|
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
set( GPROF 0 CACHE BOOL "Enable profiling with gprof for Debug and RelWithDebInfo build types." )
|
set( GPROF 0 CACHE BOOL "Enable profiling with gprof for Debug and RelWithDebInfo build types." )
|
||||||
endif( CMAKE_COMPILER_IS_GNUCXX )
|
endif( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
|
||||||
find_package( ZLIB )
|
find_package( ZLIB )
|
||||||
|
|
||||||
if( MSVC )
|
if( MSVC )
|
||||||
# Eliminate unreferenced functions and data
|
# Eliminate unreferenced functions and data
|
||||||
# Perform identical COMDAT folding
|
# Perform identical COMDAT folding
|
||||||
set( REL_LINKER_FLAGS "/opt:ref /opt:icf /nodefaultlib:msvcrt" )
|
set( REL_LINKER_FLAGS "/opt:ref /opt:icf /nodefaultlib:msvcrt" )
|
||||||
|
|
||||||
# String pooling
|
# String pooling
|
||||||
# Function-level linking
|
# Function-level linking
|
||||||
# Disable run-time type information
|
# Disable run-time type information
|
||||||
set( ALL_C_FLAGS "/GF /Gy /GR-" )
|
set( ALL_C_FLAGS "/GF /Gy /GR-" )
|
||||||
|
|
||||||
# Avoid CRT DLL dependancies in release builds
|
# Avoid CRT DLL dependancies in release builds
|
||||||
set( REL_C_FLAGS "/MT" )
|
set( REL_C_FLAGS "/MT" )
|
||||||
|
|
||||||
# Disable warnings for unsecure CRT functions from VC8+
|
# Disable warnings for unsecure CRT functions from VC8+
|
||||||
if( MSVC_VERSION GREATER 1399 )
|
if( MSVC_VERSION GREATER 1399 )
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996" )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} /wd4996" )
|
||||||
endif( MSVC_VERSION GREATER 1399 )
|
endif( MSVC_VERSION GREATER 1399 )
|
||||||
|
|
||||||
# The CMake configurations set /GR and /MD by default, which conflict with our settings.
|
# The CMake configurations set /GR and /MD by default, which conflict with our settings.
|
||||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} )
|
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} )
|
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} )
|
||||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} )
|
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} )
|
||||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} )
|
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} )
|
||||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} )
|
string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} )
|
||||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO} )
|
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO} )
|
||||||
string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} )
|
string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} )
|
||||||
endif( MSVC )
|
endif( MSVC )
|
||||||
|
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -ffast-math -pipe" )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} -ffast-math -pipe" )
|
||||||
if( GPROF )
|
if( GPROF )
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -pg -g" )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} -pg -g" )
|
||||||
else( GPROF )
|
else( GPROF )
|
||||||
set( REL_C_FLAGS "${REL_C_FLAGS} -fomit-frame-pointer" )
|
set( REL_C_FLAGS "${REL_C_FLAGS} -fomit-frame-pointer" )
|
||||||
endif( GPROF )
|
endif( GPROF )
|
||||||
if( PROFILE EQUAL 1 )
|
if( PROFILE EQUAL 1 )
|
||||||
message( STATUS "Generating profile coverage information" )
|
message( STATUS "Generating profile coverage information" )
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -fprofile-generate" )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} -fprofile-generate" )
|
||||||
set( PROF_LIB "gcov" )
|
set( PROF_LIB "gcov" )
|
||||||
elseif( PROFILE EQUAL 2 )
|
elseif( PROFILE EQUAL 2 )
|
||||||
message( STATUS "Using profile coverage information" )
|
message( STATUS "Using profile coverage information" )
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -fprofile-use" )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} -fprofile-use" )
|
||||||
endif( PROFILE EQUAL 1 )
|
endif( PROFILE EQUAL 1 )
|
||||||
endif( CMAKE_COMPILER_IS_GNUCXX )
|
endif( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
|
||||||
if( ZLIB_FOUND )
|
if( ZLIB_FOUND )
|
||||||
message( STATUS "Using system zlib" )
|
message( STATUS "Using system zlib" )
|
||||||
else( ZLIB_FOUND )
|
else( ZLIB_FOUND )
|
||||||
message( STATUS "Using internal zlib" )
|
message( STATUS "Using internal zlib" )
|
||||||
add_subdirectory( zlib )
|
add_subdirectory( zlib )
|
||||||
set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zlib )
|
set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zlib )
|
||||||
set( ZLIB_LIBRARIES z )
|
set( ZLIB_LIBRARIES z )
|
||||||
set( ZLIB_LIBRARY z )
|
set( ZLIB_LIBRARY z )
|
||||||
endif( ZLIB_FOUND )
|
endif( ZLIB_FOUND )
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS( stricmp STRICMP_EXISTS )
|
CHECK_FUNCTION_EXISTS( stricmp STRICMP_EXISTS )
|
||||||
if( NOT STRICMP_EXISTS )
|
if( NOT STRICMP_EXISTS )
|
||||||
add_definitions( -Dstricmp=strcasecmp )
|
add_definitions( -Dstricmp=strcasecmp )
|
||||||
endif( NOT STRICMP_EXISTS )
|
endif( NOT STRICMP_EXISTS )
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS( strnicmp STRNICMP_EXISTS )
|
CHECK_FUNCTION_EXISTS( strnicmp STRNICMP_EXISTS )
|
||||||
if( NOT STRNICMP_EXISTS )
|
if( NOT STRNICMP_EXISTS )
|
||||||
add_definitions( -Dstrnicmp=strncasecmp )
|
add_definitions( -Dstrnicmp=strncasecmp )
|
||||||
endif( NOT STRNICMP_EXISTS )
|
endif( NOT STRNICMP_EXISTS )
|
||||||
|
|
||||||
set( ZDBSP_LIBS "${ZLIB_LIBRARIES}" )
|
set( ZDBSP_LIBS "${ZLIB_LIBRARIES}" )
|
||||||
set( SOURCES
|
set( SOURCES
|
||||||
main.cpp
|
main.cpp
|
||||||
getopt.c
|
getopt.c
|
||||||
getopt1.c
|
getopt1.c
|
||||||
blockmapbuilder.cpp
|
blockmapbuilder.cpp
|
||||||
processor.cpp
|
processor.cpp
|
||||||
processor_udmf.cpp
|
processor_udmf.cpp
|
||||||
sc_man.cpp
|
sc_man.cpp
|
||||||
wad.cpp
|
wad.cpp
|
||||||
nodebuild.cpp
|
nodebuild.cpp
|
||||||
nodebuild_events.cpp
|
nodebuild_events.cpp
|
||||||
nodebuild_extract.cpp
|
nodebuild_extract.cpp
|
||||||
nodebuild_gl.cpp
|
nodebuild_gl.cpp
|
||||||
nodebuild_utility.cpp
|
nodebuild_utility.cpp
|
||||||
nodebuild_classify_nosse2.cpp
|
nodebuild_classify_nosse2.cpp
|
||||||
)
|
)
|
||||||
if( WIN32 )
|
if( WIN32 )
|
||||||
set( SOURCES "${SOURCES} view.cpp" )
|
set( SOURCES "${SOURCES}" view.cpp )
|
||||||
else( WIN32 )
|
else( WIN32 )
|
||||||
add_definitions( -DNO_MAP_VIEWER )
|
add_definitions( -DNO_MAP_VIEWER )
|
||||||
endif( WIN32 )
|
endif( WIN32 )
|
||||||
|
|
||||||
if( SSE_MATTERS )
|
set( HEADERS
|
||||||
if( FULL_SSE2 )
|
blockmapbuilder.h
|
||||||
message( STATUS "Using SSE2 math everywhere." )
|
doomdata.h
|
||||||
# Building everything with SSE2 is much like disabling it, in that we
|
getopt.h
|
||||||
# need not check for its existance while running.
|
nodebuild.h
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DDISABLE_SSE ${SSE2_ENABLE}" )
|
processor.h
|
||||||
else( FULL_SSE2 )
|
resource.h
|
||||||
if( SSE )
|
sc_man.h
|
||||||
message( STATUS "Using SSE math for ClassifyLine only." )
|
tarray.h
|
||||||
set( SOURCES ${SOURCES} nodebuild_classify_sse1.cpp nodebuild_classify_sse2.cpp )
|
templates.h
|
||||||
set_source_files_properties( nodebuild_classify_sse1.cpp PROPERTIES COMPILE_FLAGS "${SSE1_ENABLE}" )
|
wad.h
|
||||||
set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "${SSE2_ENABLE}" )
|
workdata.h
|
||||||
else( SSE )
|
zdbsp.h )
|
||||||
message( STATUS "SSE math is completely disabled." )
|
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DDISABLE_SSE" )
|
if( SSE_MATTERS )
|
||||||
endif( SSE )
|
if( FULL_SSE2 )
|
||||||
endif( FULL_SSE2 )
|
message( STATUS "Using SSE2 math everywhere." )
|
||||||
else( SSE_MATTERS )
|
# Building everything with SSE2 is much like disabling it, in that we
|
||||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DDISABLE_SSE" )
|
# need not check for its existance while running.
|
||||||
endif( SSE_MATTERS )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DDISABLE_SSE ${SSE2_ENABLE}" )
|
||||||
|
else( FULL_SSE2 )
|
||||||
if( WIN32 )
|
if( SSE )
|
||||||
set( ZDBSP_LIBS ${ZDBSP_LIBS} user32 gdi32 )
|
message( STATUS "Using SSE math for ClassifyLine only." )
|
||||||
|
set( SOURCES ${SOURCES} nodebuild_classify_sse1.cpp nodebuild_classify_sse2.cpp )
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
set_source_files_properties( nodebuild_classify_sse1.cpp PROPERTIES COMPILE_FLAGS "${SSE1_ENABLE}" )
|
||||||
# CMake is not set up to compile and link rc files with GCC. :(
|
set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "${SSE2_ENABLE}" )
|
||||||
add_custom_command( OUTPUT zdbsp-rc.o
|
else( SSE )
|
||||||
COMMAND windres -o zdbsp-rc.o -i ${CMAKE_CURRENT_SOURCE_DIR}/resource.rc
|
message( STATUS "SSE math is completely disabled." )
|
||||||
DEPENDS resource.rc )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DDISABLE_SSE" )
|
||||||
set( SOURCES ${SOURCES} zdbsp-rc.o )
|
endif( SSE )
|
||||||
else( CMAKE_COMPILER_IS_GNUCXX )
|
endif( FULL_SSE2 )
|
||||||
set( SOURCES ${SOURCES} resource.rc )
|
else( SSE_MATTERS )
|
||||||
endif( CMAKE_COMPILER_IS_GNUCXX )
|
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DDISABLE_SSE" )
|
||||||
endif( WIN32 )
|
endif( SSE_MATTERS )
|
||||||
|
|
||||||
|
if( WIN32 )
|
||||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )
|
set( ZDBSP_LIBS ${ZDBSP_LIBS} user32 gdi32 )
|
||||||
set( CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} ${REL_LINKER_FLAGS}" )
|
|
||||||
set( CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${REL_LINKER_FLAGS}" )
|
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
# CMake is not set up to compile and link rc files with GCC. :(
|
||||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALL_C_FLAGS}" )
|
add_custom_command( OUTPUT zdbsp-rc.o
|
||||||
set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${REL_C_FLAGS}" )
|
COMMAND windres -o zdbsp-rc.o -i ${CMAKE_CURRENT_SOURCE_DIR}/resource.rc
|
||||||
set( CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" )
|
DEPENDS resource.rc )
|
||||||
set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" )
|
set( SOURCES ${SOURCES} zdbsp-rc.o )
|
||||||
set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
else( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
set( SOURCES ${SOURCES} resource.rc )
|
||||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALL_C_FLAGS}" )
|
endif( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${REL_C_FLAGS}" )
|
endif( WIN32 )
|
||||||
set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" )
|
|
||||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" )
|
|
||||||
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )
|
||||||
|
set( CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} ${REL_LINKER_FLAGS}" )
|
||||||
add_executable( zdbsp ${SOURCES} )
|
set( CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${REL_LINKER_FLAGS}" )
|
||||||
target_link_libraries( zdbsp ${ZDBSP_LIBS} ${PROF_LIB} )
|
|
||||||
include_directories( "${ZLIB_INCLUDE_DIR}" )
|
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALL_C_FLAGS}" )
|
||||||
|
set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${REL_C_FLAGS}" )
|
||||||
|
set( CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" )
|
||||||
|
set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" )
|
||||||
|
set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
||||||
|
|
||||||
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALL_C_FLAGS}" )
|
||||||
|
set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${REL_C_FLAGS}" )
|
||||||
|
set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" )
|
||||||
|
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" )
|
||||||
|
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
||||||
|
|
||||||
|
add_executable( zdbsp ${SOURCES} ${HEADERS} )
|
||||||
|
target_link_libraries( zdbsp ${ZDBSP_LIBS} ${PROF_LIB} )
|
||||||
|
include_directories( "${ZLIB_INCLUDE_DIR}" )
|
||||||
|
|
1
main.cpp
1
main.cpp
|
@ -113,6 +113,7 @@ bool ForceCompression = false;
|
||||||
bool GLOnly = false;
|
bool GLOnly = false;
|
||||||
bool V5GLNodes = false;
|
bool V5GLNodes = false;
|
||||||
bool HaveSSE1, HaveSSE2;
|
bool HaveSSE1, HaveSSE2;
|
||||||
|
int SSELevel;
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,11 @@
|
||||||
|
|
||||||
FNodeBuilder::FNodeBuilder (FLevel &level,
|
FNodeBuilder::FNodeBuilder (FLevel &level,
|
||||||
TArray<FPolyStart> &polyspots, TArray<FPolyStart> &anchors,
|
TArray<FPolyStart> &polyspots, TArray<FPolyStart> &anchors,
|
||||||
const char *name, bool makeGLnodes, BYTE sselevel)
|
const char *name, bool makeGLnodes)
|
||||||
: Level(level), SegsStuffed(0), MapName(name)
|
: Level(level), SegsStuffed(0), MapName(name)
|
||||||
{
|
{
|
||||||
VertexMap = new FVertexMap (*this, Level.MinX, Level.MinY, Level.MaxX, Level.MaxY);
|
VertexMap = new FVertexMap (*this, Level.MinX, Level.MinY, Level.MaxX, Level.MaxY);
|
||||||
GLNodes = makeGLnodes;
|
GLNodes = makeGLnodes;
|
||||||
SSELevel = sselevel;
|
|
||||||
FindUsedVertices (Level.Vertices, Level.NumVertices);
|
FindUsedVertices (Level.Vertices, Level.NumVertices);
|
||||||
MakeSegsFromSides ();
|
MakeSegsFromSides ();
|
||||||
FindPolyContainers (polyspots, anchors);
|
FindPolyContainers (polyspots, anchors);
|
||||||
|
@ -508,7 +507,7 @@ int FNodeBuilder::Heuristic (node_t &node, DWORD set, bool honorNoSplit)
|
||||||
int realSegs[2] = { 0, 0 };
|
int realSegs[2] = { 0, 0 };
|
||||||
int specialSegs[2] = { 0, 0 };
|
int specialSegs[2] = { 0, 0 };
|
||||||
DWORD i = set;
|
DWORD i = set;
|
||||||
int sidev1, sidev2;
|
int sidev[2];
|
||||||
int side;
|
int side;
|
||||||
bool splitter = false;
|
bool splitter = false;
|
||||||
unsigned int max, m2, p, q;
|
unsigned int max, m2, p, q;
|
||||||
|
@ -527,7 +526,7 @@ int FNodeBuilder::Heuristic (node_t &node, DWORD set, bool honorNoSplit)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
side = ClassifyLine (node, test, sidev1, sidev2);
|
side = ClassifyLine (node, &Vertices[test->v1], &Vertices[test->v2], sidev);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (side)
|
switch (side)
|
||||||
|
@ -538,9 +537,9 @@ int FNodeBuilder::Heuristic (node_t &node, DWORD set, bool honorNoSplit)
|
||||||
// The "right" thing to do in this case is to only reject it if there is
|
// The "right" thing to do in this case is to only reject it if there is
|
||||||
// another nosplit seg from the same sector at this vertex. Note that a line
|
// another nosplit seg from the same sector at this vertex. Note that a line
|
||||||
// that lies exactly on top of the splitter is okay.
|
// that lies exactly on top of the splitter is okay.
|
||||||
if (test->loopnum && honorNoSplit && (sidev1 == 0 || sidev2 == 0))
|
if (test->loopnum && honorNoSplit && (sidev[0] == 0 || sidev[1] == 0))
|
||||||
{
|
{
|
||||||
if ((sidev1 | sidev2) != 0)
|
if ((sidev[0] | sidev[1]) != 0)
|
||||||
{
|
{
|
||||||
max = Touched.Size();
|
max = Touched.Size();
|
||||||
for (p = 0; p < max; ++p)
|
for (p = 0; p < max; ++p)
|
||||||
|
@ -752,18 +751,18 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
|
||||||
FPrivSeg *seg = &Segs[set];
|
FPrivSeg *seg = &Segs[set];
|
||||||
int next = seg->next;
|
int next = seg->next;
|
||||||
|
|
||||||
int sidev1, sidev2, side;
|
int sidev[2], side;
|
||||||
|
|
||||||
if (HackSeg == set)
|
if (HackSeg == set)
|
||||||
{
|
{
|
||||||
HackSeg = DWORD_MAX;
|
HackSeg = DWORD_MAX;
|
||||||
side = 1;
|
side = 1;
|
||||||
sidev1 = sidev2 = 0;
|
sidev[0] = sidev[1] = 0;
|
||||||
hack = true;
|
hack = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
side = ClassifyLine (node, seg, sidev1, sidev2);
|
side = ClassifyLine (node, &Vertices[seg->v1], &Vertices[seg->v2], sidev);
|
||||||
hack = false;
|
hack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,7 +809,7 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
|
||||||
Printf("SelectVertexClose selected endpoint of seg %u\n", (unsigned int)set);
|
Printf("SelectVertexClose selected endpoint of seg %u\n", (unsigned int)set);
|
||||||
}
|
}
|
||||||
|
|
||||||
seg2 = SplitSeg (set, vertnum, sidev1);
|
seg2 = SplitSeg (set, vertnum, sidev[0]);
|
||||||
|
|
||||||
Segs[seg2].next = outset0;
|
Segs[seg2].next = outset0;
|
||||||
outset0 = seg2;
|
outset0 = seg2;
|
||||||
|
@ -821,7 +820,7 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
|
||||||
if (Segs[set].partner != DWORD_MAX)
|
if (Segs[set].partner != DWORD_MAX)
|
||||||
{
|
{
|
||||||
int partner1 = Segs[set].partner;
|
int partner1 = Segs[set].partner;
|
||||||
int partner2 = SplitSeg (partner1, vertnum, sidev2);
|
int partner2 = SplitSeg (partner1, vertnum, sidev[1]);
|
||||||
// The newly created seg stays in the same set as the
|
// The newly created seg stays in the same set as the
|
||||||
// back seg because it has not been considered for splitting
|
// back seg because it has not been considered for splitting
|
||||||
// yet. If it had been, then the front seg would have already
|
// yet. If it had been, then the front seg would have already
|
||||||
|
@ -847,17 +846,17 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
|
||||||
}
|
}
|
||||||
if (side >= 0 && GLNodes)
|
if (side >= 0 && GLNodes)
|
||||||
{
|
{
|
||||||
if (sidev1 == 0)
|
if (sidev[0] == 0)
|
||||||
{
|
{
|
||||||
double dist1 = AddIntersection (node, seg->v1);
|
double dist1 = AddIntersection (node, seg->v1);
|
||||||
if (sidev2 == 0)
|
if (sidev[1] == 0)
|
||||||
{
|
{
|
||||||
double dist2 = AddIntersection (node, seg->v2);
|
double dist2 = AddIntersection (node, seg->v2);
|
||||||
FSplitSharer share = { dist1, set, dist2 > dist1 };
|
FSplitSharer share = { dist1, set, dist2 > dist1 };
|
||||||
SplitSharers.Push (share);
|
SplitSharers.Push (share);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sidev2 == 0)
|
else if (sidev[1] == 0)
|
||||||
{
|
{
|
||||||
AddIntersection (node, seg->v2);
|
AddIntersection (node, seg->v2);
|
||||||
}
|
}
|
||||||
|
@ -1058,39 +1057,31 @@ void FNodeBuilder::PrintSet (int l, DWORD set)
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
int FNodeBuilder::ClassifyLineBackpatch (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2)
|
extern "C" int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||||
{
|
{
|
||||||
// Select the routine based on SSELevel and patch the caller so that
|
// Select the routine based on SSELevel and patch the caller so that
|
||||||
// they call that routine directly next time instead of going through here.
|
// they call that routine directly next time instead of going through here.
|
||||||
int *calleroffset = (int *)__builtin_return_address(0) - 1;
|
int *calleroffset = (int *)__builtin_return_address(0) - 1;
|
||||||
int diff;
|
int diff;
|
||||||
int (*func)(FNodeBuilder *, node_t &, const FNodeBuilder::FPrivSeg *, int &, int &);
|
int (*func)(node_t &, const FSimpleVert *, const FSimpleVert *, int[2]);
|
||||||
DWORD oldprotect;
|
DWORD oldprotect;
|
||||||
|
|
||||||
// printf ("Patching for SSE %d\n", SSELevel);
|
// printf ("Patching for SSE %d\n", SSELevel);
|
||||||
|
|
||||||
// I wasn't sure how to calculate the difference between the function addresses with C++
|
|
||||||
// (or if it's even possible), so here's some asm to do it instead:
|
|
||||||
if (SSELevel == 2)
|
if (SSELevel == 2)
|
||||||
{
|
{
|
||||||
__asm (
|
func = ClassifyLineSSE2;
|
||||||
"movl $__ZN12FNodeBuilder16ClassifyLineSSE2ER6node_tPKNS_8FPrivSegERiS5_,%1\n\t"
|
diff = (char *)ClassifyLineSSE2 - (char *)ClassifyLineBackpatch;
|
||||||
"movl $__ZN12FNodeBuilder16ClassifyLineSSE2ER6node_tPKNS_8FPrivSegERiS5_-__ZN12FNodeBuilder21ClassifyLineBackpatchER6node_tPKNS_8FPrivSegERiS5_,%0\n\t"
|
|
||||||
: "=r" (diff), "=r" (func));
|
|
||||||
}
|
}
|
||||||
else if (SSELevel == 1)
|
else if (SSELevel == 1)
|
||||||
{
|
{
|
||||||
__asm (
|
func = ClassifyLineSSE1;
|
||||||
"movl $__ZN12FNodeBuilder16ClassifyLineSSE1ER6node_tPKNS_8FPrivSegERiS5_,%1\n\t"
|
diff = (char *)ClassifyLineSSE1 - (char *)ClassifyLineBackpatch;
|
||||||
"movl $__ZN12FNodeBuilder16ClassifyLineSSE1ER6node_tPKNS_8FPrivSegERiS5_-__ZN12FNodeBuilder21ClassifyLineBackpatchER6node_tPKNS_8FPrivSegERiS5_,%0\n\t"
|
|
||||||
: "=r" (diff), "=r" (func));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
__asm (
|
func = ClassifyLine2;
|
||||||
"movl $__ZN12FNodeBuilder13ClassifyLine2ER6node_tPKNS_8FPrivSegERiS5_,%1\n\t"
|
diff = (char *)ClassifyLine2 - (char *)ClassifyLineBackpatch;
|
||||||
"movl $__ZN12FNodeBuilder13ClassifyLine2ER6node_tPKNS_8FPrivSegERiS5_-__ZN12FNodeBuilder21ClassifyLineBackpatchER6node_tPKNS_8FPrivSegERiS5_,%0\n\t"
|
|
||||||
: "=r" (diff), "=r" (func));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch the caller.
|
// Patch the caller.
|
||||||
|
@ -1101,6 +1092,6 @@ int FNodeBuilder::ClassifyLineBackpatch (node_t &node, const FPrivSeg *seg, int
|
||||||
}
|
}
|
||||||
|
|
||||||
// And return by calling the real function.
|
// And return by calling the real function.
|
||||||
return func (this, node, seg, sidev1, sidev2);
|
return func (node, v1, v2, sidev);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
51
nodebuild.h
51
nodebuild.h
|
@ -45,6 +45,23 @@ private:
|
||||||
void PrintTree (const FEvent *event) const;
|
void PrintTree (const FEvent *event) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FSimpleVert
|
||||||
|
{
|
||||||
|
fixed_t x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
int ClassifyLine2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||||
|
#ifndef DISABLE_SSE
|
||||||
|
int ClassifyLineSSE1 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||||
|
int ClassifyLineSSE2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||||
|
#if defined(_WIN32) && defined(__GNUC__) && !defined(DISABLE_BACKPATCH)
|
||||||
|
int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]) __attribute__((noinline));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
class FNodeBuilder
|
class FNodeBuilder
|
||||||
{
|
{
|
||||||
struct FPrivSeg
|
struct FPrivSeg
|
||||||
|
@ -67,9 +84,8 @@ class FNodeBuilder
|
||||||
bool planefront;
|
bool planefront;
|
||||||
FPrivSeg *hashnext;
|
FPrivSeg *hashnext;
|
||||||
};
|
};
|
||||||
struct FPrivVert
|
struct FPrivVert : FSimpleVert
|
||||||
{
|
{
|
||||||
fixed_t x, y;
|
|
||||||
DWORD segs; // segs that use this vertex as v1
|
DWORD segs; // segs that use this vertex as v1
|
||||||
DWORD segs2; // segs that use this vertex as v2
|
DWORD segs2; // segs that use this vertex as v2
|
||||||
int index;
|
int index;
|
||||||
|
@ -139,7 +155,7 @@ public:
|
||||||
|
|
||||||
FNodeBuilder (FLevel &level,
|
FNodeBuilder (FLevel &level,
|
||||||
TArray<FPolyStart> &polyspots, TArray<FPolyStart> &anchors,
|
TArray<FPolyStart> &polyspots, TArray<FPolyStart> &anchors,
|
||||||
const char *name, bool makeGLnodes, BYTE sselevel);
|
const char *name, bool makeGLnodes);
|
||||||
~FNodeBuilder ();
|
~FNodeBuilder ();
|
||||||
|
|
||||||
void GetVertices (WideVertex *&verts, int &count);
|
void GetVertices (WideVertex *&verts, int &count);
|
||||||
|
@ -179,7 +195,6 @@ private:
|
||||||
DWORD HackMate; // Seg to use in front of hack seg
|
DWORD HackMate; // Seg to use in front of hack seg
|
||||||
FLevel &Level;
|
FLevel &Level;
|
||||||
bool GLNodes;
|
bool GLNodes;
|
||||||
int SSELevel;
|
|
||||||
|
|
||||||
// Progress meter stuff
|
// Progress meter stuff
|
||||||
int SegsStuffed;
|
int SegsStuffed;
|
||||||
|
@ -211,16 +226,7 @@ private:
|
||||||
// 1 = seg is in back
|
// 1 = seg is in back
|
||||||
// -1 = seg cuts the node
|
// -1 = seg cuts the node
|
||||||
|
|
||||||
inline int ClassifyLine (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2);
|
inline int ClassifyLine (node_t &node, const FPrivVert *v1, const FPrivVert *v2, int sidev[2]);
|
||||||
int ClassifyLine2 (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2);
|
|
||||||
#ifndef DISABLE_SSE
|
|
||||||
int ClassifyLineSSE1 (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2);
|
|
||||||
int ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2);
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(__GNUC__) && !defined(DISABLE_BACKPATCH)
|
|
||||||
int ClassifyLineBackpatch (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2) __attribute__((noinline));
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FixSplitSharers ();
|
void FixSplitSharers ();
|
||||||
double AddIntersection (const node_t &node, int vertex);
|
double AddIntersection (const node_t &node, int vertex);
|
||||||
|
@ -281,29 +287,28 @@ inline int FNodeBuilder::PointOnSide (int x, int y, int x1, int y1, int dx, int
|
||||||
return s_num > 0.0 ? -1 : 1;
|
return s_num > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int FNodeBuilder::ClassifyLine (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2)
|
inline int FNodeBuilder::ClassifyLine (node_t &node, const FPrivVert *v1, const FPrivVert *v2, int sidev[2])
|
||||||
{
|
{
|
||||||
#ifdef DISABLE_SSE
|
#ifdef DISABLE_SSE
|
||||||
return ClassifyLine2 (node, seg, sidev1, sidev2);
|
return ClassifyLine2 (node, v1, v2, sidev);
|
||||||
#else
|
#else
|
||||||
#if defined(__SSE2__) || defined(_M_IX64)
|
#if defined(__SSE2__) || defined(_M_IX64)
|
||||||
// If compiling with SSE2 support everywhere, just use the SSE2 version.
|
// If compiling with SSE2 support everywhere, just use the SSE2 version.
|
||||||
return ClassifyLineSSE2 (node, seg, sidev1, sidev2);
|
return ClassifyLineSSE2 (node, v1, v2, sidev);
|
||||||
#elif defined(_MSC_VER) && _MSC_VER < 1300
|
#elif defined(_MSC_VER) && _MSC_VER < 1300
|
||||||
// VC 6 does not support SSE optimizations.
|
// VC 6 does not support SSE optimizations.
|
||||||
return ClassifyLine2 (node, seg, sidev1, sidev2);
|
return ClassifyLine2 (node, v1, v2, sidev);
|
||||||
#else
|
#else
|
||||||
// Select the routine based on our flag.
|
// Select the routine based on our flag.
|
||||||
#if defined(_WIN32) && defined(__GNUC__) && !defined(DISABLE_BACKPATCH)
|
#if defined(_WIN32) && defined(__GNUC__) && !defined(DISABLE_BACKPATCH)
|
||||||
return ClassifyLineBackpatch (node, seg, sidev1, sidev2);
|
return ClassifyLineBackpatch (node, v1, v2, sidev);
|
||||||
#else
|
#else
|
||||||
if (SSELevel == 2)
|
if (SSELevel == 2)
|
||||||
{ int foo = ClassifyLineSSE2 (node, seg, sidev1, sidev2); assert(foo == ClassifyLine2(node,seg,sidev1,sidev2));
|
return ClassifyLineSSE2 (node, v1, v2, sidev);
|
||||||
return foo; }
|
|
||||||
else if (SSELevel == 1)
|
else if (SSELevel == 1)
|
||||||
return ClassifyLineSSE1 (node, seg, sidev1, sidev2);
|
return ClassifyLineSSE1 (node, v1, v2, sidev);
|
||||||
else
|
else
|
||||||
return ClassifyLine2 (node, seg, sidev1, sidev2);
|
return ClassifyLine2 (node, v1, v2, sidev);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,11 +23,8 @@
|
||||||
|
|
||||||
#define FAR_ENOUGH 17179869184.f // 4<<32
|
#define FAR_ENOUGH 17179869184.f // 4<<32
|
||||||
|
|
||||||
int FNodeBuilder::ClassifyLine2 (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2)
|
extern "C" int ClassifyLine2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||||
{
|
{
|
||||||
const FPrivVert *v1 = &Vertices[seg->v1];
|
|
||||||
const FPrivVert *v2 = &Vertices[seg->v2];
|
|
||||||
|
|
||||||
double d_x1 = double(node.x);
|
double d_x1 = double(node.x);
|
||||||
double d_y1 = double(node.y);
|
double d_y1 = double(node.y);
|
||||||
double d_dx = double(node.dx);
|
double d_dx = double(node.dx);
|
||||||
|
@ -46,13 +43,13 @@ int FNodeBuilder::ClassifyLine2 (node_t &node, const FPrivSeg *seg, int &sidev1,
|
||||||
{
|
{
|
||||||
if (s_num2 <= -FAR_ENOUGH)
|
if (s_num2 <= -FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = 1;
|
sidev[0] = sidev[1] = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (s_num2 >= FAR_ENOUGH)
|
if (s_num2 >= FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = 1;
|
sidev[0] = 1;
|
||||||
sidev2 = -1;
|
sidev[1] = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
|
@ -61,13 +58,13 @@ int FNodeBuilder::ClassifyLine2 (node_t &node, const FPrivSeg *seg, int &sidev1,
|
||||||
{
|
{
|
||||||
if (s_num2 >= FAR_ENOUGH)
|
if (s_num2 >= FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = -1;
|
sidev[0] = sidev[1] = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (s_num2 <= -FAR_ENOUGH)
|
if (s_num2 <= -FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = -1;
|
sidev[0] = -1;
|
||||||
sidev2 = 1;
|
sidev[1] = 1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
|
@ -85,41 +82,41 @@ int FNodeBuilder::ClassifyLine2 (node_t &node, const FPrivSeg *seg, int &sidev1,
|
||||||
double dist = s_num1 * s_num1 * l;
|
double dist = s_num1 * s_num1 * l;
|
||||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||||
{
|
{
|
||||||
sidev1 = 0;
|
sidev[0] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
if (nears & 1)
|
if (nears & 1)
|
||||||
{
|
{
|
||||||
double dist = s_num2 * s_num2 * l;
|
double dist = s_num2 * s_num2 * l;
|
||||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||||
{
|
{
|
||||||
sidev2 = 0;
|
sidev[1] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sidev1 | sidev2) == 0)
|
if ((sidev[0] | sidev[1]) == 0)
|
||||||
{ // seg is coplanar with the splitter, so use its orientation to determine
|
{ // seg is coplanar with the splitter, so use its orientation to determine
|
||||||
// which child it ends up in. If it faces the same direction as the splitter,
|
// which child it ends up in. If it faces the same direction as the splitter,
|
||||||
// it goes in front. Otherwise, it goes in back.
|
// it goes in front. Otherwise, it goes in back.
|
||||||
|
@ -147,11 +144,11 @@ int FNodeBuilder::ClassifyLine2 (node_t &node, const FPrivSeg *seg, int &sidev1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sidev1 <= 0 && sidev2 <= 0)
|
else if (sidev[0] <= 0 && sidev[1] <= 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (sidev1 >= 0 && sidev2 >= 0)
|
else if (sidev[0] >= 0 && sidev[1] >= 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,8 @@
|
||||||
// The reason it is SSE is because this file is explicitly compiled
|
// The reason it is SSE is because this file is explicitly compiled
|
||||||
// with SSE math enabled, but the other files are not.
|
// with SSE math enabled, but the other files are not.
|
||||||
|
|
||||||
int FNodeBuilder::ClassifyLineSSE1 (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2)
|
extern "C" int ClassifyLineSSE1 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||||
{
|
{
|
||||||
const FPrivVert *v1 = &Vertices[seg->v1];
|
|
||||||
const FPrivVert *v2 = &Vertices[seg->v2];
|
|
||||||
|
|
||||||
double d_x1 = double(node.x);
|
double d_x1 = double(node.x);
|
||||||
double d_y1 = double(node.y);
|
double d_y1 = double(node.y);
|
||||||
double d_dx = double(node.dx);
|
double d_dx = double(node.dx);
|
||||||
|
@ -52,13 +49,13 @@ int FNodeBuilder::ClassifyLineSSE1 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
{
|
{
|
||||||
if (s_num2 <= -FAR_ENOUGH)
|
if (s_num2 <= -FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = 1;
|
sidev[0] = sidev[1] = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (s_num2 >= FAR_ENOUGH)
|
if (s_num2 >= FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = 1;
|
sidev[0] = 1;
|
||||||
sidev2 = -1;
|
sidev[1] = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
|
@ -67,13 +64,13 @@ int FNodeBuilder::ClassifyLineSSE1 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
{
|
{
|
||||||
if (s_num2 >= FAR_ENOUGH)
|
if (s_num2 >= FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = -1;
|
sidev[0] = sidev[1] = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (s_num2 <= -FAR_ENOUGH)
|
if (s_num2 <= -FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = -1;
|
sidev[0] = -1;
|
||||||
sidev2 = 1;
|
sidev[1] = 1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
|
@ -91,41 +88,41 @@ int FNodeBuilder::ClassifyLineSSE1 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
double dist = s_num1 * s_num1 * l;
|
double dist = s_num1 * s_num1 * l;
|
||||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||||
{
|
{
|
||||||
sidev1 = 0;
|
sidev[0] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
if (nears & 1)
|
if (nears & 1)
|
||||||
{
|
{
|
||||||
double dist = s_num2 * s_num2 * l;
|
double dist = s_num2 * s_num2 * l;
|
||||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||||
{
|
{
|
||||||
sidev2 = 0;
|
sidev[1] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sidev1 | sidev2) == 0)
|
if ((sidev[0] | sidev[1]) == 0)
|
||||||
{ // seg is coplanar with the splitter, so use its orientation to determine
|
{ // seg is coplanar with the splitter, so use its orientation to determine
|
||||||
// which child it ends up in. If it faces the same direction as the splitter,
|
// which child it ends up in. If it faces the same direction as the splitter,
|
||||||
// it goes in front. Otherwise, it goes in back.
|
// it goes in front. Otherwise, it goes in back.
|
||||||
|
@ -153,11 +150,11 @@ int FNodeBuilder::ClassifyLineSSE1 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sidev1 <= 0 && sidev2 <= 0)
|
else if (sidev[0] <= 0 && sidev[1] <= 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (sidev1 >= 0 && sidev2 >= 0)
|
else if (sidev[0] >= 0 && sidev[1] >= 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,8 @@
|
||||||
// The reason it is SSE2 is because this file is explicitly compiled
|
// The reason it is SSE2 is because this file is explicitly compiled
|
||||||
// with SSE2 math enabled, but the other files are not.
|
// with SSE2 math enabled, but the other files are not.
|
||||||
|
|
||||||
int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2)
|
extern "C" int ClassifyLineSSE2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||||
{
|
{
|
||||||
const FPrivVert *v1 = &Vertices[seg->v1];
|
|
||||||
const FPrivVert *v2 = &Vertices[seg->v2];
|
|
||||||
|
|
||||||
double d_x1 = double(node.x);
|
double d_x1 = double(node.x);
|
||||||
double d_y1 = double(node.y);
|
double d_y1 = double(node.y);
|
||||||
double d_dx = double(node.dx);
|
double d_dx = double(node.dx);
|
||||||
|
@ -52,13 +49,13 @@ int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
{
|
{
|
||||||
if (s_num2 <= -FAR_ENOUGH)
|
if (s_num2 <= -FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = 1;
|
sidev[0] = sidev[1] = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (s_num2 >= FAR_ENOUGH)
|
if (s_num2 >= FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = 1;
|
sidev[0] = 1;
|
||||||
sidev2 = -1;
|
sidev[1] = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
|
@ -67,13 +64,13 @@ int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
{
|
{
|
||||||
if (s_num2 >= FAR_ENOUGH)
|
if (s_num2 >= FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = -1;
|
sidev[0] = sidev[1] = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (s_num2 <= -FAR_ENOUGH)
|
if (s_num2 <= -FAR_ENOUGH)
|
||||||
{
|
{
|
||||||
sidev1 = -1;
|
sidev[0] = -1;
|
||||||
sidev2 = 1;
|
sidev[1] = 1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
|
@ -91,41 +88,41 @@ int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
double dist = s_num1 * s_num1 * l;
|
double dist = s_num1 * s_num1 * l;
|
||||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||||
{
|
{
|
||||||
sidev1 = 0;
|
sidev[0] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
if (nears & 1)
|
if (nears & 1)
|
||||||
{
|
{
|
||||||
double dist = s_num2 * s_num2 * l;
|
double dist = s_num2 * s_num2 * l;
|
||||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||||
{
|
{
|
||||||
sidev2 = 0;
|
sidev[1] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sidev1 = s_num1 > 0.0 ? -1 : 1;
|
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||||
sidev2 = s_num2 > 0.0 ? -1 : 1;
|
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sidev1 | sidev2) == 0)
|
if ((sidev[0] | sidev[1]) == 0)
|
||||||
{ // seg is coplanar with the splitter, so use its orientation to determine
|
{ // seg is coplanar with the splitter, so use its orientation to determine
|
||||||
// which child it ends up in. If it faces the same direction as the splitter,
|
// which child it ends up in. If it faces the same direction as the splitter,
|
||||||
// it goes in front. Otherwise, it goes in back.
|
// it goes in front. Otherwise, it goes in back.
|
||||||
|
@ -153,11 +150,11 @@ int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sidev1 <= 0 && sidev2 <= 0)
|
else if (sidev[0] <= 0 && sidev[1] <= 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (sidev1 >= 0 && sidev2 >= 0)
|
else if (sidev[0] >= 0 && sidev[1] >= 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,20 +30,17 @@
|
||||||
// The reason it is SSE2 is because this file is explicitly compiled
|
// The reason it is SSE2 is because this file is explicitly compiled
|
||||||
// with SSE2 math enabled, but the other files are not.
|
// with SSE2 math enabled, but the other files are not.
|
||||||
|
|
||||||
int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &sidev1, int &sidev2)
|
extern "C" int ClassifyLineSSE2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||||
{
|
{
|
||||||
const FPrivVert *v1 = &Vertices[seg->v1];
|
|
||||||
const FPrivVert *v2 = &Vertices[seg->v2];
|
|
||||||
|
|
||||||
__m128d xy, dxy, xyv1, xyv2;
|
__m128d xy, dxy, xyv1, xyv2;
|
||||||
|
|
||||||
// Why does this intrinsic go through an MMX register, when it can just go through memory?
|
// Why does this intrinsic go through an MMX register, when it can just go through memory?
|
||||||
// That would let it work with x64, too.
|
// That would let it work with x64, too. (This only applies to VC++. GCC
|
||||||
xy = _mm_cvtpi32_pd(node.p64); // d_y1 d_x1
|
// is smarter and can load directly from memory without touching the MMX registers.)
|
||||||
dxy = _mm_cvtpi32_pd(node.d64); // d_dy d_dx
|
xy = _mm_cvtpi32_pd(*(__m64*)&node.x); // d_y1 d_x1
|
||||||
xyv1 = _mm_cvtpi32_pd(v1->p64); // d_yv1 d_xv1
|
dxy = _mm_cvtpi32_pd(*(__m64*)&node.dx); // d_dy d_dx
|
||||||
xyv2 = _mm_cvtpi32_pd(v2->p64); // d_yv2 d_xv2
|
xyv1 = _mm_cvtpi32_pd(*(__m64*)&v1->x); // d_yv1 d_xv1
|
||||||
_mm_empty();
|
xyv2 = _mm_cvtpi32_pd(*(__m64*)&v2->x); // d_yv2 d_xv2
|
||||||
|
|
||||||
__m128d num1, num2, dyx;
|
__m128d num1, num2, dyx;
|
||||||
|
|
||||||
|
@ -76,54 +73,56 @@ int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
__int64 ni[2], pi[2];
|
int ni[4], pi[4];
|
||||||
};
|
};
|
||||||
};
|
} _;
|
||||||
|
|
||||||
_mm_storeu_pd(n, neg_check);
|
_mm_storeu_pd(_.n, neg_check);
|
||||||
_mm_storeu_pd(p, pos_check);
|
_mm_storeu_pd(_.p, pos_check);
|
||||||
|
|
||||||
int nears = 0;
|
int nears = 0;
|
||||||
|
|
||||||
if (ni[0])
|
if (_.ni[0])
|
||||||
{
|
{
|
||||||
if (ni[1])
|
if (_.ni[2])
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = 1;
|
sidev[0] = sidev[1] = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (pi[1])
|
if (_.pi[2])
|
||||||
{
|
{
|
||||||
sidev1 = 1;
|
sidev[0] = 1;
|
||||||
sidev2 = -1;
|
sidev[1] = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
}
|
}
|
||||||
else if (pi[0])
|
else if (_.pi[0])
|
||||||
{
|
{
|
||||||
if (pi[1])
|
if (_.pi[2])
|
||||||
{
|
{
|
||||||
sidev1 = sidev2 = -1;
|
sidev[0] = sidev[1] = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ni[1])
|
if (_.ni[2])
|
||||||
{
|
{
|
||||||
sidev1 = -1;
|
sidev[0] = -1;
|
||||||
sidev2 = 1;
|
sidev[1] = 1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nears = 1;
|
nears = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nears = 2 | ((ni[1] | pi[1]) ? 0 : 1);
|
nears = 2 | ((_.ni[2] | _.pi[2]) ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
__m128d zero = _mm_setzero_pd();
|
__m128d zero = _mm_setzero_pd();
|
||||||
__m128d posi = _mm_cmpgt_pd(num, zero);
|
__m128d posi = _mm_cmpgt_pd(num, zero);
|
||||||
_mm_storeu_pd(p, posi);
|
_mm_storeu_pd(_.p, posi);
|
||||||
|
|
||||||
|
int sv1 = _.pi[0] ? _.pi[0] : 1;
|
||||||
|
int sv2 = _.pi[2] ? _.pi[2] : 1;
|
||||||
if (nears)
|
if (nears)
|
||||||
{
|
{
|
||||||
__m128d sqnum = _mm_mul_pd(num, num);
|
__m128d sqnum = _mm_mul_pd(num, num);
|
||||||
|
@ -133,45 +132,20 @@ int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
__m128d dist = _mm_div_pd(sqnum, l);
|
__m128d dist = _mm_div_pd(sqnum, l);
|
||||||
__m128d epsilon = _mm_set1_pd(SIDE_EPSILON);
|
__m128d epsilon = _mm_set1_pd(SIDE_EPSILON);
|
||||||
__m128d close = _mm_cmplt_pd(dist, epsilon);
|
__m128d close = _mm_cmplt_pd(dist, epsilon);
|
||||||
_mm_storeu_pd(n, close);
|
_mm_storeu_pd(_.n, close);
|
||||||
if (nears & 2)
|
if ((nears & 2) && _.ni[0])
|
||||||
{
|
{
|
||||||
if (ni[0])
|
sv1 = 0;
|
||||||
{
|
|
||||||
sidev1 = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sidev1 = pi[0] ? -1 : 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
if ((nears & 1) && _.ni[2])
|
||||||
{
|
{
|
||||||
sidev1 = pi[0] ? -1 : 1;
|
sv2 = 0;
|
||||||
}
|
|
||||||
if (nears & 1)
|
|
||||||
{
|
|
||||||
if (ni[1])
|
|
||||||
{
|
|
||||||
sidev2 = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sidev2 = pi[1] ? -1 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sidev2 = pi[1] ? -1 : 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
sidev[0] = sv1;
|
||||||
{
|
sidev[1] = sv2;
|
||||||
sidev1 = pi[0] ? -1 : 1;
|
|
||||||
sidev2 = pi[1] ? -1 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((sidev1 | sidev2) == 0)
|
if ((sv1 | sv2) == 0)
|
||||||
{ // seg is coplanar with the splitter, so use its orientation to determine
|
{ // seg is coplanar with the splitter, so use its orientation to determine
|
||||||
// which child it ends up in. If it faces the same direction as the splitter,
|
// which child it ends up in. If it faces the same direction as the splitter,
|
||||||
// it goes in front. Otherwise, it goes in back.
|
// it goes in front. Otherwise, it goes in back.
|
||||||
|
@ -199,11 +173,11 @@ int FNodeBuilder::ClassifyLineSSE2 (node_t &node, const FPrivSeg *seg, int &side
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sidev1 <= 0 && sidev2 <= 0)
|
else if (sv1 <= 0 && sv2 <= 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (sidev1 >= 0 && sidev2 >= 0)
|
else if (sv1 >= 0 && sv2 >= 0)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -577,21 +577,19 @@ void FProcessor::Write (FWadWriter &out)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int ssetype;
|
|
||||||
|
|
||||||
if (HaveSSE2)
|
if (HaveSSE2)
|
||||||
{
|
{
|
||||||
ssetype = 2;
|
SSELevel = 2;
|
||||||
}
|
}
|
||||||
else if (HaveSSE1)
|
else if (HaveSSE1)
|
||||||
{
|
{
|
||||||
ssetype = 1;
|
SSELevel = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ssetype = 0;
|
SSELevel = 0;
|
||||||
}
|
}
|
||||||
builder = new FNodeBuilder (Level, PolyStarts, PolyAnchors, Wad.LumpName (Lump), BuildGLNodes, ssetype);
|
builder = new FNodeBuilder (Level, PolyStarts, PolyAnchors, Wad.LumpName (Lump), BuildGLNodes);
|
||||||
if (builder == NULL)
|
if (builder == NULL)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(" Not enough memory to build nodes!");
|
throw std::runtime_error(" Not enough memory to build nodes!");
|
||||||
|
@ -627,7 +625,7 @@ void FProcessor::Write (FWadWriter &out)
|
||||||
{
|
{
|
||||||
// Now repeat the process to obtain regular nodes
|
// Now repeat the process to obtain regular nodes
|
||||||
delete builder;
|
delete builder;
|
||||||
builder = new FNodeBuilder (Level, PolyStarts, PolyAnchors, Wad.LumpName (Lump), false, ssetype);
|
builder = new FNodeBuilder (Level, PolyStarts, PolyAnchors, Wad.LumpName (Lump), false);
|
||||||
if (builder == NULL)
|
if (builder == NULL)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(" Not enough memory to build regular nodes!");
|
throw std::runtime_error(" Not enough memory to build regular nodes!");
|
||||||
|
|
1
zdbsp.h
1
zdbsp.h
|
@ -46,6 +46,7 @@ extern bool CheckPolyobjs;
|
||||||
extern bool ShowMap;
|
extern bool ShowMap;
|
||||||
extern bool CompressNodes, CompressGLNodes, ForceCompression, V5GLNodes;
|
extern bool CompressNodes, CompressGLNodes, ForceCompression, V5GLNodes;
|
||||||
extern bool HaveSSE1, HaveSSE2;
|
extern bool HaveSSE1, HaveSSE2;
|
||||||
|
extern int SSELevel;
|
||||||
|
|
||||||
|
|
||||||
#define FIXED_MAX INT_MAX
|
#define FIXED_MAX INT_MAX
|
||||||
|
|
|
@ -10,5 +10,11 @@ add_library( z
|
||||||
crc32.c
|
crc32.c
|
||||||
deflate.c
|
deflate.c
|
||||||
trees.c
|
trees.c
|
||||||
zutil.c )
|
zutil.c
|
||||||
|
crc32.h
|
||||||
|
deflate.h
|
||||||
|
trees.h
|
||||||
|
zconf.h
|
||||||
|
zlib.h
|
||||||
|
zutil.h )
|
||||||
target_link_libraries( z )
|
target_link_libraries( z )
|
||||||
|
|
Loading…
Reference in a new issue