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

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.3 ! root      272:                if (name[0] == '#')
        !           273:                {
1.1.1.2   root      274:                        // special player weapon model
1.1.1.3 ! root      275:                        if (num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS)
        !           276:                        {
1.1.1.2   root      277:                                strncpy(cl_weaponmodels[num_cl_weaponmodels], cl.configstrings[CS_MODELS+i]+1,
                    278:                                        sizeof(cl_weaponmodels[num_cl_weaponmodels]) - 1);
                    279:                                num_cl_weaponmodels++;
                    280:                        }
1.1.1.3 ! root      281:                } 
        !           282:                else
        !           283:                {
1.1.1.2   root      284:                        cl.model_draw[i] = re.RegisterModel (cl.configstrings[CS_MODELS+i]);
                    285:                        if (name[0] == '*')
                    286:                                cl.model_clip[i] = CM_InlineModel (cl.configstrings[CS_MODELS+i]);
                    287:                        else
                    288:                                cl.model_clip[i] = NULL;
                    289:                }
1.1       root      290:                if (name[0] != '*')
                    291:                        Com_Printf ("                                     \r");
                    292:        }
1.1.1.3 ! root      293: 
1.1       root      294:        Com_Printf ("images\r", i); 
                    295:        SCR_UpdateScreen ();
                    296:        for (i=1 ; i<MAX_IMAGES && cl.configstrings[CS_IMAGES+i][0] ; i++)
                    297:        {
                    298:                cl.image_precache[i] = re.RegisterPic (cl.configstrings[CS_IMAGES+i]);
                    299:                Sys_SendKeyEvents ();   // pump message loop
                    300:        }
1.1.1.3 ! root      301:        
1.1       root      302:        Com_Printf ("                                     \r");
                    303:        for (i=0 ; i<MAX_CLIENTS ; i++)
                    304:        {
                    305:                if (!cl.configstrings[CS_PLAYERSKINS+i][0])
                    306:                        continue;
                    307:                Com_Printf ("client %i\r", i); 
                    308:                SCR_UpdateScreen ();
                    309:                Sys_SendKeyEvents ();   // pump message loop
                    310:                CL_ParseClientinfo (i);
                    311:                Com_Printf ("                                     \r");
                    312:        }
1.1.1.2   root      313: 
1.1       root      314:        CL_LoadClientinfo (&cl.baseclientinfo, "unnamed\\male/grunt");
1.1.1.2   root      315: 
1.1       root      316:        // set sky textures and speed
                    317:        Com_Printf ("sky\r", i); 
                    318:        SCR_UpdateScreen ();
                    319:        rotate = atof (cl.configstrings[CS_SKYROTATE]);
                    320:        sscanf (cl.configstrings[CS_SKYAXIS], "%f %f %f", 
                    321:                &axis[0], &axis[1], &axis[2]);
                    322:        re.SetSky (cl.configstrings[CS_SKY], rotate, axis);
                    323:        Com_Printf ("                                     \r");
1.1.1.2   root      324: 
1.1       root      325:        // the renderer can now free unneeded stuff
                    326:        re.EndRegistration ();
1.1.1.2   root      327: 
1.1       root      328:        // clear any lines of console text
                    329:        Con_ClearNotify ();
1.1.1.2   root      330: 
1.1       root      331:        SCR_UpdateScreen ();
                    332:        cl.refresh_prepped = true;
                    333:        cl.force_refdef = true; // make sure we have a valid refdef
                    334: 
                    335:        // start the cd track
                    336:        CDAudio_Play (atoi(cl.configstrings[CS_CDTRACK]), true);
                    337: }
1.1.1.2   root      338: 
1.1       root      339: /*
                    340: ====================
                    341: CalcFov
                    342: ====================
                    343: */
                    344: float CalcFov (float fov_x, float width, float height)
                    345: {
                    346:        float   a;
                    347:        float   x;
1.1.1.2   root      348: 
1.1       root      349:        if (fov_x < 1 || fov_x > 179)
                    350:                Com_Error (ERR_DROP, "Bad fov: %f", fov_x);
1.1.1.2   root      351: 
1.1       root      352:        x = width/tan(fov_x/360*M_PI);
1.1.1.2   root      353: 
1.1       root      354:        a = atan (height/x);
1.1.1.2   root      355: 
1.1       root      356:        a = a*360/M_PI;
1.1.1.2   root      357: 
1.1       root      358:        return a;
                    359: }
1.1.1.2   root      360: 
1.1       root      361: //============================================================================
1.1.1.2   root      362: 
1.1       root      363: // gun frame debugging functions
                    364: void V_Gun_Next_f (void)
                    365: {
                    366:        gun_frame++;
                    367:        Com_Printf ("frame %i\n", gun_frame);
                    368: }
1.1.1.2   root      369: 
1.1       root      370: void V_Gun_Prev_f (void)
                    371: {
                    372:        gun_frame--;
                    373:        if (gun_frame < 0)
                    374:                gun_frame = 0;
                    375:        Com_Printf ("frame %i\n", gun_frame);
                    376: }
1.1.1.2   root      377: 
1.1       root      378: void V_Gun_Model_f (void)
                    379: {
                    380:        char    name[MAX_QPATH];
1.1.1.2   root      381: 
1.1       root      382:        if (Cmd_Argc() != 2)
                    383:        {
                    384:                gun_model = NULL;
                    385:                return;
                    386:        }
                    387:        Com_sprintf (name, sizeof(name), "models/%s/tris.md2", Cmd_Argv(1));
                    388:        gun_model = re.RegisterModel (name);
                    389: }
1.1.1.2   root      390: 
1.1       root      391: //============================================================================
                    392: 
1.1.1.2   root      393: 
1.1       root      394: /*
                    395: =================
                    396: SCR_DrawCrosshair
                    397: =================
                    398: */
                    399: void SCR_DrawCrosshair (void)
                    400: {
                    401:        if (!crosshair->value)
                    402:                return;
                    403: 
                    404:        if (crosshair->modified)
                    405:        {
                    406:                crosshair->modified = false;
                    407:                SCR_TouchPics ();
                    408:        }
                    409: 
                    410:        if (!crosshair_pic[0])
                    411:                return;
                    412: 
                    413:        re.DrawPic (scr_vrect.x + ((scr_vrect.width - crosshair_width)>>1)
                    414:        , scr_vrect.y + ((scr_vrect.height - crosshair_height)>>1), crosshair_pic);
                    415: }
1.1.1.2   root      416: 
1.1       root      417: /*
                    418: ==================
                    419: V_RenderView
1.1.1.2   root      420: 
1.1       root      421: ==================
                    422: */
                    423: void V_RenderView( float stereo_separation )
                    424: {
                    425:        extern int entitycmpfnc( const entity_t *, const entity_t * );
                    426: 
                    427:        if (cls.state != ca_active)
                    428:                return;
1.1.1.2   root      429: 
1.1       root      430:        if (!cl.refresh_prepped)
                    431:                return;                 // still loading
                    432: 
                    433:        if (cl_timedemo->value)
                    434:        {
                    435:                if (!cl.timedemo_start)
                    436:                        cl.timedemo_start = Sys_Milliseconds ();
                    437:                cl.timedemo_frames++;
                    438:        }
                    439: 
                    440:        // an invalid frame will just use the exact previous refdef
                    441:        // we can't use the old frame if the video mode has changed, though...
                    442:        if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) )
                    443:        {
                    444:                cl.force_refdef = false;
1.1.1.2   root      445: 
1.1       root      446:                V_ClearScene ();
                    447: 
                    448:                // build a refresh entity list and calc cl.sim*
                    449:                // this also calls CL_CalcViewValues which loads
                    450:                // v_forward, etc.
                    451:                CL_AddEntities ();
1.1.1.2   root      452: 
1.1       root      453:                if (cl_testparticles->value)
                    454:                        V_TestParticles ();
                    455:                if (cl_testentities->value)
                    456:                        V_TestEntities ();
                    457:                if (cl_testlights->value)
                    458:                        V_TestLights ();
                    459:                if (cl_testblend->value)
                    460:                {
                    461:                        cl.refdef.blend[0] = 1;
                    462:                        cl.refdef.blend[1] = 0.5;
                    463:                        cl.refdef.blend[2] = 0.25;
                    464:                        cl.refdef.blend[3] = 0.5;
                    465:                }
1.1.1.2   root      466: 
1.1       root      467:                // offset vieworg appropriately if we're doing stereo separation
                    468:                if ( stereo_separation != 0 )
                    469:                {
                    470:                        vec3_t tmp;
                    471: 
                    472:                        VectorScale( cl.v_right, stereo_separation, tmp );
                    473:                        VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg );
                    474:                }
1.1.1.2   root      475: 
1.1       root      476:                // never let it sit exactly on a node line, because a water plane can
                    477:                // dissapear when viewed with the eye exactly on it.
                    478:                // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis
                    479:                cl.refdef.vieworg[0] += 1.0/16;
                    480:                cl.refdef.vieworg[1] += 1.0/16;
                    481:                cl.refdef.vieworg[2] += 1.0/16;
                    482: 
                    483:                cl.refdef.x = scr_vrect.x;
                    484:                cl.refdef.y = scr_vrect.y;
                    485:                cl.refdef.width = scr_vrect.width;
                    486:                cl.refdef.height = scr_vrect.height;
                    487:                cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height);
                    488:                cl.refdef.time = cl.time*0.001;
1.1.1.2   root      489: 
1.1       root      490:                cl.refdef.areabits = cl.frame.areabits;
                    491: 
                    492:                if (!cl_add_entities->value)
                    493:                        r_numentities = 0;
                    494:                if (!cl_add_particles->value)
                    495:                        r_numparticles = 0;
                    496:                if (!cl_add_lights->value)
                    497:                        r_numdlights = 0;
                    498:                if (!cl_add_blend->value)
                    499:                {
                    500:                        VectorClear (cl.refdef.blend);
                    501:                }
1.1.1.2   root      502: 
1.1       root      503:                cl.refdef.num_entities = r_numentities;
                    504:                cl.refdef.entities = r_entities;
                    505:                cl.refdef.num_particles = r_numparticles;
                    506:                cl.refdef.particles = r_particles;
                    507:                cl.refdef.num_dlights = r_numdlights;
                    508:                cl.refdef.dlights = r_dlights;
                    509:                cl.refdef.lightstyles = r_lightstyles;
1.1.1.2   root      510: 
1.1       root      511:                cl.refdef.rdflags = cl.frame.playerstate.rdflags;
1.1.1.2   root      512: 
1.1       root      513:                // sort entities for better cache locality
                    514:         qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int (*)(const void *, const void *))entitycmpfnc );
                    515:        }
1.1.1.2   root      516: 
1.1       root      517:        re.RenderFrame (&cl.refdef);
                    518:        if (cl_stats->value)
                    519:                Com_Printf ("ent:%i  lt:%i  part:%i\n", r_numentities, r_numdlights, r_numparticles);
                    520:        if ( log_stats->value && ( log_stats_file != 0 ) )
                    521:                fprintf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles);
                    522: 
                    523: 
                    524:        SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y);
                    525:        SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,
                    526:                scr_vrect.y+scr_vrect.height-1);
                    527: 
                    528:        SCR_DrawCrosshair ();
                    529: }
                    530: 
1.1.1.2   root      531: 
1.1       root      532: /*
                    533: =============
                    534: V_Viewpos_f
                    535: =============
                    536: */
                    537: void V_Viewpos_f (void)
                    538: {
                    539:        Com_Printf ("(%i %i %i) : %i\n", (int)cl.refdef.vieworg[0],
                    540:                (int)cl.refdef.vieworg[1], (int)cl.refdef.vieworg[2], 
                    541:                (int)cl.refdef.viewangles[YAW]);
                    542: }
1.1.1.2   root      543: 
1.1       root      544: /*
                    545: =============
                    546: V_Init
                    547: =============
                    548: */
                    549: void V_Init (void)
                    550: {
                    551:        Cmd_AddCommand ("gun_next", V_Gun_Next_f);
                    552:        Cmd_AddCommand ("gun_prev", V_Gun_Prev_f);
                    553:        Cmd_AddCommand ("gun_model", V_Gun_Model_f);
                    554: 
                    555:        Cmd_AddCommand ("viewpos", V_Viewpos_f);
1.1.1.2   root      556: 
1.1       root      557:        crosshair = Cvar_Get ("crosshair", "0", CVAR_ARCHIVE);
1.1.1.2   root      558: 
1.1       root      559:        cl_testblend = Cvar_Get ("cl_testblend", "0", 0);
                    560:        cl_testparticles = Cvar_Get ("cl_testparticles", "0", 0);
                    561:        cl_testentities = Cvar_Get ("cl_testentities", "0", 0);
                    562:        cl_testlights = Cvar_Get ("cl_testlights", "0", 0);
                    563: 
                    564:        cl_stats = Cvar_Get ("cl_stats", "0", 0);
                    565: }

unix.superglobalmegacorp.com

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