[nostalgia/core/gba] Fix C++20 compatibility issues
This commit is contained in:
parent
d58570d76b
commit
67cbe6ef7f
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user