Annotation of quakeworld/client/view.c, revision 1.1

1.1     ! root        1: /*
        !             2: Copyright (C) 1996-1997 Id Software, Inc.
        !             3: 
        !             4: This program is free software; you can redistribute it and/or
        !             5: modify it under the terms of the GNU General Public License
        !             6: as published by the Free Software Foundation; either version 2
        !             7: of the License, or (at your option) any later version.
        !             8: 
        !             9: This program is distributed in the hope that it will be useful,
        !            10: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
        !            12: 
        !            13: See the GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with this program; if not, write to the Free Software
        !            17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            18: 
        !            19: */
        !            20: // view.c -- player eye positioning
        !            21: 
        !            22: #include "quakedef.h"
        !            23: #include "r_local.h"
        !            24: 
        !            25: /*
        !            26: 
        !            27: The view is allowed to move slightly from it's true position for bobbing,
        !            28: but if it exceeds 8 pixels linear distance (spherical, not box), the list of
        !            29: entities sent from the server may not include everything in the pvs, especially
        !            30: when crossing a water boudnary.
        !            31: 
        !            32: */
        !            33: 
        !            34: cvar_t lcd_x = {"lcd_x", "0"}; // FIXME: make this work sometime...
        !            35: 
        !            36: cvar_t cl_rollspeed = {"cl_rollspeed", "200"};
        !            37: cvar_t cl_rollangle = {"cl_rollangle", "2.0"};
        !            38: 
        !            39: cvar_t cl_bob = {"cl_bob","0.02", false};
        !            40: cvar_t cl_bobcycle = {"cl_bobcycle","0.6", false};
        !            41: cvar_t cl_bobup = {"cl_bobup","0.5", false};
        !            42: 
        !            43: cvar_t v_kicktime = {"v_kicktime", "0.5", false};
        !            44: cvar_t v_kickroll = {"v_kickroll", "0.6", false};
        !            45: cvar_t v_kickpitch = {"v_kickpitch", "0.6", false};
        !            46: 
        !            47: cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "2", false};
        !            48: cvar_t v_iroll_cycle = {"v_iroll_cycle", "0.5", false};
        !            49: cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "1", false};
        !            50: cvar_t v_iyaw_level = {"v_iyaw_level", "0.3", false};
        !            51: cvar_t v_iroll_level = {"v_iroll_level", "0.1", false};
        !            52: cvar_t v_ipitch_level = {"v_ipitch_level", "0.3", false};
        !            53: 
        !            54: cvar_t v_idlescale = {"v_idlescale", "0", false};
        !            55: 
        !            56: cvar_t crosshair = {"crosshair", "0", true};
        !            57: cvar_t crosshaircolor = {"crosshaircolor", "79", true};
        !            58: 
        !            59: cvar_t  cl_crossx = {"cl_crossx", "0", true};
        !            60: cvar_t  cl_crossy = {"cl_crossy", "0", true};
        !            61: 
        !            62: #ifdef GLQUAKE
        !            63: cvar_t gl_cshiftpercent = {"gl_cshiftpercent", "100", false};
        !            64: #endif
        !            65: 
        !            66: cvar_t  v_contentblend = {"v_contentblend", "1", false};
        !            67: 
        !            68: float  v_dmg_time, v_dmg_roll, v_dmg_pitch;
        !            69: 
        !            70: extern int                     in_forward, in_forward2, in_back;
        !            71: 
        !            72: frame_t                *view_frame;
        !            73: player_state_t         *view_message;
        !            74: 
        !            75: /*
        !            76: ===============
        !            77: V_CalcRoll
        !            78: 
        !            79: ===============
        !            80: */
        !            81: float V_CalcRoll (vec3_t angles, vec3_t velocity)
        !            82: {
        !            83:        vec3_t  forward, right, up;
        !            84:        float   sign;
        !            85:        float   side;
        !            86:        float   value;
        !            87:        
        !            88:        AngleVectors (angles, forward, right, up);
        !            89:        side = DotProduct (velocity, right);
        !            90:        sign = side < 0 ? -1 : 1;
        !            91:        side = fabs(side);
        !            92:        
        !            93:        value = cl_rollangle.value;
        !            94: 
        !            95:        if (side < cl_rollspeed.value)
        !            96:                side = side * value / cl_rollspeed.value;
        !            97:        else
        !            98:                side = value;
        !            99:        
        !           100:        return side*sign;
        !           101:        
        !           102: }
        !           103: 
        !           104: 
        !           105: /*
        !           106: ===============
        !           107: V_CalcBob
        !           108: 
        !           109: ===============
        !           110: */
        !           111: float V_CalcBob (void)
        !           112: {
        !           113:        static  double  bobtime;
        !           114:        static float    bob;
        !           115:        float   cycle;
        !           116:        
        !           117:        if (cl.spectator)
        !           118:                return 0;
        !           119: 
        !           120:        if (onground == -1)
        !           121:                return bob;             // just use old value
        !           122: 
        !           123:        bobtime += host_frametime;
        !           124:        cycle = bobtime - (int)(bobtime/cl_bobcycle.value)*cl_bobcycle.value;
        !           125:        cycle /= cl_bobcycle.value;
        !           126:        if (cycle < cl_bobup.value)
        !           127:                cycle = M_PI * cycle / cl_bobup.value;
        !           128:        else
        !           129:                cycle = M_PI + M_PI*(cycle-cl_bobup.value)/(1.0 - cl_bobup.value);
        !           130: 
        !           131: // bob is proportional to simulated velocity in the xy plane
        !           132: // (don't count Z, or jumping messes it up)
        !           133: 
        !           134:        bob = sqrt(cl.simvel[0]*cl.simvel[0] + cl.simvel[1]*cl.simvel[1]) * cl_bob.value;
        !           135:        bob = bob*0.3 + bob*0.7*sin(cycle);
        !           136:        if (bob > 4)
        !           137:                bob = 4;
        !           138:        else if (bob < -7)
        !           139:                bob = -7;
        !           140:        return bob;
        !           141:        
        !           142: }
        !           143: 
        !           144: 
        !           145: //=============================================================================
        !           146: 
        !           147: 
        !           148: cvar_t v_centermove = {"v_centermove", "0.15", false};
        !           149: cvar_t v_centerspeed = {"v_centerspeed","500"};
        !           150: 
        !           151: 
        !           152: void V_StartPitchDrift (void)
        !           153: {
        !           154: #if 1
        !           155:        if (cl.laststop == cl.time)
        !           156:        {
        !           157:                return;         // something else is keeping it from drifting
        !           158:        }
        !           159: #endif
        !           160:        if (cl.nodrift || !cl.pitchvel)
        !           161:        {
        !           162:                cl.pitchvel = v_centerspeed.value;
        !           163:                cl.nodrift = false;
        !           164:                cl.driftmove = 0;
        !           165:        }
        !           166: }
        !           167: 
        !           168: void V_StopPitchDrift (void)
        !           169: {
        !           170:        cl.laststop = cl.time;
        !           171:        cl.nodrift = true;
        !           172:        cl.pitchvel = 0;
        !           173: }
        !           174: 
        !           175: /*
        !           176: ===============
        !           177: V_DriftPitch
        !           178: 
        !           179: Moves the client pitch angle towards cl.idealpitch sent by the server.
        !           180: 
        !           181: If the user is adjusting pitch manually, either with lookup/lookdown,
        !           182: mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped.
        !           183: 
        !           184: Drifting is enabled when the center view key is hit, mlook is released and
        !           185: lookspring is non 0, or when 
        !           186: ===============
        !           187: */
        !           188: void V_DriftPitch (void)
        !           189: {
        !           190:        float           delta, move;
        !           191: 
        !           192:        if (view_message->onground == -1 || cls.demoplayback )
        !           193:        {
        !           194:                cl.driftmove = 0;
        !           195:                cl.pitchvel = 0;
        !           196:                return;
        !           197:        }
        !           198: 
        !           199: // don't count small mouse motion
        !           200:        if (cl.nodrift)
        !           201:        {
        !           202:                if ( fabs(cl.frames[(cls.netchan.outgoing_sequence-1)&UPDATE_MASK].cmd.forwardmove) < 200)
        !           203:                        cl.driftmove = 0;
        !           204:                else
        !           205:                        cl.driftmove += host_frametime;
        !           206:        
        !           207:                if ( cl.driftmove > v_centermove.value)
        !           208:                {
        !           209:                        V_StartPitchDrift ();
        !           210:                }
        !           211:                return;
        !           212:        }
        !           213:        
        !           214:        delta = 0 - cl.viewangles[PITCH];
        !           215: 
        !           216:        if (!delta)
        !           217:        {
        !           218:                cl.pitchvel = 0;
        !           219:                return;
        !           220:        }
        !           221: 
        !           222:        move = host_frametime * cl.pitchvel;
        !           223:        cl.pitchvel += host_frametime * v_centerspeed.value;
        !           224:        
        !           225: //Con_Printf ("move: %f (%f)\n", move, host_frametime);
        !           226: 
        !           227:        if (delta > 0)
        !           228:        {
        !           229:                if (move > delta)
        !           230:                {
        !           231:                        cl.pitchvel = 0;
        !           232:                        move = delta;
        !           233:                }
        !           234:                cl.viewangles[PITCH] += move;
        !           235:        }
        !           236:        else if (delta < 0)
        !           237:        {
        !           238:                if (move > -delta)
        !           239:                {
        !           240:                        cl.pitchvel = 0;
        !           241:                        move = -delta;
        !           242:                }
        !           243:                cl.viewangles[PITCH] -= move;
        !           244:        }
        !           245: }
        !           246: 
        !           247: 
        !           248: 
        !           249: 
        !           250: 
        !           251: /*
        !           252: ============================================================================== 
        !           253:  
        !           254:                                                PALETTE FLASHES 
        !           255:  
        !           256: ============================================================================== 
        !           257: */ 
        !           258:  
        !           259:  
        !           260: cshift_t       cshift_empty = { {130,80,50}, 0 };
        !           261: cshift_t       cshift_water = { {130,80,50}, 128 };
        !           262: cshift_t       cshift_slime = { {0,25,5}, 150 };
        !           263: cshift_t       cshift_lava = { {255,80,0}, 150 };
        !           264: 
        !           265: cvar_t         v_gamma = {"gamma", "1", true};
        !           266: 
        !           267: byte           gammatable[256];        // palette is sent through this
        !           268: 
        !           269: 
        !           270: #ifdef GLQUAKE
        !           271: byte           ramps[3][256];
        !           272: float          v_blend[4];             // rgba 0.0 - 1.0
        !           273: #endif // GLQUAKE
        !           274: 
        !           275: void BuildGammaTable (float g)
        !           276: {
        !           277:        int             i, inf;
        !           278:        
        !           279:        if (g == 1.0)
        !           280:        {
        !           281:                for (i=0 ; i<256 ; i++)
        !           282:                        gammatable[i] = i;
        !           283:                return;
        !           284:        }
        !           285:        
        !           286:        for (i=0 ; i<256 ; i++)
        !           287:        {
        !           288:                inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
        !           289:                if (inf < 0)
        !           290:                        inf = 0;
        !           291:                if (inf > 255)
        !           292:                        inf = 255;
        !           293:                gammatable[i] = inf;
        !           294:        }
        !           295: }
        !           296: 
        !           297: /*
        !           298: =================
        !           299: V_CheckGamma
        !           300: =================
        !           301: */
        !           302: qboolean V_CheckGamma (void)
        !           303: {
        !           304:        static float oldgammavalue;
        !           305:        
        !           306:        if (v_gamma.value == oldgammavalue)
        !           307:                return false;
        !           308:        oldgammavalue = v_gamma.value;
        !           309:        
        !           310:        BuildGammaTable (v_gamma.value);
        !           311:        vid.recalc_refdef = 1;                          // force a surface cache flush
        !           312:        
        !           313:        return true;
        !           314: }
        !           315: 
        !           316: 
        !           317: 
        !           318: /*
        !           319: ===============
        !           320: V_ParseDamage
        !           321: ===============
        !           322: */
        !           323: void V_ParseDamage (void)
        !           324: {
        !           325:        int             armor, blood;
        !           326:        vec3_t  from;
        !           327:        int             i;
        !           328:        vec3_t  forward, right, up;
        !           329:        float   side;
        !           330:        float   count;
        !           331:        
        !           332:        armor = MSG_ReadByte ();
        !           333:        blood = MSG_ReadByte ();
        !           334:        for (i=0 ; i<3 ; i++)
        !           335:                from[i] = MSG_ReadCoord ();
        !           336: 
        !           337:        count = blood*0.5 + armor*0.5;
        !           338:        if (count < 10)
        !           339:                count = 10;
        !           340: 
        !           341:        cl.faceanimtime = cl.time + 0.2;                // but sbar face into pain frame
        !           342: 
        !           343:        cl.cshifts[CSHIFT_DAMAGE].percent += 3*count;
        !           344:        if (cl.cshifts[CSHIFT_DAMAGE].percent < 0)
        !           345:                cl.cshifts[CSHIFT_DAMAGE].percent = 0;
        !           346:        if (cl.cshifts[CSHIFT_DAMAGE].percent > 150)
        !           347:                cl.cshifts[CSHIFT_DAMAGE].percent = 150;
        !           348: 
        !           349:        if (armor > blood)              
        !           350:        {
        !           351:                cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200;
        !           352:                cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100;
        !           353:                cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100;
        !           354:        }
        !           355:        else if (armor)
        !           356:        {
        !           357:                cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220;
        !           358:                cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50;
        !           359:                cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50;
        !           360:        }
        !           361:        else
        !           362:        {
        !           363:                cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255;
        !           364:                cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0;
        !           365:                cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0;
        !           366:        }
        !           367: 
        !           368: //
        !           369: // calculate view angle kicks
        !           370: //
        !           371:        VectorSubtract (from, cl.simorg, from);
        !           372:        VectorNormalize (from);
        !           373:        
        !           374:        AngleVectors (cl.simangles, forward, right, up);
        !           375: 
        !           376:        side = DotProduct (from, right);
        !           377:        v_dmg_roll = count*side*v_kickroll.value;
        !           378:        
        !           379:        side = DotProduct (from, forward);
        !           380:        v_dmg_pitch = count*side*v_kickpitch.value;
        !           381: 
        !           382:        v_dmg_time = v_kicktime.value;
        !           383: }
        !           384: 
        !           385: 
        !           386: /*
        !           387: ==================
        !           388: V_cshift_f
        !           389: ==================
        !           390: */
        !           391: void V_cshift_f (void)
        !           392: {
        !           393:        cshift_empty.destcolor[0] = atoi(Cmd_Argv(1));
        !           394:        cshift_empty.destcolor[1] = atoi(Cmd_Argv(2));
        !           395:        cshift_empty.destcolor[2] = atoi(Cmd_Argv(3));
        !           396:        cshift_empty.percent = atoi(Cmd_Argv(4));
        !           397: }
        !           398: 
        !           399: 
        !           400: /*
        !           401: ==================
        !           402: V_BonusFlash_f
        !           403: 
        !           404: When you run over an item, the server sends this command
        !           405: ==================
        !           406: */
        !           407: void V_BonusFlash_f (void)
        !           408: {
        !           409:        cl.cshifts[CSHIFT_BONUS].destcolor[0] = 215;
        !           410:        cl.cshifts[CSHIFT_BONUS].destcolor[1] = 186;
        !           411:        cl.cshifts[CSHIFT_BONUS].destcolor[2] = 69;
        !           412:        cl.cshifts[CSHIFT_BONUS].percent = 50;
        !           413: }
        !           414: 
        !           415: /*
        !           416: =============
        !           417: V_SetContentsColor
        !           418: 
        !           419: Underwater, lava, etc each has a color shift
        !           420: =============
        !           421: */
        !           422: void V_SetContentsColor (int contents)
        !           423: {
        !           424:        if (!v_contentblend.value) {
        !           425:                cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;
        !           426:                return;
        !           427:        }
        !           428: 
        !           429:        switch (contents)
        !           430:        {
        !           431:        case CONTENTS_EMPTY:
        !           432:                cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;
        !           433:                break;
        !           434:        case CONTENTS_LAVA:
        !           435:                cl.cshifts[CSHIFT_CONTENTS] = cshift_lava;
        !           436:                break;
        !           437:        case CONTENTS_SOLID:
        !           438:        case CONTENTS_SLIME:
        !           439:                cl.cshifts[CSHIFT_CONTENTS] = cshift_slime;
        !           440:                break;
        !           441:        default:
        !           442:                cl.cshifts[CSHIFT_CONTENTS] = cshift_water;
        !           443:        }
        !           444: }
        !           445: 
        !           446: /*
        !           447: =============
        !           448: V_CalcPowerupCshift
        !           449: =============
        !           450: */
        !           451: void V_CalcPowerupCshift (void)
        !           452: {
        !           453:        if (cl.stats[STAT_ITEMS] & IT_QUAD)
        !           454:        {
        !           455:                cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0;
        !           456:                cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0;
        !           457:                cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255;
        !           458:                cl.cshifts[CSHIFT_POWERUP].percent = 30;
        !           459:        }
        !           460:        else if (cl.stats[STAT_ITEMS] & IT_SUIT)
        !           461:        {
        !           462:                cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0;
        !           463:                cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;
        !           464:                cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0;
        !           465:                cl.cshifts[CSHIFT_POWERUP].percent = 20;
        !           466:        }
        !           467:        else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
        !           468:        {
        !           469:                cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100;
        !           470:                cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100;
        !           471:                cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100;
        !           472:                cl.cshifts[CSHIFT_POWERUP].percent = 100;
        !           473:        }
        !           474:        else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
        !           475:        {
        !           476:                cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255;
        !           477:                cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;
        !           478:                cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0;
        !           479:                cl.cshifts[CSHIFT_POWERUP].percent = 30;
        !           480:        }
        !           481:        else
        !           482:                cl.cshifts[CSHIFT_POWERUP].percent = 0;
        !           483: }
        !           484: 
        !           485: 
        !           486: /*
        !           487: =============
        !           488: V_CalcBlend
        !           489: =============
        !           490: */
        !           491: #ifdef GLQUAKE
        !           492: void V_CalcBlend (void)
        !           493: {
        !           494:        float   r, g, b, a, a2;
        !           495:        int             j;
        !           496: 
        !           497:        r = 0;
        !           498:        g = 0;
        !           499:        b = 0;
        !           500:        a = 0;
        !           501: 
        !           502:        for (j=0 ; j<NUM_CSHIFTS ; j++) 
        !           503:        {
        !           504:                if (!gl_cshiftpercent.value)
        !           505:                        continue;
        !           506: 
        !           507:                a2 = ((cl.cshifts[j].percent * gl_cshiftpercent.value) / 100.0) / 255.0;
        !           508: 
        !           509: //             a2 = (cl.cshifts[j].percent/2)/255.0;
        !           510:                if (!a2)
        !           511:                        continue;
        !           512:                a = a + a2*(1-a);
        !           513: //Con_Printf ("j:%i a:%f\n", j, a);
        !           514:                a2 = a2/a;
        !           515:                r = r*(1-a2) + cl.cshifts[j].destcolor[0]*a2;
        !           516:                g = g*(1-a2) + cl.cshifts[j].destcolor[1]*a2;
        !           517:                b = b*(1-a2) + cl.cshifts[j].destcolor[2]*a2;
        !           518:        }
        !           519: 
        !           520:        v_blend[0] = r/255.0;
        !           521:        v_blend[1] = g/255.0;
        !           522:        v_blend[2] = b/255.0;
        !           523:        v_blend[3] = a;
        !           524:        if (v_blend[3] > 1)
        !           525:                v_blend[3] = 1;
        !           526:        if (v_blend[3] < 0)
        !           527:                v_blend[3] = 0;
        !           528: }
        !           529: #endif
        !           530: 
        !           531: /*
        !           532: =============
        !           533: V_UpdatePalette
        !           534: =============
        !           535: */
        !           536: #ifdef GLQUAKE
        !           537: void V_UpdatePalette (void)
        !           538: {
        !           539:        int             i, j;
        !           540:        qboolean        new;
        !           541:        byte    *basepal, *newpal;
        !           542:        byte    pal[768];
        !           543:        float   r,g,b,a;
        !           544:        int             ir, ig, ib;
        !           545:        qboolean force;
        !           546: 
        !           547:        V_CalcPowerupCshift ();
        !           548:        
        !           549:        new = false;
        !           550:        
        !           551:        for (i=0 ; i<NUM_CSHIFTS ; i++)
        !           552:        {
        !           553:                if (cl.cshifts[i].percent != cl.prev_cshifts[i].percent)
        !           554:                {
        !           555:                        new = true;
        !           556:                        cl.prev_cshifts[i].percent = cl.cshifts[i].percent;
        !           557:                }
        !           558:                for (j=0 ; j<3 ; j++)
        !           559:                        if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j])
        !           560:                        {
        !           561:                                new = true;
        !           562:                                cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];
        !           563:                        }
        !           564:        }
        !           565: 
        !           566: // drop the damage value
        !           567:        cl.cshifts[CSHIFT_DAMAGE].percent -= host_frametime*150;
        !           568:        if (cl.cshifts[CSHIFT_DAMAGE].percent <= 0)
        !           569:                cl.cshifts[CSHIFT_DAMAGE].percent = 0;
        !           570: 
        !           571: // drop the bonus value
        !           572:        cl.cshifts[CSHIFT_BONUS].percent -= host_frametime*100;
        !           573:        if (cl.cshifts[CSHIFT_BONUS].percent <= 0)
        !           574:                cl.cshifts[CSHIFT_BONUS].percent = 0;
        !           575: 
        !           576:        force = V_CheckGamma ();
        !           577:        if (!new && !force)
        !           578:                return;
        !           579: 
        !           580:        V_CalcBlend ();
        !           581: 
        !           582: //Con_Printf("b: %4.2f %4.2f %4.2f %4.6f\n", v_blend[0],       v_blend[1],     v_blend[2],     v_blend[3]);
        !           583: 
        !           584:        a = v_blend[3];
        !           585:        r = 255*v_blend[0]*a;
        !           586:        g = 255*v_blend[1]*a;
        !           587:        b = 255*v_blend[2]*a;
        !           588: 
        !           589:        a = 1-a;
        !           590:        for (i=0 ; i<256 ; i++)
        !           591:        {
        !           592:                ir = i*a + r;
        !           593:                ig = i*a + g;
        !           594:                ib = i*a + b;
        !           595:                if (ir > 255)
        !           596:                        ir = 255;
        !           597:                if (ig > 255)
        !           598:                        ig = 255;
        !           599:                if (ib > 255)
        !           600:                        ib = 255;
        !           601: 
        !           602:                ramps[0][i] = gammatable[ir];
        !           603:                ramps[1][i] = gammatable[ig];
        !           604:                ramps[2][i] = gammatable[ib];
        !           605:        }
        !           606: 
        !           607:        basepal = host_basepal;
        !           608:        newpal = pal;
        !           609:        
        !           610:        for (i=0 ; i<256 ; i++)
        !           611:        {
        !           612:                ir = basepal[0];
        !           613:                ig = basepal[1];
        !           614:                ib = basepal[2];
        !           615:                basepal += 3;
        !           616:                
        !           617:                newpal[0] = ramps[0][ir];
        !           618:                newpal[1] = ramps[1][ig];
        !           619:                newpal[2] = ramps[2][ib];
        !           620:                newpal += 3;
        !           621:        }
        !           622: 
        !           623:        VID_ShiftPalette (pal); 
        !           624: }
        !           625: #else  // !GLQUAKE
        !           626: /*
        !           627: =============
        !           628: V_UpdatePalette
        !           629: =============
        !           630: */
        !           631: void V_UpdatePalette (void)
        !           632: {
        !           633:        int             i, j;
        !           634:        qboolean        new;
        !           635:        byte    *basepal, *newpal;
        !           636:        byte    pal[768];
        !           637:        int             r,g,b;
        !           638:        qboolean force;
        !           639: 
        !           640:        V_CalcPowerupCshift ();
        !           641:        
        !           642:        new = false;
        !           643:        
        !           644:        for (i=0 ; i<NUM_CSHIFTS ; i++)
        !           645:        {
        !           646:                if (cl.cshifts[i].percent != cl.prev_cshifts[i].percent)
        !           647:                {
        !           648:                        new = true;
        !           649:                        cl.prev_cshifts[i].percent = cl.cshifts[i].percent;
        !           650:                }
        !           651:                for (j=0 ; j<3 ; j++)
        !           652:                        if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j])
        !           653:                        {
        !           654:                                new = true;
        !           655:                                cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];
        !           656:                        }
        !           657:        }
        !           658:        
        !           659: // drop the damage value
        !           660:        cl.cshifts[CSHIFT_DAMAGE].percent -= host_frametime*150;
        !           661:        if (cl.cshifts[CSHIFT_DAMAGE].percent <= 0)
        !           662:                cl.cshifts[CSHIFT_DAMAGE].percent = 0;
        !           663: 
        !           664: // drop the bonus value
        !           665:        cl.cshifts[CSHIFT_BONUS].percent -= host_frametime*100;
        !           666:        if (cl.cshifts[CSHIFT_BONUS].percent <= 0)
        !           667:                cl.cshifts[CSHIFT_BONUS].percent = 0;
        !           668: 
        !           669:        force = V_CheckGamma ();
        !           670:        if (!new && !force)
        !           671:                return;
        !           672:                        
        !           673:        basepal = host_basepal;
        !           674:        newpal = pal;
        !           675:        
        !           676:        for (i=0 ; i<256 ; i++)
        !           677:        {
        !           678:                r = basepal[0];
        !           679:                g = basepal[1];
        !           680:                b = basepal[2];
        !           681:                basepal += 3;
        !           682:        
        !           683:                for (j=0 ; j<NUM_CSHIFTS ; j++) 
        !           684:                {
        !           685:                        r += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[0]-r))>>8;
        !           686:                        g += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[1]-g))>>8;
        !           687:                        b += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[2]-b))>>8;
        !           688:                }
        !           689:                
        !           690:                newpal[0] = gammatable[r];
        !           691:                newpal[1] = gammatable[g];
        !           692:                newpal[2] = gammatable[b];
        !           693:                newpal += 3;
        !           694:        }
        !           695: 
        !           696:        VID_ShiftPalette (pal); 
        !           697: }
        !           698: 
        !           699: #endif // !GLQUAKE
        !           700: 
        !           701: /* 
        !           702: ============================================================================== 
        !           703:  
        !           704:                                                VIEW RENDERING 
        !           705:  
        !           706: ============================================================================== 
        !           707: */ 
        !           708: 
        !           709: float angledelta (float a)
        !           710: {
        !           711:        a = anglemod(a);
        !           712:        if (a > 180)
        !           713:                a -= 360;
        !           714:        return a;
        !           715: }
        !           716: 
        !           717: /*
        !           718: ==================
        !           719: CalcGunAngle
        !           720: ==================
        !           721: */
        !           722: void CalcGunAngle (void)
        !           723: {      
        !           724:        float   yaw, pitch, move;
        !           725:        static float oldyaw = 0;
        !           726:        static float oldpitch = 0;
        !           727:        
        !           728:        yaw = r_refdef.viewangles[YAW];
        !           729:        pitch = -r_refdef.viewangles[PITCH];
        !           730: 
        !           731:        yaw = angledelta(yaw - r_refdef.viewangles[YAW]) * 0.4;
        !           732:        if (yaw > 10)
        !           733:                yaw = 10;
        !           734:        if (yaw < -10)
        !           735:                yaw = -10;
        !           736:        pitch = angledelta(-pitch - r_refdef.viewangles[PITCH]) * 0.4;
        !           737:        if (pitch > 10)
        !           738:                pitch = 10;
        !           739:        if (pitch < -10)
        !           740:                pitch = -10;
        !           741:        move = host_frametime*20;
        !           742:        if (yaw > oldyaw)
        !           743:        {
        !           744:                if (oldyaw + move < yaw)
        !           745:                        yaw = oldyaw + move;
        !           746:        }
        !           747:        else
        !           748:        {
        !           749:                if (oldyaw - move > yaw)
        !           750:                        yaw = oldyaw - move;
        !           751:        }
        !           752:        
        !           753:        if (pitch > oldpitch)
        !           754:        {
        !           755:                if (oldpitch + move < pitch)
        !           756:                        pitch = oldpitch + move;
        !           757:        }
        !           758:        else
        !           759:        {
        !           760:                if (oldpitch - move > pitch)
        !           761:                        pitch = oldpitch - move;
        !           762:        }
        !           763:        
        !           764:        oldyaw = yaw;
        !           765:        oldpitch = pitch;
        !           766: 
        !           767:        cl.viewent.angles[YAW] = r_refdef.viewangles[YAW] + yaw;
        !           768:        cl.viewent.angles[PITCH] = - (r_refdef.viewangles[PITCH] + pitch);
        !           769: }
        !           770: 
        !           771: /*
        !           772: ==============
        !           773: V_BoundOffsets
        !           774: ==============
        !           775: */
        !           776: void V_BoundOffsets (void)
        !           777: {
        !           778: // absolutely bound refresh reletive to entity clipping hull
        !           779: // so the view can never be inside a solid wall
        !           780: 
        !           781:        if (r_refdef.vieworg[0] < cl.simorg[0] - 14)
        !           782:                r_refdef.vieworg[0] = cl.simorg[0] - 14;
        !           783:        else if (r_refdef.vieworg[0] > cl.simorg[0] + 14)
        !           784:                r_refdef.vieworg[0] = cl.simorg[0] + 14;
        !           785:        if (r_refdef.vieworg[1] < cl.simorg[1] - 14)
        !           786:                r_refdef.vieworg[1] = cl.simorg[1] - 14;
        !           787:        else if (r_refdef.vieworg[1] > cl.simorg[1] + 14)
        !           788:                r_refdef.vieworg[1] = cl.simorg[1] + 14;
        !           789:        if (r_refdef.vieworg[2] < cl.simorg[2] - 22)
        !           790:                r_refdef.vieworg[2] = cl.simorg[2] - 22;
        !           791:        else if (r_refdef.vieworg[2] > cl.simorg[2] + 30)
        !           792:                r_refdef.vieworg[2] = cl.simorg[2] + 30;
        !           793: }
        !           794: 
        !           795: /*
        !           796: ==============
        !           797: V_AddIdle
        !           798: 
        !           799: Idle swaying
        !           800: ==============
        !           801: */
        !           802: void V_AddIdle (void)
        !           803: {
        !           804:        r_refdef.viewangles[ROLL] += v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;
        !           805:        r_refdef.viewangles[PITCH] += v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value;
        !           806:        r_refdef.viewangles[YAW] += v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value;
        !           807: 
        !           808:        cl.viewent.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;
        !           809:        cl.viewent.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value;
        !           810:        cl.viewent.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value;
        !           811: }
        !           812: 
        !           813: 
        !           814: /*
        !           815: ==============
        !           816: V_CalcViewRoll
        !           817: 
        !           818: Roll is induced by movement and damage
        !           819: ==============
        !           820: */
        !           821: void V_CalcViewRoll (void)
        !           822: {
        !           823:        float           side;
        !           824:                
        !           825:        side = V_CalcRoll (cl.simangles, cl.simvel);
        !           826:        r_refdef.viewangles[ROLL] += side;
        !           827: 
        !           828:        if (v_dmg_time > 0)
        !           829:        {
        !           830:                r_refdef.viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll;
        !           831:                r_refdef.viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch;
        !           832:                v_dmg_time -= host_frametime;
        !           833:        }
        !           834: 
        !           835: }
        !           836: 
        !           837: 
        !           838: /*
        !           839: ==================
        !           840: V_CalcIntermissionRefdef
        !           841: 
        !           842: ==================
        !           843: */
        !           844: void V_CalcIntermissionRefdef (void)
        !           845: {
        !           846:        entity_t        *view;
        !           847:        float           old;
        !           848: 
        !           849: // view is the weapon model
        !           850:        view = &cl.viewent;
        !           851: 
        !           852:        VectorCopy (cl.simorg, r_refdef.vieworg);
        !           853:        VectorCopy (cl.simangles, r_refdef.viewangles);
        !           854:        view->model = NULL;
        !           855: 
        !           856: // allways idle in intermission
        !           857:        old = v_idlescale.value;
        !           858:        v_idlescale.value = 1;
        !           859:        V_AddIdle ();
        !           860:        v_idlescale.value = old;
        !           861: }
        !           862: 
        !           863: /*
        !           864: ==================
        !           865: V_CalcRefdef
        !           866: 
        !           867: ==================
        !           868: */
        !           869: void V_CalcRefdef (void)
        !           870: {
        !           871:        entity_t        *view;
        !           872:        int                     i;
        !           873:        vec3_t          forward, right, up;
        !           874:        float           bob;
        !           875:        static float oldz = 0;
        !           876: 
        !           877:        V_DriftPitch ();
        !           878: 
        !           879: // view is the weapon model (only visible from inside body)
        !           880:        view = &cl.viewent;
        !           881: 
        !           882:        bob = V_CalcBob ();
        !           883:        
        !           884: // refresh position from simulated origin
        !           885:        VectorCopy (cl.simorg, r_refdef.vieworg);
        !           886: 
        !           887:        r_refdef.vieworg[2] += bob;
        !           888: 
        !           889: // never let it sit exactly on a node line, because a water plane can
        !           890: // dissapear when viewed with the eye exactly on it.
        !           891: // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis
        !           892:        r_refdef.vieworg[0] += 1.0/16;
        !           893:        r_refdef.vieworg[1] += 1.0/16;
        !           894:        r_refdef.vieworg[2] += 1.0/16;
        !           895: 
        !           896:        VectorCopy (cl.simangles, r_refdef.viewangles);
        !           897:        V_CalcViewRoll ();
        !           898:        V_AddIdle ();
        !           899: 
        !           900:        if (view_message->flags & PF_GIB)
        !           901:                r_refdef.vieworg[2] += 8;       // gib view height
        !           902:        else if (view_message->flags & PF_DEAD)
        !           903:                r_refdef.vieworg[2] -= 16;      // corpse view height
        !           904:        else
        !           905:                r_refdef.vieworg[2] += 22;      // view height
        !           906: 
        !           907:        if (view_message->flags & PF_DEAD)              // PF_GIB will also set PF_DEAD
        !           908:                r_refdef.viewangles[ROLL] = 80; // dead view angle
        !           909: 
        !           910: 
        !           911: // offsets
        !           912:        AngleVectors (cl.simangles, forward, right, up);
        !           913:        
        !           914: // set up gun position
        !           915:        VectorCopy (cl.simangles, view->angles);
        !           916:        
        !           917:        CalcGunAngle ();
        !           918: 
        !           919:        VectorCopy (cl.simorg, view->origin);
        !           920:        view->origin[2] += 22;
        !           921: 
        !           922:        for (i=0 ; i<3 ; i++)
        !           923:        {
        !           924:                view->origin[i] += forward[i]*bob*0.4;
        !           925: //             view->origin[i] += right[i]*bob*0.4;
        !           926: //             view->origin[i] += up[i]*bob*0.8;
        !           927:        }
        !           928:        view->origin[2] += bob;
        !           929: 
        !           930: // fudge position around to keep amount of weapon visible
        !           931: // roughly equal with different FOV
        !           932:        if (scr_viewsize.value == 110)
        !           933:                view->origin[2] += 1;
        !           934:        else if (scr_viewsize.value == 100)
        !           935:                view->origin[2] += 2;
        !           936:        else if (scr_viewsize.value == 90)
        !           937:                view->origin[2] += 1;
        !           938:        else if (scr_viewsize.value == 80)
        !           939:                view->origin[2] += 0.5;
        !           940: 
        !           941:        if (view_message->flags & (PF_GIB|PF_DEAD) )
        !           942:                view->model = NULL;
        !           943:        else
        !           944:                view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
        !           945:        view->frame = view_message->weaponframe;
        !           946:        view->colormap = vid.colormap;
        !           947: 
        !           948: // set up the refresh position
        !           949:        r_refdef.viewangles[PITCH] += cl.punchangle;
        !           950: 
        !           951: // smooth out stair step ups
        !           952:        if ( (view_message->onground != -1) && (cl.simorg[2] - oldz > 0) )
        !           953:        {
        !           954:                float steptime;
        !           955:                
        !           956:                steptime = host_frametime;
        !           957:        
        !           958:                oldz += steptime * 80;
        !           959:                if (oldz > cl.simorg[2])
        !           960:                        oldz = cl.simorg[2];
        !           961:                if (cl.simorg[2] - oldz > 12)
        !           962:                        oldz = cl.simorg[2] - 12;
        !           963:                r_refdef.vieworg[2] += oldz - cl.simorg[2];
        !           964:                view->origin[2] += oldz - cl.simorg[2];
        !           965:        }
        !           966:        else
        !           967:                oldz = cl.simorg[2];
        !           968: }
        !           969: 
        !           970: /*
        !           971: =============
        !           972: DropPunchAngle
        !           973: =============
        !           974: */
        !           975: void DropPunchAngle (void)
        !           976: {
        !           977:        cl.punchangle -= 10*host_frametime;
        !           978:        if (cl.punchangle < 0)
        !           979:                cl.punchangle = 0;
        !           980: }
        !           981: 
        !           982: /*
        !           983: ==================
        !           984: V_RenderView
        !           985: 
        !           986: The player's clipping box goes from (-16 -16 -24) to (16 16 32) from
        !           987: the entity origin, so any view position inside that will be valid
        !           988: ==================
        !           989: */
        !           990: extern vrect_t scr_vrect;
        !           991: 
        !           992: void V_RenderView (void)
        !           993: {
        !           994: //     if (cl.simangles[ROLL])
        !           995: //             Sys_Error ("cl.simangles[ROLL]");       // DEBUG
        !           996: cl.simangles[ROLL] = 0;        // FIXME @@@ 
        !           997: 
        !           998:        if (cls.state != ca_active)
        !           999:                return;
        !          1000: 
        !          1001:        view_frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK];
        !          1002:        view_message = &view_frame->playerstate[cl.playernum];
        !          1003: 
        !          1004:        DropPunchAngle ();
        !          1005:        if (cl.intermission)
        !          1006:        {       // intermission / finale rendering
        !          1007:                V_CalcIntermissionRefdef ();    
        !          1008:        }
        !          1009:        else
        !          1010:        {
        !          1011:                V_CalcRefdef ();
        !          1012:        }
        !          1013: 
        !          1014:        R_PushDlights ();
        !          1015:        R_RenderView ();
        !          1016:        
        !          1017: #ifndef GLQUAKE
        !          1018:        if (crosshair.value)
        !          1019:                Draw_Crosshair();
        !          1020: #endif
        !          1021:                
        !          1022: }
        !          1023: 
        !          1024: //============================================================================
        !          1025: 
        !          1026: /*
        !          1027: =============
        !          1028: V_Init
        !          1029: =============
        !          1030: */
        !          1031: void V_Init (void)
        !          1032: {
        !          1033:        Cmd_AddCommand ("v_cshift", V_cshift_f);        
        !          1034:        Cmd_AddCommand ("bf", V_BonusFlash_f);
        !          1035:        Cmd_AddCommand ("centerview", V_StartPitchDrift);
        !          1036: 
        !          1037:        Cvar_RegisterVariable (&v_centermove);
        !          1038:        Cvar_RegisterVariable (&v_centerspeed);
        !          1039: 
        !          1040:        Cvar_RegisterVariable (&v_iyaw_cycle);
        !          1041:        Cvar_RegisterVariable (&v_iroll_cycle);
        !          1042:        Cvar_RegisterVariable (&v_ipitch_cycle);
        !          1043:        Cvar_RegisterVariable (&v_iyaw_level);
        !          1044:        Cvar_RegisterVariable (&v_iroll_level);
        !          1045:        Cvar_RegisterVariable (&v_ipitch_level);
        !          1046: 
        !          1047:        Cvar_RegisterVariable (&v_contentblend);
        !          1048: 
        !          1049:        Cvar_RegisterVariable (&v_idlescale);
        !          1050:        Cvar_RegisterVariable (&crosshaircolor);
        !          1051:        Cvar_RegisterVariable (&crosshair);
        !          1052:        Cvar_RegisterVariable (&cl_crossx);
        !          1053:        Cvar_RegisterVariable (&cl_crossy);
        !          1054: #ifdef GLQUAKE
        !          1055:        Cvar_RegisterVariable (&gl_cshiftpercent);
        !          1056: #endif
        !          1057: 
        !          1058:        Cvar_RegisterVariable (&cl_rollspeed);
        !          1059:        Cvar_RegisterVariable (&cl_rollangle);
        !          1060:        Cvar_RegisterVariable (&cl_bob);
        !          1061:        Cvar_RegisterVariable (&cl_bobcycle);
        !          1062:        Cvar_RegisterVariable (&cl_bobup);
        !          1063: 
        !          1064:        Cvar_RegisterVariable (&v_kicktime);
        !          1065:        Cvar_RegisterVariable (&v_kickroll);
        !          1066:        Cvar_RegisterVariable (&v_kickpitch);   
        !          1067: 
        !          1068:        BuildGammaTable (1.0);  // no gamma yet
        !          1069:        Cvar_RegisterVariable (&v_gamma);
        !          1070: }
        !          1071: 
        !          1072: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.