Browse Source

Add new GetOffsetForWalking helper and use it for player drawing and camera

pull/2004/head
obligaron 5 years ago committed by Anders Jenbo
parent
commit
4d2ac0502a
  1. 8
      Source/cursor.cpp
  2. 46
      Source/scrollrt.cpp
  3. 9
      Source/scrollrt.h

8
Source/cursor.cpp

@ -276,8 +276,12 @@ void CheckCursMove()
// Adjust by player offset and tile grid alignment
CalcTileOffset(&xo, &yo);
sx -= ScrollInfo.offset.x - xo;
sy -= ScrollInfo.offset.y - yo;
PlayerStruct *pPlayer = &plr[myplr];
Point offset = ScrollInfo.offset;
if (pPlayer->IsWalking())
offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir, true);
sx -= offset.x - xo;
sy -= offset.y - yo;
// Predict the next frame when walking to avoid input jitter
fx = plr[myplr].position.offset2.x / 256;

46
Source/scrollrt.cpp

@ -124,6 +124,36 @@ const char *const szPlrModeAssert[] = {
"quitting"
};
Point GetOffsetForWalking(const AnimationInfo &animationInfo, const direction dir, bool cameraMode /*= false*/)
{
// clang-format off
// DIR_S, DIR_SW, DIR_W, DIR_NW, DIR_N, DIR_NE, DIR_E, DIR_SE,
constexpr Point startOffset[8] = { { 0, -32 }, { 32, -16 }, { 32, -16 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { -32, -16 }, { -32, -16 } };
constexpr Point movingOffset[8] = { { 0, 32 }, { -32, 16 }, { -64, 0 }, { -32, -16 }, { 0, -32 }, { 32, -16 }, { 64, 0 }, { 32, 16 } };
constexpr bool isDiagionalWalk[8] = { false, true, false, true, false, true, false, true };
// clang-format on
float fAnimationProgress = animationInfo.GetAnimationProgress();
Point offset = movingOffset[dir];
offset *= fAnimationProgress;
// In diagonal walks the offset for y is smaller then x.
// This means that sometimes x is updated but y not.
// That result in a small stuttering.
// To fix this we disallow odd x as this is the only case where y is not updated.
if (isDiagionalWalk[dir] && ((offset.x % 2) != 0)) {
offset.x -= offset.x > 0 ? 1 : -1;
}
if (cameraMode) {
offset = -offset;
} else {
offset += startOffset[dir];
}
return offset;
}
/**
* @brief Clear cursor state
*/
@ -677,8 +707,12 @@ static void DrawPlayerHelper(const CelOutputBuffer &out, int x, int y, int sx, i
}
PlayerStruct *pPlayer = &plr[p];
int px = sx + pPlayer->position.offset.x - CalculateWidth2(pPlayer->_pAnimWidth);
int py = sy + pPlayer->position.offset.y;
Point offset = ScrollInfo.offset;
if (pPlayer->IsWalking()) {
offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir);
}
int px = sx + offset.x - CalculateWidth2(pPlayer->_pAnimWidth);
int py = sy + offset.y;
DrawPlayer(out, p, x, y, px, py);
}
@ -1107,8 +1141,12 @@ static void DrawGame(const CelOutputBuffer &full_out, int x, int y)
: full_out.subregionY(0, (gnViewportHeight + 1) / 2);
// Adjust by player offset and tile grid alignment
sx = ScrollInfo.offset.x + tileOffsetX;
sy = ScrollInfo.offset.y + tileOffsetY;
PlayerStruct *pPlayer = &plr[myplr];
Point offset = ScrollInfo.offset;
if (pPlayer->IsWalking())
offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir, true);
sx = offset.x + tileOffsetX;
sy = offset.y + tileOffsetY;
columns = tileColums;
rows = tileRows;

9
Source/scrollrt.h

@ -7,6 +7,7 @@
#include <cstdint>
#include "engine/animationinfo.h"
#include "engine.h"
namespace devilution {
@ -35,6 +36,14 @@ extern bool cel_foliage_active;
extern int level_piece_id;
extern bool AutoMapShowItems;
/**
* @brief Returns the offset for the walking animation
* @param animationInfo the current active walking animation
* @param dir walking direction
* @param cameraMode Adjusts the offset relative to the camera
*/
Point GetOffsetForWalking(const AnimationInfo &animationInfo, const direction dir, bool cameraMode = false);
void ClearCursor();
void ShiftGrid(int *x, int *y, int horizontal, int vertical);
int RowsCoveredByPanel();

Loading…
Cancel
Save