2022-02-08 21:49:56 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
Copyright ( C ) 2007 Peter Mackay and Chris Swindle .
Copyright ( C ) 2008 - 2009 Crow_bar .
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.
extern " C "
{
# include "../quakedef.h"
}
# include <malloc.h>
# include <pspgu.h>
# include "video_hardware_fullbright.h"
# include "video_hardware_hlmdl.h"
# include <list>
using namespace std ;
list < int > mapTextureNameList ;
int LIGHTMAP_BYTES ;
model_t * loadmodel ;
char loadname [ 32 ] ; // for hunk tags
//void UnloadWads (void); //wad unload by Crow_bar
void VID_InitPaleteH2 ( unsigned char * palette ) ;
void Mod_LoadSpriteModel ( model_t * mod , void * buffer ) ;
void Mod_LoadBrushModel ( model_t * mod , void * buffer ) ;
void Mod_LoadAliasModel ( model_t * mod , void * buffer ) ;
void Mod_LoadH2AliasModel ( model_t * mod , void * buffer ) ;
void Mod_LoadQ2AliasModel ( model_t * mod , void * buffer ) ;
qboolean Mod_LoadQ2SpriteModel ( model_t * mod , void * buffer ) ;
//void Mod_LoadQ2BrushModel (model_t *mod, void *buffer);
void Mod_LoadQ3AliasModel ( model_t * mod , void * buffer ) ;
model_t * Mod_LoadModel ( model_t * mod , qboolean crash ) ;
byte mod_novis [ MAX_MAP_LEAFS / 8 ] ;
# define MAX_MOD_KNOWN 512
model_t mod_known [ MAX_MOD_KNOWN ] ;
int mod_numknown ;
//model_t mod_inline[MAX_MOD_KNOWN];
cvar_t gl_subdivide_size = { " gl_subdivide_size " , " 128 " , qtrue } ;
extern int solidskytexture ;
extern int alphaskytexture ;
/*
= = = = = = = = = = = = = = =
Mod_Init
= = = = = = = = = = = = = = =
*/
void Mod_Init ( void )
{
Cvar_RegisterVariable ( & gl_subdivide_size ) ;
memset ( mod_novis , 0xff , sizeof ( mod_novis ) ) ;
}
/*
= = = = = = = = = = = = = = =
Mod_Init
Caches the data if needed
= = = = = = = = = = = = = = =
*/
void * Mod_Extradata ( model_t * mod )
{
void * r ;
r = Cache_Check ( & mod - > cache ) ;
if ( r )
return r ;
Mod_LoadModel ( mod , qtrue ) ;
if ( ! mod - > cache . data )
Sys_Error ( " Mod_Extradata: caching failed " ) ;
return mod - > cache . data ;
}
/*
= = = = = = = = = = = = = = =
Mod_PointInLeaf
= = = = = = = = = = = = = = =
*/
mleaf_t * Mod_PointInLeaf ( vec3_t p , model_t * model )
{
mnode_t * node ;
float d ;
mplane_t * plane ;
if ( ! model | | ! model - > nodes )
Sys_Error ( " Mod_PointInLeaf: bad model " ) ;
node = model - > nodes ;
while ( 1 )
{
if ( node - > contents < 0 )
return ( mleaf_t * ) node ;
plane = node - > plane ;
d = DotProduct ( p , plane - > normal ) - plane - > dist ;
if ( d > 0 )
node = node - > children [ 0 ] ;
else
node = node - > children [ 1 ] ;
}
return NULL ; // never reached
}
/*
= = = = = = = = = = = = = = = = = = =
Mod_DecompressVis
= = = = = = = = = = = = = = = = = = =
*/
byte * Mod_DecompressVis ( byte * in , model_t * model )
{
static byte decompressed [ MAX_MAP_LEAFS / 8 ] ;
int c ;
byte * out ;
int row ;
row = ( model - > numleafs + 7 ) > > 3 ;
out = decompressed ;
#if 0
memcpy ( out , in , row ) ;
# else
if ( ! in )
{ // no vis info, so make all visible
while ( row )
{
* out + + = 0xff ;
row - - ;
}
return decompressed ;
}
do
{
if ( * in )
{
* out + + = * in + + ;
continue ;
}
c = in [ 1 ] ;
in + = 2 ;
while ( c )
{
* out + + = 0 ;
c - - ;
}
} while ( out - decompressed < row ) ;
# endif
return decompressed ;
}
byte * Mod_LeafPVS ( mleaf_t * leaf , model_t * model )
{
if ( leaf = = model - > leafs )
return mod_novis ;
return Mod_DecompressVis ( leaf - > compressed_vis , model ) ;
}
/*
= = = = = = = = = = = = = = = = = = =
Mod_ClearAll
= = = = = = = = = = = = = = = = = = =
*/
static byte * ent_file = NULL ;
void Mod_ClearAll ( void )
{
int i , texture_index ;
model_t * mod ;
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
{
if ( mod - > type ! = mod_alias & & mod - > type ! = mod_md3 & & mod - > type ! = mod_halflife )
{
mod - > needload = qtrue ;
}
//Models & Sprite Unloading code By Crow_bar
if ( mod - > type = = mod_alias | | mod - > type = = mod_md3 | | mod - > type = = mod_halflife )
{
if ( Cache_Check ( & mod - > cache ) )
Cache_Free ( & mod - > cache ) ;
}
else if ( mod - > type = = mod_sprite )
{
mod - > cache . data = NULL ;
}
}
UnloadWads ( ) ; //Crow_bar
ent_file = NULL ; //~~~~
// maybe we should check if it is new map or not
// (so we dont unload textures unnecessary)
while ( mapTextureNameList . size ( ) > 0 )
{
texture_index = mapTextureNameList . front ( ) ;
mapTextureNameList . pop_front ( ) ;
GL_UnloadTexture ( texture_index ) ;
}
solidskytexture = - 1 ;
alphaskytexture = - 1 ;
//purge old sky textures
for ( i = 0 ; i < 6 ; i + + )
{
if ( skyimage [ i ] & & skyimage [ i ] ! = solidskytexture )
GL_UnloadTexture ( skyimage [ i ] ) ;
skyimage [ i ] = NULL ;
}
//purge old lightmaps
for ( i = 0 ; i < MAX_LIGHTMAPS ; i + + )
{
if ( lightmap_index [ i ] & & lightmap_index [ i ] ! = 0 )
GL_UnloadTexture ( lightmap_index [ i ] ) ;
lightmap_index [ i ] = NULL ;
}
}
/*
= = = = = = = = = = = = = = = = = =
Mod_FindName
= = = = = = = = = = = = = = = = = =
*/
model_t * Mod_FindName ( char * name )
{
int i ;
model_t * mod ;
if ( ! name [ 0 ] )
Sys_Error ( " Mod_ForName: NULL name " ) ;
/*
if ( ! name [ 0 ] )
{
//Search a loaded model
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
if ( ! strcmp ( mod - > name , name ) )
break ;
return mod ;
}
*/
//
// search the currently loaded models
//
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
if ( ! strcmp ( mod - > name , name ) )
break ;
if ( i = = mod_numknown )
{
if ( mod_numknown = = MAX_MOD_KNOWN )
Sys_Error ( " mod_numknown == MAX_MOD_KNOWN " ) ;
strcpy ( mod - > name , name ) ;
mod - > needload = qtrue ;
mod_numknown + + ;
}
return mod ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_TouchModel
= = = = = = = = = = = = = = = = = =
*/
void Mod_TouchModel ( char * name )
{
model_t * mod ;
mod = Mod_FindName ( name ) ;
if ( ! mod - > needload & & ( mod - > type = = mod_alias | | mod - > type = = mod_md3 | | mod - > type = = mod_halflife ) )
Cache_Check ( & mod - > cache ) ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_LoadModel
Loads a model into the cache
= = = = = = = = = = = = = = = = = =
*/
model_t * Mod_LoadModel ( model_t * mod , qboolean crash )
{
void * d ;
unsigned * buf ;
byte stackbuf [ 1024 ] ; // avoid dirtying the cache heap
char strip [ 128 ] ;
char md3name [ 128 ] ;
if ( ! mod - > needload )
{
if ( mod - > type = = mod_alias | | mod - > type = = mod_md3 | | mod - > type = = mod_halflife )
{
d = Cache_Check ( & mod - > cache ) ;
if ( d )
return mod ;
}
else
return mod ; // not cached at all
}
//
// because the world is so huge, load it one piece at a time
//
if ( ! crash )
{
}
//
// load the file
//
if ( r_loadq3models . value )
{
COM_StripExtension ( mod - > name , & strip [ 0 ] ) ;
sprintf ( & md3name [ 0 ] , " %s.md3 " , & strip [ 0 ] ) ;
buf = ( unsigned * ) COM_LoadStackFile ( md3name , stackbuf , sizeof ( stackbuf ) ) ;
if ( ! buf )
{
buf = ( unsigned * ) COM_LoadStackFile ( mod - > name , stackbuf , sizeof ( stackbuf ) ) ;
if ( ! buf )
{
if ( crash )
Sys_Error ( " Mod_NumForName: %s not found " , mod - > name ) ;
return NULL ;
}
}
}
else
{
buf = ( unsigned * ) COM_LoadStackFile ( mod - > name , stackbuf , sizeof ( stackbuf ) ) ;
if ( ! buf & & crash )
{
// Reload with another .mdl
buf = ( unsigned * ) COM_LoadStackFile ( " progs/missing_model.mdl " , stackbuf , sizeof ( stackbuf ) ) ;
if ( buf )
{
Con_Printf ( " Missing model %s substituted \n " , mod - > name ) ;
}
}
if ( ! buf )
{
if ( crash )
Sys_Error ( " Mod_NumForName: %s not found " , mod - > name ) ;
return NULL ;
}
}
//
// allocate a new model
//
COM_FileBase ( mod - > name , loadname ) ;
loadmodel = mod ;
//
// fill it in
//
// call the apropriate loader
mod - > needload = qfalse ;
switch ( LittleLong ( * ( unsigned * ) buf ) )
{
case IDPOLYHEADER : //Quake .mdl support
Mod_LoadAliasModel ( mod , buf ) ;
break ;
case RAPOLYHEADER : //Hexen II .mdl support
Mod_LoadH2AliasModel ( mod , buf ) ;
break ;
case MD2IDALIASHEADER : //Quake II .md2 support
Mod_LoadQ2AliasModel ( mod , buf ) ;
break ;
case MD3IDHEADER : //Quake III .md3 support
Mod_LoadQ3AliasModel ( mod , buf ) ;
break ;
case HLPOLYHEADER : //Half-Life .mdl support
Mod_LoadHLModel ( mod , buf ) ;
break ;
case IDSPRITEHEADER : //Quake .spr .spr32 and HL sprite support
Mod_LoadSpriteModel ( mod , buf ) ;
break ;
case IDSPRITE2HEADER : //Quake II .sp2 support
Mod_LoadQ2SpriteModel ( mod , buf ) ;
break ;
/*
case IDBSPHEADER : //q2 bsp support
Mod_LoadQ2BrushModel ( mod , buf ) ;
break ;
*/
default : //.bsp ver 29,30 support
Mod_LoadBrushModel ( mod , buf ) ;
break ;
}
return mod ;
}
/*
= = = = = = = = = = = = = = = = = =
Mod_ForName
Loads in a model for the given name
= = = = = = = = = = = = = = = = = =
*/
model_t * Mod_ForName ( char * name , qboolean crash )
{
model_t * mod ;
mod = Mod_FindName ( name ) ;
return Mod_LoadModel ( mod , crash ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
BRUSHMODEL LOADING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
byte * mod_base ;
int GL_LoadTexturePixels ( byte * data , char * identifier , int width , int height , int mode ) ;
# define ISSKYTEX(name) ((name)[0] == 's' && (name)[1] == 'k' && (name)[2] == 'y')
# define ISTURBTEX(name) ((loadmodel->bspversion == BSPVERSION && (name)[0] == '*') || \
( loadmodel - > bspversion = = HL_BSPVERSION & & ( name ) [ 0 ] = = ' ! ' ) | | \
( loadmodel - > bspversion = = NZP_BSPVERSION & & ( name ) [ 0 ] = = ' ! ' ) )
extern int detail_texture ;
extern int nonetexture ;
/*
= = = = = = = = = = = = = = = = =
Mod_LoadTextures
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadTextures ( lump_t * l )
{
int i , j , pixels , num , max , altmax ;
miptex_t * mt ;
texture_t * tx , * tx2 ;
texture_t * anims [ 10 ] ;
texture_t * altanims [ 10 ] ;
dmiptexlump_t * m ;
char texname [ 64 ] ;
loadmodel - > textures = NULL ;
char fbr_mask_name [ 64 ] ;
if ( ! l - > filelen )
{
return ;
}
m = ( dmiptexlump_t * ) ( mod_base + l - > fileofs ) ;
m - > nummiptex = LittleLong ( m - > nummiptex ) ;
loadmodel - > numtextures = m - > nummiptex ;
loadmodel - > textures = static_cast < texture_t * * > ( Hunk_AllocName ( m - > nummiptex * sizeof ( * loadmodel - > textures ) , loadname ) ) ;
loading_num_step = loading_num_step + m - > nummiptex ;
for ( i = 0 ; i < m - > nummiptex ; i + + )
{
m - > dataofs [ i ] = LittleLong ( m - > dataofs [ i ] ) ;
if ( m - > dataofs [ i ] = = - 1 )
continue ;
mt = ( miptex_t * ) ( ( byte * ) m + m - > dataofs [ i ] ) ;
mt - > width = LittleLong ( mt - > width ) ;
mt - > height = LittleLong ( mt - > height ) ;
for ( j = 0 ; j < MIPLEVELS ; j + + )
mt - > offsets [ j ] = LittleLong ( mt - > offsets [ j ] ) ;
if ( ( mt - > width & 15 ) | | ( mt - > height & 15 ) )
Sys_Error ( " Texture %s is not 16 aligned " , mt - > name ) ;
pixels = mt - > width * mt - > height / 64 * 85 ;
tx = static_cast < texture_t * > ( Hunk_AllocName ( sizeof ( texture_t ) , loadname ) ) ;
const std : : size_t buffer_size = pixels ;
byte * tx_pixels = static_cast < byte * > ( memalign ( 16 , buffer_size ) ) ;
if ( ! tx_pixels )
{
Sys_Error ( " BrushTex: Out of RAM for loading textures \n " ) ;
}
loadmodel - > textures [ i ] = tx ;
memcpy ( tx - > name , mt - > name , sizeof ( tx - > name ) ) ;
tx - > width = mt - > width ;
tx - > height = mt - > height ;
for ( j = 0 ; j < MIPLEVELS ; j + + )
tx - > offsets [ j ] = mt - > offsets [ j ] + sizeof ( texture_t ) - sizeof ( miptex_t ) ;
// the pixels immediately follow the structures
memcpy ( tx_pixels , mt + 1 , pixels ) ;
int level = 0 ;
if ( r_mipmaps . value > 0 )
level = 3 ;
//if (loadmodel->isworldmodel && loadmodel->bspversion != HL_BSPVERSION && ISSKYTEX(tx->name))
if ( loadmodel - > bspversion ! = HL_BSPVERSION & & loadmodel - > bspversion ! = NZP_BSPVERSION & & ISSKYTEX ( tx - > name ) )
{
R_InitSky ( tx_pixels ) ;
mapTextureNameList . push_back ( solidskytexture ) ;
mapTextureNameList . push_back ( alphaskytexture ) ;
}
else
{
if ( loadmodel - > bspversion = = HL_BSPVERSION | | loadmodel - > bspversion = = NZP_BSPVERSION )
{
char filename [ 64 ] ; // Filename to check r4w file
byte * f ;
sprintf ( filename , " textures/maps/%s/%s.r4w " , sv . name , mt - > name ) ; // search in textures/maps/MAPNAME/TEXNAME
f = static_cast < byte * > ( COM_LoadHunkFile ( filename ) ) ;
if ( ! f ) {
sprintf ( filename , " textures/%s.r4w " , mt - > name ) ; // search in textures/TEXNAME
f = static_cast < byte * > ( COM_LoadHunkFile ( filename ) ) ;
}
if ( ! f ) {
Con_Printf ( " Loading texture %s as WAD3 \n " , mt - > name ) ; // didn't find the texture in the folder
// naievil -- try to push wad3 loading
int index = WAD3_LoadTexture ( mt ) ;
if ( index )
{
com_netpath [ 0 ] = 0 ;
tx - > gl_texturenum = index ;
tx - > fullbright = - 1 ;
mapTextureNameList . push_back ( tx - > gl_texturenum ) ;
tx - > dt_texturenum = 0 ;
// if(tx_pixels = WAD3_LoadTexture(mt))
// {
// com_netpath[0] = 0;
// tx->gl_texturenum = GL_LoadPalletedTexture (tx_pixels, tx->name, tx->width, tx->height, 0);
// tx->fullbright = -1;
// mapTextureNameList.push_back(tx->gl_texturenum);
// tx->dt_texturenum = 0;
}
else
{
Con_Printf ( " Texture %s not found \n " , mt - > name ) ; // didn't find the texture in the folder
com_netpath [ 0 ] = 0 ;
tx - > gl_texturenum = nonetexture ;
}
} else {
int w , h ;
unsigned int magic = * ( ( unsigned int * ) ( f ) ) ;
if ( magic = = 0x65663463 ) // what the fuck?
{
w = * ( ( int * ) ( f + 4 ) ) ;
h = * ( ( int * ) ( f + 8 ) ) ;
tx - > gl_texturenum = GL_LoadTexture4 ( mt - > name , w , h , ( byte * ) ( f + 16 ) , GU_LINEAR ) ;
mapTextureNameList . push_back ( tx - > gl_texturenum ) ;
}
}
}
else
{
sprintf ( texname , " textures/%s " , mt - > name ) ;
tx - > gl_texturenum = loadtextureimage ( texname , 0 , 0 , qfalse , GU_LINEAR ) ;
if ( tx - > gl_texturenum = = 0 )
{
tx - > gl_texturenum = GL_LoadTexture ( mt - > name , tx - > width , tx - > height , ( byte * ) ( tx_pixels ) , qtrue , GU_LINEAR , level ) ;
}
mapTextureNameList . push_back ( tx - > gl_texturenum ) ;
/*
//Crow_bar mult detail textures
sprintf ( detname , " gfx/detail/%s " , mt - > name ) ;
tx - > dt_texturenum = loadtextureimage ( detname , 0 , 0 , qfalse , GU_LINEAR ) ;
mapTextureNameList . push_back ( tx - > dt_texturenum ) ;
*/
tx - > dt_texturenum = 0 ;
// check for fullbright pixels in the texture - only if it ain't liquid, etc also
if ( ( tx - > name [ 0 ] ! = ' * ' ) & & ( FindFullbrightTexture ( ( byte * ) ( tx_pixels ) , pixels ) ) )
{
// convert any non fullbright pixel to fully transparent
ConvertPixels ( ( byte * ) ( tx_pixels ) , pixels ) ;
// get a new name for the fullbright mask to avoid cache mismatches
sprintf ( fbr_mask_name , " fullbright_mask_%s " , mt - > name ) ;
// load the fullbright pixels version of the texture
tx - > fullbright =
GL_LoadTexture ( fbr_mask_name , tx - > width , tx - > height , ( byte * ) ( tx_pixels ) , qtrue , GU_LINEAR , level ) ;
mapTextureNameList . push_back ( tx - > fullbright ) ;
}
else
tx - > fullbright = - 1 ; // because 0 is a potentially valid texture number
}
}
strcpy ( loading_name , mt - > name ) ;
free ( tx_pixels ) ;
loading_cur_step + + ;
SCR_UpdateScreen ( ) ;
}
//
// sequence the animations
//
for ( i = 0 ; i < m - > nummiptex ; i + + )
{
tx = loadmodel - > textures [ i ] ;
if ( ! tx | | tx - > name [ 0 ] ! = ' + ' )
continue ;
if ( tx - > anim_next )
continue ; // allready sequenced
// 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
Sys_Error ( " Bad animating texture %s " , tx - > name ) ;
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
Sys_Error ( " Bad animating texture %s " , tx - > name ) ;
}
# define ANIM_CYCLE 2
// link them all together
for ( j = 0 ; j < max ; j + + )
{
tx2 = anims [ j ] ;
if ( ! tx2 )
Sys_Error ( " Missing frame %i of %s " , j , tx - > name ) ;
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 )
Sys_Error ( " Missing frame %i of %s " , j , tx - > name ) ;
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 ] ;
}
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadLighting
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadLighting ( lump_t * l )
{
if ( COM_CheckParm ( " -lm_1 " ) )
LIGHTMAP_BYTES = 1 ;
else if ( COM_CheckParm ( " -lm_2 " ) )
LIGHTMAP_BYTES = 2 ;
else if ( COM_CheckParm ( " -lm_3 " ) )
LIGHTMAP_BYTES = 3 ;
else
LIGHTMAP_BYTES = 4 ;
loadmodel - > lightdata = NULL ;
if ( loadmodel - > bspversion = = HL_BSPVERSION | | loadmodel - > bspversion = = NZP_BSPVERSION )
{
if ( ! l - > filelen )
{
return ;
}
loadmodel - > lightdata = static_cast < byte * > ( Hunk_AllocName ( l - > filelen , loadname ) ) ;
memcpy ( loadmodel - > lightdata , mod_base + l - > fileofs , l - > filelen ) ;
return ;
}
int i ;
byte * in , * out , * data ;
byte d ;
char litfilename [ 1024 ] ;
// LordHavoc: check for a .lit file
strcpy ( litfilename , loadmodel - > name ) ;
COM_StripExtension ( litfilename , litfilename ) ;
strcat ( litfilename , " .lit " ) ;
data = ( byte * ) COM_LoadHunkFile ( litfilename ) ;
if ( data )
{
if ( data [ 0 ] = = ' Q ' & & data [ 1 ] = = ' L ' & & data [ 2 ] = = ' I ' & & data [ 3 ] = = ' T ' )
{
i = LittleLong ( ( ( int * ) data ) [ 1 ] ) ;
if ( i = = 1 )
{
Con_DPrintf ( " %s loaded " , litfilename ) ;
loadmodel - > lightdata = data + 8 ;
return ;
}
else
Con_Printf ( " Unknown .lit file version (%d) \n " , i ) ;
}
else
Con_Printf ( " Corrupt .lit file (old version?), ignoring \n " ) ;
}
// LordHavoc: no .lit found, expand the white lighting data to color
if ( ! l - > filelen )
{
return ;
}
loadmodel - > lightdata = static_cast < byte * > ( Hunk_AllocName ( l - > filelen * 3 , litfilename ) ) ;
in = loadmodel - > lightdata + l - > filelen * 2 ; // place the file at the end, so it will not be overwritten until the very last write
out = loadmodel - > lightdata ;
memcpy ( in , mod_base + l - > fileofs , l - > filelen ) ;
for ( i = 0 ; i < l - > filelen ; i + + )
{
d = * in + + ;
* out + + = d ;
* out + + = d ;
* out + + = d ;
}
// LordHavoc: .lit support end
}
// added by dr_mabuse1981
/*
= = = = = = = = = = = = = = = = =
Mod_HL_LoadLighting
= = = = = = = = = = = = = = = = =
*/
void Mod_HL_LoadLighting ( lump_t * l )
{
if ( COM_CheckParm ( " -lm_1 " ) )
LIGHTMAP_BYTES = 1 ;
else if ( COM_CheckParm ( " -lm_2 " ) )
LIGHTMAP_BYTES = 2 ;
else if ( COM_CheckParm ( " -lm_3 " ) )
LIGHTMAP_BYTES = 3 ;
else
LIGHTMAP_BYTES = 4 ;
if ( ! l - > filelen )
{
loadmodel - > lightdata = NULL ;
return ;
}
loadmodel - > lightdata = static_cast < byte * > ( Hunk_AllocName ( l - > filelen , loadname ) ) ;
memcpy ( loadmodel - > lightdata , mod_base + l - > fileofs , l - > filelen ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadVisibility
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadVisibility ( lump_t * l )
{
loadmodel - > visdata = NULL ;
if ( ! l - > filelen )
{
return ;
}
loadmodel - > visdata = static_cast < byte * > ( Hunk_AllocName ( l - > filelen , loadname ) ) ;
memcpy ( loadmodel - > visdata , mod_base + l - > fileofs , l - > filelen ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_ParseWadsFromEntityLump
For Half - life maps
= = = = = = = = = = = = = = = = =
*/
static void Mod_ParseWadsFromEntityLump ( char * data )
{
char * s , key [ 1024 ] , value [ 1024 ] ;
int i , j , k ;
if ( ! data | | ! ( data = COM_Parse ( data ) ) )
return ;
if ( com_token [ 0 ] ! = ' { ' )
return ; // error
while ( 1 )
{
if ( ! ( data = COM_Parse ( data ) ) )
return ; // error
if ( com_token [ 0 ] = = ' } ' )
break ; // end of worldspawn
Q_strncpyz ( key , ( com_token [ 0 ] = = ' _ ' ) ? com_token + 1 : com_token , sizeof ( key ) ) ;
for ( s = key + strlen ( key ) - 1 ; s > = key & & * s = = ' ' ; s - - ) // remove trailing spaces
* s = 0 ;
if ( ! ( data = COM_Parse ( data ) ) )
return ; // error
Q_strncpyz ( value , com_token , sizeof ( value ) ) ;
if ( ! strcmp ( " MaxRange " , key ) )
Cvar_Set ( " r_maxrange " , value ) ;
if ( ! strcmp ( " wad " , key ) )
{
j = 0 ;
for ( i = 0 ; i < strlen ( value ) ; i + + )
{
if ( value [ i ] ! = ' ; ' & & value [ i ] ! = ' \\ ' & & value [ i ] ! = ' / ' & & value [ i ] ! = ' : ' )
break ;
}
if ( ! value [ i ] )
continue ;
for ( ; i < sizeof ( value ) ; i + + )
{
// ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
if ( value [ i ] = = ' \\ ' | | value [ i ] = = ' / ' | | value [ i ] = = ' : ' )
{
j = i + 1 ;
}
else if ( value [ i ] = = ' ; ' | | value [ i ] = = 0 )
{
k = value [ i ] ;
value [ i ] = 0 ;
if ( value [ j ] )
WAD3_LoadTextureWadFile ( value + j ) ;
j = i + 1 ;
if ( ! k )
break ;
}
}
}
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadEntities
. ent file support by Crow_bar
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadEntities ( lump_t * l )
{
char entfilename [ 128 ] ;
loadmodel - > entities = NULL ;
strcpy ( entfilename , loadmodel - > name ) ;
COM_StripExtension ( entfilename , entfilename ) ;
strcat ( entfilename , " .ent " ) ;
ent_file = ( byte * ) COM_LoadHunkFile ( entfilename ) ;
if ( ent_file )
{
if ( ent_file [ 0 ] = = ' { ' )
{
Con_DPrintf ( " %s loaded " , entfilename ) ;
loadmodel - > entities = ( char * ) ent_file ;
return ;
}
else
Con_Printf ( " Corrupt .ent file, ignoring \n " ) ;
}
if ( ! l - > filelen )
{
//loadmodel->entities = NULL;
return ;
}
loadmodel - > entities = static_cast < char * > ( Hunk_AllocName ( l - > filelen , entfilename ) ) ;
memcpy ( loadmodel - > entities , mod_base + l - > fileofs , l - > filelen ) ;
if ( loadmodel - > bspversion = = HL_BSPVERSION | | loadmodel - > bspversion = = NZP_BSPVERSION )
Mod_ParseWadsFromEntityLump ( loadmodel - > entities ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadVertexes
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadVertexes ( lump_t * l )
{
dvertex_t * in ;
mvertex_t * out ;
int i , count ;
in = reinterpret_cast < dvertex_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < mvertex_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > vertexes = out ;
loadmodel - > numvertexes = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
out - > position [ 0 ] = LittleFloat ( in - > point [ 0 ] ) ;
out - > position [ 1 ] = LittleFloat ( in - > point [ 1 ] ) ;
out - > position [ 2 ] = LittleFloat ( in - > point [ 2 ] ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSubmodels
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadSubmodels ( lump_t * l )
{
dmodel_t * in ;
dmodel_t * out ;
int i , j , count ;
in = reinterpret_cast < dmodel_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < dmodel_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > submodels = out ;
loadmodel - > numsubmodels = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{ // spread the mins / maxs by a pixel
out - > mins [ j ] = LittleFloat ( in - > mins [ j ] ) - 1 ;
out - > maxs [ j ] = LittleFloat ( in - > maxs [ j ] ) + 1 ;
out - > origin [ j ] = LittleFloat ( in - > origin [ j ] ) ;
}
for ( j = 0 ; j < MAX_MAP_HULLS ; j + + )
out - > headnode [ j ] = LittleLong ( in - > headnode [ j ] ) ;
out - > visleafs = LittleLong ( in - > visleafs ) ;
out - > firstface = LittleLong ( in - > firstface ) ;
out - > numfaces = LittleLong ( in - > numfaces ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadEdges
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadEdges ( lump_t * l )
{
dedge_t * in ;
medge_t * out ;
int i , count ;
in = reinterpret_cast < dedge_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < medge_t * > ( Hunk_AllocName ( ( count + 1 ) * sizeof ( * out ) , loadname ) ) ;
loadmodel - > edges = out ;
loadmodel - > numedges = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
out - > v [ 0 ] = ( unsigned short ) LittleShort ( in - > v [ 0 ] ) ;
out - > v [ 1 ] = ( unsigned short ) LittleShort ( in - > v [ 1 ] ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadTexinfo
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadTexinfo ( lump_t * l )
{
texinfo_t * in ;
mtexinfo_t * out ;
int i , j , count ;
int miptex ;
float len1 , len2 ;
in = reinterpret_cast < texinfo_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < mtexinfo_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > texinfo = out ;
loadmodel - > numtexinfo = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 8 ; j + + )
out - > vecs [ 0 ] [ j ] = LittleFloat ( in - > vecs [ 0 ] [ j ] ) ;
len1 = Length ( out - > vecs [ 0 ] ) ;
len2 = Length ( out - > vecs [ 1 ] ) ;
len1 = ( len1 + len2 ) / 2 ;
if ( len1 < 0.32 )
out - > mipadjust = 4 ;
else if ( len1 < 0.49 )
out - > mipadjust = 3 ;
else if ( len1 < 0.99 )
out - > mipadjust = 2 ;
else
out - > mipadjust = 1 ;
#if 0
if ( len1 + len2 < 0.001 )
out - > mipadjust = 1 ; // don't crash
else
out - > mipadjust = 1 / floorf ( ( len1 + len2 ) / 2 + 0.1 ) ;
# endif
miptex = LittleLong ( in - > miptex ) ;
out - > flags = LittleLong ( in - > flags ) ;
if ( ! loadmodel - > textures )
{
out - > texture = r_notexture_mip ; // checkerboard texture
out - > flags = 0 ;
}
else
{
if ( miptex > = loadmodel - > numtextures )
Sys_Error ( " miptex >= loadmodel->numtextures " ) ;
out - > texture = loadmodel - > textures [ miptex ] ;
if ( ! out - > texture )
{
out - > texture = r_notexture_mip ; // texture not found
out - > flags = 0 ;
}
}
}
}
/*
= = = = = = = = = = = = = = = =
CalcSurfaceExtents
Fills in s - > texturemins [ ] and s - > extents [ ]
= = = = = = = = = = = = = = = =
*/
void CalcSurfaceExtents ( msurface_t * s )
{
float mins [ 2 ] , maxs [ 2 ] , val ;
int i , j , e ;
mvertex_t * v ;
mtexinfo_t * tex ;
int bmins [ 2 ] , bmaxs [ 2 ] ;
mins [ 0 ] = mins [ 1 ] = 999999 ;
maxs [ 0 ] = maxs [ 1 ] = - 99999 ;
tex = s - > texinfo ;
for ( i = 0 ; i < s - > numedges ; i + + )
{
e = loadmodel - > surfedges [ s - > firstedge + i ] ;
if ( e > = 0 )
v = & loadmodel - > vertexes [ loadmodel - > edges [ e ] . v [ 0 ] ] ;
else
v = & loadmodel - > vertexes [ loadmodel - > edges [ - e ] . v [ 1 ] ] ;
for ( j = 0 ; j < 2 ; j + + )
{
val = v - > position [ 0 ] * tex - > vecs [ j ] [ 0 ] +
v - > position [ 1 ] * tex - > vecs [ j ] [ 1 ] +
v - > position [ 2 ] * tex - > vecs [ j ] [ 2 ] +
tex - > vecs [ j ] [ 3 ] ;
if ( val < mins [ j ] )
mins [ j ] = val ;
if ( val > maxs [ j ] )
maxs [ j ] = val ;
}
}
for ( i = 0 ; i < 2 ; i + + )
{
bmins [ i ] = ( int ) floorf ( mins [ i ] / 16 ) ;
bmaxs [ i ] = ( int ) ceilf ( maxs [ i ] / 16 ) ;
s - > texturemins [ i ] = bmins [ i ] * 16 ;
s - > extents [ i ] = ( bmaxs [ i ] - bmins [ i ] ) * 16 ;
if ( ! ( tex - > flags & TEX_SPECIAL ) & & s - > extents [ i ] > 512 /* 256 */ )
Sys_Error ( " Bad surface extents " ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadFaces
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadFaces ( lump_t * l )
{
dface_t * in ;
msurface_t * out ;
int i , count , surfnum ;
int planenum , side ;
in = reinterpret_cast < dface_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < msurface_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > surfaces = out ;
loadmodel - > numsurfaces = count ;
for ( surfnum = 0 ; surfnum < count ; surfnum + + , in + + , out + + )
{
out - > firstedge = LittleLong ( in - > firstedge ) ;
out - > numedges = LittleShort ( in - > numedges ) ;
out - > flags = 0 ;
planenum = LittleShort ( in - > planenum ) ;
side = LittleShort ( in - > side ) ;
if ( side )
out - > flags | = SURF_PLANEBACK ;
out - > plane = loadmodel - > planes + planenum ;
out - > texinfo = loadmodel - > texinfo + LittleShort ( in - > texinfo ) ;
CalcSurfaceExtents ( out ) ;
// lighting info
for ( i = 0 ; i < MAXLIGHTMAPS ; i + + )
out - > styles [ i ] = in - > styles [ i ] ;
if ( loadmodel - > bspversion = = HL_BSPVERSION | | loadmodel - > bspversion = = NZP_BSPVERSION )
i = LittleLong ( in - > lightofs ) ;
else
i = LittleLong ( in - > lightofs * 3 ) ;
if ( i = = - 1 )
out - > samples = NULL ;
else
out - > samples = loadmodel - > lightdata + ( i ) ;
if ( ! Q_strncmp ( out - > texinfo - > texture - > name , " sky " , 3 ) )
{
out - > flags | = ( SURF_DRAWSKY | SURF_DRAWTILED ) ;
//if(kurok)
//GL_SubdivideSurface (out); // cut up polygon for warps
//else
GL_Surface ( out ) ; // Don't cut up polygon for warps
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 ;
}
GL_Surface ( out ) ; // Don't cut up polygon for warps
//GL_SubdivideSurface (out);// cut up polygon for warps
continue ;
}
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_SetParent
= = = = = = = = = = = = = = = = =
*/
void Mod_SetParent ( mnode_t * node , mnode_t * parent )
{
node - > parent = parent ;
if ( node - > contents < 0 )
return ;
Mod_SetParent ( node - > children [ 0 ] , node ) ;
Mod_SetParent ( node - > children [ 1 ] , node ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadNodes
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadNodes ( lump_t * l )
{
int i , j , count , p ;
dnode_t * in ;
mnode_t * out ;
in = reinterpret_cast < dnode_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < mnode_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > nodes = out ;
loadmodel - > numnodes = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
out - > minmaxs [ j ] = LittleShort ( in - > mins [ j ] ) ;
out - > minmaxs [ 3 + j ] = LittleShort ( in - > maxs [ j ] ) ;
}
p = LittleLong ( in - > planenum ) ;
out - > plane = loadmodel - > planes + p ;
out - > firstsurface = LittleShort ( in - > firstface ) ;
out - > numsurfaces = LittleShort ( in - > numfaces ) ;
for ( j = 0 ; j < 2 ; j + + )
{
p = LittleShort ( in - > children [ j ] ) ;
if ( p > = 0 )
out - > children [ j ] = loadmodel - > nodes + p ;
else
out - > children [ j ] = ( mnode_t * ) ( loadmodel - > leafs + ( - 1 - p ) ) ;
}
}
Mod_SetParent ( loadmodel - > nodes , NULL ) ; // sets nodes and leafs
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadLeafs
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadLeafs ( lump_t * l )
{
dleaf_t * in ;
mleaf_t * out ;
int i , j , count , p ;
in = reinterpret_cast < dleaf_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < mleaf_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > leafs = out ;
loadmodel - > numleafs = count ;
for ( i = 0 ; i < count ; i + + , in + + , out + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
out - > minmaxs [ j ] = LittleShort ( in - > mins [ j ] ) ;
out - > minmaxs [ 3 + j ] = LittleShort ( in - > maxs [ j ] ) ;
}
p = LittleLong ( in - > contents ) ;
out - > contents = p ;
out - > firstmarksurface = loadmodel - > marksurfaces +
LittleShort ( in - > firstmarksurface ) ;
out - > nummarksurfaces = LittleShort ( in - > nummarksurfaces ) ;
p = LittleLong ( in - > visofs ) ;
if ( p = = - 1 )
out - > compressed_vis = NULL ;
else
out - > compressed_vis = loadmodel - > visdata + p ;
out - > efrags = NULL ;
for ( j = 0 ; j < 4 ; j + + )
out - > ambient_sound_level [ j ] = in - > ambient_level [ j ] ;
// gl underwater warp
if ( out - > contents ! = CONTENTS_EMPTY )
{
for ( j = 0 ; j < out - > nummarksurfaces ; j + + )
out - > firstmarksurface [ j ] - > flags | = SURF_UNDERWATER ;
}
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadClipnodes
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadClipnodes ( lump_t * l )
{
dclipnode_t * in , * out ;
int i , count ;
hull_t * hull ;
in = reinterpret_cast < dclipnode_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < dclipnode_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > clipnodes = out ;
loadmodel - > numclipnodes = count ;
if ( loadmodel - > bspversion = = HL_BSPVERSION | | loadmodel - > bspversion = = NZP_BSPVERSION )
{
hull = & loadmodel - > hulls [ 1 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 36 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 36 ;
hull = & loadmodel - > hulls [ 2 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 32 ;
hull - > clip_mins [ 1 ] = - 32 ;
hull - > clip_mins [ 2 ] = - 32 ;
hull - > clip_maxs [ 0 ] = 32 ;
hull - > clip_maxs [ 1 ] = 32 ;
hull - > clip_maxs [ 2 ] = 32 ;
hull = & loadmodel - > hulls [ 3 ] ;
hull - > clipnodes = out ;
hull - > firstclipnode = 0 ;
hull - > lastclipnode = count - 1 ;
hull - > planes = loadmodel - > planes ;
hull - > clip_mins [ 0 ] = - 16 ;
hull - > clip_mins [ 1 ] = - 16 ;
hull - > clip_mins [ 2 ] = - 18 ;
hull - > clip_maxs [ 0 ] = 16 ;
hull - > clip_maxs [ 1 ] = 16 ;
hull - > clip_maxs [ 2 ] = 18 ;
}
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 = & 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 ;
}
for ( i = 0 ; i < count ; i + + , out + + , in + + )
{
out - > planenum = LittleLong ( in - > planenum ) ;
out - > children [ 0 ] = LittleShort ( in - > children [ 0 ] ) ;
out - > children [ 1 ] = LittleShort ( in - > children [ 1 ] ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_MakeHull0
Deplicate the drawing hull structure as a clipping hull
= = = = = = = = = = = = = = = = =
*/
void Mod_MakeHull0 ( void )
{
mnode_t * in , * child ;
dclipnode_t * out ;
int i , j , count ;
hull_t * hull ;
hull = & loadmodel - > hulls [ 0 ] ;
in = loadmodel - > nodes ;
count = loadmodel - > numnodes ;
out = static_cast < dclipnode_t * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
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
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadMarksurfaces ( lump_t * l )
{
int i , j , count ;
short * in ;
msurface_t * * out ;
in = reinterpret_cast < short * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < msurface_t * * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > marksurfaces = out ;
loadmodel - > nummarksurfaces = count ;
for ( i = 0 ; i < count ; i + + )
{
j = LittleShort ( in [ i ] ) ;
if ( j > = loadmodel - > numsurfaces )
Sys_Error ( " Mod_ParseMarksurfaces: bad surface number " ) ;
out [ i ] = loadmodel - > surfaces + j ;
}
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSurfedges
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadSurfedges ( lump_t * l )
{
int i , count ;
int * in , * out ;
in = reinterpret_cast < int * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < int * > ( Hunk_AllocName ( count * sizeof ( * out ) , loadname ) ) ;
loadmodel - > surfedges = out ;
loadmodel - > numsurfedges = count ;
for ( i = 0 ; i < count ; i + + )
out [ i ] = LittleLong ( in [ i ] ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadPlanes
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadPlanes ( lump_t * l )
{
int i , j ;
mplane_t * out ;
dplane_t * in ;
int count ;
int bits ;
in = reinterpret_cast < dplane_t * > ( mod_base + l - > fileofs ) ;
if ( l - > filelen % sizeof ( * in ) )
Con_Printf ( " MOD_LoadBmodel: funny lump size in %s " , loadmodel - > name ) ;
count = l - > filelen / sizeof ( * in ) ;
out = static_cast < mplane_t * > ( Hunk_AllocName ( count * 2 * sizeof ( * out ) , loadname ) ) ;
loadmodel - > planes = out ;
loadmodel - > numplanes = count ;
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 ;
}
}
/*
= = = = = = = = = = = = = = = = =
RadiusFromBounds
= = = = = = = = = = = = = = = = =
*/
float RadiusFromBounds ( vec3_t mins , vec3_t maxs )
{
int i ;
vec3_t corner ;
for ( i = 0 ; i < 3 ; i + + )
{
# ifdef PSP_VFPU
corner [ i ] = vfpu_fabsf ( mins [ i ] ) > vfpu_fabsf ( maxs [ i ] ) ? vfpu_fabsf ( mins [ i ] ) : vfpu_fabsf ( maxs [ i ] ) ;
# else
corner [ i ] = fabsf ( mins [ i ] ) > fabsf ( maxs [ i ] ) ? fabsf ( mins [ i ] ) : fabsf ( maxs [ i ] ) ;
# endif
}
return Length ( corner ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadBrushModel
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadBrushModel ( model_t * mod , void * buffer )
{
int i , j ;
dheader_t * header ;
dmodel_t * bm ;
loadmodel - > type = mod_brush ;
header = ( dheader_t * ) buffer ;
i = LittleLong ( header - > version ) ;
mod - > bspversion = LittleLong ( header - > version ) ;
if ( mod - > bspversion ! = BSPVERSION & & mod - > bspversion ! = HL_BSPVERSION & & mod - > bspversion ! = NZP_BSPVERSION )
Host_Error ( " Mod_LoadBrushModel: %s has wrong version number (%i should be %i (Quake) or %i (HalfLife)) " , mod - > name , mod - > bspversion , BSPVERSION , HL_BSPVERSION ) ;
//loadmodel->isworldmodel = !strcmp(loadmodel->name, va("maps/%s.bsp", mapname.string));
if ( mod - > bspversion = = BSPVERSION & & r_hlbsponly . value & & ! developer . value )
Host_Error ( " Mod_LoadBrushModel: Normal quake maps are disabled. Please use half life bsp. " ) ;
// swap all the lumps
mod_base = ( byte * ) header ;
for ( i = 0 ; i < sizeof ( dheader_t ) / 4 ; i + + )
( ( int * ) header ) [ i ] = LittleLong ( ( ( int * ) header ) [ i ] ) ;
loading_num_step = loading_num_step + 16 ;
2022-04-05 15:54:40 +00:00
loading_step = 2 ;
2022-02-08 21:49:56 +00:00
strcpy ( loading_name , " Vertexes " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadVertexes ( & header - > lumps [ LUMP_VERTEXES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Edges " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadEdges ( & header - > lumps [ LUMP_EDGES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Surfedges " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadSurfedges ( & header - > lumps [ LUMP_SURFEDGES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Entities " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadEntities ( & header - > lumps [ LUMP_ENTITIES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Textures " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadTextures ( & header - > lumps [ LUMP_TEXTURES ] ) ;
if ( mod - > bspversion = = HL_BSPVERSION | | mod - > bspversion = = NZP_BSPVERSION ) // dr_mabuse1981
{
Mod_HL_LoadLighting ( & header - > lumps [ LUMP_LIGHTING ] ) ;
}
else
{
Mod_LoadLighting ( & header - > lumps [ LUMP_LIGHTING ] ) ;
}
loading_cur_step + + ;
SCR_UpdateScreen ( ) ;
Mod_LoadPlanes ( & header - > lumps [ LUMP_PLANES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Texinfo " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadTexinfo ( & header - > lumps [ LUMP_TEXINFO ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Faces " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadFaces ( & header - > lumps [ LUMP_FACES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Marksurfaces " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadMarksurfaces ( & header - > lumps [ LUMP_MARKSURFACES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Visibility " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadVisibility ( & header - > lumps [ LUMP_VISIBILITY ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Leafs " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadLeafs ( & header - > lumps [ LUMP_LEAFS ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Nodes " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadNodes ( & header - > lumps [ LUMP_NODES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Clipnodes " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadClipnodes ( & header - > lumps [ LUMP_CLIPNODES ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Submodels " ) ;
SCR_UpdateScreen ( ) ;
Mod_LoadSubmodels ( & header - > lumps [ LUMP_MODELS ] ) ;
loading_cur_step + + ;
strcpy ( loading_name , " Hull " ) ;
SCR_UpdateScreen ( ) ;
Mod_MakeHull0 ( ) ;
2022-04-05 15:54:40 +00:00
loading_cur_step + + ;
loading_step = 3 ;
2022-02-08 21:49:56 +00:00
strcpy ( loading_name , " Screen " ) ;
loading_cur_step + + ;
SCR_UpdateScreen ( ) ;
mod - > numframes = 2 ; // regular and alternate animation
//
// set up the submodels (FIXME: this is confusing)
//
for ( i = 0 ; i < mod - > numsubmodels ; i + + )
{
bm = & mod - > submodels [ i ] ;
mod - > hulls [ 0 ] . firstclipnode = bm - > headnode [ 0 ] ;
for ( j = 1 ; j < MAX_MAP_HULLS ; j + + )
{
mod - > hulls [ j ] . firstclipnode = bm - > headnode [ j ] ;
mod - > hulls [ j ] . lastclipnode = mod - > numclipnodes - 1 ;
}
mod - > firstmodelsurface = bm - > firstface ;
mod - > nummodelsurfaces = bm - > numfaces ;
VectorCopy ( bm - > maxs , mod - > maxs ) ;
VectorCopy ( bm - > mins , mod - > mins ) ;
mod - > radius = RadiusFromBounds ( mod - > mins , mod - > maxs ) ;
mod - > numleafs = bm - > visleafs ;
if ( i < mod - > numsubmodels - 1 )
{ // duplicate the basic information
char name [ 10 ] ;
sprintf ( name , " *%i " , i + 1 ) ;
loadmodel = Mod_FindName ( name ) ;
* loadmodel = * mod ;
strcpy ( loadmodel - > name , name ) ;
mod = loadmodel ;
}
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
ALIAS MODELS
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
aliashdr_t * pheader ;
stvert_t stverts [ MAXALIASVERTS ] ;
mtriangle_t triangles [ MAXALIASTRIS ] ;
mh2triangle_t h2triangles [ MAXALIASTRIS ] ;
// a pose is a single set of vertexes. a frame may be
// an animating sequence of poses
trivertx_t * poseverts [ MAXALIASFRAMES ] ;
int posenum ;
byte * * player_8bit_texels_tbl ;
byte * player_8bit_texels ;
/*
= = = = = = = = = = = = = = = = =
Mod_LoadAliasFrame
= = = = = = = = = = = = = = = = =
*/
void * Mod_LoadAliasFrame ( void * pin , maliasframedesc_t * frame )
{
//trivertx_t *pframe;
trivertx_t * pinframe ;
int i ;
//int j;
daliasframe_t * pdaliasframe ;
pdaliasframe = ( daliasframe_t * ) pin ;
strcpy ( frame - > name , pdaliasframe - > name ) ;
frame - > firstpose = posenum ;
frame - > numposes = 1 ;
for ( i = 0 ; i < 3 ; i + + )
{
// these are byte values, so we don't have to worry about
// endianness
frame - > bboxmin . v [ i ] = pdaliasframe - > bboxmin . v [ i ] ;
frame - > bboxmax . v [ i ] = pdaliasframe - > bboxmax . v [ i ] ;
}
pinframe = ( trivertx_t * ) ( pdaliasframe + 1 ) ;
poseverts [ posenum ] = pinframe ;
posenum + + ;
pinframe + = pheader - > numverts ;
return ( void * ) pinframe ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadAliasGroup
= = = = = = = = = = = = = = = = =
*/
void * Mod_LoadAliasGroup ( void * pin , maliasframedesc_t * frame )
{
daliasgroup_t * pingroup ;
int i , numframes ;
daliasinterval_t * pin_intervals ;
void * ptemp ;
pingroup = ( daliasgroup_t * ) pin ;
numframes = LittleLong ( pingroup - > numframes ) ;
frame - > firstpose = posenum ;
frame - > numposes = numframes ;
for ( i = 0 ; i < 3 ; i + + )
{
// these are byte values, so we don't have to worry about endianness
frame - > bboxmin . v [ i ] = pingroup - > bboxmin . v [ i ] ;
frame - > bboxmax . v [ i ] = pingroup - > bboxmax . v [ i ] ;
}
pin_intervals = ( daliasinterval_t * ) ( pingroup + 1 ) ;
frame - > interval = LittleFloat ( pin_intervals - > interval ) ;
pin_intervals + = numframes ;
ptemp = ( void * ) pin_intervals ;
for ( i = 0 ; i < numframes ; i + + )
{
poseverts [ posenum ] = ( trivertx_t * ) ( ( daliasframe_t * ) ptemp + 1 ) ;
posenum + + ;
ptemp = ( trivertx_t * ) ( ( daliasframe_t * ) ptemp + 1 ) + pheader - > numverts ;
}
return ptemp ;
}
//=========================================================
/*
= = = = = = = = = = = = = = = = =
Mod_FloodFillSkin
Fill background pixels so mipmapping doesn ' t have haloes - Ed
= = = = = = = = = = = = = = = = =
*/
typedef struct
{
short x , y ;
} floodfill_t ;
/*
extern unsigned d_8to24table [ ] ;
*/
// must be a power of 2
# define FLOODFILL_FIFO_SIZE 0x1000
# define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1)
# define FLOODFILL_STEP( off, dx, dy ) \
{ \
if ( pos [ off ] = = fillcolor ) \
{ \
pos [ off ] = 255 ; \
fifo [ inpt ] . x = x + ( dx ) , fifo [ inpt ] . y = y + ( dy ) ; \
inpt = ( inpt + 1 ) & FLOODFILL_FIFO_MASK ; \
} \
else if ( pos [ off ] ! = 255 ) fdc = pos [ off ] ; \
}
void Mod_FloodFillSkin ( byte * skin , int skinwidth , int skinheight )
{
byte fillcolor = * skin ; // assume this is the pixel to fill
floodfill_t fifo [ FLOODFILL_FIFO_SIZE ] ;
int inpt = 0 , outpt = 0 ;
int filledcolor = - 1 ;
int i ;
if ( filledcolor = = - 1 )
{
filledcolor = 0 ;
// attempt to find opaque black
for ( i = 0 ; i < 256 ; + + i )
{
if ( d_8to24table [ i ] = = ( 255 < < 0 ) ) // alpha 1.0
{
filledcolor = i ;
break ;
}
}
}
// can't fill to filled color or to transparent color (used as visited marker)
if ( ( fillcolor = = filledcolor ) | | ( fillcolor = = 255 ) )
{
//printf( "not filling skin from %d to %d\n", fillcolor, filledcolor );
return ;
}
fifo [ inpt ] . x = 0 , fifo [ inpt ] . y = 0 ;
inpt = ( inpt + 1 ) & FLOODFILL_FIFO_MASK ;
while ( outpt ! = inpt )
{
int x = fifo [ outpt ] . x , y = fifo [ outpt ] . y ;
int fdc = filledcolor ;
byte * pos = & skin [ x + skinwidth * y ] ;
outpt = ( outpt + 1 ) & FLOODFILL_FIFO_MASK ;
if ( x > 0 ) FLOODFILL_STEP ( - 1 , - 1 , 0 ) ;
if ( x < skinwidth - 1 ) FLOODFILL_STEP ( 1 , 1 , 0 ) ;
if ( y > 0 ) FLOODFILL_STEP ( - skinwidth , 0 , - 1 ) ;
if ( y < skinheight - 1 ) FLOODFILL_STEP ( skinwidth , 0 , 1 ) ;
skin [ x + skinwidth * y ] = fdc ;
}
}
/*
= = = = = = = = = = = = = = =
Mod_LoadAllSkins
= = = = = = = = = = = = = = =
*/
static qboolean mod_h2 ;
void * Mod_LoadAllSkins ( int numskins , daliasskintype_t * pskintype )
{
int i , j , k ;
char name [ 64 ] , model [ 64 ] , model2 [ 64 ] ;
int s ;
//byte *copy;
byte * skin ;
//byte *texels;
daliasskingroup_t * pinskingroup ;
int groupskins ;
daliasskininterval_t * pinskinintervals ;
skin = ( byte * ) ( pskintype + 1 ) ;
if ( numskins < 1 | | numskins > MAX_SKINS )
Sys_Error ( " Mod_LoadAliasModel: Invalid # of skins: %d \n " , numskins ) ;
s = pheader - > skinwidth * pheader - > skinheight ;
/*
if ( ( pheader - > skinwidth & 15 ) | | ( pheader - > skinheight & 15 ) )
Sys_Error ( " Texture %s is not 16 aligned " , name ) ;
*/
for ( i = 0 ; i < numskins ; i + + )
{
if ( pskintype - > type = = ALIAS_SKIN_SINGLE )
{
Mod_FloodFillSkin ( skin , pheader - > skinwidth , pheader - > skinheight ) ;
COM_StripExtension ( loadmodel - > name , model ) ;
sprintf ( model2 , " %s_%i " , model , i ) ;
pheader - > gl_texturenum [ i ] [ 0 ] =
pheader - > gl_texturenum [ i ] [ 1 ] =
pheader - > gl_texturenum [ i ] [ 2 ] =
pheader - > gl_texturenum [ i ] [ 3 ] = loadtextureimage ( model2 , 0 , 0 , qfalse , GU_LINEAR ) ;
if ( pheader - > gl_texturenum [ i ] [ 0 ] = = 0 ) // did not find a matching TGA...
{
sprintf ( name , " %s_%i " , loadmodel - > name , i ) ;
if ( mod_h2 )
{
pheader - > gl_texturenum [ i ] [ 0 ] =
pheader - > gl_texturenum [ i ] [ 1 ] =
pheader - > gl_texturenum [ i ] [ 2 ] =
pheader - > gl_texturenum [ i ] [ 3 ] =
GL_LoadPalTex ( name , pheader - > skinwidth , pheader - > skinheight , ( byte * ) ( pskintype + 1 ) , qtrue , GU_LINEAR , 0 , NULL , PAL_H2 ) ;
}
else
{
pheader - > gl_texturenum [ i ] [ 0 ] =
pheader - > gl_texturenum [ i ] [ 1 ] =
pheader - > gl_texturenum [ i ] [ 2 ] =
pheader - > gl_texturenum [ i ] [ 3 ] =
GL_LoadTexture ( name , pheader - > skinwidth , pheader - > skinheight , ( byte * ) ( pskintype + 1 ) , qtrue , GU_LINEAR , 0 ) ;
}
}
pskintype = ( daliasskintype_t * ) ( ( byte * ) ( pskintype + 1 ) + s ) ;
/* Crow_bar Memory Leak Fixed One Work not used */
mapTextureNameList . push_back ( pheader - > gl_texturenum [ i ] [ i ] ) ;
/* Crow_bar Memory Leak Fixed */
}
else
{
// animating skin group. yuck.
pskintype + + ;
pinskingroup = ( daliasskingroup_t * ) pskintype ;
groupskins = LittleLong ( pinskingroup - > numskins ) ;
pinskinintervals = ( daliasskininterval_t * ) ( pinskingroup + 1 ) ;
pskintype = reinterpret_cast < daliasskintype_t * > ( pinskinintervals + groupskins ) ;
for ( j = 0 ; j < groupskins ; j + + )
{
Mod_FloodFillSkin ( skin , pheader - > skinwidth , pheader - > skinheight ) ;
COM_StripExtension ( loadmodel - > name , model ) ;
sprintf ( model2 , " %s_%i_%i " , model , i , j ) ;
pheader - > gl_texturenum [ i ] [ j & 3 ] =
loadtextureimage ( model2 , 0 , 0 , qfalse , GU_LINEAR ) ;
if ( pheader - > gl_texturenum [ i ] [ j & 3 ] = = 0 ) // did not find a matching TGA...
{
sprintf ( name , " %s_%i_%i " , loadmodel - > name , i , j ) ;
if ( mod_h2 )
{
pheader - > gl_texturenum [ i ] [ j & 3 ] =
GL_LoadPalTex ( name , pheader - > skinwidth , pheader - > skinheight , ( byte * ) ( pskintype ) , qtrue , GU_LINEAR , 0 , NULL , PAL_H2 ) ;
}
else
{
pheader - > gl_texturenum [ i ] [ j & 3 ] =
GL_LoadTexture ( name , pheader - > skinwidth , pheader - > skinheight , ( byte * ) ( pskintype ) , qtrue , GU_LINEAR , 0 ) ;
}
}
pskintype = ( daliasskintype_t * ) ( ( byte * ) ( pskintype ) + s ) ;
/* Crow_bar Memory Leak Fixed*/
mapTextureNameList . push_back ( pheader - > gl_texturenum [ i ] [ j & 3 ] ) ;
/* Crow_bar Memory Leak Fixed*/
}
k = j ;
for ( /* */ ; j < 4 ; j + + )
pheader - > gl_texturenum [ i ] [ j & 3 ] = pheader - > gl_texturenum [ i ] [ j - k ] ;
}
}
return ( void * ) pskintype ;
}
//=========================================================================
/*
= = = = = = = = = = = = = = = = =
Mod_LoadAliasModel
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadAliasModel ( model_t * mod , void * buffer )
{
int i , j ;
mdl_t * pinmodel ;
stvert_t * pinstverts ;
dtriangle_t * pintriangles ;
int version , numframes ; //numskins;
int size ;
daliasframetype_t * pframetype ;
daliasskintype_t * pskintype ;
int start , end , total ;
// some models are special
// NOTE: comparing not only with player.mdl, but with all models
// begin with "player" coz we need to support DME models as well!
if ( ! strncmp ( mod - > name , " progs/player " , 12 ) )
mod - > modhint = MOD_PLAYER ;
else if ( ! strcmp ( mod - > name , " progs/eyes.mdl " ) )
mod - > modhint = MOD_EYES ;
else if ( ! strcmp ( mod - > name , " progs/flame0.mdl " ) | |
! strcmp ( mod - > name , " progs/flame.mdl " ) | |
! strcmp ( mod - > name , " progs/flame2.mdl " ) )
mod - > modhint = MOD_FLAME ;
else if ( ! strcmp ( mod - > name , " progs/bolt.mdl " ) | |
! strcmp ( mod - > name , " progs/bolt2.mdl " ) | |
! strcmp ( mod - > name , " progs/bolt3.mdl " ) )
mod - > modhint = MOD_THUNDERBOLT ;
else if ( ! strcmp ( mod - > name , " progs/VModels/v_Colt.mdl " ) | | //JUKKI Add nzp weapons here please plox
! strcmp ( mod - > name , " progs/VModels/v_kar.mdl " ) | |
! strcmp ( mod - > name , " progs/VModels/v_thomp.mdl " ) )
mod - > modhint = MOD_WEAPON ;
else if ( ! strcmp ( mod - > name , " progs/lavaball.mdl " ) )
mod - > modhint = MOD_LAVABALL ;
else if ( ! strcmp ( mod - > name , " progs/spike.mdl " ) | |
! strcmp ( mod - > name , " progs/s_spike.mdl " ) )
mod - > modhint = MOD_SPIKE ;
else if ( ! strcmp ( mod - > name , " progs/shambler.mdl " ) )
mod - > modhint = MOD_SHAMBLER ;
else
mod - > modhint = MOD_NORMAL ;
start = Hunk_LowMark ( ) ;
pinmodel = ( mdl_t * ) buffer ;
version = LittleLong ( pinmodel - > version ) ;
if ( version ! = ALIAS_VERSION )
Sys_Error ( " %s has wrong version number (%i should be %i) " ,
mod - > name , version , ALIAS_VERSION ) ;
//
// allocate space for a working header, plus all the data except the frames,
// skin and group info
//
size = sizeof ( aliashdr_t )
+ ( LittleLong ( pinmodel - > numframes ) - 1 ) *
sizeof ( pheader - > frames [ 0 ] ) ;
pheader = static_cast < aliashdr_t * > ( Hunk_AllocName ( size , loadname ) ) ;
mod - > flags = LittleLong ( pinmodel - > flags ) ;
//
// endian-adjust and copy the data, starting with the alias model header
//
pheader - > boundingradius = LittleFloat ( pinmodel - > boundingradius ) ;
pheader - > numskins = LittleLong ( pinmodel - > numskins ) ;
pheader - > skinwidth = LittleLong ( pinmodel - > skinwidth ) ;
pheader - > skinheight = LittleLong ( pinmodel - > skinheight ) ;
if ( pheader - > skinheight > MAX_LBM_HEIGHT )
Sys_Error ( " model %s has a skin taller than %d " , mod - > name ,
MAX_LBM_HEIGHT ) ;
pheader - > numverts = LittleLong ( pinmodel - > numverts ) ;
if ( pheader - > numverts < = 0 )
Sys_Error ( " model %s has no vertices " , mod - > name ) ;
if ( pheader - > numverts > MAXALIASVERTS )
Sys_Error ( " model %s has too many vertices " , mod - > name ) ;
pheader - > numtris = LittleLong ( pinmodel - > numtris ) ;
if ( pheader - > numtris < = 0 )
Sys_Error ( " model %s has no triangles " , mod - > name ) ;
pheader - > numframes = LittleLong ( pinmodel - > numframes ) ;
numframes = pheader - > numframes ;
if ( numframes < 1 )
Sys_Error ( " Mod_LoadAliasModel: Invalid # of frames: %d \n " , numframes ) ;
pheader - > size = LittleFloat ( pinmodel - > size ) * ALIAS_BASE_SIZE_RATIO ;
mod - > synctype = static_cast < synctype_t > ( LittleLong ( pinmodel - > synctype ) ) ;
mod - > numframes = pheader - > numframes ;
for ( i = 0 ; i < 3 ; i + + )
{
pheader - > scale [ i ] = LittleFloat ( pinmodel - > scale [ i ] ) ;
pheader - > scale_origin [ i ] = LittleFloat ( pinmodel - > scale_origin [ i ] ) ;
pheader - > eyeposition [ i ] = LittleFloat ( pinmodel - > eyeposition [ i ] ) ;
}
//
// load the skins
//
pskintype = ( daliasskintype_t * ) & pinmodel [ 1 ] ;
pskintype = static_cast < daliasskintype_t * > ( Mod_LoadAllSkins ( pheader - > numskins , pskintype ) ) ;
//
// load base s and t vertices
//
pinstverts = ( stvert_t * ) pskintype ;
for ( i = 0 ; i < pheader - > numverts ; i + + )
{
stverts [ i ] . onseam = LittleLong ( pinstverts [ i ] . onseam ) ;
stverts [ i ] . s = LittleLong ( pinstverts [ i ] . s ) ;
stverts [ i ] . t = LittleLong ( pinstverts [ i ] . t ) ;
}
//
// load triangle lists
//
pintriangles = ( dtriangle_t * ) & pinstverts [ pheader - > numverts ] ;
for ( i = 0 ; i < pheader - > numtris ; i + + )
{
triangles [ i ] . facesfront = LittleLong ( pintriangles [ i ] . facesfront ) ;
for ( j = 0 ; j < 3 ; j + + )
{
triangles [ i ] . vertindex [ j ] = LittleLong ( pintriangles [ i ] . vertindex [ j ] ) ;
}
}
//
// load the frames
//
posenum = 0 ;
pframetype = ( daliasframetype_t * ) & pintriangles [ pheader - > numtris ] ;
//maliasframedesc_t *frame0;
for ( i = 0 ; i < numframes ; i + + )
{
aliasframetype_t frametype ;
frametype = static_cast < aliasframetype_t > ( LittleLong ( pframetype - > type ) ) ;
/*if(i == 0)//see this right here? blubs can type, but something is a-miss with the precalculated mdl min and max values, so let's not use this.
{
frame0 = & pheader - > frames [ 0 ] ;
mod - > mins [ 0 ] = frame0 - > bboxmin . v [ 0 ] ;
mod - > mins [ 1 ] = frame0 - > bboxmin . v [ 1 ] ;
mod - > mins [ 2 ] = frame0 - > bboxmin . v [ 2 ] ;
mod - > maxs [ 0 ] = frame0 - > bboxmax . v [ 0 ] ;
mod - > maxs [ 1 ] = frame0 - > bboxmax . v [ 1 ] ;
mod - > maxs [ 2 ] = frame0 - > bboxmax . v [ 2 ] ;
} */
if ( frametype = = ALIAS_SINGLE )
{
pframetype = ( daliasframetype_t * )
Mod_LoadAliasFrame ( pframetype + 1 , & pheader - > frames [ i ] ) ;
}
else
{
pframetype = ( daliasframetype_t * )
Mod_LoadAliasGroup ( pframetype + 1 , & pheader - > frames [ i ] ) ;
}
}
pheader - > numposes = posenum ;
mod - > type = mod_alias ;
// FIXME: do this right
mod - > mins [ 0 ] = mod - > mins [ 1 ] = mod - > mins [ 2 ] = - 32 ;
mod - > maxs [ 0 ] = mod - > maxs [ 1 ] = mod - > maxs [ 2 ] = 32 ;
//
// build the draw lists
//
GL_MakeAliasModelDisplayLists ( mod , pheader ) ;
//
// move the complete, relocatable alias model to the cache
//
end = Hunk_LowMark ( ) ;
total = end - start ;
Cache_Alloc ( & mod - > cache , total , loadname ) ;
if ( ! mod - > cache . data )
return ;
memcpy ( mod - > cache . data , pheader , total ) ;
Hunk_FreeToLowMark ( start ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadAliasH2Model
reads extra field for num ST verts , and extra index list of them
Hexen II model format
= = = = = = = = = = = = = = = = =
*/
void GL_MakeAliasModelDisplayListsH2 ( model_t * m , aliashdr_t * hdr ) ;
void Mod_LoadH2AliasModel ( model_t * mod , void * buffer )
{
int i , j ;
newmdl_t * pinmodel ;
stvert_t * pinstverts ;
dnewtriangle_t * pintriangles ;
int version , numframes ; //, numskins;
int size ;
daliasframetype_t * pframetype ;
daliasskintype_t * pskintype ;
int start , end , total ;
start = Hunk_LowMark ( ) ;
pinmodel = ( newmdl_t * ) buffer ;
version = LittleLong ( pinmodel - > version ) ;
if ( version ! = ALIAS_NEWVERSION )
Sys_Error ( " %s has wrong version number (%i should be %i) " ,
mod - > name , version , ALIAS_NEWVERSION ) ;
//
// allocate space for a working header, plus all the data except the frames,
// skin and group info
//
size = sizeof ( aliashdr_t )
+ ( LittleLong ( pinmodel - > numframes ) - 1 ) *
sizeof ( pheader - > frames [ 0 ] ) ;
pheader = static_cast < aliashdr_t * > ( Hunk_AllocName ( size , loadname ) ) ;
mod - > flags = LittleLong ( pinmodel - > flags ) ;
//
// endian-adjust and copy the data, starting with the alias model header
//
pheader - > boundingradius = LittleFloat ( pinmodel - > boundingradius ) ;
pheader - > numskins = LittleLong ( pinmodel - > numskins ) ;
pheader - > skinwidth = LittleLong ( pinmodel - > skinwidth ) ;
pheader - > skinheight = LittleLong ( pinmodel - > skinheight ) ;
//if (pheader->skinheight > MAX_LBM_HEIGHT)
// Sys_Error ("model %s has a skin taller than %d", mod->name,
// MAX_LBM_HEIGHT);
pheader - > numverts = LittleLong ( pinmodel - > numverts ) ;
pheader - > version = LittleLong ( pinmodel - > num_st_verts ) ; //hide num_st in version
if ( pheader - > numverts < = 0 )
Sys_Error ( " model %s has no vertices " , mod - > name ) ;
if ( pheader - > numverts > MAXALIASVERTS )
Sys_Error ( " model %s has too many vertices " , mod - > name ) ;
pheader - > numtris = LittleLong ( pinmodel - > numtris ) ;
if ( pheader - > numtris < = 0 )
Sys_Error ( " model %s has no triangles " , mod - > name ) ;
pheader - > numframes = LittleLong ( pinmodel - > numframes ) ;
numframes = pheader - > numframes ;
if ( numframes < 1 )
Sys_Error ( " Mod_LoadAliasModel: Invalid # of frames: %d \n " , numframes ) ;
pheader - > size = LittleFloat ( pinmodel - > size ) * ALIAS_BASE_SIZE_RATIO ;
mod - > synctype = static_cast < synctype_t > ( LittleLong ( pinmodel - > synctype ) ) ;
mod - > numframes = pheader - > numframes ;
for ( i = 0 ; i < 3 ; i + + )
{
pheader - > scale [ i ] = LittleFloat ( pinmodel - > scale [ i ] ) ;
pheader - > scale_origin [ i ] = LittleFloat ( pinmodel - > scale_origin [ i ] ) ;
pheader - > eyeposition [ i ] = LittleFloat ( pinmodel - > eyeposition [ i ] ) ;
}
/*
//
// load the skins
//
pskintype = ( daliasskintype_t * ) & pinmodel [ 1 ] ;
pskintype = static_cast < daliasskintype_t * > ( Mod_LoadAllSkins ( pheader - > numskins , pskintype , mod - > flags ) ) ;
*/
mod_h2 = qtrue ;
pskintype = ( daliasskintype_t * ) & pinmodel [ 1 ] ;
pskintype = static_cast < daliasskintype_t * > ( Mod_LoadAllSkins ( pheader - > numskins , pskintype ) ) ;
mod_h2 = qfalse ;
//
// load base s and t vertices
//
pinstverts = ( stvert_t * ) pskintype ;
for ( i = 0 ; i < pheader - > version ; i + + ) //version holds num_st_verts
{
stverts [ i ] . onseam = LittleLong ( pinstverts [ i ] . onseam ) ;
stverts [ i ] . s = LittleLong ( pinstverts [ i ] . s ) ;
stverts [ i ] . t = LittleLong ( pinstverts [ i ] . t ) ;
}
//
// load triangle lists
//
pintriangles = ( dnewtriangle_t * ) & pinstverts [ pheader - > version ] ;
for ( i = 0 ; i < pheader - > numtris ; i + + )
{
triangles [ i ] . facesfront = LittleLong ( pintriangles [ i ] . facesfront ) ;
for ( j = 0 ; j < 3 ; j + + )
{
h2triangles [ i ] . vertindex [ j ] = LittleShort ( pintriangles [ i ] . vertindex [ j ] ) ;
h2triangles [ i ] . stindex [ j ] = LittleShort ( pintriangles [ i ] . stindex [ j ] ) ;
}
}
//
// load the frames
//
posenum = 0 ;
pframetype = ( daliasframetype_t * ) & pintriangles [ pheader - > numtris ] ;
for ( i = 0 ; i < numframes ; i + + )
{
aliasframetype_t frametype ;
frametype = static_cast < aliasframetype_t > ( LittleLong ( pframetype - > type ) ) ;
if ( frametype = = ALIAS_SINGLE )
{
pframetype = ( daliasframetype_t * )
Mod_LoadAliasFrame ( pframetype + 1 , & pheader - > frames [ i ] ) ;
}
else
{
pframetype = ( daliasframetype_t * )
Mod_LoadAliasGroup ( pframetype + 1 , & pheader - > frames [ i ] ) ;
}
}
pheader - > numposes = posenum ;
mod - > type = mod_alias ;
// FIXME: do this right
mod - > mins [ 0 ] = mod - > mins [ 1 ] = mod - > mins [ 2 ] = - 16 ;
mod - > maxs [ 0 ] = mod - > maxs [ 1 ] = mod - > maxs [ 2 ] = 16 ;
//
// build the draw lists
//
GL_MakeAliasModelDisplayListsH2 ( mod , pheader ) ;
//
// move the complete, relocatable alias model to the cache
//
end = Hunk_LowMark ( ) ;
total = end - start ;
Cache_Alloc ( & mod - > cache , total , loadname ) ;
if ( ! mod - > cache . data )
return ;
memcpy ( mod - > cache . data , pheader , total ) ;
Hunk_FreeToLowMark ( start ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadQ2AliasModel
= = = = = = = = = = = = = = = = =
*/
int loadtextureimage ( char * filename , int matchwidth , int matchheight , qboolean complain , int filter ) ;
void Mod_LoadQ2AliasModel ( model_t * mod , void * buffer )
{
//int numskins;
int i , j , version , numframes , size , * pinglcmd , * poutglcmd , start , end , total ;
md2_t * pinmodel , * pheader ;
md2triangle_t * pintriangles , * pouttriangles ;
md2frame_t * pinframe , * poutframe ;
char * pinskins ;
//char skinname[256], *skinnamebase;
start = Hunk_LowMark ( ) ;
pinmodel = ( md2_t * ) buffer ;
version = LittleLong ( pinmodel - > version ) ;
if ( version ! = MD2ALIAS_VERSION )
Sys_Error ( " %s has wrong version number (%i should be %i) " ,
mod - > name , version , MD2ALIAS_VERSION ) ;
mod - > type = mod_alias ;
mod - > aliastype = ALIASTYPE_MD2 ;
// LordHavoc: see pheader ofs adjustment code below for why this is bigger
size = LittleLong ( pinmodel - > ofs_end ) + sizeof ( md2_t ) ;
if ( size < = 0 | | size > = MD2MAX_SIZE )
Sys_Error ( " %s is not a valid model " , mod - > name ) ;
pheader = static_cast < md2_t * > ( Hunk_AllocName ( size , loadname ) ) ;
mod - > flags = 0 ; // there are no MD2 flags
// endian-adjust and copy the data, starting with the alias model header
for ( i = 0 ; i < 17 ; i + + ) // LordHavoc: err... FIXME or something...
( ( int * ) pheader ) [ i ] = LittleLong ( ( ( int * ) pinmodel ) [ i ] ) ;
mod - > numframes = numframes = pheader - > num_frames ;
mod - > synctype = ST_RAND ;
if ( pheader - > ofs_skins < = 0 | | pheader - > ofs_skins > = pheader - > ofs_end )
Sys_Error ( " %s is not a valid model " , mod - > name ) ;
if ( pheader - > ofs_st < = 0 | | pheader - > ofs_st > = pheader - > ofs_end )
Sys_Error ( " %s is not a valid model " , mod - > name ) ;
if ( pheader - > ofs_tris < = 0 | | pheader - > ofs_tris > = pheader - > ofs_end )
Sys_Error ( " %s is not a valid model " , mod - > name ) ;
if ( pheader - > ofs_frames < = 0 | | pheader - > ofs_frames > = pheader - > ofs_end )
Sys_Error ( " %s is not a valid model " , mod - > name ) ;
if ( pheader - > ofs_glcmds < = 0 | | pheader - > ofs_glcmds > = pheader - > ofs_end )
Sys_Error ( " %s is not a valid model " , mod - > name ) ;
if ( pheader - > num_tris < 1 | | pheader - > num_tris > MD2MAX_TRIANGLES )
Sys_Error ( " %s has invalid number of triangles: %i " , mod - > name , pheader - > num_tris ) ;
if ( pheader - > num_xyz < 1 | | pheader - > num_xyz > MD2MAX_VERTS )
Sys_Error ( " %s has invalid number of vertices: %i " , mod - > name , pheader - > num_xyz ) ;
if ( pheader - > num_frames < 1 | | pheader - > num_frames > 256 ) //MD2MAX_FRAMES)
Sys_Error ( " %s has invalid number of frames: %i " , mod - > name , pheader - > num_frames ) ;
if ( pheader - > num_skins < 0 | | pheader - > num_skins > MD2MAX_SKINS )
Sys_Error ( " %s has invalid number of skins: %i " , mod - > name , pheader - > num_skins ) ;
// LordHavoc: adjust offsets in new model to give us some room for the bigger header
// cheap offsetting trick, just offset it all by the pheader size...mildly wasteful
for ( i = 0 ; i < 7 ; i + + )
( ( int * ) & pheader - > ofs_skins ) [ i ] + = sizeof ( pheader ) ;
// load the skins
if ( pheader - > num_skins )
{
pinskins = static_cast < char * > ( ( void * ) ( ( int ) pinmodel + LittleLong ( pinmodel - > ofs_skins ) ) ) ;
for ( i = 0 ; i < pheader - > num_skins ; i + + )
{
pheader - > gl_texturenum [ i ] = loadtextureimage ( pinskins , 0 , 0 , qtrue , GU_LINEAR ) ;
pinskins + = MD2MAX_SKINNAME ;
/* Crow_bar Memory Leak Fixed */
mapTextureNameList . push_back ( pheader - > gl_texturenum [ i ] ) ;
/* Crow_bar Memory Leak Fixed */
}
}
// load triangles
pintriangles = static_cast < md2triangle_t * > ( ( void * ) ( ( int ) pinmodel + LittleLong ( pinmodel - > ofs_tris ) ) ) ;
pouttriangles = static_cast < md2triangle_t * > ( ( void * ) ( ( int ) pheader + pheader - > ofs_tris ) ) ;
// swap the triangle list
for ( i = 0 ; i < pheader - > num_tris ; i + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
pouttriangles - > index_xyz [ j ] = LittleShort ( pintriangles - > index_xyz [ j ] ) ;
pouttriangles - > index_st [ j ] = LittleShort ( pintriangles - > index_st [ j ] ) ;
if ( pouttriangles - > index_xyz [ j ] > = pheader - > num_xyz )
Sys_Error ( " %s has invalid vertex indices " , mod - > name ) ;
if ( pouttriangles - > index_st [ j ] > = pheader - > num_st )
Sys_Error ( " %s has invalid vertex indices " , mod - > name ) ;
}
pintriangles + + ;
pouttriangles + + ;
}
//
// load the frames
//
pinframe = static_cast < md2frame_t * > ( ( void * ) ( ( int ) pinmodel + LittleLong ( pinmodel - > ofs_frames ) ) ) ;
poutframe = static_cast < md2frame_t * > ( ( void * ) ( ( int ) pheader + pheader - > ofs_frames ) ) ;
for ( i = 0 ; i < numframes ; i + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
poutframe - > scale [ j ] = LittleFloat ( pinframe - > scale [ j ] ) ;
poutframe - > translate [ j ] = LittleFloat ( pinframe - > translate [ j ] ) ;
}
for ( j = 0 ; j < 16 ; j + + )
poutframe - > name [ j ] = pinframe - > name [ j ] ;
for ( j = 0 ; j < pheader - > num_xyz ; j + + )
{
poutframe - > verts [ j ] . v [ 0 ] = pinframe - > verts [ j ] . v [ 0 ] ;
poutframe - > verts [ j ] . v [ 1 ] = pinframe - > verts [ j ] . v [ 1 ] ;
poutframe - > verts [ j ] . v [ 2 ] = pinframe - > verts [ j ] . v [ 2 ] ;
poutframe - > verts [ j ] . lightnormalindex = pinframe - > verts [ j ] . lightnormalindex ;
}
pinframe = static_cast < md2frame_t * > ( ( void * ) & pinframe - > verts [ j ] . v [ 0 ] ) ;
poutframe = static_cast < md2frame_t * > ( ( void * ) & poutframe - > verts [ j ] . v [ 0 ] ) ;
}
// LordHavoc: I may fix this at some point
mod - > mins [ 0 ] = mod - > mins [ 1 ] = mod - > mins [ 2 ] = - 64 ;
mod - > maxs [ 0 ] = mod - > maxs [ 1 ] = mod - > maxs [ 2 ] = 64 ;
// load the draw list
pinglcmd = static_cast < int * > ( ( void * ) ( ( int ) pinmodel + LittleLong ( pinmodel - > ofs_glcmds ) ) ) ;
poutglcmd = static_cast < int * > ( ( void * ) ( ( int ) pheader + pheader - > ofs_glcmds ) ) ;
for ( i = 0 ; i < pheader - > num_glcmds ; i + + )
* poutglcmd + + = LittleLong ( * pinglcmd + + ) ;
// move the complete, relocatable alias model to the cache
end = Hunk_LowMark ( ) ;
total = end - start ;
Cache_Alloc ( & mod - > cache , total , loadname ) ;
if ( ! mod - > cache . data )
return ;
memcpy ( mod - > cache . data , pheader , total ) ;
Hunk_FreeToLowMark ( start ) ;
}
//=============================================================================
//========================Q3 Models============================================
//=============================================================================
//additional skin loading
char * * skinfilelist ;
int skinfilecount ;
static qboolean Mod_TryAddSkin ( char * skinname , . . . )
{
va_list argptr ;
char string [ MAX_QPATH ] ;
//make sure we don't add it twice
int i ;
va_start ( argptr , skinname ) ;
vsnprintf ( string , sizeof ( string ) - 1 , skinname , argptr ) ;
va_end ( argptr ) ;
string [ MAX_QPATH - 1 ] = ' \0 ' ;
for ( i = 0 ; i < skinfilecount ; i + + )
{
if ( ! strcmp ( skinfilelist [ i ] , string ) )
return qtrue ; //already added
}
//if (!COM_FCheckExists(string))
// return false;
if ( ! Sys_FileTime ( string ) )
return qfalse ;
skinfilelist = static_cast < char * * > ( realloc ( skinfilelist , sizeof ( * skinfilelist ) * ( skinfilecount + 1 ) ) ) ;
skinfilelist [ skinfilecount ] = static_cast < char * > ( malloc ( strlen ( string ) + 1 ) ) ;
strcpy ( skinfilelist [ skinfilecount ] , string ) ;
skinfilecount + + ;
return qtrue ;
}
int Mod_BuildSkinFileList ( char * modelname )
{
int i ;
char skinfilename [ MAX_QPATH ] ;
//flush the old list
for ( i = 0 ; i < skinfilecount ; i + + )
{
Z_Free ( skinfilelist [ i ] ) ;
skinfilelist [ i ] = NULL ;
}
skinfilecount = 0 ;
COM_StripExtension ( modelname , skinfilename ) ;
//try and add numbered skins, and then try fixed names.
for ( i = 0 ; ; i + + )
{
if ( ! Mod_TryAddSkin ( " %s_%i.skin " , modelname , i ) )
{
if ( i = = 0 )
{
if ( ! Mod_TryAddSkin ( " %s_default.skin " , skinfilename , i ) )
break ;
}
else if ( i = = 1 )
{
if ( ! Mod_TryAddSkin ( " %s_blue.skin " , skinfilename , i ) )
break ;
}
else if ( i = = 2 )
{
if ( ! Mod_TryAddSkin ( " %s_red.skin " , skinfilename , i ) )
break ;
}
else if ( i = = 3 )
{
if ( ! Mod_TryAddSkin ( " %s_green.skin " , skinfilename , i ) )
break ;
}
else if ( i = = 4 )
{
if ( ! Mod_TryAddSkin ( " %s_yellow.skin " , skinfilename , i ) )
break ;
}
else
break ;
}
}
return skinfilecount ;
}
animdata_t anims [ NUM_ANIMTYPES ] ;
vec3_t md3bboxmins , md3bboxmaxs ;
void Mod_GetQ3AnimData ( char * buf , char * animtype , animdata_t * adata )
{
int i , j , data [ 4 ] ;
char * token , num [ 4 ] ;
if ( ( token = strstr ( buf , animtype ) ) )
{
while ( * token ! = ' \n ' )
token - - ;
token + + ; // so we jump back to the first char
for ( i = 0 ; i < 4 ; i + + )
{
memset ( num , 0 , sizeof ( num ) ) ;
for ( j = 0 ; * token ! = ' \t ' ; j + + )
num [ j ] = * token + + ;
data [ i ] = Q_atoi ( num ) ;
token + + ;
}
adata - > offset = data [ 0 ] ;
adata - > num_frames = data [ 1 ] ;
adata - > loop_frames = data [ 2 ] ;
adata - > interval = 1.0 / ( float ) data [ 3 ] ;
}
}
void Mod_LoadQ3Animation ( void )
{
int ofs_legs ;
char * animdata ;
animdata_t tmp1 , tmp2 ;
tmp1 . offset = 0 ;
tmp2 . offset = 0 ;
if ( ! ( animdata = ( char * ) COM_LoadFile ( " progs/player/animation.cfg " , 0 ) ) )
{
Con_Printf ( " ERROR: Couldn't open animation file \n " ) ;
return ;
}
memset ( anims , 0 , sizeof ( anims ) ) ;
Mod_GetQ3AnimData ( animdata , " BOTH_DEATH1 " , & anims [ both_death1 ] ) ;
Mod_GetQ3AnimData ( animdata , " BOTH_DEATH2 " , & anims [ both_death2 ] ) ;
Mod_GetQ3AnimData ( animdata , " BOTH_DEATH3 " , & anims [ both_death3 ] ) ;
Mod_GetQ3AnimData ( animdata , " BOTH_DEAD1 " , & anims [ both_dead1 ] ) ;
Mod_GetQ3AnimData ( animdata , " BOTH_DEAD2 " , & anims [ both_dead2 ] ) ;
Mod_GetQ3AnimData ( animdata , " BOTH_DEAD3 " , & anims [ both_dead3 ] ) ;
Mod_GetQ3AnimData ( animdata , " TORSO_ATTACK " , & anims [ torso_attack ] ) ;
Mod_GetQ3AnimData ( animdata , " TORSO_ATTACK2 " , & anims [ torso_attack2 ] ) ;
Mod_GetQ3AnimData ( animdata , " TORSO_STAND " , & anims [ torso_stand ] ) ;
Mod_GetQ3AnimData ( animdata , " TORSO_STAND2 " , & anims [ torso_stand2 ] ) ;
Mod_GetQ3AnimData ( animdata , " TORSO_GESTURE " , & tmp1 ) ;
Mod_GetQ3AnimData ( animdata , " LEGS_WALKCR " , & tmp2 ) ;
// we need to subtract the torso-only frames to get the correct indices
ofs_legs = tmp2 . offset - tmp1 . offset ;
Mod_GetQ3AnimData ( animdata , " LEGS_WALK " , & anims [ legs_walk ] ) ; //R00k
Mod_GetQ3AnimData ( animdata , " LEGS_RUN " , & anims [ legs_run ] ) ;
Mod_GetQ3AnimData ( animdata , " LEGS_IDLE " , & anims [ legs_idle ] ) ;
anims [ legs_walk ] . offset - = ofs_legs ;
anims [ legs_run ] . offset - = ofs_legs ;
anims [ legs_idle ] . offset - = ofs_legs ;
Z_Free ( animdata ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadQ3ModelTexture
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadQ3ModelTexture ( char * identifier , int flags , int * gl_texnum )
{
char loadpath [ 64 ] ;
Q_snprintfz ( loadpath , sizeof ( loadpath ) , " textures/q3models/%s " , identifier ) ;
* gl_texnum = loadtextureimage ( loadpath , 0 , 0 , qtrue , GU_LINEAR ) ;
if ( ! * gl_texnum )
{
Q_snprintfz ( loadpath , sizeof ( loadpath ) , " textures/%s " , identifier ) ;
* gl_texnum = loadtextureimage ( loadpath , 0 , 0 , qtrue , GU_LINEAR ) ;
}
if ( ! * gl_texnum )
{
Q_snprintfz ( loadpath , sizeof ( loadpath ) , " progs/%s " , identifier ) ;
* gl_texnum = loadtextureimage ( loadpath , 0 , 0 , qtrue , GU_LINEAR ) ;
}
if ( ! * gl_texnum )
{
Q_snprintfz ( loadpath , sizeof ( loadpath ) , " maps/%s " , identifier ) ;
* gl_texnum = loadtextureimage ( loadpath , 0 , 0 , qtrue , GU_LINEAR ) ;
}
mapTextureNameList . push_back ( * gl_texnum ) ;
}
//==============================================================================
# define CLASSIC_MAX_QPATH 64
typedef struct
{
char name [ CLASSIC_MAX_QPATH ] ;
int filepos , filelen ;
} packfile_t ;
typedef struct pack_s
{
char filename [ MAX_OSPATH ] ;
int handle ;
int numfiles ;
packfile_t * files ;
} pack_t ;
typedef struct searchpath_s
{
char filename [ MAX_OSPATH ] ;
pack_t * pack ; // only one of filename / pack will be used
struct searchpath_s * next ;
} searchpath_t ;
extern char loadname [ 32 ] ; // for hunk tags
typedef struct searchpath_s searchpath_t ;
extern searchpath_t * com_searchpaths ;
//==============================================================================
/*
= = = = = = = = = = = = = = = = =
Mod_LoadAllQ3Skins
supporting only the default skin yet
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadAllQ3Skins ( char * modelname , md3header_t * header )
{
#if 0
int i , j , defaultskin , numskinsfound ;
char skinname [ MAX_QPATH ] , * * skinsfound ;
md3surface_t * surf ;
md3shader_t * shader ;
searchpath_t * search ;
i = strrchr ( modelname , ' / ' ) - modelname ;
Q_strncpyz ( skinname , modelname , i + 1 ) ;
/*
//EraseDirEntries ();
for ( search = com_searchpaths ; search ; search = search - > next )
{
if ( ! search - > pack )
{
RDFlags | = RD_NOERASE ;
ReadDir ( va ( " %s/%s " , search - > filename , skinname ) , va ( " %s*.skin " , loadname ) ) ;
}
}
numskinsfound = num_files ;
skinsfound = ( char * * ) malloc ( numskinsfound * sizeof ( char * ) ) ;
for ( i = 0 ; i < numskinsfound ; i + + )
{
skinsfound [ i ] = static_cast < char * > ( malloc ( MAX_QPATH ) ) ;
Q_snprintfz ( skinsfound [ i ] , MAX_QPATH , " %s/%s " , skinname , i ) ;
}
*/
SceUID dir = sceIoDopen ( va ( " %s/models/%s " , com_gamedir , skinname ) ) ;
if ( dir < 0 )
{
return ;
}
SceIoDirent dirent ;
memset ( & dirent , 0 , sizeof ( SceIoDirent ) ) ;
while ( sceIoDread ( dir , & dirent ) > 0 )
{
if ( dirent . d_name [ 0 ] = = ' . ' )
{
continue ;
}
if ( ! strcmp ( COM_FileExtension ( dirent . d_name ) , " .skin " ) | |
! strcmp ( COM_FileExtension ( dirent . d_name ) , " .SKIN " ) )
{
}
}
// It only works this lame way coz if I snprintf to skinname from skinname
// then linux's vsnprintf clears out skinname first and it's gonna lost
Q_strncpyz ( skinname , va ( " %s/%s " , skinname , loadname ) , MAX_QPATH ) ;
defaultskin = - 1 ;
for ( i = 0 ; i < numskinsfound ; i + + )
{
if ( ! strcmp ( skinsfound [ i ] , va ( " %s_default.skin " , skinname ) ) )
{
defaultskin = i ;
break ;
}
}
Con_Printf ( " Load skindata: %s \n " , skinname ) ;
Con_Printf ( " Load to: %s \n " , defaultskin ) ;
// load default skin if exists
if ( defaultskin ! = - 1 )
{
int pos ;
char * token , * skindata ;
skindata = ( char * ) COM_LoadFile ( skinname , 0 ) ;
pos = 0 ;
while ( pos < com_filesize )
{
token = & skindata [ pos ] ;
while ( skindata [ pos ] ! = ' , ' & & skindata [ pos ] )
pos + + ;
skindata [ pos + + ] = ' \0 ' ;
surf = ( md3surface_t * ) ( ( byte * ) header + header - > ofssurfs ) ;
for ( j = 0 ; j < header - > numsurfs & & strcmp ( surf - > name , token ) ; j + + )
surf = ( md3surface_t * ) ( ( byte * ) surf + surf - > ofsend ) ;
token = & skindata [ pos ] ;
while ( skindata [ pos ] ! = ' \n ' & & skindata [ pos ] )
pos + + ;
skindata [ pos + + - 1 ] = ' \0 ' ; // becoz of \r\n
if ( token [ 0 ] & & j < header - > numsurfs )
{
shader = ( md3shader_t * ) ( ( byte * ) surf + surf - > ofsshaders ) ;
for ( j = 0 ; j < surf - > numshaders ; j + + , shader + + )
Q_strncpyz ( shader - > name , token , MAX_QPATH ) ;
}
}
Z_Free ( skindata ) ;
}
for ( i = 0 ; i < numskinsfound ; i + + )
free ( skinsfound [ i ] ) ;
free ( skinsfound ) ;
# endif
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadQ3Model
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadQ3AliasModel ( model_t * mod , void * buffer )
{
int i , j , size , base , texture_flag , version , gl_texnum ;
char basename [ MAX_QPATH ] ;
float radiusmax ;
md3header_t * header ;
md3frame_t * frame ;
md3tag_t * tag ;
md3surface_t * surf ;
md3shader_t * shader ;
md3triangle_t * tris ;
md3tc_t * tc ;
md3vert_t * vert ;
char md3name [ 128 ] ;
COM_StripExtension ( mod - > name , & md3name [ 0 ] ) ;
if ( ! strcmp ( md3name , " progs/g_shot " ) | |
! strcmp ( md3name , " progs/g_nail " ) | |
! strcmp ( md3name , " progs/g_nail2 " ) | |
! strcmp ( md3name , " progs/g_rock " ) | |
! strcmp ( md3name , " progs/g_rock2 " ) | |
! strcmp ( md3name , " progs/g_light " ) | |
! strcmp ( md3name , " progs/armor " ) | |
! strcmp ( md3name , " progs/backpack " ) | |
! strcmp ( md3name , " progs/w_g_key " ) | |
! strcmp ( md3name , " progs/w_s_key " ) | |
! strcmp ( md3name , " progs/m_g_key " ) | |
! strcmp ( md3name , " progs/m_s_key " ) | |
! strcmp ( md3name , " progs/b_g_key " ) | |
! strcmp ( md3name , " progs/b_s_key " ) | |
! strcmp ( md3name , " progs/quaddama " ) | |
! strcmp ( md3name , " progs/invisibl " ) | |
! strcmp ( md3name , " progs/invulner " ) | |
! strcmp ( md3name , " progs/jetpack " ) | |
! strcmp ( md3name , " progs/cube " ) | |
! strcmp ( md3name , " progs/suit " ) | |
! strcmp ( md3name , " progs/boots " ) | |
! strcmp ( md3name , " progs/end1 " ) | |
! strcmp ( md3name , " progs/end2 " ) | |
! strcmp ( md3name , " progs/end3 " ) | |
! strcmp ( md3name , " progs/end4 " ) ) {
mod - > flags | = EF_ROTATE ;
}
else if ( ! strcmp ( md3name , " progs/missile " ) )
{
mod - > flags | = EF_ROCKET ;
}
else if ( ! strcmp ( md3name , " progs/gib1 " ) | | //EF_GIB
! strcmp ( md3name , " progs/gib2 " ) | |
! strcmp ( md3name , " progs/gib3 " ) | |
! strcmp ( md3name , " progs/h_player " ) | |
! strcmp ( md3name , " progs/h_dog " ) | |
! strcmp ( md3name , " progs/h_mega " ) | |
! strcmp ( md3name , " progs/h_guard " ) | |
! strcmp ( md3name , " progs/h_wizard " ) | |
! strcmp ( md3name , " progs/h_knight " ) | |
! strcmp ( md3name , " progs/h_hellkn " ) | |
! strcmp ( md3name , " progs/h_zombie " ) | |
! strcmp ( md3name , " progs/h_shams " ) | |
! strcmp ( md3name , " progs/h_shal " ) | |
! strcmp ( md3name , " progs/h_ogre " ) | |
! strcmp ( md3name , " progs/armor " ) | |
! strcmp ( md3name , " progs/h_demon " ) ) {
mod - > flags | = EF_GIB ;
}
else if ( ! strcmp ( md3name , " progs/grenade " ) )
{
mod - > flags | = EF_GRENADE ;
}
else if ( ! strcmp ( md3name , " progs/w_spike " ) )
{
mod - > flags | = EF_TRACER ;
}
else if ( ! strcmp ( md3name , " progs/k_spike " ) )
{
mod - > flags | = EF_TRACER2 ;
}
else if ( ! strcmp ( md3name , " progs/v_spike " ) )
{
mod - > flags | = EF_TRACER3 ;
}
else if ( ! strcmp ( md3name , " progs/zom_gib " ) )
{
mod - > flags | = EF_ZOMGIB ;
}
else if ( ! strcmp ( md3name , " progs/VModel/v_colt " ) | |
! strcmp ( md3name , " progs/VModel/v_kar " ) | |
! strcmp ( md3name , " progs/VModel/v_thomp " ) )
{
mod - > modhint = MOD_WEAPON ;
}
else if ( ! strcmp ( md3name , " progs/lavaball " ) )
{
mod - > modhint = MOD_LAVABALL ;
}
header = ( md3header_t * ) buffer ;
version = LittleLong ( header - > version ) ;
if ( version ! = MD3_VERSION )
Sys_Error ( " Mod_LoadQ3Model: %s has wrong version number (%i should be %i) " , md3name , version , MD3_VERSION ) ;
// endian-adjust all data
header - > numframes = LittleLong ( header - > numframes ) ;
if ( header - > numframes < 1 )
Sys_Error ( " Mod_LoadQ3Model: model %s has no frames " , md3name ) ;
else if ( header - > numframes > MAXMD3FRAMES )
Sys_Error ( " Mod_LoadQ3Model: model %s has too many frames " , md3name ) ;
header - > numtags = LittleLong ( header - > numtags ) ;
if ( header - > numtags > MAXMD3TAGS )
Sys_Error ( " Mod_LoadQ3Model: model %s has too many tags " , md3name ) ;
header - > numsurfs = LittleLong ( header - > numsurfs ) ;
if ( header - > numsurfs < 1 )
Sys_Error ( " Mod_LoadQ3Model: model %s has no surfaces " , md3name ) ;
else if ( header - > numsurfs > MAXMD3SURFS )
Sys_Error ( " Mod_LoadQ3Model: model %s has too many surfaces " , md3name ) ;
header - > numskins = LittleLong ( header - > numskins ) ;
header - > ofsframes = LittleLong ( header - > ofsframes ) ;
header - > ofstags = LittleLong ( header - > ofstags ) ;
header - > ofssurfs = LittleLong ( header - > ofssurfs ) ;
header - > ofsend = LittleLong ( header - > ofsend ) ;
// swap all the frames
frame = ( md3frame_t * ) ( ( byte * ) header + header - > ofsframes ) ;
for ( i = 0 ; i < header - > numframes ; i + + )
{
frame [ i ] . radius = LittleFloat ( frame - > radius ) ;
for ( j = 0 ; j < 3 ; j + + )
{
frame [ i ] . mins [ j ] = LittleFloat ( frame [ i ] . mins [ j ] ) ;
frame [ i ] . maxs [ j ] = LittleFloat ( frame [ i ] . maxs [ j ] ) ;
frame [ i ] . pos [ j ] = LittleFloat ( frame [ i ] . pos [ j ] ) ;
}
}
// swap all the tags
tag = ( md3tag_t * ) ( ( byte * ) header + header - > ofstags ) ;
for ( i = 0 ; i < header - > numtags ; i + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
tag [ i ] . pos [ j ] = LittleFloat ( tag [ i ] . pos [ j ] ) ;
tag [ i ] . rot [ 0 ] [ j ] = LittleFloat ( tag [ i ] . rot [ 0 ] [ j ] ) ;
tag [ i ] . rot [ 1 ] [ j ] = LittleFloat ( tag [ i ] . rot [ 1 ] [ j ] ) ;
tag [ i ] . rot [ 2 ] [ j ] = LittleFloat ( tag [ i ] . rot [ 2 ] [ j ] ) ;
}
}
// swap all the surfaces
surf = ( md3surface_t * ) ( ( byte * ) header + header - > ofssurfs ) ;
for ( i = 0 ; i < header - > numsurfs ; i + + )
{
surf - > ident = LittleLong ( surf - > ident ) ;
surf - > flags = LittleLong ( surf - > flags ) ;
surf - > numframes = LittleLong ( surf - > numframes ) ;
if ( surf - > numframes ! = header - > numframes )
Sys_Error ( " Mod_LoadQ3Model: number of frames don't match in %s " , md3name ) ;
surf - > numshaders = LittleLong ( surf - > numshaders ) ;
if ( surf - > numshaders < = 0 )
Sys_Error ( " Mod_LoadQ3Model: model %s has no shaders " , md3name ) ;
else if ( surf - > numshaders > MAXMD3SHADERS )
Sys_Error ( " Mod_LoadQ3Model: model %s has too many shaders " , md3name ) ;
surf - > numverts = LittleLong ( surf - > numverts ) ;
if ( surf - > numverts < = 0 )
Sys_Error ( " Mod_LoadQ3Model: model %s has no vertices " , md3name ) ;
else if ( surf - > numverts > MAXMD3VERTS )
Sys_Error ( " Mod_LoadQ3Model: model %s has too many vertices " , md3name ) ;
surf - > numtris = LittleLong ( surf - > numtris ) ;
if ( surf - > numtris < = 0 )
Sys_Error ( " Mod_LoadQ3Model: model %s has no triangles " , md3name ) ;
else if ( surf - > numtris > MAXMD3TRIS )
Sys_Error ( " Mod_LoadQ3Model: model %s has too many triangles " , md3name ) ;
surf - > ofstris = LittleLong ( surf - > ofstris ) ;
surf - > ofsshaders = LittleLong ( surf - > ofsshaders ) ;
surf - > ofstc = LittleLong ( surf - > ofstc ) ;
surf - > ofsverts = LittleLong ( surf - > ofsverts ) ;
surf - > ofsend = LittleLong ( surf - > ofsend ) ;
// swap all the shaders
shader = ( md3shader_t * ) ( ( byte * ) surf + surf - > ofsshaders ) ;
for ( j = 0 ; j < surf - > numshaders ; j + + )
shader [ j ] . index = LittleLong ( shader [ j ] . index ) ;
// swap all the triangles
tris = ( md3triangle_t * ) ( ( byte * ) surf + surf - > ofstris ) ;
for ( j = 0 ; j < surf - > numtris ; j + + )
{
tris [ j ] . indexes [ 0 ] = LittleLong ( tris [ j ] . indexes [ 0 ] ) ;
tris [ j ] . indexes [ 1 ] = LittleLong ( tris [ j ] . indexes [ 1 ] ) ;
tris [ j ] . indexes [ 2 ] = LittleLong ( tris [ j ] . indexes [ 2 ] ) ;
}
// swap all the texture coords
tc = ( md3tc_t * ) ( ( byte * ) surf + surf - > ofstc ) ;
for ( j = 0 ; j < surf - > numverts ; j + + )
{
tc [ j ] . s = LittleFloat ( tc [ j ] . s ) ;
tc [ j ] . t = LittleFloat ( tc [ j ] . t ) ;
}
// swap all the vertices
vert = ( md3vert_t * ) ( ( byte * ) surf + surf - > ofsverts ) ;
for ( j = 0 ; j < surf - > numverts * surf - > numframes ; j + + )
{
vert [ j ] . vec [ 0 ] = LittleShort ( vert [ j ] . vec [ 0 ] ) ;
vert [ j ] . vec [ 1 ] = LittleShort ( vert [ j ] . vec [ 1 ] ) ;
vert [ j ] . vec [ 2 ] = LittleShort ( vert [ j ] . vec [ 2 ] ) ;
vert [ j ] . normal = LittleShort ( vert [ j ] . normal ) ;
}
// find the next surface
surf = ( md3surface_t * ) ( ( byte * ) surf + surf - > ofsend ) ;
}
// allocate extra size for structures different in memory
surf = ( md3surface_t * ) ( ( byte * ) header + header - > ofssurfs ) ;
for ( size = 0 , i = 0 ; i < header - > numsurfs ; i + + )
{
size + = surf - > numshaders * sizeof ( md3shader_mem_t ) ; // shader containing texnum
size + = surf - > numverts * surf - > numframes * sizeof ( md3vert_mem_t ) ; // floating point vertices
surf = ( md3surface_t * ) ( ( byte * ) surf + surf - > ofsend ) ;
}
header = static_cast < md3header_t * > ( Cache_Alloc ( & mod - > cache , com_filesize + size , loadname ) ) ;
if ( ! mod - > cache . data )
return ;
memcpy ( header , buffer , com_filesize ) ;
base = com_filesize ;
mod - > type = mod_md3 ;
mod - > numframes = header - > numframes ;
md3bboxmins [ 0 ] = md3bboxmins [ 1 ] = md3bboxmins [ 2 ] = 99999 ;
md3bboxmaxs [ 0 ] = md3bboxmaxs [ 1 ] = md3bboxmaxs [ 2 ] = - 99999 ;
radiusmax = 0 ;
frame = ( md3frame_t * ) ( ( byte * ) header + header - > ofsframes ) ;
for ( i = 0 ; i < header - > numframes ; i + + )
{
for ( j = 0 ; j < 3 ; j + + )
{
md3bboxmins [ j ] = min ( md3bboxmins [ j ] , frame [ i ] . mins [ j ] ) ;
md3bboxmaxs [ j ] = max ( md3bboxmaxs [ j ] , frame [ i ] . maxs [ j ] ) ;
}
radiusmax = max ( radiusmax , frame [ i ] . radius ) ;
}
VectorCopy ( md3bboxmins , mod - > mins ) ;
VectorCopy ( md3bboxmaxs , mod - > maxs ) ;
mod - > radius = radiusmax ;
// load the skins
Mod_LoadAllQ3Skins ( mod - > name , header ) ;
// load the animation frames if loading the player model
if ( ! strcmp ( mod - > name , " progs/player/lower.md3 " ) )
Mod_LoadQ3Animation ( ) ;
surf = ( md3surface_t * ) ( ( byte * ) header + header - > ofssurfs ) ;
for ( i = 0 ; i < header - > numsurfs ; i + + )
{
shader = ( md3shader_t * ) ( ( byte * ) surf + surf - > ofsshaders ) ;
surf - > ofsshaders = base ;
size = surf - > numshaders ;
for ( j = 0 ; j < size ; j + + )
{
md3shader_mem_t * memshader = ( md3shader_mem_t * ) ( ( byte * ) header + surf - > ofsshaders ) ;
Q_strncpyz ( memshader [ j ] . name , shader - > name , sizeof ( memshader [ j ] . name ) ) ;
memshader [ j ] . index = shader - > index ;
COM_StripExtension ( COM_SkipPath ( shader - > name ) , basename ) ;
gl_texnum = 0 ;
texture_flag = 0 ;
Mod_LoadQ3ModelTexture ( basename , texture_flag , & gl_texnum ) ;
memshader [ j ] . gl_texnum = gl_texnum ;
shader + + ;
}
base + = size * sizeof ( md3shader_mem_t ) ;
vert = ( md3vert_t * ) ( ( byte * ) surf + surf - > ofsverts ) ;
surf - > ofsverts = base ;
size = surf - > numverts * surf - > numframes ;
for ( j = 0 ; j < size ; j + + )
{
float lat , lng ;
vec3_t ang ;
md3vert_mem_t * vertexes = ( md3vert_mem_t * ) ( ( byte * ) header + surf - > ofsverts ) ;
vertexes [ j ] . oldnormal = vert - > normal ;
vertexes [ j ] . vec [ 0 ] = ( float ) vert - > vec [ 0 ] * MD3_XYZ_SCALE ;
vertexes [ j ] . vec [ 1 ] = ( float ) vert - > vec [ 1 ] * MD3_XYZ_SCALE ;
vertexes [ j ] . vec [ 2 ] = ( float ) vert - > vec [ 2 ] * MD3_XYZ_SCALE ;
lat = ( ( vert - > normal > > 8 ) & 0xff ) * M_PI / 128.0f ;
lng = ( vert - > normal & 0xff ) * M_PI / 128.0f ;
# ifdef PSP_VFPU
vertexes [ j ] . normal [ 0 ] = vfpu_cosf ( lat ) * vfpu_sinf ( lng ) ;
vertexes [ j ] . normal [ 1 ] = vfpu_sinf ( lat ) * vfpu_sinf ( lng ) ;
vertexes [ j ] . normal [ 2 ] = vfpu_cosf ( lng ) ;
# else
vertexes [ j ] . normal [ 0 ] = cos ( lat ) * sin ( lng ) ;
vertexes [ j ] . normal [ 1 ] = sin ( lat ) * sin ( lng ) ;
vertexes [ j ] . normal [ 2 ] = cos ( lng ) ;
# endif
vectoangles ( vertexes [ j ] . normal , ang ) ;
vertexes [ j ] . anorm_pitch = ang [ 0 ] * 256 / 360 ;
vertexes [ j ] . anorm_yaw = ang [ 1 ] * 256 / 360 ;
vert + + ;
}
base + = size * sizeof ( md3vert_mem_t ) ;
surf = ( md3surface_t * ) ( ( byte * ) surf + surf - > ofsend ) ;
}
}
//==============================================================================
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteFrame
= = = = = = = = = = = = = = = = =
*/
void * Mod_LoadSpriteFrame ( void * pin , mspriteframe_t * * ppframe , int framenum , int version , byte * palette )
{
dspriteframe_t * pinframe ;
mspriteframe_t * pspriteframe ;
int width , height , size , origin [ 2 ] ;
char name [ 64 ] , sprite [ 64 ] , sprite2 [ 64 ] ;
pinframe = ( dspriteframe_t * ) pin ;
width = LittleLong ( pinframe - > width ) ;
height = LittleLong ( pinframe - > height ) ;
size = width * height ;
pspriteframe = static_cast < mspriteframe_t * > ( Hunk_AllocName ( sizeof ( mspriteframe_t ) , loadname ) ) ;
Q_memset ( pspriteframe , 0 , sizeof ( mspriteframe_t ) ) ;
* ppframe = pspriteframe ;
pspriteframe - > width = width ;
pspriteframe - > height = height ;
origin [ 0 ] = LittleLong ( pinframe - > origin [ 0 ] ) ;
origin [ 1 ] = LittleLong ( pinframe - > origin [ 1 ] ) ;
pspriteframe - > up = origin [ 1 ] ;
pspriteframe - > down = origin [ 1 ] - height ;
pspriteframe - > left = origin [ 0 ] ;
pspriteframe - > right = width + origin [ 0 ] ;
sprintf ( name , " %s_%i " , loadmodel - > name , framenum ) ;
if ( version = = SPRITE_VERSION )
{
COM_StripExtension ( loadmodel - > name , sprite ) ;
sprintf ( sprite2 , " %s_%i " , sprite , framenum ) ;
pspriteframe - > gl_texturenum = loadtextureimage ( sprite2 , 0 , 0 , qfalse , GU_LINEAR ) ;
if ( pspriteframe - > gl_texturenum = = 0 ) // did not find a matching TGA...
{
pspriteframe - > gl_texturenum = GL_LoadTexture ( name , width , height , ( byte * ) ( pinframe + 1 ) , qtrue , GU_LINEAR , 0 ) ;
}
}
else if ( version = = SPRITE32_VERSION )
{
size * = 4 ;
pspriteframe - > gl_texturenum = GL_LoadImages ( name , width , height , ( byte * ) ( pinframe + 1 ) , qtrue , GU_LINEAR , 0 , 4 ) ;
}
else if ( version = = SPRITEHL_VERSION )
{
pspriteframe - > gl_texturenum =
GL_LoadPalTex ( name , width , height , ( byte * ) ( pinframe + 1 ) , qtrue , GU_LINEAR , 0 , palette , PAL_RGBA ) ;
Con_Printf ( " HL Sprite TEX - OK \n " ) ;
}
else
{
Sys_Error ( " Mod_LoadSpriteFrame: Non sprite type " ) ;
}
/* Crow_bar Memory Leak Fixed */
mapTextureNameList . push_back ( pspriteframe - > gl_texturenum ) ;
/* Crow_bar Memory Leak Fixed */
return ( void * ) ( ( byte * ) pinframe + sizeof ( dspriteframe_t ) + size ) ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteGroup
= = = = = = = = = = = = = = = = =
*/
void * Mod_LoadSpriteGroup ( void * pin , mspriteframe_t * * ppframe , int framenum , int version , byte * palette )
{
dspritegroup_t * pingroup ;
mspritegroup_t * pspritegroup ;
int i , numframes ;
dspriteinterval_t * pin_intervals ;
float * poutintervals ;
void * ptemp ;
pingroup = ( dspritegroup_t * ) pin ;
numframes = LittleLong ( pingroup - > numframes ) ;
pspritegroup = static_cast < mspritegroup_t * > ( Hunk_AllocName ( sizeof ( mspritegroup_t ) +
( numframes - 1 ) * sizeof ( pspritegroup - > frames [ 0 ] ) , loadname ) ) ;
pspritegroup - > numframes = numframes ;
* ppframe = ( mspriteframe_t * ) pspritegroup ;
pin_intervals = ( dspriteinterval_t * ) ( pingroup + 1 ) ;
poutintervals = static_cast < float * > ( Hunk_AllocName ( numframes * sizeof ( float ) , loadname ) ) ;
pspritegroup - > intervals = poutintervals ;
for ( i = 0 ; i < numframes ; i + + )
{
* poutintervals = LittleFloat ( pin_intervals - > interval ) ;
if ( * poutintervals < = 0.0 )
{
Sys_Error ( " Mod_LoadSpriteGroup: interval<=0 " ) ;
}
poutintervals + + ;
pin_intervals + + ;
}
ptemp = ( void * ) pin_intervals ;
for ( i = 0 ; i < numframes ; i + + )
{
ptemp = Mod_LoadSpriteFrame ( ptemp , & pspritegroup - > frames [ i ] , framenum * 100 + i , version , palette ) ;
}
return ptemp ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadSpriteModel
= = = = = = = = = = = = = = = = =
*/
void Mod_LoadSpriteModel ( model_t * mod , void * buffer )
{
int i ;
int version ;
//dsprite_t *pin;
msprite_t * psprite ;
int numframes ;
int size ;
dspriteframetype_t * pframetype ;
byte palette [ 256 * 4 ] ;
int sptype ;
const unsigned char * datain ;
datain = ( unsigned char * ) buffer ;
version = LittleLong ( ( ( dsprite_t * ) buffer ) - > version ) ;
switch ( version )
{
case SPRITE_VERSION :
case SPRITEHL_VERSION :
case SPRITE32_VERSION :
break ;
default :
Sys_Error ( " %s has wrong version number (%i should be %i(q1),%i(hl),%i(dp)) " , mod - > name , version , SPRITE_VERSION , SPRITEHL_VERSION , SPRITE32_VERSION ) ;
}
if ( version = = SPRITEHL_VERSION ) //Not work
{
Con_Printf ( " Half_Life sprite begin loading \n " ) ;
int i , rendermode ;
const unsigned char * in ;
dspritehl_t * pinhlsprite ;
pinhlsprite = ( dspritehl_t * ) datain ;
datain + = sizeof ( dspritehl_t ) ;
numframes = LittleLong ( pinhlsprite - > numframes ) ;
size = sizeof ( msprite_t ) + ( numframes - 1 ) * sizeof ( psprite - > frames ) ;
psprite = static_cast < msprite_t * > ( Hunk_AllocName ( size , loadname ) ) ;
mod - > cache . data = psprite ;
psprite - > numframes = LittleLong ( pinhlsprite - > numframes ) ;
psprite - > type = LittleLong ( pinhlsprite - > type ) ;
mod - > synctype = ( synctype_t ) LittleLong ( pinhlsprite - > synctype ) ;
rendermode = LittleLong ( pinhlsprite - > texFormat ) ;
in = datain ;
datain + = 2 ;
i = in [ 0 ] + in [ 1 ] * 256 ;
if ( i ! = 256 )
Host_Error ( " Mod_LoadSpriteModel: unexpected number of palette colors %i (should be 256) " , i ) ;
in = datain ;
datain + = 768 ;
switch ( rendermode )
{
case SPR_NORMAL :
for ( i = 0 ; i < 256 ; i + + )
{
palette [ i * 4 + 2 ] = in [ i * 3 + 0 ] ;
palette [ i * 4 + 1 ] = in [ i * 3 + 1 ] ;
palette [ i * 4 + 0 ] = in [ i * 3 + 2 ] ;
palette [ i * 4 + 3 ] = 255 ;
}
break ;
case SPR_ADDITIVE :
for ( i = 0 ; i < 256 ; i + + )
{
palette [ i * 4 + 2 ] = in [ i * 3 + 0 ] ;
palette [ i * 4 + 1 ] = in [ i * 3 + 1 ] ;
palette [ i * 4 + 0 ] = in [ i * 3 + 2 ] ;
palette [ i * 4 + 3 ] = 255 ;
}
// also passes additive == true to Mod_Sprite_SharedSetup
break ;
case SPR_INDEXALPHA :
for ( i = 0 ; i < 256 ; i + + )
{
palette [ i * 4 + 2 ] = in [ 765 ] ;
palette [ i * 4 + 1 ] = in [ 766 ] ;
palette [ i * 4 + 0 ] = in [ 767 ] ;
palette [ i * 4 + 3 ] = i ;
in + = 3 ;
}
break ;
case SPR_ALPHATEST :
for ( i = 0 ; i < 256 ; i + + )
{
palette [ i * 4 + 2 ] = in [ i * 3 + 0 ] ;
palette [ i * 4 + 1 ] = in [ i * 3 + 1 ] ;
palette [ i * 4 + 0 ] = in [ i * 3 + 2 ] ;
palette [ i * 4 + 3 ] = 255 ;
}
palette [ 255 * 4 + 0 ] = palette [ 255 * 4 + 1 ] = palette [ 255 * 4 + 2 ] = palette [ 255 * 4 + 3 ] = 0 ;
// should this use alpha test or alpha blend? (currently blend)
break ;
default :
Host_Error ( " Mod_LoadSpriteModel: unknown texFormat (%i, should be 0, 1, 2, or 3) " , i ) ;
return ;
}
psprite - > maxwidth = LittleLong ( pinhlsprite - > width ) ;
psprite - > maxheight = LittleLong ( pinhlsprite - > height ) ;
psprite - > beamlength = LittleFloat ( pinhlsprite - > beamlength ) ;
pframetype = ( dspriteframetype_t * ) ( pinhlsprite + 1 ) ;
Con_Printf ( " Half_Life sprite end loading \n " ) ;
}
else
{
dsprite_t * pinqsprite ;
pinqsprite = ( dsprite_t * ) datain ;
datain + = sizeof ( dsprite_t ) ;
sptype = LittleLong ( pinqsprite - > type ) ;
numframes = LittleLong ( pinqsprite - > numframes ) ;
size = sizeof ( msprite_t ) + ( numframes - 1 ) * sizeof ( psprite - > frames ) ;
psprite = static_cast < msprite_t * > ( Hunk_AllocName ( size , loadname ) ) ;
mod - > cache . data = psprite ;
psprite - > type = sptype ;
mod - > synctype = static_cast < synctype_t > ( LittleLong ( pinqsprite - > synctype ) ) ;
psprite - > numframes = numframes ;
psprite - > maxwidth = LittleLong ( pinqsprite - > width ) ;
psprite - > maxheight = LittleLong ( pinqsprite - > height ) ;
psprite - > beamlength = LittleFloat ( pinqsprite - > beamlength ) ;
pframetype = ( dspriteframetype_t * ) ( pinqsprite + 1 ) ;
}
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 )
{
Con_Printf ( " Mod_LoadSpriteModel: Invalid # of frames: %d \n " , numframes ) ;
}
mod - > numframes = numframes ;
for ( i = 0 ; i < numframes ; i + + )
{
spriteframetype_t frametype ;
frametype = static_cast < spriteframetype_t > ( LittleFloat ( pframetype - > type ) ) ;
psprite - > frames [ i ] . type = frametype ;
if ( frametype = = SPR_SINGLE )
{
pframetype = ( dspriteframetype_t * )
Mod_LoadSpriteFrame ( pframetype + 1 ,
& psprite - > frames [ i ] . frameptr , i , version , palette ) ;
}
else
{
pframetype = ( dspriteframetype_t * )
Mod_LoadSpriteGroup ( pframetype + 1 ,
& psprite - > frames [ i ] . frameptr , i , version , palette ) ;
}
}
mod - > type = mod_sprite ;
}
/*
= = = = = = = = = = = = = = = = =
Mod_LoadQ2SpriteModel
By Crow_bar
= = = = = = = = = = = = = = = = =
*/
qboolean Mod_LoadQ2SpriteModel ( model_t * mod , void * buffer )
{
int i ;
int version ;
dmd2sprite_t * pin ;
msprite_t * psprite ;
int numframes ;
int size ;
dmd2sprframe_t * pframetype ;
mspriteframe_t * frame ;
float origin [ 2 ] ;
int hunkstart ;
hunkstart = Hunk_LowMark ( ) ;
pin = ( dmd2sprite_t * ) buffer ;
version = LittleLong ( pin - > version ) ;
if ( version ! = SPRITE2_VERSION )
{
Sys_Error ( " %s has wrong version number "
" (%i should be %i) " , mod - > name , version , SPRITE2_VERSION ) ;
return qfalse ;
}
numframes = LittleLong ( pin - > numframes ) ;
size = sizeof ( msprite_t ) + ( numframes - 1 ) * sizeof ( psprite - > frames ) ;
psprite = static_cast < msprite_t * > ( Hunk_AllocName ( size , loadname ) ) ;
mod - > cache . data = psprite ;
psprite - > type = SPR_VP_PARALLEL ;
psprite - > maxwidth = 1 ;
psprite - > maxheight = 1 ;
psprite - > beamlength = 1 ;
mod - > synctype = static_cast < synctype_t > ( 1 ) ;
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 )
{
Sys_Error ( " Mod_LoadSpriteModel: Invalid # of frames: %d \n " , numframes ) ;
Hunk_FreeToLowMark ( hunkstart ) ;
return qfalse ;
}
mod - > numframes = numframes ;
pframetype = pin - > frames ;
for ( i = 0 ; i < numframes ; i + + )
{
spriteframetype_t frametype ;
frametype = SPR_SINGLE ;
psprite - > frames [ i ] . type = frametype ;
frame = psprite - > frames [ i ] . frameptr = static_cast < mspriteframe_t * > ( Hunk_AllocName ( sizeof ( mspriteframe_t ) , loadname ) ) ;
frame - > gl_texturenum = loadtextureimage ( pframetype - > name , 0 , 0 , qtrue , GU_LINEAR ) ;
mapTextureNameList . push_back ( frame - > gl_texturenum ) ;
frame - > width = LittleLong ( pframetype - > width ) ;
frame - > height = LittleLong ( pframetype - > height ) ;
origin [ 0 ] = LittleLong ( pframetype - > origin_x ) ;
origin [ 1 ] = LittleLong ( pframetype - > origin_y ) ;
#if 0 //quake 2 negative translate
frame - > up = - origin [ 1 ] ;
frame - > down = frame - > height - origin [ 1 ] ;
frame - > left = - origin [ 0 ] ;
frame - > right = frame - > width - origin [ 0 ] ;
# else
frame - > up = origin [ 1 ] ;
frame - > down = origin [ 1 ] - frame - > height ;
frame - > left = - origin [ 0 ] ;
frame - > right = - origin [ 0 ] + frame - > width ;
# endif
pframetype + + ;
}
mod - > type = mod_sprite ;
return qtrue ;
}
//=============================================================================
/*
= = = = = = = = = = = = = = = =
Mod_Print
= = = = = = = = = = = = = = = =
*/
extern " C " void Mod_Print ( void )
{
int i ;
model_t * mod ;
Con_Printf ( " Cached models: \n " ) ;
for ( i = 0 , mod = mod_known ; i < mod_numknown ; i + + , mod + + )
{
Con_Printf ( " %8p : %s \n " , mod - > cache . data , mod - > name ) ;
}
}