mirror of https://github.com/mgba-emu/mgba.git
Core: Add support for caching bitmapped modes
This commit is contained in:
parent
19a42a387a
commit
fbe375fab9
1
CHANGES
1
CHANGES
|
@ -7,6 +7,7 @@ Features:
|
|||
- GB: Expose platform information to CLI debugger
|
||||
- Support Discord Rich Presence
|
||||
- Debugger: Add tracing to file
|
||||
- Map viewer supports bitmapped GBA modes
|
||||
Emulation fixes:
|
||||
- GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208)
|
||||
- GBA: Reset now reloads multiboot ROMs
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/* Copyright (c) 2013-2019 Jeffrey Pfau
|
||||
*
|
||||
* 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
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef M_BITMAP_CACHE_H
|
||||
#define M_BITMAP_CACHE_H
|
||||
|
||||
#include <mgba-util/common.h>
|
||||
|
||||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/core/interface.h>
|
||||
|
||||
DECL_BITFIELD(mBitmapCacheConfiguration, uint32_t);
|
||||
DECL_BIT(mBitmapCacheConfiguration, ShouldStore, 0);
|
||||
|
||||
DECL_BITFIELD(mBitmapCacheSystemInfo, uint32_t);
|
||||
DECL_BITS(mBitmapCacheSystemInfo, EntryBPP, 0, 3);
|
||||
DECL_BIT(mBitmapCacheSystemInfo, UsesPalette, 3);
|
||||
DECL_BITS(mBitmapCacheSystemInfo, Width, 4, 10);
|
||||
DECL_BITS(mBitmapCacheSystemInfo, Height, 14, 10);
|
||||
DECL_BITS(mBitmapCacheSystemInfo, Buffers, 24, 2);
|
||||
|
||||
struct mBitmapCacheEntry {
|
||||
uint32_t paletteVersion;
|
||||
uint32_t vramVersion;
|
||||
uint8_t vramClean;
|
||||
};
|
||||
|
||||
struct mBitmapCache {
|
||||
color_t* cache;
|
||||
struct mBitmapCacheEntry* status;
|
||||
|
||||
uint32_t globalPaletteVersion;
|
||||
|
||||
uint8_t* vram;
|
||||
color_t* palette;
|
||||
|
||||
uint32_t bitsSize;
|
||||
uint32_t bitsStart[2];
|
||||
uint32_t stride;
|
||||
uint8_t buffer;
|
||||
|
||||
mBitmapCacheConfiguration config;
|
||||
mBitmapCacheSystemInfo sysConfig;
|
||||
|
||||
void* context;
|
||||
};
|
||||
|
||||
void mBitmapCacheInit(struct mBitmapCache* cache);
|
||||
void mBitmapCacheDeinit(struct mBitmapCache* cache);
|
||||
void mBitmapCacheConfigure(struct mBitmapCache* cache, mBitmapCacheConfiguration config);
|
||||
void mBitmapCacheConfigureSystem(struct mBitmapCache* cache, mBitmapCacheSystemInfo config);
|
||||
void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address);
|
||||
void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color);
|
||||
|
||||
void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry* entry, unsigned y);
|
||||
bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheEntry* entry, unsigned y);
|
||||
const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
||||
#endif
|
|
@ -10,19 +10,22 @@
|
|||
|
||||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/core/bitmap-cache.h>
|
||||
#include <mgba/core/map-cache.h>
|
||||
#include <mgba/core/tile-cache.h>
|
||||
#include <mgba-util/vector.h>
|
||||
|
||||
DECLARE_VECTOR(mMapCacheSet, struct mMapCache);
|
||||
DECLARE_VECTOR(mBitmapCacheSet, struct mBitmapCache);
|
||||
DECLARE_VECTOR(mTileCacheSet, struct mTileCache);
|
||||
|
||||
struct mCacheSet {
|
||||
struct mMapCacheSet maps;
|
||||
struct mBitmapCacheSet bitmaps;
|
||||
struct mTileCacheSet tiles;
|
||||
};
|
||||
|
||||
void mCacheSetInit(struct mCacheSet*, size_t nMaps, size_t nTiles);
|
||||
void mCacheSetInit(struct mCacheSet*, size_t nMaps, size_t nBitmaps, size_t nTiles);
|
||||
void mCacheSetDeinit(struct mCacheSet*);
|
||||
|
||||
void mCacheSetAssignVRAM(struct mCacheSet*, void* vram);
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/* Copyright (c) 2013-2019 Jeffrey Pfau
|
||||
*
|
||||
* 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
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <mgba/core/bitmap-cache.h>
|
||||
|
||||
#include <mgba-util/memory.h>
|
||||
|
||||
void mBitmapCacheInit(struct mBitmapCache* cache) {
|
||||
// TODO: Reconfigurable cache for space savings
|
||||
cache->cache = NULL;
|
||||
cache->config = mBitmapCacheConfigurationFillShouldStore(0);
|
||||
cache->status = NULL;
|
||||
cache->palette = NULL;
|
||||
cache->buffer = 0;
|
||||
}
|
||||
|
||||
static void _freeCache(struct mBitmapCache* cache) {
|
||||
size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig);
|
||||
mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t));
|
||||
mappedMemoryFree(cache->status, size * sizeof(*cache->status));
|
||||
if (cache->palette) {
|
||||
free(cache->palette);
|
||||
}
|
||||
cache->cache = NULL;
|
||||
cache->status = NULL;
|
||||
cache->palette = NULL;
|
||||
}
|
||||
|
||||
static void _redoCacheSize(struct mBitmapCache* cache) {
|
||||
if (!mBitmapCacheConfigurationIsShouldStore(cache->config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig);
|
||||
cache->cache = anonymousMemoryMap(mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t));
|
||||
cache->status = anonymousMemoryMap(size * sizeof(*cache->status));
|
||||
if (mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) {
|
||||
cache->palette = malloc((1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig))) * sizeof(color_t));
|
||||
} else {
|
||||
cache->palette = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void mBitmapCacheConfigure(struct mBitmapCache* cache, mBitmapCacheConfiguration config) {
|
||||
if (config == cache->config) {
|
||||
return;
|
||||
}
|
||||
_freeCache(cache);
|
||||
cache->config = config;
|
||||
_redoCacheSize(cache);
|
||||
}
|
||||
|
||||
void mBitmapCacheConfigureSystem(struct mBitmapCache* cache, mBitmapCacheSystemInfo config) {
|
||||
if (config == cache->sysConfig) {
|
||||
return;
|
||||
}
|
||||
_freeCache(cache);
|
||||
cache->sysConfig = config;
|
||||
_redoCacheSize(cache);
|
||||
|
||||
size_t stride = mBitmapCacheSystemInfoGetWidth(cache->sysConfig);
|
||||
size_t size = stride * mBitmapCacheSystemInfoGetHeight(cache->sysConfig);
|
||||
size_t bpe = mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig);
|
||||
if (bpe > 3) {
|
||||
size <<= bpe - 3;
|
||||
stride <<= bpe - 3;
|
||||
} else {
|
||||
size >>= 3 - bpe;
|
||||
stride >>= 3 - bpe;
|
||||
}
|
||||
cache->bitsSize = size;
|
||||
cache->stride = stride;
|
||||
}
|
||||
|
||||
void mBitmapCacheDeinit(struct mBitmapCache* cache) {
|
||||
_freeCache(cache);
|
||||
}
|
||||
|
||||
void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address) {
|
||||
size_t i;
|
||||
for (i = 0; i < mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); ++i) {
|
||||
if (address < cache->bitsStart[i]) {
|
||||
continue;
|
||||
}
|
||||
uint32_t offset = address - cache->bitsStart[i];
|
||||
if (offset >= cache->bitsSize) {
|
||||
continue;
|
||||
}
|
||||
offset /= cache->stride;
|
||||
offset *= mBitmapCacheSystemInfoGetBuffers(cache->sysConfig);
|
||||
offset += cache->buffer;
|
||||
cache->status[offset].vramClean = 0;
|
||||
++cache->status[offset].vramVersion;
|
||||
}
|
||||
}
|
||||
|
||||
void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color) {
|
||||
if (!mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) {
|
||||
return;
|
||||
}
|
||||
size_t maxEntry = 1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig));
|
||||
if (entry >= maxEntry) {
|
||||
return;
|
||||
}
|
||||
cache->palette[entry] = color;
|
||||
++cache->globalPaletteVersion;
|
||||
}
|
||||
|
||||
uint32_t _lookupEntry8(void* vram, uint32_t offset) {
|
||||
return ((uint8_t*) vram)[offset];
|
||||
}
|
||||
|
||||
uint32_t _lookupEntry15(void* vram, uint32_t offset) {
|
||||
return mColorFrom555(((uint16_t*) vram)[offset]);
|
||||
}
|
||||
|
||||
void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry* entry, unsigned y) {
|
||||
color_t* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)];
|
||||
size_t location = cache->buffer + mBitmapCacheSystemInfoGetBuffers(cache->sysConfig) * y;
|
||||
struct mBitmapCacheEntry* status = &cache->status[location];
|
||||
struct mBitmapCacheEntry desiredStatus = {
|
||||
.paletteVersion = cache->globalPaletteVersion,
|
||||
.vramVersion = entry->vramVersion,
|
||||
.vramClean = 1
|
||||
};
|
||||
|
||||
if (entry) {
|
||||
entry[location] = desiredStatus;
|
||||
}
|
||||
|
||||
if (!mBitmapCacheConfigurationIsShouldStore(cache->config) || !memcmp(status, &desiredStatus, sizeof(*entry))) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t offset = cache->bitsStart[cache->buffer] + y * mBitmapCacheSystemInfoGetWidth(cache->sysConfig);
|
||||
void* vram;
|
||||
int bpe = mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig);
|
||||
uint32_t (*lookupEntry)(void*, uint32_t);
|
||||
switch (bpe) {
|
||||
case 3:
|
||||
lookupEntry = _lookupEntry8;
|
||||
vram = &cache->vram[offset];
|
||||
break;
|
||||
case 4:
|
||||
lookupEntry = _lookupEntry15;
|
||||
vram = &cache->vram[offset << 1];
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
size_t x;
|
||||
if (mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) {
|
||||
for (x = 0; x < mBitmapCacheSystemInfoGetWidth(cache->sysConfig); ++x) {
|
||||
row[x] = cache->palette[lookupEntry(vram, x)];
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < mBitmapCacheSystemInfoGetWidth(cache->sysConfig); ++x) {
|
||||
row[x] = lookupEntry(vram, x);
|
||||
}
|
||||
}
|
||||
*status = desiredStatus;
|
||||
}
|
||||
|
||||
bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheEntry* entry, unsigned y) {
|
||||
size_t location = cache->buffer + mBitmapCacheSystemInfoGetBuffers(cache->sysConfig) * y;
|
||||
struct mBitmapCacheEntry desiredStatus = {
|
||||
.paletteVersion = cache->globalPaletteVersion,
|
||||
.vramVersion = entry->vramVersion,
|
||||
.vramClean = 1
|
||||
};
|
||||
|
||||
return memcmp(&entry[location], &desiredStatus, sizeof(*entry)) == 0;
|
||||
}
|
||||
|
||||
const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y) {
|
||||
color_t* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)];
|
||||
return row;
|
||||
}
|
|
@ -6,11 +6,14 @@
|
|||
#include <mgba/core/cache-set.h>
|
||||
|
||||
DEFINE_VECTOR(mMapCacheSet, struct mMapCache);
|
||||
DEFINE_VECTOR(mBitmapCacheSet, struct mBitmapCache);
|
||||
DEFINE_VECTOR(mTileCacheSet, struct mTileCache);
|
||||
|
||||
void mCacheSetInit(struct mCacheSet* cache, size_t nMaps, size_t nTiles) {
|
||||
void mCacheSetInit(struct mCacheSet* cache, size_t nMaps, size_t nBitmaps, size_t nTiles) {
|
||||
mMapCacheSetInit(&cache->maps, nMaps);
|
||||
mMapCacheSetResize(&cache->maps, nMaps);
|
||||
mBitmapCacheSetInit(&cache->bitmaps, nBitmaps);
|
||||
mBitmapCacheSetResize(&cache->bitmaps, nBitmaps);
|
||||
mTileCacheSetInit(&cache->tiles, nTiles);
|
||||
mTileCacheSetResize(&cache->tiles, nTiles);
|
||||
|
||||
|
@ -18,6 +21,9 @@ void mCacheSetInit(struct mCacheSet* cache, size_t nMaps, size_t nTiles) {
|
|||
for (i = 0; i < nMaps; ++i) {
|
||||
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, i));
|
||||
}
|
||||
for (i = 0; i < nBitmaps; ++i) {
|
||||
mBitmapCacheInit(mBitmapCacheSetGetPointer(&cache->bitmaps, i));
|
||||
}
|
||||
for (i = 0; i < nTiles; ++i) {
|
||||
mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, i));
|
||||
}
|
||||
|
@ -28,6 +34,9 @@ void mCacheSetDeinit(struct mCacheSet* cache) {
|
|||
for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) {
|
||||
mMapCacheDeinit(mMapCacheSetGetPointer(&cache->maps, i));
|
||||
}
|
||||
for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) {
|
||||
mBitmapCacheDeinit(mBitmapCacheSetGetPointer(&cache->bitmaps, i));
|
||||
}
|
||||
for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) {
|
||||
mTileCacheDeinit(mTileCacheSetGetPointer(&cache->tiles, i));
|
||||
}
|
||||
|
@ -38,6 +47,9 @@ void mCacheSetAssignVRAM(struct mCacheSet* cache, void* vram) {
|
|||
for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) {
|
||||
mMapCacheSetGetPointer(&cache->maps, i)->vram = vram;
|
||||
}
|
||||
for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) {
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, i)->vram = vram;
|
||||
}
|
||||
for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) {
|
||||
struct mTileCache* tileCache = mTileCacheSetGetPointer(&cache->tiles, i);
|
||||
tileCache->vram = (void*) ((uintptr_t) vram + tileCache->tileBase);
|
||||
|
@ -49,6 +61,9 @@ void mCacheSetWriteVRAM(struct mCacheSet* cache, uint32_t address) {
|
|||
for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) {
|
||||
mMapCacheWriteVRAM(mMapCacheSetGetPointer(&cache->maps, i), address);
|
||||
}
|
||||
for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) {
|
||||
mBitmapCacheWriteVRAM(mBitmapCacheSetGetPointer(&cache->bitmaps, i), address);
|
||||
}
|
||||
for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) {
|
||||
mTileCacheWriteVRAM(mTileCacheSetGetPointer(&cache->tiles, i), address);
|
||||
}
|
||||
|
@ -56,6 +71,9 @@ void mCacheSetWriteVRAM(struct mCacheSet* cache, uint32_t address) {
|
|||
|
||||
void mCacheSetWritePalette(struct mCacheSet* cache, uint32_t entry, color_t color) {
|
||||
size_t i;
|
||||
for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) {
|
||||
mBitmapCacheWritePalette(mBitmapCacheSetGetPointer(&cache->bitmaps, i), entry, color);
|
||||
}
|
||||
for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) {
|
||||
mTileCacheWritePalette(mTileCacheSetGetPointer(&cache->tiles, i), entry, color);
|
||||
}
|
||||
|
|
|
@ -11,16 +11,13 @@
|
|||
#include <mgba/internal/gb/video.h>
|
||||
|
||||
void GBVideoCacheInit(struct mCacheSet* cache) {
|
||||
mCacheSetInit(cache, 2, 1);
|
||||
mCacheSetInit(cache, 2, 0, 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);
|
||||
}
|
||||
|
|
|
@ -11,35 +11,45 @@
|
|||
#include <mgba/internal/gba/video.h>
|
||||
|
||||
void GBAVideoCacheInit(struct mCacheSet* cache) {
|
||||
mCacheSetInit(cache, 4, 4);
|
||||
mCacheSetInit(cache, 4, 2, 4);
|
||||
mTileCacheSystemInfo sysconfig = 0;
|
||||
mTileCacheConfiguration config = mTileCacheConfigurationFillShouldStore(0);
|
||||
sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 2); // 2^(2^2) = 16 entries
|
||||
sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes
|
||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
|
||||
mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 0));
|
||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config);
|
||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0);
|
||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
|
||||
mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 2));
|
||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 2), config);
|
||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 2), sysconfig, 0x10000, 0x100);
|
||||
|
||||
sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 3); // 2^(2^3) = 256 entries
|
||||
sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 0); // 1 palettes
|
||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048);
|
||||
mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 1));
|
||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 1), config);
|
||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 1), sysconfig, 0, 0);
|
||||
sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024);
|
||||
mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 3));
|
||||
mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 3), config);
|
||||
mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 3), sysconfig, 0x10000, 0x100);
|
||||
|
||||
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 0));
|
||||
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 1));
|
||||
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 2));
|
||||
mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 3));
|
||||
mBitmapCacheSystemInfo bitConfig;
|
||||
bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4);
|
||||
bitConfig = mBitmapCacheSystemInfoClearUsesPalette(bitConfig);
|
||||
bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 160);
|
||||
bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 240);
|
||||
bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 1);
|
||||
mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 0), bitConfig);
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->bitsStart[0] = 0;
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->bitsStart[1] = 0xA000;
|
||||
|
||||
bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 3);
|
||||
bitConfig = mBitmapCacheSystemInfoFillUsesPalette(bitConfig);
|
||||
bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 160);
|
||||
bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 240);
|
||||
bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 2);
|
||||
mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 1), bitConfig);
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[0] = 0;
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[1] = 0xA000;
|
||||
}
|
||||
|
||||
void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video) {
|
||||
|
@ -77,6 +87,8 @@ static void mapParser2(struct mMapCache* cache, struct mMapCacheEntry* entry, vo
|
|||
}
|
||||
|
||||
static void GBAVideoCacheWriteDISPCNT(struct mCacheSet* cache, uint16_t value) {
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->buffer = GBARegisterDISPCNTGetFrameSelect(value);
|
||||
|
||||
switch (GBARegisterDISPCNTGetMode(value)) {
|
||||
case 0:
|
||||
default:
|
||||
|
@ -110,6 +122,28 @@ static void GBAVideoCacheWriteDISPCNT(struct mCacheSet* cache, uint16_t value) {
|
|||
mMapCacheSetGetPointer(&cache->maps, 3)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
mBitmapCacheSystemInfo bitConfig;
|
||||
switch (GBARegisterDISPCNTGetMode(value)) {
|
||||
case 3:
|
||||
bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4);
|
||||
bitConfig = mBitmapCacheSystemInfoClearUsesPalette(bitConfig);
|
||||
bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 160);
|
||||
bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 240);
|
||||
bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 1);
|
||||
mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 0), bitConfig);
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->buffer = 0;
|
||||
break;
|
||||
case 5:
|
||||
bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4);
|
||||
bitConfig = mBitmapCacheSystemInfoClearUsesPalette(bitConfig);
|
||||
bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 128);
|
||||
bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 160);
|
||||
bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 2);
|
||||
mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 0), bitConfig);
|
||||
mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->buffer = GBARegisterDISPCNTGetFrameSelect(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void GBAVideoCacheWriteBGCNT(struct mCacheSet* cache, size_t bg, uint16_t value) {
|
||||
|
|
|
@ -12,7 +12,10 @@
|
|||
#include <mgba-util/png-io.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
#ifdef M_CORE_GBA
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
#include <mgba/internal/gba/memory.h>
|
||||
#include <mgba/internal/gba/video.h>
|
||||
#endif
|
||||
#ifdef M_CORE_GB
|
||||
#include <mgba/internal/gb/memory.h>
|
||||
|
@ -139,17 +142,36 @@ bool MapView::eventFilter(QObject* obj, QEvent* event) {
|
|||
void MapView::updateTilesGBA(bool force) {
|
||||
{
|
||||
CoreController::Interrupter interrupter(m_controller);
|
||||
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
|
||||
int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig);
|
||||
int tilesH = 1 << mMapCacheSystemInfoGetTilesHigh(mapCache->sysConfig);
|
||||
m_rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32);
|
||||
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);
|
||||
int bitmap = -1;
|
||||
if (m_controller->platform() == PLATFORM_GBA) {
|
||||
int mode = GBARegisterDISPCNTGetMode(static_cast<GBA*>(m_controller->thread()->core->board)->memory.io[REG_DISPCNT]);
|
||||
if (m_map == 2 && mode > 2) {
|
||||
bitmap = mode == 4 ? 1 : 0;
|
||||
}
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
memcpy(static_cast<void*>(&bgBits[tilesW * 32 * (i + j * 8)]), mMapCacheGetRow(mapCache, i + j * 8), tilesW * 32);
|
||||
}
|
||||
if (bitmap >= 0) {
|
||||
mBitmapCache* bitmapCache = mBitmapCacheSetGetPointer(&m_cacheSet->bitmaps, bitmap);
|
||||
int width = mBitmapCacheSystemInfoGetWidth(bitmapCache->sysConfig);
|
||||
int height = mBitmapCacheSystemInfoGetHeight(bitmapCache->sysConfig);
|
||||
m_rawMap = QImage(QSize(width, height), QImage::Format_ARGB32);
|
||||
uchar* bgBits = m_rawMap.bits();
|
||||
for (int j = 0; j < height; ++j) {
|
||||
mBitmapCacheCleanRow(bitmapCache, m_bitmapStatus, j);
|
||||
memcpy(static_cast<void*>(&bgBits[width * j * 4]), mBitmapCacheGetRow(bitmapCache, j), width * 4);
|
||||
}
|
||||
} else {
|
||||
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
|
||||
int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig);
|
||||
int tilesH = 1 << mMapCacheSystemInfoGetTilesHigh(mapCache->sysConfig);
|
||||
m_rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32);
|
||||
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);
|
||||
}
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
memcpy(static_cast<void*>(&bgBits[tilesW * 32 * (i + j * 8)]), mMapCacheGetRow(mapCache, i + j * 8), tilesW * 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +203,6 @@ void MapView::exportMap() {
|
|||
png_structp png = PNGWriteOpen(vf);
|
||||
png_infop info = PNGWriteHeaderA(png, m_rawMap.width(), m_rawMap.height());
|
||||
|
||||
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
|
||||
QImage map = m_rawMap.rgbSwapped();
|
||||
PNGWritePixelsA(png, map.width(), map.height(), map.bytesPerLine() / 4, static_cast<const void*>(map.constBits()));
|
||||
PNGWriteClose(png, info);
|
||||
|
|
|
@ -45,6 +45,7 @@ private:
|
|||
|
||||
std::shared_ptr<CoreController> m_controller;
|
||||
mMapCacheEntry m_mapStatus[128 * 128] = {}; // TODO: Correct size
|
||||
mBitmapCacheEntry m_bitmapStatus[512 * 2] = {}; // TODO: Correct size
|
||||
int m_map = 0;
|
||||
QImage m_rawMap;
|
||||
int m_boundary;
|
||||
|
|
Loading…
Reference in New Issue