Files
Editor2D/src/Format/Layer.cpp

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;
}