[nostalgia] Add start for Scene editor in Studio
This commit is contained in:
parent
19d5641c6e
commit
ae9272841f
@ -2,8 +2,6 @@
|
|||||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ox/std/array.hpp>
|
|
||||||
|
|
||||||
#include <nostalgia/foundation/module.hpp>
|
#include <nostalgia/foundation/module.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/module.hpp>
|
#include <nostalgia/core/module.hpp>
|
||||||
@ -16,8 +14,8 @@ void loadModules() noexcept {
|
|||||||
if (modulesLoaded) {
|
if (modulesLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foundation::registerModule(&core::CoreModule::mod);
|
foundation::registerModule(core::module());
|
||||||
foundation::registerModule(&scene::SceneModule::mod);
|
foundation::registerModule(scene::module());
|
||||||
modulesLoaded = true;
|
modulesLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,12 +7,6 @@ add_library(
|
|||||||
typestore.cpp
|
typestore.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(
|
|
||||||
NostalgiaCore-Headless
|
|
||||||
headless/core.cpp
|
|
||||||
headless/gfx.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(NostalgiaCore)
|
add_library(NostalgiaCore)
|
||||||
|
|
||||||
if(NOT NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
|
if(NOT NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
|
||||||
@ -65,11 +59,6 @@ target_link_libraries(
|
|||||||
NostalgiaCore-Common
|
NostalgiaCore-Common
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
|
||||||
NostalgiaCore-Headless PUBLIC
|
|
||||||
NostalgiaCore-Common
|
|
||||||
)
|
|
||||||
|
|
||||||
if(NOSTALGIA_BUILD_STUDIO)
|
if(NOSTALGIA_BUILD_STUDIO)
|
||||||
add_subdirectory(studio)
|
add_subdirectory(studio)
|
||||||
endif()
|
endif()
|
||||||
@ -84,7 +73,9 @@ install(
|
|||||||
core.hpp
|
core.hpp
|
||||||
event.hpp
|
event.hpp
|
||||||
gfx.hpp
|
gfx.hpp
|
||||||
|
ptidxconv.hpp
|
||||||
input.hpp
|
input.hpp
|
||||||
|
tilesheet.hpp
|
||||||
typeconv.hpp
|
typeconv.hpp
|
||||||
typestore.hpp
|
typestore.hpp
|
||||||
DESTINATION
|
DESTINATION
|
||||||
@ -94,7 +85,6 @@ install(
|
|||||||
install(
|
install(
|
||||||
TARGETS
|
TARGETS
|
||||||
NostalgiaCore
|
NostalgiaCore
|
||||||
NostalgiaCore-Headless
|
|
||||||
DESTINATION
|
DESTINATION
|
||||||
LIBRARY DESTINATION lib/nostalgia
|
LIBRARY DESTINATION lib/nostalgia
|
||||||
ARCHIVE DESTINATION lib/nostalgia
|
ARCHIVE DESTINATION lib/nostalgia
|
||||||
|
@ -10,7 +10,7 @@ constexpr auto TileWidth = 8;
|
|||||||
constexpr auto TileHeight = 8;
|
constexpr auto TileHeight = 8;
|
||||||
constexpr auto PixelsPerTile = TileWidth * TileHeight;
|
constexpr auto PixelsPerTile = TileWidth * TileHeight;
|
||||||
|
|
||||||
constexpr auto FileExt_ng = ".ng";
|
constexpr auto FileExt_ng = "ng";
|
||||||
constexpr auto FileExt_npal = ".npal";
|
constexpr auto FileExt_npal = "npal";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,22 @@
|
|||||||
#include <ox/std/buffer.hpp>
|
#include <ox/std/buffer.hpp>
|
||||||
|
|
||||||
#include <nostalgia/foundation/context.hpp>
|
#include <nostalgia/foundation/context.hpp>
|
||||||
|
#include <nostalgia/geo/size.hpp>
|
||||||
|
|
||||||
#include "event.hpp"
|
#include "event.hpp"
|
||||||
#include "input.hpp"
|
#include "input.hpp"
|
||||||
|
|
||||||
|
namespace nostalgia::core::gl {
|
||||||
|
void drawMainView(core::Context*) noexcept;
|
||||||
|
void setRenderSize(core::Context*, int width, int height) noexcept;
|
||||||
|
geo::Size getRenderSize(core::Context*) noexcept;
|
||||||
|
void clearRenderSize(core::Context *ctx) noexcept;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace nostalgia::core::renderer {
|
||||||
|
ox::Error init(Context *ctx) noexcept;
|
||||||
|
}
|
||||||
|
|
||||||
namespace nostalgia::geo {
|
namespace nostalgia::geo {
|
||||||
class Size;
|
class Size;
|
||||||
}
|
}
|
||||||
@ -58,6 +70,7 @@ class Context: public foundation::Context {
|
|||||||
friend int getScreenHeight(Context *ctx) noexcept;
|
friend int getScreenHeight(Context *ctx) noexcept;
|
||||||
friend int getScreenWidth(Context *ctx) noexcept;
|
friend int getScreenWidth(Context *ctx) noexcept;
|
||||||
friend ox::Error initGfx(Context *ctx) noexcept;
|
friend ox::Error initGfx(Context *ctx) noexcept;
|
||||||
|
friend ox::Error renderer::init(Context *ctx) noexcept;
|
||||||
friend ox::Error loadBgTileSheet(Context *ctx,
|
friend ox::Error loadBgTileSheet(Context *ctx,
|
||||||
unsigned cbb,
|
unsigned cbb,
|
||||||
const ox::FileAddress &tilesheetPath,
|
const ox::FileAddress &tilesheetPath,
|
||||||
@ -92,6 +105,10 @@ class Context: public foundation::Context {
|
|||||||
unsigned spriteSize,
|
unsigned spriteSize,
|
||||||
unsigned flipX) noexcept;
|
unsigned flipX) noexcept;
|
||||||
friend void hideSprite(Context *ctx, unsigned idx) noexcept;
|
friend void hideSprite(Context *ctx, unsigned idx) noexcept;
|
||||||
|
friend void gl::drawMainView(core::Context*) noexcept;
|
||||||
|
friend void gl::setRenderSize(core::Context*, int width, int height) noexcept;
|
||||||
|
friend geo::Size gl::getRenderSize(core::Context*) noexcept;
|
||||||
|
friend void gl::clearRenderSize(core::Context *ctx) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ox::Vector<Drawer*, 5> drawers;
|
ox::Vector<Drawer*, 5> drawers;
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
void setMainViewEnabled(bool) noexcept;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
extern ox::Array<char, 128> charMap;
|
extern ox::Array<char, 128> charMap;
|
||||||
|
|
||||||
class Drawer {
|
class Drawer {
|
||||||
|
@ -216,9 +216,7 @@ ox::Error initGfx(Context *ctx) noexcept {
|
|||||||
ImGui_ImplGlfw_InitForOpenGL(id->window, true);
|
ImGui_ImplGlfw_InitForOpenGL(id->window, true);
|
||||||
}
|
}
|
||||||
themeImgui();
|
themeImgui();
|
||||||
void *rendererData = nullptr;
|
oxReturnError(renderer::init(ctx));
|
||||||
oxReturnError(renderer::init(ctx, &rendererData));
|
|
||||||
ctx->setRendererData(rendererData);
|
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <nostalgia/core/core.hpp>
|
|
||||||
#include <nostalgia/core/input.hpp>
|
|
||||||
|
|
||||||
namespace nostalgia::core {
|
|
||||||
|
|
||||||
ox::Result<ox::UniquePtr<Context>> init(ox::UniquePtr<ox::FileSystem>, ox::CRStringView) noexcept {
|
|
||||||
return OxError(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setUpdateHandler(Context*, UpdateHandler) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t ticksMs(Context*) noexcept {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool buttonDown(Context*, Key) noexcept {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <nostalgia/core/context.hpp>
|
|
||||||
#include <nostalgia/core/gfx.hpp>
|
|
||||||
|
|
||||||
namespace nostalgia::core {
|
|
||||||
|
|
||||||
ox::Error initGfx(Context*) noexcept {
|
|
||||||
return OxError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error shutdownGfx(Context*) noexcept {
|
|
||||||
return OxError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setWindowTitle(Context*, ox::CRStringView) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
void focusWindow(Context*) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
int getScreenWidth(Context*) noexcept {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getScreenHeight(Context*) noexcept {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
geo::Size getScreenSize(Context*) noexcept {
|
|
||||||
return {0, 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t bgStatus(Context*) noexcept {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBgStatus(Context*, uint32_t) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bgStatus(Context*, unsigned) noexcept {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBgStatus(Context*, unsigned, bool) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do NOT rely on Context in the GBA version of this function.
|
|
||||||
ox::Error initConsole(Context*) noexcept {
|
|
||||||
return OxError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error loadBgTileSheet(Context*,
|
|
||||||
int,
|
|
||||||
const ox::FileAddress&,
|
|
||||||
const ox::FileAddress&) noexcept {
|
|
||||||
return OxError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error loadSpriteTileSheet(Context*,
|
|
||||||
const ox::FileAddress&,
|
|
||||||
const ox::FileAddress&) noexcept {
|
|
||||||
return OxError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error loadBgPalette(Context*, int, const ox::FileAddress&) noexcept {
|
|
||||||
return OxError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error loadSpritePalette(Context*, int, const ox::FileAddress&) noexcept {
|
|
||||||
return OxError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do NOT use Context in the GBA version of this function.
|
|
||||||
void puts(Context*, int, int, ox::CRStringView) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTile(Context*, int, int, int, uint8_t) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do NOT use Context in the GBA version of this function.
|
|
||||||
void clearTileLayer(Context*, int) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]]
|
|
||||||
void hideSprite(Context*, unsigned) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSprite(Context*,
|
|
||||||
unsigned,
|
|
||||||
int,
|
|
||||||
int,
|
|
||||||
unsigned,
|
|
||||||
unsigned,
|
|
||||||
unsigned,
|
|
||||||
unsigned) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -14,8 +14,29 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
|
class CoreModule: public foundation::Module {
|
||||||
|
private:
|
||||||
|
NostalgiaPaletteToPaletteConverter nostalgiaPaletteToPaletteConverter;
|
||||||
|
TileSheetV1ToTileSheetConverter nostalgiaGraphicToTileSheetConverter;
|
||||||
|
TileSheetToCompactTileSheetConverter tileSheetToCompactTileSheetConverter;
|
||||||
|
TileSheetV2ToTileSheetConverter tileSheetV2ToTileSheetConverter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static CoreModule mod;
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::Vector<foundation::TypeDescGenerator> types() const noexcept override;
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::Vector<const foundation::BaseConverter*> converters() const noexcept override;
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::Vector<foundation::PackTransform> packTransforms() const noexcept override;
|
||||||
|
};
|
||||||
|
|
||||||
CoreModule CoreModule::mod;
|
CoreModule CoreModule::mod;
|
||||||
|
|
||||||
|
const foundation::Module *module() noexcept {
|
||||||
|
return &CoreModule::mod;
|
||||||
|
}
|
||||||
|
|
||||||
ox::Vector<foundation::TypeDescGenerator> CoreModule::types() const noexcept {
|
ox::Vector<foundation::TypeDescGenerator> CoreModule::types() const noexcept {
|
||||||
return {
|
return {
|
||||||
foundation::generateTypeDesc<TileSheetV1>,
|
foundation::generateTypeDesc<TileSheetV1>,
|
||||||
|
@ -6,25 +6,8 @@
|
|||||||
|
|
||||||
#include <nostalgia/foundation/module.hpp>
|
#include <nostalgia/foundation/module.hpp>
|
||||||
|
|
||||||
#include "typeconv.hpp"
|
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
class CoreModule: public foundation::Module {
|
const foundation::Module *module() noexcept;
|
||||||
private:
|
|
||||||
NostalgiaPaletteToPaletteConverter nostalgiaPaletteToPaletteConverter;
|
|
||||||
TileSheetV1ToTileSheetConverter nostalgiaGraphicToTileSheetConverter;
|
|
||||||
TileSheetToCompactTileSheetConverter tileSheetToCompactTileSheetConverter;
|
|
||||||
TileSheetV2ToTileSheetConverter tileSheetV2ToTileSheetConverter;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static CoreModule mod;
|
|
||||||
[[nodiscard]]
|
|
||||||
ox::Vector<foundation::TypeDescGenerator> types() const noexcept override;
|
|
||||||
[[nodiscard]]
|
|
||||||
ox::Vector<const foundation::BaseConverter*> converters() const noexcept override;
|
|
||||||
[[nodiscard]]
|
|
||||||
ox::Vector<foundation::PackTransform> packTransforms() const noexcept override;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,16 @@ namespace nostalgia::core {
|
|||||||
|
|
||||||
void ImGui_Impl_NewFrame() noexcept;
|
void ImGui_Impl_NewFrame() noexcept;
|
||||||
|
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
static bool mainViewEnabled = true;
|
||||||
|
|
||||||
|
void setMainViewEnabled(bool enabled) noexcept {
|
||||||
|
mainViewEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace renderer {
|
namespace renderer {
|
||||||
|
|
||||||
constexpr uint64_t TileRows = 128;
|
constexpr uint64_t TileRows = 128;
|
||||||
@ -67,6 +77,7 @@ struct GlImplData {
|
|||||||
SpriteBlockset spriteBlocks;
|
SpriteBlockset spriteBlocks;
|
||||||
ox::Array<Sprite, 128> spriteStates;
|
ox::Array<Sprite, 128> spriteStates;
|
||||||
ox::Array<Background, 4> backgrounds;
|
ox::Array<Background, 4> backgrounds;
|
||||||
|
ox::Optional<geo::Size> renderSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr ox::StringView bgvshadTmpl = R"(
|
constexpr ox::StringView bgvshadTmpl = R"(
|
||||||
@ -74,9 +85,13 @@ constexpr ox::StringView bgvshadTmpl = R"(
|
|||||||
in vec2 vTexCoord;
|
in vec2 vTexCoord;
|
||||||
in vec2 vPosition;
|
in vec2 vPosition;
|
||||||
out vec2 fTexCoord;
|
out vec2 fTexCoord;
|
||||||
|
uniform float vXScale;
|
||||||
uniform float vTileHeight;
|
uniform float vTileHeight;
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(vPosition, 0.0, 1.0);
|
float xScaleInvert = 1.0 - vXScale;
|
||||||
|
gl_Position = vec4(
|
||||||
|
vPosition.x * vXScale - xScaleInvert, vPosition.y,
|
||||||
|
0.0, 1.0);
|
||||||
fTexCoord = vTexCoord * vec2(1, vTileHeight);
|
fTexCoord = vTexCoord * vec2(1, vTileHeight);
|
||||||
})";
|
})";
|
||||||
|
|
||||||
@ -98,9 +113,13 @@ constexpr ox::StringView spritevshadTmpl = R"(
|
|||||||
in vec2 vTexCoord;
|
in vec2 vTexCoord;
|
||||||
in vec2 vPosition;
|
in vec2 vPosition;
|
||||||
out vec2 fTexCoord;
|
out vec2 fTexCoord;
|
||||||
|
uniform float vXScale;
|
||||||
uniform float vTileHeight;
|
uniform float vTileHeight;
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(vPosition, 0.0, 1.0);
|
float xScaleInvert = 1.0 - vXScale;
|
||||||
|
gl_Position = vec4(
|
||||||
|
vPosition.x * vXScale - xScaleInvert, vPosition.y,
|
||||||
|
0.0, 1.0);
|
||||||
fTexCoord = vTexCoord * vec2(1, vTileHeight) * vec2(vEnabled, vEnabled);
|
fTexCoord = vTexCoord * vec2(1, vTileHeight) * vec2(vEnabled, vEnabled);
|
||||||
})";
|
})";
|
||||||
|
|
||||||
@ -111,7 +130,7 @@ static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept {
|
|||||||
return y * TileRows + x;
|
return y * TileRows + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setSpriteBufferObject(Context *ctx,
|
static void setSpriteBufferObject(Context*,
|
||||||
unsigned vi,
|
unsigned vi,
|
||||||
float enabled,
|
float enabled,
|
||||||
float x, float y,
|
float x, float y,
|
||||||
@ -120,9 +139,8 @@ static void setSpriteBufferObject(Context *ctx,
|
|||||||
float *vbo,
|
float *vbo,
|
||||||
GLuint *ebo) noexcept {
|
GLuint *ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
const auto [sw, sh] = getScreenSize(ctx);
|
constexpr float xmod = 0.1f;
|
||||||
constexpr float ymod = 0.1f;
|
constexpr float ymod = 0.1f;
|
||||||
const auto xmod = ymod * static_cast<float>(sh) / static_cast<float>(sw);
|
|
||||||
x *= xmod;
|
x *= xmod;
|
||||||
y *= -ymod;
|
y *= -ymod;
|
||||||
x -= 1.f;
|
x -= 1.f;
|
||||||
@ -144,7 +162,7 @@ static void setSpriteBufferObject(Context *ctx,
|
|||||||
memcpy(ebo, elms.data(), sizeof(elms));
|
memcpy(ebo, elms.data(), sizeof(elms));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setTileBufferObject(Context *ctx,
|
static void setTileBufferObject(Context*,
|
||||||
unsigned vi,
|
unsigned vi,
|
||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
@ -152,9 +170,8 @@ static void setTileBufferObject(Context *ctx,
|
|||||||
float *vbo,
|
float *vbo,
|
||||||
GLuint *ebo) noexcept {
|
GLuint *ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
const auto [sw, sh] = getScreenSize(ctx);
|
constexpr float ymod = 0.1f;
|
||||||
constexpr float ymod = 2.0f / 20.0f;
|
constexpr float xmod = 0.1f;
|
||||||
const float xmod = ymod * static_cast<float>(sh) / static_cast<float>(sw);
|
|
||||||
x *= xmod;
|
x *= xmod;
|
||||||
y *= -ymod;
|
y *= -ymod;
|
||||||
x -= 1.0f;
|
x -= 1.0f;
|
||||||
@ -279,11 +296,15 @@ static void drawBackground(CBB *cbb) noexcept {
|
|||||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(cbb->elements.size()), GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(cbb->elements.size()), GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawBackgrounds(GlImplData *id) noexcept {
|
static void drawBackgrounds(core::Context *ctx, GlImplData *id) noexcept {
|
||||||
// load background shader and its uniforms
|
// load background shader and its uniforms
|
||||||
glUseProgram(id->bgShader);
|
glUseProgram(id->bgShader);
|
||||||
|
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vXScale"));
|
||||||
const auto uniformTileHeight = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vTileHeight"));
|
const auto uniformTileHeight = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vTileHeight"));
|
||||||
//glUniform3fv(uniformPalette, GlImplData::ColorCnt, id->palette.data());
|
const auto [wi, hi] = gl::getRenderSize(ctx);
|
||||||
|
const auto wf = static_cast<float>(wi);
|
||||||
|
const auto hf = static_cast<float>(hi);
|
||||||
|
glUniform1f(uniformXScale, hf / wf);
|
||||||
for (const auto &bg : id->backgrounds) {
|
for (const auto &bg : id->backgrounds) {
|
||||||
if (bg.enabled) {
|
if (bg.enabled) {
|
||||||
auto &cbb = id->cbbs[bg.cbbIdx];
|
auto &cbb = id->cbbs[bg.cbbIdx];
|
||||||
@ -294,10 +315,15 @@ static void drawBackgrounds(GlImplData *id) noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawSprites(GlImplData *id) noexcept {
|
static void drawSprites(core::Context *ctx, GlImplData *id) noexcept {
|
||||||
glUseProgram(id->spriteShader);
|
glUseProgram(id->spriteShader);
|
||||||
auto &sb = id->spriteBlocks;
|
auto &sb = id->spriteBlocks;
|
||||||
|
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vXScale"));
|
||||||
const auto uniformTileHeight = static_cast<GLint>(glGetUniformLocation(id->spriteShader, "vTileHeight"));
|
const auto uniformTileHeight = static_cast<GLint>(glGetUniformLocation(id->spriteShader, "vTileHeight"));
|
||||||
|
const auto [wi, hi] = gl::getRenderSize(ctx);
|
||||||
|
const auto wf = static_cast<float>(wi);
|
||||||
|
const auto hf = static_cast<float>(hi);
|
||||||
|
glUniform1f(uniformXScale, hf / wf);
|
||||||
// update vbo
|
// update vbo
|
||||||
glBindVertexArray(sb.vao);
|
glBindVertexArray(sb.vao);
|
||||||
if (sb.updated) {
|
if (sb.updated) {
|
||||||
@ -312,7 +338,7 @@ static void drawSprites(GlImplData *id) noexcept {
|
|||||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sb.elements.size()), GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sb.elements.size()), GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error init(Context *ctx, void **rendererData) noexcept {
|
ox::Error init(Context *ctx) noexcept {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
const auto bgVshad = ox::sfmt(bgvshadTmpl, glutils::GlslVersion);
|
const auto bgVshad = ox::sfmt(bgvshadTmpl, glutils::GlslVersion);
|
||||||
@ -320,7 +346,7 @@ ox::Error init(Context *ctx, void **rendererData) noexcept {
|
|||||||
const auto spriteVshad = ox::sfmt(spritevshadTmpl, glutils::GlslVersion);
|
const auto spriteVshad = ox::sfmt(spritevshadTmpl, glutils::GlslVersion);
|
||||||
const auto spriteFshad = ox::sfmt(spritefshadTmpl, glutils::GlslVersion);
|
const auto spriteFshad = ox::sfmt(spritefshadTmpl, glutils::GlslVersion);
|
||||||
const auto id = ox::make<GlImplData>();
|
const auto id = ox::make<GlImplData>();
|
||||||
*rendererData = id;
|
ctx->setRendererData(id);
|
||||||
oxReturnError(glutils::buildShaderProgram(bgVshad.c_str(), bgFshad.c_str()).moveTo(&id->bgShader));
|
oxReturnError(glutils::buildShaderProgram(bgVshad.c_str(), bgFshad.c_str()).moveTo(&id->bgShader));
|
||||||
oxReturnError(glutils::buildShaderProgram(spriteVshad.c_str(), spriteFshad.c_str()).moveTo(&id->spriteShader));
|
oxReturnError(glutils::buildShaderProgram(spriteVshad.c_str(), spriteFshad.c_str()).moveTo(&id->spriteShader));
|
||||||
for (auto &bg : id->cbbs) {
|
for (auto &bg : id->cbbs) {
|
||||||
@ -328,7 +354,7 @@ ox::Error init(Context *ctx, void **rendererData) noexcept {
|
|||||||
}
|
}
|
||||||
initSpritesBufferset(ctx, id->spriteShader, &id->spriteBlocks);
|
initSpritesBufferset(ctx, id->spriteShader, &id->spriteBlocks);
|
||||||
ImGui_ImplOpenGL3_Init(glutils::GlslVersion);
|
ImGui_ImplOpenGL3_Init(glutils::GlslVersion);
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown(Context*, void *rendererData) noexcept {
|
void shutdown(Context*, void *rendererData) noexcept {
|
||||||
@ -422,9 +448,8 @@ void draw(Context *ctx) noexcept {
|
|||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
// render
|
// render
|
||||||
renderer::drawBackgrounds(id);
|
if (gl::mainViewEnabled) {
|
||||||
if (id->spriteBlocks.tex) {
|
gl::drawMainView(ctx);
|
||||||
renderer::drawSprites(id);
|
|
||||||
}
|
}
|
||||||
for (const auto cd : ctx->drawers) {
|
for (const auto cd : ctx->drawers) {
|
||||||
cd->draw(ctx);
|
cd->draw(ctx);
|
||||||
@ -530,4 +555,35 @@ void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) no
|
|||||||
bg.updated = true;
|
bg.updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
void drawMainView(core::Context *ctx) noexcept {
|
||||||
|
const auto id = ctx->rendererData<renderer::GlImplData>();
|
||||||
|
renderer::drawBackgrounds(ctx, id);
|
||||||
|
if (id->spriteBlocks.tex) {
|
||||||
|
renderer::drawSprites(ctx, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRenderSize(core::Context *ctx, int width, int height) noexcept {
|
||||||
|
const auto id = ctx->rendererData<renderer::GlImplData>();
|
||||||
|
id->renderSize.emplace(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearRenderSize(core::Context *ctx) noexcept {
|
||||||
|
auto id = ctx->rendererData<renderer::GlImplData>();
|
||||||
|
id->renderSize.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
geo::Size getRenderSize(core::Context *ctx) noexcept {
|
||||||
|
const auto id = ctx->rendererData<renderer::GlImplData>();
|
||||||
|
if (id->renderSize.has_value()) {
|
||||||
|
return id->renderSize.value();
|
||||||
|
} else {
|
||||||
|
return core::getScreenSize(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,19 +11,20 @@ ox::Result<ox::UUID> readUuidHeader(const ox::Buffer &buff) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Result<ox::UUID> readUuidHeader(const char *buff, std::size_t buffLen) noexcept {
|
ox::Result<ox::UUID> readUuidHeader(const char *buff, std::size_t buffLen) noexcept {
|
||||||
if (buffLen < 40) {
|
if (buffLen < N1HdrSz) {
|
||||||
return OxError(1, "Insufficient data contain complete Nostalgia header");
|
return OxError(1, "Insufficient data to contain complete Nostalgia header");
|
||||||
}
|
}
|
||||||
if (ox_memcmp(buff, "N1;", 3) != 0) {
|
ox::StringView n1Hdr = "N1;";
|
||||||
return OxError(2, "No Nostalgia header data");
|
if (n1Hdr == buff) {
|
||||||
|
return OxError(2, "No Nostalgia asset header data");
|
||||||
}
|
}
|
||||||
return ox::UUID::fromString(ox::StringView(buff + 3, 36));
|
return ox::UUID::fromString(ox::StringView(buff + n1Hdr.bytes(), 36));
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Result<ox::ModelObject> readAsset(ox::TypeStore *ts, const ox::Buffer &buff) noexcept {
|
ox::Result<ox::ModelObject> readAsset(ox::TypeStore *ts, const ox::Buffer &buff) noexcept {
|
||||||
std::size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
if (!readUuidHeader(buff).error) {
|
if (!readUuidHeader(buff).error) {
|
||||||
offset = 40; // the size of N1 headers
|
offset = N1HdrSz;
|
||||||
}
|
}
|
||||||
return ox::readClaw(ts, buff.data() + offset, buff.size() - offset);
|
return ox::readClaw(ts, buff.data() + offset, buff.size() - offset);
|
||||||
}
|
}
|
||||||
@ -31,7 +32,7 @@ ox::Result<ox::ModelObject> readAsset(ox::TypeStore *ts, const ox::Buffer &buff)
|
|||||||
ox::Result<AssetHdr> readAssetHeader(const char *buff, std::size_t buffLen) noexcept {
|
ox::Result<AssetHdr> readAssetHeader(const char *buff, std::size_t buffLen) noexcept {
|
||||||
AssetHdr out;
|
AssetHdr out;
|
||||||
const auto err = readUuidHeader(buff, buffLen).moveTo(&out.uuid);
|
const auto err = readUuidHeader(buff, buffLen).moveTo(&out.uuid);
|
||||||
const auto offset = err ? 0 : 40;
|
const auto offset = err ? 0 : N1HdrSz;
|
||||||
buff = buff + offset;
|
buff = buff + offset;
|
||||||
buffLen = buffLen - offset;
|
buffLen = buffLen - offset;
|
||||||
oxReturnError(ox::readClawHeader(buff, buffLen).moveTo(&out.clawHdr));
|
oxReturnError(ox::readClawHeader(buff, buffLen).moveTo(&out.clawHdr));
|
||||||
|
@ -9,17 +9,16 @@
|
|||||||
#include <ox/claw/claw.hpp>
|
#include <ox/claw/claw.hpp>
|
||||||
#include <ox/fs/fs.hpp>
|
#include <ox/fs/fs.hpp>
|
||||||
|
|
||||||
#include <nostalgia/foundation/context.hpp>
|
|
||||||
|
|
||||||
namespace nostalgia::foundation {
|
namespace nostalgia::foundation {
|
||||||
|
|
||||||
[[nodiscard]]
|
constexpr auto N1HdrSz = 40;
|
||||||
|
|
||||||
ox::Result<ox::UUID> readUuidHeader(const ox::Buffer &buff) noexcept;
|
ox::Result<ox::UUID> readUuidHeader(const ox::Buffer &buff) noexcept;
|
||||||
|
|
||||||
ox::Result<ox::UUID> readUuidHeader(const char *buff, std::size_t buffLen) noexcept;
|
ox::Result<ox::UUID> readUuidHeader(const char *buff, std::size_t buffLen) noexcept;
|
||||||
|
|
||||||
ox::Error writeUuidHeader(ox::Writer_c auto *writer, const ox::UUID &uuid) noexcept {
|
ox::Error writeUuidHeader(ox::Writer_c auto *writer, const ox::UUID &uuid) noexcept {
|
||||||
const auto hdr = ox::sfmt<ox::BString<40>>("N1;{};", uuid.toString());
|
const auto hdr = ox::sfmt<ox::BString<N1HdrSz>>("N1;{};", uuid.toString());
|
||||||
return write(writer, hdr);
|
return write(writer, hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +27,7 @@ ox::Result<T> readAsset(const ox::Buffer &buff) noexcept {
|
|||||||
std::size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
const auto err = readUuidHeader(buff).error;
|
const auto err = readUuidHeader(buff).error;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
offset = 40; // the size of N1 headers
|
offset = N1HdrSz; // the size of N1 headers
|
||||||
}
|
}
|
||||||
return ox::readClaw<T>(buff.data() + offset, buff.size() - offset);
|
return ox::readClaw<T>(buff.data() + offset, buff.size() - offset);
|
||||||
}
|
}
|
||||||
|
@ -41,10 +41,12 @@ class AssetContainer {
|
|||||||
AssetContainer& operator=(AssetContainer&) = delete;
|
AssetContainer& operator=(AssetContainer&) = delete;
|
||||||
AssetContainer& operator=(AssetContainer&&) = delete;
|
AssetContainer& operator=(AssetContainer&&) = delete;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr T *get() noexcept {
|
constexpr T *get() noexcept {
|
||||||
return &m_obj;
|
return &m_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr const T *get() const noexcept {
|
constexpr const T *get() const noexcept {
|
||||||
return &m_obj;
|
return &m_obj;
|
||||||
}
|
}
|
||||||
@ -66,6 +68,7 @@ class AssetContainer {
|
|||||||
--m_references;
|
--m_references;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr int references() const noexcept {
|
constexpr int references() const noexcept {
|
||||||
return m_references;
|
return m_references;
|
||||||
}
|
}
|
||||||
@ -92,6 +95,7 @@ class AssetRef: public ox::SignalHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
constexpr const T *get() const noexcept {
|
constexpr const T *get() const noexcept {
|
||||||
if (m_ctr) {
|
if (m_ctr) {
|
||||||
return m_ctr->get();
|
return m_ctr->get();
|
||||||
|
@ -17,9 +17,8 @@ ox::Result<ox::UPtr<Ctx>> init(ox::UPtr<ox::FileSystem> &&fs, ox::CRStringView a
|
|||||||
auto ctx = ox::make_unique<Ctx>();
|
auto ctx = ox::make_unique<Ctx>();
|
||||||
ctx->appName = appName;
|
ctx->appName = appName;
|
||||||
oxIgnoreError(setRomFs(ctx.get(), std::move(fs)));
|
oxIgnoreError(setRomFs(ctx.get(), std::move(fs)));
|
||||||
auto mods = modules();
|
const auto &mods = modules();
|
||||||
if (mods) {
|
for (auto &mod : mods) {
|
||||||
for (auto &mod : *mods) {
|
|
||||||
// register type converters
|
// register type converters
|
||||||
for (auto c : mod->converters()) {
|
for (auto c : mod->converters()) {
|
||||||
ctx->converters.emplace_back(c);
|
ctx->converters.emplace_back(c);
|
||||||
@ -29,7 +28,6 @@ ox::Result<ox::UPtr<Ctx>> init(ox::UPtr<ox::FileSystem> &&fs, ox::CRStringView a
|
|||||||
ctx->packTransforms.emplace_back(c);
|
ctx->packTransforms.emplace_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ void registerModule(const Module *mod) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
const ox::Vector<const Module*> *modules() noexcept {
|
const ox::Vector<const Module*> &modules() noexcept {
|
||||||
return &mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +38,6 @@ class Module {
|
|||||||
void registerModule(const Module *mod) noexcept;
|
void registerModule(const Module *mod) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
const ox::Vector<const foundation::Module*> *modules() noexcept;
|
const ox::Vector<const foundation::Module*> &modules() noexcept;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ ox::Result<ox::Buffer> convertBuffToBuff(foundation::Context *ctx, const ox::Buf
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal>
|
template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal>
|
||||||
auto transformRule(foundation::Context *ctx, ox::Buffer *buff) -> ox::Error {
|
auto transformRule(foundation::Context *ctx, ox::Buffer *buff) noexcept -> ox::Error {
|
||||||
oxRequire(hdr, readAssetHeader(*buff));
|
oxRequire(hdr, readAssetHeader(*buff));
|
||||||
const auto typeId = ox::buildTypeId(
|
const auto typeId = ox::buildTypeId(
|
||||||
hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams);
|
hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nostalgia/core/core.hpp>
|
#include <nostalgia/core/core.hpp>
|
||||||
#include <nostalgia/foundation/media.hpp>
|
|
||||||
#include <nostalgia/scene/scene.hpp>
|
#include <nostalgia/scene/scene.hpp>
|
||||||
|
|
||||||
using namespace nostalgia;
|
using namespace nostalgia;
|
||||||
@ -37,7 +36,7 @@ ox::Error run(ox::UniquePtr<ox::FileSystem> fs) noexcept {
|
|||||||
oxRequire(scn, foundation::readObj<scene::SceneStatic>(ctx.get(), SceneAddr));
|
oxRequire(scn, foundation::readObj<scene::SceneStatic>(ctx.get(), SceneAddr));
|
||||||
core::setUpdateHandler(ctx.get(), updateHandler);
|
core::setUpdateHandler(ctx.get(), updateHandler);
|
||||||
core::setKeyEventHandler(ctx.get(), keyEventHandler);
|
core::setKeyEventHandler(ctx.get(), keyEventHandler);
|
||||||
s_scene.emplace(scn.get());
|
s_scene.emplace(*scn);
|
||||||
oxReturnError(s_scene->setupDisplay(ctx.get()));
|
oxReturnError(s_scene->setupDisplay(ctx.get()));
|
||||||
return core::run(ctx.get());
|
return core::run(ctx.get());
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <ox/logconn/logconn.hpp>
|
#include <ox/logconn/logconn.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/core.hpp>
|
#include <nostalgia/core/core.hpp>
|
||||||
#include <nostalgia/foundation/media.hpp>
|
|
||||||
|
|
||||||
#include <nostalgia/appmodules/appmodules.hpp>
|
#include <nostalgia/appmodules/appmodules.hpp>
|
||||||
|
|
||||||
|
@ -22,6 +22,6 @@ install(
|
|||||||
include/nostalgia/scene
|
include/nostalgia/scene
|
||||||
)
|
)
|
||||||
|
|
||||||
#if(NOSTALGIA_BUILD_STUDIO)
|
if(NOSTALGIA_BUILD_STUDIO)
|
||||||
# add_subdirectory(studio)
|
add_subdirectory(studio)
|
||||||
#endif()
|
endif()
|
||||||
|
@ -8,25 +8,25 @@
|
|||||||
|
|
||||||
namespace nostalgia::scene {
|
namespace nostalgia::scene {
|
||||||
|
|
||||||
Scene::Scene(const SceneStatic *sceneStatic) noexcept:
|
Scene::Scene(const SceneStatic &sceneStatic) noexcept:
|
||||||
m_sceneStatic(sceneStatic) {
|
m_sceneStatic(sceneStatic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error Scene::setupDisplay(core::Context *ctx) noexcept {
|
ox::Error Scene::setupDisplay(core::Context *ctx) noexcept {
|
||||||
if (m_sceneStatic->palettes.empty()) {
|
if (m_sceneStatic.palettes.empty()) {
|
||||||
return OxError(1, "Scene has no palettes");
|
return OxError(1, "Scene has no palettes");
|
||||||
}
|
}
|
||||||
const auto &palette = m_sceneStatic->palettes[0];
|
const auto &palette = m_sceneStatic.palettes[0];
|
||||||
oxReturnError(core::loadBgTileSheet(
|
oxReturnError(core::loadBgTileSheet(
|
||||||
ctx, 0, m_sceneStatic->tilesheet, palette));
|
ctx, 0, m_sceneStatic.tilesheet, palette));
|
||||||
// disable all backgrounds
|
// disable all backgrounds
|
||||||
core::setBgStatus(ctx, 0);
|
core::setBgStatus(ctx, 0);
|
||||||
for (auto layerNo = 0u; const auto &layer : m_sceneStatic->tileMapIdx) {
|
for (auto layerNo = 0u; const auto &layer : m_sceneStatic.tileMapIdx) {
|
||||||
core::setBgStatus(ctx, layerNo, true);
|
core::setBgStatus(ctx, layerNo, true);
|
||||||
core::setBgCbb(ctx, layerNo, 0);
|
core::setBgCbb(ctx, layerNo, 0);
|
||||||
auto x = 0;
|
auto x = 0;
|
||||||
auto y = 0;
|
auto y = 0;
|
||||||
auto width = m_sceneStatic->rows[layerNo];
|
auto width = m_sceneStatic.rows[layerNo];
|
||||||
for (const auto &tile : layer) {
|
for (const auto &tile : layer) {
|
||||||
core::setTile(ctx, layerNo, x, y, tile);
|
core::setTile(ctx, layerNo, x, y, tile);
|
||||||
core::setTile(ctx, layerNo, x + 1, y, tile + 1);
|
core::setTile(ctx, layerNo, x + 1, y, tile + 1);
|
||||||
|
@ -10,10 +10,10 @@ namespace nostalgia::scene {
|
|||||||
|
|
||||||
class Scene {
|
class Scene {
|
||||||
private:
|
private:
|
||||||
const SceneStatic *m_sceneStatic = nullptr;
|
const SceneStatic &m_sceneStatic;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Scene(const SceneStatic *sceneStatic) noexcept;
|
explicit Scene(const SceneStatic &sceneStatic) noexcept;
|
||||||
|
|
||||||
ox::Error setupDisplay(core::Context *ctx) noexcept;
|
ox::Error setupDisplay(core::Context *ctx) noexcept;
|
||||||
|
|
||||||
|
@ -5,29 +5,44 @@
|
|||||||
#include <ox/model/model.hpp>
|
#include <ox/model/model.hpp>
|
||||||
|
|
||||||
#include "scenestatic.hpp"
|
#include "scenestatic.hpp"
|
||||||
|
#include "typeconv.hpp"
|
||||||
|
|
||||||
#include "scenemodule.hpp"
|
#include "scenemodule.hpp"
|
||||||
|
|
||||||
namespace nostalgia::scene {
|
namespace nostalgia::scene {
|
||||||
|
|
||||||
SceneModule SceneModule::mod;
|
class SceneModule: public foundation::Module {
|
||||||
|
private:
|
||||||
|
SceneDocToSceneStaticConverter sceneDocToSceneStaticConverter;
|
||||||
|
|
||||||
ox::Vector<foundation::TypeDescGenerator> SceneModule::types() const noexcept {
|
public:
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::Vector<foundation::TypeDescGenerator> types() const noexcept override {
|
||||||
return {
|
return {
|
||||||
foundation::generateTypeDesc<SceneDoc>,
|
foundation::generateTypeDesc<SceneDoc>,
|
||||||
foundation::generateTypeDesc<SceneStatic>,
|
foundation::generateTypeDesc<SceneStatic>,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Vector<const foundation::BaseConverter*> SceneModule::converters() const noexcept {
|
[[nodiscard]]
|
||||||
|
ox::Vector<const foundation::BaseConverter*> converters() const noexcept override {
|
||||||
return {
|
return {
|
||||||
&sceneDocToSceneStaticConverter,
|
&sceneDocToSceneStaticConverter,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Vector<foundation::PackTransform> SceneModule::packTransforms() const noexcept {
|
[[nodiscard]]
|
||||||
|
ox::Vector<foundation::PackTransform> packTransforms() const noexcept override {
|
||||||
return {
|
return {
|
||||||
foundation::transformRule<SceneDoc, SceneStatic>,
|
foundation::transformRule<SceneDoc, SceneStatic>,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static SceneModule mod;
|
||||||
|
const foundation::Module *module() noexcept {
|
||||||
|
return &mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,22 +6,8 @@
|
|||||||
|
|
||||||
#include <nostalgia/foundation/module.hpp>
|
#include <nostalgia/foundation/module.hpp>
|
||||||
|
|
||||||
#include "typeconv.hpp"
|
|
||||||
|
|
||||||
namespace nostalgia::scene {
|
namespace nostalgia::scene {
|
||||||
|
|
||||||
class SceneModule: public foundation::Module {
|
const foundation::Module *module() noexcept;
|
||||||
private:
|
|
||||||
SceneDocToSceneStaticConverter sceneDocToSceneStaticConverter;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static SceneModule mod;
|
|
||||||
[[nodiscard]]
|
|
||||||
ox::Vector<foundation::TypeDescGenerator> types() const noexcept override;
|
|
||||||
[[nodiscard]]
|
|
||||||
ox::Vector<const foundation::BaseConverter*> converters() const noexcept override;
|
|
||||||
[[nodiscard]]
|
|
||||||
ox::Vector<foundation::PackTransform> packTransforms() const noexcept override;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,17 @@
|
|||||||
|
|
||||||
namespace nostalgia::scene {
|
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 {
|
struct TileDoc {
|
||||||
|
|
||||||
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.TileDoc";
|
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.TileDoc";
|
||||||
@ -23,6 +34,7 @@ struct TileDoc {
|
|||||||
core::SubSheetId subsheetId = -1;
|
core::SubSheetId subsheetId = -1;
|
||||||
ox::String subsheetPath;
|
ox::String subsheetPath;
|
||||||
uint8_t type = 0;
|
uint8_t type = 0;
|
||||||
|
ox::Array<uint8_t, 4> layerAttachments;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr ox::Result<core::SubSheetId> getSubsheetId(const core::TileSheet &ts) const noexcept {
|
constexpr ox::Result<core::SubSheetId> getSubsheetId(const core::TileSheet &ts) const noexcept {
|
||||||
@ -88,6 +100,38 @@ oxModelBegin(SceneDoc)
|
|||||||
oxModelField(tiles)
|
oxModelField(tiles)
|
||||||
oxModelEnd()
|
oxModelEnd()
|
||||||
|
|
||||||
|
|
||||||
|
constexpr void setTopEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||||
|
layerAttachments = (layerAttachments & 0b11111100) | val;
|
||||||
|
}
|
||||||
|
constexpr void setBottomEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||||
|
layerAttachments = (layerAttachments & 0b11110011) | (val << 2);
|
||||||
|
}
|
||||||
|
constexpr void setLeftEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||||
|
layerAttachments = (layerAttachments & 0b11001111) | (val << 4);
|
||||||
|
}
|
||||||
|
constexpr void setRightEdge(uint8_t &layerAttachments, unsigned val) noexcept {
|
||||||
|
layerAttachments = (layerAttachments & 0b00111111) | (val << 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 {
|
struct SceneStatic {
|
||||||
|
|
||||||
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.SceneStatic";
|
constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.SceneStatic";
|
||||||
@ -97,9 +141,11 @@ struct SceneStatic {
|
|||||||
struct Tile {
|
struct Tile {
|
||||||
uint16_t &tileMapIdx;
|
uint16_t &tileMapIdx;
|
||||||
uint8_t &tileType;
|
uint8_t &tileType;
|
||||||
constexpr Tile(uint16_t *pTileMapIdx, uint8_t *pTileType) noexcept:
|
uint8_t &layerAttachments;
|
||||||
tileMapIdx(*pTileMapIdx),
|
constexpr Tile(uint16_t &pTileMapIdx, uint8_t &pTileType, uint8_t &pLayerAttachments) noexcept:
|
||||||
tileType(*pTileType) {
|
tileMapIdx(pTileMapIdx),
|
||||||
|
tileType(pTileType),
|
||||||
|
layerAttachments(pLayerAttachments) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct Layer {
|
struct Layer {
|
||||||
@ -107,19 +153,22 @@ struct SceneStatic {
|
|||||||
uint16_t &rows;
|
uint16_t &rows;
|
||||||
ox::Vector<uint16_t> &tileMapIdx;
|
ox::Vector<uint16_t> &tileMapIdx;
|
||||||
ox::Vector<uint8_t> &tileType;
|
ox::Vector<uint8_t> &tileType;
|
||||||
|
ox::Vector<uint8_t> &layerAttachments;
|
||||||
constexpr Layer(
|
constexpr Layer(
|
||||||
uint16_t *pColumns,
|
uint16_t &pColumns,
|
||||||
uint16_t *pRows,
|
uint16_t &pRows,
|
||||||
ox::Vector<uint16_t> *pTileMapIdx,
|
ox::Vector<uint16_t> &pTileMapIdx,
|
||||||
ox::Vector<uint8_t> *pTileType) noexcept:
|
ox::Vector<uint8_t> &pTileType,
|
||||||
columns(*pColumns),
|
ox::Vector<uint8_t> &pLayerAttachments) noexcept:
|
||||||
rows(*pRows),
|
columns(pColumns),
|
||||||
tileMapIdx(*pTileMapIdx),
|
rows(pRows),
|
||||||
tileType(*pTileType) {
|
tileMapIdx(pTileMapIdx),
|
||||||
|
tileType(pTileType),
|
||||||
|
layerAttachments(pLayerAttachments) {
|
||||||
}
|
}
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Tile tile(std::size_t i) noexcept {
|
constexpr Tile tile(std::size_t i) noexcept {
|
||||||
return {&tileMapIdx[i], &tileType[i]};
|
return {tileMapIdx[i], tileType[i], layerAttachments[i]};
|
||||||
}
|
}
|
||||||
constexpr auto setDimensions(geo::Size dim) noexcept {
|
constexpr auto setDimensions(geo::Size dim) noexcept {
|
||||||
columns = dim.width;
|
columns = dim.width;
|
||||||
@ -127,6 +176,7 @@ struct SceneStatic {
|
|||||||
const auto tileCnt = static_cast<unsigned>(columns * rows);
|
const auto tileCnt = static_cast<unsigned>(columns * rows);
|
||||||
tileMapIdx.resize(tileCnt);
|
tileMapIdx.resize(tileCnt);
|
||||||
tileType.resize(tileCnt);
|
tileType.resize(tileCnt);
|
||||||
|
layerAttachments.resize(tileCnt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,13 +187,21 @@ struct SceneStatic {
|
|||||||
ox::Vector<uint16_t> rows;
|
ox::Vector<uint16_t> rows;
|
||||||
ox::Vector<ox::Vector<uint16_t>> tileMapIdx;
|
ox::Vector<ox::Vector<uint16_t>> tileMapIdx;
|
||||||
ox::Vector<ox::Vector<uint8_t>> tileType;
|
ox::Vector<ox::Vector<uint8_t>> tileType;
|
||||||
|
ox::Vector<ox::Vector<uint8_t>> layerAttachments;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Layer layer(std::size_t i) noexcept {
|
constexpr Layer layer(std::size_t i) noexcept {
|
||||||
return {&columns[i], &rows[i], &tileMapIdx[i], &tileType[i]};
|
return {
|
||||||
|
columns[i],
|
||||||
|
rows[i],
|
||||||
|
tileMapIdx[i],
|
||||||
|
tileType[i],
|
||||||
|
layerAttachments[i],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto setLayerCnt(std::size_t layerCnt) noexcept {
|
constexpr auto setLayerCnt(std::size_t layerCnt) noexcept {
|
||||||
|
this->layerAttachments.resize(layerCnt);
|
||||||
this->columns.resize(layerCnt);
|
this->columns.resize(layerCnt);
|
||||||
this->rows.resize(layerCnt);
|
this->rows.resize(layerCnt);
|
||||||
this->tileMapIdx.resize(layerCnt);
|
this->tileMapIdx.resize(layerCnt);
|
||||||
@ -157,8 +215,9 @@ oxModelBegin(SceneStatic)
|
|||||||
oxModelField(palettes)
|
oxModelField(palettes)
|
||||||
oxModelField(columns)
|
oxModelField(columns)
|
||||||
oxModelField(rows)
|
oxModelField(rows)
|
||||||
oxModelFieldRename(tile_map_idx, tileMapIdx)
|
oxModelField(tileMapIdx)
|
||||||
oxModelFieldRename(tile_type, tileType)
|
oxModelField(tileType)
|
||||||
|
oxModelField(layerAttachments)
|
||||||
oxModelEnd()
|
oxModelEnd()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,30 @@
|
|||||||
|
|
||||||
namespace nostalgia::scene {
|
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(
|
ox::Error SceneDocToSceneStaticConverter::convert(
|
||||||
foundation::Context *ctx,
|
foundation::Context *ctx,
|
||||||
SceneDoc *src,
|
SceneDoc *src,
|
||||||
@ -32,6 +56,7 @@ ox::Error SceneDocToSceneStaticConverter::convert(
|
|||||||
oxRequire(path, srcTile.getSubsheetPath(*ts));
|
oxRequire(path, srcTile.getSubsheetPath(*ts));
|
||||||
oxRequire(mapIdx, ts->getTileOffset(path));
|
oxRequire(mapIdx, ts->getTileOffset(path));
|
||||||
dstTile.tileMapIdx = static_cast<uint16_t>(mapIdx);
|
dstTile.tileMapIdx = static_cast<uint16_t>(mapIdx);
|
||||||
|
setLayerAttachments(layerIdx, srcTile, dstTile);
|
||||||
++tileIdx;
|
++tileIdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ target_link_libraries(
|
|||||||
NostalgiaAppModules
|
NostalgiaAppModules
|
||||||
NostalgiaStudio
|
NostalgiaStudio
|
||||||
NostalgiaCore-Studio
|
NostalgiaCore-Studio
|
||||||
|
NostalgiaScene-Studio
|
||||||
)
|
)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT WIN32)
|
if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT WIN32)
|
||||||
|
@ -7,13 +7,17 @@
|
|||||||
#include <ox/std/memory.hpp>
|
#include <ox/std/memory.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/studio/module.hpp>
|
#include <nostalgia/core/studio/module.hpp>
|
||||||
|
#include <nostalgia/scene/studio/module.hpp>
|
||||||
|
|
||||||
namespace nostalgia {
|
namespace nostalgia {
|
||||||
|
|
||||||
[[maybe_unused]] // GCC warns about the existence of this "unused" constexpr list in a header file...
|
[[maybe_unused]] // GCC warns about the existence of this "unused" inline list in a header file...
|
||||||
constexpr auto BuiltinModules = {
|
inline ox::Vector<std::function<ox::UPtr<studio::Module>()>, 2> BuiltinModules = {
|
||||||
[] {
|
[]() -> ox::UPtr<studio::Module> {
|
||||||
return ox::make_unique<core::StudioModule>();
|
return ox::UPtr<studio::Module>(new core::StudioModule());
|
||||||
|
},
|
||||||
|
[]() -> ox::UPtr<studio::Module> {
|
||||||
|
return ox::UPtr<studio::Module>(new scene::StudioModule());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ constexpr auto ConfigDir = [] {
|
|||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
ox::String configPath(const core::Context *ctx) noexcept {
|
ox::String configPath(const foundation::Context *ctx) noexcept {
|
||||||
const auto homeDir = std::getenv(ox::defines::OS == ox::OS::Windows ? "USERPROFILE" : "HOME");
|
const auto homeDir = std::getenv(ox::defines::OS == ox::OS::Windows ? "USERPROFILE" : "HOME");
|
||||||
return ox::sfmt(ConfigDir, homeDir, ctx->appName);
|
return ox::sfmt(ConfigDir, homeDir, ctx->appName);
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
namespace nostalgia::studio {
|
namespace nostalgia::studio {
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::String configPath(const core::Context *ctx) noexcept;
|
ox::String configPath(const foundation::Context *ctx) noexcept;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Result<T> readConfig(core::Context *ctx, ox::CRStringView name) noexcept {
|
ox::Result<T> readConfig(foundation::Context *ctx, ox::CRStringView name) noexcept {
|
||||||
oxAssert(name != "", "Config type has no TypeName");
|
oxAssert(name != "", "Config type has no TypeName");
|
||||||
const auto path = ox::sfmt("/{}.json", name);
|
const auto path = ox::sfmt("/{}.json", name);
|
||||||
ox::PassThroughFS fs(configPath(ctx));
|
ox::PassThroughFS fs(configPath(ctx));
|
||||||
@ -34,13 +34,13 @@ ox::Result<T> readConfig(core::Context *ctx, ox::CRStringView name) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Result<T> readConfig(core::Context *ctx) noexcept {
|
ox::Result<T> readConfig(foundation::Context *ctx) noexcept {
|
||||||
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
||||||
return readConfig<T>(ctx, TypeName);
|
return readConfig<T>(ctx, TypeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Error writeConfig(core::Context *ctx, ox::CRStringView name, T *data) noexcept {
|
ox::Error writeConfig(foundation::Context *ctx, ox::CRStringView name, T *data) noexcept {
|
||||||
oxAssert(name != "", "Config type has no TypeName");
|
oxAssert(name != "", "Config type has no TypeName");
|
||||||
const auto path = ox::sfmt("/{}.json", name);
|
const auto path = ox::sfmt("/{}.json", name);
|
||||||
ox::PassThroughFS fs(configPath(ctx));
|
ox::PassThroughFS fs(configPath(ctx));
|
||||||
@ -58,13 +58,13 @@ ox::Error writeConfig(core::Context *ctx, ox::CRStringView name, T *data) noexce
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Error writeConfig(core::Context *ctx, T *data) noexcept {
|
ox::Error writeConfig(foundation::Context *ctx, T *data) noexcept {
|
||||||
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
||||||
return writeConfig(ctx, TypeName, data);
|
return writeConfig(ctx, TypeName, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Func>
|
template<typename T, typename Func>
|
||||||
void openConfig(core::Context *ctx, const auto &name, Func f) noexcept {
|
void openConfig(foundation::Context *ctx, const auto &name, Func f) noexcept {
|
||||||
oxAssert(name != "", "Config type has no TypeName");
|
oxAssert(name != "", "Config type has no TypeName");
|
||||||
const auto [c, err] = readConfig<T>(ctx, name);
|
const auto [c, err] = readConfig<T>(ctx, name);
|
||||||
oxLogError(err);
|
oxLogError(err);
|
||||||
@ -72,13 +72,13 @@ void openConfig(core::Context *ctx, const auto &name, Func f) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Func>
|
template<typename T, typename Func>
|
||||||
void openConfig(core::Context *ctx, Func f) noexcept {
|
void openConfig(foundation::Context *ctx, Func f) noexcept {
|
||||||
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
||||||
openConfig<T>(ctx, TypeName, f);
|
openConfig<T>(ctx, TypeName, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Func>
|
template<typename T, typename Func>
|
||||||
void editConfig(core::Context *ctx, const auto &name, Func f) noexcept {
|
void editConfig(foundation::Context *ctx, const auto &name, Func f) noexcept {
|
||||||
oxAssert(ox_strcmp(name, ""), "Config type has no TypeName");
|
oxAssert(ox_strcmp(name, ""), "Config type has no TypeName");
|
||||||
auto [c, err] = readConfig<T>(ctx, name);
|
auto [c, err] = readConfig<T>(ctx, name);
|
||||||
oxLogError(err);
|
oxLogError(err);
|
||||||
@ -87,7 +87,7 @@ void editConfig(core::Context *ctx, const auto &name, Func f) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Func>
|
template<typename T, typename Func>
|
||||||
void editConfig(core::Context *ctx, Func f) noexcept {
|
void editConfig(foundation::Context *ctx, Func f) noexcept {
|
||||||
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
constexpr auto TypeName = ox::requireModelTypeName<T>();
|
||||||
editConfig<T>(ctx, TypeName, f);
|
editConfig<T>(ctx, TypeName, f);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,13 @@ void BaseEditor::exportFile() {
|
|||||||
void BaseEditor::keyStateChanged(core::Key, bool) {
|
void BaseEditor::keyStateChanged(core::Key, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseEditor::onActivated() noexcept {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseEditor::requiresConstantRefresh() const noexcept {
|
||||||
|
return m_requiresConstantRefresh;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseEditor::close() const {
|
void BaseEditor::close() const {
|
||||||
this->closed.emit(itemName());
|
this->closed.emit(itemName());
|
||||||
}
|
}
|
||||||
@ -100,6 +107,11 @@ ox::StringView BaseEditor::pathToItemName(ox::CRStringView path) noexcept {
|
|||||||
return path.substr(lastSlash + 1);
|
return path.substr(lastSlash + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseEditor::setRequiresConstantRefresh(bool value) noexcept {
|
||||||
|
m_requiresConstantRefresh = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Editor::Editor() noexcept {
|
Editor::Editor() noexcept {
|
||||||
m_undoStack.changeTriggered.connect(this, &Editor::markUnsavedChanges);
|
m_undoStack.changeTriggered.connect(this, &Editor::markUnsavedChanges);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ class NOSTALGIASTUDIO_EXPORT BaseEditor: public Widget {
|
|||||||
bool m_cutEnabled = false;
|
bool m_cutEnabled = false;
|
||||||
bool m_copyEnabled = false;
|
bool m_copyEnabled = false;
|
||||||
bool m_pasteEnabled = false;
|
bool m_pasteEnabled = false;
|
||||||
|
bool m_requiresConstantRefresh = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~BaseEditor() override = default;
|
~BaseEditor() override = default;
|
||||||
@ -50,6 +51,11 @@ class NOSTALGIASTUDIO_EXPORT BaseEditor: public Widget {
|
|||||||
|
|
||||||
virtual void keyStateChanged(core::Key key, bool down);
|
virtual void keyStateChanged(core::Key key, bool down);
|
||||||
|
|
||||||
|
virtual void onActivated() noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
bool requiresConstantRefresh() const noexcept;
|
||||||
|
|
||||||
void close() const;
|
void close() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,6 +108,8 @@ class NOSTALGIASTUDIO_EXPORT BaseEditor: public Widget {
|
|||||||
|
|
||||||
static ox::StringView pathToItemName(ox::CRStringView path) noexcept;
|
static ox::StringView pathToItemName(ox::CRStringView path) noexcept;
|
||||||
|
|
||||||
|
void setRequiresConstantRefresh(bool value) noexcept;
|
||||||
|
|
||||||
// signals
|
// signals
|
||||||
public:
|
public:
|
||||||
ox::Signal<ox::Error(bool)> unsavedChangesChanged;
|
ox::Signal<ox::Error(bool)> unsavedChangesChanged;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
namespace nostalgia::studio {
|
namespace nostalgia::studio {
|
||||||
|
|
||||||
static void generateTypes(ox::TypeStore *ts) noexcept {
|
static void generateTypes(ox::TypeStore *ts) noexcept {
|
||||||
for (const auto mod : *foundation::modules()) {
|
for (const auto mod : foundation::modules()) {
|
||||||
for (auto gen : mod->types()) {
|
for (auto gen : mod->types()) {
|
||||||
oxLogError(gen(ts));
|
oxLogError(gen(ts));
|
||||||
}
|
}
|
||||||
|
@ -48,13 +48,16 @@ static ox::Error run(ox::UniquePtr<ox::FileSystem> fs) noexcept {
|
|||||||
core::setUpdateHandler(ctx.get(), updateHandler);
|
core::setUpdateHandler(ctx.get(), updateHandler);
|
||||||
core::setKeyEventHandler(ctx.get(), keyEventHandler);
|
core::setKeyEventHandler(ctx.get(), keyEventHandler);
|
||||||
core::setConstantRefresh(ctx.get(), false);
|
core::setConstantRefresh(ctx.get(), false);
|
||||||
|
core::gl::setMainViewEnabled(false);
|
||||||
studio::StudioContext studioCtx;
|
studio::StudioContext studioCtx;
|
||||||
core::setApplicationData(ctx.get(), &studioCtx);
|
core::setApplicationData(ctx.get(), &studioCtx);
|
||||||
StudioUI ui(ctx.get());
|
StudioUI ui(ctx.get());
|
||||||
studioCtx.ui = &ui;
|
studioCtx.ui = &ui;
|
||||||
StudioUIDrawer drawer(&ui);
|
StudioUIDrawer drawer(&ui);
|
||||||
ctx->drawers.emplace_back(&drawer);
|
core::addCustomDrawer(ctx.get(), &drawer);
|
||||||
return core::run(ctx.get());
|
auto err = core::run(ctx.get());
|
||||||
|
core::removeCustomDrawer(ctx.get(), &drawer);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ox::Error run(int, const char**) noexcept {
|
static ox::Error run(int, const char**) noexcept {
|
||||||
|
@ -217,7 +217,12 @@ void StudioUI::drawTabs() noexcept {
|
|||||||
if (m_activeEditorUpdatePending == e.get()) {
|
if (m_activeEditorUpdatePending == e.get()) {
|
||||||
m_activeEditorUpdatePending = nullptr;
|
m_activeEditorUpdatePending = nullptr;
|
||||||
}
|
}
|
||||||
|
if (m_activeEditorOnLastDraw != e.get()) [[unlikely]] {
|
||||||
|
m_activeEditor->onActivated();
|
||||||
|
core::setConstantRefresh(m_ctx, m_activeEditor->requiresConstantRefresh());
|
||||||
|
}
|
||||||
e->draw(m_ctx);
|
e->draw(m_ctx);
|
||||||
|
m_activeEditorOnLastDraw = e.get();
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (!open) {
|
if (!open) {
|
||||||
@ -346,7 +351,7 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab)
|
|||||||
}
|
}
|
||||||
// save to config
|
// save to config
|
||||||
studio::editConfig<StudioConfig>(m_ctx, [&](StudioConfig *config) {
|
studio::editConfig<StudioConfig>(m_ctx, [&](StudioConfig *config) {
|
||||||
if (!config->openFiles.contains((path))) {
|
if (!config->openFiles.contains(path)) {
|
||||||
config->openFiles.emplace_back(path);
|
config->openFiles.emplace_back(path);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -31,6 +31,7 @@ class StudioUI: public ox::SignalHandler {
|
|||||||
ox::HashMap<ox::String, studio::EditorMaker::Func> m_editorMakers;
|
ox::HashMap<ox::String, studio::EditorMaker::Func> m_editorMakers;
|
||||||
ox::UniquePtr<ProjectExplorer> m_projectExplorer;
|
ox::UniquePtr<ProjectExplorer> m_projectExplorer;
|
||||||
ox::Vector<ox::String> m_openFiles;
|
ox::Vector<ox::String> m_openFiles;
|
||||||
|
studio::BaseEditor *m_activeEditorOnLastDraw = nullptr;
|
||||||
studio::BaseEditor *m_activeEditor = nullptr;
|
studio::BaseEditor *m_activeEditor = nullptr;
|
||||||
studio::BaseEditor *m_activeEditorUpdatePending = nullptr;
|
studio::BaseEditor *m_activeEditorUpdatePending = nullptr;
|
||||||
NewMenu m_newMenu;
|
NewMenu m_newMenu;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user