- replaced the engine automap drawer with one leveraging the newly added sector geometry data.

This eliminates a lot of code depending on Build's projection math.
This commit is contained in:
Christoph Oelckers 2021-03-20 12:47:51 +01:00
parent 88706e8e13
commit 30f4e2b29d
18 changed files with 327 additions and 607 deletions

View file

@ -886,6 +886,12 @@ inline void tileUpdatePicnum(int* const tileptr, int const obj, int stat)
tile = RotTile(tile).newtile;
}
inline void setgotpic(int32_t tilenume)
{
gotpic[tilenume >> 3] |= pow2char[tilenume & 7];
}
#include "iterators.h"

View file

@ -223,19 +223,13 @@ struct spritetype
int8_t xoffset, yoffset;
int16_t sectnum, statnum;
int16_t oang, ang, owner;
union {
struct
{
union {
int16_t xvel, index;
};
int16_t yvel;
union {
int16_t zvel, inittype;
};
union {
int16_t xvel, index;
};
int16_t yvel;
union {
int16_t zvel, inittype;
};
vec3_16_t vel;
};
union {
int16_t lotag, type;
};

View file

@ -116,18 +116,10 @@ typedef ssize_t bssize_t;
using std::enable_if_t;
using native_t = intptr_t;
typedef struct MAY_ALIAS {
int32_t x, y;
} vec2_t;
typedef struct {
float x, y;
} vec2f_t;
typedef struct {
double x, y;
} vec2d_t;
typedef struct MAY_ALIAS {
union {
struct { int32_t x, y, z; };
@ -135,12 +127,6 @@ typedef struct MAY_ALIAS {
};
} vec3_t;
typedef struct MAY_ALIAS {
union {
struct { int16_t x, y, z; };
vec2_16_t vec2;
};
} vec3_16_t;
typedef struct {
union {
@ -177,8 +163,6 @@ static_assert(sizeof(vec3d_t) == sizeof(double) * 3);
////////// Data serialization //////////
inline int32_t B_LITTLE32(int32_t val) { return LittleLong(val); }
inline uint32_t B_LITTLE32(uint32_t val) { return LittleLong(val); }
inline int32_t B_LITTLE16(int16_t val) { return LittleShort(val); }
inline uint32_t B_LITTLE16(uint16_t val) { return LittleShort(val); }

View file

@ -1,6 +1,6 @@
#pragma once
// nobody uses these. What's so cool about naked numbers? :(
#if 0
// system defines for status bits
#define CEILING_STAT_PLAX BIT(0)
#define CEILING_STAT_SLOPE BIT(1)
@ -39,4 +39,5 @@
#define CSTAT_WALL_YFLIP BIT(8)
#define CSTAT_WALL_TRANS_FLIP BIT(9)
#define CSTAT_WALL_BLOCK_ACTOR (BIT(14)) // my def
#define CSTAT_WALL_WARP_HITSCAN (BIT(15)) // my def
#define CSTAT_WALL_WARP_HITSCAN (BIT(15)) // my def
#endif

View file

@ -10,6 +10,7 @@
#include "clip.h"
#include "engine_priv.h"
#include "printf.h"
#include "gamefuncs.h"
static int16_t clipnum;
@ -574,7 +575,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
if ((cstat&dasprclipmask) == 0)
continue;
vec2_t p1 = *(vec2_t const *)spr;
auto p1 = spr->pos.vec2;
switch (cstat & (CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR))
{
@ -599,31 +600,30 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
{
int32_t height, daz = spr->z+spriteheightofs(j, &height, 1);
if (pos->z > daz-height-flordist && pos->z < daz+ceildist)
if (pos->z > daz - height - flordist && pos->z < daz + ceildist)
{
vec2_t p2;
vec2_t pp[2];
GetWallSpritePosition(spr, p1, pp);
get_wallspr_points(spr, &p1.x, &p2.x, &p1.y, &p2.y);
if (clipinsideboxline(cent.x, cent.y, p1.x, p1.y, p2.x, p2.y, rad) != 0)
if (clipinsideboxline(cent.x, cent.y, pp[0].x, pp[0].y, pp[1].x, pp[1].y, rad) != 0)
{
vec2_t v = { MulScale(bcos(spr->ang + 256), walldist, 14),
MulScale(bsin(spr->ang + 256), walldist, 14) };
if ((p1.x-pos->x) * (p2.y-pos->y) >= (p2.x-pos->x) * (p1.y-pos->y)) // Front
addclipline(p1.x+v.x, p1.y+v.y, p2.x+v.y, p2.y-v.x, (int16_t)j+49152, false);
if ((pp[0].x - pos->x) * (pp[1].y - pos->y) >= (pp[1].x - pos->x) * (pp[0].y - pos->y)) // Front
addclipline(pp[0].x + v.x, pp[0].y + v.y, pp[1].x + v.y, pp[1].y - v.x, (int16_t)j + 49152, false);
else
{
if ((cstat & 64) != 0)
continue;
addclipline(p2.x-v.x, p2.y-v.y, p1.x-v.y, p1.y+v.x, (int16_t)j+49152, false);
addclipline(pp[1].x - v.x, pp[1].y - v.y, pp[0].x - v.y, pp[0].y + v.x, (int16_t)j + 49152, false);
}
//Side blocker
if ((p2.x-p1.x) * (pos->x-p1.x)+(p2.y-p1.y) * (pos->y-p1.y) < 0)
addclipline(p1.x-v.y, p1.y+v.x, p1.x+v.x, p1.y+v.y, (int16_t)j+49152, true);
else if ((p1.x-p2.x) * (pos->x-p2.x)+(p1.y-p2.y) * (pos->y-p2.y) < 0)
addclipline(p2.x+v.y, p2.y-v.x, p2.x-v.x, p2.y-v.y, (int16_t)j+49152, true);
if ((pp[1].x - pp[0].x) * (pos->x - pp[0].x) + (pp[1].y - pp[0].y) * (pos->y - pp[0].y) < 0)
addclipline(pp[0].x - v.y, pp[0].y + v.x, pp[0].x + v.x, pp[0].y + v.y, (int16_t)j + 49152, true);
else if ((pp[0].x - pp[1].x) * (pos->x - pp[1].x) + (pp[0].y - pp[1].y) * (pos->y - pp[1].y) < 0)
addclipline(pp[1].x + v.y, pp[1].y - v.x, pp[1].x - v.x, pp[1].y - v.y, (int16_t)j + 49152, true);
}
}
break;
@ -631,41 +631,38 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
{
if (pos->z > spr->z-flordist && pos->z < spr->z+ceildist)
if (pos->z > spr->z - flordist && pos->z < spr->z + ceildist)
{
if ((cstat&64) != 0)
if ((pos->z > spr->z) == ((cstat&8)==0))
if ((cstat & 64) != 0)
if ((pos->z > spr->z) == ((cstat & 8) == 0))
continue;
rxi[0] = p1.x;
ryi[0] = p1.y;
get_floorspr_points((uspriteptr_t) spr, 0, 0, &rxi[0], &rxi[1], &rxi[2], &rxi[3],
&ryi[0], &ryi[1], &ryi[2], &ryi[3]);
vec2_t pp[4];
GetFlatSpritePosition(spr, p1, pp);
vec2_t v = { MulScale(bcos(spr->ang - 256), walldist, 14),
MulScale(bsin(spr->ang - 256), walldist, 14) };
if ((rxi[0]-pos->x) * (ryi[1]-pos->y) < (rxi[1]-pos->x) * (ryi[0]-pos->y))
if ((pp[0].x - pos->x) * (pp[1].y - pos->y) < (pp[1].x - pos->x) * (pp[0].y - pos->y))
{
if (clipinsideboxline(cent.x, cent.y, rxi[1], ryi[1], rxi[0], ryi[0], rad) != 0)
addclipline(rxi[1]-v.y, ryi[1]+v.x, rxi[0]+v.x, ryi[0]+v.y, (int16_t)j+49152, false);
if (clipinsideboxline(cent.x, cent.y, pp[1].x, pp[1].y, pp[0].x, pp[0].y, rad) != 0)
addclipline(pp[1].x - v.y, pp[1].y + v.x, pp[0].x + v.x, pp[0].y + v.y, (int16_t)j + 49152, false);
}
else if ((rxi[2]-pos->x) * (ryi[3]-pos->y) < (rxi[3]-pos->x) * (ryi[2]-pos->y))
else if ((pp[2].x - pos->x) * (pp[3].y - pos->y) < (pp[3].x - pos->x) * (pp[2].y - pos->y))
{
if (clipinsideboxline(cent.x, cent.y, rxi[3], ryi[3], rxi[2], ryi[2], rad) != 0)
addclipline(rxi[3]+v.y, ryi[3]-v.x, rxi[2]-v.x, ryi[2]-v.y, (int16_t)j+49152, false);
if (clipinsideboxline(cent.x, cent.y, pp[3].x, pp[3].y, pp[2].x, pp[2].y, rad) != 0)
addclipline(pp[3].x + v.y, pp[3].y - v.x, pp[2].x - v.x, pp[2].y - v.y, (int16_t)j + 49152, false);
}
if ((rxi[1]-pos->x) * (ryi[2]-pos->y) < (rxi[2]-pos->x) * (ryi[1]-pos->y))
if ((pp[1].x - pos->x) * (pp[2].y - pos->y) < (pp[2].x - pos->x) * (pp[1].y - pos->y))
{
if (clipinsideboxline(cent.x, cent.y, rxi[2], ryi[2], rxi[1], ryi[1], rad) != 0)
addclipline(rxi[2]-v.x, ryi[2]-v.y, rxi[1]-v.y, ryi[1]+v.x, (int16_t)j+49152, false);
if (clipinsideboxline(cent.x, cent.y, pp[2].x, pp[2].y, pp[1].x, pp[1].y, rad) != 0)
addclipline(pp[2].x - v.x, pp[2].y - v.y, pp[1].x - v.y, pp[1].y + v.x, (int16_t)j + 49152, false);
}
else if ((rxi[3]-pos->x) * (ryi[0]-pos->y) < (rxi[0]-pos->x) * (ryi[3]-pos->y))
else if ((pp[3].x - pos->x) * (pp[0].y - pos->y) < (pp[0].x - pos->x) * (pp[3].y - pos->y))
{
if (clipinsideboxline(cent.x, cent.y, rxi[0], ryi[0], rxi[3], ryi[3], rad) != 0)
addclipline(rxi[0]+v.x, ryi[0]+v.y, rxi[3]+v.y, ryi[3]-v.x, (int16_t)j+49152, false);
if (clipinsideboxline(cent.x, cent.y, pp[0].x, pp[0].y, pp[3].x, pp[3].y, rad) != 0)
addclipline(pp[0].x + v.x, pp[0].y + v.y, pp[3].x + v.y, pp[3].y - v.x, (int16_t)j + 49152, false);
}
}
break;
@ -1043,7 +1040,7 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
{
int32_t clipyou = 0;
vec2_t v1 = sprite[j].pos.vec2;
auto v1 = sprite[j].pos.vec2;
switch (cstat & CSTAT_SPRITE_ALIGNMENT_MASK)
{
@ -1061,14 +1058,14 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
case CSTAT_SPRITE_ALIGNMENT_WALL:
{
vec2_t v2;
get_wallspr_points((uspriteptr_t)&sprite[j], &v1.x, &v2.x, &v1.y, &v2.y);
vec2_t pp[2];
GetWallSpritePosition(&sprite[j], v1, pp);
if (clipinsideboxline(pos->x,pos->y,v1.x,v1.y,v2.x,v2.y,walldist+1) != 0)
if (clipinsideboxline(pos->x, pos->y, pp[0].x, pp[0].y, pp[1].x, pp[1].y, walldist + 1) != 0)
{
int32_t k;
daz = sprite[j].z + spriteheightofs(j, &k, 1);
daz2 = daz-k;
daz2 = daz - k;
clipyou = 1;
}
break;
@ -1081,17 +1078,16 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
if ((cstat&64) != 0 && (pos->z > daz) == ((cstat&8)==0))
continue;
vec2_t v2, v3, v4;
get_floorspr_points((uspriteptr_t) &sprite[j], pos->x, pos->y, &v1.x, &v2.x, &v3.x, &v4.x,
&v1.y, &v2.y, &v3.y, &v4.y);
vec2_t pp[4];
GetFlatSpritePosition(&sprite[j], v1 - pos->vec2, pp);
vec2_t const da = { MulScale(bcos(sprite[j].ang - 256), walldist + 4, 14),
MulScale(bsin(sprite[j].ang - 256), walldist + 4, 14) };
v1.x += da.x; v2.x -= da.y; v3.x -= da.x; v4.x += da.y;
v1.y += da.y; v2.y += da.x; v3.y -= da.y; v4.y -= da.x;
pp[0].x += da.x; pp[1].x -= da.y; pp[2].x -= da.x; pp[3].x += da.y;
pp[0].y += da.y; pp[1].y += da.x; pp[2].y -= da.y; pp[3].y -= da.x;
clipyou = get_floorspr_clipyou(v1, v2, v3, v4);
clipyou = get_floorspr_clipyou(pp[0], pp[1], pp[2], pp[3]);
break;
}
}
@ -1379,7 +1375,6 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
if ((cstat&dasprclipmask) == 0)
continue;
x1 = spr->x; y1 = spr->y; z1 = spr->z;
switch (cstat&CSTAT_SPRITE_ALIGNMENT)
{
case 0:
@ -1399,13 +1394,14 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
int32_t ucoefup16;
int32_t tilenum = spr->picnum;
get_wallspr_points(spr, &x1, &x2, &y1, &y2);
vec2_t pp[2];
GetWallSpritePosition(spr, spr->pos.vec2, pp);
if ((cstat&64) != 0) //back side of 1-way sprite
if (compat_maybe_truncate_to_int32((coord_t)(x1-sv->x)*(y2-sv->y))
< compat_maybe_truncate_to_int32((coord_t)(x2-sv->x)*(y1-sv->y))) continue;
if ((cstat & 64) != 0) //back side of 1-way sprite
if (compat_maybe_truncate_to_int32((coord_t)(pp[0].x - sv->x) * (pp[1].y - sv->y))
< compat_maybe_truncate_to_int32((coord_t)(pp[1].x - sv->x) * (pp[0].y - sv->y))) continue;
ucoefup16 = rintersect(sv->x,sv->y,sv->z,vx,vy,vz,x1,y1,x2,y2,&intx,&inty,&intz);
ucoefup16 = rintersect(sv->x, sv->y, sv->z, vx, vy, vz, pp[0].x, pp[0].y, pp[1].x, pp[1].y, &intx, &inty, &intz);
if (ucoefup16 == -1) continue;
if (abs(intx-sv->x)+abs(inty-sv->y) > abs((hit->pos.x)-sv->x)+abs((hit->pos.y)-sv->y))
@ -1438,9 +1434,10 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
{
int32_t x3, y3, x4, y4, zz;
int32_t zz;
intz = z1;
if (vz == 0 || ((intz-sv->z)^vz) < 0) continue;
if ((cstat&64) != 0)
@ -1465,10 +1462,10 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
if (abs(intx-sv->x)+abs(inty-sv->y) > abs((hit->pos.x)-sv->x)+abs((hit->pos.y)-sv->y))
continue;
get_floorspr_points((uspriteptr_t)spr, intx, inty, &x1, &x2, &x3, &x4,
&y1, &y2, &y3, &y4);
vec2_t pp[4];
GetFlatSpritePosition(spr, spr->pos.vec2 - vec2_t(intx, inty), pp);
if (get_floorspr_clipyou({x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}))
if (get_floorspr_clipyou(pp[0], pp[1], pp[2], pp[3]))
hit_set(hit, dasector, -1, z, intx, inty, intz);
break;

View file

@ -157,8 +157,6 @@ int32_t xdimen = -1, xdimenscale, xdimscale;
float fxdimen = -1.f;
int32_t ydimen;
int32_t rxi[8], ryi[8];
int32_t globalposx, globalposy, globalposz;
fixed_t qglobalhoriz;
float fglobalposx, fglobalposy, fglobalposz;
@ -1289,8 +1287,7 @@ killsprite:
if (!ok)
{
// If not, check if any of the border points are...
int32_t xx[4] = { tspr->x };
int32_t yy[4] = { tspr->y };
vec2_t pp[4];
int32_t numpts, jj;
const _equation pineq = inleft ? p1eq : p2eq;
@ -1298,9 +1295,7 @@ killsprite:
if ((tspr->cstat & 48) == 32)
{
numpts = 4;
get_floorspr_points(tspr, 0, 0,
&xx[0], &xx[1], &xx[2], &xx[3],
&yy[0], &yy[1], &yy[2], &yy[3]);
GetFlatSpritePosition(tspr, tspr->pos.vec2, pp);
}
else
{
@ -1312,7 +1307,7 @@ killsprite:
if ((tspr->cstat & 48) != 16)
tspriteptr[i]->ang = globalang;
get_wallspr_points(tspr, &xx[0], &xx[1], &yy[0], &yy[1]);
GetWallSpritePosition(tspr, tspr->pos.vec2, pp);
if ((tspr->cstat & 48) != 16)
tspriteptr[i]->ang = oang;
@ -1320,8 +1315,8 @@ killsprite:
for (jj=0; jj<numpts; jj++)
{
spr.x = (float)xx[jj];
spr.y = (float)yy[jj];
spr.x = (float)pp[jj].x;
spr.y = (float)pp[jj].y;
if (!sameside(&maskeq, &spr, &pos)) // behind the maskwall,
if ((sameside(&p1eq, &middle, &spr) && // inside the 'cone',
@ -1365,367 +1360,6 @@ killsprite:
}
//==========================================================================
//
//
//
//==========================================================================
void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex,
int clipx1, int clipy1, int clipx2, int clipy2)
{
//Convert int32_t to float (in-place)
TArray<FVector4> points(npoints, true);
using Point = std::pair<float, float>;
std::vector<std::vector<Point>> polygon;
std::vector<Point>* curPoly;
polygon.resize(1);
curPoly = &polygon.back();
for (bssize_t i = 0; i < npoints; ++i)
{
auto X = ((float)rx1[i]) * (1.0f / 4096.f);
auto Y = ((float)ry1[i]) * (1.0f / 4096.f);
curPoly->push_back(std::make_pair(X, Y));
if (xb1[i] < i && i < npoints - 1)
{
polygon.resize(polygon.size() + 1);
curPoly = &polygon.back();
}
}
// Now make sure that the outer boundary is the first polygon by picking a point that's as much to the outside as possible.
int outer = 0;
float minx = FLT_MAX;
float miny = FLT_MAX;
for (size_t a = 0; a < polygon.size(); a++)
{
for (auto& pt : polygon[a])
{
if (pt.first < minx || (pt.first == minx && pt.second < miny))
{
minx = pt.first;
miny = pt.second;
outer = a;
}
}
}
if (outer != 0) std::swap(polygon[0], polygon[outer]);
auto indices = mapbox::earcut(polygon);
int p = 0;
for (size_t a = 0; a < polygon.size(); a++)
{
for (auto& pt : polygon[a])
{
FVector4 point = { pt.first, pt.second, float(pt.first * xtex.X + pt.second * ytex.X + otex.X), float(pt.first * xtex.Y + pt.second * ytex.Y + otex.Y) };
points[p++] = point;
}
}
int maskprops = (props >> 7) & DAMETH_MASKPROPS;
FRenderStyle rs = LegacyRenderStyles[STYLE_Translucent];
double alpha = 1.;
if (maskprops > DAMETH_MASK)
{
rs = GetRenderStyle(0, maskprops == DAMETH_TRANS2);
alpha = GetAlphaFromBlend(maskprops, 0);
}
int translation = TRANSLATION(Translation_Remap + curbasepal, palette);
int light = clamp(Scale((numshades - shade), 255, numshades), 0, 255);
PalEntry pe = PalEntry(uint8_t(alpha*255), light, light, light);
twod->AddPoly(tileGetTexture(picnum), points.Data(), points.Size(), indices.data(), indices.size(), translation, pe, rs, clipx1, clipy1, clipx2, clipy2);
}
//==========================================================================
//
//
//
//==========================================================================
#include "build.h"
#include "../src/engine_priv.h"
//
// fillpolygon (internal)
//
static void renderFillPolygon(int32_t npoints)
{
int width = screen->GetWidth();
int height = screen->GetHeight();
// fix for bad next-point (xb1) values...
for (int z = 0; z < npoints; z++)
if ((unsigned)xb1[z] >= (unsigned)npoints)
xb1[z] = 0;
FVector2 xtex, ytex, otex;
int x1 = MulScale(globalx1, xyaspect, 16);
int y2 = MulScale(globaly2, xyaspect, 16);
xtex.X = ((float)asm1) * (1.f / 4294967296.f);
xtex.Y = ((float)asm2) * (1.f / 4294967296.f);
ytex.X = ((float)x1) * (1.f / 4294967296.f);
ytex.Y = ((float)y2) * (-1.f / 4294967296.f);
otex.X = (width * xtex.X + height * ytex.X) * -0.5f + fglobalposx * (1.f / 4294967296.f);
otex.Y = (width * xtex.Y + height * ytex.Y) * -0.5f - fglobalposy * (1.f / 4294967296.f);
FillPolygon(rx1, ry1, xb1, npoints, globalpicnum, globalpal, globalshade, globalorientation, xtex, ytex, otex, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y);
}
//
// drawmapview
//
void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
{
int32_t i, j, k, l;
int32_t x, y;
int32_t s, ox, oy;
int width = screen->GetWidth();
int height = screen->GetHeight();
int32_t const oyxaspect = yxaspect, oviewingrange = viewingrange;
renderSetAspect(65536, DivScale((320*5)/8, 200, 16));
memset(gotsector, 0, sizeof(gotsector));
vec2_t const c1 = { (windowxy1.x<<12), (windowxy1.y<<12) };
vec2_t const c2 = { ((windowxy2.x+1)<<12)-1, ((windowxy2.y+1)<<12)-1 };
zoome <<= 8;
vec2_t const bakgvect = { DivScale(-bcos(ang), zoome, 28), DivScale(-bsin(ang), zoome, 28) };
vec2_t const vect = { MulScale(-bsin(ang), zoome, 8), MulScale(-bcos(ang), zoome, 8) };
vec2_t const vect2 = { MulScale(vect.x, yxaspect, 16), MulScale(vect.y, yxaspect, 16) };
int32_t sortnum = 0;
usectorptr_t sec;
for (s=0,sec=(usectorptr_t)&sector[s]; s<numsectors; s++,sec++)
if (gFullMap || show2dsector[s])
{
int32_t npoints = 0; i = 0;
int32_t startwall = sec->wallptr;
j = startwall; l = 0;
uwallptr_t wal;
int32_t w;
for (w=sec->wallnum,wal=(uwallptr_t)&wall[startwall]; w>0; w--,wal++,j++)
{
k = lastwall(j);
if ((k > j) && (npoints > 0)) { xb1[npoints-1] = l; l = npoints; } //overwrite point2
//wall[k].x wal->x wall[wal->point2].x
//wall[k].y wal->y wall[wal->point2].y
if (!DMulScale(wal->x-wall[k].x,wall[wal->point2].y-wal->y,-(wal->y-wall[k].y),wall[wal->point2].x-wal->x, 1)) continue;
ox = wal->x - dax; oy = wal->y - day;
x = DMulScale(ox,vect.x,-oy,vect.y, 16) + (width<<11);
y = DMulScale(oy,vect2.x,ox,vect2.y, 16) + (height<<11);
i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
rx1[npoints] = x;
ry1[npoints] = y;
xb1[npoints] = npoints+1;
npoints++;
}
if (npoints > 0) xb1[npoints-1] = l; //overwrite point2
vec2_t bak = { rx1[0], MulScale(ry1[0]-(height<<11),xyaspect, 16)+(height<<11) };
//Collect floor sprites to draw
SectIterator it(s);
while ((i = it.NextIndex()) >= 0)
{
if (sprite[i].cstat & 32768)
continue;
if ((sprite[i].cstat & 48) == 32)
{
if ((sprite[i].cstat & (64 + 8)) == (64 + 8))
continue;
tsprite[sortnum++].owner = i;
}
}
gotsector[s>>3] |= pow2char[s&7];
globalorientation = (int32_t)sec->floorstat;
if ((globalorientation&1) != 0) continue;
globalfloorpal = globalpal = sec->floorpal;
int _globalpicnum = sec->floorpicnum;
if ((unsigned)_globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
tileUpdatePicnum(&_globalpicnum, s, 0);
globalpicnum = _globalpicnum;
setgotpic(globalpicnum);
if ((tileWidth(globalpicnum) <= 0) || (tileHeight(globalpicnum) <= 0)) continue;
globalshade = max(min<int>(sec->floorshade, numshades - 1), 0);
if ((globalorientation&64) == 0)
{
set_globalpos(dax, day, globalposz);
globalx1 = bakgvect.x; globaly1 = bakgvect.y;
globalx2 = bakgvect.x; globaly2 = bakgvect.y;
}
else
{
ox = wall[wall[startwall].point2].x - wall[startwall].x;
oy = wall[wall[startwall].point2].y - wall[startwall].y;
i = ksqrt(uhypsq(ox,oy)); if (i == 0) continue;
i = 1048576/i;
globalx1 = MulScale(DMulScale(ox,bakgvect.x,oy,bakgvect.y, 10),i, 10);
globaly1 = MulScale(DMulScale(ox,bakgvect.y,-oy,bakgvect.x, 10),i, 10);
ox = (bak.x>>4)-(width<<7); oy = (bak.y>>4)-(height<<7);
globalposx = DMulScale(-oy, globalx1, -ox, globaly1, 28);
globalposy = DMulScale(-ox, globalx1, oy, globaly1, 28);
globalx2 = -globalx1;
globaly2 = -globaly1;
int32_t const daslope = sector[s].floorheinum;
i = ksqrt(daslope*daslope+16777216);
set_globalpos(globalposx, MulScale(globalposy,i, 12), globalposz);
globalx2 = MulScale(globalx2,i, 12);
globaly2 = MulScale(globaly2,i, 12);
}
int globalxshift = (8 - widthBits(globalpicnum));
int globalyshift = (8 - heightBits(globalpicnum));
if (globalorientation & 8) { globalxshift++; globalyshift++; }
// PK: the following can happen for large (>= 512) tile sizes.
if (globalxshift < 0) globalxshift = 0;
if (globalyshift < 0) globalyshift = 0;
if ((globalorientation&0x4) > 0)
{
i = globalposx; globalposx = -globalposy; globalposy = -i;
i = globalx2; globalx2 = globaly1; globaly1 = i;
i = globalx1; globalx1 = -globaly2; globaly2 = -i;
}
if ((globalorientation&0x10) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalposx = -globalposx;
if ((globalorientation&0x20) > 0) globalx2 = -globalx2, globaly2 = -globaly2, globalposy = -globalposy;
asm1 = (globaly1<<globalxshift);
asm2 = (globalx2<<globalyshift);
globalx1 <<= globalxshift;
globaly2 <<= globalyshift;
set_globalpos(((int64_t) globalposx<<(20+globalxshift))+(((uint32_t) sec->floorxpan())<<24),
((int64_t) globalposy<<(20+globalyshift))-(((uint32_t) sec->floorypan())<<24),
globalposz);
renderFillPolygon(npoints);
}
//Sort sprite list
int32_t gap = 1;
while (gap < sortnum) gap = (gap << 1) + 1;
for (gap>>=1; gap>0; gap>>=1)
for (i=0; i<sortnum-gap; i++)
for (j=i; j>=0; j-=gap)
{
if (sprite[tsprite[j].owner].z <= sprite[tsprite[j+gap].owner].z) break;
std::swap(tsprite[j].owner, tsprite[j+gap].owner);
}
for (s=sortnum-1; s>=0; s--)
{
auto const spr = (uspritetype * )&sprite[tsprite[s].owner];
if ((spr->cstat&48) == 32)
{
const int32_t xspan = tileWidth(spr->picnum);
int32_t npoints = 0;
vec2_t v1 = { spr->x, spr->y }, v2, v3, v4;
get_floorspr_points(spr, 0, 0, &v1.x, &v2.x, &v3.x, &v4.x,
&v1.y, &v2.y, &v3.y, &v4.y);
xb1[0] = 1; xb1[1] = 2; xb1[2] = 3; xb1[3] = 0;
npoints = 4;
i = 0;
ox = v1.x - dax; oy = v1.y - day;
x = DMulScale(ox,vect.x,-oy,vect.y, 16) + (width<<11);
y = DMulScale(oy,vect2.x,ox,vect2.y, 16) + (height<<11);
i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
rx1[0] = x; ry1[0] = y;
ox = v2.x - dax; oy = v2.y - day;
x = DMulScale(ox,vect.x,-oy,vect.y, 16) + (width<<11);
y = DMulScale(oy,vect2.x,ox,vect2.y, 16) + (height<<11);
i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
rx1[1] = x; ry1[1] = y;
ox = v3.x - dax; oy = v3.y - day;
x = DMulScale(ox,vect.x,-oy,vect.y, 16) + (width<<11);
y = DMulScale(oy,vect2.x,ox,vect2.y, 16) + (height<<11);
i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
rx1[2] = x; ry1[2] = y;
x = rx1[0]+rx1[2]-rx1[1];
y = ry1[0]+ry1[2]-ry1[1];
i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
rx1[3] = x; ry1[3] = y;
vec2_t bak = { rx1[0], MulScale(ry1[0] - (height << 11), xyaspect, 16) + (height << 11) };
globalpicnum = spr->picnum;
globalpal = spr->pal; // GL needs this, software doesn't
int _globalpicnum = sec->floorpicnum;
if ((unsigned)_globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
tileUpdatePicnum(&_globalpicnum, s, 0);
globalpicnum = _globalpicnum;
setgotpic(globalpicnum);
if ((tileWidth(globalpicnum) <= 0) || (tileHeight(globalpicnum) <= 0)) continue;
if ((sector[spr->sectnum].ceilingstat&1) > 0)
globalshade = ((int32_t)sector[spr->sectnum].ceilingshade);
else
globalshade = ((int32_t)sector[spr->sectnum].floorshade);
globalshade = max(min(globalshade+spr->shade+6,numshades-1),0);
//relative alignment stuff
ox = v2.x-v1.x; oy = v2.y-v1.y;
i = ox*ox+oy*oy; if (i == 0) continue; i = 65536*16384 / i;
globalx1 = MulScale(DMulScale(ox,bakgvect.x,oy,bakgvect.y, 10),i, 10);
globaly1 = MulScale(DMulScale(ox,bakgvect.y,-oy,bakgvect.x, 10),i, 10);
ox = v1.y-v4.y; oy = v4.x-v1.x;
i = ox*ox+oy*oy; if (i == 0) continue; i = 65536 * 16384 / i;
globalx2 = MulScale(DMulScale(ox,bakgvect.x,oy,bakgvect.y, 10),i, 10);
globaly2 = MulScale(DMulScale(ox,bakgvect.y,-oy,bakgvect.x, 10),i, 10);
ox = widthBits(globalpicnum);
oy = heightBits(globalpicnum);
if ((1 << ox) != xspan)
{
ox++;
globalx1 = MulScale(globalx1,xspan,ox);
globaly1 = MulScale(globaly1,xspan,ox);
}
bak.x = (bak.x>>4)-(width<<7); bak.y = (bak.y>>4)-(height<<7);
globalposx = DMulScale(-bak.y,globalx1,-bak.x,globaly1, 28);
globalposy = DMulScale(bak.x,globalx2,-bak.y,globaly2, 28);
if ((spr->cstat&0x4) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalposx = -globalposx;
asm1 = (globaly1<<2); globalx1 <<= 2; globalposx <<= (20+2);
asm2 = (globalx2<<2); globaly2 <<= 2; globalposy <<= (20+2);
set_globalpos(globalposx, globalposy, globalposz);
// so polymost can get the translucency. ignored in software mode:
globalorientation = ((spr->cstat&2)<<7) | ((spr->cstat&512)>>2);
renderFillPolygon(npoints);
}
}
}
//
// qloadkvx
//

View file

@ -62,7 +62,6 @@ extern int32_t xb1[MAXWALLSB];
extern int32_t rx1[MAXWALLSB], ry1[MAXWALLSB];
extern int16_t bunchp2[MAXWALLSB];
extern int16_t numscans, numbunches;
extern int32_t rxi[8], ryi[8];
// int32_t wallmost(int16_t *mostbuf, int32_t w, int32_t sectnum, char dastat);
@ -79,17 +78,11 @@ static FORCE_INLINE int32_t bad_tspr(tspriteptr_t tspr)
return (tspr->owner < 0 || (unsigned)tspr->picnum >= MAXTILES);
}
static FORCE_INLINE void setgotpic(int32_t tilenume)
{
gotpic[tilenume>>3] |= pow2char[tilenume&7];
}
// Get properties of parallaxed sky to draw.
// Returns: pointer to tile offset array. Sets-by-pointer the other three.
const int16_t* getpsky(int32_t picnum, int32_t* dapyscale, int32_t* dapskybits, int32_t* dapyoffs, int32_t* daptileyscale);
static FORCE_INLINE void set_globalpos(int32_t const x, int32_t const y, int32_t const z)
inline void set_globalpos(int32_t const x, int32_t const y, int32_t const z)
{
globalposx = x, fglobalposx = (float)x;
globalposy = y, fglobalposy = (float)y;
@ -97,72 +90,6 @@ static FORCE_INLINE void set_globalpos(int32_t const x, int32_t const y, int32_t
}
// x1, y1: in/out
// rest x/y: out
template <typename T>
static inline void get_wallspr_points(T const * const spr, int32_t *x1, int32_t *x2,
int32_t *y1, int32_t *y2)
{
//These lines get the 2 points of the rotated sprite
//Given: (x1, y1) starts out as the center point
const int32_t tilenum=spr->picnum, ang=spr->ang;
const int32_t xrepeat = spr->xrepeat;
int32_t xoff = tileLeftOffset(tilenum) + spr->xoffset;
int32_t k, l, dax, day;
if (spr->cstat&4)
xoff = -xoff;
dax = bsin(ang) * xrepeat;
day = -bcos(ang) * xrepeat;
l = tileWidth(tilenum);
k = (l>>1)+xoff;
*x1 -= MulScale(dax,k, 16);
*x2 = *x1 + MulScale(dax,l, 16);
*y1 -= MulScale(day,k, 16);
*y2 = *y1 + MulScale(day,l, 16);
}
// x1, y1: in/out
// rest x/y: out
template <typename T>
static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t py,
int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4)
{
const int32_t tilenum = spr->picnum;
const int32_t cosang = bcos(spr->ang);
const int32_t sinang = bsin(spr->ang);
vec2_t const span = { tileWidth(tilenum), tileHeight(tilenum)};
vec2_t const repeat = { spr->xrepeat, spr->yrepeat };
vec2_t adjofs = { tileLeftOffset(tilenum) + spr->xoffset, tileTopOffset(tilenum) + spr->yoffset };
if (spr->cstat & 4)
adjofs.x = -adjofs.x;
if (spr->cstat & 8)
adjofs.y = -adjofs.y;
vec2_t const center = { ((span.x >> 1) + adjofs.x) * repeat.x, ((span.y >> 1) + adjofs.y) * repeat.y };
vec2_t const rspan = { span.x * repeat.x, span.y * repeat.y };
vec2_t const ofs = { -MulScale(cosang, rspan.y, 16), -MulScale(sinang, rspan.y, 16) };
*x1 += DMulScale(sinang, center.x, cosang, center.y, 16) - px;
*y1 += DMulScale(sinang, center.y, -cosang, center.x, 16) - py;
*x2 = *x1 - MulScale(sinang, rspan.x, 16);
*y2 = *y1 + MulScale(cosang, rspan.x, 16);
*x3 = *x2 + ofs.x, *x4 = *x1 + ofs.x;
*y3 = *y2 + ofs.y, *y4 = *y1 + ofs.y;
}
inline int widthBits(int num)
{
return sizeToBits(tileWidth(num));

View file

@ -675,15 +675,15 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
fil.Read((char *)&head,sizeof(md2head_t));
#if B_BIG_ENDIAN != 0
head.id = B_LITTLE32(head.id); head.vers = B_LITTLE32(head.vers);
head.skinxsiz = B_LITTLE32(head.skinxsiz); head.skinysiz = B_LITTLE32(head.skinysiz);
head.framebytes = B_LITTLE32(head.framebytes); head.numskins = B_LITTLE32(head.numskins);
head.numverts = B_LITTLE32(head.numverts); head.numuv = B_LITTLE32(head.numuv);
head.numtris = B_LITTLE32(head.numtris); head.numglcmds = B_LITTLE32(head.numglcmds);
head.numframes = B_LITTLE32(head.numframes); head.ofsskins = B_LITTLE32(head.ofsskins);
head.ofsuv = B_LITTLE32(head.ofsuv); head.ofstris = B_LITTLE32(head.ofstris);
head.ofsframes = B_LITTLE32(head.ofsframes); head.ofsglcmds = B_LITTLE32(head.ofsglcmds);
head.ofseof = B_LITTLE32(head.ofseof);
head.id = LittleLong(head.id); head.vers = LittleLong(head.vers);
head.skinxsiz = LittleLong(head.skinxsiz); head.skinysiz = LittleLong(head.skinysiz);
head.framebytes = LittleLong(head.framebytes); head.numskins = LittleLong(head.numskins);
head.numverts = LittleLong(head.numverts); head.numuv = LittleLong(head.numuv);
head.numtris = LittleLong(head.numtris); head.numglcmds = LittleLong(head.numglcmds);
head.numframes = LittleLong(head.numframes); head.ofsskins = LittleLong(head.ofsskins);
head.ofsuv = LittleLong(head.ofsuv); head.ofstris = LittleLong(head.ofstris);
head.ofsframes = LittleLong(head.ofsframes); head.ofsglcmds = LittleLong(head.ofsglcmds);
head.ofseof = LittleLong(head.ofseof);
#endif
if ((head.id != IDP2_MAGIC) || (head.vers != 8)) { Xfree(m); return 0; } //"IDP2"
@ -731,13 +731,13 @@ static md2model_t *md2load(FileReader & fil, const char *filnam)
{
fr = (md2frame_t *)f;
l = (int32_t *)&fr->mul;
for (j=5; j>=0; j--) l[j] = B_LITTLE32(l[j]);
for (j=5; j>=0; j--) l[j] = LittleLong(l[j]);
f += m->framebytes;
}
for (i = m->numglcmds-1; i>=0; i--)
{
m->glcmds[i] = B_LITTLE32(m->glcmds[i]);
m->glcmds[i] = LittleLong(m->glcmds[i]);
}
for (i = head.numtris-1; i>=0; i--)
{
@ -957,12 +957,12 @@ static md3model_t *md3load(FileReader & fil)
fil.Read(&m->head,SIZEOF_MD3HEAD_T);
#if B_BIG_ENDIAN != 0
m->head.id = B_LITTLE32(m->head.id); m->head.vers = B_LITTLE32(m->head.vers);
m->head.flags = B_LITTLE32(m->head.flags); m->head.numframes = B_LITTLE32(m->head.numframes);
m->head.numtags = B_LITTLE32(m->head.numtags); m->head.numsurfs = B_LITTLE32(m->head.numsurfs);
m->head.numskins = B_LITTLE32(m->head.numskins); m->head.ofsframes = B_LITTLE32(m->head.ofsframes);
m->head.ofstags = B_LITTLE32(m->head.ofstags); m->head.ofssurfs = B_LITTLE32(m->head.ofssurfs);
m->head.eof = B_LITTLE32(m->head.eof);
m->head.id = LittleLong(m->head.id); m->head.vers = LittleLong(m->head.vers);
m->head.flags = LittleLong(m->head.flags); m->head.numframes = LittleLong(m->head.numframes);
m->head.numtags = LittleLong(m->head.numtags); m->head.numsurfs = LittleLong(m->head.numsurfs);
m->head.numskins = LittleLong(m->head.numskins); m->head.ofsframes = LittleLong(m->head.ofsframes);
m->head.ofstags = LittleLong(m->head.ofstags); m->head.ofssurfs = LittleLong(m->head.ofssurfs);
m->head.eof = LittleLong(m->head.eof);
#endif
if ((m->head.id != IDP3_MAGIC) && (m->head.vers != 15)) { Xfree(m); return 0; } //"IDP3"
@ -998,13 +998,13 @@ static md3model_t *md3load(FileReader & fil)
for (i = m->head.numframes-1; i>=0; i--)
{
l = (int32_t *)&m->head.frames[i].min;
for (j=3+3+3+1-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
for (j=3+3+3+1-1; j>=0; j--) l[j] = LittleLong(l[j]);
}
for (i = m->head.numtags-1; i>=0; i--)
{
l = (int32_t *)&m->head.tags[i].p;
for (j=3+3+3+3-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
for (j=3+3+3+3-1; j>=0; j--) l[j] = LittleLong(l[j]);
}
}
#endif
@ -1019,9 +1019,9 @@ static md3model_t *md3load(FileReader & fil)
#if B_BIG_ENDIAN != 0
{
int32_t j, *l;
s->id = B_LITTLE32(s->id);
s->id = LittleLong(s->id);
l = (int32_t *)&s->flags;
for (j=1+1+1+1+1+1+1+1+1+1-1; j>=0; j--) l[j] = B_LITTLE32(l[j]);
for (j=1+1+1+1+1+1+1+1+1+1-1; j>=0; j--) l[j] = LittleLong(l[j]);
}
#endif
@ -1055,17 +1055,17 @@ static md3model_t *md3load(FileReader & fil)
for (i=s->numtris-1; i>=0; i--)
{
for (j=2; j>=0; j--) s->tris[i].i[j] = B_LITTLE32(s->tris[i].i[j]);
for (j=2; j>=0; j--) s->tris[i].i[j] = LittleLong(s->tris[i].i[j]);
}
for (i=s->numshaders-1; i>=0; i--)
{
s->shaders[i].i = B_LITTLE32(s->shaders[i].i);
s->shaders[i].i = LittleLong(s->shaders[i].i);
}
for (i=s->numverts-1; i>=0; i--)
{
l = (int32_t *)&s->uv[i].u;
l[0] = B_LITTLE32(l[0]);
l[1] = B_LITTLE32(l[1]);
l[0] = LittleLong(l[0]);
l[1] = LittleLong(l[1]);
}
for (i=s->numframes*s->numverts-1; i>=0; i--)
{
@ -1605,7 +1605,7 @@ static mdmodel_t *mdload(const char *filnam)
fil.Read(&i,4);
fil.Seek(0,FileReader::SeekSet);
switch (B_LITTLE32(i))
switch (LittleLong(i))
{
case IDP2_MAGIC:
// Printf("Warning: model \"%s\" is version IDP2; wanted version IDP3\n",filnam);

View file

@ -1846,7 +1846,7 @@ void polymost_scansector(int32_t sectnum)
int scanfirst = numscans;
vec2d_t p2 = { 0, 0 };
DVector2 p2 = { 0, 0 };
uwallptr_t wal;
@ -1854,37 +1854,37 @@ void polymost_scansector(int32_t sectnum)
{
auto const wal2 = (uwallptr_t)&wall[wal->point2];
vec2d_t const fp1 = { double(wal->x - globalposx), double(wal->y - globalposy) };
vec2d_t const fp2 = { double(wal2->x - globalposx), double(wal2->y - globalposy) };
DVector2 const fp1 = { double(wal->x - globalposx), double(wal->y - globalposy) };
DVector2 const fp2 = { double(wal2->x - globalposx), double(wal2->y - globalposy) };
int const nextsectnum = wal->nextsector; //Scan close sectors
if (nextsectnum >= 0 && !(wal->cstat&32) && sectorbordercnt < countof(sectorborder))
if ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0)
{
double const d = fp1.x*fp2.y - fp2.x*fp1.y;
vec2d_t const p1 = { fp2.x-fp1.x, fp2.y-fp1.y };
double const d = fp1.X* fp2.Y - fp2.X * fp1.Y;
DVector2 const p1 = fp2 - fp1;
// this said (SCISDIST*SCISDIST*260.f), but SCISDIST is 1 and the significance of 260 isn't obvious to me
// is 260 fudged to solve a problem, and does the problem still apply to our version of the renderer?
if (d*d < (p1.x*p1.x + p1.y*p1.y) * 256.f)
if (d*d < (p1.LengthSquared()) * 256.f)
{
sectorborder[sectorbordercnt++] = nextsectnum;
gotsector[nextsectnum>>3] |= pow2char[nextsectnum&7];
}
}
vec2d_t p1;
DVector2 p1;
if ((z == startwall) || (wall[z-1].point2 != z))
{
p1 = { (((fp1.y * fcosglobalang) - (fp1.x * fsinglobalang)) * (1.0/64.0)),
(((fp1.x * cosviewingrangeglobalang) + (fp1.y * sinviewingrangeglobalang)) * (1.0/64.0)) };
p1 = { (((fp1.Y * fcosglobalang) - (fp1.X * fsinglobalang)) * (1.0/64.0)),
(((fp1.X * cosviewingrangeglobalang) + (fp1.Y * sinviewingrangeglobalang)) * (1.0/64.0)) };
}
else { p1 = p2; }
p2 = { (((fp2.y * fcosglobalang) - (fp2.x * fsinglobalang)) * (1.0/64.0)),
(((fp2.x * cosviewingrangeglobalang) + (fp2.y * sinviewingrangeglobalang)) * (1.0/64.0)) };
p2 = { (((fp2.Y * fcosglobalang) - (fp2.X * fsinglobalang)) * (1.0/64.0)),
(((fp2.X * cosviewingrangeglobalang) + (fp2.Y * sinviewingrangeglobalang)) * (1.0/64.0)) };
if (numscans >= MAXWALLSB-1)
{
@ -1893,10 +1893,10 @@ void polymost_scansector(int32_t sectnum)
}
//if wall is facing you...
if ((p1.y >= SCISDIST || p2.y >= SCISDIST) && (nexttoward(p1.x*p2.y, p2.x*p1.y) < p2.x*p1.y))
if ((p1.Y >= SCISDIST || p2.Y >= SCISDIST) && (nexttoward(p1.X*p2.Y, p2.X*p1.Y) < p2.X*p1.Y))
{
dxb1[numscans] = (p1.y >= SCISDIST) ? float(p1.x*ghalfx/p1.y + ghalfx) : -1e32f;
dxb2[numscans] = (p2.y >= SCISDIST) ? float(p2.x*ghalfx/p2.y + ghalfx) : 1e32f;
dxb1[numscans] = (p1.Y >= SCISDIST) ? float(p1.X*ghalfx/p1.Y + ghalfx) : -1e32f;
dxb2[numscans] = (p2.Y >= SCISDIST) ? float(p2.X*ghalfx/p2.Y + ghalfx) : 1e32f;
if (dxb1[numscans] < xbl)
dxb1[numscans] = xbl;
@ -2865,10 +2865,10 @@ void polymost_drawsprite(int32_t snum)
{
int32_t const ang = getangle(wall[w].x - POINT2(w).x, wall[w].y - POINT2(w).y);
float const foffs = TSPR_OFFSET(tspr);
vec2d_t const offs = { -bsinf(ang, -6) * foffs, bcosf(ang, -6) * foffs };
DVector2 const offs = { -bsinf(ang, -6) * foffs, bcosf(ang, -6) * foffs };
vec0.x -= offs.x;
vec0.y -= offs.y;
vec0.x -= offs.X;
vec0.y -= offs.Y;
}
}

View file

@ -738,12 +738,12 @@ void F2DDrawer::AddPoly(FGameTexture *texture, FVector2 *points, int npoints,
//
//==========================================================================
void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, unsigned int* ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2)
void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, const unsigned int* ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2)
{
RenderCommand dg;
int method = 0;
if (!img->isValid()) return;
if (!img || !img->isValid()) return;
dg.mType = DrawTypeTriangles;
if (clipx1 > 0 || clipy1 > 0 || clipx2 < GetWidth() - 1 || clipy2 < GetHeight() - 1)
@ -769,14 +769,28 @@ void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, unsigne
Set(ptr, vt[i].X, vt[i].Y, 0.f, vt[i].Z, vt[i].W, color);
ptr++;
}
dg.mIndexIndex = mIndices.Size();
mIndices.Reserve(idxcount);
for (size_t i = 0; i < idxcount; i++)
if (idxcount > 0)
{
mIndices[dg.mIndexIndex + i] = ind[i] + dg.mVertIndex;
mIndices.Reserve(idxcount);
for (size_t i = 0; i < idxcount; i++)
{
mIndices[dg.mIndexIndex + i] = ind[i] + dg.mVertIndex;
}
dg.mIndexCount = (int)idxcount;
}
else
{
// If we have no index buffer, treat this as an unindexed list of triangles.
mIndices.Reserve(vtcount);
for (size_t i = 0; i < vtcount; i++)
{
mIndices[dg.mIndexIndex + i] = i + dg.mVertIndex;
}
dg.mIndexCount = (int)vtcount;
}
dg.mIndexCount = (int)idxcount;
AddCommand(&dg);
}

View file

@ -187,7 +187,7 @@ public:
void AddPoly(FGameTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double lightlevel, uint32_t *indices, size_t indexcount);
void AddPoly(FGameTexture* img, FVector4 *vt, size_t vtcount, unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2);
void AddPoly(FGameTexture* img, FVector4 *vt, size_t vtcount, const unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2);
void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex,
int clipx1, int clipy1, int clipx2, int clipy2);
void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin = false, double flatscale = 1.0, PalEntry color = 0xffffffff, ERenderStyle rs = STYLE_Normal);

View file

@ -44,6 +44,8 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
#include "v_video.h"
#include "gamestruct.h"
#include "v_draw.h"
#include "sectorgeometry.h"
#include "gamefuncs.h"
CVAR(Bool, am_followplayer, true, CVAR_ARCHIVE)
CVAR(Bool, am_rotate, true, CVAR_ARCHIVE)
@ -408,8 +410,6 @@ void drawredlines(int cposx, int cposy, int czoom, int cang)
{
int xvect = -bsin(cang) * czoom;
int yvect = -bcos(cang) * czoom;
int xvect2 = MulScale(xvect, yxaspect, 16);
int yvect2 = MulScale(yvect, yxaspect, 16);
int width = screen->GetWidth();
int height = screen->GetHeight();
@ -438,13 +438,13 @@ void drawredlines(int cposx, int cposy, int czoom, int cang)
int ox = wal->x - cposx;
int oy = wal->y - cposy;
int x1 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 11);
int y1 = DMulScale(oy, xvect2, ox, yvect2, 16) + (height << 11);
int y1 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11);
auto wal2 = &wall[wal->point2];
ox = wal2->x - cposx;
oy = wal2->y - cposy;
int x2 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 11);
int y2 = DMulScale(oy, xvect2, ox, yvect2, 16) + (height << 11);
int y2 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11);
drawlinergb(x1, y1, x2, y2, RedLineColor());
}
@ -462,8 +462,6 @@ static void drawwhitelines(int cposx, int cposy, int czoom, int cang)
{
int xvect = -bsin(cang) * czoom;
int yvect = -bcos(cang) * czoom;
int xvect2 = MulScale(xvect, yxaspect, 16);
int yvect2 = MulScale(yvect, yxaspect, 16);
int width = screen->GetWidth();
int height = screen->GetHeight();
@ -488,20 +486,25 @@ static void drawwhitelines(int cposx, int cposy, int czoom, int cang)
int ox = wal->x - cposx;
int oy = wal->y - cposy;
int x1 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 11);
int y1 = DMulScale(oy, xvect2, ox, yvect2, 16) + (height << 11);
int y1 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11);
int k = wal->point2;
auto wal2 = &wall[k];
ox = wal2->x - cposx;
oy = wal2->y - cposy;
int x2 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 11);
int y2 = DMulScale(oy, xvect2, ox, yvect2, 16) + (height << 11);
int y2 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11);
drawlinergb(x1, y1, x2, y2, WhiteLineColor());
}
}
}
//---------------------------------------------------------------------------
//
// player sprite fallback
//
//---------------------------------------------------------------------------
void DrawPlayerArrow(int cposx, int cposy, int cang, int pl_x, int pl_y, int zoom, int pl_angle)
{
@ -514,8 +517,6 @@ void DrawPlayerArrow(int cposx, int cposy, int cang, int pl_x, int pl_y, int zoo
int xvect = -bsin(cang) * zoom;
int yvect = -bcos(cang) * zoom;
int xvect2 = MulScale(xvect, yxaspect, 16);
int yvect2 = MulScale(yvect, yxaspect, 16);
int pxvect = -bsin(pl_angle);
int pyvect = -bcos(pl_angle);
@ -537,14 +538,119 @@ void DrawPlayerArrow(int cposx, int cposy, int cang, int pl_x, int pl_y, int zoo
int oy2 = py2 - cposx;
int sx1 = DMulScale(ox1, xvect, -oy1, yvect, 16) + (width << 11);
int sy1 = DMulScale(oy1, xvect2, ox1, yvect2, 16) + (height << 11);
int sy1 = DMulScale(oy1, xvect, ox1, yvect, 16) + (height << 11);
int sx2 = DMulScale(ox2, xvect, -oy2, yvect, 16) + (width << 11);
int sy2 = DMulScale(oy2, xvect2, ox2, yvect2, 16) + (height << 11);
int sy2 = DMulScale(oy2, xvect, ox2, yvect, 16) + (height << 11);
drawlinergb(sx1, sy1, sx2, sy2, WhiteLineColor());
}
}
//---------------------------------------------------------------------------
//
// floor textures
//
//---------------------------------------------------------------------------
void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
{
int xvect = -bsin(cang) * czoom;
int yvect = -bcos(cang) * czoom;
int width = screen->GetWidth();
int height = screen->GetHeight();
TArray<FVector4> vertices;
TArray<int> floorsprites;
for (int i = numsectors - 1; i >= 0; i--)
{
if (!gFullMap && !show2dsector[i] && !(g_gameType & GAMEFLAG_SW)) continue;
//Collect floor sprites to draw
SectIterator it(i);
int s;
while ((s = it.NextIndex()) >= 0)
{
if (sprite[s].cstat & CSTAT_SPRITE_INVISIBLE)
continue;
if ((sprite[s].cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR)
{
if ((sprite[s].cstat & (CSTAT_SPRITE_ONE_SIDED | CSTAT_SPRITE_YFLIP)) == (CSTAT_SPRITE_ONE_SIDED | CSTAT_SPRITE_YFLIP))
continue; // upside down
floorsprites.Push(s);
}
}
if (sector[i].floorstat & CSTAT_SECTOR_SKY) continue;
auto mesh = sectorGeometry.get(i, 0);
vertices.Resize(mesh->vertices.Size());
for (unsigned j = 0; j < mesh->vertices.Size(); j++)
{
int ox = int(mesh->vertices[j].X * 16.f) - cposx;
int oy = int(mesh->vertices[j].Y * -16.f) - cposy;
int x1 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 11);
int y1 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11);
vertices[j] = { x1 / 4096.f, y1 / 4096.f, mesh->texcoords[j].X, mesh->texcoords[j].Y };
}
int picnum = sector[i].floorpicnum;
if ((unsigned)picnum >= (unsigned)MAXTILES) continue;
int translation = TRANSLATION(Translation_Remap + curbasepal, sector[i].floorpal);
setgotpic(picnum);
twod->AddPoly(tileGetTexture(picnum, true), vertices.Data(), vertices.Size(), nullptr, 0, translation, shadeToLight(sector[i].floorshade),
LegacyRenderStyles[STYLE_Translucent], windowxy1.x, windowxy1.y, windowxy2.x + 1, windowxy2.y + 1);
}
qsort(floorsprites.Data(), floorsprites.Size(), sizeof(int), [](const void* a, const void* b)
{
int A = *(int*)a;
int B = *(int*)b;
if (sprite[A].z != sprite[B].z) return sprite[B].z - sprite[A].z;
return A - B; // ensures stable sort.
});
vertices.Resize(4);
for (auto sn : floorsprites)
{
auto spr = &sprite[sn];
vec2_t pp[4];
GetFlatSpritePosition(spr, spr->pos.vec2, pp);
for (unsigned j = 0; j < 4; j++)
{
int ox = pp[j].x - cposx;
int oy = pp[j].y - cposy;
int x1 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 11);
int y1 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11);
vertices[j] = { x1 / 4096.f, y1 / 4096.f, j == 1 || j == 2 ? 1.f : 0.f, j == 2 || j == 3 ? 1.f : 0.f };
}
int shade;
if ((sector[spr->sectnum].ceilingstat & CSTAT_SECTOR_SKY)) shade = sector[spr->sectnum].ceilingshade;
else shade = sector[spr->sectnum].floorshade;
shade += spr->shade;
PalEntry color = shadeToLight(shade);
FRenderStyle rs = LegacyRenderStyles[STYLE_Translucent];
float alpha = 1;
if (spr->cstat & CSTAT_SPRITE_TRANSLUCENT)
{
rs = GetRenderStyle(0, !!(spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
alpha = GetAlphaFromBlend((spr->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
color.a = uint8_t(alpha * 255);
}
int translation = TRANSLATION(Translation_Remap + curbasepal, spr->pal);
int picnum = spr->picnum;
setgotpic(picnum);
const static unsigned indices[] = { 0, 1, 2, 0, 2, 3 };
twod->AddPoly(tileGetTexture(picnum, true), vertices.Data(), vertices.Size(), indices, 6, translation, color, rs,
windowxy1.x, windowxy1.y, windowxy2.x + 1, windowxy2.y + 1);
}
}
//---------------------------------------------------------------------------
//
//
@ -570,7 +676,6 @@ void DrawOverheadMap(int pl_x, int pl_y, int pl_angle, double const smoothratio)
renderDrawMapView(x, y, gZoom, follow_a);
}
int32_t tmpydim = (width * 5) / 8;
renderSetAspect(65536, DivScale(tmpydim * 320, width * 200, 16));
drawredlines(x, y, gZoom, follow_a);
drawwhitelines(x, y, gZoom, follow_a);

View file

@ -200,3 +200,61 @@ void PlanesAtPoint(const sectortype* sec, float dax, float day, float* pceilz, f
if (pceilz) *pceilz = ceilz * -(1.f / 256.f);
if (pflorz) *pflorz = florz * -(1.f / 256.f);
}
//==========================================================================
//
// Calculate the position of a wall sprite in the world
//
//==========================================================================
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out)
{
int x = bsin(spr->ang) * spr->xrepeat;
int y = -bcos(spr->ang) * spr->xrepeat;
int width = tileWidth(spr->picnum);
int xoff = tileLeftOffset(spr->picnum) + spr->xoffset;
if (spr->cstat & CSTAT_SPRITE_XFLIP) xoff = -xoff;
int origin = (width >> 1) + xoff;
out[0].x = pos.x - MulScale(x, origin, 16);
out[0].y = pos.y - MulScale(y, origin, 16);
out[1].x = out[0].x + MulScale(x, width, 16);
out[1].y = out[0].y + MulScale(y, width, 16);
}
//==========================================================================
//
// Calculate the position of a wall sprite in the world
//
//==========================================================================
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out)
{
auto tex = tileGetTexture(spr->picnum);
int width = tex->GetTexelWidth() * spr->xrepeat;
int height = tex->GetTexelHeight() * spr->yrepeat;
int leftofs = (tex->GetTexelLeftOffset() + spr->xoffset) * spr->xrepeat;
int topofs = (tex->GetTexelTopOffset() + spr->yoffset) * spr->yrepeat;
if (spr->cstat & CSTAT_SPRITE_XFLIP) leftofs = -leftofs;
if (spr->cstat & CSTAT_SPRITE_YFLIP) topofs = -topofs;
int sprcenterx = (width >> 1) + leftofs;
int sprcentery = (height >> 1) + topofs;
int cosang = bcos(spr->ang);
int sinang = bsin(spr->ang);
out[0].x = pos.x + DMulScale(sinang, sprcenterx, cosang, sprcentery, 16);
out[0].y = pos.y + DMulScale(sinang, sprcentery, -cosang, sprcenterx, 16);
out[1].x = out[0].x - MulScale(sinang, width, 16);
out[1].y = out[0].y + MulScale(cosang, width, 16);
vec2_t sub = { MulScale(cosang, height, 16), MulScale(sinang, height, 16) };
out[2] = out[1] - sub;
out[3] = out[0] - sub;
}

View file

@ -10,6 +10,8 @@ bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnu
bool spriteIsModelOrVoxel(const spritetype* tspr);
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz);
void setWallSectors();
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out);
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out);
// y is negated so that the orientation is the same as in GZDoom, in order to use its utilities.
// The render code should NOT use Build coordinates for anything!

View file

@ -5,23 +5,27 @@ struct vec2_16_t
int16_t x, y;
};
#if 0
struct vec2_t
struct vec2_t
{
int32_t x, y;
vec2_t() = default;
vec2_t(const vec2_t&) = default;
vec2_t(int x_, int y_) : x(x_), y(y_) {}
vec2_t operator+(const vec2_t& other) const { return { x + other.x, y + other.y }; }
vec2_t operator-(const vec2_t& other) const { return { x - other.x, y - other.y }; }
vec2_t& operator+=(const vec2_t& other) { x += other.x; y += other.y; return *this; };
vec2_t& operator-=(const vec2_t& other) { x -= other.x; y -= other.y; return *this; };
};
#if 0
struct vec2f_t
{
float x, y;
};
struct vec2d_t
{
double x, y;
};
struct vec3_t
{
union

View file

@ -158,10 +158,8 @@ void hudDraw(PLAYER *gView, int nSectnum, double bobx, double boby, double zDelt
DoLensEffect();
viewingRange = viewingrange;
yxAspect = yxaspect;
renderSetAspect(65536, 54613);
r otatesprite(IntToFixed(280), IntToFixed(35), 53248, 512, 4077, v10, v14, 512 + 6, gViewX0, gViewY0, gViewX1, gViewY1);
r otatesprite(IntToFixed(280), IntToFixed(35), 53248, 0, 1683, v10, 0, 512 + 35, gViewX0, gViewY0, gViewX1, gViewY1);
renderSetAspect(viewingRange, yxAspect);
}
#endif
}

View file

@ -374,9 +374,6 @@ void DrawView(double smoothRatio, bool sceneonly)
}
}
renderSetAspect(viewingRange, DivScale(ydim * 8, xdim * 5, 16));
if (nFreeze)
{
nSnakeCam = -1;

View file

@ -1637,7 +1637,6 @@ drawscreen(PLAYERp pp, double smoothratio)
renderDrawMasks();
renderSetAspect(viewingRange, DivScale(ydim * 8, xdim * 5, 16));
if (!ScreenSavePic) UpdatePanel(smoothratio);
#define SLIME 2305