void wad_rehash (wad_t *wad) { int i; for (i = 0; i < wad->numlumps; i++) { Hash_AddElement (wad->lump_hash, &wad->lumps[i]); } }
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; }
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; }
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; }
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; }
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); } }
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)); }