📄 r_things.c
字号:
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 + -