all repos — mgba @ 507d033a973907ed9040ea6b4a6df84176559c27

mGBA Game Boy Advance Emulator

GB Video: Support map cache
Vicki Pfau vi@endrift.com
Sat, 23 Sep 2017 11:00:26 -0700
commit

507d033a973907ed9040ea6b4a6df84176559c27

parent

6e9507f0822f76bba63f29fba6a78d1f14f34b9f

M include/mgba/internal/gb/renderers/cache-set.hinclude/mgba/internal/gb/renderers/cache-set.h

@@ -16,6 +16,8 @@

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
M src/gb/core.csrc/gb/core.c

@@ -26,8 +26,8 @@ #include <mgba-util/vfs.h>

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[] = {
M src/gb/renderers/cache-set.csrc/gb/renderers/cache-set.c

@@ -6,16 +6,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#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 @@ size_t i;

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); }
M src/gb/renderers/software.csrc/gb/renderers/software.c

@@ -7,6 +7,7 @@ #include <mgba/internal/gb/renderers/software.h>

#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 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;
M src/gb/video.csrc/gb/video.c

@@ -10,6 +10,7 @@ #include <mgba/core/thread.h>

#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 @@ // Nothing to do

} 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; }
M src/platform/qt/MapView.cppsrc/platform/qt/MapView.cpp

@@ -72,7 +72,6 @@ m_map = map;

updateTiles(true); } -#ifdef M_CORE_GBA void MapView::updateTilesGBA(bool force) { QImage bg; {

@@ -98,10 +97,10 @@ map = map.scaled(map.size() * m_ui.magnification->value());

} m_ui.map->setPixmap(map); } -#endif #ifdef M_CORE_GB void MapView::updateTilesGB(bool force) { + updateTilesGBA(force); } #endif