192 lines
3.9 KiB
C++
192 lines
3.9 KiB
C++
#include <Format/Layer.hpp>
|
|
|
|
Layer::Layer(): rows(0), cols(0), cell_width(0), cell_height(0), parallax_x(0), parallax_y(0), cells(nullptr), visible(true), order(0)
|
|
{ }
|
|
|
|
Layer::Layer(int rows, int cols, int cell_width, int cell_height): cells(nullptr), parallax_x(0), parallax_y(0)
|
|
{
|
|
this->rows = rows;
|
|
this->cols = cols;
|
|
this->cell_width = cell_width;
|
|
this->cell_height = cell_height;
|
|
this->visible = true;
|
|
}
|
|
|
|
Layer::Layer(const json::value& json)
|
|
{
|
|
Deserialize(json);
|
|
}
|
|
|
|
Layer::~Layer()
|
|
{
|
|
DeleteGrid();
|
|
}
|
|
|
|
Layer::Layer(const std::filesystem::path& path)
|
|
{
|
|
auto [json, err] = json::parse(read_file_contents(path));
|
|
Deserialize(json);
|
|
}
|
|
|
|
json::value Layer::Serialize() const
|
|
{
|
|
json::object data;
|
|
data["name"] = name;
|
|
data["binary-path"] = binary_path;
|
|
data["rows"] = (float)rows;
|
|
data["cols"] = (float)cols;
|
|
data["cell-width"] = (float)cell_width;
|
|
data["cell-height"] = (float)cell_height;
|
|
data["order"] = (float)order;
|
|
|
|
return data;
|
|
}
|
|
|
|
void Layer::Deserialize(const json::value& json)
|
|
{
|
|
name = json["name"].as_string();
|
|
binary_path = json["binary-path"].as_string();
|
|
rows = json["rows"].number.value();
|
|
cols = json["cols"].number.value();
|
|
cell_width = json["cell-width"].number.value();
|
|
cell_height = json["cell-height"].number.value();
|
|
order = json["order"].number.value_or(0);
|
|
}
|
|
|
|
void Layer::InitGrid()
|
|
{
|
|
if (grid_allocated)
|
|
return; // TODO: Throw double allocation.
|
|
|
|
cells = new int*[rows];
|
|
|
|
for (int i = 0; i < rows; i++)
|
|
cells[i] = new int[cols];
|
|
|
|
for (int x = 0; x < rows; x++) {
|
|
for (int y = 0; y < cols; y++) {
|
|
cells[x][y] = -1;
|
|
}
|
|
}
|
|
|
|
grid_allocated = true;
|
|
}
|
|
|
|
void Layer::DeleteGrid()
|
|
{
|
|
|
|
if (!grid_allocated)
|
|
return;
|
|
|
|
for (int i = 0; i < rows; i++)
|
|
delete[] cells[i];
|
|
|
|
delete[] cells;
|
|
|
|
grid_allocated = false;
|
|
}
|
|
|
|
void Layer::Resize(int newWidth, int newHeight) {
|
|
|
|
// If dimensions are unchanged, do nothing.
|
|
if (newWidth == rows && newHeight == cols)
|
|
return;
|
|
|
|
int best_fit_rows = J3ML::Math::Min(rows, newWidth);
|
|
int best_fit_cols = J3ML::Math::Min(cols, newHeight);
|
|
|
|
int old_data_length = rows*cols;
|
|
int* old_data_contiguous = new int[old_data_length];
|
|
|
|
for (int x = 0; x < best_fit_rows; x++) {
|
|
for (int y = 0; y < best_fit_cols; y++) {
|
|
int index = (x * best_fit_cols + y);
|
|
old_data_contiguous[index] = cells[x][y];
|
|
}
|
|
}
|
|
|
|
DeleteGrid();
|
|
this->rows = newWidth;
|
|
this->cols = newHeight;
|
|
InitGrid();
|
|
|
|
for (int x = 0; x < best_fit_rows; x++) {
|
|
for (int y = 0; y < best_fit_cols; y++) {
|
|
int index = (x * best_fit_cols + y);
|
|
cells[x][y] = old_data_contiguous[index];
|
|
}
|
|
}
|
|
|
|
delete[] old_data_contiguous;
|
|
}
|
|
|
|
void Layer::LoadFromDataBuffer(const int* buffer)
|
|
{
|
|
for (int x = 0; x < rows; x++)
|
|
{
|
|
for (int y = 0; y < cols; y++)
|
|
{
|
|
int index = (x * cols + y);
|
|
cells[x][y] = buffer[index];
|
|
}
|
|
}
|
|
}
|
|
|
|
void Layer::WriteToDataBuffer(int* buffer) const
|
|
{
|
|
//int* buffer = new int[rows*cols];
|
|
for (int x = 0; x < rows; x++)
|
|
{
|
|
for (int y = 0; y < cols; y++)
|
|
{
|
|
int index = (x*cols + y);
|
|
buffer[index] = cells[x][y];
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Layer::WriteBinaryData(const std::filesystem::path& path) const
|
|
{
|
|
int* buffer = new int[rows*cols];
|
|
WriteToDataBuffer(buffer);
|
|
std::ofstream output;
|
|
output.open(path, std::ios::out | std::ios::binary);
|
|
output.write(reinterpret_cast<const char*>(buffer), rows * cols * sizeof(int));
|
|
output.close();
|
|
|
|
delete[] buffer;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Layer::Save()
|
|
{ return WriteBinaryData(binary_path); }
|
|
|
|
bool Layer::Load() {
|
|
if (!std::filesystem::exists(binary_path)) {
|
|
InitGrid();
|
|
return true;
|
|
}
|
|
return ReadBinaryData(binary_path);
|
|
}
|
|
|
|
bool Layer::ReadBinaryData(const std::filesystem::path& path)
|
|
{
|
|
std::ifstream input;
|
|
input.open(path, std::ios::binary | std::ios::in);
|
|
input.seekg(0, std::ios::end);
|
|
int data_length = input.tellg();
|
|
input.seekg(0, std::ios::beg);
|
|
|
|
char* buffer = new char[data_length];
|
|
input.read(buffer, data_length);
|
|
input.close();
|
|
|
|
InitGrid();
|
|
LoadFromDataBuffer(reinterpret_cast<int*>(buffer));
|
|
|
|
delete[] buffer;
|
|
|
|
return true;
|
|
}
|