⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_things.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
        ds->prev = ds-1;    }    //vissprites[0].prev = &unsorted;    //unsorted.next = &vissprites[0];    //(vissprite_p-1)->next = &unsorted;    //unsorted.prev = vissprite_p-1;    vs_start->prev = &unsorted;    unsorted.next = vs_start;    (vs_end - 1)->next = &unsorted;    unsorted.prev = vs_end - 1;    // pull the vissprites out by scale    vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;    for (i=0 ; i<count ; i++)    {        bestscale = MAXINT;        for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next)        {            if (ds->scale < bestscale)            {                bestscale = ds->scale;                best = ds;            }        }        best->next->prev = best->prev;        best->prev->next = best->next;        best->next = &vsprsortedhead;        best->prev = vsprsortedhead.prev;        vsprsortedhead.prev->next = best;        vsprsortedhead.prev = best;    }}//// R_CreateDrawNodes// Creates and sorts a list of drawnodes for the scene being rendered.static void           R_CreateDrawNodes();static drawnode_t*    R_CreateDrawNode (drawnode_t* link);static drawnode_t     nodebankhead;static visgroup_t     visgrouphead;static visgroup_t     grouphead;static void R_CreateDrawNodes(){  drawnode_t*   entry;  drawseg_t*    ds;  int           i, p, best, x1, x2;  fixed_t       bestdelta, delta;  vissprite_t*  rover;  drawnode_t*   r2;  visgroup_t*   group;  visplane_t*   plane;  int           sintersect;  fixed_t       gzm;  fixed_t       scale;  for(group = grouphead.prev; group != &grouphead; group = group->prev)  {    ds_start = &drawsegs[group->ds_start];    ds_end = &drawsegs[group->ds_end];    vs_start = &vissprites[group->vs_start];    vs_end = &vissprites[group->vs_end];    // Add the 3D floors, thicksides, and masked textures...    for(ds = ds_end; ds-- > ds_start;)    {      if(ds->numthicksides)      {        for(i = 0; i < ds->numthicksides; i++)        {          entry = R_CreateDrawNode(&group->nodehead);          entry->thickseg = ds;          entry->ffloor = ds->thicksides[i];        }      }      if(ds->maskedtexturecol)      {        entry = R_CreateDrawNode(&group->nodehead);        entry->seg = ds;      }      if(ds->numffloorplanes)      {        for(i = 0; i < ds->numffloorplanes; i++)        {          best = -1;          bestdelta = 0;          for(p = 0; p < ds->numffloorplanes; p++)          {            if(!ds->ffloorplanes[p])              continue;            plane = ds->ffloorplanes[p];            R_PlaneBounds(plane);            if(plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low)            {              ds->ffloorplanes[p] = NULL;              continue;            }            delta = abs(plane->height - viewz);            if(delta > bestdelta)            {              best = p;              bestdelta = delta;            }          }          if(best != -1)          {            entry = R_CreateDrawNode(&group->nodehead);            entry->plane = ds->ffloorplanes[best];            entry->seg = ds;            ds->ffloorplanes[best] = NULL;          }          else            break;        }      }    }    if(vs_end == vs_start)      continue;    R_SortVisSprites();    for(rover = vsprsortedhead.prev; rover != &vsprsortedhead; rover = rover->prev)    {      if(rover->szt > vid.height || rover->sz < 0)        continue;      sintersect = (rover->x1 + rover->x2) / 2;      gzm = (rover->gz + rover->gzt) / 2;      for(r2 = group->nodehead.next; r2 != &group->nodehead; r2 = r2->next)      {        if(r2->plane)        {          if(r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1)            continue;          if(rover->szt > r2->plane->low || rover->sz < r2->plane->high)            continue;          if((r2->plane->height < viewz && gzm < r2->plane->height) ||            (r2->plane->height > viewz && gzm > r2->plane->height))          {            // SoM: NOTE: Because a visplane's shape and scale is not directly            // bound to any single lindef, a simple poll of it's frontscale is            // not adiquate. We must check the entire frontscale array for any            // part that is in of the sprite.            x1 = rover->x1;            x2 = rover->x2;            if(x1 < r2->plane->minx) x1 = r2->plane->minx;            if(x2 > r2->plane->maxx) x2 = r2->plane->maxx;            for(i = x1; i <= x2; i++)            {              if(r2->plane->frontscale[i] > rover->scale)                break;            }            if(i > x2)              continue;            entry = R_CreateDrawNode(NULL);            (entry->prev = r2->prev)->next = entry;            (entry->next = r2)->prev = entry;            entry->sprite = rover;            break;          }        }        else if(r2->thickseg)        {          if(rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1)            continue;          scale = r2->thickseg->scale1 > r2->thickseg->scale2 ? r2->thickseg->scale1 : r2->thickseg->scale2;          if(scale <= rover->scale)            continue;          scale = r2->thickseg->scale1 + (r2->thickseg->scalestep * (sintersect - r2->thickseg->x1));          if(scale <= rover->scale)            continue;          if(scale > rover->scale &&            ((*r2->ffloor->topheight > viewz && *r2->ffloor->bottomheight < viewz) ||            (*r2->ffloor->topheight < viewz && rover->gzt < *r2->ffloor->topheight) ||            (*r2->ffloor->bottomheight > viewz && rover->gz > *r2->ffloor->bottomheight)))          {            entry = R_CreateDrawNode(NULL);            (entry->prev = r2->prev)->next = entry;            (entry->next = r2)->prev = entry;            entry->sprite = rover;            break;          }        }        else if(r2->seg)        {          if(rover->x1 > r2->seg->x2 || rover->x2 < r2->seg->x1)            continue;          scale = r2->seg->scale1 + (r2->seg->scalestep * (sintersect - r2->seg->x1));          if(rover->scale < scale)          {            entry = R_CreateDrawNode(NULL);            (entry->prev = r2->prev)->next = entry;            (entry->next = r2)->prev = entry;            entry->sprite = rover;            break;          }        }        else if(r2->sprite)        {          if(r2->sprite->x1 > rover->x2 || r2->sprite->x2 < rover->x1)            continue;          if(r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt)            continue;          if(r2->sprite->scale > rover->scale)          {            entry = R_CreateDrawNode(NULL);            (entry->prev = r2->prev)->next = entry;            (entry->next = r2)->prev = entry;            entry->sprite = rover;            break;          }        }      }      if(r2 == &group->nodehead)      {        entry = R_CreateDrawNode(&group->nodehead);        entry->sprite = rover;      }    }  }}//// R_CreateDrawGroup//// Acts basically as a marker. Basically creates a new group drawnode// and sets the drawseg and vissprite markers accordingly.// NOTE: Must not call after R_CreateDrawNodes is called...void R_CreateDrawGroup(lvlportal_t* lvl){  visgroup_t*  group;  group = visgrouphead.next;  if(group == &visgrouphead)    group = (visgroup_t *)malloc(sizeof(visgroup_t));  else    (group->next->prev = group->prev)->next = group->next;  (group->prev = grouphead.prev)->next = group;  (group->next = &grouphead)->prev = group;  group->nodehead.next = group->nodehead.prev = &group->nodehead;  group->lvl = lvl;  if(group->prev == &grouphead)  {    group->ds_start = 0;    group->ds_end = ds_p - drawsegs;    group->vs_start = 0;    group->vs_end = vissprite_p - vissprites;  }  else  {    group->ds_start = group->prev->ds_end;    group->ds_end = ds_p - drawsegs;    group->vs_start = group->prev->vs_end;    group->vs_end = vissprite_p - vissprites;  }}static drawnode_t* R_CreateDrawNode (drawnode_t* link){  drawnode_t* node;  node = nodebankhead.next;  if(node == &nodebankhead)  {    node = malloc(sizeof(drawnode_t));  }  else    (nodebankhead.next = node->next)->prev = &nodebankhead;  if(link)  {    node->next = link;    node->prev = link->prev;    link->prev->next = node;    link->prev = node;  }  node->plane = NULL;  node->seg = NULL;  node->thickseg = NULL;  node->ffloor = NULL;  node->sprite = NULL;  return node;}static void R_DoneWithNode(drawnode_t* node){  (node->next->prev = node->prev)->next = node->next;  (node->next = nodebankhead.next)->prev = node;  (node->prev = &nodebankhead)->next = node;}static void R_ClearDrawNodes(){  drawnode_t* rover;  drawnode_t* next;  visgroup_t* group;  visgroup_t* nextgroup;  for(group = grouphead.next; group != &grouphead; )  {    nextgroup = group->next;    for(rover = group->nodehead.next; rover != &group->nodehead; )    {      next = rover->next;      R_DoneWithNode(rover);      rover = next;    }    (group->prev = visgrouphead.prev)->next = group;    (group->next = &visgrouphead)->prev = group;    group = nextgroup;  }  grouphead.next = grouphead.prev = &grouphead;}void R_InitDrawNodes(){  nodebankhead.next = nodebankhead.prev = &nodebankhead;  visgrouphead.next = visgrouphead.prev = &visgrouphead;  grouphead.next = grouphead.prev = &grouphead;}//// R_DrawSprite////Fab:26-04-98:// NOTE : uses con_clipviewtop, so that when console is on,//        don't draw the part of sprites hidden under the consolevoid R_DrawSprite (vissprite_t* spr){    drawseg_t*          ds;    short               clipbot[MAXVIDWIDTH];    short               cliptop[MAXVIDWIDTH];    int                 x;    int                 r1;    int                 r2;    fixed_t             scale;    fixed_t             lowscale;    int                 silhouette;    for (x = spr->x1 ; x<=spr->x2 ; x++)        clipbot[x] = cliptop[x] = -2;    // Scan drawsegs from end to start for obscuring segs.    // The first drawseg that has a greater scale    //  is the clip seg.    //SoM: 4/8/2000:    // Pointer check was originally nonportable    // and buggy, by going past LEFT end of array:    //    for (ds=ds_p-1 ; ds >= drawsegs ; ds--)    old buggy code    //    for (ds=ds_p ; ds-- > drawsegs ; )    for(ds = ds_end; ds-- > ds_start; )    {        // determine if the drawseg obscures the sprite        if (ds->x1 > spr->x2         || ds->x2 < spr->x1         || (!ds->silhouette             && !ds->maskedtexturecol) )        {            // does not cover sprite            continue;        }        r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;        r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;        if (ds->scale1 > ds->scale2)        {            lowscale = ds->scale2;            scale = ds->scale1;        }        else        {            lowscale = ds->scale1;            scale = ds->scale2;        }        if (scale < spr->scale            || ( lowscale < spr->scale                 && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) )        {            // masked mid texture?            /*if (ds->maskedtexturecol)                R_RenderMaskedSegRange (ds, r1, r2);*/            // seg is behind sprite            continue;        }        // clip this piece of the sprite        silhouette = ds->silhouette;        if (spr->gz >= ds->bsilheight)            silhouette &= ~SIL_BOTTOM;        if (spr->gzt <= ds->tsilheight)            silhouette &= ~SIL_TOP;        if (silhouette == 1)        {            // bottom sil            for (x=r1 ; x<=r2 ; x++)                if (clipbot[x] == -2)                    clipbot[x] = ds->sprbottomclip[x];        }        else if (silhouette == 2)        {            // top sil            for (x=r1 ; x<=r2 ; x++)                if (cliptop[x] == -2)                    cliptop[x] = ds->sprtopclip[x];        }        else if (silhouette == 3)        {            // both            for (x=r1 ; x<=r2 ; x++)            {                if (clipbot[x] == -2)                    clipbot[x] = ds->sprbottomclip[x];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -