ref: 516fc276f112baf0bd4508596598aed49929bde9
dir: /src/engine.c/
/* Copyright (C) 1994-1995 Apogee Software, Ltd. Copyright (C) 2002-2015 icculus.org, GNU/Linux port Copyright (C) 2017-2018 Steven LeVesque This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include "rt_def.h" #include "watcom.h" #include "engine.h" #include "_engine.h" #include "rt_draw.h" #include "rt_door.h" #include "rt_stat.h" #include "rt_ted.h" #include "rt_view.h" #include <stdlib.h> /* ============================================================================= Global Variables GLOBAL VARIABLES ============================================================================= */ //wallcast_t posts[642];//bna++ wallcast_t posts[MAXSCREENWIDTH+4];//bna++ //wallcast_t posts[321]; int lasttilex; int lasttiley; /* ============================================================================= Local Variables GLOBAL VARIABLES ============================================================================= */ static int xtilestep,ytilestep; static int c_vx,c_vy; void InitialCast ( void ); void Cast ( int curx ); void Interpolate (int x1, int x2) { int i; int dtexture; int frac; int dheight; int hfrac; int dx; dx=x2-x1; dtexture=(((posts[x2].texture-posts[x1].texture)<<12)+0x800)/dx; dheight=(((posts[x2].wallheight-posts[x1].wallheight)<<8)+0x80)/dx; frac=dtexture+(posts[x1].texture<<12); hfrac=dheight+(posts[x1].wallheight<<8); for (i=x1+1; i<=x2-1; i++,frac+=dtexture,hfrac+=dheight) { posts[i].lump=posts[x1].lump; posts[i].posttype=posts[x1].posttype; posts[i].offset=posts[x1].offset; posts[i].alttile=posts[x1].alttile; posts[i].texture=(frac>>12); posts[i].wallheight=hfrac>>8; } } void Refresh ( void ) { int x; // Cast Initial comb filter InitialCast(); for (x=0; x<=viewwidth-4; x+=4) { if NOTSAMETILE(x,x+4) { Cast(x+2); if NOTSAMETILE(x,x+2) { Cast(x+1); } else Interpolate (x,x+2); if NOTSAMETILE(x+2,x+4) { Cast(x+3); } else Interpolate (x+2,x+4); } else Interpolate(x,x+4); } } void HitWall(int curx, int vertical, int xtile, int ytile) { int num; posts[curx].offset=(xtile<<7)+ytile; posts[curx].lump = tilemap[xtile][ytile]; posts[curx].alttile=0; posts[curx].posttype=0; if (vertical<0) { xintercept=xtile<<16; if (xtilestep<0) xintercept+=0xffff; yintercept=FixedScale(xintercept-viewx,c_vy,c_vx)+viewy; if (posts[curx].lump & 0x4000) { if (tilemap[xtile-(xtilestep>>7)][ytile]&0x8000) { num=tilemap[xtile-(xtilestep>>7)][ytile]; if (num&0x4000) { if (maskobjlist[num&0x3ff]->sidepic) posts[curx].lump = maskobjlist[num&0x3ff]->sidepic; else posts[curx].lump &= 0x3ff; } else posts[curx].lump = doorobjlist[num&0x3ff]->sidepic; } else { if (posts[curx].lump&0x1000) posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture; else posts[curx].lump &= 0x3ff; } } else if (posts[curx].lump & 0x2000) { if (IsWindow(xtile,ytile)) posts[curx].alttile=-1; else posts[curx].alttile=(MAPSPOT(xtile,ytile,2))+1; posts[curx].lump &= 0x3ff; } else if (posts[curx].lump & 0x1000) posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture; else if (posts[curx].lump & 0x800) { posts[curx].lump &= 0x3ff; posts[curx].posttype=2; } posts[curx].texture=yintercept-(ytile<<16); // posts[curx].texture&=0xffff; if (posts[curx].texture<0) posts[curx].texture=0; if (posts[curx].texture>65535) posts[curx].texture=65535; if (xtilestep<0) posts[curx].texture^=0xffff; posts[curx].posttype+=1; // posts[curx].texture=(posts[curx].texture+firstcoloffset)&65535; } else { yintercept=ytile<<16; if (ytilestep<0) yintercept+=0xffff; xintercept=FixedScale(yintercept-viewy,c_vx,c_vy)+viewx; if (posts[curx].lump & 0x4000) { // check for adjacent doors if (tilemap[xtile][ytile-ytilestep]&0x8000) { num=tilemap[xtile][ytile-ytilestep]; if (num&0x4000) { if (maskobjlist[num&0x3ff]->sidepic) posts[curx].lump = maskobjlist[num&0x3ff]->sidepic; else posts[curx].lump &= 0x3ff; } else posts[curx].lump = doorobjlist[num&0x3ff]->sidepic; } else { if (posts[curx].lump&0x1000) posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture; else posts[curx].lump &= 0x3ff; } } else if (posts[curx].lump & 0x2000) { if (IsWindow(xtile,ytile)) posts[curx].alttile=-1; else posts[curx].alttile=(MAPSPOT(xtile,ytile,2))+1; posts[curx].lump &= 0x3ff; } else if (posts[curx].lump & 0x1000) posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture; else if (posts[curx].lump & 0x800) { posts[curx].lump &= 0x3ff; posts[curx].posttype=2; } posts[curx].texture=xintercept-(xtile<<16); // posts[curx].texture&=0xffff; if (posts[curx].texture<0) posts[curx].texture=0; if (posts[curx].texture>65535) posts[curx].texture=65535; if (ytilestep>0) posts[curx].texture^=0xffff; // posts[curx].posttype+=0; // posts[curx].texture=(posts[curx].texture+firstcoloffset)&65535; } posts[curx].wallheight=CalcHeight(); } void InitialCast ( void ) { int snx,sny; int incr[2]; int thedir[2]; int cnt; int grid[2]; int index; int curx; c_vx=c_startx; c_vy=c_starty; for (curx=0; curx<=viewwidth; curx+=4) { snx=viewx&0xffff; sny=viewy&0xffff; if (c_vx>0) { thedir[0]=1; xtilestep=0x80; snx^=0xffff; incr[1]=-c_vx; } else { thedir[0]=-1; xtilestep=-0x80; incr[1]=c_vx; } if (c_vy>0) { thedir[1]=1; ytilestep=1; sny^=0xffff; incr[0]=c_vy; } else { thedir[1]=-1; ytilestep=-1; incr[0]=-c_vy; } cnt=FixedMul(snx,incr[0])+FixedMul(sny,incr[1]); grid[0]=viewx>>16; grid[1]=viewy>>16; do { int tile; index=(cnt>=0); cnt+=incr[index]; spotvis[grid[0]][grid[1]]=1; grid[index]+=thedir[index]; if ((tile=tilemap[grid[0]][grid[1]])!=0) { if (tile&0x8000) { if ( (!(tile&0x4000)) && (doorobjlist[tile&0x3ff]->action==dr_closed)) { spotvis[grid[0]][grid[1]]=1; if (doorobjlist[tile&0x3ff]->flags&DF_MULTI) MakeWideDoorVisible(tile&0x3ff); do { index=(cnt>=0); cnt+=incr[index]; grid[index]+=thedir[index]; if ((tilemap[grid[0]][grid[1]]!=0) && (!(tilemap[grid[0]][grid[1]]&0x8000)) ) break; } while (1); break; } else continue; } else { mapseen[grid[0]][grid[1]]=1; break; } } } while (1); HitWall(curx, cnt-incr[index], grid[0], grid[1]); c_vx+=viewsin<<2; c_vy+=viewcos<<2; } } void Cast ( int curx ) { int snx,sny; int incr[2]; int thedir[2]; int cnt; int grid[2]; int index; c_vx=c_startx+(curx*viewsin); c_vy=c_starty+(curx*viewcos); snx=viewx&0xffff; sny=viewy&0xffff; if (c_vx>0) { thedir[0]=1; xtilestep=0x80; snx^=0xffff; incr[1]=-c_vx; } else { thedir[0]=-1; xtilestep=-0x80; incr[1]=c_vx; } if (c_vy>0) { thedir[1]=1; ytilestep=1; sny^=0xffff; incr[0]=c_vy; } else { thedir[1]=-1; ytilestep=-1; incr[0]=-c_vy; } cnt=FixedMul(snx,incr[0])+FixedMul(sny,incr[1]); grid[0]=viewx>>16; grid[1]=viewy>>16; do { int tile; index=(cnt>=0); cnt+=incr[index]; spotvis[grid[0]][grid[1]]=1; grid[index]+=thedir[index]; if ((tile=tilemap[grid[0]][grid[1]])!=0) { if (tile&0x8000) { if ( (!(tile&0x4000)) && (doorobjlist[tile&0x3ff]->action==dr_closed)) { spotvis[grid[0]][grid[1]]=1; if (doorobjlist[tile&0x3ff]->flags&DF_MULTI) MakeWideDoorVisible(tile&0x3ff); do { index=(cnt>=0); cnt+=incr[index]; grid[index]+=thedir[index]; if ((tilemap[grid[0]][grid[1]]!=0) && (!(tilemap[grid[0]][grid[1]]&0x8000)) ) break; } while (1); break; } else continue; } else { mapseen[grid[0]][grid[1]]=1; break; } } } while (1); HitWall(curx, cnt-incr[index], grid[0], grid[1]); }