Annotation of quake2/client/cl_view.c, revision 1.1.1.2

1.1       root        1: // cl_view.c -- player rendering positioning
1.1.1.2 ! root        2: 
1.1       root        3: #include "client.h"
1.1.1.2 ! root        4: 
1.1       root        5: //=============
                      6: //
                      7: // development tools for weapons
                      8: //
                      9: int                    gun_frame;
                     10: struct model_s *gun_model;
1.1.1.2 ! root       11: 
1.1       root       12: //=============
1.1.1.2 ! root       13: 
1.1       root       14: cvar_t         *crosshair;
                     15: cvar_t         *cl_testparticles;
                     16: cvar_t         *cl_testentities;
                     17: cvar_t         *cl_testlights;
                     18: cvar_t         *cl_testblend;
1.1.1.2 ! root       19: 
1.1       root       20: cvar_t         *cl_stats;
1.1.1.2 ! root       21: 
        !            22: 
1.1       root       23: int                    r_numdlights;
                     24: dlight_t       r_dlights[MAX_DLIGHTS];
1.1.1.2 ! root       25: 
1.1       root       26: int                    r_numentities;
                     27: entity_t       r_entities[MAX_ENTITIES];
1.1.1.2 ! root       28: 
1.1       root       29: int                    r_numparticles;
                     30: particle_t     r_particles[MAX_PARTICLES];
1.1.1.2 ! root       31: 
1.1       root       32: lightstyle_t   r_lightstyles[MAX_LIGHTSTYLES];
1.1.1.2 ! root       33: 
        !            34: char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH];
        !            35: int num_cl_weaponmodels;
        !            36: 
1.1       root       37: /*
                     38: ====================
                     39: V_ClearScene
1.1.1.2 ! root       40: 
1.1       root       41: Specifies the model that will be used as the world
                     42: ====================
                     43: */
                     44: void V_ClearScene (void)
                     45: {
                     46:        r_numdlights = 0;
                     47:        r_numentities = 0;
                     48:        r_numparticles = 0;
                     49: }
1.1.1.2 ! root       50: 
        !            51: 
1.1       root       52: /*
                     53: =====================
                     54: V_AddEntity
1.1.1.2 ! root       55: 
1.1       root       56: =====================
                     57: */
                     58: void V_AddEntity (entity_t *ent)
                     59: {
                     60:        if (r_numentities >= MAX_ENTITIES)
                     61:                return;
                     62:        r_entities[r_numentities++] = *ent;
                     63: }
1.1.1.2 ! root       64: 
        !            65: 
1.1       root       66: /*
                     67: =====================
                     68: V_AddParticle
1.1.1.2 ! root       69: 
1.1       root       70: =====================
                     71: */
                     72: void V_AddParticle (vec3_t org, int color, float alpha)
                     73: {
                     74:        particle_t      *p;
1.1.1.2 ! root       75: 
1.1       root       76:        if (r_numparticles >= MAX_PARTICLES)
                     77:                return;
                     78:        p = &r_particles[r_numparticles++];
                     79:        VectorCopy (org, p->origin);
                     80:        p->color = color;
                     81:        p->alpha = alpha;
                     82: }
1.1.1.2 ! root       83: 
1.1       root       84: /*
                     85: =====================
                     86: V_AddLight
1.1.1.2 ! root       87: 
1.1       root       88: =====================
                     89: */
                     90: void V_AddLight (vec3_t org, float intensity, float r, float g, float b)
                     91: {
                     92:        dlight_t        *dl;
1.1.1.2 ! root       93: 
1.1       root       94:        if (r_numdlights >= MAX_DLIGHTS)
                     95:                return;
                     96:        dl = &r_dlights[r_numdlights++];
                     97:        VectorCopy (org, dl->origin);
                     98:        dl->intensity = intensity;
                     99:        dl->color[0] = r;
                    100:        dl->color[1] = g;
                    101:        dl->color[2] = b;
                    102: }
1.1.1.2 ! root      103: 
        !           104: 
1.1       root      105: /*
                    106: =====================
                    107: V_AddLightStyle
1.1.1.2 ! root      108: 
1.1       root      109: =====================
                    110: */
                    111: void V_AddLightStyle (int style, float r, float g, float b)
                    112: {
                    113:        lightstyle_t    *ls;
1.1.1.2 ! root      114: 
1.1       root      115:        if (style < 0 || style > MAX_LIGHTSTYLES)
                    116:                Com_Error (ERR_DROP, "Bad light style %i", style);
                    117:        ls = &r_lightstyles[style];
1.1.1.2 ! root      118: 
1.1       root      119:        ls->white = r+g+b;
                    120:        ls->rgb[0] = r;
                    121:        ls->rgb[1] = g;
                    122:        ls->rgb[2] = b;
                    123: }
1.1.1.2 ! root      124: 
1.1       root      125: /*
                    126: ================
                    127: V_TestParticles
1.1.1.2 ! root      128: 
1.1       root      129: If cl_testparticles is set, create 4096 particles in the view
                    130: ================
                    131: */
                    132: void V_TestParticles (void)
                    133: {
                    134:        particle_t      *p;
                    135:        int                     i, j;
                    136:        float           d, r, u;
1.1.1.2 ! root      137: 
1.1       root      138:        r_numparticles = MAX_PARTICLES;
                    139:        for (i=0 ; i<r_numparticles ; i++)
                    140:        {
                    141:                d = i*0.25;
                    142:                r = 4*((i&7)-3.5);
                    143:                u = 4*(((i>>3)&7)-3.5);
                    144:                p = &r_particles[i];
1.1.1.2 ! root      145: 
1.1       root      146:                for (j=0 ; j<3 ; j++)
                    147:                        p->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*d +
                    148:                        cl.v_right[j]*r + cl.v_up[j]*u;
1.1.1.2 ! root      149: 
1.1       root      150:                p->color = 8;
                    151:                p->alpha = cl_testparticles->value;
                    152:        }
                    153: }
1.1.1.2 ! root      154: 
1.1       root      155: /*
                    156: ================
                    157: V_TestEntities
                    158: 
                    159: If cl_testentities is set, create 32 player models
                    160: ================
                    161: */
                    162: void V_TestEntities (void)
                    163: {
                    164:        int                     i, j;
                    165:        float           f, r;
                    166:        entity_t        *ent;
                    167: 
                    168:        r_numentities = 32;
                    169:        memset (r_entities, 0, sizeof(r_entities));
                    170: 
                    171:        for (i=0 ; i<r_numentities ; i++)
                    172:        {
                    173:                ent = &r_entities[i];
                    174: 
                    175:                r = 64 * ( (i%4) - 1.5 );
                    176:                f = 64 * (i/4) + 128;
                    177: 
                    178:                for (j=0 ; j<3 ; j++)
                    179:                        ent->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f +
                    180:                        cl.v_right[j]*r;
                    181: 
                    182:                ent->model = cl.baseclientinfo.model;
                    183:                ent->skin = cl.baseclientinfo.skin;
                    184:        }
                    185: }
                    186: 
                    187: /*
                    188: ================
                    189: V_TestLights
                    190: 
                    191: If cl_testlights is set, create 32 lights models
                    192: ================
                    193: */
                    194: void V_TestLights (void)
                    195: {
                    196:        int                     i, j;
                    197:        float           f, r;
                    198:        dlight_t        *dl;
                    199: 
                    200:        r_numdlights = 32;
                    201:        memset (r_dlights, 0, sizeof(r_dlights));
                    202: 
                    203:        for (i=0 ; i<r_numdlights ; i++)
                    204:        {
                    205:                dl = &r_dlights[i];
                    206: 
                    207:                r = 64 * ( (i%4) - 1.5 );
                    208:                f = 64 * (i/4) + 128;
                    209: 
                    210:                for (j=0 ; j<3 ; j++)
                    211:                        dl->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f +
                    212:                        cl.v_right[j]*r;
                    213:                dl->color[0] = ((i%6)+1) & 1;
                    214:                dl->color[1] = (((i%6)+1) & 2)>>1;
                    215:                dl->color[2] = (((i%6)+1) & 4)>>2;
                    216:                dl->intensity = 200;
                    217:        }
                    218: }
                    219: 
                    220: //===================================================================
1.1.1.2 ! root      221: 
1.1       root      222: /*
                    223: =================
                    224: CL_PrepRefresh
1.1.1.2 ! root      225: 
1.1       root      226: Call before entering a new level, or after changing dlls
                    227: =================
                    228: */
                    229: void CL_PrepRefresh (void)
                    230: {
                    231:        char            mapname[32];
                    232:        int                     i;
                    233:        char            name[MAX_QPATH];
                    234:        float           rotate;
                    235:        vec3_t          axis;
1.1.1.2 ! root      236: 
1.1       root      237:        if (!cl.configstrings[CS_MODELS+1][0])
                    238:                return;         // no map loaded
1.1.1.2 ! root      239: 
1.1       root      240:        SCR_AddDirtyPoint (0, 0);
                    241:        SCR_AddDirtyPoint (viddef.width-1, viddef.height-1);
1.1.1.2 ! root      242: 
1.1       root      243:        // let the render dll load the map
                    244:        strcpy (mapname, cl.configstrings[CS_MODELS+1] + 5);    // skip "maps/"
                    245:        mapname[strlen(mapname)-4] = 0;         // cut off ".bsp"
1.1.1.2 ! root      246: 
1.1       root      247:        // register models, pics, and skins
                    248:        Com_Printf ("Map: %s\r", mapname); 
                    249:        SCR_UpdateScreen ();
                    250:        re.BeginRegistration (mapname);
                    251:        Com_Printf ("                                     \r");
1.1.1.2 ! root      252: 
1.1       root      253:        // precache status bar pics
                    254:        Com_Printf ("pics\r"); 
                    255:        SCR_UpdateScreen ();
                    256:        SCR_TouchPics ();
                    257:        Com_Printf ("                                     \r");
                    258: 
                    259:        CL_RegisterTEntModels ();
1.1.1.2 ! root      260: 
        !           261:        num_cl_weaponmodels = 1;
        !           262:        strcpy(cl_weaponmodels[0], "weapon.md2");
        !           263: 
1.1       root      264:        for (i=1 ; i<MAX_MODELS && cl.configstrings[CS_MODELS+i][0] ; i++)
                    265:        {
                    266:                strcpy (name, cl.configstrings[CS_MODELS+i]);
                    267:                name[37] = 0;   // never go beyond one line
                    268:                if (name[0] != '*')
                    269:                        Com_Printf ("%s\r", name); 
                    270:                SCR_UpdateScreen ();
                    271:                Sys_SendKeyEvents ();   // pump message loop
1.1.1.2 ! root      272:                if (name[0] == '#') {
        !           273:                        // special player weapon model
        !           274:                        if (num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS) {
        !           275:                                strncpy(cl_weaponmodels[num_cl_weaponmodels], cl.configstrings[CS_MODELS+i]+1,
        !           276:                                        sizeof(cl_weaponmodels[num_cl_weaponmodels]) - 1);
        !           277:                                num_cl_weaponmodels++;
        !           278:                        }
        !           279:                } else {
        !           280:                        cl.model_draw[i] = re.RegisterModel (cl.configstrings[CS_MODELS+i]);
        !           281:                        if (name[0] == '*')
        !           282:                                cl.model_clip[i] = CM_InlineModel (cl.configstrings[CS_MODELS+i]);
        !           283:                        else
        !           284:                                cl.model_clip[i] = NULL;
        !           285:                }
1.1       root      286:                if (name[0] != '*')
                    287:                        Com_Printf ("                                     \r");
                    288:        }
                    289:        Com_Printf ("images\r", i); 
                    290:        SCR_UpdateScreen ();
                    291:        for (i=1 ; i<MAX_IMAGES && cl.configstrings[CS_IMAGES+i][0] ; i++)
                    292:        {
                    293:                cl.image_precache[i] = re.RegisterPic (cl.configstrings[CS_IMAGES+i]);
                    294:                Sys_SendKeyEvents ();   // pump message loop
                    295:        }
                    296:        Com_Printf ("                                     \r");
                    297:        for (i=0 ; i<MAX_CLIENTS ; i++)
                    298:        {
                    299:                if (!cl.configstrings[CS_PLAYERSKINS+i][0])
                    300:                        continue;
                    301:                Com_Printf ("client %i\r", i); 
                    302:                SCR_UpdateScreen ();
                    303:                Sys_SendKeyEvents ();   // pump message loop
                    304:                CL_ParseClientinfo (i);
                    305:                Com_Printf ("                                     \r");
                    306:        }
1.1.1.2 ! root      307: 
1.1       root      308:        CL_LoadClientinfo (&cl.baseclientinfo, "unnamed\\male/grunt");
1.1.1.2 ! root      309: 
1.1       root      310:        // set sky textures and speed
                    311:        Com_Printf ("sky\r", i); 
                    312:        SCR_UpdateScreen ();
                    313:        rotate = atof (cl.configstrings[CS_SKYROTATE]);
                    314:        sscanf (cl.configstrings[CS_SKYAXIS], "%f %f %f", 
                    315:                &axis[0], &axis[1], &axis[2]);
                    316:        re.SetSky (cl.configstrings[CS_SKY], rotate, axis);
                    317:        Com_Printf ("                                     \r");
1.1.1.2 ! root      318: 
1.1       root      319:        // the renderer can now free unneeded stuff
                    320:        re.EndRegistration ();
1.1.1.2 ! root      321: 
1.1       root      322:        // clear any lines of console text
                    323:        Con_ClearNotify ();
1.1.1.2 ! root      324: 
1.1       root      325:        SCR_UpdateScreen ();
                    326:        cl.refresh_prepped = true;
                    327:        cl.force_refdef = true; // make sure we have a valid refdef
                    328: 
                    329:        // start the cd track
                    330:        CDAudio_Play (atoi(cl.configstrings[CS_CDTRACK]), true);
                    331: }
1.1.1.2 ! root      332: 
1.1       root      333: /*
                    334: ====================
                    335: CalcFov
                    336: ====================
                    337: */
                    338: float CalcFov (float fov_x, float width, float height)
                    339: {
                    340:        float   a;
                    341:        float   x;
1.1.1.2 ! root      342: 
1.1       root      343:        if (fov_x < 1 || fov_x > 179)
                    344:                Com_Error (ERR_DROP, "Bad fov: %f", fov_x);
1.1.1.2 ! root      345: 
1.1       root      346:        x = width/tan(fov_x/360*M_PI);
1.1.1.2 ! root      347: 
1.1       root      348:        a = atan (height/x);
1.1.1.2 ! root      349: 
1.1       root      350:        a = a*360/M_PI;
1.1.1.2 ! root      351: 
1.1       root      352:        return a;
                    353: }
1.1.1.2 ! root      354: 
1.1       root      355: //============================================================================
1.1.1.2 ! root      356: 
1.1       root      357: // gun frame debugging functions
                    358: void V_Gun_Next_f (void)
                    359: {
                    360:        gun_frame++;
                    361:        Com_Printf ("frame %i\n", gun_frame);
                    362: }
1.1.1.2 ! root      363: 
1.1       root      364: void V_Gun_Prev_f (void)
                    365: {
                    366:        gun_frame--;
                    367:        if (gun_frame < 0)
                    368:                gun_frame = 0;
                    369:        Com_Printf ("frame %i\n", gun_frame);
                    370: }
1.1.1.2 ! root      371: 
1.1       root      372: void V_Gun_Model_f (void)
                    373: {
                    374:        char    name[MAX_QPATH];
1.1.1.2 ! root      375: 
1.1       root      376:        if (Cmd_Argc() != 2)
                    377:        {
                    378:                gun_model = NULL;
                    379:                return;
                    380:        }
                    381:        Com_sprintf (name, sizeof(name), "models/%s/tris.md2", Cmd_Argv(1));
                    382:        gun_model = re.RegisterModel (name);
                    383: }
1.1.1.2 ! root      384: 
1.1       root      385: //============================================================================
                    386: 
1.1.1.2 ! root      387: 
1.1       root      388: /*
                    389: =================
                    390: SCR_DrawCrosshair
                    391: =================
                    392: */
                    393: void SCR_DrawCrosshair (void)
                    394: {
                    395:        if (!crosshair->value)
                    396:                return;
                    397: 
                    398:        if (crosshair->modified)
                    399:        {
                    400:                crosshair->modified = false;
                    401:                SCR_TouchPics ();
                    402:        }
                    403: 
                    404:        if (!crosshair_pic[0])
                    405:                return;
                    406: 
                    407:        re.DrawPic (scr_vrect.x + ((scr_vrect.width - crosshair_width)>>1)
                    408:        , scr_vrect.y + ((scr_vrect.height - crosshair_height)>>1), crosshair_pic);
                    409: }
1.1.1.2 ! root      410: 
1.1       root      411: /*
                    412: ==================
                    413: V_RenderView
1.1.1.2 ! root      414: 
1.1       root      415: ==================
                    416: */
                    417: void V_RenderView( float stereo_separation )
                    418: {
                    419:        extern int entitycmpfnc( const entity_t *, const entity_t * );
                    420: 
                    421:        if (cls.state != ca_active)
                    422:                return;
1.1.1.2 ! root      423: 
1.1       root      424:        if (!cl.refresh_prepped)
                    425:                return;                 // still loading
                    426: 
                    427:        if (cl_timedemo->value)
                    428:        {
                    429:                if (!cl.timedemo_start)
                    430:                        cl.timedemo_start = Sys_Milliseconds ();
                    431:                cl.timedemo_frames++;
                    432:        }
                    433: 
                    434:        // an invalid frame will just use the exact previous refdef
                    435:        // we can't use the old frame if the video mode has changed, though...
                    436:        if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) )
                    437:        {
                    438:                cl.force_refdef = false;
1.1.1.2 ! root      439: 
1.1       root      440:                V_ClearScene ();
                    441: 
                    442:                // build a refresh entity list and calc cl.sim*
                    443:                // this also calls CL_CalcViewValues which loads
                    444:                // v_forward, etc.
                    445:                CL_AddEntities ();
1.1.1.2 ! root      446: 
1.1       root      447:                if (cl_testparticles->value)
                    448:                        V_TestParticles ();
                    449:                if (cl_testentities->value)
                    450:                        V_TestEntities ();
                    451:                if (cl_testlights->value)
                    452:                        V_TestLights ();
                    453:                if (cl_testblend->value)
                    454:                {
                    455:                        cl.refdef.blend[0] = 1;
                    456:                        cl.refdef.blend[1] = 0.5;
                    457:                        cl.refdef.blend[2] = 0.25;
                    458:                        cl.refdef.blend[3] = 0.5;
                    459:                }
1.1.1.2 ! root      460: 
1.1       root      461:                // offset vieworg appropriately if we're doing stereo separation
                    462:                if ( stereo_separation != 0 )
                    463:                {
                    464:                        vec3_t tmp;
                    465: 
                    466:                        VectorScale( cl.v_right, stereo_separation, tmp );
                    467:                        VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg );
                    468:                }
1.1.1.2 ! root      469: 
1.1       root      470:                // never let it sit exactly on a node line, because a water plane can
                    471:                // dissapear when viewed with the eye exactly on it.
                    472:                // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis
                    473:                cl.refdef.vieworg[0] += 1.0/16;
                    474:                cl.refdef.vieworg[1] += 1.0/16;
                    475:                cl.refdef.vieworg[2] += 1.0/16;
                    476: 
                    477:                cl.refdef.x = scr_vrect.x;
                    478:                cl.refdef.y = scr_vrect.y;
                    479:                cl.refdef.width = scr_vrect.width;
                    480:                cl.refdef.height = scr_vrect.height;
                    481:                cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height);
                    482:                cl.refdef.time = cl.time*0.001;
1.1.1.2 ! root      483: 
1.1       root      484:                cl.refdef.areabits = cl.frame.areabits;
                    485: 
                    486:                if (!cl_add_entities->value)
                    487:                        r_numentities = 0;
                    488:                if (!cl_add_particles->value)
                    489:                        r_numparticles = 0;
                    490:                if (!cl_add_lights->value)
                    491:                        r_numdlights = 0;
                    492:                if (!cl_add_blend->value)
                    493:                {
                    494:                        VectorClear (cl.refdef.blend);
                    495:                }
1.1.1.2 ! root      496: 
1.1       root      497:                cl.refdef.num_entities = r_numentities;
                    498:                cl.refdef.entities = r_entities;
                    499:                cl.refdef.num_particles = r_numparticles;
                    500:                cl.refdef.particles = r_particles;
                    501:                cl.refdef.num_dlights = r_numdlights;
                    502:                cl.refdef.dlights = r_dlights;
                    503:                cl.refdef.lightstyles = r_lightstyles;
1.1.1.2 ! root      504: 
1.1       root      505:                cl.refdef.rdflags = cl.frame.playerstate.rdflags;
1.1.1.2 ! root      506: 
1.1       root      507:                // sort entities for better cache locality
                    508:         qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int (*)(const void *, const void *))entitycmpfnc );
                    509:        }
1.1.1.2 ! root      510: 
1.1       root      511:        re.RenderFrame (&cl.refdef);
                    512:        if (cl_stats->value)
                    513:                Com_Printf ("ent:%i  lt:%i  part:%i\n", r_numentities, r_numdlights, r_numparticles);
                    514:        if ( log_stats->value && ( log_stats_file != 0 ) )
                    515:                fprintf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles);
                    516: 
                    517: 
                    518:        SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y);
                    519:        SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,
                    520:                scr_vrect.y+scr_vrect.height-1);
                    521: 
                    522:        SCR_DrawCrosshair ();
                    523: }
                    524: 
1.1.1.2 ! root      525: 
1.1       root      526: /*
                    527: =============
                    528: V_Viewpos_f
                    529: =============
                    530: */
                    531: void V_Viewpos_f (void)
                    532: {
                    533:        Com_Printf ("(%i %i %i) : %i\n", (int)cl.refdef.vieworg[0],
                    534:                (int)cl.refdef.vieworg[1], (int)cl.refdef.vieworg[2], 
                    535:                (int)cl.refdef.viewangles[YAW]);
                    536: }
1.1.1.2 ! root      537: 
1.1       root      538: /*
                    539: =============
                    540: V_Init
                    541: =============
                    542: */
                    543: void V_Init (void)
                    544: {
                    545:        Cmd_AddCommand ("gun_next", V_Gun_Next_f);
                    546:        Cmd_AddCommand ("gun_prev", V_Gun_Prev_f);
                    547:        Cmd_AddCommand ("gun_model", V_Gun_Model_f);
                    548: 
                    549:        Cmd_AddCommand ("viewpos", V_Viewpos_f);
1.1.1.2 ! root      550: 
1.1       root      551:        crosshair = Cvar_Get ("crosshair", "0", CVAR_ARCHIVE);
1.1.1.2 ! root      552: 
1.1       root      553:        cl_testblend = Cvar_Get ("cl_testblend", "0", 0);
                    554:        cl_testparticles = Cvar_Get ("cl_testparticles", "0", 0);
                    555:        cl_testentities = Cvar_Get ("cl_testentities", "0", 0);
                    556:        cl_testlights = Cvar_Get ("cl_testlights", "0", 0);
                    557: 
                    558:        cl_stats = Cvar_Get ("cl_stats", "0", 0);
                    559: }

unix.superglobalmegacorp.com

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