165 lines
4.0 KiB
C++
165 lines
4.0 KiB
C++
/*
|
|
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <ox/fs/fs.hpp>
|
|
#include <ox/std/error.hpp>
|
|
#include <ox/std/types.hpp>
|
|
#include <ox/std/vector.hpp>
|
|
|
|
#include <nostalgia/core/tilesheet.hpp>
|
|
#include <nostalgia/geo/size.hpp>
|
|
|
|
namespace nostalgia::scene {
|
|
|
|
struct TileDoc {
|
|
|
|
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.TileDoc";
|
|
constexpr static auto TypeVersion = 1;
|
|
constexpr static auto Preloadable = true;
|
|
|
|
core::SubSheetId subsheetId = -1;
|
|
ox::String subsheetPath;
|
|
uint8_t type = 0;
|
|
|
|
[[nodiscard]]
|
|
constexpr ox::Result<core::SubSheetId> getSubsheetId(const core::TileSheet &ts) const noexcept {
|
|
// prefer the already present ID
|
|
if (subsheetId > -1) {
|
|
return subsheetId;
|
|
}
|
|
return ts.getIdFor(subsheetPath);
|
|
}
|
|
|
|
[[nodiscard]]
|
|
constexpr ox::Result<ox::StringView> getSubsheetPath(
|
|
const core::TileSheet &ts) const noexcept {
|
|
// prefer the already present path
|
|
if (!subsheetPath.len()) {
|
|
return ts.getNameFor(subsheetId);
|
|
}
|
|
return ox::StringView(subsheetPath);
|
|
}
|
|
|
|
};
|
|
|
|
oxModelBegin(TileDoc)
|
|
oxModelFieldRename(subsheet_id, subsheetId);
|
|
oxModelFieldRename(subsheet_path, subsheetPath);
|
|
oxModelField(type);
|
|
oxModelEnd()
|
|
|
|
struct SceneDoc {
|
|
|
|
using TileMapRow = ox::Vector<TileDoc>;
|
|
using TileMapLayer = ox::Vector<TileMapRow>;
|
|
using TileMap = ox::Vector<TileMapLayer>;
|
|
|
|
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.SceneDoc";
|
|
constexpr static auto TypeVersion = 1;
|
|
constexpr static auto Preloadable = true;
|
|
|
|
ox::String tilesheet; // path
|
|
ox::Vector<ox::String> palettes; // paths
|
|
TileMap tiles;
|
|
|
|
[[nodiscard]]
|
|
constexpr geo::Size size(std::size_t layerIdx) const noexcept {
|
|
const auto &layer = this->tiles[layerIdx];
|
|
const auto rowCnt = static_cast<int>(layer.size());
|
|
if (!rowCnt) {
|
|
return {};
|
|
}
|
|
auto colCnt = layer[0].size();
|
|
// find shortest row (they should all be the same, but you know this data
|
|
// could come from a file)
|
|
for (const auto &row : layer) {
|
|
colCnt = ox::min(colCnt, row.size());
|
|
}
|
|
return {static_cast<int>(colCnt), rowCnt};
|
|
}
|
|
};
|
|
|
|
oxModelBegin(SceneDoc)
|
|
oxModelField(tilesheet)
|
|
oxModelField(palettes)
|
|
oxModelField(tiles)
|
|
oxModelEnd()
|
|
|
|
struct SceneStatic {
|
|
|
|
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.SceneStatic";
|
|
constexpr static auto TypeVersion = 1;
|
|
constexpr static auto Preloadable = true;
|
|
|
|
struct Tile {
|
|
uint16_t &tileMapIdx;
|
|
uint8_t &tileType;
|
|
constexpr Tile(uint16_t *pTileMapIdx, uint8_t *pTileType) noexcept:
|
|
tileMapIdx(*pTileMapIdx),
|
|
tileType(*pTileType) {
|
|
}
|
|
};
|
|
struct Layer {
|
|
uint16_t &columns;
|
|
uint16_t &rows;
|
|
ox::Vector<uint16_t> &tileMapIdx;
|
|
ox::Vector<uint8_t> &tileType;
|
|
constexpr Layer(
|
|
uint16_t *pColumns,
|
|
uint16_t *pRows,
|
|
ox::Vector<uint16_t> *pTileMapIdx,
|
|
ox::Vector<uint8_t> *pTileType) noexcept:
|
|
columns(*pColumns),
|
|
rows(*pRows),
|
|
tileMapIdx(*pTileMapIdx),
|
|
tileType(*pTileType) {
|
|
}
|
|
[[nodiscard]]
|
|
constexpr Tile tile(std::size_t i) noexcept {
|
|
return {&tileMapIdx[i], &tileType[i]};
|
|
}
|
|
constexpr auto setDimensions(geo::Size dim) noexcept {
|
|
columns = dim.width;
|
|
rows = dim.height;
|
|
const auto tileCnt = static_cast<unsigned>(columns * rows);
|
|
tileMapIdx.resize(tileCnt);
|
|
tileType.resize(tileCnt);
|
|
}
|
|
};
|
|
|
|
ox::FileAddress tilesheet;
|
|
ox::Vector<ox::FileAddress> palettes;
|
|
// tile layer data
|
|
ox::Vector<uint16_t> columns;
|
|
ox::Vector<uint16_t> rows;
|
|
ox::Vector<ox::Vector<uint16_t>> tileMapIdx;
|
|
ox::Vector<ox::Vector<uint8_t>> tileType;
|
|
|
|
[[nodiscard]]
|
|
constexpr Layer layer(std::size_t i) noexcept {
|
|
return {&columns[i], &rows[i], &tileMapIdx[i], &tileType[i]};
|
|
}
|
|
|
|
constexpr auto setLayerCnt(std::size_t layerCnt) noexcept {
|
|
this->columns.resize(layerCnt);
|
|
this->rows.resize(layerCnt);
|
|
this->tileMapIdx.resize(layerCnt);
|
|
this->tileType.resize(layerCnt);
|
|
}
|
|
|
|
};
|
|
|
|
oxModelBegin(SceneStatic)
|
|
oxModelField(tilesheet)
|
|
oxModelField(palettes)
|
|
oxModelField(columns)
|
|
oxModelField(rows)
|
|
oxModelFieldRename(tile_map_idx, tileMapIdx)
|
|
oxModelFieldRename(tile_type, tileType)
|
|
oxModelEnd()
|
|
|
|
}
|