/* ===================== CL_NewTranslation ===================== */ void CL_NewTranslation(int slot) { int i, j; int top, bottom; byte *dest, *source; if (slot > cl.maxclients) Sys_Error("%s: slot > cl.maxclients", __func__); dest = cl.players[slot].translations; source = vid.colormap; memcpy(dest, vid.colormap, sizeof(cl.players[slot].translations)); top = cl.players[slot].topcolor; bottom = cl.players[slot].bottomcolor; #ifdef GLQUAKE R_TranslatePlayerSkin(slot); #endif for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256) { if (top < 128) // the artists made some backwards ranges. sigh. memcpy(dest + TOP_RANGE, source + top, 16); else for (j = 0; j < 16; j++) dest[TOP_RANGE + j] = source[top + 15 - j]; if (bottom < 128) memcpy(dest + BOTTOM_RANGE, source + bottom, 16); else for (j = 0; j < 16; j++) dest[BOTTOM_RANGE + j] = source[bottom + 15 - j]; } }
/* ===================== CL_NewTranslation ===================== */ void CL_NewTranslation (int slot) { int i, j; int top, bottom; byte *dest, *source; if (slot > cl.maxclients) Sys_Error ("CL_NewTranslation: slot > cl.maxclients"); dest = cl.scores[slot].translations; source = vid.colormap; memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations)); top = cl.scores[slot].colors & 0xf0; bottom = (cl.scores[slot].colors &15)<<4; R_TranslatePlayerSkin (slot); for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256) { if (top < 128) // the artists made some backwards ranges. sigh. memcpy (dest + TOP_RANGE, source + top, 16); else for (j=0 ; j<16 ; j++) dest[TOP_RANGE+j] = source[top+15-j]; if (bottom < 128) memcpy (dest + BOTTOM_RANGE, source + bottom, 16); else for (j=0 ; j<16 ; j++) dest[BOTTOM_RANGE+j] = source[bottom+15-j]; } }
/* ===================== CL_NewTranslation ===================== */ static void CL_NewTranslation (int slot) { #ifndef GLQUAKE int i, j; int top, bottom; byte *dest, *source, *sourceA, *sourceB, *colorA, *colorB; #endif if (slot >= cl.maxclients) Sys_Error ("%s: slot > cl.maxclients", __thisfunc__); if (!cl.scores[slot].playerclass) return; #ifdef GLQUAKE R_TranslatePlayerSkin (slot); return; #else dest = cl.scores[slot].translations; source = vid.colormap; memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations)); top = (cl.scores[slot].colors & 0xf0) >> 4; bottom = (cl.scores[slot].colors & 15); if (top > 11 || bottom > 11) { Con_Printf("Invalid Player Color: %d,%d\n",top,bottom); } if (top > 10) top = 0; if (bottom > 10) bottom = 0; top -= 1; bottom -= 1; // Con_Printf("Class is %d for slot %d\n",(int)cl.scores[slot].playerclass,slot); for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256) { colorA = playerTranslation + 256 + color_offsets[(int)cl.scores[slot].playerclass-1]; colorB = colorA + 256; sourceA = colorB + 256 + (top * 256); sourceB = colorB + 256 + (bottom * 256); for (j = 0; j < 256; j++, colorA++, colorB++, sourceA++, sourceB++) { if (top >= 0 && (*colorA != 255)) dest[j] = source[*sourceA]; if (bottom >= 0 && (*colorB != 255)) dest[j] = source[*sourceB]; } } #endif }
void CL_ParseUpdate(unsigned int bits) { int i; model_t *model; int modnum; qboolean forcelink; entity_t *ent; int num; // FIXME - do this cleanly... #ifdef GLQUAKE int skin; #endif if (cls.state == ca_firstupdate) { // first update is the final signon stage cls.signon = SIGNONS; CL_SignonReply(); } if (bits & U_MOREBITS) { i = MSG_ReadByte(); bits |= (i << 8); } if (cl.protocol == PROTOCOL_VERSION_FITZ) { if (bits & U_FITZ_EXTEND1) bits |= MSG_ReadByte() << 16; if (bits & U_FITZ_EXTEND2) bits |= MSG_ReadByte() << 24; } if (bits & U_LONGENTITY) num = MSG_ReadShort(); else num = MSG_ReadByte(); ent = CL_EntityNum(num); if (ent->msgtime != cl.mtime[1]) forcelink = true; // no previous frame to lerp from else forcelink = false; ent->msgtime = cl.mtime[0]; if (bits & U_MODEL) { modnum = CL_ReadModelIndex(0); if (modnum >= max_models(cl.protocol)) Host_Error("CL_ParseModel: bad modnum"); } else modnum = ent->baseline.modelindex; if (bits & U_FRAME) ent->frame = MSG_ReadByte(); else ent->frame = ent->baseline.frame; /* ANIMATION LERPING INFO */ if (ent->currentframe != ent->frame) { /* TODO: invalidate things when they fall off the currententities list or haven't been updated for a while */ ent->previousframe = ent->currentframe; ent->previousframetime = ent->currentframetime; ent->currentframe = ent->frame; ent->currentframetime = cl.time; } if (bits & U_COLORMAP) i = MSG_ReadByte(); else i = ent->baseline.colormap; if (!i) ent->colormap = vid.colormap; else { if (i > cl.maxclients) Sys_Error("i >= cl.maxclients"); ent->colormap = cl.players[i - 1].translations; } #ifdef GLQUAKE if (bits & U_SKIN) skin = MSG_ReadByte(); else skin = ent->baseline.skinnum; if (skin != ent->skinnum) { ent->skinnum = skin; if (num > 0 && num <= cl.maxclients) R_TranslatePlayerSkin(num - 1); } #else if (bits & U_SKIN) ent->skinnum = MSG_ReadByte(); else ent->skinnum = ent->baseline.skinnum; #endif if (bits & U_EFFECTS) ent->effects = MSG_ReadByte(); else ent->effects = ent->baseline.effects; // shift the known values for interpolation VectorCopy(ent->msg_origins[0], ent->msg_origins[1]); VectorCopy(ent->msg_angles[0], ent->msg_angles[1]); if (bits & U_ORIGIN1) ent->msg_origins[0][0] = MSG_ReadCoord(); else ent->msg_origins[0][0] = ent->baseline.origin[0]; if (bits & U_ANGLE1) ent->msg_angles[0][0] = MSG_ReadAngle(); else ent->msg_angles[0][0] = ent->baseline.angles[0]; if (bits & U_ORIGIN2) ent->msg_origins[0][1] = MSG_ReadCoord(); else ent->msg_origins[0][1] = ent->baseline.origin[1]; if (bits & U_ANGLE2) ent->msg_angles[0][1] = MSG_ReadAngle(); else ent->msg_angles[0][1] = ent->baseline.angles[1]; if (bits & U_ORIGIN3) ent->msg_origins[0][2] = MSG_ReadCoord(); else ent->msg_origins[0][2] = ent->baseline.origin[2]; if (bits & U_ANGLE3) ent->msg_angles[0][2] = MSG_ReadAngle(); else ent->msg_angles[0][2] = ent->baseline.angles[2]; if (cl.protocol == PROTOCOL_VERSION_FITZ) { if (bits & U_NOLERP) { // FIXME - TODO (called U_STEP in FQ) } if (bits & U_FITZ_ALPHA) { MSG_ReadByte(); // FIXME - TODO } if (bits & U_FITZ_FRAME2) ent->frame = (ent->frame & 0xFF) | (MSG_ReadByte() << 8); if (bits & U_FITZ_MODEL2) modnum = (modnum & 0xFF)| (MSG_ReadByte() << 8); if (bits & U_FITZ_LERPFINISH) { MSG_ReadByte(); // FIXME - TODO } } model = cl.model_precache[modnum]; if (model != ent->model) { ent->model = model; // automatic animation (torches, etc) can be either all together // or randomized if (model) { if (model->synctype == ST_RAND) ent->syncbase = (float)(rand() & 0x7fff) / 0x7fff; else ent->syncbase = 0.0; } else forcelink = true; // hack to make null model players work #ifdef GLQUAKE if (num > 0 && num <= cl.maxclients) R_TranslatePlayerSkin(num - 1); #endif } /* MOVEMENT LERP INFO - could I just extend baseline instead? */ if (!VectorCompare(ent->msg_origins[0], ent->currentorigin)) { if (ent->currentorigintime) { VectorCopy(ent->currentorigin, ent->previousorigin); ent->previousorigintime = ent->currentorigintime; } else { VectorCopy(ent->msg_origins[0], ent->previousorigin); ent->previousorigintime = cl.mtime[0]; } VectorCopy(ent->msg_origins[0], ent->currentorigin); ent->currentorigintime = cl.mtime[0]; } if (!VectorCompare(ent->msg_angles[0], ent->currentangles)) { if (ent->currentanglestime) { VectorCopy(ent->currentangles, ent->previousangles); ent->previousanglestime = ent->currentanglestime; } else { VectorCopy(ent->msg_angles[0], ent->previousangles); ent->previousanglestime = cl.mtime[0]; } VectorCopy(ent->msg_angles[0], ent->currentangles); ent->currentanglestime = cl.mtime[0]; } if (bits & U_NOLERP) ent->forcelink = true; if (forcelink) { // didn't have an update last message VectorCopy(ent->msg_origins[0], ent->msg_origins[1]); VectorCopy(ent->msg_origins[0], ent->origin); VectorCopy(ent->msg_angles[0], ent->msg_angles[1]); VectorCopy(ent->msg_angles[0], ent->angles); ent->forcelink = true; } }
void CL_ParseUpdate (int bits) { int i; model_t *model; int modnum; qboolean forcelink; entity_t *ent; int num; int skin; if (cls.signon == SIGNONS - 1) { // first update is the final signon stage cls.signon = SIGNONS; CL_SignonReply (); } if (bits & U_MOREBITS) { i = MSG_ReadByte (); bits |= (i<<8); } if (bits & U_LONGENTITY) num = MSG_ReadShort (); else num = MSG_ReadByte (); ent = CL_EntityNum (num); for (i=0 ; i<16 ; i++) if (bits&(1<<i)) bitcounts[i]++; if (ent->msgtime != cl.mtime[1]) forcelink = true; // no previous frame to lerp from else forcelink = false; ent->msgtime = cl.mtime[0]; if (bits & U_MODEL) { modnum = MSG_ReadByte (); if (modnum >= MAX_MODELS) Host_Error ("CL_ParseModel: bad modnum"); } else modnum = ent->baseline.modelindex; model = cl.model_precache[modnum]; if (model != ent->model) { ent->model = model; // automatic animation (torches, etc) can be either all together // or randomized if (model) { if (model->synctype == ST_RAND) ent->syncbase = (float)(rand()&0x7fff) / 0x7fff; else ent->syncbase = 0.0; } else forcelink = true; // hack to make null model players work #ifdef GLQUAKE if (num > 0 && num <= cl.maxclients) R_TranslatePlayerSkin (num - 1); #endif } if (bits & U_FRAME) ent->frame = MSG_ReadByte (); else ent->frame = ent->baseline.frame; if (bits & U_COLORMAP) i = MSG_ReadByte(); else i = ent->baseline.colormap; if (!i) ent->colormap = vid.colormap; else { if (i > cl.maxclients) Sys_Error ("i >= cl.maxclients"); ent->colormap = cl.scores[i-1].translations; } #ifdef GLQUAKE if (bits & U_SKIN) skin = MSG_ReadByte(); else skin = ent->baseline.skin; if (skin != ent->skinnum) { ent->skinnum = skin; if (num > 0 && num <= cl.maxclients) R_TranslatePlayerSkin (num - 1); } #else if (bits & U_SKIN) ent->skinnum = MSG_ReadByte(); else ent->skinnum = ent->baseline.skin; #endif if (bits & U_EFFECTS) ent->effects = MSG_ReadByte(); else ent->effects = ent->baseline.effects; // shift the known values for interpolation VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); if (bits & U_ORIGIN1) ent->msg_origins[0][0] = MSG_ReadCoord (); else ent->msg_origins[0][0] = ent->baseline.origin[0]; if (bits & U_ANGLE1) ent->msg_angles[0][0] = MSG_ReadAngle(); else ent->msg_angles[0][0] = ent->baseline.angles[0]; if (bits & U_ORIGIN2) ent->msg_origins[0][1] = MSG_ReadCoord (); else ent->msg_origins[0][1] = ent->baseline.origin[1]; if (bits & U_ANGLE2) ent->msg_angles[0][1] = MSG_ReadAngle(); else ent->msg_angles[0][1] = ent->baseline.angles[1]; if (bits & U_ORIGIN3) ent->msg_origins[0][2] = MSG_ReadCoord (); else ent->msg_origins[0][2] = ent->baseline.origin[2]; if (bits & U_ANGLE3) ent->msg_angles[0][2] = MSG_ReadAngle(); else ent->msg_angles[0][2] = ent->baseline.angles[2]; if ( bits & U_NOLERP ) ent->forcelink = true; if ( forcelink ) { // didn't have an update last message VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); VectorCopy (ent->msg_origins[0], ent->origin); VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); VectorCopy (ent->msg_angles[0], ent->angles); ent->forcelink = true; } }
/* ================== CL_ParseUpdate_H2 ================== */ qboolean CL_ParseUpdate_H2 (entity_t *ent, int num, int bits) { entity_state_t *ref_ent, *set_ent, dummy; qboolean forcelink; int i, modnum, flag; model_t *model; ent->baseline.flags |= ENT_STATE_ON; ref_ent = NULL; for (i=0; i < cl.frames[0].count; i++) { if (cl.frames[0].states[i].index == num) { ref_ent = &cl.frames[0].states[i]; // if (entnum == 2) fprintf(FH,"Found Reference\n"); break; } } if (!ref_ent) { ref_ent = &ent->baseline; ref_ent->index = num; } if (bits & U_CLEAR_ENT) { memset(ent, 0, sizeof(entity_t)); memset(ref_ent, 0, sizeof(entity_state_t)); ref_ent->index = num; } if (cl.need_build) // new sequence, first valid frame { set_ent = &cl.frames[1].states[cl.frames[1].count]; cl.frames[1].count++; *set_ent = *ref_ent; } else set_ent = &dummy; forcelink = (ent->msgtime != cl.mtime_prev) ? true : false; ent->msgtime = cl.mtime; if (bits & U_MODEL) { modnum = MSG_ReadShort (); if (modnum >= MAX_MODELS) Host_Error ("CL_ParseModel: bad modnum"); } else modnum = ref_ent->modelindex; model = cl.model_precache[modnum]; set_ent->modelindex = modnum; if (model != ent->model) { ent->model = model; // automatic animation (torches, etc) can be either all together // or randomized if (model) { if (model->synctype == ST_RAND) ent->syncbase = rand()*(1.0/RAND_MAX);//(float)(rand()&0x7fff) / 0x7fff; else ent->syncbase = 0.0; } else forcelink = true; // hack to make null model players work if (num > 0 && num <= cl.maxclients) R_TranslatePlayerSkin (num - 1); // **** FIXME: need Hexen II-specific proc **** } if (bits & U_FRAME) set_ent->frame = ent->frame = MSG_ReadByte (); else ent->frame = ref_ent->frame; if (bits & U_COLORMAP_H2) set_ent->colormap = i = MSG_ReadByte(); else i = ref_ent->colormap; if (num && num <= cl.maxclients) ent->colormap = /*ent->sourcecolormap =*/ cl.scores[num-1].translations; /*else ent->sourcecolormap = vid.colormap;*/ ent->colorshade = i; // ent->colormap = i ? globalcolormap : ent->sourcecolormap; if (bits & U_SKIN_H2) { set_ent->skin = ent->skinnum = MSG_ReadByte(); set_ent->drawflags = ent->drawflags = MSG_ReadByte(); } else { ent->skinnum = ref_ent->skin; ent->drawflags = ref_ent->drawflags; } if (bits & U_EFFECTS_H2) { set_ent->effects = ent->effects = MSG_ReadByte(); // if (num == 2) fprintf(FH,"Read effects %d\n",set_ent->effects); } else { ent->effects = ref_ent->effects; //if (num == 2) fprintf(FH,"restored effects %d\n",ref_ent->effects); } // shift the known values for interpolation VectorCopy (ent->msg_origin, ent->msg_origin_prev); VectorCopy (ent->msg_angles, ent->msg_angles_prev); for (i = 0; i < 3; i++) { if (bits & (U_ORIGIN1 << i)) { set_ent->origin[i] = ent->msg_origin[i] = MSG_ReadCoord(); } else ent->msg_origin[i] = ref_ent->origin[i]; flag = (i == 0) ? U_ANGLE1 : (i == 1) ? U_ANGLE2 : U_ANGLE3; if (bits & flag) { set_ent->angles[i] = ent->msg_angles[i] = MSG_ReadAngle(); #ifdef _DEBUG if (ent->model && (ent->model->type == mod_brush)) i *= 1; #endif } else ent->msg_angles[i] = ref_ent->angles[i]; } // JDH: blatant hack to smooth rotating entities if (sv.active && (bits & (U_ANGLE1 | U_ANGLE2 | U_ANGLE3))) { edict_t *ed = EDICT_NUM(num); if (ed) VectorCopy (ed->v.angles, ent->msg_angles); } if (bits & U_SCALE) { set_ent->scale = ent->scale = MSG_ReadByte(); set_ent->abslight = ent->abslight = MSG_ReadByte(); } else { ent->scale = ref_ent->scale; ent->abslight = ref_ent->abslight; } return forcelink; }
/* ================== CL_ParseUpdate Parse an entity update message from the server If an entities model or origin changes from frame to frame, it must be relinked. Other attributes can change without relinking. ================== */ static void CL_ParseUpdate (int bits) { int i; model_t *model; int modnum; qboolean forcelink; entity_t *ent; int num; entity_state2_t *ref_ent,*set_ent,build_ent,dummy; if (cls.signon == SIGNONS - 1) { // first update is the final signon stage cls.signon = SIGNONS; CL_SignonReply (); } if (bits & U_MOREBITS) { i = MSG_ReadByte (); bits |= (i<<8); } if (bits & U_MOREBITS2) { i = MSG_ReadByte (); bits |= (i<<16); } if (bits & U_LONGENTITY) num = MSG_ReadShort (); else num = MSG_ReadByte (); ent = CL_EntityNum (num); ent->baseline.flags |= BE_ON; /* if (num == 2) { FH = fopen("c.txt","r+"); fseek(FH,0,SEEK_END); } */ ref_ent = NULL; for (i = 0; i < cl.frames[0].count; i++) if (cl.frames[0].states[i].index == num) { ref_ent = &cl.frames[0].states[i]; // if (num == 2) fprintf(FH,"Found Reference\n"); break; } if (!ref_ent) { ref_ent = &build_ent; build_ent.index = num; build_ent.origin[0] = ent->baseline.origin[0]; build_ent.origin[1] = ent->baseline.origin[1]; build_ent.origin[2] = ent->baseline.origin[2]; build_ent.angles[0] = ent->baseline.angles[0]; build_ent.angles[1] = ent->baseline.angles[1]; build_ent.angles[2] = ent->baseline.angles[2]; build_ent.modelindex = ent->baseline.modelindex; build_ent.frame = ent->baseline.frame; build_ent.colormap = ent->baseline.colormap; build_ent.skin = ent->baseline.skin; build_ent.effects = ent->baseline.effects; build_ent.scale = ent->baseline.scale; build_ent.drawflags = ent->baseline.drawflags; build_ent.abslight = ent->baseline.abslight; } if (cl.need_build) { // new sequence, first valid frame set_ent = &cl.frames[1].states[cl.frames[1].count]; cl.frames[1].count++; } else set_ent = &dummy; if (bits & U_CLEAR_ENT) { memset(ent, 0, sizeof(entity_t)); memset(ref_ent, 0, sizeof(*ref_ent)); ref_ent->index = num; } *set_ent = *ref_ent; if (ent->msgtime != cl.mtime[1]) forcelink = true; // no previous frame to lerp from else forcelink = false; ent->msgtime = cl.mtime[0]; if (bits & U_MODEL) { modnum = MSG_ReadShort (); if (modnum >= MAX_MODELS) Host_Error ("%s: bad modnum", __thisfunc__); } else modnum = ref_ent->modelindex; model = cl.model_precache[modnum]; set_ent->modelindex = modnum; if (model != ent->model) { ent->model = model; // automatic animation (torches, etc) can be either all together // or randomized if (model) { if (model->synctype == ST_RAND) ent->syncbase = rand() * (1.0 / RAND_MAX);//(float)(rand() & 0x7fff) / 0x7fff; else ent->syncbase = 0.0; } else forcelink = true; // hack to make null model players work #ifdef GLQUAKE if (num > 0 && num <= cl.maxclients) R_TranslatePlayerSkin (num - 1); #endif } if (bits & U_FRAME) set_ent->frame = ent->frame = MSG_ReadByte (); else ent->frame = ref_ent->frame; if (bits & U_COLORMAP) set_ent->colormap = i = MSG_ReadByte(); else i = ref_ent->colormap; if (num && num <= cl.maxclients) ent->colormap = ent->sourcecolormap = cl.scores[num-1].translations; else ent->sourcecolormap = vid.colormap; #ifdef GLQUAKE // ent->colormap = vid.colormap; #endif if (!i) { ent->colorshade = i; ent->colormap = ent->sourcecolormap; } else { ent->colorshade = i; #ifdef GLQUAKE // ent->colormap = vid.colormap; ent->colormap = globalcolormap; #else ent->colormap = globalcolormap; #endif } if (bits & U_SKIN) { set_ent->skin = ent->skinnum = MSG_ReadByte(); set_ent->drawflags = ent->drawflags = MSG_ReadByte(); } else { ent->skinnum = ref_ent->skin; ent->drawflags = ref_ent->drawflags; } if (bits & U_EFFECTS) { set_ent->effects = ent->effects = MSG_ReadByte(); // if (num == 2) // fprintf(FH,"Read effects %d\n",set_ent->effects); } else { ent->effects = ref_ent->effects; //if (num == 2) // fprintf(FH,"restored effects %d\n",ref_ent->effects); } // shift the known values for interpolation VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); if (bits & U_ORIGIN1) { set_ent->origin[0] = ent->msg_origins[0][0] = MSG_ReadCoord (); //if (num == 2) // fprintf(FH,"Read origin[0] %f\n",set_ent->angles[0]); } else { ent->msg_origins[0][0] = ref_ent->origin[0]; //if (num == 2) // fprintf(FH,"Restored origin[0] %f\n",ref_ent->angles[0]); } if (bits & U_ANGLE1) set_ent->angles[0] = ent->msg_angles[0][0] = MSG_ReadAngle(); else ent->msg_angles[0][0] = ref_ent->angles[0]; if (bits & U_ORIGIN2) set_ent->origin[1] = ent->msg_origins[0][1] = MSG_ReadCoord (); else ent->msg_origins[0][1] = ref_ent->origin[1]; if (bits & U_ANGLE2) set_ent->angles[1] = ent->msg_angles[0][1] = MSG_ReadAngle(); else ent->msg_angles[0][1] = ref_ent->angles[1]; if (bits & U_ORIGIN3) set_ent->origin[2] = ent->msg_origins[0][2] = MSG_ReadCoord (); else ent->msg_origins[0][2] = ref_ent->origin[2]; if (bits & U_ANGLE3) set_ent->angles[2] = ent->msg_angles[0][2] = MSG_ReadAngle(); else ent->msg_angles[0][2] = ref_ent->angles[2]; if (bits & U_SCALE) { set_ent->scale = ent->scale = MSG_ReadByte(); set_ent->abslight = ent->abslight = MSG_ReadByte(); } else { ent->scale = ref_ent->scale; ent->abslight = ref_ent->abslight; } if (bits & U_NOLERP) ent->forcelink = true; if ( forcelink ) { // didn't have an update last message VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); VectorCopy (ent->msg_origins[0], ent->origin); VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); VectorCopy (ent->msg_angles[0], ent->angles); ent->forcelink = true; } // if (sv.active || num != 2) // return; }
/* ================= R_DrawAliasModel ================= */ void R_DrawAliasModel (entity_t *e) { int i; int lnum; vec3_t dist; float add; model_t *clmodel; vec3_t mins, maxs; aliashdr_t *paliashdr; float an; int anim; clmodel = currententity->model; VectorAdd (currententity->origin, clmodel->mins, mins); VectorAdd (currententity->origin, clmodel->maxs, maxs); if (R_CullBox (mins, maxs)) return; VectorCopy (currententity->origin, r_entorigin); VectorSubtract (r_origin, r_entorigin, modelorg); // // get lighting information // ambientlight = shadelight = R_LightPoint (currententity->origin); // allways give the gun some light if (e == &cl.viewent && ambientlight < 24) ambientlight = shadelight = 24; for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++) { if (cl_dlights[lnum].die >= cl.time) { VectorSubtract (currententity->origin, cl_dlights[lnum].origin, dist); add = cl_dlights[lnum].radius - Length(dist); if (add > 0) { ambientlight += add; //ZOID models should be affected by dlights as well shadelight += add; } } } // clamp lighting so it doesn't overbright as much if (ambientlight > 128) ambientlight = 128; if (ambientlight + shadelight > 192) shadelight = 192 - ambientlight; // ZOID: never allow players to go totally black if (!strcmp(clmodel->name, "progs/player.mdl")) { if (ambientlight < 8) ambientlight = shadelight = 8; } else if (!strcmp (clmodel->name, "progs/flame2.mdl") || !strcmp (clmodel->name, "progs/flame.mdl") ) // HACK HACK HACK -- no fullbright colors, so make torches full light ambientlight = shadelight = 256; shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; shadelight = shadelight / 200.0; an = e->angles[1]/180*M_PI; shadevector[0] = cos(-an); shadevector[1] = sin(-an); shadevector[2] = 1; VectorNormalize (shadevector); // // locate the proper data // paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); c_alias_polys += paliashdr->numtris; // // draw all the triangles // GL_DisableMultitexture(); glPushMatrix (); R_RotateForEntity (e); if (!strcmp (clmodel->name, "progs/eyes.mdl") ) { glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8)); // double size of eyes, since they are really hard to see in gl glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2); } else { glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); } anim = (int)(cl.time*10) & 3; GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]); // we can't dynamically colormap textures, so they are cached // seperately for the players. Heads are just uncolored. if (currententity->scoreboard && !gl_nocolors.value) { i = currententity->scoreboard - cl.players; if (!currententity->scoreboard->skin) { Skin_Find(currententity->scoreboard); R_TranslatePlayerSkin(i); } if (i >= 0 && i<MAX_CLIENTS) GL_Bind(playertextures + i); } if (gl_smoothmodels.value) glShadeModel (GL_SMOOTH); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (gl_affinemodels.value) glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); R_SetupAliasFrame (currententity->frame, paliashdr); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glShadeModel (GL_FLAT); if (gl_affinemodels.value) glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glPopMatrix (); if (r_shadows.value) { glPushMatrix (); R_RotateForEntity (e); glDisable (GL_TEXTURE_2D); glEnable (GL_BLEND); glColor4f (0,0,0,0.5); GL_DrawAliasShadow (paliashdr, lastposenum); glEnable (GL_TEXTURE_2D); glDisable (GL_BLEND); glColor4f (1,1,1,1); glPopMatrix (); } }