[jasper/world] Cleanup, add frames to WorldObjectSetEditor
All checks were successful
Build / build (push) Successful in 3m42s
All checks were successful
Build / build (push) Successful in 3m42s
This commit is contained in:
parent
2b9609e308
commit
953edfa64a
@ -33,6 +33,7 @@ struct WorldObject {
|
||||
uint16_t palBank{};
|
||||
ncore::SubSheetId subsheetId{};
|
||||
CollisionMap collisionMap{};
|
||||
uint8_t frames{};
|
||||
uint8_t objectType{};
|
||||
uint8_t ext1{};
|
||||
uint8_t ext2{};
|
||||
@ -46,6 +47,7 @@ OX_MODEL_BEGIN(WorldObject)
|
||||
OX_MODEL_FIELD_RENAME(palBank, pal_bank)
|
||||
OX_MODEL_FIELD_RENAME(subsheetId, subsheet_id)
|
||||
OX_MODEL_FIELD_RENAME(collisionMap, collision_map)
|
||||
OX_MODEL_FIELD(frames)
|
||||
OX_MODEL_FIELD_RENAME(objectType, object_type)
|
||||
OX_MODEL_FIELD(ext1)
|
||||
OX_MODEL_FIELD(ext2)
|
||||
|
@ -2,7 +2,6 @@ target_sources(
|
||||
JasperWorld-Studio PRIVATE
|
||||
commands/addobject.cpp
|
||||
commands/rmobject.cpp
|
||||
commands/editobject.cpp
|
||||
commands/addpalette.cpp
|
||||
commands/rmpalette.cpp
|
||||
commands/changetilesheet.cpp
|
||||
|
@ -11,6 +11,7 @@ enum class WorldObjCommand {
|
||||
AddObject,
|
||||
RmObject,
|
||||
EditObjectName,
|
||||
EditObjectFrames,
|
||||
EditObjectInterval,
|
||||
EditObjectPalette,
|
||||
EditObjectSubSheet,
|
||||
|
@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include "commands.hpp"
|
||||
#include "editobject.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace jasper::world {
|
||||
|
||||
EditObjectName::EditObjectName(WorldObjectSet &doc, size_t objIdx, ox::String newName) noexcept:
|
||||
m_doc(doc),
|
||||
m_objIdx(objIdx),
|
||||
m_oldVal(m_doc.objects[objIdx].name),
|
||||
m_newVal(std::move(newName)) {
|
||||
}
|
||||
|
||||
ox::Error EditObjectName::redo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.name = std::move(m_newVal);
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error EditObjectName::undo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
m_newVal = std::move(obj.name);
|
||||
obj.name = m_oldVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
int EditObjectName::commandId() const noexcept {
|
||||
return static_cast<int>(WorldObjCommand::EditObjectName);
|
||||
}
|
||||
|
||||
bool EditObjectName::mergeWith(UndoCommand &cmd) noexcept {
|
||||
auto const en = dynamic_cast<EditObjectName const*>(&cmd);
|
||||
if (en && m_objIdx == en->m_objIdx) {
|
||||
m_newVal = en->m_newVal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
EditObjectInterval::EditObjectInterval(WorldObjectSet &doc, size_t objIdx, uint16_t newInterval) noexcept:
|
||||
m_doc(doc),
|
||||
m_objIdx(objIdx),
|
||||
m_oldVal(m_doc.objects[objIdx].intervalMs),
|
||||
m_newVal(newInterval) {}
|
||||
|
||||
ox::Error EditObjectInterval::redo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.intervalMs = m_newVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error EditObjectInterval::undo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.intervalMs = m_oldVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
int EditObjectInterval::commandId() const noexcept {
|
||||
return static_cast<int>(WorldObjCommand::EditObjectInterval);
|
||||
}
|
||||
|
||||
bool EditObjectInterval::mergeWith(UndoCommand &cmd) noexcept {
|
||||
auto const en = dynamic_cast<EditObjectInterval const*>(&cmd);
|
||||
if (en && m_objIdx == en->m_objIdx) {
|
||||
m_newVal = en->m_newVal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
EditObjectSubSheet::EditObjectSubSheet(
|
||||
WorldObjectSet &doc,
|
||||
size_t objIdx,
|
||||
ncore::SubSheetId subSheetId) noexcept:
|
||||
m_doc(doc),
|
||||
m_objIdx(objIdx),
|
||||
m_newVal(subSheetId),
|
||||
m_oldVal(m_doc.objects[m_objIdx].subsheetId) {
|
||||
}
|
||||
|
||||
ox::Error EditObjectSubSheet::redo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.subsheetId = m_newVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error EditObjectSubSheet::undo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.subsheetId = m_oldVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
int EditObjectSubSheet::commandId() const noexcept {
|
||||
return static_cast<int>(WorldObjCommand::EditObjectSubSheet);
|
||||
}
|
||||
|
||||
|
||||
EditObjectPalette::EditObjectPalette(WorldObjectSet &doc, size_t objIdx, uint16_t palBank) noexcept:
|
||||
m_doc(doc),
|
||||
m_objIdx(objIdx),
|
||||
m_oldVal(m_doc.objects[m_objIdx].palBank),
|
||||
m_newVal(palBank) {
|
||||
}
|
||||
|
||||
ox::Error EditObjectPalette::redo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.palBank = m_newVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error EditObjectPalette::undo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.palBank = m_oldVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int EditObjectPalette::commandId() const noexcept {
|
||||
return static_cast<int>(WorldObjCommand::EditObjectPalette);
|
||||
}
|
||||
|
||||
|
||||
EditObjectCollisionMap::EditObjectCollisionMap(WorldObjectSet &doc, size_t objIdx, CollisionMap colMap) noexcept:
|
||||
m_doc(doc),
|
||||
m_objIdx(objIdx),
|
||||
m_oldVal(m_doc.objects[m_objIdx].collisionMap),
|
||||
m_newVal(colMap) {
|
||||
}
|
||||
|
||||
ox::Error EditObjectCollisionMap::redo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.collisionMap = m_newVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error EditObjectCollisionMap::undo() noexcept {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
obj.collisionMap = m_oldVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int EditObjectCollisionMap::commandId() const noexcept {
|
||||
return static_cast<int>(WorldObjCommand::EditObjectCollisionMap);
|
||||
}
|
||||
|
||||
}
|
@ -10,78 +10,100 @@
|
||||
|
||||
#include <jasper/world/worldobject.hpp>
|
||||
|
||||
#include "commands.hpp"
|
||||
|
||||
namespace jasper::world {
|
||||
|
||||
class EditObjectName: public studio::UndoCommand {
|
||||
template<
|
||||
WorldObjCommand cmd, auto getVar, auto hasMerge = false,
|
||||
typename ValType = decltype([] { WorldObject o; return std::move(getVar(o)); }())>
|
||||
class EditObject: public studio::UndoCommand {
|
||||
private:
|
||||
WorldObjectSet &m_doc;
|
||||
size_t const m_objIdx{};
|
||||
ox::String const m_oldVal{};
|
||||
ox::String m_newVal{};
|
||||
ValType const m_oldVal{};
|
||||
ValType m_newVal{};
|
||||
public:
|
||||
EditObjectName(WorldObjectSet &doc, size_t objIdx, ox::String newName) noexcept;
|
||||
ox::Error redo() noexcept override;
|
||||
ox::Error undo() noexcept override;
|
||||
EditObject(WorldObjectSet &doc, size_t const objIdx, ValType newVal) noexcept:
|
||||
m_doc{doc},
|
||||
m_objIdx{objIdx},
|
||||
m_oldVal{getVar(m_doc.objects[objIdx])},
|
||||
m_newVal{std::move(newVal)} {}
|
||||
|
||||
ox::Error redo() noexcept override {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
if constexpr(!std::is_trivially_copy_assignable_v<ValType>) {
|
||||
getVar(obj) = std::move(m_newVal);
|
||||
} else {
|
||||
getVar(obj) = m_newVal;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error undo() noexcept override {
|
||||
auto &obj = m_doc.objects[m_objIdx];
|
||||
if constexpr(!std::is_trivially_copy_assignable_v<ValType>) {
|
||||
m_newVal = std::move(getVar(obj));
|
||||
}
|
||||
getVar(obj) = m_oldVal;
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override;
|
||||
bool mergeWith(UndoCommand &cmd) noexcept override;
|
||||
int commandId() const noexcept override {
|
||||
return static_cast<int>(cmd);
|
||||
}
|
||||
|
||||
bool mergeWith(UndoCommand &undoCmd) noexcept override {
|
||||
if constexpr(hasMerge) {
|
||||
auto const c = dynamic_cast<EditObject const*>(&undoCmd);
|
||||
if (c && m_objIdx == c->m_objIdx) {
|
||||
m_newVal = std::move(c->m_newVal);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class EditObjectInterval: public studio::UndoCommand {
|
||||
private:
|
||||
WorldObjectSet &m_doc;
|
||||
size_t const m_objIdx{};
|
||||
uint16_t const m_oldVal{};
|
||||
uint16_t m_newVal{};
|
||||
public:
|
||||
EditObjectInterval(WorldObjectSet &doc, size_t objIdx, uint16_t newName) noexcept;
|
||||
ox::Error redo() noexcept override;
|
||||
ox::Error undo() noexcept override;
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override;
|
||||
bool mergeWith(UndoCommand &cmd) noexcept override;
|
||||
};
|
||||
|
||||
class EditObjectSubSheet: public studio::UndoCommand {
|
||||
private:
|
||||
WorldObjectSet &m_doc;
|
||||
size_t const m_objIdx{};
|
||||
ncore::SubSheetId const m_newVal{};
|
||||
ncore::SubSheetId const m_oldVal{};
|
||||
public:
|
||||
EditObjectSubSheet(WorldObjectSet &doc, size_t objIdx, ncore::SubSheetId subSheetId) noexcept;
|
||||
ox::Error redo() noexcept override;
|
||||
ox::Error undo() noexcept override;
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override;
|
||||
};
|
||||
using EditObjectName = EditObject<
|
||||
WorldObjCommand::EditObjectName,
|
||||
[](WorldObject &obj) -> auto& {
|
||||
return obj.name;
|
||||
},
|
||||
true>;
|
||||
|
||||
class EditObjectPalette: public studio::UndoCommand {
|
||||
private:
|
||||
WorldObjectSet &m_doc;
|
||||
size_t const m_objIdx{};
|
||||
uint16_t const m_oldVal{};
|
||||
uint16_t const m_newVal{};
|
||||
public:
|
||||
EditObjectPalette(WorldObjectSet &doc, size_t objIdx, uint16_t palBank) noexcept;
|
||||
ox::Error redo() noexcept override;
|
||||
ox::Error undo() noexcept override;
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override;
|
||||
};
|
||||
using EditObjectFrames = EditObject<
|
||||
WorldObjCommand::EditObjectFrames,
|
||||
[](WorldObject &obj) -> auto& {
|
||||
return obj.frames;
|
||||
}>;
|
||||
|
||||
using EditObjectInterval = EditObject<
|
||||
WorldObjCommand::EditObjectInterval,
|
||||
[](WorldObject &obj) -> auto& {
|
||||
return obj.intervalMs;
|
||||
}>;
|
||||
|
||||
using EditObjectSubSheet = EditObject<
|
||||
WorldObjCommand::EditObjectSubSheet,
|
||||
[](WorldObject &obj) -> auto& {
|
||||
return obj.subsheetId;
|
||||
}>;
|
||||
|
||||
using EditObjectPalette = EditObject<
|
||||
WorldObjCommand::EditObjectPalette,
|
||||
[](WorldObject &obj) -> auto& {
|
||||
return obj.palBank;
|
||||
}>;
|
||||
|
||||
using EditObjectCollisionMap = EditObject<
|
||||
WorldObjCommand::EditObjectCollisionMap,
|
||||
[](WorldObject &obj) -> auto& {
|
||||
return obj.collisionMap;
|
||||
}>;
|
||||
|
||||
class EditObjectCollisionMap: public studio::UndoCommand {
|
||||
private:
|
||||
WorldObjectSet &m_doc;
|
||||
size_t const m_objIdx{};
|
||||
CollisionMap const m_oldVal{};
|
||||
CollisionMap const m_newVal{};
|
||||
public:
|
||||
EditObjectCollisionMap(WorldObjectSet &doc, size_t objIdx, CollisionMap colMap) noexcept;
|
||||
ox::Error redo() noexcept override;
|
||||
ox::Error undo() noexcept override;
|
||||
[[nodiscard]]
|
||||
int commandId() const noexcept override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -52,17 +52,17 @@ void WorldObjectSetEditorImGui::draw(studio::StudioContext&) noexcept {
|
||||
ImGui::BeginChild("Resources", {0, 0});
|
||||
{
|
||||
{
|
||||
ig::IDStackItem const idStackItem("TileSheetSelector");
|
||||
ig::IDStackItem const idStackItem{"TileSheetSelector"};
|
||||
drawTileSheetSelector();
|
||||
}
|
||||
ImGui::Separator();
|
||||
{
|
||||
ig::IDStackItem const idStackItem("ObjSelector");
|
||||
ig::IDStackItem const idStackItem{"ObjSelector"};
|
||||
drawObjSelector();
|
||||
}
|
||||
ImGui::Separator();
|
||||
{
|
||||
ig::IDStackItem const idStackItem("PaletteList");
|
||||
ig::IDStackItem const idStackItem{"PaletteList"};
|
||||
drawPaletteList();
|
||||
}
|
||||
}
|
||||
@ -132,6 +132,7 @@ void WorldObjectSetEditorImGui::loadObj() noexcept {
|
||||
auto &nameBuff = m_objEditor.nameBuff;
|
||||
ox::strncpy(nameBuff.data(), obj.name.data(), nameBuff.size());
|
||||
m_objEditor.palette = obj.palBank;
|
||||
m_objEditor.frames = obj.frames;
|
||||
m_objEditor.interval = obj.intervalMs;
|
||||
m_subsheet = getSubsheet(*m_tileSheet, obj.subsheetId);
|
||||
int w = 0;
|
||||
@ -160,8 +161,8 @@ static ox::Vec2 clickPos(ImVec2 const&imgSz, ImVec2 const&offset, ox::Vec2 click
|
||||
}
|
||||
|
||||
void WorldObjectSetEditorImGui::drawObjEditor() noexcept {
|
||||
ig::IDStackItem const idStackItem("ObjEditor");
|
||||
ig::IndentStackItem const indent1(10);
|
||||
ig::IDStackItem const idStackItem{"ObjEditor"};
|
||||
ig::IndentStackItem const indent1{10};
|
||||
ImGui::NewLine();
|
||||
auto &nameBuff = m_objEditor.nameBuff;
|
||||
if (ImGui::InputText("Name", nameBuff.data(), nameBuff.size())) {
|
||||
@ -177,6 +178,11 @@ void WorldObjectSetEditorImGui::drawObjEditor() noexcept {
|
||||
std::ignore = pushCommand<EditObjectPalette>(
|
||||
m_doc, m_selectedObj, static_cast<uint16_t>(m_objEditor.palette));
|
||||
}
|
||||
if (ImGui::InputInt("Frames", &m_objEditor.frames, 1)) {
|
||||
m_objEditor.frames = ox::max(m_objEditor.frames, 1);
|
||||
std::ignore = pushCommand<EditObjectFrames>(
|
||||
m_doc, m_selectedObj, static_cast<uint8_t>(m_objEditor.frames));
|
||||
}
|
||||
if (ImGui::InputInt("Interval (ms)", &m_objEditor.interval, 50, 1000)) {
|
||||
m_objEditor.interval = ox::clamp(m_objEditor.interval, 50, 65535);
|
||||
std::ignore = pushCommand<EditObjectInterval>(
|
||||
@ -197,7 +203,7 @@ void WorldObjectSetEditorImGui::drawObjEditor() noexcept {
|
||||
if (m_subsheet) {
|
||||
ImGui::NewLine();
|
||||
ImGui::Text("Collision Map:");
|
||||
ig::IndentStackItem const indent2(30);
|
||||
ig::IndentStackItem const indent2{30};
|
||||
m_colView.draw();
|
||||
auto const&fb = m_colView.framebuffer();
|
||||
uintptr_t const buffId = fb.color.id;
|
||||
@ -229,7 +235,7 @@ void WorldObjectSetEditorImGui::drawSubSheetNode(ncore::TileSheet::SubSheet cons
|
||||
auto constexpr dirFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
|
||||
auto &obj = activeObj();
|
||||
auto const selected = ss.id == obj.subsheetId ? ImGuiTreeNodeFlags_Selected : 0;
|
||||
ig::IDStackItem const idStackItem(ss.name);
|
||||
ig::IDStackItem const idStackItem{ss.name};
|
||||
if (!ss.subsheets.empty()) {
|
||||
if (ImGui::TreeNodeEx(ss.name.c_str(), dirFlags)) {
|
||||
for (auto const&child : ss.subsheets) {
|
||||
@ -246,7 +252,7 @@ void WorldObjectSetEditorImGui::drawSubSheetNode(ncore::TileSheet::SubSheet cons
|
||||
}
|
||||
|
||||
void WorldObjectSetEditorImGui::drawPaletteList() noexcept {
|
||||
ig::IDStackItem const idStackItem("PaletteList");
|
||||
ig::IDStackItem const idStackItem{"PaletteList"};
|
||||
if (ig::PushButton("+", btnSize)) {
|
||||
addPalette();
|
||||
}
|
||||
@ -265,7 +271,7 @@ void WorldObjectSetEditorImGui::drawPaletteList() noexcept {
|
||||
|
||||
void WorldObjectSetEditorImGui::drawPaletteListItems() noexcept {
|
||||
for (auto i = 0u; auto const&pal : m_doc.palettes) {
|
||||
ig::IDStackItem const idStackItem(static_cast<int>(i));
|
||||
ig::IDStackItem const idStackItem{static_cast<int>(i)};
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
auto const path
|
||||
@ -285,7 +291,7 @@ void WorldObjectSetEditorImGui::drawAddPalettePopup() noexcept {
|
||||
}
|
||||
auto constexpr popupName = ox::CStringView("Add Palette");
|
||||
auto constexpr popupSz = ImVec2{285.f, 0};
|
||||
ig::IDStackItem const idStackItem("AddPalette");
|
||||
ig::IDStackItem const idStackItem{"AddPalette"};
|
||||
if (ig::BeginPopup(m_sctx.tctx, popupName, m_addPalPopup.show, popupSz)) {
|
||||
auto const&palettes = m_sctx.project->fileList(ncore::FileExt_npal);
|
||||
ig::ComboBox("Palette", palettes, m_addPalPopup.selectedIdx);
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <turbine/context.hpp>
|
||||
#include <studio/studio.hpp>
|
||||
|
||||
#include <jasper/world/worldobject.hpp>
|
||||
@ -32,6 +31,7 @@ class WorldObjectSetEditorImGui: public studio::Editor {
|
||||
CollisionView m_colView{m_sctx};
|
||||
struct {
|
||||
ox::Buffer nameBuff = ox::Buffer(256);
|
||||
int frames{};
|
||||
int interval{};
|
||||
size_t palette{};
|
||||
} m_objEditor;
|
||||
|
@ -156,6 +156,7 @@ ox::Result<uint8_t> WorldStaticLoader::setupTileResrc(DocObjRef const&docObjRef)
|
||||
.cbbIdx = m_cbbIt,
|
||||
.tilesheetId = tsIdx,
|
||||
.tileCnt = static_cast<uint8_t>(subsheet->size()),
|
||||
.frames = obj->frames,
|
||||
});
|
||||
m_cbbIt += refSet.tileCnt;
|
||||
m_resourcesChanged = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user