/* =============== Cmd_Exec_f =============== */ void Cmd_Exec_f (void) { char *f; int mark; if (Cmd_Argc () != 2) { Con_Printf ("exec <filename> : execute a script file\n"); return; } // FIXME: is this safe freeing the hunk here??? mark = Hunk_LowMark (); f = (char *)COM_LoadHunkFile (Cmd_Argv(1)); if (!f) { Con_Printf ("couldn't exec %s\n",Cmd_Argv(1)); return; } if (!Cvar_Command () && (cl_warncmd.value || developer.value)) Con_Printf ("execing %s\n",Cmd_Argv(1)); Cbuf_InsertText (f); Hunk_FreeToLowMark (mark); }
/* =============== Cmd_Exec_f =============== */ void Cmd_Exec_f (void) { char *f; int mark; if (Cmd_Argc () != 2) { Con_Printf ("exec <filename> : execute a script file\n"); return; } // FIXME: is this safe freeing the hunk here??? mark = Hunk_LowMark (); f = (char *)FS_LoadHunkFile (Cmd_Argv(1), NULL); if (!f) { Con_Printf ("couldn't exec %s\n",Cmd_Argv(1)); return; } Con_Printf ("execing %s\n",Cmd_Argv(1)); Cbuf_InsertText (f); Hunk_FreeToLowMark (mark); }
static qboolean S_MODPLUG_CodecOpenStream (snd_stream_t *stream) { /* need to load the whole file into memory and pass it to libmodplug */ byte *moddata; long len; int mark; len = FS_filelength (&stream->fh); mark = Hunk_LowMark(); moddata = (byte *) Hunk_Alloc(len); FS_fread(moddata, 1, len, &stream->fh); S_MODPLUG_SetSettings(stream); stream->priv = ModPlug_Load(moddata, len); Hunk_FreeToLowMark(mark); /* free original file data */ if (!stream->priv) { Con_DPrintf("Could not load module %s\n", stream->name); return false; } ModPlug_Seek((ModPlugFile*)stream->priv, 0); #if 0 /* default volume (128) sounds rather low? */ ModPlug_SetMasterVolume((ModPlugFile*)stream->priv, 384); /* 0-512 */ #endif return true; }
static unsigned SV_CheckModel(char *mdl) { unsigned char *buf; unsigned short crc; int filesize; int mark; mark = Hunk_LowMark (); buf = (byte *) FS_LoadHunkFile (mdl, &filesize); if (!buf) { if (!strcmp (mdl, "progs/player.mdl")) return 33168; else if (!strcmp (mdl, "progs/newplayer.mdl")) return 62211; else if (!strcmp (mdl, "progs/eyes.mdl")) return 6967; else SV_Error ("SV_CheckModel: could not load %s\n", mdl); } crc = CRC_Block (buf, filesize); Hunk_FreeToLowMark (mark); return crc; }
void R_LoadSkys (void) { int i, mark; FILE *f; char name[64], texname[20]; for (i = 0; i < 6; i++) { q_snprintf (name, sizeof(name), "gfx/env/bkgtst%s.tga", suf[i]); FS_OpenFile (name, &f, false); if (!f) { Con_Printf ("Couldn't load %s\n", name); continue; } mark = Hunk_LowMark(); LoadTGA (f); // LoadPCX (f); q_snprintf (texname, sizeof(texname), "skybox%i", i); sky_tex[i] = GL_LoadTexture(texname, 256, 256, targa_rgba, false, false, 0, true); Hunk_FreeToLowMark(mark); glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); glTexParameterf_fp(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } }
/* ===================== CL_ClearState ===================== */ void CL_ClearState (void) { int i; // STRIP S_StopAllSounds (true); Con_DPrintf ("Clearing memory\n"); //D_FlushCaches (); Mod_ClearAll (); if (host_hunklevel) // FIXME: check this... Hunk_FreeToLowMark (host_hunklevel); CL_ClearTEnts (); // wipe the entire cl structure memset (&cl, 0, sizeof(cl)); SZ_Clear (&cls.netchan.message); // clear other arrays memset (cl_efrags, 0, sizeof(cl_efrags)); memset (cl_dlights, 0, sizeof(cl_dlights)); memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); // // allocate the efrags and chain together into a free list // cl.free_efrags = cl_efrags; for (i=0 ; i<MAX_EFRAGS-1 ; i++) cl.free_efrags[i].entnext = &cl.free_efrags[i+1]; cl.free_efrags[i].entnext = NULL; }
/* ================ Host_ClearMemory This clears all the memory used by the server, but does not reinitialize anything. ================ */ void Host_ClearMemory (void) { Con_DPrintf ("Clearing memory\n"); Mod_ClearAll (); if (host_hunklevel) Hunk_FreeToLowMark (host_hunklevel); memset (&sv, 0, sizeof(sv)); }
/* ================ Host_ClearMemory This clears all the memory used by both the client and server, but does not reinitialize anything. ================ */ void Host_ClearMemory (void) { Con_DPrintf ("Clearing memory\n"); D_FlushCaches (); Mod_ClearAll (); /* host_hunklevel MUST be set at this point */ Hunk_FreeToLowMark (host_hunklevel); cls.signon = 0; memset (&sv, 0, sizeof(sv)); memset (&cl, 0, sizeof(cl)); }
static qboolean S_XMP_CodecOpenStream (snd_stream_t *stream) { /* need to load the whole file into memory and pass it to libxmp * using xmp_load_module_from_memory() which requires libxmp >= 4.2. * libxmp-4.0/4.1 only have xmp_load_module() which accepts a file * name which isn't good with files in containers like paks, etc. */ xmp_context c; byte *moddata; long len; int mark; c = xmp_create_context(); if (c == NULL) return false; len = FS_filelength (&stream->fh); mark = Hunk_LowMark(); moddata = (byte *) Hunk_Alloc(len); FS_fread(moddata, 1, len, &stream->fh); if (xmp_load_module_from_memory(c, moddata, len) != 0) { Con_DPrintf("Could not load module %s\n", stream->name); goto err1; } Hunk_FreeToLowMark(mark); /* free original file data */ stream->priv = c; if (shm->speed > XMP_MAX_SRATE) stream->info.rate = 44100; else if (shm->speed < XMP_MIN_SRATE) stream->info.rate = 11025; else stream->info.rate = shm->speed; stream->info.bits = shm->samplebits; stream->info.width = stream->info.bits / 8; stream->info.channels = shm->channels; if (S_XMP_StartPlay(stream) != 0) goto err2; /* percentual left/right channel separation, default is 70. */ if (stream->info.channels == 2) if (xmp_set_player(c, XMP_PLAYER_MIX, 100) != 0) goto err3; /* interpolation type, default is XMP_INTERP_LINEAR */ if (xmp_set_player(c, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE) != 0) goto err3; return true; err3: xmp_end_player(c); err2: xmp_release_module(c); err1: xmp_free_context(c); return false; }
/* ================ Host_ClearMemory This clears all the memory used by both the client and server, but does not reinitialize anything. ================ */ void Host_ClearMemory (void) { Con_DPrintf ("Clearing memory\n"); D_FlushCaches (); Mod_ClearAll (); /* host_hunklevel MUST be set at this point */ Hunk_FreeToLowMark (host_hunklevel); cls.signon = 0; if (sv.edicts) free(sv.edicts); // ericw -- sv.edicts switched to use malloc() memset (&sv, 0, sizeof(sv)); memset (&cl, 0, sizeof(cl)); }
void Sky_DrawFace (int axis) { glpoly_t *p; MathVector3f_t verts[4]; int i, j, start; float di,qi,dj,qj; MathVector3f_t v_up, v_right, temp, temp2; Sky_SetBoxVert(-1.0f,-1.0f,axis,verts[0]); Sky_SetBoxVert(-1.0f,1.0f,axis,verts[1]); Sky_SetBoxVert(1.0f,1.0f,axis,verts[2]); Sky_SetBoxVert(1.0f,-1.0f,axis,verts[3]); start = Hunk_LowMark (); p = (glpoly_t*)Hunk_Alloc(sizeof(glpoly_t)); Math_VectorSubtract(verts[2],verts[3], v_up); Math_VectorSubtract(verts[2],verts[1], v_right); di = Math_Max((int)r_sky_quality.value,1); qi = 1.0f/di; dj = (axis < 4) ? di*2 : di; // Subdivide vertically more than horizontally on skybox sides qj = 1.0f/dj; for (i=0; i<di; i++) { for (j=0; j<dj; j++) { if (i*qi < skymins[0][axis]/2+0.5 - qi || i*qi > skymaxs[0][axis]/2+0.5 || j*qj < skymins[1][axis]/2+0.5 - qj || j*qj > skymaxs[1][axis]/2+0.5) continue; //if (i&1 ^ j&1) continue; //checkerboard test Math_VectorScale(v_right, qi*i, temp); Math_VectorScale(v_up, qj*j, temp2); Math_VectorAdd(temp,temp2,temp); Math_VectorAdd(verts[0],temp,p->verts[0]); Math_VectorScale(v_up, qj, temp); Math_VectorAdd(p->verts[0],temp,p->verts[1]); Math_VectorScale(v_right, qi, temp); Math_VectorAdd(p->verts[1],temp,p->verts[2]); Math_VectorAdd(p->verts[0],temp,p->verts[3]); Sky_DrawFaceQuad(p); } } Hunk_FreeToLowMark(start); }
//Free hunk memory up to host_hunklevel //Can only be called when changing levels! void Host_ClearMemory (void) { // FIXME, move to CL_ClearState D_FlushCaches (); // FIXME, move to CL_ClearState Mod_ClearAll (); CM_InvalidateMap (); // any data previously allocated on hunk is no longer valid Hunk_FreeToLowMark (host_hunklevel); }
/* =============== Cmd_Exec_f =============== */ void Cmd_Exec_f (void) { char *f; int mark; char name[MAX_OSPATH]; if (Cmd_Argc () != 2) { Com_Printf ("exec <filename> : execute a script file\n"); return; } strlcpy (name, Cmd_Argv(1), sizeof(name) - 4); mark = Hunk_LowMark (); f = (char *)FS_LoadHunkFile (name); if (!f) { char *p; p = COM_SkipPath (name); if (!strchr (p, '.')) { // no extension, so try the default (.cfg) strcat (name, ".cfg"); f = (char *)FS_LoadHunkFile (name); } if (!f) { Com_Printf ("couldn't exec %s\n", Cmd_Argv(1)); return; } } if (cl_warncmd.value || developer.value) Com_Printf ("execing %s\n", name); #ifndef SERVERONLY if (cbuf_current == &cbuf_svc) { Cbuf_AddText (f); Cbuf_AddText ("\n"); } else #endif { Cbuf_InsertText ("\n"); Cbuf_InsertText (f); } Hunk_FreeToLowMark (mark); }
/* =============== Host_ClearMemory Free hunk memory up to host_hunklevel Can only be called when changing levels! =============== */ void Host_ClearMemory () { // FIXME, move to CL_ClearState if (!dedicated) D_FlushCaches (); // FIXME, move to CL_ClearState #ifndef SERVERONLY if (!dedicated) Mod_ClearAll (); #endif CM_InvalidateMap (); // any data previously allocated on hunk is no longer valid Hunk_FreeToLowMark (host_hunklevel); }
void CL_ClearState (void) { int i; S_StopAllSounds (); // wipe the entire cl structure if (cl.serverinfo) Info_Destroy (cl.serverinfo); memset (&cl, 0, sizeof (cl)); r_data->force_fullscreen = 0; cl.maxclients = MAX_CLIENTS; // Note: we should probably hack around this and give diff values for // diff gamedirs cl.fpd = FPD_DEFAULT; cl.fbskins = FBSKINS_DEFAULT; for (i = 0; i < UPDATE_BACKUP; i++) cl.frames[i].packet_entities.entities = qw_entstates.frame[i]; cl.serverinfo = Info_ParseString ("", MAX_INFO_STRING, 0); CL_Init_Entity (&cl.viewent); Sys_MaskPrintf (SYS_DEV, "Clearing memory\n"); if (viddef.flush_caches) viddef.flush_caches (); Mod_ClearAll (); if (host_hunklevel) // FIXME: check this... Hunk_FreeToLowMark (host_hunklevel); CL_ClearEnts (); CL_ClearTEnts (); r_funcs->R_ClearState (); SZ_Clear (&cls.netchan.message); if (centerprint) dstring_clearstr (centerprint); }
/* =============== Cmd_Exec_f =============== */ void Cmd_Exec_f (void) { char *f; int mark; if (Cmd_Argc () != 2) { Con_Printf ("exec <filename> : execute a script file\n"); return; } mark = Hunk_LowMark (); f = (char *)COM_LoadHunkFile (Cmd_Argv(1)); if (!f) { Con_Printf ("couldn't exec %s\n",Cmd_Argv(1)); return; } Con_Printf ("execing %s\n",Cmd_Argv(1)); Cbuf_InsertText (f); Hunk_FreeToLowMark (mark); }
static void Cmd_Exec_f (void) { char *f; int mark; if (Cmd_Argc () != 2) { Sys_Printf ("exec <filename> : execute a script file\n"); return; } mark = Hunk_LowMark (); f = (char *) QFS_LoadHunkFile (Cmd_Argv (1)); if (!f) { Sys_Printf ("couldn't exec %s\n", Cmd_Argv (1)); return; } if (!Cvar_Command () && (cmd_warncmd->int_val || (developer && developer->int_val & SYS_DEV))) Sys_Printf ("execing %s\n", Cmd_Argv (1)); Cbuf_InsertText (cbuf_active, f); Hunk_FreeToLowMark (mark); }
/* ================= Mod_LoadLighting ================= */ void Mod_LoadLighting (lump_t *l) { int mark; #ifndef RQM_SV_ONLY int i; byte *in, *out/*, d*/; byte *data; char *litfilename; int lit_ver; #endif loadmodel->lightdata = NULL; loadmodel->lightdatadepth = 1; // JDH // if (!l->filelen) // return; // check for a .lit file mark = Hunk_LowMark (); #ifndef RQM_SV_ONLY data = LoadColoredLighting (loadmodel->name, &litfilename); if (data) { if (com_filesize < 8 || strncmp((char *)data, "QLIT", 4)) Con_Printf ("\x02""Corrupt .lit file (%s)...ignoring\n", COM_SkipPath(litfilename)); else if (l->filelen * 3 + 8 != com_filesize) Con_Printf ("\x02""Warning: .lit file (%s) has incorrect size\n", COM_SkipPath(litfilename)); else if ((lit_ver = LittleLong(((int *)data)[1])) != 1) Con_Printf ("\x02""Unknown .lit file version (v%d)\n", lit_ver); else { Con_DPrintf ("Static coloured lighting loaded\n"); loadmodel->lightdata = data + 8; loadmodel->lightdatadepth = 3; in = mod_base + l->fileofs; out = loadmodel->lightdata; for (i=0 ; i<l->filelen ; i++) { int b = max(out[3*i], max(out[3*i+1], out[3*i+2])); if (!b) out[3*i] = out[3*i+1] = out[3*i+2] = in[i]; else { // too bright float r = in[i] / (float)b; out[3*i+0] = (int)(r * out[3*i+0]); out[3*i+1] = (int)(r * out[3*i+1]); out[3*i+2] = (int)(r * out[3*i+2]); } } return; } Hunk_FreeToLowMark (mark); } #endif if (!l->filelen) { //loadmodel->lightdata = NULL; return; } // no .lit found, expand the white lighting data to color #if 0 loadmodel->lightdata = Hunk_AllocName (l->filelen * 3, va("%s_@lightdata", loadmodel->name)); loadmodel->lightdatadepth = 3; // place the file at the end, so it will not be overwritten until the very last write //in = loadmodel->lightdata + l->filelen * 2; in = mod_base + l->fileofs; out = loadmodel->lightdata; //memcpy (in, mod_base + l->fileofs, l->filelen); for (i = 0 ; i < l->filelen ; i++, out += 3) { out[0] = out[1] = out[2] = *in++; } #else loadmodel->lightdata = Hunk_AllocName (l->filelen, "lights"); memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); #endif }
void SV_PushMove (edict_t *pusher, float movetime) { int i, e; edict_t *check, *block; vec3_t mins, maxs, move; vec3_t entorig, pushorig; int num_moved; edict_t **moved_edict; //johnfitz -- dynamically allocate vec3_t *moved_from; //johnfitz -- dynamically allocate int mark; //johnfitz if(!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2]) { pusher->v.ltime += movetime; return; } for (i=0 ; i<3 ; i++) { move[i] = pusher->v.velocity[i] * movetime; mins[i] = pusher->v.absmin[i] + move[i]; maxs[i] = pusher->v.absmax[i] + move[i]; } Math_VectorCopy (pusher->v.origin, pushorig); // move the pusher to it's final position Math_VectorAdd (pusher->v.origin, move, pusher->v.origin); pusher->v.ltime += movetime; SV_LinkEdict(pusher,false); //johnfitz -- dynamically allocate mark = Hunk_LowMark (); moved_edict = (edict_t**)Hunk_Alloc(sv.num_edicts*sizeof(edict_t*)); moved_from = (vec3_t(*))Hunk_Alloc (sv.num_edicts*sizeof(vec3_t)); //johnfitz // see if any solid entities are inside the final position num_moved = 0; check = NEXT_EDICT(sv.edicts); for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check)) { if (check->free) continue; if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE || check->v.movetype == MOVETYPE_NOCLIP) continue; // if the entity is standing on the pusher, it will definately be moved if(!((check->v.flags & FL_ONGROUND) && check->v.groundentity == pusher)) { if ( check->v.absmin[0] >= maxs[0] || check->v.absmin[1] >= maxs[1] || check->v.absmin[2] >= maxs[2] || check->v.absmax[0] <= mins[0] || check->v.absmax[1] <= mins[1] || check->v.absmax[2] <= mins[2] ) continue; // see if the ent's bbox is inside the pusher's final position if (!SV_TestEntityPosition (check)) continue; } // remove the onground flag for non-players if (check->v.movetype != MOVETYPE_WALK) check->v.flags = check->v.flags & ~FL_ONGROUND; Math_VectorCopy(check->v.origin,entorig); Math_VectorCopy(check->v.origin,moved_from[num_moved]); moved_edict[num_moved] = check; num_moved++; // try moving the contacted entity pusher->Physics.iSolid = SOLID_NOT; SV_PushEntity (check, move); pusher->Physics.iSolid = SOLID_BSP; // if it is still inside the pusher, block block = SV_TestEntityPosition (check); if (block) { // fail the move if (check->v.mins[0] == check->v.maxs[0]) continue; if (check->Physics.iSolid == SOLID_NOT || check->Physics.iSolid == SOLID_TRIGGER) { // corpse check->v.mins[0] = check->v.mins[1] = 0; Math_VectorCopy(check->v.mins,check->v.maxs); continue; } Math_VectorCopy(entorig,check->v.origin); SV_LinkEdict(check,true); Math_VectorCopy(pushorig,pusher->v.origin); SV_LinkEdict(pusher,false); pusher->v.ltime -= movetime; // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone if(pusher->v.blocked) { pr_global_struct.self = EDICT_TO_PROG(pusher); pr_global_struct.eOther = check; pusher->v.blocked(pusher,check); } // move back any entities we already moved for (i=0 ; i<num_moved ; i++) { Math_VectorCopy(moved_from[i],moved_edict[i]->v.origin); SV_LinkEdict (moved_edict[i], false); } Hunk_FreeToLowMark (mark); //johnfitz return; } } Hunk_FreeToLowMark (mark); //johnfitz }
/* ============= EmitWaterPolys Does a water warp on the pre-fragmented glpoly_t chain ============= */ void EmitWaterPolys (msurface_t *fa) { glpoly_t *p; float *v; int i; float s, t, os, ot; int mark = Hunk_LowMark (); int segmentcount = 0; for (p=fa->polys ; p ; p=p->next) { segmentcount++; } GLsizei* segments = Hunk_AllocName (segmentcount * sizeof(GLsizei), "segments"); int segmentpos = 0; int vertexcount = 0; for (p=fa->polys ; p ; p=p->next) { segments[segmentpos++] = p->numverts; vertexcount += p->numverts; } GLfloat* vertices = Hunk_AllocName (vertexcount * 5 * sizeof(GLfloat), "vertex_buffer"); int vertexpos = 0; for (p=fa->polys ; p ; p=p->next) { for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE) { os = v[3]; ot = v[4]; s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255]; s *= (1.0/64); t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255]; t *= (1.0/64); vertices[vertexpos++] = v[0]; vertices[vertexpos++] = v[1]; vertices[vertexpos++] = v[2]; vertices[vertexpos++] = s; vertices[vertexpos++] = t; } } GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, vertexcount * 5 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(gl_waterpolygon_position); glVertexAttribPointer(gl_waterpolygon_position, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const GLvoid *)0); glEnableVertexAttribArray(gl_waterpolygon_texcoords); glVertexAttribPointer(gl_waterpolygon_texcoords, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const GLvoid *)(3 * sizeof(GLfloat))); GLsizei offset = 0; for (int i = 0; i < segmentcount; i++) { GLsizei count = segments[i]; glDrawArrays(GL_TRIANGLE_FAN, offset, count); offset += count; } glDisableVertexAttribArray(gl_waterpolygon_texcoords); glDisableVertexAttribArray(gl_waterpolygon_position); glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &vertexbuffer); Hunk_FreeToLowMark (mark); }
/* ================= Mod_LoadAliasModel ================= */ void Mod_LoadAliasModel(const model_loader_t *loader, model_t *mod, void *buffer, const model_t *loadmodel, const char *loadname) { byte *container; int i, j, pad; mdl_t *pinmodel; stvert_t *pinstverts; dtriangle_t *pintriangles; int version, numframes; int size; daliasframetype_t *pframetype; daliasframe_t *frame; daliasgroup_t *group; daliasskintype_t *pskintype; int start, end, total; float *intervals; #ifdef QW_HACK const char *crcmodel = NULL; if (!strcmp(loadmodel->name, "progs/player.mdl")) crcmodel = "pmodel"; if (!strcmp(loadmodel->name, "progs/eyes.mdl")) crcmodel = "emodel"; if (crcmodel) { uint16_t crc = CRC_Block(buffer, com_filesize); Info_SetValueForKey(cls.userinfo, crcmodel, va("%d", (int)crc), MAX_INFO_STRING); if (cls.state >= ca_connected) { MSG_WriteByte(&cls.netchan.message, clc_stringcmd); MSG_WriteStringf(&cls.netchan.message, "setinfo %s %d", crcmodel, (int)crc); } } #endif start = Hunk_LowMark(); pinmodel = (mdl_t *)buffer; #ifdef MSB_FIRST version = LittleLong(pinmodel->version); #else version = (pinmodel->version); #endif if (version != ALIAS_VERSION) Sys_Error("%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); // allocate space for a working header, plus all the data except the frames, // skin and group info pad = loader->Aliashdr_Padding(); #ifdef MSB_FIRST size = pad + sizeof(aliashdr_t) + LittleLong(pinmodel->numframes) * sizeof(pheader->frames[0]); #else size = pad + sizeof(aliashdr_t) + (pinmodel->numframes) * sizeof(pheader->frames[0]); #endif container = (byte*)Hunk_AllocName(size, loadname); pheader = (aliashdr_t *)(container + pad); #ifdef MSB_FIRST mod->flags = LittleLong(pinmodel->flags); // endian-adjust and copy the data, starting with the alias model header pheader->numskins = LittleLong(pinmodel->numskins); pheader->skinwidth = LittleLong(pinmodel->skinwidth); pheader->skinheight = LittleLong(pinmodel->skinheight); #else mod->flags = (pinmodel->flags); pheader->numskins = (pinmodel->numskins); pheader->skinwidth = (pinmodel->skinwidth); pheader->skinheight = (pinmodel->skinheight); #endif if (pheader->skinheight > MAX_LBM_HEIGHT) Sys_Error("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); #ifdef MSB_FIRST pheader->numverts = LittleLong(pinmodel->numverts); #else pheader->numverts = (pinmodel->numverts); #endif if (pheader->numverts <= 0) Sys_Error("model %s has no vertices", mod->name); if (pheader->numverts > MAXALIASVERTS) Sys_Error("model %s has too many vertices", mod->name); #ifdef MSB_FIRST pheader->numtris = LittleLong(pinmodel->numtris); #else pheader->numtris = (pinmodel->numtris); #endif if (pheader->numtris <= 0) Sys_Error("model %s has no triangles", mod->name); #ifdef MSB_FIRST pheader->numframes = LittleLong(pinmodel->numframes); pheader->size = LittleFloat(pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = (synctype_t)LittleLong(pinmodel->synctype); #else pheader->numframes = (pinmodel->numframes); pheader->size = (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = (synctype_t)(pinmodel->synctype); #endif mod->numframes = pheader->numframes; for (i = 0; i < 3; i++) { #ifdef MSB_FIRST pheader->scale[i] = LittleFloat(pinmodel->scale[i]); pheader->scale_origin[i] = LittleFloat(pinmodel->scale_origin[i]); #else pheader->scale[i] = (pinmodel->scale[i]); pheader->scale_origin[i] = (pinmodel->scale_origin[i]); #endif } // load the skins pskintype = (daliasskintype_t *)&pinmodel[1]; pskintype = (daliasskintype_t *)Mod_LoadAllSkins(loader, loadmodel, pheader->numskins, pskintype, loadname); // set base s and t vertices pinstverts = (stvert_t *)pskintype; for (i = 0; i < pheader->numverts; i++) { #ifdef MSB_FIRST stverts[i].onseam = LittleLong(pinstverts[i].onseam); stverts[i].s = LittleLong(pinstverts[i].s); stverts[i].t = LittleLong(pinstverts[i].t); #else stverts[i].onseam = (pinstverts[i].onseam); stverts[i].s = (pinstverts[i].s); stverts[i].t = (pinstverts[i].t); #endif } // set up the triangles pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; for (i = 0; i < pheader->numtris; i++) { #ifdef MSB_FIRST triangles[i].facesfront = LittleLong(pintriangles[i].facesfront); #else triangles[i].facesfront = (pintriangles[i].facesfront); #endif for (j = 0; j < 3; j++) { #ifdef MSB_FIRST triangles[i].vertindex[j] = LittleLong(pintriangles[i].vertindex[j]); #else triangles[i].vertindex[j] = (pintriangles[i].vertindex[j]); #endif if (triangles[i].vertindex[j] < 0 || triangles[i].vertindex[j] >= pheader->numverts) Sys_Error("%s: invalid vertex index (%d of %d) in %s\n", __func__, triangles[i].vertindex[j], pheader->numverts, mod->name); } } /* load the frames */ numframes = pheader->numframes; if (numframes < 1) Sys_Error("%s: Invalid # of frames: %d", __func__, numframes); posenum = 0; pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; for (i = 0; i < numframes; i++) { #ifdef MSB_FIRST if (LittleLong(pframetype->type) == ALIAS_SINGLE) #else if ((pframetype->type) == ALIAS_SINGLE) #endif { frame = (daliasframe_t *)(pframetype + 1); Mod_LoadAliasFrame(frame, &pheader->frames[i]); pframetype = (daliasframetype_t *)&frame->verts[pheader->numverts]; } else { group = (daliasgroup_t *)(pframetype + 1); pframetype = Mod_LoadAliasGroup(group, &pheader->frames[i], loadname); } } pheader->numposes = posenum; mod->type = mod_alias; // FIXME: do this right mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; /* Save the frame intervals */ intervals = (float*)Hunk_Alloc(pheader->numposes * sizeof(float)); pheader->poseintervals = (byte *)intervals - (byte *)pheader; for (i = 0; i < pheader->numposes; i++) intervals[i] = poseintervals[i]; /* Save the mesh data (verts, stverts, triangles) */ loader->LoadMeshData(loadmodel, pheader, triangles, stverts, poseverts); // move the complete, relocatable alias model to the cache end = Hunk_LowMark(); total = end - start; Cache_AllocPadded(&mod->cache, pad, total - pad, loadname); if (!mod->cache.data) return; memcpy((byte *)mod->cache.data - pad, container, total); Hunk_FreeToLowMark(start); }
void Sky_ProcessEntities(void) { int i,k,mark; unsigned int j; float dot; bool bRotated; ClientEntity_t *e; msurface_t *s; glpoly_t *p; MathVector3f_t vTemp, forward, right, up; if (!r_drawentities.value) return; for (i=0 ; i<cl_numvisedicts ; i++) { e = cl_visedicts[i]; if (e->model->type != MODEL_TYPE_LEVEL) continue; if(R_CullModelForEntity(e)) continue; if(e->alpha == ENTALPHA_ZERO) continue; Math_VectorSubtract (r_refdef.vieworg, e->origin, modelorg); if(e->angles[0] || e->angles[1] || e->angles[2]) { bRotated = true; Math_AngleVectors(e->angles, forward, right, up); Math_VectorCopy(modelorg,vTemp); modelorg[0] = Math_DotProduct(vTemp,forward); modelorg[1] = -Math_DotProduct(vTemp,right); modelorg[2] = Math_DotProduct(vTemp,up); } else bRotated = false; s = &e->model->surfaces[e->model->firstmodelsurface]; for (j=0 ; j<e->model->nummodelsurfaces ; j++, s++) { if (s->flags & SURF_DRAWSKY) { dot = Math_DotProduct (modelorg, s->plane->normal) - s->plane->dist; if (((s->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || (!(s->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) { //copy the polygon and translate manually, since Sky_ProcessPoly needs it to be in world space mark = Hunk_LowMark(); p = (glpoly_t*)Hunk_Alloc (sizeof(*s->polys)); //FIXME: don't allocate for each poly p->numverts = s->polys->numverts; for (k=0; k<p->numverts; k++) { if(bRotated) { p->verts[k][0] = e->origin[0] + s->polys->verts[k][0] * forward[0] - s->polys->verts[k][1] * right[0] + s->polys->verts[k][2] * up[0]; p->verts[k][1] = e->origin[1] + s->polys->verts[k][0] * forward[1] - s->polys->verts[k][1] * right[1] + s->polys->verts[k][2] * up[1]; p->verts[k][2] = e->origin[2] + s->polys->verts[k][0] * forward[2] - s->polys->verts[k][1] * right[2] + s->polys->verts[k][2] * up[2]; } else Math_VectorAdd(s->polys->verts[k], e->origin, p->verts[k]); } Sky_ProcessPoly (p); Hunk_FreeToLowMark (mark); } } } } }
/* ============= EmitSkyPolys ============= */ void EmitSkyPolys (msurface_t *fa) { glpoly_t *p; float *v; int i; float s, t; vec3_t dir; float length; int mark = Hunk_LowMark (); int segmentcount = 0; for (p=fa->polys ; p ; p=p->next) { segmentcount++; } GLsizei* segments = Hunk_AllocName (segmentcount * sizeof(GLsizei), "segments"); int segmentpos = 0; int vertexcount = 0; for (p=fa->polys ; p ; p=p->next) { segments[segmentpos++] = p->numverts; vertexcount += p->numverts; } GLfloat* vertices = Hunk_AllocName (vertexcount * 5 * sizeof(GLfloat), "vertex_buffer"); int vertexpos = 0; for (p=fa->polys ; p ; p=p->next) { for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE) { VectorSubtract (v, r_origin, dir); dir[2] *= 3; // flatten the sphere length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; length = sqrt (length); length = 6*63/length; dir[0] *= length; dir[1] *= length; s = (speedscale + dir[0]) * (1.0/128); t = (speedscale + dir[1]) * (1.0/128); vertices[vertexpos++] = v[0]; vertices[vertexpos++] = v[1]; vertices[vertexpos++] = v[2]; vertices[vertexpos++] = s; vertices[vertexpos++] = t; } } GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, vertexcount * 5 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(gl_polygon1textureprogram_position); glVertexAttribPointer(gl_polygon1textureprogram_position, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const GLvoid *)0); glEnableVertexAttribArray(gl_polygon1textureprogram_texcoords); glVertexAttribPointer(gl_polygon1textureprogram_texcoords, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const GLvoid *)(3 * sizeof(GLfloat))); GLsizei offset = 0; for (int i = 0; i < segmentcount; i++) { GLsizei count = segments[i]; glDrawArrays(GL_TRIANGLE_FAN, offset, count); offset += count; } glDisableVertexAttribArray(gl_polygon1textureprogram_texcoords); glDisableVertexAttribArray(gl_polygon1textureprogram_position); glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &vertexbuffer); Hunk_FreeToLowMark (mark); }
void Sky_LoadSkyBox (char *name) { int i, mark; unsigned int width, height; char filename[PLATFORM_MAX_PATH]; bool bNoneFound = true; uint8_t *data; if(strcmp(cSkyBoxName, name) == 0) return; //no change // Purge old textures for(i = 0; i < 6; i++) { if(gSkyBoxTexture[i] && gSkyBoxTexture[i] != notexture) TexMgr_FreeTexture(gSkyBoxTexture[i]); gSkyBoxTexture[i] = NULL; } // Turn off skybox if sky is set to "" if(name[0] == 0) { cSkyBoxName[0] = 0; return; } // Load textures for (i=0; i<6; i++) { mark = Hunk_LowMark (); sprintf(filename, "%ssky/%s%s", g_state.cTexturePath, name, suf[i]); data = Image_LoadImage (filename, &width, &height); if (data) { gSkyBoxTexture[i] = TexMgr_LoadImage (cl.worldmodel, filename, width, height, SRC_RGBA, data, filename, 0, TEXPREF_NONE); bNoneFound = false; } else { Con_Warning("Couldn't load %s\n", filename); gSkyBoxTexture[i] = notexture; } Hunk_FreeToLowMark (mark); } if(bNoneFound) // go back to scrolling sky if skybox is totally missing { for(i = 0; i < 6; i++) { if(gSkyBoxTexture[i] && gSkyBoxTexture[i] != notexture) TexMgr_FreeTexture(gSkyBoxTexture[i]); gSkyBoxTexture[i] = NULL; } cSkyBoxName[0] = 0; return; } strcpy(cSkyBoxName, name); }
/* ================= Mod_LoadAliasModel ================= */ void Mod_LoadAliasModel (model_t *mod, void *buffer) { int i, j; mdl_t *pinmodel; stvert_t *pinstverts; dtriangle_t *pintriangles; int version, numframes, numskins; int size; daliasframetype_t *pframetype; daliasskintype_t *pskintype; int start, end, total; start = Hunk_LowMark (); pinmodel = (mdl_t *)buffer; version = LittleLong (pinmodel->version); if (version != ALIAS_VERSION) Sys_Error ("%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); // // allocate space for a working header, plus all the data except the frames, // skin and group info // size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * sizeof (pheader->frames[0]); pheader = Hunk_AllocName (size, loadname); mod->flags = LittleLong (pinmodel->flags); // // endian-adjust and copy the data, starting with the alias model header // pheader->boundingradius = LittleFloat (pinmodel->boundingradius); pheader->numskins = LittleLong (pinmodel->numskins); pheader->skinwidth = LittleLong (pinmodel->skinwidth); pheader->skinheight = LittleLong (pinmodel->skinheight); if (pheader->skinheight > MAX_LBM_HEIGHT) Sys_Error ("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); pheader->numverts = LittleLong (pinmodel->numverts); if (pheader->numverts <= 0) Sys_Error ("model %s has no vertices", mod->name); if (pheader->numverts > MAXALIASVERTS) Sys_Error ("model %s has too many vertices", mod->name); pheader->numtris = LittleLong (pinmodel->numtris); if (pheader->numtris <= 0) Sys_Error ("model %s has no triangles", mod->name); pheader->numframes = LittleLong (pinmodel->numframes); numframes = pheader->numframes; if (numframes < 1) Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = LittleLong (pinmodel->synctype); mod->numframes = pheader->numframes; for (i=0 ; i<3 ; i++) { pheader->scale[i] = LittleFloat (pinmodel->scale[i]); pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); } // // load the skins // pskintype = (daliasskintype_t *)&pinmodel[1]; pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); // // load base s and t vertices // pinstverts = (stvert_t *)pskintype; for (i=0 ; i<pheader->numverts ; i++) { stverts[i].onseam = LittleLong (pinstverts[i].onseam); stverts[i].s = LittleLong (pinstverts[i].s); stverts[i].t = LittleLong (pinstverts[i].t); } // // load triangle lists // pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; for (i=0 ; i<pheader->numtris ; i++) { triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); for (j=0 ; j<3 ; j++) { triangles[i].vertindex[j] = LittleLong (pintriangles[i].vertindex[j]); } } // // load the frames // posenum = 0; pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; for (i=0 ; i<numframes ; i++) { aliasframetype_t frametype; frametype = LittleLong (pframetype->type); if (frametype == ALIAS_SINGLE) { pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); } else { pframetype = (daliasframetype_t *) Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); } } pheader->numposes = posenum; mod->type = mod_alias; // FIXME: do this right mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; #if ALIAS_VBO /////////////////////////////////////////////////////////// // //create a gl VBO object so we don't have to send this data each frame // //FORMAT [TEXTURE DATA BLOCK] // [VERTEX BLOCK FRAME 0] // [VERTEX BLOCK FRAME 1] // [VERTEX BLOCK FRAME 2] // ... // [VERTEX BLOCK FRAME N] //int numfloats = pheader->numposes * pheader->numtris * /*floats per verts*/ 9 * /*verts per triangle*/ 3; int numGLVerts = pheader->numposes * pheader->numtris * 3; glAliasData* gpuBoundData = (glAliasData*)malloc(sizeof(glAliasData)*numGLVerts); int processedIndex = 0; int f, t, v; for (f=0 ; f<pheader->numposes ; f++) { for (t = 0; t < pheader->numtris; t++) { for(v=0; v<3; v++){ // int vIdx = triangles[t].vertindex[v]; const trivertx_t* pVtx = &poseverts[f][vIdx]; //pintriangles[t].facesfront; byte x = pVtx->v[0]; //render code applies scale + translation byte y = pVtx->v[1]; byte z = pVtx->v[2]; /* Compute texture coordinates */ float cs = stverts[vIdx].s; float ct = stverts[vIdx].t; if (!triangles[t].facesfront && stverts[vIdx].onseam) { cs += pheader->skinwidth * 0.5f; } cs = (cs + 0.5f) / pheader->skinwidth; ct = (ct + 0.5f) / pheader->skinheight; gpuBoundData[processedIndex].st[0] = (unsigned char)(255 * cs); gpuBoundData[processedIndex].st[1] = (unsigned char)(255 * ct); //gpuBoundData[processedIndex].st[0] = cs; //gpuBoundData[processedIndex].st[1] = ct; gpuBoundData[processedIndex].pos[0] = x; gpuBoundData[processedIndex].pos[1] = y; gpuBoundData[processedIndex].pos[2] = z; gpuBoundData[processedIndex].lightNormalIndex = pVtx->lightnormalindex; processedIndex++; } } } CreatAliasBuffers(&pheader->vbo_offset,numGLVerts,gpuBoundData); free(gpuBoundData); //JAMES //we can brobably safely ditch most of what is below, just a waste of memory now #endif //ALIAS_VBO /////////////////////////////////////////////////////////// // // build the draw lists // GL_MakeAliasModelDisplayLists (mod, pheader); // // move the complete, relocatable alias model to the cache // end = Hunk_LowMark (); total = end - start; Cache_Alloc (&mod->cache, total, loadname); if (!mod->cache.data) return; memcpy (mod->cache.data, pheader, total); Hunk_FreeToLowMark (start); }
void Sky_LoadCubeMap (char *name) { #if 0 int i, mark, width[6], height[6]; char filename[MAX_OSPATH]; byte *data[6]; qbool nonefound = true; int largest; // so that I can call Sky_LoadCubeMap (NULL) to flush a texture. if (!name) { // purge old texture Sky_ClearSkybox (); return; } // no change if (strcmp (skybox_name, name) == 0) return; // purge old texture Sky_ClearSkybox (); // turn off skybox if sky is set to "" if (name[0] == 0) { skybox_name[0] = 0; return; } mark = Hunk_LowMark (); // skybox faces must all be square and the same dimension so track the largest largest = 0; // load textures for (i=0 ; i<6 ; i++) { sprintf (filename, "gfx/env/%s%s", name, suf[i]); data[i] = Image_LoadImage (filename, &width[i], &height[i]); if (data[i]) { // skybox faces must all be square and the same dimension so track the largest if (width[i] > largest) largest = width[i]; if (height[i] > largest) largest = height[i]; } else width[i] = height[i] = 0; } // fixme - this could get a mite cleaner if (largest > 0) { // now let's see what we got byte *cubebuffer = NULL; glBindTexture (GL_TEXTURE_2D, 0); glDisable (GL_TEXTURE_2D); glEnable (GL_TEXTURE_CUBE_MAP); glGenTextures (1, &skyCubeTexture); glBindTexture (GL_TEXTURE_CUBE_MAP, skyCubeTexture); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // ATI strikes again - cubemaps should be loaded in a specific order for (i = 0; i < 6; i++) { if (!data[loadorder[i]]) { if (!cubebuffer) cubebuffer = (byte *) Hunk_Alloc (largest * largest * 4); memset (cubebuffer, 0, largest * largest * 4); data[loadorder[i]] = cubebuffer; width[loadorder[i]] = largest; height[loadorder[i]] = largest; } if (width[loadorder[i]] != largest || height[loadorder[i]] != largest) { if (!cubebuffer) cubebuffer = (byte *) Hunk_Alloc (largest * largest * 4); // upsize to cube buffer and set back GL_Resample32BitTexture ((unsigned *) data[loadorder[i]], width[loadorder[i]], height[loadorder[i]], (unsigned *) cubebuffer, largest, largest); data[loadorder[i]] = cubebuffer; width[loadorder[i]] = largest; height[loadorder[i]] = largest; } switch (loadorder[i]) { case 0: D3D_RotateTexelsInPlace ((unsigned int *) data[0], width[0]); break; case 1: D3D_FlipTexels ((unsigned int *) data[1], width[1], height[1]); break; case 2: D3D_RotateTexelsInPlace ((unsigned int *) data[2], width[2]); D3D_MirrorTexels ((unsigned int *) data[2], width[2], height[2]); D3D_FlipTexels ((unsigned int *) data[2], width[2], height[2]); break; case 3: D3D_MirrorTexels ((unsigned int *) data[3], width[3], height[3]); break; case 4: D3D_RotateTexelsInPlace ((unsigned int *) data[4], width[4]); break; case 5: D3D_RotateTexelsInPlace ((unsigned int *) data[5], width[5]); break; } // standard face glTexImage2D (cubefaces[i], 0, GL_RGBA8, largest, largest, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data[loadorder[i]]); nonefound = false; } glBindTexture (GL_TEXTURE_CUBE_MAP, 0); glDisable (GL_TEXTURE_CUBE_MAP); glEnable (GL_TEXTURE_2D); GL_BindTexture (GL_TEXTURE0, NULL); } Hunk_FreeToLowMark (mark); if (nonefound) // go back to scrolling sky if skybox is totally missing { Sky_ClearSkybox (); Com_Printf ("Couldn't load %s\n", name); return; } strcpy (skybox_name, name); Com_DPrintf ("loaded skybox %s OK\n", name); #endif }
/* ================= Mod_LoadAliasModel ================= */ void Mod_LoadAliasModel (model_t *mod, void *buffer) { int i, j; mdl_t *pinmodel; stvert_t *pinstverts; dtriangle_t *pintriangles; int version, numframes; int size; daliasframetype_t *pframetype; daliasskintype_t *pskintype; int start, end, total; if (!strcmp(loadmodel->name, "progs/player.mdl") || !strcmp(loadmodel->name, "progs/eyes.mdl")) { unsigned short crc; byte *p; int len; char st[40]; CRC_Init(&crc); for (len = com_filesize, p = buffer; len; len--, p++) CRC_ProcessByte(&crc, *p); sprintf(st, "%d", (int) crc); Info_SetValueForKey (cls.userinfo, !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name, st, MAX_INFO_STRING); if (cls.state >= ca_connected) { MSG_WriteByte (&cls.netchan.message, clc_stringcmd); sprintf(st, "setinfo %s %d", !strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name, (int)crc); SZ_Print (&cls.netchan.message, st); } } start = Hunk_LowMark (); pinmodel = (mdl_t *)buffer; version = LittleLong (pinmodel->version); if (version != ALIAS_VERSION) Sys_Error ("%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); // // allocate space for a working header, plus all the data except the frames, // skin and group info // size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * sizeof (pheader->frames[0]); pheader = Hunk_AllocName (size, loadname); mod->flags = LittleLong (pinmodel->flags); // // endian-adjust and copy the data, starting with the alias model header // pheader->boundingradius = LittleFloat (pinmodel->boundingradius); pheader->numskins = LittleLong (pinmodel->numskins); pheader->skinwidth = LittleLong (pinmodel->skinwidth); pheader->skinheight = LittleLong (pinmodel->skinheight); if (pheader->skinheight > MAX_LBM_HEIGHT) Sys_Error ("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); pheader->numverts = LittleLong (pinmodel->numverts); if (pheader->numverts <= 0) Sys_Error ("model %s has no vertices", mod->name); if (pheader->numverts > MAXALIASVERTS) Sys_Error ("model %s has too many vertices", mod->name); pheader->numtris = LittleLong (pinmodel->numtris); if (pheader->numtris <= 0) Sys_Error ("model %s has no triangles", mod->name); pheader->numframes = LittleLong (pinmodel->numframes); numframes = pheader->numframes; if (numframes < 1) Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = LittleLong (pinmodel->synctype); mod->numframes = pheader->numframes; for (i=0 ; i<3 ; i++) { pheader->scale[i] = LittleFloat (pinmodel->scale[i]); pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); } // // load the skins // pskintype = (daliasskintype_t *)&pinmodel[1]; pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); // // load base s and t vertices // pinstverts = (stvert_t *)pskintype; for (i=0 ; i<pheader->numverts ; i++) { stverts[i].onseam = LittleLong (pinstverts[i].onseam); stverts[i].s = LittleLong (pinstverts[i].s); stverts[i].t = LittleLong (pinstverts[i].t); } // // load triangle lists // pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; for (i=0 ; i<pheader->numtris ; i++) { triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); for (j=0 ; j<3 ; j++) { triangles[i].vertindex[j] = LittleLong (pintriangles[i].vertindex[j]); } } // // load the frames // posenum = 0; pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; for (i=0 ; i<numframes ; i++) { aliasframetype_t frametype; frametype = LittleLong (pframetype->type); if (frametype == ALIAS_SINGLE) { pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); } else { pframetype = (daliasframetype_t *) Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); } } pheader->numposes = posenum; mod->type = mod_alias; // FIXME: do this right mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; // // build the draw lists // GL_MakeAliasModelDisplayLists (mod, pheader); // // move the complete, relocatable alias model to the cache // end = Hunk_LowMark (); total = end - start; Cache_Alloc (&mod->cache, total, loadname); if (!mod->cache.data) return; memcpy (mod->cache.data, pheader, total); Hunk_FreeToLowMark (start); }
/* ================= Mod_LoadAliasModel ================= */ void Mod_LoadAliasModel (model_t *mod, void *buffer) { int i; mdl_t *pmodel, *pinmodel; stvert_t *pstverts, *pinstverts; aliashdr_t *pheader; mtriangle_t *ptri; dtriangle_t *pintriangles; int version, numframes, numskins; int size; daliasframetype_t *pframetype; daliasskintype_t *pskintype; maliasskindesc_t *pskindesc; int skinsize; int start, end, total; start = Hunk_LowMark (); pinmodel = (mdl_t *)buffer; version = LittleLong (pinmodel->version); if (version != ALIAS_VERSION) Sys_Error ("%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); // // allocate space for a working header, plus all the data except the frames, // skin and group info // size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * sizeof (pheader->frames[0]) + sizeof (mdl_t) + LittleLong (pinmodel->numverts) * sizeof (stvert_t) + LittleLong (pinmodel->numtris) * sizeof (mtriangle_t); pheader = Hunk_AllocName (size, loadname); pmodel = (mdl_t *) ((byte *)&pheader[1] + (LittleLong (pinmodel->numframes) - 1) * sizeof (pheader->frames[0])); // mod->cache.data = pheader; mod->flags = LittleLong (pinmodel->flags); // // endian-adjust and copy the data, starting with the alias model header // pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); pmodel->numskins = LittleLong (pinmodel->numskins); pmodel->skinwidth = LittleLong (pinmodel->skinwidth); pmodel->skinheight = LittleLong (pinmodel->skinheight); if (pmodel->skinheight > MAX_LBM_HEIGHT) Sys_Error ("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); pmodel->numverts = LittleLong (pinmodel->numverts); if (pmodel->numverts <= 0) Sys_Error ("model %s has no vertices", mod->name); if (pmodel->numverts > MAXALIASVERTS) Sys_Error ("model %s has too many vertices", mod->name); pmodel->numtris = LittleLong (pinmodel->numtris); if (pmodel->numtris <= 0) Sys_Error ("model %s has no triangles", mod->name); pmodel->numframes = LittleLong (pinmodel->numframes); pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = LittleLong (pinmodel->synctype); mod->numframes = pmodel->numframes; for (i=0 ; i<3 ; i++) { pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); } numskins = pmodel->numskins; numframes = pmodel->numframes; if (pmodel->skinwidth & 0x03) Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4"); pheader->model = (byte *)pmodel - (byte *)pheader; // // load the skins // skinsize = pmodel->skinheight * pmodel->skinwidth; if (numskins < 1) Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); pskintype = (daliasskintype_t *)&pinmodel[1]; pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), loadname); pheader->skindesc = (byte *)pskindesc - (byte *)pheader; for (i=0 ; i<numskins ; i++) { aliasskintype_t skintype; skintype = LittleLong (pskintype->type); pskindesc[i].type = skintype; if (skintype == ALIAS_SKIN_SINGLE) { pskintype = (daliasskintype_t *) Mod_LoadAliasSkin (pskintype + 1, &pskindesc[i].skin, skinsize, pheader); } else { pskintype = (daliasskintype_t *) Mod_LoadAliasSkinGroup (pskintype + 1, &pskindesc[i].skin, skinsize, pheader); } } // // set base s and t vertices // pstverts = (stvert_t *)&pmodel[1]; pinstverts = (stvert_t *)pskintype; pheader->stverts = (byte *)pstverts - (byte *)pheader; for (i=0 ; i<pmodel->numverts ; i++) { pstverts[i].onseam = LittleLong (pinstverts[i].onseam); // put s and t in 16.16 format pstverts[i].s = LittleLong (pinstverts[i].s) << 16; pstverts[i].t = LittleLong (pinstverts[i].t) << 16; } // // set up the triangles // ptri = (mtriangle_t *)&pstverts[pmodel->numverts]; pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; pheader->triangles = (byte *)ptri - (byte *)pheader; for (i=0 ; i<pmodel->numtris ; i++) { int j; ptri[i].facesfront = LittleLong (pintriangles[i].facesfront); for (j=0 ; j<3 ; j++) { ptri[i].vertindex[j] = LittleLong (pintriangles[i].vertindex[j]); } } // // load the frames // if (numframes < 1) Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris]; for (i=0 ; i<numframes ; i++) { aliasframetype_t frametype; frametype = LittleLong (pframetype->type); pheader->frames[i].type = frametype; if (frametype == ALIAS_SINGLE) { pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i].frame, pmodel->numverts, &pheader->frames[i].bboxmin, &pheader->frames[i].bboxmax, pheader, pheader->frames[i].name); } else { pframetype = (daliasframetype_t *) Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i].frame, pmodel->numverts, &pheader->frames[i].bboxmin, &pheader->frames[i].bboxmax, pheader, pheader->frames[i].name); } } mod->type = mod_alias; // FIXME: do this right mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; // // move the complete, relocatable alias model to the cache // end = Hunk_LowMark (); total = end - start; Cache_Alloc (&mod->cache, total, loadname); if (!mod->cache.data) return; memcpy (mod->cache.data, pheader, total); Hunk_FreeToLowMark (start); }
/* ================= Mod_LoadAliasModel ================= */ void Mod_LoadAliasModel (model_t *mod, void *buffer) { int i, j; mdl_t *pinmodel; stvert_t *pinstverts; dtriangle_t *pintriangles; int version, numframes, numskins; int size; daliasframetype_t *pframetype; daliasskintype_t *pskintype; int start, end, total; start = Hunk_LowMark (); pinmodel = (mdl_t *)buffer; version = LittleLong (pinmodel->version); if (version != ALIAS_VERSION) Sys_Error ("%s has wrong version number (%i should be %i)", mod->name, version, ALIAS_VERSION); // // allocate space for a working header, plus all the data except the frames, // skin and group info // size = sizeof (aliashdr_t) + (LittleLong (pinmodel->numframes) - 1) * sizeof (pheader->frames[0]); pheader = Hunk_AllocName (size, loadname); mod->flags = LittleLong (pinmodel->flags); // // endian-adjust and copy the data, starting with the alias model header // pheader->boundingradius = LittleFloat (pinmodel->boundingradius); pheader->numskins = LittleLong (pinmodel->numskins); pheader->skinwidth = LittleLong (pinmodel->skinwidth); pheader->skinheight = LittleLong (pinmodel->skinheight); if (pheader->skinheight > MAX_LBM_HEIGHT) Sys_Error ("model %s has a skin taller than %d", mod->name, MAX_LBM_HEIGHT); pheader->numverts = LittleLong (pinmodel->numverts); if (pheader->numverts <= 0) Sys_Error ("model %s has no vertices", mod->name); if (pheader->numverts > MAXALIASVERTS) Sys_Error ("model %s has too many vertices", mod->name); pheader->numtris = LittleLong (pinmodel->numtris); if (pheader->numtris <= 0) Sys_Error ("model %s has no triangles", mod->name); pheader->numframes = LittleLong (pinmodel->numframes); numframes = pheader->numframes; if (numframes < 1) Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; mod->synctype = LittleLong (pinmodel->synctype); mod->numframes = pheader->numframes; for (i=0 ; i<3 ; i++) { pheader->scale[i] = LittleFloat (pinmodel->scale[i]); pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); } // // load the skins // pskintype = (daliasskintype_t *)&pinmodel[1]; pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); // // load base s and t vertices // pinstverts = (stvert_t *)pskintype; for (i=0 ; i<pheader->numverts ; i++) { stverts[i].onseam = LittleLong (pinstverts[i].onseam); stverts[i].s = LittleLong (pinstverts[i].s); stverts[i].t = LittleLong (pinstverts[i].t); } // // load triangle lists // pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; for (i=0 ; i<pheader->numtris ; i++) { triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); for (j=0 ; j<3 ; j++) { triangles[i].vertindex[j] = LittleLong (pintriangles[i].vertindex[j]); } } // // load the frames // posenum = 0; pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; for (i=0 ; i<numframes ; i++) { aliasframetype_t frametype; frametype = LittleLong (pframetype->type); if (frametype == ALIAS_SINGLE) { pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); } else { pframetype = (daliasframetype_t *) Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); } } pheader->numposes = posenum; mod->type = mod_alias; // FIXME: do this right mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; // // build the draw lists // GL_MakeAliasModelDisplayLists (mod, pheader); // // move the complete, relocatable alias model to the cache // end = Hunk_LowMark (); total = end - start; Cache_Alloc (&mod->cache, total, loadname); if (!mod->cache.data) return; memcpy (mod->cache.data, pheader, total); Hunk_FreeToLowMark (start); }
void R_DrawParticles (void) { particle_t *p, *kill; float grav; int i; float time2, time3; float time1; float dvel; float frametime; #ifdef GLQUAKE vec3_t up, right; float scale; GL_Use (gl_coloredpolygon1textureprogram); glUniformMatrix4fv(gl_coloredpolygon1textureprogram_transform, 1, 0, gl_polygon_matrix); GL_Bind(particletexture); glEnable (GL_BLEND); VectorScale (vup, 1.5, up); VectorScale (vright, 1.5, right); #else D_StartParticles (); VectorScale (vright, xscaleshrink, r_pright); VectorScale (vup, yscaleshrink, r_pup); VectorCopy (vpn, r_ppn); #endif frametime = cl.time - cl.oldtime; time3 = frametime * 15; time2 = frametime * 10; // 15; time1 = frametime * 5; grav = frametime * sv_gravity.value * 0.05; dvel = 4*frametime; for ( ;; ) { kill = active_particles; if (kill && kill->die < cl.time) { active_particles = kill->next; kill->next = free_particles; free_particles = kill; continue; } break; } #ifdef GLQUAKE int mark = Hunk_LowMark(); int vertexcount = 0; for (p=active_particles ; p ; p=p->next) { vertexcount += 3; } if (vertexcount == 0) return; GLfloat* vertices = Hunk_AllocName (vertexcount * 9 * sizeof(GLfloat), "vertex_buffer"); int vertexpos = 0; #endif for (p=active_particles ; p ; p=p->next) { for ( ;; ) { kill = p->next; if (kill && kill->die < cl.time) { p->next = kill->next; kill->next = free_particles; free_particles = kill; continue; } break; } #ifdef GLQUAKE // hack a scale up to keep particles from disapearing scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + (p->org[2] - r_origin[2])*vpn[2]; if (scale < 20) scale = 1; else scale = 1 + scale * 0.004; unsigned c = d_8to24table[(int)p->color]; GLfloat r = (GLfloat)(c & 0xFF) / 255.0; GLfloat g = (GLfloat)((c >> 8) & 0xFF) / 255.0; GLfloat b = (GLfloat)((c >> 16) & 0xFF) / 255.0; GLfloat a = (GLfloat)((c >> 24) & 0xFF) / 255.0; vertices[vertexpos++] = p->org[0]; vertices[vertexpos++] = p->org[1]; vertices[vertexpos++] = p->org[2]; vertices[vertexpos++] = r; vertices[vertexpos++] = g; vertices[vertexpos++] = b; vertices[vertexpos++] = a; vertices[vertexpos++] = 0.0; vertices[vertexpos++] = 0.0; vertices[vertexpos++] = p->org[0] + up[0] * scale; vertices[vertexpos++] = p->org[1] + up[1] * scale; vertices[vertexpos++] = p->org[2] + up[2] * scale; vertices[vertexpos++] = r; vertices[vertexpos++] = g; vertices[vertexpos++] = b; vertices[vertexpos++] = a; vertices[vertexpos++] = 1.0; vertices[vertexpos++] = 0.0; vertices[vertexpos++] = p->org[0] + right[0] * scale; vertices[vertexpos++] = p->org[1] + right[1] * scale; vertices[vertexpos++] = p->org[2] + right[2] * scale; vertices[vertexpos++] = r; vertices[vertexpos++] = g; vertices[vertexpos++] = b; vertices[vertexpos++] = a; vertices[vertexpos++] = 0.0; vertices[vertexpos++] = 1.0; #else D_DrawParticle (p); #endif p->org[0] += p->vel[0]*frametime; p->org[1] += p->vel[1]*frametime; p->org[2] += p->vel[2]*frametime; switch (p->type) { case pt_static: break; case pt_fire: p->ramp += time1; if (p->ramp >= 6) p->die = -1; else p->color = ramp3[(int)p->ramp]; p->vel[2] += grav; break; case pt_explode: p->ramp += time2; if (p->ramp >=8) p->die = -1; else p->color = ramp1[(int)p->ramp]; for (i=0 ; i<3 ; i++) p->vel[i] += p->vel[i]*dvel; p->vel[2] -= grav; break; case pt_explode2: p->ramp += time3; if (p->ramp >=8) p->die = -1; else p->color = ramp2[(int)p->ramp]; for (i=0 ; i<3 ; i++) p->vel[i] -= p->vel[i]*frametime; p->vel[2] -= grav; break; case pt_blob: for (i=0 ; i<3 ; i++) p->vel[i] += p->vel[i]*dvel; p->vel[2] -= grav; break; case pt_blob2: for (i=0 ; i<2 ; i++) p->vel[i] -= p->vel[i]*dvel; p->vel[2] -= grav; break; case pt_grav: #ifdef QUAKE2 p->vel[2] -= grav * 20; break; #endif case pt_slowgrav: p->vel[2] -= grav; break; } } #ifdef GLQUAKE GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, vertexcount * 9 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(gl_coloredpolygon1textureprogram_position); glVertexAttribPointer(gl_coloredpolygon1textureprogram_position, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), (const GLvoid *)0); glEnableVertexAttribArray(gl_coloredpolygon1textureprogram_color); glVertexAttribPointer(gl_coloredpolygon1textureprogram_color, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), (const GLvoid *)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(gl_coloredpolygon1textureprogram_texcoords); glVertexAttribPointer(gl_coloredpolygon1textureprogram_texcoords, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), (const GLvoid *)(7 * sizeof(GLfloat))); glDrawArrays(GL_TRIANGLES, 0, vertexcount); glDisableVertexAttribArray(gl_coloredpolygon1textureprogram_texcoords); glDisableVertexAttribArray(gl_coloredpolygon1textureprogram_color); glDisableVertexAttribArray(gl_coloredpolygon1textureprogram_position); glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &vertexbuffer); Hunk_FreeToLowMark (mark); glDisable (GL_BLEND); #else D_EndParticles (); #endif }