[nostalgia/core/userland] Add support for multiple sprite size/shapes

This commit is contained in:
Gary Talent 2023-02-01 02:07:55 -06:00
parent 17cb40c0ec
commit 4bcef4bd35

View File

@ -7,6 +7,7 @@
#include <ox/std/array.hpp> #include <ox/std/array.hpp>
#include <ox/std/fmt.hpp> #include <ox/std/fmt.hpp>
#include <nostalgia/geo/vec.hpp>
#include <nostalgia/glutils/glutils.hpp> #include <nostalgia/glutils/glutils.hpp>
#include <nostalgia/core/context.hpp> #include <nostalgia/core/context.hpp>
@ -27,7 +28,7 @@ constexpr uint64_t BgVertexVboRows = 4;
constexpr uint64_t BgVertexVboRowLength = 4; constexpr uint64_t BgVertexVboRowLength = 4;
constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength; constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength;
constexpr uint64_t BgVertexEboLength = 6; constexpr uint64_t BgVertexEboLength = 6;
constexpr uint64_t SpriteVertexVboRows = 4; constexpr uint64_t SpriteVertexVboRows = 256;
constexpr uint64_t SpriteVertexVboRowLength = 5; constexpr uint64_t SpriteVertexVboRowLength = 5;
constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength; constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength;
constexpr uint64_t SpriteVertexEboLength = 6; constexpr uint64_t SpriteVertexEboLength = 6;
@ -103,17 +104,7 @@ constexpr ox::StringView spritevshadTmpl = R"(
fTexCoord = vTexCoord * vec2(1, vTileHeight) * vec2(vEnabled, vEnabled); fTexCoord = vTexCoord * vec2(1, vTileHeight) * vec2(vEnabled, vEnabled);
})"; })";
constexpr ox::StringView spritefshadTmpl = R"( constexpr ox::StringView spritefshadTmpl = bgfshadTmpl;
{}
out vec4 outColor;
in vec2 fTexCoord;
uniform sampler2D image;
uniform vec4 fPalette[256];
void main() {
int idx = int(texture(image, fTexCoord).rgb.r * 256);
outColor = fPalette[idx];
//outColor = vec4(0.0, 0.7, 1.0, 1.0);
})";
[[nodiscard]] [[nodiscard]]
static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept { static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept {
@ -270,9 +261,9 @@ static void tickFps(GlImplData *id) noexcept {
const auto duration = static_cast<double>(now - id->prevFpsCheckTime) / 1000.0; const auto duration = static_cast<double>(now - id->prevFpsCheckTime) / 1000.0;
const auto fps = static_cast<int>(static_cast<double>(id->draws) / duration); const auto fps = static_cast<int>(static_cast<double>(id->draws) / duration);
if constexpr(config::UserlandFpsPrint) { if constexpr(config::UserlandFpsPrint) {
oxInfof("FPS: {}", fps); oxOutf("FPS: {}\n", fps);
} }
oxTracef("nostalgia::core::gfx::gl::fps", "FPS: {}", fps); oxTracef("nostalgia::core::gfx::fps", "FPS: {}", fps);
id->prevFpsCheckTime = now; id->prevFpsCheckTime = now;
id->draws = 0; id->draws = 0;
} }
@ -432,7 +423,9 @@ void draw(Context *ctx) noexcept {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
// render // render
renderer::drawBackgrounds(id); renderer::drawBackgrounds(id);
renderer::drawSprites(id); if (id->spriteBlocks.tex) {
renderer::drawSprites(id);
}
for (const auto cd : ctx->drawers) { for (const auto cd : ctx->drawers) {
cd->draw(ctx); cd->draw(ctx);
} }
@ -466,17 +459,59 @@ void setSprite(Context *ctx,
[[maybe_unused]] unsigned spriteShape, [[maybe_unused]] unsigned spriteShape,
[[maybe_unused]] unsigned spriteSize, [[maybe_unused]] unsigned spriteSize,
unsigned flipX) noexcept { unsigned flipX) noexcept {
//oxTracef("nostalgia::core::gfx::gl", "setSprite(ctx, {}, {}, {}, {}, {}, {}, {})",
// idx, x, y, tileIdx, spriteShape, spriteSize, flipX);
// Tonc Table 8.4
static constexpr ox::Array<geo::Vec<unsigned>, 12> dimensions{
// col 0
{1, 1}, // 0, 0
{2, 2}, // 0, 1
{4, 4}, // 0, 2
{8, 8}, // 0, 3
// col 1
{2, 1}, // 1, 0
{4, 1}, // 1, 1
{4, 2}, // 1, 2
{8, 4}, // 1, 3
// col 2
{1, 1}, // 2, 0
{1, 4}, // 2, 1
{2, 4}, // 2, 2
{4, 8}, // 2, 3
};
const auto dim = dimensions[(spriteShape << 2) | spriteSize];
const auto uX = static_cast<unsigned>(x) % 255; const auto uX = static_cast<unsigned>(x) % 255;
const auto uY = static_cast<unsigned>(y) % 127; const auto uY = static_cast<unsigned>(y) % 127;
auto &id = *ctx->rendererData<renderer::GlImplData>(); auto &id = *ctx->rendererData<renderer::GlImplData>();
auto vbo = &id.spriteBlocks.vertices[idx * renderer::SpriteVertexVboLength]; auto i = 0u;
auto ebo = &id.spriteBlocks.elements[idx * renderer::SpriteVertexEboLength]; const auto set = [&](unsigned xIt, unsigned yIt) {
renderer::setSpriteBufferObject(ctx, idx * renderer::SpriteVertexVboRows, 1, const auto fX = static_cast<float>(uX + xIt * 8) / 8;
static_cast<float>(uX) / 8, static_cast<float>(uY) / 8, tileIdx, flipX, vbo, ebo); const auto fY = static_cast<float>(uY + yIt * 8) / 8;
const auto cidx = idx + i;
auto vbo = &id.spriteBlocks.vertices[cidx * renderer::SpriteVertexVboLength];
auto ebo = &id.spriteBlocks.elements[cidx * renderer::SpriteVertexEboLength];
renderer::setSpriteBufferObject(ctx, cidx * renderer::SpriteVertexVboRows, 1,
fX, fY, tileIdx + i, flipX, vbo, ebo);
++i;
};
if (!flipX) {
for (auto yIt = 0u; yIt < dim.y; ++yIt) {
for (auto xIt = 0u; xIt < dim.x; ++xIt) {
set(xIt, yIt);
}
}
} else {
for (auto yIt = 0u; yIt < dim.y; ++yIt) {
for (auto xIt = dim.x - 1; xIt < ~0u; --xIt) {
set(xIt, yIt);
}
}
}
id.spriteBlocks.updated = true; id.spriteBlocks.updated = true;
} }
void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) noexcept { void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) noexcept {
//oxTracef("nostalgia::core::gfx::gl", "setTile(ctx, {}, {}, {}, {})", bgIdx, column, row, tile);
const auto id = ctx->rendererData<renderer::GlImplData>(); const auto id = ctx->rendererData<renderer::GlImplData>();
const auto z = static_cast<unsigned>(bgIdx); const auto z = static_cast<unsigned>(bgIdx);
const auto y = static_cast<unsigned>(row); const auto y = static_cast<unsigned>(row);