122 lines
3.4 KiB
C++
122 lines
3.4 KiB
C++
#include "camera.hpp"
|
|
#include <fmt/core.h>
|
|
#include "animation.hpp"
|
|
#include <unordered_map>
|
|
#include "components.hpp"
|
|
#include "config.hpp"
|
|
#include <algorithm>
|
|
|
|
namespace cinematic {
|
|
using components::Animation, std::string, std::min, std::clamp;
|
|
|
|
struct CameraManager {
|
|
std::unordered_map<string, Animation> animations;
|
|
};
|
|
|
|
static CameraManager MGR;
|
|
static bool initialized = false;
|
|
|
|
void init() {
|
|
if(!initialized) {
|
|
auto cameras = settings::get("cameras");
|
|
for(auto &[name, data] : cameras.json().items()) {
|
|
auto anim = components::convert<Animation>(data);
|
|
MGR.animations.try_emplace(name, anim);
|
|
}
|
|
|
|
initialized = true;
|
|
}
|
|
}
|
|
|
|
Camera::Camera(sf::Vector2f size) :
|
|
anim(MGR.animations.at("shake")),
|
|
base_size(size),
|
|
size(size)
|
|
{
|
|
}
|
|
|
|
void Camera::update_camera_bounds(sf::Vector2f size) {
|
|
// camera bounds now constrains the x/y so that the mid-point
|
|
// of the size won't go too far outside of the frame
|
|
camera_bounds = {
|
|
{size.x / 2.0f, size.y / 2.0f},
|
|
{base_size.x - size.x / 2.0f, base_size.y - size.y / 2.0f}
|
|
};
|
|
|
|
fmt::println("!!!!! CAMERA BOUNDS camera_bounds={},{},{},{}",
|
|
camera_bounds.position.x, camera_bounds.position.y,
|
|
camera_bounds.size.x, camera_bounds.size.y);
|
|
}
|
|
|
|
void Camera::scale(float ratio) {
|
|
size.x = base_size.x * ratio;
|
|
size.y = base_size.y * ratio;
|
|
update_camera_bounds(size);
|
|
}
|
|
|
|
void Camera::resize(float width) {
|
|
dbc::check(width <= base_size.x, "invalid width for camera");
|
|
|
|
size.x = width;
|
|
size.y = base_size.y * (width / base_size.x);
|
|
update_camera_bounds(size);
|
|
}
|
|
|
|
void Camera::style(const std::string &name) {
|
|
anim = MGR.animations.at(name);
|
|
}
|
|
|
|
void Camera::position(float x, float y) {
|
|
aimed_at.x = clamp(x, camera_bounds.position.x, camera_bounds.size.x);
|
|
aimed_at.y = clamp(y, camera_bounds.position.y, camera_bounds.size.y);
|
|
|
|
fmt::println("!!! CAMERA POSITION aimed_at={},{}; x/y={},{}; camera_bounds={},{},{},{}",
|
|
aimed_at.x, aimed_at.y, x, y,
|
|
camera_bounds.position.x, camera_bounds.position.y,
|
|
camera_bounds.size.x, camera_bounds.size.y);
|
|
}
|
|
|
|
void Camera::move(float x, float y) {
|
|
going_to.x = clamp(x, camera_bounds.position.x, camera_bounds.size.x);
|
|
going_to.y = clamp(y, camera_bounds.position.y, camera_bounds.size.y);
|
|
|
|
fmt::println("!!!! CAMERA MOVE going_to={},{}; x/y={},{}; camera_bounds={},{},{},{}",
|
|
going_to.x, going_to.y, x, y,
|
|
camera_bounds.position.x, camera_bounds.position.y,
|
|
camera_bounds.size.x, camera_bounds.size.y);
|
|
|
|
// BUG: annoying special case
|
|
if(anim.motion == ease::SLIDE) {
|
|
anim.min_x = aimed_at.x;
|
|
anim.min_y = aimed_at.y;
|
|
anim.max_x = going_to.x;
|
|
anim.max_y = going_to.y;
|
|
}
|
|
}
|
|
|
|
void Camera::reset(sf::RenderTexture& target) {
|
|
size = {base_size.x, base_size.y};
|
|
aimed_at = {base_size.x/2, base_size.y/2};
|
|
going_to = {base_size.x/2, base_size.y/2};
|
|
view = {aimed_at, size};
|
|
camera_bounds = {{0,0}, base_size};
|
|
|
|
// BUG: is getDefaultView different from view?
|
|
target.setView(target.getDefaultView());
|
|
}
|
|
|
|
void Camera::render(sf::RenderTexture& target) {
|
|
if(anim.playing) {
|
|
anim.apply(view, going_to, size);
|
|
target.setView(view);
|
|
}
|
|
}
|
|
|
|
bool Camera::playing() {
|
|
return anim.playing;
|
|
}
|
|
|
|
void Camera::play() {
|
|
anim.play();
|
|
}
|
|
}
|