47 changed files with 241 additions and 146 deletions
@ -0,0 +1,62 @@
|
||||
#pragma once |
||||
|
||||
#include <memory> |
||||
#include <utility> |
||||
|
||||
#include "utils/stdcompat/cstddef.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
/**
|
||||
* Stores a CEL or CL2 sprite and its width(s). |
||||
* |
||||
* The data may be unowned. |
||||
* Eventually we'd like to remove the unowned version. |
||||
*/ |
||||
class CelSprite { |
||||
public: |
||||
CelSprite(std::unique_ptr<byte[]> data, int width) |
||||
: data_(std::move(data)) |
||||
, data_ptr_(data_.get()) |
||||
, width_(width) |
||||
{ |
||||
} |
||||
|
||||
CelSprite(std::unique_ptr<byte[]> data, const int *widths) |
||||
: data_(std::move(data)) |
||||
, data_ptr_(data_.get()) |
||||
, widths_(widths) |
||||
{ |
||||
} |
||||
|
||||
/**
|
||||
* Constructs an unowned sprite. |
||||
* Ideally we'd like to remove all uses of this constructor. |
||||
*/ |
||||
CelSprite(const byte *data, int width) |
||||
: data_ptr_(data) |
||||
, width_(width) |
||||
{ |
||||
} |
||||
|
||||
CelSprite(CelSprite &&) noexcept = default; |
||||
CelSprite &operator=(CelSprite &&) noexcept = default; |
||||
|
||||
[[nodiscard]] const byte *Data() const |
||||
{ |
||||
return data_ptr_; |
||||
} |
||||
|
||||
[[nodiscard]] int Width(std::size_t frame = 1) const |
||||
{ |
||||
return widths_ == nullptr ? width_ : widths_[frame]; |
||||
} |
||||
|
||||
private: |
||||
std::unique_ptr<byte[]> data_; |
||||
const byte *data_ptr_; |
||||
int width_ = 0; |
||||
const int *widths_ = nullptr; // unowned
|
||||
}; |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,17 @@
|
||||
#include "engine/load_cel.hpp" |
||||
|
||||
#include "engine/load_file.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
CelSprite LoadCel(const char *pszName, int width) |
||||
{ |
||||
return CelSprite(LoadFileInMem(pszName), width); |
||||
} |
||||
|
||||
CelSprite LoadCel(const char *pszName, const int *widths) |
||||
{ |
||||
return CelSprite(LoadFileInMem(pszName), widths); |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,13 @@
|
||||
#pragma once |
||||
|
||||
#include "engine/cel_sprite.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
/**
|
||||
* @brief Loads a Cel sprite and sets its width |
||||
*/ |
||||
CelSprite LoadCel(const char *pszName, int width); |
||||
CelSprite LoadCel(const char *pszName, const int *widths); |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,38 @@
|
||||
#include "load_file.hpp" |
||||
|
||||
#include "diablo.h" |
||||
#include "storm/storm.h" |
||||
|
||||
namespace devilution { |
||||
|
||||
size_t GetFileSize(const char *pszName) |
||||
{ |
||||
HANDLE file; |
||||
if (!SFileOpenFile(pszName, &file)) { |
||||
if (!gbQuietMode) |
||||
app_fatal("GetFileSize - SFileOpenFile failed for file:\n%s", pszName); |
||||
return 0; |
||||
} |
||||
const size_t fileLen = SFileGetFileSize(file); |
||||
SFileCloseFileThreadSafe(file); |
||||
|
||||
return fileLen; |
||||
} |
||||
|
||||
void LoadFileData(const char *pszName, byte *buffer, size_t fileLen) |
||||
{ |
||||
HANDLE file; |
||||
if (!SFileOpenFile(pszName, &file)) { |
||||
if (!gbQuietMode) |
||||
app_fatal("LoadFileData - SFileOpenFile failed for file:\n%s", pszName); |
||||
return; |
||||
} |
||||
|
||||
if (fileLen == 0) |
||||
app_fatal("Zero length SFILE:\n%s", pszName); |
||||
|
||||
SFileReadFileThreadSafe(file, buffer, fileLen); |
||||
SFileCloseFileThreadSafe(file); |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,54 @@
|
||||
#pragma once |
||||
|
||||
#include <array> |
||||
#include <memory> |
||||
|
||||
#include "appfat.h" |
||||
#include "utils/stdcompat/cstddef.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
size_t GetFileSize(const char *pszName); |
||||
|
||||
void LoadFileData(const char *pszName, byte *buffer, size_t bufferSize); |
||||
|
||||
template <typename T> |
||||
void LoadFileInMem(const char *path, T *data, std::size_t count = 0) |
||||
{ |
||||
if (count == 0) |
||||
count = GetFileSize(path); |
||||
|
||||
LoadFileData(path, reinterpret_cast<byte *>(data), count * sizeof(T)); |
||||
} |
||||
|
||||
template <typename T, std::size_t N> |
||||
void LoadFileInMem(const char *path, std::array<T, N> &data) |
||||
{ |
||||
LoadFileInMem(path, &data, N); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Load a file in to a buffer |
||||
* @param path Path of file |
||||
* @param elements Number of T elements read |
||||
* @return Buffer with content of file |
||||
*/ |
||||
template <typename T = byte> |
||||
std::unique_ptr<T[]> LoadFileInMem(const char *path, size_t *elements = nullptr) |
||||
{ |
||||
const size_t fileLen = GetFileSize(path); |
||||
|
||||
if ((fileLen % sizeof(T)) != 0) |
||||
app_fatal("File size does not align with type\n%s", path); |
||||
|
||||
if (elements != nullptr) |
||||
*elements = fileLen / sizeof(T); |
||||
|
||||
std::unique_ptr<T[]> buf { new T[fileLen / sizeof(T)] }; |
||||
|
||||
LoadFileData(path, reinterpret_cast<byte *>(buf.get()), fileLen); |
||||
|
||||
return buf; |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
Loading…
Reference in new issue