summaryrefslogtreecommitdiffstats
path: root/apps/plugins/sdl/progs/wolf3d/wl_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/wl_draw.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/wl_draw.c1647
1 files changed, 1647 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/wl_draw.c b/apps/plugins/sdl/progs/wolf3d/wl_draw.c
new file mode 100644
index 0000000000..625e93dc0a
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/wl_draw.c
@@ -0,0 +1,1647 @@
+// WL_DRAW.C
+
+#include "wl_def.h"
+#pragma hdrstop
+
+#include "wl_cloudsky.h"
+#include "wl_atmos.h"
+#include "wl_shade.h"
+
+/*
+=============================================================================
+
+ LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+// the door is the last picture before the sprites
+#define DOORWALL (PMSpriteStart-8)
+
+#define ACTORSIZE 0x4000
+
+/*
+=============================================================================
+
+ GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+static byte *vbuf = NULL;
+unsigned vbufPitch = 0;
+
+int32_t lasttimecount;
+int32_t frameon;
+boolean fpscounter;
+
+int fps_frames=0, fps_time=0, fps=0;
+
+int *wallheight;
+int min_wallheight;
+
+//
+// math tables
+//
+short *pixelangle;
+int32_t finetangent[FINEANGLES/4];
+fixed sintable[ANGLES+ANGLES/4];
+fixed *costable = sintable+(ANGLES/4);
+
+//
+// refresh variables
+//
+fixed viewx,viewy; // the focal point
+short viewangle;
+fixed viewsin,viewcos;
+
+void TransformActor (objtype *ob);
+void BuildTables (void);
+void ClearScreen (void);
+int CalcRotate (objtype *ob);
+void DrawScaleds (void);
+void CalcTics (void);
+void ThreeDRefresh (void);
+
+
+
+//
+// wall optimization variables
+//
+int lastside; // true for vertical
+int32_t lastintercept;
+int lasttilehit;
+int lasttexture;
+
+//
+// ray tracing variables
+//
+short focaltx,focalty,viewtx,viewty;
+longword xpartialup,xpartialdown,ypartialup,ypartialdown;
+
+short midangle,angle;
+
+word tilehit;
+int pixx;
+
+short xtile,ytile;
+short xtilestep,ytilestep;
+int32_t xintercept,yintercept;
+word xstep,ystep;
+word xspot,yspot;
+int texdelta;
+
+word horizwall[MAXWALLTILES],vertwall[MAXWALLTILES];
+
+
+/*
+============================================================================
+
+ 3 - D DEFINITIONS
+
+============================================================================
+*/
+
+/*
+========================
+=
+= TransformActor
+=
+= Takes paramaters:
+= gx,gy : globalx/globaly of point
+=
+= globals:
+= viewx,viewy : point of view
+= viewcos,viewsin : sin/cos of viewangle
+= scale : conversion from global value to screen value
+=
+= sets:
+= screenx,transx,transy,screenheight: projected edge location and size
+=
+========================
+*/
+
+
+//
+// transform actor
+//
+void TransformActor (objtype *ob)
+{
+ fixed gx,gy,gxt,gyt,nx,ny;
+
+//
+// translate point to view centered coordinates
+//
+ gx = ob->x-viewx;
+ gy = ob->y-viewy;
+
+//
+// calculate newx
+//
+ gxt = FixedMul(gx,viewcos);
+ gyt = FixedMul(gy,viewsin);
+ nx = gxt-gyt-ACTORSIZE; // fudge the shape forward a bit, because
+ // the midpoint could put parts of the shape
+ // into an adjacent wall
+
+//
+// calculate newy
+//
+ gxt = FixedMul(gx,viewsin);
+ gyt = FixedMul(gy,viewcos);
+ ny = gyt+gxt;
+
+//
+// calculate perspective ratio
+//
+ ob->transx = nx;
+ ob->transy = ny;
+
+ if (nx<MINDIST) // too close, don't overflow the divide
+ {
+ ob->viewheight = 0;
+ return;
+ }
+
+ ob->viewx = (word)(centerx + ny*scale/nx);
+
+//
+// calculate height (heightnumerator/(nx>>8))
+//
+ ob->viewheight = (word)(heightnumerator/(nx>>8));
+}
+
+//==========================================================================
+
+/*
+========================
+=
+= TransformTile
+=
+= Takes paramaters:
+= tx,ty : tile the object is centered in
+=
+= globals:
+= viewx,viewy : point of view
+= viewcos,viewsin : sin/cos of viewangle
+= scale : conversion from global value to screen value
+=
+= sets:
+= screenx,transx,transy,screenheight: projected edge location and size
+=
+= Returns true if the tile is withing getting distance
+=
+========================
+*/
+
+boolean TransformTile (int tx, int ty, short *dispx, short *dispheight)
+{
+ fixed gx,gy,gxt,gyt,nx,ny;
+
+//
+// translate point to view centered coordinates
+//
+ gx = ((int32_t)tx<<TILESHIFT)+0x8000-viewx;
+ gy = ((int32_t)ty<<TILESHIFT)+0x8000-viewy;
+
+//
+// calculate newx
+//
+ gxt = FixedMul(gx,viewcos);
+ gyt = FixedMul(gy,viewsin);
+ nx = gxt-gyt-0x2000; // 0x2000 is size of object
+
+//
+// calculate newy
+//
+ gxt = FixedMul(gx,viewsin);
+ gyt = FixedMul(gy,viewcos);
+ ny = gyt+gxt;
+
+
+//
+// calculate height / perspective ratio
+//
+ if (nx<MINDIST) // too close, don't overflow the divide
+ *dispheight = 0;
+ else
+ {
+ *dispx = (short)(centerx + ny*scale/nx);
+ *dispheight = (short)(heightnumerator/(nx>>8));
+ }
+
+//
+// see if it should be grabbed
+//
+ if (nx<TILEGLOBAL && ny>-TILEGLOBAL/2 && ny<TILEGLOBAL/2)
+ return true;
+ else
+ return false;
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= CalcHeight
+=
+= Calculates the height of xintercept,yintercept from viewx,viewy
+=
+====================
+*/
+
+int CalcHeight()
+{
+ fixed z = FixedMul(xintercept - viewx, viewcos)
+ - FixedMul(yintercept - viewy, viewsin);
+ if(z < MINDIST) z = MINDIST;
+ int height = heightnumerator / (z >> 8);
+ if(height < min_wallheight) min_wallheight = height;
+ return height;
+}
+
+//==========================================================================
+
+/*
+===================
+=
+= ScalePost
+=
+===================
+*/
+
+byte *postsource;
+int postx;
+int postwidth;
+
+void ScalePost()
+{
+ int ywcount, yoffs, yw, yd, yendoffs;
+ byte col;
+
+#ifdef USE_SHADING
+ byte *curshades = shadetable[GetShade(wallheight[postx])];
+#endif
+
+ ywcount = yd = wallheight[postx] >> 3;
+ if(yd <= 0) yd = 100;
+
+ yoffs = (viewheight / 2 - ywcount) * vbufPitch;
+ if(yoffs < 0) yoffs = 0;
+ yoffs += postx;
+
+ yendoffs = viewheight / 2 + ywcount - 1;
+ yw=TEXTURESIZE-1;
+
+ while(yendoffs >= viewheight)
+ {
+ ywcount -= TEXTURESIZE/2;
+ while(ywcount <= 0)
+ {
+ ywcount += yd;
+ yw--;
+ }
+ yendoffs--;
+ }
+ if(yw < 0) return;
+
+#ifdef USE_SHADING
+ col = curshades[postsource[yw]];
+#else
+ col = postsource[yw];
+#endif
+ yendoffs = yendoffs * vbufPitch + postx;
+ while(yoffs <= yendoffs)
+ {
+ vbuf[yendoffs] = col;
+ ywcount -= TEXTURESIZE/2;
+ if(ywcount <= 0)
+ {
+ do
+ {
+ ywcount += yd;
+ yw--;
+ }
+ while(ywcount <= 0);
+ if(yw < 0) break;
+#ifdef USE_SHADING
+ col = curshades[postsource[yw]];
+#else
+ col = postsource[yw];
+#endif
+ }
+ yendoffs -= vbufPitch;
+ }
+}
+
+void GlobalScalePost(byte *vidbuf, unsigned pitch)
+{
+ vbuf = vidbuf;
+ vbufPitch = pitch;
+ ScalePost();
+}
+
+/*
+====================
+=
+= HitVertWall
+=
+= tilehit bit 7 is 0, because it's not a door tile
+= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
+=
+====================
+*/
+
+void HitVertWall (void)
+{
+ int wallpic;
+ int texture;
+
+ texture = ((yintercept+texdelta)>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
+ if (xtilestep == -1)
+ {
+ texture = TEXTUREMASK-texture;
+ xintercept += TILEGLOBAL;
+ }
+
+ if(lastside==1 && lastintercept==xtile && lasttilehit==tilehit && !(lasttilehit & 0x40))
+ {
+ if((pixx&3) && texture == lasttexture)
+ {
+ ScalePost();
+ postx = pixx;
+ wallheight[pixx] = wallheight[pixx-1];
+ return;
+ }
+ ScalePost();
+ wallheight[pixx] = CalcHeight();
+ postsource+=texture-lasttexture;
+ postwidth=1;
+ postx=pixx;
+ lasttexture=texture;
+ return;
+ }
+
+ if(lastside!=-1) ScalePost();
+
+ lastside=1;
+ lastintercept=xtile;
+ lasttilehit=tilehit;
+ lasttexture=texture;
+ wallheight[pixx] = CalcHeight();
+ postx = pixx;
+ postwidth = 1;
+
+ if (tilehit & 0x40)
+ { // check for adjacent doors
+ ytile = (short)(yintercept>>TILESHIFT);
+ if ( tilemap[xtile-xtilestep][ytile]&0x80 )
+ wallpic = DOORWALL+3;
+ else
+ wallpic = vertwall[tilehit & ~0x40];
+ }
+ else
+ wallpic = vertwall[tilehit];
+
+ postsource = PM_GetTexture(wallpic) + texture;
+}
+
+
+/*
+====================
+=
+= HitHorizWall
+=
+= tilehit bit 7 is 0, because it's not a door tile
+= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
+=
+====================
+*/
+
+void HitHorizWall (void)
+{
+ int wallpic;
+ int texture;
+
+ texture = ((xintercept+texdelta)>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
+ if (ytilestep == -1)
+ yintercept += TILEGLOBAL;
+ else
+ texture = TEXTUREMASK-texture;
+
+ if(lastside==0 && lastintercept==ytile && lasttilehit==tilehit && !(lasttilehit & 0x40))
+ {
+ if((pixx&3) && texture == lasttexture)
+ {
+ ScalePost();
+ postx=pixx;
+ wallheight[pixx] = wallheight[pixx-1];
+ return;
+ }
+ ScalePost();
+ wallheight[pixx] = CalcHeight();
+ postsource+=texture-lasttexture;
+ postwidth=1;
+ postx=pixx;
+ lasttexture=texture;
+ return;
+ }
+
+ if(lastside!=-1) ScalePost();
+
+ lastside=0;
+ lastintercept=ytile;
+ lasttilehit=tilehit;
+ lasttexture=texture;
+ wallheight[pixx] = CalcHeight();
+ postx = pixx;
+ postwidth = 1;
+
+ if (tilehit & 0x40)
+ { // check for adjacent doors
+ xtile = (short)(xintercept>>TILESHIFT);
+ if ( tilemap[xtile][ytile-ytilestep]&0x80)
+ wallpic = DOORWALL+2;
+ else
+ wallpic = horizwall[tilehit & ~0x40];
+ }
+ else
+ wallpic = horizwall[tilehit];
+
+ postsource = PM_GetTexture(wallpic) + texture;
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= HitHorizDoor
+=
+====================
+*/
+
+void HitHorizDoor (void)
+{
+ int doorpage;
+ int doornum;
+ int texture;
+
+ doornum = tilehit&0x7f;
+ texture = ((xintercept-doorposition[doornum])>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
+
+ if(lasttilehit==tilehit)
+ {
+ if((pixx&3) && texture == lasttexture)
+ {
+ ScalePost();
+ postx=pixx;
+ wallheight[pixx] = wallheight[pixx-1];
+ return;
+ }
+ ScalePost();
+ wallheight[pixx] = CalcHeight();
+ postsource+=texture-lasttexture;
+ postwidth=1;
+ postx=pixx;
+ lasttexture=texture;
+ return;
+ }
+
+ if(lastside!=-1) ScalePost();
+
+ lastside=2;
+ lasttilehit=tilehit;
+ lasttexture=texture;
+ wallheight[pixx] = CalcHeight();
+ postx = pixx;
+ postwidth = 1;
+
+ switch(doorobjlist[doornum].lock)
+ {
+ case dr_normal:
+ doorpage = DOORWALL;
+ break;
+ case dr_lock1:
+ case dr_lock2:
+ case dr_lock3:
+ case dr_lock4:
+ doorpage = DOORWALL+6;
+ break;
+ case dr_elevator:
+ doorpage = DOORWALL+4;
+ break;
+ }
+
+ postsource = PM_GetTexture(doorpage) + texture;
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= HitVertDoor
+=
+====================
+*/
+
+void HitVertDoor (void)
+{
+ int doorpage;
+ int doornum;
+ int texture;
+
+ doornum = tilehit&0x7f;
+ texture = ((yintercept-doorposition[doornum])>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
+
+ if(lasttilehit==tilehit)
+ {
+ if((pixx&3) && texture == lasttexture)
+ {
+ ScalePost();
+ postx=pixx;
+ wallheight[pixx] = wallheight[pixx-1];
+ return;
+ }
+ ScalePost();
+ wallheight[pixx] = CalcHeight();
+ postsource+=texture-lasttexture;
+ postwidth=1;
+ postx=pixx;
+ lasttexture=texture;
+ return;
+ }
+
+ if(lastside!=-1) ScalePost();
+
+ lastside=2;
+ lasttilehit=tilehit;
+ lasttexture=texture;
+ wallheight[pixx] = CalcHeight();
+ postx = pixx;
+ postwidth = 1;
+
+ switch(doorobjlist[doornum].lock)
+ {
+ case dr_normal:
+ doorpage = DOORWALL+1;
+ break;
+ case dr_lock1:
+ case dr_lock2:
+ case dr_lock3:
+ case dr_lock4:
+ doorpage = DOORWALL+7;
+ break;
+ case dr_elevator:
+ doorpage = DOORWALL+5;
+ break;
+ }
+
+ postsource = PM_GetTexture(doorpage) + texture;
+}
+
+//==========================================================================
+
+#define HitHorizBorder HitHorizWall
+#define HitVertBorder HitVertWall
+
+//==========================================================================
+
+byte vgaCeiling[]=
+{
+#ifndef SPEAR
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0xbf,
+ 0x4e,0x4e,0x4e,0x1d,0x8d,0x4e,0x1d,0x2d,0x1d,0x8d,
+ 0x1d,0x1d,0x1d,0x1d,0x1d,0x2d,0xdd,0x1d,0x1d,0x98,
+
+ 0x1d,0x9d,0x2d,0xdd,0xdd,0x9d,0x2d,0x4d,0x1d,0xdd,
+ 0x7d,0x1d,0x2d,0x2d,0xdd,0xd7,0x1d,0x1d,0x1d,0x2d,
+ 0x1d,0x1d,0x1d,0x1d,0xdd,0xdd,0x7d,0xdd,0xdd,0xdd
+#else
+ 0x6f,0x4f,0x1d,0xde,0xdf,0x2e,0x7f,0x9e,0xae,0x7f,
+ 0x1d,0xde,0xdf,0xde,0xdf,0xde,0xe1,0xdc,0x2e,0x1d,0xdc
+#endif
+};
+
+/*
+=====================
+=
+= VGAClearScreen
+=
+=====================
+*/
+
+void VGAClearScreen (void)
+{
+ byte ceiling=vgaCeiling[gamestate.episode*10+mapon];
+
+ int y;
+ byte *ptr = vbuf;
+#ifdef USE_SHADING
+ for(y = 0; y < viewheight / 2; y++, ptr += vbufPitch)
+ memset(ptr, shadetable[GetShade((viewheight / 2 - y) << 3)][ceiling], viewwidth);
+ for(; y < viewheight; y++, ptr += vbufPitch)
+ memset(ptr, shadetable[GetShade((y - viewheight / 2) << 3)][0x19], viewwidth);
+#else
+ for(y = 0; y < viewheight / 2; y++, ptr += vbufPitch)
+ memset(ptr, ceiling, viewwidth);
+ for(; y < viewheight; y++, ptr += vbufPitch)
+ memset(ptr, 0x19, viewwidth);
+#endif
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= CalcRotate
+=
+=====================
+*/
+
+int CalcRotate (objtype *ob)
+{
+ int angle, viewangle;
+
+ // this isn't exactly correct, as it should vary by a trig value,
+ // but it is close enough with only eight rotations
+
+ viewangle = player->angle + (centerx - ob->viewx)/8;
+
+ if (ob->obclass == rocketobj || ob->obclass == hrocketobj)
+ angle = (viewangle-180) - ob->angle;
+ else
+ angle = (viewangle-180) - dirangle[ob->dir];
+
+ angle+=ANGLES/16;
+ while (angle>=ANGLES)
+ angle-=ANGLES;
+ while (angle<0)
+ angle+=ANGLES;
+
+ if (ob->state->rotate == 2) // 2 rotation pain frame
+ return 0; // pain with shooting frame bugfix
+
+ return angle/(ANGLES/8);
+}
+
+void ScaleShape (int xcenter, int shapenum, unsigned height, uint32_t flags)
+{
+ t_compshape *shape;
+ unsigned scale,pixheight;
+ unsigned starty,endy;
+ word *cmdptr;
+ byte *cline;
+ byte *line;
+ byte *vmem;
+ int actx,i,upperedge;
+ short newstart;
+ int scrstarty,screndy,lpix,rpix,pixcnt,ycnt;
+ unsigned j;
+ byte col;
+
+#ifdef USE_SHADING
+ byte *curshades;
+ if(flags & FL_FULLBRIGHT)
+ curshades = shadetable[0];
+ else
+ curshades = shadetable[GetShade(height)];
+#endif
+
+ shape = (t_compshape *) PM_GetSprite(shapenum);
+
+ scale=height>>3; // low three bits are fractional
+ if(!scale) return; // too close or far away
+
+ pixheight=scale*SPRITESCALEFACTOR;
+ actx=xcenter-scale;
+ upperedge=viewheight/2-scale;
+
+ cmdptr=(word *) shape->dataofs;
+
+ for(i=shape->leftpix,pixcnt=i*pixheight,rpix=(pixcnt>>6)+actx;i<=shape->rightpix;i++,cmdptr++)
+ {
+ lpix=rpix;
+ if(lpix>=viewwidth) break;
+ pixcnt+=pixheight;
+ rpix=(pixcnt>>6)+actx;
+ if(lpix!=rpix && rpix>0)
+ {
+ if(lpix<0) lpix=0;
+ if(rpix>viewwidth) rpix=viewwidth,i=shape->rightpix+1;
+ cline=(byte *)shape + *cmdptr;
+ while(lpix<rpix)
+ {
+ if(wallheight[lpix]<=(int)height)
+ {
+ line=cline;
+ while((endy = READWORD(&line)) != 0)
+ {
+ endy >>= 1;
+ newstart = READWORD(&line);
+ starty = READWORD(&line) >> 1;
+ j=starty;
+ ycnt=j*pixheight;
+ screndy=(ycnt>>6)+upperedge;
+ if(screndy<0) vmem=vbuf+lpix;
+ else vmem=vbuf+screndy*vbufPitch+lpix;
+ for(;j<endy;j++)
+ {
+ scrstarty=screndy;
+ ycnt+=pixheight;
+ screndy=(ycnt>>6)+upperedge;
+ if(scrstarty!=screndy && screndy>0)
+ {
+#ifdef USE_SHADING
+ col=curshades[((byte *)shape)[newstart+j]];
+#else
+ col=((byte *)shape)[newstart+j];
+#endif
+ if(scrstarty<0) scrstarty=0;
+ if(screndy>viewheight) screndy=viewheight,j=endy;
+
+ while(scrstarty<screndy)
+ {
+ *vmem=col;
+ vmem+=vbufPitch;
+ scrstarty++;
+ }
+ }
+ }
+ }
+ }
+ lpix++;
+ }
+ }
+ }
+}
+
+void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
+{
+ t_compshape *shape;
+ unsigned scale,pixheight;
+ unsigned starty,endy;
+ word *cmdptr;
+ byte *cline;
+ byte *line;
+ int actx,i,upperedge;
+ short newstart;
+ int scrstarty,screndy,lpix,rpix,pixcnt,ycnt;
+ unsigned j;
+ byte col;
+ byte *vmem;
+
+ shape = (t_compshape *) PM_GetSprite(shapenum);
+
+ scale=height>>1;
+ pixheight=scale*SPRITESCALEFACTOR;
+ actx=xcenter-scale;
+ upperedge=viewheight/2-scale;
+
+ cmdptr=shape->dataofs;
+
+ for(i=shape->leftpix,pixcnt=i*pixheight,rpix=(pixcnt>>6)+actx;i<=shape->rightpix;i++,cmdptr++)
+ {
+ lpix=rpix;
+ if(lpix>=viewwidth) break;
+ pixcnt+=pixheight;
+ rpix=(pixcnt>>6)+actx;
+ if(lpix!=rpix && rpix>0)
+ {
+ if(lpix<0) lpix=0;
+ if(rpix>viewwidth) rpix=viewwidth,i=shape->rightpix+1;
+ cline = (byte *)shape + *cmdptr;
+ while(lpix<rpix)
+ {
+ line=cline;
+ while((endy = READWORD(&line)) != 0)
+ {
+ endy >>= 1;
+ newstart = READWORD(&line);
+ starty = READWORD(&line) >> 1;
+ j=starty;
+ ycnt=j*pixheight;
+ screndy=(ycnt>>6)+upperedge;
+ if(screndy<0) vmem=vbuf+lpix;
+ else vmem=vbuf+screndy*vbufPitch+lpix;
+ for(;j<endy;j++)
+ {
+ scrstarty=screndy;
+ ycnt+=pixheight;
+ screndy=(ycnt>>6)+upperedge;
+ if(scrstarty!=screndy && screndy>0)
+ {
+ col=((byte *)shape)[newstart+j];
+ if(scrstarty<0) scrstarty=0;
+ if(screndy>viewheight) screndy=viewheight,j=endy;
+
+ while(scrstarty<screndy)
+ {
+ *vmem=col;
+ vmem+=vbufPitch;
+ scrstarty++;
+ }
+ }
+ }
+ }
+ lpix++;
+ }
+ }
+ }
+}
+
+/*
+=====================
+=
+= DrawScaleds
+=
+= Draws all objects that are visable
+=
+=====================
+*/
+
+#define MAXVISABLE 250
+
+typedef struct
+{
+ short viewx,
+ viewheight,
+ shapenum;
+ short flags; // this must be changed to uint32_t, when you
+ // you need more than 16-flags for drawing
+#ifdef USE_DIR3DSPR
+ statobj_t *transsprite;
+#endif
+} visobj_t;
+
+visobj_t vislist[MAXVISABLE];
+visobj_t *visptr,*visstep,*farthest;
+
+void DrawScaleds (void)
+{
+ int i,least,numvisable,height;
+ byte *tilespot,*visspot;
+ unsigned spotloc;
+
+ statobj_t *statptr;
+ objtype *obj;
+
+ visptr = &vislist[0];
+
+//
+// place static objects
+//
+ for (statptr = &statobjlist[0] ; statptr !=laststatobj ; statptr++)
+ {
+ if ((visptr->shapenum = statptr->shapenum) == -1)
+ continue; // object has been deleted
+
+ if (!*statptr->visspot)
+ continue; // not visable
+
+ if (TransformTile (statptr->tilex,statptr->tiley,
+ &visptr->viewx,&visptr->viewheight) && statptr->flags & FL_BONUS)
+ {
+ GetBonus (statptr);
+ if(statptr->shapenum == -1)
+ continue; // object has been taken
+ }
+
+ if (!visptr->viewheight)
+ continue; // to close to the object
+
+#ifdef USE_DIR3DSPR
+ if(statptr->flags & FL_DIR_MASK)
+ visptr->transsprite=statptr;
+ else
+ visptr->transsprite=NULL;
+#endif
+
+ if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow
+ {
+ visptr->flags = (short) statptr->flags;
+ visptr++;
+ }
+ }
+
+//
+// place active objects
+//
+ for (obj = player->next;obj;obj=obj->next)
+ {
+ if ((visptr->shapenum = obj->state->shapenum)==0)
+ continue; // no shape
+
+ spotloc = (obj->tilex<<mapshift)+obj->tiley; // optimize: keep in struct?
+ visspot = &spotvis[0][0]+spotloc;
+ tilespot = &tilemap[0][0]+spotloc;
+
+ //
+ // could be in any of the nine surrounding tiles
+ //
+ if (*visspot
+ || ( *(visspot-1) && !*(tilespot-1) )
+ || ( *(visspot+1) && !*(tilespot+1) )
+ || ( *(visspot-65) && !*(tilespot-65) )
+ || ( *(visspot-64) && !*(tilespot-64) )
+ || ( *(visspot-63) && !*(tilespot-63) )
+ || ( *(visspot+65) && !*(tilespot+65) )
+ || ( *(visspot+64) && !*(tilespot+64) )
+ || ( *(visspot+63) && !*(tilespot+63) ) )
+ {
+ obj->active = ac_yes;
+ TransformActor (obj);
+ if (!obj->viewheight)
+ continue; // too close or far away
+
+ visptr->viewx = obj->viewx;
+ visptr->viewheight = obj->viewheight;
+ if (visptr->shapenum == -1)
+ visptr->shapenum = obj->temp1; // special shape
+
+ if (obj->state->rotate)
+ visptr->shapenum += CalcRotate (obj);
+
+ if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow
+ {
+ visptr->flags = (short) obj->flags;
+#ifdef USE_DIR3DSPR
+ visptr->transsprite = NULL;
+#endif
+ visptr++;
+ }
+ obj->flags |= FL_VISABLE;
+ }
+ else
+ obj->flags &= ~FL_VISABLE;
+ }
+
+//
+// draw from back to front
+//
+ numvisable = (int) (visptr-&vislist[0]);
+
+ if (!numvisable)
+ return; // no visable objects
+
+ for (i = 0; i<numvisable; i++)
+ {
+ least = 32000;
+ for (visstep=&vislist[0] ; visstep<visptr ; visstep++)
+ {
+ height = visstep->viewheight;
+ if (height < least)
+ {
+ least = height;
+ farthest = visstep;
+ }
+ }
+ //
+ // draw farthest
+ //
+#ifdef USE_DIR3DSPR
+ if(farthest->transsprite)
+ Scale3DShape(vbuf, vbufPitch, farthest->transsprite);
+ else
+#endif
+ ScaleShape(farthest->viewx, farthest->shapenum, farthest->viewheight, farthest->flags);
+
+ farthest->viewheight = 32000;
+ }
+}
+
+//==========================================================================
+
+/*
+==============
+=
+= DrawPlayerWeapon
+=
+= Draw the player's hands
+=
+==============
+*/
+
+int weaponscale[NUMWEAPONS] = {SPR_KNIFEREADY, SPR_PISTOLREADY,
+ SPR_MACHINEGUNREADY, SPR_CHAINREADY};
+
+void DrawPlayerWeapon (void)
+{
+ int shapenum;
+
+#ifndef SPEAR
+ if (gamestate.victoryflag)
+ {
+#ifndef APOGEE_1_0
+ if (player->state == &s_deathcam && (GetTimeCount()&32) )
+ SimpleScaleShape(viewwidth/2,SPR_DEATHCAM,viewheight+1);
+#endif
+ return;
+ }
+#endif
+
+ if (gamestate.weapon != -1)
+ {
+ shapenum = weaponscale[gamestate.weapon]+gamestate.weaponframe;
+ SimpleScaleShape(viewwidth/2,shapenum,viewheight+1);
+ }
+
+ if (demorecord || demoplayback)
+ SimpleScaleShape(viewwidth/2,SPR_DEMO,viewheight+1);
+}
+
+
+//==========================================================================
+
+
+/*
+=====================
+=
+= CalcTics
+=
+=====================
+*/
+
+void CalcTics (void)
+{
+//
+// calculate tics since last refresh for adaptive timing
+//
+ if (lasttimecount > (int32_t) GetTimeCount())
+ lasttimecount = GetTimeCount(); // if the game was paused a LONG time
+
+ uint32_t curtime = SDL_GetTicks();
+ tics = (curtime * 7) / 100 - lasttimecount;
+ if(!tics)
+ {
+ // wait until end of current tic
+ SDL_Delay(((lasttimecount + 1) * 100) / 7 - curtime);
+ tics = 1;
+ }
+
+ lasttimecount += tics;
+
+ if (tics>MAXTICS)
+ tics = MAXTICS;
+}
+
+
+//==========================================================================
+
+void AsmRefresh()
+{
+ int32_t xstep,ystep;
+ longword xpartial,ypartial;
+ boolean playerInPushwallBackTile = tilemap[focaltx][focalty] == 64;
+
+ for(pixx=0;pixx<viewwidth;pixx++)
+ {
+ short angl=midangle+pixelangle[pixx];
+ if(angl<0) angl+=FINEANGLES;
+ if(angl>=3600) angl-=FINEANGLES;
+ if(angl<900)
+ {
+ xtilestep=1;
+ ytilestep=-1;
+ xstep=finetangent[900-1-angl];
+ ystep=-finetangent[angl];
+ xpartial=xpartialup;
+ ypartial=ypartialdown;
+ }
+ else if(angl<1800)
+ {
+ xtilestep=-1;
+ ytilestep=-1;
+ xstep=-finetangent[angl-900];
+ ystep=-finetangent[1800-1-angl];
+ xpartial=xpartialdown;
+ ypartial=ypartialdown;
+ }
+ else if(angl<2700)
+ {
+ xtilestep=-1;
+ ytilestep=1;
+ xstep=-finetangent[2700-1-angl];
+ ystep=finetangent[angl-1800];
+ xpartial=xpartialdown;
+ ypartial=ypartialup;
+ }
+ else if(angl<3600)
+ {
+ xtilestep=1;
+ ytilestep=1;
+ xstep=finetangent[angl-2700];
+ ystep=finetangent[3600-1-angl];
+ xpartial=xpartialup;
+ ypartial=ypartialup;
+ }
+ yintercept=FixedMul(ystep,xpartial)+viewy;
+ xtile=focaltx+xtilestep;
+ xspot=(word)((xtile<<mapshift)+((uint32_t)yintercept>>16));
+ xintercept=FixedMul(xstep,ypartial)+viewx;
+ ytile=focalty+ytilestep;
+ yspot=(word)((((uint32_t)xintercept>>16)<<mapshift)+ytile);
+ texdelta=0;
+
+ // Special treatment when player is in back tile of pushwall
+ if(playerInPushwallBackTile)
+ {
+ if( pwalldir == di_east && xtilestep == 1
+ || pwalldir == di_west && xtilestep == -1)
+ {
+ int32_t yintbuf = yintercept - ((ystep * (64 - pwallpos)) >> 6);
+ if((yintbuf >> 16) == focalty) // ray hits pushwall back?
+ {
+ if(pwalldir == di_east)
+ xintercept = (focaltx << TILESHIFT) + (pwallpos << 10);
+ else
+ xintercept = (focaltx << TILESHIFT) - TILEGLOBAL + ((64 - pwallpos) << 10);
+ yintercept = yintbuf;
+ ytile = (short) (yintercept >> TILESHIFT);
+ tilehit = pwalltile;
+ HitVertWall();
+ continue;
+ }
+ }
+ else if(pwalldir == di_south && ytilestep == 1
+ || pwalldir == di_north && ytilestep == -1)
+ {
+ int32_t xintbuf = xintercept - ((xstep * (64 - pwallpos)) >> 6);
+ if((xintbuf >> 16) == focaltx) // ray hits pushwall back?
+ {
+ xintercept = xintbuf;
+ if(pwalldir == di_south)
+ yintercept = (focalty << TILESHIFT) + (pwallpos << 10);
+ else
+ yintercept = (focalty << TILESHIFT) - TILEGLOBAL + ((64 - pwallpos) << 10);
+ xtile = (short) (xintercept >> TILESHIFT);
+ tilehit = pwalltile;
+ HitHorizWall();
+ continue;
+ }
+ }
+ }
+
+ do
+ {
+ if(ytilestep==-1 && (yintercept>>16)<=ytile) goto horizentry;
+ if(ytilestep==1 && (yintercept>>16)>=ytile) goto horizentry;
+vertentry:
+ if((uint32_t)yintercept>mapheight*65536-1 || (word)xtile>=mapwidth)
+ {
+ if(xtile<0) xintercept=0, xtile=0;
+ else if(xtile>=mapwidth) xintercept=mapwidth<<TILESHIFT, xtile=mapwidth-1;
+ else xtile=(short) (xintercept >> TILESHIFT);
+ if(yintercept<0) yintercept=0, ytile=0;
+ else if(yintercept>=(mapheight<<TILESHIFT)) yintercept=mapheight<<TILESHIFT, ytile=mapheight-1;
+ yspot=0xffff;
+ tilehit=0;
+ HitHorizBorder();
+ break;
+ }
+ if(xspot>=maparea) break;
+ tilehit=((byte *)tilemap)[xspot];
+ if(tilehit)
+ {
+ if(tilehit&0x80)
+ {
+ int32_t yintbuf=yintercept+(ystep>>1);
+ if((yintbuf>>16)!=(yintercept>>16))
+ goto passvert;
+ if((word)yintbuf<doorposition[tilehit&0x7f])
+ goto passvert;
+ yintercept=yintbuf;
+ xintercept=(xtile<<TILESHIFT)|0x8000;
+ ytile = (short) (yintercept >> TILESHIFT);
+ HitVertDoor();
+ }
+ else
+ {
+ if(tilehit==64)
+ {
+ if(pwalldir==di_west || pwalldir==di_east)
+ {
+ int32_t yintbuf;
+ int pwallposnorm;
+ int pwallposinv;
+ if(pwalldir==di_west)
+ {
+ pwallposnorm = 64-pwallpos;
+ pwallposinv = pwallpos;
+ }
+ else
+ {
+ pwallposnorm = pwallpos;
+ pwallposinv = 64-pwallpos;
+ }
+ if(pwalldir == di_east && xtile==pwallx && ((uint32_t)yintercept>>16)==pwally
+ || pwalldir == di_west && !(xtile==pwallx && ((uint32_t)yintercept>>16)==pwally))
+ {
+ yintbuf=yintercept+((ystep*pwallposnorm)>>6);
+ if((yintbuf>>16)!=(yintercept>>16))
+ goto passvert;
+
+ xintercept=(xtile<<TILESHIFT)+TILEGLOBAL-(pwallposinv<<10);
+ yintercept=yintbuf;
+ ytile = (short) (yintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitVertWall();
+ }
+ else
+ {
+ yintbuf=yintercept+((ystep*pwallposinv)>>6);
+ if((yintbuf>>16)!=(yintercept>>16))
+ goto passvert;
+
+ xintercept=(xtile<<TILESHIFT)-(pwallposinv<<10);
+ yintercept=yintbuf;
+ ytile = (short) (yintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitVertWall();
+ }
+ }
+ else
+ {
+ int pwallposi = pwallpos;
+ if(pwalldir==di_north) pwallposi = 64-pwallpos;
+ if(pwalldir==di_south && (word)yintercept<(pwallposi<<10)
+ || pwalldir==di_north && (word)yintercept>(pwallposi<<10))
+ {
+ if(((uint32_t)yintercept>>16)==pwally && xtile==pwallx)
+ {
+ if(pwalldir==di_south && (int32_t)((word)yintercept)+ystep<(pwallposi<<10)
+ || pwalldir==di_north && (int32_t)((word)yintercept)+ystep>(pwallposi<<10))
+ goto passvert;
+
+ if(pwalldir==di_south)
+ yintercept=(yintercept&0xffff0000)+(pwallposi<<10);
+ else
+ yintercept=(yintercept&0xffff0000)-TILEGLOBAL+(pwallposi<<10);
+ xintercept=xintercept-((xstep*(64-pwallpos))>>6);
+ xtile = (short) (xintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitHorizWall();
+ }
+ else
+ {
+ texdelta = -(pwallposi<<10);
+ xintercept=xtile<<TILESHIFT;
+ ytile = (short) (yintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitVertWall();
+ }
+ }
+ else
+ {
+ if(((uint32_t)yintercept>>16)==pwally && xtile==pwallx)
+ {
+ texdelta = -(pwallposi<<10);
+ xintercept=xtile<<TILESHIFT;
+ ytile = (short) (yintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitVertWall();
+ }
+ else
+ {
+ if(pwalldir==di_south && (int32_t)((word)yintercept)+ystep>(pwallposi<<10)
+ || pwalldir==di_north && (int32_t)((word)yintercept)+ystep<(pwallposi<<10))
+ goto passvert;
+
+ if(pwalldir==di_south)
+ yintercept=(yintercept&0xffff0000)-((64-pwallpos)<<10);
+ else
+ yintercept=(yintercept&0xffff0000)+((64-pwallpos)<<10);
+ xintercept=xintercept-((xstep*pwallpos)>>6);
+ xtile = (short) (xintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitHorizWall();
+ }
+ }
+ }
+ }
+ else
+ {
+ xintercept=xtile<<TILESHIFT;
+ ytile = (short) (yintercept >> TILESHIFT);
+ HitVertWall();
+ }
+ }
+ break;
+ }
+passvert:
+ *((byte *)spotvis+xspot)=1;
+ xtile+=xtilestep;
+ yintercept+=ystep;
+ xspot=(word)((xtile<<mapshift)+((uint32_t)yintercept>>16));
+ }
+ while(1);
+ continue;
+
+ do
+ {
+ if(xtilestep==-1 && (xintercept>>16)<=xtile) goto vertentry;
+ if(xtilestep==1 && (xintercept>>16)>=xtile) goto vertentry;
+horizentry:
+ if((uint32_t)xintercept>mapwidth*65536-1 || (word)ytile>=mapheight)
+ {
+ if(ytile<0) yintercept=0, ytile=0;
+ else if(ytile>=mapheight) yintercept=mapheight<<TILESHIFT, ytile=mapheight-1;
+ else ytile=(short) (yintercept >> TILESHIFT);
+ if(xintercept<0) xintercept=0, xtile=0;
+ else if(xintercept>=(mapwidth<<TILESHIFT)) xintercept=mapwidth<<TILESHIFT, xtile=mapwidth-1;
+ xspot=0xffff;
+ tilehit=0;
+ HitVertBorder();
+ break;
+ }
+ if(yspot>=maparea) break;
+ tilehit=((byte *)tilemap)[yspot];
+ if(tilehit)
+ {
+ if(tilehit&0x80)
+ {
+ int32_t xintbuf=xintercept+(xstep>>1);
+ if((xintbuf>>16)!=(xintercept>>16))
+ goto passhoriz;
+ if((word)xintbuf<doorposition[tilehit&0x7f])
+ goto passhoriz;
+ xintercept=xintbuf;
+ yintercept=(ytile<<TILESHIFT)+0x8000;
+ xtile = (short) (xintercept >> TILESHIFT);
+ HitHorizDoor();
+ }
+ else
+ {
+ if(tilehit==64)
+ {
+ if(pwalldir==di_north || pwalldir==di_south)
+ {
+ int32_t xintbuf;
+ int pwallposnorm;
+ int pwallposinv;
+ if(pwalldir==di_north)
+ {
+ pwallposnorm = 64-pwallpos;
+ pwallposinv = pwallpos;
+ }
+ else
+ {
+ pwallposnorm = pwallpos;
+ pwallposinv = 64-pwallpos;
+ }
+ if(pwalldir == di_south && ytile==pwally && ((uint32_t)xintercept>>16)==pwallx
+ || pwalldir == di_north && !(ytile==pwally && ((uint32_t)xintercept>>16)==pwallx))
+ {
+ xintbuf=xintercept+((xstep*pwallposnorm)>>6);
+ if((xintbuf>>16)!=(xintercept>>16))
+ goto passhoriz;
+
+ yintercept=(ytile<<TILESHIFT)+TILEGLOBAL-(pwallposinv<<10);
+ xintercept=xintbuf;
+ xtile = (short) (xintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitHorizWall();
+ }
+ else
+ {
+ xintbuf=xintercept+((xstep*pwallposinv)>>6);
+ if((xintbuf>>16)!=(xintercept>>16))
+ goto passhoriz;
+
+ yintercept=(ytile<<TILESHIFT)-(pwallposinv<<10);
+ xintercept=xintbuf;
+ xtile = (short) (xintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitHorizWall();
+ }
+ }
+ else
+ {
+ int pwallposi = pwallpos;
+ if(pwalldir==di_west) pwallposi = 64-pwallpos;
+ if(pwalldir==di_east && (word)xintercept<(pwallposi<<10)
+ || pwalldir==di_west && (word)xintercept>(pwallposi<<10))
+ {
+ if(((uint32_t)xintercept>>16)==pwallx && ytile==pwally)
+ {
+ if(pwalldir==di_east && (int32_t)((word)xintercept)+xstep<(pwallposi<<10)
+ || pwalldir==di_west && (int32_t)((word)xintercept)+xstep>(pwallposi<<10))
+ goto passhoriz;
+
+ if(pwalldir==di_east)
+ xintercept=(xintercept&0xffff0000)+(pwallposi<<10);
+ else
+ xintercept=(xintercept&0xffff0000)-TILEGLOBAL+(pwallposi<<10);
+ yintercept=yintercept-((ystep*(64-pwallpos))>>6);
+ ytile = (short) (yintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitVertWall();
+ }
+ else
+ {
+ texdelta = -(pwallposi<<10);
+ yintercept=ytile<<TILESHIFT;
+ xtile = (short) (xintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitHorizWall();
+ }
+ }
+ else
+ {
+ if(((uint32_t)xintercept>>16)==pwallx && ytile==pwally)
+ {
+ texdelta = -(pwallposi<<10);
+ yintercept=ytile<<TILESHIFT;
+ xtile = (short) (xintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitHorizWall();
+ }
+ else
+ {
+ if(pwalldir==di_east && (int32_t)((word)xintercept)+xstep>(pwallposi<<10)
+ || pwalldir==di_west && (int32_t)((word)xintercept)+xstep<(pwallposi<<10))
+ goto passhoriz;
+
+ if(pwalldir==di_east)
+ xintercept=(xintercept&0xffff0000)-((64-pwallpos)<<10);
+ else
+ xintercept=(xintercept&0xffff0000)+((64-pwallpos)<<10);
+ yintercept=yintercept-((ystep*pwallpos)>>6);
+ ytile = (short) (yintercept >> TILESHIFT);
+ tilehit=pwalltile;
+ HitVertWall();
+ }
+ }
+ }
+ }
+ else
+ {
+ yintercept=ytile<<TILESHIFT;
+ xtile = (short) (xintercept >> TILESHIFT);
+ HitHorizWall();
+ }
+ }
+ break;
+ }
+passhoriz:
+ *((byte *)spotvis+yspot)=1;
+ ytile+=ytilestep;
+ xintercept+=xstep;
+ yspot=(word)((((uint32_t)xintercept>>16)<<mapshift)+ytile);
+ }
+ while(1);
+ }
+}
+
+/*
+====================
+=
+= WallRefresh
+=
+====================
+*/
+
+void WallRefresh (void)
+{
+ xpartialdown = viewx&(TILEGLOBAL-1);
+ xpartialup = TILEGLOBAL-xpartialdown;
+ ypartialdown = viewy&(TILEGLOBAL-1);
+ ypartialup = TILEGLOBAL-ypartialdown;
+
+ min_wallheight = viewheight;
+ lastside = -1; // the first pixel is on a new wall
+ AsmRefresh ();
+ ScalePost (); // no more optimization on last post
+}
+
+void CalcViewVariables()
+{
+ viewangle = player->angle;
+ midangle = viewangle*(FINEANGLES/ANGLES);
+ viewsin = sintable[viewangle];
+ viewcos = costable[viewangle];
+ viewx = player->x - FixedMul(focallength,viewcos);
+ viewy = player->y + FixedMul(focallength,viewsin);
+
+ focaltx = (short)(viewx>>TILESHIFT);
+ focalty = (short)(viewy>>TILESHIFT);
+
+ viewtx = (short)(player->x >> TILESHIFT);
+ viewty = (short)(player->y >> TILESHIFT);
+}
+
+//==========================================================================
+
+/*
+========================
+=
+= ThreeDRefresh
+=
+========================
+*/
+
+void ThreeDRefresh (void)
+{
+//
+// clear out the traced array
+//
+ memset(spotvis,0,maparea);
+ spotvis[player->tilex][player->tiley] = 1; // Detect all sprites over player fix
+
+ vbuf = VL_LockSurface(screenBuffer);
+ vbuf+=screenofs;
+ vbufPitch = bufferPitch;
+
+ CalcViewVariables();
+
+//
+// follow the walls from there to the right, drawing as we go
+//
+ VGAClearScreen ();
+#if defined(USE_FEATUREFLAGS) && defined(USE_STARSKY)
+ if(GetFeatureFlags() & FF_STARSKY)
+ DrawStarSky(vbuf, vbufPitch);
+#endif
+
+ WallRefresh ();
+
+#if defined(USE_FEATUREFLAGS) && defined(USE_PARALLAX)
+ if(GetFeatureFlags() & FF_PARALLAXSKY)
+ DrawParallax(vbuf, vbufPitch);
+#endif
+#if defined(USE_FEATUREFLAGS) && defined(USE_CLOUDSKY)
+ if(GetFeatureFlags() & FF_CLOUDSKY)
+ DrawClouds(vbuf, vbufPitch, min_wallheight);
+#endif
+#ifdef USE_FLOORCEILINGTEX
+ DrawFloorAndCeiling(vbuf, vbufPitch, min_wallheight);
+#endif
+
+//
+// draw all the scaled images
+//
+ DrawScaleds(); // draw scaled stuff
+
+#if defined(USE_FEATUREFLAGS) && defined(USE_RAIN)
+ if(GetFeatureFlags() & FF_RAIN)
+ DrawRain(vbuf, vbufPitch);
+#endif
+#if defined(USE_FEATUREFLAGS) && defined(USE_SNOW)
+ if(GetFeatureFlags() & FF_SNOW)
+ DrawSnow(vbuf, vbufPitch);
+#endif
+
+ DrawPlayerWeapon (); // draw player's hands
+
+ if(Keyboard[sc_Tab] && viewsize == 21 && gamestate.weapon != -1)
+ ShowActStatus();
+
+ VL_UnlockSurface(screenBuffer);
+ vbuf = NULL;
+
+//
+// show screen and time last cycle
+//
+
+ if (fizzlein)
+ {
+ FizzleFade(screenBuffer, 0, 0, screenWidth, screenHeight, 20, false);
+ fizzlein = false;
+
+ lasttimecount = GetTimeCount(); // don't make a big tic count
+ }
+ else
+ {
+#ifndef REMDEBUG
+ if (fpscounter)
+ {
+ fontnumber = 0;
+ SETFONTCOLOR(7,127);
+ PrintX=4; PrintY=1;
+ VWB_Bar(0,0,50,10,bordercol);
+ US_PrintSigned(fps);
+ US_Print(" fps");
+ }
+#endif
+ SDL_BlitSurface(screenBuffer, NULL, screen, NULL);
+ SDL_Flip(screen);
+ }
+
+#ifndef REMDEBUG
+ if (fpscounter)
+ {
+ fps_frames++;
+ fps_time+=tics;
+
+ if(fps_time>35)
+ {
+ fps_time-=35;
+ fps=fps_frames<<1;
+ fps_frames=0;
+ }
+ }
+#endif
+}