GB Video: Support map cache

This commit is contained in:
Vicki Pfau 2017-09-23 11:00:26 -07:00
parent 6e9507f082
commit 507d033a97
6 changed files with 119 additions and 7 deletions

View File

@ -16,6 +16,8 @@ struct mCacheSet;
void GBVideoCacheInit(struct mCacheSet* cache);
void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video);
void GBVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint16_t address, uint8_t value);
CXX_GUARD_END
#endif

View File

@ -26,8 +26,8 @@
static const struct mCoreChannelInfo _GBVideoLayers[] = {
{ 0, "bg", "Background", NULL },
{ 1, "obj", "Objects", NULL },
{ 2, "win", "Window", NULL },
{ 1, "bgwin", "Window", NULL },
{ 2, "obj", "Objects", NULL },
};
static const struct mCoreChannelInfo _GBAudioChannels[] = {

View File

@ -6,16 +6,23 @@
#include <mgba/internal/gb/renderers/cache-set.h>
#include <mgba/core/cache-set.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/video.h>
void GBVideoCacheInit(struct mCacheSet* cache) {
mCacheSetInit(cache, 0, 1);
mCacheSetInit(cache, 2, 1);
mTileCacheConfiguration config = 0;
config = mTileCacheSystemInfoSetPaletteBPP(config, 1); // 2^(2^1) = 4 entries
config = mTileCacheSystemInfoSetPaletteCount(config, 4); // 16 palettes
config = mTileCacheSystemInfoSetMaxTiles(config, 1024);
mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 0));
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), config, 0, 0);
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 0));
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 1));
mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0);
}
void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video) {
@ -25,4 +32,102 @@ void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video) {
for (i = 0; i < 64; ++i) {
mCacheSetWritePalette(cache, i, mColorFrom555(video->palette[i]));
}
mMapCacheSystemInfo sysconfig = mMapCacheSystemInfoSetPaletteCount(0, 0);
if (video->p->model >= GB_MODEL_CGB) {
sysconfig = mMapCacheSystemInfoSetPaletteCount(0, 2);
}
mMapCacheConfigureSystem(mMapCacheSetGetPointer(&cache->maps, 0), sysconfig);
mMapCacheConfigureSystem(mMapCacheSetGetPointer(&cache->maps, 1), sysconfig);
GBVideoCacheWriteVideoRegister(cache, REG_LCDC, video->p->memory.io[REG_LCDC]);
}
static void mapParserDMG0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
UNUSED(cache);
int map = *(uint8_t*) vram;
entry->tileId = map;
entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
entry->flags = mMapCacheEntryFlagsClearVMirror(entry->flags);
entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, 0);
}
static void mapParserDMG1(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
UNUSED(cache);
int map = *(int8_t*) vram;
entry->tileId = map + 128;
entry->flags = mMapCacheEntryFlagsClearHMirror(entry->flags);
entry->flags = mMapCacheEntryFlagsClearVMirror(entry->flags);
entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, 0);
}
static void mapParserCGB0(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
UNUSED(cache);
int map = *(uint8_t*) vram;
uint8_t attr = ((uint8_t*) vram)[0x2000];
entry->tileId = map + GBObjAttributesGetBank(attr) * 512;
entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBObjAttributesGetXFlip(attr));
entry->flags = mMapCacheEntryFlagsSetVMirror(entry->flags, GBObjAttributesGetYFlip(attr));
entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBObjAttributesGetCGBPalette(attr));
}
static void mapParserCGB1(struct mMapCache* cache, struct mMapCacheEntry* entry, void* vram) {
UNUSED(cache);
int map = *(int8_t*) vram;
uint8_t attr = ((uint8_t*) vram)[0x2000];
entry->tileId = map + 128 + GBObjAttributesGetBank(attr) * 512;
entry->flags = mMapCacheEntryFlagsSetHMirror(entry->flags, GBObjAttributesGetXFlip(attr));
entry->flags = mMapCacheEntryFlagsSetVMirror(entry->flags, GBObjAttributesGetYFlip(attr));
entry->flags = mMapCacheEntryFlagsSetPaletteId(entry->flags, GBObjAttributesGetCGBPalette(attr));
}
void GBVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint16_t address, uint8_t value) {
if (address != REG_LCDC) {
return;
}
struct mMapCache* map = mMapCacheSetGetPointer(&cache->maps, 0);
struct mMapCache* window = mMapCacheSetGetPointer(&cache->maps, 1);
mMapCacheSystemInfo sysconfig = mMapCacheSystemInfoIsPaletteCount(map->sysConfig);
int tileStart = 0;
int mapStart = GB_BASE_MAP;
int windowStart = GB_BASE_MAP;
if (GBRegisterLCDCIsTileMap(value)) {
mapStart += GB_SIZE_MAP;
}
if (GBRegisterLCDCIsWindowTileMap(value)) {
windowStart += GB_SIZE_MAP;
}
if (GBRegisterLCDCIsTileData(value)) {
if (!sysconfig) {
map->mapParser = mapParserDMG0;
window->mapParser = mapParserDMG0;
} else {
map->mapParser = mapParserCGB0;
window->mapParser = mapParserCGB0;
}
} else {
if (!sysconfig) {
map->mapParser = mapParserDMG1;
window->mapParser = mapParserDMG1;
} else {
map->mapParser = mapParserCGB1;
window->mapParser = mapParserCGB1;
}
tileStart = 0x80;
}
map->tileStart = tileStart;
window->tileStart = tileStart;
if (sysconfig) {
sysconfig = mMapCacheSystemInfoSetMaxTiles(sysconfig, 896);
} else {
sysconfig = mMapCacheSystemInfoSetMaxTiles(sysconfig, 384);
}
sysconfig = mMapCacheSystemInfoSetPaletteBPP(sysconfig, 1);
sysconfig = mMapCacheSystemInfoSetMapAlign(sysconfig, 0);
sysconfig = mMapCacheSystemInfoSetTilesHigh(sysconfig, 5);
sysconfig = mMapCacheSystemInfoSetTilesWide(sysconfig, 5);
mMapCacheConfigureSystem(map, sysconfig);
mMapCacheConfigureSystem(window, sysconfig);
mMapCacheConfigureMap(map, mapStart);
mMapCacheConfigureMap(window, windowStart);
}

View File

@ -7,6 +7,7 @@
#include <mgba/core/cache-set.h>
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/renderers/cache-set.h>
#include <mgba-util/math.h>
#include <mgba-util/memory.h>
@ -194,6 +195,9 @@ static void GBVideoSoftwareRendererDeinit(struct GBVideoRenderer* renderer) {
static uint8_t GBVideoSoftwareRendererWriteVideoRegister(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value) {
struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
if (renderer->cache) {
GBVideoCacheWriteVideoRegister(renderer->cache, address, value);
}
switch (address) {
case REG_LCDC:
softwareRenderer->lcdc = value;

View File

@ -10,6 +10,7 @@
#include <mgba/core/cache-set.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/io.h>
#include <mgba/internal/gb/renderers/cache-set.h>
#include <mgba/internal/gb/serialize.h>
#include <mgba/internal/lr35902/lr35902.h>
@ -693,8 +694,9 @@ static void GBVideoDummyRendererDeinit(struct GBVideoRenderer* renderer) {
}
static uint8_t GBVideoDummyRendererWriteVideoRegister(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value) {
UNUSED(renderer);
UNUSED(address);
if (renderer->cache) {
GBVideoCacheWriteVideoRegister(renderer->cache, address, value);
}
return value;
}

View File

@ -72,7 +72,6 @@ void MapView::selectMap(int map) {
updateTiles(true);
}
#ifdef M_CORE_GBA
void MapView::updateTilesGBA(bool force) {
QImage bg;
{
@ -98,10 +97,10 @@ void MapView::updateTilesGBA(bool force) {
}
m_ui.map->setPixmap(map);
}
#endif
#ifdef M_CORE_GB
void MapView::updateTilesGB(bool force) {
updateTilesGBA(force);
}
#endif