Add an option for mosaic affine rendering
Currently software only; would require a shader or more "involved" solution for OpenGL
This commit is contained in:
parent
cb578f423d
commit
951c43d1e8
9 changed files with 58 additions and 11 deletions
|
|
@ -43,12 +43,6 @@ typedef struct
|
|||
float z;
|
||||
} polyvertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
} f_vector2_t;
|
||||
|
||||
// a convex 'plane' polygon, clockwise order
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
|||
|
|
@ -351,6 +351,13 @@ struct vector2_t
|
|||
fixed_t y;
|
||||
};
|
||||
|
||||
// Floating-point version, used sparingly, primarily in rendering
|
||||
struct f_vector2_t
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y);
|
||||
vector2_t *FV2_UnLoad(vector2_t *vec, fixed_t *x, fixed_t *y);
|
||||
vector2_t *FV2_Copy(vector2_t *a_o, const vector2_t *a_i);
|
||||
|
|
|
|||
|
|
@ -1168,6 +1168,7 @@ typedef struct
|
|||
affine_t affine;
|
||||
vector2_t affineoffset;
|
||||
fixed_t affineystep;
|
||||
f_vector2_t affinemosaic; // Truncates how columndrawers "move" across the screen
|
||||
fixed_t frac;
|
||||
} drawcolumndata_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -635,19 +635,50 @@ static void R_DrawAffineColumnTemplate(drawcolumndata_t *dc)
|
|||
|
||||
//I_OutputMsg("xdiff: %f, ydiff: %f\n", FIXED_TO_FLOAT(xdiff), FIXED_TO_FLOAT(ydiff));
|
||||
|
||||
// If we're smaller than usual, mosaic isn't necessary.
|
||||
|
||||
const float y_mosaic = std::max(1.0f, dc->affinemosaic.y);
|
||||
const float x_mosaic = std::max(1.0f, dc->affinemosaic.x);
|
||||
|
||||
const boolean mosaic_on = cv_affinemosaic.value;
|
||||
const boolean xmosaic_on = (FLOAT_TO_FIXED(x_mosaic) > FRACUNIT);
|
||||
const boolean ymosaic_on = (FLOAT_TO_FIXED(y_mosaic) > FRACUNIT);
|
||||
|
||||
fixed_t usefrac = dc->frac;
|
||||
|
||||
if (mosaic_on && xmosaic_on)
|
||||
{
|
||||
usefrac = FLOAT_TO_FIXED(static_cast<INT32>(FIXED_TO_FLOAT(dc->frac) / x_mosaic) * x_mosaic);
|
||||
}
|
||||
|
||||
float ypx = 0.0f;
|
||||
|
||||
// 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, -cyy) + FixedMul(a, -cxx) + FixedMul(a, dc->frac) + cx;
|
||||
fixed_t uy = FixedMul(d, -cyy) + FixedMul(c, -cxx) + FixedMul(c, dc->frac) + cy;
|
||||
fixed_t ux = FixedMul(b, -cyy) + FixedMul(a, -cxx) + FixedMul(a, usefrac) + cx;
|
||||
fixed_t uy = FixedMul(d, -cyy) + FixedMul(c, -cxx) + FixedMul(c, usefrac) + cy;
|
||||
float ux_base = FIXED_TO_FLOAT(ux);
|
||||
float uy_base = FIXED_TO_FLOAT(uy);
|
||||
float f_b = FIXED_TO_FLOAT(FixedMul(b, ystep_delta));
|
||||
float f_d = FIXED_TO_FLOAT(FixedMul(d, ystep_delta));
|
||||
|
||||
for (; count > 0; dest += stride, --count)
|
||||
{
|
||||
ypx += 1.0f;
|
||||
|
||||
const INT32 srcx = ux >> FRACBITS;
|
||||
const INT32 srcy = (vflip) ? (ph - (uy >> FRACBITS)) : (uy >> FRACBITS);
|
||||
ux += FixedMul(b, ystep_delta);
|
||||
uy += FixedMul(d, ystep_delta);
|
||||
INT32 y_real = static_cast<INT32>(ypx);
|
||||
|
||||
if (mosaic_on && ymosaic_on)
|
||||
{
|
||||
y_real = (static_cast<INT32>(ypx / y_mosaic) * y_mosaic);
|
||||
}
|
||||
|
||||
ux = FLOAT_TO_FIXED(ux_base + (f_b * y_real));
|
||||
uy = FLOAT_TO_FIXED(uy_base + (f_d * y_real));
|
||||
|
||||
if (srcx < 0 || srcx >= pw || srcy < 0 || srcy >= ph)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ consvar_t cv_nulldrifttilt = CVAR_INIT ("nulldrifttilt", "On", CV_SAVE, CV_OnOff
|
|||
consvar_t cv_fakerollangle = CVAR_INIT ("fakerollangle", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_affineprescale = CVAR_INIT ("affineprescale", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
consvar_t cv_affinemosaic = CVAR_INIT ("affinemosaic", "Off", 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}};
|
||||
|
|
@ -1813,6 +1814,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_nulldrifttilt);
|
||||
CV_RegisterVar(&cv_fakerollangle);
|
||||
CV_RegisterVar(&cv_affineprescale);
|
||||
CV_RegisterVar(&cv_affinemosaic);
|
||||
|
||||
CV_RegisterVar(&cv_showhud);
|
||||
CV_RegisterVar(&cv_translucenthud);
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ extern consvar_t cv_sliptidetilt;
|
|||
extern consvar_t cv_nulldriftefx, cv_nulldrifttilt;
|
||||
|
||||
extern consvar_t cv_fakerollangle;
|
||||
extern consvar_t cv_affineprescale;
|
||||
extern consvar_t cv_affineprescale, cv_affinemosaic;
|
||||
|
||||
// debugging
|
||||
|
||||
|
|
|
|||
|
|
@ -1182,6 +1182,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
dc.affineoffset.x = vis->affine.offset.x;
|
||||
dc.affineoffset.y = vis->affine.offset.y;
|
||||
|
||||
dc.affinemosaic.x = vis->affine.mosaic.x;
|
||||
dc.affinemosaic.y = vis->affine.mosaic.y;
|
||||
|
||||
R_CopyAffineBounds(&vis->affine.bounds, &dc.affinebound);
|
||||
|
||||
fixed_t fixed_ylen = (FRACUNIT*dc.affinebound.ylen);
|
||||
|
|
@ -2081,6 +2084,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vector2_t affine_scale = {0};
|
||||
vector2_t affine_distscale = {0};
|
||||
vector2_t affine_pivotoffsetdiff = {0};
|
||||
f_vector2_t affine_mosaic = {.x = 1.0f, .y = 1.0f};
|
||||
|
||||
if (R_IsOverlayingSMonitorPlayer(thing))
|
||||
{
|
||||
|
|
@ -2355,6 +2359,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
affine_scale.x = FixedMul(affine_scale.x, FixedMul(spritexscale, this_scale));
|
||||
affine_scale.y = FixedMul(affine_scale.y, FixedMul(spriteyscale, this_scale));
|
||||
|
||||
affine_mosaic.x = FIXED_TO_FLOAT(FixedMul(affine_distscale.x, this_scale));
|
||||
affine_mosaic.y = FIXED_TO_FLOAT(FixedMul(affine_distscale.y, this_scale));
|
||||
|
||||
angle_t angle;
|
||||
|
||||
INT32 flipsign = ((flip) ? -1 : 1);
|
||||
|
|
@ -2940,6 +2947,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->affine.transform.ox = affine_transform.ox;
|
||||
vis->affine.transform.oy = affine_transform.oy;
|
||||
|
||||
vis->affine.mosaic.x = affine_mosaic.x;
|
||||
vis->affine.mosaic.y = affine_mosaic.y;
|
||||
|
||||
R_CopyAffineBounds(&affine_bounds, &vis->affine.bounds);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ struct vissprite_t
|
|||
vector2_t scaling; // Affine scaling
|
||||
vector2_t distscale; // X/Y scale based on camera distance
|
||||
vector2_t offset; // Per-pixel offset
|
||||
f_vector2_t mosaic; // Truncates how columndrawers "move" across the screen
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ TYPEDEF (mdllistitem_t);
|
|||
|
||||
// m_fixed.h
|
||||
TYPEDEF (vector2_t);
|
||||
TYPEDEF (f_vector2_t);
|
||||
TYPEDEF (vector3_t);
|
||||
TYPEDEF (vector4_t);
|
||||
TYPEDEF (matrix_t);
|
||||
|
|
|
|||
Loading…
Reference in a new issue