44 lines
1.7 KiB
C++
44 lines
1.7 KiB
C++
#include "core/rendering/effects/shadow.hpp"
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include "core/rendering/surface.hpp"
|
|
#include "core/resources/resource_cache.hpp"
|
|
|
|
namespace Effects::Shadow {
|
|
|
|
void render(int center_x, int feet_y, float height_factor) {
|
|
// Lookup únic al primer ús: la Surface viu a Cache durant tota la
|
|
// sessió, així evitem la cerca lineal a cada frame.
|
|
static const auto SURFACE = Resource::Cache::get().getSurface(CACHE_KEY);
|
|
|
|
const int FRAME_COUNT = SURFACE->getWidth() / FRAME_SIZE;
|
|
if (FRAME_COUNT <= 0) { return; }
|
|
|
|
// Mapping a bandes uniformes: factor 0 → últim (gran), factor 1 →
|
|
// primer (petit). Per a 3 fotogrames: [0, 1/3) → 2, [1/3, 2/3) → 1,
|
|
// [2/3, 1] → 0. Generalitza a qualsevol nombre de fotogrames per
|
|
// si afegim mides intermèdies.
|
|
const float CLAMPED = std::clamp(height_factor, 0.0F, 1.0F);
|
|
int frame_index = static_cast<int>((1.0F - CLAMPED) * static_cast<float>(FRAME_COUNT));
|
|
frame_index = std::clamp(frame_index, 0, FRAME_COUNT - 1);
|
|
|
|
SDL_FRect clip{
|
|
static_cast<float>(frame_index * FRAME_SIZE),
|
|
0.0F,
|
|
static_cast<float>(FRAME_SIZE),
|
|
static_cast<float>(FRAME_SIZE),
|
|
};
|
|
|
|
// Ancoratge: vora inferior del fotograma a `feet_y` — així el
|
|
// quadrat 16x16 del sprite encaixa exactament al 16x16 inferior
|
|
// d'una entitat 16x16/16x32 centrada en `center_x`.
|
|
const int X = center_x - (FRAME_SIZE / 2);
|
|
const int Y = feet_y - FRAME_SIZE;
|
|
SURFACE->render(X, Y, &clip);
|
|
}
|
|
|
|
} // namespace Effects::Shadow
|