diff --git a/include/mgba/core/map-cache.h b/include/mgba/core/map-cache.h index 5d16287b4..22771459d 100644 --- a/include/mgba/core/map-cache.h +++ b/include/mgba/core/map-cache.h @@ -56,6 +56,7 @@ struct mMapCache { mMapCacheSystemInfo sysConfig; void (*mapParser)(struct mMapCache*, struct mMapCacheEntry* entry, void* vram); + void* context; }; void mMapCacheInit(struct mMapCache* cache); diff --git a/src/core/map-cache.c b/src/core/map-cache.c index f818c7e2f..ed18979f6 100644 --- a/src/core/map-cache.c +++ b/src/core/map-cache.c @@ -132,21 +132,21 @@ static inline size_t _tileId(struct mMapCache* cache, unsigned x, unsigned y) { void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y) { size_t location = _tileId(cache, x, y); struct mMapCacheEntry* status = &cache->status[location]; - int paletteId = mMapCacheEntryFlagsGetPaletteId(status->flags); const color_t* tile = NULL; if (!mMapCacheEntryFlagsIsVramClean(status->flags)) { status->flags = mMapCacheEntryFlagsFillVramClean(status->flags); cache->mapParser(cache, status, &cache->vram[cache->mapStart + (location << mMapCacheSystemInfoGetMapAlign(cache->sysConfig))]); - tile = mTileCacheGetTileIfDirty(cache->tileCache, &status->tileStatus[paletteId], status->tileId + cache->tileStart, mMapCacheEntryFlagsGetPaletteId(status->flags)); - if (!tile) { - tile = mTileCacheGetTile(cache->tileCache, status->tileId + cache->tileStart, mMapCacheEntryFlagsGetPaletteId(status->flags)); - } - } else { - tile = mTileCacheGetTileIfDirty(cache->tileCache, &status->tileStatus[paletteId], status->tileId + cache->tileStart, mMapCacheEntryFlagsGetPaletteId(status->flags)); - if (!tile && memcmp(status, &entry[location], sizeof(*entry)) == 0) { + } + unsigned tileId = status->tileId + cache->tileStart; + if (tileId >= mTileCacheSystemInfoGetMaxTiles(cache->tileCache->sysConfig)) { + tileId = 0; + } + tile = mTileCacheGetTileIfDirty(cache->tileCache, status->tileStatus, tileId, mMapCacheEntryFlagsGetPaletteId(status->flags)); + if (!tile) { + if (mMapCacheEntryFlagsIsVramClean(status->flags) && memcmp(status, &entry[location], sizeof(*entry)) == 0) { return; } - tile = mTileCacheGetTile(cache->tileCache, status->tileId + cache->tileStart, mMapCacheEntryFlagsGetPaletteId(status->flags)); + tile = mTileCacheGetTile(cache->tileCache, tileId, mMapCacheEntryFlagsGetPaletteId(status->flags)); } size_t stride = 8 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig); @@ -161,7 +161,11 @@ bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* en int paletteId = mMapCacheEntryFlagsGetPaletteId(status->flags); const color_t* tile = NULL; if (mMapCacheEntryFlagsIsVramClean(status->flags) && memcmp(status, &entry[location], sizeof(*entry)) == 0) { - tile = mTileCacheGetTileIfDirty(cache->tileCache, &status->tileStatus[paletteId], status->tileId + cache->tileStart, mMapCacheEntryFlagsGetPaletteId(status->flags)); + unsigned tileId = status->tileId + cache->tileStart; + if (tileId >= mTileCacheSystemInfoGetMaxTiles(cache->tileCache->sysConfig)) { + tileId = 0; + } + tile = mTileCacheGetTileIfDirty(cache->tileCache, &status->tileStatus[paletteId], tileId, mMapCacheEntryFlagsGetPaletteId(status->flags)); return !tile; } return false; diff --git a/src/gba/renderers/cache-set.c b/src/gba/renderers/cache-set.c index ddbeb0dfc..ce28d7e20 100644 --- a/src/gba/renderers/cache-set.c +++ b/src/gba/renderers/cache-set.c @@ -104,6 +104,7 @@ static void GBAVideoCacheWriteDISPCNT(struct mCacheSet* cache, uint16_t value) { static void GBAVideoCacheWriteBGCNT(struct mCacheSet* cache, size_t bg, uint16_t value) { struct mMapCache* map = mMapCacheSetGetPointer(&cache->maps, bg); + map->context = (void*) (uintptr_t) value; int tileStart = GBARegisterBGCNTGetCharBase(value) * 256; bool p = GBARegisterBGCNTGet256Color(value); @@ -145,6 +146,10 @@ void GBAVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint32_t address, switch (address) { case REG_DISPCNT: GBAVideoCacheWriteDISPCNT(cache, value); + GBAVideoCacheWriteBGCNT(cache, 0, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 0)->context); + GBAVideoCacheWriteBGCNT(cache, 1, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 1)->context); + GBAVideoCacheWriteBGCNT(cache, 2, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 2)->context); + GBAVideoCacheWriteBGCNT(cache, 3, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 3)->context); break; case REG_BG0CNT: GBAVideoCacheWriteBGCNT(cache, 0, value); diff --git a/src/platform/qt/MapView.cpp b/src/platform/qt/MapView.cpp index 129bea3d8..4db7b1b8b 100644 --- a/src/platform/qt/MapView.cpp +++ b/src/platform/qt/MapView.cpp @@ -90,7 +90,7 @@ void MapView::updateTilesGBA(bool force) { uchar* bgBits = m_rawMap.bits(); for (int j = 0; j < tilesH; ++j) { for (int i = 0; i < tilesW; ++i) { - mMapCacheCleanTile(mapCache, &m_mapStatus[i + j * tilesW], i, j); + mMapCacheCleanTile(mapCache, m_mapStatus, i, j); } for (int i = 0; i < 8; ++i) { memcpy(static_cast(&bgBits[tilesW * 32 * (i + j * 8)]), mMapCacheGetRow(mapCache, i + j * 8), tilesW * 32); diff --git a/src/platform/qt/MapView.h b/src/platform/qt/MapView.h index 7b9865ed3..7466cb038 100644 --- a/src/platform/qt/MapView.h +++ b/src/platform/qt/MapView.h @@ -40,7 +40,7 @@ private: Ui::MapView m_ui; std::shared_ptr m_controller; - mMapCacheEntry m_mapStatus[1024 * 1024] = {}; // TODO: Correct size + mMapCacheEntry m_mapStatus[128 * 128] = {}; // TODO: Correct size int m_map = 0; QImage m_rawMap; };