Draw area system works, need to fix alignment

This commit is contained in:
yamamama 2026-02-22 15:06:11 -05:00
parent 3c961033ca
commit b86e3416e5
6 changed files with 99 additions and 50 deletions

View file

@ -884,6 +884,14 @@ void P_Ticker(boolean run)
{
leveltime++;
#ifdef AFFINEROT_TESTER
if (cv_affinerottest.value == 2)
{
fixed_t newaffineangle = (cv_affineangle.value + (FRACUNIT)) % (360 * FRACUNIT);
CV_StealthSet(&cv_affineangle, va("%f", FIXED_TO_FLOAT(newaffineangle)));
}
#endif
if (starttime > introtime && leveltime == starttime)
{
ACS_RunRaceStartScript();

View file

@ -21,6 +21,7 @@
// a has a constant z depth from top to bottom.
//
#include "r_main.h"
#include "r_draw.h"
#include <tracy/tracy/Tracy.hpp>
@ -546,29 +547,29 @@ void R_DrawAffineColumn(drawcolumndata_t *dc)
const fixed_t b = transform->b;
const fixed_t c = transform->c;
const fixed_t d = transform->d;
fixed_t cx = (bounds->xlen * FRACHALF); //transform->ox;
fixed_t cy = (bounds->ylen * FRACHALF); //transform->oy;
fixed_t cx = transform->ox;
fixed_t cy = transform->oy;
const INT32 pw = dc->sourcelength, ph = dc->texheight;
INT32 ydiff = (bounds->yup - (transform->oy >> FRACBITS));
INT32 xdiff = (bounds->xleft - (transform->ox >> FRACBITS));
fixed_t ydiff = (bounds->yup * FRACUNIT) - cy;
fixed_t xdiff = (bounds->xleft * FRACUNIT) - cx;
vector2_t centering;
centering.x = (bounds->xlen * FRACHALF);
centering.y = (bounds->ylen * FRACHALF);
xdiff -= (xdiff ? FRACUNIT : 0);
ydiff -= (ydiff ? FRACUNIT : 0);
// Offset our X and Y positions by the bounding differences.
fixed_t cxx = (xdiff * FRACUNIT);
fixed_t cyy = 0; //+ (ydiff * FRACUNIT);
fixed_t cxx = cx + xdiff;
fixed_t cyy = cy + ydiff;
//I_OutputMsg("xdiff: %f, ydiff: %f\n", FIXED_TO_FLOAT(xdiff), FIXED_TO_FLOAT(ydiff));
// yoinked from NovaSquirrel's mode 7 0preview
// ...which is in turn yoinked from Mesen's S-PPU code
// i can't do matrix math to save my life :face_holding_back_tears:
// (m7xofs and m7yofs are already factored in by destbase)
fixed_t ux = FixedMul(b, -cxx) + FixedMul(a, -cyy) + FixedMul(a, dc->frac);// + cx;
fixed_t uy = FixedMul(d, -cxx) + FixedMul(c, -cyy) + FixedMul(c, dc->frac) + cy;
fixed_t ux = FixedMul(b, -cyy) + FixedMul(a, -cxx) + FixedMul(a, dc->frac) + cx;
fixed_t uy = FixedMul(d, -cyy) + FixedMul(c, -cxx) + FixedMul(c, dc->frac) + cy;
for (; count > 0; dest += stride, --count)
{

View file

@ -197,6 +197,14 @@ consvar_t cv_sliptidetilt = CVAR_INIT ("sliptidetilt", "On", CV_SAVE, CV_OnOff,
consvar_t cv_nulldriftefx = CVAR_INIT ("nulldriftefx", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_nulldrifttilt = CVAR_INIT ("nulldrifttilt", "On", CV_SAVE, CV_OnOff, NULL);
static CV_PossibleValue_t affineangle_cons_t[] = {{0, "MIN"}, {360 * FRACUNIT, "MAX"}, {0, NULL}};
static CV_PossibleValue_t affinetest_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Auto"}, {0, NULL}};
#ifdef AFFINEROT_TESTER
consvar_t cv_affineangle = CVAR_INIT ("affineangle", "0", CV_FLOAT, affineangle_cons_t, NULL);
consvar_t cv_affinerottest = CVAR_INIT ("affinerottest", "Off", CV_FLOAT, affinetest_cons_t, NULL);
#endif
void SplitScreen_OnChange(void)
{
UINT8 i;
@ -1812,6 +1820,11 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_playerfade);
#ifdef AFFINEROT_TESTER
CV_RegisterVar(&cv_affineangle);
CV_RegisterVar(&cv_affinerottest);
#endif
CV_RegisterVar(&cv_movebob);
// Frame interpolation/uncapped

View file

@ -161,6 +161,10 @@ extern consvar_t cv_sloperoll;
extern consvar_t cv_sliptidetilt;
extern consvar_t cv_nulldriftefx, cv_nulldrifttilt;
#ifdef AFFINEROT_TESTER
extern consvar_t cv_affineangle, cv_affinerottest;
#endif
// debugging
typedef enum {

View file

@ -986,6 +986,8 @@ static void R_DrawVisSprite(vissprite_t *vis)
drawcolumndata_t dc {0};
const INT32 vidwidth = vid.width;
fixed_t maxpatchwidth = (patch->width << FRACBITS);
if (!patch)
return;
@ -1001,10 +1003,16 @@ static void R_DrawVisSprite(vissprite_t *vis)
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
}
if (vis->cut & SC_AFFINE)
{
// Resize the max horizontal bounds so we can draw the whole affine patch.
maxpatchwidth = std::max(maxpatchwidth, vis->affine.bounds.xlen * FRACUNIT);
}
// TODO This check should not be necessary. But Papersprites near to the camera will sometimes create invalid values
// for the vissprite's startfrac. This happens because they are not depth culled like other sprites.
// Someone who is more familiar with papersprites pls check and try to fix <3
if (vis->startfrac < 0 || vis->startfrac > (patch->width << FRACBITS))
if (vis->startfrac < 0 || vis->startfrac > maxpatchwidth)
{
// never draw vissprites with startfrac out of patch range
return;
@ -1104,9 +1112,11 @@ static void R_DrawVisSprite(vissprite_t *vis)
spryscale = vis->scale;
fixed_t ymovescale = (vis->cut & SC_AFFINE) ? vis->affine.scaling.y : spryscale;
if (!(vis->scalestep))
{
sprtopscreen = centeryfrac - FixedMul(dc.texturemid, spryscale);
sprtopscreen = centeryfrac - FixedMul(dc.texturemid, ymovescale);
sprtopscreen += vis->shear.tan * vis->shear.offset;
dc.iscale = FixedDiv(FRACUNIT, vis->scale);
}
@ -1970,11 +1980,11 @@ static void R_ProjectSprite(mobj_t *thing)
if (affinesprite)
{
xscale = FRACUNIT;
sortscale = FRACUNIT;
affine_scale.x = FixedDiv(projection[viewssnum], tz);
affine_scale.y = FixedDiv(projectiony[viewssnum], tz);
xscale = FRACUNIT;
sortscale = affine_scale.y;
}
else
{
@ -2180,6 +2190,44 @@ static void R_ProjectSprite(mobj_t *thing)
}
#endif
if (affinesprite)
{
affine_scale.x = FixedMul(affine_scale.x, FixedMul(spritexscale, this_scale));
affine_scale.y = FixedMul(affine_scale.y, FixedMul(spriteyscale, this_scale));
angle_t angle;
INT32 flipsign = ((flip) ? -1 : 1);
#ifdef AFFINEROT_TESTER
if (!cv_affinerottest.value)
angle = spriterotangle * flipsign;
else
angle = FixedAngle(cv_affineangle.value);
#else
angle = spriterotangle * flipsign;
#endif
fixed_t sa = FSIN(angle), ca = FCOS(angle);
affine_transform.a = FixedDiv(ca, affine_scale.x);
affine_transform.b = FixedDiv(-sa, affine_scale.x);
affine_transform.c = FixedDiv(sa, affine_scale.y);
affine_transform.d = FixedDiv(ca, affine_scale.y);
affine_transform.ox = (patch->pivot.x + patch->leftoffset) * FRACUNIT;
affine_transform.oy = (patch->pivot.y + patch->topoffset) * FRACUNIT;
V_GetAffineBounds(&affine_transform, patch, FRACUNIT, &affine_bounds);
spr_width = (affine_bounds.xlen * FRACUNIT);
spr_offset = (affine_bounds.xleft * FRACUNIT);
//spr_height = (affine_bounds.ylen * FRACUNIT);
//spr_topoffset = (affine_bounds.yup * FRACUNIT);
spritexscale = FRACUNIT;
spriteyscale = FRACUNIT;
}
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
{
spr_offset = FixedDiv(interp.spritexoffset, highresscale);
@ -2221,37 +2269,8 @@ static void R_ProjectSprite(mobj_t *thing)
}
#endif
if (affinesprite)
{
affine_scale.x = FixedMul(affine_scale.x, FixedMul(spritexscale, this_scale));
angle_t angle = spriterotangle; //leveltime*ANG2;
fixed_t sa = FSIN(angle), ca = FCOS(angle);
affine_transform.a = FixedDiv(ca, FRACUNIT);
affine_transform.b = FixedDiv(-sa, FRACUNIT);
affine_transform.c = FixedDiv(sa, FRACUNIT);
affine_transform.d = FixedDiv(ca, FRACUNIT);
affine_transform.ox = (patch->pivot.x + patch->leftoffset) * FRACUNIT;
affine_transform.oy = (patch->pivot.y + patch->topoffset) * FRACUNIT;
V_GetAffineBounds(&affine_transform, patch, FRACUNIT, &affine_bounds);
spr_width = (affine_bounds.xlen * FRACUNIT);
spr_height = (affine_bounds.ylen * FRACUNIT);
INT32 xdiff = (affine_bounds.xleft - (affine_transform.ox >> FRACBITS));
offset -= (xdiff * FRACUNIT);
offset2 = spr_width;
spritexscale = FRACUNIT;
spriteyscale = FRACUNIT;
}
else
{
offset = FixedMul(offset, FixedMul(spritexscale, this_scale));
offset2 = FixedMul(spr_width, FixedMul(spritexscale, this_scale));
}
offset = FixedMul(offset, FixedMul(spritexscale, this_scale));
offset2 = FixedMul(spr_width, FixedMul(spritexscale, this_scale));
if (papersprite)
{
@ -2356,7 +2375,7 @@ static void R_ProjectSprite(mobj_t *thing)
else
{
scalestep = 0;
yscale = sortscale;
yscale = (affinesprite) ? FRACUNIT : sortscale;
tx += offset;
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
@ -2677,6 +2696,8 @@ static void R_ProjectSprite(mobj_t *thing)
if (affinesprite)
{
vis->affine.scaling.x = affine_scale.x;
vis->affine.scaling.y = affine_scale.y;
vis->affine.rollangle = spriterotangle;
vis->affine.transform.a = affine_transform.a;
@ -2708,7 +2729,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->xscale = FixedMul(spritexscale, xscale); //SoM: 4/17/2000
vis->scale = FixedMul(spriteyscale, yscale); //<<detailshift;
vis->thingscale = this_scale;
vis->thingscale = (affinesprite) ? FRACUNIT : this_scale;
vis->spritexscale = spritexscale;
vis->spriteyscale = spriteyscale;

View file

@ -186,6 +186,7 @@ struct vissprite_t
fixed_t startfrac; // horizontal position of x1
fixed_t xscale, scale; // projected horizontal and vertical scales
fixed_t ypush_scale; // Scale for downwards Y movement. Likely only relevant for affines.
fixed_t thingscale; // the object's scale
fixed_t sortscale; // sortscale only differs from scale for paper sprites and floor sprites
fixed_t sortsplat; // the sortscale from behind the floor sprite
@ -208,6 +209,7 @@ struct vissprite_t
} shear;
struct {
vector2_t scaling; // Affine scaling
angle_t rollangle; // Affine rotation angle
affine_t transform; // The actual affine transformation.
affine_bounding_t bounds; // The "bounding box" (draw area) of the affine sprite.