/* @@@@@@@@@@@@@@@@@@@@@ R_EndRegistration @@@@@@@@@@@@@@@@@@@@@ */ void R_EndRegistration (void) { Prof_Begin(__FUNCTION__); Hunk_End(&hunk_ref); Prof_End(); }
/* @@@@@@@@@@@@@@@@@@@@@ R_EndRegistration @@@@@@@@@@@@@@@@@@@@@ */ void R_EndRegistration (void) { Prof_Begin(__FUNCTION__); Hunk_End (&hunk_ref); GL_FreeUnusedImages (); Prof_End(); }
/* ===================== S_EndRegistration ===================== */ void S_EndRegistration (void) { int i; sfx_t *sfx; // load everything in for (i=0, sfx=known_sfx ; i < num_sfx ; i++,sfx++) { if (!sfx->name[0]) continue; S_LoadSound (sfx); } Hunk_End(&hunk_snd); s_registering = false; }
/* ================== 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 (!mod->name[0]) continue; 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, &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_ForName Loads in a model for the given name ================== */ model_t *Mod_ForName (const char *name_, qboolean crash) { model_t *mod; model_t *modelhash; mscache_t *model_size; byte *buf; int i; unsigned hash; size_t len = strlen(name_); char *name = (char *) alloca(len + 1); strcpy(name, name_); if (!name || !name[0]) VID_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) VID_Error (ERR_DROP, "bad inline model number %d", i); return &mod_inline[i]; } fast_strlwr (name); hash = hashify (name) % MODEL_HASH_SIZE; for (modelhash = models_hash[hash]; modelhash; modelhash = modelhash->hash_next) { if (!strcmp (modelhash->name, name)) { return modelhash; } } for (model_size = model_size_cache[hash]; model_size; model_size = model_size->hash_next) { if (!strcmp (model_size->name, name)) break; } // // search the currently loaded models // /*for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) { if (!mod->name[0] || mod->hash != hash) continue; 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) VID_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN"); mod_numknown++; } strncpy (mod->name, name, sizeof(mod->name)-1); // // load the file // modfilelen = FS_LoadFile (name, (void **)&buf); if (!buf) { if (crash) VID_Error (ERR_DROP, "Mod_NumForName: %s not found", mod->name); mod->name[0] = 0; return NULL; } loadmodel = mod; // // fill it in // // call the apropriate loader switch (LittleLong(*(unsigned *)buf)) { case IDALIASHEADER: if (model_size) loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size); else loadmodel->extradata = Hunk_Begin (0x200000, 0); Mod_LoadAliasModel (mod, buf); break; case IDSPRITEHEADER: if (model_size) loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size); else loadmodel->extradata = Hunk_Begin (0x4000, 0); Mod_LoadSpriteModel (mod, buf); break; case IDBSPHEADER: if (model_size) loadmodel->extradata = Hunk_Begin (model_size->size, model_size->size); else loadmodel->extradata = Hunk_Begin (0x1000000, 0); Mod_LoadBrushModel (mod, buf); break; default: VID_Error (ERR_DROP,"Mod_NumForName: unknown 0x%.8x fileid for %s", LittleLong(*(unsigned *)buf), mod->name); break; } if (model_size) { loadmodel->extradatasize = model_size->size; } else { loadmodel->extradatasize = Hunk_End (); model_size = (mscache_t *) malloc (sizeof(*model_size)); if (!model_size) VID_Error (ERR_FATAL, "Mod_ForName: out of memory"); strcpy (model_size->name, mod->name); model_size->size = loadmodel->extradatasize; model_size->hash_next = model_size_cache[hash]; model_size_cache[hash] = model_size; } mod->hash_next = models_hash[hash]; models_hash[hash] = mod; FS_FreeFile (buf); return mod; }
/* * 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 = (int)strtol(name + 1, (char **)NULL, 10); 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 (!mod->name[0]) { continue; } 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; /* call the apropriate loader */ switch (LittleLong(*(unsigned *)buf)) { case IDALIASHEADER: loadmodel->extradata = Hunk_Begin(0x200000); LoadMD2(mod, buf); break; case IDSPRITEHEADER: loadmodel->extradata = Hunk_Begin(0x10000); LoadSP2(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_LoadAliasModel ================= */ qerror_t MOD_LoadMD2(model_t *model, const void *rawdata, size_t length) { dmd2header_t header; dmd2frame_t *src_frame; //dmd2trivertx_t *src_vert; dmd2triangle_t *src_tri; dmd2stvert_t *src_st; maliasframe_t *dst_frame; //maliasvert_t *dst_vert; maliastri_t *dst_tri; maliasst_t *dst_st; char skinname[MAX_QPATH]; char *src_skin; int i, j; qerror_t ret; if (length < sizeof(header)) { return Q_ERR_FILE_TOO_SMALL; } // byte swap the header header = *(dmd2header_t *)rawdata; for (i = 0; i < sizeof(header) / 4; i++) { ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]); } // validate the header ret = MOD_ValidateMD2(&header, length); if (ret) { if (ret == Q_ERR_TOO_FEW) { // empty models draw nothing model->type = MOD_EMPTY; return Q_ERR_SUCCESS; } return ret; } Hunk_Begin(&model->hunk, 0x400000); model->type = MOD_ALIAS; // load triangle indices model->tris = MOD_Malloc(header.num_tris * sizeof(maliastri_t)); model->numtris = header.num_tris; src_tri = (dmd2triangle_t *)((byte *)rawdata + header.ofs_tris); dst_tri = model->tris; for (i = 0; i < header.num_tris; i++, src_tri++, dst_tri++) { for (j = 0; j < 3; j++) { unsigned idx_xyz = LittleShort(src_tri->index_xyz[j]); unsigned idx_st = LittleShort(src_tri->index_st[j]); if (idx_xyz >= header.num_xyz || idx_st >= header.num_st) { ret = Q_ERR_BAD_INDEX; goto fail; } dst_tri->index_xyz[j] = idx_xyz; dst_tri->index_st[j] = idx_st; } } // load base s and t vertices model->sts = MOD_Malloc(header.num_st * sizeof(maliasst_t)); model->numsts = header.num_st; src_st = (dmd2stvert_t *)((byte *)rawdata + header.ofs_st); dst_st = model->sts; for (i = 0; i < header.num_st; i++, src_st++, dst_st++) { dst_st->s = (int16_t)LittleShort(src_st->s); dst_st->t = (int16_t)LittleShort(src_st->t); } // load the frames model->frames = MOD_Malloc(header.num_frames * sizeof(maliasframe_t)); model->numframes = header.num_frames; model->numverts = header.num_xyz; src_frame = (dmd2frame_t *)((byte *)rawdata + header.ofs_frames); dst_frame = model->frames; for (i = 0; i < header.num_frames; i++, dst_frame++) { for (j = 0; j < 3; j++) { dst_frame->scale[j] = LittleFloat(src_frame->scale[j]); dst_frame->translate[j] = LittleFloat(src_frame->translate[j]); } // verts are all 8 bit, so no swapping needed dst_frame->verts = MOD_Malloc(header.num_xyz * sizeof(maliasvert_t)); // TODO: check normal indices memcpy(dst_frame->verts, src_frame->verts, header.num_xyz * sizeof(maliasvert_t)); src_frame = (dmd2frame_t *)((byte *)src_frame + header.framesize); } // register all skins src_skin = (char *)rawdata + header.ofs_skins; for (i = 0; i < header.num_skins; i++) { if (!Q_memccpy(skinname, src_skin, 0, sizeof(skinname))) { ret = Q_ERR_STRING_TRUNCATED; goto fail; } FS_NormalizePath(skinname, skinname); model->skins[i] = IMG_Find(skinname, IT_SKIN); src_skin += MD2_MAX_SKINNAME; } model->numskins = header.num_skins; Hunk_End(&model->hunk); return Q_ERR_SUCCESS; fail: Hunk_Free(&model->hunk); return ret; }