[nostalgia] Fill out basic Scene system functionality

This commit is contained in:
2023-02-07 23:17:58 -06:00
parent eb55144211
commit 8077aaf0ae
34 changed files with 1111 additions and 631 deletions
+3 -1
View File
@@ -2,6 +2,7 @@
add_library(
NostalgiaScene
scene.cpp
scenestatic.cpp
scenemodule.cpp
typeconv.cpp
)
@@ -9,11 +10,12 @@ add_library(
target_link_libraries(
NostalgiaScene PUBLIC
NostalgiaCore
NostalgiaGeo
)
install(
FILES
scene.hpp
scenestatic.hpp
scenemodule.hpp
typeconv.hpp
DESTINATION
+36 -1
View File
@@ -1,11 +1,46 @@
/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <nostalgia/core/gfx.hpp>
#include "scene.hpp"
namespace nostalgia::scene {
Scene::Scene(const SceneStatic *sceneStatic) noexcept:
m_sceneStatic(sceneStatic) {
}
ox::Error Scene::setupDisplay(core::Context *ctx) noexcept {
if (m_sceneStatic->palettes.empty()) {
return OxError(1, "Scene has no palettes");
}
const auto &palette = m_sceneStatic->palettes[0];
oxReturnError(core::loadBgTileSheet(
ctx, 0, m_sceneStatic->tilesheet, palette));
// disable all backgrounds
core::setBgStatus(ctx, 0);
for (auto layerNo = 0u; const auto &layer : m_sceneStatic->tileMapIdx) {
core::setBgStatus(ctx, layerNo, true);
core::setBgCbb(ctx, layerNo, 0);
auto x = 0;
auto y = 0;
auto width = m_sceneStatic->rows[layerNo];
for (const auto &tile : layer) {
core::setTile(ctx, layerNo, x, y, tile);
core::setTile(ctx, layerNo, x + 1, y, tile + 1);
core::setTile(ctx, layerNo, x, y + 1, tile + 2);
core::setTile(ctx, layerNo, x + 1, y + 1, tile + 3);
x += 2;
if (x >= width * 2) {
x = 0;
y += 2;
}
}
++layerNo;
}
return {};
}
}
+7 -92
View File
@@ -4,104 +4,19 @@
#pragma once
#include <ox/fs/fs.hpp>
#include <ox/std/error.hpp>
#include <ox/std/types.hpp>
#include <ox/std/vector.hpp>
#include "scenestatic.hpp"
namespace nostalgia::scene {
struct TileDoc {
class Scene {
private:
const SceneStatic *m_sceneStatic = nullptr;
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.TileDoc";
constexpr static auto TypeVersion = 1;
constexpr static auto Preloadable = true;
public:
explicit Scene(const SceneStatic *sceneStatic) noexcept;
ox::String sheetIdx;
uint8_t type = 0;
ox::Error setupDisplay(core::Context *ctx) noexcept;
};
oxModelBegin(TileDoc)
oxModelFieldRename(sheet_idx, sheetIdx);
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::FileAddress tilesheet;
ox::FileAddress palette;
TileMap tiles;
};
oxModelBegin(SceneDoc)
oxModelField(tilesheet)
oxModelField(palette)
oxModelField(tiles)
oxModelEnd()
struct Scene {
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Scene";
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;
uint16_t *tileMapIdx = nullptr;
uint8_t *tileType = nullptr;
constexpr Layer(uint16_t &pColumns,
uint16_t &pRows,
uint16_t *pTileMapIdx,
uint8_t *pTileType) noexcept:
columns(pColumns),
rows(pRows),
tileMapIdx(pTileMapIdx),
tileType(pTileType) {
}
[[nodiscard]]
constexpr Tile tile(std::size_t i) const noexcept {
return {tileMapIdx[i], tileType[i]};
}
};
uint16_t layers = 0;
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].data(), tileType[i].data()};
}
};
oxModelBegin(Scene)
oxModelField(layers)
oxModelField(columns)
oxModelField(rows)
oxModelFieldRename(tile_map_idx, tileMapIdx)
oxModelFieldRename(tile_type, tileType)
oxModelEnd()
}
+3 -3
View File
@@ -10,15 +10,15 @@ namespace nostalgia::scene {
SceneModule SceneModule::mod;
ox::Vector<foundation::BaseConverter*> SceneModule::converters() const noexcept {
ox::Vector<const foundation::BaseConverter*> SceneModule::converters() const noexcept {
return {
&sceneToSceneInstaceConverter,
&sceneDocToSceneStaticConverter,
};
}
ox::Vector<foundation::PackTransform> SceneModule::packTransforms() const noexcept {
return {
foundation::transformRule<SceneDoc, Scene>,
foundation::transformRule<SceneDoc, SceneStatic>,
};
}
+2 -2
View File
@@ -12,12 +12,12 @@ namespace nostalgia::scene {
class SceneModule: public foundation::Module {
private:
mutable SceneDocToSceneConverter sceneToSceneInstaceConverter;
SceneDocToSceneStaticConverter sceneDocToSceneStaticConverter;
public:
static SceneModule mod;
[[nodiscard]]
ox::Vector<foundation::BaseConverter*> converters() const noexcept override;
ox::Vector<const foundation::BaseConverter*> converters() const noexcept override;
[[nodiscard]]
ox::Vector<foundation::PackTransform> packTransforms() const noexcept override;
};
+11
View File
@@ -0,0 +1,11 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include "scenestatic.hpp"
namespace nostalgia::scene {
}
+164
View File
@@ -0,0 +1,164 @@
/*
* 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()
}
+31 -3
View File
@@ -2,13 +2,41 @@
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <nostalgia/core/gfx.hpp>
#include <nostalgia/foundation/media.hpp>
#include "typeconv.hpp"
namespace nostalgia::scene {
// Type converters
ox::Error SceneDocToSceneConverter::convert(foundation::Context*, SceneDoc *, Scene *) noexcept {
ox::Error SceneDocToSceneStaticConverter::convert(
foundation::Context *ctx,
SceneDoc *src,
SceneStatic *dst) const noexcept {
oxRequire(ts, foundation::readObj<core::TileSheet>(ctx, src->tilesheet));
const auto layerCnt = src->tiles.size();
dst->setLayerCnt(layerCnt);
dst->tilesheet = ox::FileAddress(src->tilesheet);
dst->palettes.reserve(src->palettes.size());
for (const auto &pal : src->palettes) {
dst->palettes.emplace_back(pal);
}
for (auto layerIdx = 0u; const auto &layer : src->tiles) {
const auto layerDim = src->size(layerIdx);
auto dstLayer = dst->layer(layerIdx);
dstLayer.setDimensions(layerDim);
for (auto tileIdx = 0u; const auto &row : layer) {
for (const auto &srcTile : row) {
auto dstTile = dstLayer.tile(tileIdx);
dstTile.tileType = srcTile.type;
oxRequire(path, srcTile.getSubsheetPath(*ts));
oxRequire(mapIdx, ts->getTileOffset(path));
dstTile.tileMapIdx = static_cast<uint16_t>(mapIdx);
++tileIdx;
}
}
++layerIdx;
}
return {};
}
+3 -3
View File
@@ -6,12 +6,12 @@
#include <nostalgia/foundation/typeconv.hpp>
#include "scene.hpp"
#include "scenestatic.hpp"
namespace nostalgia::scene {
struct SceneDocToSceneConverter: public foundation::Converter<SceneDoc, Scene> {
ox::Error convert(foundation::Context*, SceneDoc *src, Scene *dst) noexcept final;
class SceneDocToSceneStaticConverter: public foundation::Converter<SceneDoc, SceneStatic> {
ox::Error convert(foundation::Context*, SceneDoc *src, SceneStatic *dst) const noexcept final;
};
}