|
|
|
@@ -71,42 +71,43 @@ constexpr ox::Error model(auto *io, ox::CommonPtrWith<GbaTileMapTarget> auto *t)
|
|
|
|
|
return io->template field<uint8_t, decltype(handleTileMap)>("tileMap", handleTileMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ox::Error initGfx(Context*, InitParams const&) noexcept {
|
|
|
|
|
ox::Error initGfx(Context&, InitParams const&) noexcept {
|
|
|
|
|
for (auto bgCtl = ®_BG0CTL; bgCtl <= ®_BG3CTL; bgCtl += 2) {
|
|
|
|
|
teagba::bgSetSbb(bgCtl, 28);
|
|
|
|
|
}
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void shutdownGfx(Context*) noexcept {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t bgStatus(Context*) noexcept {
|
|
|
|
|
uint8_t bgStatus(Context&) noexcept {
|
|
|
|
|
return (REG_DISPCTL >> 8u) & 0b1111u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setBgStatus(Context*, uint32_t status) noexcept {
|
|
|
|
|
void setBgStatus(Context&, uint32_t status) noexcept {
|
|
|
|
|
constexpr auto BgStatus = 8;
|
|
|
|
|
REG_DISPCTL = (REG_DISPCTL & ~0b111100000000u) | status << BgStatus;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool bgStatus(Context*, unsigned bg) noexcept {
|
|
|
|
|
bool bgStatus(Context&, unsigned bg) noexcept {
|
|
|
|
|
return (REG_DISPCTL >> (8 + bg)) & 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setBgStatus(Context*, unsigned bg, bool status) noexcept {
|
|
|
|
|
void setBgStatus(Context&, unsigned bg, bool status) noexcept {
|
|
|
|
|
constexpr auto Bg0Status = 8;
|
|
|
|
|
const auto mask = static_cast<uint32_t>(status) << (Bg0Status + bg);
|
|
|
|
|
REG_DISPCTL = REG_DISPCTL | ((REG_DISPCTL & ~mask) | mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setBgCbb(Context*, unsigned bgIdx, unsigned cbb) noexcept {
|
|
|
|
|
static void setBgCbb(Context*, unsigned bgIdx, unsigned cbb) noexcept {
|
|
|
|
|
auto &bgCtl = regBgCtl(bgIdx);
|
|
|
|
|
const auto &cbbData = g_cbbData[cbb];
|
|
|
|
|
teagba::bgSetBpp(&bgCtl, cbbData.bpp);
|
|
|
|
|
teagba::bgSetCbb(&bgCtl, cbb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setBgCbb(Context&, unsigned bgIdx, unsigned cbb) noexcept {
|
|
|
|
|
setBgCbb(nullptr, bgIdx, cbb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ox::Error loadBgTileSheet(
|
|
|
|
|
const ox::MemFS &rom,
|
|
|
|
|
unsigned cbb,
|
|
|
|
@@ -136,20 +137,20 @@ static ox::Error loadBgTileSheet(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ox::Error loadBgTileSheet(
|
|
|
|
|
Context *ctx,
|
|
|
|
|
Context &ctx,
|
|
|
|
|
unsigned cbb,
|
|
|
|
|
ox::FileAddress const&tilesheetAddr,
|
|
|
|
|
ox::FileAddress const&paletteAddr) noexcept {
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(*ctx);
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(ctx);
|
|
|
|
|
auto &rom = static_cast<const ox::MemFS&>(gctx.rom());
|
|
|
|
|
return loadBgTileSheet(rom, cbb, tilesheetAddr, paletteAddr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ox::Error loadSpriteTileSheet(
|
|
|
|
|
Context *ctx,
|
|
|
|
|
Context &ctx,
|
|
|
|
|
ox::FileAddress const&tilesheetAddr,
|
|
|
|
|
ox::FileAddress const&paletteAddr) noexcept {
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(*ctx);
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(ctx);
|
|
|
|
|
auto &rom = static_cast<const ox::MemFS&>(gctx.rom());
|
|
|
|
|
oxRequire(tsStat, gctx.rom().stat(tilesheetAddr));
|
|
|
|
|
oxRequire(ts, rom.directAccess(tilesheetAddr));
|
|
|
|
@@ -166,8 +167,8 @@ ox::Error loadSpriteTileSheet(
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ox::Error loadBgPalette(Context *ctx, unsigned, ox::FileAddress const&paletteAddr) noexcept {
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(*ctx);
|
|
|
|
|
ox::Error loadBgPalette(Context &ctx, unsigned, ox::FileAddress const&paletteAddr) noexcept {
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(ctx);
|
|
|
|
|
auto &rom = static_cast<const ox::MemFS&>(gctx.rom());
|
|
|
|
|
GbaPaletteTarget target;
|
|
|
|
|
target.palette = MEM_BG_PALETTE;
|
|
|
|
@@ -177,8 +178,8 @@ ox::Error loadBgPalette(Context *ctx, unsigned, ox::FileAddress const&paletteAdd
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ox::Error loadSpritePalette(Context *ctx, unsigned cbb, ox::FileAddress const&paletteAddr) noexcept {
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(*ctx);
|
|
|
|
|
ox::Error loadSpritePalette(Context &ctx, unsigned cbb, ox::FileAddress const&paletteAddr) noexcept {
|
|
|
|
|
auto &gctx = static_cast<GbaContext&>(ctx);
|
|
|
|
|
auto &rom = static_cast<const ox::MemFS&>(gctx.rom());
|
|
|
|
|
GbaPaletteTarget target;
|
|
|
|
|
target.palette = &MEM_SPRITE_PALETTE[cbb];
|
|
|
|
@@ -188,25 +189,16 @@ ox::Error loadSpritePalette(Context *ctx, unsigned cbb, ox::FileAddress const&pa
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do NOT rely on Context in the GBA version of this function.
|
|
|
|
|
ox::Error initConsole(Context *ctx) noexcept {
|
|
|
|
|
ox::Error initConsole(Context &ctx) noexcept {
|
|
|
|
|
constexpr ox::FileAddress TilesheetAddr("/TileSheets/Charset.ng");
|
|
|
|
|
constexpr ox::FileAddress PaletteAddr("/Palettes/Charset.npal");
|
|
|
|
|
setBgStatus(ctx, 0b0001);
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
oxRequire(rom, keel::loadRom());
|
|
|
|
|
const ox::FileSystem32 romFs(ox::FileStore32(rom, 32 * ox::units::MB));
|
|
|
|
|
oxReturnError(loadBgTileSheet(romFs, 0, TilesheetAddr, PaletteAddr));
|
|
|
|
|
setBgCbb(nullptr, 0, 0);
|
|
|
|
|
return {};
|
|
|
|
|
} else {
|
|
|
|
|
oxReturnError(loadBgTileSheet(ctx, 0, TilesheetAddr, PaletteAddr));
|
|
|
|
|
setBgCbb(ctx, 0, 0);
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
oxReturnError(loadBgTileSheet(ctx, 0, TilesheetAddr, PaletteAddr));
|
|
|
|
|
setBgCbb(ctx, 0, 0);
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void puts(Context *ctx, int column, int row, ox::CRStringView str) noexcept {
|
|
|
|
|
void puts(Context &ctx, int column, int row, ox::CRStringView str) noexcept {
|
|
|
|
|
const auto col = static_cast<unsigned>(column);
|
|
|
|
|
for (auto i = 0u; i < str.bytes(); i++) {
|
|
|
|
|
const auto c = charMap[static_cast<std::size_t>(str[i])];
|
|
|
|
@@ -214,18 +206,18 @@ void puts(Context *ctx, int column, int row, ox::CRStringView str) noexcept {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setTile(Context*, unsigned bgIdx, int column, int row, uint8_t tile) noexcept {
|
|
|
|
|
void setTile(Context&, unsigned bgIdx, int column, int row, uint8_t tile) noexcept {
|
|
|
|
|
const auto tileIdx = static_cast<std::size_t>(row * GbaTileColumns + column);
|
|
|
|
|
MEM_BG_MAP[bgIdx][tileIdx] = tile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do NOT use Context in the GBA version of this function.
|
|
|
|
|
void clearTileLayer(Context*, unsigned bgIdx) noexcept {
|
|
|
|
|
void clearTileLayer(Context&, unsigned bgIdx) noexcept {
|
|
|
|
|
memset(MEM_BG_MAP[bgIdx].data(), 0, GbaTileRows * GbaTileColumns);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[maybe_unused]]
|
|
|
|
|
void hideSprite(Context*, unsigned idx) noexcept {
|
|
|
|
|
void hideSprite(Context&, unsigned idx) noexcept {
|
|
|
|
|
//oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
|
|
|
|
|
teagba::GbaSpriteAttrUpdate oa;
|
|
|
|
|
oa.attr0 = 2 << 8;
|
|
|
|
@@ -233,7 +225,7 @@ void hideSprite(Context*, unsigned idx) noexcept {
|
|
|
|
|
teagba::addSpriteUpdate(oa);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setSprite(Context*,
|
|
|
|
|
void setSprite(Context&,
|
|
|
|
|
unsigned idx,
|
|
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|