From 4bcef4bd354286bdaa50c61deba8a07707466bef Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 1 Feb 2023 02:07:55 -0600 Subject: [PATCH] [nostalgia/core/userland] Add support for multiple sprite size/shapes --- src/nostalgia/core/userland/gfx_opengl.cpp | 73 ++++++++++++++++------ 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/src/nostalgia/core/userland/gfx_opengl.cpp b/src/nostalgia/core/userland/gfx_opengl.cpp index 5f66eeab..00941963 100644 --- a/src/nostalgia/core/userland/gfx_opengl.cpp +++ b/src/nostalgia/core/userland/gfx_opengl.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -27,7 +28,7 @@ constexpr uint64_t BgVertexVboRows = 4; constexpr uint64_t BgVertexVboRowLength = 4; constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength; constexpr uint64_t BgVertexEboLength = 6; -constexpr uint64_t SpriteVertexVboRows = 4; +constexpr uint64_t SpriteVertexVboRows = 256; constexpr uint64_t SpriteVertexVboRowLength = 5; constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength; constexpr uint64_t SpriteVertexEboLength = 6; @@ -103,17 +104,7 @@ constexpr ox::StringView spritevshadTmpl = R"( fTexCoord = vTexCoord * vec2(1, vTileHeight) * vec2(vEnabled, vEnabled); })"; -constexpr ox::StringView spritefshadTmpl = R"( - {} - 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); - })"; +constexpr ox::StringView spritefshadTmpl = bgfshadTmpl; [[nodiscard]] static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept { @@ -270,9 +261,9 @@ static void tickFps(GlImplData *id) noexcept { const auto duration = static_cast(now - id->prevFpsCheckTime) / 1000.0; const auto fps = static_cast(static_cast(id->draws) / duration); 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->draws = 0; } @@ -432,7 +423,9 @@ void draw(Context *ctx) noexcept { glClear(GL_COLOR_BUFFER_BIT); // render renderer::drawBackgrounds(id); - renderer::drawSprites(id); + if (id->spriteBlocks.tex) { + renderer::drawSprites(id); + } for (const auto cd : ctx->drawers) { cd->draw(ctx); } @@ -466,17 +459,59 @@ void setSprite(Context *ctx, [[maybe_unused]] unsigned spriteShape, [[maybe_unused]] unsigned spriteSize, 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, 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(x) % 255; const auto uY = static_cast(y) % 127; auto &id = *ctx->rendererData(); - auto vbo = &id.spriteBlocks.vertices[idx * renderer::SpriteVertexVboLength]; - auto ebo = &id.spriteBlocks.elements[idx * renderer::SpriteVertexEboLength]; - renderer::setSpriteBufferObject(ctx, idx * renderer::SpriteVertexVboRows, 1, - static_cast(uX) / 8, static_cast(uY) / 8, tileIdx, flipX, vbo, ebo); + auto i = 0u; + const auto set = [&](unsigned xIt, unsigned yIt) { + const auto fX = static_cast(uX + xIt * 8) / 8; + const auto fY = static_cast(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; } 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(); const auto z = static_cast(bgIdx); const auto y = static_cast(row);