[nostalgia] Move modules into modules directory
This commit is contained in:
13
src/nostalgia/modules/scene/CMakeLists.txt
Normal file
13
src/nostalgia/modules/scene/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
add_subdirectory(src)
|
||||
|
||||
target_include_directories(
|
||||
NostalgiaScene PUBLIC
|
||||
include
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY
|
||||
include/nostalgia
|
||||
DESTINATION
|
||||
include
|
||||
)
|
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <keel/module.hpp>
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
const keel::Module *keelModule() noexcept;
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenestatic.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
class Scene {
|
||||
private:
|
||||
const SceneStatic &m_sceneStatic;
|
||||
|
||||
public:
|
||||
explicit Scene(const SceneStatic &sceneStatic) noexcept;
|
||||
|
||||
ox::Error setupDisplay(core::Context *ctx) noexcept;
|
||||
|
||||
};
|
||||
|
||||
}
|
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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/size.hpp>
|
||||
#include <ox/std/types.hpp>
|
||||
#include <ox/std/vector.hpp>
|
||||
|
||||
#include <nostalgia/core/tilesheet.hpp>
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
struct SpriteDoc {
|
||||
|
||||
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.SpriteDoc";
|
||||
constexpr static auto TypeVersion = 1;
|
||||
constexpr static auto Preloadable = true;
|
||||
|
||||
ox::String tilesheetPath;
|
||||
ox::Vector<core::SubSheetId> subsheetId;
|
||||
|
||||
};
|
||||
|
||||
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;
|
||||
ox::Array<uint8_t, 4> layerAttachments;
|
||||
|
||||
[[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 ox::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()
|
||||
|
||||
|
||||
constexpr void setTopEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||
const auto val8 = static_cast<uint8_t>(val);
|
||||
layerAttachments = (layerAttachments & 0b11111100) | val8;
|
||||
}
|
||||
constexpr void setBottomEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||
const auto val8 = static_cast<uint8_t>(val);
|
||||
layerAttachments = (layerAttachments & 0b11110011) | static_cast<uint8_t>(val8 << 2);
|
||||
}
|
||||
constexpr void setLeftEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||
const auto val8 = static_cast<uint8_t>(val);
|
||||
layerAttachments = (layerAttachments & 0b11001111) | static_cast<uint8_t>(val8 << 4);
|
||||
}
|
||||
constexpr void setRightEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||
const auto val8 = static_cast<uint8_t>(val);
|
||||
layerAttachments = (layerAttachments & 0b00111111) | static_cast<uint8_t>(val8 << 6);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr unsigned topEdge(uint8_t layerAttachments) noexcept {
|
||||
return layerAttachments & 0b11;
|
||||
}
|
||||
[[nodiscard]]
|
||||
constexpr unsigned bottomEdge(uint8_t layerAttachments) noexcept {
|
||||
return (layerAttachments >> 2) & 0b11;
|
||||
}
|
||||
[[nodiscard]]
|
||||
constexpr unsigned leftEdge(uint8_t layerAttachments) noexcept {
|
||||
return (layerAttachments >> 4) & 0b11;
|
||||
}
|
||||
[[nodiscard]]
|
||||
constexpr unsigned rightEdge(uint8_t layerAttachments) noexcept {
|
||||
return (layerAttachments >> 6) & 0b11;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
uint8_t &layerAttachments;
|
||||
constexpr Tile(uint16_t &pTileMapIdx, uint8_t &pTileType, uint8_t &pLayerAttachments) noexcept:
|
||||
tileMapIdx(pTileMapIdx),
|
||||
tileType(pTileType),
|
||||
layerAttachments(pLayerAttachments) {
|
||||
}
|
||||
};
|
||||
struct Layer {
|
||||
uint16_t &columns;
|
||||
uint16_t &rows;
|
||||
ox::Vector<uint16_t> &tileMapIdx;
|
||||
ox::Vector<uint8_t> &tileType;
|
||||
ox::Vector<uint8_t> &layerAttachments;
|
||||
constexpr Layer(
|
||||
uint16_t &pColumns,
|
||||
uint16_t &pRows,
|
||||
ox::Vector<uint16_t> &pTileMapIdx,
|
||||
ox::Vector<uint8_t> &pTileType,
|
||||
ox::Vector<uint8_t> &pLayerAttachments) noexcept:
|
||||
columns(pColumns),
|
||||
rows(pRows),
|
||||
tileMapIdx(pTileMapIdx),
|
||||
tileType(pTileType),
|
||||
layerAttachments(pLayerAttachments) {
|
||||
}
|
||||
[[nodiscard]]
|
||||
constexpr Tile tile(std::size_t i) noexcept {
|
||||
return {tileMapIdx[i], tileType[i], layerAttachments[i]};
|
||||
}
|
||||
constexpr auto setDimensions(ox::Size dim) noexcept {
|
||||
columns = static_cast<uint16_t>(dim.width);
|
||||
rows = static_cast<uint16_t>(dim.height);
|
||||
const auto tileCnt = static_cast<unsigned>(columns * rows);
|
||||
tileMapIdx.resize(tileCnt);
|
||||
tileType.resize(tileCnt);
|
||||
layerAttachments.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;
|
||||
ox::Vector<ox::Vector<uint8_t>> layerAttachments;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr Layer layer(std::size_t i) noexcept {
|
||||
return {
|
||||
columns[i],
|
||||
rows[i],
|
||||
tileMapIdx[i],
|
||||
tileType[i],
|
||||
layerAttachments[i],
|
||||
};
|
||||
}
|
||||
|
||||
constexpr auto setLayerCnt(std::size_t layerCnt) noexcept {
|
||||
this->layerAttachments.resize(layerCnt);
|
||||
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)
|
||||
oxModelField(tileMapIdx)
|
||||
oxModelField(tileType)
|
||||
oxModelField(layerAttachments)
|
||||
oxModelEnd()
|
||||
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <studio/studio.hpp>
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
const studio::Module *studioModule() noexcept;
|
||||
|
||||
}
|
22
src/nostalgia/modules/scene/src/CMakeLists.txt
Normal file
22
src/nostalgia/modules/scene/src/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
add_library(
|
||||
NostalgiaScene
|
||||
scene.cpp
|
||||
scenestatic.cpp
|
||||
keelmodule.cpp
|
||||
typeconv.cpp
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
NostalgiaScene PUBLIC
|
||||
../include
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
NostalgiaScene PUBLIC
|
||||
NostalgiaCore
|
||||
)
|
||||
|
||||
if(NOSTALGIA_BUILD_STUDIO)
|
||||
add_subdirectory(studio)
|
||||
endif()
|
47
src/nostalgia/modules/scene/src/keelmodule.cpp
Normal file
47
src/nostalgia/modules/scene/src/keelmodule.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <keel/module.hpp>
|
||||
|
||||
#include <nostalgia/scene/scenestatic.hpp>
|
||||
|
||||
#include "typeconv.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
class SceneModule: public keel::Module {
|
||||
private:
|
||||
SceneDocToSceneStaticConverter sceneDocToSceneStaticConverter;
|
||||
|
||||
public:
|
||||
[[nodiscard]]
|
||||
ox::Vector<keel::TypeDescGenerator> types() const noexcept override {
|
||||
return {
|
||||
keel::generateTypeDesc<SceneDoc>,
|
||||
keel::generateTypeDesc<SceneStatic>,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
ox::Vector<const keel::BaseConverter*> converters() const noexcept override {
|
||||
return {
|
||||
&sceneDocToSceneStaticConverter,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
ox::Vector<keel::PackTransform> packTransforms() const noexcept override {
|
||||
return {
|
||||
keel::transformRule<SceneDoc, SceneStatic>,
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static SceneModule mod;
|
||||
const keel::Module *keelModule() noexcept {
|
||||
return &mod;
|
||||
}
|
||||
|
||||
}
|
47
src/nostalgia/modules/scene/src/scene.cpp
Normal file
47
src/nostalgia/modules/scene/src/scene.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
|
||||
#include <nostalgia/scene/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) {
|
||||
auto tile8 = static_cast<uint8_t >(tile);
|
||||
core::setTile(ctx, layerNo, x, y, tile8);
|
||||
core::setTile(ctx, layerNo, x + 1, y, tile8 + 1);
|
||||
core::setTile(ctx, layerNo, x, y + 1, tile8 + 2);
|
||||
core::setTile(ctx, layerNo, x + 1, y + 1, tile8 + 3);
|
||||
x += 2;
|
||||
if (x >= width * 2) {
|
||||
x = 0;
|
||||
y += 2;
|
||||
}
|
||||
}
|
||||
++layerNo;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
11
src/nostalgia/modules/scene/src/scenestatic.cpp
Normal file
11
src/nostalgia/modules/scene/src/scenestatic.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nostalgia/scene/scenestatic.hpp>
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
|
||||
|
||||
}
|
24
src/nostalgia/modules/scene/src/studio/CMakeLists.txt
Normal file
24
src/nostalgia/modules/scene/src/studio/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
add_library(
|
||||
NostalgiaScene-Studio OBJECT
|
||||
studiomodule.cpp
|
||||
sceneeditor-imgui.cpp
|
||||
sceneeditor.cpp
|
||||
sceneeditorview.cpp
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
target_compile_options(NostalgiaScene-Studio PRIVATE -Wsign-conversion)
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
NostalgiaScene-Studio PUBLIC
|
||||
NostalgiaScene
|
||||
Studio
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
NostalgiaScene-Studio
|
||||
LIBRARY DESTINATION
|
||||
${NOSTALGIA_DIST_MODULE}
|
||||
)
|
57
src/nostalgia/modules/scene/src/studio/sceneeditor-imgui.cpp
Normal file
57
src/nostalgia/modules/scene/src/studio/sceneeditor-imgui.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <keel/media.hpp>
|
||||
|
||||
#include "sceneeditor-imgui.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
SceneEditorImGui::SceneEditorImGui(turbine::Context *ctx, ox::CRStringView path):
|
||||
m_editor(ctx, path),
|
||||
m_view(ctx, m_editor.scene()) {
|
||||
m_ctx = ctx;
|
||||
m_itemPath = path;
|
||||
const auto lastSlash = std::find(m_itemPath.rbegin(), m_itemPath.rend(), '/').offset();
|
||||
m_itemName = m_itemPath.substr(lastSlash + 1);
|
||||
setRequiresConstantRefresh(false);
|
||||
}
|
||||
|
||||
ox::CRString SceneEditorImGui::itemName() const noexcept {
|
||||
return m_itemPath;
|
||||
}
|
||||
|
||||
ox::CRString SceneEditorImGui::itemDisplayName() const noexcept {
|
||||
return m_itemName;
|
||||
}
|
||||
|
||||
void SceneEditorImGui::draw(turbine::Context*) noexcept {
|
||||
const auto paneSize = ImGui::GetContentRegionAvail();
|
||||
const ox::Size fbSize{
|
||||
static_cast<int>(paneSize.x),
|
||||
static_cast<int>(paneSize.y)};
|
||||
m_view.draw(fbSize.width, fbSize.height);
|
||||
auto &fb = m_view.framebuffer();
|
||||
const uintptr_t buffId = fb.color.id;
|
||||
ImGui::Image(
|
||||
reinterpret_cast<void*>(buffId),
|
||||
paneSize,
|
||||
ImVec2(0, 1),
|
||||
ImVec2(1, 0));
|
||||
}
|
||||
|
||||
void SceneEditorImGui::onActivated() noexcept {
|
||||
oxLogError(m_view.setupScene());
|
||||
}
|
||||
|
||||
ox::Error SceneEditorImGui::saveItem() noexcept {
|
||||
const auto sctx = applicationData<studio::StudioContext>(*m_ctx);
|
||||
oxReturnError(sctx->project->writeObj(m_itemPath, &m_editor.scene()));
|
||||
oxReturnError(m_ctx->assetManager.setAsset(m_itemPath, m_editor.scene()));
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
44
src/nostalgia/modules/scene/src/studio/sceneeditor-imgui.hpp
Normal file
44
src/nostalgia/modules/scene/src/studio/sceneeditor-imgui.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <studio/studio.hpp>
|
||||
|
||||
#include <turbine/context.hpp>
|
||||
|
||||
#include "sceneeditor.hpp"
|
||||
#include "sceneeditorview.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
class SceneEditorImGui: public studio::Editor {
|
||||
|
||||
private:
|
||||
turbine::Context *m_ctx = nullptr;
|
||||
ox::String m_itemName;
|
||||
ox::String m_itemPath;
|
||||
SceneEditor m_editor;
|
||||
SceneEditorView m_view;
|
||||
|
||||
public:
|
||||
SceneEditorImGui(turbine::Context *ctx, ox::CRStringView path);
|
||||
|
||||
/**
|
||||
* Returns the name of item being edited.
|
||||
*/
|
||||
ox::CRString itemName() const noexcept final;
|
||||
|
||||
ox::CRString itemDisplayName() const noexcept final;
|
||||
|
||||
void draw(turbine::Context*) noexcept final;
|
||||
|
||||
void onActivated() noexcept override;
|
||||
|
||||
protected:
|
||||
ox::Error saveItem() noexcept final;
|
||||
|
||||
};
|
||||
|
||||
}
|
17
src/nostalgia/modules/scene/src/studio/sceneeditor.cpp
Normal file
17
src/nostalgia/modules/scene/src/studio/sceneeditor.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <keel/keel.hpp>
|
||||
|
||||
#include "sceneeditor.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
SceneEditor::SceneEditor(turbine::Context *ctx, ox::CRStringView path) {
|
||||
m_ctx = ctx;
|
||||
oxRequireT(scn, keel::readObj<SceneStatic>(m_ctx, path));
|
||||
m_scene = *scn;
|
||||
}
|
||||
|
||||
}
|
33
src/nostalgia/modules/scene/src/studio/sceneeditor.hpp
Normal file
33
src/nostalgia/modules/scene/src/studio/sceneeditor.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <turbine/context.hpp>
|
||||
|
||||
#include <nostalgia/scene/scene.hpp>
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
class SceneEditor {
|
||||
|
||||
private:
|
||||
turbine::Context *m_ctx = nullptr;
|
||||
ox::String m_itemName;
|
||||
ox::String m_itemPath;
|
||||
SceneStatic m_scene;
|
||||
|
||||
public:
|
||||
SceneEditor(turbine::Context *ctx, ox::CRStringView path);
|
||||
|
||||
const SceneStatic &scene() noexcept {
|
||||
return m_scene;
|
||||
}
|
||||
|
||||
protected:
|
||||
ox::Error saveItem() noexcept;
|
||||
|
||||
};
|
||||
|
||||
}
|
33
src/nostalgia/modules/scene/src/studio/sceneeditorview.cpp
Normal file
33
src/nostalgia/modules/scene/src/studio/sceneeditorview.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
|
||||
#include "sceneeditorview.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
SceneEditorView::SceneEditorView(turbine::Context *tctx, const SceneStatic &sceneStatic):
|
||||
m_sceneStatic(sceneStatic),
|
||||
m_scene(m_sceneStatic) {
|
||||
oxThrowError(core::init(tctx, {.glInstallDrawer = false}).moveTo(&m_cctx));
|
||||
}
|
||||
|
||||
ox::Error SceneEditorView::setupScene() noexcept {
|
||||
return m_scene.setupDisplay(m_cctx.get());
|
||||
}
|
||||
|
||||
void SceneEditorView::draw(int width, int height) noexcept {
|
||||
if (width != m_frameBuffer.width || height != m_frameBuffer.height) {
|
||||
glutils::resizeInitFrameBuffer(&m_frameBuffer, width, height);
|
||||
}
|
||||
const glutils::FrameBufferBind frameBufferBind(m_frameBuffer);
|
||||
core::gl::drawMainView(m_cctx.get(), {width, height});
|
||||
}
|
||||
|
||||
const glutils::FrameBuffer &SceneEditorView::framebuffer() const noexcept {
|
||||
return m_frameBuffer;
|
||||
}
|
||||
|
||||
}
|
34
src/nostalgia/modules/scene/src/studio/sceneeditorview.hpp
Normal file
34
src/nostalgia/modules/scene/src/studio/sceneeditorview.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glutils/glutils.hpp>
|
||||
|
||||
#include <nostalgia/core/context.hpp>
|
||||
#include <nostalgia/scene/scene.hpp>
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
class SceneEditorView {
|
||||
|
||||
private:
|
||||
ox::UPtr<core::Context> m_cctx;
|
||||
const SceneStatic &m_sceneStatic;
|
||||
Scene m_scene;
|
||||
glutils::FrameBuffer m_frameBuffer;
|
||||
|
||||
public:
|
||||
SceneEditorView(turbine::Context *ctx, const SceneStatic &sceneStatic);
|
||||
|
||||
ox::Error setupScene() noexcept;
|
||||
|
||||
void draw(int width, int height) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
const glutils::FrameBuffer &framebuffer() const noexcept;
|
||||
|
||||
};
|
||||
|
||||
}
|
38
src/nostalgia/modules/scene/src/studio/studiomodule.cpp
Normal file
38
src/nostalgia/modules/scene/src/studio/studiomodule.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <studio/studio.hpp>
|
||||
|
||||
#include "sceneeditor-imgui.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
class StudioModule: public studio::Module {
|
||||
public:
|
||||
ox::Vector<studio::EditorMaker> editors(turbine::Context *ctx) const noexcept override;
|
||||
ox::Vector<ox::UPtr<studio::ItemMaker>> itemMakers(turbine::Context*) const noexcept override;
|
||||
};
|
||||
|
||||
ox::Vector<studio::EditorMaker> StudioModule::editors(turbine::Context *ctx) const noexcept {
|
||||
return {
|
||||
{
|
||||
{"nscn"},
|
||||
[ctx](ox::CRStringView path) -> ox::Result<studio::BaseEditor*> {
|
||||
return ox::makeCatch<SceneEditorImGui>(ctx, path);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ox::Vector<ox::UPtr<studio::ItemMaker>> StudioModule::itemMakers(turbine::Context*) const noexcept {
|
||||
ox::Vector<ox::UPtr<studio::ItemMaker>> out;
|
||||
return out;
|
||||
}
|
||||
|
||||
static StudioModule mod;
|
||||
const studio::Module *studioModule() noexcept {
|
||||
return &mod;
|
||||
}
|
||||
|
||||
}
|
68
src/nostalgia/modules/scene/src/typeconv.cpp
Normal file
68
src/nostalgia/modules/scene/src/typeconv.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
#include <keel/media.hpp>
|
||||
|
||||
#include "typeconv.hpp"
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr unsigned adjustLayerAttachment(unsigned layer, unsigned attachment) noexcept {
|
||||
if (attachment == 0) {
|
||||
return layer;
|
||||
} else {
|
||||
return attachment - 1;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void setLayerAttachments(unsigned layer, const TileDoc &srcTile, SceneStatic::Tile &dstTile) noexcept {
|
||||
setTopEdge(
|
||||
dstTile.layerAttachments,
|
||||
adjustLayerAttachment(layer, srcTile.layerAttachments[0]));
|
||||
setBottomEdge(
|
||||
dstTile.layerAttachments,
|
||||
adjustLayerAttachment(layer, srcTile.layerAttachments[1]));
|
||||
setLeftEdge(
|
||||
dstTile.layerAttachments,
|
||||
adjustLayerAttachment(layer, srcTile.layerAttachments[2]));
|
||||
setRightEdge(
|
||||
dstTile.layerAttachments,
|
||||
adjustLayerAttachment(layer, srcTile.layerAttachments[3]));
|
||||
}
|
||||
|
||||
ox::Error SceneDocToSceneStaticConverter::convert(
|
||||
keel::Context *ctx,
|
||||
SceneDoc *src,
|
||||
SceneStatic *dst) const noexcept {
|
||||
oxRequire(ts, keel::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);
|
||||
setLayerAttachments(layerIdx, srcTile, dstTile);
|
||||
++tileIdx;
|
||||
}
|
||||
}
|
||||
++layerIdx;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
17
src/nostalgia/modules/scene/src/typeconv.hpp
Normal file
17
src/nostalgia/modules/scene/src/typeconv.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <keel/typeconv.hpp>
|
||||
|
||||
#include <nostalgia/scene/scenestatic.hpp>
|
||||
|
||||
namespace nostalgia::scene {
|
||||
|
||||
class SceneDocToSceneStaticConverter: public keel::Converter<SceneDoc, SceneStatic> {
|
||||
ox::Error convert(keel::Context*, SceneDoc *src, SceneStatic *dst) const noexcept final;
|
||||
};
|
||||
|
||||
}
|
Reference in New Issue
Block a user