[nostalgia/core/gba] Fix C++20 compatibility issues

This commit is contained in:
Gary Talent 2021-01-21 00:24:02 -06:00
parent d58570d76b
commit 67cbe6ef7f
4 changed files with 51 additions and 38 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016 - 2020 gary@drinkingtea.net * Copyright 2016 - 2021 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -37,7 +37,7 @@ static void initTimer() {
REG_TIMER0 = TicksMs59ns; REG_TIMER0 = TicksMs59ns;
REG_TIMER0CTL = 0b11000000; REG_TIMER0CTL = 0b11000000;
// enable interrupt for timer0 // enable interrupt for timer0
REG_IE |= Int_timer0; REG_IE = REG_IE | Int_timer0;
} }
ox::Error init(Context *ctx) { ox::Error init(Context *ctx) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016 - 2020 gary@drinkingtea.net * Copyright 2016 - 2021 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -8,7 +8,6 @@
#include <ox/fs/fs.hpp> #include <ox/fs/fs.hpp>
#include <ox/mc/mc.hpp> #include <ox/mc/mc.hpp>
#include <ox/std/std.hpp>
#include <nostalgia/core/media.hpp> #include <nostalgia/core/media.hpp>
#include <nostalgia/core/gfx.hpp> #include <nostalgia/core/gfx.hpp>
@ -66,15 +65,15 @@ ox::Error modelRead(T *io, GbaTileMapTarget *t) {
constexpr auto Bpp8 = 1 << 7; constexpr auto Bpp8 = 1 << 7;
*t->bgCtl = (28 << 8) | 1; *t->bgCtl = (28 << 8) | 1;
if (bpp == 4) { if (bpp == 4) {
*t->bgCtl |= (*t->bgCtl | Bpp8) ^ Bpp8; // set to use 4 bits per pixel *t->bgCtl = *t->bgCtl | ((*t->bgCtl | Bpp8) ^ Bpp8); // set to use 4 bits per pixel
} else { } else {
*t->bgCtl |= Bpp8; // set to use 8 bits per pixel *t->bgCtl = *t->bgCtl | Bpp8; // set to use 8 bits per pixel
} }
oxReturnError(io->field("defaultPalette", &t->defaultPalette)); oxReturnError(io->field("defaultPalette", &t->defaultPalette));
oxReturnError(io->field("pal", &t->pal)); oxReturnError(io->field("pal", &t->pal));
uint16_t intermediate = 0; uint16_t intermediate = 0;
auto handleTileMap = [t, &intermediate](std::size_t i, uint8_t *tile) { const auto handleTileMap = [t, &intermediate](std::size_t i, uint8_t *tile) {
if (i & 1) { // i is odd if (i & 1) { // i is odd
intermediate |= static_cast<uint16_t>(*tile) << 8; intermediate |= static_cast<uint16_t>(*tile) << 8;
t->tileMap[i / 2] = intermediate; t->tileMap[i / 2] = intermediate;
@ -92,9 +91,9 @@ ox::Error initGfx(Context*) {
| DispCtl_Bg0 | DispCtl_Bg0
| DispCtl_Obj; | DispCtl_Obj;
// tell display to trigger vblank interrupts // tell display to trigger vblank interrupts
REG_DISPSTAT |= DispStat_irq_vblank; REG_DISPSTAT = REG_DISPSTAT | DispStat_irq_vblank;
// enable vblank interrupt // enable vblank interrupt
REG_IE |= Int_vblank; REG_IE = REG_IE | Int_vblank;
return OxError(0); return OxError(0);
} }
@ -138,9 +137,9 @@ ox::Error loadBgTileSheet(Context *ctx,
int section, int section,
ox::FileAddress tilesheetAddr, ox::FileAddress tilesheetAddr,
ox::FileAddress paletteAddr) { ox::FileAddress paletteAddr) {
auto [tsStat, tsStatErr] = ctx->rom->stat(tilesheetAddr); const auto [tsStat, tsStatErr] = ctx->rom->stat(tilesheetAddr);
oxReturnError(tsStatErr); oxReturnError(tsStatErr);
auto [ts, tserr] = ctx->rom->read(tilesheetAddr); const auto [ts, tserr] = ctx->rom->read(tilesheetAddr);
oxReturnError(tserr); oxReturnError(tserr);
GbaTileMapTarget target; GbaTileMapTarget target;
target.pal.palette = &MEM_BG_PALETTE[section]; target.pal.palette = &MEM_BG_PALETTE[section];
@ -162,9 +161,9 @@ ox::Error loadSpriteTileSheet(Context *ctx,
int section, int section,
ox::FileAddress tilesheetAddr, ox::FileAddress tilesheetAddr,
ox::FileAddress paletteAddr) { ox::FileAddress paletteAddr) {
auto [tsStat, tsStatErr] = ctx->rom->stat(tilesheetAddr); const auto [tsStat, tsStatErr] = ctx->rom->stat(tilesheetAddr);
oxReturnError(tsStatErr); oxReturnError(tsStatErr);
auto [ts, tserr] = ctx->rom->read(tilesheetAddr); const auto [ts, tserr] = ctx->rom->read(tilesheetAddr);
oxReturnError(tserr); oxReturnError(tserr);
GbaTileMapTarget target; GbaTileMapTarget target;
target.pal.palette = &MEM_SPRITE_PALETTE[section]; target.pal.palette = &MEM_SPRITE_PALETTE[section];
@ -173,9 +172,9 @@ ox::Error loadSpriteTileSheet(Context *ctx,
oxReturnError(ox::readMC(ts, tsStat.size, &target)); oxReturnError(ox::readMC(ts, tsStat.size, &target));
// load external palette if available // load external palette if available
if (paletteAddr) { if (paletteAddr) {
auto [palStat, palStatErr] = ctx->rom->stat(paletteAddr); const auto [palStat, palStatErr] = ctx->rom->stat(paletteAddr);
oxReturnError(palStatErr); oxReturnError(palStatErr);
auto [pal, palErr] = ctx->rom->read(paletteAddr); const auto [pal, palErr] = ctx->rom->read(paletteAddr);
oxReturnError(palErr); oxReturnError(palErr);
oxReturnError(ox::readMC(pal, palStat.size, &target.pal)); oxReturnError(ox::readMC(pal, palStat.size, &target.pal));
} }
@ -185,9 +184,9 @@ ox::Error loadSpriteTileSheet(Context *ctx,
ox::Error loadBgPalette(Context *ctx, int section, ox::FileAddress paletteAddr) { ox::Error loadBgPalette(Context *ctx, int section, ox::FileAddress paletteAddr) {
GbaPaletteTarget target; GbaPaletteTarget target;
target.palette = &MEM_BG_PALETTE[section]; target.palette = &MEM_BG_PALETTE[section];
auto [palStat, palStatErr] = ctx->rom->stat(paletteAddr); const auto [palStat, palStatErr] = ctx->rom->stat(paletteAddr);
oxReturnError(palStatErr); oxReturnError(palStatErr);
auto [pal, palErr] = ctx->rom->read(paletteAddr); const auto [pal, palErr] = ctx->rom->read(paletteAddr);
oxReturnError(palErr); oxReturnError(palErr);
oxReturnError(ox::readMC(pal, palStat.size, &target)); oxReturnError(ox::readMC(pal, palStat.size, &target));
return OxError(0); return OxError(0);
@ -196,9 +195,9 @@ ox::Error loadBgPalette(Context *ctx, int section, ox::FileAddress paletteAddr)
ox::Error loadSpritePalette(Context *ctx, int section, ox::FileAddress paletteAddr) { ox::Error loadSpritePalette(Context *ctx, int section, ox::FileAddress paletteAddr) {
GbaPaletteTarget target; GbaPaletteTarget target;
target.palette = &MEM_SPRITE_PALETTE[section]; target.palette = &MEM_SPRITE_PALETTE[section];
auto [palStat, palStatErr] = ctx->rom->stat(paletteAddr); const auto [palStat, palStatErr] = ctx->rom->stat(paletteAddr);
oxReturnError(palStatErr); oxReturnError(palStatErr);
auto [pal, palErr] = ctx->rom->read(paletteAddr); const auto [pal, palErr] = ctx->rom->read(paletteAddr);
oxReturnError(palErr); oxReturnError(palErr);
oxReturnError(ox::readMC(pal, palStat.size, &target)); oxReturnError(ox::readMC(pal, palStat.size, &target));
return OxError(0); return OxError(0);
@ -221,6 +220,7 @@ void clearTileLayer(Context*, int layer) {
} }
void hideSprite(Context*, unsigned idx) { void hideSprite(Context*, unsigned idx) {
oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
GbaSpriteAttrUpdate oa; GbaSpriteAttrUpdate oa;
oa.attr0 = 2 << 8; oa.attr0 = 2 << 8;
oa.idx = idx; oa.idx = idx;
@ -229,18 +229,26 @@ void hideSprite(Context*, unsigned idx) {
nostalgia_core_vblankintrwait(); nostalgia_core_vblankintrwait();
} }
if constexpr(config::GbaEventLoopTimerBased) { if constexpr(config::GbaEventLoopTimerBased) {
REG_IE &= ~Int_vblank; // disable vblank interrupt handler REG_IE = REG_IE & ~Int_vblank; // disable vblank interrupt handler
g_spriteBuffer[g_spriteUpdates++] = oa; g_spriteBuffer[g_spriteUpdates] = oa;
REG_IE |= Int_vblank; // enable vblank interrupt handler REG_IE = REG_IE | Int_vblank; // enable vblank interrupt handler
} else { } else {
auto ie = REG_IE; // disable vblank interrupt handler const auto ie = REG_IE; // disable vblank interrupt handler
REG_IE &= ~Int_vblank; // disable vblank interrupt handler REG_IE = REG_IE & ~Int_vblank; // disable vblank interrupt handler
g_spriteBuffer[g_spriteUpdates++] = oa; g_spriteBuffer[g_spriteUpdates] = oa;
REG_IE = ie; // enable vblank interrupt handler REG_IE = ie; // enable vblank interrupt handler
} }
g_spriteUpdates = g_spriteUpdates + 1;
} }
void setSprite(Context*, unsigned idx, unsigned x, unsigned y, unsigned tileIdx, unsigned spriteShape, unsigned spriteSize, unsigned flipX) { void setSprite(Context*,
unsigned idx,
unsigned x,
unsigned y,
unsigned tileIdx,
unsigned spriteShape,
unsigned spriteSize,
unsigned flipX) {
oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow"); oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
GbaSpriteAttrUpdate oa; GbaSpriteAttrUpdate oa;
oa.attr0 = static_cast<uint16_t>(y & ox::onMask<uint8_t>(7)) oa.attr0 = static_cast<uint16_t>(y & ox::onMask<uint8_t>(7))
@ -256,15 +264,16 @@ void setSprite(Context*, unsigned idx, unsigned x, unsigned y, unsigned tileIdx,
nostalgia_core_vblankintrwait(); nostalgia_core_vblankintrwait();
} }
if constexpr(config::GbaEventLoopTimerBased) { if constexpr(config::GbaEventLoopTimerBased) {
REG_IE &= ~Int_vblank; // disable vblank interrupt handler REG_IE = REG_IE & ~Int_vblank; // disable vblank interrupt handler
g_spriteBuffer[g_spriteUpdates++] = oa; g_spriteBuffer[g_spriteUpdates] = oa;
REG_IE |= Int_vblank; // enable vblank interrupt handler REG_IE = REG_IE | Int_vblank; // enable vblank interrupt handler
} else { } else {
auto ie = REG_IE; // disable vblank interrupt handler const auto ie = REG_IE; // disable vblank interrupt handler
REG_IE &= ~Int_vblank; // disable vblank interrupt handler REG_IE = REG_IE & ~Int_vblank; // disable vblank interrupt handler
g_spriteBuffer[g_spriteUpdates++] = oa; g_spriteBuffer[g_spriteUpdates] = oa;
REG_IE = ie; // enable vblank interrupt handler REG_IE = ie; // enable vblank interrupt handler
} }
g_spriteUpdates = g_spriteUpdates + 1;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016 - 2020 gary@drinkingtea.net * Copyright 2016 - 2021 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -9,6 +9,8 @@
// NOTE: this file is compiled as ARM and not THUMB, so don't but too much in // NOTE: this file is compiled as ARM and not THUMB, so don't but too much in
// here // here
#include <ox/std/bit.hpp>
#include "addresses.hpp" #include "addresses.hpp"
#include "gfx.hpp" #include "gfx.hpp"
#include "irq.hpp" #include "irq.hpp"
@ -32,18 +34,18 @@ void nostalgia_core_isr_vblank() {
// is volatile // is volatile
const auto updates = g_spriteUpdates; const auto updates = g_spriteUpdates;
for (uint16_t i = 0; i < updates; ++i) { for (uint16_t i = 0; i < updates; ++i) {
auto &oa = g_spriteBuffer[i]; const auto &oa = g_spriteBuffer[i];
MEM_OAM[oa.idx] = *reinterpret_cast<uint64_t*>(&oa); MEM_OAM[oa.idx] = *ox::bit_cast<const uint64_t*>(&oa);
} }
g_spriteUpdates = 0; g_spriteUpdates = 0;
if constexpr(config::GbaEventLoopTimerBased) { if constexpr(config::GbaEventLoopTimerBased) {
// disable vblank interrupt until it is needed again // disable vblank interrupt until it is needed again
REG_IE &= ~Int_vblank; REG_IE = REG_IE & ~Int_vblank;
} }
} }
void nostalgia_core_isr_timer0() { void nostalgia_core_isr_timer0() {
++g_timerMs; g_timerMs = g_timerMs + 1;
} }
} }

View File

@ -1,11 +1,13 @@
/* /*
* Copyright 2016 - 2020 gary@drinkingtea.net * Copyright 2016 - 2021 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include <ox/std/types.hpp>
namespace nostalgia::core { namespace nostalgia::core {
constexpr uint16_t Int_vblank = 1 << 0; constexpr uint16_t Int_vblank = 1 << 0;