mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-16 20:50:38 +00:00
- split Blood prediction code into its own file.
This commit is contained in:
parent
a9820abcae
commit
e2498a53a9
5 changed files with 778 additions and 751 deletions
|
@ -52,6 +52,7 @@ set( PCH_SOURCES
|
||||||
src/nnexts.cpp
|
src/nnexts.cpp
|
||||||
src/osdcmd.cpp
|
src/osdcmd.cpp
|
||||||
src/player.cpp
|
src/player.cpp
|
||||||
|
src/prediction.cpp
|
||||||
src/qav.cpp
|
src/qav.cpp
|
||||||
src/replace.cpp
|
src/replace.cpp
|
||||||
src/sbar.cpp
|
src/sbar.cpp
|
||||||
|
|
|
@ -97,9 +97,6 @@ CEndGameMgr::CEndGameMgr()
|
||||||
void CEndGameMgr::Draw(void)
|
void CEndGameMgr::Draw(void)
|
||||||
{
|
{
|
||||||
drawTextScreenBackground();
|
drawTextScreenBackground();
|
||||||
int nHeight;
|
|
||||||
viewGetFontInfo(1, NULL, NULL, &nHeight);
|
|
||||||
int nY = 20 - nHeight / 2;
|
|
||||||
if (gGameOptions.nGameType == 0)
|
if (gGameOptions.nGameType == 0)
|
||||||
{
|
{
|
||||||
DrawMenuCaption(GStrings("TXTB_LEVELSTATS"));
|
DrawMenuCaption(GStrings("TXTB_LEVELSTATS"));
|
||||||
|
|
730
source/blood/src/prediction.cpp
Normal file
730
source/blood/src/prediction.cpp
Normal file
|
@ -0,0 +1,730 @@
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
||||||
|
Copyright (C) 2019 Nuke.YKT
|
||||||
|
|
||||||
|
This file is part of NBlood.
|
||||||
|
|
||||||
|
NBlood is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License version 2
|
||||||
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
#include "ns.h" // Must come before everything else!
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "compat.h"
|
||||||
|
#include "build.h"
|
||||||
|
#include "pragmas.h"
|
||||||
|
#include "mmulti.h"
|
||||||
|
#include "v_font.h"
|
||||||
|
|
||||||
|
#include "endgame.h"
|
||||||
|
#include "aistate.h"
|
||||||
|
#include "map2d.h"
|
||||||
|
#include "loadsave.h"
|
||||||
|
#include "sectorfx.h"
|
||||||
|
#include "choke.h"
|
||||||
|
#include "view.h"
|
||||||
|
#include "nnexts.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
#include "menu.h"
|
||||||
|
#include "gstrings.h"
|
||||||
|
#include "v_2ddrawer.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "v_font.h"
|
||||||
|
#include "glbackend/glbackend.h"
|
||||||
|
|
||||||
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
void fakePlayerProcess(PLAYER* pPlayer, GINPUT* pInput);
|
||||||
|
void fakeActProcessSprites(void);
|
||||||
|
|
||||||
|
bool gPrediction = true;
|
||||||
|
VIEW predict, predictOld;
|
||||||
|
static VIEW predictFifo[256];
|
||||||
|
|
||||||
|
void viewInitializePrediction(void)
|
||||||
|
{
|
||||||
|
predict.at30 = gMe->q16ang;
|
||||||
|
predict.at20 = gMe->q16look;
|
||||||
|
predict.at24 = gMe->q16horiz;
|
||||||
|
predict.at28 = gMe->q16slopehoriz;
|
||||||
|
predict.at2c = gMe->slope;
|
||||||
|
predict.at6f = gMe->cantJump;
|
||||||
|
predict.at70 = gMe->isRunning;
|
||||||
|
predict.at72 = gMe->isUnderwater;
|
||||||
|
predict.at71 = gMe->input.buttonFlags.jump;
|
||||||
|
predict.at50 = gMe->pSprite->x;
|
||||||
|
predict.at54 = gMe->pSprite->y;
|
||||||
|
predict.at58 = gMe->pSprite->z;
|
||||||
|
predict.at68 = gMe->pSprite->sectnum;
|
||||||
|
predict.at73 = gMe->pSprite->flags;
|
||||||
|
predict.at5c = xvel[gMe->pSprite->index];
|
||||||
|
predict.at60 = yvel[gMe->pSprite->index];
|
||||||
|
predict.at64 = zvel[gMe->pSprite->index];
|
||||||
|
predict.at6a = gMe->pXSprite->height;
|
||||||
|
predict.at48 = gMe->posture;
|
||||||
|
predict.at4c = gMe->spin;
|
||||||
|
predict.at6e = gMe->input.keyFlags.lookCenter;
|
||||||
|
memcpy(&predict.at75,&gSpriteHit[gMe->pSprite->extra],sizeof(SPRITEHIT));
|
||||||
|
predict.at0 = gMe->bobPhase;
|
||||||
|
predict.at4 = gMe->bobAmp;
|
||||||
|
predict.at8 = gMe->bobHeight;
|
||||||
|
predict.atc = gMe->bobWidth;
|
||||||
|
predict.at10 = gMe->swayPhase;
|
||||||
|
predict.at14 = gMe->swayAmp;
|
||||||
|
predict.at18 = gMe->swayHeight;
|
||||||
|
predict.at1c = gMe->swayWidth;
|
||||||
|
predict.at34 = gMe->zWeapon-gMe->zView-(12<<8);
|
||||||
|
predict.at38 = gMe->zView;
|
||||||
|
predict.at3c = gMe->zViewVel;
|
||||||
|
predict.at40 = gMe->zWeapon;
|
||||||
|
predict.at44 = gMe->zWeaponVel;
|
||||||
|
predictOld = predict;
|
||||||
|
if (numplayers != 1)
|
||||||
|
{
|
||||||
|
gViewAngle = predict.at30;
|
||||||
|
gViewLook = predict.at20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void viewUpdatePrediction(GINPUT *pInput)
|
||||||
|
{
|
||||||
|
predictOld = predict;
|
||||||
|
short bakCstat = gMe->pSprite->cstat;
|
||||||
|
gMe->pSprite->cstat = 0;
|
||||||
|
fakePlayerProcess(gMe, pInput);
|
||||||
|
fakeActProcessSprites();
|
||||||
|
gMe->pSprite->cstat = bakCstat;
|
||||||
|
predictFifo[gPredictTail&255] = predict;
|
||||||
|
gPredictTail++;
|
||||||
|
if (numplayers != 1)
|
||||||
|
{
|
||||||
|
gViewAngle = predict.at30;
|
||||||
|
gViewLook = predict.at20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sub_158B4(PLAYER *pPlayer)
|
||||||
|
{
|
||||||
|
predict.at38 = predict.at58 - pPlayer->pPosture[pPlayer->lifeMode][predict.at48].eyeAboveZ;
|
||||||
|
predict.at40 = predict.at58 - pPlayer->pPosture[pPlayer->lifeMode][predict.at48].weaponAboveZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fakeProcessInput(PLAYER *pPlayer, GINPUT *pInput)
|
||||||
|
{
|
||||||
|
POSTURE *pPosture = &pPlayer->pPosture[pPlayer->lifeMode][predict.at48];
|
||||||
|
|
||||||
|
if (numplayers > 1 && gPrediction)
|
||||||
|
{
|
||||||
|
gViewAngleAdjust = 0.f;
|
||||||
|
gViewLookRecenter = false;
|
||||||
|
gViewLookAdjust = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
predict.at70 = pInput->syncFlags.run;
|
||||||
|
predict.at70 = 0;
|
||||||
|
predict.at71 = pInput->buttonFlags.jump;
|
||||||
|
if (predict.at48 == 1)
|
||||||
|
{
|
||||||
|
int x = Cos(fix16_to_int(predict.at30));
|
||||||
|
int y = Sin(fix16_to_int(predict.at30));
|
||||||
|
if (pInput->forward)
|
||||||
|
{
|
||||||
|
int forward = pInput->forward;
|
||||||
|
if (forward > 0)
|
||||||
|
forward = mulscale8(pPosture->frontAccel, forward);
|
||||||
|
else
|
||||||
|
forward = mulscale8(pPosture->backAccel, forward);
|
||||||
|
predict.at5c += mulscale30(forward, x);
|
||||||
|
predict.at60 += mulscale30(forward, y);
|
||||||
|
}
|
||||||
|
if (pInput->strafe)
|
||||||
|
{
|
||||||
|
int strafe = pInput->strafe;
|
||||||
|
strafe = mulscale8(pPosture->sideAccel, strafe);
|
||||||
|
predict.at5c += mulscale30(strafe, y);
|
||||||
|
predict.at60 -= mulscale30(strafe, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (predict.at6a < 0x100)
|
||||||
|
{
|
||||||
|
int speed = 0x10000;
|
||||||
|
if (predict.at6a > 0)
|
||||||
|
speed -= divscale16(predict.at6a, 0x100);
|
||||||
|
int x = Cos(fix16_to_int(predict.at30));
|
||||||
|
int y = Sin(fix16_to_int(predict.at30));
|
||||||
|
if (pInput->forward)
|
||||||
|
{
|
||||||
|
int forward = pInput->forward;
|
||||||
|
if (forward > 0)
|
||||||
|
forward = mulscale8(pPosture->frontAccel, forward);
|
||||||
|
else
|
||||||
|
forward = mulscale8(pPosture->backAccel, forward);
|
||||||
|
if (predict.at6a)
|
||||||
|
forward = mulscale16(forward, speed);
|
||||||
|
predict.at5c += mulscale30(forward, x);
|
||||||
|
predict.at60 += mulscale30(forward, y);
|
||||||
|
}
|
||||||
|
if (pInput->strafe)
|
||||||
|
{
|
||||||
|
int strafe = pInput->strafe;
|
||||||
|
strafe = mulscale8(pPosture->sideAccel, strafe);
|
||||||
|
if (predict.at6a)
|
||||||
|
strafe = mulscale16(strafe, speed);
|
||||||
|
predict.at5c += mulscale30(strafe, y);
|
||||||
|
predict.at60 -= mulscale30(strafe, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pInput->q16turn)
|
||||||
|
predict.at30 = (predict.at30+pInput->q16turn)&0x7ffffff;
|
||||||
|
if (pInput->keyFlags.spin180)
|
||||||
|
if (!predict.at4c)
|
||||||
|
predict.at4c = -1024;
|
||||||
|
if (predict.at4c < 0)
|
||||||
|
{
|
||||||
|
int speed;
|
||||||
|
if (predict.at48 == 1)
|
||||||
|
speed = 64;
|
||||||
|
else
|
||||||
|
speed = 128;
|
||||||
|
|
||||||
|
predict.at4c = min(predict.at4c+speed, 0);
|
||||||
|
predict.at30 += fix16_from_int(speed);
|
||||||
|
if (numplayers > 1 && gPrediction)
|
||||||
|
gViewAngleAdjust += float(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!predict.at71)
|
||||||
|
predict.at6f = 0;
|
||||||
|
|
||||||
|
switch (predict.at48)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (predict.at71)
|
||||||
|
predict.at64 -= pPosture->normalJumpZ;//0x5b05;
|
||||||
|
if (pInput->buttonFlags.crouch)
|
||||||
|
predict.at64 += pPosture->normalJumpZ;//0x5b05;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (!pInput->buttonFlags.crouch)
|
||||||
|
predict.at48 = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!predict.at6f && predict.at71 && predict.at6a == 0) {
|
||||||
|
if (packItemActive(pPlayer, 4)) predict.at64 = pPosture->pwupJumpZ;//-0x175555;
|
||||||
|
else predict.at64 = pPosture->normalJumpZ;//-0xbaaaa;
|
||||||
|
predict.at6f = 1;
|
||||||
|
}
|
||||||
|
if (pInput->buttonFlags.crouch)
|
||||||
|
predict.at48 = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if (predict.at6e && !pInput->buttonFlags.lookUp && !pInput->buttonFlags.lookDown)
|
||||||
|
{
|
||||||
|
if (predict.at20 < 0)
|
||||||
|
predict.at20 = fix16_min(predict.at20+fix16_from_int(4), fix16_from_int(0));
|
||||||
|
if (predict.at20 > 0)
|
||||||
|
predict.at20 = fix16_max(predict.at20-fix16_from_int(4), fix16_from_int(0));
|
||||||
|
if (predict.at20 == 0)
|
||||||
|
predict.at6e = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pInput->buttonFlags.lookUp)
|
||||||
|
predict.at20 = fix16_min(predict.at20+fix16_from_int(4), fix16_from_int(60));
|
||||||
|
if (pInput->buttonFlags.lookDown)
|
||||||
|
predict.at20 = fix16_max(predict.at20-fix16_from_int(4), fix16_from_int(-60));
|
||||||
|
}
|
||||||
|
predict.at20 = fix16_clamp(predict.at20+pInput->q16mlook, fix16_from_int(-60), fix16_from_int(60));
|
||||||
|
|
||||||
|
if (predict.at20 > 0)
|
||||||
|
predict.at24 = mulscale30(fix16_from_int(120), Sin(fix16_to_int(predict.at20<<3)));
|
||||||
|
else if (predict.at20 < 0)
|
||||||
|
predict.at24 = mulscale30(fix16_from_int(180), Sin(fix16_to_int(predict.at20<<3)));
|
||||||
|
else
|
||||||
|
predict.at24 = 0;
|
||||||
|
#endif
|
||||||
|
int upAngle = 289;
|
||||||
|
int downAngle = -347;
|
||||||
|
double lookStepUp = 4.0*upAngle/60.0;
|
||||||
|
double lookStepDown = -4.0*downAngle/60.0;
|
||||||
|
if (predict.at6e && !pInput->buttonFlags.lookUp && !pInput->buttonFlags.lookDown)
|
||||||
|
{
|
||||||
|
if (predict.at20 < 0)
|
||||||
|
predict.at20 = fix16_min(predict.at20+fix16_from_dbl(lookStepDown), fix16_from_int(0));
|
||||||
|
if (predict.at20 > 0)
|
||||||
|
predict.at20 = fix16_max(predict.at20-fix16_from_dbl(lookStepUp), fix16_from_int(0));
|
||||||
|
if (predict.at20 == 0)
|
||||||
|
predict.at6e = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pInput->buttonFlags.lookUp)
|
||||||
|
predict.at20 = fix16_min(predict.at20+fix16_from_dbl(lookStepUp), fix16_from_int(upAngle));
|
||||||
|
if (pInput->buttonFlags.lookDown)
|
||||||
|
predict.at20 = fix16_max(predict.at20-fix16_from_dbl(lookStepDown), fix16_from_int(downAngle));
|
||||||
|
}
|
||||||
|
if (numplayers > 1 && gPrediction)
|
||||||
|
{
|
||||||
|
if (pInput->buttonFlags.lookUp)
|
||||||
|
{
|
||||||
|
gViewLookAdjust += float(lookStepUp);
|
||||||
|
}
|
||||||
|
if (pInput->buttonFlags.lookDown)
|
||||||
|
{
|
||||||
|
gViewLookAdjust -= float(lookStepDown);
|
||||||
|
}
|
||||||
|
gViewLookRecenter = predict.at6e && !pInput->buttonFlags.lookUp && !pInput->buttonFlags.lookDown;
|
||||||
|
}
|
||||||
|
predict.at20 = fix16_clamp(predict.at20+(pInput->q16mlook<<3), fix16_from_int(downAngle), fix16_from_int(upAngle));
|
||||||
|
predict.at24 = fix16_from_float(100.f*tanf(fix16_to_float(predict.at20)*fPI/1024.f));
|
||||||
|
|
||||||
|
int nSector = predict.at68;
|
||||||
|
int florhit = predict.at75.florhit & 0xc000;
|
||||||
|
char va;
|
||||||
|
if (predict.at6a < 16 && (florhit == 0x4000 || florhit == 0))
|
||||||
|
va = 1;
|
||||||
|
else
|
||||||
|
va = 0;
|
||||||
|
if (va && (sector[nSector].floorstat&2) != 0)
|
||||||
|
{
|
||||||
|
int z1 = getflorzofslope(nSector, predict.at50, predict.at54);
|
||||||
|
int x2 = predict.at50+mulscale30(64, Cos(fix16_to_int(predict.at30)));
|
||||||
|
int y2 = predict.at54+mulscale30(64, Sin(fix16_to_int(predict.at30)));
|
||||||
|
short nSector2 = nSector;
|
||||||
|
updatesector(x2, y2, &nSector2);
|
||||||
|
if (nSector2 == nSector)
|
||||||
|
{
|
||||||
|
int z2 = getflorzofslope(nSector2, x2, y2);
|
||||||
|
predict.at28 = interpolate(predict.at28, fix16_from_int(z1-z2)>>3, 0x4000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
predict.at28 = interpolate(predict.at28, 0, 0x4000);
|
||||||
|
if (klabs(predict.at28) < 4)
|
||||||
|
predict.at28 = 0;
|
||||||
|
}
|
||||||
|
predict.at2c = (-fix16_to_int(predict.at24))<<7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fakePlayerProcess(PLAYER *pPlayer, GINPUT *pInput)
|
||||||
|
{
|
||||||
|
spritetype *pSprite = pPlayer->pSprite;
|
||||||
|
XSPRITE *pXSprite = pPlayer->pXSprite;
|
||||||
|
POSTURE* pPosture = &pPlayer->pPosture[pPlayer->lifeMode][predict.at48];
|
||||||
|
|
||||||
|
int top, bottom;
|
||||||
|
GetSpriteExtents(pSprite, &top, &bottom);
|
||||||
|
|
||||||
|
top += predict.at58-pSprite->z;
|
||||||
|
bottom += predict.at58-pSprite->z;
|
||||||
|
|
||||||
|
int dzb = (bottom-predict.at58)/4;
|
||||||
|
int dzt = (predict.at58-top)/4;
|
||||||
|
|
||||||
|
int dw = pSprite->clipdist<<2;
|
||||||
|
short nSector = predict.at68;
|
||||||
|
if (!gNoClip)
|
||||||
|
{
|
||||||
|
pushmove_old((int32_t*)&predict.at50, (int32_t*)&predict.at54, (int32_t*)&predict.at58, &predict.at68, dw, dzt, dzb, CLIPMASK0);
|
||||||
|
if (predict.at68 == -1)
|
||||||
|
predict.at68 = nSector;
|
||||||
|
}
|
||||||
|
fakeProcessInput(pPlayer, pInput);
|
||||||
|
|
||||||
|
int nSpeed = approxDist(predict.at5c, predict.at60);
|
||||||
|
|
||||||
|
predict.at3c = interpolate(predict.at3c, predict.at64, 0x7000);
|
||||||
|
int dz = predict.at58-pPosture->eyeAboveZ-predict.at38;
|
||||||
|
if (dz > 0)
|
||||||
|
predict.at3c += mulscale16(dz<<8, 0xa000);
|
||||||
|
else
|
||||||
|
predict.at3c += mulscale16(dz<<8, 0x1800);
|
||||||
|
predict.at38 += predict.at3c>>8;
|
||||||
|
|
||||||
|
predict.at44 = interpolate(predict.at44, predict.at64, 0x5000);
|
||||||
|
dz = predict.at58-pPosture->weaponAboveZ-predict.at40;
|
||||||
|
if (dz > 0)
|
||||||
|
predict.at44 += mulscale16(dz<<8, 0x8000);
|
||||||
|
else
|
||||||
|
predict.at44 += mulscale16(dz<<8, 0xc00);
|
||||||
|
predict.at40 += predict.at44>>8;
|
||||||
|
|
||||||
|
predict.at34 = predict.at40 - predict.at38 - (12<<8);
|
||||||
|
|
||||||
|
predict.at0 = ClipLow(predict.at0-4, 0);
|
||||||
|
|
||||||
|
nSpeed >>= 16;
|
||||||
|
if (predict.at48 == 1)
|
||||||
|
{
|
||||||
|
predict.at4 = (predict.at4+17)&2047;
|
||||||
|
predict.at14 = (predict.at14+17)&2047;
|
||||||
|
predict.at8 = mulscale30(10*pPosture->bobV,Sin(predict.at4*2));
|
||||||
|
predict.atc = mulscale30(predict.at0*pPosture->bobH,Sin(predict.at4-256));
|
||||||
|
predict.at18 = mulscale30(predict.at0*pPosture->swayV,Sin(predict.at14*2));
|
||||||
|
predict.at1c = mulscale30(predict.at0*pPosture->swayH,Sin(predict.at14-0x155));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pXSprite->height < 256)
|
||||||
|
{
|
||||||
|
predict.at4 = (predict.at4+(pPosture->pace[predict.at70]*4))&2047;
|
||||||
|
predict.at14 = (predict.at14+(pPosture->pace[predict.at70]*4)/2)&2047;
|
||||||
|
if (predict.at70)
|
||||||
|
{
|
||||||
|
if (predict.at0 < 60)
|
||||||
|
predict.at0 = ClipHigh(predict.at0 + nSpeed, 60);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (predict.at0 < 30)
|
||||||
|
predict.at0 = ClipHigh(predict.at0 + nSpeed, 30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
predict.at8 = mulscale30(predict.at0*pPosture->bobV,Sin(predict.at4*2));
|
||||||
|
predict.atc = mulscale30(predict.at0*pPosture->bobH,Sin(predict.at4-256));
|
||||||
|
predict.at18 = mulscale30(predict.at0*pPosture->swayV,Sin(predict.at14*2));
|
||||||
|
predict.at1c = mulscale30(predict.at0*pPosture->swayH,Sin(predict.at14-0x155));
|
||||||
|
}
|
||||||
|
if (!pXSprite->health)
|
||||||
|
return;
|
||||||
|
predict.at72 = 0;
|
||||||
|
if (predict.at48 == 1)
|
||||||
|
{
|
||||||
|
predict.at72 = 1;
|
||||||
|
int nSector = predict.at68;
|
||||||
|
int nLink = gLowerLink[nSector];
|
||||||
|
if (nLink > 0 && (sprite[nLink].type == kMarkerLowGoo || sprite[nLink].type == kMarkerLowWater))
|
||||||
|
{
|
||||||
|
if (getceilzofslope(nSector, predict.at50, predict.at54) > predict.at38)
|
||||||
|
predict.at72 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fakeMoveDude(spritetype *pSprite)
|
||||||
|
{
|
||||||
|
PLAYER *pPlayer = NULL;
|
||||||
|
int bottom, top;
|
||||||
|
if (IsPlayerSprite(pSprite))
|
||||||
|
pPlayer = &gPlayer[pSprite->type-kDudePlayer1];
|
||||||
|
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
||||||
|
GetSpriteExtents(pSprite, &top, &bottom);
|
||||||
|
top += predict.at58 - pSprite->z;
|
||||||
|
bottom += predict.at58 - pSprite->z;
|
||||||
|
int bz = (bottom-predict.at58)/4;
|
||||||
|
int tz = (predict.at58-top)/4;
|
||||||
|
int wd = pSprite->clipdist*4;
|
||||||
|
int nSector = predict.at68;
|
||||||
|
dassert(nSector >= 0 && nSector < kMaxSectors);
|
||||||
|
if (predict.at5c || predict.at60)
|
||||||
|
{
|
||||||
|
if (pPlayer && gNoClip)
|
||||||
|
{
|
||||||
|
predict.at50 += predict.at5c>>12;
|
||||||
|
predict.at54 += predict.at60>>12;
|
||||||
|
if (!FindSector(predict.at50, predict.at54, &nSector))
|
||||||
|
nSector = predict.at68;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
short bakCstat = pSprite->cstat;
|
||||||
|
pSprite->cstat &= ~257;
|
||||||
|
predict.at75.hit = ClipMove(&predict.at50, &predict.at54, &predict.at58, &nSector, predict.at5c >> 12, predict.at60 >> 12, wd, tz, bz, CLIPMASK0);
|
||||||
|
if (nSector == -1)
|
||||||
|
nSector = predict.at68;
|
||||||
|
|
||||||
|
if (sector[nSector].type >= kSectorPath && sector[nSector].type <= kSectorRotate)
|
||||||
|
{
|
||||||
|
short nSector2 = nSector;
|
||||||
|
pushmove_old((int32_t*)&predict.at50, (int32_t*)&predict.at54, (int32_t*)&predict.at58, &nSector2, wd, tz, bz, CLIPMASK0);
|
||||||
|
if (nSector2 != -1)
|
||||||
|
nSector = nSector2;
|
||||||
|
}
|
||||||
|
|
||||||
|
dassert(nSector >= 0);
|
||||||
|
|
||||||
|
pSprite->cstat = bakCstat;
|
||||||
|
}
|
||||||
|
switch (predict.at75.hit&0xc000)
|
||||||
|
{
|
||||||
|
case 0x8000:
|
||||||
|
{
|
||||||
|
int nHitWall = predict.at75.hit&0x3fff;
|
||||||
|
walltype *pHitWall = &wall[nHitWall];
|
||||||
|
if (pHitWall->nextsector != -1)
|
||||||
|
{
|
||||||
|
sectortype *pHitSector = §or[pHitWall->nextsector];
|
||||||
|
if (top < pHitSector->ceilingz || bottom > pHitSector->floorz)
|
||||||
|
{
|
||||||
|
// ???
|
||||||
|
}
|
||||||
|
}
|
||||||
|
actWallBounceVector(&predict.at5c, &predict.at60, nHitWall, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (predict.at68 != nSector)
|
||||||
|
{
|
||||||
|
dassert(nSector >= 0 && nSector < kMaxSectors);
|
||||||
|
predict.at68 = nSector;
|
||||||
|
}
|
||||||
|
char bUnderwater = 0;
|
||||||
|
char bDepth = 0;
|
||||||
|
int nXSector = sector[nSector].extra;
|
||||||
|
if (nXSector > 0)
|
||||||
|
{
|
||||||
|
XSECTOR *pXSector = &xsector[nXSector];
|
||||||
|
if (pXSector->Underwater)
|
||||||
|
bUnderwater = 1;
|
||||||
|
if (pXSector->Depth)
|
||||||
|
bDepth = 1;
|
||||||
|
}
|
||||||
|
int nUpperLink = gUpperLink[nSector];
|
||||||
|
int nLowerLink = gLowerLink[nSector];
|
||||||
|
if (nUpperLink >= 0 && (sprite[nUpperLink].type == kMarkerUpWater || sprite[nUpperLink].type == kMarkerUpGoo))
|
||||||
|
bDepth = 1;
|
||||||
|
if (nLowerLink >= 0 && (sprite[nLowerLink].type == kMarkerLowWater || sprite[nLowerLink].type == kMarkerLowGoo))
|
||||||
|
bDepth = 1;
|
||||||
|
if (pPlayer)
|
||||||
|
wd += 16;
|
||||||
|
|
||||||
|
if (predict.at64)
|
||||||
|
predict.at58 += predict.at64 >> 8;
|
||||||
|
|
||||||
|
spritetype pSpriteBak = *pSprite;
|
||||||
|
spritetype *pTempSprite = pSprite;
|
||||||
|
pTempSprite->x = predict.at50;
|
||||||
|
pTempSprite->y = predict.at54;
|
||||||
|
pTempSprite->z = predict.at58;
|
||||||
|
pTempSprite->sectnum = predict.at68;
|
||||||
|
int ceilZ, ceilHit, floorZ, floorHit;
|
||||||
|
GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0);
|
||||||
|
GetSpriteExtents(pTempSprite, &top, &bottom);
|
||||||
|
if (predict.at73 & 2)
|
||||||
|
{
|
||||||
|
int vc = 58254;
|
||||||
|
if (bDepth)
|
||||||
|
{
|
||||||
|
if (bUnderwater)
|
||||||
|
{
|
||||||
|
int cz = getceilzofslope(nSector, predict.at50, predict.at54);
|
||||||
|
if (cz > top)
|
||||||
|
vc += ((bottom-cz)*-80099) / (bottom-top);
|
||||||
|
else
|
||||||
|
vc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int fz = getflorzofslope(nSector, predict.at50, predict.at54);
|
||||||
|
if (fz < bottom)
|
||||||
|
vc += ((bottom-fz)*-80099) / (bottom-top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bUnderwater)
|
||||||
|
vc = 0;
|
||||||
|
else if (bottom >= floorZ)
|
||||||
|
vc = 0;
|
||||||
|
}
|
||||||
|
if (vc)
|
||||||
|
{
|
||||||
|
predict.at58 += ((vc*4)/2)>>8;
|
||||||
|
predict.at64 += vc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GetSpriteExtents(pTempSprite, &top, &bottom);
|
||||||
|
if (bottom >= floorZ)
|
||||||
|
{
|
||||||
|
int floorZ2 = floorZ;
|
||||||
|
int floorHit2 = floorHit;
|
||||||
|
GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist<<2, CLIPMASK0, PARALLAXCLIP_CEILING|PARALLAXCLIP_FLOOR);
|
||||||
|
if (bottom <= floorZ && predict.at58-floorZ2 < bz)
|
||||||
|
{
|
||||||
|
floorZ = floorZ2;
|
||||||
|
floorHit = floorHit2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (floorZ <= bottom)
|
||||||
|
{
|
||||||
|
predict.at75.florhit = floorHit;
|
||||||
|
predict.at58 += floorZ-bottom;
|
||||||
|
int var44 = predict.at64-velFloor[predict.at68];
|
||||||
|
if (var44 > 0)
|
||||||
|
{
|
||||||
|
actFloorBounceVector(&predict.at5c, &predict.at60, &var44, predict.at68, 0);
|
||||||
|
predict.at64 = var44;
|
||||||
|
if (klabs(predict.at64) < 0x10000)
|
||||||
|
{
|
||||||
|
predict.at64 = velFloor[predict.at68];
|
||||||
|
predict.at73 &= ~4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
predict.at73 |= 4;
|
||||||
|
}
|
||||||
|
else if (predict.at64 == 0)
|
||||||
|
predict.at73 &= ~4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
predict.at75.florhit = 0;
|
||||||
|
if (predict.at73 & 2)
|
||||||
|
predict.at73 |= 4;
|
||||||
|
}
|
||||||
|
if (top <= ceilZ)
|
||||||
|
{
|
||||||
|
predict.at75.ceilhit = ceilHit;
|
||||||
|
predict.at58 += ClipLow(ceilZ-top, 0);
|
||||||
|
if (predict.at64 <= 0 && (predict.at73&4))
|
||||||
|
predict.at64 = mulscale16(-predict.at64, 0x2000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
predict.at75.ceilhit = 0;
|
||||||
|
|
||||||
|
GetSpriteExtents(pTempSprite, &top, &bottom);
|
||||||
|
*pSprite = pSpriteBak;
|
||||||
|
predict.at6a = ClipLow(floorZ-bottom, 0)>>8;
|
||||||
|
if (predict.at5c || predict.at60)
|
||||||
|
{
|
||||||
|
if ((floorHit & 0xc000) == 0xc000)
|
||||||
|
{
|
||||||
|
int nHitSprite = floorHit & 0x3fff;
|
||||||
|
if ((sprite[nHitSprite].cstat & 0x30) == 0)
|
||||||
|
{
|
||||||
|
predict.at5c += mulscale(4, predict.at50 - sprite[nHitSprite].x, 2);
|
||||||
|
predict.at60 += mulscale(4, predict.at54 - sprite[nHitSprite].y, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nXSector = sector[pSprite->sectnum].extra;
|
||||||
|
if (nXSector > 0 && xsector[nXSector].Underwater)
|
||||||
|
return;
|
||||||
|
if (predict.at6a >= 0x100)
|
||||||
|
return;
|
||||||
|
int nDrag = gDudeDrag;
|
||||||
|
if (predict.at6a > 0)
|
||||||
|
nDrag -= scale(gDudeDrag, predict.at6a, 0x100);
|
||||||
|
predict.at5c -= mulscale16r(predict.at5c, nDrag);
|
||||||
|
predict.at60 -= mulscale16r(predict.at60, nDrag);
|
||||||
|
if (approxDist(predict.at5c, predict.at60) < 0x1000)
|
||||||
|
predict.at5c = predict.at60 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fakeActAirDrag(spritetype *, int num)
|
||||||
|
{
|
||||||
|
int xvec = 0;
|
||||||
|
int yvec = 0;
|
||||||
|
int nSector = predict.at68;
|
||||||
|
dassert(nSector >= 0 && nSector < kMaxSectors);
|
||||||
|
sectortype *pSector = §or[nSector];
|
||||||
|
int nXSector = pSector->extra;
|
||||||
|
if (nXSector > 0)
|
||||||
|
{
|
||||||
|
dassert(nXSector < kMaxXSectors);
|
||||||
|
XSECTOR *pXSector = &xsector[nXSector];
|
||||||
|
if (pXSector->windVel && (pXSector->windAlways || pXSector->busy))
|
||||||
|
{
|
||||||
|
int vel = pXSector->windVel<<12;
|
||||||
|
if (!pXSector->windAlways && pXSector->busy)
|
||||||
|
vel = mulscale16(vel, pXSector->busy);
|
||||||
|
xvec = mulscale30(vel, Cos(pXSector->windAng));
|
||||||
|
yvec = mulscale30(vel, Sin(pXSector->windAng));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
predict.at5c += mulscale16(xvec-predict.at5c, num);
|
||||||
|
predict.at60 += mulscale16(yvec-predict.at60, num);
|
||||||
|
predict.at64 -= mulscale16(predict.at64, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fakeActProcessSprites(void)
|
||||||
|
{
|
||||||
|
spritetype *pSprite = gMe->pSprite;
|
||||||
|
if (pSprite->statnum == kStatDude)
|
||||||
|
{
|
||||||
|
int nXSprite = pSprite->extra;
|
||||||
|
dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
|
||||||
|
int nSector = predict.at68;
|
||||||
|
int nXSector = sector[nSector].extra;
|
||||||
|
XSECTOR *pXSector = NULL;
|
||||||
|
if (nXSector > 0)
|
||||||
|
{
|
||||||
|
dassert(nXSector > 0 && nXSector < kMaxXSectors);
|
||||||
|
dassert(xsector[nXSector].reference == nSector);
|
||||||
|
pXSector = &xsector[nXSector];
|
||||||
|
}
|
||||||
|
if (pXSector)
|
||||||
|
{
|
||||||
|
int top, bottom;
|
||||||
|
GetSpriteExtents(pSprite, &top, &bottom);
|
||||||
|
top += predict.at58 - pSprite->z;
|
||||||
|
bottom += predict.at58 - pSprite->z;
|
||||||
|
if (getflorzofslope(nSector, predict.at50, predict.at54) < bottom)
|
||||||
|
{
|
||||||
|
int angle = pXSector->panAngle;
|
||||||
|
int speed = 0;
|
||||||
|
if (pXSector->panAlways || pXSector->state || pXSector->busy)
|
||||||
|
{
|
||||||
|
speed = pXSector->panVel << 9;
|
||||||
|
if (!pXSector->panAlways && pXSector->busy)
|
||||||
|
speed = mulscale16(speed, pXSector->busy);
|
||||||
|
}
|
||||||
|
if (sector[nSector].floorstat&64)
|
||||||
|
angle = (GetWallAngle(sector[nSector].wallptr)+512)&2047;
|
||||||
|
predict.at5c += mulscale30(speed,Cos(angle));
|
||||||
|
predict.at60 += mulscale30(speed,Sin(angle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pXSector && pXSector->Underwater)
|
||||||
|
fakeActAirDrag(pSprite, 5376);
|
||||||
|
else
|
||||||
|
fakeActAirDrag(pSprite, 128);
|
||||||
|
|
||||||
|
if ((predict.at73 & 4) != 0 || predict.at5c != 0 || predict.at60 != 0 || predict.at64 != 0 || velFloor[predict.at68] != 0 || velCeil[predict.at68] != 0)
|
||||||
|
{
|
||||||
|
fakeMoveDude(pSprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void viewCorrectPrediction(void)
|
||||||
|
{
|
||||||
|
if (numplayers == 1)
|
||||||
|
{
|
||||||
|
gViewLook = gMe->q16look;
|
||||||
|
gViewAngle = gMe->q16ang;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
spritetype *pSprite = gMe->pSprite;
|
||||||
|
VIEW *pView = &predictFifo[(gNetFifoTail-1)&255];
|
||||||
|
if (gMe->q16ang != pView->at30 || pView->at24 != gMe->q16horiz || pView->at50 != pSprite->x || pView->at54 != pSprite->y || pView->at58 != pSprite->z)
|
||||||
|
{
|
||||||
|
viewInitializePrediction();
|
||||||
|
predictOld = gPrevView[myconnectindex];
|
||||||
|
gPredictTail = gNetFifoTail;
|
||||||
|
while (gPredictTail < gNetFifoHead[myconnectindex])
|
||||||
|
{
|
||||||
|
viewUpdatePrediction(&gFifoInput[gPredictTail&255][myconnectindex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END_BLD_NS
|
|
@ -49,43 +49,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
struct VIEW {
|
|
||||||
int at0;
|
|
||||||
int at4;
|
|
||||||
int at8; // bob height
|
|
||||||
int atc; // bob width
|
|
||||||
int at10;
|
|
||||||
int at14;
|
|
||||||
int at18; // bob sway y
|
|
||||||
int at1c; // bob sway x
|
|
||||||
fix16_t at20;
|
|
||||||
fix16_t at24; // horiz
|
|
||||||
int at28; // horizoff
|
|
||||||
int at2c;
|
|
||||||
fix16_t at30; // angle
|
|
||||||
int at34; // weapon z
|
|
||||||
int at38; // view z
|
|
||||||
int at3c;
|
|
||||||
int at40;
|
|
||||||
int at44;
|
|
||||||
int at48; // posture
|
|
||||||
int at4c; // spin
|
|
||||||
int at50; // x
|
|
||||||
int at54; // y
|
|
||||||
int at58; // z
|
|
||||||
int at5c; //xvel
|
|
||||||
int at60; //yvel
|
|
||||||
int at64; //zvel
|
|
||||||
short at68; // sectnum
|
|
||||||
unsigned int at6a; // floordist
|
|
||||||
char at6e; // look center
|
|
||||||
char at6f;
|
|
||||||
char at70; // run
|
|
||||||
char at71; // jump
|
|
||||||
char at72; // underwater
|
|
||||||
short at73; // sprite flags
|
|
||||||
SPRITEHIT at75;
|
|
||||||
};
|
|
||||||
|
|
||||||
VIEW gPrevView[kMaxPlayers];
|
VIEW gPrevView[kMaxPlayers];
|
||||||
VIEWPOS gViewPos;
|
VIEWPOS gViewPos;
|
||||||
|
@ -101,12 +64,6 @@ struct INTERPOLATE {
|
||||||
int gViewMode = 3;
|
int gViewMode = 3;
|
||||||
int gViewSize = 2;
|
int gViewSize = 2;
|
||||||
|
|
||||||
bool gPrediction = true;
|
|
||||||
|
|
||||||
VIEW predict, predictOld;
|
|
||||||
|
|
||||||
VIEW predictFifo[256];
|
|
||||||
|
|
||||||
int gInterpolate;
|
int gInterpolate;
|
||||||
int nInterpolations;
|
int nInterpolations;
|
||||||
char gInterpolateSprite[(kMaxSprites+7)>>3];
|
char gInterpolateSprite[(kMaxSprites+7)>>3];
|
||||||
|
@ -188,27 +145,6 @@ void FontSet(int id, int tile, int space)
|
||||||
if (ptrs[id]) *ptrs[id] = gFont[id];
|
if (ptrs[id]) *ptrs[id] = gFont[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
void viewGetFontInfo(int id, const char *unk1, int *pXSize, int *pYSize)
|
|
||||||
{
|
|
||||||
if (id < 0 || id >= kFontNum)
|
|
||||||
return;
|
|
||||||
FFont *pFont = gFont[id];
|
|
||||||
if (!unk1)
|
|
||||||
{
|
|
||||||
if (pXSize)
|
|
||||||
*pXSize = pFont->GetCharWidth('N');
|
|
||||||
if (pYSize)
|
|
||||||
*pYSize = pFont->GetHeight();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pXSize)
|
|
||||||
*pXSize = pFont->StringWidth(unk1);
|
|
||||||
if (pYSize)
|
|
||||||
*pYSize = pFont->GetHeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void viewToggle(int viewMode)
|
void viewToggle(int viewMode)
|
||||||
{
|
{
|
||||||
if (viewMode == 3)
|
if (viewMode == 3)
|
||||||
|
@ -220,678 +156,6 @@ void viewToggle(int viewMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void viewInitializePrediction(void)
|
|
||||||
{
|
|
||||||
predict.at30 = gMe->q16ang;
|
|
||||||
predict.at20 = gMe->q16look;
|
|
||||||
predict.at24 = gMe->q16horiz;
|
|
||||||
predict.at28 = gMe->q16slopehoriz;
|
|
||||||
predict.at2c = gMe->slope;
|
|
||||||
predict.at6f = gMe->cantJump;
|
|
||||||
predict.at70 = gMe->isRunning;
|
|
||||||
predict.at72 = gMe->isUnderwater;
|
|
||||||
predict.at71 = gMe->input.buttonFlags.jump;
|
|
||||||
predict.at50 = gMe->pSprite->x;
|
|
||||||
predict.at54 = gMe->pSprite->y;
|
|
||||||
predict.at58 = gMe->pSprite->z;
|
|
||||||
predict.at68 = gMe->pSprite->sectnum;
|
|
||||||
predict.at73 = gMe->pSprite->flags;
|
|
||||||
predict.at5c = xvel[gMe->pSprite->index];
|
|
||||||
predict.at60 = yvel[gMe->pSprite->index];
|
|
||||||
predict.at64 = zvel[gMe->pSprite->index];
|
|
||||||
predict.at6a = gMe->pXSprite->height;
|
|
||||||
predict.at48 = gMe->posture;
|
|
||||||
predict.at4c = gMe->spin;
|
|
||||||
predict.at6e = gMe->input.keyFlags.lookCenter;
|
|
||||||
memcpy(&predict.at75,&gSpriteHit[gMe->pSprite->extra],sizeof(SPRITEHIT));
|
|
||||||
predict.at0 = gMe->bobPhase;
|
|
||||||
predict.at4 = gMe->bobAmp;
|
|
||||||
predict.at8 = gMe->bobHeight;
|
|
||||||
predict.atc = gMe->bobWidth;
|
|
||||||
predict.at10 = gMe->swayPhase;
|
|
||||||
predict.at14 = gMe->swayAmp;
|
|
||||||
predict.at18 = gMe->swayHeight;
|
|
||||||
predict.at1c = gMe->swayWidth;
|
|
||||||
predict.at34 = gMe->zWeapon-gMe->zView-(12<<8);
|
|
||||||
predict.at38 = gMe->zView;
|
|
||||||
predict.at3c = gMe->zViewVel;
|
|
||||||
predict.at40 = gMe->zWeapon;
|
|
||||||
predict.at44 = gMe->zWeaponVel;
|
|
||||||
predictOld = predict;
|
|
||||||
if (numplayers != 1)
|
|
||||||
{
|
|
||||||
gViewAngle = predict.at30;
|
|
||||||
gViewLook = predict.at20;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void viewUpdatePrediction(GINPUT *pInput)
|
|
||||||
{
|
|
||||||
predictOld = predict;
|
|
||||||
short bakCstat = gMe->pSprite->cstat;
|
|
||||||
gMe->pSprite->cstat = 0;
|
|
||||||
fakePlayerProcess(gMe, pInput);
|
|
||||||
fakeActProcessSprites();
|
|
||||||
gMe->pSprite->cstat = bakCstat;
|
|
||||||
predictFifo[gPredictTail&255] = predict;
|
|
||||||
gPredictTail++;
|
|
||||||
if (numplayers != 1)
|
|
||||||
{
|
|
||||||
gViewAngle = predict.at30;
|
|
||||||
gViewLook = predict.at20;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sub_158B4(PLAYER *pPlayer)
|
|
||||||
{
|
|
||||||
predict.at38 = predict.at58 - pPlayer->pPosture[pPlayer->lifeMode][predict.at48].eyeAboveZ;
|
|
||||||
predict.at40 = predict.at58 - pPlayer->pPosture[pPlayer->lifeMode][predict.at48].weaponAboveZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fakeProcessInput(PLAYER *pPlayer, GINPUT *pInput)
|
|
||||||
{
|
|
||||||
POSTURE *pPosture = &pPlayer->pPosture[pPlayer->lifeMode][predict.at48];
|
|
||||||
|
|
||||||
if (numplayers > 1 && gPrediction)
|
|
||||||
{
|
|
||||||
gViewAngleAdjust = 0.f;
|
|
||||||
gViewLookRecenter = false;
|
|
||||||
gViewLookAdjust = 0.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
predict.at70 = pInput->syncFlags.run;
|
|
||||||
predict.at70 = 0;
|
|
||||||
predict.at71 = pInput->buttonFlags.jump;
|
|
||||||
if (predict.at48 == 1)
|
|
||||||
{
|
|
||||||
int x = Cos(fix16_to_int(predict.at30));
|
|
||||||
int y = Sin(fix16_to_int(predict.at30));
|
|
||||||
if (pInput->forward)
|
|
||||||
{
|
|
||||||
int forward = pInput->forward;
|
|
||||||
if (forward > 0)
|
|
||||||
forward = mulscale8(pPosture->frontAccel, forward);
|
|
||||||
else
|
|
||||||
forward = mulscale8(pPosture->backAccel, forward);
|
|
||||||
predict.at5c += mulscale30(forward, x);
|
|
||||||
predict.at60 += mulscale30(forward, y);
|
|
||||||
}
|
|
||||||
if (pInput->strafe)
|
|
||||||
{
|
|
||||||
int strafe = pInput->strafe;
|
|
||||||
strafe = mulscale8(pPosture->sideAccel, strafe);
|
|
||||||
predict.at5c += mulscale30(strafe, y);
|
|
||||||
predict.at60 -= mulscale30(strafe, x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (predict.at6a < 0x100)
|
|
||||||
{
|
|
||||||
int speed = 0x10000;
|
|
||||||
if (predict.at6a > 0)
|
|
||||||
speed -= divscale16(predict.at6a, 0x100);
|
|
||||||
int x = Cos(fix16_to_int(predict.at30));
|
|
||||||
int y = Sin(fix16_to_int(predict.at30));
|
|
||||||
if (pInput->forward)
|
|
||||||
{
|
|
||||||
int forward = pInput->forward;
|
|
||||||
if (forward > 0)
|
|
||||||
forward = mulscale8(pPosture->frontAccel, forward);
|
|
||||||
else
|
|
||||||
forward = mulscale8(pPosture->backAccel, forward);
|
|
||||||
if (predict.at6a)
|
|
||||||
forward = mulscale16(forward, speed);
|
|
||||||
predict.at5c += mulscale30(forward, x);
|
|
||||||
predict.at60 += mulscale30(forward, y);
|
|
||||||
}
|
|
||||||
if (pInput->strafe)
|
|
||||||
{
|
|
||||||
int strafe = pInput->strafe;
|
|
||||||
strafe = mulscale8(pPosture->sideAccel, strafe);
|
|
||||||
if (predict.at6a)
|
|
||||||
strafe = mulscale16(strafe, speed);
|
|
||||||
predict.at5c += mulscale30(strafe, y);
|
|
||||||
predict.at60 -= mulscale30(strafe, x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pInput->q16turn)
|
|
||||||
predict.at30 = (predict.at30+pInput->q16turn)&0x7ffffff;
|
|
||||||
if (pInput->keyFlags.spin180)
|
|
||||||
if (!predict.at4c)
|
|
||||||
predict.at4c = -1024;
|
|
||||||
if (predict.at4c < 0)
|
|
||||||
{
|
|
||||||
int speed;
|
|
||||||
if (predict.at48 == 1)
|
|
||||||
speed = 64;
|
|
||||||
else
|
|
||||||
speed = 128;
|
|
||||||
|
|
||||||
predict.at4c = min(predict.at4c+speed, 0);
|
|
||||||
predict.at30 += fix16_from_int(speed);
|
|
||||||
if (numplayers > 1 && gPrediction)
|
|
||||||
gViewAngleAdjust += float(speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!predict.at71)
|
|
||||||
predict.at6f = 0;
|
|
||||||
|
|
||||||
switch (predict.at48)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
if (predict.at71)
|
|
||||||
predict.at64 -= pPosture->normalJumpZ;//0x5b05;
|
|
||||||
if (pInput->buttonFlags.crouch)
|
|
||||||
predict.at64 += pPosture->normalJumpZ;//0x5b05;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (!pInput->buttonFlags.crouch)
|
|
||||||
predict.at48 = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (!predict.at6f && predict.at71 && predict.at6a == 0) {
|
|
||||||
if (packItemActive(pPlayer, 4)) predict.at64 = pPosture->pwupJumpZ;//-0x175555;
|
|
||||||
else predict.at64 = pPosture->normalJumpZ;//-0xbaaaa;
|
|
||||||
predict.at6f = 1;
|
|
||||||
}
|
|
||||||
if (pInput->buttonFlags.crouch)
|
|
||||||
predict.at48 = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
if (predict.at6e && !pInput->buttonFlags.lookUp && !pInput->buttonFlags.lookDown)
|
|
||||||
{
|
|
||||||
if (predict.at20 < 0)
|
|
||||||
predict.at20 = fix16_min(predict.at20+fix16_from_int(4), fix16_from_int(0));
|
|
||||||
if (predict.at20 > 0)
|
|
||||||
predict.at20 = fix16_max(predict.at20-fix16_from_int(4), fix16_from_int(0));
|
|
||||||
if (predict.at20 == 0)
|
|
||||||
predict.at6e = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pInput->buttonFlags.lookUp)
|
|
||||||
predict.at20 = fix16_min(predict.at20+fix16_from_int(4), fix16_from_int(60));
|
|
||||||
if (pInput->buttonFlags.lookDown)
|
|
||||||
predict.at20 = fix16_max(predict.at20-fix16_from_int(4), fix16_from_int(-60));
|
|
||||||
}
|
|
||||||
predict.at20 = fix16_clamp(predict.at20+pInput->q16mlook, fix16_from_int(-60), fix16_from_int(60));
|
|
||||||
|
|
||||||
if (predict.at20 > 0)
|
|
||||||
predict.at24 = mulscale30(fix16_from_int(120), Sin(fix16_to_int(predict.at20<<3)));
|
|
||||||
else if (predict.at20 < 0)
|
|
||||||
predict.at24 = mulscale30(fix16_from_int(180), Sin(fix16_to_int(predict.at20<<3)));
|
|
||||||
else
|
|
||||||
predict.at24 = 0;
|
|
||||||
#endif
|
|
||||||
int upAngle = 289;
|
|
||||||
int downAngle = -347;
|
|
||||||
double lookStepUp = 4.0*upAngle/60.0;
|
|
||||||
double lookStepDown = -4.0*downAngle/60.0;
|
|
||||||
if (predict.at6e && !pInput->buttonFlags.lookUp && !pInput->buttonFlags.lookDown)
|
|
||||||
{
|
|
||||||
if (predict.at20 < 0)
|
|
||||||
predict.at20 = fix16_min(predict.at20+fix16_from_dbl(lookStepDown), fix16_from_int(0));
|
|
||||||
if (predict.at20 > 0)
|
|
||||||
predict.at20 = fix16_max(predict.at20-fix16_from_dbl(lookStepUp), fix16_from_int(0));
|
|
||||||
if (predict.at20 == 0)
|
|
||||||
predict.at6e = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pInput->buttonFlags.lookUp)
|
|
||||||
predict.at20 = fix16_min(predict.at20+fix16_from_dbl(lookStepUp), fix16_from_int(upAngle));
|
|
||||||
if (pInput->buttonFlags.lookDown)
|
|
||||||
predict.at20 = fix16_max(predict.at20-fix16_from_dbl(lookStepDown), fix16_from_int(downAngle));
|
|
||||||
}
|
|
||||||
if (numplayers > 1 && gPrediction)
|
|
||||||
{
|
|
||||||
if (pInput->buttonFlags.lookUp)
|
|
||||||
{
|
|
||||||
gViewLookAdjust += float(lookStepUp);
|
|
||||||
}
|
|
||||||
if (pInput->buttonFlags.lookDown)
|
|
||||||
{
|
|
||||||
gViewLookAdjust -= float(lookStepDown);
|
|
||||||
}
|
|
||||||
gViewLookRecenter = predict.at6e && !pInput->buttonFlags.lookUp && !pInput->buttonFlags.lookDown;
|
|
||||||
}
|
|
||||||
predict.at20 = fix16_clamp(predict.at20+(pInput->q16mlook<<3), fix16_from_int(downAngle), fix16_from_int(upAngle));
|
|
||||||
predict.at24 = fix16_from_float(100.f*tanf(fix16_to_float(predict.at20)*fPI/1024.f));
|
|
||||||
|
|
||||||
int nSector = predict.at68;
|
|
||||||
int florhit = predict.at75.florhit & 0xc000;
|
|
||||||
char va;
|
|
||||||
if (predict.at6a < 16 && (florhit == 0x4000 || florhit == 0))
|
|
||||||
va = 1;
|
|
||||||
else
|
|
||||||
va = 0;
|
|
||||||
if (va && (sector[nSector].floorstat&2) != 0)
|
|
||||||
{
|
|
||||||
int z1 = getflorzofslope(nSector, predict.at50, predict.at54);
|
|
||||||
int x2 = predict.at50+mulscale30(64, Cos(fix16_to_int(predict.at30)));
|
|
||||||
int y2 = predict.at54+mulscale30(64, Sin(fix16_to_int(predict.at30)));
|
|
||||||
short nSector2 = nSector;
|
|
||||||
updatesector(x2, y2, &nSector2);
|
|
||||||
if (nSector2 == nSector)
|
|
||||||
{
|
|
||||||
int z2 = getflorzofslope(nSector2, x2, y2);
|
|
||||||
predict.at28 = interpolate(predict.at28, fix16_from_int(z1-z2)>>3, 0x4000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
predict.at28 = interpolate(predict.at28, 0, 0x4000);
|
|
||||||
if (klabs(predict.at28) < 4)
|
|
||||||
predict.at28 = 0;
|
|
||||||
}
|
|
||||||
predict.at2c = (-fix16_to_int(predict.at24))<<7;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fakePlayerProcess(PLAYER *pPlayer, GINPUT *pInput)
|
|
||||||
{
|
|
||||||
spritetype *pSprite = pPlayer->pSprite;
|
|
||||||
XSPRITE *pXSprite = pPlayer->pXSprite;
|
|
||||||
POSTURE* pPosture = &pPlayer->pPosture[pPlayer->lifeMode][predict.at48];
|
|
||||||
|
|
||||||
int top, bottom;
|
|
||||||
GetSpriteExtents(pSprite, &top, &bottom);
|
|
||||||
|
|
||||||
top += predict.at58-pSprite->z;
|
|
||||||
bottom += predict.at58-pSprite->z;
|
|
||||||
|
|
||||||
int dzb = (bottom-predict.at58)/4;
|
|
||||||
int dzt = (predict.at58-top)/4;
|
|
||||||
|
|
||||||
int dw = pSprite->clipdist<<2;
|
|
||||||
short nSector = predict.at68;
|
|
||||||
if (!gNoClip)
|
|
||||||
{
|
|
||||||
pushmove_old((int32_t*)&predict.at50, (int32_t*)&predict.at54, (int32_t*)&predict.at58, &predict.at68, dw, dzt, dzb, CLIPMASK0);
|
|
||||||
if (predict.at68 == -1)
|
|
||||||
predict.at68 = nSector;
|
|
||||||
}
|
|
||||||
fakeProcessInput(pPlayer, pInput);
|
|
||||||
|
|
||||||
int nSpeed = approxDist(predict.at5c, predict.at60);
|
|
||||||
|
|
||||||
predict.at3c = interpolate(predict.at3c, predict.at64, 0x7000);
|
|
||||||
int dz = predict.at58-pPosture->eyeAboveZ-predict.at38;
|
|
||||||
if (dz > 0)
|
|
||||||
predict.at3c += mulscale16(dz<<8, 0xa000);
|
|
||||||
else
|
|
||||||
predict.at3c += mulscale16(dz<<8, 0x1800);
|
|
||||||
predict.at38 += predict.at3c>>8;
|
|
||||||
|
|
||||||
predict.at44 = interpolate(predict.at44, predict.at64, 0x5000);
|
|
||||||
dz = predict.at58-pPosture->weaponAboveZ-predict.at40;
|
|
||||||
if (dz > 0)
|
|
||||||
predict.at44 += mulscale16(dz<<8, 0x8000);
|
|
||||||
else
|
|
||||||
predict.at44 += mulscale16(dz<<8, 0xc00);
|
|
||||||
predict.at40 += predict.at44>>8;
|
|
||||||
|
|
||||||
predict.at34 = predict.at40 - predict.at38 - (12<<8);
|
|
||||||
|
|
||||||
predict.at0 = ClipLow(predict.at0-4, 0);
|
|
||||||
|
|
||||||
nSpeed >>= 16;
|
|
||||||
if (predict.at48 == 1)
|
|
||||||
{
|
|
||||||
predict.at4 = (predict.at4+17)&2047;
|
|
||||||
predict.at14 = (predict.at14+17)&2047;
|
|
||||||
predict.at8 = mulscale30(10*pPosture->bobV,Sin(predict.at4*2));
|
|
||||||
predict.atc = mulscale30(predict.at0*pPosture->bobH,Sin(predict.at4-256));
|
|
||||||
predict.at18 = mulscale30(predict.at0*pPosture->swayV,Sin(predict.at14*2));
|
|
||||||
predict.at1c = mulscale30(predict.at0*pPosture->swayH,Sin(predict.at14-0x155));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pXSprite->height < 256)
|
|
||||||
{
|
|
||||||
predict.at4 = (predict.at4+(pPosture->pace[predict.at70]*4))&2047;
|
|
||||||
predict.at14 = (predict.at14+(pPosture->pace[predict.at70]*4)/2)&2047;
|
|
||||||
if (predict.at70)
|
|
||||||
{
|
|
||||||
if (predict.at0 < 60)
|
|
||||||
predict.at0 = ClipHigh(predict.at0 + nSpeed, 60);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (predict.at0 < 30)
|
|
||||||
predict.at0 = ClipHigh(predict.at0 + nSpeed, 30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
predict.at8 = mulscale30(predict.at0*pPosture->bobV,Sin(predict.at4*2));
|
|
||||||
predict.atc = mulscale30(predict.at0*pPosture->bobH,Sin(predict.at4-256));
|
|
||||||
predict.at18 = mulscale30(predict.at0*pPosture->swayV,Sin(predict.at14*2));
|
|
||||||
predict.at1c = mulscale30(predict.at0*pPosture->swayH,Sin(predict.at14-0x155));
|
|
||||||
}
|
|
||||||
if (!pXSprite->health)
|
|
||||||
return;
|
|
||||||
predict.at72 = 0;
|
|
||||||
if (predict.at48 == 1)
|
|
||||||
{
|
|
||||||
predict.at72 = 1;
|
|
||||||
int nSector = predict.at68;
|
|
||||||
int nLink = gLowerLink[nSector];
|
|
||||||
if (nLink > 0 && (sprite[nLink].type == kMarkerLowGoo || sprite[nLink].type == kMarkerLowWater))
|
|
||||||
{
|
|
||||||
if (getceilzofslope(nSector, predict.at50, predict.at54) > predict.at38)
|
|
||||||
predict.at72 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fakeMoveDude(spritetype *pSprite)
|
|
||||||
{
|
|
||||||
PLAYER *pPlayer = NULL;
|
|
||||||
int bottom, top;
|
|
||||||
if (IsPlayerSprite(pSprite))
|
|
||||||
pPlayer = &gPlayer[pSprite->type-kDudePlayer1];
|
|
||||||
dassert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
|
||||||
GetSpriteExtents(pSprite, &top, &bottom);
|
|
||||||
top += predict.at58 - pSprite->z;
|
|
||||||
bottom += predict.at58 - pSprite->z;
|
|
||||||
int bz = (bottom-predict.at58)/4;
|
|
||||||
int tz = (predict.at58-top)/4;
|
|
||||||
int wd = pSprite->clipdist*4;
|
|
||||||
int nSector = predict.at68;
|
|
||||||
dassert(nSector >= 0 && nSector < kMaxSectors);
|
|
||||||
if (predict.at5c || predict.at60)
|
|
||||||
{
|
|
||||||
if (pPlayer && gNoClip)
|
|
||||||
{
|
|
||||||
predict.at50 += predict.at5c>>12;
|
|
||||||
predict.at54 += predict.at60>>12;
|
|
||||||
if (!FindSector(predict.at50, predict.at54, &nSector))
|
|
||||||
nSector = predict.at68;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
short bakCstat = pSprite->cstat;
|
|
||||||
pSprite->cstat &= ~257;
|
|
||||||
predict.at75.hit = ClipMove(&predict.at50, &predict.at54, &predict.at58, &nSector, predict.at5c >> 12, predict.at60 >> 12, wd, tz, bz, CLIPMASK0);
|
|
||||||
if (nSector == -1)
|
|
||||||
nSector = predict.at68;
|
|
||||||
|
|
||||||
if (sector[nSector].type >= kSectorPath && sector[nSector].type <= kSectorRotate)
|
|
||||||
{
|
|
||||||
short nSector2 = nSector;
|
|
||||||
pushmove_old((int32_t*)&predict.at50, (int32_t*)&predict.at54, (int32_t*)&predict.at58, &nSector2, wd, tz, bz, CLIPMASK0);
|
|
||||||
if (nSector2 != -1)
|
|
||||||
nSector = nSector2;
|
|
||||||
}
|
|
||||||
|
|
||||||
dassert(nSector >= 0);
|
|
||||||
|
|
||||||
pSprite->cstat = bakCstat;
|
|
||||||
}
|
|
||||||
switch (predict.at75.hit&0xc000)
|
|
||||||
{
|
|
||||||
case 0x8000:
|
|
||||||
{
|
|
||||||
int nHitWall = predict.at75.hit&0x3fff;
|
|
||||||
walltype *pHitWall = &wall[nHitWall];
|
|
||||||
if (pHitWall->nextsector != -1)
|
|
||||||
{
|
|
||||||
sectortype *pHitSector = §or[pHitWall->nextsector];
|
|
||||||
if (top < pHitSector->ceilingz || bottom > pHitSector->floorz)
|
|
||||||
{
|
|
||||||
// ???
|
|
||||||
}
|
|
||||||
}
|
|
||||||
actWallBounceVector(&predict.at5c, &predict.at60, nHitWall, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (predict.at68 != nSector)
|
|
||||||
{
|
|
||||||
dassert(nSector >= 0 && nSector < kMaxSectors);
|
|
||||||
predict.at68 = nSector;
|
|
||||||
}
|
|
||||||
char bUnderwater = 0;
|
|
||||||
char bDepth = 0;
|
|
||||||
int nXSector = sector[nSector].extra;
|
|
||||||
if (nXSector > 0)
|
|
||||||
{
|
|
||||||
XSECTOR *pXSector = &xsector[nXSector];
|
|
||||||
if (pXSector->Underwater)
|
|
||||||
bUnderwater = 1;
|
|
||||||
if (pXSector->Depth)
|
|
||||||
bDepth = 1;
|
|
||||||
}
|
|
||||||
int nUpperLink = gUpperLink[nSector];
|
|
||||||
int nLowerLink = gLowerLink[nSector];
|
|
||||||
if (nUpperLink >= 0 && (sprite[nUpperLink].type == kMarkerUpWater || sprite[nUpperLink].type == kMarkerUpGoo))
|
|
||||||
bDepth = 1;
|
|
||||||
if (nLowerLink >= 0 && (sprite[nLowerLink].type == kMarkerLowWater || sprite[nLowerLink].type == kMarkerLowGoo))
|
|
||||||
bDepth = 1;
|
|
||||||
if (pPlayer)
|
|
||||||
wd += 16;
|
|
||||||
|
|
||||||
if (predict.at64)
|
|
||||||
predict.at58 += predict.at64 >> 8;
|
|
||||||
|
|
||||||
spritetype pSpriteBak = *pSprite;
|
|
||||||
spritetype *pTempSprite = pSprite;
|
|
||||||
pTempSprite->x = predict.at50;
|
|
||||||
pTempSprite->y = predict.at54;
|
|
||||||
pTempSprite->z = predict.at58;
|
|
||||||
pTempSprite->sectnum = predict.at68;
|
|
||||||
int ceilZ, ceilHit, floorZ, floorHit;
|
|
||||||
GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, wd, CLIPMASK0);
|
|
||||||
GetSpriteExtents(pTempSprite, &top, &bottom);
|
|
||||||
if (predict.at73 & 2)
|
|
||||||
{
|
|
||||||
int vc = 58254;
|
|
||||||
if (bDepth)
|
|
||||||
{
|
|
||||||
if (bUnderwater)
|
|
||||||
{
|
|
||||||
int cz = getceilzofslope(nSector, predict.at50, predict.at54);
|
|
||||||
if (cz > top)
|
|
||||||
vc += ((bottom-cz)*-80099) / (bottom-top);
|
|
||||||
else
|
|
||||||
vc = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int fz = getflorzofslope(nSector, predict.at50, predict.at54);
|
|
||||||
if (fz < bottom)
|
|
||||||
vc += ((bottom-fz)*-80099) / (bottom-top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bUnderwater)
|
|
||||||
vc = 0;
|
|
||||||
else if (bottom >= floorZ)
|
|
||||||
vc = 0;
|
|
||||||
}
|
|
||||||
if (vc)
|
|
||||||
{
|
|
||||||
predict.at58 += ((vc*4)/2)>>8;
|
|
||||||
predict.at64 += vc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GetSpriteExtents(pTempSprite, &top, &bottom);
|
|
||||||
if (bottom >= floorZ)
|
|
||||||
{
|
|
||||||
int floorZ2 = floorZ;
|
|
||||||
int floorHit2 = floorHit;
|
|
||||||
GetZRange(pTempSprite, &ceilZ, &ceilHit, &floorZ, &floorHit, pSprite->clipdist<<2, CLIPMASK0, PARALLAXCLIP_CEILING|PARALLAXCLIP_FLOOR);
|
|
||||||
if (bottom <= floorZ && predict.at58-floorZ2 < bz)
|
|
||||||
{
|
|
||||||
floorZ = floorZ2;
|
|
||||||
floorHit = floorHit2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (floorZ <= bottom)
|
|
||||||
{
|
|
||||||
predict.at75.florhit = floorHit;
|
|
||||||
predict.at58 += floorZ-bottom;
|
|
||||||
int var44 = predict.at64-velFloor[predict.at68];
|
|
||||||
if (var44 > 0)
|
|
||||||
{
|
|
||||||
actFloorBounceVector(&predict.at5c, &predict.at60, &var44, predict.at68, 0);
|
|
||||||
predict.at64 = var44;
|
|
||||||
if (klabs(predict.at64) < 0x10000)
|
|
||||||
{
|
|
||||||
predict.at64 = velFloor[predict.at68];
|
|
||||||
predict.at73 &= ~4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
predict.at73 |= 4;
|
|
||||||
}
|
|
||||||
else if (predict.at64 == 0)
|
|
||||||
predict.at73 &= ~4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
predict.at75.florhit = 0;
|
|
||||||
if (predict.at73 & 2)
|
|
||||||
predict.at73 |= 4;
|
|
||||||
}
|
|
||||||
if (top <= ceilZ)
|
|
||||||
{
|
|
||||||
predict.at75.ceilhit = ceilHit;
|
|
||||||
predict.at58 += ClipLow(ceilZ-top, 0);
|
|
||||||
if (predict.at64 <= 0 && (predict.at73&4))
|
|
||||||
predict.at64 = mulscale16(-predict.at64, 0x2000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
predict.at75.ceilhit = 0;
|
|
||||||
|
|
||||||
GetSpriteExtents(pTempSprite, &top, &bottom);
|
|
||||||
*pSprite = pSpriteBak;
|
|
||||||
predict.at6a = ClipLow(floorZ-bottom, 0)>>8;
|
|
||||||
if (predict.at5c || predict.at60)
|
|
||||||
{
|
|
||||||
if ((floorHit & 0xc000) == 0xc000)
|
|
||||||
{
|
|
||||||
int nHitSprite = floorHit & 0x3fff;
|
|
||||||
if ((sprite[nHitSprite].cstat & 0x30) == 0)
|
|
||||||
{
|
|
||||||
predict.at5c += mulscale(4, predict.at50 - sprite[nHitSprite].x, 2);
|
|
||||||
predict.at60 += mulscale(4, predict.at54 - sprite[nHitSprite].y, 2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int nXSector = sector[pSprite->sectnum].extra;
|
|
||||||
if (nXSector > 0 && xsector[nXSector].Underwater)
|
|
||||||
return;
|
|
||||||
if (predict.at6a >= 0x100)
|
|
||||||
return;
|
|
||||||
int nDrag = gDudeDrag;
|
|
||||||
if (predict.at6a > 0)
|
|
||||||
nDrag -= scale(gDudeDrag, predict.at6a, 0x100);
|
|
||||||
predict.at5c -= mulscale16r(predict.at5c, nDrag);
|
|
||||||
predict.at60 -= mulscale16r(predict.at60, nDrag);
|
|
||||||
if (approxDist(predict.at5c, predict.at60) < 0x1000)
|
|
||||||
predict.at5c = predict.at60 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fakeActAirDrag(spritetype *pSprite, int num)
|
|
||||||
{
|
|
||||||
UNREFERENCED_PARAMETER(pSprite);
|
|
||||||
int xvec = 0;
|
|
||||||
int yvec = 0;
|
|
||||||
int nSector = predict.at68;
|
|
||||||
dassert(nSector >= 0 && nSector < kMaxSectors);
|
|
||||||
sectortype *pSector = §or[nSector];
|
|
||||||
int nXSector = pSector->extra;
|
|
||||||
if (nXSector > 0)
|
|
||||||
{
|
|
||||||
dassert(nXSector < kMaxXSectors);
|
|
||||||
XSECTOR *pXSector = &xsector[nXSector];
|
|
||||||
if (pXSector->windVel && (pXSector->windAlways || pXSector->busy))
|
|
||||||
{
|
|
||||||
int vel = pXSector->windVel<<12;
|
|
||||||
if (!pXSector->windAlways && pXSector->busy)
|
|
||||||
vel = mulscale16(vel, pXSector->busy);
|
|
||||||
xvec = mulscale30(vel, Cos(pXSector->windAng));
|
|
||||||
yvec = mulscale30(vel, Sin(pXSector->windAng));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
predict.at5c += mulscale16(xvec-predict.at5c, num);
|
|
||||||
predict.at60 += mulscale16(yvec-predict.at60, num);
|
|
||||||
predict.at64 -= mulscale16(predict.at64, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fakeActProcessSprites(void)
|
|
||||||
{
|
|
||||||
spritetype *pSprite = gMe->pSprite;
|
|
||||||
if (pSprite->statnum == kStatDude)
|
|
||||||
{
|
|
||||||
int nXSprite = pSprite->extra;
|
|
||||||
dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
|
|
||||||
int nSector = predict.at68;
|
|
||||||
int nXSector = sector[nSector].extra;
|
|
||||||
XSECTOR *pXSector = NULL;
|
|
||||||
if (nXSector > 0)
|
|
||||||
{
|
|
||||||
dassert(nXSector > 0 && nXSector < kMaxXSectors);
|
|
||||||
dassert(xsector[nXSector].reference == nSector);
|
|
||||||
pXSector = &xsector[nXSector];
|
|
||||||
}
|
|
||||||
if (pXSector)
|
|
||||||
{
|
|
||||||
int top, bottom;
|
|
||||||
GetSpriteExtents(pSprite, &top, &bottom);
|
|
||||||
top += predict.at58 - pSprite->z;
|
|
||||||
bottom += predict.at58 - pSprite->z;
|
|
||||||
if (getflorzofslope(nSector, predict.at50, predict.at54) < bottom)
|
|
||||||
{
|
|
||||||
int angle = pXSector->panAngle;
|
|
||||||
int speed = 0;
|
|
||||||
if (pXSector->panAlways || pXSector->state || pXSector->busy)
|
|
||||||
{
|
|
||||||
speed = pXSector->panVel << 9;
|
|
||||||
if (!pXSector->panAlways && pXSector->busy)
|
|
||||||
speed = mulscale16(speed, pXSector->busy);
|
|
||||||
}
|
|
||||||
if (sector[nSector].floorstat&64)
|
|
||||||
angle = (GetWallAngle(sector[nSector].wallptr)+512)&2047;
|
|
||||||
predict.at5c += mulscale30(speed,Cos(angle));
|
|
||||||
predict.at60 += mulscale30(speed,Sin(angle));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pXSector && pXSector->Underwater)
|
|
||||||
fakeActAirDrag(pSprite, 5376);
|
|
||||||
else
|
|
||||||
fakeActAirDrag(pSprite, 128);
|
|
||||||
|
|
||||||
if ((predict.at73 & 4) != 0 || predict.at5c != 0 || predict.at60 != 0 || predict.at64 != 0 || velFloor[predict.at68] != 0 || velCeil[predict.at68] != 0)
|
|
||||||
{
|
|
||||||
fakeMoveDude(pSprite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void viewCorrectPrediction(void)
|
|
||||||
{
|
|
||||||
if (numplayers == 1)
|
|
||||||
{
|
|
||||||
gViewLook = gMe->q16look;
|
|
||||||
gViewAngle = gMe->q16ang;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spritetype *pSprite = gMe->pSprite;
|
|
||||||
VIEW *pView = &predictFifo[(gNetFifoTail-1)&255];
|
|
||||||
if (gMe->q16ang != pView->at30 || pView->at24 != gMe->q16horiz || pView->at50 != pSprite->x || pView->at54 != pSprite->y || pView->at58 != pSprite->z)
|
|
||||||
{
|
|
||||||
viewInitializePrediction();
|
|
||||||
predictOld = gPrevView[myconnectindex];
|
|
||||||
gPredictTail = gNetFifoTail;
|
|
||||||
while (gPredictTail < gNetFifoHead[myconnectindex])
|
|
||||||
{
|
|
||||||
viewUpdatePrediction(&gFifoInput[gPredictTail&255][myconnectindex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void viewBackupView(int nPlayer)
|
void viewBackupView(int nPlayer)
|
||||||
{
|
{
|
||||||
PLAYER *pPlayer = &gPlayer[nPlayer];
|
PLAYER *pPlayer = &gPlayer[nPlayer];
|
||||||
|
@ -1003,7 +267,7 @@ void viewDrawText(int nFont, const char *pString, int x, int y, int nShade, int
|
||||||
DrawText(twod, pFont, CR_UNDEFINED, x+1, y+1, pString, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_Color, 0xff000000, DTA_Alpha, 0.5, TAG_DONE);
|
DrawText(twod, pFont, CR_UNDEFINED, x+1, y+1, pString, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_Color, 0xff000000, DTA_Alpha, 0.5, TAG_DONE);
|
||||||
}
|
}
|
||||||
DrawText(twod, pFont, CR_UNDEFINED, x, y, pString, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_TranslationIndex, TRANSLATION(Translation_Remap, nPalette),
|
DrawText(twod, pFont, CR_UNDEFINED, x, y, pString, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_TranslationIndex, TRANSLATION(Translation_Remap, nPalette),
|
||||||
DTA_Color, shadeToLight(nShade), TAG_DONE);
|
DTA_Color, shadeToLight(nShade), DTA_Alpha, alpha / 255., TAG_DONE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,13 +285,13 @@ void viewDrawMapTitle(void)
|
||||||
if (!hud_showmapname || M_Active())
|
if (!hud_showmapname || M_Active())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int const fadeStartTic = int((videoGetRenderMode() == REND_CLASSIC ? 1.25f : 1.f)*kTicsPerSec);
|
int const fadeStartTic = kTicsPerSec;
|
||||||
int const fadeEndTic = int(1.5f*kTicsPerSec);
|
int const fadeEndTic = int(1.5f*kTicsPerSec);
|
||||||
if (gLevelTime > fadeEndTic)
|
if (gLevelTime > fadeEndTic)
|
||||||
return;
|
return;
|
||||||
uint8_t const alpha = clamp((gLevelTime-fadeStartTic)*255/(fadeEndTic-fadeStartTic), 0, 255);
|
int const alpha = 255 - clamp((gLevelTime-fadeStartTic)*255/(fadeEndTic-fadeStartTic), 0, 255);
|
||||||
|
|
||||||
if (alpha != 255)
|
if (alpha != 0)
|
||||||
{
|
{
|
||||||
viewDrawText(1, levelGetTitle(), 160, 50, -128, 0, 1, 1, 0, alpha);
|
viewDrawText(1, levelGetTitle(), 160, 50, -128, 0, 1, 1, 0, alpha);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,49 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
BEGIN_BLD_NS
|
BEGIN_BLD_NS
|
||||||
|
|
||||||
|
struct VIEW {
|
||||||
|
int at0;
|
||||||
|
int at4;
|
||||||
|
int at8; // bob height
|
||||||
|
int atc; // bob width
|
||||||
|
int at10;
|
||||||
|
int at14;
|
||||||
|
int at18; // bob sway y
|
||||||
|
int at1c; // bob sway x
|
||||||
|
fix16_t at20;
|
||||||
|
fix16_t at24; // horiz
|
||||||
|
int at28; // horizoff
|
||||||
|
int at2c;
|
||||||
|
fix16_t at30; // angle
|
||||||
|
int at34; // weapon z
|
||||||
|
int at38; // view z
|
||||||
|
int at3c;
|
||||||
|
int at40;
|
||||||
|
int at44;
|
||||||
|
int at48; // posture
|
||||||
|
int at4c; // spin
|
||||||
|
int at50; // x
|
||||||
|
int at54; // y
|
||||||
|
int at58; // z
|
||||||
|
int at5c; //xvel
|
||||||
|
int at60; //yvel
|
||||||
|
int at64; //zvel
|
||||||
|
short at68; // sectnum
|
||||||
|
unsigned int at6a; // floordist
|
||||||
|
char at6e; // look center
|
||||||
|
char at6f;
|
||||||
|
char at70; // run
|
||||||
|
char at71; // jump
|
||||||
|
char at72; // underwater
|
||||||
|
short at73; // sprite flags
|
||||||
|
SPRITEHIT at75;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern VIEW gPrevView[kMaxPlayers];
|
||||||
|
|
||||||
|
extern VIEW predict, predictOld;
|
||||||
|
extern bool gPrediction;
|
||||||
|
|
||||||
enum VIEW_EFFECT {
|
enum VIEW_EFFECT {
|
||||||
VIEW_EFFECT_0 = 0,
|
VIEW_EFFECT_0 = 0,
|
||||||
VIEW_EFFECT_1,
|
VIEW_EFFECT_1,
|
||||||
|
@ -104,16 +147,9 @@ extern int gViewX0S, gViewY0S, gViewX1S, gViewY1S;
|
||||||
extern int gLastPal;
|
extern int gLastPal;
|
||||||
|
|
||||||
void hudDraw(PLAYER* gView, int nSectnum, int defaultHoriz, int bobx, int boby, int zDelta, int basepal);
|
void hudDraw(PLAYER* gView, int nSectnum, int defaultHoriz, int bobx, int boby, int zDelta, int basepal);
|
||||||
void viewGetFontInfo(int id, const char *unk1, int *pXSize, int *pYSize);
|
|
||||||
void viewToggle(int viewMode);
|
void viewToggle(int viewMode);
|
||||||
void viewInitializePrediction(void);
|
void viewInitializePrediction(void);
|
||||||
void viewUpdatePrediction(GINPUT *pInput);
|
void viewUpdatePrediction(GINPUT *pInput);
|
||||||
void sub_158B4(PLAYER *pPlayer);
|
|
||||||
void fakeProcessInput(PLAYER *pPlayer, GINPUT *pInput);
|
|
||||||
void fakePlayerProcess(PLAYER *pPlayer, GINPUT *pInput);
|
|
||||||
void fakeMoveDude(spritetype *pSprite);
|
|
||||||
void fakeActAirDrag(spritetype *pSprite, int num);
|
|
||||||
void fakeActProcessSprites(void);
|
|
||||||
void viewCorrectPrediction(void);
|
void viewCorrectPrediction(void);
|
||||||
void viewBackupView(int nPlayer);
|
void viewBackupView(int nPlayer);
|
||||||
void viewCorrectViewOffsets(int nPlayer, vec3_t const *oldpos);
|
void viewCorrectViewOffsets(int nPlayer, vec3_t const *oldpos);
|
||||||
|
@ -122,7 +158,6 @@ void viewAddInterpolation(void *data, INTERPOLATE_TYPE type);
|
||||||
void CalcInterpolations(void);
|
void CalcInterpolations(void);
|
||||||
void RestoreInterpolations(void);
|
void RestoreInterpolations(void);
|
||||||
void viewDrawText(int nFont, const char *pString, int x, int y, int nShade, int nPalette, int position, char shadow, unsigned int nStat = 0, uint8_t alpha = 0);
|
void viewDrawText(int nFont, const char *pString, int x, int y, int nShade, int nPalette, int position, char shadow, unsigned int nStat = 0, uint8_t alpha = 0);
|
||||||
void viewTileSprite(int nTile, int nShade, int nPalette, int x1, int y1, int x2, int y2);
|
|
||||||
void InitStatusBar(void);
|
void InitStatusBar(void);
|
||||||
void UpdateStatusBar(ClockTicks arg);
|
void UpdateStatusBar(ClockTicks arg);
|
||||||
void viewInit(void);
|
void viewInit(void);
|
||||||
|
|
Loading…
Reference in a new issue