247 lines · 4.5 KB · C
RawDownload
#include "quakedef.h" enum {	// values for model_t's needload	NL_PRESENT,	NL_NEEDS_LOADED,	NL_UNREFERENCED, 	MAX_MOD_KNOWN = 4096,}; static char loadname[32]; // for hunk tagsstatic model_t *mod_known;static int mod_numknown; static model_t *Mod_LoadModel(model_t *mod, bool crash); voidMod_Init(void){	mod_known = Hunk_Alloc(MAX_MOD_KNOWN * sizeof(*mod_known));} /* Caches the data if needed */void *Mod_Extradata(model_t *mod){	void *r; 	if((r = Cache_Check(&mod->cache)) != nil)		return r;	Mod_LoadModel(mod, true);	if(!mod->cache.data)		Host_Error("Mod_Extradata: caching failed: %s", mod->name);	return mod->cache.data;} mleaf_t *Mod_PointInLeaf(const vec3_t p, model_t *model){	mnode_t *node;	float d;	mplane_t *plane; 	if(!model || !model->nodes)		Host_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;		node = node->children[d <= 0];	}} static byte *Mod_DecompressVis(byte *in, model_t *model, int *outsz){	static byte *decompressed;	static int decompressed_size;	int c;	byte *out;	int row; 	row = (model->numleafs + 7) / 8;	if(decompressed == nil || row > decompressed_size) {		decompressed_size = row;		decompressed = realloc(decompressed, decompressed_size);	}	out = decompressed;	*outsz = row; 	if(!in) { // no vis info, so make all visible		memset(out, 0xff, row);		return decompressed;	} 	do {		if(*in) {			*out++ = *in++;			continue;		} 		c = in[1];		in += 2;		while(c && out - decompressed < row) {			*out++ = 0;			c--;		}	} while(out - decompressed < row); 	return decompressed;} byte *Mod_LeafPVS(mleaf_t *leaf, model_t *model, int *outsz){	static byte *mod_novis;	static int mod_novis_size;	int sz; 	sz = ((model->numleafs + 7) / 8 + 3) & ~3;	*outsz = sz;	if(leaf == model->leafs) {		if(mod_novis == nil || mod_novis_size < sz) {			mod_novis = realloc(mod_novis, sz);			mod_novis_size = sz;		}		memset(mod_novis, 0xff, mod_novis_size);		return mod_novis;	}	return Mod_DecompressVis(leaf->compressed_vis, model, outsz);} voidMod_ClearAll(void){	int i;	model_t *mod; 	for(i = 0, mod = mod_known; i < mod_numknown; i++, mod++) {		mod->needload = NL_UNREFERENCED;		// FIX FOR CACHE_ALLOC ERRORS:		if(mod->type == mod_sprite)			mod->cache.data = nil;	}} model_t *Mod_FindName(const char *name){	int i;	model_t *mod, *avail = nil; 	if(!name[0])		Host_Error("Mod_FindName: nil name"); 	// search the currently loaded models	for(i = 0, mod = mod_known; i < mod_numknown; i++, mod++) {		if(strcmp(mod->name, name) == 0)			break;		if(mod->needload == NL_UNREFERENCED)			if(!avail || mod->type != mod_alias)				avail = mod;	} 	if(i == mod_numknown) {		if(mod_numknown == MAX_MOD_KNOWN) {			if(avail) {				mod = avail;				if(mod->type == mod_alias)					if(Cache_Check(&mod->cache))						Cache_Free(&mod->cache);			} else				Host_Error("mod_numknown == MAX_MOD_KNOWN");		} else			mod_numknown++;		strcpy(mod->name, name);		mod->needload = NL_NEEDS_LOADED;	} 	return mod;} voidMod_TouchModel(const char *name){	model_t *mod; 	mod = Mod_FindName(name); 	if(mod->needload == NL_PRESENT) {		if(mod->type == mod_alias)			Cache_Check(&mod->cache);	}} static model_t *Mod_LoadModel(model_t *mod, bool crash){	byte *buf;	int len; 	if(mod->type == mod_alias) {		if(Cache_Check(&mod->cache)) {			mod->needload = NL_PRESENT;			return mod;		}	} else if(mod->needload == NL_PRESENT)		return mod; 	// because the world is so huge, load it one piece at a time	if((buf = loadstklmp(mod->name, nil, 0, &len)) == nil) {		if(crash)			Host_Error("Mod_LoadModel: %s", lerr());		return nil;	} 	// allocate a new model	radix(mod->name, loadname); 	// fill it in	mod->lmpfrom = fs_lmpfrom; 	// call the apropriate loader	mod->needload = NL_PRESENT; 	switch(LittleLong(*(unsigned *)buf)) {	case IDPOLYHEADER:		Mod_LoadAliasModel(mod, buf);		break;	case IDSPRITEHEADER:		Mod_LoadSpriteModel(mod, buf, len);		break;	default:		Mod_LoadBrushModel(mod, buf, len);		break;	} 	return mod;} model_t *Mod_ForName(const char *name, bool crash){	return Mod_LoadModel(Mod_FindName(name), crash);} voidMod_Print_f(cmd_t *c){	int i;	model_t *mod; 	USED(c);	Con_Printf("Cached models:\n");	for(i = 0, mod = mod_known; i < mod_numknown; i++, mod++) {		Con_Printf("%8p : %s", mod->cache.data, mod->name);		if(mod->needload & NL_UNREFERENCED)			Con_Printf(" (!R)");		if(mod->needload & NL_NEEDS_LOADED)			Con_Printf(" (!P)");		Con_Printf("\n");	}}

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