raze/source/sw/src/draw.cpp

1949 lines
56 KiB
C++
Raw Normal View History

//-------------------------------------------------------------------------
/*
Copyright (C) 1997, 2005 - 3D Realms Entertainment
This file is part of Shadow Warrior version 1.2
Shadow Warrior 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.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Original Source: 1997 - Frank Maddin and Jim Norwood
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include "ns.h"
#define QUIET
#include "build.h"
#include "pragmas.h"
#include "names2.h"
#include "panel.h"
#include "game.h"
#include "jsector.h"
#include "mytypes.h"
#include "gamecontrol.h"
#include "network.h"
#include "pal.h"
#include "player.h"
#include "jtags.h"
#include "parent.h"
#include "misc.h"
#include "menus.h"
#include "interp.h"
#include "interpso.h"
#include "sector.h"
#include "menu.h"
#include "v_2ddrawer.h"
#include "v_video.h"
#include "glbackend/glbackend.h"
BEGIN_SW_NS
static int OverlapDraw = FALSE;
2020-08-16 07:04:24 +00:00
extern SWBOOL QuitFlag, LocationInfo, SpriteInfo;
extern SWBOOL Voxel;
extern char buffer[];
SWBOOL DrawScreen;
extern short f_c;
extern ParentalStruct aVoxelArray[MAXTILES];
int ConnectCopySprite(uspritetype const * tsp);
void PreDrawStackedWater(void);
void SW_InitMultiPsky(void)
{
// default
psky_t* const defaultsky = tileSetupSky(DEFAULTPSKY);
defaultsky->lognumtiles = 1;
defaultsky->horizfrac = 8192;
}
#if 1
void
ShadeSprite(tspriteptr_t tsp)
{
// set shade of sprite
tsp->shade = sector[tsp->sectnum].floorshade - 25;
if (tsp->shade > -3)
tsp->shade = -3;
if (tsp->shade < -30)
tsp->shade = -30;
}
#else
#endif
short
GetRotation(short tSpriteNum, int viewx, int viewy)
{
static short RotTable8[] = {0, 7, 6, 5, 4, 3, 2, 1};
static short RotTable5[] = {0, 1, 2, 3, 4, 3, 2, 1};
short rotation;
tspriteptr_t tsp = &tsprite[tSpriteNum];
USERp tu = User[tsp->owner];
short angle2;
if (tu->RotNum == 0)
return 0;
// Get which of the 8 angles of the sprite to draw (0-7)
// rotation ranges from 0-7
angle2 = getangle(tsp->x - viewx, tsp->y - viewy);
rotation = ((tsp->ang + 3072 + 128 - angle2) & 2047);
rotation = (rotation >> 8) & 7;
if (tu->RotNum == 5)
{
if (TEST(tu->Flags, SPR_XFLIP_TOGGLE))
{
if (rotation <= 4)
{
// leave rotation alone
RESET(tsp->cstat, CSTAT_SPRITE_XFLIP);
}
else
{
rotation = (8 - rotation);
SET(tsp->cstat, CSTAT_SPRITE_XFLIP); // clear x-flipping bit
}
}
else
{
if (rotation > 3 || rotation == 0)
{
// leave rotation alone
RESET(tsp->cstat, CSTAT_SPRITE_XFLIP); // clear x-flipping bit
}
else
{
rotation = (8 - rotation);
SET(tsp->cstat, CSTAT_SPRITE_XFLIP); // set
}
}
// Special case bunk
if (tu->ID == TOILETGIRL_R0 || tu->ID == WASHGIRL_R0 || tu->ID == TRASHCAN ||
tu->ID == CARGIRL_R0 || tu->ID == MECHANICGIRL_R0 || tu->ID == PRUNEGIRL_R0 ||
tu->ID == SAILORGIRL_R0)
RESET(tsp->cstat, CSTAT_SPRITE_XFLIP); // clear x-flipping bit
return RotTable5[rotation];
}
return RotTable8[rotation];
}
/*
!AIC - At draw time this is called for actor rotation. GetRotation() is more
complex than needs to be in part because importing of actor rotations and x-flip
directions was not standardized.
*/
int
SetActorRotation(short tSpriteNum, int viewx, int viewy)
{
tspriteptr_t tsp = &tsprite[tSpriteNum];
USERp tu = User[tsp->owner];
short StateOffset, Rotation;
// don't modify ANY tu vars - back them up!
STATEp State = tu->State;
STATEp StateStart = tu->StateStart;
if (tu->RotNum == 0)
return 0;
// Get the offset into the State animation
StateOffset = State - StateStart;
// Get the rotation angle
Rotation = GetRotation(tSpriteNum, viewx, viewy);
ASSERT(Rotation < 5);
// Reset the State animation start based on the Rotation
StateStart = tu->Rot[Rotation];
// Set the sprites state
State = StateStart + StateOffset;
// set the picnum here - may be redundant, but we just changed states and
// thats a big deal
tsp->picnum = State->Pic;
return 0;
}
int
DoShadowFindGroundPoint(tspriteptr_t sp)
{
// USES TSPRITE !!!!!
USERp u = User[sp->owner];
SPRITEp hsp;
int ceilhit, florhit;
int hiz, loz = u->loz;
short save_cstat, bak_cstat;
// recursive routine to find the ground - either sector or floor sprite
// skips over enemy and other types of sprites
// IMPORTANT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This will return invalid FAF ceiling and floor heights inside of analyzesprite
// because the ceiling and floors get moved out of the way for drawing.
save_cstat = sp->cstat;
RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN);
FAFgetzrangepoint(sp->x, sp->y, sp->z, sp->sectnum, &hiz, &ceilhit, &loz, &florhit);
sp->cstat = save_cstat;
ASSERT(TEST(florhit, HIT_SPRITE | HIT_SECTOR));
switch (TEST(florhit, HIT_MASK))
{
case HIT_SPRITE:
{
hsp = &sprite[NORM_SPRITE(florhit)];
if (TEST(hsp->cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR))
{
// found a sprite floor
return loz;
}
else
{
// reset the blocking bit of what you hit and try again -
// recursive
bak_cstat = hsp->cstat;
RESET(hsp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN);
loz = DoShadowFindGroundPoint(sp);
hsp->cstat = bak_cstat;
}
break;
}
case HIT_SECTOR:
break;
default:
ASSERT(TRUE == FALSE);
break;
}
return loz;
}
void
DoShadows(tspriteptr_t tsp, int viewz, SWBOOL mirror)
{
tspriteptr_t New = &tsprite[spritesortcnt];
USERp tu = User[tsp->owner];
int ground_dist = 0;
int view_dist = 0;
int loz;
short xrepeat;
short yrepeat;
short sectnum;
sectnum = tsp->sectnum;
// make sure its the correct sector
// DoShadowFindGroundPoint calls FAFgetzrangepoint and this is sensitive
//updatesectorz(tsp->x, tsp->y, tsp->z, &sectnum);
updatesector(tsp->x, tsp->y, &sectnum);
if (sectnum < 0)
{
return;
}
tsp->sectnum = sectnum;
*New = *tsp;
// shadow is ALWAYS draw last - status is priority
New->statnum = MAXSTATUS;
New->sectnum = sectnum;
if ((tsp->yrepeat >> 2) > 4)
{
yrepeat = (tsp->yrepeat >> 2) - (SPRITEp_SIZE_Y(tsp) / 64) * 2;
xrepeat = New->xrepeat;
}
else
{
yrepeat = New->yrepeat;
xrepeat = New->xrepeat;
}
New->shade = 127;
SET(New->cstat, CSTAT_SPRITE_TRANSLUCENT);
loz = tu->loz;
if (tu->lo_sp)
{
if (!TEST(tu->lo_sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR))
{
loz = DoShadowFindGroundPoint(tsp);
}
}
// need to find the ground here
New->z = loz;
// if below or close to sprites z don't bother to draw it
if ((viewz - loz) > -Z(8))
return;
// if close to shadows z shrink it
view_dist = labs(loz - viewz) >> 8;
if (view_dist < 32)
view_dist = 256/view_dist;
else
view_dist = 0;
// make shadow smaller depending on height from ground
ground_dist = labs(loz - SPRITEp_BOS(tsp)) >> 8;
ground_dist = DIV16(ground_dist);
xrepeat = max(xrepeat - ground_dist - view_dist, 4);
yrepeat = max(yrepeat - ground_dist - view_dist, 4);
xrepeat = min(xrepeat, short(255));
yrepeat = min(yrepeat, short(255));
New->xrepeat = xrepeat;
New->yrepeat = yrepeat;
if (tilehasmodelorvoxel(tsp->picnum,tsp->pal))
{
New->yrepeat = 0;
// cstat: trans reverse
// clipdist: tell mdsprite.cpp to use Z-buffer hacks to hide overdraw issues
New->clipdist |= TSPR_FLAGS_MDHACK;
New->cstat |= 512;
}
else
{
int const camang = mirror ? NORM_ANGLE(2048 - Player[screenpeek].siang) : Player[screenpeek].siang;
vec2_t const ofs = { sintable[NORM_ANGLE(camang+512)]>>11, sintable[NORM_ANGLE(camang)]>>11};
New->x += ofs.x;
New->y += ofs.y;
}
// Check for voxel items and use a round generic pic if so
//DoVoxelShadow(New);
spritesortcnt++;
}
void
DoMotionBlur(tspritetype const * const tsp)
{
USERp tu = User[tsp->owner];
int nx,ny,nz = 0,dx,dy,dz;
short i, ang;
short xrepeat, yrepeat, repeat_adj = 0;
int z_amt_per_pixel;
ang = NORM_ANGLE(tsp->ang + 1024);
if (tsp->xvel == 0)
{
return;
}
if (TEST(tsp->extra, SPRX_PLAYER_OR_ENEMY))
{
z_amt_per_pixel = IntToFixed((int)-tu->jump_speed * ACTORMOVETICS)/tsp->xvel;
}
else
{
z_amt_per_pixel = IntToFixed((int)-tsp->zvel)/tsp->xvel;
}
switch (tu->motion_blur_dist)
{
case 64:
dx = nx = MOVEx(64, ang);
dy = ny = MOVEy(64, ang);
nz = FixedToInt(z_amt_per_pixel * 64);
break;
case 128:
dx = nx = MOVEx(128, ang);
dy = ny = MOVEy(128, ang);
nz = FixedToInt(z_amt_per_pixel * 128);
break;
case 256:
dx = nx = MOVEx(256, ang);
dy = ny = MOVEy(256, ang);
nz = FixedToInt(z_amt_per_pixel * 256);
break;
case 512:
dx = nx = MOVEx(512, ang);
dy = ny = MOVEy(512, ang);
nz = FixedToInt(z_amt_per_pixel * 512);
break;
default:
dx = nx = MOVEx(tu->motion_blur_dist, ang);
dy = ny = MOVEy(tu->motion_blur_dist, ang);
break;
}
dz = nz;
xrepeat = tsp->xrepeat;
yrepeat = tsp->yrepeat;
switch (TEST(tu->Flags2, SPR2_BLUR_TAPER))
{
case 0:
repeat_adj = 0;
break;
case SPR2_BLUR_TAPER_SLOW:
repeat_adj = xrepeat / (tu->motion_blur_num*2);
break;
case SPR2_BLUR_TAPER_FAST:
repeat_adj = xrepeat / tu->motion_blur_num;
break;
}
for (i = 0; i < tu->motion_blur_num; i++)
{
tspriteptr_t New = &tsprite[spritesortcnt];
*New = *tsp;
SET(New->cstat, CSTAT_SPRITE_TRANSLUCENT|CSTAT_SPRITE_TRANSLUCENT_INVERT);
New->x += dx;
New->y += dy;
dx += nx;
dy += ny;
New->z += dz;
dz += nz;
New->xrepeat = xrepeat;
New->yrepeat = yrepeat;
xrepeat -= repeat_adj;
yrepeat -= repeat_adj;
spritesortcnt++;
}
}
void SetVoxelSprite(SPRITEp sp, short pic)
{
SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_SLAB);
sp->picnum = pic;
}
void WarpCopySprite(void)
{
SPRITEp sp1, sp2, sp;
short sn, nsn;
short sn2, nsn2;
short spnum, next_spnum;
int xoff,yoff,zoff;
short match;
short sect1, sect2;
// look for the first one
TRAVERSE_SPRITE_STAT(headspritestat[STAT_WARP_COPY_SPRITE1], sn, nsn)
{
sp1 = &sprite[sn];
match = sp1->lotag;
// look for the second one
TRAVERSE_SPRITE_STAT(headspritestat[STAT_WARP_COPY_SPRITE2], sn2, nsn2)
{
sp = &sprite[sn2];
if (sp->lotag == match)
{
sp2 = sp;
sect1 = sp1->sectnum;
sect2 = sp2->sectnum;
TRAVERSE_SPRITE_SECT(headspritesect[sect1], spnum, next_spnum)
{
if (&sprite[spnum] == sp1)
continue;
if (sprite[spnum].picnum == ST1)
continue;
tspriteptr_t New = renderAddTSpriteFromSprite(spnum);
New->statnum = 0;
xoff = sp1->x - New->x;
yoff = sp1->y - New->y;
zoff = sp1->z - New->z;
New->x = sp2->x - xoff;
New->y = sp2->y - yoff;
New->z = sp2->z - zoff;
New->sectnum = sp2->sectnum;
}
TRAVERSE_SPRITE_SECT(headspritesect[sect2], spnum, next_spnum)
{
if (&sprite[spnum] == sp2)
continue;
if (sprite[spnum].picnum == ST1)
continue;
tspriteptr_t New = renderAddTSpriteFromSprite(spnum);
New->statnum = 0;
xoff = sp2->x - New->x;
yoff = sp2->y - New->y;
zoff = sp2->z - New->z;
New->x = sp1->x - xoff;
New->y = sp1->y - yoff;
New->z = sp1->z - zoff;
New->sectnum = sp1->sectnum;
}
}
}
}
}
void DoStarView(tspriteptr_t tsp, USERp tu, int viewz)
{
extern STATE s_Star[], s_StarDown[];
extern STATE s_StarStuck[], s_StarDownStuck[];
int zdiff = viewz - tsp->z;
if (labs(zdiff) > Z(24))
{
if (tu->StateStart == s_StarStuck)
tsp->picnum = s_StarDownStuck[tu->State - s_StarStuck].Pic;
else
tsp->picnum = s_StarDown[tu->State - s_Star].Pic;
if (zdiff > 0)
SET(tsp->cstat, CSTAT_SPRITE_YFLIP);
}
else
{
if (zdiff > 0)
SET(tsp->cstat, CSTAT_SPRITE_YFLIP);
}
}
void
analyzesprites(int viewx, int viewy, int viewz, SWBOOL mirror)
{
int tSpriteNum;
short SpriteNum;
int smr4, smr2;
USERp tu;
static int ang = 0;
PLAYERp pp = Player + screenpeek;
short newshade=0;
2020-08-16 07:04:24 +00:00
const int DART_PIC = 2526;
const int DART_REPEAT = 16;
ang = NORM_ANGLE(ang + 12);
smr4 = smoothratio + IntToFixed(MoveSkip4);
smr2 = smoothratio + IntToFixed(MoveSkip2);
for (tSpriteNum = spritesortcnt - 1; tSpriteNum >= 0; tSpriteNum--)
{
SpriteNum = tsprite[tSpriteNum].owner;
tspriteptr_t tsp = &tsprite[tSpriteNum];
tu = User[SpriteNum];
#if 0
// Brighten up the sprite if set somewhere else to do so
if (tu && tu->Vis > 0)
{
short tmpshade; // Having this prevent overflow
tmpshade = tsp->shade - tu->Vis;
if (tmpshade < -128) tmpshade = -128;
tsp->shade = tmpshade;
tu->Vis -= 8;
}
#endif
// don't draw these
if (tsp->statnum >= STAT_DONT_DRAW)
{
tsp->owner = -1;
continue;
}
// Diss any parentally locked sprites
if (adult_lockout)
{
if (aVoxelArray[tsp->picnum].Parental == 6145)
{
tsp->owner = -1;
tu = NULL;
}
else if (aVoxelArray[tsp->picnum].Parental > 0)
{
ASSERT(aVoxelArray[tsp->picnum].Parental >= 0 && aVoxelArray[tsp->picnum].Parental < 6145);
tsp->picnum=aVoxelArray[tsp->picnum].Parental; // Change the pic
}
}
if (tu)
{
if (tsp->statnum != STAT_DEFAULT)
{
if (TEST(tu->Flags, SPR_SKIP4))
{
if (tsp->statnum <= STAT_SKIP4_INTERP_END)
{
tsp->x = tu->ox + mulscale18(tsp->x - tu->ox, smr4);
tsp->y = tu->oy + mulscale18(tsp->y - tu->oy, smr4);
tsp->z = tu->oz + mulscale18(tsp->z - tu->oz, smr4);
}
}
if (TEST(tu->Flags, SPR_SKIP2))
{
if (tsp->statnum <= STAT_SKIP2_INTERP_END)
{
tsp->x = tu->ox + mulscale17(tsp->x - tu->ox, smr2);
tsp->y = tu->oy + mulscale17(tsp->y - tu->oy, smr2);
tsp->z = tu->oz + mulscale17(tsp->z - tu->oz, smr2);
}
}
}
// workaround for mines and floor decals beneath the floor
if (tsp->picnum == BETTY_R0 || tsp->picnum == FLOORBLOOD1)
{
auto sp = (uspriteptr_t)&sprite[SpriteNum];
int32_t const floorz = getflorzofslope(sp->sectnum, sp->x, sp->y);
if (sp->z > floorz)
tsp->z = floorz;
}
if (r_shadows && TEST(tu->Flags, SPR_SHADOW))
{
DoShadows(tsp, viewz, mirror);
}
//#define UK_VERSION 1
//#define DART_REPEAT 6
//#define DART_PIC 2233
2019-12-07 19:48:16 +00:00
if (sw_darts)
if (tu->ID == 1793 || tsp->picnum == 1793)
{
tsp->picnum = 2519;
tsp->xrepeat = 27;
tsp->yrepeat = 29;
}
if (tu->ID == STAR1)
{
2019-12-07 19:48:16 +00:00
if (sw_darts)
{
2020-08-16 07:04:24 +00:00
tsp->picnum = DART_PIC;
tsp->ang = NORM_ANGLE(tsp->ang - 512 - 24);
tsp->xrepeat = tsp->yrepeat = DART_REPEAT;
SET(tsp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL);
}
else
DoStarView(tsp, tu, viewz);
}
// rotation
if (tu->RotNum > 0)
SetActorRotation(tSpriteNum, viewx, viewy);
if (tu->motion_blur_num)
{
DoMotionBlur(tsp);
}
// set palette lookup correctly
if (tsp->pal != sector[tsp->sectnum].floorpal)
{
if (sector[tsp->sectnum].floorpal == PALETTE_DEFAULT)
{
// default pal for sprite is stored in tu->spal
// mostly for players and other monster types
tsp->pal = tu->spal;
}
else
{
// if sector pal is something other than default
SECT_USERp sectu = SectUser[tsp->sectnum];
uint8_t pal = sector[tsp->sectnum].floorpal;
SWBOOL nosectpal=FALSE;
// sprite does not take on the new pal if sector flag is set
if (sectu && TEST(sectu->flags, SECTFU_DONT_COPY_PALETTE))
{
pal = PALETTE_DEFAULT;
nosectpal = TRUE;
}
//if(tu->spal == PALETTE_DEFAULT)
if (tsp->hitag != SECTFU_DONT_COPY_PALETTE && tsp->hitag != LUMINOUS
&& !nosectpal
&& pal != PALETTE_FOG && pal != PALETTE_DIVE &&
pal != PALETTE_DIVE_LAVA)
tsp->pal = pal;
else
tsp->pal = tu->spal;
}
}
// Sprite debug information mode
if (tsp->hitag == 9997)
{
tsp->pal = PALETTE_RED_LIGHTING;
// Turn it off, it gets reset by PrintSpriteInfo
sprite[tu->SpriteNum].hitag = 0;
}
}
2019-12-07 19:48:16 +00:00
if (sw_darts)
if (tsp->statnum == STAT_STAR_QUEUE)
{
tsp->picnum = DART_PIC;
tsp->ang = NORM_ANGLE(tsp->ang - 512);
tsp->xrepeat = tsp->yrepeat = DART_REPEAT;
SET(tsp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL);
}
// Call my sprite handler
// Does autosizing and voxel handling
JAnalyzeSprites(tsp);
// only do this of you are a player sprite
//if (tsp->statnum >= STAT_PLAYER0 && tsp->statnum < STAT_PLAYER0 + MAX_SW_PLAYERS)
if (tu && tu->PlayerP)
{
// Shadow spell
if (!TEST(tsp->cstat, CSTAT_SPRITE_TRANSLUCENT))
ShadeSprite(tsp);
// sw if its your playersprite
//if ((Player + screenpeek)->PlayerSprite == SpriteNum)
if ((Player + screenpeek)->PlayerSprite == tu->SpriteNum)
{
PLAYERp pp = Player + screenpeek;
if (mirror || TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE|PF_VIEW_FROM_CAMERA))
{
if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE))
SET(tsp->cstat, CSTAT_SPRITE_TRANSLUCENT);
if (TEST(pp->Flags, PF_CLIMBING))
{
// move sprite forward some so he looks like he's
// climbing
tsp->x = pp->six + MOVEx(128 + 80, tsp->ang);
tsp->y = pp->siy + MOVEy(128 + 80, tsp->ang);
}
else
{
tsp->x = pp->six;
tsp->y = pp->siy;
}
tsp->z = tsp->z + pp->siz;
tsp->ang = pp->siang;
//continue;
}
else
{
// dont draw your sprite
tsp->owner = -1;
//SET(tsp->cstat, CSTAT_SPRITE_INVISIBLE);
}
}
else // Otherwise just interpolate the player sprite
{
PLAYERp pp = tu->PlayerP;
tsp->x -= mulscale16(pp->posx - pp->oposx, 65536-smoothratio);
tsp->y -= mulscale16(pp->posy - pp->oposy, 65536-smoothratio);
tsp->z -= mulscale16(pp->posz - pp->oposz, 65536-smoothratio);
tsp->ang -= FixedToInt(mulscale16(pp->q16ang - pp->oq16ang, 65536-smoothratio));
}
}
if (OverlapDraw && FAF_ConnectArea(tsp->sectnum) && tsp->owner >= 0)
{
EDUKE32_STATIC_ASSERT(sizeof(uspritetype) == sizeof(tspritetype)); // see TSPRITE_SIZE
ConnectCopySprite((uspriteptr_t)tsp);
}
//
// kens original sprite shade code he moved out of the engine
//
switch (tsp->statnum)
{
case STAT_ENEMY:
case STAT_DEAD_ACTOR:
case STAT_FAF_COPY:
break;
default:
newshade = tsp->shade;
newshade += 6;
if (newshade > 127) newshade = 127;
tsp->shade = newshade;
}
if (TEST(sector[tsp->sectnum].ceilingstat, CEILING_STAT_PLAX))
{
newshade = tsp->shade;
newshade += sector[tsp->sectnum].ceilingshade;
if (newshade > 127) newshade = 127;
if (newshade < -128) newshade = -128;
tsp->shade = newshade;
}
else
{
newshade = tsp->shade;
newshade += sector[tsp->sectnum].floorshade;
if (newshade > 127) newshade = 127;
if (newshade < -128) newshade = -128;
tsp->shade = newshade;
}
if (tsp->hitag == 9998)
tsp->shade = 127; // Invisible enemy ninjas
// Correct shades for luminous sprites
if (tsp->hitag == LUMINOUS)
{
tsp->shade = -128;
}
if (pp->NightVision && TEST(tsp->extra, SPRX_PLAYER_OR_ENEMY))
{
if (tu && tu->ID == TRASHCAN) continue; // Don't light up trashcan
tsp->pal = PALETTE_ILLUMINATE; // Make sprites REALLY bright green.
tsp->shade = -128;
}
if (tu && tu->PlayerP)
{
if (TEST(tu->Flags2, SPR2_VIS_SHADING))
{
if ((Player + screenpeek)->PlayerSprite != tu->SpriteNum)
{
if (!TEST(tu->PlayerP->Flags, PF_VIEW_FROM_OUTSIDE))
{
RESET(tsp->cstat, CSTAT_SPRITE_TRANSLUCENT);
}
}
tsp->shade = 12 - STD_RANDOM_RANGE(30);
}
}
}
WarpCopySprite();
}
#if 1
tspriteptr_t get_tsprite(short SpriteNum)
{
int tSpriteNum;
for (tSpriteNum = spritesortcnt - 1; tSpriteNum >= 0; tSpriteNum--)
{
if (tsprite[tSpriteNum].owner == SpriteNum)
return &tsprite[tSpriteNum];
}
return NULL;
}
void
post_analyzesprites(void)
{
int tSpriteNum;
short SpriteNum;
USERp tu;
for (tSpriteNum = spritesortcnt - 1; tSpriteNum >= 0; tSpriteNum--)
{
SpriteNum = tsprite[tSpriteNum].owner;
if (SpriteNum < 0) continue; // JBF: verify this is safe
tspriteptr_t tsp = &tsprite[tSpriteNum];
tu = User[SpriteNum];
if (tu)
{
if (tu->ID == FIREBALL_FLAMES && tu->Attach >= 0)
{
//uspritetype * const atsp = &sprite[tu->Attach];
tspriteptr_t const atsp = get_tsprite(tu->Attach);
if (!atsp)
{
//DSPRINTF(ds,"Attach not found");
MONO_PRINT(ds);
continue;
}
tsp->x = atsp->x;
tsp->y = atsp->y;
// statnum is priority - draw this ALWAYS first at 0
// statnum is priority - draw this ALWAYS last at MAXSTATUS
if (TEST(atsp->extra, SPRX_BURNABLE))
{
atsp->statnum = 1;
tsp->statnum = 0;
}
else
tsp->statnum = MAXSTATUS;
}
}
}
}
#endif
2020-09-02 16:59:56 +00:00
static int nonsharedtimer;
void
ResizeView(PLAYERp pp)
{
2020-09-02 16:59:56 +00:00
int ms = screen->FrameTime;
int interval;
if (nonsharedtimer > 0 || ms < nonsharedtimer)
{
interval = ms - nonsharedtimer;
}
else
{
interval = 0;
}
nonsharedtimer = screen->FrameTime;
if (System_WantGuiCapture())
return;
if (automapMode != am_off)
{
2020-09-02 16:59:56 +00:00
double j = interval * (120. / 1000);
if (buttonMap.ButtonDown(gamefunc_Enlarge_Screen))
2020-09-02 16:59:56 +00:00
zoom += (int)fmulscale6(j, max(zoom, 256));
if (buttonMap.ButtonDown(gamefunc_Shrink_Screen))
zoom -= (int)fmulscale6(j, max(zoom, 256));
2020-09-02 16:59:56 +00:00
zoom = clamp(zoom, 48, 2048);
}
}
void
BackView(int *nx, int *ny, int *nz, short *vsect, fixed_t *nq16ang, short horiz)
{
vec3_t n = { *nx, *ny, *nz };
SPRITEp sp;
hitdata_t hitinfo;
int i, vx, vy, vz, hx, hy;
short bakcstat, daang;
PLAYERp pp = &Player[screenpeek];
short ang;
ASSERT(*vsect >= 0 && *vsect < MAXSECTORS);
ang = FixedToInt(*nq16ang) + pp->view_outside_dang;
// Calculate the vector (nx,ny,nz) to shoot backwards
vx = (sintable[NORM_ANGLE(ang + 1536)] >> 3);
vy = (sintable[NORM_ANGLE(ang + 1024)] >> 3);
vz = (horiz - 100) * 256L;
// Player sprite of current view
sp = &sprite[pp->PlayerSprite];
bakcstat = sp->cstat;
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
// Make sure sector passed to FAFhitscan is correct
//COVERupdatesector(*nx, *ny, vsect);
hitscan(&n, *vsect, vx, vy, vz,
&hitinfo, CLIPMASK_PLAYER);
ASSERT(*vsect >= 0 && *vsect < MAXSECTORS);
sp->cstat = bakcstat; // Restore cstat
hx = hitinfo.pos.x - (*nx);
hy = hitinfo.pos.y - (*ny);
// If something is in the way, make pp->camera_dist lower if necessary
if (klabs(vx) + klabs(vy) > klabs(hx) + klabs(hy))
{
if (hitinfo.wall >= 0) // Push you a little bit off the wall
{
*vsect = hitinfo.sect;
daang = getangle(wall[wall[hitinfo.wall].point2].x - wall[hitinfo.wall].x,
wall[wall[hitinfo.wall].point2].y - wall[hitinfo.wall].y);
i = vx * sintable[daang] + vy * sintable[NORM_ANGLE(daang + 1536)];
if (klabs(vx) > klabs(vy))
hx -= mulscale28(vx, i);
else
hy -= mulscale28(vy, i);
}
else if (hitinfo.sprite < 0) // Push you off the ceiling/floor
{
*vsect = hitinfo.sect;
if (klabs(vx) > klabs(vy))
hx -= (vx >> 5);
else
hy -= (vy >> 5);
}
else
{
SPRITEp hsp = &sprite[hitinfo.sprite];
int flag_backup;
// if you hit a sprite that's not a wall sprite - try again
if (!TEST(hsp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL))
{
flag_backup = hsp->cstat;
RESET(hsp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
ASSERT(*vsect >= 0 && *vsect < MAXSECTORS);
BackView(nx, ny, nz, vsect, nq16ang, horiz);
hsp->cstat = flag_backup;
return;
}
else
{
// same as wall calculation
daang = NORM_ANGLE(sp->ang-512);
i = vx * sintable[daang] + vy * sintable[NORM_ANGLE(daang + 1536)];
if (klabs(vx) > klabs(vy))
hx -= mulscale28(vx, i);
else
hy -= mulscale28(vy, i);
}
}
if (klabs(vx) > klabs(vy))
i = IntToFixed(hx) / vx;
else
i = IntToFixed(hy) / vy;
if (i < pp->camera_dist)
pp->camera_dist = i;
}
// Actually move you! (Camerdist is 65536 if nothing is in the way)
*nx = (*nx) + mulscale16(vx, pp->camera_dist);
*ny = (*ny) + mulscale16(vy, pp->camera_dist);
*nz = (*nz) + mulscale16(vz, pp->camera_dist);
// Slowly increase pp->camera_dist until it reaches 65536
// Synctics is a timer variable so it increases the same rate
// on all speed computers
pp->camera_dist = min(pp->camera_dist + (3 << 10), 65536);
//pp->camera_dist = min(pp->camera_dist + (synctics << 10), 65536);
// Make sure vsect is correct
updatesectorz(*nx, *ny, *nz, vsect);
*nq16ang = IntToFixed(ang);
}
void
CircleCamera(int *nx, int *ny, int *nz, short *vsect, int *nq16ang, short horiz)
{
vec3_t n = { *nx, *ny, *nz };
SPRITEp sp;
hitdata_t hitinfo;
int i, vx, vy, vz, hx, hy;
short bakcstat, daang;
PLAYERp pp = &Player[screenpeek];
short ang;
ang = FixedToInt(*nq16ang) + pp->circle_camera_ang;
// Calculate the vector (nx,ny,nz) to shoot backwards
vx = (sintable[NORM_ANGLE(ang + 1536)] >> 4);
vy = (sintable[NORM_ANGLE(ang + 1024)] >> 4);
// lengthen the vector some
vx += DIV2(vx);
vy += DIV2(vy);
vz = (horiz - 100) * 256;
// Player sprite of current view
sp = &sprite[pp->PlayerSprite];
bakcstat = sp->cstat;
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
// Make sure sector passed to hitscan is correct
//COVERupdatesector(*nx, *ny, vsect);
hitscan(&n, *vsect, vx, vy, vz,
&hitinfo, CLIPMASK_MISSILE);
sp->cstat = bakcstat; // Restore cstat
//ASSERT(hitinfo.sect >= 0);
hx = hitinfo.pos.x - (*nx);
hy = hitinfo.pos.y - (*ny);
// If something is in the way, make pp->circle_camera_dist lower if necessary
if (klabs(vx) + klabs(vy) > klabs(hx) + klabs(hy))
{
if (hitinfo.wall >= 0) // Push you a little bit off the wall
{
*vsect = hitinfo.sect;
daang = getangle(wall[wall[hitinfo.wall].point2].x - wall[hitinfo.wall].x,
wall[wall[hitinfo.wall].point2].y - wall[hitinfo.wall].y);
i = vx * sintable[daang] + vy * sintable[NORM_ANGLE(daang + 1536)];
if (klabs(vx) > klabs(vy))
hx -= mulscale28(vx, i);
else
hy -= mulscale28(vy, i);
}
else if (hitinfo.sprite < 0) // Push you off the ceiling/floor
{
*vsect = hitinfo.sect;
if (klabs(vx) > klabs(vy))
hx -= (vx >> 5);
else
hy -= (vy >> 5);
}
else
{
SPRITEp hsp = &sprite[hitinfo.sprite];
int flag_backup;
// if you hit a sprite that's not a wall sprite - try again
if (!TEST(hsp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL))
{
flag_backup = hsp->cstat;
RESET(hsp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
CircleCamera(nx, ny, nz, vsect, nq16ang, horiz);
hsp->cstat = flag_backup;
return;
}
}
if (klabs(vx) > klabs(vy))
i = IntToFixed(hx) / vx;
else
i = IntToFixed(hy) / vy;
if (i < pp->circle_camera_dist)
pp->circle_camera_dist = i;
}
// Actually move you! (Camerdist is 65536 if nothing is in the way)
*nx = (*nx) + FixedToInt(vx * pp->circle_camera_dist);
*ny = (*ny) + FixedToInt(vy * pp->circle_camera_dist);
*nz = (*nz) + FixedToInt(vz * pp->circle_camera_dist);
// Slowly increase pp->circle_camera_dist until it reaches 65536
// Synctics is a timer variable so it increases the same rate
// on all speed computers
pp->circle_camera_dist = min(pp->circle_camera_dist + (3 << 8), 65536);
//pp->circle_camera_dist = min(pp->circle_camera_dist + (synctics << 10), 65536);
// Make sure vsect is correct
updatesectorz(*nx, *ny, *nz, vsect);
*nq16ang = IntToFixed(ang);
}
FString GameInterface::GetCoordString()
{
PLAYERp pp = Player + myconnectindex;
FString out;
out.AppendFormat("POSX:%d ", pp->posx);
out.AppendFormat("POSY:%d ", pp->posy);
out.AppendFormat("POSZ:%d ", pp->posz);
out.AppendFormat("ANG:%d\n", FixedToInt(pp->camq16ang));
return out;
}
void PrintSpriteInfo(PLAYERp pp)
{
2020-08-16 07:04:24 +00:00
const int Y_STEP = 7;
int x = windowxy1.x+2;
int y = windowxy1.y+2;
SPRITEp sp;
USERp u;
//if (SpriteInfo && !LocationInfo)
{
short hit_sprite = DoPickTarget(pp->SpriteP, 32, 2);
sp = &sprite[hit_sprite];
u = User[hit_sprite];
sp->hitag = 9997; // Special tag to make the actor glow red for one frame
if (hit_sprite == -1)
{
Printf("SPRITENUM: NONE TARGETED\n");
return;
}
else
Printf("SPRITENUM:%d\n", hit_sprite);
if (u)
{
Printf("ID:%d, ", u->ID);
Printf("PALETTE:%d, ", u->spal);
Printf("HEALTH:%d, ", u->Health);
Printf("WAITTICS:%d, ", u->WaitTics);
Printf("COUNTER:%d, ", u->Counter);
Printf("COUNTER2:%d\n", u->Counter);
}
if (sp)
{
Printf("POSX:%d, ", TrackerCast(sp->x));
Printf("POSY:%d, ", TrackerCast(sp->y));
Printf("POSZ:%d,", TrackerCast(sp->z));
Printf("ANG:%d\n", TrackerCast(sp->ang));
}
}
}
void SpriteSortList2D(int tx, int ty)
{
SPRITEp sp;
int i;
int dist,a,b,c;
spritesortcnt = 0;
for (i = 0; i < MAXSPRITES; i++)
{
if (sprite[i].statnum < MAXSTATUS)
{
sp = &sprite[i];
if (!TEST(sp->cstat, CSTAT_SPRITE_INVISIBLE) &&
(sp->xrepeat > 0) && (sp->yrepeat > 0) &&
(spritesortcnt < MAXSPRITESONSCREEN))
{
DISTANCE(tx,ty,sp->x,sp->y,dist,a,b,c);
if (dist < 22000)
{
renderAddTSpriteFromSprite(i);
}
}
}
}
}
void DrawCrosshair(PLAYERp pp)
{
2020-08-15 20:31:44 +00:00
extern SWBOOL CameraTestMode;
if (cl_crosshair && !(CameraTestMode) && !TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE) && automapMode == am_off)
{
int32_t a = 2326;
2020-08-17 18:28:12 +00:00
double crosshair_scale = cl_crosshairscale * .02;
if (isRR()) crosshair_scale *= .5;
DrawTexture(twod, tileGetTexture(a), 160, 100, DTA_Color, shadeToLight(10),
DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, crosshair_scale, DTA_ScaleY, crosshair_scale, DTA_CenterOffsetRel, true,
DTA_ViewportX, windowxy1.x, DTA_ViewportY, windowxy1.y, DTA_ViewportWidth, windowxy2.x - windowxy1.x + 1, DTA_ViewportHeight, windowxy2.y - windowxy1.y + 1, TAG_DONE);
}
}
void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, fixed_t *tq16ang, fixed_t *tq16horiz)
{
int i,nexti;
short ang;
SPRITEp sp;
SWBOOL found_camera = FALSE;
SWBOOL player_in_camera = FALSE;
SWBOOL FAFcansee_test;
SWBOOL ang_test;
if (pp == &Player[screenpeek])
{
TRAVERSE_SPRITE_STAT(headspritestat[STAT_DEMO_CAMERA], i, nexti)
{
sp = &sprite[i];
ang = getangle(*tx - sp->x, *ty - sp->y);
ang_test = GetDeltaAngle(sp->ang, ang) < sp->lotag;
FAFcansee_test =
(FAFcansee(sp->x, sp->y, sp->z, sp->sectnum, *tx, *ty, *tz, pp->cursectnum) ||
FAFcansee(sp->x, sp->y, sp->z, sp->sectnum, *tx, *ty, *tz + SPRITEp_SIZE_Z(pp->SpriteP), pp->cursectnum));
player_in_camera = ang_test && FAFcansee_test;
if (player_in_camera || pp->camera_check_time_delay > 0)
{
// if your not in the camera but are still looking
// make sure that only the last camera shows you
if (!player_in_camera && pp->camera_check_time_delay > 0)
{
if (pp->last_camera_sp != sp)
continue;
}
switch (sp->clipdist)
{
case 1:
pp->last_camera_sp = sp;
CircleCamera(tx, ty, tz, tsectnum, tq16ang, 100);
found_camera = TRUE;
break;
default:
{
int xvect,yvect,zvect,zdiff;
pp->last_camera_sp = sp;
xvect = sintable[NORM_ANGLE(ang + 512)] >> 3;
yvect = sintable[NORM_ANGLE(ang)] >> 3;
zdiff = sp->z - *tz;
if (labs(sp->x - *tx) > 1000)
zvect = scale(xvect, zdiff, sp->x - *tx);
else if (labs(sp->y - *ty) > 1000)
zvect = scale(yvect, zdiff, sp->y - *ty);
else if (sp->x - *tx != 0)
zvect = scale(xvect, zdiff, sp->x - *tx);
else if (sp->y - *ty != 0)
zvect = scale(yvect, zdiff, sp->y - *ty);
else
zvect = 0;
// new horiz to player
*tq16horiz = IntToFixed(100 - (zvect/256));
*tq16horiz = max(*tq16horiz, IntToFixed(PLAYER_HORIZ_MIN));
*tq16horiz = min(*tq16horiz, IntToFixed(PLAYER_HORIZ_MAX));
//DSPRINTF(ds,"xvect %d,yvect %d,zvect %d,tq16horiz %d",xvect,yvect,zvect,*tq16horiz);
MONO_PRINT(ds);
*tq16ang = IntToFixed(ang);
*tx = sp->x;
*ty = sp->y;
*tz = sp->z;
*tsectnum = sp->sectnum;
found_camera = TRUE;
break;
}
}
}
if (found_camera)
break;
}
}
// if you player_in_camera you definately have a camera
if (player_in_camera)
{
pp->camera_check_time_delay = 120/2;
SET(pp->Flags, PF_VIEW_FROM_CAMERA);
ASSERT(found_camera);
}
else
// if you !player_in_camera you still might have a camera
// for a split second
{
if (found_camera)
{
SET(pp->Flags, PF_VIEW_FROM_CAMERA);
}
else
{
pp->circle_camera_ang = 0;
pp->circle_camera_dist = CIRCLE_CAMERA_DIST_MIN;
RESET(pp->Flags, PF_VIEW_FROM_CAMERA);
}
}
}
void
PreDraw(void)
{
short i, nexti;
PreDrawStackedWater();
TRAVERSE_SPRITE_STAT(headspritestat[STAT_FLOOR_SLOPE_DONT_DRAW], i, nexti)
{
RESET(sector[sprite[i].sectnum].floorstat, FLOOR_STAT_SLOPE);
}
}
void
PostDraw(void)
{
short i, nexti;
TRAVERSE_SPRITE_STAT(headspritestat[STAT_FLOOR_SLOPE_DONT_DRAW], i, nexti)
{
SET(sector[sprite[i].sectnum].floorstat, FLOOR_STAT_SLOPE);
}
TRAVERSE_SPRITE_STAT(headspritestat[STAT_FAF_COPY], i, nexti)
{
if (User[i])
{
FreeMem(User[i]);
User[i] = NULL;
}
deletesprite(i);
}
}
int CopySprite(uspritetype const * tsp, short newsector)
{
short New;
SPRITEp sp;
New = COVERinsertsprite(newsector, STAT_FAF_COPY);
sp = &sprite[New];
sp->x = tsp->x;
sp->y = tsp->y;
sp->z = tsp->z;
sp->cstat = tsp->cstat;
sp->picnum = tsp->picnum;
sp->pal = tsp->pal;
sp->xrepeat = tsp->xrepeat;
sp->yrepeat = tsp->yrepeat;
sp->xoffset = tsp->xoffset;
sp->yoffset = tsp->yoffset;
sp->ang = tsp->ang;
sp->xvel = tsp->xvel;
sp->yvel = tsp->yvel;
sp->zvel = tsp->zvel;
sp->shade = tsp->shade;
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
return New;
}
int ConnectCopySprite(uspritetype const * tsp)
{
short newsector;
int testz;
if (FAF_ConnectCeiling(tsp->sectnum))
{
newsector = tsp->sectnum;
testz = SPRITEp_TOS(tsp) - Z(10);
if (testz < sector[tsp->sectnum].ceilingz)
updatesectorz(tsp->x, tsp->y, testz, &newsector);
if (newsector >= 0 && newsector != tsp->sectnum)
{
return CopySprite(tsp, newsector);
}
}
if (FAF_ConnectFloor(tsp->sectnum))
{
newsector = tsp->sectnum;
testz = SPRITEp_BOS(tsp) + Z(10);
if (testz > sector[tsp->sectnum].floorz)
updatesectorz(tsp->x, tsp->y, testz, &newsector);
if (newsector >= 0 && newsector != tsp->sectnum)
{
return CopySprite(tsp, newsector);
}
}
return -1;
}
void PreDrawStackedWater(void)
{
short si,snexti;
short i,nexti;
SPRITEp sp;
USERp u,nu;
short New;
TRAVERSE_SPRITE_STAT(headspritestat[STAT_CEILING_FLOOR_PIC_OVERRIDE], si, snexti)
{
TRAVERSE_SPRITE_SECT(headspritesect[sprite[si].sectnum], i, nexti)
{
if (User[i])
{
if (sprite[i].statnum == STAT_ITEM)
continue;
if (sprite[i].statnum <= STAT_DEFAULT || sprite[i].statnum > STAT_PLAYER0 + MAX_SW_PLAYERS)
continue;
// code so that a copied sprite will not make another copy
if (User[i]->xchange == -989898)
continue;
sp = &sprite[i];
u = User[i];
New = ConnectCopySprite((uspritetype const *)sp);
if (New >= 0)
{
// spawn a user
User[New] = nu = (USERp)CallocMem(sizeof(USER), 1);
ASSERT(nu != NULL);
nu->xchange = -989898;
// copy everything reasonable from the user that
// analyzesprites() needs to draw the image
nu->State = u->State;
nu->Rot = u->Rot;
nu->StateStart = u->StateStart;
nu->StateEnd = u->StateEnd;
nu->ox = u->ox;
nu->oy = u->oy;
nu->oz = u->oz;
nu->Flags = u->Flags;
nu->Flags2 = u->Flags2;
nu->RotNum = u->RotNum;
nu->ID = u->ID;
// set these to other sprite for players draw
nu->SpriteNum = i;
nu->SpriteP = sp;
nu->PlayerP = u->PlayerP;
nu->spal = u->spal;
}
}
}
}
}
void FAF_DrawRooms(int x, int y, int z, fixed_t q16ang, fixed_t q16horiz, short sectnum)
{
short i,nexti;
TRAVERSE_SPRITE_STAT(headspritestat[STAT_CEILING_FLOOR_PIC_OVERRIDE], i, nexti)
{
if (SPRITE_TAG3(i) == 0)
{
// back up ceilingpicnum and ceilingstat
SPRITE_TAG5(i) = sector[sprite[i].sectnum].ceilingpicnum;
sector[sprite[i].sectnum].ceilingpicnum = SPRITE_TAG2(i);
SPRITE_TAG4(i) = sector[sprite[i].sectnum].ceilingstat;
//SET(sector[sprite[i].sectnum].ceilingstat, ((int)SPRITE_TAG7(i))<<7);
SET(sector[sprite[i].sectnum].ceilingstat, SPRITE_TAG6(i));
RESET(sector[sprite[i].sectnum].ceilingstat, CEILING_STAT_PLAX);
}
else if (SPRITE_TAG3(i) == 1)
{
SPRITE_TAG5(i) = sector[sprite[i].sectnum].floorpicnum;
sector[sprite[i].sectnum].floorpicnum = SPRITE_TAG2(i);
SPRITE_TAG4(i) = sector[sprite[i].sectnum].floorstat;
//SET(sector[sprite[i].sectnum].floorstat, ((int)SPRITE_TAG7(i))<<7);
SET(sector[sprite[i].sectnum].floorstat, SPRITE_TAG6(i));
RESET(sector[sprite[i].sectnum].floorstat, FLOOR_STAT_PLAX);
}
}
2020-03-29 08:03:00 +00:00
renderDrawRoomsQ16(x,y,z,q16ang,q16horiz,sectnum);
TRAVERSE_SPRITE_STAT(headspritestat[STAT_CEILING_FLOOR_PIC_OVERRIDE], i, nexti)
{
// manually set gotpic
if (TEST_GOTSECTOR(sprite[i].sectnum))
{
SET_GOTPIC(FAF_MIRROR_PIC);
}
if (SPRITE_TAG3(i) == 0)
{
// restore ceilingpicnum and ceilingstat
sector[sprite[i].sectnum].ceilingpicnum = SPRITE_TAG5(i);
sector[sprite[i].sectnum].ceilingstat = SPRITE_TAG4(i);
//RESET(sector[sprite[i].sectnum].ceilingstat, CEILING_STAT_TYPE_MASK);
RESET(sector[sprite[i].sectnum].ceilingstat, CEILING_STAT_PLAX);
}
else if (SPRITE_TAG3(i) == 1)
{
sector[sprite[i].sectnum].floorpicnum = SPRITE_TAG5(i);
sector[sprite[i].sectnum].floorstat = SPRITE_TAG4(i);
//RESET(sector[sprite[i].sectnum].floorstat, FLOOR_STAT_TYPE_MASK);
RESET(sector[sprite[i].sectnum].floorstat, FLOOR_STAT_PLAX);
}
}
}
short ScreenSavePic = FALSE;
SWBOOL PicInView(short, SWBOOL);
void DoPlayerDiveMeter(PLAYERp pp);
Revert "SW: Improve main game loop." This reverts commit e878c5bab8bc15e00e7a999a018f59ba4980505c. Revert "SW: Use Q16.16 for horiz." This reverts commit f07a0ae01ef8340c4b32c2b110bcb1431ae93c4f. Revert "SW: Use Q16.16 for angle." This reverts commit 1ecc74c2ecd8bb310c0099249ce148a28a73e26a. Revert "SW: Minor repairs for Q16.16 implementation." This reverts commit d78d046bad6c1679fff32efaa98bc6b4478d20eb. Revert "SW: Process input at frame rate." This reverts commit c162014dab5433dff2c5c3e5397178c992e1e761. Revert "SW: Amendments to accommodate changes in master." This reverts commit eaa51138add0d83568fafb79bc9afa35fe67a64f. Revert "SW: Fix incorrectly declared function input type." This reverts commit 1cdd5b08d82a88eb57013e78a34e4ef9e0796d34. Revert "SW: Amend scaleAdjustmentToInterval() with correct value for SW." This reverts commit d4dd737cd54e5c30c41a339fba6cefad696f3a42. Revert "SW: Refinements to new input code." This reverts commit 5ebc65a1fb19f86c2add664470108002a0078945. Revert "SW: Adjust look and snap up/down keys and slightly tune PLAYER_TURN_AMOUNT." This reverts commit 2852536dbf50f4cab58a158083b8c6e2de6ac1dd. Revert "SW: Get PLAYER_TURN_SCALE to be just right." This reverts commit 4630c8a0b7a24819e04a14a64efff5d4b36271cf. Revert "SW: Make map follow mode work better." This reverts commit 8e94c48eff599078364a7b0a7b94750cd40daf28. Revert "SW: Remove line accidentally left from 'MoveScrollMode2D()'." This reverts commit 5db8047b413548d3ef02d08d1d581c303a3d5907. Revert "Fix multiplayer desync after the change to q16 angle and horiz." This reverts commit 3bc46078b833e27fab42eaa77a0f5071c35dd584. Revert "SW: Revert commented out horiz->q16horiz renames in DSPRINTF strings" This reverts commit 537313f620dc98a832d862aff86a78e0b3b3cb23. Revert "sw/src/draw.cpp:drawscreen: We can set the pp->si* fields just once," This reverts commit d2e9595980c283d62de28f029b5f6394bf2522ff. Revert "sw/src/game.cpp:LoadLevel: Rename q16ang -> ang" This reverts commit a178961a3eed2522147f60d7265bb2d08f4a0bfe. Revert "SW: Minor tweaks." This reverts commit 377ba68344e34495638c6fa7685ff78c9a0ed6f8. Revert "SW: Further refine turning and optimise horizon adjustment." This reverts commit 039022d9ac476cc784e47633bfbac039a965f217. Revert "SW: Don't process input at frame rate if ScrollMode2D is true." This reverts commit 1aa1e62c4d4dc1fff24201ff8eaebcccef6d7646. Revert "SW: Use a bit more Q16.16 in places." This reverts commit 40ca656f38de5d941cf5deac440eeafa965df3bd. Revert "SW: Use the old interpolation path in drawscreen if player is dead" This reverts commit 2d734664259e47b999fe989b924ecaa0a97bb109. Revert "SW: Smooth out 180 degree turn landing and replace some fix16_min/max with fix16_clamp." This reverts commit 0996e87f7991490d70fba9e5b525e7c7404ce637. Revert "Change Next/Previous Weapon button handling for Shadow Warrior." This reverts commit f6b8ca6a223923b0ec5665aedacd729391ea1d4d. Revert "SW: Make "Center_View" key return smoothly." This reverts commit 23c401fbc28845a7ecb1ad9b29d0e72781b052b5. Revert "SW: Use the old interpolation path in drawscreen if player is dead" This reverts commit 43ec16eb5576124bed3699943bb70b9ea943bd93. Revert "Interpolation fixes for SW:" This reverts commit ac8a7ecfbdfbe9152a8ead605723c1d18eca7798. Revert "SW: Reset the number of interpolations on level load" This reverts commit 04bf8499e72fd48e1e6e7487d743b38a2a206a14. Revert "Another change modifying saved game format in SW:" This reverts commit e80888523ea62df60c69b098236f6af1f994177a. Revert "SW: Interpolate sector objects in non-demo, single player games." This reverts commit 996ab77cf47b5eeb142d6c93e7b307418f3b53a6. Revert "- fixed merge errors in SW." This reverts commit b8cfa94568b85e4ed51c558f09734ede794ad988. Revert "- fix interpolation stutters when opening console for SW." This reverts commit 99fdbfb6cb62bd02d91f4b2d95339cbd918c71fa. Revert "- reset buttonMap button states after returning from pause for SW (stops keys acting stuck down if down prior to pausing)." This reverts commit 693b6955dac84b13fc5de91aee29364c3be6e526. Revert "SW: fix stupid input scaling bug" This reverts commit 1c79e6e17c0028e650f525db6cdbd1b38095708e. Revert "SW: Make vehicle input better." This reverts commit 670a53c402f08ac0aecd721f8c5cf1543f699250. Revert "SW: Change fix16_from_float() to fix16_from_int() that was changed in 4630c8a0b7a24819e04a14a64efff5d4b36271cf but should have been reverted in 377ba68344e34495638c6fa7685ff78c9a0ed6f8." This reverts commit 423c9da071844bdfb716d39e1cd2cf103727a37c. Revert "SW: Remove ScrollMode2D extern boolean and move into PLAYERp struct." This reverts commit 31eb55c1fa69bfe90c09ce9611e0d32445341284.
2020-05-19 11:44:52 +00:00
void MoveScrollMode2D(PLAYERp pp);
void
drawscreen(PLAYERp pp, double smoothratio)
{
2020-08-15 20:31:44 +00:00
extern SWBOOL CameraTestMode;
int tx, ty, tz;
fixed_t tq16horiz, tq16ang;
2020-03-29 08:03:00 +00:00
short tsectnum;
short i,j;
int bob_amt = 0;
int quake_z, quake_x, quake_y;
short quake_ang;
extern SWBOOL FAF_DebugView;
PLAYERp camerapp; // prediction player if prediction is on, else regular player
// last valid stuff
static short lv_sectnum = -1;
static int lv_x, lv_y, lv_z;
int const viewingRange = viewingrange;
DrawScreen = TRUE;
PreDraw();
PreUpdatePanel(smoothratio);
if (!ScreenSavePic)
{
dointerpolations(smoothratio); // Stick at beginning of drawscreen
short_dointerpolations(smoothratio); // Stick at beginning of drawscreen
if (cl_sointerpolation)
so_dointerpolations(smoothratio); // Stick at beginning of drawscreen
}
// TENSW: when rendering with prediction, the only thing that counts should
// be the predicted player.
if (PredictionOn && CommEnabled && pp == Player+myconnectindex)
camerapp = ppp;
else
camerapp = pp;
tx = camerapp->oposx + xs_CRoundToInt(fmulscale16(camerapp->posx - camerapp->oposx, smoothratio));
ty = camerapp->oposy + xs_CRoundToInt(fmulscale16(camerapp->posy - camerapp->oposy, smoothratio));
tz = camerapp->oposz + xs_CRoundToInt(fmulscale16(camerapp->posz - camerapp->oposz, smoothratio));
// TODO: It'd be better to check pp->input.q16angvel instead, problem is that
// it's been repurposed for the q16ang diff while tying input to framerate
if (cl_syncinput || (pp != Player+myconnectindex) ||
(TEST(pp->Flags, PF_DEAD) && (loc.q16avel == 0)))
2020-04-11 07:17:59 +00:00
{
tq16ang = camerapp->oq16ang + xs_CRoundToInt(fmulscale16(NORM_Q16ANGLE(camerapp->q16ang + IntToFixed(1024) - camerapp->oq16ang) - IntToFixed(1024), smoothratio));
tq16horiz = camerapp->oq16horiz + xs_CRoundToInt(fmulscale16(camerapp->q16horiz - camerapp->oq16horiz, smoothratio));
2020-04-11 07:17:59 +00:00
}
else if (cl_sointerpolation && !CommEnabled)
{
tq16ang = camerapp->oq16ang + xs_CRoundToInt(fmulscale16(((pp->camq16ang + IntToFixed(1024) - camerapp->oq16ang) & 0x7FFFFFF) - IntToFixed(1024), smoothratio));
tq16horiz = camerapp->oq16horiz + xs_CRoundToInt(fmulscale16(pp->camq16horiz - camerapp->oq16horiz, smoothratio));
}
2020-04-11 07:17:59 +00:00
else
{
tq16ang = pp->camq16ang;
tq16horiz = pp->camq16horiz;
}
tsectnum = camerapp->cursectnum;
COVERupdatesector(tx, ty, &tsectnum);
2020-08-16 07:04:24 +00:00
if (tsectnum >= 0)
{
// last valid stuff
lv_sectnum = tsectnum;
lv_x = tx;
lv_y = ty;
lv_z = tz;
}
if (pp->sop_riding || pp->sop_control)
{
if (pp->sop_control &&
(!cl_sointerpolation || (CommEnabled && !pp->sop_remote)))
{
tx = pp->posx;
ty = pp->posy;
tz = pp->posz;
tq16ang = pp->q16ang;
}
tsectnum = pp->cursectnum;
updatesectorz(tx, ty, tz, &tsectnum);
Revert "SW: Improve main game loop." This reverts commit e878c5bab8bc15e00e7a999a018f59ba4980505c. Revert "SW: Use Q16.16 for horiz." This reverts commit f07a0ae01ef8340c4b32c2b110bcb1431ae93c4f. Revert "SW: Use Q16.16 for angle." This reverts commit 1ecc74c2ecd8bb310c0099249ce148a28a73e26a. Revert "SW: Minor repairs for Q16.16 implementation." This reverts commit d78d046bad6c1679fff32efaa98bc6b4478d20eb. Revert "SW: Process input at frame rate." This reverts commit c162014dab5433dff2c5c3e5397178c992e1e761. Revert "SW: Amendments to accommodate changes in master." This reverts commit eaa51138add0d83568fafb79bc9afa35fe67a64f. Revert "SW: Fix incorrectly declared function input type." This reverts commit 1cdd5b08d82a88eb57013e78a34e4ef9e0796d34. Revert "SW: Amend scaleAdjustmentToInterval() with correct value for SW." This reverts commit d4dd737cd54e5c30c41a339fba6cefad696f3a42. Revert "SW: Refinements to new input code." This reverts commit 5ebc65a1fb19f86c2add664470108002a0078945. Revert "SW: Adjust look and snap up/down keys and slightly tune PLAYER_TURN_AMOUNT." This reverts commit 2852536dbf50f4cab58a158083b8c6e2de6ac1dd. Revert "SW: Get PLAYER_TURN_SCALE to be just right." This reverts commit 4630c8a0b7a24819e04a14a64efff5d4b36271cf. Revert "SW: Make map follow mode work better." This reverts commit 8e94c48eff599078364a7b0a7b94750cd40daf28. Revert "SW: Remove line accidentally left from 'MoveScrollMode2D()'." This reverts commit 5db8047b413548d3ef02d08d1d581c303a3d5907. Revert "Fix multiplayer desync after the change to q16 angle and horiz." This reverts commit 3bc46078b833e27fab42eaa77a0f5071c35dd584. Revert "SW: Revert commented out horiz->q16horiz renames in DSPRINTF strings" This reverts commit 537313f620dc98a832d862aff86a78e0b3b3cb23. Revert "sw/src/draw.cpp:drawscreen: We can set the pp->si* fields just once," This reverts commit d2e9595980c283d62de28f029b5f6394bf2522ff. Revert "sw/src/game.cpp:LoadLevel: Rename q16ang -> ang" This reverts commit a178961a3eed2522147f60d7265bb2d08f4a0bfe. Revert "SW: Minor tweaks." This reverts commit 377ba68344e34495638c6fa7685ff78c9a0ed6f8. Revert "SW: Further refine turning and optimise horizon adjustment." This reverts commit 039022d9ac476cc784e47633bfbac039a965f217. Revert "SW: Don't process input at frame rate if ScrollMode2D is true." This reverts commit 1aa1e62c4d4dc1fff24201ff8eaebcccef6d7646. Revert "SW: Use a bit more Q16.16 in places." This reverts commit 40ca656f38de5d941cf5deac440eeafa965df3bd. Revert "SW: Use the old interpolation path in drawscreen if player is dead" This reverts commit 2d734664259e47b999fe989b924ecaa0a97bb109. Revert "SW: Smooth out 180 degree turn landing and replace some fix16_min/max with fix16_clamp." This reverts commit 0996e87f7991490d70fba9e5b525e7c7404ce637. Revert "Change Next/Previous Weapon button handling for Shadow Warrior." This reverts commit f6b8ca6a223923b0ec5665aedacd729391ea1d4d. Revert "SW: Make "Center_View" key return smoothly." This reverts commit 23c401fbc28845a7ecb1ad9b29d0e72781b052b5. Revert "SW: Use the old interpolation path in drawscreen if player is dead" This reverts commit 43ec16eb5576124bed3699943bb70b9ea943bd93. Revert "Interpolation fixes for SW:" This reverts commit ac8a7ecfbdfbe9152a8ead605723c1d18eca7798. Revert "SW: Reset the number of interpolations on level load" This reverts commit 04bf8499e72fd48e1e6e7487d743b38a2a206a14. Revert "Another change modifying saved game format in SW:" This reverts commit e80888523ea62df60c69b098236f6af1f994177a. Revert "SW: Interpolate sector objects in non-demo, single player games." This reverts commit 996ab77cf47b5eeb142d6c93e7b307418f3b53a6. Revert "- fixed merge errors in SW." This reverts commit b8cfa94568b85e4ed51c558f09734ede794ad988. Revert "- fix interpolation stutters when opening console for SW." This reverts commit 99fdbfb6cb62bd02d91f4b2d95339cbd918c71fa. Revert "- reset buttonMap button states after returning from pause for SW (stops keys acting stuck down if down prior to pausing)." This reverts commit 693b6955dac84b13fc5de91aee29364c3be6e526. Revert "SW: fix stupid input scaling bug" This reverts commit 1c79e6e17c0028e650f525db6cdbd1b38095708e. Revert "SW: Make vehicle input better." This reverts commit 670a53c402f08ac0aecd721f8c5cf1543f699250. Revert "SW: Change fix16_from_float() to fix16_from_int() that was changed in 4630c8a0b7a24819e04a14a64efff5d4b36271cf but should have been reverted in 377ba68344e34495638c6fa7685ff78c9a0ed6f8." This reverts commit 423c9da071844bdfb716d39e1cd2cf103727a37c. Revert "SW: Remove ScrollMode2D extern boolean and move into PLAYERp struct." This reverts commit 31eb55c1fa69bfe90c09ce9611e0d32445341284.
2020-05-19 11:44:52 +00:00
}
pp->six = tx;
pp->siy = ty;
pp->siz = tz - pp->posz;
pp->siang = FixedToInt(tq16ang);
QuakeViewChange(camerapp, &quake_z, &quake_x, &quake_y, &quake_ang);
VisViewChange(camerapp, &g_visibility);
tz = tz + quake_z;
tx = tx + quake_x;
ty = ty + quake_y;
//tq16horiz = tq16horiz + IntToFixed(quake_x);
tq16ang = IntToFixed(NORM_ANGLE(FixedToInt(tq16ang) + quake_ang));
if (pp->sop_remote)
{
if (TEST_BOOL1(pp->remote_sprite))
tq16ang = IntToFixed(pp->remote_sprite->ang);
else
tq16ang = gethiq16angle(pp->sop_remote->xmid - tx, pp->sop_remote->ymid - ty);
}
if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE))
{
BackView(&tx, &ty, &tz, &tsectnum, &tq16ang, FixedToInt(tq16horiz));
}
else
{
bob_amt = camerapp->bob_amt;
2020-08-15 20:31:44 +00:00
if (CameraTestMode)
2020-03-28 11:31:02 +00:00
{
CameraView(camerapp, &tx, &ty, &tz, &tsectnum, &tq16ang, &tq16horiz);
2020-03-28 11:31:02 +00:00
}
}
if (!TEST(pp->Flags, PF_VIEW_FROM_CAMERA|PF_VIEW_FROM_OUTSIDE))
{
tz += bob_amt;
tz += pp->obob_z + xs_CRoundToInt(fmulscale16(pp->bob_z - pp->obob_z, smoothratio));
// recoil only when not in camera
tq16horiz = tq16horiz + IntToFixed(pp->recoil_horizoff);
tq16horiz = max(tq16horiz, IntToFixed(PLAYER_HORIZ_MIN));
tq16horiz = min(tq16horiz, IntToFixed(PLAYER_HORIZ_MAX));
}
if (automapMode != am_full)// && !ScreenSavePic)
{
// Cameras must be done before the main loop.
JS_DrawCameras(pp, tx, ty, tz);
}
videoSetCorrectedAspect();
renderSetAspect(Blrintf(float(viewingrange)* tanf(r_fov* (fPI / 360.f))), yxaspect);
OverlapDraw = TRUE;
2020-03-29 08:03:00 +00:00
DrawOverlapRoom(tx, ty, tz, tq16ang, tq16horiz, tsectnum);
OverlapDraw = FALSE;
if (automapMode != am_full)// && !ScreenSavePic)
{
// TEST this! Changed to camerapp
2020-03-29 08:03:00 +00:00
//JS_DrawMirrors(camerapp, tx, ty, tz, tq16ang, tq16horiz);
JS_DrawMirrors(pp, tx, ty, tz, tq16ang, tq16horiz);
}
// TODO: This call is redundant if the tiled overhead map is shown, but the
// HUD elements should be properly outputted with hardware rendering first.
if (!FAF_DebugView)
2020-03-29 08:03:00 +00:00
FAF_DrawRooms(tx, ty, tz, tq16ang, tq16horiz, tsectnum);
analyzesprites(tx, ty, tz, FALSE);
post_analyzesprites();
renderDrawMasks();
renderSetAspect(viewingRange, divscale16(ydim * 8, xdim * 5));
UpdatePanel(smoothratio);
#define SLIME 2305
// Only animate lava if its picnum is on screen
// gotpic is a bit array where the tile number's bit is set
// whenever it is drawn (ceilings, walls, sprites, etc.)
#if 0 // This needs a different implementation.
if ((gotpic[SLIME >> 3] & (1 << (SLIME & 7))) > 0)
{
gotpic[SLIME >> 3] &= ~(1 << (SLIME & 7));
if (waloff[SLIME])
movelava((char *) waloff[SLIME]);
}
#endif
i = pp->cursectnum;
if (i >= 0)
{
show2dsector.Set(i);
walltype *wal = &wall[sector[i].wallptr];
for (j=sector[i].wallnum; j>0; j--,wal++)
{
i = wal->nextsector;
if (i < 0) continue;
if (wal->cstat&0x0071) continue;
uint16_t const nextwall = wal->nextwall;
if (nextwall < MAXWALLS && wall[nextwall].cstat&0x0071) continue;
if (sector[i].lotag == 32767) continue;
if (sector[i].ceilingz >= sector[i].floorz) continue;
show2dsector.Set(i);
}
}
if ((automapMode != am_off) && pp == Player+myconnectindex)
{
if (automapFollow)
{
Revert "SW: Improve main game loop." This reverts commit e878c5bab8bc15e00e7a999a018f59ba4980505c. Revert "SW: Use Q16.16 for horiz." This reverts commit f07a0ae01ef8340c4b32c2b110bcb1431ae93c4f. Revert "SW: Use Q16.16 for angle." This reverts commit 1ecc74c2ecd8bb310c0099249ce148a28a73e26a. Revert "SW: Minor repairs for Q16.16 implementation." This reverts commit d78d046bad6c1679fff32efaa98bc6b4478d20eb. Revert "SW: Process input at frame rate." This reverts commit c162014dab5433dff2c5c3e5397178c992e1e761. Revert "SW: Amendments to accommodate changes in master." This reverts commit eaa51138add0d83568fafb79bc9afa35fe67a64f. Revert "SW: Fix incorrectly declared function input type." This reverts commit 1cdd5b08d82a88eb57013e78a34e4ef9e0796d34. Revert "SW: Amend scaleAdjustmentToInterval() with correct value for SW." This reverts commit d4dd737cd54e5c30c41a339fba6cefad696f3a42. Revert "SW: Refinements to new input code." This reverts commit 5ebc65a1fb19f86c2add664470108002a0078945. Revert "SW: Adjust look and snap up/down keys and slightly tune PLAYER_TURN_AMOUNT." This reverts commit 2852536dbf50f4cab58a158083b8c6e2de6ac1dd. Revert "SW: Get PLAYER_TURN_SCALE to be just right." This reverts commit 4630c8a0b7a24819e04a14a64efff5d4b36271cf. Revert "SW: Make map follow mode work better." This reverts commit 8e94c48eff599078364a7b0a7b94750cd40daf28. Revert "SW: Remove line accidentally left from 'MoveScrollMode2D()'." This reverts commit 5db8047b413548d3ef02d08d1d581c303a3d5907. Revert "Fix multiplayer desync after the change to q16 angle and horiz." This reverts commit 3bc46078b833e27fab42eaa77a0f5071c35dd584. Revert "SW: Revert commented out horiz->q16horiz renames in DSPRINTF strings" This reverts commit 537313f620dc98a832d862aff86a78e0b3b3cb23. Revert "sw/src/draw.cpp:drawscreen: We can set the pp->si* fields just once," This reverts commit d2e9595980c283d62de28f029b5f6394bf2522ff. Revert "sw/src/game.cpp:LoadLevel: Rename q16ang -> ang" This reverts commit a178961a3eed2522147f60d7265bb2d08f4a0bfe. Revert "SW: Minor tweaks." This reverts commit 377ba68344e34495638c6fa7685ff78c9a0ed6f8. Revert "SW: Further refine turning and optimise horizon adjustment." This reverts commit 039022d9ac476cc784e47633bfbac039a965f217. Revert "SW: Don't process input at frame rate if ScrollMode2D is true." This reverts commit 1aa1e62c4d4dc1fff24201ff8eaebcccef6d7646. Revert "SW: Use a bit more Q16.16 in places." This reverts commit 40ca656f38de5d941cf5deac440eeafa965df3bd. Revert "SW: Use the old interpolation path in drawscreen if player is dead" This reverts commit 2d734664259e47b999fe989b924ecaa0a97bb109. Revert "SW: Smooth out 180 degree turn landing and replace some fix16_min/max with fix16_clamp." This reverts commit 0996e87f7991490d70fba9e5b525e7c7404ce637. Revert "Change Next/Previous Weapon button handling for Shadow Warrior." This reverts commit f6b8ca6a223923b0ec5665aedacd729391ea1d4d. Revert "SW: Make "Center_View" key return smoothly." This reverts commit 23c401fbc28845a7ecb1ad9b29d0e72781b052b5. Revert "SW: Use the old interpolation path in drawscreen if player is dead" This reverts commit 43ec16eb5576124bed3699943bb70b9ea943bd93. Revert "Interpolation fixes for SW:" This reverts commit ac8a7ecfbdfbe9152a8ead605723c1d18eca7798. Revert "SW: Reset the number of interpolations on level load" This reverts commit 04bf8499e72fd48e1e6e7487d743b38a2a206a14. Revert "Another change modifying saved game format in SW:" This reverts commit e80888523ea62df60c69b098236f6af1f994177a. Revert "SW: Interpolate sector objects in non-demo, single player games." This reverts commit 996ab77cf47b5eeb142d6c93e7b307418f3b53a6. Revert "- fixed merge errors in SW." This reverts commit b8cfa94568b85e4ed51c558f09734ede794ad988. Revert "- fix interpolation stutters when opening console for SW." This reverts commit 99fdbfb6cb62bd02d91f4b2d95339cbd918c71fa. Revert "- reset buttonMap button states after returning from pause for SW (stops keys acting stuck down if down prior to pausing)." This reverts commit 693b6955dac84b13fc5de91aee29364c3be6e526. Revert "SW: fix stupid input scaling bug" This reverts commit 1c79e6e17c0028e650f525db6cdbd1b38095708e. Revert "SW: Make vehicle input better." This reverts commit 670a53c402f08ac0aecd721f8c5cf1543f699250. Revert "SW: Change fix16_from_float() to fix16_from_int() that was changed in 4630c8a0b7a24819e04a14a64efff5d4b36271cf but should have been reverted in 377ba68344e34495638c6fa7685ff78c9a0ed6f8." This reverts commit 423c9da071844bdfb716d39e1cd2cf103727a37c. Revert "SW: Remove ScrollMode2D extern boolean and move into PLAYERp struct." This reverts commit 31eb55c1fa69bfe90c09ce9611e0d32445341284.
2020-05-19 11:44:52 +00:00
tx = Follow_posx;
ty = Follow_posy;
}
for (j = 0; j < MAXSPRITES; j++)
{
// Don't show sprites tagged with 257
if (sprite[j].lotag == 257)
{
if (TEST(sprite[j].cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR))
{
RESET(sprite[j].cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR);
sprite[j].owner = -2;
}
}
}
if (automapMode == am_full)
{
// only clear the actual window.
twod->AddColorOnlyQuad(windowxy1.x, windowxy1.y, (windowxy2.x + 1) - windowxy1.x, (windowxy2.y + 1) - windowxy1.y, 0xff000000);
2020-09-02 16:59:56 +00:00
renderDrawMapView(tx, ty, zoom*2, FixedToInt(tq16ang));
}
// Draw the line map on top of texture 2d map or just stand alone
2020-09-02 16:59:56 +00:00
drawoverheadmap(tx, ty, zoom*2, FixedToInt(tq16ang));
}
for (j = 0; j < MAXSPRITES; j++)
{
// Don't show sprites tagged with 257
if (sprite[j].lotag == 257 && sprite[j].owner == -2)
SET(sprite[j].cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR);
}
// if doing a screen save don't need to process the rest
if (ScreenSavePic)
{
DrawScreen = FALSE;
return;
}
//PrintLocationInfo(pp);
//PrintSpriteInfo(pp);
#if SYNC_TEST
SyncStatMessage();
#endif
2020-09-02 16:59:56 +00:00
UpdateStatusBar();
DrawCrosshair(pp);
DoPlayerDiveMeter(pp); // Do the underwater breathing bar
// Boss Health Meter, if Boss present
BossHealthMeter();
#if SYNC_TEST
SyncStatMessage();
#endif
// certain input is done here - probably shouldn't be
2020-08-16 15:09:59 +00:00
ResizeView(pp);
restoreinterpolations(); // Stick at end of drawscreen
short_restoreinterpolations(); // Stick at end of drawscreen
if (cl_sointerpolation)
so_restoreinterpolations(); // Stick at end of drawscreen
if (paused && !M_Active())
{
MNU_DrawString(160, 100, "Game Paused", 0, 0, 0);
}
if (!CommEnabled && TEST(pp->Flags, PF_DEAD))
{
if (ReloadPrompt)
{
ReloadPrompt = FALSE;
}
}
PostDraw();
DrawScreen = FALSE;
}
bool GameInterface::GenerateSavePic()
{
ScreenSavePic = TRUE;
drawscreen(Player + myconnectindex, 65536);
ScreenSavePic = FALSE;
return true;
}
END_SW_NS