- fully floatified GetFlatSpritePosition

This commit is contained in:
Christoph Oelckers 2022-08-17 20:40:11 +02:00
parent b9ea355e2e
commit c712d594e0
4 changed files with 42 additions and 40 deletions

View file

@ -616,13 +616,13 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
for (auto actor : floorsprites)
{
if (!gFullMap && !(actor->spr.cstat2 & CSTAT2_SPRITE_MAPPED)) continue;
vec2_t pp[4];
GetFlatSpritePosition(actor, actor->int_pos().vec2, pp, true);
DVector2 pp[4];
GetFlatSpritePosition(actor, actor->spr.pos.XY(), pp, true);
for (unsigned j = 0; j < 4; j++)
{
int ox = pp[j].X - cposx;
int oy = pp[j].Y - cposy;
int ox = int(pp[j].X * worldtoint) - cposx;
int oy = int(pp[j].Y * worldtoint) - 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 };

View file

@ -323,49 +323,51 @@ void GetWallSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool
//
//==========================================================================
void TGetFlatSpritePosition(const spritetypebase* spr, vec2_t pos, vec2_t* out, int* outz, int heinum, bool render)
void TGetFlatSpritePosition(const spritetypebase* spr, const DVector2& pos, DVector2* out, double* outz, int heinum, bool render)
{
auto tex = tileGetTexture(spr->picnum);
int width, height, leftofs, topofs;
int ratio = ksqrt(heinum * heinum + 4096 * 4096);
double width, height, leftofs, topofs;
double sloperatio = sqrt(heinum * heinum + 4096 * 4096) * (1. / 4096.);
double xrepeat = spr->xrepeat * (1. / 64.);
double yrepeat = spr->yrepeat * (1. / 64.);
int xo = heinum ? 0 : spr->xoffset;
int yo = heinum ? 0 : spr->yoffset;
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].hiofs.xsize)
{
width = TileFiles.tiledata[spr->picnum].hiofs.xsize * spr->xrepeat;
height = TileFiles.tiledata[spr->picnum].hiofs.ysize * spr->yrepeat;
leftofs = (TileFiles.tiledata[spr->picnum].hiofs.xoffs + xo) * spr->xrepeat;
topofs = (TileFiles.tiledata[spr->picnum].hiofs.yoffs + yo) * spr->yrepeat;
width = TileFiles.tiledata[spr->picnum].hiofs.xsize * xrepeat;
height = TileFiles.tiledata[spr->picnum].hiofs.ysize * yrepeat;
leftofs = (TileFiles.tiledata[spr->picnum].hiofs.xoffs + xo) * xrepeat;
topofs = (TileFiles.tiledata[spr->picnum].hiofs.yoffs + yo) * yrepeat;
}
else
{
width = (int)tex->GetDisplayWidth() * spr->xrepeat;
height = (int)tex->GetDisplayHeight() * spr->yrepeat;
leftofs = ((int)tex->GetDisplayLeftOffset() + xo) * spr->xrepeat;
topofs = ((int)tex->GetDisplayTopOffset() + yo) * spr->yrepeat;
width = (int)tex->GetDisplayWidth() * xrepeat;
height = (int)tex->GetDisplayHeight() * yrepeat;
leftofs = ((int)tex->GetDisplayLeftOffset() + xo) * xrepeat;
topofs = ((int)tex->GetDisplayTopOffset() + yo) * 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;
double sprcenterx = (width * 0.5) + leftofs;
double sprcentery = (height * 0.5) + topofs;
int cosang = bcos(spr->int_ang());
int sinang = bsin(spr->int_ang());
int cosangslope = DivScale(cosang, ratio, 12);
int sinangslope = DivScale(sinang, ratio, 12);
double cosang = spr->angle.Cos();
double sinang = spr->angle.Sin();
double cosangslope = cosang / sloperatio;
double sinangslope = sinang / sloperatio;
out[0].X = pos.X + DMulScale(sinang, sprcenterx, cosangslope, sprcentery, 16);
out[0].Y = pos.Y + DMulScale(sinangslope, sprcentery, -cosang, sprcenterx, 16);
out[0].X = pos.X + sinang * sprcenterx + cosangslope * sprcentery;
out[0].Y = pos.Y + sinangslope * sprcentery - cosang * sprcenterx;
out[1].X = out[0].X - MulScale(sinang, width, 16);
out[1].Y = out[0].Y + MulScale(cosang, width, 16);
out[1].X = out[0].X - sinang * width;
out[1].Y = out[0].Y + cosang * width;
vec2_t sub = { MulScale(cosangslope, height, 16), MulScale(sinangslope, height, 16) };
DVector2 sub = { cosangslope * height, sinangslope * height };
out[2] = out[1] - sub;
out[3] = out[0] - sub;
if (outz)
@ -375,19 +377,19 @@ void TGetFlatSpritePosition(const spritetypebase* spr, vec2_t pos, vec2_t* out,
{
for (int i = 0; i < 4; i++)
{
int spos = DMulScale(-sinang, out[i].Y - pos.Y, -cosang, out[i].X - pos.X, 4);
outz[i] = MulScale(heinum, spos, 18);
outz[i] = (sinang * (out[i].Y - pos.Y) + cosang * (out[i].X - pos.X)) * heinum * (1. / 4096);
}
}
}
}
void GetFlatSpritePosition(DCoreActor* actor, vec2_t pos, vec2_t* out, bool render)
void GetFlatSpritePosition(DCoreActor* actor, const DVector2& pos, DVector2* out, bool render)
{
TGetFlatSpritePosition(&actor->spr, pos, out, nullptr, spriteGetSlope(actor), render);
}
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, int* outz, bool render)
void GetFlatSpritePosition(const tspritetype* spr, const DVector2& pos, DVector2* out, double* outz, bool render)
{
TGetFlatSpritePosition(spr, pos, out, outz, tspriteGetSlope(spr), render);
}

View file

@ -266,8 +266,8 @@ int getslopeval(sectortype* sect, int x, int y, int z, int planez);
void setWallSectors();
void GetWallSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
void GetFlatSpritePosition(DCoreActor* spr, vec2_t pos, vec2_t* out, bool render = false);
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, int* outz = nullptr, bool render = false);
void GetFlatSpritePosition(DCoreActor* spr, const DVector2& pos, DVector2* out, bool render = false);
void GetFlatSpritePosition(const tspritetype* spr, const DVector2& pos, DVector2* out, double* outz, bool render = false);
void checkRotatedWalls();
bool sectorsConnected(int sect1, int sect2);
void dragpoint(walltype* wal, int newx, int newy);

View file

@ -120,11 +120,11 @@ void HWFlat::MakeVertices(HWDrawInfo* di)
}
else
{
vec2_t pos[4];
int ofsz[4];
DVector2 pos[4];
double ofsz[4];
auto cstat = Sprite->cstat;
if (tspriteGetSlope(Sprite)) cstat &= ~CSTAT_SPRITE_YFLIP; // NBlood doesn't y-flip slope sprites.
GetFlatSpritePosition(Sprite, Sprite->int_pos().vec2, pos, ofsz, true);
GetFlatSpritePosition(Sprite, Sprite->pos.XY(), pos, ofsz, true);
Sprite->cstat = cstat;
auto ret = screen->mVertexData->AllocVertices(6);
@ -144,8 +144,8 @@ void HWFlat::MakeVertices(HWDrawInfo* di)
float maxofs = -FLT_MAX, minofs = FLT_MAX;
for (int i = 0; i < 4; i++)
{
float vz = getceilzofslopeptr(Sprite->sectp, pos[i].X, pos[i].Y) * (1 / -256.f);
float sz = z + ofsz[i] * (1 / -256.f);
float vz = -getceilzofslopeptrf(Sprite->sectp, pos[i].X, pos[i].Y);
float sz = z - ofsz[i];
int diff = vz - sz;
if (diff > maxofs) maxofs = diff;
if (diff < minofs) minofs = diff;
@ -157,8 +157,8 @@ void HWFlat::MakeVertices(HWDrawInfo* di)
float maxofs = -FLT_MAX, minofs = FLT_MAX;
for (int i = 0; i < 4; i++)
{
float vz = getflorzofslopeptr(Sprite->sectp, pos[i].X, pos[i].Y) * (1 / -256.f);
float sz = z + ofsz[i] * (1 / -256.f);
float vz = -getflorzofslopeptrf(Sprite->sectp, pos[i].X, pos[i].Y);
float sz = z - ofsz[i];
int diff = vz - sz;
if (diff > maxofs) maxofs = diff;
if (diff < minofs) minofs = diff;
@ -181,7 +181,7 @@ void HWFlat::MakeVertices(HWDrawInfo* di)
for (unsigned j = 0; j < 4; j++)
{
svp->SetVertex(pos[j].X * (1 / 16.f), z + ofsz[j] * (1 / -256.f), pos[j].Y * (1 / -16.f));
svp->SetVertex(pos[j].X, z - ofsz[j], -pos[j].Y);
if (!canvas) svp->SetTexCoord(j == 1 || j == 2 ? 1.f - x : x, j == 2 || j == 3 ? 1.f - y : y);
else svp->SetTexCoord(j == 1 || j == 2 ? 1.f - x : x, j == 2 || j == 3 ? y : 1.f - y);
svp++;