diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index c8e7da63f..0a06b46b4 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -10468,17 +10468,40 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, in { sectortype *sec; walltype *wal, *wal2; - int32_t i, cnt, nexts, x, y, z, cz, fz, dasectnum, dacnt, danum; + int32_t cnt, nexts, x, y, z, cfz[2], dasectnum, dacnt, danum; int32_t x21, y21, z21, x31, y31, x34, y34, bot, t; + static uint8_t sectbitmap[MAXSECTORS>>3]; +#ifdef YAX_ENABLE + int16_t pendingsectnum; + vec3_t pendingvec; + + int32_t cfz1[2], cfz2[2]; // both wrt dasectnum + int16_t bn[2]; +#endif + + Bmemset(&pendingvec, 0, sizeof(vec3_t)); // compiler-happy + Bmemset(sectbitmap, 0, (numsectors+7)>>3); + +#ifdef YAX_ENABLE +restart_grand: +#endif if ((x1 == x2) && (y1 == y2)) return(sect1 == sect2); + pendingsectnum = -1; x21 = x2-x1; y21 = y2-y1; z21 = z2-z1; + sectbitmap[sect1>>3] |= (1<<(sect1&7)); clipsectorlist[0] = sect1; danum = 1; + for (dacnt=0; dacntwallnum,wal=&wall[sec->wallptr]; cnt>0; cnt--,wal++) { wal2 = &wall[wal->point2]; @@ -10487,26 +10510,124 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, in bot = y21*x34-x21*y34; if (bot <= 0) continue; t = y21*x31-x21*y31; if ((unsigned)t >= (unsigned)bot) continue; - t = y31*x34-x31*y34; if ((unsigned)t >= (unsigned)bot) continue; + t = y31*x34-x31*y34; + if ((unsigned)t >= (unsigned)bot) + { + if (t >= bot) + { +#ifdef YAX_ENABLE + int32_t cf, frac, ns; + for (cf=0; cf<2; cf++) + { + if ((cf==0 && bn[0]>=0 && z1 > cfz1[0] && cfz2[0] > z2) || + (cf==1 && bn[1]>=0 && z1 < cfz1[1] && cfz2[1] < z2)) + { + if ((cfz1[cf]-cfz2[cf])-(z1-z2)==0) + continue; + frac = divscale24(z1-cfz1[cf], (z1-z2)-(cfz1[cf]-cfz2[cf])); + + if ((unsigned)frac >= (1<<24)) + continue; + + x = x1 + mulscale24(x21,frac); + y = y1 + mulscale24(y21,frac); + + ns = yax_getneighborsect(x, y, dasectnum, cf, NULL); + if (ns < 0) + continue; + + if (!(sectbitmap[ns>>3] & (1<<(ns&7))) && pendingsectnum==-1) + { + sectbitmap[ns>>3] |= (1<<(ns&7)); + pendingsectnum = ns; + pendingvec.x = x; + pendingvec.y = y; + pendingvec.z = z1 + mulscale24(z21,frac); + } + } + } + } +#endif + continue; + } nexts = wal->nextsector; - if ((nexts < 0) || (wal->cstat&32)) return(0); + +#ifdef YAX_ENABLE + if (bn[0]<0 && bn[1]<0) +#endif + if ((nexts < 0) || (wal->cstat&32)) + return(0); t = divscale24(t,bot); x = x1 + mulscale24(x21,t); y = y1 + mulscale24(y21,t); z = z1 + mulscale24(z21,t); - getzsofslope((int16_t)dasectnum,x,y,&cz,&fz); - if ((z <= cz) || (z >= fz)) return(0); - getzsofslope((int16_t)nexts,x,y,&cz,&fz); - if ((z <= cz) || (z >= fz)) return(0); + getzsofslope((int16_t)dasectnum, x,y, &cfz[0],&cfz[1]); - for (i=danum-1; i>=0; i--) if (clipsectorlist[i] == nexts) break; - if (i < 0) clipsectorlist[danum++] = nexts; + if ((z <= cfz[0]) || (z >= cfz[1])) + { +#ifdef YAX_ENABLE + int32_t cf, frac; + + // XXX: Is this any good? + for (cf=0; cf<2; cf++) + if ((cf==0 && bn[0]>=0 && z <= cfz[0] && z1 >= cfz1[0]) || + (cf==1 && bn[1]>=0 && z >= cfz[1] && z1 <= cfz1[1])) + { + if ((cfz1[cf]-cfz[cf])-(z1-z)==0) + continue; + + frac = divscale24(z1-cfz1[cf], (z1-z)-(cfz1[cf]-cfz[cf])); + t = mulscale24(t, frac); + + if ((unsigned)t < (1<<24)) + { + x = x1 + mulscale24(x21,t); + y = y1 + mulscale24(y21,t); + + nexts = yax_getneighborsect(x, y, dasectnum, cf, NULL); + if (nexts >= 0) + goto add_nextsector; + } + } + +#endif + return(0); + } + +#ifdef YAX_ENABLE + if ((nexts < 0) || (wal->cstat&32)) + return 0; +#endif + getzsofslope((int16_t)nexts,x,y,&cfz[0],&cfz[1]); + if ((z <= cfz[0]) || (z >= cfz[1])) + return(0); + +add_nextsector: + if (!(sectbitmap[nexts>>3] & (1<<(nexts&7)))) + { + sectbitmap[nexts>>3] |= (1<<(nexts&7)); + clipsectorlist[danum++] = nexts; + } } + +#ifdef YAX_ENABLE + if (pendingsectnum>=0) + { + sect1 = pendingsectnum; + x1 = pendingvec.x; + y1 = pendingvec.y; + z1 = pendingvec.z; + goto restart_grand; + } +#endif } - for (i=danum-1; i>=0; i--) if (clipsectorlist[i] == sect2) return(1); + + if ((sectbitmap[sect2>>3] & (1<<(sect2&7)))) + return 1; + return(0); } diff --git a/polymer/eduke32/source/actors.c b/polymer/eduke32/source/actors.c index 5dd2dfcf8..15c6c15d7 100644 --- a/polymer/eduke32/source/actors.c +++ b/polymer/eduke32/source/actors.c @@ -608,9 +608,9 @@ void A_DoGutsDir(int32_t sp, int32_t gtype, int32_t n) } } -void Sect_SetInterpolation(int32_t i) +void Sect_SetInterpolation(int32_t sectnum) { - int32_t k, j = sector[SECT].wallptr, endwall = j+sector[SECT].wallnum; + int32_t k, j = sector[sectnum].wallptr, endwall = j+sector[sectnum].wallnum; for (; j sectnum directly +void Sect_ClearInterpolation(int32_t sectnum); +void Sect_SetInterpolation(int32_t sectnum); #endif diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index a580db24d..b4d549ce0 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -5581,8 +5581,15 @@ int32_t A_Spawn(int32_t j, int32_t pn) if (upperwall>=0 && wall[upperwall].nextsector>=0) { - Sect_SetInterpolation(wall[upperwall].nextsector); - actor[i].t_data[9] = wall[upperwall].nextsector; + int32_t jj, uppersect=wall[upperwall].nextsector; + for (jj=headspritesect[uppersect]; jj>=0; jj=nextspritesect[jj]) + if (sprite[jj].picnum==SECTOREFFECTOR && sprite[jj].lotag==sp->lotag) + break; + if (jj < 0) + { + Sect_SetInterpolation(wall[upperwall].nextsector); + actor[i].t_data[9] = wall[upperwall].nextsector; + } } } #endif @@ -5636,7 +5643,7 @@ int32_t A_Spawn(int32_t j, int32_t pn) case 15: case 16: case 26: - Sect_SetInterpolation(i); + Sect_SetInterpolation(sprite[i].sectnum); break; } diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index af85cdb0d..4563c63d5 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -2478,7 +2478,7 @@ nullquote: case CON_SECTCLEARINTERPOLATION: insptr++; { - int32_t sectnum = Gv_GetVarX(*insptr++), osectnum; + int32_t sectnum = Gv_GetVarX(*insptr++); if ((unsigned)sectnum >= (unsigned)numsectors) { @@ -2486,13 +2486,10 @@ nullquote: continue; } - osectnum = sprite[MAXSPRITES-1].sectnum; - sprite[MAXSPRITES-1].sectnum = sectnum; if (tw==CON_SECTSETINTERPOLATION) - Sect_SetInterpolation(MAXSPRITES-1); + Sect_SetInterpolation(sectnum); else - Sect_ClearInterpolation(MAXSPRITES-1); - sprite[MAXSPRITES-1].sectnum = osectnum; + Sect_ClearInterpolation(sectnum); continue; } @@ -5184,6 +5181,7 @@ void G_RestoreMapState(mapstate_t *save) } } + // TODO: sync with TROR special interpolations? (e.g. upper floor of subway) g_numInterpolations = 0; startofdynamicinterpolations = 0; @@ -5215,7 +5213,7 @@ void G_RestoreMapState(mapstate_t *save) case 16: case 26: case 30: - Sect_SetInterpolation(k); + Sect_SetInterpolation(sprite[k].sectnum); break; } diff --git a/polymer/eduke32/source/savegame.c b/polymer/eduke32/source/savegame.c index d3e7f68e0..b2f543d42 100644 --- a/polymer/eduke32/source/savegame.c +++ b/polymer/eduke32/source/savegame.c @@ -583,7 +583,7 @@ int32_t G_LoadPlayer(int32_t spot) case 16: case 26: case 30: - Sect_SetInterpolation(k); + Sect_SetInterpolation(sprite[k].sectnum); break; } @@ -2284,7 +2284,7 @@ static void postloadplayer1() case 16: case 26: case 30: - Sect_SetInterpolation(i); + Sect_SetInterpolation(sprite[i].sectnum); break; }