2020-07-04 21:40:54 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 1996, 2003 - 3D Realms Entertainment
|
|
|
|
|
|
|
|
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
|
|
|
|
|
|
|
|
Duke Nukem 3D 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
Original Source: 1996 - Todd Replogle
|
|
|
|
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
|
|
|
Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "ns.h"
|
|
|
|
#include "duke3d.h"
|
2020-07-05 14:49:00 +00:00
|
|
|
#include "build.h"
|
|
|
|
#include "v_video.h"
|
2020-07-06 09:39:39 +00:00
|
|
|
#include "prediction.h"
|
2020-09-06 18:49:43 +00:00
|
|
|
#include "automap.h"
|
2020-11-04 06:01:25 +00:00
|
|
|
#include "dukeactor.h"
|
2020-11-26 15:03:40 +00:00
|
|
|
#include "interpolate.h"
|
2021-03-21 09:58:11 +00:00
|
|
|
#include "render.h"
|
2020-07-04 21:40:54 +00:00
|
|
|
|
2021-03-18 16:18:03 +00:00
|
|
|
// temporary hack to pass along RRRA's global fog. Needs to be done better later.
|
|
|
|
extern PalEntry GlobalMapFog;
|
|
|
|
extern float GlobalFogDensity;
|
|
|
|
|
2020-07-04 21:40:54 +00:00
|
|
|
BEGIN_DUKE_NS
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Floor Over Floor
|
|
|
|
|
|
|
|
// If standing in sector with SE42
|
|
|
|
// then draw viewing to SE41 and raise all =hi SE43 cielings.
|
|
|
|
|
|
|
|
// If standing in sector with SE43
|
|
|
|
// then draw viewing to SE40 and lower all =hi SE42 floors.
|
|
|
|
|
|
|
|
// If standing in sector with SE44
|
|
|
|
// then draw viewing to SE40.
|
|
|
|
|
|
|
|
// If standing in sector with SE45
|
|
|
|
// then draw viewing to SE41.
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2022-08-27 08:24:16 +00:00
|
|
|
void renderView(DDukeActor* playersprite, sectortype* sect, int x, int y, int z, DAngle a, fixedhoriz h, DAngle rotscrnang, double smoothratio, bool sceneonly, float fov)
|
2020-07-04 21:40:54 +00:00
|
|
|
{
|
2022-08-03 13:50:27 +00:00
|
|
|
if (!sceneonly) drawweapon(smoothratio);
|
2022-08-27 08:24:16 +00:00
|
|
|
render_drawrooms(playersprite, { x, y, z }, sectnum(sect), a, h, rotscrnang, smoothratio, fov);
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2021-03-28 17:22:51 +00:00
|
|
|
void GameInterface::UpdateCameras(double smoothratio)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2020-07-06 20:23:18 +00:00
|
|
|
const int VIEWSCREEN_ACTIVE_DISTANCE = 8192;
|
|
|
|
|
2020-11-04 18:25:49 +00:00
|
|
|
if (camsprite == nullptr)
|
2020-07-05 14:49:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
auto p = &ps[screenpeek];
|
2020-11-04 18:25:49 +00:00
|
|
|
if (p->newOwner != nullptr) camsprite->SetOwner(p->newOwner);
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2020-11-04 18:25:49 +00:00
|
|
|
if (camsprite->GetOwner() && dist(p->GetActor(), camsprite) < VIEWSCREEN_ACTIVE_DISTANCE)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2021-12-21 20:35:07 +00:00
|
|
|
auto tex = tileGetTexture(camsprite->spr.picnum);
|
2021-05-12 15:57:36 +00:00
|
|
|
TileFiles.MakeCanvas(TILE_VIEWSCR, (int)tex->GetDisplayWidth(), (int)tex->GetDisplayHeight());
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2022-08-04 21:47:01 +00:00
|
|
|
auto canvas = tileGetCanvas(TILE_VIEWSCR);
|
2020-07-05 14:49:00 +00:00
|
|
|
if (!canvas) return;
|
|
|
|
|
|
|
|
screen->RenderTextureView(canvas, [=](IntRect& rect)
|
|
|
|
{
|
2021-12-22 22:27:32 +00:00
|
|
|
auto camera = camsprite->GetOwner();
|
2020-07-05 14:49:00 +00:00
|
|
|
display_mirror = 1; // should really be 'display external view'.
|
2022-08-03 13:50:27 +00:00
|
|
|
auto cstat = camera->spr.cstat;
|
|
|
|
camera->spr.cstat = CSTAT_SPRITE_INVISIBLE;
|
2022-08-29 09:44:48 +00:00
|
|
|
render_camtex(camera, camera->int_pos(), camera->sector(), camera->interpolatedangle(smoothratio / 65536.), buildhoriz(camera->spr.shade), nullAngle, tex, rect, smoothratio);
|
2022-08-03 13:50:27 +00:00
|
|
|
camera->spr.cstat = cstat;
|
2020-07-05 14:49:00 +00:00
|
|
|
display_mirror = 0;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-22 22:27:32 +00:00
|
|
|
void GameInterface::EnterPortal(DCoreActor* viewer, int type)
|
2021-03-29 19:48:23 +00:00
|
|
|
{
|
|
|
|
if (type == PORTAL_WALL_MIRROR) display_mirror++;
|
|
|
|
}
|
|
|
|
|
2021-12-22 22:27:32 +00:00
|
|
|
void GameInterface::LeavePortal(DCoreActor* viewer, int type)
|
2021-03-29 19:48:23 +00:00
|
|
|
{
|
|
|
|
if (type == PORTAL_WALL_MIRROR) display_mirror--;
|
|
|
|
}
|
|
|
|
|
2021-11-18 18:33:32 +00:00
|
|
|
bool GameInterface::GetGeoEffect(GeoEffect* eff, sectortype* viewsector)
|
2021-04-02 20:52:46 +00:00
|
|
|
{
|
2021-11-18 18:33:32 +00:00
|
|
|
if (isRR() && viewsector->lotag == 848)
|
2021-04-02 20:52:46 +00:00
|
|
|
{
|
|
|
|
eff->geocnt = geocnt;
|
|
|
|
eff->geosector = geosector;
|
|
|
|
eff->geosectorwarp = geosectorwarp;
|
|
|
|
eff->geosectorwarp2 = geosectorwarp2;
|
|
|
|
eff->geox = geox;
|
|
|
|
eff->geoy = geoy;
|
|
|
|
eff->geox2 = geox2;
|
|
|
|
eff->geoy2 = geoy2;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-07-05 14:49:00 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
2020-07-05 19:21:39 +00:00
|
|
|
// RRRA's drug distortion effect
|
2020-07-05 14:49:00 +00:00
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
2020-11-05 06:25:44 +00:00
|
|
|
int DrugTimer;
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2020-11-06 09:52:43 +00:00
|
|
|
static int getdrugmode(player_struct *p, int oyrepeat)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2020-11-05 06:25:44 +00:00
|
|
|
int now = I_GetBuildTime() >> 1; // this function works on a 60 fps setup.
|
|
|
|
if (playrunning() && p->DrugMode > 0)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2020-11-05 06:25:44 +00:00
|
|
|
if (now - DrugTimer > 4 || now - DrugTimer < 0) DrugTimer = now - 1;
|
|
|
|
while (DrugTimer < now)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2020-11-05 06:25:44 +00:00
|
|
|
DrugTimer++;
|
2020-07-05 14:49:00 +00:00
|
|
|
int var_8c;
|
|
|
|
if (p->drug_stat[0] == 0)
|
|
|
|
{
|
|
|
|
p->drug_stat[1]++;
|
|
|
|
var_8c = oyrepeat + p->drug_stat[1] * 5000;
|
|
|
|
if (oyrepeat * 3 < var_8c)
|
|
|
|
{
|
|
|
|
p->drug_aspect = oyrepeat * 3;
|
|
|
|
p->drug_stat[0] = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->drug_aspect = var_8c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (p->drug_stat[0] == 3)
|
|
|
|
{
|
|
|
|
p->drug_stat[1]--;
|
|
|
|
var_8c = oyrepeat + p->drug_stat[1] * 5000;
|
|
|
|
if (var_8c < oyrepeat)
|
|
|
|
{
|
|
|
|
p->DrugMode = 0;
|
|
|
|
p->drug_stat[0] = 0;
|
|
|
|
p->drug_stat[2] = 0;
|
|
|
|
p->drug_stat[1] = 0;
|
2020-11-06 09:52:43 +00:00
|
|
|
p->drug_aspect = oyrepeat;
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->drug_aspect = var_8c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (p->drug_stat[0] == 2)
|
|
|
|
{
|
|
|
|
if (p->drug_stat[2] > 30)
|
|
|
|
{
|
|
|
|
p->drug_stat[0] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->drug_stat[2]++;
|
|
|
|
p->drug_aspect = oyrepeat * 3 + p->drug_stat[2] * 500;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (p->drug_stat[2] < 1)
|
|
|
|
{
|
|
|
|
p->drug_stat[0] = 2;
|
|
|
|
p->DrugMode--;
|
|
|
|
if (p->DrugMode == 1)
|
|
|
|
p->drug_stat[0] = 3;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->drug_stat[2]--;
|
|
|
|
p->drug_aspect = oyrepeat * 3 + p->drug_stat[2] * 500;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-06 09:52:43 +00:00
|
|
|
return p->drug_aspect;
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
2020-11-06 09:52:43 +00:00
|
|
|
else
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2020-11-06 09:52:43 +00:00
|
|
|
DrugTimer = now;
|
|
|
|
return oyrepeat;
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2022-01-08 11:09:04 +00:00
|
|
|
void displayrooms(int snum, double smoothratio, bool sceneonly)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2020-07-05 19:24:55 +00:00
|
|
|
int cposx, cposy, cposz, fz, cz;
|
2022-08-27 08:24:16 +00:00
|
|
|
DAngle cang, rotscrnang;
|
2020-07-23 15:01:37 +00:00
|
|
|
fixedhoriz choriz;
|
2022-02-07 10:04:19 +00:00
|
|
|
player_struct* p;
|
2020-07-05 14:49:00 +00:00
|
|
|
|
|
|
|
p = &ps[snum];
|
|
|
|
|
2021-11-21 07:45:07 +00:00
|
|
|
if (automapMode == am_full || !p->insector())
|
2020-07-05 14:49:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Do not light up the fog in RRRA's E2L1. Ideally this should apply to all foggy levels but all others use lookup table hacks for their fog.
|
|
|
|
if (isRRRA() && fogactive)
|
|
|
|
{
|
|
|
|
p->visibility = ud.const_visibility;
|
|
|
|
}
|
|
|
|
|
2022-01-08 11:23:05 +00:00
|
|
|
g_visibility = ud.const_visibility;
|
|
|
|
g_relvisibility = p->visibility - ud.const_visibility;
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2021-11-21 07:56:39 +00:00
|
|
|
auto sect = p->cursector;
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2021-03-18 16:18:03 +00:00
|
|
|
GlobalMapFog = fogactive ? 0x999999 : 0;
|
|
|
|
GlobalFogDensity = fogactive ? 350.f : 0.f;
|
2020-11-26 15:03:40 +00:00
|
|
|
DoInterpolations(smoothratio / 65536.);
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2020-07-07 02:54:12 +00:00
|
|
|
setgamepalette(BASEPAL);
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2022-08-03 17:38:39 +00:00
|
|
|
float fov = r_fov;
|
|
|
|
|
2020-11-02 22:53:55 +00:00
|
|
|
if (ud.cameraactor)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2021-12-22 22:27:32 +00:00
|
|
|
auto act = ud.cameraactor;
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2021-12-22 22:27:32 +00:00
|
|
|
if (act->spr.yvel < 0) act->spr.yvel = -100;
|
|
|
|
else if (act->spr.yvel > 199) act->spr.yvel = 300;
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2022-08-28 03:15:31 +00:00
|
|
|
cang = interpolatedangle(DAngle::fromBuild(ud.cameraactor->tempang), act->spr.angle, smoothratio);
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2021-12-22 22:27:32 +00:00
|
|
|
auto bh = buildhoriz(act->spr.yvel);
|
2021-12-27 09:15:42 +00:00
|
|
|
auto cstat = act->spr.cstat;
|
|
|
|
act->spr.cstat = CSTAT_SPRITE_INVISIBLE;
|
2022-08-28 00:40:50 +00:00
|
|
|
renderView(act, act->sector(), act->int_pos().X, act->int_pos().Y, act->int_pos().Z - (4 << 8), cang, bh, nullAngle, smoothratio, sceneonly, fov);
|
2021-12-27 09:15:42 +00:00
|
|
|
act->spr.cstat = cstat;
|
|
|
|
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-08-03 17:59:46 +00:00
|
|
|
if (isRRRA() && p->DrugMode)
|
|
|
|
{
|
|
|
|
double fovdelta = atan(getdrugmode(p, 65536) * (1. / 65536.)) * (360. / pi::pi()) - 90.;
|
|
|
|
fov = (float)clamp<double>(r_fov + fovdelta * 0.6, r_fov, 150.);
|
|
|
|
}
|
2022-08-03 17:38:39 +00:00
|
|
|
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2020-11-05 06:25:44 +00:00
|
|
|
// The camera texture must be rendered with the base palette, so this is the only place where the current global palette can be set.
|
|
|
|
// The setting here will be carried over to the rendering of the weapon sprites, but other 2D content will always default to the main palette.
|
|
|
|
setgamepalette(setpal(p));
|
|
|
|
|
2020-09-23 05:34:03 +00:00
|
|
|
// set screen rotation.
|
2022-08-27 11:48:57 +00:00
|
|
|
rotscrnang = !SyncInput() ? p->angle.rotscrnang : p->angle.interpolatedrotscrn(smoothratio);
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2021-11-18 18:33:32 +00:00
|
|
|
#if 0
|
2020-07-05 14:49:00 +00:00
|
|
|
if ((snum == myconnectindex) && (numplayers > 1))
|
|
|
|
{
|
2021-04-11 06:45:19 +00:00
|
|
|
cposx = interpolatedvalue(omyx, myx, smoothratio);
|
|
|
|
cposy = interpolatedvalue(omyy, myy, smoothratio);
|
|
|
|
cposz = interpolatedvalue(omyz, myz, smoothratio);
|
2020-11-30 22:40:16 +00:00
|
|
|
if (SyncInput())
|
2020-07-16 15:59:25 +00:00
|
|
|
{
|
2021-11-06 03:00:41 +00:00
|
|
|
choriz = interpolatedhorizon(omyhoriz + omyhorizoff, myhoriz + myhorizoff, smoothratio);
|
2021-04-11 06:45:19 +00:00
|
|
|
cang = interpolatedangle(omyang, myang, smoothratio);
|
2020-07-16 15:59:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-07 12:13:21 +00:00
|
|
|
cang = myang;
|
|
|
|
choriz = myhoriz + myhorizoff;
|
2020-07-16 15:59:25 +00:00
|
|
|
}
|
2020-07-05 14:49:00 +00:00
|
|
|
sect = mycursectnum;
|
|
|
|
}
|
|
|
|
else
|
2021-11-18 18:33:32 +00:00
|
|
|
#endif
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2022-02-04 17:11:44 +00:00
|
|
|
cposx = interpolatedvalue(p->player_int_opos().X, p->player_int_pos().X, smoothratio);
|
|
|
|
cposy = interpolatedvalue(p->player_int_opos().Y, p->player_int_pos().Y, smoothratio);
|
|
|
|
cposz = interpolatedvalue(p->player_int_opos().Z, p->player_int_pos().Z, smoothratio);;
|
2020-11-30 22:40:16 +00:00
|
|
|
if (SyncInput())
|
2020-07-16 15:59:25 +00:00
|
|
|
{
|
|
|
|
// Original code for when the values are passed through the sync struct
|
2022-08-27 13:09:22 +00:00
|
|
|
cang = p->angle.interpolatedsum(smoothratio);
|
2020-10-07 06:12:37 +00:00
|
|
|
choriz = p->horizon.interpolatedsum(smoothratio);
|
2020-07-16 15:59:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// This is for real time updating of the view direction.
|
2022-08-27 13:09:22 +00:00
|
|
|
cang = p->angle.sum();
|
2020-10-07 06:12:37 +00:00
|
|
|
choriz = p->horizon.sum();
|
2020-07-16 15:59:25 +00:00
|
|
|
}
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-22 22:27:32 +00:00
|
|
|
DDukeActor* viewer;
|
2021-12-27 09:15:42 +00:00
|
|
|
bool camview = false;
|
2020-11-02 23:20:51 +00:00
|
|
|
if (p->newOwner != nullptr)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2021-12-22 22:27:32 +00:00
|
|
|
auto act = p->newOwner;
|
2022-08-29 09:44:48 +00:00
|
|
|
cang = act->interpolatedangle(smoothratio / 65536.);
|
2021-12-22 22:27:32 +00:00
|
|
|
choriz = buildhoriz(act->spr.shade);
|
2022-01-31 18:21:49 +00:00
|
|
|
cposx = act->int_pos().X;
|
|
|
|
cposy = act->int_pos().Y;
|
|
|
|
cposz = act->int_pos().Z;
|
2021-12-30 15:51:56 +00:00
|
|
|
sect = act->sector();
|
2022-08-28 00:40:50 +00:00
|
|
|
rotscrnang = nullAngle;
|
2020-07-31 00:35:24 +00:00
|
|
|
smoothratio = MaxSmoothRatio;
|
2021-12-22 22:27:32 +00:00
|
|
|
viewer = act;
|
2021-12-27 09:15:42 +00:00
|
|
|
camview = true;
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
else if (p->over_shoulder_on == 0)
|
|
|
|
{
|
2021-04-11 06:45:19 +00:00
|
|
|
if (cl_viewbob) cposz += interpolatedvalue(p->opyoff, p->pyoff, smoothratio);
|
2021-12-22 22:27:32 +00:00
|
|
|
viewer = p->GetActor();
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
2020-09-25 07:52:00 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
cposz -= isRR() ? 3840 : 3072;
|
|
|
|
|
2021-12-22 22:27:32 +00:00
|
|
|
viewer = p->GetActor();
|
2022-08-27 08:24:16 +00:00
|
|
|
if (!calcChaseCamPos(&cposx, &cposy, &cposz, viewer, §, cang, choriz, smoothratio))
|
2020-09-25 07:52:00 +00:00
|
|
|
{
|
|
|
|
cposz += isRR() ? 3840 : 3072;
|
2022-08-27 08:24:16 +00:00
|
|
|
calcChaseCamPos(&cposx, &cposy, &cposz, viewer, §, cang, choriz, smoothratio);
|
2020-09-25 07:52:00 +00:00
|
|
|
}
|
|
|
|
}
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2022-08-21 10:19:06 +00:00
|
|
|
cz = int(p->GetActor()->ceilingz * zworldtoint);
|
|
|
|
fz = int(p->GetActor()->floorz * zworldtoint);
|
2020-07-05 14:49:00 +00:00
|
|
|
|
|
|
|
if (earthquaketime > 0 && p->on_ground == 1)
|
|
|
|
{
|
|
|
|
cposz += 256 - (((earthquaketime) & 1) << 9);
|
2022-08-27 08:24:16 +00:00
|
|
|
cang += DAngle::fromBuild((2 - ((earthquaketime) & 2)) << 2);
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-21 17:19:45 +00:00
|
|
|
if (p->GetActor()->spr.pal == 1) cposz -= (18 << 8);
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2020-11-02 23:20:51 +00:00
|
|
|
else if (p->spritebridge == 0 && p->newOwner == nullptr)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2022-02-04 16:49:48 +00:00
|
|
|
if (cposz < (p->truecz * zworldtoint + (4 << 8))) cposz = cz + (4 << 8);
|
|
|
|
else if (cposz > (p->truefz * zworldtoint - (4 << 8))) cposz = fz - (4 << 8);
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
|
|
|
|
2021-11-18 18:33:32 +00:00
|
|
|
if (sect)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
2021-11-18 18:33:32 +00:00
|
|
|
getzsofslopeptr(sect, cposx, cposy, &cz, &fz);
|
2020-07-05 14:49:00 +00:00
|
|
|
if (cposz < cz + (4 << 8)) cposz = cz + (4 << 8);
|
|
|
|
if (cposz > fz - (4 << 8)) cposz = fz - (4 << 8);
|
|
|
|
}
|
|
|
|
|
2020-10-07 02:28:38 +00:00
|
|
|
choriz = clamp(choriz, q16horiz(gi->playerHorizMin()), q16horiz(gi->playerHorizMax()));
|
2020-07-05 14:49:00 +00:00
|
|
|
|
2021-12-27 09:15:42 +00:00
|
|
|
auto cstat = viewer->spr.cstat;
|
|
|
|
if (camview) viewer->spr.cstat = CSTAT_SPRITE_INVISIBLE;
|
2022-08-03 17:38:39 +00:00
|
|
|
renderView(viewer, sect, cposx, cposy, cposz, cang, choriz, rotscrnang, smoothratio, sceneonly, fov);
|
2021-12-27 09:15:42 +00:00
|
|
|
viewer->spr.cstat = cstat;
|
2020-07-05 14:49:00 +00:00
|
|
|
}
|
2020-09-05 21:20:48 +00:00
|
|
|
//GLInterface.SetMapFog(false);
|
2020-11-26 15:03:40 +00:00
|
|
|
RestoreInterpolations();
|
2020-07-05 14:49:00 +00:00
|
|
|
|
|
|
|
if (!isRRRA() || !fogactive)
|
|
|
|
{
|
2021-02-18 10:46:36 +00:00
|
|
|
if (PlayClock < lastvisinc)
|
2020-07-05 14:49:00 +00:00
|
|
|
{
|
|
|
|
if (abs(p->visibility - ud.const_visibility) > 8)
|
|
|
|
p->visibility += (ud.const_visibility - p->visibility) >> 2;
|
|
|
|
}
|
|
|
|
else p->visibility = ud.const_visibility;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-05 19:21:39 +00:00
|
|
|
bool GameInterface::GenerateSavePic()
|
|
|
|
{
|
2022-01-08 11:09:04 +00:00
|
|
|
displayrooms(myconnectindex, MaxSmoothRatio, true);
|
2020-07-05 19:21:39 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-08-27 08:49:41 +00:00
|
|
|
void GameInterface::processSprites(tspriteArray& tsprites, int viewx, int viewy, int viewz, DAngle viewang, double smoothRatio)
|
2021-03-26 00:35:23 +00:00
|
|
|
{
|
2022-08-27 08:49:41 +00:00
|
|
|
fi.animatesprites(tsprites, viewx, viewy, viewang.Buildang(), int(smoothRatio));
|
2021-03-26 00:35:23 +00:00
|
|
|
}
|
2020-07-05 19:21:39 +00:00
|
|
|
|
|
|
|
|
2020-07-04 21:40:54 +00:00
|
|
|
END_DUKE_NS
|