mirror of
https://github.com/ZDoom/Raze.git
synced 2024-12-03 01:22:19 +00:00
- temporarily reinstated rotatesprite, for easier porting of the 2D code. This will have to be removed again afterward.
This commit is contained in:
parent
23c6f4434e
commit
33f44c5627
2 changed files with 276 additions and 0 deletions
|
@ -92,6 +92,7 @@ enum {
|
|||
RS_ALIGN_MASK = 768,
|
||||
RS_STRETCH = 1024,
|
||||
|
||||
ROTATESPRITE_FULL16 = 2048,
|
||||
RS_MODELSUBST= 4096,
|
||||
// ROTATESPRITE_MAX-1 is the mask of all externally available orientation bits
|
||||
ROTATESPRITE_MAX = 8192,
|
||||
|
@ -497,9 +498,22 @@ void videoInit();
|
|||
void videoClearViewableArea(int32_t dacol);
|
||||
void videoClearScreen(int32_t dacol);
|
||||
void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang);
|
||||
void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture *pic = nullptr, int basepal = 0);
|
||||
|
||||
class F2DDrawer;
|
||||
void twod_rotatesprite(F2DDrawer* twod, int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FGameTexture* pic = nullptr, int basepal = 0);
|
||||
|
||||
////////// specialized rotatesprite wrappers for (very) often used cases //////////
|
||||
static FORCE_INLINE void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture* pic = nullptr, int basepal = 0)
|
||||
{
|
||||
rotatesprite_(sx, sy, z, a, picnum, dashade, dapalnum, dastat, 0, 0, cx1, cy1, cx2, cy2, pic, basepal);
|
||||
}
|
||||
|
||||
void getzrange(const vec3_t *pos, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz,
|
||||
int32_t *florhit, int32_t walldist, uint32_t cliptype) ATTRIBUTE((nonnull(1,3,4,5,6)));
|
||||
|
|
|
@ -1660,6 +1660,268 @@ void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int
|
|||
#include "build.h"
|
||||
#include "../src/engine_priv.h"
|
||||
|
||||
//sx,sy center of sprite; screen coords*65536
|
||||
//z zoom*65536. > is zoomed in
|
||||
//a angle (0 is default)
|
||||
//dastat&1 1:translucence
|
||||
//dastat&2 1:auto-scale mode (use 320*200 coordinates)
|
||||
//dastat&4 1:y-flip
|
||||
//dastat&8 1:don't clip to startumost/startdmost
|
||||
//dastat&16 1:force point passed to be top-left corner, 0:Editart center
|
||||
//dastat&32 1:reverse translucence
|
||||
//dastat&64 1:non-masked, 0:masked
|
||||
//dastat&128 1:draw all pages (permanent - no longer used)
|
||||
//cx1,... clip window (actual screen coords)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// INTERNAL helper function for classic/polymost dorotatesprite
|
||||
// sxptr, sxptr, z: in/out
|
||||
// ret_yxaspect, ret_xyaspect: out
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int32_t dorotspr_handle_bit2(int32_t* sxptr, int32_t* syptr, int32_t* z, int32_t dastat, int32_t cx1_plus_cx2, int32_t cy1_plus_cy2)
|
||||
{
|
||||
if ((dastat & RS_AUTO) == 0)
|
||||
{
|
||||
if (!(dastat & RS_STRETCH) && 4 * ydim <= 3 * xdim)
|
||||
{
|
||||
return (10 << 16) / 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
return xyaspect;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// dastat&2: Auto window size scaling
|
||||
const int32_t oxdim = xdim;
|
||||
const int32_t oydim = ydim;
|
||||
int32_t xdim = oxdim; // SHADOWS global
|
||||
int32_t ydim = oydim;
|
||||
|
||||
int32_t zoomsc, sx = *sxptr, sy = *syptr;
|
||||
int32_t ouryxaspect = yxaspect, ourxyaspect = xyaspect;
|
||||
|
||||
if (!(dastat & RS_STRETCH) && 4 * ydim <= 3 * xdim)
|
||||
{
|
||||
if ((dastat & RS_ALIGN_MASK) && (dastat & RS_ALIGN_MASK) != RS_ALIGN_MASK)
|
||||
sx += (scale(120 << 16, xdim, ydim) - (160 << 16)) * ((!(dastat & RS_ALIGN_R))?-1:1);
|
||||
|
||||
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
|
||||
ydim = scale(xdim, 3, 4);
|
||||
else
|
||||
xdim = scale(ydim, 4, 3);
|
||||
|
||||
ouryxaspect = (12 << 16) / 10;
|
||||
ourxyaspect = (10 << 16) / 12;
|
||||
}
|
||||
|
||||
// screen center to s[xy], 320<<16 coords.
|
||||
const int32_t normxofs = sx - (320 << 15), normyofs = sy - (200 << 15);
|
||||
|
||||
// nasty hacks go here
|
||||
if (!(dastat & RS_NOCLIP))
|
||||
{
|
||||
const int32_t twice_midcx = cx1_plus_cx2 + 2;
|
||||
|
||||
// screen x center to sx1, scaled to viewport
|
||||
const int32_t scaledxofs = scale(normxofs, scale(xdimen, xdim, oxdim), 320);
|
||||
|
||||
sx = ((twice_midcx) << 15) + scaledxofs;
|
||||
|
||||
zoomsc = xdimenscale; //= scale(xdimen,yxaspect,320);
|
||||
|
||||
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
|
||||
zoomsc = scale(zoomsc, ydim, oydim);
|
||||
|
||||
sy = ((cy1_plus_cy2 + 2) << 15) + mulscale16(normyofs, zoomsc);
|
||||
}
|
||||
else
|
||||
{
|
||||
//If not clipping to startmosts, & auto-scaling on, as a
|
||||
//hard-coded bonus, scale to full screen instead
|
||||
|
||||
sx = (xdim << 15) + 32768 + scale(normxofs, xdim, 320);
|
||||
|
||||
zoomsc = scale(xdim, ouryxaspect, 320);
|
||||
sy = (ydim << 15) + 32768 + mulscale16(normyofs, zoomsc);
|
||||
|
||||
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
|
||||
sy += (oydim - ydim) << 15;
|
||||
else
|
||||
sx += (oxdim - xdim) << 15;
|
||||
|
||||
if (dastat & RS_CENTERORIGIN)
|
||||
sx += oxdim << 15;
|
||||
}
|
||||
|
||||
*sxptr = sx;
|
||||
*syptr = sy;
|
||||
*z = mulscale16(*z, zoomsc);
|
||||
|
||||
return ourxyaspect;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void twod_rotatesprite(F2DDrawer *twod, int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FGameTexture* pic, int basepal)
|
||||
{
|
||||
// todo: re-add
|
||||
#if 0
|
||||
if (!tex && (dastat & RS_MODELSUBST))
|
||||
{
|
||||
tileUpdatePicnum(&picnum, (int16_t)0xc000);
|
||||
if ((tileWidth(picnum) <= 0) || (tileHeight(picnum) <= 0)) return;
|
||||
if (hw_models && tile2model[picnum].hudmem[(dastat & 4) >> 2])
|
||||
{
|
||||
polymost_dorotatespritemodel(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, guniqhudid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!pic) tileUpdatePicnum(&picnum, 0);
|
||||
|
||||
|
||||
|
||||
F2DDrawer::RenderCommand dg = {};
|
||||
int method = 0;
|
||||
|
||||
dg.mType = F2DDrawer::DrawTypeTriangles;
|
||||
if (clipx1 > 0 || clipy1 > 0 || clipx2 < screen->GetWidth() - 1 || clipy2 < screen->GetHeight() - 1)
|
||||
{
|
||||
dg.mScissor[0] = clipx1;
|
||||
dg.mScissor[1] = clipy1;
|
||||
dg.mScissor[2] = clipx2 + 1;
|
||||
dg.mScissor[3] = clipy2 + 1;
|
||||
dg.mFlags |= F2DDrawer::DTF_Scissor;
|
||||
}
|
||||
|
||||
if (!(dastat & RS_NOMASK))
|
||||
{
|
||||
if (dastat & RS_TRANS1)
|
||||
method |= (dastat & RS_TRANS2) ? DAMETH_TRANS2 : DAMETH_TRANS1;
|
||||
else
|
||||
method |= DAMETH_MASK;
|
||||
|
||||
dg.mRenderStyle = GetRenderStyle(dablend, (dastat & RS_TRANS2) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dg.mRenderStyle = LegacyRenderStyles[STYLE_Normal];
|
||||
}
|
||||
|
||||
dg.mTexture = pic ? pic : tileGetTexture(picnum);
|
||||
if (!dg.mTexture || !dg.mTexture->isValid()) return; // empty tile.
|
||||
|
||||
// todo: check for hires replacements.
|
||||
|
||||
// The weapon drawer needs to use the global base palette.
|
||||
dg.mTranslationId = TRANSLATION(Translation_Remap + basepal, dapalnum);
|
||||
|
||||
dg.mVertCount = 4;
|
||||
dg.mVertIndex = (int)twod->mVertices.Reserve(4);
|
||||
auto ptr = &twod->mVertices[dg.mVertIndex];
|
||||
float drawpoly_alpha = daalpha * (1.0f / 255.0f);
|
||||
float alpha = GetAlphaFromBlend(method, dablend) * (1.f - drawpoly_alpha); // Hmmm...
|
||||
PalEntry p;
|
||||
|
||||
if (!hw_useindexedcolortextures)
|
||||
{
|
||||
int light = clamp(scale((numshades - dashade), 255, numshades), 0, 255);
|
||||
p = PalEntry((uint8_t)(alpha * 255), light, light, light);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = PalEntry((uint8_t)(alpha * 255), 255, 255, 255);
|
||||
dg.mLightLevel = clamp(dashade, 0, numshades);
|
||||
}
|
||||
|
||||
|
||||
vec2_t const siz = { (int)dg.mTexture->GetDisplayWidth(), (int)dg.mTexture->GetDisplayHeight() };
|
||||
vec2_16_t ofs = { 0, 0 };
|
||||
|
||||
if (!(dastat & RS_TOPLEFT))
|
||||
{
|
||||
if (!pic && !(dastat & RS_CENTER))
|
||||
{
|
||||
ofs = { int16_t(tileLeftOffset(picnum) + (siz.x >> 1)),
|
||||
int16_t(tileTopOffset(picnum) + (siz.y >> 1)) };
|
||||
}
|
||||
else
|
||||
{
|
||||
ofs = { int16_t((siz.x >> 1)),
|
||||
int16_t((siz.y >> 1)) };
|
||||
}
|
||||
}
|
||||
|
||||
if (dastat & RS_YFLIP)
|
||||
ofs.y = siz.y - ofs.y;
|
||||
|
||||
int32_t aspectcorrect = dorotspr_handle_bit2(&sx, &sy, &z, dastat, clipx1 + clipx2, clipy1 + clipy2);
|
||||
|
||||
int32_t cosang = mulscale14(sintable[(a + 512) & 2047], z);
|
||||
int32_t cosang2 = cosang;
|
||||
int32_t sinang = mulscale14(sintable[a & 2047], z);
|
||||
int32_t sinang2 = sinang;
|
||||
|
||||
if ((dastat & RS_AUTO) || (!(dastat & RS_NOCLIP))) // Don't aspect unscaled perms
|
||||
{
|
||||
cosang2 = mulscale16(cosang2, aspectcorrect);
|
||||
sinang2 = mulscale16(sinang2, aspectcorrect);
|
||||
}
|
||||
|
||||
int cx0 = sx - ofs.x * cosang2 + ofs.y * sinang2;
|
||||
int cy0 = sy - ofs.x * sinang - ofs.y * cosang;
|
||||
|
||||
int cx1 = cx0 + siz.x * cosang2;
|
||||
int cy1 = cy0 + siz.x * sinang;
|
||||
|
||||
int cx3 = cx0 - siz.y * sinang2;
|
||||
int cy3 = cy0 + siz.y * cosang;
|
||||
|
||||
int cx2 = cx1 + cx3 - cx0;
|
||||
int cy2 = cy1 + cy3 - cy0;
|
||||
|
||||
float y = (dastat & RS_YFLIP) ? 1.f : 0.f;
|
||||
|
||||
ptr->Set(cx0 / 65536.f, cy0 / 65536.f, 0.f, 0.f, y, p); ptr++;
|
||||
ptr->Set(cx1 / 65536.f, cy1 / 65536.f, 0.f, 1.f, y, p); ptr++;
|
||||
ptr->Set(cx2 / 65536.f, cy2 / 65536.f, 0.f, 1.f, 1.f - y, p); ptr++;
|
||||
ptr->Set(cx3 / 65536.f, cy3 / 65536.f, 0.f, 0.f, 1.f - y, p); ptr++;
|
||||
dg.mIndexIndex = twod->mIndices.Size();
|
||||
dg.mIndexCount += 6;
|
||||
twod->AddIndices(dg.mVertIndex, 6, 0, 1, 2, 0, 2, 3);
|
||||
twod->AddCommand(&dg);
|
||||
|
||||
}
|
||||
|
||||
void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
|
||||
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
|
||||
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FGameTexture* tex, int basepal)
|
||||
{
|
||||
if (!tex && (unsigned)picnum >= MAXTILES)
|
||||
return;
|
||||
|
||||
if ((cx1 > cx2) || (cy1 > cy2)) return;
|
||||
if (z <= 16) return;
|
||||
|
||||
// We must store all calls in the 2D drawer so that the backend can operate on a clean 3D view.
|
||||
twod_rotatesprite(twod, sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, cx1, cy1, cx2, cy2, tex, basepal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// fillpolygon (internal)
|
||||
|
|
Loading…
Reference in a new issue