Example #1
0
void
wad_rehash (wad_t *wad)
{
	int         i;

	for (i = 0; i < wad->numlumps; i++) {
		Hash_AddElement (wad->lump_hash, &wad->lumps[i]);
	}
}
Example #2
0
int
wad_add (wad_t *wad, const char *filename, const char *lumpname, byte type)
{
	lumpinfo_t *pf;
	lumpinfo_t  dummy;
	QFile      *file;
	char        buffer[16384];
	int         bytes;

	strncpy (dummy.name, lumpname, 16);
	dummy.name[15] = 0;

	pf = Hash_FindElement (wad->lump_hash, &dummy);
	if (pf)
		return -1;
	if (wad->numlumps == wad->lumps_size) {
		lumpinfo_t *f;
		
		wad->lumps_size += 64;

		f = realloc (wad->lumps, wad->lumps_size * sizeof (lumpinfo_t));
		if (!f)
			return -1;
		wad->lumps = f;
	}

	file = Qopen (filename, "rb");
	if (!file)
		return -1;

	wad->modified = 1;

	pf = &wad->lumps[wad->numlumps++];

	strncpy (pf->name, lumpname, sizeof (pf->name));
	pf->name[sizeof (pf->name) - 1] = 0;

	Qseek (wad->handle, 0, SEEK_END);
	pf->filepos = Qtell (wad->handle);
	pf->type = type;
	pf->size = 0;
	while ((bytes = Qread (file, buffer, sizeof (buffer)))) {
		Qwrite (wad->handle, buffer, bytes);
		pf->size += bytes;
	}
	Qclose (file);
	if (wad->pad && pf->size & 3) {
		static char buf[4];
		Qwrite (wad->handle, buf, 4 - (pf->size & 3));
	}
	Hash_AddElement (wad->lump_hash, pf);
	return 0;
}
Example #3
0
static ex_value_t *
find_value (const ex_value_t *val)
{
	ex_value_t *value;

	value = Hash_FindElement (value_table, val);
	if (value)
		return value;
	value = new_value ();
	*value = *val;
	Hash_AddElement (value_table, value);
	return value;
}
Example #4
0
static int
load_progs (const char *name)
{
	QFile      *file;
	int         i, size;
	char        buff[5];

	Hash_FlushTable (func_tab);

	file = open_file (name, &size);
	if (!file) {
		perror (name);
		return 0;
	}
	Qread (file, buff, 4);
	buff[4] = 0;
	Qseek (file, 0, SEEK_SET);
	if (!strcmp (buff, QFO)) {
		qfo = qfo_read (file);
		Qclose (file);

		if (!qfo)
			return 0;

		if (!need_progs)
			return 1;
		convert_qfo ();
	} else {
		pr.progs_name = name;
		PR_LoadProgsFile (&pr, file, size, 1, 0);
		Qclose (file);

		if (!pr.progs)
			return 0;

		PR_LoadStrings (&pr);
		PR_ResolveGlobals (&pr);
		PR_LoadDebug (&pr);
	}
	for (i = 0; i < pr.progs->numfunctions; i++) {
		// don't bother with builtins
		if (pr.pr_functions[i].first_statement > 0)
			Hash_AddElement (func_tab, &pr.pr_functions[i]);
	}
	return 1;
}
Example #5
0
int
wad_add_data (wad_t *wad, const char *lumpname, byte type, const void *data,
			  int bytes)
{
	lumpinfo_t *pf;
	lumpinfo_t  dummy;

	strncpy (dummy.name, lumpname, 16);
	dummy.name[15] = 0;

	pf = Hash_FindElement (wad->lump_hash, &dummy);
	if (pf)
		return -1;
	if (wad->numlumps == wad->lumps_size) {
		lumpinfo_t *f;
		
		wad->lumps_size += 64;

		f = realloc (wad->lumps, wad->lumps_size * sizeof (lumpinfo_t));
		if (!f)
			return -1;
		wad->lumps = f;
	}

	wad->modified = 1;

	pf = &wad->lumps[wad->numlumps++];

	strncpy (pf->name, lumpname, sizeof (pf->name));
	pf->name[sizeof (pf->name) - 1] = 0;

	Qseek (wad->handle, 0, SEEK_END);
	pf->filepos = Qtell (wad->handle);
	pf->type = type;
	pf->size = bytes;

	Qwrite (wad->handle, data, bytes);

	if (wad->pad && pf->size & 3) {
		static char buf[4];
		Qwrite (wad->handle, buf, 4 - (pf->size & 3));
	}
	Hash_AddElement (wad->lump_hash, pf);
	return 0;
}
Example #6
0
void
opcode_init (void)
{
	opcode_t   *op, *mop;

	if (opcode_type_table) {
		Hash_FlushTable (opcode_void_table);
		Hash_FlushTable (opcode_type_table);
	} else {
		PR_Opcode_Init ();
		opcode_type_table = Hash_NewTable (1021, 0, opcode_free, 0);
		Hash_SetHashCompare (opcode_type_table, get_hash, compare);
		opcode_void_table = Hash_NewTable (1021, get_key, 0, 0);
	}
	for (op = pr_opcodes; op->name; op++) {
		if (op->min_version > options.code.progsversion)
			continue;
		mop = malloc (sizeof (opcode_t));
		*mop = *op;
		if (options.code.progsversion == PROG_ID_VERSION) {
			// v6 progs have no concept of integer, but the QF engine
			// treats the operands of certain operands as integers
			// irrespective the progs version, so convert the engine's
			// view of the operands to the prog's view.
			if (mop->type_a == ev_integer)
				mop->type_a = ev_float;
			if (mop->type_b == ev_integer)
				mop->type_b = ev_float;
			if (mop->type_c == ev_integer)
				mop->type_c = ev_float;
		}
		Hash_AddElement (opcode_type_table, mop);
		if (mop->type_a == ev_void || mop->type_b == ev_void
			|| mop->type_c == ev_void)
			Hash_Add (opcode_void_table, mop);
	}
}
Example #7
0
iqmblend_t *
Mod_IQMBuildBlendPalette (iqm_t *iqm, int *size)
{
	int         i, j;
	iqmvertexarray *bindices = 0;
	iqmvertexarray *bweights = 0;
	iqmblend_t *blend_list;
	int         num_blends;
	hashtab_t  *blend_hash;

	for (i = 0; i < iqm->num_arrays; i++) {
		if (iqm->vertexarrays[i].type == IQM_BLENDINDEXES)
			bindices = &iqm->vertexarrays[i];
		if (iqm->vertexarrays[i].type == IQM_BLENDWEIGHTS)
			bweights = &iqm->vertexarrays[i];
	}
	if (!bindices || !bweights) {
		// Not necessarily an error: might be a static model with no bones
		// Either way, no need to make a blend palette
		Sys_MaskPrintf (SYS_MODEL, "bone index or weight array missing\n");
		*size = 0;
		return 0;
	}

	blend_list = calloc (MAX_BLENDS, sizeof (iqmblend_t));
	for (i = 0; i < iqm->num_joints; i++) {
		blend_list[i].indices[0] = i;
		blend_list[i].weights[0] = 255;
	}
	num_blends = iqm->num_joints;

	blend_hash = Hash_NewTable (1023, 0, 0, 0);
	Hash_SetHashCompare (blend_hash, blend_get_hash, blend_compare);

	for (i = 0; i < iqm->num_verts; i++) {
		byte       *vert = iqm->vertices + i * iqm->stride;
		byte       *bi = vert + bindices->offset;
		byte       *bw = vert + bweights->offset;
		iqmblend_t  blend;
		iqmblend_t *bl;

		// First, canonicalize vextex bone data:
		//   bone indices are in increasing order
		//   bone weight of zero is never followed by a non-zero weight
		//   bone weight of zero has bone index of zero

		// if the weight is zero, ensure the index is also zero
		// also, ensure non-zero weights never follow zero weights
		for (j = 0; j < 4; j++) {
			if (!bw[j]) {
				bi[j] = 0;
			} else {
				if (j && !bw[j-1]) {
					swap_bones (bi, bw, j - 1, j);
					j = 0;					// force a rescan
				}
			}
		}
		// sort the bones such that the indeces are increasing (unless the
		// weight is zero)
		for (j = 0; j < 3; j++) {
			if (!bw[j+1])					// zero weight == end of list
				break;
			if (bi[j] > bi[j+1]) {
				swap_bones (bi, bw, j, j + 1);
				j = -1;						// force rescan
			}
		}

		// Now that the bone data is canonical, it can be hashed.
		// However, no need to check other combinations if the vertex has
		// only one influencing bone: the bone index will only change format.
		if (!bw[1]) {
			*(uint32_t *) bi = bi[0];
			continue;
		}
		QuatCopy (bi, blend.indices);
		QuatCopy (bw, blend.weights);
		if ((bl = Hash_FindElement (blend_hash, &blend))) {
			*(uint32_t *) bi = (bl - blend_list);
			continue;
		}
		if (num_blends >= MAX_BLENDS)
			Sys_Error ("Too many blends. Tell taniwha to stop being lazy.");
		blend_list[num_blends] = blend;
		Hash_AddElement (blend_hash, &blend_list[num_blends]);
		*(uint32_t *) bi = num_blends;
		num_blends++;
	}

	Hash_DelTable (blend_hash);
	*size = num_blends;
	return realloc (blend_list, num_blends * sizeof (iqmblend_t));
}