diff --git a/src/k_hud.c b/src/k_hud.c index 72a8ecdbb..67b6ebd09 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -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); diff --git a/src/r_defs.h b/src/r_defs.h index b75540c32..0d70653e9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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 diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index 0b8a08851..f2ccfe6ec 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -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); } diff --git a/src/st_stuff.c b/src/st_stuff.c index 1019979ab..8fe54c0e0 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -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++; } diff --git a/src/typedef.h b/src/typedef.h index b5280480b..9db93cd6a 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -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);