]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
tools/heretic2: move heretic2 stuff to its own directory
authorThomas Debesse <dev@illwieckz.net>
Fri, 5 Jul 2019 22:33:50 +0000 (00:33 +0200)
committerThomas Debesse <dev@illwieckz.net>
Sat, 13 Jul 2019 17:57:15 +0000 (19:57 +0200)
134 files changed:
Makefile
tools/CMakeLists.txt
tools/heretic2/CMakeLists.txt [new file with mode: 0644]
tools/heretic2/common/bspfile.c [new file with mode: 0644]
tools/heretic2/common/bspfile.h [new file with mode: 0644]
tools/heretic2/common/cmdlib.c [new file with mode: 0644]
tools/heretic2/common/cmdlib.h [new file with mode: 0644]
tools/heretic2/common/her2_threads.h [new file with mode: 0644]
tools/heretic2/common/inout.c [new file with mode: 0644]
tools/heretic2/common/inout.h [new file with mode: 0644]
tools/heretic2/common/l3dslib.c [new file with mode: 0644]
tools/heretic2/common/l3dslib.h [new file with mode: 0644]
tools/heretic2/common/lbmlib.c [new file with mode: 0644]
tools/heretic2/common/lbmlib.h [new file with mode: 0644]
tools/heretic2/common/mathlib.c [new file with mode: 0644]
tools/heretic2/common/mathlib.h [new file with mode: 0644]
tools/heretic2/common/md4.c [new file with mode: 0644]
tools/heretic2/common/md4.h [new file with mode: 0644]
tools/heretic2/common/path_init.c [new file with mode: 0644]
tools/heretic2/common/polylib.c [new file with mode: 0644]
tools/heretic2/common/polylib.h [new file with mode: 0644]
tools/heretic2/common/qfiles.c [new file with mode: 0644]
tools/heretic2/common/qfiles.h [new file with mode: 0644]
tools/heretic2/common/scriplib.c [new file with mode: 0644]
tools/heretic2/common/scriplib.h [new file with mode: 0644]
tools/heretic2/common/threads.c [new file with mode: 0644]
tools/heretic2/common/token.c [new file with mode: 0644]
tools/heretic2/common/token.h [new file with mode: 0644]
tools/heretic2/common/trilib.c [new file with mode: 0644]
tools/heretic2/common/trilib.h [new file with mode: 0644]
tools/heretic2/h2data/adpcm.h [new file with mode: 0644]
tools/heretic2/h2data/animcomp.c [new file with mode: 0644]
tools/heretic2/h2data/animcomp.h [new file with mode: 0644]
tools/heretic2/h2data/anorms.h [new file with mode: 0644]
tools/heretic2/h2data/book.c [new file with mode: 0644]
tools/heretic2/h2data/fmodels.c [new file with mode: 0644]
tools/heretic2/h2data/h2data.rc [new file with mode: 0644]
tools/heretic2/h2data/images.c [new file with mode: 0644]
tools/heretic2/h2data/jointed.c [new file with mode: 0644]
tools/heretic2/h2data/jointed.h [new file with mode: 0644]
tools/heretic2/h2data/joints.h [new file with mode: 0644]
tools/heretic2/h2data/models.c [new file with mode: 0644]
tools/heretic2/h2data/pics.c [new file with mode: 0644]
tools/heretic2/h2data/qd_fmodel.h [new file with mode: 0644]
tools/heretic2/h2data/qd_skeletons.c [new file with mode: 0644]
tools/heretic2/h2data/qd_skeletons.h [new file with mode: 0644]
tools/heretic2/h2data/qdata.c [new file with mode: 0644]
tools/heretic2/h2data/qdata.h [new file with mode: 0644]
tools/heretic2/h2data/resource.h [new file with mode: 0644]
tools/heretic2/h2data/sprites.c [new file with mode: 0644]
tools/heretic2/h2data/svdcmp.c [new file with mode: 0644]
tools/heretic2/h2data/tables.c [new file with mode: 0644]
tools/heretic2/h2data/tmix.c [new file with mode: 0644]
tools/heretic2/h2data/video.c [new file with mode: 0644]
tools/heretic2/qcommon/angles.h [new file with mode: 0644]
tools/heretic2/qcommon/arrayedlist.h [new file with mode: 0644]
tools/heretic2/qcommon/flex.h [new file with mode: 0644]
tools/heretic2/qcommon/fmodel.h [new file with mode: 0644]
tools/heretic2/qcommon/h2common.h [new file with mode: 0644]
tools/heretic2/qcommon/placement.h [new file with mode: 0644]
tools/heretic2/qcommon/q_typedef.h [new file with mode: 0644]
tools/heretic2/qcommon/qfiles.h [new file with mode: 0644]
tools/heretic2/qcommon/reference.c [new file with mode: 0644]
tools/heretic2/qcommon/reference.h [new file with mode: 0644]
tools/heretic2/qcommon/resourcemanager.c [new file with mode: 0644]
tools/heretic2/qcommon/resourcemanager.h [new file with mode: 0644]
tools/heretic2/qcommon/skeletons.c [new file with mode: 0644]
tools/heretic2/qcommon/skeletons.h [new file with mode: 0644]
tools/quake2/qdata_heretic2/CMakeLists.txt [deleted file]
tools/quake2/qdata_heretic2/adpcm.h [deleted file]
tools/quake2/qdata_heretic2/animcomp.c [deleted file]
tools/quake2/qdata_heretic2/animcomp.h [deleted file]
tools/quake2/qdata_heretic2/anorms.h [deleted file]
tools/quake2/qdata_heretic2/book.c [deleted file]
tools/quake2/qdata_heretic2/common/bspfile.c [deleted file]
tools/quake2/qdata_heretic2/common/bspfile.h [deleted file]
tools/quake2/qdata_heretic2/common/cmdlib.c [deleted file]
tools/quake2/qdata_heretic2/common/cmdlib.h [deleted file]
tools/quake2/qdata_heretic2/common/her2_threads.h [deleted file]
tools/quake2/qdata_heretic2/common/inout.c [deleted file]
tools/quake2/qdata_heretic2/common/inout.h [deleted file]
tools/quake2/qdata_heretic2/common/l3dslib.c [deleted file]
tools/quake2/qdata_heretic2/common/l3dslib.h [deleted file]
tools/quake2/qdata_heretic2/common/lbmlib.c [deleted file]
tools/quake2/qdata_heretic2/common/lbmlib.h [deleted file]
tools/quake2/qdata_heretic2/common/mathlib.c [deleted file]
tools/quake2/qdata_heretic2/common/mathlib.h [deleted file]
tools/quake2/qdata_heretic2/common/md4.c [deleted file]
tools/quake2/qdata_heretic2/common/md4.h [deleted file]
tools/quake2/qdata_heretic2/common/path_init.c [deleted file]
tools/quake2/qdata_heretic2/common/polylib.c [deleted file]
tools/quake2/qdata_heretic2/common/polylib.h [deleted file]
tools/quake2/qdata_heretic2/common/qfiles.c [deleted file]
tools/quake2/qdata_heretic2/common/qfiles.h [deleted file]
tools/quake2/qdata_heretic2/common/scriplib.c [deleted file]
tools/quake2/qdata_heretic2/common/scriplib.h [deleted file]
tools/quake2/qdata_heretic2/common/threads.c [deleted file]
tools/quake2/qdata_heretic2/common/token.c [deleted file]
tools/quake2/qdata_heretic2/common/token.h [deleted file]
tools/quake2/qdata_heretic2/common/trilib.c [deleted file]
tools/quake2/qdata_heretic2/common/trilib.h [deleted file]
tools/quake2/qdata_heretic2/fmodels.c [deleted file]
tools/quake2/qdata_heretic2/h2data.rc [deleted file]
tools/quake2/qdata_heretic2/images.c [deleted file]
tools/quake2/qdata_heretic2/jointed.c [deleted file]
tools/quake2/qdata_heretic2/jointed.h [deleted file]
tools/quake2/qdata_heretic2/joints.h [deleted file]
tools/quake2/qdata_heretic2/models.c [deleted file]
tools/quake2/qdata_heretic2/pics.c [deleted file]
tools/quake2/qdata_heretic2/qcommon/angles.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/arrayedlist.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/flex.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/fmodel.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/h2common.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/placement.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/q_typedef.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/qfiles.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/reference.c [deleted file]
tools/quake2/qdata_heretic2/qcommon/reference.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/resourcemanager.c [deleted file]
tools/quake2/qdata_heretic2/qcommon/resourcemanager.h [deleted file]
tools/quake2/qdata_heretic2/qcommon/skeletons.c [deleted file]
tools/quake2/qdata_heretic2/qcommon/skeletons.h [deleted file]
tools/quake2/qdata_heretic2/qd_fmodel.h [deleted file]
tools/quake2/qdata_heretic2/qd_skeletons.c [deleted file]
tools/quake2/qdata_heretic2/qd_skeletons.h [deleted file]
tools/quake2/qdata_heretic2/qdata.c [deleted file]
tools/quake2/qdata_heretic2/qdata.h [deleted file]
tools/quake2/qdata_heretic2/resource.h [deleted file]
tools/quake2/qdata_heretic2/sprites.c [deleted file]
tools/quake2/qdata_heretic2/svdcmp.c [deleted file]
tools/quake2/qdata_heretic2/tables.c [deleted file]
tools/quake2/qdata_heretic2/tmix.c [deleted file]
tools/quake2/qdata_heretic2/video.c [deleted file]

index 85049a8b2525fdba32b2d0b1f023b91aa6aa5eb0..cdfbff0f87c6e7320c9c8938cabcce783a3398f1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1019,38 +1019,38 @@ $(INSTALLDIR)/plugins/bkgrnd2d.$(DLL): \
        contrib/bkgrnd2d/plugin.o \
 
 $(INSTALLDIR)/heretic2/h2data.$(EXE): LIBS_EXTRA := $(LIBS_XML)
-$(INSTALLDIR)/heretic2/h2data.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_XML) -Itools/quake2/qdata_heretic2/common -Itools/quake2/qdata_heretic2/qcommon -Itools/quake2/qdata_heretic2 -Itools/quake2/common -Ilibs -Iinclude
+$(INSTALLDIR)/heretic2/h2data.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_XML) -Itools/heretic2/common -Itools/heretic2/qcommon -Itools/heretic2/h2data -Itools/quake2/common -Ilibs -Iinclude
 $(INSTALLDIR)/heretic2/h2data.$(EXE): \
-       tools/quake2/qdata_heretic2/common/bspfile.o \
-       tools/quake2/qdata_heretic2/common/cmdlib.o \
-       tools/quake2/qdata_heretic2/common/inout.o \
-       tools/quake2/qdata_heretic2/common/l3dslib.o \
-       tools/quake2/qdata_heretic2/common/lbmlib.o \
-       tools/quake2/qdata_heretic2/common/mathlib.o \
-       tools/quake2/qdata_heretic2/common/md4.o \
-       tools/quake2/qdata_heretic2/common/path_init.o \
-       tools/quake2/qdata_heretic2/common/qfiles.o \
-       tools/quake2/qdata_heretic2/common/scriplib.o \
-       tools/quake2/qdata_heretic2/common/threads.o \
-       tools/quake2/qdata_heretic2/common/token.o \
-       tools/quake2/qdata_heretic2/common/trilib.o \
-       tools/quake2/qdata_heretic2/qcommon/reference.o \
-       tools/quake2/qdata_heretic2/qcommon/resourcemanager.o \
-       tools/quake2/qdata_heretic2/qcommon/skeletons.o \
-       tools/quake2/qdata_heretic2/animcomp.o \
-       tools/quake2/qdata_heretic2/book.o \
-       tools/quake2/qdata_heretic2/fmodels.o \
-       tools/quake2/qdata_heretic2/images.o \
-       tools/quake2/qdata_heretic2/jointed.o \
-       tools/quake2/qdata_heretic2/models.o \
-       tools/quake2/qdata_heretic2/pics.o \
-       tools/quake2/qdata_heretic2/qdata.o \
-       tools/quake2/qdata_heretic2/qd_skeletons.o \
-       tools/quake2/qdata_heretic2/sprites.o \
-       tools/quake2/qdata_heretic2/svdcmp.o \
-       tools/quake2/qdata_heretic2/tables.o \
-       tools/quake2/qdata_heretic2/tmix.o \
-       tools/quake2/qdata_heretic2/video.o \
+       tools/heretic2/common/bspfile.o \
+       tools/heretic2/common/cmdlib.o \
+       tools/heretic2/common/inout.o \
+       tools/heretic2/common/l3dslib.o \
+       tools/heretic2/common/lbmlib.o \
+       tools/heretic2/common/mathlib.o \
+       tools/heretic2/common/md4.o \
+       tools/heretic2/common/path_init.o \
+       tools/heretic2/common/qfiles.o \
+       tools/heretic2/common/scriplib.o \
+       tools/heretic2/common/threads.o \
+       tools/heretic2/common/token.o \
+       tools/heretic2/common/trilib.o \
+       tools/heretic2/qcommon/reference.o \
+       tools/heretic2/qcommon/resourcemanager.o \
+       tools/heretic2/qcommon/skeletons.o \
+       tools/heretic2/h2data/animcomp.o \
+       tools/heretic2/h2data/book.o \
+       tools/heretic2/h2data/fmodels.o \
+       tools/heretic2/h2data/images.o \
+       tools/heretic2/h2data/jointed.o \
+       tools/heretic2/h2data/models.o \
+       tools/heretic2/h2data/pics.o \
+       tools/heretic2/h2data/qdata.o \
+       tools/heretic2/h2data/qd_skeletons.o \
+       tools/heretic2/h2data/sprites.o \
+       tools/heretic2/h2data/svdcmp.o \
+       tools/heretic2/h2data/tables.o \
+       tools/heretic2/h2data/tmix.o \
+       tools/heretic2/h2data/video.o \
        libl_net.$(A) \
        $(if $(findstring $(OS),Win32),icons/h2data.o,) \
 
index b36bb6cf399f9a8761477c021c30d9e6da792d9f..b8f8565418b48968ecb7b4ecd67c1286be83fe1e 100644 (file)
@@ -1,7 +1,7 @@
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
 
 add_subdirectory(quake2)
-add_subdirectory(quake2/qdata_heretic2)
+add_subdirectory(heretic2)
 add_subdirectory(quake3)
 
 add_custom_target(tools)
diff --git a/tools/heretic2/CMakeLists.txt b/tools/heretic2/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0cb9cb4
--- /dev/null
@@ -0,0 +1,73 @@
+include_directories(BEFORE h2data common qcommon)
+
+find_package(OpenGL REQUIRED)
+
+find_package(LibXml2 REQUIRED)
+include_directories(${LIBXML2_INCLUDE_DIR})
+
+radiant_tool(h2data
+    h2data/h2data.rc
+
+    common/bspfile.c common/bspfile.h
+    common/cmdlib.c common/cmdlib.h
+    common/inout.c common/inout.h
+    common/l3dslib.c common/l3dslib.h
+    common/lbmlib.c common/lbmlib.h
+    common/mathlib.c common/mathlib.h
+    common/md4.c common/md4.h
+    common/path_init.c
+    common/polylib.c common/polylib.h
+    common/qfiles.c common/qfiles.h
+    common/scriplib.c common/scriplib.h
+    common/threads.c common/her2_threads.h
+    common/token.c common/token.h
+    common/trilib.c common/trilib.h
+
+    qcommon/angles.h
+    qcommon/arrayedlist.h
+    qcommon/flex.h
+    qcommon/fmodel.h
+    qcommon/h2common.h
+    qcommon/placement.h
+    qcommon/qfiles.h
+    qcommon/q_typedef.h
+    qcommon/reference.c qcommon/reference.h
+    qcommon/resourcemanager.c qcommon/resourcemanager.h
+    qcommon/skeletons.c qcommon/skeletons.h
+
+    h2data/adpcm.h
+    h2data/animcomp.c h2data/animcomp.h 
+    h2data/anorms.h
+    h2data/book.c
+    h2data/fmodels.c h2data/qd_fmodel.h
+    h2data/images.c
+    h2data/jointed.c
+    h2data/jointed.h
+    h2data/joints.h
+    h2data/models.c
+    h2data/pics.c
+    h2data/qdata.c h2data/qdata.h
+    h2data/qd_skeletons.c h2data/qd_skeletons.h
+    h2data/resource.h
+    h2data/sprites.c
+    h2data/svdcmp.c
+    h2data/tables.c
+    h2data/tmix.c
+    h2data/video.c
+)
+
+target_compile_definitions(h2data
+    PRIVATE
+)
+
+target_link_libraries(h2data
+    ${LIBXML2_LIBRARIES}
+    l_net
+)
+
+add_custom_target(heretic2)
+add_dependencies(heretic2 h2data)
+
+if (UNIX)
+    target_link_libraries(h2data pthread m)
+endif ()
diff --git a/tools/heretic2/common/bspfile.c b/tools/heretic2/common/bspfile.c
new file mode 100644 (file)
index 0000000..add0ef3
--- /dev/null
@@ -0,0 +1,793 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include "cmdlib.h"
+#include "inout.h"
+#include "mathlib.h"
+#include "bspfile.h"
+#include "scriplib.h"
+
+void GetLeafNums( void );
+
+//=============================================================================
+
+int nummodels;
+dmodel_t dmodels[MAX_MAP_MODELS];
+
+int visdatasize;
+byte dvisdata[MAX_MAP_VISIBILITY];
+dvis_t      *dvis = (dvis_t *)dvisdata;
+
+int lightdatasize;
+byte dlightdata[MAX_MAP_LIGHTING];
+
+int entdatasize;
+char dentdata[MAX_MAP_ENTSTRING];
+
+int numleafs;
+dleaf_t dleafs[MAX_MAP_LEAFS];
+
+int numplanes;
+dplane_t dplanes[MAX_MAP_PLANES];
+
+int numvertexes;
+dvertex_t dvertexes[MAX_MAP_VERTS];
+
+int numnodes;
+dnode_t dnodes[MAX_MAP_NODES];
+
+int numtexinfo;
+texinfo_t texinfo[MAX_MAP_TEXINFO];
+
+int numfaces;
+dface_t dfaces[MAX_MAP_FACES];
+
+int numedges;
+dedge_t dedges[MAX_MAP_EDGES];
+
+int numleaffaces;
+unsigned short dleaffaces[MAX_MAP_LEAFFACES];
+
+int numleafbrushes;
+unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
+
+int numsurfedges;
+int dsurfedges[MAX_MAP_SURFEDGES];
+
+int numbrushes;
+dbrush_t dbrushes[MAX_MAP_BRUSHES];
+
+int numbrushsides;
+dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
+
+int numareas;
+darea_t dareas[MAX_MAP_AREAS];
+
+int numareaportals;
+dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
+
+byte dpop[256];
+
+/*
+   ===============
+   CompressVis
+
+   ===============
+ */
+int CompressVis( byte *vis, byte *dest ){
+       int j;
+       int rep;
+       int visrow;
+       byte    *dest_p;
+
+       dest_p = dest;
+//     visrow = (r_numvisleafs + 7)>>3;
+       visrow = ( dvis->numclusters + 7 ) >> 3;
+
+       for ( j = 0 ; j < visrow ; j++ )
+       {
+               *dest_p++ = vis[j];
+               if ( vis[j] ) {
+                       continue;
+               }
+
+               rep = 1;
+               for ( j++; j < visrow ; j++ )
+                       if ( vis[j] || rep == 255 ) {
+                               break;
+                       }
+                       else{
+                               rep++;
+                       }
+               *dest_p++ = rep;
+               j--;
+       }
+
+       return dest_p - dest;
+}
+
+
+/*
+   ===================
+   DecompressVis
+   ===================
+ */
+void DecompressVis( byte *in, byte *decompressed ){
+       int c;
+       byte    *out;
+       int row;
+
+//     row = (r_numvisleafs+7)>>3;
+       row = ( dvis->numclusters + 7 ) >> 3;
+       out = decompressed;
+
+       do
+       {
+               if ( *in ) {
+                       *out++ = *in++;
+                       continue;
+               }
+
+               c = in[1];
+               if ( !c ) {
+                       Error( "DecompressVis: 0 repeat" );
+               }
+               in += 2;
+               while ( c )
+               {
+                       *out++ = 0;
+                       c--;
+               }
+       } while ( out - decompressed < row );
+}
+
+//=============================================================================
+
+/*
+   =============
+   SwapBSPFile
+
+   Byte swaps all data in a bsp file.
+   =============
+ */
+void SwapBSPFile( qboolean todisk ){
+       int i, j;
+       dmodel_t        *d;
+
+
+// models
+       for ( i = 0 ; i < nummodels ; i++ )
+       {
+               d = &dmodels[i];
+
+               d->firstface = LittleLong( d->firstface );
+               d->numfaces = LittleLong( d->numfaces );
+               d->headnode = LittleLong( d->headnode );
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       d->mins[j] = LittleFloat( d->mins[j] );
+                       d->maxs[j] = LittleFloat( d->maxs[j] );
+                       d->origin[j] = LittleFloat( d->origin[j] );
+               }
+       }
+
+//
+// vertexes
+//
+       for ( i = 0 ; i < numvertexes ; i++ )
+       {
+               for ( j = 0 ; j < 3 ; j++ )
+                       dvertexes[i].point[j] = LittleFloat( dvertexes[i].point[j] );
+       }
+
+//
+// planes
+//
+       for ( i = 0 ; i < numplanes ; i++ )
+       {
+               for ( j = 0 ; j < 3 ; j++ )
+                       dplanes[i].normal[j] = LittleFloat( dplanes[i].normal[j] );
+               dplanes[i].dist = LittleFloat( dplanes[i].dist );
+               dplanes[i].type = LittleLong( dplanes[i].type );
+       }
+
+//
+// texinfos
+//
+       for ( i = 0 ; i < numtexinfo ; i++ )
+       {
+               for ( j = 0 ; j < 8 ; j++ )
+                       texinfo[i].vecs[0][j] = LittleFloat( texinfo[i].vecs[0][j] );
+               texinfo[i].flags = LittleLong( texinfo[i].flags );
+               texinfo[i].value = LittleLong( texinfo[i].value );
+               texinfo[i].nexttexinfo = LittleLong( texinfo[i].nexttexinfo );
+       }
+
+//
+// faces
+//
+       for ( i = 0 ; i < numfaces ; i++ )
+       {
+               dfaces[i].texinfo = LittleShort( dfaces[i].texinfo );
+               dfaces[i].planenum = LittleShort( dfaces[i].planenum );
+               dfaces[i].side = LittleShort( dfaces[i].side );
+               dfaces[i].lighting.c = LittleLong( dfaces[i].lighting.c );
+               dfaces[i].lightofs = LittleLong( dfaces[i].lightofs );
+               dfaces[i].firstedge = LittleLong( dfaces[i].firstedge );
+               dfaces[i].numedges = LittleShort( dfaces[i].numedges );
+       }
+
+//
+// nodes
+//
+       for ( i = 0 ; i < numnodes ; i++ )
+       {
+               dnodes[i].planenum = LittleLong( dnodes[i].planenum );
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       dnodes[i].mins[j] = LittleShort( dnodes[i].mins[j] );
+                       dnodes[i].maxs[j] = LittleShort( dnodes[i].maxs[j] );
+               }
+               dnodes[i].children[0] = LittleLong( dnodes[i].children[0] );
+               dnodes[i].children[1] = LittleLong( dnodes[i].children[1] );
+               dnodes[i].firstface = LittleShort( dnodes[i].firstface );
+               dnodes[i].numfaces = LittleShort( dnodes[i].numfaces );
+       }
+
+//
+// leafs
+//
+       for ( i = 0 ; i < numleafs ; i++ )
+       {
+               dleafs[i].contents = LittleLong( dleafs[i].contents );
+               dleafs[i].cluster = LittleShort( dleafs[i].cluster );
+               dleafs[i].area = LittleShort( dleafs[i].area );
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       dleafs[i].mins[j] = LittleShort( dleafs[i].mins[j] );
+                       dleafs[i].maxs[j] = LittleShort( dleafs[i].maxs[j] );
+               }
+
+               dleafs[i].firstleafface = LittleShort( dleafs[i].firstleafface );
+               dleafs[i].numleaffaces = LittleShort( dleafs[i].numleaffaces );
+               dleafs[i].firstleafbrush = LittleShort( dleafs[i].firstleafbrush );
+               dleafs[i].numleafbrushes = LittleShort( dleafs[i].numleafbrushes );
+       }
+
+//
+// leaffaces
+//
+       for ( i = 0 ; i < numleaffaces ; i++ )
+               dleaffaces[i] = LittleShort( dleaffaces[i] );
+
+//
+// leafbrushes
+//
+       for ( i = 0 ; i < numleafbrushes ; i++ )
+               dleafbrushes[i] = LittleShort( dleafbrushes[i] );
+
+//
+// surfedges
+//
+       for ( i = 0 ; i < numsurfedges ; i++ )
+               dsurfedges[i] = LittleLong( dsurfedges[i] );
+
+//
+// edges
+//
+       for ( i = 0 ; i < numedges ; i++ )
+       {
+               dedges[i].v[0] = LittleShort( dedges[i].v[0] );
+               dedges[i].v[1] = LittleShort( dedges[i].v[1] );
+       }
+
+//
+// brushes
+//
+       for ( i = 0 ; i < numbrushes ; i++ )
+       {
+               dbrushes[i].firstside = LittleLong( dbrushes[i].firstside );
+               dbrushes[i].numsides = LittleLong( dbrushes[i].numsides );
+               dbrushes[i].contents = LittleLong( dbrushes[i].contents );
+       }
+
+//
+// areas
+//
+       for ( i = 0 ; i < numareas ; i++ )
+       {
+               dareas[i].numareaportals = LittleLong( dareas[i].numareaportals );
+               dareas[i].firstareaportal = LittleLong( dareas[i].firstareaportal );
+       }
+
+//
+// areasportals
+//
+       for ( i = 0 ; i < numareaportals ; i++ )
+       {
+               dareaportals[i].portalnum = LittleLong( dareaportals[i].portalnum );
+               dareaportals[i].otherarea = LittleLong( dareaportals[i].otherarea );
+       }
+
+//
+// brushsides
+//
+       for ( i = 0 ; i < numbrushsides ; i++ )
+       {
+               dbrushsides[i].planenum = LittleShort( dbrushsides[i].planenum );
+               dbrushsides[i].texinfo = LittleShort( dbrushsides[i].texinfo );
+       }
+
+//
+// visibility
+//
+       if ( todisk ) {
+               j = dvis->numclusters;
+       }
+       else{
+               j = LittleLong( dvis->numclusters );
+       }
+       dvis->numclusters = LittleLong( dvis->numclusters );
+       for ( i = 0 ; i < j ; i++ )
+       {
+               dvis->bitofs[i][0] = LittleLong( dvis->bitofs[i][0] );
+               dvis->bitofs[i][1] = LittleLong( dvis->bitofs[i][1] );
+       }
+}
+
+
+dheader_t   *header;
+
+int CopyLump( int lump, void *dest, int size ){
+       int length, ofs;
+
+       length = header->lumps[lump].filelen;
+       ofs = header->lumps[lump].fileofs;
+
+       if ( length % size ) {
+               Error( "LoadBSPFile: odd lump size" );
+       }
+
+       memcpy( dest, (byte *)header + ofs, length );
+
+       return length / size;
+}
+
+/*
+   =============
+   LoadBSPFile
+   =============
+ */
+void    LoadBSPFile( char *filename ){
+       int i;
+
+//
+// load the file header
+//
+       LoadFile( filename, (void **)&header );
+
+// swap the header
+       for ( i = 0 ; i < sizeof( dheader_t ) / 4 ; i++ )
+               ( (int *)header )[i] = LittleLong( ( (int *)header )[i] );
+
+       if ( header->ident != IDBSPHEADER ) {
+               Error( "%s is not a IBSP file", filename );
+       }
+       if ( header->version != BSPVERSION ) {
+               Error( "%s is version %i, not %i", filename, header->version, BSPVERSION );
+       }
+
+       nummodels = CopyLump( LUMP_MODELS, dmodels, sizeof( dmodel_t ) );
+       numvertexes = CopyLump( LUMP_VERTEXES, dvertexes, sizeof( dvertex_t ) );
+       numplanes = CopyLump( LUMP_PLANES, dplanes, sizeof( dplane_t ) );
+       numleafs = CopyLump( LUMP_LEAFS, dleafs, sizeof( dleaf_t ) );
+       numnodes = CopyLump( LUMP_NODES, dnodes, sizeof( dnode_t ) );
+       numtexinfo = CopyLump( LUMP_TEXINFO, texinfo, sizeof( texinfo_t ) );
+       numfaces = CopyLump( LUMP_FACES, dfaces, sizeof( dface_t ) );
+       numleaffaces = CopyLump( LUMP_LEAFFACES, dleaffaces, sizeof( dleaffaces[0] ) );
+       numleafbrushes = CopyLump( LUMP_LEAFBRUSHES, dleafbrushes, sizeof( dleafbrushes[0] ) );
+       numsurfedges = CopyLump( LUMP_SURFEDGES, dsurfedges, sizeof( dsurfedges[0] ) );
+       numedges = CopyLump( LUMP_EDGES, dedges, sizeof( dedge_t ) );
+       numbrushes = CopyLump( LUMP_BRUSHES, dbrushes, sizeof( dbrush_t ) );
+       numbrushsides = CopyLump( LUMP_BRUSHSIDES, dbrushsides, sizeof( dbrushside_t ) );
+       numareas = CopyLump( LUMP_AREAS, dareas, sizeof( darea_t ) );
+       numareaportals = CopyLump( LUMP_AREAPORTALS, dareaportals, sizeof( dareaportal_t ) );
+
+       visdatasize = CopyLump( LUMP_VISIBILITY, dvisdata, 1 );
+       lightdatasize = CopyLump( LUMP_LIGHTING, dlightdata, 1 );
+       entdatasize = CopyLump( LUMP_ENTITIES, dentdata, 1 );
+
+       CopyLump( LUMP_POP, dpop, 1 );
+
+       free( header );      // everything has been copied out
+
+//
+// swap everything
+//
+       SwapBSPFile( false );
+}
+
+
+/*
+   =============
+   LoadBSPFileTexinfo
+
+   Only loads the texinfo lump, so qdata can scan for textures
+   =============
+ */
+void    LoadBSPFileTexinfo( char *filename ){
+       int i;
+       FILE        *f;
+       int length, ofs;
+
+       header = malloc( sizeof( dheader_t ) );
+
+       f = fopen( filename, "rb" );
+       fread( header, sizeof( dheader_t ), 1, f );
+
+// swap the header
+       for ( i = 0 ; i < sizeof( dheader_t ) / 4 ; i++ )
+               ( (int *)header )[i] = LittleLong( ( (int *)header )[i] );
+
+       if ( header->ident != IDBSPHEADER ) {
+               Error( "%s is not a IBSP file", filename );
+       }
+       if ( header->version != BSPVERSION ) {
+               Error( "%s is version %i, not %i", filename, header->version, BSPVERSION );
+       }
+
+
+       length = header->lumps[LUMP_TEXINFO].filelen;
+       ofs = header->lumps[LUMP_TEXINFO].fileofs;
+
+       fseek( f, ofs, SEEK_SET );
+       fread( texinfo, length, 1, f );
+       fclose( f );
+
+       numtexinfo = length / sizeof( texinfo_t );
+
+       free( header );      // everything has been copied out
+
+       SwapBSPFile( false );
+}
+
+
+//============================================================================
+
+FILE        *wadfile;
+dheader_t outheader;
+
+void AddLump( int lumpnum, void *data, int len ){
+       lump_t *lump;
+
+       lump = &header->lumps[lumpnum];
+
+       lump->fileofs = LittleLong( ftell( wadfile ) );
+       lump->filelen = LittleLong( len );
+       SafeWrite( wadfile, data, ( len + 3 ) & ~3 );
+}
+
+/*
+   =============
+   WriteBSPFile
+
+   Swaps the bsp file in place, so it should not be referenced again
+   =============
+ */
+void    WriteBSPFile( char *filename ){
+       header = &outheader;
+       memset( header, 0, sizeof( dheader_t ) );
+
+       SwapBSPFile( true );
+
+       header->ident = LittleLong( IDBSPHEADER );
+       header->version = LittleLong( BSPVERSION );
+
+       wadfile = SafeOpenWrite( filename );
+       SafeWrite( wadfile, header, sizeof( dheader_t ) ); // overwritten later
+
+       AddLump( LUMP_PLANES, dplanes, numplanes * sizeof( dplane_t ) );
+       AddLump( LUMP_LEAFS, dleafs, numleafs * sizeof( dleaf_t ) );
+       AddLump( LUMP_VERTEXES, dvertexes, numvertexes * sizeof( dvertex_t ) );
+       AddLump( LUMP_NODES, dnodes, numnodes * sizeof( dnode_t ) );
+       AddLump( LUMP_TEXINFO, texinfo, numtexinfo * sizeof( texinfo_t ) );
+       AddLump( LUMP_FACES, dfaces, numfaces * sizeof( dface_t ) );
+       AddLump( LUMP_BRUSHES, dbrushes, numbrushes * sizeof( dbrush_t ) );
+       AddLump( LUMP_BRUSHSIDES, dbrushsides, numbrushsides * sizeof( dbrushside_t ) );
+       AddLump( LUMP_LEAFFACES, dleaffaces, numleaffaces * sizeof( dleaffaces[0] ) );
+       AddLump( LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) );
+       AddLump( LUMP_SURFEDGES, dsurfedges, numsurfedges * sizeof( dsurfedges[0] ) );
+       AddLump( LUMP_EDGES, dedges, numedges * sizeof( dedge_t ) );
+       AddLump( LUMP_MODELS, dmodels, nummodels * sizeof( dmodel_t ) );
+       AddLump( LUMP_AREAS, dareas, numareas * sizeof( darea_t ) );
+       AddLump( LUMP_AREAPORTALS, dareaportals, numareaportals * sizeof( dareaportal_t ) );
+
+       AddLump( LUMP_LIGHTING, dlightdata, lightdatasize );
+       AddLump( LUMP_VISIBILITY, dvisdata, visdatasize );
+       AddLump( LUMP_ENTITIES, dentdata, entdatasize );
+       AddLump( LUMP_POP, dpop, sizeof( dpop ) );
+
+       fseek( wadfile, 0, SEEK_SET );
+       SafeWrite( wadfile, header, sizeof( dheader_t ) );
+       fclose( wadfile );
+}
+
+//============================================================================
+
+/*
+   =============
+   PrintBSPFileSizes
+
+   Dumps info about current file
+   =============
+ */
+void PrintBSPFileSizes( void ){
+       if ( !num_entities ) {
+               ParseEntities();
+       }
+
+       printf( "%5i models       %7i\n"
+                       ,nummodels, (int)( nummodels * sizeof( dmodel_t ) ) );
+       printf( "%5i brushes      %7i\n"
+                       ,numbrushes, (int)( numbrushes * sizeof( dbrush_t ) ) );
+       printf( "%5i brushsides   %7i\n"
+                       ,numbrushsides, (int)( numbrushsides * sizeof( dbrushside_t ) ) );
+       printf( "%5i planes       %7i\n"
+                       ,numplanes, (int)( numplanes * sizeof( dplane_t ) ) );
+       printf( "%5i texinfo      %7i\n"
+                       ,numtexinfo, (int)( numtexinfo * sizeof( texinfo_t ) ) );
+       printf( "%5i entdata      %7i\n", num_entities, entdatasize );
+
+       printf( "\n" );
+
+       printf( "%5i vertexes     %7i\n"
+                       ,numvertexes, (int)( numvertexes * sizeof( dvertex_t ) ) );
+       printf( "%5i nodes        %7i\n"
+                       ,numnodes, (int)( numnodes * sizeof( dnode_t ) ) );
+       printf( "%5i faces        %7i\n"
+                       ,numfaces, (int)( numfaces * sizeof( dface_t ) ) );
+       printf( "%5i leafs        %7i\n"
+                       ,numleafs, (int)( numleafs * sizeof( dleaf_t ) ) );
+       printf( "%5i leaffaces    %7i\n"
+                       ,numleaffaces, (int)( numleaffaces * sizeof( dleaffaces[0] ) ) );
+       printf( "%5i leafbrushes  %7i\n"
+                       ,numleafbrushes, (int)( numleafbrushes * sizeof( dleafbrushes[0] ) ) );
+       printf( "%5i surfedges    %7i\n"
+                       ,numsurfedges, (int)( numsurfedges * sizeof( dsurfedges[0] ) ) );
+       printf( "%5i edges        %7i\n"
+                       ,numedges, (int)( numedges * sizeof( dedge_t ) ) );
+       printf( "      lightdata    %7i\n", lightdatasize );
+       printf( "      visdata      %7i\n", visdatasize );
+}
+
+
+//============================================
+
+int num_entities;
+entity_t entities[MAX_MAP_ENTITIES];
+
+void StripTrailing( char *e ){
+       char    *s;
+
+       s = e + strlen( e ) - 1;
+       while ( s >= e && *s <= 32 )
+       {
+               *s = 0;
+               s--;
+       }
+}
+
+/*
+   =================
+   ParseEpair
+   =================
+ */
+epair_t *ParseEpair( void ){
+       epair_t *e;
+
+       e = malloc( sizeof( epair_t ) );
+       memset( e, 0, sizeof( epair_t ) );
+
+       if ( strlen( token ) >= MAX_KEY - 1 ) {
+               Error( "ParseEpar: token too long" );
+       }
+       e->key = copystring( token );
+       GetScriptToken( false );
+       if ( strlen( token ) >= MAX_VALUE - 1 ) {
+               Error( "ParseEpar: token too long" );
+       }
+       e->value = copystring( token );
+
+       // strip trailing spaces
+       StripTrailing( e->key );
+       StripTrailing( e->value );
+
+       return e;
+}
+
+
+/*
+   ================
+   ParseEntity
+   ================
+ */
+qboolean    ParseEntity( void ){
+       epair_t     *e;
+       entity_t    *mapent;
+
+       if ( !GetScriptToken( true ) ) {
+               return false;
+       }
+
+       if ( strcmp( token, "{" ) ) {
+               Error( "ParseEntity: { not found" );
+       }
+
+       if ( num_entities == MAX_MAP_ENTITIES ) {
+               Error( "num_entities == MAX_MAP_ENTITIES" );
+       }
+
+       mapent = &entities[num_entities];
+       num_entities++;
+
+       do
+       {
+               if ( !GetScriptToken( true ) ) {
+                       Error( "ParseEntity: EOF without closing brace" );
+               }
+               if ( !strcmp( token, "}" ) ) {
+                       break;
+               }
+               e = ParseEpair();
+               e->next = mapent->epairs;
+               mapent->epairs = e;
+       } while ( 1 );
+
+       return true;
+}
+
+/*
+   ================
+   ParseEntities
+
+   Parses the dentdata string into entities
+   ================
+ */
+void ParseEntities( void ){
+       num_entities = 0;
+       ParseFromMemory( dentdata, entdatasize );
+
+       while ( ParseEntity() )
+       {
+       }
+}
+
+
+/*
+   ================
+   UnparseEntities
+
+   Generates the dentdata string from all the entities
+   ================
+ */
+void UnparseEntities( void ){
+       char    *buf, *end;
+       epair_t *ep;
+       char line[2048];
+       int i;
+       char key[1024], value[1024];
+
+       buf = dentdata;
+       end = buf;
+       *end = 0;
+
+       for ( i = 0 ; i < num_entities ; i++ )
+       {
+               ep = entities[i].epairs;
+               if ( !ep ) {
+                       continue;   // ent got removed
+
+               }
+               strcat( end,"{\n" );
+               end += 2;
+
+               for ( ep = entities[i].epairs ; ep ; ep = ep->next )
+               {
+                       strcpy( key, ep->key );
+                       StripTrailing( key );
+                       strcpy( value, ep->value );
+                       StripTrailing( value );
+
+                       sprintf( line, "\"%s\" \"%s\"\n", key, value );
+                       strcat( end, line );
+                       end += strlen( line );
+               }
+               strcat( end,"}\n" );
+               end += 2;
+
+               if ( end > buf + MAX_MAP_ENTSTRING ) {
+                       Error( "Entity text too long" );
+               }
+       }
+       entdatasize = end - buf + 1;
+}
+
+void PrintEntity( entity_t *ent ){
+       epair_t *ep;
+
+       printf( "------- entity %p -------\n", ent );
+       for ( ep = ent->epairs ; ep ; ep = ep->next )
+       {
+               printf( "%s = %s\n", ep->key, ep->value );
+       }
+
+}
+
+void    SetKeyValue( entity_t *ent, char *key, char *value ){
+       epair_t *ep;
+
+       for ( ep = ent->epairs ; ep ; ep = ep->next )
+               if ( !strcmp( ep->key, key ) ) {
+                       free( ep->value );
+                       ep->value = copystring( value );
+                       return;
+               }
+       ep = malloc( sizeof( *ep ) );
+       if ( !ep ) {
+               Error( "SetKeyValue MALLOC failed!  Could not allocate %s bytes.", sizeof( *ep ) );
+       }
+       ep->next = ent->epairs;
+       ent->epairs = ep;
+       ep->key = copystring( key );
+       ep->value = copystring( value );
+}
+
+char    *ValueForKey( entity_t *ent, char *key ){
+       epair_t *ep;
+
+       for ( ep = ent->epairs ; ep ; ep = ep->next )
+               if ( !strcmp( ep->key, key ) ) {
+                       return ep->value;
+               }
+       return "";
+}
+
+vec_t   FloatForKey( entity_t *ent, char *key ){
+       char    *k;
+
+       k = ValueForKey( ent, key );
+       return atof( k );
+}
+
+void    GetVectorForKey( entity_t *ent, char *key, vec3_t vec ){
+       char    *k;
+       double v1, v2, v3;
+
+       k = ValueForKey( ent, key );
+// scanf into doubles, then assign, so it is vec_t size independent
+       v1 = v2 = v3 = 0;
+       sscanf( k, "%lf %lf %lf", &v1, &v2, &v3 );
+       vec[0] = v1;
+       vec[1] = v2;
+       vec[2] = v3;
+}
diff --git a/tools/heretic2/common/bspfile.h b/tools/heretic2/common/bspfile.h
new file mode 100644 (file)
index 0000000..f66659b
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _QBSP3_H
+#define _QBSP3_H
+
+
+#include "qfiles.h"
+
+
+extern int nummodels;
+extern dmodel_t dmodels[MAX_MAP_MODELS];
+
+extern int visdatasize;
+extern byte dvisdata[MAX_MAP_VISIBILITY];
+extern dvis_t      *dvis;
+
+extern int lightdatasize;
+extern byte dlightdata[MAX_MAP_LIGHTING];
+
+extern int entdatasize;
+extern char dentdata[MAX_MAP_ENTSTRING];
+
+extern int numleafs;
+extern dleaf_t dleafs[MAX_MAP_LEAFS];
+
+extern int numplanes;
+extern dplane_t dplanes[MAX_MAP_PLANES];
+
+extern int numvertexes;
+extern dvertex_t dvertexes[MAX_MAP_VERTS];
+
+extern int numnodes;
+extern dnode_t dnodes[MAX_MAP_NODES];
+
+extern int numtexinfo;
+extern texinfo_t texinfo[MAX_MAP_TEXINFO];
+
+extern int numfaces;
+extern dface_t dfaces[MAX_MAP_FACES];
+
+extern int numedges;
+extern dedge_t dedges[MAX_MAP_EDGES];
+
+extern int numleaffaces;
+extern unsigned short dleaffaces[MAX_MAP_LEAFFACES];
+
+extern int numleafbrushes;
+extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
+
+extern int numsurfedges;
+extern int dsurfedges[MAX_MAP_SURFEDGES];
+
+extern int numareas;
+extern darea_t dareas[MAX_MAP_AREAS];
+
+extern int numareaportals;
+extern dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
+
+extern int numbrushes;
+extern dbrush_t dbrushes[MAX_MAP_BRUSHES];
+
+extern int numbrushsides;
+extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
+
+extern byte dpop[256];
+
+void DecompressVis( byte *in, byte *decompressed );
+int CompressVis( byte *vis, byte *dest );
+
+void    LoadBSPFile( char *filename );
+void    LoadBSPFileTexinfo( char *filename );    // just for qdata
+void    WriteBSPFile( char *filename );
+void    PrintBSPFileSizes( void );
+
+//===============
+
+
+typedef struct epair_s
+{
+       struct epair_s  *next;
+       char    *key;
+       char    *value;
+} epair_t;
+
+typedef struct
+{
+       vec3_t origin;
+       int firstbrush;
+       int numbrushes;
+       epair_t     *epairs;
+
+// only valid for func_areaportals
+       int areaportalnum;
+       int portalareas[2];
+} entity_t;
+
+extern int num_entities;
+extern entity_t entities[MAX_MAP_ENTITIES];
+
+void    ParseEntities( void );
+void    UnparseEntities( void );
+
+void    SetKeyValue( entity_t *ent, char *key, char *value );
+char    *ValueForKey( entity_t *ent, char *key );
+// will return "" if not present
+
+vec_t   FloatForKey( entity_t *ent, char *key );
+void    GetVectorForKey( entity_t *ent, char *key, vec3_t vec );
+
+epair_t *ParseEpair( void );
+
+void PrintEntity( entity_t *ent );
+
+#endif //_QBSP3_H
diff --git a/tools/heretic2/common/cmdlib.c b/tools/heretic2/common/cmdlib.c
new file mode 100644 (file)
index 0000000..c45ff16
--- /dev/null
@@ -0,0 +1,1186 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// Nurail: Swiped from quake3/common
+
+#include "cmdlib.h"
+#include "globaldefs.h"
+#include "mathlib.h"
+#include "inout.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if GDEF_OS_WINDOWS
+#include <direct.h>
+#include <windows.h>
+#elif GDEF_OS_NEXT
+#include <libc.h>
+#else // OTHER OSES
+#include <unistd.h>
+#endif // OTHER OSES
+
+#if !GDEF_OS_WINDOWS
+#define strlwr strlower
+#endif // !GDEF_OS_WINDOWS
+
+#define BASEDIRNAME "h"
+#define PATHSEPERATOR '/'
+
+extern qboolean verbose;
+
+qboolean g_dokeypress = false;
+
+qboolean g_nomkdir = false;
+
+
+#ifdef SAFE_MALLOC
+void *safe_malloc( size_t size ){
+       void *p;
+
+       p = malloc( size );
+       if ( !p ) {
+               Error( "safe_malloc failed on allocation of %i bytes", size );
+       }
+
+       return p;
+}
+
+void *safe_malloc_info( size_t size, char* info ){
+       void *p;
+
+       p = malloc( size );
+       if ( !p ) {
+               Error( "%s: safe_malloc failed on allocation of %i bytes", info, size );
+       }
+
+       return p;
+}
+#endif // !SAFE_MALLOC
+
+void *SafeMalloc( size_t n, char *desc ){
+       void *p;
+
+       if ( ( p = malloc( n ) ) == NULL ) {
+               Error( "Failed to allocate %d bytes for '%s'.\n", n, desc );
+       }
+       memset( p, 0, n );
+       return p;
+}
+
+// set these before calling CheckParm
+int myargc;
+char **myargv;
+
+char com_token[1024];
+qboolean com_eof;
+
+qboolean archive;
+char archivedir[1024];
+
+
+/*
+   ===================
+   ExpandWildcards
+
+   Mimic unix command line expansion
+   ===================
+ */
+#define MAX_EX_ARGC 1024
+
+int ex_argc;
+char    *ex_argv[MAX_EX_ARGC];
+
+#if GDEF_OS_WINDOWS
+#include "io.h"
+void ExpandWildcards( int *argc, char ***argv ){
+       struct _finddata_t fileinfo;
+       int handle;
+       int i;
+       char filename[1024];
+       char filebase[1024];
+       char    *path;
+
+       ex_argc = 0;
+       for ( i = 0 ; i < *argc ; i++ )
+       {
+               path = ( *argv )[i];
+               if ( path[0] == '-'
+                        || ( !strstr( path, "*" ) && !strstr( path, "?" ) ) ) {
+                       ex_argv[ex_argc++] = path;
+                       continue;
+               }
+
+               handle = _findfirst( path, &fileinfo );
+               if ( handle == -1 ) {
+                       return;
+               }
+
+               ExtractFilePath( path, filebase );
+
+               do
+               {
+                       sprintf( filename, "%s%s", filebase, fileinfo.name );
+                       ex_argv[ex_argc++] = copystring( filename );
+               } while ( _findnext( handle, &fileinfo ) != -1 );
+
+               _findclose( handle );
+       }
+
+       *argc = ex_argc;
+       *argv = ex_argv;
+}
+#else // !GDEF_OS_WINDOWS
+void ExpandWildcards( int *argc, char ***argv ){
+}
+#endif // !GDEF_OS_WINDOWS
+
+/*
+
+   qdir will hold the path up to the quake directory, including the slash
+
+   f:\quake\
+   /raid/quake/
+
+   gamedir will hold qdir + the game directory (id1, id2, etc)
+
+ */
+
+char qdir[1024];
+char gamedir[1024];
+char writedir[1024];
+
+void SetQdirFromPath( const char *path ){
+       char temp[1024];
+       const char  *c;
+       const char *sep;
+       int len, count;
+
+       if ( !( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) ) { // path is partial
+               Q_getwd( temp );
+               strcat( temp, path );
+               path = temp;
+       }
+
+       // search for "quake2" in path
+
+       len = strlen( BASEDIRNAME );
+       for ( c = path + strlen( path ) - 1 ; c != path ; c-- )
+       {
+               int i;
+
+               if ( !Q_strncasecmp( c, BASEDIRNAME, len ) ) {
+                       //
+                       //strncpy (qdir, path, c+len+2-path);
+                       // the +2 assumes a 2 or 3 following quake which is not the
+                       // case with a retail install
+                       // so we need to add up how much to the next separator
+                       sep = c + len;
+                       count = 1;
+                       while ( *sep && *sep != '/' && *sep != '\\' )
+                       {
+                               sep++;
+                               count++;
+                       }
+                       strncpy( qdir, path, c + len + count - path );
+                       Sys_Printf( "qdir: %s\n", qdir );
+                       for ( i = 0; i < strlen( qdir ); i++ )
+                       {
+                               if ( qdir[i] == '\\' ) {
+                                       qdir[i] = '/';
+                               }
+                       }
+
+                       c += len + count;
+                       while ( *c )
+                       {
+                               if ( *c == '/' || *c == '\\' ) {
+                                       strncpy( gamedir, path, c + 1 - path );
+
+                                       for ( i = 0; i < strlen( gamedir ); i++ )
+                                       {
+                                               if ( gamedir[i] == '\\' ) {
+                                                       gamedir[i] = '/';
+                                               }
+                                       }
+
+                                       Sys_Printf( "gamedir: %s\n", gamedir );
+
+                                       if ( !writedir[0] ) {
+                                               strcpy( writedir, gamedir );
+                                       }
+                                       else if ( writedir[strlen( writedir ) - 1] != '/' ) {
+                                               writedir[strlen( writedir )] = '/';
+                                               writedir[strlen( writedir ) + 1] = 0;
+                                       }
+
+                                       return;
+                               }
+                               c++;
+                       }
+                       Error( "No gamedir in %s", path );
+                       return;
+               }
+       }
+       Error( "SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path );
+}
+
+char *ExpandArg( const char *path ){
+       static char full[1024];
+
+       if ( path[0] != '/' && path[0] != '\\' && path[1] != ':' ) {
+               Q_getwd( full );
+               strcat( full, path );
+       }
+       else{
+               strcpy( full, path );
+       }
+       return full;
+}
+
+char *ExpandPath( const char *path ){
+       static char full[1024];
+       if ( !qdir ) {
+               Error( "ExpandPath called without qdir set" );
+       }
+       if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) {
+               strcpy( full, path );
+               return full;
+       }
+       sprintf( full, "%s%s", qdir, path );
+       return full;
+}
+
+char *ExpandGamePath( const char *path ){
+       static char full[1024];
+       if ( !qdir ) {
+               Error( "ExpandGamePath called without qdir set" );
+       }
+       if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) {
+               strcpy( full, path );
+               return full;
+       }
+       sprintf( full, "%s%s", gamedir, path );
+       return full;
+}
+
+char *ExpandPathAndArchive( const char *path ){
+       char    *expanded;
+       char archivename[1024];
+
+       expanded = ExpandPath( path );
+
+       if ( archive ) {
+               sprintf( archivename, "%s/%s", archivedir, path );
+               QCopyFile( expanded, archivename );
+       }
+       return expanded;
+}
+
+
+char *copystring( const char *s ){
+       char    *b;
+       b = safe_malloc( strlen( s ) + 1 );
+       strcpy( b, s );
+       return b;
+}
+
+
+
+/*
+   ================
+   I_FloatTime
+   ================
+ */
+double I_FloatTime( void ){
+       time_t t;
+
+       time( &t );
+
+       return t;
+#if 0
+// more precise, less portable
+       struct timeval tp;
+       struct timezone tzp;
+       static int secbase;
+
+       gettimeofday( &tp, &tzp );
+
+       if ( !secbase ) {
+               secbase = tp.tv_sec;
+               return tp.tv_usec / 1000000.0;
+       }
+
+       return ( tp.tv_sec - secbase ) + tp.tv_usec / 1000000.0;
+#endif
+}
+
+void Q_getwd( char *out ){
+       int i = 0;
+
+#if GDEF_OS_WINDOWS
+       _getcwd( out, 256 );
+       strcat( out, "\\" );
+#else // !GDEF_OS_WINDOWS
+       // Gef: Changed from getwd() to getcwd() to avoid potential buffer overflow
+       getcwd( out, 256 );
+       strcat( out, "/" );
+#endif // !GDEF_OS_WINDOWS
+       while ( out[i] != 0 )
+       {
+               if ( out[i] == '\\' ) {
+                       out[i] = '/';
+               }
+               i++;
+       }
+}
+
+
+void Q_mkdir( const char *path ){
+#if GDEF_OS_WINDOWS
+       if ( _mkdir( path ) != -1 ) {
+               return;
+       }
+#else // !GDEF_OS_WINDOWS
+       if ( mkdir( path, 0777 ) != -1 ) {
+               return;
+       }
+#endif // !GDEF_OS_WINDOWS
+       if ( errno != EEXIST ) {
+               Error( "mkdir %s: %s",path, strerror( errno ) );
+       }
+}
+
+/*
+   ============
+   FileTime
+
+   returns -1 if not present
+   ============
+ */
+int FileTime( const char *path ){
+       struct  stat buf;
+
+       if ( stat( path,&buf ) == -1 ) {
+               return -1;
+       }
+
+       return buf.st_mtime;
+}
+
+
+
+/*
+   ==============
+   COM_Parse
+
+   Parse a token out of a string
+   ==============
+ */
+char *COM_Parse( char *data ){
+       int c;
+       int len;
+
+       len = 0;
+       com_token[0] = 0;
+
+       if ( !data ) {
+               return NULL;
+       }
+
+// skip whitespace
+skipwhite:
+       while ( ( c = *data ) <= ' ' )
+       {
+               if ( c == 0 ) {
+                       com_eof = true;
+                       return NULL;            // end of file;
+               }
+               data++;
+       }
+
+// skip // comments
+       if ( c == '/' && data[1] == '/' ) {
+               while ( *data && *data != '\n' )
+                       data++;
+               goto skipwhite;
+       }
+
+
+// handle quoted strings specially
+       if ( c == '\"' ) {
+               data++;
+               do
+               {
+                       c = *data++;
+                       if ( c == '\"' ) {
+                               com_token[len] = 0;
+                               return data;
+                       }
+                       com_token[len] = c;
+                       len++;
+               } while ( 1 );
+       }
+
+// parse single characters
+       if ( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' ) {
+               com_token[len] = c;
+               len++;
+               com_token[len] = 0;
+               return data + 1;
+       }
+
+// parse a regular word
+       do
+       {
+               com_token[len] = c;
+               data++;
+               len++;
+               c = *data;
+               if ( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' ) {
+                       break;
+               }
+       } while ( c > 32 );
+
+       com_token[len] = 0;
+       return data;
+}
+
+int Q_strncasecmp( const char *s1, const char *s2, int n ){
+       int c1, c2;
+
+       do
+       {
+               c1 = *s1++;
+               c2 = *s2++;
+
+               if ( !n-- ) {
+                       return 0;       // strings are equal until end point
+
+               }
+               if ( c1 != c2 ) {
+                       if ( c1 >= 'a' && c1 <= 'z' ) {
+                               c1 -= ( 'a' - 'A' );
+                       }
+                       if ( c2 >= 'a' && c2 <= 'z' ) {
+                               c2 -= ( 'a' - 'A' );
+                       }
+                       if ( c1 != c2 ) {
+                               return -1;      // strings not equal
+                       }
+               }
+       } while ( c1 );
+
+       return 0;       // strings are equal
+}
+
+int Q_stricmp( const char *s1, const char *s2 ){
+       return Q_strncasecmp( s1, s2, 99999 );
+}
+
+int Q_strcasecmp( const char *s1, const char *s2 ){
+       return Q_strncasecmp( s1, s2, 99999 );
+}
+
+// NOTE TTimo when switching to Multithread DLL (Release/Debug) in the config
+//   started getting warnings about that function, prolly a duplicate with the runtime function
+//   maybe we still need to have it in linux builds
+/*
+   char *strupr (char *start)
+   {
+    char       *in;
+    in = start;
+    while (*in)
+    {
+   *in = toupper(*in);
+        in++;
+    }
+    return start;
+   }
+ */
+
+char *strlower( char *start ){
+       char    *in;
+       in = start;
+       while ( *in )
+       {
+               *in = tolower( *in );
+               in++;
+       }
+       return start;
+}
+
+
+/*
+   =============================================================================
+
+                        MISC FUNCTIONS
+
+   =============================================================================
+ */
+
+
+/*
+   =================
+   CheckParm
+
+   Checks for the given parameter in the program's command line arguments
+   Returns the argument number (1 to argc-1) or 0 if not present
+   =================
+ */
+int CheckParm( const char *check ){
+       int i;
+
+       for ( i = 1; i < myargc; i++ )
+       {
+               if ( !Q_stricmp( check, myargv[i] ) ) {
+                       return i;
+               }
+       }
+
+       return 0;
+}
+
+
+
+/*
+   ================
+   Q_filelength
+   ================
+ */
+int Q_filelength( FILE *f ){
+       int pos;
+       int end;
+
+       pos = ftell( f );
+       fseek( f, 0, SEEK_END );
+       end = ftell( f );
+       fseek( f, pos, SEEK_SET );
+
+       return end;
+}
+
+
+FILE *SafeOpenWrite( const char *filename ){
+       FILE    *f;
+
+       f = fopen( filename, "wb" );
+
+       if ( !f ) {
+               Error( "Error opening %s: %s",filename,strerror( errno ) );
+       }
+
+       return f;
+}
+
+FILE *SafeOpenRead( const char *filename ){
+       FILE    *f;
+
+       f = fopen( filename, "rb" );
+
+       if ( !f ) {
+               Error( "Error opening %s: %s",filename,strerror( errno ) );
+       }
+
+       return f;
+}
+
+
+void SafeRead( FILE *f, void *buffer, int count ){
+       if ( fread( buffer, 1, count, f ) != (size_t)count ) {
+               Error( "File read failure" );
+       }
+}
+
+
+void SafeWrite( FILE *f, const void *buffer, int count ){
+       if ( fwrite( buffer, 1, count, f ) != (size_t)count ) {
+               Error( "File write failure" );
+       }
+}
+
+
+/*
+   ==============
+   FileExists
+   ==============
+ */
+qboolean    FileExists( const char *filename ){
+       FILE    *f;
+
+       f = fopen( filename, "r" );
+       if ( !f ) {
+               return false;
+       }
+       fclose( f );
+       return true;
+}
+
+/*
+   ==============
+   LoadFile
+   ==============
+ */
+int    LoadFile( const char *filename, void **bufferptr ){
+       FILE    *f;
+       int length;
+       void    *buffer;
+
+       f = SafeOpenRead( filename );
+       length = Q_filelength( f );
+       buffer = safe_malloc( length + 1 );
+       ( (char *)buffer )[length] = 0;
+       SafeRead( f, buffer, length );
+       fclose( f );
+
+       *bufferptr = buffer;
+       return length;
+}
+
+
+/*
+   ==============
+   LoadFileBlock
+   -
+   rounds up memory allocation to 4K boundry
+   -
+   ==============
+ */
+int    LoadFileBlock( const char *filename, void **bufferptr ){
+       FILE    *f;
+       int length, nBlock, nAllocSize;
+       void    *buffer;
+
+       f = SafeOpenRead( filename );
+       length = Q_filelength( f );
+       nAllocSize = length;
+       nBlock = nAllocSize % MEM_BLOCKSIZE;
+       if ( nBlock > 0 ) {
+               nAllocSize += MEM_BLOCKSIZE - nBlock;
+       }
+       buffer = safe_malloc( nAllocSize + 1 );
+       memset( buffer, 0, nAllocSize + 1 );
+       SafeRead( f, buffer, length );
+       fclose( f );
+
+       *bufferptr = buffer;
+       return length;
+}
+
+
+/*
+   ==============
+   TryLoadFile
+
+   Allows failure
+   ==============
+ */
+int    TryLoadFile( const char *filename, void **bufferptr ){
+       FILE    *f;
+       int length;
+       void    *buffer;
+
+       *bufferptr = NULL;
+
+       f = fopen( filename, "rb" );
+       if ( !f ) {
+               return -1;
+       }
+       length = Q_filelength( f );
+       buffer = safe_malloc( length + 1 );
+       ( (char *)buffer )[length] = 0;
+       SafeRead( f, buffer, length );
+       fclose( f );
+
+       *bufferptr = buffer;
+       return length;
+}
+
+
+/*
+   ==============
+   SaveFile
+   ==============
+ */
+void    SaveFile( const char *filename, const void *buffer, int count ){
+       FILE    *f;
+
+       f = SafeOpenWrite( filename );
+       SafeWrite( f, buffer, count );
+       fclose( f );
+}
+
+
+
+void DefaultExtension( char *path, const char *extension ){
+       char    *src;
+//
+// if path doesnt have a .EXT, append extension
+// (extension should include the .)
+//
+       src = path + strlen( path ) - 1;
+
+       while ( *src != '/' && *src != '\\' && src != path )
+       {
+               if ( *src == '.' ) {
+                       return;                 // it has an extension
+               }
+               src--;
+       }
+
+       strcat( path, extension );
+}
+
+
+void DefaultPath( char *path, const char *basepath ){
+       char temp[128];
+
+       if ( path[ 0 ] == '/' || path[ 0 ] == '\\' ) {
+               return;                   // absolute path location
+       }
+       strcpy( temp,path );
+       strcpy( path,basepath );
+       strcat( path,temp );
+}
+
+
+void    StripFilename( char *path ){
+       int length;
+
+       length = strlen( path ) - 1;
+       while ( length > 0 && path[length] != '/' && path[ length ] != '\\' )
+               length--;
+       path[length] = 0;
+}
+
+void    StripExtension( char *path ){
+       int length;
+
+       length = strlen( path ) - 1;
+       while ( length > 0 && path[length] != '.' )
+       {
+               length--;
+               if ( path[length] == '/' || path[ length ] == '\\' ) {
+                       return;     // no extension
+               }
+       }
+       if ( length ) {
+               path[length] = 0;
+       }
+}
+
+
+/*
+   ====================
+   Extract file parts
+   ====================
+ */
+
+// FIXME: should include the slash, otherwise
+// backing to an empty path will be wrong when appending a slash
+void ExtractFilePath( const char *path, char *dest ){
+       const char    *src;
+
+       src = path + strlen( path ) - 1;
+
+//
+// back up until a \ or the start
+//
+       while ( src != path && *( src - 1 ) != '\\' && *( src - 1 ) != '/' )
+               src--;
+
+       memcpy( dest, path, src - path );
+       dest[src - path] = 0;
+}
+
+void ExtractFileBase( const char *path, char *dest ){
+       const char    *src;
+
+       src = path + strlen( path ) - 1;
+
+//
+// back up until a \ or the start
+//
+       while ( src != path && *( src - 1 ) != '/' && *( src - 1 ) != '\\' )
+               src--;
+
+       while ( *src && *src != '.' )
+       {
+               *dest++ = *src++;
+       }
+       *dest = 0;
+}
+
+void ExtractFileExtension( const char *path, char *dest ){
+       const char    *src;
+
+       src = path + strlen( path ) - 1;
+
+//
+// back up until a . or the start
+//
+       while ( src != path && *( src - 1 ) != '.' )
+               src--;
+       if ( src == path ) {
+               *dest = 0;  // no extension
+               return;
+       }
+
+       strcpy( dest,src );
+}
+
+
+/*
+   ==============
+   ParseNum / ParseHex
+   ==============
+ */
+int ParseHex( const char *hex ){
+       const char    *str;
+       int num;
+
+       num = 0;
+       str = hex;
+
+       while ( *str )
+       {
+               num <<= 4;
+               if ( *str >= '0' && *str <= '9' ) {
+                       num += *str - '0';
+               }
+               else if ( *str >= 'a' && *str <= 'f' ) {
+                       num += 10 + *str - 'a';
+               }
+               else if ( *str >= 'A' && *str <= 'F' ) {
+                       num += 10 + *str - 'A';
+               }
+               else{
+                       Error( "Bad hex number: %s",hex );
+               }
+               str++;
+       }
+
+       return num;
+}
+
+
+int ParseNum( const char *str ){
+       if ( str[0] == '$' ) {
+               return ParseHex( str + 1 );
+       }
+       if ( str[0] == '0' && str[1] == 'x' ) {
+               return ParseHex( str + 2 );
+       }
+       return atol( str );
+}
+/*
+   // all output ends up through here
+   void FPrintf (int flag, char *buf)
+   {
+   printf(buf);
+
+   }
+
+   void Sys_FPrintf (int flag, const char *format, ...)
+   {
+   char out_buffer[4096];
+    va_list argptr;
+
+   if ((flag == SYS_VRB) && (verbose == false))
+    return;
+
+   va_start (argptr, format);
+    vsprintf (out_buffer, format, argptr);
+    va_end (argptr);
+
+   FPrintf (flag, out_buffer);
+   }
+
+   void Sys_Printf (const char *format, ...)
+   {
+   char out_buffer[4096];
+    va_list argptr;
+
+   va_start (argptr, format);
+    vsprintf (out_buffer, format, argptr);
+    va_end (argptr);
+
+   FPrintf (SYS_STD, out_buffer);
+   }
+
+   //=================
+   //Error
+   //
+   //For abnormal program terminations
+   //=================
+
+   void Error( const char *error, ...)
+   {
+   char out_buffer[4096];
+   char tmp[4096];
+    va_list argptr;
+
+    va_start (argptr,error);
+    vsprintf (tmp, error, argptr);
+    va_end (argptr);
+
+   sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
+
+   FPrintf( SYS_ERR, out_buffer );
+
+    exit (1);
+   }
+
+ */
+
+/*
+   ============================================================================
+
+                    BYTE ORDER FUNCTIONS
+
+   ============================================================================
+ */
+
+#if GDEF_ARCH_ENDIAN_BIG
+
+short   LittleShort( short l ){
+       byte b1,b2;
+
+       b1 = l & 255;
+       b2 = ( l >> 8 ) & 255;
+
+       return ( b1 << 8 ) + b2;
+}
+
+short   BigShort( short l ){
+       return l;
+}
+
+
+int    LittleLong( int l ){
+       byte b1,b2,b3,b4;
+
+       b1 = l & 255;
+       b2 = ( l >> 8 ) & 255;
+       b3 = ( l >> 16 ) & 255;
+       b4 = ( l >> 24 ) & 255;
+
+       return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4;
+}
+
+int    BigLong( int l ){
+       return l;
+}
+
+
+float   LittleFloat( float l ){
+       union {byte b[4]; float f; } in, out;
+
+       in.f = l;
+       out.b[0] = in.b[3];
+       out.b[1] = in.b[2];
+       out.b[2] = in.b[1];
+       out.b[3] = in.b[0];
+
+       return out.f;
+}
+
+float   BigFloat( float l ){
+       return l;
+}
+
+
+#else // !GDEF_ARCH_ENDIAN_BIG
+
+
+short   BigShort( short l ){
+       byte b1,b2;
+
+       b1 = l & 255;
+       b2 = ( l >> 8 ) & 255;
+
+       return ( b1 << 8 ) + b2;
+}
+
+short   LittleShort( short l ){
+       return l;
+}
+
+
+int    BigLong( int l ){
+       byte b1,b2,b3,b4;
+
+       b1 = l & 255;
+       b2 = ( l >> 8 ) & 255;
+       b3 = ( l >> 16 ) & 255;
+       b4 = ( l >> 24 ) & 255;
+
+       return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4;
+}
+
+int    LittleLong( int l ){
+       return l;
+}
+
+float   BigFloat( float l ){
+       union {byte b[4]; float f; } in, out;
+
+       in.f = l;
+       out.b[0] = in.b[3];
+       out.b[1] = in.b[2];
+       out.b[2] = in.b[1];
+       out.b[3] = in.b[0];
+
+       return out.f;
+}
+
+float   LittleFloat( float l ){
+       return l;
+}
+
+#endif // ! GDEF_ARCH_ENDIAN_BIG
+
+
+//=======================================================
+
+
+// FIXME: byte swap?
+
+// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
+// and the initial and final xor values shown below...  in other words, the
+// CCITT standard CRC used by XMODEM
+
+#define CRC_INIT_VALUE  0xffff
+#define CRC_XOR_VALUE   0x0000
+
+static unsigned short crctable[256] =
+{
+       0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+       0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+       0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+       0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+       0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+       0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+       0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+       0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+       0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+       0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+       0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+       0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+       0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+       0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+       0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+       0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+       0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+       0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+       0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+       0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+       0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+       0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+       0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+       0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+       0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+       0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+       0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+       0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+       0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+       0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+       0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+       0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+void CRC_Init( unsigned short *crcvalue ){
+       *crcvalue = CRC_INIT_VALUE;
+}
+
+void CRC_ProcessByte( unsigned short *crcvalue, byte data ){
+       *crcvalue = ( *crcvalue << 8 ) ^ crctable[( *crcvalue >> 8 ) ^ data];
+}
+
+unsigned short CRC_Value( unsigned short crcvalue ){
+       return crcvalue ^ CRC_XOR_VALUE;
+}
+//=============================================================================
+
+/*
+   ============
+   CreatePath
+   ============
+ */
+void    CreatePath( const char *path ){
+       const char  *ofs;
+       char c;
+       char dir[1024];
+
+#if GDEF_OS_WINDOWS
+       int olddrive = -1;
+
+       if ( path[1] == ':' ) {
+               olddrive = _getdrive();
+               _chdrive( toupper( path[0] ) - 'A' + 1 );
+       }
+#endif // !GDEF_OS_WINDOWS
+
+       if ( path[1] == ':' ) {
+               path += 2;
+       }
+
+       for ( ofs = path + 1 ; *ofs ; ofs++ )
+       {
+               c = *ofs;
+               if ( c == '/' || c == '\\' ) { // create the directory
+                       memcpy( dir, path, ofs - path );
+                       dir[ ofs - path ] = 0;
+                       Q_mkdir( dir );
+               }
+       }
+
+#if GDEF_OS_WINDOWS
+       if ( olddrive != -1 ) {
+               _chdrive( olddrive );
+       }
+#endif // !GDEF_OS_WINDOWS
+}
+
+
+/*
+   ============
+   QCopyFile
+
+   Used to archive source files
+   ============
+ */
+void QCopyFile( const char *from, const char *to ){
+       void    *buffer;
+       int length;
+
+       length = LoadFile( from, &buffer );
+       CreatePath( to );
+       SaveFile( to, buffer, length );
+       free( buffer );
+}
+
+void Sys_Sleep( int n ){
+#if GDEF_OS_WINDOWS
+       Sleep( n );
+#else // !GDEF_OS_WINDOWS
+       usleep( n * 1000 );
+#endif // !GDEF_OS_WINDOWS
+}
diff --git a/tools/heretic2/common/cmdlib.h b/tools/heretic2/common/cmdlib.h
new file mode 100644 (file)
index 0000000..b8b1aa3
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// cmdlib.h
+
+#ifndef __CMDLIB__
+#define __CMDLIB__
+
+#if GDEF_COMPILER_MSVC
+#pragma warning(disable : 4244)     // MIPS
+#pragma warning(disable : 4136)     // X86
+#pragma warning(disable : 4051)     // ALPHA
+
+#pragma warning(disable : 4018)     // signed/unsigned mismatch
+#pragma warning(disable : 4305)     // truncate from double to float
+
+#pragma check_stack(off)
+
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <time.h>
+#include <stdarg.h>
+
+#if GDEF_COMPILER_MSVC
+
+#pragma intrinsic( memset, memcpy )
+
+#endif
+
+#ifndef __BYTEBOOL__
+  #define __BYTEBOOL__
+//typedef enum {false, true} qboolean;
+//typedef unsigned char byte;
+  #include "q_typedef.h"
+#endif
+
+#ifdef PATH_MAX
+#define MAX_OS_PATH     PATH_MAX
+#else
+#define MAX_OS_PATH     1024
+#endif
+#define MEM_BLOCKSIZE 4096
+/*
+   extern      qboolean verbose;
+   #define SYS_VRB 0 // verbose support (on/off)
+   #define SYS_STD 1 // standard print level
+   #define SYS_WRN 2 // warnings
+   #define SYS_ERR 3 // error
+ */
+// the dec offsetof macro doesnt work very well...
+#define myoffsetof( type,identifier ) ( (size_t)& ( (type *)0 )->identifier )
+
+#define SAFE_MALLOC
+#ifdef SAFE_MALLOC
+void *safe_malloc( size_t size );
+void *safe_malloc_info( size_t size, char* info );
+#else
+#define safe_malloc( a ) malloc( a )
+#endif /* SAFE_MALLOC */
+
+// set these before calling CheckParm
+extern int myargc;
+extern char **myargv;
+
+char *strlower( char *in );
+int Q_strncasecmp( const char *s1, const char *s2, int n );
+int Q_stricmp( const char *s1, const char *s2 );
+int Q_strcasecmp( const char *s1, const char *s2 );
+void Q_getwd( char *out );
+
+int Q_filelength( FILE *f );
+int FileTime( const char *path );
+
+void    Q_mkdir( const char *path );
+
+extern char qdir[1024];
+extern char gamedir[1024];
+extern char writedir[1024];
+extern char    *moddirparam;
+void SetQdirFromPath( const char *path );
+char *ExpandArg( const char *path );    // from cmd line
+char *ExpandPath( const char *path );   // from scripts
+char *ExpandGamePath( const char *path );
+char *ExpandPathAndArchive( const char *path );
+void ExpandWildcards( int *argc, char ***argv );
+
+
+double I_FloatTime( void );
+
+int     CheckParm( const char *check );
+
+void    *SafeMalloc( size_t n, char *desc );
+FILE    *SafeOpenWrite( const char *filename );
+FILE    *SafeOpenRead( const char *filename );
+void    SafeRead( FILE *f, void *buffer, int count );
+void    SafeWrite( FILE *f, const void *buffer, int count );
+
+int     LoadFile( const char *filename, void **bufferptr );
+int   LoadFileBlock( const char *filename, void **bufferptr );
+int     TryLoadFile( const char *filename, void **bufferptr );
+void    SaveFile( const char *filename, const void *buffer, int count );
+qboolean    FileExists( const char *filename );
+
+void    DefaultExtension( char *path, const char *extension );
+void    DefaultPath( char *path, const char *basepath );
+void    StripFilename( char *path );
+void    StripExtension( char *path );
+
+void    ExtractFilePath( const char *path, char *dest );
+void    ExtractFileBase( const char *path, char *dest );
+void    ExtractFileExtension( const char *path, char *dest );
+
+int     ParseNum( const char *str );
+/*
+   void Sys_Printf (const char *text, ...);
+   void Sys_FPrintf (int flag, const char *text, ...);
+   void        Error( const char *error, ... );
+ */
+short   BigShort( short l );
+short   LittleShort( short l );
+int     BigLong( int l );
+int     LittleLong( int l );
+float   BigFloat( float l );
+float   LittleFloat( float l );
+
+
+char *COM_Parse( char *data );
+
+extern char com_token[1024];
+extern qboolean com_eof;
+
+char *copystring( const char *s );
+
+
+void CRC_Init( unsigned short *crcvalue );
+void CRC_ProcessByte( unsigned short *crcvalue, byte data );
+unsigned short CRC_Value( unsigned short crcvalue );
+
+void    CreatePath( const char *path );
+void    QCopyFile( const char *from, const char *to );
+
+extern qboolean archive;
+extern char archivedir[1024];
+
+extern qboolean g_dokeypress;
+
+// sleep for the given amount of milliseconds
+void Sys_Sleep( int n );
+
+// for compression routines
+typedef struct
+{
+       byte    *data;
+       int count;
+} cblock_t;
+
+
+#endif
diff --git a/tools/heretic2/common/her2_threads.h b/tools/heretic2/common/her2_threads.h
new file mode 100644 (file)
index 0000000..6027a69
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef _THREADS_H
+
+#define _THREADS_H
+
+
+extern int numthreads;
+
+void ThreadSetDefault( void );
+int GetThreadWork( void );
+void RunThreadsOnIndividual( int workcnt, qboolean showpacifier, void ( *func )( int ) );
+void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) );
+void ThreadLock( void );
+void ThreadUnlock( void );
+
+#endif //_THREADS_H
diff --git a/tools/heretic2/common/inout.c b/tools/heretic2/common/inout.c
new file mode 100644 (file)
index 0000000..e0c1484
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+//-----------------------------------------------------------------------------
+//
+//
+// DESCRIPTION:
+// deal with in/out tasks, for either stdin/stdout or network/XML stream
+//
+
+#include "globaldefs.h"
+#include "cmdlib.h"
+#include "mathlib.h"
+#include "polylib.h"
+#include "inout.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if GDEF_OS_WINDOWS
+#include <direct.h>
+#include <windows.h>
+#endif
+
+// network broadcasting
+#include "l_net/l_net.h"
+#include "libxml/tree.h"
+
+#if GDEF_OS_WINDOWS
+HWND hwndOut = NULL;
+qboolean lookedForServer = false;
+UINT wm_BroadcastCommand = -1;
+#endif
+
+socket_t *brdcst_socket;
+netmessage_t msg;
+
+qboolean verbose = false;
+
+// our main document
+// is streamed through the network to Radiant
+// possibly written to disk at the end of the run
+//++timo FIXME: need to be global, required when creating nodes?
+xmlDocPtr doc;
+xmlNodePtr tree;
+
+// some useful stuff
+xmlNodePtr xml_NodeForVec( vec3_t v ){
+       xmlNodePtr ret;
+       char buf[1024];
+
+       sprintf( buf, "%f %f %f", v[0], v[1], v[2] );
+       ret = xmlNewNode( NULL, "point" );
+       xmlNodeAddContent( ret, buf );
+       return ret;
+}
+
+// send a node down the stream, add it to the document
+void xml_SendNode( xmlNodePtr node ){
+       xmlBufferPtr xml_buf;
+       char xmlbuf[MAX_NETMESSAGE]; // we have to copy content from the xmlBufferPtr into an aux buffer .. that sucks ..
+       // this index loops through the node buffer
+       int pos = 0;
+       int size;
+
+       xmlAddChild( doc->children, node );
+
+       if ( brdcst_socket ) {
+               xml_buf = xmlBufferCreate();
+               xmlNodeDump( xml_buf, doc, node, 0, 0 );
+
+               // the XML node might be too big to fit in a single network message
+               // l_net library defines an upper limit of MAX_NETMESSAGE
+               // there are some size check errors, so we use MAX_NETMESSAGE-10 to be safe
+               // if the size of the buffer exceeds MAX_NETMESSAGE-10 we'll send in several network messages
+               while ( pos < xml_buf->use )
+               {
+                       // what size are we gonna send now?
+                       ( xml_buf->use - pos < MAX_NETMESSAGE - 10 ) ? ( size = xml_buf->use - pos ) : ( size = MAX_NETMESSAGE - 10 );
+                       //++timo just a debug thing
+                       if ( size == MAX_NETMESSAGE - 10 ) {
+                               Sys_FPrintf( SYS_NOXML, "Got to split the buffer\n" );
+                       }
+                       memcpy( xmlbuf, xml_buf->content + pos, size );
+                       xmlbuf[size] = '\0';
+                       NMSG_Clear( &msg );
+                       NMSG_WriteString( &msg, xmlbuf );
+                       Net_Send( brdcst_socket, &msg );
+                       // now that the thing is sent prepare to loop again
+                       pos += size;
+               }
+
+#if 0
+               // NOTE: the NMSG_WriteString is limited to MAX_NETMESSAGE
+               // we will need to split into chunks
+               // (we could also go lower level, in the end it's using send and receiv which are not size limited)
+               //++timo FIXME: MAX_NETMESSAGE is not exactly the max size we can stick in the message
+               //  there's some tweaking to do in l_net for that .. so let's give us a margin for now
+
+               //++timo we need to handle the case of a buffer too big to fit in a single message
+               // try without checks for now
+               if ( xml_buf->use > MAX_NETMESSAGE - 10 ) {
+                       // if we send that we are probably gonna break the stream at the other end..
+                       // and Error will call right there
+                       //Error( "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
+                       Sys_FPrintf( SYS_NOXML, "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use );
+                       xml_buf->content[xml_buf->use] = '\0'; //++timo this corrupts the buffer but we don't care it's for printing
+                       Sys_FPrintf( SYS_NOXML, xml_buf->content );
+
+               }
+
+               size = xml_buf->use;
+               memcpy( xmlbuf, xml_buf->content, size );
+               xmlbuf[size] = '\0';
+               NMSG_Clear( &msg );
+               NMSG_WriteString( &msg, xmlbuf );
+               Net_Send( brdcst_socket, &msg );
+#endif
+
+               xmlBufferFree( xml_buf );
+       }
+}
+
+void xml_Select( char *msg, int entitynum, int brushnum, qboolean bError ){
+       xmlNodePtr node, select;
+       char buf[1024];
+       char level[2];
+
+       // now build a proper "select" XML node
+       sprintf( buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg );
+       node = xmlNewNode( NULL, "select" );
+       xmlNodeAddContent( node, buf );
+       level[0] = (int)'0' + ( bError ? SYS_ERR : SYS_WRN )  ;
+       level[1] = 0;
+       xmlSetProp( node, "level", (char *)&level );
+       // a 'select' information
+       sprintf( buf, "%i %i", entitynum, brushnum );
+       select = xmlNewNode( NULL, "brush" );
+       xmlNodeAddContent( select, buf );
+       xmlAddChild( node, select );
+       xml_SendNode( node );
+
+       sprintf( buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg );
+       if ( bError ) {
+               Error( buf );
+       }
+       else{
+               Sys_FPrintf( SYS_NOXML, "%s\n", buf );
+       }
+
+}
+
+void xml_Point( char *msg, vec3_t pt ){
+       xmlNodePtr node, point;
+       char buf[1024];
+       char level[2];
+
+       node = xmlNewNode( NULL, "pointmsg" );
+       xmlNodeAddContent( node, msg );
+       level[0] = (int)'0' + SYS_ERR;
+       level[1] = 0;
+       xmlSetProp( node, "level", (char *)&level );
+       // a 'point' node
+       sprintf( buf, "%g %g %g", pt[0], pt[1], pt[2] );
+       point = xmlNewNode( NULL, "point" );
+       xmlNodeAddContent( point, buf );
+       xmlAddChild( node, point );
+       xml_SendNode( node );
+
+       sprintf( buf, "%s (%g %g %g)", msg, pt[0], pt[1], pt[2] );
+       Error( buf );
+}
+
+#define WINDING_BUFSIZE 2048
+void xml_Winding( char *msg, vec3_t p[], int numpoints, qboolean die ){
+       xmlNodePtr node, winding;
+       char buf[WINDING_BUFSIZE];
+       char smlbuf[128];
+       char level[2];
+       int i;
+
+       node = xmlNewNode( NULL, "windingmsg" );
+       xmlNodeAddContent( node, msg );
+       level[0] = (int)'0' + SYS_ERR;
+       level[1] = 0;
+       xmlSetProp( node, "level", (char *)&level );
+       // a 'winding' node
+       sprintf( buf, "%i ", numpoints );
+       for ( i = 0; i < numpoints; i++ )
+       {
+               sprintf( smlbuf, "(%g %g %g)", p[i][0], p[i][1], p[i][2] );
+               // don't overflow
+               if ( strlen( buf ) + strlen( smlbuf ) > WINDING_BUFSIZE ) {
+                       break;
+               }
+               strcat( buf, smlbuf );
+       }
+
+       winding = xmlNewNode( NULL, "winding" );
+       xmlNodeAddContent( winding, buf );
+       xmlAddChild( node, winding );
+       xml_SendNode( node );
+
+       if ( die ) {
+               Error( msg );
+       }
+       else
+       {
+               Sys_Printf( msg );
+               Sys_Printf( "\n" );
+       }
+}
+
+// in include
+#include "stream_version.h"
+
+void Broadcast_Setup( const char *dest ){
+       address_t address;
+       char sMsg[1024];
+
+       Net_Setup();
+       Net_StringToAddress( (char *)dest, &address );
+       brdcst_socket = Net_Connect( &address, 0 );
+       if ( brdcst_socket ) {
+               // send in a header
+               sprintf( sMsg, "<?xml version=\"1.0\"?><q3map_feedback version=\"" Q3MAP_STREAM_VERSION "\">" );
+               NMSG_Clear( &msg );
+               NMSG_WriteString( &msg, sMsg );
+               Net_Send( brdcst_socket, &msg );
+       }
+}
+
+void Broadcast_Shutdown(){
+       if ( brdcst_socket ) {
+               Sys_Printf( "Disconnecting\n" );
+               Net_Disconnect( brdcst_socket );
+               brdcst_socket = NULL;
+       }
+}
+
+// all output ends up through here
+void FPrintf( int flag, char *buf ){
+       xmlNodePtr node;
+       static qboolean bGotXML = false;
+       char level[2];
+
+       printf( buf );
+
+       // the following part is XML stuff only.. but maybe we don't want that message to go down the XML pipe?
+       if ( flag == SYS_NOXML ) {
+               return;
+       }
+
+       // ouput an XML file of the run
+       // use the DOM interface to build a tree
+       /*
+          <message level='flag'>
+          message string
+          .. various nodes to describe corresponding geometry ..
+          </message>
+        */
+       if ( !bGotXML ) {
+               // initialize
+               doc = xmlNewDoc( "1.0" );
+               doc->children = xmlNewDocRawNode( doc, NULL, "q3map_feedback", NULL );
+               bGotXML = true;
+       }
+       node = xmlNewNode( NULL, "message" );
+       xmlNodeAddContent( node, buf );
+       level[0] = (int)'0' + flag;
+       level[1] = 0;
+       xmlSetProp( node, "level", (char *)&level );
+
+       xml_SendNode( node );
+}
+
+#ifdef DBG_XML
+void DumpXML(){
+       xmlSaveFile( "XMLDump.xml", doc );
+}
+#endif
+
+void Sys_FPrintf( int flag, const char *format, ... ){
+       char out_buffer[4096];
+       va_list argptr;
+
+       if ( ( flag == SYS_VRB ) && ( verbose == false ) ) {
+               return;
+       }
+
+       va_start( argptr, format );
+       vsprintf( out_buffer, format, argptr );
+       va_end( argptr );
+
+       FPrintf( flag, out_buffer );
+}
+
+void Sys_Printf( const char *format, ... ){
+       char out_buffer[4096];
+       va_list argptr;
+
+       va_start( argptr, format );
+       vsprintf( out_buffer, format, argptr );
+       va_end( argptr );
+
+       FPrintf( SYS_STD, out_buffer );
+}
+
+/*
+   =================
+   Error
+
+   For abnormal program terminations
+   =================
+ */
+void Error( const char *error, ... ){
+       char out_buffer[4096];
+       char tmp[4096];
+       va_list argptr;
+
+       va_start( argptr,error );
+       vsprintf( tmp, error, argptr );
+       va_end( argptr );
+
+       sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
+
+       FPrintf( SYS_ERR, out_buffer );
+
+#ifdef DBG_XML
+       DumpXML();
+#endif
+
+       //++timo HACK ALERT .. if we shut down too fast the xml stream won't reach the listener.
+       // a clean solution is to send a sync request node in the stream and wait for an answer before exiting
+       Sys_Sleep( 1000 );
+
+       Broadcast_Shutdown();
+
+       exit( 1 );
+}
diff --git a/tools/heretic2/common/inout.h b/tools/heretic2/common/inout.h
new file mode 100644 (file)
index 0000000..934189f
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __INOUT__
+#define __INOUT__
+
+#include "globaldefs.h"
+// inout is the only stuff relying on xml, include the headers there
+#include "libxml/tree.h"
+#include "mathlib.h"
+
+// some useful xml routines
+xmlNodePtr xml_NodeForVec( vec3_t v );
+void xml_SendNode( xmlNodePtr node );
+// print a message in q3map output and send the corresponding select information down the xml stream
+// bError: do we end with an error on this one or do we go ahead?
+void xml_Select( char *msg, int entitynum, int brushnum, qboolean bError );
+// end q3map with an error message and send a point information in the xml stream
+// note: we might want to add a boolean to use this as a warning or an error thing..
+void xml_Winding( char *msg, vec3_t p[], int numpoints, qboolean die );
+void xml_Point( char *msg, vec3_t pt );
+
+extern qboolean bNetworkBroadcast;
+void Broadcast_Setup( const char *dest );
+void Broadcast_Shutdown();
+
+#define SYS_VRB 0 // verbose support (on/off)
+#define SYS_STD 1 // standard print level
+#define SYS_WRN 2 // warnings
+#define SYS_ERR 3 // error
+#define SYS_NOXML 4 // don't send that down the XML stream
+
+extern qboolean verbose;
+void Sys_Printf( const char *text, ... );
+void Sys_FPrintf( int flag, const char *text, ... );
+void Error( const char *error, ... );
+
+#if GDEF_DEBUG
+#define DBG_XML 1
+#endif
+
+#ifdef DBG_XML
+void DumpXML();
+#endif
+
+#endif
diff --git a/tools/heretic2/common/l3dslib.c b/tools/heretic2/common/l3dslib.c
new file mode 100644 (file)
index 0000000..708577a
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+//
+// l3dslib.c: library for loading triangles from an Alias triangle file
+//
+
+#include <stdio.h>
+#include "cmdlib.h"
+#include "inout.h"
+#include "mathlib.h"
+#include "trilib.h"
+#include "l3dslib.h"
+#include "token.h"
+#include "fmodel.h"
+#include "bspfile.h"
+
+#define MAIN3DS       0x4D4D
+#define EDIT3DS       0x3D3D  // this is the start of the editor config
+#define EDIT_OBJECT   0x4000
+#define OBJ_TRIMESH   0x4100
+#define TRI_VERTEXL   0x4110
+#define TRI_FACEL1    0x4120
+
+#define MAXVERTS    2000
+
+typedef struct {
+       int v[4];
+} tri;
+
+float fverts[MAXVERTS][3];
+tri tris[MAXTRIANGLES];
+
+int bytesread, level, numtris, totaltris;
+int vertsfound, trisfound;
+
+triangle_t  *ptri;
+
+
+
+void DefaultNodesList( mesh_node_t **nodesList, int *num_mesh_nodes, int *numtriangles ){
+       int pos, bit, i;
+
+       if ( nodesList ) {
+               *num_mesh_nodes = 1;
+               memset( &( *nodesList )[0], 0, sizeof( mesh_node_t ) );
+               strcpy( ( *nodesList )[0].name, "default" );
+
+               // set all of the tris to be used for the top node
+               for ( i = 0; i < ( *numtriangles ); i++ )
+               {
+                       pos = ( i ) >> 3;
+                       bit = 1 << ( ( i ) & 7 );
+
+                       ( *nodesList )[0].tris[pos] |= bit;
+               }
+       }
+}
+
+
+// Alias stores triangles as 3 explicit vertices in .tri files, so even though we
+// start out with a vertex pool and vertex indices for triangles, we have to convert
+// to raw, explicit triangles
+void StoreAliasTriangles( void ){
+       int i, j, k;
+
+       if ( ( totaltris + numtris ) > MAXTRIANGLES ) {
+               Error( "Error: Too many triangles" );
+       }
+
+       for ( i = 0; i < numtris ; i++ )
+       {
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       for ( k = 0 ; k < 3 ; k++ )
+                       {
+                               ptri[i + totaltris].verts[j][k] = fverts[tris[i].v[j]][k];
+                       }
+               }
+       }
+
+       totaltris += numtris;
+       numtris = 0;
+       vertsfound = 0;
+       trisfound = 0;
+}
+
+
+int ParseVertexL( FILE *input ){
+       int i, j, startbytesread, numverts;
+       unsigned short tshort;
+
+       if ( vertsfound ) {
+               Error( "Error: Multiple vertex chunks" );
+       }
+
+       vertsfound = 1;
+       startbytesread = bytesread;
+
+       if ( feof( input ) ) {
+               Error( "Error: unexpected end of file" );
+       }
+
+       fread( &tshort, sizeof( tshort ), 1, input );
+       bytesread += sizeof( tshort );
+       numverts = (int)tshort;
+
+       if ( numverts > MAXVERTS ) {
+               Error( "Error: Too many vertices" );
+       }
+
+       for ( i = 0 ; i < numverts ; i++ )
+       {
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       if ( feof( input ) ) {
+                               Error( "Error: unexpected end of file" );
+                       }
+
+                       fread( &fverts[i][j], sizeof( float ), 1, input );
+                       bytesread += sizeof( float );
+               }
+       }
+
+       if ( vertsfound && trisfound ) {
+               StoreAliasTriangles();
+       }
+
+       return bytesread - startbytesread;
+}
+
+
+int ParseFaceL1( FILE *input ){
+
+       int i, j, startbytesread;
+       unsigned short tshort;
+
+       if ( trisfound ) {
+               Error( "Error: Multiple face chunks" );
+       }
+
+       trisfound = 1;
+       startbytesread = bytesread;
+
+       if ( feof( input ) ) {
+               Error( "Error: unexpected end of file" );
+       }
+
+       fread( &tshort, sizeof( tshort ), 1, input );
+       bytesread += sizeof( tshort );
+       numtris = (int)tshort;
+
+       if ( numtris > MAXTRIANGLES ) {
+               Error( "Error: Too many triangles" );
+       }
+
+       for ( i = 0 ; i < numtris ; i++ )
+       {
+               for ( j = 0 ; j < 4 ; j++ )
+               {
+                       if ( feof( input ) ) {
+                               Error( "Error: unexpected end of file" );
+                       }
+
+                       fread( &tshort, sizeof( tshort ), 1, input );
+                       bytesread += sizeof( tshort );
+                       tris[i].v[j] = (int)tshort;
+               }
+       }
+
+       if ( vertsfound && trisfound ) {
+               StoreAliasTriangles();
+       }
+
+       return bytesread - startbytesread;
+}
+
+
+int ParseChunk( FILE *input ){
+#define BLOCK_SIZE  4096
+       char temp[BLOCK_SIZE];
+       unsigned short type;
+       int i, length, w, t, retval;
+
+       level++;
+       retval = 0;
+
+// chunk type
+       if ( feof( input ) ) {
+               Error( "Error: unexpected end of file" );
+       }
+
+       fread( &type, sizeof( type ), 1, input );
+       bytesread += sizeof( type );
+
+// chunk length
+       if ( feof( input ) ) {
+               Error( "Error: unexpected end of file" );
+       }
+
+       fread( &length, sizeof( length ), 1, input );
+       bytesread += sizeof( length );
+       w = length - 6;
+
+// process chunk if we care about it, otherwise skip it
+       switch ( type )
+       {
+       case TRI_VERTEXL:
+               w -= ParseVertexL( input );
+               goto ParseSubchunk;
+
+       case TRI_FACEL1:
+               w -= ParseFaceL1( input );
+               goto ParseSubchunk;
+
+       case EDIT_OBJECT:
+               // read the name
+               i = 0;
+
+               do
+               {
+                       if ( feof( input ) ) {
+                               Error( "Error: unexpected end of file" );
+                       }
+
+                       fread( &temp[i], 1, 1, input );
+                       i++;
+                       w--;
+                       bytesread++;
+               } while ( temp[i - 1] );
+
+       case MAIN3DS:
+       case OBJ_TRIMESH:
+       case EDIT3DS:
+               // parse through subchunks
+ParseSubchunk:
+               while ( w > 0 )
+               {
+                       w -= ParseChunk( input );
+               }
+
+               retval = length;
+               goto Done;
+
+       default:
+               // skip other chunks
+               while ( w > 0 )
+               {
+                       t = w;
+
+                       if ( t > BLOCK_SIZE ) {
+                               t = BLOCK_SIZE;
+                       }
+
+                       if ( feof( input ) ) {
+                               Error( "Error: unexpected end of file" );
+                       }
+
+                       fread( &temp, t, 1, input );
+                       bytesread += t;
+
+                       w -= t;
+               }
+
+               retval = length;
+               goto Done;
+       }
+
+Done:
+       level--;
+       return retval;
+}
+
+
+void Load3DSTriangleList( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **nodesList, int *num_mesh_nodes ){
+       FILE        *input;
+       short int tshort;
+
+       if ( nodesList ) {
+               *num_mesh_nodes = 0;
+               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
+       }
+
+       bytesread = 0;
+       level = 0;
+       numtris = 0;
+       totaltris = 0;
+       vertsfound = 0;
+       trisfound = 0;
+
+       if ( ( input = fopen( filename, "rb" ) ) == 0 ) {
+               fprintf( stderr,"reader: could not open file '%s'\n", filename );
+               exit( 0 );
+       }
+
+       fread( &tshort, sizeof( tshort ), 1, input );
+
+// should only be MAIN3DS, but some files seem to start with EDIT3DS, with
+// no MAIN3DS
+       if ( ( tshort != MAIN3DS ) && ( tshort != EDIT3DS ) ) {
+               fprintf( stderr,"File is not a 3DS file.\n" );
+               exit( 0 );
+       }
+
+// back to top of file so we can parse the first chunk descriptor
+       fseek( input, 0, SEEK_SET );
+
+       ptri = malloc( MAXTRIANGLES * sizeof( triangle_t ) );
+
+       *pptri = ptri;
+
+// parse through looking for the relevant chunk tree (MAIN3DS | EDIT3DS | EDIT_OBJECT |
+// OBJ_TRIMESH | {TRI_VERTEXL, TRI_FACEL1}) and skipping other chunks
+       ParseChunk( input );
+
+       if ( vertsfound || trisfound ) {
+               Error( "Incomplete triangle set" );
+       }
+
+       *numtriangles = totaltris;
+
+       fclose( input );
+
+       DefaultNodesList( nodesList,num_mesh_nodes,numtriangles );
+}
+
+//==========================================================================
+//
+// LoadASC
+//
+//==========================================================================
+
+void LoadASC( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
+       int i, j;
+       int vertexCount;
+       struct
+       {
+               float v[3];
+       }           *vList;
+       int triCount;
+       triangle_t  *tList;
+       float x, y, z;
+//     float           x2, y2, z2;
+//     float           rx, ry, rz;
+       qboolean goodObject;
+
+       if ( nodesList ) {
+               *num_mesh_nodes = 0;
+               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
+       }
+
+       TK_OpenSource( fileName );
+
+       goodObject = false;
+       while ( goodObject == false )
+       {
+               TK_Beyond( TK_C_NAMED );
+               TK_Beyond( TK_OBJECT );
+               TK_Beyond( TK_C_TRI );
+               TK_Beyond( TK_MESH );
+               TK_BeyondRequire( TK_C_VERTICES, TK_COLON );
+               TK_FetchRequire( TK_INTNUMBER );
+               vertexCount = tk_IntNumber;
+               if ( vertexCount > 0 ) {
+                       goodObject = true;
+               }
+       }
+       TK_BeyondRequire( TK_C_FACES, TK_COLON );
+       TK_FetchRequire( TK_INTNUMBER );
+       triCount = tk_IntNumber;
+       if ( triCount >= MAXTRIANGLES ) {
+               Error( "Too many triangles in file %s\n", fileName );
+       }
+       *triangleCount = triCount;
+       tList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
+       *triList = tList;
+
+       memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
+       TK_BeyondRequire( TK_C_VERTEX, TK_LIST );
+
+/*     rx = ((rotation[0]+90.0)/360.0)*2.0*M_PI;
+    //rx = (rotation[0]/360.0)*2.0*M_PI;
+    ry = (rotation[1]/360.0)*2.0*M_PI;
+    rz = (rotation[2]/360.0)*2.0*M_PI;
+ */
+       vList = (void *) SafeMalloc( vertexCount * sizeof vList[0], "Vertex list" );
+       for ( i = 0; i < vertexCount; i++ )
+       {
+               TK_BeyondRequire( TK_C_VERTEX, TK_INTNUMBER );
+               if ( tk_IntNumber != i ) {
+                       Error( "File '%s', line %d:\nVertex index mismatch.\n",
+                                  tk_SourceName, tk_Line );
+               }
+               TK_FetchRequireFetch( TK_COLON );
+
+               TK_BeyondRequire( TK_COLON, TK_FLOATNUMBER );
+               x = tk_FloatNumber;
+               TK_BeyondRequire( TK_COLON, TK_FLOATNUMBER );
+               y = tk_FloatNumber;
+               TK_BeyondRequire( TK_COLON, TK_FLOATNUMBER );
+               z = tk_FloatNumber;
+
+/*             x2 = x*cos(rz)+y*sin(rz);
+        y2 = -x*sin(rz)+y*cos(rz);
+        x = x2;
+        y = y2;
+        y2 = y*cos(rx)+z*sin(rx);
+        z2 = -y*sin(rx)+z*cos(rx);
+        y = y2;
+        z = z2;
+        x2 = x*cos(ry)-z*sin(ry);
+        z2 = x*sin(ry)+z*cos(ry);
+        x = x2;
+        z = z2;
+ */
+               vList[i].v[0] = x;
+               vList[i].v[1] = y;
+               vList[i].v[2] = z;
+       }
+       TK_BeyondRequire( TK_C_FACE, TK_LIST );
+       for ( i = 0; i < triCount; i++ )
+       {
+               TK_BeyondRequire( TK_C_FACE, TK_INTNUMBER );
+               if ( tk_IntNumber != i ) {
+                       Error( "File '%s', line %d:\nTriangle index mismatch.\n",
+                                  tk_SourceName, tk_Line );
+               }
+               for ( j = 0; j < 3; j++ )
+               {
+                       TK_BeyondRequire( TK_IDENTIFIER, TK_COLON );
+                       TK_FetchRequire( TK_INTNUMBER );
+                       if ( tk_IntNumber >= vertexCount ) {
+                               Error( "File '%s', line %d:\nVertex number"
+                                          " > vertexCount: %d\n", tk_SourceName, tk_Line,
+                                          tk_IntNumber );
+                       }
+                       tList[i].verts[2 - j][0] = vList[tk_IntNumber].v[0];
+                       tList[i].verts[2 - j][1] = vList[tk_IntNumber].v[1];
+                       tList[i].verts[2 - j][2] = vList[tk_IntNumber].v[2];
+#ifdef _QDATA
+                       tList[i].indicies[2 - j] = tk_IntNumber;
+#endif
+               }
+
+/*             printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
+            "  v2: %f, %f, %f\n", i,
+            tList[i].verts[0][0],
+            tList[i].verts[0][1],
+            tList[i].verts[0][2],
+            tList[i].verts[1][0],
+            tList[i].verts[1][1],
+            tList[i].verts[1][2],
+            tList[i].verts[2][0],
+            tList[i].verts[2][1],
+            tList[i].verts[2][2]);
+ */
+       }
+
+       DefaultNodesList( nodesList,num_mesh_nodes,triangleCount );
+}
diff --git a/tools/heretic2/common/l3dslib.h b/tools/heretic2/common/l3dslib.h
new file mode 100644 (file)
index 0000000..0b1b537
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+//
+// l3dslib.h: header file for loading triangles from a 3DS triangle file
+//
+void DefaultNodesList( mesh_node_t **nodesList, int *num_mesh_nodes, int *numtriangles );
+
+void Load3DSTriangleList( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **ppmnodes, int *num_mesh_nodes );
+void LoadASC( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **ppmnodes, int *num_mesh_nodes );
diff --git a/tools/heretic2/common/lbmlib.c b/tools/heretic2/common/lbmlib.c
new file mode 100644 (file)
index 0000000..7eabd19
--- /dev/null
@@ -0,0 +1,1043 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// lbmlib.c
+
+#include "cmdlib.h"
+#include "inout.h"
+#include "lbmlib.h"
+
+// Ups the palette values so no pixels except 0 appear transparent
+// Need a value of 8 to cater for 16bit renderers
+
+typedef struct
+{
+       byte r;
+       byte g;
+       byte b;
+} paletteRGB_t;
+
+
+void CorrectPalette( byte *pal ){
+       paletteRGB_t    *p;
+
+       p = (paletteRGB_t *)pal;
+       // Color 0 always transparent
+       p->r = 0;
+       p->g = 0;
+       p->b = 0;
+}
+
+/*
+   ============================================================================
+
+                        LBM STUFF
+
+   ============================================================================
+ */
+
+
+typedef unsigned char UBYTE;
+//conflicts with windows typedef short                 WORD;
+typedef unsigned short UWORD;
+typedef long LONG;
+
+typedef enum
+{
+       ms_none,
+       ms_mask,
+       ms_transcolor,
+       ms_lasso
+} mask_t;
+
+typedef enum
+{
+       cm_none,
+       cm_rle1
+} compress_t;
+
+typedef struct
+{
+       UWORD w,h;
+       short x,y;
+       UBYTE nPlanes;
+       UBYTE masking;
+       UBYTE compression;
+       UBYTE pad1;
+       UWORD transparentColor;
+       UBYTE xAspect,yAspect;
+       short pageWidth,pageHeight;
+} bmhd_t;
+
+extern bmhd_t bmhd;                         // will be in native byte order
+
+
+
+#define FORMID ( 'F' + ( 'O' << 8 ) + ( (int)'R' << 16 ) + ( (int)'M' << 24 ) )
+#define ILBMID ( 'I' + ( 'L' << 8 ) + ( (int)'B' << 16 ) + ( (int)'M' << 24 ) )
+#define PBMID  ( 'P' + ( 'B' << 8 ) + ( (int)'M' << 16 ) + ( (int)' ' << 24 ) )
+#define BMHDID ( 'B' + ( 'M' << 8 ) + ( (int)'H' << 16 ) + ( (int)'D' << 24 ) )
+#define BODYID ( 'B' + ( 'O' << 8 ) + ( (int)'D' << 16 ) + ( (int)'Y' << 24 ) )
+#define CMAPID ( 'C' + ( 'M' << 8 ) + ( (int)'A' << 16 ) + ( (int)'P' << 24 ) )
+
+
+bmhd_t bmhd;
+
+int    Align( int l ){
+       if ( l & 1 ) {
+               return l + 1;
+       }
+       return l;
+}
+
+
+
+/*
+   ================
+   LBMRLEdecompress
+
+   Source must be evenly aligned!
+   ================
+ */
+byte  *LBMRLEDecompress( byte *source,byte *unpacked, int bpwidth ){
+       int count;
+       byte b,rept;
+
+       count = 0;
+
+       do
+       {
+               rept = *source++;
+
+               if ( rept > 0x80 ) {
+                       rept = ( rept ^ 0xff ) + 2;
+                       b = *source++;
+                       memset( unpacked,b,rept );
+                       unpacked += rept;
+               }
+               else if ( rept < 0x80 ) {
+                       rept++;
+                       memcpy( unpacked,source,rept );
+                       unpacked += rept;
+                       source += rept;
+               }
+               else{
+                       rept = 0;               // rept of 0x80 is NOP
+
+               }
+               count += rept;
+
+       } while ( count < bpwidth );
+
+       if ( count > bpwidth ) {
+               Error( "Decompression exceeded width!\n" );
+       }
+
+
+       return source;
+}
+
+
+/*
+   =================
+   LoadLBM
+   =================
+ */
+void LoadLBM( char *filename, byte **picture, byte **palette ){
+       byte    *LBMbuffer, *picbuffer, *cmapbuffer;
+       int y;
+       byte    *LBM_P, *LBMEND_P;
+       byte    *pic_p;
+       byte    *body_p;
+
+       int formtype,formlength;
+       int chunktype,chunklength;
+
+// qiet compiler warnings
+       picbuffer = NULL;
+       cmapbuffer = NULL;
+
+//
+// load the LBM
+//
+       LoadFile( filename, (void **)&LBMbuffer );
+
+//
+// parse the LBM header
+//
+       LBM_P = LBMbuffer;
+       if ( *(int *)LBMbuffer != LittleLong( FORMID ) ) {
+               Error( "No FORM ID at start of file!\n" );
+       }
+
+       LBM_P += 4;
+       formlength = BigLong( *(int *)LBM_P );
+       LBM_P += 4;
+       LBMEND_P = LBM_P + Align( formlength );
+
+       formtype = LittleLong( *(int *)LBM_P );
+
+       if ( formtype != ILBMID && formtype != PBMID ) {
+               Error( "Unrecognized form type: %c%c%c%c\n", formtype & 0xff
+                          ,( formtype >> 8 ) & 0xff,( formtype >> 16 ) & 0xff,( formtype >> 24 ) & 0xff );
+       }
+
+       LBM_P += 4;
+
+//
+// parse chunks
+//
+
+       while ( LBM_P < LBMEND_P )
+       {
+               chunktype = LBM_P[0] + ( LBM_P[1] << 8 ) + ( LBM_P[2] << 16 ) + ( LBM_P[3] << 24 );
+               LBM_P += 4;
+               chunklength = LBM_P[3] + ( LBM_P[2] << 8 ) + ( LBM_P[1] << 16 ) + ( LBM_P[0] << 24 );
+               LBM_P += 4;
+
+               switch ( chunktype )
+               {
+               case BMHDID:
+                       memcpy( &bmhd,LBM_P,sizeof( bmhd ) );
+                       bmhd.w = BigShort( bmhd.w );
+                       bmhd.h = BigShort( bmhd.h );
+                       bmhd.x = BigShort( bmhd.x );
+                       bmhd.y = BigShort( bmhd.y );
+                       bmhd.pageWidth = BigShort( bmhd.pageWidth );
+                       bmhd.pageHeight = BigShort( bmhd.pageHeight );
+                       break;
+
+               case CMAPID:
+                       cmapbuffer = malloc( 768 );
+                       memset( cmapbuffer, 0, 768 );
+                       memcpy( cmapbuffer, LBM_P, chunklength );
+                       CorrectPalette( cmapbuffer );
+                       break;
+
+               case BODYID:
+                       body_p = LBM_P;
+
+                       pic_p = picbuffer = malloc( bmhd.w * bmhd.h );
+                       if ( formtype == PBMID ) {
+                               //
+                               // unpack PBM
+                               //
+                               for ( y = 0 ; y < bmhd.h ; y++, pic_p += bmhd.w )
+                               {
+                                       if ( bmhd.compression == cm_rle1 ) {
+                                               body_p = LBMRLEDecompress( (byte *)body_p
+                                                                                                  , pic_p, bmhd.w );
+                                       }
+                                       else if ( bmhd.compression == cm_none ) {
+                                               memcpy( pic_p,body_p,bmhd.w );
+                                               body_p += Align( bmhd.w );
+                                       }
+                               }
+
+                       }
+                       else
+                       {
+                               //
+                               // unpack ILBM
+                               //
+                               Error( "%s is an interlaced LBM, not packed", filename );
+                       }
+                       break;
+               }
+
+               LBM_P += Align( chunklength );
+       }
+
+       free( LBMbuffer );
+
+       *picture = picbuffer;
+
+       if ( palette ) {
+               *palette = cmapbuffer;
+       }
+}
+
+
+/*
+   ============================================================================
+
+                            WRITE LBM
+
+   ============================================================================
+ */
+
+/*
+   ==============
+   WriteLBMfile
+   ==============
+ */
+void WriteLBMfile( char *filename, byte *data,
+                                  int width, int height, byte *palette ){
+       byte    *lbm, *lbmptr;
+       int    *formlength, *bmhdlength, *cmaplength, *bodylength;
+       int length;
+       bmhd_t basebmhd;
+
+       lbm = lbmptr = malloc( width * height + 1000 );
+
+//
+// start FORM
+//
+       *lbmptr++ = 'F';
+       *lbmptr++ = 'O';
+       *lbmptr++ = 'R';
+       *lbmptr++ = 'M';
+
+       formlength = (int*)lbmptr;
+       lbmptr += 4;                      // leave space for length
+
+       *lbmptr++ = 'P';
+       *lbmptr++ = 'B';
+       *lbmptr++ = 'M';
+       *lbmptr++ = ' ';
+
+//
+// write BMHD
+//
+       *lbmptr++ = 'B';
+       *lbmptr++ = 'M';
+       *lbmptr++ = 'H';
+       *lbmptr++ = 'D';
+
+       bmhdlength = (int *)lbmptr;
+       lbmptr += 4;                      // leave space for length
+
+       memset( &basebmhd,0,sizeof( basebmhd ) );
+       basebmhd.w = BigShort( (short)width );
+       basebmhd.h = BigShort( (short)height );
+       basebmhd.nPlanes = BigShort( 8 );
+       basebmhd.xAspect = BigShort( 5 );
+       basebmhd.yAspect = BigShort( 6 );
+       basebmhd.pageWidth = BigShort( (short)width );
+       basebmhd.pageHeight = BigShort( (short)height );
+
+       memcpy( lbmptr,&basebmhd,sizeof( basebmhd ) );
+       lbmptr += sizeof( basebmhd );
+
+       length = lbmptr - (byte *)bmhdlength - 4;
+       *bmhdlength = BigLong( length );
+       if ( length & 1 ) {
+               *lbmptr++ = 0;          // pad chunk to even offset
+
+       }
+//
+// write CMAP
+//
+       *lbmptr++ = 'C';
+       *lbmptr++ = 'M';
+       *lbmptr++ = 'A';
+       *lbmptr++ = 'P';
+
+       cmaplength = (int *)lbmptr;
+       lbmptr += 4;                      // leave space for length
+
+       memcpy( lbmptr,palette,768 );
+       lbmptr += 768;
+
+       length = lbmptr - (byte *)cmaplength - 4;
+       *cmaplength = BigLong( length );
+       if ( length & 1 ) {
+               *lbmptr++ = 0;          // pad chunk to even offset
+
+       }
+//
+// write BODY
+//
+       *lbmptr++ = 'B';
+       *lbmptr++ = 'O';
+       *lbmptr++ = 'D';
+       *lbmptr++ = 'Y';
+
+       bodylength = (int *)lbmptr;
+       lbmptr += 4;                      // leave space for length
+
+       memcpy( lbmptr,data,width * height );
+       lbmptr += width * height;
+
+       length = lbmptr - (byte *)bodylength - 4;
+       *bodylength = BigLong( length );
+       if ( length & 1 ) {
+               *lbmptr++ = 0;          // pad chunk to even offset
+
+       }
+//
+// done
+//
+       length = lbmptr - (byte *)formlength - 4;
+       *formlength = BigLong( length );
+       if ( length & 1 ) {
+               *lbmptr++ = 0;          // pad chunk to even offset
+
+       }
+//
+// write output file
+//
+       SaveFile( filename, lbm, lbmptr - lbm );
+       free( lbm );
+}
+
+
+/*
+   ============================================================================
+
+   LOAD PCX
+
+   ============================================================================
+ */
+
+typedef struct
+{
+       char manufacturer;
+       char version;
+       char encoding;
+       char bits_per_pixel;
+       unsigned short xmin,ymin,xmax,ymax;
+       unsigned short hres,vres;
+       unsigned char palette[48];
+       char reserved;
+       char color_planes;
+       unsigned short bytes_per_line;
+       unsigned short palette_type;
+       char filler[58];
+       unsigned char data;             // unbounded
+} pcx_t;
+
+/*
+   ==============
+   LoadPCX
+   ==============
+ */
+void LoadPCX( char *filename, byte **pic, byte **palette, int *width, int *height ){
+       byte    *raw;
+       pcx_t   *pcx;
+       int x, y;
+       int len;
+       int dataByte, runLength;
+       byte    *out, *pix;
+
+       //
+       // load the file
+       //
+       len = LoadFile( filename, (void **)&raw );
+
+       //
+       // parse the PCX file
+       //
+       pcx = (pcx_t *)raw;
+       raw = &pcx->data;
+
+       pcx->xmin = LittleShort( pcx->xmin );
+       pcx->ymin = LittleShort( pcx->ymin );
+       pcx->xmax = LittleShort( pcx->xmax );
+       pcx->ymax = LittleShort( pcx->ymax );
+       pcx->hres = LittleShort( pcx->hres );
+       pcx->vres = LittleShort( pcx->vres );
+       pcx->bytes_per_line = LittleShort( pcx->bytes_per_line );
+       pcx->palette_type = LittleShort( pcx->palette_type );
+
+       if ( pcx->manufacturer != 0x0a
+                || pcx->version != 5
+                || pcx->encoding != 1
+                || pcx->bits_per_pixel != 8
+                || pcx->xmax >= 640
+                || pcx->ymax >= 480 ) {
+               Error( "Bad pcx file %s", filename );
+       }
+
+       if ( palette ) {
+               *palette = malloc( 768 );
+               memcpy( *palette, (byte *)pcx + len - 768, 768 );
+               CorrectPalette( *palette );
+       }
+
+       if ( width ) {
+               *width = pcx->xmax + 1;
+       }
+       if ( height ) {
+               *height = pcx->ymax + 1;
+       }
+
+       if ( !pic ) {
+               return;
+       }
+
+       out = malloc( ( pcx->ymax + 1 ) * ( pcx->xmax + 1 ) );
+       if ( !out ) {
+               Error( "Skin_Cache: couldn't allocate" );
+       }
+
+       *pic = out;
+
+       pix = out;
+
+       for ( y = 0 ; y <= pcx->ymax ; y++, pix += pcx->xmax + 1 )
+       {
+               for ( x = 0 ; x <= pcx->xmax ; )
+               {
+                       dataByte = *raw++;
+
+                       if ( ( dataByte & 0xC0 ) == 0xC0 ) {
+                               runLength = dataByte & 0x3F;
+                               dataByte = *raw++;
+                       }
+                       else{
+                               runLength = 1;
+                       }
+
+                       while ( runLength-- > 0 )
+                               pix[x++] = dataByte;
+               }
+
+       }
+
+       if ( raw - (byte *)pcx > len ) {
+               Error( "PCX file %s was malformed", filename );
+       }
+
+       free( pcx );
+}
+
+/*
+   ==============
+   WritePCXfile
+   ==============
+ */
+
+void StuffPackedByte( int curRepCount, byte curByte, byte** packPtr ){
+       byte* pack;
+
+       pack = *packPtr;
+
+       while ( curRepCount > 0 )
+       {
+               if ( curRepCount == 1 ) {
+                       if ( ( curByte & 0xc0 ) != 0xc0 ) {
+                               *pack++ = curByte;
+                       }
+                       else
+                       {
+                               *pack++ = 0xc1;
+                               *pack++ = curByte;
+                       }
+                       break;
+               }
+               if ( curRepCount < 0x0040 ) {
+                       *pack++ = ( 0x00c0 | curRepCount );
+                       curRepCount = 0;
+               }
+               else
+               {
+                       *pack++ = 0xff;
+                       curRepCount -= 0x003f;
+               }
+               *pack++ = curByte;
+       }
+       *packPtr = pack;
+}
+
+void WritePCXfile( char *filename, byte *data,
+                                  int width, int height, byte *palette ){
+       int i, j, length;
+       pcx_t       *pcx;
+       byte        *pack;
+       byte curByte;
+       int curRepCount;
+
+       pcx = malloc( width * height * 2 + 1000 );
+       memset( pcx, 0, sizeof( *pcx ) );
+
+       pcx->manufacturer = 0x0a;   // PCX id
+       pcx->version = 5;           // 256 color
+       pcx->encoding = 1;      // RLE
+       pcx->bits_per_pixel = 8;        // 256 color
+       pcx->xmin = 0;
+       pcx->ymin = 0;
+       pcx->xmax = LittleShort( (short)( width - 1 ) );
+       pcx->ymax = LittleShort( (short)( height - 1 ) );
+       pcx->hres = LittleShort( (short)width );
+       pcx->vres = LittleShort( (short)height );
+       pcx->color_planes = 1;      // chunky image
+       pcx->bytes_per_line = LittleShort( (short)width );
+       pcx->palette_type = LittleShort( 1 );     // not a grey scale
+
+       // pack the image
+       pack = &pcx->data;
+
+/*     for (i=0 ; i<height ; i++)
+    {
+        for (j=0 ; j<width ; j++)
+        {
+            if ( (*data & 0xc0) != 0xc0)
+   *pack++ = *data++;
+            else
+            {
+   *pack++ = 0xc1;
+   *pack++ = *data++;
+            }
+        }
+    }
+ */
+       for ( i = 0 ; i < height ; i++ )
+       {
+               curByte = *data;
+               curRepCount = 0;
+               for ( j = 0 ; j < width ; j++ )
+               {
+                       if ( *data == curByte ) {
+                               curRepCount++;
+                               data++;
+                               continue;
+                       }
+                       StuffPackedByte( curRepCount, curByte, &pack );
+                       curByte = *data++;
+                       curRepCount = 1;
+               }
+               StuffPackedByte( curRepCount, curByte, &pack );
+       }
+       // write the palette
+       *pack++ = 0x0c; // palette ID byte
+       for ( i = 0 ; i < 768 ; i++ )
+               *pack++ = *palette++;
+
+// write output file
+       length = pack - (byte *)pcx;
+       SaveFile( filename, pcx, length );
+
+       free( pcx );
+}
+
+
+/*
+   ============================================================================
+
+   LOAD IMAGE
+
+   ============================================================================
+ */
+
+/*
+   ==============
+   Load256Image
+
+   Will load either an lbm or pcx, depending on extension.
+   Any of the return pointers can be NULL if you don't want them.
+   ==============
+ */
+void Load256Image( char *name, byte **pixels, byte **palette,
+                                  int *width, int *height ){
+       char ext[128];
+
+       ExtractFileExtension( name, ext );
+       if ( !Q_strcasecmp( ext, "lbm" ) ) {
+               LoadLBM( name, pixels, palette );
+               if ( width ) {
+                       *width = bmhd.w;
+               }
+               if ( height ) {
+                       *height = bmhd.h;
+               }
+       }
+       else if ( !Q_strcasecmp( ext, "pcx" ) ) {
+               LoadPCX( name, pixels, palette, width, height );
+       }
+       else{
+               Error( "%s doesn't have a known image extension", name );
+       }
+}
+
+
+/*
+   ==============
+   Save256Image
+
+   Will save either an lbm or pcx, depending on extension.
+   ==============
+ */
+void Save256Image( char *name, byte *pixels, byte *palette,
+                                  int width, int height ){
+       char ext[128];
+
+       ExtractFileExtension( name, ext );
+       if ( !Q_strcasecmp( ext, "lbm" ) ) {
+               WriteLBMfile( name, pixels, width, height, palette );
+       }
+       else if ( !Q_strcasecmp( ext, "pcx" ) ) {
+               WritePCXfile( name, pixels, width, height, palette );
+       }
+       else{
+               Error( "%s doesn't have a known image extension", name );
+       }
+}
+
+
+
+
+/*
+   ============================================================================
+
+   TARGA IMAGE
+
+   ============================================================================
+ */
+
+typedef struct _TargaHeader
+{
+       unsigned char id_length, colormap_type, image_type;
+       unsigned short colormap_index, colormap_length;
+       unsigned char colormap_size;
+       unsigned short x_origin, y_origin, width, height;
+       unsigned char pixel_size, attributes;
+} TargaHeader;
+
+int fgetLittleShort( FILE *f ){
+       byte b1, b2;
+
+       b1 = fgetc( f );
+       b2 = fgetc( f );
+
+       return( (short)( b1 + ( b2 << 8 ) ) );
+}
+
+int fgetLittleLong( FILE *f ){
+       byte b1, b2, b3, b4;
+
+       b1 = fgetc( f );
+       b2 = fgetc( f );
+       b3 = fgetc( f );
+       b4 = fgetc( f );
+
+       return( b1 + ( b2 << 8 ) + ( b3 << 16 ) + ( b4 << 24 ) );
+}
+
+
+/*
+   =============
+   LoadTGA
+   =============
+ */
+void LoadTGA( char *name, byte **pixels, int *width, int *height ){
+       int columns, rows, numPixels;
+       byte            *pixbuf;
+       byte            *rowBuf;
+       int row, column;
+       FILE            *fin;
+       byte            *targa_rgba;
+       TargaHeader targa_header;
+       unsigned char red, green, blue, alphabyte;
+       unsigned char packetHeader, packetSize, j;
+       int flip;
+       int mirror;
+       int rowOffset;
+       int pixDirection;
+
+       fin = fopen( name, "rb" );
+       if ( !fin ) {
+               Error( "Couldn't read %s", name );
+       }
+
+       targa_header.id_length = fgetc( fin );
+       targa_header.colormap_type = fgetc( fin );
+       targa_header.image_type = fgetc( fin );
+
+       targa_header.colormap_index = fgetLittleShort( fin );
+       targa_header.colormap_length = fgetLittleShort( fin );
+       targa_header.colormap_size = fgetc( fin );
+       targa_header.x_origin = fgetLittleShort( fin );
+       targa_header.y_origin = fgetLittleShort( fin );
+       targa_header.width = fgetLittleShort( fin );
+       targa_header.height = fgetLittleShort( fin );
+       targa_header.pixel_size = fgetc( fin );
+       targa_header.attributes = fgetc( fin );
+       flip = ( targa_header.attributes & 0x020 ) == 0;
+       mirror = ( targa_header.attributes & 0x010 ) != 0;
+
+       if ( ( targa_header.image_type != 2 ) && ( targa_header.image_type != 10 ) ) {
+               Error( "LoadTGA: Only type 2 and 10 targa RGB images supported\n" );
+       }
+
+       if ( targa_header.colormap_type || ( ( targa_header.pixel_size != 32 ) && ( targa_header.pixel_size != 24 ) ) ) {
+               Error( "Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n" );
+       }
+
+       columns = targa_header.width;
+       rows = targa_header.height;
+       numPixels = columns * rows;
+
+       if ( width ) {
+               *width = columns;
+       }
+       if ( height ) {
+               *height = rows;
+       }
+
+       if ( !pixels ) {
+               return;
+       }
+
+       targa_rgba = malloc( numPixels * 4 );
+       *pixels = targa_rgba;
+
+       if ( flip ) {
+               pixbuf = targa_rgba + ( ( rows - 1 ) * columns * 4 );
+               rowOffset = -columns * 4;
+       }
+       else
+       {
+               pixbuf = targa_rgba;
+               rowOffset = columns * 4;
+       }
+       if ( mirror ) {
+               pixDirection = -4;
+               pixbuf += ( ( columns - 1 ) * 4 );
+       }
+       else
+       {
+               pixDirection = 4;
+       }
+
+       if ( targa_header.id_length ) {
+               fseek( fin, targa_header.id_length, SEEK_CUR );  // skip TARGA image comment
+
+       }
+       if ( targa_header.image_type == 2 ) {                 // Uncompressed, RGB images
+               for ( row = 0; row < rows; row++ )
+               {
+                       rowBuf = pixbuf;
+                       for ( column = 0; column < columns; column++ )
+                       {
+                               switch ( targa_header.pixel_size )
+                               {
+                               case 24:
+                                       blue = getc( fin );
+                                       green = getc( fin );
+                                       red = getc( fin );
+                                       rowBuf[0] = red;
+                                       rowBuf[1] = green;
+                                       rowBuf[2] = blue;
+                                       rowBuf[3] = 255;
+                                       rowBuf += pixDirection;
+                                       break;
+                               case 32:
+                                       blue = getc( fin );
+                                       green = getc( fin );
+                                       red = getc( fin );
+                                       alphabyte = getc( fin );
+                                       rowBuf[0] = red;
+                                       rowBuf[1] = green;
+                                       rowBuf[2] = blue;
+                                       rowBuf[3] = alphabyte;
+                                       rowBuf += pixDirection;
+                                       break;
+                               }
+                       }
+                       pixbuf += rowOffset;
+               }
+       }
+       else if ( targa_header.image_type == 10 ) {        // Runlength encoded RGB images
+               for ( row = 0; row < rows; row++ )
+               {
+                       rowBuf = pixbuf;
+                       for ( column = 0; column < columns; )
+                       {
+                               packetHeader = getc( fin );
+                               packetSize = 1 + ( packetHeader & 0x7f );
+                               if ( packetHeader & 0x80 ) {          // run-length packet
+                                       switch ( targa_header.pixel_size )
+                                       {
+                                       case 24:
+                                               blue = getc( fin );
+                                               green = getc( fin );
+                                               red = getc( fin );
+                                               alphabyte = 255;
+                                               break;
+                                       case 32:
+                                               blue = getc( fin );
+                                               green = getc( fin );
+                                               red = getc( fin );
+                                               alphabyte = getc( fin );
+                                               break;
+                                       }
+
+                                       for ( j = 0; j < packetSize; j++ )
+                                       {
+                                               rowBuf[0] = red;
+                                               rowBuf[1] = green;
+                                               rowBuf[2] = blue;
+                                               rowBuf[3] = alphabyte;
+                                               rowBuf += pixDirection;
+                                               column++;
+                                               if ( column == columns ) {             // run spans across rows
+                                                       column = 0;
+                                                       row++;
+                                                       if ( row >= rows ) {
+                                                               goto breakOut;
+                                                       }
+                                                       pixbuf += rowOffset;
+                                                       rowBuf = pixbuf;
+                                               }
+                                       }
+                               }
+                               else
+                               {                                       // non run-length packet
+                                       for ( j = 0; j < packetSize; j++ )
+                                       {
+                                               switch ( targa_header.pixel_size )
+                                               {
+                                               case 24:
+                                                       blue = getc( fin );
+                                                       green = getc( fin );
+                                                       red = getc( fin );
+                                                       rowBuf[0] = red;
+                                                       rowBuf[1] = green;
+                                                       rowBuf[2] = blue;
+                                                       rowBuf[3] = 255;
+                                                       rowBuf += pixDirection;
+                                                       break;
+                                               case 32:
+                                                       blue = getc( fin );
+                                                       green = getc( fin );
+                                                       red = getc( fin );
+                                                       alphabyte = getc( fin );
+                                                       rowBuf[0] = red;
+                                                       rowBuf[1] = green;
+                                                       rowBuf[2] = blue;
+                                                       rowBuf[3] = alphabyte;
+                                                       rowBuf += pixDirection;
+                                                       break;
+                                               }
+                                               column++;
+                                               if ( column == columns ) {    // pixel packet run spans across rows
+                                                       column = 0;
+                                                       row++;
+                                                       if ( row >= rows ) {
+                                                               goto breakOut;
+                                                       }
+                                                       pixbuf += rowOffset;
+                                                       rowBuf = pixbuf;
+                                               }
+                                       }
+                               }
+                       }
+breakOut:;
+                       pixbuf += rowOffset;
+               }
+       }
+       fclose( fin );
+}
+
+void MergeAlpha( byte *pix, byte *alpha, byte *pal, byte **out, int width, int height ){
+       int size, i;
+       byte    *data, *src, *srca;
+
+       size = width * height;
+       data = malloc( size * 4 );
+       if ( !data ) {
+               Error( "Could not allocate memory for true color image" );
+       }
+
+       *out = data;
+       src = pix;
+       srca = alpha;
+
+       for ( i = 0; i < size; i++, src++, srca++ )
+       {
+               *data++ = pal[*src * 3 + 0];      // r
+               *data++ = pal[*src * 3 + 1];      // g
+               *data++ = pal[*src * 3 + 2];      // b
+               *data++ = *srca;                  // a
+       }
+       free( pix );
+       free( alpha );
+       free( pal );
+}
+
+/*
+   ==============
+   LoadAnyImage
+
+   Return Value:
+    false: paletted texture
+    true:  true color RGBA image (no palette)
+   ==============
+ */
+qboolean LoadAnyImage( char *name, byte **pixels, byte **palette, int *width, int *height ){
+       char ext[128];
+       int len;
+       int alpha_width, alpha_height;
+       char alpha_name[128];
+       byte    *alpha_pixels;
+
+       ExtractFileExtension( name, ext );
+
+       if ( palette ) {
+               *palette = NULL;
+       }
+
+       if ( !Q_strcasecmp( ext, "lbm" ) ) {
+               LoadLBM( name, pixels, palette );
+               if ( width ) {
+                       *width = bmhd.w;
+               }
+               if ( height ) {
+                       *height = bmhd.h;
+               }
+               return false;
+       }
+       else if ( !Q_strcasecmp( ext, "pcx" ) ) {
+               len = strlen( name );
+               strcpy( alpha_name, name );
+               strcpy( &alpha_name[len - 4], "_a.pcx" );                 // Alpha map name (may not exist)
+
+               if ( FileExists( alpha_name ) ) {
+                       LoadPCX( name, pixels, palette, width, height );                         // Load in image
+                       LoadPCX( alpha_name, &alpha_pixels, NULL, &alpha_width, &alpha_height ); // Load in alpha map
+                       if ( ( *width != alpha_width ) || ( *height != alpha_height ) ) {
+                               Error( "Alpha image dimensions not equal to graphic image dimensions" );
+                       }
+                       MergeAlpha( *pixels, alpha_pixels, *palette, pixels, *width, *height );
+                       *palette = NULL; //Merge Frees pal
+                       return true;
+               }
+               else
+               {
+                       LoadPCX( name, pixels, palette, width, height );         // Load in image
+                       return false;
+               }
+       }
+       else if ( !Q_strcasecmp( ext, "tga" ) ) {
+               LoadTGA( name, pixels, width, height );
+               if ( palette ) {
+                       *palette = NULL;
+               }
+
+               return true;
+       }
+       else{
+               Error( "%s doesn't have a known image extension", name );
+       }
+
+       return false;
+}
diff --git a/tools/heretic2/common/lbmlib.h b/tools/heretic2/common/lbmlib.h
new file mode 100644 (file)
index 0000000..5ee2909
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// piclib.h
+
+
+void LoadLBM( char *filename, byte **picture, byte **palette );
+void WriteLBMfile( char *filename, byte *data, int width, int height
+                                  , byte *palette );
+void LoadPCX( char *filename, byte **picture, byte **palette, int *width, int *height );
+void WritePCXfile( char *filename, byte *data, int width, int height
+                                  , byte *palette );
+
+// loads / saves either lbm or pcx, depending on extension
+void Load256Image( char *name, byte **pixels, byte **palette,
+                                  int *width, int *height );
+void Save256Image( char *name, byte *pixels, byte *palette,
+                                  int width, int height );
+
+
+void LoadTGA( char *filename, byte **pixels, int *width, int *height );
+
+qboolean LoadAnyImage( char *name, byte **pixels, byte **palette, int *width, int *height );
diff --git a/tools/heretic2/common/mathlib.c b/tools/heretic2/common/mathlib.c
new file mode 100644 (file)
index 0000000..8243d86
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// mathlib.c -- math primitives
+
+#include "cmdlib.h"
+#include "mathlib.h"
+
+vec3_t vec3_origin = {0,0,0};
+
+
+double VectorLength( vec3_t v ){
+       int i;
+       double length;
+
+       length = 0;
+       for ( i = 0 ; i < 3 ; i++ )
+               length += v[i] * v[i];
+       length = sqrt( length );     // FIXME
+
+       return length;
+}
+
+qboolean VectorCompare( vec3_t v1, vec3_t v2 ){
+       int i;
+
+       for ( i = 0 ; i < 3 ; i++ )
+               if ( fabs( v1[i] - v2[i] ) > EQUAL_EPSILON ) {
+                       return false;
+               }
+
+       return true;
+}
+
+vec_t Q_rint( vec_t in ){
+       return floor( in + 0.5 );
+}
+
+void VectorMA( vec3_t va, double scale, vec3_t vb, vec3_t vc ){
+       vc[0] = va[0] + scale * vb[0];
+       vc[1] = va[1] + scale * vb[1];
+       vc[2] = va[2] + scale * vb[2];
+}
+
+void CrossProduct( vec3_t v1, vec3_t v2, vec3_t cross ){
+       cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
+       cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
+       cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
+}
+
+vec_t _DotProduct( vec3_t v1, vec3_t v2 ){
+       return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
+}
+
+void _VectorSubtract( vec3_t va, vec3_t vb, vec3_t out ){
+       out[0] = va[0] - vb[0];
+       out[1] = va[1] - vb[1];
+       out[2] = va[2] - vb[2];
+}
+
+void _VectorAdd( vec3_t va, vec3_t vb, vec3_t out ){
+       out[0] = va[0] + vb[0];
+       out[1] = va[1] + vb[1];
+       out[2] = va[2] + vb[2];
+}
+
+void _VectorCopy( vec3_t in, vec3_t out ){
+       out[0] = in[0];
+       out[1] = in[1];
+       out[2] = in[2];
+}
+
+void _VectorScale( vec3_t v, vec_t scale, vec3_t out ){
+       out[0] = v[0] * scale;
+       out[1] = v[1] * scale;
+       out[2] = v[2] * scale;
+}
+
+#if GDEF_COMPILER_MSVC
+#pragma optimize("g", off)  // went back to turning optimization off,
+                            // the bug_fix thing stopped working
+#endif
+
+vec_t VectorNormalize( vec3_t in, vec3_t out ){
+       vec_t length, ilength;
+
+       length = sqrt( in[0] * in[0] + in[1] * in[1] + in[2] * in[2] );
+       if ( length == 0 ) {
+               VectorClear( out );
+               return 0;
+       }
+
+       ilength = 1.0 / length;
+       out[0] = in[0] * ilength;
+       out[1] = in[1] * ilength;
+       out[2] = in[2] * ilength;
+
+       return length;
+}
+
+vec_t ColorNormalize( vec3_t in, vec3_t out ){
+       float max, scale;
+
+       max = in[0];
+       if ( in[1] > max ) {
+               max = in[1];
+       }
+       if ( in[2] > max ) {
+               max = in[2];
+       }
+
+       if ( max == 0 ) {
+               return 0;
+       }
+
+       scale = 1.0 / max;
+
+       VectorScale( in, scale, out );
+
+       return max;
+}
+
+#if GDEF_COMPILER_MSVC
+#pragma optimize("", on)
+#endif
+
+void VectorInverse( vec3_t v ){
+       v[0] = -v[0];
+       v[1] = -v[1];
+       v[2] = -v[2];
+}
+
+void ClearBounds( vec3_t mins, vec3_t maxs ){
+       mins[0] = mins[1] = mins[2] = 99999;
+       maxs[0] = maxs[1] = maxs[2] = -99999;
+}
+
+void AddPointToBounds( vec3_t v, vec3_t mins, vec3_t maxs ){
+       int i;
+       vec_t val;
+
+       for ( i = 0 ; i < 3 ; i++ )
+       {
+               val = v[i];
+               if ( val < mins[i] ) {
+                       mins[i] = val;
+               }
+               if ( val > maxs[i] ) {
+                       maxs[i] = val;
+               }
+       }
+}
diff --git a/tools/heretic2/common/mathlib.h b/tools/heretic2/common/mathlib.h
new file mode 100644 (file)
index 0000000..cd989ea
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __MATHLIB__
+#define __MATHLIB__
+
+// mathlib.h
+
+#include <math.h>
+/*
+   #ifdef DOUBLEVEC_T
+   typedef double vec_t;
+   #else
+   typedef float vec_t;
+   #endif
+   typedef vec_t vec3_t[3];
+ */
+#define SIDE_FRONT      0
+#define SIDE_ON         2
+#define SIDE_BACK       1
+#define SIDE_CROSS      -2
+
+#define Q_PI    3.14159265358979323846
+
+extern vec3_t vec3_origin;
+
+#define EQUAL_EPSILON   0.001
+
+qboolean VectorCompare( vec3_t v1, vec3_t v2 );
+
+#define DotProduct( x,y ) ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] )
+#define VectorSubtract( a,b,c ) {c[0] = a[0] - b[0]; c[1] = a[1] - b[1]; c[2] = a[2] - b[2]; }
+#define VectorAdd( a,b,c ) {c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; }
+#define VectorCopy( a,b ) {b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
+#define VectorScale( a,b,c ) {c[0] = b * a[0]; c[1] = b * a[1]; c[2] = b * a[2]; }
+#define VectorClear( x ) {x[0] = x[1] = x[2] = 0; }
+#define VectorNegate( x ) {x[0] = -x[0]; x[1] = -x[1]; x[2] = -x[2]; }
+
+vec_t Q_rint( vec_t in );
+vec_t _DotProduct( vec3_t v1, vec3_t v2 );
+void _VectorSubtract( vec3_t va, vec3_t vb, vec3_t out );
+void _VectorAdd( vec3_t va, vec3_t vb, vec3_t out );
+void _VectorCopy( vec3_t in, vec3_t out );
+void _VectorScale( vec3_t v, vec_t scale, vec3_t out );
+
+double VectorLength( vec3_t v );
+
+void VectorMA( vec3_t va, double scale, vec3_t vb, vec3_t vc );
+
+void CrossProduct( vec3_t v1, vec3_t v2, vec3_t cross );
+vec_t VectorNormalize( vec3_t in, vec3_t out );
+vec_t ColorNormalize( vec3_t in, vec3_t out );
+void VectorInverse( vec3_t v );
+
+void ClearBounds( vec3_t mins, vec3_t maxs );
+void AddPointToBounds( vec3_t v, vec3_t mins, vec3_t maxs );
+
+#endif
diff --git a/tools/heretic2/common/md4.c b/tools/heretic2/common/md4.c
new file mode 100644 (file)
index 0000000..f503422
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+    mdfour.c
+
+    An implementation of MD4 designed for use in the samba SMB
+    authentication protocol
+
+    Copyright (C) 1997-1998  Andrew Tridgell
+
+    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:
+
+        Free Software Foundation, Inc.
+        59 Temple Place - Suite 330
+        Boston, MA  02111-1307, USA
+
+    $Id: mdfour.c 7689 2007-11-12 14:28:40Z divverent $
+ */
+
+#include <string.h>     /* XoXus: needed for memset call */
+#include "md4.h"
+
+/* NOTE: This code makes no attempt to be fast!
+
+   It assumes that a int is at least 32 bits long
+ */
+
+static struct mdfour *m;
+
+#define F( X,Y,Z ) ( ( (X)&( Y ) ) | ( ( ~( X ) ) & ( Z ) ) )
+#define G( X,Y,Z ) ( ( (X)&( Y ) ) | ( (X)&( Z ) ) | ( (Y)&( Z ) ) )
+#define H( X,Y,Z ) ( ( X ) ^ ( Y ) ^ ( Z ) )
+#ifdef LARGE_INT32
+#define lshift( x,s ) ( ( ( ( x ) << ( s ) ) & 0xFFFFFFFF ) | ( ( ( x ) >> ( 32 - ( s ) ) ) & 0xFFFFFFFF ) )
+#else
+#define lshift( x,s ) ( ( ( x ) << ( s ) ) | ( ( x ) >> ( 32 - ( s ) ) ) )
+#endif
+
+#define ROUND1( a,b,c,d,k,s ) a = lshift( a + F( b,c,d ) + X[k], s )
+#define ROUND2( a,b,c,d,k,s ) a = lshift( a + G( b,c,d ) + X[k] + 0x5A827999,s )
+#define ROUND3( a,b,c,d,k,s ) a = lshift( a + H( b,c,d ) + X[k] + 0x6ED9EBA1,s )
+
+/* this applies md4 to 64 byte chunks */
+static void mdfour64( uint32 *M ){
+       int j;
+       uint32 AA, BB, CC, DD;
+       uint32 X[16];
+       uint32 A,B,C,D;
+
+       for ( j = 0; j < 16; j++ )
+               X[j] = M[j];
+
+       A = m->A; B = m->B; C = m->C; D = m->D;
+       AA = A; BB = B; CC = C; DD = D;
+
+       ROUND1( A,B,C,D,  0,  3 );  ROUND1( D,A,B,C,  1,  7 );
+       ROUND1( C,D,A,B,  2, 11 );  ROUND1( B,C,D,A,  3, 19 );
+       ROUND1( A,B,C,D,  4,  3 );  ROUND1( D,A,B,C,  5,  7 );
+       ROUND1( C,D,A,B,  6, 11 );  ROUND1( B,C,D,A,  7, 19 );
+       ROUND1( A,B,C,D,  8,  3 );  ROUND1( D,A,B,C,  9,  7 );
+       ROUND1( C,D,A,B, 10, 11 );  ROUND1( B,C,D,A, 11, 19 );
+       ROUND1( A,B,C,D, 12,  3 );  ROUND1( D,A,B,C, 13,  7 );
+       ROUND1( C,D,A,B, 14, 11 );  ROUND1( B,C,D,A, 15, 19 );
+
+       ROUND2( A,B,C,D,  0,  3 );  ROUND2( D,A,B,C,  4,  5 );
+       ROUND2( C,D,A,B,  8,  9 );  ROUND2( B,C,D,A, 12, 13 );
+       ROUND2( A,B,C,D,  1,  3 );  ROUND2( D,A,B,C,  5,  5 );
+       ROUND2( C,D,A,B,  9,  9 );  ROUND2( B,C,D,A, 13, 13 );
+       ROUND2( A,B,C,D,  2,  3 );  ROUND2( D,A,B,C,  6,  5 );
+       ROUND2( C,D,A,B, 10,  9 );  ROUND2( B,C,D,A, 14, 13 );
+       ROUND2( A,B,C,D,  3,  3 );  ROUND2( D,A,B,C,  7,  5 );
+       ROUND2( C,D,A,B, 11,  9 );  ROUND2( B,C,D,A, 15, 13 );
+
+       ROUND3( A,B,C,D,  0,  3 );  ROUND3( D,A,B,C,  8,  9 );
+       ROUND3( C,D,A,B,  4, 11 );  ROUND3( B,C,D,A, 12, 15 );
+       ROUND3( A,B,C,D,  2,  3 );  ROUND3( D,A,B,C, 10,  9 );
+       ROUND3( C,D,A,B,  6, 11 );  ROUND3( B,C,D,A, 14, 15 );
+       ROUND3( A,B,C,D,  1,  3 );  ROUND3( D,A,B,C,  9,  9 );
+       ROUND3( C,D,A,B,  5, 11 );  ROUND3( B,C,D,A, 13, 15 );
+       ROUND3( A,B,C,D,  3,  3 );  ROUND3( D,A,B,C, 11,  9 );
+       ROUND3( C,D,A,B,  7, 11 );  ROUND3( B,C,D,A, 15, 15 );
+
+       A += AA; B += BB; C += CC; D += DD;
+
+#ifdef LARGE_INT32
+       A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
+       C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
+#endif
+
+       for ( j = 0; j < 16; j++ )
+               X[j] = 0;
+
+       m->A = A; m->B = B; m->C = C; m->D = D;
+}
+
+static void copy64( uint32 *M, unsigned char *in ){
+       int i;
+
+       for ( i = 0; i < 16; i++ )
+               M[i] = ( in[i * 4 + 3] << 24 ) | ( in[i * 4 + 2] << 16 ) |
+                          ( in[i * 4 + 1] << 8 ) | ( in[i * 4 + 0] << 0 );
+}
+
+static void copy4( unsigned char *out,uint32 x ){
+       out[0] = x & 0xFF;
+       out[1] = ( x >> 8 ) & 0xFF;
+       out[2] = ( x >> 16 ) & 0xFF;
+       out[3] = ( x >> 24 ) & 0xFF;
+}
+
+void mdfour_begin( struct mdfour *md ){
+       md->A = 0x67452301;
+       md->B = 0xefcdab89;
+       md->C = 0x98badcfe;
+       md->D = 0x10325476;
+       md->totalN = 0;
+}
+
+
+static void mdfour_tail( unsigned char *in, int n ){
+       unsigned char buf[128];
+       uint32 M[16];
+       uint32 b;
+
+       m->totalN += n;
+
+       b = m->totalN * 8;
+
+       memset( buf, 0, 128 );
+       if ( n ) {
+               memcpy( buf, in, n );
+       }
+       buf[n] = 0x80;
+
+       if ( n <= 55 ) {
+               copy4( buf + 56, b );
+               copy64( M, buf );
+               mdfour64( M );
+       }
+       else {
+               copy4( buf + 120, b );
+               copy64( M, buf );
+               mdfour64( M );
+               copy64( M, buf + 64 );
+               mdfour64( M );
+       }
+}
+
+void mdfour_update( struct mdfour *md, unsigned char *in, int n ){
+       uint32 M[16];
+
+// start of edit by Forest 'LordHavoc' Hale
+// commented out to prevent crashing when length is 0
+//     if (n == 0) mdfour_tail(in, n);
+// end of edit by Forest 'LordHavoc' Hale
+
+       m = md;
+
+       while ( n >= 64 ) {
+               copy64( M, in );
+               mdfour64( M );
+               in += 64;
+               n -= 64;
+               m->totalN += 64;
+       }
+
+       mdfour_tail( in, n );
+}
+
+
+void mdfour_result( struct mdfour *md, unsigned char *out ){
+       m = md;
+
+       copy4( out, m->A );
+       copy4( out + 4, m->B );
+       copy4( out + 8, m->C );
+       copy4( out + 12, m->D );
+}
+
+
+void mdfour( unsigned char *out, unsigned char *in, int n ){
+       struct mdfour md;
+       mdfour_begin( &md );
+       mdfour_update( &md, in, n );
+       mdfour_result( &md, out );
+}
+
+///////////////////////////////////////////////////////////////
+//     MD4-based checksum utility functions
+//
+//     Copyright (C) 2000       Jeff Teunissen <d2deek@pmail.net>
+//
+//     Author: Jeff Teunissen  <d2deek@pmail.net>
+//     Date: 01 Jan 2000
+
+unsigned Com_BlockChecksum( void *buffer, int length ){
+       int digest[4];
+       unsigned val;
+
+       mdfour( (unsigned char *) digest, (unsigned char *) buffer, length );
+
+       val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
+
+       return val;
+}
+
+void Com_BlockFullChecksum( void *buffer, int len, unsigned char *outbuf ){
+       mdfour( outbuf, (unsigned char *) buffer, len );
+}
diff --git a/tools/heretic2/common/md4.h b/tools/heretic2/common/md4.h
new file mode 100644 (file)
index 0000000..6f64c28
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+    mdfour.h
+
+    an implementation of MD4 designed for use in the SMB authentication
+    protocol
+
+    Copyright (C) Andrew Tridgell 1997-1998
+
+    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:
+
+        Free Software Foundation, Inc.
+        59 Temple Place - Suite 330
+        Boston, MA  02111-1307, USA
+ */
+
+#ifndef _MDFOUR_H
+#define _MDFOUR_H
+
+#ifndef int32
+#define int32 int
+#endif
+
+#if SIZEOF_INT > 4
+#define LARGE_INT32
+#endif
+
+#ifndef uint32
+#define uint32 unsigned int32
+#endif
+
+struct mdfour {
+       uint32 A, B, C, D;
+       uint32 totalN;
+};
+
+void mdfour_begin( struct mdfour *md ); // old: MD4Init
+void mdfour_update( struct mdfour *md, unsigned char *in, int n ); //old: MD4Update
+void mdfour_result( struct mdfour *md, unsigned char *out ); // old: MD4Final
+void mdfour( unsigned char *out, unsigned char *in, int n );
+
+unsigned Com_BlockChecksum( void *buffer, int length );
+void Com_BlockFullChecksum( void *buffer, int len, unsigned char *outbuf );
+
+#endif  // _MDFOUR_H
diff --git a/tools/heretic2/common/path_init.c b/tools/heretic2/common/path_init.c
new file mode 100644 (file)
index 0000000..254977b
--- /dev/null
@@ -0,0 +1,391 @@
+/* -------------------------------------------------------------------------------
+
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+   Nurail: Swiped from Q3Map2
+ */
+
+#include "globaldefs.h"
+
+#if !GDEF_OS_WINDOWS
+       #include <unistd.h>
+       #include <pwd.h>
+       #include <limits.h>
+#endif // !GDEF_OS_WINDOWS
+
+/* dependencies */
+#include "cmdlib.h"
+#include "inout.h"
+
+/* path support */
+#define MAX_BASE_PATHS  10
+#define MAX_GAME_PATHS  10
+
+char                    *homePath;
+char installPath[ MAX_OS_PATH ];
+
+int numBasePaths;
+char                    *basePaths[ MAX_BASE_PATHS ];
+int numGamePaths;
+char                    *gamePaths[ MAX_GAME_PATHS ];
+
+/*
+   some of this code is based off the original q3map port from loki
+   and finds various paths. moved here from bsp.c for clarity.
+ */
+
+/*
+   PathLokiGetHomeDir()
+   gets the user's home dir (for ~/.q3a)
+ */
+
+char *LokiGetHomeDir( void ){
+       #if GDEF_OS_WINDOWS
+       return NULL;
+       #else // !GDEF_OS_WINDOWS
+       char            *home;
+       uid_t id;
+       struct passwd   *pwd;
+
+
+       /* get the home environment variable */
+       home = getenv( "HOME" );
+       if ( home == NULL ) {
+               /* do some more digging */
+               id = getuid();
+               setpwent();
+               while ( ( pwd = getpwent() ) != NULL )
+               {
+                       if ( pwd->pw_uid == id ) {
+                               home = pwd->pw_dir;
+                               break;
+                       }
+               }
+               endpwent();
+       }
+
+       /* return it */
+       return home;
+       #endif // !GDEF_OS_WINDOWS
+}
+
+
+
+/*
+   PathLokiInitPaths()
+   initializes some paths on linux/os x
+ */
+
+void LokiInitPaths( char *argv0 ){
+       #if GDEF_OS_WINDOWS
+       /* this is kinda crap, but hey */
+       strcpy( installPath, "../" );
+       #else // !GDEF_OS_WINDOWS
+       char temp[ MAX_OS_PATH ];
+       char        *home;
+       char        *path;
+       char        *last;
+       qboolean found;
+
+
+       /* get home dir */
+       home = LokiGetHomeDir();
+       if ( home == NULL ) {
+               home = ".";
+       }
+
+       /* do some path divining */
+       strcpy( temp, argv0 );
+       if ( strrchr( temp, '/' ) ) {
+               argv0 = strrchr( argv0, '/' ) + 1;
+       }
+       else
+       {
+               /* get path environment variable */
+               path = getenv( "PATH" );
+
+               /* minor setup */
+               last[ 0 ] = path[ 0 ];
+               last[ 1 ] = '\0';
+               found = false;
+
+               /* go through each : segment of path */
+               while ( last[ 0 ] != '\0' && found == false )
+               {
+                       /* null out temp */
+                       temp[ 0 ] = '\0';
+
+                       /* find next chunk */
+                       last = strchr( path, ':' );
+                       if ( last == NULL ) {
+                               last = path + strlen( path );
+                       }
+
+                       /* found home dir candidate */
+                       if ( *path == '~' ) {
+                               strcpy( temp, home );
+                               path++;
+                       }
+
+                       /* concatenate */
+                       if ( last > ( path + 1 ) ) {
+                               strncat( temp, path, ( last - path ) );
+                               strcat( temp, "/" );
+                       }
+                       strcat( temp, "./" );
+                       strcat( temp, argv0 );
+
+                       /* verify the path */
+                       if ( access( temp, X_OK ) == 0 ) {
+                               found++;
+                       }
+                       path = last + 1;
+               }
+       }
+
+       /* flake */
+       if ( realpath( temp, installPath ) ) {
+               /* q3map is in "tools/" */
+               *( strrchr( installPath, '/' ) ) = '\0';
+               *( strrchr( installPath, '/' ) + 1 ) = '\0';
+       }
+
+       /* set home path */
+       homePath = home;
+       #endif // !GDEF_OS_WINDOWS
+}
+
+
+
+/*
+   CleanPath() - ydnar
+   cleans a dos path \ -> /
+ */
+
+void CleanPath( char *path ){
+       while ( *path )
+       {
+               if ( *path == '\\' ) {
+                       *path = '/';
+               }
+               path++;
+       }
+}
+
+/*
+   AddBasePath() - ydnar
+   adds a base path to the list
+ */
+
+void AddBasePath( char *path ){
+       /* dummy check */
+       if ( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS ) {
+               return;
+       }
+
+       /* add it to the list */
+       basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
+       strcpy( basePaths[ numBasePaths ], path );
+       CleanPath( basePaths[ numBasePaths ] );
+       numBasePaths++;
+}
+
+
+
+/*
+   AddHomeBasePath() - ydnar
+   adds a base path to the beginning of the list, prefixed by ~/
+ */
+
+void AddHomeBasePath( char *path ){
+       #if !GDEF_OS_WINDOWS
+       int i;
+       char temp[ MAX_OS_PATH ];
+
+
+       /* dummy check */
+       if ( path == NULL || path[ 0 ] == '\0' ) {
+               return;
+       }
+
+       /* make a hole */
+       for ( i = 0; i < ( MAX_BASE_PATHS - 1 ); i++ )
+               basePaths[ i + 1 ] = basePaths[ i ];
+
+       /* concatenate home dir and path */
+       sprintf( temp, "%s/%s", homePath, path );
+
+       /* add it to the list */
+       basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
+       strcpy( basePaths[ 0 ], temp );
+       CleanPath( basePaths[ 0 ] );
+       numBasePaths++;
+       #endif // !GDEF_OS_WINDOWS
+}
+
+
+
+/*
+   AddGamePath() - ydnar
+   adds a game path to the list
+ */
+
+void AddGamePath( char *path ){
+       /* dummy check */
+       if ( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS ) {
+               return;
+       }
+
+       /* add it to the list */
+       gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
+       strcpy( gamePaths[ numGamePaths ], path );
+       CleanPath( gamePaths[ numGamePaths ] );
+       numGamePaths++;
+}
+
+
+
+
+/*
+   InitPaths() - ydnar
+   cleaned up some of the path initialization code from bsp.c
+   will remove any arguments it uses
+ */
+
+void InitPaths( int *argc, char **argv ){
+       int i, j, k, len, len2;
+       char temp[ MAX_OS_PATH ];
+       char gamePath[MAX_OS_PATH], homeBasePath[MAX_OS_PATH], game_magic[10];
+
+       strcpy( gamePath, "base" );
+       strcpy( game_magic, "h" );
+       strcpy( homeBasePath, ".heretic2" );
+
+       /* note it */
+       Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
+
+       /* get the install path for backup */
+       LokiInitPaths( argv[ 0 ] );
+
+       /* set game to default (q3a) */
+       numBasePaths = 0;
+       numGamePaths = 0;
+
+       /* parse through the arguments and extract those relevant to paths */
+       for ( i = 0; i < *argc; i++ )
+       {
+               /* check for null */
+               if ( argv[ i ] == NULL ) {
+                       continue;
+               }
+
+               /* -fs_basepath */
+               if ( strcmp( argv[ i ], "-fs_basepath" ) == 0 ) {
+                       if ( ++i >= *argc ) {
+                               Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
+                       }
+                       argv[ i - 1 ] = NULL;
+                       AddBasePath( argv[ i ] );
+                       argv[ i ] = NULL;
+               }
+
+       }
+
+       /* remove processed arguments */
+       for ( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
+       {
+               for ( j; j < *argc && argv[ j ] == NULL; j++ ) ;
+               argv[ i ] = argv[ j ];
+               if ( argv[ i ] != NULL ) {
+                       k++;
+               }
+       }
+       *argc = k;
+
+       /* add standard game path */
+       AddGamePath( gamePath );
+
+       /* if there is no base path set, figure it out */
+       if ( numBasePaths == 0 ) {
+               /* this is another crappy replacement for SetQdirFromPath() */
+               len2 = strlen( game_magic );
+               for ( i = 0; i < *argc && numBasePaths == 0; i++ )
+               {
+                       /* extract the arg */
+                       strcpy( temp, argv[ i ] );
+                       CleanPath( temp );
+                       len = strlen( temp );
+                       Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game_magic, temp, i );
+
+                       /* this is slow, but only done once */
+                       for ( j = 0; j < ( len - len2 ); j++ )
+                       {
+                               /* check for the game's magic word */
+                               if ( Q_strncasecmp( &temp[ j ], game_magic, len2 ) == 0 ) {
+                                       /* now find the next slash and nuke everything after it */
+                                       while ( temp[ ++j ] != '/' && temp[ j ] != '\0' ) ;
+                                       temp[ j ] = '\0';
+
+                                       /* add this as a base path */
+                                       AddBasePath( temp );
+                                       break;
+                               }
+                       }
+               }
+
+               /* add install path */
+               if ( numBasePaths == 0 ) {
+                       AddBasePath( installPath );
+               }
+
+               /* check again */
+               if ( numBasePaths == 0 ) {
+                       Error( "Failed to find a valid base path." );
+               }
+       }
+
+       /* this only affects unix */
+       AddHomeBasePath( homeBasePath );
+
+       /* initialize vfs paths */
+       if ( numBasePaths > MAX_BASE_PATHS ) {
+               numBasePaths = MAX_BASE_PATHS;
+       }
+       if ( numGamePaths > MAX_GAME_PATHS ) {
+               numGamePaths = MAX_GAME_PATHS;
+       }
+
+       /* walk the list of game paths */
+       //for( j = 0; j < numGamePaths; j++ )
+       //{
+       /* walk the list of base paths */
+       //      for( i = 0; i < numBasePaths; i++ )
+       //      {
+       /* create a full path and initialize it */
+       //              sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
+       //              vfsInitDirectory( temp );
+       //      }
+       //}
+
+       /* done */
+       Sys_Printf( "\n" );
+}
diff --git a/tools/heretic2/common/polylib.c b/tools/heretic2/common/polylib.c
new file mode 100644 (file)
index 0000000..af5df49
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include "cmdlib.h"
+#include "inout.h"
+#include "mathlib.h"
+#include "polylib.h"
+
+
+extern int numthreads;
+
+// counters are only bumped when running single threaded,
+// because they are an awefull coherence problem
+int c_active_windings;
+int c_peak_windings;
+int c_winding_allocs;
+int c_winding_points;
+
+#define BOGUS_RANGE 8192
+
+void pw( winding_t *w ){
+       int i;
+       for ( i = 0 ; i < w->numpoints ; i++ )
+               printf( "(%5.1f, %5.1f, %5.1f)\n",w->p[i][0], w->p[i][1],w->p[i][2] );
+}
+
+
+/*
+   =============
+   AllocWinding
+   =============
+ */
+winding_t   *AllocWinding( int points ){
+       winding_t   *w;
+       int s;
+
+       if ( numthreads == 1 ) {
+               c_winding_allocs++;
+               c_winding_points += points;
+               c_active_windings++;
+               if ( c_active_windings > c_peak_windings ) {
+                       c_peak_windings = c_active_windings;
+               }
+       }
+       s = sizeof( vec_t ) * 3 * points + sizeof( int );
+       w = malloc( s );
+       if ( !w ) {
+               Error( "AllocWinding MALLOC failed!  Could not allocate %s bytes.", s );
+       }
+       memset( w, 0, s );
+       return w;
+}
+
+void FreeWinding( winding_t *w ){
+       if ( *(unsigned *)w == 0xdeaddead ) {
+               Error( "FreeWinding: freed a freed winding" );
+       }
+       *(unsigned *)w = 0xdeaddead;
+
+       if ( numthreads == 1 ) {
+               c_active_windings--;
+       }
+       free( w );
+}
+
+/*
+   ============
+   RemoveColinearPoints
+   ============
+ */
+int c_removed;
+
+void    RemoveColinearPoints( winding_t *w ){
+       int i, j, k;
+       vec3_t v1, v2;
+       int nump;
+       vec3_t p[MAX_POINTS_ON_WINDING];
+
+       nump = 0;
+       for ( i = 0 ; i < w->numpoints ; i++ )
+       {
+               j = ( i + 1 ) % w->numpoints;
+               k = ( i + w->numpoints - 1 ) % w->numpoints;
+               VectorSubtract( w->p[j], w->p[i], v1 );
+               VectorSubtract( w->p[i], w->p[k], v2 );
+               VectorNormalize( v1,v1 );
+               VectorNormalize( v2,v2 );
+               if ( DotProduct( v1, v2 ) < 0.999 ) {
+                       VectorCopy( w->p[i], p[nump] );
+                       nump++;
+               }
+       }
+
+       if ( nump == w->numpoints ) {
+               return;
+       }
+
+       if ( numthreads == 1 ) {
+               c_removed += w->numpoints - nump;
+       }
+       w->numpoints = nump;
+       memcpy( w->p, p, nump * sizeof( p[0] ) );
+}
+
+/*
+   ============
+   WindingPlane
+   ============
+ */
+void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist ){
+       vec3_t v1, v2;
+
+       VectorSubtract( w->p[1], w->p[0], v1 );
+       VectorSubtract( w->p[2], w->p[0], v2 );
+       CrossProduct( v2, v1, normal );
+       VectorNormalize( normal, normal );
+       *dist = DotProduct( w->p[0], normal );
+
+}
+
+/*
+   =============
+   WindingArea
+   =============
+ */
+vec_t   WindingArea( winding_t *w ){
+       int i;
+       vec3_t d1, d2, cross;
+       vec_t total;
+
+       total = 0;
+       for ( i = 2 ; i < w->numpoints ; i++ )
+       {
+               VectorSubtract( w->p[i - 1], w->p[0], d1 );
+               VectorSubtract( w->p[i], w->p[0], d2 );
+               CrossProduct( d1, d2, cross );
+               total += 0.5 * VectorLength( cross );
+       }
+       return total;
+}
+
+void    WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs ){
+       vec_t v;
+       int i,j;
+
+       mins[0] = mins[1] = mins[2] = 99999;
+       maxs[0] = maxs[1] = maxs[2] = -99999;
+
+       for ( i = 0 ; i < w->numpoints ; i++ )
+       {
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       v = w->p[i][j];
+                       if ( v < mins[j] ) {
+                               mins[j] = v;
+                       }
+                       if ( v > maxs[j] ) {
+                               maxs[j] = v;
+                       }
+               }
+       }
+}
+
+/*
+   =============
+   WindingCenter
+   =============
+ */
+void    WindingCenter( winding_t *w, vec3_t center ){
+       int i;
+       float scale;
+
+       VectorCopy( vec3_origin, center );
+       for ( i = 0 ; i < w->numpoints ; i++ )
+               VectorAdd( w->p[i], center, center );
+
+       scale = 1.0 / w->numpoints;
+       VectorScale( center, scale, center );
+}
+
+/*
+   =================
+   BaseWindingForPlane
+   =================
+ */
+winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){
+       int i, x;
+       vec_t max, v;
+       vec3_t org, vright, vup;
+       winding_t   *w;
+
+// find the major axis
+
+       max = -BOGUS_RANGE;
+       x = -1;
+       for ( i = 0 ; i < 3; i++ )
+       {
+               v = fabs( normal[i] );
+               if ( v > max ) {
+                       x = i;
+                       max = v;
+               }
+       }
+       if ( x == -1 ) {
+               Error( "BaseWindingForPlane: no axis found" );
+       }
+
+       VectorCopy( vec3_origin, vup );
+       switch ( x )
+       {
+       case 0:
+       case 1:
+               vup[2] = 1;
+               break;
+       case 2:
+               vup[0] = 1;
+               break;
+       }
+
+       v = DotProduct( vup, normal );
+       VectorMA( vup, -v, normal, vup );
+       VectorNormalize( vup, vup );
+
+       VectorScale( normal, dist, org );
+
+       CrossProduct( vup, normal, vright );
+
+       VectorScale( vup, 8192, vup );
+       VectorScale( vright, 8192, vright );
+
+// project a really big        axis aligned box onto the plane
+       w = AllocWinding( 4 );
+
+       VectorSubtract( org, vright, w->p[0] );
+       VectorAdd( w->p[0], vup, w->p[0] );
+
+       VectorAdd( org, vright, w->p[1] );
+       VectorAdd( w->p[1], vup, w->p[1] );
+
+       VectorAdd( org, vright, w->p[2] );
+       VectorSubtract( w->p[2], vup, w->p[2] );
+
+       VectorSubtract( org, vright, w->p[3] );
+       VectorSubtract( w->p[3], vup, w->p[3] );
+
+       w->numpoints = 4;
+
+       return w;
+}
+
+/*
+   ==================
+   CopyWinding
+   ==================
+ */
+winding_t   *CopyWinding( winding_t *w ){
+       int size;
+       winding_t   *c;
+
+       c = AllocWinding( w->numpoints );
+       size = (int)( (winding_t *)0 )->p[w->numpoints];
+       memcpy( c, w, size );
+       return c;
+}
+
+/*
+   ==================
+   ReverseWinding
+   ==================
+ */
+winding_t   *ReverseWinding( winding_t *w ){
+       int i;
+       winding_t   *c;
+
+       c = AllocWinding( w->numpoints );
+       for ( i = 0 ; i < w->numpoints ; i++ )
+       {
+               VectorCopy( w->p[w->numpoints - 1 - i], c->p[i] );
+       }
+       c->numpoints = w->numpoints;
+       return c;
+}
+
+
+/*
+   =============
+   ClipWindingEpsilon
+   =============
+ */
+void    ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist,
+                                                       vec_t epsilon, winding_t **front, winding_t **back ){
+       vec_t dists[MAX_POINTS_ON_WINDING + 4];
+       int sides[MAX_POINTS_ON_WINDING + 4];
+       int counts[3];
+       vec_t dot;          // VC 4.2 optimizer bug if not static
+       int i, j;
+       vec_t   *p1, *p2;
+       vec3_t mid;
+       winding_t   *f, *b;
+       int maxpts;
+
+       if ( in->numpoints >= MAX_POINTS_ON_WINDING - 4 ) {
+               Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
+       }
+
+       counts[0] = counts[1] = counts[2] = 0;
+
+// determine sides for each point
+       for ( i = 0 ; i < in->numpoints ; i++ )
+       {
+               dot = DotProduct( in->p[i], normal );
+               dot -= dist;
+               dists[i] = dot;
+               if ( dot > epsilon ) {
+                       sides[i] = SIDE_FRONT;
+               }
+               else if ( dot < -epsilon ) {
+                       sides[i] = SIDE_BACK;
+               }
+               else
+               {
+                       sides[i] = SIDE_ON;
+               }
+               counts[sides[i]]++;
+       }
+       sides[i] = sides[0];
+       dists[i] = dists[0];
+
+       *front = *back = NULL;
+
+       if ( !counts[0] ) {
+               *back = CopyWinding( in );
+               return;
+       }
+       if ( !counts[1] ) {
+               *front = CopyWinding( in );
+               return;
+       }
+
+       maxpts = in->numpoints + 4;   // cant use counts[0]+2 because
+                                     // of fp grouping errors
+
+       *front = f = AllocWinding( maxpts );
+       *back = b = AllocWinding( maxpts );
+
+       for ( i = 0 ; i < in->numpoints ; i++ )
+       {
+               p1 = in->p[i];
+
+               if ( sides[i] == SIDE_ON ) {
+                       VectorCopy( p1, f->p[f->numpoints] );
+                       f->numpoints++;
+                       VectorCopy( p1, b->p[b->numpoints] );
+                       b->numpoints++;
+                       continue;
+               }
+
+               if ( sides[i] == SIDE_FRONT ) {
+                       VectorCopy( p1, f->p[f->numpoints] );
+                       f->numpoints++;
+               }
+               if ( sides[i] == SIDE_BACK ) {
+                       VectorCopy( p1, b->p[b->numpoints] );
+                       b->numpoints++;
+               }
+
+               if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
+                       continue;
+               }
+
+               // generate a split point
+               p2 = in->p[( i + 1 ) % in->numpoints];
+
+               dot = dists[i] / ( dists[i] - dists[i + 1] );
+               for ( j = 0 ; j < 3 ; j++ )
+               {   // avoid round off error when possible
+                       if ( normal[j] == 1 ) {
+                               mid[j] = dist;
+                       }
+                       else if ( normal[j] == -1 ) {
+                               mid[j] = -dist;
+                       }
+                       else{
+                               mid[j] = p1[j] + dot * ( p2[j] - p1[j] );
+                       }
+               }
+
+               VectorCopy( mid, f->p[f->numpoints] );
+               f->numpoints++;
+               VectorCopy( mid, b->p[b->numpoints] );
+               b->numpoints++;
+       }
+
+       if ( f->numpoints > maxpts || b->numpoints > maxpts ) {
+               Error( "ClipWinding: points exceeded estimate" );
+       }
+       if ( f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING ) {
+               Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
+       }
+}
+
+
+/*
+   =============
+   ChopWindingInPlace
+   =============
+ */
+void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t epsilon ){
+       winding_t   *in;
+       vec_t dists[MAX_POINTS_ON_WINDING + 4];
+       int sides[MAX_POINTS_ON_WINDING + 4];
+       int counts[3];
+       vec_t dot;          // VC 4.2 optimizer bug if not static
+       int i, j;
+       vec_t   *p1, *p2;
+       vec3_t mid;
+       winding_t   *f;
+       int maxpts;
+
+       in = *inout;
+       counts[0] = counts[1] = counts[2] = 0;
+
+       if ( !in ) {
+               printf( "Warning: NULL passed to ChopWindingInPlace\n" );
+               return;
+       }
+       if ( in->numpoints >= MAX_POINTS_ON_WINDING - 4 ) {
+               Error( "ChopWinding: MAX_POINTS_ON_WINDING" );
+       }
+
+// determine sides for each point
+       for ( i = 0 ; i < in->numpoints ; i++ )
+       {
+               dot = DotProduct( in->p[i], normal );
+               dot -= dist;
+               dists[i] = dot;
+               if ( dot > epsilon ) {
+                       sides[i] = SIDE_FRONT;
+               }
+               else if ( dot < -epsilon ) {
+                       sides[i] = SIDE_BACK;
+               }
+               else
+               {
+                       sides[i] = SIDE_ON;
+               }
+               counts[sides[i]]++;
+       }
+       sides[i] = sides[0];
+       dists[i] = dists[0];
+
+       if ( !counts[0] ) {
+               FreeWinding( in );
+               *inout = NULL;
+               return;
+       }
+       if ( !counts[1] ) {
+               return;     // inout stays the same
+
+       }
+       maxpts = in->numpoints + 4;   // cant use counts[0]+2 because
+                                     // of fp grouping errors
+
+       f = AllocWinding( maxpts );
+
+       for ( i = 0 ; i < in->numpoints ; i++ )
+       {
+               p1 = in->p[i];
+
+               if ( sides[i] == SIDE_ON ) {
+                       VectorCopy( p1, f->p[f->numpoints] );
+                       f->numpoints++;
+                       continue;
+               }
+
+               if ( sides[i] == SIDE_FRONT ) {
+                       VectorCopy( p1, f->p[f->numpoints] );
+                       f->numpoints++;
+               }
+
+               if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
+                       continue;
+               }
+
+               // generate a split point
+               p2 = in->p[( i + 1 ) % in->numpoints];
+
+               dot = dists[i] / ( dists[i] - dists[i + 1] );
+               for ( j = 0 ; j < 3 ; j++ )
+               {   // avoid round off error when possible
+                       if ( normal[j] == 1 ) {
+                               mid[j] = dist;
+                       }
+                       else if ( normal[j] == -1 ) {
+                               mid[j] = -dist;
+                       }
+                       else{
+                               mid[j] = p1[j] + dot * ( p2[j] - p1[j] );
+                       }
+               }
+
+               VectorCopy( mid, f->p[f->numpoints] );
+               f->numpoints++;
+       }
+
+       if ( f->numpoints > maxpts ) {
+               Error( "ClipWinding: points exceeded estimate" );
+       }
+       if ( f->numpoints > MAX_POINTS_ON_WINDING ) {
+               Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
+       }
+
+       FreeWinding( in );
+       *inout = f;
+}
+
+
+/*
+   =================
+   ChopWinding
+
+   Returns the fragment of in that is on the front side
+   of the cliping plane.  The original is freed.
+   =================
+ */
+winding_t   *ChopWinding( winding_t *in, vec3_t normal, vec_t dist ){
+       winding_t   *f, *b;
+
+       ClipWindingEpsilon( in, normal, dist, ON_EPSILON, &f, &b );
+       FreeWinding( in );
+       if ( b ) {
+               FreeWinding( b );
+       }
+       return f;
+}
+
+
+/*
+   =================
+   CheckWinding
+
+   =================
+ */
+void CheckWinding( winding_t *w ){
+       int i, j;
+       vec_t   *p1, *p2;
+       vec_t d, edgedist;
+       vec3_t dir, edgenormal, facenormal;
+       vec_t area;
+       vec_t facedist;
+
+       if ( w->numpoints < 3 ) {
+               Error( "CheckWinding: %i points",w->numpoints );
+       }
+
+       area = WindingArea( w );
+       if ( area < 1 ) {
+               Error( "CheckWinding: %f area", area );
+       }
+
+       WindingPlane( w, facenormal, &facedist );
+
+       for ( i = 0 ; i < w->numpoints ; i++ )
+       {
+               p1 = w->p[i];
+
+               for ( j = 0 ; j < 3 ; j++ )
+                       if ( p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE ) {
+                               Error( "CheckFace: BUGUS_RANGE: %f",p1[j] );
+                       }
+
+               j = i + 1 == w->numpoints ? 0 : i + 1;
+
+               // check the point is on the face plane
+               d = DotProduct( p1, facenormal ) - facedist;
+               if ( d < -ON_EPSILON || d > ON_EPSILON ) {
+                       Error( "CheckWinding: point off plane" );
+               }
+
+               // check the edge isnt degenerate
+               p2 = w->p[j];
+               VectorSubtract( p2, p1, dir );
+
+               if ( VectorLength( dir ) < ON_EPSILON ) {
+                       Error( "CheckWinding: degenerate edge" );
+               }
+
+               CrossProduct( facenormal, dir, edgenormal );
+               VectorNormalize( edgenormal, edgenormal );
+               edgedist = DotProduct( p1, edgenormal );
+               edgedist += ON_EPSILON;
+
+               // all other points must be on front side
+               for ( j = 0 ; j < w->numpoints ; j++ )
+               {
+                       if ( j == i ) {
+                               continue;
+                       }
+                       d = DotProduct( w->p[j], edgenormal );
+                       if ( d > edgedist ) {
+                               Error( "CheckWinding: non-convex" );
+                       }
+               }
+       }
+}
+
+
+/*
+   ============
+   WindingOnPlaneSide
+   ============
+ */
+int     WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){
+       qboolean front, back;
+       int i;
+       vec_t d;
+
+       front = false;
+       back = false;
+       for ( i = 0 ; i < w->numpoints ; i++ )
+       {
+               d = DotProduct( w->p[i], normal ) - dist;
+               if ( d < -ON_EPSILON ) {
+                       if ( front ) {
+                               return SIDE_CROSS;
+                       }
+                       back = true;
+                       continue;
+               }
+               if ( d > ON_EPSILON ) {
+                       if ( back ) {
+                               return SIDE_CROSS;
+                       }
+                       front = true;
+                       continue;
+               }
+       }
+
+       if ( back ) {
+               return SIDE_BACK;
+       }
+       if ( front ) {
+               return SIDE_FRONT;
+       }
+       return SIDE_ON;
+}
diff --git a/tools/heretic2/common/polylib.h b/tools/heretic2/common/polylib.h
new file mode 100644 (file)
index 0000000..00b7b39
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+typedef struct
+{
+       int numpoints;
+       vec3_t p[4];        // variable sized
+} winding_t;
+
+#define MAX_POINTS_ON_WINDING   64
+
+// you can define on_epsilon in the makefile as tighter
+#ifndef ON_EPSILON
+#define ON_EPSILON  0.1
+#endif
+
+winding_t   *AllocWinding( int points );
+vec_t   WindingArea( winding_t *w );
+void    WindingCenter( winding_t *w, vec3_t center );
+void    ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist,
+                                                       vec_t epsilon, winding_t **front, winding_t **back );
+winding_t   *ChopWinding( winding_t *in, vec3_t normal, vec_t dist );
+winding_t   *CopyWinding( winding_t *w );
+winding_t   *ReverseWinding( winding_t *w );
+winding_t   *BaseWindingForPlane( vec3_t normal, vec_t dist );
+void    CheckWinding( winding_t *w );
+void    WindingPlane( winding_t *w, vec3_t normal, vec_t *dist );
+void    RemoveColinearPoints( winding_t *w );
+int     WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist );
+void    FreeWinding( winding_t *w );
+void    WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs );
+
+void    ChopWindingInPlace( winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon );
+// frees the original if clipped
+
+void pw( winding_t *w );
diff --git a/tools/heretic2/common/qfiles.c b/tools/heretic2/common/qfiles.c
new file mode 100644 (file)
index 0000000..53452f3
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qfiles.h"
+#include "scriplib.h"
+//#include <windows.h>
+
+materialtype_t defaultmaterialtypes[] =
+{
+       {"gravel",  MATERIAL_GRAVEL},
+       {"metal",   MATERIAL_METAL},
+       {"stone",   MATERIAL_STONE},
+       {"wood",    MATERIAL_WOOD},
+       {NULL,      0}
+};
+
+materialtype_t  *materialtypes;
+
+void QFile_ReadMaterialTypes( char* filename ){
+       int i;
+       FILE    *f;
+
+       f = fopen( filename, "rb" );
+       if ( !f ) {
+               materialtypes = defaultmaterialtypes;
+               return;
+       }
+       fclose( f );
+
+       free( materialtypes );
+       materialtypes = (materialtype_t*)malloc( 256 * sizeof( materialtype_t ) );
+
+       LoadScriptFile( filename );
+       i = 0;
+
+       while ( i < 255 )
+       {
+               GetScriptToken( true );
+               if ( endofscript ) {
+                       break;
+               }
+               if ( strcmp( token, "material" ) != 0 ) {
+                       while ( ScriptTokenAvailable() )
+                       {
+                               GetScriptToken( false );
+                       }
+               }
+               else
+               {
+                       GetScriptToken( false );
+                       materialtypes[i].name = (char*)malloc( strlen( token ) + 1 );
+                       strcpy( materialtypes[i].name, token );
+                       GetScriptToken( false );
+                       materialtypes[i].value = atoi( token );
+               }
+               i++;
+       }
+       materialtypes[i].name = NULL;
+       materialtypes[i].value = 0;
+}
diff --git a/tools/heretic2/common/qfiles.h b/tools/heretic2/common/qfiles.h
new file mode 100644 (file)
index 0000000..bee4b4f
--- /dev/null
@@ -0,0 +1,619 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _QFILES_H
+#define _QFILES_H
+
+#include "q_typedef.h"
+
+//
+// qfiles.h: quake file formats
+// This file must be identical in the quake and utils directories
+//
+
+/*
+   ========================================================================
+
+   The .pak files are just a linear collapse of a directory tree
+
+   ========================================================================
+ */
+
+#define IDPAKHEADER     ( ( 'K' << 24 ) + ( 'C' << 16 ) + ( 'A' << 8 ) + 'P' )
+
+typedef struct
+{
+       char name[56];
+       int filepos, filelen;
+} dpackfile_t;
+
+typedef struct
+{
+       int ident;          // == IDPAKHEADER
+       int dirofs;
+       int dirlen;
+} dpackheader_t;
+
+#define MAX_FILES_IN_PACK   4096
+
+
+/*
+   ========================================================================
+
+   PCX files are used for as many images as possible
+
+   ========================================================================
+ */
+
+typedef struct
+{
+       char manufacturer;
+       char version;
+       char encoding;
+       char bits_per_pixel;
+       unsigned short xmin,ymin,xmax,ymax;
+       unsigned short hres,vres;
+       unsigned char palette[48];
+       char reserved;
+       char color_planes;
+       unsigned short bytes_per_line;
+       unsigned short palette_type;
+       char filler[58];
+       unsigned char data;             // unbounded
+} pcx_t;
+
+
+/*
+   ========================================================================
+
+   .MD2 compressed triangle model file format
+
+   ========================================================================
+ */
+#define IDJOINTEDALIASHEADER    ( ( '2' << 24 ) + ( 'J' << 16 ) + ( 'D' << 8 ) + 'I' )
+
+/*
+   ========================================================================
+
+   .MD2 triangle model file format
+
+   ========================================================================
+ */
+
+#define IDALIASHEADER       ( ( '2' << 24 ) + ( 'P' << 16 ) + ( 'D' << 8 ) + 'I' )
+#define ALIAS_VERSION   8
+
+#define MAX_TRIANGLES   2048
+#define MAX_VERTS       2048
+#define MAX_FRAMES      512
+#define MAX_MD2SKINS    64
+#define MAX_SKINNAME    64
+
+typedef struct
+{
+       short s;
+       short t;
+} dstvert_t;
+
+typedef struct
+{
+       short index_xyz[3];
+       short index_st[3];
+} dtriangle_t;
+
+typedef struct
+{
+       byte v[3];              // scaled byte to fit in frame mins/maxs
+       byte lightnormalindex;
+} dtrivertx_t;
+
+#define DTRIVERTX_V0   0
+#define DTRIVERTX_V1   1
+#define DTRIVERTX_V2   2
+#define DTRIVERTX_LNI  3
+#define DTRIVERTX_SIZE 4
+
+typedef struct
+{
+       float scale[3];         // multiply byte verts by this
+       float translate[3];         // then add this
+       char name[16];          // frame name from grabbing
+       dtrivertx_t verts[1];   // variable sized
+} daliasframe_t;
+
+
+// the glcmd format:
+// a positive integer starts a tristrip command, followed by that many
+// vertex structures.
+// a negative integer starts a trifan command, followed by -x vertexes
+// a zero indicates the end of the command list.
+// a vertex consists of a floating point s, a floating point t,
+// and an integer vertex index.
+
+
+typedef struct
+{
+       int ident;
+       int version;
+
+       int skinwidth;
+       int skinheight;
+       int framesize;              // byte size of each frame
+
+       int num_skins;
+       int num_xyz;
+       int num_st;                 // greater than num_xyz for seams
+       int num_tris;
+       int num_glcmds;             // dwords in strip/fan command list
+       int num_frames;
+
+       int ofs_skins;              // each skin is a MAX_SKINNAME string
+       int ofs_st;                 // byte offset from start for stverts
+       int ofs_tris;               // offset for dtriangles
+       int ofs_frames;             // offset for first frame
+       int ofs_glcmds;
+       int ofs_end;                // end of file
+
+} dmdl_t;
+
+/*
+   ========================================================================
+
+   .BK file format
+
+   ========================================================================
+ */
+
+#define IDBOOKHEADER    ( ( 'K' << 24 ) + ( 'O' << 16 ) + ( 'O' << 8 ) + 'B' )
+#define BOOK_VERSION    2
+
+typedef struct bookframe_s
+{
+       int x;
+       int y;
+       int w;
+       int h;
+       char name[MAX_SKINNAME];            // name of gfx file
+} bookframe_t;
+
+typedef struct bookheader_s
+{
+       unsigned int ident;
+       unsigned int version;
+       int num_segments;
+       int total_w;
+       int total_h;
+} bookheader_t;
+
+typedef struct book_s
+{
+       bookheader_t bheader;
+       bookframe_t bframes[MAX_MD2SKINS];
+} book_t;
+
+/*
+   ========================================================================
+
+   .SP2 sprite file format
+
+   ========================================================================
+ */
+
+#define IDSPRITEHEADER  ( ( '2' << 24 ) + ( 'S' << 16 ) + ( 'D' << 8 ) + 'I' )
+// little-endian "IDS2"
+#define SPRITE_VERSION  2
+
+typedef struct
+{
+       int width, height;
+       int origin_x, origin_y;         // raster coordinates inside pic
+       char name[MAX_SKINNAME];        // name of pcx file
+} dsprframe_t;
+
+typedef struct {
+       int ident;
+       int version;
+       int numframes;
+       dsprframe_t frames[1];          // variable sized
+} dsprite_t;
+
+/*
+   ==============================================================================
+
+   .M8 texture file format
+
+   ==============================================================================
+ */
+
+typedef struct palette_s
+{
+       union
+       {
+               struct
+               {
+                       byte r,g,b;
+               };
+       };
+} palette_t;
+
+#define MIP_VERSION     2
+#define PAL_SIZE        256
+#define MIPLEVELS       16
+
+typedef struct miptex_s
+{
+       int version;
+       char name[32];
+       unsigned width[MIPLEVELS], height[MIPLEVELS];
+       unsigned offsets[MIPLEVELS];        // four mip maps stored
+       char animname[32];                  // next frame in animation chain
+       palette_t palette[PAL_SIZE];
+       int flags;
+       int contents;
+       int value;
+} miptex_t;
+
+
+#define MIP32_VERSION   4
+
+#define MIP32_NOMIP_FLAG2           0x00000001
+#define MIP32_DETAILER_FLAG2        0x00000002
+
+typedef struct miptex32_s
+{
+       int version;
+       char name[128];
+       char altname[128];                  // texture substitution
+       char animname[128];                 // next frame in animation chain
+       char damagename[128];               // image that should be shown when damaged
+       unsigned width[MIPLEVELS], height[MIPLEVELS];
+       unsigned offsets[MIPLEVELS];
+       int flags;
+       int contents;
+       int value;
+       float scale_x, scale_y;
+       int mip_scale;
+
+       // detail texturing info
+       char dt_name[128];              // detailed texture name
+       float dt_scale_x, dt_scale_y;
+       float dt_u, dt_v;
+       float dt_alpha;
+       int dt_src_blend_mode, dt_dst_blend_mode;
+
+       int flags2;
+       int unused[19];                     // future expansion to maintain compatibility with h2
+} miptex32_t;
+
+
+
+/*
+   ==============================================================================
+
+   .BSP file format
+
+   ==============================================================================
+ */
+
+#define IDBSPHEADER ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'B' << 8 ) + 'I' )
+// little-endian "IBSP"
+
+#define BSPVERSION  38
+
+
+// upper design bounds
+// leaffaces, leafbrushes, planes, and verts are still bounded by
+// 16 bit short limits
+#define MAX_MAP_MODELS      1024
+#define MAX_MAP_BRUSHES     8192
+#define MAX_MAP_ENTITIES    2048
+#define MAX_MAP_ENTSTRING   0x40000
+#define MAX_MAP_TEXINFO     8192
+
+#define MAX_MAP_AREAS       256
+#define MAX_MAP_AREAPORTALS 1024
+#define MAX_MAP_PLANES      65536
+#define MAX_MAP_NODES       65536
+#define MAX_MAP_BRUSHSIDES  65536
+#define MAX_MAP_LEAFS       65536
+#define MAX_MAP_VERTS       65536
+#define MAX_MAP_FACES       65536
+#define MAX_MAP_LEAFFACES   65536
+#define MAX_MAP_LEAFBRUSHES 65536
+#define MAX_MAP_PORTALS     65536
+#define MAX_MAP_EDGES       128000
+#define MAX_MAP_SURFEDGES   256000
+#define MAX_MAP_LIGHTING    0x200000
+#define MAX_MAP_VISIBILITY  0x180000
+
+// key / value pair sizes
+
+#define MAX_KEY     32
+#define MAX_VALUE   1024
+
+//=============================================================================
+
+typedef struct
+{
+       int fileofs, filelen;
+} lump_t;
+
+#define LUMP_ENTITIES       0
+#define LUMP_PLANES         1
+#define LUMP_VERTEXES       2
+#define LUMP_VISIBILITY     3
+#define LUMP_NODES          4
+#define LUMP_TEXINFO        5
+#define LUMP_FACES          6
+#define LUMP_LIGHTING       7
+#define LUMP_LEAFS          8
+#define LUMP_LEAFFACES      9
+#define LUMP_LEAFBRUSHES    10
+#define LUMP_EDGES          11
+#define LUMP_SURFEDGES      12
+#define LUMP_MODELS         13
+#define LUMP_BRUSHES        14
+#define LUMP_BRUSHSIDES     15
+#define LUMP_POP            16
+#define LUMP_AREAS          17
+#define LUMP_AREAPORTALS    18
+#define HEADER_LUMPS        19
+
+typedef struct
+{
+       int ident;
+       int version;
+       lump_t lumps[HEADER_LUMPS];
+} dheader_t;
+
+typedef struct
+{
+       float mins[3], maxs[3];
+       float origin[3];            // for sounds or lights
+       int headnode;
+       int firstface, numfaces;            // submodels just draw faces
+                                           // without walking the bsp tree
+} dmodel_t;
+
+
+typedef struct
+{
+       float point[3];
+} dvertex_t;
+
+
+// 0-2 are axial planes
+#define PLANE_X         0
+#define PLANE_Y         1
+#define PLANE_Z         2
+
+// 3-5 are non-axial planes snapped to the nearest
+#define PLANE_ANYX      3
+#define PLANE_ANYY      4
+#define PLANE_ANYZ      5
+
+// planes (x&~1) and (x&~1)+1 are allways opposites
+
+typedef struct
+{
+       float normal[3];
+       float dist;
+       int type;           // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
+} dplane_t;
+
+
+// contents flags are seperate bits
+// a given brush can contribute multiple content bits
+// multiple brushes can be in a single leaf
+
+// these definitions also need to be in q_shared.h!
+
+// lower bits are stronger, and will eat weaker brushes completely
+#define CONTENTS_SOLID          0x00000001      // an eye is never valid in a solid
+#define CONTENTS_WINDOW         0x00000002      // translucent, but not watery
+#define CONTENTS_PUSHPULL       0x00000004
+#define CONTENTS_LAVA           0x00000008
+#define CONTENTS_SLIME          0x00000010
+#define CONTENTS_WATER          0x00000020
+#define CONTENTS_MIST           0x00000040      // 64
+#define LAST_VISIBLE_CONTENTS   64              // this one worries me a bit JKH
+
+// remaining contents are non-visible, and don't eat brushes
+
+#define CONTENTS_AREAPORTAL     0x00008000
+
+#define CONTENTS_PLAYERCLIP     0x00010000
+#define CONTENTS_MONSTERCLIP    0x00020000
+
+// currents can be added to any other contents, and may be mixed
+#define CONTENTS_CURRENT_0      0x00040000
+#define CONTENTS_CURRENT_90     0x00080000
+#define CONTENTS_CURRENT_180    0x00100000
+#define CONTENTS_CURRENT_270    0x00200000
+#define CONTENTS_CURRENT_UP     0x00400000
+#define CONTENTS_CURRENT_DOWN   0x00800000
+
+#define CONTENTS_ORIGIN         0x01000000  // removed before bsping an entity
+
+#define CONTENTS_MONSTER        0x02000000  // should never be on a brush, only in game
+#define CONTENTS_DEADMONSTER    0x04000000
+#define CONTENTS_DETAIL         0x08000000  // brushes to be added after vis leafs
+#define CONTENTS_TRANSLUCENT    0x10000000  // auto set if any surface has trans
+#define CONTENTS_LADDER         0x20000000
+
+
+
+#define SURF_LIGHT              0x00000001      // value will hold the light strength
+
+#define SURF_SLICK              0x00000002      // effects game physics
+
+#define SURF_SKY                0x00000004      // don't draw, but add to skybox
+#define SURF_WARP               0x00000008      // turbulent water warp
+#define SURF_TRANS33            0x00000010
+#define SURF_TRANS66            0x00000020
+#define SURF_FLOWING            0x00000040  // scroll towards angle
+#define SURF_NODRAW             0x00000080  // don't bother referencing the texture
+
+#define SURF_HINT               0x00000100  // make a primary bsp splitter
+#define SURF_SKIP               0x00000200  // completely ignore, allowing non-closed brushes
+#define SURF_TALL_WALL          0x00000400  // face doesn't get broken up as normal
+
+#define SURF_ALPHA_TEXTURE      0x00000800  // texture has alpha in it, and should show through in bsp process
+#define SURF_ANIMSPEED          0x00001000      // value will hold the anim speed in fps
+
+#define SURF_UNDULATE           0x00002000  // rock surface up and down...
+#define SURF_SKYREFLECT         0x00004000  // liquid will somewhat reflect the sky - not quite finished....
+
+#define SURF_TYPE_GRAVEL        0x00000000
+#define SURF_TYPE_METAL         0x01000000
+#define SURF_TYPE_STONE         0x02000000
+#define SURF_TYPE_WOOD          0x03000000
+#define SURF_MATERIAL           0xFF000000
+
+
+
+typedef struct
+{
+       int planenum;
+       int children[2];            // negative numbers are -(leafs+1), not nodes
+       short mins[3];              // for frustom culling
+       short maxs[3];
+       unsigned short firstface;
+       unsigned short numfaces;    // counting both sides
+} dnode_t;
+
+
+typedef struct texinfo_s
+{
+       float vecs[2][4];           // [s/t][xyz offset]
+       int flags;                  // miptex flags + overrides
+       int value;                  // light emission, etc
+       char texture[32];           // texture name (textures/*.wal)
+       int nexttexinfo;            // for animations, -1 = end of chain
+} texinfo_t;
+
+
+// note that edge 0 is never used, because negative edge nums are used for
+// counterclockwise use of the edge in a face
+typedef struct
+{
+       unsigned short v[2];        // vertex numbers
+} dedge_t;
+
+#define MAXLIGHTMAPS    4
+typedef struct
+{
+       unsigned short planenum;
+       short side;
+
+       int firstedge;              // we must support > 64k edges
+       short numedges;
+       short texinfo;
+
+// lighting info
+       union {
+               byte styles[MAXLIGHTMAPS];
+               paletteRGBA_t lighting;
+       };
+       int lightofs;               // start of [numstyles*surfsize] samples
+} dface_t;
+
+typedef struct
+{
+       int contents;                       // OR of all brushes (not needed?)
+
+       short cluster;
+       short area;
+
+       short mins[3];                      // for frustum culling
+       short maxs[3];
+
+       unsigned short firstleafface;
+       unsigned short numleaffaces;
+
+       unsigned short firstleafbrush;
+       unsigned short numleafbrushes;
+} dleaf_t;
+
+typedef struct
+{
+       unsigned short planenum;        // facing out of the leaf
+       short texinfo;
+} dbrushside_t;
+
+typedef struct
+{
+       int firstside;
+       int numsides;
+       int contents;
+} dbrush_t;
+
+#define ANGLE_UP    -1
+#define ANGLE_DOWN  -2
+
+
+// the visibility lump consists of a header with a count, then
+// byte offsets for the PVS and PHS of each cluster, then the raw
+// compressed bit vectors
+#define DVIS_PVS    0
+#define DVIS_PHS    1
+typedef struct
+{
+       int numclusters;
+       int bitofs[8][2];           // bitofs[numclusters][2]
+} dvis_t;
+
+// each area has a list of portals that lead into other areas
+// when portals are closed, other areas may not be visible or
+// hearable even if the vis info says that it should be
+typedef struct
+{
+       int portalnum;
+       int otherarea;
+} dareaportal_t;
+
+
+typedef struct
+{
+       int numareaportals;
+       int firstareaportal;
+} darea_t;
+
+typedef struct
+{
+       char    *name;
+       int value;
+} materialtype_t;
+
+enum
+{
+       MATERIAL_GRAVEL,
+       MATERIAL_METAL,
+       MATERIAL_STONE,
+       MATERIAL_WOOD,
+};
+
+materialtype_t  *materialtypes;
+
+void QFile_ReadMaterialTypes( char* filename );
+
+
+#endif //_QFILES_H
diff --git a/tools/heretic2/common/scriplib.c b/tools/heretic2/common/scriplib.c
new file mode 100644 (file)
index 0000000..af5e571
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// scriplib.c
+
+#include "cmdlib.h"
+#include "inout.h"
+#include "scriplib.h"
+
+/*
+   =============================================================================
+
+                        PARSING STUFF
+
+   =============================================================================
+ */
+
+typedef struct
+{
+       char filename[1024];
+       char    *buffer,*script_p,*end_p;
+       int line;
+} script_t;
+
+#define MAX_INCLUDES    8
+script_t scriptstack[MAX_INCLUDES];
+script_t    *script;
+int scriptline;
+
+char token[MAXTOKEN];
+qboolean endofscript;
+qboolean tokenready;                     // only true if UnGetScriptToken was just called
+
+/*
+   ==============
+   AddScriptToStack
+   ==============
+ */
+void AddScriptToStack( char *filename ){
+       int size;
+
+       script++;
+       if ( script == &scriptstack[MAX_INCLUDES] ) {
+               Error( "script file exceeded MAX_INCLUDES" );
+       }
+       strcpy( script->filename, ExpandPath( filename ) );
+
+       size = LoadFile( script->filename, (void **)&script->buffer );
+
+       printf( "entering %s\n", script->filename );
+
+       script->line = 1;
+
+       script->script_p = script->buffer;
+       script->end_p = script->buffer + size;
+}
+
+
+/*
+   ==============
+   LoadScriptFile
+   ==============
+ */
+void LoadScriptFile( char *filename ){
+       script = scriptstack;
+       AddScriptToStack( filename );
+
+       endofscript = false;
+       tokenready = false;
+}
+
+
+/*
+   ==============
+   ParseFromMemory
+   ==============
+ */
+void ParseFromMemory( char *buffer, int size ){
+       script = scriptstack;
+       script++;
+       if ( script == &scriptstack[MAX_INCLUDES] ) {
+               Error( "script file exceeded MAX_INCLUDES" );
+       }
+       strcpy( script->filename, "memory buffer" );
+
+       script->buffer = buffer;
+       script->line = 1;
+       script->script_p = script->buffer;
+       script->end_p = script->buffer + size;
+
+       endofscript = false;
+       tokenready = false;
+}
+
+
+/*
+   ==============
+   UnGetScriptToken
+
+   Signals that the current token was not used, and should be reported
+   for the next GetScriptToken.  Note that
+
+   GetScriptToken (true);
+   UnGetScriptToken ();
+   GetScriptToken (false);
+
+   could cross a line boundary.
+   ==============
+ */
+void UnGetScriptToken( void ){
+       tokenready = true;
+}
+
+
+qboolean EndOfScript( qboolean crossline ){
+       if ( !crossline ) {
+               Error( "Line %i is incomplete\n",scriptline );
+       }
+
+       if ( !strcmp( script->filename, "memory buffer" ) ) {
+               endofscript = true;
+               return false;
+       }
+
+       free( script->buffer );
+       if ( script == scriptstack + 1 ) {
+               endofscript = true;
+               return false;
+       }
+       script--;
+       scriptline = script->line;
+       printf( "returning to %s\n", script->filename );
+       return GetScriptToken( crossline );
+}
+
+/*
+   ==============
+   GetScriptToken
+   ==============
+ */
+qboolean GetScriptToken( qboolean crossline ){
+       char    *token_p;
+
+       if ( tokenready ) {                       // is a token allready waiting?
+               tokenready = false;
+               return true;
+       }
+
+       if ( script->script_p >= script->end_p ) {
+               return EndOfScript( crossline );
+       }
+
+//
+// skip space
+//
+skipspace:
+       while ( *script->script_p <= 32 )
+       {
+               if ( script->script_p >= script->end_p ) {
+                       return EndOfScript( crossline );
+               }
+               if ( *script->script_p++ == '\n' ) {
+                       if ( !crossline ) {
+                               Error( "Line %i is incomplete\n",scriptline );
+                       }
+                       scriptline = script->line++;
+               }
+       }
+
+       if ( script->script_p >= script->end_p ) {
+               return EndOfScript( crossline );
+       }
+
+       // ; # // comments
+       if ( *script->script_p == ';' || *script->script_p == '#'
+                || ( script->script_p[0] == '/' && script->script_p[1] == '/' ) ) {
+               if ( !crossline ) {
+                       Error( "Line %i is incomplete\n",scriptline );
+               }
+               while ( *script->script_p++ != '\n' )
+                       if ( script->script_p >= script->end_p ) {
+                               return EndOfScript( crossline );
+                       }
+               goto skipspace;
+       }
+
+       // /* */ comments
+       if ( script->script_p[0] == '/' && script->script_p[1] == '*' ) {
+               if ( !crossline ) {
+                       Error( "Line %i is incomplete\n",scriptline );
+               }
+               script->script_p += 2;
+               while ( script->script_p[0] != '*' && script->script_p[1] != '/' )
+               {
+                       script->script_p++;
+                       if ( script->script_p >= script->end_p ) {
+                               return EndOfScript( crossline );
+                       }
+               }
+               script->script_p += 2;
+               goto skipspace;
+       }
+
+//
+// copy token
+//
+       token_p = token;
+
+       if ( *script->script_p == '"' ) {
+               // quoted token
+               script->script_p++;
+               while ( *script->script_p != '"' )
+               {
+                       *token_p++ = *script->script_p++;
+                       if ( script->script_p == script->end_p ) {
+                               break;
+                       }
+                       if ( token_p == &token[MAXTOKEN] ) {
+                               Error( "Token too large on line %i\n",scriptline );
+                       }
+               }
+               script->script_p++;
+       }
+       else{   // regular token
+               while ( *script->script_p > 32 && *script->script_p != ';' )
+               {
+                       *token_p++ = *script->script_p++;
+                       if ( script->script_p == script->end_p ) {
+                               break;
+                       }
+                       if ( token_p == &token[MAXTOKEN] ) {
+                               Error( "Token too large on line %i\n",scriptline );
+                       }
+               }
+       }
+
+       *token_p = 0;
+
+       if ( !strcmp( token, "$include" ) ) {
+               GetScriptToken( false );
+               AddScriptToStack( token );
+               return GetScriptToken( crossline );
+       }
+
+       return true;
+}
+
+
+/*
+   ==============
+   ScriptTokenAvailable
+
+   Returns true if there is another token on the line
+   ==============
+ */
+qboolean ScriptTokenAvailable( void ){
+       char    *search_p;
+
+       search_p = script->script_p;
+
+       if ( search_p >= script->end_p ) {
+               return false;
+       }
+
+       while ( *search_p <= 32 )
+       {
+               if ( *search_p == '\n' ) {
+                       return false;
+               }
+               search_p++;
+               if ( search_p == script->end_p ) {
+                       return false;
+               }
+
+       }
+
+       if ( *search_p == ';' ) {
+               return false;
+       }
+
+       return true;
+}
diff --git a/tools/heretic2/common/scriplib.h b/tools/heretic2/common/scriplib.h
new file mode 100644 (file)
index 0000000..8c441c8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// scriplib.h
+
+#ifndef __CMDLIB__
+#include "cmdlib.h"
+#endif
+
+#define MAXTOKEN    1024
+
+extern char token[MAXTOKEN];
+extern char    *scriptbuffer,*script_p,*scriptend_p;
+extern int grabbed;
+extern int scriptline;
+extern qboolean endofscript;
+
+
+void LoadScriptFile( char *filename );
+void ParseFromMemory( char *buffer, int size );
+
+qboolean GetScriptToken( qboolean crossline );
+void UnGetScriptToken( void );
+qboolean ScriptTokenAvailable( void );
diff --git a/tools/heretic2/common/threads.c b/tools/heretic2/common/threads.c
new file mode 100644 (file)
index 0000000..239226b
--- /dev/null
@@ -0,0 +1,606 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "globaldefs.h"
+
+#if !GDEF_OS_WINDOWS
+// The below define is necessary to use
+// pthreads extensions like pthread_mutexattr_settype
+#define _GNU_SOURCE
+#endif // !GDEF_OS_WINDOWS
+
+#include "cmdlib.h"
+#include "mathlib.h"
+#include "inout.h"
+#include "her2_threads.h"
+
+#define MAX_THREADS 64
+
+int dispatch;
+int workcount;
+int oldf;
+qboolean pacifier;
+
+qboolean threaded;
+
+/*
+   =============
+   GetThreadWork
+
+   =============
+ */
+int GetThreadWork( void ){
+       int r;
+       int f;
+
+       ThreadLock();
+
+       if ( dispatch == workcount ) {
+               ThreadUnlock();
+               return -1;
+       }
+
+       f = 10 * dispatch / workcount;
+       if ( f != oldf ) {
+               oldf = f;
+               if ( pacifier ) {
+                       Sys_Printf( "%i...", f );
+                       fflush( stdout );   /* ydnar */
+               }
+       }
+
+       r = dispatch;
+       dispatch++;
+       ThreadUnlock();
+
+       return r;
+}
+
+
+void ( *workfunction )( int );
+
+void ThreadWorkerFunction( int threadnum ){
+       int work;
+
+       while ( 1 )
+       {
+               work = GetThreadWork();
+               if ( work == -1 ) {
+                       break;
+               }
+               //Sys_Printf ("thread %i, work %i\n", threadnum, work);
+               workfunction( work );
+       }
+}
+
+void RunThreadsOnIndividual( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
+       if ( numthreads == -1 ) {
+               ThreadSetDefault();
+       }
+       workfunction = func;
+       RunThreadsOn( workcnt, showpacifier, ThreadWorkerFunction );
+}
+
+
+#if GDEF_OS_WINDOWS
+
+/*
+   ===================================================================
+
+   WIN32
+
+   ===================================================================
+ */
+
+#include <windows.h>
+
+// Setting default Threads to 1
+int numthreads = 1;
+CRITICAL_SECTION crit;
+static int enter;
+
+void ThreadSetDefault( void ){
+       SYSTEM_INFO info;
+
+       if ( numthreads == -1 ) { // not set manually
+               GetSystemInfo( &info );
+               numthreads = info.dwNumberOfProcessors;
+               if ( numthreads < 1 || numthreads > 32 ) {
+                       numthreads = 1;
+               }
+       }
+
+       Sys_Printf( "%i threads\n", numthreads );
+}
+
+
+void ThreadLock( void ){
+       if ( !threaded ) {
+               return;
+       }
+       EnterCriticalSection( &crit );
+       if ( enter ) {
+               Error( "Recursive ThreadLock\n" );
+       }
+       enter = 1;
+}
+
+void ThreadUnlock( void ){
+       if ( !threaded ) {
+               return;
+       }
+       if ( !enter ) {
+               Error( "ThreadUnlock without lock\n" );
+       }
+       enter = 0;
+       LeaveCriticalSection( &crit );
+}
+
+/*
+   =============
+   RunThreadsOn
+   =============
+ */
+void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
+       int threadid[MAX_THREADS];
+       HANDLE threadhandle[MAX_THREADS];
+       int i;
+       int start, end;
+
+       start = I_FloatTime();
+       dispatch = 0;
+       workcount = workcnt;
+       oldf = -1;
+       pacifier = showpacifier;
+       threaded = true;
+
+       //
+       // run threads in parallel
+       //
+       InitializeCriticalSection( &crit );
+
+       if ( numthreads == 1 ) { // use same thread
+               func( 0 );
+       }
+       else
+       {
+               for ( i = 0 ; i < numthreads ; i++ )
+               {
+                       threadhandle[i] = CreateThread(
+                               NULL,   // LPSECURITY_ATTRIBUTES lpsa,
+                           //0,                // DWORD cbStack,
+
+                           /* ydnar: cranking stack size to eliminate radiosity crash with 1MB stack on win32 */
+                               ( 4096 * 1024 ),
+
+                               (LPTHREAD_START_ROUTINE)func,   // LPTHREAD_START_ROUTINE lpStartAddr,
+                               (LPVOID)i,  // LPVOID lpvThreadParm,
+                               0,          //   DWORD fdwCreate,
+                               &threadid[i] );
+               }
+
+               for ( i = 0 ; i < numthreads ; i++ )
+                       WaitForSingleObject( threadhandle[i], INFINITE );
+       }
+       DeleteCriticalSection( &crit );
+
+       threaded = false;
+       end = I_FloatTime();
+       if ( pacifier ) {
+               Sys_Printf( " (%i)\n", end - start );
+       }
+}
+
+
+#elif GDEF_OS_OSF1
+
+/*
+   ===================================================================
+
+   OSF1
+
+   ===================================================================
+ */
+
+int numthreads = 4;
+
+void ThreadSetDefault( void ){
+       if ( numthreads == -1 ) { // not set manually
+               numthreads = 4;
+       }
+}
+
+
+#include <pthread.h>
+
+pthread_mutex_t *my_mutex;
+
+void ThreadLock( void ){
+       if ( my_mutex ) {
+               pthread_mutex_lock( my_mutex );
+       }
+}
+
+void ThreadUnlock( void ){
+       if ( my_mutex ) {
+               pthread_mutex_unlock( my_mutex );
+       }
+}
+
+
+/*
+   =============
+   RunThreadsOn
+   =============
+ */
+void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
+       int i;
+       pthread_t work_threads[MAX_THREADS];
+       pthread_addr_t status;
+       pthread_attr_t attrib;
+       pthread_mutexattr_t mattrib;
+       int start, end;
+
+       start = I_FloatTime();
+       dispatch = 0;
+       workcount = workcnt;
+       oldf = -1;
+       pacifier = showpacifier;
+       threaded = true;
+
+       if ( pacifier ) {
+               setbuf( stdout, NULL );
+       }
+
+       if ( !my_mutex ) {
+               my_mutex = safe_malloc( sizeof( *my_mutex ) );
+               if ( pthread_mutexattr_create( &mattrib ) == -1 ) {
+                       Error( "pthread_mutex_attr_create failed" );
+               }
+               if ( pthread_mutexattr_setkind_np( &mattrib, MUTEX_FAST_NP ) == -1 ) {
+                       Error( "pthread_mutexattr_setkind_np failed" );
+               }
+               if ( pthread_mutex_init( my_mutex, mattrib ) == -1 ) {
+                       Error( "pthread_mutex_init failed" );
+               }
+       }
+
+       if ( pthread_attr_create( &attrib ) == -1 ) {
+               Error( "pthread_attr_create failed" );
+       }
+       if ( pthread_attr_setstacksize( &attrib, 0x100000 ) == -1 ) {
+               Error( "pthread_attr_setstacksize failed" );
+       }
+
+       for ( i = 0 ; i < numthreads ; i++ )
+       {
+               if ( pthread_create( &work_threads[i], attrib
+                                                        , (pthread_startroutine_t)func, (pthread_addr_t)i ) == -1 ) {
+                       Error( "pthread_create failed" );
+               }
+       }
+
+       for ( i = 0 ; i < numthreads ; i++ )
+       {
+               if ( pthread_join( work_threads[i], &status ) == -1 ) {
+                       Error( "pthread_join failed" );
+               }
+       }
+
+       threaded = false;
+
+       end = I_FloatTime();
+       if ( pacifier ) {
+               Sys_Printf( " (%i)\n", end - start );
+       }
+}
+
+
+#elif GDEF_OS_IRIX
+
+/*
+   ===================================================================
+
+   IRIX
+
+   ===================================================================
+ */
+
+#include <task.h>
+#include <abi_mutex.h>
+#include <sys/types.h>
+#include <sys/prctl.h>
+
+int numthreads = -1;
+abilock_t lck;
+
+void ThreadSetDefault( void ){
+       if ( numthreads == -1 ) {
+               numthreads = prctl( PR_MAXPPROCS );
+       }
+       Sys_Printf( "%i threads\n", numthreads );
+       usconfig( CONF_INITUSERS, numthreads );
+}
+
+
+void ThreadLock( void ){
+       spin_lock( &lck );
+}
+
+void ThreadUnlock( void ){
+       release_lock( &lck );
+}
+
+
+/*
+   =============
+   RunThreadsOn
+   =============
+ */
+void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
+       int i;
+       int pid[MAX_THREADS];
+       int start, end;
+
+       start = I_FloatTime();
+       dispatch = 0;
+       workcount = workcnt;
+       oldf = -1;
+       pacifier = showpacifier;
+       threaded = true;
+
+       if ( pacifier ) {
+               setbuf( stdout, NULL );
+       }
+
+       init_lock( &lck );
+
+       for ( i = 0 ; i < numthreads - 1 ; i++ )
+       {
+               pid[i] = sprocsp( ( void ( * )( void *, size_t ) )func, PR_SALL, (void *)i
+                                                 , NULL, 0x200000 ); // 2 meg stacks
+               if ( pid[i] == -1 ) {
+                       perror( "sproc" );
+                       Error( "sproc failed" );
+               }
+       }
+
+       func( i );
+
+       for ( i = 0 ; i < numthreads - 1 ; i++ )
+               wait( NULL );
+
+       threaded = false;
+
+       end = I_FloatTime();
+       if ( pacifier ) {
+               Sys_Printf( " (%i)\n", end - start );
+       }
+}
+
+
+#elif GDEF_OS_LINUX || GDEF_OS_BSD || GDEF_OS_MACOS
+
+/*
+   =======================================================================
+
+   Linux pthreads
+
+   =======================================================================
+ */
+
+// Setting default Threads to 1
+int numthreads = 1;
+
+void ThreadSetDefault( void ){
+       if ( numthreads == -1 ) { // not set manually
+               /* default to one thread, only multi-thread when specifically told to */
+               numthreads = 1;
+       }
+       if ( numthreads > 1 ) {
+               Sys_Printf( "threads: %d\n", numthreads );
+       }
+}
+
+#include <pthread.h>
+
+typedef struct pt_mutex_s
+{
+       pthread_t       *owner;
+       pthread_mutex_t a_mutex;
+       pthread_cond_t cond;
+       unsigned int lock;
+} pt_mutex_t;
+
+pt_mutex_t global_lock;
+
+void ThreadLock( void ){
+       pt_mutex_t *pt_mutex = &global_lock;
+
+       if ( !threaded ) {
+               return;
+       }
+
+       pthread_mutex_lock( &pt_mutex->a_mutex );
+       if ( pthread_equal( pthread_self(), (pthread_t)&pt_mutex->owner ) ) {
+               pt_mutex->lock++;
+       }
+       else
+       {
+               if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
+                       pt_mutex->owner = (pthread_t *)pthread_self();
+                       pt_mutex->lock  = 1;
+               }
+               else
+               {
+                       while ( 1 )
+                       {
+                               pthread_cond_wait( &pt_mutex->cond, &pt_mutex->a_mutex );
+                               if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
+                                       pt_mutex->owner = (pthread_t *)pthread_self();
+                                       pt_mutex->lock  = 1;
+                                       break;
+                               }
+                       }
+               }
+       }
+       pthread_mutex_unlock( &pt_mutex->a_mutex );
+}
+
+void ThreadUnlock( void ){
+       pt_mutex_t *pt_mutex = &global_lock;
+
+       if ( !threaded ) {
+               return;
+       }
+
+       pthread_mutex_lock( &pt_mutex->a_mutex );
+       pt_mutex->lock--;
+
+       if ( pt_mutex->lock == 0 ) {
+               pt_mutex->owner = NULL;
+               pthread_cond_signal( &pt_mutex->cond );
+       }
+
+       pthread_mutex_unlock( &pt_mutex->a_mutex );
+}
+
+void recursive_mutex_init( pthread_mutexattr_t attribs ){
+       pt_mutex_t *pt_mutex = &global_lock;
+
+       pt_mutex->owner = NULL;
+       if ( pthread_mutex_init( &pt_mutex->a_mutex, &attribs ) != 0 ) {
+               Error( "pthread_mutex_init failed\n" );
+       }
+       if ( pthread_cond_init( &pt_mutex->cond, NULL ) != 0 ) {
+               Error( "pthread_cond_init failed\n" );
+       }
+
+       pt_mutex->lock = 0;
+}
+
+/*
+   =============
+   RunThreadsOn
+   =============
+ */
+void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
+       pthread_mutexattr_t mattrib;
+       pthread_t work_threads[MAX_THREADS];
+
+       int start, end;
+       int i = 0, status = 0;
+
+       start     = I_FloatTime();
+       pacifier  = showpacifier;
+
+       dispatch  = 0;
+       oldf      = -1;
+       workcount = workcnt;
+
+       if ( numthreads == 1 ) {
+               func( 0 );
+       }
+       else
+       {
+               threaded  = true;
+
+               if ( pacifier ) {
+                       setbuf( stdout, NULL );
+               }
+
+               if ( pthread_mutexattr_init( &mattrib ) != 0 ) {
+                       Error( "pthread_mutexattr_init failed" );
+               }
+               if ( pthread_mutexattr_settype( &mattrib, PTHREAD_MUTEX_ERRORCHECK ) != 0 ) {
+                       Error( "pthread_mutexattr_settype failed" );
+               }
+               recursive_mutex_init( mattrib );
+
+               for ( i = 0 ; i < numthreads ; i++ )
+               {
+                       /* Default pthread attributes: joinable & non-realtime scheduling */
+                       if ( pthread_create( &work_threads[i], NULL, (void*)func, (void*)i ) != 0 ) {
+                               Error( "pthread_create failed" );
+                       }
+               }
+               for ( i = 0 ; i < numthreads ; i++ )
+               {
+                       if ( pthread_join( work_threads[i], (void **)&status ) != 0 ) {
+                               Error( "pthread_join failed" );
+                       }
+               }
+               pthread_mutexattr_destroy( &mattrib );
+               threaded = false;
+       }
+
+       end = I_FloatTime();
+       if ( pacifier ) {
+               Sys_Printf( " (%i)\n", end - start );
+       }
+}
+
+
+#else // UNKNOWN OS
+
+/*
+   =======================================================================
+
+   SINGLE THREAD
+
+   =======================================================================
+ */
+
+int numthreads = 1;
+
+void ThreadSetDefault( void ){
+       numthreads = 1;
+}
+
+void ThreadLock( void ){
+}
+
+void ThreadUnlock( void ){
+}
+
+/*
+   =============
+   RunThreadsOn
+   =============
+ */
+void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
+       int i;
+       int start, end;
+
+       dispatch = 0;
+       workcount = workcnt;
+       oldf = -1;
+       pacifier = showpacifier;
+       start = I_FloatTime();
+       func( 0 );
+
+       end = I_FloatTime();
+       if ( pacifier ) {
+               Sys_Printf( " (%i)\n", end - start );
+       }
+}
+
+#endif // UNKNOWN OS
diff --git a/tools/heretic2/common/token.c b/tools/heretic2/common/token.c
new file mode 100644 (file)
index 0000000..632cfe4
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+//**************************************************************************
+//**
+//** token.c
+//**
+//**************************************************************************
+
+// HEADER FILES ------------------------------------------------------------
+
+#include "token.h"
+#include "inout.h"
+
+// MACROS ------------------------------------------------------------------
+
+// TYPES -------------------------------------------------------------------
+
+typedef enum
+{
+       CHR_EOF,
+       CHR_LETTER,
+       CHR_NUMBER,
+       CHR_QUOTE,
+       CHR_SPECIAL
+} chr_t;
+
+// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
+
+// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
+
+// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
+
+static void ProcessLetterToken( void );
+static void ProcessNumberToken( void );
+static void ProcessQuoteToken( void );
+static void ProcessSpecialToken( void );
+static qboolean CheckForKeyword( void );
+static void NextChr( void );
+
+// EXTERNAL DATA DECLARATIONS ----------------------------------------------
+
+// PUBLIC DATA DEFINITIONS -------------------------------------------------
+
+tokenType_t tk_Token;
+int tk_Line;
+int tk_IntNumber;
+float tk_FloatNumber;
+char *tk_String;
+char tk_SourceName[MAX_FILE_NAME_LENGTH];
+
+// PRIVATE DATA DEFINITIONS ------------------------------------------------
+
+static char Chr;
+static char *FileStart;
+static char *FilePtr;
+static char *FileEnd;
+static qboolean SourceOpen;
+static char ASCIIToChrCode[256];
+static char TokenStringBuffer[MAX_QUOTED_LENGTH];
+static qboolean IncLineNumber;
+static char TempBuffer[2048];
+
+static struct
+{
+       char *name;
+       tokenType_t token;
+} Keywords[] =
+{
+       "model",            TK_MODEL,
+       "mesh",             TK_MESH,
+       "vertices",         TK_VERTICES,
+       "edges",            TK_EDGES,
+       "position",         TK_POSITION,
+       "polygons",         TK_POLYGONS,
+       "nodes",            TK_NODES,
+       "rotation",         TK_ROTATION,
+       "scaling",          TK_SCALING,
+       "translation",      TK_TRANSLATION,
+       "vertex",           TK_VERTEX,
+       "HRCH",             TK_HRCH,
+       "Softimage",        TK_SOFTIMAGE,
+       "material",         TK_MATERIAL,
+       "spline",           TK_SPLINE,
+
+       "Named",            TK_C_NAMED,
+       "object",           TK_OBJECT,
+       "Tri",              TK_C_TRI,
+       "Vertices",         TK_C_VERTICES,
+       "Faces",            TK_C_FACES,
+       "Vertex",           TK_C_VERTEX,
+       "list",             TK_LIST,
+       "Face",             TK_C_FACE,
+
+       "Hexen",            TK_C_HEXEN,
+       "Triangles",        TK_C_TRIANGLES,
+       "Version",          TK_C_VERSION,
+       "faces",            TK_FACES,
+       "face",             TK_FACE,
+       "origin",           TK_ORIGIN,
+
+       "DK_clusters",      TK_CLUSTERS,
+       "DK_cluster_ncvs",  TK_NUM_CLUSTER_VERTICES,
+       "name",             TK_NAME,
+       "DK_cluster_name",  TK_CLUSTER_NAME,
+       "DK_cluster_state", TK_CLUSTER_STATE,
+
+       "actor_data",       TK_ACTOR_DATA,
+       "uvTexture",        TK_UVTEXTURE,
+
+       NULL,               -1
+};
+
+static char *TokenNames[] =
+{
+       "<nothing>",
+       "<unknown_char>",
+       "<EOF>",
+       "<identifier>",
+       "<string>",
+       "<int_number>",
+       "<float_number>",
+       "(",
+       ")",
+       "{",
+       "}",
+       "[",
+       "]",
+       ":",
+       "mesh",
+       "model",
+       "nodes",
+       "rotation",
+       "scaling",
+       "translation",
+       "polygons",
+       "position",
+       "vertex",
+       "vertices",
+       "HRCH",
+       "Softimage"
+};
+
+// CODE --------------------------------------------------------------------
+
+//==========================================================================
+//
+// TK_Init
+//
+//==========================================================================
+
+void TK_Init( void ){
+       int i;
+
+       for ( i = 0; i < 256; i++ )
+       {
+               ASCIIToChrCode[i] = CHR_SPECIAL;
+       }
+       for ( i = '0'; i <= '9'; i++ )
+       {
+               ASCIIToChrCode[i] = CHR_NUMBER;
+       }
+       for ( i = 'A'; i <= 'Z'; i++ )
+       {
+               ASCIIToChrCode[i] = CHR_LETTER;
+       }
+       for ( i = 'a'; i <= 'z'; i++ )
+       {
+               ASCIIToChrCode[i] = CHR_LETTER;
+       }
+       ASCIIToChrCode[ASCII_QUOTE] = CHR_QUOTE;
+       ASCIIToChrCode[ASCII_UNDERSCORE] = CHR_LETTER;
+       ASCIIToChrCode[EOF_CHARACTER] = CHR_EOF;
+       tk_String = TokenStringBuffer;
+       IncLineNumber = FALSE;
+       SourceOpen = FALSE;
+}
+
+//==========================================================================
+//
+// TK_OpenSource
+//
+//==========================================================================
+
+void TK_OpenSource( char *fileName ){
+       int size;
+
+       TK_CloseSource();
+       size = LoadFile( fileName, (void **)&FileStart );
+       strcpy( tk_SourceName, fileName );
+       SourceOpen = TRUE;
+       FileEnd = FileStart + size;
+       FilePtr = FileStart;
+       tk_Line = 1;
+       tk_Token = TK_NONE;
+       NextChr();
+}
+
+//==========================================================================
+//
+// TK_CloseSource
+//
+//==========================================================================
+
+void TK_CloseSource( void ){
+       if ( SourceOpen ) {
+               free( FileStart );
+               SourceOpen = FALSE;
+       }
+}
+
+//==========================================================================
+//
+// TK_Fetch
+//
+//==========================================================================
+
+tokenType_t TK_Fetch( void ){
+       while ( Chr == ASCII_SPACE )
+       {
+               NextChr();
+       }
+       if ( Chr == '-' ) {
+               ProcessNumberToken();
+       }
+       else{switch ( ASCIIToChrCode[(byte)Chr] )
+                {
+                case CHR_EOF:
+                        tk_Token = TK_EOF;
+                        break;
+                case CHR_LETTER:
+                        ProcessLetterToken();
+                        break;
+                case CHR_NUMBER:
+                        ProcessNumberToken();
+                        break;
+                case CHR_QUOTE:
+                        ProcessQuoteToken();
+                        break;
+                default:
+                        ProcessSpecialToken();
+                        break;
+                }}
+       return tk_Token;
+}
+
+//==========================================================================
+//
+// TK_Require
+//
+//==========================================================================
+
+void TK_Require( tokenType_t tokType ){
+       if ( tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER ) {
+               tk_FloatNumber = (float)tk_IntNumber;
+               tk_Token = TK_FLOATNUMBER;
+               return;
+       }
+       if ( tk_Token != tokType ) {
+               Error( "File '%s', line %d:\nExpected '%s', found '%s'.\n",
+                          tk_SourceName, tk_Line, TokenNames[tokType],
+                          TokenNames[tk_Token] );
+       }
+}
+
+void TK_FetchRequire( tokenType_t tokType ){
+       TK_Fetch();
+       TK_Require( tokType );
+}
+
+tokenType_t TK_RequireFetch( tokenType_t tokType ){
+       TK_Require( tokType );
+       return TK_Fetch();
+}
+
+tokenType_t TK_FetchRequireFetch( tokenType_t tokType ){
+       TK_Fetch();
+       TK_Require( tokType );
+       return TK_Fetch();
+}
+
+tokenType_t TK_Beyond( tokenType_t tokType ){
+       while ( tk_Token != tokType )
+       {
+               if ( TK_Fetch() == TK_EOF ) {
+                       Error( "File '%s':\nCould not find token '%s'.\n",       // FIXME: TokenNames table not big enuff
+                                  tk_SourceName, TokenNames[tokType] );
+               }
+       }
+       return TK_Fetch();
+}
+
+void TK_BeyondRequire( tokenType_t bTok, tokenType_t rTok ){
+       TK_Beyond( bTok );
+       TK_Require( rTok );
+}
+
+tokenType_t TK_Search( tokenType_t tokType ){
+       while ( tk_Token != tokType )
+       {
+               if ( TK_Fetch() == TK_EOF ) {
+                       return TK_EOF;
+               }
+       }
+       return TK_Fetch();
+}
+
+tokenType_t TK_Get( tokenType_t tokType ){
+       while ( tk_Token != tokType )
+       {
+               if ( TK_Fetch() == TK_EOF ) {
+                       Error( "File '%s':\nCould not find token '%s'.\n",
+                                  tk_SourceName, TokenNames[tokType] );
+               }
+       }
+       return tk_Token;
+}
+
+//==========================================================================
+//
+// ProcessLetterToken
+//
+//==========================================================================
+
+static void ProcessLetterToken( void ){
+       int i;
+       char *text;
+
+       i = 0;
+       text = TokenStringBuffer;
+       while ( ASCIIToChrCode[(byte)Chr] == CHR_LETTER
+                       || ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
+       {
+               if ( ++i == MAX_IDENTIFIER_LENGTH ) {
+                       Error( "File '%s', line %d:\nIdentifier too long.\n",
+                                  tk_SourceName, tk_Line );
+               }
+               *text++ = Chr;
+               NextChr();
+       }
+       *text = 0;
+       if ( CheckForKeyword() == FALSE ) {
+               tk_Token = TK_IDENTIFIER;
+       }
+}
+
+//==========================================================================
+//
+// CheckForKeyword
+//
+//==========================================================================
+
+static qboolean CheckForKeyword( void ){
+       int i;
+
+       for ( i = 0; Keywords[i].name != NULL; i++ )
+       {
+               if ( strcmp( tk_String, Keywords[i].name ) == 0 ) {
+                       tk_Token = Keywords[i].token;
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+//==========================================================================
+//
+// ProcessNumberToken
+//
+//==========================================================================
+
+static void ProcessNumberToken( void ){
+       char *buffer;
+
+       buffer = TempBuffer;
+       *buffer++ = Chr;
+       NextChr();
+       while ( ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
+       {
+               *buffer++ = Chr;
+               NextChr();
+       }
+       if ( Chr == '.' ) { // Float
+               *buffer++ = Chr;
+               NextChr(); // Skip period
+               while ( ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
+               {
+                       *buffer++ = Chr;
+                       NextChr();
+               }
+               *buffer = 0;
+               tk_FloatNumber = (float)atof( TempBuffer );
+               tk_Token = TK_FLOATNUMBER;
+               return;
+       }
+
+       // Integer
+       *buffer = 0;
+       tk_IntNumber = atoi( TempBuffer );
+       tk_Token = TK_INTNUMBER;
+}
+
+//==========================================================================
+//
+// ProcessQuoteToken
+//
+//==========================================================================
+
+static void ProcessQuoteToken( void ){
+       int i;
+       char *text;
+
+       i = 0;
+       text = TokenStringBuffer;
+       NextChr();
+       while ( Chr != ASCII_QUOTE )
+       {
+               if ( Chr == EOF_CHARACTER ) {
+                       Error( "File '%s', line %d:\n<EOF> inside string.\n",
+                                  tk_SourceName, tk_Line );
+               }
+               if ( ++i > MAX_QUOTED_LENGTH - 1 ) {
+                       Error( "File '%s', line %d:\nString literal too long.\n",
+                                  tk_SourceName, tk_Line );
+               }
+               *text++ = Chr;
+               NextChr();
+       }
+       *text = 0;
+       NextChr();
+       tk_Token = TK_STRING;
+}
+
+//==========================================================================
+//
+// ProcessSpecialToken
+//
+//==========================================================================
+
+static void ProcessSpecialToken( void ){
+       char c;
+
+       c = Chr;
+       NextChr();
+       switch ( c )
+       {
+       case '(':
+               tk_Token = TK_LPAREN;
+               break;
+       case ')':
+               tk_Token = TK_RPAREN;
+               break;
+       case '{':
+               tk_Token = TK_LBRACE;
+               break;
+       case '}':
+               tk_Token = TK_RBRACE;
+               break;
+       case '[':
+               tk_Token = TK_LBRACKET;
+               break;
+       case ']':
+               tk_Token = TK_RBRACKET;
+               break;
+       case ':':
+               tk_Token = TK_COLON;
+               break;
+       default:
+               tk_Token = TK_UNKNOWNCHAR;
+               break;
+       }
+}
+
+//==========================================================================
+//
+// NextChr
+//
+//==========================================================================
+
+static void NextChr( void ){
+       if ( FilePtr >= FileEnd ) {
+               Chr = EOF_CHARACTER;
+               return;
+       }
+       if ( IncLineNumber == TRUE ) {
+               tk_Line++;
+               IncLineNumber = FALSE;
+       }
+       Chr = *FilePtr++;
+       if ( Chr < ASCII_SPACE ) {
+               if ( Chr == '\n' ) {
+                       IncLineNumber = TRUE;
+               }
+               Chr = ASCII_SPACE;
+       }
+}
diff --git a/tools/heretic2/common/token.h b/tools/heretic2/common/token.h
new file mode 100644 (file)
index 0000000..6dca1a1
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+//**************************************************************************
+//**
+//** token.h
+//**
+//**************************************************************************
+
+#ifndef __TOKEN_H__
+#define __TOKEN_H__
+
+#include "cmdlib.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef YES
+#define YES 1
+#endif
+#ifndef NO
+#define NO 0
+#endif
+#define ASCII_SPACE 32
+#define ASCII_QUOTE 34
+#define ASCII_UNDERSCORE 95
+#define EOF_CHARACTER 127
+#define MAX_IDENTIFIER_LENGTH 64
+#define MAX_QUOTED_LENGTH 1024
+#define MAX_FILE_NAME_LENGTH 1024
+
+typedef enum
+{
+       TK_NONE,
+       TK_UNKNOWNCHAR,
+       TK_EOF,
+       TK_IDENTIFIER,          // VALUE: (char *) tk_String
+       TK_STRING,              // VALUE: (char *) tk_String
+       TK_INTNUMBER,           // VALUE: (int) tk_IntNumber
+       TK_FLOATNUMBER,         // VALUE: (float) tk_FloatNumber
+       TK_LPAREN,
+       TK_RPAREN,
+       TK_LBRACE,
+       TK_RBRACE,              // 10
+       TK_LBRACKET,
+       TK_RBRACKET,
+       TK_COLON,
+       TK_MESH,
+       TK_MODEL,               // 15
+       TK_NODES,
+       TK_ROTATION,
+       TK_SCALING,
+       TK_TRANSLATION,
+       TK_POLYGONS,            // 20
+       TK_POSITION,
+       TK_VERTEX,
+       TK_VERTICES,
+       TK_EDGES,
+       TK_HRCH,                // 25
+       TK_SOFTIMAGE,
+       TK_MATERIAL,
+       TK_SPLINE,              // 28
+
+       TK_C_NAMED,
+       TK_OBJECT,              // 30
+       TK_C_TRI,
+       TK_C_VERTICES,
+       TK_C_FACES,
+       TK_C_VERTEX,
+       TK_LIST,                // 35
+       TK_C_FACE,
+
+       TK_C_HEXEN,
+       TK_C_TRIANGLES,
+       TK_C_VERSION,
+       TK_FACES,               // 40
+       TK_FACE,
+       TK_ORIGIN,
+
+       TK_CLUSTERS,
+       TK_NUM_CLUSTER_VERTICES,
+       TK_NAME,                // 45
+       TK_CLUSTER_NAME,
+       TK_CLUSTER_STATE,
+
+       TK_ACTOR_DATA,
+       TK_UVTEXTURE,
+} tokenType_t;
+
+void TK_Init( void );
+void TK_OpenSource( char *fileName );
+void TK_CloseSource( void );
+tokenType_t TK_Fetch( void );
+void TK_Require( tokenType_t tokType );
+void TK_FetchRequire( tokenType_t tokType );
+tokenType_t TK_RequireFetch( tokenType_t tokType );
+tokenType_t TK_FetchRequireFetch( tokenType_t tokType );
+tokenType_t TK_Beyond( tokenType_t tokType );
+void TK_BeyondRequire( tokenType_t bTok, tokenType_t rTok );
+tokenType_t TK_Search( tokenType_t tokType );
+tokenType_t TK_Get( tokenType_t tokType );
+
+extern tokenType_t tk_Token;
+extern int tk_Line;
+extern int tk_IntNumber;
+extern float tk_FloatNumber;
+extern char *tk_String;
+extern char tk_SourceName[MAX_FILE_NAME_LENGTH];
+
+#endif
diff --git a/tools/heretic2/common/trilib.c b/tools/heretic2/common/trilib.c
new file mode 100644 (file)
index 0000000..29acab6
--- /dev/null
@@ -0,0 +1,1039 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+//
+// trilib.c: library for loading triangles from an Alias triangle file
+//
+
+#include <stdio.h>
+#include "cmdlib.h"
+#include "inout.h"
+#include "mathlib.h"
+#include "trilib.h"
+#include "token.h"
+#include "l3dslib.h"
+#include "fmodel.h"
+#if 1
+#include "qd_skeletons.h"
+#endif
+
+// on disk representation of a face
+#define FLOAT_START 99999.0
+#define FLOAT_END   -FLOAT_START
+#define MAGIC       123322
+#ifndef M_PI
+  #define M_PI      3.14159265
+#endif
+
+float FixHTRRotateX = 0.0;
+float FixHTRRotateY = 0.0;
+float FixHTRRotateZ = 0.0;
+float FixHTRTranslateX = 0.0;
+float FixHTRTranslateY = 0.0;
+float FixHTRTranslateZ = 0.0;
+
+//#define NOISY 1
+
+typedef struct {
+       float v[3];
+} vector;
+
+typedef struct
+{
+       vector n;    /* normal */
+       vector p;    /* point */
+       vector c;    /* color */
+       float u;     /* u */
+       float v;     /* v */
+} aliaspoint_t;
+
+typedef struct {
+       aliaspoint_t pt[3];
+} tf_triangle;
+
+
+void ByteSwapTri( tf_triangle *tri ){
+       int i;
+
+       for ( i = 0 ; i < sizeof( tf_triangle ) / 4 ; i++ )
+       {
+               ( (int *)tri )[i] = BigLong( ( (int *)tri )[i] );
+       }
+}
+
+void LoadTRI( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **nodesList, int *num_mesh_nodes ){
+       FILE        *input;
+       float start;
+       char name[256], tex[256];
+       int i, count, magic;
+       tf_triangle tri;
+       triangle_t  *ptri;
+       int iLevel;
+       int exitpattern;
+       float t;
+
+       if ( nodesList ) {
+               *num_mesh_nodes = 0;
+               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
+       }
+
+       t = -FLOAT_START;
+       *( (unsigned char *)&exitpattern + 0 ) = *( (unsigned char *)&t + 3 );
+       *( (unsigned char *)&exitpattern + 1 ) = *( (unsigned char *)&t + 2 );
+       *( (unsigned char *)&exitpattern + 2 ) = *( (unsigned char *)&t + 1 );
+       *( (unsigned char *)&exitpattern + 3 ) = *( (unsigned char *)&t + 0 );
+
+       if ( ( input = fopen( filename, "rb" ) ) == 0 ) {
+               Error( "reader: could not open file '%s'", filename );
+       }
+
+       iLevel = 0;
+
+       fread( &magic, sizeof( int ), 1, input );
+       if ( BigLong( magic ) != MAGIC ) {
+               Error( "%s is not a Alias object separated triangle file, magic number is wrong.", filename );
+       }
+
+       ptri = malloc( MAXTRIANGLES * sizeof( triangle_t ) );
+
+       *pptri = ptri;
+
+       while ( feof( input ) == 0 ) {
+               if ( fread( &start,  sizeof( float ), 1, input ) < 1 ) {
+                       break;
+               }
+               *(int *)&start = BigLong( *(int *)&start );
+               if ( *(int *)&start != exitpattern ) {
+                       if ( start == FLOAT_START ) {
+                               /* Start of an object or group of objects. */
+                               i = -1;
+                               do {
+                                       /* There are probably better ways to read a string from */
+                                       /* a file, but this does allow you to do error checking */
+                                       /* (which I'm not doing) on a per character basis.      */
+                                       ++i;
+                                       fread( &( name[i] ), sizeof( char ), 1, input );
+                               } while ( name[i] != '\0' );
+
+//                             indent();
+//                             fprintf(stdout,"OBJECT START: %s\n",name);
+                               fread( &count, sizeof( int ), 1, input );
+                               count = BigLong( count );
+                               ++iLevel;
+                               if ( count != 0 ) {
+//                                     indent();
+//                                     fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);
+
+                                       i = -1;
+                                       do {
+                                               ++i;
+                                               fread( &( tex[i] ), sizeof( char ), 1, input );
+                                       } while ( tex[i] != '\0' );
+
+//                                     indent();
+//                                     fprintf(stdout,"  Object texture name: '%s'\n",tex);
+                               }
+
+                               /* Else (count == 0) this is the start of a group, and */
+                               /* no texture name is present. */
+                       }
+                       else if ( start == FLOAT_END ) {
+                               /* End of an object or group. Yes, the name should be */
+                               /* obvious from context, but it is in here just to be */
+                               /* safe and to provide a little extra information for */
+                               /* those who do not wish to write a recursive reader. */
+                               /* Mia culpa. */
+                               --iLevel;
+                               i = -1;
+                               do {
+                                       ++i;
+                                       fread( &( name[i] ), sizeof( char ), 1, input );
+                               } while ( name[i] != '\0' );
+
+//                             indent();
+//                             fprintf(stdout,"OBJECT END: %s\n",name);
+                               continue;
+                       }
+               }
+
+//
+// read the triangles
+//
+               for ( i = 0; i < count; ++i ) {
+                       int j;
+
+                       fread( &tri, sizeof( tf_triangle ), 1, input );
+                       ByteSwapTri( &tri );
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               int k;
+
+                               for ( k = 0 ; k < 3 ; k++ )
+                               {
+                                       ptri->verts[j][k] = tri.pt[j].p.v[k];
+                               }
+                       }
+
+                       ptri++;
+
+                       if ( ( ptri - *pptri ) >= MAXTRIANGLES ) {
+                               Error( "Error: too many triangles; increase MAXTRIANGLES\n" );
+                       }
+               }
+       }
+
+       *numtriangles = ptri - *pptri;
+
+       fclose( input );
+
+       DefaultNodesList( nodesList,num_mesh_nodes,numtriangles );
+}
+
+
+//==========================================================================
+//
+// LoadHRC
+//
+//==========================================================================
+
+float scaling[3];
+float rotation[3];
+float translation[3];
+static char     *hrc_name;
+
+struct
+{
+       float v[3];
+} vList[8192];
+
+void HandleHRCModel( triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,
+                                        int ActiveNode, int Depth, int numVerts ){
+       void ReadHRCClusterList( mesh_node_t *meshNode, int baseIndex );
+
+       int i, j;
+       int vertexCount;
+       int triCount;
+       triangle_t  *tList;
+       mesh_node_t *meshNode;
+       float x, y, z;
+       float x2, y2, z2;
+       float rx, ry, rz;
+       tokenType_t nextToken;
+       float orig_scaling[3];
+       float orig_rotation[3];
+       float orig_translation[3];
+       int start_tri;
+       int pos,bit;
+       int vertIndexBase;
+
+       // Update Node Info
+       if ( nodesList ) {
+               TK_BeyondRequire( TK_NAME, TK_STRING );
+
+               if ( Depth == 0 || tk_String[0] == '_' ) { // Root
+                       ActiveNode = *num_mesh_nodes;
+                       ( *num_mesh_nodes )++;
+                       if ( ( *num_mesh_nodes ) > MAX_FM_MESH_NODES ) {
+                               Error( "Too many mesh nodes in file %s\n", hrc_name );
+                       }
+                       meshNode = &( *nodesList )[ActiveNode];
+
+//                     memset(meshNode, 0, sizeof(mesh_node_t));
+                       strcpy( meshNode->name, tk_String );
+
+                       memset( meshNode->tris, 0, sizeof( meshNode->tris ) );
+                       memset( meshNode->verts, 0, sizeof( meshNode->verts ) );
+
+                       meshNode->start_glcmds = 0;
+                       meshNode->num_glcmds = 0;
+                       vertIndexBase = 0;
+               }
+               else
+               {   // Childs under the children
+                       meshNode = &( *nodesList )[ActiveNode];
+                       vertIndexBase = numVerts;
+               }
+       }
+       else
+       {
+               meshNode = NULL;
+       }
+
+
+       // Get the scaling, rotation, and translation values
+       TK_Beyond( TK_SCALING );
+       for ( i = 0; i < 3; i++ )
+       {
+               orig_scaling[i] = scaling[i];
+
+               TK_Require( TK_FLOATNUMBER );
+               scaling[i] *= tk_FloatNumber;
+
+               TK_Fetch();
+       }
+       TK_Beyond( TK_ROTATION );
+       for ( i = 0; i < 3; i++ )
+       {
+               orig_rotation[i] = rotation[i];
+
+               TK_Require( TK_FLOATNUMBER );
+               rotation[i] = tk_FloatNumber;
+
+               TK_Fetch();
+       }
+       TK_Beyond( TK_TRANSLATION );
+       for ( i = 0; i < 3; i++ )
+       {
+               orig_translation[i] = translation[i];
+
+               TK_Require( TK_FLOATNUMBER );
+               translation[i] += tk_FloatNumber;
+
+               TK_Fetch();
+       }
+
+       rx = ( ( rotation[0] - 90.0 ) / 360.0 ) * 2.0 * M_PI;
+       ry = ( rotation[2] / 360.0 ) * 2.0 * M_PI;
+       rz = ( rotation[1] / 360.0 ) * 2.0 * M_PI;
+
+       // rjr - might not work if there an item doesn't have a mesh
+       nextToken = tk_Token;
+       if ( nextToken == TK_ACTOR_DATA ) {
+               while ( nextToken != TK_MODEL && nextToken != TK_RBRACE )
+               {
+                       nextToken = TK_Fetch();
+               }
+       }
+
+       while ( nextToken == TK_SPLINE )
+       {   // spline node has two right braces
+               nextToken = TK_Beyond( TK_RBRACE );
+               nextToken = TK_Beyond( TK_RBRACE );
+       }
+
+       while ( nextToken == TK_MATERIAL )
+       {
+               nextToken = TK_Beyond( TK_RBRACE );
+       }
+
+       while ( nextToken == TK_MODEL )
+       {
+               HandleHRCModel( triList,triangleCount,nodesList,num_mesh_nodes,ActiveNode, Depth + 1, 0 );
+
+               nextToken = TK_Fetch();
+       }
+
+       if ( nextToken == TK_MESH ) {
+               // Get all the tri and vertex info
+               TK_BeyondRequire( TK_VERTICES, TK_INTNUMBER );
+               vertexCount = tk_IntNumber;
+               for ( i = 0; i < vertexCount; i++ )
+               {
+                       TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
+                       if ( tk_IntNumber != i ) {
+                               Error( "File '%s', line %d:\nVertex index mismatch.\n",
+                                          tk_SourceName, tk_Line );
+                       }
+                       TK_Beyond( TK_POSITION );
+                       // Apply the scaling, rotation, and translation in the order
+                       // specified in the HRC file.  This could be wrong.
+                       TK_Require( TK_FLOATNUMBER );
+                       x = tk_FloatNumber * scaling[0];
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       y = tk_FloatNumber * scaling[1];
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       z = tk_FloatNumber * scaling[2];
+
+                       y2 = y * cos( rx ) + z*sin( rx );
+                       z2 = -y*sin( rx ) + z*cos( rx );
+                       y = y2;
+                       z = z2;
+
+                       x2 = x * cos( ry ) - z*sin( ry );
+                       z2 = x * sin( ry ) + z*cos( ry );
+                       x = x2;
+                       z = z2;
+
+                       x2 = x * cos( rz ) + y*sin( rz );
+                       y2 = -x*sin( rz ) + y*cos( rz );
+                       x = x2;
+                       y = y2;
+
+                       vList[i].v[0] = x + translation[0];
+                       vList[i].v[1] = y - translation[2];
+                       vList[i].v[2] = z + translation[1];
+               }
+               TK_BeyondRequire( TK_POLYGONS, TK_INTNUMBER );
+               triCount = tk_IntNumber;
+               if ( triCount >= MAXTRIANGLES ) {
+                       Error( "Too many triangles in file %s\n", hrc_name );
+               }
+
+               start_tri = *triangleCount;
+               *triangleCount += triCount;
+
+               tList = *triList;
+
+               for ( i = 0; i < triCount; i++ )
+               {
+                       if ( meshNode ) { // Update the node
+                               pos = ( i + start_tri ) >> 3;
+                               bit = 1 << ( ( i + start_tri ) & 7 );
+                               meshNode->tris[pos] |= bit;
+                       }
+
+                       TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
+                       if ( tk_IntNumber != i ) {
+                               Error( "File '%s', line %d:\nTriangle index mismatch.\n",
+                                          tk_SourceName, tk_Line );
+                       }
+                       TK_BeyondRequire( TK_NODES, TK_INTNUMBER );
+                       if ( tk_IntNumber != 3 ) {
+                               Error( "File '%s', line %d:\nBad polygon vertex count: %d.",
+                                          tk_SourceName, tk_Line, tk_IntNumber );
+                       }
+                       tList[i + start_tri].HasUV = true;
+                       for ( j = 0; j < 3; j++ )
+                       {
+                               TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
+                               if ( tk_IntNumber != j ) {
+                                       Error( "File '%s', line %d:\nTriangle vertex index"
+                                                  " mismatch.  %d should be %d\n", tk_SourceName, tk_Line,
+                                                  tk_IntNumber, j );
+                               }
+                               TK_BeyondRequire( TK_VERTEX, TK_INTNUMBER );
+
+                               tList[i + start_tri].verts[2 - j][0] = vList[tk_IntNumber].v[0];
+                               tList[i + start_tri].verts[2 - j][1] = vList[tk_IntNumber].v[1];
+                               tList[i + start_tri].verts[2 - j][2] = vList[tk_IntNumber].v[2];
+#if 1
+                               tList[i + start_tri].indicies[2 - j] = tk_IntNumber + vertIndexBase;
+#endif
+                               TK_BeyondRequire( TK_UVTEXTURE, TK_FLOATNUMBER );
+                               tList[i + start_tri].uv[2 - j][0] = tk_FloatNumber;
+                               TK_Fetch();
+                               TK_Require( TK_FLOATNUMBER );
+                               tList[i + start_tri].uv[2 - j][1] = tk_FloatNumber;
+                       }
+
+                       /*              printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
+                                   "  v2: %f, %f, %f\n", i,
+                                   tList[i].verts[0][0],
+                                   tList[i].verts[0][1],
+                                   tList[i].verts[0][2],
+                                   tList[i].verts[1][0],
+                                   tList[i].verts[1][1],
+                                   tList[i].verts[1][2],
+                                   tList[i].verts[2][0],
+                                   tList[i].verts[2][1],
+                                   tList[i].verts[2][2]);
+                        */
+               }
+
+               TK_Beyond( TK_RBRACE );
+               TK_Beyond( TK_RBRACE );
+
+               if ( tk_Token == TK_EDGES ) {
+                       //      TK_Beyond(TK_EDGES);
+                       TK_Beyond( TK_RBRACE );
+               }
+
+               scaling[0] = scaling[1] = scaling[2] = 1.0;
+               //      rotation[0] = rotation[1] = rotation[2] = 0.0;
+               //      translation[0] = translation[1] = translation[2] = 0.0;
+
+               // See if there are any other models belonging to this node
+
+#if 1
+               TK_Fetch();
+
+               nextToken = tk_Token;
+               if ( nextToken == TK_CLUSTERS ) {
+                       if ( g_skelModel.clustered == -1 ) {
+                               ReadHRCClusterList( meshNode, vertIndexBase );
+                       }
+                       else
+                       {
+                               nextToken = TK_Get( TK_CLUSTER_NAME );
+
+                               while ( nextToken == TK_CLUSTER_NAME )
+                               {
+                                       TK_BeyondRequire( TK_CLUSTER_STATE, TK_INTNUMBER );
+                                       nextToken = TK_Fetch();
+                               }
+                       }
+
+                       // one right brace follow the list of clusters
+                       nextToken = TK_Beyond( TK_RBRACE );
+               }
+               else
+               {
+                       if ( g_skelModel.clustered == -1 && !vertIndexBase ) {
+                               meshNode->clustered = false;
+                       }
+               }
+#endif
+
+               nextToken = tk_Token;
+               if ( nextToken == TK_SPLINE ) {
+                       while ( nextToken == TK_SPLINE )
+                       {   // spline node has two right braces
+                               nextToken = TK_Beyond( TK_RBRACE );
+                               nextToken = TK_Beyond( TK_RBRACE );
+                       }
+
+                       nextToken = TK_Beyond( TK_RBRACE );
+               }
+
+               while ( nextToken == TK_MATERIAL )
+               {
+                       nextToken = TK_Beyond( TK_RBRACE );
+               }
+
+               while ( nextToken == TK_MODEL )
+               {
+                       HandleHRCModel( triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth + 1, vertexCount + vertIndexBase );
+
+                       nextToken = TK_Fetch();
+               }
+       }
+
+       for ( i = 0; i < 3; i++ )
+       {
+               scaling[i] = orig_scaling[i];
+               rotation[i] = orig_rotation[i];
+               translation[i] = orig_translation[i];
+       }
+}
+
+static void LoadHRC( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
+       if ( nodesList ) {
+               *num_mesh_nodes = 0;
+
+               if ( !*nodesList ) {
+                       *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
+               }
+       }
+
+       hrc_name = fileName;
+
+       scaling[0] = scaling[1] = scaling[2] = 1.0;
+       rotation[0] = rotation[1] = rotation[2] = 0.0;
+       translation[0] = translation[1] = translation[2] = 0.0;
+
+       *triangleCount = 0;
+       *triList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
+       memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+
+       // prime it
+       TK_Beyond( TK_MODEL );
+
+       HandleHRCModel( triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0 );
+       TK_CloseSource();
+}
+
+//==========================================================================
+//
+// LoadHTR
+//
+//==========================================================================
+/*
+   static int Version2;
+
+   void HandleHTRModel(triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,
+                           int ActiveNode, int Depth, int numVerts)
+   {
+    int                        i, j;
+    int                        vertexCount;
+    int                        vertexNum;
+    int                        triCount;
+    float              origin[3];
+    triangle_t *tList;
+    float              x, y, z;
+    float              x2, y2, z2;
+    float              rx, ry, rz;
+    mesh_node_t *meshNode;
+    int                        pos,bit;
+    int                        vertIndexBase;
+    int                        start_tri;
+
+    if (nodesList)
+    {
+        TK_BeyondRequire(TK_NAME, TK_STRING);
+
+        if (Depth == 0 || tk_String[0] == '_')
+        {      // Root
+            ActiveNode = *num_mesh_nodes;
+            (*num_mesh_nodes)++;
+            if ((*num_mesh_nodes) > MAX_FM_MESH_NODES)
+            {
+                Error("Too many mesh nodes in file %s\n", hrc_name);
+            }
+            meshNode = &(*nodesList)[ActiveNode];
+
+   //                  memset(meshNode, 0, sizeof(mesh_node_t));
+            strcpy(meshNode->name, tk_String);
+
+            memset(meshNode->tris, 0, sizeof(meshNode->tris));
+            memset(meshNode->verts, 0, sizeof(meshNode->verts));
+
+            meshNode->start_glcmds = 0;
+            meshNode->num_glcmds = 0;
+            vertIndexBase = 0;
+        }
+        else
+        {      // Childs under the children
+            meshNode = &(*nodesList)[ActiveNode];
+            vertIndexBase = numVerts;
+        }
+    }
+    else
+    {
+        meshNode = NULL;
+    }
+
+    // Get vertex count
+    TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);
+    vertexCount = tk_IntNumber;
+
+    // Get triangle count
+    TK_BeyondRequire(TK_FACES, TK_INTNUMBER);
+    triCount = tk_IntNumber;
+    if(triCount >= MAXTRIANGLES)
+    {
+        Error("Too many triangles in file %s\n", hrc_name);
+    }
+
+    // Get origin
+    TK_Beyond(TK_ORIGIN);
+    TK_Require(TK_FLOATNUMBER);
+    origin[0] = tk_FloatNumber;
+    TK_FetchRequire(TK_FLOATNUMBER);
+    origin[1] = tk_FloatNumber;
+    TK_FetchRequire(TK_FLOATNUMBER);
+    origin[2] = tk_FloatNumber;
+
+    //rx = 90.0/360.0*2.0*M_PI;
+    rx = FixHTRRotateX/360.0*2.0*M_PI;
+    ry = FixHTRRotateY/360.0*2.0*M_PI;
+    rz = FixHTRRotateZ/360.0*2.0*M_PI;
+
+    // Get vertex list
+    for(i = 0; i < vertexCount; i++)
+    {
+        TK_FetchRequire(TK_VERTEX);
+        TK_FetchRequire(TK_FLOATNUMBER);
+        x = tk_FloatNumber-origin[0];
+        TK_FetchRequire(TK_FLOATNUMBER);
+        y = tk_FloatNumber-origin[1];
+        TK_FetchRequire(TK_FLOATNUMBER);
+        z = tk_FloatNumber-origin[2];
+
+        x += FixHTRTranslateX;
+        y += FixHTRTranslateY;
+        z += FixHTRTranslateZ;
+
+        y2 = y*cos(rx)-z*sin(rx);
+        z2 = y*sin(rx)+z*cos(rx);
+        y = y2;
+        z = z2;
+        x2 = x*cos(ry)+z*sin(ry);
+        z2 = -x*sin(ry)+z*cos(ry);
+        x = x2;
+        z = z2;
+        x2 = x*cos(rz)-y*sin(rz);
+        y2 = x*sin(rz)+y*cos(rz);
+        x = x2;
+        y = y2;
+
+        vList[i].v[0] = x;
+        vList[i].v[1] = y;
+        vList[i].v[2] = z;
+    }
+
+    start_tri = *triangleCount;
+   *triangleCount += triCount;
+
+    tList = *triList;
+
+    // Get face list
+    for(i = 0; i < triCount; i++)
+    {
+        if (meshNode)
+        {      // Update the node
+            pos = (i + start_tri) >> 3;
+            bit = 1 << ((i + start_tri) & 7 );
+            meshNode->tris[pos] |= bit;
+        }
+
+        TK_FetchRequire(TK_FACE);
+        TK_FetchRequire(TK_LPAREN);
+        for(j = 0; j < 3; j++)
+        {
+            TK_FetchRequire(TK_INTNUMBER);
+            vertexNum = tk_IntNumber-1;
+            if(vertexNum >= vertexCount)
+            {
+                Error("File '%s', line %d:\nVertex number"
+                    " >= vertexCount: %d\n", tk_SourceName, tk_Line,
+                    tk_IntNumber);
+            }
+            tList[i+start_tri].verts[2-j][0] = vList[vertexNum].v[0];
+            tList[i+start_tri].verts[2-j][1] = vList[vertexNum].v[1];
+            tList[i+start_tri].verts[2-j][2] = vList[vertexNum].v[2];
+        }
+        TK_FetchRequire(TK_RPAREN);
+   #ifdef _QDATA
+        if (Version2)
+        {
+            TK_FetchRequire(TK_FLOATNUMBER);
+            tList[i+start_tri].uv[0][0]=tk_FloatNumber;
+            TK_FetchRequire(TK_FLOATNUMBER);
+            tList[i+start_tri].uv[0][1]=tk_FloatNumber;
+            TK_FetchRequire(TK_FLOATNUMBER);
+            tList[i+start_tri].uv[1][0]=tk_FloatNumber;
+            TK_FetchRequire(TK_FLOATNUMBER);
+            tList[i+start_tri].uv[1][1]=tk_FloatNumber;
+            TK_FetchRequire(TK_FLOATNUMBER);
+            tList[i+start_tri].uv[2][0]=tk_FloatNumber;
+            TK_FetchRequire(TK_FLOATNUMBER);
+            tList[i+start_tri].uv[2][1]=tk_FloatNumber;
+            tList[i+start_tri].HasUV=1;
+        }
+        else
+            tList[i+start_tri].HasUV=0;
+   #endif
+   //          printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
+   //                  "  v2: %f, %f, %f\n", i,
+   //                  tList[i].verts[0][0],
+   //                  tList[i].verts[0][1],
+   //                  tList[i].verts[0][2],
+   //                  tList[i].verts[1][0],
+   //                  tList[i].verts[1][1],
+   //                  tList[i].verts[1][2],
+   //                  tList[i].verts[2][0],
+   //                  tList[i].verts[2][1],
+   //                  tList[i].verts[2][2]);
+
+    }
+
+    TK_Fetch();
+
+    if (tk_Token == TK_VERTICES)
+    {
+        HandleHTRModel(triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth+1, vertexCount+vertIndexBase);
+    }
+   }
+
+   static void LoadHTR(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes)
+   {
+    if (nodesList)
+    {
+   *num_mesh_nodes = 0;
+
+        if(!*nodesList)
+        {
+   *nodesList = SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
+        }
+    }
+
+    hrc_name = fileName;
+
+    scaling[0] = scaling[1] = scaling[2] = 1.0;
+    rotation[0] = rotation[1] = rotation[2] = 0.0;
+    translation[0] = translation[1] = translation[2] = 0.0;
+
+   *triangleCount = 0;
+   *triList = SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");
+    memset(*triList,0,MAXTRIANGLES*sizeof(triangle_t));
+
+    TK_OpenSource(fileName);
+
+    TK_Beyond(TK_C_HEXEN);
+    TK_Beyond(TK_C_TRIANGLES);
+    TK_BeyondRequire(TK_C_VERSION, TK_INTNUMBER);
+    if(tk_IntNumber != 1&&tk_IntNumber != 2)
+    {
+        Error("Unsupported version (%d) in file %s\n", tk_IntNumber,
+            fileName);
+    }
+    Version2=(tk_IntNumber==2);
+
+
+    HandleHTRModel(triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0);
+   }
+
+ */
+
+static void LoadHTR( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
+       int Version2 = 0;
+       int i, j;
+       int vertexCount;
+       int vertexNum;
+       struct
+       {
+               float v[3];
+       }           *vList;
+       int triCount;
+       float origin[3];
+       triangle_t  *tList;
+       float x, y, z;
+       float x2, y2, z2;
+       float rx, ry, rz;
+
+       if ( nodesList ) {
+               *num_mesh_nodes = 0;
+               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
+       }
+
+       TK_OpenSource( fileName );
+
+       TK_Beyond( TK_C_HEXEN );
+       TK_Beyond( TK_C_TRIANGLES );
+       TK_BeyondRequire( TK_C_VERSION, TK_INTNUMBER );
+       if ( tk_IntNumber != 1 && tk_IntNumber != 2 ) {
+               Error( "Unsupported version (%d) in file %s\n", tk_IntNumber,
+                          fileName );
+       }
+       Version2 = ( tk_IntNumber == 2 );
+
+
+       // Get vertex count
+       TK_BeyondRequire( TK_VERTICES, TK_INTNUMBER );
+       vertexCount = tk_IntNumber;
+       vList = (void *) SafeMalloc( vertexCount * sizeof vList[0], "Vertex list" );
+
+       // Get triangle count
+       TK_BeyondRequire( TK_FACES, TK_INTNUMBER );
+       triCount = tk_IntNumber;
+       if ( triCount >= MAXTRIANGLES ) {
+               Error( "Too many triangles in file %s\n", fileName );
+       }
+       *triangleCount = triCount;
+       tList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
+       *triList = tList;
+       memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
+
+       // Get origin
+       TK_Beyond( TK_ORIGIN );
+       TK_Require( TK_FLOATNUMBER );
+       origin[0] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       origin[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       origin[2] = tk_FloatNumber;
+
+       //rx = 90.0/360.0*2.0*M_PI;
+       rx = FixHTRRotateX / 360.0 * 2.0 * M_PI;
+       ry = FixHTRRotateY / 360.0 * 2.0 * M_PI;
+       rz = FixHTRRotateZ / 360.0 * 2.0 * M_PI;
+
+       // Get vertex list
+       for ( i = 0; i < vertexCount; i++ )
+       {
+               TK_FetchRequire( TK_VERTEX );
+               TK_FetchRequire( TK_FLOATNUMBER );
+               x = tk_FloatNumber - origin[0];
+               TK_FetchRequire( TK_FLOATNUMBER );
+               y = tk_FloatNumber - origin[1];
+               TK_FetchRequire( TK_FLOATNUMBER );
+               z = tk_FloatNumber - origin[2];
+
+               x += FixHTRTranslateX;
+               y += FixHTRTranslateY;
+               z += FixHTRTranslateZ;
+
+               y2 = y * cos( rx ) - z*sin( rx );
+               z2 = y * sin( rx ) + z*cos( rx );
+               y = y2;
+               z = z2;
+               x2 = x * cos( ry ) + z*sin( ry );
+               z2 = -x*sin( ry ) + z*cos( ry );
+               x = x2;
+               z = z2;
+               x2 = x * cos( rz ) - y*sin( rz );
+               y2 = x * sin( rz ) + y*cos( rz );
+               x = x2;
+               y = y2;
+
+               vList[i].v[0] = x;
+               vList[i].v[1] = y;
+               vList[i].v[2] = z;
+       }
+
+       // Get face list
+       for ( i = 0; i < triCount; i++ )
+       {
+               TK_FetchRequire( TK_FACE );
+               TK_FetchRequire( TK_LPAREN );
+               for ( j = 0; j < 3; j++ )
+               {
+                       TK_FetchRequire( TK_INTNUMBER );
+                       vertexNum = tk_IntNumber - 1;
+                       if ( vertexNum >= vertexCount ) {
+                               Error( "File '%s', line %d:\nVertex number"
+                                          " >= vertexCount: %d\n", tk_SourceName, tk_Line,
+                                          tk_IntNumber );
+                       }
+                       tList[i].verts[2 - j][0] = vList[vertexNum].v[0];
+                       tList[i].verts[2 - j][1] = vList[vertexNum].v[1];
+                       tList[i].verts[2 - j][2] = vList[vertexNum].v[2];
+               }
+               TK_FetchRequire( TK_RPAREN );
+#if 1
+               if ( Version2 ) {
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       tList[i].uv[2][0] = fmod( 1000 + tk_FloatNumber,1 );
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       tList[i].uv[2][1] = fmod( 1000 + tk_FloatNumber,1 );
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       tList[i].uv[1][0] = fmod( 1000 + tk_FloatNumber,1 );
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       tList[i].uv[1][1] = fmod( 1000 + tk_FloatNumber,1 );
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       tList[i].uv[0][0] = fmod( 1000 + tk_FloatNumber,1 );
+                       TK_FetchRequire( TK_FLOATNUMBER );
+                       tList[i].uv[0][1] = fmod( 1000 + tk_FloatNumber,1 );
+                       tList[i].HasUV = 1;
+               }
+               else{
+                       tList[i].HasUV = 0;
+               }
+#endif
+/*             printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
+            "  v2: %f, %f, %f\n", i,
+            tList[i].verts[0][0],
+            tList[i].verts[0][1],
+            tList[i].verts[0][2],
+            tList[i].verts[1][0],
+            tList[i].verts[1][1],
+            tList[i].verts[1][2],
+            tList[i].verts[2][0],
+            tList[i].verts[2][1],
+            tList[i].verts[2][2]);
+ */
+       }
+
+       free( vList );
+       TK_CloseSource();
+       DefaultNodesList( nodesList,num_mesh_nodes,triangleCount );
+}
+
+//==========================================================================
+//
+// LoadTriangleList
+//
+//==========================================================================
+
+void LoadTriangleList( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **ppmnodes, int *num_mesh_nodes ){
+       FILE    *file1;
+       int dot = '.';
+       char    *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+                       LoadHRC( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".asc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+                       LoadASC( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       printf( " - assuming .ASC\n" );
+                       return;
+               }
+
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".tri" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+                       LoadTRI( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       printf( " - assuming .TRI\n" );
+                       return;
+               }
+
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".3ds" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+                       Load3DSTriangleList( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       printf( " - assuming .3DS\n" );
+                       return;
+               }
+
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".htr" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+                       LoadHTR( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       printf( " - assuming .HTR\n" );
+                       return;
+               }
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC, ASC, 3DS, HTR, or TRI match.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+                       printf( "\n" );
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRC( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       }
+                       else if ( strcmp( dotstart,".asc" ) == 0 || strcmp( dotstart,".ASC" ) == 0 ) {
+                               LoadASC( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       }
+                       else if ( strcmp( dotstart,".tri" ) == 0 || strcmp( dotstart,".TRI" ) == 0 ) {
+                               LoadTRI( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       }
+                       else if ( strcmp( dotstart,".3ds" ) == 0 || strcmp( dotstart,".3DS" ) == 0 ) {
+                               Load3DSTriangleList( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       }
+                       else if ( strcmp( dotstart,".htr" ) == 0 || strcmp( dotstart,".HTR" ) == 0 ) {
+                               LoadHTR( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
+                       }
+                       else
+                       {
+                               Error( "Could not open file '%s':\n",fileName );
+                               return;
+                       }
+               }
+               else    //failed to load file
+               {
+                       Error( "Could not open file '%s':\n",fileName );
+               }
+
+       }
+}
diff --git a/tools/heretic2/common/trilib.h b/tools/heretic2/common/trilib.h
new file mode 100644 (file)
index 0000000..8dfd6d2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+//
+// trilib.h: header file for loading triangles from an Alias triangle file
+//
+
+#include "fmodel.h"
+
+#define MAXTRIANGLES    MAX_FM_TRIANGLES
+
+typedef struct
+{
+       vec3_t verts[3];
+#if 1
+       int indicies[3];
+       float uv[3][2];
+       qboolean HasUV;
+#endif
+} triangle_t;
+
+#define NUM_CLUSTERS 8
+
+typedef struct
+{
+       char name[64];
+       byte tris[MAXTRIANGLES >> 3];
+       byte verts[MAX_FM_VERTS >> 3];
+       int start_glcmds, num_glcmds;
+
+       int *clusters[NUM_CLUSTERS];
+       struct IntListNode_s *vertLists[NUM_CLUSTERS];
+       int num_verts[NUM_CLUSTERS + 1];
+       int new_num_verts[NUM_CLUSTERS + 1];
+       qboolean clustered;
+} mesh_node_t;
+
+void LoadTriangleList( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **ppmnodes, int *num_mesh_nodes );
diff --git a/tools/heretic2/h2data/adpcm.h b/tools/heretic2/h2data/adpcm.h
new file mode 100644 (file)
index 0000000..aad74ea
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+** adpcm.h - include file for adpcm coder.
+**
+** Version 1.0, 7-Jul-92.
+**
+** Modded 10/3/98
+** John Scott
+*/
+
+typedef struct adpcm_state_s
+{
+       short in_valprev;           // Previous output value
+       short in_index;             // Index into stepsize table
+       short out_valprev;          // Previous output value
+       short out_index;            // Index into stepsize table
+       int count;                  // Number of sample counts
+}   adpcm_state_t;
+
+typedef struct adpcm_s
+{
+       adpcm_state_t state;
+       char adpcm[0x10000];
+}   adpcm_t;
+
+void adpcm_coder( short [], adpcm_t * );
+void adpcm_decoder( adpcm_t *, short [] );
+
+// end
diff --git a/tools/heretic2/h2data/animcomp.c b/tools/heretic2/h2data/animcomp.c
new file mode 100644 (file)
index 0000000..a761932
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <memory.h>
+#include "animcomp.h"
+
+
+void    *SafeMalloc( size_t n, char *desc );
+
+
+
+float *matrix;
+float *delta;
+float *best;
+float *comp;
+float *tcomp;
+float *bestcomp;
+float *frames;
+float *base;
+
+int MatWidth;
+int MatHeight;
+int CFrameSize;
+int nFrames;
+
+
+void AnimCompressInit( int nframes,int nVerts,int CompressedFrameSize ){
+       nFrames = nframes;
+       MatWidth = nVerts * 3;
+       MatHeight = CompressedFrameSize;
+       CFrameSize = CompressedFrameSize;
+       matrix = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
+       best = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
+       delta = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
+       comp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
+       tcomp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
+       bestcomp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
+       base = (float *)SafeMalloc( MatWidth * sizeof( float ), "AnimCompressInit" );
+       frames = (float *)SafeMalloc( MatWidth * nFrames * sizeof( float ), "AnimCompressInit" );
+}
+
+void AnimSetFrame( int frame,int index,float x,float y,float z ){
+       frames[frame * MatWidth + index * 3] = x;
+       frames[frame * MatWidth + index * 3 + 1] = y;
+       frames[frame * MatWidth + index * 3 + 2] = z;
+}
+
+typedef struct
+{
+       int index;
+       float val;
+} SORTP;
+
+
+#define F_RANDOM ( ( (float)rand() ) / (float)RAND_MAX )
+
+extern void DOsvd( float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize );
+
+void AnimCompressDoit(){
+       float compression;
+       float *rescale;
+       float *ans;
+       float maxdev;
+       float avedev;
+       float tmp;
+       int j,k,l,numave;
+
+       for ( k = 0; k < MatWidth; k++ )
+               base[k] = 0.0f;
+       for ( j = 0; j < nFrames; j++ )
+               for ( k = 0; k < MatWidth; k++ )
+                       base[k] += frames[j * MatWidth + k];
+       tmp = 1.0f / (float)nFrames;
+       for ( k = 0; k < MatWidth; k++ )
+               base[k] *= tmp;
+       for ( j = 0; j < nFrames; j++ )
+               for ( k = 0; k < MatWidth; k++ )
+                       frames[j * MatWidth + k] -= base[k];
+
+       ans = (float *)SafeMalloc( sizeof( float ) * MatWidth, "AnimCompressDoit" );
+       rescale = (float *)SafeMalloc( sizeof( float ) * CFrameSize, "AnimCompressDoit" );
+       DOsvd( frames,best,bestcomp,rescale,nFrames,MatWidth,MatHeight );
+       avedev = 0.0;
+       for ( l = 0; l < CFrameSize; l++ )
+               avedev += rescale[l];
+       for ( l = 0; l < CFrameSize; l++ )
+               printf( "%3.1f ",100.0f * rescale[l] / avedev );
+       printf( "\n" );
+       for ( j = 0; j < nFrames; j++ )
+       {
+               for ( l = 0; l < CFrameSize; l++ )
+               {
+                       bestcomp[j * CFrameSize + l] = 0.0;
+                       for ( k = 0; k < MatWidth; k++ )
+                               bestcomp[j * CFrameSize + l] += best[l * MatWidth + k] * frames[j * MatWidth + k];
+               }
+       }
+       numave = 0;
+       avedev = 0.0;
+       maxdev = 0.0;
+       for ( j = 0; j < nFrames; j++ )
+       {
+               for ( k = 0; k < MatWidth; k++ )
+               {
+                       ans[k] = 0.0;
+                       for ( l = 0; l < CFrameSize; l++ )
+                               ans[k] += best[l * MatWidth + k] * bestcomp[j * CFrameSize + l];
+                       ans[k] -= frames[j * MatWidth + k];
+                       tmp = (float)fabs( ans[k] );
+                       if ( tmp > maxdev ) {
+                               maxdev = tmp;
+                       }
+                       avedev += tmp;
+                       numave++;
+               }
+       }
+       avedev /= (float)numave;
+       printf( "%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev );
+       printf( "%d bytes original size\n",MatWidth * nFrames );
+       printf( "%d bytes of overhead\n",MatWidth * MatHeight );
+       printf( "%d bytes/frame * %d frames = %d bytes\n",CFrameSize,nFrames,CFrameSize * nFrames );
+       compression = (float)( MatWidth * MatHeight + CFrameSize * nFrames + MatWidth );
+       compression /= (float)( MatWidth * nFrames );
+       printf( "Overall compression = %f %%\n",100.0f - 100.0f * compression );
+       compression = (float)( CFrameSize );
+       compression /= (float)( MatWidth );
+       printf( "frame size compression = %f %%\n",100.0f - 100.0f * compression );
+       free( rescale );
+       free( ans );
+}
+
+void AnimCompressToBytes( float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax ){
+       int k,l,nv,j;
+       float maxdev;
+       float avedev;
+       float tmp;
+       int numave;
+       float t,mx;
+       float *ans;
+
+
+       nv = MatWidth / 3;
+
+       trans[0] = 1E30f;
+       scale[0] = -1E30f;
+       trans[1] = 1E30f;
+       scale[1] = -1E30f;
+       trans[2] = 1E30f;
+       scale[2] = -1E30f;
+       for ( k = 0; k < MatWidth; k += 3 )
+       {
+               if ( base[k] > scale[0] ) {
+                       scale[0] = base[k];
+               }
+               if ( base[k] < trans[0] ) {
+                       trans[0] = base[k];
+               }
+
+               if ( base[k + 1] > scale[1] ) {
+                       scale[1] = base[k + 1];
+               }
+               if ( base[k + 1] < trans[1] ) {
+                       trans[1] = base[k + 1];
+               }
+
+               if ( base[k + 2] > scale[2] ) {
+                       scale[2] = base[k + 2];
+               }
+               if ( base[k + 2] < trans[2] ) {
+                       trans[2] = base[k + 2];
+               }
+       }
+
+       scale[0] -= trans[0];
+       scale[1] -= trans[1];
+       scale[2] -= trans[2];
+       scale[0] /= 255.0f;
+       scale[1] /= 255.0f;
+       scale[2] /= 255.0f;
+       for ( k = 0; k < MatWidth; k += 3 )
+       {
+               t = ( base[k] - trans[0] ) / scale[0];
+               if ( t < 0.0f ) {
+                       t = 0.0f;
+               }
+               if ( t > 255.0f ) {
+                       t = 255.0f;
+               }
+               cbase[k] = (unsigned char)t;
+
+               t = ( base[k + 1] - trans[1] ) / scale[1];
+               if ( t < 0.0f ) {
+                       t = 0.0f;
+               }
+               if ( t > 255.0f ) {
+                       t = 255.0f;
+               }
+               cbase[k + 1] = (unsigned char)t;
+
+               t = ( base[k + 2] - trans[2] ) / scale[2];
+               if ( t < 0.0f ) {
+                       t = 0.0f;
+               }
+               if ( t > 255.0f ) {
+                       t = 255.0f;
+               }
+               cbase[k + 2] = (unsigned char)t;
+       }
+       for ( l = 0; l < MatHeight; l++ )
+       {
+               mx = 0.0;
+               for ( k = 0; k < MatWidth; k++ )
+               {
+                       if ( fabs( best[l * MatWidth + k] ) > mx ) {
+                               mx = (float)fabs( best[l * MatWidth + k] );
+                       }
+               }
+               if ( mx > 1E-8 ) {
+                       mx /= 127.0f;
+                       coffset[l] = 1E30f;
+                       cscale[l] = -1E30f;
+                       for ( j = 0; j < nFrames; j++ )
+                       {
+                               bestcomp[j * MatHeight + l] *= mx;
+                               if ( bestcomp[j * MatHeight + l] > cscale[l] ) {
+                                       cscale[l] = bestcomp[j * MatHeight + l];
+                               }
+                               if ( bestcomp[j * MatHeight + l] < coffset[l] ) {
+                                       coffset[l] = bestcomp[j * MatHeight + l];
+                               }
+                       }
+                       cscale[l] -= coffset[l];
+                       if ( cscale[l] > 1E-10 ) {
+                               for ( j = 0; j < nFrames; j++ )
+                               {
+                                       tmp = 254.0f * ( bestcomp[j * MatHeight + l] - coffset[l] ) / cscale[l] - 127.0f;
+                                       if ( tmp > 127.0f ) {
+                                               tmp = 127.0f;
+                                       }
+                                       if ( tmp < -127.0f ) {
+                                               tmp = -127.0f;
+                                       }
+                                       ccomp[j * MatHeight + l] = (char)floor( tmp + 0.5 );
+                               }
+                               coffset[l] += cscale[l] * 127.0f / 254.0f;
+                               cscale[l] /= 254.0f;
+                       }
+                       else
+                       {
+                               cscale[l] = 1.0f;
+                               coffset[l] = 0.0f;
+                               for ( j = 0; j < nFrames; j++ )
+                                       ccomp[j * MatHeight + l] = 0;
+                       }
+                       mx = 1.0f / mx;
+                       for ( k = 0; k < MatWidth; k++ )
+                       {
+                               tmp = best[l * MatWidth + k] * mx;
+                               if ( tmp > 127.0f ) {
+                                       tmp = 127.0f;
+                               }
+                               if ( tmp < -127.0f ) {
+                                       tmp = -127.0f;
+                               }
+                               mat[k * MatHeight + l] = (char)floor( tmp + 0.5 );
+                       }
+               }
+               else
+               {
+                       cscale[l] = 1.0f;
+                       coffset[l] = 0.0f;
+                       for ( j = 0; j < nFrames; j++ )
+                               ccomp[j * MatHeight + l] = 0;
+                       for ( k = 0; k < MatWidth; k++ )
+                               mat[k * MatHeight + l] = 0;
+               }
+       }
+       bmin[0] = 1E30f;
+       bmin[1] = 1E30f;
+       bmin[2] = 1E30f;
+       bmax[0] = -1E30f;
+       bmax[1] = -1E30f;
+       bmax[2] = -1E30f;
+       numave = 0;
+       avedev = 0.0;
+       maxdev = 0.0;
+       ans = (float *)SafeMalloc( sizeof( float ) * MatWidth, "AnimCompressToBytes" );
+       for ( j = 0; j < nFrames; j++ )
+       {
+               for ( k = 0; k < MatWidth; k++ )
+               {
+                       ans[k] = 0.0;
+                       for ( l = 0; l < CFrameSize; l++ )
+                               ans[k] += (float)( mat[l + k * MatHeight] ) * ( (float)( ccomp[j * CFrameSize + l] ) * cscale[l] + coffset[l] );
+                       ans[k] += (float)( cbase[k] ) * scale[k % 3] + trans[k % 3];
+                       tmp = (float)fabs( ans[k] - frames[j * MatWidth + k] - base[k] );
+                       if ( tmp > maxdev ) {
+                               maxdev = tmp;
+                       }
+                       avedev += tmp;
+                       numave++;
+
+                       if ( bmin[k % 3] > ans[k] ) {
+                               bmin[k % 3] = ans[k];
+                       }
+                       if ( bmax[k % 3] < ans[k] ) {
+                               bmax[k % 3] = ans[k];
+                       }
+               }
+       }
+       avedev /= (float)numave;
+       printf( "%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev );
+       free( ans );
+}
+
+void AnimCompressGetMatrix( float *mat ){
+       int k,l;
+       for ( k = 0; k < MatWidth; k++ )
+               for ( l = 0; l < MatHeight; l++ )
+                       mat[k * MatHeight + l] = best[l * MatWidth + k];
+}
+
+void AnimCompressGetFrames( float *mat ){
+       memcpy( mat,bestcomp,CFrameSize * nFrames * sizeof( float ) );
+}
+
+void AnimCompressGetBase( int i,float *x,float *y,float *z ){
+       *x = base[i * 3];
+       *y = base[i * 3 + 1];
+       *z = base[i * 3 + 2];
+}
+
+void AnimCompressEnd(){
+       free( matrix );
+       free( best );
+       free( delta );
+       free( comp );
+       free( tcomp );
+       free( bestcomp );
+       free( base );
+       free( frames );
+}
diff --git a/tools/heretic2/h2data/animcomp.h b/tools/heretic2/h2data/animcomp.h
new file mode 100644 (file)
index 0000000..36ea3b1
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined( ANIMCOMP_INC )
+#define ANIMCOMP_INC
+
+#ifdef  __cplusplus
+extern "C"
+{
+#endif
+void AnimCompressInit( int nFrames,int nVerts,int CompressedFrameSize );
+void AnimSetFrame( int frame,int index,float x,float y,float z );
+void AnimCompressDoit();
+void AnimCompressToBytes( float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax );
+void AnimCompressGetMatrix( float *mat );
+void AnimCompressGetFrames( float *mat );
+void AnimCompressGetBase( int i,float *x,float *y,float *z );
+void AnimCompressEnd();
+void DOsvdPlane( float *pnts,int npnts,float *n,float *base );
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/heretic2/h2data/anorms.h b/tools/heretic2/h2data/anorms.h
new file mode 100644 (file)
index 0000000..65e92ef
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+{-0.525731f, 0.000000f, 0.850651f},
+{-0.442863f, 0.238856f, 0.864188f},
+{-0.295242f, 0.000000f, 0.955423f},
+{-0.309017f, 0.500000f, 0.809017f},
+{-0.162460f, 0.262866f, 0.951056f},
+{0.000000f, 0.000000f, 1.000000f},
+{0.000000f, 0.850651f, 0.525731f},
+{-0.147621f, 0.716567f, 0.681718f},
+{0.147621f, 0.716567f, 0.681718f},
+{0.000000f, 0.525731f, 0.850651f},
+{0.309017f, 0.500000f, 0.809017f},
+{0.525731f, 0.000000f, 0.850651f},
+{0.295242f, 0.000000f, 0.955423f},
+{0.442863f, 0.238856f, 0.864188f},
+{0.162460f, 0.262866f, 0.951056f},
+{-0.681718f, 0.147621f, 0.716567f},
+{-0.809017f, 0.309017f, 0.500000f},
+{-0.587785f, 0.425325f, 0.688191f},
+{-0.850651f, 0.525731f, 0.000000f},
+{-0.864188f, 0.442863f, 0.238856f},
+{-0.716567f, 0.681718f, 0.147621f},
+{-0.688191f, 0.587785f, 0.425325f},
+{-0.500000f, 0.809017f, 0.309017f},
+{-0.238856f, 0.864188f, 0.442863f},
+{-0.425325f, 0.688191f, 0.587785f},
+{-0.716567f, 0.681718f, -0.147621f},
+{-0.500000f, 0.809017f, -0.309017f},
+{-0.525731f, 0.850651f, 0.000000f},
+{0.000000f, 0.850651f, -0.525731f},
+{-0.238856f, 0.864188f, -0.442863f},
+{0.000000f, 0.955423f, -0.295242f},
+{-0.262866f, 0.951056f, -0.162460f},
+{0.000000f, 1.000000f, 0.000000f},
+{0.000000f, 0.955423f, 0.295242f},
+{-0.262866f, 0.951056f, 0.162460f},
+{0.238856f, 0.864188f, 0.442863f},
+{0.262866f, 0.951056f, 0.162460f},
+{0.500000f, 0.809017f, 0.309017f},
+{0.238856f, 0.864188f, -0.442863f},
+{0.262866f, 0.951056f, -0.162460f},
+{0.500000f, 0.809017f, -0.309017f},
+{0.850651f, 0.525731f, 0.000000f},
+{0.716567f, 0.681718f, 0.147621f},
+{0.716567f, 0.681718f, -0.147621f},
+{0.525731f, 0.850651f, 0.000000f},
+{0.425325f, 0.688191f, 0.587785f},
+{0.864188f, 0.442863f, 0.238856f},
+{0.688191f, 0.587785f, 0.425325f},
+{0.809017f, 0.309017f, 0.500000f},
+{0.681718f, 0.147621f, 0.716567f},
+{0.587785f, 0.425325f, 0.688191f},
+{0.955423f, 0.295242f, 0.000000f},
+{1.000000f, 0.000000f, 0.000000f},
+{0.951056f, 0.162460f, 0.262866f},
+{0.850651f, -0.525731f, 0.000000f},
+{0.955423f, -0.295242f, 0.000000f},
+{0.864188f, -0.442863f, 0.238856f},
+{0.951056f, -0.162460f, 0.262866f},
+{0.809017f, -0.309017f, 0.500000f},
+{0.681718f, -0.147621f, 0.716567f},
+{0.850651f, 0.000000f, 0.525731f},
+{0.864188f, 0.442863f, -0.238856f},
+{0.809017f, 0.309017f, -0.500000f},
+{0.951056f, 0.162460f, -0.262866f},
+{0.525731f, 0.000000f, -0.850651f},
+{0.681718f, 0.147621f, -0.716567f},
+{0.681718f, -0.147621f, -0.716567f},
+{0.850651f, 0.000000f, -0.525731f},
+{0.809017f, -0.309017f, -0.500000f},
+{0.864188f, -0.442863f, -0.238856f},
+{0.951056f, -0.162460f, -0.262866f},
+{0.147621f, 0.716567f, -0.681718f},
+{0.309017f, 0.500000f, -0.809017f},
+{0.425325f, 0.688191f, -0.587785f},
+{0.442863f, 0.238856f, -0.864188f},
+{0.587785f, 0.425325f, -0.688191f},
+{0.688191f, 0.587785f, -0.425325f},
+{-0.147621f, 0.716567f, -0.681718f},
+{-0.309017f, 0.500000f, -0.809017f},
+{0.000000f, 0.525731f, -0.850651f},
+{-0.525731f, 0.000000f, -0.850651f},
+{-0.442863f, 0.238856f, -0.864188f},
+{-0.295242f, 0.000000f, -0.955423f},
+{-0.162460f, 0.262866f, -0.951056f},
+{0.000000f, 0.000000f, -1.000000f},
+{0.295242f, 0.000000f, -0.955423f},
+{0.162460f, 0.262866f, -0.951056f},
+{-0.442863f, -0.238856f, -0.864188f},
+{-0.309017f, -0.500000f, -0.809017f},
+{-0.162460f, -0.262866f, -0.951056f},
+{0.000000f, -0.850651f, -0.525731f},
+{-0.147621f, -0.716567f, -0.681718f},
+{0.147621f, -0.716567f, -0.681718f},
+{0.000000f, -0.525731f, -0.850651f},
+{0.309017f, -0.500000f, -0.809017f},
+{0.442863f, -0.238856f, -0.864188f},
+{0.162460f, -0.262866f, -0.951056f},
+{0.238856f, -0.864188f, -0.442863f},
+{0.500000f, -0.809017f, -0.309017f},
+{0.425325f, -0.688191f, -0.587785f},
+{0.716567f, -0.681718f, -0.147621f},
+{0.688191f, -0.587785f, -0.425325f},
+{0.587785f, -0.425325f, -0.688191f},
+{0.000000f, -0.955423f, -0.295242f},
+{0.000000f, -1.000000f, 0.000000f},
+{0.262866f, -0.951056f, -0.162460f},
+{0.000000f, -0.850651f, 0.525731f},
+{0.000000f, -0.955423f, 0.295242f},
+{0.238856f, -0.864188f, 0.442863f},
+{0.262866f, -0.951056f, 0.162460f},
+{0.500000f, -0.809017f, 0.309017f},
+{0.716567f, -0.681718f, 0.147621f},
+{0.525731f, -0.850651f, 0.000000f},
+{-0.238856f, -0.864188f, -0.442863f},
+{-0.500000f, -0.809017f, -0.309017f},
+{-0.262866f, -0.951056f, -0.162460f},
+{-0.850651f, -0.525731f, 0.000000f},
+{-0.716567f, -0.681718f, -0.147621f},
+{-0.716567f, -0.681718f, 0.147621f},
+{-0.525731f, -0.850651f, 0.000000f},
+{-0.500000f, -0.809017f, 0.309017f},
+{-0.238856f, -0.864188f, 0.442863f},
+{-0.262866f, -0.951056f, 0.162460f},
+{-0.864188f, -0.442863f, 0.238856f},
+{-0.809017f, -0.309017f, 0.500000f},
+{-0.688191f, -0.587785f, 0.425325f},
+{-0.681718f, -0.147621f, 0.716567f},
+{-0.442863f, -0.238856f, 0.864188f},
+{-0.587785f, -0.425325f, 0.688191f},
+{-0.309017f, -0.500000f, 0.809017f},
+{-0.147621f, -0.716567f, 0.681718f},
+{-0.425325f, -0.688191f, 0.587785f},
+{-0.162460f, -0.262866f, 0.951056f},
+{0.442863f, -0.238856f, 0.864188f},
+{0.162460f, -0.262866f, 0.951056f},
+{0.309017f, -0.500000f, 0.809017f},
+{0.147621f, -0.716567f, 0.681718f},
+{0.000000f, -0.525731f, 0.850651f},
+{0.425325f, -0.688191f, 0.587785f},
+{0.587785f, -0.425325f, 0.688191f},
+{0.688191f, -0.587785f, 0.425325f},
+{-0.955423f, 0.295242f, 0.000000f},
+{-0.951056f, 0.162460f, 0.262866f},
+{-1.000000f, 0.000000f, 0.000000f},
+{-0.850651f, 0.000000f, 0.525731f},
+{-0.955423f, -0.295242f, 0.000000f},
+{-0.951056f, -0.162460f, 0.262866f},
+{-0.864188f, 0.442863f, -0.238856f},
+{-0.951056f, 0.162460f, -0.262866f},
+{-0.809017f, 0.309017f, -0.500000f},
+{-0.864188f, -0.442863f, -0.238856f},
+{-0.951056f, -0.162460f, -0.262866f},
+{-0.809017f, -0.309017f, -0.500000f},
+{-0.681718f, 0.147621f, -0.716567f},
+{-0.681718f, -0.147621f, -0.716567f},
+{-0.850651f, 0.000000f, -0.525731f},
+{-0.688191f, 0.587785f, -0.425325f},
+{-0.587785f, 0.425325f, -0.688191f},
+{-0.425325f, 0.688191f, -0.587785f},
+{-0.425325f, -0.688191f, -0.587785f},
+{-0.587785f, -0.425325f, -0.688191f},
+{-0.688191f, -0.587785f, -0.425325f},
diff --git a/tools/heretic2/h2data/book.c b/tools/heretic2/h2data/book.c
new file mode 100644 (file)
index 0000000..412aefe
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include "qdata.h"
+
+byte            *byteimage, *lbmpalette;
+int byteimagewidth, byteimageheight;
+
+qboolean TrueColorImage;
+int longimagewidth, longimageheight;
+
+char book_prefix[1024];
+byte buffer[640 * 480];
+unsigned long bufferl[640 * 480];
+
+miptex_t *CreateBook8( byte *buffer, int w, int h, byte *palette, int *FinalSize ){
+       miptex_t    *mp;
+       int i, j;
+       byte        *pos;
+       int size;
+
+       size = sizeof( *mp ) + ( w * h );
+       mp = (miptex_t *)SafeMalloc( size, "CreateBook8" );
+       memset( mp, 0, size );
+
+       mp->version = MIP_VERSION;
+
+       for ( i = j = 0; i < 256; i++,j += 3 )
+       {
+               mp->palette[i].r = palette[j];
+               mp->palette[i].g = palette[j + 1];
+               mp->palette[i].b = palette[j + 2];
+       }
+       pos = (byte *)( mp + 1 );
+
+       mp->width[0] = w;
+       mp->height[0] = h;
+       mp->offsets[0] = sizeof( *mp );
+       memcpy( pos, buffer, w * h );
+
+       *FinalSize = size;
+       return( mp );
+}
+
+miptex32_t *CreateBook32( long *buffer, int w, int h, int *FinalSize ){
+       miptex32_t  *mp;
+       byte        *pos;
+       int size;
+
+       size = sizeof( *mp ) + ( w * h * 4 );
+       mp = (miptex32_t *)SafeMalloc( size, "CreateBook32" );
+       memset( mp, 0, size );
+
+       mp->version = MIP32_VERSION;
+
+       pos = (byte *)( mp + 1 );
+
+       mp->width[0] = w;
+       mp->height[0] = h;
+       mp->offsets[0] = sizeof( *mp );
+       memcpy( pos, buffer, w * h * 4 );
+
+       *FinalSize = size;
+       return( mp );
+}
+
+
+// Routines to chop a random sized image into gl texture friendly chunks
+
+typedef struct rect_s
+{
+       int x, y;
+       int w, h;
+       char name[4];
+} rect_t;
+
+int GetCoords( int x, int store[MAX_MD2SKINS] ){
+       int index, start, delta;
+
+       index = 0;
+       start = 0;
+       delta = 256;
+
+       store[index++] = start;
+       while ( x )
+       {
+               if ( x >= delta ) {
+                       start += delta;
+                       store[index++] = start;
+                       x -= delta;
+               }
+               else
+               {
+                       delta >>= 1;
+               }
+       }
+       return( index );
+}
+
+int ChopImage( int w, int h, rect_t coords[MAX_MD2SKINS] ){
+       int xs[MAX_MD2SKINS], ys[MAX_MD2SKINS];
+       int xcount, ycount, x, y, index;
+
+       index = 0;
+       xcount = GetCoords( w, xs ) - 1;
+       ycount = GetCoords( h, ys ) - 1;
+
+       for ( y = 0; y < ycount; y++ )
+       {
+               for ( x = 0; x < xcount; x++, index++ )
+               {
+                       coords[index].x = xs[x];
+                       coords[index].y = ys[y];
+                       coords[index].w = xs[x + 1] - xs[x];
+                       coords[index].h = ys[y + 1] - ys[y];
+                       coords[index].name[0] = x + '0';
+                       coords[index].name[1] = y + '0';
+                       coords[index].name[2] = 0;
+               }
+       }
+       return( index );
+}
+
+/*
+   ===============
+   Cmd_Pic
+   ===============
+ */
+
+void Cmd_Book(){
+       int xl,yl,xh,yh,w,h;
+       byte            *dest, *source;
+       int flags, value, contents;
+       char lumpname[64];
+       char filename[1024];
+       unsigned long   *destl, *sourcel;
+       int linedelta, x, y;
+       int size;
+       miptex_t        *qtex;
+       miptex32_t      *qtex32;
+       float scale_x, scale_y;
+       int numrects, i;
+       rect_t coords[MAX_MD2SKINS];
+       bookframe_t bframes[MAX_MD2SKINS];
+       bookframe_t     *bf;
+       book_t book;
+
+       GetScriptToken( false );
+       strcpy( lumpname, token );
+
+       GetScriptToken( false );
+       xl = atoi( token );
+       GetScriptToken( false );
+       yl = atoi( token );
+       GetScriptToken( false );
+       w = atoi( token );
+       GetScriptToken( false );
+       h = atoi( token );
+
+       total_x += w;
+       total_y += h;
+       total_textures++;
+
+       if ( ( w & 7 ) || ( h & 7 ) ) {
+               Error( "line %i: miptex sizes must be multiples of 8", scriptline );
+       }
+
+       flags = 0;
+       contents = 0;
+       value = 0;
+
+       scale_x = scale_y = 0.5;
+
+       if ( g_release ) {
+               return;
+       }
+
+       if ( TrueColorImage ) {
+               xh = xl + w;
+               yh = yl + h;
+
+               if ( xl >= longimagewidth || xh > longimagewidth ||
+                        yl >= longimageheight || yh > longimageheight ) {
+                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight );
+               }
+
+               sourcel = (unsigned long *) longimage + ( yl * longimagewidth ) + xl;
+               destl = (unsigned long *) longimage;
+               linedelta = ( longimagewidth - w );
+
+               for ( y = yl; y < yh; y++ )
+               {
+                       for ( x = xl; x < xh; x++ )
+                       {
+                               *destl++ = *sourcel++;  // RGBA
+                       }
+                       sourcel += linedelta;
+               }
+
+               // Get rectangles to chop into
+               numrects = ChopImage( w, h, coords );
+
+               bf = bframes;
+               for ( i = 0; i < numrects; i++, bf++ )
+               {
+                       // Copy section of image to buffer
+                       sourcel = (unsigned long *) longimage + ( coords[i].y * w ) + coords[i].x;
+                       destl = bufferl;
+                       linedelta = w - coords[i].w;
+
+                       for ( y = 0; y < coords[i].h; y++ )
+                       {
+                               for ( x = 0; x < coords[i].w; x++ )
+                               {
+                                       *destl++ = *sourcel++;
+                               }
+                               sourcel += linedelta;
+                       }
+
+                       qtex32 = CreateBook32( bufferl, coords[i].w, coords[i].h, &size );
+
+                       qtex32->flags = flags;
+                       qtex32->contents = contents;
+                       qtex32->value = value;
+                       qtex32->scale_x = scale_x;
+                       qtex32->scale_y = scale_y;
+
+                       sprintf( filename, "%sbook/%s/%s_%s.m32", gamedir, book_prefix, lumpname, coords[i].name );
+                       sprintf( qtex32->name, "%s/%s_%s.m32", book_prefix, lumpname, coords[i].name );
+
+                       strcpy( bf->name, qtex32->name );
+                       bf->x = coords[i].x;
+                       bf->y = coords[i].y;
+                       bf->w = coords[i].w;
+                       bf->h = coords[i].h;
+                       //
+                       // write it out
+                       //
+                       printf( "writing %s\n", filename );
+                       SaveFile( filename, (byte *)qtex32, size );
+
+                       free( qtex32 );
+               }
+       }
+       else
+       {
+               xh = xl + w;
+               yh = yl + h;
+
+               if ( xl >= byteimagewidth || xh > byteimagewidth ||
+                        yl >= byteimageheight || yh > byteimageheight ) {
+                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
+               }
+
+               // Copy image to top left
+               source = byteimage + yl * byteimagewidth + xl;
+               dest = byteimage;
+               linedelta = byteimagewidth - w;
+
+               for ( y = yl; y < yh; y++ )
+               {
+                       for ( x = xl; x < xh; x++ )
+                       {
+                               *dest++ = *source++;
+                       }
+                       source += linedelta;
+               }
+
+               // Get rectangles to chop into
+               numrects = ChopImage( w, h, coords );
+
+               bf = bframes;
+               for ( i = 0; i < numrects; i++, bf++ )
+               {
+                       // Copy section of image to buffer
+                       source = byteimage + ( coords[i].y * w ) + coords[i].x;
+                       dest = buffer;
+                       linedelta = w - coords[i].w;
+
+                       for ( y = 0; y < coords[i].h; y++ )
+                       {
+                               for ( x = 0; x < coords[i].w; x++ )
+                               {
+                                       *dest++ = *source++;
+                               }
+                               source += linedelta;
+                       }
+
+                       qtex = CreateBook8( buffer, coords[i].w, coords[i].h, lbmpalette, &size );
+
+                       qtex->flags = flags;
+                       qtex->contents = contents;
+                       qtex->value = value;
+
+                       sprintf( filename, "%sbook/%s/%s_%s.m8", gamedir, book_prefix, lumpname, coords[i].name );
+                       sprintf( qtex->name, "%s/%s_%s.m8", book_prefix, lumpname, coords[i].name );
+
+                       strcpy( bf->name, qtex->name );
+                       bf->x = coords[i].x;
+                       bf->y = coords[i].y;
+                       bf->w = coords[i].w;
+                       bf->h = coords[i].h;
+                       //
+                       // write it out
+                       //
+                       printf( "writing %s\n", filename );
+                       SaveFile( filename, (byte *)qtex, size );
+
+                       free( qtex );
+               }
+       }
+       // Set up descriptor
+       size = sizeof( bookframe_t ) * numrects;
+
+       book.bheader.ident = IDBOOKHEADER;
+       book.bheader.version = BOOK_VERSION;
+       book.bheader.num_segments = numrects;
+       book.bheader.total_w = w;
+       book.bheader.total_h = h;
+       memcpy( book.bframes, bframes, size );
+
+       // Save out segment descriptor
+       sprintf( filename, "%sBook/%s/%s.bk", gamedir, book_prefix, lumpname );
+       printf( "writing %s\n", filename );
+       SaveFile( filename, (byte *)&book, size + sizeof( bookheader_t ) );
+}
+
+/*
+   ===============
+   Cmd_picdir
+   ===============
+ */
+void Cmd_Bookdir( void ){
+       char filename[1024];
+
+       GetScriptToken( false );
+       strcpy( book_prefix, token );
+       // create the directory if needed
+       sprintf( filename, "%sBook", gamedir );
+       Q_mkdir( filename );
+       sprintf( filename, "%sBook/%s", gamedir, book_prefix );
+       Q_mkdir( filename );
+}
+
+// end
diff --git a/tools/heretic2/h2data/fmodels.c b/tools/heretic2/h2data/fmodels.c
new file mode 100644 (file)
index 0000000..7d8df18
--- /dev/null
@@ -0,0 +1,3311 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qd_fmodel.h"
+#include "animcomp.h"
+#include "qd_skeletons.h"
+#include "skeletons.h"
+#include "qdata.h"
+#include "flex.h"
+#include "reference.h"
+
+#include <assert.h>
+
+/*
+   ========================================================================
+
+   .FM triangle flexible model file format
+
+   ========================================================================
+ */
+
+//=================================================================
+
+#define NUMVERTEXNORMALS    162
+
+extern float avertexnormals[NUMVERTEXNORMALS][3];
+
+#define MAX_GROUPS  128
+
+typedef struct
+{
+       triangle_t triangle;
+       int group;
+} trigroup_t;
+
+#define TRIVERT_DIST    .1
+
+typedef struct
+{
+       int start_frame;
+       int num_frames;
+       int degrees;
+       char *mat;
+       char *ccomp;
+       char *cbase;
+       float *cscale;
+       float *coffset;
+       float trans[3];
+       float scale[3];
+       float bmin[3];
+       float bmax[3];
+} fmgroup_t;
+
+//================================================================
+
+// Initial
+fmheader_t fmheader;
+
+// Skin
+extern char g_skins[MAX_FM_SKINS][64];
+
+// ST Coord
+extern fmstvert_t base_st[MAX_FM_VERTS];
+
+// Triangles
+extern fmtriangle_t triangles[MAX_FM_TRIANGLES];
+
+// Frames
+fmframe_t g_frames[MAX_FM_FRAMES];
+//fmframe_t    *g_FMframes;
+
+// GL Commands
+extern int commands[16384];
+extern int numcommands;
+
+
+//
+// varibles set by commands
+//
+extern float scale_up;                              // set by $scale
+extern vec3_t adjust;                               // set by $origin
+extern int g_fixedwidth, g_fixedheight;             // set by $skinsize
+extern char modelname[64];                          // set by $modelname
+
+
+extern char        *g_outputDir;
+
+
+// Mesh Nodes
+mesh_node_t *pmnodes = NULL;
+fmmeshnode_t mesh_nodes[MAX_FM_MESH_NODES];
+
+fmgroup_t groups[MAX_GROUPS];
+int num_groups;
+int frame_to_group[MAX_FM_FRAMES];
+
+//
+// variables set by command line arguments
+//
+qboolean g_no_opimizations = false;
+
+
+//
+// base frame info
+//
+static int triangle_st[MAX_FM_TRIANGLES][3][2];
+
+
+// number of gl vertices
+extern int numglverts;
+// indicates if a triangle has already been used in a glcmd
+extern int used[MAX_FM_TRIANGLES];
+// indicates if a triangle has translucency in it or not
+static qboolean translucent[MAX_FM_TRIANGLES];
+
+// main output file handle
+extern FILE         *headerouthandle;
+// output sizes of buildst()
+static int skin_width, skin_height;
+
+
+// statistics
+static int total_skin_pixels;
+static int skin_pixels_used;
+
+int ShareVertex( trigroup_t trione, trigroup_t tritwo );
+float DistBetween( vec3_t point1, vec3_t point2 );
+int GetNumTris( trigroup_t *tris, int group );
+void GetOneGroup( trigroup_t *tris, int grp, triangle_t* triangles );
+void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts );
+void NewDrawLine( int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height );
+
+#if !GDEF_OS_WINDOWS
+
+void strupr( char *string ){
+       int i;
+
+       for ( i = 0 ; i < strlen( string ); i++ )
+               toupper( string[i] );
+
+       return;
+}
+
+#endif
+//==============================================================
+
+/*
+   ===============
+   ClearModel
+   ===============
+ */
+static void ClearModel( void ){
+       memset( &fmheader, 0, sizeof( fmheader ) );
+
+       modelname[0] = 0;
+       scale_up = 1.0;
+       VectorCopy( vec3_origin, adjust );
+       g_fixedwidth = g_fixedheight = 0;
+       g_skipmodel = false;
+       num_groups = 0;
+
+       if ( pmnodes ) {
+               free( pmnodes );
+               pmnodes = NULL;
+       }
+
+       ClearSkeletalModel();
+}
+
+
+extern void H_printf( char *fmt, ... );
+
+
+void WriteHeader( FILE *FH, char *Ident, int Version, int Size, void *Data ){
+       header_t header;
+       static long pos = -1;
+       long CurrentPos;
+
+       if ( Size == 0 ) { // Don't write out empty packets
+               return;
+       }
+
+       if ( pos != -1 ) {
+               CurrentPos = ftell( FH );
+               Size = CurrentPos - pos + sizeof( header_t );
+               fseek( FH, pos, SEEK_SET );
+               pos = -2;
+       }
+       else if ( Size == -1 ) {
+               pos = ftell( FH );
+       }
+
+       memset( &header,0,sizeof( header ) );
+       strcpy( header.ident,Ident );
+       header.version = Version;
+       header.size = Size;
+
+       SafeWrite( FH, &header, sizeof( header ) );
+
+       if ( Data ) {
+               SafeWrite( FH, Data, Size );
+       }
+
+       if ( pos == -2 ) {
+               pos = -1;
+               fseek( FH, 0, SEEK_END );
+       }
+}
+
+/*
+   ============
+   WriteModelFile
+   ============
+ */
+static void WriteModelFile( FILE *modelouthandle ){
+       int i;
+       int j, k;
+       fmframe_t       *in;
+       fmaliasframe_t  *out;
+       byte buffer[MAX_FM_VERTS * 4 + 128];
+       float v;
+       int c_on, c_off;
+       IntListNode_t   *current, *toFree;
+       qboolean framesWritten = false;
+       size_t temp,size = 0;
+
+       // probably should do this dynamically one of these days
+       struct
+       {
+               float scale[3];         // multiply byte verts by this
+               float translate[3];         // then add this
+       } outFrames[MAX_FM_FRAMES];
+
+#define DATA_SIZE 0x60000       // 384K had better be enough, particularly for the reference points
+       byte data[DATA_SIZE];
+       byte data2[DATA_SIZE];
+
+       fmheader.num_glcmds = numcommands;
+       fmheader.framesize = (int)&( (fmaliasframe_t *)0 )->verts[fmheader.num_xyz];
+
+       WriteHeader( modelouthandle, FM_HEADER_NAME, FM_HEADER_VER, sizeof( fmheader ), &fmheader );
+
+       //
+       // write out the skin names
+       //
+
+       WriteHeader( modelouthandle, FM_SKIN_NAME, FM_SKIN_VER, fmheader.num_skins * MAX_FM_SKINNAME, g_skins );
+
+       //
+       // write out the texture coordinates
+       //
+       c_on = c_off = 0;
+       for ( i = 0 ; i < fmheader.num_st ; i++ )
+       {
+               base_st[i].s = LittleShort( base_st[i].s );
+               base_st[i].t = LittleShort( base_st[i].t );
+       }
+
+       WriteHeader( modelouthandle, FM_ST_NAME, FM_ST_VER, fmheader.num_st * sizeof( base_st[0] ), base_st );
+
+       //
+       // write out the triangles
+       //
+       WriteHeader( modelouthandle, FM_TRI_NAME, FM_TRI_VER, fmheader.num_tris * sizeof( fmtriangle_t ), NULL );
+
+       for ( i = 0 ; i < fmheader.num_tris ; i++ )
+       {
+               int j;
+               fmtriangle_t tri;
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       tri.index_xyz[j] = LittleShort( triangles[i].index_xyz[j] );
+                       tri.index_st[j] = LittleShort( triangles[i].index_st[j] );
+               }
+
+               SafeWrite( modelouthandle, &tri, sizeof( tri ) );
+       }
+
+       if ( !num_groups ) {
+               //
+               // write out the frames
+               //
+               WriteHeader( modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, fmheader.num_frames * fmheader.framesize, NULL );
+               //      WriteHeader(modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, -1, NULL);
+
+               for ( i = 0 ; i < fmheader.num_frames ; i++ )
+               {
+                       in = &g_frames[i];
+                       out = (fmaliasframe_t *)buffer;
+
+                       strcpy( out->name, in->name );
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               out->scale[j] = ( in->maxs[j] - in->mins[j] ) / 255;
+                               out->translate[j] = in->mins[j];
+
+                               outFrames[i].scale[j] = out->scale[j];
+                               outFrames[i].translate[j] = out->translate[j];
+                       }
+
+                       for ( j = 0 ; j < fmheader.num_xyz ; j++ )
+                       {
+                               // all of these are byte values, so no need to deal with endianness
+                               out->verts[j].lightnormalindex = in->v[j].lightnormalindex;
+
+                               for ( k = 0 ; k < 3 ; k++ )
+                               {
+                                       // scale to byte values & min/max check
+                                       v = Q_rint( ( in->v[j].v[k] - out->translate[k] ) / out->scale[k] );
+
+                                       // clamp, so rounding doesn't wrap from 255.6 to 0
+                                       if ( v > 255.0 ) {
+                                               v = 255.0;
+                                       }
+                                       if ( v < 0 ) {
+                                               v = 0;
+                                       }
+                                       out->verts[j].v[k] = v;
+                               }
+                       }
+
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               out->scale[j] = LittleFloat( out->scale[j] );
+                               out->translate[j] = LittleFloat( out->translate[j] );
+                       }
+
+                       SafeWrite( modelouthandle, out, fmheader.framesize );
+               }
+
+               // Go back and finish the header
+               //      WriteHeader(modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, -1, NULL);
+       }
+       else
+       {
+               WriteHeader( modelouthandle, FM_SHORT_FRAME_NAME, FM_SHORT_FRAME_VER,FRAME_NAME_LEN * fmheader.num_frames, NULL );
+               for ( i = 0 ; i < fmheader.num_frames ; i++ )
+               {
+                       in = &g_frames[i];
+                       SafeWrite( modelouthandle,in->name,FRAME_NAME_LEN );
+               }
+               WriteHeader( modelouthandle, FM_NORMAL_NAME, FM_NORMAL_VER,fmheader.num_xyz, NULL );
+               in = &g_frames[0];
+               for ( j = 0 ; j < fmheader.num_xyz ; j++ )
+                       SafeWrite( modelouthandle,&in->v[j].lightnormalindex,1 );
+       }
+
+       //
+       // write out glcmds
+       //
+       WriteHeader( modelouthandle, FM_GLCMDS_NAME, FM_GLCMDS_VER, numcommands * 4, commands );
+
+       //
+       // write out mesh nodes
+       //
+       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
+       {
+               memcpy( mesh_nodes[i].tris, pmnodes[i].tris, sizeof( mesh_nodes[i].tris ) );
+               memcpy( mesh_nodes[i].verts, pmnodes[i].verts, sizeof( mesh_nodes[i].verts ) );
+               mesh_nodes[i].start_glcmds = LittleShort( (short)pmnodes[i].start_glcmds );
+               mesh_nodes[i].num_glcmds = LittleShort( (short)pmnodes[i].num_glcmds );
+       }
+
+       WriteHeader( modelouthandle, FM_MESH_NAME, FM_MESH_VER, sizeof( fmmeshnode_t ) * fmheader.num_mesh_nodes, mesh_nodes );
+
+       if ( num_groups ) {
+
+/*
+   typedef struct
+   {
+    int                        start_frame;
+    int                        num_frames;
+    int                        degrees;
+    char *mat; fmheader.num_xyz*3*g->degrees*sizeof(char)
+    char *ccomp; g->num_frames*g->degrees*sizeof(char)
+    char *cbase; fmheader.num_xyz*3*sizeof(unsigned char)
+    float *cscale; g->degrees*sizeof(float)
+    float *coffset; g->degrees*sizeof(float)
+    float trans[3]; 3*sizeof(float)
+    float scale[3]; 3*sizeof(float)
+   } fmgroup_t;
+ */
+               int tmp,k;
+               fmgroup_t *g;
+               size = sizeof( int ) + fmheader.num_frames * sizeof( int );
+               for ( k = 0; k < num_groups; k++ )
+               {
+                       g = &groups[k];
+                       size += sizeof( int ) * 3;
+                       size += fmheader.num_xyz * 3 * g->degrees * sizeof( char );
+                       size += g->num_frames * g->degrees * sizeof( char );
+                       size += fmheader.num_xyz * 3 * sizeof( unsigned char );
+                       size += g->degrees * sizeof( float );
+                       size += g->degrees * sizeof( float );
+                       size += 12 * sizeof( float );
+               }
+               WriteHeader( modelouthandle, FM_COMP_NAME, FM_COMP_VER,size, NULL );
+               SafeWrite( modelouthandle,&num_groups,sizeof( int ) );
+               SafeWrite( modelouthandle,frame_to_group,sizeof( int ) * fmheader.num_frames );
+
+               for ( k = 0; k < num_groups; k++ )
+               {
+                       g = &groups[k];
+                       tmp = LittleLong( g->start_frame );
+                       SafeWrite( modelouthandle,&tmp,sizeof( int ) );
+                       tmp = LittleLong( g->num_frames );
+                       SafeWrite( modelouthandle,&tmp,sizeof( int ) );
+                       tmp = LittleLong( g->degrees );
+                       SafeWrite( modelouthandle,&tmp,sizeof( int ) );
+
+                       SafeWrite( modelouthandle,g->mat,fmheader.num_xyz * 3 * g->degrees * sizeof( char ) );
+                       SafeWrite( modelouthandle,g->ccomp,g->num_frames * g->degrees * sizeof( char ) );
+                       SafeWrite( modelouthandle,g->cbase,fmheader.num_xyz * 3 * sizeof( unsigned char ) );
+                       SafeWrite( modelouthandle,g->cscale,g->degrees * sizeof( float ) );
+                       SafeWrite( modelouthandle,g->coffset,g->degrees * sizeof( float ) );
+                       SafeWrite( modelouthandle,g->trans,3 * sizeof( float ) );
+                       SafeWrite( modelouthandle,g->scale,3 * sizeof( float ) );
+                       SafeWrite( modelouthandle,g->bmin,3 * sizeof( float ) );
+                       SafeWrite( modelouthandle,g->bmax,3 * sizeof( float ) );
+                       free( g->mat );
+                       free( g->ccomp );
+                       free( g->cbase );
+                       free( g->cscale );
+                       free( g->coffset );
+               }
+       }
+
+       // write the skeletal info
+       if ( g_skelModel.type != SKEL_NULL ) {
+               size = 0;
+
+               temp = sizeof( int );     // change this to a byte
+               memcpy( data + size, &g_skelModel.type, temp );
+               size += temp;
+
+               // number of joints
+               temp = sizeof( int );     // change this to a byte
+               memcpy( data + size, &numJointsInSkeleton[g_skelModel.type], temp );
+               size += temp;
+
+               // number of verts in each joint cluster
+               temp = sizeof( int ) * numJointsInSkeleton[g_skelModel.type]; // change this to shorts
+               memcpy( data + size, &g_skelModel.new_num_verts[1], temp );
+               size += temp;
+
+               // cluster verts
+               for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i )
+               {
+                       current = g_skelModel.vertLists[i];
+                       while ( current )
+                       {
+                               temp = sizeof( int ); // change this to a short
+                               memcpy( data + size, &current->data, temp );
+                               size += temp;
+                               toFree = current;
+                               current = current->next;
+                               free( toFree );  // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base
+                       }
+               }
+
+               if ( !num_groups ) { // joints are stored with regular verts for compressed models
+                       framesWritten = true;
+
+                       temp = sizeof( int ); // change this to a byte
+                       memcpy( data + size, &framesWritten, temp );
+                       size += temp;
+
+                       for ( i = 0; i < fmheader.num_frames; ++i )
+                       {
+                               in = &g_frames[i];
+
+                               for ( j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j )
+                               {
+                                       for ( k = 0 ; k < 3 ; k++ )
+                                       {
+                                               // scale to byte values & min/max check
+                                               v = Q_rint( ( in->joints[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                                               // write out origin as a float since they arn't clamped
+                                               temp = sizeof( float );   // change this to a short
+                                               assert( size + temp < DATA_SIZE );
+                                               memcpy( data + size, &v, temp );
+                                               size += temp;
+                                       }
+
+                                       for ( k = 0 ; k < 3 ; k++ )
+                                       {
+                                               v = Q_rint( ( in->joints[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                                               // write out origin as a float since they arn't clamped
+                                               temp = sizeof( float );   // change this to a short
+                                               assert( size + temp < DATA_SIZE );
+                                               memcpy( data + size, &v, temp );
+                                               size += temp;
+                                       }
+
+                                       for ( k = 0 ; k < 3 ; k++ )
+                                       {
+                                               v = Q_rint( ( in->joints[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                                               // write out origin as a float since they arn't clamped
+                                               temp = sizeof( float );   // change this to a short
+                                               assert( size + temp < DATA_SIZE );
+                                               memcpy( data + size, &v, temp );
+                                               size += temp;
+                                       }
+                               }
+                       }
+
+               }
+               else
+               {
+                       temp = sizeof( int ); // change this to a byte
+                       memcpy( data + size, &framesWritten, temp );
+                       size += temp;
+               }
+
+               WriteHeader( modelouthandle, FM_SKELETON_NAME, FM_SKELETON_VER, size, data );
+       }
+
+       if ( g_skelModel.references != REF_NULL ) {
+               int refnum;
+
+               size = 0;
+               if ( RefPointNum <= 0 ) { // Hard-coded labels
+                       refnum = numReferences[g_skelModel.references];
+               }
+               else
+               {   // Labels indicated in QDT
+                       refnum = RefPointNum;
+               }
+
+               temp = sizeof( int ); // change this to a byte
+               memcpy( data2 + size, &g_skelModel.references, temp );
+               size += temp;
+
+               if ( !num_groups ) {
+                       framesWritten = true;
+
+                       temp = sizeof( int ); // change this to a byte
+                       memcpy( data2 + size, &framesWritten, temp );
+                       size += temp;
+
+                       for ( i = 0; i < fmheader.num_frames; ++i )
+                       {
+                               in = &g_frames[i];
+
+                               for ( j = 0 ; j < refnum; ++j )
+                               {
+                                       for ( k = 0 ; k < 3 ; k++ )
+                                       {
+                                               // scale to byte values & min/max check
+                                               v = Q_rint( ( in->references[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                                               // write out origin as a float since they arn't clamped
+                                               temp = sizeof( float );   // change this to a short
+                                               assert( size + temp < DATA_SIZE );
+                                               memcpy( data2 + size, &v, temp );
+                                               size += temp;
+                                       }
+
+                                       for ( k = 0 ; k < 3 ; k++ )
+                                       {
+                                               v = Q_rint( ( in->references[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                                               // write out origin as a float since they arn't clamped
+                                               temp = sizeof( float );   // change this to a short
+                                               assert( size + temp < DATA_SIZE );
+                                               memcpy( data2 + size, &v, temp );
+                                               size += temp;
+                                       }
+
+                                       for ( k = 0 ; k < 3 ; k++ )
+                                       {
+                                               v = Q_rint( ( in->references[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                                               // write out origin as a float since they arn't clamped
+                                               temp = sizeof( float );   // change this to a short
+                                               assert( size + temp < DATA_SIZE );
+                                               memcpy( data2 + size, &v, temp );
+                                               size += temp;
+                                       }
+                               }
+                       }
+               }
+               else    // FINISH ME: references need to be stored with regular verts for compressed models
+               {
+                       framesWritten = false;
+
+                       temp = sizeof( int ); // change this to a byte
+                       memcpy( data2 + size, &framesWritten, temp );
+                       size += temp;
+               }
+
+               WriteHeader( modelouthandle, FM_REFERENCES_NAME, FM_REFERENCES_VER, size, data2 );
+       }
+}
+
+static void CompressFrames(){
+       fmgroup_t *g;
+       int i,j,k;
+       fmframe_t   *in;
+
+       j = 0;
+       for ( i = 0; i < fmheader.num_frames; i++ )
+       {
+               while ( i >= groups[j].start_frame + groups[j].num_frames && j < num_groups - 1 )
+                       j++;
+               frame_to_group[i] = j;
+       }
+
+       for ( k = 0; k < num_groups; k++ )
+       {
+               g = &groups[k];
+
+               printf( "\nCompressing Frames for group %i...\n", k );
+               AnimCompressInit( g->num_frames,fmheader.num_xyz,g->degrees );
+               for ( i = 0; i < g->num_frames; i++ )
+               {
+                       in = &g_frames[i + g->start_frame];
+                       for ( j = 0; j < fmheader.num_xyz; j++ )
+                               AnimSetFrame( i,j,in->v[j].v[0],in->v[j].v[1],in->v[j].v[2] );
+               }
+               AnimCompressDoit();
+               g->mat = (char *) SafeMalloc( fmheader.num_xyz * 3 * g->degrees * sizeof( char ), "CompressFrames" );
+               g->ccomp = (char *) SafeMalloc( g->num_frames * g->degrees * sizeof( char ), "CompressFrames" );
+               g->cbase = (char *) SafeMalloc( fmheader.num_xyz * 3 * sizeof( unsigned char ), "CompressFrames" );
+               g->cscale = (float *) SafeMalloc( g->degrees * sizeof( float ), "CompressFrames" );
+               g->coffset = (float *) SafeMalloc( g->degrees * sizeof( float ), "CompressFrames" );
+               AnimCompressToBytes( g->trans,g->scale,g->mat,g->ccomp,g->cbase,g->cscale,g->coffset,g->bmin,g->bmax );
+               AnimCompressEnd();
+       }
+}
+
+static void OptimizeVertices( void ){
+       qboolean vert_used[MAX_FM_VERTS];
+       short vert_replacement[MAX_FM_VERTS];
+       int i,j,k,l,pos,bit,set_pos,set_bit;
+       fmframe_t   *in;
+       qboolean Found;
+       int num_unique;
+       static IntListNode_t *newVertLists[NUM_CLUSTERS];
+       static int newNum_verts[NUM_CLUSTERS];
+       IntListNode_t *current, *next;
+
+       printf( "Optimizing vertices..." );
+
+       memset( vert_used, 0, sizeof( vert_used ) );
+
+       if ( g_skelModel.clustered == true ) {
+               memset( newNum_verts, 0, sizeof( newNum_verts ) );
+               memset( newVertLists, 0, sizeof( newVertLists ) );
+       }
+
+       num_unique = 0;
+
+       // search for common points among all the frames
+       for ( i = 0 ; i < fmheader.num_frames ; i++ )
+       {
+               in = &g_frames[i];
+
+               for ( j = 0; j < fmheader.num_xyz; j++ )
+               {
+                       for ( k = 0,Found = false; k < j; k++ )
+                       {   // starting from the beginning always ensures vert_replacement points to the first point in the array
+                               if ( in->v[j].v[0] == in->v[k].v[0] &&
+                                        in->v[j].v[1] == in->v[k].v[1] &&
+                                        in->v[j].v[2] == in->v[k].v[2] ) {
+                                       Found = true;
+                                       vert_replacement[j] = k;
+                                       break;
+                               }
+
+                       }
+
+                       if ( !Found ) {
+                               if ( !vert_used[j] ) {
+                                       num_unique++;
+                               }
+                               vert_used[j] = true;
+                       }
+               }
+       }
+
+       // recompute the light normals
+       for ( i = 0 ; i < fmheader.num_frames ; i++ )
+       {
+               in = &g_frames[i];
+
+               for ( j = 0; j < fmheader.num_xyz; j++ )
+               {
+                       if ( !vert_used[j] ) {
+                               k = vert_replacement[j];
+
+                               VectorAdd( in->v[j].vnorm.normalsum, in->v[k].vnorm.normalsum, in->v[k].vnorm.normalsum );
+                               in->v[k].vnorm.numnormals += in->v[j].vnorm.numnormals++;
+                       }
+               }
+
+               for ( j = 0 ; j < fmheader.num_xyz ; j++ )
+               {
+                       vec3_t v;
+                       float maxdot;
+                       int maxdotindex;
+                       int c;
+
+                       c = in->v[j].vnorm.numnormals;
+                       if ( !c ) {
+                               Error( "Vertex with no triangles attached" );
+                       }
+
+                       VectorScale( in->v[j].vnorm.normalsum, 1.0 / c, v );
+                       VectorNormalize( v, v );
+
+                       maxdot = -999999.0;
+                       maxdotindex = -1;
+
+                       for ( k = 0 ; k < NUMVERTEXNORMALS ; k++ )
+                       {
+                               float dot;
+
+                               dot = DotProduct( v, avertexnormals[k] );
+                               if ( dot > maxdot ) {
+                                       maxdot = dot;
+                                       maxdotindex = k;
+                               }
+                       }
+
+                       in->v[j].lightnormalindex = maxdotindex;
+               }
+       }
+
+       // create substitution list
+       num_unique = 0;
+       for ( i = 0; i < fmheader.num_xyz; i++ )
+       {
+               if ( vert_used[i] ) {
+                       vert_replacement[i] = num_unique;
+                       num_unique++;
+               }
+               else
+               {
+                       vert_replacement[i] = vert_replacement[vert_replacement[i]];
+               }
+
+               // vert_replacement[i] is the new index, i is the old index
+               // need to add the new index to the cluster list if old index was in it
+               if ( g_skelModel.clustered == true ) {
+                       for ( k = 0; k < numJointsInSkeleton[g_skelModel.type]; ++k )
+                       {
+                               for ( l = 0, current = g_skelModel.vertLists[k];
+                                         l < g_skelModel.new_num_verts[k + 1]; ++l, current = current->next )
+                               {
+                                       if ( current->data == i ) {
+                                               IntListNode_t *current2;
+                                               int m;
+                                               qboolean added = false;
+
+                                               for ( m = 0, current2 = newVertLists[k]; m < newNum_verts[k + 1];
+                                                         ++m, current2 = current2->next )
+                                               {
+                                                       if ( current2->data == vert_replacement[i] ) {
+                                                               added = true;
+                                                               break;
+                                                       }
+                                               }
+
+                                               if ( !added ) {
+                                                       ++newNum_verts[k + 1];
+
+                                                       next = newVertLists[k];
+
+                                                       newVertLists[k] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "OptimizeVertices" );
+                                                       // freed after model write out
+
+                                                       newVertLists[k]->data = vert_replacement[i];
+                                                       newVertLists[k]->next = next;
+                                               }
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // substitute
+       for ( i = 0 ; i < fmheader.num_frames ; i++ )
+       {
+               in = &g_frames[i];
+
+               for ( j = 0; j < fmheader.num_xyz; j++ )
+               {
+                       in->v[vert_replacement[j]] = in->v[j];
+               }
+
+       }
+
+       for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i )
+       {
+               IntListNode_t *toFree;
+               current = g_skelModel.vertLists[i];
+
+               while ( current )
+               {
+                       toFree = current;
+                       current = current->next;
+                       free( toFree );  // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base
+               }
+
+               g_skelModel.vertLists[i] = newVertLists[i];
+               g_skelModel.new_num_verts[i + 1] = newNum_verts[i + 1];
+       }
+
+#ifndef NDEBUG
+       for ( k = 0; k < numJointsInSkeleton[g_skelModel.type]; ++k )
+       {
+               for ( l = 0, current = g_skelModel.vertLists[k];
+                         l < g_skelModel.new_num_verts[k + 1]; ++l, current = current->next )
+               {
+                       IntListNode_t *current2;
+                       int m;
+
+                       for ( m = l + 1, current2 = current->next; m < newNum_verts[k + 1];
+                                 ++m, current2 = current2->next )
+                       {
+                               if ( current->data == current2->data ) {
+                                       printf( "Warning duplicate vertex:  %d\n", current->data );
+                                       break;
+                               }
+                       }
+               }
+       }
+#endif
+
+       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
+       {   // reset the vert bits
+               memset( pmnodes[i].verts,0,sizeof( pmnodes[i].verts ) );
+       }
+
+       // repleace the master triangle list vertex indexes and update the vert bits for each mesh node
+       for ( i = 0 ; i < fmheader.num_tris ; i++ )
+       {
+               pos = i >> 3;
+               bit = 1 << ( i & 7 );
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       set_bit = set_pos = triangles[i].index_xyz[j] = vert_replacement[triangles[i].index_xyz[j]];
+
+                       set_pos >>= 3;
+                       set_bit = 1 << ( set_bit & 7 );
+
+                       for ( k = 0; k < fmheader.num_mesh_nodes; k++ )
+                       {
+                               if ( !( pmnodes[k].tris[pos] & bit ) ) {
+                                       continue;
+                               }
+                               pmnodes[k].verts[set_pos] |= set_bit;
+                       }
+               }
+       }
+
+       for ( i = 0; i < numcommands; i++ )
+       {
+               j = commands[i];
+               if ( !j ) {
+                       continue;
+               }
+
+               j = abs( j );
+               for ( i++; j; j--,i += 3 )
+               {
+                       commands[i + 2] = vert_replacement[commands[i + 2]];
+               }
+               i--;
+       }
+
+       printf( "Reduced by %d\n",fmheader.num_xyz - num_unique );
+
+       fmheader.num_xyz = num_unique;
+       if ( num_groups ) {
+               // tack on the reference verts to the regular verts
+               if ( g_skelModel.references != REF_NULL ) {
+                       fmframe_t   *in;
+                       int index;
+                       int refnum;
+
+                       if ( RefPointNum <= 0 ) { // Hard-coded labels
+                               refnum = numReferences[g_skelModel.references];
+                       }
+                       else
+                       {   // Labels indicated in QDT
+                               refnum = RefPointNum;
+                       }
+
+
+                       for ( i = 0; i < fmheader.num_frames; ++i )
+                       {
+                               in = &g_frames[i];
+                               index = fmheader.num_xyz;
+
+                               for ( j = 0 ; j < refnum; ++j )
+                               {
+                                       VectorCopy( in->references[j].placement.origin, in->v[index].v );
+                                       index++;
+
+                                       VectorCopy( in->references[j].placement.direction, in->v[index].v );
+                                       index++;
+
+                                       VectorCopy( in->references[j].placement.up, in->v[index].v );
+                                       index++;
+                               }
+                       }
+
+                       fmheader.num_xyz += refnum * 3;
+               }
+
+               // tack on the skeletal joint verts to the regular verts
+               if ( g_skelModel.type != SKEL_NULL ) {
+                       fmframe_t   *in;
+                       int index;
+
+                       for ( i = 0; i < fmheader.num_frames; ++i )
+                       {
+                               in = &g_frames[i];
+                               index = fmheader.num_xyz;
+
+                               for ( j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j )
+                               {
+                                       VectorCopy( in->joints[j].placement.origin, in->v[index].v );
+                                       index++;
+
+                                       VectorCopy( in->joints[j].placement.direction, in->v[index].v );
+                                       index++;
+
+                                       VectorCopy( in->joints[j].placement.up, in->v[index].v );
+                                       index++;
+                               }
+                       }
+
+                       fmheader.num_xyz += numJointsInSkeleton[g_skelModel.type] * 3;
+               }
+
+               CompressFrames();
+       }
+}
+
+
+/*
+   ===============
+   FinishModel
+   ===============
+ */
+void FMFinishModel( void ){
+       FILE        *modelouthandle;
+       int i,j,length,tris,verts,bit,pos,total_tris,total_verts;
+       char name[1024];
+       int trans_count;
+
+       if ( !fmheader.num_frames ) {
+               return;
+       }
+
+//
+// copy to release directory tree if doing a release build
+//
+       if ( g_release ) {
+               if ( modelname[0] ) {
+                       sprintf( name, "%s", modelname );
+               }
+               else{
+                       sprintf( name, "%s/tris.fm", cdpartial );
+               }
+               ReleaseFile( name );
+
+               for ( i = 0 ; i < fmheader.num_skins ; i++ )
+               {
+                       ReleaseFile( g_skins[i] );
+               }
+               fmheader.num_frames = 0;
+               return;
+       }
+
+       printf( "\n" );
+
+       trans_count = 0;
+       for ( i = 0; i < fmheader.num_tris; i++ )
+               if ( translucent[i] ) {
+                       trans_count++;
+               }
+
+       if ( !g_no_opimizations ) {
+               OptimizeVertices();
+       }
+
+//
+// write the model output file
+//
+       if ( modelname[0] ) {
+               sprintf( name, "%s%s", g_outputDir, modelname );
+       }
+       else{
+               sprintf( name, "%s/tris.fm", g_outputDir );
+       }
+       printf( "saving to %s\n", name );
+       CreatePath( name );
+       modelouthandle = SafeOpenWrite( name );
+
+       WriteModelFile( modelouthandle );
+
+       printf( "%3dx%3d skin\n", fmheader.skinwidth, fmheader.skinheight );
+       printf( "First frame boundaries:\n" );
+       printf( "       minimum x: %3f\n", g_frames[0].mins[0] );
+       printf( "       maximum x: %3f\n", g_frames[0].maxs[0] );
+       printf( "       minimum y: %3f\n", g_frames[0].mins[1] );
+       printf( "       maximum y: %3f\n", g_frames[0].maxs[1] );
+       printf( "       minimum z: %3f\n", g_frames[0].mins[2] );
+       printf( "       maximum z: %3f\n", g_frames[0].maxs[2] );
+       printf( "%4d vertices\n", fmheader.num_xyz );
+       printf( "%4d triangles, %4d of them translucent\n", fmheader.num_tris, trans_count );
+       printf( "%4d frame\n", fmheader.num_frames );
+       printf( "%4d glverts\n", numglverts );
+       printf( "%4d glcmd\n", fmheader.num_glcmds );
+       printf( "%4d skins\n", fmheader.num_skins );
+       printf( "%4d mesh nodes\n", fmheader.num_mesh_nodes );
+       printf( "wasted pixels: %d / %d (%5.2f Percent)\n",total_skin_pixels - skin_pixels_used,
+                       total_skin_pixels, (double)( total_skin_pixels - skin_pixels_used ) / (double)total_skin_pixels * 100.0 );
+
+       printf( "file size: %d\n", (int)ftell( modelouthandle ) );
+       printf( "---------------------\n" );
+
+       if ( g_verbose ) {
+               if ( fmheader.num_mesh_nodes ) {
+                       total_tris = total_verts = 0;
+                       printf( "Node Name                         Tris Verts\n" );
+                       printf( "--------------------------------- ---- -----\n" );
+                       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
+                       {
+                               tris = 0;
+                               verts = 0;
+                               for ( j = 0; j < MAXTRIANGLES; j++ )
+                               {
+                                       pos = ( j ) >> 3;
+                                       bit = 1 << ( ( j ) & 7 );
+                                       if ( pmnodes[i].tris[pos] & bit ) {
+                                               tris++;
+                                       }
+                               }
+                               for ( j = 0; j < MAX_FM_VERTS; j++ )
+                               {
+                                       pos = ( j ) >> 3;
+                                       bit = 1 << ( ( j ) & 7 );
+                                       if ( pmnodes[i].verts[pos] & bit ) {
+                                               verts++;
+                                       }
+                               }
+
+                               printf( "%-33s %4d %5d\n",pmnodes[i].name,tris,verts );
+
+                               total_tris += tris;
+                               total_verts += verts;
+                       }
+                       printf( "--------------------------------- ---- -----\n" );
+                       printf( "%-33s %4d %5d\n","TOTALS",total_tris,total_verts );
+               }
+       }
+       fclose( modelouthandle );
+
+       // finish writing header file
+       H_printf( "\n" );
+
+       // scale_up is usefull to allow step distances to be adjusted
+       H_printf( "#define MODEL_SCALE\t\t%f\n", scale_up );
+
+       // mesh nodes
+       if ( fmheader.num_mesh_nodes ) {
+               H_printf( "\n" );
+               H_printf( "#define NUM_MESH_NODES\t\t%d\n\n",fmheader.num_mesh_nodes );
+               for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
+               {
+                       strcpy( name, pmnodes[i].name );
+                       strupr( name );
+                       length = strlen( name );
+                       for ( j = 0; j < length; j++ )
+                       {
+                               if ( name[j] == ' ' ) {
+                                       name[j] = '_';
+                               }
+                       }
+                       H_printf( "#define MESH_%s\t\t%d\n", name, i );
+               }
+       }
+
+       fclose( headerouthandle );
+       headerouthandle = NULL;
+       free( pmnodes );
+}
+
+
+/*
+   =================================================================
+
+   ALIAS MODEL DISPLAY LIST GENERATION
+
+   =================================================================
+ */
+
+extern int strip_xyz[128];
+extern int strip_st[128];
+extern int strip_tris[128];
+extern int stripcount;
+
+/*
+   ================
+   StripLength
+   ================
+ */
+static int  StripLength( int starttri, int startv, int num_tris, int node ){
+       int m1, m2;
+       int st1, st2;
+       int j;
+       fmtriangle_t    *last, *check;
+       int k;
+       int pos, bit;
+
+       used[starttri] = 2;
+
+       last = &triangles[starttri];
+
+       strip_xyz[0] = last->index_xyz[( startv ) % 3];
+       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
+       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
+       strip_st[0] = last->index_st[( startv ) % 3];
+       strip_st[1] = last->index_st[( startv + 1 ) % 3];
+       strip_st[2] = last->index_st[( startv + 2 ) % 3];
+
+       strip_tris[0] = starttri;
+       stripcount = 1;
+
+       m1 = last->index_xyz[( startv + 2 ) % 3];
+       st1 = last->index_st[( startv + 2 ) % 3];
+       m2 = last->index_xyz[( startv + 1 ) % 3];
+       st2 = last->index_st[( startv + 1 ) % 3];
+
+       // look for a matching triangle
+nexttri:
+       for ( j = starttri + 1, check = &triangles[starttri + 1]
+                 ; j < num_tris ; j++, check++ )
+       {
+               pos = j >> 3;
+               bit = 1 << ( j & 7 );
+               if ( !( pmnodes[node].tris[pos] & bit ) ) {
+                       continue;
+               }
+               for ( k = 0 ; k < 3 ; k++ )
+               {
+                       if ( check->index_xyz[k] != m1 ) {
+                               continue;
+                       }
+                       if ( check->index_st[k] != st1 ) {
+                               continue;
+                       }
+                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
+                               continue;
+                       }
+                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
+                               continue;
+                       }
+
+                       // this is the next part of the fan
+
+                       // if we can't use this triangle, this tristrip is done
+                       if ( used[j] || translucent[j] != translucent[starttri] ) {
+                               goto done;
+                       }
+
+                       // the new edge
+                       if ( stripcount & 1 ) {
+                               m2 = check->index_xyz[ ( k + 2 ) % 3 ];
+                               st2 = check->index_st[ ( k + 2 ) % 3 ];
+                       }
+                       else
+                       {
+                               m1 = check->index_xyz[ ( k + 2 ) % 3 ];
+                               st1 = check->index_st[ ( k + 2 ) % 3 ];
+                       }
+
+                       strip_xyz[stripcount + 2] = check->index_xyz[ ( k + 2 ) % 3 ];
+                       strip_st[stripcount + 2] = check->index_st[ ( k + 2 ) % 3 ];
+                       strip_tris[stripcount] = j;
+                       stripcount++;
+
+                       used[j] = 2;
+                       goto nexttri;
+               }
+       }
+done:
+
+       // clear the temp used flags
+       for ( j = starttri + 1 ; j < num_tris ; j++ )
+               if ( used[j] == 2 ) {
+                       used[j] = 0;
+               }
+
+       return stripcount;
+}
+
+
+/*
+   ===========
+   FanLength
+   ===========
+ */
+static int  FanLength( int starttri, int startv, int num_tris, int node ){
+       int m1, m2;
+       int st1, st2;
+       int j;
+       fmtriangle_t    *last, *check;
+       int k;
+       int pos, bit;
+
+       used[starttri] = 2;
+
+       last = &triangles[starttri];
+
+       strip_xyz[0] = last->index_xyz[( startv ) % 3];
+       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
+       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
+       strip_st[0] = last->index_st[( startv ) % 3];
+       strip_st[1] = last->index_st[( startv + 1 ) % 3];
+       strip_st[2] = last->index_st[( startv + 2 ) % 3];
+
+       strip_tris[0] = starttri;
+       stripcount = 1;
+
+       m1 = last->index_xyz[( startv + 0 ) % 3];
+       st1 = last->index_st[( startv + 0 ) % 3];
+       m2 = last->index_xyz[( startv + 2 ) % 3];
+       st2 = last->index_st[( startv + 2 ) % 3];
+
+
+       // look for a matching triangle
+nexttri:
+       for ( j = starttri + 1, check = &triangles[starttri + 1]
+                 ; j < num_tris ; j++, check++ )
+       {
+               pos = j >> 3;
+               bit = 1 << ( j & 7 );
+               if ( !( pmnodes[node].tris[pos] & bit ) ) {
+                       continue;
+               }
+               for ( k = 0 ; k < 3 ; k++ )
+               {
+                       if ( check->index_xyz[k] != m1 ) {
+                               continue;
+                       }
+                       if ( check->index_st[k] != st1 ) {
+                               continue;
+                       }
+                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
+                               continue;
+                       }
+                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
+                               continue;
+                       }
+
+                       // this is the next part of the fan
+
+                       // if we can't use this triangle, this tristrip is done
+                       if ( used[j] || translucent[j] != translucent[starttri] ) {
+                               goto done;
+                       }
+
+                       // the new edge
+                       m2 = check->index_xyz[ ( k + 2 ) % 3 ];
+                       st2 = check->index_st[ ( k + 2 ) % 3 ];
+
+                       strip_xyz[stripcount + 2] = m2;
+                       strip_st[stripcount + 2] = st2;
+                       strip_tris[stripcount] = j;
+                       stripcount++;
+
+                       used[j] = 2;
+                       goto nexttri;
+               }
+       }
+done:
+
+       // clear the temp used flags
+       for ( j = starttri + 1 ; j < num_tris ; j++ )
+               if ( used[j] == 2 ) {
+                       used[j] = 0;
+               }
+
+       return stripcount;
+}
+
+
+
+/*
+   ================
+   BuildGlCmds
+
+   Generate a list of trifans or strips
+   for the model, which holds for all frames
+   ================
+ */
+static void BuildGlCmds( void ){
+       int i, j, k, l;
+       int startv;
+       float s, t;
+       int len, bestlen, besttype;
+       int best_xyz[1024];
+       int best_st[1024];
+       int best_tris[1024];
+       int type;
+       int trans_check;
+       int bit,pos;
+
+       //
+       // build tristrips
+       //
+       numcommands = 0;
+       numglverts = 0;
+
+
+       for ( l = 0; l < fmheader.num_mesh_nodes; l++ )
+       {
+               memset( used, 0, sizeof( used ) );
+
+               pmnodes[l].start_glcmds = numcommands;
+
+               for ( trans_check = 0; trans_check < 2; trans_check++ )
+               {
+                       for ( i = 0 ; i < fmheader.num_tris ; i++ )
+                       {
+                               pos = i >> 3;
+                               bit = 1 << ( i & 7 );
+                               if ( !( pmnodes[l].tris[pos] & bit ) ) {
+                                       continue;
+                               }
+
+                               // pick an unused triangle and start the trifan
+                               if ( used[i] || trans_check != translucent[i] ) {
+                                       continue;
+                               }
+
+                               bestlen = 0;
+                               for ( type = 0 ; type < 2 ; type++ )
+                               //      type = 1;
+                               {
+                                       for ( startv = 0 ; startv < 3 ; startv++ )
+                                       {
+                                               if ( type == 1 ) {
+                                                       len = StripLength( i, startv, fmheader.num_tris, l );
+                                               }
+                                               else{
+                                                       len = FanLength( i, startv, fmheader.num_tris, l );
+                                               }
+                                               if ( len > bestlen ) {
+                                                       besttype = type;
+                                                       bestlen = len;
+                                                       for ( j = 0 ; j < bestlen + 2 ; j++ )
+                                                       {
+                                                               best_st[j] = strip_st[j];
+                                                               best_xyz[j] = strip_xyz[j];
+                                                       }
+                                                       for ( j = 0 ; j < bestlen ; j++ )
+                                                               best_tris[j] = strip_tris[j];
+                                               }
+                                       }
+                               }
+
+                               // mark the tris on the best strip/fan as used
+                               for ( j = 0 ; j < bestlen ; j++ )
+                                       used[best_tris[j]] = 1;
+
+                               if ( besttype == 1 ) {
+                                       commands[numcommands++] = ( bestlen + 2 );
+                               }
+                               else{
+                                       commands[numcommands++] = -( bestlen + 2 );
+                               }
+
+                               numglverts += bestlen + 2;
+
+                               for ( j = 0 ; j < bestlen + 2 ; j++ )
+                               {
+                                       // emit a vertex into the reorder buffer
+                                       k = best_st[j];
+
+                                       // emit s/t coords into the commands stream
+                                       s = base_st[k].s;
+                                       t = base_st[k].t;
+
+                                       s = ( s  ) / fmheader.skinwidth;
+                                       t = ( t  ) / fmheader.skinheight;
+
+                                       *(float *)&commands[numcommands++] = s;
+                                       *(float *)&commands[numcommands++] = t;
+                                       *(int *)&commands[numcommands++] = best_xyz[j];
+                               }
+                       }
+               }
+               commands[numcommands++] = 0;        // end of list marker
+               pmnodes[l].num_glcmds = numcommands - pmnodes[l].start_glcmds;
+       }
+}
+
+
+/*
+   ===============================================================
+
+   BASE FRAME SETUP
+
+   ===============================================================
+ */
+
+
+#define LINE_NORMAL 1
+#define LINE_FAT 2
+#define LINE_DOTTED 3
+
+
+#define ASCII_SPACE 32
+
+int LineType = LINE_NORMAL;
+extern unsigned char pic[SKINPAGE_HEIGHT * SKINPAGE_WIDTH], pic_palette[768];
+unsigned char LineColor = 255;
+int ScaleWidth, ScaleHeight;
+
+
+static char *CharDefs[] =
+{
+       "-------------------------",
+       "-------------------------", // !
+       "-------------------------", // "
+       "-------------------------", // #
+       "-------------------------", // $
+       "-------------------------", // %
+       "-------------------------", // &
+       "--*----*-----------------", // '
+       "-*---*----*----*-----*---", // (
+       "*-----*----*----*---*----", // )
+       "-----*--*--**---**--*--*-", // *
+       "-------------------------", // +
+       "----------------**--**---", // ,
+       "-------------------------", // -
+       "----------------**---**--", // .
+       "-------------------------", // /
+       " *** *  *** * ***  * *** ", // 0
+       "   *   **    *    *    * ",
+       "****     * *** *    *****",
+       "****     * ***     ***** ",
+       "  **  * * *  * *****   * ",
+       "**** *    ****     ***** ",
+       " *** *    **** *   * *** ",
+       "*****    *   *   *    *  ",
+       " *** *   * *** *   * *** ",
+       " *** *   * ****    * *** ", // 9
+       "-**---**--------**---**--", // :
+       "-------------------------", // ;
+       "-------------------------", // <
+       "-------------------------", // =
+       "-------------------------", // >
+       "-------------------------", // ?
+       "-------------------------", // @
+       "-***-*---*******---**---*", // A
+       "****-*---*****-*---*****-",
+       "-*****----*----*-----****",
+       "****-*---**---**---*****-",
+       "******----****-*----*****",
+       "******----****-*----*----",
+       "-*****----*--***---*-****",
+       "*---**---*******---**---*",
+       "-***---*----*----*---***-",
+       "----*----*----**---*-***-",
+       "-*--*-*-*--**---*-*--*--*",
+       "-*----*----*----*----****",
+       "*---***-***-*-**---**---*",
+       "*---***--**-*-**--***---*",
+       "-***-*---**---**---*-***-",
+       "****-*---*****-*----*----",
+       "-***-*---**---*-***----**",
+       "****-*---*****-*-*--*--**",
+       "-*****-----***-----*****-",
+       "*****--*----*----*----*--",
+       "*---**---**---**---******",
+       "*---**---**---*-*-*---*--",
+       "*---**---**-*-***-***---*",
+       "*---*-*-*---*---*-*-*---*",
+       "*---**---*-*-*---*----*--",
+       "*****---*---*---*---*****" // Z
+};
+
+void DrawLine( int x1, int y1, int x2, int y2 ){
+       int dx, dy;
+       int adx, ady;
+       int count;
+       float xfrac, yfrac, xstep, ystep;
+       unsigned sx, sy;
+       float u, v;
+
+       dx = x2 - x1;
+       dy = y2 - y1;
+       adx = abs( dx );
+       ady = abs( dy );
+
+       count = adx > ady ? adx : ady;
+       count++;
+
+       if ( count > 300 ) {
+               printf( "Bad count\n" );
+               return; // don't ever hang up on bad data
+       }
+
+       xfrac = x1;
+       yfrac = y1;
+
+       xstep = (float)dx / count;
+       ystep = (float)dy / count;
+
+       switch ( LineType )
+       {
+       case LINE_NORMAL:
+               do
+               {
+                       if ( xfrac < SKINPAGE_WIDTH && yfrac < SKINPAGE_HEIGHT ) {
+                               pic[(int)yfrac * SKINPAGE_WIDTH + (int)xfrac] = LineColor;
+                       }
+                       xfrac += xstep;
+                       yfrac += ystep;
+                       count--;
+               } while ( count > 0 );
+               break;
+       case LINE_FAT:
+               do
+               {
+                       for ( u = -0.1 ; u <= 0.9 ; u += 0.999 )
+                       {
+                               for ( v = -0.1 ; v <= 0.9 ; v += 0.999 )
+                               {
+                                       sx = xfrac + u;
+                                       sy = yfrac + v;
+                                       if ( sx < SKINPAGE_WIDTH && sy < SKINPAGE_HEIGHT ) {
+                                               pic[sy * SKINPAGE_WIDTH + sx] = LineColor;
+                                       }
+                               }
+                       }
+                       xfrac += xstep;
+                       yfrac += ystep;
+                       count--;
+               } while ( count > 0 );
+               break;
+       case LINE_DOTTED:
+               do
+               {
+                       if ( count & 1 && xfrac < SKINPAGE_WIDTH &&
+                                yfrac < SKINPAGE_HEIGHT ) {
+                               pic[(int)yfrac * SKINPAGE_WIDTH + (int)xfrac] = LineColor;
+                       }
+                       xfrac += xstep;
+                       yfrac += ystep;
+                       count--;
+               } while ( count > 0 );
+               break;
+       default:
+               Error( "Unknown <linetype> %d.\n", LineType );
+       }
+}
+
+//==========================================================================
+//
+// DrawCharacter
+//
+//==========================================================================
+
+static void DrawCharacter( int x, int y, int character ){
+       int r, c;
+       char *def;
+
+       character = toupper( character );
+       if ( character < ASCII_SPACE || character > 'Z' ) {
+               character = ASCII_SPACE;
+       }
+       character -= ASCII_SPACE;
+       for ( def = CharDefs[character], r = 0; r < 5; r++ )
+       {
+               for ( c = 0; c < 5; c++ )
+               {
+                       pic[( y + r ) * SKINPAGE_WIDTH + x + c] = *def++ == '*' ? 255 : 0;
+               }
+       }
+}
+
+//==========================================================================
+//
+// DrawTextChar
+//
+//==========================================================================
+
+void DrawTextChar( int x, int y, char *text ){
+       int c;
+
+       while ( ( c = *text++ ) != '\0' )
+       {
+               DrawCharacter( x, y, c );
+               x += 6;
+       }
+}
+
+
+extern void DrawScreen( float s_scale, float t_scale, float iwidth, float iheight );
+
+//==========================================================================
+// ExtractDigit
+
+static int ExtractDigit( byte *pic, int x, int y ){
+       int i;
+       int r, c;
+       char digString[32];
+       char    *buffer;
+       byte backColor;
+       char    **DigitDefs;
+
+       backColor = pic[( SKINPAGE_HEIGHT - 1 ) * SKINPAGE_WIDTH];
+       DigitDefs = &CharDefs['0' - ASCII_SPACE];
+
+       buffer = digString;
+       for ( r = 0; r < 5; r++ )
+       {
+               for ( c = 0; c < 5; c++ )
+               {
+                       *buffer++ = ( pic[( y + r ) * SKINPAGE_WIDTH + x + c] == backColor ) ? ' ' : '*';
+               }
+       }
+       *buffer = '\0';
+       for ( i = 0; i < 10; i++ )
+       {
+               if ( strcmp( DigitDefs[i], digString ) == 0 ) {
+                       return i;
+               }
+       }
+
+       Error( "Unable to extract scaling info from skin PCX." );
+       return 0;
+}
+
+//==========================================================================
+// ExtractNumber
+
+int ExtractNumber( byte *pic, int x, int y ){
+       return ExtractDigit( pic, x, y ) * 100 + ExtractDigit( pic, x + 6, y ) * 10 + ExtractDigit( pic, x + 12, y );
+}
+
+
+
+
+
+/*
+   ============
+   BuildST
+
+   Builds the triangle_st array for the base frame and
+   fmheader.skinwidth / fmheader.skinheight
+
+   FIXME: allow this to be loaded from a file for
+   arbitrary mappings
+   ============
+ */
+static void BuildST( triangle_t *ptri, int numtri, qboolean DrawSkin ){
+       int backface_flag;
+       int i, j;
+       int width, height, iwidth, iheight, swidth;
+       float basex, basey;
+       float scale;
+       vec3_t mins, maxs;
+       float       *pbasevert;
+       vec3_t vtemp1, vtemp2, normal;
+       float s_scale, t_scale;
+       float scWidth;
+       float scHeight;
+       int skinwidth;
+       int skinheight;
+
+       //
+       // find bounds of all the verts on the base frame
+       //
+       ClearBounds( mins, maxs );
+       backface_flag = false;
+
+       if ( ptri[0].HasUV ) { // if we have the uv already, we don't want to double up or scale
+               iwidth = ScaleWidth;
+               iheight = ScaleHeight;
+
+               t_scale = s_scale = 1.0;
+       }
+       else
+       {
+               for ( i = 0 ; i < numtri ; i++ )
+                       for ( j = 0 ; j < 3 ; j++ )
+                               AddPointToBounds( ptri[i].verts[j], mins, maxs );
+
+               for ( i = 0 ; i < 3 ; i++ )
+               {
+                       mins[i] = floor( mins[i] );
+                       maxs[i] = ceil( maxs[i] );
+               }
+
+               width = maxs[0] - mins[0];
+               height = maxs[2] - mins[2];
+
+               for ( i = 0 ; i < numtri ; i++ )
+               {
+                       VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
+                       VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
+                       CrossProduct( vtemp1, vtemp2, normal );
+
+                       if ( normal[1] > 0 ) {
+                               backface_flag = true;
+                               break;
+                       }
+               }
+               scWidth = ScaleWidth * SCALE_ADJUST_FACTOR;
+               if ( backface_flag ) {  //we are doubling
+                       scWidth /= 2;
+               }
+
+               scHeight = ScaleHeight * SCALE_ADJUST_FACTOR;
+
+               scale = scWidth / width;
+
+               if ( height * scale >= scHeight ) {
+                       scale = scHeight / height;
+               }
+
+               iwidth = ceil( width * scale ) + 4;
+               iheight = ceil( height * scale ) + 4;
+
+               s_scale = (float)( iwidth - 4 ) / width;
+               t_scale = (float)( iheight - 4 ) / height;
+               t_scale = s_scale;
+       }
+       if ( DrawSkin ) {
+               if ( backface_flag ) {
+                       DrawScreen( s_scale, t_scale, iwidth * 2, iheight );
+               }
+               else{
+                       DrawScreen( s_scale, t_scale, iwidth, iheight );
+               }
+       }
+       if ( backface_flag ) {
+               skinwidth = iwidth * 2;
+       }
+       else{
+               skinwidth = iwidth;
+       }
+       skinheight = iheight;
+
+
+/*     if (!g_fixedwidth)
+    {  // old style
+        scale = 8;
+        if (width*scale >= 150)
+            scale = 150.0 / width;
+        if (height*scale >= 190)
+            scale = 190.0 / height;
+
+        s_scale = t_scale = scale;
+
+        iwidth = ceil(width*s_scale);
+        iheight = ceil(height*t_scale);
+
+        iwidth += 4;
+        iheight += 4;
+    }
+    else
+    {  // new style
+        iwidth = g_fixedwidth / 2;
+        iheight = g_fixedheight;
+
+        s_scale = (float)(iwidth-4) / width;
+        t_scale = (float)(iheight-4) / height;
+    }*/
+
+//
+// determine which side of each triangle to map the texture to
+//
+       basey = 2;
+       for ( i = 0 ; i < numtri ; i++ )
+       {
+               if ( ptri[i].HasUV ) {
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               triangle_st[i][j][0] = Q_rint( ptri[i].uv[j][0] * skinwidth );
+                               triangle_st[i][j][1] = Q_rint( ( 1.0f - ptri[i].uv[j][1] ) * skinheight );
+                       }
+               }
+               else
+               {
+                       VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
+                       VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
+                       CrossProduct( vtemp1, vtemp2, normal );
+
+                       if ( normal[1] > 0 ) {
+                               basex = iwidth + 2;
+                       }
+                       else
+                       {
+                               basex = 2;
+                       }
+
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               pbasevert = ptri[i].verts[j];
+
+                               triangle_st[i][j][0] = Q_rint( ( pbasevert[0] - mins[0] ) * s_scale + basex );
+                               triangle_st[i][j][1] = Q_rint( ( maxs[2] - pbasevert[2] ) * t_scale + basey );
+                       }
+               }
+
+               if ( DrawSkin ) {
+                       DrawLine( triangle_st[i][0][0], triangle_st[i][0][1],
+                                         triangle_st[i][1][0], triangle_st[i][1][1] );
+                       DrawLine( triangle_st[i][1][0], triangle_st[i][1][1],
+                                         triangle_st[i][2][0], triangle_st[i][2][1] );
+                       DrawLine( triangle_st[i][2][0], triangle_st[i][2][1],
+                                         triangle_st[i][0][0], triangle_st[i][0][1] );
+               }
+       }
+
+// make the width a multiple of 4; some hardware requires this, and it ensures
+// dword alignment for each scan
+
+       swidth = iwidth;
+       if ( backface_flag ) {
+               swidth *= 2;
+       }
+       fmheader.skinwidth = ( swidth + 3 ) & ~3;
+       fmheader.skinheight = iheight;
+
+       skin_width = iwidth;
+       skin_height = iheight;
+}
+
+
+static void BuildNewST( triangle_t *ptri, int numtri, qboolean DrawSkin ){
+       int i, j;
+
+       for ( i = 0 ; i < numtri ; i++ )
+       {
+               if ( ptri[i].HasUV ) {
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               triangle_st[i][j][0] = Q_rint( ptri[i].uv[j][0] * ( ScaleWidth - 1 ) );
+                               triangle_st[i][j][1] = Q_rint( ( 1.0f - ptri[i].uv[j][1] ) * ( ScaleHeight - 1 ) );
+                       }
+               }
+
+               if ( DrawSkin ) {
+                       DrawLine( triangle_st[i][0][0], triangle_st[i][0][1],
+                                         triangle_st[i][1][0], triangle_st[i][1][1] );
+                       DrawLine( triangle_st[i][1][0], triangle_st[i][1][1],
+                                         triangle_st[i][2][0], triangle_st[i][2][1] );
+                       DrawLine( triangle_st[i][2][0], triangle_st[i][2][1],
+                                         triangle_st[i][0][0], triangle_st[i][0][1] );
+               }
+       }
+
+// make the width a multiple of 4; some hardware requires this, and it ensures
+// dword alignment for each scan
+
+       fmheader.skinwidth = ( ScaleWidth + 3 ) & ~3;
+       fmheader.skinheight = ScaleHeight;
+
+       skin_width = ScaleWidth;
+       skin_height = ScaleHeight;
+}
+
+
+
+
+byte            *BasePalette;
+byte            *BasePixels,*TransPixels;
+int BaseWidth, BaseHeight, TransWidth, TransHeight;
+qboolean BaseTrueColor;
+static qboolean SetPixel = false;
+
+int CheckTransRecursiveTri( int *lp1, int *lp2, int *lp3 ){
+       int     *temp;
+       int d;
+       int new[2];
+
+       d = lp2[0] - lp1[0];
+       if ( d < -1 || d > 1 ) {
+               goto split;
+       }
+       d = lp2[1] - lp1[1];
+       if ( d < -1 || d > 1 ) {
+               goto split;
+       }
+
+       d = lp3[0] - lp2[0];
+       if ( d < -1 || d > 1 ) {
+               goto split2;
+       }
+       d = lp3[1] - lp2[1];
+       if ( d < -1 || d > 1 ) {
+               goto split2;
+       }
+
+       d = lp1[0] - lp3[0];
+       if ( d < -1 || d > 1 ) {
+               goto split3;
+       }
+       d = lp1[1] - lp3[1];
+       if ( d < -1 || d > 1 ) {
+split3:
+               temp = lp1;
+               lp1 = lp3;
+               lp3 = lp2;
+               lp2 = temp;
+
+               goto split;
+       }
+
+       return 0;           // entire tri is filled
+
+split2:
+       temp = lp1;
+       lp1 = lp2;
+       lp2 = lp3;
+       lp3 = temp;
+
+split:
+// split this edge
+       new[0] = ( lp1[0] + lp2[0] ) >> 1;
+       new[1] = ( lp1[1] + lp2[1] ) >> 1;
+
+// draw the point if splitting a leading edge
+       if ( lp2[1] > lp1[1] ) {
+               goto nodraw;
+       }
+       if ( ( lp2[1] == lp1[1] ) && ( lp2[0] < lp1[0] ) ) {
+               goto nodraw;
+       }
+
+       if ( SetPixel ) {
+               assert( ( new[1] * BaseWidth ) + new[0] < BaseWidth * BaseHeight );
+
+               if ( BaseTrueColor ) {
+                       BasePixels[( ( new[1] * BaseWidth ) + new[0] ) * 4] = 1;
+               }
+               else
+               {
+                       BasePixels[( new[1] * BaseWidth ) + new[0]] = 1;
+               }
+       }
+       else
+       {
+               if ( TransPixels ) {
+                       if ( TransPixels[( new[1] * TransWidth ) + new[0]] != 255 ) {
+                               return 1;
+                       }
+               }
+               else if ( BaseTrueColor ) {
+                       if ( BasePixels[( ( ( new[1] * BaseWidth ) + new[0] ) * 4 ) + 3] != 255 ) {
+                               return 1;
+                       }
+               }
+               else
+               {
+//                     pixel = BasePixels[(new[1]*BaseWidth) + new[0]];
+               }
+       }
+
+nodraw:
+// recursively continue
+       if ( CheckTransRecursiveTri( lp3, lp1, new ) ) {
+               return 1;
+       }
+
+       return CheckTransRecursiveTri( lp3, new, lp2 );
+}
+
+static void ReplaceClusterIndex( int newIndex, int oldindex, int **clusters,
+                                                                IntListNode_t **vertLists, int *num_verts, int *new_num_verts ){
+       int i, j;
+       IntListNode_t *next;
+
+       for ( j = 0; j < numJointsInSkeleton[g_skelModel.type]; ++j )
+       {
+               if ( !clusters[j] ) {
+                       continue;
+               }
+
+               for ( i = 0; i < num_verts[j + 1]; ++i )
+               {
+                       if ( clusters[j][i] == oldindex ) {
+                               ++new_num_verts[j + 1];
+
+                               next = vertLists[j];
+
+                               vertLists[j] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "ReplaceClusterIndex" );
+                               // Currently freed in WriteJointedModelFile only
+
+                               vertLists[j]->data = newIndex;
+                               vertLists[j]->next = next;
+                       }
+               }
+       }
+}
+
+#define FUDGE_EPSILON   0.002
+
+qboolean VectorFudgeCompare( vec3_t v1, vec3_t v2 ){
+       int i;
+
+       for ( i = 0 ; i < 3 ; i++ )
+               if ( fabs( v1[i] - v2[i] ) > FUDGE_EPSILON ) {
+                       return false;
+               }
+
+       return true;
+}
+
+/*
+   =================
+   Cmd_Base
+   =================
+ */
+void Cmd_FMBase( qboolean GetST ){
+       triangle_t  *ptri, *st_tri;
+       int num_st_tris;
+       int i, j, k, l;
+       int x,y,z;
+//     int                     time1;
+       char file1[1024],file2[1024],trans_file[1024], stfile[1024], extension[256];
+       vec3_t base_xyz[MAX_FM_VERTS];
+       FILE        *FH;
+       int pos,bit;
+       qboolean NewSkin;
+
+       GetScriptToken( false );
+
+       if ( g_skipmodel || g_release || g_archive ) {
+               return;
+       }
+
+       printf( "---------------------\n" );
+       sprintf( file1, "%s/%s.%s", cdarchive, token, trifileext );
+       printf( "%s ", file1 );
+
+       ExpandPathAndArchive( file1 );
+
+       // Use the input filepath for this one.
+       sprintf( file1, "%s/%s", cddir, token );
+
+//     time1 = FileTime (file1);
+//     if (time1 == -1)
+//             Error ("%s doesn't exist", file1);
+
+//
+// load the base triangles
+//
+       if ( do3ds ) {
+               Load3DSTriangleList( file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes );
+       }
+       else{
+               LoadTriangleList( file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes );
+       }
+
+       if ( g_ignoreTriUV ) {
+               for ( i = 0; i < fmheader.num_tris; i++ )
+               {
+                       ptri[i].HasUV = 0;
+               }
+       }
+
+       GetScriptToken( false );
+       sprintf( file2, "%s/%s", cddir, token );
+       sprintf( trans_file, "%s/!%s_a.pcx", cddir, token );
+
+       ExtractFileExtension( file2, extension );
+       if ( extension[0] == 0 ) {
+               strcat( file2, ".pcx" );
+       }
+       printf( "skin: %s\n", file2 );
+
+       BaseTrueColor = LoadAnyImage( file2, &BasePixels, &BasePalette, &BaseWidth, &BaseHeight );
+
+       NewSkin = false;
+       if ( BaseWidth != SKINPAGE_WIDTH || BaseHeight != SKINPAGE_HEIGHT ) {
+               if ( g_allow_newskin ) {
+                       ScaleWidth = BaseWidth;
+                       ScaleHeight = BaseHeight;
+                       NewSkin = true;
+               }
+               else
+               {
+                       Error( "Invalid skin page size: (%d,%d) should be (%d,%d)",
+                                  BaseWidth,BaseHeight,SKINPAGE_WIDTH,SKINPAGE_HEIGHT );
+               }
+       }
+       else if ( !BaseTrueColor ) {
+               ScaleWidth = (float)ExtractNumber( BasePixels, ENCODED_WIDTH_X,
+                                                                                  ENCODED_WIDTH_Y );
+               ScaleHeight = (float)ExtractNumber( BasePixels, ENCODED_HEIGHT_X,
+                                                                                       ENCODED_HEIGHT_Y );
+       }
+       else
+       {
+               Error( "Texture coordinates not supported on true color image" );
+       }
+
+       if ( GetST ) {
+               GetScriptToken( false );
+
+               sprintf( stfile, "%s/%s.%s", cdarchive, token, trifileext );
+               printf( "ST: %s ", stfile );
+
+               sprintf( stfile, "%s/%s", cddir, token );
+
+               if ( do3ds ) {
+                       Load3DSTriangleList( stfile, &st_tri, &num_st_tris, NULL, NULL );
+               }
+               else{
+                       LoadTriangleList( stfile, &st_tri, &num_st_tris, NULL, NULL );
+               }
+
+               if ( num_st_tris != fmheader.num_tris ) {
+                       Error( "num st tris mismatch: st %d / base %d", num_st_tris, fmheader.num_tris );
+               }
+
+               printf( "   matching triangles...\n" );
+               for ( i = 0; i < fmheader.num_tris; i++ )
+               {
+                       k = -1;
+                       for ( j = 0; j < num_st_tris; j++ )
+                       {
+                               for ( x = 0; x < 3; x++ )
+                               {
+                                       for ( y = 0; y < 3; y++ )
+                                       {
+                                               if ( x == y ) {
+                                                       continue;
+                                               }
+                                               for ( z = 0; z < 3; z++ )
+                                               {
+                                                       if ( z == x || z == y ) {
+                                                               continue;
+                                                       }
+
+                                                       if ( VectorFudgeCompare( ptri[i].verts[0], st_tri[j].verts[x] ) &&
+                                                                VectorFudgeCompare( ptri[i].verts[1], st_tri[j].verts[y] ) &&
+                                                                VectorFudgeCompare( ptri[i].verts[2], st_tri[j].verts[z] ) ) {
+                                                               if ( k == -1 ) {
+                                                                       k = j;
+                                                                       ptri[i].HasUV = st_tri[k].HasUV;
+                                                                       ptri[i].uv[0][0] = st_tri[k].uv[x][0];
+                                                                       ptri[i].uv[0][1] = st_tri[k].uv[x][1];
+                                                                       ptri[i].uv[1][0] = st_tri[k].uv[y][0];
+                                                                       ptri[i].uv[1][1] = st_tri[k].uv[y][1];
+                                                                       ptri[i].uv[2][0] = st_tri[k].uv[z][0];
+                                                                       ptri[i].uv[2][1] = st_tri[k].uv[z][1];
+                                                                       x = y = z = 999;
+                                                               }
+                                                               else if ( k != j ) {
+                                                                       printf( "Duplicate triangle %d found in st file: %d and %d\n",i,k,j );
+                                                                       printf( "   (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f)\n",
+                                                                                       ptri[i].verts[0][0],ptri[i].verts[0][1],ptri[i].verts[0][2],
+                                                                                       ptri[i].verts[1][0],ptri[i].verts[1][1],ptri[i].verts[1][2],
+                                                                                       ptri[i].verts[2][0],ptri[i].verts[2][1],ptri[i].verts[2][2] );
+                                                                       printf( "   (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f)\n",
+                                                                                       st_tri[k].verts[0][0],st_tri[k].verts[0][1],st_tri[k].verts[0][2],
+                                                                                       st_tri[k].verts[1][0],st_tri[k].verts[1][1],st_tri[k].verts[1][2],
+                                                                                       st_tri[k].verts[2][0],st_tri[k].verts[2][1],st_tri[k].verts[2][2] );
+                                                                       printf( "   (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f)\n",
+                                                                                       st_tri[j].verts[0][0],st_tri[j].verts[0][1],st_tri[j].verts[0][2],
+                                                                                       st_tri[j].verts[1][0],st_tri[j].verts[1][1],st_tri[j].verts[1][2],
+                                                                                       st_tri[j].verts[2][0],st_tri[j].verts[2][1],st_tri[j].verts[2][2] );
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       if ( k == -1 ) {
+                               printf( "No matching triangle %d\n",i );
+                       }
+               }
+               free( st_tri );
+       }
+
+//
+// get the ST values
+//
+       if ( ptri && ptri[0].HasUV ) {
+               if ( !NewSkin ) {
+                       Error( "Base has UVs with old style skin page\nMaybe you want to use -ignoreUV" );
+               }
+               else
+               {
+                       BuildNewST( ptri, fmheader.num_tris, false );
+               }
+       }
+       else
+       {
+               if ( NewSkin ) {
+                       Error( "Base has new style skin without UVs" );
+               }
+               else
+               {
+                       BuildST( ptri, fmheader.num_tris, false );
+               }
+       }
+
+       TransPixels = NULL;
+       if ( !BaseTrueColor ) {
+               FH = fopen( trans_file,"rb" );
+               if ( FH ) {
+                       fclose( FH );
+                       Load256Image( trans_file, &TransPixels, NULL, &TransWidth, &TransHeight );
+                       if ( TransWidth != fmheader.skinwidth || TransHeight != fmheader.skinheight ) {
+                               Error( "source image %s dimensions (%d,%d) are not the same as alpha image (%d,%d)\n",file2,fmheader.skinwidth,fmheader.skinheight,TransWidth,TransHeight );
+                       }
+               }
+       }
+
+//
+// run through all the base triangles, storing each unique vertex in the
+// base vertex list and setting the indirect triangles to point to the base
+// vertices
+//
+       for ( l = 0; l < fmheader.num_mesh_nodes; l++ )
+       {
+               for ( i = 0 ; i < fmheader.num_tris ; i++ )
+               {
+                       pos = i >> 3;
+                       bit = 1 << ( i & 7 );
+                       if ( !( pmnodes[l].tris[pos] & bit ) ) {
+                               continue;
+                       }
+
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               // get the xyz index
+                               for ( k = 0 ; k < fmheader.num_xyz ; k++ )
+                               {
+                                       if ( VectorCompare( ptri[i].verts[j], base_xyz[k] ) ) {
+                                               break;  // this vertex is already in the base vertex list
+                                       }
+                               }
+
+                               if ( k == fmheader.num_xyz ) { // new index
+                                       VectorCopy( ptri[i].verts[j], base_xyz[fmheader.num_xyz] );
+
+                                       if ( pmnodes[l].clustered == true ) {
+                                               ReplaceClusterIndex( k, ptri[i].indicies[j], (int **)&pmnodes[l].clusters, (IntListNode_t **)&g_skelModel.vertLists, (int *)&pmnodes[l].num_verts, (int *)&g_skelModel.new_num_verts );
+                                       }
+
+                                       fmheader.num_xyz++;
+                               }
+
+                               pos = k >> 3;
+                               bit = 1 << ( k & 7 );
+                               pmnodes[l].verts[pos] |= bit;
+
+                               triangles[i].index_xyz[j] = k;
+
+                               // get the st index
+                               for ( k = 0 ; k < fmheader.num_st ; k++ )
+                               {
+                                       if ( triangle_st[i][j][0] == base_st[k].s
+                                                && triangle_st[i][j][1] == base_st[k].t ) {
+                                               break;  // this vertex is already in the base vertex list
+                                       }
+                               }
+
+                               if ( k == fmheader.num_st ) { // new index
+                                       base_st[fmheader.num_st].s = triangle_st[i][j][0];
+                                       base_st[fmheader.num_st].t = triangle_st[i][j][1];
+                                       fmheader.num_st++;
+                               }
+
+                               triangles[i].index_st[j] = k;
+                       }
+
+                       if ( TransPixels || BaseTrueColor ) {
+                               translucent[i] = CheckTransRecursiveTri( triangle_st[i][0], triangle_st[i][1], triangle_st[i][2] );
+                       }
+                       else
+                       {
+                               translucent[i] = false;
+                       }
+               }
+       }
+
+       if ( !BaseTrueColor ) {
+               SetPixel = true;
+               memset( BasePixels,0,BaseWidth * BaseHeight );
+               for ( i = 0 ; i < fmheader.num_tris ; i++ )
+               {
+                       CheckTransRecursiveTri( triangle_st[i][0], triangle_st[i][1], triangle_st[i][2] );
+               }
+               SetPixel = false;
+
+               skin_pixels_used = 0;
+               for ( i = 0; i < fmheader.skinheight; i++ )
+               {
+                       for ( j = 0; j < fmheader.skinwidth; j++ )
+                       {
+                               skin_pixels_used += BasePixels[( i * BaseWidth ) + j];
+                       }
+               }
+               total_skin_pixels = fmheader.skinheight * fmheader.skinwidth;
+       }
+       else
+       {
+               SetPixel = true;
+               memset( BasePixels,0,BaseWidth * BaseHeight * 4 );
+               for ( i = 0 ; i < fmheader.num_tris ; i++ )
+               {
+                       CheckTransRecursiveTri( triangle_st[i][0], triangle_st[i][1], triangle_st[i][2] );
+               }
+               SetPixel = false;
+
+               skin_pixels_used = 0;
+               for ( i = 0; i < fmheader.skinheight; i++ )
+               {
+                       for ( j = 0; j < fmheader.skinwidth; j++ )
+                       {
+                               skin_pixels_used += BasePixels[( ( i * BaseWidth ) + j ) * 4];
+                       }
+               }
+               total_skin_pixels = fmheader.skinheight * fmheader.skinwidth;
+       }
+
+       // build triangle strips / fans
+       BuildGlCmds();
+
+       if ( TransPixels ) {
+               free( TransPixels );
+       }
+       free( BasePixels );
+       if ( BasePalette ) {
+               free( BasePalette );
+       }
+       free( ptri );
+}
+
+void Cmd_FMNodeOrder( void ){
+       mesh_node_t *newnodes, *pos;
+       int i,j;
+
+       if ( !pmnodes ) {
+               Error( "Base has not been established yet" );
+       }
+
+       pos = newnodes = malloc( sizeof( mesh_node_t ) * fmheader.num_mesh_nodes );
+
+       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
+       {
+               GetScriptToken( false );
+
+               for ( j = 0; j < fmheader.num_mesh_nodes; j++ )
+               {
+                       if ( strcmpi( pmnodes[j].name, token ) == 0 ) {
+                               *pos = pmnodes[j];
+                               pos++;
+                               break;
+                       }
+               }
+               if ( j >= fmheader.num_mesh_nodes ) {
+                       Error( "Node '%s' not in base list!\n", token );
+               }
+       }
+
+       free( pmnodes );
+       pmnodes = newnodes;
+}
+
+//===============================================================
+
+extern char *FindFrameFile( char *frame );
+
+
+/*
+   ===============
+   GrabFrame
+   ===============
+ */
+void GrabFrame( char *frame ){
+       triangle_t      *ptri;
+       int i, j;
+       fmtrivert_t     *ptrivert;
+       int num_tris;
+       char file1[1024];
+       fmframe_t       *fr;
+       int index_xyz;
+       char            *framefile;
+
+       // the frame 'run1' will be looked for as either
+       // run.1 or run1.tri, so the new alias sequence save
+       // feature an be used
+       framefile = FindFrameFile( frame );
+
+       sprintf( file1, "%s/%s", cdarchive, framefile );
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s",cddir, framefile );
+
+       printf( "grabbing %s  ", file1 );
+
+       if ( fmheader.num_frames >= MAX_FM_FRAMES ) {
+               Error( "fmheader.num_frames >= MAX_FM_FRAMES" );
+       }
+       fr = &g_frames[fmheader.num_frames];
+       fmheader.num_frames++;
+
+       strcpy( fr->name, frame );
+
+//
+// load the frame
+//
+       if ( do3ds ) {
+               Load3DSTriangleList( file1, &ptri, &num_tris, NULL, NULL );
+       }
+       else{
+               LoadTriangleList( file1, &ptri, &num_tris, NULL, NULL );
+       }
+
+       if ( num_tris != fmheader.num_tris ) {
+               Error( "%s: number of triangles (%d) doesn't match base frame (%d)\n", file1, num_tris, fmheader.num_tris );
+       }
+
+//
+// allocate storage for the frame's vertices
+//
+       ptrivert = fr->v;
+
+       for ( i = 0 ; i < fmheader.num_xyz ; i++ )
+       {
+               ptrivert[i].vnorm.numnormals = 0;
+               VectorClear( ptrivert[i].vnorm.normalsum );
+       }
+       ClearBounds( fr->mins, fr->maxs );
+
+//
+// store the frame's vertices in the same order as the base. This assumes the
+// triangles and vertices in this frame are in exactly the same order as in the
+// base
+//
+       for ( i = 0 ; i < num_tris ; i++ )
+       {
+               vec3_t vtemp1, vtemp2, normal;
+               float ftemp;
+
+               VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
+               VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
+               CrossProduct( vtemp1, vtemp2, normal );
+
+               VectorNormalize( normal, normal );
+
+               // rotate the normal so the model faces down the positive x axis
+               ftemp = normal[0];
+               normal[0] = -normal[1];
+               normal[1] = ftemp;
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       index_xyz = triangles[i].index_xyz[j];
+
+                       // rotate the vertices so the model faces down the positive x axis
+                       // also adjust the vertices to the desired origin
+                       ptrivert[index_xyz].v[0] = ( ( -ptri[i].verts[j][1] ) * scale_up ) +
+                                                                          adjust[0];
+                       ptrivert[index_xyz].v[1] = ( ptri[i].verts[j][0] * scale_up ) +
+                                                                          adjust[1];
+                       ptrivert[index_xyz].v[2] = ( ptri[i].verts[j][2] * scale_up ) +
+                                                                          adjust[2];
+
+                       AddPointToBounds( ptrivert[index_xyz].v, fr->mins, fr->maxs );
+
+                       VectorAdd( ptrivert[index_xyz].vnorm.normalsum, normal, ptrivert[index_xyz].vnorm.normalsum );
+                       ptrivert[index_xyz].vnorm.numnormals++;
+               }
+       }
+
+//
+// calculate the vertex normals, match them to the template list, and store the
+// index of the best match
+//
+       for ( i = 0 ; i < fmheader.num_xyz ; i++ )
+       {
+               int j;
+               vec3_t v;
+               float maxdot;
+               int maxdotindex;
+               int c;
+
+               c = ptrivert[i].vnorm.numnormals;
+               if ( !c ) {
+                       Error( "Vertex with no triangles attached" );
+               }
+
+               VectorScale( ptrivert[i].vnorm.normalsum, 1.0 / c, v );
+               VectorNormalize( v, v );
+
+               maxdot = -999999.0;
+               maxdotindex = -1;
+
+               for ( j = 0 ; j < NUMVERTEXNORMALS ; j++ )
+               {
+                       float dot;
+
+                       dot = DotProduct( v, avertexnormals[j] );
+                       if ( dot > maxdot ) {
+                               maxdot = dot;
+                               maxdotindex = j;
+                       }
+               }
+
+               ptrivert[i].lightnormalindex = maxdotindex;
+       }
+
+       free( ptri );
+}
+
+/*
+   ===============
+   Cmd_Frame
+   ===============
+ */
+void Cmd_FMFrame( void ){
+       while ( ScriptTokenAvailable() )
+       {
+               GetScriptToken( false );
+               if ( g_skipmodel ) {
+                       continue;
+               }
+               if ( g_release || g_archive ) {
+                       fmheader.num_frames = 1;    // don't skip the writeout
+                       continue;
+               }
+
+               H_printf( "#define FRAME_%-16s\t%i\n", token, fmheader.num_frames );
+
+               if ( ( g_skelModel.type != SKEL_NULL ) || ( g_skelModel.references != REF_NULL ) ) {
+                       GrabModelTransform( token );
+               }
+
+               GrabFrame( token );
+
+               if ( g_skelModel.type != SKEL_NULL ) {
+                       GrabSkeletalFrame( token );
+               }
+
+               if ( g_skelModel.references != REF_NULL ) {
+                       GrabReferencedFrame( token );
+               }
+
+               // need to add the up and dir points to the frame bounds here
+               // using AddPointToBounds (ptrivert[index_xyz].v, fr->mins, fr->maxs);
+               // then remove fudge in determining scale on frame write out
+       }
+}
+
+/*
+   ===============
+   Cmd_Skin
+
+   Skins aren't actually stored in the file, only a reference
+   is saved out to the header file.
+   ===============
+ */
+void Cmd_FMSkin( void ){
+       byte        *palette;
+       byte        *pixels;
+       int width, height;
+       byte        *cropped;
+       int y;
+       char name[1024], savename[1024], transname[1024], extension[256];
+       miptex32_t  *qtex32;
+       int size;
+       FILE        *FH;
+       qboolean TrueColor;
+
+       GetScriptToken( false );
+
+       if ( fmheader.num_skins == MAX_FM_SKINS ) {
+               Error( "fmheader.num_skins == MAX_FM_SKINS" );
+       }
+
+       if ( g_skipmodel ) {
+               return;
+       }
+
+       sprintf( name, "%s/%s", cdarchive, token );
+       strcpy( name, ExpandPathAndArchive( name ) );
+//     sprintf (name, "%s/%s.lbm", cddir, token);
+
+       if ( ScriptTokenAvailable() ) {
+               GetScriptToken( false );
+               sprintf( g_skins[fmheader.num_skins], "!%s", token );
+               sprintf( savename, "%s!%s", g_outputDir, token );
+               sprintf( transname, "%s!%s_a.pcx", gamedir, token );
+       }
+       else
+       {
+               sprintf( g_skins[fmheader.num_skins], "%s/!%s", cdpartial, token );
+               sprintf( savename, "%s/!%s", g_outputDir, token );
+               sprintf( transname, "%s/!%s_a.pcx", cddir, token );
+       }
+
+       fmheader.num_skins++;
+
+       if ( g_skipmodel || g_release || g_archive ) {
+               return;
+       }
+
+       // load the image
+       printf( "loading %s\n", name );
+       ExtractFileExtension( name, extension );
+       if ( extension[0] == 0 ) {
+               strcat( name, ".pcx" );
+       }
+
+
+       TrueColor = LoadAnyImage( name, &pixels, &palette, &width, &height );
+//     RemapZero (pixels, palette, width, height);
+
+       // crop it to the proper size
+
+       if ( !TrueColor ) {
+               cropped = (byte *) SafeMalloc( fmheader.skinwidth * fmheader.skinheight, "Cmd_FMSkin" );
+               for ( y = 0 ; y < fmheader.skinheight ; y++ )
+               {
+                       memcpy( cropped + y * fmheader.skinwidth,
+                                       pixels + y * width, fmheader.skinwidth );
+               }
+
+               TransPixels = NULL;
+               FH = fopen( transname,"rb" );
+               if ( FH ) {
+                       fclose( FH );
+
+                       strcat( g_skins[fmheader.num_skins - 1],".pcx" );
+                       strcat( savename,".pcx" );
+
+                       // save off the new image
+                       printf( "saving %s\n", savename );
+                       CreatePath( savename );
+                       WritePCXfile( savename, cropped, fmheader.skinwidth, fmheader.skinheight, palette );
+               }
+               else
+               {
+       #if 1
+                       miptex_t    *qtex;
+                       qtex = CreateMip( cropped, fmheader.skinwidth, fmheader.skinheight, palette, &size, true );
+
+                       strcat( g_skins[fmheader.num_skins - 1],".m8" );
+                       strcat( savename,".m8" );
+
+                       printf( "saving %s\n", savename );
+                       CreatePath( savename );
+                       SaveFile( savename, (byte *)qtex, size );
+                       free( qtex );
+       #else
+                       strcat( g_skins[fmheader.num_skins - 1],".pcx" );
+                       strcat( savename,".pcx" );
+
+                       // save off the new image
+                       printf( "saving %s\n", savename );
+                       CreatePath( savename );
+                       WritePCXfile( savename, cropped, fmheader.skinwidth, fmheader.skinheight, palette );
+       #endif
+               }
+       }
+       else
+       {
+               cropped = (byte *) SafeMalloc( fmheader.skinwidth * fmheader.skinheight * 4, "Cmd_FMSkin" );
+               for ( y = 0 ; y < fmheader.skinheight ; y++ )
+               {
+                       memcpy( cropped + ( ( y * fmheader.skinwidth ) * 4 ), pixels + ( y * width * 4 ), fmheader.skinwidth * 4 );
+               }
+
+               qtex32 = CreateMip32( (unsigned *)cropped, fmheader.skinwidth, fmheader.skinheight, &size, true );
+
+               StripExtension( g_skins[fmheader.num_skins - 1] );
+               strcat( g_skins[fmheader.num_skins - 1],".m32" );
+               StripExtension( savename );
+               strcat( savename,".m32" );
+
+               printf( "saving %s\n", savename );
+               CreatePath( savename );
+               SaveFile( savename, (byte *)qtex32, size );
+       }
+
+       free( pixels );
+       if ( palette ) {
+               free( palette );
+       }
+       free( cropped );
+}
+
+
+/*
+   ===============
+   Cmd_Cd
+   ===============
+ */
+void Cmd_FMCd( void ){
+       char temp[256];
+
+       FinishModel();
+       ClearModel();
+
+       GetScriptToken( false );
+
+       // this is a silly mess...
+       sprintf( cdpartial, "models/%s", token );
+       sprintf( cdarchive, "%smodels/%s", gamedir + strlen( qdir ), token );
+       sprintf( cddir, "%s%s", gamedir, cdpartial );
+
+       // Since we also changed directories on the output side (for mirror) make sure the outputdir is set properly too.
+       sprintf( temp, "%s%s", g_outputDir, cdpartial );
+       strcpy( g_outputDir, temp );
+
+       // if -only was specified and this cd doesn't match,
+       // skip the model (you only need to match leading chars,
+       // so you could regrab all monsters with -only monsters)
+       if ( !g_only[0] ) {
+               return;
+       }
+       if ( strncmp( token, g_only, strlen( g_only ) ) ) {
+               g_skipmodel = true;
+               printf( "skipping %s\n", cdpartial );
+       }
+}
+
+
+/*
+
+   //=======================
+   //          NEW GEN
+   //=======================
+
+   void NewGen (char *ModelFile, char *OutputName, int width, int height)
+   {
+    trigroup_t  *triangles;
+    triangle_t *ptri;
+    triangle_t *grouptris;
+    mesh_node_t        *pmnodes;
+
+    vec3_t             *vertices;
+    vec3_t             *uvs;
+    vec3_t             aveNorm, crossvect;
+    vec3_t             diffvect1, diffvect2;
+    vec3_t             v0, v1, v2;
+    vec3_t             n, u, v;
+    vec3_t             base, zaxis, yaxis;
+    vec3_t             uvwMin, uvwMax;
+    vec3_t             groupMin, groupMax;
+    vec3_t             uvw;
+
+    float              *uFinal, *vFinal;
+    unsigned char      *newpic;
+
+    int                        finalstart = 0, finalcount = 0;
+    int                        xbase = 0, xwidth = 0, ywidth = 0;
+    int                        *todo, *done, finished;
+    int                        i, j, k, l; //counters
+    int                        groupnum, numtris, numverts, num;
+    int                        count;
+    FILE               *grpfile;
+    long               datasize;
+
+    for ( i = 0; i<3; i++)
+    {
+        aveNorm[i] = 0;
+        uvwMin[i] = 1e30f;
+        uvwMax[i] = -1e30f;
+    }
+
+    pmnodes = NULL;
+    ptri = NULL;
+    triangles = NULL;
+
+    zaxis[0] = 0;
+    zaxis[1] = 0;
+    zaxis[2] = 1;
+
+    yaxis[0] = 0;
+    yaxis[1] = 1;
+    yaxis[2] = 0;
+
+    LoadTriangleList (ModelFile, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes);
+
+    todo = (int*)SafeMalloc(fmheader.num_tris*sizeof(int), "NewGen");
+    done = (int*)SafeMalloc(fmheader.num_tris*sizeof(int), "NewGen");
+    triangles = (trigroup_t*)SafeMalloc(fmheader.num_tris*sizeof(trigroup_t), "NewGen");
+
+    for ( i=0; i < fmheader.num_tris; i++)
+    {
+        todo[i] = false;
+        done[i] = false;
+        triangles[i].triangle = ptri[i];
+        triangles[i].group = 0;
+    }
+
+    groupnum = 0;
+
+   //  transitive closure algorithm follows
+   //  put all triangles who transitively share vertices into separate groups
+
+    while (1)
+    {
+        for ( i = 0; i < fmheader.num_tris; i++)
+        {
+            if (!done[i])
+            {
+                break;
+            }
+        }
+        if ( i == fmheader.num_tris)
+        {
+            break;
+        }
+        finished = false;
+        todo[i] = true;
+        while (!finished)
+        {
+            finished = true;
+            for ( i = 0; i < fmheader.num_tris; i++)
+            {
+                if (todo[i])
+                {
+                    done[i] = true;
+                    triangles[i].group = groupnum;
+                    todo[i] = false;
+                    for ( j = 0; j < fmheader.num_tris; j++)
+                    {
+                        if ((!done[j]) && (ShareVertex(triangles[i],triangles[j])))
+                        {
+                            todo[j] = true;
+                            finished = false;
+                        }
+                    }
+                }
+            }
+        }
+        groupnum++;
+    }
+        uFinal = (float*)SafeMalloc(3*fmheader.num_tris*sizeof(float), "NewGen");
+        vFinal = (float*)SafeMalloc(3*fmheader.num_tris*sizeof(float), "NewGen");
+
+    grpfile = fopen("grpdebug.txt","w");
+
+
+    for (i = 0; i < groupnum; i++)
+    {
+
+        fprintf(grpfile,"Group Number: %d\n", i);
+
+        numtris = GetNumTris(triangles, i); // number of triangles in group i
+        numverts = numtris * 3;
+
+        fprintf(grpfile,"%d triangles.\n", numtris);
+
+        vertices = (vec3_t*)SafeMalloc(numverts*sizeof(vec3_t), "NewGen");
+        uvs = (vec3_t*)SafeMalloc(numverts*sizeof(vec3_t), "NewGen");
+        grouptris = (triangle_t*)SafeMalloc(numtris*sizeof(triangle_t), "NewGen");
+
+        for (count = 0; count < fmheader.num_tris; count++)
+        {
+            if (triangles[count].group == i)
+            {
+                fprintf(grpfile,"Triangle %d\n", count);
+            }
+        }
+        fprintf(grpfile,"\n");
+
+
+
+
+        GetOneGroup(triangles, i, grouptris);
+
+        num = 0;
+        for (j = 0; j < numtris; j++)
+        {
+            VectorCopy(grouptris[j].verts[0], v0);
+            VectorCopy(grouptris[j].verts[1], v1);
+            VectorCopy(grouptris[j].verts[2], v2);
+            VectorSubtract(v1, v0, diffvect1);
+            VectorSubtract(v2, v1, diffvect2);
+            CrossProduct( diffvect1, diffvect2, crossvect);
+            VectorAdd(aveNorm, crossvect, aveNorm);
+            VectorCopy(v0,vertices[num]);
+            num++;                                     //  FIXME
+            VectorCopy(v1,vertices[num]);
+            num++;                                     //  add routine to add only verts that
+            VectorCopy(v2,vertices[num]);
+            num++;                                     // have not already been added
+        }
+
+        assert (num >= 3);
+   // figure out the best plane projections
+        DOsvdPlane ((float*)vertices, num, (float *)&n, (float *)&base);
+
+        if (DotProduct(aveNorm,n) < 0.0f)
+        {
+            VectorScale(n, -1.0f, n);
+        }
+        VectorNormalize(n,n);
+        if (fabs(n[2]) < .57)
+        {
+            CrossProduct( zaxis, n, crossvect);
+            VectorCopy(crossvect, u);
+        }
+        else
+        {
+            CrossProduct( yaxis, n, crossvect);
+            VectorCopy(crossvect, u);
+        }
+        VectorNormalize(u,u);
+        CrossProduct( n, u, crossvect);
+        VectorCopy(crossvect, v);
+        VectorNormalize(v,v);
+
+        num = 0;
+
+        for ( j = 0; j < 3; j++)
+        {
+            groupMin[j] = 1e30f;
+            groupMax[j] = -1e30f;
+        }
+
+        for ( j = 0; j < numtris; j++)
+        {
+            for ( k = 0; k < 3; k++)
+            {
+                VectorCopy(grouptris[j].verts[k],v0);
+                VectorSubtract(v0, base, v0);
+                uvw[0] = DotProduct(v0, u);
+                uvw[1] = DotProduct(v0, v);
+                uvw[2] = DotProduct(v0, n);
+                VectorCopy(uvw,uvs[num]);
+                num++;
+                for ( l = 0; l < 3; l++)
+                {
+                    if (uvw[l] < groupMin[l])
+                    {
+                        groupMin[l] = uvw[l];
+                    }
+                    if (uvw[l] > groupMax[l])
+                    {
+                        groupMax[l] = uvw[l];
+                    }
+                }
+            }
+        }
+
+        xwidth = ceil(0 - groupMin[0]) + 2; // move right of origin and avoid overlap
+        ywidth = ceil(0 - groupMin[1]) + 2; // move "above" origin
+
+        for ( j=0; j < numverts; j++)
+        {
+            uFinal[finalcount] = uvs[j][0] + xwidth + xbase;
+            vFinal[finalcount] = uvs[j][1] + ywidth;
+            if (uFinal[finalcount] < uvwMin[0])
+            {
+                uvwMin[0] = uFinal[finalcount];
+            }
+            if (uFinal[finalcount] > uvwMax[0])
+            {
+                uvwMax[0] = uFinal[finalcount];
+            }
+            if (vFinal[finalcount] < uvwMin[1])
+            {
+                uvwMin[1] = vFinal[finalcount];
+            }
+            if (vFinal[finalcount] > uvwMax[1])
+            {
+                uvwMax[1] = vFinal[finalcount];
+            }
+            finalcount++;
+        }
+
+        fprintf(grpfile,"svdPlaned Group min: ( %f , %f )\n",groupMin[0] + xwidth + xbase, groupMin[1] + ywidth);
+        fprintf(grpfile,"svdPlaned Group max: ( %f , %f )\n",groupMax[0] + xwidth + xbase, groupMax[1] + ywidth);
+
+        finalcount = finalstart;
+
+        for ( count = 0; count < numverts; count++)
+        {
+            fprintf(grpfile,"Vertex %d: ( %f , %f , %f )\n",count,vertices[count][0],vertices[count][1],vertices[count][2]);
+            fprintf(grpfile,"svdPlaned: ( %f , %f )\n",uFinal[finalcount],vFinal[finalcount++]);
+        }
+
+        finalstart = finalcount;
+
+        fprintf(grpfile,"\n");
+
+        free(vertices);
+        free(uvs);
+        free(grouptris);
+
+        xbase += ceil(groupMax[0] - groupMin[0]) + 2;
+
+    }
+
+    fprintf(grpfile,"Global Min ( %f , %f )\n",uvwMin[0],uvwMin[1]);
+    fprintf(grpfile,"Global Max ( %f , %f )\n",uvwMax[0],uvwMax[1]);
+
+
+    ScaleTris(uvwMin, uvwMax, width, height, uFinal, vFinal, finalcount);
+
+    for (k = 0; k < finalcount; k++)
+    {
+        fprintf(grpfile, "scaled vertex %d: ( %f , %f )\n",k,uFinal[k],vFinal[k]);
+    }
+
+    //  i've got the array of vertices in uFinal and vFinal.  Now I need to write them and draw lines
+
+    datasize = width * height*sizeof(unsigned char);
+    newpic = (unsigned char*)SafeMalloc(datasize, "NewGen");
+    memset(newpic,0,datasize);
+    memset(pic_palette,0,sizeof(pic_palette));
+    pic_palette[767] = pic_palette[766] = pic_palette[765] = 255;
+
+    k = 0;
+    while (k < finalcount)
+    {
+        NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height);
+        k++;
+        NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height);
+        k++;
+        NewDrawLine(uFinal[k], vFinal[k], uFinal[k-2], vFinal[k-2], newpic, width, height);
+        k++;
+        fprintf(grpfile, "output tri with verts %d, %d, %d", k-2, k-1, k);
+    }
+
+    WritePCXfile (OutputName, newpic, width, height, pic_palette);
+
+    fclose(grpfile);
+
+    free(todo);
+    free(done);
+    free(triangles);
+    free(newpic);
+    return;
+   }
+   void NewDrawLine(int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height)
+   {
+    long dx, dy;
+    long adx, ady;
+    long count;
+    float xfrac, yfrac, xstep, ystep;
+    unsigned long sx, sy;
+    float u, v;
+
+    dx = x2 - x1;
+    dy = y2 - y1;
+    adx = abs(dx);
+    ady = abs(dy);
+
+    count = adx > ady ? adx : ady;
+    count++;
+
+    if(count > 300)
+    {
+        printf("Bad count\n");
+        return; // don't ever hang up on bad data
+    }
+
+    xfrac = x1;
+    yfrac = y1;
+
+    xstep = (float)dx/count;
+    ystep = (float)dy/count;
+
+    switch(LineType)
+    {
+        case LINE_NORMAL:
+            do
+            {
+                if(xfrac < width && yfrac < height)
+                {
+                    picture[(long)yfrac*width+(long)xfrac] = LineColor;
+                }
+                xfrac += xstep;
+                yfrac += ystep;
+                count--;
+            } while (count > 0);
+            break;
+        case LINE_FAT:
+            do
+            {
+                for (u=-0.1 ; u<=0.9 ; u+=0.999)
+                {
+                    for (v=-0.1 ; v<=0.9 ; v+=0.999)
+                    {
+                        sx = xfrac+u;
+                        sy = yfrac+v;
+                        if(sx < width && sy < height)
+                        {
+                            picture[sy*width+sx] = LineColor;
+                        }
+                    }
+                }
+                xfrac += xstep;
+                yfrac += ystep;
+                count--;
+            } while (count > 0);
+            break;
+        case LINE_DOTTED:
+            do
+            {
+                if(count&1 && xfrac < width &&
+                    yfrac < height)
+                {
+                    picture[(long)yfrac*width+(long)xfrac] = LineColor;
+                }
+                xfrac += xstep;
+                yfrac += ystep;
+                count--;
+            } while (count > 0);
+            break;
+        default:
+            Error("Unknown <linetype> %d.\n", LineType);
+    }
+   }
+ */
+void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts ){
+
+       int i;
+       float hscale, vscale;
+       float scale;
+
+       hscale = max[0];
+       vscale = max[1];
+
+       hscale = ( Width - 2 ) / max[0];
+       vscale = ( Height - 2 ) / max[1];
+
+       scale = hscale;
+       if ( scale > vscale ) {
+               scale = vscale;
+       }
+       for ( i = 0; i < verts; i++ )
+       {
+               u[i] *= scale;
+               v[i] *= scale;
+       }
+       return;
+}
+
+
+void GetOneGroup( trigroup_t *tris, int grp, triangle_t* triangles ){
+       int i;
+       int j;
+
+       j = 0;
+       for ( i = 0; i < fmheader.num_tris; i++ )
+       {
+               if ( tris[i].group == grp ) {
+                       triangles[j++] = tris[i].triangle;
+               }
+       }
+       return;
+}
+
+
+int GetNumTris( trigroup_t *tris, int grp ){
+       int i;
+       int verts;
+
+       verts = 0;
+       for ( i = 0; i < fmheader.num_tris; i++ )
+       {
+               if ( tris[i].group == grp ) {
+                       verts++;
+               }
+       }
+       return verts;
+}
+
+
+int ShareVertex( trigroup_t trione, trigroup_t tritwo ){
+       int i;
+       int j;
+
+       i = 1;
+       j = 1;
+       for ( i = 0; i < 3; i++ )
+       {
+               for ( j = 0; j < 3; j++ )
+               {
+                       if ( DistBetween( trione.triangle.verts[i],tritwo.triangle.verts[j] ) < TRIVERT_DIST ) {
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
+
+
+float DistBetween( vec3_t point1, vec3_t point2 ){
+       float dist;
+
+       dist = ( point1[0] - point2[0] );
+       dist *= dist;
+       dist += ( point1[1] - point2[1] ) * ( point1[1] - point2[1] );
+       dist += ( point1[2] - point2[2] ) * ( point1[2] - point2[2] );
+       dist = sqrt( dist );
+       return dist;
+}
+
+
+void GenSkin( char *ModelFile, char *OutputName, int Width, int Height ){
+       triangle_t  *ptri;
+       mesh_node_t *pmnodes;
+       int i;
+
+       pmnodes = NULL;
+       ptri = NULL;
+
+       LoadTriangleList( ModelFile, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes );
+       if ( g_ignoreTriUV ) {
+               for ( i = 0; i < fmheader.num_tris; i++ )
+               {
+                       ptri[i].HasUV = 0;
+               }
+       }
+
+       memset( pic,0,sizeof( pic ) );
+       memset( pic_palette,0,sizeof( pic_palette ) );
+       pic_palette[767] = pic_palette[766] = pic_palette[765] = 255;
+
+       ScaleWidth = Width;
+       ScaleHeight = Height;
+
+       BuildST( ptri, fmheader.num_tris, true );
+
+       WritePCXfile( OutputName, pic, SKINPAGE_WIDTH, SKINPAGE_HEIGHT, pic_palette );
+
+       printf( "Gen Skin Stats:\n" );
+       printf( "   Input Base: %s\n",ModelFile );
+       printf( "   Input Dimensions: %d,%d\n",Width,Height );
+       printf( "\n" );
+       printf( "   Output File: %s\n",OutputName );
+       printf( "   Output Dimensions: %d,%d\n",ScaleWidth,ScaleHeight );
+
+       if ( fmheader.num_mesh_nodes ) {
+               printf( "\nNodes:\n" );
+               for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
+               {
+                       printf( "   %s\n",pmnodes[i].name );
+               }
+       }
+
+       free( ptri );
+       free( pmnodes );
+}
+
+
+void Cmd_FMBeginGroup( void ){
+       GetScriptToken( false );
+
+       g_no_opimizations = false;
+
+       groups[num_groups].start_frame = fmheader.num_frames;
+       groups[num_groups].num_frames = 0;
+
+       groups[num_groups].degrees = atol( token );
+       if ( groups[num_groups].degrees < 1 || groups[num_groups].degrees > 32 ) {
+               Error( "Degrees of freedom out of range: %d",groups[num_groups].degrees );
+       }
+}
+
+void Cmd_FMEndGroup( void ){
+       groups[num_groups].num_frames = fmheader.num_frames - groups[num_groups].start_frame;
+
+       if ( num_groups < MAX_GROUPS - 1 ) {
+               num_groups++;
+       }
+       else
+       {
+               Error( "Number of compression groups exceded: %i\n", MAX_GROUPS );
+       }
+}
diff --git a/tools/heretic2/h2data/h2data.rc b/tools/heretic2/h2data/h2data.rc
new file mode 100644 (file)
index 0000000..21540bc
--- /dev/null
@@ -0,0 +1,115 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1               ICON    DISCARDABLE     "..\\..\\..\\icons\\h2data.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "Comments", "Heavily modified from original ID tool\0"
+            VALUE "CompanyName", "Raven Software\0"
+            VALUE "FileDescription", "qdata\0"
+            VALUE "FileVersion", "2.0\0"
+            VALUE "InternalName", "qdata\0"
+            VALUE "LegalCopyright", "Copyright Â© 1998\0"
+            VALUE "OriginalFilename", "qdata.exe\0"
+            VALUE "ProductName", "Raven Software qdata\0"
+            VALUE "ProductVersion", "2.0\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // !_MAC
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/tools/heretic2/h2data/images.c b/tools/heretic2/h2data/images.c
new file mode 100644 (file)
index 0000000..555303b
--- /dev/null
@@ -0,0 +1,1409 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qdata.h"
+
+#if GDEF_OS_WINDOWS
+ #include <windows.h>
+#endif
+
+#if GDEF_OS_MACOS && !defined( XWINDOWS )
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+
+#if 1
+extern char     *g_outputDir;
+#endif // _QDATA
+
+char mip_prefix[1024];              // directory to dump the textures in
+
+qboolean colormap_issued;
+byte colormap_palette[768];
+
+unsigned total_x = 0;
+unsigned total_y = 0;
+unsigned total_textures = 0;
+
+#define MAX_IMAGE_SIZE 512
+
+#if 0
+/*
+   ==============
+   RemapZero
+
+   Replaces all 0 bytes in an image with the closest palette entry.
+   This is because NT won't let us change index 0, so any palette
+   animation leaves those pixels untouched.
+   ==============
+ */
+void RemapZero( byte *pixels, byte *palette, int width, int height ){
+       int i, c;
+       int alt_zero;
+       int value, best;
+
+       alt_zero = 0;
+       best = 9999999;
+       for ( i = 1 ; i < 255 ; i++ )
+       {
+               value = palette[i * 3 + 0] + palette[i * 3 + 1] + palette[i * 3 + 2];
+               if ( value < best ) {
+                       best = value;
+                       alt_zero = i;
+               }
+       }
+
+       c = width * height;
+       for ( i = 0 ; i < c ; i++ )
+               if ( pixels[i] == 0 ) {
+                       pixels[i] = alt_zero;
+               }
+}
+
+#endif
+
+
+// ********************************************************************
+// **  Mip Map Pre-Processing Routines
+// ********************************************************************
+
+#define intensity_value 1
+
+static unsigned image_pal[256];
+
+#define MAX_LAST 25
+
+long palette_r[256], palette_g[256], palette_b[256];
+long last_r[MAX_LAST],last_g[MAX_LAST],last_b[MAX_LAST], last_i[MAX_LAST], last_place;
+
+long cached;
+
+void PrepareConvert( unsigned *palette ){
+       int i;
+
+       for ( i = 0; i < 256; i++ )
+       {
+               palette_r[i] = ( palette[i] & 0x00ff0000 ) >> 16;
+               palette_g[i] = ( palette[i] & 0x0000ff00 ) >> 8;
+               palette_b[i] = ( palette[i] & 0x000000ff );
+       }
+
+       for ( i = 0; i < MAX_LAST; i++ )
+               last_r[i] = -1;
+
+       last_place = -1;
+}
+
+int ConvertTrueColorToPal( unsigned r, unsigned g, unsigned b ){
+       int i;
+       long min_dist;
+       int min_index;
+       long dist;
+       long dr, dg, db, biggest_delta;
+
+       for ( i = 0; i < MAX_LAST; i++ )
+               if ( r == last_r[i] && g == last_g[i] && b == last_b[i] ) {
+                       cached++;
+                       return last_i[i];
+               }
+
+       min_dist = 256 * 256 + 256 * 256 + 256 * 256;
+       biggest_delta = 256 * 256;
+       min_index = 0;
+
+       for ( i = 0; i < 256; i++ )
+       {
+               dr = abs( palette_r[i] - r );
+               if ( dr > biggest_delta ) {
+                       continue;
+               }
+               dg = abs( palette_g[i] - g );
+               if ( dg > biggest_delta ) {
+                       continue;
+               }
+               db = abs( palette_b[i] - b );
+               if ( db > biggest_delta ) {
+                       continue;
+               }
+
+               dist = dr * dr + dg * dg + db * db;
+               if ( dist < min_dist ) {
+                       min_dist = dist;
+                       min_index = i;
+                       if ( min_dist == 0 ) {
+                               break;
+                       }
+
+                       dist = dr;
+                       if ( dg > dist ) {
+                               dist = dg;
+                       }
+                       if ( db > dist ) {
+                               dist = db;
+                       }
+                       if ( dist < biggest_delta ) {
+                               biggest_delta = dist;
+                       }
+               }
+       }
+
+       last_place++;
+       if ( last_place >= MAX_LAST ) {
+               last_place = 0;
+       }
+
+       last_r[last_place] = r;
+       last_g[last_place] = g;
+       last_b[last_place] = b;
+       last_i[last_place] = min_index;
+
+       return min_index;
+}
+
+
+void GL_ResampleTexture8P( byte *in, int inwidth, int inheight, byte *out,
+                                                  int outwidth, int outheight, palette_t *palette ){
+       int i, j;
+       byte    *inrow, *inrow2;
+       unsigned frac, fracstep;
+       unsigned p1[1024], p2[1024], *p1p, *p2p;
+       palette_t   *c1,*c2,*c3,*c4;
+       unsigned r,g,b;
+
+       fracstep = inwidth * 0x10000 / outwidth;
+
+       frac = fracstep >> 2;
+       for ( i = 0 ; i < outwidth ; i++ )
+       {
+               p1[i] = frac >> 16;
+               frac += fracstep;
+       }
+       frac = 3 * ( fracstep >> 2 );
+       for ( i = 0 ; i < outwidth ; i++ )
+       {
+               p2[i] = frac >> 16;
+               frac += fracstep;
+       }
+
+       cached = 0;
+
+       for ( i = 0 ; i < outheight ; i++ ) //, out += outwidth)
+       {
+               inrow = in + inwidth * (int)( ( i + 0.25 ) * inheight / outheight );
+               inrow2 = in + inwidth * (int)( ( i + 0.75 ) * inheight / outheight );
+
+               p1p = p1;
+               p2p = p2;
+               for ( j = 0 ; j < outwidth ; j++ )
+               {
+                       c1 = &palette[*( (byte *)inrow + ( *p1p ) )];
+                       c2 = &palette[*( (byte *)inrow + ( *p2p ) )];
+                       c3 = &palette[*( (byte *)inrow2 + ( *p1p++ ) )];
+                       c4 = &palette[*( (byte *)inrow2 + ( *p2p++ ) )];
+
+                       r = ( (unsigned)c1->r + (unsigned)c2->r + (unsigned)c3->r + (unsigned)c4->r ) >> 2;
+                       g = ( (unsigned)c1->g + (unsigned)c2->g + (unsigned)c3->g + (unsigned)c4->g ) >> 2;
+                       b = ( (unsigned)c1->b + (unsigned)c2->b + (unsigned)c3->b + (unsigned)c4->b ) >> 2;
+
+                       *out++ = ConvertTrueColorToPal( r,g,b );
+               }
+       }
+}
+
+void GL_MipMap8P( byte *out, byte *in, int width, int height, palette_t *palette ){
+       int i, j;
+       palette_t   *c1,*c2,*c3,*c4;
+       unsigned r,g,b;
+
+       cached = 0;
+       memset( out, 0, 256 * 256 );
+       width <<= 1;
+       height <<= 1;
+
+       for ( i = 0; i < height; i += 2, in += width )
+       {
+               for ( j = 0; j < width; j += 2 )
+               {
+                       c1 = &palette[in[0]];
+                       c3 = &palette[in[width]];
+                       in++;
+                       c2 = &palette[in[0]];
+                       c4 = &palette[in[width]];
+                       in++;
+
+                       r = ( (unsigned)c1->r + (unsigned)c2->r + (unsigned)c3->r + (unsigned)c4->r ) >> 2;
+                       g = ( (unsigned)c1->g + (unsigned)c2->g + (unsigned)c3->g + (unsigned)c4->g ) >> 2;
+                       b = ( (unsigned)c1->b + (unsigned)c2->b + (unsigned)c3->b + (unsigned)c4->b ) >> 2;
+
+                       *out++ = ConvertTrueColorToPal( r, g, b );
+               }
+       }
+}
+
+
+miptex_t *CreateMip( byte *data, unsigned width, unsigned height, byte *palette, int *FinalSize, qboolean mip ){
+       int scaled_width, scaled_height;
+       int i,j,r,g,b;
+       byte intensitytable[256];
+       byte scaled[256 * 256];
+       byte out[256 * 256];
+       int miplevel;
+       miptex_t    *mp;
+       byte        *pos;
+       int size;
+
+       for ( i = 0 ; i < 256 ; i++ )
+       {
+               j = i * intensity_value;
+               if ( j > 255 ) {
+                       j = 255;
+               }
+               intensitytable[i] = j;
+       }
+
+       for ( scaled_width = 1 ; scaled_width < width ; scaled_width <<= 1 )
+               ;
+       if ( 1 && scaled_width > width && 1 ) {
+               scaled_width >>= 1;
+       }
+       for ( scaled_height = 1 ; scaled_height < height ; scaled_height <<= 1 )
+               ;
+       if ( 1 && scaled_height > height && 1 ) {
+               scaled_height >>= 1;
+       }
+
+       // don't ever bother with >256 textures
+       if ( scaled_width > 256 ) {
+               scaled_width = 256;
+       }
+       if ( scaled_height > 256 ) {
+               scaled_height = 256;
+       }
+
+       if ( scaled_width < 1 ) {
+               scaled_width = 1;
+       }
+       if ( scaled_height < 1 ) {
+               scaled_height = 1;
+       }
+
+       size = sizeof( *mp ) + ( scaled_width * scaled_height * 3 );
+       mp = (miptex_t *)SafeMalloc( size, "CreateMip" );
+       memset( mp,0,size );
+
+       mp->version = MIP_VERSION;
+
+       for ( i = j = 0; i < 256; i++,j += 3 )
+       {
+               mp->palette[i].r = r = intensitytable[palette[j]];
+               mp->palette[i].g = g = intensitytable[palette[j + 1]];
+               mp->palette[i].b = b = intensitytable[palette[j + 2]];
+               image_pal[i] = 0xff000000 | ( r << 16 ) | ( g << 8 ) | ( b );
+       }
+
+       PrepareConvert( image_pal );
+
+       if ( scaled_width == width && scaled_height == height ) {
+               memcpy( scaled, data, width * height );
+       }
+       else{
+               GL_ResampleTexture8P( data, width, height, scaled, scaled_width, scaled_height, mp->palette );
+       }
+
+       pos = (byte *)( mp + 1 );
+       miplevel = 0;
+
+       while ( ( scaled_width >= 1 || scaled_height >= 1 ) && ( miplevel <= MIPLEVELS - 1 ) && ( !miplevel || mip ) )
+       {
+               if ( scaled_width < 1 ) {
+                       scaled_width = 1;
+               }
+               if ( scaled_height < 1 ) {
+                       scaled_height = 1;
+               }
+
+               if ( miplevel > 0 ) {
+                       GL_MipMap8P( out, (byte *)scaled, scaled_width, scaled_height, mp->palette );
+               }
+               else{
+                       memcpy( out, scaled, 256 * 256 );
+               }
+
+               mp->width[miplevel] = scaled_width;
+               mp->height[miplevel] = scaled_height;
+               mp->offsets[miplevel] = pos - ( (byte *)( mp ) );
+               memcpy( pos, out, scaled_width * scaled_height );
+               memcpy( scaled, out, 256 * 256 );
+               pos += scaled_width * scaled_height;
+
+               scaled_width >>= 1;
+               scaled_height >>= 1;
+
+               miplevel++;
+       }
+
+       *FinalSize = pos - ( (byte *)( mp ) );
+
+       return mp;
+}
+
+
+void GL_ResampleTexture( unsigned *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight ){
+       int i, j;
+       unsigned    *inrow, *inrow2;
+       unsigned frac, fracstep;
+       unsigned p1[1024], p2[1024];
+       byte        *pix1, *pix2, *pix3, *pix4;
+
+       fracstep = inwidth * 0x10000 / outwidth;
+
+       frac = fracstep >> 2;
+       for ( i = 0 ; i < outwidth ; i++ )
+       {
+               p1[i] = 4 * ( frac >> 16 );
+               frac += fracstep;
+       }
+       frac = 3 * ( fracstep >> 2 );
+       for ( i = 0 ; i < outwidth ; i++ )
+       {
+               p2[i] = 4 * ( frac >> 16 );
+               frac += fracstep;
+       }
+
+       for ( i = 0 ; i < outheight ; i++, out += outwidth )
+       {
+               inrow = in + inwidth * (int)( ( i + 0.25 ) * inheight / outheight );
+               inrow2 = in + inwidth * (int)( ( i + 0.75 ) * inheight / outheight );
+               frac = fracstep >> 1;
+               for ( j = 0 ; j < outwidth ; j++ )
+               {
+                       pix1 = (byte *)inrow + p1[j];
+                       pix2 = (byte *)inrow + p2[j];
+                       pix3 = (byte *)inrow2 + p1[j];
+                       pix4 = (byte *)inrow2 + p2[j];
+                       ( (byte *)( out + j ) )[0] = ( pix1[0] + pix2[0] + pix3[0] + pix4[0] ) >> 2;
+                       ( (byte *)( out + j ) )[1] = ( pix1[1] + pix2[1] + pix3[1] + pix4[1] ) >> 2;
+                       ( (byte *)( out + j ) )[2] = ( pix1[2] + pix2[2] + pix3[2] + pix4[2] ) >> 2;
+                       ( (byte *)( out + j ) )[3] = ( pix1[3] + pix2[3] + pix3[3] + pix4[3] ) >> 2;
+               }
+       }
+}
+
+void GL_MipMap( byte *out, byte *in, int width, int height ){
+       int i, j;
+
+       width <<= 3;
+       height <<= 1;
+       for ( i = 0 ; i < height ; i++, in += width )
+       {
+               for ( j = 0 ; j < width ; j += 8, out += 4, in += 8 )
+               {
+                       out[0] = ( in[0] + in[4] + in[width + 0] + in[width + 4] ) >> 2;
+                       out[1] = ( in[1] + in[5] + in[width + 1] + in[width + 5] ) >> 2;
+                       out[2] = ( in[2] + in[6] + in[width + 2] + in[width + 6] ) >> 2;
+                       out[3] = ( in[3] + in[7] + in[width + 3] + in[width + 7] ) >> 2;
+               }
+       }
+}
+
+miptex32_t *CreateMip32( unsigned *data, unsigned width, unsigned height, int *FinalSize, qboolean mip ){
+       int scaled_width, scaled_height;
+       unsigned scaled[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
+       unsigned out[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
+       int miplevel;
+       miptex32_t      *mp;
+       byte            *pos;
+       int size;
+       paletteRGBA_t   *test;
+
+       for ( scaled_width = 1 ; scaled_width < width ; scaled_width <<= 1 )
+               ;
+       if ( 1 && scaled_width > width && 1 ) {
+               scaled_width >>= 1;
+       }
+       for ( scaled_height = 1 ; scaled_height < height ; scaled_height <<= 1 )
+               ;
+       if ( 1 && scaled_height > height && 1 ) {
+               scaled_height >>= 1;
+       }
+
+       // don't ever bother with >256 textures
+       if ( scaled_width > MAX_IMAGE_SIZE ) {
+               scaled_width = MAX_IMAGE_SIZE;
+       }
+       if ( scaled_height > MAX_IMAGE_SIZE ) {
+               scaled_height = MAX_IMAGE_SIZE;
+       }
+
+       if ( scaled_width < 1 ) {
+               scaled_width = 1;
+       }
+       if ( scaled_height < 1 ) {
+               scaled_height = 1;
+       }
+
+       size = sizeof( *mp ) + ( scaled_width * scaled_height * 3 * 4 );
+       mp = (miptex32_t *)SafeMalloc( size, "CreateMip" );
+       memset( mp,0,size );
+
+       mp->version = MIP32_VERSION;
+
+       size = width * height;
+       test = (paletteRGBA_t *)data;
+       while ( size )
+       {
+               if ( test->a != 255 ) {
+                       mp->flags |= LittleLong( SURF_ALPHA_TEXTURE );
+                       break;
+               }
+
+               size--;
+               test++;
+       }
+
+       if ( scaled_width == width && scaled_height == height ) {
+               memcpy( scaled, data, width * height * 4 );
+       }
+       else{
+               GL_ResampleTexture( data, width, height, scaled, scaled_width, scaled_height );
+       }
+
+       pos = (byte *)( mp + 1 );
+       miplevel = 0;
+
+       while ( ( scaled_width >= 1 || scaled_height >= 1 ) && ( miplevel <= MIPLEVELS - 1 ) && ( !miplevel || mip ) )
+       {
+               if ( scaled_width < 1 ) {
+                       scaled_width = 1;
+               }
+               if ( scaled_height < 1 ) {
+                       scaled_height = 1;
+               }
+
+               if ( miplevel > 0 ) {
+                       GL_MipMap( (byte *)out, (byte *)scaled, scaled_width, scaled_height );
+               }
+               else
+               {
+                       memcpy( out, scaled, MAX_IMAGE_SIZE * MAX_IMAGE_SIZE * 4 );
+               }
+
+               mp->width[miplevel] = scaled_width;
+               mp->height[miplevel] = scaled_height;
+               mp->offsets[miplevel] = pos - ( (byte *)( mp ) );
+               memcpy( pos, out, scaled_width * scaled_height * 4 );
+               memcpy( scaled, out, MAX_IMAGE_SIZE * MAX_IMAGE_SIZE * 4 );
+               pos += scaled_width * scaled_height * 4;
+
+               scaled_width >>= 1;
+               scaled_height >>= 1;
+
+               miplevel++;
+       }
+
+       *FinalSize = pos - ( (byte *)( mp ) );
+
+       return mp;
+}
+
+/*
+   ==============
+   Cmd_Grab
+
+   $grab filename x y width height
+   ==============
+ */
+void Cmd_Grab( void ){
+       int xl,yl,w,h,y;
+       byte            *cropped;
+       char savename[1024];
+       char dest[1024];
+
+       GetScriptToken( false );
+
+       if ( token[0] == '/' || token[0] == '\\' ) {
+               sprintf( savename, "%s%s.pcx", gamedir, token + 1 );
+       }
+       else{
+               sprintf( savename, "%spics/%s.pcx", gamedir, token );
+       }
+
+       if ( g_release ) {
+               if ( token[0] == '/' || token[0] == '\\' ) {
+                       sprintf( dest, "%s.pcx", token + 1 );
+               }
+               else{
+                       sprintf( dest, "pics/%s.pcx", token );
+               }
+
+               ReleaseFile( dest );
+               return;
+       }
+
+       GetScriptToken( false );
+       xl = atoi( token );
+       GetScriptToken( false );
+       yl = atoi( token );
+       GetScriptToken( false );
+       w = atoi( token );
+       GetScriptToken( false );
+       h = atoi( token );
+
+       if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) {
+               Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h );
+       }
+
+       // crop it to the proper size
+       cropped = (byte *) SafeMalloc( w * h, "Cmd_Grab" );
+       for ( y = 0 ; y < h ; y++ )
+       {
+               memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w );
+       }
+
+       // save off the new image
+       printf( "saving %s\n", savename );
+       CreatePath( savename );
+       WritePCXfile( savename, cropped, w, h, lbmpalette );
+
+       free( cropped );
+}
+
+/*
+   ==============
+   Cmd_Raw
+
+   $grab filename x y width height
+   ==============
+ */
+void Cmd_Raw( void ){
+       int xl,yl,w,h,y;
+       byte            *cropped;
+       char savename[1024];
+       char dest[1024];
+
+       GetScriptToken( false );
+
+       sprintf( savename, "%s%s.lmp", gamedir, token );
+
+       if ( g_release ) {
+               sprintf( dest, "%s.lmp", token );
+               ReleaseFile( dest );
+               return;
+       }
+
+       GetScriptToken( false );
+       xl = atoi( token );
+       GetScriptToken( false );
+       yl = atoi( token );
+       GetScriptToken( false );
+       w = atoi( token );
+       GetScriptToken( false );
+       h = atoi( token );
+
+       if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) {
+               Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h );
+       }
+
+       // crop it to the proper size
+       cropped = (byte *) SafeMalloc( w * h, "Cmd_Raw" );
+       for ( y = 0 ; y < h ; y++ )
+       {
+               memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w );
+       }
+
+       // save off the new image
+       printf( "saving %s\n", savename );
+       CreatePath( savename );
+
+       SaveFile( savename, cropped, w * h );
+
+       free( cropped );
+}
+
+/*
+   =============================================================================
+
+   COLORMAP GRABBING
+
+   =============================================================================
+ */
+
+/*
+   ===============
+   BestColor
+   ===============
+ */
+byte BestColor( int r, int g, int b, int start, int stop ){
+       int i;
+       int dr, dg, db;
+       int bestdistortion, distortion;
+       int bestcolor;
+       byte    *pal;
+
+//
+// let any color go to 0 as a last resort
+//
+       bestdistortion = 256 * 256 * 4;
+       bestcolor = 0;
+
+       pal = colormap_palette + start * 3;
+       for ( i = start ; i <= stop ; i++ )
+       {
+               dr = r - (int)pal[0];
+               dg = g - (int)pal[1];
+               db = b - (int)pal[2];
+               pal += 3;
+               distortion = dr * dr + dg * dg + db * db;
+               if ( distortion < bestdistortion ) {
+                       if ( !distortion ) {
+                               return i;       // perfect match
+
+                       }
+                       bestdistortion = distortion;
+                       bestcolor = i;
+               }
+       }
+
+       return bestcolor;
+}
+
+
+/*
+   ==============
+   Cmd_Colormap
+
+   $colormap filename
+
+   the brightes colormap is first in the table (FIXME: reverse this now?)
+
+   64 rows of 256 : lightmaps
+   256 rows of 256 : translucency table
+   ==============
+ */
+void Cmd_Colormap( void ){
+       int levels, brights;
+       int l, c;
+       float frac, red, green, blue;
+       float range;
+       byte    *cropped, *lump_p;
+       char savename[1024];
+       char dest[1024];
+
+       colormap_issued = true;
+       if ( !g_release ) {
+               memcpy( colormap_palette, lbmpalette, 768 );
+       }
+
+       if ( !ScriptTokenAvailable() ) { // just setting colormap_issued
+               return;
+       }
+
+       GetScriptToken( false );
+       sprintf( savename, "%spics/%s.pcx", gamedir, token );
+
+       if ( g_release ) {
+               sprintf( dest, "pics/%s.pcx", token );
+               ReleaseFile( dest );
+               return;
+       }
+
+       range = 2;
+       levels = 64;
+       brights = 1;    // ignore 255 (transparent)
+
+       cropped = (byte *) SafeMalloc( ( levels + 256 ) * 256, "Cmd_ColorMap" );
+       lump_p = cropped;
+
+// shaded levels
+       for ( l = 0; l < levels; l++ )
+       {
+               frac = range - range * (float)l / ( levels - 1 );
+               for ( c = 0 ; c < 256 - brights ; c++ )
+               {
+                       red = lbmpalette[c * 3];
+                       green = lbmpalette[c * 3 + 1];
+                       blue = lbmpalette[c * 3 + 2];
+
+                       red = (int)( red * frac + 0.5 );
+                       green = (int)( green * frac + 0.5 );
+                       blue = (int)( blue * frac + 0.5 );
+
+//
+// note: 254 instead of 255 because 255 is the transparent color, and we
+// don't want anything remapping to that
+// don't use color 0, because NT can't remap that (or 255)
+//
+                       *lump_p++ = BestColor( red,green,blue, 1, 254 );
+               }
+
+               // fullbrights allways stay the same
+               for ( ; c < 256 ; c++ )
+                       *lump_p++ = c;
+       }
+
+// 66% transparancy table
+       for ( l = 0; l < 255; l++ )
+       {
+               for ( c = 0 ; c < 255 ; c++ )
+               {
+                       red = lbmpalette[c * 3] * 0.33 + lbmpalette[l * 3] * 0.66;
+                       green = lbmpalette[c * 3 + 1] * 0.33 + lbmpalette[l * 3 + 1] * 0.66;
+                       blue = lbmpalette[c * 3 + 2] * 0.33 + lbmpalette[l * 3 + 2] * 0.66;
+
+                       *lump_p++ = BestColor( red,green,blue, 1, 254 );
+               }
+               *lump_p++ = 255;
+       }
+       for ( c = 0 ; c < 256 ; c++ )
+               *lump_p++ = 255;
+
+       // save off the new image
+       printf( "saving %s\n", savename );
+       CreatePath( savename );
+       WritePCXfile( savename, cropped, 256, levels + 256, lbmpalette );
+
+       free( cropped );
+}
+
+/*
+   =============================================================================
+
+   MIPTEX GRABBING
+
+   =============================================================================
+ */
+
+byte pixdata[256];
+
+int d_red, d_green, d_blue;
+
+byte palmap[32][32][32];
+qboolean palmap_built;
+
+/*
+   =============
+   FindColor
+   =============
+ */
+int FindColor( int r, int g, int b ){
+       int bestcolor;
+
+       if ( r > 255 ) {
+               r = 255;
+       }
+       if ( r < 0 ) {
+               r = 0;
+       }
+       if ( g > 255 ) {
+               g = 255;
+       }
+       if ( g < 0 ) {
+               g = 0;
+       }
+       if ( b > 255 ) {
+               b = 255;
+       }
+       if ( b < 0 ) {
+               b = 0;
+       }
+#ifndef TABLECOLORS
+       bestcolor = BestColor( r, g, b, 0, 254 );
+#else
+       bestcolor = palmap[r >> 3][g >> 3][b >> 3];
+#endif
+
+       return bestcolor;
+}
+
+
+void BuildPalmap( void ){
+#ifdef TABLECOLORS
+       int r, g, b;
+       int bestcolor;
+
+       if ( palmap_built ) {
+               return;
+       }
+       palmap_built = true;
+
+       for ( r = 4 ; r < 256 ; r += 8 )
+       {
+               for ( g = 4 ; g < 256 ; g += 8 )
+               {
+                       for ( b = 4 ; b < 256 ; b += 8 )
+                       {
+                               bestcolor = BestColor( r, g, b, 1, 254 );
+                               palmap[r >> 3][g >> 3][b >> 3] = bestcolor;
+                       }
+               }
+       }
+#endif
+
+       if ( !colormap_issued ) {
+               Error( "You must issue a $colormap command first" );
+       }
+
+}
+
+/*
+   =============
+   AveragePixels
+   =============
+ */
+byte AveragePixels( int count ){
+       int r,g,b;
+       int i;
+       int vis;
+       int pix;
+       int bestcolor;
+       byte    *pal;
+       int fullbright;
+
+       vis = 0;
+       r = g = b = 0;
+       fullbright = 0;
+       for ( i = 0 ; i < count ; i++ )
+       {
+               pix = pixdata[i];
+
+               r += lbmpalette[pix * 3];
+               g += lbmpalette[pix * 3 + 1];
+               b += lbmpalette[pix * 3 + 2];
+               vis++;
+       }
+
+       r /= vis;
+       g /= vis;
+       b /= vis;
+
+       // error diffusion
+       r += d_red;
+       g += d_green;
+       b += d_blue;
+
+//
+// find the best color
+//
+       bestcolor = FindColor( r, g, b );
+
+       // error diffusion
+       pal = colormap_palette + bestcolor * 3;
+       d_red = r - (int)pal[0];
+       d_green = g - (int)pal[1];
+       d_blue = b - (int)pal[2];
+
+       return bestcolor;
+}
+
+
+typedef enum
+{
+       pt_contents,
+       pt_flags,
+       pt_animvalue,
+       pt_altnamevalue,
+       pt_damagenamevalue,
+       pt_flagvalue,
+       pt_materialvalue,
+       pt_scale,
+       pt_mip,
+       pt_detail,
+       pt_gl,
+       pt_nomip,
+       pt_detailer,
+} parmtype_t;
+
+typedef struct
+{
+       char    *name;
+       int flags;
+       parmtype_t type;
+} mipparm_t;
+
+mipparm_t mipparms[] =
+{
+       // utility content attributes
+       {"pushpull",CONTENTS_PUSHPULL, pt_contents},
+       {"water",   CONTENTS_WATER, pt_contents},
+       {"slime",   CONTENTS_SLIME, pt_contents},       // mildly damaging
+       {"lava",    CONTENTS_LAVA, pt_contents},        // very damaging
+       {"window",  CONTENTS_WINDOW, pt_contents},  // solid, but doesn't eat internal textures
+       {"mist",    CONTENTS_MIST, pt_contents},    // non-solid window
+       {"origin",  CONTENTS_ORIGIN, pt_contents},  // center of rotating brushes
+       {"playerclip",  CONTENTS_PLAYERCLIP, pt_contents},
+       {"monsterclip", CONTENTS_MONSTERCLIP, pt_contents},
+
+       // utility surface attributes
+       {"hint",    SURF_HINT, pt_flags},
+       {"skip",    SURF_SKIP, pt_flags},
+       {"light",   SURF_LIGHT, pt_flagvalue},      // value is the light quantity
+
+       {"animspeed",SURF_ANIMSPEED, pt_flagvalue},     // value will hold the anim speed in fps
+
+       // texture chaining
+       {"anim",    0,          pt_animvalue},      // animname is the next animation
+       {"alt",     0,          pt_altnamevalue},   // altname is the alternate texture
+       {"damage",  0,          pt_damagenamevalue},    // damagename is the damage texture
+       {"scale",   0,          pt_scale},      // next two values are for scale
+       {"mip",     0,          pt_mip},
+       {"detail",  0,          pt_detail},
+
+       {"GL_ZERO",                 GL_ZERO,                pt_gl},
+       {"GL_ONE",                  GL_ONE,                 pt_gl},
+       {"GL_SRC_COLOR",            GL_SRC_COLOR,           pt_gl},
+       {"GL_ONE_MINUS_SRC_COLOR",  GL_ONE_MINUS_SRC_COLOR, pt_gl},
+       {"GL_DST_COLOR",            GL_DST_COLOR,           pt_gl},
+       {"GL_ONE_MINUS_DST_COLOR",  GL_ONE_MINUS_DST_COLOR, pt_gl},
+       {"GL_SRC_ALPHA",            GL_SRC_ALPHA,           pt_gl},
+       {"GL_ONE_MINUS_SRC_ALPHA",  GL_ONE_MINUS_SRC_ALPHA, pt_gl},
+       {"GL_DST_ALPHA",            GL_DST_ALPHA,           pt_gl},
+       {"GL_ONE_MINUS_DST_ALPHA",  GL_ONE_MINUS_DST_ALPHA, pt_gl},
+       {"GL_SRC_ALPHA_SATURATE",   GL_SRC_ALPHA_SATURATE,  pt_gl},
+
+       // server attributes
+       {"slick",   SURF_SLICK, pt_flags},
+
+       // drawing attributes
+       {"sky",     SURF_SKY, pt_flags},
+       {"warping", SURF_WARP, pt_flags},       // only valid with 64x64 textures
+       {"trans33", SURF_TRANS33, pt_flags},    // translucent should allso set fullbright
+       {"trans66", SURF_TRANS66, pt_flags},
+       {"flowing", SURF_FLOWING, pt_flags},    // flow direction towards angle 0
+       {"nodraw",  SURF_NODRAW, pt_flags}, // for clip textures and trigger textures
+       {"alpha",   SURF_ALPHA_TEXTURE, pt_flags},
+       {"undulate",    SURF_UNDULATE, pt_flags},       // rock surface up and down...
+       {"skyreflect",  SURF_SKYREFLECT, pt_flags},     // liquid will somewhat reflect the sky - not quite finished....
+
+       {"material", SURF_MATERIAL, pt_materialvalue},
+       {"metal",   SURF_TYPE_METAL, pt_flags},
+       {"stone",   SURF_TYPE_STONE, pt_flags},
+       {"wood",    SURF_TYPE_WOOD, pt_flags},
+
+       {"m_nomip", 0, pt_nomip},
+       {"m_detail", 0, pt_detailer},
+
+       {NULL, 0, pt_contents}
+};
+
+/*
+   ==============
+   Cmd_Mip
+
+   $mip filename x y width height <OPTIONS>
+   must be multiples of sixteen
+   SURF_WINDOW
+   ==============
+ */
+
+void Cmd_Mip( void ){
+       int xl,yl,xh,yh,w,h;
+       byte            *dest, *source;
+       int flags, value, contents;
+       mipparm_t       *mp;
+       char lumpname[128];
+       char altname[128];
+       char animname[128];
+       char damagename[128];
+       byte buffer[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
+       unsigned bufferl[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
+       materialtype_t  *mat;
+       char filename[1024];
+       unsigned        *destl, *sourcel;
+       int linedelta, x, y;
+       int size;
+       miptex_t        *qtex;
+       miptex32_t      *qtex32;
+       float scale_x, scale_y;
+       int mip_scale;
+       // detail texturing
+       char dt_name[128];
+       float dt_scale_x, dt_scale_y;
+       float dt_u, dt_v;
+       float dt_alpha;
+       int dt_src_blend_mode, dt_dst_blend_mode;
+       int flags2;
+
+
+       GetScriptToken( false );
+       strcpy( lumpname, token );
+
+       GetScriptToken( false );
+       xl = atoi( token );
+       GetScriptToken( false );
+       yl = atoi( token );
+       GetScriptToken( false );
+       w = atoi( token );
+       GetScriptToken( false );
+       h = atoi( token );
+
+       total_x += w;
+       total_y += h;
+       total_textures++;
+
+       if ( ( w & 15 ) || ( h & 15 ) ) {
+               Error( "line %i: miptex sizes must be multiples of 16", scriptline );
+       }
+
+       flags = 0;
+       flags2 = 0;
+       contents = 0;
+       value = 0;
+       mip_scale = 0;
+
+       altname[0] = animname[0] = damagename[0] = 0;
+
+       scale_x = scale_y = 0.5;
+
+       // detail texturing
+       dt_name[0] = 0;
+       dt_scale_x = dt_scale_y = 0.0;
+       dt_u = dt_v = 0.0;
+       dt_alpha = 0.0;
+       dt_src_blend_mode = dt_dst_blend_mode = 0;
+
+       // get optional flags and values
+       while ( ScriptTokenAvailable() )
+       {
+               GetScriptToken( false );
+
+               for ( mp = mipparms ; mp->name ; mp++ )
+               {
+                       if ( !strcmp( mp->name, token ) ) {
+                               switch ( mp->type )
+                               {
+                               case pt_animvalue:
+                                       GetScriptToken( false );    // specify the next animation frame
+                                       strcpy( animname, token );
+                                       break;
+                               case pt_altnamevalue:
+                                       GetScriptToken( false );    // specify the alternate texture
+                                       strcpy( altname, token );
+                                       break;
+                               case pt_damagenamevalue:
+                                       GetScriptToken( false );    // specify the damage texture
+                                       strcpy( damagename, token );
+                                       break;
+                               case pt_flags:
+                                       flags |= mp->flags;
+                                       break;
+                               case pt_contents:
+                                       contents |= mp->flags;
+                                       break;
+                               case pt_flagvalue:
+                                       flags |= mp->flags;
+                                       GetScriptToken( false );    // specify the light value
+                                       value = atoi( token );
+                                       break;
+                               case pt_materialvalue:
+                                       GetScriptToken( false );
+                                       for ( mat = materialtypes ; mat->name ; mat++ )
+                                       {
+                                               if ( !strcmp( mat->name, token ) ) {
+                                                       // assumes SURF_MATERIAL is in top 8 bits
+                                                       flags = ( flags & 0x0FFFFFF ) | ( mat->value << 24 );
+                                                       break;
+                                               }
+                                       }
+                                       break;
+                               case pt_scale:
+                                       GetScriptToken( false );    // specify the x scale
+                                       scale_x = atof( token );
+                                       GetScriptToken( false );    // specify the y scale
+                                       scale_y = atof( token );
+                                       break;
+
+                               case pt_mip:
+                                       mip_scale = 1;
+                                       break;
+
+                               case pt_detailer:
+                                       flags2 |= MIP32_DETAILER_FLAG2;
+                                       break;
+
+                               case pt_nomip:
+                                       flags2 |= MIP32_NOMIP_FLAG2;
+                                       break;
+
+                               case pt_detail:
+                                       GetScriptToken( false );
+                                       strcpy( dt_name, token );
+                                       GetScriptToken( false );
+                                       dt_scale_x = atof( token );
+                                       GetScriptToken( false );
+                                       dt_scale_y = atof( token );
+                                       GetScriptToken( false );
+                                       dt_u = atof( token );
+                                       GetScriptToken( false );
+                                       dt_v = atof( token );
+                                       GetScriptToken( false );
+                                       dt_alpha = atof( token );
+                                       GetScriptToken( false );
+                                       for ( mp = mipparms ; mp->name ; mp++ )
+                                       {
+                                               if ( !strcmp( mp->name, token ) ) {
+                                                       if ( mp->type == pt_gl ) {
+                                                               dt_src_blend_mode = mp->flags;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if ( !mp->name ) {
+                                               Error( "line %i: invalid gl blend mode %s", scriptline, token );
+                                       }
+                                       GetScriptToken( false );
+                                       for ( mp = mipparms ; mp->name ; mp++ )
+                                       {
+                                               if ( !strcmp( mp->name, token ) ) {
+                                                       if ( mp->type == pt_gl ) {
+                                                               dt_dst_blend_mode = mp->flags;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       if ( !mp->name ) {
+                                               Error( "line %i: invalid gl blend mode %s", scriptline, token );
+                                       }
+                                       break;
+                               }
+                               break;
+                       }
+               }
+               if ( !mp->name ) {
+                       Error( "line %i: unknown parm %s", scriptline, token );
+               }
+       }
+
+       if ( g_release ) {
+               return; // textures are only released by $maps
+
+       }
+       xh = xl + w;
+       yh = yl + h;
+       if ( xh * yh > MAX_IMAGE_SIZE * MAX_IMAGE_SIZE ) {
+               Error( "line %i image %s: image is too big!", scriptline, lumpname );
+       }
+
+       if ( TrueColorImage ) {
+               if ( xl >= longimagewidth || xh > longimagewidth ||
+                        yl >= longimageheight || yh > longimageheight ) {
+                       Error( "line %i image %s: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, lumpname, xl,yl,w,h,longimagewidth,longimageheight );
+               }
+
+               sourcel = longimage + ( yl * longimagewidth ) + xl;
+               destl = bufferl;
+               linedelta = ( longimagewidth - w );
+
+               for ( y = yl ; y < yh ; y++ )
+               {
+                       for ( x = xl ; x < xh ; x++ )
+                       {
+                               *destl++ = *sourcel++;  // RGBA
+                       }
+                       sourcel += linedelta;
+               }
+
+               qtex32 = CreateMip32( bufferl, w, h, &size, true );
+
+               qtex32->flags |= LittleLong( flags );
+               qtex32->flags2 |= LittleLong( flags2 );
+               qtex32->contents = LittleLong( contents );
+               qtex32->value = LittleLong( value );
+               qtex32->scale_x = scale_x;
+               qtex32->scale_y = scale_y;
+               qtex32->mip_scale = mip_scale;
+               sprintf( qtex32->name, "%s/%s", mip_prefix, lumpname );
+               if ( animname[0] ) {
+                       sprintf( qtex32->animname, "%s/%s", mip_prefix, animname );
+               }
+               if ( altname[0] ) {
+                       sprintf( qtex32->altname, "%s/%s", mip_prefix, altname );
+               }
+               if ( damagename[0] ) {
+                       sprintf( qtex32->damagename, "%s/%s", mip_prefix, damagename );
+               }
+               if ( dt_name[0] & ( ( flags2 & MIP32_DETAILER_FLAG2 ) == 0 ) ) {
+                       sprintf( qtex32->dt_name, "%s/%s", mip_prefix, dt_name );
+                       qtex32->dt_scale_x = dt_scale_x;
+                       qtex32->dt_scale_y = dt_scale_y;
+                       qtex32->dt_u = dt_u;
+                       qtex32->dt_v = dt_v;
+                       qtex32->dt_alpha = dt_alpha;
+                       qtex32->dt_src_blend_mode = dt_src_blend_mode;
+                       qtex32->dt_dst_blend_mode = dt_dst_blend_mode;
+               }
+
+               //
+               // write it out
+               //
+               sprintf( filename, "%stextures/%s/%s.m32", g_outputDir, mip_prefix, lumpname );
+               if ( qtex32->flags & ( SURF_ALPHA_TEXTURE ) ) {
+                       printf( "writing %s with ALPHA\n", filename );
+               }
+               else{
+                       printf( "writing %s\n", filename );
+               }
+               SaveFile( filename, (byte *)qtex32, size );
+
+               free( qtex32 );
+       }
+       else
+       {
+               if ( xl >= byteimagewidth || xh > byteimagewidth ||
+                        yl >= byteimageheight || yh > byteimageheight ) {
+                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
+               }
+
+               source = byteimage + yl * byteimagewidth + xl;
+               dest = buffer;
+               linedelta = byteimagewidth - w;
+
+               for ( y = yl ; y < yh ; y++ )
+               {
+                       for ( x = xl ; x < xh ; x++ )
+                       {
+                               *dest++ = *source++;
+                       }
+                       source += linedelta;
+               }
+
+               qtex = CreateMip( buffer, w, h, lbmpalette, &size, true );
+
+               qtex->flags = LittleLong( flags );
+               qtex->contents = LittleLong( contents );
+               qtex->value = LittleLong( value );
+               sprintf( qtex->name, "%s/%s", mip_prefix, lumpname );
+               if ( animname[0] ) {
+                       sprintf( qtex->animname, "%s/%s", mip_prefix, animname );
+               }
+
+               //
+               // write it out
+               //
+               sprintf( filename, "%stextures/%s/%s.m8", g_outputDir, mip_prefix, lumpname );
+               printf( "writing %s\n", filename );
+               SaveFile( filename, (byte *)qtex, size );
+
+               free( qtex );
+       }
+}
+
+/*
+   ===============
+   Cmd_Mippal
+   ===============
+ */
+void Cmd_Mippal( void ){
+       colormap_issued = true;
+       if ( g_release ) {
+               return;
+       }
+
+       memcpy( colormap_palette, lbmpalette, 768 );
+
+       BuildPalmap();
+}
+
+
+/*
+   ===============
+   Cmd_Mipdir
+   ===============
+ */
+void Cmd_Mipdir( void ){
+       char filename[1024];
+
+       GetScriptToken( false );
+       strcpy( mip_prefix, token );
+       // create the directory if needed
+       sprintf( filename, "%stextures", g_outputDir );
+       Q_mkdir( filename );
+       sprintf( filename, "%stextures/%s", g_outputDir, mip_prefix );
+       Q_mkdir( filename );
+}
+
+
+/*
+   =============================================================================
+
+   ENVIRONMENT MAP GRABBING
+
+   Creates six pcx files from tga files without any palette edge seams
+   also copies the tga files for GL rendering.
+   =============================================================================
+ */
+
+// 3dstudio environment map suffixes
+char    *suf[6] = {"rt", "ft", "lf", "bk", "up", "dn"};
+
+/*
+   =================
+   Cmd_Environment
+   =================
+ */
+void Cmd_Environment( void ){
+       char name[1024];
+       int i, x, y;
+       byte image[256 * 256];
+       byte    *tga;
+
+       GetScriptToken( false );
+
+       if ( g_release ) {
+               for ( i = 0 ; i < 6 ; i++ )
+               {
+                       sprintf( name, "env/%s%s.pcx", token, suf[i] );
+                       ReleaseFile( name );
+                       sprintf( name, "env/%s%s.tga", token, suf[i] );
+                       ReleaseFile( name );
+               }
+               return;
+       }
+       // get the palette
+       BuildPalmap();
+
+       sprintf( name, "%senv/", gamedir );
+       CreatePath( name );
+
+       // convert the images
+       for ( i = 0 ; i < 6 ; i++ )
+       {
+               sprintf( name, "%senv/%s%s.tga", gamedir, token, suf[i] );
+               printf( "loading %s...\n", name );
+               LoadTGA( name, &tga, NULL, NULL );
+
+               for ( y = 0 ; y < 256 ; y++ )
+               {
+                       for ( x = 0 ; x < 256 ; x++ )
+                       {
+                               image[y * 256 + x] = FindColor( tga[( y * 256 + x ) * 4 + 0],tga[( y * 256 + x ) * 4 + 1],tga[( y * 256 + x ) * 4 + 2] );
+                       }
+               }
+               free( tga );
+               sprintf( name, "%senv/%s%s.pcx", gamedir, token, suf[i] );
+               if ( FileTime( name ) != -1 ) {
+                       printf( "%s already exists, not overwriting.\n", name );
+               }
+               else{
+                       WritePCXfile( name, image, 256, 256, colormap_palette );
+               }
+       }
+}
diff --git a/tools/heretic2/h2data/jointed.c b/tools/heretic2/h2data/jointed.c
new file mode 100644 (file)
index 0000000..de8b802
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <assert.h>
+#include <math.h>
+#include "token.h"
+#include "joints.h"
+#include "angles.h"
+#include "inout.h"
+
+char *SKEL_ROOT_NAMES[] =
+{
+       "RAVEN_SPINE"
+};
+
+char *SKEL_NAMES[] =
+{
+       "RAVEN_WAIST1",
+       "RAVEN_WAIST2",
+       "RAVEN_NECK"
+};
+
+int NAME_OFFSETS[] =
+{
+       0
+};
+
+int numJointsForSkeleton[] =
+{
+       NUM_JOINTS_RAVEN,
+       NUM_JOINTS_BOX
+};
+
+float g_scaling[3];
+float g_rotation[3];
+float g_translation[3];
+
+//==========================================================================
+//
+// LoadHRCClustered
+//
+//==========================================================================
+
+static void LoadHRCClustered( char *fileName, int **clusterList, int *num_verts, int skelType ){
+       int i, j;
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+
+       TK_Beyond( TK_CLUSTERS );
+
+       while ( TK_Search( TK_CLUSTER_NAME ) != TK_EOF )
+       {
+               TK_Require( TK_STRING );
+
+               for ( i = 0; i < numJointsForSkeleton[skelType]; ++i )
+               {
+                       if ( stricmp( tk_String, SKEL_NAMES[NAME_OFFSETS[skelType] + i] ) == 0 ) {
+                               i = -i + numJointsForSkeleton[skelType] - 1;
+
+                               TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER );
+
+                               num_verts[i + 1] = tk_IntNumber;
+
+                               clusterList[i] = (int *) SafeMalloc( num_verts[i + 1] * sizeof( int ), "LoadHRCClustered" );
+                               assert( clusterList[i] );
+                               // currently this function is only called by LoadTriangleListClustered, which in turn is only
+                               // called by Cmd_Base in qdata.  This is where the only call to free for this memory is being made.
+
+                               TK_Beyond( TK_LBRACE );
+
+                               for ( j = 0; j < num_verts[i + 1]; ++j )
+                               {
+                                       TK_Require( TK_INTNUMBER );
+                                       clusterList[i][j] = tk_IntNumber;
+                                       TK_Fetch();
+                               }
+
+                               break;
+                       }
+               }
+       }
+
+       num_verts[0] = numJointsForSkeleton[skelType];
+}
+
+static void LoadHRCGlobals( char *fileName ){
+       int i;
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+       TK_Beyond( TK_MODEL );
+
+       TK_Beyond( TK_SCALING );
+       for ( i = 0; i < 3; i++ )
+       {
+               TK_Require( TK_FLOATNUMBER );
+               g_scaling[i] = tk_FloatNumber;
+               TK_Fetch();
+       }
+
+       TK_Beyond( TK_ROTATION );
+       for ( i = 0; i < 3; i++ )
+       {
+               TK_Require( TK_FLOATNUMBER );
+               g_rotation[i] = tk_FloatNumber;
+               TK_Fetch();
+       }
+
+       TK_Beyond( TK_TRANSLATION );
+       for ( i = 0; i < 3; i++ )
+       {
+               TK_Require( TK_FLOATNUMBER );
+               g_translation[i] = tk_FloatNumber;
+               TK_Fetch();
+       }
+}
+
+static void ParseVec3( vec3_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void ParseRotation3( vec3_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = -tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void ParseTranslation3( vec3_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void LoadHRCJointList( char *fileName, QDataJoint_t *jointList, int skelType ){
+#define MAX_STACK 64
+       int i, j;
+       vec3_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];
+       int curCorrespondingJoint[MAX_STACK];
+       int currentStack = 0, stackSize;
+       int baseJoint;
+       float cx, sx, cy, sy, cz, sz;
+       float rx, ry, rz;
+       float x2, y2, z2;
+
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+
+       TK_Beyond( TK_MODEL );
+       TK_Beyond( TK_MODEL );
+
+/*     while(1)
+    {
+        TK_Beyond(TK_MODEL);
+        TK_BeyondRequire(TK_NAME, TK_STRING);
+
+        if(_stricmp(tk_String, SKEL_ROOT_NAMES[skelType]) == 0)
+            break;
+    }*/
+
+       TK_Beyond( TK_SCALING );
+
+       ParseVec3( curScale[currentStack] );
+
+       TK_Beyond( TK_ROTATION );
+
+       ParseRotation3( curRotation[currentStack] );
+
+       TK_Beyond( TK_TRANSLATION );
+
+       ParseVec3( curTranslation[currentStack] );
+
+       // account for global model translation
+       curTranslation[currentStack][1] += g_translation[0];
+       curTranslation[currentStack][2] += g_translation[1];
+       curTranslation[currentStack][0] += g_translation[2];
+
+       ++currentStack;
+
+       for ( i = 0; i < NUM_JOINTS_RAVEN; ++i )
+       {
+               while ( 1 )
+               {
+                       TK_Beyond( TK_MODEL );
+
+//                     TK_BeyondRequire(TK_NAME, TK_STRING);
+
+//                     if(_stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0)
+                       break;
+
+                       TK_Beyond( TK_SCALING );
+
+                       ParseVec3( curScale[currentStack] );
+
+                       TK_Beyond( TK_ROTATION );
+
+                       ParseRotation3( curRotation[currentStack] );
+
+                       TK_Beyond( TK_TRANSLATION );
+
+                       ParseVec3( curTranslation[currentStack] );
+
+                       curCorrespondingJoint[currentStack] = -1;
+
+                       ++currentStack;
+               }
+
+               TK_Beyond( TK_SCALING );
+
+               ParseVec3( curScale[currentStack] );
+
+               TK_Beyond( TK_ROTATION );
+
+               ParseRotation3( curRotation[currentStack] );
+
+               jointList[i].rotation[1] = curRotation[currentStack][1];
+               jointList[i].rotation[2] = curRotation[currentStack][2];
+               jointList[i].rotation[0] = curRotation[currentStack][0];
+
+               TK_Beyond( TK_TRANSLATION );
+
+               ParseVec3( curTranslation[currentStack] );
+
+               jointList[i].placement.origin[1] = curTranslation[currentStack][1];
+               jointList[i].placement.origin[2] = curTranslation[currentStack][2];
+               jointList[i].placement.origin[0] = curTranslation[currentStack][0];
+
+               jointList[i].placement.direction[1] = 7.5;
+               jointList[i].placement.direction[2] = 0.0;
+               jointList[i].placement.direction[0] = 0.0;
+
+               jointList[i].placement.up[1] = 0.0;
+               jointList[i].placement.up[2] = 7.5;
+               jointList[i].placement.up[0] = 0.0;
+
+               curCorrespondingJoint[currentStack] = i;
+
+               ++currentStack;
+       }
+
+       stackSize = currentStack;
+
+       for ( i = 0; i < NUM_JOINTS_RAVEN; ++i )
+       {
+               rx = jointList[i].rotation[0] * ANGLE_TO_RAD;
+               ry = jointList[i].rotation[1] * ANGLE_TO_RAD;
+               rz = jointList[i].rotation[2] * ANGLE_TO_RAD;
+
+               cx = cos( rx );
+               sx = sin( rx );
+
+               cy = cos( ry );
+               sy = sin( ry );
+
+               cz = cos( rz );
+               sz = sin( rz );
+
+               // y-axis rotation for direction
+               x2 = jointList[i].placement.direction[0] * cy + jointList[i].placement.direction[2] * sy;
+               z2 = -jointList[i].placement.direction[0] * sy + jointList[i].placement.direction[2] * cy;
+               jointList[i].placement.direction[0] = x2;
+               jointList[i].placement.direction[2] = z2;
+
+               // y-axis rotation for up
+               x2 = jointList[i].placement.up[0] * cy + jointList[i].placement.up[2] * sy;
+               z2 = -jointList[i].placement.up[0] * sy + jointList[i].placement.up[2] * cy;
+               jointList[i].placement.up[0] = x2;
+               jointList[i].placement.up[2] = z2;
+
+               // z-axis rotation for direction
+               x2 = jointList[i].placement.direction[0] * cz - jointList[i].placement.direction[1] * sz;
+               y2 = jointList[i].placement.direction[0] * sz + jointList[i].placement.direction[1] * cz;
+               jointList[i].placement.direction[0] = x2;
+               jointList[i].placement.direction[1] = y2;
+
+               // z-axis rotation for up
+               x2 = jointList[i].placement.up[0] * cz - jointList[i].placement.up[1] * sz;
+               y2 = jointList[i].placement.up[0] * sz + jointList[i].placement.up[1] * cz;
+               jointList[i].placement.up[0] = x2;
+               jointList[i].placement.up[1] = y2;
+
+               // x-axis rotation for direction vector
+               y2 = jointList[i].placement.direction[1] * cx - jointList[i].placement.direction[2] * sx;
+               z2 = jointList[i].placement.direction[1] * sx + jointList[i].placement.direction[2] * cx;
+               jointList[i].placement.direction[1] = y2;
+               jointList[i].placement.direction[2] = z2;
+
+               // x-axis rotation for up vector
+               y2 = jointList[i].placement.up[1] * cx - jointList[i].placement.up[2] * sx;
+               z2 = jointList[i].placement.up[1] * sx + jointList[i].placement.up[2] * cx;
+               jointList[i].placement.up[1] = y2;
+               jointList[i].placement.up[2] = z2;
+
+               // translate to position in model
+               jointList[i].placement.direction[0] += jointList[i].placement.origin[0];
+               jointList[i].placement.direction[1] += jointList[i].placement.origin[1];
+               jointList[i].placement.direction[2] += jointList[i].placement.origin[2];
+
+               // translate to position in model
+               jointList[i].placement.up[0] += jointList[i].placement.origin[0];
+               jointList[i].placement.up[1] += jointList[i].placement.origin[1];
+               jointList[i].placement.up[2] += jointList[i].placement.origin[2];
+       }
+
+       baseJoint = NUM_JOINTS_RAVEN;
+
+       for ( i = stackSize /*NUM_JOINTS_RAVEN*/ - 1; i > 0; --i )
+       {
+
+               rx = curRotation[i - 1][0] * ANGLE_TO_RAD;
+               ry = curRotation[i - 1][1] * ANGLE_TO_RAD;
+               rz = curRotation[i - 1][2] * ANGLE_TO_RAD;
+
+               cx = cos( rx );
+               sx = sin( rx );
+
+               cy = cos( ry );
+               sy = sin( ry );
+
+               cz = cos( rz );
+               sz = sin( rz );
+
+               for ( j = i - 1; j < stackSize - 1; ++j )
+               {
+                       // y-axis rotation for origin
+                       x2 = jointList[j].placement.origin[0] * cy + jointList[j].placement.origin[2] * sy;
+                       z2 = -jointList[j].placement.origin[0] * sy + jointList[j].placement.origin[2] * cy;
+                       jointList[j].placement.origin[0] = x2;
+                       jointList[j].placement.origin[2] = z2;
+
+                       // y-axis rotation for direction
+                       x2 = jointList[j].placement.direction[0] * cy + jointList[j].placement.direction[2] * sy;
+                       z2 = -jointList[j].placement.direction[0] * sy + jointList[j].placement.direction[2] * cy;
+                       jointList[j].placement.direction[0] = x2;
+                       jointList[j].placement.direction[2] = z2;
+
+                       // y-axis rotation for up
+                       x2 = jointList[j].placement.up[0] * cy + jointList[j].placement.up[2] * sy;
+                       z2 = -jointList[j].placement.up[0] * sy + jointList[j].placement.up[2] * cy;
+                       jointList[j].placement.up[0] = x2;
+                       jointList[j].placement.up[2] = z2;
+
+                       // z-axis rotation for origin
+                       x2 = jointList[j].placement.origin[0] * cz - jointList[j].placement.origin[1] * sz;
+                       y2 = jointList[j].placement.origin[0] * sz + jointList[j].placement.origin[1] * cz;
+                       jointList[j].placement.origin[0] = x2;
+                       jointList[j].placement.origin[1] = y2;
+
+                       // z-axis rotation for direction
+                       x2 = jointList[j].placement.direction[0] * cz - jointList[j].placement.direction[1] * sz;
+                       y2 = jointList[j].placement.direction[0] * sz + jointList[j].placement.direction[1] * cz;
+                       jointList[j].placement.direction[0] = x2;
+                       jointList[j].placement.direction[1] = y2;
+
+                       // z-axis rotation for up
+                       x2 = jointList[j].placement.up[0] * cz - jointList[j].placement.up[1] * sz;
+                       y2 = jointList[j].placement.up[0] * sz + jointList[j].placement.up[1] * cz;
+                       jointList[j].placement.up[0] = x2;
+                       jointList[j].placement.up[1] = y2;
+
+                       // x-axis rotation for origin
+                       y2 = jointList[j].placement.origin[1] * cx - jointList[j].placement.origin[2] * sx;
+                       z2 = jointList[j].placement.origin[1] * sx + jointList[j].placement.origin[2] * cx;
+                       jointList[j].placement.origin[1] = y2;
+                       jointList[j].placement.origin[2] = z2;
+
+                       // x-axis rotation for direction vector
+                       y2 = jointList[j].placement.direction[1] * cx - jointList[j].placement.direction[2] * sx;
+                       z2 = jointList[j].placement.direction[1] * sx + jointList[j].placement.direction[2] * cx;
+                       jointList[j].placement.direction[1] = y2;
+                       jointList[j].placement.direction[2] = z2;
+
+                       // x-axis rotation for up vector
+                       y2 = jointList[j].placement.up[1] * cx - jointList[j].placement.up[2] * sx;
+                       z2 = jointList[j].placement.up[1] * sx + jointList[j].placement.up[2] * cx;
+                       jointList[j].placement.up[1] = y2;
+                       jointList[j].placement.up[2] = z2;
+
+                       if ( curCorrespondingJoint[j + 1] != -1 ) {
+                               // translate origin
+                               jointList[j].placement.origin[0] += curTranslation[i - 1][0];
+                               jointList[j].placement.origin[1] += curTranslation[i - 1][1];
+                               jointList[j].placement.origin[2] += curTranslation[i - 1][2];
+
+                               // translate back to local coord
+                               jointList[j].placement.direction[0] += curTranslation[i - 1][0];
+                               jointList[j].placement.direction[1] += curTranslation[i - 1][1];
+                               jointList[j].placement.direction[2] += curTranslation[i - 1][2];
+
+                               // translate back to local coord
+                               jointList[j].placement.up[0] += curTranslation[i - 1][0];
+                               jointList[j].placement.up[1] += curTranslation[i - 1][1];
+                               jointList[j].placement.up[2] += curTranslation[i - 1][2];
+                       }
+               }
+       }
+}
+
+void LoadGlobals( char *fileName ){
+       FILE *file1;
+       int dot = '.';
+       char *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+
+                       LoadHRCGlobals( InputFileName );
+
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC match.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+                       printf( "\n" );
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRCGlobals( fileName );
+                               return;
+                       }
+               }
+
+               Error( "Could not open file '%s':\n",fileName );
+       }
+}
+
+void LoadClusters( char *fileName, int **clusterList, int *num_verts, int skelType ){
+       FILE *file1;
+       int dot = '.';
+       char *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+
+                       LoadHRCClustered( InputFileName, clusterList, num_verts, skelType );
+
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC match.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+                       printf( "\n" );
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRCClustered( fileName, clusterList, num_verts, skelType );
+                               return;
+                       }
+               }
+
+               Error( "Could not open file '%s':\n",fileName );
+       }
+}
+
+void LoadJointList( char *fileName, QDataJoint_t *jointList, int skelType ){
+       FILE *file1;
+       int dot = '.';
+       char *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+
+                       LoadHRCJointList( InputFileName, jointList, skelType );
+
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+                       printf( "\n" );
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRCJointList( fileName, jointList, skelType );
+
+                               return;
+                       }
+               }
+
+               Error( "Could not open file '%s':\n",fileName );
+       }
+}
diff --git a/tools/heretic2/h2data/jointed.h b/tools/heretic2/h2data/jointed.h
new file mode 100644 (file)
index 0000000..264d317
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _JOINTED_H
+#define _JOINTED_H
+
+#include "joints.h"
+
+void LoadGlobals( char *fileName );
+void LoadClusters( char *fileName, int **clusterList, int *num_verts, int skel_type );
+void LoadJointList( char *fileName, struct QDataJoint_s *jointList, int num_verts );
+
+#define NUM_CLUSTERS 8
+
+#define NOT_JOINTED -1
+
+#endif //_JOINTED_H
diff --git a/tools/heretic2/h2data/joints.h b/tools/heretic2/h2data/joints.h
new file mode 100644 (file)
index 0000000..f8e64bf
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef JOINTS_H
+#define JOINTS_H
+
+#include "globaldefs.h"
+
+#ifdef _HERETIC2_
+#include "angles.h"
+#endif
+
+//typedef float vec3_t[3];
+//typedef unsigned char byte;
+
+#if !GDEF_OS_WINDOWS
+#define stricmp strcasecmp
+#define strcmpi strcasecmp
+#endif
+
+typedef struct Placement_s
+{
+       vec3_t origin;
+       vec3_t direction;
+       vec3_t up;
+} Placement_t;
+
+#if 1
+typedef struct QDataJoint_s
+{
+       Placement_t placement;
+       vec3_t rotation;
+} QDataJoint_t;
+#endif
+
+typedef struct ArrayedListNode_s
+{
+       int data;
+       int next;
+       int inUse;
+} ArrayedListNode_t;
+
+#define ARRAYEDLISTNODE_NULL -1
+
+typedef struct JointAngles_s
+{
+       float angles[3];
+       int children;
+       int created;
+} JointAngles_t;
+
+typedef struct JointAngles2_s
+{
+       float angles[3];
+       int children;
+       int changed[3];
+       int inUse;
+} JointAngles2_t;
+
+#define MAX_MODELJOINTS         256
+#define MAX_MODELJOINTNODES     255
+
+extern JointAngles_t jointAngles[MAX_MODELJOINTS];
+extern JointAngles2_t jointAngles2[MAX_MODELJOINTS];
+
+extern ArrayedListNode_t jointAngleNodes[MAX_MODELJOINTNODES];
+
+// Skeletal structures enums
+enum {
+       SKEL_RAVEN = 0,
+       SKEL_BOX,
+       NUM_SKELETONS
+};
+
+// Raven Skeletal structures enums
+enum {
+       RAVEN_WAIST1 = 0,
+       RAVEN_WAIST2 = 1,
+       RAVEN_HEAD = 2,
+       NUM_JOINTS_RAVEN
+};
+
+// Box Skeletal structures enums
+enum {
+       BOX_CENTER = 0,
+       NUM_JOINTS_BOX
+};
+
+extern int numJointsForSkeleton[];
+extern char *RAVEN_SKEL_NAMES[];
+
+#define J_NEW_SKELETON      0x00001000
+#define J_YAW_CHANGED       0x00002000
+#define J_PITCH_CHANGED     0x00004000
+#define J_ROLL_CHANGED      0x00008000
+#define MAX_JOINTS          0x00000fff
+/*
+   inline int GetFreeNode(ArrayedListNode_t *nodeArray, int max)
+   {   // yeah, I know this is a sucky, inefficient way to do this, but I didn't feel like taking the time to write a real resource manager in C
+    int i;
+
+    for(i = 0; i < max; ++i)
+    {
+        if(!nodeArray[i].inUse)
+        {
+            nodeArray[i].inUse = 1;
+            return i;
+        }
+    }
+
+    assert(0);
+    return -1;
+   }
+
+   inline void FreeNode(ArrayedListNode_t *nodeArray, int index)
+   {
+    nodeArray[index].inUse = 0;
+   }
+ */
+int CreateSkeleton( int structure );
+void CreateSkeletonAtIndex( int structure, int index );
+void FreeSkeleton( int structure, int index );
+void SetJointAngle( int jointIndex, int angleIndex, float angle );
+float ModifyJointAngle( int jointIndex, int angleIndex, float deltaAngle );
+int ZeroJointAngle( int jointIndex, int angleIndex, float angVel );
+int ApplyAngVelToJoint( int jointIndex, int angleIndex, float angVel, float destAng );
+
+#endif
diff --git a/tools/heretic2/h2data/models.c b/tools/heretic2/h2data/models.c
new file mode 100644 (file)
index 0000000..244f24a
--- /dev/null
@@ -0,0 +1,2041 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include "qdata.h"
+#include <assert.h>
+#include "jointed.h"
+#include "fmodel.h"
+
+//=================================================================
+
+typedef struct
+{
+       int numnormals;
+       vec3_t normalsum;
+} vertexnormals_t;
+
+typedef struct
+{
+       vec3_t v;
+       int lightnormalindex;
+} trivert_t;
+
+typedef struct
+{
+       vec3_t mins, maxs;
+       char name[16];
+       trivert_t v[MAX_VERTS];
+       QDataJoint_t joints[NUM_CLUSTERS];    // ,this
+} frame_t;
+
+// ,and all of this should get out of here, need to use new stuff in fmodels instead
+
+typedef struct IntListNode_s
+{
+       int data;
+       struct IntListNode_s *next;
+} IntListNode_t;  // gaak
+
+typedef struct
+{
+       float scale[3];         // multiply byte verts by this
+       float translate[3];         // then add this
+} PartialAliasFrame_t;
+
+int jointed;
+int clustered;
+
+int *clusters[NUM_CLUSTERS];
+IntListNode_t *vertLists[NUM_CLUSTERS];
+int num_verts[NUM_CLUSTERS + 1];
+int new_num_verts[NUM_CLUSTERS + 1];
+
+// end that
+
+//================================================================
+
+frame_t g_frames[MAX_FRAMES];
+//frame_t              *g_frames;
+
+static dmdl_t model;
+
+
+float scale_up;                 // set by $scale
+vec3_t adjust;                  // set by $origin
+int g_fixedwidth, g_fixedheight;            // set by $skinsize
+
+
+//
+// base frame info
+//
+dstvert_t base_st[MAX_VERTS];
+dtriangle_t triangles[MAX_TRIANGLES];
+
+static int triangle_st[MAX_TRIANGLES][3][2];
+
+// the command list holds counts, s/t values, and xyz indexes
+// that are valid for every frame
+int commands[16384];
+int numcommands;
+int numglverts;
+int used[MAX_TRIANGLES];
+
+char g_skins[MAX_MD2SKINS][64];
+
+char cdarchive[1024];
+char cdpartial[1024];
+char cddir[1024];
+
+char modelname[64];         // empty unless $modelname issued (players)
+
+extern char        *g_outputDir;
+
+#define NUMVERTEXNORMALS    162
+
+float avertexnormals[NUMVERTEXNORMALS][3] =
+{
+       #include "anorms.h"
+};
+
+unsigned char pic[SKINPAGE_HEIGHT * SKINPAGE_WIDTH], pic_palette[768];
+
+FILE    *headerouthandle = NULL;
+
+//==============================================================
+
+/*
+   ===============
+   ClearModel
+   ===============
+ */
+static void ClearModel( void ){
+       memset( &model, 0, sizeof( model ) );
+
+       modelname[0] = 0;
+       jointed = NOT_JOINTED;
+       clustered = 0;
+       scale_up = 1.0;
+       VectorCopy( vec3_origin, adjust );
+       g_fixedwidth = g_fixedheight = 0;
+       g_skipmodel = false;
+}
+
+
+void H_printf( char *fmt, ... ){
+       va_list argptr;
+       char name[1024];
+
+       if ( !headerouthandle ) {
+               sprintf( name, "%s/tris.h", cddir );
+               headerouthandle = SafeOpenWrite( name );
+               fprintf( headerouthandle, "// %s\n\n", cddir );
+               fprintf( headerouthandle, "// This file generated by qdata - Do NOT Modify\n\n" );
+       }
+
+       va_start( argptr, fmt );
+       vfprintf( headerouthandle, fmt, argptr );
+       va_end( argptr );
+}
+
+#if 1
+/*
+   ============
+   WriteModelFile
+   ============
+ */
+void WriteCommonModelFile( FILE *modelouthandle, PartialAliasFrame_t *outFrames ){
+       int i;
+       dmdl_t modeltemp;
+       int j, k;
+       frame_t         *in;
+       daliasframe_t   *out;
+       byte buffer[MAX_VERTS * 4 + 128];
+       float v;
+       int c_on, c_off;
+
+       model.version = ALIAS_VERSION;
+       model.framesize = (int)&( (daliasframe_t *)0 )->verts[model.num_xyz];
+       model.num_glcmds = numcommands;
+       model.ofs_skins = sizeof( dmdl_t );
+       model.ofs_st = model.ofs_skins + model.num_skins * MAX_SKINNAME;
+       model.ofs_tris = model.ofs_st + model.num_st * sizeof( dstvert_t );
+       model.ofs_frames = model.ofs_tris + model.num_tris * sizeof( dtriangle_t );
+       model.ofs_glcmds = model.ofs_frames + model.num_frames * model.framesize;
+       model.ofs_end = model.ofs_glcmds + model.num_glcmds * sizeof( int );
+       //
+       // write out the model header
+       //
+       for ( i = 0 ; i < sizeof( dmdl_t ) / 4 ; i++ )
+               ( (int *)&modeltemp )[i] = LittleLong( ( (int *)&model )[i] );
+
+       SafeWrite( modelouthandle, &modeltemp, sizeof( modeltemp ) );
+
+       //
+       // write out the skin names
+       //
+       SafeWrite( modelouthandle, g_skins, model.num_skins * MAX_SKINNAME );
+
+       //
+       // write out the texture coordinates
+       //
+       c_on = c_off = 0;
+       for ( i = 0 ; i < model.num_st ; i++ )
+       {
+               base_st[i].s = LittleShort( base_st[i].s );
+               base_st[i].t = LittleShort( base_st[i].t );
+       }
+
+       SafeWrite( modelouthandle, base_st, model.num_st * sizeof( base_st[0] ) );
+
+       //
+       // write out the triangles
+       //
+       for ( i = 0 ; i < model.num_tris ; i++ )
+       {
+               int j;
+               dtriangle_t tri;
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       tri.index_xyz[j] = LittleShort( triangles[i].index_xyz[j] );
+                       tri.index_st[j] = LittleShort( triangles[i].index_st[j] );
+               }
+
+               SafeWrite( modelouthandle, &tri, sizeof( tri ) );
+       }
+
+       //
+       // write out the frames
+       //
+       for ( i = 0 ; i < model.num_frames ; i++ )
+       {
+               in = &g_frames[i];
+               out = (daliasframe_t *)buffer;
+
+               strcpy( out->name, in->name );
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       out->scale[j] = ( in->maxs[j] - in->mins[j] ) / 255;
+                       out->translate[j] = in->mins[j];
+
+                       if ( outFrames ) {
+                               outFrames[i].scale[j] = out->scale[j];
+                               outFrames[i].translate[j] = out->translate[j];
+                       }
+               }
+
+               for ( j = 0 ; j < model.num_xyz ; j++ )
+               {
+                       // all of these are byte values, so no need to deal with endianness
+                       out->verts[j].lightnormalindex = in->v[j].lightnormalindex;
+
+                       for ( k = 0 ; k < 3 ; k++ )
+                       {
+                               // scale to byte values & min/max check
+                               v = Q_rint( ( in->v[j].v[k] - out->translate[k] ) / out->scale[k] );
+
+                               // clamp, so rounding doesn't wrap from 255.6 to 0
+                               if ( v > 255.0 ) {
+                                       v = 255.0;
+                               }
+                               if ( v < 0 ) {
+                                       v = 0;
+                               }
+                               out->verts[j].v[k] = v;
+                       }
+               }
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       out->scale[j] = LittleFloat( out->scale[j] );
+                       out->translate[j] = LittleFloat( out->translate[j] );
+               }
+
+               SafeWrite( modelouthandle, out, model.framesize );
+       }
+
+       //
+       // write out glcmds
+       //
+       SafeWrite( modelouthandle, commands, numcommands * 4 );
+}
+
+/*
+   ============
+   WriteModelFile
+   ============
+ */
+void WriteModelFile( FILE *modelouthandle ){
+       model.ident = IDALIASHEADER;
+
+       WriteCommonModelFile( modelouthandle, NULL );
+}
+
+/*
+   ============
+   WriteJointedModelFile
+   ============
+ */
+void WriteJointedModelFile( FILE *modelouthandle ){
+       int i;
+       int j, k;
+       frame_t         *in;
+       float v;
+       IntListNode_t   *current, *toFree;
+       PartialAliasFrame_t outFrames[MAX_FRAMES];
+
+       model.ident = IDJOINTEDALIASHEADER;
+
+       WriteCommonModelFile( modelouthandle, outFrames );
+
+       // Skeletal Type
+       SafeWrite( modelouthandle, &jointed, sizeof( int ) );
+
+       // number of joints
+       SafeWrite( modelouthandle, &numJointsForSkeleton[jointed], sizeof( int ) );
+
+       // number of verts in each cluster
+       SafeWrite( modelouthandle, &new_num_verts[1], sizeof( int ) * numJointsForSkeleton[jointed] );
+
+       // cluster verts
+       for ( i = 0; i < new_num_verts[0]; ++i )
+       {
+               current = vertLists[i];
+               while ( current )
+               {
+                       SafeWrite( modelouthandle, &current->data, sizeof( int ) );
+                       toFree = current;
+                       current = current->next;
+                       free( toFree );  // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base
+               }
+       }
+
+       for ( i = 0 ; i < model.num_frames ; i++ )
+       {
+               in = &g_frames[i];
+
+               for ( j = 0 ; j < new_num_verts[0]; ++j )
+               {
+                       for ( k = 0 ; k < 3 ; k++ )
+                       {
+                               // scale to byte values & min/max check
+                               v = Q_rint( ( in->joints[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                               // clamp, so rounding doesn't wrap from 255.6 to 0
+                               if ( v > 255.0 ) {
+                                       v = 255.0;
+                               }
+
+                               if ( v < 0 ) {
+                                       v = 0;
+                               }
+
+                               // write out origin as a float (there's only a few per model, so it's not really
+                               // a size issue)
+                               SafeWrite( modelouthandle, &v, sizeof( float ) );
+                       }
+
+                       for ( k = 0 ; k < 3 ; k++ )
+                       {
+                               v = Q_rint( ( in->joints[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                               // clamp, so rounding doesn't wrap from 255.6 to 0
+                               if ( v > 255.0 ) {
+                                       v = 255.0;
+                               }
+
+                               if ( v < 0 ) {
+                                       v = 0;
+                               }
+
+                               // write out origin as a float (there's only a few per model, so it's not really
+                               // a size issue)
+                               SafeWrite( modelouthandle, &v, sizeof( float ) );
+                       }
+
+                       for ( k = 0 ; k < 3 ; k++ )
+                       {
+                               v = Q_rint( ( in->joints[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
+
+                               // clamp, so rounding doesn't wrap from 255.6 to 0
+                               if ( v > 255.0 ) {
+                                       v = 255.0;
+                               }
+
+                               if ( v < 0 ) {
+                                       v = 0;
+                               }
+
+                               // write out origin as a float (there's only a few per model, so it's not really
+                               // a size issue)
+                               SafeWrite( modelouthandle, &v, sizeof( float ) );
+                       }
+               }
+       }
+}
+#else
+/*
+   ============
+   WriteModelFile
+   ============
+ */
+static void WriteModelFile( FILE *modelouthandle ){
+       int i;
+       dmdl_t modeltemp;
+       int j, k;
+       frame_t         *in;
+       daliasframe_t   *out;
+       byte buffer[MAX_VERTS * 4 + 128];
+       float v;
+       int c_on, c_off;
+
+       model.ident = IDALIASHEADER;
+       model.version = ALIAS_VERSION;
+       model.framesize = (int)&( (daliasframe_t *)0 )->verts[model.num_xyz];
+       model.num_glcmds = numcommands;
+       model.ofs_skins = sizeof( dmdl_t );
+       model.ofs_st = model.ofs_skins + model.num_skins * MAX_SKINNAME;
+       model.ofs_tris = model.ofs_st + model.num_st * sizeof( dstvert_t );
+       model.ofs_frames = model.ofs_tris + model.num_tris * sizeof( dtriangle_t );
+       model.ofs_glcmds = model.ofs_frames + model.num_frames * model.framesize;
+       model.ofs_end = model.ofs_glcmds + model.num_glcmds * 4;
+
+       //
+       // write out the model header
+       //
+       for ( i = 0 ; i < sizeof( dmdl_t ) / 4 ; i++ )
+               ( (int *)&modeltemp )[i] = LittleLong( ( (int *)&model )[i] );
+
+       SafeWrite( modelouthandle, &modeltemp, sizeof( modeltemp ) );
+
+       //
+       // write out the skin names
+       //
+       SafeWrite( modelouthandle, g_skins, model.num_skins * MAX_SKINNAME );
+
+       //
+       // write out the texture coordinates
+       //
+       c_on = c_off = 0;
+       for ( i = 0 ; i < model.num_st ; i++ )
+       {
+               base_st[i].s = LittleShort( base_st[i].s );
+               base_st[i].t = LittleShort( base_st[i].t );
+       }
+
+       SafeWrite( modelouthandle, base_st, model.num_st * sizeof( base_st[0] ) );
+
+       //
+       // write out the triangles
+       //
+       for ( i = 0 ; i < model.num_tris ; i++ )
+       {
+               int j;
+               dtriangle_t tri;
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       tri.index_xyz[j] = LittleShort( triangles[i].index_xyz[j] );
+                       tri.index_st[j] = LittleShort( triangles[i].index_st[j] );
+               }
+
+               SafeWrite( modelouthandle, &tri, sizeof( tri ) );
+       }
+
+       //
+       // write out the frames
+       //
+       for ( i = 0 ; i < model.num_frames ; i++ )
+       {
+               in = &g_frames[i];
+               out = (daliasframe_t *)buffer;
+
+               strcpy( out->name, in->name );
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       out->scale[j] = ( in->maxs[j] - in->mins[j] ) / 255;
+                       out->translate[j] = in->mins[j];
+               }
+
+               for ( j = 0 ; j < model.num_xyz ; j++ )
+               {
+                       // all of these are byte values, so no need to deal with endianness
+                       out->verts[j].lightnormalindex = in->v[j].lightnormalindex;
+
+                       for ( k = 0 ; k < 3 ; k++ )
+                       {
+                               // scale to byte values & min/max check
+                               v = Q_rint( ( in->v[j].v[k] - out->translate[k] ) / out->scale[k] );
+
+                               // clamp, so rounding doesn't wrap from 255.6 to 0
+                               if ( v > 255.0 ) {
+                                       v = 255.0;
+                               }
+                               if ( v < 0 ) {
+                                       v = 0;
+                               }
+                               out->verts[j].v[k] = v;
+                       }
+               }
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       out->scale[j] = LittleFloat( out->scale[j] );
+                       out->translate[j] = LittleFloat( out->translate[j] );
+               }
+
+               SafeWrite( modelouthandle, out, model.framesize );
+       }
+
+       //
+       // write out glcmds
+       //
+       SafeWrite( modelouthandle, commands, numcommands * 4 );
+}
+#endif
+
+/*
+   ===============
+   FinishModel
+   ===============
+ */
+void FinishModel( void ){
+       FILE        *modelouthandle;
+       int i;
+       char name[1024];
+
+       if ( !model.num_frames ) {
+               return;
+       }
+
+//
+// copy to release directory tree if doing a release build
+//
+       if ( g_release ) {
+               if ( modelname[0] ) {
+                       sprintf( name, "%s", modelname );
+               }
+               else{
+                       sprintf( name, "%s/tris.md2", cdpartial );
+               }
+               ReleaseFile( name );
+
+               for ( i = 0 ; i < model.num_skins ; i++ )
+               {
+                       ReleaseFile( g_skins[i] );
+               }
+               model.num_frames = 0;
+               return;
+       }
+
+//
+// write the model output file
+//
+       if ( modelname[0] ) {
+               sprintf( name, "%s%s", g_outputDir, modelname );
+       }
+       else{
+               sprintf( name, "%s/tris.md2", g_outputDir );
+       }
+       printf( "saving to %s\n", name );
+       CreatePath( name );
+       modelouthandle = SafeOpenWrite( name );
+
+#if 1
+       if ( jointed != NOT_JOINTED ) {
+               WriteJointedModelFile( modelouthandle );
+       }
+       else
+#endif
+       WriteModelFile( modelouthandle );
+
+       printf( "%3dx%3d skin\n", model.skinwidth, model.skinheight );
+       printf( "First frame boundaries:\n" );
+       printf( "       minimum x: %3f\n", g_frames[0].mins[0] );
+       printf( "       maximum x: %3f\n", g_frames[0].maxs[0] );
+       printf( "       minimum y: %3f\n", g_frames[0].mins[1] );
+       printf( "       maximum y: %3f\n", g_frames[0].maxs[1] );
+       printf( "       minimum z: %3f\n", g_frames[0].mins[2] );
+       printf( "       maximum z: %3f\n", g_frames[0].maxs[2] );
+       printf( "%4d vertices\n", model.num_xyz );
+       printf( "%4d triangles\n", model.num_tris );
+       printf( "%4d frame\n", model.num_frames );
+       printf( "%4d glverts\n", numglverts );
+       printf( "%4d glcmd\n", model.num_glcmds );
+       printf( "%4d skins\n", model.num_skins );
+       printf( "file size: %d\n", (int)ftell( modelouthandle ) );
+       printf( "---------------------\n" );
+
+       fclose( modelouthandle );
+
+       // finish writing header file
+       H_printf( "\n" );
+
+       // scale_up is usefull to allow step distances to be adjusted
+       H_printf( "#define MODEL_SCALE\t\t%f\n", scale_up );
+
+       fclose( headerouthandle );
+       headerouthandle = NULL;
+}
+
+
+/*
+   =================================================================
+
+   ALIAS MODEL DISPLAY LIST GENERATION
+
+   =================================================================
+ */
+
+int strip_xyz[128];
+int strip_st[128];
+int strip_tris[128];
+int stripcount;
+
+/*
+   ================
+   StripLength
+   ================
+ */
+static int  StripLength( int starttri, int startv ){
+       int m1, m2;
+       int st1, st2;
+       int j;
+       dtriangle_t *last, *check;
+       int k;
+
+       used[starttri] = 2;
+
+       last = &triangles[starttri];
+
+       strip_xyz[0] = last->index_xyz[( startv ) % 3];
+       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
+       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
+       strip_st[0] = last->index_st[( startv ) % 3];
+       strip_st[1] = last->index_st[( startv + 1 ) % 3];
+       strip_st[2] = last->index_st[( startv + 2 ) % 3];
+
+       strip_tris[0] = starttri;
+       stripcount = 1;
+
+       m1 = last->index_xyz[( startv + 2 ) % 3];
+       st1 = last->index_st[( startv + 2 ) % 3];
+       m2 = last->index_xyz[( startv + 1 ) % 3];
+       st2 = last->index_st[( startv + 1 ) % 3];
+
+       // look for a matching triangle
+nexttri:
+       for ( j = starttri + 1, check = &triangles[starttri + 1]
+                 ; j < model.num_tris ; j++, check++ )
+       {
+               for ( k = 0 ; k < 3 ; k++ )
+               {
+                       if ( check->index_xyz[k] != m1 ) {
+                               continue;
+                       }
+                       if ( check->index_st[k] != st1 ) {
+                               continue;
+                       }
+                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
+                               continue;
+                       }
+                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
+                               continue;
+                       }
+
+                       // this is the next part of the fan
+
+                       // if we can't use this triangle, this tristrip is done
+                       if ( used[j] ) {
+                               goto done;
+                       }
+
+                       // the new edge
+                       if ( stripcount & 1 ) {
+                               m2 = check->index_xyz[ ( k + 2 ) % 3 ];
+                               st2 = check->index_st[ ( k + 2 ) % 3 ];
+                       }
+                       else
+                       {
+                               m1 = check->index_xyz[ ( k + 2 ) % 3 ];
+                               st1 = check->index_st[ ( k + 2 ) % 3 ];
+                       }
+
+                       strip_xyz[stripcount + 2] = check->index_xyz[ ( k + 2 ) % 3 ];
+                       strip_st[stripcount + 2] = check->index_st[ ( k + 2 ) % 3 ];
+                       strip_tris[stripcount] = j;
+                       stripcount++;
+
+                       used[j] = 2;
+                       goto nexttri;
+               }
+       }
+done:
+
+       // clear the temp used flags
+       for ( j = starttri + 1 ; j < model.num_tris ; j++ )
+               if ( used[j] == 2 ) {
+                       used[j] = 0;
+               }
+
+       return stripcount;
+}
+
+
+/*
+   ===========
+   FanLength
+   ===========
+ */
+static int  FanLength( int starttri, int startv ){
+       int m1, m2;
+       int st1, st2;
+       int j;
+       dtriangle_t *last, *check;
+       int k;
+
+       used[starttri] = 2;
+
+       last = &triangles[starttri];
+
+       strip_xyz[0] = last->index_xyz[( startv ) % 3];
+       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
+       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
+       strip_st[0] = last->index_st[( startv ) % 3];
+       strip_st[1] = last->index_st[( startv + 1 ) % 3];
+       strip_st[2] = last->index_st[( startv + 2 ) % 3];
+
+       strip_tris[0] = starttri;
+       stripcount = 1;
+
+       m1 = last->index_xyz[( startv + 0 ) % 3];
+       st1 = last->index_st[( startv + 0 ) % 3];
+       m2 = last->index_xyz[( startv + 2 ) % 3];
+       st2 = last->index_st[( startv + 2 ) % 3];
+
+
+       // look for a matching triangle
+nexttri:
+       for ( j = starttri + 1, check = &triangles[starttri + 1]
+                 ; j < model.num_tris ; j++, check++ )
+       {
+               for ( k = 0 ; k < 3 ; k++ )
+               {
+                       if ( check->index_xyz[k] != m1 ) {
+                               continue;
+                       }
+                       if ( check->index_st[k] != st1 ) {
+                               continue;
+                       }
+                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
+                               continue;
+                       }
+                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
+                               continue;
+                       }
+
+                       // this is the next part of the fan
+
+                       // if we can't use this triangle, this tristrip is done
+                       if ( used[j] ) {
+                               goto done;
+                       }
+
+                       // the new edge
+                       m2 = check->index_xyz[ ( k + 2 ) % 3 ];
+                       st2 = check->index_st[ ( k + 2 ) % 3 ];
+
+                       strip_xyz[stripcount + 2] = m2;
+                       strip_st[stripcount + 2] = st2;
+                       strip_tris[stripcount] = j;
+                       stripcount++;
+
+                       used[j] = 2;
+                       goto nexttri;
+               }
+       }
+done:
+
+       // clear the temp used flags
+       for ( j = starttri + 1 ; j < model.num_tris ; j++ )
+               if ( used[j] == 2 ) {
+                       used[j] = 0;
+               }
+
+       return stripcount;
+}
+
+
+
+/*
+   ================
+   BuildGlCmds
+
+   Generate a list of trifans or strips
+   for the model, which holds for all frames
+   ================
+ */
+static void BuildGlCmds( void ){
+       int i, j, k;
+       int startv;
+       float s, t;
+       int len, bestlen, besttype;
+       int best_xyz[1024];
+       int best_st[1024];
+       int best_tris[1024];
+       int type;
+
+       //
+       // build tristrips
+       //
+       numcommands = 0;
+       numglverts = 0;
+       memset( used, 0, sizeof( used ) );
+       for ( i = 0 ; i < model.num_tris ; i++ )
+       {
+               // pick an unused triangle and start the trifan
+               if ( used[i] ) {
+                       continue;
+               }
+
+               bestlen = 0;
+               for ( type = 0 ; type < 2 ; type++ )
+//     type = 1;
+               {
+                       for ( startv = 0 ; startv < 3 ; startv++ )
+                       {
+                               if ( type == 1 ) {
+                                       len = StripLength( i, startv );
+                               }
+                               else{
+                                       len = FanLength( i, startv );
+                               }
+                               if ( len > bestlen ) {
+                                       besttype = type;
+                                       bestlen = len;
+                                       for ( j = 0 ; j < bestlen + 2 ; j++ )
+                                       {
+                                               best_st[j] = strip_st[j];
+                                               best_xyz[j] = strip_xyz[j];
+                                       }
+                                       for ( j = 0 ; j < bestlen ; j++ )
+                                               best_tris[j] = strip_tris[j];
+                               }
+                       }
+               }
+
+               // mark the tris on the best strip/fan as used
+               for ( j = 0 ; j < bestlen ; j++ )
+                       used[best_tris[j]] = 1;
+
+               if ( besttype == 1 ) {
+                       commands[numcommands++] = ( bestlen + 2 );
+               }
+               else{
+                       commands[numcommands++] = -( bestlen + 2 );
+               }
+
+               numglverts += bestlen + 2;
+
+               for ( j = 0 ; j < bestlen + 2 ; j++ )
+               {
+                       // emit a vertex into the reorder buffer
+                       k = best_st[j];
+
+                       // emit s/t coords into the commands stream
+                       s = base_st[k].s;
+                       t = base_st[k].t;
+
+                       s = ( s + 0.5 ) / model.skinwidth;
+                       t = ( t + 0.5 ) / model.skinheight;
+
+                       *(float *)&commands[numcommands++] = s;
+                       *(float *)&commands[numcommands++] = t;
+                       *(int *)&commands[numcommands++] = best_xyz[j];
+               }
+       }
+
+       commands[numcommands++] = 0;        // end of list marker
+}
+
+
+/*
+   ===============================================================
+
+   BASE FRAME SETUP
+
+   ===============================================================
+ */
+
+/*
+   ============
+   BuildST
+
+   Builds the triangle_st array for the base frame and
+   model.skinwidth / model.skinheight
+
+   FIXME: allow this to be loaded from a file for
+   arbitrary mappings
+   ============
+ */
+#if 0
+static void OldBuildST( triangle_t *ptri, int numtri ){
+       int i, j;
+       int width, height, iwidth, iheight, swidth;
+       float basex, basey;
+       float s_scale, t_scale;
+       float scale;
+       vec3_t mins, maxs;
+       float       *pbasevert;
+       vec3_t vtemp1, vtemp2, normal;
+
+       //
+       // find bounds of all the verts on the base frame
+       //
+       ClearBounds( mins, maxs );
+
+       for ( i = 0 ; i < numtri ; i++ )
+               for ( j = 0 ; j < 3 ; j++ )
+                       AddPointToBounds( ptri[i].verts[j], mins, maxs );
+
+       for ( i = 0 ; i < 3 ; i++ )
+       {
+               mins[i] = floor( mins[i] );
+               maxs[i] = ceil( maxs[i] );
+       }
+
+       width = maxs[0] - mins[0];
+       height = maxs[2] - mins[2];
+
+       if ( !g_fixedwidth ) { // old style
+               scale = 8;
+               if ( width * scale >= 150 ) {
+                       scale = 150.0 / width;
+               }
+               if ( height * scale >= 190 ) {
+                       scale = 190.0 / height;
+               }
+
+               s_scale = t_scale = scale;
+
+               iwidth = ceil( width * s_scale );
+               iheight = ceil( height * t_scale );
+
+               iwidth += 4;
+               iheight += 4;
+       }
+       else
+       {   // new style
+               iwidth = g_fixedwidth / 2;
+               iheight = g_fixedheight;
+
+               s_scale = (float)( iwidth - 4 ) / width;
+               t_scale = (float)( iheight - 4 ) / height;
+       }
+
+//
+// determine which side of each triangle to map the texture to
+//
+       for ( i = 0 ; i < numtri ; i++ )
+       {
+               VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
+               VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
+               CrossProduct( vtemp1, vtemp2, normal );
+
+               if ( normal[1] > 0 ) {
+                       basex = iwidth + 2;
+               }
+               else
+               {
+                       basex = 2;
+               }
+               basey = 2;
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       pbasevert = ptri[i].verts[j];
+
+                       triangle_st[i][j][0] = Q_rint( ( pbasevert[0] - mins[0] ) * s_scale + basex );
+                       triangle_st[i][j][1] = Q_rint( ( maxs[2] - pbasevert[2] ) * t_scale + basey );
+               }
+       }
+
+// make the width a multiple of 4; some hardware requires this, and it ensures
+// dword alignment for each scan
+       swidth = iwidth * 2;
+       model.skinwidth = ( swidth + 3 ) & ~3;
+       model.skinheight = iheight;
+}
+#endif
+
+//==========================================================================
+//
+// DrawScreen
+//
+//==========================================================================
+
+void DrawScreen( float s_scale, float t_scale, float iwidth, float iheight ){
+       int i;
+       byte *scrpos;
+       char buffer[256];
+
+       // Divider
+       scrpos = &pic[( INFO_Y - 2 ) * SKINPAGE_WIDTH];
+       for ( i = 0; i < SKINPAGE_WIDTH; i++ )
+       {
+               *scrpos++ = 255;
+       }
+
+       sprintf( buffer, "GENSKIN:  " );
+       DrawTextChar( 16, INFO_Y, buffer );
+
+       sprintf( buffer, "( %03d * %03d )   SCALE %f %f, SKINWIDTH %d,"
+                                        " SKINHEIGHT %d", (int)ScaleWidth, (int)ScaleHeight, s_scale, t_scale, (int)iwidth * 2, (int)iheight );
+       DrawTextChar( 80, INFO_Y, buffer );
+}
+
+/*
+   ============
+   BuildST
+
+   Builds the triangle_st array for the base frame and
+   model.skinwidth / model.skinheight
+
+   FIXME: allow this to be loaded from a file for
+   arbitrary mappings
+   ============
+ */
+void BuildST( triangle_t *ptri, int numtri, qboolean DrawSkin ){
+       int i, j;
+       int width, height, iwidth, iheight, swidth;
+       float basex, basey;
+       float scale;
+       vec3_t mins, maxs;
+       float       *pbasevert;
+       vec3_t vtemp1, vtemp2, normal;
+       float s_scale, t_scale;
+       float scWidth;
+       float scHeight;
+
+       //
+       // find bounds of all the verts on the base frame
+       //
+       ClearBounds( mins, maxs );
+
+       for ( i = 0 ; i < numtri ; i++ )
+               for ( j = 0 ; j < 3 ; j++ )
+                       AddPointToBounds( ptri[i].verts[j], mins, maxs );
+
+       for ( i = 0 ; i < 3 ; i++ )
+       {
+               mins[i] = floor( mins[i] );
+               maxs[i] = ceil( maxs[i] );
+       }
+
+       width = maxs[0] - mins[0];
+       height = maxs[2] - mins[2];
+
+
+       scWidth = ( ScaleWidth / 2 ) * SCALE_ADJUST_FACTOR;
+       scHeight = ScaleHeight * SCALE_ADJUST_FACTOR;
+
+       scale = scWidth / width;
+
+       if ( height * scale >= scHeight ) {
+               scale = scHeight / height;
+       }
+
+       iwidth = ceil( width * scale ) + 4;
+       iheight = ceil( height * scale ) + 4;
+
+       s_scale = (float)( iwidth - 4 ) / width;
+       t_scale = (float)( iheight - 4 ) / height;
+       t_scale = s_scale;
+
+       if ( DrawSkin ) {
+               DrawScreen( s_scale, t_scale, iwidth, iheight );
+       }
+
+
+/*     if (!g_fixedwidth)
+    {  // old style
+        scale = 8;
+        if (width*scale >= 150)
+            scale = 150.0 / width;
+        if (height*scale >= 190)
+            scale = 190.0 / height;
+
+        s_scale = t_scale = scale;
+
+        iwidth = ceil(width*s_scale);
+        iheight = ceil(height*t_scale);
+
+        iwidth += 4;
+        iheight += 4;
+    }
+    else
+    {  // new style
+        iwidth = g_fixedwidth / 2;
+        iheight = g_fixedheight;
+
+        s_scale = (float)(iwidth-4) / width;
+        t_scale = (float)(iheight-4) / height;
+    }*/
+
+//
+// determine which side of each triangle to map the texture to
+//
+       for ( i = 0 ; i < numtri ; i++ )
+       {
+               if ( ptri[i].HasUV ) {
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               triangle_st[i][j][0] = Q_rint( ptri[i].uv[j][0] * iwidth );
+                               triangle_st[i][j][1] = Q_rint( ( 1.0f - ptri[i].uv[j][1] ) * iheight );
+                       }
+               }
+               else
+               {
+                       VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
+                       VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
+                       CrossProduct( vtemp1, vtemp2, normal );
+
+                       if ( normal[1] > 0 ) {
+                               basex = iwidth + 2;
+                       }
+                       else
+                       {
+                               basex = 2;
+                       }
+                       basey = 2;
+
+                       for ( j = 0 ; j < 3 ; j++ )
+                       {
+                               pbasevert = ptri[i].verts[j];
+
+                               triangle_st[i][j][0] = Q_rint( ( pbasevert[0] - mins[0] ) * s_scale + basex );
+                               triangle_st[i][j][1] = Q_rint( ( maxs[2] - pbasevert[2] ) * t_scale + basey );
+                       }
+               }
+
+               DrawLine( triangle_st[i][0][0], triangle_st[i][0][1],
+                                 triangle_st[i][1][0], triangle_st[i][1][1] );
+               DrawLine( triangle_st[i][1][0], triangle_st[i][1][1],
+                                 triangle_st[i][2][0], triangle_st[i][2][1] );
+               DrawLine( triangle_st[i][2][0], triangle_st[i][2][1],
+                                 triangle_st[i][0][0], triangle_st[i][0][1] );
+       }
+
+// make the width a multiple of 4; some hardware requires this, and it ensures
+// dword alignment for each scan
+
+       swidth = iwidth * 2;
+       model.skinwidth = ( swidth + 3 ) & ~3;
+       model.skinheight = iheight;
+}
+
+
+static void ReplaceClusterIndex( int newIndex, int oldindex, int **clusters,
+                                                                IntListNode_t **vertLists, int *num_verts, int *new_num_verts ){
+       int i, j;
+       IntListNode_t *next;
+
+       for ( j = 0; j < num_verts[0]; ++j )
+       {
+               for ( i = 0; i < num_verts[j + 1]; ++i )
+               {
+                       if ( clusters[j][i] == oldindex ) {
+                               ++new_num_verts[j + 1];
+
+                               next = vertLists[j];
+
+                               vertLists[j] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "ReplaceClusterIndex" );
+                               // Currently freed in WriteJointedModelFile only
+
+                               vertLists[j]->data = newIndex;
+                               vertLists[j]->next = next;
+                       }
+               }
+       }
+}
+
+/*
+   =================
+   Cmd_Base
+   =================
+ */
+void Cmd_Base( void ){
+       vec3_t base_xyz[MAX_VERTS];
+       triangle_t  *ptri;
+       int i, j, k;
+#if 1
+#else
+       int time1;
+#endif
+       char file1[1024];
+       char file2[1024];
+
+       GetScriptToken( false );
+
+       if ( g_skipmodel || g_release || g_archive ) {
+               return;
+       }
+
+       printf( "---------------------\n" );
+#if 1
+       sprintf( file1, "%s/%s", cdpartial, token );
+       printf( "%s  ", file1 );
+
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s", cddir, token );
+#else
+       sprintf( file1, "%s/%s.%s", cdarchive, token, trifileext );
+       printf( "%s\n", file1 );
+
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s.%s", cddir, token, trifileext );
+
+       time1 = FileTime( file1 );
+       if ( time1 == -1 ) {
+               Error( "%s doesn't exist", file1 );
+       }
+#endif
+//
+// load the base triangles
+//
+       if ( do3ds ) {
+               Load3DSTriangleList( file1, &ptri, &model.num_tris, NULL, NULL );
+       }
+       else{
+               LoadTriangleList( file1, &ptri, &model.num_tris, NULL, NULL );
+       }
+
+
+       GetScriptToken( false );
+       sprintf( file2, "%s/%s.pcx", cddir, token );
+//     sprintf (trans_file, "%s/!%s_a.pcx", cddir, token);
+
+       printf( "skin: %s\n", file2 );
+       Load256Image( file2, &BasePixels, &BasePalette, &BaseWidth, &BaseHeight );
+
+       if ( BaseWidth != SKINPAGE_WIDTH || BaseHeight != SKINPAGE_HEIGHT ) {
+               if ( g_allow_newskin ) {
+                       ScaleWidth = BaseWidth;
+                       ScaleHeight = BaseHeight;
+               }
+               else
+               {
+                       Error( "Invalid skin page size: (%d,%d) should be (%d,%d)",
+                                  BaseWidth,BaseHeight,SKINPAGE_WIDTH,SKINPAGE_HEIGHT );
+               }
+       }
+       else
+       {
+               ScaleWidth = (float)ExtractNumber( BasePixels, ENCODED_WIDTH_X,
+                                                                                  ENCODED_WIDTH_Y );
+               ScaleHeight = (float)ExtractNumber( BasePixels, ENCODED_HEIGHT_X,
+                                                                                       ENCODED_HEIGHT_Y );
+       }
+
+//
+// get the ST values
+//
+       BuildST( ptri, model.num_tris,false );
+
+//
+// run through all the base triangles, storing each unique vertex in the
+// base vertex list and setting the indirect triangles to point to the base
+// vertices
+//
+       for ( i = 0 ; i < model.num_tris ; i++ )
+       {
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       // get the xyz index
+                       for ( k = 0 ; k < model.num_xyz ; k++ )
+                               if ( VectorCompare( ptri[i].verts[j], base_xyz[k] ) ) {
+                                       break;
+                               }           // this vertex is already in the base vertex list
+
+                       if ( k == model.num_xyz ) { // new index
+                               VectorCopy( ptri[i].verts[j], base_xyz[model.num_xyz] );
+
+                               if ( clustered ) {
+                                       ReplaceClusterIndex( k, ptri[i].indicies[j], (int **)&clusters, (IntListNode_t **)&vertLists, (int *)&num_verts, (int *)&new_num_verts );
+                               }
+
+                               model.num_xyz++;
+                       }
+
+                       triangles[i].index_xyz[j] = k;
+
+                       // get the st index
+                       for ( k = 0 ; k < model.num_st ; k++ )
+                               if ( triangle_st[i][j][0] == base_st[k].s
+                                        && triangle_st[i][j][1] == base_st[k].t ) {
+                                       break;
+                               }           // this vertex is already in the base vertex list
+
+                       if ( k == model.num_st ) { // new index
+                               base_st[model.num_st].s = triangle_st[i][j][0];
+                               base_st[model.num_st].t = triangle_st[i][j][1];
+                               model.num_st++;
+                       }
+
+                       triangles[i].index_st[j] = k;
+               }
+       }
+
+       // build triangle strips / fans
+       BuildGlCmds();
+}
+
+//===============================================================
+
+char    *FindFrameFile( char *frame ){
+       int time1;
+       char file1[1024];
+       static char retname[1024];
+       char base[32];
+       char suffix[32];
+       char            *s;
+
+       if ( strstr( frame, "." ) ) {
+               return frame;       // allready in dot format
+
+       }
+       // split 'run1' into 'run' and '1'
+       s = frame + strlen( frame ) - 1;
+
+       while ( s != frame && *s >= '0' && *s <= '9' )
+               s--;
+
+       strcpy( suffix, s + 1 );
+       strcpy( base, frame );
+       base[s - frame + 1] = 0;
+
+       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "hrc" );
+       time1 = FileTime( file1 );
+       if ( time1 != -1 ) {
+               sprintf( retname, "%s%s.%s", base, suffix, "hrc" );
+               return retname;
+       }
+
+       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "asc" );
+       time1 = FileTime( file1 );
+       if ( time1 != -1 ) {
+               sprintf( retname, "%s%s.%s", base, suffix, "asc" );
+               return retname;
+       }
+
+       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "tri" );
+       time1 = FileTime( file1 );
+       if ( time1 != -1 ) {
+               sprintf( retname, "%s%s.%s", base, suffix, "tri" );
+               return retname;
+       }
+
+       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "3ds" );
+       time1 = FileTime( file1 );
+       if ( time1 != -1 ) {
+               sprintf( retname, "%s%s.%s", base, suffix, "3ds" );
+               return retname;
+       }
+
+       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "htr" );
+       time1 = FileTime( file1 );
+       if ( time1 != -1 ) {
+               sprintf( retname, "%s%s.%s", base, suffix, "htr" );
+               return retname;
+       }
+
+       // check for 'run.1'
+       sprintf( file1, "%s/%s.%s",cddir, base, suffix );
+       time1 = FileTime( file1 );
+       if ( time1 != -1 ) {
+               sprintf( retname, "%s.%s", base, suffix );
+               return retname;
+       }
+
+       Error( "frame %s could not be found",frame );
+       return NULL;
+}
+
+/*
+   ===============
+   GrabFrame
+   ===============
+ */
+static void GrabFrame( char *frame ){
+       triangle_t      *ptri;
+       int i, j;
+       trivert_t       *ptrivert;
+       int num_tris;
+       char file1[1024];
+       frame_t         *fr;
+       vertexnormals_t vnorms[MAX_VERTS];
+       int index_xyz;
+       char            *framefile;
+
+       // the frame 'run1' will be looked for as either
+       // run.1 or run1.tri, so the new alias sequence save
+       // feature an be used
+       framefile = FindFrameFile( frame );
+
+       sprintf( file1, "%s/%s", cdarchive, framefile );
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s",cddir, framefile );
+
+       printf( "grabbing %s  ", file1 );
+
+       if ( model.num_frames >= MAX_FRAMES ) {
+               Error( "model.num_frames >= MAX_FRAMES" );
+       }
+       fr = &g_frames[model.num_frames];
+       model.num_frames++;
+
+       strcpy( fr->name, frame );
+
+//
+// load the frame
+//
+       if ( do3ds ) {
+               Load3DSTriangleList( file1, &ptri, &num_tris, NULL, NULL );
+       }
+       else{
+               LoadTriangleList( file1, &ptri, &num_tris, NULL, NULL );
+       }
+
+       if ( num_tris != model.num_tris ) {
+               Error( "%s: number of triangles doesn't match base frame\n", file1 );
+       }
+
+//
+// allocate storage for the frame's vertices
+//
+       ptrivert = fr->v;
+
+       for ( i = 0 ; i < model.num_xyz ; i++ )
+       {
+               vnorms[i].numnormals = 0;
+               VectorClear( vnorms[i].normalsum );
+       }
+       ClearBounds( fr->mins, fr->maxs );
+
+//
+// store the frame's vertices in the same order as the base. This assumes the
+// triangles and vertices in this frame are in exactly the same order as in the
+// base
+//
+       for ( i = 0 ; i < num_tris ; i++ )
+       {
+               vec3_t vtemp1, vtemp2, normal;
+               float ftemp;
+
+               VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
+               VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
+               CrossProduct( vtemp1, vtemp2, normal );
+
+               VectorNormalize( normal, normal );
+
+               // rotate the normal so the model faces down the positive x axis
+               ftemp = normal[0];
+               normal[0] = -normal[1];
+               normal[1] = ftemp;
+
+               for ( j = 0 ; j < 3 ; j++ )
+               {
+                       index_xyz = triangles[i].index_xyz[j];
+
+                       // rotate the vertices so the model faces down the positive x axis
+                       // also adjust the vertices to the desired origin
+                       ptrivert[index_xyz].v[0] = ( ( -ptri[i].verts[j][1] ) * scale_up ) +
+                                                                          adjust[0];
+                       ptrivert[index_xyz].v[1] = ( ptri[i].verts[j][0] * scale_up ) +
+                                                                          adjust[1];
+                       ptrivert[index_xyz].v[2] = ( ptri[i].verts[j][2] * scale_up ) +
+                                                                          adjust[2];
+
+                       AddPointToBounds( ptrivert[index_xyz].v, fr->mins, fr->maxs );
+
+                       VectorAdd( vnorms[index_xyz].normalsum, normal, vnorms[index_xyz].normalsum );
+                       vnorms[index_xyz].numnormals++;
+               }
+       }
+
+//
+// calculate the vertex normals, match them to the template list, and store the
+// index of the best match
+//
+       for ( i = 0 ; i < model.num_xyz ; i++ )
+       {
+               int j;
+               vec3_t v;
+               float maxdot;
+               int maxdotindex;
+               int c;
+
+               c = vnorms[i].numnormals;
+               if ( !c ) {
+                       Error( "Vertex with no triangles attached" );
+               }
+
+               VectorScale( vnorms[i].normalsum, 1.0 / c, v );
+               VectorNormalize( v, v );
+
+               maxdot = -999999.0;
+               maxdotindex = -1;
+
+               for ( j = 0 ; j < NUMVERTEXNORMALS ; j++ )
+               {
+                       float dot;
+
+                       dot = DotProduct( v, avertexnormals[j] );
+                       if ( dot > maxdot ) {
+                               maxdot = dot;
+                               maxdotindex = j;
+                       }
+               }
+
+               ptrivert[i].lightnormalindex = maxdotindex;
+       }
+
+       free( ptri );
+}
+
+/*
+   ===============
+   GrabJointedFrame
+   ===============
+ */
+void GrabJointedFrame( char *frame ){
+       char file1[1024];
+       char    *framefile;
+       frame_t     *fr;
+
+       framefile = FindFrameFile( frame );
+
+       sprintf( file1, "%s/%s", cdarchive, framefile );
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s",cddir, framefile );
+
+       printf( "grabbing %s\n", file1 );
+
+       fr = &g_frames[model.num_frames - 1]; // last frame read in
+
+       LoadJointList( file1, fr->joints, jointed );
+}
+
+/*
+   ===============
+   GrabGlobals
+   ===============
+ */
+void GrabGlobals( char *frame ){
+       char file1[1024];
+       char    *framefile;
+       frame_t     *fr;
+
+       framefile = FindFrameFile( frame );
+
+       sprintf( file1, "%s/%s", cdarchive, framefile );
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s",cddir, framefile );
+
+       printf( "grabbing %s\n", file1 );
+
+       fr = &g_frames[model.num_frames - 1]; // last frame read in
+
+       LoadGlobals( file1 );
+}
+
+/*
+   ===============
+   Cmd_Frame
+   ===============
+ */
+void Cmd_Frame( void ){
+       while ( ScriptTokenAvailable() )
+       {
+               GetScriptToken( false );
+               if ( g_skipmodel ) {
+                       continue;
+               }
+               if ( g_release || g_archive ) {
+                       model.num_frames = 1;   // don't skip the writeout
+                       continue;
+               }
+
+               H_printf( "#define FRAME_%-16s\t%i\n", token, model.num_frames );
+
+               GrabFrame( token );
+       }
+}
+
+/*
+   ===============
+   Cmd_Skin
+
+   Skins aren't actually stored in the file, only a reference
+   is saved out to the header file.
+   ===============
+ */
+void Cmd_Skin( void ){
+       byte    *palette;
+       byte    *pixels;
+       int width, height;
+       byte    *cropped;
+       int y;
+       char name[1024], savename[1024];
+
+       GetScriptToken( false );
+
+       if ( model.num_skins == MAX_MD2SKINS ) {
+               Error( "model.num_skins == MAX_MD2SKINS" );
+       }
+
+       if ( g_skipmodel ) {
+               return;
+       }
+
+#if 1
+       sprintf( name, "%s/%s.pcx", cddir, token );
+       sprintf( savename, "%s/!%s.pcx", g_outputDir, token );
+       sprintf( g_skins[model.num_skins], "%s/!%s.pcx", cdpartial, token );
+#else
+       sprintf( name, "%s/%s.lbm", cdarchive, token );
+       strcpy( name, ExpandPathAndArchive( name ) );
+//     sprintf (name, "%s/%s.lbm", cddir, token);
+
+       if ( ScriptTokenAvailable() ) {
+               GetScriptToken( false );
+               sprintf( g_skins[model.num_skins], "%s.pcx", token );
+               sprintf( savename, "%s%s.pcx", g_outputDir, g_skins[model.num_skins] );
+       }
+       else
+       {
+               sprintf( savename, "%s/%s.pcx", g_outputDir, token );
+               sprintf( g_skins[model.num_skins], "%s/%s.pcx", cdpartial, token );
+       }
+#endif
+
+       model.num_skins++;
+
+       if ( g_skipmodel || g_release || g_archive ) {
+               return;
+       }
+
+       // load the image
+       printf( "loading %s\n", name );
+       Load256Image( name, &pixels, &palette, &width, &height );
+//     RemapZero (pixels, palette, width, height);
+
+       // crop it to the proper size
+       cropped = (byte *) SafeMalloc( model.skinwidth * model.skinheight, "Cmd_Skin" );
+       for ( y = 0 ; y < model.skinheight ; y++ )
+       {
+               memcpy( cropped + y * model.skinwidth,
+                               pixels + y * width, model.skinwidth );
+       }
+
+       // save off the new image
+       printf( "saving %s\n", savename );
+       CreatePath( savename );
+       WritePCXfile( savename, cropped, model.skinwidth,
+                                 model.skinheight, palette );
+
+       free( pixels );
+       free( palette );
+       free( cropped );
+}
+
+
+/*
+   =================
+   Cmd_Origin
+   =================
+ */
+void Cmd_Origin( void ){
+       // rotate points into frame of reference so model points down the
+       // positive x axis
+       GetScriptToken( false );
+       adjust[1] = -atof( token );
+
+       GetScriptToken( false );
+       adjust[0] = atof( token );
+
+       GetScriptToken( false );
+       adjust[2] = -atof( token );
+}
+
+
+/*
+   =================
+   Cmd_ScaleUp
+   =================
+ */
+void Cmd_ScaleUp( void ){
+       GetScriptToken( false );
+       scale_up = atof( token );
+       if ( g_skipmodel || g_release || g_archive ) {
+               return;
+       }
+
+       printf( "Scale up: %f\n", scale_up );
+}
+
+
+/*
+   =================
+   Cmd_Skinsize
+
+   Set a skin size other than the default
+   =================
+ */
+void Cmd_Skinsize( void ){
+       GetScriptToken( false );
+       g_fixedwidth = atoi( token );
+       GetScriptToken( false );
+       g_fixedheight = atoi( token );
+}
+
+/*
+   =================
+   Cmd_Modelname
+
+   Gives a different name/location for the file, instead of the cddir
+   =================
+ */
+void Cmd_Modelname( void ){
+       GetScriptToken( false );
+       strcpy( modelname, token );
+}
+
+/*
+   ===============
+   Cmd_Cd
+   ===============
+ */
+void Cmd_Cd( void ){
+       char temp[256];
+
+       FinishModel();
+       ClearModel();
+
+       GetScriptToken( false );
+
+       // this is a silly mess...
+       sprintf( cdpartial, "models/%s", token );
+       sprintf( cdarchive, "%smodels/%s", gamedir + strlen( qdir ), token );
+       sprintf( cddir, "%s%s", gamedir, cdpartial );
+
+       // Since we also changed directories on the output side (for mirror) make sure the outputdir is set properly too.
+       sprintf( temp, "%s%s", g_outputDir, cdpartial );
+       strcpy( g_outputDir, temp );
+
+       // if -only was specified and this cd doesn't match,
+       // skip the model (you only need to match leading chars,
+       // so you could regrab all monsters with -only monsters)
+       if ( !g_only[0] ) {
+               return;
+       }
+       if ( strncmp( token, g_only, strlen( g_only ) ) ) {
+               g_skipmodel = true;
+               printf( "skipping %s\n", cdpartial );
+       }
+}
+
+/*
+   =================
+   Cmd_Cluster
+   =================
+ */
+void Cmd_Cluster(){
+       char file1[1024];
+
+       GetScriptToken( false );
+
+       printf( "---------------------\n" );
+       sprintf( file1, "%s/%s", cdpartial, token );
+       printf( "%s\n", file1 );
+
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s", cddir, token );
+
+       LoadClusters( file1, (int **)&clusters, (int *)&num_verts, jointed );
+
+       new_num_verts[0] = num_verts[0];
+
+       clustered = 1;
+}
+
+// Model construction cover functions.
+void MODELCMD_Modelname( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       Cmd_Modelname();
+/*
+    switch(modeltype)
+    {
+    case MODEL_MD2:
+        Cmd_Modelname ();
+        break;
+    case MODEL_FM:
+        Cmd_FMModelname ();
+        break;
+    }
+ */
+}
+
+void MODELCMD_Cd( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               Cmd_Cd();
+               break;
+       case MODEL_FM:
+               Cmd_FMCd();
+               break;
+       }
+}
+
+void MODELCMD_Origin( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       Cmd_Origin();
+/*     switch(modeltype)
+    {
+    case MODEL_MD2:
+        Cmd_Origin ();
+        break;
+    case MODEL_FM:
+        Cmd_FMOrigin ();
+        break;
+    }
+ */
+}
+
+void MODELCMD_Cluster( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               Cmd_Cluster();
+               break;
+       case MODEL_FM:
+               Cmd_FMCluster();
+               break;
+       }
+}
+
+void MODELCMD_Base( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               Cmd_Base();
+               break;
+       case MODEL_FM:
+               Cmd_FMBase( false );
+               break;
+       }
+}
+
+void MODELCMD_BaseST( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               Cmd_Base();
+               break;
+       case MODEL_FM:
+               Cmd_FMBase( true );
+               break;
+       }
+}
+
+void MODELCMD_ScaleUp( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       Cmd_ScaleUp();
+/*     switch(modeltype)
+    {
+    case MODEL_MD2:
+        Cmd_ScaleUp ();
+        break;
+    case MODEL_FM:
+        Cmd_FMScaleUp ();
+        break;
+    }
+ */
+}
+
+void MODELCMD_Frame( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               Cmd_Frame();
+               break;
+       case MODEL_FM:
+               Cmd_FMFrame();
+               break;
+       }
+}
+
+void MODELCMD_Skin( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               Cmd_Skin();
+               break;
+       case MODEL_FM:
+               Cmd_FMSkin();
+               break;
+       }
+}
+
+void MODELCMD_Skinsize( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       Cmd_Skinsize();
+/*
+    switch(modeltype)
+    {
+    case MODEL_MD2:
+        Cmd_Skinsize ();
+        break;
+    case MODEL_FM:
+        Cmd_FMSkinsize ();
+        break;
+    }
+ */
+}
+
+void MODELCMD_Skeleton( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               break;
+       case MODEL_FM:
+               Cmd_FMSkeleton();
+               break;
+       }
+}
+
+void MODELCMD_BeginGroup( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               break;
+       case MODEL_FM:
+               Cmd_FMBeginGroup();
+               break;
+       }
+}
+
+void MODELCMD_EndGroup( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               break;
+       case MODEL_FM:
+               Cmd_FMEndGroup();
+               break;
+       }
+}
+
+void MODELCMD_Referenced( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               break;
+       case MODEL_FM:
+               Cmd_FMReferenced();
+               break;
+       }
+}
+
+void MODELCMD_NodeOrder( int modeltype ){
+       if ( g_forcemodel ) {
+               modeltype = g_forcemodel;
+       }
+
+       switch ( modeltype )
+       {
+       case MODEL_MD2:
+               break;
+       case MODEL_FM:
+               Cmd_FMNodeOrder();
+               break;
+       }
+}
diff --git a/tools/heretic2/h2data/pics.c b/tools/heretic2/h2data/pics.c
new file mode 100644 (file)
index 0000000..e9e91c2
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include "qdata.h"
+
+byte            *byteimage, *lbmpalette;
+int byteimagewidth, byteimageheight;
+
+qboolean TrueColorImage;
+unsigned        *longimage;
+int longimagewidth, longimageheight;
+
+char pic_prefix[1024];
+extern char        *g_outputDir;
+
+/*
+   ===============
+   Cmd_Pic
+   ===============
+ */
+
+void Cmd_Pic( void ){
+       int xl,yl,xh,yh,w,h;
+       byte            *dest, *source;
+       int flags, value, contents;
+       char lumpname[128];
+       char animname[128];
+       byte buffer[256 * 256];
+       unsigned bufferl[256 * 256];
+       char filename[1024];
+       unsigned        *destl, *sourcel;
+       int linedelta, x, y;
+       int size;
+       miptex_t        *qtex;
+       miptex32_t      *qtex32;
+       float scale_x, scale_y;
+
+       GetScriptToken( false );
+       strcpy( lumpname, token );
+
+       GetScriptToken( false );
+       xl = atoi( token );
+       GetScriptToken( false );
+       yl = atoi( token );
+       GetScriptToken( false );
+       w = atoi( token );
+       GetScriptToken( false );
+       h = atoi( token );
+
+       total_x += w;
+       total_y += h;
+       total_textures++;
+
+       if ( ( w & 7 ) || ( h & 7 ) ) {
+               Error( "line %i: miptex sizes must be multiples of 8", scriptline );
+       }
+
+       flags = 0;
+       contents = 0;
+       value = 0;
+
+       animname[0] = 0;
+
+       scale_x = scale_y = 0.5;
+
+       if ( TrueColorImage ) {
+               sprintf( filename, "%spics/%s/%s.m32", g_outputDir, pic_prefix, lumpname );
+               if ( g_release ) {
+                       return; // textures are only released by $maps
+
+               }
+               xh = xl + w;
+               yh = yl + h;
+
+               if ( xl >= longimagewidth || xh > longimagewidth ||
+                        yl >= longimageheight || yh > longimageheight ) {
+                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight );
+               }
+
+               sourcel = longimage + ( yl * longimagewidth ) + xl;
+               destl = bufferl;
+               linedelta = ( longimagewidth - w );
+
+               for ( y = yl ; y < yh ; y++ )
+               {
+                       for ( x = xl ; x < xh ; x++ )
+                       {
+                               *destl++ = *sourcel++;  // RGBA
+                       }
+                       sourcel += linedelta;
+               }
+
+               qtex32 = CreateMip32( bufferl, w, h, &size, false );
+
+               qtex32->flags |= LittleLong( flags );
+               qtex32->contents = contents;
+               qtex32->value = value;
+               qtex32->scale_x = scale_x;
+               qtex32->scale_y = scale_y;
+               sprintf( qtex32->name, "%s/%s", pic_prefix, lumpname );
+               if ( animname[0] ) {
+                       sprintf( qtex32->animname, "%s/%s", pic_prefix, animname );
+               }
+
+               //
+               // write it out
+               //
+               printf( "writing %s\n", filename );
+               SaveFile( filename, (byte *)qtex32, size );
+
+               free( qtex32 );
+       }
+       else
+       {
+               sprintf( filename, "%spics/%s/%s.m8", g_outputDir, pic_prefix, lumpname );
+               if ( g_release ) {
+                       return; // textures are only released by $maps
+
+               }
+               xh = xl + w;
+               yh = yl + h;
+
+               if ( xl >= byteimagewidth || xh > byteimagewidth ||
+                        yl >= byteimageheight || yh > byteimageheight ) {
+                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
+               }
+
+               source = byteimage + yl * byteimagewidth + xl;
+               dest = buffer;
+               linedelta = byteimagewidth - w;
+
+               for ( y = yl ; y < yh ; y++ )
+               {
+                       for ( x = xl ; x < xh ; x++ )
+                       {
+                               *dest++ = *source++;
+                       }
+                       source += linedelta;
+               }
+
+               qtex = CreateMip( buffer, w, h, lbmpalette, &size, false );
+
+               qtex->flags = flags;
+               qtex->contents = contents;
+               qtex->value = value;
+               sprintf( qtex->name, "%s/%s", pic_prefix, lumpname );
+               if ( animname[0] ) {
+                       sprintf( qtex->animname, "%s/%s", pic_prefix, animname );
+               }
+
+               //
+               // write it out
+               //
+               printf( "writing %s\n", filename );
+               SaveFile( filename, (byte *)qtex, size );
+
+               free( qtex );
+       }
+}
+
+
+/*
+   ===============
+   Cmd_picdir
+   ===============
+ */
+void Cmd_Picdir( void ){
+       char filename[1024];
+
+       GetScriptToken( false );
+       strcpy( pic_prefix, token );
+       // create the directory if needed
+       sprintf( filename, "%sPics", g_outputDir );
+       Q_mkdir( filename );
+       sprintf( filename, "%sPics/%s", g_outputDir, pic_prefix );
+       Q_mkdir( filename );
+}
diff --git a/tools/heretic2/h2data/qd_fmodel.h b/tools/heretic2/h2data/qd_fmodel.h
new file mode 100644 (file)
index 0000000..286fb07
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef FMODEL_H
+#define FMODEL_H
+#include "fmodel.h"
+#endif
+#include "qd_skeletons.h"
+
+typedef struct
+{
+       int numnormals;
+       vec3_t normalsum;
+} fmvertexnormals_t;
+
+typedef struct
+{
+       vec3_t v;
+       int lightnormalindex;
+       fmvertexnormals_t vnorm;
+} fmtrivert_t;
+
+#define FRAME_NAME_LEN ( 16 )
+
+typedef struct
+{
+       vec3_t mins, maxs;
+       char name[FRAME_NAME_LEN];
+       fmtrivert_t v[MAX_FM_VERTS];
+       struct QD_SkeletalJoint_s joints[NUM_CLUSTERS];
+       struct QD_SkeletalJoint_s references[NUM_REFERENCES];
+} fmframe_t;
+
+extern fmframe_t g_frames[MAX_FM_FRAMES];
+
+extern fmheader_t fmheader;
+extern char cdarchive[1024];                        // set by $fmcd
+extern char cdpartial[1024];                        // set by $fmcd
+extern char cddir[1024];                            // set by $fmcd
+
+void GrabFrame( char *frame );
+void H_printf( char *fmt, ... );
+char *FindFrameFile( char *frame );
diff --git a/tools/heretic2/h2data/qd_skeletons.c b/tools/heretic2/h2data/qd_skeletons.c
new file mode 100644 (file)
index 0000000..97e2a1f
--- /dev/null
@@ -0,0 +1,1231 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qd_skeletons.h"
+#include "skeletons.h"
+#include "qd_fmodel.h"
+#include "angles.h"
+#include "token.h"
+#include "qdata.h"
+#include "reference.h"
+
+#include <assert.h>
+#include <math.h>
+#include <memory.h>
+
+
+// We're assuming no more than 16 reference points, with no more than 32 characters in the name
+char RefPointNameList[REF_MAX_POINTS][REF_MAX_STRLEN];
+int RefPointNum = 0;
+
+Skeletalfmheader_t g_skelModel;
+
+void ClearSkeletalModel(){
+       g_skelModel.type = SKEL_NULL;
+       g_skelModel.clustered = false;
+       g_skelModel.references = REF_NULL;
+}
+
+//==========================================================================
+//
+// LoadHRCClustered
+//
+//==========================================================================
+
+// Places the null terminated src string into the dest string less any trailing digits or underscores
+void StripTrailingDigits( char *src, char *dest ){
+#ifndef NDEBUG
+       int max = SKELETAL_NAME_MAX; // should be sufficient for inteded use on names from hrc files
+#endif
+       int i = 0;
+
+       while ( src[i] != '\0' )
+       {
+               ++i;
+#ifndef NDEBUG
+               assert( i < max );
+#endif
+       }
+
+       while ( ( src[--i] >= '0' && src[i] <= '9' ) || src[i] == '_' )
+       {
+
+       }
+
+       memcpy( dest, src, ++i );
+
+       dest[i] = '\0';
+}
+
+static void LoadHRCClustered( char *fileName, int **clusterList, int *num_verts, int skelType ){
+       extern void HandleHRCModel( triangle_t **triList, int *triangleCount,
+                                                               mesh_node_t **nodesList, int *num_mesh_nodes, int ActiveNode, int Depth );
+
+       extern mesh_node_t  *pmnodes;
+
+       triangle_t *triList;
+//      mesh_node_t *nodesList;
+       int num_mesh_nodes = 0, triangleCount = 0;
+
+#if 0
+       int i;
+       int j, numVerts;
+       char stripped[SKELETAL_NAME_MAX];
+
+       for ( i = 1; i < numJointsInSkeleton[skelType] + 1; ++i )
+       {
+               num_verts[i] = 0;
+       }
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+
+       TK_Beyond( TK_CLUSTERS );
+
+       while ( TK_Search( TK_CLUSTER_NAME ) != TK_EOF )
+       {
+               TK_Require( TK_STRING );
+
+               StripTrailingDigits( tk_String, stripped );
+
+               for ( i = 0; i < numJointsInSkeleton[skelType]; ++i )
+               {
+                       if ( stricmp( stripped, skeletonJointNames[skeletonNameOffsets[skelType] + i] ) == 0 ) {
+                               i = -i + numJointsInSkeleton[skelType] - 1;
+
+                               TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER );
+
+                               numVerts = tk_IntNumber;
+
+                               if ( !num_verts[i + 1] ) { // first set of verts for cluster
+                                       clusterList[i] = SafeMalloc( numVerts * sizeof( int ), "LoadHRCClustered" );
+                                       assert( clusterList[i] );
+                               }
+                               else                // any later sets of verts need to copy current
+                               {
+                                       int *temp;
+
+                                       temp = SafeMalloc( ( num_verts[i + 1] + numVerts ) * sizeof( int ), "LoadHRCClustered" );
+                                       assert( temp );
+
+                                       memcpy( temp + numVerts, clusterList[i], num_verts[i + 1] * sizeof( int ) );
+
+                                       free( clusterList[i] );
+
+                                       clusterList[i] = temp;
+                               }
+
+                               // currently this function is only called by LoadModelClusters.
+                               // Apparently the matching free has disappeared,
+                               // should probably be free at the end of FMCmd_Base
+
+                               TK_Beyond( TK_LBRACE );
+
+                               for ( j = 0; j < numVerts; ++j )
+                               {
+                                       TK_Require( TK_INTNUMBER );
+                                       clusterList[i][j] = tk_IntNumber;
+                                       TK_Fetch();
+                               }
+
+                               num_verts[i + 1] += numVerts;
+
+                               break;
+                       }
+               }
+       }
+
+       num_verts[0] = numJointsInSkeleton[skelType];
+#endif
+
+#if 1   // get the index number localized to the root
+//     for( i = 1; i < numJointsInSkeleton[skelType] + 1; ++i)
+//     {
+//             g_skelModel.num_verts[i] = 0;
+//     }
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+
+       // prime it
+       TK_Beyond( TK_MODEL );
+
+       triList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
+       memset( triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
+//     nodesList = SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
+       pmnodes = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
+
+       memset( pmnodes, 0, MAX_FM_MESH_NODES * sizeof( mesh_node_t ) );
+
+       // this should eventually use a stripped down version of this
+       HandleHRCModel( &triList, &triangleCount, &pmnodes, &num_mesh_nodes, 0, 0 );
+
+//     free(nodesList);
+       free( triList );
+
+       num_verts[0] = numJointsInSkeleton[skelType];
+#endif
+}
+
+void ReadHRCClusterList( mesh_node_t *meshNode, int baseIndex ){
+       int i, j, numVerts;
+       tokenType_t nextToken;
+       char stripped[SKELETAL_NAME_MAX];
+
+       meshNode->clustered = true;
+
+       nextToken = TK_Get( TK_CLUSTER_NAME );
+
+       while ( nextToken == TK_CLUSTER_NAME )
+       {
+               TK_FetchRequire( TK_STRING );
+
+               StripTrailingDigits( tk_String, stripped );
+
+               for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i )
+               {
+                       if ( stricmp( stripped, skeletonJointNames[skeletonNameOffsets[g_skelModel.type] + i] ) == 0 ) {
+                               i = -i + numJointsInSkeleton[g_skelModel.type] - 1;
+
+                               TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER );
+
+                               numVerts = tk_IntNumber;
+
+                               if ( !baseIndex ) {
+                                       meshNode->clusters[i] = (int *) SafeMalloc( numVerts * sizeof( int ), "ReadHRCClusterList" );
+                                       assert( meshNode->clusters[i] );
+                               }
+                               else
+                               {
+                                       int *temp;
+
+                                       temp = meshNode->clusters[i];
+                                       meshNode->clusters[i] = (int *) SafeMalloc( ( meshNode->num_verts[i + 1] + numVerts ) * sizeof( int ), "ReadHRCClusterList" );
+                                       assert( meshNode->clusters[i] );
+
+                                       memcpy( meshNode->clusters[i], temp, meshNode->num_verts[i + 1] * sizeof( int ) );
+                                       free( temp );
+                               }
+
+                               // currently this function is only called by LoadModelClusters.
+                               // Apparently the matching free has disappeared,
+                               // should probably be free at the end of FMCmd_Base
+
+                               TK_Beyond( TK_LBRACE );
+
+                               for ( j = 0; j < numVerts; ++j )
+                               {
+                                       TK_Require( TK_INTNUMBER );
+                                       meshNode->clusters[i][baseIndex + j] = tk_IntNumber + baseIndex;
+                                       TK_Fetch();
+                               }
+
+                               if ( baseIndex ) {
+                                       meshNode->num_verts[i + 1] += numVerts;
+                               }
+                               else
+                               {
+                                       meshNode->num_verts[i + 1] = numVerts;
+                               }
+
+                               break;
+                       }
+               }
+
+               TK_BeyondRequire( TK_CLUSTER_STATE, TK_INTNUMBER );
+               nextToken = TK_Fetch();
+       }
+}
+
+static void LoadHRCGlobals( char *fileName ){
+       int i;
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+       TK_Beyond( TK_MODEL );
+
+       TK_Beyond( TK_SCALING );
+       for ( i = 0; i < 3; i++ )
+       {
+               TK_Require( TK_FLOATNUMBER );
+               g_skelModel.scaling[i] = tk_FloatNumber;
+               TK_Fetch();
+       }
+
+       TK_Beyond( TK_ROTATION );
+       for ( i = 0; i < 3; i++ )
+       {
+               TK_Require( TK_FLOATNUMBER );
+               g_skelModel.rotation[i] = tk_FloatNumber;
+               TK_Fetch();
+       }
+
+       TK_Beyond( TK_TRANSLATION );
+       for ( i = 0; i < 3; i++ )
+       {
+               TK_Require( TK_FLOATNUMBER );
+               g_skelModel.translation[i] = tk_FloatNumber;
+               TK_Fetch();
+       }
+}
+
+static void ParseVec3( vec3_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void ParseVec3d( vec3d_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void ParseRotation3( vec3_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void ParseRotation3d( vec3d_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void ParseTranslation3( vec3_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void ParseTranslation3d( vec3d_t in ){
+       TK_Require( TK_FLOATNUMBER );
+       in[1] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[2] = tk_FloatNumber;
+       TK_FetchRequire( TK_FLOATNUMBER );
+       in[0] = tk_FloatNumber;
+}
+
+static void LoadHRCJointList( char *fileName, QD_SkeletalJoint_t *jointList, int skelType ){
+#define MAX_STACK 64
+       int i, j;
+       vec3d_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];
+       int curCorrespondingJoint[MAX_STACK];
+       int currentStack = 0, stackSize;
+       double cx, sx, cy, sy, cz, sz;
+       double rx, ry, rz;
+       double x2, y2, z2;
+       char stripped[SKELETAL_NAME_MAX];
+       Placement_d_t *placement;
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+
+       TK_Beyond( TK_MODEL );
+
+       while ( TK_Search( TK_NAME ) != TK_EOF )
+       {
+               TK_Require( TK_STRING );
+
+               StripTrailingDigits( tk_String, stripped );
+
+               if ( stricmp( stripped, skeletonRootNames[skeletonRNameOffsets[skelType]] ) == 0 ) {
+                       break;
+               }
+       }
+
+       if ( tk_Token == TK_EOF ) {
+               Error( "Bone Chain Root: %s not found\n", skeletonRootNames[skeletonRNameOffsets[skelType]] );
+               return;
+       }
+
+       TK_Beyond( TK_SCALING );
+
+       ParseVec3d( curScale[currentStack] );
+
+       TK_Beyond( TK_ROTATION );
+
+       ParseRotation3d( curRotation[currentStack] );
+
+       TK_Beyond( TK_TRANSLATION );
+
+       ParseVec3d( curTranslation[currentStack] );
+
+       // account for global model translation
+       curTranslation[currentStack][1] += g_skelModel.translation[0];
+       curTranslation[currentStack][2] += g_skelModel.translation[1];
+       curTranslation[currentStack][0] += g_skelModel.translation[2];
+
+       curCorrespondingJoint[currentStack] = -1;
+
+       ++currentStack;
+
+       for ( i = 0; i < numJointsInSkeleton[skelType]; ++i )
+       {
+               while ( 1 )
+               {
+                       TK_Beyond( TK_MODEL );
+
+                       TK_BeyondRequire( TK_NAME, TK_STRING );
+
+                       StripTrailingDigits( tk_String, stripped );
+
+                       if ( stricmp( stripped, skeletonJointNames[skeletonNameOffsets[skelType] + i] ) == 0 ) {
+                               break;
+                       }
+
+                       TK_Beyond( TK_SCALING );
+
+                       ParseVec3d( curScale[currentStack] );
+
+                       TK_Beyond( TK_ROTATION );
+
+                       ParseRotation3d( curRotation[currentStack] );
+
+                       TK_Beyond( TK_TRANSLATION );
+
+                       ParseVec3d( curTranslation[currentStack] );
+
+                       curCorrespondingJoint[currentStack] = -1;
+
+                       ++currentStack;
+               }
+
+               TK_Beyond( TK_SCALING );
+
+               ParseVec3d( curScale[currentStack] );
+
+               TK_Beyond( TK_ROTATION );
+
+               ParseRotation3d( curRotation[currentStack] );
+
+               jointList[i].rotation[1] = curRotation[currentStack][1];
+               jointList[i].rotation[2] = curRotation[currentStack][2];
+               jointList[i].rotation[0] = curRotation[currentStack][0];
+
+               TK_Beyond( TK_TRANSLATION );
+
+               ParseVec3d( curTranslation[currentStack] );
+
+//             jointList[i].placement.origin[1] = curTranslation[currentStack][1];
+//             jointList[i].placement.origin[2] = curTranslation[currentStack][2];
+//             jointList[i].placement.origin[0] = curTranslation[currentStack][0];
+
+               jointList[i].placement.origin[1] = 0.0;
+               jointList[i].placement.origin[2] = 0.0;
+               jointList[i].placement.origin[0] = 0.0;
+
+               jointList[i].placement.direction[1] = 20.0;
+               jointList[i].placement.direction[2] = 0.0;
+               jointList[i].placement.direction[0] = 0.0;
+
+               jointList[i].placement.up[1] = 0.0;
+               jointList[i].placement.up[2] = 20.0;
+               jointList[i].placement.up[0] = 0.0;
+
+               curCorrespondingJoint[currentStack] = i;
+
+               ++currentStack;
+       }
+
+       stackSize = currentStack;
+
+#if 0
+       // rotate the direction and up vectors to correspond to the rotation
+       for ( i = 0; i < numJointsInSkeleton[skelType]; ++i )
+       {
+               rx = jointList[i].rotation[0] * ANGLE_TO_RAD;
+               ry = jointList[i].rotation[1] * ANGLE_TO_RAD;
+               rz = jointList[i].rotation[2] * ANGLE_TO_RAD;
+
+               cx = cos( rx );
+               sx = sin( rx );
+
+               cy = cos( ry );
+               sy = sin( ry );
+
+               cz = cos( rz );
+               sz = sin( rz );
+
+               // y-axis rotation for direction
+               x2 = jointList[i].placement.direction[0] * cy + jointList[i].placement.direction[2] * sy;
+               z2 = -jointList[i].placement.direction[0] * sy + jointList[i].placement.direction[2] * cy;
+               jointList[i].placement.direction[0] = x2;
+               jointList[i].placement.direction[2] = z2;
+
+               // y-axis rotation for up
+               x2 = jointList[i].placement.up[0] * cy + jointList[i].placement.up[2] * sy;
+               z2 = -jointList[i].placement.up[0] * sy + jointList[i].placement.up[2] * cy;
+               jointList[i].placement.up[0] = x2;
+               jointList[i].placement.up[2] = z2;
+
+               // z-axis rotation for direction
+               x2 = jointList[i].placement.direction[0] * cz - jointList[i].placement.direction[1] * sz;
+               y2 = jointList[i].placement.direction[0] * sz + jointList[i].placement.direction[1] * cz;
+               jointList[i].placement.direction[0] = x2;
+               jointList[i].placement.direction[1] = y2;
+
+               // z-axis rotation for up
+               x2 = jointList[i].placement.up[0] * cz - jointList[i].placement.up[1] * sz;
+               y2 = jointList[i].placement.up[0] * sz + jointList[i].placement.up[1] * cz;
+               jointList[i].placement.up[0] = x2;
+               jointList[i].placement.up[1] = y2;
+
+               // x-axis rotation for direction vector
+               y2 = jointList[i].placement.direction[1] * cx - jointList[i].placement.direction[2] * sx;
+               z2 = jointList[i].placement.direction[1] * sx + jointList[i].placement.direction[2] * cx;
+               jointList[i].placement.direction[1] = y2;
+               jointList[i].placement.direction[2] = z2;
+
+               // x-axis rotation for up vector
+               y2 = jointList[i].placement.up[1] * cx - jointList[i].placement.up[2] * sx;
+               z2 = jointList[i].placement.up[1] * sx + jointList[i].placement.up[2] * cx;
+               jointList[i].placement.up[1] = y2;
+               jointList[i].placement.up[2] = z2;
+
+               // translate direction to a point in the model
+               jointList[i].placement.direction[0] += jointList[i].placement.origin[0];
+               jointList[i].placement.direction[1] += jointList[i].placement.origin[1];
+               jointList[i].placement.direction[2] += jointList[i].placement.origin[2];
+
+               // translate up to a point in the model
+               jointList[i].placement.up[0] += jointList[i].placement.origin[0];
+               jointList[i].placement.up[1] += jointList[i].placement.origin[1];
+               jointList[i].placement.up[2] += jointList[i].placement.origin[2];
+       }
+#endif
+
+       for ( i = stackSize - 1; i >= 0; --i )
+       {
+               rx = curRotation[i][0] * ANGLE_TO_RAD;
+               ry = curRotation[i][1] * ANGLE_TO_RAD;
+               rz = curRotation[i][2] * ANGLE_TO_RAD;
+
+               cx = cos( rx );
+               sx = sin( rx );
+
+               cy = cos( ry );
+               sy = sin( ry );
+
+               cz = cos( rz );
+               sz = sin( rz );
+
+#if 1
+               for ( j = i; j < stackSize; ++j )
+               {
+                       if ( curCorrespondingJoint[j] != -1 ) {
+                               placement = &jointList[curCorrespondingJoint[j]].placement;
+
+                               // y-axis rotation for origin
+                               x2 = placement->origin[0] * cy + placement->origin[2] * sy;
+                               z2 = -placement->origin[0] * sy + placement->origin[2] * cy;
+                               placement->origin[0] = x2;
+                               placement->origin[2] = z2;
+
+                               // y-axis rotation for direction
+                               x2 = placement->direction[0] * cy + placement->direction[2] * sy;
+                               z2 = -placement->direction[0] * sy + placement->direction[2] * cy;
+                               placement->direction[0] = x2;
+                               placement->direction[2] = z2;
+
+                               // y-axis rotation for up
+                               x2 = placement->up[0] * cy + placement->up[2] * sy;
+                               z2 = -placement->up[0] * sy + placement->up[2] * cy;
+                               placement->up[0] = x2;
+                               placement->up[2] = z2;
+
+                               // z-axis rotation for origin
+                               x2 = placement->origin[0] * cz - placement->origin[1] * sz;
+                               y2 = placement->origin[0] * sz + placement->origin[1] * cz;
+                               placement->origin[0] = x2;
+                               placement->origin[1] = y2;
+
+                               // z-axis rotation for direction
+                               x2 = placement->direction[0] * cz - placement->direction[1] * sz;
+                               y2 = placement->direction[0] * sz + placement->direction[1] * cz;
+                               placement->direction[0] = x2;
+                               placement->direction[1] = y2;
+
+                               // z-axis rotation for up
+                               x2 = placement->up[0] * cz - placement->up[1] * sz;
+                               y2 = placement->up[0] * sz + placement->up[1] * cz;
+                               placement->up[0] = x2;
+                               placement->up[1] = y2;
+
+                               // x-axis rotation for origin
+                               y2 = placement->origin[1] * cx - placement->origin[2] * sx;
+                               z2 = placement->origin[1] * sx + placement->origin[2] * cx;
+                               placement->origin[1] = y2;
+                               placement->origin[2] = z2;
+
+                               // x-axis rotation for direction vector
+                               y2 = placement->direction[1] * cx - placement->direction[2] * sx;
+                               z2 = placement->direction[1] * sx + placement->direction[2] * cx;
+                               placement->direction[1] = y2;
+                               placement->direction[2] = z2;
+
+                               // x-axis rotation for up vector
+                               y2 = placement->up[1] * cx - placement->up[2] * sx;
+                               z2 = placement->up[1] * sx + placement->up[2] * cx;
+                               placement->up[1] = y2;
+                               placement->up[2] = z2;
+
+                               // translate origin
+                               placement->origin[0] += curTranslation[i][0];
+                               placement->origin[1] += curTranslation[i][1];
+                               placement->origin[2] += curTranslation[i][2];
+
+                               // translate back to local coord
+                               placement->direction[0] += curTranslation[i][0];
+                               placement->direction[1] += curTranslation[i][1];
+                               placement->direction[2] += curTranslation[i][2];
+
+                               // translate back to local coord
+                               placement->up[0] += curTranslation[i][0];
+                               placement->up[1] += curTranslation[i][1];
+                               placement->up[2] += curTranslation[i][2];
+                       }
+               }
+#else
+               // This screwed up and needs to be sorted out!!!
+               // The stack info needs to be written too instead of the jointList for j > numJoints for Skeleton
+               for ( j = i - 1; j < stackSize - 1; ++j )
+               {
+                       // y-axis rotation for origin
+                       x2 = jointList[j].placement.origin[0] * cy + jointList[j].placement.origin[2] * sy;
+                       z2 = -jointList[j].placement.origin[0] * sy + jointList[j].placement.origin[2] * cy;
+                       jointList[j].placement.origin[0] = x2;
+                       jointList[j].placement.origin[2] = z2;
+
+                       // y-axis rotation for direction
+                       x2 = jointList[j].placement.direction[0] * cy + jointList[j].placement.direction[2] * sy;
+                       z2 = -jointList[j].placement.direction[0] * sy + jointList[j].placement.direction[2] * cy;
+                       jointList[j].placement.direction[0] = x2;
+                       jointList[j].placement.direction[2] = z2;
+
+                       // y-axis rotation for up
+                       x2 = jointList[j].placement.up[0] * cy + jointList[j].placement.up[2] * sy;
+                       z2 = -jointList[j].placement.up[0] * sy + jointList[j].placement.up[2] * cy;
+                       jointList[j].placement.up[0] = x2;
+                       jointList[j].placement.up[2] = z2;
+
+                       // z-axis rotation for origin
+                       x2 = jointList[j].placement.origin[0] * cz - jointList[j].placement.origin[1] * sz;
+                       y2 = jointList[j].placement.origin[0] * sz + jointList[j].placement.origin[1] * cz;
+                       jointList[j].placement.origin[0] = x2;
+                       jointList[j].placement.origin[1] = y2;
+
+                       // z-axis rotation for direction
+                       x2 = jointList[j].placement.direction[0] * cz - jointList[j].placement.direction[1] * sz;
+                       y2 = jointList[j].placement.direction[0] * sz + jointList[j].placement.direction[1] * cz;
+                       jointList[j].placement.direction[0] = x2;
+                       jointList[j].placement.direction[1] = y2;
+
+                       // z-axis rotation for up
+                       x2 = jointList[j].placement.up[0] * cz - jointList[j].placement.up[1] * sz;
+                       y2 = jointList[j].placement.up[0] * sz + jointList[j].placement.up[1] * cz;
+                       jointList[j].placement.up[0] = x2;
+                       jointList[j].placement.up[1] = y2;
+
+                       // x-axis rotation for origin
+                       y2 = jointList[j].placement.origin[1] * cx - jointList[j].placement.origin[2] * sx;
+                       z2 = jointList[j].placement.origin[1] * sx + jointList[j].placement.origin[2] * cx;
+                       jointList[j].placement.origin[1] = y2;
+                       jointList[j].placement.origin[2] = z2;
+
+                       // x-axis rotation for direction vector
+                       y2 = jointList[j].placement.direction[1] * cx - jointList[j].placement.direction[2] * sx;
+                       z2 = jointList[j].placement.direction[1] * sx + jointList[j].placement.direction[2] * cx;
+                       jointList[j].placement.direction[1] = y2;
+                       jointList[j].placement.direction[2] = z2;
+
+                       // x-axis rotation for up vector
+                       y2 = jointList[j].placement.up[1] * cx - jointList[j].placement.up[2] * sx;
+                       z2 = jointList[j].placement.up[1] * sx + jointList[j].placement.up[2] * cx;
+                       jointList[j].placement.up[1] = y2;
+                       jointList[j].placement.up[2] = z2;
+
+                       if ( curCorrespondingJoint[j + 1] != -1 ) {
+                               // translate origin
+                               jointList[j].placement.origin[0] += curTranslation[i - 1][0];
+                               jointList[j].placement.origin[1] += curTranslation[i - 1][1];
+                               jointList[j].placement.origin[2] += curTranslation[i - 1][2];
+
+                               // translate back to local coord
+                               jointList[j].placement.direction[0] += curTranslation[i - 1][0];
+                               jointList[j].placement.direction[1] += curTranslation[i - 1][1];
+                               jointList[j].placement.direction[2] += curTranslation[i - 1][2];
+
+                               // translate back to local coord
+                               jointList[j].placement.up[0] += curTranslation[i - 1][0];
+                               jointList[j].placement.up[1] += curTranslation[i - 1][1];
+                               jointList[j].placement.up[2] += curTranslation[i - 1][2];
+                       }
+               }
+#endif
+       }
+}
+
+void LoadModelTransform( char *fileName ){
+       FILE *file1;
+       int dot = '.';
+       char *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+
+                       LoadHRCGlobals( InputFileName );
+
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC match.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+//                     printf("\n");
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRCGlobals( fileName );
+                               return;
+                       }
+               }
+
+               Error( "Could not open file '%s':\n",fileName );
+       }
+}
+
+void LoadModelClusters( char *fileName, int **clusterList, int *num_verts, int skelType ){
+       FILE *file1;
+       int dot = '.';
+       char *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+
+                       LoadHRCClustered( InputFileName, clusterList, num_verts, skelType );
+
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC match.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+//                     printf("\n");
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRCClustered( fileName, clusterList, num_verts, skelType );
+                               return;
+                       }
+               }
+
+               Error( "Could not open file '%s':\n",fileName );
+       }
+}
+
+void LoadSkeleton( char *fileName, QD_SkeletalJoint_t *jointList, int skelType ){
+       FILE *file1;
+       int dot = '.';
+       char *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+
+                       LoadHRCJointList( InputFileName, jointList, skelType );
+
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+//                     printf("\n");
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRCJointList( fileName, jointList, skelType );
+
+                               return;
+                       }
+               }
+
+               Error( "Could not open file '%s':\n",fileName );
+       }
+}
+
+/*
+   ===============
+   GrabSkeletalFrame
+   ===============
+ */
+void GrabSkeletalFrame( char *frame ){
+       char file1[1024];
+       char    *framefile;
+       fmframe_t   *fr;
+
+       framefile = FindFrameFile( frame );
+
+       sprintf( file1, "%s/%s", cdarchive, framefile );
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s",cddir, framefile );
+
+       printf( "Grabbing Skeletal Frame %s\n", file1 );
+
+       fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
+
+       LoadSkeleton( file1, fr->joints, g_skelModel.type );
+}
+
+/*
+   ===============
+   GrabModelTransform
+   ===============
+ */
+void GrabModelTransform( char *frame ){
+       char file1[1024];
+       char    *framefile;
+       fmframe_t   *fr;
+
+       framefile = FindFrameFile( frame );
+
+       sprintf( file1, "%s/%s", cdarchive, framefile );
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s",cddir, framefile );
+
+//     printf ("grabbing %s\n", file1);
+
+       fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
+
+       LoadModelTransform( file1 );
+}
+
+void Cmd_FMCluster(){
+       char file1[1024];
+
+       GetScriptToken( false );
+
+       printf( "---------------------\n" );
+       sprintf( file1, "%s/%s", cdpartial, token );
+       printf( "%s\n", file1 );
+
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s", cddir, token );
+
+       g_skelModel.clustered = -1;
+
+       LoadModelClusters( file1, (int **)&g_skelModel.clusters, (int *)&g_skelModel.num_verts, g_skelModel.type );
+
+       g_skelModel.new_num_verts[0] = g_skelModel.num_verts[0];
+
+       g_skelModel.clustered = true;
+}
+
+void Cmd_FMSkeleton(){
+       GetScriptToken( false );
+       g_skelModel.type = atoi( token );
+}
+
+void Cmd_FMSkeletalFrame(){
+       while ( ScriptTokenAvailable() )
+       {
+               GetScriptToken( false );
+               if ( g_skipmodel ) {
+                       GetScriptToken( false );
+                       continue;
+               }
+               if ( g_release || g_archive ) {
+                       fmheader.num_frames = 1;    // don't skip the writeout
+                       GetScriptToken( false );
+                       continue;
+               }
+
+               H_printf( "#define FRAME_%-16s\t%i\n", token, fmheader.num_frames );
+
+               GrabModelTransform( token );
+               GrabFrame( token );
+               GrabSkeletalFrame( token );
+
+               // need to add the up and dir points to the frame bounds here
+               // using AddPointToBounds (ptrivert[index_xyz].v, fr->mins, fr->maxs);
+               // then remove fudge in determining scale on frame write out
+       }
+}
+
+static void LoadHRCReferences( char *fileName, fmframe_t *fr ){
+#define MAX_STACK 64
+       int i, j, k;
+       vec3d_t curTranslation[MAX_STACK], curRotation[MAX_STACK];
+       int curCorrespondingJoint[MAX_STACK];
+       int currentStack, stackSize;
+       double cx, sx, cy, sy, cz, sz;
+       double rx, ry, rz;
+       double x2, y2, z2;
+       char stripped[SKELETAL_NAME_MAX];
+       Placement_d_t *placement;
+       int refnum;
+
+       TK_OpenSource( fileName );
+       TK_FetchRequire( TK_HRCH );
+       TK_FetchRequire( TK_COLON );
+       TK_FetchRequire( TK_SOFTIMAGE );
+
+       if ( RefPointNum <= 0 ) { // There were no labels indicated in the QDT, so use the hard-coded stuff.
+               refnum = numReferences[g_skelModel.references];
+       }
+       else
+       {
+               refnum = RefPointNum;
+       }
+
+       for ( k = 0; k < refnum; ++k )
+       {
+               currentStack = 0;
+
+               // Load the root to get translation and initial rotation
+//             TK_Beyond(TK_MODEL);
+
+               while ( TK_Search( TK_NAME ) != TK_EOF )
+               {
+                       TK_Require( TK_STRING );
+
+                       StripTrailingDigits( tk_String, stripped );
+
+                       if ( RefPointNum == 0 ) { // Hard coded refpoint labels
+                               if ( stricmp( stripped,
+                                                         referenceRootNames[referenceRootNameOffsets[g_skelModel.references] + k] ) == 0 ) {
+                                       break;
+                               }
+                       }
+                       else
+                       {   // labels indicated by the QDT
+                               if ( stricmp( stripped, RefPointNameList[k] ) == 0 ) {
+                                       break;
+                               }
+                       }
+               }
+
+               if ( tk_Token == TK_EOF ) {
+                       if ( RefPointNum == 0 ) { // Hard coded refpoint labels
+                               Error( "Bone Chain Root: %s not found\n", referenceRootNames[referenceRootNameOffsets[g_skelModel.references]] );
+                       }
+                       else
+                       {   // labels indicated by the QDT
+                               Error( "Bone Chain Root: %s not found\n", RefPointNameList[k] );
+                       }
+                       return;
+               }
+
+//             TK_Beyond(TK_SCALING);
+
+//             ParseVec3d(curScale[currentStack]);
+
+               TK_Beyond( TK_ROTATION );
+
+               ParseRotation3d( curRotation[currentStack] );
+
+               TK_Beyond( TK_TRANSLATION );
+
+               ParseVec3d( curTranslation[currentStack] );
+
+               // account for global model translation
+               curTranslation[currentStack][1] += g_skelModel.translation[0];
+               curTranslation[currentStack][2] += g_skelModel.translation[1];
+               curTranslation[currentStack][0] += g_skelModel.translation[2];
+
+               curCorrespondingJoint[currentStack] = -1;
+
+//             rjr - this one not needed, as there is also a stack increment 20 lines below???
+//             ++currentStack;
+
+               // Load the joint to get orientation
+               TK_Beyond( TK_MODEL );
+
+//             TK_Beyond(TK_SCALING);
+
+//             ParseVec3d(curScale[currentStack]);
+
+               TK_Beyond( TK_ROTATION );
+
+               ParseRotation3d( curRotation[currentStack] );
+
+//             TK_Beyond(TK_TRANSLATION);
+
+//             ParseVec3d(curTranslation[currentStack]);
+
+               fr->references[k].placement.origin[1] = 0.0;
+               fr->references[k].placement.origin[2] = 0.0;
+               fr->references[k].placement.origin[0] = 0.0;
+
+               fr->references[k].placement.direction[1] = 20.0;
+               fr->references[k].placement.direction[2] = 0.0;
+               fr->references[k].placement.direction[0] = 0.0;
+
+               fr->references[k].placement.up[1] = 0.0;
+               fr->references[k].placement.up[2] = 20.0;
+               fr->references[k].placement.up[0] = 0.0;
+
+               curCorrespondingJoint[currentStack] = k;
+
+               ++currentStack;
+
+               stackSize = currentStack;
+
+               for ( i = stackSize - 1; i >= 0; --i )
+               {
+                       rx = curRotation[i][0] * ANGLE_TO_RAD;
+                       ry = curRotation[i][1] * ANGLE_TO_RAD;
+                       rz = curRotation[i][2] * ANGLE_TO_RAD;
+
+                       cx = cos( rx );
+                       sx = sin( rx );
+
+                       cy = cos( ry );
+                       sy = sin( ry );
+
+                       cz = cos( rz );
+                       sz = sin( rz );
+
+                       for ( j = i; j < stackSize; ++j )
+                       {
+                               if ( curCorrespondingJoint[j] != -1 ) {
+                                       placement = &fr->references[curCorrespondingJoint[j]].placement;
+
+                                       // y-axis rotation for origin
+                                       x2 = placement->origin[0] * cy + placement->origin[2] * sy;
+                                       z2 = -placement->origin[0] * sy + placement->origin[2] * cy;
+                                       placement->origin[0] = x2;
+                                       placement->origin[2] = z2;
+
+                                       // y-axis rotation for direction
+                                       x2 = placement->direction[0] * cy + placement->direction[2] * sy;
+                                       z2 = -placement->direction[0] * sy + placement->direction[2] * cy;
+                                       placement->direction[0] = x2;
+                                       placement->direction[2] = z2;
+
+                                       // y-axis rotation for up
+                                       x2 = placement->up[0] * cy + placement->up[2] * sy;
+                                       z2 = -placement->up[0] * sy + placement->up[2] * cy;
+                                       placement->up[0] = x2;
+                                       placement->up[2] = z2;
+
+                                       // z-axis rotation for origin
+                                       x2 = placement->origin[0] * cz - placement->origin[1] * sz;
+                                       y2 = placement->origin[0] * sz + placement->origin[1] * cz;
+                                       placement->origin[0] = x2;
+                                       placement->origin[1] = y2;
+
+                                       // z-axis rotation for direction
+                                       x2 = placement->direction[0] * cz - placement->direction[1] * sz;
+                                       y2 = placement->direction[0] * sz + placement->direction[1] * cz;
+                                       placement->direction[0] = x2;
+                                       placement->direction[1] = y2;
+
+                                       // z-axis rotation for up
+                                       x2 = placement->up[0] * cz - placement->up[1] * sz;
+                                       y2 = placement->up[0] * sz + placement->up[1] * cz;
+                                       placement->up[0] = x2;
+                                       placement->up[1] = y2;
+
+                                       // x-axis rotation for origin
+                                       y2 = placement->origin[1] * cx - placement->origin[2] * sx;
+                                       z2 = placement->origin[1] * sx + placement->origin[2] * cx;
+                                       placement->origin[1] = y2;
+                                       placement->origin[2] = z2;
+
+                                       // x-axis rotation for direction vector
+                                       y2 = placement->direction[1] * cx - placement->direction[2] * sx;
+                                       z2 = placement->direction[1] * sx + placement->direction[2] * cx;
+                                       placement->direction[1] = y2;
+                                       placement->direction[2] = z2;
+
+                                       // x-axis rotation for up vector
+                                       y2 = placement->up[1] * cx - placement->up[2] * sx;
+                                       z2 = placement->up[1] * sx + placement->up[2] * cx;
+                                       placement->up[1] = y2;
+                                       placement->up[2] = z2;
+
+                                       // translate origin
+                                       placement->origin[0] += curTranslation[i][0];
+                                       placement->origin[1] += curTranslation[i][1];
+                                       placement->origin[2] += curTranslation[i][2];
+
+                                       // translate back to local coord
+                                       placement->direction[0] += curTranslation[i][0];
+                                       placement->direction[1] += curTranslation[i][1];
+                                       placement->direction[2] += curTranslation[i][2];
+
+                                       // translate back to local coord
+                                       placement->up[0] += curTranslation[i][0];
+                                       placement->up[1] += curTranslation[i][1];
+                                       placement->up[2] += curTranslation[i][2];
+
+                               }
+                       }
+               }
+               printf( "%f, %f, %f\n", placement->origin[0], placement->origin[1], placement->origin[2] );
+       }
+       printf( "\n" );
+}
+
+void Cmd_FMReferenced(){
+       int i;
+
+       GetScriptToken( false );
+       g_skelModel.references = atoi( token );
+
+       // Guess what?  Now, we now want a list of strings to look for here instead of a hard-coded list
+       for ( i = 0; i < REF_MAX_POINTS; i++ )
+       {
+               if ( ScriptTokenAvailable() ) { // There is yet another reference point waiting.
+                       GetScriptToken( false );
+                       strcpy( RefPointNameList[i], token );
+               }
+               else
+               {
+                       break;
+               }
+       }
+
+       RefPointNum = i;
+
+       if ( RefPointNum > 0 ) {
+               printf( "Searching for %d different reference points.\n", RefPointNum );
+       }
+       else
+       {
+               printf( "Using built-in reference points.\n" );
+       }
+
+}
+
+void LoadReferences( char *fileName, fmframe_t *fr ){
+       FILE *file1;
+       int dot = '.';
+       char *dotstart;
+       char InputFileName[256];
+
+       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
+
+       if ( !dotstart ) {
+               strcpy( InputFileName, fileName );
+               strcat( InputFileName, ".hrc" );
+               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
+                       fclose( file1 );
+
+                       LoadHRCReferences( InputFileName, fr );
+
+                       printf( " - assuming .HRC\n" );
+                       return;
+               }
+
+               Error( "\n Could not open file '%s':\n"
+                          "No HRC.\n", fileName );
+       }
+       else
+       {
+               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
+                       printf( "\n" );
+                       fclose( file1 );
+                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
+                               LoadHRCReferences( fileName, fr );
+
+                               return;
+                       }
+               }
+
+               Error( "Could not open file '%s':\n",fileName );
+       }
+}
+
+void GrabReferencedFrame( char *frame ){
+       char file1[1024];
+       char    *framefile;
+       fmframe_t   *fr;
+
+       framefile = FindFrameFile( frame );
+
+       sprintf( file1, "%s/%s", cdarchive, framefile );
+       ExpandPathAndArchive( file1 );
+
+       sprintf( file1, "%s/%s",cddir, framefile );
+
+       printf( "Grabbing Referenced %s\n", file1 );
+
+       fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
+
+       LoadReferences( file1, fr );
+}
diff --git a/tools/heretic2/h2data/qd_skeletons.h b/tools/heretic2/h2data/qd_skeletons.h
new file mode 100644 (file)
index 0000000..7765c57
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef QD_SKELETONS_H
+#define QD_SKELETONS_H
+
+#include "placement.h"
+
+
+typedef struct Placement_d_s
+{
+       vec3d_t origin;
+       vec3d_t direction;
+       vec3d_t up;
+} Placement_d_t;
+
+typedef struct QD_SkeletalJoint_s
+{
+       Placement_d_t placement;
+       vec3d_t rotation;
+} QD_SkeletalJoint_t;
+
+#define NUM_CLUSTERS 8
+
+typedef struct IntListNode_s
+{
+       int data;
+       struct IntListNode_s *next;
+} IntListNode_t;  // gaak
+
+typedef struct Skeletalfmheader_s
+{
+       int type;
+       int clustered;
+       int references;
+
+       int *clusters[NUM_CLUSTERS];
+       IntListNode_t *vertLists[NUM_CLUSTERS];
+       int num_verts[NUM_CLUSTERS + 1];
+       int new_num_verts[NUM_CLUSTERS + 1];
+
+       float scaling[3];
+       float rotation[3];
+       float translation[3];
+} Skeletalfmheader_t;
+
+#define SKELETAL_NAME_MAX 32
+
+extern Skeletalfmheader_t g_skelModel;
+
+void ClearSkeletalModel();
+void GrabModelTransform( char *frame );
+void GrabSkeletalFrame( char *frame );
+void GrabReferencedFrame( char *frame );
+
+// Reference Stuff
+#define NUM_REFERENCES 8
+
+#define REF_MAX_POINTS  16
+#define REF_MAX_STRLEN  32
+
+// We're assuming no more than 16 reference points, with no more than 32 characters in the name
+extern char RefPointNameList[REF_MAX_POINTS][REF_MAX_STRLEN];
+extern int RefPointNum;
+
+#endif
diff --git a/tools/heretic2/h2data/qdata.c b/tools/heretic2/h2data/qdata.c
new file mode 100644 (file)
index 0000000..5ec53a9
--- /dev/null
@@ -0,0 +1,764 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qdata.h"
+#include "globaldefs.h"
+#include "md4.h"
+
+void TK_Init();
+
+qboolean g_compress_pak;
+qboolean g_release;             // don't grab, copy output data to new tree
+qboolean g_pak;                 // if true, copy to pak instead of release
+char g_releasedir[1024];        // c:\quake2\baseq2, etc
+qboolean g_archive;             // don't grab, copy source data to new tree
+qboolean do3ds;
+char g_only[256];               // if set, only grab this cd
+qboolean g_skipmodel;           // set true when a cd is not g_only
+int g_forcemodel = MODEL_AUTO;
+qboolean g_verbose = false;
+qboolean g_allow_newskin = true;
+qboolean g_ignoreTriUV = false;
+qboolean g_publishOutput = false;
+
+char        *ext_3ds = "3ds";
+char        *ext_tri = "tri";
+char        *trifileext;
+
+char g_materialFile[256] = "none";          // default for Heretic2
+char        *g_outputDir;
+extern char *g_publishDir;
+
+extern qboolean g_nomkdir;
+
+/*
+   =======================================================
+
+   PAK FILES
+
+   =======================================================
+ */
+
+typedef struct
+{
+       char name[56];
+       int filepos, filelen;
+} packfile_t;
+
+typedef struct
+{
+       char id[4];
+       int dirofs;
+       int dirlen;
+} packheader_t;
+
+packfile_t pfiles[16384];
+FILE            *pakfile;
+packfile_t      *pf;
+packheader_t pakheader;
+
+
+
+/*
+   ==============
+   BeginPak
+   ==============
+ */
+void BeginPak( char *outname ){
+       if ( !g_pak ) {
+               return;
+       }
+
+       pakfile = SafeOpenWrite( outname );
+
+       // leave space for header
+       SafeWrite( pakfile, &pakheader, sizeof( pakheader ) );
+
+       pf = pfiles;
+}
+
+
+/*
+   ==============
+   ReleaseFile
+
+   Filename should be gamedir reletive.
+   Either copies the file to the release dir, or adds it to
+   the pak file.
+   ==============
+ */
+void ReleaseFile( char *filename ){
+       int len;
+       byte    *buf;
+       char source[1024];
+       char dest[1024];
+
+       if ( !g_release ) {
+               return;
+       }
+
+       sprintf( source, "%s%s", gamedir, filename );
+
+       if ( !g_pak ) { // copy it
+               sprintf( dest, "%s/%s", g_releasedir, filename );
+               printf( "copying to %s\n", dest );
+               QCopyFile( source, dest );
+               return;
+       }
+
+       // pak it
+       printf( "paking %s\n", filename );
+       if ( strlen( filename ) >= sizeof( pf->name ) ) {
+               Error( "Filename too long for pak: %s", filename );
+       }
+
+       len = LoadFile( source, (void **)&buf );
+
+       // segment moved to old.c
+
+       strcpy( pf->name, filename );
+       pf->filepos = LittleLong( ftell( pakfile ) );
+       pf->filelen = LittleLong( len );
+       pf++;
+
+       SafeWrite( pakfile, buf, len );
+
+       free( buf );
+}
+
+
+/*
+   ==============
+   FinishPak
+   ==============
+ */
+void FinishPak( void ){
+       int dirlen;
+       int d;
+       int i;
+       unsigned checksum;
+
+       if ( !g_pak ) {
+               return;
+       }
+
+       pakheader.id[0] = 'P';
+       pakheader.id[1] = 'A';
+       pakheader.id[2] = 'C';
+       pakheader.id[3] = 'K';
+       dirlen = (byte *)pf - (byte *)pfiles;
+       pakheader.dirofs = LittleLong( ftell( pakfile ) );
+       pakheader.dirlen = LittleLong( dirlen );
+
+       checksum = Com_BlockChecksum( (void *)pfiles, dirlen );
+
+       SafeWrite( pakfile, pfiles, dirlen );
+
+       i = ftell( pakfile );
+
+       fseek( pakfile, 0, SEEK_SET );
+       SafeWrite( pakfile, &pakheader, sizeof( pakheader ) );
+       fclose( pakfile );
+
+       d = pf - pfiles;
+       printf( "%i files packed in %i bytes\n",d, i );
+       printf( "checksum: 0x%x\n", checksum );
+}
+
+
+/*
+   ===============
+   Cmd_File
+
+   This is only used to cause a file to be copied during a release
+   build (default.cfg, maps, etc)
+   ===============
+ */
+void Cmd_File( void ){
+       GetScriptToken( false );
+       ReleaseFile( token );
+}
+
+/*
+   ===============
+   PackDirectory_r
+
+   ===============
+ */
+#if GDEF_OS_WINDOWS
+#include "io.h"
+void PackDirectory_r( char *dir ){
+       struct _finddata_t fileinfo;
+       int handle;
+       char dirstring[1024];
+       char filename[1024];
+
+       sprintf( dirstring, "%s%s/*.*", gamedir, dir );
+
+       handle = _findfirst( dirstring, &fileinfo );
+       if ( handle == -1 ) {
+               return;
+       }
+
+       do
+       {
+               sprintf( filename, "%s/%s", dir, fileinfo.name );
+               if ( fileinfo.attrib & _A_SUBDIR ) { // directory
+                       if ( fileinfo.name[0] != '.' ) {  // don't pak . and ..
+                               PackDirectory_r( filename );
+                       }
+                       continue;
+               }
+               // copy or pack the file
+               ReleaseFile( filename );
+       } while ( _findnext( handle, &fileinfo ) != -1 );
+
+       _findclose( handle );
+}
+#else
+
+#include <sys/types.h>
+#ifdef NeXT
+#include <sys/dir.h>
+#else
+#include <dirent.h>
+#endif
+
+void PackDirectory_r( char *dir ){
+#ifdef NeXT
+       struct direct **namelist, *ent;
+#else
+       struct dirent **namelist, *ent;
+#endif
+       int count;
+       struct stat st;
+       int i;
+       int len;
+       char fullname[1024];
+       char dirstring[1024];
+       char        *name;
+
+       sprintf( dirstring, "%s%s", gamedir, dir );
+       count = scandir( dirstring, &namelist, NULL, NULL );
+
+       for ( i = 0 ; i < count ; i++ )
+       {
+               ent = namelist[i];
+               name = ent->d_name;
+
+               if ( name[0] == '.' ) {
+                       continue;
+               }
+
+               sprintf( fullname, "%s/%s", dir, name );
+               sprintf( dirstring, "%s%s/%s", gamedir, dir, name );
+
+               if ( stat( dirstring, &st ) == -1 ) {
+                       Error( "fstating %s", pf->name );
+               }
+               if ( st.st_mode & S_IFDIR ) { // directory
+                       PackDirectory_r( fullname );
+                       continue;
+               }
+
+               // copy or pack the file
+               ReleaseFile( fullname );
+       }
+}
+#endif
+
+
+/*
+   ===============
+   Cmd_Dir
+
+   This is only used to cause a directory to be copied during a
+   release build (sounds, etc)
+   ===============
+ */
+void Cmd_Dir( void ){
+       GetScriptToken( false );
+       PackDirectory_r( token );
+}
+
+//========================================================================
+
+#define MAX_RTEX    16384
+int numrtex;
+char rtex[MAX_RTEX][64];
+
+void ReleaseTexture( char *name ){
+       int i;
+       char path[1024];
+
+       for ( i = 0 ; i < numrtex ; i++ )
+               if ( !Q_strcasecmp( name, rtex[i] ) ) {
+                       return;
+               }
+
+       if ( numrtex == MAX_RTEX ) {
+               Error( "numrtex == MAX_RTEX" );
+       }
+
+       strcpy( rtex[i], name );
+       numrtex++;
+
+       sprintf( path, "textures/%s.wal", name );
+       ReleaseFile( path );
+}
+
+/*
+   ===============
+   Cmd_Maps
+
+   Only relevent for release and pak files.
+   Releases the .bsp files for the maps, and scans all of the files to
+   build a list of all textures used, which are then released.
+   ===============
+ */
+void Cmd_Maps( void ){
+       char map[1024];
+       int i;
+
+       while ( ScriptTokenAvailable() )
+       {
+               GetScriptToken( false );
+               sprintf( map, "maps/%s.bsp", token );
+               ReleaseFile( map );
+
+               if ( !g_release ) {
+                       continue;
+               }
+
+               // get all the texture references
+               sprintf( map, "%smaps/%s.bsp", gamedir, token );
+               LoadBSPFileTexinfo( map );
+               for ( i = 0 ; i < numtexinfo ; i++ )
+                       ReleaseTexture( texinfo[i].texture );
+       }
+}
+
+
+//==============================================================
+
+/*
+   ===============
+   ParseScript
+   ===============
+ */
+void ParseScript( void ){
+       while ( 1 )
+       {
+               do
+               {   // look for a line starting with a $ command
+                       GetScriptToken( true );
+                       if ( endofscript ) {
+                               return;
+                       }
+                       if ( token[0] == '$' ) {
+                               break;
+                       }
+                       while ( ScriptTokenAvailable() )
+                               GetScriptToken( false );
+               } while ( 1 );
+
+               //
+               // model commands
+               //
+               if ( !strcmp( token, "$modelname" ) ) {
+                       MODELCMD_Modelname( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$cd" ) ) {
+                       MODELCMD_Cd( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$origin" ) ) {
+                       MODELCMD_Origin( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$cluster" ) ) {
+                       MODELCMD_Cluster( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$base" ) ) {
+                       MODELCMD_Base( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$scale" ) ) {
+                       MODELCMD_ScaleUp( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$frame" ) ) {
+                       MODELCMD_Frame( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$skin" ) ) {
+                       MODELCMD_Skin( MODEL_MD2 );
+               }
+               else if ( !strcmp( token, "$skinsize" ) ) {
+                       MODELCMD_Skinsize( MODEL_MD2 );
+               }
+               //
+               // flexible model commands
+               //
+               else if ( !strcmp( token, "$fm_modelname" ) ) {
+                       MODELCMD_Modelname( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_base" ) ) {
+                       MODELCMD_Base( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_basest" ) ) {
+                       MODELCMD_BaseST( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_cd" ) ) {
+                       MODELCMD_Cd( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_origin" ) ) {
+                       MODELCMD_Origin( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_cluster" ) ) {
+                       MODELCMD_Cluster( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_skeleton" ) ) {
+                       MODELCMD_Skeleton( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_scale" ) ) {
+                       MODELCMD_ScaleUp( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_frame" ) ) {
+                       MODELCMD_Frame( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_skeletal_frame" ) ) { // left in for compadibility with qdt already using fm_skeletal_frame
+                       MODELCMD_Frame( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_skin" ) ) {
+                       MODELCMD_Skin( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_skinsize" ) ) {
+                       MODELCMD_Skinsize( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_begin_group" ) ) {
+                       MODELCMD_BeginGroup( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_end_group" ) ) {
+                       MODELCMD_EndGroup( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_referenced" ) ) {
+                       MODELCMD_Referenced( MODEL_FM );
+               }
+               else if ( !strcmp( token, "$fm_node_order" ) ) {
+                       MODELCMD_NodeOrder( MODEL_FM );
+               }
+
+               //
+               // sprite commands
+               //
+               else if ( !strcmp( token, "$spritename" ) ) {
+                       Cmd_SpriteName();
+               }
+               else if ( !strcmp( token, "$sprdir" ) ) {
+                       Cmd_Sprdir();
+               }
+               else if ( !strcmp( token, "$load" ) ) {
+                       Cmd_Load();
+               }
+               else if ( !strcmp( token, "$spriteframe" ) ) {
+                       Cmd_SpriteFrame();
+               }
+               //
+               // image commands
+               //
+               else if ( !strcmpi( token, "$grab" ) ) {
+                       Cmd_Grab();
+               }
+               else if ( !strcmpi( token, "$raw" ) ) {
+                       Cmd_Raw();
+               }
+               else if ( !strcmpi( token, "$colormap" ) ) {
+                       Cmd_Colormap();
+               }
+               else if ( !strcmpi( token, "$mippal" ) ) {
+                       Cmd_Mippal();
+               }
+               else if ( !strcmpi( token, "$mipdir" ) ) {
+                       Cmd_Mipdir();
+               }
+               else if ( !strcmpi( token, "$mip" ) ) {
+                       Cmd_Mip();
+               }
+               else if ( !strcmp( token, "$environment" ) ) {
+                       Cmd_Environment();
+               }
+               //
+               // pics
+               //
+               else if ( !strcmp( token, "$picdir" ) ) {
+                       Cmd_Picdir();
+               }
+               else if ( !strcmp( token, "$pic" ) ) {
+                       Cmd_Pic();
+               }
+               //
+               // book
+               //
+               else if ( !strcmp( token, "$bookdir" ) ) {
+                       Cmd_Bookdir();
+               }
+               else if ( !strcmp( token, "$book" ) ) {
+                       Cmd_Book();
+               }
+               //
+               // tmix
+               //
+               else if ( !strcmp( token, "$texturemix" ) ) {
+                       Cmd_TextureMix();
+               }
+               //
+               // video
+               //
+               else if ( !strcmp( token, "$video" ) ) {
+                       Cmd_Video();
+               }
+               //
+               // misc
+               //
+               else if ( !strcmp( token, "$file" ) ) {
+                       Cmd_File();
+               }
+               else if ( !strcmp( token, "$dir" ) ) {
+                       Cmd_Dir();
+               }
+               else if ( !strcmp( token, "$maps" ) ) {
+                       Cmd_Maps();
+               }
+               else if ( !strcmp( token, "$alphalight" ) ) {
+                       Cmd_Alphalight();
+               }
+               else if ( !strcmp( token, "$inverse16table" ) ) {
+                       Cmd_Inverse16Table();
+               }
+               else{
+                       Error( "bad command %s\n", token );
+               }
+       }
+}
+
+//=======================================================
+
+/*
+   ==============
+   main
+   ==============
+ */
+int main( int argc, char **argv ){
+       int i;
+       char path[1024];
+       char        *basedir;
+       double starttime, endtime;
+
+       printf( "Qdata Plus : "__TIME__ " "__DATE__ "\n" );
+
+       starttime = I_FloatTime();
+       basedir = NULL;
+
+       TK_Init();
+       ExpandWildcards( &argc, &argv );
+
+       for ( i = 1 ; i < argc ; i++ )
+       {
+               if ( !strcmp( argv[i], "-archive" ) ) {
+                       // -archive f:/quake2/release/dump_11_30
+                       archive = true;
+                       strcpy( archivedir, argv[i + 1] );
+                       printf( "Archiving source to: %s\n", archivedir );
+                       i++;
+               }
+               else if ( !strcmp( argv[i], "-release" ) ) {
+                       g_release = true;
+                       strcpy( g_releasedir, argv[i + 1] );
+                       printf( "Copy output to: %s\n", g_releasedir );
+                       i++;
+               }
+               else if ( !strcmp( argv[i], "-base" ) ) {
+                       i++;
+                       basedir = argv[i];
+               }
+               else if ( !strcmp( argv[i], "-compress" ) ) {
+                       g_compress_pak = true;
+                       printf( "Compressing pakfile\n" );
+               }
+               else if ( !strcmp( argv[i], "-pak" ) ) {
+                       g_release = true;
+                       g_pak = true;
+                       printf( "Building pakfile: %s\n", argv[i + 1] );
+                       BeginPak( argv[i + 1] );
+                       i++;
+               }
+               else if ( !strcmp( argv[i], "-only" ) ) {
+                       strcpy( g_only, argv[i + 1] );
+                       printf( "Only grabbing %s\n", g_only );
+                       i++;
+               }
+               else if ( !strcmpi( argv[i], "-keypress" ) ) {
+                       g_dokeypress = true;
+               }
+               else if ( !strcmp( argv[i], "-3ds" ) ) {
+                       do3ds = true;
+                       printf( "loading .3ds files\n" );
+               }
+               else if ( !strcmp( argv[i], "-materialfile" ) ) {
+                       strcpy( g_materialFile, argv[i + 1] );
+                       printf( "Setting material file to %s\n", g_materialFile );
+                       i++;
+               }
+/*             else if (!strcmpi(argv[i], "-newgen"))
+        {
+            if (i < argc-4)
+            {
+                printf("run new triangle grouping routine here\n");
+                NewGen(argv[i+1],argv[i+2],atoi(argv[i+3]),atoi(argv[i+4]));
+            }
+            else
+            {
+                printf("qdata -newskin <base.hrc> <skin.pcx> width height\n");
+            }
+            return 0;
+        }
+ */     else if ( !strcmpi( argv[i], "-genskin" ) ) {
+                       i++;
+                       if ( i < argc - 3 ) {
+                               GenSkin( argv[i],argv[i + 1],atol( argv[i + 2] ),atol( argv[i + 3] ) );
+                       }
+                       else
+                       {
+                               printf( "qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>\n" );
+                       }
+                       return 0;
+
+               }
+               else if ( !strcmpi( argv[i], "-noopts" ) ) {
+                       g_no_opimizations = true;
+                       printf( "not performing optimizations\n" );
+               }
+               else if ( !strcmpi( argv[i], "-md2" ) ) {
+                       g_forcemodel = MODEL_MD2;
+               }
+               else if ( !strcmpi( argv[i], "-fm" ) ) {
+                       g_forcemodel = MODEL_FM;
+               }
+               else if ( !strcmpi( argv[i], "-verbose" ) ) {
+                       g_verbose = true;
+               }
+               else if ( !strcmpi( argv[i], "-oldskin" ) ) {
+                       g_allow_newskin = false;
+               }
+               else if ( !strcmpi( argv[i], "-ignoreUV" ) ) {
+                       g_ignoreTriUV = true;
+               }
+               else if ( !strcmpi( argv[i], "-publish" ) ) {
+                       g_publishOutput = true;
+               }
+               else if ( !strcmpi( argv[i], "-nomkdir" ) ) {
+                       g_nomkdir = true;
+               }
+               else if ( argv[i][0] == '-' ) {
+                       Error( "Unknown option \"%s\"", argv[i] );
+               }
+               else{
+                       break;
+               }
+       }
+
+       if ( i >= argc ) {
+               Error( "usage: qdata [-archive <directory>]\n"
+                          "             [-release <directory>]\n"
+                          "             [-base <directory>]\n"
+                          "             [-compress]\n"
+                          "             [-pak <file>]\n"
+                          "             [-only <model>]\n"
+                          "             [-keypress]\n"
+                          "             [-3ds]\n"
+                          "             [-materialfile <file>]\n"
+                          "             [-noopts]\n"
+                          "             [-md2]\n"
+                          "             [-fm]\n"
+                          "             [-verbose]\n"
+                          "             [-ignoreUV]\n"
+                          "             [-oldskin]\n"
+                          "             [-publish]\n"
+                          "             [-nomkdir]\n"
+                          "             file.qdt\n"
+                          "or\n"
+                          "       qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>" );
+       }
+
+       if ( do3ds ) {
+               trifileext = ext_3ds;
+       }
+       else{
+               trifileext = ext_tri;
+       }
+
+       for ( ; i < argc ; i++ )
+       {
+               printf( "--------------- %s ---------------\n", argv[i] );
+               // load the script
+               strcpy( path, argv[i] );
+               DefaultExtension( path, ".qdt" );
+               DefaultExtension( g_materialFile, ".mat" );
+               SetQdirFromPath( path );
+
+               printf( "workingdir='%s'\n", gamedir );
+               if ( basedir ) {
+                       qdir[0] = 0;
+                       g_outputDir = basedir;
+               }
+
+               printf( "outputdir='%s'\n", g_outputDir );
+
+               QFile_ReadMaterialTypes( g_materialFile );
+               LoadScriptFile( ExpandArg( path ) );
+
+               //
+               // parse it
+               //
+               ParseScript();
+
+               // write out the last model
+               FinishModel();
+               FMFinishModel();
+               FinishSprite();
+       }
+
+       if ( total_textures ) {
+               printf( "\n" );
+               printf( "Total textures processed: %d\n",total_textures );
+               printf( "Average size: %d x %d\n",total_x / total_textures, total_y / total_textures );
+       }
+
+       if ( g_pak ) {
+               FinishPak();
+       }
+
+       endtime = I_FloatTime();
+       printf( "Time elapsed:  %f\n", endtime - starttime );
+
+       if ( g_dokeypress ) {
+               printf( "Success! ... Hit a key: " );
+               getchar();
+       }
+
+       return 0;
+}
diff --git a/tools/heretic2/h2data/qdata.h b/tools/heretic2/h2data/qdata.h
new file mode 100644 (file)
index 0000000..0cfa606
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// qdata.h
+
+#include "globaldefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "cmdlib.h"
+#include "inout.h"
+#include "scriplib.h"
+#include "mathlib.h"
+#include "trilib.h"
+#include "lbmlib.h"
+#include "her2_threads.h"
+#include "l3dslib.h"
+#include "bspfile.h"
+
+#if !GDEF_OS_WINDOWS
+#define stricmp strcasecmp
+#define strcmpi strcasecmp
+#endif
+
+
+#define MODEL_AUTO  0
+#define MODEL_MD2   1
+#define MODEL_FM    2
+
+// Model cover functions (to allow the forcing of a model type)
+void MODELCMD_Modelname( int modeltype );
+void MODELCMD_Cd( int modeltype );
+void MODELCMD_Origin( int modeltype );
+void MODELCMD_Jointed( int modeltype );
+void MODELCMD_Cluster( int modeltype );
+void MODELCMD_Base( int modeltype );
+void MODELCMD_BaseST( int modeltype );
+void MODELCMD_ScaleUp( int modeltype );
+void MODELCMD_Frame( int modeltype );
+void MODELCMD_Skin( int modeltype );
+void MODELCMD_Skinsize( int modeltype );
+void MODELCMD_Skeleton( int modeltype );
+void MODELCMD_SkeletalFrame( int modeltype );
+void MODELCMD_BeginGroup( int modeltype );
+void MODELCMD_EndGroup( int modeltype );
+void MODELCMD_Referenced( int modeltype );
+void MODELCMD_NodeOrder( int modeltype );
+
+void Cmd_Modelname( void );
+void Cmd_Base( void );
+void Cmd_Cd( void );
+void Cmd_Origin( void );
+void Cmd_ScaleUp( void );
+void Cmd_Frame( void );
+void Cmd_Skin( void );
+void Cmd_Skinsize( void );
+void FinishModel( void );
+void Cmd_Cluster( void );
+
+// Flexible Models
+//void Cmd_FMModelname (void);
+void Cmd_FMBase( qboolean GetST );
+void Cmd_FMCd( void );
+//void Cmd_FMOrigin (void);
+void Cmd_FMCluster();
+void Cmd_FMSkeleton();
+//void Cmd_FMScaleUp (void);
+void Cmd_FMFrame( void );
+void Cmd_FMSkeletalFrame();
+void Cmd_FMSkin( void );
+//void Cmd_FMSkinsize (void);
+void Cmd_FMBeginGroup( void );
+void Cmd_FMEndGroup( void );
+void Cmd_FMReferenced();
+void Cmd_FMNodeOrder( void );
+void FMFinishModel( void );
+void GenSkin( char *ModelFile, char *OutputName, int Width, int Height );
+void NewGen( char *ModelFile, char *OutputName, int width, int height );
+
+
+void Cmd_Inverse16Table( void );
+
+void Cmd_SpriteName( void );
+void Cmd_Load( void );
+void Cmd_SpriteFrame( void );
+void Cmd_Sprdir( void );
+void FinishSprite( void );
+
+void Cmd_Grab( void );
+void Cmd_Raw( void );
+void Cmd_Mip( void );
+void Cmd_Environment( void );
+void Cmd_Colormap( void );
+
+void Cmd_File( void );
+void Cmd_Dir( void );
+void Cmd_StartWad( void );
+void Cmd_EndWad( void );
+void Cmd_Mippal( void );
+void Cmd_Mipdir( void );
+void Cmd_Alphalight( void );
+
+void Cmd_Picdir( void );
+void Cmd_Pic( void );
+
+void Cmd_Bookdir( void );
+void Cmd_Book( void );
+
+void Cmd_TextureMix( void );
+
+void Cmd_Video( void );
+
+//void RemapZero (byte *pixels, byte *palette, int width, int height);
+
+void ReleaseFile( char *filename );
+
+extern byte        *byteimage, *lbmpalette;
+extern int byteimagewidth, byteimageheight;
+extern qboolean TrueColorImage;
+extern unsigned    *longimage;
+extern int longimagewidth, longimageheight;
+
+extern qboolean g_release;              // don't grab, copy output data to new tree
+extern char g_releasedir[1024];         // c:\quake2\baseq2, etc
+extern qboolean g_archive;              // don't grab, copy source data to new tree
+extern qboolean do3ds;
+extern char g_only[256];                // if set, only grab this cd
+extern qboolean g_skipmodel;            // set true when a cd is not g_only
+extern qboolean g_no_opimizations;
+extern int g_forcemodel;
+extern qboolean g_verbose;
+extern qboolean g_allow_newskin;
+extern qboolean g_ignoreTriUV;      //from qdata.c
+extern qboolean g_dokeypress;
+
+extern char        *trifileext;
+
+extern char g_materialFile[256];
+
+extern unsigned total_x;
+extern unsigned total_y;
+extern unsigned total_textures;
+
+miptex_t *CreateMip( byte *data, unsigned width, unsigned height, byte *palette, int *FinalSize, qboolean mip );
+miptex32_t *CreateMip32( unsigned *data, unsigned width, unsigned height, int *FinalSize, qboolean mip );
diff --git a/tools/heretic2/h2data/resource.h b/tools/heretic2/h2data/resource.h
new file mode 100644 (file)
index 0000000..3d6343e
--- /dev/null
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by Script1.rc
+//
+#define IDI_ICON1                       101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_3D_CONTROLS                     1
+#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/tools/heretic2/h2data/sprites.c b/tools/heretic2/h2data/sprites.c
new file mode 100644 (file)
index 0000000..ecb9d09
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include "qdata.h"
+
+#define MAX_SPRFRAMES           MAX_MD2SKINS
+
+dsprite_t sprite;
+dsprframe_t frames[MAX_SPRFRAMES];
+
+byte            *byteimage, *lbmpalette;
+int byteimagewidth, byteimageheight;
+
+qboolean TrueColorImage;
+unsigned        *longimage;
+int longimagewidth, longimageheight;
+
+char spritename[1024];
+
+
+void FinishSprite( void );
+void Cmd_Spritename( void );
+
+char spr_prefix[1024];
+char pic_prefix[1024];
+
+extern char        *g_outputDir;
+
+
+/*
+   ==============
+   FinishSprite
+   ==============
+ */
+void FinishSprite( void ){
+       FILE    *spriteouthandle;
+       int i, curframe;
+       dsprite_t spritetemp;
+       char savename[1024];
+
+       if ( sprite.numframes == 0 ) {
+               return;
+       }
+
+       if ( !strlen( spritename ) ) {
+               Error( "Didn't name sprite file" );
+       }
+
+       sprintf( savename, "%sSprites/%s/%s.sp2", g_outputDir, spr_prefix, spritename );
+
+       if ( g_release ) {
+               char name[1024];
+
+               sprintf( name, "%s.sp2", spritename );
+               ReleaseFile( name );
+               spritename[0] = 0;      // clear for a new sprite
+               sprite.numframes = 0;
+               return;
+       }
+
+
+       printf( "saving in %s\n", savename );
+       CreatePath( savename );
+       spriteouthandle = SafeOpenWrite( savename );
+
+
+//
+// write out the sprite header
+//
+       spritetemp.ident = LittleLong( IDSPRITEHEADER );
+       spritetemp.version = LittleLong( SPRITE_VERSION );
+       spritetemp.numframes = LittleLong( sprite.numframes );
+
+       SafeWrite( spriteouthandle, &spritetemp, 12 );
+
+//
+// write out the frames
+//
+       curframe = 0;
+
+       for ( i = 0 ; i < sprite.numframes ; i++ )
+       {
+               frames[i].width = LittleLong( frames[i].width );
+               frames[i].height = LittleLong( frames[i].height );
+               frames[i].origin_x = LittleLong( frames[i].origin_x );
+               frames[i].origin_y = LittleLong( frames[i].origin_y );
+       }
+       SafeWrite( spriteouthandle, frames, sizeof( frames[0] ) * sprite.numframes );
+
+       fclose( spriteouthandle );
+
+       spritename[0] = 0;      // clear for a new sprite
+       sprite.numframes = 0;
+}
+
+
+/*
+   ===============
+   Cmd_Load
+   ===============
+ */
+void Cmd_Load( void ){
+       char    *name;
+
+       GetScriptToken( false );
+
+       if ( g_release ) {
+               return;
+       }
+
+       name = ExpandPathAndArchive( token );
+
+       // load the image
+       printf( "loading %s\n", name );
+       TrueColorImage = LoadAnyImage( name, &byteimage, &lbmpalette, &byteimagewidth, &byteimageheight );
+
+       if ( !TrueColorImage ) {
+//             RemapZero (byteimage, lbmpalette, byteimagewidth, byteimageheight);
+       }
+       else
+       {
+               if ( longimage ) {
+                       free( longimage );
+               }
+               longimage = (unsigned *)byteimage;
+               longimagewidth = byteimagewidth;
+               longimageheight = byteimageheight;
+
+               byteimage = NULL;
+               byteimagewidth = 0;
+               byteimageheight = 0;
+       }
+}
+
+
+/*
+   ===============
+   Cmd_SpriteFrame
+   ===============
+ */
+
+void Cmd_SpriteFrame( void ){
+       int x,y,xl,yl,xh,yh,w,h;
+       dsprframe_t     *pframe;
+       int ox, oy, linedelta, size;
+//     byte                    *cropped;
+       char filename[1024];
+       miptex_t        *qtex;
+       miptex32_t      *qtex32;
+       unsigned        *destl, *sourcel;
+       unsigned bufferl[256 * 256];
+       byte            *dest, *source;
+       byte buffer[256 * 256];
+
+       GetScriptToken( false );
+       xl = atoi( token );
+       GetScriptToken( false );
+       yl = atoi( token );
+       GetScriptToken( false );
+       w = atoi( token );
+       GetScriptToken( false );
+       h = atoi( token );
+
+       // origin offset is optional
+       if ( ScriptTokenAvailable() ) {
+               GetScriptToken( false );
+               ox = atoi( token );
+               GetScriptToken( false );
+               oy = atoi( token );
+       }
+       else
+       {
+               ox = w / 2;
+               oy = h / 2;
+       }
+
+       if ( ( xl & 0x0f ) || ( yl & 0x0f ) || ( w & 0x0f ) || ( h & 0x0f ) ) {
+               Error( "Sprite dimensions not multiples of 16\n" );
+       }
+
+       if ( ( w > 256 ) || ( h > 256 ) ) {
+               Error( "Sprite has a dimension longer than 256" );
+       }
+
+       xh = xl + w;
+       yh = yl + h;
+
+       if ( sprite.numframes >= MAX_SPRFRAMES ) {
+               Error( "Too many frames; increase MAX_SPRFRAMES\n" );
+       }
+
+       pframe = &frames[sprite.numframes];
+       pframe->width = w;
+       pframe->height = h;
+       pframe->origin_x = ox;
+       pframe->origin_y = oy;
+
+       if ( g_release ) {
+               ReleaseFile( pframe->name );
+               return;
+       }
+
+       if ( TrueColorImage ) {
+               sprintf( filename, "%ssprites/%s/%s_%i.m32", g_outputDir, spr_prefix, spritename, sprite.numframes );
+               sprintf( pframe->name, "%s/%s_%i.m32", spr_prefix, spritename, sprite.numframes );
+
+               if ( g_release ) {
+                       return; // textures are only released by $maps
+
+               }
+               xh = xl + w;
+               yh = yl + h;
+
+               if ( xl >= longimagewidth || xh > longimagewidth ||
+                        yl >= longimageheight || yh > longimageheight ) {
+                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight );
+               }
+
+               sourcel = longimage + ( yl * longimagewidth ) + xl;
+               destl = bufferl;
+               linedelta = ( longimagewidth - w );
+
+               for ( y = yl ; y < yh ; y++ )
+               {
+                       for ( x = xl ; x < xh ; x++ )
+                       {
+                               *destl++ = *sourcel++;  // RGBA
+                       }
+                       sourcel += linedelta;
+               }
+
+               qtex32 = CreateMip32( bufferl, w, h, &size, true );
+
+               qtex32->contents = 0;
+               qtex32->value = 0;
+               strcpy( qtex32->name, pframe->name );
+               //
+               // write it out
+               //
+               printf( "writing %s\n", filename );
+               SaveFile( filename, (byte *)qtex32, size );
+
+               free( qtex32 );
+       }
+       else
+       {
+               sprintf( filename, "%ssprites/%s/%s_%i.m8", g_outputDir, spr_prefix, spritename, sprite.numframes );
+               sprintf( pframe->name, "%s/%s_%i.m8", spr_prefix, spritename, sprite.numframes );
+
+               if ( g_release ) {
+                       return; // textures are only released by $maps
+
+               }
+               xh = xl + w;
+               yh = yl + h;
+
+               if ( xl >= byteimagewidth || xh > byteimagewidth ||
+                        yl >= byteimageheight || yh > byteimageheight ) {
+                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
+               }
+
+               source = byteimage + yl * byteimagewidth + xl;
+               dest = buffer;
+               linedelta = byteimagewidth - w;
+
+               for ( y = yl ; y < yh ; y++ )
+               {
+                       for ( x = xl ; x < xh ; x++ )
+                       {
+                               *dest++ = *source++;
+                       }
+                       source += linedelta;
+               }
+
+               qtex = CreateMip( buffer, w, h, lbmpalette, &size, true );
+
+               qtex->flags = 0;
+               qtex->contents = 0;
+               qtex->value = 0;
+               strcpy( qtex->name, pframe->name );
+               //
+               // write it out
+               //
+               printf( "writing %s\n", filename );
+               SaveFile( filename, (byte *)qtex, size );
+
+               free( qtex );
+       }
+
+       sprite.numframes++;
+}
+
+
+/*
+   ==============
+   Cmd_SpriteName
+   ==============
+ */
+void Cmd_SpriteName( void ){
+       if ( sprite.numframes ) {
+               FinishSprite();
+       }
+
+       GetScriptToken( false );
+       strcpy( spritename, token );
+       memset( &sprite, 0, sizeof( sprite ) );
+       memset( &frames, 0, sizeof( frames ) );
+}
+
+
+/*
+   ===============
+   Cmd_Sprdir
+   ===============
+ */
+void Cmd_Sprdir( void ){
+       char filename[1024];
+
+       GetScriptToken( false );
+       strcpy( spr_prefix, token );
+       // create the directory if needed
+       sprintf( filename, "%sSprites", g_outputDir );
+       Q_mkdir( filename );
+       sprintf( filename, "%sSprites/%s", g_outputDir, spr_prefix );
+       Q_mkdir( filename );
+}
diff --git a/tools/heretic2/h2data/svdcmp.c b/tools/heretic2/h2data/svdcmp.c
new file mode 100644 (file)
index 0000000..14865af
--- /dev/null
@@ -0,0 +1,487 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+static double at,bt,ct;
+#define PYTHAG( a,b ) ( ( at = fabs( a ) ) > ( bt = fabs( b ) ) ? \
+                                               ( ct = bt / at,at * sqrt( 1.0 + ct * ct ) ) : ( bt ? ( ct = at / bt,bt * sqrt( 1.0 + ct * ct ) ) : 0.0 ) )
+
+static double maxarg1,maxarg2;
+#define MAX( a,b ) ( maxarg1 = ( a ),maxarg2 = ( b ),( maxarg1 ) > ( maxarg2 ) ? \
+                                        ( maxarg1 ) : ( maxarg2 ) )
+#define SIGN( a,b ) ( ( b ) >= 0.0 ? fabs( a ) : -fabs( a ) )
+
+void ntrerror( char *s ){
+       printf( "%s\n",s );
+       exit( 1 );
+}
+
+double *allocVect( int sz ){
+       double *ret;
+
+       ret = calloc( sizeof( double ), (size_t)sz );
+       return ret;
+}
+
+void freeVect( double *ret ){
+       free( ret );
+}
+
+double **allocMatrix( int r,int c ){
+       double **ret;
+
+       ret = calloc( sizeof( double ), (size_t)( r * c ) );
+       return ret;
+}
+
+void freeMatrix( double **ret,int r ){
+       free( ret );
+}
+
+void svdcmp( double** a, int m, int n, double* w, double** v ){
+       int flag,i,its,j,jj,k,l,nm;
+       double c,f,h,s,x,y,z;
+       double anorm = 0.0,g = 0.0,scale = 0.0;
+       double *rv1;
+       void nrerror();
+
+       if ( m < n ) {
+               ntrerror( "SVDCMP: You must augment A with extra zero rows" );
+       }
+       rv1 = allocVect( n );
+       for ( i = 1; i <= n; i++ ) {
+               l = i + 1;
+               rv1[i] = scale * g;
+               g = s = scale = 0.0;
+               if ( i <= m ) {
+                       for ( k = i; k <= m; k++ ) scale += fabs( a[k][i] );
+                       if ( scale ) {
+                               for ( k = i; k <= m; k++ ) {
+                                       a[k][i] /= scale;
+                                       s += a[k][i] * a[k][i];
+                               }
+                               f = a[i][i];
+                               g = -SIGN( sqrt( s ),f );
+                               h = f * g - s;
+                               a[i][i] = f - g;
+                               if ( i != n ) {
+                                       for ( j = l; j <= n; j++ ) {
+                                               for ( s = 0.0,k = i; k <= m; k++ ) s += a[k][i] * a[k][j];
+                                               f = s / h;
+                                               for ( k = i; k <= m; k++ ) a[k][j] += f * a[k][i];
+                                       }
+                               }
+                               for ( k = i; k <= m; k++ ) a[k][i] *= scale;
+                       }
+               }
+               w[i] = scale * g;
+               g = s = scale = 0.0;
+               if ( i <= m && i != n ) {
+                       for ( k = l; k <= n; k++ ) scale += fabs( a[i][k] );
+                       if ( scale ) {
+                               for ( k = l; k <= n; k++ ) {
+                                       a[i][k] /= scale;
+                                       s += a[i][k] * a[i][k];
+                               }
+                               f = a[i][l];
+                               g = -SIGN( sqrt( s ),f );
+                               h = f * g - s;
+                               a[i][l] = f - g;
+                               for ( k = l; k <= n; k++ ) rv1[k] = a[i][k] / h;
+                               if ( i != m ) {
+                                       for ( j = l; j <= m; j++ ) {
+                                               for ( s = 0.0,k = l; k <= n; k++ ) s += a[j][k] * a[i][k];
+                                               for ( k = l; k <= n; k++ ) a[j][k] += s * rv1[k];
+                                       }
+                               }
+                               for ( k = l; k <= n; k++ ) a[i][k] *= scale;
+                       }
+               }
+               anorm = MAX( anorm,( fabs( w[i] ) + fabs( rv1[i] ) ) );
+       }
+       for ( i = n; i >= 1; i-- ) {
+               if ( i < n ) {
+                       if ( g ) {
+                               for ( j = l; j <= n; j++ )
+                                       v[j][i] = ( a[i][j] / a[i][l] ) / g;
+                               for ( j = l; j <= n; j++ ) {
+                                       for ( s = 0.0,k = l; k <= n; k++ ) s += a[i][k] * v[k][j];
+                                       for ( k = l; k <= n; k++ ) v[k][j] += s * v[k][i];
+                               }
+                       }
+                       for ( j = l; j <= n; j++ ) v[i][j] = v[j][i] = 0.0;
+               }
+               v[i][i] = 1.0;
+               g = rv1[i];
+               l = i;
+       }
+       for ( i = n; i >= 1; i-- ) {
+               l = i + 1;
+               g = w[i];
+               if ( i < n ) {
+                       for ( j = l; j <= n; j++ ) a[i][j] = 0.0;
+               }
+               if ( g ) {
+                       g = 1.0 / g;
+                       if ( i != n ) {
+                               for ( j = l; j <= n; j++ ) {
+                                       for ( s = 0.0,k = l; k <= m; k++ ) s += a[k][i] * a[k][j];
+                                       f = ( s / a[i][i] ) * g;
+                                       for ( k = i; k <= m; k++ ) a[k][j] += f * a[k][i];
+                               }
+                       }
+                       for ( j = i; j <= m; j++ ) a[j][i] *= g;
+               }
+               else {
+                       for ( j = i; j <= m; j++ ) a[j][i] = 0.0;
+               }
+               ++a[i][i];
+       }
+       for ( k = n; k >= 1; k-- ) {
+               for ( its = 1; its <= 30; its++ ) {
+                       flag = 1;
+                       for ( l = k; l >= 1; l-- ) {
+                               nm = l - 1;
+                               if ( fabs( rv1[l] ) + anorm == anorm ) {
+                                       flag = 0;
+                                       break;
+                               }
+                               if ( fabs( w[nm] ) + anorm == anorm ) {
+                                       break;
+                               }
+                       }
+                       if ( flag ) {
+                               c = 0.0;
+                               s = 1.0;
+                               for ( i = l; i <= k; i++ ) {
+                                       f = s * rv1[i];
+                                       if ( fabs( f ) + anorm != anorm ) {
+                                               g = w[i];
+                                               h = PYTHAG( f,g );
+                                               w[i] = h;
+                                               h = 1.0 / h;
+                                               c = g * h;
+                                               s = ( -f * h );
+                                               for ( j = 1; j <= m; j++ ) {
+                                                       y = a[j][nm];
+                                                       z = a[j][i];
+                                                       a[j][nm] = y * c + z * s;
+                                                       a[j][i] = z * c - y * s;
+                                               }
+                                       }
+                               }
+                       }
+                       z = w[k];
+                       if ( l == k ) {
+                               if ( z < 0.0 ) {
+                                       w[k] = -z;
+                                       for ( j = 1; j <= n; j++ ) v[j][k] = ( -v[j][k] );
+                               }
+                               break;
+                       }
+                       if ( its == 30 ) {
+                               ntrerror( "No convergence in 30 SVDCMP iterations" );
+                       }
+                       x = w[l];
+                       nm = k - 1;
+                       y = w[nm];
+                       g = rv1[nm];
+                       h = rv1[k];
+                       f = ( ( y - z ) * ( y + z ) + ( g - h ) * ( g + h ) ) / ( 2.0 * h * y );
+                       g = PYTHAG( f,1.0 );
+                       f = ( ( x - z ) * ( x + z ) + h * ( ( y / ( f + SIGN( g,f ) ) ) - h ) ) / x;
+                       c = s = 1.0;
+                       for ( j = l; j <= nm; j++ ) {
+                               i = j + 1;
+                               g = rv1[i];
+                               y = w[i];
+                               h = s * g;
+                               g = c * g;
+                               z = PYTHAG( f,h );
+                               rv1[j] = z;
+                               c = f / z;
+                               s = h / z;
+                               f = x * c + g * s;
+                               g = g * c - x * s;
+                               h = y * s;
+                               y = y * c;
+                               for ( jj = 1; jj <= n; jj++ ) {
+                                       x = v[jj][j];
+                                       z = v[jj][i];
+                                       v[jj][j] = x * c + z * s;
+                                       v[jj][i] = z * c - x * s;
+                               }
+                               z = PYTHAG( f,h );
+                               w[j] = z;
+                               if ( z ) {
+                                       z = 1.0 / z;
+                                       c = f * z;
+                                       s = h * z;
+                               }
+                               f = ( c * g ) + ( s * y );
+                               x = ( c * y ) - ( s * g );
+                               for ( jj = 1; jj <= m; jj++ ) {
+                                       y = a[jj][j];
+                                       z = a[jj][i];
+                                       a[jj][j] = y * c + z * s;
+                                       a[jj][i] = z * c - y * s;
+                               }
+                       }
+                       rv1[l] = 0.0;
+                       rv1[k] = f;
+                       w[k] = x;
+               }
+       }
+       freeVect( rv1 );
+}
+
+
+
+void svbksb( double** u, double* w, double** v,int m, int n, double* b, double* x ){
+       int jj,j,i;
+       double s,*tmp;
+       tmp = allocVect( n );
+       for ( j = 1; j <= n; j++ )
+       {
+               s = 0.0;
+               if ( w[j] ) {
+                       for ( i = 1; i <= m; i++ )
+                               s += u[i][j] * b[i];
+                       s /= w[j];
+               }
+               tmp[j] = s;
+       }
+       for ( j = 1; j <= n; j++ )
+       {
+               s = 0.0;
+               for ( jj = 1; jj <= n; jj++ )
+                       s += v[j][jj] * tmp[jj];
+               x[j] = s;
+       }
+       freeVect( tmp );
+}
+
+#undef SIGN
+#undef MAX
+#undef PYTHAG
+
+
+#if 1
+void DOsvd( float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize ){
+       int usedfs;
+       int *remap;
+       int i,j;
+       double **da;
+       double **v;
+       double *w;
+       int DOFerr;
+       float mx;
+       int bestat;
+
+       if ( nframes > framesize ) {
+               usedfs = nframes;
+       }
+       else{
+               usedfs = framesize;
+       }
+
+       da = allocMatrix( usedfs,nframes );
+       v = allocMatrix( nframes,nframes );
+       w = allocVect( nframes );
+
+       DOFerr = 0; //false
+       for ( i = 0; i < nframes; i++ )
+       {
+               for ( j = 0; j < framesize; j++ )
+                       da[j + 1][i + 1] = a[i * framesize + j];
+               for (; j < usedfs; j++ )
+                       da[j + 1][i + 1] = 0.0;
+       }
+
+       svdcmp( da,usedfs,nframes,w,v );
+
+       remap = calloc( sizeof( int ), (size_t)nframes );
+
+
+       for ( i = 0; i < nframes; i++ )
+               remap[i] = -1;
+       for ( j = 0; j < compressedsize; j++ )
+       {
+               mx = -1.0f;
+               for ( i = 0; i < nframes; i++ )
+               {
+                       if ( remap[i] < 0 && fabs( w[i + 1] ) > mx ) {
+                               mx = (float) fabs( w[i + 1] );
+                               bestat = i;
+                       }
+               }
+
+               if ( mx > 0 ) {
+                       remap[bestat] = j;
+               }
+               else
+               {
+                       DOFerr = 1; //true
+               }
+       }
+
+       if ( DOFerr ) {
+               printf( "Warning:  To many degrees of freedom!  File size may increase\n" );
+
+               for ( i = 0; i < compressedsize; i++ )
+               {
+                       values[i] = 0;
+                       for ( j = 0; j < framesize; j++ )
+                               res[i * framesize + j] = 0;
+               }
+       }
+
+       for ( i = 0; i < nframes; i++ )
+       {
+               if ( remap[i] < 0 ) {
+                       w[i + 1] = 0.0;
+               }
+               else
+               {
+                       values[remap[i]] = (float) w[i + 1];
+                       for ( j = 0; j < framesize; j++ )
+                               res[remap[i] * framesize + j] = (float) da[j + 1][i + 1];
+               }
+       }
+       freeVect( w );
+       freeMatrix( v,nframes );
+       freeMatrix( da,framesize );
+       free( remap );
+}
+
+#else
+
+void DOsvd( float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize ){
+       int *remap;
+       int i,j;
+       int nrows;
+       nrows = nframes;
+       if ( nrows < framesize ) {
+               nrows = framesize;
+       }
+       double **da = allocMatrix( nrows,framesize );
+       double **v = allocMatrix( framesize,framesize );
+       double *w = allocVect( framesize );
+       float mx;
+       int bestat;
+
+       for ( j = 0; j < framesize; j++ )
+       {
+               for ( i = 0; i < nframes; i++ )
+                       da[j + 1][i + 1] = a[i * framesize + j];
+               for (; i < nrows; i++ )
+                       da[j + 1][i + 1] = 0.0;
+       }
+
+       svdcmp( da,nrows,framesize,w,v );
+
+       remap = new int[framesize];
+
+
+       for ( i = 0; i < framesize; i++ )
+               remap[i] = -1;
+       for ( j = 0; j < compressedsize; j++ )
+       {
+               mx = -1.0f;
+               for ( i = 0; i < framesize; i++ )
+               {
+                       if ( remap[i] < 0 && fabs( w[i + 1] ) > mx ) {
+                               mx = fabs( w[i + 1] );
+                               bestat = i;
+                       }
+               }
+               assert( mx > -.5f );
+               remap[bestat] = j;
+       }
+       // josh **DO NOT** put your dof>nframes mod here
+       for ( i = 0; i < framesize; i++ )
+       {
+               if ( remap[i] < 0 ) {
+                       w[i + 1] = 0.0;
+               }
+               else
+               {
+                       values[remap[i]] = w[i + 1];
+                       for ( j = 0; j < framesize; j++ )
+                               res[remap[i] * framesize + j] = v[j + 1][i + 1];
+               }
+       }
+       freeVect( w );
+       freeMatrix( v,framesize );
+       freeMatrix( da,nrows );
+       delete[] remap;
+}
+
+#endif
+
+void DOsvdPlane( float *pnts,int npnts,float *n,float *base ){
+       int i,j;
+       double **da = allocMatrix( npnts,3 );
+       double **v = allocMatrix( 3,3 );
+       double *w = allocVect( 3 );
+       float mn = 1E30f;
+       int bestat;
+
+
+       assert( npnts >= 3 );
+       base[0] = pnts[0];
+       base[1] = pnts[1];
+       base[2] = pnts[2];
+       for ( i = 1; i < npnts; i++ )
+       {
+               for ( j = 0; j < 3; j++ )
+                       base[j] += pnts[i * 3 + j];
+       }
+       base[0] /= (float)( npnts );
+       base[1] /= (float)( npnts );
+       base[2] /= (float)( npnts );
+
+       for ( i = 0; i < 3; i++ )
+       {
+               for ( j = 0; j < npnts; j++ )
+                       da[j + 1][i + 1] = pnts[j * 3 + i] - base[i];
+       }
+
+       svdcmp( da,npnts,3,w,v );
+       for ( i = 0; i < 3; i++ )
+       {
+               if ( fabs( w[i + 1] ) < mn ) {
+                       mn = (float) fabs( w[i + 1] );
+                       bestat = i;
+               }
+       }
+       n[0] = (float) v[1][bestat + 1];
+       n[1] = (float) v[2][bestat + 1];
+       n[2] = (float) v[3][bestat + 1];
+       freeVect( w );
+       freeMatrix( v,3 );
+       freeMatrix( da,npnts );
+}
diff --git a/tools/heretic2/h2data/tables.c b/tools/heretic2/h2data/tables.c
new file mode 100644 (file)
index 0000000..ad86c1e
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qdata.h"
+
+/*
+   =============================================================================
+
+   ALPHALIGHT GENERATION
+
+   Find alphamap values that best match modulated lightmap values
+
+   This isn't used anymore, but I'm keeping it around...
+   =============================================================================
+ */
+
+unsigned short alphamap[32 * 32 * 32];
+unsigned char inverse16to8table[65536];
+
+/*
+   static int FindNearestColor( unsigned int color )
+   {
+    int i;
+    int closest_so_far = 0;
+    float closest_distance_so_far = 100000000;
+    float d;
+    float r[2], g[2], b[2];
+
+    // incoming color is assumed to be in 0xRRGGBB format
+    r[0] = ( color & 31 ) << 3;
+    g[0] = ( ( color >> 5 ) & 63 ) << 2;
+    b[0] = ( ( color >> 11 ) & 31 ) << 3;
+
+    for ( i = 0; i < 256; i++ )
+    {
+        r[1] = ( d_8to24table[i] >> 0 ) & 0xFF;
+        g[1] = ( d_8to24table[i] >> 8 ) & 0xFF;
+        b[1] = ( d_8to24table[i] >> 16 ) & 0xFF;
+
+        d = ( r[1] - r[0] ) * ( r[1] - r[0] ) +
+            ( g[1] - g[0] ) * ( g[1] - g[0] ) +
+            ( b[1] - b[0] ) * ( b[1] - b[0] );
+
+        if ( d < closest_distance_so_far )
+        {
+            closest_distance_so_far = d;
+            closest_so_far = i;
+        }
+    }
+
+    return closest_so_far;
+   }
+ */
+
+extern byte BestColor( int, int, int, int, int );
+
+void Inverse16_BuildTable( void ){
+       int i;
+
+       /*
+       ** create the 16-to-8 table
+       */
+       for ( i = 0; i < 65536; i++ )
+       {
+               int r = i & 31;
+               int g = ( i >> 5 ) & 63;
+               int b = ( i >> 11 ) & 31;
+
+               r <<= 3;
+               g <<= 2;
+               b <<= 3;
+
+               inverse16to8table[i] = BestColor( r, g, b, 0, 255 );
+       }
+}
+
+void Alphalight_Thread( int i ){
+       int j;
+       float r, g, b;
+       float mr, mg, mb, ma;
+       float distortion, bestdistortion;
+       float v;
+
+       r = ( i >> 10 ) * ( 1.0 / 16 );
+       g = ( ( i >> 5 ) & 31 )  * ( 1.0 / 16 );
+       b = ( i & 31 ) * ( 1.0 / 16 );
+
+       bestdistortion = 999999;
+       for ( j = 0 ; j < 16 * 16 * 16 * 16 ; j++ )
+       {
+               mr = ( j >> 12 ) * ( 1.0 / 16 );
+               mg = ( ( j >> 8 ) & 15 ) * ( 1.0 / 16 );
+               mb = ( ( j >> 4 ) & 15 ) * ( 1.0 / 16 );
+               ma = ( j & 15 ) * ( 1.0 / 16 );
+
+               v = r * 0.5 - ( mr * ma + 0.5 * ( 1.0 - ma ) );
+               distortion = v * v;
+               v = g * 0.5 - ( mg * ma + 0.5 * ( 1.0 - ma ) );
+               distortion += v * v;
+               v = b * 0.5 - ( mb * ma + 0.5 * ( 1.0 - ma ) );
+               distortion += v * v;
+
+               distortion *= 1.0 + ma * 4;
+
+               if ( distortion < bestdistortion ) {
+                       bestdistortion = distortion;
+                       alphamap[i] = j;
+               }
+       }
+}
+
+void Cmd_Alphalight( void ){
+       char savename[1024];
+
+       GetScriptToken( false );
+
+       if ( g_release ) {
+               ReleaseFile( token );
+               return;
+       }
+
+       sprintf( savename, "%s%s", gamedir, token );
+       printf( "Building alphalight table...\n" );
+
+       RunThreadsOnIndividual( 32 * 32 * 32, true, Alphalight_Thread );
+
+       SaveFile( savename, (byte *)alphamap, sizeof( alphamap ) );
+}
+
+
+void Cmd_Inverse16Table( void ){
+       char savename[1024];
+
+       if ( g_release ) {
+               sprintf( savename, "pics/16to8.dat" );
+               ReleaseFile( savename );
+               return;
+       }
+
+       sprintf( savename, "%spics/16to8.dat", gamedir );
+       printf( "Building inverse 16-to-8 table...\n" );
+
+       Inverse16_BuildTable();
+
+       SaveFile( savename, (byte *) inverse16to8table, sizeof( inverse16to8table ) );
+}
diff --git a/tools/heretic2/h2data/tmix.c b/tools/heretic2/h2data/tmix.c
new file mode 100644 (file)
index 0000000..936cd6e
--- /dev/null
@@ -0,0 +1,671 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qdata.h"
+#include "flex.h"
+
+#define     MAXFILES    2048
+
+#if !GDEF_OS_WINDOWS
+#define strlwr strlower
+#endif // !GDEF_OS_WINDOWS
+
+typedef struct
+{
+       int x;
+       int y;
+       int w;
+       int h;
+       int cw;
+       int ch;
+       int rw;
+       int index;
+       int depth;
+       int col;
+       int baseline;
+       char name[128];
+} Coords;
+
+int filenum;
+int valid;
+Coords in[MAXFILES];
+Coords out;
+char outscript[256];
+char sourcedir[256];
+char outusage[256];
+char root[32];
+
+int destsize = 0;
+byte            *pixels = NULL;             // Buffer to load image
+long            *outpixels = NULL;          // Buffer to store combined textures
+long            *usagemap = NULL;           // Buffer of usage map
+void            *bmptemp = NULL;            // Buffer of usage map
+byte            *map = NULL;
+
+int xcharsize;
+int ycharsize;
+int dosort = 0;
+int missed = 0;
+int overlap = 0;
+int nobaseline = 0;
+int percent;
+
+//////////////////////////////////////////////////
+// Setting the char based usage map                            //
+//////////////////////////////////////////////////
+
+byte    TryPlace( Coords *coord ){
+       int x, y;
+       byte entry = 0;
+       byte    *mapitem;
+
+       mapitem = map + ( coord->x / xcharsize ) + ( ( coord->y / ycharsize ) * out.cw );
+
+       for ( y = 0; y < coord->ch; y++, mapitem += out.cw - coord->cw )
+       {
+               for ( x = 0; x < coord->cw; x++ )
+               {
+                       if ( entry |= *mapitem++ & 8 ) {
+                               return( entry );
+                       }
+               }
+       }
+       return( entry );
+}
+
+void    SetMap( Coords *coord ){
+       int x, y;
+       byte    *mapitem;
+
+       mapitem = map + ( coord->x / xcharsize ) + ( ( coord->y / ycharsize ) * out.cw );
+
+       for ( y = 0; y < coord->ch; y++, mapitem += out.cw - coord->cw )
+               for ( x = 0; x < coord->cw; x++ )
+                       *mapitem++ |= 8;
+}
+
+//////////////////////////////////////////////////
+// Setting the pixel based usage map                   //
+//////////////////////////////////////////////////
+
+void    CheckOverlap( Coords *coord ){
+       int x;
+       int y;
+       long        *dest;
+
+       x = coord->x;
+       y = coord->y;
+
+       dest = (long *)( usagemap + x + ( y * out.w ) );
+
+       for ( y = 0; y < coord->h; y++, dest += out.w - coord->w )
+       {
+               for ( x = 0; x < coord->w; x++ )
+               {
+                       if ( *dest++ ) {
+                               overlap++;
+                               return;
+                       }
+               }
+       }
+}
+
+void    SetUsageMap( Coords *coord ){
+       int x;
+       int y;
+       long        *dest;
+
+       x = coord->x;
+       y = coord->y;
+
+       dest = (long *)( usagemap + x + ( y * out.w ) );
+
+       for ( y = 0; y < coord->h; y++, dest += out.w - coord->w )
+       {
+               for ( x = 0; x < coord->w; x++ )
+               {
+                       *dest++ = coord->col;
+               }
+       }
+}
+
+//////////////////////////////////////////////////
+// Flips the BMP image to the correct way up   //
+//////////////////////////////////////////////////
+
+void    CopyLine( byte *dest, byte *src, int size ){
+       int x;
+
+       for ( x = 0; x < size; x++ )
+               *dest++ = *src++;
+}
+
+/****************************************************/
+/* Printing headers etc                                                                */
+/****************************************************/
+
+void RemoveLeading( char *name ){
+       int i;
+       char temp[128];
+
+       for ( i = strlen( name ) - 1; i > 0; i-- )
+       {
+               if ( ( name[i] == '\\' ) || ( name[i] == '/' ) ) {
+                       strcpy( temp, name + i + 1 );
+                       strcpy( name, temp );
+                       return;
+               }
+       }
+}
+
+void RemoveExt( char *name ){
+       while ( ( *name != '.' ) && *name )
+               name++;
+       *name = 0;
+}
+
+/****************************************************/
+/* Misc calcualtions                                                           */
+/****************************************************/
+
+int TotalArea(){
+       int i;
+       int total = 0;
+
+       for ( i = 0; i < ( filenum + 2 ); i++ )
+               total += in[i].w * in[i].h;
+
+       return( total );
+}
+
+/****************************************************/
+/* Setup and checking of all info                                      */
+/****************************************************/
+
+void    InitVars(){
+       filenum = 0;
+       valid = 0;
+       dosort = 0;
+       missed = 0;
+       overlap = 0;
+       nobaseline = 0;
+
+       memset( outscript, 0, sizeof( outscript ) );
+       memset( outscript, 0, sizeof( sourcedir ) );
+       memset( outscript, 0, sizeof( outusage ) );
+       memset( outscript, 0, sizeof( root ) );
+
+       memset( in, 0, sizeof( in ) );
+       memset( &out, 0, sizeof( out ) );
+}
+void Cleanup(){
+       if ( pixels ) {
+               free( pixels );
+       }
+       if ( usagemap ) {
+               free( usagemap );
+       }
+       if ( outpixels ) {
+               free( outpixels );
+       }
+       if ( bmptemp ) {
+               free( bmptemp );
+       }
+       if ( map ) {
+               free( map );
+       }
+}
+
+typedef struct glxy_s
+{
+       float xl, yt, xr, yb;
+       int w, h, baseline;
+} glxy_t;
+
+int SaveScript( char *name ){
+       FILE        *fp;
+       int i, j;
+       glxy_t buff;
+
+       if ( fp = fopen( name, "wb" ) ) {
+               for ( j = 0; j < filenum; j++ )
+               {
+                       for ( i = 0; i < filenum; i++ )
+                       {
+                               if ( in[i].index == j ) {
+                                       if ( in[i].depth ) {
+                                               buff.xl = (float)in[i].x / (float)out.w;
+                                               buff.yt = (float)in[i].y / (float)out.h;
+                                               buff.xr = ( (float)in[i].w + (float)in[i].x ) / (float)out.w;
+                                               buff.yb = ( (float)in[i].h + (float)in[i].y ) / (float)out.h;
+                                               buff.w = in[i].w;
+                                               buff.h = in[i].h;
+                                               buff.baseline = in[i].baseline;
+                                       }
+                                       else
+                                       {
+                                               memset( &buff, 0, sizeof( glxy_t ) );
+                                       }
+                                       fwrite( &buff, 1, sizeof( glxy_t ), fp );
+                                       i = filenum;
+                               }
+                       }
+               }
+               fclose( fp );
+               return( true );
+       }
+       else{
+               return( false );
+       }
+}
+
+int     GetScriptInfo( char *name ){
+       FILE        *fp;
+       char buffer[256];
+       char tempbuff[256];
+       char delims[] = {" \t,\n"};
+
+       printf( "Opening script file %s.\n", name );
+
+       if ( fp = fopen( name, "r" ) ) {
+               while ( fgets( buffer, 256, fp ) )
+               {
+                       if ( strncmp( buffer, "//", 2 ) && strncmp( buffer, "\n", 1 ) ) {
+                               strupr( buffer );
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "OUTPUT" ) == 0 ) {
+                                       strcpy( out.name, strtok( NULL, delims ) );
+                                       strlwr( out.name );
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "SOURCEDIR" ) == 0 ) {
+                                       strcpy( tempbuff, strtok( NULL, delims ) );
+                                       strcpy( sourcedir, ExpandPathAndArchive( tempbuff ) );
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "DOSORT" ) == 0 ) {
+                                       dosort = 1;
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "XCHARSIZE" ) == 0 ) {
+                                       xcharsize = strtol( strtok( NULL, delims ), NULL, 0 );
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "YCHARSIZE" ) == 0 ) {
+                                       ycharsize = strtol( strtok( NULL, delims ), NULL, 0 );
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "OUTSCRIPT" ) == 0 ) {
+                                       strcpy( outscript, strtok( NULL, delims ) );
+                                       strlwr( outscript );
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "OUTUSAGE" ) == 0 ) {
+                                       strcpy( outusage, strtok( NULL, delims ) );
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "POS" ) == 0 ) {
+                                       out.w = strtol( strtok( NULL, delims ), NULL, 0 );
+                                       out.h = strtol( strtok( NULL, delims ), NULL, 0 );
+                               }
+
+                               strcpy( tempbuff, buffer );
+                               if ( strcmp( strtok( tempbuff, delims ), "FILE" ) == 0 ) {
+                                       strcpy( in[filenum].name, strtok( NULL, delims ) );
+                                       in[filenum].x = strtol( strtok( NULL, delims ), NULL, 0 );
+                                       in[filenum].y = strtol( strtok( NULL, delims ), NULL, 0 );
+                                       in[filenum].col = strtol( strtok( NULL, delims ), NULL, 0 );
+                                       filenum++;
+                               }
+                       }
+               }
+               fclose( fp );
+               return( true );
+       }
+       else
+       {
+               printf( "ERROR : Could not open script file.\n" );
+               return( false );
+       }
+}
+
+int CheckVars(){
+       int i;
+
+       if ( out.name[0] == 0 ) {
+               printf( "ERROR : No output name specified.\n" );
+               return( false );
+       }
+       if ( ( out.w <= 0 ) || ( out.h <= 0 ) ) {
+               printf( "ERROR : Invalid VRAM coordinates.\n" );
+               return( false );
+       }
+       if ( filenum == 0 ) {
+               printf( "ERROR : No input files specified.\n" );
+               return( false );
+       }
+       for ( i = 0; i < filenum; i++ )
+               if ( in[i].name[0] == 0 ) {
+                       printf( "ERROR : Input filename invalid.\n" );
+                       return( false );
+               }
+       return( true );
+}
+
+// Makes sure texture is totally within the output area
+
+int CheckCoords( Coords *coord ){
+       if ( ( coord->x + coord->w ) > out.w ) {
+               return( false );
+       }
+       if ( ( coord->y + coord->h ) > out.h ) {
+               return( false );
+       }
+
+       return( true );
+}
+// Gets the width, height, palette width and palette height of each BMP file
+
+int     GetFileDimensions(){
+       int i;
+       int width, height;
+       char name[128];
+
+       for ( i = 0; i < filenum; i++ )
+       {
+               in[i].index = i;
+
+               strcpy( name, sourcedir );
+               strcat( name, in[i].name );
+               printf( "Getting file dimensions, file : %s        \r", in[i].name );
+               if ( FileExists( name ) ) {
+                       LoadAnyImage( name, NULL, NULL, &width, &height );
+                       in[i].depth = 32;
+                       in[i].rw = width;
+                       in[i].w = width;                        // makes it width in
+                       in[i].h = height;
+                       in[i].cw = ( in[i].w + ( xcharsize - 1 ) ) / xcharsize;
+                       in[i].ch = ( in[i].h + ( ycharsize - 1 ) ) / ycharsize;
+
+                       if ( !CheckCoords( &in[i] ) && ( in[i].x >= 0 ) ) {
+                               printf( "Error : texture %s out of bounds.\n", in[i].name );
+                               return( false );
+                       }
+                       valid++;
+               }
+               else
+               {
+                       in[i].depth = 0;
+                       in[i].x = -1;
+                       in[i].y = -1;
+                       in[i].w = 0;
+                       in[i].h = 0;
+               }
+       }
+       printf( "\n\n" );
+       return( true );
+}
+
+// Sorts files into order for optimal space finding
+// Fixed position ones first, followed by the others in descending size
+// The theory being that it is easier to find space for smaller textures.
+// size = (width + height)
+// For space finding it is easier to place a 32x32 than a 128x2
+
+#define WEIGHT  0x8000
+
+void    Swap( Coords *a, Coords *b ){
+       Coords c;
+
+       c = *a;
+       *a = *b;
+       *b = c;
+}
+
+void    SortInNames(){
+       int i, j;
+       int largest, largcount;
+       int size;
+
+       printf( "Sorting filenames by size.\n\n" );
+
+       for ( j = 0; j < filenum; j++ )
+       {
+               largest = -1;
+               largcount = -1;
+
+               for ( i = j; i < filenum; i++ )
+               {
+                       if ( in[i].depth ) {
+                               size = in[i].w + in[i].h;
+
+                               if ( ( in[i].x < 0 ) && ( size > largest ) ) {
+                                       largcount = i;
+                                       largest = size;
+                               }
+                       }
+               }
+               if ( ( largcount >= 0 ) && ( largcount != j ) ) {
+                       Swap( &in[j], &in[largcount] );
+               }
+       }
+}
+
+int SetVars( char *name ){
+       if ( !GetScriptInfo( name ) ) {
+               return( false );
+       }
+
+       if ( !CheckVars() ) {
+               return( false );
+       }
+
+       destsize = out.w * out.h;
+
+       out.cw = out.w / xcharsize;
+       out.ch = out.h / ycharsize;
+
+       if ( ( usagemap = (long *)SafeMalloc( destsize * 4, "" ) ) == NULL ) {
+               return( false );
+       }
+       if ( ( outpixels = (long *)SafeMalloc( destsize * 4, "" ) ) == NULL ) {
+               return( false );
+       }
+       if ( ( bmptemp = (void *)SafeMalloc( destsize * 4, "" ) ) == NULL ) {
+               return( false );
+       }
+       if ( ( map = (byte *)SafeMalloc( destsize / ( xcharsize * ycharsize ), "" ) ) == NULL ) {
+               return( false );
+       }
+
+       if ( GetFileDimensions() == false ) {
+               return( false );
+       }
+
+       if ( dosort ) {
+               SortInNames();
+       }
+
+       return( true );
+}
+/****************************************************/
+/* Actual copying routines                                                     */
+/****************************************************/
+
+int FindCoords( Coords *coord ){
+       int tx, ty;
+
+       if ( coord->x >= 0 ) {
+               SetMap( coord );
+               return( true );
+       }
+       else
+       {
+               for ( ty = 0; ty < out.ch; ty++ )
+               {
+                       for ( tx = 0; tx < out.cw; tx++ )
+                       {
+                               coord->x = ( tx * xcharsize );
+                               coord->y = ( ty * ycharsize );
+
+                               if ( CheckCoords( coord ) && !TryPlace( coord ) ) {
+                                       SetMap( coord );
+                                       return( true );
+                               }
+                       }
+               }
+       }
+       coord->x = -1;
+       coord->y = -1;
+
+       return( false );
+}
+
+void CheckBaseline( int i ){
+       int y;
+       long    *pix;
+
+       in[i].baseline = -1;
+       pix = (long *)pixels;
+
+       for ( y = 0; y < in[i].h; y++, pix += in[i].w )
+       {
+               if ( ( *pix & 0x00ffffff ) == 0x00ff00ff ) {
+                       in[i].baseline = y;
+                       break;
+               }
+       }
+       pix = (long *)pixels;
+       for ( y = 0; y < in[i].w * in[i].h; y++, pix++ )
+       {
+               if ( ( *pix & 0x00ffffff ) == 0x00ff00ff ) {
+                       *pix = 0;
+               }
+       }
+
+       if ( in[i].baseline == -1 ) {
+               printf( "\nERROR : %s has no baseline\n", in[i].name );
+               nobaseline++;
+       }
+}
+
+void    CopyToMain32( Coords *coord ){
+       int x;
+       int y;
+       long        *source;
+       long        *dest;
+
+       x = coord->x;
+       y = coord->y;
+
+       source = (long *)pixels;
+       dest = (long *)( outpixels + x + ( y * out.w ) );
+
+       for ( y = 0; y < coord->h; y++, dest += out.w - coord->w )
+       {
+               for ( x = 0; x < coord->w; x++ )
+               {
+                       *dest++ = *source++;
+               }
+       }
+}
+
+void CreateMain(){
+       int i, count;
+       int width, height;
+       char name[128];
+
+       for ( i = 0, count = 0; i < filenum; i++ )
+       {
+               if ( in[i].depth ) {
+                       printf( "\rProcessing %d of %d (%d missed, %d overlapping, %d nobase)\r", count + 1, valid, missed, overlap, nobaseline );
+                       count++;
+                       if ( !FindCoords( &in[i] ) ) {
+                               missed++;
+                       }
+                       else
+                       {
+                               strcpy( name, sourcedir );
+                               strcat( name, in[i].name );
+                               LoadAnyImage( name, &pixels, NULL, &width, &height );
+                               CheckBaseline( i );
+                               CheckOverlap( &in[i] );
+                               CopyToMain32( &in[i] );
+                               SetUsageMap( &in[i] );
+                       }
+               }
+       }
+}
+
+void Cmd_TextureMix(){
+       miptex32_t      *qtex32;
+       char filename[1024];
+       int size;
+
+       InitVars();
+
+       GetScriptToken( false );
+
+       strcpy( root, token );
+       RemoveExt( root );
+       RemoveLeading( root );
+
+       strcpy( filename, ExpandPathAndArchive( token ) );
+       if ( SetVars( filename ) ) {
+               // Create combined texture
+               percent = ( ( TotalArea() * 100 ) / ( out.w * out.h ) );
+               printf( "Total area consumed : %d%%\n", percent );
+               printf( "Texture resolution  : %dx%d pixels.\n", xcharsize, ycharsize );
+               CreateMain();
+
+               // Save image as m32
+               sprintf( filename, "%spics/misc/%s.m32", gamedir, out.name );
+               qtex32 = CreateMip32( (unsigned *)outpixels, out.w, out.h, &size, false );
+
+               qtex32->contents = 0;
+               qtex32->value = 0;
+               qtex32->scale_x = 1.0;
+               qtex32->scale_y = 1.0;
+               sprintf( qtex32->name, "misc/%s", out.name );
+
+               printf( "\n\nwriting %s\n", filename );
+               SaveFile( filename, (byte *)qtex32, size );
+               free( qtex32 );
+
+               // Save out script file
+               sprintf( filename, "%spics/misc/%s.fnt", gamedir, outscript );
+               printf( "Writing %s as script file\n", filename );
+               if ( !SaveScript( filename ) ) {
+                       printf( "Unable to save output script.\n" );
+               }
+       }
+       printf( "Everythings groovy.\n" );
+       Cleanup();
+}
+
+// end
diff --git a/tools/heretic2/h2data/video.c b/tools/heretic2/h2data/video.c
new file mode 100644 (file)
index 0000000..51bf462
--- /dev/null
@@ -0,0 +1,1154 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// To do
+
+// Sound error handling (when sound too short)
+// rle b4 huffing
+// adpcm encoding of sound
+
+#if 0
+#include "qdata.h"
+#include "flex.h"
+#include "fc.h"
+#include "adpcm.h"
+
+#define MIN_REPT    15
+#define MAX_REPT    0
+#define HUF_TOKENS  ( 256 + MAX_REPT )
+
+#define BLOCKSIZE   8
+
+#define M_PI        3.14159265358979323846  // matches value in gcc v2 math.h
+#define SQRT2       1.414213562
+
+typedef struct hnode_s
+{
+       int count;
+       qboolean used;
+       int children[2];
+} hnode_t;
+
+typedef struct
+{
+       int rate;
+       int width;
+       int channels;
+       int loopstart;
+       int samples;
+       int dataofs;                // chunk starts this many bytes from file start
+} wavinfo_t;
+
+// These weren`t picked out my ass....
+// They were defined at http://www.rahul.net/jfm/dct.html
+// However, I think he plucked them out of his ass.....
+
+float Quantise[BLOCKSIZE * BLOCKSIZE];
+
+float LUT_Quantise[BLOCKSIZE * BLOCKSIZE] =
+{
+       16.0F / 16.0F, 11.0F / 16.0F, 10.0F / 16.0F, 16.0F / 16.0F, 24.0F / 16.0F, 40.0F / 16.0F, 51.0F / 16.0F, 61.0F / 16.0F,
+       12.0F / 16.0F, 13.0F / 16.0F, 14.0F / 16.0F, 19.0F / 16.0F, 26.0F / 16.0F, 58.0F / 16.0F, 60.0F / 16.0F, 55.0F / 16.0F,
+       14.0F / 16.0F, 13.0F / 16.0F, 16.0F / 16.0F, 24.0F / 16.0F, 40.0F / 16.0F, 57.0F / 16.0F, 69.0F / 16.0F, 56.0F / 16.0F,
+       14.0F / 16.0F, 17.0F / 16.0F, 22.0F / 16.0F, 29.0F / 16.0F, 51.0F / 16.0F, 87.0F / 16.0F, 80.0F / 16.0F, 62.0F / 16.0F,
+       18.0F / 16.0F, 22.0F / 16.0F, 37.0F / 16.0F, 56.0F / 16.0F, 68.0F / 16.0F,109.0F / 16.0F,103.0F / 16.0F, 77.0F / 16.0F,
+       24.0F / 16.0F, 35.0F / 16.0F, 55.0F / 16.0F, 64.0F / 16.0F, 81.0F / 16.0F,104.0F / 16.0F,113.0F / 16.0F, 92.0F / 16.0F,
+       49.0F / 16.0F, 64.0F / 16.0F, 78.0F / 16.0F, 87.0F / 16.0F,103.0F / 16.0F,121.0F / 16.0F,120.0F / 16.0F,101.0F / 16.0F,
+       72.0F / 16.0F, 92.0F / 16.0F, 95.0F / 16.0F, 98.0F / 16.0F,112.0F / 16.0F,100.0F / 16.0F,103.0F / 16.0F, 99.0F / 16.0F
+};
+
+int LUT_ZZ[BLOCKSIZE * BLOCKSIZE] =
+{
+       0,
+       1,  8,
+       16,  9,  2,
+       3, 10, 17, 24,
+       32, 25, 18, 11,  4,
+       5, 12, 19, 26, 33, 40,
+       48, 41, 34, 27, 20, 13, 6,
+       7, 14, 21, 28, 35, 42, 49, 56,
+       57, 50, 43, 36, 29, 22, 15,
+       23, 30, 37, 44, 51, 58,
+       59, 52, 45, 38, 31,
+       39, 46, 53, 60,
+       61, 54, 47,
+       55, 62,
+       63
+};
+
+char base[32];
+
+byte            *soundtrack;
+
+byte scaled[256][HUF_TOKENS];
+unsigned int charbits1[256][HUF_TOKENS];
+int charbitscount1[256][HUF_TOKENS];
+hnode_t hnodes1[256][HUF_TOKENS * 2];
+int numhnodes1[256];
+int order0counts[256];
+int numhnodes;
+hnode_t hnodes[512];
+unsigned charbits[256];
+int charbitscount[256];
+
+CineHead_t cinehead;
+
+byte            *data_p;
+byte            *iff_end;
+byte            *last_chunk;
+byte            *iff_data;
+int iff_chunk_len;
+
+float dctbase[BLOCKSIZE][BLOCKSIZE];
+float red[BLOCKSIZE * BLOCKSIZE];
+float green[BLOCKSIZE * BLOCKSIZE];
+float blue[BLOCKSIZE * BLOCKSIZE];
+float temp[BLOCKSIZE * BLOCKSIZE];
+
+wavinfo_t wavinfo;
+adpcm_t adpcm;
+
+/*
+   ===============================================================================
+
+   WAV loading
+
+   ===============================================================================
+ */
+
+/* Intel ADPCM step variation table */
+static int indexTable[16] =
+{
+       -1, -1, -1, -1, 2, 4, 6, 8,
+       -1, -1, -1, -1, 2, 4, 6, 8,
+};
+
+static int stepsizeTable[89] =
+{
+       7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+       19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+       50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+       130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+       337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+       876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+       2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+       5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+       15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
+#if 0
+static void adpcm_decoder( char *indata, short *outdata, int len, adpcm_state_t *state ){
+       signed char *inp;       /* Input buffer pointer */
+       short *outp;        /* output buffer pointer */
+       int sign;           /* Current adpcm sign bit */
+       int delta;          /* Current adpcm output value */
+       int step;           /* Stepsize */
+       int valpred;        /* Predicted value */
+       int vpdiff;         /* Current change to valpred */
+       int index;          /* Current step change index */
+       int inputbuffer;        /* place to keep next 4-bit value */
+       int bufferstep;     /* toggle between inputbuffer/input */
+
+       outp = outdata;
+       inp = (signed char *)indata;
+
+       valpred = state->valprev;
+       index = state->index;
+       step = stepsizeTable[index];
+
+       bufferstep = 0;
+
+       for (; len > 0; len-- )
+       {
+               /* Step 1 - get the delta value */
+               if ( bufferstep ) {
+                       delta = inputbuffer & 0xf;
+               }
+               else
+               {
+                       inputbuffer = *inp++;
+                       delta = ( inputbuffer >> 4 ) & 0xf;
+               }
+               bufferstep = !bufferstep;
+
+               /* Step 2 - Find new index value (for later) */
+               index += indexTable[delta];
+               if ( index < 0 ) {
+                       index = 0;
+               }
+               if ( index > 88 ) {
+                       index = 88;
+               }
+
+               /* Step 3 - Separate sign and magnitude */
+               sign = delta & 8;
+               delta = delta & 7;
+
+               /* Step 4 - Compute difference and new predicted value */
+               /*
+               ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
+               ** in adpcm_coder.
+               */
+               vpdiff = step >> 3;
+               if ( delta & 4 ) {
+                       vpdiff += step;
+               }
+               if ( delta & 2 ) {
+                       vpdiff += step >> 1;
+               }
+               if ( delta & 1 ) {
+                       vpdiff += step >> 2;
+               }
+
+               if ( sign ) {
+                       valpred -= vpdiff;
+               }
+               else{
+                       valpred += vpdiff;
+               }
+
+               /* Step 5 - clamp output value */
+               if ( valpred > 32767 ) {
+                       valpred = 32767;
+               }
+               else if ( valpred < -32768 ) {
+                       valpred = -32768;
+               }
+
+               /* Step 6 - Update step value */
+               step = stepsizeTable[index];
+
+               /* Step 7 - Output value */
+               *outp++ = valpred;
+       }
+
+       state->valprev = valpred;
+       state->index = index;
+}
+#endif
+
+void adpcm_coder( short *inp, adpcm_t *adpcm ){
+       int val;                        /* Current input sample value */
+       int sign;                       /* Current adpcm sign bit */
+       int delta;                      /* Current adpcm output value */
+       int diff;                       /* Difference between val and valprev */
+       int step;                       /* Stepsize */
+       int valpred;                    /* Predicted output value */
+       int vpdiff;                     /* Current change to valpred */
+       int index;                      /* Current step change index */
+       int outputbuffer;               /* place to keep previous 4-bit value */
+       int bufferstep;                 /* toggle between outputbuffer/output */
+       adpcm_state_t   *state;
+       char            *outp;
+       int len;
+
+       state = &adpcm->state;
+       len = state->count;
+       outp = adpcm->adpcm;
+
+       valpred = state->in_valprev;
+       index = state->in_index;
+       step = stepsizeTable[index];
+
+       bufferstep = 1;
+       while ( len-- )
+       {
+               val = *inp++;
+
+               /* Step 1 - compute difference with previous value */
+               diff = val - valpred;
+               sign = ( diff < 0 ) ? 8 : 0;
+               if ( sign ) {
+                       diff = -diff;
+               }
+
+               /* Step 2 - Divide and clamp */
+               /* Note:
+               ** This code *approximately* computes:
+               **        delta = diff*4/step;
+               **        vpdiff = (delta+0.5)*step/4;
+               ** but in shift step bits are dropped. The net result of this is
+               ** that even if you have fast mul/div hardware you cannot put it to
+               ** good use since the fixup would be too expensive.
+               */
+               delta = 0;
+               vpdiff = ( step >> 3 );
+
+               if ( diff >= step ) {
+                       delta = 4;
+                       diff -= step;
+                       vpdiff += step;
+               }
+               step >>= 1;
+               if ( diff >= step ) {
+                       delta |= 2;
+                       diff -= step;
+                       vpdiff += step;
+               }
+               step >>= 1;
+               if ( diff >= step ) {
+                       delta |= 1;
+                       vpdiff += step;
+               }
+
+               /* Step 3 - Update previous value */
+               if ( sign ) {
+                       valpred -= vpdiff;
+               }
+               else{
+                       valpred += vpdiff;
+               }
+
+               /* Step 4 - Clamp previous value to 16 bits */
+               if ( valpred > 32767 ) {
+                       valpred = 32767;
+               }
+               else if ( valpred < -32768 ) {
+                       valpred = -32768;
+               }
+
+               /* Step 5 - Assemble value, update index and step values */
+               delta |= sign;
+
+               index += indexTable[delta];
+               if ( index < 0 ) {
+                       index = 0;
+               }
+               if ( index > 88 ) {
+                       index = 88;
+               }
+               step = stepsizeTable[index];
+
+               /* Step 6 - Output value */
+               if ( bufferstep ) {
+                       outputbuffer = ( delta << 4 ) & 0xf0;
+               }
+               else{
+                       *outp++ = ( delta & 0x0f ) | outputbuffer;
+               }
+
+               bufferstep = !bufferstep;
+       }
+
+       /* Output last step, if needed */
+       if ( !bufferstep ) {
+               *outp++ = outputbuffer;
+       }
+
+       state->out_valprev = valpred;
+       state->out_index = index;
+}
+
+void FindNextChunk( char *name ){
+       while ( 1 )
+       {
+               data_p = last_chunk;
+
+               if ( data_p >= iff_end ) {         // didn't find the chunk
+                       data_p = NULL;
+                       return;
+               }
+
+               data_p += 4;
+               iff_chunk_len = *(long *)data_p;
+               data_p += 4;
+               if ( iff_chunk_len < 0 ) {
+                       data_p = NULL;
+                       return;
+               }
+
+               data_p -= 8;
+               last_chunk = data_p + 8 + ( ( iff_chunk_len + 1 ) & ~1 );
+               if ( !strncmp( data_p, name, 4 ) ) {
+                       return;
+               }
+       }
+}
+
+void FindChunk( char *name ){
+       last_chunk = iff_data;
+       FindNextChunk( name );
+}
+
+void DumpChunks( void ){
+       char str[5];
+
+       str[4] = 0;
+       data_p = iff_data;
+       do
+       {
+               memcpy( str, data_p, 4 );
+               data_p += 4;
+               iff_chunk_len = *(long *)data_p;
+               data_p += 4;
+               printf( "0x%x : %s (%d)\n", (int)( data_p - 4 ), str, iff_chunk_len );
+               data_p += ( iff_chunk_len + 1 ) & ~1;
+       }
+       while ( data_p < iff_end );
+}
+
+/*
+   ============
+   GetWavinfo
+   ============
+ */
+wavinfo_t GetWavinfo( char *name, byte *wav, int wavlength ){
+       wavinfo_t info;
+       int i;
+       int format;
+       int samples;
+
+       memset( &info, 0, sizeof( info ) );
+
+       if ( !wav ) {
+               return( info );
+       }
+
+       iff_data = wav;
+       iff_end = wav + wavlength;
+
+// find "RIFF" chunk
+       FindChunk( "RIFF" );
+       if ( !( data_p && !strncmp( data_p + 8, "WAVE", 4 ) ) ) {
+               printf( "Missing RIFF/WAVE chunks\n" );
+               return( info );
+       }
+
+// get "fmt " chunk
+       iff_data = data_p + 12;
+
+       FindChunk( "fmt " );
+       if ( !data_p ) {
+               printf( "Missing fmt chunk\n" );
+               return( info );
+       }
+       data_p += 8;
+       format = *(short *)data_p;
+       data_p += 2;
+       if ( format != 1 ) {
+               printf( "Microsoft PCM format only\n" );
+               return( info );
+       }
+
+       info.channels = *(short *)data_p;
+       data_p += 2;
+       info.rate = *(long *)data_p;
+       data_p += 4;
+       data_p += 6;
+       info.width = *(short *)data_p / 8;
+       data_p += 2;
+
+// get cue chunk
+       FindChunk( "cue " );
+       if ( data_p ) {
+               data_p += 32;
+               info.loopstart = *(long *)data_p;
+               data_p += 4;
+
+// if the next chunk is a LIST chunk, look for a cue length marker
+               FindNextChunk( "LIST" );
+               if ( data_p ) {
+// this is not a proper parse, but it works with cooledit...
+                       if ( !strncmp( data_p + 28, "mark", 4 ) ) {
+                               data_p += 24;
+                               i = *(long *)data_p;                    // samples in loop
+                               data_p += 4;
+                               info.samples = info.loopstart + i;
+                       }
+               }
+       }
+       else{
+               info.loopstart = -1;
+       }
+
+// find data chunk
+       FindChunk( "data" );
+       if ( !data_p ) {
+               printf( "Missing data chunk\n" );
+               return( info );
+       }
+
+       data_p += 4;
+       samples = *(long *)data_p;
+       data_p += 4;
+
+       if ( info.samples ) {
+               if ( samples < info.samples ) {
+                       Error( "Sound %s has a bad loop length", name );
+               }
+       }
+       else{
+               info.samples = samples;
+       }
+
+       info.dataofs = data_p - wav;
+       return( info );
+}
+
+// ==============
+// LoadSoundtrack
+// ==============
+
+void LoadSoundtrack(){
+       char name[1024];
+       FILE    *f;
+       int len;
+
+       soundtrack = NULL;
+       sprintf( name, "%svideo/%s/%s.wav", gamedir, base, base );
+       printf( "\nLoading sound    : %s\n", name );
+       f = fopen( name, "rb" );
+       if ( !f ) {
+               printf( "\nNo soundtrack for %s\n", base );
+               return;
+       }
+       len = Q_filelength( f );
+       soundtrack = SafeMalloc( len, "LoadSoundtrack" );
+       fread( soundtrack, 1, len, f );
+       fclose( f );
+
+       wavinfo = GetWavinfo( name, soundtrack, len );
+       adpcm.state.out_valprev = 0;
+       adpcm.state.out_index = 0;
+}
+
+// ==================
+// WriteSound
+// ==================
+
+int WriteSound( FILE *output, int frame, int numframes ){
+       int start, end;
+       int count;
+       int empty = 0;
+       int width;
+       char    *work;
+
+       width = wavinfo.width * wavinfo.channels;
+       start = ( ( frame * wavinfo.rate / 14 ) + 31 ) & 0xffffffe0;                // start sample
+       end = ( ( ( frame + numframes ) * wavinfo.rate / 14 ) + 31 ) & 0xffffffe0;    // end sample
+       count = end - start;
+
+       work = soundtrack + wavinfo.dataofs + ( start * width );
+       adpcm.state.count = count * wavinfo.channels;           // Number of samples
+       adpcm.state.in_valprev = adpcm.state.out_valprev;
+       adpcm.state.in_index = adpcm.state.out_index;
+       adpcm_coder( (short *)work, &adpcm );
+       WriteHeader( output, FC_SOUND_22KMADPCM, FC_ADPCM_VERSION, ( adpcm.state.count / 2 ) + sizeof( adpcm_state_t ), (char *)&adpcm );
+       return( count / 2 );
+}
+// ==============================
+// Basic run length encoder
+// ==============================
+
+char *RLEZZ( char *in, char *out ){
+       int srun;
+       char count;
+       int idx = 0;
+
+       while ( idx < 64 )
+       {
+               srun = idx;                             // Start of run
+
+               while ( idx < 63 )
+               {
+                       if ( in[LUT_ZZ[idx]] != in[LUT_ZZ[idx + 1]] ) {
+                               break;
+                       }
+                       idx++;
+               }
+               count = (char)( idx - srun );             // count of repeated bytes
+
+               if ( !count ) {
+                       while ( idx < 63 )
+                       {
+                               if ( in[LUT_ZZ[idx]] == in[LUT_ZZ[idx + 1]] ) {
+                                       break;
+                               }
+                               idx++;
+                       }
+                       if ( idx == 63 ) {
+                               idx++;
+                       }
+
+                       count = (char)( idx - srun );         // count of unique bytes
+                       *out++ = count;
+                       while ( count-- )
+                               *out++ = in[LUT_ZZ[srun++]];
+               }
+               else
+               {
+                       *out++ = -( count + 1 );
+                       *out++ = in[LUT_ZZ[idx]];
+                       idx++;
+               }
+       }
+       return( out );
+}
+
+// ==============================
+// Discrete Cosine Transformation
+// ==============================
+
+void init_base( float quant ){
+       int y, x;
+
+       for ( y = 0; y < BLOCKSIZE; y++ )
+               for ( x = 0; x < BLOCKSIZE; x++ )
+               {
+                       if ( y == 0 ) {
+                               dctbase[y][x] = 1;
+                       }
+                       else{
+                               dctbase[y][x] = SQRT2 * cos( ( ( x * 2 + 1 ) * y * M_PI ) / ( BLOCKSIZE * 2 ) );
+                       }
+               }
+
+       for ( y = 0; y < BLOCKSIZE * BLOCKSIZE; y++ )
+               Quantise[y] = LUT_Quantise[y] / quant;
+}
+
+void SplitComponents( byte *src, int width, int height ){
+       int i, j;
+       float   *tr = red;
+       float   *tg = green;
+       float   *tb = blue;
+
+       for ( i = 0; i < BLOCKSIZE; i++, src += ( width - BLOCKSIZE ) * 4 )
+               for ( j = 0; j < BLOCKSIZE; j++ )
+               {
+                       *tr++ = ( (float)*src++ ) - 128.0F;
+                       *tg++ = ( (float)*src++ ) - 128.0F;
+                       *tb++ = ( (float)*src++ ) - 128.0F;
+                       src++;
+               }
+}
+
+void transferH( float *src, float *dst ){
+       int y, dx, dy;
+       float sum;
+       float   *work;
+
+       for ( y = 0; y < BLOCKSIZE; y++, src += BLOCKSIZE )
+       {
+               for ( dy = 0; dy < BLOCKSIZE; dy++ )
+               {
+                       sum = 0;
+                       work = src;
+                       for ( dx = 0; dx < BLOCKSIZE; dx++, work++ )
+                               sum += dctbase[dy][dx] * *work;
+
+                       *dst++ = sum / BLOCKSIZE;
+               }
+       }
+}
+
+void transferV( float *src, float *dst ){
+       int x, dy, fy;
+       float sum;
+       float   *work;
+
+       for ( x = 0; x < BLOCKSIZE; x++, src++, dst++ )
+       {
+               for ( fy = 0; fy < BLOCKSIZE; fy++ )
+               {
+                       sum = 0;
+                       work = src;
+                       for ( dy = 0; dy < BLOCKSIZE; dy++, work += BLOCKSIZE )
+                               sum += dctbase[fy][dy] * *work;
+
+                       dst[fy * BLOCKSIZE] = sum / BLOCKSIZE;
+               }
+       }
+}
+
+char *Combine( byte *dst, float *p, float *q ){
+       int i, j;
+       byte rlesrc[BLOCKSIZE * BLOCKSIZE];
+       int c;
+       byte    *work;
+
+       work = rlesrc;
+       for ( j = 0; j < BLOCKSIZE; j++ )
+               for ( i = 0; i < BLOCKSIZE; i++ )
+               {
+                       c = (int)( ( *p++ / *q++ ) + 128.5F );
+                       c -= 128;
+
+                       if ( c < -128 ) {
+                               c = -128;
+                       }
+                       if ( c > 127 ) {
+                               c = 127;
+                       }
+
+                       *work++ = (char)c;
+               }
+
+       dst = RLEZZ( rlesrc, dst );
+       return( dst );
+}
+
+char *CombineComponents( char *dst, int width, int height ){
+       dst = Combine( dst, red, Quantise );
+       dst = Combine( dst, green, Quantise );
+       dst = Combine( dst, blue, Quantise );
+       return( dst );
+}
+
+void DCT( cblock_t *out, cblock_t in, int width, int height ){
+       int x, y;
+       char    *cursrc;
+       char    *curdst;
+
+       curdst = out->data;
+       for ( y = 0; y < height; y += BLOCKSIZE )
+               for ( x = 0; x < width; x += BLOCKSIZE )
+               {
+                       cursrc = in.data + ( ( y * width ) + x ) * 4;
+                       SplitComponents( cursrc, width, height );
+                       transferH( red, temp );
+                       transferV( temp, red );
+                       transferH( green, temp );
+                       transferV( temp, green );
+                       transferH( blue, temp );
+                       transferV( temp, blue );
+                       curdst = CombineComponents( curdst, width, height );
+               }
+       out->count = curdst - out->data;
+}
+
+// ==================
+// BuildChars1
+// ==================
+
+void BuildChars1( int prev, int nodenum, unsigned bits, int bitcount ){
+       hnode_t     *node;
+
+       if ( nodenum < HUF_TOKENS ) {
+               if ( bitcount > 32 ) {
+                       Error( "bitcount > 32" );
+               }
+               charbits1[prev][nodenum] = bits;
+               charbitscount1[prev][nodenum] = bitcount;
+               return;
+       }
+
+       node = &hnodes1[prev][nodenum];
+       bits <<= 1;
+       BuildChars1( prev, node->children[0], bits, bitcount + 1 );
+       bits |= 1;
+       BuildChars1( prev, node->children[1], bits, bitcount + 1 );
+}
+
+// ==================
+// SmallestNode1
+// ==================
+
+int SmallestNode1( hnode_t *hnodes, int numhnodes ){
+       int i;
+       int best, bestnode;
+
+       best = 99999999;
+       bestnode = -1;
+       for ( i = 0; i < numhnodes; i++ )
+       {
+               if ( hnodes[i].used ) {
+                       continue;
+               }
+               if ( !hnodes[i].count ) {
+                       continue;
+               }
+               if ( hnodes[i].count < best ) {
+                       best = hnodes[i].count;
+                       bestnode = i;
+               }
+       }
+
+       if ( bestnode == -1 ) {
+               return( -1 );
+       }
+
+       hnodes[bestnode].used = true;
+       return( bestnode );
+}
+
+// ==================
+// BuildTree1
+// ==================
+
+void BuildTree1( int prev ){
+       hnode_t     *node, *nodebase;
+       int numhnodes;
+
+       // build the nodes
+       numhnodes = HUF_TOKENS;
+       nodebase = hnodes1[prev];
+       while ( 1 )
+       {
+               node = &nodebase[numhnodes];
+
+               // pick two lowest counts
+               node->children[0] = SmallestNode1( nodebase, numhnodes );
+               if ( node->children[0] == -1 ) {
+                       break;  // no more
+
+               }
+               node->children[1] = SmallestNode1( nodebase, numhnodes );
+               if ( node->children[1] == -1 ) {
+                       break;
+               }
+
+               node->count = nodebase[node->children[0]].count +
+                                         nodebase[node->children[1]].count;
+               numhnodes++;
+       }
+       numhnodes1[prev] = numhnodes - 1;
+       BuildChars1( prev, numhnodes - 1, 0, 0 );
+}
+
+// ==================
+// Huffman1_Count
+// ==================
+
+void Huffman1_Count( cblock_t in ){
+       int i;
+       int prev;
+       int v;
+       int rept;
+
+       prev = 0;
+       for ( i = 0; i < in.count; i++ )
+       {
+               v = in.data[i];
+               order0counts[v]++;
+               hnodes1[prev][v].count++;
+               prev = v;
+
+               for ( rept = 1; ( i + rept < in.count ) && ( rept < MAX_REPT ); rept++ )
+                       if ( in.data[i + rept] != v ) {
+                               break;
+                       }
+               if ( rept > MIN_REPT ) {
+                       hnodes1[prev][255 + rept].count++;
+                       i += rept - 1;
+               }
+       }
+}
+
+// ==================
+// Huffman1_Build
+// ==================
+
+void Huffman1_Build(){
+       int i, j, v;
+       int max;
+       int total;
+
+       for ( i = 0; i < 256; i++ )
+       {
+// normalize and save the counts
+               max = 0;
+               for ( j = 0; j < HUF_TOKENS; j++ )
+               {
+                       if ( hnodes1[i][j].count > max ) {
+                               max = hnodes1[i][j].count;
+                       }
+               }
+               if ( max == 0 ) {
+                       max = 1;
+               }
+               total = 0;
+// easy to overflow 32 bits here!
+               for ( j = 0; j < HUF_TOKENS; j++ )
+               {
+                       v = ( hnodes1[i][j].count * (double) 255 + max - 1 ) / max;
+                       if ( v > 255 ) {
+                               Error( "v > 255" );
+                       }
+                       scaled[i][j] = hnodes1[i][j].count = v;
+                       if ( v ) {
+                               total++;
+                       }
+               }
+               if ( total == 1 ) { // must have two tokens
+                       if ( !scaled[i][0] ) {
+                               scaled[i][0] = hnodes1[i][0].count = 1;
+                       }
+                       else{
+                               scaled[i][1] = hnodes1[i][1].count = 1;
+                       }
+               }
+               BuildTree1( i );
+       }
+}
+
+// ==================
+// Huffman1
+// Order 1 compression with pre-built table
+// ==================
+
+cblock_t Huffman1( cblock_t in ){
+       int i;
+       int outbits, c;
+       unsigned bits;
+       byte        *out_p;
+       cblock_t out;
+       int prev;
+       int v;
+       int rept;
+
+       out_p = out.data = SafeMalloc( ( in.count * 2 ) + 1024 + 4, "Huffman" );
+       memset( out_p, 0, ( in.count * 2 ) + 1024 + 4 );
+
+       // leave space for compressed count
+       out_p += 4;
+       // write count
+       *(long *)out_p = in.count;
+       out_p += 4;
+
+       // write bits
+       outbits = 0;
+       prev = 0;
+       for ( i = 0; i < in.count; i++ )
+       {
+               v = in.data[i];
+
+               c = charbitscount1[prev][v];
+               bits = charbits1[prev][v];
+               if ( !c ) {
+                       Error( "!bits" );
+               }
+               while ( c )
+               {
+                       c--;
+                       if ( bits & ( 1 << c ) ) {
+                               out_p[outbits >> 3] |= 1 << ( outbits & 7 );
+                       }
+                       outbits++;
+               }
+
+               prev = v;
+               // check for repeat encodes
+               for ( rept = 1; ( i + rept < in.count ) && ( rept < MAX_REPT ); rept++ )
+                       if ( in.data[i + rept] != v ) {
+                               break;
+                       }
+               if ( rept > MIN_REPT ) {
+                       c = charbitscount1[prev][255 + rept];
+                       bits = charbits1[prev][255 + rept];
+                       if ( !c ) {
+                               Error( "!bits" );
+                       }
+                       while ( c )
+                       {
+                               c--;
+                               if ( bits & ( 1 << c ) ) {
+                                       out_p[outbits >> 3] |= 1 << ( outbits & 7 );
+                               }
+                               outbits++;
+                       }
+                       i += rept - 1;
+               }
+       }
+       out_p += ( outbits + 7 ) >> 3;
+       out.count = out_p - out.data;
+
+       out_p = out.data;
+       *(long *)out_p = out.count;
+       return( out );
+}
+// ===================
+// LoadFrame
+// ===================
+
+void LoadFrame( cblock_t *out, char *base, int frame ){
+       cblock_t in;
+       int width, height;
+       char name[1024];
+       FILE        *f;
+
+       in.data = NULL;
+       in.count = -1;
+       sprintf( name, "%svideo/%s/%s%04i.tga", gamedir, base, base, frame );
+
+       f = fopen( name, "rb" );
+       if ( !f ) {
+               out->data = NULL;
+               return;
+       }
+       fclose( f );
+
+       LoadTGA( name, &in.data, &width, &height );
+       if ( ( width != cinehead.Width ) || ( height != cinehead.Height ) ) {
+               free( in.data );
+               printf( "Invalid picture size\n" );
+               out->data = NULL;
+               return;
+       }
+       out->data = SafeMalloc( width * height * 3, "LoadFrame" );        // rle could possibly expand file so this not 100% safe (however DCT should force a lot of compression)
+       DCT( out, in, width, height );
+       free( in.data );
+}
+
+// ==================================
+// Cmd_Video
+//
+// video <directory> <framedigits>
+// ==================================
+
+void Cmd_Video(){
+       char savename[256];
+       char name[256];
+       FILE        *output;
+       int frame;
+       int width, height;
+       cblock_t in, huffman;
+       int size;
+       float dctconst;
+       int maxsize, ssize;
+       int min_rle_size, warnings;
+       int ave_image, ave_sound;
+
+       GetScriptToken( false );
+       strcpy( base, token );
+       if ( g_release ) {
+               return;
+       }
+
+       GetScriptToken( false );
+       dctconst = atof( token );
+       GetScriptToken( false );
+       maxsize = atoi( token );
+
+       sprintf( savename, "%svideo/%s.cin", gamedir, base );
+
+       // clear stuff
+       memset( charbits1, 0, sizeof( charbits1 ) );
+       memset( charbitscount1, 0, sizeof( charbitscount1 ) );
+       memset( hnodes1, 0, sizeof( hnodes1 ) );
+       memset( numhnodes1, 0, sizeof( numhnodes1 ) );
+       memset( order0counts, 0, sizeof( order0counts ) );
+
+       // load the entire sound wav file if present
+       LoadSoundtrack();
+
+       cinehead.SndRate = wavinfo.rate;
+       cinehead.SndWidth = wavinfo.width;
+       cinehead.SndChannels = wavinfo.channels;
+
+       sprintf( name, "%svideo/%s/%s0000.tga", gamedir, base, base );
+       printf( "Loading sequence : %s\n", name );
+       printf( "DCT constant     : %f\n", dctconst );
+
+       LoadTGA( name, NULL, &width, &height );
+
+       output = fopen( savename, "wb" );
+       if ( !output ) {
+               Error( "Can't open %s", savename );
+       }
+
+       if ( ( width % BLOCKSIZE ) || ( height % BLOCKSIZE ) ) {
+               Error( "Width and height must be a multiple of %d", BLOCKSIZE );
+       }
+
+       cinehead.Width = width;
+       cinehead.Height = height;
+       init_base( dctconst );
+
+       // build the dictionary
+       printf( "Counting         : " );
+       min_rle_size = 0;
+       for ( frame = 0;  ; frame++ )
+       {
+               printf( "." );
+               LoadFrame( &in, base, frame );
+               if ( !in.data ) {
+                       break;
+               }
+               Huffman1_Count( in );
+               if ( in.count > min_rle_size ) {
+                       min_rle_size = in.count;
+               }
+               free( in.data );
+       }
+       printf( "\n" );
+       cinehead.NumFrames = frame;
+       printf( "Num Frames       : %d\n", frame );
+       cinehead.MaxRleSize = ( min_rle_size + 0x1f ) & 0xfffffe0;
+       cinehead.MaxSndSize = ( ( 4 * wavinfo.rate * wavinfo.channels / 14 ) + 0x1f ) & 0xffffffe0;
+
+       WriteHeader( output, FC_HEADER_NAME, FC_HEADER_VERSION, sizeof( CineHead_t ), &cinehead );
+
+       // build nodes and write counts
+       Huffman1_Build();
+       WriteHeader( output, FC_HUFFBITS_NAME, FC_HUFFBITS_VERSION, sizeof( scaled ), scaled );
+       WriteHeader( output, FC_QUANT_NAME, FC_QUANT_VERSION, sizeof( Quantise ), Quantise );
+
+       ave_image = 0;
+       ave_sound = 0;
+       warnings = 0;
+       // compress it with the dictionary
+       if ( soundtrack ) {
+               ssize = WriteSound( output, frame, 4 );
+               ave_sound += ssize;
+       }
+
+       for ( frame = 0; frame < cinehead.NumFrames; frame++ )
+       {
+               // save some sound samples
+               printf( "Packing          : ", frame );
+               LoadFrame( &in, base, frame );
+
+               // save the image
+               huffman = Huffman1( in );
+               printf( "%d bytes rle, %d bytes huffman", in.count, huffman.count );
+               size = ( huffman.count + 3 ) & 0xfffffffc;                    // round up to longwords
+               if ( size > maxsize ) {
+                       printf( " ** WARNING **" );
+                       warnings++;
+               }
+               printf( "\n" );
+               ave_image += huffman.count;
+
+               WriteHeader( output, FC_IMAGE_NAME, FC_IMAGE_VERSION, size, huffman.data );
+               if ( soundtrack ) {
+                       ssize = WriteSound( output, frame + 4, 1 );
+                       ave_sound += ssize;
+               }
+
+               free( in.data );
+               free( huffman.data );
+       }
+       printf( "\nTotal size: %d (headers + %d image + %d sound)\n", ftell( output ), ave_image, ave_sound );
+       printf( "Data rate : %d bytes per sec (image and sound)\n", ( ave_image + ave_sound ) / cinehead.NumFrames );
+       printf( "Cin created ok with %d warnings.\n", warnings );
+       fclose( output );
+
+       if ( soundtrack ) {
+               free( soundtrack );
+       }
+}
+#endif
+
+void Cmd_Video(){
+}
+
+// end
diff --git a/tools/heretic2/qcommon/angles.h b/tools/heretic2/qcommon/angles.h
new file mode 100644 (file)
index 0000000..b0baf31
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// Angles in radians
+
+#define ANGLE_0         0.0F
+#define ANGLE_1         0.017453292F
+#define ANGLE_5         0.087266462F
+#define ANGLE_10        0.174532925F
+#define ANGLE_15        0.261799387F
+#define ANGLE_20        0.392699081F
+#define ANGLE_30        0.523598775F
+#define ANGLE_45        0.785398163F
+#define ANGLE_60        1.047197551F
+#define ANGLE_72        1.256637061F
+#define ANGLE_90        1.570796327F
+#define ANGLE_120       2.094395102F
+#define ANGLE_135       2.35619449F
+#define ANGLE_144       2.513274123F
+#define ANGLE_180       3.141592653F
+#define ANGLE_225       3.926990817F
+#define ANGLE_270       4.71238898F
+#define ANGLE_315       5.497787144F
+#define ANGLE_360       6.283185307F
+
+// Angles in degrees
+
+#define DEGREE_0        0.0F
+#define DEGREE_180      180.0F
+#define DEGREE_45       ( DEGREE_180 / 4.0F )
+#define DEGREE_90       ( DEGREE_180 / 2.0F )
+#define DEGREE_135      ( DEGREE_90 + DEGREE_45 )
+#define DEGREE_270      ( DEGREE_180 + DEGREE_90 )
+#define DEGREE_360      ( DEGREE_180 * 2.0F )
+
+#define DEGREE_225      ( DEGREE_180 + DEGREE_45 )
+#define DEGREE_315      ( DEGREE_270 + DEGREE_45 )
+
+#define DEGREE_30       ( DEGREE_180 / 6.0F )
+#define DEGREE_60       ( DEGREE_180 / 3.0F )
+#define DEGREE_120      ( DEGREE_360 / 3.0F )
+
+#define DEGREE_1        ( DEGREE_180 / 180.0F )
+#define DEGREE_5        ( DEGREE_180 / 36.0F )
+#define DEGREE_10       ( DEGREE_180 / 18.0F )
+#define DEGREE_15       ( DEGREE_180 / 12.0F )
+#define DEGREE_20       ( DEGREE_180 / 8.0F )
+
+// Conversion routines
+
+#define ANGLE_TO_RAD    ANGLE_1
+#define RAD_TO_ANGLE    ( 180.0F / ANGLE_180 )
+
+#define SHORT_TO_ANGLE  ( 360.0 / 65536 )
+
+#if GDEF_COMPILER_MSVC
+#pragma warning(disable : 4305)     // 'initializing' : truncation from 'const double ' to 'float '
+#endif
diff --git a/tools/heretic2/qcommon/arrayedlist.h b/tools/heretic2/qcommon/arrayedlist.h
new file mode 100644 (file)
index 0000000..46663dd
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _ARRAYEDLIST_H
+#define _ARRAYEDLIST_H
+
+#include <assert.h>
+#include <globaldefs.h>
+
+typedef struct ArrayedListNode_s
+{
+       int data;
+       int next;
+       int inUse;
+} ArrayedListNode_t;
+
+#define ARRAYEDLISTNODE_NULL -1
+
+static GDEF_ATTRIBUTE_INLINE int GetFreeNode( ArrayedListNode_t *nodeArray, int max ){
+       int i;
+
+       for ( i = 0; i < max; ++i )
+       {
+               if ( !nodeArray[i].inUse ) {
+                       nodeArray[i].inUse = 1;
+                       return i;
+               }
+       }
+
+       assert( 0 );
+       return -1;
+}
+
+static GDEF_ATTRIBUTE_INLINE void FreeNode( ArrayedListNode_t *nodeArray, int index ){
+       nodeArray[index].inUse = 0;
+}
+
+#endif //_ARRAYEDLIST_H
diff --git a/tools/heretic2/qcommon/flex.h b/tools/heretic2/qcommon/flex.h
new file mode 100644 (file)
index 0000000..98184e8
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+// Generic flexible format
+
+typedef struct
+{
+       char ident[32];
+       int version;
+       int size;
+} header_t;
+
+void WriteHeader( FILE *, char *, int, int, void * );
+
+// end
diff --git a/tools/heretic2/qcommon/fmodel.h b/tools/heretic2/qcommon/fmodel.h
new file mode 100644 (file)
index 0000000..e2ebfa8
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+/*
+   ========================================================================
+
+   .FM triangle flexible model file format
+
+   ========================================================================
+ */
+
+#ifndef __FMODEL_HEADER
+#define __FMODEL_HEADER
+
+#include "bspfile.h"
+
+//typedef unsigned char         byte;
+//typedef int  qboolean;
+//typedef float vec3_t[3];
+
+#define MAX_FM_TRIANGLES    2048
+#define MAX_FM_VERTS        2048
+#define MAX_FM_FRAMES       2048
+#define MAX_FM_SKINS        64
+#define MAX_FM_SKINNAME     64
+#define MAX_FM_MESH_NODES   16      // also defined in game/qshared.h
+
+
+#define DTRIVERTX_V0   0
+#define DTRIVERTX_V1   1
+#define DTRIVERTX_V2   2
+#define DTRIVERTX_LNI  3
+#define DTRIVERTX_SIZE 4
+
+#define SKINPAGE_WIDTH 640
+#define SKINPAGE_HEIGHT 480
+
+#define ENCODED_WIDTH_X 92
+#define ENCODED_WIDTH_Y 475
+#define ENCODED_HEIGHT_X 128
+#define ENCODED_HEIGHT_Y 475
+
+#define SCALE_ADJUST_FACTOR 0.96
+
+#define INFO_HEIGHT 5
+#define INFO_Y ( SKINPAGE_HEIGHT - INFO_HEIGHT )
+
+extern byte     *BasePalette;
+extern byte     *BasePixels,*TransPixels;
+extern int BaseWidth, BaseHeight, TransWidth, TransHeight;
+extern int ScaleWidth, ScaleHeight;
+
+int ExtractNumber( byte *pic, int x, int y );
+void DrawTextChar( int x, int y, char *text );
+void DrawLine( int x1, int y1, int x2, int y2 );
+
+// the glcmd format:
+// a positive integer starts a tristrip command, followed by that many
+// vertex structures.
+// a negative integer starts a trifan command, followed by -x vertexes
+// a zero indicates the end of the command list.
+// a vertex consists of a floating point s, a floating point t,
+// and an integer vertex index.
+
+
+// Initial Header
+#define FM_HEADER_NAME  "header"
+#define FM_HEADER_VER   2
+
+typedef struct
+{
+       int skinwidth;
+       int skinheight;
+       int framesize;              // byte size of each frame
+
+       int num_skins;
+       int num_xyz;
+       int num_st;                 // greater than num_xyz for seams
+       int num_tris;
+       int num_glcmds;             // dwords in strip/fan command list
+       int num_frames;
+       int num_mesh_nodes;
+} fmheader_t;
+
+
+// Skin Header
+#define FM_SKIN_NAME    "skin"
+#define FM_SKIN_VER     1
+
+
+// ST Coord Header
+#define FM_ST_NAME      "st coord"
+#define FM_ST_VER       1
+
+typedef struct
+{
+       short s;
+       short t;
+} fmstvert_t;
+
+
+// Tri Header
+#define FM_TRI_NAME     "tris"
+#define FM_TRI_VER      1
+
+typedef struct
+{
+       short index_xyz[3];
+       short index_st[3];
+} fmtriangle_t;
+
+
+// Frame Header
+#define FM_FRAME_NAME   "frames"
+#define FM_FRAME_VER    1
+
+// Frame for compression, just the names
+#define FM_SHORT_FRAME_NAME "short frames"
+#define FM_SHORT_FRAME_VER  1
+
+// Normals for compressed frames
+#define FM_NORMAL_NAME  "normals"
+#define FM_NORMAL_VER   1
+
+// Compressed Frame Data
+#define FM_COMP_NAME    "comp data"
+#define FM_COMP_VER 1
+
+// GL Cmds Header
+#define FM_GLCMDS_NAME  "glcmds"
+#define FM_GLCMDS_VER   1
+
+
+// Mesh Nodes Header
+#define FM_MESH_NAME    "mesh nodes"
+#define FM_MESH_VER     3
+
+// Skeleton Header
+#define FM_SKELETON_NAME "skeleton"
+#define FM_SKELETON_VER 1
+
+// References Header
+#define FM_REFERENCES_NAME "references"
+#define FM_REFERENCES_VER   1
+
+typedef struct
+{
+
+       union
+       {
+
+               byte tris[MAX_FM_TRIANGLES >> 3];
+
+               struct {
+                       short   *triIndicies;
+                       int num_tris;
+               };
+
+       };
+
+       byte verts[MAX_FM_VERTS >> 3];
+       short start_glcmds, num_glcmds;
+} fmmeshnode_t;
+
+//=================================================================
+
+// Frame info
+typedef struct
+{
+       byte v[3];              // scaled byte to fit in frame mins/maxs
+       byte lightnormalindex;
+} fmtrivertx_t;
+
+typedef struct
+{
+       float scale[3];                 // multiply byte verts by this
+       float translate[3];             // then add this
+       char name[16];                  // frame name from grabbing
+       fmtrivertx_t verts[1];          // variable sized
+} fmaliasframe_t;
+
+
+#endif // #define __FMODEL_HEADER
diff --git a/tools/heretic2/qcommon/h2common.h b/tools/heretic2/qcommon/h2common.h
new file mode 100644 (file)
index 0000000..e1f2559
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef H2COMMON_H
+#define H2COMMON_H
+  #define H2COMMON_API
+#endif
diff --git a/tools/heretic2/qcommon/placement.h b/tools/heretic2/qcommon/placement.h
new file mode 100644 (file)
index 0000000..9151183
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef PLACEMENT_H
+#define PLACEMENT_H
+
+#include "q_typedef.h"
+
+//typedef float vec3_t[3];
+
+typedef struct Placement_s
+{
+       vec3_t origin;
+       vec3_t direction;
+       vec3_t up;
+} Placement_t;
+
+#endif
diff --git a/tools/heretic2/qcommon/q_typedef.h b/tools/heretic2/qcommon/q_typedef.h
new file mode 100644 (file)
index 0000000..cbe69dd
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef Q_TYPEDEF_H
+#define Q_TYPEDEF_H
+
+typedef float vec_t;
+typedef vec_t vec2_t[2];
+typedef vec_t vec3_t[3];
+typedef double vec3d_t[3];
+typedef vec_t vec5_t[5];
+
+typedef float matrix3_t[3][3];
+typedef float matrix3d_t[3][3];
+
+typedef int fixed4_t;
+typedef int fixed8_t;
+typedef int fixed16_t;
+
+typedef unsigned char byte;
+
+#ifndef __cplusplus
+typedef enum {false, true}  qboolean;
+#else
+typedef int qboolean;
+#endif
+
+typedef struct edict_s edict_t;
+
+typedef struct paletteRGBA_s
+{
+       union
+       {
+               struct
+               {
+                       byte r,g,b,a;
+               };
+               unsigned c;
+               byte c_array[4];
+       };
+} paletteRGBA_t;
+
+#endif
diff --git a/tools/heretic2/qcommon/qfiles.h b/tools/heretic2/qcommon/qfiles.h
new file mode 100644 (file)
index 0000000..4d0648c
--- /dev/null
@@ -0,0 +1,603 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+//
+// qfiles.h: quake file formats
+// This file must be identical in the quake and utils directories
+//
+
+/*
+   ========================================================================
+
+   The .pak files are just a linear collapse of a directory tree
+
+   ========================================================================
+ */
+
+#define IDPAKHEADER     ( ( 'K' << 24 ) + ( 'C' << 16 ) + ( 'A' << 8 ) + 'P' )
+
+typedef struct
+{
+       char name[56];
+       int filepos, filelen;
+} dpackfile_t;
+
+typedef struct
+{
+       int ident;          // == IDPAKHEADER
+       int dirofs;
+       int dirlen;
+} dpackheader_t;
+
+#define MAX_FILES_IN_PACK   6144
+
+
+/*
+   ========================================================================
+
+   PCX files are used for as many images as possible
+
+   ========================================================================
+ */
+
+typedef struct
+{
+       char manufacturer;
+       char version;
+       char encoding;
+       char bits_per_pixel;
+       unsigned short xmin,ymin,xmax,ymax;
+       unsigned short hres,vres;
+       unsigned char palette[48];
+       char reserved;
+       char color_planes;
+       unsigned short bytes_per_line;
+       unsigned short palette_type;
+       char filler[58];
+       unsigned char data;             // unbounded
+} pcx_t;
+
+/*
+   ========================================================================
+
+   .MD2 compressed triangle model file format
+
+   ========================================================================
+ */
+#define IDCOMPRESSEDALIASHEADER ( ( '2' << 24 ) + ( 'C' << 16 ) + ( 'D' << 8 ) + 'I' )
+
+/*
+   ========================================================================
+
+   .MD2 compressed triangle model file format
+
+   ========================================================================
+ */
+#define IDJOINTEDALIASHEADER    ( ( '2' << 24 ) + ( 'J' << 16 ) + ( 'D' << 8 ) + 'I' )
+
+/*
+   ========================================================================
+
+   .MD2 triangle model file format
+
+   ========================================================================
+ */
+
+#define IDALIASHEADER       ( ( '2' << 24 ) + ( 'P' << 16 ) + ( 'D' << 8 ) + 'I' )
+#define ALIAS_VERSION   8
+
+#define MAX_TRIANGLES   4096
+#define MAX_VERTS       2048
+#define MAX_FRAMES      512
+#define MAX_MD2SKINS    64
+#define MAX_SKINNAME    64
+
+typedef struct
+{
+       short s;
+       short t;
+} dstvert_t;
+
+typedef struct
+{
+       short index_xyz[3];
+       short index_st[3];
+} dtriangle_t;
+
+typedef struct
+{
+       union
+       {
+               struct
+               {
+                       byte v[3];          // scaled byte to fit in frame mins/maxs
+                       byte lightnormalindex;
+               };
+
+               int vert;
+       };
+} dtrivertx_t;
+
+#define DTRIVERTX_V0   0
+#define DTRIVERTX_V1   1
+#define DTRIVERTX_V2   2
+#define DTRIVERTX_LNI  3
+#define DTRIVERTX_SIZE 4
+
+typedef struct
+{
+       float scale[3];         // multiply byte verts by this
+       float translate[3];         // then add this
+       char name[16];          // frame name from grabbing
+       dtrivertx_t verts[1];   // variable sized
+} daliasframe_t;
+
+
+// the glcmd format:
+// a positive integer starts a tristrip command, followed by that many
+// vertex structures.
+// a negative integer starts a trifan command, followed by -x vertexes
+// a zero indicates the end of the command list.
+// a vertex consists of a floating point s, a floating point t,
+// and an integer vertex index.
+
+
+typedef struct
+{
+       int ident;
+       int version;
+
+       int skinwidth;
+       int skinheight;
+       int framesize;              // byte size of each frame
+
+       int num_skins;
+       int num_xyz;
+       int num_st;                 // greater than num_xyz for seams
+       int num_tris;
+       int num_glcmds;             // dwords in strip/fan command list
+       int num_frames;
+
+       int ofs_skins;              // each skin is a MAX_SKINNAME string
+       int ofs_st;                 // byte offset from start for stverts
+       int ofs_tris;               // offset for dtriangles
+       int ofs_frames;             // offset for first frame
+       int ofs_glcmds;
+       int ofs_end;                // end of file
+
+} dmdl_t;
+
+// compressed model
+typedef struct dcompmdl_s
+{
+       dmdl_t header;
+       short CompressedFrameSize;
+       short UniqueVerts;
+       short *remap;
+       float *translate;   // then add this
+       float *scale;   // multiply byte verts by this
+       char *mat;
+       char *frames;
+       char *base;
+       float *ctranslate;
+       float *cscale;
+       char data[1];
+} dcompmdl_t;
+
+typedef struct
+{
+       dcompmdl_t compModInfo;
+       int rootCluster;
+       int skeletalType;
+       struct ModelSkeleton_s *skeletons;
+} JointedModel_t;
+
+/*
+   ========================================================================
+
+   .BK file format
+
+   ========================================================================
+ */
+
+#define IDBOOKHEADER    ( ( 'K' << 24 ) + ( 'O' << 16 ) + ( 'O' << 8 ) + 'B' )
+#define BOOK_VERSION    2
+
+typedef struct bookframe_s
+{
+       int x;
+       int y;
+       int w;
+       int h;
+       char name[MAX_SKINNAME];            // name of gfx file
+} bookframe_t;
+
+typedef struct bookheader_s
+{
+       unsigned int ident;
+       unsigned int version;
+       int num_segments;
+       int total_w;
+       int total_h;
+} bookheader_t;
+
+typedef struct book_s
+{
+       bookheader_t bheader;
+       bookframe_t bframes[MAX_MD2SKINS];
+} book_t;
+
+/*
+   ========================================================================
+
+   .SP2 sprite file format
+
+   ========================================================================
+ */
+
+#define IDSPRITEHEADER  ( ( '2' << 24 ) + ( 'S' << 16 ) + ( 'D' << 8 ) + 'I' )
+// little-endian "IDS2"
+#define SPRITE_VERSION  2
+
+typedef struct
+{
+       int width, height;
+       int origin_x, origin_y;         // raster coordinates inside pic
+       char name[MAX_SKINNAME];        // name of pcx file
+} dsprframe_t;
+
+typedef struct {
+       int ident;
+       int version;
+       int numframes;
+       dsprframe_t frames[1];          // variable sized
+} dsprite_t;
+
+/*
+   ==============================================================================
+
+   .M8 texture file format
+
+   ==============================================================================
+ */
+
+typedef struct palette_s
+{
+       union
+       {
+               struct
+               {
+                       byte r,g,b;
+               };
+       };
+} palette_t;
+
+#define MIP_VERSION     2
+#define PAL_SIZE        256
+#define MIPLEVELS       16
+
+typedef struct miptex_s
+{
+       int version;
+       char name[32];
+       unsigned width[MIPLEVELS], height[MIPLEVELS];
+       unsigned offsets[MIPLEVELS];        // four mip maps stored
+       char animname[32];                  // next frame in animation chain
+       palette_t palette[PAL_SIZE];
+       int flags;
+       int contents;
+       int value;
+} miptex_t;
+
+
+
+#define MIP32_VERSION   4
+
+typedef struct miptex32_s
+{
+       int version;
+       char name[128];
+       char altname[128];                  // texture substitution
+       char animname[128];                 // next frame in animation chain
+       char damagename[128];               // image that should be shown when damaged
+       unsigned width[MIPLEVELS], height[MIPLEVELS];
+       unsigned offsets[MIPLEVELS];
+       int flags;
+       int contents;
+       int value;
+       float scale_x, scale_y;
+       int mip_scale;
+
+       // detail texturing info
+       char dt_name[128];              // detailed texture name
+       float dt_scale_x, dt_scale_y;
+       float dt_u, dt_v;
+       float dt_alpha;
+       int dt_src_blend_mode, dt_dst_blend_mode;
+
+       int unused[20];                     // future expansion to maintain compatibility with h2
+} miptex32_t;
+
+
+/*
+   ==============================================================================
+
+   .BSP file format
+
+   ==============================================================================
+ */
+
+#define IDBSPHEADER ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'B' << 8 ) + 'I' )
+// little-endian "IBSP"
+
+#define BSPVERSION  38
+
+
+// upper design bounds
+// leaffaces, leafbrushes, planes, and verts are still bounded by
+// 16 bit short limits
+#define MAX_MAP_MODELS      1024
+//#define      MAX_MAP_BRUSHES         8192    // Quake 2 original
+#define MAX_MAP_BRUSHES     10240
+#define MAX_MAP_ENTITIES    2048
+#define MAX_MAP_ENTSTRING   0x40000
+#define MAX_MAP_TEXINFO     8192
+
+#define MAX_MAP_AREAS       256
+#define MAX_MAP_AREAPORTALS 1024
+#define MAX_MAP_PLANES      65536
+#define MAX_MAP_NODES       65536
+#define MAX_MAP_BRUSHSIDES  65536
+#define MAX_MAP_LEAFS       65536
+#define MAX_MAP_VERTS       65536
+#define MAX_MAP_FACES       65536
+#define MAX_MAP_LEAFFACES   65536
+#define MAX_MAP_LEAFBRUSHES 65536
+#define MAX_MAP_PORTALS     65536
+#define MAX_MAP_EDGES       128000
+#define MAX_MAP_SURFEDGES   256000
+#define MAX_MAP_LIGHTING    0x200000
+#define MAX_MAP_VISIBILITY  0x180000
+
+// key / value pair sizes
+
+#define MAX_KEY     32
+#define MAX_VALUE   1024
+
+//=============================================================================
+
+typedef struct
+{
+       int fileofs, filelen;
+} lump_t;
+
+#define LUMP_ENTITIES       0
+#define LUMP_PLANES         1
+#define LUMP_VERTEXES       2
+#define LUMP_VISIBILITY     3
+#define LUMP_NODES          4
+#define LUMP_TEXINFO        5
+#define LUMP_FACES          6
+#define LUMP_LIGHTING       7
+#define LUMP_LEAFS          8
+#define LUMP_LEAFFACES      9
+#define LUMP_LEAFBRUSHES    10
+#define LUMP_EDGES          11
+#define LUMP_SURFEDGES      12
+#define LUMP_MODELS         13
+#define LUMP_BRUSHES        14
+#define LUMP_BRUSHSIDES     15
+#define LUMP_POP            16
+#define LUMP_AREAS          17
+#define LUMP_AREAPORTALS    18
+#define HEADER_LUMPS        19
+
+typedef struct
+{
+       int ident;
+       int version;
+       lump_t lumps[HEADER_LUMPS];
+} dheader_t;
+
+typedef struct
+{
+       float mins[3], maxs[3];
+       float origin[3];            // for sounds or lights
+       int headnode;
+       int firstface, numfaces;            // submodels just draw faces
+                                           // without walking the bsp tree
+} dmodel_t;
+
+
+typedef struct
+{
+       float point[3];
+} dvertex_t;
+
+
+// 0-2 are axial planes
+#define PLANE_X         0
+#define PLANE_Y         1
+#define PLANE_Z         2
+
+// 3-5 are non-axial planes snapped to the nearest
+#define PLANE_ANYX      3
+#define PLANE_ANYY      4
+#define PLANE_ANYZ      5
+
+// planes (x&~1) and (x&~1)+1 are allways opposites
+
+typedef struct
+{
+       float normal[3];
+       float dist;
+       int type;           // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
+} dplane_t;
+
+
+// contents flags are seperate bits
+// a given brush can contribute multiple content bits
+// multiple brushes can be in a single leaf
+
+// These definitions also need to be in q_shared.h!
+
+// ************************************************************************************************
+// CONTENTS_XXX
+// ------------
+// Contents flags.
+// ************************************************************************************************
+
+// Lower bits are stronger, and will eat weaker brushes completely.
+
+#define CONTENTS_SOLID          0x00000001  // An eye is never valid in a solid.
+#define CONTENTS_WINDOW         0x00000002  // Translucent, but not watery.
+#define CONTENTS_AUX            0x00000004
+#define CONTENTS_LAVA           0x00000008
+#define CONTENTS_SLIME          0x00000010
+#define CONTENTS_WATER          0x00000020
+#define CONTENTS_MIST           0x00000040
+#define LAST_VISIBLE_CONTENTS   CONTENTS_MIST
+
+// Remaining contents are non-visible, and don't eat brushes.
+
+#define CONTENTS_AREAPORTAL     0x00008000
+#define CONTENTS_PLAYERCLIP     0x00010000
+#define CONTENTS_MONSTERCLIP    0x00020000
+
+// Currents can be added to any other contents, and may be mixed.
+
+#define CONTENTS_CURRENT_0      0x00040000
+#define CONTENTS_CURRENT_90     0x00080000
+#define CONTENTS_CURRENT_180    0x00100000
+#define CONTENTS_CURRENT_270    0x00200000
+#define CONTENTS_CURRENT_UP     0x00400000
+#define CONTENTS_CURRENT_DOWN   0x00800000
+#define CONTENTS_ORIGIN         0x01000000  // Removed before bsping an entity.
+#define CONTENTS_MONSTER        0x02000000  // Should never be on a brush, only in game.
+#define CONTENTS_DEADMONSTER    0x04000000
+#define CONTENTS_DETAIL         0x08000000  // Brushes to be added after vis leaves.
+#define CONTENTS_TRANSLUCENT    0x10000000  // Auto set if any surface has transparency.
+#define CONTENTS_LADDER         0x20000000
+#define CONTENTS_CAMERANOBLOCK  0x40000000  // Camera LOS ignores any brushes with this flag.
+
+typedef struct
+{
+       int planenum;
+       int children[2];            // negative numbers are -(leafs+1), not nodes
+       short mins[3];              // for frustom culling
+       short maxs[3];
+       unsigned short firstface;
+       unsigned short numfaces;    // counting both sides
+} dnode_t;
+
+
+typedef struct texinfo_s
+{
+       float vecs[2][4];           // [s/t][xyz offset]
+       int flags;                  // miptex flags + overrides
+       int value;                  // light emission, etc
+       char texture[32];           // texture name (textures/*.wal)
+       int nexttexinfo;            // for animations, -1 = end of chain
+} texinfo_t;
+
+
+// note that edge 0 is never used, because negative edge nums are used for
+// counterclockwise use of the edge in a face
+typedef struct
+{
+       unsigned short v[2];        // vertex numbers
+} dedge_t;
+
+#define MAXLIGHTMAPS    4
+typedef struct
+{
+       unsigned short planenum;
+       short side;
+
+       int firstedge;              // we must support > 64k edges
+       short numedges;
+       short texinfo;
+
+// lighting info
+       byte styles[MAXLIGHTMAPS];
+       int lightofs;               // start of [numstyles*surfsize] samples
+} dface_t;
+
+typedef struct
+{
+       int contents;                       // OR of all brushes (not needed?)
+
+       short cluster;
+       short area;
+
+       short mins[3];                      // for frustum culling
+       short maxs[3];
+
+       unsigned short firstleafface;
+       unsigned short numleaffaces;
+
+       unsigned short firstleafbrush;
+       unsigned short numleafbrushes;
+} dleaf_t;
+
+typedef struct
+{
+       unsigned short planenum;        // facing out of the leaf
+       short texinfo;
+} dbrushside_t;
+
+typedef struct
+{
+       int firstside;
+       int numsides;
+       int contents;
+} dbrush_t;
+
+#define ANGLE_UP    -1
+#define ANGLE_DOWN  -2
+
+
+// the visibility lump consists of a header with a count, then
+// byte offsets for the PVS and PHS of each cluster, then the raw
+// compressed bit vectors
+#define DVIS_PVS    0
+#define DVIS_PHS    1
+typedef struct
+{
+       int numclusters;
+       int bitofs[8][2];           // bitofs[numclusters][2]
+} dvis_t;
+
+// each area has a list of portals that lead into other areas
+// when portals are closed, other areas may not be visible or
+// hearable even if the vis info says that it should be
+typedef struct
+{
+       int portalnum;
+       int otherarea;
+} dareaportal_t;
+
+typedef struct
+{
+       int numareaportals;
+       int firstareaportal;
+} darea_t;
diff --git a/tools/heretic2/qcommon/reference.c b/tools/heretic2/qcommon/reference.c
new file mode 100644 (file)
index 0000000..7be9740
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <string.h>
+#include "reference.h"
+#include "arrayedlist.h"
+#include "resourcemanager.h"
+#include "skeletons.h"
+
+char *referenceRootNames[] =
+{
+       "elf_Lhandroot", //0
+       "elf_Rhandroot",
+       "elf_Rfootroot",
+       "elf_Lfootroot",
+       "elf_Bstaffroot",
+       "elf_bladeroot",
+       "elf_hellroot",
+       "StaffBone", //7
+       "SwordBone",
+       "SpearBone",
+       "RFootBone",
+       "LFootBone",
+       "hp_backroot", //12
+       "hp_staffroot",
+       "hp_lhandroot",
+       "hp_rhandroot",
+       "hp_rfootroot",
+       "hp_lfootroot",
+       "staffroot", //18
+       "rfootroot",
+       "lfootroot",
+       "rhandroot",
+       "lhandroot",
+       "leyeroot",
+       "reyeroot"
+};
+
+int referenceRootNameOffsets[NUM_REFERENCED] =
+{
+       0,  // CORVUS
+       7,  // INSECT
+       12, // HIGH PRIESTESS
+       18, // MORCALAVIN
+};
+
+int numReferences[NUM_REFERENCED] =
+{
+       NUM_REFERENCES_CORVUS,
+       NUM_REFERENCES_INSECT,
+       NUM_REFERENCES_PRIESTESS,
+       NUM_REFERENCES_MORK,
+};
+
+int corvusJointIDs[NUM_REFERENCES_CORVUS] =
+{
+       CORVUS_UPPERBACK,
+       CORVUS_UPPERBACK,
+       -1,
+       -1,
+       CORVUS_UPPERBACK,
+       CORVUS_UPPERBACK,
+       CORVUS_UPPERBACK,
+};
+
+int *jointIDs[NUM_REFERENCED] =
+{
+       corvusJointIDs,
+};
+
+static ResourceManager_t ReferenceMngr;
+
+void InitReferenceMngr(){
+#define REFERENCE_BLOCK_SIZE 8
+       char *dummystr = NULL;
+
+       ResMngr_Con( &ReferenceMngr, sizeof( LERPedReferences_t ), REFERENCE_BLOCK_SIZE, dummystr );
+}
+
+void ReleaseReferenceMngr(){
+       ResMngr_Des( &ReferenceMngr );
+}
+
+LERPedReferences_t *LERPedReferences_new( int init_refType ){
+       LERPedReferences_t  *newRefs;
+
+       newRefs = ResMngr_AllocateResource( &ReferenceMngr, sizeof( *newRefs ) );
+       newRefs->refType = init_refType;
+       newRefs->jointIDs = jointIDs[init_refType];
+       newRefs->lastUpdate = -( REF_MINCULLTIME * 2.0 );
+
+       memset( newRefs->references, 0, MAX_REFPOINTS * sizeof( Reference_t ) );
+       memset( newRefs->oldReferences, 0, MAX_REFPOINTS * sizeof( Reference_t ) );
+
+       return newRefs;
+}
+
+void LERPedReferences_delete( LERPedReferences_t *toDelete ){
+       ResMngr_DeallocateResource( &ReferenceMngr, toDelete, sizeof( *toDelete ) );
+}
+
+// end
diff --git a/tools/heretic2/qcommon/reference.h b/tools/heretic2/qcommon/reference.h
new file mode 100644 (file)
index 0000000..747c4d4
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef REFERENCE_H
+#define REFERENCE_H
+
+#include "placement.h"
+
+#define MAX_REFPOINTS       16
+#define REF_MINCULLTIME     1.0
+
+typedef struct Reference_s
+{
+       int activecount;
+       Placement_t placement;
+} Reference_t;
+
+typedef struct LERPedReferences_s
+{
+       int refType;
+       int         *jointIDs;
+       float lastUpdate;
+       Reference_t references[MAX_REFPOINTS];
+       Reference_t oldReferences[MAX_REFPOINTS];
+} LERPedReferences_t;
+
+// Reference Types
+enum {
+       REF_NULL = -1,
+       REF_CORVUS, //0
+       REF_INSECT, //1
+       REF_PRIESTESS, //2
+       REF_MORK, //3
+       NUM_REFERENCED //4
+};
+
+// Corvus Reference Points
+enum {
+       CORVUS_LEFTHAND, //0
+       CORVUS_RIGHTHAND,
+       CORVUS_LEFTFOOT,
+       CORVUS_RIGHTFOOT,
+       CORVUS_STAFF,
+       CORVUS_BLADE,
+       CORVUS_HELL_HEAD,
+       NUM_REFERENCES_CORVUS //7
+};
+
+// Tchekrik Reference Points
+enum {
+       INSECT_STAFF, //0
+       INSECT_SWORD,
+       INSECT_SPEAR,
+       INSECT_RIGHTFOOT,
+       INSECT_LEFTFOOT,
+       NUM_REFERENCES_INSECT //5
+};
+
+// High Priestess Reference Points
+enum {
+       PRIESTESS_BACK, //0
+       PRIESTESS_STAFF,
+       PRIESTESS_LHAND,
+       PRIESTESS_RHAND,
+       PRIESTESS_RFOOT,
+       PRIESTESS_LFOOT,
+       NUM_REFERENCES_PRIESTESS //6
+};
+
+// Morcalavin Reference Points
+enum
+{
+       MORK_STAFFREF, //0
+       MORK_RFOOTREF, //1
+       MORK_LFOOTREF, //2
+       MORK_RHANDREF, //3
+       MORK_LHANDREF, //4
+       MORK_LEYEREF, //5
+       MORK_REYEREF, //6
+       NUM_REFERENCES_MORK //7
+};
+
+#define CORVUS_LIMBS_MASK   ( ( 1 << CORVUS_LEFTHAND ) | ( 1 << CORVUS_RIGHTHAND ) | ( 1 << CORVUS_LEFTFOOT ) | ( 1 << CORVUS_RIGHTFOOT ) )
+#define CORVUS_WEAPON_MASK  ( ( 1 << CORVUS_STAFF ) | ( 1 << CORVUS_BLADE ) | ( 1 << CORVUS_HELL_HEAD ) )
+#define CORVUS_MASK         ( CORVUS_LIMBS_MASK | CORVUS_WEAPON_MASK )
+
+#define INSECT_MASK         ( ( 1 << INSECT_STAFF ) | ( 1 << INSECT_SWORD ) | ( 1 << INSECT_SPEAR ) | ( 1 << INSECT_RIGHTFOOT ) | ( 1 << INSECT_LEFTFOOT ) )
+
+#define PRIESTESS_MASK      ( ( 1 << PRIESTESS_BACK ) | ( 1 << PRIESTESS_STAFF ) | ( 1 << PRIESTESS_LHAND ) | ( 1 << PRIESTESS_RHAND ) | ( 1 << PRIESTESS_RFOOT ) | ( 1 << PRIESTESS_LFOOT ) )
+
+#define MORK_MASK           ( ( 1 << MORK_STAFFREF ) | ( 1 << MORK_RFOOTREF ) | ( 1 << MORK_LFOOTREF ) | ( 1 << MORK_RHANDREF ) | ( 1 << MORK_LHANDREF ) | ( 1 << MORK_LEYEREF ) | ( 1 << MORK_REYEREF ) )
+
+extern char *referenceRootNames[];
+extern int referenceRootNameOffsets[];
+extern int numReferences[];
+
+void EnableRefPoints( LERPedReferences_t *refInfo, int mask );
+void DisableRefPoints( LERPedReferences_t *refInfo, int mask );
+
+void InitReferenceMngr();
+void ReleaseReferenceMngr();
+
+LERPedReferences_t *LERPedReferences_new( int init_refType );
+void LERPedReferences_delete( LERPedReferences_t *toDelete );
+
+#endif
diff --git a/tools/heretic2/qcommon/resourcemanager.c b/tools/heretic2/qcommon/resourcemanager.c
new file mode 100644 (file)
index 0000000..2eb0140
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+//
+// ResourceManager.c
+//
+
+#include <stdio.h>
+#include "resourcemanager.h"
+#include <assert.h>
+
+typedef struct ResMngr_Block_s
+{
+       char *start;
+       unsigned int size;
+       struct ResMngr_Block_s *next;
+} ResMngr_Block_t;
+
+static void ResMngr_CreateBlock( ResourceManager_t *resource ){
+       unsigned int _blockSize;
+       char *block;
+       char **current;
+       ResMngr_Block_t *temp;
+       unsigned int i;
+
+       _blockSize = resource->nodeSize * resource->resPerBlock;
+
+       block = malloc( _blockSize );
+
+       assert( block );
+
+       temp = malloc( sizeof( *temp ) );
+
+       temp->start = block;
+       temp->size = _blockSize;
+       temp->next = resource->blockList;
+
+       resource->blockList = temp;
+
+       resource->free = (char **)( block );
+
+       current = resource->free;
+
+       for ( i = 1; i < resource->resPerBlock; ++i )
+       {
+               // set current->next to point to next node
+               *current = (char *)( current ) + resource->nodeSize;
+
+               // set current node to current->next
+               current = (char **)( *current );
+       }
+
+       *current = NULL;
+}
+
+H2COMMON_API void ResMngr_Con( ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name ){
+       resource->resSize = init_resSize;
+
+       resource->resPerBlock = init_resPerBlock;
+
+       resource->nodeSize = resource->resSize + sizeof( *resource->free );
+
+       resource->blockList = NULL;
+
+       resource->numResourcesAllocated = 0;
+
+       ResMngr_CreateBlock( resource );
+}
+
+H2COMMON_API void ResMngr_Des( ResourceManager_t *resource ){
+       ResMngr_Block_t *toDelete;
+
+#if 0
+       if ( resource->numResourcesAllocated ) {
+               char mess[100];
+               sprintf( mess,"Potential memory leak %d bytes unfreed\n",resource->resSize * resource->numResourcesAllocated );
+               OutputDebugString( mess );
+       }
+#endif
+
+       while ( resource->blockList )
+       {
+               toDelete = resource->blockList;
+               resource->blockList = resource->blockList->next;
+               free( toDelete->start );
+               free( toDelete );
+       }
+}
+
+H2COMMON_API void *ResMngr_AllocateResource( ResourceManager_t *resource, size_t size ){
+       char **toPop;
+
+       assert( size == resource->resSize );
+
+       ++resource->numResourcesAllocated;
+
+       assert( resource->free ); // constructor not called; possibly due to a static object
+       // containing a static ResourceManagerFastLarge member being
+       // constructed before its own static members
+
+       toPop = resource->free;
+
+       // set unallocated to the next node and check for NULL (end of list)
+       if ( !( resource->free = (char **)( *resource->free ) ) ) { // if at end create new block
+               ResMngr_CreateBlock( resource );
+       }
+
+       // set next to NULL
+       *toPop = NULL;
+
+       // return the resource for the node
+       return (void *)( toPop + 1 );
+}
+
+H2COMMON_API void ResMngr_DeallocateResource( ResourceManager_t *resource, void *toDeallocate, size_t size ){
+       char **toPush;
+
+       assert( size == resource->resSize );
+
+       --resource->numResourcesAllocated;
+
+       toPush = (char **)( toDeallocate ) - 1;
+
+       assert( resource->free ); // see same assert at top of AllocateResource
+
+       // set toPop->next to current unallocated front
+       *toPush = (char *)( resource->free );
+
+       // set unallocated to the node removed from allocated
+       resource->free = toPush;
+}
+
+// end
diff --git a/tools/heretic2/qcommon/resourcemanager.h b/tools/heretic2/qcommon/resourcemanager.h
new file mode 100644 (file)
index 0000000..be82d78
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+//
+// ResourceManager.h
+//
+
+#include "h2common.h"
+#include <stdlib.h>     // needed here for size_t
+
+typedef struct ResourceManager_s
+{
+       size_t resSize;
+       unsigned int resPerBlock;
+       unsigned int nodeSize;
+       struct ResMngr_Block_s *blockList;
+       char **free;
+       char *ResMan_Name;
+
+       unsigned numResourcesAllocated;
+
+} ResourceManager_t;
+
+extern H2COMMON_API void ResMngr_Con( ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name );
+extern H2COMMON_API void ResMngr_Des( ResourceManager_t *resource );
+extern H2COMMON_API void *ResMngr_AllocateResource( ResourceManager_t *resource, size_t size );
+extern H2COMMON_API void ResMngr_DeallocateResource( ResourceManager_t *resource, void *toDeallocate, size_t size );
diff --git a/tools/heretic2/qcommon/skeletons.c b/tools/heretic2/qcommon/skeletons.c
new file mode 100644 (file)
index 0000000..453cb77
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+//
+// Skeletons.c
+//
+
+#include "skeletons.h"
+
+char *skeletonRootNames[] =
+{
+       "RAVEN_ROOT",
+       "BOX_ROOT",
+       "BEETLE_ROOT",
+       "ELFLORD_ROOT",
+       "PLAGUELF_ROOT",
+       "ELF_BACKROOT",
+};
+
+int skeletonRNameOffsets[] =
+{
+       0,  // RAVEN
+       1,  // BOX
+       2,  // BEETLE
+       3,  // ELFLORD
+       4,  // PLAGUE ELF
+       5,  // CORVUS
+};
+
+char *skeletonJointNames[] =
+{
+       "RAVEN_LOWERBACK",  // 0
+       "RAVEN_UPPERBACK",
+       "RAVEN_NECK",
+       "BOX_CENTER",       // 3
+       "BEETLE_NECK",      // 4
+       "BEETLE_HEAD",
+       "PLAGUELF_BACKB",   // 6
+       "PLAGUELF_BACKC",
+       "PLAGUELF_NECK",
+       "ELF_BACKB",        // 9
+       "ELF_BACKC",
+       "ELF_NECKB",
+};
+
+int skeletonNameOffsets[] =
+{
+       0,  // RAVEN
+       3,  // BOX
+       4,  // BEETLE
+       -1, // ELFLORD
+       6,  // PLAGUE ELF
+       9,  // CORVUS
+};
+
+char *skeletonEffectorNames[] =
+{
+       "BEETLE_EYES",      // 0
+       "CORVUS_EYES",      // 1
+};
+
+int skeletonENameOffsets[] =
+{
+       -1, // RAVEN
+       -1, // BOX
+       0,  // BEETLE
+       -1, // ELFLORD
+       1,  // PLAGUE ELF
+};
+
+int numJointsInSkeleton[] =
+{
+       NUM_JOINTS_RAVEN,
+       NUM_JOINTS_BOX,
+       NUM_JOINTS_BEETLE,
+       NUM_JOINTS_ELFLORD,
+       NUM_JOINTS_PLAGUE_ELF,
+       NUM_JOINTS_CORVUS,
+};
+
+int numNodesInSkeleton[] =
+{
+       2,  // RAVEN
+       0,  // BOX
+       1,  // BEETLE
+       -1, // ELFLORD
+       2,  // PLAGUE ELF
+       2,  // CORVUS
+};
+
+void CreateRavenSkel( void *g_skeletalJoints, size_t jointSize, struct ArrayedListNode_s *g_jointNodes, int root );
+void CreateBoxSkel( void *g_skeletalJoints, size_t jointSize, struct ArrayedListNode_s *g_jointNodes, int root );
+void CreateBeetleSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex );
+void CreateElfLordSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex );
+void CreatePlagueElfSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex );
+
+CreateSkeleton_t SkeletonCreators[NUM_SKELETONS] =
+{
+       CreateRavenSkel,
+       CreateBoxSkel,
+       CreateBeetleSkel,
+       CreateElfLordSkel,
+       CreatePlagueElfSkel,
+       CreatePlagueElfSkel,    // Corvus has the same structure as the Plague Elf
+};
+
+void CreateRavenSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
+       char *root;
+       int *children;
+       int nodeIndex;
+
+       root = (char *)g_skeletalJoints + rootIndex * jointSize;
+
+       children = (int *)( root + RAVEN_HEAD * jointSize );
+       *children = ARRAYEDLISTNODE_NULL;
+
+       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
+
+       children = (int *)( root + RAVEN_UPPERBACK * jointSize );
+       *children = nodeIndex;
+
+       g_jointNodes[nodeIndex].data = rootIndex + RAVEN_HEAD;
+       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
+
+       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
+
+       children = (int *)( root + RAVEN_LOWERBACK * jointSize );
+       *children = nodeIndex;
+
+       g_jointNodes[nodeIndex].data = rootIndex + RAVEN_UPPERBACK;
+       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
+}
+
+void CreateBoxSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
+       char *root;
+       int *children;
+
+       root = (char *)g_skeletalJoints + rootIndex * jointSize;
+
+       children = (int *)( root + RAVEN_HEAD * jointSize );
+       *children = ARRAYEDLISTNODE_NULL;
+}
+
+void CreateBeetleSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
+       char *root;
+       int *children;
+       int nodeIndex;
+
+       root = (char *)g_skeletalJoints + rootIndex * jointSize;
+
+       children = (int *)( root + BEETLE_HEAD * jointSize );
+       *children = ARRAYEDLISTNODE_NULL;
+
+       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
+
+       children = (int *)( root + BEETLE_NECK * jointSize );
+       *children = nodeIndex;
+
+       g_jointNodes[nodeIndex].data = rootIndex + BEETLE_HEAD;
+       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
+}
+
+void CreateElfLordSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
+       char *root;
+       int *children;
+       int nodeIndex;
+
+       root = (char *)g_skeletalJoints + rootIndex * jointSize;
+
+       children = (int *)( root + BEETLE_HEAD * jointSize );
+       *children = ARRAYEDLISTNODE_NULL;
+
+       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
+
+       children = (int *)( root + BEETLE_NECK * jointSize );
+       *children = nodeIndex;
+
+       g_jointNodes[nodeIndex].data = rootIndex + BEETLE_HEAD;
+       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
+}
+
+void CreatePlagueElfSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
+       char *root;
+       int *children;
+       int nodeIndex;
+
+       root = (char *)g_skeletalJoints + rootIndex * jointSize;
+
+       children = (int *)( root + PLAGUE_ELF_HEAD * jointSize );
+       *children = ARRAYEDLISTNODE_NULL;
+
+       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
+
+       children = (int *)( root + PLAGUE_ELF_UPPERBACK * jointSize );
+       *children = nodeIndex;
+
+       g_jointNodes[nodeIndex].data = rootIndex + PLAGUE_ELF_HEAD;
+       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
+
+       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
+
+       children = (int *)( root + PLAGUE_ELF_LOWERBACK * jointSize );
+       *children = nodeIndex;
+
+       g_jointNodes[nodeIndex].data = rootIndex + PLAGUE_ELF_UPPERBACK;
+       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
+}
diff --git a/tools/heretic2/qcommon/skeletons.h b/tools/heretic2/qcommon/skeletons.h
new file mode 100644 (file)
index 0000000..9d7fe96
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant 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.
+
+   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdlib.h> // for size_t
+#include "arrayedlist.h"
+
+#define JN_YAW_CHANGED      0x00000001
+#define JN_PITCH_CHANGED    0x00000002
+#define JN_ROLL_CHANGED     0x00000004
+
+// Skeleton types
+enum {
+       SKEL_NULL = -1,
+       SKEL_RAVEN = 0,
+       SKEL_BOX,
+       SKEL_BEETLE,
+       SKEL_ELFLORD,
+       SKEL_PLAGUE_ELF,
+       SKEL_CORVUS,
+       NUM_SKELETONS
+};
+
+// Raven Skeletal joints
+enum {
+       RAVEN_LOWERBACK = 0,
+       RAVEN_UPPERBACK,
+       RAVEN_HEAD,
+       NUM_JOINTS_RAVEN
+};
+
+// Box Skeletal joints
+enum {
+       BOX_CENTER = 0,
+       NUM_JOINTS_BOX
+};
+
+// Beetle Skeletal joints
+enum {
+       BEETLE_NECK = 0,
+       BEETLE_HEAD,
+       NUM_JOINTS_BEETLE
+};
+
+// Elflord Skeletal joints
+enum {
+       ELFLORD_,
+       ELFLORD__,
+       NUM_JOINTS_ELFLORD
+};
+
+// Plague Elf Skeletal joints
+enum {
+       PLAGUE_ELF_LOWERBACK,
+       PLAGUE_ELF_UPPERBACK,
+       PLAGUE_ELF_HEAD,
+       NUM_JOINTS_PLAGUE_ELF
+};
+
+// Corvus Skeletal joints
+enum {
+       CORVUS_LOWERBACK,
+       CORVUS_UPPERBACK,
+       CORVUS_HEAD,
+       NUM_JOINTS_CORVUS
+};
+
+#define NO_SWAP_FRAME -1
+#define NULL_ROOT_JOINT -1
+
+#define MAX_ARRAYED_SKELETAL_JOINTS 255 // has max of 65,535 (if this remains at 255, net code can be changed to reflect)
+#define MAX_ARRAYED_JOINT_NODES ( MAX_ARRAYED_SKELETAL_JOINTS - 1 )
+
+#define MAX_JOINTS_PER_SKELETON 8   // arbitrary small number
+#define MAX_JOINT_NODES_PER_SKELETON ( MAX_JOINTS_PER_SKELETON - 1 )
+
+extern char *skeletonRootNames[];
+extern int skeletonRNameOffsets[];
+extern char *skeletonJointNames[];
+extern int skeletonNameOffsets[];
+extern int numJointsInSkeleton[];
+extern char *skeletonEffectorNames[];
+extern int skeletonENameOffsets[];
+extern int numNodesInSkeleton[];
+
+typedef void ( *CreateSkeleton_t )( void *skeletalJoints, size_t jointSize, struct ArrayedListNode_s *jointNodes, int rootIndex );
+
+extern CreateSkeleton_t SkeletonCreators[NUM_SKELETONS];
diff --git a/tools/quake2/qdata_heretic2/CMakeLists.txt b/tools/quake2/qdata_heretic2/CMakeLists.txt
deleted file mode 100644 (file)
index 3413162..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-include_directories(BEFORE . common qcommon)
-
-find_package(OpenGL REQUIRED)
-
-find_package(LibXml2 REQUIRED)
-include_directories(${LIBXML2_INCLUDE_DIR})
-
-radiant_tool(h2data
-    h2data.rc
-
-    common/bspfile.c common/bspfile.h
-    common/cmdlib.c common/cmdlib.h
-    common/inout.c common/inout.h
-    common/l3dslib.c common/l3dslib.h
-    common/lbmlib.c common/lbmlib.h
-    common/mathlib.c common/mathlib.h
-    common/md4.c common/md4.h
-    common/path_init.c
-    common/polylib.c common/polylib.h
-    common/qfiles.c common/qfiles.h
-    common/scriplib.c common/scriplib.h
-    common/threads.c common/her2_threads.h
-    common/token.c common/token.h
-    common/trilib.c common/trilib.h
-
-    qcommon/angles.h
-    qcommon/arrayedlist.h
-    qcommon/flex.h
-    qcommon/fmodel.h
-    qcommon/h2common.h
-    qcommon/placement.h
-    qcommon/qfiles.h
-    qcommon/q_typedef.h
-    qcommon/reference.c qcommon/reference.h
-    qcommon/resourcemanager.c qcommon/resourcemanager.h
-    qcommon/skeletons.c qcommon/skeletons.h
-
-    adpcm.h
-    animcomp.c animcomp.h 
-    anorms.h
-    book.c
-    fmodels.c qd_fmodel.h
-    images.c
-    jointed.c
-    jointed.h
-    joints.h
-    models.c
-    pics.c
-    qdata.c qdata.h
-    qd_skeletons.c qd_skeletons.h
-    resource.h
-    sprites.c
-    svdcmp.c
-    tables.c
-    tmix.c
-    video.c
-)
-
-target_compile_definitions(h2data
-    PRIVATE
-)
-
-target_link_libraries(h2data
-    ${LIBXML2_LIBRARIES}
-    l_net
-)
-
-add_custom_target(heretic2)
-add_dependencies(heretic2 h2data)
-
-if (UNIX)
-    target_link_libraries(h2data pthread m)
-endif ()
diff --git a/tools/quake2/qdata_heretic2/adpcm.h b/tools/quake2/qdata_heretic2/adpcm.h
deleted file mode 100644 (file)
index aad74ea..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-/*
-** adpcm.h - include file for adpcm coder.
-**
-** Version 1.0, 7-Jul-92.
-**
-** Modded 10/3/98
-** John Scott
-*/
-
-typedef struct adpcm_state_s
-{
-       short in_valprev;           // Previous output value
-       short in_index;             // Index into stepsize table
-       short out_valprev;          // Previous output value
-       short out_index;            // Index into stepsize table
-       int count;                  // Number of sample counts
-}   adpcm_state_t;
-
-typedef struct adpcm_s
-{
-       adpcm_state_t state;
-       char adpcm[0x10000];
-}   adpcm_t;
-
-void adpcm_coder( short [], adpcm_t * );
-void adpcm_decoder( adpcm_t *, short [] );
-
-// end
diff --git a/tools/quake2/qdata_heretic2/animcomp.c b/tools/quake2/qdata_heretic2/animcomp.c
deleted file mode 100644 (file)
index a761932..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <memory.h>
-#include "animcomp.h"
-
-
-void    *SafeMalloc( size_t n, char *desc );
-
-
-
-float *matrix;
-float *delta;
-float *best;
-float *comp;
-float *tcomp;
-float *bestcomp;
-float *frames;
-float *base;
-
-int MatWidth;
-int MatHeight;
-int CFrameSize;
-int nFrames;
-
-
-void AnimCompressInit( int nframes,int nVerts,int CompressedFrameSize ){
-       nFrames = nframes;
-       MatWidth = nVerts * 3;
-       MatHeight = CompressedFrameSize;
-       CFrameSize = CompressedFrameSize;
-       matrix = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
-       best = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
-       delta = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
-       comp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
-       tcomp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
-       bestcomp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
-       base = (float *)SafeMalloc( MatWidth * sizeof( float ), "AnimCompressInit" );
-       frames = (float *)SafeMalloc( MatWidth * nFrames * sizeof( float ), "AnimCompressInit" );
-}
-
-void AnimSetFrame( int frame,int index,float x,float y,float z ){
-       frames[frame * MatWidth + index * 3] = x;
-       frames[frame * MatWidth + index * 3 + 1] = y;
-       frames[frame * MatWidth + index * 3 + 2] = z;
-}
-
-typedef struct
-{
-       int index;
-       float val;
-} SORTP;
-
-
-#define F_RANDOM ( ( (float)rand() ) / (float)RAND_MAX )
-
-extern void DOsvd( float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize );
-
-void AnimCompressDoit(){
-       float compression;
-       float *rescale;
-       float *ans;
-       float maxdev;
-       float avedev;
-       float tmp;
-       int j,k,l,numave;
-
-       for ( k = 0; k < MatWidth; k++ )
-               base[k] = 0.0f;
-       for ( j = 0; j < nFrames; j++ )
-               for ( k = 0; k < MatWidth; k++ )
-                       base[k] += frames[j * MatWidth + k];
-       tmp = 1.0f / (float)nFrames;
-       for ( k = 0; k < MatWidth; k++ )
-               base[k] *= tmp;
-       for ( j = 0; j < nFrames; j++ )
-               for ( k = 0; k < MatWidth; k++ )
-                       frames[j * MatWidth + k] -= base[k];
-
-       ans = (float *)SafeMalloc( sizeof( float ) * MatWidth, "AnimCompressDoit" );
-       rescale = (float *)SafeMalloc( sizeof( float ) * CFrameSize, "AnimCompressDoit" );
-       DOsvd( frames,best,bestcomp,rescale,nFrames,MatWidth,MatHeight );
-       avedev = 0.0;
-       for ( l = 0; l < CFrameSize; l++ )
-               avedev += rescale[l];
-       for ( l = 0; l < CFrameSize; l++ )
-               printf( "%3.1f ",100.0f * rescale[l] / avedev );
-       printf( "\n" );
-       for ( j = 0; j < nFrames; j++ )
-       {
-               for ( l = 0; l < CFrameSize; l++ )
-               {
-                       bestcomp[j * CFrameSize + l] = 0.0;
-                       for ( k = 0; k < MatWidth; k++ )
-                               bestcomp[j * CFrameSize + l] += best[l * MatWidth + k] * frames[j * MatWidth + k];
-               }
-       }
-       numave = 0;
-       avedev = 0.0;
-       maxdev = 0.0;
-       for ( j = 0; j < nFrames; j++ )
-       {
-               for ( k = 0; k < MatWidth; k++ )
-               {
-                       ans[k] = 0.0;
-                       for ( l = 0; l < CFrameSize; l++ )
-                               ans[k] += best[l * MatWidth + k] * bestcomp[j * CFrameSize + l];
-                       ans[k] -= frames[j * MatWidth + k];
-                       tmp = (float)fabs( ans[k] );
-                       if ( tmp > maxdev ) {
-                               maxdev = tmp;
-                       }
-                       avedev += tmp;
-                       numave++;
-               }
-       }
-       avedev /= (float)numave;
-       printf( "%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev );
-       printf( "%d bytes original size\n",MatWidth * nFrames );
-       printf( "%d bytes of overhead\n",MatWidth * MatHeight );
-       printf( "%d bytes/frame * %d frames = %d bytes\n",CFrameSize,nFrames,CFrameSize * nFrames );
-       compression = (float)( MatWidth * MatHeight + CFrameSize * nFrames + MatWidth );
-       compression /= (float)( MatWidth * nFrames );
-       printf( "Overall compression = %f %%\n",100.0f - 100.0f * compression );
-       compression = (float)( CFrameSize );
-       compression /= (float)( MatWidth );
-       printf( "frame size compression = %f %%\n",100.0f - 100.0f * compression );
-       free( rescale );
-       free( ans );
-}
-
-void AnimCompressToBytes( float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax ){
-       int k,l,nv,j;
-       float maxdev;
-       float avedev;
-       float tmp;
-       int numave;
-       float t,mx;
-       float *ans;
-
-
-       nv = MatWidth / 3;
-
-       trans[0] = 1E30f;
-       scale[0] = -1E30f;
-       trans[1] = 1E30f;
-       scale[1] = -1E30f;
-       trans[2] = 1E30f;
-       scale[2] = -1E30f;
-       for ( k = 0; k < MatWidth; k += 3 )
-       {
-               if ( base[k] > scale[0] ) {
-                       scale[0] = base[k];
-               }
-               if ( base[k] < trans[0] ) {
-                       trans[0] = base[k];
-               }
-
-               if ( base[k + 1] > scale[1] ) {
-                       scale[1] = base[k + 1];
-               }
-               if ( base[k + 1] < trans[1] ) {
-                       trans[1] = base[k + 1];
-               }
-
-               if ( base[k + 2] > scale[2] ) {
-                       scale[2] = base[k + 2];
-               }
-               if ( base[k + 2] < trans[2] ) {
-                       trans[2] = base[k + 2];
-               }
-       }
-
-       scale[0] -= trans[0];
-       scale[1] -= trans[1];
-       scale[2] -= trans[2];
-       scale[0] /= 255.0f;
-       scale[1] /= 255.0f;
-       scale[2] /= 255.0f;
-       for ( k = 0; k < MatWidth; k += 3 )
-       {
-               t = ( base[k] - trans[0] ) / scale[0];
-               if ( t < 0.0f ) {
-                       t = 0.0f;
-               }
-               if ( t > 255.0f ) {
-                       t = 255.0f;
-               }
-               cbase[k] = (unsigned char)t;
-
-               t = ( base[k + 1] - trans[1] ) / scale[1];
-               if ( t < 0.0f ) {
-                       t = 0.0f;
-               }
-               if ( t > 255.0f ) {
-                       t = 255.0f;
-               }
-               cbase[k + 1] = (unsigned char)t;
-
-               t = ( base[k + 2] - trans[2] ) / scale[2];
-               if ( t < 0.0f ) {
-                       t = 0.0f;
-               }
-               if ( t > 255.0f ) {
-                       t = 255.0f;
-               }
-               cbase[k + 2] = (unsigned char)t;
-       }
-       for ( l = 0; l < MatHeight; l++ )
-       {
-               mx = 0.0;
-               for ( k = 0; k < MatWidth; k++ )
-               {
-                       if ( fabs( best[l * MatWidth + k] ) > mx ) {
-                               mx = (float)fabs( best[l * MatWidth + k] );
-                       }
-               }
-               if ( mx > 1E-8 ) {
-                       mx /= 127.0f;
-                       coffset[l] = 1E30f;
-                       cscale[l] = -1E30f;
-                       for ( j = 0; j < nFrames; j++ )
-                       {
-                               bestcomp[j * MatHeight + l] *= mx;
-                               if ( bestcomp[j * MatHeight + l] > cscale[l] ) {
-                                       cscale[l] = bestcomp[j * MatHeight + l];
-                               }
-                               if ( bestcomp[j * MatHeight + l] < coffset[l] ) {
-                                       coffset[l] = bestcomp[j * MatHeight + l];
-                               }
-                       }
-                       cscale[l] -= coffset[l];
-                       if ( cscale[l] > 1E-10 ) {
-                               for ( j = 0; j < nFrames; j++ )
-                               {
-                                       tmp = 254.0f * ( bestcomp[j * MatHeight + l] - coffset[l] ) / cscale[l] - 127.0f;
-                                       if ( tmp > 127.0f ) {
-                                               tmp = 127.0f;
-                                       }
-                                       if ( tmp < -127.0f ) {
-                                               tmp = -127.0f;
-                                       }
-                                       ccomp[j * MatHeight + l] = (char)floor( tmp + 0.5 );
-                               }
-                               coffset[l] += cscale[l] * 127.0f / 254.0f;
-                               cscale[l] /= 254.0f;
-                       }
-                       else
-                       {
-                               cscale[l] = 1.0f;
-                               coffset[l] = 0.0f;
-                               for ( j = 0; j < nFrames; j++ )
-                                       ccomp[j * MatHeight + l] = 0;
-                       }
-                       mx = 1.0f / mx;
-                       for ( k = 0; k < MatWidth; k++ )
-                       {
-                               tmp = best[l * MatWidth + k] * mx;
-                               if ( tmp > 127.0f ) {
-                                       tmp = 127.0f;
-                               }
-                               if ( tmp < -127.0f ) {
-                                       tmp = -127.0f;
-                               }
-                               mat[k * MatHeight + l] = (char)floor( tmp + 0.5 );
-                       }
-               }
-               else
-               {
-                       cscale[l] = 1.0f;
-                       coffset[l] = 0.0f;
-                       for ( j = 0; j < nFrames; j++ )
-                               ccomp[j * MatHeight + l] = 0;
-                       for ( k = 0; k < MatWidth; k++ )
-                               mat[k * MatHeight + l] = 0;
-               }
-       }
-       bmin[0] = 1E30f;
-       bmin[1] = 1E30f;
-       bmin[2] = 1E30f;
-       bmax[0] = -1E30f;
-       bmax[1] = -1E30f;
-       bmax[2] = -1E30f;
-       numave = 0;
-       avedev = 0.0;
-       maxdev = 0.0;
-       ans = (float *)SafeMalloc( sizeof( float ) * MatWidth, "AnimCompressToBytes" );
-       for ( j = 0; j < nFrames; j++ )
-       {
-               for ( k = 0; k < MatWidth; k++ )
-               {
-                       ans[k] = 0.0;
-                       for ( l = 0; l < CFrameSize; l++ )
-                               ans[k] += (float)( mat[l + k * MatHeight] ) * ( (float)( ccomp[j * CFrameSize + l] ) * cscale[l] + coffset[l] );
-                       ans[k] += (float)( cbase[k] ) * scale[k % 3] + trans[k % 3];
-                       tmp = (float)fabs( ans[k] - frames[j * MatWidth + k] - base[k] );
-                       if ( tmp > maxdev ) {
-                               maxdev = tmp;
-                       }
-                       avedev += tmp;
-                       numave++;
-
-                       if ( bmin[k % 3] > ans[k] ) {
-                               bmin[k % 3] = ans[k];
-                       }
-                       if ( bmax[k % 3] < ans[k] ) {
-                               bmax[k % 3] = ans[k];
-                       }
-               }
-       }
-       avedev /= (float)numave;
-       printf( "%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev );
-       free( ans );
-}
-
-void AnimCompressGetMatrix( float *mat ){
-       int k,l;
-       for ( k = 0; k < MatWidth; k++ )
-               for ( l = 0; l < MatHeight; l++ )
-                       mat[k * MatHeight + l] = best[l * MatWidth + k];
-}
-
-void AnimCompressGetFrames( float *mat ){
-       memcpy( mat,bestcomp,CFrameSize * nFrames * sizeof( float ) );
-}
-
-void AnimCompressGetBase( int i,float *x,float *y,float *z ){
-       *x = base[i * 3];
-       *y = base[i * 3 + 1];
-       *z = base[i * 3 + 2];
-}
-
-void AnimCompressEnd(){
-       free( matrix );
-       free( best );
-       free( delta );
-       free( comp );
-       free( tcomp );
-       free( bestcomp );
-       free( base );
-       free( frames );
-}
diff --git a/tools/quake2/qdata_heretic2/animcomp.h b/tools/quake2/qdata_heretic2/animcomp.h
deleted file mode 100644 (file)
index 36ea3b1..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#if !defined( ANIMCOMP_INC )
-#define ANIMCOMP_INC
-
-#ifdef  __cplusplus
-extern "C"
-{
-#endif
-void AnimCompressInit( int nFrames,int nVerts,int CompressedFrameSize );
-void AnimSetFrame( int frame,int index,float x,float y,float z );
-void AnimCompressDoit();
-void AnimCompressToBytes( float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax );
-void AnimCompressGetMatrix( float *mat );
-void AnimCompressGetFrames( float *mat );
-void AnimCompressGetBase( int i,float *x,float *y,float *z );
-void AnimCompressEnd();
-void DOsvdPlane( float *pnts,int npnts,float *n,float *base );
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/anorms.h b/tools/quake2/qdata_heretic2/anorms.h
deleted file mode 100644 (file)
index 65e92ef..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-{-0.525731f, 0.000000f, 0.850651f},
-{-0.442863f, 0.238856f, 0.864188f},
-{-0.295242f, 0.000000f, 0.955423f},
-{-0.309017f, 0.500000f, 0.809017f},
-{-0.162460f, 0.262866f, 0.951056f},
-{0.000000f, 0.000000f, 1.000000f},
-{0.000000f, 0.850651f, 0.525731f},
-{-0.147621f, 0.716567f, 0.681718f},
-{0.147621f, 0.716567f, 0.681718f},
-{0.000000f, 0.525731f, 0.850651f},
-{0.309017f, 0.500000f, 0.809017f},
-{0.525731f, 0.000000f, 0.850651f},
-{0.295242f, 0.000000f, 0.955423f},
-{0.442863f, 0.238856f, 0.864188f},
-{0.162460f, 0.262866f, 0.951056f},
-{-0.681718f, 0.147621f, 0.716567f},
-{-0.809017f, 0.309017f, 0.500000f},
-{-0.587785f, 0.425325f, 0.688191f},
-{-0.850651f, 0.525731f, 0.000000f},
-{-0.864188f, 0.442863f, 0.238856f},
-{-0.716567f, 0.681718f, 0.147621f},
-{-0.688191f, 0.587785f, 0.425325f},
-{-0.500000f, 0.809017f, 0.309017f},
-{-0.238856f, 0.864188f, 0.442863f},
-{-0.425325f, 0.688191f, 0.587785f},
-{-0.716567f, 0.681718f, -0.147621f},
-{-0.500000f, 0.809017f, -0.309017f},
-{-0.525731f, 0.850651f, 0.000000f},
-{0.000000f, 0.850651f, -0.525731f},
-{-0.238856f, 0.864188f, -0.442863f},
-{0.000000f, 0.955423f, -0.295242f},
-{-0.262866f, 0.951056f, -0.162460f},
-{0.000000f, 1.000000f, 0.000000f},
-{0.000000f, 0.955423f, 0.295242f},
-{-0.262866f, 0.951056f, 0.162460f},
-{0.238856f, 0.864188f, 0.442863f},
-{0.262866f, 0.951056f, 0.162460f},
-{0.500000f, 0.809017f, 0.309017f},
-{0.238856f, 0.864188f, -0.442863f},
-{0.262866f, 0.951056f, -0.162460f},
-{0.500000f, 0.809017f, -0.309017f},
-{0.850651f, 0.525731f, 0.000000f},
-{0.716567f, 0.681718f, 0.147621f},
-{0.716567f, 0.681718f, -0.147621f},
-{0.525731f, 0.850651f, 0.000000f},
-{0.425325f, 0.688191f, 0.587785f},
-{0.864188f, 0.442863f, 0.238856f},
-{0.688191f, 0.587785f, 0.425325f},
-{0.809017f, 0.309017f, 0.500000f},
-{0.681718f, 0.147621f, 0.716567f},
-{0.587785f, 0.425325f, 0.688191f},
-{0.955423f, 0.295242f, 0.000000f},
-{1.000000f, 0.000000f, 0.000000f},
-{0.951056f, 0.162460f, 0.262866f},
-{0.850651f, -0.525731f, 0.000000f},
-{0.955423f, -0.295242f, 0.000000f},
-{0.864188f, -0.442863f, 0.238856f},
-{0.951056f, -0.162460f, 0.262866f},
-{0.809017f, -0.309017f, 0.500000f},
-{0.681718f, -0.147621f, 0.716567f},
-{0.850651f, 0.000000f, 0.525731f},
-{0.864188f, 0.442863f, -0.238856f},
-{0.809017f, 0.309017f, -0.500000f},
-{0.951056f, 0.162460f, -0.262866f},
-{0.525731f, 0.000000f, -0.850651f},
-{0.681718f, 0.147621f, -0.716567f},
-{0.681718f, -0.147621f, -0.716567f},
-{0.850651f, 0.000000f, -0.525731f},
-{0.809017f, -0.309017f, -0.500000f},
-{0.864188f, -0.442863f, -0.238856f},
-{0.951056f, -0.162460f, -0.262866f},
-{0.147621f, 0.716567f, -0.681718f},
-{0.309017f, 0.500000f, -0.809017f},
-{0.425325f, 0.688191f, -0.587785f},
-{0.442863f, 0.238856f, -0.864188f},
-{0.587785f, 0.425325f, -0.688191f},
-{0.688191f, 0.587785f, -0.425325f},
-{-0.147621f, 0.716567f, -0.681718f},
-{-0.309017f, 0.500000f, -0.809017f},
-{0.000000f, 0.525731f, -0.850651f},
-{-0.525731f, 0.000000f, -0.850651f},
-{-0.442863f, 0.238856f, -0.864188f},
-{-0.295242f, 0.000000f, -0.955423f},
-{-0.162460f, 0.262866f, -0.951056f},
-{0.000000f, 0.000000f, -1.000000f},
-{0.295242f, 0.000000f, -0.955423f},
-{0.162460f, 0.262866f, -0.951056f},
-{-0.442863f, -0.238856f, -0.864188f},
-{-0.309017f, -0.500000f, -0.809017f},
-{-0.162460f, -0.262866f, -0.951056f},
-{0.000000f, -0.850651f, -0.525731f},
-{-0.147621f, -0.716567f, -0.681718f},
-{0.147621f, -0.716567f, -0.681718f},
-{0.000000f, -0.525731f, -0.850651f},
-{0.309017f, -0.500000f, -0.809017f},
-{0.442863f, -0.238856f, -0.864188f},
-{0.162460f, -0.262866f, -0.951056f},
-{0.238856f, -0.864188f, -0.442863f},
-{0.500000f, -0.809017f, -0.309017f},
-{0.425325f, -0.688191f, -0.587785f},
-{0.716567f, -0.681718f, -0.147621f},
-{0.688191f, -0.587785f, -0.425325f},
-{0.587785f, -0.425325f, -0.688191f},
-{0.000000f, -0.955423f, -0.295242f},
-{0.000000f, -1.000000f, 0.000000f},
-{0.262866f, -0.951056f, -0.162460f},
-{0.000000f, -0.850651f, 0.525731f},
-{0.000000f, -0.955423f, 0.295242f},
-{0.238856f, -0.864188f, 0.442863f},
-{0.262866f, -0.951056f, 0.162460f},
-{0.500000f, -0.809017f, 0.309017f},
-{0.716567f, -0.681718f, 0.147621f},
-{0.525731f, -0.850651f, 0.000000f},
-{-0.238856f, -0.864188f, -0.442863f},
-{-0.500000f, -0.809017f, -0.309017f},
-{-0.262866f, -0.951056f, -0.162460f},
-{-0.850651f, -0.525731f, 0.000000f},
-{-0.716567f, -0.681718f, -0.147621f},
-{-0.716567f, -0.681718f, 0.147621f},
-{-0.525731f, -0.850651f, 0.000000f},
-{-0.500000f, -0.809017f, 0.309017f},
-{-0.238856f, -0.864188f, 0.442863f},
-{-0.262866f, -0.951056f, 0.162460f},
-{-0.864188f, -0.442863f, 0.238856f},
-{-0.809017f, -0.309017f, 0.500000f},
-{-0.688191f, -0.587785f, 0.425325f},
-{-0.681718f, -0.147621f, 0.716567f},
-{-0.442863f, -0.238856f, 0.864188f},
-{-0.587785f, -0.425325f, 0.688191f},
-{-0.309017f, -0.500000f, 0.809017f},
-{-0.147621f, -0.716567f, 0.681718f},
-{-0.425325f, -0.688191f, 0.587785f},
-{-0.162460f, -0.262866f, 0.951056f},
-{0.442863f, -0.238856f, 0.864188f},
-{0.162460f, -0.262866f, 0.951056f},
-{0.309017f, -0.500000f, 0.809017f},
-{0.147621f, -0.716567f, 0.681718f},
-{0.000000f, -0.525731f, 0.850651f},
-{0.425325f, -0.688191f, 0.587785f},
-{0.587785f, -0.425325f, 0.688191f},
-{0.688191f, -0.587785f, 0.425325f},
-{-0.955423f, 0.295242f, 0.000000f},
-{-0.951056f, 0.162460f, 0.262866f},
-{-1.000000f, 0.000000f, 0.000000f},
-{-0.850651f, 0.000000f, 0.525731f},
-{-0.955423f, -0.295242f, 0.000000f},
-{-0.951056f, -0.162460f, 0.262866f},
-{-0.864188f, 0.442863f, -0.238856f},
-{-0.951056f, 0.162460f, -0.262866f},
-{-0.809017f, 0.309017f, -0.500000f},
-{-0.864188f, -0.442863f, -0.238856f},
-{-0.951056f, -0.162460f, -0.262866f},
-{-0.809017f, -0.309017f, -0.500000f},
-{-0.681718f, 0.147621f, -0.716567f},
-{-0.681718f, -0.147621f, -0.716567f},
-{-0.850651f, 0.000000f, -0.525731f},
-{-0.688191f, 0.587785f, -0.425325f},
-{-0.587785f, 0.425325f, -0.688191f},
-{-0.425325f, 0.688191f, -0.587785f},
-{-0.425325f, -0.688191f, -0.587785f},
-{-0.587785f, -0.425325f, -0.688191f},
-{-0.688191f, -0.587785f, -0.425325f},
diff --git a/tools/quake2/qdata_heretic2/book.c b/tools/quake2/qdata_heretic2/book.c
deleted file mode 100644 (file)
index 412aefe..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#include "qdata.h"
-
-byte            *byteimage, *lbmpalette;
-int byteimagewidth, byteimageheight;
-
-qboolean TrueColorImage;
-int longimagewidth, longimageheight;
-
-char book_prefix[1024];
-byte buffer[640 * 480];
-unsigned long bufferl[640 * 480];
-
-miptex_t *CreateBook8( byte *buffer, int w, int h, byte *palette, int *FinalSize ){
-       miptex_t    *mp;
-       int i, j;
-       byte        *pos;
-       int size;
-
-       size = sizeof( *mp ) + ( w * h );
-       mp = (miptex_t *)SafeMalloc( size, "CreateBook8" );
-       memset( mp, 0, size );
-
-       mp->version = MIP_VERSION;
-
-       for ( i = j = 0; i < 256; i++,j += 3 )
-       {
-               mp->palette[i].r = palette[j];
-               mp->palette[i].g = palette[j + 1];
-               mp->palette[i].b = palette[j + 2];
-       }
-       pos = (byte *)( mp + 1 );
-
-       mp->width[0] = w;
-       mp->height[0] = h;
-       mp->offsets[0] = sizeof( *mp );
-       memcpy( pos, buffer, w * h );
-
-       *FinalSize = size;
-       return( mp );
-}
-
-miptex32_t *CreateBook32( long *buffer, int w, int h, int *FinalSize ){
-       miptex32_t  *mp;
-       byte        *pos;
-       int size;
-
-       size = sizeof( *mp ) + ( w * h * 4 );
-       mp = (miptex32_t *)SafeMalloc( size, "CreateBook32" );
-       memset( mp, 0, size );
-
-       mp->version = MIP32_VERSION;
-
-       pos = (byte *)( mp + 1 );
-
-       mp->width[0] = w;
-       mp->height[0] = h;
-       mp->offsets[0] = sizeof( *mp );
-       memcpy( pos, buffer, w * h * 4 );
-
-       *FinalSize = size;
-       return( mp );
-}
-
-
-// Routines to chop a random sized image into gl texture friendly chunks
-
-typedef struct rect_s
-{
-       int x, y;
-       int w, h;
-       char name[4];
-} rect_t;
-
-int GetCoords( int x, int store[MAX_MD2SKINS] ){
-       int index, start, delta;
-
-       index = 0;
-       start = 0;
-       delta = 256;
-
-       store[index++] = start;
-       while ( x )
-       {
-               if ( x >= delta ) {
-                       start += delta;
-                       store[index++] = start;
-                       x -= delta;
-               }
-               else
-               {
-                       delta >>= 1;
-               }
-       }
-       return( index );
-}
-
-int ChopImage( int w, int h, rect_t coords[MAX_MD2SKINS] ){
-       int xs[MAX_MD2SKINS], ys[MAX_MD2SKINS];
-       int xcount, ycount, x, y, index;
-
-       index = 0;
-       xcount = GetCoords( w, xs ) - 1;
-       ycount = GetCoords( h, ys ) - 1;
-
-       for ( y = 0; y < ycount; y++ )
-       {
-               for ( x = 0; x < xcount; x++, index++ )
-               {
-                       coords[index].x = xs[x];
-                       coords[index].y = ys[y];
-                       coords[index].w = xs[x + 1] - xs[x];
-                       coords[index].h = ys[y + 1] - ys[y];
-                       coords[index].name[0] = x + '0';
-                       coords[index].name[1] = y + '0';
-                       coords[index].name[2] = 0;
-               }
-       }
-       return( index );
-}
-
-/*
-   ===============
-   Cmd_Pic
-   ===============
- */
-
-void Cmd_Book(){
-       int xl,yl,xh,yh,w,h;
-       byte            *dest, *source;
-       int flags, value, contents;
-       char lumpname[64];
-       char filename[1024];
-       unsigned long   *destl, *sourcel;
-       int linedelta, x, y;
-       int size;
-       miptex_t        *qtex;
-       miptex32_t      *qtex32;
-       float scale_x, scale_y;
-       int numrects, i;
-       rect_t coords[MAX_MD2SKINS];
-       bookframe_t bframes[MAX_MD2SKINS];
-       bookframe_t     *bf;
-       book_t book;
-
-       GetScriptToken( false );
-       strcpy( lumpname, token );
-
-       GetScriptToken( false );
-       xl = atoi( token );
-       GetScriptToken( false );
-       yl = atoi( token );
-       GetScriptToken( false );
-       w = atoi( token );
-       GetScriptToken( false );
-       h = atoi( token );
-
-       total_x += w;
-       total_y += h;
-       total_textures++;
-
-       if ( ( w & 7 ) || ( h & 7 ) ) {
-               Error( "line %i: miptex sizes must be multiples of 8", scriptline );
-       }
-
-       flags = 0;
-       contents = 0;
-       value = 0;
-
-       scale_x = scale_y = 0.5;
-
-       if ( g_release ) {
-               return;
-       }
-
-       if ( TrueColorImage ) {
-               xh = xl + w;
-               yh = yl + h;
-
-               if ( xl >= longimagewidth || xh > longimagewidth ||
-                        yl >= longimageheight || yh > longimageheight ) {
-                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight );
-               }
-
-               sourcel = (unsigned long *) longimage + ( yl * longimagewidth ) + xl;
-               destl = (unsigned long *) longimage;
-               linedelta = ( longimagewidth - w );
-
-               for ( y = yl; y < yh; y++ )
-               {
-                       for ( x = xl; x < xh; x++ )
-                       {
-                               *destl++ = *sourcel++;  // RGBA
-                       }
-                       sourcel += linedelta;
-               }
-
-               // Get rectangles to chop into
-               numrects = ChopImage( w, h, coords );
-
-               bf = bframes;
-               for ( i = 0; i < numrects; i++, bf++ )
-               {
-                       // Copy section of image to buffer
-                       sourcel = (unsigned long *) longimage + ( coords[i].y * w ) + coords[i].x;
-                       destl = bufferl;
-                       linedelta = w - coords[i].w;
-
-                       for ( y = 0; y < coords[i].h; y++ )
-                       {
-                               for ( x = 0; x < coords[i].w; x++ )
-                               {
-                                       *destl++ = *sourcel++;
-                               }
-                               sourcel += linedelta;
-                       }
-
-                       qtex32 = CreateBook32( bufferl, coords[i].w, coords[i].h, &size );
-
-                       qtex32->flags = flags;
-                       qtex32->contents = contents;
-                       qtex32->value = value;
-                       qtex32->scale_x = scale_x;
-                       qtex32->scale_y = scale_y;
-
-                       sprintf( filename, "%sbook/%s/%s_%s.m32", gamedir, book_prefix, lumpname, coords[i].name );
-                       sprintf( qtex32->name, "%s/%s_%s.m32", book_prefix, lumpname, coords[i].name );
-
-                       strcpy( bf->name, qtex32->name );
-                       bf->x = coords[i].x;
-                       bf->y = coords[i].y;
-                       bf->w = coords[i].w;
-                       bf->h = coords[i].h;
-                       //
-                       // write it out
-                       //
-                       printf( "writing %s\n", filename );
-                       SaveFile( filename, (byte *)qtex32, size );
-
-                       free( qtex32 );
-               }
-       }
-       else
-       {
-               xh = xl + w;
-               yh = yl + h;
-
-               if ( xl >= byteimagewidth || xh > byteimagewidth ||
-                        yl >= byteimageheight || yh > byteimageheight ) {
-                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
-               }
-
-               // Copy image to top left
-               source = byteimage + yl * byteimagewidth + xl;
-               dest = byteimage;
-               linedelta = byteimagewidth - w;
-
-               for ( y = yl; y < yh; y++ )
-               {
-                       for ( x = xl; x < xh; x++ )
-                       {
-                               *dest++ = *source++;
-                       }
-                       source += linedelta;
-               }
-
-               // Get rectangles to chop into
-               numrects = ChopImage( w, h, coords );
-
-               bf = bframes;
-               for ( i = 0; i < numrects; i++, bf++ )
-               {
-                       // Copy section of image to buffer
-                       source = byteimage + ( coords[i].y * w ) + coords[i].x;
-                       dest = buffer;
-                       linedelta = w - coords[i].w;
-
-                       for ( y = 0; y < coords[i].h; y++ )
-                       {
-                               for ( x = 0; x < coords[i].w; x++ )
-                               {
-                                       *dest++ = *source++;
-                               }
-                               source += linedelta;
-                       }
-
-                       qtex = CreateBook8( buffer, coords[i].w, coords[i].h, lbmpalette, &size );
-
-                       qtex->flags = flags;
-                       qtex->contents = contents;
-                       qtex->value = value;
-
-                       sprintf( filename, "%sbook/%s/%s_%s.m8", gamedir, book_prefix, lumpname, coords[i].name );
-                       sprintf( qtex->name, "%s/%s_%s.m8", book_prefix, lumpname, coords[i].name );
-
-                       strcpy( bf->name, qtex->name );
-                       bf->x = coords[i].x;
-                       bf->y = coords[i].y;
-                       bf->w = coords[i].w;
-                       bf->h = coords[i].h;
-                       //
-                       // write it out
-                       //
-                       printf( "writing %s\n", filename );
-                       SaveFile( filename, (byte *)qtex, size );
-
-                       free( qtex );
-               }
-       }
-       // Set up descriptor
-       size = sizeof( bookframe_t ) * numrects;
-
-       book.bheader.ident = IDBOOKHEADER;
-       book.bheader.version = BOOK_VERSION;
-       book.bheader.num_segments = numrects;
-       book.bheader.total_w = w;
-       book.bheader.total_h = h;
-       memcpy( book.bframes, bframes, size );
-
-       // Save out segment descriptor
-       sprintf( filename, "%sBook/%s/%s.bk", gamedir, book_prefix, lumpname );
-       printf( "writing %s\n", filename );
-       SaveFile( filename, (byte *)&book, size + sizeof( bookheader_t ) );
-}
-
-/*
-   ===============
-   Cmd_picdir
-   ===============
- */
-void Cmd_Bookdir( void ){
-       char filename[1024];
-
-       GetScriptToken( false );
-       strcpy( book_prefix, token );
-       // create the directory if needed
-       sprintf( filename, "%sBook", gamedir );
-       Q_mkdir( filename );
-       sprintf( filename, "%sBook/%s", gamedir, book_prefix );
-       Q_mkdir( filename );
-}
-
-// end
diff --git a/tools/quake2/qdata_heretic2/common/bspfile.c b/tools/quake2/qdata_heretic2/common/bspfile.c
deleted file mode 100644 (file)
index add0ef3..0000000
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#include "cmdlib.h"
-#include "inout.h"
-#include "mathlib.h"
-#include "bspfile.h"
-#include "scriplib.h"
-
-void GetLeafNums( void );
-
-//=============================================================================
-
-int nummodels;
-dmodel_t dmodels[MAX_MAP_MODELS];
-
-int visdatasize;
-byte dvisdata[MAX_MAP_VISIBILITY];
-dvis_t      *dvis = (dvis_t *)dvisdata;
-
-int lightdatasize;
-byte dlightdata[MAX_MAP_LIGHTING];
-
-int entdatasize;
-char dentdata[MAX_MAP_ENTSTRING];
-
-int numleafs;
-dleaf_t dleafs[MAX_MAP_LEAFS];
-
-int numplanes;
-dplane_t dplanes[MAX_MAP_PLANES];
-
-int numvertexes;
-dvertex_t dvertexes[MAX_MAP_VERTS];
-
-int numnodes;
-dnode_t dnodes[MAX_MAP_NODES];
-
-int numtexinfo;
-texinfo_t texinfo[MAX_MAP_TEXINFO];
-
-int numfaces;
-dface_t dfaces[MAX_MAP_FACES];
-
-int numedges;
-dedge_t dedges[MAX_MAP_EDGES];
-
-int numleaffaces;
-unsigned short dleaffaces[MAX_MAP_LEAFFACES];
-
-int numleafbrushes;
-unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
-
-int numsurfedges;
-int dsurfedges[MAX_MAP_SURFEDGES];
-
-int numbrushes;
-dbrush_t dbrushes[MAX_MAP_BRUSHES];
-
-int numbrushsides;
-dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
-
-int numareas;
-darea_t dareas[MAX_MAP_AREAS];
-
-int numareaportals;
-dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
-
-byte dpop[256];
-
-/*
-   ===============
-   CompressVis
-
-   ===============
- */
-int CompressVis( byte *vis, byte *dest ){
-       int j;
-       int rep;
-       int visrow;
-       byte    *dest_p;
-
-       dest_p = dest;
-//     visrow = (r_numvisleafs + 7)>>3;
-       visrow = ( dvis->numclusters + 7 ) >> 3;
-
-       for ( j = 0 ; j < visrow ; j++ )
-       {
-               *dest_p++ = vis[j];
-               if ( vis[j] ) {
-                       continue;
-               }
-
-               rep = 1;
-               for ( j++; j < visrow ; j++ )
-                       if ( vis[j] || rep == 255 ) {
-                               break;
-                       }
-                       else{
-                               rep++;
-                       }
-               *dest_p++ = rep;
-               j--;
-       }
-
-       return dest_p - dest;
-}
-
-
-/*
-   ===================
-   DecompressVis
-   ===================
- */
-void DecompressVis( byte *in, byte *decompressed ){
-       int c;
-       byte    *out;
-       int row;
-
-//     row = (r_numvisleafs+7)>>3;
-       row = ( dvis->numclusters + 7 ) >> 3;
-       out = decompressed;
-
-       do
-       {
-               if ( *in ) {
-                       *out++ = *in++;
-                       continue;
-               }
-
-               c = in[1];
-               if ( !c ) {
-                       Error( "DecompressVis: 0 repeat" );
-               }
-               in += 2;
-               while ( c )
-               {
-                       *out++ = 0;
-                       c--;
-               }
-       } while ( out - decompressed < row );
-}
-
-//=============================================================================
-
-/*
-   =============
-   SwapBSPFile
-
-   Byte swaps all data in a bsp file.
-   =============
- */
-void SwapBSPFile( qboolean todisk ){
-       int i, j;
-       dmodel_t        *d;
-
-
-// models
-       for ( i = 0 ; i < nummodels ; i++ )
-       {
-               d = &dmodels[i];
-
-               d->firstface = LittleLong( d->firstface );
-               d->numfaces = LittleLong( d->numfaces );
-               d->headnode = LittleLong( d->headnode );
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       d->mins[j] = LittleFloat( d->mins[j] );
-                       d->maxs[j] = LittleFloat( d->maxs[j] );
-                       d->origin[j] = LittleFloat( d->origin[j] );
-               }
-       }
-
-//
-// vertexes
-//
-       for ( i = 0 ; i < numvertexes ; i++ )
-       {
-               for ( j = 0 ; j < 3 ; j++ )
-                       dvertexes[i].point[j] = LittleFloat( dvertexes[i].point[j] );
-       }
-
-//
-// planes
-//
-       for ( i = 0 ; i < numplanes ; i++ )
-       {
-               for ( j = 0 ; j < 3 ; j++ )
-                       dplanes[i].normal[j] = LittleFloat( dplanes[i].normal[j] );
-               dplanes[i].dist = LittleFloat( dplanes[i].dist );
-               dplanes[i].type = LittleLong( dplanes[i].type );
-       }
-
-//
-// texinfos
-//
-       for ( i = 0 ; i < numtexinfo ; i++ )
-       {
-               for ( j = 0 ; j < 8 ; j++ )
-                       texinfo[i].vecs[0][j] = LittleFloat( texinfo[i].vecs[0][j] );
-               texinfo[i].flags = LittleLong( texinfo[i].flags );
-               texinfo[i].value = LittleLong( texinfo[i].value );
-               texinfo[i].nexttexinfo = LittleLong( texinfo[i].nexttexinfo );
-       }
-
-//
-// faces
-//
-       for ( i = 0 ; i < numfaces ; i++ )
-       {
-               dfaces[i].texinfo = LittleShort( dfaces[i].texinfo );
-               dfaces[i].planenum = LittleShort( dfaces[i].planenum );
-               dfaces[i].side = LittleShort( dfaces[i].side );
-               dfaces[i].lighting.c = LittleLong( dfaces[i].lighting.c );
-               dfaces[i].lightofs = LittleLong( dfaces[i].lightofs );
-               dfaces[i].firstedge = LittleLong( dfaces[i].firstedge );
-               dfaces[i].numedges = LittleShort( dfaces[i].numedges );
-       }
-
-//
-// nodes
-//
-       for ( i = 0 ; i < numnodes ; i++ )
-       {
-               dnodes[i].planenum = LittleLong( dnodes[i].planenum );
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       dnodes[i].mins[j] = LittleShort( dnodes[i].mins[j] );
-                       dnodes[i].maxs[j] = LittleShort( dnodes[i].maxs[j] );
-               }
-               dnodes[i].children[0] = LittleLong( dnodes[i].children[0] );
-               dnodes[i].children[1] = LittleLong( dnodes[i].children[1] );
-               dnodes[i].firstface = LittleShort( dnodes[i].firstface );
-               dnodes[i].numfaces = LittleShort( dnodes[i].numfaces );
-       }
-
-//
-// leafs
-//
-       for ( i = 0 ; i < numleafs ; i++ )
-       {
-               dleafs[i].contents = LittleLong( dleafs[i].contents );
-               dleafs[i].cluster = LittleShort( dleafs[i].cluster );
-               dleafs[i].area = LittleShort( dleafs[i].area );
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       dleafs[i].mins[j] = LittleShort( dleafs[i].mins[j] );
-                       dleafs[i].maxs[j] = LittleShort( dleafs[i].maxs[j] );
-               }
-
-               dleafs[i].firstleafface = LittleShort( dleafs[i].firstleafface );
-               dleafs[i].numleaffaces = LittleShort( dleafs[i].numleaffaces );
-               dleafs[i].firstleafbrush = LittleShort( dleafs[i].firstleafbrush );
-               dleafs[i].numleafbrushes = LittleShort( dleafs[i].numleafbrushes );
-       }
-
-//
-// leaffaces
-//
-       for ( i = 0 ; i < numleaffaces ; i++ )
-               dleaffaces[i] = LittleShort( dleaffaces[i] );
-
-//
-// leafbrushes
-//
-       for ( i = 0 ; i < numleafbrushes ; i++ )
-               dleafbrushes[i] = LittleShort( dleafbrushes[i] );
-
-//
-// surfedges
-//
-       for ( i = 0 ; i < numsurfedges ; i++ )
-               dsurfedges[i] = LittleLong( dsurfedges[i] );
-
-//
-// edges
-//
-       for ( i = 0 ; i < numedges ; i++ )
-       {
-               dedges[i].v[0] = LittleShort( dedges[i].v[0] );
-               dedges[i].v[1] = LittleShort( dedges[i].v[1] );
-       }
-
-//
-// brushes
-//
-       for ( i = 0 ; i < numbrushes ; i++ )
-       {
-               dbrushes[i].firstside = LittleLong( dbrushes[i].firstside );
-               dbrushes[i].numsides = LittleLong( dbrushes[i].numsides );
-               dbrushes[i].contents = LittleLong( dbrushes[i].contents );
-       }
-
-//
-// areas
-//
-       for ( i = 0 ; i < numareas ; i++ )
-       {
-               dareas[i].numareaportals = LittleLong( dareas[i].numareaportals );
-               dareas[i].firstareaportal = LittleLong( dareas[i].firstareaportal );
-       }
-
-//
-// areasportals
-//
-       for ( i = 0 ; i < numareaportals ; i++ )
-       {
-               dareaportals[i].portalnum = LittleLong( dareaportals[i].portalnum );
-               dareaportals[i].otherarea = LittleLong( dareaportals[i].otherarea );
-       }
-
-//
-// brushsides
-//
-       for ( i = 0 ; i < numbrushsides ; i++ )
-       {
-               dbrushsides[i].planenum = LittleShort( dbrushsides[i].planenum );
-               dbrushsides[i].texinfo = LittleShort( dbrushsides[i].texinfo );
-       }
-
-//
-// visibility
-//
-       if ( todisk ) {
-               j = dvis->numclusters;
-       }
-       else{
-               j = LittleLong( dvis->numclusters );
-       }
-       dvis->numclusters = LittleLong( dvis->numclusters );
-       for ( i = 0 ; i < j ; i++ )
-       {
-               dvis->bitofs[i][0] = LittleLong( dvis->bitofs[i][0] );
-               dvis->bitofs[i][1] = LittleLong( dvis->bitofs[i][1] );
-       }
-}
-
-
-dheader_t   *header;
-
-int CopyLump( int lump, void *dest, int size ){
-       int length, ofs;
-
-       length = header->lumps[lump].filelen;
-       ofs = header->lumps[lump].fileofs;
-
-       if ( length % size ) {
-               Error( "LoadBSPFile: odd lump size" );
-       }
-
-       memcpy( dest, (byte *)header + ofs, length );
-
-       return length / size;
-}
-
-/*
-   =============
-   LoadBSPFile
-   =============
- */
-void    LoadBSPFile( char *filename ){
-       int i;
-
-//
-// load the file header
-//
-       LoadFile( filename, (void **)&header );
-
-// swap the header
-       for ( i = 0 ; i < sizeof( dheader_t ) / 4 ; i++ )
-               ( (int *)header )[i] = LittleLong( ( (int *)header )[i] );
-
-       if ( header->ident != IDBSPHEADER ) {
-               Error( "%s is not a IBSP file", filename );
-       }
-       if ( header->version != BSPVERSION ) {
-               Error( "%s is version %i, not %i", filename, header->version, BSPVERSION );
-       }
-
-       nummodels = CopyLump( LUMP_MODELS, dmodels, sizeof( dmodel_t ) );
-       numvertexes = CopyLump( LUMP_VERTEXES, dvertexes, sizeof( dvertex_t ) );
-       numplanes = CopyLump( LUMP_PLANES, dplanes, sizeof( dplane_t ) );
-       numleafs = CopyLump( LUMP_LEAFS, dleafs, sizeof( dleaf_t ) );
-       numnodes = CopyLump( LUMP_NODES, dnodes, sizeof( dnode_t ) );
-       numtexinfo = CopyLump( LUMP_TEXINFO, texinfo, sizeof( texinfo_t ) );
-       numfaces = CopyLump( LUMP_FACES, dfaces, sizeof( dface_t ) );
-       numleaffaces = CopyLump( LUMP_LEAFFACES, dleaffaces, sizeof( dleaffaces[0] ) );
-       numleafbrushes = CopyLump( LUMP_LEAFBRUSHES, dleafbrushes, sizeof( dleafbrushes[0] ) );
-       numsurfedges = CopyLump( LUMP_SURFEDGES, dsurfedges, sizeof( dsurfedges[0] ) );
-       numedges = CopyLump( LUMP_EDGES, dedges, sizeof( dedge_t ) );
-       numbrushes = CopyLump( LUMP_BRUSHES, dbrushes, sizeof( dbrush_t ) );
-       numbrushsides = CopyLump( LUMP_BRUSHSIDES, dbrushsides, sizeof( dbrushside_t ) );
-       numareas = CopyLump( LUMP_AREAS, dareas, sizeof( darea_t ) );
-       numareaportals = CopyLump( LUMP_AREAPORTALS, dareaportals, sizeof( dareaportal_t ) );
-
-       visdatasize = CopyLump( LUMP_VISIBILITY, dvisdata, 1 );
-       lightdatasize = CopyLump( LUMP_LIGHTING, dlightdata, 1 );
-       entdatasize = CopyLump( LUMP_ENTITIES, dentdata, 1 );
-
-       CopyLump( LUMP_POP, dpop, 1 );
-
-       free( header );      // everything has been copied out
-
-//
-// swap everything
-//
-       SwapBSPFile( false );
-}
-
-
-/*
-   =============
-   LoadBSPFileTexinfo
-
-   Only loads the texinfo lump, so qdata can scan for textures
-   =============
- */
-void    LoadBSPFileTexinfo( char *filename ){
-       int i;
-       FILE        *f;
-       int length, ofs;
-
-       header = malloc( sizeof( dheader_t ) );
-
-       f = fopen( filename, "rb" );
-       fread( header, sizeof( dheader_t ), 1, f );
-
-// swap the header
-       for ( i = 0 ; i < sizeof( dheader_t ) / 4 ; i++ )
-               ( (int *)header )[i] = LittleLong( ( (int *)header )[i] );
-
-       if ( header->ident != IDBSPHEADER ) {
-               Error( "%s is not a IBSP file", filename );
-       }
-       if ( header->version != BSPVERSION ) {
-               Error( "%s is version %i, not %i", filename, header->version, BSPVERSION );
-       }
-
-
-       length = header->lumps[LUMP_TEXINFO].filelen;
-       ofs = header->lumps[LUMP_TEXINFO].fileofs;
-
-       fseek( f, ofs, SEEK_SET );
-       fread( texinfo, length, 1, f );
-       fclose( f );
-
-       numtexinfo = length / sizeof( texinfo_t );
-
-       free( header );      // everything has been copied out
-
-       SwapBSPFile( false );
-}
-
-
-//============================================================================
-
-FILE        *wadfile;
-dheader_t outheader;
-
-void AddLump( int lumpnum, void *data, int len ){
-       lump_t *lump;
-
-       lump = &header->lumps[lumpnum];
-
-       lump->fileofs = LittleLong( ftell( wadfile ) );
-       lump->filelen = LittleLong( len );
-       SafeWrite( wadfile, data, ( len + 3 ) & ~3 );
-}
-
-/*
-   =============
-   WriteBSPFile
-
-   Swaps the bsp file in place, so it should not be referenced again
-   =============
- */
-void    WriteBSPFile( char *filename ){
-       header = &outheader;
-       memset( header, 0, sizeof( dheader_t ) );
-
-       SwapBSPFile( true );
-
-       header->ident = LittleLong( IDBSPHEADER );
-       header->version = LittleLong( BSPVERSION );
-
-       wadfile = SafeOpenWrite( filename );
-       SafeWrite( wadfile, header, sizeof( dheader_t ) ); // overwritten later
-
-       AddLump( LUMP_PLANES, dplanes, numplanes * sizeof( dplane_t ) );
-       AddLump( LUMP_LEAFS, dleafs, numleafs * sizeof( dleaf_t ) );
-       AddLump( LUMP_VERTEXES, dvertexes, numvertexes * sizeof( dvertex_t ) );
-       AddLump( LUMP_NODES, dnodes, numnodes * sizeof( dnode_t ) );
-       AddLump( LUMP_TEXINFO, texinfo, numtexinfo * sizeof( texinfo_t ) );
-       AddLump( LUMP_FACES, dfaces, numfaces * sizeof( dface_t ) );
-       AddLump( LUMP_BRUSHES, dbrushes, numbrushes * sizeof( dbrush_t ) );
-       AddLump( LUMP_BRUSHSIDES, dbrushsides, numbrushsides * sizeof( dbrushside_t ) );
-       AddLump( LUMP_LEAFFACES, dleaffaces, numleaffaces * sizeof( dleaffaces[0] ) );
-       AddLump( LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) );
-       AddLump( LUMP_SURFEDGES, dsurfedges, numsurfedges * sizeof( dsurfedges[0] ) );
-       AddLump( LUMP_EDGES, dedges, numedges * sizeof( dedge_t ) );
-       AddLump( LUMP_MODELS, dmodels, nummodels * sizeof( dmodel_t ) );
-       AddLump( LUMP_AREAS, dareas, numareas * sizeof( darea_t ) );
-       AddLump( LUMP_AREAPORTALS, dareaportals, numareaportals * sizeof( dareaportal_t ) );
-
-       AddLump( LUMP_LIGHTING, dlightdata, lightdatasize );
-       AddLump( LUMP_VISIBILITY, dvisdata, visdatasize );
-       AddLump( LUMP_ENTITIES, dentdata, entdatasize );
-       AddLump( LUMP_POP, dpop, sizeof( dpop ) );
-
-       fseek( wadfile, 0, SEEK_SET );
-       SafeWrite( wadfile, header, sizeof( dheader_t ) );
-       fclose( wadfile );
-}
-
-//============================================================================
-
-/*
-   =============
-   PrintBSPFileSizes
-
-   Dumps info about current file
-   =============
- */
-void PrintBSPFileSizes( void ){
-       if ( !num_entities ) {
-               ParseEntities();
-       }
-
-       printf( "%5i models       %7i\n"
-                       ,nummodels, (int)( nummodels * sizeof( dmodel_t ) ) );
-       printf( "%5i brushes      %7i\n"
-                       ,numbrushes, (int)( numbrushes * sizeof( dbrush_t ) ) );
-       printf( "%5i brushsides   %7i\n"
-                       ,numbrushsides, (int)( numbrushsides * sizeof( dbrushside_t ) ) );
-       printf( "%5i planes       %7i\n"
-                       ,numplanes, (int)( numplanes * sizeof( dplane_t ) ) );
-       printf( "%5i texinfo      %7i\n"
-                       ,numtexinfo, (int)( numtexinfo * sizeof( texinfo_t ) ) );
-       printf( "%5i entdata      %7i\n", num_entities, entdatasize );
-
-       printf( "\n" );
-
-       printf( "%5i vertexes     %7i\n"
-                       ,numvertexes, (int)( numvertexes * sizeof( dvertex_t ) ) );
-       printf( "%5i nodes        %7i\n"
-                       ,numnodes, (int)( numnodes * sizeof( dnode_t ) ) );
-       printf( "%5i faces        %7i\n"
-                       ,numfaces, (int)( numfaces * sizeof( dface_t ) ) );
-       printf( "%5i leafs        %7i\n"
-                       ,numleafs, (int)( numleafs * sizeof( dleaf_t ) ) );
-       printf( "%5i leaffaces    %7i\n"
-                       ,numleaffaces, (int)( numleaffaces * sizeof( dleaffaces[0] ) ) );
-       printf( "%5i leafbrushes  %7i\n"
-                       ,numleafbrushes, (int)( numleafbrushes * sizeof( dleafbrushes[0] ) ) );
-       printf( "%5i surfedges    %7i\n"
-                       ,numsurfedges, (int)( numsurfedges * sizeof( dsurfedges[0] ) ) );
-       printf( "%5i edges        %7i\n"
-                       ,numedges, (int)( numedges * sizeof( dedge_t ) ) );
-       printf( "      lightdata    %7i\n", lightdatasize );
-       printf( "      visdata      %7i\n", visdatasize );
-}
-
-
-//============================================
-
-int num_entities;
-entity_t entities[MAX_MAP_ENTITIES];
-
-void StripTrailing( char *e ){
-       char    *s;
-
-       s = e + strlen( e ) - 1;
-       while ( s >= e && *s <= 32 )
-       {
-               *s = 0;
-               s--;
-       }
-}
-
-/*
-   =================
-   ParseEpair
-   =================
- */
-epair_t *ParseEpair( void ){
-       epair_t *e;
-
-       e = malloc( sizeof( epair_t ) );
-       memset( e, 0, sizeof( epair_t ) );
-
-       if ( strlen( token ) >= MAX_KEY - 1 ) {
-               Error( "ParseEpar: token too long" );
-       }
-       e->key = copystring( token );
-       GetScriptToken( false );
-       if ( strlen( token ) >= MAX_VALUE - 1 ) {
-               Error( "ParseEpar: token too long" );
-       }
-       e->value = copystring( token );
-
-       // strip trailing spaces
-       StripTrailing( e->key );
-       StripTrailing( e->value );
-
-       return e;
-}
-
-
-/*
-   ================
-   ParseEntity
-   ================
- */
-qboolean    ParseEntity( void ){
-       epair_t     *e;
-       entity_t    *mapent;
-
-       if ( !GetScriptToken( true ) ) {
-               return false;
-       }
-
-       if ( strcmp( token, "{" ) ) {
-               Error( "ParseEntity: { not found" );
-       }
-
-       if ( num_entities == MAX_MAP_ENTITIES ) {
-               Error( "num_entities == MAX_MAP_ENTITIES" );
-       }
-
-       mapent = &entities[num_entities];
-       num_entities++;
-
-       do
-       {
-               if ( !GetScriptToken( true ) ) {
-                       Error( "ParseEntity: EOF without closing brace" );
-               }
-               if ( !strcmp( token, "}" ) ) {
-                       break;
-               }
-               e = ParseEpair();
-               e->next = mapent->epairs;
-               mapent->epairs = e;
-       } while ( 1 );
-
-       return true;
-}
-
-/*
-   ================
-   ParseEntities
-
-   Parses the dentdata string into entities
-   ================
- */
-void ParseEntities( void ){
-       num_entities = 0;
-       ParseFromMemory( dentdata, entdatasize );
-
-       while ( ParseEntity() )
-       {
-       }
-}
-
-
-/*
-   ================
-   UnparseEntities
-
-   Generates the dentdata string from all the entities
-   ================
- */
-void UnparseEntities( void ){
-       char    *buf, *end;
-       epair_t *ep;
-       char line[2048];
-       int i;
-       char key[1024], value[1024];
-
-       buf = dentdata;
-       end = buf;
-       *end = 0;
-
-       for ( i = 0 ; i < num_entities ; i++ )
-       {
-               ep = entities[i].epairs;
-               if ( !ep ) {
-                       continue;   // ent got removed
-
-               }
-               strcat( end,"{\n" );
-               end += 2;
-
-               for ( ep = entities[i].epairs ; ep ; ep = ep->next )
-               {
-                       strcpy( key, ep->key );
-                       StripTrailing( key );
-                       strcpy( value, ep->value );
-                       StripTrailing( value );
-
-                       sprintf( line, "\"%s\" \"%s\"\n", key, value );
-                       strcat( end, line );
-                       end += strlen( line );
-               }
-               strcat( end,"}\n" );
-               end += 2;
-
-               if ( end > buf + MAX_MAP_ENTSTRING ) {
-                       Error( "Entity text too long" );
-               }
-       }
-       entdatasize = end - buf + 1;
-}
-
-void PrintEntity( entity_t *ent ){
-       epair_t *ep;
-
-       printf( "------- entity %p -------\n", ent );
-       for ( ep = ent->epairs ; ep ; ep = ep->next )
-       {
-               printf( "%s = %s\n", ep->key, ep->value );
-       }
-
-}
-
-void    SetKeyValue( entity_t *ent, char *key, char *value ){
-       epair_t *ep;
-
-       for ( ep = ent->epairs ; ep ; ep = ep->next )
-               if ( !strcmp( ep->key, key ) ) {
-                       free( ep->value );
-                       ep->value = copystring( value );
-                       return;
-               }
-       ep = malloc( sizeof( *ep ) );
-       if ( !ep ) {
-               Error( "SetKeyValue MALLOC failed!  Could not allocate %s bytes.", sizeof( *ep ) );
-       }
-       ep->next = ent->epairs;
-       ent->epairs = ep;
-       ep->key = copystring( key );
-       ep->value = copystring( value );
-}
-
-char    *ValueForKey( entity_t *ent, char *key ){
-       epair_t *ep;
-
-       for ( ep = ent->epairs ; ep ; ep = ep->next )
-               if ( !strcmp( ep->key, key ) ) {
-                       return ep->value;
-               }
-       return "";
-}
-
-vec_t   FloatForKey( entity_t *ent, char *key ){
-       char    *k;
-
-       k = ValueForKey( ent, key );
-       return atof( k );
-}
-
-void    GetVectorForKey( entity_t *ent, char *key, vec3_t vec ){
-       char    *k;
-       double v1, v2, v3;
-
-       k = ValueForKey( ent, key );
-// scanf into doubles, then assign, so it is vec_t size independent
-       v1 = v2 = v3 = 0;
-       sscanf( k, "%lf %lf %lf", &v1, &v2, &v3 );
-       vec[0] = v1;
-       vec[1] = v2;
-       vec[2] = v3;
-}
diff --git a/tools/quake2/qdata_heretic2/common/bspfile.h b/tools/quake2/qdata_heretic2/common/bspfile.h
deleted file mode 100644 (file)
index f66659b..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _QBSP3_H
-#define _QBSP3_H
-
-
-#include "qfiles.h"
-
-
-extern int nummodels;
-extern dmodel_t dmodels[MAX_MAP_MODELS];
-
-extern int visdatasize;
-extern byte dvisdata[MAX_MAP_VISIBILITY];
-extern dvis_t      *dvis;
-
-extern int lightdatasize;
-extern byte dlightdata[MAX_MAP_LIGHTING];
-
-extern int entdatasize;
-extern char dentdata[MAX_MAP_ENTSTRING];
-
-extern int numleafs;
-extern dleaf_t dleafs[MAX_MAP_LEAFS];
-
-extern int numplanes;
-extern dplane_t dplanes[MAX_MAP_PLANES];
-
-extern int numvertexes;
-extern dvertex_t dvertexes[MAX_MAP_VERTS];
-
-extern int numnodes;
-extern dnode_t dnodes[MAX_MAP_NODES];
-
-extern int numtexinfo;
-extern texinfo_t texinfo[MAX_MAP_TEXINFO];
-
-extern int numfaces;
-extern dface_t dfaces[MAX_MAP_FACES];
-
-extern int numedges;
-extern dedge_t dedges[MAX_MAP_EDGES];
-
-extern int numleaffaces;
-extern unsigned short dleaffaces[MAX_MAP_LEAFFACES];
-
-extern int numleafbrushes;
-extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
-
-extern int numsurfedges;
-extern int dsurfedges[MAX_MAP_SURFEDGES];
-
-extern int numareas;
-extern darea_t dareas[MAX_MAP_AREAS];
-
-extern int numareaportals;
-extern dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
-
-extern int numbrushes;
-extern dbrush_t dbrushes[MAX_MAP_BRUSHES];
-
-extern int numbrushsides;
-extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
-
-extern byte dpop[256];
-
-void DecompressVis( byte *in, byte *decompressed );
-int CompressVis( byte *vis, byte *dest );
-
-void    LoadBSPFile( char *filename );
-void    LoadBSPFileTexinfo( char *filename );    // just for qdata
-void    WriteBSPFile( char *filename );
-void    PrintBSPFileSizes( void );
-
-//===============
-
-
-typedef struct epair_s
-{
-       struct epair_s  *next;
-       char    *key;
-       char    *value;
-} epair_t;
-
-typedef struct
-{
-       vec3_t origin;
-       int firstbrush;
-       int numbrushes;
-       epair_t     *epairs;
-
-// only valid for func_areaportals
-       int areaportalnum;
-       int portalareas[2];
-} entity_t;
-
-extern int num_entities;
-extern entity_t entities[MAX_MAP_ENTITIES];
-
-void    ParseEntities( void );
-void    UnparseEntities( void );
-
-void    SetKeyValue( entity_t *ent, char *key, char *value );
-char    *ValueForKey( entity_t *ent, char *key );
-// will return "" if not present
-
-vec_t   FloatForKey( entity_t *ent, char *key );
-void    GetVectorForKey( entity_t *ent, char *key, vec3_t vec );
-
-epair_t *ParseEpair( void );
-
-void PrintEntity( entity_t *ent );
-
-#endif //_QBSP3_H
diff --git a/tools/quake2/qdata_heretic2/common/cmdlib.c b/tools/quake2/qdata_heretic2/common/cmdlib.c
deleted file mode 100644 (file)
index c45ff16..0000000
+++ /dev/null
@@ -1,1186 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// Nurail: Swiped from quake3/common
-
-#include "cmdlib.h"
-#include "globaldefs.h"
-#include "mathlib.h"
-#include "inout.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if GDEF_OS_WINDOWS
-#include <direct.h>
-#include <windows.h>
-#elif GDEF_OS_NEXT
-#include <libc.h>
-#else // OTHER OSES
-#include <unistd.h>
-#endif // OTHER OSES
-
-#if !GDEF_OS_WINDOWS
-#define strlwr strlower
-#endif // !GDEF_OS_WINDOWS
-
-#define BASEDIRNAME "h"
-#define PATHSEPERATOR '/'
-
-extern qboolean verbose;
-
-qboolean g_dokeypress = false;
-
-qboolean g_nomkdir = false;
-
-
-#ifdef SAFE_MALLOC
-void *safe_malloc( size_t size ){
-       void *p;
-
-       p = malloc( size );
-       if ( !p ) {
-               Error( "safe_malloc failed on allocation of %i bytes", size );
-       }
-
-       return p;
-}
-
-void *safe_malloc_info( size_t size, char* info ){
-       void *p;
-
-       p = malloc( size );
-       if ( !p ) {
-               Error( "%s: safe_malloc failed on allocation of %i bytes", info, size );
-       }
-
-       return p;
-}
-#endif // !SAFE_MALLOC
-
-void *SafeMalloc( size_t n, char *desc ){
-       void *p;
-
-       if ( ( p = malloc( n ) ) == NULL ) {
-               Error( "Failed to allocate %d bytes for '%s'.\n", n, desc );
-       }
-       memset( p, 0, n );
-       return p;
-}
-
-// set these before calling CheckParm
-int myargc;
-char **myargv;
-
-char com_token[1024];
-qboolean com_eof;
-
-qboolean archive;
-char archivedir[1024];
-
-
-/*
-   ===================
-   ExpandWildcards
-
-   Mimic unix command line expansion
-   ===================
- */
-#define MAX_EX_ARGC 1024
-
-int ex_argc;
-char    *ex_argv[MAX_EX_ARGC];
-
-#if GDEF_OS_WINDOWS
-#include "io.h"
-void ExpandWildcards( int *argc, char ***argv ){
-       struct _finddata_t fileinfo;
-       int handle;
-       int i;
-       char filename[1024];
-       char filebase[1024];
-       char    *path;
-
-       ex_argc = 0;
-       for ( i = 0 ; i < *argc ; i++ )
-       {
-               path = ( *argv )[i];
-               if ( path[0] == '-'
-                        || ( !strstr( path, "*" ) && !strstr( path, "?" ) ) ) {
-                       ex_argv[ex_argc++] = path;
-                       continue;
-               }
-
-               handle = _findfirst( path, &fileinfo );
-               if ( handle == -1 ) {
-                       return;
-               }
-
-               ExtractFilePath( path, filebase );
-
-               do
-               {
-                       sprintf( filename, "%s%s", filebase, fileinfo.name );
-                       ex_argv[ex_argc++] = copystring( filename );
-               } while ( _findnext( handle, &fileinfo ) != -1 );
-
-               _findclose( handle );
-       }
-
-       *argc = ex_argc;
-       *argv = ex_argv;
-}
-#else // !GDEF_OS_WINDOWS
-void ExpandWildcards( int *argc, char ***argv ){
-}
-#endif // !GDEF_OS_WINDOWS
-
-/*
-
-   qdir will hold the path up to the quake directory, including the slash
-
-   f:\quake\
-   /raid/quake/
-
-   gamedir will hold qdir + the game directory (id1, id2, etc)
-
- */
-
-char qdir[1024];
-char gamedir[1024];
-char writedir[1024];
-
-void SetQdirFromPath( const char *path ){
-       char temp[1024];
-       const char  *c;
-       const char *sep;
-       int len, count;
-
-       if ( !( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) ) { // path is partial
-               Q_getwd( temp );
-               strcat( temp, path );
-               path = temp;
-       }
-
-       // search for "quake2" in path
-
-       len = strlen( BASEDIRNAME );
-       for ( c = path + strlen( path ) - 1 ; c != path ; c-- )
-       {
-               int i;
-
-               if ( !Q_strncasecmp( c, BASEDIRNAME, len ) ) {
-                       //
-                       //strncpy (qdir, path, c+len+2-path);
-                       // the +2 assumes a 2 or 3 following quake which is not the
-                       // case with a retail install
-                       // so we need to add up how much to the next separator
-                       sep = c + len;
-                       count = 1;
-                       while ( *sep && *sep != '/' && *sep != '\\' )
-                       {
-                               sep++;
-                               count++;
-                       }
-                       strncpy( qdir, path, c + len + count - path );
-                       Sys_Printf( "qdir: %s\n", qdir );
-                       for ( i = 0; i < strlen( qdir ); i++ )
-                       {
-                               if ( qdir[i] == '\\' ) {
-                                       qdir[i] = '/';
-                               }
-                       }
-
-                       c += len + count;
-                       while ( *c )
-                       {
-                               if ( *c == '/' || *c == '\\' ) {
-                                       strncpy( gamedir, path, c + 1 - path );
-
-                                       for ( i = 0; i < strlen( gamedir ); i++ )
-                                       {
-                                               if ( gamedir[i] == '\\' ) {
-                                                       gamedir[i] = '/';
-                                               }
-                                       }
-
-                                       Sys_Printf( "gamedir: %s\n", gamedir );
-
-                                       if ( !writedir[0] ) {
-                                               strcpy( writedir, gamedir );
-                                       }
-                                       else if ( writedir[strlen( writedir ) - 1] != '/' ) {
-                                               writedir[strlen( writedir )] = '/';
-                                               writedir[strlen( writedir ) + 1] = 0;
-                                       }
-
-                                       return;
-                               }
-                               c++;
-                       }
-                       Error( "No gamedir in %s", path );
-                       return;
-               }
-       }
-       Error( "SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path );
-}
-
-char *ExpandArg( const char *path ){
-       static char full[1024];
-
-       if ( path[0] != '/' && path[0] != '\\' && path[1] != ':' ) {
-               Q_getwd( full );
-               strcat( full, path );
-       }
-       else{
-               strcpy( full, path );
-       }
-       return full;
-}
-
-char *ExpandPath( const char *path ){
-       static char full[1024];
-       if ( !qdir ) {
-               Error( "ExpandPath called without qdir set" );
-       }
-       if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) {
-               strcpy( full, path );
-               return full;
-       }
-       sprintf( full, "%s%s", qdir, path );
-       return full;
-}
-
-char *ExpandGamePath( const char *path ){
-       static char full[1024];
-       if ( !qdir ) {
-               Error( "ExpandGamePath called without qdir set" );
-       }
-       if ( path[0] == '/' || path[0] == '\\' || path[1] == ':' ) {
-               strcpy( full, path );
-               return full;
-       }
-       sprintf( full, "%s%s", gamedir, path );
-       return full;
-}
-
-char *ExpandPathAndArchive( const char *path ){
-       char    *expanded;
-       char archivename[1024];
-
-       expanded = ExpandPath( path );
-
-       if ( archive ) {
-               sprintf( archivename, "%s/%s", archivedir, path );
-               QCopyFile( expanded, archivename );
-       }
-       return expanded;
-}
-
-
-char *copystring( const char *s ){
-       char    *b;
-       b = safe_malloc( strlen( s ) + 1 );
-       strcpy( b, s );
-       return b;
-}
-
-
-
-/*
-   ================
-   I_FloatTime
-   ================
- */
-double I_FloatTime( void ){
-       time_t t;
-
-       time( &t );
-
-       return t;
-#if 0
-// more precise, less portable
-       struct timeval tp;
-       struct timezone tzp;
-       static int secbase;
-
-       gettimeofday( &tp, &tzp );
-
-       if ( !secbase ) {
-               secbase = tp.tv_sec;
-               return tp.tv_usec / 1000000.0;
-       }
-
-       return ( tp.tv_sec - secbase ) + tp.tv_usec / 1000000.0;
-#endif
-}
-
-void Q_getwd( char *out ){
-       int i = 0;
-
-#if GDEF_OS_WINDOWS
-       _getcwd( out, 256 );
-       strcat( out, "\\" );
-#else // !GDEF_OS_WINDOWS
-       // Gef: Changed from getwd() to getcwd() to avoid potential buffer overflow
-       getcwd( out, 256 );
-       strcat( out, "/" );
-#endif // !GDEF_OS_WINDOWS
-       while ( out[i] != 0 )
-       {
-               if ( out[i] == '\\' ) {
-                       out[i] = '/';
-               }
-               i++;
-       }
-}
-
-
-void Q_mkdir( const char *path ){
-#if GDEF_OS_WINDOWS
-       if ( _mkdir( path ) != -1 ) {
-               return;
-       }
-#else // !GDEF_OS_WINDOWS
-       if ( mkdir( path, 0777 ) != -1 ) {
-               return;
-       }
-#endif // !GDEF_OS_WINDOWS
-       if ( errno != EEXIST ) {
-               Error( "mkdir %s: %s",path, strerror( errno ) );
-       }
-}
-
-/*
-   ============
-   FileTime
-
-   returns -1 if not present
-   ============
- */
-int FileTime( const char *path ){
-       struct  stat buf;
-
-       if ( stat( path,&buf ) == -1 ) {
-               return -1;
-       }
-
-       return buf.st_mtime;
-}
-
-
-
-/*
-   ==============
-   COM_Parse
-
-   Parse a token out of a string
-   ==============
- */
-char *COM_Parse( char *data ){
-       int c;
-       int len;
-
-       len = 0;
-       com_token[0] = 0;
-
-       if ( !data ) {
-               return NULL;
-       }
-
-// skip whitespace
-skipwhite:
-       while ( ( c = *data ) <= ' ' )
-       {
-               if ( c == 0 ) {
-                       com_eof = true;
-                       return NULL;            // end of file;
-               }
-               data++;
-       }
-
-// skip // comments
-       if ( c == '/' && data[1] == '/' ) {
-               while ( *data && *data != '\n' )
-                       data++;
-               goto skipwhite;
-       }
-
-
-// handle quoted strings specially
-       if ( c == '\"' ) {
-               data++;
-               do
-               {
-                       c = *data++;
-                       if ( c == '\"' ) {
-                               com_token[len] = 0;
-                               return data;
-                       }
-                       com_token[len] = c;
-                       len++;
-               } while ( 1 );
-       }
-
-// parse single characters
-       if ( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' ) {
-               com_token[len] = c;
-               len++;
-               com_token[len] = 0;
-               return data + 1;
-       }
-
-// parse a regular word
-       do
-       {
-               com_token[len] = c;
-               data++;
-               len++;
-               c = *data;
-               if ( c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' ) {
-                       break;
-               }
-       } while ( c > 32 );
-
-       com_token[len] = 0;
-       return data;
-}
-
-int Q_strncasecmp( const char *s1, const char *s2, int n ){
-       int c1, c2;
-
-       do
-       {
-               c1 = *s1++;
-               c2 = *s2++;
-
-               if ( !n-- ) {
-                       return 0;       // strings are equal until end point
-
-               }
-               if ( c1 != c2 ) {
-                       if ( c1 >= 'a' && c1 <= 'z' ) {
-                               c1 -= ( 'a' - 'A' );
-                       }
-                       if ( c2 >= 'a' && c2 <= 'z' ) {
-                               c2 -= ( 'a' - 'A' );
-                       }
-                       if ( c1 != c2 ) {
-                               return -1;      // strings not equal
-                       }
-               }
-       } while ( c1 );
-
-       return 0;       // strings are equal
-}
-
-int Q_stricmp( const char *s1, const char *s2 ){
-       return Q_strncasecmp( s1, s2, 99999 );
-}
-
-int Q_strcasecmp( const char *s1, const char *s2 ){
-       return Q_strncasecmp( s1, s2, 99999 );
-}
-
-// NOTE TTimo when switching to Multithread DLL (Release/Debug) in the config
-//   started getting warnings about that function, prolly a duplicate with the runtime function
-//   maybe we still need to have it in linux builds
-/*
-   char *strupr (char *start)
-   {
-    char       *in;
-    in = start;
-    while (*in)
-    {
-   *in = toupper(*in);
-        in++;
-    }
-    return start;
-   }
- */
-
-char *strlower( char *start ){
-       char    *in;
-       in = start;
-       while ( *in )
-       {
-               *in = tolower( *in );
-               in++;
-       }
-       return start;
-}
-
-
-/*
-   =============================================================================
-
-                        MISC FUNCTIONS
-
-   =============================================================================
- */
-
-
-/*
-   =================
-   CheckParm
-
-   Checks for the given parameter in the program's command line arguments
-   Returns the argument number (1 to argc-1) or 0 if not present
-   =================
- */
-int CheckParm( const char *check ){
-       int i;
-
-       for ( i = 1; i < myargc; i++ )
-       {
-               if ( !Q_stricmp( check, myargv[i] ) ) {
-                       return i;
-               }
-       }
-
-       return 0;
-}
-
-
-
-/*
-   ================
-   Q_filelength
-   ================
- */
-int Q_filelength( FILE *f ){
-       int pos;
-       int end;
-
-       pos = ftell( f );
-       fseek( f, 0, SEEK_END );
-       end = ftell( f );
-       fseek( f, pos, SEEK_SET );
-
-       return end;
-}
-
-
-FILE *SafeOpenWrite( const char *filename ){
-       FILE    *f;
-
-       f = fopen( filename, "wb" );
-
-       if ( !f ) {
-               Error( "Error opening %s: %s",filename,strerror( errno ) );
-       }
-
-       return f;
-}
-
-FILE *SafeOpenRead( const char *filename ){
-       FILE    *f;
-
-       f = fopen( filename, "rb" );
-
-       if ( !f ) {
-               Error( "Error opening %s: %s",filename,strerror( errno ) );
-       }
-
-       return f;
-}
-
-
-void SafeRead( FILE *f, void *buffer, int count ){
-       if ( fread( buffer, 1, count, f ) != (size_t)count ) {
-               Error( "File read failure" );
-       }
-}
-
-
-void SafeWrite( FILE *f, const void *buffer, int count ){
-       if ( fwrite( buffer, 1, count, f ) != (size_t)count ) {
-               Error( "File write failure" );
-       }
-}
-
-
-/*
-   ==============
-   FileExists
-   ==============
- */
-qboolean    FileExists( const char *filename ){
-       FILE    *f;
-
-       f = fopen( filename, "r" );
-       if ( !f ) {
-               return false;
-       }
-       fclose( f );
-       return true;
-}
-
-/*
-   ==============
-   LoadFile
-   ==============
- */
-int    LoadFile( const char *filename, void **bufferptr ){
-       FILE    *f;
-       int length;
-       void    *buffer;
-
-       f = SafeOpenRead( filename );
-       length = Q_filelength( f );
-       buffer = safe_malloc( length + 1 );
-       ( (char *)buffer )[length] = 0;
-       SafeRead( f, buffer, length );
-       fclose( f );
-
-       *bufferptr = buffer;
-       return length;
-}
-
-
-/*
-   ==============
-   LoadFileBlock
-   -
-   rounds up memory allocation to 4K boundry
-   -
-   ==============
- */
-int    LoadFileBlock( const char *filename, void **bufferptr ){
-       FILE    *f;
-       int length, nBlock, nAllocSize;
-       void    *buffer;
-
-       f = SafeOpenRead( filename );
-       length = Q_filelength( f );
-       nAllocSize = length;
-       nBlock = nAllocSize % MEM_BLOCKSIZE;
-       if ( nBlock > 0 ) {
-               nAllocSize += MEM_BLOCKSIZE - nBlock;
-       }
-       buffer = safe_malloc( nAllocSize + 1 );
-       memset( buffer, 0, nAllocSize + 1 );
-       SafeRead( f, buffer, length );
-       fclose( f );
-
-       *bufferptr = buffer;
-       return length;
-}
-
-
-/*
-   ==============
-   TryLoadFile
-
-   Allows failure
-   ==============
- */
-int    TryLoadFile( const char *filename, void **bufferptr ){
-       FILE    *f;
-       int length;
-       void    *buffer;
-
-       *bufferptr = NULL;
-
-       f = fopen( filename, "rb" );
-       if ( !f ) {
-               return -1;
-       }
-       length = Q_filelength( f );
-       buffer = safe_malloc( length + 1 );
-       ( (char *)buffer )[length] = 0;
-       SafeRead( f, buffer, length );
-       fclose( f );
-
-       *bufferptr = buffer;
-       return length;
-}
-
-
-/*
-   ==============
-   SaveFile
-   ==============
- */
-void    SaveFile( const char *filename, const void *buffer, int count ){
-       FILE    *f;
-
-       f = SafeOpenWrite( filename );
-       SafeWrite( f, buffer, count );
-       fclose( f );
-}
-
-
-
-void DefaultExtension( char *path, const char *extension ){
-       char    *src;
-//
-// if path doesnt have a .EXT, append extension
-// (extension should include the .)
-//
-       src = path + strlen( path ) - 1;
-
-       while ( *src != '/' && *src != '\\' && src != path )
-       {
-               if ( *src == '.' ) {
-                       return;                 // it has an extension
-               }
-               src--;
-       }
-
-       strcat( path, extension );
-}
-
-
-void DefaultPath( char *path, const char *basepath ){
-       char temp[128];
-
-       if ( path[ 0 ] == '/' || path[ 0 ] == '\\' ) {
-               return;                   // absolute path location
-       }
-       strcpy( temp,path );
-       strcpy( path,basepath );
-       strcat( path,temp );
-}
-
-
-void    StripFilename( char *path ){
-       int length;
-
-       length = strlen( path ) - 1;
-       while ( length > 0 && path[length] != '/' && path[ length ] != '\\' )
-               length--;
-       path[length] = 0;
-}
-
-void    StripExtension( char *path ){
-       int length;
-
-       length = strlen( path ) - 1;
-       while ( length > 0 && path[length] != '.' )
-       {
-               length--;
-               if ( path[length] == '/' || path[ length ] == '\\' ) {
-                       return;     // no extension
-               }
-       }
-       if ( length ) {
-               path[length] = 0;
-       }
-}
-
-
-/*
-   ====================
-   Extract file parts
-   ====================
- */
-
-// FIXME: should include the slash, otherwise
-// backing to an empty path will be wrong when appending a slash
-void ExtractFilePath( const char *path, char *dest ){
-       const char    *src;
-
-       src = path + strlen( path ) - 1;
-
-//
-// back up until a \ or the start
-//
-       while ( src != path && *( src - 1 ) != '\\' && *( src - 1 ) != '/' )
-               src--;
-
-       memcpy( dest, path, src - path );
-       dest[src - path] = 0;
-}
-
-void ExtractFileBase( const char *path, char *dest ){
-       const char    *src;
-
-       src = path + strlen( path ) - 1;
-
-//
-// back up until a \ or the start
-//
-       while ( src != path && *( src - 1 ) != '/' && *( src - 1 ) != '\\' )
-               src--;
-
-       while ( *src && *src != '.' )
-       {
-               *dest++ = *src++;
-       }
-       *dest = 0;
-}
-
-void ExtractFileExtension( const char *path, char *dest ){
-       const char    *src;
-
-       src = path + strlen( path ) - 1;
-
-//
-// back up until a . or the start
-//
-       while ( src != path && *( src - 1 ) != '.' )
-               src--;
-       if ( src == path ) {
-               *dest = 0;  // no extension
-               return;
-       }
-
-       strcpy( dest,src );
-}
-
-
-/*
-   ==============
-   ParseNum / ParseHex
-   ==============
- */
-int ParseHex( const char *hex ){
-       const char    *str;
-       int num;
-
-       num = 0;
-       str = hex;
-
-       while ( *str )
-       {
-               num <<= 4;
-               if ( *str >= '0' && *str <= '9' ) {
-                       num += *str - '0';
-               }
-               else if ( *str >= 'a' && *str <= 'f' ) {
-                       num += 10 + *str - 'a';
-               }
-               else if ( *str >= 'A' && *str <= 'F' ) {
-                       num += 10 + *str - 'A';
-               }
-               else{
-                       Error( "Bad hex number: %s",hex );
-               }
-               str++;
-       }
-
-       return num;
-}
-
-
-int ParseNum( const char *str ){
-       if ( str[0] == '$' ) {
-               return ParseHex( str + 1 );
-       }
-       if ( str[0] == '0' && str[1] == 'x' ) {
-               return ParseHex( str + 2 );
-       }
-       return atol( str );
-}
-/*
-   // all output ends up through here
-   void FPrintf (int flag, char *buf)
-   {
-   printf(buf);
-
-   }
-
-   void Sys_FPrintf (int flag, const char *format, ...)
-   {
-   char out_buffer[4096];
-    va_list argptr;
-
-   if ((flag == SYS_VRB) && (verbose == false))
-    return;
-
-   va_start (argptr, format);
-    vsprintf (out_buffer, format, argptr);
-    va_end (argptr);
-
-   FPrintf (flag, out_buffer);
-   }
-
-   void Sys_Printf (const char *format, ...)
-   {
-   char out_buffer[4096];
-    va_list argptr;
-
-   va_start (argptr, format);
-    vsprintf (out_buffer, format, argptr);
-    va_end (argptr);
-
-   FPrintf (SYS_STD, out_buffer);
-   }
-
-   //=================
-   //Error
-   //
-   //For abnormal program terminations
-   //=================
-
-   void Error( const char *error, ...)
-   {
-   char out_buffer[4096];
-   char tmp[4096];
-    va_list argptr;
-
-    va_start (argptr,error);
-    vsprintf (tmp, error, argptr);
-    va_end (argptr);
-
-   sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
-
-   FPrintf( SYS_ERR, out_buffer );
-
-    exit (1);
-   }
-
- */
-
-/*
-   ============================================================================
-
-                    BYTE ORDER FUNCTIONS
-
-   ============================================================================
- */
-
-#if GDEF_ARCH_ENDIAN_BIG
-
-short   LittleShort( short l ){
-       byte b1,b2;
-
-       b1 = l & 255;
-       b2 = ( l >> 8 ) & 255;
-
-       return ( b1 << 8 ) + b2;
-}
-
-short   BigShort( short l ){
-       return l;
-}
-
-
-int    LittleLong( int l ){
-       byte b1,b2,b3,b4;
-
-       b1 = l & 255;
-       b2 = ( l >> 8 ) & 255;
-       b3 = ( l >> 16 ) & 255;
-       b4 = ( l >> 24 ) & 255;
-
-       return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4;
-}
-
-int    BigLong( int l ){
-       return l;
-}
-
-
-float   LittleFloat( float l ){
-       union {byte b[4]; float f; } in, out;
-
-       in.f = l;
-       out.b[0] = in.b[3];
-       out.b[1] = in.b[2];
-       out.b[2] = in.b[1];
-       out.b[3] = in.b[0];
-
-       return out.f;
-}
-
-float   BigFloat( float l ){
-       return l;
-}
-
-
-#else // !GDEF_ARCH_ENDIAN_BIG
-
-
-short   BigShort( short l ){
-       byte b1,b2;
-
-       b1 = l & 255;
-       b2 = ( l >> 8 ) & 255;
-
-       return ( b1 << 8 ) + b2;
-}
-
-short   LittleShort( short l ){
-       return l;
-}
-
-
-int    BigLong( int l ){
-       byte b1,b2,b3,b4;
-
-       b1 = l & 255;
-       b2 = ( l >> 8 ) & 255;
-       b3 = ( l >> 16 ) & 255;
-       b4 = ( l >> 24 ) & 255;
-
-       return ( (int)b1 << 24 ) + ( (int)b2 << 16 ) + ( (int)b3 << 8 ) + b4;
-}
-
-int    LittleLong( int l ){
-       return l;
-}
-
-float   BigFloat( float l ){
-       union {byte b[4]; float f; } in, out;
-
-       in.f = l;
-       out.b[0] = in.b[3];
-       out.b[1] = in.b[2];
-       out.b[2] = in.b[1];
-       out.b[3] = in.b[0];
-
-       return out.f;
-}
-
-float   LittleFloat( float l ){
-       return l;
-}
-
-#endif // ! GDEF_ARCH_ENDIAN_BIG
-
-
-//=======================================================
-
-
-// FIXME: byte swap?
-
-// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
-// and the initial and final xor values shown below...  in other words, the
-// CCITT standard CRC used by XMODEM
-
-#define CRC_INIT_VALUE  0xffff
-#define CRC_XOR_VALUE   0x0000
-
-static unsigned short crctable[256] =
-{
-       0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
-       0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
-       0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
-       0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
-       0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
-       0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
-       0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
-       0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
-       0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
-       0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
-       0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
-       0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
-       0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
-       0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
-       0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
-       0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
-       0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
-       0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
-       0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
-       0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
-       0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
-       0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
-       0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
-       0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
-       0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
-       0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
-       0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
-       0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
-       0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
-       0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
-       0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
-       0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
-};
-
-void CRC_Init( unsigned short *crcvalue ){
-       *crcvalue = CRC_INIT_VALUE;
-}
-
-void CRC_ProcessByte( unsigned short *crcvalue, byte data ){
-       *crcvalue = ( *crcvalue << 8 ) ^ crctable[( *crcvalue >> 8 ) ^ data];
-}
-
-unsigned short CRC_Value( unsigned short crcvalue ){
-       return crcvalue ^ CRC_XOR_VALUE;
-}
-//=============================================================================
-
-/*
-   ============
-   CreatePath
-   ============
- */
-void    CreatePath( const char *path ){
-       const char  *ofs;
-       char c;
-       char dir[1024];
-
-#if GDEF_OS_WINDOWS
-       int olddrive = -1;
-
-       if ( path[1] == ':' ) {
-               olddrive = _getdrive();
-               _chdrive( toupper( path[0] ) - 'A' + 1 );
-       }
-#endif // !GDEF_OS_WINDOWS
-
-       if ( path[1] == ':' ) {
-               path += 2;
-       }
-
-       for ( ofs = path + 1 ; *ofs ; ofs++ )
-       {
-               c = *ofs;
-               if ( c == '/' || c == '\\' ) { // create the directory
-                       memcpy( dir, path, ofs - path );
-                       dir[ ofs - path ] = 0;
-                       Q_mkdir( dir );
-               }
-       }
-
-#if GDEF_OS_WINDOWS
-       if ( olddrive != -1 ) {
-               _chdrive( olddrive );
-       }
-#endif // !GDEF_OS_WINDOWS
-}
-
-
-/*
-   ============
-   QCopyFile
-
-   Used to archive source files
-   ============
- */
-void QCopyFile( const char *from, const char *to ){
-       void    *buffer;
-       int length;
-
-       length = LoadFile( from, &buffer );
-       CreatePath( to );
-       SaveFile( to, buffer, length );
-       free( buffer );
-}
-
-void Sys_Sleep( int n ){
-#if GDEF_OS_WINDOWS
-       Sleep( n );
-#else // !GDEF_OS_WINDOWS
-       usleep( n * 1000 );
-#endif // !GDEF_OS_WINDOWS
-}
diff --git a/tools/quake2/qdata_heretic2/common/cmdlib.h b/tools/quake2/qdata_heretic2/common/cmdlib.h
deleted file mode 100644 (file)
index b8b1aa3..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// cmdlib.h
-
-#ifndef __CMDLIB__
-#define __CMDLIB__
-
-#if GDEF_COMPILER_MSVC
-#pragma warning(disable : 4244)     // MIPS
-#pragma warning(disable : 4136)     // X86
-#pragma warning(disable : 4051)     // ALPHA
-
-#pragma warning(disable : 4018)     // signed/unsigned mismatch
-#pragma warning(disable : 4305)     // truncate from double to float
-
-#pragma check_stack(off)
-
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <ctype.h>
-#include <time.h>
-#include <stdarg.h>
-
-#if GDEF_COMPILER_MSVC
-
-#pragma intrinsic( memset, memcpy )
-
-#endif
-
-#ifndef __BYTEBOOL__
-  #define __BYTEBOOL__
-//typedef enum {false, true} qboolean;
-//typedef unsigned char byte;
-  #include "q_typedef.h"
-#endif
-
-#ifdef PATH_MAX
-#define MAX_OS_PATH     PATH_MAX
-#else
-#define MAX_OS_PATH     1024
-#endif
-#define MEM_BLOCKSIZE 4096
-/*
-   extern      qboolean verbose;
-   #define SYS_VRB 0 // verbose support (on/off)
-   #define SYS_STD 1 // standard print level
-   #define SYS_WRN 2 // warnings
-   #define SYS_ERR 3 // error
- */
-// the dec offsetof macro doesnt work very well...
-#define myoffsetof( type,identifier ) ( (size_t)& ( (type *)0 )->identifier )
-
-#define SAFE_MALLOC
-#ifdef SAFE_MALLOC
-void *safe_malloc( size_t size );
-void *safe_malloc_info( size_t size, char* info );
-#else
-#define safe_malloc( a ) malloc( a )
-#endif /* SAFE_MALLOC */
-
-// set these before calling CheckParm
-extern int myargc;
-extern char **myargv;
-
-char *strlower( char *in );
-int Q_strncasecmp( const char *s1, const char *s2, int n );
-int Q_stricmp( const char *s1, const char *s2 );
-int Q_strcasecmp( const char *s1, const char *s2 );
-void Q_getwd( char *out );
-
-int Q_filelength( FILE *f );
-int FileTime( const char *path );
-
-void    Q_mkdir( const char *path );
-
-extern char qdir[1024];
-extern char gamedir[1024];
-extern char writedir[1024];
-extern char    *moddirparam;
-void SetQdirFromPath( const char *path );
-char *ExpandArg( const char *path );    // from cmd line
-char *ExpandPath( const char *path );   // from scripts
-char *ExpandGamePath( const char *path );
-char *ExpandPathAndArchive( const char *path );
-void ExpandWildcards( int *argc, char ***argv );
-
-
-double I_FloatTime( void );
-
-int     CheckParm( const char *check );
-
-void    *SafeMalloc( size_t n, char *desc );
-FILE    *SafeOpenWrite( const char *filename );
-FILE    *SafeOpenRead( const char *filename );
-void    SafeRead( FILE *f, void *buffer, int count );
-void    SafeWrite( FILE *f, const void *buffer, int count );
-
-int     LoadFile( const char *filename, void **bufferptr );
-int   LoadFileBlock( const char *filename, void **bufferptr );
-int     TryLoadFile( const char *filename, void **bufferptr );
-void    SaveFile( const char *filename, const void *buffer, int count );
-qboolean    FileExists( const char *filename );
-
-void    DefaultExtension( char *path, const char *extension );
-void    DefaultPath( char *path, const char *basepath );
-void    StripFilename( char *path );
-void    StripExtension( char *path );
-
-void    ExtractFilePath( const char *path, char *dest );
-void    ExtractFileBase( const char *path, char *dest );
-void    ExtractFileExtension( const char *path, char *dest );
-
-int     ParseNum( const char *str );
-/*
-   void Sys_Printf (const char *text, ...);
-   void Sys_FPrintf (int flag, const char *text, ...);
-   void        Error( const char *error, ... );
- */
-short   BigShort( short l );
-short   LittleShort( short l );
-int     BigLong( int l );
-int     LittleLong( int l );
-float   BigFloat( float l );
-float   LittleFloat( float l );
-
-
-char *COM_Parse( char *data );
-
-extern char com_token[1024];
-extern qboolean com_eof;
-
-char *copystring( const char *s );
-
-
-void CRC_Init( unsigned short *crcvalue );
-void CRC_ProcessByte( unsigned short *crcvalue, byte data );
-unsigned short CRC_Value( unsigned short crcvalue );
-
-void    CreatePath( const char *path );
-void    QCopyFile( const char *from, const char *to );
-
-extern qboolean archive;
-extern char archivedir[1024];
-
-extern qboolean g_dokeypress;
-
-// sleep for the given amount of milliseconds
-void Sys_Sleep( int n );
-
-// for compression routines
-typedef struct
-{
-       byte    *data;
-       int count;
-} cblock_t;
-
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/common/her2_threads.h b/tools/quake2/qdata_heretic2/common/her2_threads.h
deleted file mode 100644 (file)
index 6027a69..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#ifndef _THREADS_H
-
-#define _THREADS_H
-
-
-extern int numthreads;
-
-void ThreadSetDefault( void );
-int GetThreadWork( void );
-void RunThreadsOnIndividual( int workcnt, qboolean showpacifier, void ( *func )( int ) );
-void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) );
-void ThreadLock( void );
-void ThreadUnlock( void );
-
-#endif //_THREADS_H
diff --git a/tools/quake2/qdata_heretic2/common/inout.c b/tools/quake2/qdata_heretic2/common/inout.c
deleted file mode 100644 (file)
index e0c1484..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-//-----------------------------------------------------------------------------
-//
-//
-// DESCRIPTION:
-// deal with in/out tasks, for either stdin/stdout or network/XML stream
-//
-
-#include "globaldefs.h"
-#include "cmdlib.h"
-#include "mathlib.h"
-#include "polylib.h"
-#include "inout.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if GDEF_OS_WINDOWS
-#include <direct.h>
-#include <windows.h>
-#endif
-
-// network broadcasting
-#include "l_net/l_net.h"
-#include "libxml/tree.h"
-
-#if GDEF_OS_WINDOWS
-HWND hwndOut = NULL;
-qboolean lookedForServer = false;
-UINT wm_BroadcastCommand = -1;
-#endif
-
-socket_t *brdcst_socket;
-netmessage_t msg;
-
-qboolean verbose = false;
-
-// our main document
-// is streamed through the network to Radiant
-// possibly written to disk at the end of the run
-//++timo FIXME: need to be global, required when creating nodes?
-xmlDocPtr doc;
-xmlNodePtr tree;
-
-// some useful stuff
-xmlNodePtr xml_NodeForVec( vec3_t v ){
-       xmlNodePtr ret;
-       char buf[1024];
-
-       sprintf( buf, "%f %f %f", v[0], v[1], v[2] );
-       ret = xmlNewNode( NULL, "point" );
-       xmlNodeAddContent( ret, buf );
-       return ret;
-}
-
-// send a node down the stream, add it to the document
-void xml_SendNode( xmlNodePtr node ){
-       xmlBufferPtr xml_buf;
-       char xmlbuf[MAX_NETMESSAGE]; // we have to copy content from the xmlBufferPtr into an aux buffer .. that sucks ..
-       // this index loops through the node buffer
-       int pos = 0;
-       int size;
-
-       xmlAddChild( doc->children, node );
-
-       if ( brdcst_socket ) {
-               xml_buf = xmlBufferCreate();
-               xmlNodeDump( xml_buf, doc, node, 0, 0 );
-
-               // the XML node might be too big to fit in a single network message
-               // l_net library defines an upper limit of MAX_NETMESSAGE
-               // there are some size check errors, so we use MAX_NETMESSAGE-10 to be safe
-               // if the size of the buffer exceeds MAX_NETMESSAGE-10 we'll send in several network messages
-               while ( pos < xml_buf->use )
-               {
-                       // what size are we gonna send now?
-                       ( xml_buf->use - pos < MAX_NETMESSAGE - 10 ) ? ( size = xml_buf->use - pos ) : ( size = MAX_NETMESSAGE - 10 );
-                       //++timo just a debug thing
-                       if ( size == MAX_NETMESSAGE - 10 ) {
-                               Sys_FPrintf( SYS_NOXML, "Got to split the buffer\n" );
-                       }
-                       memcpy( xmlbuf, xml_buf->content + pos, size );
-                       xmlbuf[size] = '\0';
-                       NMSG_Clear( &msg );
-                       NMSG_WriteString( &msg, xmlbuf );
-                       Net_Send( brdcst_socket, &msg );
-                       // now that the thing is sent prepare to loop again
-                       pos += size;
-               }
-
-#if 0
-               // NOTE: the NMSG_WriteString is limited to MAX_NETMESSAGE
-               // we will need to split into chunks
-               // (we could also go lower level, in the end it's using send and receiv which are not size limited)
-               //++timo FIXME: MAX_NETMESSAGE is not exactly the max size we can stick in the message
-               //  there's some tweaking to do in l_net for that .. so let's give us a margin for now
-
-               //++timo we need to handle the case of a buffer too big to fit in a single message
-               // try without checks for now
-               if ( xml_buf->use > MAX_NETMESSAGE - 10 ) {
-                       // if we send that we are probably gonna break the stream at the other end..
-                       // and Error will call right there
-                       //Error( "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
-                       Sys_FPrintf( SYS_NOXML, "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use );
-                       xml_buf->content[xml_buf->use] = '\0'; //++timo this corrupts the buffer but we don't care it's for printing
-                       Sys_FPrintf( SYS_NOXML, xml_buf->content );
-
-               }
-
-               size = xml_buf->use;
-               memcpy( xmlbuf, xml_buf->content, size );
-               xmlbuf[size] = '\0';
-               NMSG_Clear( &msg );
-               NMSG_WriteString( &msg, xmlbuf );
-               Net_Send( brdcst_socket, &msg );
-#endif
-
-               xmlBufferFree( xml_buf );
-       }
-}
-
-void xml_Select( char *msg, int entitynum, int brushnum, qboolean bError ){
-       xmlNodePtr node, select;
-       char buf[1024];
-       char level[2];
-
-       // now build a proper "select" XML node
-       sprintf( buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg );
-       node = xmlNewNode( NULL, "select" );
-       xmlNodeAddContent( node, buf );
-       level[0] = (int)'0' + ( bError ? SYS_ERR : SYS_WRN )  ;
-       level[1] = 0;
-       xmlSetProp( node, "level", (char *)&level );
-       // a 'select' information
-       sprintf( buf, "%i %i", entitynum, brushnum );
-       select = xmlNewNode( NULL, "brush" );
-       xmlNodeAddContent( select, buf );
-       xmlAddChild( node, select );
-       xml_SendNode( node );
-
-       sprintf( buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg );
-       if ( bError ) {
-               Error( buf );
-       }
-       else{
-               Sys_FPrintf( SYS_NOXML, "%s\n", buf );
-       }
-
-}
-
-void xml_Point( char *msg, vec3_t pt ){
-       xmlNodePtr node, point;
-       char buf[1024];
-       char level[2];
-
-       node = xmlNewNode( NULL, "pointmsg" );
-       xmlNodeAddContent( node, msg );
-       level[0] = (int)'0' + SYS_ERR;
-       level[1] = 0;
-       xmlSetProp( node, "level", (char *)&level );
-       // a 'point' node
-       sprintf( buf, "%g %g %g", pt[0], pt[1], pt[2] );
-       point = xmlNewNode( NULL, "point" );
-       xmlNodeAddContent( point, buf );
-       xmlAddChild( node, point );
-       xml_SendNode( node );
-
-       sprintf( buf, "%s (%g %g %g)", msg, pt[0], pt[1], pt[2] );
-       Error( buf );
-}
-
-#define WINDING_BUFSIZE 2048
-void xml_Winding( char *msg, vec3_t p[], int numpoints, qboolean die ){
-       xmlNodePtr node, winding;
-       char buf[WINDING_BUFSIZE];
-       char smlbuf[128];
-       char level[2];
-       int i;
-
-       node = xmlNewNode( NULL, "windingmsg" );
-       xmlNodeAddContent( node, msg );
-       level[0] = (int)'0' + SYS_ERR;
-       level[1] = 0;
-       xmlSetProp( node, "level", (char *)&level );
-       // a 'winding' node
-       sprintf( buf, "%i ", numpoints );
-       for ( i = 0; i < numpoints; i++ )
-       {
-               sprintf( smlbuf, "(%g %g %g)", p[i][0], p[i][1], p[i][2] );
-               // don't overflow
-               if ( strlen( buf ) + strlen( smlbuf ) > WINDING_BUFSIZE ) {
-                       break;
-               }
-               strcat( buf, smlbuf );
-       }
-
-       winding = xmlNewNode( NULL, "winding" );
-       xmlNodeAddContent( winding, buf );
-       xmlAddChild( node, winding );
-       xml_SendNode( node );
-
-       if ( die ) {
-               Error( msg );
-       }
-       else
-       {
-               Sys_Printf( msg );
-               Sys_Printf( "\n" );
-       }
-}
-
-// in include
-#include "stream_version.h"
-
-void Broadcast_Setup( const char *dest ){
-       address_t address;
-       char sMsg[1024];
-
-       Net_Setup();
-       Net_StringToAddress( (char *)dest, &address );
-       brdcst_socket = Net_Connect( &address, 0 );
-       if ( brdcst_socket ) {
-               // send in a header
-               sprintf( sMsg, "<?xml version=\"1.0\"?><q3map_feedback version=\"" Q3MAP_STREAM_VERSION "\">" );
-               NMSG_Clear( &msg );
-               NMSG_WriteString( &msg, sMsg );
-               Net_Send( brdcst_socket, &msg );
-       }
-}
-
-void Broadcast_Shutdown(){
-       if ( brdcst_socket ) {
-               Sys_Printf( "Disconnecting\n" );
-               Net_Disconnect( brdcst_socket );
-               brdcst_socket = NULL;
-       }
-}
-
-// all output ends up through here
-void FPrintf( int flag, char *buf ){
-       xmlNodePtr node;
-       static qboolean bGotXML = false;
-       char level[2];
-
-       printf( buf );
-
-       // the following part is XML stuff only.. but maybe we don't want that message to go down the XML pipe?
-       if ( flag == SYS_NOXML ) {
-               return;
-       }
-
-       // ouput an XML file of the run
-       // use the DOM interface to build a tree
-       /*
-          <message level='flag'>
-          message string
-          .. various nodes to describe corresponding geometry ..
-          </message>
-        */
-       if ( !bGotXML ) {
-               // initialize
-               doc = xmlNewDoc( "1.0" );
-               doc->children = xmlNewDocRawNode( doc, NULL, "q3map_feedback", NULL );
-               bGotXML = true;
-       }
-       node = xmlNewNode( NULL, "message" );
-       xmlNodeAddContent( node, buf );
-       level[0] = (int)'0' + flag;
-       level[1] = 0;
-       xmlSetProp( node, "level", (char *)&level );
-
-       xml_SendNode( node );
-}
-
-#ifdef DBG_XML
-void DumpXML(){
-       xmlSaveFile( "XMLDump.xml", doc );
-}
-#endif
-
-void Sys_FPrintf( int flag, const char *format, ... ){
-       char out_buffer[4096];
-       va_list argptr;
-
-       if ( ( flag == SYS_VRB ) && ( verbose == false ) ) {
-               return;
-       }
-
-       va_start( argptr, format );
-       vsprintf( out_buffer, format, argptr );
-       va_end( argptr );
-
-       FPrintf( flag, out_buffer );
-}
-
-void Sys_Printf( const char *format, ... ){
-       char out_buffer[4096];
-       va_list argptr;
-
-       va_start( argptr, format );
-       vsprintf( out_buffer, format, argptr );
-       va_end( argptr );
-
-       FPrintf( SYS_STD, out_buffer );
-}
-
-/*
-   =================
-   Error
-
-   For abnormal program terminations
-   =================
- */
-void Error( const char *error, ... ){
-       char out_buffer[4096];
-       char tmp[4096];
-       va_list argptr;
-
-       va_start( argptr,error );
-       vsprintf( tmp, error, argptr );
-       va_end( argptr );
-
-       sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
-
-       FPrintf( SYS_ERR, out_buffer );
-
-#ifdef DBG_XML
-       DumpXML();
-#endif
-
-       //++timo HACK ALERT .. if we shut down too fast the xml stream won't reach the listener.
-       // a clean solution is to send a sync request node in the stream and wait for an answer before exiting
-       Sys_Sleep( 1000 );
-
-       Broadcast_Shutdown();
-
-       exit( 1 );
-}
diff --git a/tools/quake2/qdata_heretic2/common/inout.h b/tools/quake2/qdata_heretic2/common/inout.h
deleted file mode 100644 (file)
index 934189f..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef __INOUT__
-#define __INOUT__
-
-#include "globaldefs.h"
-// inout is the only stuff relying on xml, include the headers there
-#include "libxml/tree.h"
-#include "mathlib.h"
-
-// some useful xml routines
-xmlNodePtr xml_NodeForVec( vec3_t v );
-void xml_SendNode( xmlNodePtr node );
-// print a message in q3map output and send the corresponding select information down the xml stream
-// bError: do we end with an error on this one or do we go ahead?
-void xml_Select( char *msg, int entitynum, int brushnum, qboolean bError );
-// end q3map with an error message and send a point information in the xml stream
-// note: we might want to add a boolean to use this as a warning or an error thing..
-void xml_Winding( char *msg, vec3_t p[], int numpoints, qboolean die );
-void xml_Point( char *msg, vec3_t pt );
-
-extern qboolean bNetworkBroadcast;
-void Broadcast_Setup( const char *dest );
-void Broadcast_Shutdown();
-
-#define SYS_VRB 0 // verbose support (on/off)
-#define SYS_STD 1 // standard print level
-#define SYS_WRN 2 // warnings
-#define SYS_ERR 3 // error
-#define SYS_NOXML 4 // don't send that down the XML stream
-
-extern qboolean verbose;
-void Sys_Printf( const char *text, ... );
-void Sys_FPrintf( int flag, const char *text, ... );
-void Error( const char *error, ... );
-
-#if GDEF_DEBUG
-#define DBG_XML 1
-#endif
-
-#ifdef DBG_XML
-void DumpXML();
-#endif
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/common/l3dslib.c b/tools/quake2/qdata_heretic2/common/l3dslib.c
deleted file mode 100644 (file)
index 708577a..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-//
-// l3dslib.c: library for loading triangles from an Alias triangle file
-//
-
-#include <stdio.h>
-#include "cmdlib.h"
-#include "inout.h"
-#include "mathlib.h"
-#include "trilib.h"
-#include "l3dslib.h"
-#include "token.h"
-#include "fmodel.h"
-#include "bspfile.h"
-
-#define MAIN3DS       0x4D4D
-#define EDIT3DS       0x3D3D  // this is the start of the editor config
-#define EDIT_OBJECT   0x4000
-#define OBJ_TRIMESH   0x4100
-#define TRI_VERTEXL   0x4110
-#define TRI_FACEL1    0x4120
-
-#define MAXVERTS    2000
-
-typedef struct {
-       int v[4];
-} tri;
-
-float fverts[MAXVERTS][3];
-tri tris[MAXTRIANGLES];
-
-int bytesread, level, numtris, totaltris;
-int vertsfound, trisfound;
-
-triangle_t  *ptri;
-
-
-
-void DefaultNodesList( mesh_node_t **nodesList, int *num_mesh_nodes, int *numtriangles ){
-       int pos, bit, i;
-
-       if ( nodesList ) {
-               *num_mesh_nodes = 1;
-               memset( &( *nodesList )[0], 0, sizeof( mesh_node_t ) );
-               strcpy( ( *nodesList )[0].name, "default" );
-
-               // set all of the tris to be used for the top node
-               for ( i = 0; i < ( *numtriangles ); i++ )
-               {
-                       pos = ( i ) >> 3;
-                       bit = 1 << ( ( i ) & 7 );
-
-                       ( *nodesList )[0].tris[pos] |= bit;
-               }
-       }
-}
-
-
-// Alias stores triangles as 3 explicit vertices in .tri files, so even though we
-// start out with a vertex pool and vertex indices for triangles, we have to convert
-// to raw, explicit triangles
-void StoreAliasTriangles( void ){
-       int i, j, k;
-
-       if ( ( totaltris + numtris ) > MAXTRIANGLES ) {
-               Error( "Error: Too many triangles" );
-       }
-
-       for ( i = 0; i < numtris ; i++ )
-       {
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       for ( k = 0 ; k < 3 ; k++ )
-                       {
-                               ptri[i + totaltris].verts[j][k] = fverts[tris[i].v[j]][k];
-                       }
-               }
-       }
-
-       totaltris += numtris;
-       numtris = 0;
-       vertsfound = 0;
-       trisfound = 0;
-}
-
-
-int ParseVertexL( FILE *input ){
-       int i, j, startbytesread, numverts;
-       unsigned short tshort;
-
-       if ( vertsfound ) {
-               Error( "Error: Multiple vertex chunks" );
-       }
-
-       vertsfound = 1;
-       startbytesread = bytesread;
-
-       if ( feof( input ) ) {
-               Error( "Error: unexpected end of file" );
-       }
-
-       fread( &tshort, sizeof( tshort ), 1, input );
-       bytesread += sizeof( tshort );
-       numverts = (int)tshort;
-
-       if ( numverts > MAXVERTS ) {
-               Error( "Error: Too many vertices" );
-       }
-
-       for ( i = 0 ; i < numverts ; i++ )
-       {
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       if ( feof( input ) ) {
-                               Error( "Error: unexpected end of file" );
-                       }
-
-                       fread( &fverts[i][j], sizeof( float ), 1, input );
-                       bytesread += sizeof( float );
-               }
-       }
-
-       if ( vertsfound && trisfound ) {
-               StoreAliasTriangles();
-       }
-
-       return bytesread - startbytesread;
-}
-
-
-int ParseFaceL1( FILE *input ){
-
-       int i, j, startbytesread;
-       unsigned short tshort;
-
-       if ( trisfound ) {
-               Error( "Error: Multiple face chunks" );
-       }
-
-       trisfound = 1;
-       startbytesread = bytesread;
-
-       if ( feof( input ) ) {
-               Error( "Error: unexpected end of file" );
-       }
-
-       fread( &tshort, sizeof( tshort ), 1, input );
-       bytesread += sizeof( tshort );
-       numtris = (int)tshort;
-
-       if ( numtris > MAXTRIANGLES ) {
-               Error( "Error: Too many triangles" );
-       }
-
-       for ( i = 0 ; i < numtris ; i++ )
-       {
-               for ( j = 0 ; j < 4 ; j++ )
-               {
-                       if ( feof( input ) ) {
-                               Error( "Error: unexpected end of file" );
-                       }
-
-                       fread( &tshort, sizeof( tshort ), 1, input );
-                       bytesread += sizeof( tshort );
-                       tris[i].v[j] = (int)tshort;
-               }
-       }
-
-       if ( vertsfound && trisfound ) {
-               StoreAliasTriangles();
-       }
-
-       return bytesread - startbytesread;
-}
-
-
-int ParseChunk( FILE *input ){
-#define BLOCK_SIZE  4096
-       char temp[BLOCK_SIZE];
-       unsigned short type;
-       int i, length, w, t, retval;
-
-       level++;
-       retval = 0;
-
-// chunk type
-       if ( feof( input ) ) {
-               Error( "Error: unexpected end of file" );
-       }
-
-       fread( &type, sizeof( type ), 1, input );
-       bytesread += sizeof( type );
-
-// chunk length
-       if ( feof( input ) ) {
-               Error( "Error: unexpected end of file" );
-       }
-
-       fread( &length, sizeof( length ), 1, input );
-       bytesread += sizeof( length );
-       w = length - 6;
-
-// process chunk if we care about it, otherwise skip it
-       switch ( type )
-       {
-       case TRI_VERTEXL:
-               w -= ParseVertexL( input );
-               goto ParseSubchunk;
-
-       case TRI_FACEL1:
-               w -= ParseFaceL1( input );
-               goto ParseSubchunk;
-
-       case EDIT_OBJECT:
-               // read the name
-               i = 0;
-
-               do
-               {
-                       if ( feof( input ) ) {
-                               Error( "Error: unexpected end of file" );
-                       }
-
-                       fread( &temp[i], 1, 1, input );
-                       i++;
-                       w--;
-                       bytesread++;
-               } while ( temp[i - 1] );
-
-       case MAIN3DS:
-       case OBJ_TRIMESH:
-       case EDIT3DS:
-               // parse through subchunks
-ParseSubchunk:
-               while ( w > 0 )
-               {
-                       w -= ParseChunk( input );
-               }
-
-               retval = length;
-               goto Done;
-
-       default:
-               // skip other chunks
-               while ( w > 0 )
-               {
-                       t = w;
-
-                       if ( t > BLOCK_SIZE ) {
-                               t = BLOCK_SIZE;
-                       }
-
-                       if ( feof( input ) ) {
-                               Error( "Error: unexpected end of file" );
-                       }
-
-                       fread( &temp, t, 1, input );
-                       bytesread += t;
-
-                       w -= t;
-               }
-
-               retval = length;
-               goto Done;
-       }
-
-Done:
-       level--;
-       return retval;
-}
-
-
-void Load3DSTriangleList( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **nodesList, int *num_mesh_nodes ){
-       FILE        *input;
-       short int tshort;
-
-       if ( nodesList ) {
-               *num_mesh_nodes = 0;
-               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
-       }
-
-       bytesread = 0;
-       level = 0;
-       numtris = 0;
-       totaltris = 0;
-       vertsfound = 0;
-       trisfound = 0;
-
-       if ( ( input = fopen( filename, "rb" ) ) == 0 ) {
-               fprintf( stderr,"reader: could not open file '%s'\n", filename );
-               exit( 0 );
-       }
-
-       fread( &tshort, sizeof( tshort ), 1, input );
-
-// should only be MAIN3DS, but some files seem to start with EDIT3DS, with
-// no MAIN3DS
-       if ( ( tshort != MAIN3DS ) && ( tshort != EDIT3DS ) ) {
-               fprintf( stderr,"File is not a 3DS file.\n" );
-               exit( 0 );
-       }
-
-// back to top of file so we can parse the first chunk descriptor
-       fseek( input, 0, SEEK_SET );
-
-       ptri = malloc( MAXTRIANGLES * sizeof( triangle_t ) );
-
-       *pptri = ptri;
-
-// parse through looking for the relevant chunk tree (MAIN3DS | EDIT3DS | EDIT_OBJECT |
-// OBJ_TRIMESH | {TRI_VERTEXL, TRI_FACEL1}) and skipping other chunks
-       ParseChunk( input );
-
-       if ( vertsfound || trisfound ) {
-               Error( "Incomplete triangle set" );
-       }
-
-       *numtriangles = totaltris;
-
-       fclose( input );
-
-       DefaultNodesList( nodesList,num_mesh_nodes,numtriangles );
-}
-
-//==========================================================================
-//
-// LoadASC
-//
-//==========================================================================
-
-void LoadASC( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
-       int i, j;
-       int vertexCount;
-       struct
-       {
-               float v[3];
-       }           *vList;
-       int triCount;
-       triangle_t  *tList;
-       float x, y, z;
-//     float           x2, y2, z2;
-//     float           rx, ry, rz;
-       qboolean goodObject;
-
-       if ( nodesList ) {
-               *num_mesh_nodes = 0;
-               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
-       }
-
-       TK_OpenSource( fileName );
-
-       goodObject = false;
-       while ( goodObject == false )
-       {
-               TK_Beyond( TK_C_NAMED );
-               TK_Beyond( TK_OBJECT );
-               TK_Beyond( TK_C_TRI );
-               TK_Beyond( TK_MESH );
-               TK_BeyondRequire( TK_C_VERTICES, TK_COLON );
-               TK_FetchRequire( TK_INTNUMBER );
-               vertexCount = tk_IntNumber;
-               if ( vertexCount > 0 ) {
-                       goodObject = true;
-               }
-       }
-       TK_BeyondRequire( TK_C_FACES, TK_COLON );
-       TK_FetchRequire( TK_INTNUMBER );
-       triCount = tk_IntNumber;
-       if ( triCount >= MAXTRIANGLES ) {
-               Error( "Too many triangles in file %s\n", fileName );
-       }
-       *triangleCount = triCount;
-       tList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
-       *triList = tList;
-
-       memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
-       TK_BeyondRequire( TK_C_VERTEX, TK_LIST );
-
-/*     rx = ((rotation[0]+90.0)/360.0)*2.0*M_PI;
-    //rx = (rotation[0]/360.0)*2.0*M_PI;
-    ry = (rotation[1]/360.0)*2.0*M_PI;
-    rz = (rotation[2]/360.0)*2.0*M_PI;
- */
-       vList = (void *) SafeMalloc( vertexCount * sizeof vList[0], "Vertex list" );
-       for ( i = 0; i < vertexCount; i++ )
-       {
-               TK_BeyondRequire( TK_C_VERTEX, TK_INTNUMBER );
-               if ( tk_IntNumber != i ) {
-                       Error( "File '%s', line %d:\nVertex index mismatch.\n",
-                                  tk_SourceName, tk_Line );
-               }
-               TK_FetchRequireFetch( TK_COLON );
-
-               TK_BeyondRequire( TK_COLON, TK_FLOATNUMBER );
-               x = tk_FloatNumber;
-               TK_BeyondRequire( TK_COLON, TK_FLOATNUMBER );
-               y = tk_FloatNumber;
-               TK_BeyondRequire( TK_COLON, TK_FLOATNUMBER );
-               z = tk_FloatNumber;
-
-/*             x2 = x*cos(rz)+y*sin(rz);
-        y2 = -x*sin(rz)+y*cos(rz);
-        x = x2;
-        y = y2;
-        y2 = y*cos(rx)+z*sin(rx);
-        z2 = -y*sin(rx)+z*cos(rx);
-        y = y2;
-        z = z2;
-        x2 = x*cos(ry)-z*sin(ry);
-        z2 = x*sin(ry)+z*cos(ry);
-        x = x2;
-        z = z2;
- */
-               vList[i].v[0] = x;
-               vList[i].v[1] = y;
-               vList[i].v[2] = z;
-       }
-       TK_BeyondRequire( TK_C_FACE, TK_LIST );
-       for ( i = 0; i < triCount; i++ )
-       {
-               TK_BeyondRequire( TK_C_FACE, TK_INTNUMBER );
-               if ( tk_IntNumber != i ) {
-                       Error( "File '%s', line %d:\nTriangle index mismatch.\n",
-                                  tk_SourceName, tk_Line );
-               }
-               for ( j = 0; j < 3; j++ )
-               {
-                       TK_BeyondRequire( TK_IDENTIFIER, TK_COLON );
-                       TK_FetchRequire( TK_INTNUMBER );
-                       if ( tk_IntNumber >= vertexCount ) {
-                               Error( "File '%s', line %d:\nVertex number"
-                                          " > vertexCount: %d\n", tk_SourceName, tk_Line,
-                                          tk_IntNumber );
-                       }
-                       tList[i].verts[2 - j][0] = vList[tk_IntNumber].v[0];
-                       tList[i].verts[2 - j][1] = vList[tk_IntNumber].v[1];
-                       tList[i].verts[2 - j][2] = vList[tk_IntNumber].v[2];
-#ifdef _QDATA
-                       tList[i].indicies[2 - j] = tk_IntNumber;
-#endif
-               }
-
-/*             printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
-            "  v2: %f, %f, %f\n", i,
-            tList[i].verts[0][0],
-            tList[i].verts[0][1],
-            tList[i].verts[0][2],
-            tList[i].verts[1][0],
-            tList[i].verts[1][1],
-            tList[i].verts[1][2],
-            tList[i].verts[2][0],
-            tList[i].verts[2][1],
-            tList[i].verts[2][2]);
- */
-       }
-
-       DefaultNodesList( nodesList,num_mesh_nodes,triangleCount );
-}
diff --git a/tools/quake2/qdata_heretic2/common/l3dslib.h b/tools/quake2/qdata_heretic2/common/l3dslib.h
deleted file mode 100644 (file)
index 0b1b537..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-//
-// l3dslib.h: header file for loading triangles from a 3DS triangle file
-//
-void DefaultNodesList( mesh_node_t **nodesList, int *num_mesh_nodes, int *numtriangles );
-
-void Load3DSTriangleList( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **ppmnodes, int *num_mesh_nodes );
-void LoadASC( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **ppmnodes, int *num_mesh_nodes );
diff --git a/tools/quake2/qdata_heretic2/common/lbmlib.c b/tools/quake2/qdata_heretic2/common/lbmlib.c
deleted file mode 100644 (file)
index 7eabd19..0000000
+++ /dev/null
@@ -1,1043 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// lbmlib.c
-
-#include "cmdlib.h"
-#include "inout.h"
-#include "lbmlib.h"
-
-// Ups the palette values so no pixels except 0 appear transparent
-// Need a value of 8 to cater for 16bit renderers
-
-typedef struct
-{
-       byte r;
-       byte g;
-       byte b;
-} paletteRGB_t;
-
-
-void CorrectPalette( byte *pal ){
-       paletteRGB_t    *p;
-
-       p = (paletteRGB_t *)pal;
-       // Color 0 always transparent
-       p->r = 0;
-       p->g = 0;
-       p->b = 0;
-}
-
-/*
-   ============================================================================
-
-                        LBM STUFF
-
-   ============================================================================
- */
-
-
-typedef unsigned char UBYTE;
-//conflicts with windows typedef short                 WORD;
-typedef unsigned short UWORD;
-typedef long LONG;
-
-typedef enum
-{
-       ms_none,
-       ms_mask,
-       ms_transcolor,
-       ms_lasso
-} mask_t;
-
-typedef enum
-{
-       cm_none,
-       cm_rle1
-} compress_t;
-
-typedef struct
-{
-       UWORD w,h;
-       short x,y;
-       UBYTE nPlanes;
-       UBYTE masking;
-       UBYTE compression;
-       UBYTE pad1;
-       UWORD transparentColor;
-       UBYTE xAspect,yAspect;
-       short pageWidth,pageHeight;
-} bmhd_t;
-
-extern bmhd_t bmhd;                         // will be in native byte order
-
-
-
-#define FORMID ( 'F' + ( 'O' << 8 ) + ( (int)'R' << 16 ) + ( (int)'M' << 24 ) )
-#define ILBMID ( 'I' + ( 'L' << 8 ) + ( (int)'B' << 16 ) + ( (int)'M' << 24 ) )
-#define PBMID  ( 'P' + ( 'B' << 8 ) + ( (int)'M' << 16 ) + ( (int)' ' << 24 ) )
-#define BMHDID ( 'B' + ( 'M' << 8 ) + ( (int)'H' << 16 ) + ( (int)'D' << 24 ) )
-#define BODYID ( 'B' + ( 'O' << 8 ) + ( (int)'D' << 16 ) + ( (int)'Y' << 24 ) )
-#define CMAPID ( 'C' + ( 'M' << 8 ) + ( (int)'A' << 16 ) + ( (int)'P' << 24 ) )
-
-
-bmhd_t bmhd;
-
-int    Align( int l ){
-       if ( l & 1 ) {
-               return l + 1;
-       }
-       return l;
-}
-
-
-
-/*
-   ================
-   LBMRLEdecompress
-
-   Source must be evenly aligned!
-   ================
- */
-byte  *LBMRLEDecompress( byte *source,byte *unpacked, int bpwidth ){
-       int count;
-       byte b,rept;
-
-       count = 0;
-
-       do
-       {
-               rept = *source++;
-
-               if ( rept > 0x80 ) {
-                       rept = ( rept ^ 0xff ) + 2;
-                       b = *source++;
-                       memset( unpacked,b,rept );
-                       unpacked += rept;
-               }
-               else if ( rept < 0x80 ) {
-                       rept++;
-                       memcpy( unpacked,source,rept );
-                       unpacked += rept;
-                       source += rept;
-               }
-               else{
-                       rept = 0;               // rept of 0x80 is NOP
-
-               }
-               count += rept;
-
-       } while ( count < bpwidth );
-
-       if ( count > bpwidth ) {
-               Error( "Decompression exceeded width!\n" );
-       }
-
-
-       return source;
-}
-
-
-/*
-   =================
-   LoadLBM
-   =================
- */
-void LoadLBM( char *filename, byte **picture, byte **palette ){
-       byte    *LBMbuffer, *picbuffer, *cmapbuffer;
-       int y;
-       byte    *LBM_P, *LBMEND_P;
-       byte    *pic_p;
-       byte    *body_p;
-
-       int formtype,formlength;
-       int chunktype,chunklength;
-
-// qiet compiler warnings
-       picbuffer = NULL;
-       cmapbuffer = NULL;
-
-//
-// load the LBM
-//
-       LoadFile( filename, (void **)&LBMbuffer );
-
-//
-// parse the LBM header
-//
-       LBM_P = LBMbuffer;
-       if ( *(int *)LBMbuffer != LittleLong( FORMID ) ) {
-               Error( "No FORM ID at start of file!\n" );
-       }
-
-       LBM_P += 4;
-       formlength = BigLong( *(int *)LBM_P );
-       LBM_P += 4;
-       LBMEND_P = LBM_P + Align( formlength );
-
-       formtype = LittleLong( *(int *)LBM_P );
-
-       if ( formtype != ILBMID && formtype != PBMID ) {
-               Error( "Unrecognized form type: %c%c%c%c\n", formtype & 0xff
-                          ,( formtype >> 8 ) & 0xff,( formtype >> 16 ) & 0xff,( formtype >> 24 ) & 0xff );
-       }
-
-       LBM_P += 4;
-
-//
-// parse chunks
-//
-
-       while ( LBM_P < LBMEND_P )
-       {
-               chunktype = LBM_P[0] + ( LBM_P[1] << 8 ) + ( LBM_P[2] << 16 ) + ( LBM_P[3] << 24 );
-               LBM_P += 4;
-               chunklength = LBM_P[3] + ( LBM_P[2] << 8 ) + ( LBM_P[1] << 16 ) + ( LBM_P[0] << 24 );
-               LBM_P += 4;
-
-               switch ( chunktype )
-               {
-               case BMHDID:
-                       memcpy( &bmhd,LBM_P,sizeof( bmhd ) );
-                       bmhd.w = BigShort( bmhd.w );
-                       bmhd.h = BigShort( bmhd.h );
-                       bmhd.x = BigShort( bmhd.x );
-                       bmhd.y = BigShort( bmhd.y );
-                       bmhd.pageWidth = BigShort( bmhd.pageWidth );
-                       bmhd.pageHeight = BigShort( bmhd.pageHeight );
-                       break;
-
-               case CMAPID:
-                       cmapbuffer = malloc( 768 );
-                       memset( cmapbuffer, 0, 768 );
-                       memcpy( cmapbuffer, LBM_P, chunklength );
-                       CorrectPalette( cmapbuffer );
-                       break;
-
-               case BODYID:
-                       body_p = LBM_P;
-
-                       pic_p = picbuffer = malloc( bmhd.w * bmhd.h );
-                       if ( formtype == PBMID ) {
-                               //
-                               // unpack PBM
-                               //
-                               for ( y = 0 ; y < bmhd.h ; y++, pic_p += bmhd.w )
-                               {
-                                       if ( bmhd.compression == cm_rle1 ) {
-                                               body_p = LBMRLEDecompress( (byte *)body_p
-                                                                                                  , pic_p, bmhd.w );
-                                       }
-                                       else if ( bmhd.compression == cm_none ) {
-                                               memcpy( pic_p,body_p,bmhd.w );
-                                               body_p += Align( bmhd.w );
-                                       }
-                               }
-
-                       }
-                       else
-                       {
-                               //
-                               // unpack ILBM
-                               //
-                               Error( "%s is an interlaced LBM, not packed", filename );
-                       }
-                       break;
-               }
-
-               LBM_P += Align( chunklength );
-       }
-
-       free( LBMbuffer );
-
-       *picture = picbuffer;
-
-       if ( palette ) {
-               *palette = cmapbuffer;
-       }
-}
-
-
-/*
-   ============================================================================
-
-                            WRITE LBM
-
-   ============================================================================
- */
-
-/*
-   ==============
-   WriteLBMfile
-   ==============
- */
-void WriteLBMfile( char *filename, byte *data,
-                                  int width, int height, byte *palette ){
-       byte    *lbm, *lbmptr;
-       int    *formlength, *bmhdlength, *cmaplength, *bodylength;
-       int length;
-       bmhd_t basebmhd;
-
-       lbm = lbmptr = malloc( width * height + 1000 );
-
-//
-// start FORM
-//
-       *lbmptr++ = 'F';
-       *lbmptr++ = 'O';
-       *lbmptr++ = 'R';
-       *lbmptr++ = 'M';
-
-       formlength = (int*)lbmptr;
-       lbmptr += 4;                      // leave space for length
-
-       *lbmptr++ = 'P';
-       *lbmptr++ = 'B';
-       *lbmptr++ = 'M';
-       *lbmptr++ = ' ';
-
-//
-// write BMHD
-//
-       *lbmptr++ = 'B';
-       *lbmptr++ = 'M';
-       *lbmptr++ = 'H';
-       *lbmptr++ = 'D';
-
-       bmhdlength = (int *)lbmptr;
-       lbmptr += 4;                      // leave space for length
-
-       memset( &basebmhd,0,sizeof( basebmhd ) );
-       basebmhd.w = BigShort( (short)width );
-       basebmhd.h = BigShort( (short)height );
-       basebmhd.nPlanes = BigShort( 8 );
-       basebmhd.xAspect = BigShort( 5 );
-       basebmhd.yAspect = BigShort( 6 );
-       basebmhd.pageWidth = BigShort( (short)width );
-       basebmhd.pageHeight = BigShort( (short)height );
-
-       memcpy( lbmptr,&basebmhd,sizeof( basebmhd ) );
-       lbmptr += sizeof( basebmhd );
-
-       length = lbmptr - (byte *)bmhdlength - 4;
-       *bmhdlength = BigLong( length );
-       if ( length & 1 ) {
-               *lbmptr++ = 0;          // pad chunk to even offset
-
-       }
-//
-// write CMAP
-//
-       *lbmptr++ = 'C';
-       *lbmptr++ = 'M';
-       *lbmptr++ = 'A';
-       *lbmptr++ = 'P';
-
-       cmaplength = (int *)lbmptr;
-       lbmptr += 4;                      // leave space for length
-
-       memcpy( lbmptr,palette,768 );
-       lbmptr += 768;
-
-       length = lbmptr - (byte *)cmaplength - 4;
-       *cmaplength = BigLong( length );
-       if ( length & 1 ) {
-               *lbmptr++ = 0;          // pad chunk to even offset
-
-       }
-//
-// write BODY
-//
-       *lbmptr++ = 'B';
-       *lbmptr++ = 'O';
-       *lbmptr++ = 'D';
-       *lbmptr++ = 'Y';
-
-       bodylength = (int *)lbmptr;
-       lbmptr += 4;                      // leave space for length
-
-       memcpy( lbmptr,data,width * height );
-       lbmptr += width * height;
-
-       length = lbmptr - (byte *)bodylength - 4;
-       *bodylength = BigLong( length );
-       if ( length & 1 ) {
-               *lbmptr++ = 0;          // pad chunk to even offset
-
-       }
-//
-// done
-//
-       length = lbmptr - (byte *)formlength - 4;
-       *formlength = BigLong( length );
-       if ( length & 1 ) {
-               *lbmptr++ = 0;          // pad chunk to even offset
-
-       }
-//
-// write output file
-//
-       SaveFile( filename, lbm, lbmptr - lbm );
-       free( lbm );
-}
-
-
-/*
-   ============================================================================
-
-   LOAD PCX
-
-   ============================================================================
- */
-
-typedef struct
-{
-       char manufacturer;
-       char version;
-       char encoding;
-       char bits_per_pixel;
-       unsigned short xmin,ymin,xmax,ymax;
-       unsigned short hres,vres;
-       unsigned char palette[48];
-       char reserved;
-       char color_planes;
-       unsigned short bytes_per_line;
-       unsigned short palette_type;
-       char filler[58];
-       unsigned char data;             // unbounded
-} pcx_t;
-
-/*
-   ==============
-   LoadPCX
-   ==============
- */
-void LoadPCX( char *filename, byte **pic, byte **palette, int *width, int *height ){
-       byte    *raw;
-       pcx_t   *pcx;
-       int x, y;
-       int len;
-       int dataByte, runLength;
-       byte    *out, *pix;
-
-       //
-       // load the file
-       //
-       len = LoadFile( filename, (void **)&raw );
-
-       //
-       // parse the PCX file
-       //
-       pcx = (pcx_t *)raw;
-       raw = &pcx->data;
-
-       pcx->xmin = LittleShort( pcx->xmin );
-       pcx->ymin = LittleShort( pcx->ymin );
-       pcx->xmax = LittleShort( pcx->xmax );
-       pcx->ymax = LittleShort( pcx->ymax );
-       pcx->hres = LittleShort( pcx->hres );
-       pcx->vres = LittleShort( pcx->vres );
-       pcx->bytes_per_line = LittleShort( pcx->bytes_per_line );
-       pcx->palette_type = LittleShort( pcx->palette_type );
-
-       if ( pcx->manufacturer != 0x0a
-                || pcx->version != 5
-                || pcx->encoding != 1
-                || pcx->bits_per_pixel != 8
-                || pcx->xmax >= 640
-                || pcx->ymax >= 480 ) {
-               Error( "Bad pcx file %s", filename );
-       }
-
-       if ( palette ) {
-               *palette = malloc( 768 );
-               memcpy( *palette, (byte *)pcx + len - 768, 768 );
-               CorrectPalette( *palette );
-       }
-
-       if ( width ) {
-               *width = pcx->xmax + 1;
-       }
-       if ( height ) {
-               *height = pcx->ymax + 1;
-       }
-
-       if ( !pic ) {
-               return;
-       }
-
-       out = malloc( ( pcx->ymax + 1 ) * ( pcx->xmax + 1 ) );
-       if ( !out ) {
-               Error( "Skin_Cache: couldn't allocate" );
-       }
-
-       *pic = out;
-
-       pix = out;
-
-       for ( y = 0 ; y <= pcx->ymax ; y++, pix += pcx->xmax + 1 )
-       {
-               for ( x = 0 ; x <= pcx->xmax ; )
-               {
-                       dataByte = *raw++;
-
-                       if ( ( dataByte & 0xC0 ) == 0xC0 ) {
-                               runLength = dataByte & 0x3F;
-                               dataByte = *raw++;
-                       }
-                       else{
-                               runLength = 1;
-                       }
-
-                       while ( runLength-- > 0 )
-                               pix[x++] = dataByte;
-               }
-
-       }
-
-       if ( raw - (byte *)pcx > len ) {
-               Error( "PCX file %s was malformed", filename );
-       }
-
-       free( pcx );
-}
-
-/*
-   ==============
-   WritePCXfile
-   ==============
- */
-
-void StuffPackedByte( int curRepCount, byte curByte, byte** packPtr ){
-       byte* pack;
-
-       pack = *packPtr;
-
-       while ( curRepCount > 0 )
-       {
-               if ( curRepCount == 1 ) {
-                       if ( ( curByte & 0xc0 ) != 0xc0 ) {
-                               *pack++ = curByte;
-                       }
-                       else
-                       {
-                               *pack++ = 0xc1;
-                               *pack++ = curByte;
-                       }
-                       break;
-               }
-               if ( curRepCount < 0x0040 ) {
-                       *pack++ = ( 0x00c0 | curRepCount );
-                       curRepCount = 0;
-               }
-               else
-               {
-                       *pack++ = 0xff;
-                       curRepCount -= 0x003f;
-               }
-               *pack++ = curByte;
-       }
-       *packPtr = pack;
-}
-
-void WritePCXfile( char *filename, byte *data,
-                                  int width, int height, byte *palette ){
-       int i, j, length;
-       pcx_t       *pcx;
-       byte        *pack;
-       byte curByte;
-       int curRepCount;
-
-       pcx = malloc( width * height * 2 + 1000 );
-       memset( pcx, 0, sizeof( *pcx ) );
-
-       pcx->manufacturer = 0x0a;   // PCX id
-       pcx->version = 5;           // 256 color
-       pcx->encoding = 1;      // RLE
-       pcx->bits_per_pixel = 8;        // 256 color
-       pcx->xmin = 0;
-       pcx->ymin = 0;
-       pcx->xmax = LittleShort( (short)( width - 1 ) );
-       pcx->ymax = LittleShort( (short)( height - 1 ) );
-       pcx->hres = LittleShort( (short)width );
-       pcx->vres = LittleShort( (short)height );
-       pcx->color_planes = 1;      // chunky image
-       pcx->bytes_per_line = LittleShort( (short)width );
-       pcx->palette_type = LittleShort( 1 );     // not a grey scale
-
-       // pack the image
-       pack = &pcx->data;
-
-/*     for (i=0 ; i<height ; i++)
-    {
-        for (j=0 ; j<width ; j++)
-        {
-            if ( (*data & 0xc0) != 0xc0)
-   *pack++ = *data++;
-            else
-            {
-   *pack++ = 0xc1;
-   *pack++ = *data++;
-            }
-        }
-    }
- */
-       for ( i = 0 ; i < height ; i++ )
-       {
-               curByte = *data;
-               curRepCount = 0;
-               for ( j = 0 ; j < width ; j++ )
-               {
-                       if ( *data == curByte ) {
-                               curRepCount++;
-                               data++;
-                               continue;
-                       }
-                       StuffPackedByte( curRepCount, curByte, &pack );
-                       curByte = *data++;
-                       curRepCount = 1;
-               }
-               StuffPackedByte( curRepCount, curByte, &pack );
-       }
-       // write the palette
-       *pack++ = 0x0c; // palette ID byte
-       for ( i = 0 ; i < 768 ; i++ )
-               *pack++ = *palette++;
-
-// write output file
-       length = pack - (byte *)pcx;
-       SaveFile( filename, pcx, length );
-
-       free( pcx );
-}
-
-
-/*
-   ============================================================================
-
-   LOAD IMAGE
-
-   ============================================================================
- */
-
-/*
-   ==============
-   Load256Image
-
-   Will load either an lbm or pcx, depending on extension.
-   Any of the return pointers can be NULL if you don't want them.
-   ==============
- */
-void Load256Image( char *name, byte **pixels, byte **palette,
-                                  int *width, int *height ){
-       char ext[128];
-
-       ExtractFileExtension( name, ext );
-       if ( !Q_strcasecmp( ext, "lbm" ) ) {
-               LoadLBM( name, pixels, palette );
-               if ( width ) {
-                       *width = bmhd.w;
-               }
-               if ( height ) {
-                       *height = bmhd.h;
-               }
-       }
-       else if ( !Q_strcasecmp( ext, "pcx" ) ) {
-               LoadPCX( name, pixels, palette, width, height );
-       }
-       else{
-               Error( "%s doesn't have a known image extension", name );
-       }
-}
-
-
-/*
-   ==============
-   Save256Image
-
-   Will save either an lbm or pcx, depending on extension.
-   ==============
- */
-void Save256Image( char *name, byte *pixels, byte *palette,
-                                  int width, int height ){
-       char ext[128];
-
-       ExtractFileExtension( name, ext );
-       if ( !Q_strcasecmp( ext, "lbm" ) ) {
-               WriteLBMfile( name, pixels, width, height, palette );
-       }
-       else if ( !Q_strcasecmp( ext, "pcx" ) ) {
-               WritePCXfile( name, pixels, width, height, palette );
-       }
-       else{
-               Error( "%s doesn't have a known image extension", name );
-       }
-}
-
-
-
-
-/*
-   ============================================================================
-
-   TARGA IMAGE
-
-   ============================================================================
- */
-
-typedef struct _TargaHeader
-{
-       unsigned char id_length, colormap_type, image_type;
-       unsigned short colormap_index, colormap_length;
-       unsigned char colormap_size;
-       unsigned short x_origin, y_origin, width, height;
-       unsigned char pixel_size, attributes;
-} TargaHeader;
-
-int fgetLittleShort( FILE *f ){
-       byte b1, b2;
-
-       b1 = fgetc( f );
-       b2 = fgetc( f );
-
-       return( (short)( b1 + ( b2 << 8 ) ) );
-}
-
-int fgetLittleLong( FILE *f ){
-       byte b1, b2, b3, b4;
-
-       b1 = fgetc( f );
-       b2 = fgetc( f );
-       b3 = fgetc( f );
-       b4 = fgetc( f );
-
-       return( b1 + ( b2 << 8 ) + ( b3 << 16 ) + ( b4 << 24 ) );
-}
-
-
-/*
-   =============
-   LoadTGA
-   =============
- */
-void LoadTGA( char *name, byte **pixels, int *width, int *height ){
-       int columns, rows, numPixels;
-       byte            *pixbuf;
-       byte            *rowBuf;
-       int row, column;
-       FILE            *fin;
-       byte            *targa_rgba;
-       TargaHeader targa_header;
-       unsigned char red, green, blue, alphabyte;
-       unsigned char packetHeader, packetSize, j;
-       int flip;
-       int mirror;
-       int rowOffset;
-       int pixDirection;
-
-       fin = fopen( name, "rb" );
-       if ( !fin ) {
-               Error( "Couldn't read %s", name );
-       }
-
-       targa_header.id_length = fgetc( fin );
-       targa_header.colormap_type = fgetc( fin );
-       targa_header.image_type = fgetc( fin );
-
-       targa_header.colormap_index = fgetLittleShort( fin );
-       targa_header.colormap_length = fgetLittleShort( fin );
-       targa_header.colormap_size = fgetc( fin );
-       targa_header.x_origin = fgetLittleShort( fin );
-       targa_header.y_origin = fgetLittleShort( fin );
-       targa_header.width = fgetLittleShort( fin );
-       targa_header.height = fgetLittleShort( fin );
-       targa_header.pixel_size = fgetc( fin );
-       targa_header.attributes = fgetc( fin );
-       flip = ( targa_header.attributes & 0x020 ) == 0;
-       mirror = ( targa_header.attributes & 0x010 ) != 0;
-
-       if ( ( targa_header.image_type != 2 ) && ( targa_header.image_type != 10 ) ) {
-               Error( "LoadTGA: Only type 2 and 10 targa RGB images supported\n" );
-       }
-
-       if ( targa_header.colormap_type || ( ( targa_header.pixel_size != 32 ) && ( targa_header.pixel_size != 24 ) ) ) {
-               Error( "Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n" );
-       }
-
-       columns = targa_header.width;
-       rows = targa_header.height;
-       numPixels = columns * rows;
-
-       if ( width ) {
-               *width = columns;
-       }
-       if ( height ) {
-               *height = rows;
-       }
-
-       if ( !pixels ) {
-               return;
-       }
-
-       targa_rgba = malloc( numPixels * 4 );
-       *pixels = targa_rgba;
-
-       if ( flip ) {
-               pixbuf = targa_rgba + ( ( rows - 1 ) * columns * 4 );
-               rowOffset = -columns * 4;
-       }
-       else
-       {
-               pixbuf = targa_rgba;
-               rowOffset = columns * 4;
-       }
-       if ( mirror ) {
-               pixDirection = -4;
-               pixbuf += ( ( columns - 1 ) * 4 );
-       }
-       else
-       {
-               pixDirection = 4;
-       }
-
-       if ( targa_header.id_length ) {
-               fseek( fin, targa_header.id_length, SEEK_CUR );  // skip TARGA image comment
-
-       }
-       if ( targa_header.image_type == 2 ) {                 // Uncompressed, RGB images
-               for ( row = 0; row < rows; row++ )
-               {
-                       rowBuf = pixbuf;
-                       for ( column = 0; column < columns; column++ )
-                       {
-                               switch ( targa_header.pixel_size )
-                               {
-                               case 24:
-                                       blue = getc( fin );
-                                       green = getc( fin );
-                                       red = getc( fin );
-                                       rowBuf[0] = red;
-                                       rowBuf[1] = green;
-                                       rowBuf[2] = blue;
-                                       rowBuf[3] = 255;
-                                       rowBuf += pixDirection;
-                                       break;
-                               case 32:
-                                       blue = getc( fin );
-                                       green = getc( fin );
-                                       red = getc( fin );
-                                       alphabyte = getc( fin );
-                                       rowBuf[0] = red;
-                                       rowBuf[1] = green;
-                                       rowBuf[2] = blue;
-                                       rowBuf[3] = alphabyte;
-                                       rowBuf += pixDirection;
-                                       break;
-                               }
-                       }
-                       pixbuf += rowOffset;
-               }
-       }
-       else if ( targa_header.image_type == 10 ) {        // Runlength encoded RGB images
-               for ( row = 0; row < rows; row++ )
-               {
-                       rowBuf = pixbuf;
-                       for ( column = 0; column < columns; )
-                       {
-                               packetHeader = getc( fin );
-                               packetSize = 1 + ( packetHeader & 0x7f );
-                               if ( packetHeader & 0x80 ) {          // run-length packet
-                                       switch ( targa_header.pixel_size )
-                                       {
-                                       case 24:
-                                               blue = getc( fin );
-                                               green = getc( fin );
-                                               red = getc( fin );
-                                               alphabyte = 255;
-                                               break;
-                                       case 32:
-                                               blue = getc( fin );
-                                               green = getc( fin );
-                                               red = getc( fin );
-                                               alphabyte = getc( fin );
-                                               break;
-                                       }
-
-                                       for ( j = 0; j < packetSize; j++ )
-                                       {
-                                               rowBuf[0] = red;
-                                               rowBuf[1] = green;
-                                               rowBuf[2] = blue;
-                                               rowBuf[3] = alphabyte;
-                                               rowBuf += pixDirection;
-                                               column++;
-                                               if ( column == columns ) {             // run spans across rows
-                                                       column = 0;
-                                                       row++;
-                                                       if ( row >= rows ) {
-                                                               goto breakOut;
-                                                       }
-                                                       pixbuf += rowOffset;
-                                                       rowBuf = pixbuf;
-                                               }
-                                       }
-                               }
-                               else
-                               {                                       // non run-length packet
-                                       for ( j = 0; j < packetSize; j++ )
-                                       {
-                                               switch ( targa_header.pixel_size )
-                                               {
-                                               case 24:
-                                                       blue = getc( fin );
-                                                       green = getc( fin );
-                                                       red = getc( fin );
-                                                       rowBuf[0] = red;
-                                                       rowBuf[1] = green;
-                                                       rowBuf[2] = blue;
-                                                       rowBuf[3] = 255;
-                                                       rowBuf += pixDirection;
-                                                       break;
-                                               case 32:
-                                                       blue = getc( fin );
-                                                       green = getc( fin );
-                                                       red = getc( fin );
-                                                       alphabyte = getc( fin );
-                                                       rowBuf[0] = red;
-                                                       rowBuf[1] = green;
-                                                       rowBuf[2] = blue;
-                                                       rowBuf[3] = alphabyte;
-                                                       rowBuf += pixDirection;
-                                                       break;
-                                               }
-                                               column++;
-                                               if ( column == columns ) {    // pixel packet run spans across rows
-                                                       column = 0;
-                                                       row++;
-                                                       if ( row >= rows ) {
-                                                               goto breakOut;
-                                                       }
-                                                       pixbuf += rowOffset;
-                                                       rowBuf = pixbuf;
-                                               }
-                                       }
-                               }
-                       }
-breakOut:;
-                       pixbuf += rowOffset;
-               }
-       }
-       fclose( fin );
-}
-
-void MergeAlpha( byte *pix, byte *alpha, byte *pal, byte **out, int width, int height ){
-       int size, i;
-       byte    *data, *src, *srca;
-
-       size = width * height;
-       data = malloc( size * 4 );
-       if ( !data ) {
-               Error( "Could not allocate memory for true color image" );
-       }
-
-       *out = data;
-       src = pix;
-       srca = alpha;
-
-       for ( i = 0; i < size; i++, src++, srca++ )
-       {
-               *data++ = pal[*src * 3 + 0];      // r
-               *data++ = pal[*src * 3 + 1];      // g
-               *data++ = pal[*src * 3 + 2];      // b
-               *data++ = *srca;                  // a
-       }
-       free( pix );
-       free( alpha );
-       free( pal );
-}
-
-/*
-   ==============
-   LoadAnyImage
-
-   Return Value:
-    false: paletted texture
-    true:  true color RGBA image (no palette)
-   ==============
- */
-qboolean LoadAnyImage( char *name, byte **pixels, byte **palette, int *width, int *height ){
-       char ext[128];
-       int len;
-       int alpha_width, alpha_height;
-       char alpha_name[128];
-       byte    *alpha_pixels;
-
-       ExtractFileExtension( name, ext );
-
-       if ( palette ) {
-               *palette = NULL;
-       }
-
-       if ( !Q_strcasecmp( ext, "lbm" ) ) {
-               LoadLBM( name, pixels, palette );
-               if ( width ) {
-                       *width = bmhd.w;
-               }
-               if ( height ) {
-                       *height = bmhd.h;
-               }
-               return false;
-       }
-       else if ( !Q_strcasecmp( ext, "pcx" ) ) {
-               len = strlen( name );
-               strcpy( alpha_name, name );
-               strcpy( &alpha_name[len - 4], "_a.pcx" );                 // Alpha map name (may not exist)
-
-               if ( FileExists( alpha_name ) ) {
-                       LoadPCX( name, pixels, palette, width, height );                         // Load in image
-                       LoadPCX( alpha_name, &alpha_pixels, NULL, &alpha_width, &alpha_height ); // Load in alpha map
-                       if ( ( *width != alpha_width ) || ( *height != alpha_height ) ) {
-                               Error( "Alpha image dimensions not equal to graphic image dimensions" );
-                       }
-                       MergeAlpha( *pixels, alpha_pixels, *palette, pixels, *width, *height );
-                       *palette = NULL; //Merge Frees pal
-                       return true;
-               }
-               else
-               {
-                       LoadPCX( name, pixels, palette, width, height );         // Load in image
-                       return false;
-               }
-       }
-       else if ( !Q_strcasecmp( ext, "tga" ) ) {
-               LoadTGA( name, pixels, width, height );
-               if ( palette ) {
-                       *palette = NULL;
-               }
-
-               return true;
-       }
-       else{
-               Error( "%s doesn't have a known image extension", name );
-       }
-
-       return false;
-}
diff --git a/tools/quake2/qdata_heretic2/common/lbmlib.h b/tools/quake2/qdata_heretic2/common/lbmlib.h
deleted file mode 100644 (file)
index 5ee2909..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// piclib.h
-
-
-void LoadLBM( char *filename, byte **picture, byte **palette );
-void WriteLBMfile( char *filename, byte *data, int width, int height
-                                  , byte *palette );
-void LoadPCX( char *filename, byte **picture, byte **palette, int *width, int *height );
-void WritePCXfile( char *filename, byte *data, int width, int height
-                                  , byte *palette );
-
-// loads / saves either lbm or pcx, depending on extension
-void Load256Image( char *name, byte **pixels, byte **palette,
-                                  int *width, int *height );
-void Save256Image( char *name, byte *pixels, byte *palette,
-                                  int width, int height );
-
-
-void LoadTGA( char *filename, byte **pixels, int *width, int *height );
-
-qboolean LoadAnyImage( char *name, byte **pixels, byte **palette, int *width, int *height );
diff --git a/tools/quake2/qdata_heretic2/common/mathlib.c b/tools/quake2/qdata_heretic2/common/mathlib.c
deleted file mode 100644 (file)
index 8243d86..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// mathlib.c -- math primitives
-
-#include "cmdlib.h"
-#include "mathlib.h"
-
-vec3_t vec3_origin = {0,0,0};
-
-
-double VectorLength( vec3_t v ){
-       int i;
-       double length;
-
-       length = 0;
-       for ( i = 0 ; i < 3 ; i++ )
-               length += v[i] * v[i];
-       length = sqrt( length );     // FIXME
-
-       return length;
-}
-
-qboolean VectorCompare( vec3_t v1, vec3_t v2 ){
-       int i;
-
-       for ( i = 0 ; i < 3 ; i++ )
-               if ( fabs( v1[i] - v2[i] ) > EQUAL_EPSILON ) {
-                       return false;
-               }
-
-       return true;
-}
-
-vec_t Q_rint( vec_t in ){
-       return floor( in + 0.5 );
-}
-
-void VectorMA( vec3_t va, double scale, vec3_t vb, vec3_t vc ){
-       vc[0] = va[0] + scale * vb[0];
-       vc[1] = va[1] + scale * vb[1];
-       vc[2] = va[2] + scale * vb[2];
-}
-
-void CrossProduct( vec3_t v1, vec3_t v2, vec3_t cross ){
-       cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
-       cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
-       cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
-}
-
-vec_t _DotProduct( vec3_t v1, vec3_t v2 ){
-       return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
-}
-
-void _VectorSubtract( vec3_t va, vec3_t vb, vec3_t out ){
-       out[0] = va[0] - vb[0];
-       out[1] = va[1] - vb[1];
-       out[2] = va[2] - vb[2];
-}
-
-void _VectorAdd( vec3_t va, vec3_t vb, vec3_t out ){
-       out[0] = va[0] + vb[0];
-       out[1] = va[1] + vb[1];
-       out[2] = va[2] + vb[2];
-}
-
-void _VectorCopy( vec3_t in, vec3_t out ){
-       out[0] = in[0];
-       out[1] = in[1];
-       out[2] = in[2];
-}
-
-void _VectorScale( vec3_t v, vec_t scale, vec3_t out ){
-       out[0] = v[0] * scale;
-       out[1] = v[1] * scale;
-       out[2] = v[2] * scale;
-}
-
-#if GDEF_COMPILER_MSVC
-#pragma optimize("g", off)  // went back to turning optimization off,
-                            // the bug_fix thing stopped working
-#endif
-
-vec_t VectorNormalize( vec3_t in, vec3_t out ){
-       vec_t length, ilength;
-
-       length = sqrt( in[0] * in[0] + in[1] * in[1] + in[2] * in[2] );
-       if ( length == 0 ) {
-               VectorClear( out );
-               return 0;
-       }
-
-       ilength = 1.0 / length;
-       out[0] = in[0] * ilength;
-       out[1] = in[1] * ilength;
-       out[2] = in[2] * ilength;
-
-       return length;
-}
-
-vec_t ColorNormalize( vec3_t in, vec3_t out ){
-       float max, scale;
-
-       max = in[0];
-       if ( in[1] > max ) {
-               max = in[1];
-       }
-       if ( in[2] > max ) {
-               max = in[2];
-       }
-
-       if ( max == 0 ) {
-               return 0;
-       }
-
-       scale = 1.0 / max;
-
-       VectorScale( in, scale, out );
-
-       return max;
-}
-
-#if GDEF_COMPILER_MSVC
-#pragma optimize("", on)
-#endif
-
-void VectorInverse( vec3_t v ){
-       v[0] = -v[0];
-       v[1] = -v[1];
-       v[2] = -v[2];
-}
-
-void ClearBounds( vec3_t mins, vec3_t maxs ){
-       mins[0] = mins[1] = mins[2] = 99999;
-       maxs[0] = maxs[1] = maxs[2] = -99999;
-}
-
-void AddPointToBounds( vec3_t v, vec3_t mins, vec3_t maxs ){
-       int i;
-       vec_t val;
-
-       for ( i = 0 ; i < 3 ; i++ )
-       {
-               val = v[i];
-               if ( val < mins[i] ) {
-                       mins[i] = val;
-               }
-               if ( val > maxs[i] ) {
-                       maxs[i] = val;
-               }
-       }
-}
diff --git a/tools/quake2/qdata_heretic2/common/mathlib.h b/tools/quake2/qdata_heretic2/common/mathlib.h
deleted file mode 100644 (file)
index cd989ea..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef __MATHLIB__
-#define __MATHLIB__
-
-// mathlib.h
-
-#include <math.h>
-/*
-   #ifdef DOUBLEVEC_T
-   typedef double vec_t;
-   #else
-   typedef float vec_t;
-   #endif
-   typedef vec_t vec3_t[3];
- */
-#define SIDE_FRONT      0
-#define SIDE_ON         2
-#define SIDE_BACK       1
-#define SIDE_CROSS      -2
-
-#define Q_PI    3.14159265358979323846
-
-extern vec3_t vec3_origin;
-
-#define EQUAL_EPSILON   0.001
-
-qboolean VectorCompare( vec3_t v1, vec3_t v2 );
-
-#define DotProduct( x,y ) ( x[0] * y[0] + x[1] * y[1] + x[2] * y[2] )
-#define VectorSubtract( a,b,c ) {c[0] = a[0] - b[0]; c[1] = a[1] - b[1]; c[2] = a[2] - b[2]; }
-#define VectorAdd( a,b,c ) {c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; }
-#define VectorCopy( a,b ) {b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
-#define VectorScale( a,b,c ) {c[0] = b * a[0]; c[1] = b * a[1]; c[2] = b * a[2]; }
-#define VectorClear( x ) {x[0] = x[1] = x[2] = 0; }
-#define VectorNegate( x ) {x[0] = -x[0]; x[1] = -x[1]; x[2] = -x[2]; }
-
-vec_t Q_rint( vec_t in );
-vec_t _DotProduct( vec3_t v1, vec3_t v2 );
-void _VectorSubtract( vec3_t va, vec3_t vb, vec3_t out );
-void _VectorAdd( vec3_t va, vec3_t vb, vec3_t out );
-void _VectorCopy( vec3_t in, vec3_t out );
-void _VectorScale( vec3_t v, vec_t scale, vec3_t out );
-
-double VectorLength( vec3_t v );
-
-void VectorMA( vec3_t va, double scale, vec3_t vb, vec3_t vc );
-
-void CrossProduct( vec3_t v1, vec3_t v2, vec3_t cross );
-vec_t VectorNormalize( vec3_t in, vec3_t out );
-vec_t ColorNormalize( vec3_t in, vec3_t out );
-void VectorInverse( vec3_t v );
-
-void ClearBounds( vec3_t mins, vec3_t maxs );
-void AddPointToBounds( vec3_t v, vec3_t mins, vec3_t maxs );
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/common/md4.c b/tools/quake2/qdata_heretic2/common/md4.c
deleted file mode 100644 (file)
index f503422..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-    mdfour.c
-
-    An implementation of MD4 designed for use in the samba SMB
-    authentication protocol
-
-    Copyright (C) 1997-1998  Andrew Tridgell
-
-    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:
-
-        Free Software Foundation, Inc.
-        59 Temple Place - Suite 330
-        Boston, MA  02111-1307, USA
-
-    $Id: mdfour.c 7689 2007-11-12 14:28:40Z divverent $
- */
-
-#include <string.h>     /* XoXus: needed for memset call */
-#include "md4.h"
-
-/* NOTE: This code makes no attempt to be fast!
-
-   It assumes that a int is at least 32 bits long
- */
-
-static struct mdfour *m;
-
-#define F( X,Y,Z ) ( ( (X)&( Y ) ) | ( ( ~( X ) ) & ( Z ) ) )
-#define G( X,Y,Z ) ( ( (X)&( Y ) ) | ( (X)&( Z ) ) | ( (Y)&( Z ) ) )
-#define H( X,Y,Z ) ( ( X ) ^ ( Y ) ^ ( Z ) )
-#ifdef LARGE_INT32
-#define lshift( x,s ) ( ( ( ( x ) << ( s ) ) & 0xFFFFFFFF ) | ( ( ( x ) >> ( 32 - ( s ) ) ) & 0xFFFFFFFF ) )
-#else
-#define lshift( x,s ) ( ( ( x ) << ( s ) ) | ( ( x ) >> ( 32 - ( s ) ) ) )
-#endif
-
-#define ROUND1( a,b,c,d,k,s ) a = lshift( a + F( b,c,d ) + X[k], s )
-#define ROUND2( a,b,c,d,k,s ) a = lshift( a + G( b,c,d ) + X[k] + 0x5A827999,s )
-#define ROUND3( a,b,c,d,k,s ) a = lshift( a + H( b,c,d ) + X[k] + 0x6ED9EBA1,s )
-
-/* this applies md4 to 64 byte chunks */
-static void mdfour64( uint32 *M ){
-       int j;
-       uint32 AA, BB, CC, DD;
-       uint32 X[16];
-       uint32 A,B,C,D;
-
-       for ( j = 0; j < 16; j++ )
-               X[j] = M[j];
-
-       A = m->A; B = m->B; C = m->C; D = m->D;
-       AA = A; BB = B; CC = C; DD = D;
-
-       ROUND1( A,B,C,D,  0,  3 );  ROUND1( D,A,B,C,  1,  7 );
-       ROUND1( C,D,A,B,  2, 11 );  ROUND1( B,C,D,A,  3, 19 );
-       ROUND1( A,B,C,D,  4,  3 );  ROUND1( D,A,B,C,  5,  7 );
-       ROUND1( C,D,A,B,  6, 11 );  ROUND1( B,C,D,A,  7, 19 );
-       ROUND1( A,B,C,D,  8,  3 );  ROUND1( D,A,B,C,  9,  7 );
-       ROUND1( C,D,A,B, 10, 11 );  ROUND1( B,C,D,A, 11, 19 );
-       ROUND1( A,B,C,D, 12,  3 );  ROUND1( D,A,B,C, 13,  7 );
-       ROUND1( C,D,A,B, 14, 11 );  ROUND1( B,C,D,A, 15, 19 );
-
-       ROUND2( A,B,C,D,  0,  3 );  ROUND2( D,A,B,C,  4,  5 );
-       ROUND2( C,D,A,B,  8,  9 );  ROUND2( B,C,D,A, 12, 13 );
-       ROUND2( A,B,C,D,  1,  3 );  ROUND2( D,A,B,C,  5,  5 );
-       ROUND2( C,D,A,B,  9,  9 );  ROUND2( B,C,D,A, 13, 13 );
-       ROUND2( A,B,C,D,  2,  3 );  ROUND2( D,A,B,C,  6,  5 );
-       ROUND2( C,D,A,B, 10,  9 );  ROUND2( B,C,D,A, 14, 13 );
-       ROUND2( A,B,C,D,  3,  3 );  ROUND2( D,A,B,C,  7,  5 );
-       ROUND2( C,D,A,B, 11,  9 );  ROUND2( B,C,D,A, 15, 13 );
-
-       ROUND3( A,B,C,D,  0,  3 );  ROUND3( D,A,B,C,  8,  9 );
-       ROUND3( C,D,A,B,  4, 11 );  ROUND3( B,C,D,A, 12, 15 );
-       ROUND3( A,B,C,D,  2,  3 );  ROUND3( D,A,B,C, 10,  9 );
-       ROUND3( C,D,A,B,  6, 11 );  ROUND3( B,C,D,A, 14, 15 );
-       ROUND3( A,B,C,D,  1,  3 );  ROUND3( D,A,B,C,  9,  9 );
-       ROUND3( C,D,A,B,  5, 11 );  ROUND3( B,C,D,A, 13, 15 );
-       ROUND3( A,B,C,D,  3,  3 );  ROUND3( D,A,B,C, 11,  9 );
-       ROUND3( C,D,A,B,  7, 11 );  ROUND3( B,C,D,A, 15, 15 );
-
-       A += AA; B += BB; C += CC; D += DD;
-
-#ifdef LARGE_INT32
-       A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
-       C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
-#endif
-
-       for ( j = 0; j < 16; j++ )
-               X[j] = 0;
-
-       m->A = A; m->B = B; m->C = C; m->D = D;
-}
-
-static void copy64( uint32 *M, unsigned char *in ){
-       int i;
-
-       for ( i = 0; i < 16; i++ )
-               M[i] = ( in[i * 4 + 3] << 24 ) | ( in[i * 4 + 2] << 16 ) |
-                          ( in[i * 4 + 1] << 8 ) | ( in[i * 4 + 0] << 0 );
-}
-
-static void copy4( unsigned char *out,uint32 x ){
-       out[0] = x & 0xFF;
-       out[1] = ( x >> 8 ) & 0xFF;
-       out[2] = ( x >> 16 ) & 0xFF;
-       out[3] = ( x >> 24 ) & 0xFF;
-}
-
-void mdfour_begin( struct mdfour *md ){
-       md->A = 0x67452301;
-       md->B = 0xefcdab89;
-       md->C = 0x98badcfe;
-       md->D = 0x10325476;
-       md->totalN = 0;
-}
-
-
-static void mdfour_tail( unsigned char *in, int n ){
-       unsigned char buf[128];
-       uint32 M[16];
-       uint32 b;
-
-       m->totalN += n;
-
-       b = m->totalN * 8;
-
-       memset( buf, 0, 128 );
-       if ( n ) {
-               memcpy( buf, in, n );
-       }
-       buf[n] = 0x80;
-
-       if ( n <= 55 ) {
-               copy4( buf + 56, b );
-               copy64( M, buf );
-               mdfour64( M );
-       }
-       else {
-               copy4( buf + 120, b );
-               copy64( M, buf );
-               mdfour64( M );
-               copy64( M, buf + 64 );
-               mdfour64( M );
-       }
-}
-
-void mdfour_update( struct mdfour *md, unsigned char *in, int n ){
-       uint32 M[16];
-
-// start of edit by Forest 'LordHavoc' Hale
-// commented out to prevent crashing when length is 0
-//     if (n == 0) mdfour_tail(in, n);
-// end of edit by Forest 'LordHavoc' Hale
-
-       m = md;
-
-       while ( n >= 64 ) {
-               copy64( M, in );
-               mdfour64( M );
-               in += 64;
-               n -= 64;
-               m->totalN += 64;
-       }
-
-       mdfour_tail( in, n );
-}
-
-
-void mdfour_result( struct mdfour *md, unsigned char *out ){
-       m = md;
-
-       copy4( out, m->A );
-       copy4( out + 4, m->B );
-       copy4( out + 8, m->C );
-       copy4( out + 12, m->D );
-}
-
-
-void mdfour( unsigned char *out, unsigned char *in, int n ){
-       struct mdfour md;
-       mdfour_begin( &md );
-       mdfour_update( &md, in, n );
-       mdfour_result( &md, out );
-}
-
-///////////////////////////////////////////////////////////////
-//     MD4-based checksum utility functions
-//
-//     Copyright (C) 2000       Jeff Teunissen <d2deek@pmail.net>
-//
-//     Author: Jeff Teunissen  <d2deek@pmail.net>
-//     Date: 01 Jan 2000
-
-unsigned Com_BlockChecksum( void *buffer, int length ){
-       int digest[4];
-       unsigned val;
-
-       mdfour( (unsigned char *) digest, (unsigned char *) buffer, length );
-
-       val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
-
-       return val;
-}
-
-void Com_BlockFullChecksum( void *buffer, int len, unsigned char *outbuf ){
-       mdfour( outbuf, (unsigned char *) buffer, len );
-}
diff --git a/tools/quake2/qdata_heretic2/common/md4.h b/tools/quake2/qdata_heretic2/common/md4.h
deleted file mode 100644 (file)
index 6f64c28..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-    mdfour.h
-
-    an implementation of MD4 designed for use in the SMB authentication
-    protocol
-
-    Copyright (C) Andrew Tridgell 1997-1998
-
-    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:
-
-        Free Software Foundation, Inc.
-        59 Temple Place - Suite 330
-        Boston, MA  02111-1307, USA
- */
-
-#ifndef _MDFOUR_H
-#define _MDFOUR_H
-
-#ifndef int32
-#define int32 int
-#endif
-
-#if SIZEOF_INT > 4
-#define LARGE_INT32
-#endif
-
-#ifndef uint32
-#define uint32 unsigned int32
-#endif
-
-struct mdfour {
-       uint32 A, B, C, D;
-       uint32 totalN;
-};
-
-void mdfour_begin( struct mdfour *md ); // old: MD4Init
-void mdfour_update( struct mdfour *md, unsigned char *in, int n ); //old: MD4Update
-void mdfour_result( struct mdfour *md, unsigned char *out ); // old: MD4Final
-void mdfour( unsigned char *out, unsigned char *in, int n );
-
-unsigned Com_BlockChecksum( void *buffer, int length );
-void Com_BlockFullChecksum( void *buffer, int len, unsigned char *outbuf );
-
-#endif  // _MDFOUR_H
diff --git a/tools/quake2/qdata_heretic2/common/path_init.c b/tools/quake2/qdata_heretic2/common/path_init.c
deleted file mode 100644 (file)
index 254977b..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-/* -------------------------------------------------------------------------------
-
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-/*
-   Nurail: Swiped from Q3Map2
- */
-
-#include "globaldefs.h"
-
-#if !GDEF_OS_WINDOWS
-       #include <unistd.h>
-       #include <pwd.h>
-       #include <limits.h>
-#endif // !GDEF_OS_WINDOWS
-
-/* dependencies */
-#include "cmdlib.h"
-#include "inout.h"
-
-/* path support */
-#define MAX_BASE_PATHS  10
-#define MAX_GAME_PATHS  10
-
-char                    *homePath;
-char installPath[ MAX_OS_PATH ];
-
-int numBasePaths;
-char                    *basePaths[ MAX_BASE_PATHS ];
-int numGamePaths;
-char                    *gamePaths[ MAX_GAME_PATHS ];
-
-/*
-   some of this code is based off the original q3map port from loki
-   and finds various paths. moved here from bsp.c for clarity.
- */
-
-/*
-   PathLokiGetHomeDir()
-   gets the user's home dir (for ~/.q3a)
- */
-
-char *LokiGetHomeDir( void ){
-       #if GDEF_OS_WINDOWS
-       return NULL;
-       #else // !GDEF_OS_WINDOWS
-       char            *home;
-       uid_t id;
-       struct passwd   *pwd;
-
-
-       /* get the home environment variable */
-       home = getenv( "HOME" );
-       if ( home == NULL ) {
-               /* do some more digging */
-               id = getuid();
-               setpwent();
-               while ( ( pwd = getpwent() ) != NULL )
-               {
-                       if ( pwd->pw_uid == id ) {
-                               home = pwd->pw_dir;
-                               break;
-                       }
-               }
-               endpwent();
-       }
-
-       /* return it */
-       return home;
-       #endif // !GDEF_OS_WINDOWS
-}
-
-
-
-/*
-   PathLokiInitPaths()
-   initializes some paths on linux/os x
- */
-
-void LokiInitPaths( char *argv0 ){
-       #if GDEF_OS_WINDOWS
-       /* this is kinda crap, but hey */
-       strcpy( installPath, "../" );
-       #else // !GDEF_OS_WINDOWS
-       char temp[ MAX_OS_PATH ];
-       char        *home;
-       char        *path;
-       char        *last;
-       qboolean found;
-
-
-       /* get home dir */
-       home = LokiGetHomeDir();
-       if ( home == NULL ) {
-               home = ".";
-       }
-
-       /* do some path divining */
-       strcpy( temp, argv0 );
-       if ( strrchr( temp, '/' ) ) {
-               argv0 = strrchr( argv0, '/' ) + 1;
-       }
-       else
-       {
-               /* get path environment variable */
-               path = getenv( "PATH" );
-
-               /* minor setup */
-               last[ 0 ] = path[ 0 ];
-               last[ 1 ] = '\0';
-               found = false;
-
-               /* go through each : segment of path */
-               while ( last[ 0 ] != '\0' && found == false )
-               {
-                       /* null out temp */
-                       temp[ 0 ] = '\0';
-
-                       /* find next chunk */
-                       last = strchr( path, ':' );
-                       if ( last == NULL ) {
-                               last = path + strlen( path );
-                       }
-
-                       /* found home dir candidate */
-                       if ( *path == '~' ) {
-                               strcpy( temp, home );
-                               path++;
-                       }
-
-                       /* concatenate */
-                       if ( last > ( path + 1 ) ) {
-                               strncat( temp, path, ( last - path ) );
-                               strcat( temp, "/" );
-                       }
-                       strcat( temp, "./" );
-                       strcat( temp, argv0 );
-
-                       /* verify the path */
-                       if ( access( temp, X_OK ) == 0 ) {
-                               found++;
-                       }
-                       path = last + 1;
-               }
-       }
-
-       /* flake */
-       if ( realpath( temp, installPath ) ) {
-               /* q3map is in "tools/" */
-               *( strrchr( installPath, '/' ) ) = '\0';
-               *( strrchr( installPath, '/' ) + 1 ) = '\0';
-       }
-
-       /* set home path */
-       homePath = home;
-       #endif // !GDEF_OS_WINDOWS
-}
-
-
-
-/*
-   CleanPath() - ydnar
-   cleans a dos path \ -> /
- */
-
-void CleanPath( char *path ){
-       while ( *path )
-       {
-               if ( *path == '\\' ) {
-                       *path = '/';
-               }
-               path++;
-       }
-}
-
-/*
-   AddBasePath() - ydnar
-   adds a base path to the list
- */
-
-void AddBasePath( char *path ){
-       /* dummy check */
-       if ( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS ) {
-               return;
-       }
-
-       /* add it to the list */
-       basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
-       strcpy( basePaths[ numBasePaths ], path );
-       CleanPath( basePaths[ numBasePaths ] );
-       numBasePaths++;
-}
-
-
-
-/*
-   AddHomeBasePath() - ydnar
-   adds a base path to the beginning of the list, prefixed by ~/
- */
-
-void AddHomeBasePath( char *path ){
-       #if !GDEF_OS_WINDOWS
-       int i;
-       char temp[ MAX_OS_PATH ];
-
-
-       /* dummy check */
-       if ( path == NULL || path[ 0 ] == '\0' ) {
-               return;
-       }
-
-       /* make a hole */
-       for ( i = 0; i < ( MAX_BASE_PATHS - 1 ); i++ )
-               basePaths[ i + 1 ] = basePaths[ i ];
-
-       /* concatenate home dir and path */
-       sprintf( temp, "%s/%s", homePath, path );
-
-       /* add it to the list */
-       basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
-       strcpy( basePaths[ 0 ], temp );
-       CleanPath( basePaths[ 0 ] );
-       numBasePaths++;
-       #endif // !GDEF_OS_WINDOWS
-}
-
-
-
-/*
-   AddGamePath() - ydnar
-   adds a game path to the list
- */
-
-void AddGamePath( char *path ){
-       /* dummy check */
-       if ( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS ) {
-               return;
-       }
-
-       /* add it to the list */
-       gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
-       strcpy( gamePaths[ numGamePaths ], path );
-       CleanPath( gamePaths[ numGamePaths ] );
-       numGamePaths++;
-}
-
-
-
-
-/*
-   InitPaths() - ydnar
-   cleaned up some of the path initialization code from bsp.c
-   will remove any arguments it uses
- */
-
-void InitPaths( int *argc, char **argv ){
-       int i, j, k, len, len2;
-       char temp[ MAX_OS_PATH ];
-       char gamePath[MAX_OS_PATH], homeBasePath[MAX_OS_PATH], game_magic[10];
-
-       strcpy( gamePath, "base" );
-       strcpy( game_magic, "h" );
-       strcpy( homeBasePath, ".heretic2" );
-
-       /* note it */
-       Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
-
-       /* get the install path for backup */
-       LokiInitPaths( argv[ 0 ] );
-
-       /* set game to default (q3a) */
-       numBasePaths = 0;
-       numGamePaths = 0;
-
-       /* parse through the arguments and extract those relevant to paths */
-       for ( i = 0; i < *argc; i++ )
-       {
-               /* check for null */
-               if ( argv[ i ] == NULL ) {
-                       continue;
-               }
-
-               /* -fs_basepath */
-               if ( strcmp( argv[ i ], "-fs_basepath" ) == 0 ) {
-                       if ( ++i >= *argc ) {
-                               Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
-                       }
-                       argv[ i - 1 ] = NULL;
-                       AddBasePath( argv[ i ] );
-                       argv[ i ] = NULL;
-               }
-
-       }
-
-       /* remove processed arguments */
-       for ( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
-       {
-               for ( j; j < *argc && argv[ j ] == NULL; j++ ) ;
-               argv[ i ] = argv[ j ];
-               if ( argv[ i ] != NULL ) {
-                       k++;
-               }
-       }
-       *argc = k;
-
-       /* add standard game path */
-       AddGamePath( gamePath );
-
-       /* if there is no base path set, figure it out */
-       if ( numBasePaths == 0 ) {
-               /* this is another crappy replacement for SetQdirFromPath() */
-               len2 = strlen( game_magic );
-               for ( i = 0; i < *argc && numBasePaths == 0; i++ )
-               {
-                       /* extract the arg */
-                       strcpy( temp, argv[ i ] );
-                       CleanPath( temp );
-                       len = strlen( temp );
-                       Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game_magic, temp, i );
-
-                       /* this is slow, but only done once */
-                       for ( j = 0; j < ( len - len2 ); j++ )
-                       {
-                               /* check for the game's magic word */
-                               if ( Q_strncasecmp( &temp[ j ], game_magic, len2 ) == 0 ) {
-                                       /* now find the next slash and nuke everything after it */
-                                       while ( temp[ ++j ] != '/' && temp[ j ] != '\0' ) ;
-                                       temp[ j ] = '\0';
-
-                                       /* add this as a base path */
-                                       AddBasePath( temp );
-                                       break;
-                               }
-                       }
-               }
-
-               /* add install path */
-               if ( numBasePaths == 0 ) {
-                       AddBasePath( installPath );
-               }
-
-               /* check again */
-               if ( numBasePaths == 0 ) {
-                       Error( "Failed to find a valid base path." );
-               }
-       }
-
-       /* this only affects unix */
-       AddHomeBasePath( homeBasePath );
-
-       /* initialize vfs paths */
-       if ( numBasePaths > MAX_BASE_PATHS ) {
-               numBasePaths = MAX_BASE_PATHS;
-       }
-       if ( numGamePaths > MAX_GAME_PATHS ) {
-               numGamePaths = MAX_GAME_PATHS;
-       }
-
-       /* walk the list of game paths */
-       //for( j = 0; j < numGamePaths; j++ )
-       //{
-       /* walk the list of base paths */
-       //      for( i = 0; i < numBasePaths; i++ )
-       //      {
-       /* create a full path and initialize it */
-       //              sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
-       //              vfsInitDirectory( temp );
-       //      }
-       //}
-
-       /* done */
-       Sys_Printf( "\n" );
-}
diff --git a/tools/quake2/qdata_heretic2/common/polylib.c b/tools/quake2/qdata_heretic2/common/polylib.c
deleted file mode 100644 (file)
index af5df49..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#include "cmdlib.h"
-#include "inout.h"
-#include "mathlib.h"
-#include "polylib.h"
-
-
-extern int numthreads;
-
-// counters are only bumped when running single threaded,
-// because they are an awefull coherence problem
-int c_active_windings;
-int c_peak_windings;
-int c_winding_allocs;
-int c_winding_points;
-
-#define BOGUS_RANGE 8192
-
-void pw( winding_t *w ){
-       int i;
-       for ( i = 0 ; i < w->numpoints ; i++ )
-               printf( "(%5.1f, %5.1f, %5.1f)\n",w->p[i][0], w->p[i][1],w->p[i][2] );
-}
-
-
-/*
-   =============
-   AllocWinding
-   =============
- */
-winding_t   *AllocWinding( int points ){
-       winding_t   *w;
-       int s;
-
-       if ( numthreads == 1 ) {
-               c_winding_allocs++;
-               c_winding_points += points;
-               c_active_windings++;
-               if ( c_active_windings > c_peak_windings ) {
-                       c_peak_windings = c_active_windings;
-               }
-       }
-       s = sizeof( vec_t ) * 3 * points + sizeof( int );
-       w = malloc( s );
-       if ( !w ) {
-               Error( "AllocWinding MALLOC failed!  Could not allocate %s bytes.", s );
-       }
-       memset( w, 0, s );
-       return w;
-}
-
-void FreeWinding( winding_t *w ){
-       if ( *(unsigned *)w == 0xdeaddead ) {
-               Error( "FreeWinding: freed a freed winding" );
-       }
-       *(unsigned *)w = 0xdeaddead;
-
-       if ( numthreads == 1 ) {
-               c_active_windings--;
-       }
-       free( w );
-}
-
-/*
-   ============
-   RemoveColinearPoints
-   ============
- */
-int c_removed;
-
-void    RemoveColinearPoints( winding_t *w ){
-       int i, j, k;
-       vec3_t v1, v2;
-       int nump;
-       vec3_t p[MAX_POINTS_ON_WINDING];
-
-       nump = 0;
-       for ( i = 0 ; i < w->numpoints ; i++ )
-       {
-               j = ( i + 1 ) % w->numpoints;
-               k = ( i + w->numpoints - 1 ) % w->numpoints;
-               VectorSubtract( w->p[j], w->p[i], v1 );
-               VectorSubtract( w->p[i], w->p[k], v2 );
-               VectorNormalize( v1,v1 );
-               VectorNormalize( v2,v2 );
-               if ( DotProduct( v1, v2 ) < 0.999 ) {
-                       VectorCopy( w->p[i], p[nump] );
-                       nump++;
-               }
-       }
-
-       if ( nump == w->numpoints ) {
-               return;
-       }
-
-       if ( numthreads == 1 ) {
-               c_removed += w->numpoints - nump;
-       }
-       w->numpoints = nump;
-       memcpy( w->p, p, nump * sizeof( p[0] ) );
-}
-
-/*
-   ============
-   WindingPlane
-   ============
- */
-void WindingPlane( winding_t *w, vec3_t normal, vec_t *dist ){
-       vec3_t v1, v2;
-
-       VectorSubtract( w->p[1], w->p[0], v1 );
-       VectorSubtract( w->p[2], w->p[0], v2 );
-       CrossProduct( v2, v1, normal );
-       VectorNormalize( normal, normal );
-       *dist = DotProduct( w->p[0], normal );
-
-}
-
-/*
-   =============
-   WindingArea
-   =============
- */
-vec_t   WindingArea( winding_t *w ){
-       int i;
-       vec3_t d1, d2, cross;
-       vec_t total;
-
-       total = 0;
-       for ( i = 2 ; i < w->numpoints ; i++ )
-       {
-               VectorSubtract( w->p[i - 1], w->p[0], d1 );
-               VectorSubtract( w->p[i], w->p[0], d2 );
-               CrossProduct( d1, d2, cross );
-               total += 0.5 * VectorLength( cross );
-       }
-       return total;
-}
-
-void    WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs ){
-       vec_t v;
-       int i,j;
-
-       mins[0] = mins[1] = mins[2] = 99999;
-       maxs[0] = maxs[1] = maxs[2] = -99999;
-
-       for ( i = 0 ; i < w->numpoints ; i++ )
-       {
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       v = w->p[i][j];
-                       if ( v < mins[j] ) {
-                               mins[j] = v;
-                       }
-                       if ( v > maxs[j] ) {
-                               maxs[j] = v;
-                       }
-               }
-       }
-}
-
-/*
-   =============
-   WindingCenter
-   =============
- */
-void    WindingCenter( winding_t *w, vec3_t center ){
-       int i;
-       float scale;
-
-       VectorCopy( vec3_origin, center );
-       for ( i = 0 ; i < w->numpoints ; i++ )
-               VectorAdd( w->p[i], center, center );
-
-       scale = 1.0 / w->numpoints;
-       VectorScale( center, scale, center );
-}
-
-/*
-   =================
-   BaseWindingForPlane
-   =================
- */
-winding_t *BaseWindingForPlane( vec3_t normal, vec_t dist ){
-       int i, x;
-       vec_t max, v;
-       vec3_t org, vright, vup;
-       winding_t   *w;
-
-// find the major axis
-
-       max = -BOGUS_RANGE;
-       x = -1;
-       for ( i = 0 ; i < 3; i++ )
-       {
-               v = fabs( normal[i] );
-               if ( v > max ) {
-                       x = i;
-                       max = v;
-               }
-       }
-       if ( x == -1 ) {
-               Error( "BaseWindingForPlane: no axis found" );
-       }
-
-       VectorCopy( vec3_origin, vup );
-       switch ( x )
-       {
-       case 0:
-       case 1:
-               vup[2] = 1;
-               break;
-       case 2:
-               vup[0] = 1;
-               break;
-       }
-
-       v = DotProduct( vup, normal );
-       VectorMA( vup, -v, normal, vup );
-       VectorNormalize( vup, vup );
-
-       VectorScale( normal, dist, org );
-
-       CrossProduct( vup, normal, vright );
-
-       VectorScale( vup, 8192, vup );
-       VectorScale( vright, 8192, vright );
-
-// project a really big        axis aligned box onto the plane
-       w = AllocWinding( 4 );
-
-       VectorSubtract( org, vright, w->p[0] );
-       VectorAdd( w->p[0], vup, w->p[0] );
-
-       VectorAdd( org, vright, w->p[1] );
-       VectorAdd( w->p[1], vup, w->p[1] );
-
-       VectorAdd( org, vright, w->p[2] );
-       VectorSubtract( w->p[2], vup, w->p[2] );
-
-       VectorSubtract( org, vright, w->p[3] );
-       VectorSubtract( w->p[3], vup, w->p[3] );
-
-       w->numpoints = 4;
-
-       return w;
-}
-
-/*
-   ==================
-   CopyWinding
-   ==================
- */
-winding_t   *CopyWinding( winding_t *w ){
-       int size;
-       winding_t   *c;
-
-       c = AllocWinding( w->numpoints );
-       size = (int)( (winding_t *)0 )->p[w->numpoints];
-       memcpy( c, w, size );
-       return c;
-}
-
-/*
-   ==================
-   ReverseWinding
-   ==================
- */
-winding_t   *ReverseWinding( winding_t *w ){
-       int i;
-       winding_t   *c;
-
-       c = AllocWinding( w->numpoints );
-       for ( i = 0 ; i < w->numpoints ; i++ )
-       {
-               VectorCopy( w->p[w->numpoints - 1 - i], c->p[i] );
-       }
-       c->numpoints = w->numpoints;
-       return c;
-}
-
-
-/*
-   =============
-   ClipWindingEpsilon
-   =============
- */
-void    ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist,
-                                                       vec_t epsilon, winding_t **front, winding_t **back ){
-       vec_t dists[MAX_POINTS_ON_WINDING + 4];
-       int sides[MAX_POINTS_ON_WINDING + 4];
-       int counts[3];
-       vec_t dot;          // VC 4.2 optimizer bug if not static
-       int i, j;
-       vec_t   *p1, *p2;
-       vec3_t mid;
-       winding_t   *f, *b;
-       int maxpts;
-
-       if ( in->numpoints >= MAX_POINTS_ON_WINDING - 4 ) {
-               Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
-       }
-
-       counts[0] = counts[1] = counts[2] = 0;
-
-// determine sides for each point
-       for ( i = 0 ; i < in->numpoints ; i++ )
-       {
-               dot = DotProduct( in->p[i], normal );
-               dot -= dist;
-               dists[i] = dot;
-               if ( dot > epsilon ) {
-                       sides[i] = SIDE_FRONT;
-               }
-               else if ( dot < -epsilon ) {
-                       sides[i] = SIDE_BACK;
-               }
-               else
-               {
-                       sides[i] = SIDE_ON;
-               }
-               counts[sides[i]]++;
-       }
-       sides[i] = sides[0];
-       dists[i] = dists[0];
-
-       *front = *back = NULL;
-
-       if ( !counts[0] ) {
-               *back = CopyWinding( in );
-               return;
-       }
-       if ( !counts[1] ) {
-               *front = CopyWinding( in );
-               return;
-       }
-
-       maxpts = in->numpoints + 4;   // cant use counts[0]+2 because
-                                     // of fp grouping errors
-
-       *front = f = AllocWinding( maxpts );
-       *back = b = AllocWinding( maxpts );
-
-       for ( i = 0 ; i < in->numpoints ; i++ )
-       {
-               p1 = in->p[i];
-
-               if ( sides[i] == SIDE_ON ) {
-                       VectorCopy( p1, f->p[f->numpoints] );
-                       f->numpoints++;
-                       VectorCopy( p1, b->p[b->numpoints] );
-                       b->numpoints++;
-                       continue;
-               }
-
-               if ( sides[i] == SIDE_FRONT ) {
-                       VectorCopy( p1, f->p[f->numpoints] );
-                       f->numpoints++;
-               }
-               if ( sides[i] == SIDE_BACK ) {
-                       VectorCopy( p1, b->p[b->numpoints] );
-                       b->numpoints++;
-               }
-
-               if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
-                       continue;
-               }
-
-               // generate a split point
-               p2 = in->p[( i + 1 ) % in->numpoints];
-
-               dot = dists[i] / ( dists[i] - dists[i + 1] );
-               for ( j = 0 ; j < 3 ; j++ )
-               {   // avoid round off error when possible
-                       if ( normal[j] == 1 ) {
-                               mid[j] = dist;
-                       }
-                       else if ( normal[j] == -1 ) {
-                               mid[j] = -dist;
-                       }
-                       else{
-                               mid[j] = p1[j] + dot * ( p2[j] - p1[j] );
-                       }
-               }
-
-               VectorCopy( mid, f->p[f->numpoints] );
-               f->numpoints++;
-               VectorCopy( mid, b->p[b->numpoints] );
-               b->numpoints++;
-       }
-
-       if ( f->numpoints > maxpts || b->numpoints > maxpts ) {
-               Error( "ClipWinding: points exceeded estimate" );
-       }
-       if ( f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING ) {
-               Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
-       }
-}
-
-
-/*
-   =============
-   ChopWindingInPlace
-   =============
- */
-void ChopWindingInPlace( winding_t **inout, vec3_t normal, vec_t dist, vec_t epsilon ){
-       winding_t   *in;
-       vec_t dists[MAX_POINTS_ON_WINDING + 4];
-       int sides[MAX_POINTS_ON_WINDING + 4];
-       int counts[3];
-       vec_t dot;          // VC 4.2 optimizer bug if not static
-       int i, j;
-       vec_t   *p1, *p2;
-       vec3_t mid;
-       winding_t   *f;
-       int maxpts;
-
-       in = *inout;
-       counts[0] = counts[1] = counts[2] = 0;
-
-       if ( !in ) {
-               printf( "Warning: NULL passed to ChopWindingInPlace\n" );
-               return;
-       }
-       if ( in->numpoints >= MAX_POINTS_ON_WINDING - 4 ) {
-               Error( "ChopWinding: MAX_POINTS_ON_WINDING" );
-       }
-
-// determine sides for each point
-       for ( i = 0 ; i < in->numpoints ; i++ )
-       {
-               dot = DotProduct( in->p[i], normal );
-               dot -= dist;
-               dists[i] = dot;
-               if ( dot > epsilon ) {
-                       sides[i] = SIDE_FRONT;
-               }
-               else if ( dot < -epsilon ) {
-                       sides[i] = SIDE_BACK;
-               }
-               else
-               {
-                       sides[i] = SIDE_ON;
-               }
-               counts[sides[i]]++;
-       }
-       sides[i] = sides[0];
-       dists[i] = dists[0];
-
-       if ( !counts[0] ) {
-               FreeWinding( in );
-               *inout = NULL;
-               return;
-       }
-       if ( !counts[1] ) {
-               return;     // inout stays the same
-
-       }
-       maxpts = in->numpoints + 4;   // cant use counts[0]+2 because
-                                     // of fp grouping errors
-
-       f = AllocWinding( maxpts );
-
-       for ( i = 0 ; i < in->numpoints ; i++ )
-       {
-               p1 = in->p[i];
-
-               if ( sides[i] == SIDE_ON ) {
-                       VectorCopy( p1, f->p[f->numpoints] );
-                       f->numpoints++;
-                       continue;
-               }
-
-               if ( sides[i] == SIDE_FRONT ) {
-                       VectorCopy( p1, f->p[f->numpoints] );
-                       f->numpoints++;
-               }
-
-               if ( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) {
-                       continue;
-               }
-
-               // generate a split point
-               p2 = in->p[( i + 1 ) % in->numpoints];
-
-               dot = dists[i] / ( dists[i] - dists[i + 1] );
-               for ( j = 0 ; j < 3 ; j++ )
-               {   // avoid round off error when possible
-                       if ( normal[j] == 1 ) {
-                               mid[j] = dist;
-                       }
-                       else if ( normal[j] == -1 ) {
-                               mid[j] = -dist;
-                       }
-                       else{
-                               mid[j] = p1[j] + dot * ( p2[j] - p1[j] );
-                       }
-               }
-
-               VectorCopy( mid, f->p[f->numpoints] );
-               f->numpoints++;
-       }
-
-       if ( f->numpoints > maxpts ) {
-               Error( "ClipWinding: points exceeded estimate" );
-       }
-       if ( f->numpoints > MAX_POINTS_ON_WINDING ) {
-               Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
-       }
-
-       FreeWinding( in );
-       *inout = f;
-}
-
-
-/*
-   =================
-   ChopWinding
-
-   Returns the fragment of in that is on the front side
-   of the cliping plane.  The original is freed.
-   =================
- */
-winding_t   *ChopWinding( winding_t *in, vec3_t normal, vec_t dist ){
-       winding_t   *f, *b;
-
-       ClipWindingEpsilon( in, normal, dist, ON_EPSILON, &f, &b );
-       FreeWinding( in );
-       if ( b ) {
-               FreeWinding( b );
-       }
-       return f;
-}
-
-
-/*
-   =================
-   CheckWinding
-
-   =================
- */
-void CheckWinding( winding_t *w ){
-       int i, j;
-       vec_t   *p1, *p2;
-       vec_t d, edgedist;
-       vec3_t dir, edgenormal, facenormal;
-       vec_t area;
-       vec_t facedist;
-
-       if ( w->numpoints < 3 ) {
-               Error( "CheckWinding: %i points",w->numpoints );
-       }
-
-       area = WindingArea( w );
-       if ( area < 1 ) {
-               Error( "CheckWinding: %f area", area );
-       }
-
-       WindingPlane( w, facenormal, &facedist );
-
-       for ( i = 0 ; i < w->numpoints ; i++ )
-       {
-               p1 = w->p[i];
-
-               for ( j = 0 ; j < 3 ; j++ )
-                       if ( p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE ) {
-                               Error( "CheckFace: BUGUS_RANGE: %f",p1[j] );
-                       }
-
-               j = i + 1 == w->numpoints ? 0 : i + 1;
-
-               // check the point is on the face plane
-               d = DotProduct( p1, facenormal ) - facedist;
-               if ( d < -ON_EPSILON || d > ON_EPSILON ) {
-                       Error( "CheckWinding: point off plane" );
-               }
-
-               // check the edge isnt degenerate
-               p2 = w->p[j];
-               VectorSubtract( p2, p1, dir );
-
-               if ( VectorLength( dir ) < ON_EPSILON ) {
-                       Error( "CheckWinding: degenerate edge" );
-               }
-
-               CrossProduct( facenormal, dir, edgenormal );
-               VectorNormalize( edgenormal, edgenormal );
-               edgedist = DotProduct( p1, edgenormal );
-               edgedist += ON_EPSILON;
-
-               // all other points must be on front side
-               for ( j = 0 ; j < w->numpoints ; j++ )
-               {
-                       if ( j == i ) {
-                               continue;
-                       }
-                       d = DotProduct( w->p[j], edgenormal );
-                       if ( d > edgedist ) {
-                               Error( "CheckWinding: non-convex" );
-                       }
-               }
-       }
-}
-
-
-/*
-   ============
-   WindingOnPlaneSide
-   ============
- */
-int     WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist ){
-       qboolean front, back;
-       int i;
-       vec_t d;
-
-       front = false;
-       back = false;
-       for ( i = 0 ; i < w->numpoints ; i++ )
-       {
-               d = DotProduct( w->p[i], normal ) - dist;
-               if ( d < -ON_EPSILON ) {
-                       if ( front ) {
-                               return SIDE_CROSS;
-                       }
-                       back = true;
-                       continue;
-               }
-               if ( d > ON_EPSILON ) {
-                       if ( back ) {
-                               return SIDE_CROSS;
-                       }
-                       front = true;
-                       continue;
-               }
-       }
-
-       if ( back ) {
-               return SIDE_BACK;
-       }
-       if ( front ) {
-               return SIDE_FRONT;
-       }
-       return SIDE_ON;
-}
diff --git a/tools/quake2/qdata_heretic2/common/polylib.h b/tools/quake2/qdata_heretic2/common/polylib.h
deleted file mode 100644 (file)
index 00b7b39..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-typedef struct
-{
-       int numpoints;
-       vec3_t p[4];        // variable sized
-} winding_t;
-
-#define MAX_POINTS_ON_WINDING   64
-
-// you can define on_epsilon in the makefile as tighter
-#ifndef ON_EPSILON
-#define ON_EPSILON  0.1
-#endif
-
-winding_t   *AllocWinding( int points );
-vec_t   WindingArea( winding_t *w );
-void    WindingCenter( winding_t *w, vec3_t center );
-void    ClipWindingEpsilon( winding_t *in, vec3_t normal, vec_t dist,
-                                                       vec_t epsilon, winding_t **front, winding_t **back );
-winding_t   *ChopWinding( winding_t *in, vec3_t normal, vec_t dist );
-winding_t   *CopyWinding( winding_t *w );
-winding_t   *ReverseWinding( winding_t *w );
-winding_t   *BaseWindingForPlane( vec3_t normal, vec_t dist );
-void    CheckWinding( winding_t *w );
-void    WindingPlane( winding_t *w, vec3_t normal, vec_t *dist );
-void    RemoveColinearPoints( winding_t *w );
-int     WindingOnPlaneSide( winding_t *w, vec3_t normal, vec_t dist );
-void    FreeWinding( winding_t *w );
-void    WindingBounds( winding_t *w, vec3_t mins, vec3_t maxs );
-
-void    ChopWindingInPlace( winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon );
-// frees the original if clipped
-
-void pw( winding_t *w );
diff --git a/tools/quake2/qdata_heretic2/common/qfiles.c b/tools/quake2/qdata_heretic2/common/qfiles.c
deleted file mode 100644 (file)
index 53452f3..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "qfiles.h"
-#include "scriplib.h"
-//#include <windows.h>
-
-materialtype_t defaultmaterialtypes[] =
-{
-       {"gravel",  MATERIAL_GRAVEL},
-       {"metal",   MATERIAL_METAL},
-       {"stone",   MATERIAL_STONE},
-       {"wood",    MATERIAL_WOOD},
-       {NULL,      0}
-};
-
-materialtype_t  *materialtypes;
-
-void QFile_ReadMaterialTypes( char* filename ){
-       int i;
-       FILE    *f;
-
-       f = fopen( filename, "rb" );
-       if ( !f ) {
-               materialtypes = defaultmaterialtypes;
-               return;
-       }
-       fclose( f );
-
-       free( materialtypes );
-       materialtypes = (materialtype_t*)malloc( 256 * sizeof( materialtype_t ) );
-
-       LoadScriptFile( filename );
-       i = 0;
-
-       while ( i < 255 )
-       {
-               GetScriptToken( true );
-               if ( endofscript ) {
-                       break;
-               }
-               if ( strcmp( token, "material" ) != 0 ) {
-                       while ( ScriptTokenAvailable() )
-                       {
-                               GetScriptToken( false );
-                       }
-               }
-               else
-               {
-                       GetScriptToken( false );
-                       materialtypes[i].name = (char*)malloc( strlen( token ) + 1 );
-                       strcpy( materialtypes[i].name, token );
-                       GetScriptToken( false );
-                       materialtypes[i].value = atoi( token );
-               }
-               i++;
-       }
-       materialtypes[i].name = NULL;
-       materialtypes[i].value = 0;
-}
diff --git a/tools/quake2/qdata_heretic2/common/qfiles.h b/tools/quake2/qdata_heretic2/common/qfiles.h
deleted file mode 100644 (file)
index bee4b4f..0000000
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _QFILES_H
-#define _QFILES_H
-
-#include "q_typedef.h"
-
-//
-// qfiles.h: quake file formats
-// This file must be identical in the quake and utils directories
-//
-
-/*
-   ========================================================================
-
-   The .pak files are just a linear collapse of a directory tree
-
-   ========================================================================
- */
-
-#define IDPAKHEADER     ( ( 'K' << 24 ) + ( 'C' << 16 ) + ( 'A' << 8 ) + 'P' )
-
-typedef struct
-{
-       char name[56];
-       int filepos, filelen;
-} dpackfile_t;
-
-typedef struct
-{
-       int ident;          // == IDPAKHEADER
-       int dirofs;
-       int dirlen;
-} dpackheader_t;
-
-#define MAX_FILES_IN_PACK   4096
-
-
-/*
-   ========================================================================
-
-   PCX files are used for as many images as possible
-
-   ========================================================================
- */
-
-typedef struct
-{
-       char manufacturer;
-       char version;
-       char encoding;
-       char bits_per_pixel;
-       unsigned short xmin,ymin,xmax,ymax;
-       unsigned short hres,vres;
-       unsigned char palette[48];
-       char reserved;
-       char color_planes;
-       unsigned short bytes_per_line;
-       unsigned short palette_type;
-       char filler[58];
-       unsigned char data;             // unbounded
-} pcx_t;
-
-
-/*
-   ========================================================================
-
-   .MD2 compressed triangle model file format
-
-   ========================================================================
- */
-#define IDJOINTEDALIASHEADER    ( ( '2' << 24 ) + ( 'J' << 16 ) + ( 'D' << 8 ) + 'I' )
-
-/*
-   ========================================================================
-
-   .MD2 triangle model file format
-
-   ========================================================================
- */
-
-#define IDALIASHEADER       ( ( '2' << 24 ) + ( 'P' << 16 ) + ( 'D' << 8 ) + 'I' )
-#define ALIAS_VERSION   8
-
-#define MAX_TRIANGLES   2048
-#define MAX_VERTS       2048
-#define MAX_FRAMES      512
-#define MAX_MD2SKINS    64
-#define MAX_SKINNAME    64
-
-typedef struct
-{
-       short s;
-       short t;
-} dstvert_t;
-
-typedef struct
-{
-       short index_xyz[3];
-       short index_st[3];
-} dtriangle_t;
-
-typedef struct
-{
-       byte v[3];              // scaled byte to fit in frame mins/maxs
-       byte lightnormalindex;
-} dtrivertx_t;
-
-#define DTRIVERTX_V0   0
-#define DTRIVERTX_V1   1
-#define DTRIVERTX_V2   2
-#define DTRIVERTX_LNI  3
-#define DTRIVERTX_SIZE 4
-
-typedef struct
-{
-       float scale[3];         // multiply byte verts by this
-       float translate[3];         // then add this
-       char name[16];          // frame name from grabbing
-       dtrivertx_t verts[1];   // variable sized
-} daliasframe_t;
-
-
-// the glcmd format:
-// a positive integer starts a tristrip command, followed by that many
-// vertex structures.
-// a negative integer starts a trifan command, followed by -x vertexes
-// a zero indicates the end of the command list.
-// a vertex consists of a floating point s, a floating point t,
-// and an integer vertex index.
-
-
-typedef struct
-{
-       int ident;
-       int version;
-
-       int skinwidth;
-       int skinheight;
-       int framesize;              // byte size of each frame
-
-       int num_skins;
-       int num_xyz;
-       int num_st;                 // greater than num_xyz for seams
-       int num_tris;
-       int num_glcmds;             // dwords in strip/fan command list
-       int num_frames;
-
-       int ofs_skins;              // each skin is a MAX_SKINNAME string
-       int ofs_st;                 // byte offset from start for stverts
-       int ofs_tris;               // offset for dtriangles
-       int ofs_frames;             // offset for first frame
-       int ofs_glcmds;
-       int ofs_end;                // end of file
-
-} dmdl_t;
-
-/*
-   ========================================================================
-
-   .BK file format
-
-   ========================================================================
- */
-
-#define IDBOOKHEADER    ( ( 'K' << 24 ) + ( 'O' << 16 ) + ( 'O' << 8 ) + 'B' )
-#define BOOK_VERSION    2
-
-typedef struct bookframe_s
-{
-       int x;
-       int y;
-       int w;
-       int h;
-       char name[MAX_SKINNAME];            // name of gfx file
-} bookframe_t;
-
-typedef struct bookheader_s
-{
-       unsigned int ident;
-       unsigned int version;
-       int num_segments;
-       int total_w;
-       int total_h;
-} bookheader_t;
-
-typedef struct book_s
-{
-       bookheader_t bheader;
-       bookframe_t bframes[MAX_MD2SKINS];
-} book_t;
-
-/*
-   ========================================================================
-
-   .SP2 sprite file format
-
-   ========================================================================
- */
-
-#define IDSPRITEHEADER  ( ( '2' << 24 ) + ( 'S' << 16 ) + ( 'D' << 8 ) + 'I' )
-// little-endian "IDS2"
-#define SPRITE_VERSION  2
-
-typedef struct
-{
-       int width, height;
-       int origin_x, origin_y;         // raster coordinates inside pic
-       char name[MAX_SKINNAME];        // name of pcx file
-} dsprframe_t;
-
-typedef struct {
-       int ident;
-       int version;
-       int numframes;
-       dsprframe_t frames[1];          // variable sized
-} dsprite_t;
-
-/*
-   ==============================================================================
-
-   .M8 texture file format
-
-   ==============================================================================
- */
-
-typedef struct palette_s
-{
-       union
-       {
-               struct
-               {
-                       byte r,g,b;
-               };
-       };
-} palette_t;
-
-#define MIP_VERSION     2
-#define PAL_SIZE        256
-#define MIPLEVELS       16
-
-typedef struct miptex_s
-{
-       int version;
-       char name[32];
-       unsigned width[MIPLEVELS], height[MIPLEVELS];
-       unsigned offsets[MIPLEVELS];        // four mip maps stored
-       char animname[32];                  // next frame in animation chain
-       palette_t palette[PAL_SIZE];
-       int flags;
-       int contents;
-       int value;
-} miptex_t;
-
-
-#define MIP32_VERSION   4
-
-#define MIP32_NOMIP_FLAG2           0x00000001
-#define MIP32_DETAILER_FLAG2        0x00000002
-
-typedef struct miptex32_s
-{
-       int version;
-       char name[128];
-       char altname[128];                  // texture substitution
-       char animname[128];                 // next frame in animation chain
-       char damagename[128];               // image that should be shown when damaged
-       unsigned width[MIPLEVELS], height[MIPLEVELS];
-       unsigned offsets[MIPLEVELS];
-       int flags;
-       int contents;
-       int value;
-       float scale_x, scale_y;
-       int mip_scale;
-
-       // detail texturing info
-       char dt_name[128];              // detailed texture name
-       float dt_scale_x, dt_scale_y;
-       float dt_u, dt_v;
-       float dt_alpha;
-       int dt_src_blend_mode, dt_dst_blend_mode;
-
-       int flags2;
-       int unused[19];                     // future expansion to maintain compatibility with h2
-} miptex32_t;
-
-
-
-/*
-   ==============================================================================
-
-   .BSP file format
-
-   ==============================================================================
- */
-
-#define IDBSPHEADER ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'B' << 8 ) + 'I' )
-// little-endian "IBSP"
-
-#define BSPVERSION  38
-
-
-// upper design bounds
-// leaffaces, leafbrushes, planes, and verts are still bounded by
-// 16 bit short limits
-#define MAX_MAP_MODELS      1024
-#define MAX_MAP_BRUSHES     8192
-#define MAX_MAP_ENTITIES    2048
-#define MAX_MAP_ENTSTRING   0x40000
-#define MAX_MAP_TEXINFO     8192
-
-#define MAX_MAP_AREAS       256
-#define MAX_MAP_AREAPORTALS 1024
-#define MAX_MAP_PLANES      65536
-#define MAX_MAP_NODES       65536
-#define MAX_MAP_BRUSHSIDES  65536
-#define MAX_MAP_LEAFS       65536
-#define MAX_MAP_VERTS       65536
-#define MAX_MAP_FACES       65536
-#define MAX_MAP_LEAFFACES   65536
-#define MAX_MAP_LEAFBRUSHES 65536
-#define MAX_MAP_PORTALS     65536
-#define MAX_MAP_EDGES       128000
-#define MAX_MAP_SURFEDGES   256000
-#define MAX_MAP_LIGHTING    0x200000
-#define MAX_MAP_VISIBILITY  0x180000
-
-// key / value pair sizes
-
-#define MAX_KEY     32
-#define MAX_VALUE   1024
-
-//=============================================================================
-
-typedef struct
-{
-       int fileofs, filelen;
-} lump_t;
-
-#define LUMP_ENTITIES       0
-#define LUMP_PLANES         1
-#define LUMP_VERTEXES       2
-#define LUMP_VISIBILITY     3
-#define LUMP_NODES          4
-#define LUMP_TEXINFO        5
-#define LUMP_FACES          6
-#define LUMP_LIGHTING       7
-#define LUMP_LEAFS          8
-#define LUMP_LEAFFACES      9
-#define LUMP_LEAFBRUSHES    10
-#define LUMP_EDGES          11
-#define LUMP_SURFEDGES      12
-#define LUMP_MODELS         13
-#define LUMP_BRUSHES        14
-#define LUMP_BRUSHSIDES     15
-#define LUMP_POP            16
-#define LUMP_AREAS          17
-#define LUMP_AREAPORTALS    18
-#define HEADER_LUMPS        19
-
-typedef struct
-{
-       int ident;
-       int version;
-       lump_t lumps[HEADER_LUMPS];
-} dheader_t;
-
-typedef struct
-{
-       float mins[3], maxs[3];
-       float origin[3];            // for sounds or lights
-       int headnode;
-       int firstface, numfaces;            // submodels just draw faces
-                                           // without walking the bsp tree
-} dmodel_t;
-
-
-typedef struct
-{
-       float point[3];
-} dvertex_t;
-
-
-// 0-2 are axial planes
-#define PLANE_X         0
-#define PLANE_Y         1
-#define PLANE_Z         2
-
-// 3-5 are non-axial planes snapped to the nearest
-#define PLANE_ANYX      3
-#define PLANE_ANYY      4
-#define PLANE_ANYZ      5
-
-// planes (x&~1) and (x&~1)+1 are allways opposites
-
-typedef struct
-{
-       float normal[3];
-       float dist;
-       int type;           // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
-} dplane_t;
-
-
-// contents flags are seperate bits
-// a given brush can contribute multiple content bits
-// multiple brushes can be in a single leaf
-
-// these definitions also need to be in q_shared.h!
-
-// lower bits are stronger, and will eat weaker brushes completely
-#define CONTENTS_SOLID          0x00000001      // an eye is never valid in a solid
-#define CONTENTS_WINDOW         0x00000002      // translucent, but not watery
-#define CONTENTS_PUSHPULL       0x00000004
-#define CONTENTS_LAVA           0x00000008
-#define CONTENTS_SLIME          0x00000010
-#define CONTENTS_WATER          0x00000020
-#define CONTENTS_MIST           0x00000040      // 64
-#define LAST_VISIBLE_CONTENTS   64              // this one worries me a bit JKH
-
-// remaining contents are non-visible, and don't eat brushes
-
-#define CONTENTS_AREAPORTAL     0x00008000
-
-#define CONTENTS_PLAYERCLIP     0x00010000
-#define CONTENTS_MONSTERCLIP    0x00020000
-
-// currents can be added to any other contents, and may be mixed
-#define CONTENTS_CURRENT_0      0x00040000
-#define CONTENTS_CURRENT_90     0x00080000
-#define CONTENTS_CURRENT_180    0x00100000
-#define CONTENTS_CURRENT_270    0x00200000
-#define CONTENTS_CURRENT_UP     0x00400000
-#define CONTENTS_CURRENT_DOWN   0x00800000
-
-#define CONTENTS_ORIGIN         0x01000000  // removed before bsping an entity
-
-#define CONTENTS_MONSTER        0x02000000  // should never be on a brush, only in game
-#define CONTENTS_DEADMONSTER    0x04000000
-#define CONTENTS_DETAIL         0x08000000  // brushes to be added after vis leafs
-#define CONTENTS_TRANSLUCENT    0x10000000  // auto set if any surface has trans
-#define CONTENTS_LADDER         0x20000000
-
-
-
-#define SURF_LIGHT              0x00000001      // value will hold the light strength
-
-#define SURF_SLICK              0x00000002      // effects game physics
-
-#define SURF_SKY                0x00000004      // don't draw, but add to skybox
-#define SURF_WARP               0x00000008      // turbulent water warp
-#define SURF_TRANS33            0x00000010
-#define SURF_TRANS66            0x00000020
-#define SURF_FLOWING            0x00000040  // scroll towards angle
-#define SURF_NODRAW             0x00000080  // don't bother referencing the texture
-
-#define SURF_HINT               0x00000100  // make a primary bsp splitter
-#define SURF_SKIP               0x00000200  // completely ignore, allowing non-closed brushes
-#define SURF_TALL_WALL          0x00000400  // face doesn't get broken up as normal
-
-#define SURF_ALPHA_TEXTURE      0x00000800  // texture has alpha in it, and should show through in bsp process
-#define SURF_ANIMSPEED          0x00001000      // value will hold the anim speed in fps
-
-#define SURF_UNDULATE           0x00002000  // rock surface up and down...
-#define SURF_SKYREFLECT         0x00004000  // liquid will somewhat reflect the sky - not quite finished....
-
-#define SURF_TYPE_GRAVEL        0x00000000
-#define SURF_TYPE_METAL         0x01000000
-#define SURF_TYPE_STONE         0x02000000
-#define SURF_TYPE_WOOD          0x03000000
-#define SURF_MATERIAL           0xFF000000
-
-
-
-typedef struct
-{
-       int planenum;
-       int children[2];            // negative numbers are -(leafs+1), not nodes
-       short mins[3];              // for frustom culling
-       short maxs[3];
-       unsigned short firstface;
-       unsigned short numfaces;    // counting both sides
-} dnode_t;
-
-
-typedef struct texinfo_s
-{
-       float vecs[2][4];           // [s/t][xyz offset]
-       int flags;                  // miptex flags + overrides
-       int value;                  // light emission, etc
-       char texture[32];           // texture name (textures/*.wal)
-       int nexttexinfo;            // for animations, -1 = end of chain
-} texinfo_t;
-
-
-// note that edge 0 is never used, because negative edge nums are used for
-// counterclockwise use of the edge in a face
-typedef struct
-{
-       unsigned short v[2];        // vertex numbers
-} dedge_t;
-
-#define MAXLIGHTMAPS    4
-typedef struct
-{
-       unsigned short planenum;
-       short side;
-
-       int firstedge;              // we must support > 64k edges
-       short numedges;
-       short texinfo;
-
-// lighting info
-       union {
-               byte styles[MAXLIGHTMAPS];
-               paletteRGBA_t lighting;
-       };
-       int lightofs;               // start of [numstyles*surfsize] samples
-} dface_t;
-
-typedef struct
-{
-       int contents;                       // OR of all brushes (not needed?)
-
-       short cluster;
-       short area;
-
-       short mins[3];                      // for frustum culling
-       short maxs[3];
-
-       unsigned short firstleafface;
-       unsigned short numleaffaces;
-
-       unsigned short firstleafbrush;
-       unsigned short numleafbrushes;
-} dleaf_t;
-
-typedef struct
-{
-       unsigned short planenum;        // facing out of the leaf
-       short texinfo;
-} dbrushside_t;
-
-typedef struct
-{
-       int firstside;
-       int numsides;
-       int contents;
-} dbrush_t;
-
-#define ANGLE_UP    -1
-#define ANGLE_DOWN  -2
-
-
-// the visibility lump consists of a header with a count, then
-// byte offsets for the PVS and PHS of each cluster, then the raw
-// compressed bit vectors
-#define DVIS_PVS    0
-#define DVIS_PHS    1
-typedef struct
-{
-       int numclusters;
-       int bitofs[8][2];           // bitofs[numclusters][2]
-} dvis_t;
-
-// each area has a list of portals that lead into other areas
-// when portals are closed, other areas may not be visible or
-// hearable even if the vis info says that it should be
-typedef struct
-{
-       int portalnum;
-       int otherarea;
-} dareaportal_t;
-
-
-typedef struct
-{
-       int numareaportals;
-       int firstareaportal;
-} darea_t;
-
-typedef struct
-{
-       char    *name;
-       int value;
-} materialtype_t;
-
-enum
-{
-       MATERIAL_GRAVEL,
-       MATERIAL_METAL,
-       MATERIAL_STONE,
-       MATERIAL_WOOD,
-};
-
-materialtype_t  *materialtypes;
-
-void QFile_ReadMaterialTypes( char* filename );
-
-
-#endif //_QFILES_H
diff --git a/tools/quake2/qdata_heretic2/common/scriplib.c b/tools/quake2/qdata_heretic2/common/scriplib.c
deleted file mode 100644 (file)
index af5e571..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// scriplib.c
-
-#include "cmdlib.h"
-#include "inout.h"
-#include "scriplib.h"
-
-/*
-   =============================================================================
-
-                        PARSING STUFF
-
-   =============================================================================
- */
-
-typedef struct
-{
-       char filename[1024];
-       char    *buffer,*script_p,*end_p;
-       int line;
-} script_t;
-
-#define MAX_INCLUDES    8
-script_t scriptstack[MAX_INCLUDES];
-script_t    *script;
-int scriptline;
-
-char token[MAXTOKEN];
-qboolean endofscript;
-qboolean tokenready;                     // only true if UnGetScriptToken was just called
-
-/*
-   ==============
-   AddScriptToStack
-   ==============
- */
-void AddScriptToStack( char *filename ){
-       int size;
-
-       script++;
-       if ( script == &scriptstack[MAX_INCLUDES] ) {
-               Error( "script file exceeded MAX_INCLUDES" );
-       }
-       strcpy( script->filename, ExpandPath( filename ) );
-
-       size = LoadFile( script->filename, (void **)&script->buffer );
-
-       printf( "entering %s\n", script->filename );
-
-       script->line = 1;
-
-       script->script_p = script->buffer;
-       script->end_p = script->buffer + size;
-}
-
-
-/*
-   ==============
-   LoadScriptFile
-   ==============
- */
-void LoadScriptFile( char *filename ){
-       script = scriptstack;
-       AddScriptToStack( filename );
-
-       endofscript = false;
-       tokenready = false;
-}
-
-
-/*
-   ==============
-   ParseFromMemory
-   ==============
- */
-void ParseFromMemory( char *buffer, int size ){
-       script = scriptstack;
-       script++;
-       if ( script == &scriptstack[MAX_INCLUDES] ) {
-               Error( "script file exceeded MAX_INCLUDES" );
-       }
-       strcpy( script->filename, "memory buffer" );
-
-       script->buffer = buffer;
-       script->line = 1;
-       script->script_p = script->buffer;
-       script->end_p = script->buffer + size;
-
-       endofscript = false;
-       tokenready = false;
-}
-
-
-/*
-   ==============
-   UnGetScriptToken
-
-   Signals that the current token was not used, and should be reported
-   for the next GetScriptToken.  Note that
-
-   GetScriptToken (true);
-   UnGetScriptToken ();
-   GetScriptToken (false);
-
-   could cross a line boundary.
-   ==============
- */
-void UnGetScriptToken( void ){
-       tokenready = true;
-}
-
-
-qboolean EndOfScript( qboolean crossline ){
-       if ( !crossline ) {
-               Error( "Line %i is incomplete\n",scriptline );
-       }
-
-       if ( !strcmp( script->filename, "memory buffer" ) ) {
-               endofscript = true;
-               return false;
-       }
-
-       free( script->buffer );
-       if ( script == scriptstack + 1 ) {
-               endofscript = true;
-               return false;
-       }
-       script--;
-       scriptline = script->line;
-       printf( "returning to %s\n", script->filename );
-       return GetScriptToken( crossline );
-}
-
-/*
-   ==============
-   GetScriptToken
-   ==============
- */
-qboolean GetScriptToken( qboolean crossline ){
-       char    *token_p;
-
-       if ( tokenready ) {                       // is a token allready waiting?
-               tokenready = false;
-               return true;
-       }
-
-       if ( script->script_p >= script->end_p ) {
-               return EndOfScript( crossline );
-       }
-
-//
-// skip space
-//
-skipspace:
-       while ( *script->script_p <= 32 )
-       {
-               if ( script->script_p >= script->end_p ) {
-                       return EndOfScript( crossline );
-               }
-               if ( *script->script_p++ == '\n' ) {
-                       if ( !crossline ) {
-                               Error( "Line %i is incomplete\n",scriptline );
-                       }
-                       scriptline = script->line++;
-               }
-       }
-
-       if ( script->script_p >= script->end_p ) {
-               return EndOfScript( crossline );
-       }
-
-       // ; # // comments
-       if ( *script->script_p == ';' || *script->script_p == '#'
-                || ( script->script_p[0] == '/' && script->script_p[1] == '/' ) ) {
-               if ( !crossline ) {
-                       Error( "Line %i is incomplete\n",scriptline );
-               }
-               while ( *script->script_p++ != '\n' )
-                       if ( script->script_p >= script->end_p ) {
-                               return EndOfScript( crossline );
-                       }
-               goto skipspace;
-       }
-
-       // /* */ comments
-       if ( script->script_p[0] == '/' && script->script_p[1] == '*' ) {
-               if ( !crossline ) {
-                       Error( "Line %i is incomplete\n",scriptline );
-               }
-               script->script_p += 2;
-               while ( script->script_p[0] != '*' && script->script_p[1] != '/' )
-               {
-                       script->script_p++;
-                       if ( script->script_p >= script->end_p ) {
-                               return EndOfScript( crossline );
-                       }
-               }
-               script->script_p += 2;
-               goto skipspace;
-       }
-
-//
-// copy token
-//
-       token_p = token;
-
-       if ( *script->script_p == '"' ) {
-               // quoted token
-               script->script_p++;
-               while ( *script->script_p != '"' )
-               {
-                       *token_p++ = *script->script_p++;
-                       if ( script->script_p == script->end_p ) {
-                               break;
-                       }
-                       if ( token_p == &token[MAXTOKEN] ) {
-                               Error( "Token too large on line %i\n",scriptline );
-                       }
-               }
-               script->script_p++;
-       }
-       else{   // regular token
-               while ( *script->script_p > 32 && *script->script_p != ';' )
-               {
-                       *token_p++ = *script->script_p++;
-                       if ( script->script_p == script->end_p ) {
-                               break;
-                       }
-                       if ( token_p == &token[MAXTOKEN] ) {
-                               Error( "Token too large on line %i\n",scriptline );
-                       }
-               }
-       }
-
-       *token_p = 0;
-
-       if ( !strcmp( token, "$include" ) ) {
-               GetScriptToken( false );
-               AddScriptToStack( token );
-               return GetScriptToken( crossline );
-       }
-
-       return true;
-}
-
-
-/*
-   ==============
-   ScriptTokenAvailable
-
-   Returns true if there is another token on the line
-   ==============
- */
-qboolean ScriptTokenAvailable( void ){
-       char    *search_p;
-
-       search_p = script->script_p;
-
-       if ( search_p >= script->end_p ) {
-               return false;
-       }
-
-       while ( *search_p <= 32 )
-       {
-               if ( *search_p == '\n' ) {
-                       return false;
-               }
-               search_p++;
-               if ( search_p == script->end_p ) {
-                       return false;
-               }
-
-       }
-
-       if ( *search_p == ';' ) {
-               return false;
-       }
-
-       return true;
-}
diff --git a/tools/quake2/qdata_heretic2/common/scriplib.h b/tools/quake2/qdata_heretic2/common/scriplib.h
deleted file mode 100644 (file)
index 8c441c8..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// scriplib.h
-
-#ifndef __CMDLIB__
-#include "cmdlib.h"
-#endif
-
-#define MAXTOKEN    1024
-
-extern char token[MAXTOKEN];
-extern char    *scriptbuffer,*script_p,*scriptend_p;
-extern int grabbed;
-extern int scriptline;
-extern qboolean endofscript;
-
-
-void LoadScriptFile( char *filename );
-void ParseFromMemory( char *buffer, int size );
-
-qboolean GetScriptToken( qboolean crossline );
-void UnGetScriptToken( void );
-qboolean ScriptTokenAvailable( void );
diff --git a/tools/quake2/qdata_heretic2/common/threads.c b/tools/quake2/qdata_heretic2/common/threads.c
deleted file mode 100644 (file)
index 239226b..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "globaldefs.h"
-
-#if !GDEF_OS_WINDOWS
-// The below define is necessary to use
-// pthreads extensions like pthread_mutexattr_settype
-#define _GNU_SOURCE
-#endif // !GDEF_OS_WINDOWS
-
-#include "cmdlib.h"
-#include "mathlib.h"
-#include "inout.h"
-#include "her2_threads.h"
-
-#define MAX_THREADS 64
-
-int dispatch;
-int workcount;
-int oldf;
-qboolean pacifier;
-
-qboolean threaded;
-
-/*
-   =============
-   GetThreadWork
-
-   =============
- */
-int GetThreadWork( void ){
-       int r;
-       int f;
-
-       ThreadLock();
-
-       if ( dispatch == workcount ) {
-               ThreadUnlock();
-               return -1;
-       }
-
-       f = 10 * dispatch / workcount;
-       if ( f != oldf ) {
-               oldf = f;
-               if ( pacifier ) {
-                       Sys_Printf( "%i...", f );
-                       fflush( stdout );   /* ydnar */
-               }
-       }
-
-       r = dispatch;
-       dispatch++;
-       ThreadUnlock();
-
-       return r;
-}
-
-
-void ( *workfunction )( int );
-
-void ThreadWorkerFunction( int threadnum ){
-       int work;
-
-       while ( 1 )
-       {
-               work = GetThreadWork();
-               if ( work == -1 ) {
-                       break;
-               }
-               //Sys_Printf ("thread %i, work %i\n", threadnum, work);
-               workfunction( work );
-       }
-}
-
-void RunThreadsOnIndividual( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
-       if ( numthreads == -1 ) {
-               ThreadSetDefault();
-       }
-       workfunction = func;
-       RunThreadsOn( workcnt, showpacifier, ThreadWorkerFunction );
-}
-
-
-#if GDEF_OS_WINDOWS
-
-/*
-   ===================================================================
-
-   WIN32
-
-   ===================================================================
- */
-
-#include <windows.h>
-
-// Setting default Threads to 1
-int numthreads = 1;
-CRITICAL_SECTION crit;
-static int enter;
-
-void ThreadSetDefault( void ){
-       SYSTEM_INFO info;
-
-       if ( numthreads == -1 ) { // not set manually
-               GetSystemInfo( &info );
-               numthreads = info.dwNumberOfProcessors;
-               if ( numthreads < 1 || numthreads > 32 ) {
-                       numthreads = 1;
-               }
-       }
-
-       Sys_Printf( "%i threads\n", numthreads );
-}
-
-
-void ThreadLock( void ){
-       if ( !threaded ) {
-               return;
-       }
-       EnterCriticalSection( &crit );
-       if ( enter ) {
-               Error( "Recursive ThreadLock\n" );
-       }
-       enter = 1;
-}
-
-void ThreadUnlock( void ){
-       if ( !threaded ) {
-               return;
-       }
-       if ( !enter ) {
-               Error( "ThreadUnlock without lock\n" );
-       }
-       enter = 0;
-       LeaveCriticalSection( &crit );
-}
-
-/*
-   =============
-   RunThreadsOn
-   =============
- */
-void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
-       int threadid[MAX_THREADS];
-       HANDLE threadhandle[MAX_THREADS];
-       int i;
-       int start, end;
-
-       start = I_FloatTime();
-       dispatch = 0;
-       workcount = workcnt;
-       oldf = -1;
-       pacifier = showpacifier;
-       threaded = true;
-
-       //
-       // run threads in parallel
-       //
-       InitializeCriticalSection( &crit );
-
-       if ( numthreads == 1 ) { // use same thread
-               func( 0 );
-       }
-       else
-       {
-               for ( i = 0 ; i < numthreads ; i++ )
-               {
-                       threadhandle[i] = CreateThread(
-                               NULL,   // LPSECURITY_ATTRIBUTES lpsa,
-                           //0,                // DWORD cbStack,
-
-                           /* ydnar: cranking stack size to eliminate radiosity crash with 1MB stack on win32 */
-                               ( 4096 * 1024 ),
-
-                               (LPTHREAD_START_ROUTINE)func,   // LPTHREAD_START_ROUTINE lpStartAddr,
-                               (LPVOID)i,  // LPVOID lpvThreadParm,
-                               0,          //   DWORD fdwCreate,
-                               &threadid[i] );
-               }
-
-               for ( i = 0 ; i < numthreads ; i++ )
-                       WaitForSingleObject( threadhandle[i], INFINITE );
-       }
-       DeleteCriticalSection( &crit );
-
-       threaded = false;
-       end = I_FloatTime();
-       if ( pacifier ) {
-               Sys_Printf( " (%i)\n", end - start );
-       }
-}
-
-
-#elif GDEF_OS_OSF1
-
-/*
-   ===================================================================
-
-   OSF1
-
-   ===================================================================
- */
-
-int numthreads = 4;
-
-void ThreadSetDefault( void ){
-       if ( numthreads == -1 ) { // not set manually
-               numthreads = 4;
-       }
-}
-
-
-#include <pthread.h>
-
-pthread_mutex_t *my_mutex;
-
-void ThreadLock( void ){
-       if ( my_mutex ) {
-               pthread_mutex_lock( my_mutex );
-       }
-}
-
-void ThreadUnlock( void ){
-       if ( my_mutex ) {
-               pthread_mutex_unlock( my_mutex );
-       }
-}
-
-
-/*
-   =============
-   RunThreadsOn
-   =============
- */
-void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
-       int i;
-       pthread_t work_threads[MAX_THREADS];
-       pthread_addr_t status;
-       pthread_attr_t attrib;
-       pthread_mutexattr_t mattrib;
-       int start, end;
-
-       start = I_FloatTime();
-       dispatch = 0;
-       workcount = workcnt;
-       oldf = -1;
-       pacifier = showpacifier;
-       threaded = true;
-
-       if ( pacifier ) {
-               setbuf( stdout, NULL );
-       }
-
-       if ( !my_mutex ) {
-               my_mutex = safe_malloc( sizeof( *my_mutex ) );
-               if ( pthread_mutexattr_create( &mattrib ) == -1 ) {
-                       Error( "pthread_mutex_attr_create failed" );
-               }
-               if ( pthread_mutexattr_setkind_np( &mattrib, MUTEX_FAST_NP ) == -1 ) {
-                       Error( "pthread_mutexattr_setkind_np failed" );
-               }
-               if ( pthread_mutex_init( my_mutex, mattrib ) == -1 ) {
-                       Error( "pthread_mutex_init failed" );
-               }
-       }
-
-       if ( pthread_attr_create( &attrib ) == -1 ) {
-               Error( "pthread_attr_create failed" );
-       }
-       if ( pthread_attr_setstacksize( &attrib, 0x100000 ) == -1 ) {
-               Error( "pthread_attr_setstacksize failed" );
-       }
-
-       for ( i = 0 ; i < numthreads ; i++ )
-       {
-               if ( pthread_create( &work_threads[i], attrib
-                                                        , (pthread_startroutine_t)func, (pthread_addr_t)i ) == -1 ) {
-                       Error( "pthread_create failed" );
-               }
-       }
-
-       for ( i = 0 ; i < numthreads ; i++ )
-       {
-               if ( pthread_join( work_threads[i], &status ) == -1 ) {
-                       Error( "pthread_join failed" );
-               }
-       }
-
-       threaded = false;
-
-       end = I_FloatTime();
-       if ( pacifier ) {
-               Sys_Printf( " (%i)\n", end - start );
-       }
-}
-
-
-#elif GDEF_OS_IRIX
-
-/*
-   ===================================================================
-
-   IRIX
-
-   ===================================================================
- */
-
-#include <task.h>
-#include <abi_mutex.h>
-#include <sys/types.h>
-#include <sys/prctl.h>
-
-int numthreads = -1;
-abilock_t lck;
-
-void ThreadSetDefault( void ){
-       if ( numthreads == -1 ) {
-               numthreads = prctl( PR_MAXPPROCS );
-       }
-       Sys_Printf( "%i threads\n", numthreads );
-       usconfig( CONF_INITUSERS, numthreads );
-}
-
-
-void ThreadLock( void ){
-       spin_lock( &lck );
-}
-
-void ThreadUnlock( void ){
-       release_lock( &lck );
-}
-
-
-/*
-   =============
-   RunThreadsOn
-   =============
- */
-void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
-       int i;
-       int pid[MAX_THREADS];
-       int start, end;
-
-       start = I_FloatTime();
-       dispatch = 0;
-       workcount = workcnt;
-       oldf = -1;
-       pacifier = showpacifier;
-       threaded = true;
-
-       if ( pacifier ) {
-               setbuf( stdout, NULL );
-       }
-
-       init_lock( &lck );
-
-       for ( i = 0 ; i < numthreads - 1 ; i++ )
-       {
-               pid[i] = sprocsp( ( void ( * )( void *, size_t ) )func, PR_SALL, (void *)i
-                                                 , NULL, 0x200000 ); // 2 meg stacks
-               if ( pid[i] == -1 ) {
-                       perror( "sproc" );
-                       Error( "sproc failed" );
-               }
-       }
-
-       func( i );
-
-       for ( i = 0 ; i < numthreads - 1 ; i++ )
-               wait( NULL );
-
-       threaded = false;
-
-       end = I_FloatTime();
-       if ( pacifier ) {
-               Sys_Printf( " (%i)\n", end - start );
-       }
-}
-
-
-#elif GDEF_OS_LINUX || GDEF_OS_BSD || GDEF_OS_MACOS
-
-/*
-   =======================================================================
-
-   Linux pthreads
-
-   =======================================================================
- */
-
-// Setting default Threads to 1
-int numthreads = 1;
-
-void ThreadSetDefault( void ){
-       if ( numthreads == -1 ) { // not set manually
-               /* default to one thread, only multi-thread when specifically told to */
-               numthreads = 1;
-       }
-       if ( numthreads > 1 ) {
-               Sys_Printf( "threads: %d\n", numthreads );
-       }
-}
-
-#include <pthread.h>
-
-typedef struct pt_mutex_s
-{
-       pthread_t       *owner;
-       pthread_mutex_t a_mutex;
-       pthread_cond_t cond;
-       unsigned int lock;
-} pt_mutex_t;
-
-pt_mutex_t global_lock;
-
-void ThreadLock( void ){
-       pt_mutex_t *pt_mutex = &global_lock;
-
-       if ( !threaded ) {
-               return;
-       }
-
-       pthread_mutex_lock( &pt_mutex->a_mutex );
-       if ( pthread_equal( pthread_self(), (pthread_t)&pt_mutex->owner ) ) {
-               pt_mutex->lock++;
-       }
-       else
-       {
-               if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
-                       pt_mutex->owner = (pthread_t *)pthread_self();
-                       pt_mutex->lock  = 1;
-               }
-               else
-               {
-                       while ( 1 )
-                       {
-                               pthread_cond_wait( &pt_mutex->cond, &pt_mutex->a_mutex );
-                               if ( ( !pt_mutex->owner ) && ( pt_mutex->lock == 0 ) ) {
-                                       pt_mutex->owner = (pthread_t *)pthread_self();
-                                       pt_mutex->lock  = 1;
-                                       break;
-                               }
-                       }
-               }
-       }
-       pthread_mutex_unlock( &pt_mutex->a_mutex );
-}
-
-void ThreadUnlock( void ){
-       pt_mutex_t *pt_mutex = &global_lock;
-
-       if ( !threaded ) {
-               return;
-       }
-
-       pthread_mutex_lock( &pt_mutex->a_mutex );
-       pt_mutex->lock--;
-
-       if ( pt_mutex->lock == 0 ) {
-               pt_mutex->owner = NULL;
-               pthread_cond_signal( &pt_mutex->cond );
-       }
-
-       pthread_mutex_unlock( &pt_mutex->a_mutex );
-}
-
-void recursive_mutex_init( pthread_mutexattr_t attribs ){
-       pt_mutex_t *pt_mutex = &global_lock;
-
-       pt_mutex->owner = NULL;
-       if ( pthread_mutex_init( &pt_mutex->a_mutex, &attribs ) != 0 ) {
-               Error( "pthread_mutex_init failed\n" );
-       }
-       if ( pthread_cond_init( &pt_mutex->cond, NULL ) != 0 ) {
-               Error( "pthread_cond_init failed\n" );
-       }
-
-       pt_mutex->lock = 0;
-}
-
-/*
-   =============
-   RunThreadsOn
-   =============
- */
-void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
-       pthread_mutexattr_t mattrib;
-       pthread_t work_threads[MAX_THREADS];
-
-       int start, end;
-       int i = 0, status = 0;
-
-       start     = I_FloatTime();
-       pacifier  = showpacifier;
-
-       dispatch  = 0;
-       oldf      = -1;
-       workcount = workcnt;
-
-       if ( numthreads == 1 ) {
-               func( 0 );
-       }
-       else
-       {
-               threaded  = true;
-
-               if ( pacifier ) {
-                       setbuf( stdout, NULL );
-               }
-
-               if ( pthread_mutexattr_init( &mattrib ) != 0 ) {
-                       Error( "pthread_mutexattr_init failed" );
-               }
-               if ( pthread_mutexattr_settype( &mattrib, PTHREAD_MUTEX_ERRORCHECK ) != 0 ) {
-                       Error( "pthread_mutexattr_settype failed" );
-               }
-               recursive_mutex_init( mattrib );
-
-               for ( i = 0 ; i < numthreads ; i++ )
-               {
-                       /* Default pthread attributes: joinable & non-realtime scheduling */
-                       if ( pthread_create( &work_threads[i], NULL, (void*)func, (void*)i ) != 0 ) {
-                               Error( "pthread_create failed" );
-                       }
-               }
-               for ( i = 0 ; i < numthreads ; i++ )
-               {
-                       if ( pthread_join( work_threads[i], (void **)&status ) != 0 ) {
-                               Error( "pthread_join failed" );
-                       }
-               }
-               pthread_mutexattr_destroy( &mattrib );
-               threaded = false;
-       }
-
-       end = I_FloatTime();
-       if ( pacifier ) {
-               Sys_Printf( " (%i)\n", end - start );
-       }
-}
-
-
-#else // UNKNOWN OS
-
-/*
-   =======================================================================
-
-   SINGLE THREAD
-
-   =======================================================================
- */
-
-int numthreads = 1;
-
-void ThreadSetDefault( void ){
-       numthreads = 1;
-}
-
-void ThreadLock( void ){
-}
-
-void ThreadUnlock( void ){
-}
-
-/*
-   =============
-   RunThreadsOn
-   =============
- */
-void RunThreadsOn( int workcnt, qboolean showpacifier, void ( *func )( int ) ){
-       int i;
-       int start, end;
-
-       dispatch = 0;
-       workcount = workcnt;
-       oldf = -1;
-       pacifier = showpacifier;
-       start = I_FloatTime();
-       func( 0 );
-
-       end = I_FloatTime();
-       if ( pacifier ) {
-               Sys_Printf( " (%i)\n", end - start );
-       }
-}
-
-#endif // UNKNOWN OS
diff --git a/tools/quake2/qdata_heretic2/common/token.c b/tools/quake2/qdata_heretic2/common/token.c
deleted file mode 100644 (file)
index 632cfe4..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-//**************************************************************************
-//**
-//** token.c
-//**
-//**************************************************************************
-
-// HEADER FILES ------------------------------------------------------------
-
-#include "token.h"
-#include "inout.h"
-
-// MACROS ------------------------------------------------------------------
-
-// TYPES -------------------------------------------------------------------
-
-typedef enum
-{
-       CHR_EOF,
-       CHR_LETTER,
-       CHR_NUMBER,
-       CHR_QUOTE,
-       CHR_SPECIAL
-} chr_t;
-
-// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
-
-// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
-
-// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
-
-static void ProcessLetterToken( void );
-static void ProcessNumberToken( void );
-static void ProcessQuoteToken( void );
-static void ProcessSpecialToken( void );
-static qboolean CheckForKeyword( void );
-static void NextChr( void );
-
-// EXTERNAL DATA DECLARATIONS ----------------------------------------------
-
-// PUBLIC DATA DEFINITIONS -------------------------------------------------
-
-tokenType_t tk_Token;
-int tk_Line;
-int tk_IntNumber;
-float tk_FloatNumber;
-char *tk_String;
-char tk_SourceName[MAX_FILE_NAME_LENGTH];
-
-// PRIVATE DATA DEFINITIONS ------------------------------------------------
-
-static char Chr;
-static char *FileStart;
-static char *FilePtr;
-static char *FileEnd;
-static qboolean SourceOpen;
-static char ASCIIToChrCode[256];
-static char TokenStringBuffer[MAX_QUOTED_LENGTH];
-static qboolean IncLineNumber;
-static char TempBuffer[2048];
-
-static struct
-{
-       char *name;
-       tokenType_t token;
-} Keywords[] =
-{
-       "model",            TK_MODEL,
-       "mesh",             TK_MESH,
-       "vertices",         TK_VERTICES,
-       "edges",            TK_EDGES,
-       "position",         TK_POSITION,
-       "polygons",         TK_POLYGONS,
-       "nodes",            TK_NODES,
-       "rotation",         TK_ROTATION,
-       "scaling",          TK_SCALING,
-       "translation",      TK_TRANSLATION,
-       "vertex",           TK_VERTEX,
-       "HRCH",             TK_HRCH,
-       "Softimage",        TK_SOFTIMAGE,
-       "material",         TK_MATERIAL,
-       "spline",           TK_SPLINE,
-
-       "Named",            TK_C_NAMED,
-       "object",           TK_OBJECT,
-       "Tri",              TK_C_TRI,
-       "Vertices",         TK_C_VERTICES,
-       "Faces",            TK_C_FACES,
-       "Vertex",           TK_C_VERTEX,
-       "list",             TK_LIST,
-       "Face",             TK_C_FACE,
-
-       "Hexen",            TK_C_HEXEN,
-       "Triangles",        TK_C_TRIANGLES,
-       "Version",          TK_C_VERSION,
-       "faces",            TK_FACES,
-       "face",             TK_FACE,
-       "origin",           TK_ORIGIN,
-
-       "DK_clusters",      TK_CLUSTERS,
-       "DK_cluster_ncvs",  TK_NUM_CLUSTER_VERTICES,
-       "name",             TK_NAME,
-       "DK_cluster_name",  TK_CLUSTER_NAME,
-       "DK_cluster_state", TK_CLUSTER_STATE,
-
-       "actor_data",       TK_ACTOR_DATA,
-       "uvTexture",        TK_UVTEXTURE,
-
-       NULL,               -1
-};
-
-static char *TokenNames[] =
-{
-       "<nothing>",
-       "<unknown_char>",
-       "<EOF>",
-       "<identifier>",
-       "<string>",
-       "<int_number>",
-       "<float_number>",
-       "(",
-       ")",
-       "{",
-       "}",
-       "[",
-       "]",
-       ":",
-       "mesh",
-       "model",
-       "nodes",
-       "rotation",
-       "scaling",
-       "translation",
-       "polygons",
-       "position",
-       "vertex",
-       "vertices",
-       "HRCH",
-       "Softimage"
-};
-
-// CODE --------------------------------------------------------------------
-
-//==========================================================================
-//
-// TK_Init
-//
-//==========================================================================
-
-void TK_Init( void ){
-       int i;
-
-       for ( i = 0; i < 256; i++ )
-       {
-               ASCIIToChrCode[i] = CHR_SPECIAL;
-       }
-       for ( i = '0'; i <= '9'; i++ )
-       {
-               ASCIIToChrCode[i] = CHR_NUMBER;
-       }
-       for ( i = 'A'; i <= 'Z'; i++ )
-       {
-               ASCIIToChrCode[i] = CHR_LETTER;
-       }
-       for ( i = 'a'; i <= 'z'; i++ )
-       {
-               ASCIIToChrCode[i] = CHR_LETTER;
-       }
-       ASCIIToChrCode[ASCII_QUOTE] = CHR_QUOTE;
-       ASCIIToChrCode[ASCII_UNDERSCORE] = CHR_LETTER;
-       ASCIIToChrCode[EOF_CHARACTER] = CHR_EOF;
-       tk_String = TokenStringBuffer;
-       IncLineNumber = FALSE;
-       SourceOpen = FALSE;
-}
-
-//==========================================================================
-//
-// TK_OpenSource
-//
-//==========================================================================
-
-void TK_OpenSource( char *fileName ){
-       int size;
-
-       TK_CloseSource();
-       size = LoadFile( fileName, (void **)&FileStart );
-       strcpy( tk_SourceName, fileName );
-       SourceOpen = TRUE;
-       FileEnd = FileStart + size;
-       FilePtr = FileStart;
-       tk_Line = 1;
-       tk_Token = TK_NONE;
-       NextChr();
-}
-
-//==========================================================================
-//
-// TK_CloseSource
-//
-//==========================================================================
-
-void TK_CloseSource( void ){
-       if ( SourceOpen ) {
-               free( FileStart );
-               SourceOpen = FALSE;
-       }
-}
-
-//==========================================================================
-//
-// TK_Fetch
-//
-//==========================================================================
-
-tokenType_t TK_Fetch( void ){
-       while ( Chr == ASCII_SPACE )
-       {
-               NextChr();
-       }
-       if ( Chr == '-' ) {
-               ProcessNumberToken();
-       }
-       else{switch ( ASCIIToChrCode[(byte)Chr] )
-                {
-                case CHR_EOF:
-                        tk_Token = TK_EOF;
-                        break;
-                case CHR_LETTER:
-                        ProcessLetterToken();
-                        break;
-                case CHR_NUMBER:
-                        ProcessNumberToken();
-                        break;
-                case CHR_QUOTE:
-                        ProcessQuoteToken();
-                        break;
-                default:
-                        ProcessSpecialToken();
-                        break;
-                }}
-       return tk_Token;
-}
-
-//==========================================================================
-//
-// TK_Require
-//
-//==========================================================================
-
-void TK_Require( tokenType_t tokType ){
-       if ( tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER ) {
-               tk_FloatNumber = (float)tk_IntNumber;
-               tk_Token = TK_FLOATNUMBER;
-               return;
-       }
-       if ( tk_Token != tokType ) {
-               Error( "File '%s', line %d:\nExpected '%s', found '%s'.\n",
-                          tk_SourceName, tk_Line, TokenNames[tokType],
-                          TokenNames[tk_Token] );
-       }
-}
-
-void TK_FetchRequire( tokenType_t tokType ){
-       TK_Fetch();
-       TK_Require( tokType );
-}
-
-tokenType_t TK_RequireFetch( tokenType_t tokType ){
-       TK_Require( tokType );
-       return TK_Fetch();
-}
-
-tokenType_t TK_FetchRequireFetch( tokenType_t tokType ){
-       TK_Fetch();
-       TK_Require( tokType );
-       return TK_Fetch();
-}
-
-tokenType_t TK_Beyond( tokenType_t tokType ){
-       while ( tk_Token != tokType )
-       {
-               if ( TK_Fetch() == TK_EOF ) {
-                       Error( "File '%s':\nCould not find token '%s'.\n",       // FIXME: TokenNames table not big enuff
-                                  tk_SourceName, TokenNames[tokType] );
-               }
-       }
-       return TK_Fetch();
-}
-
-void TK_BeyondRequire( tokenType_t bTok, tokenType_t rTok ){
-       TK_Beyond( bTok );
-       TK_Require( rTok );
-}
-
-tokenType_t TK_Search( tokenType_t tokType ){
-       while ( tk_Token != tokType )
-       {
-               if ( TK_Fetch() == TK_EOF ) {
-                       return TK_EOF;
-               }
-       }
-       return TK_Fetch();
-}
-
-tokenType_t TK_Get( tokenType_t tokType ){
-       while ( tk_Token != tokType )
-       {
-               if ( TK_Fetch() == TK_EOF ) {
-                       Error( "File '%s':\nCould not find token '%s'.\n",
-                                  tk_SourceName, TokenNames[tokType] );
-               }
-       }
-       return tk_Token;
-}
-
-//==========================================================================
-//
-// ProcessLetterToken
-//
-//==========================================================================
-
-static void ProcessLetterToken( void ){
-       int i;
-       char *text;
-
-       i = 0;
-       text = TokenStringBuffer;
-       while ( ASCIIToChrCode[(byte)Chr] == CHR_LETTER
-                       || ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
-       {
-               if ( ++i == MAX_IDENTIFIER_LENGTH ) {
-                       Error( "File '%s', line %d:\nIdentifier too long.\n",
-                                  tk_SourceName, tk_Line );
-               }
-               *text++ = Chr;
-               NextChr();
-       }
-       *text = 0;
-       if ( CheckForKeyword() == FALSE ) {
-               tk_Token = TK_IDENTIFIER;
-       }
-}
-
-//==========================================================================
-//
-// CheckForKeyword
-//
-//==========================================================================
-
-static qboolean CheckForKeyword( void ){
-       int i;
-
-       for ( i = 0; Keywords[i].name != NULL; i++ )
-       {
-               if ( strcmp( tk_String, Keywords[i].name ) == 0 ) {
-                       tk_Token = Keywords[i].token;
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-//==========================================================================
-//
-// ProcessNumberToken
-//
-//==========================================================================
-
-static void ProcessNumberToken( void ){
-       char *buffer;
-
-       buffer = TempBuffer;
-       *buffer++ = Chr;
-       NextChr();
-       while ( ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
-       {
-               *buffer++ = Chr;
-               NextChr();
-       }
-       if ( Chr == '.' ) { // Float
-               *buffer++ = Chr;
-               NextChr(); // Skip period
-               while ( ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
-               {
-                       *buffer++ = Chr;
-                       NextChr();
-               }
-               *buffer = 0;
-               tk_FloatNumber = (float)atof( TempBuffer );
-               tk_Token = TK_FLOATNUMBER;
-               return;
-       }
-
-       // Integer
-       *buffer = 0;
-       tk_IntNumber = atoi( TempBuffer );
-       tk_Token = TK_INTNUMBER;
-}
-
-//==========================================================================
-//
-// ProcessQuoteToken
-//
-//==========================================================================
-
-static void ProcessQuoteToken( void ){
-       int i;
-       char *text;
-
-       i = 0;
-       text = TokenStringBuffer;
-       NextChr();
-       while ( Chr != ASCII_QUOTE )
-       {
-               if ( Chr == EOF_CHARACTER ) {
-                       Error( "File '%s', line %d:\n<EOF> inside string.\n",
-                                  tk_SourceName, tk_Line );
-               }
-               if ( ++i > MAX_QUOTED_LENGTH - 1 ) {
-                       Error( "File '%s', line %d:\nString literal too long.\n",
-                                  tk_SourceName, tk_Line );
-               }
-               *text++ = Chr;
-               NextChr();
-       }
-       *text = 0;
-       NextChr();
-       tk_Token = TK_STRING;
-}
-
-//==========================================================================
-//
-// ProcessSpecialToken
-//
-//==========================================================================
-
-static void ProcessSpecialToken( void ){
-       char c;
-
-       c = Chr;
-       NextChr();
-       switch ( c )
-       {
-       case '(':
-               tk_Token = TK_LPAREN;
-               break;
-       case ')':
-               tk_Token = TK_RPAREN;
-               break;
-       case '{':
-               tk_Token = TK_LBRACE;
-               break;
-       case '}':
-               tk_Token = TK_RBRACE;
-               break;
-       case '[':
-               tk_Token = TK_LBRACKET;
-               break;
-       case ']':
-               tk_Token = TK_RBRACKET;
-               break;
-       case ':':
-               tk_Token = TK_COLON;
-               break;
-       default:
-               tk_Token = TK_UNKNOWNCHAR;
-               break;
-       }
-}
-
-//==========================================================================
-//
-// NextChr
-//
-//==========================================================================
-
-static void NextChr( void ){
-       if ( FilePtr >= FileEnd ) {
-               Chr = EOF_CHARACTER;
-               return;
-       }
-       if ( IncLineNumber == TRUE ) {
-               tk_Line++;
-               IncLineNumber = FALSE;
-       }
-       Chr = *FilePtr++;
-       if ( Chr < ASCII_SPACE ) {
-               if ( Chr == '\n' ) {
-                       IncLineNumber = TRUE;
-               }
-               Chr = ASCII_SPACE;
-       }
-}
diff --git a/tools/quake2/qdata_heretic2/common/token.h b/tools/quake2/qdata_heretic2/common/token.h
deleted file mode 100644 (file)
index 6dca1a1..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-//**************************************************************************
-//**
-//** token.h
-//**
-//**************************************************************************
-
-#ifndef __TOKEN_H__
-#define __TOKEN_H__
-
-#include "cmdlib.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-#ifndef YES
-#define YES 1
-#endif
-#ifndef NO
-#define NO 0
-#endif
-#define ASCII_SPACE 32
-#define ASCII_QUOTE 34
-#define ASCII_UNDERSCORE 95
-#define EOF_CHARACTER 127
-#define MAX_IDENTIFIER_LENGTH 64
-#define MAX_QUOTED_LENGTH 1024
-#define MAX_FILE_NAME_LENGTH 1024
-
-typedef enum
-{
-       TK_NONE,
-       TK_UNKNOWNCHAR,
-       TK_EOF,
-       TK_IDENTIFIER,          // VALUE: (char *) tk_String
-       TK_STRING,              // VALUE: (char *) tk_String
-       TK_INTNUMBER,           // VALUE: (int) tk_IntNumber
-       TK_FLOATNUMBER,         // VALUE: (float) tk_FloatNumber
-       TK_LPAREN,
-       TK_RPAREN,
-       TK_LBRACE,
-       TK_RBRACE,              // 10
-       TK_LBRACKET,
-       TK_RBRACKET,
-       TK_COLON,
-       TK_MESH,
-       TK_MODEL,               // 15
-       TK_NODES,
-       TK_ROTATION,
-       TK_SCALING,
-       TK_TRANSLATION,
-       TK_POLYGONS,            // 20
-       TK_POSITION,
-       TK_VERTEX,
-       TK_VERTICES,
-       TK_EDGES,
-       TK_HRCH,                // 25
-       TK_SOFTIMAGE,
-       TK_MATERIAL,
-       TK_SPLINE,              // 28
-
-       TK_C_NAMED,
-       TK_OBJECT,              // 30
-       TK_C_TRI,
-       TK_C_VERTICES,
-       TK_C_FACES,
-       TK_C_VERTEX,
-       TK_LIST,                // 35
-       TK_C_FACE,
-
-       TK_C_HEXEN,
-       TK_C_TRIANGLES,
-       TK_C_VERSION,
-       TK_FACES,               // 40
-       TK_FACE,
-       TK_ORIGIN,
-
-       TK_CLUSTERS,
-       TK_NUM_CLUSTER_VERTICES,
-       TK_NAME,                // 45
-       TK_CLUSTER_NAME,
-       TK_CLUSTER_STATE,
-
-       TK_ACTOR_DATA,
-       TK_UVTEXTURE,
-} tokenType_t;
-
-void TK_Init( void );
-void TK_OpenSource( char *fileName );
-void TK_CloseSource( void );
-tokenType_t TK_Fetch( void );
-void TK_Require( tokenType_t tokType );
-void TK_FetchRequire( tokenType_t tokType );
-tokenType_t TK_RequireFetch( tokenType_t tokType );
-tokenType_t TK_FetchRequireFetch( tokenType_t tokType );
-tokenType_t TK_Beyond( tokenType_t tokType );
-void TK_BeyondRequire( tokenType_t bTok, tokenType_t rTok );
-tokenType_t TK_Search( tokenType_t tokType );
-tokenType_t TK_Get( tokenType_t tokType );
-
-extern tokenType_t tk_Token;
-extern int tk_Line;
-extern int tk_IntNumber;
-extern float tk_FloatNumber;
-extern char *tk_String;
-extern char tk_SourceName[MAX_FILE_NAME_LENGTH];
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/common/trilib.c b/tools/quake2/qdata_heretic2/common/trilib.c
deleted file mode 100644 (file)
index 29acab6..0000000
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-//
-// trilib.c: library for loading triangles from an Alias triangle file
-//
-
-#include <stdio.h>
-#include "cmdlib.h"
-#include "inout.h"
-#include "mathlib.h"
-#include "trilib.h"
-#include "token.h"
-#include "l3dslib.h"
-#include "fmodel.h"
-#if 1
-#include "qd_skeletons.h"
-#endif
-
-// on disk representation of a face
-#define FLOAT_START 99999.0
-#define FLOAT_END   -FLOAT_START
-#define MAGIC       123322
-#ifndef M_PI
-  #define M_PI      3.14159265
-#endif
-
-float FixHTRRotateX = 0.0;
-float FixHTRRotateY = 0.0;
-float FixHTRRotateZ = 0.0;
-float FixHTRTranslateX = 0.0;
-float FixHTRTranslateY = 0.0;
-float FixHTRTranslateZ = 0.0;
-
-//#define NOISY 1
-
-typedef struct {
-       float v[3];
-} vector;
-
-typedef struct
-{
-       vector n;    /* normal */
-       vector p;    /* point */
-       vector c;    /* color */
-       float u;     /* u */
-       float v;     /* v */
-} aliaspoint_t;
-
-typedef struct {
-       aliaspoint_t pt[3];
-} tf_triangle;
-
-
-void ByteSwapTri( tf_triangle *tri ){
-       int i;
-
-       for ( i = 0 ; i < sizeof( tf_triangle ) / 4 ; i++ )
-       {
-               ( (int *)tri )[i] = BigLong( ( (int *)tri )[i] );
-       }
-}
-
-void LoadTRI( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **nodesList, int *num_mesh_nodes ){
-       FILE        *input;
-       float start;
-       char name[256], tex[256];
-       int i, count, magic;
-       tf_triangle tri;
-       triangle_t  *ptri;
-       int iLevel;
-       int exitpattern;
-       float t;
-
-       if ( nodesList ) {
-               *num_mesh_nodes = 0;
-               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
-       }
-
-       t = -FLOAT_START;
-       *( (unsigned char *)&exitpattern + 0 ) = *( (unsigned char *)&t + 3 );
-       *( (unsigned char *)&exitpattern + 1 ) = *( (unsigned char *)&t + 2 );
-       *( (unsigned char *)&exitpattern + 2 ) = *( (unsigned char *)&t + 1 );
-       *( (unsigned char *)&exitpattern + 3 ) = *( (unsigned char *)&t + 0 );
-
-       if ( ( input = fopen( filename, "rb" ) ) == 0 ) {
-               Error( "reader: could not open file '%s'", filename );
-       }
-
-       iLevel = 0;
-
-       fread( &magic, sizeof( int ), 1, input );
-       if ( BigLong( magic ) != MAGIC ) {
-               Error( "%s is not a Alias object separated triangle file, magic number is wrong.", filename );
-       }
-
-       ptri = malloc( MAXTRIANGLES * sizeof( triangle_t ) );
-
-       *pptri = ptri;
-
-       while ( feof( input ) == 0 ) {
-               if ( fread( &start,  sizeof( float ), 1, input ) < 1 ) {
-                       break;
-               }
-               *(int *)&start = BigLong( *(int *)&start );
-               if ( *(int *)&start != exitpattern ) {
-                       if ( start == FLOAT_START ) {
-                               /* Start of an object or group of objects. */
-                               i = -1;
-                               do {
-                                       /* There are probably better ways to read a string from */
-                                       /* a file, but this does allow you to do error checking */
-                                       /* (which I'm not doing) on a per character basis.      */
-                                       ++i;
-                                       fread( &( name[i] ), sizeof( char ), 1, input );
-                               } while ( name[i] != '\0' );
-
-//                             indent();
-//                             fprintf(stdout,"OBJECT START: %s\n",name);
-                               fread( &count, sizeof( int ), 1, input );
-                               count = BigLong( count );
-                               ++iLevel;
-                               if ( count != 0 ) {
-//                                     indent();
-//                                     fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);
-
-                                       i = -1;
-                                       do {
-                                               ++i;
-                                               fread( &( tex[i] ), sizeof( char ), 1, input );
-                                       } while ( tex[i] != '\0' );
-
-//                                     indent();
-//                                     fprintf(stdout,"  Object texture name: '%s'\n",tex);
-                               }
-
-                               /* Else (count == 0) this is the start of a group, and */
-                               /* no texture name is present. */
-                       }
-                       else if ( start == FLOAT_END ) {
-                               /* End of an object or group. Yes, the name should be */
-                               /* obvious from context, but it is in here just to be */
-                               /* safe and to provide a little extra information for */
-                               /* those who do not wish to write a recursive reader. */
-                               /* Mia culpa. */
-                               --iLevel;
-                               i = -1;
-                               do {
-                                       ++i;
-                                       fread( &( name[i] ), sizeof( char ), 1, input );
-                               } while ( name[i] != '\0' );
-
-//                             indent();
-//                             fprintf(stdout,"OBJECT END: %s\n",name);
-                               continue;
-                       }
-               }
-
-//
-// read the triangles
-//
-               for ( i = 0; i < count; ++i ) {
-                       int j;
-
-                       fread( &tri, sizeof( tf_triangle ), 1, input );
-                       ByteSwapTri( &tri );
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               int k;
-
-                               for ( k = 0 ; k < 3 ; k++ )
-                               {
-                                       ptri->verts[j][k] = tri.pt[j].p.v[k];
-                               }
-                       }
-
-                       ptri++;
-
-                       if ( ( ptri - *pptri ) >= MAXTRIANGLES ) {
-                               Error( "Error: too many triangles; increase MAXTRIANGLES\n" );
-                       }
-               }
-       }
-
-       *numtriangles = ptri - *pptri;
-
-       fclose( input );
-
-       DefaultNodesList( nodesList,num_mesh_nodes,numtriangles );
-}
-
-
-//==========================================================================
-//
-// LoadHRC
-//
-//==========================================================================
-
-float scaling[3];
-float rotation[3];
-float translation[3];
-static char     *hrc_name;
-
-struct
-{
-       float v[3];
-} vList[8192];
-
-void HandleHRCModel( triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,
-                                        int ActiveNode, int Depth, int numVerts ){
-       void ReadHRCClusterList( mesh_node_t *meshNode, int baseIndex );
-
-       int i, j;
-       int vertexCount;
-       int triCount;
-       triangle_t  *tList;
-       mesh_node_t *meshNode;
-       float x, y, z;
-       float x2, y2, z2;
-       float rx, ry, rz;
-       tokenType_t nextToken;
-       float orig_scaling[3];
-       float orig_rotation[3];
-       float orig_translation[3];
-       int start_tri;
-       int pos,bit;
-       int vertIndexBase;
-
-       // Update Node Info
-       if ( nodesList ) {
-               TK_BeyondRequire( TK_NAME, TK_STRING );
-
-               if ( Depth == 0 || tk_String[0] == '_' ) { // Root
-                       ActiveNode = *num_mesh_nodes;
-                       ( *num_mesh_nodes )++;
-                       if ( ( *num_mesh_nodes ) > MAX_FM_MESH_NODES ) {
-                               Error( "Too many mesh nodes in file %s\n", hrc_name );
-                       }
-                       meshNode = &( *nodesList )[ActiveNode];
-
-//                     memset(meshNode, 0, sizeof(mesh_node_t));
-                       strcpy( meshNode->name, tk_String );
-
-                       memset( meshNode->tris, 0, sizeof( meshNode->tris ) );
-                       memset( meshNode->verts, 0, sizeof( meshNode->verts ) );
-
-                       meshNode->start_glcmds = 0;
-                       meshNode->num_glcmds = 0;
-                       vertIndexBase = 0;
-               }
-               else
-               {   // Childs under the children
-                       meshNode = &( *nodesList )[ActiveNode];
-                       vertIndexBase = numVerts;
-               }
-       }
-       else
-       {
-               meshNode = NULL;
-       }
-
-
-       // Get the scaling, rotation, and translation values
-       TK_Beyond( TK_SCALING );
-       for ( i = 0; i < 3; i++ )
-       {
-               orig_scaling[i] = scaling[i];
-
-               TK_Require( TK_FLOATNUMBER );
-               scaling[i] *= tk_FloatNumber;
-
-               TK_Fetch();
-       }
-       TK_Beyond( TK_ROTATION );
-       for ( i = 0; i < 3; i++ )
-       {
-               orig_rotation[i] = rotation[i];
-
-               TK_Require( TK_FLOATNUMBER );
-               rotation[i] = tk_FloatNumber;
-
-               TK_Fetch();
-       }
-       TK_Beyond( TK_TRANSLATION );
-       for ( i = 0; i < 3; i++ )
-       {
-               orig_translation[i] = translation[i];
-
-               TK_Require( TK_FLOATNUMBER );
-               translation[i] += tk_FloatNumber;
-
-               TK_Fetch();
-       }
-
-       rx = ( ( rotation[0] - 90.0 ) / 360.0 ) * 2.0 * M_PI;
-       ry = ( rotation[2] / 360.0 ) * 2.0 * M_PI;
-       rz = ( rotation[1] / 360.0 ) * 2.0 * M_PI;
-
-       // rjr - might not work if there an item doesn't have a mesh
-       nextToken = tk_Token;
-       if ( nextToken == TK_ACTOR_DATA ) {
-               while ( nextToken != TK_MODEL && nextToken != TK_RBRACE )
-               {
-                       nextToken = TK_Fetch();
-               }
-       }
-
-       while ( nextToken == TK_SPLINE )
-       {   // spline node has two right braces
-               nextToken = TK_Beyond( TK_RBRACE );
-               nextToken = TK_Beyond( TK_RBRACE );
-       }
-
-       while ( nextToken == TK_MATERIAL )
-       {
-               nextToken = TK_Beyond( TK_RBRACE );
-       }
-
-       while ( nextToken == TK_MODEL )
-       {
-               HandleHRCModel( triList,triangleCount,nodesList,num_mesh_nodes,ActiveNode, Depth + 1, 0 );
-
-               nextToken = TK_Fetch();
-       }
-
-       if ( nextToken == TK_MESH ) {
-               // Get all the tri and vertex info
-               TK_BeyondRequire( TK_VERTICES, TK_INTNUMBER );
-               vertexCount = tk_IntNumber;
-               for ( i = 0; i < vertexCount; i++ )
-               {
-                       TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
-                       if ( tk_IntNumber != i ) {
-                               Error( "File '%s', line %d:\nVertex index mismatch.\n",
-                                          tk_SourceName, tk_Line );
-                       }
-                       TK_Beyond( TK_POSITION );
-                       // Apply the scaling, rotation, and translation in the order
-                       // specified in the HRC file.  This could be wrong.
-                       TK_Require( TK_FLOATNUMBER );
-                       x = tk_FloatNumber * scaling[0];
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       y = tk_FloatNumber * scaling[1];
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       z = tk_FloatNumber * scaling[2];
-
-                       y2 = y * cos( rx ) + z*sin( rx );
-                       z2 = -y*sin( rx ) + z*cos( rx );
-                       y = y2;
-                       z = z2;
-
-                       x2 = x * cos( ry ) - z*sin( ry );
-                       z2 = x * sin( ry ) + z*cos( ry );
-                       x = x2;
-                       z = z2;
-
-                       x2 = x * cos( rz ) + y*sin( rz );
-                       y2 = -x*sin( rz ) + y*cos( rz );
-                       x = x2;
-                       y = y2;
-
-                       vList[i].v[0] = x + translation[0];
-                       vList[i].v[1] = y - translation[2];
-                       vList[i].v[2] = z + translation[1];
-               }
-               TK_BeyondRequire( TK_POLYGONS, TK_INTNUMBER );
-               triCount = tk_IntNumber;
-               if ( triCount >= MAXTRIANGLES ) {
-                       Error( "Too many triangles in file %s\n", hrc_name );
-               }
-
-               start_tri = *triangleCount;
-               *triangleCount += triCount;
-
-               tList = *triList;
-
-               for ( i = 0; i < triCount; i++ )
-               {
-                       if ( meshNode ) { // Update the node
-                               pos = ( i + start_tri ) >> 3;
-                               bit = 1 << ( ( i + start_tri ) & 7 );
-                               meshNode->tris[pos] |= bit;
-                       }
-
-                       TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
-                       if ( tk_IntNumber != i ) {
-                               Error( "File '%s', line %d:\nTriangle index mismatch.\n",
-                                          tk_SourceName, tk_Line );
-                       }
-                       TK_BeyondRequire( TK_NODES, TK_INTNUMBER );
-                       if ( tk_IntNumber != 3 ) {
-                               Error( "File '%s', line %d:\nBad polygon vertex count: %d.",
-                                          tk_SourceName, tk_Line, tk_IntNumber );
-                       }
-                       tList[i + start_tri].HasUV = true;
-                       for ( j = 0; j < 3; j++ )
-                       {
-                               TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
-                               if ( tk_IntNumber != j ) {
-                                       Error( "File '%s', line %d:\nTriangle vertex index"
-                                                  " mismatch.  %d should be %d\n", tk_SourceName, tk_Line,
-                                                  tk_IntNumber, j );
-                               }
-                               TK_BeyondRequire( TK_VERTEX, TK_INTNUMBER );
-
-                               tList[i + start_tri].verts[2 - j][0] = vList[tk_IntNumber].v[0];
-                               tList[i + start_tri].verts[2 - j][1] = vList[tk_IntNumber].v[1];
-                               tList[i + start_tri].verts[2 - j][2] = vList[tk_IntNumber].v[2];
-#if 1
-                               tList[i + start_tri].indicies[2 - j] = tk_IntNumber + vertIndexBase;
-#endif
-                               TK_BeyondRequire( TK_UVTEXTURE, TK_FLOATNUMBER );
-                               tList[i + start_tri].uv[2 - j][0] = tk_FloatNumber;
-                               TK_Fetch();
-                               TK_Require( TK_FLOATNUMBER );
-                               tList[i + start_tri].uv[2 - j][1] = tk_FloatNumber;
-                       }
-
-                       /*              printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
-                                   "  v2: %f, %f, %f\n", i,
-                                   tList[i].verts[0][0],
-                                   tList[i].verts[0][1],
-                                   tList[i].verts[0][2],
-                                   tList[i].verts[1][0],
-                                   tList[i].verts[1][1],
-                                   tList[i].verts[1][2],
-                                   tList[i].verts[2][0],
-                                   tList[i].verts[2][1],
-                                   tList[i].verts[2][2]);
-                        */
-               }
-
-               TK_Beyond( TK_RBRACE );
-               TK_Beyond( TK_RBRACE );
-
-               if ( tk_Token == TK_EDGES ) {
-                       //      TK_Beyond(TK_EDGES);
-                       TK_Beyond( TK_RBRACE );
-               }
-
-               scaling[0] = scaling[1] = scaling[2] = 1.0;
-               //      rotation[0] = rotation[1] = rotation[2] = 0.0;
-               //      translation[0] = translation[1] = translation[2] = 0.0;
-
-               // See if there are any other models belonging to this node
-
-#if 1
-               TK_Fetch();
-
-               nextToken = tk_Token;
-               if ( nextToken == TK_CLUSTERS ) {
-                       if ( g_skelModel.clustered == -1 ) {
-                               ReadHRCClusterList( meshNode, vertIndexBase );
-                       }
-                       else
-                       {
-                               nextToken = TK_Get( TK_CLUSTER_NAME );
-
-                               while ( nextToken == TK_CLUSTER_NAME )
-                               {
-                                       TK_BeyondRequire( TK_CLUSTER_STATE, TK_INTNUMBER );
-                                       nextToken = TK_Fetch();
-                               }
-                       }
-
-                       // one right brace follow the list of clusters
-                       nextToken = TK_Beyond( TK_RBRACE );
-               }
-               else
-               {
-                       if ( g_skelModel.clustered == -1 && !vertIndexBase ) {
-                               meshNode->clustered = false;
-                       }
-               }
-#endif
-
-               nextToken = tk_Token;
-               if ( nextToken == TK_SPLINE ) {
-                       while ( nextToken == TK_SPLINE )
-                       {   // spline node has two right braces
-                               nextToken = TK_Beyond( TK_RBRACE );
-                               nextToken = TK_Beyond( TK_RBRACE );
-                       }
-
-                       nextToken = TK_Beyond( TK_RBRACE );
-               }
-
-               while ( nextToken == TK_MATERIAL )
-               {
-                       nextToken = TK_Beyond( TK_RBRACE );
-               }
-
-               while ( nextToken == TK_MODEL )
-               {
-                       HandleHRCModel( triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth + 1, vertexCount + vertIndexBase );
-
-                       nextToken = TK_Fetch();
-               }
-       }
-
-       for ( i = 0; i < 3; i++ )
-       {
-               scaling[i] = orig_scaling[i];
-               rotation[i] = orig_rotation[i];
-               translation[i] = orig_translation[i];
-       }
-}
-
-static void LoadHRC( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
-       if ( nodesList ) {
-               *num_mesh_nodes = 0;
-
-               if ( !*nodesList ) {
-                       *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
-               }
-       }
-
-       hrc_name = fileName;
-
-       scaling[0] = scaling[1] = scaling[2] = 1.0;
-       rotation[0] = rotation[1] = rotation[2] = 0.0;
-       translation[0] = translation[1] = translation[2] = 0.0;
-
-       *triangleCount = 0;
-       *triList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
-       memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-
-       // prime it
-       TK_Beyond( TK_MODEL );
-
-       HandleHRCModel( triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0 );
-       TK_CloseSource();
-}
-
-//==========================================================================
-//
-// LoadHTR
-//
-//==========================================================================
-/*
-   static int Version2;
-
-   void HandleHTRModel(triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,
-                           int ActiveNode, int Depth, int numVerts)
-   {
-    int                        i, j;
-    int                        vertexCount;
-    int                        vertexNum;
-    int                        triCount;
-    float              origin[3];
-    triangle_t *tList;
-    float              x, y, z;
-    float              x2, y2, z2;
-    float              rx, ry, rz;
-    mesh_node_t *meshNode;
-    int                        pos,bit;
-    int                        vertIndexBase;
-    int                        start_tri;
-
-    if (nodesList)
-    {
-        TK_BeyondRequire(TK_NAME, TK_STRING);
-
-        if (Depth == 0 || tk_String[0] == '_')
-        {      // Root
-            ActiveNode = *num_mesh_nodes;
-            (*num_mesh_nodes)++;
-            if ((*num_mesh_nodes) > MAX_FM_MESH_NODES)
-            {
-                Error("Too many mesh nodes in file %s\n", hrc_name);
-            }
-            meshNode = &(*nodesList)[ActiveNode];
-
-   //                  memset(meshNode, 0, sizeof(mesh_node_t));
-            strcpy(meshNode->name, tk_String);
-
-            memset(meshNode->tris, 0, sizeof(meshNode->tris));
-            memset(meshNode->verts, 0, sizeof(meshNode->verts));
-
-            meshNode->start_glcmds = 0;
-            meshNode->num_glcmds = 0;
-            vertIndexBase = 0;
-        }
-        else
-        {      // Childs under the children
-            meshNode = &(*nodesList)[ActiveNode];
-            vertIndexBase = numVerts;
-        }
-    }
-    else
-    {
-        meshNode = NULL;
-    }
-
-    // Get vertex count
-    TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);
-    vertexCount = tk_IntNumber;
-
-    // Get triangle count
-    TK_BeyondRequire(TK_FACES, TK_INTNUMBER);
-    triCount = tk_IntNumber;
-    if(triCount >= MAXTRIANGLES)
-    {
-        Error("Too many triangles in file %s\n", hrc_name);
-    }
-
-    // Get origin
-    TK_Beyond(TK_ORIGIN);
-    TK_Require(TK_FLOATNUMBER);
-    origin[0] = tk_FloatNumber;
-    TK_FetchRequire(TK_FLOATNUMBER);
-    origin[1] = tk_FloatNumber;
-    TK_FetchRequire(TK_FLOATNUMBER);
-    origin[2] = tk_FloatNumber;
-
-    //rx = 90.0/360.0*2.0*M_PI;
-    rx = FixHTRRotateX/360.0*2.0*M_PI;
-    ry = FixHTRRotateY/360.0*2.0*M_PI;
-    rz = FixHTRRotateZ/360.0*2.0*M_PI;
-
-    // Get vertex list
-    for(i = 0; i < vertexCount; i++)
-    {
-        TK_FetchRequire(TK_VERTEX);
-        TK_FetchRequire(TK_FLOATNUMBER);
-        x = tk_FloatNumber-origin[0];
-        TK_FetchRequire(TK_FLOATNUMBER);
-        y = tk_FloatNumber-origin[1];
-        TK_FetchRequire(TK_FLOATNUMBER);
-        z = tk_FloatNumber-origin[2];
-
-        x += FixHTRTranslateX;
-        y += FixHTRTranslateY;
-        z += FixHTRTranslateZ;
-
-        y2 = y*cos(rx)-z*sin(rx);
-        z2 = y*sin(rx)+z*cos(rx);
-        y = y2;
-        z = z2;
-        x2 = x*cos(ry)+z*sin(ry);
-        z2 = -x*sin(ry)+z*cos(ry);
-        x = x2;
-        z = z2;
-        x2 = x*cos(rz)-y*sin(rz);
-        y2 = x*sin(rz)+y*cos(rz);
-        x = x2;
-        y = y2;
-
-        vList[i].v[0] = x;
-        vList[i].v[1] = y;
-        vList[i].v[2] = z;
-    }
-
-    start_tri = *triangleCount;
-   *triangleCount += triCount;
-
-    tList = *triList;
-
-    // Get face list
-    for(i = 0; i < triCount; i++)
-    {
-        if (meshNode)
-        {      // Update the node
-            pos = (i + start_tri) >> 3;
-            bit = 1 << ((i + start_tri) & 7 );
-            meshNode->tris[pos] |= bit;
-        }
-
-        TK_FetchRequire(TK_FACE);
-        TK_FetchRequire(TK_LPAREN);
-        for(j = 0; j < 3; j++)
-        {
-            TK_FetchRequire(TK_INTNUMBER);
-            vertexNum = tk_IntNumber-1;
-            if(vertexNum >= vertexCount)
-            {
-                Error("File '%s', line %d:\nVertex number"
-                    " >= vertexCount: %d\n", tk_SourceName, tk_Line,
-                    tk_IntNumber);
-            }
-            tList[i+start_tri].verts[2-j][0] = vList[vertexNum].v[0];
-            tList[i+start_tri].verts[2-j][1] = vList[vertexNum].v[1];
-            tList[i+start_tri].verts[2-j][2] = vList[vertexNum].v[2];
-        }
-        TK_FetchRequire(TK_RPAREN);
-   #ifdef _QDATA
-        if (Version2)
-        {
-            TK_FetchRequire(TK_FLOATNUMBER);
-            tList[i+start_tri].uv[0][0]=tk_FloatNumber;
-            TK_FetchRequire(TK_FLOATNUMBER);
-            tList[i+start_tri].uv[0][1]=tk_FloatNumber;
-            TK_FetchRequire(TK_FLOATNUMBER);
-            tList[i+start_tri].uv[1][0]=tk_FloatNumber;
-            TK_FetchRequire(TK_FLOATNUMBER);
-            tList[i+start_tri].uv[1][1]=tk_FloatNumber;
-            TK_FetchRequire(TK_FLOATNUMBER);
-            tList[i+start_tri].uv[2][0]=tk_FloatNumber;
-            TK_FetchRequire(TK_FLOATNUMBER);
-            tList[i+start_tri].uv[2][1]=tk_FloatNumber;
-            tList[i+start_tri].HasUV=1;
-        }
-        else
-            tList[i+start_tri].HasUV=0;
-   #endif
-   //          printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
-   //                  "  v2: %f, %f, %f\n", i,
-   //                  tList[i].verts[0][0],
-   //                  tList[i].verts[0][1],
-   //                  tList[i].verts[0][2],
-   //                  tList[i].verts[1][0],
-   //                  tList[i].verts[1][1],
-   //                  tList[i].verts[1][2],
-   //                  tList[i].verts[2][0],
-   //                  tList[i].verts[2][1],
-   //                  tList[i].verts[2][2]);
-
-    }
-
-    TK_Fetch();
-
-    if (tk_Token == TK_VERTICES)
-    {
-        HandleHTRModel(triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth+1, vertexCount+vertIndexBase);
-    }
-   }
-
-   static void LoadHTR(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes)
-   {
-    if (nodesList)
-    {
-   *num_mesh_nodes = 0;
-
-        if(!*nodesList)
-        {
-   *nodesList = SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
-        }
-    }
-
-    hrc_name = fileName;
-
-    scaling[0] = scaling[1] = scaling[2] = 1.0;
-    rotation[0] = rotation[1] = rotation[2] = 0.0;
-    translation[0] = translation[1] = translation[2] = 0.0;
-
-   *triangleCount = 0;
-   *triList = SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");
-    memset(*triList,0,MAXTRIANGLES*sizeof(triangle_t));
-
-    TK_OpenSource(fileName);
-
-    TK_Beyond(TK_C_HEXEN);
-    TK_Beyond(TK_C_TRIANGLES);
-    TK_BeyondRequire(TK_C_VERSION, TK_INTNUMBER);
-    if(tk_IntNumber != 1&&tk_IntNumber != 2)
-    {
-        Error("Unsupported version (%d) in file %s\n", tk_IntNumber,
-            fileName);
-    }
-    Version2=(tk_IntNumber==2);
-
-
-    HandleHTRModel(triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0);
-   }
-
- */
-
-static void LoadHTR( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
-       int Version2 = 0;
-       int i, j;
-       int vertexCount;
-       int vertexNum;
-       struct
-       {
-               float v[3];
-       }           *vList;
-       int triCount;
-       float origin[3];
-       triangle_t  *tList;
-       float x, y, z;
-       float x2, y2, z2;
-       float rx, ry, rz;
-
-       if ( nodesList ) {
-               *num_mesh_nodes = 0;
-               *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
-       }
-
-       TK_OpenSource( fileName );
-
-       TK_Beyond( TK_C_HEXEN );
-       TK_Beyond( TK_C_TRIANGLES );
-       TK_BeyondRequire( TK_C_VERSION, TK_INTNUMBER );
-       if ( tk_IntNumber != 1 && tk_IntNumber != 2 ) {
-               Error( "Unsupported version (%d) in file %s\n", tk_IntNumber,
-                          fileName );
-       }
-       Version2 = ( tk_IntNumber == 2 );
-
-
-       // Get vertex count
-       TK_BeyondRequire( TK_VERTICES, TK_INTNUMBER );
-       vertexCount = tk_IntNumber;
-       vList = (void *) SafeMalloc( vertexCount * sizeof vList[0], "Vertex list" );
-
-       // Get triangle count
-       TK_BeyondRequire( TK_FACES, TK_INTNUMBER );
-       triCount = tk_IntNumber;
-       if ( triCount >= MAXTRIANGLES ) {
-               Error( "Too many triangles in file %s\n", fileName );
-       }
-       *triangleCount = triCount;
-       tList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
-       *triList = tList;
-       memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
-
-       // Get origin
-       TK_Beyond( TK_ORIGIN );
-       TK_Require( TK_FLOATNUMBER );
-       origin[0] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       origin[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       origin[2] = tk_FloatNumber;
-
-       //rx = 90.0/360.0*2.0*M_PI;
-       rx = FixHTRRotateX / 360.0 * 2.0 * M_PI;
-       ry = FixHTRRotateY / 360.0 * 2.0 * M_PI;
-       rz = FixHTRRotateZ / 360.0 * 2.0 * M_PI;
-
-       // Get vertex list
-       for ( i = 0; i < vertexCount; i++ )
-       {
-               TK_FetchRequire( TK_VERTEX );
-               TK_FetchRequire( TK_FLOATNUMBER );
-               x = tk_FloatNumber - origin[0];
-               TK_FetchRequire( TK_FLOATNUMBER );
-               y = tk_FloatNumber - origin[1];
-               TK_FetchRequire( TK_FLOATNUMBER );
-               z = tk_FloatNumber - origin[2];
-
-               x += FixHTRTranslateX;
-               y += FixHTRTranslateY;
-               z += FixHTRTranslateZ;
-
-               y2 = y * cos( rx ) - z*sin( rx );
-               z2 = y * sin( rx ) + z*cos( rx );
-               y = y2;
-               z = z2;
-               x2 = x * cos( ry ) + z*sin( ry );
-               z2 = -x*sin( ry ) + z*cos( ry );
-               x = x2;
-               z = z2;
-               x2 = x * cos( rz ) - y*sin( rz );
-               y2 = x * sin( rz ) + y*cos( rz );
-               x = x2;
-               y = y2;
-
-               vList[i].v[0] = x;
-               vList[i].v[1] = y;
-               vList[i].v[2] = z;
-       }
-
-       // Get face list
-       for ( i = 0; i < triCount; i++ )
-       {
-               TK_FetchRequire( TK_FACE );
-               TK_FetchRequire( TK_LPAREN );
-               for ( j = 0; j < 3; j++ )
-               {
-                       TK_FetchRequire( TK_INTNUMBER );
-                       vertexNum = tk_IntNumber - 1;
-                       if ( vertexNum >= vertexCount ) {
-                               Error( "File '%s', line %d:\nVertex number"
-                                          " >= vertexCount: %d\n", tk_SourceName, tk_Line,
-                                          tk_IntNumber );
-                       }
-                       tList[i].verts[2 - j][0] = vList[vertexNum].v[0];
-                       tList[i].verts[2 - j][1] = vList[vertexNum].v[1];
-                       tList[i].verts[2 - j][2] = vList[vertexNum].v[2];
-               }
-               TK_FetchRequire( TK_RPAREN );
-#if 1
-               if ( Version2 ) {
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       tList[i].uv[2][0] = fmod( 1000 + tk_FloatNumber,1 );
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       tList[i].uv[2][1] = fmod( 1000 + tk_FloatNumber,1 );
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       tList[i].uv[1][0] = fmod( 1000 + tk_FloatNumber,1 );
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       tList[i].uv[1][1] = fmod( 1000 + tk_FloatNumber,1 );
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       tList[i].uv[0][0] = fmod( 1000 + tk_FloatNumber,1 );
-                       TK_FetchRequire( TK_FLOATNUMBER );
-                       tList[i].uv[0][1] = fmod( 1000 + tk_FloatNumber,1 );
-                       tList[i].HasUV = 1;
-               }
-               else{
-                       tList[i].HasUV = 0;
-               }
-#endif
-/*             printf("Face %i:\n  v0: %f, %f, %f\n  v1: %f, %f, %f\n"
-            "  v2: %f, %f, %f\n", i,
-            tList[i].verts[0][0],
-            tList[i].verts[0][1],
-            tList[i].verts[0][2],
-            tList[i].verts[1][0],
-            tList[i].verts[1][1],
-            tList[i].verts[1][2],
-            tList[i].verts[2][0],
-            tList[i].verts[2][1],
-            tList[i].verts[2][2]);
- */
-       }
-
-       free( vList );
-       TK_CloseSource();
-       DefaultNodesList( nodesList,num_mesh_nodes,triangleCount );
-}
-
-//==========================================================================
-//
-// LoadTriangleList
-//
-//==========================================================================
-
-void LoadTriangleList( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **ppmnodes, int *num_mesh_nodes ){
-       FILE    *file1;
-       int dot = '.';
-       char    *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-                       LoadHRC( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".asc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-                       LoadASC( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       printf( " - assuming .ASC\n" );
-                       return;
-               }
-
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".tri" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-                       LoadTRI( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       printf( " - assuming .TRI\n" );
-                       return;
-               }
-
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".3ds" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-                       Load3DSTriangleList( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       printf( " - assuming .3DS\n" );
-                       return;
-               }
-
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".htr" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-                       LoadHTR( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       printf( " - assuming .HTR\n" );
-                       return;
-               }
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC, ASC, 3DS, HTR, or TRI match.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-                       printf( "\n" );
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRC( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       }
-                       else if ( strcmp( dotstart,".asc" ) == 0 || strcmp( dotstart,".ASC" ) == 0 ) {
-                               LoadASC( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       }
-                       else if ( strcmp( dotstart,".tri" ) == 0 || strcmp( dotstart,".TRI" ) == 0 ) {
-                               LoadTRI( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       }
-                       else if ( strcmp( dotstart,".3ds" ) == 0 || strcmp( dotstart,".3DS" ) == 0 ) {
-                               Load3DSTriangleList( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       }
-                       else if ( strcmp( dotstart,".htr" ) == 0 || strcmp( dotstart,".HTR" ) == 0 ) {
-                               LoadHTR( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
-                       }
-                       else
-                       {
-                               Error( "Could not open file '%s':\n",fileName );
-                               return;
-                       }
-               }
-               else    //failed to load file
-               {
-                       Error( "Could not open file '%s':\n",fileName );
-               }
-
-       }
-}
diff --git a/tools/quake2/qdata_heretic2/common/trilib.h b/tools/quake2/qdata_heretic2/common/trilib.h
deleted file mode 100644 (file)
index 8dfd6d2..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-//
-// trilib.h: header file for loading triangles from an Alias triangle file
-//
-
-#include "fmodel.h"
-
-#define MAXTRIANGLES    MAX_FM_TRIANGLES
-
-typedef struct
-{
-       vec3_t verts[3];
-#if 1
-       int indicies[3];
-       float uv[3][2];
-       qboolean HasUV;
-#endif
-} triangle_t;
-
-#define NUM_CLUSTERS 8
-
-typedef struct
-{
-       char name[64];
-       byte tris[MAXTRIANGLES >> 3];
-       byte verts[MAX_FM_VERTS >> 3];
-       int start_glcmds, num_glcmds;
-
-       int *clusters[NUM_CLUSTERS];
-       struct IntListNode_s *vertLists[NUM_CLUSTERS];
-       int num_verts[NUM_CLUSTERS + 1];
-       int new_num_verts[NUM_CLUSTERS + 1];
-       qboolean clustered;
-} mesh_node_t;
-
-void LoadTriangleList( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **ppmnodes, int *num_mesh_nodes );
diff --git a/tools/quake2/qdata_heretic2/fmodels.c b/tools/quake2/qdata_heretic2/fmodels.c
deleted file mode 100644 (file)
index 7d8df18..0000000
+++ /dev/null
@@ -1,3311 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "qd_fmodel.h"
-#include "animcomp.h"
-#include "qd_skeletons.h"
-#include "skeletons.h"
-#include "qdata.h"
-#include "flex.h"
-#include "reference.h"
-
-#include <assert.h>
-
-/*
-   ========================================================================
-
-   .FM triangle flexible model file format
-
-   ========================================================================
- */
-
-//=================================================================
-
-#define NUMVERTEXNORMALS    162
-
-extern float avertexnormals[NUMVERTEXNORMALS][3];
-
-#define MAX_GROUPS  128
-
-typedef struct
-{
-       triangle_t triangle;
-       int group;
-} trigroup_t;
-
-#define TRIVERT_DIST    .1
-
-typedef struct
-{
-       int start_frame;
-       int num_frames;
-       int degrees;
-       char *mat;
-       char *ccomp;
-       char *cbase;
-       float *cscale;
-       float *coffset;
-       float trans[3];
-       float scale[3];
-       float bmin[3];
-       float bmax[3];
-} fmgroup_t;
-
-//================================================================
-
-// Initial
-fmheader_t fmheader;
-
-// Skin
-extern char g_skins[MAX_FM_SKINS][64];
-
-// ST Coord
-extern fmstvert_t base_st[MAX_FM_VERTS];
-
-// Triangles
-extern fmtriangle_t triangles[MAX_FM_TRIANGLES];
-
-// Frames
-fmframe_t g_frames[MAX_FM_FRAMES];
-//fmframe_t    *g_FMframes;
-
-// GL Commands
-extern int commands[16384];
-extern int numcommands;
-
-
-//
-// varibles set by commands
-//
-extern float scale_up;                              // set by $scale
-extern vec3_t adjust;                               // set by $origin
-extern int g_fixedwidth, g_fixedheight;             // set by $skinsize
-extern char modelname[64];                          // set by $modelname
-
-
-extern char        *g_outputDir;
-
-
-// Mesh Nodes
-mesh_node_t *pmnodes = NULL;
-fmmeshnode_t mesh_nodes[MAX_FM_MESH_NODES];
-
-fmgroup_t groups[MAX_GROUPS];
-int num_groups;
-int frame_to_group[MAX_FM_FRAMES];
-
-//
-// variables set by command line arguments
-//
-qboolean g_no_opimizations = false;
-
-
-//
-// base frame info
-//
-static int triangle_st[MAX_FM_TRIANGLES][3][2];
-
-
-// number of gl vertices
-extern int numglverts;
-// indicates if a triangle has already been used in a glcmd
-extern int used[MAX_FM_TRIANGLES];
-// indicates if a triangle has translucency in it or not
-static qboolean translucent[MAX_FM_TRIANGLES];
-
-// main output file handle
-extern FILE         *headerouthandle;
-// output sizes of buildst()
-static int skin_width, skin_height;
-
-
-// statistics
-static int total_skin_pixels;
-static int skin_pixels_used;
-
-int ShareVertex( trigroup_t trione, trigroup_t tritwo );
-float DistBetween( vec3_t point1, vec3_t point2 );
-int GetNumTris( trigroup_t *tris, int group );
-void GetOneGroup( trigroup_t *tris, int grp, triangle_t* triangles );
-void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts );
-void NewDrawLine( int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height );
-
-#if !GDEF_OS_WINDOWS
-
-void strupr( char *string ){
-       int i;
-
-       for ( i = 0 ; i < strlen( string ); i++ )
-               toupper( string[i] );
-
-       return;
-}
-
-#endif
-//==============================================================
-
-/*
-   ===============
-   ClearModel
-   ===============
- */
-static void ClearModel( void ){
-       memset( &fmheader, 0, sizeof( fmheader ) );
-
-       modelname[0] = 0;
-       scale_up = 1.0;
-       VectorCopy( vec3_origin, adjust );
-       g_fixedwidth = g_fixedheight = 0;
-       g_skipmodel = false;
-       num_groups = 0;
-
-       if ( pmnodes ) {
-               free( pmnodes );
-               pmnodes = NULL;
-       }
-
-       ClearSkeletalModel();
-}
-
-
-extern void H_printf( char *fmt, ... );
-
-
-void WriteHeader( FILE *FH, char *Ident, int Version, int Size, void *Data ){
-       header_t header;
-       static long pos = -1;
-       long CurrentPos;
-
-       if ( Size == 0 ) { // Don't write out empty packets
-               return;
-       }
-
-       if ( pos != -1 ) {
-               CurrentPos = ftell( FH );
-               Size = CurrentPos - pos + sizeof( header_t );
-               fseek( FH, pos, SEEK_SET );
-               pos = -2;
-       }
-       else if ( Size == -1 ) {
-               pos = ftell( FH );
-       }
-
-       memset( &header,0,sizeof( header ) );
-       strcpy( header.ident,Ident );
-       header.version = Version;
-       header.size = Size;
-
-       SafeWrite( FH, &header, sizeof( header ) );
-
-       if ( Data ) {
-               SafeWrite( FH, Data, Size );
-       }
-
-       if ( pos == -2 ) {
-               pos = -1;
-               fseek( FH, 0, SEEK_END );
-       }
-}
-
-/*
-   ============
-   WriteModelFile
-   ============
- */
-static void WriteModelFile( FILE *modelouthandle ){
-       int i;
-       int j, k;
-       fmframe_t       *in;
-       fmaliasframe_t  *out;
-       byte buffer[MAX_FM_VERTS * 4 + 128];
-       float v;
-       int c_on, c_off;
-       IntListNode_t   *current, *toFree;
-       qboolean framesWritten = false;
-       size_t temp,size = 0;
-
-       // probably should do this dynamically one of these days
-       struct
-       {
-               float scale[3];         // multiply byte verts by this
-               float translate[3];         // then add this
-       } outFrames[MAX_FM_FRAMES];
-
-#define DATA_SIZE 0x60000       // 384K had better be enough, particularly for the reference points
-       byte data[DATA_SIZE];
-       byte data2[DATA_SIZE];
-
-       fmheader.num_glcmds = numcommands;
-       fmheader.framesize = (int)&( (fmaliasframe_t *)0 )->verts[fmheader.num_xyz];
-
-       WriteHeader( modelouthandle, FM_HEADER_NAME, FM_HEADER_VER, sizeof( fmheader ), &fmheader );
-
-       //
-       // write out the skin names
-       //
-
-       WriteHeader( modelouthandle, FM_SKIN_NAME, FM_SKIN_VER, fmheader.num_skins * MAX_FM_SKINNAME, g_skins );
-
-       //
-       // write out the texture coordinates
-       //
-       c_on = c_off = 0;
-       for ( i = 0 ; i < fmheader.num_st ; i++ )
-       {
-               base_st[i].s = LittleShort( base_st[i].s );
-               base_st[i].t = LittleShort( base_st[i].t );
-       }
-
-       WriteHeader( modelouthandle, FM_ST_NAME, FM_ST_VER, fmheader.num_st * sizeof( base_st[0] ), base_st );
-
-       //
-       // write out the triangles
-       //
-       WriteHeader( modelouthandle, FM_TRI_NAME, FM_TRI_VER, fmheader.num_tris * sizeof( fmtriangle_t ), NULL );
-
-       for ( i = 0 ; i < fmheader.num_tris ; i++ )
-       {
-               int j;
-               fmtriangle_t tri;
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       tri.index_xyz[j] = LittleShort( triangles[i].index_xyz[j] );
-                       tri.index_st[j] = LittleShort( triangles[i].index_st[j] );
-               }
-
-               SafeWrite( modelouthandle, &tri, sizeof( tri ) );
-       }
-
-       if ( !num_groups ) {
-               //
-               // write out the frames
-               //
-               WriteHeader( modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, fmheader.num_frames * fmheader.framesize, NULL );
-               //      WriteHeader(modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, -1, NULL);
-
-               for ( i = 0 ; i < fmheader.num_frames ; i++ )
-               {
-                       in = &g_frames[i];
-                       out = (fmaliasframe_t *)buffer;
-
-                       strcpy( out->name, in->name );
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               out->scale[j] = ( in->maxs[j] - in->mins[j] ) / 255;
-                               out->translate[j] = in->mins[j];
-
-                               outFrames[i].scale[j] = out->scale[j];
-                               outFrames[i].translate[j] = out->translate[j];
-                       }
-
-                       for ( j = 0 ; j < fmheader.num_xyz ; j++ )
-                       {
-                               // all of these are byte values, so no need to deal with endianness
-                               out->verts[j].lightnormalindex = in->v[j].lightnormalindex;
-
-                               for ( k = 0 ; k < 3 ; k++ )
-                               {
-                                       // scale to byte values & min/max check
-                                       v = Q_rint( ( in->v[j].v[k] - out->translate[k] ) / out->scale[k] );
-
-                                       // clamp, so rounding doesn't wrap from 255.6 to 0
-                                       if ( v > 255.0 ) {
-                                               v = 255.0;
-                                       }
-                                       if ( v < 0 ) {
-                                               v = 0;
-                                       }
-                                       out->verts[j].v[k] = v;
-                               }
-                       }
-
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               out->scale[j] = LittleFloat( out->scale[j] );
-                               out->translate[j] = LittleFloat( out->translate[j] );
-                       }
-
-                       SafeWrite( modelouthandle, out, fmheader.framesize );
-               }
-
-               // Go back and finish the header
-               //      WriteHeader(modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, -1, NULL);
-       }
-       else
-       {
-               WriteHeader( modelouthandle, FM_SHORT_FRAME_NAME, FM_SHORT_FRAME_VER,FRAME_NAME_LEN * fmheader.num_frames, NULL );
-               for ( i = 0 ; i < fmheader.num_frames ; i++ )
-               {
-                       in = &g_frames[i];
-                       SafeWrite( modelouthandle,in->name,FRAME_NAME_LEN );
-               }
-               WriteHeader( modelouthandle, FM_NORMAL_NAME, FM_NORMAL_VER,fmheader.num_xyz, NULL );
-               in = &g_frames[0];
-               for ( j = 0 ; j < fmheader.num_xyz ; j++ )
-                       SafeWrite( modelouthandle,&in->v[j].lightnormalindex,1 );
-       }
-
-       //
-       // write out glcmds
-       //
-       WriteHeader( modelouthandle, FM_GLCMDS_NAME, FM_GLCMDS_VER, numcommands * 4, commands );
-
-       //
-       // write out mesh nodes
-       //
-       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
-       {
-               memcpy( mesh_nodes[i].tris, pmnodes[i].tris, sizeof( mesh_nodes[i].tris ) );
-               memcpy( mesh_nodes[i].verts, pmnodes[i].verts, sizeof( mesh_nodes[i].verts ) );
-               mesh_nodes[i].start_glcmds = LittleShort( (short)pmnodes[i].start_glcmds );
-               mesh_nodes[i].num_glcmds = LittleShort( (short)pmnodes[i].num_glcmds );
-       }
-
-       WriteHeader( modelouthandle, FM_MESH_NAME, FM_MESH_VER, sizeof( fmmeshnode_t ) * fmheader.num_mesh_nodes, mesh_nodes );
-
-       if ( num_groups ) {
-
-/*
-   typedef struct
-   {
-    int                        start_frame;
-    int                        num_frames;
-    int                        degrees;
-    char *mat; fmheader.num_xyz*3*g->degrees*sizeof(char)
-    char *ccomp; g->num_frames*g->degrees*sizeof(char)
-    char *cbase; fmheader.num_xyz*3*sizeof(unsigned char)
-    float *cscale; g->degrees*sizeof(float)
-    float *coffset; g->degrees*sizeof(float)
-    float trans[3]; 3*sizeof(float)
-    float scale[3]; 3*sizeof(float)
-   } fmgroup_t;
- */
-               int tmp,k;
-               fmgroup_t *g;
-               size = sizeof( int ) + fmheader.num_frames * sizeof( int );
-               for ( k = 0; k < num_groups; k++ )
-               {
-                       g = &groups[k];
-                       size += sizeof( int ) * 3;
-                       size += fmheader.num_xyz * 3 * g->degrees * sizeof( char );
-                       size += g->num_frames * g->degrees * sizeof( char );
-                       size += fmheader.num_xyz * 3 * sizeof( unsigned char );
-                       size += g->degrees * sizeof( float );
-                       size += g->degrees * sizeof( float );
-                       size += 12 * sizeof( float );
-               }
-               WriteHeader( modelouthandle, FM_COMP_NAME, FM_COMP_VER,size, NULL );
-               SafeWrite( modelouthandle,&num_groups,sizeof( int ) );
-               SafeWrite( modelouthandle,frame_to_group,sizeof( int ) * fmheader.num_frames );
-
-               for ( k = 0; k < num_groups; k++ )
-               {
-                       g = &groups[k];
-                       tmp = LittleLong( g->start_frame );
-                       SafeWrite( modelouthandle,&tmp,sizeof( int ) );
-                       tmp = LittleLong( g->num_frames );
-                       SafeWrite( modelouthandle,&tmp,sizeof( int ) );
-                       tmp = LittleLong( g->degrees );
-                       SafeWrite( modelouthandle,&tmp,sizeof( int ) );
-
-                       SafeWrite( modelouthandle,g->mat,fmheader.num_xyz * 3 * g->degrees * sizeof( char ) );
-                       SafeWrite( modelouthandle,g->ccomp,g->num_frames * g->degrees * sizeof( char ) );
-                       SafeWrite( modelouthandle,g->cbase,fmheader.num_xyz * 3 * sizeof( unsigned char ) );
-                       SafeWrite( modelouthandle,g->cscale,g->degrees * sizeof( float ) );
-                       SafeWrite( modelouthandle,g->coffset,g->degrees * sizeof( float ) );
-                       SafeWrite( modelouthandle,g->trans,3 * sizeof( float ) );
-                       SafeWrite( modelouthandle,g->scale,3 * sizeof( float ) );
-                       SafeWrite( modelouthandle,g->bmin,3 * sizeof( float ) );
-                       SafeWrite( modelouthandle,g->bmax,3 * sizeof( float ) );
-                       free( g->mat );
-                       free( g->ccomp );
-                       free( g->cbase );
-                       free( g->cscale );
-                       free( g->coffset );
-               }
-       }
-
-       // write the skeletal info
-       if ( g_skelModel.type != SKEL_NULL ) {
-               size = 0;
-
-               temp = sizeof( int );     // change this to a byte
-               memcpy( data + size, &g_skelModel.type, temp );
-               size += temp;
-
-               // number of joints
-               temp = sizeof( int );     // change this to a byte
-               memcpy( data + size, &numJointsInSkeleton[g_skelModel.type], temp );
-               size += temp;
-
-               // number of verts in each joint cluster
-               temp = sizeof( int ) * numJointsInSkeleton[g_skelModel.type]; // change this to shorts
-               memcpy( data + size, &g_skelModel.new_num_verts[1], temp );
-               size += temp;
-
-               // cluster verts
-               for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i )
-               {
-                       current = g_skelModel.vertLists[i];
-                       while ( current )
-                       {
-                               temp = sizeof( int ); // change this to a short
-                               memcpy( data + size, &current->data, temp );
-                               size += temp;
-                               toFree = current;
-                               current = current->next;
-                               free( toFree );  // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base
-                       }
-               }
-
-               if ( !num_groups ) { // joints are stored with regular verts for compressed models
-                       framesWritten = true;
-
-                       temp = sizeof( int ); // change this to a byte
-                       memcpy( data + size, &framesWritten, temp );
-                       size += temp;
-
-                       for ( i = 0; i < fmheader.num_frames; ++i )
-                       {
-                               in = &g_frames[i];
-
-                               for ( j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j )
-                               {
-                                       for ( k = 0 ; k < 3 ; k++ )
-                                       {
-                                               // scale to byte values & min/max check
-                                               v = Q_rint( ( in->joints[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                                               // write out origin as a float since they arn't clamped
-                                               temp = sizeof( float );   // change this to a short
-                                               assert( size + temp < DATA_SIZE );
-                                               memcpy( data + size, &v, temp );
-                                               size += temp;
-                                       }
-
-                                       for ( k = 0 ; k < 3 ; k++ )
-                                       {
-                                               v = Q_rint( ( in->joints[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                                               // write out origin as a float since they arn't clamped
-                                               temp = sizeof( float );   // change this to a short
-                                               assert( size + temp < DATA_SIZE );
-                                               memcpy( data + size, &v, temp );
-                                               size += temp;
-                                       }
-
-                                       for ( k = 0 ; k < 3 ; k++ )
-                                       {
-                                               v = Q_rint( ( in->joints[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                                               // write out origin as a float since they arn't clamped
-                                               temp = sizeof( float );   // change this to a short
-                                               assert( size + temp < DATA_SIZE );
-                                               memcpy( data + size, &v, temp );
-                                               size += temp;
-                                       }
-                               }
-                       }
-
-               }
-               else
-               {
-                       temp = sizeof( int ); // change this to a byte
-                       memcpy( data + size, &framesWritten, temp );
-                       size += temp;
-               }
-
-               WriteHeader( modelouthandle, FM_SKELETON_NAME, FM_SKELETON_VER, size, data );
-       }
-
-       if ( g_skelModel.references != REF_NULL ) {
-               int refnum;
-
-               size = 0;
-               if ( RefPointNum <= 0 ) { // Hard-coded labels
-                       refnum = numReferences[g_skelModel.references];
-               }
-               else
-               {   // Labels indicated in QDT
-                       refnum = RefPointNum;
-               }
-
-               temp = sizeof( int ); // change this to a byte
-               memcpy( data2 + size, &g_skelModel.references, temp );
-               size += temp;
-
-               if ( !num_groups ) {
-                       framesWritten = true;
-
-                       temp = sizeof( int ); // change this to a byte
-                       memcpy( data2 + size, &framesWritten, temp );
-                       size += temp;
-
-                       for ( i = 0; i < fmheader.num_frames; ++i )
-                       {
-                               in = &g_frames[i];
-
-                               for ( j = 0 ; j < refnum; ++j )
-                               {
-                                       for ( k = 0 ; k < 3 ; k++ )
-                                       {
-                                               // scale to byte values & min/max check
-                                               v = Q_rint( ( in->references[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                                               // write out origin as a float since they arn't clamped
-                                               temp = sizeof( float );   // change this to a short
-                                               assert( size + temp < DATA_SIZE );
-                                               memcpy( data2 + size, &v, temp );
-                                               size += temp;
-                                       }
-
-                                       for ( k = 0 ; k < 3 ; k++ )
-                                       {
-                                               v = Q_rint( ( in->references[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                                               // write out origin as a float since they arn't clamped
-                                               temp = sizeof( float );   // change this to a short
-                                               assert( size + temp < DATA_SIZE );
-                                               memcpy( data2 + size, &v, temp );
-                                               size += temp;
-                                       }
-
-                                       for ( k = 0 ; k < 3 ; k++ )
-                                       {
-                                               v = Q_rint( ( in->references[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                                               // write out origin as a float since they arn't clamped
-                                               temp = sizeof( float );   // change this to a short
-                                               assert( size + temp < DATA_SIZE );
-                                               memcpy( data2 + size, &v, temp );
-                                               size += temp;
-                                       }
-                               }
-                       }
-               }
-               else    // FINISH ME: references need to be stored with regular verts for compressed models
-               {
-                       framesWritten = false;
-
-                       temp = sizeof( int ); // change this to a byte
-                       memcpy( data2 + size, &framesWritten, temp );
-                       size += temp;
-               }
-
-               WriteHeader( modelouthandle, FM_REFERENCES_NAME, FM_REFERENCES_VER, size, data2 );
-       }
-}
-
-static void CompressFrames(){
-       fmgroup_t *g;
-       int i,j,k;
-       fmframe_t   *in;
-
-       j = 0;
-       for ( i = 0; i < fmheader.num_frames; i++ )
-       {
-               while ( i >= groups[j].start_frame + groups[j].num_frames && j < num_groups - 1 )
-                       j++;
-               frame_to_group[i] = j;
-       }
-
-       for ( k = 0; k < num_groups; k++ )
-       {
-               g = &groups[k];
-
-               printf( "\nCompressing Frames for group %i...\n", k );
-               AnimCompressInit( g->num_frames,fmheader.num_xyz,g->degrees );
-               for ( i = 0; i < g->num_frames; i++ )
-               {
-                       in = &g_frames[i + g->start_frame];
-                       for ( j = 0; j < fmheader.num_xyz; j++ )
-                               AnimSetFrame( i,j,in->v[j].v[0],in->v[j].v[1],in->v[j].v[2] );
-               }
-               AnimCompressDoit();
-               g->mat = (char *) SafeMalloc( fmheader.num_xyz * 3 * g->degrees * sizeof( char ), "CompressFrames" );
-               g->ccomp = (char *) SafeMalloc( g->num_frames * g->degrees * sizeof( char ), "CompressFrames" );
-               g->cbase = (char *) SafeMalloc( fmheader.num_xyz * 3 * sizeof( unsigned char ), "CompressFrames" );
-               g->cscale = (float *) SafeMalloc( g->degrees * sizeof( float ), "CompressFrames" );
-               g->coffset = (float *) SafeMalloc( g->degrees * sizeof( float ), "CompressFrames" );
-               AnimCompressToBytes( g->trans,g->scale,g->mat,g->ccomp,g->cbase,g->cscale,g->coffset,g->bmin,g->bmax );
-               AnimCompressEnd();
-       }
-}
-
-static void OptimizeVertices( void ){
-       qboolean vert_used[MAX_FM_VERTS];
-       short vert_replacement[MAX_FM_VERTS];
-       int i,j,k,l,pos,bit,set_pos,set_bit;
-       fmframe_t   *in;
-       qboolean Found;
-       int num_unique;
-       static IntListNode_t *newVertLists[NUM_CLUSTERS];
-       static int newNum_verts[NUM_CLUSTERS];
-       IntListNode_t *current, *next;
-
-       printf( "Optimizing vertices..." );
-
-       memset( vert_used, 0, sizeof( vert_used ) );
-
-       if ( g_skelModel.clustered == true ) {
-               memset( newNum_verts, 0, sizeof( newNum_verts ) );
-               memset( newVertLists, 0, sizeof( newVertLists ) );
-       }
-
-       num_unique = 0;
-
-       // search for common points among all the frames
-       for ( i = 0 ; i < fmheader.num_frames ; i++ )
-       {
-               in = &g_frames[i];
-
-               for ( j = 0; j < fmheader.num_xyz; j++ )
-               {
-                       for ( k = 0,Found = false; k < j; k++ )
-                       {   // starting from the beginning always ensures vert_replacement points to the first point in the array
-                               if ( in->v[j].v[0] == in->v[k].v[0] &&
-                                        in->v[j].v[1] == in->v[k].v[1] &&
-                                        in->v[j].v[2] == in->v[k].v[2] ) {
-                                       Found = true;
-                                       vert_replacement[j] = k;
-                                       break;
-                               }
-
-                       }
-
-                       if ( !Found ) {
-                               if ( !vert_used[j] ) {
-                                       num_unique++;
-                               }
-                               vert_used[j] = true;
-                       }
-               }
-       }
-
-       // recompute the light normals
-       for ( i = 0 ; i < fmheader.num_frames ; i++ )
-       {
-               in = &g_frames[i];
-
-               for ( j = 0; j < fmheader.num_xyz; j++ )
-               {
-                       if ( !vert_used[j] ) {
-                               k = vert_replacement[j];
-
-                               VectorAdd( in->v[j].vnorm.normalsum, in->v[k].vnorm.normalsum, in->v[k].vnorm.normalsum );
-                               in->v[k].vnorm.numnormals += in->v[j].vnorm.numnormals++;
-                       }
-               }
-
-               for ( j = 0 ; j < fmheader.num_xyz ; j++ )
-               {
-                       vec3_t v;
-                       float maxdot;
-                       int maxdotindex;
-                       int c;
-
-                       c = in->v[j].vnorm.numnormals;
-                       if ( !c ) {
-                               Error( "Vertex with no triangles attached" );
-                       }
-
-                       VectorScale( in->v[j].vnorm.normalsum, 1.0 / c, v );
-                       VectorNormalize( v, v );
-
-                       maxdot = -999999.0;
-                       maxdotindex = -1;
-
-                       for ( k = 0 ; k < NUMVERTEXNORMALS ; k++ )
-                       {
-                               float dot;
-
-                               dot = DotProduct( v, avertexnormals[k] );
-                               if ( dot > maxdot ) {
-                                       maxdot = dot;
-                                       maxdotindex = k;
-                               }
-                       }
-
-                       in->v[j].lightnormalindex = maxdotindex;
-               }
-       }
-
-       // create substitution list
-       num_unique = 0;
-       for ( i = 0; i < fmheader.num_xyz; i++ )
-       {
-               if ( vert_used[i] ) {
-                       vert_replacement[i] = num_unique;
-                       num_unique++;
-               }
-               else
-               {
-                       vert_replacement[i] = vert_replacement[vert_replacement[i]];
-               }
-
-               // vert_replacement[i] is the new index, i is the old index
-               // need to add the new index to the cluster list if old index was in it
-               if ( g_skelModel.clustered == true ) {
-                       for ( k = 0; k < numJointsInSkeleton[g_skelModel.type]; ++k )
-                       {
-                               for ( l = 0, current = g_skelModel.vertLists[k];
-                                         l < g_skelModel.new_num_verts[k + 1]; ++l, current = current->next )
-                               {
-                                       if ( current->data == i ) {
-                                               IntListNode_t *current2;
-                                               int m;
-                                               qboolean added = false;
-
-                                               for ( m = 0, current2 = newVertLists[k]; m < newNum_verts[k + 1];
-                                                         ++m, current2 = current2->next )
-                                               {
-                                                       if ( current2->data == vert_replacement[i] ) {
-                                                               added = true;
-                                                               break;
-                                                       }
-                                               }
-
-                                               if ( !added ) {
-                                                       ++newNum_verts[k + 1];
-
-                                                       next = newVertLists[k];
-
-                                                       newVertLists[k] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "OptimizeVertices" );
-                                                       // freed after model write out
-
-                                                       newVertLists[k]->data = vert_replacement[i];
-                                                       newVertLists[k]->next = next;
-                                               }
-                                               break;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       // substitute
-       for ( i = 0 ; i < fmheader.num_frames ; i++ )
-       {
-               in = &g_frames[i];
-
-               for ( j = 0; j < fmheader.num_xyz; j++ )
-               {
-                       in->v[vert_replacement[j]] = in->v[j];
-               }
-
-       }
-
-       for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i )
-       {
-               IntListNode_t *toFree;
-               current = g_skelModel.vertLists[i];
-
-               while ( current )
-               {
-                       toFree = current;
-                       current = current->next;
-                       free( toFree );  // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base
-               }
-
-               g_skelModel.vertLists[i] = newVertLists[i];
-               g_skelModel.new_num_verts[i + 1] = newNum_verts[i + 1];
-       }
-
-#ifndef NDEBUG
-       for ( k = 0; k < numJointsInSkeleton[g_skelModel.type]; ++k )
-       {
-               for ( l = 0, current = g_skelModel.vertLists[k];
-                         l < g_skelModel.new_num_verts[k + 1]; ++l, current = current->next )
-               {
-                       IntListNode_t *current2;
-                       int m;
-
-                       for ( m = l + 1, current2 = current->next; m < newNum_verts[k + 1];
-                                 ++m, current2 = current2->next )
-                       {
-                               if ( current->data == current2->data ) {
-                                       printf( "Warning duplicate vertex:  %d\n", current->data );
-                                       break;
-                               }
-                       }
-               }
-       }
-#endif
-
-       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
-       {   // reset the vert bits
-               memset( pmnodes[i].verts,0,sizeof( pmnodes[i].verts ) );
-       }
-
-       // repleace the master triangle list vertex indexes and update the vert bits for each mesh node
-       for ( i = 0 ; i < fmheader.num_tris ; i++ )
-       {
-               pos = i >> 3;
-               bit = 1 << ( i & 7 );
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       set_bit = set_pos = triangles[i].index_xyz[j] = vert_replacement[triangles[i].index_xyz[j]];
-
-                       set_pos >>= 3;
-                       set_bit = 1 << ( set_bit & 7 );
-
-                       for ( k = 0; k < fmheader.num_mesh_nodes; k++ )
-                       {
-                               if ( !( pmnodes[k].tris[pos] & bit ) ) {
-                                       continue;
-                               }
-                               pmnodes[k].verts[set_pos] |= set_bit;
-                       }
-               }
-       }
-
-       for ( i = 0; i < numcommands; i++ )
-       {
-               j = commands[i];
-               if ( !j ) {
-                       continue;
-               }
-
-               j = abs( j );
-               for ( i++; j; j--,i += 3 )
-               {
-                       commands[i + 2] = vert_replacement[commands[i + 2]];
-               }
-               i--;
-       }
-
-       printf( "Reduced by %d\n",fmheader.num_xyz - num_unique );
-
-       fmheader.num_xyz = num_unique;
-       if ( num_groups ) {
-               // tack on the reference verts to the regular verts
-               if ( g_skelModel.references != REF_NULL ) {
-                       fmframe_t   *in;
-                       int index;
-                       int refnum;
-
-                       if ( RefPointNum <= 0 ) { // Hard-coded labels
-                               refnum = numReferences[g_skelModel.references];
-                       }
-                       else
-                       {   // Labels indicated in QDT
-                               refnum = RefPointNum;
-                       }
-
-
-                       for ( i = 0; i < fmheader.num_frames; ++i )
-                       {
-                               in = &g_frames[i];
-                               index = fmheader.num_xyz;
-
-                               for ( j = 0 ; j < refnum; ++j )
-                               {
-                                       VectorCopy( in->references[j].placement.origin, in->v[index].v );
-                                       index++;
-
-                                       VectorCopy( in->references[j].placement.direction, in->v[index].v );
-                                       index++;
-
-                                       VectorCopy( in->references[j].placement.up, in->v[index].v );
-                                       index++;
-                               }
-                       }
-
-                       fmheader.num_xyz += refnum * 3;
-               }
-
-               // tack on the skeletal joint verts to the regular verts
-               if ( g_skelModel.type != SKEL_NULL ) {
-                       fmframe_t   *in;
-                       int index;
-
-                       for ( i = 0; i < fmheader.num_frames; ++i )
-                       {
-                               in = &g_frames[i];
-                               index = fmheader.num_xyz;
-
-                               for ( j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j )
-                               {
-                                       VectorCopy( in->joints[j].placement.origin, in->v[index].v );
-                                       index++;
-
-                                       VectorCopy( in->joints[j].placement.direction, in->v[index].v );
-                                       index++;
-
-                                       VectorCopy( in->joints[j].placement.up, in->v[index].v );
-                                       index++;
-                               }
-                       }
-
-                       fmheader.num_xyz += numJointsInSkeleton[g_skelModel.type] * 3;
-               }
-
-               CompressFrames();
-       }
-}
-
-
-/*
-   ===============
-   FinishModel
-   ===============
- */
-void FMFinishModel( void ){
-       FILE        *modelouthandle;
-       int i,j,length,tris,verts,bit,pos,total_tris,total_verts;
-       char name[1024];
-       int trans_count;
-
-       if ( !fmheader.num_frames ) {
-               return;
-       }
-
-//
-// copy to release directory tree if doing a release build
-//
-       if ( g_release ) {
-               if ( modelname[0] ) {
-                       sprintf( name, "%s", modelname );
-               }
-               else{
-                       sprintf( name, "%s/tris.fm", cdpartial );
-               }
-               ReleaseFile( name );
-
-               for ( i = 0 ; i < fmheader.num_skins ; i++ )
-               {
-                       ReleaseFile( g_skins[i] );
-               }
-               fmheader.num_frames = 0;
-               return;
-       }
-
-       printf( "\n" );
-
-       trans_count = 0;
-       for ( i = 0; i < fmheader.num_tris; i++ )
-               if ( translucent[i] ) {
-                       trans_count++;
-               }
-
-       if ( !g_no_opimizations ) {
-               OptimizeVertices();
-       }
-
-//
-// write the model output file
-//
-       if ( modelname[0] ) {
-               sprintf( name, "%s%s", g_outputDir, modelname );
-       }
-       else{
-               sprintf( name, "%s/tris.fm", g_outputDir );
-       }
-       printf( "saving to %s\n", name );
-       CreatePath( name );
-       modelouthandle = SafeOpenWrite( name );
-
-       WriteModelFile( modelouthandle );
-
-       printf( "%3dx%3d skin\n", fmheader.skinwidth, fmheader.skinheight );
-       printf( "First frame boundaries:\n" );
-       printf( "       minimum x: %3f\n", g_frames[0].mins[0] );
-       printf( "       maximum x: %3f\n", g_frames[0].maxs[0] );
-       printf( "       minimum y: %3f\n", g_frames[0].mins[1] );
-       printf( "       maximum y: %3f\n", g_frames[0].maxs[1] );
-       printf( "       minimum z: %3f\n", g_frames[0].mins[2] );
-       printf( "       maximum z: %3f\n", g_frames[0].maxs[2] );
-       printf( "%4d vertices\n", fmheader.num_xyz );
-       printf( "%4d triangles, %4d of them translucent\n", fmheader.num_tris, trans_count );
-       printf( "%4d frame\n", fmheader.num_frames );
-       printf( "%4d glverts\n", numglverts );
-       printf( "%4d glcmd\n", fmheader.num_glcmds );
-       printf( "%4d skins\n", fmheader.num_skins );
-       printf( "%4d mesh nodes\n", fmheader.num_mesh_nodes );
-       printf( "wasted pixels: %d / %d (%5.2f Percent)\n",total_skin_pixels - skin_pixels_used,
-                       total_skin_pixels, (double)( total_skin_pixels - skin_pixels_used ) / (double)total_skin_pixels * 100.0 );
-
-       printf( "file size: %d\n", (int)ftell( modelouthandle ) );
-       printf( "---------------------\n" );
-
-       if ( g_verbose ) {
-               if ( fmheader.num_mesh_nodes ) {
-                       total_tris = total_verts = 0;
-                       printf( "Node Name                         Tris Verts\n" );
-                       printf( "--------------------------------- ---- -----\n" );
-                       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
-                       {
-                               tris = 0;
-                               verts = 0;
-                               for ( j = 0; j < MAXTRIANGLES; j++ )
-                               {
-                                       pos = ( j ) >> 3;
-                                       bit = 1 << ( ( j ) & 7 );
-                                       if ( pmnodes[i].tris[pos] & bit ) {
-                                               tris++;
-                                       }
-                               }
-                               for ( j = 0; j < MAX_FM_VERTS; j++ )
-                               {
-                                       pos = ( j ) >> 3;
-                                       bit = 1 << ( ( j ) & 7 );
-                                       if ( pmnodes[i].verts[pos] & bit ) {
-                                               verts++;
-                                       }
-                               }
-
-                               printf( "%-33s %4d %5d\n",pmnodes[i].name,tris,verts );
-
-                               total_tris += tris;
-                               total_verts += verts;
-                       }
-                       printf( "--------------------------------- ---- -----\n" );
-                       printf( "%-33s %4d %5d\n","TOTALS",total_tris,total_verts );
-               }
-       }
-       fclose( modelouthandle );
-
-       // finish writing header file
-       H_printf( "\n" );
-
-       // scale_up is usefull to allow step distances to be adjusted
-       H_printf( "#define MODEL_SCALE\t\t%f\n", scale_up );
-
-       // mesh nodes
-       if ( fmheader.num_mesh_nodes ) {
-               H_printf( "\n" );
-               H_printf( "#define NUM_MESH_NODES\t\t%d\n\n",fmheader.num_mesh_nodes );
-               for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
-               {
-                       strcpy( name, pmnodes[i].name );
-                       strupr( name );
-                       length = strlen( name );
-                       for ( j = 0; j < length; j++ )
-                       {
-                               if ( name[j] == ' ' ) {
-                                       name[j] = '_';
-                               }
-                       }
-                       H_printf( "#define MESH_%s\t\t%d\n", name, i );
-               }
-       }
-
-       fclose( headerouthandle );
-       headerouthandle = NULL;
-       free( pmnodes );
-}
-
-
-/*
-   =================================================================
-
-   ALIAS MODEL DISPLAY LIST GENERATION
-
-   =================================================================
- */
-
-extern int strip_xyz[128];
-extern int strip_st[128];
-extern int strip_tris[128];
-extern int stripcount;
-
-/*
-   ================
-   StripLength
-   ================
- */
-static int  StripLength( int starttri, int startv, int num_tris, int node ){
-       int m1, m2;
-       int st1, st2;
-       int j;
-       fmtriangle_t    *last, *check;
-       int k;
-       int pos, bit;
-
-       used[starttri] = 2;
-
-       last = &triangles[starttri];
-
-       strip_xyz[0] = last->index_xyz[( startv ) % 3];
-       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
-       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
-       strip_st[0] = last->index_st[( startv ) % 3];
-       strip_st[1] = last->index_st[( startv + 1 ) % 3];
-       strip_st[2] = last->index_st[( startv + 2 ) % 3];
-
-       strip_tris[0] = starttri;
-       stripcount = 1;
-
-       m1 = last->index_xyz[( startv + 2 ) % 3];
-       st1 = last->index_st[( startv + 2 ) % 3];
-       m2 = last->index_xyz[( startv + 1 ) % 3];
-       st2 = last->index_st[( startv + 1 ) % 3];
-
-       // look for a matching triangle
-nexttri:
-       for ( j = starttri + 1, check = &triangles[starttri + 1]
-                 ; j < num_tris ; j++, check++ )
-       {
-               pos = j >> 3;
-               bit = 1 << ( j & 7 );
-               if ( !( pmnodes[node].tris[pos] & bit ) ) {
-                       continue;
-               }
-               for ( k = 0 ; k < 3 ; k++ )
-               {
-                       if ( check->index_xyz[k] != m1 ) {
-                               continue;
-                       }
-                       if ( check->index_st[k] != st1 ) {
-                               continue;
-                       }
-                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
-                               continue;
-                       }
-                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
-                               continue;
-                       }
-
-                       // this is the next part of the fan
-
-                       // if we can't use this triangle, this tristrip is done
-                       if ( used[j] || translucent[j] != translucent[starttri] ) {
-                               goto done;
-                       }
-
-                       // the new edge
-                       if ( stripcount & 1 ) {
-                               m2 = check->index_xyz[ ( k + 2 ) % 3 ];
-                               st2 = check->index_st[ ( k + 2 ) % 3 ];
-                       }
-                       else
-                       {
-                               m1 = check->index_xyz[ ( k + 2 ) % 3 ];
-                               st1 = check->index_st[ ( k + 2 ) % 3 ];
-                       }
-
-                       strip_xyz[stripcount + 2] = check->index_xyz[ ( k + 2 ) % 3 ];
-                       strip_st[stripcount + 2] = check->index_st[ ( k + 2 ) % 3 ];
-                       strip_tris[stripcount] = j;
-                       stripcount++;
-
-                       used[j] = 2;
-                       goto nexttri;
-               }
-       }
-done:
-
-       // clear the temp used flags
-       for ( j = starttri + 1 ; j < num_tris ; j++ )
-               if ( used[j] == 2 ) {
-                       used[j] = 0;
-               }
-
-       return stripcount;
-}
-
-
-/*
-   ===========
-   FanLength
-   ===========
- */
-static int  FanLength( int starttri, int startv, int num_tris, int node ){
-       int m1, m2;
-       int st1, st2;
-       int j;
-       fmtriangle_t    *last, *check;
-       int k;
-       int pos, bit;
-
-       used[starttri] = 2;
-
-       last = &triangles[starttri];
-
-       strip_xyz[0] = last->index_xyz[( startv ) % 3];
-       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
-       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
-       strip_st[0] = last->index_st[( startv ) % 3];
-       strip_st[1] = last->index_st[( startv + 1 ) % 3];
-       strip_st[2] = last->index_st[( startv + 2 ) % 3];
-
-       strip_tris[0] = starttri;
-       stripcount = 1;
-
-       m1 = last->index_xyz[( startv + 0 ) % 3];
-       st1 = last->index_st[( startv + 0 ) % 3];
-       m2 = last->index_xyz[( startv + 2 ) % 3];
-       st2 = last->index_st[( startv + 2 ) % 3];
-
-
-       // look for a matching triangle
-nexttri:
-       for ( j = starttri + 1, check = &triangles[starttri + 1]
-                 ; j < num_tris ; j++, check++ )
-       {
-               pos = j >> 3;
-               bit = 1 << ( j & 7 );
-               if ( !( pmnodes[node].tris[pos] & bit ) ) {
-                       continue;
-               }
-               for ( k = 0 ; k < 3 ; k++ )
-               {
-                       if ( check->index_xyz[k] != m1 ) {
-                               continue;
-                       }
-                       if ( check->index_st[k] != st1 ) {
-                               continue;
-                       }
-                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
-                               continue;
-                       }
-                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
-                               continue;
-                       }
-
-                       // this is the next part of the fan
-
-                       // if we can't use this triangle, this tristrip is done
-                       if ( used[j] || translucent[j] != translucent[starttri] ) {
-                               goto done;
-                       }
-
-                       // the new edge
-                       m2 = check->index_xyz[ ( k + 2 ) % 3 ];
-                       st2 = check->index_st[ ( k + 2 ) % 3 ];
-
-                       strip_xyz[stripcount + 2] = m2;
-                       strip_st[stripcount + 2] = st2;
-                       strip_tris[stripcount] = j;
-                       stripcount++;
-
-                       used[j] = 2;
-                       goto nexttri;
-               }
-       }
-done:
-
-       // clear the temp used flags
-       for ( j = starttri + 1 ; j < num_tris ; j++ )
-               if ( used[j] == 2 ) {
-                       used[j] = 0;
-               }
-
-       return stripcount;
-}
-
-
-
-/*
-   ================
-   BuildGlCmds
-
-   Generate a list of trifans or strips
-   for the model, which holds for all frames
-   ================
- */
-static void BuildGlCmds( void ){
-       int i, j, k, l;
-       int startv;
-       float s, t;
-       int len, bestlen, besttype;
-       int best_xyz[1024];
-       int best_st[1024];
-       int best_tris[1024];
-       int type;
-       int trans_check;
-       int bit,pos;
-
-       //
-       // build tristrips
-       //
-       numcommands = 0;
-       numglverts = 0;
-
-
-       for ( l = 0; l < fmheader.num_mesh_nodes; l++ )
-       {
-               memset( used, 0, sizeof( used ) );
-
-               pmnodes[l].start_glcmds = numcommands;
-
-               for ( trans_check = 0; trans_check < 2; trans_check++ )
-               {
-                       for ( i = 0 ; i < fmheader.num_tris ; i++ )
-                       {
-                               pos = i >> 3;
-                               bit = 1 << ( i & 7 );
-                               if ( !( pmnodes[l].tris[pos] & bit ) ) {
-                                       continue;
-                               }
-
-                               // pick an unused triangle and start the trifan
-                               if ( used[i] || trans_check != translucent[i] ) {
-                                       continue;
-                               }
-
-                               bestlen = 0;
-                               for ( type = 0 ; type < 2 ; type++ )
-                               //      type = 1;
-                               {
-                                       for ( startv = 0 ; startv < 3 ; startv++ )
-                                       {
-                                               if ( type == 1 ) {
-                                                       len = StripLength( i, startv, fmheader.num_tris, l );
-                                               }
-                                               else{
-                                                       len = FanLength( i, startv, fmheader.num_tris, l );
-                                               }
-                                               if ( len > bestlen ) {
-                                                       besttype = type;
-                                                       bestlen = len;
-                                                       for ( j = 0 ; j < bestlen + 2 ; j++ )
-                                                       {
-                                                               best_st[j] = strip_st[j];
-                                                               best_xyz[j] = strip_xyz[j];
-                                                       }
-                                                       for ( j = 0 ; j < bestlen ; j++ )
-                                                               best_tris[j] = strip_tris[j];
-                                               }
-                                       }
-                               }
-
-                               // mark the tris on the best strip/fan as used
-                               for ( j = 0 ; j < bestlen ; j++ )
-                                       used[best_tris[j]] = 1;
-
-                               if ( besttype == 1 ) {
-                                       commands[numcommands++] = ( bestlen + 2 );
-                               }
-                               else{
-                                       commands[numcommands++] = -( bestlen + 2 );
-                               }
-
-                               numglverts += bestlen + 2;
-
-                               for ( j = 0 ; j < bestlen + 2 ; j++ )
-                               {
-                                       // emit a vertex into the reorder buffer
-                                       k = best_st[j];
-
-                                       // emit s/t coords into the commands stream
-                                       s = base_st[k].s;
-                                       t = base_st[k].t;
-
-                                       s = ( s  ) / fmheader.skinwidth;
-                                       t = ( t  ) / fmheader.skinheight;
-
-                                       *(float *)&commands[numcommands++] = s;
-                                       *(float *)&commands[numcommands++] = t;
-                                       *(int *)&commands[numcommands++] = best_xyz[j];
-                               }
-                       }
-               }
-               commands[numcommands++] = 0;        // end of list marker
-               pmnodes[l].num_glcmds = numcommands - pmnodes[l].start_glcmds;
-       }
-}
-
-
-/*
-   ===============================================================
-
-   BASE FRAME SETUP
-
-   ===============================================================
- */
-
-
-#define LINE_NORMAL 1
-#define LINE_FAT 2
-#define LINE_DOTTED 3
-
-
-#define ASCII_SPACE 32
-
-int LineType = LINE_NORMAL;
-extern unsigned char pic[SKINPAGE_HEIGHT * SKINPAGE_WIDTH], pic_palette[768];
-unsigned char LineColor = 255;
-int ScaleWidth, ScaleHeight;
-
-
-static char *CharDefs[] =
-{
-       "-------------------------",
-       "-------------------------", // !
-       "-------------------------", // "
-       "-------------------------", // #
-       "-------------------------", // $
-       "-------------------------", // %
-       "-------------------------", // &
-       "--*----*-----------------", // '
-       "-*---*----*----*-----*---", // (
-       "*-----*----*----*---*----", // )
-       "-----*--*--**---**--*--*-", // *
-       "-------------------------", // +
-       "----------------**--**---", // ,
-       "-------------------------", // -
-       "----------------**---**--", // .
-       "-------------------------", // /
-       " *** *  *** * ***  * *** ", // 0
-       "   *   **    *    *    * ",
-       "****     * *** *    *****",
-       "****     * ***     ***** ",
-       "  **  * * *  * *****   * ",
-       "**** *    ****     ***** ",
-       " *** *    **** *   * *** ",
-       "*****    *   *   *    *  ",
-       " *** *   * *** *   * *** ",
-       " *** *   * ****    * *** ", // 9
-       "-**---**--------**---**--", // :
-       "-------------------------", // ;
-       "-------------------------", // <
-       "-------------------------", // =
-       "-------------------------", // >
-       "-------------------------", // ?
-       "-------------------------", // @
-       "-***-*---*******---**---*", // A
-       "****-*---*****-*---*****-",
-       "-*****----*----*-----****",
-       "****-*---**---**---*****-",
-       "******----****-*----*****",
-       "******----****-*----*----",
-       "-*****----*--***---*-****",
-       "*---**---*******---**---*",
-       "-***---*----*----*---***-",
-       "----*----*----**---*-***-",
-       "-*--*-*-*--**---*-*--*--*",
-       "-*----*----*----*----****",
-       "*---***-***-*-**---**---*",
-       "*---***--**-*-**--***---*",
-       "-***-*---**---**---*-***-",
-       "****-*---*****-*----*----",
-       "-***-*---**---*-***----**",
-       "****-*---*****-*-*--*--**",
-       "-*****-----***-----*****-",
-       "*****--*----*----*----*--",
-       "*---**---**---**---******",
-       "*---**---**---*-*-*---*--",
-       "*---**---**-*-***-***---*",
-       "*---*-*-*---*---*-*-*---*",
-       "*---**---*-*-*---*----*--",
-       "*****---*---*---*---*****" // Z
-};
-
-void DrawLine( int x1, int y1, int x2, int y2 ){
-       int dx, dy;
-       int adx, ady;
-       int count;
-       float xfrac, yfrac, xstep, ystep;
-       unsigned sx, sy;
-       float u, v;
-
-       dx = x2 - x1;
-       dy = y2 - y1;
-       adx = abs( dx );
-       ady = abs( dy );
-
-       count = adx > ady ? adx : ady;
-       count++;
-
-       if ( count > 300 ) {
-               printf( "Bad count\n" );
-               return; // don't ever hang up on bad data
-       }
-
-       xfrac = x1;
-       yfrac = y1;
-
-       xstep = (float)dx / count;
-       ystep = (float)dy / count;
-
-       switch ( LineType )
-       {
-       case LINE_NORMAL:
-               do
-               {
-                       if ( xfrac < SKINPAGE_WIDTH && yfrac < SKINPAGE_HEIGHT ) {
-                               pic[(int)yfrac * SKINPAGE_WIDTH + (int)xfrac] = LineColor;
-                       }
-                       xfrac += xstep;
-                       yfrac += ystep;
-                       count--;
-               } while ( count > 0 );
-               break;
-       case LINE_FAT:
-               do
-               {
-                       for ( u = -0.1 ; u <= 0.9 ; u += 0.999 )
-                       {
-                               for ( v = -0.1 ; v <= 0.9 ; v += 0.999 )
-                               {
-                                       sx = xfrac + u;
-                                       sy = yfrac + v;
-                                       if ( sx < SKINPAGE_WIDTH && sy < SKINPAGE_HEIGHT ) {
-                                               pic[sy * SKINPAGE_WIDTH + sx] = LineColor;
-                                       }
-                               }
-                       }
-                       xfrac += xstep;
-                       yfrac += ystep;
-                       count--;
-               } while ( count > 0 );
-               break;
-       case LINE_DOTTED:
-               do
-               {
-                       if ( count & 1 && xfrac < SKINPAGE_WIDTH &&
-                                yfrac < SKINPAGE_HEIGHT ) {
-                               pic[(int)yfrac * SKINPAGE_WIDTH + (int)xfrac] = LineColor;
-                       }
-                       xfrac += xstep;
-                       yfrac += ystep;
-                       count--;
-               } while ( count > 0 );
-               break;
-       default:
-               Error( "Unknown <linetype> %d.\n", LineType );
-       }
-}
-
-//==========================================================================
-//
-// DrawCharacter
-//
-//==========================================================================
-
-static void DrawCharacter( int x, int y, int character ){
-       int r, c;
-       char *def;
-
-       character = toupper( character );
-       if ( character < ASCII_SPACE || character > 'Z' ) {
-               character = ASCII_SPACE;
-       }
-       character -= ASCII_SPACE;
-       for ( def = CharDefs[character], r = 0; r < 5; r++ )
-       {
-               for ( c = 0; c < 5; c++ )
-               {
-                       pic[( y + r ) * SKINPAGE_WIDTH + x + c] = *def++ == '*' ? 255 : 0;
-               }
-       }
-}
-
-//==========================================================================
-//
-// DrawTextChar
-//
-//==========================================================================
-
-void DrawTextChar( int x, int y, char *text ){
-       int c;
-
-       while ( ( c = *text++ ) != '\0' )
-       {
-               DrawCharacter( x, y, c );
-               x += 6;
-       }
-}
-
-
-extern void DrawScreen( float s_scale, float t_scale, float iwidth, float iheight );
-
-//==========================================================================
-// ExtractDigit
-
-static int ExtractDigit( byte *pic, int x, int y ){
-       int i;
-       int r, c;
-       char digString[32];
-       char    *buffer;
-       byte backColor;
-       char    **DigitDefs;
-
-       backColor = pic[( SKINPAGE_HEIGHT - 1 ) * SKINPAGE_WIDTH];
-       DigitDefs = &CharDefs['0' - ASCII_SPACE];
-
-       buffer = digString;
-       for ( r = 0; r < 5; r++ )
-       {
-               for ( c = 0; c < 5; c++ )
-               {
-                       *buffer++ = ( pic[( y + r ) * SKINPAGE_WIDTH + x + c] == backColor ) ? ' ' : '*';
-               }
-       }
-       *buffer = '\0';
-       for ( i = 0; i < 10; i++ )
-       {
-               if ( strcmp( DigitDefs[i], digString ) == 0 ) {
-                       return i;
-               }
-       }
-
-       Error( "Unable to extract scaling info from skin PCX." );
-       return 0;
-}
-
-//==========================================================================
-// ExtractNumber
-
-int ExtractNumber( byte *pic, int x, int y ){
-       return ExtractDigit( pic, x, y ) * 100 + ExtractDigit( pic, x + 6, y ) * 10 + ExtractDigit( pic, x + 12, y );
-}
-
-
-
-
-
-/*
-   ============
-   BuildST
-
-   Builds the triangle_st array for the base frame and
-   fmheader.skinwidth / fmheader.skinheight
-
-   FIXME: allow this to be loaded from a file for
-   arbitrary mappings
-   ============
- */
-static void BuildST( triangle_t *ptri, int numtri, qboolean DrawSkin ){
-       int backface_flag;
-       int i, j;
-       int width, height, iwidth, iheight, swidth;
-       float basex, basey;
-       float scale;
-       vec3_t mins, maxs;
-       float       *pbasevert;
-       vec3_t vtemp1, vtemp2, normal;
-       float s_scale, t_scale;
-       float scWidth;
-       float scHeight;
-       int skinwidth;
-       int skinheight;
-
-       //
-       // find bounds of all the verts on the base frame
-       //
-       ClearBounds( mins, maxs );
-       backface_flag = false;
-
-       if ( ptri[0].HasUV ) { // if we have the uv already, we don't want to double up or scale
-               iwidth = ScaleWidth;
-               iheight = ScaleHeight;
-
-               t_scale = s_scale = 1.0;
-       }
-       else
-       {
-               for ( i = 0 ; i < numtri ; i++ )
-                       for ( j = 0 ; j < 3 ; j++ )
-                               AddPointToBounds( ptri[i].verts[j], mins, maxs );
-
-               for ( i = 0 ; i < 3 ; i++ )
-               {
-                       mins[i] = floor( mins[i] );
-                       maxs[i] = ceil( maxs[i] );
-               }
-
-               width = maxs[0] - mins[0];
-               height = maxs[2] - mins[2];
-
-               for ( i = 0 ; i < numtri ; i++ )
-               {
-                       VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
-                       VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
-                       CrossProduct( vtemp1, vtemp2, normal );
-
-                       if ( normal[1] > 0 ) {
-                               backface_flag = true;
-                               break;
-                       }
-               }
-               scWidth = ScaleWidth * SCALE_ADJUST_FACTOR;
-               if ( backface_flag ) {  //we are doubling
-                       scWidth /= 2;
-               }
-
-               scHeight = ScaleHeight * SCALE_ADJUST_FACTOR;
-
-               scale = scWidth / width;
-
-               if ( height * scale >= scHeight ) {
-                       scale = scHeight / height;
-               }
-
-               iwidth = ceil( width * scale ) + 4;
-               iheight = ceil( height * scale ) + 4;
-
-               s_scale = (float)( iwidth - 4 ) / width;
-               t_scale = (float)( iheight - 4 ) / height;
-               t_scale = s_scale;
-       }
-       if ( DrawSkin ) {
-               if ( backface_flag ) {
-                       DrawScreen( s_scale, t_scale, iwidth * 2, iheight );
-               }
-               else{
-                       DrawScreen( s_scale, t_scale, iwidth, iheight );
-               }
-       }
-       if ( backface_flag ) {
-               skinwidth = iwidth * 2;
-       }
-       else{
-               skinwidth = iwidth;
-       }
-       skinheight = iheight;
-
-
-/*     if (!g_fixedwidth)
-    {  // old style
-        scale = 8;
-        if (width*scale >= 150)
-            scale = 150.0 / width;
-        if (height*scale >= 190)
-            scale = 190.0 / height;
-
-        s_scale = t_scale = scale;
-
-        iwidth = ceil(width*s_scale);
-        iheight = ceil(height*t_scale);
-
-        iwidth += 4;
-        iheight += 4;
-    }
-    else
-    {  // new style
-        iwidth = g_fixedwidth / 2;
-        iheight = g_fixedheight;
-
-        s_scale = (float)(iwidth-4) / width;
-        t_scale = (float)(iheight-4) / height;
-    }*/
-
-//
-// determine which side of each triangle to map the texture to
-//
-       basey = 2;
-       for ( i = 0 ; i < numtri ; i++ )
-       {
-               if ( ptri[i].HasUV ) {
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               triangle_st[i][j][0] = Q_rint( ptri[i].uv[j][0] * skinwidth );
-                               triangle_st[i][j][1] = Q_rint( ( 1.0f - ptri[i].uv[j][1] ) * skinheight );
-                       }
-               }
-               else
-               {
-                       VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
-                       VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
-                       CrossProduct( vtemp1, vtemp2, normal );
-
-                       if ( normal[1] > 0 ) {
-                               basex = iwidth + 2;
-                       }
-                       else
-                       {
-                               basex = 2;
-                       }
-
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               pbasevert = ptri[i].verts[j];
-
-                               triangle_st[i][j][0] = Q_rint( ( pbasevert[0] - mins[0] ) * s_scale + basex );
-                               triangle_st[i][j][1] = Q_rint( ( maxs[2] - pbasevert[2] ) * t_scale + basey );
-                       }
-               }
-
-               if ( DrawSkin ) {
-                       DrawLine( triangle_st[i][0][0], triangle_st[i][0][1],
-                                         triangle_st[i][1][0], triangle_st[i][1][1] );
-                       DrawLine( triangle_st[i][1][0], triangle_st[i][1][1],
-                                         triangle_st[i][2][0], triangle_st[i][2][1] );
-                       DrawLine( triangle_st[i][2][0], triangle_st[i][2][1],
-                                         triangle_st[i][0][0], triangle_st[i][0][1] );
-               }
-       }
-
-// make the width a multiple of 4; some hardware requires this, and it ensures
-// dword alignment for each scan
-
-       swidth = iwidth;
-       if ( backface_flag ) {
-               swidth *= 2;
-       }
-       fmheader.skinwidth = ( swidth + 3 ) & ~3;
-       fmheader.skinheight = iheight;
-
-       skin_width = iwidth;
-       skin_height = iheight;
-}
-
-
-static void BuildNewST( triangle_t *ptri, int numtri, qboolean DrawSkin ){
-       int i, j;
-
-       for ( i = 0 ; i < numtri ; i++ )
-       {
-               if ( ptri[i].HasUV ) {
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               triangle_st[i][j][0] = Q_rint( ptri[i].uv[j][0] * ( ScaleWidth - 1 ) );
-                               triangle_st[i][j][1] = Q_rint( ( 1.0f - ptri[i].uv[j][1] ) * ( ScaleHeight - 1 ) );
-                       }
-               }
-
-               if ( DrawSkin ) {
-                       DrawLine( triangle_st[i][0][0], triangle_st[i][0][1],
-                                         triangle_st[i][1][0], triangle_st[i][1][1] );
-                       DrawLine( triangle_st[i][1][0], triangle_st[i][1][1],
-                                         triangle_st[i][2][0], triangle_st[i][2][1] );
-                       DrawLine( triangle_st[i][2][0], triangle_st[i][2][1],
-                                         triangle_st[i][0][0], triangle_st[i][0][1] );
-               }
-       }
-
-// make the width a multiple of 4; some hardware requires this, and it ensures
-// dword alignment for each scan
-
-       fmheader.skinwidth = ( ScaleWidth + 3 ) & ~3;
-       fmheader.skinheight = ScaleHeight;
-
-       skin_width = ScaleWidth;
-       skin_height = ScaleHeight;
-}
-
-
-
-
-byte            *BasePalette;
-byte            *BasePixels,*TransPixels;
-int BaseWidth, BaseHeight, TransWidth, TransHeight;
-qboolean BaseTrueColor;
-static qboolean SetPixel = false;
-
-int CheckTransRecursiveTri( int *lp1, int *lp2, int *lp3 ){
-       int     *temp;
-       int d;
-       int new[2];
-
-       d = lp2[0] - lp1[0];
-       if ( d < -1 || d > 1 ) {
-               goto split;
-       }
-       d = lp2[1] - lp1[1];
-       if ( d < -1 || d > 1 ) {
-               goto split;
-       }
-
-       d = lp3[0] - lp2[0];
-       if ( d < -1 || d > 1 ) {
-               goto split2;
-       }
-       d = lp3[1] - lp2[1];
-       if ( d < -1 || d > 1 ) {
-               goto split2;
-       }
-
-       d = lp1[0] - lp3[0];
-       if ( d < -1 || d > 1 ) {
-               goto split3;
-       }
-       d = lp1[1] - lp3[1];
-       if ( d < -1 || d > 1 ) {
-split3:
-               temp = lp1;
-               lp1 = lp3;
-               lp3 = lp2;
-               lp2 = temp;
-
-               goto split;
-       }
-
-       return 0;           // entire tri is filled
-
-split2:
-       temp = lp1;
-       lp1 = lp2;
-       lp2 = lp3;
-       lp3 = temp;
-
-split:
-// split this edge
-       new[0] = ( lp1[0] + lp2[0] ) >> 1;
-       new[1] = ( lp1[1] + lp2[1] ) >> 1;
-
-// draw the point if splitting a leading edge
-       if ( lp2[1] > lp1[1] ) {
-               goto nodraw;
-       }
-       if ( ( lp2[1] == lp1[1] ) && ( lp2[0] < lp1[0] ) ) {
-               goto nodraw;
-       }
-
-       if ( SetPixel ) {
-               assert( ( new[1] * BaseWidth ) + new[0] < BaseWidth * BaseHeight );
-
-               if ( BaseTrueColor ) {
-                       BasePixels[( ( new[1] * BaseWidth ) + new[0] ) * 4] = 1;
-               }
-               else
-               {
-                       BasePixels[( new[1] * BaseWidth ) + new[0]] = 1;
-               }
-       }
-       else
-       {
-               if ( TransPixels ) {
-                       if ( TransPixels[( new[1] * TransWidth ) + new[0]] != 255 ) {
-                               return 1;
-                       }
-               }
-               else if ( BaseTrueColor ) {
-                       if ( BasePixels[( ( ( new[1] * BaseWidth ) + new[0] ) * 4 ) + 3] != 255 ) {
-                               return 1;
-                       }
-               }
-               else
-               {
-//                     pixel = BasePixels[(new[1]*BaseWidth) + new[0]];
-               }
-       }
-
-nodraw:
-// recursively continue
-       if ( CheckTransRecursiveTri( lp3, lp1, new ) ) {
-               return 1;
-       }
-
-       return CheckTransRecursiveTri( lp3, new, lp2 );
-}
-
-static void ReplaceClusterIndex( int newIndex, int oldindex, int **clusters,
-                                                                IntListNode_t **vertLists, int *num_verts, int *new_num_verts ){
-       int i, j;
-       IntListNode_t *next;
-
-       for ( j = 0; j < numJointsInSkeleton[g_skelModel.type]; ++j )
-       {
-               if ( !clusters[j] ) {
-                       continue;
-               }
-
-               for ( i = 0; i < num_verts[j + 1]; ++i )
-               {
-                       if ( clusters[j][i] == oldindex ) {
-                               ++new_num_verts[j + 1];
-
-                               next = vertLists[j];
-
-                               vertLists[j] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "ReplaceClusterIndex" );
-                               // Currently freed in WriteJointedModelFile only
-
-                               vertLists[j]->data = newIndex;
-                               vertLists[j]->next = next;
-                       }
-               }
-       }
-}
-
-#define FUDGE_EPSILON   0.002
-
-qboolean VectorFudgeCompare( vec3_t v1, vec3_t v2 ){
-       int i;
-
-       for ( i = 0 ; i < 3 ; i++ )
-               if ( fabs( v1[i] - v2[i] ) > FUDGE_EPSILON ) {
-                       return false;
-               }
-
-       return true;
-}
-
-/*
-   =================
-   Cmd_Base
-   =================
- */
-void Cmd_FMBase( qboolean GetST ){
-       triangle_t  *ptri, *st_tri;
-       int num_st_tris;
-       int i, j, k, l;
-       int x,y,z;
-//     int                     time1;
-       char file1[1024],file2[1024],trans_file[1024], stfile[1024], extension[256];
-       vec3_t base_xyz[MAX_FM_VERTS];
-       FILE        *FH;
-       int pos,bit;
-       qboolean NewSkin;
-
-       GetScriptToken( false );
-
-       if ( g_skipmodel || g_release || g_archive ) {
-               return;
-       }
-
-       printf( "---------------------\n" );
-       sprintf( file1, "%s/%s.%s", cdarchive, token, trifileext );
-       printf( "%s ", file1 );
-
-       ExpandPathAndArchive( file1 );
-
-       // Use the input filepath for this one.
-       sprintf( file1, "%s/%s", cddir, token );
-
-//     time1 = FileTime (file1);
-//     if (time1 == -1)
-//             Error ("%s doesn't exist", file1);
-
-//
-// load the base triangles
-//
-       if ( do3ds ) {
-               Load3DSTriangleList( file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes );
-       }
-       else{
-               LoadTriangleList( file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes );
-       }
-
-       if ( g_ignoreTriUV ) {
-               for ( i = 0; i < fmheader.num_tris; i++ )
-               {
-                       ptri[i].HasUV = 0;
-               }
-       }
-
-       GetScriptToken( false );
-       sprintf( file2, "%s/%s", cddir, token );
-       sprintf( trans_file, "%s/!%s_a.pcx", cddir, token );
-
-       ExtractFileExtension( file2, extension );
-       if ( extension[0] == 0 ) {
-               strcat( file2, ".pcx" );
-       }
-       printf( "skin: %s\n", file2 );
-
-       BaseTrueColor = LoadAnyImage( file2, &BasePixels, &BasePalette, &BaseWidth, &BaseHeight );
-
-       NewSkin = false;
-       if ( BaseWidth != SKINPAGE_WIDTH || BaseHeight != SKINPAGE_HEIGHT ) {
-               if ( g_allow_newskin ) {
-                       ScaleWidth = BaseWidth;
-                       ScaleHeight = BaseHeight;
-                       NewSkin = true;
-               }
-               else
-               {
-                       Error( "Invalid skin page size: (%d,%d) should be (%d,%d)",
-                                  BaseWidth,BaseHeight,SKINPAGE_WIDTH,SKINPAGE_HEIGHT );
-               }
-       }
-       else if ( !BaseTrueColor ) {
-               ScaleWidth = (float)ExtractNumber( BasePixels, ENCODED_WIDTH_X,
-                                                                                  ENCODED_WIDTH_Y );
-               ScaleHeight = (float)ExtractNumber( BasePixels, ENCODED_HEIGHT_X,
-                                                                                       ENCODED_HEIGHT_Y );
-       }
-       else
-       {
-               Error( "Texture coordinates not supported on true color image" );
-       }
-
-       if ( GetST ) {
-               GetScriptToken( false );
-
-               sprintf( stfile, "%s/%s.%s", cdarchive, token, trifileext );
-               printf( "ST: %s ", stfile );
-
-               sprintf( stfile, "%s/%s", cddir, token );
-
-               if ( do3ds ) {
-                       Load3DSTriangleList( stfile, &st_tri, &num_st_tris, NULL, NULL );
-               }
-               else{
-                       LoadTriangleList( stfile, &st_tri, &num_st_tris, NULL, NULL );
-               }
-
-               if ( num_st_tris != fmheader.num_tris ) {
-                       Error( "num st tris mismatch: st %d / base %d", num_st_tris, fmheader.num_tris );
-               }
-
-               printf( "   matching triangles...\n" );
-               for ( i = 0; i < fmheader.num_tris; i++ )
-               {
-                       k = -1;
-                       for ( j = 0; j < num_st_tris; j++ )
-                       {
-                               for ( x = 0; x < 3; x++ )
-                               {
-                                       for ( y = 0; y < 3; y++ )
-                                       {
-                                               if ( x == y ) {
-                                                       continue;
-                                               }
-                                               for ( z = 0; z < 3; z++ )
-                                               {
-                                                       if ( z == x || z == y ) {
-                                                               continue;
-                                                       }
-
-                                                       if ( VectorFudgeCompare( ptri[i].verts[0], st_tri[j].verts[x] ) &&
-                                                                VectorFudgeCompare( ptri[i].verts[1], st_tri[j].verts[y] ) &&
-                                                                VectorFudgeCompare( ptri[i].verts[2], st_tri[j].verts[z] ) ) {
-                                                               if ( k == -1 ) {
-                                                                       k = j;
-                                                                       ptri[i].HasUV = st_tri[k].HasUV;
-                                                                       ptri[i].uv[0][0] = st_tri[k].uv[x][0];
-                                                                       ptri[i].uv[0][1] = st_tri[k].uv[x][1];
-                                                                       ptri[i].uv[1][0] = st_tri[k].uv[y][0];
-                                                                       ptri[i].uv[1][1] = st_tri[k].uv[y][1];
-                                                                       ptri[i].uv[2][0] = st_tri[k].uv[z][0];
-                                                                       ptri[i].uv[2][1] = st_tri[k].uv[z][1];
-                                                                       x = y = z = 999;
-                                                               }
-                                                               else if ( k != j ) {
-                                                                       printf( "Duplicate triangle %d found in st file: %d and %d\n",i,k,j );
-                                                                       printf( "   (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f)\n",
-                                                                                       ptri[i].verts[0][0],ptri[i].verts[0][1],ptri[i].verts[0][2],
-                                                                                       ptri[i].verts[1][0],ptri[i].verts[1][1],ptri[i].verts[1][2],
-                                                                                       ptri[i].verts[2][0],ptri[i].verts[2][1],ptri[i].verts[2][2] );
-                                                                       printf( "   (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f)\n",
-                                                                                       st_tri[k].verts[0][0],st_tri[k].verts[0][1],st_tri[k].verts[0][2],
-                                                                                       st_tri[k].verts[1][0],st_tri[k].verts[1][1],st_tri[k].verts[1][2],
-                                                                                       st_tri[k].verts[2][0],st_tri[k].verts[2][1],st_tri[k].verts[2][2] );
-                                                                       printf( "   (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f) (%0.3f %0.3f %0.3f)\n",
-                                                                                       st_tri[j].verts[0][0],st_tri[j].verts[0][1],st_tri[j].verts[0][2],
-                                                                                       st_tri[j].verts[1][0],st_tri[j].verts[1][1],st_tri[j].verts[1][2],
-                                                                                       st_tri[j].verts[2][0],st_tri[j].verts[2][1],st_tri[j].verts[2][2] );
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if ( k == -1 ) {
-                               printf( "No matching triangle %d\n",i );
-                       }
-               }
-               free( st_tri );
-       }
-
-//
-// get the ST values
-//
-       if ( ptri && ptri[0].HasUV ) {
-               if ( !NewSkin ) {
-                       Error( "Base has UVs with old style skin page\nMaybe you want to use -ignoreUV" );
-               }
-               else
-               {
-                       BuildNewST( ptri, fmheader.num_tris, false );
-               }
-       }
-       else
-       {
-               if ( NewSkin ) {
-                       Error( "Base has new style skin without UVs" );
-               }
-               else
-               {
-                       BuildST( ptri, fmheader.num_tris, false );
-               }
-       }
-
-       TransPixels = NULL;
-       if ( !BaseTrueColor ) {
-               FH = fopen( trans_file,"rb" );
-               if ( FH ) {
-                       fclose( FH );
-                       Load256Image( trans_file, &TransPixels, NULL, &TransWidth, &TransHeight );
-                       if ( TransWidth != fmheader.skinwidth || TransHeight != fmheader.skinheight ) {
-                               Error( "source image %s dimensions (%d,%d) are not the same as alpha image (%d,%d)\n",file2,fmheader.skinwidth,fmheader.skinheight,TransWidth,TransHeight );
-                       }
-               }
-       }
-
-//
-// run through all the base triangles, storing each unique vertex in the
-// base vertex list and setting the indirect triangles to point to the base
-// vertices
-//
-       for ( l = 0; l < fmheader.num_mesh_nodes; l++ )
-       {
-               for ( i = 0 ; i < fmheader.num_tris ; i++ )
-               {
-                       pos = i >> 3;
-                       bit = 1 << ( i & 7 );
-                       if ( !( pmnodes[l].tris[pos] & bit ) ) {
-                               continue;
-                       }
-
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               // get the xyz index
-                               for ( k = 0 ; k < fmheader.num_xyz ; k++ )
-                               {
-                                       if ( VectorCompare( ptri[i].verts[j], base_xyz[k] ) ) {
-                                               break;  // this vertex is already in the base vertex list
-                                       }
-                               }
-
-                               if ( k == fmheader.num_xyz ) { // new index
-                                       VectorCopy( ptri[i].verts[j], base_xyz[fmheader.num_xyz] );
-
-                                       if ( pmnodes[l].clustered == true ) {
-                                               ReplaceClusterIndex( k, ptri[i].indicies[j], (int **)&pmnodes[l].clusters, (IntListNode_t **)&g_skelModel.vertLists, (int *)&pmnodes[l].num_verts, (int *)&g_skelModel.new_num_verts );
-                                       }
-
-                                       fmheader.num_xyz++;
-                               }
-
-                               pos = k >> 3;
-                               bit = 1 << ( k & 7 );
-                               pmnodes[l].verts[pos] |= bit;
-
-                               triangles[i].index_xyz[j] = k;
-
-                               // get the st index
-                               for ( k = 0 ; k < fmheader.num_st ; k++ )
-                               {
-                                       if ( triangle_st[i][j][0] == base_st[k].s
-                                                && triangle_st[i][j][1] == base_st[k].t ) {
-                                               break;  // this vertex is already in the base vertex list
-                                       }
-                               }
-
-                               if ( k == fmheader.num_st ) { // new index
-                                       base_st[fmheader.num_st].s = triangle_st[i][j][0];
-                                       base_st[fmheader.num_st].t = triangle_st[i][j][1];
-                                       fmheader.num_st++;
-                               }
-
-                               triangles[i].index_st[j] = k;
-                       }
-
-                       if ( TransPixels || BaseTrueColor ) {
-                               translucent[i] = CheckTransRecursiveTri( triangle_st[i][0], triangle_st[i][1], triangle_st[i][2] );
-                       }
-                       else
-                       {
-                               translucent[i] = false;
-                       }
-               }
-       }
-
-       if ( !BaseTrueColor ) {
-               SetPixel = true;
-               memset( BasePixels,0,BaseWidth * BaseHeight );
-               for ( i = 0 ; i < fmheader.num_tris ; i++ )
-               {
-                       CheckTransRecursiveTri( triangle_st[i][0], triangle_st[i][1], triangle_st[i][2] );
-               }
-               SetPixel = false;
-
-               skin_pixels_used = 0;
-               for ( i = 0; i < fmheader.skinheight; i++ )
-               {
-                       for ( j = 0; j < fmheader.skinwidth; j++ )
-                       {
-                               skin_pixels_used += BasePixels[( i * BaseWidth ) + j];
-                       }
-               }
-               total_skin_pixels = fmheader.skinheight * fmheader.skinwidth;
-       }
-       else
-       {
-               SetPixel = true;
-               memset( BasePixels,0,BaseWidth * BaseHeight * 4 );
-               for ( i = 0 ; i < fmheader.num_tris ; i++ )
-               {
-                       CheckTransRecursiveTri( triangle_st[i][0], triangle_st[i][1], triangle_st[i][2] );
-               }
-               SetPixel = false;
-
-               skin_pixels_used = 0;
-               for ( i = 0; i < fmheader.skinheight; i++ )
-               {
-                       for ( j = 0; j < fmheader.skinwidth; j++ )
-                       {
-                               skin_pixels_used += BasePixels[( ( i * BaseWidth ) + j ) * 4];
-                       }
-               }
-               total_skin_pixels = fmheader.skinheight * fmheader.skinwidth;
-       }
-
-       // build triangle strips / fans
-       BuildGlCmds();
-
-       if ( TransPixels ) {
-               free( TransPixels );
-       }
-       free( BasePixels );
-       if ( BasePalette ) {
-               free( BasePalette );
-       }
-       free( ptri );
-}
-
-void Cmd_FMNodeOrder( void ){
-       mesh_node_t *newnodes, *pos;
-       int i,j;
-
-       if ( !pmnodes ) {
-               Error( "Base has not been established yet" );
-       }
-
-       pos = newnodes = malloc( sizeof( mesh_node_t ) * fmheader.num_mesh_nodes );
-
-       for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
-       {
-               GetScriptToken( false );
-
-               for ( j = 0; j < fmheader.num_mesh_nodes; j++ )
-               {
-                       if ( strcmpi( pmnodes[j].name, token ) == 0 ) {
-                               *pos = pmnodes[j];
-                               pos++;
-                               break;
-                       }
-               }
-               if ( j >= fmheader.num_mesh_nodes ) {
-                       Error( "Node '%s' not in base list!\n", token );
-               }
-       }
-
-       free( pmnodes );
-       pmnodes = newnodes;
-}
-
-//===============================================================
-
-extern char *FindFrameFile( char *frame );
-
-
-/*
-   ===============
-   GrabFrame
-   ===============
- */
-void GrabFrame( char *frame ){
-       triangle_t      *ptri;
-       int i, j;
-       fmtrivert_t     *ptrivert;
-       int num_tris;
-       char file1[1024];
-       fmframe_t       *fr;
-       int index_xyz;
-       char            *framefile;
-
-       // the frame 'run1' will be looked for as either
-       // run.1 or run1.tri, so the new alias sequence save
-       // feature an be used
-       framefile = FindFrameFile( frame );
-
-       sprintf( file1, "%s/%s", cdarchive, framefile );
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s",cddir, framefile );
-
-       printf( "grabbing %s  ", file1 );
-
-       if ( fmheader.num_frames >= MAX_FM_FRAMES ) {
-               Error( "fmheader.num_frames >= MAX_FM_FRAMES" );
-       }
-       fr = &g_frames[fmheader.num_frames];
-       fmheader.num_frames++;
-
-       strcpy( fr->name, frame );
-
-//
-// load the frame
-//
-       if ( do3ds ) {
-               Load3DSTriangleList( file1, &ptri, &num_tris, NULL, NULL );
-       }
-       else{
-               LoadTriangleList( file1, &ptri, &num_tris, NULL, NULL );
-       }
-
-       if ( num_tris != fmheader.num_tris ) {
-               Error( "%s: number of triangles (%d) doesn't match base frame (%d)\n", file1, num_tris, fmheader.num_tris );
-       }
-
-//
-// allocate storage for the frame's vertices
-//
-       ptrivert = fr->v;
-
-       for ( i = 0 ; i < fmheader.num_xyz ; i++ )
-       {
-               ptrivert[i].vnorm.numnormals = 0;
-               VectorClear( ptrivert[i].vnorm.normalsum );
-       }
-       ClearBounds( fr->mins, fr->maxs );
-
-//
-// store the frame's vertices in the same order as the base. This assumes the
-// triangles and vertices in this frame are in exactly the same order as in the
-// base
-//
-       for ( i = 0 ; i < num_tris ; i++ )
-       {
-               vec3_t vtemp1, vtemp2, normal;
-               float ftemp;
-
-               VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
-               VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
-               CrossProduct( vtemp1, vtemp2, normal );
-
-               VectorNormalize( normal, normal );
-
-               // rotate the normal so the model faces down the positive x axis
-               ftemp = normal[0];
-               normal[0] = -normal[1];
-               normal[1] = ftemp;
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       index_xyz = triangles[i].index_xyz[j];
-
-                       // rotate the vertices so the model faces down the positive x axis
-                       // also adjust the vertices to the desired origin
-                       ptrivert[index_xyz].v[0] = ( ( -ptri[i].verts[j][1] ) * scale_up ) +
-                                                                          adjust[0];
-                       ptrivert[index_xyz].v[1] = ( ptri[i].verts[j][0] * scale_up ) +
-                                                                          adjust[1];
-                       ptrivert[index_xyz].v[2] = ( ptri[i].verts[j][2] * scale_up ) +
-                                                                          adjust[2];
-
-                       AddPointToBounds( ptrivert[index_xyz].v, fr->mins, fr->maxs );
-
-                       VectorAdd( ptrivert[index_xyz].vnorm.normalsum, normal, ptrivert[index_xyz].vnorm.normalsum );
-                       ptrivert[index_xyz].vnorm.numnormals++;
-               }
-       }
-
-//
-// calculate the vertex normals, match them to the template list, and store the
-// index of the best match
-//
-       for ( i = 0 ; i < fmheader.num_xyz ; i++ )
-       {
-               int j;
-               vec3_t v;
-               float maxdot;
-               int maxdotindex;
-               int c;
-
-               c = ptrivert[i].vnorm.numnormals;
-               if ( !c ) {
-                       Error( "Vertex with no triangles attached" );
-               }
-
-               VectorScale( ptrivert[i].vnorm.normalsum, 1.0 / c, v );
-               VectorNormalize( v, v );
-
-               maxdot = -999999.0;
-               maxdotindex = -1;
-
-               for ( j = 0 ; j < NUMVERTEXNORMALS ; j++ )
-               {
-                       float dot;
-
-                       dot = DotProduct( v, avertexnormals[j] );
-                       if ( dot > maxdot ) {
-                               maxdot = dot;
-                               maxdotindex = j;
-                       }
-               }
-
-               ptrivert[i].lightnormalindex = maxdotindex;
-       }
-
-       free( ptri );
-}
-
-/*
-   ===============
-   Cmd_Frame
-   ===============
- */
-void Cmd_FMFrame( void ){
-       while ( ScriptTokenAvailable() )
-       {
-               GetScriptToken( false );
-               if ( g_skipmodel ) {
-                       continue;
-               }
-               if ( g_release || g_archive ) {
-                       fmheader.num_frames = 1;    // don't skip the writeout
-                       continue;
-               }
-
-               H_printf( "#define FRAME_%-16s\t%i\n", token, fmheader.num_frames );
-
-               if ( ( g_skelModel.type != SKEL_NULL ) || ( g_skelModel.references != REF_NULL ) ) {
-                       GrabModelTransform( token );
-               }
-
-               GrabFrame( token );
-
-               if ( g_skelModel.type != SKEL_NULL ) {
-                       GrabSkeletalFrame( token );
-               }
-
-               if ( g_skelModel.references != REF_NULL ) {
-                       GrabReferencedFrame( token );
-               }
-
-               // need to add the up and dir points to the frame bounds here
-               // using AddPointToBounds (ptrivert[index_xyz].v, fr->mins, fr->maxs);
-               // then remove fudge in determining scale on frame write out
-       }
-}
-
-/*
-   ===============
-   Cmd_Skin
-
-   Skins aren't actually stored in the file, only a reference
-   is saved out to the header file.
-   ===============
- */
-void Cmd_FMSkin( void ){
-       byte        *palette;
-       byte        *pixels;
-       int width, height;
-       byte        *cropped;
-       int y;
-       char name[1024], savename[1024], transname[1024], extension[256];
-       miptex32_t  *qtex32;
-       int size;
-       FILE        *FH;
-       qboolean TrueColor;
-
-       GetScriptToken( false );
-
-       if ( fmheader.num_skins == MAX_FM_SKINS ) {
-               Error( "fmheader.num_skins == MAX_FM_SKINS" );
-       }
-
-       if ( g_skipmodel ) {
-               return;
-       }
-
-       sprintf( name, "%s/%s", cdarchive, token );
-       strcpy( name, ExpandPathAndArchive( name ) );
-//     sprintf (name, "%s/%s.lbm", cddir, token);
-
-       if ( ScriptTokenAvailable() ) {
-               GetScriptToken( false );
-               sprintf( g_skins[fmheader.num_skins], "!%s", token );
-               sprintf( savename, "%s!%s", g_outputDir, token );
-               sprintf( transname, "%s!%s_a.pcx", gamedir, token );
-       }
-       else
-       {
-               sprintf( g_skins[fmheader.num_skins], "%s/!%s", cdpartial, token );
-               sprintf( savename, "%s/!%s", g_outputDir, token );
-               sprintf( transname, "%s/!%s_a.pcx", cddir, token );
-       }
-
-       fmheader.num_skins++;
-
-       if ( g_skipmodel || g_release || g_archive ) {
-               return;
-       }
-
-       // load the image
-       printf( "loading %s\n", name );
-       ExtractFileExtension( name, extension );
-       if ( extension[0] == 0 ) {
-               strcat( name, ".pcx" );
-       }
-
-
-       TrueColor = LoadAnyImage( name, &pixels, &palette, &width, &height );
-//     RemapZero (pixels, palette, width, height);
-
-       // crop it to the proper size
-
-       if ( !TrueColor ) {
-               cropped = (byte *) SafeMalloc( fmheader.skinwidth * fmheader.skinheight, "Cmd_FMSkin" );
-               for ( y = 0 ; y < fmheader.skinheight ; y++ )
-               {
-                       memcpy( cropped + y * fmheader.skinwidth,
-                                       pixels + y * width, fmheader.skinwidth );
-               }
-
-               TransPixels = NULL;
-               FH = fopen( transname,"rb" );
-               if ( FH ) {
-                       fclose( FH );
-
-                       strcat( g_skins[fmheader.num_skins - 1],".pcx" );
-                       strcat( savename,".pcx" );
-
-                       // save off the new image
-                       printf( "saving %s\n", savename );
-                       CreatePath( savename );
-                       WritePCXfile( savename, cropped, fmheader.skinwidth, fmheader.skinheight, palette );
-               }
-               else
-               {
-       #if 1
-                       miptex_t    *qtex;
-                       qtex = CreateMip( cropped, fmheader.skinwidth, fmheader.skinheight, palette, &size, true );
-
-                       strcat( g_skins[fmheader.num_skins - 1],".m8" );
-                       strcat( savename,".m8" );
-
-                       printf( "saving %s\n", savename );
-                       CreatePath( savename );
-                       SaveFile( savename, (byte *)qtex, size );
-                       free( qtex );
-       #else
-                       strcat( g_skins[fmheader.num_skins - 1],".pcx" );
-                       strcat( savename,".pcx" );
-
-                       // save off the new image
-                       printf( "saving %s\n", savename );
-                       CreatePath( savename );
-                       WritePCXfile( savename, cropped, fmheader.skinwidth, fmheader.skinheight, palette );
-       #endif
-               }
-       }
-       else
-       {
-               cropped = (byte *) SafeMalloc( fmheader.skinwidth * fmheader.skinheight * 4, "Cmd_FMSkin" );
-               for ( y = 0 ; y < fmheader.skinheight ; y++ )
-               {
-                       memcpy( cropped + ( ( y * fmheader.skinwidth ) * 4 ), pixels + ( y * width * 4 ), fmheader.skinwidth * 4 );
-               }
-
-               qtex32 = CreateMip32( (unsigned *)cropped, fmheader.skinwidth, fmheader.skinheight, &size, true );
-
-               StripExtension( g_skins[fmheader.num_skins - 1] );
-               strcat( g_skins[fmheader.num_skins - 1],".m32" );
-               StripExtension( savename );
-               strcat( savename,".m32" );
-
-               printf( "saving %s\n", savename );
-               CreatePath( savename );
-               SaveFile( savename, (byte *)qtex32, size );
-       }
-
-       free( pixels );
-       if ( palette ) {
-               free( palette );
-       }
-       free( cropped );
-}
-
-
-/*
-   ===============
-   Cmd_Cd
-   ===============
- */
-void Cmd_FMCd( void ){
-       char temp[256];
-
-       FinishModel();
-       ClearModel();
-
-       GetScriptToken( false );
-
-       // this is a silly mess...
-       sprintf( cdpartial, "models/%s", token );
-       sprintf( cdarchive, "%smodels/%s", gamedir + strlen( qdir ), token );
-       sprintf( cddir, "%s%s", gamedir, cdpartial );
-
-       // Since we also changed directories on the output side (for mirror) make sure the outputdir is set properly too.
-       sprintf( temp, "%s%s", g_outputDir, cdpartial );
-       strcpy( g_outputDir, temp );
-
-       // if -only was specified and this cd doesn't match,
-       // skip the model (you only need to match leading chars,
-       // so you could regrab all monsters with -only monsters)
-       if ( !g_only[0] ) {
-               return;
-       }
-       if ( strncmp( token, g_only, strlen( g_only ) ) ) {
-               g_skipmodel = true;
-               printf( "skipping %s\n", cdpartial );
-       }
-}
-
-
-/*
-
-   //=======================
-   //          NEW GEN
-   //=======================
-
-   void NewGen (char *ModelFile, char *OutputName, int width, int height)
-   {
-    trigroup_t  *triangles;
-    triangle_t *ptri;
-    triangle_t *grouptris;
-    mesh_node_t        *pmnodes;
-
-    vec3_t             *vertices;
-    vec3_t             *uvs;
-    vec3_t             aveNorm, crossvect;
-    vec3_t             diffvect1, diffvect2;
-    vec3_t             v0, v1, v2;
-    vec3_t             n, u, v;
-    vec3_t             base, zaxis, yaxis;
-    vec3_t             uvwMin, uvwMax;
-    vec3_t             groupMin, groupMax;
-    vec3_t             uvw;
-
-    float              *uFinal, *vFinal;
-    unsigned char      *newpic;
-
-    int                        finalstart = 0, finalcount = 0;
-    int                        xbase = 0, xwidth = 0, ywidth = 0;
-    int                        *todo, *done, finished;
-    int                        i, j, k, l; //counters
-    int                        groupnum, numtris, numverts, num;
-    int                        count;
-    FILE               *grpfile;
-    long               datasize;
-
-    for ( i = 0; i<3; i++)
-    {
-        aveNorm[i] = 0;
-        uvwMin[i] = 1e30f;
-        uvwMax[i] = -1e30f;
-    }
-
-    pmnodes = NULL;
-    ptri = NULL;
-    triangles = NULL;
-
-    zaxis[0] = 0;
-    zaxis[1] = 0;
-    zaxis[2] = 1;
-
-    yaxis[0] = 0;
-    yaxis[1] = 1;
-    yaxis[2] = 0;
-
-    LoadTriangleList (ModelFile, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes);
-
-    todo = (int*)SafeMalloc(fmheader.num_tris*sizeof(int), "NewGen");
-    done = (int*)SafeMalloc(fmheader.num_tris*sizeof(int), "NewGen");
-    triangles = (trigroup_t*)SafeMalloc(fmheader.num_tris*sizeof(trigroup_t), "NewGen");
-
-    for ( i=0; i < fmheader.num_tris; i++)
-    {
-        todo[i] = false;
-        done[i] = false;
-        triangles[i].triangle = ptri[i];
-        triangles[i].group = 0;
-    }
-
-    groupnum = 0;
-
-   //  transitive closure algorithm follows
-   //  put all triangles who transitively share vertices into separate groups
-
-    while (1)
-    {
-        for ( i = 0; i < fmheader.num_tris; i++)
-        {
-            if (!done[i])
-            {
-                break;
-            }
-        }
-        if ( i == fmheader.num_tris)
-        {
-            break;
-        }
-        finished = false;
-        todo[i] = true;
-        while (!finished)
-        {
-            finished = true;
-            for ( i = 0; i < fmheader.num_tris; i++)
-            {
-                if (todo[i])
-                {
-                    done[i] = true;
-                    triangles[i].group = groupnum;
-                    todo[i] = false;
-                    for ( j = 0; j < fmheader.num_tris; j++)
-                    {
-                        if ((!done[j]) && (ShareVertex(triangles[i],triangles[j])))
-                        {
-                            todo[j] = true;
-                            finished = false;
-                        }
-                    }
-                }
-            }
-        }
-        groupnum++;
-    }
-        uFinal = (float*)SafeMalloc(3*fmheader.num_tris*sizeof(float), "NewGen");
-        vFinal = (float*)SafeMalloc(3*fmheader.num_tris*sizeof(float), "NewGen");
-
-    grpfile = fopen("grpdebug.txt","w");
-
-
-    for (i = 0; i < groupnum; i++)
-    {
-
-        fprintf(grpfile,"Group Number: %d\n", i);
-
-        numtris = GetNumTris(triangles, i); // number of triangles in group i
-        numverts = numtris * 3;
-
-        fprintf(grpfile,"%d triangles.\n", numtris);
-
-        vertices = (vec3_t*)SafeMalloc(numverts*sizeof(vec3_t), "NewGen");
-        uvs = (vec3_t*)SafeMalloc(numverts*sizeof(vec3_t), "NewGen");
-        grouptris = (triangle_t*)SafeMalloc(numtris*sizeof(triangle_t), "NewGen");
-
-        for (count = 0; count < fmheader.num_tris; count++)
-        {
-            if (triangles[count].group == i)
-            {
-                fprintf(grpfile,"Triangle %d\n", count);
-            }
-        }
-        fprintf(grpfile,"\n");
-
-
-
-
-        GetOneGroup(triangles, i, grouptris);
-
-        num = 0;
-        for (j = 0; j < numtris; j++)
-        {
-            VectorCopy(grouptris[j].verts[0], v0);
-            VectorCopy(grouptris[j].verts[1], v1);
-            VectorCopy(grouptris[j].verts[2], v2);
-            VectorSubtract(v1, v0, diffvect1);
-            VectorSubtract(v2, v1, diffvect2);
-            CrossProduct( diffvect1, diffvect2, crossvect);
-            VectorAdd(aveNorm, crossvect, aveNorm);
-            VectorCopy(v0,vertices[num]);
-            num++;                                     //  FIXME
-            VectorCopy(v1,vertices[num]);
-            num++;                                     //  add routine to add only verts that
-            VectorCopy(v2,vertices[num]);
-            num++;                                     // have not already been added
-        }
-
-        assert (num >= 3);
-   // figure out the best plane projections
-        DOsvdPlane ((float*)vertices, num, (float *)&n, (float *)&base);
-
-        if (DotProduct(aveNorm,n) < 0.0f)
-        {
-            VectorScale(n, -1.0f, n);
-        }
-        VectorNormalize(n,n);
-        if (fabs(n[2]) < .57)
-        {
-            CrossProduct( zaxis, n, crossvect);
-            VectorCopy(crossvect, u);
-        }
-        else
-        {
-            CrossProduct( yaxis, n, crossvect);
-            VectorCopy(crossvect, u);
-        }
-        VectorNormalize(u,u);
-        CrossProduct( n, u, crossvect);
-        VectorCopy(crossvect, v);
-        VectorNormalize(v,v);
-
-        num = 0;
-
-        for ( j = 0; j < 3; j++)
-        {
-            groupMin[j] = 1e30f;
-            groupMax[j] = -1e30f;
-        }
-
-        for ( j = 0; j < numtris; j++)
-        {
-            for ( k = 0; k < 3; k++)
-            {
-                VectorCopy(grouptris[j].verts[k],v0);
-                VectorSubtract(v0, base, v0);
-                uvw[0] = DotProduct(v0, u);
-                uvw[1] = DotProduct(v0, v);
-                uvw[2] = DotProduct(v0, n);
-                VectorCopy(uvw,uvs[num]);
-                num++;
-                for ( l = 0; l < 3; l++)
-                {
-                    if (uvw[l] < groupMin[l])
-                    {
-                        groupMin[l] = uvw[l];
-                    }
-                    if (uvw[l] > groupMax[l])
-                    {
-                        groupMax[l] = uvw[l];
-                    }
-                }
-            }
-        }
-
-        xwidth = ceil(0 - groupMin[0]) + 2; // move right of origin and avoid overlap
-        ywidth = ceil(0 - groupMin[1]) + 2; // move "above" origin
-
-        for ( j=0; j < numverts; j++)
-        {
-            uFinal[finalcount] = uvs[j][0] + xwidth + xbase;
-            vFinal[finalcount] = uvs[j][1] + ywidth;
-            if (uFinal[finalcount] < uvwMin[0])
-            {
-                uvwMin[0] = uFinal[finalcount];
-            }
-            if (uFinal[finalcount] > uvwMax[0])
-            {
-                uvwMax[0] = uFinal[finalcount];
-            }
-            if (vFinal[finalcount] < uvwMin[1])
-            {
-                uvwMin[1] = vFinal[finalcount];
-            }
-            if (vFinal[finalcount] > uvwMax[1])
-            {
-                uvwMax[1] = vFinal[finalcount];
-            }
-            finalcount++;
-        }
-
-        fprintf(grpfile,"svdPlaned Group min: ( %f , %f )\n",groupMin[0] + xwidth + xbase, groupMin[1] + ywidth);
-        fprintf(grpfile,"svdPlaned Group max: ( %f , %f )\n",groupMax[0] + xwidth + xbase, groupMax[1] + ywidth);
-
-        finalcount = finalstart;
-
-        for ( count = 0; count < numverts; count++)
-        {
-            fprintf(grpfile,"Vertex %d: ( %f , %f , %f )\n",count,vertices[count][0],vertices[count][1],vertices[count][2]);
-            fprintf(grpfile,"svdPlaned: ( %f , %f )\n",uFinal[finalcount],vFinal[finalcount++]);
-        }
-
-        finalstart = finalcount;
-
-        fprintf(grpfile,"\n");
-
-        free(vertices);
-        free(uvs);
-        free(grouptris);
-
-        xbase += ceil(groupMax[0] - groupMin[0]) + 2;
-
-    }
-
-    fprintf(grpfile,"Global Min ( %f , %f )\n",uvwMin[0],uvwMin[1]);
-    fprintf(grpfile,"Global Max ( %f , %f )\n",uvwMax[0],uvwMax[1]);
-
-
-    ScaleTris(uvwMin, uvwMax, width, height, uFinal, vFinal, finalcount);
-
-    for (k = 0; k < finalcount; k++)
-    {
-        fprintf(grpfile, "scaled vertex %d: ( %f , %f )\n",k,uFinal[k],vFinal[k]);
-    }
-
-    //  i've got the array of vertices in uFinal and vFinal.  Now I need to write them and draw lines
-
-    datasize = width * height*sizeof(unsigned char);
-    newpic = (unsigned char*)SafeMalloc(datasize, "NewGen");
-    memset(newpic,0,datasize);
-    memset(pic_palette,0,sizeof(pic_palette));
-    pic_palette[767] = pic_palette[766] = pic_palette[765] = 255;
-
-    k = 0;
-    while (k < finalcount)
-    {
-        NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height);
-        k++;
-        NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height);
-        k++;
-        NewDrawLine(uFinal[k], vFinal[k], uFinal[k-2], vFinal[k-2], newpic, width, height);
-        k++;
-        fprintf(grpfile, "output tri with verts %d, %d, %d", k-2, k-1, k);
-    }
-
-    WritePCXfile (OutputName, newpic, width, height, pic_palette);
-
-    fclose(grpfile);
-
-    free(todo);
-    free(done);
-    free(triangles);
-    free(newpic);
-    return;
-   }
-   void NewDrawLine(int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height)
-   {
-    long dx, dy;
-    long adx, ady;
-    long count;
-    float xfrac, yfrac, xstep, ystep;
-    unsigned long sx, sy;
-    float u, v;
-
-    dx = x2 - x1;
-    dy = y2 - y1;
-    adx = abs(dx);
-    ady = abs(dy);
-
-    count = adx > ady ? adx : ady;
-    count++;
-
-    if(count > 300)
-    {
-        printf("Bad count\n");
-        return; // don't ever hang up on bad data
-    }
-
-    xfrac = x1;
-    yfrac = y1;
-
-    xstep = (float)dx/count;
-    ystep = (float)dy/count;
-
-    switch(LineType)
-    {
-        case LINE_NORMAL:
-            do
-            {
-                if(xfrac < width && yfrac < height)
-                {
-                    picture[(long)yfrac*width+(long)xfrac] = LineColor;
-                }
-                xfrac += xstep;
-                yfrac += ystep;
-                count--;
-            } while (count > 0);
-            break;
-        case LINE_FAT:
-            do
-            {
-                for (u=-0.1 ; u<=0.9 ; u+=0.999)
-                {
-                    for (v=-0.1 ; v<=0.9 ; v+=0.999)
-                    {
-                        sx = xfrac+u;
-                        sy = yfrac+v;
-                        if(sx < width && sy < height)
-                        {
-                            picture[sy*width+sx] = LineColor;
-                        }
-                    }
-                }
-                xfrac += xstep;
-                yfrac += ystep;
-                count--;
-            } while (count > 0);
-            break;
-        case LINE_DOTTED:
-            do
-            {
-                if(count&1 && xfrac < width &&
-                    yfrac < height)
-                {
-                    picture[(long)yfrac*width+(long)xfrac] = LineColor;
-                }
-                xfrac += xstep;
-                yfrac += ystep;
-                count--;
-            } while (count > 0);
-            break;
-        default:
-            Error("Unknown <linetype> %d.\n", LineType);
-    }
-   }
- */
-void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts ){
-
-       int i;
-       float hscale, vscale;
-       float scale;
-
-       hscale = max[0];
-       vscale = max[1];
-
-       hscale = ( Width - 2 ) / max[0];
-       vscale = ( Height - 2 ) / max[1];
-
-       scale = hscale;
-       if ( scale > vscale ) {
-               scale = vscale;
-       }
-       for ( i = 0; i < verts; i++ )
-       {
-               u[i] *= scale;
-               v[i] *= scale;
-       }
-       return;
-}
-
-
-void GetOneGroup( trigroup_t *tris, int grp, triangle_t* triangles ){
-       int i;
-       int j;
-
-       j = 0;
-       for ( i = 0; i < fmheader.num_tris; i++ )
-       {
-               if ( tris[i].group == grp ) {
-                       triangles[j++] = tris[i].triangle;
-               }
-       }
-       return;
-}
-
-
-int GetNumTris( trigroup_t *tris, int grp ){
-       int i;
-       int verts;
-
-       verts = 0;
-       for ( i = 0; i < fmheader.num_tris; i++ )
-       {
-               if ( tris[i].group == grp ) {
-                       verts++;
-               }
-       }
-       return verts;
-}
-
-
-int ShareVertex( trigroup_t trione, trigroup_t tritwo ){
-       int i;
-       int j;
-
-       i = 1;
-       j = 1;
-       for ( i = 0; i < 3; i++ )
-       {
-               for ( j = 0; j < 3; j++ )
-               {
-                       if ( DistBetween( trione.triangle.verts[i],tritwo.triangle.verts[j] ) < TRIVERT_DIST ) {
-                               return true;
-                       }
-               }
-       }
-       return false;
-}
-
-
-float DistBetween( vec3_t point1, vec3_t point2 ){
-       float dist;
-
-       dist = ( point1[0] - point2[0] );
-       dist *= dist;
-       dist += ( point1[1] - point2[1] ) * ( point1[1] - point2[1] );
-       dist += ( point1[2] - point2[2] ) * ( point1[2] - point2[2] );
-       dist = sqrt( dist );
-       return dist;
-}
-
-
-void GenSkin( char *ModelFile, char *OutputName, int Width, int Height ){
-       triangle_t  *ptri;
-       mesh_node_t *pmnodes;
-       int i;
-
-       pmnodes = NULL;
-       ptri = NULL;
-
-       LoadTriangleList( ModelFile, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes );
-       if ( g_ignoreTriUV ) {
-               for ( i = 0; i < fmheader.num_tris; i++ )
-               {
-                       ptri[i].HasUV = 0;
-               }
-       }
-
-       memset( pic,0,sizeof( pic ) );
-       memset( pic_palette,0,sizeof( pic_palette ) );
-       pic_palette[767] = pic_palette[766] = pic_palette[765] = 255;
-
-       ScaleWidth = Width;
-       ScaleHeight = Height;
-
-       BuildST( ptri, fmheader.num_tris, true );
-
-       WritePCXfile( OutputName, pic, SKINPAGE_WIDTH, SKINPAGE_HEIGHT, pic_palette );
-
-       printf( "Gen Skin Stats:\n" );
-       printf( "   Input Base: %s\n",ModelFile );
-       printf( "   Input Dimensions: %d,%d\n",Width,Height );
-       printf( "\n" );
-       printf( "   Output File: %s\n",OutputName );
-       printf( "   Output Dimensions: %d,%d\n",ScaleWidth,ScaleHeight );
-
-       if ( fmheader.num_mesh_nodes ) {
-               printf( "\nNodes:\n" );
-               for ( i = 0; i < fmheader.num_mesh_nodes; i++ )
-               {
-                       printf( "   %s\n",pmnodes[i].name );
-               }
-       }
-
-       free( ptri );
-       free( pmnodes );
-}
-
-
-void Cmd_FMBeginGroup( void ){
-       GetScriptToken( false );
-
-       g_no_opimizations = false;
-
-       groups[num_groups].start_frame = fmheader.num_frames;
-       groups[num_groups].num_frames = 0;
-
-       groups[num_groups].degrees = atol( token );
-       if ( groups[num_groups].degrees < 1 || groups[num_groups].degrees > 32 ) {
-               Error( "Degrees of freedom out of range: %d",groups[num_groups].degrees );
-       }
-}
-
-void Cmd_FMEndGroup( void ){
-       groups[num_groups].num_frames = fmheader.num_frames - groups[num_groups].start_frame;
-
-       if ( num_groups < MAX_GROUPS - 1 ) {
-               num_groups++;
-       }
-       else
-       {
-               Error( "Number of compression groups exceded: %i\n", MAX_GROUPS );
-       }
-}
diff --git a/tools/quake2/qdata_heretic2/h2data.rc b/tools/quake2/qdata_heretic2/h2data.rc
deleted file mode 100644 (file)
index 21540bc..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-//Microsoft Developer Studio generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_ICON1               ICON    DISCARDABLE     "..\\..\\..\\icons\\h2data.ico"
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE DISCARDABLE 
-BEGIN
-    "resource.h\0"
-END
-
-2 TEXTINCLUDE DISCARDABLE 
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "\0"
-END
-
-3 TEXTINCLUDE DISCARDABLE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-#ifndef _MAC
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,1
- PRODUCTVERSION 1,0,0,1
- FILEFLAGSMASK 0x3fL
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x40004L
- FILETYPE 0x1L
- FILESUBTYPE 0x0L
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040904b0"
-        BEGIN
-            VALUE "Comments", "Heavily modified from original ID tool\0"
-            VALUE "CompanyName", "Raven Software\0"
-            VALUE "FileDescription", "qdata\0"
-            VALUE "FileVersion", "2.0\0"
-            VALUE "InternalName", "qdata\0"
-            VALUE "LegalCopyright", "Copyright Â© 1998\0"
-            VALUE "OriginalFilename", "qdata.exe\0"
-            VALUE "ProductName", "Raven Software qdata\0"
-            VALUE "ProductVersion", "2.0\0"
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x409, 1200
-    END
-END
-
-#endif    // !_MAC
-
-#endif    // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif    // not APSTUDIO_INVOKED
-
diff --git a/tools/quake2/qdata_heretic2/images.c b/tools/quake2/qdata_heretic2/images.c
deleted file mode 100644 (file)
index 555303b..0000000
+++ /dev/null
@@ -1,1409 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "qdata.h"
-
-#if GDEF_OS_WINDOWS
- #include <windows.h>
-#endif
-
-#if GDEF_OS_MACOS && !defined( XWINDOWS )
-#include <OpenGL/gl.h>
-#else
-#include <GL/gl.h>
-#endif
-
-#if 1
-extern char     *g_outputDir;
-#endif // _QDATA
-
-char mip_prefix[1024];              // directory to dump the textures in
-
-qboolean colormap_issued;
-byte colormap_palette[768];
-
-unsigned total_x = 0;
-unsigned total_y = 0;
-unsigned total_textures = 0;
-
-#define MAX_IMAGE_SIZE 512
-
-#if 0
-/*
-   ==============
-   RemapZero
-
-   Replaces all 0 bytes in an image with the closest palette entry.
-   This is because NT won't let us change index 0, so any palette
-   animation leaves those pixels untouched.
-   ==============
- */
-void RemapZero( byte *pixels, byte *palette, int width, int height ){
-       int i, c;
-       int alt_zero;
-       int value, best;
-
-       alt_zero = 0;
-       best = 9999999;
-       for ( i = 1 ; i < 255 ; i++ )
-       {
-               value = palette[i * 3 + 0] + palette[i * 3 + 1] + palette[i * 3 + 2];
-               if ( value < best ) {
-                       best = value;
-                       alt_zero = i;
-               }
-       }
-
-       c = width * height;
-       for ( i = 0 ; i < c ; i++ )
-               if ( pixels[i] == 0 ) {
-                       pixels[i] = alt_zero;
-               }
-}
-
-#endif
-
-
-// ********************************************************************
-// **  Mip Map Pre-Processing Routines
-// ********************************************************************
-
-#define intensity_value 1
-
-static unsigned image_pal[256];
-
-#define MAX_LAST 25
-
-long palette_r[256], palette_g[256], palette_b[256];
-long last_r[MAX_LAST],last_g[MAX_LAST],last_b[MAX_LAST], last_i[MAX_LAST], last_place;
-
-long cached;
-
-void PrepareConvert( unsigned *palette ){
-       int i;
-
-       for ( i = 0; i < 256; i++ )
-       {
-               palette_r[i] = ( palette[i] & 0x00ff0000 ) >> 16;
-               palette_g[i] = ( palette[i] & 0x0000ff00 ) >> 8;
-               palette_b[i] = ( palette[i] & 0x000000ff );
-       }
-
-       for ( i = 0; i < MAX_LAST; i++ )
-               last_r[i] = -1;
-
-       last_place = -1;
-}
-
-int ConvertTrueColorToPal( unsigned r, unsigned g, unsigned b ){
-       int i;
-       long min_dist;
-       int min_index;
-       long dist;
-       long dr, dg, db, biggest_delta;
-
-       for ( i = 0; i < MAX_LAST; i++ )
-               if ( r == last_r[i] && g == last_g[i] && b == last_b[i] ) {
-                       cached++;
-                       return last_i[i];
-               }
-
-       min_dist = 256 * 256 + 256 * 256 + 256 * 256;
-       biggest_delta = 256 * 256;
-       min_index = 0;
-
-       for ( i = 0; i < 256; i++ )
-       {
-               dr = abs( palette_r[i] - r );
-               if ( dr > biggest_delta ) {
-                       continue;
-               }
-               dg = abs( palette_g[i] - g );
-               if ( dg > biggest_delta ) {
-                       continue;
-               }
-               db = abs( palette_b[i] - b );
-               if ( db > biggest_delta ) {
-                       continue;
-               }
-
-               dist = dr * dr + dg * dg + db * db;
-               if ( dist < min_dist ) {
-                       min_dist = dist;
-                       min_index = i;
-                       if ( min_dist == 0 ) {
-                               break;
-                       }
-
-                       dist = dr;
-                       if ( dg > dist ) {
-                               dist = dg;
-                       }
-                       if ( db > dist ) {
-                               dist = db;
-                       }
-                       if ( dist < biggest_delta ) {
-                               biggest_delta = dist;
-                       }
-               }
-       }
-
-       last_place++;
-       if ( last_place >= MAX_LAST ) {
-               last_place = 0;
-       }
-
-       last_r[last_place] = r;
-       last_g[last_place] = g;
-       last_b[last_place] = b;
-       last_i[last_place] = min_index;
-
-       return min_index;
-}
-
-
-void GL_ResampleTexture8P( byte *in, int inwidth, int inheight, byte *out,
-                                                  int outwidth, int outheight, palette_t *palette ){
-       int i, j;
-       byte    *inrow, *inrow2;
-       unsigned frac, fracstep;
-       unsigned p1[1024], p2[1024], *p1p, *p2p;
-       palette_t   *c1,*c2,*c3,*c4;
-       unsigned r,g,b;
-
-       fracstep = inwidth * 0x10000 / outwidth;
-
-       frac = fracstep >> 2;
-       for ( i = 0 ; i < outwidth ; i++ )
-       {
-               p1[i] = frac >> 16;
-               frac += fracstep;
-       }
-       frac = 3 * ( fracstep >> 2 );
-       for ( i = 0 ; i < outwidth ; i++ )
-       {
-               p2[i] = frac >> 16;
-               frac += fracstep;
-       }
-
-       cached = 0;
-
-       for ( i = 0 ; i < outheight ; i++ ) //, out += outwidth)
-       {
-               inrow = in + inwidth * (int)( ( i + 0.25 ) * inheight / outheight );
-               inrow2 = in + inwidth * (int)( ( i + 0.75 ) * inheight / outheight );
-
-               p1p = p1;
-               p2p = p2;
-               for ( j = 0 ; j < outwidth ; j++ )
-               {
-                       c1 = &palette[*( (byte *)inrow + ( *p1p ) )];
-                       c2 = &palette[*( (byte *)inrow + ( *p2p ) )];
-                       c3 = &palette[*( (byte *)inrow2 + ( *p1p++ ) )];
-                       c4 = &palette[*( (byte *)inrow2 + ( *p2p++ ) )];
-
-                       r = ( (unsigned)c1->r + (unsigned)c2->r + (unsigned)c3->r + (unsigned)c4->r ) >> 2;
-                       g = ( (unsigned)c1->g + (unsigned)c2->g + (unsigned)c3->g + (unsigned)c4->g ) >> 2;
-                       b = ( (unsigned)c1->b + (unsigned)c2->b + (unsigned)c3->b + (unsigned)c4->b ) >> 2;
-
-                       *out++ = ConvertTrueColorToPal( r,g,b );
-               }
-       }
-}
-
-void GL_MipMap8P( byte *out, byte *in, int width, int height, palette_t *palette ){
-       int i, j;
-       palette_t   *c1,*c2,*c3,*c4;
-       unsigned r,g,b;
-
-       cached = 0;
-       memset( out, 0, 256 * 256 );
-       width <<= 1;
-       height <<= 1;
-
-       for ( i = 0; i < height; i += 2, in += width )
-       {
-               for ( j = 0; j < width; j += 2 )
-               {
-                       c1 = &palette[in[0]];
-                       c3 = &palette[in[width]];
-                       in++;
-                       c2 = &palette[in[0]];
-                       c4 = &palette[in[width]];
-                       in++;
-
-                       r = ( (unsigned)c1->r + (unsigned)c2->r + (unsigned)c3->r + (unsigned)c4->r ) >> 2;
-                       g = ( (unsigned)c1->g + (unsigned)c2->g + (unsigned)c3->g + (unsigned)c4->g ) >> 2;
-                       b = ( (unsigned)c1->b + (unsigned)c2->b + (unsigned)c3->b + (unsigned)c4->b ) >> 2;
-
-                       *out++ = ConvertTrueColorToPal( r, g, b );
-               }
-       }
-}
-
-
-miptex_t *CreateMip( byte *data, unsigned width, unsigned height, byte *palette, int *FinalSize, qboolean mip ){
-       int scaled_width, scaled_height;
-       int i,j,r,g,b;
-       byte intensitytable[256];
-       byte scaled[256 * 256];
-       byte out[256 * 256];
-       int miplevel;
-       miptex_t    *mp;
-       byte        *pos;
-       int size;
-
-       for ( i = 0 ; i < 256 ; i++ )
-       {
-               j = i * intensity_value;
-               if ( j > 255 ) {
-                       j = 255;
-               }
-               intensitytable[i] = j;
-       }
-
-       for ( scaled_width = 1 ; scaled_width < width ; scaled_width <<= 1 )
-               ;
-       if ( 1 && scaled_width > width && 1 ) {
-               scaled_width >>= 1;
-       }
-       for ( scaled_height = 1 ; scaled_height < height ; scaled_height <<= 1 )
-               ;
-       if ( 1 && scaled_height > height && 1 ) {
-               scaled_height >>= 1;
-       }
-
-       // don't ever bother with >256 textures
-       if ( scaled_width > 256 ) {
-               scaled_width = 256;
-       }
-       if ( scaled_height > 256 ) {
-               scaled_height = 256;
-       }
-
-       if ( scaled_width < 1 ) {
-               scaled_width = 1;
-       }
-       if ( scaled_height < 1 ) {
-               scaled_height = 1;
-       }
-
-       size = sizeof( *mp ) + ( scaled_width * scaled_height * 3 );
-       mp = (miptex_t *)SafeMalloc( size, "CreateMip" );
-       memset( mp,0,size );
-
-       mp->version = MIP_VERSION;
-
-       for ( i = j = 0; i < 256; i++,j += 3 )
-       {
-               mp->palette[i].r = r = intensitytable[palette[j]];
-               mp->palette[i].g = g = intensitytable[palette[j + 1]];
-               mp->palette[i].b = b = intensitytable[palette[j + 2]];
-               image_pal[i] = 0xff000000 | ( r << 16 ) | ( g << 8 ) | ( b );
-       }
-
-       PrepareConvert( image_pal );
-
-       if ( scaled_width == width && scaled_height == height ) {
-               memcpy( scaled, data, width * height );
-       }
-       else{
-               GL_ResampleTexture8P( data, width, height, scaled, scaled_width, scaled_height, mp->palette );
-       }
-
-       pos = (byte *)( mp + 1 );
-       miplevel = 0;
-
-       while ( ( scaled_width >= 1 || scaled_height >= 1 ) && ( miplevel <= MIPLEVELS - 1 ) && ( !miplevel || mip ) )
-       {
-               if ( scaled_width < 1 ) {
-                       scaled_width = 1;
-               }
-               if ( scaled_height < 1 ) {
-                       scaled_height = 1;
-               }
-
-               if ( miplevel > 0 ) {
-                       GL_MipMap8P( out, (byte *)scaled, scaled_width, scaled_height, mp->palette );
-               }
-               else{
-                       memcpy( out, scaled, 256 * 256 );
-               }
-
-               mp->width[miplevel] = scaled_width;
-               mp->height[miplevel] = scaled_height;
-               mp->offsets[miplevel] = pos - ( (byte *)( mp ) );
-               memcpy( pos, out, scaled_width * scaled_height );
-               memcpy( scaled, out, 256 * 256 );
-               pos += scaled_width * scaled_height;
-
-               scaled_width >>= 1;
-               scaled_height >>= 1;
-
-               miplevel++;
-       }
-
-       *FinalSize = pos - ( (byte *)( mp ) );
-
-       return mp;
-}
-
-
-void GL_ResampleTexture( unsigned *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight ){
-       int i, j;
-       unsigned    *inrow, *inrow2;
-       unsigned frac, fracstep;
-       unsigned p1[1024], p2[1024];
-       byte        *pix1, *pix2, *pix3, *pix4;
-
-       fracstep = inwidth * 0x10000 / outwidth;
-
-       frac = fracstep >> 2;
-       for ( i = 0 ; i < outwidth ; i++ )
-       {
-               p1[i] = 4 * ( frac >> 16 );
-               frac += fracstep;
-       }
-       frac = 3 * ( fracstep >> 2 );
-       for ( i = 0 ; i < outwidth ; i++ )
-       {
-               p2[i] = 4 * ( frac >> 16 );
-               frac += fracstep;
-       }
-
-       for ( i = 0 ; i < outheight ; i++, out += outwidth )
-       {
-               inrow = in + inwidth * (int)( ( i + 0.25 ) * inheight / outheight );
-               inrow2 = in + inwidth * (int)( ( i + 0.75 ) * inheight / outheight );
-               frac = fracstep >> 1;
-               for ( j = 0 ; j < outwidth ; j++ )
-               {
-                       pix1 = (byte *)inrow + p1[j];
-                       pix2 = (byte *)inrow + p2[j];
-                       pix3 = (byte *)inrow2 + p1[j];
-                       pix4 = (byte *)inrow2 + p2[j];
-                       ( (byte *)( out + j ) )[0] = ( pix1[0] + pix2[0] + pix3[0] + pix4[0] ) >> 2;
-                       ( (byte *)( out + j ) )[1] = ( pix1[1] + pix2[1] + pix3[1] + pix4[1] ) >> 2;
-                       ( (byte *)( out + j ) )[2] = ( pix1[2] + pix2[2] + pix3[2] + pix4[2] ) >> 2;
-                       ( (byte *)( out + j ) )[3] = ( pix1[3] + pix2[3] + pix3[3] + pix4[3] ) >> 2;
-               }
-       }
-}
-
-void GL_MipMap( byte *out, byte *in, int width, int height ){
-       int i, j;
-
-       width <<= 3;
-       height <<= 1;
-       for ( i = 0 ; i < height ; i++, in += width )
-       {
-               for ( j = 0 ; j < width ; j += 8, out += 4, in += 8 )
-               {
-                       out[0] = ( in[0] + in[4] + in[width + 0] + in[width + 4] ) >> 2;
-                       out[1] = ( in[1] + in[5] + in[width + 1] + in[width + 5] ) >> 2;
-                       out[2] = ( in[2] + in[6] + in[width + 2] + in[width + 6] ) >> 2;
-                       out[3] = ( in[3] + in[7] + in[width + 3] + in[width + 7] ) >> 2;
-               }
-       }
-}
-
-miptex32_t *CreateMip32( unsigned *data, unsigned width, unsigned height, int *FinalSize, qboolean mip ){
-       int scaled_width, scaled_height;
-       unsigned scaled[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
-       unsigned out[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
-       int miplevel;
-       miptex32_t      *mp;
-       byte            *pos;
-       int size;
-       paletteRGBA_t   *test;
-
-       for ( scaled_width = 1 ; scaled_width < width ; scaled_width <<= 1 )
-               ;
-       if ( 1 && scaled_width > width && 1 ) {
-               scaled_width >>= 1;
-       }
-       for ( scaled_height = 1 ; scaled_height < height ; scaled_height <<= 1 )
-               ;
-       if ( 1 && scaled_height > height && 1 ) {
-               scaled_height >>= 1;
-       }
-
-       // don't ever bother with >256 textures
-       if ( scaled_width > MAX_IMAGE_SIZE ) {
-               scaled_width = MAX_IMAGE_SIZE;
-       }
-       if ( scaled_height > MAX_IMAGE_SIZE ) {
-               scaled_height = MAX_IMAGE_SIZE;
-       }
-
-       if ( scaled_width < 1 ) {
-               scaled_width = 1;
-       }
-       if ( scaled_height < 1 ) {
-               scaled_height = 1;
-       }
-
-       size = sizeof( *mp ) + ( scaled_width * scaled_height * 3 * 4 );
-       mp = (miptex32_t *)SafeMalloc( size, "CreateMip" );
-       memset( mp,0,size );
-
-       mp->version = MIP32_VERSION;
-
-       size = width * height;
-       test = (paletteRGBA_t *)data;
-       while ( size )
-       {
-               if ( test->a != 255 ) {
-                       mp->flags |= LittleLong( SURF_ALPHA_TEXTURE );
-                       break;
-               }
-
-               size--;
-               test++;
-       }
-
-       if ( scaled_width == width && scaled_height == height ) {
-               memcpy( scaled, data, width * height * 4 );
-       }
-       else{
-               GL_ResampleTexture( data, width, height, scaled, scaled_width, scaled_height );
-       }
-
-       pos = (byte *)( mp + 1 );
-       miplevel = 0;
-
-       while ( ( scaled_width >= 1 || scaled_height >= 1 ) && ( miplevel <= MIPLEVELS - 1 ) && ( !miplevel || mip ) )
-       {
-               if ( scaled_width < 1 ) {
-                       scaled_width = 1;
-               }
-               if ( scaled_height < 1 ) {
-                       scaled_height = 1;
-               }
-
-               if ( miplevel > 0 ) {
-                       GL_MipMap( (byte *)out, (byte *)scaled, scaled_width, scaled_height );
-               }
-               else
-               {
-                       memcpy( out, scaled, MAX_IMAGE_SIZE * MAX_IMAGE_SIZE * 4 );
-               }
-
-               mp->width[miplevel] = scaled_width;
-               mp->height[miplevel] = scaled_height;
-               mp->offsets[miplevel] = pos - ( (byte *)( mp ) );
-               memcpy( pos, out, scaled_width * scaled_height * 4 );
-               memcpy( scaled, out, MAX_IMAGE_SIZE * MAX_IMAGE_SIZE * 4 );
-               pos += scaled_width * scaled_height * 4;
-
-               scaled_width >>= 1;
-               scaled_height >>= 1;
-
-               miplevel++;
-       }
-
-       *FinalSize = pos - ( (byte *)( mp ) );
-
-       return mp;
-}
-
-/*
-   ==============
-   Cmd_Grab
-
-   $grab filename x y width height
-   ==============
- */
-void Cmd_Grab( void ){
-       int xl,yl,w,h,y;
-       byte            *cropped;
-       char savename[1024];
-       char dest[1024];
-
-       GetScriptToken( false );
-
-       if ( token[0] == '/' || token[0] == '\\' ) {
-               sprintf( savename, "%s%s.pcx", gamedir, token + 1 );
-       }
-       else{
-               sprintf( savename, "%spics/%s.pcx", gamedir, token );
-       }
-
-       if ( g_release ) {
-               if ( token[0] == '/' || token[0] == '\\' ) {
-                       sprintf( dest, "%s.pcx", token + 1 );
-               }
-               else{
-                       sprintf( dest, "pics/%s.pcx", token );
-               }
-
-               ReleaseFile( dest );
-               return;
-       }
-
-       GetScriptToken( false );
-       xl = atoi( token );
-       GetScriptToken( false );
-       yl = atoi( token );
-       GetScriptToken( false );
-       w = atoi( token );
-       GetScriptToken( false );
-       h = atoi( token );
-
-       if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) {
-               Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h );
-       }
-
-       // crop it to the proper size
-       cropped = (byte *) SafeMalloc( w * h, "Cmd_Grab" );
-       for ( y = 0 ; y < h ; y++ )
-       {
-               memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w );
-       }
-
-       // save off the new image
-       printf( "saving %s\n", savename );
-       CreatePath( savename );
-       WritePCXfile( savename, cropped, w, h, lbmpalette );
-
-       free( cropped );
-}
-
-/*
-   ==============
-   Cmd_Raw
-
-   $grab filename x y width height
-   ==============
- */
-void Cmd_Raw( void ){
-       int xl,yl,w,h,y;
-       byte            *cropped;
-       char savename[1024];
-       char dest[1024];
-
-       GetScriptToken( false );
-
-       sprintf( savename, "%s%s.lmp", gamedir, token );
-
-       if ( g_release ) {
-               sprintf( dest, "%s.lmp", token );
-               ReleaseFile( dest );
-               return;
-       }
-
-       GetScriptToken( false );
-       xl = atoi( token );
-       GetScriptToken( false );
-       yl = atoi( token );
-       GetScriptToken( false );
-       w = atoi( token );
-       GetScriptToken( false );
-       h = atoi( token );
-
-       if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) {
-               Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h );
-       }
-
-       // crop it to the proper size
-       cropped = (byte *) SafeMalloc( w * h, "Cmd_Raw" );
-       for ( y = 0 ; y < h ; y++ )
-       {
-               memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w );
-       }
-
-       // save off the new image
-       printf( "saving %s\n", savename );
-       CreatePath( savename );
-
-       SaveFile( savename, cropped, w * h );
-
-       free( cropped );
-}
-
-/*
-   =============================================================================
-
-   COLORMAP GRABBING
-
-   =============================================================================
- */
-
-/*
-   ===============
-   BestColor
-   ===============
- */
-byte BestColor( int r, int g, int b, int start, int stop ){
-       int i;
-       int dr, dg, db;
-       int bestdistortion, distortion;
-       int bestcolor;
-       byte    *pal;
-
-//
-// let any color go to 0 as a last resort
-//
-       bestdistortion = 256 * 256 * 4;
-       bestcolor = 0;
-
-       pal = colormap_palette + start * 3;
-       for ( i = start ; i <= stop ; i++ )
-       {
-               dr = r - (int)pal[0];
-               dg = g - (int)pal[1];
-               db = b - (int)pal[2];
-               pal += 3;
-               distortion = dr * dr + dg * dg + db * db;
-               if ( distortion < bestdistortion ) {
-                       if ( !distortion ) {
-                               return i;       // perfect match
-
-                       }
-                       bestdistortion = distortion;
-                       bestcolor = i;
-               }
-       }
-
-       return bestcolor;
-}
-
-
-/*
-   ==============
-   Cmd_Colormap
-
-   $colormap filename
-
-   the brightes colormap is first in the table (FIXME: reverse this now?)
-
-   64 rows of 256 : lightmaps
-   256 rows of 256 : translucency table
-   ==============
- */
-void Cmd_Colormap( void ){
-       int levels, brights;
-       int l, c;
-       float frac, red, green, blue;
-       float range;
-       byte    *cropped, *lump_p;
-       char savename[1024];
-       char dest[1024];
-
-       colormap_issued = true;
-       if ( !g_release ) {
-               memcpy( colormap_palette, lbmpalette, 768 );
-       }
-
-       if ( !ScriptTokenAvailable() ) { // just setting colormap_issued
-               return;
-       }
-
-       GetScriptToken( false );
-       sprintf( savename, "%spics/%s.pcx", gamedir, token );
-
-       if ( g_release ) {
-               sprintf( dest, "pics/%s.pcx", token );
-               ReleaseFile( dest );
-               return;
-       }
-
-       range = 2;
-       levels = 64;
-       brights = 1;    // ignore 255 (transparent)
-
-       cropped = (byte *) SafeMalloc( ( levels + 256 ) * 256, "Cmd_ColorMap" );
-       lump_p = cropped;
-
-// shaded levels
-       for ( l = 0; l < levels; l++ )
-       {
-               frac = range - range * (float)l / ( levels - 1 );
-               for ( c = 0 ; c < 256 - brights ; c++ )
-               {
-                       red = lbmpalette[c * 3];
-                       green = lbmpalette[c * 3 + 1];
-                       blue = lbmpalette[c * 3 + 2];
-
-                       red = (int)( red * frac + 0.5 );
-                       green = (int)( green * frac + 0.5 );
-                       blue = (int)( blue * frac + 0.5 );
-
-//
-// note: 254 instead of 255 because 255 is the transparent color, and we
-// don't want anything remapping to that
-// don't use color 0, because NT can't remap that (or 255)
-//
-                       *lump_p++ = BestColor( red,green,blue, 1, 254 );
-               }
-
-               // fullbrights allways stay the same
-               for ( ; c < 256 ; c++ )
-                       *lump_p++ = c;
-       }
-
-// 66% transparancy table
-       for ( l = 0; l < 255; l++ )
-       {
-               for ( c = 0 ; c < 255 ; c++ )
-               {
-                       red = lbmpalette[c * 3] * 0.33 + lbmpalette[l * 3] * 0.66;
-                       green = lbmpalette[c * 3 + 1] * 0.33 + lbmpalette[l * 3 + 1] * 0.66;
-                       blue = lbmpalette[c * 3 + 2] * 0.33 + lbmpalette[l * 3 + 2] * 0.66;
-
-                       *lump_p++ = BestColor( red,green,blue, 1, 254 );
-               }
-               *lump_p++ = 255;
-       }
-       for ( c = 0 ; c < 256 ; c++ )
-               *lump_p++ = 255;
-
-       // save off the new image
-       printf( "saving %s\n", savename );
-       CreatePath( savename );
-       WritePCXfile( savename, cropped, 256, levels + 256, lbmpalette );
-
-       free( cropped );
-}
-
-/*
-   =============================================================================
-
-   MIPTEX GRABBING
-
-   =============================================================================
- */
-
-byte pixdata[256];
-
-int d_red, d_green, d_blue;
-
-byte palmap[32][32][32];
-qboolean palmap_built;
-
-/*
-   =============
-   FindColor
-   =============
- */
-int FindColor( int r, int g, int b ){
-       int bestcolor;
-
-       if ( r > 255 ) {
-               r = 255;
-       }
-       if ( r < 0 ) {
-               r = 0;
-       }
-       if ( g > 255 ) {
-               g = 255;
-       }
-       if ( g < 0 ) {
-               g = 0;
-       }
-       if ( b > 255 ) {
-               b = 255;
-       }
-       if ( b < 0 ) {
-               b = 0;
-       }
-#ifndef TABLECOLORS
-       bestcolor = BestColor( r, g, b, 0, 254 );
-#else
-       bestcolor = palmap[r >> 3][g >> 3][b >> 3];
-#endif
-
-       return bestcolor;
-}
-
-
-void BuildPalmap( void ){
-#ifdef TABLECOLORS
-       int r, g, b;
-       int bestcolor;
-
-       if ( palmap_built ) {
-               return;
-       }
-       palmap_built = true;
-
-       for ( r = 4 ; r < 256 ; r += 8 )
-       {
-               for ( g = 4 ; g < 256 ; g += 8 )
-               {
-                       for ( b = 4 ; b < 256 ; b += 8 )
-                       {
-                               bestcolor = BestColor( r, g, b, 1, 254 );
-                               palmap[r >> 3][g >> 3][b >> 3] = bestcolor;
-                       }
-               }
-       }
-#endif
-
-       if ( !colormap_issued ) {
-               Error( "You must issue a $colormap command first" );
-       }
-
-}
-
-/*
-   =============
-   AveragePixels
-   =============
- */
-byte AveragePixels( int count ){
-       int r,g,b;
-       int i;
-       int vis;
-       int pix;
-       int bestcolor;
-       byte    *pal;
-       int fullbright;
-
-       vis = 0;
-       r = g = b = 0;
-       fullbright = 0;
-       for ( i = 0 ; i < count ; i++ )
-       {
-               pix = pixdata[i];
-
-               r += lbmpalette[pix * 3];
-               g += lbmpalette[pix * 3 + 1];
-               b += lbmpalette[pix * 3 + 2];
-               vis++;
-       }
-
-       r /= vis;
-       g /= vis;
-       b /= vis;
-
-       // error diffusion
-       r += d_red;
-       g += d_green;
-       b += d_blue;
-
-//
-// find the best color
-//
-       bestcolor = FindColor( r, g, b );
-
-       // error diffusion
-       pal = colormap_palette + bestcolor * 3;
-       d_red = r - (int)pal[0];
-       d_green = g - (int)pal[1];
-       d_blue = b - (int)pal[2];
-
-       return bestcolor;
-}
-
-
-typedef enum
-{
-       pt_contents,
-       pt_flags,
-       pt_animvalue,
-       pt_altnamevalue,
-       pt_damagenamevalue,
-       pt_flagvalue,
-       pt_materialvalue,
-       pt_scale,
-       pt_mip,
-       pt_detail,
-       pt_gl,
-       pt_nomip,
-       pt_detailer,
-} parmtype_t;
-
-typedef struct
-{
-       char    *name;
-       int flags;
-       parmtype_t type;
-} mipparm_t;
-
-mipparm_t mipparms[] =
-{
-       // utility content attributes
-       {"pushpull",CONTENTS_PUSHPULL, pt_contents},
-       {"water",   CONTENTS_WATER, pt_contents},
-       {"slime",   CONTENTS_SLIME, pt_contents},       // mildly damaging
-       {"lava",    CONTENTS_LAVA, pt_contents},        // very damaging
-       {"window",  CONTENTS_WINDOW, pt_contents},  // solid, but doesn't eat internal textures
-       {"mist",    CONTENTS_MIST, pt_contents},    // non-solid window
-       {"origin",  CONTENTS_ORIGIN, pt_contents},  // center of rotating brushes
-       {"playerclip",  CONTENTS_PLAYERCLIP, pt_contents},
-       {"monsterclip", CONTENTS_MONSTERCLIP, pt_contents},
-
-       // utility surface attributes
-       {"hint",    SURF_HINT, pt_flags},
-       {"skip",    SURF_SKIP, pt_flags},
-       {"light",   SURF_LIGHT, pt_flagvalue},      // value is the light quantity
-
-       {"animspeed",SURF_ANIMSPEED, pt_flagvalue},     // value will hold the anim speed in fps
-
-       // texture chaining
-       {"anim",    0,          pt_animvalue},      // animname is the next animation
-       {"alt",     0,          pt_altnamevalue},   // altname is the alternate texture
-       {"damage",  0,          pt_damagenamevalue},    // damagename is the damage texture
-       {"scale",   0,          pt_scale},      // next two values are for scale
-       {"mip",     0,          pt_mip},
-       {"detail",  0,          pt_detail},
-
-       {"GL_ZERO",                 GL_ZERO,                pt_gl},
-       {"GL_ONE",                  GL_ONE,                 pt_gl},
-       {"GL_SRC_COLOR",            GL_SRC_COLOR,           pt_gl},
-       {"GL_ONE_MINUS_SRC_COLOR",  GL_ONE_MINUS_SRC_COLOR, pt_gl},
-       {"GL_DST_COLOR",            GL_DST_COLOR,           pt_gl},
-       {"GL_ONE_MINUS_DST_COLOR",  GL_ONE_MINUS_DST_COLOR, pt_gl},
-       {"GL_SRC_ALPHA",            GL_SRC_ALPHA,           pt_gl},
-       {"GL_ONE_MINUS_SRC_ALPHA",  GL_ONE_MINUS_SRC_ALPHA, pt_gl},
-       {"GL_DST_ALPHA",            GL_DST_ALPHA,           pt_gl},
-       {"GL_ONE_MINUS_DST_ALPHA",  GL_ONE_MINUS_DST_ALPHA, pt_gl},
-       {"GL_SRC_ALPHA_SATURATE",   GL_SRC_ALPHA_SATURATE,  pt_gl},
-
-       // server attributes
-       {"slick",   SURF_SLICK, pt_flags},
-
-       // drawing attributes
-       {"sky",     SURF_SKY, pt_flags},
-       {"warping", SURF_WARP, pt_flags},       // only valid with 64x64 textures
-       {"trans33", SURF_TRANS33, pt_flags},    // translucent should allso set fullbright
-       {"trans66", SURF_TRANS66, pt_flags},
-       {"flowing", SURF_FLOWING, pt_flags},    // flow direction towards angle 0
-       {"nodraw",  SURF_NODRAW, pt_flags}, // for clip textures and trigger textures
-       {"alpha",   SURF_ALPHA_TEXTURE, pt_flags},
-       {"undulate",    SURF_UNDULATE, pt_flags},       // rock surface up and down...
-       {"skyreflect",  SURF_SKYREFLECT, pt_flags},     // liquid will somewhat reflect the sky - not quite finished....
-
-       {"material", SURF_MATERIAL, pt_materialvalue},
-       {"metal",   SURF_TYPE_METAL, pt_flags},
-       {"stone",   SURF_TYPE_STONE, pt_flags},
-       {"wood",    SURF_TYPE_WOOD, pt_flags},
-
-       {"m_nomip", 0, pt_nomip},
-       {"m_detail", 0, pt_detailer},
-
-       {NULL, 0, pt_contents}
-};
-
-/*
-   ==============
-   Cmd_Mip
-
-   $mip filename x y width height <OPTIONS>
-   must be multiples of sixteen
-   SURF_WINDOW
-   ==============
- */
-
-void Cmd_Mip( void ){
-       int xl,yl,xh,yh,w,h;
-       byte            *dest, *source;
-       int flags, value, contents;
-       mipparm_t       *mp;
-       char lumpname[128];
-       char altname[128];
-       char animname[128];
-       char damagename[128];
-       byte buffer[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
-       unsigned bufferl[MAX_IMAGE_SIZE * MAX_IMAGE_SIZE];
-       materialtype_t  *mat;
-       char filename[1024];
-       unsigned        *destl, *sourcel;
-       int linedelta, x, y;
-       int size;
-       miptex_t        *qtex;
-       miptex32_t      *qtex32;
-       float scale_x, scale_y;
-       int mip_scale;
-       // detail texturing
-       char dt_name[128];
-       float dt_scale_x, dt_scale_y;
-       float dt_u, dt_v;
-       float dt_alpha;
-       int dt_src_blend_mode, dt_dst_blend_mode;
-       int flags2;
-
-
-       GetScriptToken( false );
-       strcpy( lumpname, token );
-
-       GetScriptToken( false );
-       xl = atoi( token );
-       GetScriptToken( false );
-       yl = atoi( token );
-       GetScriptToken( false );
-       w = atoi( token );
-       GetScriptToken( false );
-       h = atoi( token );
-
-       total_x += w;
-       total_y += h;
-       total_textures++;
-
-       if ( ( w & 15 ) || ( h & 15 ) ) {
-               Error( "line %i: miptex sizes must be multiples of 16", scriptline );
-       }
-
-       flags = 0;
-       flags2 = 0;
-       contents = 0;
-       value = 0;
-       mip_scale = 0;
-
-       altname[0] = animname[0] = damagename[0] = 0;
-
-       scale_x = scale_y = 0.5;
-
-       // detail texturing
-       dt_name[0] = 0;
-       dt_scale_x = dt_scale_y = 0.0;
-       dt_u = dt_v = 0.0;
-       dt_alpha = 0.0;
-       dt_src_blend_mode = dt_dst_blend_mode = 0;
-
-       // get optional flags and values
-       while ( ScriptTokenAvailable() )
-       {
-               GetScriptToken( false );
-
-               for ( mp = mipparms ; mp->name ; mp++ )
-               {
-                       if ( !strcmp( mp->name, token ) ) {
-                               switch ( mp->type )
-                               {
-                               case pt_animvalue:
-                                       GetScriptToken( false );    // specify the next animation frame
-                                       strcpy( animname, token );
-                                       break;
-                               case pt_altnamevalue:
-                                       GetScriptToken( false );    // specify the alternate texture
-                                       strcpy( altname, token );
-                                       break;
-                               case pt_damagenamevalue:
-                                       GetScriptToken( false );    // specify the damage texture
-                                       strcpy( damagename, token );
-                                       break;
-                               case pt_flags:
-                                       flags |= mp->flags;
-                                       break;
-                               case pt_contents:
-                                       contents |= mp->flags;
-                                       break;
-                               case pt_flagvalue:
-                                       flags |= mp->flags;
-                                       GetScriptToken( false );    // specify the light value
-                                       value = atoi( token );
-                                       break;
-                               case pt_materialvalue:
-                                       GetScriptToken( false );
-                                       for ( mat = materialtypes ; mat->name ; mat++ )
-                                       {
-                                               if ( !strcmp( mat->name, token ) ) {
-                                                       // assumes SURF_MATERIAL is in top 8 bits
-                                                       flags = ( flags & 0x0FFFFFF ) | ( mat->value << 24 );
-                                                       break;
-                                               }
-                                       }
-                                       break;
-                               case pt_scale:
-                                       GetScriptToken( false );    // specify the x scale
-                                       scale_x = atof( token );
-                                       GetScriptToken( false );    // specify the y scale
-                                       scale_y = atof( token );
-                                       break;
-
-                               case pt_mip:
-                                       mip_scale = 1;
-                                       break;
-
-                               case pt_detailer:
-                                       flags2 |= MIP32_DETAILER_FLAG2;
-                                       break;
-
-                               case pt_nomip:
-                                       flags2 |= MIP32_NOMIP_FLAG2;
-                                       break;
-
-                               case pt_detail:
-                                       GetScriptToken( false );
-                                       strcpy( dt_name, token );
-                                       GetScriptToken( false );
-                                       dt_scale_x = atof( token );
-                                       GetScriptToken( false );
-                                       dt_scale_y = atof( token );
-                                       GetScriptToken( false );
-                                       dt_u = atof( token );
-                                       GetScriptToken( false );
-                                       dt_v = atof( token );
-                                       GetScriptToken( false );
-                                       dt_alpha = atof( token );
-                                       GetScriptToken( false );
-                                       for ( mp = mipparms ; mp->name ; mp++ )
-                                       {
-                                               if ( !strcmp( mp->name, token ) ) {
-                                                       if ( mp->type == pt_gl ) {
-                                                               dt_src_blend_mode = mp->flags;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       if ( !mp->name ) {
-                                               Error( "line %i: invalid gl blend mode %s", scriptline, token );
-                                       }
-                                       GetScriptToken( false );
-                                       for ( mp = mipparms ; mp->name ; mp++ )
-                                       {
-                                               if ( !strcmp( mp->name, token ) ) {
-                                                       if ( mp->type == pt_gl ) {
-                                                               dt_dst_blend_mode = mp->flags;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       if ( !mp->name ) {
-                                               Error( "line %i: invalid gl blend mode %s", scriptline, token );
-                                       }
-                                       break;
-                               }
-                               break;
-                       }
-               }
-               if ( !mp->name ) {
-                       Error( "line %i: unknown parm %s", scriptline, token );
-               }
-       }
-
-       if ( g_release ) {
-               return; // textures are only released by $maps
-
-       }
-       xh = xl + w;
-       yh = yl + h;
-       if ( xh * yh > MAX_IMAGE_SIZE * MAX_IMAGE_SIZE ) {
-               Error( "line %i image %s: image is too big!", scriptline, lumpname );
-       }
-
-       if ( TrueColorImage ) {
-               if ( xl >= longimagewidth || xh > longimagewidth ||
-                        yl >= longimageheight || yh > longimageheight ) {
-                       Error( "line %i image %s: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, lumpname, xl,yl,w,h,longimagewidth,longimageheight );
-               }
-
-               sourcel = longimage + ( yl * longimagewidth ) + xl;
-               destl = bufferl;
-               linedelta = ( longimagewidth - w );
-
-               for ( y = yl ; y < yh ; y++ )
-               {
-                       for ( x = xl ; x < xh ; x++ )
-                       {
-                               *destl++ = *sourcel++;  // RGBA
-                       }
-                       sourcel += linedelta;
-               }
-
-               qtex32 = CreateMip32( bufferl, w, h, &size, true );
-
-               qtex32->flags |= LittleLong( flags );
-               qtex32->flags2 |= LittleLong( flags2 );
-               qtex32->contents = LittleLong( contents );
-               qtex32->value = LittleLong( value );
-               qtex32->scale_x = scale_x;
-               qtex32->scale_y = scale_y;
-               qtex32->mip_scale = mip_scale;
-               sprintf( qtex32->name, "%s/%s", mip_prefix, lumpname );
-               if ( animname[0] ) {
-                       sprintf( qtex32->animname, "%s/%s", mip_prefix, animname );
-               }
-               if ( altname[0] ) {
-                       sprintf( qtex32->altname, "%s/%s", mip_prefix, altname );
-               }
-               if ( damagename[0] ) {
-                       sprintf( qtex32->damagename, "%s/%s", mip_prefix, damagename );
-               }
-               if ( dt_name[0] & ( ( flags2 & MIP32_DETAILER_FLAG2 ) == 0 ) ) {
-                       sprintf( qtex32->dt_name, "%s/%s", mip_prefix, dt_name );
-                       qtex32->dt_scale_x = dt_scale_x;
-                       qtex32->dt_scale_y = dt_scale_y;
-                       qtex32->dt_u = dt_u;
-                       qtex32->dt_v = dt_v;
-                       qtex32->dt_alpha = dt_alpha;
-                       qtex32->dt_src_blend_mode = dt_src_blend_mode;
-                       qtex32->dt_dst_blend_mode = dt_dst_blend_mode;
-               }
-
-               //
-               // write it out
-               //
-               sprintf( filename, "%stextures/%s/%s.m32", g_outputDir, mip_prefix, lumpname );
-               if ( qtex32->flags & ( SURF_ALPHA_TEXTURE ) ) {
-                       printf( "writing %s with ALPHA\n", filename );
-               }
-               else{
-                       printf( "writing %s\n", filename );
-               }
-               SaveFile( filename, (byte *)qtex32, size );
-
-               free( qtex32 );
-       }
-       else
-       {
-               if ( xl >= byteimagewidth || xh > byteimagewidth ||
-                        yl >= byteimageheight || yh > byteimageheight ) {
-                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
-               }
-
-               source = byteimage + yl * byteimagewidth + xl;
-               dest = buffer;
-               linedelta = byteimagewidth - w;
-
-               for ( y = yl ; y < yh ; y++ )
-               {
-                       for ( x = xl ; x < xh ; x++ )
-                       {
-                               *dest++ = *source++;
-                       }
-                       source += linedelta;
-               }
-
-               qtex = CreateMip( buffer, w, h, lbmpalette, &size, true );
-
-               qtex->flags = LittleLong( flags );
-               qtex->contents = LittleLong( contents );
-               qtex->value = LittleLong( value );
-               sprintf( qtex->name, "%s/%s", mip_prefix, lumpname );
-               if ( animname[0] ) {
-                       sprintf( qtex->animname, "%s/%s", mip_prefix, animname );
-               }
-
-               //
-               // write it out
-               //
-               sprintf( filename, "%stextures/%s/%s.m8", g_outputDir, mip_prefix, lumpname );
-               printf( "writing %s\n", filename );
-               SaveFile( filename, (byte *)qtex, size );
-
-               free( qtex );
-       }
-}
-
-/*
-   ===============
-   Cmd_Mippal
-   ===============
- */
-void Cmd_Mippal( void ){
-       colormap_issued = true;
-       if ( g_release ) {
-               return;
-       }
-
-       memcpy( colormap_palette, lbmpalette, 768 );
-
-       BuildPalmap();
-}
-
-
-/*
-   ===============
-   Cmd_Mipdir
-   ===============
- */
-void Cmd_Mipdir( void ){
-       char filename[1024];
-
-       GetScriptToken( false );
-       strcpy( mip_prefix, token );
-       // create the directory if needed
-       sprintf( filename, "%stextures", g_outputDir );
-       Q_mkdir( filename );
-       sprintf( filename, "%stextures/%s", g_outputDir, mip_prefix );
-       Q_mkdir( filename );
-}
-
-
-/*
-   =============================================================================
-
-   ENVIRONMENT MAP GRABBING
-
-   Creates six pcx files from tga files without any palette edge seams
-   also copies the tga files for GL rendering.
-   =============================================================================
- */
-
-// 3dstudio environment map suffixes
-char    *suf[6] = {"rt", "ft", "lf", "bk", "up", "dn"};
-
-/*
-   =================
-   Cmd_Environment
-   =================
- */
-void Cmd_Environment( void ){
-       char name[1024];
-       int i, x, y;
-       byte image[256 * 256];
-       byte    *tga;
-
-       GetScriptToken( false );
-
-       if ( g_release ) {
-               for ( i = 0 ; i < 6 ; i++ )
-               {
-                       sprintf( name, "env/%s%s.pcx", token, suf[i] );
-                       ReleaseFile( name );
-                       sprintf( name, "env/%s%s.tga", token, suf[i] );
-                       ReleaseFile( name );
-               }
-               return;
-       }
-       // get the palette
-       BuildPalmap();
-
-       sprintf( name, "%senv/", gamedir );
-       CreatePath( name );
-
-       // convert the images
-       for ( i = 0 ; i < 6 ; i++ )
-       {
-               sprintf( name, "%senv/%s%s.tga", gamedir, token, suf[i] );
-               printf( "loading %s...\n", name );
-               LoadTGA( name, &tga, NULL, NULL );
-
-               for ( y = 0 ; y < 256 ; y++ )
-               {
-                       for ( x = 0 ; x < 256 ; x++ )
-                       {
-                               image[y * 256 + x] = FindColor( tga[( y * 256 + x ) * 4 + 0],tga[( y * 256 + x ) * 4 + 1],tga[( y * 256 + x ) * 4 + 2] );
-                       }
-               }
-               free( tga );
-               sprintf( name, "%senv/%s%s.pcx", gamedir, token, suf[i] );
-               if ( FileTime( name ) != -1 ) {
-                       printf( "%s already exists, not overwriting.\n", name );
-               }
-               else{
-                       WritePCXfile( name, image, 256, 256, colormap_palette );
-               }
-       }
-}
diff --git a/tools/quake2/qdata_heretic2/jointed.c b/tools/quake2/qdata_heretic2/jointed.c
deleted file mode 100644 (file)
index de8b802..0000000
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <assert.h>
-#include <math.h>
-#include "token.h"
-#include "joints.h"
-#include "angles.h"
-#include "inout.h"
-
-char *SKEL_ROOT_NAMES[] =
-{
-       "RAVEN_SPINE"
-};
-
-char *SKEL_NAMES[] =
-{
-       "RAVEN_WAIST1",
-       "RAVEN_WAIST2",
-       "RAVEN_NECK"
-};
-
-int NAME_OFFSETS[] =
-{
-       0
-};
-
-int numJointsForSkeleton[] =
-{
-       NUM_JOINTS_RAVEN,
-       NUM_JOINTS_BOX
-};
-
-float g_scaling[3];
-float g_rotation[3];
-float g_translation[3];
-
-//==========================================================================
-//
-// LoadHRCClustered
-//
-//==========================================================================
-
-static void LoadHRCClustered( char *fileName, int **clusterList, int *num_verts, int skelType ){
-       int i, j;
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-
-       TK_Beyond( TK_CLUSTERS );
-
-       while ( TK_Search( TK_CLUSTER_NAME ) != TK_EOF )
-       {
-               TK_Require( TK_STRING );
-
-               for ( i = 0; i < numJointsForSkeleton[skelType]; ++i )
-               {
-                       if ( stricmp( tk_String, SKEL_NAMES[NAME_OFFSETS[skelType] + i] ) == 0 ) {
-                               i = -i + numJointsForSkeleton[skelType] - 1;
-
-                               TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER );
-
-                               num_verts[i + 1] = tk_IntNumber;
-
-                               clusterList[i] = (int *) SafeMalloc( num_verts[i + 1] * sizeof( int ), "LoadHRCClustered" );
-                               assert( clusterList[i] );
-                               // currently this function is only called by LoadTriangleListClustered, which in turn is only
-                               // called by Cmd_Base in qdata.  This is where the only call to free for this memory is being made.
-
-                               TK_Beyond( TK_LBRACE );
-
-                               for ( j = 0; j < num_verts[i + 1]; ++j )
-                               {
-                                       TK_Require( TK_INTNUMBER );
-                                       clusterList[i][j] = tk_IntNumber;
-                                       TK_Fetch();
-                               }
-
-                               break;
-                       }
-               }
-       }
-
-       num_verts[0] = numJointsForSkeleton[skelType];
-}
-
-static void LoadHRCGlobals( char *fileName ){
-       int i;
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-       TK_Beyond( TK_MODEL );
-
-       TK_Beyond( TK_SCALING );
-       for ( i = 0; i < 3; i++ )
-       {
-               TK_Require( TK_FLOATNUMBER );
-               g_scaling[i] = tk_FloatNumber;
-               TK_Fetch();
-       }
-
-       TK_Beyond( TK_ROTATION );
-       for ( i = 0; i < 3; i++ )
-       {
-               TK_Require( TK_FLOATNUMBER );
-               g_rotation[i] = tk_FloatNumber;
-               TK_Fetch();
-       }
-
-       TK_Beyond( TK_TRANSLATION );
-       for ( i = 0; i < 3; i++ )
-       {
-               TK_Require( TK_FLOATNUMBER );
-               g_translation[i] = tk_FloatNumber;
-               TK_Fetch();
-       }
-}
-
-static void ParseVec3( vec3_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void ParseRotation3( vec3_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = -tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void ParseTranslation3( vec3_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void LoadHRCJointList( char *fileName, QDataJoint_t *jointList, int skelType ){
-#define MAX_STACK 64
-       int i, j;
-       vec3_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];
-       int curCorrespondingJoint[MAX_STACK];
-       int currentStack = 0, stackSize;
-       int baseJoint;
-       float cx, sx, cy, sy, cz, sz;
-       float rx, ry, rz;
-       float x2, y2, z2;
-
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-
-       TK_Beyond( TK_MODEL );
-       TK_Beyond( TK_MODEL );
-
-/*     while(1)
-    {
-        TK_Beyond(TK_MODEL);
-        TK_BeyondRequire(TK_NAME, TK_STRING);
-
-        if(_stricmp(tk_String, SKEL_ROOT_NAMES[skelType]) == 0)
-            break;
-    }*/
-
-       TK_Beyond( TK_SCALING );
-
-       ParseVec3( curScale[currentStack] );
-
-       TK_Beyond( TK_ROTATION );
-
-       ParseRotation3( curRotation[currentStack] );
-
-       TK_Beyond( TK_TRANSLATION );
-
-       ParseVec3( curTranslation[currentStack] );
-
-       // account for global model translation
-       curTranslation[currentStack][1] += g_translation[0];
-       curTranslation[currentStack][2] += g_translation[1];
-       curTranslation[currentStack][0] += g_translation[2];
-
-       ++currentStack;
-
-       for ( i = 0; i < NUM_JOINTS_RAVEN; ++i )
-       {
-               while ( 1 )
-               {
-                       TK_Beyond( TK_MODEL );
-
-//                     TK_BeyondRequire(TK_NAME, TK_STRING);
-
-//                     if(_stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0)
-                       break;
-
-                       TK_Beyond( TK_SCALING );
-
-                       ParseVec3( curScale[currentStack] );
-
-                       TK_Beyond( TK_ROTATION );
-
-                       ParseRotation3( curRotation[currentStack] );
-
-                       TK_Beyond( TK_TRANSLATION );
-
-                       ParseVec3( curTranslation[currentStack] );
-
-                       curCorrespondingJoint[currentStack] = -1;
-
-                       ++currentStack;
-               }
-
-               TK_Beyond( TK_SCALING );
-
-               ParseVec3( curScale[currentStack] );
-
-               TK_Beyond( TK_ROTATION );
-
-               ParseRotation3( curRotation[currentStack] );
-
-               jointList[i].rotation[1] = curRotation[currentStack][1];
-               jointList[i].rotation[2] = curRotation[currentStack][2];
-               jointList[i].rotation[0] = curRotation[currentStack][0];
-
-               TK_Beyond( TK_TRANSLATION );
-
-               ParseVec3( curTranslation[currentStack] );
-
-               jointList[i].placement.origin[1] = curTranslation[currentStack][1];
-               jointList[i].placement.origin[2] = curTranslation[currentStack][2];
-               jointList[i].placement.origin[0] = curTranslation[currentStack][0];
-
-               jointList[i].placement.direction[1] = 7.5;
-               jointList[i].placement.direction[2] = 0.0;
-               jointList[i].placement.direction[0] = 0.0;
-
-               jointList[i].placement.up[1] = 0.0;
-               jointList[i].placement.up[2] = 7.5;
-               jointList[i].placement.up[0] = 0.0;
-
-               curCorrespondingJoint[currentStack] = i;
-
-               ++currentStack;
-       }
-
-       stackSize = currentStack;
-
-       for ( i = 0; i < NUM_JOINTS_RAVEN; ++i )
-       {
-               rx = jointList[i].rotation[0] * ANGLE_TO_RAD;
-               ry = jointList[i].rotation[1] * ANGLE_TO_RAD;
-               rz = jointList[i].rotation[2] * ANGLE_TO_RAD;
-
-               cx = cos( rx );
-               sx = sin( rx );
-
-               cy = cos( ry );
-               sy = sin( ry );
-
-               cz = cos( rz );
-               sz = sin( rz );
-
-               // y-axis rotation for direction
-               x2 = jointList[i].placement.direction[0] * cy + jointList[i].placement.direction[2] * sy;
-               z2 = -jointList[i].placement.direction[0] * sy + jointList[i].placement.direction[2] * cy;
-               jointList[i].placement.direction[0] = x2;
-               jointList[i].placement.direction[2] = z2;
-
-               // y-axis rotation for up
-               x2 = jointList[i].placement.up[0] * cy + jointList[i].placement.up[2] * sy;
-               z2 = -jointList[i].placement.up[0] * sy + jointList[i].placement.up[2] * cy;
-               jointList[i].placement.up[0] = x2;
-               jointList[i].placement.up[2] = z2;
-
-               // z-axis rotation for direction
-               x2 = jointList[i].placement.direction[0] * cz - jointList[i].placement.direction[1] * sz;
-               y2 = jointList[i].placement.direction[0] * sz + jointList[i].placement.direction[1] * cz;
-               jointList[i].placement.direction[0] = x2;
-               jointList[i].placement.direction[1] = y2;
-
-               // z-axis rotation for up
-               x2 = jointList[i].placement.up[0] * cz - jointList[i].placement.up[1] * sz;
-               y2 = jointList[i].placement.up[0] * sz + jointList[i].placement.up[1] * cz;
-               jointList[i].placement.up[0] = x2;
-               jointList[i].placement.up[1] = y2;
-
-               // x-axis rotation for direction vector
-               y2 = jointList[i].placement.direction[1] * cx - jointList[i].placement.direction[2] * sx;
-               z2 = jointList[i].placement.direction[1] * sx + jointList[i].placement.direction[2] * cx;
-               jointList[i].placement.direction[1] = y2;
-               jointList[i].placement.direction[2] = z2;
-
-               // x-axis rotation for up vector
-               y2 = jointList[i].placement.up[1] * cx - jointList[i].placement.up[2] * sx;
-               z2 = jointList[i].placement.up[1] * sx + jointList[i].placement.up[2] * cx;
-               jointList[i].placement.up[1] = y2;
-               jointList[i].placement.up[2] = z2;
-
-               // translate to position in model
-               jointList[i].placement.direction[0] += jointList[i].placement.origin[0];
-               jointList[i].placement.direction[1] += jointList[i].placement.origin[1];
-               jointList[i].placement.direction[2] += jointList[i].placement.origin[2];
-
-               // translate to position in model
-               jointList[i].placement.up[0] += jointList[i].placement.origin[0];
-               jointList[i].placement.up[1] += jointList[i].placement.origin[1];
-               jointList[i].placement.up[2] += jointList[i].placement.origin[2];
-       }
-
-       baseJoint = NUM_JOINTS_RAVEN;
-
-       for ( i = stackSize /*NUM_JOINTS_RAVEN*/ - 1; i > 0; --i )
-       {
-
-               rx = curRotation[i - 1][0] * ANGLE_TO_RAD;
-               ry = curRotation[i - 1][1] * ANGLE_TO_RAD;
-               rz = curRotation[i - 1][2] * ANGLE_TO_RAD;
-
-               cx = cos( rx );
-               sx = sin( rx );
-
-               cy = cos( ry );
-               sy = sin( ry );
-
-               cz = cos( rz );
-               sz = sin( rz );
-
-               for ( j = i - 1; j < stackSize - 1; ++j )
-               {
-                       // y-axis rotation for origin
-                       x2 = jointList[j].placement.origin[0] * cy + jointList[j].placement.origin[2] * sy;
-                       z2 = -jointList[j].placement.origin[0] * sy + jointList[j].placement.origin[2] * cy;
-                       jointList[j].placement.origin[0] = x2;
-                       jointList[j].placement.origin[2] = z2;
-
-                       // y-axis rotation for direction
-                       x2 = jointList[j].placement.direction[0] * cy + jointList[j].placement.direction[2] * sy;
-                       z2 = -jointList[j].placement.direction[0] * sy + jointList[j].placement.direction[2] * cy;
-                       jointList[j].placement.direction[0] = x2;
-                       jointList[j].placement.direction[2] = z2;
-
-                       // y-axis rotation for up
-                       x2 = jointList[j].placement.up[0] * cy + jointList[j].placement.up[2] * sy;
-                       z2 = -jointList[j].placement.up[0] * sy + jointList[j].placement.up[2] * cy;
-                       jointList[j].placement.up[0] = x2;
-                       jointList[j].placement.up[2] = z2;
-
-                       // z-axis rotation for origin
-                       x2 = jointList[j].placement.origin[0] * cz - jointList[j].placement.origin[1] * sz;
-                       y2 = jointList[j].placement.origin[0] * sz + jointList[j].placement.origin[1] * cz;
-                       jointList[j].placement.origin[0] = x2;
-                       jointList[j].placement.origin[1] = y2;
-
-                       // z-axis rotation for direction
-                       x2 = jointList[j].placement.direction[0] * cz - jointList[j].placement.direction[1] * sz;
-                       y2 = jointList[j].placement.direction[0] * sz + jointList[j].placement.direction[1] * cz;
-                       jointList[j].placement.direction[0] = x2;
-                       jointList[j].placement.direction[1] = y2;
-
-                       // z-axis rotation for up
-                       x2 = jointList[j].placement.up[0] * cz - jointList[j].placement.up[1] * sz;
-                       y2 = jointList[j].placement.up[0] * sz + jointList[j].placement.up[1] * cz;
-                       jointList[j].placement.up[0] = x2;
-                       jointList[j].placement.up[1] = y2;
-
-                       // x-axis rotation for origin
-                       y2 = jointList[j].placement.origin[1] * cx - jointList[j].placement.origin[2] * sx;
-                       z2 = jointList[j].placement.origin[1] * sx + jointList[j].placement.origin[2] * cx;
-                       jointList[j].placement.origin[1] = y2;
-                       jointList[j].placement.origin[2] = z2;
-
-                       // x-axis rotation for direction vector
-                       y2 = jointList[j].placement.direction[1] * cx - jointList[j].placement.direction[2] * sx;
-                       z2 = jointList[j].placement.direction[1] * sx + jointList[j].placement.direction[2] * cx;
-                       jointList[j].placement.direction[1] = y2;
-                       jointList[j].placement.direction[2] = z2;
-
-                       // x-axis rotation for up vector
-                       y2 = jointList[j].placement.up[1] * cx - jointList[j].placement.up[2] * sx;
-                       z2 = jointList[j].placement.up[1] * sx + jointList[j].placement.up[2] * cx;
-                       jointList[j].placement.up[1] = y2;
-                       jointList[j].placement.up[2] = z2;
-
-                       if ( curCorrespondingJoint[j + 1] != -1 ) {
-                               // translate origin
-                               jointList[j].placement.origin[0] += curTranslation[i - 1][0];
-                               jointList[j].placement.origin[1] += curTranslation[i - 1][1];
-                               jointList[j].placement.origin[2] += curTranslation[i - 1][2];
-
-                               // translate back to local coord
-                               jointList[j].placement.direction[0] += curTranslation[i - 1][0];
-                               jointList[j].placement.direction[1] += curTranslation[i - 1][1];
-                               jointList[j].placement.direction[2] += curTranslation[i - 1][2];
-
-                               // translate back to local coord
-                               jointList[j].placement.up[0] += curTranslation[i - 1][0];
-                               jointList[j].placement.up[1] += curTranslation[i - 1][1];
-                               jointList[j].placement.up[2] += curTranslation[i - 1][2];
-                       }
-               }
-       }
-}
-
-void LoadGlobals( char *fileName ){
-       FILE *file1;
-       int dot = '.';
-       char *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-
-                       LoadHRCGlobals( InputFileName );
-
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC match.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-                       printf( "\n" );
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRCGlobals( fileName );
-                               return;
-                       }
-               }
-
-               Error( "Could not open file '%s':\n",fileName );
-       }
-}
-
-void LoadClusters( char *fileName, int **clusterList, int *num_verts, int skelType ){
-       FILE *file1;
-       int dot = '.';
-       char *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-
-                       LoadHRCClustered( InputFileName, clusterList, num_verts, skelType );
-
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC match.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-                       printf( "\n" );
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRCClustered( fileName, clusterList, num_verts, skelType );
-                               return;
-                       }
-               }
-
-               Error( "Could not open file '%s':\n",fileName );
-       }
-}
-
-void LoadJointList( char *fileName, QDataJoint_t *jointList, int skelType ){
-       FILE *file1;
-       int dot = '.';
-       char *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-
-                       LoadHRCJointList( InputFileName, jointList, skelType );
-
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-                       printf( "\n" );
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRCJointList( fileName, jointList, skelType );
-
-                               return;
-                       }
-               }
-
-               Error( "Could not open file '%s':\n",fileName );
-       }
-}
diff --git a/tools/quake2/qdata_heretic2/jointed.h b/tools/quake2/qdata_heretic2/jointed.h
deleted file mode 100644 (file)
index 264d317..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _JOINTED_H
-#define _JOINTED_H
-
-#include "joints.h"
-
-void LoadGlobals( char *fileName );
-void LoadClusters( char *fileName, int **clusterList, int *num_verts, int skel_type );
-void LoadJointList( char *fileName, struct QDataJoint_s *jointList, int num_verts );
-
-#define NUM_CLUSTERS 8
-
-#define NOT_JOINTED -1
-
-#endif //_JOINTED_H
diff --git a/tools/quake2/qdata_heretic2/joints.h b/tools/quake2/qdata_heretic2/joints.h
deleted file mode 100644 (file)
index f8e64bf..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef JOINTS_H
-#define JOINTS_H
-
-#include "globaldefs.h"
-
-#ifdef _HERETIC2_
-#include "angles.h"
-#endif
-
-//typedef float vec3_t[3];
-//typedef unsigned char byte;
-
-#if !GDEF_OS_WINDOWS
-#define stricmp strcasecmp
-#define strcmpi strcasecmp
-#endif
-
-typedef struct Placement_s
-{
-       vec3_t origin;
-       vec3_t direction;
-       vec3_t up;
-} Placement_t;
-
-#if 1
-typedef struct QDataJoint_s
-{
-       Placement_t placement;
-       vec3_t rotation;
-} QDataJoint_t;
-#endif
-
-typedef struct ArrayedListNode_s
-{
-       int data;
-       int next;
-       int inUse;
-} ArrayedListNode_t;
-
-#define ARRAYEDLISTNODE_NULL -1
-
-typedef struct JointAngles_s
-{
-       float angles[3];
-       int children;
-       int created;
-} JointAngles_t;
-
-typedef struct JointAngles2_s
-{
-       float angles[3];
-       int children;
-       int changed[3];
-       int inUse;
-} JointAngles2_t;
-
-#define MAX_MODELJOINTS         256
-#define MAX_MODELJOINTNODES     255
-
-extern JointAngles_t jointAngles[MAX_MODELJOINTS];
-extern JointAngles2_t jointAngles2[MAX_MODELJOINTS];
-
-extern ArrayedListNode_t jointAngleNodes[MAX_MODELJOINTNODES];
-
-// Skeletal structures enums
-enum {
-       SKEL_RAVEN = 0,
-       SKEL_BOX,
-       NUM_SKELETONS
-};
-
-// Raven Skeletal structures enums
-enum {
-       RAVEN_WAIST1 = 0,
-       RAVEN_WAIST2 = 1,
-       RAVEN_HEAD = 2,
-       NUM_JOINTS_RAVEN
-};
-
-// Box Skeletal structures enums
-enum {
-       BOX_CENTER = 0,
-       NUM_JOINTS_BOX
-};
-
-extern int numJointsForSkeleton[];
-extern char *RAVEN_SKEL_NAMES[];
-
-#define J_NEW_SKELETON      0x00001000
-#define J_YAW_CHANGED       0x00002000
-#define J_PITCH_CHANGED     0x00004000
-#define J_ROLL_CHANGED      0x00008000
-#define MAX_JOINTS          0x00000fff
-/*
-   inline int GetFreeNode(ArrayedListNode_t *nodeArray, int max)
-   {   // yeah, I know this is a sucky, inefficient way to do this, but I didn't feel like taking the time to write a real resource manager in C
-    int i;
-
-    for(i = 0; i < max; ++i)
-    {
-        if(!nodeArray[i].inUse)
-        {
-            nodeArray[i].inUse = 1;
-            return i;
-        }
-    }
-
-    assert(0);
-    return -1;
-   }
-
-   inline void FreeNode(ArrayedListNode_t *nodeArray, int index)
-   {
-    nodeArray[index].inUse = 0;
-   }
- */
-int CreateSkeleton( int structure );
-void CreateSkeletonAtIndex( int structure, int index );
-void FreeSkeleton( int structure, int index );
-void SetJointAngle( int jointIndex, int angleIndex, float angle );
-float ModifyJointAngle( int jointIndex, int angleIndex, float deltaAngle );
-int ZeroJointAngle( int jointIndex, int angleIndex, float angVel );
-int ApplyAngVelToJoint( int jointIndex, int angleIndex, float angVel, float destAng );
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/models.c b/tools/quake2/qdata_heretic2/models.c
deleted file mode 100644 (file)
index 244f24a..0000000
+++ /dev/null
@@ -1,2041 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#include "qdata.h"
-#include <assert.h>
-#include "jointed.h"
-#include "fmodel.h"
-
-//=================================================================
-
-typedef struct
-{
-       int numnormals;
-       vec3_t normalsum;
-} vertexnormals_t;
-
-typedef struct
-{
-       vec3_t v;
-       int lightnormalindex;
-} trivert_t;
-
-typedef struct
-{
-       vec3_t mins, maxs;
-       char name[16];
-       trivert_t v[MAX_VERTS];
-       QDataJoint_t joints[NUM_CLUSTERS];    // ,this
-} frame_t;
-
-// ,and all of this should get out of here, need to use new stuff in fmodels instead
-
-typedef struct IntListNode_s
-{
-       int data;
-       struct IntListNode_s *next;
-} IntListNode_t;  // gaak
-
-typedef struct
-{
-       float scale[3];         // multiply byte verts by this
-       float translate[3];         // then add this
-} PartialAliasFrame_t;
-
-int jointed;
-int clustered;
-
-int *clusters[NUM_CLUSTERS];
-IntListNode_t *vertLists[NUM_CLUSTERS];
-int num_verts[NUM_CLUSTERS + 1];
-int new_num_verts[NUM_CLUSTERS + 1];
-
-// end that
-
-//================================================================
-
-frame_t g_frames[MAX_FRAMES];
-//frame_t              *g_frames;
-
-static dmdl_t model;
-
-
-float scale_up;                 // set by $scale
-vec3_t adjust;                  // set by $origin
-int g_fixedwidth, g_fixedheight;            // set by $skinsize
-
-
-//
-// base frame info
-//
-dstvert_t base_st[MAX_VERTS];
-dtriangle_t triangles[MAX_TRIANGLES];
-
-static int triangle_st[MAX_TRIANGLES][3][2];
-
-// the command list holds counts, s/t values, and xyz indexes
-// that are valid for every frame
-int commands[16384];
-int numcommands;
-int numglverts;
-int used[MAX_TRIANGLES];
-
-char g_skins[MAX_MD2SKINS][64];
-
-char cdarchive[1024];
-char cdpartial[1024];
-char cddir[1024];
-
-char modelname[64];         // empty unless $modelname issued (players)
-
-extern char        *g_outputDir;
-
-#define NUMVERTEXNORMALS    162
-
-float avertexnormals[NUMVERTEXNORMALS][3] =
-{
-       #include "anorms.h"
-};
-
-unsigned char pic[SKINPAGE_HEIGHT * SKINPAGE_WIDTH], pic_palette[768];
-
-FILE    *headerouthandle = NULL;
-
-//==============================================================
-
-/*
-   ===============
-   ClearModel
-   ===============
- */
-static void ClearModel( void ){
-       memset( &model, 0, sizeof( model ) );
-
-       modelname[0] = 0;
-       jointed = NOT_JOINTED;
-       clustered = 0;
-       scale_up = 1.0;
-       VectorCopy( vec3_origin, adjust );
-       g_fixedwidth = g_fixedheight = 0;
-       g_skipmodel = false;
-}
-
-
-void H_printf( char *fmt, ... ){
-       va_list argptr;
-       char name[1024];
-
-       if ( !headerouthandle ) {
-               sprintf( name, "%s/tris.h", cddir );
-               headerouthandle = SafeOpenWrite( name );
-               fprintf( headerouthandle, "// %s\n\n", cddir );
-               fprintf( headerouthandle, "// This file generated by qdata - Do NOT Modify\n\n" );
-       }
-
-       va_start( argptr, fmt );
-       vfprintf( headerouthandle, fmt, argptr );
-       va_end( argptr );
-}
-
-#if 1
-/*
-   ============
-   WriteModelFile
-   ============
- */
-void WriteCommonModelFile( FILE *modelouthandle, PartialAliasFrame_t *outFrames ){
-       int i;
-       dmdl_t modeltemp;
-       int j, k;
-       frame_t         *in;
-       daliasframe_t   *out;
-       byte buffer[MAX_VERTS * 4 + 128];
-       float v;
-       int c_on, c_off;
-
-       model.version = ALIAS_VERSION;
-       model.framesize = (int)&( (daliasframe_t *)0 )->verts[model.num_xyz];
-       model.num_glcmds = numcommands;
-       model.ofs_skins = sizeof( dmdl_t );
-       model.ofs_st = model.ofs_skins + model.num_skins * MAX_SKINNAME;
-       model.ofs_tris = model.ofs_st + model.num_st * sizeof( dstvert_t );
-       model.ofs_frames = model.ofs_tris + model.num_tris * sizeof( dtriangle_t );
-       model.ofs_glcmds = model.ofs_frames + model.num_frames * model.framesize;
-       model.ofs_end = model.ofs_glcmds + model.num_glcmds * sizeof( int );
-       //
-       // write out the model header
-       //
-       for ( i = 0 ; i < sizeof( dmdl_t ) / 4 ; i++ )
-               ( (int *)&modeltemp )[i] = LittleLong( ( (int *)&model )[i] );
-
-       SafeWrite( modelouthandle, &modeltemp, sizeof( modeltemp ) );
-
-       //
-       // write out the skin names
-       //
-       SafeWrite( modelouthandle, g_skins, model.num_skins * MAX_SKINNAME );
-
-       //
-       // write out the texture coordinates
-       //
-       c_on = c_off = 0;
-       for ( i = 0 ; i < model.num_st ; i++ )
-       {
-               base_st[i].s = LittleShort( base_st[i].s );
-               base_st[i].t = LittleShort( base_st[i].t );
-       }
-
-       SafeWrite( modelouthandle, base_st, model.num_st * sizeof( base_st[0] ) );
-
-       //
-       // write out the triangles
-       //
-       for ( i = 0 ; i < model.num_tris ; i++ )
-       {
-               int j;
-               dtriangle_t tri;
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       tri.index_xyz[j] = LittleShort( triangles[i].index_xyz[j] );
-                       tri.index_st[j] = LittleShort( triangles[i].index_st[j] );
-               }
-
-               SafeWrite( modelouthandle, &tri, sizeof( tri ) );
-       }
-
-       //
-       // write out the frames
-       //
-       for ( i = 0 ; i < model.num_frames ; i++ )
-       {
-               in = &g_frames[i];
-               out = (daliasframe_t *)buffer;
-
-               strcpy( out->name, in->name );
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       out->scale[j] = ( in->maxs[j] - in->mins[j] ) / 255;
-                       out->translate[j] = in->mins[j];
-
-                       if ( outFrames ) {
-                               outFrames[i].scale[j] = out->scale[j];
-                               outFrames[i].translate[j] = out->translate[j];
-                       }
-               }
-
-               for ( j = 0 ; j < model.num_xyz ; j++ )
-               {
-                       // all of these are byte values, so no need to deal with endianness
-                       out->verts[j].lightnormalindex = in->v[j].lightnormalindex;
-
-                       for ( k = 0 ; k < 3 ; k++ )
-                       {
-                               // scale to byte values & min/max check
-                               v = Q_rint( ( in->v[j].v[k] - out->translate[k] ) / out->scale[k] );
-
-                               // clamp, so rounding doesn't wrap from 255.6 to 0
-                               if ( v > 255.0 ) {
-                                       v = 255.0;
-                               }
-                               if ( v < 0 ) {
-                                       v = 0;
-                               }
-                               out->verts[j].v[k] = v;
-                       }
-               }
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       out->scale[j] = LittleFloat( out->scale[j] );
-                       out->translate[j] = LittleFloat( out->translate[j] );
-               }
-
-               SafeWrite( modelouthandle, out, model.framesize );
-       }
-
-       //
-       // write out glcmds
-       //
-       SafeWrite( modelouthandle, commands, numcommands * 4 );
-}
-
-/*
-   ============
-   WriteModelFile
-   ============
- */
-void WriteModelFile( FILE *modelouthandle ){
-       model.ident = IDALIASHEADER;
-
-       WriteCommonModelFile( modelouthandle, NULL );
-}
-
-/*
-   ============
-   WriteJointedModelFile
-   ============
- */
-void WriteJointedModelFile( FILE *modelouthandle ){
-       int i;
-       int j, k;
-       frame_t         *in;
-       float v;
-       IntListNode_t   *current, *toFree;
-       PartialAliasFrame_t outFrames[MAX_FRAMES];
-
-       model.ident = IDJOINTEDALIASHEADER;
-
-       WriteCommonModelFile( modelouthandle, outFrames );
-
-       // Skeletal Type
-       SafeWrite( modelouthandle, &jointed, sizeof( int ) );
-
-       // number of joints
-       SafeWrite( modelouthandle, &numJointsForSkeleton[jointed], sizeof( int ) );
-
-       // number of verts in each cluster
-       SafeWrite( modelouthandle, &new_num_verts[1], sizeof( int ) * numJointsForSkeleton[jointed] );
-
-       // cluster verts
-       for ( i = 0; i < new_num_verts[0]; ++i )
-       {
-               current = vertLists[i];
-               while ( current )
-               {
-                       SafeWrite( modelouthandle, &current->data, sizeof( int ) );
-                       toFree = current;
-                       current = current->next;
-                       free( toFree );  // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base
-               }
-       }
-
-       for ( i = 0 ; i < model.num_frames ; i++ )
-       {
-               in = &g_frames[i];
-
-               for ( j = 0 ; j < new_num_verts[0]; ++j )
-               {
-                       for ( k = 0 ; k < 3 ; k++ )
-                       {
-                               // scale to byte values & min/max check
-                               v = Q_rint( ( in->joints[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                               // clamp, so rounding doesn't wrap from 255.6 to 0
-                               if ( v > 255.0 ) {
-                                       v = 255.0;
-                               }
-
-                               if ( v < 0 ) {
-                                       v = 0;
-                               }
-
-                               // write out origin as a float (there's only a few per model, so it's not really
-                               // a size issue)
-                               SafeWrite( modelouthandle, &v, sizeof( float ) );
-                       }
-
-                       for ( k = 0 ; k < 3 ; k++ )
-                       {
-                               v = Q_rint( ( in->joints[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                               // clamp, so rounding doesn't wrap from 255.6 to 0
-                               if ( v > 255.0 ) {
-                                       v = 255.0;
-                               }
-
-                               if ( v < 0 ) {
-                                       v = 0;
-                               }
-
-                               // write out origin as a float (there's only a few per model, so it's not really
-                               // a size issue)
-                               SafeWrite( modelouthandle, &v, sizeof( float ) );
-                       }
-
-                       for ( k = 0 ; k < 3 ; k++ )
-                       {
-                               v = Q_rint( ( in->joints[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] );
-
-                               // clamp, so rounding doesn't wrap from 255.6 to 0
-                               if ( v > 255.0 ) {
-                                       v = 255.0;
-                               }
-
-                               if ( v < 0 ) {
-                                       v = 0;
-                               }
-
-                               // write out origin as a float (there's only a few per model, so it's not really
-                               // a size issue)
-                               SafeWrite( modelouthandle, &v, sizeof( float ) );
-                       }
-               }
-       }
-}
-#else
-/*
-   ============
-   WriteModelFile
-   ============
- */
-static void WriteModelFile( FILE *modelouthandle ){
-       int i;
-       dmdl_t modeltemp;
-       int j, k;
-       frame_t         *in;
-       daliasframe_t   *out;
-       byte buffer[MAX_VERTS * 4 + 128];
-       float v;
-       int c_on, c_off;
-
-       model.ident = IDALIASHEADER;
-       model.version = ALIAS_VERSION;
-       model.framesize = (int)&( (daliasframe_t *)0 )->verts[model.num_xyz];
-       model.num_glcmds = numcommands;
-       model.ofs_skins = sizeof( dmdl_t );
-       model.ofs_st = model.ofs_skins + model.num_skins * MAX_SKINNAME;
-       model.ofs_tris = model.ofs_st + model.num_st * sizeof( dstvert_t );
-       model.ofs_frames = model.ofs_tris + model.num_tris * sizeof( dtriangle_t );
-       model.ofs_glcmds = model.ofs_frames + model.num_frames * model.framesize;
-       model.ofs_end = model.ofs_glcmds + model.num_glcmds * 4;
-
-       //
-       // write out the model header
-       //
-       for ( i = 0 ; i < sizeof( dmdl_t ) / 4 ; i++ )
-               ( (int *)&modeltemp )[i] = LittleLong( ( (int *)&model )[i] );
-
-       SafeWrite( modelouthandle, &modeltemp, sizeof( modeltemp ) );
-
-       //
-       // write out the skin names
-       //
-       SafeWrite( modelouthandle, g_skins, model.num_skins * MAX_SKINNAME );
-
-       //
-       // write out the texture coordinates
-       //
-       c_on = c_off = 0;
-       for ( i = 0 ; i < model.num_st ; i++ )
-       {
-               base_st[i].s = LittleShort( base_st[i].s );
-               base_st[i].t = LittleShort( base_st[i].t );
-       }
-
-       SafeWrite( modelouthandle, base_st, model.num_st * sizeof( base_st[0] ) );
-
-       //
-       // write out the triangles
-       //
-       for ( i = 0 ; i < model.num_tris ; i++ )
-       {
-               int j;
-               dtriangle_t tri;
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       tri.index_xyz[j] = LittleShort( triangles[i].index_xyz[j] );
-                       tri.index_st[j] = LittleShort( triangles[i].index_st[j] );
-               }
-
-               SafeWrite( modelouthandle, &tri, sizeof( tri ) );
-       }
-
-       //
-       // write out the frames
-       //
-       for ( i = 0 ; i < model.num_frames ; i++ )
-       {
-               in = &g_frames[i];
-               out = (daliasframe_t *)buffer;
-
-               strcpy( out->name, in->name );
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       out->scale[j] = ( in->maxs[j] - in->mins[j] ) / 255;
-                       out->translate[j] = in->mins[j];
-               }
-
-               for ( j = 0 ; j < model.num_xyz ; j++ )
-               {
-                       // all of these are byte values, so no need to deal with endianness
-                       out->verts[j].lightnormalindex = in->v[j].lightnormalindex;
-
-                       for ( k = 0 ; k < 3 ; k++ )
-                       {
-                               // scale to byte values & min/max check
-                               v = Q_rint( ( in->v[j].v[k] - out->translate[k] ) / out->scale[k] );
-
-                               // clamp, so rounding doesn't wrap from 255.6 to 0
-                               if ( v > 255.0 ) {
-                                       v = 255.0;
-                               }
-                               if ( v < 0 ) {
-                                       v = 0;
-                               }
-                               out->verts[j].v[k] = v;
-                       }
-               }
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       out->scale[j] = LittleFloat( out->scale[j] );
-                       out->translate[j] = LittleFloat( out->translate[j] );
-               }
-
-               SafeWrite( modelouthandle, out, model.framesize );
-       }
-
-       //
-       // write out glcmds
-       //
-       SafeWrite( modelouthandle, commands, numcommands * 4 );
-}
-#endif
-
-/*
-   ===============
-   FinishModel
-   ===============
- */
-void FinishModel( void ){
-       FILE        *modelouthandle;
-       int i;
-       char name[1024];
-
-       if ( !model.num_frames ) {
-               return;
-       }
-
-//
-// copy to release directory tree if doing a release build
-//
-       if ( g_release ) {
-               if ( modelname[0] ) {
-                       sprintf( name, "%s", modelname );
-               }
-               else{
-                       sprintf( name, "%s/tris.md2", cdpartial );
-               }
-               ReleaseFile( name );
-
-               for ( i = 0 ; i < model.num_skins ; i++ )
-               {
-                       ReleaseFile( g_skins[i] );
-               }
-               model.num_frames = 0;
-               return;
-       }
-
-//
-// write the model output file
-//
-       if ( modelname[0] ) {
-               sprintf( name, "%s%s", g_outputDir, modelname );
-       }
-       else{
-               sprintf( name, "%s/tris.md2", g_outputDir );
-       }
-       printf( "saving to %s\n", name );
-       CreatePath( name );
-       modelouthandle = SafeOpenWrite( name );
-
-#if 1
-       if ( jointed != NOT_JOINTED ) {
-               WriteJointedModelFile( modelouthandle );
-       }
-       else
-#endif
-       WriteModelFile( modelouthandle );
-
-       printf( "%3dx%3d skin\n", model.skinwidth, model.skinheight );
-       printf( "First frame boundaries:\n" );
-       printf( "       minimum x: %3f\n", g_frames[0].mins[0] );
-       printf( "       maximum x: %3f\n", g_frames[0].maxs[0] );
-       printf( "       minimum y: %3f\n", g_frames[0].mins[1] );
-       printf( "       maximum y: %3f\n", g_frames[0].maxs[1] );
-       printf( "       minimum z: %3f\n", g_frames[0].mins[2] );
-       printf( "       maximum z: %3f\n", g_frames[0].maxs[2] );
-       printf( "%4d vertices\n", model.num_xyz );
-       printf( "%4d triangles\n", model.num_tris );
-       printf( "%4d frame\n", model.num_frames );
-       printf( "%4d glverts\n", numglverts );
-       printf( "%4d glcmd\n", model.num_glcmds );
-       printf( "%4d skins\n", model.num_skins );
-       printf( "file size: %d\n", (int)ftell( modelouthandle ) );
-       printf( "---------------------\n" );
-
-       fclose( modelouthandle );
-
-       // finish writing header file
-       H_printf( "\n" );
-
-       // scale_up is usefull to allow step distances to be adjusted
-       H_printf( "#define MODEL_SCALE\t\t%f\n", scale_up );
-
-       fclose( headerouthandle );
-       headerouthandle = NULL;
-}
-
-
-/*
-   =================================================================
-
-   ALIAS MODEL DISPLAY LIST GENERATION
-
-   =================================================================
- */
-
-int strip_xyz[128];
-int strip_st[128];
-int strip_tris[128];
-int stripcount;
-
-/*
-   ================
-   StripLength
-   ================
- */
-static int  StripLength( int starttri, int startv ){
-       int m1, m2;
-       int st1, st2;
-       int j;
-       dtriangle_t *last, *check;
-       int k;
-
-       used[starttri] = 2;
-
-       last = &triangles[starttri];
-
-       strip_xyz[0] = last->index_xyz[( startv ) % 3];
-       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
-       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
-       strip_st[0] = last->index_st[( startv ) % 3];
-       strip_st[1] = last->index_st[( startv + 1 ) % 3];
-       strip_st[2] = last->index_st[( startv + 2 ) % 3];
-
-       strip_tris[0] = starttri;
-       stripcount = 1;
-
-       m1 = last->index_xyz[( startv + 2 ) % 3];
-       st1 = last->index_st[( startv + 2 ) % 3];
-       m2 = last->index_xyz[( startv + 1 ) % 3];
-       st2 = last->index_st[( startv + 1 ) % 3];
-
-       // look for a matching triangle
-nexttri:
-       for ( j = starttri + 1, check = &triangles[starttri + 1]
-                 ; j < model.num_tris ; j++, check++ )
-       {
-               for ( k = 0 ; k < 3 ; k++ )
-               {
-                       if ( check->index_xyz[k] != m1 ) {
-                               continue;
-                       }
-                       if ( check->index_st[k] != st1 ) {
-                               continue;
-                       }
-                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
-                               continue;
-                       }
-                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
-                               continue;
-                       }
-
-                       // this is the next part of the fan
-
-                       // if we can't use this triangle, this tristrip is done
-                       if ( used[j] ) {
-                               goto done;
-                       }
-
-                       // the new edge
-                       if ( stripcount & 1 ) {
-                               m2 = check->index_xyz[ ( k + 2 ) % 3 ];
-                               st2 = check->index_st[ ( k + 2 ) % 3 ];
-                       }
-                       else
-                       {
-                               m1 = check->index_xyz[ ( k + 2 ) % 3 ];
-                               st1 = check->index_st[ ( k + 2 ) % 3 ];
-                       }
-
-                       strip_xyz[stripcount + 2] = check->index_xyz[ ( k + 2 ) % 3 ];
-                       strip_st[stripcount + 2] = check->index_st[ ( k + 2 ) % 3 ];
-                       strip_tris[stripcount] = j;
-                       stripcount++;
-
-                       used[j] = 2;
-                       goto nexttri;
-               }
-       }
-done:
-
-       // clear the temp used flags
-       for ( j = starttri + 1 ; j < model.num_tris ; j++ )
-               if ( used[j] == 2 ) {
-                       used[j] = 0;
-               }
-
-       return stripcount;
-}
-
-
-/*
-   ===========
-   FanLength
-   ===========
- */
-static int  FanLength( int starttri, int startv ){
-       int m1, m2;
-       int st1, st2;
-       int j;
-       dtriangle_t *last, *check;
-       int k;
-
-       used[starttri] = 2;
-
-       last = &triangles[starttri];
-
-       strip_xyz[0] = last->index_xyz[( startv ) % 3];
-       strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3];
-       strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3];
-       strip_st[0] = last->index_st[( startv ) % 3];
-       strip_st[1] = last->index_st[( startv + 1 ) % 3];
-       strip_st[2] = last->index_st[( startv + 2 ) % 3];
-
-       strip_tris[0] = starttri;
-       stripcount = 1;
-
-       m1 = last->index_xyz[( startv + 0 ) % 3];
-       st1 = last->index_st[( startv + 0 ) % 3];
-       m2 = last->index_xyz[( startv + 2 ) % 3];
-       st2 = last->index_st[( startv + 2 ) % 3];
-
-
-       // look for a matching triangle
-nexttri:
-       for ( j = starttri + 1, check = &triangles[starttri + 1]
-                 ; j < model.num_tris ; j++, check++ )
-       {
-               for ( k = 0 ; k < 3 ; k++ )
-               {
-                       if ( check->index_xyz[k] != m1 ) {
-                               continue;
-                       }
-                       if ( check->index_st[k] != st1 ) {
-                               continue;
-                       }
-                       if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) {
-                               continue;
-                       }
-                       if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) {
-                               continue;
-                       }
-
-                       // this is the next part of the fan
-
-                       // if we can't use this triangle, this tristrip is done
-                       if ( used[j] ) {
-                               goto done;
-                       }
-
-                       // the new edge
-                       m2 = check->index_xyz[ ( k + 2 ) % 3 ];
-                       st2 = check->index_st[ ( k + 2 ) % 3 ];
-
-                       strip_xyz[stripcount + 2] = m2;
-                       strip_st[stripcount + 2] = st2;
-                       strip_tris[stripcount] = j;
-                       stripcount++;
-
-                       used[j] = 2;
-                       goto nexttri;
-               }
-       }
-done:
-
-       // clear the temp used flags
-       for ( j = starttri + 1 ; j < model.num_tris ; j++ )
-               if ( used[j] == 2 ) {
-                       used[j] = 0;
-               }
-
-       return stripcount;
-}
-
-
-
-/*
-   ================
-   BuildGlCmds
-
-   Generate a list of trifans or strips
-   for the model, which holds for all frames
-   ================
- */
-static void BuildGlCmds( void ){
-       int i, j, k;
-       int startv;
-       float s, t;
-       int len, bestlen, besttype;
-       int best_xyz[1024];
-       int best_st[1024];
-       int best_tris[1024];
-       int type;
-
-       //
-       // build tristrips
-       //
-       numcommands = 0;
-       numglverts = 0;
-       memset( used, 0, sizeof( used ) );
-       for ( i = 0 ; i < model.num_tris ; i++ )
-       {
-               // pick an unused triangle and start the trifan
-               if ( used[i] ) {
-                       continue;
-               }
-
-               bestlen = 0;
-               for ( type = 0 ; type < 2 ; type++ )
-//     type = 1;
-               {
-                       for ( startv = 0 ; startv < 3 ; startv++ )
-                       {
-                               if ( type == 1 ) {
-                                       len = StripLength( i, startv );
-                               }
-                               else{
-                                       len = FanLength( i, startv );
-                               }
-                               if ( len > bestlen ) {
-                                       besttype = type;
-                                       bestlen = len;
-                                       for ( j = 0 ; j < bestlen + 2 ; j++ )
-                                       {
-                                               best_st[j] = strip_st[j];
-                                               best_xyz[j] = strip_xyz[j];
-                                       }
-                                       for ( j = 0 ; j < bestlen ; j++ )
-                                               best_tris[j] = strip_tris[j];
-                               }
-                       }
-               }
-
-               // mark the tris on the best strip/fan as used
-               for ( j = 0 ; j < bestlen ; j++ )
-                       used[best_tris[j]] = 1;
-
-               if ( besttype == 1 ) {
-                       commands[numcommands++] = ( bestlen + 2 );
-               }
-               else{
-                       commands[numcommands++] = -( bestlen + 2 );
-               }
-
-               numglverts += bestlen + 2;
-
-               for ( j = 0 ; j < bestlen + 2 ; j++ )
-               {
-                       // emit a vertex into the reorder buffer
-                       k = best_st[j];
-
-                       // emit s/t coords into the commands stream
-                       s = base_st[k].s;
-                       t = base_st[k].t;
-
-                       s = ( s + 0.5 ) / model.skinwidth;
-                       t = ( t + 0.5 ) / model.skinheight;
-
-                       *(float *)&commands[numcommands++] = s;
-                       *(float *)&commands[numcommands++] = t;
-                       *(int *)&commands[numcommands++] = best_xyz[j];
-               }
-       }
-
-       commands[numcommands++] = 0;        // end of list marker
-}
-
-
-/*
-   ===============================================================
-
-   BASE FRAME SETUP
-
-   ===============================================================
- */
-
-/*
-   ============
-   BuildST
-
-   Builds the triangle_st array for the base frame and
-   model.skinwidth / model.skinheight
-
-   FIXME: allow this to be loaded from a file for
-   arbitrary mappings
-   ============
- */
-#if 0
-static void OldBuildST( triangle_t *ptri, int numtri ){
-       int i, j;
-       int width, height, iwidth, iheight, swidth;
-       float basex, basey;
-       float s_scale, t_scale;
-       float scale;
-       vec3_t mins, maxs;
-       float       *pbasevert;
-       vec3_t vtemp1, vtemp2, normal;
-
-       //
-       // find bounds of all the verts on the base frame
-       //
-       ClearBounds( mins, maxs );
-
-       for ( i = 0 ; i < numtri ; i++ )
-               for ( j = 0 ; j < 3 ; j++ )
-                       AddPointToBounds( ptri[i].verts[j], mins, maxs );
-
-       for ( i = 0 ; i < 3 ; i++ )
-       {
-               mins[i] = floor( mins[i] );
-               maxs[i] = ceil( maxs[i] );
-       }
-
-       width = maxs[0] - mins[0];
-       height = maxs[2] - mins[2];
-
-       if ( !g_fixedwidth ) { // old style
-               scale = 8;
-               if ( width * scale >= 150 ) {
-                       scale = 150.0 / width;
-               }
-               if ( height * scale >= 190 ) {
-                       scale = 190.0 / height;
-               }
-
-               s_scale = t_scale = scale;
-
-               iwidth = ceil( width * s_scale );
-               iheight = ceil( height * t_scale );
-
-               iwidth += 4;
-               iheight += 4;
-       }
-       else
-       {   // new style
-               iwidth = g_fixedwidth / 2;
-               iheight = g_fixedheight;
-
-               s_scale = (float)( iwidth - 4 ) / width;
-               t_scale = (float)( iheight - 4 ) / height;
-       }
-
-//
-// determine which side of each triangle to map the texture to
-//
-       for ( i = 0 ; i < numtri ; i++ )
-       {
-               VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
-               VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
-               CrossProduct( vtemp1, vtemp2, normal );
-
-               if ( normal[1] > 0 ) {
-                       basex = iwidth + 2;
-               }
-               else
-               {
-                       basex = 2;
-               }
-               basey = 2;
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       pbasevert = ptri[i].verts[j];
-
-                       triangle_st[i][j][0] = Q_rint( ( pbasevert[0] - mins[0] ) * s_scale + basex );
-                       triangle_st[i][j][1] = Q_rint( ( maxs[2] - pbasevert[2] ) * t_scale + basey );
-               }
-       }
-
-// make the width a multiple of 4; some hardware requires this, and it ensures
-// dword alignment for each scan
-       swidth = iwidth * 2;
-       model.skinwidth = ( swidth + 3 ) & ~3;
-       model.skinheight = iheight;
-}
-#endif
-
-//==========================================================================
-//
-// DrawScreen
-//
-//==========================================================================
-
-void DrawScreen( float s_scale, float t_scale, float iwidth, float iheight ){
-       int i;
-       byte *scrpos;
-       char buffer[256];
-
-       // Divider
-       scrpos = &pic[( INFO_Y - 2 ) * SKINPAGE_WIDTH];
-       for ( i = 0; i < SKINPAGE_WIDTH; i++ )
-       {
-               *scrpos++ = 255;
-       }
-
-       sprintf( buffer, "GENSKIN:  " );
-       DrawTextChar( 16, INFO_Y, buffer );
-
-       sprintf( buffer, "( %03d * %03d )   SCALE %f %f, SKINWIDTH %d,"
-                                        " SKINHEIGHT %d", (int)ScaleWidth, (int)ScaleHeight, s_scale, t_scale, (int)iwidth * 2, (int)iheight );
-       DrawTextChar( 80, INFO_Y, buffer );
-}
-
-/*
-   ============
-   BuildST
-
-   Builds the triangle_st array for the base frame and
-   model.skinwidth / model.skinheight
-
-   FIXME: allow this to be loaded from a file for
-   arbitrary mappings
-   ============
- */
-void BuildST( triangle_t *ptri, int numtri, qboolean DrawSkin ){
-       int i, j;
-       int width, height, iwidth, iheight, swidth;
-       float basex, basey;
-       float scale;
-       vec3_t mins, maxs;
-       float       *pbasevert;
-       vec3_t vtemp1, vtemp2, normal;
-       float s_scale, t_scale;
-       float scWidth;
-       float scHeight;
-
-       //
-       // find bounds of all the verts on the base frame
-       //
-       ClearBounds( mins, maxs );
-
-       for ( i = 0 ; i < numtri ; i++ )
-               for ( j = 0 ; j < 3 ; j++ )
-                       AddPointToBounds( ptri[i].verts[j], mins, maxs );
-
-       for ( i = 0 ; i < 3 ; i++ )
-       {
-               mins[i] = floor( mins[i] );
-               maxs[i] = ceil( maxs[i] );
-       }
-
-       width = maxs[0] - mins[0];
-       height = maxs[2] - mins[2];
-
-
-       scWidth = ( ScaleWidth / 2 ) * SCALE_ADJUST_FACTOR;
-       scHeight = ScaleHeight * SCALE_ADJUST_FACTOR;
-
-       scale = scWidth / width;
-
-       if ( height * scale >= scHeight ) {
-               scale = scHeight / height;
-       }
-
-       iwidth = ceil( width * scale ) + 4;
-       iheight = ceil( height * scale ) + 4;
-
-       s_scale = (float)( iwidth - 4 ) / width;
-       t_scale = (float)( iheight - 4 ) / height;
-       t_scale = s_scale;
-
-       if ( DrawSkin ) {
-               DrawScreen( s_scale, t_scale, iwidth, iheight );
-       }
-
-
-/*     if (!g_fixedwidth)
-    {  // old style
-        scale = 8;
-        if (width*scale >= 150)
-            scale = 150.0 / width;
-        if (height*scale >= 190)
-            scale = 190.0 / height;
-
-        s_scale = t_scale = scale;
-
-        iwidth = ceil(width*s_scale);
-        iheight = ceil(height*t_scale);
-
-        iwidth += 4;
-        iheight += 4;
-    }
-    else
-    {  // new style
-        iwidth = g_fixedwidth / 2;
-        iheight = g_fixedheight;
-
-        s_scale = (float)(iwidth-4) / width;
-        t_scale = (float)(iheight-4) / height;
-    }*/
-
-//
-// determine which side of each triangle to map the texture to
-//
-       for ( i = 0 ; i < numtri ; i++ )
-       {
-               if ( ptri[i].HasUV ) {
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               triangle_st[i][j][0] = Q_rint( ptri[i].uv[j][0] * iwidth );
-                               triangle_st[i][j][1] = Q_rint( ( 1.0f - ptri[i].uv[j][1] ) * iheight );
-                       }
-               }
-               else
-               {
-                       VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
-                       VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
-                       CrossProduct( vtemp1, vtemp2, normal );
-
-                       if ( normal[1] > 0 ) {
-                               basex = iwidth + 2;
-                       }
-                       else
-                       {
-                               basex = 2;
-                       }
-                       basey = 2;
-
-                       for ( j = 0 ; j < 3 ; j++ )
-                       {
-                               pbasevert = ptri[i].verts[j];
-
-                               triangle_st[i][j][0] = Q_rint( ( pbasevert[0] - mins[0] ) * s_scale + basex );
-                               triangle_st[i][j][1] = Q_rint( ( maxs[2] - pbasevert[2] ) * t_scale + basey );
-                       }
-               }
-
-               DrawLine( triangle_st[i][0][0], triangle_st[i][0][1],
-                                 triangle_st[i][1][0], triangle_st[i][1][1] );
-               DrawLine( triangle_st[i][1][0], triangle_st[i][1][1],
-                                 triangle_st[i][2][0], triangle_st[i][2][1] );
-               DrawLine( triangle_st[i][2][0], triangle_st[i][2][1],
-                                 triangle_st[i][0][0], triangle_st[i][0][1] );
-       }
-
-// make the width a multiple of 4; some hardware requires this, and it ensures
-// dword alignment for each scan
-
-       swidth = iwidth * 2;
-       model.skinwidth = ( swidth + 3 ) & ~3;
-       model.skinheight = iheight;
-}
-
-
-static void ReplaceClusterIndex( int newIndex, int oldindex, int **clusters,
-                                                                IntListNode_t **vertLists, int *num_verts, int *new_num_verts ){
-       int i, j;
-       IntListNode_t *next;
-
-       for ( j = 0; j < num_verts[0]; ++j )
-       {
-               for ( i = 0; i < num_verts[j + 1]; ++i )
-               {
-                       if ( clusters[j][i] == oldindex ) {
-                               ++new_num_verts[j + 1];
-
-                               next = vertLists[j];
-
-                               vertLists[j] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "ReplaceClusterIndex" );
-                               // Currently freed in WriteJointedModelFile only
-
-                               vertLists[j]->data = newIndex;
-                               vertLists[j]->next = next;
-                       }
-               }
-       }
-}
-
-/*
-   =================
-   Cmd_Base
-   =================
- */
-void Cmd_Base( void ){
-       vec3_t base_xyz[MAX_VERTS];
-       triangle_t  *ptri;
-       int i, j, k;
-#if 1
-#else
-       int time1;
-#endif
-       char file1[1024];
-       char file2[1024];
-
-       GetScriptToken( false );
-
-       if ( g_skipmodel || g_release || g_archive ) {
-               return;
-       }
-
-       printf( "---------------------\n" );
-#if 1
-       sprintf( file1, "%s/%s", cdpartial, token );
-       printf( "%s  ", file1 );
-
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s", cddir, token );
-#else
-       sprintf( file1, "%s/%s.%s", cdarchive, token, trifileext );
-       printf( "%s\n", file1 );
-
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s.%s", cddir, token, trifileext );
-
-       time1 = FileTime( file1 );
-       if ( time1 == -1 ) {
-               Error( "%s doesn't exist", file1 );
-       }
-#endif
-//
-// load the base triangles
-//
-       if ( do3ds ) {
-               Load3DSTriangleList( file1, &ptri, &model.num_tris, NULL, NULL );
-       }
-       else{
-               LoadTriangleList( file1, &ptri, &model.num_tris, NULL, NULL );
-       }
-
-
-       GetScriptToken( false );
-       sprintf( file2, "%s/%s.pcx", cddir, token );
-//     sprintf (trans_file, "%s/!%s_a.pcx", cddir, token);
-
-       printf( "skin: %s\n", file2 );
-       Load256Image( file2, &BasePixels, &BasePalette, &BaseWidth, &BaseHeight );
-
-       if ( BaseWidth != SKINPAGE_WIDTH || BaseHeight != SKINPAGE_HEIGHT ) {
-               if ( g_allow_newskin ) {
-                       ScaleWidth = BaseWidth;
-                       ScaleHeight = BaseHeight;
-               }
-               else
-               {
-                       Error( "Invalid skin page size: (%d,%d) should be (%d,%d)",
-                                  BaseWidth,BaseHeight,SKINPAGE_WIDTH,SKINPAGE_HEIGHT );
-               }
-       }
-       else
-       {
-               ScaleWidth = (float)ExtractNumber( BasePixels, ENCODED_WIDTH_X,
-                                                                                  ENCODED_WIDTH_Y );
-               ScaleHeight = (float)ExtractNumber( BasePixels, ENCODED_HEIGHT_X,
-                                                                                       ENCODED_HEIGHT_Y );
-       }
-
-//
-// get the ST values
-//
-       BuildST( ptri, model.num_tris,false );
-
-//
-// run through all the base triangles, storing each unique vertex in the
-// base vertex list and setting the indirect triangles to point to the base
-// vertices
-//
-       for ( i = 0 ; i < model.num_tris ; i++ )
-       {
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       // get the xyz index
-                       for ( k = 0 ; k < model.num_xyz ; k++ )
-                               if ( VectorCompare( ptri[i].verts[j], base_xyz[k] ) ) {
-                                       break;
-                               }           // this vertex is already in the base vertex list
-
-                       if ( k == model.num_xyz ) { // new index
-                               VectorCopy( ptri[i].verts[j], base_xyz[model.num_xyz] );
-
-                               if ( clustered ) {
-                                       ReplaceClusterIndex( k, ptri[i].indicies[j], (int **)&clusters, (IntListNode_t **)&vertLists, (int *)&num_verts, (int *)&new_num_verts );
-                               }
-
-                               model.num_xyz++;
-                       }
-
-                       triangles[i].index_xyz[j] = k;
-
-                       // get the st index
-                       for ( k = 0 ; k < model.num_st ; k++ )
-                               if ( triangle_st[i][j][0] == base_st[k].s
-                                        && triangle_st[i][j][1] == base_st[k].t ) {
-                                       break;
-                               }           // this vertex is already in the base vertex list
-
-                       if ( k == model.num_st ) { // new index
-                               base_st[model.num_st].s = triangle_st[i][j][0];
-                               base_st[model.num_st].t = triangle_st[i][j][1];
-                               model.num_st++;
-                       }
-
-                       triangles[i].index_st[j] = k;
-               }
-       }
-
-       // build triangle strips / fans
-       BuildGlCmds();
-}
-
-//===============================================================
-
-char    *FindFrameFile( char *frame ){
-       int time1;
-       char file1[1024];
-       static char retname[1024];
-       char base[32];
-       char suffix[32];
-       char            *s;
-
-       if ( strstr( frame, "." ) ) {
-               return frame;       // allready in dot format
-
-       }
-       // split 'run1' into 'run' and '1'
-       s = frame + strlen( frame ) - 1;
-
-       while ( s != frame && *s >= '0' && *s <= '9' )
-               s--;
-
-       strcpy( suffix, s + 1 );
-       strcpy( base, frame );
-       base[s - frame + 1] = 0;
-
-       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "hrc" );
-       time1 = FileTime( file1 );
-       if ( time1 != -1 ) {
-               sprintf( retname, "%s%s.%s", base, suffix, "hrc" );
-               return retname;
-       }
-
-       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "asc" );
-       time1 = FileTime( file1 );
-       if ( time1 != -1 ) {
-               sprintf( retname, "%s%s.%s", base, suffix, "asc" );
-               return retname;
-       }
-
-       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "tri" );
-       time1 = FileTime( file1 );
-       if ( time1 != -1 ) {
-               sprintf( retname, "%s%s.%s", base, suffix, "tri" );
-               return retname;
-       }
-
-       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "3ds" );
-       time1 = FileTime( file1 );
-       if ( time1 != -1 ) {
-               sprintf( retname, "%s%s.%s", base, suffix, "3ds" );
-               return retname;
-       }
-
-       sprintf( file1, "%s/%s%s.%s",cddir, base, suffix, "htr" );
-       time1 = FileTime( file1 );
-       if ( time1 != -1 ) {
-               sprintf( retname, "%s%s.%s", base, suffix, "htr" );
-               return retname;
-       }
-
-       // check for 'run.1'
-       sprintf( file1, "%s/%s.%s",cddir, base, suffix );
-       time1 = FileTime( file1 );
-       if ( time1 != -1 ) {
-               sprintf( retname, "%s.%s", base, suffix );
-               return retname;
-       }
-
-       Error( "frame %s could not be found",frame );
-       return NULL;
-}
-
-/*
-   ===============
-   GrabFrame
-   ===============
- */
-static void GrabFrame( char *frame ){
-       triangle_t      *ptri;
-       int i, j;
-       trivert_t       *ptrivert;
-       int num_tris;
-       char file1[1024];
-       frame_t         *fr;
-       vertexnormals_t vnorms[MAX_VERTS];
-       int index_xyz;
-       char            *framefile;
-
-       // the frame 'run1' will be looked for as either
-       // run.1 or run1.tri, so the new alias sequence save
-       // feature an be used
-       framefile = FindFrameFile( frame );
-
-       sprintf( file1, "%s/%s", cdarchive, framefile );
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s",cddir, framefile );
-
-       printf( "grabbing %s  ", file1 );
-
-       if ( model.num_frames >= MAX_FRAMES ) {
-               Error( "model.num_frames >= MAX_FRAMES" );
-       }
-       fr = &g_frames[model.num_frames];
-       model.num_frames++;
-
-       strcpy( fr->name, frame );
-
-//
-// load the frame
-//
-       if ( do3ds ) {
-               Load3DSTriangleList( file1, &ptri, &num_tris, NULL, NULL );
-       }
-       else{
-               LoadTriangleList( file1, &ptri, &num_tris, NULL, NULL );
-       }
-
-       if ( num_tris != model.num_tris ) {
-               Error( "%s: number of triangles doesn't match base frame\n", file1 );
-       }
-
-//
-// allocate storage for the frame's vertices
-//
-       ptrivert = fr->v;
-
-       for ( i = 0 ; i < model.num_xyz ; i++ )
-       {
-               vnorms[i].numnormals = 0;
-               VectorClear( vnorms[i].normalsum );
-       }
-       ClearBounds( fr->mins, fr->maxs );
-
-//
-// store the frame's vertices in the same order as the base. This assumes the
-// triangles and vertices in this frame are in exactly the same order as in the
-// base
-//
-       for ( i = 0 ; i < num_tris ; i++ )
-       {
-               vec3_t vtemp1, vtemp2, normal;
-               float ftemp;
-
-               VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 );
-               VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 );
-               CrossProduct( vtemp1, vtemp2, normal );
-
-               VectorNormalize( normal, normal );
-
-               // rotate the normal so the model faces down the positive x axis
-               ftemp = normal[0];
-               normal[0] = -normal[1];
-               normal[1] = ftemp;
-
-               for ( j = 0 ; j < 3 ; j++ )
-               {
-                       index_xyz = triangles[i].index_xyz[j];
-
-                       // rotate the vertices so the model faces down the positive x axis
-                       // also adjust the vertices to the desired origin
-                       ptrivert[index_xyz].v[0] = ( ( -ptri[i].verts[j][1] ) * scale_up ) +
-                                                                          adjust[0];
-                       ptrivert[index_xyz].v[1] = ( ptri[i].verts[j][0] * scale_up ) +
-                                                                          adjust[1];
-                       ptrivert[index_xyz].v[2] = ( ptri[i].verts[j][2] * scale_up ) +
-                                                                          adjust[2];
-
-                       AddPointToBounds( ptrivert[index_xyz].v, fr->mins, fr->maxs );
-
-                       VectorAdd( vnorms[index_xyz].normalsum, normal, vnorms[index_xyz].normalsum );
-                       vnorms[index_xyz].numnormals++;
-               }
-       }
-
-//
-// calculate the vertex normals, match them to the template list, and store the
-// index of the best match
-//
-       for ( i = 0 ; i < model.num_xyz ; i++ )
-       {
-               int j;
-               vec3_t v;
-               float maxdot;
-               int maxdotindex;
-               int c;
-
-               c = vnorms[i].numnormals;
-               if ( !c ) {
-                       Error( "Vertex with no triangles attached" );
-               }
-
-               VectorScale( vnorms[i].normalsum, 1.0 / c, v );
-               VectorNormalize( v, v );
-
-               maxdot = -999999.0;
-               maxdotindex = -1;
-
-               for ( j = 0 ; j < NUMVERTEXNORMALS ; j++ )
-               {
-                       float dot;
-
-                       dot = DotProduct( v, avertexnormals[j] );
-                       if ( dot > maxdot ) {
-                               maxdot = dot;
-                               maxdotindex = j;
-                       }
-               }
-
-               ptrivert[i].lightnormalindex = maxdotindex;
-       }
-
-       free( ptri );
-}
-
-/*
-   ===============
-   GrabJointedFrame
-   ===============
- */
-void GrabJointedFrame( char *frame ){
-       char file1[1024];
-       char    *framefile;
-       frame_t     *fr;
-
-       framefile = FindFrameFile( frame );
-
-       sprintf( file1, "%s/%s", cdarchive, framefile );
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s",cddir, framefile );
-
-       printf( "grabbing %s\n", file1 );
-
-       fr = &g_frames[model.num_frames - 1]; // last frame read in
-
-       LoadJointList( file1, fr->joints, jointed );
-}
-
-/*
-   ===============
-   GrabGlobals
-   ===============
- */
-void GrabGlobals( char *frame ){
-       char file1[1024];
-       char    *framefile;
-       frame_t     *fr;
-
-       framefile = FindFrameFile( frame );
-
-       sprintf( file1, "%s/%s", cdarchive, framefile );
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s",cddir, framefile );
-
-       printf( "grabbing %s\n", file1 );
-
-       fr = &g_frames[model.num_frames - 1]; // last frame read in
-
-       LoadGlobals( file1 );
-}
-
-/*
-   ===============
-   Cmd_Frame
-   ===============
- */
-void Cmd_Frame( void ){
-       while ( ScriptTokenAvailable() )
-       {
-               GetScriptToken( false );
-               if ( g_skipmodel ) {
-                       continue;
-               }
-               if ( g_release || g_archive ) {
-                       model.num_frames = 1;   // don't skip the writeout
-                       continue;
-               }
-
-               H_printf( "#define FRAME_%-16s\t%i\n", token, model.num_frames );
-
-               GrabFrame( token );
-       }
-}
-
-/*
-   ===============
-   Cmd_Skin
-
-   Skins aren't actually stored in the file, only a reference
-   is saved out to the header file.
-   ===============
- */
-void Cmd_Skin( void ){
-       byte    *palette;
-       byte    *pixels;
-       int width, height;
-       byte    *cropped;
-       int y;
-       char name[1024], savename[1024];
-
-       GetScriptToken( false );
-
-       if ( model.num_skins == MAX_MD2SKINS ) {
-               Error( "model.num_skins == MAX_MD2SKINS" );
-       }
-
-       if ( g_skipmodel ) {
-               return;
-       }
-
-#if 1
-       sprintf( name, "%s/%s.pcx", cddir, token );
-       sprintf( savename, "%s/!%s.pcx", g_outputDir, token );
-       sprintf( g_skins[model.num_skins], "%s/!%s.pcx", cdpartial, token );
-#else
-       sprintf( name, "%s/%s.lbm", cdarchive, token );
-       strcpy( name, ExpandPathAndArchive( name ) );
-//     sprintf (name, "%s/%s.lbm", cddir, token);
-
-       if ( ScriptTokenAvailable() ) {
-               GetScriptToken( false );
-               sprintf( g_skins[model.num_skins], "%s.pcx", token );
-               sprintf( savename, "%s%s.pcx", g_outputDir, g_skins[model.num_skins] );
-       }
-       else
-       {
-               sprintf( savename, "%s/%s.pcx", g_outputDir, token );
-               sprintf( g_skins[model.num_skins], "%s/%s.pcx", cdpartial, token );
-       }
-#endif
-
-       model.num_skins++;
-
-       if ( g_skipmodel || g_release || g_archive ) {
-               return;
-       }
-
-       // load the image
-       printf( "loading %s\n", name );
-       Load256Image( name, &pixels, &palette, &width, &height );
-//     RemapZero (pixels, palette, width, height);
-
-       // crop it to the proper size
-       cropped = (byte *) SafeMalloc( model.skinwidth * model.skinheight, "Cmd_Skin" );
-       for ( y = 0 ; y < model.skinheight ; y++ )
-       {
-               memcpy( cropped + y * model.skinwidth,
-                               pixels + y * width, model.skinwidth );
-       }
-
-       // save off the new image
-       printf( "saving %s\n", savename );
-       CreatePath( savename );
-       WritePCXfile( savename, cropped, model.skinwidth,
-                                 model.skinheight, palette );
-
-       free( pixels );
-       free( palette );
-       free( cropped );
-}
-
-
-/*
-   =================
-   Cmd_Origin
-   =================
- */
-void Cmd_Origin( void ){
-       // rotate points into frame of reference so model points down the
-       // positive x axis
-       GetScriptToken( false );
-       adjust[1] = -atof( token );
-
-       GetScriptToken( false );
-       adjust[0] = atof( token );
-
-       GetScriptToken( false );
-       adjust[2] = -atof( token );
-}
-
-
-/*
-   =================
-   Cmd_ScaleUp
-   =================
- */
-void Cmd_ScaleUp( void ){
-       GetScriptToken( false );
-       scale_up = atof( token );
-       if ( g_skipmodel || g_release || g_archive ) {
-               return;
-       }
-
-       printf( "Scale up: %f\n", scale_up );
-}
-
-
-/*
-   =================
-   Cmd_Skinsize
-
-   Set a skin size other than the default
-   =================
- */
-void Cmd_Skinsize( void ){
-       GetScriptToken( false );
-       g_fixedwidth = atoi( token );
-       GetScriptToken( false );
-       g_fixedheight = atoi( token );
-}
-
-/*
-   =================
-   Cmd_Modelname
-
-   Gives a different name/location for the file, instead of the cddir
-   =================
- */
-void Cmd_Modelname( void ){
-       GetScriptToken( false );
-       strcpy( modelname, token );
-}
-
-/*
-   ===============
-   Cmd_Cd
-   ===============
- */
-void Cmd_Cd( void ){
-       char temp[256];
-
-       FinishModel();
-       ClearModel();
-
-       GetScriptToken( false );
-
-       // this is a silly mess...
-       sprintf( cdpartial, "models/%s", token );
-       sprintf( cdarchive, "%smodels/%s", gamedir + strlen( qdir ), token );
-       sprintf( cddir, "%s%s", gamedir, cdpartial );
-
-       // Since we also changed directories on the output side (for mirror) make sure the outputdir is set properly too.
-       sprintf( temp, "%s%s", g_outputDir, cdpartial );
-       strcpy( g_outputDir, temp );
-
-       // if -only was specified and this cd doesn't match,
-       // skip the model (you only need to match leading chars,
-       // so you could regrab all monsters with -only monsters)
-       if ( !g_only[0] ) {
-               return;
-       }
-       if ( strncmp( token, g_only, strlen( g_only ) ) ) {
-               g_skipmodel = true;
-               printf( "skipping %s\n", cdpartial );
-       }
-}
-
-/*
-   =================
-   Cmd_Cluster
-   =================
- */
-void Cmd_Cluster(){
-       char file1[1024];
-
-       GetScriptToken( false );
-
-       printf( "---------------------\n" );
-       sprintf( file1, "%s/%s", cdpartial, token );
-       printf( "%s\n", file1 );
-
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s", cddir, token );
-
-       LoadClusters( file1, (int **)&clusters, (int *)&num_verts, jointed );
-
-       new_num_verts[0] = num_verts[0];
-
-       clustered = 1;
-}
-
-// Model construction cover functions.
-void MODELCMD_Modelname( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       Cmd_Modelname();
-/*
-    switch(modeltype)
-    {
-    case MODEL_MD2:
-        Cmd_Modelname ();
-        break;
-    case MODEL_FM:
-        Cmd_FMModelname ();
-        break;
-    }
- */
-}
-
-void MODELCMD_Cd( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               Cmd_Cd();
-               break;
-       case MODEL_FM:
-               Cmd_FMCd();
-               break;
-       }
-}
-
-void MODELCMD_Origin( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       Cmd_Origin();
-/*     switch(modeltype)
-    {
-    case MODEL_MD2:
-        Cmd_Origin ();
-        break;
-    case MODEL_FM:
-        Cmd_FMOrigin ();
-        break;
-    }
- */
-}
-
-void MODELCMD_Cluster( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               Cmd_Cluster();
-               break;
-       case MODEL_FM:
-               Cmd_FMCluster();
-               break;
-       }
-}
-
-void MODELCMD_Base( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               Cmd_Base();
-               break;
-       case MODEL_FM:
-               Cmd_FMBase( false );
-               break;
-       }
-}
-
-void MODELCMD_BaseST( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               Cmd_Base();
-               break;
-       case MODEL_FM:
-               Cmd_FMBase( true );
-               break;
-       }
-}
-
-void MODELCMD_ScaleUp( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       Cmd_ScaleUp();
-/*     switch(modeltype)
-    {
-    case MODEL_MD2:
-        Cmd_ScaleUp ();
-        break;
-    case MODEL_FM:
-        Cmd_FMScaleUp ();
-        break;
-    }
- */
-}
-
-void MODELCMD_Frame( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               Cmd_Frame();
-               break;
-       case MODEL_FM:
-               Cmd_FMFrame();
-               break;
-       }
-}
-
-void MODELCMD_Skin( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               Cmd_Skin();
-               break;
-       case MODEL_FM:
-               Cmd_FMSkin();
-               break;
-       }
-}
-
-void MODELCMD_Skinsize( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       Cmd_Skinsize();
-/*
-    switch(modeltype)
-    {
-    case MODEL_MD2:
-        Cmd_Skinsize ();
-        break;
-    case MODEL_FM:
-        Cmd_FMSkinsize ();
-        break;
-    }
- */
-}
-
-void MODELCMD_Skeleton( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               break;
-       case MODEL_FM:
-               Cmd_FMSkeleton();
-               break;
-       }
-}
-
-void MODELCMD_BeginGroup( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               break;
-       case MODEL_FM:
-               Cmd_FMBeginGroup();
-               break;
-       }
-}
-
-void MODELCMD_EndGroup( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               break;
-       case MODEL_FM:
-               Cmd_FMEndGroup();
-               break;
-       }
-}
-
-void MODELCMD_Referenced( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               break;
-       case MODEL_FM:
-               Cmd_FMReferenced();
-               break;
-       }
-}
-
-void MODELCMD_NodeOrder( int modeltype ){
-       if ( g_forcemodel ) {
-               modeltype = g_forcemodel;
-       }
-
-       switch ( modeltype )
-       {
-       case MODEL_MD2:
-               break;
-       case MODEL_FM:
-               Cmd_FMNodeOrder();
-               break;
-       }
-}
diff --git a/tools/quake2/qdata_heretic2/pics.c b/tools/quake2/qdata_heretic2/pics.c
deleted file mode 100644 (file)
index e9e91c2..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#include "qdata.h"
-
-byte            *byteimage, *lbmpalette;
-int byteimagewidth, byteimageheight;
-
-qboolean TrueColorImage;
-unsigned        *longimage;
-int longimagewidth, longimageheight;
-
-char pic_prefix[1024];
-extern char        *g_outputDir;
-
-/*
-   ===============
-   Cmd_Pic
-   ===============
- */
-
-void Cmd_Pic( void ){
-       int xl,yl,xh,yh,w,h;
-       byte            *dest, *source;
-       int flags, value, contents;
-       char lumpname[128];
-       char animname[128];
-       byte buffer[256 * 256];
-       unsigned bufferl[256 * 256];
-       char filename[1024];
-       unsigned        *destl, *sourcel;
-       int linedelta, x, y;
-       int size;
-       miptex_t        *qtex;
-       miptex32_t      *qtex32;
-       float scale_x, scale_y;
-
-       GetScriptToken( false );
-       strcpy( lumpname, token );
-
-       GetScriptToken( false );
-       xl = atoi( token );
-       GetScriptToken( false );
-       yl = atoi( token );
-       GetScriptToken( false );
-       w = atoi( token );
-       GetScriptToken( false );
-       h = atoi( token );
-
-       total_x += w;
-       total_y += h;
-       total_textures++;
-
-       if ( ( w & 7 ) || ( h & 7 ) ) {
-               Error( "line %i: miptex sizes must be multiples of 8", scriptline );
-       }
-
-       flags = 0;
-       contents = 0;
-       value = 0;
-
-       animname[0] = 0;
-
-       scale_x = scale_y = 0.5;
-
-       if ( TrueColorImage ) {
-               sprintf( filename, "%spics/%s/%s.m32", g_outputDir, pic_prefix, lumpname );
-               if ( g_release ) {
-                       return; // textures are only released by $maps
-
-               }
-               xh = xl + w;
-               yh = yl + h;
-
-               if ( xl >= longimagewidth || xh > longimagewidth ||
-                        yl >= longimageheight || yh > longimageheight ) {
-                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight );
-               }
-
-               sourcel = longimage + ( yl * longimagewidth ) + xl;
-               destl = bufferl;
-               linedelta = ( longimagewidth - w );
-
-               for ( y = yl ; y < yh ; y++ )
-               {
-                       for ( x = xl ; x < xh ; x++ )
-                       {
-                               *destl++ = *sourcel++;  // RGBA
-                       }
-                       sourcel += linedelta;
-               }
-
-               qtex32 = CreateMip32( bufferl, w, h, &size, false );
-
-               qtex32->flags |= LittleLong( flags );
-               qtex32->contents = contents;
-               qtex32->value = value;
-               qtex32->scale_x = scale_x;
-               qtex32->scale_y = scale_y;
-               sprintf( qtex32->name, "%s/%s", pic_prefix, lumpname );
-               if ( animname[0] ) {
-                       sprintf( qtex32->animname, "%s/%s", pic_prefix, animname );
-               }
-
-               //
-               // write it out
-               //
-               printf( "writing %s\n", filename );
-               SaveFile( filename, (byte *)qtex32, size );
-
-               free( qtex32 );
-       }
-       else
-       {
-               sprintf( filename, "%spics/%s/%s.m8", g_outputDir, pic_prefix, lumpname );
-               if ( g_release ) {
-                       return; // textures are only released by $maps
-
-               }
-               xh = xl + w;
-               yh = yl + h;
-
-               if ( xl >= byteimagewidth || xh > byteimagewidth ||
-                        yl >= byteimageheight || yh > byteimageheight ) {
-                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
-               }
-
-               source = byteimage + yl * byteimagewidth + xl;
-               dest = buffer;
-               linedelta = byteimagewidth - w;
-
-               for ( y = yl ; y < yh ; y++ )
-               {
-                       for ( x = xl ; x < xh ; x++ )
-                       {
-                               *dest++ = *source++;
-                       }
-                       source += linedelta;
-               }
-
-               qtex = CreateMip( buffer, w, h, lbmpalette, &size, false );
-
-               qtex->flags = flags;
-               qtex->contents = contents;
-               qtex->value = value;
-               sprintf( qtex->name, "%s/%s", pic_prefix, lumpname );
-               if ( animname[0] ) {
-                       sprintf( qtex->animname, "%s/%s", pic_prefix, animname );
-               }
-
-               //
-               // write it out
-               //
-               printf( "writing %s\n", filename );
-               SaveFile( filename, (byte *)qtex, size );
-
-               free( qtex );
-       }
-}
-
-
-/*
-   ===============
-   Cmd_picdir
-   ===============
- */
-void Cmd_Picdir( void ){
-       char filename[1024];
-
-       GetScriptToken( false );
-       strcpy( pic_prefix, token );
-       // create the directory if needed
-       sprintf( filename, "%sPics", g_outputDir );
-       Q_mkdir( filename );
-       sprintf( filename, "%sPics/%s", g_outputDir, pic_prefix );
-       Q_mkdir( filename );
-}
diff --git a/tools/quake2/qdata_heretic2/qcommon/angles.h b/tools/quake2/qdata_heretic2/qcommon/angles.h
deleted file mode 100644 (file)
index b0baf31..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// Angles in radians
-
-#define ANGLE_0         0.0F
-#define ANGLE_1         0.017453292F
-#define ANGLE_5         0.087266462F
-#define ANGLE_10        0.174532925F
-#define ANGLE_15        0.261799387F
-#define ANGLE_20        0.392699081F
-#define ANGLE_30        0.523598775F
-#define ANGLE_45        0.785398163F
-#define ANGLE_60        1.047197551F
-#define ANGLE_72        1.256637061F
-#define ANGLE_90        1.570796327F
-#define ANGLE_120       2.094395102F
-#define ANGLE_135       2.35619449F
-#define ANGLE_144       2.513274123F
-#define ANGLE_180       3.141592653F
-#define ANGLE_225       3.926990817F
-#define ANGLE_270       4.71238898F
-#define ANGLE_315       5.497787144F
-#define ANGLE_360       6.283185307F
-
-// Angles in degrees
-
-#define DEGREE_0        0.0F
-#define DEGREE_180      180.0F
-#define DEGREE_45       ( DEGREE_180 / 4.0F )
-#define DEGREE_90       ( DEGREE_180 / 2.0F )
-#define DEGREE_135      ( DEGREE_90 + DEGREE_45 )
-#define DEGREE_270      ( DEGREE_180 + DEGREE_90 )
-#define DEGREE_360      ( DEGREE_180 * 2.0F )
-
-#define DEGREE_225      ( DEGREE_180 + DEGREE_45 )
-#define DEGREE_315      ( DEGREE_270 + DEGREE_45 )
-
-#define DEGREE_30       ( DEGREE_180 / 6.0F )
-#define DEGREE_60       ( DEGREE_180 / 3.0F )
-#define DEGREE_120      ( DEGREE_360 / 3.0F )
-
-#define DEGREE_1        ( DEGREE_180 / 180.0F )
-#define DEGREE_5        ( DEGREE_180 / 36.0F )
-#define DEGREE_10       ( DEGREE_180 / 18.0F )
-#define DEGREE_15       ( DEGREE_180 / 12.0F )
-#define DEGREE_20       ( DEGREE_180 / 8.0F )
-
-// Conversion routines
-
-#define ANGLE_TO_RAD    ANGLE_1
-#define RAD_TO_ANGLE    ( 180.0F / ANGLE_180 )
-
-#define SHORT_TO_ANGLE  ( 360.0 / 65536 )
-
-#if GDEF_COMPILER_MSVC
-#pragma warning(disable : 4305)     // 'initializing' : truncation from 'const double ' to 'float '
-#endif
diff --git a/tools/quake2/qdata_heretic2/qcommon/arrayedlist.h b/tools/quake2/qdata_heretic2/qcommon/arrayedlist.h
deleted file mode 100644 (file)
index 46663dd..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _ARRAYEDLIST_H
-#define _ARRAYEDLIST_H
-
-#include <assert.h>
-#include <globaldefs.h>
-
-typedef struct ArrayedListNode_s
-{
-       int data;
-       int next;
-       int inUse;
-} ArrayedListNode_t;
-
-#define ARRAYEDLISTNODE_NULL -1
-
-static GDEF_ATTRIBUTE_INLINE int GetFreeNode( ArrayedListNode_t *nodeArray, int max ){
-       int i;
-
-       for ( i = 0; i < max; ++i )
-       {
-               if ( !nodeArray[i].inUse ) {
-                       nodeArray[i].inUse = 1;
-                       return i;
-               }
-       }
-
-       assert( 0 );
-       return -1;
-}
-
-static GDEF_ATTRIBUTE_INLINE void FreeNode( ArrayedListNode_t *nodeArray, int index ){
-       nodeArray[index].inUse = 0;
-}
-
-#endif //_ARRAYEDLIST_H
diff --git a/tools/quake2/qdata_heretic2/qcommon/flex.h b/tools/quake2/qdata_heretic2/qcommon/flex.h
deleted file mode 100644 (file)
index 98184e8..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// Generic flexible format
-
-typedef struct
-{
-       char ident[32];
-       int version;
-       int size;
-} header_t;
-
-void WriteHeader( FILE *, char *, int, int, void * );
-
-// end
diff --git a/tools/quake2/qdata_heretic2/qcommon/fmodel.h b/tools/quake2/qdata_heretic2/qcommon/fmodel.h
deleted file mode 100644 (file)
index e2ebfa8..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-/*
-   ========================================================================
-
-   .FM triangle flexible model file format
-
-   ========================================================================
- */
-
-#ifndef __FMODEL_HEADER
-#define __FMODEL_HEADER
-
-#include "bspfile.h"
-
-//typedef unsigned char         byte;
-//typedef int  qboolean;
-//typedef float vec3_t[3];
-
-#define MAX_FM_TRIANGLES    2048
-#define MAX_FM_VERTS        2048
-#define MAX_FM_FRAMES       2048
-#define MAX_FM_SKINS        64
-#define MAX_FM_SKINNAME     64
-#define MAX_FM_MESH_NODES   16      // also defined in game/qshared.h
-
-
-#define DTRIVERTX_V0   0
-#define DTRIVERTX_V1   1
-#define DTRIVERTX_V2   2
-#define DTRIVERTX_LNI  3
-#define DTRIVERTX_SIZE 4
-
-#define SKINPAGE_WIDTH 640
-#define SKINPAGE_HEIGHT 480
-
-#define ENCODED_WIDTH_X 92
-#define ENCODED_WIDTH_Y 475
-#define ENCODED_HEIGHT_X 128
-#define ENCODED_HEIGHT_Y 475
-
-#define SCALE_ADJUST_FACTOR 0.96
-
-#define INFO_HEIGHT 5
-#define INFO_Y ( SKINPAGE_HEIGHT - INFO_HEIGHT )
-
-extern byte     *BasePalette;
-extern byte     *BasePixels,*TransPixels;
-extern int BaseWidth, BaseHeight, TransWidth, TransHeight;
-extern int ScaleWidth, ScaleHeight;
-
-int ExtractNumber( byte *pic, int x, int y );
-void DrawTextChar( int x, int y, char *text );
-void DrawLine( int x1, int y1, int x2, int y2 );
-
-// the glcmd format:
-// a positive integer starts a tristrip command, followed by that many
-// vertex structures.
-// a negative integer starts a trifan command, followed by -x vertexes
-// a zero indicates the end of the command list.
-// a vertex consists of a floating point s, a floating point t,
-// and an integer vertex index.
-
-
-// Initial Header
-#define FM_HEADER_NAME  "header"
-#define FM_HEADER_VER   2
-
-typedef struct
-{
-       int skinwidth;
-       int skinheight;
-       int framesize;              // byte size of each frame
-
-       int num_skins;
-       int num_xyz;
-       int num_st;                 // greater than num_xyz for seams
-       int num_tris;
-       int num_glcmds;             // dwords in strip/fan command list
-       int num_frames;
-       int num_mesh_nodes;
-} fmheader_t;
-
-
-// Skin Header
-#define FM_SKIN_NAME    "skin"
-#define FM_SKIN_VER     1
-
-
-// ST Coord Header
-#define FM_ST_NAME      "st coord"
-#define FM_ST_VER       1
-
-typedef struct
-{
-       short s;
-       short t;
-} fmstvert_t;
-
-
-// Tri Header
-#define FM_TRI_NAME     "tris"
-#define FM_TRI_VER      1
-
-typedef struct
-{
-       short index_xyz[3];
-       short index_st[3];
-} fmtriangle_t;
-
-
-// Frame Header
-#define FM_FRAME_NAME   "frames"
-#define FM_FRAME_VER    1
-
-// Frame for compression, just the names
-#define FM_SHORT_FRAME_NAME "short frames"
-#define FM_SHORT_FRAME_VER  1
-
-// Normals for compressed frames
-#define FM_NORMAL_NAME  "normals"
-#define FM_NORMAL_VER   1
-
-// Compressed Frame Data
-#define FM_COMP_NAME    "comp data"
-#define FM_COMP_VER 1
-
-// GL Cmds Header
-#define FM_GLCMDS_NAME  "glcmds"
-#define FM_GLCMDS_VER   1
-
-
-// Mesh Nodes Header
-#define FM_MESH_NAME    "mesh nodes"
-#define FM_MESH_VER     3
-
-// Skeleton Header
-#define FM_SKELETON_NAME "skeleton"
-#define FM_SKELETON_VER 1
-
-// References Header
-#define FM_REFERENCES_NAME "references"
-#define FM_REFERENCES_VER   1
-
-typedef struct
-{
-
-       union
-       {
-
-               byte tris[MAX_FM_TRIANGLES >> 3];
-
-               struct {
-                       short   *triIndicies;
-                       int num_tris;
-               };
-
-       };
-
-       byte verts[MAX_FM_VERTS >> 3];
-       short start_glcmds, num_glcmds;
-} fmmeshnode_t;
-
-//=================================================================
-
-// Frame info
-typedef struct
-{
-       byte v[3];              // scaled byte to fit in frame mins/maxs
-       byte lightnormalindex;
-} fmtrivertx_t;
-
-typedef struct
-{
-       float scale[3];                 // multiply byte verts by this
-       float translate[3];             // then add this
-       char name[16];                  // frame name from grabbing
-       fmtrivertx_t verts[1];          // variable sized
-} fmaliasframe_t;
-
-
-#endif // #define __FMODEL_HEADER
diff --git a/tools/quake2/qdata_heretic2/qcommon/h2common.h b/tools/quake2/qdata_heretic2/qcommon/h2common.h
deleted file mode 100644 (file)
index e1f2559..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef H2COMMON_H
-#define H2COMMON_H
-  #define H2COMMON_API
-#endif
diff --git a/tools/quake2/qdata_heretic2/qcommon/placement.h b/tools/quake2/qdata_heretic2/qcommon/placement.h
deleted file mode 100644 (file)
index 9151183..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef PLACEMENT_H
-#define PLACEMENT_H
-
-#include "q_typedef.h"
-
-//typedef float vec3_t[3];
-
-typedef struct Placement_s
-{
-       vec3_t origin;
-       vec3_t direction;
-       vec3_t up;
-} Placement_t;
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/qcommon/q_typedef.h b/tools/quake2/qdata_heretic2/qcommon/q_typedef.h
deleted file mode 100644 (file)
index cbe69dd..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef Q_TYPEDEF_H
-#define Q_TYPEDEF_H
-
-typedef float vec_t;
-typedef vec_t vec2_t[2];
-typedef vec_t vec3_t[3];
-typedef double vec3d_t[3];
-typedef vec_t vec5_t[5];
-
-typedef float matrix3_t[3][3];
-typedef float matrix3d_t[3][3];
-
-typedef int fixed4_t;
-typedef int fixed8_t;
-typedef int fixed16_t;
-
-typedef unsigned char byte;
-
-#ifndef __cplusplus
-typedef enum {false, true}  qboolean;
-#else
-typedef int qboolean;
-#endif
-
-typedef struct edict_s edict_t;
-
-typedef struct paletteRGBA_s
-{
-       union
-       {
-               struct
-               {
-                       byte r,g,b,a;
-               };
-               unsigned c;
-               byte c_array[4];
-       };
-} paletteRGBA_t;
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/qcommon/qfiles.h b/tools/quake2/qdata_heretic2/qcommon/qfiles.h
deleted file mode 100644 (file)
index 4d0648c..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-//
-// qfiles.h: quake file formats
-// This file must be identical in the quake and utils directories
-//
-
-/*
-   ========================================================================
-
-   The .pak files are just a linear collapse of a directory tree
-
-   ========================================================================
- */
-
-#define IDPAKHEADER     ( ( 'K' << 24 ) + ( 'C' << 16 ) + ( 'A' << 8 ) + 'P' )
-
-typedef struct
-{
-       char name[56];
-       int filepos, filelen;
-} dpackfile_t;
-
-typedef struct
-{
-       int ident;          // == IDPAKHEADER
-       int dirofs;
-       int dirlen;
-} dpackheader_t;
-
-#define MAX_FILES_IN_PACK   6144
-
-
-/*
-   ========================================================================
-
-   PCX files are used for as many images as possible
-
-   ========================================================================
- */
-
-typedef struct
-{
-       char manufacturer;
-       char version;
-       char encoding;
-       char bits_per_pixel;
-       unsigned short xmin,ymin,xmax,ymax;
-       unsigned short hres,vres;
-       unsigned char palette[48];
-       char reserved;
-       char color_planes;
-       unsigned short bytes_per_line;
-       unsigned short palette_type;
-       char filler[58];
-       unsigned char data;             // unbounded
-} pcx_t;
-
-/*
-   ========================================================================
-
-   .MD2 compressed triangle model file format
-
-   ========================================================================
- */
-#define IDCOMPRESSEDALIASHEADER ( ( '2' << 24 ) + ( 'C' << 16 ) + ( 'D' << 8 ) + 'I' )
-
-/*
-   ========================================================================
-
-   .MD2 compressed triangle model file format
-
-   ========================================================================
- */
-#define IDJOINTEDALIASHEADER    ( ( '2' << 24 ) + ( 'J' << 16 ) + ( 'D' << 8 ) + 'I' )
-
-/*
-   ========================================================================
-
-   .MD2 triangle model file format
-
-   ========================================================================
- */
-
-#define IDALIASHEADER       ( ( '2' << 24 ) + ( 'P' << 16 ) + ( 'D' << 8 ) + 'I' )
-#define ALIAS_VERSION   8
-
-#define MAX_TRIANGLES   4096
-#define MAX_VERTS       2048
-#define MAX_FRAMES      512
-#define MAX_MD2SKINS    64
-#define MAX_SKINNAME    64
-
-typedef struct
-{
-       short s;
-       short t;
-} dstvert_t;
-
-typedef struct
-{
-       short index_xyz[3];
-       short index_st[3];
-} dtriangle_t;
-
-typedef struct
-{
-       union
-       {
-               struct
-               {
-                       byte v[3];          // scaled byte to fit in frame mins/maxs
-                       byte lightnormalindex;
-               };
-
-               int vert;
-       };
-} dtrivertx_t;
-
-#define DTRIVERTX_V0   0
-#define DTRIVERTX_V1   1
-#define DTRIVERTX_V2   2
-#define DTRIVERTX_LNI  3
-#define DTRIVERTX_SIZE 4
-
-typedef struct
-{
-       float scale[3];         // multiply byte verts by this
-       float translate[3];         // then add this
-       char name[16];          // frame name from grabbing
-       dtrivertx_t verts[1];   // variable sized
-} daliasframe_t;
-
-
-// the glcmd format:
-// a positive integer starts a tristrip command, followed by that many
-// vertex structures.
-// a negative integer starts a trifan command, followed by -x vertexes
-// a zero indicates the end of the command list.
-// a vertex consists of a floating point s, a floating point t,
-// and an integer vertex index.
-
-
-typedef struct
-{
-       int ident;
-       int version;
-
-       int skinwidth;
-       int skinheight;
-       int framesize;              // byte size of each frame
-
-       int num_skins;
-       int num_xyz;
-       int num_st;                 // greater than num_xyz for seams
-       int num_tris;
-       int num_glcmds;             // dwords in strip/fan command list
-       int num_frames;
-
-       int ofs_skins;              // each skin is a MAX_SKINNAME string
-       int ofs_st;                 // byte offset from start for stverts
-       int ofs_tris;               // offset for dtriangles
-       int ofs_frames;             // offset for first frame
-       int ofs_glcmds;
-       int ofs_end;                // end of file
-
-} dmdl_t;
-
-// compressed model
-typedef struct dcompmdl_s
-{
-       dmdl_t header;
-       short CompressedFrameSize;
-       short UniqueVerts;
-       short *remap;
-       float *translate;   // then add this
-       float *scale;   // multiply byte verts by this
-       char *mat;
-       char *frames;
-       char *base;
-       float *ctranslate;
-       float *cscale;
-       char data[1];
-} dcompmdl_t;
-
-typedef struct
-{
-       dcompmdl_t compModInfo;
-       int rootCluster;
-       int skeletalType;
-       struct ModelSkeleton_s *skeletons;
-} JointedModel_t;
-
-/*
-   ========================================================================
-
-   .BK file format
-
-   ========================================================================
- */
-
-#define IDBOOKHEADER    ( ( 'K' << 24 ) + ( 'O' << 16 ) + ( 'O' << 8 ) + 'B' )
-#define BOOK_VERSION    2
-
-typedef struct bookframe_s
-{
-       int x;
-       int y;
-       int w;
-       int h;
-       char name[MAX_SKINNAME];            // name of gfx file
-} bookframe_t;
-
-typedef struct bookheader_s
-{
-       unsigned int ident;
-       unsigned int version;
-       int num_segments;
-       int total_w;
-       int total_h;
-} bookheader_t;
-
-typedef struct book_s
-{
-       bookheader_t bheader;
-       bookframe_t bframes[MAX_MD2SKINS];
-} book_t;
-
-/*
-   ========================================================================
-
-   .SP2 sprite file format
-
-   ========================================================================
- */
-
-#define IDSPRITEHEADER  ( ( '2' << 24 ) + ( 'S' << 16 ) + ( 'D' << 8 ) + 'I' )
-// little-endian "IDS2"
-#define SPRITE_VERSION  2
-
-typedef struct
-{
-       int width, height;
-       int origin_x, origin_y;         // raster coordinates inside pic
-       char name[MAX_SKINNAME];        // name of pcx file
-} dsprframe_t;
-
-typedef struct {
-       int ident;
-       int version;
-       int numframes;
-       dsprframe_t frames[1];          // variable sized
-} dsprite_t;
-
-/*
-   ==============================================================================
-
-   .M8 texture file format
-
-   ==============================================================================
- */
-
-typedef struct palette_s
-{
-       union
-       {
-               struct
-               {
-                       byte r,g,b;
-               };
-       };
-} palette_t;
-
-#define MIP_VERSION     2
-#define PAL_SIZE        256
-#define MIPLEVELS       16
-
-typedef struct miptex_s
-{
-       int version;
-       char name[32];
-       unsigned width[MIPLEVELS], height[MIPLEVELS];
-       unsigned offsets[MIPLEVELS];        // four mip maps stored
-       char animname[32];                  // next frame in animation chain
-       palette_t palette[PAL_SIZE];
-       int flags;
-       int contents;
-       int value;
-} miptex_t;
-
-
-
-#define MIP32_VERSION   4
-
-typedef struct miptex32_s
-{
-       int version;
-       char name[128];
-       char altname[128];                  // texture substitution
-       char animname[128];                 // next frame in animation chain
-       char damagename[128];               // image that should be shown when damaged
-       unsigned width[MIPLEVELS], height[MIPLEVELS];
-       unsigned offsets[MIPLEVELS];
-       int flags;
-       int contents;
-       int value;
-       float scale_x, scale_y;
-       int mip_scale;
-
-       // detail texturing info
-       char dt_name[128];              // detailed texture name
-       float dt_scale_x, dt_scale_y;
-       float dt_u, dt_v;
-       float dt_alpha;
-       int dt_src_blend_mode, dt_dst_blend_mode;
-
-       int unused[20];                     // future expansion to maintain compatibility with h2
-} miptex32_t;
-
-
-/*
-   ==============================================================================
-
-   .BSP file format
-
-   ==============================================================================
- */
-
-#define IDBSPHEADER ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'B' << 8 ) + 'I' )
-// little-endian "IBSP"
-
-#define BSPVERSION  38
-
-
-// upper design bounds
-// leaffaces, leafbrushes, planes, and verts are still bounded by
-// 16 bit short limits
-#define MAX_MAP_MODELS      1024
-//#define      MAX_MAP_BRUSHES         8192    // Quake 2 original
-#define MAX_MAP_BRUSHES     10240
-#define MAX_MAP_ENTITIES    2048
-#define MAX_MAP_ENTSTRING   0x40000
-#define MAX_MAP_TEXINFO     8192
-
-#define MAX_MAP_AREAS       256
-#define MAX_MAP_AREAPORTALS 1024
-#define MAX_MAP_PLANES      65536
-#define MAX_MAP_NODES       65536
-#define MAX_MAP_BRUSHSIDES  65536
-#define MAX_MAP_LEAFS       65536
-#define MAX_MAP_VERTS       65536
-#define MAX_MAP_FACES       65536
-#define MAX_MAP_LEAFFACES   65536
-#define MAX_MAP_LEAFBRUSHES 65536
-#define MAX_MAP_PORTALS     65536
-#define MAX_MAP_EDGES       128000
-#define MAX_MAP_SURFEDGES   256000
-#define MAX_MAP_LIGHTING    0x200000
-#define MAX_MAP_VISIBILITY  0x180000
-
-// key / value pair sizes
-
-#define MAX_KEY     32
-#define MAX_VALUE   1024
-
-//=============================================================================
-
-typedef struct
-{
-       int fileofs, filelen;
-} lump_t;
-
-#define LUMP_ENTITIES       0
-#define LUMP_PLANES         1
-#define LUMP_VERTEXES       2
-#define LUMP_VISIBILITY     3
-#define LUMP_NODES          4
-#define LUMP_TEXINFO        5
-#define LUMP_FACES          6
-#define LUMP_LIGHTING       7
-#define LUMP_LEAFS          8
-#define LUMP_LEAFFACES      9
-#define LUMP_LEAFBRUSHES    10
-#define LUMP_EDGES          11
-#define LUMP_SURFEDGES      12
-#define LUMP_MODELS         13
-#define LUMP_BRUSHES        14
-#define LUMP_BRUSHSIDES     15
-#define LUMP_POP            16
-#define LUMP_AREAS          17
-#define LUMP_AREAPORTALS    18
-#define HEADER_LUMPS        19
-
-typedef struct
-{
-       int ident;
-       int version;
-       lump_t lumps[HEADER_LUMPS];
-} dheader_t;
-
-typedef struct
-{
-       float mins[3], maxs[3];
-       float origin[3];            // for sounds or lights
-       int headnode;
-       int firstface, numfaces;            // submodels just draw faces
-                                           // without walking the bsp tree
-} dmodel_t;
-
-
-typedef struct
-{
-       float point[3];
-} dvertex_t;
-
-
-// 0-2 are axial planes
-#define PLANE_X         0
-#define PLANE_Y         1
-#define PLANE_Z         2
-
-// 3-5 are non-axial planes snapped to the nearest
-#define PLANE_ANYX      3
-#define PLANE_ANYY      4
-#define PLANE_ANYZ      5
-
-// planes (x&~1) and (x&~1)+1 are allways opposites
-
-typedef struct
-{
-       float normal[3];
-       float dist;
-       int type;           // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
-} dplane_t;
-
-
-// contents flags are seperate bits
-// a given brush can contribute multiple content bits
-// multiple brushes can be in a single leaf
-
-// These definitions also need to be in q_shared.h!
-
-// ************************************************************************************************
-// CONTENTS_XXX
-// ------------
-// Contents flags.
-// ************************************************************************************************
-
-// Lower bits are stronger, and will eat weaker brushes completely.
-
-#define CONTENTS_SOLID          0x00000001  // An eye is never valid in a solid.
-#define CONTENTS_WINDOW         0x00000002  // Translucent, but not watery.
-#define CONTENTS_AUX            0x00000004
-#define CONTENTS_LAVA           0x00000008
-#define CONTENTS_SLIME          0x00000010
-#define CONTENTS_WATER          0x00000020
-#define CONTENTS_MIST           0x00000040
-#define LAST_VISIBLE_CONTENTS   CONTENTS_MIST
-
-// Remaining contents are non-visible, and don't eat brushes.
-
-#define CONTENTS_AREAPORTAL     0x00008000
-#define CONTENTS_PLAYERCLIP     0x00010000
-#define CONTENTS_MONSTERCLIP    0x00020000
-
-// Currents can be added to any other contents, and may be mixed.
-
-#define CONTENTS_CURRENT_0      0x00040000
-#define CONTENTS_CURRENT_90     0x00080000
-#define CONTENTS_CURRENT_180    0x00100000
-#define CONTENTS_CURRENT_270    0x00200000
-#define CONTENTS_CURRENT_UP     0x00400000
-#define CONTENTS_CURRENT_DOWN   0x00800000
-#define CONTENTS_ORIGIN         0x01000000  // Removed before bsping an entity.
-#define CONTENTS_MONSTER        0x02000000  // Should never be on a brush, only in game.
-#define CONTENTS_DEADMONSTER    0x04000000
-#define CONTENTS_DETAIL         0x08000000  // Brushes to be added after vis leaves.
-#define CONTENTS_TRANSLUCENT    0x10000000  // Auto set if any surface has transparency.
-#define CONTENTS_LADDER         0x20000000
-#define CONTENTS_CAMERANOBLOCK  0x40000000  // Camera LOS ignores any brushes with this flag.
-
-typedef struct
-{
-       int planenum;
-       int children[2];            // negative numbers are -(leafs+1), not nodes
-       short mins[3];              // for frustom culling
-       short maxs[3];
-       unsigned short firstface;
-       unsigned short numfaces;    // counting both sides
-} dnode_t;
-
-
-typedef struct texinfo_s
-{
-       float vecs[2][4];           // [s/t][xyz offset]
-       int flags;                  // miptex flags + overrides
-       int value;                  // light emission, etc
-       char texture[32];           // texture name (textures/*.wal)
-       int nexttexinfo;            // for animations, -1 = end of chain
-} texinfo_t;
-
-
-// note that edge 0 is never used, because negative edge nums are used for
-// counterclockwise use of the edge in a face
-typedef struct
-{
-       unsigned short v[2];        // vertex numbers
-} dedge_t;
-
-#define MAXLIGHTMAPS    4
-typedef struct
-{
-       unsigned short planenum;
-       short side;
-
-       int firstedge;              // we must support > 64k edges
-       short numedges;
-       short texinfo;
-
-// lighting info
-       byte styles[MAXLIGHTMAPS];
-       int lightofs;               // start of [numstyles*surfsize] samples
-} dface_t;
-
-typedef struct
-{
-       int contents;                       // OR of all brushes (not needed?)
-
-       short cluster;
-       short area;
-
-       short mins[3];                      // for frustum culling
-       short maxs[3];
-
-       unsigned short firstleafface;
-       unsigned short numleaffaces;
-
-       unsigned short firstleafbrush;
-       unsigned short numleafbrushes;
-} dleaf_t;
-
-typedef struct
-{
-       unsigned short planenum;        // facing out of the leaf
-       short texinfo;
-} dbrushside_t;
-
-typedef struct
-{
-       int firstside;
-       int numsides;
-       int contents;
-} dbrush_t;
-
-#define ANGLE_UP    -1
-#define ANGLE_DOWN  -2
-
-
-// the visibility lump consists of a header with a count, then
-// byte offsets for the PVS and PHS of each cluster, then the raw
-// compressed bit vectors
-#define DVIS_PVS    0
-#define DVIS_PHS    1
-typedef struct
-{
-       int numclusters;
-       int bitofs[8][2];           // bitofs[numclusters][2]
-} dvis_t;
-
-// each area has a list of portals that lead into other areas
-// when portals are closed, other areas may not be visible or
-// hearable even if the vis info says that it should be
-typedef struct
-{
-       int portalnum;
-       int otherarea;
-} dareaportal_t;
-
-typedef struct
-{
-       int numareaportals;
-       int firstareaportal;
-} darea_t;
diff --git a/tools/quake2/qdata_heretic2/qcommon/reference.c b/tools/quake2/qdata_heretic2/qcommon/reference.c
deleted file mode 100644 (file)
index 7be9740..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <string.h>
-#include "reference.h"
-#include "arrayedlist.h"
-#include "resourcemanager.h"
-#include "skeletons.h"
-
-char *referenceRootNames[] =
-{
-       "elf_Lhandroot", //0
-       "elf_Rhandroot",
-       "elf_Rfootroot",
-       "elf_Lfootroot",
-       "elf_Bstaffroot",
-       "elf_bladeroot",
-       "elf_hellroot",
-       "StaffBone", //7
-       "SwordBone",
-       "SpearBone",
-       "RFootBone",
-       "LFootBone",
-       "hp_backroot", //12
-       "hp_staffroot",
-       "hp_lhandroot",
-       "hp_rhandroot",
-       "hp_rfootroot",
-       "hp_lfootroot",
-       "staffroot", //18
-       "rfootroot",
-       "lfootroot",
-       "rhandroot",
-       "lhandroot",
-       "leyeroot",
-       "reyeroot"
-};
-
-int referenceRootNameOffsets[NUM_REFERENCED] =
-{
-       0,  // CORVUS
-       7,  // INSECT
-       12, // HIGH PRIESTESS
-       18, // MORCALAVIN
-};
-
-int numReferences[NUM_REFERENCED] =
-{
-       NUM_REFERENCES_CORVUS,
-       NUM_REFERENCES_INSECT,
-       NUM_REFERENCES_PRIESTESS,
-       NUM_REFERENCES_MORK,
-};
-
-int corvusJointIDs[NUM_REFERENCES_CORVUS] =
-{
-       CORVUS_UPPERBACK,
-       CORVUS_UPPERBACK,
-       -1,
-       -1,
-       CORVUS_UPPERBACK,
-       CORVUS_UPPERBACK,
-       CORVUS_UPPERBACK,
-};
-
-int *jointIDs[NUM_REFERENCED] =
-{
-       corvusJointIDs,
-};
-
-static ResourceManager_t ReferenceMngr;
-
-void InitReferenceMngr(){
-#define REFERENCE_BLOCK_SIZE 8
-       char *dummystr = NULL;
-
-       ResMngr_Con( &ReferenceMngr, sizeof( LERPedReferences_t ), REFERENCE_BLOCK_SIZE, dummystr );
-}
-
-void ReleaseReferenceMngr(){
-       ResMngr_Des( &ReferenceMngr );
-}
-
-LERPedReferences_t *LERPedReferences_new( int init_refType ){
-       LERPedReferences_t  *newRefs;
-
-       newRefs = ResMngr_AllocateResource( &ReferenceMngr, sizeof( *newRefs ) );
-       newRefs->refType = init_refType;
-       newRefs->jointIDs = jointIDs[init_refType];
-       newRefs->lastUpdate = -( REF_MINCULLTIME * 2.0 );
-
-       memset( newRefs->references, 0, MAX_REFPOINTS * sizeof( Reference_t ) );
-       memset( newRefs->oldReferences, 0, MAX_REFPOINTS * sizeof( Reference_t ) );
-
-       return newRefs;
-}
-
-void LERPedReferences_delete( LERPedReferences_t *toDelete ){
-       ResMngr_DeallocateResource( &ReferenceMngr, toDelete, sizeof( *toDelete ) );
-}
-
-// end
diff --git a/tools/quake2/qdata_heretic2/qcommon/reference.h b/tools/quake2/qdata_heretic2/qcommon/reference.h
deleted file mode 100644 (file)
index 747c4d4..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef REFERENCE_H
-#define REFERENCE_H
-
-#include "placement.h"
-
-#define MAX_REFPOINTS       16
-#define REF_MINCULLTIME     1.0
-
-typedef struct Reference_s
-{
-       int activecount;
-       Placement_t placement;
-} Reference_t;
-
-typedef struct LERPedReferences_s
-{
-       int refType;
-       int         *jointIDs;
-       float lastUpdate;
-       Reference_t references[MAX_REFPOINTS];
-       Reference_t oldReferences[MAX_REFPOINTS];
-} LERPedReferences_t;
-
-// Reference Types
-enum {
-       REF_NULL = -1,
-       REF_CORVUS, //0
-       REF_INSECT, //1
-       REF_PRIESTESS, //2
-       REF_MORK, //3
-       NUM_REFERENCED //4
-};
-
-// Corvus Reference Points
-enum {
-       CORVUS_LEFTHAND, //0
-       CORVUS_RIGHTHAND,
-       CORVUS_LEFTFOOT,
-       CORVUS_RIGHTFOOT,
-       CORVUS_STAFF,
-       CORVUS_BLADE,
-       CORVUS_HELL_HEAD,
-       NUM_REFERENCES_CORVUS //7
-};
-
-// Tchekrik Reference Points
-enum {
-       INSECT_STAFF, //0
-       INSECT_SWORD,
-       INSECT_SPEAR,
-       INSECT_RIGHTFOOT,
-       INSECT_LEFTFOOT,
-       NUM_REFERENCES_INSECT //5
-};
-
-// High Priestess Reference Points
-enum {
-       PRIESTESS_BACK, //0
-       PRIESTESS_STAFF,
-       PRIESTESS_LHAND,
-       PRIESTESS_RHAND,
-       PRIESTESS_RFOOT,
-       PRIESTESS_LFOOT,
-       NUM_REFERENCES_PRIESTESS //6
-};
-
-// Morcalavin Reference Points
-enum
-{
-       MORK_STAFFREF, //0
-       MORK_RFOOTREF, //1
-       MORK_LFOOTREF, //2
-       MORK_RHANDREF, //3
-       MORK_LHANDREF, //4
-       MORK_LEYEREF, //5
-       MORK_REYEREF, //6
-       NUM_REFERENCES_MORK //7
-};
-
-#define CORVUS_LIMBS_MASK   ( ( 1 << CORVUS_LEFTHAND ) | ( 1 << CORVUS_RIGHTHAND ) | ( 1 << CORVUS_LEFTFOOT ) | ( 1 << CORVUS_RIGHTFOOT ) )
-#define CORVUS_WEAPON_MASK  ( ( 1 << CORVUS_STAFF ) | ( 1 << CORVUS_BLADE ) | ( 1 << CORVUS_HELL_HEAD ) )
-#define CORVUS_MASK         ( CORVUS_LIMBS_MASK | CORVUS_WEAPON_MASK )
-
-#define INSECT_MASK         ( ( 1 << INSECT_STAFF ) | ( 1 << INSECT_SWORD ) | ( 1 << INSECT_SPEAR ) | ( 1 << INSECT_RIGHTFOOT ) | ( 1 << INSECT_LEFTFOOT ) )
-
-#define PRIESTESS_MASK      ( ( 1 << PRIESTESS_BACK ) | ( 1 << PRIESTESS_STAFF ) | ( 1 << PRIESTESS_LHAND ) | ( 1 << PRIESTESS_RHAND ) | ( 1 << PRIESTESS_RFOOT ) | ( 1 << PRIESTESS_LFOOT ) )
-
-#define MORK_MASK           ( ( 1 << MORK_STAFFREF ) | ( 1 << MORK_RFOOTREF ) | ( 1 << MORK_LFOOTREF ) | ( 1 << MORK_RHANDREF ) | ( 1 << MORK_LHANDREF ) | ( 1 << MORK_LEYEREF ) | ( 1 << MORK_REYEREF ) )
-
-extern char *referenceRootNames[];
-extern int referenceRootNameOffsets[];
-extern int numReferences[];
-
-void EnableRefPoints( LERPedReferences_t *refInfo, int mask );
-void DisableRefPoints( LERPedReferences_t *refInfo, int mask );
-
-void InitReferenceMngr();
-void ReleaseReferenceMngr();
-
-LERPedReferences_t *LERPedReferences_new( int init_refType );
-void LERPedReferences_delete( LERPedReferences_t *toDelete );
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/qcommon/resourcemanager.c b/tools/quake2/qdata_heretic2/qcommon/resourcemanager.c
deleted file mode 100644 (file)
index 2eb0140..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-//
-// ResourceManager.c
-//
-
-#include <stdio.h>
-#include "resourcemanager.h"
-#include <assert.h>
-
-typedef struct ResMngr_Block_s
-{
-       char *start;
-       unsigned int size;
-       struct ResMngr_Block_s *next;
-} ResMngr_Block_t;
-
-static void ResMngr_CreateBlock( ResourceManager_t *resource ){
-       unsigned int _blockSize;
-       char *block;
-       char **current;
-       ResMngr_Block_t *temp;
-       unsigned int i;
-
-       _blockSize = resource->nodeSize * resource->resPerBlock;
-
-       block = malloc( _blockSize );
-
-       assert( block );
-
-       temp = malloc( sizeof( *temp ) );
-
-       temp->start = block;
-       temp->size = _blockSize;
-       temp->next = resource->blockList;
-
-       resource->blockList = temp;
-
-       resource->free = (char **)( block );
-
-       current = resource->free;
-
-       for ( i = 1; i < resource->resPerBlock; ++i )
-       {
-               // set current->next to point to next node
-               *current = (char *)( current ) + resource->nodeSize;
-
-               // set current node to current->next
-               current = (char **)( *current );
-       }
-
-       *current = NULL;
-}
-
-H2COMMON_API void ResMngr_Con( ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name ){
-       resource->resSize = init_resSize;
-
-       resource->resPerBlock = init_resPerBlock;
-
-       resource->nodeSize = resource->resSize + sizeof( *resource->free );
-
-       resource->blockList = NULL;
-
-       resource->numResourcesAllocated = 0;
-
-       ResMngr_CreateBlock( resource );
-}
-
-H2COMMON_API void ResMngr_Des( ResourceManager_t *resource ){
-       ResMngr_Block_t *toDelete;
-
-#if 0
-       if ( resource->numResourcesAllocated ) {
-               char mess[100];
-               sprintf( mess,"Potential memory leak %d bytes unfreed\n",resource->resSize * resource->numResourcesAllocated );
-               OutputDebugString( mess );
-       }
-#endif
-
-       while ( resource->blockList )
-       {
-               toDelete = resource->blockList;
-               resource->blockList = resource->blockList->next;
-               free( toDelete->start );
-               free( toDelete );
-       }
-}
-
-H2COMMON_API void *ResMngr_AllocateResource( ResourceManager_t *resource, size_t size ){
-       char **toPop;
-
-       assert( size == resource->resSize );
-
-       ++resource->numResourcesAllocated;
-
-       assert( resource->free ); // constructor not called; possibly due to a static object
-       // containing a static ResourceManagerFastLarge member being
-       // constructed before its own static members
-
-       toPop = resource->free;
-
-       // set unallocated to the next node and check for NULL (end of list)
-       if ( !( resource->free = (char **)( *resource->free ) ) ) { // if at end create new block
-               ResMngr_CreateBlock( resource );
-       }
-
-       // set next to NULL
-       *toPop = NULL;
-
-       // return the resource for the node
-       return (void *)( toPop + 1 );
-}
-
-H2COMMON_API void ResMngr_DeallocateResource( ResourceManager_t *resource, void *toDeallocate, size_t size ){
-       char **toPush;
-
-       assert( size == resource->resSize );
-
-       --resource->numResourcesAllocated;
-
-       toPush = (char **)( toDeallocate ) - 1;
-
-       assert( resource->free ); // see same assert at top of AllocateResource
-
-       // set toPop->next to current unallocated front
-       *toPush = (char *)( resource->free );
-
-       // set unallocated to the node removed from allocated
-       resource->free = toPush;
-}
-
-// end
diff --git a/tools/quake2/qdata_heretic2/qcommon/resourcemanager.h b/tools/quake2/qdata_heretic2/qcommon/resourcemanager.h
deleted file mode 100644 (file)
index be82d78..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-//
-// ResourceManager.h
-//
-
-#include "h2common.h"
-#include <stdlib.h>     // needed here for size_t
-
-typedef struct ResourceManager_s
-{
-       size_t resSize;
-       unsigned int resPerBlock;
-       unsigned int nodeSize;
-       struct ResMngr_Block_s *blockList;
-       char **free;
-       char *ResMan_Name;
-
-       unsigned numResourcesAllocated;
-
-} ResourceManager_t;
-
-extern H2COMMON_API void ResMngr_Con( ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name );
-extern H2COMMON_API void ResMngr_Des( ResourceManager_t *resource );
-extern H2COMMON_API void *ResMngr_AllocateResource( ResourceManager_t *resource, size_t size );
-extern H2COMMON_API void ResMngr_DeallocateResource( ResourceManager_t *resource, void *toDeallocate, size_t size );
diff --git a/tools/quake2/qdata_heretic2/qcommon/skeletons.c b/tools/quake2/qdata_heretic2/qcommon/skeletons.c
deleted file mode 100644 (file)
index 453cb77..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-//
-// Skeletons.c
-//
-
-#include "skeletons.h"
-
-char *skeletonRootNames[] =
-{
-       "RAVEN_ROOT",
-       "BOX_ROOT",
-       "BEETLE_ROOT",
-       "ELFLORD_ROOT",
-       "PLAGUELF_ROOT",
-       "ELF_BACKROOT",
-};
-
-int skeletonRNameOffsets[] =
-{
-       0,  // RAVEN
-       1,  // BOX
-       2,  // BEETLE
-       3,  // ELFLORD
-       4,  // PLAGUE ELF
-       5,  // CORVUS
-};
-
-char *skeletonJointNames[] =
-{
-       "RAVEN_LOWERBACK",  // 0
-       "RAVEN_UPPERBACK",
-       "RAVEN_NECK",
-       "BOX_CENTER",       // 3
-       "BEETLE_NECK",      // 4
-       "BEETLE_HEAD",
-       "PLAGUELF_BACKB",   // 6
-       "PLAGUELF_BACKC",
-       "PLAGUELF_NECK",
-       "ELF_BACKB",        // 9
-       "ELF_BACKC",
-       "ELF_NECKB",
-};
-
-int skeletonNameOffsets[] =
-{
-       0,  // RAVEN
-       3,  // BOX
-       4,  // BEETLE
-       -1, // ELFLORD
-       6,  // PLAGUE ELF
-       9,  // CORVUS
-};
-
-char *skeletonEffectorNames[] =
-{
-       "BEETLE_EYES",      // 0
-       "CORVUS_EYES",      // 1
-};
-
-int skeletonENameOffsets[] =
-{
-       -1, // RAVEN
-       -1, // BOX
-       0,  // BEETLE
-       -1, // ELFLORD
-       1,  // PLAGUE ELF
-};
-
-int numJointsInSkeleton[] =
-{
-       NUM_JOINTS_RAVEN,
-       NUM_JOINTS_BOX,
-       NUM_JOINTS_BEETLE,
-       NUM_JOINTS_ELFLORD,
-       NUM_JOINTS_PLAGUE_ELF,
-       NUM_JOINTS_CORVUS,
-};
-
-int numNodesInSkeleton[] =
-{
-       2,  // RAVEN
-       0,  // BOX
-       1,  // BEETLE
-       -1, // ELFLORD
-       2,  // PLAGUE ELF
-       2,  // CORVUS
-};
-
-void CreateRavenSkel( void *g_skeletalJoints, size_t jointSize, struct ArrayedListNode_s *g_jointNodes, int root );
-void CreateBoxSkel( void *g_skeletalJoints, size_t jointSize, struct ArrayedListNode_s *g_jointNodes, int root );
-void CreateBeetleSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex );
-void CreateElfLordSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex );
-void CreatePlagueElfSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex );
-
-CreateSkeleton_t SkeletonCreators[NUM_SKELETONS] =
-{
-       CreateRavenSkel,
-       CreateBoxSkel,
-       CreateBeetleSkel,
-       CreateElfLordSkel,
-       CreatePlagueElfSkel,
-       CreatePlagueElfSkel,    // Corvus has the same structure as the Plague Elf
-};
-
-void CreateRavenSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
-       char *root;
-       int *children;
-       int nodeIndex;
-
-       root = (char *)g_skeletalJoints + rootIndex * jointSize;
-
-       children = (int *)( root + RAVEN_HEAD * jointSize );
-       *children = ARRAYEDLISTNODE_NULL;
-
-       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
-
-       children = (int *)( root + RAVEN_UPPERBACK * jointSize );
-       *children = nodeIndex;
-
-       g_jointNodes[nodeIndex].data = rootIndex + RAVEN_HEAD;
-       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
-
-       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
-
-       children = (int *)( root + RAVEN_LOWERBACK * jointSize );
-       *children = nodeIndex;
-
-       g_jointNodes[nodeIndex].data = rootIndex + RAVEN_UPPERBACK;
-       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
-}
-
-void CreateBoxSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
-       char *root;
-       int *children;
-
-       root = (char *)g_skeletalJoints + rootIndex * jointSize;
-
-       children = (int *)( root + RAVEN_HEAD * jointSize );
-       *children = ARRAYEDLISTNODE_NULL;
-}
-
-void CreateBeetleSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
-       char *root;
-       int *children;
-       int nodeIndex;
-
-       root = (char *)g_skeletalJoints + rootIndex * jointSize;
-
-       children = (int *)( root + BEETLE_HEAD * jointSize );
-       *children = ARRAYEDLISTNODE_NULL;
-
-       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
-
-       children = (int *)( root + BEETLE_NECK * jointSize );
-       *children = nodeIndex;
-
-       g_jointNodes[nodeIndex].data = rootIndex + BEETLE_HEAD;
-       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
-}
-
-void CreateElfLordSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
-       char *root;
-       int *children;
-       int nodeIndex;
-
-       root = (char *)g_skeletalJoints + rootIndex * jointSize;
-
-       children = (int *)( root + BEETLE_HEAD * jointSize );
-       *children = ARRAYEDLISTNODE_NULL;
-
-       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
-
-       children = (int *)( root + BEETLE_NECK * jointSize );
-       *children = nodeIndex;
-
-       g_jointNodes[nodeIndex].data = rootIndex + BEETLE_HEAD;
-       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
-}
-
-void CreatePlagueElfSkel( void *g_skeletalJoints, size_t jointSize, ArrayedListNode_t *g_jointNodes, int rootIndex ){
-       char *root;
-       int *children;
-       int nodeIndex;
-
-       root = (char *)g_skeletalJoints + rootIndex * jointSize;
-
-       children = (int *)( root + PLAGUE_ELF_HEAD * jointSize );
-       *children = ARRAYEDLISTNODE_NULL;
-
-       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
-
-       children = (int *)( root + PLAGUE_ELF_UPPERBACK * jointSize );
-       *children = nodeIndex;
-
-       g_jointNodes[nodeIndex].data = rootIndex + PLAGUE_ELF_HEAD;
-       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
-
-       nodeIndex = GetFreeNode( g_jointNodes, MAX_ARRAYED_JOINT_NODES );
-
-       children = (int *)( root + PLAGUE_ELF_LOWERBACK * jointSize );
-       *children = nodeIndex;
-
-       g_jointNodes[nodeIndex].data = rootIndex + PLAGUE_ELF_UPPERBACK;
-       g_jointNodes[nodeIndex].next = ARRAYEDLISTNODE_NULL;
-}
diff --git a/tools/quake2/qdata_heretic2/qcommon/skeletons.h b/tools/quake2/qdata_heretic2/qcommon/skeletons.h
deleted file mode 100644 (file)
index 9d7fe96..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <stdlib.h> // for size_t
-#include "arrayedlist.h"
-
-#define JN_YAW_CHANGED      0x00000001
-#define JN_PITCH_CHANGED    0x00000002
-#define JN_ROLL_CHANGED     0x00000004
-
-// Skeleton types
-enum {
-       SKEL_NULL = -1,
-       SKEL_RAVEN = 0,
-       SKEL_BOX,
-       SKEL_BEETLE,
-       SKEL_ELFLORD,
-       SKEL_PLAGUE_ELF,
-       SKEL_CORVUS,
-       NUM_SKELETONS
-};
-
-// Raven Skeletal joints
-enum {
-       RAVEN_LOWERBACK = 0,
-       RAVEN_UPPERBACK,
-       RAVEN_HEAD,
-       NUM_JOINTS_RAVEN
-};
-
-// Box Skeletal joints
-enum {
-       BOX_CENTER = 0,
-       NUM_JOINTS_BOX
-};
-
-// Beetle Skeletal joints
-enum {
-       BEETLE_NECK = 0,
-       BEETLE_HEAD,
-       NUM_JOINTS_BEETLE
-};
-
-// Elflord Skeletal joints
-enum {
-       ELFLORD_,
-       ELFLORD__,
-       NUM_JOINTS_ELFLORD
-};
-
-// Plague Elf Skeletal joints
-enum {
-       PLAGUE_ELF_LOWERBACK,
-       PLAGUE_ELF_UPPERBACK,
-       PLAGUE_ELF_HEAD,
-       NUM_JOINTS_PLAGUE_ELF
-};
-
-// Corvus Skeletal joints
-enum {
-       CORVUS_LOWERBACK,
-       CORVUS_UPPERBACK,
-       CORVUS_HEAD,
-       NUM_JOINTS_CORVUS
-};
-
-#define NO_SWAP_FRAME -1
-#define NULL_ROOT_JOINT -1
-
-#define MAX_ARRAYED_SKELETAL_JOINTS 255 // has max of 65,535 (if this remains at 255, net code can be changed to reflect)
-#define MAX_ARRAYED_JOINT_NODES ( MAX_ARRAYED_SKELETAL_JOINTS - 1 )
-
-#define MAX_JOINTS_PER_SKELETON 8   // arbitrary small number
-#define MAX_JOINT_NODES_PER_SKELETON ( MAX_JOINTS_PER_SKELETON - 1 )
-
-extern char *skeletonRootNames[];
-extern int skeletonRNameOffsets[];
-extern char *skeletonJointNames[];
-extern int skeletonNameOffsets[];
-extern int numJointsInSkeleton[];
-extern char *skeletonEffectorNames[];
-extern int skeletonENameOffsets[];
-extern int numNodesInSkeleton[];
-
-typedef void ( *CreateSkeleton_t )( void *skeletalJoints, size_t jointSize, struct ArrayedListNode_s *jointNodes, int rootIndex );
-
-extern CreateSkeleton_t SkeletonCreators[NUM_SKELETONS];
diff --git a/tools/quake2/qdata_heretic2/qd_fmodel.h b/tools/quake2/qdata_heretic2/qd_fmodel.h
deleted file mode 100644 (file)
index 286fb07..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef FMODEL_H
-#define FMODEL_H
-#include "fmodel.h"
-#endif
-#include "qd_skeletons.h"
-
-typedef struct
-{
-       int numnormals;
-       vec3_t normalsum;
-} fmvertexnormals_t;
-
-typedef struct
-{
-       vec3_t v;
-       int lightnormalindex;
-       fmvertexnormals_t vnorm;
-} fmtrivert_t;
-
-#define FRAME_NAME_LEN ( 16 )
-
-typedef struct
-{
-       vec3_t mins, maxs;
-       char name[FRAME_NAME_LEN];
-       fmtrivert_t v[MAX_FM_VERTS];
-       struct QD_SkeletalJoint_s joints[NUM_CLUSTERS];
-       struct QD_SkeletalJoint_s references[NUM_REFERENCES];
-} fmframe_t;
-
-extern fmframe_t g_frames[MAX_FM_FRAMES];
-
-extern fmheader_t fmheader;
-extern char cdarchive[1024];                        // set by $fmcd
-extern char cdpartial[1024];                        // set by $fmcd
-extern char cddir[1024];                            // set by $fmcd
-
-void GrabFrame( char *frame );
-void H_printf( char *fmt, ... );
-char *FindFrameFile( char *frame );
diff --git a/tools/quake2/qdata_heretic2/qd_skeletons.c b/tools/quake2/qdata_heretic2/qd_skeletons.c
deleted file mode 100644 (file)
index 97e2a1f..0000000
+++ /dev/null
@@ -1,1231 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "qd_skeletons.h"
-#include "skeletons.h"
-#include "qd_fmodel.h"
-#include "angles.h"
-#include "token.h"
-#include "qdata.h"
-#include "reference.h"
-
-#include <assert.h>
-#include <math.h>
-#include <memory.h>
-
-
-// We're assuming no more than 16 reference points, with no more than 32 characters in the name
-char RefPointNameList[REF_MAX_POINTS][REF_MAX_STRLEN];
-int RefPointNum = 0;
-
-Skeletalfmheader_t g_skelModel;
-
-void ClearSkeletalModel(){
-       g_skelModel.type = SKEL_NULL;
-       g_skelModel.clustered = false;
-       g_skelModel.references = REF_NULL;
-}
-
-//==========================================================================
-//
-// LoadHRCClustered
-//
-//==========================================================================
-
-// Places the null terminated src string into the dest string less any trailing digits or underscores
-void StripTrailingDigits( char *src, char *dest ){
-#ifndef NDEBUG
-       int max = SKELETAL_NAME_MAX; // should be sufficient for inteded use on names from hrc files
-#endif
-       int i = 0;
-
-       while ( src[i] != '\0' )
-       {
-               ++i;
-#ifndef NDEBUG
-               assert( i < max );
-#endif
-       }
-
-       while ( ( src[--i] >= '0' && src[i] <= '9' ) || src[i] == '_' )
-       {
-
-       }
-
-       memcpy( dest, src, ++i );
-
-       dest[i] = '\0';
-}
-
-static void LoadHRCClustered( char *fileName, int **clusterList, int *num_verts, int skelType ){
-       extern void HandleHRCModel( triangle_t **triList, int *triangleCount,
-                                                               mesh_node_t **nodesList, int *num_mesh_nodes, int ActiveNode, int Depth );
-
-       extern mesh_node_t  *pmnodes;
-
-       triangle_t *triList;
-//      mesh_node_t *nodesList;
-       int num_mesh_nodes = 0, triangleCount = 0;
-
-#if 0
-       int i;
-       int j, numVerts;
-       char stripped[SKELETAL_NAME_MAX];
-
-       for ( i = 1; i < numJointsInSkeleton[skelType] + 1; ++i )
-       {
-               num_verts[i] = 0;
-       }
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-
-       TK_Beyond( TK_CLUSTERS );
-
-       while ( TK_Search( TK_CLUSTER_NAME ) != TK_EOF )
-       {
-               TK_Require( TK_STRING );
-
-               StripTrailingDigits( tk_String, stripped );
-
-               for ( i = 0; i < numJointsInSkeleton[skelType]; ++i )
-               {
-                       if ( stricmp( stripped, skeletonJointNames[skeletonNameOffsets[skelType] + i] ) == 0 ) {
-                               i = -i + numJointsInSkeleton[skelType] - 1;
-
-                               TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER );
-
-                               numVerts = tk_IntNumber;
-
-                               if ( !num_verts[i + 1] ) { // first set of verts for cluster
-                                       clusterList[i] = SafeMalloc( numVerts * sizeof( int ), "LoadHRCClustered" );
-                                       assert( clusterList[i] );
-                               }
-                               else                // any later sets of verts need to copy current
-                               {
-                                       int *temp;
-
-                                       temp = SafeMalloc( ( num_verts[i + 1] + numVerts ) * sizeof( int ), "LoadHRCClustered" );
-                                       assert( temp );
-
-                                       memcpy( temp + numVerts, clusterList[i], num_verts[i + 1] * sizeof( int ) );
-
-                                       free( clusterList[i] );
-
-                                       clusterList[i] = temp;
-                               }
-
-                               // currently this function is only called by LoadModelClusters.
-                               // Apparently the matching free has disappeared,
-                               // should probably be free at the end of FMCmd_Base
-
-                               TK_Beyond( TK_LBRACE );
-
-                               for ( j = 0; j < numVerts; ++j )
-                               {
-                                       TK_Require( TK_INTNUMBER );
-                                       clusterList[i][j] = tk_IntNumber;
-                                       TK_Fetch();
-                               }
-
-                               num_verts[i + 1] += numVerts;
-
-                               break;
-                       }
-               }
-       }
-
-       num_verts[0] = numJointsInSkeleton[skelType];
-#endif
-
-#if 1   // get the index number localized to the root
-//     for( i = 1; i < numJointsInSkeleton[skelType] + 1; ++i)
-//     {
-//             g_skelModel.num_verts[i] = 0;
-//     }
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-
-       // prime it
-       TK_Beyond( TK_MODEL );
-
-       triList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
-       memset( triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
-//     nodesList = SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
-       pmnodes = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
-
-       memset( pmnodes, 0, MAX_FM_MESH_NODES * sizeof( mesh_node_t ) );
-
-       // this should eventually use a stripped down version of this
-       HandleHRCModel( &triList, &triangleCount, &pmnodes, &num_mesh_nodes, 0, 0 );
-
-//     free(nodesList);
-       free( triList );
-
-       num_verts[0] = numJointsInSkeleton[skelType];
-#endif
-}
-
-void ReadHRCClusterList( mesh_node_t *meshNode, int baseIndex ){
-       int i, j, numVerts;
-       tokenType_t nextToken;
-       char stripped[SKELETAL_NAME_MAX];
-
-       meshNode->clustered = true;
-
-       nextToken = TK_Get( TK_CLUSTER_NAME );
-
-       while ( nextToken == TK_CLUSTER_NAME )
-       {
-               TK_FetchRequire( TK_STRING );
-
-               StripTrailingDigits( tk_String, stripped );
-
-               for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i )
-               {
-                       if ( stricmp( stripped, skeletonJointNames[skeletonNameOffsets[g_skelModel.type] + i] ) == 0 ) {
-                               i = -i + numJointsInSkeleton[g_skelModel.type] - 1;
-
-                               TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER );
-
-                               numVerts = tk_IntNumber;
-
-                               if ( !baseIndex ) {
-                                       meshNode->clusters[i] = (int *) SafeMalloc( numVerts * sizeof( int ), "ReadHRCClusterList" );
-                                       assert( meshNode->clusters[i] );
-                               }
-                               else
-                               {
-                                       int *temp;
-
-                                       temp = meshNode->clusters[i];
-                                       meshNode->clusters[i] = (int *) SafeMalloc( ( meshNode->num_verts[i + 1] + numVerts ) * sizeof( int ), "ReadHRCClusterList" );
-                                       assert( meshNode->clusters[i] );
-
-                                       memcpy( meshNode->clusters[i], temp, meshNode->num_verts[i + 1] * sizeof( int ) );
-                                       free( temp );
-                               }
-
-                               // currently this function is only called by LoadModelClusters.
-                               // Apparently the matching free has disappeared,
-                               // should probably be free at the end of FMCmd_Base
-
-                               TK_Beyond( TK_LBRACE );
-
-                               for ( j = 0; j < numVerts; ++j )
-                               {
-                                       TK_Require( TK_INTNUMBER );
-                                       meshNode->clusters[i][baseIndex + j] = tk_IntNumber + baseIndex;
-                                       TK_Fetch();
-                               }
-
-                               if ( baseIndex ) {
-                                       meshNode->num_verts[i + 1] += numVerts;
-                               }
-                               else
-                               {
-                                       meshNode->num_verts[i + 1] = numVerts;
-                               }
-
-                               break;
-                       }
-               }
-
-               TK_BeyondRequire( TK_CLUSTER_STATE, TK_INTNUMBER );
-               nextToken = TK_Fetch();
-       }
-}
-
-static void LoadHRCGlobals( char *fileName ){
-       int i;
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-       TK_Beyond( TK_MODEL );
-
-       TK_Beyond( TK_SCALING );
-       for ( i = 0; i < 3; i++ )
-       {
-               TK_Require( TK_FLOATNUMBER );
-               g_skelModel.scaling[i] = tk_FloatNumber;
-               TK_Fetch();
-       }
-
-       TK_Beyond( TK_ROTATION );
-       for ( i = 0; i < 3; i++ )
-       {
-               TK_Require( TK_FLOATNUMBER );
-               g_skelModel.rotation[i] = tk_FloatNumber;
-               TK_Fetch();
-       }
-
-       TK_Beyond( TK_TRANSLATION );
-       for ( i = 0; i < 3; i++ )
-       {
-               TK_Require( TK_FLOATNUMBER );
-               g_skelModel.translation[i] = tk_FloatNumber;
-               TK_Fetch();
-       }
-}
-
-static void ParseVec3( vec3_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void ParseVec3d( vec3d_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void ParseRotation3( vec3_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void ParseRotation3d( vec3d_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void ParseTranslation3( vec3_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void ParseTranslation3d( vec3d_t in ){
-       TK_Require( TK_FLOATNUMBER );
-       in[1] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[2] = tk_FloatNumber;
-       TK_FetchRequire( TK_FLOATNUMBER );
-       in[0] = tk_FloatNumber;
-}
-
-static void LoadHRCJointList( char *fileName, QD_SkeletalJoint_t *jointList, int skelType ){
-#define MAX_STACK 64
-       int i, j;
-       vec3d_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];
-       int curCorrespondingJoint[MAX_STACK];
-       int currentStack = 0, stackSize;
-       double cx, sx, cy, sy, cz, sz;
-       double rx, ry, rz;
-       double x2, y2, z2;
-       char stripped[SKELETAL_NAME_MAX];
-       Placement_d_t *placement;
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-
-       TK_Beyond( TK_MODEL );
-
-       while ( TK_Search( TK_NAME ) != TK_EOF )
-       {
-               TK_Require( TK_STRING );
-
-               StripTrailingDigits( tk_String, stripped );
-
-               if ( stricmp( stripped, skeletonRootNames[skeletonRNameOffsets[skelType]] ) == 0 ) {
-                       break;
-               }
-       }
-
-       if ( tk_Token == TK_EOF ) {
-               Error( "Bone Chain Root: %s not found\n", skeletonRootNames[skeletonRNameOffsets[skelType]] );
-               return;
-       }
-
-       TK_Beyond( TK_SCALING );
-
-       ParseVec3d( curScale[currentStack] );
-
-       TK_Beyond( TK_ROTATION );
-
-       ParseRotation3d( curRotation[currentStack] );
-
-       TK_Beyond( TK_TRANSLATION );
-
-       ParseVec3d( curTranslation[currentStack] );
-
-       // account for global model translation
-       curTranslation[currentStack][1] += g_skelModel.translation[0];
-       curTranslation[currentStack][2] += g_skelModel.translation[1];
-       curTranslation[currentStack][0] += g_skelModel.translation[2];
-
-       curCorrespondingJoint[currentStack] = -1;
-
-       ++currentStack;
-
-       for ( i = 0; i < numJointsInSkeleton[skelType]; ++i )
-       {
-               while ( 1 )
-               {
-                       TK_Beyond( TK_MODEL );
-
-                       TK_BeyondRequire( TK_NAME, TK_STRING );
-
-                       StripTrailingDigits( tk_String, stripped );
-
-                       if ( stricmp( stripped, skeletonJointNames[skeletonNameOffsets[skelType] + i] ) == 0 ) {
-                               break;
-                       }
-
-                       TK_Beyond( TK_SCALING );
-
-                       ParseVec3d( curScale[currentStack] );
-
-                       TK_Beyond( TK_ROTATION );
-
-                       ParseRotation3d( curRotation[currentStack] );
-
-                       TK_Beyond( TK_TRANSLATION );
-
-                       ParseVec3d( curTranslation[currentStack] );
-
-                       curCorrespondingJoint[currentStack] = -1;
-
-                       ++currentStack;
-               }
-
-               TK_Beyond( TK_SCALING );
-
-               ParseVec3d( curScale[currentStack] );
-
-               TK_Beyond( TK_ROTATION );
-
-               ParseRotation3d( curRotation[currentStack] );
-
-               jointList[i].rotation[1] = curRotation[currentStack][1];
-               jointList[i].rotation[2] = curRotation[currentStack][2];
-               jointList[i].rotation[0] = curRotation[currentStack][0];
-
-               TK_Beyond( TK_TRANSLATION );
-
-               ParseVec3d( curTranslation[currentStack] );
-
-//             jointList[i].placement.origin[1] = curTranslation[currentStack][1];
-//             jointList[i].placement.origin[2] = curTranslation[currentStack][2];
-//             jointList[i].placement.origin[0] = curTranslation[currentStack][0];
-
-               jointList[i].placement.origin[1] = 0.0;
-               jointList[i].placement.origin[2] = 0.0;
-               jointList[i].placement.origin[0] = 0.0;
-
-               jointList[i].placement.direction[1] = 20.0;
-               jointList[i].placement.direction[2] = 0.0;
-               jointList[i].placement.direction[0] = 0.0;
-
-               jointList[i].placement.up[1] = 0.0;
-               jointList[i].placement.up[2] = 20.0;
-               jointList[i].placement.up[0] = 0.0;
-
-               curCorrespondingJoint[currentStack] = i;
-
-               ++currentStack;
-       }
-
-       stackSize = currentStack;
-
-#if 0
-       // rotate the direction and up vectors to correspond to the rotation
-       for ( i = 0; i < numJointsInSkeleton[skelType]; ++i )
-       {
-               rx = jointList[i].rotation[0] * ANGLE_TO_RAD;
-               ry = jointList[i].rotation[1] * ANGLE_TO_RAD;
-               rz = jointList[i].rotation[2] * ANGLE_TO_RAD;
-
-               cx = cos( rx );
-               sx = sin( rx );
-
-               cy = cos( ry );
-               sy = sin( ry );
-
-               cz = cos( rz );
-               sz = sin( rz );
-
-               // y-axis rotation for direction
-               x2 = jointList[i].placement.direction[0] * cy + jointList[i].placement.direction[2] * sy;
-               z2 = -jointList[i].placement.direction[0] * sy + jointList[i].placement.direction[2] * cy;
-               jointList[i].placement.direction[0] = x2;
-               jointList[i].placement.direction[2] = z2;
-
-               // y-axis rotation for up
-               x2 = jointList[i].placement.up[0] * cy + jointList[i].placement.up[2] * sy;
-               z2 = -jointList[i].placement.up[0] * sy + jointList[i].placement.up[2] * cy;
-               jointList[i].placement.up[0] = x2;
-               jointList[i].placement.up[2] = z2;
-
-               // z-axis rotation for direction
-               x2 = jointList[i].placement.direction[0] * cz - jointList[i].placement.direction[1] * sz;
-               y2 = jointList[i].placement.direction[0] * sz + jointList[i].placement.direction[1] * cz;
-               jointList[i].placement.direction[0] = x2;
-               jointList[i].placement.direction[1] = y2;
-
-               // z-axis rotation for up
-               x2 = jointList[i].placement.up[0] * cz - jointList[i].placement.up[1] * sz;
-               y2 = jointList[i].placement.up[0] * sz + jointList[i].placement.up[1] * cz;
-               jointList[i].placement.up[0] = x2;
-               jointList[i].placement.up[1] = y2;
-
-               // x-axis rotation for direction vector
-               y2 = jointList[i].placement.direction[1] * cx - jointList[i].placement.direction[2] * sx;
-               z2 = jointList[i].placement.direction[1] * sx + jointList[i].placement.direction[2] * cx;
-               jointList[i].placement.direction[1] = y2;
-               jointList[i].placement.direction[2] = z2;
-
-               // x-axis rotation for up vector
-               y2 = jointList[i].placement.up[1] * cx - jointList[i].placement.up[2] * sx;
-               z2 = jointList[i].placement.up[1] * sx + jointList[i].placement.up[2] * cx;
-               jointList[i].placement.up[1] = y2;
-               jointList[i].placement.up[2] = z2;
-
-               // translate direction to a point in the model
-               jointList[i].placement.direction[0] += jointList[i].placement.origin[0];
-               jointList[i].placement.direction[1] += jointList[i].placement.origin[1];
-               jointList[i].placement.direction[2] += jointList[i].placement.origin[2];
-
-               // translate up to a point in the model
-               jointList[i].placement.up[0] += jointList[i].placement.origin[0];
-               jointList[i].placement.up[1] += jointList[i].placement.origin[1];
-               jointList[i].placement.up[2] += jointList[i].placement.origin[2];
-       }
-#endif
-
-       for ( i = stackSize - 1; i >= 0; --i )
-       {
-               rx = curRotation[i][0] * ANGLE_TO_RAD;
-               ry = curRotation[i][1] * ANGLE_TO_RAD;
-               rz = curRotation[i][2] * ANGLE_TO_RAD;
-
-               cx = cos( rx );
-               sx = sin( rx );
-
-               cy = cos( ry );
-               sy = sin( ry );
-
-               cz = cos( rz );
-               sz = sin( rz );
-
-#if 1
-               for ( j = i; j < stackSize; ++j )
-               {
-                       if ( curCorrespondingJoint[j] != -1 ) {
-                               placement = &jointList[curCorrespondingJoint[j]].placement;
-
-                               // y-axis rotation for origin
-                               x2 = placement->origin[0] * cy + placement->origin[2] * sy;
-                               z2 = -placement->origin[0] * sy + placement->origin[2] * cy;
-                               placement->origin[0] = x2;
-                               placement->origin[2] = z2;
-
-                               // y-axis rotation for direction
-                               x2 = placement->direction[0] * cy + placement->direction[2] * sy;
-                               z2 = -placement->direction[0] * sy + placement->direction[2] * cy;
-                               placement->direction[0] = x2;
-                               placement->direction[2] = z2;
-
-                               // y-axis rotation for up
-                               x2 = placement->up[0] * cy + placement->up[2] * sy;
-                               z2 = -placement->up[0] * sy + placement->up[2] * cy;
-                               placement->up[0] = x2;
-                               placement->up[2] = z2;
-
-                               // z-axis rotation for origin
-                               x2 = placement->origin[0] * cz - placement->origin[1] * sz;
-                               y2 = placement->origin[0] * sz + placement->origin[1] * cz;
-                               placement->origin[0] = x2;
-                               placement->origin[1] = y2;
-
-                               // z-axis rotation for direction
-                               x2 = placement->direction[0] * cz - placement->direction[1] * sz;
-                               y2 = placement->direction[0] * sz + placement->direction[1] * cz;
-                               placement->direction[0] = x2;
-                               placement->direction[1] = y2;
-
-                               // z-axis rotation for up
-                               x2 = placement->up[0] * cz - placement->up[1] * sz;
-                               y2 = placement->up[0] * sz + placement->up[1] * cz;
-                               placement->up[0] = x2;
-                               placement->up[1] = y2;
-
-                               // x-axis rotation for origin
-                               y2 = placement->origin[1] * cx - placement->origin[2] * sx;
-                               z2 = placement->origin[1] * sx + placement->origin[2] * cx;
-                               placement->origin[1] = y2;
-                               placement->origin[2] = z2;
-
-                               // x-axis rotation for direction vector
-                               y2 = placement->direction[1] * cx - placement->direction[2] * sx;
-                               z2 = placement->direction[1] * sx + placement->direction[2] * cx;
-                               placement->direction[1] = y2;
-                               placement->direction[2] = z2;
-
-                               // x-axis rotation for up vector
-                               y2 = placement->up[1] * cx - placement->up[2] * sx;
-                               z2 = placement->up[1] * sx + placement->up[2] * cx;
-                               placement->up[1] = y2;
-                               placement->up[2] = z2;
-
-                               // translate origin
-                               placement->origin[0] += curTranslation[i][0];
-                               placement->origin[1] += curTranslation[i][1];
-                               placement->origin[2] += curTranslation[i][2];
-
-                               // translate back to local coord
-                               placement->direction[0] += curTranslation[i][0];
-                               placement->direction[1] += curTranslation[i][1];
-                               placement->direction[2] += curTranslation[i][2];
-
-                               // translate back to local coord
-                               placement->up[0] += curTranslation[i][0];
-                               placement->up[1] += curTranslation[i][1];
-                               placement->up[2] += curTranslation[i][2];
-                       }
-               }
-#else
-               // This screwed up and needs to be sorted out!!!
-               // The stack info needs to be written too instead of the jointList for j > numJoints for Skeleton
-               for ( j = i - 1; j < stackSize - 1; ++j )
-               {
-                       // y-axis rotation for origin
-                       x2 = jointList[j].placement.origin[0] * cy + jointList[j].placement.origin[2] * sy;
-                       z2 = -jointList[j].placement.origin[0] * sy + jointList[j].placement.origin[2] * cy;
-                       jointList[j].placement.origin[0] = x2;
-                       jointList[j].placement.origin[2] = z2;
-
-                       // y-axis rotation for direction
-                       x2 = jointList[j].placement.direction[0] * cy + jointList[j].placement.direction[2] * sy;
-                       z2 = -jointList[j].placement.direction[0] * sy + jointList[j].placement.direction[2] * cy;
-                       jointList[j].placement.direction[0] = x2;
-                       jointList[j].placement.direction[2] = z2;
-
-                       // y-axis rotation for up
-                       x2 = jointList[j].placement.up[0] * cy + jointList[j].placement.up[2] * sy;
-                       z2 = -jointList[j].placement.up[0] * sy + jointList[j].placement.up[2] * cy;
-                       jointList[j].placement.up[0] = x2;
-                       jointList[j].placement.up[2] = z2;
-
-                       // z-axis rotation for origin
-                       x2 = jointList[j].placement.origin[0] * cz - jointList[j].placement.origin[1] * sz;
-                       y2 = jointList[j].placement.origin[0] * sz + jointList[j].placement.origin[1] * cz;
-                       jointList[j].placement.origin[0] = x2;
-                       jointList[j].placement.origin[1] = y2;
-
-                       // z-axis rotation for direction
-                       x2 = jointList[j].placement.direction[0] * cz - jointList[j].placement.direction[1] * sz;
-                       y2 = jointList[j].placement.direction[0] * sz + jointList[j].placement.direction[1] * cz;
-                       jointList[j].placement.direction[0] = x2;
-                       jointList[j].placement.direction[1] = y2;
-
-                       // z-axis rotation for up
-                       x2 = jointList[j].placement.up[0] * cz - jointList[j].placement.up[1] * sz;
-                       y2 = jointList[j].placement.up[0] * sz + jointList[j].placement.up[1] * cz;
-                       jointList[j].placement.up[0] = x2;
-                       jointList[j].placement.up[1] = y2;
-
-                       // x-axis rotation for origin
-                       y2 = jointList[j].placement.origin[1] * cx - jointList[j].placement.origin[2] * sx;
-                       z2 = jointList[j].placement.origin[1] * sx + jointList[j].placement.origin[2] * cx;
-                       jointList[j].placement.origin[1] = y2;
-                       jointList[j].placement.origin[2] = z2;
-
-                       // x-axis rotation for direction vector
-                       y2 = jointList[j].placement.direction[1] * cx - jointList[j].placement.direction[2] * sx;
-                       z2 = jointList[j].placement.direction[1] * sx + jointList[j].placement.direction[2] * cx;
-                       jointList[j].placement.direction[1] = y2;
-                       jointList[j].placement.direction[2] = z2;
-
-                       // x-axis rotation for up vector
-                       y2 = jointList[j].placement.up[1] * cx - jointList[j].placement.up[2] * sx;
-                       z2 = jointList[j].placement.up[1] * sx + jointList[j].placement.up[2] * cx;
-                       jointList[j].placement.up[1] = y2;
-                       jointList[j].placement.up[2] = z2;
-
-                       if ( curCorrespondingJoint[j + 1] != -1 ) {
-                               // translate origin
-                               jointList[j].placement.origin[0] += curTranslation[i - 1][0];
-                               jointList[j].placement.origin[1] += curTranslation[i - 1][1];
-                               jointList[j].placement.origin[2] += curTranslation[i - 1][2];
-
-                               // translate back to local coord
-                               jointList[j].placement.direction[0] += curTranslation[i - 1][0];
-                               jointList[j].placement.direction[1] += curTranslation[i - 1][1];
-                               jointList[j].placement.direction[2] += curTranslation[i - 1][2];
-
-                               // translate back to local coord
-                               jointList[j].placement.up[0] += curTranslation[i - 1][0];
-                               jointList[j].placement.up[1] += curTranslation[i - 1][1];
-                               jointList[j].placement.up[2] += curTranslation[i - 1][2];
-                       }
-               }
-#endif
-       }
-}
-
-void LoadModelTransform( char *fileName ){
-       FILE *file1;
-       int dot = '.';
-       char *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-
-                       LoadHRCGlobals( InputFileName );
-
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC match.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-//                     printf("\n");
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRCGlobals( fileName );
-                               return;
-                       }
-               }
-
-               Error( "Could not open file '%s':\n",fileName );
-       }
-}
-
-void LoadModelClusters( char *fileName, int **clusterList, int *num_verts, int skelType ){
-       FILE *file1;
-       int dot = '.';
-       char *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-
-                       LoadHRCClustered( InputFileName, clusterList, num_verts, skelType );
-
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC match.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-//                     printf("\n");
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRCClustered( fileName, clusterList, num_verts, skelType );
-                               return;
-                       }
-               }
-
-               Error( "Could not open file '%s':\n",fileName );
-       }
-}
-
-void LoadSkeleton( char *fileName, QD_SkeletalJoint_t *jointList, int skelType ){
-       FILE *file1;
-       int dot = '.';
-       char *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-
-                       LoadHRCJointList( InputFileName, jointList, skelType );
-
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-//                     printf("\n");
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRCJointList( fileName, jointList, skelType );
-
-                               return;
-                       }
-               }
-
-               Error( "Could not open file '%s':\n",fileName );
-       }
-}
-
-/*
-   ===============
-   GrabSkeletalFrame
-   ===============
- */
-void GrabSkeletalFrame( char *frame ){
-       char file1[1024];
-       char    *framefile;
-       fmframe_t   *fr;
-
-       framefile = FindFrameFile( frame );
-
-       sprintf( file1, "%s/%s", cdarchive, framefile );
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s",cddir, framefile );
-
-       printf( "Grabbing Skeletal Frame %s\n", file1 );
-
-       fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
-
-       LoadSkeleton( file1, fr->joints, g_skelModel.type );
-}
-
-/*
-   ===============
-   GrabModelTransform
-   ===============
- */
-void GrabModelTransform( char *frame ){
-       char file1[1024];
-       char    *framefile;
-       fmframe_t   *fr;
-
-       framefile = FindFrameFile( frame );
-
-       sprintf( file1, "%s/%s", cdarchive, framefile );
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s",cddir, framefile );
-
-//     printf ("grabbing %s\n", file1);
-
-       fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
-
-       LoadModelTransform( file1 );
-}
-
-void Cmd_FMCluster(){
-       char file1[1024];
-
-       GetScriptToken( false );
-
-       printf( "---------------------\n" );
-       sprintf( file1, "%s/%s", cdpartial, token );
-       printf( "%s\n", file1 );
-
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s", cddir, token );
-
-       g_skelModel.clustered = -1;
-
-       LoadModelClusters( file1, (int **)&g_skelModel.clusters, (int *)&g_skelModel.num_verts, g_skelModel.type );
-
-       g_skelModel.new_num_verts[0] = g_skelModel.num_verts[0];
-
-       g_skelModel.clustered = true;
-}
-
-void Cmd_FMSkeleton(){
-       GetScriptToken( false );
-       g_skelModel.type = atoi( token );
-}
-
-void Cmd_FMSkeletalFrame(){
-       while ( ScriptTokenAvailable() )
-       {
-               GetScriptToken( false );
-               if ( g_skipmodel ) {
-                       GetScriptToken( false );
-                       continue;
-               }
-               if ( g_release || g_archive ) {
-                       fmheader.num_frames = 1;    // don't skip the writeout
-                       GetScriptToken( false );
-                       continue;
-               }
-
-               H_printf( "#define FRAME_%-16s\t%i\n", token, fmheader.num_frames );
-
-               GrabModelTransform( token );
-               GrabFrame( token );
-               GrabSkeletalFrame( token );
-
-               // need to add the up and dir points to the frame bounds here
-               // using AddPointToBounds (ptrivert[index_xyz].v, fr->mins, fr->maxs);
-               // then remove fudge in determining scale on frame write out
-       }
-}
-
-static void LoadHRCReferences( char *fileName, fmframe_t *fr ){
-#define MAX_STACK 64
-       int i, j, k;
-       vec3d_t curTranslation[MAX_STACK], curRotation[MAX_STACK];
-       int curCorrespondingJoint[MAX_STACK];
-       int currentStack, stackSize;
-       double cx, sx, cy, sy, cz, sz;
-       double rx, ry, rz;
-       double x2, y2, z2;
-       char stripped[SKELETAL_NAME_MAX];
-       Placement_d_t *placement;
-       int refnum;
-
-       TK_OpenSource( fileName );
-       TK_FetchRequire( TK_HRCH );
-       TK_FetchRequire( TK_COLON );
-       TK_FetchRequire( TK_SOFTIMAGE );
-
-       if ( RefPointNum <= 0 ) { // There were no labels indicated in the QDT, so use the hard-coded stuff.
-               refnum = numReferences[g_skelModel.references];
-       }
-       else
-       {
-               refnum = RefPointNum;
-       }
-
-       for ( k = 0; k < refnum; ++k )
-       {
-               currentStack = 0;
-
-               // Load the root to get translation and initial rotation
-//             TK_Beyond(TK_MODEL);
-
-               while ( TK_Search( TK_NAME ) != TK_EOF )
-               {
-                       TK_Require( TK_STRING );
-
-                       StripTrailingDigits( tk_String, stripped );
-
-                       if ( RefPointNum == 0 ) { // Hard coded refpoint labels
-                               if ( stricmp( stripped,
-                                                         referenceRootNames[referenceRootNameOffsets[g_skelModel.references] + k] ) == 0 ) {
-                                       break;
-                               }
-                       }
-                       else
-                       {   // labels indicated by the QDT
-                               if ( stricmp( stripped, RefPointNameList[k] ) == 0 ) {
-                                       break;
-                               }
-                       }
-               }
-
-               if ( tk_Token == TK_EOF ) {
-                       if ( RefPointNum == 0 ) { // Hard coded refpoint labels
-                               Error( "Bone Chain Root: %s not found\n", referenceRootNames[referenceRootNameOffsets[g_skelModel.references]] );
-                       }
-                       else
-                       {   // labels indicated by the QDT
-                               Error( "Bone Chain Root: %s not found\n", RefPointNameList[k] );
-                       }
-                       return;
-               }
-
-//             TK_Beyond(TK_SCALING);
-
-//             ParseVec3d(curScale[currentStack]);
-
-               TK_Beyond( TK_ROTATION );
-
-               ParseRotation3d( curRotation[currentStack] );
-
-               TK_Beyond( TK_TRANSLATION );
-
-               ParseVec3d( curTranslation[currentStack] );
-
-               // account for global model translation
-               curTranslation[currentStack][1] += g_skelModel.translation[0];
-               curTranslation[currentStack][2] += g_skelModel.translation[1];
-               curTranslation[currentStack][0] += g_skelModel.translation[2];
-
-               curCorrespondingJoint[currentStack] = -1;
-
-//             rjr - this one not needed, as there is also a stack increment 20 lines below???
-//             ++currentStack;
-
-               // Load the joint to get orientation
-               TK_Beyond( TK_MODEL );
-
-//             TK_Beyond(TK_SCALING);
-
-//             ParseVec3d(curScale[currentStack]);
-
-               TK_Beyond( TK_ROTATION );
-
-               ParseRotation3d( curRotation[currentStack] );
-
-//             TK_Beyond(TK_TRANSLATION);
-
-//             ParseVec3d(curTranslation[currentStack]);
-
-               fr->references[k].placement.origin[1] = 0.0;
-               fr->references[k].placement.origin[2] = 0.0;
-               fr->references[k].placement.origin[0] = 0.0;
-
-               fr->references[k].placement.direction[1] = 20.0;
-               fr->references[k].placement.direction[2] = 0.0;
-               fr->references[k].placement.direction[0] = 0.0;
-
-               fr->references[k].placement.up[1] = 0.0;
-               fr->references[k].placement.up[2] = 20.0;
-               fr->references[k].placement.up[0] = 0.0;
-
-               curCorrespondingJoint[currentStack] = k;
-
-               ++currentStack;
-
-               stackSize = currentStack;
-
-               for ( i = stackSize - 1; i >= 0; --i )
-               {
-                       rx = curRotation[i][0] * ANGLE_TO_RAD;
-                       ry = curRotation[i][1] * ANGLE_TO_RAD;
-                       rz = curRotation[i][2] * ANGLE_TO_RAD;
-
-                       cx = cos( rx );
-                       sx = sin( rx );
-
-                       cy = cos( ry );
-                       sy = sin( ry );
-
-                       cz = cos( rz );
-                       sz = sin( rz );
-
-                       for ( j = i; j < stackSize; ++j )
-                       {
-                               if ( curCorrespondingJoint[j] != -1 ) {
-                                       placement = &fr->references[curCorrespondingJoint[j]].placement;
-
-                                       // y-axis rotation for origin
-                                       x2 = placement->origin[0] * cy + placement->origin[2] * sy;
-                                       z2 = -placement->origin[0] * sy + placement->origin[2] * cy;
-                                       placement->origin[0] = x2;
-                                       placement->origin[2] = z2;
-
-                                       // y-axis rotation for direction
-                                       x2 = placement->direction[0] * cy + placement->direction[2] * sy;
-                                       z2 = -placement->direction[0] * sy + placement->direction[2] * cy;
-                                       placement->direction[0] = x2;
-                                       placement->direction[2] = z2;
-
-                                       // y-axis rotation for up
-                                       x2 = placement->up[0] * cy + placement->up[2] * sy;
-                                       z2 = -placement->up[0] * sy + placement->up[2] * cy;
-                                       placement->up[0] = x2;
-                                       placement->up[2] = z2;
-
-                                       // z-axis rotation for origin
-                                       x2 = placement->origin[0] * cz - placement->origin[1] * sz;
-                                       y2 = placement->origin[0] * sz + placement->origin[1] * cz;
-                                       placement->origin[0] = x2;
-                                       placement->origin[1] = y2;
-
-                                       // z-axis rotation for direction
-                                       x2 = placement->direction[0] * cz - placement->direction[1] * sz;
-                                       y2 = placement->direction[0] * sz + placement->direction[1] * cz;
-                                       placement->direction[0] = x2;
-                                       placement->direction[1] = y2;
-
-                                       // z-axis rotation for up
-                                       x2 = placement->up[0] * cz - placement->up[1] * sz;
-                                       y2 = placement->up[0] * sz + placement->up[1] * cz;
-                                       placement->up[0] = x2;
-                                       placement->up[1] = y2;
-
-                                       // x-axis rotation for origin
-                                       y2 = placement->origin[1] * cx - placement->origin[2] * sx;
-                                       z2 = placement->origin[1] * sx + placement->origin[2] * cx;
-                                       placement->origin[1] = y2;
-                                       placement->origin[2] = z2;
-
-                                       // x-axis rotation for direction vector
-                                       y2 = placement->direction[1] * cx - placement->direction[2] * sx;
-                                       z2 = placement->direction[1] * sx + placement->direction[2] * cx;
-                                       placement->direction[1] = y2;
-                                       placement->direction[2] = z2;
-
-                                       // x-axis rotation for up vector
-                                       y2 = placement->up[1] * cx - placement->up[2] * sx;
-                                       z2 = placement->up[1] * sx + placement->up[2] * cx;
-                                       placement->up[1] = y2;
-                                       placement->up[2] = z2;
-
-                                       // translate origin
-                                       placement->origin[0] += curTranslation[i][0];
-                                       placement->origin[1] += curTranslation[i][1];
-                                       placement->origin[2] += curTranslation[i][2];
-
-                                       // translate back to local coord
-                                       placement->direction[0] += curTranslation[i][0];
-                                       placement->direction[1] += curTranslation[i][1];
-                                       placement->direction[2] += curTranslation[i][2];
-
-                                       // translate back to local coord
-                                       placement->up[0] += curTranslation[i][0];
-                                       placement->up[1] += curTranslation[i][1];
-                                       placement->up[2] += curTranslation[i][2];
-
-                               }
-                       }
-               }
-               printf( "%f, %f, %f\n", placement->origin[0], placement->origin[1], placement->origin[2] );
-       }
-       printf( "\n" );
-}
-
-void Cmd_FMReferenced(){
-       int i;
-
-       GetScriptToken( false );
-       g_skelModel.references = atoi( token );
-
-       // Guess what?  Now, we now want a list of strings to look for here instead of a hard-coded list
-       for ( i = 0; i < REF_MAX_POINTS; i++ )
-       {
-               if ( ScriptTokenAvailable() ) { // There is yet another reference point waiting.
-                       GetScriptToken( false );
-                       strcpy( RefPointNameList[i], token );
-               }
-               else
-               {
-                       break;
-               }
-       }
-
-       RefPointNum = i;
-
-       if ( RefPointNum > 0 ) {
-               printf( "Searching for %d different reference points.\n", RefPointNum );
-       }
-       else
-       {
-               printf( "Using built-in reference points.\n" );
-       }
-
-}
-
-void LoadReferences( char *fileName, fmframe_t *fr ){
-       FILE *file1;
-       int dot = '.';
-       char *dotstart;
-       char InputFileName[256];
-
-       dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
-
-       if ( !dotstart ) {
-               strcpy( InputFileName, fileName );
-               strcat( InputFileName, ".hrc" );
-               if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
-                       fclose( file1 );
-
-                       LoadHRCReferences( InputFileName, fr );
-
-                       printf( " - assuming .HRC\n" );
-                       return;
-               }
-
-               Error( "\n Could not open file '%s':\n"
-                          "No HRC.\n", fileName );
-       }
-       else
-       {
-               if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
-                       printf( "\n" );
-                       fclose( file1 );
-                       if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
-                               LoadHRCReferences( fileName, fr );
-
-                               return;
-                       }
-               }
-
-               Error( "Could not open file '%s':\n",fileName );
-       }
-}
-
-void GrabReferencedFrame( char *frame ){
-       char file1[1024];
-       char    *framefile;
-       fmframe_t   *fr;
-
-       framefile = FindFrameFile( frame );
-
-       sprintf( file1, "%s/%s", cdarchive, framefile );
-       ExpandPathAndArchive( file1 );
-
-       sprintf( file1, "%s/%s",cddir, framefile );
-
-       printf( "Grabbing Referenced %s\n", file1 );
-
-       fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
-
-       LoadReferences( file1, fr );
-}
diff --git a/tools/quake2/qdata_heretic2/qd_skeletons.h b/tools/quake2/qdata_heretic2/qd_skeletons.h
deleted file mode 100644 (file)
index 7765c57..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef QD_SKELETONS_H
-#define QD_SKELETONS_H
-
-#include "placement.h"
-
-
-typedef struct Placement_d_s
-{
-       vec3d_t origin;
-       vec3d_t direction;
-       vec3d_t up;
-} Placement_d_t;
-
-typedef struct QD_SkeletalJoint_s
-{
-       Placement_d_t placement;
-       vec3d_t rotation;
-} QD_SkeletalJoint_t;
-
-#define NUM_CLUSTERS 8
-
-typedef struct IntListNode_s
-{
-       int data;
-       struct IntListNode_s *next;
-} IntListNode_t;  // gaak
-
-typedef struct Skeletalfmheader_s
-{
-       int type;
-       int clustered;
-       int references;
-
-       int *clusters[NUM_CLUSTERS];
-       IntListNode_t *vertLists[NUM_CLUSTERS];
-       int num_verts[NUM_CLUSTERS + 1];
-       int new_num_verts[NUM_CLUSTERS + 1];
-
-       float scaling[3];
-       float rotation[3];
-       float translation[3];
-} Skeletalfmheader_t;
-
-#define SKELETAL_NAME_MAX 32
-
-extern Skeletalfmheader_t g_skelModel;
-
-void ClearSkeletalModel();
-void GrabModelTransform( char *frame );
-void GrabSkeletalFrame( char *frame );
-void GrabReferencedFrame( char *frame );
-
-// Reference Stuff
-#define NUM_REFERENCES 8
-
-#define REF_MAX_POINTS  16
-#define REF_MAX_STRLEN  32
-
-// We're assuming no more than 16 reference points, with no more than 32 characters in the name
-extern char RefPointNameList[REF_MAX_POINTS][REF_MAX_STRLEN];
-extern int RefPointNum;
-
-#endif
diff --git a/tools/quake2/qdata_heretic2/qdata.c b/tools/quake2/qdata_heretic2/qdata.c
deleted file mode 100644 (file)
index 5ec53a9..0000000
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "qdata.h"
-#include "globaldefs.h"
-#include "md4.h"
-
-void TK_Init();
-
-qboolean g_compress_pak;
-qboolean g_release;             // don't grab, copy output data to new tree
-qboolean g_pak;                 // if true, copy to pak instead of release
-char g_releasedir[1024];        // c:\quake2\baseq2, etc
-qboolean g_archive;             // don't grab, copy source data to new tree
-qboolean do3ds;
-char g_only[256];               // if set, only grab this cd
-qboolean g_skipmodel;           // set true when a cd is not g_only
-int g_forcemodel = MODEL_AUTO;
-qboolean g_verbose = false;
-qboolean g_allow_newskin = true;
-qboolean g_ignoreTriUV = false;
-qboolean g_publishOutput = false;
-
-char        *ext_3ds = "3ds";
-char        *ext_tri = "tri";
-char        *trifileext;
-
-char g_materialFile[256] = "none";          // default for Heretic2
-char        *g_outputDir;
-extern char *g_publishDir;
-
-extern qboolean g_nomkdir;
-
-/*
-   =======================================================
-
-   PAK FILES
-
-   =======================================================
- */
-
-typedef struct
-{
-       char name[56];
-       int filepos, filelen;
-} packfile_t;
-
-typedef struct
-{
-       char id[4];
-       int dirofs;
-       int dirlen;
-} packheader_t;
-
-packfile_t pfiles[16384];
-FILE            *pakfile;
-packfile_t      *pf;
-packheader_t pakheader;
-
-
-
-/*
-   ==============
-   BeginPak
-   ==============
- */
-void BeginPak( char *outname ){
-       if ( !g_pak ) {
-               return;
-       }
-
-       pakfile = SafeOpenWrite( outname );
-
-       // leave space for header
-       SafeWrite( pakfile, &pakheader, sizeof( pakheader ) );
-
-       pf = pfiles;
-}
-
-
-/*
-   ==============
-   ReleaseFile
-
-   Filename should be gamedir reletive.
-   Either copies the file to the release dir, or adds it to
-   the pak file.
-   ==============
- */
-void ReleaseFile( char *filename ){
-       int len;
-       byte    *buf;
-       char source[1024];
-       char dest[1024];
-
-       if ( !g_release ) {
-               return;
-       }
-
-       sprintf( source, "%s%s", gamedir, filename );
-
-       if ( !g_pak ) { // copy it
-               sprintf( dest, "%s/%s", g_releasedir, filename );
-               printf( "copying to %s\n", dest );
-               QCopyFile( source, dest );
-               return;
-       }
-
-       // pak it
-       printf( "paking %s\n", filename );
-       if ( strlen( filename ) >= sizeof( pf->name ) ) {
-               Error( "Filename too long for pak: %s", filename );
-       }
-
-       len = LoadFile( source, (void **)&buf );
-
-       // segment moved to old.c
-
-       strcpy( pf->name, filename );
-       pf->filepos = LittleLong( ftell( pakfile ) );
-       pf->filelen = LittleLong( len );
-       pf++;
-
-       SafeWrite( pakfile, buf, len );
-
-       free( buf );
-}
-
-
-/*
-   ==============
-   FinishPak
-   ==============
- */
-void FinishPak( void ){
-       int dirlen;
-       int d;
-       int i;
-       unsigned checksum;
-
-       if ( !g_pak ) {
-               return;
-       }
-
-       pakheader.id[0] = 'P';
-       pakheader.id[1] = 'A';
-       pakheader.id[2] = 'C';
-       pakheader.id[3] = 'K';
-       dirlen = (byte *)pf - (byte *)pfiles;
-       pakheader.dirofs = LittleLong( ftell( pakfile ) );
-       pakheader.dirlen = LittleLong( dirlen );
-
-       checksum = Com_BlockChecksum( (void *)pfiles, dirlen );
-
-       SafeWrite( pakfile, pfiles, dirlen );
-
-       i = ftell( pakfile );
-
-       fseek( pakfile, 0, SEEK_SET );
-       SafeWrite( pakfile, &pakheader, sizeof( pakheader ) );
-       fclose( pakfile );
-
-       d = pf - pfiles;
-       printf( "%i files packed in %i bytes\n",d, i );
-       printf( "checksum: 0x%x\n", checksum );
-}
-
-
-/*
-   ===============
-   Cmd_File
-
-   This is only used to cause a file to be copied during a release
-   build (default.cfg, maps, etc)
-   ===============
- */
-void Cmd_File( void ){
-       GetScriptToken( false );
-       ReleaseFile( token );
-}
-
-/*
-   ===============
-   PackDirectory_r
-
-   ===============
- */
-#if GDEF_OS_WINDOWS
-#include "io.h"
-void PackDirectory_r( char *dir ){
-       struct _finddata_t fileinfo;
-       int handle;
-       char dirstring[1024];
-       char filename[1024];
-
-       sprintf( dirstring, "%s%s/*.*", gamedir, dir );
-
-       handle = _findfirst( dirstring, &fileinfo );
-       if ( handle == -1 ) {
-               return;
-       }
-
-       do
-       {
-               sprintf( filename, "%s/%s", dir, fileinfo.name );
-               if ( fileinfo.attrib & _A_SUBDIR ) { // directory
-                       if ( fileinfo.name[0] != '.' ) {  // don't pak . and ..
-                               PackDirectory_r( filename );
-                       }
-                       continue;
-               }
-               // copy or pack the file
-               ReleaseFile( filename );
-       } while ( _findnext( handle, &fileinfo ) != -1 );
-
-       _findclose( handle );
-}
-#else
-
-#include <sys/types.h>
-#ifdef NeXT
-#include <sys/dir.h>
-#else
-#include <dirent.h>
-#endif
-
-void PackDirectory_r( char *dir ){
-#ifdef NeXT
-       struct direct **namelist, *ent;
-#else
-       struct dirent **namelist, *ent;
-#endif
-       int count;
-       struct stat st;
-       int i;
-       int len;
-       char fullname[1024];
-       char dirstring[1024];
-       char        *name;
-
-       sprintf( dirstring, "%s%s", gamedir, dir );
-       count = scandir( dirstring, &namelist, NULL, NULL );
-
-       for ( i = 0 ; i < count ; i++ )
-       {
-               ent = namelist[i];
-               name = ent->d_name;
-
-               if ( name[0] == '.' ) {
-                       continue;
-               }
-
-               sprintf( fullname, "%s/%s", dir, name );
-               sprintf( dirstring, "%s%s/%s", gamedir, dir, name );
-
-               if ( stat( dirstring, &st ) == -1 ) {
-                       Error( "fstating %s", pf->name );
-               }
-               if ( st.st_mode & S_IFDIR ) { // directory
-                       PackDirectory_r( fullname );
-                       continue;
-               }
-
-               // copy or pack the file
-               ReleaseFile( fullname );
-       }
-}
-#endif
-
-
-/*
-   ===============
-   Cmd_Dir
-
-   This is only used to cause a directory to be copied during a
-   release build (sounds, etc)
-   ===============
- */
-void Cmd_Dir( void ){
-       GetScriptToken( false );
-       PackDirectory_r( token );
-}
-
-//========================================================================
-
-#define MAX_RTEX    16384
-int numrtex;
-char rtex[MAX_RTEX][64];
-
-void ReleaseTexture( char *name ){
-       int i;
-       char path[1024];
-
-       for ( i = 0 ; i < numrtex ; i++ )
-               if ( !Q_strcasecmp( name, rtex[i] ) ) {
-                       return;
-               }
-
-       if ( numrtex == MAX_RTEX ) {
-               Error( "numrtex == MAX_RTEX" );
-       }
-
-       strcpy( rtex[i], name );
-       numrtex++;
-
-       sprintf( path, "textures/%s.wal", name );
-       ReleaseFile( path );
-}
-
-/*
-   ===============
-   Cmd_Maps
-
-   Only relevent for release and pak files.
-   Releases the .bsp files for the maps, and scans all of the files to
-   build a list of all textures used, which are then released.
-   ===============
- */
-void Cmd_Maps( void ){
-       char map[1024];
-       int i;
-
-       while ( ScriptTokenAvailable() )
-       {
-               GetScriptToken( false );
-               sprintf( map, "maps/%s.bsp", token );
-               ReleaseFile( map );
-
-               if ( !g_release ) {
-                       continue;
-               }
-
-               // get all the texture references
-               sprintf( map, "%smaps/%s.bsp", gamedir, token );
-               LoadBSPFileTexinfo( map );
-               for ( i = 0 ; i < numtexinfo ; i++ )
-                       ReleaseTexture( texinfo[i].texture );
-       }
-}
-
-
-//==============================================================
-
-/*
-   ===============
-   ParseScript
-   ===============
- */
-void ParseScript( void ){
-       while ( 1 )
-       {
-               do
-               {   // look for a line starting with a $ command
-                       GetScriptToken( true );
-                       if ( endofscript ) {
-                               return;
-                       }
-                       if ( token[0] == '$' ) {
-                               break;
-                       }
-                       while ( ScriptTokenAvailable() )
-                               GetScriptToken( false );
-               } while ( 1 );
-
-               //
-               // model commands
-               //
-               if ( !strcmp( token, "$modelname" ) ) {
-                       MODELCMD_Modelname( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$cd" ) ) {
-                       MODELCMD_Cd( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$origin" ) ) {
-                       MODELCMD_Origin( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$cluster" ) ) {
-                       MODELCMD_Cluster( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$base" ) ) {
-                       MODELCMD_Base( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$scale" ) ) {
-                       MODELCMD_ScaleUp( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$frame" ) ) {
-                       MODELCMD_Frame( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$skin" ) ) {
-                       MODELCMD_Skin( MODEL_MD2 );
-               }
-               else if ( !strcmp( token, "$skinsize" ) ) {
-                       MODELCMD_Skinsize( MODEL_MD2 );
-               }
-               //
-               // flexible model commands
-               //
-               else if ( !strcmp( token, "$fm_modelname" ) ) {
-                       MODELCMD_Modelname( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_base" ) ) {
-                       MODELCMD_Base( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_basest" ) ) {
-                       MODELCMD_BaseST( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_cd" ) ) {
-                       MODELCMD_Cd( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_origin" ) ) {
-                       MODELCMD_Origin( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_cluster" ) ) {
-                       MODELCMD_Cluster( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_skeleton" ) ) {
-                       MODELCMD_Skeleton( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_scale" ) ) {
-                       MODELCMD_ScaleUp( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_frame" ) ) {
-                       MODELCMD_Frame( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_skeletal_frame" ) ) { // left in for compadibility with qdt already using fm_skeletal_frame
-                       MODELCMD_Frame( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_skin" ) ) {
-                       MODELCMD_Skin( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_skinsize" ) ) {
-                       MODELCMD_Skinsize( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_begin_group" ) ) {
-                       MODELCMD_BeginGroup( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_end_group" ) ) {
-                       MODELCMD_EndGroup( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_referenced" ) ) {
-                       MODELCMD_Referenced( MODEL_FM );
-               }
-               else if ( !strcmp( token, "$fm_node_order" ) ) {
-                       MODELCMD_NodeOrder( MODEL_FM );
-               }
-
-               //
-               // sprite commands
-               //
-               else if ( !strcmp( token, "$spritename" ) ) {
-                       Cmd_SpriteName();
-               }
-               else if ( !strcmp( token, "$sprdir" ) ) {
-                       Cmd_Sprdir();
-               }
-               else if ( !strcmp( token, "$load" ) ) {
-                       Cmd_Load();
-               }
-               else if ( !strcmp( token, "$spriteframe" ) ) {
-                       Cmd_SpriteFrame();
-               }
-               //
-               // image commands
-               //
-               else if ( !strcmpi( token, "$grab" ) ) {
-                       Cmd_Grab();
-               }
-               else if ( !strcmpi( token, "$raw" ) ) {
-                       Cmd_Raw();
-               }
-               else if ( !strcmpi( token, "$colormap" ) ) {
-                       Cmd_Colormap();
-               }
-               else if ( !strcmpi( token, "$mippal" ) ) {
-                       Cmd_Mippal();
-               }
-               else if ( !strcmpi( token, "$mipdir" ) ) {
-                       Cmd_Mipdir();
-               }
-               else if ( !strcmpi( token, "$mip" ) ) {
-                       Cmd_Mip();
-               }
-               else if ( !strcmp( token, "$environment" ) ) {
-                       Cmd_Environment();
-               }
-               //
-               // pics
-               //
-               else if ( !strcmp( token, "$picdir" ) ) {
-                       Cmd_Picdir();
-               }
-               else if ( !strcmp( token, "$pic" ) ) {
-                       Cmd_Pic();
-               }
-               //
-               // book
-               //
-               else if ( !strcmp( token, "$bookdir" ) ) {
-                       Cmd_Bookdir();
-               }
-               else if ( !strcmp( token, "$book" ) ) {
-                       Cmd_Book();
-               }
-               //
-               // tmix
-               //
-               else if ( !strcmp( token, "$texturemix" ) ) {
-                       Cmd_TextureMix();
-               }
-               //
-               // video
-               //
-               else if ( !strcmp( token, "$video" ) ) {
-                       Cmd_Video();
-               }
-               //
-               // misc
-               //
-               else if ( !strcmp( token, "$file" ) ) {
-                       Cmd_File();
-               }
-               else if ( !strcmp( token, "$dir" ) ) {
-                       Cmd_Dir();
-               }
-               else if ( !strcmp( token, "$maps" ) ) {
-                       Cmd_Maps();
-               }
-               else if ( !strcmp( token, "$alphalight" ) ) {
-                       Cmd_Alphalight();
-               }
-               else if ( !strcmp( token, "$inverse16table" ) ) {
-                       Cmd_Inverse16Table();
-               }
-               else{
-                       Error( "bad command %s\n", token );
-               }
-       }
-}
-
-//=======================================================
-
-/*
-   ==============
-   main
-   ==============
- */
-int main( int argc, char **argv ){
-       int i;
-       char path[1024];
-       char        *basedir;
-       double starttime, endtime;
-
-       printf( "Qdata Plus : "__TIME__ " "__DATE__ "\n" );
-
-       starttime = I_FloatTime();
-       basedir = NULL;
-
-       TK_Init();
-       ExpandWildcards( &argc, &argv );
-
-       for ( i = 1 ; i < argc ; i++ )
-       {
-               if ( !strcmp( argv[i], "-archive" ) ) {
-                       // -archive f:/quake2/release/dump_11_30
-                       archive = true;
-                       strcpy( archivedir, argv[i + 1] );
-                       printf( "Archiving source to: %s\n", archivedir );
-                       i++;
-               }
-               else if ( !strcmp( argv[i], "-release" ) ) {
-                       g_release = true;
-                       strcpy( g_releasedir, argv[i + 1] );
-                       printf( "Copy output to: %s\n", g_releasedir );
-                       i++;
-               }
-               else if ( !strcmp( argv[i], "-base" ) ) {
-                       i++;
-                       basedir = argv[i];
-               }
-               else if ( !strcmp( argv[i], "-compress" ) ) {
-                       g_compress_pak = true;
-                       printf( "Compressing pakfile\n" );
-               }
-               else if ( !strcmp( argv[i], "-pak" ) ) {
-                       g_release = true;
-                       g_pak = true;
-                       printf( "Building pakfile: %s\n", argv[i + 1] );
-                       BeginPak( argv[i + 1] );
-                       i++;
-               }
-               else if ( !strcmp( argv[i], "-only" ) ) {
-                       strcpy( g_only, argv[i + 1] );
-                       printf( "Only grabbing %s\n", g_only );
-                       i++;
-               }
-               else if ( !strcmpi( argv[i], "-keypress" ) ) {
-                       g_dokeypress = true;
-               }
-               else if ( !strcmp( argv[i], "-3ds" ) ) {
-                       do3ds = true;
-                       printf( "loading .3ds files\n" );
-               }
-               else if ( !strcmp( argv[i], "-materialfile" ) ) {
-                       strcpy( g_materialFile, argv[i + 1] );
-                       printf( "Setting material file to %s\n", g_materialFile );
-                       i++;
-               }
-/*             else if (!strcmpi(argv[i], "-newgen"))
-        {
-            if (i < argc-4)
-            {
-                printf("run new triangle grouping routine here\n");
-                NewGen(argv[i+1],argv[i+2],atoi(argv[i+3]),atoi(argv[i+4]));
-            }
-            else
-            {
-                printf("qdata -newskin <base.hrc> <skin.pcx> width height\n");
-            }
-            return 0;
-        }
- */     else if ( !strcmpi( argv[i], "-genskin" ) ) {
-                       i++;
-                       if ( i < argc - 3 ) {
-                               GenSkin( argv[i],argv[i + 1],atol( argv[i + 2] ),atol( argv[i + 3] ) );
-                       }
-                       else
-                       {
-                               printf( "qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>\n" );
-                       }
-                       return 0;
-
-               }
-               else if ( !strcmpi( argv[i], "-noopts" ) ) {
-                       g_no_opimizations = true;
-                       printf( "not performing optimizations\n" );
-               }
-               else if ( !strcmpi( argv[i], "-md2" ) ) {
-                       g_forcemodel = MODEL_MD2;
-               }
-               else if ( !strcmpi( argv[i], "-fm" ) ) {
-                       g_forcemodel = MODEL_FM;
-               }
-               else if ( !strcmpi( argv[i], "-verbose" ) ) {
-                       g_verbose = true;
-               }
-               else if ( !strcmpi( argv[i], "-oldskin" ) ) {
-                       g_allow_newskin = false;
-               }
-               else if ( !strcmpi( argv[i], "-ignoreUV" ) ) {
-                       g_ignoreTriUV = true;
-               }
-               else if ( !strcmpi( argv[i], "-publish" ) ) {
-                       g_publishOutput = true;
-               }
-               else if ( !strcmpi( argv[i], "-nomkdir" ) ) {
-                       g_nomkdir = true;
-               }
-               else if ( argv[i][0] == '-' ) {
-                       Error( "Unknown option \"%s\"", argv[i] );
-               }
-               else{
-                       break;
-               }
-       }
-
-       if ( i >= argc ) {
-               Error( "usage: qdata [-archive <directory>]\n"
-                          "             [-release <directory>]\n"
-                          "             [-base <directory>]\n"
-                          "             [-compress]\n"
-                          "             [-pak <file>]\n"
-                          "             [-only <model>]\n"
-                          "             [-keypress]\n"
-                          "             [-3ds]\n"
-                          "             [-materialfile <file>]\n"
-                          "             [-noopts]\n"
-                          "             [-md2]\n"
-                          "             [-fm]\n"
-                          "             [-verbose]\n"
-                          "             [-ignoreUV]\n"
-                          "             [-oldskin]\n"
-                          "             [-publish]\n"
-                          "             [-nomkdir]\n"
-                          "             file.qdt\n"
-                          "or\n"
-                          "       qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>" );
-       }
-
-       if ( do3ds ) {
-               trifileext = ext_3ds;
-       }
-       else{
-               trifileext = ext_tri;
-       }
-
-       for ( ; i < argc ; i++ )
-       {
-               printf( "--------------- %s ---------------\n", argv[i] );
-               // load the script
-               strcpy( path, argv[i] );
-               DefaultExtension( path, ".qdt" );
-               DefaultExtension( g_materialFile, ".mat" );
-               SetQdirFromPath( path );
-
-               printf( "workingdir='%s'\n", gamedir );
-               if ( basedir ) {
-                       qdir[0] = 0;
-                       g_outputDir = basedir;
-               }
-
-               printf( "outputdir='%s'\n", g_outputDir );
-
-               QFile_ReadMaterialTypes( g_materialFile );
-               LoadScriptFile( ExpandArg( path ) );
-
-               //
-               // parse it
-               //
-               ParseScript();
-
-               // write out the last model
-               FinishModel();
-               FMFinishModel();
-               FinishSprite();
-       }
-
-       if ( total_textures ) {
-               printf( "\n" );
-               printf( "Total textures processed: %d\n",total_textures );
-               printf( "Average size: %d x %d\n",total_x / total_textures, total_y / total_textures );
-       }
-
-       if ( g_pak ) {
-               FinishPak();
-       }
-
-       endtime = I_FloatTime();
-       printf( "Time elapsed:  %f\n", endtime - starttime );
-
-       if ( g_dokeypress ) {
-               printf( "Success! ... Hit a key: " );
-               getchar();
-       }
-
-       return 0;
-}
diff --git a/tools/quake2/qdata_heretic2/qdata.h b/tools/quake2/qdata_heretic2/qdata.h
deleted file mode 100644 (file)
index 0cfa606..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// qdata.h
-
-#include "globaldefs.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include "cmdlib.h"
-#include "inout.h"
-#include "scriplib.h"
-#include "mathlib.h"
-#include "trilib.h"
-#include "lbmlib.h"
-#include "her2_threads.h"
-#include "l3dslib.h"
-#include "bspfile.h"
-
-#if !GDEF_OS_WINDOWS
-#define stricmp strcasecmp
-#define strcmpi strcasecmp
-#endif
-
-
-#define MODEL_AUTO  0
-#define MODEL_MD2   1
-#define MODEL_FM    2
-
-// Model cover functions (to allow the forcing of a model type)
-void MODELCMD_Modelname( int modeltype );
-void MODELCMD_Cd( int modeltype );
-void MODELCMD_Origin( int modeltype );
-void MODELCMD_Jointed( int modeltype );
-void MODELCMD_Cluster( int modeltype );
-void MODELCMD_Base( int modeltype );
-void MODELCMD_BaseST( int modeltype );
-void MODELCMD_ScaleUp( int modeltype );
-void MODELCMD_Frame( int modeltype );
-void MODELCMD_Skin( int modeltype );
-void MODELCMD_Skinsize( int modeltype );
-void MODELCMD_Skeleton( int modeltype );
-void MODELCMD_SkeletalFrame( int modeltype );
-void MODELCMD_BeginGroup( int modeltype );
-void MODELCMD_EndGroup( int modeltype );
-void MODELCMD_Referenced( int modeltype );
-void MODELCMD_NodeOrder( int modeltype );
-
-void Cmd_Modelname( void );
-void Cmd_Base( void );
-void Cmd_Cd( void );
-void Cmd_Origin( void );
-void Cmd_ScaleUp( void );
-void Cmd_Frame( void );
-void Cmd_Skin( void );
-void Cmd_Skinsize( void );
-void FinishModel( void );
-void Cmd_Cluster( void );
-
-// Flexible Models
-//void Cmd_FMModelname (void);
-void Cmd_FMBase( qboolean GetST );
-void Cmd_FMCd( void );
-//void Cmd_FMOrigin (void);
-void Cmd_FMCluster();
-void Cmd_FMSkeleton();
-//void Cmd_FMScaleUp (void);
-void Cmd_FMFrame( void );
-void Cmd_FMSkeletalFrame();
-void Cmd_FMSkin( void );
-//void Cmd_FMSkinsize (void);
-void Cmd_FMBeginGroup( void );
-void Cmd_FMEndGroup( void );
-void Cmd_FMReferenced();
-void Cmd_FMNodeOrder( void );
-void FMFinishModel( void );
-void GenSkin( char *ModelFile, char *OutputName, int Width, int Height );
-void NewGen( char *ModelFile, char *OutputName, int width, int height );
-
-
-void Cmd_Inverse16Table( void );
-
-void Cmd_SpriteName( void );
-void Cmd_Load( void );
-void Cmd_SpriteFrame( void );
-void Cmd_Sprdir( void );
-void FinishSprite( void );
-
-void Cmd_Grab( void );
-void Cmd_Raw( void );
-void Cmd_Mip( void );
-void Cmd_Environment( void );
-void Cmd_Colormap( void );
-
-void Cmd_File( void );
-void Cmd_Dir( void );
-void Cmd_StartWad( void );
-void Cmd_EndWad( void );
-void Cmd_Mippal( void );
-void Cmd_Mipdir( void );
-void Cmd_Alphalight( void );
-
-void Cmd_Picdir( void );
-void Cmd_Pic( void );
-
-void Cmd_Bookdir( void );
-void Cmd_Book( void );
-
-void Cmd_TextureMix( void );
-
-void Cmd_Video( void );
-
-//void RemapZero (byte *pixels, byte *palette, int width, int height);
-
-void ReleaseFile( char *filename );
-
-extern byte        *byteimage, *lbmpalette;
-extern int byteimagewidth, byteimageheight;
-extern qboolean TrueColorImage;
-extern unsigned    *longimage;
-extern int longimagewidth, longimageheight;
-
-extern qboolean g_release;              // don't grab, copy output data to new tree
-extern char g_releasedir[1024];         // c:\quake2\baseq2, etc
-extern qboolean g_archive;              // don't grab, copy source data to new tree
-extern qboolean do3ds;
-extern char g_only[256];                // if set, only grab this cd
-extern qboolean g_skipmodel;            // set true when a cd is not g_only
-extern qboolean g_no_opimizations;
-extern int g_forcemodel;
-extern qboolean g_verbose;
-extern qboolean g_allow_newskin;
-extern qboolean g_ignoreTriUV;      //from qdata.c
-extern qboolean g_dokeypress;
-
-extern char        *trifileext;
-
-extern char g_materialFile[256];
-
-extern unsigned total_x;
-extern unsigned total_y;
-extern unsigned total_textures;
-
-miptex_t *CreateMip( byte *data, unsigned width, unsigned height, byte *palette, int *FinalSize, qboolean mip );
-miptex32_t *CreateMip32( unsigned *data, unsigned width, unsigned height, int *FinalSize, qboolean mip );
diff --git a/tools/quake2/qdata_heretic2/resource.h b/tools/quake2/qdata_heretic2/resource.h
deleted file mode 100644 (file)
index 3d6343e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by Script1.rc
-//
-#define IDI_ICON1                       101
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NO_MFC                     1
-#define _APS_3D_CONTROLS                     1
-#define _APS_NEXT_RESOURCE_VALUE        102
-#define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1000
-#define _APS_NEXT_SYMED_VALUE           101
-#endif
-#endif
diff --git a/tools/quake2/qdata_heretic2/sprites.c b/tools/quake2/qdata_heretic2/sprites.c
deleted file mode 100644 (file)
index ecb9d09..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#include "qdata.h"
-
-#define MAX_SPRFRAMES           MAX_MD2SKINS
-
-dsprite_t sprite;
-dsprframe_t frames[MAX_SPRFRAMES];
-
-byte            *byteimage, *lbmpalette;
-int byteimagewidth, byteimageheight;
-
-qboolean TrueColorImage;
-unsigned        *longimage;
-int longimagewidth, longimageheight;
-
-char spritename[1024];
-
-
-void FinishSprite( void );
-void Cmd_Spritename( void );
-
-char spr_prefix[1024];
-char pic_prefix[1024];
-
-extern char        *g_outputDir;
-
-
-/*
-   ==============
-   FinishSprite
-   ==============
- */
-void FinishSprite( void ){
-       FILE    *spriteouthandle;
-       int i, curframe;
-       dsprite_t spritetemp;
-       char savename[1024];
-
-       if ( sprite.numframes == 0 ) {
-               return;
-       }
-
-       if ( !strlen( spritename ) ) {
-               Error( "Didn't name sprite file" );
-       }
-
-       sprintf( savename, "%sSprites/%s/%s.sp2", g_outputDir, spr_prefix, spritename );
-
-       if ( g_release ) {
-               char name[1024];
-
-               sprintf( name, "%s.sp2", spritename );
-               ReleaseFile( name );
-               spritename[0] = 0;      // clear for a new sprite
-               sprite.numframes = 0;
-               return;
-       }
-
-
-       printf( "saving in %s\n", savename );
-       CreatePath( savename );
-       spriteouthandle = SafeOpenWrite( savename );
-
-
-//
-// write out the sprite header
-//
-       spritetemp.ident = LittleLong( IDSPRITEHEADER );
-       spritetemp.version = LittleLong( SPRITE_VERSION );
-       spritetemp.numframes = LittleLong( sprite.numframes );
-
-       SafeWrite( spriteouthandle, &spritetemp, 12 );
-
-//
-// write out the frames
-//
-       curframe = 0;
-
-       for ( i = 0 ; i < sprite.numframes ; i++ )
-       {
-               frames[i].width = LittleLong( frames[i].width );
-               frames[i].height = LittleLong( frames[i].height );
-               frames[i].origin_x = LittleLong( frames[i].origin_x );
-               frames[i].origin_y = LittleLong( frames[i].origin_y );
-       }
-       SafeWrite( spriteouthandle, frames, sizeof( frames[0] ) * sprite.numframes );
-
-       fclose( spriteouthandle );
-
-       spritename[0] = 0;      // clear for a new sprite
-       sprite.numframes = 0;
-}
-
-
-/*
-   ===============
-   Cmd_Load
-   ===============
- */
-void Cmd_Load( void ){
-       char    *name;
-
-       GetScriptToken( false );
-
-       if ( g_release ) {
-               return;
-       }
-
-       name = ExpandPathAndArchive( token );
-
-       // load the image
-       printf( "loading %s\n", name );
-       TrueColorImage = LoadAnyImage( name, &byteimage, &lbmpalette, &byteimagewidth, &byteimageheight );
-
-       if ( !TrueColorImage ) {
-//             RemapZero (byteimage, lbmpalette, byteimagewidth, byteimageheight);
-       }
-       else
-       {
-               if ( longimage ) {
-                       free( longimage );
-               }
-               longimage = (unsigned *)byteimage;
-               longimagewidth = byteimagewidth;
-               longimageheight = byteimageheight;
-
-               byteimage = NULL;
-               byteimagewidth = 0;
-               byteimageheight = 0;
-       }
-}
-
-
-/*
-   ===============
-   Cmd_SpriteFrame
-   ===============
- */
-
-void Cmd_SpriteFrame( void ){
-       int x,y,xl,yl,xh,yh,w,h;
-       dsprframe_t     *pframe;
-       int ox, oy, linedelta, size;
-//     byte                    *cropped;
-       char filename[1024];
-       miptex_t        *qtex;
-       miptex32_t      *qtex32;
-       unsigned        *destl, *sourcel;
-       unsigned bufferl[256 * 256];
-       byte            *dest, *source;
-       byte buffer[256 * 256];
-
-       GetScriptToken( false );
-       xl = atoi( token );
-       GetScriptToken( false );
-       yl = atoi( token );
-       GetScriptToken( false );
-       w = atoi( token );
-       GetScriptToken( false );
-       h = atoi( token );
-
-       // origin offset is optional
-       if ( ScriptTokenAvailable() ) {
-               GetScriptToken( false );
-               ox = atoi( token );
-               GetScriptToken( false );
-               oy = atoi( token );
-       }
-       else
-       {
-               ox = w / 2;
-               oy = h / 2;
-       }
-
-       if ( ( xl & 0x0f ) || ( yl & 0x0f ) || ( w & 0x0f ) || ( h & 0x0f ) ) {
-               Error( "Sprite dimensions not multiples of 16\n" );
-       }
-
-       if ( ( w > 256 ) || ( h > 256 ) ) {
-               Error( "Sprite has a dimension longer than 256" );
-       }
-
-       xh = xl + w;
-       yh = yl + h;
-
-       if ( sprite.numframes >= MAX_SPRFRAMES ) {
-               Error( "Too many frames; increase MAX_SPRFRAMES\n" );
-       }
-
-       pframe = &frames[sprite.numframes];
-       pframe->width = w;
-       pframe->height = h;
-       pframe->origin_x = ox;
-       pframe->origin_y = oy;
-
-       if ( g_release ) {
-               ReleaseFile( pframe->name );
-               return;
-       }
-
-       if ( TrueColorImage ) {
-               sprintf( filename, "%ssprites/%s/%s_%i.m32", g_outputDir, spr_prefix, spritename, sprite.numframes );
-               sprintf( pframe->name, "%s/%s_%i.m32", spr_prefix, spritename, sprite.numframes );
-
-               if ( g_release ) {
-                       return; // textures are only released by $maps
-
-               }
-               xh = xl + w;
-               yh = yl + h;
-
-               if ( xl >= longimagewidth || xh > longimagewidth ||
-                        yl >= longimageheight || yh > longimageheight ) {
-                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight );
-               }
-
-               sourcel = longimage + ( yl * longimagewidth ) + xl;
-               destl = bufferl;
-               linedelta = ( longimagewidth - w );
-
-               for ( y = yl ; y < yh ; y++ )
-               {
-                       for ( x = xl ; x < xh ; x++ )
-                       {
-                               *destl++ = *sourcel++;  // RGBA
-                       }
-                       sourcel += linedelta;
-               }
-
-               qtex32 = CreateMip32( bufferl, w, h, &size, true );
-
-               qtex32->contents = 0;
-               qtex32->value = 0;
-               strcpy( qtex32->name, pframe->name );
-               //
-               // write it out
-               //
-               printf( "writing %s\n", filename );
-               SaveFile( filename, (byte *)qtex32, size );
-
-               free( qtex32 );
-       }
-       else
-       {
-               sprintf( filename, "%ssprites/%s/%s_%i.m8", g_outputDir, spr_prefix, spritename, sprite.numframes );
-               sprintf( pframe->name, "%s/%s_%i.m8", spr_prefix, spritename, sprite.numframes );
-
-               if ( g_release ) {
-                       return; // textures are only released by $maps
-
-               }
-               xh = xl + w;
-               yh = yl + h;
-
-               if ( xl >= byteimagewidth || xh > byteimagewidth ||
-                        yl >= byteimageheight || yh > byteimageheight ) {
-                       Error( "line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight );
-               }
-
-               source = byteimage + yl * byteimagewidth + xl;
-               dest = buffer;
-               linedelta = byteimagewidth - w;
-
-               for ( y = yl ; y < yh ; y++ )
-               {
-                       for ( x = xl ; x < xh ; x++ )
-                       {
-                               *dest++ = *source++;
-                       }
-                       source += linedelta;
-               }
-
-               qtex = CreateMip( buffer, w, h, lbmpalette, &size, true );
-
-               qtex->flags = 0;
-               qtex->contents = 0;
-               qtex->value = 0;
-               strcpy( qtex->name, pframe->name );
-               //
-               // write it out
-               //
-               printf( "writing %s\n", filename );
-               SaveFile( filename, (byte *)qtex, size );
-
-               free( qtex );
-       }
-
-       sprite.numframes++;
-}
-
-
-/*
-   ==============
-   Cmd_SpriteName
-   ==============
- */
-void Cmd_SpriteName( void ){
-       if ( sprite.numframes ) {
-               FinishSprite();
-       }
-
-       GetScriptToken( false );
-       strcpy( spritename, token );
-       memset( &sprite, 0, sizeof( sprite ) );
-       memset( &frames, 0, sizeof( frames ) );
-}
-
-
-/*
-   ===============
-   Cmd_Sprdir
-   ===============
- */
-void Cmd_Sprdir( void ){
-       char filename[1024];
-
-       GetScriptToken( false );
-       strcpy( spr_prefix, token );
-       // create the directory if needed
-       sprintf( filename, "%sSprites", g_outputDir );
-       Q_mkdir( filename );
-       sprintf( filename, "%sSprites/%s", g_outputDir, spr_prefix );
-       Q_mkdir( filename );
-}
diff --git a/tools/quake2/qdata_heretic2/svdcmp.c b/tools/quake2/qdata_heretic2/svdcmp.c
deleted file mode 100644 (file)
index 14865af..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <math.h>
-
-static double at,bt,ct;
-#define PYTHAG( a,b ) ( ( at = fabs( a ) ) > ( bt = fabs( b ) ) ? \
-                                               ( ct = bt / at,at * sqrt( 1.0 + ct * ct ) ) : ( bt ? ( ct = at / bt,bt * sqrt( 1.0 + ct * ct ) ) : 0.0 ) )
-
-static double maxarg1,maxarg2;
-#define MAX( a,b ) ( maxarg1 = ( a ),maxarg2 = ( b ),( maxarg1 ) > ( maxarg2 ) ? \
-                                        ( maxarg1 ) : ( maxarg2 ) )
-#define SIGN( a,b ) ( ( b ) >= 0.0 ? fabs( a ) : -fabs( a ) )
-
-void ntrerror( char *s ){
-       printf( "%s\n",s );
-       exit( 1 );
-}
-
-double *allocVect( int sz ){
-       double *ret;
-
-       ret = calloc( sizeof( double ), (size_t)sz );
-       return ret;
-}
-
-void freeVect( double *ret ){
-       free( ret );
-}
-
-double **allocMatrix( int r,int c ){
-       double **ret;
-
-       ret = calloc( sizeof( double ), (size_t)( r * c ) );
-       return ret;
-}
-
-void freeMatrix( double **ret,int r ){
-       free( ret );
-}
-
-void svdcmp( double** a, int m, int n, double* w, double** v ){
-       int flag,i,its,j,jj,k,l,nm;
-       double c,f,h,s,x,y,z;
-       double anorm = 0.0,g = 0.0,scale = 0.0;
-       double *rv1;
-       void nrerror();
-
-       if ( m < n ) {
-               ntrerror( "SVDCMP: You must augment A with extra zero rows" );
-       }
-       rv1 = allocVect( n );
-       for ( i = 1; i <= n; i++ ) {
-               l = i + 1;
-               rv1[i] = scale * g;
-               g = s = scale = 0.0;
-               if ( i <= m ) {
-                       for ( k = i; k <= m; k++ ) scale += fabs( a[k][i] );
-                       if ( scale ) {
-                               for ( k = i; k <= m; k++ ) {
-                                       a[k][i] /= scale;
-                                       s += a[k][i] * a[k][i];
-                               }
-                               f = a[i][i];
-                               g = -SIGN( sqrt( s ),f );
-                               h = f * g - s;
-                               a[i][i] = f - g;
-                               if ( i != n ) {
-                                       for ( j = l; j <= n; j++ ) {
-                                               for ( s = 0.0,k = i; k <= m; k++ ) s += a[k][i] * a[k][j];
-                                               f = s / h;
-                                               for ( k = i; k <= m; k++ ) a[k][j] += f * a[k][i];
-                                       }
-                               }
-                               for ( k = i; k <= m; k++ ) a[k][i] *= scale;
-                       }
-               }
-               w[i] = scale * g;
-               g = s = scale = 0.0;
-               if ( i <= m && i != n ) {
-                       for ( k = l; k <= n; k++ ) scale += fabs( a[i][k] );
-                       if ( scale ) {
-                               for ( k = l; k <= n; k++ ) {
-                                       a[i][k] /= scale;
-                                       s += a[i][k] * a[i][k];
-                               }
-                               f = a[i][l];
-                               g = -SIGN( sqrt( s ),f );
-                               h = f * g - s;
-                               a[i][l] = f - g;
-                               for ( k = l; k <= n; k++ ) rv1[k] = a[i][k] / h;
-                               if ( i != m ) {
-                                       for ( j = l; j <= m; j++ ) {
-                                               for ( s = 0.0,k = l; k <= n; k++ ) s += a[j][k] * a[i][k];
-                                               for ( k = l; k <= n; k++ ) a[j][k] += s * rv1[k];
-                                       }
-                               }
-                               for ( k = l; k <= n; k++ ) a[i][k] *= scale;
-                       }
-               }
-               anorm = MAX( anorm,( fabs( w[i] ) + fabs( rv1[i] ) ) );
-       }
-       for ( i = n; i >= 1; i-- ) {
-               if ( i < n ) {
-                       if ( g ) {
-                               for ( j = l; j <= n; j++ )
-                                       v[j][i] = ( a[i][j] / a[i][l] ) / g;
-                               for ( j = l; j <= n; j++ ) {
-                                       for ( s = 0.0,k = l; k <= n; k++ ) s += a[i][k] * v[k][j];
-                                       for ( k = l; k <= n; k++ ) v[k][j] += s * v[k][i];
-                               }
-                       }
-                       for ( j = l; j <= n; j++ ) v[i][j] = v[j][i] = 0.0;
-               }
-               v[i][i] = 1.0;
-               g = rv1[i];
-               l = i;
-       }
-       for ( i = n; i >= 1; i-- ) {
-               l = i + 1;
-               g = w[i];
-               if ( i < n ) {
-                       for ( j = l; j <= n; j++ ) a[i][j] = 0.0;
-               }
-               if ( g ) {
-                       g = 1.0 / g;
-                       if ( i != n ) {
-                               for ( j = l; j <= n; j++ ) {
-                                       for ( s = 0.0,k = l; k <= m; k++ ) s += a[k][i] * a[k][j];
-                                       f = ( s / a[i][i] ) * g;
-                                       for ( k = i; k <= m; k++ ) a[k][j] += f * a[k][i];
-                               }
-                       }
-                       for ( j = i; j <= m; j++ ) a[j][i] *= g;
-               }
-               else {
-                       for ( j = i; j <= m; j++ ) a[j][i] = 0.0;
-               }
-               ++a[i][i];
-       }
-       for ( k = n; k >= 1; k-- ) {
-               for ( its = 1; its <= 30; its++ ) {
-                       flag = 1;
-                       for ( l = k; l >= 1; l-- ) {
-                               nm = l - 1;
-                               if ( fabs( rv1[l] ) + anorm == anorm ) {
-                                       flag = 0;
-                                       break;
-                               }
-                               if ( fabs( w[nm] ) + anorm == anorm ) {
-                                       break;
-                               }
-                       }
-                       if ( flag ) {
-                               c = 0.0;
-                               s = 1.0;
-                               for ( i = l; i <= k; i++ ) {
-                                       f = s * rv1[i];
-                                       if ( fabs( f ) + anorm != anorm ) {
-                                               g = w[i];
-                                               h = PYTHAG( f,g );
-                                               w[i] = h;
-                                               h = 1.0 / h;
-                                               c = g * h;
-                                               s = ( -f * h );
-                                               for ( j = 1; j <= m; j++ ) {
-                                                       y = a[j][nm];
-                                                       z = a[j][i];
-                                                       a[j][nm] = y * c + z * s;
-                                                       a[j][i] = z * c - y * s;
-                                               }
-                                       }
-                               }
-                       }
-                       z = w[k];
-                       if ( l == k ) {
-                               if ( z < 0.0 ) {
-                                       w[k] = -z;
-                                       for ( j = 1; j <= n; j++ ) v[j][k] = ( -v[j][k] );
-                               }
-                               break;
-                       }
-                       if ( its == 30 ) {
-                               ntrerror( "No convergence in 30 SVDCMP iterations" );
-                       }
-                       x = w[l];
-                       nm = k - 1;
-                       y = w[nm];
-                       g = rv1[nm];
-                       h = rv1[k];
-                       f = ( ( y - z ) * ( y + z ) + ( g - h ) * ( g + h ) ) / ( 2.0 * h * y );
-                       g = PYTHAG( f,1.0 );
-                       f = ( ( x - z ) * ( x + z ) + h * ( ( y / ( f + SIGN( g,f ) ) ) - h ) ) / x;
-                       c = s = 1.0;
-                       for ( j = l; j <= nm; j++ ) {
-                               i = j + 1;
-                               g = rv1[i];
-                               y = w[i];
-                               h = s * g;
-                               g = c * g;
-                               z = PYTHAG( f,h );
-                               rv1[j] = z;
-                               c = f / z;
-                               s = h / z;
-                               f = x * c + g * s;
-                               g = g * c - x * s;
-                               h = y * s;
-                               y = y * c;
-                               for ( jj = 1; jj <= n; jj++ ) {
-                                       x = v[jj][j];
-                                       z = v[jj][i];
-                                       v[jj][j] = x * c + z * s;
-                                       v[jj][i] = z * c - x * s;
-                               }
-                               z = PYTHAG( f,h );
-                               w[j] = z;
-                               if ( z ) {
-                                       z = 1.0 / z;
-                                       c = f * z;
-                                       s = h * z;
-                               }
-                               f = ( c * g ) + ( s * y );
-                               x = ( c * y ) - ( s * g );
-                               for ( jj = 1; jj <= m; jj++ ) {
-                                       y = a[jj][j];
-                                       z = a[jj][i];
-                                       a[jj][j] = y * c + z * s;
-                                       a[jj][i] = z * c - y * s;
-                               }
-                       }
-                       rv1[l] = 0.0;
-                       rv1[k] = f;
-                       w[k] = x;
-               }
-       }
-       freeVect( rv1 );
-}
-
-
-
-void svbksb( double** u, double* w, double** v,int m, int n, double* b, double* x ){
-       int jj,j,i;
-       double s,*tmp;
-       tmp = allocVect( n );
-       for ( j = 1; j <= n; j++ )
-       {
-               s = 0.0;
-               if ( w[j] ) {
-                       for ( i = 1; i <= m; i++ )
-                               s += u[i][j] * b[i];
-                       s /= w[j];
-               }
-               tmp[j] = s;
-       }
-       for ( j = 1; j <= n; j++ )
-       {
-               s = 0.0;
-               for ( jj = 1; jj <= n; jj++ )
-                       s += v[j][jj] * tmp[jj];
-               x[j] = s;
-       }
-       freeVect( tmp );
-}
-
-#undef SIGN
-#undef MAX
-#undef PYTHAG
-
-
-#if 1
-void DOsvd( float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize ){
-       int usedfs;
-       int *remap;
-       int i,j;
-       double **da;
-       double **v;
-       double *w;
-       int DOFerr;
-       float mx;
-       int bestat;
-
-       if ( nframes > framesize ) {
-               usedfs = nframes;
-       }
-       else{
-               usedfs = framesize;
-       }
-
-       da = allocMatrix( usedfs,nframes );
-       v = allocMatrix( nframes,nframes );
-       w = allocVect( nframes );
-
-       DOFerr = 0; //false
-       for ( i = 0; i < nframes; i++ )
-       {
-               for ( j = 0; j < framesize; j++ )
-                       da[j + 1][i + 1] = a[i * framesize + j];
-               for (; j < usedfs; j++ )
-                       da[j + 1][i + 1] = 0.0;
-       }
-
-       svdcmp( da,usedfs,nframes,w,v );
-
-       remap = calloc( sizeof( int ), (size_t)nframes );
-
-
-       for ( i = 0; i < nframes; i++ )
-               remap[i] = -1;
-       for ( j = 0; j < compressedsize; j++ )
-       {
-               mx = -1.0f;
-               for ( i = 0; i < nframes; i++ )
-               {
-                       if ( remap[i] < 0 && fabs( w[i + 1] ) > mx ) {
-                               mx = (float) fabs( w[i + 1] );
-                               bestat = i;
-                       }
-               }
-
-               if ( mx > 0 ) {
-                       remap[bestat] = j;
-               }
-               else
-               {
-                       DOFerr = 1; //true
-               }
-       }
-
-       if ( DOFerr ) {
-               printf( "Warning:  To many degrees of freedom!  File size may increase\n" );
-
-               for ( i = 0; i < compressedsize; i++ )
-               {
-                       values[i] = 0;
-                       for ( j = 0; j < framesize; j++ )
-                               res[i * framesize + j] = 0;
-               }
-       }
-
-       for ( i = 0; i < nframes; i++ )
-       {
-               if ( remap[i] < 0 ) {
-                       w[i + 1] = 0.0;
-               }
-               else
-               {
-                       values[remap[i]] = (float) w[i + 1];
-                       for ( j = 0; j < framesize; j++ )
-                               res[remap[i] * framesize + j] = (float) da[j + 1][i + 1];
-               }
-       }
-       freeVect( w );
-       freeMatrix( v,nframes );
-       freeMatrix( da,framesize );
-       free( remap );
-}
-
-#else
-
-void DOsvd( float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize ){
-       int *remap;
-       int i,j;
-       int nrows;
-       nrows = nframes;
-       if ( nrows < framesize ) {
-               nrows = framesize;
-       }
-       double **da = allocMatrix( nrows,framesize );
-       double **v = allocMatrix( framesize,framesize );
-       double *w = allocVect( framesize );
-       float mx;
-       int bestat;
-
-       for ( j = 0; j < framesize; j++ )
-       {
-               for ( i = 0; i < nframes; i++ )
-                       da[j + 1][i + 1] = a[i * framesize + j];
-               for (; i < nrows; i++ )
-                       da[j + 1][i + 1] = 0.0;
-       }
-
-       svdcmp( da,nrows,framesize,w,v );
-
-       remap = new int[framesize];
-
-
-       for ( i = 0; i < framesize; i++ )
-               remap[i] = -1;
-       for ( j = 0; j < compressedsize; j++ )
-       {
-               mx = -1.0f;
-               for ( i = 0; i < framesize; i++ )
-               {
-                       if ( remap[i] < 0 && fabs( w[i + 1] ) > mx ) {
-                               mx = fabs( w[i + 1] );
-                               bestat = i;
-                       }
-               }
-               assert( mx > -.5f );
-               remap[bestat] = j;
-       }
-       // josh **DO NOT** put your dof>nframes mod here
-       for ( i = 0; i < framesize; i++ )
-       {
-               if ( remap[i] < 0 ) {
-                       w[i + 1] = 0.0;
-               }
-               else
-               {
-                       values[remap[i]] = w[i + 1];
-                       for ( j = 0; j < framesize; j++ )
-                               res[remap[i] * framesize + j] = v[j + 1][i + 1];
-               }
-       }
-       freeVect( w );
-       freeMatrix( v,framesize );
-       freeMatrix( da,nrows );
-       delete[] remap;
-}
-
-#endif
-
-void DOsvdPlane( float *pnts,int npnts,float *n,float *base ){
-       int i,j;
-       double **da = allocMatrix( npnts,3 );
-       double **v = allocMatrix( 3,3 );
-       double *w = allocVect( 3 );
-       float mn = 1E30f;
-       int bestat;
-
-
-       assert( npnts >= 3 );
-       base[0] = pnts[0];
-       base[1] = pnts[1];
-       base[2] = pnts[2];
-       for ( i = 1; i < npnts; i++ )
-       {
-               for ( j = 0; j < 3; j++ )
-                       base[j] += pnts[i * 3 + j];
-       }
-       base[0] /= (float)( npnts );
-       base[1] /= (float)( npnts );
-       base[2] /= (float)( npnts );
-
-       for ( i = 0; i < 3; i++ )
-       {
-               for ( j = 0; j < npnts; j++ )
-                       da[j + 1][i + 1] = pnts[j * 3 + i] - base[i];
-       }
-
-       svdcmp( da,npnts,3,w,v );
-       for ( i = 0; i < 3; i++ )
-       {
-               if ( fabs( w[i + 1] ) < mn ) {
-                       mn = (float) fabs( w[i + 1] );
-                       bestat = i;
-               }
-       }
-       n[0] = (float) v[1][bestat + 1];
-       n[1] = (float) v[2][bestat + 1];
-       n[2] = (float) v[3][bestat + 1];
-       freeVect( w );
-       freeMatrix( v,3 );
-       freeMatrix( da,npnts );
-}
diff --git a/tools/quake2/qdata_heretic2/tables.c b/tools/quake2/qdata_heretic2/tables.c
deleted file mode 100644 (file)
index ad86c1e..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "qdata.h"
-
-/*
-   =============================================================================
-
-   ALPHALIGHT GENERATION
-
-   Find alphamap values that best match modulated lightmap values
-
-   This isn't used anymore, but I'm keeping it around...
-   =============================================================================
- */
-
-unsigned short alphamap[32 * 32 * 32];
-unsigned char inverse16to8table[65536];
-
-/*
-   static int FindNearestColor( unsigned int color )
-   {
-    int i;
-    int closest_so_far = 0;
-    float closest_distance_so_far = 100000000;
-    float d;
-    float r[2], g[2], b[2];
-
-    // incoming color is assumed to be in 0xRRGGBB format
-    r[0] = ( color & 31 ) << 3;
-    g[0] = ( ( color >> 5 ) & 63 ) << 2;
-    b[0] = ( ( color >> 11 ) & 31 ) << 3;
-
-    for ( i = 0; i < 256; i++ )
-    {
-        r[1] = ( d_8to24table[i] >> 0 ) & 0xFF;
-        g[1] = ( d_8to24table[i] >> 8 ) & 0xFF;
-        b[1] = ( d_8to24table[i] >> 16 ) & 0xFF;
-
-        d = ( r[1] - r[0] ) * ( r[1] - r[0] ) +
-            ( g[1] - g[0] ) * ( g[1] - g[0] ) +
-            ( b[1] - b[0] ) * ( b[1] - b[0] );
-
-        if ( d < closest_distance_so_far )
-        {
-            closest_distance_so_far = d;
-            closest_so_far = i;
-        }
-    }
-
-    return closest_so_far;
-   }
- */
-
-extern byte BestColor( int, int, int, int, int );
-
-void Inverse16_BuildTable( void ){
-       int i;
-
-       /*
-       ** create the 16-to-8 table
-       */
-       for ( i = 0; i < 65536; i++ )
-       {
-               int r = i & 31;
-               int g = ( i >> 5 ) & 63;
-               int b = ( i >> 11 ) & 31;
-
-               r <<= 3;
-               g <<= 2;
-               b <<= 3;
-
-               inverse16to8table[i] = BestColor( r, g, b, 0, 255 );
-       }
-}
-
-void Alphalight_Thread( int i ){
-       int j;
-       float r, g, b;
-       float mr, mg, mb, ma;
-       float distortion, bestdistortion;
-       float v;
-
-       r = ( i >> 10 ) * ( 1.0 / 16 );
-       g = ( ( i >> 5 ) & 31 )  * ( 1.0 / 16 );
-       b = ( i & 31 ) * ( 1.0 / 16 );
-
-       bestdistortion = 999999;
-       for ( j = 0 ; j < 16 * 16 * 16 * 16 ; j++ )
-       {
-               mr = ( j >> 12 ) * ( 1.0 / 16 );
-               mg = ( ( j >> 8 ) & 15 ) * ( 1.0 / 16 );
-               mb = ( ( j >> 4 ) & 15 ) * ( 1.0 / 16 );
-               ma = ( j & 15 ) * ( 1.0 / 16 );
-
-               v = r * 0.5 - ( mr * ma + 0.5 * ( 1.0 - ma ) );
-               distortion = v * v;
-               v = g * 0.5 - ( mg * ma + 0.5 * ( 1.0 - ma ) );
-               distortion += v * v;
-               v = b * 0.5 - ( mb * ma + 0.5 * ( 1.0 - ma ) );
-               distortion += v * v;
-
-               distortion *= 1.0 + ma * 4;
-
-               if ( distortion < bestdistortion ) {
-                       bestdistortion = distortion;
-                       alphamap[i] = j;
-               }
-       }
-}
-
-void Cmd_Alphalight( void ){
-       char savename[1024];
-
-       GetScriptToken( false );
-
-       if ( g_release ) {
-               ReleaseFile( token );
-               return;
-       }
-
-       sprintf( savename, "%s%s", gamedir, token );
-       printf( "Building alphalight table...\n" );
-
-       RunThreadsOnIndividual( 32 * 32 * 32, true, Alphalight_Thread );
-
-       SaveFile( savename, (byte *)alphamap, sizeof( alphamap ) );
-}
-
-
-void Cmd_Inverse16Table( void ){
-       char savename[1024];
-
-       if ( g_release ) {
-               sprintf( savename, "pics/16to8.dat" );
-               ReleaseFile( savename );
-               return;
-       }
-
-       sprintf( savename, "%spics/16to8.dat", gamedir );
-       printf( "Building inverse 16-to-8 table...\n" );
-
-       Inverse16_BuildTable();
-
-       SaveFile( savename, (byte *) inverse16to8table, sizeof( inverse16to8table ) );
-}
diff --git a/tools/quake2/qdata_heretic2/tmix.c b/tools/quake2/qdata_heretic2/tmix.c
deleted file mode 100644 (file)
index 936cd6e..0000000
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "qdata.h"
-#include "flex.h"
-
-#define     MAXFILES    2048
-
-#if !GDEF_OS_WINDOWS
-#define strlwr strlower
-#endif // !GDEF_OS_WINDOWS
-
-typedef struct
-{
-       int x;
-       int y;
-       int w;
-       int h;
-       int cw;
-       int ch;
-       int rw;
-       int index;
-       int depth;
-       int col;
-       int baseline;
-       char name[128];
-} Coords;
-
-int filenum;
-int valid;
-Coords in[MAXFILES];
-Coords out;
-char outscript[256];
-char sourcedir[256];
-char outusage[256];
-char root[32];
-
-int destsize = 0;
-byte            *pixels = NULL;             // Buffer to load image
-long            *outpixels = NULL;          // Buffer to store combined textures
-long            *usagemap = NULL;           // Buffer of usage map
-void            *bmptemp = NULL;            // Buffer of usage map
-byte            *map = NULL;
-
-int xcharsize;
-int ycharsize;
-int dosort = 0;
-int missed = 0;
-int overlap = 0;
-int nobaseline = 0;
-int percent;
-
-//////////////////////////////////////////////////
-// Setting the char based usage map                            //
-//////////////////////////////////////////////////
-
-byte    TryPlace( Coords *coord ){
-       int x, y;
-       byte entry = 0;
-       byte    *mapitem;
-
-       mapitem = map + ( coord->x / xcharsize ) + ( ( coord->y / ycharsize ) * out.cw );
-
-       for ( y = 0; y < coord->ch; y++, mapitem += out.cw - coord->cw )
-       {
-               for ( x = 0; x < coord->cw; x++ )
-               {
-                       if ( entry |= *mapitem++ & 8 ) {
-                               return( entry );
-                       }
-               }
-       }
-       return( entry );
-}
-
-void    SetMap( Coords *coord ){
-       int x, y;
-       byte    *mapitem;
-
-       mapitem = map + ( coord->x / xcharsize ) + ( ( coord->y / ycharsize ) * out.cw );
-
-       for ( y = 0; y < coord->ch; y++, mapitem += out.cw - coord->cw )
-               for ( x = 0; x < coord->cw; x++ )
-                       *mapitem++ |= 8;
-}
-
-//////////////////////////////////////////////////
-// Setting the pixel based usage map                   //
-//////////////////////////////////////////////////
-
-void    CheckOverlap( Coords *coord ){
-       int x;
-       int y;
-       long        *dest;
-
-       x = coord->x;
-       y = coord->y;
-
-       dest = (long *)( usagemap + x + ( y * out.w ) );
-
-       for ( y = 0; y < coord->h; y++, dest += out.w - coord->w )
-       {
-               for ( x = 0; x < coord->w; x++ )
-               {
-                       if ( *dest++ ) {
-                               overlap++;
-                               return;
-                       }
-               }
-       }
-}
-
-void    SetUsageMap( Coords *coord ){
-       int x;
-       int y;
-       long        *dest;
-
-       x = coord->x;
-       y = coord->y;
-
-       dest = (long *)( usagemap + x + ( y * out.w ) );
-
-       for ( y = 0; y < coord->h; y++, dest += out.w - coord->w )
-       {
-               for ( x = 0; x < coord->w; x++ )
-               {
-                       *dest++ = coord->col;
-               }
-       }
-}
-
-//////////////////////////////////////////////////
-// Flips the BMP image to the correct way up   //
-//////////////////////////////////////////////////
-
-void    CopyLine( byte *dest, byte *src, int size ){
-       int x;
-
-       for ( x = 0; x < size; x++ )
-               *dest++ = *src++;
-}
-
-/****************************************************/
-/* Printing headers etc                                                                */
-/****************************************************/
-
-void RemoveLeading( char *name ){
-       int i;
-       char temp[128];
-
-       for ( i = strlen( name ) - 1; i > 0; i-- )
-       {
-               if ( ( name[i] == '\\' ) || ( name[i] == '/' ) ) {
-                       strcpy( temp, name + i + 1 );
-                       strcpy( name, temp );
-                       return;
-               }
-       }
-}
-
-void RemoveExt( char *name ){
-       while ( ( *name != '.' ) && *name )
-               name++;
-       *name = 0;
-}
-
-/****************************************************/
-/* Misc calcualtions                                                           */
-/****************************************************/
-
-int TotalArea(){
-       int i;
-       int total = 0;
-
-       for ( i = 0; i < ( filenum + 2 ); i++ )
-               total += in[i].w * in[i].h;
-
-       return( total );
-}
-
-/****************************************************/
-/* Setup and checking of all info                                      */
-/****************************************************/
-
-void    InitVars(){
-       filenum = 0;
-       valid = 0;
-       dosort = 0;
-       missed = 0;
-       overlap = 0;
-       nobaseline = 0;
-
-       memset( outscript, 0, sizeof( outscript ) );
-       memset( outscript, 0, sizeof( sourcedir ) );
-       memset( outscript, 0, sizeof( outusage ) );
-       memset( outscript, 0, sizeof( root ) );
-
-       memset( in, 0, sizeof( in ) );
-       memset( &out, 0, sizeof( out ) );
-}
-void Cleanup(){
-       if ( pixels ) {
-               free( pixels );
-       }
-       if ( usagemap ) {
-               free( usagemap );
-       }
-       if ( outpixels ) {
-               free( outpixels );
-       }
-       if ( bmptemp ) {
-               free( bmptemp );
-       }
-       if ( map ) {
-               free( map );
-       }
-}
-
-typedef struct glxy_s
-{
-       float xl, yt, xr, yb;
-       int w, h, baseline;
-} glxy_t;
-
-int SaveScript( char *name ){
-       FILE        *fp;
-       int i, j;
-       glxy_t buff;
-
-       if ( fp = fopen( name, "wb" ) ) {
-               for ( j = 0; j < filenum; j++ )
-               {
-                       for ( i = 0; i < filenum; i++ )
-                       {
-                               if ( in[i].index == j ) {
-                                       if ( in[i].depth ) {
-                                               buff.xl = (float)in[i].x / (float)out.w;
-                                               buff.yt = (float)in[i].y / (float)out.h;
-                                               buff.xr = ( (float)in[i].w + (float)in[i].x ) / (float)out.w;
-                                               buff.yb = ( (float)in[i].h + (float)in[i].y ) / (float)out.h;
-                                               buff.w = in[i].w;
-                                               buff.h = in[i].h;
-                                               buff.baseline = in[i].baseline;
-                                       }
-                                       else
-                                       {
-                                               memset( &buff, 0, sizeof( glxy_t ) );
-                                       }
-                                       fwrite( &buff, 1, sizeof( glxy_t ), fp );
-                                       i = filenum;
-                               }
-                       }
-               }
-               fclose( fp );
-               return( true );
-       }
-       else{
-               return( false );
-       }
-}
-
-int     GetScriptInfo( char *name ){
-       FILE        *fp;
-       char buffer[256];
-       char tempbuff[256];
-       char delims[] = {" \t,\n"};
-
-       printf( "Opening script file %s.\n", name );
-
-       if ( fp = fopen( name, "r" ) ) {
-               while ( fgets( buffer, 256, fp ) )
-               {
-                       if ( strncmp( buffer, "//", 2 ) && strncmp( buffer, "\n", 1 ) ) {
-                               strupr( buffer );
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "OUTPUT" ) == 0 ) {
-                                       strcpy( out.name, strtok( NULL, delims ) );
-                                       strlwr( out.name );
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "SOURCEDIR" ) == 0 ) {
-                                       strcpy( tempbuff, strtok( NULL, delims ) );
-                                       strcpy( sourcedir, ExpandPathAndArchive( tempbuff ) );
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "DOSORT" ) == 0 ) {
-                                       dosort = 1;
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "XCHARSIZE" ) == 0 ) {
-                                       xcharsize = strtol( strtok( NULL, delims ), NULL, 0 );
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "YCHARSIZE" ) == 0 ) {
-                                       ycharsize = strtol( strtok( NULL, delims ), NULL, 0 );
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "OUTSCRIPT" ) == 0 ) {
-                                       strcpy( outscript, strtok( NULL, delims ) );
-                                       strlwr( outscript );
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "OUTUSAGE" ) == 0 ) {
-                                       strcpy( outusage, strtok( NULL, delims ) );
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "POS" ) == 0 ) {
-                                       out.w = strtol( strtok( NULL, delims ), NULL, 0 );
-                                       out.h = strtol( strtok( NULL, delims ), NULL, 0 );
-                               }
-
-                               strcpy( tempbuff, buffer );
-                               if ( strcmp( strtok( tempbuff, delims ), "FILE" ) == 0 ) {
-                                       strcpy( in[filenum].name, strtok( NULL, delims ) );
-                                       in[filenum].x = strtol( strtok( NULL, delims ), NULL, 0 );
-                                       in[filenum].y = strtol( strtok( NULL, delims ), NULL, 0 );
-                                       in[filenum].col = strtol( strtok( NULL, delims ), NULL, 0 );
-                                       filenum++;
-                               }
-                       }
-               }
-               fclose( fp );
-               return( true );
-       }
-       else
-       {
-               printf( "ERROR : Could not open script file.\n" );
-               return( false );
-       }
-}
-
-int CheckVars(){
-       int i;
-
-       if ( out.name[0] == 0 ) {
-               printf( "ERROR : No output name specified.\n" );
-               return( false );
-       }
-       if ( ( out.w <= 0 ) || ( out.h <= 0 ) ) {
-               printf( "ERROR : Invalid VRAM coordinates.\n" );
-               return( false );
-       }
-       if ( filenum == 0 ) {
-               printf( "ERROR : No input files specified.\n" );
-               return( false );
-       }
-       for ( i = 0; i < filenum; i++ )
-               if ( in[i].name[0] == 0 ) {
-                       printf( "ERROR : Input filename invalid.\n" );
-                       return( false );
-               }
-       return( true );
-}
-
-// Makes sure texture is totally within the output area
-
-int CheckCoords( Coords *coord ){
-       if ( ( coord->x + coord->w ) > out.w ) {
-               return( false );
-       }
-       if ( ( coord->y + coord->h ) > out.h ) {
-               return( false );
-       }
-
-       return( true );
-}
-// Gets the width, height, palette width and palette height of each BMP file
-
-int     GetFileDimensions(){
-       int i;
-       int width, height;
-       char name[128];
-
-       for ( i = 0; i < filenum; i++ )
-       {
-               in[i].index = i;
-
-               strcpy( name, sourcedir );
-               strcat( name, in[i].name );
-               printf( "Getting file dimensions, file : %s        \r", in[i].name );
-               if ( FileExists( name ) ) {
-                       LoadAnyImage( name, NULL, NULL, &width, &height );
-                       in[i].depth = 32;
-                       in[i].rw = width;
-                       in[i].w = width;                        // makes it width in
-                       in[i].h = height;
-                       in[i].cw = ( in[i].w + ( xcharsize - 1 ) ) / xcharsize;
-                       in[i].ch = ( in[i].h + ( ycharsize - 1 ) ) / ycharsize;
-
-                       if ( !CheckCoords( &in[i] ) && ( in[i].x >= 0 ) ) {
-                               printf( "Error : texture %s out of bounds.\n", in[i].name );
-                               return( false );
-                       }
-                       valid++;
-               }
-               else
-               {
-                       in[i].depth = 0;
-                       in[i].x = -1;
-                       in[i].y = -1;
-                       in[i].w = 0;
-                       in[i].h = 0;
-               }
-       }
-       printf( "\n\n" );
-       return( true );
-}
-
-// Sorts files into order for optimal space finding
-// Fixed position ones first, followed by the others in descending size
-// The theory being that it is easier to find space for smaller textures.
-// size = (width + height)
-// For space finding it is easier to place a 32x32 than a 128x2
-
-#define WEIGHT  0x8000
-
-void    Swap( Coords *a, Coords *b ){
-       Coords c;
-
-       c = *a;
-       *a = *b;
-       *b = c;
-}
-
-void    SortInNames(){
-       int i, j;
-       int largest, largcount;
-       int size;
-
-       printf( "Sorting filenames by size.\n\n" );
-
-       for ( j = 0; j < filenum; j++ )
-       {
-               largest = -1;
-               largcount = -1;
-
-               for ( i = j; i < filenum; i++ )
-               {
-                       if ( in[i].depth ) {
-                               size = in[i].w + in[i].h;
-
-                               if ( ( in[i].x < 0 ) && ( size > largest ) ) {
-                                       largcount = i;
-                                       largest = size;
-                               }
-                       }
-               }
-               if ( ( largcount >= 0 ) && ( largcount != j ) ) {
-                       Swap( &in[j], &in[largcount] );
-               }
-       }
-}
-
-int SetVars( char *name ){
-       if ( !GetScriptInfo( name ) ) {
-               return( false );
-       }
-
-       if ( !CheckVars() ) {
-               return( false );
-       }
-
-       destsize = out.w * out.h;
-
-       out.cw = out.w / xcharsize;
-       out.ch = out.h / ycharsize;
-
-       if ( ( usagemap = (long *)SafeMalloc( destsize * 4, "" ) ) == NULL ) {
-               return( false );
-       }
-       if ( ( outpixels = (long *)SafeMalloc( destsize * 4, "" ) ) == NULL ) {
-               return( false );
-       }
-       if ( ( bmptemp = (void *)SafeMalloc( destsize * 4, "" ) ) == NULL ) {
-               return( false );
-       }
-       if ( ( map = (byte *)SafeMalloc( destsize / ( xcharsize * ycharsize ), "" ) ) == NULL ) {
-               return( false );
-       }
-
-       if ( GetFileDimensions() == false ) {
-               return( false );
-       }
-
-       if ( dosort ) {
-               SortInNames();
-       }
-
-       return( true );
-}
-/****************************************************/
-/* Actual copying routines                                                     */
-/****************************************************/
-
-int FindCoords( Coords *coord ){
-       int tx, ty;
-
-       if ( coord->x >= 0 ) {
-               SetMap( coord );
-               return( true );
-       }
-       else
-       {
-               for ( ty = 0; ty < out.ch; ty++ )
-               {
-                       for ( tx = 0; tx < out.cw; tx++ )
-                       {
-                               coord->x = ( tx * xcharsize );
-                               coord->y = ( ty * ycharsize );
-
-                               if ( CheckCoords( coord ) && !TryPlace( coord ) ) {
-                                       SetMap( coord );
-                                       return( true );
-                               }
-                       }
-               }
-       }
-       coord->x = -1;
-       coord->y = -1;
-
-       return( false );
-}
-
-void CheckBaseline( int i ){
-       int y;
-       long    *pix;
-
-       in[i].baseline = -1;
-       pix = (long *)pixels;
-
-       for ( y = 0; y < in[i].h; y++, pix += in[i].w )
-       {
-               if ( ( *pix & 0x00ffffff ) == 0x00ff00ff ) {
-                       in[i].baseline = y;
-                       break;
-               }
-       }
-       pix = (long *)pixels;
-       for ( y = 0; y < in[i].w * in[i].h; y++, pix++ )
-       {
-               if ( ( *pix & 0x00ffffff ) == 0x00ff00ff ) {
-                       *pix = 0;
-               }
-       }
-
-       if ( in[i].baseline == -1 ) {
-               printf( "\nERROR : %s has no baseline\n", in[i].name );
-               nobaseline++;
-       }
-}
-
-void    CopyToMain32( Coords *coord ){
-       int x;
-       int y;
-       long        *source;
-       long        *dest;
-
-       x = coord->x;
-       y = coord->y;
-
-       source = (long *)pixels;
-       dest = (long *)( outpixels + x + ( y * out.w ) );
-
-       for ( y = 0; y < coord->h; y++, dest += out.w - coord->w )
-       {
-               for ( x = 0; x < coord->w; x++ )
-               {
-                       *dest++ = *source++;
-               }
-       }
-}
-
-void CreateMain(){
-       int i, count;
-       int width, height;
-       char name[128];
-
-       for ( i = 0, count = 0; i < filenum; i++ )
-       {
-               if ( in[i].depth ) {
-                       printf( "\rProcessing %d of %d (%d missed, %d overlapping, %d nobase)\r", count + 1, valid, missed, overlap, nobaseline );
-                       count++;
-                       if ( !FindCoords( &in[i] ) ) {
-                               missed++;
-                       }
-                       else
-                       {
-                               strcpy( name, sourcedir );
-                               strcat( name, in[i].name );
-                               LoadAnyImage( name, &pixels, NULL, &width, &height );
-                               CheckBaseline( i );
-                               CheckOverlap( &in[i] );
-                               CopyToMain32( &in[i] );
-                               SetUsageMap( &in[i] );
-                       }
-               }
-       }
-}
-
-void Cmd_TextureMix(){
-       miptex32_t      *qtex32;
-       char filename[1024];
-       int size;
-
-       InitVars();
-
-       GetScriptToken( false );
-
-       strcpy( root, token );
-       RemoveExt( root );
-       RemoveLeading( root );
-
-       strcpy( filename, ExpandPathAndArchive( token ) );
-       if ( SetVars( filename ) ) {
-               // Create combined texture
-               percent = ( ( TotalArea() * 100 ) / ( out.w * out.h ) );
-               printf( "Total area consumed : %d%%\n", percent );
-               printf( "Texture resolution  : %dx%d pixels.\n", xcharsize, ycharsize );
-               CreateMain();
-
-               // Save image as m32
-               sprintf( filename, "%spics/misc/%s.m32", gamedir, out.name );
-               qtex32 = CreateMip32( (unsigned *)outpixels, out.w, out.h, &size, false );
-
-               qtex32->contents = 0;
-               qtex32->value = 0;
-               qtex32->scale_x = 1.0;
-               qtex32->scale_y = 1.0;
-               sprintf( qtex32->name, "misc/%s", out.name );
-
-               printf( "\n\nwriting %s\n", filename );
-               SaveFile( filename, (byte *)qtex32, size );
-               free( qtex32 );
-
-               // Save out script file
-               sprintf( filename, "%spics/misc/%s.fnt", gamedir, outscript );
-               printf( "Writing %s as script file\n", filename );
-               if ( !SaveScript( filename ) ) {
-                       printf( "Unable to save output script.\n" );
-               }
-       }
-       printf( "Everythings groovy.\n" );
-       Cleanup();
-}
-
-// end
diff --git a/tools/quake2/qdata_heretic2/video.c b/tools/quake2/qdata_heretic2/video.c
deleted file mode 100644 (file)
index 51bf462..0000000
+++ /dev/null
@@ -1,1154 +0,0 @@
-/*
-   Copyright (C) 1999-2007 id Software, Inc. and contributors.
-   For a list of contributors, see the accompanying CONTRIBUTORS file.
-
-   This file is part of GtkRadiant.
-
-   GtkRadiant 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.
-
-   GtkRadiant 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 GtkRadiant; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-// To do
-
-// Sound error handling (when sound too short)
-// rle b4 huffing
-// adpcm encoding of sound
-
-#if 0
-#include "qdata.h"
-#include "flex.h"
-#include "fc.h"
-#include "adpcm.h"
-
-#define MIN_REPT    15
-#define MAX_REPT    0
-#define HUF_TOKENS  ( 256 + MAX_REPT )
-
-#define BLOCKSIZE   8
-
-#define M_PI        3.14159265358979323846  // matches value in gcc v2 math.h
-#define SQRT2       1.414213562
-
-typedef struct hnode_s
-{
-       int count;
-       qboolean used;
-       int children[2];
-} hnode_t;
-
-typedef struct
-{
-       int rate;
-       int width;
-       int channels;
-       int loopstart;
-       int samples;
-       int dataofs;                // chunk starts this many bytes from file start
-} wavinfo_t;
-
-// These weren`t picked out my ass....
-// They were defined at http://www.rahul.net/jfm/dct.html
-// However, I think he plucked them out of his ass.....
-
-float Quantise[BLOCKSIZE * BLOCKSIZE];
-
-float LUT_Quantise[BLOCKSIZE * BLOCKSIZE] =
-{
-       16.0F / 16.0F, 11.0F / 16.0F, 10.0F / 16.0F, 16.0F / 16.0F, 24.0F / 16.0F, 40.0F / 16.0F, 51.0F / 16.0F, 61.0F / 16.0F,
-       12.0F / 16.0F, 13.0F / 16.0F, 14.0F / 16.0F, 19.0F / 16.0F, 26.0F / 16.0F, 58.0F / 16.0F, 60.0F / 16.0F, 55.0F / 16.0F,
-       14.0F / 16.0F, 13.0F / 16.0F, 16.0F / 16.0F, 24.0F / 16.0F, 40.0F / 16.0F, 57.0F / 16.0F, 69.0F / 16.0F, 56.0F / 16.0F,
-       14.0F / 16.0F, 17.0F / 16.0F, 22.0F / 16.0F, 29.0F / 16.0F, 51.0F / 16.0F, 87.0F / 16.0F, 80.0F / 16.0F, 62.0F / 16.0F,
-       18.0F / 16.0F, 22.0F / 16.0F, 37.0F / 16.0F, 56.0F / 16.0F, 68.0F / 16.0F,109.0F / 16.0F,103.0F / 16.0F, 77.0F / 16.0F,
-       24.0F / 16.0F, 35.0F / 16.0F, 55.0F / 16.0F, 64.0F / 16.0F, 81.0F / 16.0F,104.0F / 16.0F,113.0F / 16.0F, 92.0F / 16.0F,
-       49.0F / 16.0F, 64.0F / 16.0F, 78.0F / 16.0F, 87.0F / 16.0F,103.0F / 16.0F,121.0F / 16.0F,120.0F / 16.0F,101.0F / 16.0F,
-       72.0F / 16.0F, 92.0F / 16.0F, 95.0F / 16.0F, 98.0F / 16.0F,112.0F / 16.0F,100.0F / 16.0F,103.0F / 16.0F, 99.0F / 16.0F
-};
-
-int LUT_ZZ[BLOCKSIZE * BLOCKSIZE] =
-{
-       0,
-       1,  8,
-       16,  9,  2,
-       3, 10, 17, 24,
-       32, 25, 18, 11,  4,
-       5, 12, 19, 26, 33, 40,
-       48, 41, 34, 27, 20, 13, 6,
-       7, 14, 21, 28, 35, 42, 49, 56,
-       57, 50, 43, 36, 29, 22, 15,
-       23, 30, 37, 44, 51, 58,
-       59, 52, 45, 38, 31,
-       39, 46, 53, 60,
-       61, 54, 47,
-       55, 62,
-       63
-};
-
-char base[32];
-
-byte            *soundtrack;
-
-byte scaled[256][HUF_TOKENS];
-unsigned int charbits1[256][HUF_TOKENS];
-int charbitscount1[256][HUF_TOKENS];
-hnode_t hnodes1[256][HUF_TOKENS * 2];
-int numhnodes1[256];
-int order0counts[256];
-int numhnodes;
-hnode_t hnodes[512];
-unsigned charbits[256];
-int charbitscount[256];
-
-CineHead_t cinehead;
-
-byte            *data_p;
-byte            *iff_end;
-byte            *last_chunk;
-byte            *iff_data;
-int iff_chunk_len;
-
-float dctbase[BLOCKSIZE][BLOCKSIZE];
-float red[BLOCKSIZE * BLOCKSIZE];
-float green[BLOCKSIZE * BLOCKSIZE];
-float blue[BLOCKSIZE * BLOCKSIZE];
-float temp[BLOCKSIZE * BLOCKSIZE];
-
-wavinfo_t wavinfo;
-adpcm_t adpcm;
-
-/*
-   ===============================================================================
-
-   WAV loading
-
-   ===============================================================================
- */
-
-/* Intel ADPCM step variation table */
-static int indexTable[16] =
-{
-       -1, -1, -1, -1, 2, 4, 6, 8,
-       -1, -1, -1, -1, 2, 4, 6, 8,
-};
-
-static int stepsizeTable[89] =
-{
-       7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
-       19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
-       50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
-       130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
-       337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
-       876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
-       2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
-       5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
-       15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
-#if 0
-static void adpcm_decoder( char *indata, short *outdata, int len, adpcm_state_t *state ){
-       signed char *inp;       /* Input buffer pointer */
-       short *outp;        /* output buffer pointer */
-       int sign;           /* Current adpcm sign bit */
-       int delta;          /* Current adpcm output value */
-       int step;           /* Stepsize */
-       int valpred;        /* Predicted value */
-       int vpdiff;         /* Current change to valpred */
-       int index;          /* Current step change index */
-       int inputbuffer;        /* place to keep next 4-bit value */
-       int bufferstep;     /* toggle between inputbuffer/input */
-
-       outp = outdata;
-       inp = (signed char *)indata;
-
-       valpred = state->valprev;
-       index = state->index;
-       step = stepsizeTable[index];
-
-       bufferstep = 0;
-
-       for (; len > 0; len-- )
-       {
-               /* Step 1 - get the delta value */
-               if ( bufferstep ) {
-                       delta = inputbuffer & 0xf;
-               }
-               else
-               {
-                       inputbuffer = *inp++;
-                       delta = ( inputbuffer >> 4 ) & 0xf;
-               }
-               bufferstep = !bufferstep;
-
-               /* Step 2 - Find new index value (for later) */
-               index += indexTable[delta];
-               if ( index < 0 ) {
-                       index = 0;
-               }
-               if ( index > 88 ) {
-                       index = 88;
-               }
-
-               /* Step 3 - Separate sign and magnitude */
-               sign = delta & 8;
-               delta = delta & 7;
-
-               /* Step 4 - Compute difference and new predicted value */
-               /*
-               ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
-               ** in adpcm_coder.
-               */
-               vpdiff = step >> 3;
-               if ( delta & 4 ) {
-                       vpdiff += step;
-               }
-               if ( delta & 2 ) {
-                       vpdiff += step >> 1;
-               }
-               if ( delta & 1 ) {
-                       vpdiff += step >> 2;
-               }
-
-               if ( sign ) {
-                       valpred -= vpdiff;
-               }
-               else{
-                       valpred += vpdiff;
-               }
-
-               /* Step 5 - clamp output value */
-               if ( valpred > 32767 ) {
-                       valpred = 32767;
-               }
-               else if ( valpred < -32768 ) {
-                       valpred = -32768;
-               }
-
-               /* Step 6 - Update step value */
-               step = stepsizeTable[index];
-
-               /* Step 7 - Output value */
-               *outp++ = valpred;
-       }
-
-       state->valprev = valpred;
-       state->index = index;
-}
-#endif
-
-void adpcm_coder( short *inp, adpcm_t *adpcm ){
-       int val;                        /* Current input sample value */
-       int sign;                       /* Current adpcm sign bit */
-       int delta;                      /* Current adpcm output value */
-       int diff;                       /* Difference between val and valprev */
-       int step;                       /* Stepsize */
-       int valpred;                    /* Predicted output value */
-       int vpdiff;                     /* Current change to valpred */
-       int index;                      /* Current step change index */
-       int outputbuffer;               /* place to keep previous 4-bit value */
-       int bufferstep;                 /* toggle between outputbuffer/output */
-       adpcm_state_t   *state;
-       char            *outp;
-       int len;
-
-       state = &adpcm->state;
-       len = state->count;
-       outp = adpcm->adpcm;
-
-       valpred = state->in_valprev;
-       index = state->in_index;
-       step = stepsizeTable[index];
-
-       bufferstep = 1;
-       while ( len-- )
-       {
-               val = *inp++;
-
-               /* Step 1 - compute difference with previous value */
-               diff = val - valpred;
-               sign = ( diff < 0 ) ? 8 : 0;
-               if ( sign ) {
-                       diff = -diff;
-               }
-
-               /* Step 2 - Divide and clamp */
-               /* Note:
-               ** This code *approximately* computes:
-               **        delta = diff*4/step;
-               **        vpdiff = (delta+0.5)*step/4;
-               ** but in shift step bits are dropped. The net result of this is
-               ** that even if you have fast mul/div hardware you cannot put it to
-               ** good use since the fixup would be too expensive.
-               */
-               delta = 0;
-               vpdiff = ( step >> 3 );
-
-               if ( diff >= step ) {
-                       delta = 4;
-                       diff -= step;
-                       vpdiff += step;
-               }
-               step >>= 1;
-               if ( diff >= step ) {
-                       delta |= 2;
-                       diff -= step;
-                       vpdiff += step;
-               }
-               step >>= 1;
-               if ( diff >= step ) {
-                       delta |= 1;
-                       vpdiff += step;
-               }
-
-               /* Step 3 - Update previous value */
-               if ( sign ) {
-                       valpred -= vpdiff;
-               }
-               else{
-                       valpred += vpdiff;
-               }
-
-               /* Step 4 - Clamp previous value to 16 bits */
-               if ( valpred > 32767 ) {
-                       valpred = 32767;
-               }
-               else if ( valpred < -32768 ) {
-                       valpred = -32768;
-               }
-
-               /* Step 5 - Assemble value, update index and step values */
-               delta |= sign;
-
-               index += indexTable[delta];
-               if ( index < 0 ) {
-                       index = 0;
-               }
-               if ( index > 88 ) {
-                       index = 88;
-               }
-               step = stepsizeTable[index];
-
-               /* Step 6 - Output value */
-               if ( bufferstep ) {
-                       outputbuffer = ( delta << 4 ) & 0xf0;
-               }
-               else{
-                       *outp++ = ( delta & 0x0f ) | outputbuffer;
-               }
-
-               bufferstep = !bufferstep;
-       }
-
-       /* Output last step, if needed */
-       if ( !bufferstep ) {
-               *outp++ = outputbuffer;
-       }
-
-       state->out_valprev = valpred;
-       state->out_index = index;
-}
-
-void FindNextChunk( char *name ){
-       while ( 1 )
-       {
-               data_p = last_chunk;
-
-               if ( data_p >= iff_end ) {         // didn't find the chunk
-                       data_p = NULL;
-                       return;
-               }
-
-               data_p += 4;
-               iff_chunk_len = *(long *)data_p;
-               data_p += 4;
-               if ( iff_chunk_len < 0 ) {
-                       data_p = NULL;
-                       return;
-               }
-
-               data_p -= 8;
-               last_chunk = data_p + 8 + ( ( iff_chunk_len + 1 ) & ~1 );
-               if ( !strncmp( data_p, name, 4 ) ) {
-                       return;
-               }
-       }
-}
-
-void FindChunk( char *name ){
-       last_chunk = iff_data;
-       FindNextChunk( name );
-}
-
-void DumpChunks( void ){
-       char str[5];
-
-       str[4] = 0;
-       data_p = iff_data;
-       do
-       {
-               memcpy( str, data_p, 4 );
-               data_p += 4;
-               iff_chunk_len = *(long *)data_p;
-               data_p += 4;
-               printf( "0x%x : %s (%d)\n", (int)( data_p - 4 ), str, iff_chunk_len );
-               data_p += ( iff_chunk_len + 1 ) & ~1;
-       }
-       while ( data_p < iff_end );
-}
-
-/*
-   ============
-   GetWavinfo
-   ============
- */
-wavinfo_t GetWavinfo( char *name, byte *wav, int wavlength ){
-       wavinfo_t info;
-       int i;
-       int format;
-       int samples;
-
-       memset( &info, 0, sizeof( info ) );
-
-       if ( !wav ) {
-               return( info );
-       }
-
-       iff_data = wav;
-       iff_end = wav + wavlength;
-
-// find "RIFF" chunk
-       FindChunk( "RIFF" );
-       if ( !( data_p && !strncmp( data_p + 8, "WAVE", 4 ) ) ) {
-               printf( "Missing RIFF/WAVE chunks\n" );
-               return( info );
-       }
-
-// get "fmt " chunk
-       iff_data = data_p + 12;
-
-       FindChunk( "fmt " );
-       if ( !data_p ) {
-               printf( "Missing fmt chunk\n" );
-               return( info );
-       }
-       data_p += 8;
-       format = *(short *)data_p;
-       data_p += 2;
-       if ( format != 1 ) {
-               printf( "Microsoft PCM format only\n" );
-               return( info );
-       }
-
-       info.channels = *(short *)data_p;
-       data_p += 2;
-       info.rate = *(long *)data_p;
-       data_p += 4;
-       data_p += 6;
-       info.width = *(short *)data_p / 8;
-       data_p += 2;
-
-// get cue chunk
-       FindChunk( "cue " );
-       if ( data_p ) {
-               data_p += 32;
-               info.loopstart = *(long *)data_p;
-               data_p += 4;
-
-// if the next chunk is a LIST chunk, look for a cue length marker
-               FindNextChunk( "LIST" );
-               if ( data_p ) {
-// this is not a proper parse, but it works with cooledit...
-                       if ( !strncmp( data_p + 28, "mark", 4 ) ) {
-                               data_p += 24;
-                               i = *(long *)data_p;                    // samples in loop
-                               data_p += 4;
-                               info.samples = info.loopstart + i;
-                       }
-               }
-       }
-       else{
-               info.loopstart = -1;
-       }
-
-// find data chunk
-       FindChunk( "data" );
-       if ( !data_p ) {
-               printf( "Missing data chunk\n" );
-               return( info );
-       }
-
-       data_p += 4;
-       samples = *(long *)data_p;
-       data_p += 4;
-
-       if ( info.samples ) {
-               if ( samples < info.samples ) {
-                       Error( "Sound %s has a bad loop length", name );
-               }
-       }
-       else{
-               info.samples = samples;
-       }
-
-       info.dataofs = data_p - wav;
-       return( info );
-}
-
-// ==============
-// LoadSoundtrack
-// ==============
-
-void LoadSoundtrack(){
-       char name[1024];
-       FILE    *f;
-       int len;
-
-       soundtrack = NULL;
-       sprintf( name, "%svideo/%s/%s.wav", gamedir, base, base );
-       printf( "\nLoading sound    : %s\n", name );
-       f = fopen( name, "rb" );
-       if ( !f ) {
-               printf( "\nNo soundtrack for %s\n", base );
-               return;
-       }
-       len = Q_filelength( f );
-       soundtrack = SafeMalloc( len, "LoadSoundtrack" );
-       fread( soundtrack, 1, len, f );
-       fclose( f );
-
-       wavinfo = GetWavinfo( name, soundtrack, len );
-       adpcm.state.out_valprev = 0;
-       adpcm.state.out_index = 0;
-}
-
-// ==================
-// WriteSound
-// ==================
-
-int WriteSound( FILE *output, int frame, int numframes ){
-       int start, end;
-       int count;
-       int empty = 0;
-       int width;
-       char    *work;
-
-       width = wavinfo.width * wavinfo.channels;
-       start = ( ( frame * wavinfo.rate / 14 ) + 31 ) & 0xffffffe0;                // start sample
-       end = ( ( ( frame + numframes ) * wavinfo.rate / 14 ) + 31 ) & 0xffffffe0;    // end sample
-       count = end - start;
-
-       work = soundtrack + wavinfo.dataofs + ( start * width );
-       adpcm.state.count = count * wavinfo.channels;           // Number of samples
-       adpcm.state.in_valprev = adpcm.state.out_valprev;
-       adpcm.state.in_index = adpcm.state.out_index;
-       adpcm_coder( (short *)work, &adpcm );
-       WriteHeader( output, FC_SOUND_22KMADPCM, FC_ADPCM_VERSION, ( adpcm.state.count / 2 ) + sizeof( adpcm_state_t ), (char *)&adpcm );
-       return( count / 2 );
-}
-// ==============================
-// Basic run length encoder
-// ==============================
-
-char *RLEZZ( char *in, char *out ){
-       int srun;
-       char count;
-       int idx = 0;
-
-       while ( idx < 64 )
-       {
-               srun = idx;                             // Start of run
-
-               while ( idx < 63 )
-               {
-                       if ( in[LUT_ZZ[idx]] != in[LUT_ZZ[idx + 1]] ) {
-                               break;
-                       }
-                       idx++;
-               }
-               count = (char)( idx - srun );             // count of repeated bytes
-
-               if ( !count ) {
-                       while ( idx < 63 )
-                       {
-                               if ( in[LUT_ZZ[idx]] == in[LUT_ZZ[idx + 1]] ) {
-                                       break;
-                               }
-                               idx++;
-                       }
-                       if ( idx == 63 ) {
-                               idx++;
-                       }
-
-                       count = (char)( idx - srun );         // count of unique bytes
-                       *out++ = count;
-                       while ( count-- )
-                               *out++ = in[LUT_ZZ[srun++]];
-               }
-               else
-               {
-                       *out++ = -( count + 1 );
-                       *out++ = in[LUT_ZZ[idx]];
-                       idx++;
-               }
-       }
-       return( out );
-}
-
-// ==============================
-// Discrete Cosine Transformation
-// ==============================
-
-void init_base( float quant ){
-       int y, x;
-
-       for ( y = 0; y < BLOCKSIZE; y++ )
-               for ( x = 0; x < BLOCKSIZE; x++ )
-               {
-                       if ( y == 0 ) {
-                               dctbase[y][x] = 1;
-                       }
-                       else{
-                               dctbase[y][x] = SQRT2 * cos( ( ( x * 2 + 1 ) * y * M_PI ) / ( BLOCKSIZE * 2 ) );
-                       }
-               }
-
-       for ( y = 0; y < BLOCKSIZE * BLOCKSIZE; y++ )
-               Quantise[y] = LUT_Quantise[y] / quant;
-}
-
-void SplitComponents( byte *src, int width, int height ){
-       int i, j;
-       float   *tr = red;
-       float   *tg = green;
-       float   *tb = blue;
-
-       for ( i = 0; i < BLOCKSIZE; i++, src += ( width - BLOCKSIZE ) * 4 )
-               for ( j = 0; j < BLOCKSIZE; j++ )
-               {
-                       *tr++ = ( (float)*src++ ) - 128.0F;
-                       *tg++ = ( (float)*src++ ) - 128.0F;
-                       *tb++ = ( (float)*src++ ) - 128.0F;
-                       src++;
-               }
-}
-
-void transferH( float *src, float *dst ){
-       int y, dx, dy;
-       float sum;
-       float   *work;
-
-       for ( y = 0; y < BLOCKSIZE; y++, src += BLOCKSIZE )
-       {
-               for ( dy = 0; dy < BLOCKSIZE; dy++ )
-               {
-                       sum = 0;
-                       work = src;
-                       for ( dx = 0; dx < BLOCKSIZE; dx++, work++ )
-                               sum += dctbase[dy][dx] * *work;
-
-                       *dst++ = sum / BLOCKSIZE;
-               }
-       }
-}
-
-void transferV( float *src, float *dst ){
-       int x, dy, fy;
-       float sum;
-       float   *work;
-
-       for ( x = 0; x < BLOCKSIZE; x++, src++, dst++ )
-       {
-               for ( fy = 0; fy < BLOCKSIZE; fy++ )
-               {
-                       sum = 0;
-                       work = src;
-                       for ( dy = 0; dy < BLOCKSIZE; dy++, work += BLOCKSIZE )
-                               sum += dctbase[fy][dy] * *work;
-
-                       dst[fy * BLOCKSIZE] = sum / BLOCKSIZE;
-               }
-       }
-}
-
-char *Combine( byte *dst, float *p, float *q ){
-       int i, j;
-       byte rlesrc[BLOCKSIZE * BLOCKSIZE];
-       int c;
-       byte    *work;
-
-       work = rlesrc;
-       for ( j = 0; j < BLOCKSIZE; j++ )
-               for ( i = 0; i < BLOCKSIZE; i++ )
-               {
-                       c = (int)( ( *p++ / *q++ ) + 128.5F );
-                       c -= 128;
-
-                       if ( c < -128 ) {
-                               c = -128;
-                       }
-                       if ( c > 127 ) {
-                               c = 127;
-                       }
-
-                       *work++ = (char)c;
-               }
-
-       dst = RLEZZ( rlesrc, dst );
-       return( dst );
-}
-
-char *CombineComponents( char *dst, int width, int height ){
-       dst = Combine( dst, red, Quantise );
-       dst = Combine( dst, green, Quantise );
-       dst = Combine( dst, blue, Quantise );
-       return( dst );
-}
-
-void DCT( cblock_t *out, cblock_t in, int width, int height ){
-       int x, y;
-       char    *cursrc;
-       char    *curdst;
-
-       curdst = out->data;
-       for ( y = 0; y < height; y += BLOCKSIZE )
-               for ( x = 0; x < width; x += BLOCKSIZE )
-               {
-                       cursrc = in.data + ( ( y * width ) + x ) * 4;
-                       SplitComponents( cursrc, width, height );
-                       transferH( red, temp );
-                       transferV( temp, red );
-                       transferH( green, temp );
-                       transferV( temp, green );
-                       transferH( blue, temp );
-                       transferV( temp, blue );
-                       curdst = CombineComponents( curdst, width, height );
-               }
-       out->count = curdst - out->data;
-}
-
-// ==================
-// BuildChars1
-// ==================
-
-void BuildChars1( int prev, int nodenum, unsigned bits, int bitcount ){
-       hnode_t     *node;
-
-       if ( nodenum < HUF_TOKENS ) {
-               if ( bitcount > 32 ) {
-                       Error( "bitcount > 32" );
-               }
-               charbits1[prev][nodenum] = bits;
-               charbitscount1[prev][nodenum] = bitcount;
-               return;
-       }
-
-       node = &hnodes1[prev][nodenum];
-       bits <<= 1;
-       BuildChars1( prev, node->children[0], bits, bitcount + 1 );
-       bits |= 1;
-       BuildChars1( prev, node->children[1], bits, bitcount + 1 );
-}
-
-// ==================
-// SmallestNode1
-// ==================
-
-int SmallestNode1( hnode_t *hnodes, int numhnodes ){
-       int i;
-       int best, bestnode;
-
-       best = 99999999;
-       bestnode = -1;
-       for ( i = 0; i < numhnodes; i++ )
-       {
-               if ( hnodes[i].used ) {
-                       continue;
-               }
-               if ( !hnodes[i].count ) {
-                       continue;
-               }
-               if ( hnodes[i].count < best ) {
-                       best = hnodes[i].count;
-                       bestnode = i;
-               }
-       }
-
-       if ( bestnode == -1 ) {
-               return( -1 );
-       }
-
-       hnodes[bestnode].used = true;
-       return( bestnode );
-}
-
-// ==================
-// BuildTree1
-// ==================
-
-void BuildTree1( int prev ){
-       hnode_t     *node, *nodebase;
-       int numhnodes;
-
-       // build the nodes
-       numhnodes = HUF_TOKENS;
-       nodebase = hnodes1[prev];
-       while ( 1 )
-       {
-               node = &nodebase[numhnodes];
-
-               // pick two lowest counts
-               node->children[0] = SmallestNode1( nodebase, numhnodes );
-               if ( node->children[0] == -1 ) {
-                       break;  // no more
-
-               }
-               node->children[1] = SmallestNode1( nodebase, numhnodes );
-               if ( node->children[1] == -1 ) {
-                       break;
-               }
-
-               node->count = nodebase[node->children[0]].count +
-                                         nodebase[node->children[1]].count;
-               numhnodes++;
-       }
-       numhnodes1[prev] = numhnodes - 1;
-       BuildChars1( prev, numhnodes - 1, 0, 0 );
-}
-
-// ==================
-// Huffman1_Count
-// ==================
-
-void Huffman1_Count( cblock_t in ){
-       int i;
-       int prev;
-       int v;
-       int rept;
-
-       prev = 0;
-       for ( i = 0; i < in.count; i++ )
-       {
-               v = in.data[i];
-               order0counts[v]++;
-               hnodes1[prev][v].count++;
-               prev = v;
-
-               for ( rept = 1; ( i + rept < in.count ) && ( rept < MAX_REPT ); rept++ )
-                       if ( in.data[i + rept] != v ) {
-                               break;
-                       }
-               if ( rept > MIN_REPT ) {
-                       hnodes1[prev][255 + rept].count++;
-                       i += rept - 1;
-               }
-       }
-}
-
-// ==================
-// Huffman1_Build
-// ==================
-
-void Huffman1_Build(){
-       int i, j, v;
-       int max;
-       int total;
-
-       for ( i = 0; i < 256; i++ )
-       {
-// normalize and save the counts
-               max = 0;
-               for ( j = 0; j < HUF_TOKENS; j++ )
-               {
-                       if ( hnodes1[i][j].count > max ) {
-                               max = hnodes1[i][j].count;
-                       }
-               }
-               if ( max == 0 ) {
-                       max = 1;
-               }
-               total = 0;
-// easy to overflow 32 bits here!
-               for ( j = 0; j < HUF_TOKENS; j++ )
-               {
-                       v = ( hnodes1[i][j].count * (double) 255 + max - 1 ) / max;
-                       if ( v > 255 ) {
-                               Error( "v > 255" );
-                       }
-                       scaled[i][j] = hnodes1[i][j].count = v;
-                       if ( v ) {
-                               total++;
-                       }
-               }
-               if ( total == 1 ) { // must have two tokens
-                       if ( !scaled[i][0] ) {
-                               scaled[i][0] = hnodes1[i][0].count = 1;
-                       }
-                       else{
-                               scaled[i][1] = hnodes1[i][1].count = 1;
-                       }
-               }
-               BuildTree1( i );
-       }
-}
-
-// ==================
-// Huffman1
-// Order 1 compression with pre-built table
-// ==================
-
-cblock_t Huffman1( cblock_t in ){
-       int i;
-       int outbits, c;
-       unsigned bits;
-       byte        *out_p;
-       cblock_t out;
-       int prev;
-       int v;
-       int rept;
-
-       out_p = out.data = SafeMalloc( ( in.count * 2 ) + 1024 + 4, "Huffman" );
-       memset( out_p, 0, ( in.count * 2 ) + 1024 + 4 );
-
-       // leave space for compressed count
-       out_p += 4;
-       // write count
-       *(long *)out_p = in.count;
-       out_p += 4;
-
-       // write bits
-       outbits = 0;
-       prev = 0;
-       for ( i = 0; i < in.count; i++ )
-       {
-               v = in.data[i];
-
-               c = charbitscount1[prev][v];
-               bits = charbits1[prev][v];
-               if ( !c ) {
-                       Error( "!bits" );
-               }
-               while ( c )
-               {
-                       c--;
-                       if ( bits & ( 1 << c ) ) {
-                               out_p[outbits >> 3] |= 1 << ( outbits & 7 );
-                       }
-                       outbits++;
-               }
-
-               prev = v;
-               // check for repeat encodes
-               for ( rept = 1; ( i + rept < in.count ) && ( rept < MAX_REPT ); rept++ )
-                       if ( in.data[i + rept] != v ) {
-                               break;
-                       }
-               if ( rept > MIN_REPT ) {
-                       c = charbitscount1[prev][255 + rept];
-                       bits = charbits1[prev][255 + rept];
-                       if ( !c ) {
-                               Error( "!bits" );
-                       }
-                       while ( c )
-                       {
-                               c--;
-                               if ( bits & ( 1 << c ) ) {
-                                       out_p[outbits >> 3] |= 1 << ( outbits & 7 );
-                               }
-                               outbits++;
-                       }
-                       i += rept - 1;
-               }
-       }
-       out_p += ( outbits + 7 ) >> 3;
-       out.count = out_p - out.data;
-
-       out_p = out.data;
-       *(long *)out_p = out.count;
-       return( out );
-}
-// ===================
-// LoadFrame
-// ===================
-
-void LoadFrame( cblock_t *out, char *base, int frame ){
-       cblock_t in;
-       int width, height;
-       char name[1024];
-       FILE        *f;
-
-       in.data = NULL;
-       in.count = -1;
-       sprintf( name, "%svideo/%s/%s%04i.tga", gamedir, base, base, frame );
-
-       f = fopen( name, "rb" );
-       if ( !f ) {
-               out->data = NULL;
-               return;
-       }
-       fclose( f );
-
-       LoadTGA( name, &in.data, &width, &height );
-       if ( ( width != cinehead.Width ) || ( height != cinehead.Height ) ) {
-               free( in.data );
-               printf( "Invalid picture size\n" );
-               out->data = NULL;
-               return;
-       }
-       out->data = SafeMalloc( width * height * 3, "LoadFrame" );        // rle could possibly expand file so this not 100% safe (however DCT should force a lot of compression)
-       DCT( out, in, width, height );
-       free( in.data );
-}
-
-// ==================================
-// Cmd_Video
-//
-// video <directory> <framedigits>
-// ==================================
-
-void Cmd_Video(){
-       char savename[256];
-       char name[256];
-       FILE        *output;
-       int frame;
-       int width, height;
-       cblock_t in, huffman;
-       int size;
-       float dctconst;
-       int maxsize, ssize;
-       int min_rle_size, warnings;
-       int ave_image, ave_sound;
-
-       GetScriptToken( false );
-       strcpy( base, token );
-       if ( g_release ) {
-               return;
-       }
-
-       GetScriptToken( false );
-       dctconst = atof( token );
-       GetScriptToken( false );
-       maxsize = atoi( token );
-
-       sprintf( savename, "%svideo/%s.cin", gamedir, base );
-
-       // clear stuff
-       memset( charbits1, 0, sizeof( charbits1 ) );
-       memset( charbitscount1, 0, sizeof( charbitscount1 ) );
-       memset( hnodes1, 0, sizeof( hnodes1 ) );
-       memset( numhnodes1, 0, sizeof( numhnodes1 ) );
-       memset( order0counts, 0, sizeof( order0counts ) );
-
-       // load the entire sound wav file if present
-       LoadSoundtrack();
-
-       cinehead.SndRate = wavinfo.rate;
-       cinehead.SndWidth = wavinfo.width;
-       cinehead.SndChannels = wavinfo.channels;
-
-       sprintf( name, "%svideo/%s/%s0000.tga", gamedir, base, base );
-       printf( "Loading sequence : %s\n", name );
-       printf( "DCT constant     : %f\n", dctconst );
-
-       LoadTGA( name, NULL, &width, &height );
-
-       output = fopen( savename, "wb" );
-       if ( !output ) {
-               Error( "Can't open %s", savename );
-       }
-
-       if ( ( width % BLOCKSIZE ) || ( height % BLOCKSIZE ) ) {
-               Error( "Width and height must be a multiple of %d", BLOCKSIZE );
-       }
-
-       cinehead.Width = width;
-       cinehead.Height = height;
-       init_base( dctconst );
-
-       // build the dictionary
-       printf( "Counting         : " );
-       min_rle_size = 0;
-       for ( frame = 0;  ; frame++ )
-       {
-               printf( "." );
-               LoadFrame( &in, base, frame );
-               if ( !in.data ) {
-                       break;
-               }
-               Huffman1_Count( in );
-               if ( in.count > min_rle_size ) {
-                       min_rle_size = in.count;
-               }
-               free( in.data );
-       }
-       printf( "\n" );
-       cinehead.NumFrames = frame;
-       printf( "Num Frames       : %d\n", frame );
-       cinehead.MaxRleSize = ( min_rle_size + 0x1f ) & 0xfffffe0;
-       cinehead.MaxSndSize = ( ( 4 * wavinfo.rate * wavinfo.channels / 14 ) + 0x1f ) & 0xffffffe0;
-
-       WriteHeader( output, FC_HEADER_NAME, FC_HEADER_VERSION, sizeof( CineHead_t ), &cinehead );
-
-       // build nodes and write counts
-       Huffman1_Build();
-       WriteHeader( output, FC_HUFFBITS_NAME, FC_HUFFBITS_VERSION, sizeof( scaled ), scaled );
-       WriteHeader( output, FC_QUANT_NAME, FC_QUANT_VERSION, sizeof( Quantise ), Quantise );
-
-       ave_image = 0;
-       ave_sound = 0;
-       warnings = 0;
-       // compress it with the dictionary
-       if ( soundtrack ) {
-               ssize = WriteSound( output, frame, 4 );
-               ave_sound += ssize;
-       }
-
-       for ( frame = 0; frame < cinehead.NumFrames; frame++ )
-       {
-               // save some sound samples
-               printf( "Packing          : ", frame );
-               LoadFrame( &in, base, frame );
-
-               // save the image
-               huffman = Huffman1( in );
-               printf( "%d bytes rle, %d bytes huffman", in.count, huffman.count );
-               size = ( huffman.count + 3 ) & 0xfffffffc;                    // round up to longwords
-               if ( size > maxsize ) {
-                       printf( " ** WARNING **" );
-                       warnings++;
-               }
-               printf( "\n" );
-               ave_image += huffman.count;
-
-               WriteHeader( output, FC_IMAGE_NAME, FC_IMAGE_VERSION, size, huffman.data );
-               if ( soundtrack ) {
-                       ssize = WriteSound( output, frame + 4, 1 );
-                       ave_sound += ssize;
-               }
-
-               free( in.data );
-               free( huffman.data );
-       }
-       printf( "\nTotal size: %d (headers + %d image + %d sound)\n", ftell( output ), ave_image, ave_sound );
-       printf( "Data rate : %d bytes per sec (image and sound)\n", ( ave_image + ave_sound ) / cinehead.NumFrames );
-       printf( "Cin created ok with %d warnings.\n", warnings );
-       fclose( output );
-
-       if ( soundtrack ) {
-               free( soundtrack );
-       }
-}
-#endif
-
-void Cmd_Video(){
-}
-
-// end