You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
2.3 KiB

#pragma once
#include <memory>
#include <utility>
#include "utils/pointer_value_union.hpp"
#include "utils/stdcompat/cstddef.hpp"
namespace devilution {
class OwnedCelSprite;
/**
* Stores a CEL or CL2 sprite and its width(s).
* Does not own the data.
*/
class CelSprite {
public:
CelSprite(const byte *data, uint16_t width)
: data_ptr_(data)
, width_(width)
{
}
CelSprite(const byte *data, const uint16_t *widths)
: data_ptr_(data)
, width_(widths)
{
}
CelSprite(const byte *data, PointerOrValue<uint16_t> widths)
: data_ptr_(data)
, width_(widths)
{
}
explicit CelSprite(const OwnedCelSprite &owned);
CelSprite(const CelSprite &) = default;
CelSprite(CelSprite &&) noexcept = default;
CelSprite &operator=(const CelSprite &) = default;
CelSprite &operator=(CelSprite &&) noexcept = default;
[[nodiscard]] const byte *Data() const
{
return data_ptr_;
}
[[nodiscard]] uint16_t Width(std::size_t frame = 0) const
{
return width_.HoldsPointer() ? width_.AsPointer()[frame] : width_.AsValue();
}
[[nodiscard]] bool operator==(CelSprite other) const
{
return data_ptr_ == other.data_ptr_;
}
[[nodiscard]] bool operator!=(CelSprite other) const
{
return data_ptr_ != other.data_ptr_;
}
private:
const byte *data_ptr_;
PointerOrValue<uint16_t> width_;
};
/**
* Stores a CEL or CL2 sprite and its width(s).
* Owns the data.
*/
class OwnedCelSprite {
public:
OwnedCelSprite(std::unique_ptr<byte[]> data, uint16_t width)
: data_(std::move(data))
, width_(width)
{
}
OwnedCelSprite(std::unique_ptr<byte[]> data, const uint16_t *widths)
: data_(std::move(data))
, width_(widths)
{
}
OwnedCelSprite(OwnedCelSprite &&) noexcept = default;
OwnedCelSprite &operator=(OwnedCelSprite &&) noexcept = default;
[[nodiscard]] byte *MutableData()
{
return data_.get();
}
private:
std::unique_ptr<byte[]> data_;
PointerOrValue<uint16_t> width_;
friend class CelSprite;
};
inline CelSprite::CelSprite(const OwnedCelSprite &owned)
: CelSprite(owned.data_.get(), owned.width_)
{
}
struct CelSpriteWithFrameHeight {
CelSprite sprite;
unsigned frameHeight;
};
struct OwnedCelSpriteWithFrameHeight {
OwnedCelSprite sprite;
unsigned frameHeight;
};
} // namespace devilution