📄 engine.c
字号:
globaly = mulscale19(cosglobalang,xdimenrecip); globalx1 = (globalposx<<8); globaly1 = -(globalposy<<8); i = (dax1-halfxdimen)*xdimenrecip; globalx2 = mulscale16(cosglobalang<<4,viewingrangerecip) - mulscale27(singlobalang,i); globaly2 = mulscale16(singlobalang<<4,viewingrangerecip) + mulscale27(cosglobalang,i); globalzd = (xdimscale<<9); globalzx = -dmulscale17(wx,globaly2,-wy,globalx2) + mulscale10(1-globalhoriz,globalzd); globalz = -dmulscale25(wx,globaly,-wy,globalx); if (globalorientation&64) /* Relative alignment */ { dx = mulscale14(wall[wal->point2].x-wal->x,dasqr); dy = mulscale14(wall[wal->point2].y-wal->y,dasqr); i = nsqrtasm(daslope*daslope+16777216); x = globalx; y = globaly; globalx = dmulscale16(x,dx,y,dy); globaly = mulscale12(dmulscale16(-y,dx,x,dy),i); x = ((wal->x-globalposx)<<8); y = ((wal->y-globalposy)<<8); globalx1 = dmulscale16(-x,dx,-y,dy); globaly1 = mulscale12(dmulscale16(-y,dx,x,dy),i); x = globalx2; y = globaly2; globalx2 = dmulscale16(x,dx,y,dy); globaly2 = mulscale12(dmulscale16(-y,dx,x,dy),i); } if (globalorientation&0x4) { i = globalx; globalx = -globaly; globaly = -i; i = globalx1; globalx1 = globaly1; globaly1 = i; i = globalx2; globalx2 = -globaly2; globaly2 = -i; } if (globalorientation&0x10) { globalx1 = -globalx1, globalx2 = -globalx2, globalx = -globalx; } if (globalorientation&0x20) { globaly1 = -globaly1, globaly2 = -globaly2, globaly = -globaly; } daz = dmulscale9(wx,globalposy-wal->y,-wy,globalposx-wal->x) + ((daz-globalposz)<<8); globalx2 = mulscale20(globalx2,daz); globalx = mulscale28(globalx,daz); globaly2 = mulscale20(globaly2,-daz); globaly = mulscale28(globaly,-daz); i = 8-(picsiz[globalpicnum]&15); j = 8-(picsiz[globalpicnum]>>4); if (globalorientation&8) { i++; j++; } globalx1 <<= (i+12); globalx2 <<= i; globalx <<= i; globaly1 <<= (j+12); globaly2 <<= j; globaly <<= j; if (dastat == 0) { globalx1 += (((long)sec->ceilingxpanning)<<24); globaly1 += (((long)sec->ceilingypanning)<<24); } else { globalx1 += (((long)sec->floorxpanning)<<24); globaly1 += (((long)sec->floorypanning)<<24); } asm1 = -(globalzd>>(16-BITSOFPRECISION)); globvis = globalvisibility; if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); globvis = mulscale13(globvis,daz); globvis = mulscale16(globvis,xdimscale); j =(long) FP_OFF(palookup[globalpal]); setupslopevlin(((long)(picsiz[globalpicnum]&15))+(((long)(picsiz[globalpicnum]>>4))<<8),waloff[globalpicnum],-ylookup[1]); l = (globalzd>>16); shinc = mulscale16(globalz,xdimenscale); if (shinc > 0) shoffs = (4<<15); else shoffs = ((2044-ydimen)<<15); if (dastat == 0) y1 = umost[dax1]; else y1 = max(umost[dax1],dplc[dax1]); m1 = mulscale16(y1,globalzd) + (globalzx>>6); /* Avoid visibility overflow by crossing horizon */ if (globalzd > 0) m1 += (globalzd>>16); else m1 -= (globalzd>>16); m2 = m1+l; mptr1 = (long *)&slopalookup[y1+(shoffs>>15)]; mptr2 = mptr1+1; for(x=dax1;x<=dax2;x++) { if (dastat == 0) { y1 = umost[x]; y2 = min(dmost[x],uplc[x])-1; } else { y1 = max(umost[x],dplc[x]); y2 = dmost[x]-1; } if (y1 <= y2) { nptr1 = (long *)&slopalookup[y1+(shoffs>>15)]; nptr2 = (long *)&slopalookup[y2+(shoffs>>15)]; while (nptr1 <= mptr1) { *mptr1-- = j + (getpalookup((long)mulscale24(krecipasm(m1),globvis),globalshade)<<8); m1 -= l; } while (nptr2 >= mptr2) { *mptr2++ = j + (getpalookup((long)mulscale24(krecipasm(m2),globvis),globalshade)<<8); m2 += l; } globalx3 = (globalx2>>10); globaly3 = (globaly2>>10); asm3 = mulscale16(y2,globalzd) + (globalzx>>6); slopevlin(ylookup[y2]+x+frameoffset,krecipasm(asm3>>3),(long)nptr2,y2-y1+1,globalx1,globaly1); if ((x&15) == 0) faketimerhandler(); } globalx2 += globalx; globaly2 += globaly; globalzx += globalz; shoffs += shinc; }}static int owallmost(short *mostbuf, long w, long z){ long bad, inty, xcross, y, yinc; long s1, s2, s3, s4, ix1, ix2, iy1, iy2, t; z <<= 7; s1 = mulscale20(globaluclip,yb1[w]); s2 = mulscale20(globaluclip,yb2[w]); s3 = mulscale20(globaldclip,yb1[w]); s4 = mulscale20(globaldclip,yb2[w]); bad = (z<s1)+((z<s2)<<1)+((z>s3)<<2)+((z>s4)<<3); ix1 = xb1[w]; iy1 = yb1[w]; ix2 = xb2[w]; iy2 = yb2[w]; if ((bad&3) == 3) { clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),0L); return(bad); } if ((bad&12) == 12) { clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); return(bad); } if (bad&3) { t = divscale30(z-s1,s2-s1); inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); if ((bad&3) == 2) { if (xb1[w] <= xcross) { iy2 = inty; ix2 = xcross; } clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),0L); } else { if (xcross <= xb2[w]) { iy1 = inty; ix1 = xcross; } clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),0L); } } if (bad&12) { t = divscale30(z-s3,s4-s3); inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); if ((bad&12) == 8) { if (xb1[w] <= xcross) { iy2 = inty; ix2 = xcross; } clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); } else { if (xcross <= xb2[w]) { iy1 = inty; ix1 = xcross; } clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); } } y = (scale(z,xdimenscale,iy1)<<4); yinc = ((scale(z,xdimenscale,iy2)<<4)-y) / (ix2-ix1+1); qinterpolatedown16short((long *)&mostbuf[ix1],ix2-ix1+1,y+(globalhoriz<<16),yinc); if (mostbuf[ix1] < 0) mostbuf[ix1] = 0; if (mostbuf[ix1] > ydimen) mostbuf[ix1] = ydimen; if (mostbuf[ix2] < 0) mostbuf[ix2] = 0; if (mostbuf[ix2] > ydimen) mostbuf[ix2] = ydimen; return(bad);}static int wallmost(short *mostbuf, long w, long sectnum, char dastat){ long bad, i, j, t, y, z, inty, intz, xcross, yinc, fw; long x1, y1, z1, x2, y2, z2, xv, yv, dx, dy, dasqr, oz1, oz2; long s1, s2, s3, s4, ix1, ix2, iy1, iy2; if (dastat == 0) { z = sector[sectnum].ceilingz-globalposz; if ((sector[sectnum].ceilingstat&2) == 0) return(owallmost(mostbuf,w,z)); } else { z = sector[sectnum].floorz-globalposz; if ((sector[sectnum].floorstat&2) == 0) return(owallmost(mostbuf,w,z)); } i = thewall[w]; if (i == sector[sectnum].wallptr) return(owallmost(mostbuf,w,z)); x1 = wall[i].x; x2 = wall[wall[i].point2].x-x1; y1 = wall[i].y; y2 = wall[wall[i].point2].y-y1; fw = sector[sectnum].wallptr; i = wall[fw].point2; dx = wall[i].x-wall[fw].x; dy = wall[i].y-wall[fw].y; dasqr = krecipasm(nsqrtasm(dx*dx+dy*dy)); if (xb1[w] == 0) { xv = cosglobalang+sinviewingrangeglobalang; yv = singlobalang-cosviewingrangeglobalang; } else { xv = x1-globalposx; yv = y1-globalposy; } i = xv*(y1-globalposy)-yv*(x1-globalposx); j = yv*x2-xv*y2; if (klabs(j) > klabs(i>>3)) i = divscale28(i,j); if (dastat == 0) { t = mulscale15(sector[sectnum].ceilingheinum,dasqr); z1 = sector[sectnum].ceilingz; } else { t = mulscale15(sector[sectnum].floorheinum,dasqr); z1 = sector[sectnum].floorz; } z1 = dmulscale24(dx*t,mulscale20(y2,i)+((y1-wall[fw].y)<<8), -dy*t,mulscale20(x2,i)+((x1-wall[fw].x)<<8))+((z1-globalposz)<<7); if (xb2[w] == xdimen-1) { xv = cosglobalang-sinviewingrangeglobalang; yv = singlobalang+cosviewingrangeglobalang; } else { xv = (x2+x1)-globalposx; yv = (y2+y1)-globalposy; } i = xv*(y1-globalposy)-yv*(x1-globalposx); j = yv*x2-xv*y2; if (klabs(j) > klabs(i>>3)) i = divscale28(i,j); if (dastat == 0) { t = mulscale15(sector[sectnum].ceilingheinum,dasqr); z2 = sector[sectnum].ceilingz; } else { t = mulscale15(sector[sectnum].floorheinum,dasqr); z2 = sector[sectnum].floorz; } z2 = dmulscale24(dx*t,mulscale20(y2,i)+((y1-wall[fw].y)<<8), -dy*t,mulscale20(x2,i)+((x1-wall[fw].x)<<8))+((z2-globalposz)<<7); s1 = mulscale20(globaluclip,yb1[w]); s2 = mulscale20(globaluclip,yb2[w]); s3 = mulscale20(globaldclip,yb1[w]); s4 = mulscale20(globaldclip,yb2[w]); bad = (z1<s1)+((z2<s2)<<1)+((z1>s3)<<2)+((z2>s4)<<3); ix1 = xb1[w]; ix2 = xb2[w]; iy1 = yb1[w]; iy2 = yb2[w]; oz1 = z1; oz2 = z2; if ((bad&3) == 3) { clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),0L); return(bad); } if ((bad&12) == 12) { clearbufbyte(&mostbuf[ix1],(ix2-ix1+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); return(bad); } if (bad&3) { /* inty = intz / (globaluclip>>16) */ t = divscale30(oz1-s1,s2-s1+oz1-oz2); inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); intz = oz1 + mulscale30(oz2-oz1,t); xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); /* * t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); * inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); * intz = z1 + mulscale30(z2-z1,t); */ if ((bad&3) == 2) { if (xb1[w] <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),0L); } else { if (xcross <= xb2[w]) { z1 = intz; iy1 = inty; ix1 = xcross; } clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),0L); } } if (bad&12) { /* inty = intz / (globaldclip>>16) */ t = divscale30(oz1-s3,s4-s3+oz1-oz2); inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); intz = oz1 + mulscale30(oz2-oz1,t); xcross = xb1[w] + scale(mulscale30(yb2[w],t),xb2[w]-xb1[w],inty); /* * t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); * inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); * intz = z1 + mulscale30(z2-z1,t); */ if ((bad&12) == 8) { if (xb1[w] <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } clearbufbyte(&mostbuf[xcross+1],(xb2[w]-xcross)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); } else { if (xcross <= xb2[w]) { z1 = intz; iy1 = inty; ix1 = xcross; } clearbufbyte(&mostbuf[xb1[w]],(xcross-xb1[w]+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); } } y = (scale(z1,xdimenscale,iy1)<<4); yinc = ((scale(z2,xdimenscale,iy2)<<4)-y) / (ix2-ix1+1); qinterpolatedown16short((long *)&mostbuf[ix1],ix2-ix1+1,y+(globalhoriz<<16),yinc); if (mostbuf[ix1] < 0) mostbuf[ix1] = 0; if (mostbuf[ix1] > ydimen) mostbuf[ix1] = ydimen; if (mostbuf[ix2] < 0) mostbuf[ix2] = 0; if (mostbuf[ix2] > ydimen) mostbuf[ix2] = ydimen; return(bad);}static void drawalls(long bunch){ sectortype *sec, *nextsec; walltype *wal; long i, x, x1, x2, cz[5], fz[5]; long z, wallnum, sectnum, nextsectnum; long startsmostwallcnt, startsmostcnt, gotswall; char andwstat1, andwstat2; z = bunchfirst[bunch]; sectnum = thesector[z]; sec = §or[sectnum]; andwstat1 = 0xff; andwstat2 = 0xff; for(;z>=0;z=p2[z]) /* uplc/dplc calculation */ { andwstat1 &= wallmost(uplc,z,sectnum,(char)0); andwstat2 &= wallmost(dplc,z,sectnum,(char)1); } if ((andwstat1&3) != 3) /* draw ceilings */ { if ((sec->ceilingstat&3) == 2) grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0); else if ((sec->ceilingstat&1) == 0) ceilscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); else parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0,bunch); } if ((andwstat2&12) != 12) /* draw floors */ { if ((sec->floorstat&3) == 2) grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1); else if ((sec->floorstat&1) == 0) florscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); else parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1,bunch); } /* DRAW WALLS SECTION! */ for(z=bunchfirst[bunch];z>=0;z=p2[z]) { x1 = xb1[z]; x2 = xb2[z]; if (umost[x2] >= dmost[x2]) { for(x=x1;x<x2;x++) if (umost[x] < dmost[x]) break; if (x >= x2) { smostwall[smostwallcnt] = z; smostwalltype[smostwallcnt] = 0; smostwallcnt++; continue; } } wallnum = thewall[z]; wal = &wall[wallnum]; nextsectnum = wal->nextsector; nextsec = §or[nextsectnum]; gotswall = 0; startsmostwallcnt = smostwallcnt; startsmostcnt = smostcnt; if ((searchit == 2) && (searchx >= x1) && (searchx <= x2)) { if (searchy <= uplc[searchx]) /* ceiling */ { searchsector = sectnum; searchwall = wallnum; searchstat = 1; searchit = 1; } else if (searchy >= dplc[searchx]) /* floor */ { searchsector = sectnum; searchwall = wallnum; searchstat = 2; searchit = 1; } } if (nextsectnum >= 0) { getzsofslope((short)sectnum,wal->x,wal->y,&cz[0],&fz[0]); getzsofslope((short)sectnum,wall[wal->point2].x,wall[wal->point2].y,&cz[1],&fz[1]); getzsof
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -