diff --git a/src/nostalgia/core/sdl/gfx.cpp b/src/nostalgia/core/sdl/gfx.cpp index 6704ba84..986b8c97 100644 --- a/src/nostalgia/core/sdl/gfx.cpp +++ b/src/nostalgia/core/sdl/gfx.cpp @@ -23,25 +23,8 @@ namespace nostalgia::core { -using TileMap = std::array, 128>; - constexpr auto Scale = 5; -static ox::Result> readFile(Context *ctx, const ox::FileAddress &file) { - oxRequire(stat, ctx->rom->stat(file)); - ox::Vector buff(stat.size); - oxReturnError(ctx->rom->read(file, buff.data(), buff.size())); - return buff; -} - -template -ox::Result readObj(Context *ctx, const ox::FileAddress &file) { - oxRequire(buff, readFile(ctx, file)); - T t; - oxReturnError(ox::readClaw(buff.data(), buff.size(), &t)); - return t; -} - ox::Error initGfx(Context *ctx) { auto id = new SdlImplData; ctx->setWindowerData(id); @@ -74,87 +57,4 @@ ox::Error shutdownGfx(Context *ctx) { return OxError(0); } -ox::Error initConsole(Context *ctx) { - constexpr auto TilesheetAddr = "/TileSheets/Charset.ng"; - return loadBgTileSheet(ctx, 0, TilesheetAddr); -} - -SDL_Color createSDL_Color(Color16 nc) { - SDL_Color c; - // extract the color channels and scale them up for a 24 bit color - c.r = ((nc & 0b0000000000011111) >> 0) * 8; - c.g = ((nc & 0b0000001111100000) >> 5) * 8; - c.b = ((nc & 0b0111110000000000) >> 10) * 8; - c.a = 1; - return c; -} - -SDL_Palette *createSDL_Palette(const NostalgiaPalette &npal) { - auto pal = SDL_AllocPalette(npal.colors.size()); - for (std::size_t i = 0; i < npal.colors.size(); ++i) { - pal->colors[i] = createSDL_Color(npal.colors[i]); - } - return pal; -} - -ox::Error loadBgTileSheet(Context *ctx, - int section, - ox::FileAddress tilesheetPath, - ox::FileAddress palettePath) { - oxRequire(tilesheet, readObj(ctx, tilesheetPath)); - if (!palettePath) { - palettePath = tilesheet.defaultPalette; - } - oxRequire(palette, readObj(ctx, palettePath)); - const unsigned bytesPerTile = tilesheet.bpp == 8 ? 64 : 32; - const auto tiles = tilesheet.pixels.size() / bytesPerTile; - constexpr int width = 8; - const int height = 8 * tiles; - std::vector pixels; - if (bytesPerTile == 64) { // 8 BPP - pixels.resize(tilesheet.pixels.size()); - for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) { - pixels[i] = toColor32(palette.colors[tilesheet.pixels[i]]); - } - } else { // 4 BPP - pixels.resize(tilesheet.pixels.size() * 2); - for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) { - pixels[i * 2 + 0] = toColor32(palette.colors[tilesheet.pixels[i] & 0xF]); - pixels[i * 2 + 1] = toColor32(palette.colors[tilesheet.pixels[i] >> 4]); - } - } - return renderer::loadBgTexture(ctx, section, pixels.data(), width, height); -} - -ox::Error loadSpriteTileSheet(Context*, - int, - ox::FileAddress, - ox::FileAddress) { - return OxError(0); -} - -void drawBackground(Context*, const TileMap &tm, SDL_Texture *tex) { - if (tex) { - oxTrace("nostalgia::core::sdl::drawBackground", "Drawing background"); - constexpr auto DstSize = 8 * Scale; - SDL_Rect src = {}, dst = {}; - src.x = 0; - src.w = 8; - src.h = 8; - dst.x = 0; - dst.y = 0; - dst.w = DstSize; - dst.h = DstSize; - for (auto &m : tm) { - for (auto t : m) { - src.y = t * 8; - SDL_RenderCopy(nullptr, tex, &src, &dst); - dst.x += DstSize; - } - dst.x = 0; - dst.y += DstSize; - } - } -} - } diff --git a/src/nostalgia/core/userland/CMakeLists.txt b/src/nostalgia/core/userland/CMakeLists.txt index cbb0061b..443fa47b 100644 --- a/src/nostalgia/core/userland/CMakeLists.txt +++ b/src/nostalgia/core/userland/CMakeLists.txt @@ -1,5 +1,6 @@ add_library( NostalgiaCore-Userspace OBJECT + gfx.cpp gfx_opengl.cpp glutils.cpp media.cpp diff --git a/src/nostalgia/core/userland/gfx.cpp b/src/nostalgia/core/userland/gfx.cpp new file mode 100644 index 00000000..6386dd1b --- /dev/null +++ b/src/nostalgia/core/userland/gfx.cpp @@ -0,0 +1,73 @@ +/* + * Copyright 2016 - 2021 gary@drinkingtea.net + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include +#include + +#include "gfx.hpp" + +namespace nostalgia::core { + +static ox::Result> readFile(Context *ctx, const ox::FileAddress &file) { + oxRequire(stat, ctx->rom->stat(file)); + ox::Vector buff(stat.size); + oxReturnError(ctx->rom->read(file, buff.data(), buff.size())); + return buff; +} + +template +ox::Result readObj(Context *ctx, const ox::FileAddress &file) { + oxRequire(buff, readFile(ctx, file)); + T t; + oxReturnError(ox::readClaw(buff.data(), buff.size(), &t)); + return t; +} + +ox::Error initConsole(Context *ctx) { + constexpr auto TilesheetAddr = "/TileSheets/Charset.ng"; + return loadBgTileSheet(ctx, 0, TilesheetAddr); +} + +ox::Error loadSpriteTileSheet(Context*, + int, + ox::FileAddress, + ox::FileAddress) { + return OxError(0); +} + +ox::Error loadBgTileSheet(Context *ctx, + int section, + ox::FileAddress tilesheetPath, + ox::FileAddress palettePath) { + oxRequire(tilesheet, readObj(ctx, tilesheetPath)); + if (!palettePath) { + palettePath = tilesheet.defaultPalette; + } + oxRequire(palette, readObj(ctx, palettePath)); + const unsigned bytesPerTile = tilesheet.bpp == 8 ? 64 : 32; + const auto tiles = tilesheet.pixels.size() / bytesPerTile; + constexpr int width = 8; + const int height = 8 * tiles; + ox::Vector pixels; + if (bytesPerTile == 64) { // 8 BPP + pixels.resize(tilesheet.pixels.size()); + for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) { + pixels[i] = toColor32(palette.colors[tilesheet.pixels[i]]); + } + } else { // 4 BPP + pixels.resize(tilesheet.pixels.size() * 2); + for (std::size_t i = 0; i < tilesheet.pixels.size(); ++i) { + pixels[i * 2 + 0] = toColor32(palette.colors[tilesheet.pixels[i] & 0xF]); + pixels[i * 2 + 1] = toColor32(palette.colors[tilesheet.pixels[i] >> 4]); + } + } + return renderer::loadBgTexture(ctx, section, pixels.data(), width, height); +} + +} diff --git a/src/nostalgia/core/userland/gfx_opengl.cpp b/src/nostalgia/core/userland/gfx_opengl.cpp index 7cd83d37..b08e759e 100644 --- a/src/nostalgia/core/userland/gfx_opengl.cpp +++ b/src/nostalgia/core/userland/gfx_opengl.cpp @@ -22,15 +22,16 @@ using TileMap = std::array, 128>; namespace renderer { -constexpr auto TileRows = 16; -constexpr auto TileColumns = 16; +constexpr auto TileRows = 128; +constexpr auto TileColumns = 128; constexpr auto TileCount = TileRows * TileColumns; +constexpr auto BgVertexVboRows = 4; constexpr auto BgVertexVboLength = 16; constexpr auto BgVertexEboLength = 6; struct BackgroundBufferset: public Bufferset { - std::array bgVertices; - std::array bgEbos; + std::array bgVertices; + std::array bgEbos; }; struct GlImplData { @@ -64,16 +65,17 @@ constexpr const GLchar *bgfshad = R"( void initTileBufferObjects(unsigned vi, float x, float y, float *vbo, GLuint *ebo) { // don't worry, this gets optimized to something much more ideal constexpr float xmod = 0.06f; + constexpr float ymod = 0.1f; x *= xmod; - y *= 0.1f; - const float vertices[BgVertexVboLength] = { + y *= ymod; + const float vertices[] = { x, y, 0, 0.04, // bottom left x + xmod, y, 1, 0.04, // bottom right - x + xmod, y + 0.1f, 1, 0, // top right - x, y + 0.1f, 0, 0, // top left + x + xmod, y + ymod, 1, 0.02, // top right + x, y + ymod, 0, 0.02, // top left }; memcpy(vbo, vertices, sizeof(vertices)); - const GLuint elms[BgVertexEboLength] = { + const GLuint elms[] = { vi + 0, vi + 1, vi + 2, vi + 2, vi + 3, vi + 0, }; @@ -84,10 +86,9 @@ void initBackgroundBufferObjects(GLuint shader, BackgroundBufferset *bs) { auto i = 0u; for (auto x = 0u; x < TileColumns; ++x) { for (auto y = 0u; y < TileRows; ++y) { - const auto vi = i * BgVertexVboLength; - auto vbo = &bs->bgVertices[vi]; + auto vbo = &bs->bgVertices[i * BgVertexVboLength]; auto ebo = &bs->bgEbos[i * BgVertexEboLength]; - initTileBufferObjects(vi, x, y, vbo, ebo); + initTileBufferObjects(i * BgVertexVboRows, x, y, vbo, ebo); ++i; } }