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
2009-11-04 21:16:50 +00:00
# if defined(GLQUAKE) || defined(D3DQUAKE)
2004-08-22 22:29:09 +00:00
# include "glquake.h"
2008-12-23 02:55:20 +00:00
# include "com_mesh.h"
2005-01-18 21:03:46 +00:00
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
qboolean isnotmap = true ; //used to not warp ammo models.
model_t * loadmodel ;
char loadname [ 32 ] ; // for hunk tags
void CM_Init ( void ) ;
2006-03-12 09:19:31 +00:00
qboolean GL_LoadHeightmapModel ( model_t * mod , void * buffer ) ;
2009-11-04 21:16:50 +00:00
qboolean RMod_LoadSpriteModel ( model_t * mod , void * buffer ) ;
qboolean RMod_LoadSprite2Model ( model_t * mod , void * buffer ) ;
qboolean RMod_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 ) ;
2009-11-04 21:16:50 +00:00
model_t * RMod_LoadModel ( model_t * mod , qboolean crash ) ;
2004-08-22 22:29:09 +00:00
2010-07-25 15:12:12 +00:00
# ifdef MAP_DOOM
2004-08-22 22:29:09 +00:00
qboolean Mod_LoadDoomLevel ( model_t * mod ) ;
# endif
# ifdef DOOMWADS
2009-11-04 21:16:50 +00:00
void RMod_LoadDoomSprite ( model_t * mod ) ;
2004-08-22 22:29:09 +00:00
# endif
# define MAX_MOD_KNOWN 2048
model_t mod_known [ MAX_MOD_KNOWN ] ;
int mod_numknown ;
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 ;
2010-07-11 02:22:39 +00:00
mesh_t nullmesh ;
void Mod_SortShaders ( void ) ;
2004-08-22 22:29:09 +00:00
# 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 ;
2009-11-04 21:16:50 +00:00
void RMod_UpdateLightmap ( int snum )
2004-08-22 22:29:09 +00:00
{
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
2009-11-04 21:16:50 +00:00
void RMod_TextureList_f ( void )
2004-08-22 22:29:09 +00:00
{
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 ) ;
}
}
}
}
2009-11-04 21:16:50 +00:00
void RMod_BlockTextureColour_f ( void )
2004-08-22 22:29:09 +00:00
{
char texname [ 64 ] ;
model_t * mod ;
texture_t * tx ;
2009-11-04 21:16:50 +00:00
shader_t * s ;
2004-08-22 22:29:09 +00:00
char * match = Cmd_Argv ( 1 ) ;
int i , m ;
unsigned int colour [ 8 * 8 ] ;
unsigned int rgba ;
2009-11-04 21:16:50 +00:00
2004-08-22 22:29:09 +00:00
( ( 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 ] ) ;
2009-11-04 21:16:50 +00:00
s = R_RegisterCustom ( Cmd_Argv ( 2 ) , NULL , NULL ) ;
if ( ! s )
{
2010-07-11 02:22:39 +00:00
s = R_RegisterCustom ( texname , Shader_DefaultBSPQ1 , NULL ) ;
2009-11-04 21:16:50 +00:00
}
2004-08-22 22:29:09 +00:00
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 ) )
{
2009-11-04 21:16:50 +00:00
tx - > shader = s ;
2004-08-22 22:29:09 +00:00
}
}
}
}
}
2009-11-04 21:16:50 +00:00
# if defined(RUNTIMELIGHTING) && defined(MULTITHREAD)
2010-11-22 02:03:28 +00:00
void * relightthread [ 8 ] ;
unsigned int relightthreads ;
2009-11-04 21:16:50 +00:00
volatile qboolean wantrelight ;
int RelightThread ( void * arg )
{
2010-11-22 02:03:28 +00:00
int surf ;
while ( wantrelight )
2009-11-04 21:16:50 +00:00
{
2010-11-22 02:03:28 +00:00
# ifdef _WIN32
surf = InterlockedIncrement ( & relitsurface ) ;
# else
surf = relightthreads + + ;
# endif
if ( surf > = lightmodel - > numsurfaces )
break ;
LightFace ( surf ) ;
lightmodel - > surfaces [ surf ] . cached_dlight = - 1 ;
2009-11-04 21:16:50 +00:00
}
return 0 ;
}
# endif
void RMod_Think ( void )
{
# ifdef RUNTIMELIGHTING
if ( lightmodel )
{
if ( relitsurface > = lightmodel - > numsurfaces )
{
return ;
}
# ifdef MULTITHREAD
2010-11-22 02:03:28 +00:00
if ( ! relightthreads )
2009-11-04 21:16:50 +00:00
{
2010-11-22 02:03:28 +00:00
int i ;
# ifdef _WIN32
HANDLE me = GetCurrentProcess ( ) ;
DWORD_PTR proc , sys ;
/*count cpus*/
GetProcessAffinityMask ( me , & proc , & sys ) ;
relightthreads = 0 ;
for ( i = 0 ; i < sizeof ( proc ) * 8 ; i + + )
2011-02-25 04:22:14 +00:00
if ( proc & ( ( size_t ) 1u < < i ) )
2010-11-22 02:03:28 +00:00
relightthreads + + ;
/*subtract 1*/
if ( relightthreads < = 1 )
relightthreads = 1 ;
else
relightthreads - - ;
# else
/*can't do atomics*/
relightthreads = 1 ;
# endif
if ( relightthreads > sizeof ( relightthread ) / sizeof ( relightthread [ 0 ] ) )
relightthreads = sizeof ( relightthread ) / sizeof ( relightthread [ 0 ] ) ;
2009-11-04 21:16:50 +00:00
wantrelight = true ;
2010-11-22 02:03:28 +00:00
for ( i = 0 ; i < relightthreads ; i + + )
2011-07-03 16:24:53 +00:00
relightthread [ i ] = Sys_CreateThread ( RelightThread , lightmodel , THREADP_NORMAL , 0 ) ;
2009-11-04 21:16:50 +00:00
}
# else
LightFace ( relitsurface ) ;
RMod_UpdateLightmap ( relitsurface ) ;
relitsurface + + ;
# endif
if ( relitsurface > = lightmodel - > numsurfaces )
{
char filename [ MAX_QPATH ] ;
Con_Printf ( " Finished lighting %s \n " , lightmodel - > name ) ;
# ifdef MULTITHREAD
if ( relightthread )
{
2010-11-22 02:03:28 +00:00
int i ;
2009-11-04 21:16:50 +00:00
wantrelight = false ;
2010-11-22 02:03:28 +00:00
for ( i = 0 ; i < relightthreads ; i + + )
{
Sys_WaitOnThread ( relightthread [ i ] ) ;
relightthread [ i ] = NULL ;
}
relightthreads = 0 ;
2009-11-04 21:16:50 +00:00
}
# endif
if ( lightmodel - > deluxdata )
{
COM_StripExtension ( lightmodel - > name , filename , sizeof ( filename ) ) ;
COM_DefaultExtension ( filename , " .lux " , sizeof ( filename ) ) ;
FS_WriteFile ( filename , lightmodel - > deluxdata - 8 , numlightdata * 3 + 8 , FS_GAME ) ;
}
if ( writelitfile ) //the user might already have a lit file (don't overwrite it).
{
COM_StripExtension ( lightmodel - > name , filename , sizeof ( filename ) ) ;
COM_DefaultExtension ( filename , " .lit " , sizeof ( filename ) ) ;
FS_WriteFile ( filename , lightmodel - > lightdata - 8 , numlightdata * 3 + 8 , FS_GAME ) ;
}
}
}
# endif
}
2011-05-27 17:59:31 +00:00
void Mod_RebuildLightmaps ( void )
{
int i , j ;
msurface_t * surf ;
model_t * mod ;
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
{
if ( mod - > needload )
continue ;
if ( mod - > type = = mod_brush )
{
for ( j = 0 , surf = mod - > surfaces ; j < mod - > numsurfaces ; j + + , surf + + )
surf - > cached_dlight = - 1 ; //force it
}
}
}
2009-11-04 21:16:50 +00:00
/*
= = = = = = = = = = = = = = = = = = =
Mod_ClearAll
= = = = = = = = = = = = = = = = = = =
*/
void RMod_ClearAll ( void )
{
int i ;
int t ;
model_t * mod ;
# ifdef RUNTIMELIGHTING
# ifdef MULTITHREAD
if ( relightthread )
{
wantrelight = false ;
2010-11-22 02:03:28 +00:00
for ( i = 0 ; i < relightthreads ; i + + )
{
Sys_WaitOnThread ( relightthread [ i ] ) ;
relightthread [ i ] = NULL ;
}
relightthreads = 0 ;
2009-11-04 21:16:50 +00:00
}
# endif
lightmodel = NULL ;
# endif
//when the hunk is reset, all bsp models need to be reloaded
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
{
if ( mod - > needload )
continue ;
if ( mod - > type = = mod_brush )
{
2010-07-12 22:46:37 +00:00
Surf_Clear ( mod ) ;
2009-11-04 21:16:50 +00:00
for ( t = 0 ; t < mod - > numtextures ; t + + )
{
if ( ! mod - > textures [ t ] )
continue ;
BE_ClearVBO ( & mod - > textures [ t ] - > vbo ) ;
}
}
if ( mod - > type ! = mod_alias
& & mod - > type ! = mod_halflife
)
mod - > needload = true ;
}
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = =
Mod_Init
= = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_Init ( void )
2004-08-22 22:29:09 +00:00
{
2010-07-12 22:46:37 +00:00
RMod_ClearAll ( ) ;
2004-08-22 22:29:09 +00:00
mod_numknown = 0 ;
2005-08-26 22:56:51 +00:00
Q1BSP_Init ( ) ;
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
Cmd_AddRemCommand ( " mod_texturelist " , RMod_TextureList_f ) ;
Cmd_AddRemCommand ( " mod_usetexture " , RMod_BlockTextureColour_f ) ;
2004-08-22 22:29:09 +00:00
}
2009-11-04 21:16:50 +00:00
void RMod_Shutdown ( void )
2004-08-22 22:29:09 +00:00
{
2010-07-12 22:46:37 +00:00
RMod_ClearAll ( ) ;
2004-08-22 22:29:09 +00:00
mod_numknown = 0 ;
Cmd_RemoveCommand ( " mod_texturelist " ) ;
Cmd_RemoveCommand ( " mod_usetexture " ) ;
}
/*
= = = = = = = = = = = = = = =
Mod_Init
Caches the data if needed
= = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void * RMod_Extradata ( model_t * mod )
2004-08-22 22:29:09 +00:00
{
void * r ;
r = Cache_Check ( & mod - > cache ) ;
if ( r )
return r ;
2009-11-04 21:16:50 +00:00
RMod_LoadModel ( mod , true ) ;
2004-08-22 22:29:09 +00:00
if ( ! mod - > cache . data )
Sys_Error ( " Mod_Extradata: caching failed " ) ;
return mod - > cache . data ;
}
/*
= = = = = = = = = = = = = = =
Mod_PointInLeaf
= = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
mleaf_t * RMod_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_FindName
= = = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
model_t * RMod_FindName ( char * name )
2004-08-22 22:29:09 +00:00
{
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
= = = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_TouchModel ( char * name )
2004-08-22 22:29:09 +00:00
{
model_t * mod ;
2009-11-04 21:16:50 +00:00
mod = RMod_FindName ( name ) ;
2004-08-22 22:29:09 +00:00
if ( ! mod - > needload )
{
if ( mod - > type = = mod_alias
| | mod - > type = = mod_halflife
)
Cache_Check ( & mod - > cache ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
Mod_LoadModel
Loads a model into the cache
= = = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
model_t * RMod_LoadModel ( model_t * mod , qboolean crash )
2004-08-22 22:29:09 +00:00
{
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 ] ;
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 ;
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 " ) | |
2010-08-28 17:14:38 +00:00
! strcmp ( mod - > name , " progs/flame2.mdl " ) | |
! strcmp ( mod - > name , " models/flame1.mdl " ) | | //hexen2 small standing flame
! strcmp ( mod - > name , " models/flame2.mdl " ) | | //hexen2 large standing flame
! strcmp ( mod - > name , " models/cflmtrch.mdl " ) ) //hexen2 wall torch
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 ;
2008-02-01 15:21:14 +00:00
else if ( ! strcmp ( mod - > name , " progs/backpack.mdl " ) )
mod - > engineflags | = MDLF_NOTREPLACEMENTS ;
2006-03-06 00:19:46 +00:00
else if ( ! strcmp ( mod - > name , " progs/eyes.mdl " ) )
2008-02-01 15:21:14 +00:00
mod - > engineflags | = MDLF_NOTREPLACEMENTS | MDLF_DOCRC ;
2006-03-06 00:19:46 +00:00
2012-01-24 04:24:14 +00:00
/*handle ezquake-originated cheats that would feck over fte users if fte didn't support
these are the conditions required for r_fb_models on non - players */
mod - > engineflags | = MDLF_EZQUAKEFBCHEAT ;
if ( ( mod - > engineflags & MDLF_DOCRC ) | |
! strcmp ( mod - > name , " progs/backpack.mdl " ) | |
! strcmp ( mod - > name , " progs/gib1.mdl " ) | |
! strcmp ( mod - > name , " progs/gib2.mdl " ) | |
! strcmp ( mod - > name , " progs/gib3.mdl " ) | |
! strcmp ( mod - > name , " progs/h_player.mdl " ) | |
! strncmp ( mod - > name , " progs/v_ " , 8 ) )
mod - > engineflags & = ~ MDLF_EZQUAKEFBCHEAT ;
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 " ) )
2008-11-09 22:29:28 +00:00
replstr = " " ; // sprite
2007-09-13 22:27:56 +00:00
else if ( ! Q_strcasecmp ( ext , " dsp " ) ) // doom sprite
2004-08-22 22:29:09 +00:00
{
2008-11-09 22:29:28 +00:00
replstr = " " ;
2007-09-13 22:27:56 +00:00
doomsprite = true ;
}
else // assume models
replstr = r_replacemodels . string ;
// gl_load24bit 0 disables all replacements
2007-10-23 03:14:25 +00:00
if ( ! gl_load24bit . value )
2008-11-09 22:29:28 +00:00
replstr = " " ;
2007-09-13 22:27:56 +00:00
COM_StripExtension ( mod - > name , mdlbase , sizeof ( mdlbase ) ) ;
2008-11-09 22:29:28 +00:00
while ( replstr )
2007-09-13 22:27:56 +00:00
{
2008-11-09 22:29:28 +00:00
replstr = COM_ParseStringSet ( replstr ) ;
if ( replstr )
2007-09-13 22:27:56 +00:00
buf = ( unsigned * ) COM_LoadStackFile ( va ( " %s.%s " , mdlbase , com_token ) , stackbuf , sizeof ( stackbuf ) ) ;
2008-11-09 22:29:28 +00:00
else
2007-09-13 22:27:56 +00:00
{
buf = ( unsigned * ) COM_LoadStackFile ( mod - > name , stackbuf , sizeof ( stackbuf ) ) ;
if ( ! buf )
{
# ifdef DOOMWADS
if ( doomsprite ) // special case needed for doom sprites
{
mod - > needload = false ;
2009-11-04 21:16:50 +00:00
RMod_LoadDoomSprite ( mod ) ;
2007-09-13 22:27:56 +00:00
return mod ;
}
# endif
break ; // failed to load unreplaced file and nothing left
}
}
2008-11-09 22:29:28 +00:00
if ( ! buf )
continue ;
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
//
2008-12-23 02:55:20 +00:00
Mod_DoCRC ( mod , ( char * ) buf , com_filesize ) ;
2010-05-01 22:47:47 +00:00
2007-09-13 22:27:56 +00:00
switch ( LittleLong ( * ( unsigned * ) buf ) )
{
//The binary 3d mesh model formats
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
case RAPOLYHEADER :
2007-09-13 22:27:56 +00:00
case IDPOLYHEADER :
if ( ! Mod_LoadQ1Model ( mod , buf ) )
continue ;
break ;
2010-05-01 22:47:47 +00:00
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 ;
2010-09-15 09:06:31 +00:00
# endif
# ifdef DPMMODELS
2007-09-13 22:27:56 +00:00
case ( ( ' K ' < < 24 ) + ( ' R ' < < 16 ) + ( ' A ' < < 8 ) + ' D ' ) :
if ( ! Mod_LoadDarkPlacesModel ( mod , buf ) )
continue ;
break ;
2004-08-22 22:29:09 +00:00
# endif
2010-09-15 09:06:31 +00:00
# ifdef PSKMODELS
case ( ' A ' < < 0 ) + ( ' C ' < < 8 ) + ( ' T ' < < 16 ) + ( ' R ' < < 24 ) :
if ( ! Mod_LoadPSKModel ( mod , buf ) )
continue ;
break ;
# endif
2011-05-20 04:10:46 +00:00
# ifdef INTERQUAKEMODELS
case ( ' I ' < < 0 ) + ( ' N ' < < 8 ) + ( ' T ' < < 16 ) + ( ' E ' < < 24 ) :
if ( ! Mod_LoadInterQuakeModel ( mod , buf ) )
continue ;
break ;
# 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 :
2009-11-04 21:16:50 +00:00
if ( ! RMod_LoadSprite2Model ( mod , buf ) )
2007-09-13 22:27:56 +00:00
continue ;
break ;
2004-08-22 22:29:09 +00:00
# endif
2007-09-13 22:27:56 +00:00
case IDSPRITEHEADER :
2009-11-04 21:16:50 +00:00
if ( ! RMod_LoadSpriteModel ( mod , buf ) )
2007-09-13 22:27:56 +00:00
continue ;
break ;
2007-05-25 22:16:29 +00:00
2007-09-13 22:27:56 +00:00
//Binary Map formats
2010-05-01 22:47:47 +00:00
# if defined(Q2BSPS) || defined(Q3BSPS)
2010-03-14 14:35:56 +00:00
case ( ' F ' < < 0 ) + ( ' B ' < < 8 ) + ( ' S ' < < 16 ) + ( ' P ' < < 24 ) :
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
2010-07-25 15:12:12 +00:00
# ifdef MAP_DOOM
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
2011-12-05 15:23:40 +00:00
case BSPVERSION_LONG :
2009-11-04 21:16:50 +00:00
if ( ! RMod_LoadBrushModel ( mod , buf ) )
2007-09-13 22:27:56 +00:00
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
2010-07-25 15:12:12 +00:00
# ifdef MAP_PROC
2011-02-25 04:22:14 +00:00
if ( ! strcmp ( com_token , " CM " ) ) //doom3 map.
2010-07-25 15:12:12 +00:00
{
2011-02-25 04:22:14 +00:00
if ( ! D3_LoadMap_CollisionMap ( mod , ( char * ) buf ) )
2010-07-25 15:12:12 +00:00
continue ;
break ;
}
# 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 ;
}
2010-12-05 02:46:07 +00:00
P_LoadedModel ( mod ) ;
2007-09-13 22:27:56 +00:00
Validation_IncludeFile ( mod - > name , ( char * ) buf , com_filesize ) ;
return mod ;
2004-08-22 22:29:09 +00:00
}
2009-11-04 21:16:50 +00:00
# ifdef Q2BSPS
2007-09-13 22:27:56 +00:00
couldntload :
2009-11-04 21:16:50 +00:00
# endif
2007-09-13 22:27:56 +00:00
if ( crash )
Host_EndGame ( " Mod_NumForName: %s not found or couldn't load " , mod - > name ) ;
2011-07-30 14:14:56 +00:00
if ( * mod - > name ! = ' * ' )
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 ;
2010-12-05 02:46:07 +00:00
P_LoadedModel ( mod ) ;
2004-08-22 22:29:09 +00:00
return mod ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_ForName
Loads in a model for the given name
= = = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
model_t * RMod_ForName ( char * name , qboolean crash )
2004-08-22 22:29:09 +00:00
{
model_t * mod ;
2009-11-04 21:16:50 +00:00
mod = RMod_FindName ( name ) ;
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
return RMod_LoadModel ( mod , crash ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
BRUSHMODEL LOADING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
qbyte * mod_base ;
2009-11-04 21:16:50 +00:00
#if 0
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
2009-11-04 21:16:50 +00:00
static char * RMod_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 = = ' { ' )
2009-11-04 21:16:50 +00:00
file = RMod_TD_LeaveSection ( file ) ;
2004-09-01 22:59:56 +00:00
else if ( * com_token = = ' } ' )
return file ;
}
return NULL ;
}
2009-11-04 21:16:50 +00:00
static char * RMod_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 = = ' { ' )
2009-11-04 21:16:50 +00:00
file = RMod_TD_LeaveSection ( file ) ;
2004-09-01 22:59:56 +00:00
}
return NULL ;
}
2009-11-04 21:16:50 +00:00
void RMod_InitTextureDescs ( char * mapname )
2004-09-01 22:59:56 +00:00
{
if ( advtexturedesc )
2009-05-24 10:11:17 +00:00
FS_FreeFile ( advtexturedesc ) ;
FS_LoadFile ( va ( " maps/shaders/%s.shaders " , mapname ) , ( void * * ) & advtexturedesc ) ;
2004-09-20 23:25:38 +00:00
if ( ! advtexturedesc )
2009-05-24 10:11:17 +00:00
FS_LoadFile ( va ( " shaders/%s.shaders " , mapname ) , ( void * * ) & advtexturedesc ) ;
2004-09-01 22:59:56 +00:00
if ( advtexturedesc )
{
mapsection = advtexturedesc ;
defaultsection = NULL ;
}
else
{
2009-05-24 10:11:17 +00:00
FS_LoadFile ( va ( " map.shaders " , mapname ) , ( void * * ) & advtexturedesc ) ;
2009-11-04 21:16:50 +00:00
mapsection = RMod_TD_Section ( advtexturedesc , mapname ) ;
defaultsection = RMod_TD_Section ( advtexturedesc , " default " ) ;
2004-09-01 22:59:56 +00:00
}
}
2009-11-04 21:16:50 +00:00
void RMod_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
2009-11-04 21:16:50 +00:00
section = RMod_TD_Section ( section , name ) ;
2004-09-01 22:59:56 +00:00
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 ;
2009-11-04 21:16:50 +00:00
TRACE ( ( " dbg: RMod_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 )
2009-11-04 21:16:50 +00:00
* norm = Mod_LoadHiResTexture ( normname , NULL , IF_NOALPHA | IF_NOGAMMA ) ;
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 )
2009-11-04 21:16:50 +00:00
* base = Mod_LoadHiResTexture ( flatname , NULL , IF_NOALPHA ) ;
2004-09-01 22:59:56 +00:00
}
else
{
* base = 0 ;
if ( norm )
* norm = 0 ;
}
if ( ! * base & & * stdname )
2009-11-04 21:16:50 +00:00
* base = Mod_LoadHiResTexture ( stdname , NULL , IF_NOALPHA ) ;
2004-09-01 22:59:56 +00:00
if ( ! * base & & * flatname )
2009-11-04 21:16:50 +00:00
* base = Mod_LoadHiResTexture ( flatname , NULL , IF_NOALPHA ) ;
2004-09-01 22:59:56 +00:00
if ( luma & & * lumaname )
2009-11-04 21:16:50 +00:00
* luma = Mod_LoadHiResTexture ( lumaname , NULL , 0 ) ;
2004-09-20 23:25:38 +00:00
if ( * norm & & gloss & & * glossname & & gl_specular . value )
2009-11-04 21:16:50 +00:00
* gloss = Mod_LoadHiResTexture ( glossname , NULL , 0 ) ;
2004-09-01 22:59:56 +00:00
}
2009-11-04 21:16:50 +00:00
void RMod_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 )
{
2009-11-04 21:16:50 +00:00
RMod_LoadAdvancedTextureSection ( mapsection , name , base , norm , luma , gloss , alphamode , cull ) ;
2004-09-01 22:59:56 +00:00
if ( * base )
return ;
}
if ( defaultsection )
2009-11-04 21:16:50 +00:00
RMod_LoadAdvancedTextureSection ( defaultsection , name , base , norm , luma , gloss , alphamode , cull ) ;
}
# endif
void Mod_FinishTexture ( texture_t * tx , texnums_t tn )
{
extern cvar_t gl_shadeq1_name ;
char altname [ MAX_QPATH ] ;
char * star ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
/*skies? just replace with the override sky*/
if ( ! strncmp ( tx - > name , " sky " , 3 ) & & * cl . skyname )
tx - > shader = R_RegisterCustom ( va ( " skybox_%s " , cl . skyname ) , Shader_DefaultSkybox , NULL ) ; //just load the regular name.
2009-11-04 21:16:50 +00:00
//find the *
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
else if ( ! * gl_shadeq1_name . string | | ! strcmp ( gl_shadeq1_name . string , " * " ) )
2010-07-11 02:22:39 +00:00
tx - > shader = R_RegisterCustom ( tx - > name , Shader_DefaultBSPQ1 , NULL ) ; //just load the regular name.
2009-11-04 21:16:50 +00:00
else if ( ! ( star = strchr ( gl_shadeq1_name . string , ' * ' ) ) | | ( strlen ( gl_shadeq1_name . string ) + strlen ( tx - > name ) + 1 > = sizeof ( altname ) ) ) //it's got to fit.
2010-07-11 02:22:39 +00:00
tx - > shader = R_RegisterCustom ( gl_shadeq1_name . string , Shader_DefaultBSPQ1 , NULL ) ;
2009-11-04 21:16:50 +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 , tx - > name ) ; //insert the *
strcat ( altname , star + 1 ) ; //add any final text.
2010-07-11 02:22:39 +00:00
tx - > shader = R_RegisterCustom ( altname , Shader_DefaultBSPQ1 , NULL ) ;
2009-11-04 21:16:50 +00:00
}
R_BuildDefaultTexnums ( & tn , tx - > shader ) ;
2004-09-01 22:59:56 +00:00
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_LoadTextures
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
qboolean RMod_LoadTextures ( lump_t * l )
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 ;
2009-11-04 21:16:50 +00:00
texnums_t tn ;
2004-09-01 22:59:56 +00:00
2009-11-04 21:16:50 +00:00
TRACE ( ( " dbg: RMod_LoadTextures: inittexturedescs \n " ) ) ;
2004-10-07 13:16:43 +00:00
2009-11-04 21:16:50 +00:00
// RMod_InitTextureDescs(loadname);
2004-09-20 23:25:38 +00:00
2004-08-22 22:29:09 +00:00
if ( ! l - > filelen )
{
2011-07-30 14:14:56 +00:00
loadmodel - > numtextures = 1 ;
loadmodel - > textures = Hunk_AllocName ( 1 * sizeof ( * loadmodel - > textures ) , loadname ) ;
i = 0 ;
tx = Hunk_AllocName ( sizeof ( texture_t ) , loadname ) ;
memcpy ( tx , r_notexture_mip , sizeof ( texture_t ) ) ;
sprintf ( tx - > name , " unnamed%i " , i ) ;
loadmodel - > textures [ i ] = tx ;
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
2009-10-06 00:15:55 +00:00
{
tx = Hunk_AllocName ( sizeof ( texture_t ) , loadname ) ;
memcpy ( tx , r_notexture_mip , sizeof ( texture_t ) ) ;
sprintf ( tx - > name , " unnamed%i " , i ) ;
loadmodel - > textures [ i ] = tx ;
2004-08-22 22:29:09 +00:00
continue ;
2009-10-06 00:15:55 +00:00
}
2004-08-22 22:29:09 +00:00
mt = ( miptex_t * ) ( ( qbyte * ) m + m - > dataofs [ i ] ) ;
2004-10-07 13:16:43 +00:00
2009-11-04 21:16:50 +00:00
TRACE ( ( " dbg: RMod_LoadTextures: texture %s \n " , loadname ) ) ;
2004-10-07 13:16:43 +00:00
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 ;
if ( ! mt - > offsets [ 0 ] ) //this is a hl external style texture, load it a little later (from a wad)
{
continue ;
}
2009-07-05 18:45:53 +00:00
2009-11-04 21:16:50 +00:00
memset ( & tn , 0 , sizeof ( tn ) ) ;
2004-08-22 22:29:09 +00:00
if ( ! Q_strncmp ( mt - > name , " sky " , 3 ) )
{
2011-01-04 02:56:16 +00:00
R_InitSky ( & tn , tx , ( char * ) mt + mt - > offsets [ 0 ] ) ;
2004-08-22 22:29:09 +00:00
}
else
{
2009-11-04 21:16:50 +00:00
/*
RMod_LoadAdvancedTexture ( tx - > name , & tn . base , & tn . bump , & tn . fullbright , & tn . specular , NULL , NULL ) ;
if ( tn . base )
2004-09-01 22:59:56 +00:00
continue ;
2009-11-04 21:16:50 +00:00
*/
2004-09-01 22:59:56 +00:00
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 ;
2009-11-04 21:16:50 +00:00
tn . base = R_LoadReplacementTexture ( mt - > name , loadname , alphaed ? 0 : IF_NOALPHA ) ;
if ( ! TEXVALID ( tn . base ) )
{
tn . base = R_LoadReplacementTexture ( mt - > name , " bmodels " , alphaed ? 0 : IF_NOALPHA ) ;
if ( ! TEXVALID ( tn . base ) )
tn . base = R_LoadTexture32 ( mt - > name , tx - > width , tx - > height , ( unsigned int * ) base , ( alphaed ? 0 : IF_NOALPHA ) ) ;
}
2004-08-22 22:29:09 +00:00
* tx - > name = * mt - > name ;
}
else
{
2009-11-04 21:16:50 +00:00
qbyte * mipbase ;
unsigned int mipwidth , mipheight ;
extern cvar_t gl_miptexLevel ;
if ( ( unsigned int ) gl_miptexLevel . ival < 4 & & mt - > offsets [ gl_miptexLevel . ival ] )
{
mipbase = ( qbyte * ) mt + mt - > offsets [ gl_miptexLevel . ival ] ;
mipwidth = tx - > width > > gl_miptexLevel . ival ;
mipheight = tx - > height > > gl_miptexLevel . ival ;
}
else
{
mipbase = base ;
mipwidth = tx - > width ;
mipheight = tx - > height ;
}
2012-01-01 02:26:42 +00:00
tn . base = R_LoadReplacementTexture ( mt - > name , loadname , ( ( * mt - > name = = ' { ' ) ? 0 : IF_NOALPHA ) | IF_SUBDIRONLY | IF_MIPCAP ) ;
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( tn . base ) )
{
2012-01-01 02:26:42 +00:00
tn . base = R_LoadReplacementTexture ( mt - > name , " bmodels " , ( ( * mt - > name = = ' { ' ) ? 0 : IF_NOALPHA ) | IF_MIPCAP ) ;
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( tn . base ) )
2012-01-01 02:26:42 +00:00
tn . base = R_LoadTexture8 ( mt - > name , mipwidth , mipheight , mipbase , ( ( * mt - > name = = ' { ' ) ? 0 : IF_NOALPHA ) | IF_MIPCAP , 1 ) ;
2009-11-04 21:16:50 +00:00
}
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
{
2012-01-01 02:26:42 +00:00
tn . fullbright = R_LoadReplacementTexture ( altname , loadname , IF_NOGAMMA | IF_SUBDIRONLY | IF_MIPCAP ) ;
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( tn . fullbright ) )
2012-01-01 02:26:42 +00:00
tn . fullbright = R_LoadReplacementTexture ( altname , " bmodels " , IF_NOGAMMA | IF_MIPCAP ) ;
2004-08-22 22:29:09 +00:00
}
2010-08-14 00:15:07 +00:00
if ( ( * mt - > name ! = ' { ' ) & & ! TEXVALID ( tn . fullbright ) ) //generate one (if possible).
2012-01-01 02:26:42 +00:00
tn . fullbright = R_LoadTextureFB ( altname , mipwidth , mipheight , mipbase , IF_NOGAMMA | IF_MIPCAP ) ;
2004-08-22 22:29:09 +00:00
}
}
2009-11-04 21:16:50 +00:00
tn . bump = r_nulltex ;
2011-10-27 16:16:29 +00:00
if ( r_loadbumpmapping )
2004-09-01 22:59:56 +00:00
{
2011-10-27 16:16:29 +00:00
if ( r_loadbumpmapping )
2004-09-30 22:45:08 +00:00
{
2006-03-06 01:41:09 +00:00
snprintf ( altname , sizeof ( altname ) - 1 , " %s_norm " , mt - > name ) ;
2012-01-01 02:26:42 +00:00
tn . bump = R_LoadReplacementTexture ( altname , loadname , IF_NOGAMMA | IF_SUBDIRONLY | IF_MIPCAP ) ;
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( tn . bump ) )
2012-01-01 02:26:42 +00:00
tn . bump = R_LoadReplacementTexture ( altname , " bmodels " , IF_NOGAMMA | IF_MIPCAP ) ;
2004-09-30 22:45:08 +00:00
}
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( tn . bump ) )
2004-09-30 22:45:08 +00:00
{
if ( gl_load24bit . value )
{
2006-03-06 01:41:09 +00:00
snprintf ( altname , sizeof ( altname ) - 1 , " %s_bump " , mt - > name ) ;
2009-11-04 21:16:50 +00:00
tn . bump = R_LoadBumpmapTexture ( altname , loadname ) ;
if ( ! TEXVALID ( tn . bump ) )
tn . bump = R_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
2011-12-23 03:12:29 +00:00
/* if (!TEXVALID(tn.bump) && loadmodel->fromgame != fg_halflife)
2004-09-01 22:59:56 +00:00
{
2009-11-04 21:16:50 +00:00
//no mip levels here, would be absurd.
2004-09-01 22:59:56 +00:00
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
2009-11-05 03:07:52 +00:00
tn . bump = R_LoadTexture8BumpPal ( altname , tx - > width , tx - > height , base , true ) ; //normalise it and then bump it.
2004-09-01 22:59:56 +00:00
}
2011-12-23 03:12:29 +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 ) ;
2012-01-01 11:22:24 +00:00
tn . specular = R_LoadHiResTexture ( altname , loadname , IF_NOGAMMA | IF_SUBDIRONLY | IF_MIPCAP ) ;
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( tn . specular ) )
2012-01-01 11:22:24 +00:00
tn . specular = R_LoadHiResTexture ( altname , " bmodels " , IF_NOGAMMA | IF_MIPCAP ) ;
2004-09-13 03:20:04 +00:00
}
2004-08-22 22:29:09 +00:00
}
}
2009-11-04 21:16:50 +00:00
Mod_FinishTexture ( tx , tn ) ;
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
}
2009-11-04 21:16:50 +00:00
void RMod_NowLoadExternal ( void )
2004-08-22 22:29:09 +00:00
{
extern int gl_bumpmappingpossible ;
int i , width , height ;
qboolean alphaed ;
texture_t * tx ;
2009-11-04 21:16:50 +00:00
texnums_t tn ;
2004-09-30 22:45:08 +00:00
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 ;
2009-11-04 21:16:50 +00:00
if ( tx - > shader )
continue ;
memset ( & tn , 0 , sizeof ( tn ) ) ;
if ( ! TEXVALID ( tn . base ) )
2004-08-22 22:29:09 +00:00
{
2011-03-24 14:35:24 +00:00
qbyte * data ;
2004-08-22 22:29:09 +00:00
2011-03-24 14:35:24 +00:00
data = W_GetTexture ( tx - > name , & width , & height , & alphaed ) ;
if ( data )
{ //data is from temp hunk, so no need to free.
tx - > alphaed = alphaed ;
}
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
tn . base = R_LoadHiResTexture ( tx - > name , loadname , IF_NOALPHA | IF_MIPCAP ) ;
2011-03-24 14:35:24 +00:00
if ( ! TEXVALID ( tn . base ) )
{
2012-01-01 02:26:42 +00:00
tn . base = R_LoadHiResTexture ( tx - > name , " bmodels " , IF_NOALPHA | IF_MIPCAP ) ;
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( tn . base ) )
2012-01-01 02:26:42 +00:00
tn . base = R_LoadReplacementTexture ( " light1_4 " , NULL , IF_NOALPHA | IF_MIPCAP ) ; //a fallback. :/
2004-08-22 22:29:09 +00:00
}
}
2011-10-27 16:16:29 +00:00
if ( ! TEXVALID ( tn . bump ) & & * tx - > name ! = ' { ' & & r_loadbumpmapping )
2004-08-22 22:29:09 +00:00
{
2009-11-04 21:16:50 +00:00
tn . bump = R_LoadBumpmapTexture ( va ( " %s_bump " , tx - > name ) , loadname ) ;
if ( ! TEXVALID ( tn . bump ) )
tn . bump = R_LoadBumpmapTexture ( va ( " %s_bump " , tx - > name ) , " bmodels " ) ;
2011-12-23 03:12:29 +00:00
/* if (!TEXVALID(tn.bump))
2004-08-22 22:29:09 +00:00
{
qbyte * data ;
qbyte * heightmap ;
int width , height ;
int j ;
data = W_GetTexture ( tx - > name , & width , & height , & alphaed ) ;
2009-11-04 21:16:50 +00:00
if ( data )
2004-08-22 22:29:09 +00:00
{
2009-11-04 21:16:50 +00:00
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 ;
}
2009-11-05 03:07:52 +00:00
tn . bump = R_LoadTexture8BumpPal ( va ( " %s_bump " , tx - > name ) , width , height , heightmap - j , true ) ;
2004-08-22 22:29:09 +00:00
}
}
2011-12-23 03:12:29 +00:00
*/ }
2011-07-30 14:14:56 +00:00
if ( ! TEXVALID ( tn . base ) )
{
tn . base = R_LoadTexture8 ( " notexture " , 16 , 16 , r_notexture_mip + 1 , IF_NOALPHA , 0 ) ;
}
2009-11-04 21:16:50 +00:00
Mod_FinishTexture ( tx , tn ) ;
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_LoadLighting ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
qbyte * luxdata = NULL ;
2004-10-19 16:10:14 +00:00
int mapcomeswith24bitcolouredlighting = false ;
2011-10-27 16:16:29 +00:00
extern cvar_t gl_overbright ;
2005-08-06 22:39:28 +00:00
loadmodel - > engineflags & = ~ MDLF_RGBLIGHTING ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
//q3 maps have built in 4-fold overbright.
//if we're not rendering with that, we need to brighten the lightmaps in order to keep the darker parts the same brightness. we loose the 2 upper bits. those bright areas become uniform and indistinct.
if ( loadmodel - > fromgame = = fg_quake3 )
{
gl_overbright . flags | = CVAR_LATCH ;
BuildLightMapGammaTable ( 1 , ( 1 < < ( 2 - gl_overbright . ival ) ) ) ;
}
else
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 ;
2011-10-27 16:16:29 +00:00
if ( ! mapcomeswith24bitcolouredlighting & & r_loadlits . ival & & r_deluxemapping . ival ) //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 ) ;
}
2009-11-04 21:16:50 +00:00
if ( ! luxdata )
{
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , luxname + 5 , sizeof ( luxname ) - 5 ) ;
COM_DefaultExtension ( luxname , " .dlit " , sizeof ( luxname ) ) ;
luxdata = COM_LoadHunkFile ( luxname ) ;
}
2004-08-22 22:29:09 +00:00
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
2011-10-27 16:16:29 +00:00
else if ( r_loadlits . value = = 2 & & ! lightmodel & & ( ! ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) | | ( ! luxdata & & r_deluxemapping . ival ) ) )
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 + + ;
}
2011-10-27 16:16:29 +00:00
if ( r_deluxemapping . ival )
2004-08-22 22:29:09 +00:00
{
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 ;
{
2009-11-04 21:16:50 +00:00
for ( i = 0 ; i < l - > filelen ; i + + )
{
* litdata + + = 0.5f * 255 ;
2004-08-22 22:29:09 +00:00
* litdata + + = 0.5f * 255 ;
2009-11-04 21:16:50 +00:00
* litdata + + = 255 ;
}
2004-08-22 22:29:09 +00:00
}
}
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_LoadVisibility ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_LoadEntities ( lump_t * l )
2004-08-22 22:29:09 +00:00
{
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
qboolean RMod_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 ;
2009-11-04 21:16:50 +00:00
qboolean RMod_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
= = = = = = = = = = = = = = = = =
*/
2011-10-27 16:16:29 +00:00
qboolean RMod_LoadEdges ( lump_t * l , qboolean lm )
2004-08-22 22:29:09 +00:00
{
medge_t * out ;
int i , count ;
2011-10-27 16:16:29 +00:00
if ( lm )
2006-03-12 22:01:49 +00:00
{
2011-10-27 16:16:29 +00:00
dledge_t * in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
{
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( ( count + 1 ) * sizeof ( * out ) , loadname ) ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
loadmodel - > edges = out ;
loadmodel - > numedges = count ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
out - > v [ 0 ] = LittleLong ( in - > v [ 0 ] ) ;
out - > v [ 1 ] = LittleLong ( in - > v [ 1 ] ) ;
}
}
else
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
dsedge_t * in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
{
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
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 ] ) ;
}
2004-08-22 22:29:09 +00:00
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadTexinfo
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
qboolean RMod_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 + + )
{
2012-01-02 14:59:00 +00:00
for ( j = 0 ; j < 4 ; j + + )
{
2004-08-22 22:29:09 +00:00
out - > vecs [ 0 ] [ j ] = LittleFloat ( in - > vecs [ 0 ] [ j ] ) ;
2012-01-02 14:59:00 +00:00
out - > vecs [ 1 ] [ j ] = LittleFloat ( in - > vecs [ 1 ] [ j ] ) ;
}
2004-08-22 22:29:09 +00:00
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 ) ;
2011-10-27 16:16:29 +00:00
if ( loadmodel - > numtextures )
out - > texture = loadmodel - > textures [ miptex % loadmodel - > numtextures ] ;
else
out - > texture = NULL ;
2011-07-30 14:14:56 +00:00
if ( ! out - > texture )
2004-08-22 22:29:09 +00:00
{
2011-07-30 14:14:56 +00:00
out - > texture = r_notexture_mip ; // texture not found
2004-08-22 22:29:09 +00:00
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 ) ;
2011-07-30 14:14:56 +00:00
s - > texturemins [ i ] = bmins [ i ] ;
s - > extents [ i ] = ( bmaxs [ i ] - bmins [ i ] ) ;
2004-08-22 22:29:09 +00:00
// if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 ) //q2 uses 512.
// Sys_Error ("Bad surface extents");
}
}
*/
/*
= = = = = = = = = = = = = = = = =
Mod_LoadFaces
= = = = = = = = = = = = = = = = =
*/
2011-10-27 16:16:29 +00:00
qboolean RMod_LoadFaces ( lump_t * l , qboolean lm )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
dsface_t * ins ;
dlface_t * inl ;
2004-08-22 22:29:09 +00:00
msurface_t * out ;
2011-10-27 16:16:29 +00:00
int count , surfnum ;
int i , planenum , side ;
int tn , lofs ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
if ( lm )
2006-03-12 22:01:49 +00:00
{
2011-10-27 16:16:29 +00:00
ins = NULL ;
inl = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * inl ) )
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * inl ) ;
}
else
{
ins = ( void * ) ( mod_base + l - > fileofs ) ;
inl = NULL ;
if ( l - > filelen % sizeof ( * ins ) )
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * ins ) ;
2006-03-12 22:01:49 +00:00
}
2004-08-22 22:29:09 +00:00
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > surfaces = out ;
loadmodel - > numsurfaces = count ;
2011-10-27 16:16:29 +00:00
for ( surfnum = 0 ; surfnum < count ; surfnum + + , out + + )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
if ( lm )
{
planenum = LittleLong ( inl - > planenum ) ;
side = LittleLong ( inl - > side ) ;
out - > firstedge = LittleLong ( inl - > firstedge ) ;
out - > numedges = LittleLong ( inl - > numedges ) ;
tn = LittleLong ( inl - > texinfo ) ;
for ( i = 0 ; i < MAXLIGHTMAPS ; i + + )
out - > styles [ i ] = inl - > styles [ i ] ;
lofs = LittleLong ( inl - > lightofs ) ;
inl + + ;
}
else
{
planenum = LittleShort ( ins - > planenum ) ;
side = LittleShort ( ins - > side ) ;
out - > firstedge = LittleLong ( ins - > firstedge ) ;
out - > numedges = LittleShort ( ins - > numedges ) ;
tn = LittleShort ( ins - > texinfo ) ;
for ( i = 0 ; i < MAXLIGHTMAPS ; i + + )
out - > styles [ i ] = ins - > styles [ i ] ;
lofs = LittleLong ( ins - > lightofs ) ;
ins + + ;
}
2004-08-22 22:29:09 +00:00
out - > flags = 0 ;
if ( side )
out - > flags | = SURF_PLANEBACK ;
out - > plane = loadmodel - > planes + planenum ;
2004-12-29 03:22:09 +00:00
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 ) ;
2011-10-27 16:16:29 +00:00
if ( lofs = = - 1 )
2004-08-22 22:29:09 +00:00
out - > samples = NULL ;
2005-08-06 22:39:28 +00:00
else if ( ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) & & loadmodel - > fromgame ! = fg_halflife )
2011-10-27 16:16:29 +00:00
out - > samples = loadmodel - > lightdata + lofs * 3 ;
2004-08-22 22:29:09 +00:00
else
2011-10-27 16:16:29 +00:00
out - > samples = loadmodel - > lightdata + lofs ;
2004-08-22 22:29:09 +00:00
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 ;
}
2008-12-23 02:55:20 +00:00
/*if (*out->texinfo->texture->name == '~')
{
out - > texinfo - > flags | = SURF_BLENDED ;
continue ;
} */
2004-08-22 22:29:09 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_SetParent ( mnode_t * node , mnode_t * parent )
2004-08-22 22:29:09 +00:00
{
if ( ! node )
return ;
node - > parent = parent ;
if ( node - > contents < 0 )
return ;
2009-11-04 21:16:50 +00:00
RMod_SetParent ( node - > children [ 0 ] , node ) ;
RMod_SetParent ( node - > children [ 1 ] , node ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadNodes
= = = = = = = = = = = = = = = = =
*/
2011-10-27 16:16:29 +00:00
qboolean RMod_LoadNodes ( lump_t * l , qboolean lm )
2004-08-22 22:29:09 +00:00
{
int i , j , count , p ;
mnode_t * out ;
2011-10-27 16:16:29 +00:00
if ( lm )
2006-03-12 22:01:49 +00:00
{
2011-10-27 16:16:29 +00:00
dlnode_t * in ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
loadmodel - > nodes = out ;
loadmodel - > numnodes = count ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
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 = LittleLong ( in - > firstface ) ;
out - > numsurfaces = LittleLong ( in - > numfaces ) ;
for ( j = 0 ; j < 2 ; j + + )
{
2011-12-05 15:23:40 +00:00
p = LittleLong ( in - > children [ j ] ) ;
2011-10-27 16:16:29 +00:00
if ( p > = 0 )
out - > children [ j ] = loadmodel - > nodes + p ;
else
out - > children [ j ] = ( mnode_t * ) ( loadmodel - > leafs + ( - 1 - p ) ) ;
}
}
}
else
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
dsnode_t * in ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
2004-08-22 22:29:09 +00:00
}
2011-10-27 16:16:29 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
loadmodel - > nodes = out ;
loadmodel - > numnodes = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
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 ) ) ;
}
2004-08-22 22:29:09 +00:00
}
}
2009-11-04 21:16:50 +00:00
RMod_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
= = = = = = = = = = = = = = = = =
*/
2011-10-27 16:16:29 +00:00
qboolean RMod_LoadLeafs ( lump_t * l , qboolean lm )
2004-08-22 22:29:09 +00:00
{
mleaf_t * out ;
int i , j , count , p ;
2011-10-27 16:16:29 +00:00
if ( lm )
2006-03-12 22:01:49 +00:00
{
2011-10-27 16:16:29 +00:00
dlleaf_t * in ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
loadmodel - > leafs = out ;
loadmodel - > numleafs = count ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
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 +
LittleLong ( in - > firstmarksurface ) ;
out - > nummarksurfaces = LittleLong ( in - > nummarksurfaces ) ;
p = LittleLong ( in - > visofs ) ;
if ( p = = - 1 )
out - > compressed_vis = NULL ;
else
out - > compressed_vis = loadmodel - > visdata + p ;
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 ;
}
}
}
}
else
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
dsleaf_t * in ;
in = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
2004-08-22 22:29:09 +00:00
}
2011-10-27 16:16:29 +00:00
count = l - > filelen / sizeof ( * in ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
loadmodel - > leafs = out ;
loadmodel - > numleafs = count ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
for ( i = 0 ; i < count ; i + + , in + + , out + + )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
for ( j = 0 ; j < 3 ; j + + )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
out - > minmaxs [ j ] = LittleShort ( in - > mins [ j ] ) ;
out - > minmaxs [ 3 + j ] = LittleShort ( in - > maxs [ j ] ) ;
2004-08-22 22:29:09 +00:00
}
2011-10-27 16:16:29 +00:00
p = LittleLong ( in - > contents ) ;
out - > contents = p ;
out - > firstmarksurface = loadmodel - > marksurfaces +
( unsigned short ) LittleShort ( in - > firstmarksurface ) ;
out - > nummarksurfaces = ( unsigned short ) LittleShort ( in - > nummarksurfaces ) ;
p = LittleLong ( in - > visofs ) ;
if ( p = = - 1 )
out - > compressed_vis = NULL ;
else
out - > compressed_vis = loadmodel - > visdata + p ;
for ( j = 0 ; j < 4 ; j + + )
out - > ambient_sound_level [ j ] = in - > ambient_level [ j ] ;
# ifndef CLIENTONLY
if ( ! isDedicated )
# endif
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
// 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 ;
}
2004-08-22 22:29:09 +00:00
}
}
2011-10-27 16:16:29 +00:00
}
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 ;
2009-11-04 21:16:50 +00:00
void RMod_LoadCrouchHull ( void )
2004-08-22 22:29:09 +00:00
{
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
2009-05-24 10:11:17 +00:00
FS_LoadFile ( crouchhullname , & crouchhullfile ) ;
2004-08-22 22:29:09 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2011-10-27 16:16:29 +00:00
qboolean RMod_LoadClipnodes ( lump_t * l , qboolean lm )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
dsclipnode_t * ins ;
2011-12-05 15:23:40 +00:00
dlclipnode_t * inl ;
2011-06-29 18:39:11 +00:00
mclipnode_t * out ;
2004-08-22 22:29:09 +00:00
int i , count ;
hull_t * hull ;
2011-10-27 16:16:29 +00:00
if ( lm )
2006-03-12 22:01:49 +00:00
{
2011-10-27 16:16:29 +00:00
ins = NULL ;
inl = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * inl ) )
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * inl ) ;
}
else
{
ins = ( void * ) ( mod_base + l - > fileofs ) ;
inl = NULL ;
if ( l - > filelen % sizeof ( * ins ) )
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * ins ) ;
2006-03-12 22:01:49 +00:00
}
2004-08-22 22:29:09 +00:00
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 ;
2010-08-18 21:59:06 +00:00
/*
There is some mission - pack weirdness here
in the missionpack , hull 4 is meant to be ' - 8 - 8 - 8 ' ' 8 8 8 '
in the original game , hull 4 is ' - 40 - 40 - 42 ' ' 40 40 42 '
*/
2004-08-22 22:29:09 +00:00
hull = & loadmodel - > hulls [ 4 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
2010-08-18 21:59:06 +00:00
hull - > clip_mins [ 0 ] = - 8 ;
hull - > clip_mins [ 1 ] = - 8 ;
hull - > clip_mins [ 2 ] = - 8 ;
hull - > clip_maxs [ 0 ] = 8 ;
hull - > clip_maxs [ 1 ] = 8 ;
hull - > clip_maxs [ 2 ] = 8 ;
2004-08-22 22:29:09 +00:00
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 ;
2010-08-18 21:59:06 +00:00
hull - > clip_mins [ 2 ] = - 50 ;
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 ;
2008-11-09 22:29:28 +00:00
//6 isn't used.
//7 isn't used.
2004-08-22 22:29:09 +00:00
}
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 ;
2009-04-01 22:03:56 +00:00
hull - > clip_mins [ 2 ] = - 36 ; //-36 is correct here, but mvdsv uses -32 instead. This breaks prediction between the two
2004-08-22 22:29:09 +00:00
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
2008-11-09 22:29:28 +00:00
hull - > clip_maxs [ 2 ] = hull - > clip_mins [ 2 ] + 72 ;
2004-08-22 22:29:09 +00:00
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 ;
2008-11-09 22:29:28 +00:00
hull - > clip_maxs [ 2 ] = hull - > clip_mins [ 2 ] + 64 ;
2004-08-22 22:29:09 +00:00
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 ;
2008-11-09 22:29:28 +00:00
hull - > clip_maxs [ 2 ] = hull - > clip_mins [ 2 ] + 36 ;
2004-08-22 22:29:09 +00:00
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 ;
}
2011-10-27 16:16:29 +00:00
if ( lm )
2011-07-30 14:14:56 +00:00
{
2011-10-27 16:16:29 +00:00
for ( i = 0 ; i < count ; i + + , out + + , inl + + )
2011-07-30 14:14:56 +00:00
{
2011-10-27 16:16:29 +00:00
out - > planenum = LittleLong ( inl - > planenum ) ;
out - > children [ 0 ] = LittleLong ( inl - > children [ 0 ] ) ;
out - > children [ 1 ] = LittleLong ( inl - > children [ 1 ] ) ;
2011-07-30 14:14:56 +00:00
}
}
else
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
for ( i = 0 ; i < count ; i + + , out + + , ins + + )
2011-07-30 14:14:56 +00:00
{
2011-10-27 16:16:29 +00:00
out - > planenum = LittleLong ( ins - > planenum ) ;
out - > children [ 0 ] = LittleShort ( ins - > children [ 0 ] ) ;
out - > children [ 1 ] = LittleShort ( ins - > children [ 1 ] ) ;
2011-07-30 14:14:56 +00:00
}
2004-08-22 22:29:09 +00:00
}
if ( numsuplementryclipnodes ) //now load the crouch ones.
{
2010-07-12 22:46:37 +00:00
/*This looks buggy*/
2004-08-22 22:29:09 +00:00
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 ;
}
2011-10-27 16:16:29 +00:00
ins = suplementryclipnodes ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
for ( i = 0 ; i < numsuplementryclipnodes ; i + + , out + + , ins + + )
2004-08-22 22:29:09 +00:00
{
2011-10-27 16:16:29 +00:00
out - > planenum = LittleLong ( ins - > planenum ) ;
out - > children [ 0 ] = LittleShort ( ins - > children [ 0 ] ) ;
2004-08-22 22:29:09 +00:00
out - > children [ 0 ] + = out - > children [ 0 ] > = 0 ? 1 : 0 ;
2011-10-27 16:16:29 +00:00
out - > children [ 1 ] = LittleShort ( ins - > children [ 1 ] ) ;
2004-08-22 22:29:09 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_MakeHull0 ( void )
2004-08-22 22:29:09 +00:00
{
mnode_t * in , * child ;
2011-06-29 18:39:11 +00:00
mclipnode_t * out ;
2004-08-22 22:29:09 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2011-12-05 15:23:40 +00:00
qboolean RMod_LoadMarksurfaces ( lump_t * l , qboolean lm )
2004-08-22 22:29:09 +00:00
{
int i , j , count ;
msurface_t * * out ;
2011-12-05 15:23:40 +00:00
if ( lm )
2006-03-12 22:01:49 +00:00
{
2011-12-05 15:23:40 +00:00
int * inl ;
inl = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * inl ) )
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
count = l - > filelen / sizeof ( * inl ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
2004-08-22 22:29:09 +00:00
2011-12-05 15:23:40 +00:00
loadmodel - > marksurfaces = out ;
loadmodel - > nummarksurfaces = count ;
2004-08-22 22:29:09 +00:00
2011-12-05 15:23:40 +00:00
for ( i = 0 ; i < count ; i + + )
{
j = ( unsigned int ) LittleLong ( inl [ i ] ) ;
if ( j > = loadmodel - > numsurfaces )
{
Con_Printf ( CON_ERROR " Mod_ParseMarksurfaces: bad surface number \n " ) ;
return false ;
}
out [ i ] = loadmodel - > surfaces + j ;
}
}
else
2004-08-22 22:29:09 +00:00
{
2011-12-05 15:23:40 +00:00
short * ins ;
ins = ( void * ) ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * ins ) )
2006-03-12 22:01:49 +00:00
{
2011-12-05 15:23:40 +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 ;
}
2011-12-05 15:23:40 +00:00
count = l - > filelen / sizeof ( * ins ) ;
out = Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ;
loadmodel - > marksurfaces = out ;
loadmodel - > nummarksurfaces = count ;
for ( i = 0 ; i < count ; i + + )
{
j = ( unsigned short ) LittleShort ( ins [ i ] ) ;
if ( j > = loadmodel - > numsurfaces )
{
Con_Printf ( CON_ERROR " Mod_ParseMarksurfaces: bad surface number \n " ) ;
return false ;
}
out [ i ] = loadmodel - > surfaces + j ;
}
2004-08-22 22:29:09 +00:00
}
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSurfedges
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
qboolean RMod_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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
qboolean RMod_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
static void Q1BSP_StainNode ( mnode_t * node , float * parms )
{
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 + + )
{
2010-08-14 00:15:07 +00:00
if ( surf - > flags & ~ ( SURF_DRAWALPHA | SURF_DONTWARP | SURF_PLANEBACK ) )
2004-08-22 22:29:09 +00:00
continue ;
2009-11-07 13:29:15 +00:00
Surf_StainSurf ( surf , parms ) ;
2004-08-22 22:29:09 +00:00
}
Q1BSP_StainNode ( node - > children [ 0 ] , parms ) ;
Q1BSP_StainNode ( node - > children [ 1 ] , parms ) ;
}
2009-11-04 21:16:50 +00:00
void RMod_FixupNodeMinsMaxs ( mnode_t * node , mnode_t * parent )
2007-05-25 22:16:29 +00:00
{
if ( ! node )
return ;
if ( node - > contents > = 0 )
{
2009-11-04 21:16:50 +00:00
RMod_FixupNodeMinsMaxs ( node - > children [ 0 ] , node ) ;
RMod_FixupNodeMinsMaxs ( node - > children [ 1 ] , node ) ;
2007-05-25 22:16:29 +00:00
}
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 ] ;
}
}
2009-11-04 21:16:50 +00:00
void RMod_FixupMinsMaxs ( void )
2007-05-25 22:16:29 +00:00
{
//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 ) ;
}
}
2009-11-04 21:16:50 +00:00
RMod_FixupNodeMinsMaxs ( loadmodel - > nodes , NULL ) ; // sets nodes and leafs
2007-05-25 22:16:29 +00:00
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_LoadBrushModel
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
qboolean RMod_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 ;
2011-10-27 16:16:29 +00:00
qboolean longm = false ;
2009-11-15 03:20:17 +00:00
# if (defined(ODE_STATIC) || defined(ODE_DYNAMIC))
qboolean ode = true ;
# else
# define ode true
# endif
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
2009-11-04 21:16:50 +00:00
| | ( ! sv . world . worldmodel & & sv . active )
2004-08-22 22:29:09 +00:00
# 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 ;
}
2011-10-27 16:16:29 +00:00
else if ( i = = BSPVERSION_LONG )
{
longm = true ;
loadmodel - > fromgame = fg_quake ;
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 ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
# ifndef CLIENTONLY
if ( sv . state ) //if the server is running
{
if ( ! strcmp ( loadmodel - > name , va ( " maps/%s.bsp " , sv . name ) ) )
Mod_ParseInfoFromEntityLump ( loadmodel , mod_base + header - > lumps [ LUMP_ENTITIES ] . fileofs , loadname ) ;
}
else
# endif
{
if ( ! cl . model_precache [ 1 ] ) //not copied across yet
Mod_ParseInfoFromEntityLump ( loadmodel , mod_base + header - > lumps [ LUMP_ENTITIES ] . fileofs , loadname ) ;
}
2004-08-22 22:29:09 +00:00
// load into heap
2009-11-15 03:20:17 +00:00
if ( ! isDedicated | | ode )
2004-08-22 22:29:09 +00:00
{
2009-11-04 21:16:50 +00:00
noerrors = noerrors & & RMod_LoadVertexes ( & header - > lumps [ LUMP_VERTEXES ] ) ;
2011-10-27 16:16:29 +00:00
noerrors = noerrors & & RMod_LoadEdges ( & header - > lumps [ LUMP_EDGES ] , longm ) ;
2009-11-04 21:16:50 +00:00
noerrors = noerrors & & RMod_LoadSurfedges ( & header - > lumps [ LUMP_SURFEDGES ] ) ;
2009-11-15 03:20:17 +00:00
}
if ( ! isDedicated )
{
2009-11-04 21:16:50 +00:00
noerrors = noerrors & & RMod_LoadTextures ( & header - > lumps [ LUMP_TEXTURES ] ) ;
2006-03-12 22:01:49 +00:00
if ( noerrors )
2009-11-04 21:16:50 +00:00
RMod_LoadLighting ( & header - > lumps [ LUMP_LIGHTING ] ) ;
2006-03-12 22:01:49 +00:00
}
2009-11-04 21:16:50 +00:00
noerrors = noerrors & & RMod_LoadSubmodels ( & header - > lumps [ LUMP_MODELS ] ) ;
2006-03-12 22:01:49 +00:00
if ( noerrors )
2009-11-04 21:16:50 +00:00
RMod_LoadCrouchHull ( ) ;
noerrors = noerrors & & RMod_LoadPlanes ( & header - > lumps [ LUMP_PLANES ] ) ;
2009-11-15 03:20:17 +00:00
if ( ! isDedicated | | ode )
2004-08-22 22:29:09 +00:00
{
2009-11-04 21:16:50 +00:00
noerrors = noerrors & & RMod_LoadTexinfo ( & header - > lumps [ LUMP_TEXINFO ] ) ;
2011-10-27 16:16:29 +00:00
noerrors = noerrors & & RMod_LoadFaces ( & header - > lumps [ LUMP_FACES ] , longm ) ;
2009-11-15 03:20:17 +00:00
}
if ( ! isDedicated )
2011-12-05 15:23:40 +00:00
noerrors = noerrors & & RMod_LoadMarksurfaces ( & header - > lumps [ LUMP_MARKSURFACES ] , longm ) ;
2006-03-12 22:01:49 +00:00
if ( noerrors )
2009-11-04 21:16:50 +00:00
RMod_LoadVisibility ( & header - > lumps [ LUMP_VISIBILITY ] ) ;
2011-10-27 16:16:29 +00:00
noerrors = noerrors & & RMod_LoadLeafs ( & header - > lumps [ LUMP_LEAFS ] , longm ) ;
noerrors = noerrors & & RMod_LoadNodes ( & header - > lumps [ LUMP_NODES ] , longm ) ;
noerrors = noerrors & & RMod_LoadClipnodes ( & header - > lumps [ LUMP_CLIPNODES ] , longm ) ;
2006-03-12 22:01:49 +00:00
if ( noerrors )
{
2009-11-04 21:16:50 +00:00
RMod_LoadEntities ( & header - > lumps [ LUMP_ENTITIES ] ) ;
RMod_MakeHull0 ( ) ;
2006-03-12 22:01:49 +00:00
}
2004-08-22 22:29:09 +00:00
2010-07-11 02:22:39 +00:00
if ( ! isDedicated & & noerrors )
Mod_SortShaders ( ) ;
2004-08-22 22:29:09 +00:00
if ( crouchhullfile )
{
2009-05-24 10:11:17 +00:00
FS_FreeFile ( crouchhullfile ) ;
2004-08-22 22:29:09 +00:00
crouchhullfile = NULL ;
}
2006-03-12 22:01:49 +00:00
if ( ! noerrors )
{
Hunk_FreeToLowMark ( start ) ;
return false ;
}
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
2009-11-15 03:20:17 +00:00
/*FIXME: move mesh_t and lightmap allocation out of r_surf
for ( i = 0 ; i < mod - > numsurfaces ; i + + )
{
Surf_BuildSurfaceDisplayList ( mod , mod - > surfaces + i ) ;
}
*/
2004-08-22 22:29:09 +00:00
//
// 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 ;
2010-07-12 22:46:37 +00:00
Q1BSP_CheckHullNodes ( & mod - > hulls [ 0 ] ) ;
2004-08-22 22:29:09 +00:00
for ( j = 1 ; j < MAX_MAP_HULLSM ; j + + )
{
mod - > hulls [ j ] . firstclipnode = bm - > headnode [ j ] ;
mod - > hulls [ j ] . lastclipnode = mod - > numclipnodes - 1 ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
mod - > hulls [ j ] . available & = bm - > hullavailable [ j ] ;
2004-08-22 22:29:09 +00:00
if ( mod - > hulls [ j ] . firstclipnode > mod - > hulls [ j ] . lastclipnode )
mod - > hulls [ j ] . available = false ;
2010-07-12 22:46:37 +00:00
if ( mod - > hulls [ j ] . available )
Q1BSP_CheckHullNodes ( & mod - > hulls [ j ] ) ;
2004-08-22 22:29:09 +00:00
}
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 ;
}
}
# 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 )
2009-11-04 21:16:50 +00:00
RMod_FixupMinsMaxs ( ) ;
2007-05-25 22:16:29 +00:00
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 ] ; \
}
2009-11-04 21:16:50 +00:00
void RMod_FloodFillSkin ( qbyte * skin , int skinwidth , int skinheight )
2004-08-22 22:29:09 +00:00
{
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 )
2011-10-27 16:16:29 +00:00
if ( d_8to24rgbtable [ i ] = = ( 255 < < 0 ) ) // rgb 0.0, alpha 1.0
2004-08-22 22:29:09 +00:00
{
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void * RMod_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 ] ;
2009-11-04 21:16:50 +00:00
texid_t texnum ;
2004-08-22 22:29:09 +00:00
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 ;
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 ] ;
2009-11-04 21:16:50 +00:00
texnum = r_nulltex ;
2005-09-22 12:59:34 +00:00
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( texnum ) )
2005-09-22 12:59:34 +00:00
{ //the dp way
2009-11-04 21:16:50 +00:00
Q_strncpyz ( name , loadmodel - > name , sizeof ( name ) ) ;
2010-03-14 14:35:56 +00:00
Q_strncatz ( name , va ( " _%i.tga " , framenum ) , sizeof ( name ) ) ;
2009-11-04 21:16:50 +00:00
texnum = R_LoadReplacementTexture ( name , " sprites " , 0 ) ;
2005-09-22 12:59:34 +00:00
}
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( texnum ) )
2005-09-22 12:59:34 +00:00
{ //the older fte way.
2006-03-11 03:12:10 +00:00
COM_StripExtension ( loadmodel - > name , name , sizeof ( name ) ) ;
2010-03-14 14:35:56 +00:00
Q_strncatz ( name , va ( " _%i.tga " , framenum ) , sizeof ( name ) ) ;
2009-11-04 21:16:50 +00:00
texnum = R_LoadReplacementTexture ( name , " sprites " , 0 ) ;
2005-09-22 12:59:34 +00:00
}
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( texnum ) )
2005-09-22 12:59:34 +00:00
{ //the fuhquake way
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , name , sizeof ( name ) ) ;
2010-03-14 14:35:56 +00:00
Q_strncatz ( name , va ( " _%i.tga " , framenum ) , sizeof ( name ) ) ;
2009-11-04 21:16:50 +00:00
texnum = R_LoadReplacementTexture ( name , " sprites " , 0 ) ;
2005-09-22 12:59:34 +00:00
}
2005-05-13 10:42:48 +00:00
2004-08-22 22:29:09 +00:00
if ( version = = SPRITE32_VERSION )
{
size * = 4 ;
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( texnum ) )
2010-08-28 17:14:38 +00:00
texnum = R_LoadTexture32 ( name , width , height , ( unsigned * ) ( pinframe + 1 ) , IF_NOGAMMA | IF_CLAMP ) ;
2005-05-13 10:42:48 +00:00
}
else if ( version = = SPRITEHL_VERSION )
{
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( texnum ) )
2010-08-28 17:14:38 +00:00
texnum = R_LoadTexture8Pal32 ( name , width , height , ( qbyte * ) ( pinframe + 1 ) , ( qbyte * ) palette , IF_NOGAMMA | IF_CLAMP ) ;
2005-05-13 10:42:48 +00:00
}
else
{
2009-11-04 21:16:50 +00:00
if ( ! TEXVALID ( texnum ) )
2010-08-28 17:14:38 +00:00
texnum = R_LoadTexture8 ( name , width , height , ( qbyte * ) ( pinframe + 1 ) , IF_NOMIPMAP | IF_NOGAMMA | IF_CLAMP , 1 ) ;
2009-11-04 21:16:50 +00:00
}
Q_strncpyz ( name , loadmodel - > name , sizeof ( name ) ) ;
2010-03-14 14:35:56 +00:00
Q_strncatz ( name , va ( " _%i.tga " , framenum ) , sizeof ( name ) ) ;
2009-11-04 21:16:50 +00:00
pspriteframe - > shader = R_RegisterShader ( name ,
" { \n "
" { \n "
2011-10-27 16:16:29 +00:00
" map $diffuse \n "
" alphafunc ge128 \n "
" depthwrite \n "
" rgbgen vertex \n "
" alphagen vertex \n "
2009-11-04 21:16:50 +00:00
" } \n "
" } \n "
) ;
pspriteframe - > shader - > defaulttextures . base = texnum ;
pspriteframe - > shader - > width = width ;
pspriteframe - > shader - > height = height ;
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
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void * RMod_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 + + )
{
2009-11-04 21:16:50 +00:00
ptemp = RMod_LoadSpriteFrame ( ptemp , & pspritegroup - > frames [ i ] , framenum * 100 + i , version , palette ) ;
2004-08-22 22:29:09 +00:00
}
return ptemp ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteModel
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
qboolean RMod_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 ;
2010-11-07 02:18:37 +00:00
if ( qrenderer = = QR_NONE )
{
mod - > type = mod_dummy ;
return true ;
}
2005-05-13 10:42:48 +00:00
2009-02-22 13:46:48 +00:00
if ( version = = SPRITEHL_VERSION )
2005-05-13 10:42:48 +00:00
{
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 * )
2009-11-04 21:16:50 +00:00
RMod_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 * )
2009-11-04 21:16:50 +00:00
RMod_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
}
2009-11-04 21:16:50 +00:00
qboolean RMod_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 ;
2009-11-04 21:16:50 +00:00
int w , h ;
2004-08-22 22:29:09 +00:00
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 ) ;
2009-11-04 21:16:50 +00:00
frame - > shader = R_RegisterPic ( pframetype - > name ) ;
2007-05-25 22:16:29 +00:00
2009-11-04 21:16:50 +00:00
w = LittleLong ( pframetype - > width ) ;
h = LittleLong ( pframetype - > height ) ;
2004-08-22 22:29:09 +00:00
origin [ 0 ] = LittleLong ( pframetype - > origin_x ) ;
origin [ 1 ] = LittleLong ( pframetype - > origin_y ) ;
2011-04-23 20:37:20 +00:00
frame - > down = - origin [ 1 ] ;
frame - > up = h - origin [ 1 ] ;
2004-08-22 22:29:09 +00:00
frame - > left = - origin [ 0 ] ;
2009-11-04 21:16:50 +00:00
frame - > right = w - 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 ;
2010-07-25 15:12:12 +00:00
static int FindDoomSprites ( const char * name , int size , void * param )
2004-08-22 22:29:09 +00:00
{
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 - > 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 + + ;
}
}
2010-07-25 15:12:12 +00:00
pframe - > shader = R_RegisterShader ( imagename ,
" { \n { \n map $diffuse \n blendfunc blend \n } \n } \n " ) ;
pframe - > shader - > defaulttextures . base = R_LoadTexture8Pal24 ( imagename , header - > width , header - > height , image , palette , IF_CLAMP ) ;
R_BuildDefaultTexnums ( & pframe - > shader - > defaulttextures , pframe - > shader ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Doom Sprites
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_LoadDoomSprite ( model_t * mod )
2004-08-22 22:29:09 +00:00
{
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
= = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void RMod_Print ( void )
2004-08-22 22:29:09 +00:00
{
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