Annotation of quakeworld/client/view.c, revision 1.1.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.