]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake2/qdata_heretic2/models.c
tools/heretic2: move heretic2 stuff to its own directory
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / models.c
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;
-       }
-}