[nostalgia] Add start for Scene editor in Studio

This commit is contained in:
2023-03-11 16:59:26 -06:00
parent 19d5641c6e
commit ae9272841f
37 changed files with 357 additions and 295 deletions
+2 -12
View File
@@ -7,12 +7,6 @@ add_library(
typestore.cpp
)
add_library(
NostalgiaCore-Headless
headless/core.cpp
headless/gfx.cpp
)
add_library(NostalgiaCore)
if(NOT NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
@@ -65,11 +59,6 @@ target_link_libraries(
NostalgiaCore-Common
)
target_link_libraries(
NostalgiaCore-Headless PUBLIC
NostalgiaCore-Common
)
if(NOSTALGIA_BUILD_STUDIO)
add_subdirectory(studio)
endif()
@@ -84,7 +73,9 @@ install(
core.hpp
event.hpp
gfx.hpp
ptidxconv.hpp
input.hpp
tilesheet.hpp
typeconv.hpp
typestore.hpp
DESTINATION
@@ -94,7 +85,6 @@ install(
install(
TARGETS
NostalgiaCore
NostalgiaCore-Headless
DESTINATION
LIBRARY DESTINATION lib/nostalgia
ARCHIVE DESTINATION lib/nostalgia
+2 -2
View File
@@ -10,7 +10,7 @@ constexpr auto TileWidth = 8;
constexpr auto TileHeight = 8;
constexpr auto PixelsPerTile = TileWidth * TileHeight;
constexpr auto FileExt_ng = ".ng";
constexpr auto FileExt_npal = ".npal";
constexpr auto FileExt_ng = "ng";
constexpr auto FileExt_npal = "npal";
}
+24 -7
View File
@@ -9,10 +9,22 @@
#include <ox/std/buffer.hpp>
#include <nostalgia/foundation/context.hpp>
#include <nostalgia/geo/size.hpp>
#include "event.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 {
class Size;
}
@@ -58,6 +70,7 @@ class Context: public foundation::Context {
friend int getScreenHeight(Context *ctx) noexcept;
friend int getScreenWidth(Context *ctx) noexcept;
friend ox::Error initGfx(Context *ctx) noexcept;
friend ox::Error renderer::init(Context *ctx) noexcept;
friend ox::Error loadBgTileSheet(Context *ctx,
unsigned cbb,
const ox::FileAddress &tilesheetPath,
@@ -84,14 +97,18 @@ class Context: public foundation::Context {
friend constexpr KeyEventHandler keyEventHandler(Context *ctx) noexcept;
friend void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) noexcept;
friend void setSprite(Context *ctx,
unsigned idx,
int x,
int y,
unsigned tileIdx,
unsigned spriteShape,
unsigned spriteSize,
unsigned flipX) noexcept;
unsigned idx,
int x,
int y,
unsigned tileIdx,
unsigned spriteShape,
unsigned spriteSize,
unsigned flipX) 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:
ox::Vector<Drawer*, 5> drawers;
+6
View File
@@ -18,6 +18,12 @@
namespace nostalgia::core {
namespace gl {
void setMainViewEnabled(bool) noexcept;
}
extern ox::Array<char, 128> charMap;
class Drawer {
+1 -3
View File
@@ -216,9 +216,7 @@ ox::Error initGfx(Context *ctx) noexcept {
ImGui_ImplGlfw_InitForOpenGL(id->window, true);
}
themeImgui();
void *rendererData = nullptr;
oxReturnError(renderer::init(ctx, &rendererData));
ctx->setRendererData(rendererData);
oxReturnError(renderer::init(ctx));
return OxError(0);
}
-25
View File
@@ -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;
}
}
-101
View File
@@ -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 {
}
}
+21
View File
@@ -14,8 +14,29 @@
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;
const foundation::Module *module() noexcept {
return &CoreModule::mod;
}
ox::Vector<foundation::TypeDescGenerator> CoreModule::types() const noexcept {
return {
foundation::generateTypeDesc<TileSheetV1>,
+1 -18
View File
@@ -6,25 +6,8 @@
#include <nostalgia/foundation/module.hpp>
#include "typeconv.hpp"
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;
};
const foundation::Module *module() noexcept;
}
+74 -18
View File
@@ -18,6 +18,16 @@ namespace nostalgia::core {
void ImGui_Impl_NewFrame() noexcept;
namespace gl {
static bool mainViewEnabled = true;
void setMainViewEnabled(bool enabled) noexcept {
mainViewEnabled = enabled;
}
}
namespace renderer {
constexpr uint64_t TileRows = 128;
@@ -67,6 +77,7 @@ struct GlImplData {
SpriteBlockset spriteBlocks;
ox::Array<Sprite, 128> spriteStates;
ox::Array<Background, 4> backgrounds;
ox::Optional<geo::Size> renderSize;
};
constexpr ox::StringView bgvshadTmpl = R"(
@@ -74,9 +85,13 @@ constexpr ox::StringView bgvshadTmpl = R"(
in vec2 vTexCoord;
in vec2 vPosition;
out vec2 fTexCoord;
uniform float vXScale;
uniform float vTileHeight;
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);
})";
@@ -98,9 +113,13 @@ constexpr ox::StringView spritevshadTmpl = R"(
in vec2 vTexCoord;
in vec2 vPosition;
out vec2 fTexCoord;
uniform float vXScale;
uniform float vTileHeight;
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);
})";
@@ -111,7 +130,7 @@ static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept {
return y * TileRows + x;
}
static void setSpriteBufferObject(Context *ctx,
static void setSpriteBufferObject(Context*,
unsigned vi,
float enabled,
float x, float y,
@@ -120,9 +139,8 @@ static void setSpriteBufferObject(Context *ctx,
float *vbo,
GLuint *ebo) noexcept {
// 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;
const auto xmod = ymod * static_cast<float>(sh) / static_cast<float>(sw);
x *= xmod;
y *= -ymod;
x -= 1.f;
@@ -144,7 +162,7 @@ static void setSpriteBufferObject(Context *ctx,
memcpy(ebo, elms.data(), sizeof(elms));
}
static void setTileBufferObject(Context *ctx,
static void setTileBufferObject(Context*,
unsigned vi,
float x,
float y,
@@ -152,9 +170,8 @@ static void setTileBufferObject(Context *ctx,
float *vbo,
GLuint *ebo) noexcept {
// don't worry, this memcpy gets optimized to something much more ideal
const auto [sw, sh] = getScreenSize(ctx);
constexpr float ymod = 2.0f / 20.0f;
const float xmod = ymod * static_cast<float>(sh) / static_cast<float>(sw);
constexpr float ymod = 0.1f;
constexpr float xmod = 0.1f;
x *= xmod;
y *= -ymod;
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);
}
static void drawBackgrounds(GlImplData *id) noexcept {
static void drawBackgrounds(core::Context *ctx, GlImplData *id) noexcept {
// load background shader and its uniforms
glUseProgram(id->bgShader);
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vXScale"));
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) {
if (bg.enabled) {
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);
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 [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
glBindVertexArray(sb.vao);
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);
}
ox::Error init(Context *ctx, void **rendererData) noexcept {
ox::Error init(Context *ctx) noexcept {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
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 spriteFshad = ox::sfmt(spritefshadTmpl, glutils::GlslVersion);
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(spriteVshad.c_str(), spriteFshad.c_str()).moveTo(&id->spriteShader));
for (auto &bg : id->cbbs) {
@@ -328,7 +354,7 @@ ox::Error init(Context *ctx, void **rendererData) noexcept {
}
initSpritesBufferset(ctx, id->spriteShader, &id->spriteBlocks);
ImGui_ImplOpenGL3_Init(glutils::GlslVersion);
return OxError(0);
return {};
}
void shutdown(Context*, void *rendererData) noexcept {
@@ -422,9 +448,8 @@ void draw(Context *ctx) noexcept {
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
// render
renderer::drawBackgrounds(id);
if (id->spriteBlocks.tex) {
renderer::drawSprites(id);
if (gl::mainViewEnabled) {
gl::drawMainView(ctx);
}
for (const auto cd : ctx->drawers) {
cd->draw(ctx);
@@ -530,4 +555,35 @@ void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) no
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);
}
}
}
}