| /* |
| * "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman |
| * Ken Silverman's official web site: "http://www.advsys.net/ken" |
| * See the included license file "BUILDLIC.TXT" for license info. |
| * This file has been modified from Ken Silverman's original release |
| */ |
| |
| /* SUPERBUILD define is in engine.h ... */ |
| |
| #define ENGINE |
| |
| #include "platform.h" |
| |
| #include "build.h" |
| |
| #include "engine.h" |
| #include "tiles.h" |
| |
| int32_t stereowidth = 23040, stereopixelwidth = 28, ostereopixelwidth = -1; |
| int32_t stereomode = 0, visualpage, activepage, whiteband, blackband; |
| uint8_t oa1, o3c2, ortca, ortcb, overtbits, laststereoint; |
| |
| #include "display.h" |
| |
| #define MAXCLIPNUM 512 |
| #define MAXPERMS 512 |
| #define MAXTILEFILES 256 |
| #define MAXYSAVES ((MAXXDIM*MAXSPRITES)>>7) |
| #define MAXNODESPERLINE 42 /* Warning: This depends on MAXYSAVES & MAXYDIM! */ |
| #define MAXWALLSB 2048 |
| #define MAXCLIPDIST 1024 |
| |
| /* used to be static. --ryan. */ |
| uint8_t moustat = 0; |
| |
| int32_t transarea = 0, beforedrawrooms = 1; |
| |
| /* used to be static. --ryan. */ |
| int32_t oxdimen = -1, oviewingrange = -1, oxyaspect = -1; |
| |
| /* used to be static. --ryan. */ |
| int32_t curbrightness = 0; |
| |
| /* Textured Map variables */ |
| static uint8_t globalpolytype; |
| static short *dotp1[MAXYDIM], *dotp2[MAXYDIM]; |
| |
| static char tempbuf[MAXWALLS]; |
| |
| int32_t ebpbak, espbak; |
| int32_t slopalookup[16384]; |
| |
| /* |
| * !!! used to be static. If we ever put the original setgamemode() back, this |
| * !!! can be made static again. --ryan. |
| */ |
| uint8_t permanentlock = 255; |
| int32_t mapversion; |
| |
| uint8_t picsiz[MAXTILES], tilefilenum[MAXTILES]; |
| int32_t lastageclock; |
| int32_t tilefileoffs[MAXTILES]; |
| |
| int32_t artsize = 0, cachesize = 0; |
| |
| static short radarang[1280], radarang2[MAXXDIM+1]; |
| static uint16_t sqrtable[4096], shlookup[4096+256]; |
| uint8_t pow2char[8] = {1,2,4,8,16,32,64,-128}; |
| int32_t pow2long[32] = |
| { |
| 1L,2L,4L,8L, |
| 16L,32L,64L,128L, |
| 256L,512L,1024L,2048L, |
| 4096L,8192L,16384L,32768L, |
| 65536L,131072L,262144L,524288L, |
| 1048576L,2097152L,4194304L,8388608L, |
| 16777216L,33554432L,67108864L,134217728L, |
| 268435456L,536870912L,1073741824L,2147483647L, |
| }; |
| int32_t reciptable[2048], fpuasm; |
| |
| char kensmessage[128]; |
| |
| uint8_t britable[16][64]; |
| uint8_t textfont[1024], smalltextfont[1024]; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| enum vector_index_e {VEC_X=0,VEC_Y=1}; |
| enum screenSpaceCoo_index_e {VEC_COL=0,VEC_DIST=1}; |
| typedef int32_t vector_t[2]; |
| typedef int32_t coo2D_t[2]; |
| // This is the structure emitted for each wall that is potentially visible. |
| // A stack of those is populated when the sectors are scanned. |
| typedef struct pvWall_s{ |
| vector_t cameraSpaceCoo[2]; //Camera space coordinates of the wall endpoints. Access with vector_index_e. |
| int16_t sectorId; //The index of the sector this wall belongs to in the map database. |
| int16_t worldWallId; //The index of the wall in the map database. |
| coo2D_t screenSpaceCoo[2]; //Screen space coordinate of the wall endpoints. Access with screenSpaceCoo_index_e. |
| } pvWall_t; |
| |
| // Potentially Visible walls are stored in this stack. |
| pvWall_t pvWalls[MAXWALLSB]; |
| |
| |
| |
| |
| //xb1 and xb2 seems to be storing the column of the wall endpoint |
| //yb1 and yb2 store the Y distance from the camera. |
| |
| //static int32_t xb1[MAXWALLSB], yb1[MAXWALLSB], xb2[MAXWALLSB], yb2[MAXWALLSB]; |
| |
| /* |
| //rx1,rx2,ry1,ry2 stores the cameraspace wall endpoints coordinates. |
| static int32_t rx1[MAXWALLSB], ry1[MAXWALLSB], rx2[MAXWALLSB], ry2[MAXWALLSB]; |
| static short thesector[MAXWALLSB], thewall[MAXWALLSB]; |
| */ |
| |
| // bunchWallsList contains the list of walls in a bunch. |
| static short bunchWallsList[MAXWALLSB]; |
| |
| static short bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB]; |
| |
| |
| |
| |
| |
| |
| |
| static short smost[MAXYSAVES], smostcnt; |
| static short smoststart[MAXWALLSB]; |
| static uint8_t smostwalltype[MAXWALLSB]; |
| static int32_t smostwall[MAXWALLSB], smostwallcnt = -1L; |
| |
| static short maskwall[MAXWALLSB], maskwallcnt; |
| static int32_t spritesx[MAXSPRITESONSCREEN]; |
| static int32_t spritesy[MAXSPRITESONSCREEN+1]; |
| static int32_t spritesz[MAXSPRITESONSCREEN]; |
| static spritetype *tspriteptr[MAXSPRITESONSCREEN]; |
| |
| //FCS: (up-most pixel on column x that can still be drawn to) |
| short umost[MAXXDIM+1]; |
| |
| //FCS: (down-most pixel +1 on column x that can still be drawn to) |
| short dmost[MAXXDIM+1]; |
| |
| int16_t bakumost[MAXXDIM+1], bakdmost[MAXXDIM+1]; |
| short uplc[MAXXDIM+1], dplc[MAXXDIM+1]; |
| static int16_t uwall[MAXXDIM+1], dwall[MAXXDIM+1]; |
| static int32_t swplc[MAXXDIM+1], lplc[MAXXDIM+1]; |
| static int32_t swall[MAXXDIM+1], lwall[MAXXDIM+4]; |
| int32_t xdimen = -1, xdimenrecip, halfxdimen, xdimenscale, xdimscale; |
| int32_t wx1, wy1, wx2, wy2, ydimen; |
| int32_t viewoffset; |
| |
| static int32_t rxi[8], ryi[8], rzi[8], rxi2[8], ryi2[8], rzi2[8]; |
| static int32_t xsi[8], ysi[8]; |
| |
| /* used to be static. --ryan. */ |
| int32_t *horizlookup=0, *horizlookup2=0, horizycent; |
| |
| int32_t globalposx, globalposy, globalposz, globalhoriz; |
| int16_t globalang, globalcursectnum; |
| int32_t globalpal, cosglobalang, singlobalang; |
| int32_t cosviewingrangeglobalang, sinviewingrangeglobalang; |
| uint8_t *globalpalwritten; |
| int32_t globaluclip, globaldclip, globvis = 0; |
| int32_t globalvisibility, globalhisibility, globalpisibility, globalcisibility; |
| uint8_t globparaceilclip, globparaflorclip; |
| |
| int32_t xyaspect, viewingrangerecip; |
| |
| int32_t asm1, asm4; |
| intptr_t asm2, asm3; |
| |
| |
| int32_t vplce[4], vince[4]; |
| intptr_t bufplce[4]; |
| |
| uint8_t* palookupoffse[4]; |
| |
| uint8_t globalxshift, globalyshift; |
| int32_t globalxpanning, globalypanning, globalshade; |
| int16_t globalpicnum, globalshiftval; |
| int32_t globalzd, globalyscale, globalorientation; |
| uint8_t* globalbufplc; |
| int32_t globalx1, globaly1, globalx2, globaly2, globalx3, globaly3, globalzx; |
| int32_t globalx, globaly, globalz; |
| |
| //FCS: |
| // Those two variables are using during portal flooding: |
| // sectorBorder is the stack and sectorbordercnt is the stack counter. |
| // There is no really point to have this on the heap. That would have been better on the stack. |
| |
| //static short sectorborder[256], sectorbordercnt; |
| //FCS: Moved this on the stack |
| |
| static uint8_t tablesloaded = 0; |
| int32_t pageoffset, ydim16, qsetmode = 0; |
| int32_t startposx, startposy, startposz; |
| int16_t startang, startsectnum; |
| int16_t pointhighlight, linehighlight, highlightcnt; |
| static int32_t lastx[MAXYDIM]; |
| uint8_t paletteloaded = 0; |
| |
| #define FASTPALGRIDSIZ 8 |
| static int32_t rdist[129], gdist[129], bdist[129]; |
| static uint8_t colhere[((FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2))>>3]; |
| static uint8_t colhead[(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)*(FASTPALGRIDSIZ+2)]; |
| static int32_t colnext[256]; |
| static uint8_t coldist[8] = {0,1,2,3,4,3,2,1}; |
| static int32_t colscan[27]; |
| |
| static int16_t clipnum, hitwalls[4]; |
| int32_t hitscangoalx = (1<<29)-1, hitscangoaly = (1<<29)-1; |
| |
| typedef struct { |
| int32_t x1, y1, x2, y2; |
| } linetype; |
| static linetype clipit[MAXCLIPNUM]; |
| static short clipsectorlist[MAXCLIPNUM], clipsectnum; |
| static short clipobjectval[MAXCLIPNUM]; |
| |
| typedef struct |
| { |
| int32_t sx, sy, z; |
| short a, picnum; |
| int8_t dashade; |
| uint8_t dapalnum, dastat, pagesleft; |
| int32_t cx1, cy1, cx2, cy2; |
| } permfifotype; |
| static permfifotype permfifo[MAXPERMS]; |
| static int32_t permhead = 0, permtail = 0; |
| |
| //FCS: Num walls to potentially render. |
| short numscans ; |
| |
| short numbunches; |
| |
| //FCS: Number of colums to draw. ALWAYS set to the screen dimension width. |
| short numhits; |
| |
| short editstatus = 0; |
| short searchit; |
| int32_t searchx = -1, searchy; /* search input */ |
| short searchsector, searchwall, searchstat; /* search output */ |
| |
| int32_t numtilefiles, artfil = -1, artfilnum, artfilplc; |
| |
| static uint8_t inpreparemirror = 0; |
| static int32_t mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2; |
| |
| int32_t totalclocklock; |
| |
| uint16_t mapCRC; |
| |
| #include "draw.h" |
| |
| static __inline int32_t nsqrtasm(uint32_t param) |
| { |
| uint16_t *shlookup_a = (uint16_t*)shlookup; |
| uint16_t *sqrtable_a = (uint16_t*)sqrtable; |
| uint16_t cx; |
| |
| if (param & 0xff000000) |
| cx = shlookup_a[(param>>24)+4096]; |
| else |
| cx = shlookup_a[param>>12]; |
| |
| param = param >> (cx&0xff); |
| param = ((param&0xffff0000)|sqrtable_a[param]); |
| param = param >> ((cx&0xff00)>>8); |
| |
| return param; |
| } |
| |
| static __inline int32_t krecipasm(int32_t i) |
| { // Ken did this |
| float f = (float)i; |
| i = *(int32_t *)&f; |
| return((reciptable[(i>>12)&2047]>>(((i-0x3f800000)>>23)&31))^(i>>31)); |
| } |
| |
| |
| |
| static __inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d) |
| { // Ken did this |
| d = ((a<0)*8) + ((b<0)*4) + ((c<0)*2) + (d<0); |
| return(((d<<4)^0xf0)|d); |
| } |
| |
| // |
| // krecip |
| // |
| int32_t krecip(int32_t num) |
| { |
| return(krecipasm(num)); |
| } |
| |
| uint16_t _swap16(uint16_t D) |
| { |
| return((D<<8)|(D>>8)); |
| } |
| |
| unsigned int _swap32(unsigned int D) |
| { |
| return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24)); |
| } |
| |
| /* |
| FCS: |
| Scan through sectors using portals (a portal is wall with a nextsector attribute >= 0). |
| Flood is prevented if a portal does not face the POV. |
| */ |
| static void scansector (short sectnum) |
| { |
| walltype *wal, *wal2; |
| spritetype *spr; |
| int32_t xs, ys, x1, y1, x2, y2, xp1, yp1, xp2=0, yp2=0, tempint; |
| short z, zz, startwall, endwall, numscansbefore, scanfirst, bunchfrst; |
| short nextsectnum; |
| |
| //The stack storing sectors to visit. |
| short sectorsToVisit[256], numSectorsToVisit; |
| |
| |
| if (sectnum < 0) |
| return; |
| |
| if (automapping) |
| show2dsector[sectnum>>3] |= pow2char[sectnum&7]; |
| |
| sectorsToVisit[0] = sectnum; |
| numSectorsToVisit = 1; |
| do |
| { |
| sectnum = sectorsToVisit[--numSectorsToVisit]; |
| |
| //Add every script in the current sector as potentially visible. |
| for(z=headspritesect[sectnum]; z>=0; z=nextspritesect[z]) |
| { |
| spr = &sprite[z]; |
| if ((((spr->cstat&0x8000) == 0) || (showinvisibility)) && |
| (spr->xrepeat > 0) && (spr->yrepeat > 0) && |
| (spritesortcnt < MAXSPRITESONSCREEN)) |
| { |
| xs = spr->x-globalposx; |
| ys = spr->y-globalposy; |
| if ((spr->cstat&48) || (xs*cosglobalang+ys*singlobalang > 0)) |
| { |
| copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype)); |
| tsprite[spritesortcnt++].owner = z; |
| } |
| } |
| } |
| |
| //Mark the current sector bit as "visited" in the bitvector |
| visitedSectors[sectnum>>3] |= pow2char[sectnum&7]; |
| |
| bunchfrst = numbunches; |
| numscansbefore = numscans; |
| |
| startwall = sector[sectnum].wallptr; |
| endwall = startwall + sector[sectnum].wallnum; |
| scanfirst = numscans; |
| for(z=startwall,wal=&wall[z]; z<endwall; z++,wal++) |
| { |
| nextsectnum = wal->nextsector; |
| |
| wal2 = &wall[wal->point2]; |
| |
| // In camera space the center is the player. |
| // Tranform the 2 Wall endpoints (x,y) from worldspace to camera space. |
| // After that we have two vectors starting from the camera and going to the endpoints (x1,y1) and (x2,y2). |
| x1 = wal->x-globalposx; |
| y1 = wal->y-globalposy; |
| |
| x2 = wal2->x-globalposx; |
| y2 = wal2->y-globalposy; |
| |
| // If this is a portal... |
| if ((nextsectnum >= 0) && ((wal->cstat&32) == 0)) |
| //If this portal has not been visited yet. |
| if ((visitedSectors[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0) |
| { |
| //Cross product -> Z component |
| tempint = x1*y2-x2*y1; |
| |
| // Using cross product, determine if the portal is facing us or not. |
| // If it is: Add it to the stack and bump the stack counter. |
| // This line is equivalent to tempint < 0x40000 |
| if (((uint32_t)tempint+262144) < 524288) // ??? What is this test ?? How acute the angle is ? |
| { |
| //(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1) is the squared length of the wall |
| // ??? What is this test ?? How acute the angle is ? |
| if (mulscale5(tempint,tempint) <= (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)) |
| sectorsToVisit[numSectorsToVisit++] = nextsectnum; |
| } |
| } |
| |
| // Rotate the wall endpoints vectors according to the player orientation. |
| // This is a regular rotation matrix using [29.3] fixed point. |
| if ((z == startwall) || (wall[z-1].point2 != z)) |
| { |
| //If this is the first endpoint of the bunch, rotate: This is a standard cos sin 2D rotation matrix projection |
| xp1 = dmulscale6(y1,cosglobalang,-x1,singlobalang); |
| yp1 = dmulscale6(x1,cosviewingrangeglobalang,y1,sinviewingrangeglobalang); |
| } |
| else |
| { |
| //If this is NOT the first endpoint, Save the coordinate for next loop. |
| xp1 = xp2; |
| yp1 = yp2; |
| } |
| |
| // Rotate: This is a standard cos sin 2D rotation matrix projection |
| xp2 = dmulscale6(y2,cosglobalang,-x2,singlobalang); |
| yp2 = dmulscale6(x2,cosviewingrangeglobalang,y2,sinviewingrangeglobalang); |
| |
| |
| |
| // Equivalent of a near plane clipping ? |
| if ((yp1 < 256) && (yp2 < 256)) goto skipitaddwall; |
| |
| /* If wall's NOT facing you */ |
| if (dmulscale32(xp1,yp2,-xp2,yp1) >= 0) goto skipitaddwall; |
| |
| // The wall is still not eligible for rendition: Let's do some more Frustrum culling !! |
| if (xp1 >= -yp1){ |
| |
| if ((xp1 > yp1) || (yp1 == 0)) |
| goto skipitaddwall; |
| |
| //Project the point onto screen and see in which column it belongs. |
| pvWalls[numscans].screenSpaceCoo[0][VEC_COL] = halfxdimen + scale(xp1,halfxdimen,yp1); |
| if (xp1 >= 0) |
| pvWalls[numscans].screenSpaceCoo[0][VEC_COL]++; /* Fix for SIGNED divide */ |
| |
| if (pvWalls[numscans].screenSpaceCoo[0][VEC_COL] >= xdimen) |
| pvWalls[numscans].screenSpaceCoo[0][VEC_COL] = xdimen-1; |
| |
| pvWalls[numscans].screenSpaceCoo[0][VEC_DIST] = yp1; |
| } |
| else{ |
| |
| if (xp2 < -yp2) |
| goto skipitaddwall; |
| |
| pvWalls[numscans].screenSpaceCoo[0][VEC_COL] = 0; |
| tempint = yp1-yp2+xp1-xp2; |
| |
| if (tempint == 0) |
| goto skipitaddwall; |
| |
| pvWalls[numscans].screenSpaceCoo[0][VEC_DIST] = yp1 + scale(yp2-yp1,xp1+yp1,tempint); |
| } |
| |
| if (pvWalls[numscans].screenSpaceCoo[0][VEC_DIST] < 256) |
| goto skipitaddwall; |
| |
| if (xp2 <= yp2){ |
| |
| if ((xp2 < -yp2) || (yp2 == 0)) goto skipitaddwall; |
| pvWalls[numscans].screenSpaceCoo[1][VEC_COL] = halfxdimen + scale(xp2,halfxdimen,yp2) - 1; |
| if (xp2 >= 0) pvWalls[numscans].screenSpaceCoo[1][VEC_COL]++; /* Fix for SIGNED divide */ |
| if (pvWalls[numscans].screenSpaceCoo[1][VEC_COL] >= xdimen) pvWalls[numscans].screenSpaceCoo[1][VEC_COL] = xdimen-1; |
| pvWalls[numscans].screenSpaceCoo[1][VEC_DIST] = yp2; |
| } |
| else{ |
| |
| if (xp1 > yp1) goto skipitaddwall; |
| pvWalls[numscans].screenSpaceCoo[1][VEC_COL] = xdimen-1; |
| tempint = xp2-xp1+yp1-yp2; |
| if (tempint == 0) goto skipitaddwall; |
| pvWalls[numscans].screenSpaceCoo[1][VEC_DIST] = yp1 + scale(yp2-yp1,yp1-xp1,tempint); |
| } |
| if ((pvWalls[numscans].screenSpaceCoo[1][VEC_DIST] < 256) || (pvWalls[numscans].screenSpaceCoo[0][VEC_COL] > pvWalls[numscans].screenSpaceCoo[1][VEC_COL])) goto skipitaddwall; |
| |
| // Made it all the way! |
| // Time to add this wall information to the stack of wall potentially visible. |
| pvWalls[numscans].sectorId = sectnum; |
| pvWalls[numscans].worldWallId = z; |
| |
| //Save the camera space wall endpoints coordinate (camera origin at player location + rotated according to player orientation). |
| pvWalls[numscans].cameraSpaceCoo[0][VEC_X] = xp1; |
| pvWalls[numscans].cameraSpaceCoo[0][VEC_Y] = yp1; |
| pvWalls[numscans].cameraSpaceCoo[1][VEC_X] = xp2; |
| pvWalls[numscans].cameraSpaceCoo[1][VEC_Y] = yp2; |
| |
| |
| bunchWallsList[numscans] = numscans+1; |
| numscans++; |
| |
| skipitaddwall: |
| |
| if ((wall[z].point2 < z) && (scanfirst < numscans)) |
| { |
| bunchWallsList[numscans-1] = scanfirst; |
| scanfirst = numscans; |
| } |
| } |
| |
| //FCS: TODO rename this p2[] to bunchList[] or something like that. This name is an abomination |
| // DONE, p2 is now called "bunchWallsList". |
| |
| //Break down the list of walls for this sector into bunchs. Since a bunch is a |
| // continuously visible list of wall: A sector can generate many bunches. |
| for(z=numscansbefore; z<numscans; z++) |
| { |
| if ((wall[pvWalls[z].worldWallId].point2 != |
| pvWalls[bunchWallsList[z]].worldWallId) || (pvWalls[z].screenSpaceCoo[1][VEC_COL] >= pvWalls[bunchWallsList[z]].screenSpaceCoo[0][VEC_COL])) |
| { |
| // Create an entry in the bunch list |
| bunchfirst[numbunches++] = bunchWallsList[z]; |
| |
| //Mark the end of the bunch wall list. |
| bunchWallsList[z] = -1; |
| } |
| } |
| |
| //For each bunch, find the last wall and cache it in bunchlast. |
| for(z=bunchfrst; z<numbunches; z++) |
| { |
| for(zz=bunchfirst[z]; bunchWallsList[zz]>=0; zz=bunchWallsList[zz]); |
| bunchlast[z] = zz; |
| } |
| |
| } while (numSectorsToVisit > 0); |
| // do this until the stack of sectors to visit if empty. |
| } |
| |
| /* |
| FCS: |
| |
| Goal : ???? |
| param 1: Z is the wallID in the list of potentially visible walls. |
| param 2: Only used to lookup the xrepeat attribute of the wall. |
| |
| */ |
| static void prepwall(int32_t z, walltype *wal) |
| { |
| int32_t i, l=0, ol=0, splc, sinc, x, topinc, top, botinc, bot, walxrepeat; |
| vector_t* wallCoo = pvWalls[z].cameraSpaceCoo; |
| |
| walxrepeat = (wal->xrepeat<<3); |
| |
| /* lwall calculation */ |
| i = pvWalls[z].screenSpaceCoo[0][VEC_COL]-halfxdimen; |
| |
| //Let's use some of the camera space wall coordinate now. |
| topinc = -(wallCoo[0][VEC_Y]>>2); |
| botinc = ((wallCoo[1][VEC_Y]-wallCoo[0][VEC_Y])>>8); |
| |
| top = mulscale5(wallCoo[0][VEC_X],xdimen)+mulscale2(topinc,i); |
| bot = mulscale11(wallCoo[0][VEC_X]-wallCoo[1][VEC_X],xdimen)+mulscale2(botinc,i); |
| |
| splc = mulscale19(wallCoo[0][VEC_Y],xdimscale); |
| sinc = mulscale16(wallCoo[1][VEC_Y]-wallCoo[0][VEC_Y],xdimscale); |
| |
| //X screenspce column of point Z. |
| x = pvWalls[z].screenSpaceCoo[0][VEC_COL]; |
| |
| if (bot != 0) |
| { |
| l = divscale12(top,bot); |
| swall[x] = mulscale21(l,sinc)+splc; |
| l *= walxrepeat; |
| lwall[x] = (l>>18); |
| } |
| |
| //If the wall is less than 4 column wide. |
| while (x+4 <= pvWalls[z].screenSpaceCoo[1][VEC_COL]) |
| { |
| top += topinc; |
| bot += botinc; |
| if (bot != 0) |
| { |
| ol = l; |
| l = divscale12(top,bot); |
| swall[x+4] = mulscale21(l,sinc)+splc; |
| l *= walxrepeat; |
| lwall[x+4] = (l>>18); |
| } |
| i = ((ol+l)>>1); |
| lwall[x+2] = (i>>18); |
| lwall[x+1] = ((ol+i)>>19); |
| lwall[x+3] = ((l+i)>>19); |
| swall[x+2] = ((swall[x]+swall[x+4])>>1); |
| swall[x+1] = ((swall[x]+swall[x+2])>>1); |
| swall[x+3] = ((swall[x+4]+swall[x+2])>>1); |
| x += 4; |
| } |
| |
| //If the wall is less than 2 columns wide. |
| if (x+2 <= pvWalls[z].screenSpaceCoo[1][VEC_COL]) |
| { |
| top += (topinc>>1); |
| bot += (botinc>>1); |
| if (bot != 0) |
| { |
| ol = l; |
| l = divscale12(top,bot); |
| swall[x+2] = mulscale21(l,sinc)+splc; |
| l *= walxrepeat; |
| lwall[x+2] = (l>>18); |
| } |
| lwall[x+1] = ((l+ol)>>19); |
| swall[x+1] = ((swall[x]+swall[x+2])>>1); |
| x += 2; |
| } |
| |
| //The wall is 1 column wide. |
| if (x+1 <= pvWalls[z].screenSpaceCoo[1][VEC_COL]) |
| { |
| bot += (botinc>>2); |
| if (bot != 0) |
| { |
| l = divscale12(top+(topinc>>2),bot); |
| swall[x+1] = mulscale21(l,sinc)+splc; |
| lwall[x+1] = mulscale18(l,walxrepeat); |
| } |
| } |
| |
| if (lwall[pvWalls[z].screenSpaceCoo[0][VEC_COL]] < 0) |
| lwall[pvWalls[z].screenSpaceCoo[0][VEC_COL]] = 0; |
| |
| if ((lwall[pvWalls[z].screenSpaceCoo[1][VEC_COL]] >= walxrepeat) && (walxrepeat)) |
| lwall[pvWalls[z].screenSpaceCoo[1][VEC_COL]] = walxrepeat-1; |
| |
| if (wal->cstat&8) |
| { |
| walxrepeat--; |
| for(x=pvWalls[z].screenSpaceCoo[0][VEC_COL]; x<=pvWalls[z].screenSpaceCoo[1][VEC_COL]; x++) |
| lwall[x] = walxrepeat-lwall[x]; |
| } |
| } |
| |
| |
| static int32_t getpalookup(int32_t davis, int32_t dashade) |
| { |
| return(min(max(dashade+(davis>>8),0),numpalookups-1)); |
| } |
| |
| |
| static void hline (int32_t xr, int32_t yp) |
| { |
| int32_t xl, r, s; |
| |
| xl = lastx[yp]; |
| |
| if (xl > xr) |
| return; |
| |
| r = horizlookup2[yp-globalhoriz+horizycent]; |
| asm1 = globalx1*r; |
| asm2 = globaly2*r; |
| s = (getpalookup(mulscale16(r,globvis),globalshade)<<8); |
| |
| hlineasm4(xr-xl,s,globalx2*r+globalypanning,globaly1*r+globalxpanning,ylookup[yp]+xr+frameoffset); |
| } |
| |
| |
| static void slowhline (int32_t xr, int32_t yp) |
| { |
| int32_t xl, r; |
| |
| xl = lastx[yp]; |
| if (xl > xr) return; |
| r = horizlookup2[yp-globalhoriz+horizycent]; |
| asm1 = globalx1*r; |
| asm2 = globaly2*r; |
| |
| asm3 = (int32_t)globalpalwritten + (getpalookup(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); |
| } |
| |
| |
| |
| |
| |
| /* renders non-parallaxed ceilings. --ryan. */ |
| static void ceilscan (int32_t x1, int32_t x2, int32_t sectnum) |
| { |
| int32_t i, j, ox, oy, x, y1, y2, twall, bwall; |
| sectortype *sec; |
| |
| sec = §or[sectnum]; |
| |
| if (palookup[sec->ceilingpal] != globalpalwritten) |
| globalpalwritten = palookup[sec->ceilingpal]; |
| |
| |
| globalzd = sec->ceilingz-globalposz; |
| |
| |
| if (globalzd > 0) |
| return; |
| |
| |
| globalpicnum = sec->ceilingpicnum; |
| |
| if ((uint32_t)globalpicnum >= (uint32_t)MAXTILES) |
| globalpicnum = 0; |
| |
| setgotpic(globalpicnum); |
| |
| //Check the tile dimension are valid. |
| if ((tiles[globalpicnum].dim.width <= 0) || |
| (tiles[globalpicnum].dim.height <= 0)) |
| return; |
| |
| if (tiles[globalpicnum].animFlags&192) |
| globalpicnum += animateoffs(globalpicnum); |
| |
| TILE_MakeAvailable(globalpicnum); |
| |
| globalbufplc = tiles[globalpicnum].data; |
| |
| globalshade = (int32_t)sec->ceilingshade; |
| globvis = globalcisibility; |
| if (sec->visibility != 0) |
| globvis = mulscale4(globvis,(int32_t)((uint8_t )(sec->visibility+16))); |
| |
| globalorientation = (int32_t)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 += (((int32_t)sec->ceilingxpanning)<<24); |
| globalypanning += (((int32_t)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: |
| settrans(TRANS_NORMAL); |
| tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); |
| break; |
| case 384: |
| settrans(TRANS_REVERSE); |
| 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 (int32_t x1, int32_t x2, int32_t sectnum) |
| { |
| int32_t i, j, ox, oy, x, y1, y2, twall, bwall; |
| sectortype *sec; |
| |
| //Retrieve the sector object |
| sec = §or[sectnum]; |
| |
| //Retrieve the floor palette. |
| if (palookup[sec->floorpal] != globalpalwritten) |
| globalpalwritten = palookup[sec->floorpal]; |
| |
| globalzd = globalposz-sec->floorz; |
| |
| //We are UNDER the floor: Do NOT render anything. |
| if (globalzd > 0) |
| return; |
| |
| //Retrive the floor texture. |
| globalpicnum = sec->floorpicnum; |
| if ((uint32_t)globalpicnum >= (uint32_t)MAXTILES) |
| globalpicnum = 0; |
| |
| //Lock the floor texture |
| setgotpic(globalpicnum); |
| |
| |
| //This tile has unvalid dimensions ( negative) |
| if ((tiles[globalpicnum].dim.width <= 0) || |
| (tiles[globalpicnum].dim.height <= 0)) |
| return; |
| |
| //If this is an animated texture: Animate it. |
| if (tiles[globalpicnum].animFlags&192) |
| globalpicnum += animateoffs(globalpicnum); |
| |
| //If the texture is not in RAM: Load it !! |
| TILE_MakeAvailable(globalpicnum); |
| |
| //Check where is the texture in RAM |
| globalbufplc = tiles[globalpicnum].data; |
| |
| //Retrieve the shade of the sector (illumination level). |
| globalshade = (int32_t)sec->floorshade; |
| |
| globvis = globalcisibility; |
| if (sec->visibility != 0) |
| globvis = mulscale4(globvis,(int32_t)((uint8_t)(sec->visibility+16))); |
| |
| |
| globalorientation = (int32_t)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 += (((int32_t)sec->floorxpanning)<<24); |
| globalypanning += (((int32_t)sec->floorypanning)<<24); |
| globaly1 = (-globalx1-globaly1)*halfxdimen; |
| globalx2 = (globalx2-globaly2)*halfxdimen; |
| |
| //Setup the drawing routine paramters |
| 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: |
| settrans(TRANS_NORMAL); |
| tsethlineshift(picsiz[globalpicnum]&15,picsiz[globalpicnum]>>4); |
| break; |
| case 384: |
| settrans(TRANS_REVERSE); |
| 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(int32_t x1, int32_t x2, |
| int16_t *uwal, int16_t *dwal, |
| int32_t *swal, int32_t *lwal) |
| { |
| int32_t x, xnice, ynice; |
| intptr_t i; |
| uint8_t* fpalookup; |
| int32_t y1ve[4], y2ve[4], u4, d4, z, tileWidth, tsizy; |
| uint8_t bad; |
| |
| tileWidth = tiles[globalpicnum].dim.width; |
| tsizy = tiles[globalpicnum].dim.height; |
| |
| setgotpic(globalpicnum); |
| |
| if ((tileWidth <= 0) || (tsizy <= 0)) |
| return; |
| |
| if ((uwal[x1] > ydimen) && (uwal[x2] > ydimen)) |
| return; |
| |
| if ((dwal[x1] < 0) && (dwal[x2] < 0)) |
| return; |
| |
| TILE_MakeAvailable(globalpicnum); |
| |
| xnice = (pow2long[picsiz[globalpicnum]&15] == tileWidth); |
| if (xnice) |
| tileWidth--; |
| |
| ynice = (pow2long[picsiz[globalpicnum]>>4] == tsizy); |
| if (ynice) |
| tsizy = (picsiz[globalpicnum]>>4); |
| |
| fpalookup = palookup[globalpal]; |
| |
| setupvlineasm(globalshiftval); |
| |
| //Starting on the left column of the wall, check the occlusion arrays. |
| x = x1; |
| while ((umost[x] > dmost[x]) && (x <= x2)) |
| x++; |
| |
| for(; (x<=x2)&&((x+frameoffset-(uint8_t*)NULL)&3); x++) |
| { |
| y1ve[0] = max(uwal[x],umost[x]); |
| y2ve[0] = min(dwal[x],dmost[x]); |
| if (y2ve[0] <= y1ve[0]) |
| continue; |
| |
| palookupoffse[0] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x],globvis),globalshade)<<8); |
| |
| bufplce[0] = lwal[x] + globalxpanning; |
| |
| if (bufplce[0] >= tileWidth) |
| { |
| if (xnice == 0) |
| bufplce[0] %= tileWidth; |
| else |
| bufplce[0] &= tileWidth; |
| } |
| |
| if (ynice == 0) |
| bufplce[0] *= tsizy; |
| else |
| bufplce[0] <<= tsizy; |
| |
| vince[0] = swal[x]*globalyscale; |
| vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); |
| |
| vlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+tiles[globalpicnum].data,x+frameoffset+ylookup[y1ve[0]]); |
| } |
| |
| for(; x<=x2-3; x+=4) |
| { |
| bad = 0; |
| for(z=3; z>=0; z--) |
| { |
| y1ve[z] = max(uwal[x+z],umost[x+z]); |
| y2ve[z] = min(dwal[x+z],dmost[x+z])-1; |
| |
| if (y2ve[z] < y1ve[z]) |
| { |
| bad += pow2char[z]; |
| continue; |
| } |
| |
| i = lwal[x+z] + globalxpanning; |
| if (i >= tileWidth) { |
| if (xnice == 0) i %= tileWidth; |
| else i &= tileWidth; |
| } |
| if (ynice == 0) |
| i *= tsizy; |
| else |
| i <<= tsizy; |
| bufplce[z] = tiles[globalpicnum].data+i; |
| |
| vince[z] = swal[x+z]*globalyscale; |
| vplce[z] = globalzd + vince[z]*(y1ve[z]-globalhoriz+1); |
| } |
| |
| if (bad == 15) |
| continue; |
| |
| palookupoffse[0] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x],globvis),globalshade)<<8); |
| palookupoffse[3] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x+3],globvis),globalshade)<<8); |
| |
| if ((palookupoffse[0] == palookupoffse[3]) && ((bad&0x9) == 0)) |
| { |
| palookupoffse[1] = palookupoffse[0]; |
| palookupoffse[2] = palookupoffse[0]; |
| } |
| else |
| { |
| palookupoffse[1] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x+1],globvis),globalshade)<<8); |
| palookupoffse[2] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x+2],globvis),globalshade)<<8); |
| } |
| |
| u4 = max(max(y1ve[0],y1ve[1]),max(y1ve[2],y1ve[3])); |
| d4 = min(min(y2ve[0],y2ve[1]),min(y2ve[2],y2ve[3])); |
| |
| if ((bad != 0) || (u4 >= d4)) |
| { |
| if (!(bad&1)) |
| prevlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0],vplce[0],bufplce[0],ylookup[y1ve[0]]+x+frameoffset+0); |
| if (!(bad&2)) |
| prevlineasm1(vince[1],palookupoffse[1],y2ve[1]-y1ve[1],vplce[1],bufplce[1],ylookup[y1ve[1]]+x+frameoffset+1); |
| if (!(bad&4)) |
| prevlineasm1(vince[2],palookupoffse[2],y2ve[2]-y1ve[2],vplce[2],bufplce[2],ylookup[y1ve[2]]+x+frameoffset+2); |
| if (!(bad&8)) |
| prevlineasm1(vince[3],palookupoffse[3],y2ve[3]-y1ve[3],vplce[3],bufplce[3],ylookup[y1ve[3]]+x+frameoffset+3); |
| continue; |
| } |
| |
| if (u4 > y1ve[0]) |
| vplce[0] =prevlineasm1(vince[0],palookupoffse[0],u4-y1ve[0]-1,vplce[0],bufplce[0],ylookup[y1ve[0]]+x+frameoffset+0); |
| if (u4 > y1ve[1]) |
| vplce[1] = prevlineasm1(vince[1],palookupoffse[1],u4-y1ve[1]-1,vplce[1],bufplce[1],ylookup[y1ve[1]]+x+frameoffset+1); |
| if (u4 > y1ve[2]) |
| vplce[2] = prevlineasm1(vince[2],palookupoffse[2],u4-y1ve[2]-1,vplce[2],bufplce[2],ylookup[y1ve[2]]+x+frameoffset+2); |
| if (u4 > y1ve[3]) |
| vplce[3] = prevlineasm1(vince[3],palookupoffse[3],u4-y1ve[3]-1,vplce[3],bufplce[3],ylookup[y1ve[3]]+x+frameoffset+3); |
| |
| if (d4 >= u4) |
| vlineasm4(d4-u4+1,ylookup[u4]+x+frameoffset); |
| |
| i = x+frameoffset+ylookup[d4+1]; |
| |
| if (y2ve[0] > d4) |
| prevlineasm1(vince[0],palookupoffse[0],y2ve[0]-d4-1,vplce[0],bufplce[0],i+0); |
| if (y2ve[1] > d4) |
| prevlineasm1(vince[1],palookupoffse[1],y2ve[1]-d4-1,vplce[1],bufplce[1],i+1); |
| if (y2ve[2] > d4) |
| prevlineasm1(vince[2],palookupoffse[2],y2ve[2]-d4-1,vplce[2],bufplce[2],i+2); |
| if (y2ve[3] > d4) |
| prevlineasm1(vince[3],palookupoffse[3],y2ve[3]-d4-1,vplce[3],bufplce[3],i+3); |
| } |
| for(; x<=x2; x++) |
| { |
| y1ve[0] = max(uwal[x],umost[x]); |
| y2ve[0] = min(dwal[x],dmost[x]); |
| if (y2ve[0] <= y1ve[0]) |
| continue; |
| |
| palookupoffse[0] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x],globvis),globalshade)<<8); |
| |
| bufplce[0] = lwal[x] + globalxpanning; |
| if (bufplce[0] >= tileWidth) { |
| if (xnice == 0) |
| bufplce[0] %= tileWidth; |
| else |
| bufplce[0] &= tileWidth; |
| } |
| |
| if (ynice == 0) bufplce[0] |
| *= tsizy; |
| else |
| bufplce[0] <<= tsizy; |
| |
| vince[0] = swal[x]*globalyscale; |
| vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); |
| |
| vlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+tiles[globalpicnum].data,x+frameoffset+ylookup[y1ve[0]]); |
| } |
| faketimerhandler(); |
| } |
| |
| |
| /* this renders masking sprites. See wallscan(). --ryan. */ |
| static void maskwallscan(int32_t x1, int32_t x2, |
| short *uwal, short *dwal, |
| int32_t *swal, int32_t *lwal) |
| { |
| int32_t x, startx, xnice, ynice; |
| intptr_t i; |
| uint8_t* fpalookup; |
| int32_t y1ve[4], y2ve[4], u4, d4, dax, z, tileWidth, tileHeight; |
| uint8_t* p; |
| uint8_t bad; |
| |
| tileWidth = tiles[globalpicnum].dim.width; |
| tileHeight = tiles[globalpicnum].dim.height; |
| setgotpic(globalpicnum); |
| |
| if ((tileWidth <= 0) || (tileHeight <= 0)) |
| return; |
| if ((uwal[x1] > ydimen) && (uwal[x2] > ydimen)) |
| return; |
| if ((dwal[x1] < 0) && (dwal[x2] < 0)) |
| return; |
| |
| TILE_MakeAvailable(globalpicnum); |
| |
| startx = x1; |
| |
| xnice = (pow2long[picsiz[globalpicnum]&15] == tileWidth); |
| if (xnice) |
| tileWidth = (tileWidth-1); |
| |
| ynice = (pow2long[picsiz[globalpicnum]>>4] == tileHeight); |
| if (ynice) |
| tileHeight = (picsiz[globalpicnum]>>4); |
| |
| fpalookup = palookup[globalpal]; |
| |
| setupmvlineasm(globalshiftval); |
| |
| x = startx; |
| while ((startumost[x+windowx1] > startdmost[x+windowx1]) && (x <= x2)) x++; |
| |
| p = x+frameoffset; |
| |
| for(; (x<=x2)&&((p-(uint8_t*)NULL)&3); x++,p++) |
| { |
| y1ve[0] = max(uwal[x],startumost[x+windowx1]-windowy1); |
| y2ve[0] = min(dwal[x],startdmost[x+windowx1]-windowy1); |
| if (y2ve[0] <= y1ve[0]) continue; |
| |
| palookupoffse[0] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x],globvis),globalshade)<<8); |
| |
| bufplce[0] = lwal[x] + globalxpanning; |
| if (bufplce[0] >= tileWidth) { |
| if (xnice == 0) bufplce[0] %= tileWidth; |
| else bufplce[0] &= tileWidth; |
| } |
| if (ynice == 0) |
| bufplce[0] *= tileHeight; |
| else |
| bufplce[0] <<= tileHeight; |
| |
| vince[0] = swal[x]*globalyscale; |
| vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); |
| |
| mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+tiles[globalpicnum].data,p+ylookup[y1ve[0]]); |
| } |
| for(; x<=x2-3; x+=4,p+=4) |
| { |
| bad = 0; |
| for(z=3,dax=x+3; z>=0; z--,dax--) |
| { |
| y1ve[z] = max(uwal[dax],startumost[dax+windowx1]-windowy1); |
| y2ve[z] = min(dwal[dax],startdmost[dax+windowx1]-windowy1)-1; |
| if (y2ve[z] < y1ve[z]) { |
| bad += pow2char[z]; |
| continue; |
| } |
| |
| i = lwal[dax] + globalxpanning; |
| if (i >= tileWidth) { |
| if (xnice == 0) i %= tileWidth; |
| else i &= tileWidth; |
| } |
| |
| if (ynice == 0) |
| i *= tileHeight; |
| else |
| i <<= tileHeight; |
| |
| bufplce[z] = tiles[globalpicnum].data+i; |
| |
| vince[z] = swal[dax]*globalyscale; |
| vplce[z] = globalzd + vince[z]*(y1ve[z]-globalhoriz+1); |
| } |
| if (bad == 15) continue; |
| |
| palookupoffse[0] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x],globvis),globalshade)<<8); |
| palookupoffse[3] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x+3],globvis),globalshade)<<8); |
| |
| if ((palookupoffse[0] == palookupoffse[3]) && ((bad&0x9) == 0)) |
| { |
| palookupoffse[1] = palookupoffse[0]; |
| palookupoffse[2] = palookupoffse[0]; |
| } |
| else |
| { |
| palookupoffse[1] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x+1],globvis),globalshade)<<8); |
| palookupoffse[2] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x+2],globvis),globalshade)<<8); |
| } |
| |
| u4 = max(max(y1ve[0],y1ve[1]),max(y1ve[2],y1ve[3])); |
| d4 = min(min(y2ve[0],y2ve[1]),min(y2ve[2],y2ve[3])); |
| |
| if ((bad > 0) || (u4 >= d4)) |
| { |
| if (!(bad&1)) mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0],vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); |
| if (!(bad&2)) mvlineasm1(vince[1],palookupoffse[1],y2ve[1]-y1ve[1],vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); |
| if (!(bad&4)) mvlineasm1(vince[2],palookupoffse[2],y2ve[2]-y1ve[2],vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); |
| if (!(bad&8)) mvlineasm1(vince[3],palookupoffse[3],y2ve[3]-y1ve[3],vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); |
| continue; |
| } |
| |
| if (u4 > y1ve[0]) vplce[0] = mvlineasm1(vince[0],palookupoffse[0],u4-y1ve[0]-1,vplce[0],bufplce[0],ylookup[y1ve[0]]+p+0); |
| if (u4 > y1ve[1]) vplce[1] = mvlineasm1(vince[1],palookupoffse[1],u4-y1ve[1]-1,vplce[1],bufplce[1],ylookup[y1ve[1]]+p+1); |
| if (u4 > y1ve[2]) vplce[2] = mvlineasm1(vince[2],palookupoffse[2],u4-y1ve[2]-1,vplce[2],bufplce[2],ylookup[y1ve[2]]+p+2); |
| if (u4 > y1ve[3]) vplce[3] = mvlineasm1(vince[3],palookupoffse[3],u4-y1ve[3]-1,vplce[3],bufplce[3],ylookup[y1ve[3]]+p+3); |
| |
| if (d4 >= u4) mvlineasm4(d4-u4+1,ylookup[u4]+p); |
| |
| i = p+ylookup[d4+1]; |
| if (y2ve[0] > d4) mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-d4-1,vplce[0],bufplce[0],i+0); |
| if (y2ve[1] > d4) mvlineasm1(vince[1],palookupoffse[1],y2ve[1]-d4-1,vplce[1],bufplce[1],i+1); |
| if (y2ve[2] > d4) mvlineasm1(vince[2],palookupoffse[2],y2ve[2]-d4-1,vplce[2],bufplce[2],i+2); |
| if (y2ve[3] > d4) mvlineasm1(vince[3],palookupoffse[3],y2ve[3]-d4-1,vplce[3],bufplce[3],i+3); |
| } |
| for(; x<=x2; x++,p++) |
| { |
| y1ve[0] = max(uwal[x],startumost[x+windowx1]-windowy1); |
| y2ve[0] = min(dwal[x],startdmost[x+windowx1]-windowy1); |
| if (y2ve[0] <= y1ve[0]) continue; |
| |
| palookupoffse[0] = fpalookup+(getpalookup((int32_t)mulscale16(swal[x],globvis),globalshade)<<8); |
| |
| bufplce[0] = lwal[x] + globalxpanning; |
| if (bufplce[0] >= tileWidth) { |
| if (xnice == 0) bufplce[0] %= tileWidth; |
| else bufplce[0] &= tileWidth; |
| } |
| if (ynice == 0) |
| bufplce[0] *= tileHeight; |
| else |
| bufplce[0] <<= tileHeight; |
| |
| vince[0] = swal[x]*globalyscale; |
| vplce[0] = globalzd + vince[0]*(y1ve[0]-globalhoriz+1); |
| |
| mvlineasm1(vince[0],palookupoffse[0],y2ve[0]-y1ve[0]-1,vplce[0],bufplce[0]+tiles[globalpicnum].data,p+ylookup[y1ve[0]]); |
| } |
| faketimerhandler(); |
| } |
| |
| /* renders parallaxed skies/floors --ryan. */ |
| static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum,uint8_t dastat, int32_t bunch) |
| { |
| sectortype *sec; |
| int32_t j, k, l, m, n, x, z, wallnum, nextsectnum, globalhorizbak; |
| short *topptr, *botptr; |
| |
| sectnum = pvWalls[bunchfirst[bunch]].sectorId; |
| sec = §or[sectnum]; |
| |
| globalhorizbak = globalhoriz; |
| if (parallaxyscale != 65536) |
| globalhoriz = mulscale16(globalhoriz-(ydimen>>1),parallaxyscale) + (ydimen>>1); |
| globvis = globalpisibility; |
| /* globalorientation = 0L; */ |
| if (sec->visibility != 0) globvis = mulscale4(globvis,(int32_t)((uint8_t )(sec->visibility+16))); |
| |
| if (dastat == 0) |
| { |
| globalpal = sec->ceilingpal; |
| globalpicnum = sec->ceilingpicnum; |
| globalshade = (int32_t)sec->ceilingshade; |
| globalxpanning = (int32_t)sec->ceilingxpanning; |
| globalypanning = (int32_t)sec->ceilingypanning; |
| topptr = umost; |
| botptr = uplc; |
| } |
| else |
| { |
| globalpal = sec->floorpal; |
| globalpicnum = sec->floorpicnum; |
| globalshade = (int32_t)sec->floorshade; |
| globalxpanning = (int32_t)sec->floorxpanning; |
| globalypanning = (int32_t)sec->floorypanning; |
| topptr = dplc; |
| botptr = dmost; |
| } |
| |
| if ((uint32_t)globalpicnum >= (uint32_t)MAXTILES) globalpicnum = 0; |
| |
| if (tiles[globalpicnum].animFlags&192) |
| globalpicnum += animateoffs(globalpicnum); |
| |
| globalshiftval = (picsiz[globalpicnum]>>4); |
| |
| if (pow2long[globalshiftval] != tiles[globalpicnum].dim.height) |
| globalshiftval++; |
| globalshiftval = 32-globalshiftval; |
| globalzd = (((tiles[globalpicnum].dim.height>>1)+parallaxyoffs)<<globalshiftval)+(globalypanning<<24); |
| globalyscale = (8<<(globalshiftval-19)); |
| /*if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd;*/ |
| |
| k = 11 - (picsiz[globalpicnum]&15) - pskybits; |
| x = -1; |
| |
| for(z=bunchfirst[bunch]; z>=0; z=bunchWallsList[z]) |
| { |
| wallnum = pvWalls[z].worldWallId; |
| nextsectnum = wall[wallnum].nextsector; |
| |
| if (dastat == 0) j = sector[nextsectnum].ceilingstat; |
| else j = sector[nextsectnum].floorstat; |
| |
| if ((nextsectnum < 0) || (wall[wallnum].cstat&32) || ((j&1) == 0)) |
| { |
| if (x == -1) x = pvWalls[z].screenSpaceCoo[0][VEC_COL]; |
| |
| if (parallaxtype == 0) |
| { |
| n = mulscale16(xdimenrecip,viewingrange); |
| for(j=pvWalls[z].screenSpaceCoo[0][VEC_COL]; j<=pvWalls[z].screenSpaceCoo[1][VEC_COL]; j++) |
| lplc[j] = (((mulscale23(j-halfxdimen,n)+globalang)&2047)>>k); |
| } |
| else |
| { |
| for(j=pvWalls[z].screenSpaceCoo[0][VEC_COL]; j<=pvWalls[z].screenSpaceCoo[1][VEC_COL]; j++) |
| lplc[j] = ((((int32_t)radarang2[j]+globalang)&2047)>>k); |
| } |
| if (parallaxtype == 2) |
| { |
| n = mulscale16(xdimscale,viewingrange); |
| for(j=pvWalls[z].screenSpaceCoo[0][VEC_COL]; j<=pvWalls[z].screenSpaceCoo[1][VEC_COL]; j++) |
| swplc[j] = mulscale14(sintable[((int32_t)radarang2[j]+512)&2047],n); |
| } |
| else |
| clearbuf(&swplc[pvWalls[z].screenSpaceCoo[0][VEC_COL]],pvWalls[z].screenSpaceCoo[1][VEC_COL]-pvWalls[z].screenSpaceCoo[0][VEC_COL]+1,mulscale16(xdimscale,viewingrange)); |
| } |
| else if (x >= 0) |
| { |
| l = globalpicnum; |
| m = (picsiz[globalpicnum]&15); |
| globalpicnum = l+pskyoff[lplc[x]>>m]; |
| |
| if (((lplc[x]^lplc[pvWalls[z].screenSpaceCoo[0][VEC_COL]-1])>>m) == 0) |
| wallscan(x,pvWalls[z].screenSpaceCoo[0][VEC_COL]-1,topptr,botptr,swplc,lplc); |
| else |
| { |
| j = x; |
| while (x < pvWalls[z].screenSpaceCoo[0][VEC_COL]) |
| { |
| n = l+pskyoff[lplc[x]>>m]; |
| if (n != globalpicnum) |
| { |
| wallscan(j,x-1,topptr,botptr,swplc,lplc); |
| j = x; |
| globalpicnum = n; |
| } |
| x++; |
| } |
| if (j < x) |
| wallscan(j,x-1,topptr,botptr,swplc,lplc); |
| } |
| |
| globalpicnum = l; |
| x = -1; |
| } |
| } |
| |
| if (x >= 0) |
| { |
| l = globalpicnum; |
| m = (picsiz[globalpicnum]&15); |
| globalpicnum = l+pskyoff[lplc[x]>>m]; |
| |
| if (((lplc[x]^lplc[pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL]])>>m) == 0) |
| wallscan(x,pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL],topptr,botptr,swplc,lplc); |
| else |
| { |
| j = x; |
| while (x <= pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL]) |
| { |
| n = l+pskyoff[lplc[x]>>m]; |
| if (n != globalpicnum) |
| { |
| wallscan(j,x-1,topptr,botptr,swplc,lplc); |
| j = x; |
| globalpicnum = n; |
| } |
| x++; |
| } |
| if (j <= x) |
| wallscan(j,x,topptr,botptr,swplc,lplc); |
| } |
| globalpicnum = l; |
| } |
| globalhoriz = globalhorizbak; |
| } |
| |
| |
| #define BITSOFPRECISION 3 /* Don't forget to change this in A.ASM also! */ |
| static void grouscan (int32_t dax1, int32_t dax2, int32_t sectnum, uint8_t dastat) |
| { |
| int32_t i, j, l, x, y, dx, dy, wx, wy, y1, y2, daz; |
| int32_t daslope, dasqr; |
| int32_t shoffs, shinc, m1, m2, *mptr1, *mptr2, *nptr1, *nptr2; |
| walltype *wal; |
| sectortype *sec; |
| |
| sec = §or[sectnum]; |
| |
| if (dastat == 0) |
| { |
| if (globalposz <= getceilzofslope((short) sectnum,globalposx,globalposy)) |
| return; /* Back-face culling */ |
| globalorientation = sec->ceilingstat; |
| globalpicnum = sec->ceilingpicnum; |
| globalshade = sec->ceilingshade; |
| globalpal = sec->ceilingpal; |
| daslope = sec->ceilingheinum; |
| daz = sec->ceilingz; |
| } |
| else |
| { |
| if (globalposz >= getflorzofslope((short) sectnum,globalposx,globalposy)) |
| return; /* Back-face culling */ |
| globalorientation = sec->floorstat; |
| globalpicnum = sec->floorpicnum; |
| globalshade = sec->floorshade; |
| globalpal = sec->floorpal; |
| daslope = sec->floorheinum; |
| daz = sec->floorz; |
| } |
| |
| if ((tiles[globalpicnum].animFlags&192) != 0) |
| globalpicnum += animateoffs(globalpicnum); |
| |
| setgotpic(globalpicnum); |
| |
| if ((tiles[globalpicnum].dim.width <= 0) || |
| (tiles[globalpicnum].dim.height <= 0)) |
| return; |
| |
| TILE_MakeAvailable(globalpicnum); |
| |
| wal = &wall[sec->wallptr]; |
| wx = wall[wal->point2].x - wal->x; |
| wy = wall[wal->point2].y - wal->y; |
| dasqr = krecipasm(nsqrtasm(wx*wx+wy*wy)); |
| i = mulscale21(daslope,dasqr); |
| wx *= i; |
| wy *= i; |
| |
| globalx = -mulscale19(singlobalang,xdimenrecip); |
| 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 += (((int32_t)sec->ceilingxpanning)<<24); |
| globaly1 += (((int32_t)sec->ceilingypanning)<<24); |
| } |
| else |
| { |
| globalx1 += (((int32_t)sec->floorxpanning)<<24); |
| globaly1 += (((int32_t)sec->floorypanning)<<24); |
| } |
| |
| asm1 = -(globalzd>>(16-BITSOFPRECISION)); |
| |
| globvis = globalvisibility; |
| if (sec->visibility != 0) globvis = mulscale4(globvis,(int32_t)((uint8_t )(sec->visibility+16))); |
| globvis = mulscale13(globvis,daz); |
| globvis = mulscale16(globvis,xdimscale); |
| j =(int32_t) FP_OFF(palookup[globalpal]); |
| |
| setupslopevlin(((int32_t)(picsiz[globalpicnum]&15))+(((int32_t)(picsiz[globalpicnum]>>4))<<8),tiles[globalpicnum].data,-ylookup[1]); |
| |
| l = (globalzd>>16); |
| |
| shinc = mulscale16(globalz,xdimenscale); |
| if (shinc > 0) |
| shoffs = (4<<15); |
| else |
| shoffs = ((16380-ydimen)<<15); // JBF: was 2044 16380 |
| 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 = (int32_t *)&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 = (int32_t *)&slopalookup[y1+(shoffs>>15)]; |
| nptr2 = (int32_t *)&slopalookup[y2+(shoffs>>15)]; |
| while (nptr1 <= mptr1) |
| { |
| *mptr1-- = j + (getpalookup((int32_t)mulscale24(krecipasm(m1),globvis),globalshade)<<8); |
| m1 -= l; |
| } |
| while (nptr2 >= mptr2) |
| { |
| *mptr2++ = j + (getpalookup((int32_t)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),(int32_t)nptr2,y2-y1+1,globalx1,globaly1); |
| |
| if ((x&15) == 0) faketimerhandler(); |
| } |
| globalx2 += globalx; |
| globaly2 += globaly; |
| globalzx += globalz; |
| shoffs += shinc; |
| } |
| } |
| |
| |
| static int owallmost(short *mostbuf, int32_t w, int32_t z) |
| { |
| int32_t bad, inty, xcross, y, yinc; |
| int32_t s1, s2, s3, s4, ix1, ix2, iy1, iy2, t; |
| |
| z <<= 7; |
| s1 = mulscale20(globaluclip,pvWalls[w].screenSpaceCoo[0][VEC_DIST]); |
| s2 = mulscale20(globaluclip,pvWalls[w].screenSpaceCoo[1][VEC_DIST]); |
| s3 = mulscale20(globaldclip,pvWalls[w].screenSpaceCoo[0][VEC_DIST]); |
| s4 = mulscale20(globaldclip,pvWalls[w].screenSpaceCoo[1][VEC_DIST]); |
| bad = (z<s1)+((z<s2)<<1)+((z>s3)<<2)+((z>s4)<<3); |
| |
| ix1 = pvWalls[w].screenSpaceCoo[0][VEC_COL]; |
| iy1 = pvWalls[w].screenSpaceCoo[0][VEC_DIST]; |
| ix2 = pvWalls[w].screenSpaceCoo[1][VEC_COL]; |
| iy2 = pvWalls[w].screenSpaceCoo[1][VEC_DIST]; |
| |
| 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 = pvWalls[w].screenSpaceCoo[0][VEC_DIST] + mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST]-pvWalls[w].screenSpaceCoo[0][VEC_DIST],t); |
| xcross = pvWalls[w].screenSpaceCoo[0][VEC_COL] + scale(mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST],t),pvWalls[w].screenSpaceCoo[1][VEC_COL]-pvWalls[w].screenSpaceCoo[0][VEC_COL],inty); |
| |
| if ((bad&3) == 2) |
| { |
| if (pvWalls[w].screenSpaceCoo[0][VEC_COL] <= xcross) { |
| iy2 = inty; |
| ix2 = xcross; |
| } |
| clearbufbyte(&mostbuf[xcross+1],(pvWalls[w].screenSpaceCoo[1][VEC_COL]-xcross)*sizeof(mostbuf[0]),0L); |
| } |
| else |
| { |
| if (xcross <= pvWalls[w].screenSpaceCoo[1][VEC_COL]) { |
| iy1 = inty; |
| ix1 = xcross; |
| } |
| clearbufbyte(&mostbuf[pvWalls[w].screenSpaceCoo[0][VEC_COL]],(xcross-pvWalls[w].screenSpaceCoo[0][VEC_COL]+1)*sizeof(mostbuf[0]),0L); |
| } |
| } |
| |
| if (bad&12) |
| { |
| t = divscale30(z-s3,s4-s3); |
| inty = pvWalls[w].screenSpaceCoo[0][VEC_DIST] + mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST]-pvWalls[w].screenSpaceCoo[0][VEC_DIST],t); |
| xcross = pvWalls[w].screenSpaceCoo[0][VEC_COL] + scale(mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST],t),pvWalls[w].screenSpaceCoo[1][VEC_COL]-pvWalls[w].screenSpaceCoo[0][VEC_COL],inty); |
| |
| if ((bad&12) == 8) |
| { |
| if (pvWalls[w].screenSpaceCoo[0][VEC_COL] <= xcross) { |
| iy2 = inty; |
| ix2 = xcross; |
| } |
| clearbufbyte(&mostbuf[xcross+1],(pvWalls[w].screenSpaceCoo[1][VEC_COL]-xcross)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); |
| } |
| else |
| { |
| if (xcross <= pvWalls[w].screenSpaceCoo[1][VEC_COL]) { |
| iy1 = inty; |
| ix1 = xcross; |
| } |
| clearbufbyte(&mostbuf[pvWalls[w].screenSpaceCoo[0][VEC_COL]],(xcross-pvWalls[w].screenSpaceCoo[0][VEC_COL]+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); |
| } |
| } |
| |
| y = (scale(z,xdimenscale,iy1)<<4); |
| yinc = ((scale(z,xdimenscale,iy2)<<4)-y) / (ix2-ix1+1); |
| qinterpolatedown16short((int32_t *)&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, int32_t w, int32_t sectnum, uint8_t dastat) |
| { |
| int32_t bad, i, j, t, y, z, inty, intz, xcross, yinc, fw; |
| int32_t x1, y1, z1, x2, y2, z2, xv, yv, dx, dy, dasqr, oz1, oz2; |
| int32_t 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 = pvWalls[w].worldWallId; |
| 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 (pvWalls[w].screenSpaceCoo[0][VEC_COL] == 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 (pvWalls[w].screenSpaceCoo[1][VEC_COL] == 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,pvWalls[w].screenSpaceCoo[0][VEC_DIST]); |
| s2 = mulscale20(globaluclip,pvWalls[w].screenSpaceCoo[1][VEC_DIST]); |
| s3 = mulscale20(globaldclip,pvWalls[w].screenSpaceCoo[0][VEC_DIST]); |
| s4 = mulscale20(globaldclip,pvWalls[w].screenSpaceCoo[1][VEC_DIST]); |
| bad = (z1<s1)+((z2<s2)<<1)+((z1>s3)<<2)+((z2>s4)<<3); |
| |
| ix1 = pvWalls[w].screenSpaceCoo[0][VEC_COL]; |
| ix2 = pvWalls[w].screenSpaceCoo[1][VEC_COL]; |
| iy1 = pvWalls[w].screenSpaceCoo[0][VEC_DIST]; |
| iy2 = pvWalls[w].screenSpaceCoo[1][VEC_DIST]; |
| 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 = pvWalls[w].screenSpaceCoo[0][VEC_DIST] + mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST]-pvWalls[w].screenSpaceCoo[0][VEC_DIST],t); |
| intz = oz1 + mulscale30(oz2-oz1,t); |
| xcross = pvWalls[w].screenSpaceCoo[0][VEC_COL] + scale(mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST],t),pvWalls[w].screenSpaceCoo[1][VEC_COL]-pvWalls[w].screenSpaceCoo[0][VEC_COL],inty); |
| |
| if ((bad&3) == 2){ |
| if (pvWalls[w].screenSpaceCoo[0][VEC_COL] <= xcross){ |
| z2 = intz; |
| iy2 = inty; |
| ix2 = xcross; |
| } |
| clearbufbyte(&mostbuf[xcross+1],(pvWalls[w].screenSpaceCoo[1][VEC_COL]-xcross)*sizeof(mostbuf[0]),0L); |
| } |
| else{ |
| if (xcross <= pvWalls[w].screenSpaceCoo[1][VEC_COL]) { |
| z1 = intz; |
| iy1 = inty; |
| ix1 = xcross; |
| } |
| clearbufbyte(&mostbuf[pvWalls[w].screenSpaceCoo[0][VEC_COL]],(xcross-pvWalls[w].screenSpaceCoo[0][VEC_COL]+1)*sizeof(mostbuf[0]),0L); |
| } |
| } |
| |
| if (bad&12){ |
| /* inty = intz / (globaldclip>>16) */ |
| t = divscale30(oz1-s3,s4-s3+oz1-oz2); |
| inty = pvWalls[w].screenSpaceCoo[0][VEC_DIST] + mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST]-pvWalls[w].screenSpaceCoo[0][VEC_DIST],t); |
| intz = oz1 + mulscale30(oz2-oz1,t); |
| xcross = pvWalls[w].screenSpaceCoo[0][VEC_COL] + scale(mulscale30(pvWalls[w].screenSpaceCoo[1][VEC_DIST],t),pvWalls[w].screenSpaceCoo[1][VEC_COL]-pvWalls[w].screenSpaceCoo[0][VEC_COL],inty); |
| |
| if ((bad&12) == 8){ |
| if (pvWalls[w].screenSpaceCoo[0][VEC_COL] <= xcross) { |
| z2 = intz; |
| iy2 = inty; |
| ix2 = xcross; |
| } |
| clearbufbyte(&mostbuf[xcross+1],(pvWalls[w].screenSpaceCoo[1][VEC_COL]-xcross)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); |
| } |
| else{ |
| if (xcross <= pvWalls[w].screenSpaceCoo[1][VEC_COL]) { |
| z1 = intz; |
| iy1 = inty; |
| ix1 = xcross; |
| } |
| clearbufbyte(&mostbuf[pvWalls[w].screenSpaceCoo[0][VEC_COL]],(xcross-pvWalls[w].screenSpaceCoo[0][VEC_COL]+1)*sizeof(mostbuf[0]),ydimen+(ydimen<<16)); |
| } |
| } |
| |
| y = (scale(z1,xdimenscale,iy1)<<4); |
| yinc = ((scale(z2,xdimenscale,iy2)<<4)-y) / (ix2-ix1+1); |
| qinterpolatedown16short((int32_t *)&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(int32_t bunch) |
| { |
| sectortype *sec, *nextsec; |
| walltype *wal; |
| int32_t i, x, x1, x2, cz[5], fz[5]; |
| int32_t z, wallnum, sectnum, nextsectnum; |
| int32_t startsmostwallcnt, startsmostcnt, gotswall; |
| uint8_t andwstat1, andwstat2; |
| |
| z = bunchfirst[bunch]; |
| sectnum = pvWalls[z].sectorId; |
| sec = §or[sectnum]; |
| |
| andwstat1 = 0xff; |
| andwstat2 = 0xff; |
| for(; z>=0; z=bunchWallsList[z]){ /* uplc/dplc calculation */ |
| |
| andwstat1 &= wallmost(uplc,z,sectnum,(uint8_t )0); |
| andwstat2 &= wallmost(dplc,z,sectnum,(uint8_t )1); |
| } |
| |
| /* draw ceilings */ |
| if ((andwstat1&3) != 3){ |
| if ((sec->ceilingstat&3) == 2) |
| grouscan(pvWalls[bunchfirst[bunch]].screenSpaceCoo[0][VEC_COL],pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL],sectnum,0); |
| else if ((sec->ceilingstat&1) == 0) |
| ceilscan(pvWalls[bunchfirst[bunch]].screenSpaceCoo[0][VEC_COL],pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL],sectnum); |
| else |
| parascan(pvWalls[bunchfirst[bunch]].screenSpaceCoo[0][VEC_COL],pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL],sectnum,0,bunch); |
| } |
| |
| /* draw floors */ |
| if ((andwstat2&12) != 12){ |
| if ((sec->floorstat&3) == 2) |
| grouscan(pvWalls[bunchfirst[bunch]].screenSpaceCoo[0][VEC_COL],pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL],sectnum,1); |
| else if ((sec->floorstat&1) == 0) |
| florscan(pvWalls[bunchfirst[bunch]].screenSpaceCoo[0][VEC_COL],pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL],sectnum); |
| else |
| parascan(pvWalls[bunchfirst[bunch]].screenSpaceCoo[0][VEC_COL],pvWalls[bunchlast[bunch]].screenSpaceCoo[1][VEC_COL],sectnum,1,bunch); |
| } |
| |
| /* DRAW WALLS SECTION! */ |
| for(z=bunchfirst[bunch]; z>=0; z=bunchWallsList[z]){ |
| |
| x1 = pvWalls[z].screenSpaceCoo[0][VEC_COL]; |
| x2 = pvWalls[z].screenSpaceCoo[1][VEC_COL]; |
| 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 = pvWalls[z].worldWallId; |
| 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]); |
| getzsofslope((short)nextsectnum,wal->x,wal->y,&cz[2],&fz[2]); |
| getzsofslope((short)nextsectnum,wall[wal->point2].x,wall[wal->point2].y,&cz[3],&fz[3]); |
| getzsofslope((short)nextsectnum,globalposx,globalposy,&cz[4],&fz[4]); |
| |
| if ((wal->cstat&48) == 16) |
| maskwall[maskwallcnt++] = z; |
| |
| if (((sec->ceilingstat&1) == 0) || ((nextsec->ceilingstat&1) == 0)){ |
| if ((cz[2] <= cz[0]) && (cz[3] <= cz[1])){ |
| if (globparaceilclip) |
| for(x=x1; x<=x2; x++) |
| if (uplc[x] > umost[x]) |
| if (umost[x] <= dmost[x]){ |
| umost[x] = uplc[x]; |
| if (umost[x] > dmost[x]) numhits--; |
| } |
| } |
| else{ |
| wallmost(dwall,z,nextsectnum,(uint8_t )0); |
| if ((cz[2] > fz[0]) || (cz[3] > fz[1])) |
| for(i=x1; i<=x2; i++) if (dwall[i] > dplc[i]) dwall[i] = dplc[i]; |
| |
| if ((searchit == 2) && (searchx >= x1) && (searchx <= x2)) |
| if (searchy <= dwall[searchx]) /* wall */{ |
| searchsector = sectnum; |
| searchwall = wallnum; |
| searchstat = 0; |
| searchit = 1; |
| } |
| |
| globalorientation = (int32_t)wal->cstat; |
| globalpicnum = wal->picnum; |
| if ((uint32_t)globalpicnum >= (uint32_t)MAXTILES) globalpicnum = 0; |
| globalxpanning = (int32_t)wal->xpanning; |
| globalypanning = (int32_t)wal->ypanning; |
| globalshiftval = (picsiz[globalpicnum]>>4); |
| if (pow2long[globalshiftval] != tiles[globalpicnum].dim.height) globalshiftval++; |
| globalshiftval = 32-globalshiftval; |
| |
| //Animated |
| if (tiles[globalpicnum].animFlags&192) |
| globalpicnum += animateoffs(globalpicnum); |
| |
| globalshade = (int32_t)wal->shade; |
| globvis = globalvisibility; |
| if (sec->visibility != 0) globvis = mulscale4(globvis,(int32_t)((uint8_t )(sec->visibility+16))); |
| globalpal = (int32_t)wal->pal; |
| globalyscale = (wal->yrepeat<<(globalshiftval-19)); |
| if ((globalorientation&4) == 0) |
| globalzd = (((globalposz-nextsec->ceilingz)*globalyscale)<<8); |
| else |
| globalzd = (((globalposz-sec->ceilingz)*globalyscale)<<8); |
| globalzd += (globalypanning<<24); |
| if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd; |
|