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
2014-05-10 13:42:13 +00:00
# if 1 //ndef SERVERONLY //FIXME
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 ;
2014-04-02 00:58:02 +00:00
extern cvar_t gl_lightmap_average ;
2014-10-05 20:04:11 +00:00
cvar_t mod_loadentfiles = CVAR ( " sv_loadentfiles " , " 1 " ) ;
2014-09-08 23:47:19 +00:00
cvar_t mod_external_vis = CVARD ( " mod_external_vis " , " 1 " , " Attempt to load .vis patches for quake maps, allowing transparent water to work properly. " ) ;
2014-10-05 20:04:11 +00:00
cvar_t mod_warnmodels = CVARD ( " mod_warnmodels " , " 1 " , " Warn if any models failed to load. Set to 0 if your mod is likely to lack optional models (like its in development). " ) ; //set to 0 for hexen2 and its otherwise-spammy-as-heck demo.
cvar_t mod_litsprites = CVARD ( " mod_litsprites " , " 0 " , " If set to 1, sprites will be lit according to world lighting (including rtlights), like Tenebrae. Use EF_ADDITIVE or EF_FULLBRIGHT to make emissive sprites instead. " ) ;
2014-05-10 13:42:13 +00:00
# ifdef SERVERONLY
cvar_t gl_overbright , gl_specular , gl_load24bit , r_replacemodels , gl_miptexLevel , r_fb_bmodels ; //all of these can/should default to 0
cvar_t r_noframegrouplerp = CVARF ( " r_noframegrouplerp " , " 0 " , CVAR_ARCHIVE ) ;
cvar_t dpcompat_psa_ungroup = CVAR ( " dpcompat_psa_ungroup " , " 0 " ) ;
texture_t r_notexture_mip_real ;
texture_t * r_notexture_mip = & r_notexture_mip_real ;
# endif
2004-08-22 22:29:09 +00:00
qboolean isnotmap = true ; //used to not warp ammo models.
void CM_Init ( void ) ;
2014-03-30 08:55:06 +00:00
void CM_Shutdown ( void ) ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
void Mod_LoadSpriteShaders ( model_t * spr ) ;
2014-03-30 08:55:06 +00:00
qboolean QDECL Mod_LoadSpriteModel ( model_t * mod , void * buffer , size_t fsize ) ;
qboolean QDECL Mod_LoadSprite2Model ( model_t * mod , void * buffer , size_t fsize ) ;
qboolean QDECL Mod_LoadBrushModel ( model_t * mod , void * buffer , size_t fsize ) ;
2004-08-22 22:29:09 +00:00
# ifdef Q2BSPS
2014-03-30 08:55:06 +00:00
qboolean QDECL Mod_LoadQ2BrushModel ( model_t * mod , void * buffer , size_t fsize ) ;
2012-09-30 05:52:03 +00:00
# endif
2014-03-30 08:55:06 +00:00
model_t * Mod_LoadModel ( model_t * mod , enum mlverbosity_e verbose ) ;
2014-10-05 20:04:11 +00:00
static void Mod_PrintFormats_f ( void ) ;
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
2014-05-10 13:42:13 +00:00
# ifdef DSPMODELS
2013-07-14 12:22:51 +00:00
void Mod_LoadDoomSprite ( model_t * mod ) ;
2004-08-22 22:29:09 +00:00
# endif
2013-10-29 17:38:22 +00:00
# define MAX_MOD_KNOWN 8192
2014-08-25 07:35:41 +00:00
model_t * mod_known ;
2004-08-22 22:29:09 +00:00
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 ;
2014-10-05 20:04:11 +00:00
void Mod_SortShaders ( model_t * mod ) ;
void Mod_LoadAliasShaders ( model_t * mod ) ;
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
2013-06-24 09:04:00 +00:00
long relitsurface ;
2013-07-14 12:22:51 +00:00
void Mod_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
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
static void Mod_MemList_f ( void )
2013-07-14 12:22:51 +00:00
{
int m ;
model_t * mod ;
int total = 0 ;
for ( m = 0 , mod = mod_known ; m < mod_numknown ; m + + , mod + + )
{
if ( mod - > memgroup . bytes )
Con_Printf ( " %s: %i bytes \n " , mod - > name , mod - > memgroup . bytes ) ;
total + = mod - > memgroup . bytes ;
}
Con_Printf ( " Total: %i bytes \n " , total ) ;
}
2014-05-10 13:42:13 +00:00
static void Mod_BatchList_f ( void )
2012-07-05 19:42:36 +00:00
{
int m , i ;
model_t * mod ;
batch_t * batch ;
unsigned int count ;
for ( m = 0 , mod = mod_known ; m < mod_numknown ; m + + , mod + + )
{
2014-10-05 20:04:11 +00:00
if ( mod - > type = = mod_brush & & mod - > loadstate = = MLS_LOADED )
2012-07-05 19:42:36 +00:00
{
Con_Printf ( " %s: \n " , mod - > name ) ;
count = 0 ;
for ( i = 0 ; i < SHADER_SORT_COUNT ; i + + )
{
for ( batch = mod - > batches [ i ] ; batch ; batch = batch - > next )
{
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2012-07-05 19:42:36 +00:00
if ( batch - > lightmap [ 3 ] > = 0 )
2013-08-27 13:18:09 +00:00
Con_Printf ( " %s lm=(%i:%i %i:%i %i:%i %i:%i) surfs=%u \n " , batch - > texture - > shader - > name , batch - > lightmap [ 0 ] , batch - > lmlightstyle [ 0 ] , batch - > lightmap [ 1 ] , batch - > lmlightstyle [ 1 ] , batch - > lightmap [ 2 ] , batch - > lmlightstyle [ 2 ] , batch - > lightmap [ 3 ] , batch - > lmlightstyle [ 3 ] , batch - > maxmeshes ) ;
2012-07-05 19:42:36 +00:00
else if ( batch - > lightmap [ 2 ] > = 0 )
2013-08-27 13:18:09 +00:00
Con_Printf ( " %s lm=(%i:%i %i:%i %i:%i) surfs=%u \n " , batch - > texture - > shader - > name , batch - > lightmap [ 0 ] , batch - > lmlightstyle [ 0 ] , batch - > lightmap [ 1 ] , batch - > lmlightstyle [ 1 ] , batch - > lightmap [ 2 ] , batch - > lmlightstyle [ 2 ] , batch - > maxmeshes ) ;
2012-07-05 19:42:36 +00:00
else if ( batch - > lightmap [ 1 ] > = 0 )
2013-08-27 13:18:09 +00:00
Con_Printf ( " %s lm=(%i:%i %i:%i) surfs=%u \n " , batch - > texture - > shader - > name , batch - > lightmap [ 0 ] , batch - > lmlightstyle [ 0 ] , batch - > lightmap [ 1 ] , batch - > lmlightstyle [ 1 ] , batch - > maxmeshes ) ;
2013-10-08 14:28:11 +00:00
else
# endif
if ( batch - > lmlightstyle [ 0 ] ! = 255 )
2013-08-27 13:18:09 +00:00
Con_Printf ( " %s lm=(%i:%i) surfs=%u \n " , batch - > texture - > shader - > name , batch - > lightmap [ 0 ] , batch - > lmlightstyle [ 0 ] , batch - > maxmeshes ) ;
2012-07-05 19:42:36 +00:00
else
Con_Printf ( " %s lm=%i surfs=%u \n " , batch - > texture - > shader - > name , batch - > lightmap [ 0 ] , batch - > maxmeshes ) ;
count + + ;
}
}
Con_Printf ( " %u \n " , count ) ;
}
}
}
2014-05-10 13:42:13 +00:00
static void Mod_TextureList_f ( void )
2004-08-22 22:29:09 +00:00
{
int m , i ;
texture_t * tx ;
model_t * mod ;
2012-07-05 19:42:36 +00:00
qboolean shownmodelname = false ;
int count = 0 ;
2004-08-22 22:29:09 +00:00
for ( m = 0 , mod = mod_known ; m < mod_numknown ; m + + , mod + + )
{
2012-07-05 19:42:36 +00:00
if ( shownmodelname )
Con_Printf ( " %u \n " , count ) ;
shownmodelname = false ;
2014-10-05 20:04:11 +00:00
if ( mod - > type = = mod_brush & & mod - > loadstate = = MLS_LOADED )
2004-08-22 22:29:09 +00:00
{
if ( * mod - > name = = ' * ' )
continue ; // inlines don't count
2012-07-05 19:42:36 +00:00
if ( shownmodelname )
Con_Printf ( " %u \n " , count ) ;
count = 0 ;
2004-08-22 22:29:09 +00:00
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 ) ;
2012-07-05 19:42:36 +00:00
count = 0 ;
2004-08-22 22:29:09 +00:00
}
Con_Printf ( " %s \n " , tx - > name ) ;
2012-07-05 19:42:36 +00:00
count + + ;
2004-08-22 22:29:09 +00:00
}
}
}
2012-07-05 19:42:36 +00:00
if ( shownmodelname )
Con_Printf ( " %u \n " , count ) ;
2004-08-22 22:29:09 +00:00
}
2014-05-10 13:42:13 +00:00
static void Mod_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 ] ) ;
2013-08-21 07:14:39 +00:00
s = R_RegisterCustom ( Cmd_Argv ( 2 ) , SUF_LIGHTMAP , NULL , NULL ) ;
2009-11-04 21:16:50 +00:00
if ( ! s )
{
2013-08-21 07:14:39 +00:00
s = R_RegisterCustom ( texname , SUF_LIGHTMAP , Shader_DefaultBSPQ1 , NULL ) ;
2009-11-04 21:16:50 +00:00
2014-10-05 20:04:11 +00:00
for ( i = 0 ; i < sizeof ( colour ) / sizeof ( colour [ 0 ] ) ; i + + )
colour [ i ] = rgba ;
// s->defaulttextures.base = GL_LoadTexture32(texname, 8, 8, colour, IF_NOMIPMAP);
}
2004-08-22 22:29:09 +00:00
for ( m = 0 , mod = mod_known ; m < mod_numknown ; m + + , mod + + )
{
2014-10-05 20:04:11 +00:00
if ( mod - > type = = mod_brush & & mod - > loadstate = = MLS_LOADED )
2004-08-22 22:29:09 +00:00
{
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
}
}
}
}
}
2014-05-10 13:42:13 +00:00
# endif
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 ) ;
2014-03-30 08:55:06 +00:00
# elif defined(__GNUC__)
surf = __sync_add_and_fetch ( & relitsurface , 1 ) ;
2010-11-22 02:03:28 +00:00
# else
2014-03-30 08:55:06 +00:00
surf = relitsurface + + ;
2010-11-22 02:03:28 +00:00
# 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
2013-07-14 12:22:51 +00:00
void Mod_Think ( void )
2009-11-04 21:16:50 +00:00
{
# ifdef RUNTIMELIGHTING
if ( lightmodel )
{
# 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 ;
2014-03-30 08:55:06 +00:00
# if defined(_WIN32) && !defined(WINRT)
2010-11-22 02:03:28 +00:00
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 - - ;
2014-03-30 08:55:06 +00:00
# elif defined(__GNUC__)
relightthreads = 2 ; //erm, lets hope...
2010-11-22 02:03:28 +00:00
# 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 + + )
2012-11-29 13:37:48 +00:00
relightthread [ i ] = Sys_CreateThread ( " relight " , RelightThread , lightmodel , THREADP_NORMAL , 0 ) ;
2009-11-04 21:16:50 +00:00
}
2012-04-24 07:59:11 +00:00
if ( relitsurface < lightmodel - > numsurfaces )
{
return ;
}
2009-11-04 21:16:50 +00:00
# else
LightFace ( relitsurface ) ;
2013-07-14 12:22:51 +00:00
Mod_UpdateLightmap ( relitsurface ) ;
2009-11-04 21:16:50 +00:00
relitsurface + + ;
# endif
if ( relitsurface > = lightmodel - > numsurfaces )
{
2012-02-27 12:23:15 +00:00
vfsfile_t * f ;
2009-11-04 21:16:50 +00:00
char filename [ MAX_QPATH ] ;
Con_Printf ( " Finished lighting %s \n " , lightmodel - > name ) ;
# ifdef MULTITHREAD
2012-04-24 07:59:11 +00:00
if ( relightthreads )
2009-11-04 21:16:50 +00:00
{
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 ) ) ;
2012-11-27 03:23:19 +00:00
f = FS_OpenVFS ( filename , " wb " , FS_GAME ) ;
2012-02-27 12:23:15 +00:00
if ( f )
{
VFS_WRITE ( f , " QLIT \1 \0 \0 \0 " , 8 ) ;
VFS_WRITE ( f , lightmodel - > deluxdata , numlightdata * 3 ) ;
VFS_CLOSE ( f ) ;
}
else
Con_Printf ( " Unable to write \" %s \" \n " , filename ) ;
2009-11-04 21:16:50 +00:00
}
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 ) ) ;
2012-11-27 03:23:19 +00:00
f = FS_OpenVFS ( filename , " wb " , FS_GAME ) ;
2012-02-27 12:23:15 +00:00
if ( f )
{
VFS_WRITE ( f , " QLIT \1 \0 \0 \0 " , 8 ) ;
VFS_WRITE ( f , lightmodel - > lightdata , numlightdata * 3 ) ;
VFS_CLOSE ( f ) ;
}
else
Con_Printf ( " Unable to write \" %s \" \n " , filename ) ;
2009-11-04 21:16:50 +00:00
}
2012-04-24 07:59:11 +00:00
lightmodel = NULL ;
2009-11-04 21:16:50 +00:00
}
}
# 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 + + )
{
2014-10-05 20:04:11 +00:00
if ( mod - > loadstate ! = MLS_LOADED )
2011-05-27 17:59:31 +00:00
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
2013-07-14 12:22:51 +00:00
void Mod_ResortShaders ( void )
2013-03-12 23:10:44 +00:00
{
//called when some shader changed its sort key.
//this means we have to hunt down all models and update their batches.
//really its only bsps that need this.
batch_t * oldlists [ SHADER_SORT_COUNT ] , * b ;
int i , j , bs ;
model_t * mod ;
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
{
2014-10-05 20:04:11 +00:00
if ( mod - > loadstate ! = MLS_LOADED )
2013-03-12 23:10:44 +00:00
continue ;
memcpy ( oldlists , mod - > batches , sizeof ( oldlists ) ) ;
memset ( mod - > batches , 0 , sizeof ( oldlists ) ) ;
for ( j = 0 ; j < SHADER_SORT_COUNT ; j + + )
{
while ( ( b = oldlists [ j ] ) )
{
oldlists [ j ] = b - > next ;
bs = b - > shader ? b - > shader - > sort : j ;
b - > next = mod - > batches [ bs ] ;
mod - > batches [ bs ] = b ;
}
}
}
}
2009-11-04 21:16:50 +00:00
/*
= = = = = = = = = = = = = = = = = = =
Mod_ClearAll
= = = = = = = = = = = = = = = = = = =
2013-07-14 12:22:51 +00:00
called before new content is loaded .
2009-11-04 21:16:50 +00:00
*/
2013-07-14 12:22:51 +00:00
static int mod_datasequence ;
void Mod_ClearAll ( void )
2009-11-04 21:16:50 +00:00
{
# ifdef RUNTIMELIGHTING
# ifdef MULTITHREAD
2013-07-14 12:22:51 +00:00
int i ;
2013-05-07 19:39:04 +00:00
wantrelight = false ;
for ( i = 0 ; i < relightthreads ; i + + )
2009-11-04 21:16:50 +00:00
{
2013-05-07 19:39:04 +00:00
Sys_WaitOnThread ( relightthread [ i ] ) ;
relightthread [ i ] = NULL ;
2009-11-04 21:16:50 +00:00
}
2013-05-07 19:39:04 +00:00
relightthreads = 0 ;
2009-11-04 21:16:50 +00:00
# endif
lightmodel = NULL ;
# endif
2013-07-14 12:22:51 +00:00
mod_datasequence + + ;
}
2013-10-29 17:38:22 +00:00
//can be called in one of two ways.
//force=true: explicit flush. everything goes, even if its still in use.
//force=false: map change. lots of stuff is no longer in use and can be freely flushed.
//certain models cannot be safely flushed while still in use. such models will not be flushed even if forced (they may still be partially flushed).
void Mod_Purge ( enum mod_purge_e ptype )
2013-07-14 12:22:51 +00:00
{
int i ;
model_t * mod ;
2013-10-29 17:38:22 +00:00
qboolean unused ;
2013-07-14 12:22:51 +00:00
2009-11-04 21:16:50 +00:00
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
{
2013-10-29 17:38:22 +00:00
unused = mod - > datasequence ! = mod_datasequence ;
2013-07-14 12:22:51 +00:00
//this model isn't active any more.
2013-10-29 17:38:22 +00:00
if ( unused | | ptype ! = MP_MAPCHANGED )
2009-11-04 21:16:50 +00:00
{
2014-10-05 20:04:11 +00:00
if ( mod - > loadstate = = MLS_LOADING )
COM_WorkerPartialSync ( mod , & mod - > loadstate , MLS_LOADING ) ;
2013-10-29 17:38:22 +00:00
if ( unused )
Con_DPrintf ( " model \" %s \" no longer needed \n " , mod - > name ) ;
# ifdef TERRAIN
//we can safely flush all terrain sections at any time
if ( mod - > terrain & & ptype ! = MP_MAPCHANGED )
Terr_PurgeTerrainModel ( mod , false , true ) ;
# endif
2013-07-14 12:22:51 +00:00
//purge any vbos
if ( mod - > type = = mod_brush )
{
2013-10-29 17:38:22 +00:00
//brush models cannot be safely flushed.
if ( ! unused & & ptype ! = MP_RESET )
continue ;
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2013-07-14 12:22:51 +00:00
Surf_Clear ( mod ) ;
2014-05-10 13:42:13 +00:00
# endif
2013-07-14 12:22:51 +00:00
}
2012-04-09 19:12:12 +00:00
# ifdef TERRAIN
2013-10-29 17:38:22 +00:00
if ( mod - > type = = mod_brush | | mod - > type = = mod_heightmap )
2013-07-14 12:22:51 +00:00
{
2013-10-29 17:38:22 +00:00
//heightmap/terrain models cannot be safely flushed (brush models might have terrain embedded).
if ( ! unused & & ptype ! = MP_RESET )
continue ;
Terr_FreeModel ( mod ) ;
2013-07-14 12:22:51 +00:00
}
2012-04-09 19:12:12 +00:00
# endif
2014-10-05 20:04:11 +00:00
if ( mod - > type = = mod_alias )
{
Mod_DestroyMesh ( mod - > meshinfo ) ;
mod - > meshinfo = NULL ;
}
2009-11-04 21:16:50 +00:00
2013-07-14 12:22:51 +00:00
//and obliterate anything else remaining in memory.
ZG_FreeGroup ( & mod - > memgroup ) ;
mod - > meshinfo = NULL ;
2014-10-05 20:04:11 +00:00
mod - > loadstate = MLS_NOTLOADED ;
2013-07-14 12:22:51 +00:00
}
2009-11-04 21:16:50 +00:00
}
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = =
Mod_Init
= = = = = = = = = = = = = = =
*/
2013-10-29 17:38:22 +00:00
void Mod_Init ( qboolean initial )
2004-08-22 22:29:09 +00:00
{
2014-08-25 07:35:41 +00:00
mod_known = malloc ( MAX_MOD_KNOWN * sizeof ( * mod_known ) ) ;
2013-10-29 17:38:22 +00:00
if ( ! initial )
{
Mod_ClearAll ( ) ; //shouldn't be needed
Mod_Purge ( MP_RESET ) ; //shouldn't be needed
mod_numknown = 0 ;
Q1BSP_Init ( ) ;
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2013-10-29 17:38:22 +00:00
Cmd_AddCommand ( " mod_memlist " , Mod_MemList_f ) ;
Cmd_AddCommand ( " mod_batchlist " , Mod_BatchList_f ) ;
Cmd_AddCommand ( " mod_texturelist " , Mod_TextureList_f ) ;
Cmd_AddCommand ( " mod_usetexture " , Mod_BlockTextureColour_f ) ;
2014-05-10 13:42:13 +00:00
# endif
2013-10-29 17:38:22 +00:00
}
2014-09-08 23:47:19 +00:00
else
2014-10-05 20:04:11 +00:00
{
2014-09-08 23:47:19 +00:00
Cvar_Register ( & mod_external_vis , " Graphical Nicaties " ) ;
2014-10-05 20:04:11 +00:00
Cvar_Register ( & mod_warnmodels , " Graphical Nicaties " ) ;
Cvar_Register ( & mod_litsprites , " Graphical Nicaties " ) ;
Cvar_Register ( & mod_loadentfiles , NULL ) ;
Cmd_AddCommand ( " version_modelformats " , Mod_PrintFormats_f ) ;
}
2013-10-29 17:38:22 +00:00
if ( initial )
{
Alias_Register ( ) ;
2014-05-10 13:42:13 +00:00
# ifdef SPRMODELS
2013-10-29 17:38:22 +00:00
Mod_RegisterModelFormatMagic ( NULL , " Quake1 Sprite (spr) " , IDSPRITEHEADER , Mod_LoadSpriteModel ) ;
2014-05-10 13:42:13 +00:00
# endif
2013-10-29 17:38:22 +00:00
# ifdef SP2MODELS
Mod_RegisterModelFormatMagic ( NULL , " Quake2 Sprite (sp2) " , IDSPRITE2HEADER , Mod_LoadSprite2Model ) ;
# endif
//q2/q3bsps
# ifdef Q2BSPS
Mod_RegisterModelFormatMagic ( NULL , " Quake2/Quake2 Map (bsp) " , IDBSPHEADER , Mod_LoadQ2BrushModel ) ;
# endif
# ifdef Q3BSPS
Mod_RegisterModelFormatMagic ( NULL , " Raven Map (bsp) " , ( ' R ' < < 0 ) + ( ' B ' < < 8 ) + ( ' S ' < < 16 ) + ( ' P ' < < 24 ) , Mod_LoadQ2BrushModel ) ;
Mod_RegisterModelFormatMagic ( NULL , " QFusion Map (bsp) " , ( ' F ' < < 0 ) + ( ' B ' < < 8 ) + ( ' S ' < < 16 ) + ( ' P ' < < 24 ) , Mod_LoadQ2BrushModel ) ;
# endif
//doom maps
# ifdef MAP_DOOM
Mod_RegisterModelFormatMagic ( NULL , " Doom IWad Map " , ( ( ' D ' < < 24 ) + ( ' A ' < < 16 ) + ( ' W ' < < 8 ) + ' I ' ) , Mod_LoadDoomLevel ) ;
Mod_RegisterModelFormatMagic ( NULL , " Doom PWad Map " , ( ( ' D ' < < 24 ) + ( ' A ' < < 16 ) + ( ' W ' < < 8 ) + ' P ' ) , Mod_LoadDoomLevel ) ;
# endif
2013-12-07 00:30:48 +00:00
# ifdef MAP_PROC
Mod_RegisterModelFormatText ( NULL , " Doom3 (cm) " , " CM " , D3_LoadMap_CollisionMap ) ;
# endif
2013-10-29 17:38:22 +00:00
//q1-based formats
Mod_RegisterModelFormatMagic ( NULL , " Quake1 2PSB Map(bsp) " , BSPVERSION_LONG1 , Mod_LoadBrushModel ) ;
Mod_RegisterModelFormatMagic ( NULL , " Quake1 BSP2 Map(bsp) " , BSPVERSION_LONG2 , Mod_LoadBrushModel ) ;
Mod_RegisterModelFormatMagic ( NULL , " Half-Life Map (bsp) " , 30 , Mod_LoadBrushModel ) ;
Mod_RegisterModelFormatMagic ( NULL , " Quake1 Map (bsp) " , 29 , Mod_LoadBrushModel ) ;
Mod_RegisterModelFormatMagic ( NULL , " Quake1 Prerelease Map (bsp) " , 28 , Mod_LoadBrushModel ) ;
}
2004-08-22 22:29:09 +00:00
}
2013-10-29 17:38:22 +00:00
void Mod_Shutdown ( qboolean final )
2004-08-22 22:29:09 +00:00
{
2013-10-29 17:38:22 +00:00
if ( final )
{
Mod_UnRegisterAllModelFormats ( NULL ) ;
2014-03-30 08:55:06 +00:00
# ifdef Q2BSPS
CM_Shutdown ( ) ;
# endif
2013-10-29 17:38:22 +00:00
}
else
{
Mod_ClearAll ( ) ;
Mod_Purge ( MP_RESET ) ;
2004-08-22 22:29:09 +00:00
2013-10-29 17:38:22 +00:00
Cmd_RemoveCommand ( " mod_memlist " ) ;
Cmd_RemoveCommand ( " mod_batchlist " ) ;
Cmd_RemoveCommand ( " mod_texturelist " ) ;
Cmd_RemoveCommand ( " mod_usetexture " ) ;
}
2014-08-25 07:35:41 +00:00
free ( mod_known ) ;
mod_known = NULL ;
mod_numknown = 0 ;
2014-08-29 04:50:49 +00:00
# ifndef SERVERONLY
2014-08-25 07:35:41 +00:00
r_worldentity . model = NULL ; //just in case.
2014-08-29 04:50:49 +00:00
# endif
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = =
Mod_Init
Caches the data if needed
= = = = = = = = = = = = = = =
*/
2013-07-14 12:22:51 +00:00
void * Mod_Extradata ( model_t * mod )
2004-08-22 22:29:09 +00:00
{
void * r ;
2013-07-14 12:22:51 +00:00
r = mod - > meshinfo ;
2004-08-22 22:29:09 +00:00
if ( r )
return r ;
2014-03-30 08:55:06 +00:00
Mod_LoadModel ( mod , MLV_ERROR ) ;
2004-08-22 22:29:09 +00:00
2013-07-14 12:22:51 +00:00
if ( ! mod - > meshinfo )
2004-08-22 22:29:09 +00:00
Sys_Error ( " Mod_Extradata: caching failed " ) ;
2013-07-14 12:22:51 +00:00
return mod - > meshinfo ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = =
Mod_PointInLeaf
= = = = = = = = = = = = = = =
*/
2013-07-14 12:22:51 +00:00
mleaf_t * Mod_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
}
2014-10-05 20:04:11 +00:00
const char * Mod_FixName ( const char * modname , const char * worldname )
{
if ( * modname = = ' * ' & & worldname & & * worldname )
{
//make sure that the value is an inline value with no existing extra postfix or anything.
char * e ;
if ( strtoul ( modname + 1 , & e , 10 ) ! = 0 )
if ( ! * e )
return va ( " %s:%s " , modname , worldname ) ;
}
return modname ;
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = = =
Mod_FindName
= = = = = = = = = = = = = = = = = =
*/
2014-03-30 08:55:06 +00:00
model_t * Mod_FindName ( const 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 )
{
2014-10-05 20:04:11 +00:00
# ifdef LOADERTHREAD
Sys_LockMutex ( com_resourcemutex ) ;
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
if ( ! strcmp ( mod - > name , name ) )
break ;
if ( i = = mod_numknown )
{
# endif
if ( mod_numknown = = MAX_MOD_KNOWN )
Sys_Error ( " mod_numknown == MAX_MOD_KNOWN " ) ;
if ( strlen ( name ) > = sizeof ( mod - > name ) )
Sys_Error ( " model name is too long: %s " , name ) ;
memset ( mod , 0 , sizeof ( model_t ) ) ; //clear the old model as the renderers use the same globals
Q_strncpyz ( mod - > name , name , sizeof ( mod - > name ) ) ;
mod - > loadstate = MLS_NOTLOADED ;
mod_numknown + + ;
mod - > particleeffect = - 1 ;
mod - > particletrail = - 1 ;
# ifdef LOADERTHREAD
}
Sys_UnlockMutex ( com_resourcemutex ) ;
# endif
2004-08-22 22:29:09 +00:00
}
2014-10-05 20:04:11 +00:00
if ( mod - > loadstate = = MLS_FAILED )
mod - > loadstate = MLS_NOTLOADED ;
2013-10-29 17:38:22 +00:00
2013-07-14 12:22:51 +00:00
//mark it as active, so it doesn't get flushed prematurely
mod - > datasequence = mod_datasequence ;
2004-08-22 22:29:09 +00:00
return mod ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_TouchModel
= = = = = = = = = = = = = = = = = =
*/
2014-03-30 08:55:06 +00:00
void Mod_TouchModel ( const char * name )
2004-08-22 22:29:09 +00:00
{
2014-10-05 20:04:11 +00:00
//findname does this anyway.
Mod_FindName ( name ) ;
2004-08-22 22:29:09 +00:00
}
2013-10-29 17:38:22 +00:00
static struct
{
void * module ;
char * formatname ;
char * ident ;
unsigned int magic ;
2014-03-30 08:55:06 +00:00
qboolean ( QDECL * load ) ( model_t * mod , void * buffer , size_t buffersize ) ;
2013-10-29 17:38:22 +00:00
} modelloaders [ 64 ] ;
2014-10-05 20:04:11 +00:00
static void Mod_PrintFormats_f ( void )
{
int i ;
for ( i = 0 ; i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) ; i + + )
{
if ( modelloaders [ i ] . load & & modelloaders [ i ] . formatname )
Con_Printf ( " %s \n " , modelloaders [ i ] . formatname ) ;
}
}
2014-05-16 01:34:58 +00:00
int Mod_RegisterModelFormatText ( void * module , const char * formatname , char * magictext , qboolean ( QDECL * load ) ( model_t * mod , void * buffer , size_t fsize ) )
2013-10-29 17:38:22 +00:00
{
int i , free = - 1 ;
for ( i = 0 ; i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) ; i + + )
{
if ( modelloaders [ i ] . ident & & ! strcmp ( modelloaders [ i ] . ident , magictext ) )
{
free = i ;
break ; //extension match always replaces
}
else if ( ! modelloaders [ i ] . load & & free < 0 )
free = i ;
}
if ( free < 0 )
return 0 ;
modelloaders [ free ] . module = module ;
modelloaders [ free ] . formatname = Z_StrDup ( formatname ) ;
modelloaders [ free ] . magic = 0 ;
modelloaders [ free ] . ident = Z_StrDup ( magictext ) ;
modelloaders [ free ] . load = load ;
return free + 1 ;
}
2014-05-16 01:34:58 +00:00
int Mod_RegisterModelFormatMagic ( void * module , const char * formatname , unsigned int magic , qboolean ( QDECL * load ) ( model_t * mod , void * buffer , size_t fsize ) )
2013-10-29 17:38:22 +00:00
{
int i , free = - 1 ;
for ( i = 0 ; i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) ; i + + )
{
if ( modelloaders [ i ] . magic & & modelloaders [ i ] . magic = = magic )
{
free = i ;
break ; //extension match always replaces
}
else if ( ! modelloaders [ i ] . load & & free < 0 )
free = i ;
}
if ( free < 0 )
return 0 ;
modelloaders [ free ] . module = module ;
if ( modelloaders [ free ] . formatname )
Z_Free ( modelloaders [ free ] . formatname ) ;
modelloaders [ free ] . formatname = Z_StrDup ( formatname ) ;
modelloaders [ free ] . magic = magic ;
modelloaders [ free ] . ident = NULL ;
modelloaders [ free ] . load = load ;
return free + 1 ;
}
2014-05-16 01:34:58 +00:00
void Mod_UnRegisterModelFormat ( void * module , int idx )
2013-10-29 17:38:22 +00:00
{
2014-10-05 20:04:11 +00:00
2013-10-29 17:38:22 +00:00
idx - - ;
if ( ( unsigned int ) ( idx ) > = sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) )
return ;
2014-05-16 01:34:58 +00:00
if ( modelloaders [ idx ] . module ! = module )
return ;
2013-10-29 17:38:22 +00:00
2014-10-05 20:04:11 +00:00
COM_WorkerFullSync ( ) ;
2013-10-29 17:38:22 +00:00
Z_Free ( modelloaders [ idx ] . ident ) ;
modelloaders [ idx ] . ident = NULL ;
Z_Free ( modelloaders [ idx ] . formatname ) ;
modelloaders [ idx ] . formatname = NULL ;
modelloaders [ idx ] . magic = 0 ;
modelloaders [ idx ] . load = NULL ;
modelloaders [ idx ] . module = NULL ;
//FS_Restart will be needed
}
2014-05-16 01:34:58 +00:00
void Mod_UnRegisterAllModelFormats ( void * module )
2013-10-29 17:38:22 +00:00
{
int i ;
2014-10-05 20:04:11 +00:00
COM_WorkerFullSync ( ) ;
2013-10-29 17:38:22 +00:00
for ( i = 0 ; i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) ; i + + )
{
if ( modelloaders [ i ] . module = = module )
2014-05-16 01:34:58 +00:00
Mod_UnRegisterModelFormat ( module , i + 1 ) ;
2013-10-29 17:38:22 +00:00
}
}
2014-10-05 20:04:11 +00:00
void Mod_ModelLoaded ( void * ctx , void * data , size_t a , size_t b )
{
model_t * mod = ctx ;
enum mlverbosity_e verbose = b ;
# ifndef SERVERONLY
P_LoadedModel ( mod ) ;
# endif
# ifdef TERRAIN
if ( mod - > terrain )
Terr_FinishTerrain ( mod ) ;
# endif
# ifndef SERVERONLY
if ( mod - > type = = mod_brush )
{
Surf_BuildModelLightmaps ( mod ) ;
}
if ( mod - > type = = mod_sprite )
{
Mod_LoadSpriteShaders ( mod ) ;
}
if ( mod - > type = = mod_alias )
{
if ( qrenderer ! = QR_NONE )
Mod_LoadAliasShaders ( mod ) ;
# ifdef RAGDOLL
{
int numbones = Mod_GetNumBones ( mod , false ) ;
if ( numbones )
{
size_t filesize ;
char * buf ;
char dollname [ MAX_QPATH ] ;
Q_snprintfz ( dollname , sizeof ( dollname ) , " %s.doll " , mod - > name ) ;
buf = COM_LoadFile ( dollname , 5 , & filesize ) ;
if ( buf )
{
mod - > dollinfo = rag_createdollfromstring ( mod , dollname , numbones , buf ) ;
BZ_Free ( buf ) ;
}
}
}
# endif
}
# endif
mod - > loadstate = a ;
switch ( verbose )
{
default :
case MLV_ERROR :
Host_EndGame ( " Mod_NumForName: %s not found or couldn't load " , mod - > name ) ;
break ;
case MLV_WARN :
if ( * mod - > name ! = ' * ' & & strcmp ( mod - > name , " null " ) & & mod_warnmodels . ival )
Con_Printf ( CON_ERROR " Unable to load %s \n " , mod - > name ) ;
break ;
case MLV_SILENT :
break ;
}
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = = =
Mod_LoadModel
Loads a model into the cache
= = = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
void Mod_LoadModelWorker ( void * ctx , void * data , size_t a , size_t b )
2004-08-22 22:29:09 +00:00
{
2014-10-05 20:04:11 +00:00
model_t * mod = ctx ;
enum mlverbosity_e verbose = a ;
2004-08-22 22:29:09 +00:00
unsigned * buf = NULL ;
2007-09-13 22:27:56 +00:00
char mdlbase [ MAX_QPATH ] ;
char * replstr ;
2014-10-05 20:04:11 +00:00
qboolean doomsprite = false ;
2013-10-29 17:38:22 +00:00
unsigned int magic , i ;
2014-10-05 20:04:11 +00:00
size_t filesize ;
char ext [ 8 ] ;
2004-08-22 22:29:09 +00:00
if ( ! * mod - > name )
{
2012-09-30 05:52:03 +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 - > engineflags = 0 ;
2014-10-05 20:04:11 +00:00
COM_AddWork ( 0 , Mod_ModelLoaded , mod , NULL , MLS_LOADED , 0 ) ;
return ;
2004-08-22 22:29:09 +00:00
}
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
# ifdef RAGDOLL
if ( mod - > dollinfo )
{
rag_freedoll ( mod - > dollinfo ) ;
mod - > dollinfo = NULL ;
}
# endif
2014-10-05 20:04:11 +00:00
if ( mod - > loadstate = = MLS_FAILED )
return ;
2013-10-29 17:38:22 +00:00
2004-08-22 22:29:09 +00:00
//
// 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
// get string used for replacement tokens
2014-10-05 20:04:11 +00:00
COM_FileExtension ( mod - > name , ext , sizeof ( ext ) ) ;
2007-09-13 22:27:56 +00:00
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
{
2014-10-05 20:04:11 +00:00
char token [ 256 ] ;
replstr = COM_ParseStringSet ( replstr , token , sizeof ( token ) ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
2008-11-09 22:29:28 +00:00
if ( replstr )
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
{
2014-10-05 20:04:11 +00:00
char altname [ MAX_QPATH ] ;
Q_snprintfz ( altname , sizeof ( altname ) , " %s.%s " , mdlbase , token ) ;
TRACE ( ( " Mod_LoadModel: Trying to load (replacement) model \" %s \" \n " , altname ) ) ;
buf = ( unsigned * ) COM_LoadFile ( altname , 5 , & filesize ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
}
2008-11-09 22:29:28 +00:00
else
2007-09-13 22:27:56 +00:00
{
2013-07-14 12:22:51 +00:00
TRACE ( ( " Mod_LoadModel: Trying to load model \" %s \" \n " , mod - > name ) ) ;
2014-10-05 20:04:11 +00:00
buf = ( unsigned * ) COM_LoadFile ( mod - > name , 5 , & filesize ) ;
2007-09-13 22:27:56 +00:00
if ( ! buf )
{
2014-05-10 13:42:13 +00:00
# ifdef DSPMODELS
2007-09-13 22:27:56 +00:00
if ( doomsprite ) // special case needed for doom sprites
{
2013-07-14 12:22:51 +00:00
TRACE ( ( " Mod_LoadModel: doomsprite: \" %s \" \n " , mod - > name ) ) ;
Mod_LoadDoomSprite ( mod ) ;
2014-10-05 20:04:11 +00:00
BZ_Free ( buf ) ;
COM_AddWork ( 0 , Mod_ModelLoaded , mod , NULL , MLS_LOADED , 0 ) ;
return ;
2007-09-13 22:27:56 +00:00
}
# 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
//
// fill it in
//
2014-10-05 20:04:11 +00:00
Mod_DoCRC ( mod , ( char * ) buf , filesize ) ;
2010-05-01 22:47:47 +00:00
2013-10-29 17:38:22 +00:00
magic = LittleLong ( * ( unsigned * ) buf ) ;
for ( i = 0 ; i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) ; i + + )
2007-09-13 22:27:56 +00:00
{
2013-10-29 17:38:22 +00:00
if ( modelloaders [ i ] . load & & modelloaders [ i ] . magic = = magic & & ! modelloaders [ i ] . ident )
break ;
}
if ( i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) )
{
2014-10-05 20:04:11 +00:00
if ( ! modelloaders [ i ] . load ( mod , buf , filesize ) )
{
BZ_Free ( buf ) ;
2007-09-13 22:27:56 +00:00
continue ;
2014-10-05 20:04:11 +00:00
}
2013-10-29 17:38:22 +00:00
}
else
{
2014-10-05 20:04:11 +00:00
COM_ParseOut ( ( char * ) buf , token , sizeof ( token ) ) ;
2013-10-29 17:38:22 +00:00
for ( i = 0 ; i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) ; i + + )
2007-09-13 22:27:56 +00:00
{
2014-10-05 20:04:11 +00:00
if ( modelloaders [ i ] . load & & modelloaders [ i ] . ident & & ! strcmp ( modelloaders [ i ] . ident , token ) )
2013-10-29 17:38:22 +00:00
break ;
2007-09-13 22:27:56 +00:00
}
2013-10-29 17:38:22 +00:00
if ( i < sizeof ( modelloaders ) / sizeof ( modelloaders [ 0 ] ) )
2007-09-13 22:27:56 +00:00
{
2014-10-05 20:04:11 +00:00
if ( ! modelloaders [ i ] . load ( mod , buf , filesize ) )
{
BZ_Free ( buf ) ;
2007-09-13 22:27:56 +00:00
continue ;
2014-10-05 20:04:11 +00:00
}
2007-09-13 22:27:56 +00:00
}
2013-10-29 17:38:22 +00:00
else
{
Con_Printf ( CON_WARNING " Unrecognised model format 0x%x (%c%c%c%c) \n " , LittleLong ( * ( unsigned * ) buf ) , ( ( char * ) buf ) [ 0 ] , ( ( char * ) buf ) [ 1 ] , ( ( char * ) buf ) [ 2 ] , ( ( char * ) buf ) [ 3 ] ) ;
2014-10-05 20:04:11 +00:00
BZ_Free ( buf ) ;
2013-10-29 17:38:22 +00:00
continue ;
}
}
/*
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
{
2013-07-14 12:22:51 +00:00
TRACE ( ( " Mod_LoadModel: doom3 CM \n " ) ) ;
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
2013-10-29 17:38:22 +00:00
*/
2007-09-13 22:27:56 +00:00
2013-07-14 12:22:51 +00:00
TRACE ( ( " Mod_LoadModel: Loaded \n " ) ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
2014-10-05 20:04:11 +00:00
BZ_Free ( buf ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
2014-10-05 20:04:11 +00:00
COM_AddWork ( 0 , Mod_ModelLoaded , mod , NULL , MLS_LOADED , 0 ) ;
return ;
2004-08-22 22:29:09 +00:00
}
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 - > engineflags = 0 ;
2014-10-05 20:04:11 +00:00
COM_AddWork ( 0 , Mod_ModelLoaded , mod , NULL , MLS_FAILED , verbose ) ;
}
model_t * Mod_LoadModel ( model_t * mod , enum mlverbosity_e verbose )
{
if ( mod - > loadstate = = MLS_NOTLOADED & & * mod - > name ! = ' * ' )
{
mod - > loadstate = MLS_LOADING ;
// if (verbose == MLV_ERROR) //if its fatal on failure (ie: world), do it on the main thread and block to wait for it.
// Mod_LoadModelWorker(mod, MLV_WARN, 0);
// else
COM_AddWork ( 1 , Mod_LoadModelWorker , mod , NULL , verbose , 0 ) ;
}
if ( verbose = = MLV_ERROR )
{
//someone already tried to load it without caring if it failed or not. make sure its loaded.
//fixme: this is a spinloop.
if ( mod - > loadstate = = MLS_LOADING )
COM_WorkerPartialSync ( mod , & mod - > loadstate , MLS_LOADING ) ;
if ( mod - > loadstate ! = MLS_LOADED )
Host_EndGame ( " Mod_NumForName: %s not found or couldn't load " , mod - > name ) ;
}
2004-08-22 22:29:09 +00:00
return mod ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_ForName
Loads in a model for the given name
= = = = = = = = = = = = = = = = = =
*/
2014-03-30 08:55:06 +00:00
model_t * Mod_ForName ( const char * name , enum mlverbosity_e verbosity )
2004-08-22 22:29:09 +00:00
{
model_t * mod ;
2013-07-14 12:22:51 +00:00
mod = Mod_FindName ( name ) ;
2004-08-22 22:29:09 +00:00
2014-03-30 08:55:06 +00:00
return Mod_LoadModel ( mod , verbosity ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
BRUSHMODEL LOADING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
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
2013-07-14 12:22:51 +00:00
static char * Mod_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 = = ' { ' )
2013-07-14 12:22:51 +00:00
file = Mod_TD_LeaveSection ( file ) ;
2004-09-01 22:59:56 +00:00
else if ( * com_token = = ' } ' )
return file ;
}
return NULL ;
}
2013-07-14 12:22:51 +00:00
static char * Mod_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 = = ' { ' )
2013-07-14 12:22:51 +00:00
file = Mod_TD_LeaveSection ( file ) ;
2004-09-01 22:59:56 +00:00
}
return NULL ;
}
2013-07-14 12:22:51 +00:00
void Mod_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 ) ;
2013-07-14 12:22:51 +00:00
mapsection = Mod_TD_Section ( advtexturedesc , mapname ) ;
defaultsection = Mod_TD_Section ( advtexturedesc , " default " ) ;
2004-09-01 22:59:56 +00:00
}
}
2013-07-14 12:22:51 +00:00
void Mod_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
2013-07-14 12:22:51 +00:00
section = Mod_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 ;
2013-07-14 12:22:51 +00:00
TRACE ( ( " dbg: Mod_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
}
2013-07-14 12:22:51 +00:00
void Mod_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 )
{
2013-07-14 12:22:51 +00:00
Mod_LoadAdvancedTextureSection ( mapsection , name , base , norm , luma , gloss , alphamode , cull ) ;
2004-09-01 22:59:56 +00:00
if ( * base )
return ;
}
if ( defaultsection )
2013-07-14 12:22:51 +00:00
Mod_LoadAdvancedTextureSection ( defaultsection , name , base , norm , luma , gloss , alphamode , cull ) ;
2009-11-04 21:16:50 +00:00
}
# endif
2014-10-05 20:04:11 +00:00
void Mod_FinishTexture ( texture_t * tx )
2009-11-04 21:16:50 +00:00
{
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2009-11-04 21:16:50 +00:00
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 )
2013-08-21 07:14:39 +00:00
tx - > shader = R_RegisterCustom ( va ( " skybox_%s " , cl . skyname ) , SUF_NONE , 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 , " * " ) )
2013-08-21 07:14:39 +00:00
tx - > shader = R_RegisterCustom ( tx - > name , SUF_LIGHTMAP , 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.
2013-08-21 07:14:39 +00:00
tx - > shader = R_RegisterCustom ( gl_shadeq1_name . string , SUF_LIGHTMAP , 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.
2013-08-21 07:14:39 +00:00
tx - > shader = R_RegisterCustom ( altname , SUF_LIGHTMAP , Shader_DefaultBSPQ1 , NULL ) ;
2009-11-04 21:16:50 +00:00
}
2014-10-05 20:04:11 +00:00
R_BuildDefaultTexnums ( & tx - > texnums , tx - > shader ) ;
2014-05-10 13:42:13 +00:00
# endif
2004-09-01 22:59:56 +00:00
}
2012-05-11 01:57:00 +00:00
# define LMT_DIFFUSE 1
# define LMT_FULLBRIGHT 2
# define LMT_BUMP 4
# define LMT_SPEC 8
2014-10-05 20:04:11 +00:00
static void Mod_LoadMiptex ( model_t * loadmodel , char * loadname , texture_t * tx , miptex_t * mt , int maps )
2012-05-11 01:57:00 +00:00
{
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2012-05-11 01:57:00 +00:00
char altname [ 256 ] ;
qbyte * base ;
qboolean alphaed ;
int pixels = mt - > width * mt - > height / 64 * 85 ;
2014-10-05 20:04:11 +00:00
if ( ! strncmp ( loadname , " b_ " , 2 ) )
loadname = " bmodels " ;
2012-05-11 01:57:00 +00:00
if ( ! Q_strncmp ( mt - > name , " sky " , 3 ) )
{
if ( maps & LMT_DIFFUSE )
2014-10-05 20:04:11 +00:00
R_InitSky ( & tx - > texnums , tx , ( char * ) mt + mt - > offsets [ 0 ] ) ;
2012-05-11 01:57:00 +00:00
}
else
{
/*
2013-07-14 12:22:51 +00:00
Mod_LoadAdvancedTexture ( tx - > name , & tn . base , & tn . bump , & tn . fullbright , & tn . specular , NULL , NULL ) ;
2012-05-11 01:57:00 +00:00
if ( tn . base )
continue ;
*/
base = ( qbyte * ) ( mt + 1 ) ;
if ( loadmodel - > fromgame = = fg_halflife )
{ //external textures have already been filtered.
if ( maps & LMT_DIFFUSE )
{
base = W_ConvertWAD3Texture ( mt , & mt - > width , & mt - > height , & alphaed ) ; //convert texture to 32 bit.
tx - > alphaed = alphaed ;
2014-10-05 20:04:11 +00:00
tx - > texnums . base = R_LoadReplacementTexture ( mt - > name , loadname , alphaed ? 0 : IF_NOALPHA , base , tx - > width , tx - > height , alphaed ? TF_RGBA32 : TF_RGBX32 ) ;
2012-07-05 19:42:36 +00:00
BZ_Free ( base ) ;
2012-05-11 01:57:00 +00:00
}
* tx - > name = * mt - > name ;
}
else
{
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 ;
}
if ( maps & LMT_DIFFUSE )
{
2014-10-05 20:04:11 +00:00
tx - > texnums . base = R_LoadReplacementTexture ( mt - > name , loadname , ( ( * mt - > name = = ' { ' ) ? 0 : IF_NOALPHA ) | IF_MIPCAP , mipbase , mipwidth , mipheight , ( * mt - > name = = ' { ' ) ? TF_TRANS8 : TF_SOLID8 ) ;
2012-05-11 01:57:00 +00:00
}
if ( maps & LMT_FULLBRIGHT )
{
snprintf ( altname , sizeof ( altname ) - 1 , " %s_luma " , mt - > name ) ;
2014-10-05 20:04:11 +00:00
tx - > texnums . fullbright = R_LoadReplacementTexture ( altname , loadname , IF_MIPCAP , mipbase , mipwidth , mipheight , TF_TRANS8_FULLBRIGHT ) ;
}
if ( ( maps & LMT_BUMP ) & & ( r_shadow_bumpscale_basetexture . value ! = 0 | | * mt - > name = = ' * ' ) )
{
maps & = ~ LMT_BUMP ;
snprintf ( altname , sizeof ( altname ) - 1 , " %s_norm " , mt - > name ) ;
tx - > texnums . bump = R_LoadReplacementTexture ( altname , loadname , IF_NOGAMMA | IF_MIPCAP | IF_TRYBUMP , mipbase , mipwidth , mipheight , TF_HEIGHT8PAL ) ;
2012-05-11 01:57:00 +00:00
}
}
if ( maps & LMT_BUMP )
{
snprintf ( altname , sizeof ( altname ) - 1 , " %s_norm " , mt - > name ) ;
2014-10-05 20:04:11 +00:00
tx - > texnums . bump = R_LoadReplacementTexture ( altname , loadname , IF_NOGAMMA | IF_MIPCAP | IF_TRYBUMP , NULL , 0 , 0 , TF_INVALID ) ;
2014-05-16 01:34:58 +00:00
}
2012-05-11 01:57:00 +00:00
2014-05-16 01:34:58 +00:00
//don't do any complex quake 8bit -> glossmap. It would likly look a little ugly...
2014-10-05 20:04:11 +00:00
if ( maps & LMT_SPEC ) //allows bumpmaps replacement without diffuse
2014-05-16 01:34:58 +00:00
{
snprintf ( altname , sizeof ( altname ) - 1 , " %s_gloss " , mt - > name ) ;
2014-10-05 20:04:11 +00:00
tx - > texnums . specular = R_LoadReplacementTexture ( altname , loadname , IF_NOGAMMA | IF_MIPCAP , NULL , 0 , 0 , TF_INVALID ) ;
2012-05-11 01:57:00 +00:00
}
}
2014-05-10 13:42:13 +00:00
# endif
2012-05-11 01:57:00 +00:00
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_LoadTextures
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadTextures ( model_t * loadmodel , qbyte * mod_base , lump_t * l , char * loadname )
2004-08-22 22:29:09 +00:00
{
2012-05-11 01:57:00 +00:00
int i , j , num , max , altmax ;
2004-08-22 22:29:09 +00:00
miptex_t * mt ;
texture_t * tx , * tx2 ;
texture_t * anims [ 10 ] ;
texture_t * altanims [ 10 ] ;
dmiptexlump_t * m ;
2009-11-04 21:16:50 +00:00
texnums_t tn ;
2012-05-11 01:57:00 +00:00
int maps ;
2004-09-01 22:59:56 +00:00
2013-07-14 12:22:51 +00:00
TRACE ( ( " dbg: Mod_LoadTextures: inittexturedescs \n " ) ) ;
2004-10-07 13:16:43 +00:00
2013-07-14 12:22:51 +00:00
// Mod_InitTextureDescs(loadname);
2004-09-20 23:25:38 +00:00
2004-08-22 22:29:09 +00:00
if ( ! l - > filelen )
{
2012-02-27 12:23:15 +00:00
Con_Printf ( CON_WARNING " warning: %s contains no texture data \n " , loadmodel - > name ) ;
2011-07-30 14:14:56 +00:00
loadmodel - > numtextures = 1 ;
2013-07-14 12:22:51 +00:00
loadmodel - > textures = ZG_Malloc ( & loadmodel - > memgroup , 1 * sizeof ( * loadmodel - > textures ) ) ;
2011-07-30 14:14:56 +00:00
i = 0 ;
2013-07-14 12:22:51 +00:00
tx = ZG_Malloc ( & loadmodel - > memgroup , sizeof ( texture_t ) ) ;
2011-07-30 14:14:56 +00:00
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 ) ;
2014-10-05 20:04:11 +00:00
2004-08-22 22:29:09 +00:00
m - > nummiptex = LittleLong ( m - > nummiptex ) ;
2014-10-05 20:04:11 +00:00
2004-08-22 22:29:09 +00:00
loadmodel - > numtextures = m - > nummiptex ;
2013-07-14 12:22:51 +00:00
loadmodel - > textures = ZG_Malloc ( & loadmodel - > memgroup , m - > nummiptex * sizeof ( * loadmodel - > textures ) ) ;
2004-08-22 22:29:09 +00:00
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
{
2013-07-14 12:22:51 +00:00
tx = ZG_Malloc ( & loadmodel - > memgroup , sizeof ( texture_t ) ) ;
2009-10-06 00:15:55 +00:00
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
2013-07-14 12:22:51 +00:00
TRACE ( ( " dbg: Mod_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 ] ) ;
2014-10-05 20:04:11 +00:00
2004-08-22 22:29:09 +00:00
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 ) ;
2013-07-14 12:22:51 +00:00
tx = ZG_Malloc ( & loadmodel - > memgroup , sizeof ( texture_t ) ) ;
2004-08-22 22:29:09 +00:00
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 ) ) ;
2014-10-05 20:04:11 +00:00
maps = 0 ;
# ifndef SERVERONLY
if ( qrenderer ! = QR_NONE )
{
maps | = LMT_DIFFUSE ;
if ( r_fb_bmodels . ival )
maps | = LMT_FULLBRIGHT ;
if ( r_loadbumpmapping | | ( r_waterstyle . ival > 1 & & * tx - > name = = ' * ' ) )
maps | = LMT_BUMP ;
if ( gl_specular . ival )
maps | = LMT_SPEC ;
}
# endif
2012-05-11 01:57:00 +00:00
2014-10-05 20:04:11 +00:00
Mod_LoadMiptex ( loadmodel , loadname , tx , mt , maps ) ;
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
}
2014-10-05 20:04:11 +00:00
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
}
2014-10-05 20:04:11 +00:00
void Mod_NowLoadExternal ( model_t * loadmodel )
2004-08-22 22:29:09 +00:00
{
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2004-08-22 22:29:09 +00:00
int i , width , height ;
qboolean alphaed ;
texture_t * tx ;
2014-10-05 20:04:11 +00:00
char loadname [ 32 ] ;
COM_FileBase ( cl . worldmodel - > name , loadname , sizeof ( loadname ) ) ;
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 ;
2014-10-05 20:04:11 +00:00
if ( ! TEXVALID ( tx - > texnums . 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 )
2012-07-05 19:42:36 +00:00
{
2011-03-24 14:35:24 +00:00
tx - > alphaed = alphaed ;
}
2009-11-04 21:16:50 +00:00
2014-10-05 20:04:11 +00:00
tx - > texnums . base = R_LoadHiResTexture ( tx - > name , loadname , IF_NOALPHA | IF_MIPCAP ) ;
if ( ! TEXVALID ( tx - > texnums . base ) )
2011-03-24 14:35:24 +00:00
{
2014-10-05 20:04:11 +00:00
tx - > texnums . base = R_LoadHiResTexture ( tx - > name , " bmodels " , IF_NOALPHA | IF_MIPCAP ) ;
2012-02-27 12:23:15 +00:00
// if (!TEXVALID(tn.base))
// tn.base = R_LoadReplacementTexture("light1_4", NULL, IF_NOALPHA|IF_MIPCAP); //a fallback. :/
2004-08-22 22:29:09 +00:00
}
2012-07-05 19:42:36 +00:00
BZ_Free ( data ) ;
2004-08-22 22:29:09 +00:00
}
2014-10-05 20:04:11 +00:00
if ( ! TEXVALID ( tx - > texnums . bump ) & & * tx - > name ! = ' { ' & & r_loadbumpmapping )
2004-08-22 22:29:09 +00:00
{
2014-10-05 20:04:11 +00:00
/* tx->texnums.bump = R_LoadBumpmapTexture(va("%s_bump", tx->name), loadname);
if ( ! TEXVALID ( tx - > texnums . bump ) )
tx - > texnums . bump = R_LoadBumpmapTexture ( va ( " %s_bump " , tx - > name ) , " bmodels " ) ;
2009-11-04 21:16:50 +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
*/ }
2014-10-05 20:04:11 +00:00
if ( ! TEXVALID ( tx - > texnums . base ) )
2011-07-30 14:14:56 +00:00
{
2014-10-05 20:04:11 +00:00
tx - > texnums . base = R_LoadTexture8 ( " notexture " , 16 , 16 , r_notexture_mip + 1 , IF_NOALPHA , 0 ) ;
2011-07-30 14:14:56 +00:00
}
2014-10-05 20:04:11 +00:00
Mod_FinishTexture ( tx ) ;
2004-08-22 22:29:09 +00:00
}
2014-05-10 13:42:13 +00:00
# endif
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
void Mod_LoadLighting ( model_t * loadmodel , qbyte * mod_base , lump_t * l )
2012-02-27 12:23:15 +00:00
{
qboolean luxtmp = true ;
qboolean littmp = true ;
2004-08-22 22:29:09 +00:00
qbyte * luxdata = NULL ;
2012-02-27 12:23:15 +00:00
qbyte * litdata = NULL ;
qbyte * lumdata = NULL ;
qbyte * out ;
unsigned int samples ;
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 ;
2012-02-27 12:23:15 +00:00
if ( loadmodel - > fromgame = = fg_halflife | | loadmodel - > fromgame = = fg_quake2 | | loadmodel - > fromgame = = fg_quake3 )
2004-10-07 13:16:43 +00:00
{
2012-02-27 12:23:15 +00:00
litdata = mod_base + l - > fileofs ;
samples = l - > filelen / 3 ;
2004-10-07 13:16:43 +00:00
}
2012-02-27 12:23:15 +00:00
else
{
lumdata = mod_base + l - > fileofs ;
samples = l - > filelen ;
}
if ( ! samples )
return ;
2004-10-07 13:16:43 +00:00
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2012-02-27 12:23:15 +00:00
if ( ! luxdata & & r_loadlits . ival & & r_deluxemapping . ival )
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.
2014-10-05 20:04:11 +00:00
char luxname [ MAX_QPATH ] ;
size_t luxsz = 0 ;
2004-08-22 22:29:09 +00:00
if ( ! luxdata )
{
2014-10-05 20:04:11 +00:00
Q_strncpyz ( luxname , loadmodel - > name , sizeof ( luxname ) ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( loadmodel - > name , luxname , sizeof ( luxname ) ) ;
COM_DefaultExtension ( luxname , " .lux " , sizeof ( luxname ) ) ;
2014-10-05 20:04:11 +00:00
luxdata = FS_LoadMallocGroupFile ( & loadmodel - > memgroup , luxname , & luxsz ) ;
2012-02-27 12:23:15 +00:00
luxtmp = false ;
2004-08-22 22:29:09 +00:00
}
if ( ! luxdata )
{
2014-10-05 20:04:11 +00:00
Q_strncpyz ( luxname , " luxs/ " , sizeof ( luxname ) ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , luxname + 5 , sizeof ( luxname ) - 5 ) ;
2014-10-05 20:04:11 +00:00
Q_strncatz ( luxname , " .lux " , sizeof ( luxname ) ) ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
luxdata = FS_LoadMallocGroupFile ( & loadmodel - > memgroup , luxname , & luxsz ) ;
2012-02-27 12:23:15 +00:00
luxtmp = false ;
2004-08-22 22:29:09 +00:00
}
2012-02-27 12:23:15 +00:00
if ( ! luxdata ) //dp...
2009-11-04 21:16:50 +00:00
{
2012-09-30 05:52:03 +00:00
COM_StripExtension ( loadmodel - > name , luxname , sizeof ( luxname ) ) ;
2009-11-04 21:16:50 +00:00
COM_DefaultExtension ( luxname , " .dlit " , sizeof ( luxname ) ) ;
2014-10-05 20:04:11 +00:00
luxdata = FS_LoadMallocGroupFile ( & loadmodel - > memgroup , luxname , & luxsz ) ;
2012-02-27 12:23:15 +00:00
luxtmp = false ;
2009-11-04 21:16:50 +00:00
}
2012-02-27 12:23:15 +00:00
if ( ! luxdata )
{
int size ;
luxdata = Q1BSPX_FindLump ( " LIGHTINGDIR " , & size ) ;
if ( size ! = samples * 3 )
luxdata = NULL ;
luxtmp = true ;
}
else if ( luxdata )
2004-08-22 22:29:09 +00:00
{
2014-10-05 20:04:11 +00:00
if ( l - > filelen & & l - > filelen ! = ( luxsz - 8 ) / 3 )
2004-08-22 22:29:09 +00:00
{
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 ;
}
}
}
2012-02-27 12:23:15 +00:00
if ( ! litdata & & r_loadlits . value )
2004-08-22 22:29:09 +00:00
{
2004-09-30 23:02:52 +00:00
char * litname ;
char litnamemaps [ MAX_QPATH ] ;
char litnamelits [ MAX_QPATH ] ;
int depthmaps ;
int depthlits ;
2014-10-05 20:04:11 +00:00
size_t litsize ;
2004-09-30 23:02:52 +00:00
2004-08-22 22:29:09 +00:00
{
2014-10-05 20:04:11 +00:00
Q_strncpyz ( litnamemaps , loadmodel - > name , sizeof ( litnamelits ) ) ;
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
}
{
2014-10-05 20:04:11 +00:00
Q_strncpyz ( litnamelits , " lits/ " , sizeof ( litnamelits ) ) ;
2006-03-11 03:12:10 +00:00
COM_StripExtension ( COM_SkipPath ( loadmodel - > name ) , litnamelits + 5 , sizeof ( litnamelits ) - 5 ) ;
2014-10-05 20:04:11 +00:00
Q_strncatz ( litnamelits , " .lit " , sizeof ( litnamelits ) ) ;
2004-09-30 23:02:52 +00:00
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
2014-10-05 20:04:11 +00:00
litdata = FS_LoadMallocGroupFile ( & loadmodel - > memgroup , litname , & litsize ) ;
2012-02-27 12:23:15 +00:00
littmp = false ;
if ( ! litdata )
{
int size ;
litdata = Q1BSPX_FindLump ( " RGBLIGHTING " , & size ) ;
if ( size ! = samples * 3 )
litdata = NULL ;
littmp = true ;
}
else if ( litdata [ 0 ] = = ' Q ' & & litdata [ 1 ] = = ' L ' & & litdata [ 2 ] = = ' I ' & & litdata [ 3 ] = = ' T ' )
2004-08-22 22:29:09 +00:00
{
2014-10-05 20:04:11 +00:00
if ( LittleLong ( * ( int * ) & litdata [ 4 ] ) = = 1 & & l - > filelen & & samples * 3 ! = ( litsize - 8 ) )
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
{
litdata = NULL ;
2004-08-22 22:29:09 +00:00
Con_Printf ( " lit \" %s \" doesn't match level. Ignored. \n " , litname ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
}
2004-08-22 22:29:09 +00:00
else if ( LittleLong ( * ( int * ) & litdata [ 4 ] ) ! = 1 )
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
{
2004-08-22 22:29:09 +00:00
Con_Printf ( " lit \" %s \" isn't version 1. \n " , litname ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
litdata = NULL ;
}
2012-02-27 12:23:15 +00:00
else if ( lumdata )
2004-08-22 22:29:09 +00:00
{
float prop ;
int i ;
2012-02-27 12:23:15 +00:00
qbyte * lum ;
qbyte * lit ;
2004-08-22 22:29:09 +00:00
2012-02-27 12:23:15 +00:00
litdata + = 8 ;
2004-08-22 22:29:09 +00:00
//now some cheat protection.
2012-02-27 12:23:15 +00:00
lum = lumdata ;
lit = litdata ;
2004-08-22 22:29:09 +00:00
2012-02-27 12:23:15 +00:00
for ( i = 0 ; i < samples ; i + + ) //force it to the same intensity. (or less, depending on how you see it...)
2004-08-22 22:29:09 +00:00
{
# define m(a, b, c) (a>(b>c?b:c)?a:(b>c?b:c))
2012-02-27 12:23:15 +00:00
prop = ( float ) m ( lit [ 0 ] , lit [ 1 ] , lit [ 2 ] ) ;
2004-08-22 22:29:09 +00:00
if ( ! prop )
{
2012-02-27 12:23:15 +00:00
lit [ 0 ] = * lum ;
lit [ 1 ] = * lum ;
lit [ 2 ] = * lum ;
2004-08-22 22:29:09 +00:00
}
else
{
2012-02-27 12:23:15 +00:00
prop = * lum / prop ;
lit [ 0 ] * = prop ;
lit [ 1 ] * = prop ;
lit [ 2 ] * = prop ;
2004-08-22 22:29:09 +00:00
}
2012-02-27 12:23:15 +00:00
lum + + ;
lit + = 3 ;
2004-08-22 22:29:09 +00:00
}
//end anti-cheat
}
}
else if ( litdata )
2013-03-12 22:53:23 +00:00
{
2004-08-22 22:29:09 +00:00
Con_Printf ( " lit \" %s \" isn't a lit \n " , litname ) ;
2013-03-12 22:53:23 +00:00
litdata = NULL ;
}
2004-08-22 22:29:09 +00:00
// else
//failed to find
}
2014-05-10 13:42:13 +00:00
# endif
2004-08-22 22:29:09 +00:00
# ifdef RUNTIMELIGHTING
2012-02-27 12:23:15 +00:00
if ( r_loadlits . value = = 2 & & ! lightmodel & & ( ! litdata | | ( ! luxdata & & r_deluxemapping . ival ) ) )
2004-08-22 22:29:09 +00:00
{
2012-04-24 07:59:11 +00:00
if ( ! litdata )
writelitfile = true ;
2004-08-22 22:29:09 +00:00
numlightdata = l - > filelen ;
lightmodel = loadmodel ;
relitsurface = 0 ;
}
2012-02-27 12:23:15 +00:00
/*if we're relighting, make sure there's the proper lit data to be updated*/
if ( lightmodel = = loadmodel & & ! litdata )
2005-05-18 01:40:01 +00:00
{
2012-02-27 12:23:15 +00:00
int i ;
2013-07-14 12:22:51 +00:00
litdata = ZG_Malloc ( & loadmodel - > memgroup , samples * 3 ) ;
2012-02-27 12:23:15 +00:00
littmp = false ;
if ( lumdata )
2005-05-18 01:40:01 +00:00
{
2012-02-27 12:23:15 +00:00
for ( i = 0 ; i < samples ; i + + )
{
litdata [ i * 3 + 0 ] = lumdata [ i ] ;
litdata [ i * 3 + 1 ] = lumdata [ i ] ;
litdata [ i * 3 + 2 ] = lumdata [ i ] ;
}
lumdata = NULL ;
2005-05-18 01:40:01 +00:00
}
}
2012-02-27 12:23:15 +00:00
/*if we're relighting, make sure there's the proper lux data to be updated*/
if ( lightmodel = = loadmodel & & r_deluxemapping . ival & & ! luxdata )
2004-08-22 22:29:09 +00:00
{
int i ;
2013-07-14 12:22:51 +00:00
luxdata = ZG_Malloc ( & loadmodel - > memgroup , samples * 3 ) ;
2012-02-27 12:23:15 +00:00
for ( i = 0 ; i < samples ; i + + )
2004-08-22 22:29:09 +00:00
{
2012-11-27 03:23:19 +00:00
luxdata [ i * 3 + 0 ] = 0.5f * 255 ;
luxdata [ i * 3 + 1 ] = 0.5f * 255 ;
luxdata [ i * 3 + 2 ] = 255 ;
2004-08-22 22:29:09 +00:00
}
2012-02-27 12:23:15 +00:00
}
# endif
if ( luxdata & & luxtmp )
{
loadmodel - > engineflags | = MDLF_RGBLIGHTING ;
2013-07-14 12:22:51 +00:00
loadmodel - > deluxdata = ZG_Malloc ( & loadmodel - > memgroup , samples * 3 ) ;
2012-02-27 12:23:15 +00:00
memcpy ( loadmodel - > deluxdata , luxdata , samples * 3 ) ;
}
else if ( luxdata )
{
loadmodel - > deluxdata = luxdata ;
}
if ( litdata & & littmp )
{
loadmodel - > engineflags | = MDLF_RGBLIGHTING ;
2013-07-14 12:22:51 +00:00
loadmodel - > lightdata = ZG_Malloc ( & loadmodel - > memgroup , samples * 3 ) ;
2012-02-27 12:23:15 +00:00
/*the memcpy is below*/
samples * = 3 ;
}
else if ( litdata )
{
loadmodel - > engineflags | = MDLF_RGBLIGHTING ;
loadmodel - > lightdata = litdata ;
samples * = 3 ;
}
else if ( lumdata )
{
loadmodel - > engineflags & = ~ MDLF_RGBLIGHTING ;
2013-07-14 12:22:51 +00:00
loadmodel - > lightdata = ZG_Malloc ( & loadmodel - > memgroup , samples ) ;
2012-02-27 12:23:15 +00:00
litdata = lumdata ;
}
2005-05-18 01:40:01 +00:00
2012-02-27 12:23:15 +00:00
/*apply lightmap gamma to the entire lightmap*/
out = loadmodel - > lightdata ;
while ( samples - - > 0 )
{
* out + + = lmgamma [ * litdata + + ] ;
2004-08-22 22:29:09 +00:00
}
2012-02-27 12:23:15 +00:00
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2012-02-27 12:23:15 +00:00
if ( ( loadmodel - > engineflags & MDLF_RGBLIGHTING ) & & r_lightmap_saturation . value ! = 1.0f )
SaturateR8G8B8 ( loadmodel - > lightdata , l - > filelen , r_lightmap_saturation . value ) ;
2014-05-10 13:42:13 +00:00
# endif
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadVisibility
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
void Mod_LoadVisibility ( model_t * loadmodel , qbyte * mod_base , lump_t * l , qbyte * ptr , size_t len )
2004-08-22 22:29:09 +00:00
{
2014-09-08 23:47:19 +00:00
if ( ! ptr )
{
ptr = mod_base + l - > fileofs ;
len = l - > filelen ;
}
if ( ! len )
2004-08-22 22:29:09 +00:00
{
loadmodel - > visdata = NULL ;
return ;
}
2014-09-08 23:47:19 +00:00
loadmodel - > visdata = ZG_Malloc ( & loadmodel - > memgroup , len ) ;
memcpy ( loadmodel - > visdata , ptr , len ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadEntities
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
void Mod_LoadEntities ( model_t * loadmodel , qbyte * mod_base , lump_t * l )
2004-08-22 22:29:09 +00:00
{
2014-10-05 20:04:11 +00:00
char fname [ MAX_QPATH ] ;
size_t sz ;
loadmodel - > entitiescrc = 0 ;
loadmodel - > entities = NULL ;
2004-08-22 22:29:09 +00:00
if ( ! l - > filelen )
return ;
2014-10-05 20:04:11 +00:00
if ( mod_loadentfiles . value & & ! loadmodel - > entities )
{
COM_StripExtension ( loadmodel - > name , fname , sizeof ( fname ) ) ;
Q_strncatz ( fname , " .ent " , sizeof ( fname ) ) ;
loadmodel - > entities = FS_LoadMallocGroupFile ( & loadmodel - > memgroup , fname , & sz ) ;
}
if ( mod_loadentfiles . value & & ! loadmodel - > entities )
{ //tenebrae compat
COM_StripExtension ( loadmodel - > name , fname , sizeof ( fname ) ) ;
Q_strncatz ( fname , " .edo " , sizeof ( fname ) ) ;
loadmodel - > entities = FS_LoadMallocGroupFile ( & loadmodel - > memgroup , fname , & sz ) ;
}
if ( ! loadmodel - > entities )
{
loadmodel - > entities = ZG_Malloc ( & loadmodel - > memgroup , l - > filelen + 1 ) ;
memcpy ( loadmodel - > entities , mod_base + l - > fileofs , l - > filelen ) ;
loadmodel - > entities [ l - > filelen ] = 0 ;
2004-08-22 22:29:09 +00:00
}
2014-10-05 20:04:11 +00:00
else
loadmodel - > entitiescrc = QCRC_Block ( loadmodel - > entities , strlen ( loadmodel - > entities ) ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadVertexes
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadVertexes ( model_t * loadmodel , qbyte * mod_base , 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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
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 ;
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadSubmodels ( model_t * loadmodel , qbyte * mod_base , 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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
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 ;
2013-12-29 22:48:28 +00:00
for ( j = 0 ; j < 4 ; j + + )
2004-08-22 22:29:09 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadEdges ( model_t * loadmodel , qbyte * mod_base , 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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , ( count + 1 ) * sizeof ( * out ) ) ;
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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , ( count + 1 ) * sizeof ( * out ) ) ;
2011-10-27 16:16:29 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadTexinfo ( model_t * loadmodel , qbyte * mod_base , 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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
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 [ ]
= = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
void CalcSurfaceExtents ( model_t * mod , msurface_t * s ) ;
2004-08-22 22:29:09 +00:00
/*
{
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadFaces ( model_t * loadmodel , qbyte * mod_base , 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
}
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
// *meshlist = ZG_Malloc(&loadmodel->memgroup, count*sizeof(**meshlist));
2004-08-22 22:29:09 +00:00
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 ) ;
2013-10-08 14:28:11 +00:00
for ( i = 0 ; i < MAXRLIGHTMAPS ; i + + )
2011-10-27 16:16:29 +00:00
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 ) ;
2013-10-08 14:28:11 +00:00
for ( i = 0 ; i < MAXQ1LIGHTMAPS ; i + + )
2011-10-27 16:16:29 +00:00
out - > styles [ i ] = ins - > styles [ i ] ;
lofs = LittleLong ( ins - > lightofs ) ;
ins + + ;
}
2012-07-05 19:42:36 +00:00
// (*meshlist)[surfnum].vbofirstvert = out->firstedge;
// (*meshlist)[surfnum].numvertexes = out->numedges;
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 )
2014-10-05 20:04:11 +00:00
{
Con_Printf ( " texinfo 0 <= %i < %i \n " , tn , loadmodel - > numtexinfo ) ;
return false ;
}
2004-12-29 03:22:09 +00:00
out - > texinfo = loadmodel - > texinfo + tn ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
CalcSurfaceExtents ( loadmodel , 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
}
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2013-07-14 12:22:51 +00:00
void ModQ1_Batches_BuildQ1Q2Poly ( model_t * mod , msurface_t * surf , void * cookie )
2012-07-05 19:42:36 +00:00
{
int i , lindex ;
mesh_t * mesh = surf - > mesh ;
medge_t * pedge ;
float * vec ;
float s , t , d ;
int sty ;
//output the mesh's indicies
for ( i = 0 ; i < mesh - > numvertexes - 2 ; i + + )
{
mesh - > indexes [ i * 3 ] = 0 ;
mesh - > indexes [ i * 3 + 1 ] = i + 1 ;
mesh - > indexes [ i * 3 + 2 ] = i + 2 ;
}
//output the renderable verticies
for ( i = 0 ; i < mesh - > numvertexes ; i + + )
{
lindex = mod - > surfedges [ surf - > firstedge + i ] ;
if ( lindex > 0 )
{
pedge = & mod - > edges [ lindex ] ;
vec = mod - > vertexes [ pedge - > v [ 0 ] ] . position ;
}
else
{
pedge = & mod - > edges [ - lindex ] ;
vec = mod - > vertexes [ pedge - > v [ 1 ] ] . position ;
}
s = DotProduct ( vec , surf - > texinfo - > vecs [ 0 ] ) + surf - > texinfo - > vecs [ 0 ] [ 3 ] ;
t = DotProduct ( vec , surf - > texinfo - > vecs [ 1 ] ) + surf - > texinfo - > vecs [ 1 ] [ 3 ] ;
VectorCopy ( vec , mesh - > xyz_array [ i ] ) ;
mesh - > st_array [ i ] [ 0 ] = s / surf - > texinfo - > texture - > width ;
mesh - > st_array [ i ] [ 1 ] = t / surf - > texinfo - > texture - > height ;
2014-04-02 00:58:02 +00:00
if ( gl_lightmap_average . ival )
2012-07-05 19:42:36 +00:00
{
2014-04-02 00:58:02 +00:00
for ( sty = 0 ; sty < 1 ; sty + + )
{
mesh - > lmst_array [ sty ] [ i ] [ 0 ] = ( surf - > extents [ 0 ] * 0.5 + ( surf - > light_s [ sty ] * 16 ) + 8 ) / ( mod - > lightmaps . width * 16 ) ;
mesh - > lmst_array [ sty ] [ i ] [ 1 ] = ( surf - > extents [ 1 ] * 0.5 + ( surf - > light_t [ sty ] * 16 ) + 8 ) / ( mod - > lightmaps . height * 16 ) ;
}
}
else
{
for ( sty = 0 ; sty < 1 ; sty + + )
{
mesh - > lmst_array [ sty ] [ i ] [ 0 ] = ( s - surf - > texturemins [ 0 ] + ( surf - > light_s [ sty ] * 16 ) + 8 ) / ( mod - > lightmaps . width * 16 ) ;
mesh - > lmst_array [ sty ] [ i ] [ 1 ] = ( t - surf - > texturemins [ 1 ] + ( surf - > light_t [ sty ] * 16 ) + 8 ) / ( mod - > lightmaps . height * 16 ) ;
}
2012-07-05 19:42:36 +00:00
}
//figure out the texture directions, for bumpmapping and stuff
if ( surf - > flags & SURF_PLANEBACK )
VectorNegate ( surf - > plane - > normal , mesh - > normals_array [ i ] ) ;
else
VectorCopy ( surf - > plane - > normal , mesh - > normals_array [ i ] ) ;
2014-01-13 02:42:25 +00:00
VectorCopy ( surf - > texinfo - > vecs [ 0 ] , mesh - > snormals_array [ i ] ) ;
2012-07-05 19:42:36 +00:00
VectorNegate ( surf - > texinfo - > vecs [ 1 ] , mesh - > tnormals_array [ i ] ) ;
//the s+t vectors are axis-aligned, so fiddle them so they're normal aligned instead
d = - DotProduct ( mesh - > normals_array [ i ] , mesh - > snormals_array [ i ] ) ;
VectorMA ( mesh - > snormals_array [ i ] , d , mesh - > normals_array [ i ] , mesh - > snormals_array [ i ] ) ;
d = - DotProduct ( mesh - > normals_array [ i ] , mesh - > tnormals_array [ i ] ) ;
VectorMA ( mesh - > tnormals_array [ i ] , d , mesh - > normals_array [ i ] , mesh - > tnormals_array [ i ] ) ;
VectorNormalize ( mesh - > snormals_array [ i ] ) ;
VectorNormalize ( mesh - > tnormals_array [ i ] ) ;
2013-08-27 13:18:09 +00:00
//q1bsp has no colour information (fixme: sample from the lightmap?)
for ( sty = 0 ; sty < 1 ; sty + + )
{
mesh - > colors4f_array [ sty ] [ i ] [ 0 ] = 1 ;
mesh - > colors4f_array [ sty ] [ i ] [ 1 ] = 1 ;
mesh - > colors4f_array [ sty ] [ i ] [ 2 ] = 1 ;
mesh - > colors4f_array [ sty ] [ i ] [ 3 ] = 1 ;
}
2012-07-05 19:42:36 +00:00
}
}
2014-10-05 20:04:11 +00:00
static void Mod_Batches_BuildModelMeshes ( model_t * mod , int maxverts , int maxindicies , void ( * build ) ( model_t * mod , msurface_t * surf , builddata_t * bd ) , builddata_t * bd )
2012-07-05 19:42:36 +00:00
{
batch_t * batch ;
msurface_t * surf ;
mesh_t * mesh ;
int numverts = 0 ;
int numindicies = 0 ;
int j ;
int sortid ;
int sty ;
vbo_t vbo ;
2013-05-03 04:28:08 +00:00
int styles = mod - > lightmaps . surfstyles ;
2013-08-27 13:18:09 +00:00
char * ptr ;
2012-07-05 19:42:36 +00:00
2014-08-25 07:35:41 +00:00
memset ( & vbo , 0 , sizeof ( vbo ) ) ;
2014-10-05 20:04:11 +00:00
vbo . indicies . sysptr = ZG_Malloc ( & mod - > memgroup , sizeof ( index_t ) * maxindicies ) ;
ptr = ZG_Malloc ( & mod - > memgroup , ( sizeof ( vecV_t ) + sizeof ( vec2_t ) * ( 1 + styles ) + sizeof ( vec3_t ) * 3 + sizeof ( vec4_t ) * styles ) * maxverts ) ;
vbo . coord . sysptr = ptr ;
2013-08-27 13:18:09 +00:00
ptr + = sizeof ( vecV_t ) * maxverts ;
for ( sty = 0 ; sty < styles ; sty + + )
2013-05-03 04:28:08 +00:00
{
2014-10-05 20:04:11 +00:00
vbo . colours [ sty ] . sysptr = ptr ;
2013-08-27 13:18:09 +00:00
ptr + = sizeof ( vec4_t ) * maxverts ;
2013-05-03 04:28:08 +00:00
}
2013-10-08 14:28:11 +00:00
for ( ; sty < MAXRLIGHTMAPS ; sty + + )
2014-10-05 20:04:11 +00:00
vbo . colours [ sty ] . sysptr = NULL ;
vbo . texcoord . sysptr = ptr ;
2013-08-27 13:18:09 +00:00
ptr + = sizeof ( vec2_t ) * maxverts ;
sty = 0 ;
2013-05-03 04:28:08 +00:00
for ( ; sty < styles ; sty + + )
2013-08-27 13:18:09 +00:00
{
2014-10-05 20:04:11 +00:00
vbo . lmcoord [ sty ] . sysptr = ptr ;
2013-08-27 13:18:09 +00:00
ptr + = sizeof ( vec2_t ) * maxverts ;
}
2013-10-08 14:28:11 +00:00
for ( ; sty < MAXRLIGHTMAPS ; sty + + )
2014-10-05 20:04:11 +00:00
vbo . lmcoord [ sty ] . sysptr = NULL ;
vbo . normals . sysptr = ptr ;
2013-08-27 13:18:09 +00:00
ptr + = sizeof ( vec3_t ) * maxverts ;
2014-10-05 20:04:11 +00:00
vbo . svector . sysptr = ptr ;
2013-08-27 13:18:09 +00:00
ptr + = sizeof ( vec3_t ) * maxverts ;
2014-10-05 20:04:11 +00:00
vbo . tvector . sysptr = ptr ;
2013-08-27 13:18:09 +00:00
ptr + = sizeof ( vec3_t ) * maxverts ;
2012-07-05 19:42:36 +00:00
numindicies = 0 ;
numverts = 0 ;
//build each mesh
for ( sortid = 0 ; sortid < SHADER_SORT_COUNT ; sortid + + )
{
for ( batch = mod - > batches [ sortid ] ; batch ; batch = batch - > next )
{
for ( j = 0 ; j < batch - > maxmeshes ; j + + )
{
surf = ( msurface_t * ) batch - > mesh [ j ] ;
mesh = surf - > mesh ;
batch - > mesh [ j ] = mesh ;
mesh - > vbofirstvert = numverts ;
mesh - > vbofirstelement = numindicies ;
numverts + = mesh - > numvertexes ;
numindicies + = mesh - > numindexes ;
//set up the arrays. the arrangement is required for the backend to optimise vbos
2014-10-05 20:04:11 +00:00
mesh - > xyz_array = ( vecV_t * ) vbo . coord . sysptr + mesh - > vbofirstvert ;
mesh - > st_array = ( vec2_t * ) vbo . texcoord . sysptr + mesh - > vbofirstvert ;
2013-10-08 14:28:11 +00:00
for ( sty = 0 ; sty < MAXRLIGHTMAPS ; sty + + )
2013-05-03 04:28:08 +00:00
{
2014-10-05 20:04:11 +00:00
if ( vbo . lmcoord [ sty ] . sysptr )
mesh - > lmst_array [ sty ] = ( vec2_t * ) vbo . lmcoord [ sty ] . sysptr + mesh - > vbofirstvert ;
2013-05-03 04:28:08 +00:00
else
mesh - > lmst_array [ sty ] = NULL ;
2014-10-05 20:04:11 +00:00
if ( vbo . colours [ sty ] . sysptr )
mesh - > colors4f_array [ sty ] = ( vec4_t * ) vbo . colours [ sty ] . sysptr + mesh - > vbofirstvert ;
2013-08-27 13:18:09 +00:00
else
mesh - > colors4f_array [ sty ] = NULL ;
2013-05-03 04:28:08 +00:00
}
2014-10-05 20:04:11 +00:00
mesh - > normals_array = ( vec3_t * ) vbo . normals . sysptr + mesh - > vbofirstvert ;
mesh - > snormals_array = ( vec3_t * ) vbo . svector . sysptr + mesh - > vbofirstvert ;
mesh - > tnormals_array = ( vec3_t * ) vbo . tvector . sysptr + mesh - > vbofirstvert ;
mesh - > indexes = ( index_t * ) vbo . indicies . sysptr + mesh - > vbofirstelement ;
2012-07-05 19:42:36 +00:00
mesh - > vbofirstvert = 0 ;
mesh - > vbofirstelement = 0 ;
2014-10-05 20:04:11 +00:00
build ( mod , surf , bd ) ;
2012-07-05 19:42:36 +00:00
}
batch - > meshes = 0 ;
batch - > firstmesh = 0 ;
}
}
}
2013-12-02 14:30:30 +00:00
//q1 autoanimates. if the frame is set, it uses the alternate animation.
void Mod_UpdateBatchShader_Q1 ( struct batch_s * batch )
{
texture_t * base = batch - > texture ;
int reletive ;
int count ;
if ( batch - > ent - > framestate . g [ FS_REG ] . frame [ 0 ] )
{
if ( base - > alternate_anims )
base = base - > alternate_anims ;
}
if ( base - > anim_total )
{
reletive = ( int ) ( cl . time * 10 ) % base - > anim_total ;
count = 0 ;
while ( base - > anim_min > reletive | | base - > anim_max < = reletive )
{
base = base - > anim_next ;
if ( ! base )
Sys_Error ( " R_TextureAnimation: broken cycle " ) ;
if ( + + count > 100 )
Sys_Error ( " R_TextureAnimation: infinite cycle " ) ;
}
}
batch - > shader = base - > shader ;
}
//q2 has direct control over the texture frames used, but typically has the client generate the frame (different flags autogenerate different ranges).
void Mod_UpdateBatchShader_Q2 ( struct batch_s * batch )
{
texture_t * base = batch - > texture ;
int reletive ;
int frame = batch - > ent - > framestate . g [ FS_REG ] . frame [ 0 ] ;
if ( batch - > ent = = & r_worldentity )
frame = cl . time * 2 ;
if ( base - > anim_total )
{
reletive = frame % base - > anim_total ;
while ( reletive - - > 0 )
{
base = base - > anim_next ;
if ( ! base )
Sys_Error ( " R_TextureAnimation: broken cycle " ) ;
}
}
batch - > shader = base - > shader ;
}
2012-07-05 19:42:36 +00:00
/*
batch - > firstmesh is set only in and for this function , its cleared out elsewhere
*/
2013-07-14 12:22:51 +00:00
static void Mod_Batches_Generate ( model_t * mod )
2012-07-05 19:42:36 +00:00
{
int i ;
msurface_t * surf ;
shader_t * shader ;
int sortid ;
batch_t * batch , * lbatch = NULL ;
vec4_t plane ;
//for each surface, find a suitable batch to insert it into.
//we use 'firstmesh' to avoid chucking out too many verts in a single vbo (gl2 hardware tends to have a 16bit limit)
for ( i = 0 ; i < mod - > nummodelsurfaces ; i + + )
{
surf = mod - > surfaces + mod - > firstmodelsurface + i ;
shader = surf - > texinfo - > texture - > shader ;
if ( shader )
{
sortid = shader - > sort ;
//shaders that are portals need to be split into separate batches to have the same surface planes
if ( sortid = = SHADER_SORT_PORTAL | | ( shader - > flags & ( SHADER_HASREFLECT | SHADER_HASREFRACT ) ) )
{
if ( surf - > flags & SURF_PLANEBACK )
{
VectorNegate ( surf - > plane - > normal , plane ) ;
plane [ 3 ] = - surf - > plane - > dist ;
}
else
{
VectorCopy ( surf - > plane - > normal , plane ) ;
plane [ 3 ] = surf - > plane - > dist ;
}
}
else
{
VectorClear ( plane ) ;
plane [ 3 ] = 0 ;
}
}
else
{
sortid = SHADER_SORT_OPAQUE ;
VectorClear ( plane ) ;
plane [ 3 ] = 0 ;
}
2012-10-08 04:36:10 +00:00
if ( lbatch & & (
lbatch - > texture = = surf - > texinfo - > texture & &
lbatch - > lightmap [ 0 ] = = surf - > lightmaptexturenums [ 0 ] & &
Vector4Compare ( plane , lbatch - > plane ) & &
lbatch - > firstmesh + surf - > mesh - > numvertexes < = MAX_INDICIES ) & &
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2012-10-08 04:36:10 +00:00
lbatch - > lightmap [ 1 ] = = surf - > lightmaptexturenums [ 1 ] & &
lbatch - > lightmap [ 2 ] = = surf - > lightmaptexturenums [ 2 ] & &
lbatch - > lightmap [ 3 ] = = surf - > lightmaptexturenums [ 3 ] & &
2013-10-08 14:28:11 +00:00
# endif
2012-10-08 04:36:10 +00:00
lbatch - > fog = = surf - > fog )
2012-07-05 19:42:36 +00:00
batch = lbatch ;
else
{
for ( batch = mod - > batches [ sortid ] ; batch ; batch = batch - > next )
{
2012-10-08 04:36:10 +00:00
if (
batch - > texture = = surf - > texinfo - > texture & &
batch - > lightmap [ 0 ] = = surf - > lightmaptexturenums [ 0 ] & &
Vector4Compare ( plane , batch - > plane ) & &
batch - > firstmesh + surf - > mesh - > numvertexes < = MAX_INDICIES & &
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2012-10-08 04:36:10 +00:00
batch - > lightmap [ 1 ] = = surf - > lightmaptexturenums [ 1 ] & &
batch - > lightmap [ 2 ] = = surf - > lightmaptexturenums [ 2 ] & &
batch - > lightmap [ 3 ] = = surf - > lightmaptexturenums [ 3 ] & &
2013-10-08 14:28:11 +00:00
# endif
2012-10-08 04:36:10 +00:00
batch - > fog = = surf - > fog )
2012-07-05 19:42:36 +00:00
break ;
}
}
if ( ! batch )
{
2014-10-05 20:04:11 +00:00
batch = ZG_Malloc ( & mod - > memgroup , sizeof ( * batch ) ) ;
2012-07-05 19:42:36 +00:00
batch - > lightmap [ 0 ] = surf - > lightmaptexturenums [ 0 ] ;
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2012-07-05 19:42:36 +00:00
batch - > lightmap [ 1 ] = surf - > lightmaptexturenums [ 1 ] ;
batch - > lightmap [ 2 ] = surf - > lightmaptexturenums [ 2 ] ;
batch - > lightmap [ 3 ] = surf - > lightmaptexturenums [ 3 ] ;
2013-10-08 14:28:11 +00:00
# endif
2012-07-05 19:42:36 +00:00
batch - > texture = surf - > texinfo - > texture ;
2013-12-02 14:30:30 +00:00
batch - > shader = surf - > texinfo - > texture - > shader ;
if ( surf - > texinfo - > texture - > alternate_anims | | surf - > texinfo - > texture - > anim_total )
{
if ( mod - > fromgame = = fg_quake2 )
batch - > buildmeshes = Mod_UpdateBatchShader_Q2 ;
else
batch - > buildmeshes = Mod_UpdateBatchShader_Q1 ;
}
2012-07-05 19:42:36 +00:00
batch - > next = mod - > batches [ sortid ] ;
batch - > ent = & r_worldentity ;
2012-10-08 04:36:10 +00:00
batch - > fog = surf - > fog ;
2012-07-05 19:42:36 +00:00
Vector4Copy ( plane , batch - > plane ) ;
mod - > batches [ sortid ] = batch ;
}
surf - > sbatch = batch ; //let the surface know which batch its in
batch - > maxmeshes + + ;
batch - > firstmesh + = surf - > mesh - > numvertexes ;
lbatch = batch ;
}
}
typedef struct
{
int allocated [ LMBLOCK_WIDTH ] ;
int lmnum ;
2012-09-30 05:52:03 +00:00
qboolean deluxe ;
2012-07-05 19:42:36 +00:00
} lmalloc_t ;
2013-07-14 12:22:51 +00:00
static void Mod_LightmapAllocInit ( lmalloc_t * lmallocator , qboolean hasdeluxe )
2012-07-05 19:42:36 +00:00
{
memset ( lmallocator , 0 , sizeof ( * lmallocator ) ) ;
2012-09-30 05:52:03 +00:00
lmallocator - > deluxe = hasdeluxe ;
2012-07-05 19:42:36 +00:00
}
2013-07-14 12:22:51 +00:00
static void Mod_LightmapAllocDone ( lmalloc_t * lmallocator , model_t * mod )
2012-07-05 19:42:36 +00:00
{
mod - > lightmaps . first = 1 ;
mod - > lightmaps . count = lmallocator - > lmnum ;
2012-09-30 05:52:03 +00:00
if ( lmallocator - > deluxe )
{
mod - > lightmaps . first * = 2 ;
mod - > lightmaps . count * = 2 ;
mod - > lightmaps . deluxemapping = true ;
}
else
mod - > lightmaps . deluxemapping = false ;
2012-07-05 19:42:36 +00:00
}
2013-07-14 12:22:51 +00:00
static void Mod_LightmapAllocBlock ( lmalloc_t * lmallocator , int w , int h , unsigned short * x , unsigned short * y , int * tnum )
2012-07-05 19:42:36 +00:00
{
int best , best2 ;
int i , j ;
if ( ! lmallocator - > lmnum )
lmallocator - > lmnum = 1 ;
for ( ; ; )
{
best = LMBLOCK_HEIGHT ;
for ( i = 0 ; i < = LMBLOCK_WIDTH - w ; i + + )
{
best2 = 0 ;
for ( j = 0 ; j < w ; j + + )
{
if ( lmallocator - > allocated [ i + j ] > = best )
break ;
if ( lmallocator - > allocated [ i + j ] > best2 )
best2 = lmallocator - > allocated [ i + j ] ;
}
if ( j = = w )
{ // this is a valid spot
* x = i ;
* y = best = best2 ;
}
}
if ( best + h > LMBLOCK_HEIGHT )
{
memset ( lmallocator - > allocated , 0 , sizeof ( lmallocator - > allocated ) ) ;
lmallocator - > lmnum + + ;
continue ;
}
for ( i = 0 ; i < w ; i + + )
lmallocator - > allocated [ * x + i ] = best + h ;
2012-09-30 05:52:03 +00:00
if ( lmallocator - > deluxe )
* tnum = lmallocator - > lmnum * 2 ;
else
* tnum = lmallocator - > lmnum ;
2012-07-05 19:42:36 +00:00
break ;
}
}
2013-07-14 12:22:51 +00:00
static void Mod_LightmapAllocSurf ( lmalloc_t * lmallocator , msurface_t * surf , int surfstyle )
2012-07-05 19:42:36 +00:00
{
int smax , tmax ;
smax = ( surf - > extents [ 0 ] > > 4 ) + 1 ;
tmax = ( surf - > extents [ 1 ] > > 4 ) + 1 ;
if ( isDedicated | |
( surf - > texinfo - > texture - > shader & & ! ( surf - > texinfo - > texture - > shader - > flags & SHADER_HASLIGHTMAP ) ) | | //fte
( surf - > flags & ( SURF_DRAWSKY | SURF_DRAWTURB ) ) | | //q1
( surf - > texinfo - > flags & TEX_SPECIAL ) | | //the original 'no lightmap'
( surf - > texinfo - > flags & ( TI_SKY | TI_TRANS33 | TI_TRANS66 | TI_WARP ) ) | | //q2 surfaces
smax > LMBLOCK_WIDTH | | tmax > LMBLOCK_HEIGHT | | smax < 0 | | tmax < 0 ) //bugs/bounds/etc
{
surf - > lightmaptexturenums [ surfstyle ] = - 1 ;
return ;
}
2013-07-14 12:22:51 +00:00
Mod_LightmapAllocBlock ( lmallocator , smax , tmax , & surf - > light_s [ surfstyle ] , & surf - > light_t [ surfstyle ] , & surf - > lightmaptexturenums [ surfstyle ] ) ;
2012-07-05 19:42:36 +00:00
}
2013-07-14 12:22:51 +00:00
static void Mod_Batches_SplitLightmaps ( model_t * mod )
2012-07-05 19:42:36 +00:00
{
batch_t * batch ;
batch_t * nb ;
int i , j , sortid ;
msurface_t * surf ;
int sty ;
for ( sortid = 0 ; sortid < SHADER_SORT_COUNT ; sortid + + )
for ( batch = mod - > batches [ sortid ] ; batch ! = NULL ; batch = batch - > next )
{
surf = ( msurface_t * ) batch - > mesh [ 0 ] ;
2013-10-08 14:28:11 +00:00
for ( sty = 0 ; sty < MAXRLIGHTMAPS ; sty + + )
2012-07-05 19:42:36 +00:00
{
batch - > lightmap [ sty ] = surf - > lightmaptexturenums [ sty ] ;
2013-08-27 13:18:09 +00:00
batch - > lmlightstyle [ sty ] = surf - > styles [ sty ] ;
2012-07-05 19:42:36 +00:00
}
for ( j = 1 ; j < batch - > maxmeshes ; j + + )
{
surf = ( msurface_t * ) batch - > mesh [ j ] ;
2013-10-08 14:28:11 +00:00
for ( sty = 0 ; sty < MAXRLIGHTMAPS ; sty + + )
2013-08-27 13:18:09 +00:00
{
if ( surf - > lightmaptexturenums [ sty ] ! = batch - > lightmap [ sty ] | |
//fixme: we should merge later (reverted matching) surfaces into the prior batch
surf - > styles [ sty ] ! = batch - > lmlightstyle [ sty ] | |
surf - > vlstyles [ sty ] ! = batch - > vtlightstyle [ sty ] )
break ;
}
2013-10-08 14:28:11 +00:00
if ( sty < MAXRLIGHTMAPS )
2012-07-05 19:42:36 +00:00
{
2014-10-05 20:04:11 +00:00
nb = ZG_Malloc ( & mod - > memgroup , sizeof ( * batch ) ) ;
2012-07-05 19:42:36 +00:00
* nb = * batch ;
batch - > next = nb ;
nb - > mesh = batch - > mesh + j * 2 ;
nb - > maxmeshes = batch - > maxmeshes - j ;
batch - > maxmeshes = j ;
2013-10-08 14:28:11 +00:00
for ( sty = 0 ; sty < MAXRLIGHTMAPS ; sty + + )
2012-07-05 19:42:36 +00:00
{
nb - > lightmap [ sty ] = surf - > lightmaptexturenums [ sty ] ;
2013-08-27 13:18:09 +00:00
nb - > lmlightstyle [ sty ] = surf - > styles [ sty ] ;
nb - > vtlightstyle [ sty ] = surf - > vlstyles [ sty ] ;
2012-07-05 19:42:36 +00:00
}
memmove ( nb - > mesh , batch - > mesh + j , sizeof ( msurface_t * ) * nb - > maxmeshes ) ;
for ( i = 0 ; i < nb - > maxmeshes ; i + + )
{
surf = ( msurface_t * ) nb - > mesh [ i ] ;
surf - > sbatch = nb ;
}
batch = nb ;
j = 1 ;
}
}
}
}
/*
allocates lightmaps and splits batches upon lightmap boundaries
*/
2013-07-14 12:22:51 +00:00
static void Mod_Batches_AllocLightmaps ( model_t * mod )
2012-07-05 19:42:36 +00:00
{
batch_t * batch ;
batch_t * nb ;
lmalloc_t lmallocator ;
int i , j , sortid ;
msurface_t * surf ;
int sty ;
2013-07-14 12:22:51 +00:00
Mod_LightmapAllocInit ( & lmallocator , mod - > deluxdata ! = NULL ) ;
2012-07-05 19:42:36 +00:00
for ( sortid = 0 ; sortid < SHADER_SORT_COUNT ; sortid + + )
for ( batch = mod - > batches [ sortid ] ; batch ! = NULL ; batch = batch - > next )
{
surf = ( msurface_t * ) batch - > mesh [ 0 ] ;
2013-07-14 12:22:51 +00:00
Mod_LightmapAllocSurf ( & lmallocator , surf , 0 ) ;
2013-10-08 14:28:11 +00:00
for ( sty = 1 ; sty < MAXRLIGHTMAPS ; sty + + )
2012-07-05 19:42:36 +00:00
surf - > lightmaptexturenums [ sty ] = - 1 ;
2013-10-08 14:28:11 +00:00
for ( sty = 0 ; sty < MAXRLIGHTMAPS ; sty + + )
2012-07-05 19:42:36 +00:00
{
batch - > lightmap [ sty ] = surf - > lightmaptexturenums [ sty ] ;
2013-08-27 13:18:09 +00:00
batch - > lmlightstyle [ sty ] = 255 ; //don't do special backend rendering of lightstyles.
batch - > vtlightstyle [ sty ] = 255 ; //don't do special backend rendering of lightstyles.
2012-07-05 19:42:36 +00:00
}
for ( j = 1 ; j < batch - > maxmeshes ; j + + )
{
surf = ( msurface_t * ) batch - > mesh [ j ] ;
2013-07-14 12:22:51 +00:00
Mod_LightmapAllocSurf ( & lmallocator , surf , 0 ) ;
2013-10-08 14:28:11 +00:00
for ( sty = 1 ; sty < MAXRLIGHTMAPS ; sty + + )
2012-07-05 19:42:36 +00:00
surf - > lightmaptexturenums [ sty ] = - 1 ;
if ( surf - > lightmaptexturenums [ 0 ] ! = batch - > lightmap [ 0 ] )
{
2014-10-05 20:04:11 +00:00
nb = ZG_Malloc ( & mod - > memgroup , sizeof ( * batch ) ) ;
2012-07-05 19:42:36 +00:00
* nb = * batch ;
batch - > next = nb ;
nb - > mesh = batch - > mesh + j * 2 ;
nb - > maxmeshes = batch - > maxmeshes - j ;
batch - > maxmeshes = j ;
2013-10-08 14:28:11 +00:00
for ( sty = 0 ; sty < MAXRLIGHTMAPS ; sty + + )
2012-07-05 19:42:36 +00:00
nb - > lightmap [ sty ] = surf - > lightmaptexturenums [ sty ] ;
memmove ( nb - > mesh , batch - > mesh + j , sizeof ( msurface_t * ) * nb - > maxmeshes ) ;
for ( i = 0 ; i < nb - > maxmeshes ; i + + )
{
surf = ( msurface_t * ) nb - > mesh [ i ] ;
surf - > sbatch = nb ;
}
batch = nb ;
j = 0 ;
}
}
}
2013-07-14 12:22:51 +00:00
Mod_LightmapAllocDone ( & lmallocator , mod ) ;
2012-07-05 19:42:36 +00:00
}
extern void Surf_CreateSurfaceLightmap ( msurface_t * surf , int shift ) ;
//if build is NULL, uses q1/q2 surf generation, and allocates lightmaps
2014-10-05 20:04:11 +00:00
void Mod_Batches_Build ( model_t * mod , builddata_t * bd )
2012-07-05 19:42:36 +00:00
{
int i ;
int numverts = 0 , numindicies = 0 ;
msurface_t * surf ;
mesh_t * mesh ;
mesh_t * * bmeshes ;
int sortid ;
batch_t * batch ;
2014-10-05 20:04:11 +00:00
mesh_t * meshlist ;
2012-07-05 19:42:36 +00:00
currentmodel = mod ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
if ( ! mod - > textures )
return ;
2014-10-05 20:04:11 +00:00
if ( bd )
meshlist = NULL ;
else
meshlist = ZG_Malloc ( & mod - > memgroup , sizeof ( mesh_t ) * mod - > nummodelsurfaces ) ;
2012-07-05 19:42:36 +00:00
for ( i = 0 ; i < mod - > nummodelsurfaces ; i + + )
{
surf = mod - > surfaces + i + mod - > firstmodelsurface ;
if ( meshlist )
{
mesh = surf - > mesh = & meshlist [ i ] ;
mesh - > numvertexes = surf - > numedges ;
mesh - > numindexes = ( surf - > numedges - 2 ) * 3 ;
}
else
mesh = surf - > mesh ;
numverts + = mesh - > numvertexes ;
numindicies + = mesh - > numindexes ;
// surf->lightmaptexturenum = -1;
}
/*assign each mesh to a batch, generating as needed*/
2013-07-14 12:22:51 +00:00
Mod_Batches_Generate ( mod ) ;
2012-07-05 19:42:36 +00:00
2014-10-05 20:04:11 +00:00
bmeshes = ZG_Malloc ( & mod - > memgroup , sizeof ( * bmeshes ) * mod - > nummodelsurfaces * R_MAX_RECURSE ) ;
2012-07-05 19:42:36 +00:00
//we now know which batch each surface is in, and how many meshes there are in each batch.
//allocate the mesh-pointer-lists for each batch. *2 for recursion.
for ( i = 0 , sortid = 0 ; sortid < SHADER_SORT_COUNT ; sortid + + )
for ( batch = mod - > batches [ sortid ] ; batch ! = NULL ; batch = batch - > next )
{
batch - > mesh = bmeshes + i ;
2013-12-29 22:48:28 +00:00
i + = batch - > maxmeshes * R_MAX_RECURSE ;
2012-07-05 19:42:36 +00:00
}
//store the *surface* into the batch's mesh list (yes, this is an evil cast hack, but at least both are pointers)
for ( i = 0 ; i < mod - > nummodelsurfaces ; i + + )
{
surf = mod - > surfaces + mod - > firstmodelsurface + i ;
surf - > sbatch - > mesh [ surf - > sbatch - > meshes + + ] = ( mesh_t * ) surf ;
}
2014-10-05 20:04:11 +00:00
if ( bd ) //q3
2013-07-14 12:22:51 +00:00
Mod_Batches_SplitLightmaps ( mod ) ;
2012-07-05 19:42:36 +00:00
else
2013-07-14 12:22:51 +00:00
Mod_Batches_AllocLightmaps ( mod ) ;
2012-07-05 19:42:36 +00:00
2014-10-05 20:04:11 +00:00
if ( ! bd )
2013-05-03 04:28:08 +00:00
{
mod - > lightmaps . surfstyles = 1 ;
2014-10-05 20:04:11 +00:00
Mod_Batches_BuildModelMeshes ( mod , numverts , numindicies , ModQ1_Batches_BuildQ1Q2Poly , bd ) ;
2013-05-03 04:28:08 +00:00
}
2014-10-05 20:04:11 +00:00
else
Mod_Batches_BuildModelMeshes ( mod , numverts , numindicies , bd - > buildfunc , bd ) ;
2012-07-05 19:42:36 +00:00
if ( BE_GenBrushModelVBO )
BE_GenBrushModelVBO ( mod ) ;
}
2014-05-10 13:42:13 +00:00
# endif
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_SetParent
= = = = = = = = = = = = = = = = =
*/
2013-07-14 12:22:51 +00:00
void Mod_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 ;
2013-07-14 12:22:51 +00:00
Mod_SetParent ( node - > children [ 0 ] , node ) ;
Mod_SetParent ( node - > children [ 1 ] , node ) ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadNodes
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
static qboolean Mod_LoadNodes ( model_t * loadmodel , qbyte * mod_base , lump_t * l , int lm )
2004-08-22 22:29:09 +00:00
{
int i , j , count , p ;
mnode_t * out ;
2012-09-30 05:52:03 +00:00
if ( lm = = 2 )
{
dl2node_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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2012-09-30 05:52:03 +00:00
loadmodel - > nodes = out ;
loadmodel - > numnodes = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
out - > minmaxs [ j ] = LittleFloat ( in - > mins [ j ] ) ;
out - > minmaxs [ 3 + j ] = LittleFloat ( 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 + + )
{
p = LittleLong ( in - > children [ j ] ) ;
if ( p > = 0 )
out - > children [ j ] = loadmodel - > nodes + p ;
else
out - > children [ j ] = ( mnode_t * ) ( loadmodel - > leafs + ( - 1 - p ) ) ;
}
}
}
else if ( lm )
2006-03-12 22:01:49 +00:00
{
2012-09-30 05:52:03 +00:00
dl1node_t * in ;
2011-10-27 16:16:29 +00:00
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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
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 ;
2012-09-30 05:52:03 +00:00
out - > firstsurface = ( unsigned short ) LittleShort ( in - > firstface ) ;
out - > numsurfaces = ( unsigned short ) LittleShort ( in - > numfaces ) ;
2011-10-27 16:16:29 +00:00
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
}
}
2013-07-14 12:22:51 +00:00
Mod_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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
static qboolean Mod_LoadLeafs ( model_t * loadmodel , qbyte * mod_base , lump_t * l , int lm , qbyte * ptr , size_t len )
2004-08-22 22:29:09 +00:00
{
mleaf_t * out ;
int i , j , count , p ;
2014-09-08 23:47:19 +00:00
if ( ! ptr )
{
ptr = mod_base + l - > fileofs ;
len = l - > filelen ;
}
2012-09-30 05:52:03 +00:00
if ( lm = = 2 )
2006-03-12 22:01:49 +00:00
{
2012-09-30 05:52:03 +00:00
dl2leaf_t * in ;
2014-09-08 23:47:19 +00:00
in = ( void * ) ptr ;
if ( len % sizeof ( * in ) )
2012-09-30 05:52:03 +00:00
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
2014-09-08 23:47:19 +00:00
count = len / sizeof ( * in ) ;
2013-12-29 22:48:28 +00:00
if ( count > MAX_MAP_LEAFS )
{
Con_Printf ( CON_ERROR " Mod_LoadLeafs: %s has more than %i leafs \n " , loadmodel - > name , MAX_MAP_LEAFS ) ;
return false ;
}
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2012-09-30 05:52:03 +00:00
loadmodel - > leafs = out ;
loadmodel - > numleafs = count ;
2014-05-23 02:02:51 +00:00
loadmodel - > numclusters = count - 1 ;
2012-09-30 05:52:03 +00:00
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
out - > minmaxs [ j ] = LittleFloat ( in - > mins [ j ] ) ;
out - > minmaxs [ 3 + j ] = LittleFloat ( 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 if ( lm )
{
dl1leaf_t * in ;
2014-09-08 23:47:19 +00:00
in = ( void * ) ( ptr ) ;
if ( len % sizeof ( * in ) )
2011-10-27 16:16:29 +00:00
{
Con_Printf ( CON_ERROR " MOD_LoadBmodel: funny lump size in %s \n " , loadmodel - > name ) ;
return false ;
}
2014-09-08 23:47:19 +00:00
count = len / sizeof ( * in ) ;
2013-12-29 22:48:28 +00:00
if ( count > MAX_MAP_LEAFS )
{
Con_Printf ( CON_ERROR " Mod_LoadLeafs: %s has more than %i leafs \n " , loadmodel - > name , MAX_MAP_LEAFS ) ;
return false ;
}
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
loadmodel - > leafs = out ;
loadmodel - > numleafs = count ;
2014-05-23 02:02:51 +00:00
loadmodel - > numclusters = count - 1 ;
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 ;
2014-09-08 23:47:19 +00:00
in = ( void * ) ( ptr ) ;
if ( len % 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
}
2014-09-08 23:47:19 +00:00
count = len / sizeof ( * in ) ;
2013-12-29 22:48:28 +00:00
if ( count > MAX_MAP_LEAFS )
{
Con_Printf ( CON_ERROR " Mod_LoadLeafs: %s has more than %i leafs \n " , loadmodel - > name , MAX_MAP_LEAFS ) ;
return false ;
}
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
loadmodel - > leafs = out ;
loadmodel - > numleafs = count ;
2014-05-23 02:02:51 +00:00
loadmodel - > numclusters = count - 1 ;
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 ;
2014-10-05 20:04:11 +00:00
void Mod_LoadCrouchHull ( model_t * loadmodel )
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadClipnodes ( model_t * loadmodel , qbyte * mod_base , 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
}
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , ( count + numsuplementryclipnodes ) * sizeof ( * out ) ) ; //space for both
2004-08-22 22:29:09 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
void Mod_MakeHull0 ( model_t * loadmodel )
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 ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadMarksurfaces ( model_t * loadmodel , qbyte * mod_base , 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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2011-12-05 15:23:40 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadSurfedges ( model_t * loadmodel , qbyte * mod_base , 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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , count * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
qboolean Mod_LoadPlanes ( model_t * loadmodel , qbyte * mod_base , 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 ) ;
2013-07-14 12:22:51 +00:00
out = ZG_Malloc ( & loadmodel - > memgroup , ( count + numsuplementryplanes ) * 2 * sizeof ( * out ) ) ;
2004-08-22 22:29:09 +00:00
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
}
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2004-08-22 22:29:09 +00:00
//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 ) ;
}
2014-05-10 13:42:13 +00:00
# endif
2004-08-22 22:29:09 +00:00
2013-07-14 12:22:51 +00:00
void Mod_FixupNodeMinsMaxs ( mnode_t * node , mnode_t * parent )
2007-05-25 22:16:29 +00:00
{
if ( ! node )
return ;
if ( node - > contents > = 0 )
{
2013-07-14 12:22:51 +00:00
Mod_FixupNodeMinsMaxs ( node - > children [ 0 ] , node ) ;
Mod_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 ] ;
}
}
2014-05-10 13:42:13 +00:00
2014-10-05 20:04:11 +00:00
static void Mod_FixupMinsMaxs ( model_t * loadmodel )
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 + + )
{
2014-05-10 13:42:13 +00:00
lindex = loadmodel - > surfedges [ surf - > firstedge + en ] ;
2007-05-25 22:16:29 +00:00
if ( lindex > 0 )
{
e = & pedges [ lindex ] ;
2014-05-10 13:42:13 +00:00
v = loadmodel - > vertexes [ e - > v [ 0 ] ] . position ;
2007-05-25 22:16:29 +00:00
}
else
{
e = & pedges [ - lindex ] ;
2014-05-10 13:42:13 +00:00
v = loadmodel - > vertexes [ e - > v [ 1 ] ] . position ;
2007-05-25 22:16:29 +00:00
}
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 ) ;
}
}
2013-07-14 12:22:51 +00:00
Mod_FixupNodeMinsMaxs ( loadmodel - > nodes , NULL ) ; // sets nodes and leafs
2007-05-25 22:16:29 +00:00
}
2014-10-05 20:04:11 +00:00
void ModBrush_LoadGLStuff ( void * ctx , void * data , size_t a , size_t b )
{
# ifndef SERVERONLY
model_t * mod = ctx ;
if ( ! a )
{ //submodels share textures, so only do this if 'a' is 0 (inline index, 0 = world).
for ( a = 0 ; a < mod - > numfogs ; a + + )
{
mod - > fogs [ a ] . shader = R_RegisterShader_Lightmap ( mod - > fogs [ a ] . shadername ) ;
R_BuildDefaultTexnums ( & mod - > fogs [ a ] . shader - > defaulttextures , mod - > fogs [ a ] . shader ) ;
if ( ! mod - > fogs [ a ] . shader - > fog_dist )
{
//invalid fog shader, don't use.
mod - > fogs [ a ] . shader = NULL ;
mod - > fogs [ a ] . numplanes = 0 ;
}
}
if ( mod - > fromgame = = fg_quake3 )
{
for ( a = 0 ; a < mod - > numtexinfo ; a + + )
{
mod - > textures [ a ] - > shader = R_RegisterShader_Lightmap ( mod - > textures [ a ] - > name ) ;
R_BuildDefaultTexnums ( & mod - > textures [ a ] - > texnums , mod - > textures [ a ] - > shader ) ;
mod - > textures [ a + mod - > numtexinfo ] - > shader = R_RegisterShader_Vertex ( mod - > textures [ a + mod - > numtexinfo ] - > name ) ;
R_BuildDefaultTexnums ( & mod - > textures [ a + mod - > numtexinfo ] - > texnums , mod - > textures [ a + mod - > numtexinfo ] - > shader ) ;
}
mod - > textures [ 2 * mod - > numtexinfo ] - > shader = R_RegisterShader_Flare ( " noshader " ) ;
}
else if ( mod - > fromgame = = fg_quake2 )
{
for ( a = 0 ; a < mod - > numtextures ; a + + )
{
mod - > textures [ a ] - > shader = R_RegisterCustom ( mod - > textures [ a ] - > name , SUF_LIGHTMAP , Shader_DefaultBSPQ2 , NULL ) ;
R_BuildDefaultTexnums ( & mod - > textures [ a ] - > texnums , mod - > textures [ a ] - > shader ) ;
}
}
else
{
for ( a = 0 ; a < mod - > numtextures ; a + + )
Mod_FinishTexture ( mod - > textures [ a ] ) ;
}
}
Mod_Batches_Build ( mod , data ) ;
if ( data )
BZ_Free ( data ) ;
# endif
}
2014-09-08 23:47:19 +00:00
struct vispatch_s
{
void * fileptr ;
size_t filelen ;
void * visptr ;
int vislen ;
void * leafptr ;
int leaflen ;
} ;
2014-10-05 20:04:11 +00:00
static void Mod_FindVisPatch ( struct vispatch_s * patch , model_t * mod , size_t leaflumpsize )
2014-09-08 23:47:19 +00:00
{
char patchname [ MAX_QPATH ] ;
int * lenptr , len ;
int ofs ;
qbyte * file ;
memset ( patch , 0 , sizeof ( * patch ) ) ;
if ( ! mod_external_vis . ival )
return ;
COM_StripExtension ( mod - > name , patchname , sizeof ( patchname ) ) ;
Q_strncatz ( patchname , " .vis " , sizeof ( patchname ) ) ;
//ignore the patch file if its in a different gamedir.
//this file format sucks too much for other verification.
if ( FS_FLocateFile ( mod - > name , FSLFRT_DEPTH_OSONLY , NULL ) ! = FS_FLocateFile ( patchname , FSLFRT_DEPTH_OSONLY , NULL ) )
return ;
patch - > filelen = FS_LoadFile ( patchname , & patch - > fileptr ) ;
if ( ! patch - > fileptr )
return ;
ofs = 0 ;
while ( ofs + 36 < = patch - > filelen )
{
file = patch - > fileptr ;
file + = ofs ;
memcpy ( patchname , file , 32 ) ;
patchname [ 32 ] = 0 ;
file + = 32 ;
lenptr = ( int * ) file ;
file + = sizeof ( int ) ;
len = LittleLong ( * lenptr ) ;
if ( ofs + 36 + len > patch - > filelen )
break ;
// if (!Q_strcasecmp(patchname, "foo"))
{
lenptr = ( int * ) file ;
patch - > vislen = LittleLong ( * lenptr ) ;
file + = sizeof ( int ) ;
patch - > visptr = file ;
file + = patch - > vislen ;
lenptr = ( int * ) file ;
patch - > leaflen = LittleLong ( * lenptr ) ;
file + = sizeof ( int ) ;
patch - > leafptr = file ;
file + = patch - > leaflen ;
if ( sizeof ( int ) * 2 + patch - > vislen + patch - > leaflen ! = len | | patch - > leaflen ! = leaflumpsize )
{
Con_Printf ( " Vis patch is unsuitable \n " ) ;
patch - > visptr = NULL ;
patch - > leafptr = NULL ;
}
}
ofs + = 36 + len ;
}
}
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_LoadBrushModel
= = = = = = = = = = = = = = = = =
*/
2014-03-30 08:55:06 +00:00
qboolean QDECL Mod_LoadBrushModel ( model_t * mod , void * buffer , size_t fsize )
2004-08-22 22:29:09 +00:00
{
2014-09-08 23:47:19 +00:00
struct vispatch_s vispatch ;
2004-08-22 22:29:09 +00:00
int i , j ;
dheader_t * header ;
mmodel_t * bm ;
2014-10-05 20:04:11 +00:00
model_t * submod ;
2006-02-22 23:50:12 +00:00
unsigned int chksum ;
2006-03-12 22:01:49 +00:00
qboolean noerrors ;
2012-09-30 05:52:03 +00:00
int longm = false ;
2014-10-05 20:04:11 +00:00
char loadname [ 32 ] ;
qbyte * mod_base = buffer ;
2009-11-15 03:20:17 +00:00
# if (defined(ODE_STATIC) || defined(ODE_DYNAMIC))
qboolean ode = true ;
# else
# define ode true
# endif
2006-03-12 22:01:49 +00:00
2014-10-05 20:04:11 +00:00
COM_FileBase ( mod - > name , loadname , sizeof ( loadname ) ) ;
mod - > type = mod_brush ;
2004-08-22 22:29:09 +00:00
header = ( dheader_t * ) buffer ;
2014-05-10 13:42:13 +00:00
# ifdef SERVERONLY
isnotmap = ! ! sv . world . worldmodel ;
# else
2004-08-22 22:29:09 +00:00
if ( ( ! cl . worldmodel & & cls . state > = ca_connected )
# ifndef CLIENTONLY
2014-10-05 20:04:11 +00:00
| | ( ! sv . world . worldmodel & & sv . state )
2004-08-22 22:29:09 +00:00
# endif
)
isnotmap = false ;
else
isnotmap = true ;
2014-05-10 13:42:13 +00:00
# endif
2004-08-22 22:29:09 +00:00
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
{
2014-10-05 20:04:11 +00:00
mod - > fromgame = fg_quake ;
mod - > engineflags | = MDLF_NEEDOVERBRIGHT ;
2006-04-16 06:03:58 +00:00
}
2012-09-30 05:52:03 +00:00
else if ( i = = BSPVERSION_LONG1 )
2011-10-27 16:16:29 +00:00
{
longm = true ;
2014-10-05 20:04:11 +00:00
mod - > fromgame = fg_quake ;
mod - > engineflags | = MDLF_NEEDOVERBRIGHT ;
2011-10-27 16:16:29 +00:00
}
2012-09-30 05:52:03 +00:00
else if ( i = = BSPVERSION_LONG2 )
{
longm = 2 ;
2014-10-05 20:04:11 +00:00
mod - > fromgame = fg_quake ;
mod - > engineflags | = MDLF_NEEDOVERBRIGHT ;
2012-09-30 05:52:03 +00:00
}
2004-08-22 22:29:09 +00:00
else if ( i = = BSPVERSIONHL ) //halflife support
2014-10-05 20:04:11 +00:00
mod - > fromgame = fg_halflife ;
2004-08-22 22:29:09 +00:00
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
2012-07-05 19:42:36 +00:00
mod - > lightmaps . width = LMBLOCK_WIDTH ;
mod - > lightmaps . height = LMBLOCK_HEIGHT ;
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 ] ) ;
2014-10-05 20:04:11 +00:00
Q1BSPX_Setup ( mod , mod_base , fsize , header - > lumps , HEADER_LUMPS ) ;
2004-08-22 22:29:09 +00:00
// 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 + + )
{
2014-10-05 20:04:11 +00:00
if ( ( unsigned ) header - > lumps [ i ] . fileofs + ( unsigned ) header - > lumps [ i ] . filelen > fsize )
2006-10-05 21:12:04 +00:00
{
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 ;
2014-10-05 20:04:11 +00:00
Mod_FindVisPatch ( & vispatch , mod , header - > lumps [ LUMP_LEAFS ] . filelen ) ;
2014-09-08 23:47:19 +00:00
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading info \n " ) ) ;
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
if ( ! isnotmap )
2014-10-05 20:04:11 +00:00
Mod_ParseInfoFromEntityLump ( mod , mod_base + header - > lumps [ LUMP_ENTITIES ] . fileofs , loadname ) ;
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
# endif
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
{
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading verts \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadVertexes ( mod , mod_base , & header - > lumps [ LUMP_VERTEXES ] ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading edges \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadEdges ( mod , mod_base , & header - > lumps [ LUMP_EDGES ] , longm ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Surfedges \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadSurfedges ( mod , mod_base , & header - > lumps [ LUMP_SURFEDGES ] ) ;
2009-11-15 03:20:17 +00:00
}
if ( ! isDedicated )
{
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Textures \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadTextures ( mod , mod_base , & header - > lumps [ LUMP_TEXTURES ] , loadname ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Lighting \n " ) ) ;
2006-03-12 22:01:49 +00:00
if ( noerrors )
2014-10-05 20:04:11 +00:00
Mod_LoadLighting ( mod , mod_base , & header - > lumps [ LUMP_LIGHTING ] ) ;
2006-03-12 22:01:49 +00:00
}
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Submodels \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadSubmodels ( mod , mod_base , & header - > lumps [ LUMP_MODELS ] ) ;
2006-03-12 22:01:49 +00:00
if ( noerrors )
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
{
TRACE ( ( " Loading CH \n " ) ) ;
2014-10-05 20:04:11 +00:00
Mod_LoadCrouchHull ( mod ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
}
TRACE ( ( " Loading Planes \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadPlanes ( mod , mod_base , & header - > lumps [ LUMP_PLANES ] ) ;
2009-11-15 03:20:17 +00:00
if ( ! isDedicated | | ode )
2004-08-22 22:29:09 +00:00
{
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Texinfo \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadTexinfo ( mod , mod_base , & header - > lumps [ LUMP_TEXINFO ] ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Faces \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadFaces ( mod , mod_base , & header - > lumps [ LUMP_FACES ] , longm ) ;
2009-11-15 03:20:17 +00:00
}
if ( ! isDedicated )
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
{
TRACE ( ( " Loading MarkSurfaces \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadMarksurfaces ( mod , mod_base , & header - > lumps [ LUMP_MARKSURFACES ] , longm ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
}
2006-03-12 22:01:49 +00:00
if ( noerrors )
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
{
TRACE ( ( " Loading Vis \n " ) ) ;
2014-10-05 20:04:11 +00:00
Mod_LoadVisibility ( mod , mod_base , & header - > lumps [ LUMP_VISIBILITY ] , vispatch . visptr , vispatch . vislen ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
}
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadLeafs ( mod , mod_base , & header - > lumps [ LUMP_LEAFS ] , longm , vispatch . leafptr , vispatch . leaflen ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Nodes \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadNodes ( mod , mod_base , & header - > lumps [ LUMP_NODES ] , longm ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Clipnodes \n " ) ) ;
2014-10-05 20:04:11 +00:00
noerrors = noerrors & & Mod_LoadClipnodes ( mod , mod_base , & header - > lumps [ LUMP_CLIPNODES ] , longm ) ;
2006-03-12 22:01:49 +00:00
if ( noerrors )
{
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading Entities \n " ) ) ;
2014-10-05 20:04:11 +00:00
Mod_LoadEntities ( mod , mod_base , & header - > lumps [ LUMP_ENTITIES ] ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " Loading hull 0 \n " ) ) ;
2014-10-05 20:04:11 +00:00
Mod_MakeHull0 ( mod ) ;
2006-03-12 22:01:49 +00:00
}
2004-08-22 22:29:09 +00:00
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " sorting shaders \n " ) ) ;
2010-07-11 02:22:39 +00:00
if ( ! isDedicated & & noerrors )
2014-10-05 20:04:11 +00:00
Mod_SortShaders ( mod ) ;
2010-07-11 02:22:39 +00:00
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 ;
}
2014-09-08 23:47:19 +00:00
BZ_Free ( vispatch . fileptr ) ;
2006-03-12 22:01:49 +00:00
if ( ! noerrors )
{
return false ;
}
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2012-02-27 12:23:15 +00:00
Q1BSP_LoadBrushes ( mod ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2005-08-26 22:56:51 +00:00
Q1BSP_SetModelFuncs ( mod ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2014-05-10 13:42:13 +00:00
# ifndef SERVERONLY
2004-08-22 22:29:09 +00:00
mod - > funcs . LightPointValues = GLQ1BSP_LightPointValues ;
mod - > funcs . MarkLights = Q1BSP_MarkLights ;
2014-05-10 13:42:13 +00:00
mod - > funcs . StainNode = Q1BSP_StainNode ;
# endif
2004-08-22 22:29:09 +00:00
mod - > numframes = 2 ; // regular and alternate animation
2009-11-15 03:20:17 +00:00
2004-08-22 22:29:09 +00:00
//
// set up the submodels (FIXME: this is confusing)
//
2014-10-05 20:04:11 +00:00
for ( i = 0 , submod = mod ; i < mod - > numsubmodels ; i + + )
2004-08-22 22:29:09 +00:00
{
bm = & mod - > submodels [ i ] ;
2014-10-05 20:04:11 +00:00
submod - > rootnode = submod - > nodes + bm - > headnode [ 0 ] ;
submod - > hulls [ 0 ] . firstclipnode = bm - > headnode [ 0 ] ;
submod - > hulls [ 0 ] . available = true ;
Q1BSP_CheckHullNodes ( & submod - > hulls [ 0 ] ) ;
2010-07-12 22:46:37 +00:00
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2004-08-22 22:29:09 +00:00
for ( j = 1 ; j < MAX_MAP_HULLSM ; j + + )
{
2014-10-05 20:04:11 +00:00
submod - > hulls [ j ] . firstclipnode = bm - > headnode [ j ] ;
submod - > hulls [ j ] . lastclipnode = submod - > numclipnodes - 1 ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
submod - > hulls [ j ] . available & = bm - > hullavailable [ j ] ;
if ( submod - > hulls [ j ] . firstclipnode > submod - > hulls [ j ] . lastclipnode )
submod - > hulls [ j ] . available = false ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
if ( submod - > hulls [ j ] . available )
Q1BSP_CheckHullNodes ( & submod - > hulls [ j ] ) ;
2004-08-22 22:29:09 +00:00
}
2014-10-05 20:04:11 +00:00
submod - > firstmodelsurface = bm - > firstface ;
submod - > nummodelsurfaces = bm - > numfaces ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
VectorCopy ( bm - > maxs , submod - > maxs ) ;
VectorCopy ( bm - > mins , submod - > mins ) ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
submod - > radius = RadiusFromBounds ( submod - > mins , submod - > maxs ) ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
submod - > numclusters = bm - > visleafs ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
memset ( & submod - > batches , 0 , sizeof ( submod - > batches ) ) ;
submod - > vbos = NULL ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2014-10-05 20:04:11 +00:00
if ( ! isDedicated | | ode )
2012-07-05 19:42:36 +00:00
{
2014-10-05 20:04:11 +00:00
COM_AddWork ( 0 , ModBrush_LoadGLStuff , submod , NULL , i , 0 ) ;
2012-07-05 19:42:36 +00:00
}
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2012-07-05 19:42:36 +00:00
2014-10-05 20:04:11 +00:00
if ( i )
COM_AddWork ( 0 , Mod_ModelLoaded , submod , NULL , MLS_LOADED , 0 ) ;
if ( i < submod - > numsubmodels - 1 )
2004-08-22 22:29:09 +00:00
{ // duplicate the basic information
2014-10-05 20:04:11 +00:00
char name [ MAX_QPATH ] ;
model_t * nextmod ;
// if (isnotmap)
Q_snprintfz ( name , sizeof ( name ) , " *%i:%s " , i + 1 , mod - > name ) ;
// else//FIXME: this can bug out if we've still got one of these queued from a previous map change
// Q_snprintfz (name, sizeof(name), "*%i", i+1);
nextmod = Mod_FindName ( name ) ;
* nextmod = * submod ;
Q_strncpyz ( nextmod - > name , name , sizeof ( nextmod - > name ) ) ;
submod = nextmod ;
memset ( & submod - > memgroup , 0 , sizeof ( submod - > memgroup ) ) ;
2004-08-22 22:29:09 +00:00
}
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2004-08-22 22:29:09 +00:00
}
# ifdef RUNTIMELIGHTING
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2014-10-05 20:04:11 +00:00
if ( lightmodel = = mod )
2004-08-22 22:29:09 +00:00
LightLoadEntities ( lightmodel - > entities ) ;
# endif
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2014-05-20 02:23:37 +00:00
if ( ! isDedicated )
2014-10-05 20:04:11 +00:00
Mod_FixupMinsMaxs ( mod ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " LoadBrushModel %i \n " , __LINE__ ) ) ;
2007-05-25 22:16:29 +00:00
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
# ifdef TERRAIN
2014-10-05 20:04:11 +00:00
mod - > terrain = Mod_LoadTerrainInfo ( mod , loadname , false ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
# endif
2006-03-12 22:01:49 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2014-10-05 20:04:11 +00:00
SPRITES
2004-08-22 22:29:09 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
//=========================================================
2014-10-05 20:04:11 +00:00
//we need to override the rtlight shader for sprites so they get lit properly ignoring n+s+t dirs
//so lets split the shader into parts to avoid too many dupes
# define SPRITE_SHADER_MAIN \
" { \n " \
" if gl_blendsprites \n " \
" program defaultsprite \n " \
" else \n " \
" program defaultsprite#MASK=1 \n " \
" endif \n " \
" { \n " \
" map $diffuse \n " \
" if gl_blendsprites \n " \
" blendfunc GL_SRC_ALPHA GL_ONE \n " \
" else \n " \
" alphafunc ge128 \n " \
" depthwrite \n " \
" endif \n " \
" rgbgen vertex \n " \
" alphagen vertex \n " \
" } \n " \
" surfaceparm noshadows \n "
# define SPRITE_SHADER_UNLIT "surfaceparm nodlight\n"
# define SPRITE_SHADER_LIT \
" sort seethrough \n " \
" bemode rtlight \n " \
" { \n " \
" program rtlight#NOBUMP \n " \
" { \n " \
" map $diffuse \n " \
" blendfunc add \n " \
" } \n " \
" { \n " \
" map $null \n " /*normalmap*/ \
" } \n " \
" { \n " \
" map $null \n " /*specular*/ \
" } \n " \
" { \n " \
" map $lightcubemap \n " \
" } \n " \
" { \n " \
" map $shadowmap \n " \
" } \n " \
" { \n " \
" map $null \n " /*lower*/ \
" } \n " \
" { \n " \
" map $null \n " /*upper*/ \
" } \n " \
" } \n "
# define SPRITE_SHADER_FOOTER "}\n"
void Mod_LoadSpriteFrameShader ( model_t * spr , int frame , int subframe , mspriteframe_t * frameinfo )
{
# ifndef SERVERONLY
/*
A quick note on tenebrae and sprites : In tenebrae , sprites are always lit , unless the light_lev field is set ( which makes it fullbright ) .
While its generally preferable and more consistent to assume lit sprites , this is incompatible with vanilla quake and thus unacceptable to us , but you can set the mod_assumelitsprites cvar if you want it .
So for better compatibility , we have a whitelist of ' well - known ' sprites that tenebrae uses in this way , which we do lighting on .
You should still be able to use EF_FULLBRIGHT on these , but light_lev is an imprecise setting and will result in issues . Just be specific about fullbright or additive .
DP on the other hand , supports lit sprites only when the sprite contains a ! in its name . We support that too .
*/
char * forcelitsprites [ ] =
{
" progs/smokepuff.spr " ,
NULL
} ;
int i ;
char * shadertext ;
char name [ MAX_QPATH ] ;
if ( qrenderer = = QR_NONE )
return ;
if ( subframe = = - 1 )
Q_snprintfz ( name , sizeof ( name ) , " %s_%i.tga " , spr - > name , frame ) ;
else
Q_snprintfz ( name , sizeof ( name ) , " %s_%i_%i.tga " , spr - > name , frame , subframe ) ;
if ( mod_litsprites . ival | | strchr ( spr - > name , ' ! ' ) )
i = - 1 ;
else
{
for ( i = 0 ; forcelitsprites [ i ] ; i + + )
if ( ! strcmp ( spr - > name , forcelitsprites [ i ] ) )
{
i = - 1 ;
break ;
}
}
if ( i = = - 1 ) // a ! in the filename makes it non-fullbright (and can also be lit by rtlights too).
shadertext = SPRITE_SHADER_MAIN SPRITE_SHADER_LIT SPRITE_SHADER_FOOTER ;
else
shadertext = SPRITE_SHADER_MAIN SPRITE_SHADER_UNLIT SPRITE_SHADER_FOOTER ;
frameinfo - > shader = R_RegisterShader ( name , SUF_NONE , shadertext ) ;
frameinfo - > shader - > defaulttextures . base = frameinfo - > image ;
frameinfo - > shader - > width = frameinfo - > right - frameinfo - > left ;
frameinfo - > shader - > height = frameinfo - > up - frameinfo - > down ;
# endif
}
void Mod_LoadSpriteShaders ( model_t * spr )
{
msprite_t * psprite = spr - > meshinfo ;
int i , j ;
mspritegroup_t * group ;
for ( i = 0 ; i < psprite - > numframes ; i + + )
{
switch ( psprite - > frames [ i ] . type )
{
case SPR_SINGLE :
Mod_LoadSpriteFrameShader ( spr , i , - 1 , psprite - > frames [ i ] . frameptr ) ;
break ;
case SPR_ANGLED :
case SPR_GROUP :
group = ( mspritegroup_t * ) psprite - > frames [ i ] . frameptr ;
for ( j = 0 ; j < group - > numframes ; j + + )
Mod_LoadSpriteFrameShader ( spr , i , j , group - > frames [ j ] ) ;
break ;
}
}
}
2014-05-10 13:42:13 +00:00
# ifdef SPRMODELS
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteFrame
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
static void * Mod_LoadSpriteFrame ( model_t * mod , void * pin , void * pend , 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 ] ;
2014-10-05 20:04:11 +00:00
uploadfmt_t lowresfmt ;
void * dataptr ;
2004-08-22 22:29:09 +00:00
pinframe = ( dspriteframe_t * ) pin ;
width = LittleLong ( pinframe - > width ) ;
height = LittleLong ( pinframe - > height ) ;
size = width * height ;
2014-10-05 20:04:11 +00:00
pspriteframe = ZG_Malloc ( & mod - > memgroup , sizeof ( mspriteframe_t ) ) ;
2004-08-22 22:29:09 +00:00
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 ] ;
2014-10-05 20:04:11 +00:00
dataptr = ( pinframe + 1 ) ;
2005-05-13 10:42:48 +00:00
2004-08-22 22:29:09 +00:00
if ( version = = SPRITE32_VERSION )
{
size * = 4 ;
2014-10-05 20:04:11 +00:00
lowresfmt = TF_RGBA32 ;
2005-05-13 10:42:48 +00:00
}
else if ( version = = SPRITEHL_VERSION )
2014-10-05 20:04:11 +00:00
lowresfmt = TF_8PAL32 ;
2005-05-13 10:42:48 +00:00
else
2014-10-05 20:04:11 +00:00
lowresfmt = TF_TRANS8 ;
if ( ( qbyte * ) dataptr + size > ( qbyte * ) pend )
2005-05-13 10:42:48 +00:00
{
2014-10-05 20:04:11 +00:00
//tenebrae has a couple of dodgy truncated sprites. yay for replacement textures.
dataptr = NULL ;
lowresfmt = TF_INVALID ;
}
Q_snprintfz ( name , sizeof ( name ) , " %s_%i.tga " , mod - > name , framenum ) ;
pspriteframe - > image = Image_GetTexture ( name , " sprites " , IF_NOMIPMAP | IF_NOGAMMA | IF_CLAMP , dataptr , palette , width , height , lowresfmt ) ;
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
= = = = = = = = = = = = = = = = =
*/
2014-10-05 20:04:11 +00:00
static void * Mod_LoadSpriteGroup ( model_t * mod , void * pin , void * pend , 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 ) ;
2014-10-05 20:04:11 +00:00
pspritegroup = ZG_Malloc ( & mod - > memgroup , sizeof ( mspritegroup_t ) + ( numframes - 1 ) * sizeof ( pspritegroup - > frames [ 0 ] ) ) ;
2004-08-22 22:29:09 +00:00
pspritegroup - > numframes = numframes ;
* ppframe = ( mspriteframe_t * ) pspritegroup ;
pin_intervals = ( dspriteinterval_t * ) ( pingroup + 1 ) ;
2014-10-05 20:04:11 +00:00
poutintervals = ZG_Malloc ( & mod - > memgroup , numframes * sizeof ( float ) ) ;
2004-08-22 22:29:09 +00:00
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 + + )
{
2014-10-05 20:04:11 +00:00
ptemp = Mod_LoadSpriteFrame ( mod , ptemp , pend , & pspritegroup - > frames [ i ] , framenum * 100 + i , version , palette ) ;
2004-08-22 22:29:09 +00:00
}
return ptemp ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteModel
= = = = = = = = = = = = = = = = =
*/
2014-03-30 08:55:06 +00:00
qboolean QDECL Mod_LoadSpriteModel ( model_t * mod , void * buffer , size_t fsize )
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 ;
2013-12-29 22:48:28 +00:00
int rendertype = SPRHL_ALPHATEST ;
2005-05-13 10:42:48 +00:00
unsigned char pal [ 256 * 4 ] ;
int sptype ;
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 ) ;
2013-12-29 22:48:28 +00:00
rendertype = LittleLong ( pin - > type ) ; //not sure what the values mean.
2005-05-13 10:42:48 +00:00
}
2004-08-22 22:29:09 +00:00
numframes = LittleLong ( pin - > numframes ) ;
size = sizeof ( msprite_t ) + ( numframes - 1 ) * sizeof ( psprite - > frames ) ;
2014-10-05 20:04:11 +00:00
psprite = ZG_Malloc ( & mod - > memgroup , size ) ;
2004-08-22 22:29:09 +00:00
2013-07-14 12:22:51 +00:00
mod - > meshinfo = psprite ;
2013-12-29 22:48:28 +00:00
switch ( sptype )
{
case SPR_VP_PARALLEL_UPRIGHT :
case SPR_FACING_UPRIGHT :
case SPR_VP_PARALLEL :
case SPR_ORIENTED :
// case SPR_VP_PARALLEL_ORIENTED:
// case SPRDP_LABEL:
// case SPRDP_LABEL_SCALE:
// case SPRDP_OVERHEAD:
break ;
default :
Con_DPrintf ( CON_ERROR " %s has unsupported sprite type %i \n " , mod - > name , sptype ) ;
sptype = SPR_VP_PARALLEL ;
break ;
}
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
return false ;
}
2005-05-13 10:42:48 +00:00
2013-12-29 22:48:28 +00:00
if ( rendertype = = SPRHL_INDEXALPHA )
2005-05-13 10:42:48 +00:00
{
2013-12-29 22:48:28 +00:00
Con_Printf ( CON_ERROR " %s: SPRHL_INDEXALPHA sprites are not supported \n " , mod - > name ) ;
return false ;
}
else
{
for ( i = 0 ; i < 256 ; i + + )
{ //FIXME: bgr?
pal [ i * 4 + 0 ] = * src + + ;
pal [ i * 4 + 1 ] = * src + + ;
pal [ i * 4 + 2 ] = * src + + ;
pal [ i * 4 + 3 ] = 255 ;
}
if ( rendertype = = SPRHL_ALPHATEST )
{
pal [ 255 * 4 + 0 ] = 0 ;
pal [ 255 * 4 + 1 ] = 0 ;
pal [ 255 * 4 + 2 ] = 0 ;
pal [ 255 * 4 + 3 ] = 0 ;
}
2005-05-13 10:42:48 +00:00
}
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
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 * )
2014-10-05 20:04:11 +00:00
Mod_LoadSpriteFrame ( mod , pframetype + 1 , ( qbyte * ) buffer + fsize ,
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 * )
2014-10-05 20:04:11 +00:00
Mod_LoadSpriteGroup ( mod , pframetype + 1 , ( qbyte * ) buffer + fsize ,
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 )
{
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
}
2014-05-10 13:42:13 +00:00
# endif
2004-08-22 22:29:09 +00:00
2013-07-14 12:22:51 +00:00
# ifdef SP2MODELS
2014-03-30 08:55:06 +00:00
qboolean QDECL Mod_LoadSprite2Model ( model_t * mod , void * buffer , size_t fsize )
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 ] ;
2014-10-05 20:04:11 +00:00
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 ) ;
2014-10-05 20:04:11 +00:00
psprite = ZG_Malloc ( & mod - > memgroup , size ) ;
2004-08-22 22:29:09 +00:00
2013-07-14 12:22:51 +00:00
mod - > meshinfo = psprite ;
2004-08-22 22:29:09 +00:00
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
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 ;
2014-10-05 20:04:11 +00:00
frame = psprite - > frames [ i ] . frameptr = ZG_Malloc ( & mod - > memgroup , sizeof ( mspriteframe_t ) ) ;
2004-08-22 22:29:09 +00:00
2014-10-05 20:04:11 +00:00
frame - > image = Image_GetTexture ( pframetype - > name , NULL , IF_NOMIPMAP | IF_NOGAMMA | IF_CLAMP , NULL , NULL , 0 , 0 , TF_INVALID ) ;
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
}
2013-07-14 12:22:51 +00:00
# endif
2004-08-22 22:29:09 +00:00
2014-05-10 13:42:13 +00:00
# ifdef DSPMODELS
2004-08-22 22:29:09 +00:00
typedef struct {
short width ;
short height ;
short xpos ;
short ypos ;
} doomimage_t ;
2014-02-07 08:38:40 +00:00
static int QDECL FindDoomSprites ( const char * name , qofs_t size , void * param , searchpathfuncs_t * spath )
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 ;
}
2014-10-05 20:04:11 +00:00
static void LoadDoomSpriteFrame ( model_t * mod , char * imagename , mspriteframedesc_t * pdesc , int anglenum , qboolean xmirrored )
2004-08-22 22:29:09 +00:00
{
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 ;
2014-10-05 20:04:11 +00:00
pdesc - > frameptr = pframe = ZG_Malloc ( & mod - > memgroup , sizeof ( * pframe ) ) ;
2004-08-22 22:29:09 +00:00
}
else
{
mspritegroup_t * group ;
if ( ! pdesc - > frameptr | | pdesc - > type ! = SPR_ANGLED )
{
pdesc - > type = SPR_ANGLED ;
2014-10-05 20:04:11 +00:00
group = ZG_Malloc ( & mod - > memgroup , sizeof ( * group ) + sizeof ( mspriteframe_t * ) * ( 8 - 1 ) ) ;
2004-08-22 22:29:09 +00:00
pdesc - > frameptr = ( mspriteframe_t * ) group ;
group - > numframes = 8 ;
}
else
group = ( mspritegroup_t * ) pdesc - > frameptr ;
2014-10-05 20:04:11 +00:00
pframe = ZG_Malloc ( & mod - > memgroup , sizeof ( * pframe ) ) ;
2004-08-22 22:29:09 +00:00
group - > frames [ anglenum - 1 ] = pframe ;
}
palette = COM_LoadTempFile ( " wad/playpal " ) ;
2012-02-27 12:23:15 +00:00
header = ( doomimage_t * ) COM_LoadTempMoreFile ( imagename ) ;
2004-08-22 22:29:09 +00:00
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 + + ;
}
}
2013-08-21 07:14:39 +00:00
pframe - > shader = R_RegisterShader ( imagename , SUF_NONE ,
2010-07-25 15:12:12 +00:00
" { \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
= = = = = = = = = = = = = = = = =
*/
2013-07-14 12:22:51 +00:00
void Mod_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 ) ;
2014-10-05 20:04:11 +00:00
psprite = ZG_Malloc ( & mod - > memgroup , size ) ;
2004-08-22 22:29:09 +00:00
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 ' ;
2014-10-05 20:04:11 +00:00
LoadDoomSpriteFrame ( mod , name , & psprite - > frames [ framenum ] , anglenum , false ) ;
2004-08-22 22:29:09 +00:00
if ( name [ baselen + 2 ] ) //is there a second element?
{
framenum = name [ baselen + 2 ] - ' a ' ;
anglenum = name [ baselen + 3 ] - ' 0 ' ;
2014-10-05 20:04:11 +00:00
LoadDoomSpriteFrame ( mod , name , & psprite - > frames [ framenum ] , anglenum , true ) ;
2004-08-22 22:29:09 +00:00
}
}
psprite - > type = SPR_FACING_UPRIGHT ;
mod - > type = mod_sprite ;
2013-07-14 12:22:51 +00:00
mod - > meshinfo = psprite ;
2004-08-22 22:29:09 +00:00
}
# endif
//=============================================================================
/*
= = = = = = = = = = = = = = = =
Mod_Print
= = = = = = = = = = = = = = = =
*/
2013-07-14 12:22:51 +00:00
void Mod_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 + + )
{
2013-07-14 12:22:51 +00:00
Con_Printf ( " %8p : %s \n " , mod - > meshinfo , mod - > name ) ;
2004-08-22 22:29:09 +00:00
}
}
2004-12-15 19:53:30 +00:00
# endif