1205 lines · 26.0 KB · C
RawDownload
// models.c -- model loading and caching // models are the only shared resource between a client and server running// on the same machine. #include <u.h>#include <libc.h>#include <stdio.h>#include "dat.h"#include "fns.h" model_t	*loadmodel;char	loadname[32];	// for hunk tags void Mod_LoadSpriteModel (model_t *mod, void *buffer);void Mod_LoadBrushModel (model_t *mod, void *buffer);void Mod_LoadAliasModel (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	256model_t	mod_known[MAX_MOD_KNOWN];int		mod_numknown; // the inline * models from the current map are kept seperatemodel_t	mod_inline[MAX_MOD_KNOWN]; int		registration_sequence;int		modfilelen; //===============================================================================  /*================Mod_Modellist_f================*/void Mod_Modellist_f (void){	int		i;	model_t	*mod;	int		total; 	total = 0;	ri.Con_Printf (PRINT_ALL,"Loaded models:\n");	for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)	{		if (!mod->name[0])			continue;		ri.Con_Printf (PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);		total += mod->extradatasize;	}	ri.Con_Printf (PRINT_ALL, "Total resident: %i\n", total);} /*===============Mod_Init===============*/void Mod_Init (void){	memset (mod_novis, 0xff, sizeof(mod_novis));} /*==================Mod_ForName Loads in a model for the given name==================*/model_t *Mod_ForName (char *name, qboolean crash){	model_t	*mod;	unsigned *buf;	int		i;		if (!name[0])		ri.Sys_Error (ERR_DROP,"Mod_ForName: NULL name"); 	//	// inline models are grabbed only from worldmodel	//	if (name[0] == '*')	{		i = atoi(name+1);		if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)			ri.Sys_Error (ERR_DROP, "bad inline model number");		return &mod_inline[i];	} 	//	// search the currently loaded models	//	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)		if (!strcmp (mod->name, name) )			return mod;				//	// find a free model slot spot	//	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)	{		if (!mod->name[0])			break;	// free spot	}	if (i == mod_numknown)	{		if (mod_numknown == MAX_MOD_KNOWN)			ri.Sys_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");		mod_numknown++;	}	strcpy (mod->name, name);		//	// load the file	//	modfilelen = ri.FS_LoadFile (mod->name, (void **)&buf);	if (!buf)	{		if (crash)			ri.Sys_Error (ERR_DROP,"Mod_NumForName: %s not found", mod->name);		memset (mod->name, 0, sizeof(mod->name));		return NULL;	}		loadmodel = mod; 	//	// fill it in	// 	// call the apropriate loader		switch (LittleLong(*(unsigned *)buf))	{	case IDALIASHEADER:		loadmodel->extradata = Hunk_Begin (0x200000);		Mod_LoadAliasModel (mod, buf);		break;			case IDSPRITEHEADER:		loadmodel->extradata = Hunk_Begin (0x10000);		Mod_LoadSpriteModel (mod, buf);		break;		case IDBSPHEADER:		loadmodel->extradata = Hunk_Begin (0x1000000);		Mod_LoadBrushModel (mod, buf);		break; 	default:		ri.Sys_Error (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name);		break;	} 	loadmodel->extradatasize = Hunk_End (); 	ri.FS_FreeFile (buf); 	return mod;}  /*===============Mod_PointInLeaf===============*/mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model){	mnode_t		*node;	float		d;	mplane_t	*plane;		if (!model || !model->nodes)		ri.Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model"); 	node = model->nodes;	while (1)	{		if (node->contents != -1)			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];	}}  /*===================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->vis->numclusters+7)>>3;		out = decompressed; 	/*	memcpy (out, in, row);	*/	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);		return decompressed;} /*==============Mod_ClusterPVS==============*/byte *Mod_ClusterPVS (int cluster, model_t *model){	if (cluster == -1 || !model->vis)		return mod_novis;	return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS],		model);} /*=============================================================================== 					BRUSHMODEL LOADING ===============================================================================*/ byte	*mod_base;  /*=================Mod_LoadLighting Converts the 24 bit lighting down to 8 bitby taking the brightest component=================*/void Mod_LoadLighting (lump_t *l){	int		i, size;	byte	*in; 	if (!l->filelen)	{		loadmodel->lightdata = NULL;		return;	}	size = l->filelen/3;	loadmodel->lightdata = Hunk_Alloc (size);	in = (void *)(mod_base + l->fileofs);	for (i=0 ; i<size ; i++, in+=3)	{		if (in[0] > in[1] && in[0] > in[2])			loadmodel->lightdata[i] = in[0];		else if (in[1] > in[0] && in[1] > in[2])			loadmodel->lightdata[i] = in[1];		else			loadmodel->lightdata[i] = in[2];	}}  int		r_leaftovis[MAX_MAP_LEAFS];int		r_vistoleaf[MAX_MAP_LEAFS];int		r_numvisleafs; void	R_NumberLeafs (mnode_t *node){	mleaf_t	*leaf;	int		leafnum; 	if (node->contents != -1)	{		leaf = (mleaf_t *)node;		leafnum = leaf - loadmodel->leafs;		if (leaf->contents & CONTENTS_SOLID)			return;		r_leaftovis[leafnum] = r_numvisleafs;		r_vistoleaf[r_numvisleafs] = leafnum;		r_numvisleafs++;		return;	} 	R_NumberLeafs (node->children[0]);	R_NumberLeafs (node->children[1]);}  /*=================Mod_LoadVisibility=================*/void Mod_LoadVisibility (lump_t *l){	int		i; 	if (!l->filelen)	{		loadmodel->vis = NULL;		return;	}	loadmodel->vis = Hunk_Alloc ( l->filelen);		memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen); 	loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters);	for (i=0 ; i<loadmodel->vis->numclusters ; i++)	{		loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]);		loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]);	}}  /*=================Mod_LoadVertexes=================*/void Mod_LoadVertexes (lump_t *l){	dvertex_t	*in;	mvertex_t	*out;	int			i, count; 	in = (void *)(mod_base + l->fileofs);	if (l->filelen % sizeof(*in))		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);	count = l->filelen / sizeof(*in);	out = Hunk_Alloc ( (count+8)*sizeof(*out));		// extra for skybox 	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 = (void *)(mod_base + l->fileofs);	if (l->filelen % sizeof(*in))		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);	count = l->filelen / sizeof(*in);	out = Hunk_Alloc ( count*sizeof(*out));	 	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]);		}		out->headnode = LittleLong (in->headnode);		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 = (void *)(mod_base + l->fileofs);	if (l->filelen % sizeof(*in))		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);	count = l->filelen / sizeof(*in);	out = Hunk_Alloc ( (count + 13) * sizeof(*out));	// extra for skybox 	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, *step;	int 	i, j, count;	float	len1, len2;	char	name[MAX_QPATH];	int		next; 	in = (void *)(mod_base + l->fileofs);	if (l->filelen % sizeof(*in))		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);	count = l->filelen / sizeof(*in);	out = Hunk_Alloc ( (count+6)*sizeof(*out));	// extra for skybox 	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 = VectorLength (out->vecs[0]);		len2 = VectorLength (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 (len1 + len2 < 0.001)			out->mipadjust = 1;		// don't crash		else			out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );		*/ 		out->flags = LittleLong (in->flags); 		next = LittleLong (in->nexttexinfo);		if (next > 0)			out->next = loadmodel->texinfo + next; 		Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);		out->image = R_FindImage (name, it_wall);		if (!out->image)		{			out->image = r_notexture_mip; // texture not found			out->flags = 0;		}

Lines 1–500 of 1205.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t