Add pivot vectors and alignment flags to patches

Having to rely on offsets for rotation alignment is annoying and breaks Lua.
So... let's not!
This commit is contained in:
Anonimus 2025-10-07 14:44:50 -04:00
parent 9f8af1a7dd
commit 62457690a5
5 changed files with 78 additions and 16 deletions

View file

@ -375,8 +375,9 @@ void K_LoadKartHUDGraphics(void)
buffer[7] = '0'+(i+1);
HU_UpdatePatch(&kp_facehighlight[i], "%s", buffer);
kp_facehighlight[i]->leftoffset = kp_facehighlight[i]->width / 2;
kp_facehighlight[i]->topoffset = kp_facehighlight[i]->height / 2;
kp_facehighlight[i]->pivot.x = kp_facehighlight[i]->width / 2;
kp_facehighlight[i]->pivot.y = kp_facehighlight[i]->height / 2;
kp_facehighlight[i]->alignflags |= PATCHALIGN_USEPIVOTS;
}
// Special minimap icons
@ -4097,8 +4098,19 @@ static void K_drawKartMinimap(void)
interpy = R_InterpolateFixed(g->mo->old_y, g->mo->y);
patch_t *ghostPic = faceprefix[skin][FACE_MINIMAP];
iconoffsets.x = ((ghostPic->width) / 2) - FixedMul(ghostPic->leftoffset, minimapscale);
iconoffsets.y = ((ghostPic->height) / 2) - FixedMul(ghostPic->topoffset, minimapscale);
widthhalf = ((ghostPic->width) / 2);
heighthalf = ((ghostPic->height) / 2);
if (cv_minihead.value)
{
adjustx = FixedMul(4, (widthhalf - ghostPic->leftoffset) * FRACUNIT / widthhalf);
adjusty = FixedMul(4, (heighthalf - ghostPic->topoffset) *
FRACUNIT / heighthalf);
}
iconoffsets.x = widthhalf - ghostPic->leftoffset - adjustx;
iconoffsets.y = heighthalf - ghostPic->topoffset - adjusty;
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, ghostPic, colormap, &iconoffsets);
g = g->next;
@ -4144,8 +4156,18 @@ static void K_drawKartMinimap(void)
{
workingPic = kp_nocontestminimap;
iconoffsets.x = ((workingPic->width) / 2);
iconoffsets.y = ((workingPic->height) / 2);
widthhalf = ((workingPic->width) / 2);
heighthalf = ((workingPic->height) / 2);
if (cv_minihead.value)
{
adjustx = FixedMul(4, (widthhalf - workingPic->leftoffset) * FRACUNIT / widthhalf);
adjusty = FixedMul(4, (heighthalf - workingPic->topoffset) *
FRACUNIT / heighthalf);
}
iconoffsets.x = widthhalf - workingPic->leftoffset - adjustx;
iconoffsets.y = heighthalf - workingPic->topoffset - adjusty;
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
}
@ -4368,8 +4390,18 @@ static void K_drawKartMinimap(void)
{
workingPic = kp_nocontestminimap;
iconoffsets.x = ((workingPic->width) / 2);
iconoffsets.y = ((workingPic->height) / 2);
widthhalf = ((workingPic->width) / 2);
heighthalf = ((workingPic->height) / 2);
if (cv_minihead.value)
{
adjustx = FixedMul(4, (widthhalf - workingPic->leftoffset) * FRACUNIT / widthhalf);
adjusty = FixedMul(4, (heighthalf - workingPic->topoffset) *
FRACUNIT / heighthalf);
}
iconoffsets.x = widthhalf - workingPic->leftoffset - adjustx;
iconoffsets.y = heighthalf - workingPic->topoffset - adjusty;
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);

View file

@ -897,6 +897,11 @@ typedef enum
} pic_mode_t;
#ifdef ROTSPRITE
struct pivotvector_t
{
INT16 x, y;
};
struct rotsprite_t
{
INT32 angles;
@ -909,11 +914,22 @@ struct rotsprite_t
// Patches are used for sprites and all masked pictures, and we compose
// textures from the TEXTURES list of patches.
//
typedef enum
{
PATCHALIGN_AUTOCENTER = 1<<0,
PATCHALIGN_USEPIVOTS = 1<<1,
// free: up to 1<<7
} patchalignflags_t;
struct patch_t
{
INT16 width, height;
// Offsets and rotation pivots.
INT16 leftoffset, topoffset;
UINT8 autocentered; // Automatically centered for certain VFX
pivotvector_t pivot;
UINT8 alignflags; // Alignment-related flags.
INT32 *columnofs; // Column offsets. This is relative to patch->columns
UINT8 *columns; // Software column data

View file

@ -248,8 +248,18 @@ patch_t *Patch_GetRotated(patch_t *patch, INT32 angle, boolean flip)
if (rotsprite->patches[angle] == NULL)
{
INT32 xpivot = 0, ypivot = 0;
xpivot = patch->leftoffset;
ypivot = patch->topoffset;
if (patch->alignflags & PATCHALIGN_USEPIVOTS)
{
xpivot = patch->pivot.x;
ypivot = patch->pivot.y;
}
else
{
xpivot = patch->leftoffset;
ypivot = patch->topoffset;
}
RotatedPatch_DoRotation(rotsprite, patch, angle, xpivot, ypivot, flip);
}

View file

@ -212,11 +212,13 @@ void ST_LoadFaceGraphics(INT32 skinnum)
sprframe = &sprdef->spriteframes[i];
faceprefix[skinnum][i] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
alreadycentered = (boolean)faceprefix[skinnum][i]->autocentered;
alreadycentered = ((faceprefix[skinnum][i]->alignflags & PATCHALIGN_AUTOCENTER) ==
PATCHALIGN_AUTOCENTER);
if ((ST_IconCanSpinout(i)) && (!alreadycentered))
{
// Auto-center all minimap and rank patches with the ability to spinout.
// Auto-center the pivots of all minimap and rank patches with
// the ability to spinout.
// This is a shitty, hacky solution... but it's less work for spinout
// rotations!
if ((!baseleftoffs) && (faceprefix[skinnum][i]->leftoffset))
@ -229,13 +231,14 @@ void ST_LoadFaceGraphics(INT32 skinnum)
basetopoffs = faceprefix[skinnum][i]->topoffset;
}
faceprefix[skinnum][i]->leftoffset =
faceprefix[skinnum][i]->pivot.x =
(faceprefix[skinnum][i]->width / 2) + baseleftoffs;
faceprefix[skinnum][i]->topoffset =
faceprefix[skinnum][i]->pivot.y =
(faceprefix[skinnum][i]->height / 2) + basetopoffs;
// We're centered; don't do this operation again.
faceprefix[skinnum][i]->autocentered = 1;
faceprefix[skinnum][i]->alignflags |=
(PATCHALIGN_AUTOCENTER | PATCHALIGN_USEPIVOTS);
}
i++;
}

View file

@ -333,6 +333,7 @@ TYPEDEF (light_t);
TYPEDEF (node_t);
TYPEDEF (post_t);
TYPEDEF (drawseg_t);
TYPEDEF (pivotvector_t);
TYPEDEF (rotsprite_t);
TYPEDEF (patch_t);
TYPEDEF (softwarepatch_t);