2004-08-22 22:29:09 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// models.c -- model loading and caching
// models are the only shared resource between a client and server running
// on the same machine.
# include "quakedef.h"
2007-05-25 22:16:29 +00:00
# if defined(RGLQUAKE) || defined(D3DQUAKE)
# if defined(RGLQUAKE)
2004-08-22 22:29:09 +00:00
# include "glquake.h"
2007-05-25 22:16:29 +00:00
# endif
# ifdef D3DQUAKE
# include "d3dquake.h"
# endif
2004-08-22 22:29:09 +00:00
2005-01-18 21:03:46 +00:00
# ifdef Q3SHADERS
# include "shader.h"
# endif
2005-08-03 23:14:59 +00:00
extern cvar_t r_shadow_bumpscale_basetexture ;
2007-09-13 22:27:56 +00:00
extern cvar_t r_replacemodels ;
2004-08-22 22:29:09 +00:00
extern int gl_bumpmappingpossible ;
qboolean isnotmap = true ; //used to not warp ammo models.
# ifndef SWQUAKE
model_t * loadmodel ;
char loadname [ 32 ] ; // for hunk tags
# else
extern model_t * loadmodel ;
extern char loadname [ 32 ] ; // for hunk tags
# endif
void CM_Init ( void ) ;
2007-05-25 22:16:29 +00:00
qboolean Mod_LoadCompositeAnim ( model_t * mod , void * buffer ) ;
2006-03-12 09:19:31 +00:00
qboolean GL_LoadHeightmapModel ( model_t * mod , void * buffer ) ;
2006-03-13 06:15:11 +00:00
qboolean GLMod_LoadSpriteModel ( model_t * mod , void * buffer ) ;
qboolean GLMod_LoadSprite2Model ( model_t * mod , void * buffer ) ;
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadBrushModel ( model_t * mod , void * buffer ) ;
2004-08-22 22:29:09 +00:00
# ifdef Q2BSPS
2006-03-12 22:01:49 +00:00
qboolean Mod_LoadQ2BrushModel ( model_t * mod , void * buffer ) ;
2004-08-22 22:29:09 +00:00
# endif
2006-03-12 09:19:31 +00:00
qboolean Mod_LoadHLModel ( model_t * mod , void * buffer ) ;
2004-11-29 01:21:00 +00:00
# ifdef ZYMOTICMODELS
2007-05-25 22:16:29 +00:00
qboolean Mod_LoadZymoticModel ( model_t * mod , void * buffer ) ;
qboolean Mod_LoadDarkPlacesModel ( model_t * mod , void * buffer ) ;
2004-11-29 01:21:00 +00:00
# endif
2005-08-03 23:14:59 +00:00
# ifdef MD5MODELS
2007-05-25 22:16:29 +00:00
qboolean Mod_LoadMD5MeshModel ( model_t * mod , void * buffer ) ;
2005-08-03 23:14:59 +00:00
# endif
2004-08-22 22:29:09 +00:00
model_t * GLMod_LoadModel ( model_t * mod , qboolean crash ) ;
# ifdef DOOMWADS
qboolean Mod_LoadDoomLevel ( model_t * mod ) ;
# endif
2007-05-25 22:16:29 +00:00
qboolean Mod_LoadQ1Model ( model_t * mod , void * buffer ) ;
2004-08-22 22:29:09 +00:00
# ifdef MD2MODELS
2007-05-25 22:16:29 +00:00
qboolean Mod_LoadQ2Model ( model_t * mod , void * buffer ) ;
2004-08-22 22:29:09 +00:00
# endif
# ifdef MD3MODELS
2007-05-25 22:16:29 +00:00
qboolean Mod_LoadQ3Model ( model_t * mod , void * buffer ) ;
2004-08-22 22:29:09 +00:00
# endif
# ifdef DOOMWADS
void GLMod_LoadDoomSprite ( model_t * mod ) ;
# endif
# define MAX_MOD_KNOWN 2048
# ifndef SWQUAKE
model_t mod_known [ MAX_MOD_KNOWN ] ;
int mod_numknown ;
# else
extern model_t mod_known [ MAX_MOD_KNOWN ] ;
extern int mod_numknown ;
# endif
extern cvar_t r_loadlits ;
2004-09-13 03:20:04 +00:00
# ifdef SPECULAR
extern cvar_t gl_specular ;
# endif
2004-08-22 22:29:09 +00:00
extern cvar_t r_fb_bmodels ;
# ifdef RUNTIMELIGHTING
model_t * lightmodel ;
int numlightdata ;
2004-09-14 05:14:46 +00:00
qboolean writelitfile ;
2004-08-22 22:29:09 +00:00
int relitsurface ;
void GLMod_UpdateLightmap ( int snum )
{
msurface_t * s ;
if ( lightmodel )
{
// int i;
// for (s = lightmodel->surfaces,i=0; i < lightmodel->numsurfaces; i++,s++)
// s->cached_dlight = -1;
if ( snum < lightmodel - > numsurfaces )
{
s = lightmodel - > surfaces + snum ;
s - > cached_dlight = - 1 ;
}
else
Con_Printf ( " lit non-existant surface \n " ) ;
}
}
# endif
void GLMod_TextureList_f ( void )
{
int m , i ;
texture_t * tx ;
model_t * mod ;
qboolean shownmodelname ;
for ( m = 0 , mod = mod_known ; m < mod_numknown ; m + + , mod + + )
{
if ( mod - > type = = mod_brush & & ! mod - > needload )
{
if ( * mod - > name = = ' * ' )
continue ; // inlines don't count
shownmodelname = false ;
for ( i = 0 ; i < mod - > numtextures ; i + + )
{
tx = mod - > textures [ i ] ;
if ( ! tx )
continue ; //happens on e1m2
if ( ! shownmodelname )
{
shownmodelname = true ;
Con_Printf ( " %s \n " , mod - > name ) ;
}
Con_Printf ( " %s \n " , tx - > name ) ;
}
}
}
}
void GLMod_BlockTextureColour_f ( void )
{
char texname [ 64 ] ;
model_t * mod ;
texture_t * tx ;
char * match = Cmd_Argv ( 1 ) ;
int i , m ;
unsigned int colour [ 8 * 8 ] ;
unsigned int rgba ;
( ( char * ) & rgba ) [ 0 ] = atoi ( Cmd_Argv ( 2 ) ) ;
( ( char * ) & rgba ) [ 1 ] = atoi ( Cmd_Argv ( 3 ) ) ;
( ( char * ) & rgba ) [ 2 ] = atoi ( Cmd_Argv ( 4 ) ) ;
( ( char * ) & rgba ) [ 3 ] = 255 ;
sprintf ( texname , " 8*8_%i_%i_%i " , ( int ) ( ( char * ) & rgba ) [ 0 ] , ( int ) ( ( char * ) & rgba ) [ 1 ] , ( int ) ( ( char * ) & rgba ) [ 2 ] ) ;
for ( i = 0 ; i < sizeof ( colour ) / sizeof ( colour [ 0 ] ) ; i + + )
colour [ i ] = rgba ;
for ( m = 0 , mod = mod_known ; m < mod_numknown ; m + + , mod + + )
{
if ( mod - > type = = mod_brush & & ! mod - > needload )
{
for ( i = 0 ; i < mod - > numtextures ; i + + )
{
tx = mod - > textures [ i ] ;
if ( ! tx )
continue ; //happens on e1m2
if ( ! stricmp ( tx - > name , match ) )
{
2007-05-25 22:16:29 +00:00
tx - > gl_texturenum = R_LoadTexture32 ( texname , 8 , 8 , colour , true , false ) ;
2004-08-22 22:29:09 +00:00
}
}
}
}
}
/*
= = = = = = = = = = = = = = =
Mod_Init
= = = = = = = = = = = = = = =
*/
void GLMod_Init ( void )
{
mod_numknown = 0 ;
2005-08-26 22:56:51 +00:00
Q1BSP_Init ( ) ;
2004-08-22 22:29:09 +00:00
Cmd_AddRemCommand ( " mod_texturelist " , GLMod_TextureList_f ) ;
Cmd_AddRemCommand ( " mod_usetexture " , GLMod_BlockTextureColour_f ) ;
}
void GLMod_Shutdown ( void )
{
mod_numknown = 0 ;
Cmd_RemoveCommand ( " mod_texturelist " ) ;
Cmd_RemoveCommand ( " mod_usetexture " ) ;
# ifdef RUNTIMELIGHTING
lightmodel = NULL ;
# endif
}
/*
= = = = = = = = = = = = = = =
Mod_Init
Caches the data if needed
= = = = = = = = = = = = = = =
*/
void * GLMod_Extradata ( model_t * mod )
{
void * r ;
r = Cache_Check ( & mod - > cache ) ;
if ( r )
return r ;
GLMod_LoadModel ( mod , true ) ;
if ( ! mod - > cache . data )
Sys_Error ( " Mod_Extradata: caching failed " ) ;
return mod - > cache . data ;
}
/*
= = = = = = = = = = = = = = =
Mod_PointInLeaf
= = = = = = = = = = = = = = =
*/
2005-08-26 22:56:51 +00:00
mleaf_t * GLMod_PointInLeaf ( model_t * model , vec3_t p )
2004-08-22 22:29:09 +00:00
{
mnode_t * node ;
float d ;
mplane_t * plane ;
if ( ! model )
{
Sys_Error ( " Mod_PointInLeaf: bad model " ) ;
}
if ( ! model - > nodes )
return NULL ;
# ifdef Q2BSPS
if ( model - > fromgame = = fg_quake2 | | model - > fromgame = = fg_quake3 )
{
2005-08-26 22:56:51 +00:00
return model - > leafs + CM_PointLeafnum ( model , p ) ;
2004-08-22 22:29:09 +00:00
}
# endif
if ( model - > fromgame = = fg_doom )
{
return NULL ;
}
node = model - > nodes ;
while ( 1 )
{
if ( node - > contents < 0 )
return ( mleaf_t * ) node ;
plane = node - > plane ;
d = DotProduct ( p , plane - > normal ) - plane - > dist ;
if ( d > 0 )
node = node - > children [ 0 ] ;
else
node = node - > children [ 1 ] ;
}
return NULL ; // never reached
}
/*
= = = = = = = = = = = = = = = = = = =
Mod_ClearAll
= = = = = = = = = = = = = = = = = = =
*/
void GLMod_ClearAll ( void )
{
int i ;
model_t * mod ;
# ifdef RUNTIMELIGHTING
lightmodel = NULL ;
# endif
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
if ( mod - > type ! = mod_alias
& & mod - > type ! = mod_halflife
)
mod - > needload = true ;
}
void GLMod_Think ( void )
{
# ifdef RUNTIMELIGHTING
if ( lightmodel )
{
if ( relitsurface > = lightmodel - > numsurfaces )
{
return ;
}
LightFace ( relitsurface ) ;
GLMod_UpdateLightmap ( relitsurface ) ;
relitsurface + + ;
if ( relitsurface > = lightmodel - > numsurfaces )
{
char filename [ MAX_QPATH ] ;
2004-11-27 08:16:25 +00:00
char * f ;
2004-08-22 22:29:09 +00:00
Con_Printf ( " Finished lighting level \n " ) ;
2004-11-27 08:16:25 +00:00
strcpy ( filename , lightmodel - > name ) ;
f = COM_SkipPath ( filename ) ;
* f = ' \0 ' ;
2004-10-01 22:17:33 +00:00
if ( lightmodel - > deluxdata )
{
2006-03-11 03:12:10 +00:00
COM_StripExtension ( lightmodel - > name , filename , sizeof ( filename ) ) ;
COM_DefaultExtension ( filename , " .lux " , sizeof ( filename ) ) ;
2006-01-02 23:01:54 +00:00
FS_WriteFile ( filename , lightmodel - > deluxdata - 8 , numlightdata * 3 + 8 , FS_GAME ) ;
2004-10-01 22:17:33 +00:00
}
2004-08-22 22:29:09 +00:00
2004-09-14 05:14:46 +00:00
if ( writelitfile ) //the user might already have a lit file (don't overwrite it).
{
2006-03-11 03:12:10 +00:00
COM_StripExtension ( lightmodel - > name , filename , sizeof ( filename ) ) ;
COM_DefaultExtension ( filename , " .lit " , sizeof ( filename ) ) ;
2006-01-02 23:01:54 +00:00
FS_WriteFile ( filename , lightmodel - > lightdata - 8 , numlightdata * 3 + 8 , FS_GAME ) ;
2004-09-14 05:14:46 +00:00
}
2004-08-22 22:29:09 +00:00
}
}
# endif
}
/*
= = = = = = = = = = = = = = = = = =
Mod_FindName
= = = = = = = = = = = = = = = = = =
*/
model_t * GLMod_FindName ( char * name )
{
int i ;
model_t * mod ;
// if (!name[0])
// Sys_Error ("Mod_ForName: NULL name");
//
// search the currently loaded models
//
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
if ( ! strcmp ( mod - > name , name ) )
break ;
if ( i = = mod_numknown )
{
if ( mod_numknown = = MAX_MOD_KNOWN )
Sys_Error ( " mod_numknown == MAX_MOD_KNOWN " ) ;
memset ( mod , 0 , sizeof ( model_t ) ) ; //clear the old model as the renderers use the same globals
strcpy ( mod - > name , name ) ;
mod - > needload = true ;
mod_numknown + + ;
mod - > particleeffect = - 1 ;
2005-08-06 22:39:28 +00:00
mod - > particletrail = - 1 ;
2004-08-22 22:29:09 +00:00
}
return mod ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_TouchModel
= = = = = = = = = = = = = = = = = =
*/
void GLMod_TouchModel ( char * name )
{
model_t * mod ;
mod = GLMod_FindName ( name ) ;
if ( ! mod - > needload )
{
if ( mod - > type = = mod_alias
| | mod - > type = = mod_halflife
)
Cache_Check ( & mod - > cache ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
Mod_LoadModel
Loads a model into the cache
= = = = = = = = = = = = = = = = = =
*/
char * COM_FileExtension ( char * in ) ;
model_t * GLMod_LoadModel ( model_t * mod , qboolean crash )
{
void * d ;
unsigned * buf = NULL ;
qbyte stackbuf [ 1024 ] ; // avoid dirtying the cache heap
2007-09-13 22:27:56 +00:00
char mdlbase [ MAX_QPATH ] ;
qboolean lastload = false ;
char * replstr ;
qboolean doomsprite = false ;
2004-08-22 22:29:09 +00:00
char * ext ;
if ( ! mod - > needload & & mod - > type ! = mod_dummy )
{
if ( mod - > type = = mod_alias
| | mod - > type = = mod_halflife
)
{
d = Cache_Check ( & mod - > cache ) ;
if ( d )
return mod ;
}
else
return mod ; // not cached at all
}
loadmodel = mod ;
# ifdef Q2BSPS
if ( ! * mod - > name )
{
2006-03-12 22:01:49 +00:00
if ( ! Mod_LoadQ2BrushModel ( mod , buf ) )
goto couldntload ;
2004-08-22 22:29:09 +00:00
mod - > needload = false ;
2005-03-10 03:55:18 +00:00
P_DefaultTrail ( mod ) ;
2004-08-22 22:29:09 +00:00
return mod ;
}
# endif
//
// load the file
//
2006-03-06 00:19:46 +00:00
// set necessary engine flags for loading purposes
if ( ! strcmp ( mod - > name , " progs/player.mdl " ) )
mod - > engineflags | = MDLF_PLAYER | MDLF_DOCRC ;
2006-06-08 06:24:07 +00:00
else if ( ! strcmp ( mod - > name , " progs/flame.mdl " ) | |
! strcmp ( mod - > name , " progs/flame2.mdl " ) )
2006-03-06 00:19:46 +00:00
mod - > engineflags | = MDLF_FLAME ;
2006-06-08 06:24:07 +00:00
else if ( ! strcmp ( mod - > name , " progs/bolt.mdl " ) | |
! strcmp ( mod - > name , " progs/bolt2.mdl " ) | |
! strcmp ( mod - > name , " progs/bolt3.mdl " ) | |
! strcmp ( mod - > name , " progs/beam.mdl " ) | |
! strcmp ( mod - > name , " models/stsunsf2.mdl " ) | |
! strcmp ( mod - > name , " models/stsunsf1.mdl " ) | |
! strcmp ( mod - > name , " models/stice.mdl " ) )
mod - > engineflags | = MDLF_BOLT ;
2006-03-06 00:19:46 +00:00
else if ( ! strcmp ( mod - > name , " progs/eyes.mdl " ) )
mod - > engineflags | = MDLF_DOCRC ;
2007-09-13 22:27:56 +00:00
// call the apropriate loader
2004-08-22 22:29:09 +00:00
mod - > needload = false ;
2007-09-13 22:27:56 +00:00
// get string used for replacement tokens
ext = COM_FileExtension ( mod - > name ) ;
if ( ! Q_strcasecmp ( ext , " spr " ) | | ! Q_strcasecmp ( ext , " sp2 " ) )
replstr = NULL ; // sprite
else if ( ! Q_strcasecmp ( ext , " dsp " ) ) // doom sprite
2004-08-22 22:29:09 +00:00
{
2007-09-13 22:27:56 +00:00
replstr = NULL ;
doomsprite = true ;
}
else // assume models
replstr = r_replacemodels . string ;
// gl_load24bit 0 disables all replacements
if ( gl_load24bit . value )
replstr = NULL ;
COM_StripExtension ( mod - > name , mdlbase , sizeof ( mdlbase ) ) ;
while ( 1 )
{
for ( replstr = COM_ParseStringSet ( replstr ) ; com_token [ 0 ] & & ! buf ; replstr = COM_ParseStringSet ( replstr ) )
buf = ( unsigned * ) COM_LoadStackFile ( va ( " %s.%s " , mdlbase , com_token ) , stackbuf , sizeof ( stackbuf ) ) ;
if ( ! buf )
{
if ( lastload ) // only load unreplaced file once
break ;
lastload = true ;
buf = ( unsigned * ) COM_LoadStackFile ( mod - > name , stackbuf , sizeof ( stackbuf ) ) ;
if ( ! buf )
{
# ifdef DOOMWADS
if ( doomsprite ) // special case needed for doom sprites
{
mod - > needload = false ;
GLMod_LoadDoomSprite ( mod ) ;
P_DefaultTrail ( mod ) ;
return mod ;
}
# endif
break ; // failed to load unreplaced file and nothing left
}
}
2004-08-22 22:29:09 +00:00
2007-09-13 22:27:56 +00:00
//
// allocate a new model
//
COM_FileBase ( mod - > name , loadname , sizeof ( loadname ) ) ;
//
// fill it in
//
switch ( LittleLong ( * ( unsigned * ) buf ) )
{
//The binary 3d mesh model formats
case IDPOLYHEADER :
if ( ! Mod_LoadQ1Model ( mod , buf ) )
continue ;
break ;
2004-08-22 22:29:09 +00:00
# ifdef MD2MODELS
2007-09-13 22:27:56 +00:00
case MD2IDALIASHEADER :
if ( ! Mod_LoadQ2Model ( mod , buf ) )
continue ;
break ;
2004-08-22 22:29:09 +00:00
# endif
# ifdef MD3MODELS
2007-09-13 22:27:56 +00:00
case MD3_IDENT :
if ( ! Mod_LoadQ3Model ( mod , buf ) )
continue ;
break ;
2007-05-25 22:16:29 +00:00
# endif
# ifdef HALFLIFEMODELS
2007-09-13 22:27:56 +00:00
case ( ( ' T ' < < 24 ) + ( ' S ' < < 16 ) + ( ' D ' < < 8 ) + ' I ' ) :
if ( ! Mod_LoadHLModel ( mod , buf ) )
continue ;
break ;
2007-05-25 22:16:29 +00:00
# endif
//Binary skeletal model formats
# ifdef ZYMOTICMODELS
2007-09-13 22:27:56 +00:00
case ( ( ' O ' < < 24 ) + ( ' M ' < < 16 ) + ( ' Y ' < < 8 ) + ' Z ' ) :
if ( ! Mod_LoadZymoticModel ( mod , buf ) )
continue ;
break ;
case ( ( ' K ' < < 24 ) + ( ' R ' < < 16 ) + ( ' A ' < < 8 ) + ' D ' ) :
if ( ! Mod_LoadDarkPlacesModel ( mod , buf ) )
continue ;
break ;
2004-08-22 22:29:09 +00:00
# endif
2007-05-25 22:16:29 +00:00
//Binary Sprites
2004-08-22 22:29:09 +00:00
# ifdef SP2MODELS
2007-09-13 22:27:56 +00:00
case IDSPRITE2HEADER :
if ( ! GLMod_LoadSprite2Model ( mod , buf ) )
continue ;
break ;
2004-08-22 22:29:09 +00:00
# endif
2007-09-13 22:27:56 +00:00
case IDSPRITEHEADER :
if ( ! GLMod_LoadSpriteModel ( mod , buf ) )
continue ;
break ;
2007-05-25 22:16:29 +00:00
2007-09-13 22:27:56 +00:00
//Binary Map formats
2004-08-22 22:29:09 +00:00
# ifdef Q2BSPS
2007-09-13 22:27:56 +00:00
case ( ' R ' < < 0 ) + ( ' B ' < < 8 ) + ( ' S ' < < 16 ) + ( ' P ' < < 24 ) :
case IDBSPHEADER : //looks like id switched to have proper ids
if ( ! Mod_LoadQ2BrushModel ( mod , buf ) )
continue ;
break ;
2004-08-22 22:29:09 +00:00
# endif
# ifdef DOOMWADS
2007-09-13 22:27:56 +00:00
case ( ( ' D ' < < 24 ) + ( ' A ' < < 16 ) + ( ' W ' < < 8 ) + ' I ' ) : //the id is hacked by the FS .wad loader (main wad).
case ( ( ' D ' < < 24 ) + ( ' A ' < < 16 ) + ( ' W ' < < 8 ) + ' P ' ) : //the id is hacked by the FS .wad loader (patch wad).
if ( ! Mod_LoadDoomLevel ( mod ) )
continue ;
break ;
2004-08-22 22:29:09 +00:00
# endif
2007-09-13 22:27:56 +00:00
case 30 : //hl
case 29 : //q1
case 28 : //prerel
if ( ! GLMod_LoadBrushModel ( mod , buf ) )
continue ;
break ;
2007-05-25 22:16:29 +00:00
2007-09-13 22:27:56 +00:00
//Text based misc types.
default :
//check for text based headers
COM_Parse ( ( char * ) buf ) ;
2005-08-19 15:42:56 +00:00
# ifdef MD5MODELS
2007-09-13 22:27:56 +00:00
if ( ! strcmp ( com_token , " MD5Version " ) ) //doom3 format, text based, skeletal
{
if ( ! Mod_LoadMD5MeshModel ( mod , buf ) )
continue ;
break ;
}
if ( ! strcmp ( com_token , " EXTERNALANIM " ) ) //custom format, text based, specifies skeletal models to load and which md5anim files to use.
{
if ( ! Mod_LoadCompositeAnim ( mod , buf ) )
continue ;
break ;
}
2005-08-19 15:42:56 +00:00
# endif
2005-08-26 22:56:51 +00:00
# ifdef TERRAIN
2007-09-13 22:27:56 +00:00
if ( ! strcmp ( com_token , " terrain " ) ) //custom format, text based.
{
if ( ! GL_LoadHeightmapModel ( mod , buf ) )
continue ;
break ;
}
2005-08-26 22:56:51 +00:00
# endif
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_WARNING " Unrecognised model format %i \n " , LittleLong ( * ( unsigned * ) buf ) ) ;
2007-09-13 22:27:56 +00:00
continue ;
}
P_DefaultTrail ( mod ) ;
Validation_IncludeFile ( mod - > name , ( char * ) buf , com_filesize ) ;
return mod ;
2004-08-22 22:29:09 +00:00
}
2007-09-13 22:27:56 +00:00
couldntload :
if ( crash )
Host_EndGame ( " Mod_NumForName: %s not found or couldn't load " , mod - > name ) ;
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Unable to load or replace %s \n " , mod - > name ) ;
2007-09-13 22:27:56 +00:00
mod - > type = mod_dummy ;
mod - > mins [ 0 ] = - 16 ;
mod - > mins [ 1 ] = - 16 ;
mod - > mins [ 2 ] = - 16 ;
mod - > maxs [ 0 ] = 16 ;
mod - > maxs [ 1 ] = 16 ;
mod - > maxs [ 2 ] = 16 ;
mod - > needload = true ;
mod - > engineflags = 0 ;
2005-03-10 03:55:18 +00:00
P_DefaultTrail ( mod ) ;
2004-08-22 22:29:09 +00:00
return mod ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_ForName
Loads in a model for the given name
= = = = = = = = = = = = = = = = = =
*/
model_t * GLMod_ForName ( char * name , qboolean crash )
{
model_t * mod ;
mod = GLMod_FindName ( name ) ;
return GLMod_LoadModel ( mod , crash ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
BRUSHMODEL LOADING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# ifdef SWQUAKE
extern qbyte * mod_base ;
# else
qbyte * mod_base ;
# endif
2004-09-01 22:59:56 +00:00
char * advtexturedesc ;
2005-08-26 22:56:51 +00:00
char * mapsection ;
char * defaultsection ;
2004-09-01 22:59:56 +00:00
2005-08-26 22:56:51 +00:00
static char * GLMod_TD_LeaveSection ( char * file )
2004-09-01 22:59:56 +00:00
{ //recursive routine to find the next }
while ( file )
{
2005-08-26 22:56:51 +00:00
file = COM_Parse ( file ) ;
2004-09-01 22:59:56 +00:00
if ( * com_token = = ' { ' )
file = GLMod_TD_LeaveSection ( file ) ;
else if ( * com_token = = ' } ' )
return file ;
}
return NULL ;
}
2005-08-26 22:56:51 +00:00
static char * GLMod_TD_Section ( char * file , const char * sectionname )
2004-09-01 22:59:56 +00:00
{ //position within the open brace.
while ( file )
{
while ( * file < = ' ' ) //skip whitespace and new lines.
{
if ( ! * file )
return NULL ;
file + + ;
}
2005-08-26 22:56:51 +00:00
file = COM_Parse ( file ) ;
2004-09-01 22:59:56 +00:00
if ( ! stricmp ( com_token , sectionname ) )
{
2005-08-26 22:56:51 +00:00
file = COM_Parse ( file ) ;
2004-09-01 22:59:56 +00:00
if ( * com_token ! = ' { ' )
return NULL ;
return file ;
}
if ( * com_token = = ' { ' )
file = GLMod_TD_LeaveSection ( file ) ;
}
return NULL ;
}
void GLMod_InitTextureDescs ( char * mapname )
{
if ( advtexturedesc )
BZ_Free ( advtexturedesc ) ;
advtexturedesc = COM_LoadMallocFile ( va ( " maps/shaders/%s.shaders " , mapname ) ) ;
2004-09-20 23:25:38 +00:00
if ( ! advtexturedesc )
advtexturedesc = COM_LoadMallocFile ( va ( " shaders/%s.shaders " , mapname ) ) ;
2004-09-01 22:59:56 +00:00
if ( advtexturedesc )
{
mapsection = advtexturedesc ;
defaultsection = NULL ;
}
else
{
advtexturedesc = COM_LoadMallocFile ( va ( " map.shaders " , mapname ) ) ;
mapsection = GLMod_TD_Section ( advtexturedesc , mapname ) ;
defaultsection = GLMod_TD_Section ( advtexturedesc , " default " ) ;
}
}
2005-08-26 22:56:51 +00:00
void GLMod_LoadAdvancedTextureSection ( char * section , char * name , int * base , int * norm , int * luma , int * gloss , int * alphamode , qboolean * cull ) //fixme: add gloss
2004-09-01 22:59:56 +00:00
{
char stdname [ MAX_QPATH ] = " " ;
char flatname [ MAX_QPATH ] = " " ;
char bumpname [ MAX_QPATH ] = " " ;
char normname [ MAX_QPATH ] = " " ;
char lumaname [ MAX_QPATH ] = " " ;
2004-09-20 23:25:38 +00:00
char glossname [ MAX_QPATH ] = " " ;
2004-09-01 22:59:56 +00:00
section = GLMod_TD_Section ( section , name ) ;
while ( section )
{
2005-08-26 22:56:51 +00:00
section = COM_Parse ( section ) ;
2004-09-01 22:59:56 +00:00
if ( * com_token = = ' } ' )
break ;
while ( * section < = ' ' ) //get rid of nasty whitespace.
{
if ( ! * section )
return ;
section + + ;
}
if ( * section = = ' = ' )
section + + ; //evil notation.
if ( ! stricmp ( com_token , " texture " ) | | ! stricmp ( com_token , " base " ) )
{
2005-08-26 22:56:51 +00:00
section = COM_Parse ( section ) ;
2004-09-01 22:59:56 +00:00
Q_strncpyz ( stdname , com_token , sizeof ( stdname ) ) ;
}
2004-09-20 23:25:38 +00:00
else if ( ! stricmp ( com_token , " flatmap " ) | | ! stricmp ( com_token , " flat " )
| | ! stricmp ( com_token , " diffusemap " ) | | ! stricmp ( com_token , " diffuse " ) )
2004-09-01 22:59:56 +00:00
{
2005-08-26 22:56:51 +00:00
section = COM_Parse ( section ) ;
2004-09-01 22:59:56 +00:00
Q_strncpyz ( flatname , com_token , sizeof ( flatname ) ) ;
}
2004-09-20 23:25:38 +00:00
else if ( ! stricmp ( com_token , " bumpmap " ) | | ! stricmp ( com_token , " bump " ) )
2004-09-01 22:59:56 +00:00
{
2005-08-26 22:56:51 +00:00
section = COM_Parse ( section ) ;
2004-09-01 22:59:56 +00:00
Q_strncpyz ( bumpname , com_token , sizeof ( bumpname ) ) ;
}
2004-09-20 23:25:38 +00:00
else if ( ! stricmp ( com_token , " normalmap " ) | | ! stricmp ( com_token , " normal " ) )
2004-09-01 22:59:56 +00:00
{
2005-08-26 22:56:51 +00:00
section = COM_Parse ( section ) ;
2004-09-01 22:59:56 +00:00
Q_strncpyz ( normname , com_token , sizeof ( normname ) ) ;
}
2004-09-20 23:25:38 +00:00
else if ( ! stricmp ( com_token , " glossmap " ) | | ! stricmp ( com_token , " gloss " ) )
{
2005-08-26 22:56:51 +00:00
section = COM_Parse ( section ) ;
2004-09-20 23:25:38 +00:00
Q_strncpyz ( glossname , com_token , sizeof ( glossname ) ) ;
}
else if ( ! stricmp ( com_token , " luma " ) | | ! stricmp ( com_token , " glow " )
| | ! stricmp ( com_token , " ambient " ) | | ! stricmp ( com_token , " ambientmap " ) )
2004-09-01 22:59:56 +00:00
{
2005-08-26 22:56:51 +00:00
section = COM_Parse ( section ) ;
2004-09-01 22:59:56 +00:00
Q_strncpyz ( lumaname , com_token , sizeof ( lumaname ) ) ;
}
else
{
//best thing we can do is jump to the end of the line, and hope they were a good creator...
while ( * section & & * section ! = ' \n ' )
section + + ;
}
}
//okay it's all parsed. Try and interpret the data now.
* base = 0 ;
if ( norm )
* norm = 0 ;
if ( luma )
* luma = 0 ;
2004-09-20 23:25:38 +00:00
if ( gloss )
* gloss = 0 ;
2004-09-01 22:59:56 +00:00
if ( ! * stdname & & ! * flatname )
return ;
2004-10-07 13:16:43 +00:00
TRACE ( ( " dbg: GLMod_LoadAdvancedTextureSection: %s \n " , name ) ) ;
2007-05-25 22:16:29 +00:00
2004-09-01 22:59:56 +00:00
if ( norm & & gl_bumpmappingpossible & & cls . allow_bump )
{
* base = 0 ;
* norm = 0 ;
if ( ! * norm & & * normname )
2005-04-26 16:04:12 +00:00
* norm = Mod_LoadHiResTexture ( normname , NULL , true , false , false ) ;
2004-09-01 22:59:56 +00:00
if ( ! * norm & & * bumpname )
2005-04-26 16:04:12 +00:00
* norm = Mod_LoadBumpmapTexture ( bumpname , NULL ) ;
2004-09-01 22:59:56 +00:00
if ( * norm & & * flatname )
2005-04-26 16:04:12 +00:00
* base = Mod_LoadHiResTexture ( flatname , NULL , true , false , true ) ;
2004-09-01 22:59:56 +00:00
}
else
{
* base = 0 ;
if ( norm )
* norm = 0 ;
}
if ( ! * base & & * stdname )
2005-04-26 16:04:12 +00:00
* base = Mod_LoadHiResTexture ( stdname , NULL , true , false , true ) ;
2004-09-01 22:59:56 +00:00
if ( ! * base & & * flatname )
2005-04-26 16:04:12 +00:00
* base = Mod_LoadHiResTexture ( flatname , NULL , true , false , true ) ;
2004-09-01 22:59:56 +00:00
if ( luma & & * lumaname )
2005-04-26 16:04:12 +00:00
* luma = Mod_LoadHiResTexture ( lumaname , NULL , true , true , true ) ;
2004-09-20 23:25:38 +00:00
if ( * norm & & gloss & & * glossname & & gl_specular . value )
2005-04-26 16:04:12 +00:00
* gloss = Mod_LoadHiResTexture ( glossname , NULL , true , false , true ) ;
2004-09-01 22:59:56 +00:00
}
2004-09-20 23:25:38 +00:00
void GLMod_LoadAdvancedTexture ( char * name , int * base , int * norm , int * luma , int * gloss , int * alphamode , qboolean * cull ) //fixme: add gloss
2004-09-01 22:59:56 +00:00
{
if ( ! gl_load24bit . value )
return ;
if ( mapsection )
{
2004-09-20 23:25:38 +00:00
GLMod_LoadAdvancedTextureSection ( mapsection , name , base , norm , luma , gloss , alphamode , cull ) ;
2004-09-01 22:59:56 +00:00
if ( * base )
return ;
}
if ( defaultsection )
2004-09-20 23:25:38 +00:00
GLMod_LoadAdvancedTextureSection ( defaultsection , name , base , norm , luma , gloss , alphamode , cull ) ;
2004-09-01 22:59:56 +00:00
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_LoadTextures
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadTextures ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
2005-01-18 21:03:46 +00:00
extern cvar_t gl_shadeq1 , gl_shadeq1_name ;
2004-08-22 22:29:09 +00:00
extern int gl_bumpmappingpossible ;
int i , j , pixels , num , max , altmax ;
miptex_t * mt ;
texture_t * tx , * tx2 ;
texture_t * anims [ 10 ] ;
texture_t * altanims [ 10 ] ;
char altname [ 256 ] ;
dmiptexlump_t * m ;
qboolean alphaed ;
qbyte * base ;
2004-09-01 22:59:56 +00:00
2004-10-07 13:16:43 +00:00
TRACE ( ( " dbg: GLMod_LoadTextures: inittexturedescs \n " ) ) ;
2004-09-01 22:59:56 +00:00
GLMod_InitTextureDescs ( loadname ) ;
2004-09-20 23:25:38 +00:00
2004-08-22 22:29:09 +00:00
if ( ! l - > filelen )
{
loadmodel - > textures = NULL ;
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
m = ( dmiptexlump_t * ) ( mod_base + l - > fileofs ) ;
m - > nummiptex = LittleLong ( m - > nummiptex ) ;
loadmodel - > numtextures = m - > nummiptex ;
loadmodel - > textures = Hunk_AllocName ( m - > nummiptex * sizeof ( * loadmodel - > textures ) , loadname ) ;
for ( i = 0 ; i < m - > nummiptex ; i + + )
{
m - > dataofs [ i ] = LittleLong ( m - > dataofs [ i ] ) ;
if ( m - > dataofs [ i ] = = - 1 ) //e1m2, this happens
continue ;
mt = ( miptex_t * ) ( ( qbyte * ) m + m - > dataofs [ i ] ) ;
2004-10-07 13:16:43 +00:00
TRACE ( ( " dbg: GLMod_LoadTextures: texture %s \n " , loadname ) ) ;
2004-12-03 09:43:35 +00:00
if ( ! * mt - > name ) //I HATE MAPPERS!
{
sprintf ( mt - > name , " unnamed%i " , i ) ;
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_WARNING " warning: unnamed texture in %s, renaming to %s \n " , loadmodel - > name , mt - > name ) ;
2004-12-03 09:43:35 +00:00
}
2004-08-22 22:29:09 +00:00
mt - > width = LittleLong ( mt - > width ) ;
mt - > height = LittleLong ( mt - > height ) ;
for ( j = 0 ; j < MIPLEVELS ; j + + )
mt - > offsets [ j ] = LittleLong ( mt - > offsets [ j ] ) ;
if ( ( mt - > width & 15 ) | | ( mt - > height & 15 ) )
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_WARNING " Warning: Texture %s is not 16 aligned " , mt - > name ) ;
2005-08-26 22:56:51 +00:00
if ( mt - > width < 1 | | mt - > height < 1 )
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_WARNING " Warning: Texture %s has no size " , mt - > name ) ;
2004-08-22 22:29:09 +00:00
pixels = mt - > width * mt - > height / 64 * 85 ;
tx = Hunk_AllocName ( sizeof ( texture_t ) /* +pixels*/ , loadname ) ;
loadmodel - > textures [ i ] = tx ;
memcpy ( tx - > name , mt - > name , sizeof ( tx - > name ) ) ;
tx - > width = mt - > width ;
tx - > height = mt - > height ;
2005-03-10 03:55:18 +00:00
tx - > parttype = P_ParticleTypeForName ( va ( " tex_%s " , tx - > name ) ) ;
2004-08-22 22:29:09 +00:00
if ( ! mt - > offsets [ 0 ] ) //this is a hl external style texture, load it a little later (from a wad)
{
// tx->gl_texturenum = Mod_LoadReplacementTexture("light1_4", true, false);
continue ;
}
// for (j=0 ; j<MIPLEVELS ; j++)
// tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
// the pixels immediately follow the structures
// memcpy ( tx+1, mt+1, pixels); //have to be saved for dynamic screen changing (done by reloading entire vid/draw subsystem and all textures)
if ( ! Q_strncmp ( mt - > name , " sky " , 3 ) )
{
tx - > offsets [ 0 ] = ( char * ) mt + mt - > offsets [ 0 ] - ( char * ) tx ;
2007-05-25 22:16:29 +00:00
R_InitSky ( tx ) ;
2004-08-22 22:29:09 +00:00
}
else
# ifdef PEXT_BULLETENS
if ( ! R_AddBulleten ( tx ) )
# endif
{
2004-09-20 23:25:38 +00:00
tx - > gl_texturenum = 0 ;
GLMod_LoadAdvancedTexture ( tx - > name , & tx - > gl_texturenum , & tx - > gl_texturenumbumpmap , & tx - > gl_texturenumfb , & tx - > gl_texturenumspec , NULL , NULL ) ;
2004-09-01 22:59:56 +00:00
if ( tx - > gl_texturenum )
continue ;
2004-08-22 22:29:09 +00:00
base = ( qbyte * ) ( mt + 1 ) ;
2004-09-01 22:59:56 +00:00
2004-08-22 22:29:09 +00:00
if ( loadmodel - > fromgame = = fg_halflife )
{ //external textures have already been filtered.
base = W_ConvertWAD3Texture ( mt , & mt - > width , & mt - > height , & alphaed ) ; //convert texture to 32 bit.
tx - > alphaed = alphaed ;
2005-04-26 16:04:12 +00:00
if ( ! ( tx - > gl_texturenum = Mod_LoadReplacementTexture ( mt - > name , loadname , true , alphaed , true ) ) )
if ( ! ( tx - > gl_texturenum = Mod_LoadReplacementTexture ( mt - > name , " bmodels " , true , alphaed , true ) ) )
2007-05-25 22:16:29 +00:00
tx - > gl_texturenum = R_LoadTexture32 ( mt - > name , tx - > width , tx - > height , ( unsigned int * ) base , true , alphaed ) ;
2004-08-22 22:29:09 +00:00
* tx - > name = * mt - > name ;
}
else
{
2005-04-26 16:04:12 +00:00
if ( ! ( tx - > gl_texturenum = Mod_LoadReplacementTexture ( mt - > name , loadname , true , false , true ) ) )
if ( ! ( tx - > gl_texturenum = Mod_LoadReplacementTexture ( mt - > name , " bmodels " , true , false , true ) ) )
2007-05-25 22:16:29 +00:00
tx - > gl_texturenum = R_LoadTexture8 ( mt - > name , tx - > width , tx - > height , base , true , false ) ;
2004-08-22 22:29:09 +00:00
if ( r_fb_bmodels . value )
{
2006-03-06 01:41:09 +00:00
snprintf ( altname , sizeof ( altname ) - 1 , " %s_luma " , mt - > name ) ;
2005-04-26 16:04:12 +00:00
if ( gl_load24bit . value )
2004-08-22 22:29:09 +00:00
{
2005-04-26 16:04:12 +00:00
tx - > gl_texturenumfb = Mod_LoadReplacementTexture ( altname , loadname , true , false , true ) ;
if ( ! tx - > gl_texturenumfb )
tx - > gl_texturenumfb = Mod_LoadReplacementTexture ( altname , " bmodels " , true , false , true ) ;
2004-08-22 22:29:09 +00:00
}
if ( ! tx - > gl_texturenumfb ) //generate one (if possible).
2007-05-25 22:16:29 +00:00
tx - > gl_texturenumfb = R_LoadTextureFB ( altname , tx - > width , tx - > height , base , true , true ) ;
2004-08-22 22:29:09 +00:00
}
}
2004-09-01 22:59:56 +00:00
tx - > gl_texturenumbumpmap = 0 ;
if ( gl_bumpmappingpossible & & cls . allow_bump )
{
2004-09-30 22:45:08 +00:00
extern cvar_t gl_bump ;
if ( gl_bump . value < 2 ) //set to 2 to have faster loading.
{
2006-03-06 01:41:09 +00:00
snprintf ( altname , sizeof ( altname ) - 1 , " %s_norm " , mt - > name ) ;
2005-04-26 16:04:12 +00:00
tx - > gl_texturenumbumpmap = Mod_LoadHiResTexture ( altname , loadname , true , false , false ) ;
if ( ! tx - > gl_texturenumbumpmap )
tx - > gl_texturenumbumpmap = Mod_LoadHiResTexture ( altname , " bmodels " , true , false , false ) ;
2004-09-30 22:45:08 +00:00
}
if ( ! tx - > gl_texturenumbumpmap )
{
if ( gl_load24bit . value )
{
2006-03-06 01:41:09 +00:00
snprintf ( altname , sizeof ( altname ) - 1 , " %s_bump " , mt - > name ) ;
2005-04-26 16:04:12 +00:00
tx - > gl_texturenumbumpmap = Mod_LoadBumpmapTexture ( altname , loadname ) ;
if ( ! tx - > gl_texturenumbumpmap )
tx - > gl_texturenumbumpmap = Mod_LoadBumpmapTexture ( altname , " bmodels " ) ;
2004-09-30 22:45:08 +00:00
}
else
2006-03-06 01:41:09 +00:00
snprintf ( altname , sizeof ( altname ) - 1 , " %s_bump " , mt - > name ) ;
2004-09-30 22:45:08 +00:00
}
2004-08-22 22:29:09 +00:00
2004-09-01 22:59:56 +00:00
if ( ! ( tx - > gl_texturenumbumpmap ) & & loadmodel - > fromgame ! = fg_halflife )
{
base = ( qbyte * ) ( mt + 1 ) ; //convert to greyscale.
for ( j = 0 ; j < pixels ; j + + )
base [ j ] = ( host_basepal [ base [ j ] * 3 ] + host_basepal [ base [ j ] * 3 + 1 ] + host_basepal [ base [ j ] * 3 + 2 ] ) / 3 ;
2004-08-22 22:29:09 +00:00
2007-05-25 22:16:29 +00:00
tx - > gl_texturenumbumpmap = R_LoadTexture8Bump ( altname , tx - > width , tx - > height , base , true , r_shadow_bumpscale_basetexture . value ) ; //normalise it and then bump it.
2004-09-01 22:59:56 +00:00
}
2004-09-13 03:20:04 +00:00
//don't do any complex quake 8bit -> glossmap. It would likly look a little ugly...
if ( gl_specular . value & & gl_load24bit . value )
{
2006-03-06 01:41:09 +00:00
snprintf ( altname , sizeof ( altname ) - 1 , " %s_gloss " , mt - > name ) ;
2005-04-26 16:04:12 +00:00
tx - > gl_texturenumspec = Mod_LoadHiResTexture ( altname , loadname , true , false , false ) ;
if ( ! tx - > gl_texturenumspec )
tx - > gl_texturenumspec = Mod_LoadHiResTexture ( altname , " bmodels " , true , false , false ) ;
2004-09-13 03:20:04 +00:00
}
2004-08-22 22:29:09 +00:00
}
}
2005-01-18 21:03:46 +00:00
# ifdef Q3SHADERS //load q3 syntax shader last, after the textures inside the bsp have been loaded and stuff.
2006-03-11 03:12:10 +00:00
if ( cls . allow_shaders & & gl_shadeq1 . value & & * gl_shadeq1_name . string )
2005-01-18 21:03:46 +00:00
{
char * star ;
//find the *
if ( ! strcmp ( gl_shadeq1_name . string , " * " ) )
2006-03-11 03:12:10 +00:00
tx - > shader = R_RegisterCustom ( mt - > name , NULL ) ; //just load the regular name.
2005-01-18 21:03:46 +00:00
else if ( ! ( star = strchr ( gl_shadeq1_name . string , ' * ' ) ) | | ( strlen ( gl_shadeq1_name . string ) + strlen ( mt - > name ) + 1 > = sizeof ( altname ) ) ) //it's got to fit.
2006-03-11 03:12:10 +00:00
tx - > shader = R_RegisterCustom ( gl_shadeq1_name . string , NULL ) ;
2005-01-18 21:03:46 +00:00
else
{
strncpy ( altname , gl_shadeq1_name . string , star - gl_shadeq1_name . string ) ; //copy the left
altname [ star - gl_shadeq1_name . string ] = ' \0 ' ;
strcat ( altname , mt - > name ) ; //insert the *
strcat ( altname , star + 1 ) ; //add any final text.
2006-03-11 03:12:10 +00:00
tx - > shader = R_RegisterCustom ( altname , NULL ) ;
2005-01-18 21:03:46 +00:00
}
}
# endif
2004-08-22 22:29:09 +00:00
}
//
// sequence the animations
//
for ( i = 0 ; i < m - > nummiptex ; i + + )
{
tx = loadmodel - > textures [ i ] ;
if ( ! tx | | tx - > name [ 0 ] ! = ' + ' )
continue ;
if ( tx - > anim_next )
2005-07-28 15:22:15 +00:00
continue ; // already sequenced
2004-08-22 22:29:09 +00:00
// find the number of frames in the animation
memset ( anims , 0 , sizeof ( anims ) ) ;
memset ( altanims , 0 , sizeof ( altanims ) ) ;
max = tx - > name [ 1 ] ;
altmax = 0 ;
if ( max > = ' a ' & & max < = ' z ' )
max - = ' a ' - ' A ' ;
if ( max > = ' 0 ' & & max < = ' 9 ' )
{
max - = ' 0 ' ;
altmax = 0 ;
anims [ max ] = tx ;
max + + ;
}
else if ( max > = ' A ' & & max < = ' J ' )
{
altmax = max - ' A ' ;
max = 0 ;
altanims [ altmax ] = tx ;
altmax + + ;
}
else
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Bad animating texture %s \n " , tx - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
for ( j = i + 1 ; j < m - > nummiptex ; j + + )
{
tx2 = loadmodel - > textures [ j ] ;
if ( ! tx2 | | tx2 - > name [ 0 ] ! = ' + ' )
continue ;
if ( strcmp ( tx2 - > name + 2 , tx - > name + 2 ) )
continue ;
num = tx2 - > name [ 1 ] ;
if ( num > = ' a ' & & num < = ' z ' )
num - = ' a ' - ' A ' ;
if ( num > = ' 0 ' & & num < = ' 9 ' )
{
num - = ' 0 ' ;
anims [ num ] = tx2 ;
if ( num + 1 > max )
max = num + 1 ;
}
else if ( num > = ' A ' & & num < = ' J ' )
{
num = num - ' A ' ;
altanims [ num ] = tx2 ;
if ( num + 1 > altmax )
altmax = num + 1 ;
}
else
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Bad animating texture %s \n " , tx - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
}
# define ANIM_CYCLE 2
// link them all together
for ( j = 0 ; j < max ; j + + )
{
tx2 = anims [ j ] ;
if ( ! tx2 )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Missing frame %i of %s \n " , j , tx - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
tx2 - > anim_total = max * ANIM_CYCLE ;
tx2 - > anim_min = j * ANIM_CYCLE ;
tx2 - > anim_max = ( j + 1 ) * ANIM_CYCLE ;
tx2 - > anim_next = anims [ ( j + 1 ) % max ] ;
if ( altmax )
tx2 - > alternate_anims = altanims [ 0 ] ;
}
for ( j = 0 ; j < altmax ; j + + )
{
tx2 = altanims [ j ] ;
if ( ! tx2 )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Missing frame %i of %s \n " , j , tx - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
tx2 - > anim_total = altmax * ANIM_CYCLE ;
tx2 - > anim_min = j * ANIM_CYCLE ;
tx2 - > anim_max = ( j + 1 ) * ANIM_CYCLE ;
tx2 - > anim_next = altanims [ ( j + 1 ) % altmax ] ;
if ( max )
tx2 - > alternate_anims = anims [ 0 ] ;
}
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
void GLMod_NowLoadExternal ( void )
{
extern int gl_bumpmappingpossible ;
int i , width , height ;
qboolean alphaed ;
texture_t * tx ;
2004-09-30 22:45:08 +00:00
if ( loadmodel - > fromgame ! = fg_halflife )
return ;
2004-08-22 22:29:09 +00:00
for ( i = 0 ; i < loadmodel - > numtextures ; i + + )
{
tx = loadmodel - > textures [ i ] ;
if ( ! tx ) //e1m2, this happens
continue ;
if ( ! tx - > gl_texturenum )
{
# ifdef PEXT_BULLETENS
if ( ! R_AddBulleten ( tx ) )
# endif
{
qbyte * data ;
data = W_GetTexture ( tx - > name , & width , & height , & alphaed ) ;
if ( data )
{ //data is from temp hunk, so no need to free.
tx - > alphaed = alphaed ;
}
2005-04-26 16:04:12 +00:00
if ( ! ( tx - > gl_texturenum = Mod_LoadHiResTexture ( tx - > name , loadname , true , false , true ) ) )
if ( ! ( tx - > gl_texturenum = Mod_LoadHiResTexture ( tx - > name , " bmodels " , true , false , true ) ) )
tx - > gl_texturenum = Mod_LoadReplacementTexture ( " light1_4 " , NULL , true , false , true ) ; //a fallback. :/
2004-08-22 22:29:09 +00:00
}
}
if ( ! tx - > gl_texturenumbumpmap & & * tx - > name ! = ' { ' & & gl_bumpmappingpossible & & cls . allow_bump )
{
2005-04-26 16:04:12 +00:00
tx - > gl_texturenumbumpmap = Mod_LoadBumpmapTexture ( va ( " %s_bump " , tx - > name ) , loadname ) ;
if ( ! tx - > gl_texturenumbumpmap )
tx - > gl_texturenumbumpmap = Mod_LoadBumpmapTexture ( va ( " %s_bump " , tx - > name ) , " bmodels " ) ;
2004-08-22 22:29:09 +00:00
if ( ! tx - > gl_texturenumbumpmap )
{
qbyte * data ;
qbyte * heightmap ;
int width , height ;
int j ;
data = W_GetTexture ( tx - > name , & width , & height , & alphaed ) ;
if ( ! data )
continue ;
heightmap = Hunk_TempAllocMore ( width * height ) ;
for ( j = 0 ; j < width * height ; j + + )
{
* heightmap + + = ( data [ j * 4 + 0 ] + data [ j * 4 + 1 ] + data [ j * 4 + 2 ] ) / 3 ;
}
2007-05-25 22:16:29 +00:00
tx - > gl_texturenumbumpmap = R_LoadTexture8Bump ( va ( " %s_bump " , tx - > name ) , width , height , heightmap - j , true , r_shadow_bumpscale_basetexture . value ) ;
2004-08-22 22:29:09 +00:00
}
}
}
}
qbyte lmgamma [ 256 ] ;
void BuildLightMapGammaTable ( float g , float c )
{
int i , inf ;
// g = bound (0.1, g, 3);
// c = bound (1, c, 3);
if ( g = = 1 & & c = = 1 )
{
for ( i = 0 ; i < 256 ; i + + )
lmgamma [ i ] = i ;
return ;
}
for ( i = 0 ; i < 256 ; i + + )
{
inf = 255 * pow ( ( i + 0.5 ) / 255.5 * c , g ) + 0.5 ;
if ( inf < 0 )
inf = 0 ;
else if ( inf > 255 )
inf = 255 ;
lmgamma [ i ] = inf ;
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadLighting
= = = = = = = = = = = = = = = = =
*/
void GLMod_LoadLighting ( lump_t * l )
{
qbyte * luxdata = NULL ;
2004-10-19 16:10:14 +00:00
int mapcomeswith24bitcolouredlighting = false ;
2005-08-06 22:39:28 +00:00
loadmodel - > engineflags & = ~ MDLF_RGBLIGHTING ;
2004-08-22 22:29:09 +00:00
//lit file light intensity is made to match the world's light intensity.
2005-09-08 22:52:46 +00:00
// if (cls.allow_lightmapgamma)
// BuildLightMapGammaTable(0.6, 2);
// else
2004-08-22 22:29:09 +00:00
BuildLightMapGammaTable ( 1 , 1 ) ;
2004-10-07 13:16:43 +00:00
loadmodel - > lightdata = NULL ;
2004-08-22 22:29:09 +00:00
loadmodel - > deluxdata = NULL ;
2004-10-07 13:16:43 +00:00
if ( ! l - > filelen )
{
return ;
}
2004-10-19 16:10:14 +00:00
if ( loadmodel - > fromgame = = fg_halflife | | loadmodel - > fromgame = = fg_quake2 | | loadmodel - > fromgame = = fg_quake3 )
mapcomeswith24bitcolouredlighting = true ;
if ( ! mapcomeswith24bitcolouredlighting & & r_loadlits . value & & gl_bumpmappingpossible ) //fixme: adjust the light intensities.
2004-08-22 22:29:09 +00:00
{ //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous.
char luxname [ MAX_QPATH ] ;
if ( ! luxdata )
{
strcpy ( luxname , loadmodel - > name ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( loadmodel - > name , luxname , sizeof ( luxname ) ) ;
COM_DefaultExtension ( luxname , " .lux " , sizeof ( luxname ) ) ;
2004-08-22 22:29:09 +00:00
luxdata = COM_LoadHunkFile ( luxname ) ;
}
if ( ! luxdata )
{
strcpy ( luxname , " luxs/ " ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , luxname + 5 , sizeof ( luxname ) - 5 ) ;
2004-08-22 22:29:09 +00:00
strcat ( luxname , " .lux " ) ;
luxdata = COM_LoadHunkFile ( luxname ) ;
}
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , luxname + 5 , sizeof ( luxname ) - 5 ) ;
2004-08-22 22:29:09 +00:00
strcat ( luxname , " .lux " ) ;
if ( luxdata )
{
if ( l - > filelen & & l - > filelen ! = ( com_filesize - 8 ) / 3 )
{
Con_Printf ( " deluxmap \" %s \" doesn't match level. Ignored. \n " , luxname ) ;
luxdata = NULL ;
}
else if ( luxdata [ 0 ] = = ' Q ' & & luxdata [ 1 ] = = ' L ' & & luxdata [ 2 ] = = ' I ' & & luxdata [ 3 ] = = ' T ' )
{
if ( LittleLong ( * ( int * ) & luxdata [ 4 ] ) = = 1 )
{
luxdata + = 8 ;
loadmodel - > deluxdata = luxdata ;
}
else
{
Con_Printf ( " \" %s \" isn't a version 1 deluxmap \n " , luxname ) ;
luxdata = NULL ;
}
}
else
{
Con_Printf ( " lit \" %s \" isn't a deluxmap \n " , luxname ) ;
luxdata = NULL ;
}
}
}
2004-10-19 16:10:14 +00:00
if ( ! mapcomeswith24bitcolouredlighting & & r_loadlits . value )
2004-08-22 22:29:09 +00:00
{
qbyte * litdata = NULL ;
2004-09-30 23:02:52 +00:00
char * litname ;
char litnamemaps [ MAX_QPATH ] ;
char litnamelits [ MAX_QPATH ] ;
int depthmaps ;
int depthlits ;
2004-08-22 22:29:09 +00:00
{
2004-09-30 23:02:52 +00:00
strcpy ( litnamemaps , loadmodel - > name ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( loadmodel - > name , litnamemaps , sizeof ( litnamemaps ) ) ;
COM_DefaultExtension ( litnamemaps , " .lit " , sizeof ( litnamemaps ) ) ;
2004-09-30 23:02:52 +00:00
depthmaps = COM_FDepthFile ( litnamemaps , false ) ;
2004-08-22 22:29:09 +00:00
}
{
2004-09-30 23:02:52 +00:00
strcpy ( litnamelits , " lits/ " ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , litnamelits + 5 , sizeof ( litnamelits ) - 5 ) ;
2004-09-30 23:02:52 +00:00
strcat ( litnamelits , " .lit " ) ;
depthlits = COM_FDepthFile ( litnamelits , false ) ;
}
2004-08-22 22:29:09 +00:00
2004-09-30 23:02:52 +00:00
if ( depthmaps < = depthlits )
litname = litnamemaps ; //maps has priority over lits
else
{
litname = litnamelits ;
2004-08-22 22:29:09 +00:00
}
2004-09-30 23:02:52 +00:00
litdata = COM_LoadHunkFile ( litname ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , litname + 5 , sizeof ( litname ) - 5 ) ;
2004-08-22 22:29:09 +00:00
strcat ( litname , " .lit " ) ;
if ( litdata & & ( litdata [ 0 ] = = ' Q ' & & litdata [ 1 ] = = ' L ' & & litdata [ 2 ] = = ' I ' & & litdata [ 3 ] = = ' T ' ) )
{
if ( LittleLong ( * ( int * ) & litdata [ 4 ] ) = = 1 & & l - > filelen & & l - > filelen ! = ( com_filesize - 8 ) / 3 )
Con_Printf ( " lit \" %s \" doesn't match level. Ignored. \n " , litname ) ;
else if ( LittleLong ( * ( int * ) & litdata [ 4 ] ) ! = 1 )
Con_Printf ( " lit \" %s \" isn't version 1. \n " , litname ) ;
else
{
float prop ;
int i ;
qbyte * normal ;
//load it
loadmodel - > lightdata = litdata + 8 ;
2005-08-06 22:39:28 +00:00
loadmodel - > engineflags | = MDLF_RGBLIGHTING ;
2004-08-22 22:29:09 +00:00
//now some cheat protection.
normal = mod_base + l - > fileofs ;
litdata = loadmodel - > lightdata ;
for ( i = 0 ; i < l - > filelen ; i + + ) //force it to the same intensity. (or less, depending on how you see it...)
{
# define m(a, b, c) (a>(b>c?b:c)?a:(b>c?b:c))
prop = ( float ) m ( litdata [ 0 ] , litdata [ 1 ] , litdata [ 2 ] ) ;
if ( ! prop )
{
litdata [ 0 ] = lmgamma [ * normal ] ;
litdata [ 1 ] = lmgamma [ * normal ] ;
litdata [ 2 ] = lmgamma [ * normal ] ;
}
else
{
prop = lmgamma [ * normal ] / prop ;
litdata [ 0 ] * = prop ;
litdata [ 1 ] * = prop ;
litdata [ 2 ] * = prop ;
}
normal + + ;
litdata + = 3 ;
}
//end anti-cheat
}
}
else if ( litdata )
Con_Printf ( " lit \" %s \" isn't a lit \n " , litname ) ;
// else
//failed to find
}
2004-10-19 16:10:14 +00:00
if ( mapcomeswith24bitcolouredlighting )
2005-08-06 22:39:28 +00:00
loadmodel - > engineflags | = MDLF_RGBLIGHTING ;
2004-08-22 22:29:09 +00:00
# ifdef RUNTIMELIGHTING
2005-08-06 22:39:28 +00:00
else if ( r_loadlits . value = = 2 & & ! lightmodel & & ( ! ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) | | ( ! luxdata & & gl_bumpmappingpossible ) ) )
2004-08-22 22:29:09 +00:00
{
qbyte * litdata = NULL ;
int i ;
qbyte * normal ;
2005-08-06 22:39:28 +00:00
writelitfile = ! ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) ;
loadmodel - > engineflags | = MDLF_RGBLIGHTING ;
2004-08-22 22:29:09 +00:00
loadmodel - > lightdata = Hunk_AllocName ( l - > filelen * 3 + 8 , loadname ) ;
strcpy ( loadmodel - > lightdata , " QLIT " ) ;
( ( int * ) loadmodel - > lightdata ) [ 1 ] = LittleLong ( 1 ) ;
loadmodel - > lightdata + = 8 ;
litdata = loadmodel - > lightdata ;
normal = mod_base + l - > fileofs ;
for ( i = 0 ; i < l - > filelen ; i + + )
{
* litdata + + = lmgamma [ * normal ] ;
* litdata + + = lmgamma [ * normal ] ;
* litdata + + = lmgamma [ * normal ] ;
normal + + ;
}
if ( gl_bumpmappingpossible )
{
loadmodel - > deluxdata = Hunk_AllocName ( l - > filelen * 3 + 8 , loadname ) ;
strcpy ( loadmodel - > deluxdata , " QLIT " ) ;
( ( int * ) loadmodel - > deluxdata ) [ 1 ] = LittleLong ( 1 ) ;
loadmodel - > deluxdata + = 8 ;
litdata = loadmodel - > deluxdata ;
{
for ( i = 0 ; i < l - > filelen * 3 ; i + + )
* litdata + + = 0.5f * 255 ;
}
}
numlightdata = l - > filelen ;
lightmodel = loadmodel ;
relitsurface = 0 ;
return ;
}
# endif
2004-10-07 13:16:43 +00:00
if ( loadmodel - > lightdata )
2005-05-18 01:40:01 +00:00
{
2005-08-06 22:39:28 +00:00
if ( ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) & & r_lightmap_saturation . value ! = 1.0f )
2005-05-18 01:40:01 +00:00
{
// desaturate lightmap according to cvar
SaturateR8G8B8 ( loadmodel - > lightdata , l - > filelen , r_lightmap_saturation . value ) ;
}
2004-10-07 13:16:43 +00:00
return ;
2005-05-18 01:40:01 +00:00
}
2004-10-07 13:16:43 +00:00
2004-08-22 22:29:09 +00:00
loadmodel - > lightdata = Hunk_AllocName ( l - > filelen , loadname ) ;
{
int i ;
qbyte * in , * out ;
in = mod_base + l - > fileofs ;
out = loadmodel - > lightdata ;
for ( i = 0 ; i < l - > filelen ; i + + )
{
* out + + = lmgamma [ * in + + ] ;
}
2005-05-18 01:40:01 +00:00
2005-08-06 22:39:28 +00:00
if ( ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) & & r_lightmap_saturation . value ! = 1.0f )
2005-05-18 01:40:01 +00:00
SaturateR8G8B8 ( loadmodel - > lightdata , l - > filelen , r_lightmap_saturation . value ) ;
2004-08-22 22:29:09 +00:00
}
//memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadVisibility
= = = = = = = = = = = = = = = = =
*/
void GLMod_LoadVisibility ( lump_t * l )
{
if ( ! l - > filelen )
{
loadmodel - > visdata = NULL ;
return ;
}
loadmodel - > visdata = Hunk_AllocName ( l - > filelen , loadname ) ;
memcpy ( loadmodel - > visdata , mod_base + l - > fileofs , l - > filelen ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadEntities
= = = = = = = = = = = = = = = = =
*/
void GLMod_LoadEntities ( lump_t * l )
{
if ( ! l - > filelen )
{
loadmodel - > entities = NULL ;
return ;
}
2006-03-05 03:50:54 +00:00
loadmodel - > entities = Hunk_AllocName ( l - > filelen + 1 , loadname ) ;
2004-08-22 22:29:09 +00:00
memcpy ( loadmodel - > entities , mod_base + l - > fileofs , l - > filelen ) ;
2006-03-05 03:50:54 +00:00
loadmodel - > entities [ l - > filelen ] = 0 ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadVertexes
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadVertexes ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
dvertex_t * in ;
mvertex_t * out ;
int i , count ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > vertexes = out ;
loadmodel - > numvertexes = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
out - > position [ 0 ] = LittleFloat ( in - > point [ 0 ] ) ;
out - > position [ 1 ] = LittleFloat ( in - > point [ 1 ] ) ;
out - > position [ 2 ] = LittleFloat ( in - > point [ 2 ] ) ;
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSubmodels
= = = = = = = = = = = = = = = = =
*/
static qboolean hexen2map ;
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadSubmodels ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
dq1model_t * inq ;
dh2model_t * inh ;
mmodel_t * out ;
int i , j , count ;
//this is crazy!
inq = ( void * ) ( mod_base + l - > fileofs ) ;
inh = ( void * ) ( mod_base + l - > fileofs ) ;
if ( ! inq - > numfaces )
{
hexen2map = true ;
if ( l - > filelen % sizeof ( * inh ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * inh ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > submodels = out ;
loadmodel - > numsubmodels = count ;
for ( i = 0 ; i < count ; i + + , inh + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{ // spread the mins / maxs by a pixel
out - > mins [ j ] = LittleFloat ( inh - > mins [ j ] ) - 1 ;
out - > maxs [ j ] = LittleFloat ( inh - > maxs [ j ] ) + 1 ;
out - > origin [ j ] = LittleFloat ( inh - > origin [ j ] ) ;
}
for ( j = 0 ; j < MAX_MAP_HULLSDH2 ; j + + )
{
out - > headnode [ j ] = LittleLong ( inh - > headnode [ j ] ) ;
}
for ( ; j < MAX_MAP_HULLSM ; j + + )
out - > headnode [ j ] = 0 ;
for ( j = 0 ; j < MAX_MAP_HULLSDH2 ; j + + )
out - > hullavailable [ j ] = true ;
for ( ; j < MAX_MAP_HULLSM ; j + + )
out - > hullavailable [ j ] = false ;
out - > visleafs = LittleLong ( inh - > visleafs ) ;
out - > firstface = LittleLong ( inh - > firstface ) ;
out - > numfaces = LittleLong ( inh - > numfaces ) ;
}
}
else
{
hexen2map = false ;
if ( l - > filelen % sizeof ( * inq ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * inq ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > submodels = out ;
loadmodel - > numsubmodels = count ;
for ( i = 0 ; i < count ; i + + , inq + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{ // spread the mins / maxs by a pixel
out - > mins [ j ] = LittleFloat ( inq - > mins [ j ] ) - 1 ;
out - > maxs [ j ] = LittleFloat ( inq - > maxs [ j ] ) + 1 ;
out - > origin [ j ] = LittleFloat ( inq - > origin [ j ] ) ;
}
for ( j = 0 ; j < MAX_MAP_HULLSDQ1 ; j + + )
{
out - > headnode [ j ] = LittleLong ( inq - > headnode [ j ] ) ;
}
for ( ; j < MAX_MAP_HULLSM ; j + + )
out - > headnode [ j ] = 0 ;
for ( j = 0 ; j < 3 ; j + + )
out - > hullavailable [ j ] = true ;
for ( ; j < MAX_MAP_HULLSM ; j + + )
out - > hullavailable [ j ] = false ;
out - > visleafs = LittleLong ( inq - > visleafs ) ;
out - > firstface = LittleLong ( inq - > firstface ) ;
out - > numfaces = LittleLong ( inq - > numfaces ) ;
}
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadEdges
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadEdges ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
dedge_t * in ;
medge_t * out ;
int i , count ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( ( count + 1 ) * sizeof ( * out ) , loadname ) ;
loadmodel - > edges = out ;
loadmodel - > numedges = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
out - > v [ 0 ] = ( unsigned short ) LittleShort ( in - > v [ 0 ] ) ;
out - > v [ 1 ] = ( unsigned short ) LittleShort ( in - > v [ 1 ] ) ;
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadTexinfo
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadTexinfo ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
texinfo_t * in ;
mtexinfo_t * out ;
int i , j , count ;
int miptex ;
float len1 , len2 ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > texinfo = out ;
loadmodel - > numtexinfo = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 8 ; j + + )
out - > vecs [ 0 ] [ j ] = LittleFloat ( in - > vecs [ 0 ] [ j ] ) ;
len1 = Length ( out - > vecs [ 0 ] ) ;
len2 = Length ( out - > vecs [ 1 ] ) ;
len1 = ( len1 + len2 ) / 2 ;
if ( len1 < 0.32 )
out - > mipadjust = 4 ;
else if ( len1 < 0.49 )
out - > mipadjust = 3 ;
else if ( len1 < 0.99 )
out - > mipadjust = 2 ;
else
out - > mipadjust = 1 ;
#if 0
if ( len1 + len2 < 0.001 )
out - > mipadjust = 1 ; // don't crash
else
out - > mipadjust = 1 / floor ( ( len1 + len2 ) / 2 + 0.1 ) ;
# endif
miptex = LittleLong ( in - > miptex ) ;
out - > flags = LittleLong ( in - > flags ) ;
2004-12-29 03:22:09 +00:00
if ( ! loadmodel - > textures | | miptex < 0 | | miptex > = loadmodel - > numtextures )
2004-08-22 22:29:09 +00:00
{
out - > texture = r_notexture_mip ; // checkerboard texture
out - > flags = 0 ;
}
else
{
out - > texture = loadmodel - > textures [ miptex ] ;
if ( ! out - > texture )
{
out - > texture = r_notexture_mip ; // texture not found
out - > flags = 0 ;
}
}
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = =
CalcSurfaceExtents
Fills in s - > texturemins [ ] and s - > extents [ ]
= = = = = = = = = = = = = = = =
*/
void CalcSurfaceExtents ( msurface_t * s ) ;
/*
{
float mins [ 2 ] , maxs [ 2 ] , val ;
int i , j , e ;
mvertex_t * v ;
mtexinfo_t * tex ;
int bmins [ 2 ] , bmaxs [ 2 ] ;
mins [ 0 ] = mins [ 1 ] = 999999 ;
maxs [ 0 ] = maxs [ 1 ] = - 99999 ;
tex = s - > texinfo ;
for ( i = 0 ; i < s - > numedges ; i + + )
{
e = loadmodel - > surfedges [ s - > firstedge + i ] ;
if ( e > = 0 )
v = & loadmodel - > vertexes [ loadmodel - > edges [ e ] . v [ 0 ] ] ;
else
v = & loadmodel - > vertexes [ loadmodel - > edges [ - e ] . v [ 1 ] ] ;
for ( j = 0 ; j < 2 ; j + + )
{
val = v - > position [ 0 ] * tex - > vecs [ j ] [ 0 ] +
v - > position [ 1 ] * tex - > vecs [ j ] [ 1 ] +
v - > position [ 2 ] * tex - > vecs [ j ] [ 2 ] +
tex - > vecs [ j ] [ 3 ] ;
if ( val < mins [ j ] )
mins [ j ] = val ;
if ( val > maxs [ j ] )
maxs [ j ] = val ;
}
}
for ( i = 0 ; i < 2 ; i + + )
{
bmins [ i ] = floor ( mins [ i ] / 16 ) ;
bmaxs [ i ] = ceil ( maxs [ i ] / 16 ) ;
s - > texturemins [ i ] = bmins [ i ] * 16 ;
s - > extents [ i ] = ( bmaxs [ i ] - bmins [ i ] ) * 16 ;
// if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 ) //q2 uses 512.
// Sys_Error ("Bad surface extents");
}
}
*/
/*
= = = = = = = = = = = = = = = = =
Mod_LoadFaces
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadFaces ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
dface_t * in ;
msurface_t * out ;
int i , count , surfnum ;
int planenum , side ;
2004-12-29 03:22:09 +00:00
int tn ;
2004-08-22 22:29:09 +00:00
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > surfaces = out ;
loadmodel - > numsurfaces = count ;
for ( surfnum = 0 ; surfnum < count ; surfnum + + , in + + , out + + )
{
out - > firstedge = LittleLong ( in - > firstedge ) ;
out - > numedges = LittleShort ( in - > numedges ) ;
out - > flags = 0 ;
planenum = LittleShort ( in - > planenum ) ;
side = LittleShort ( in - > side ) ;
if ( side )
out - > flags | = SURF_PLANEBACK ;
out - > plane = loadmodel - > planes + planenum ;
2004-12-29 03:22:09 +00:00
tn = LittleShort ( in - > texinfo ) ;
if ( tn < 0 | | tn > = loadmodel - > numtexinfo )
Host_EndGame ( " Hey! That map has texinfos out of bounds! \n " ) ;
out - > texinfo = loadmodel - > texinfo + tn ;
2004-08-22 22:29:09 +00:00
CalcSurfaceExtents ( out ) ;
// lighting info
for ( i = 0 ; i < MAXLIGHTMAPS ; i + + )
out - > styles [ i ] = in - > styles [ i ] ;
i = LittleLong ( in - > lightofs ) ;
if ( i = = - 1 )
out - > samples = NULL ;
2005-08-06 22:39:28 +00:00
else if ( ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) & & loadmodel - > fromgame ! = fg_halflife )
2004-08-22 22:29:09 +00:00
out - > samples = loadmodel - > lightdata + i * 3 ;
else
out - > samples = loadmodel - > lightdata + i ;
if ( ! out - > texinfo - > texture )
continue ;
// set the drawing flags flag
if ( ! Q_strncmp ( out - > texinfo - > texture - > name , " sky " , 3 ) ) // sky
{
out - > flags | = ( SURF_DRAWSKY | SURF_DRAWTILED ) ;
continue ;
}
if ( ! Q_strncmp ( out - > texinfo - > texture - > name , " * " , 1 ) ) // turbulent
{
out - > flags | = ( SURF_DRAWTURB | SURF_DRAWTILED ) ;
for ( i = 0 ; i < 2 ; i + + )
{
out - > extents [ i ] = 16384 ;
out - > texturemins [ i ] = - 8192 ;
}
continue ;
}
if ( ! Q_strncmp ( out - > texinfo - > texture - > name , " { " , 1 ) ) // alpha
{
out - > flags | = ( SURF_DRAWALPHA ) ;
continue ;
}
if ( ! Q_strncmp ( out - > texinfo - > texture - > name , " glass " , 5 ) ) // alpha
{
out - > flags | = ( SURF_DRAWALPHA ) ;
continue ;
}
if ( out - > flags & SURF_DRAWALPHA )
out - > flags & = ~ SURF_DRAWALPHA ;
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_SetParent
= = = = = = = = = = = = = = = = =
*/
void GLMod_SetParent ( mnode_t * node , mnode_t * parent )
{
if ( ! node )
return ;
node - > parent = parent ;
if ( node - > contents < 0 )
return ;
GLMod_SetParent ( node - > children [ 0 ] , node ) ;
GLMod_SetParent ( node - > children [ 1 ] , node ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadNodes
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadNodes ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
int i , j , count , p ;
dnode_t * in ;
mnode_t * out ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > nodes = out ;
loadmodel - > numnodes = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
out - > minmaxs [ j ] = LittleShort ( in - > mins [ j ] ) ;
out - > minmaxs [ 3 + j ] = LittleShort ( in - > maxs [ j ] ) ;
}
p = LittleLong ( in - > planenum ) ;
out - > plane = loadmodel - > planes + p ;
out - > firstsurface = LittleShort ( in - > firstface ) ;
out - > numsurfaces = LittleShort ( in - > numfaces ) ;
for ( j = 0 ; j < 2 ; j + + )
{
p = LittleShort ( in - > children [ j ] ) ;
if ( p > = 0 )
out - > children [ j ] = loadmodel - > nodes + p ;
else
out - > children [ j ] = ( mnode_t * ) ( loadmodel - > leafs + ( - 1 - p ) ) ;
}
}
GLMod_SetParent ( loadmodel - > nodes , NULL ) ; // sets nodes and leafs
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadLeafs
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadLeafs ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
dleaf_t * in ;
mleaf_t * out ;
int i , j , count , p ;
// char s[80];
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > leafs = out ;
loadmodel - > numleafs = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
out - > minmaxs [ j ] = LittleShort ( in - > mins [ j ] ) ;
out - > minmaxs [ 3 + j ] = LittleShort ( in - > maxs [ j ] ) ;
}
p = LittleLong ( in - > contents ) ;
out - > contents = p ;
out - > firstmarksurface = loadmodel - > marksurfaces +
LittleShort ( in - > firstmarksurface ) ;
out - > nummarksurfaces = LittleShort ( in - > nummarksurfaces ) ;
p = LittleLong ( in - > visofs ) ;
if ( p = = - 1 )
out - > compressed_vis = NULL ;
else
out - > compressed_vis = loadmodel - > visdata + p ;
out - > efrags = NULL ;
for ( j = 0 ; j < 4 ; j + + )
out - > ambient_sound_level [ j ] = in - > ambient_level [ j ] ;
# ifndef CLIENTONLY
if ( ! isDedicated )
# endif
{
// gl underwater warp
if ( out - > contents ! = Q1CONTENTS_EMPTY )
{
for ( j = 0 ; j < out - > nummarksurfaces ; j + + )
out - > firstmarksurface [ j ] - > flags | = SURF_UNDERWATER ;
}
if ( isnotmap )
{
for ( j = 0 ; j < out - > nummarksurfaces ; j + + )
out - > firstmarksurface [ j ] - > flags | = SURF_DONTWARP ;
}
}
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
//these are used to boost other info sizes
int numsuplementryplanes ;
int numsuplementryclipnodes ;
void * suplementryclipnodes ;
void * suplementryplanes ;
void * crouchhullfile ;
qbyte * COM_LoadMallocFile ( char * path ) ;
void GLMod_LoadCrouchHull ( void )
{
int i , h ;
int numsm ;
char crouchhullname [ MAX_QPATH ] ;
int * data ;
int hulls ;
// dclipnode_t *cn;
memset ( loadmodel - > hulls , 0 , sizeof ( loadmodel - > hulls ) ) ; //ensure all the sizes are 0 (this is how we check for the existance of a hull
numsuplementryplanes = numsuplementryclipnodes = 0 ;
//find a name for a ccn and try to load it.
strcpy ( crouchhullname , loadmodel - > name ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( loadmodel - > name , crouchhullname , sizeof ( crouchhullname ) ) ;
COM_DefaultExtension ( crouchhullname , " .crh " , sizeof ( crouchhullname ) ) ; //crouch hull
2004-08-22 22:29:09 +00:00
crouchhullfile = COM_LoadMallocFile ( crouchhullname ) ; //or otherwise temporary storage. load on hunk if you want, but that would be a waste.
if ( ! crouchhullfile )
return ;
data = crouchhullfile ;
if ( LittleLong ( * data + + ) ! = ( ' S ' ) + ( ' C ' < < 8 ) + ( ' N ' < < 16 ) + ( ' P ' < < 24 ) ) //make sure it's the right version
return ;
if ( LittleLong ( * data ) = = 2 )
{
data + + ;
hulls = LittleLong ( * data + + ) ;
}
else
return ;
if ( hulls > MAX_MAP_HULLSM - MAX_MAP_HULLSDQ1 )
{
return ;
}
numsm = LittleLong ( * data + + ) ;
2007-10-05 18:08:47 +00:00
if ( numsm ! = loadmodel - > numsubmodels ) //not compatible
2004-08-22 22:29:09 +00:00
return ;
numsuplementryplanes = LittleLong ( * data + + ) ;
numsuplementryclipnodes = LittleLong ( * data + + ) ;
for ( h = 0 ; h < hulls ; h + + )
{
for ( i = 0 ; i < 3 ; i + + )
loadmodel - > hulls [ 3 + h ] . clip_mins [ i ] = LittleLong ( * data + + ) ;
for ( i = 0 ; i < 3 ; i + + )
loadmodel - > hulls [ 3 + h ] . clip_maxs [ i ] = LittleLong ( * data + + ) ;
for ( i = 0 ; i < numsm ; i + + ) //load headnode references
{
loadmodel - > submodels [ i ] . headnode [ 3 + h ] = LittleLong ( * data ) + 1 ;
data + + ;
}
}
suplementryplanes = data ;
suplementryclipnodes = ( qbyte * ) data + sizeof ( dplane_t ) * numsuplementryplanes ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadClipnodes
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadClipnodes ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
dclipnode_t * in , * out ;
int i , count ;
hull_t * hull ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( ( count + numsuplementryclipnodes ) * sizeof ( * out ) , loadname ) ; //space for both
loadmodel - > clipnodes = out ;
loadmodel - > numclipnodes = count + numsuplementryclipnodes ;
if ( hexen2map )
{ //hexen2.
hexen2map = false ;
hull = & loadmodel - > hulls [ 1 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 24 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 32 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 2 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 24 ;
hull - > clip_mins [ 1 ] = - 24 ;
hull - > clip_mins [ 2 ] = - 20 ;
hull - > clip_maxs [ 0 ] = 24 ;
hull - > clip_maxs [ 1 ] = 24 ;
hull - > clip_maxs [ 2 ] = 20 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 3 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 12 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 16 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 4 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 40 ;
hull - > clip_mins [ 1 ] = - 40 ;
hull - > clip_mins [ 2 ] = - 42 ;
hull - > clip_maxs [ 0 ] = 40 ;
hull - > clip_maxs [ 1 ] = 40 ;
hull - > clip_maxs [ 2 ] = 42 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 5 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 48 ;
hull - > clip_mins [ 1 ] = - 48 ;
2006-03-23 19:22:12 +00:00
hull - > clip_mins [ 2 ] = - 50 - 24 ;
2004-08-22 22:29:09 +00:00
hull - > clip_maxs [ 0 ] = 48 ;
hull - > clip_maxs [ 1 ] = 48 ;
hull - > clip_maxs [ 2 ] = 50 ;
hull - > available = true ;
}
else if ( loadmodel - > fromgame = = fg_halflife )
{
hull = & loadmodel - > hulls [ 1 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 36 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 36 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 2 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 32 ;
hull - > clip_mins [ 1 ] = - 32 ;
hull - > clip_mins [ 2 ] = - 32 ;
hull - > clip_maxs [ 0 ] = 32 ;
hull - > clip_maxs [ 1 ] = 32 ;
hull - > clip_maxs [ 2 ] = 32 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 3 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 18 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 18 ;
hull - > available = true ;
}
else
{
hull = & loadmodel - > hulls [ 1 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 24 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 32 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 2 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 32 ;
hull - > clip_mins [ 1 ] = - 32 ;
hull - > clip_mins [ 2 ] = - 24 ;
hull - > clip_maxs [ 0 ] = 32 ;
hull - > clip_maxs [ 1 ] = 32 ;
hull - > clip_maxs [ 2 ] = 64 ;
hull - > available = true ;
hull = & loadmodel - > hulls [ 3 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 6 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 30 ;
hull - > available = false ;
}
for ( i = 0 ; i < count ; i + + , out + + , in + + )
{
out - > planenum = LittleLong ( in - > planenum ) ;
out - > children [ 0 ] = LittleShort ( in - > children [ 0 ] ) ;
out - > children [ 1 ] = LittleShort ( in - > children [ 1 ] ) ;
}
if ( numsuplementryclipnodes ) //now load the crouch ones.
{
for ( i = 3 ; i < MAX_MAP_HULLSM ; i + + )
{
hull = & loadmodel - > hulls [ i ] ;
hull - > planes = suplementryplanes ;
hull - > clipnodes = out - 1 ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = numsuplementryclipnodes ;
hull - > available = true ;
}
in = suplementryclipnodes ;
for ( i = 0 ; i < numsuplementryclipnodes ; i + + , out + + , in + + )
{
out - > planenum = LittleLong ( in - > planenum ) ;
out - > children [ 0 ] = LittleShort ( in - > children [ 0 ] ) ;
out - > children [ 0 ] + = out - > children [ 0 ] > = 0 ? 1 : 0 ;
out - > children [ 1 ] = LittleShort ( in - > children [ 1 ] ) ;
out - > children [ 1 ] + = out - > children [ 1 ] > = 0 ? 1 : 0 ;
}
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_MakeHull0
Deplicate the drawing hull structure as a clipping hull
= = = = = = = = = = = = = = = = =
*/
void GLMod_MakeHull0 ( void )
{
mnode_t * in , * child ;
dclipnode_t * out ;
int i , j , count ;
hull_t * hull ;
2005-04-16 16:21:27 +00:00
2004-08-22 22:29:09 +00:00
hull = & loadmodel - > hulls [ 0 ] ;
2005-04-16 16:21:27 +00:00
2004-08-22 22:29:09 +00:00
in = loadmodel - > nodes ;
count = loadmodel - > numnodes ;
2005-04-16 16:21:27 +00:00
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
2004-08-22 22:29:09 +00:00
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
for ( i = 0 ; i < count ; i + + , out + + , in + + )
{
out - > planenum = in - > plane - loadmodel - > planes ;
for ( j = 0 ; j < 2 ; j + + )
{
child = in - > children [ j ] ;
if ( child - > contents < 0 )
out - > children [ j ] = child - > contents ;
else
out - > children [ j ] = child - loadmodel - > nodes ;
}
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadMarksurfaces
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadMarksurfaces ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
int i , j , count ;
short * in ;
msurface_t * * out ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > marksurfaces = out ;
loadmodel - > nummarksurfaces = count ;
for ( i = 0 ; i < count ; i + + )
{
j = LittleShort ( in [ i ] ) ;
if ( j < 0 | | j > = loadmodel - > numsurfaces )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Mod_ParseMarksurfaces: bad surface number \n " ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
out [ i ] = loadmodel - > surfaces + j ;
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSurfedges
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadSurfedges ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
int i , count ;
int * in , * out ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > surfedges = out ;
loadmodel - > numsurfedges = count ;
for ( i = 0 ; i < count ; i + + )
out [ i ] = LittleLong ( in [ i ] ) ;
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadPlanes
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadPlanes ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
int i , j ;
mplane_t * out ;
dplane_t * in ;
int count ;
int bits ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( ( count + numsuplementryplanes ) * 2 * sizeof ( * out ) , loadname ) ;
loadmodel - > planes = out ;
loadmodel - > numplanes = count + numsuplementryplanes ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
bits = 0 ;
for ( j = 0 ; j < 3 ; j + + )
{
out - > normal [ j ] = LittleFloat ( in - > normal [ j ] ) ;
if ( out - > normal [ j ] < 0 )
bits | = 1 < < j ;
}
out - > dist = LittleFloat ( in - > dist ) ;
out - > type = LittleLong ( in - > type ) ;
out - > signbits = bits ;
}
if ( numsuplementryplanes )
{
in = suplementryplanes ;
suplementryplanes = out ;
for ( i = 0 ; i < numsuplementryplanes ; i + + , in + + , out + + )
{
bits = 0 ;
for ( j = 0 ; j < 3 ; j + + )
{
out - > normal [ j ] = LittleFloat ( in - > normal [ j ] ) ;
if ( out - > normal [ j ] < 0 )
bits | = 1 < < j ;
}
out - > dist = LittleFloat ( in - > dist ) ;
out - > type = LittleLong ( in - > type ) ;
out - > signbits = bits ;
}
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
RadiusFromBounds
= = = = = = = = = = = = = = = = =
*/
float RadiusFromBounds ( vec3_t mins , vec3_t maxs ) ;
/*
{
int i ;
vec3_t corner ;
for ( i = 0 ; i < 3 ; i + + )
{
corner [ i ] = fabs ( mins [ i ] ) > fabs ( maxs [ i ] ) ? fabs ( mins [ i ] ) : fabs ( maxs [ i ] ) ;
}
return Length ( corner ) ;
}
*/
//combination of R_AddDynamicLights and R_MarkLights
void GLR_StainSurf ( msurface_t * surf , float * parms ) ;
static void Q1BSP_StainNode ( mnode_t * node , float * parms )
{
2007-05-25 22:16:29 +00:00
# ifdef RGLQUAKE
2004-08-22 22:29:09 +00:00
mplane_t * splitplane ;
float dist ;
msurface_t * surf ;
int i ;
if ( node - > contents < 0 )
return ;
splitplane = node - > plane ;
dist = DotProduct ( ( parms + 1 ) , splitplane - > normal ) - splitplane - > dist ;
if ( dist > ( * parms ) )
{
Q1BSP_StainNode ( node - > children [ 0 ] , parms ) ;
return ;
}
if ( dist < ( - * parms ) )
{
Q1BSP_StainNode ( node - > children [ 1 ] , parms ) ;
return ;
}
// mark the polygons
surf = cl . worldmodel - > surfaces + node - > firstsurface ;
for ( i = 0 ; i < node - > numsurfaces ; i + + , surf + + )
{
if ( surf - > flags & ~ ( SURF_DONTWARP | SURF_PLANEBACK ) )
continue ;
GLR_StainSurf ( surf , parms ) ;
}
Q1BSP_StainNode ( node - > children [ 0 ] , parms ) ;
Q1BSP_StainNode ( node - > children [ 1 ] , parms ) ;
2007-05-25 22:16:29 +00:00
# endif
2004-08-22 22:29:09 +00:00
}
void Q1BSP_MarkLights ( dlight_t * light , int bit , mnode_t * node ) ;
2005-07-16 00:53:08 +00:00
qboolean Q1BSP_Trace ( model_t * model , int forcehullnum , int frame , vec3_t start , vec3_t end , vec3_t mins , vec3_t maxs , trace_t * trace ) ;
2006-09-17 00:59:22 +00:00
void GLQ1BSP_LightPointValues ( model_t * model , vec3_t point , vec3_t res_diffuse , vec3_t res_ambient , vec3_t res_dir ) ;
2004-08-22 22:29:09 +00:00
2007-05-25 22:16:29 +00:00
void GLMod_FixupNodeMinsMaxs ( mnode_t * node , mnode_t * parent )
{
if ( ! node )
return ;
if ( node - > contents > = 0 )
{
GLMod_FixupNodeMinsMaxs ( node - > children [ 0 ] , node ) ;
GLMod_FixupNodeMinsMaxs ( node - > children [ 1 ] , node ) ;
}
if ( parent )
{
if ( parent - > minmaxs [ 0 ] > node - > minmaxs [ 0 ] )
parent - > minmaxs [ 0 ] = node - > minmaxs [ 0 ] ;
if ( parent - > minmaxs [ 1 ] > node - > minmaxs [ 1 ] )
parent - > minmaxs [ 1 ] = node - > minmaxs [ 1 ] ;
if ( parent - > minmaxs [ 2 ] > node - > minmaxs [ 2 ] )
parent - > minmaxs [ 2 ] = node - > minmaxs [ 2 ] ;
if ( parent - > minmaxs [ 3 ] < node - > minmaxs [ 3 ] )
parent - > minmaxs [ 3 ] = node - > minmaxs [ 3 ] ;
if ( parent - > minmaxs [ 4 ] < node - > minmaxs [ 4 ] )
parent - > minmaxs [ 4 ] = node - > minmaxs [ 4 ] ;
if ( parent - > minmaxs [ 5 ] < node - > minmaxs [ 5 ] )
parent - > minmaxs [ 5 ] = node - > minmaxs [ 5 ] ;
}
}
void GLMod_FixupMinsMaxs ( void )
{
//q1 bsps are capped to +/- 32767 by the nodes/leafs
//verts arn't though
//so if the map is too big, let's figure out what they should be
float * v ;
msurface_t * * mark , * surf ;
mleaf_t * pleaf ;
medge_t * e , * pedges ;
int en , lindex ;
int i , c , lnumverts ;
qboolean needsfixup = false ;
if ( loadmodel - > mins [ 0 ] < - 32768 )
needsfixup = true ;
if ( loadmodel - > mins [ 1 ] < - 32768 )
needsfixup = true ;
if ( loadmodel - > mins [ 2 ] < - 32768 )
needsfixup = true ;
if ( loadmodel - > maxs [ 0 ] > 32767 )
needsfixup = true ;
if ( loadmodel - > maxs [ 1 ] > 32767 )
needsfixup = true ;
if ( loadmodel - > maxs [ 2 ] > 32767 )
needsfixup = true ;
if ( ! needsfixup )
return ;
//this is insane.
//why am I writing this?
//by the time the world actually gets this large, the floating point errors are going to be so immensly crazy that it's just not worth it.
pedges = loadmodel - > edges ;
for ( i = 0 ; i < loadmodel - > numleafs ; i + + )
{
pleaf = & loadmodel - > leafs [ i ] ;
mark = pleaf - > firstmarksurface ;
c = pleaf - > nummarksurfaces ;
if ( c )
{
do
{
surf = ( * mark + + ) ;
lnumverts = surf - > numedges ;
for ( en = 0 ; en < lnumverts ; en + + )
{
lindex = currentmodel - > surfedges [ surf - > firstedge + en ] ;
if ( lindex > 0 )
{
e = & pedges [ lindex ] ;
v = currentmodel - > vertexes [ e - > v [ 0 ] ] . position ;
}
else
{
e = & pedges [ - lindex ] ;
v = currentmodel - > vertexes [ e - > v [ 1 ] ] . position ;
}
if ( pleaf - > minmaxs [ 0 ] > v [ 0 ] )
pleaf - > minmaxs [ 0 ] = v [ 0 ] ;
if ( pleaf - > minmaxs [ 1 ] > v [ 1 ] )
pleaf - > minmaxs [ 1 ] = v [ 1 ] ;
if ( pleaf - > minmaxs [ 2 ] > v [ 2 ] )
pleaf - > minmaxs [ 2 ] = v [ 2 ] ;
if ( pleaf - > minmaxs [ 3 ] < v [ 0 ] )
pleaf - > minmaxs [ 3 ] = v [ 0 ] ;
if ( pleaf - > minmaxs [ 4 ] < v [ 1 ] )
pleaf - > minmaxs [ 4 ] = v [ 1 ] ;
if ( pleaf - > minmaxs [ 5 ] < v [ 2 ] )
pleaf - > minmaxs [ 5 ] = v [ 2 ] ;
}
} while ( - - c ) ;
}
}
GLMod_FixupNodeMinsMaxs ( loadmodel - > nodes , NULL ) ; // sets nodes and leafs
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_LoadBrushModel
= = = = = = = = = = = = = = = = =
*/
2006-03-12 22:01:49 +00:00
qboolean GLMod_LoadBrushModel ( model_t * mod , void * buffer )
2004-08-22 22:29:09 +00:00
{
int i , j ;
dheader_t * header ;
mmodel_t * bm ;
model_t * lm = mod ;
2006-02-22 23:50:12 +00:00
unsigned int chksum ;
2006-03-12 22:01:49 +00:00
int start ;
qboolean noerrors ;
2004-08-22 22:29:09 +00:00
2006-03-12 22:01:49 +00:00
start = Hunk_LowMark ( ) ;
2004-08-22 22:29:09 +00:00
loadmodel - > type = mod_brush ;
header = ( dheader_t * ) buffer ;
if ( ( ! cl . worldmodel & & cls . state > = ca_connected )
# ifndef CLIENTONLY
| | ( ! sv . worldmodel & & sv . active )
# endif
)
isnotmap = false ;
else
isnotmap = true ;
i = LittleLong ( header - > version ) ;
2005-05-08 03:41:24 +00:00
if ( i = = BSPVERSION | | i = = BSPVERSIONPREREL )
2006-04-16 06:03:58 +00:00
{
2004-08-22 22:29:09 +00:00
loadmodel - > fromgame = fg_quake ;
2006-04-16 06:03:58 +00:00
loadmodel - > engineflags | = MDLF_NEEDOVERBRIGHT ;
}
2004-08-22 22:29:09 +00:00
else if ( i = = BSPVERSIONHL ) //halflife support
loadmodel - > fromgame = fg_halflife ;
else
2006-03-12 22:01:49 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Mod_LoadBrushModel: %s has wrong version number (%i should be %i) \n " , mod - > name , i , BSPVERSION ) ;
2006-03-12 22:01:49 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
// swap all the lumps
mod_base = ( qbyte * ) header ;
for ( i = 0 ; i < sizeof ( dheader_t ) / 4 ; i + + )
( ( int * ) header ) [ i ] = LittleLong ( ( ( int * ) header ) [ i ] ) ;
// checksum all of the map, except for entities
mod - > checksum = 0 ;
mod - > checksum2 = 0 ;
2006-10-05 21:12:04 +00:00
for ( i = 0 ; i < HEADER_LUMPS ; i + + )
{
if ( ( unsigned ) header - > lumps [ i ] . fileofs + ( unsigned ) header - > lumps [ i ] . filelen > com_filesize )
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Mod_LoadBrushModel: %s appears truncated \n " , mod - > name ) ;
2006-10-05 21:12:04 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
if ( i = = LUMP_ENTITIES )
continue ;
2006-02-22 23:50:12 +00:00
chksum = Com_BlockChecksum ( mod_base + header - > lumps [ i ] . fileofs , header - > lumps [ i ] . filelen ) ;
mod - > checksum ^ = chksum ;
2004-08-22 22:29:09 +00:00
if ( i = = LUMP_VISIBILITY | | i = = LUMP_LEAFS | | i = = LUMP_NODES )
continue ;
2006-02-22 23:50:12 +00:00
mod - > checksum2 ^ = chksum ;
2004-08-22 22:29:09 +00:00
}
2006-10-05 21:12:04 +00:00
if ( 1 ) //mod_ebfs.value)
{
char * id ;
id = ( char * ) ( header + 1 ) ;
if ( id [ 0 ] = = ' P ' & & id [ 1 ] = = ' A ' & & id [ 2 ] = = ' C ' & & id [ 3 ] = = ' K ' )
{ //EBFS detected.
COM_LoadMapPackFile ( mod - > name , sizeof ( dheader_t ) ) ;
}
}
2004-08-22 22:29:09 +00:00
2006-03-12 22:01:49 +00:00
noerrors = true ;
crouchhullfile = NULL ;
2004-08-22 22:29:09 +00:00
// load into heap
# ifndef CLIENTONLY
if ( ! isDedicated )
# endif
{
2006-03-12 22:01:49 +00:00
noerrors = noerrors & & GLMod_LoadVertexes ( & header - > lumps [ LUMP_VERTEXES ] ) ;
noerrors = noerrors & & GLMod_LoadEdges ( & header - > lumps [ LUMP_EDGES ] ) ;
noerrors = noerrors & & GLMod_LoadSurfedges ( & header - > lumps [ LUMP_SURFEDGES ] ) ;
noerrors = noerrors & & GLMod_LoadTextures ( & header - > lumps [ LUMP_TEXTURES ] ) ;
if ( noerrors )
GLMod_LoadLighting ( & header - > lumps [ LUMP_LIGHTING ] ) ;
}
noerrors = noerrors & & GLMod_LoadSubmodels ( & header - > lumps [ LUMP_MODELS ] ) ;
if ( noerrors )
GLMod_LoadCrouchHull ( ) ;
noerrors = noerrors & & GLMod_LoadPlanes ( & header - > lumps [ LUMP_PLANES ] ) ;
2004-08-22 22:29:09 +00:00
# ifndef CLIENTONLY
if ( ! isDedicated )
# endif
{
2006-03-12 22:01:49 +00:00
noerrors = noerrors & & GLMod_LoadTexinfo ( & header - > lumps [ LUMP_TEXINFO ] ) ;
noerrors = noerrors & & GLMod_LoadFaces ( & header - > lumps [ LUMP_FACES ] ) ;
noerrors = noerrors & & GLMod_LoadMarksurfaces ( & header - > lumps [ LUMP_MARKSURFACES ] ) ;
2004-08-22 22:29:09 +00:00
}
2006-03-12 22:01:49 +00:00
if ( noerrors )
GLMod_LoadVisibility ( & header - > lumps [ LUMP_VISIBILITY ] ) ;
noerrors = noerrors & & GLMod_LoadLeafs ( & header - > lumps [ LUMP_LEAFS ] ) ;
noerrors = noerrors & & GLMod_LoadNodes ( & header - > lumps [ LUMP_NODES ] ) ;
noerrors = noerrors & & GLMod_LoadClipnodes ( & header - > lumps [ LUMP_CLIPNODES ] ) ;
if ( noerrors )
{
GLMod_LoadEntities ( & header - > lumps [ LUMP_ENTITIES ] ) ;
GLMod_MakeHull0 ( ) ;
}
2004-08-22 22:29:09 +00:00
if ( crouchhullfile )
{
BZ_Free ( crouchhullfile ) ;
crouchhullfile = NULL ;
}
2006-03-12 22:01:49 +00:00
if ( ! noerrors )
{
Hunk_FreeToLowMark ( start ) ;
return false ;
}
2004-08-22 22:29:09 +00:00
# ifndef CLIENTONLY
if ( sv . state ) //if the server is running
{
if ( ! strcmp ( loadmodel - > name , va ( " maps/%s.bsp " , sv . name ) ) )
Mod_ParseInfoFromEntityLump ( mod_base + header - > lumps [ LUMP_ENTITIES ] . fileofs ) ;
}
else
# endif
{
if ( ! cl . model_precache [ 1 ] ) //not copied across yet
Mod_ParseInfoFromEntityLump ( mod_base + header - > lumps [ LUMP_ENTITIES ] . fileofs ) ;
}
2005-08-26 22:56:51 +00:00
Q1BSP_SetModelFuncs ( mod ) ;
2004-08-22 22:29:09 +00:00
mod - > funcs . LightPointValues = GLQ1BSP_LightPointValues ;
mod - > funcs . StainNode = Q1BSP_StainNode ;
mod - > funcs . MarkLights = Q1BSP_MarkLights ;
mod - > numframes = 2 ; // regular and alternate animation
//
// set up the submodels (FIXME: this is confusing)
//
for ( i = 0 ; i < mod - > numsubmodels ; i + + )
{
bm = & mod - > submodels [ i ] ;
mod - > hulls [ 0 ] . firstclipnode = bm - > headnode [ 0 ] ;
mod - > hulls [ 0 ] . available = true ;
Q1BSP_SetHullFuncs ( & mod - > hulls [ 0 ] ) ;
for ( j = 1 ; j < MAX_MAP_HULLSM ; j + + )
{
mod - > hulls [ j ] . firstclipnode = bm - > headnode [ j ] ;
mod - > hulls [ j ] . lastclipnode = mod - > numclipnodes - 1 ;
mod - > hulls [ j ] . available = bm - > hullavailable [ j ] ;
if ( mod - > hulls [ j ] . firstclipnode > mod - > hulls [ j ] . lastclipnode )
mod - > hulls [ j ] . available = false ;
Q1BSP_SetHullFuncs ( & mod - > hulls [ j ] ) ;
}
mod - > firstmodelsurface = bm - > firstface ;
mod - > nummodelsurfaces = bm - > numfaces ;
VectorCopy ( bm - > maxs , mod - > maxs ) ;
VectorCopy ( bm - > mins , mod - > mins ) ;
mod - > radius = RadiusFromBounds ( mod - > mins , mod - > maxs ) ;
mod - > numleafs = bm - > visleafs ;
if ( i < mod - > numsubmodels - 1 )
{ // duplicate the basic information
char name [ 10 ] ;
sprintf ( name , " *%i " , i + 1 ) ;
loadmodel = Mod_FindName ( name ) ;
* loadmodel = * mod ;
strcpy ( loadmodel - > name , name ) ;
mod = loadmodel ;
2005-03-10 03:55:18 +00:00
P_DefaultTrail ( mod ) ;
2004-08-22 22:29:09 +00:00
}
}
# ifdef RUNTIMELIGHTING
if ( lightmodel = = lm )
LightLoadEntities ( lightmodel - > entities ) ;
# endif
2006-03-12 22:01:49 +00:00
2007-05-25 22:16:29 +00:00
if ( 1 )
GLMod_FixupMinsMaxs ( ) ;
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
ALIAS MODELS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
//aliashdr_t *pheader;
//mstvert_t stverts[MAXALIASVERTS*2];
//mtriangle_t triangles[MAXALIASTRIS];
// a pose is a single set of vertexes. a frame may be
// an animating sequence of poses
//dtrivertx_t *poseverts[MAXALIASFRAMES];
//int posenum;
qbyte * player_8bit_texels /*[320*200]*/ ;
//=========================================================
/*
= = = = = = = = = = = = = = = = =
Mod_FloodFillSkin
Fill background pixels so mipmapping doesn ' t have haloes - Ed
= = = = = = = = = = = = = = = = =
*/
typedef struct
{
short x , y ;
} floodfill_t ;
// must be a power of 2
# define FLOODFILL_FIFO_SIZE 0x1000
# define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1)
# define FLOODFILL_STEP( off, dx, dy ) \
{ \
if ( pos [ off ] = = fillcolor ) \
{ \
pos [ off ] = 255 ; \
fifo [ inpt ] . x = x + ( dx ) , fifo [ inpt ] . y = y + ( dy ) ; \
inpt = ( inpt + 1 ) & FLOODFILL_FIFO_MASK ; \
} \
else if ( pos [ off ] ! = 255 ) fdc = pos [ off ] ; \
}
void GLMod_FloodFillSkin ( qbyte * skin , int skinwidth , int skinheight )
{
qbyte fillcolor = * skin ; // assume this is the pixel to fill
floodfill_t fifo [ FLOODFILL_FIFO_SIZE ] ;
int inpt = 0 , outpt = 0 ;
int filledcolor = - 1 ;
int i ;
if ( filledcolor = = - 1 )
{
filledcolor = 0 ;
// attempt to find opaque black
for ( i = 0 ; i < 256 ; + + i )
if ( d_8to24rgbtable [ i ] = = ( 255 < < 0 ) ) // alpha 1.0
{
filledcolor = i ;
break ;
}
}
// can't fill to filled color or to transparent color (used as visited marker)
if ( ( fillcolor = = filledcolor ) | | ( fillcolor = = 255 ) )
{
//printf( "not filling skin from %d to %d\n", fillcolor, filledcolor );
return ;
}
fifo [ inpt ] . x = 0 , fifo [ inpt ] . y = 0 ;
inpt = ( inpt + 1 ) & FLOODFILL_FIFO_MASK ;
while ( outpt ! = inpt )
{
int x = fifo [ outpt ] . x , y = fifo [ outpt ] . y ;
int fdc = filledcolor ;
qbyte * pos = & skin [ x + skinwidth * y ] ;
outpt = ( outpt + 1 ) & FLOODFILL_FIFO_MASK ;
if ( x > 0 ) FLOODFILL_STEP ( - 1 , - 1 , 0 ) ;
if ( x < skinwidth - 1 ) FLOODFILL_STEP ( 1 , 1 , 0 ) ;
if ( y > 0 ) FLOODFILL_STEP ( - skinwidth , 0 , - 1 ) ;
if ( y < skinheight - 1 ) FLOODFILL_STEP ( skinwidth , 0 , 1 ) ;
skin [ x + skinwidth * y ] = fdc ;
}
}
//=============================================================================
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteFrame
= = = = = = = = = = = = = = = = =
*/
2005-05-13 10:42:48 +00:00
void * GLMod_LoadSpriteFrame ( void * pin , mspriteframe_t * * ppframe , int framenum , int version , unsigned char * palette )
2004-08-22 22:29:09 +00:00
{
dspriteframe_t * pinframe ;
mspriteframe_t * pspriteframe ;
int width , height , size , origin [ 2 ] ;
char name [ 64 ] ;
pinframe = ( dspriteframe_t * ) pin ;
width = LittleLong ( pinframe - > width ) ;
height = LittleLong ( pinframe - > height ) ;
size = width * height ;
pspriteframe = Hunk_AllocName ( sizeof ( mspriteframe_t ) , loadname ) ;
Q_memset ( pspriteframe , 0 , sizeof ( mspriteframe_t ) ) ;
* ppframe = pspriteframe ;
pspriteframe - > width = width ;
pspriteframe - > height = height ;
origin [ 0 ] = LittleLong ( pinframe - > origin [ 0 ] ) ;
origin [ 1 ] = LittleLong ( pinframe - > origin [ 1 ] ) ;
pspriteframe - > up = origin [ 1 ] ;
pspriteframe - > down = origin [ 1 ] - height ;
pspriteframe - > left = origin [ 0 ] ;
pspriteframe - > right = width + origin [ 0 ] ;
2005-09-22 12:59:34 +00:00
pspriteframe - > gl_texturenum = 0 ;
if ( ! pspriteframe - > gl_texturenum )
{ //the dp way
strcat ( name , va ( " _%i " , framenum ) ) ;
pspriteframe - > gl_texturenum = Mod_LoadReplacementTexture ( name , " sprites " , true , true , true ) ;
}
if ( ! pspriteframe - > gl_texturenum )
{ //the older fte way.
2006-03-11 03:12:10 +00:00
COM_StripExtension ( loadmodel - > name , name , sizeof ( name ) ) ;
2005-09-22 12:59:34 +00:00
strcat ( name , va ( " _%i " , framenum ) ) ;
pspriteframe - > gl_texturenum = Mod_LoadReplacementTexture ( name , " sprites " , true , true , true ) ;
}
if ( ! pspriteframe - > gl_texturenum )
{ //the fuhquake way
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , name , sizeof ( name ) ) ;
2005-09-22 12:59:34 +00:00
strcat ( name , va ( " _%i " , framenum ) ) ;
pspriteframe - > gl_texturenum = Mod_LoadReplacementTexture ( name , " sprites " , true , true , true ) ;
}
2005-05-13 10:42:48 +00:00
2004-08-22 22:29:09 +00:00
if ( version = = SPRITE32_VERSION )
{
size * = 4 ;
2005-05-13 10:42:48 +00:00
if ( ! pspriteframe - > gl_texturenum )
2007-05-25 22:16:29 +00:00
pspriteframe - > gl_texturenum = R_LoadTexture32 ( name , width , height , ( unsigned * ) ( pinframe + 1 ) , true , true ) ;
2005-05-13 10:42:48 +00:00
}
else if ( version = = SPRITEHL_VERSION )
{
if ( ! pspriteframe - > gl_texturenum )
2007-05-25 22:16:29 +00:00
pspriteframe - > gl_texturenum = R_LoadTexture8Pal32 ( name , width , height , ( qbyte * ) ( pinframe + 1 ) , ( qbyte * ) palette , true , true ) ;
2005-05-13 10:42:48 +00:00
}
else
{
if ( ! pspriteframe - > gl_texturenum )
2007-05-25 22:16:29 +00:00
pspriteframe - > gl_texturenum = R_LoadTexture8 ( name , width , height , ( qbyte * ) ( pinframe + 1 ) , true , true ) ;
2004-08-22 22:29:09 +00:00
}
2005-05-13 10:42:48 +00:00
return ( void * ) ( ( qbyte * ) ( pinframe + 1 ) + size ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteGroup
= = = = = = = = = = = = = = = = =
*/
2005-05-13 10:42:48 +00:00
void * GLMod_LoadSpriteGroup ( void * pin , mspriteframe_t * * ppframe , int framenum , int version , unsigned char * palette )
2004-08-22 22:29:09 +00:00
{
dspritegroup_t * pingroup ;
mspritegroup_t * pspritegroup ;
int i , numframes ;
dspriteinterval_t * pin_intervals ;
float * poutintervals ;
void * ptemp ;
pingroup = ( dspritegroup_t * ) pin ;
numframes = LittleLong ( pingroup - > numframes ) ;
pspritegroup = Hunk_AllocName ( sizeof ( mspritegroup_t ) +
( numframes - 1 ) * sizeof ( pspritegroup - > frames [ 0 ] ) , loadname ) ;
pspritegroup - > numframes = numframes ;
* ppframe = ( mspriteframe_t * ) pspritegroup ;
pin_intervals = ( dspriteinterval_t * ) ( pingroup + 1 ) ;
poutintervals = Hunk_AllocName ( numframes * sizeof ( float ) , loadname ) ;
pspritegroup - > intervals = poutintervals ;
for ( i = 0 ; i < numframes ; i + + )
{
* poutintervals = LittleFloat ( pin_intervals - > interval ) ;
if ( * poutintervals < = 0.0 )
2006-03-13 06:15:11 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Mod_LoadSpriteGroup: interval<=0 \n " ) ;
2006-03-13 06:15:11 +00:00
return NULL ;
}
2004-08-22 22:29:09 +00:00
poutintervals + + ;
pin_intervals + + ;
}
ptemp = ( void * ) pin_intervals ;
for ( i = 0 ; i < numframes ; i + + )
{
2005-05-13 10:42:48 +00:00
ptemp = GLMod_LoadSpriteFrame ( ptemp , & pspritegroup - > frames [ i ] , framenum * 100 + i , version , palette ) ;
2004-08-22 22:29:09 +00:00
}
return ptemp ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteModel
= = = = = = = = = = = = = = = = =
*/
2006-03-13 06:15:11 +00:00
qboolean GLMod_LoadSpriteModel ( model_t * mod , void * buffer )
2004-08-22 22:29:09 +00:00
{
int i ;
int version ;
dsprite_t * pin ;
msprite_t * psprite ;
int numframes ;
int size ;
dspriteframetype_t * pframetype ;
2005-05-13 10:42:48 +00:00
int rendertype = 0 ;
unsigned char pal [ 256 * 4 ] ;
int sptype ;
2006-03-13 06:15:11 +00:00
int hunkstart ;
2004-08-22 22:29:09 +00:00
2006-03-13 06:15:11 +00:00
hunkstart = Hunk_LowMark ( ) ;
2004-08-22 22:29:09 +00:00
pin = ( dsprite_t * ) buffer ;
version = LittleLong ( pin - > version ) ;
if ( version ! = SPRITE_VERSION )
2005-05-13 10:42:48 +00:00
if ( version ! = SPRITE32_VERSION )
if ( version ! = SPRITEHL_VERSION )
2006-03-13 06:15:11 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " %s has wrong version number "
2006-03-13 06:15:11 +00:00
" (%i should be %i) \n " , mod - > name , version , SPRITE_VERSION ) ;
return false ;
}
2004-08-22 22:29:09 +00:00
2005-05-13 10:42:48 +00:00
sptype = LittleLong ( pin - > type ) ;
2006-04-09 15:35:50 +00:00
if ( LittleLong ( pin - > version ) = = SPRITEHL_VERSION )
2005-05-13 10:42:48 +00:00
{
pin = ( dsprite_t * ) ( ( char * ) pin + 4 ) ;
rendertype = LittleLong ( pin - > type ) ;
}
2004-08-22 22:29:09 +00:00
numframes = LittleLong ( pin - > numframes ) ;
size = sizeof ( msprite_t ) + ( numframes - 1 ) * sizeof ( psprite - > frames ) ;
psprite = Hunk_AllocName ( size , loadname ) ;
mod - > cache . data = psprite ;
2005-05-13 10:42:48 +00:00
psprite - > type = sptype ;
2004-08-22 22:29:09 +00:00
psprite - > maxwidth = LittleLong ( pin - > width ) ;
psprite - > maxheight = LittleLong ( pin - > height ) ;
psprite - > beamlength = LittleFloat ( pin - > beamlength ) ;
mod - > synctype = LittleLong ( pin - > synctype ) ;
psprite - > numframes = numframes ;
mod - > mins [ 0 ] = mod - > mins [ 1 ] = - psprite - > maxwidth / 2 ;
mod - > maxs [ 0 ] = mod - > maxs [ 1 ] = psprite - > maxwidth / 2 ;
mod - > mins [ 2 ] = - psprite - > maxheight / 2 ;
mod - > maxs [ 2 ] = psprite - > maxheight / 2 ;
2005-05-13 10:42:48 +00:00
if ( pin - > version = = SPRITEHL_VERSION )
{
int i ;
short * numi = ( short * ) ( pin + 1 ) ;
unsigned char * src = ( unsigned char * ) ( numi + 1 ) ;
2006-04-09 15:35:50 +00:00
if ( LittleShort ( * numi ) ! = 256 )
2006-03-13 06:15:11 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " %s has wrong number of palette indexes (we only support 256) \n " , mod - > name ) ;
2006-03-13 06:15:11 +00:00
Hunk_FreeToLowMark ( hunkstart ) ;
return false ;
}
2005-05-13 10:42:48 +00:00
for ( i = 0 ; i < 256 ; i + + )
{
pal [ i * 4 + 0 ] = * src + + ;
pal [ i * 4 + 1 ] = * src + + ;
pal [ i * 4 + 2 ] = * src + + ;
pal [ i * 4 + 3 ] = 255 ;
}
pframetype = ( dspriteframetype_t * ) ( src ) ;
}
else
pframetype = ( dspriteframetype_t * ) ( pin + 1 ) ;
2004-08-22 22:29:09 +00:00
//
// load the frames
//
if ( numframes < 1 )
2006-03-13 06:15:11 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Mod_LoadSpriteModel: Invalid # of frames: %d \n " , numframes ) ;
2006-03-13 06:15:11 +00:00
Hunk_FreeToLowMark ( hunkstart ) ;
return false ;
}
2004-08-22 22:29:09 +00:00
mod - > numframes = numframes ;
for ( i = 0 ; i < numframes ; i + + )
{
spriteframetype_t frametype ;
frametype = LittleLong ( pframetype - > type ) ;
psprite - > frames [ i ] . type = frametype ;
if ( frametype = = SPR_SINGLE )
{
pframetype = ( dspriteframetype_t * )
GLMod_LoadSpriteFrame ( pframetype + 1 ,
2005-05-13 10:42:48 +00:00
& psprite - > frames [ i ] . frameptr , i , version , pal ) ;
2004-08-22 22:29:09 +00:00
}
else
{
pframetype = ( dspriteframetype_t * )
GLMod_LoadSpriteGroup ( pframetype + 1 ,
2005-05-13 10:42:48 +00:00
& psprite - > frames [ i ] . frameptr , i , version , pal ) ;
2004-08-22 22:29:09 +00:00
}
2006-03-13 06:15:11 +00:00
if ( pframetype = = NULL )
{
Hunk_FreeToLowMark ( hunkstart ) ;
return false ;
}
2004-08-22 22:29:09 +00:00
}
mod - > type = mod_sprite ;
2006-03-13 06:15:11 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
2006-03-13 06:15:11 +00:00
qboolean GLMod_LoadSprite2Model ( model_t * mod , void * buffer )
2004-08-22 22:29:09 +00:00
{
int i ;
int version ;
dmd2sprite_t * pin ;
msprite_t * psprite ;
int numframes ;
int size ;
dmd2sprframe_t * pframetype ;
mspriteframe_t * frame ;
float origin [ 2 ] ;
2006-03-13 06:15:11 +00:00
int hunkstart ;
hunkstart = Hunk_LowMark ( ) ;
2004-08-22 22:29:09 +00:00
pin = ( dmd2sprite_t * ) buffer ;
version = LittleLong ( pin - > version ) ;
if ( version ! = SPRITE2_VERSION )
2006-03-13 06:15:11 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " %s has wrong version number "
2004-08-22 22:29:09 +00:00
" (%i should be %i) " , mod - > name , version , SPRITE2_VERSION ) ;
2006-03-13 06:15:11 +00:00
return false ;
}
2004-08-22 22:29:09 +00:00
numframes = LittleLong ( pin - > numframes ) ;
size = sizeof ( msprite_t ) + ( numframes - 1 ) * sizeof ( psprite - > frames ) ;
psprite = Hunk_AllocName ( size , loadname ) ;
mod - > cache . data = psprite ;
psprite - > type = SPR_VP_PARALLEL ;
psprite - > maxwidth = 1 ;
psprite - > maxheight = 1 ;
psprite - > beamlength = 1 ;
mod - > synctype = 0 ;
psprite - > numframes = numframes ;
mod - > mins [ 0 ] = mod - > mins [ 1 ] = - psprite - > maxwidth / 2 ;
mod - > maxs [ 0 ] = mod - > maxs [ 1 ] = psprite - > maxwidth / 2 ;
mod - > mins [ 2 ] = - psprite - > maxheight / 2 ;
mod - > maxs [ 2 ] = psprite - > maxheight / 2 ;
//
// load the frames
//
if ( numframes < 1 )
2006-03-13 06:15:11 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_ERROR " Mod_LoadSpriteModel: Invalid # of frames: %d \n " , numframes ) ;
2006-03-13 06:15:11 +00:00
Hunk_FreeToLowMark ( hunkstart ) ;
return false ;
}
2004-08-22 22:29:09 +00:00
mod - > numframes = numframes ;
pframetype = pin - > frames ;
for ( i = 0 ; i < numframes ; i + + )
{
spriteframetype_t frametype ;
frametype = SPR_SINGLE ;
psprite - > frames [ i ] . type = frametype ;
frame = psprite - > frames [ i ] . frameptr = Hunk_AllocName ( sizeof ( mspriteframe_t ) , loadname ) ;
2005-04-26 16:04:12 +00:00
frame - > gl_texturenum = Mod_LoadHiResTexture ( pframetype - > name , NULL , true , true , true ) ;
2007-05-25 22:16:29 +00:00
2004-08-22 22:29:09 +00:00
frame - > width = LittleLong ( pframetype - > width ) ;
frame - > height = LittleLong ( pframetype - > height ) ;
origin [ 0 ] = LittleLong ( pframetype - > origin_x ) ;
origin [ 1 ] = LittleLong ( pframetype - > origin_y ) ;
frame - > up = - origin [ 1 ] ;
frame - > down = frame - > height - origin [ 1 ] ;
frame - > left = - origin [ 0 ] ;
frame - > right = frame - > width - origin [ 0 ] ;
2005-03-18 06:14:33 +00:00
pframetype + + ;
2004-08-22 22:29:09 +00:00
}
mod - > type = mod_sprite ;
2006-03-13 06:15:11 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
# ifdef DOOMWADS
typedef struct {
short width ;
short height ;
short xpos ;
short ypos ;
} doomimage_t ;
static int FindDoomSprites ( char * name , int size , void * param )
{
if ( * ( int * ) param + strlen ( name ) + 1 > 16000 )
Sys_Error ( " Too many doom sprites \n " ) ;
strcpy ( ( char * ) param + * ( int * ) param , name ) ;
* ( int * ) param + = strlen ( name ) + 1 ;
return true ;
}
static void LoadDoomSpriteFrame ( char * imagename , mspriteframedesc_t * pdesc , int anglenum , qboolean xmirrored )
{
int c ;
int fr ;
int rc ;
unsigned int * colpointers ;
qbyte * data ;
doomimage_t * header ;
qbyte image [ 256 * 256 ] ;
qbyte * palette ;
qbyte * coldata ;
mspriteframe_t * pframe ;
if ( ! anglenum )
{
pdesc - > type = SPR_SINGLE ;
pdesc - > frameptr = pframe = Hunk_AllocName ( sizeof ( * pframe ) , loadname ) ;
}
else
{
mspritegroup_t * group ;
if ( ! pdesc - > frameptr | | pdesc - > type ! = SPR_ANGLED )
{
pdesc - > type = SPR_ANGLED ;
group = Hunk_AllocName ( sizeof ( * group ) + sizeof ( mspriteframe_t * ) * ( 8 - 1 ) , loadname ) ;
pdesc - > frameptr = ( mspriteframe_t * ) group ;
group - > numframes = 8 ;
}
else
group = ( mspritegroup_t * ) pdesc - > frameptr ;
pframe = Hunk_AllocName ( sizeof ( * pframe ) , loadname ) ;
group - > frames [ anglenum - 1 ] = pframe ;
}
palette = COM_LoadTempFile ( " wad/playpal " ) ;
header = ( doomimage_t * ) COM_LoadTempFile2 ( imagename ) ;
data = ( qbyte * ) header ;
pframe - > width = header - > width ;
pframe - > height = header - > height ;
pframe - > up = + header - > ypos ;
pframe - > down = - header - > height + header - > ypos ;
if ( xmirrored )
{
pframe - > right = - header - > xpos ;
pframe - > left = header - > width - header - > xpos ;
}
else
{
pframe - > left = - header - > xpos ;
pframe - > right = header - > width - header - > xpos ;
}
if ( header - > width * header - > height > sizeof ( image ) )
return ;
memset ( image , 255 , header - > width * header - > height ) ;
colpointers = ( unsigned int * ) ( data + sizeof ( doomimage_t ) ) ;
for ( c = 0 ; c < header - > width ; c + + )
{
if ( colpointers [ c ] > = com_filesize )
break ;
coldata = data + colpointers [ c ] ;
while ( 1 )
{
fr = * coldata + + ;
if ( fr = = 255 )
break ;
rc = * coldata + + ;
coldata + + ;
if ( ( fr + rc ) > header - > height )
break ;
while ( rc )
{
image [ c + fr * header - > width ] = * coldata + + ;
fr + + ;
rc - - ;
}
coldata + + ;
}
}
pframe - > gl_texturenum = GL_LoadTexture8Pal24 ( imagename , pframe - > width , pframe - > height , image , palette , true , true ) ;
}
/*
= = = = = = = = = = = = = = = = =
Doom Sprites
= = = = = = = = = = = = = = = = =
*/
void GLMod_LoadDoomSprite ( model_t * mod )
{
char files [ 16384 ] ;
char basename [ MAX_QPATH ] ;
int baselen ;
char * name ;
int numframes = 0 ;
int ofs ;
int size ;
int elements = 0 ;
int framenum ;
int anglenum ;
msprite_t * psprite ;
2006-05-12 21:02:56 +00:00
COM_StripExtension ( mod - > name , basename , sizeof ( basename ) ) ;
2004-08-22 22:29:09 +00:00
baselen = strlen ( basename ) ;
strcat ( basename , " * " ) ;
* ( int * ) files = 4 ;
COM_EnumerateFiles ( basename , FindDoomSprites , files ) ;
//find maxframes and validate the rest.
for ( ofs = 4 ; ofs < * ( int * ) files ; ofs + = strlen ( files + ofs ) + 1 )
{
name = files + ofs + baselen ;
if ( ! * name )
Host_Error ( " Doom sprite componant lacks frame name " ) ;
if ( * name - ' a ' + 1 > numframes )
numframes = * name - ' a ' + 1 ;
if ( name [ 1 ] < ' 0 ' | | name [ 1 ] > ' 8 ' )
Host_Error ( " Doom sprite componant has bad angle number " ) ;
if ( name [ 1 ] = = ' 0 ' )
elements + = 8 ;
else
elements + + ;
if ( name [ 2 ] ) //is there a second element?
{
if ( name [ 2 ] - ' a ' + 1 > numframes )
numframes = name [ 2 ] - ' a ' + 1 ;
if ( name [ 3 ] < ' 0 ' | | name [ 3 ] > ' 8 ' )
Host_Error ( " Doom sprite componant has bad angle number " ) ;
if ( name [ 3 ] = = ' 0 ' )
elements + = 8 ;
else
elements + + ;
}
}
if ( elements ! = numframes * 8 )
Host_Error ( " Doom sprite has wrong componant count " ) ;
if ( ! numframes )
Host_Error ( " Doom sprite componant has no frames " ) ;
size = sizeof ( msprite_t ) + ( elements - 1 ) * sizeof ( psprite - > frames ) ;
psprite = Hunk_AllocName ( size , loadname ) ;
psprite - > numframes = numframes ;
//do the actual loading.
for ( ofs = 4 ; ofs < * ( int * ) files ; ofs + = strlen ( files + ofs ) + 1 )
{
name = files + ofs ;
framenum = name [ baselen + 0 ] - ' a ' ;
anglenum = name [ baselen + 1 ] - ' 0 ' ;
LoadDoomSpriteFrame ( name , & psprite - > frames [ framenum ] , anglenum , false ) ;
if ( name [ baselen + 2 ] ) //is there a second element?
{
framenum = name [ baselen + 2 ] - ' a ' ;
anglenum = name [ baselen + 3 ] - ' 0 ' ;
LoadDoomSpriteFrame ( name , & psprite - > frames [ framenum ] , anglenum , true ) ;
}
}
psprite - > type = SPR_FACING_UPRIGHT ;
mod - > type = mod_sprite ;
mod - > cache . data = psprite ;
}
# endif
//=============================================================================
/*
= = = = = = = = = = = = = = = =
Mod_Print
= = = = = = = = = = = = = = = =
*/
void GLMod_Print ( void )
{
int i ;
model_t * mod ;
Con_Printf ( " Cached models: \n " ) ;
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
{
Con_Printf ( " %8p : %s \n " , mod - > cache . data , mod - > name ) ;
}
}
2004-12-15 19:53:30 +00:00
# endif