📄 hw_trick.c
字号:
// Free Stacklists of all sectors//static void freeStacklists(void){ int i; for(i=0; i<numsectors; i++) { if(sectors[i].stackList) { free(sectors[i].stackList); sectors[i].stackList = NULL; } }}//// if more than half of the toptextures are missing//static boolean areToptexturesMissing(sector_t *thisSector){ linechain_t *thisElem, *nextElem; sector_t *frontSector, *backSector; int nomiss; side_t *sdl, *sdr; thisElem = NULL; nextElem = thisSector->sectorLines; nomiss = 0; while(NULL != nextElem) // walk through chain { thisElem = nextElem; nextElem = thisElem->next; frontSector = thisElem->line->frontsector; backSector = thisElem->line->backsector; if(frontSector == backSector) // skip damn renderer tricks here { continue; } if(frontSector == NULL || backSector == NULL) { continue; } sdr = &sides[thisElem->line->sidenum[0]]; sdl = &sides[thisElem->line->sidenum[1]]; if(backSector->ceilingheight < frontSector->ceilingheight) { if(sdr->toptexture != 0) { nomiss++; break; // we can stop here if decision criterium is ==0 } } else if(backSector->ceilingheight > frontSector->ceilingheight) { if(sdl->toptexture != 0) { nomiss++; break; // we can stop here if decision criterium is ==0 } } } return nomiss == 0;}//// are more textures missing than present?//static boolean areBottomtexturesMissing(sector_t *thisSector){ linechain_t *thisElem, *nextElem; sector_t *frontSector, *backSector; int nomiss; side_t *sdl, *sdr; thisElem = NULL; nextElem = thisSector->sectorLines; nomiss = 0; while(NULL != nextElem) // walk through chain { thisElem = nextElem; nextElem = thisElem->next; frontSector = thisElem->line->frontsector; backSector = thisElem->line->backsector; if(frontSector == backSector) // skip damn renderer tricks here { continue; } if(frontSector == NULL || backSector == NULL) { continue; } sdr = &sides[thisElem->line->sidenum[0]]; sdl = &sides[thisElem->line->sidenum[1]]; if(backSector->floorheight > frontSector->floorheight) { if(sdr->bottomtexture != 0) { nomiss++; break; // we can stop here if decision criterium is ==0 } } else if(backSector->floorheight < frontSector->floorheight) { if(sdl->bottomtexture != 0) { nomiss++; break; // we can stop here if decision criterium is ==0 } } } // return missing >= nomiss; return nomiss == 0;}//// check if no adjacent sector has same ceiling height//static boolean isCeilingFloating(sector_t *thisSector){ sector_t *adjSector, *refSector, *frontSector, *backSector; boolean floating = true; linechain_t *thisElem, *nextElem; if(NULL == thisSector) return false; refSector = NULL; thisElem = NULL; nextElem = thisSector->sectorLines; while(NULL != nextElem) // walk through chain { thisElem = nextElem; nextElem = thisElem->next; frontSector = thisElem->line->frontsector; backSector = thisElem->line->backsector; if(frontSector == thisSector) adjSector = backSector; else adjSector = frontSector; if(NULL == adjSector) // assume floating sectors have surrounding sectors { floating = false; break; } if(NULL == refSector) { refSector = adjSector; continue; } // if adjacent sector has same height or more than one adjacent sector exists -> stop if(thisSector->ceilingheight == adjSector->ceilingheight || refSector != adjSector) { floating = false; break; } } // now check for walltextures if(floating) { if(!areToptexturesMissing(thisSector)) { floating = false; } } return floating;}//// check if no adjacent sector has same ceiling height// FIXME: throw that together with isCeilingFloating??//static boolean isFloorFloating(sector_t *thisSector){ sector_t *adjSector, *refSector, *frontSector, *backSector; boolean floating = true; linechain_t *thisElem, *nextElem; if(NULL == thisSector) return false; refSector = NULL; thisElem = NULL; nextElem = thisSector->sectorLines; while(NULL != nextElem) // walk through chain { thisElem = nextElem; nextElem = thisElem->next; frontSector = thisElem->line->frontsector; backSector = thisElem->line->backsector; if(frontSector == thisSector) adjSector = backSector; else adjSector = frontSector; if(NULL == adjSector) // assume floating sectors have surrounding sectors { floating = false; break; } if(NULL == refSector) { refSector = adjSector; continue; } // if adjacent sector has same height or more than one adjacent sector exists -> stop if(thisSector->floorheight == adjSector->floorheight || refSector != adjSector) { floating = false; break; } } // now check for walltextures if(floating) { if(!areBottomtexturesMissing(thisSector)) { floating = false; } } return floating;}//// estimate ceilingheight according to height of adjacent sector//static fixed_t estimateCeilHeight(sector_t *thisSector){ sector_t *adjSector; if(NULL == thisSector || NULL == thisSector->sectorLines || NULL == thisSector->sectorLines->line) return 0; adjSector = thisSector->sectorLines->line->frontsector; if(adjSector == thisSector) adjSector = thisSector->sectorLines->line->backsector; if(NULL == adjSector) return 0; return adjSector->ceilingheight;}//// estimate ceilingheight according to height of adjacent sector//static fixed_t estimateFloorHeight(sector_t *thisSector){ sector_t *adjSector; if(NULL == thisSector || NULL == thisSector->sectorLines || NULL == thisSector->sectorLines->line) return 0; adjSector = thisSector->sectorLines->line->frontsector; if(adjSector == thisSector) adjSector = thisSector->sectorLines->line->backsector; if(NULL == adjSector) return 0; return adjSector->floorheight;}#define CORRECT_FLOAT_EXPERIMENTALextern boolean raven; // true with heretic and hexen// --------------------------------------------------------------------------// Some levels have missing sidedefs, which produces HOM, so let硈 try to compensate for that// and some levels have deep water trick, invisible staircases etc.// --------------------------------------------------------------------------// FIXME: put some nice default texture in doom3.wad and use itvoid HWR_CorrectSWTricks(void){ int i, k; line_t *ld; side_t *sdl, *sdr; sector_t *secl, *secr; sector_t **sectorList; sector_t *outSector; if ( (0 == cv_grcorrecttricks.value) || raven ) return; // determine lines for sectors for(i=0; i<numlines; i++) { ld = &lines[i]; secr = ld->frontsector; secl = ld->backsector; if(secr == secl) { secr->pseudoSector = true; // special renderer trick? addLineToChain(secr, ld); } else { addLineToChain(secr, ld); addLineToChain(secl, ld); } } // preprocessing for(i=0; i<numsectors; i++) { sector_t *checkSector; checkSector = §ors[i]; // identify real pseudosectors first if(checkSector->pseudoSector) { if(!isPSectorValid(checkSector)) // drop invalid pseudo sectors { checkSector->pseudoSector = false; } } // determine enclosing sectors for pseudosectors ... used later if(checkSector->pseudoSector) { generateStacklist(checkSector); calcLineouts(checkSector); sortStacklist(checkSector); } } // set virtual floor heights for pseudo sectors for(i=0; i<numsectors; i++) { if(sectors[i].pseudoSector) { sectorList = sectors[i].stackList; k = 0; while(*(sectorList+k)) { outSector = *(sectorList+k); if(!outSector->pseudoSector) { sectors[i].virtualFloorheight = outSector->floorheight; sectors[i].virtualCeilingheight = outSector->ceilingheight; break; } k++; } if(*(sectorList+k) == NULL) // sorry, did not work :( { sectors[i].virtualFloorheight = sectors[i].floorheight; sectors[i].virtualCeilingheight = sectors[i].ceilingheight; } } }#ifdef CORRECT_FLOAT_EXPERIMENTAL // correct ceiling/floor heights of totally floating sectors for(i=0; i<numsectors; i++) { sector_t *floatSector; floatSector = §ors[i]; // correct height of floating sectors // FIXME: it should be more like with real pseudosectors: // inherit properties of surrounding sectors (height, light, ...) but only virtual!! if(isCeilingFloating(floatSector)) { fixed_t corrheight; corrheight = estimateCeilHeight(floatSector); floatSector->virtualCeilingheight = corrheight; floatSector->virtualFloorheight = floatSector->floorheight; floatSector->pseudoSector = true; // use virtual heights } if(isFloorFloating(floatSector)) { fixed_t corrheight; corrheight = estimateFloorHeight(floatSector); if(floatSector->virtualFloorheight == floatSector->floorheight) { floatSector->virtualFloorheight = corrheight; floatSector->pseudoSector = true; // use virtual heights } else { floatSector->virtualFloorheight = corrheight; floatSector->virtualCeilingheight = floatSector->ceilingheight; floatSector->pseudoSector = true; // use virtual heights } } }#endif // now for the missing textures for(i=0; i<numlines; i++) { ld = &lines[i]; sdr = &sides[ld->sidenum[0]]; if(ld->sidenum[1] >= 0) { sdl = &sides[ld->sidenum[1]]; } secr = ld->frontsector; secl = ld->backsector; if(secr == secl) // special renderer trick continue; // we can硉 correct missing textures here if(NULL != secl) // only if there is a backsector { if(secr->pseudoSector || secl->pseudoSector) continue; if(secl->floorheight > secr->floorheight) { // now check if r-sidedef is correct if(sdr->bottomtexture == 0) { if(sdr->midtexture == 0) sdr->bottomtexture = R_TextureNumForName("STONE2"); else sdr->bottomtexture = sdr->midtexture; } } else if(secl->floorheight < secr->floorheight) { // now check if l-sidedef is correct if(sdl->bottomtexture == 0) { if(sdl->midtexture == 0) sdl->bottomtexture = R_TextureNumForName("STONE2"); else sdl->bottomtexture = sdl->midtexture; } } if(secl->ceilingheight < secr->ceilingheight) { // now check if r-sidedef is correct if(sdr->toptexture == 0) { if(sdr->midtexture == 0) sdr->toptexture = R_TextureNumForName("STONE2"); else sdr->toptexture = sdr->midtexture; } } else if(secl->ceilingheight > secr->ceilingheight) { // now check if l-sidedef is correct if(sdl->toptexture == 0) { if(sdl->midtexture == 0) sdl->toptexture = R_TextureNumForName("STONE2"); else sdl->toptexture = sdl->midtexture; } } } // if(NULL != secl) } // for(i=0; i<numlines; i++) // release all linechains releaseLineChains(); freeStacklists();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -