📄 engine.c
字号:
asm3 = (long)globalpalwritten + ((long)getpalookup((long)mulscale16(r,globvis),globalshade)<<8); if (!(globalorientation&256)) { mhline(globalbufplc,globaly1*r+globalxpanning-asm1*(xr-xl),(xr-xl)<<16,0L, globalx2*r+globalypanning-asm2*(xr-xl),ylookup[yp]+xl+frameoffset); return; } thline(globalbufplc,globaly1*r+globalxpanning-asm1*(xr-xl),(xr-xl)<<16,0L, globalx2*r+globalypanning-asm2*(xr-xl),ylookup[yp]+xl+frameoffset); transarea += (xr-xl);}static int animateoffs(short tilenum, short fakevar){ long i, k, offs; offs = 0; i = (totalclocklock>>((picanm[tilenum]>>24)&15)); if ((picanm[tilenum]&63) > 0) { switch(picanm[tilenum]&192) { case 64: k = (i%((picanm[tilenum]&63)<<1)); if (k < (picanm[tilenum]&63)) offs = k; else offs = (((picanm[tilenum]&63)<<1)-k); break; case 128: offs = (i%((picanm[tilenum]&63)+1)); break; case 192: offs = -(i%((picanm[tilenum]&63)+1)); } } return(offs);}/* renders non-parallaxed ceilings. --ryan. */static void ceilscan (long x1, long x2, long sectnum){ long i, j, ox, oy, x, y1, y2, twall, bwall; sectortype *sec; sec = §or[sectnum]; if (palookup[sec->ceilingpal] != globalpalwritten) { globalpalwritten = palookup[sec->ceilingpal]; setpalookupaddress(globalpalwritten); } globalzd = sec->ceilingz-globalposz; if (globalzd > 0) return; globalpicnum = sec->ceilingpicnum; if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; setgotpic(globalpicnum); if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) return; if (picanm[globalpicnum]&192) globalpicnum += animateoffs((short)globalpicnum,(short)sectnum); if (waloff[globalpicnum] == 0) loadtile(globalpicnum); globalbufplc = waloff[globalpicnum]; globalshade = (long)sec->ceilingshade; globvis = globalcisibility; if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); globalorientation = (long)sec->ceilingstat; if ((globalorientation&64) == 0) { globalx1 = singlobalang; globalx2 = singlobalang; globaly1 = cosglobalang; globaly2 = cosglobalang; globalxpanning = (globalposx<<20); globalypanning = -(globalposy<<20); } else { j = sec->wallptr; ox = wall[wall[j].point2].x - wall[j].x; oy = wall[wall[j].point2].y - wall[j].y; i = nsqrtasm(ox*ox+oy*oy); if (i == 0) i = 1024; else i = 1048576/i; globalx1 = mulscale10(dmulscale10(ox,singlobalang,-oy,cosglobalang),i); globaly1 = mulscale10(dmulscale10(ox,cosglobalang,oy,singlobalang),i); globalx2 = -globalx1; globaly2 = -globaly1; ox = ((wall[j].x-globalposx)<<6); oy = ((wall[j].y-globalposy)<<6); i = dmulscale14(oy,cosglobalang,-ox,singlobalang); j = dmulscale14(ox,cosglobalang,oy,singlobalang); ox = i; oy = j; globalxpanning = globalx1*ox - globaly1*oy; globalypanning = globaly2*ox + globalx2*oy; } globalx2 = mulscale16(globalx2,viewingrangerecip); globaly1 = mulscale16(globaly1,viewingrangerecip); globalxshift = (8-(picsiz[globalpicnum]&15)); globalyshift = (8-(picsiz[globalpicnum]>>4)); if (globalorientation&8) { globalxshift++; globalyshift++; } if ((globalorientation&0x4) > 0) { i = globalxpanning; globalxpanning = globalypanning; globalypanning = i; i = globalx2; globalx2 = -globaly1; globaly1 = -i; i = globalx1; globalx1 = globaly2; globaly2 = i; } if ((globalorientation&0x10) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalxpanning = -globalxpanning; if ((globalorientation&0x20) > 0) globalx2 = -globalx2, globaly2 = -globaly2, globalypanning = -globalypanning; globalx1 <<= globalxshift; globaly1 <<= globalxshift; globalx2 <<= globalyshift; globaly2 <<= globalyshift; globalxpanning <<= globalxshift; globalypanning <<= globalyshift; globalxpanning += (((long)sec->ceilingxpanning)<<24); globalypanning += (((long)sec->ceilingypanning)<<24); globaly1 = (-globalx1-globaly1)*halfxdimen; globalx2 = (globalx2-globaly2)*halfxdimen; sethlinesizes(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4,globalbufplc); globalx2 += globaly2*(x1-1); globaly1 += globalx1*(x1-1); globalx1 = mulscale16(globalx1,globalzd); globalx2 = mulscale16(globalx2,globalzd); globaly1 = mulscale16(globaly1,globalzd); globaly2 = mulscale16(globaly2,globalzd); globvis = klabs(mulscale10(globvis,globalzd)); if (!(globalorientation&0x180)) { y1 = umost[x1]; y2 = y1; for(x=x1;x<=x2;x++) { twall = umost[x]-1; bwall = min(uplc[x],dmost[x]); if (twall < bwall-1) { if (twall >= y2) { while (y1 < y2-1) hline(x-1,++y1); y1 = twall; } else { while (y1 < twall) hline(x-1,++y1); while (y1 > twall) lastx[y1--] = x; } while (y2 > bwall) hline(x-1,--y2); while (y2 < bwall) lastx[y2++] = x; } else { while (y1 < y2-1) hline(x-1,++y1); if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } y1 = umost[x+1]; y2 = y1; } globalx2 += globaly2; globaly1 += globalx1; } while (y1 < y2-1) hline(x2,++y1); faketimerhandler(); return; } switch(globalorientation&0x180) { case 128: msethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); break; case 256: settransnormal(); tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); break; case 384: settransreverse(); tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); break; } y1 = umost[x1]; y2 = y1; for(x=x1;x<=x2;x++) { twall = umost[x]-1; bwall = min(uplc[x],dmost[x]); if (twall < bwall-1) { if (twall >= y2) { while (y1 < y2-1) slowhline(x-1,++y1); y1 = twall; } else { while (y1 < twall) slowhline(x-1,++y1); while (y1 > twall) lastx[y1--] = x; } while (y2 > bwall) slowhline(x-1,--y2); while (y2 < bwall) lastx[y2++] = x; } else { while (y1 < y2-1) slowhline(x-1,++y1); if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } y1 = umost[x+1]; y2 = y1; } globalx2 += globaly2; globaly1 += globalx1; } while (y1 < y2-1) slowhline(x2,++y1); faketimerhandler();}/* renders non-parallaxed floors. --ryan. */static void florscan (long x1, long x2, long sectnum){ long i, j, ox, oy, x, y1, y2, twall, bwall; sectortype *sec; sec = §or[sectnum]; if (palookup[sec->floorpal] != globalpalwritten) { globalpalwritten = palookup[sec->floorpal]; setpalookupaddress(globalpalwritten); } globalzd = globalposz-sec->floorz; if (globalzd > 0) return; globalpicnum = sec->floorpicnum; if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; setgotpic(globalpicnum); if ((tilesizx[globalpicnum] <= 0) || (tilesizy[globalpicnum] <= 0)) return; if (picanm[globalpicnum]&192) globalpicnum += animateoffs((short)globalpicnum,(short)sectnum); if (waloff[globalpicnum] == 0) loadtile(globalpicnum); globalbufplc = waloff[globalpicnum]; globalshade = (long)sec->floorshade; globvis = globalcisibility; if (sec->visibility != 0) globvis = mulscale4(globvis,(long)((unsigned char)(sec->visibility+16))); globalorientation = (long)sec->floorstat; if ((globalorientation&64) == 0) { globalx1 = singlobalang; globalx2 = singlobalang; globaly1 = cosglobalang; globaly2 = cosglobalang; globalxpanning = (globalposx<<20); globalypanning = -(globalposy<<20); } else { j = sec->wallptr; ox = wall[wall[j].point2].x - wall[j].x; oy = wall[wall[j].point2].y - wall[j].y; i = nsqrtasm(ox*ox+oy*oy); if (i == 0) i = 1024; else i = 1048576/i; globalx1 = mulscale10(dmulscale10(ox,singlobalang,-oy,cosglobalang),i); globaly1 = mulscale10(dmulscale10(ox,cosglobalang,oy,singlobalang),i); globalx2 = -globalx1; globaly2 = -globaly1; ox = ((wall[j].x-globalposx)<<6); oy = ((wall[j].y-globalposy)<<6); i = dmulscale14(oy,cosglobalang,-ox,singlobalang); j = dmulscale14(ox,cosglobalang,oy,singlobalang); ox = i; oy = j; globalxpanning = globalx1*ox - globaly1*oy; globalypanning = globaly2*ox + globalx2*oy; } globalx2 = mulscale16(globalx2,viewingrangerecip); globaly1 = mulscale16(globaly1,viewingrangerecip); globalxshift = (8-(picsiz[globalpicnum]&15)); globalyshift = (8-(picsiz[globalpicnum]>>4)); if (globalorientation&8) { globalxshift++; globalyshift++; } if ((globalorientation&0x4) > 0) { i = globalxpanning; globalxpanning = globalypanning; globalypanning = i; i = globalx2; globalx2 = -globaly1; globaly1 = -i; i = globalx1; globalx1 = globaly2; globaly2 = i; } if ((globalorientation&0x10) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalxpanning = -globalxpanning; if ((globalorientation&0x20) > 0) globalx2 = -globalx2, globaly2 = -globaly2, globalypanning = -globalypanning; globalx1 <<= globalxshift; globaly1 <<= globalxshift; globalx2 <<= globalyshift; globaly2 <<= globalyshift; globalxpanning <<= globalxshift; globalypanning <<= globalyshift; globalxpanning += (((long)sec->floorxpanning)<<24); globalypanning += (((long)sec->floorypanning)<<24); globaly1 = (-globalx1-globaly1)*halfxdimen; globalx2 = (globalx2-globaly2)*halfxdimen; sethlinesizes(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4,globalbufplc); globalx2 += globaly2*(x1-1); globaly1 += globalx1*(x1-1); globalx1 = mulscale16(globalx1,globalzd); globalx2 = mulscale16(globalx2,globalzd); globaly1 = mulscale16(globaly1,globalzd); globaly2 = mulscale16(globaly2,globalzd); globvis = klabs(mulscale10(globvis,globalzd)); if (!(globalorientation&0x180)) { y1 = max(dplc[x1],umost[x1]); y2 = y1; for(x=x1;x<=x2;x++) { twall = max(dplc[x],umost[x])-1; bwall = dmost[x]; if (twall < bwall-1) { if (twall >= y2) { while (y1 < y2-1) hline(x-1,++y1); y1 = twall; } else { while (y1 < twall) hline(x-1,++y1); while (y1 > twall) lastx[y1--] = x; } while (y2 > bwall) hline(x-1,--y2); while (y2 < bwall) lastx[y2++] = x; } else { while (y1 < y2-1) hline(x-1,++y1); if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } y1 = max(dplc[x+1],umost[x+1]); y2 = y1; } globalx2 += globaly2; globaly1 += globalx1; } while (y1 < y2-1) hline(x2,++y1); faketimerhandler(); return; } switch(globalorientation&0x180) { case 128: msethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); break; case 256: settransnormal(); tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); break; case 384: settransreverse(); tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); break; } y1 = max(dplc[x1],umost[x1]); y2 = y1; for(x=x1;x<=x2;x++) { twall = max(dplc[x],umost[x])-1; bwall = dmost[x]; if (twall < bwall-1) { if (twall >= y2) { while (y1 < y2-1) slowhline(x-1,++y1); y1 = twall; } else { while (y1 < twall) slowhline(x-1,++y1); while (y1 > twall) lastx[y1--] = x; } while (y2 > bwall) slowhline(x-1,--y2); while (y2 < bwall) lastx[y2++] = x; } else { while (y1 < y2-1) slowhline(x-1,++y1); if (x == x2) { globalx2 += globaly2; globaly1 += globalx1; break; } y1 = max(dplc[x+1],umost[x+1]); y2 = y1; } globalx2 += globaly2; globaly1 += globalx1; } while (y1 < y2-1) slowhline(x2,++y1); faketimerhandler();}/* * renders walls and parallaxed skies/floors. Look at parascan() for the * higher level of parallaxing. * * x1 == offset of leftmost pixel of wall. 0 is left of surface. * x2 == offset of rightmost pixel of wall. 0 is left of surface. * * apparently, walls are always vertical; there are sloping functions * (!!!) er...elsewhere. Only the sides need be vertical, as the top and * bottom of the polygon will need to be angled as the camera perspective * shifts (user spins in a circle, etc.) * * uwal is an array of the upper most pixels, and dwal are the lower most. * This must be a list, as the top and bottom of the polygon are not * necessarily horizontal lines. * * So, the screen coordinate of the top left of a wall is specified by * uwal[x1], the bottom left by dwal[x1], the top right by uwal[x2], and * the bottom right by dwal[x2]. Every physical point on the edge of the * wall in between is specified by traversing those arrays, one pixel per * element. * * --ryan. */static void wallscan(long x1, long x2, short *uwal, short *dwal, long *swal, long *lwal){ long i, x, xnice, ynice, fpalookup; long y1ve[4], y2ve[4], u4, d4, z, tsizx, tsizy; char bad; tsizx = tilesizx[globalpicnum]; tsizy = tilesizy[globalpicnum]; setgotpic(globalpicnum); if ((tsizx <= 0) || (tsizy <= 0)) return; if ((uwal[x1] > ydimen) && (uwal[x2] > ydimen)) return; if ((dwal[x1] < 0) && (dwal[x2] < 0)) return; if (waloff[globalpicnum] == 0) loadtile(globalpicnum); xnice = (pow2long[picsiz[globalpicnum]&15] == tsizx); if (xnice) tsizx--; ynice = (pow2long[picsiz[globalpicnum]>>4] == tsizy);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -