[nostalgia/core] Add support for implementation data to Context and move SDL data to it

This commit is contained in:
Gary Talent 2020-03-22 18:30:33 -05:00
parent 0e2276bab8
commit 6d2155d1ed
9 changed files with 81 additions and 52 deletions

View File

@ -13,8 +13,22 @@
namespace nostalgia::core { namespace nostalgia::core {
// User Input Output // User Input Output
struct Context { class Context {
ox::FileSystem *rom = nullptr; public:
ox::FileSystem *rom = nullptr;
private:
void *m_implData = nullptr;
public:
constexpr void setImplData(void *implData) noexcept {
m_implData = implData;
}
template<typename T>
constexpr T *implData() noexcept {
return static_cast<T*>(m_implData);
}
}; };
} }

View File

@ -19,6 +19,6 @@ namespace nostalgia::core {
[[nodiscard]] ox::Error init(Context *ctx); [[nodiscard]] ox::Error init(Context *ctx);
[[nodiscard]] ox::Error run(); [[nodiscard]] ox::Error run(Context *ctx);
} }

View File

@ -10,7 +10,7 @@
namespace nostalgia::core { namespace nostalgia::core {
ox::Error run() { ox::Error run(Context*) {
while (1) { while (1) {
} }
return OxError(0); return OxError(0);

View File

@ -89,7 +89,7 @@ ox::Error initGfx(Context*) {
return OxError(0); return OxError(0);
} }
ox::Error shutdownGfx() { ox::Error shutdownGfx(Context*) {
return OxError(0); return OxError(0);
} }

View File

@ -65,7 +65,7 @@ ox::Error model(T *io, NostalgiaGraphic *ng) {
[[nodiscard]] ox::Error initGfx(Context *ctx); [[nodiscard]] ox::Error initGfx(Context *ctx);
[[nodiscard]] ox::Error shutdownGfx(); [[nodiscard]] ox::Error shutdownGfx(Context*);
[[nodiscard]] ox::Error initConsole(Context *ctx); [[nodiscard]] ox::Error initConsole(Context *ctx);

View File

@ -14,6 +14,9 @@ ox::Error initGfx(Context*) {
return OxError(1); return OxError(1);
} }
ox::Error shutdownGfx(Context*) {
}
ox::Error initConsole(Context*) { ox::Error initConsole(Context*) {
return OxError(1); return OxError(1);
} }

View File

@ -12,9 +12,9 @@
namespace nostalgia::core { namespace nostalgia::core {
void draw(); void draw(Context *ctx);
ox::Error run() { ox::Error run(Context *ctx) {
for (auto running = true; running;) { for (auto running = true; running;) {
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
@ -30,7 +30,7 @@ ox::Error run() {
} }
} }
} }
draw(); draw(ctx);
} }
return OxError(0); return OxError(0);
} }

View File

@ -6,6 +6,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#define NOST_FPS_PRINT
#include <array> #include <array>
#include <vector> #include <vector>
#ifdef NOST_FPS_PRINT #ifdef NOST_FPS_PRINT
@ -20,12 +22,19 @@
namespace nostalgia::core { namespace nostalgia::core {
static SDL_Window *window = nullptr;
static SDL_Renderer *renderer = nullptr;
static std::array<SDL_Texture*, 4> bgTextures;
using TileMap = std::array<std::array<int, 128>, 128>; using TileMap = std::array<std::array<int, 128>, 128>;
static std::array<TileMap, 4> bgTileMaps;
struct SdlImplData {
SDL_Window *window = nullptr;
SDL_Renderer *renderer = nullptr;
std::array<SDL_Texture*, 4> bgTextures;
std::array<TileMap, 4> bgTileMaps;
#ifdef NOST_FPS_PRINT
uint64_t prevFpsCheckTime = 0;
uint64_t draws = 0;
#endif
};
[[nodiscard]] static ox::ValErr<ox::Vector<uint8_t>> readFile(Context *ctx, const ox::FileAddress &file) { [[nodiscard]] static ox::ValErr<ox::Vector<uint8_t>> readFile(Context *ctx, const ox::FileAddress &file) {
auto [stat, err] = ctx->rom->stat(file); auto [stat, err] = ctx->rom->stat(file);
@ -44,19 +53,23 @@ template<typename T>
return t; return t;
} }
ox::Error initGfx(Context*) { ox::Error initGfx(Context *ctx) {
window = SDL_CreateWindow("nostalgia", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768, auto id = new SdlImplData;
SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); ctx->setImplData(id);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); id->window = SDL_CreateWindow("nostalgia", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768,
return OxError(window == nullptr); SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
id->renderer = SDL_CreateRenderer(id->window, -1, SDL_RENDERER_ACCELERATED);
return OxError(id->window == nullptr);
} }
ox::Error shutdownGfx() { ox::Error shutdownGfx(Context *ctx) {
for (auto tex : bgTextures) { auto id = ctx->implData<SdlImplData>();
for (auto tex : id->bgTextures) {
SDL_DestroyTexture(tex); SDL_DestroyTexture(tex);
} }
SDL_DestroyRenderer(renderer); SDL_DestroyRenderer(id->renderer);
SDL_DestroyWindow(window); SDL_DestroyWindow(id->window);
delete id;
return OxError(0); return OxError(0);
} }
@ -89,6 +102,7 @@ ox::Error loadTileSheet(Context *ctx,
int section, int section,
ox::FileAddress tilesheetPath, ox::FileAddress tilesheetPath,
ox::FileAddress palettePath) { ox::FileAddress palettePath) {
auto id = ctx->implData<SdlImplData>();
auto [tilesheet, tserr] = readMC<NostalgiaGraphic>(ctx, tilesheetPath); auto [tilesheet, tserr] = readMC<NostalgiaGraphic>(ctx, tilesheetPath);
oxReturnError(tserr); oxReturnError(tserr);
NostalgiaPalette palette; NostalgiaPalette palette;
@ -110,28 +124,29 @@ ox::Error loadTileSheet(Context *ctx,
SDL_memcpy(surface->pixels, tilesheet.tiles.data(), bytesPerTile * tiles); SDL_memcpy(surface->pixels, tilesheet.tiles.data(), bytesPerTile * tiles);
} else { } else {
for (std::size_t i = 0; i < tilesheet.tiles.size(); ++i) { for (std::size_t i = 0; i < tilesheet.tiles.size(); ++i) {
static_cast<uint8_t*>(surface->pixels)[i * 2 + 0] = tilesheet.tiles[i] & 0xF; static_cast<uint8_t*>(surface->pixels)[i * 2 + 0] = tilesheet.tiles[i] & 0xF;
static_cast<uint8_t*>(surface->pixels)[i * 2 + 1] = tilesheet.tiles[i] >> 4; static_cast<uint8_t*>(surface->pixels)[i * 2 + 1] = tilesheet.tiles[i] >> 4;
} }
} }
auto texture = SDL_CreateTextureFromSurface(renderer, surface); auto texture = SDL_CreateTextureFromSurface(id->renderer, surface);
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
SDL_FreePalette(sdlPalette); SDL_FreePalette(sdlPalette);
if (tss == TileSheetSpace::Background) { if (tss == TileSheetSpace::Background) {
if (bgTextures[section]) { if (id->bgTextures[section]) {
SDL_DestroyTexture(bgTextures[section]); SDL_DestroyTexture(id->bgTextures[section]);
} }
bgTextures[section] = texture; id->bgTextures[section] = texture;
} }
return OxError(0); return OxError(0);
} }
void drawBackground(const TileMap &tm, SDL_Texture *tex) { void drawBackground(Context *ctx, const TileMap &tm, SDL_Texture *tex) {
if (tex) { if (tex) {
constexpr auto DstSize = 32; constexpr auto DstSize = 32;
auto id = ctx->implData<SdlImplData>();
//oxTrace("nostalgia::core::drawBackground") << "Drawing background"; //oxTrace("nostalgia::core::drawBackground") << "Drawing background";
SDL_Rect src = {}, dst = {}; SDL_Rect src = {}, dst = {};
src.x = 0; src.x = 0;
@ -144,7 +159,7 @@ void drawBackground(const TileMap &tm, SDL_Texture *tex) {
for (auto &m : tm) { for (auto &m : tm) {
for (auto t : m) { for (auto t : m) {
src.y = t * 8; src.y = t * 8;
SDL_RenderCopy(renderer, tex, &src, &dst); SDL_RenderCopy(id->renderer, tex, &src, &dst);
dst.x += DstSize; dst.x += DstSize;
} }
dst.x = 0; dst.x = 0;
@ -153,34 +168,31 @@ void drawBackground(const TileMap &tm, SDL_Texture *tex) {
} }
} }
void draw(Context *ctx) {
auto id = ctx->implData<SdlImplData>();
#ifdef NOST_FPS_PRINT #ifdef NOST_FPS_PRINT
static uint64_t prevFpsCheckTime = 0; ++id->draws;
static uint64_t draws = 0; if (id->draws >= 5000) {
#endif
void draw() {
#ifdef NOST_FPS_PRINT
++draws;
if (draws >= 5000) {
using namespace std::chrono; using namespace std::chrono;
auto now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); auto now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
auto duration = static_cast<double>(now - prevFpsCheckTime) / 1000.0; auto duration = static_cast<double>(now - id->prevFpsCheckTime) / 1000.0;
std::cout << "FPS: " << static_cast<int>(static_cast<double>(draws) / duration) << '\n'; std::cout << "FPS: " << static_cast<int>(static_cast<double>(id->draws) / duration) << '\n';
prevFpsCheckTime = now; id->prevFpsCheckTime = now;
draws = 0; id->draws = 0;
} }
#endif #endif
SDL_RenderClear(renderer); SDL_RenderClear(id->renderer);
for (std::size_t i = 0; i < bgTileMaps.size(); i++) { for (std::size_t i = 0; i < id->bgTileMaps.size(); i++) {
auto tex = bgTextures[i]; auto tex = id->bgTextures[i];
auto &tm = bgTileMaps[i]; auto &tm = id->bgTileMaps[i];
drawBackground(tm, tex); drawBackground(ctx, tm, tex);
} }
SDL_RenderPresent(renderer); SDL_RenderPresent(id->renderer);
} }
void setTile(Context*, int layer, int column, int row, uint8_t tile) { void setTile(Context *ctx, int layer, int column, int row, uint8_t tile) {
bgTileMaps[layer][row][column] = tile; auto id = ctx->implData<SdlImplData>();
id->bgTileMaps[layer][row][column] = tile;
} }
} }

View File

@ -22,8 +22,8 @@ ox::Error run(ox::FileSystem *fs) {
//zone.draw(&ctx); //zone.draw(&ctx);
oxReturnError(core::initConsole(&ctx)); oxReturnError(core::initConsole(&ctx));
core::puts(&ctx, 10, 9, "DOPENESS!!!"); core::puts(&ctx, 10, 9, "DOPENESS!!!");
oxReturnError(core::run()); oxReturnError(core::run(&ctx));
oxReturnError(core::shutdownGfx()); oxReturnError(core::shutdownGfx(&ctx));
return OxError(0); return OxError(0);
} }